package models import ( "errors" "fmt" "github.com/gin-gonic/gin" "github.com/xuri/excelize/v2" orm "go-admin/common/global" "go-admin/logger" "go-admin/tools" "go-admin/tools/config" "math" "strconv" "sync" "time" ) // ErpDecisionReportReq 进销存报表入参 type ErpDecisionReportReq struct { StoreId []uint32 `json:"store_id"` // 门店id CommodityName []string `json:"commodity_name"` // 商品名称 CategoryID []uint32 `json:"category_id"` // 商品分类id StartTime string `json:"start_time"` // 开始时间 EndTime string `json:"end_time"` // 结束时间 IsExport uint32 `json:"is_export"` // 1-导出 PageIndex int `json:"pageIndex"` // 页码 PageSize int `json:"pageSize"` // 页面条数 } // ErpDecisionReportResp 进销存报表出参 type ErpDecisionReportResp struct { Total int `json:"total"` // 总条数/记录数 PageIndex int `json:"pageIndex"` // 页码 PageSize int `json:"pageSize"` // 页面条数 ExportUrl string `json:"export_url"` // 导出excel路径 SumData DecisionSumData `json:"sum_data"` // 汇总数据 List []DecisionReportData `json:"list"` // 明细数据 } // DecisionSumData 进销存汇总数据 type DecisionSumData struct { TotalBeginStock uint32 `json:"total_begin_stock"` // 期初库存 TotalBeginAmount float64 `json:"total_begin_amount"` // 期初金额 TotalPurchaseStock uint32 `json:"total_purchase_stock"` // 采购进货 TotalPurchaseAmount float64 `json:"total_purchase_amount"` // 采购进货金额 TotalPurchaseReturn uint32 `json:"total_purchase_return"` // 采购退货 TotalReturnAmount float64 `json:"total_return_amount"` // 采购退货金额 TotalOrderSale uint32 `json:"total_order_sale"` // 零售销售 TotalSaleAmount float64 `json:"total_sale_amount"` // 零售销售金额 TotalOrderReject uint32 `json:"total_order_reject"` // 零售退货 TotalRejectAmount float64 `json:"total_reject_amount"` // 零售退货金额 TotalAllotIn uint32 `json:"total_allot_in"` // 调拨入库 TotalAllotInAmount float64 `json:"total_allot_in_amount"` // 调拨入库金额 TotalAllotWaitIn uint32 `json:"total_allot_wait_in"` // 在途库存(入库) TotalWaitInAmount float64 `json:"total_wait_in_amount"` // 在途库存(入库)金额 TotalAllotOut uint32 `json:"total_allot_out"` // 调拨出库 TotalAllotOutAmount float64 `json:"total_allot_out_amount"` // 调拨出库金额 TotalAllotWaitOut uint32 `json:"total_allot_wait_out"` // 在途库存(出库) TotalWaitOutAmount float64 `json:"total_wait_out_amount"` // 在途库存(出库)金额 TotalProductIn uint32 `json:"total_product_in"` // 产品入库 TotalProductInAmount float64 `json:"total_product_in_amount"` // 产品入库金额 TotalSystemIn uint32 `json:"total_system_in"` // 系统入库 TotalSystemInAmount float64 `json:"total_system_in_amount"` // 系统入库金额 TotalSystemOut uint32 `json:"total_system_out"` // 系统出库 TotalSystemOutAmount float64 `json:"total_system_out_amount"` // 系统出库金额 TotalCheckIn uint32 `json:"total_check_in"` // 盘点入库 TotalCheckInAmount float64 `json:"total_check_in_amount"` // 盘点入库金额 TotalCheckOut uint32 `json:"total_check_out"` // 盘点出库 TotalCheckOutAmount float64 `json:"total_check_out_amount"` // 盘点出库金额 TotalEndStock uint32 `json:"total_end_stock"` // 期末数量 TotalEndAmount float64 `json:"total_end_amount"` // 期末金额 } // DecisionReportData 进销存报表数据 type DecisionReportData struct { CommodityId uint32 `json:"commodity_id"` // 商品id CommodityName string `json:"commodity_name"` // 商品名称 CommoditySerialNumber string `json:"commodity_serial_number" gorm:"-"` // 商品编码 CategoryID uint32 `json:"category_id"` // 商品分类id CategoryName string `json:"category_name"` // 商品分类名称 BeginStock uint32 `json:"begin_stock"` // 期初库存 BeginAmount float64 `json:"begin_amount"` // 期初金额 PurchaseStock uint32 `json:"purchase_stock"` // 采购进货 PurchaseStockAmount float64 `json:"purchase_stock_amount"` // 采购进货金额 PurchaseReturn uint32 `json:"purchase_return"` // 采购退货 PurchaseReturnAmount float64 `json:"purchase_return_amount"` // 采购退货金额 OrderSale uint32 `json:"order_sale"` // 零售销售 OrderSaleAmount float64 `json:"order_sale_amount"` // 零售销售金额 OrderReject uint32 `json:"order_reject"` // 零售退货 OrderRejectAmount float64 `json:"order_reject_amount"` // 零售退货金额 AllotIn uint32 `json:"allot_in"` // 调拨入库 AllotInAmount float64 `json:"allot_in_amount"` // 调拨入库金额 AllotWaitIn uint32 `json:"allot_wait_in"` // 在途库存(入库) AllotWaitInAmount float64 `json:"allot_wait_in_amount"` // 在途库存(入库)金额 AllotOut uint32 `json:"allot_out"` // 调拨出库 AllotOutAmount float64 `json:"allot_out_amount"` // 调拨出库金额 AllotWaitOut uint32 `json:"allot_wait_out"` // 在途库存(出库) AllotWaitOutAmount float64 `json:"allot_wait_out_amount"` // 在途库存(出库)金额 ProductIn uint32 `json:"product_in"` // 产品入库 ProductInAmount float64 `json:"product_in_amount"` // 产品入库金额 SystemIn uint32 `json:"system_in"` // 系统入库 SystemInAmount float64 `json:"system_in_amount"` // 系统入库金额 SystemOut uint32 `json:"system_out"` // 系统出库 SystemOutAmount float64 `json:"system_out_amount"` // 系统出库金额 CheckIn uint32 `json:"check_in"` // 盘点入库 CheckInAmount float64 `json:"check_in_amount"` // 盘点入库金额 CheckOut uint32 `json:"check_out"` // 盘点出库 CheckOutAmount float64 `json:"check_out_amount"` // 盘点出库金额 EndStock uint32 `json:"end_stock"` // 期末数量 EndAmount float64 `json:"end_amount"` // 期末金额 } // DecisionReportList 进销存报表 func (m *ErpDecisionReportReq) DecisionReportList(c *gin.Context) (*ErpDecisionReportResp, 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 &ErpDecisionReportResp{}, nil } } else { return nil, errors.New("用户未绑定门店") } } resp := &ErpDecisionReportResp{ 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_stock") if len(m.StoreId) > 0 { // 门店复选 var storeIDs []uint32 for _, store := range m.StoreId { storeIDs = append(storeIDs, store) } if len(storeIDs) == 1 { qs = qs.Where("store_id = ?", storeIDs[0]) } else { qs = qs.Where("store_id IN (?)", storeIDs) } } if len(m.CommodityName) > 0 { // 商品名称 var commodityNames []string for _, commodityName := range m.CommodityName { commodityNames = append(commodityNames, commodityName) } if len(commodityNames) == 1 { qs = qs.Where("erp_commodity_name = ?", commodityNames[0]) } else { qs = qs.Where("erp_commodity_name IN (?)", commodityNames) } } if len(m.CategoryID) > 0 { // 商品分类id //var categoryIDs []uint32 //for _, category := range m.CategoryID { // categoryIDs = append(categoryIDs, category) //} //if len(categoryIDs) == 1 { // qs = qs.Where("erp_category_id = ?", categoryIDs[0]) //} else { // qs = qs.Where("erp_category_id IN (?)", categoryIDs) //} // categoryList, err := TransformErpCategoryIds(m.CategoryID) if err != nil { return nil, err } qs = qs.Where("erp_category_id IN ?", categoryList) } var count int64 err := qs.Count(&count).Error if err != nil { logger.Error("查询无库存列表数量失败", logger.Field("err", err)) return nil, err } var commodities []ErpStock if len(m.StoreId) == 1 && m.IsExport != 1 { // 只查询1个门店数据 err = qs.Order("erp_commodity_id, store_id desc").Offset(page * m.PageSize).Limit(m.PageSize).Find(&commodities).Error } else { err = qs.Order("erp_commodity_id, store_id desc").Find(&commodities).Error } if err != nil && err != RecordNotFound { logger.Error("查询无库存列表失败", logger.Field("err", err)) return nil, err } if len(m.StoreId) != 1 && m.IsExport != 1 { // 查询多个or所有门店数据 // 剔除商品id重复的数据 var tempCommodityMap = make(map[uint32]ErpStock) for i, item := range commodities { if existingItem, found := tempCommodityMap[item.ErpCommodityId]; found { // 在已有记录的 DecisionStoreId 中追加 StoreId existingItem.DecisionStoreId = append(existingItem.DecisionStoreId, item.StoreId) // 更新 map 中的记录 tempCommodityMap[item.ErpCommodityId] = existingItem } else { if len(m.StoreId) != 0 { commodities[i].StoreId = 0 } commodities[i].DecisionStoreId = append(commodities[i].DecisionStoreId, item.StoreId) tempCommodityMap[item.ErpCommodityId] = commodities[i] } } // 从 map 中提取所有不重复的商品记录到 trimCommodities trimCommodities := make([]ErpStock, 0, len(tempCommodityMap)) for _, item := range tempCommodityMap { trimCommodities = append(trimCommodities, item) } SortStockCommodities(trimCommodities) // 分页 resp.Total = len(trimCommodities) commodities = nil startIdx := (resp.PageIndex - 1) * resp.PageSize endIdx := resp.PageIndex * resp.PageSize // 确保不超出索引范围 if startIdx >= len(trimCommodities) { commodities = []ErpStock{} } else if endIdx > len(trimCommodities) { commodities = trimCommodities[startIdx:] } else { commodities = trimCommodities[startIdx:endIdx] } } var reportList []DecisionReportData var wg sync.WaitGroup ch := make(chan DecisionReportData, len(commodities)) for _, item := range commodities { wg.Add(1) go func(item ErpStock) { defer wg.Done() if len(item.DecisionStoreId) == 0 { item.DecisionStoreId = append(item.DecisionStoreId, item.StoreId) } reportData, _ := calculateInventoryReport(m, item) reportData.CommodityId = item.ErpCommodityId reportData.CommodityName = item.ErpCommodityName reportData.CommoditySerialNumber = item.CommoditySerialNumber reportData.CategoryID = item.ErpCategoryId reportData.CategoryName = item.ErpCategoryName // 发送结果到通道 ch <- reportData }(item) } go func() { wg.Wait() close(ch) }() // 从通道中接收结果 commodityMap := make(map[uint32]DecisionReportData) for data := range ch { if existing, found := commodityMap[data.CommodityId]; found { // Merge data if the commodity already exists in the map existing.BeginStock += data.BeginStock existing.BeginAmount += data.BeginAmount existing.PurchaseStock += data.PurchaseStock existing.PurchaseReturn += data.PurchaseReturn existing.OrderSale += data.OrderSale existing.OrderReject += data.OrderReject existing.AllotIn += data.AllotIn existing.AllotWaitIn += data.AllotWaitIn existing.AllotOut += data.AllotOut existing.AllotWaitOut += data.AllotWaitOut existing.ProductIn += data.ProductIn existing.SystemOut += data.SystemOut existing.CheckIn += data.CheckIn existing.CheckOut += data.CheckOut existing.EndStock += data.EndStock existing.EndAmount += data.EndAmount commodityMap[data.CommodityId] = existing } else { // If not found, add new entry to the map commodityMap[data.CommodityId] = data } } for _, data := range commodityMap { reportList = append(reportList, data) } // 排序规则:商品编号小 SortReportByDecisionCommodities(reportList) var sumData DecisionSumData sumData, err = getSumDecisionReportData(m) if err != nil { logger.Error("查询进销存汇总数据报错", logger.Field("err", err)) return nil, err } resp.SumData = sumData if m.IsExport == 1 { resp.Total = len(reportList) resp.List = reportList resp.ExportUrl, err = reportDecisionExport(resp) if err != nil { return nil, err } resp.Total = 0 resp.List = nil resp.SumData = DecisionSumData{} } else { if len(m.StoreId) == 1 { resp.Total = int(count) resp.List = reportList } else { resp.List = reportList } } return resp, nil } func calculateInventoryReport(m *ErpDecisionReportReq, item ErpStock) (DecisionReportData, error) { var reportData DecisionReportData // Step 1: 查询期初库存和金额 systemStartData, err := getSystemStartData(m, item) if err != nil { return DecisionReportData{}, err } reportData.BeginStock = systemStartData.BeginStock reportData.BeginAmount = systemStartData.BeginAmount // Step 2: 查询期末库存和金额 systemEndData, err := getSystemEndCount(m, item) if err != nil { return DecisionReportData{}, err } reportData.EndStock = systemEndData.EndStock reportData.EndAmount = systemEndData.EndAmount // Step 3: 查询期间内的各类库存变动数据 purchaseStockData, err := getPurchaseStockCount(m, item) if err != nil { return DecisionReportData{}, err } reportData.PurchaseStock = purchaseStockData.PurchaseStock purchaseReturnData, err := getPurchaseReturnCount(m, item) if err != nil { return DecisionReportData{}, err } reportData.PurchaseReturn = purchaseReturnData.PurchaseReturn saleOutData, err := getSaleOutCount(m, item) if err != nil { return DecisionReportData{}, err } reportData.OrderSale = saleOutData.OrderSale saleReturnData, err := getSaleReturnCount(m, item) if err != nil { return DecisionReportData{}, err } reportData.OrderReject = saleReturnData.OrderReject allotInData, err := getAllotInCount(m, item) if err != nil { return DecisionReportData{}, err } reportData.AllotIn = allotInData.AllotIn allotWaitInData, err := getAllotWaitInCount(m, item) if err != nil { return DecisionReportData{}, err } reportData.AllotWaitIn = allotWaitInData.AllotWaitIn allotOutData, err := getAllotOutCount(m, item) if err != nil { return DecisionReportData{}, err } reportData.AllotOut = allotOutData.AllotOut allotWaitOutData, err := getAllotWaitOutCount(m, item) if err != nil { return DecisionReportData{}, err } reportData.AllotWaitOut = allotWaitOutData.AllotWaitOut productData, err := getProductCount(m, item) if err != nil { return DecisionReportData{}, err } reportData.ProductIn = productData.ProductIn systemInData, err := getSystemInCount(m, item) if err != nil { return DecisionReportData{}, err } reportData.SystemIn = systemInData.SystemIn systemOutData, err := getSystemOutCount(m, item) if err != nil { return DecisionReportData{}, err } reportData.SystemOut = systemOutData.SystemOut changeAddData, err := getChangeAddCount(m, item) if err != nil { return DecisionReportData{}, err } reportData.CheckIn = changeAddData.CheckIn changeReduceData, err := getChangeReduceCount(m, item) if err != nil { return DecisionReportData{}, err } reportData.CheckOut = changeReduceData.CheckOut if m.EndTime != "" { // Step 4: 计算调整库存逻辑(期初+入库-出库) reportData.EndStock = reportData.BeginStock + reportData.PurchaseStock + reportData.AllotIn + reportData.ProductIn + reportData.CheckIn + reportData.OrderReject + reportData.SystemIn if reportData.EndStock < (reportData.PurchaseReturn + reportData.OrderSale + reportData.AllotOut + reportData.SystemOut + reportData.CheckOut) { reportData.EndStock = 0 reportData.EndAmount = 0 } else { reportData.EndStock -= reportData.PurchaseReturn + reportData.OrderSale + reportData.AllotOut + reportData.SystemOut + reportData.CheckOut } } return reportData, nil } // 查询期初库存 func getSystemStartData(req *ErpDecisionReportReq, stock ErpStock) (DecisionReportData, error) { if req.StartTime == "" || req.EndTime == "" { return DecisionReportData{}, nil } tempReq1 := *req tempReq := &tempReq1 tempReq.EndTime = time.Now().Format(QueryTimeFormat) var respData DecisionReportData // 期末库存 sumEndData, err := getSystemEndCount(tempReq, stock) if err != nil { return DecisionReportData{}, err } // 查询采购进货数量 purchaseStockData, err := getPurchaseStockCount(tempReq, stock) if err != nil { return DecisionReportData{}, err } // 查询采购退货数量 purchaseReturnData, err := getPurchaseReturnCount(tempReq, stock) if err != nil { return DecisionReportData{}, err } // 查询零售销售数量 saleOutData, err := getSaleOutCount(tempReq, stock) if err != nil { return DecisionReportData{}, err } // 查询零售退货数量 saleReturnData, err := getSaleReturnCount(tempReq, stock) if err != nil { return DecisionReportData{}, err } // 查询调拨入库数量 allotInData, err := getAllotInCount(tempReq, stock) if err != nil { return DecisionReportData{}, err } // 查询调拨出库数量 allotOutData, err := getAllotOutCount(tempReq, stock) if err != nil { return DecisionReportData{}, err } // 查询产品入库数量:产品入库 productData, err := getProductCount(tempReq, stock) if err != nil { return DecisionReportData{}, err } // 查询系统出库数据:系统出库 systemOutData, err := getSystemOutCount(tempReq, stock) if err != nil { return DecisionReportData{}, err } // 查询盘点入库数量 changeAddData, err := getChangeAddCount(tempReq, stock) if err != nil { return DecisionReportData{}, err } // 查询盘点出库数量 changeReduceData, err := getChangeReduceCount(tempReq, stock) if err != nil { return DecisionReportData{}, err } respData.BeginStock = sumEndData.EndStock + (saleOutData.OrderSale - saleReturnData.OrderReject) + allotOutData.AllotOut + systemOutData.SystemOut + changeReduceData.CheckOut - (purchaseStockData.PurchaseStock - purchaseReturnData.PurchaseReturn) - allotInData.AllotIn - productData.ProductIn - changeAddData.CheckIn return respData, nil } // 查询期初库存和金额 func getSystemStartCount(req *ErpDecisionReportReq, stock ErpStock) (DecisionReportData, error) { var reportData DecisionReportData if req.StartTime != "" { // 有开始时间 startTime, err := time.Parse(QueryTimeFormat, req.StartTime) if err != nil { logger.Errorf("getSystemStartCount err:", err) return DecisionReportData{}, err } // 计算开始时间的前一天 //previousDay := startTime.AddDate(0, 0, -1) previousDay := startTime.AddDate(0, 0, -1).Truncate(24 * time.Hour). Add(23*time.Hour + 59*time.Minute + 59*time.Second) // 获取系统入库数量 var systemStartData DecisionReportData qs := orm.Eloquent.Debug().Table("erp_stock_commodity"). Select("SUM(count) as begin_stock, SUM(wholesale_price) as begin_amount"). Where("storage_type = ? and erp_commodity_id = ?", SystemInventory, stock.ErpCommodityId). Where("first_stock_time <= ?", previousDay) if stock.StoreId != 0 { if len(stock.DecisionStoreId) > 1 { qs = qs.Where("store_id in (?)", stock.DecisionStoreId) } else { qs = qs.Where("store_id = ?", stock.DecisionStoreId[0]) } } err = qs.Find(&systemStartData).Error if err != nil { return DecisionReportData{}, err } // 获取开始时间前一天的所有出库数量(包括销售出库、系统出库、盘点出库、采购退货) var outStockData struct { SoldOut uint32 `json:"sold_out"` SoldOutAmount float64 `json:"sold_out_amount"` SystemOut uint32 `json:"system_out"` SystemOutAmount float64 `json:"system_out_amount"` CheckOut uint32 `json:"check_out"` CheckOutAmount float64 `json:"check_out_amount"` } es := orm.Eloquent.Debug().Table("erp_stock_commodity"). Select("SUM(CASE WHEN state = ? THEN count ELSE 0 END) AS sold_out, "+ "SUM(CASE WHEN state = ? THEN wholesale_price ELSE 0 END) AS sold_out_amount, "+ "SUM(CASE WHEN state = ? THEN count ELSE 0 END) AS system_out, "+ "SUM(CASE WHEN state = ? THEN wholesale_price ELSE 0 END) AS system_out_amount, "+ "SUM(CASE WHEN state = ? THEN count ELSE 0 END) AS check_out, "+ "SUM(CASE WHEN state = ? THEN wholesale_price ELSE 0 END) AS check_out_amount", SoldOut, SoldOut, SystemOut, SystemOut, CheckOut, CheckOut). Where("updated_at <= ?", previousDay). Where("state IN (?)", []int{SoldOut, SystemOut, CheckOut}). Where("erp_commodity_id = ?", stock.ErpCommodityId) if stock.StoreId != 0 { if len(stock.DecisionStoreId) > 1 { es = es.Where("store_id in (?)", stock.DecisionStoreId) } else { es = es.Where("store_id = ?", stock.DecisionStoreId[0]) } } err = es.Find(&outStockData).Error if err != nil { return DecisionReportData{}, err } // 获取开始时间前一天的所有入库数量(包括采购入库、产品入库、盘点入库) var inStockData struct { PurchaseIn uint32 `json:"purchase_in"` PurchaseInAmount float64 `json:"purchase_in_amount"` ProductIn uint32 `json:"product_in"` ProductInAmount float64 `json:"product_in_amount"` CheckIn uint32 `json:"check_in"` CheckInAmount float64 `json:"check_in_amount"` } ts := orm.Eloquent.Debug().Table("erp_stock_commodity"). Select("SUM(CASE WHEN storage_type = ? THEN count ELSE 0 END) AS purchase_in, "+ "SUM(CASE WHEN storage_type = ? THEN wholesale_price ELSE 0 END) AS purchase_in_amount, "+ "SUM(CASE WHEN storage_type = ? THEN count ELSE 0 END) AS product_in, "+ "SUM(CASE WHEN storage_type = ? THEN wholesale_price ELSE 0 END) AS product_in_amount, "+ "SUM(CASE WHEN storage_type = ? THEN count ELSE 0 END) AS check_in, "+ "SUM(CASE WHEN storage_type = ? THEN wholesale_price ELSE 0 END) AS check_in_amount", PurchaseInventory, PurchaseInventory, ProductInventory, ProductInventory, CheckInventory, CheckInventory). Where("created_at <= ?", previousDay). Where("erp_commodity_id = ?", stock.ErpCommodityId) if stock.StoreId != 0 { if len(stock.DecisionStoreId) > 1 { ts = ts.Where("store_id in (?)", stock.DecisionStoreId) } else { ts = ts.Where("store_id = ?", stock.DecisionStoreId[0]) } } err = ts.Find(&inStockData).Error if err != nil { return DecisionReportData{}, err } // 查询调拨入库、调拨出库的数量和金额 // 调拨入库数量和金额 var allotInData struct { AllotIn uint32 `json:"allot_in"` AllotInAmount float64 `json:"allot_in_amount"` } allotInQuery := orm.Eloquent.Debug().Table("erp_inventory_allot_commodity"). Select("SUM(erp_inventory_allot_commodity.count) AS allot_in, "+ "SUM(erp_inventory_allot_commodity.amount) AS allot_in_amount"). Joins("JOIN erp_inventory_allot_order "+ "ON erp_inventory_allot_order.id = erp_inventory_allot_commodity.allot_order_id"). Where("erp_inventory_allot_order.state = ? AND erp_inventory_allot_commodity.commodity_id = ?", ErpInventoryAllotOrderFinished, stock.ErpCommodityId). Where("erp_inventory_allot_order.receive_time <= ?", previousDay) // 处理 `store_id` 条件 if len(stock.DecisionStoreId) > 1 { allotInQuery = allotInQuery.Where("erp_inventory_allot_order.receive_store_id IN (?)", stock.DecisionStoreId) } else { allotInQuery = allotInQuery.Where("erp_inventory_allot_order.receive_store_id = ?", stock.DecisionStoreId[0]) } err = allotInQuery.Find(&allotInData).Error if err != nil { return DecisionReportData{}, err } // 调拨出库数量和金额 var allotOutData struct { AllotOut uint32 `json:"allot_out"` AllotOutAmount float64 `json:"allot_out_amount"` } allotOutQuery := orm.Eloquent.Debug().Table("erp_inventory_allot_commodity"). Select("SUM(erp_inventory_allot_commodity.count) AS allot_out, "+ "SUM(erp_inventory_allot_commodity.amount) AS allot_out_amount"). Joins("JOIN erp_inventory_allot_order "+ "ON erp_inventory_allot_order.id = erp_inventory_allot_commodity.allot_order_id"). Where("erp_inventory_allot_order.state = ? AND erp_inventory_allot_commodity.commodity_id = ?", ErpInventoryAllotOrderFinished, stock.ErpCommodityId). Where("erp_inventory_allot_order.receive_time <= ?", previousDay) // 处理 `store_id` 条件 if len(stock.DecisionStoreId) > 1 { allotOutQuery = allotOutQuery.Where("erp_inventory_allot_order.deliver_store_id IN (?)", stock.DecisionStoreId) } else { allotOutQuery = allotOutQuery.Where("erp_inventory_allot_order.deliver_store_id = ?", stock.DecisionStoreId[0]) } err = allotOutQuery.Find(&allotOutData).Error if err != nil { return DecisionReportData{}, err } // 计算期初库存 beginStock := int64(systemStartData.BeginStock) - int64(outStockData.SoldOut) - int64(outStockData.SystemOut) - int64(outStockData.CheckOut) - int64(allotOutData.AllotOut) + int64(allotInData.AllotIn) + int64(inStockData.PurchaseIn) + int64(inStockData.ProductIn) + int64(inStockData.CheckIn) if beginStock < 0 { beginStock = 0 // 确保库存不会为负 } // 计算期初金额 beginAmount := systemStartData.BeginAmount - outStockData.SoldOutAmount - outStockData.SystemOutAmount - outStockData.CheckOutAmount - allotOutData.AllotOutAmount + allotInData.AllotInAmount + inStockData.PurchaseInAmount + inStockData.ProductInAmount + inStockData.CheckInAmount if beginAmount < 0 { beginAmount = 0 // 确保库存不会为负 } reportData.BeginStock = uint32(beginStock) reportData.BeginAmount = beginAmount } else { //// 如果没有开始时间,直接获取系统入库数量作为期初库存 //qs := orm.Eloquent.Debug().Table("erp_stock_commodity"). // Select("SUM(count) as begin_stock, SUM(wholesale_price) as begin_amount"). // Where("storage_type = ? and erp_commodity_id = ?", SystemInventory, stock.ErpCommodityId) // //if stock.StoreId != 0 { // if len(stock.DecisionStoreId) > 1 { // qs = qs.Where("store_id in (?)", stock.DecisionStoreId) // } else { // qs = qs.Where("store_id = ?", stock.DecisionStoreId) // } //} //err := qs.Find(&reportData).Error //if err != nil { // return DecisionReportData{}, err //} } return reportData, nil } func getSystemEndCount(req *ErpDecisionReportReq, stock ErpStock) (DecisionReportData, error) { var reportData DecisionReportData qs := orm.Eloquent.Debug().Table("erp_stock_commodity") //es := orm.Eloquent.Debug().Table("erp_stock_commodity") //if req.EndTime != "" { // 有结束时间 // endTime, err := time.Parse(QueryTimeFormat, req.EndTime) // if err != nil { // logger.Errorf("getSystemEndCount err:", err) // return DecisionReportData{}, err // } // // // 获取结束时间之前的所有入库数量(包括系统入库、采购入库、产品入库和盘点入库) // var inStockData struct { // SystemIn uint32 `json:"system_in"` // SystemInAmount float64 `json:"system_in_amount"` // PurchaseIn uint32 `json:"purchase_in"` // PurchaseInAmount float64 `json:"purchase_in_amount"` // ProductIn uint32 `json:"product_in"` // ProductInAmount float64 `json:"product_in_amount"` // CheckIn uint32 `json:"check_in"` // CheckInAmount float64 `json:"check_in_amount"` // } // qs = qs.Select("SUM(CASE WHEN storage_type = ? THEN count ELSE 0 END) AS system_in, "+ // "SUM(CASE WHEN storage_type = ? THEN wholesale_price ELSE 0 END) AS system_in_amount, "+ // "SUM(CASE WHEN storage_type = ? THEN count ELSE 0 END) AS purchase_in, "+ // "SUM(CASE WHEN storage_type = ? THEN wholesale_price ELSE 0 END) AS purchase_in_amount, "+ // "SUM(CASE WHEN storage_type = ? THEN count ELSE 0 END) AS product_in, "+ // "SUM(CASE WHEN storage_type = ? THEN wholesale_price ELSE 0 END) AS product_in_amount, "+ // "SUM(CASE WHEN storage_type = ? THEN count ELSE 0 END) AS check_in, "+ // "SUM(CASE WHEN storage_type = ? THEN wholesale_price ELSE 0 END) AS check_in_amount", // SystemInventory, SystemInventory, PurchaseInventory, PurchaseInventory, ProductInventory, ProductInventory, // CheckInventory, CheckInventory). // Where("updated_at <= ?", endTime). // Where("erp_commodity_id = ?", stock.ErpCommodityId) // // if stock.StoreId != 0 { // if len(stock.DecisionStoreId) > 1 { // qs = qs.Where("store_id in (?)", stock.DecisionStoreId) // } else { // qs = qs.Where("store_id = ?", stock.DecisionStoreId[0]) // } // } // // err = qs.Find(&inStockData).Error // if err != nil { // return DecisionReportData{}, err // } // // // 获取结束时间之前的所有出库数量(包括销售出库、系统出库和盘点出库) // var outStockData struct { // SoldOut uint32 `json:"sold_out"` // SoldOutAmount float64 `json:"sold_out_amount"` // SystemOut uint32 `json:"system_out"` // SystemOutAmount float64 `json:"system_out_amount"` // CheckOut uint32 `json:"check_out"` // CheckOutAmount float64 `json:"check_out_amount"` // } // es = es.Select("SUM(CASE WHEN state = ? THEN count ELSE 0 END) AS sold_out, "+ // "SUM(CASE WHEN state = ? THEN wholesale_price ELSE 0 END) AS sold_out_amount, "+ // "SUM(CASE WHEN state = ? THEN count ELSE 0 END) AS system_out, "+ // "SUM(CASE WHEN state = ? THEN wholesale_price ELSE 0 END) AS system_out_amount, "+ // "SUM(CASE WHEN state = ? THEN count ELSE 0 END) AS check_out, "+ // "SUM(CASE WHEN state = ? THEN wholesale_price ELSE 0 END) AS check_out_amount", // SoldOut, SoldOut, SystemOut, SystemOut, CheckOut, CheckOut). // Where("updated_at <= ?", endTime). // Where("state IN (?)", []int{SoldOut, SystemOut, CheckOut}). // Where("erp_commodity_id = ?", stock.ErpCommodityId) // // if stock.StoreId != 0 { // if len(stock.DecisionStoreId) > 1 { // es = es.Where("store_id in (?)", stock.DecisionStoreId) // } else { // es = es.Where("store_id = ?", stock.DecisionStoreId[0]) // } // } // err = es.Find(&outStockData).Error // if err != nil { // return DecisionReportData{}, err // } // // // 计算期末库存 // endStock := int64(inStockData.SystemIn) + int64(inStockData.PurchaseIn) + int64(inStockData.ProductIn) + // int64(inStockData.CheckIn) - int64(outStockData.SoldOut) - int64(outStockData.SystemOut) - // int64(outStockData.CheckOut) // // if endStock < 0 { // endStock = 0 // 确保库存不会为负 // } // // // 计算期末金额 // endAmount := inStockData.SystemInAmount + inStockData.PurchaseInAmount + inStockData.ProductInAmount + // inStockData.CheckInAmount - outStockData.SoldOutAmount - outStockData.SystemOutAmount - // outStockData.CheckOutAmount // if endAmount < 0 { // endAmount = 0 // } // // reportData.EndStock = uint32(endStock) // reportData.EndAmount = endAmount //} else { // // 如果没有结束时间,直接获取系统在库数量作为期末库存 // qs = qs.Select("SUM(count) as end_stock, SUM(wholesale_price) as end_amount"). // Where("state in (?) and erp_commodity_id = ?", []uint32{InStock, InAllot}, stock.ErpCommodityId). // Find(&reportData) // // if stock.StoreId != 0 { // if len(stock.DecisionStoreId) > 1 { // qs = qs.Where("store_id in (?)", stock.DecisionStoreId) // } else { // qs = qs.Where("store_id = ?", stock.DecisionStoreId[0]) // } // } // err := qs.Find(&reportData).Error // if err != nil { // return DecisionReportData{}, err // } //} // 直接获取系统在库数量作为期末库存 qs = qs.Select("SUM(count) as end_stock, SUM(wholesale_price) as end_amount"). Where("state in (?) and erp_commodity_id = ?", []uint32{InStock, InAllot}, stock.ErpCommodityId). Find(&reportData) if stock.StoreId != 0 { if len(stock.DecisionStoreId) > 1 { qs = qs.Where("store_id in (?)", stock.DecisionStoreId) } else { qs = qs.Where("store_id = ?", stock.DecisionStoreId[0]) } } err := qs.Find(&reportData).Error if err != nil { return DecisionReportData{}, err } return reportData, nil } ////查询期初库存、期初金额 ////没有时间:默认为系统入库数量 ////某一天:默认系统入库数量 - 某一天前的所有出库数量 + 某一天前的所有入库数量 ////某个时间段:默认系统入库数量 - 开始时间前的所有出库数量 + 开始时间前的所有入库数量 //func getSystemStartCount(req *ErpDecisionReportReq, stock ErpStock) (DecisionReportData, error) { // var reportData DecisionReportData // // qs := orm.Eloquent.Debug().Table("erp_stock_commodity") // // // 进行条件查询 // if req.StartTime != "" { // 出入库开始时间 // parse, err := time.Parse(QueryTimeFormat, req.StartTime) // if err != nil { // logger.Errorf("getSystemStartCount err:", err) // return DecisionReportData{}, err // } // // // 将时间往前推一天 // previousDay := parse.AddDate(0, 0, -1) // // // 手动创建 req 的深拷贝 // tempReq := &ErpDecisionReportReq{ // StartTime: "", // 清空 StartTime // EndTime: previousDay.Format(QueryTimeFormat), // IsExport: req.IsExport, // PageIndex: req.PageIndex, // PageSize: req.PageSize, // StoreId: req.StoreId, // CommodityName: req.CommodityName, // CategoryID: req.CategoryID, // } // // tempReportData, err := getSystemEndCount(tempReq, stock) // if err != nil { // return DecisionReportData{}, err // } // reportData.BeginStock = tempReportData.EndStock // reportData.BeginAmount = tempReportData.EndAmount // } else { // var err error // if stock.StoreId != 0 { // if len(stock.DecisionStoreId) > 1 { // err = qs.Select("SUM(count) as begin_stock, SUM(wholesale_price) as begin_amount"). // Where("storage_type = ? and store_id in (?) and erp_commodity_id = ?", SystemInventory, stock.DecisionStoreId, // stock.ErpCommodityId).Find(&reportData).Error // } else { // err = qs.Select("SUM(count) as begin_stock, SUM(wholesale_price) as begin_amount"). // Where("storage_type = ? and store_id = ? and erp_commodity_id = ?", SystemInventory, stock.StoreId, // stock.ErpCommodityId).Find(&reportData).Error // } // } else { // err = qs.Select("SUM(count) as begin_stock, SUM(wholesale_price) as begin_amount"). // Where("storage_type = ? and erp_commodity_id = ?", SystemInventory, stock.ErpCommodityId). // Find(&reportData).Error // } // if err != nil { // return DecisionReportData{}, err // } // } // // //if req.EndTime != "" { // 出入库结束时间 // // parse, err := time.Parse(QueryTimeFormat, req.EndTime) // // if err != nil { // // logger.Errorf("getSystemStartCount err:", err) // // return DecisionReportData{}, err // // } // // qs = qs.Where("created_at <= ?", parse) // //} // // return reportData, nil //} // ////查询期末库存、期末金额 //func getSystemEndCount(req *ErpDecisionReportReq, stock ErpStock) (DecisionReportData, error) { // var reportData DecisionReportData // // qs := orm.Eloquent.Debug().Table("erp_stock_commodity") // // //// 进行条件查询 // //if req.StartTime != "" { // 出入库开始时间 // // parse, err := time.Parse(QueryTimeFormat, req.StartTime) // // if err != nil { // // logger.Errorf("getSystemStartCount err:", err) // // return DecisionReportData{}, err // // } // // qs = qs.Where("created_at > ?", parse) // //} // // if req.EndTime != "" { // 出入库结束时间 // parse, err := time.Parse(QueryTimeFormat, req.EndTime) // if err != nil { // logger.Errorf("getSystemStartCount err:", err) // return DecisionReportData{}, err // } // qs = qs.Where("created_at <= ?", parse) // } // // var err error // if stock.StoreId != 0 { // if len(stock.DecisionStoreId) > 1 { // err = qs.Select("SUM(count) as end_stock, SUM(wholesale_price) as end_amount"). // Where("state in (?) and store_id in (?) and erp_commodity_id = ?", []uint32{InStock, InAllot}, stock.DecisionStoreId, // stock.ErpCommodityId).Find(&reportData).Error // } else { // err = qs.Select("SUM(count) as end_stock, SUM(wholesale_price) as end_amount"). // Where("state in (?) and store_id = ? and erp_commodity_id = ?", []uint32{InStock, InAllot}, stock.StoreId, // stock.ErpCommodityId).Find(&reportData).Error // } // } else { // err = qs.Select("SUM(count) as end_stock, SUM(wholesale_price) as end_amount"). // Where("state in (?) and erp_commodity_id = ?", []uint32{InStock, InAllot}, // stock.ErpCommodityId).Find(&reportData).Error // } // if err != nil { // return DecisionReportData{}, err // } // // return reportData, nil //} // 查询采购进货数量 func getPurchaseStockCount(req *ErpDecisionReportReq, stock ErpStock) (DecisionReportData, error) { var reportData DecisionReportData qs := orm.Eloquent.Debug().Table("erp_purchase_inventory") // 进行条件查询 if req.StartTime != "" { // 出入库开始时间 parse, err := time.Parse(QueryTimeFormat, req.StartTime) if err != nil { logger.Errorf("getPurchaseCount err:", err) return DecisionReportData{}, err } qs = qs.Where("erp_purchase_inventory.updated_at > ?", parse) } if req.EndTime != "" { // 出入库结束时间 parse, err := time.Parse(QueryTimeFormat, req.EndTime) if err != nil { logger.Errorf("getPurchaseCount err:", err) return DecisionReportData{}, err } qs = qs.Where("erp_purchase_inventory.updated_at <= ?", parse) } var err error if stock.StoreId != 0 { if len(stock.DecisionStoreId) > 1 { err = qs.Select("SUM(erp_purchase_inventory.count) AS purchase_stock"). Joins("JOIN erp_purchase_order ON erp_purchase_order.id = erp_purchase_inventory.erp_purchase_order_id"). Where("erp_purchase_order.store_id in (?) and erp_purchase_inventory.erp_commodity_id = ? and "+ "erp_purchase_inventory.purchase_type = ?", stock.DecisionStoreId, stock.ErpCommodityId, ErpProcureOrder). Find(&reportData).Error } else { err = qs.Select("SUM(erp_purchase_inventory.count) AS purchase_stock"). Joins("JOIN erp_purchase_order ON erp_purchase_order.id = erp_purchase_inventory.erp_purchase_order_id"). Where("erp_purchase_order.store_id = ? and erp_purchase_inventory.erp_commodity_id = ? and "+ "erp_purchase_inventory.purchase_type = ?", stock.StoreId, stock.ErpCommodityId, ErpProcureOrder). Find(&reportData).Error } } else { err = qs.Select("SUM(erp_purchase_inventory.count) AS purchase_stock"). Joins("JOIN erp_purchase_order ON erp_purchase_order.id = erp_purchase_inventory.erp_purchase_order_id"). Where("erp_purchase_inventory.erp_commodity_id = ? and "+ "erp_purchase_inventory.purchase_type = ?", stock.ErpCommodityId, ErpProcureOrder). Find(&reportData).Error } if err != nil { return DecisionReportData{}, err } return reportData, nil } // 查询采购退货数量 func getPurchaseReturnCount(req *ErpDecisionReportReq, stock ErpStock) (DecisionReportData, error) { var reportData DecisionReportData qs := orm.Eloquent.Debug().Table("erp_stock_commodity") // 进行条件查询 if req.StartTime != "" { // 出入库开始时间 parse, err := time.Parse(QueryTimeFormat, req.StartTime) if err != nil { logger.Errorf("getSystemStartCount err:", err) return DecisionReportData{}, err } qs = qs.Where("updated_at > ?", parse) } if req.EndTime != "" { // 出入库结束时间 parse, err := time.Parse(QueryTimeFormat, req.EndTime) if err != nil { logger.Errorf("getSystemStartCount err:", err) return DecisionReportData{}, err } qs = qs.Where("updated_at <= ?", parse) } var err error if stock.StoreId != 0 { if len(stock.DecisionStoreId) > 1 { err = qs.Select("SUM(count) as purchase_return").Where("state = ? and store_id in (?) and "+ "erp_commodity_id = ?", PurchaseReturn, stock.DecisionStoreId, stock.ErpCommodityId).Find(&reportData).Error } else { err = qs.Select("SUM(count) as purchase_return").Where("state = ? and store_id = ? and "+ "erp_commodity_id = ?", PurchaseReturn, stock.StoreId, stock.ErpCommodityId).Find(&reportData).Error } } else { err = qs.Select("SUM(count) as purchase_return").Where("state = ? and "+ "erp_commodity_id = ?", PurchaseReturn, stock.ErpCommodityId).Find(&reportData).Error } if err != nil { return DecisionReportData{}, err } return reportData, nil } // 查询零售销售数量 func getSaleOutCount(req *ErpDecisionReportReq, stock ErpStock) (DecisionReportData, error) { var reportData DecisionReportData qs := orm.Eloquent.Debug().Table("erp_order_commodity"). Joins("JOIN erp_order ON erp_order_commodity.erp_order_id = erp_order.id") if req.StartTime != "" { // 审核开始时间 parse, err := time.Parse(QueryTimeFormat, req.StartTime) if err != nil { logger.Errorf("err:", err) } qs = qs.Where("erp_order.audit_time > ?", parse) } if req.EndTime != "" { // 审核结束时间 parse, err := time.Parse(QueryTimeFormat, req.EndTime) if err != nil { logger.Errorf("err:", err) } qs = qs.Where("erp_order.audit_time <= ?", parse) } var err error if stock.StoreId != 0 { if len(stock.DecisionStoreId) > 1 { err = qs.Select("sum(erp_order_commodity.count) as order_sale").Where("erp_order.retail_type = ? and erp_order.state = ? "+ "and erp_order.store_id in (?) and erp_order.pay_status = ? "+ "and erp_order_commodity.erp_commodity_id = ?", RetailTypeSale, ErpOrderStateAudited, stock.DecisionStoreId, HavePaid, stock.ErpCommodityId).Find(&reportData).Error } else { err = qs.Select("sum(erp_order_commodity.count) as order_sale").Where("erp_order.retail_type = ? and erp_order.state = ? "+ "and erp_order.store_id = ? and erp_order.pay_status = ? "+ "and erp_order_commodity.erp_commodity_id = ?", RetailTypeSale, ErpOrderStateAudited, stock.StoreId, HavePaid, stock.ErpCommodityId).Find(&reportData).Error } } else { err = qs.Select("sum(erp_order_commodity.count) as order_sale").Where("erp_order.retail_type = ? and erp_order.state = ? "+ "and erp_order.pay_status = ? "+ "and erp_order_commodity.erp_commodity_id = ?", RetailTypeSale, ErpOrderStateAudited, HavePaid, stock.ErpCommodityId).Find(&reportData).Error } if err != nil { return DecisionReportData{}, err } return reportData, nil } // 查询零售退货数量 func getSaleReturnCount(req *ErpDecisionReportReq, stock ErpStock) (DecisionReportData, error) { var reportData DecisionReportData qs := orm.Eloquent.Debug().Table("erp_order_commodity") // 进行条件查询 if req.StartTime != "" { // 出入库开始时间 parse, err := time.Parse(QueryTimeFormat, req.StartTime) if err != nil { logger.Errorf("getPurchaseCount err:", err) return DecisionReportData{}, err } qs = qs.Where("erp_order.audit_time > ?", parse) } if req.EndTime != "" { // 出入库结束时间 parse, err := time.Parse(QueryTimeFormat, req.EndTime) if err != nil { logger.Errorf("getPurchaseCount err:", err) return DecisionReportData{}, err } qs = qs.Where("erp_order.audit_time <= ?", parse) } var err error if stock.StoreId != 0 { if len(stock.DecisionStoreId) > 1 { err = qs.Select("SUM(erp_order_commodity.count) AS order_reject"). Joins("JOIN erp_order ON erp_order.id = erp_order_commodity.erp_order_id"). Where("erp_order.retail_type = ? and erp_order.store_id in (?) and erp_order.state = ? "+ "and erp_order_commodity.erp_commodity_id = ?", RetailTypeRejected, stock.DecisionStoreId, ErpOrderStateAudited, stock.ErpCommodityId).Find(&reportData).Error } else { err = qs.Select("SUM(erp_order_commodity.count) AS order_reject"). Joins("JOIN erp_order ON erp_order.id = erp_order_commodity.erp_order_id"). Where("erp_order.retail_type = ? and erp_order.store_id = ? and erp_order.state = ? "+ "and erp_order_commodity.erp_commodity_id = ?", RetailTypeRejected, stock.StoreId, ErpOrderStateAudited, stock.ErpCommodityId).Find(&reportData).Error } } else { err = qs.Select("SUM(erp_order_commodity.count) AS order_reject"). Joins("JOIN erp_order ON erp_order.id = erp_order_commodity.erp_order_id"). Where("erp_order.retail_type = ? and erp_order.state = ? "+ "and erp_order_commodity.erp_commodity_id = ?", RetailTypeRejected, ErpOrderStateAudited, stock.ErpCommodityId).Find(&reportData).Error } if err != nil { return DecisionReportData{}, err } return reportData, nil } // 查询产品入库数量:产品入库 func getProductCount(req *ErpDecisionReportReq, stock ErpStock) (DecisionReportData, error) { var reportData DecisionReportData qs := orm.Eloquent.Debug().Table("erp_stock_commodity") // 进行条件查询 if req.StartTime != "" { // 出入库开始时间 parse, err := time.Parse(QueryTimeFormat, req.StartTime) if err != nil { logger.Errorf("getSystemStartCount err:", err) return DecisionReportData{}, err } qs = qs.Where("created_at > ?", parse) } if req.EndTime != "" { // 出入库结束时间 parse, err := time.Parse(QueryTimeFormat, req.EndTime) if err != nil { logger.Errorf("getSystemStartCount err:", err) return DecisionReportData{}, err } qs = qs.Where("created_at <= ?", parse) } var err error if stock.StoreId != 0 { if len(stock.DecisionStoreId) > 1 { err = qs.Select("SUM(count) as product_in").Where("storage_type = ? and store_id in (?) "+ "and erp_commodity_id = ?", ProductInventory, stock.DecisionStoreId, stock.ErpCommodityId).Find(&reportData).Error } else { err = qs.Select("SUM(count) as product_in").Where("storage_type = ? and store_id = ? "+ "and erp_commodity_id = ?", ProductInventory, stock.StoreId, stock.ErpCommodityId).Find(&reportData).Error } } else { err = qs.Select("SUM(count) as product_in").Where("storage_type = ? "+ "and erp_commodity_id = ?", ProductInventory, stock.ErpCommodityId).Find(&reportData).Error } if err != nil { return DecisionReportData{}, err } return reportData, nil } // 查询盘点入库数量 func getChangeAddCount(req *ErpDecisionReportReq, stock ErpStock) (DecisionReportData, error) { var reportData DecisionReportData qs := orm.Eloquent.Debug().Table("erp_inventory_change_commodity") // 进行条件查询 if req.StartTime != "" { // 出入库开始时间 parse, err := time.Parse(QueryTimeFormat, req.StartTime) if err != nil { logger.Errorf("getChangeAddCount err:", err) return DecisionReportData{}, err } qs = qs.Where("erp_inventory_change_order.updated_at > ?", parse) } if req.EndTime != "" { // 出入库结束时间 parse, err := time.Parse(QueryTimeFormat, req.EndTime) if err != nil { logger.Errorf("getChangeAddCount err:", err) return DecisionReportData{}, err } qs = qs.Where("erp_inventory_change_order.updated_at <= ?", parse) } var err error if stock.StoreId != 0 { if len(stock.DecisionStoreId) > 1 { err = qs.Select("SUM(erp_inventory_change_commodity.count) AS check_in"). Joins("JOIN erp_inventory_change_order "+ "ON erp_inventory_change_order.id = erp_inventory_change_commodity.change_order_id"). Where("erp_inventory_change_order.change_type = ? and erp_inventory_change_order.store_id in (?) "+ "and erp_inventory_change_order.state = ? "+"and erp_inventory_change_commodity.commodity_id = ?", AddChangeOrder, stock.DecisionStoreId, ErpInventoryChangeOrderFinished, stock.ErpCommodityId). Find(&reportData).Error } else { err = qs.Select("SUM(erp_inventory_change_commodity.count) AS check_in"). Joins("JOIN erp_inventory_change_order "+ "ON erp_inventory_change_order.id = erp_inventory_change_commodity.change_order_id"). Where("erp_inventory_change_order.change_type = ? and erp_inventory_change_order.store_id = ? "+ "and erp_inventory_change_order.state = ? "+"and erp_inventory_change_commodity.commodity_id = ?", AddChangeOrder, stock.StoreId, ErpInventoryChangeOrderFinished, stock.ErpCommodityId). Find(&reportData).Error } } else { err = qs.Select("SUM(erp_inventory_change_commodity.count) AS check_in"). Joins("JOIN erp_inventory_change_order "+ "ON erp_inventory_change_order.id = erp_inventory_change_commodity.change_order_id"). Where("erp_inventory_change_order.change_type = ? "+ "and erp_inventory_change_order.state = ? "+"and erp_inventory_change_commodity.commodity_id = ?", AddChangeOrder, ErpInventoryChangeOrderFinished, stock.ErpCommodityId). Find(&reportData).Error } if err != nil { return DecisionReportData{}, err } return reportData, nil } // 查询盘点出库数量 func getChangeReduceCount(req *ErpDecisionReportReq, stock ErpStock) (DecisionReportData, error) { var reportData DecisionReportData qs := orm.Eloquent.Debug().Table("erp_inventory_change_commodity") // 进行条件查询 if req.StartTime != "" { // 出入库开始时间 parse, err := time.Parse(QueryTimeFormat, req.StartTime) if err != nil { logger.Errorf("getChangeAddCount err:", err) return DecisionReportData{}, err } qs = qs.Where("erp_inventory_change_order.updated_at > ?", parse) } if req.EndTime != "" { // 出入库结束时间 parse, err := time.Parse(QueryTimeFormat, req.EndTime) if err != nil { logger.Errorf("getChangeAddCount err:", err) return DecisionReportData{}, err } qs = qs.Where("erp_inventory_change_order.updated_at <= ?", parse) } var err error if stock.StoreId != 0 { if len(stock.DecisionStoreId) > 1 { err = qs.Select("SUM(erp_inventory_change_commodity.count) AS check_out"). Joins("JOIN erp_inventory_change_order "+ "ON erp_inventory_change_order.id = erp_inventory_change_commodity.change_order_id"). Where("erp_inventory_change_order.change_type = ? and erp_inventory_change_order.store_id in (?) "+ "and erp_inventory_change_order.state = ? and erp_inventory_change_commodity.commodity_id = ?", ReduceChangeOrder, stock.DecisionStoreId, ErpInventoryChangeOrderFinished, stock.ErpCommodityId). Find(&reportData).Error } else { err = qs.Select("SUM(erp_inventory_change_commodity.count) AS check_out"). Joins("JOIN erp_inventory_change_order "+ "ON erp_inventory_change_order.id = erp_inventory_change_commodity.change_order_id"). Where("erp_inventory_change_order.change_type = ? and erp_inventory_change_order.store_id = ? "+ "and erp_inventory_change_order.state = ? and erp_inventory_change_commodity.commodity_id = ?", ReduceChangeOrder, stock.StoreId, ErpInventoryChangeOrderFinished, stock.ErpCommodityId). Find(&reportData).Error } } else { err = qs.Select("SUM(erp_inventory_change_commodity.count) AS check_out"). Joins("JOIN erp_inventory_change_order "+ "ON erp_inventory_change_order.id = erp_inventory_change_commodity.change_order_id"). Where("erp_inventory_change_order.change_type = ? "+ "and erp_inventory_change_order.state = ? and erp_inventory_change_commodity.commodity_id = ?", ReduceChangeOrder, ErpInventoryChangeOrderFinished, stock.ErpCommodityId). Find(&reportData).Error } if err != nil { return DecisionReportData{}, err } return reportData, nil } // 查询系统入库数据:系统入库 func getSystemInCount(req *ErpDecisionReportReq, stock ErpStock) (DecisionReportData, error) { var reportData DecisionReportData qs := orm.Eloquent.Debug().Table("erp_stock_commodity") // 进行条件查询 if req.StartTime != "" { // 出入库开始时间 parse, err := time.Parse(QueryTimeFormat, req.StartTime) if err != nil { logger.Errorf("getSystemStartCount err:", err) return DecisionReportData{}, err } qs = qs.Where("created_at > ?", parse) qs = qs.Where("first_stock_time > ?", parse) } if req.EndTime != "" { // 出入库结束时间 parse, err := time.Parse(QueryTimeFormat, req.EndTime) if err != nil { logger.Errorf("getSystemStartCount err:", err) return DecisionReportData{}, err } qs = qs.Where("created_at <= ?", parse) qs = qs.Where("first_stock_time <= ?", parse) } var err error if stock.StoreId != 0 { if len(stock.DecisionStoreId) > 1 { err = qs.Select("SUM(count) as system_in").Where("storage_type = ? and store_id in (?) "+ "and erp_commodity_id = ?", SystemInventory, stock.DecisionStoreId, stock.ErpCommodityId).Find(&reportData).Error } else { err = qs.Select("SUM(count) as system_in").Where("storage_type = ? and store_id = ? "+ "and erp_commodity_id = ?", SystemInventory, stock.StoreId, stock.ErpCommodityId).Find(&reportData).Error } } else { err = qs.Select("SUM(count) as system_in").Where("storage_type = ? "+ "and erp_commodity_id = ?", SystemInventory, stock.ErpCommodityId).Find(&reportData).Error } if err != nil { return DecisionReportData{}, err } return reportData, nil } // 查询系统出库数据:系统出库 func getSystemOutCount(req *ErpDecisionReportReq, stock ErpStock) (DecisionReportData, error) { var reportData DecisionReportData qs := orm.Eloquent.Debug().Table("erp_stock_commodity") // 进行条件查询 if req.StartTime != "" { // 出入库开始时间 parse, err := time.Parse(QueryTimeFormat, req.StartTime) if err != nil { logger.Errorf("getSystemStartCount err:", err) return DecisionReportData{}, err } qs = qs.Where("updated_at > ?", parse) } if req.EndTime != "" { // 出入库结束时间 parse, err := time.Parse(QueryTimeFormat, req.EndTime) if err != nil { logger.Errorf("getSystemStartCount err:", err) return DecisionReportData{}, err } qs = qs.Where("updated_at <= ?", parse) } var err error if stock.StoreId != 0 { if len(stock.DecisionStoreId) > 1 { err = qs.Select("SUM(count) as system_out").Where("state = ? and store_id in (?) "+ "and erp_commodity_id = ?", SystemOut, stock.DecisionStoreId, stock.ErpCommodityId).Find(&reportData).Error } else { err = qs.Select("SUM(count) as system_out").Where("state = ? and store_id = ? "+ "and erp_commodity_id = ?", SystemOut, stock.StoreId, stock.ErpCommodityId).Find(&reportData).Error } } else { err = qs.Select("SUM(count) as system_out").Where("state = ? "+ "and erp_commodity_id = ?", SystemOut, stock.ErpCommodityId).Find(&reportData).Error } if err != nil { return DecisionReportData{}, err } return reportData, nil } // 查询在途库存(入库)数量 func getAllotWaitInCount(req *ErpDecisionReportReq, stock ErpStock) (DecisionReportData, error) { var reportData DecisionReportData qs := orm.Eloquent.Debug().Table("erp_stock_commodity") // 进行条件查询 if req.StartTime != "" { // 出入库开始时间 parse, err := time.Parse(QueryTimeFormat, req.StartTime) if err != nil { logger.Errorf("getSystemStartCount err:", err) return DecisionReportData{}, err } qs = qs.Where("updated_at > ?", parse) } if req.EndTime != "" { // 出入库结束时间 parse, err := time.Parse(QueryTimeFormat, req.EndTime) if err != nil { logger.Errorf("getSystemStartCount err:", err) return DecisionReportData{}, err } qs = qs.Where("updated_at <= ?", parse) } var err error if stock.StoreId != 0 { if len(stock.DecisionStoreId) > 1 { err = qs.Select("SUM(count) as allot_wait_in").Where("state = ? and store_id in (?) "+ "and erp_commodity_id = ?", InAllot, stock.DecisionStoreId, stock.ErpCommodityId).Find(&reportData).Error } else { err = qs.Select("SUM(count) as allot_wait_in").Where("state = ? and store_id = ? "+ "and erp_commodity_id = ?", InAllot, stock.StoreId, stock.ErpCommodityId).Find(&reportData).Error } } else { err = qs.Select("SUM(count) as allot_wait_in").Where("state = ? "+ "and erp_commodity_id = ?", InAllot, stock.ErpCommodityId).Find(&reportData).Error } if err != nil { return DecisionReportData{}, err } return reportData, nil } // 查询在途库存(出库)数量 func getAllotWaitOutCount(req *ErpDecisionReportReq, stock ErpStock) (DecisionReportData, error) { var reportData DecisionReportData qs := orm.Eloquent.Debug().Table("erp_inventory_allot_commodity") // 进行条件查询 if req.StartTime != "" { // 出入库开始时间 parse, err := time.Parse(QueryTimeFormat, req.StartTime) if err != nil { logger.Errorf("getAllotOutCount err:", err) return DecisionReportData{}, err } qs = qs.Where("erp_inventory_allot_commodity.updated_at > ?", parse) } if req.EndTime != "" { // 出入库结束时间 parse, err := time.Parse(QueryTimeFormat, req.EndTime) if err != nil { logger.Errorf("getAllotOutCount err:", err) return DecisionReportData{}, err } qs = qs.Where("erp_inventory_allot_commodity.updated_at <= ?", parse) } var err error if stock.StoreId != 0 { if len(stock.DecisionStoreId) > 1 { err = qs.Select("SUM(erp_inventory_allot_commodity.count) AS allot_wait_out"). Joins("JOIN erp_inventory_allot_order "+ "ON erp_inventory_allot_order.id = erp_inventory_allot_commodity.allot_order_id"). Where("erp_inventory_allot_order.deliver_store_id in (?) and erp_inventory_allot_order.state in (?) "+ "and erp_inventory_allot_commodity.commodity_id = ?", stock.DecisionStoreId, []uint32{ErpInventoryAllotOrderWaitSend, ErpInventoryAllotOrderWaitReceive}, stock.ErpCommodityId). Find(&reportData).Error } else { err = qs.Select("SUM(erp_inventory_allot_commodity.count) AS allot_wait_out"). Joins("JOIN erp_inventory_allot_order "+ "ON erp_inventory_allot_order.id = erp_inventory_allot_commodity.allot_order_id"). Where("erp_inventory_allot_order.deliver_store_id = ? and erp_inventory_allot_order.state in (?) "+ "and erp_inventory_allot_commodity.commodity_id = ?", stock.StoreId, []uint32{ErpInventoryAllotOrderWaitSend, ErpInventoryAllotOrderWaitReceive}, stock.ErpCommodityId). Find(&reportData).Error } } else { err = qs.Select("SUM(erp_inventory_allot_commodity.count) AS allot_wait_out"). Joins("JOIN erp_inventory_allot_order "+ "ON erp_inventory_allot_order.id = erp_inventory_allot_commodity.allot_order_id"). Where("erp_inventory_allot_order.state in (?) "+ "and erp_inventory_allot_commodity.commodity_id = ?", []uint32{ErpInventoryAllotOrderWaitSend, ErpInventoryAllotOrderWaitReceive}, stock.ErpCommodityId). Find(&reportData).Error } if err != nil { return DecisionReportData{}, err } return reportData, nil } // 查询调拨入库数量 func getAllotInCount(req *ErpDecisionReportReq, stock ErpStock) (DecisionReportData, error) { var reportData DecisionReportData qs := orm.Eloquent.Debug().Table("erp_inventory_allot_commodity") // 进行条件查询 if req.StartTime != "" { // 出入库开始时间 parse, err := time.Parse(QueryTimeFormat, req.StartTime) if err != nil { logger.Errorf("getChangeAddCount err:", err) return DecisionReportData{}, err } qs = qs.Where("erp_inventory_allot_commodity.updated_at > ?", parse) } if req.EndTime != "" { // 出入库结束时间 parse, err := time.Parse(QueryTimeFormat, req.EndTime) if err != nil { logger.Errorf("getChangeAddCount err:", err) return DecisionReportData{}, err } qs = qs.Where("erp_inventory_allot_commodity.updated_at <= ?", parse) } var err error if stock.StoreId != 0 { if len(stock.DecisionStoreId) > 1 { err = qs.Select("SUM(erp_inventory_allot_commodity.count) AS allot_in"). Joins("JOIN erp_inventory_allot_order "+ "ON erp_inventory_allot_order.id = erp_inventory_allot_commodity.allot_order_id"). Where("erp_inventory_allot_order.receive_store_id in (?) and erp_inventory_allot_order.state = ? "+ "and erp_inventory_allot_commodity.commodity_id = ?", stock.DecisionStoreId, ErpInventoryAllotOrderFinished, stock.ErpCommodityId). Find(&reportData).Error } else { err = qs.Select("SUM(erp_inventory_allot_commodity.count) AS allot_in"). Joins("JOIN erp_inventory_allot_order "+ "ON erp_inventory_allot_order.id = erp_inventory_allot_commodity.allot_order_id"). Where("erp_inventory_allot_order.receive_store_id = ? and erp_inventory_allot_order.state = ? "+ "and erp_inventory_allot_commodity.commodity_id = ?", stock.StoreId, ErpInventoryAllotOrderFinished, stock.ErpCommodityId). Find(&reportData).Error } } else { err = qs.Select("SUM(erp_inventory_allot_commodity.count) AS allot_in"). Joins("JOIN erp_inventory_allot_order "+ "ON erp_inventory_allot_order.id = erp_inventory_allot_commodity.allot_order_id"). Where("erp_inventory_allot_order.state = ? "+ "and erp_inventory_allot_commodity.commodity_id = ?", ErpInventoryAllotOrderFinished, stock.ErpCommodityId). Find(&reportData).Error } if err != nil { return DecisionReportData{}, err } return reportData, nil } // 查询调拨出库数量 func getAllotOutCount(req *ErpDecisionReportReq, stock ErpStock) (DecisionReportData, error) { var reportData DecisionReportData qs := orm.Eloquent.Debug().Table("erp_inventory_allot_commodity") // 进行条件查询 if req.StartTime != "" { // 出入库开始时间 parse, err := time.Parse(QueryTimeFormat, req.StartTime) if err != nil { logger.Errorf("getAllotOutCount err:", err) return DecisionReportData{}, err } qs = qs.Where("erp_inventory_allot_commodity.updated_at > ?", parse) } if req.EndTime != "" { // 出入库结束时间 parse, err := time.Parse(QueryTimeFormat, req.EndTime) if err != nil { logger.Errorf("getAllotOutCount err:", err) return DecisionReportData{}, err } qs = qs.Where("erp_inventory_allot_commodity.updated_at <= ?", parse) } var err error if stock.StoreId != 0 { if len(stock.DecisionStoreId) > 1 { err = qs.Select("SUM(erp_inventory_allot_commodity.count) AS allot_out"). Joins("JOIN erp_inventory_allot_order "+ "ON erp_inventory_allot_order.id = erp_inventory_allot_commodity.allot_order_id"). Where("erp_inventory_allot_order.deliver_store_id in (?) and erp_inventory_allot_order.state = ? "+ "and erp_inventory_allot_commodity.commodity_id = ?", stock.DecisionStoreId, ErpInventoryAllotOrderFinished, stock.ErpCommodityId). Find(&reportData).Error } else { err = qs.Select("SUM(erp_inventory_allot_commodity.count) AS allot_out"). Joins("JOIN erp_inventory_allot_order "+ "ON erp_inventory_allot_order.id = erp_inventory_allot_commodity.allot_order_id"). Where("erp_inventory_allot_order.deliver_store_id = ? and erp_inventory_allot_order.state = ? "+ "and erp_inventory_allot_commodity.commodity_id = ?", stock.StoreId, ErpInventoryAllotOrderFinished, stock.ErpCommodityId). Find(&reportData).Error } } else { err = qs.Select("SUM(erp_inventory_allot_commodity.count) AS allot_out"). Joins("JOIN erp_inventory_allot_order "+ "ON erp_inventory_allot_order.id = erp_inventory_allot_commodity.allot_order_id"). Where("erp_inventory_allot_order.state = ? "+ "and erp_inventory_allot_commodity.commodity_id = ?", ErpInventoryAllotOrderFinished, stock.ErpCommodityId). Find(&reportData).Error } if err != nil { return DecisionReportData{}, err } return reportData, nil } // 查询期初库存 func getSumStartData(req *ErpDecisionReportReq) (DecisionReportData, error) { if req.StartTime == "" || req.EndTime == "" { return DecisionReportData{}, nil } tempReq1 := *req tempReq := &tempReq1 tempReq.EndTime = time.Now().Format(QueryTimeFormat) var respData DecisionReportData // 期末库存 sumEndData, err := getSumEndCount(tempReq) if err != nil { return DecisionReportData{}, err } // 查询库存汇总数据:采购退货数量、产品入库、系统入库、系统出库、在途库存(入库)数量 sumStockData, err := getSumStockData(tempReq, false) if err != nil { return DecisionReportData{}, err } // 查询采购进货数量 sumPurchaseData, err := getSumPurchaseData(tempReq, false) if err != nil { return DecisionReportData{}, err } // 查询零售汇总数据:零售销售数量、零售退货数量 sumSalesData, err := getSumSalesData(tempReq, false) if err != nil { return DecisionReportData{}, err } // 查询盘点汇总数据:盘点入库数量、盘点出库数量 sumInventoryData, err := getSumInventoryData(tempReq, false) if err != nil { return DecisionReportData{}, err } // 查询调拨汇总数据:在途库存(出库)数量、调拨入库数量、调拨出库数量 sumAllotData, err := getSumAllotData(tempReq, false) if err != nil { return DecisionReportData{}, err } respData.BeginStock = sumEndData.EndStock + (sumSalesData.OrderSale - sumSalesData.OrderReject) + sumAllotData.AllotOut + sumStockData.SystemOut + sumInventoryData.CheckOut - (sumPurchaseData.PurchaseStock - sumStockData.PurchaseReturn) - sumAllotData.AllotIn - sumStockData.ProductIn - sumInventoryData.CheckIn respData.BeginAmount = sumEndData.EndAmount + ((sumSalesData.OrderSaleAmount - sumSalesData.OrderRejectAmount) + sumAllotData.AllotOutAmount + sumStockData.SystemOutAmount + sumInventoryData.CheckOutAmount) - ((sumPurchaseData.PurchaseStockAmount - sumStockData.PurchaseReturnAmount) + sumAllotData.AllotInAmount + sumStockData.ProductInAmount + sumInventoryData.CheckInAmount) return respData, nil } // 查询汇总数据:期初库存,期初金额 // 期初库存 = 目前在库的数据 + 期初之后的出库(销售、调拨出库、系统出库、盘点出库)-期初之后的入库(采购、调拨入库、产品入库、盘点入库) func getSumStartCount(req *ErpDecisionReportReq) (DecisionReportData, error) { var reportData DecisionReportData if req.StartTime != "" { // 有开始时间 startTime, err := time.Parse(QueryTimeFormat, req.StartTime) if err != nil { logger.Errorf("getSystemStartCount err:", err) return DecisionReportData{}, err } // 计算开始时间的前一天 //previousDay := startTime.AddDate(0, 0, -1) previousDay := startTime.AddDate(0, 0, -1).Truncate(24 * time.Hour). Add(23*time.Hour + 59*time.Minute + 59*time.Second) // 获取系统入库数量 var systemStartData DecisionReportData qs := orm.Eloquent.Debug().Table("erp_stock_commodity"). Select("SUM(count) as begin_stock, SUM(wholesale_price) as begin_amount"). Where("storage_type = ?", SystemInventory). Where("first_stock_time <= ?", previousDay) // 获取开始时间前一天的所有出库数量(包括销售出库、系统出库和盘点出库) var outStockData struct { SoldOut uint32 `json:"sold_out"` SoldOutAmount float64 `json:"sold_out_amount"` SystemOut uint32 `json:"system_out"` SystemOutAmount float64 `json:"system_out_amount"` CheckOut uint32 `json:"check_out"` CheckOutAmount float64 `json:"check_out_amount"` } es := orm.Eloquent.Debug().Table("erp_stock_commodity"). Select("SUM(CASE WHEN state = ? THEN count ELSE 0 END) AS sold_out, "+ "SUM(CASE WHEN state = ? THEN wholesale_price ELSE 0 END) AS sold_out_amount, "+ "SUM(CASE WHEN state = ? THEN count ELSE 0 END) AS system_out, "+ "SUM(CASE WHEN state = ? THEN wholesale_price ELSE 0 END) AS system_out_amount, "+ "SUM(CASE WHEN state = ? THEN count ELSE 0 END) AS check_out, "+ "SUM(CASE WHEN state = ? THEN wholesale_price ELSE 0 END) AS check_out_amount", SoldOut, SoldOut, SystemOut, SystemOut, CheckOut, CheckOut). Where("updated_at <= ?", previousDay). Where("state IN (?)", []int{SoldOut, SystemOut, CheckOut}) // 获取开始时间前一天的所有入库数量(包括采购入库、产品入库和盘点入库) var inStockData struct { PurchaseIn uint32 `json:"purchase_in"` PurchaseInAmount float64 `json:"purchase_in_amount"` ProductIn uint32 `json:"product_in"` ProductInAmount float64 `json:"product_in_amount"` CheckIn uint32 `json:"check_in"` CheckInAmount float64 `json:"check_in_amount"` } ts := orm.Eloquent.Debug().Table("erp_stock_commodity"). Select("SUM(CASE WHEN storage_type = ? THEN count ELSE 0 END) AS purchase_in, "+ "SUM(CASE WHEN storage_type = ? THEN wholesale_price ELSE 0 END) AS purchase_in_amount, "+ "SUM(CASE WHEN storage_type = ? THEN count ELSE 0 END) AS product_in, "+ "SUM(CASE WHEN storage_type = ? THEN wholesale_price ELSE 0 END) AS product_in_amount, "+ "SUM(CASE WHEN storage_type = ? THEN count ELSE 0 END) AS check_in, "+ "SUM(CASE WHEN storage_type = ? THEN wholesale_price ELSE 0 END) AS check_in_amount", PurchaseInventory, PurchaseInventory, ProductInventory, ProductInventory, CheckInventory, CheckInventory). Where("created_at <= ?", previousDay) // 调拨入库数量和金额 var allotInData struct { AllotIn uint32 `json:"allot_in"` AllotInAmount float64 `json:"allot_in_amount"` } allotInQuery := orm.Eloquent.Debug().Table("erp_inventory_allot_commodity"). Select("SUM(erp_inventory_allot_commodity.count) AS allot_in, "+ "SUM(erp_inventory_allot_commodity.amount) AS allot_in_amount"). Joins("JOIN erp_inventory_allot_order "+ "ON erp_inventory_allot_order.id = erp_inventory_allot_commodity.allot_order_id"). Where("erp_inventory_allot_order.state = ?", ErpInventoryAllotOrderFinished). Where("erp_inventory_allot_order.receive_time <= ?", previousDay) // 调拨出库数量和金额 var allotOutData struct { AllotOut uint32 `json:"allot_out"` AllotOutAmount float64 `json:"allot_out_amount"` } allotOutQuery := orm.Eloquent.Debug().Table("erp_inventory_allot_commodity"). Select("SUM(erp_inventory_allot_commodity.count) AS allot_out, "+ "SUM(erp_inventory_allot_commodity.amount) AS allot_out_amount"). Joins("JOIN erp_inventory_allot_order "+ "ON erp_inventory_allot_order.id = erp_inventory_allot_commodity.allot_order_id"). Where("erp_inventory_allot_order.state = ?", ErpInventoryAllotOrderFinished). Where("erp_inventory_allot_order.receive_time <= ?", previousDay) if len(req.StoreId) > 0 { // 门店复选 var storeIDs []uint32 for _, store := range req.StoreId { storeIDs = append(storeIDs, store) } if len(storeIDs) == 1 { qs = qs.Where("store_id = ?", storeIDs[0]) es = es.Where("store_id = ?", storeIDs[0]) ts = ts.Where("store_id = ?", storeIDs[0]) allotInQuery = allotInQuery.Where("erp_inventory_allot_order.receive_store_id = ?", storeIDs[0]) allotOutQuery = allotOutQuery.Where("erp_inventory_allot_order.deliver_store_id = ?", storeIDs[0]) } else { qs = qs.Where("store_id IN (?)", storeIDs) es = es.Where("store_id IN (?)", storeIDs) ts = ts.Where("store_id IN (?)", storeIDs) allotInQuery = allotInQuery.Where("erp_inventory_allot_order.receive_store_id IN (?)", storeIDs) allotOutQuery = allotOutQuery.Where("erp_inventory_allot_order.deliver_store_id IN (?)", storeIDs) } } if len(req.CommodityName) > 0 { // 商品名称 var commodityNames []string for _, commodityName := range req.CommodityName { commodityNames = append(commodityNames, commodityName) } if len(commodityNames) == 1 { qs = qs.Where("erp_commodity_name = ?", commodityNames[0]) es = es.Where("erp_commodity_name = ?", commodityNames[0]) ts = ts.Where("erp_commodity_name = ?", commodityNames[0]) allotOutQuery = allotOutQuery.Where("erp_commodity_name = ?", commodityNames[0]) allotInQuery = allotInQuery.Where("erp_commodity_name = ?", commodityNames[0]) } else { qs = qs.Where("erp_commodity_name IN (?)", commodityNames) es = es.Where("erp_commodity_name IN (?)", commodityNames) ts = ts.Where("erp_commodity_name IN (?)", commodityNames) allotOutQuery = allotOutQuery.Where("erp_commodity_name IN (?)", commodityNames) allotInQuery = allotInQuery.Where("erp_commodity_name IN (?)", commodityNames) } } if len(req.CategoryID) > 0 { // 商品分类id var categoryIDs []uint32 for _, category := range req.CategoryID { categoryIDs = append(categoryIDs, category) } if len(categoryIDs) == 1 { qs = qs.Where("erp_category_id = ?", categoryIDs[0]) es = es.Where("erp_category_id = ?", categoryIDs[0]) ts = ts.Where("erp_category_id = ?", categoryIDs[0]) allotOutQuery = allotOutQuery.Where("erp_category_id = ?", categoryIDs[0]) allotInQuery = allotInQuery.Where("erp_category_id = ?", categoryIDs[0]) } else { qs = qs.Where("erp_category_id IN (?)", categoryIDs) es = es.Where("erp_category_id IN (?)", categoryIDs) ts = ts.Where("erp_category_id IN (?)", categoryIDs) allotOutQuery = allotOutQuery.Where("erp_category_id IN (?)", categoryIDs) allotInQuery = allotInQuery.Where("erp_category_id IN (?)", categoryIDs) } } err = qs.Find(&systemStartData).Error if err != nil { return DecisionReportData{}, err } err = es.Find(&outStockData).Error if err != nil { return DecisionReportData{}, err } err = ts.Find(&inStockData).Error if err != nil { return DecisionReportData{}, err } err = allotInQuery.Find(&allotInData).Error // 查询调拨入库 if err != nil { return DecisionReportData{}, err } err = allotOutQuery.Find(&allotOutData).Error // 查询调拨出库 if err != nil { return DecisionReportData{}, err } // 计算期初库存 beginStock := int64(systemStartData.BeginStock) - int64(outStockData.SoldOut) - int64(outStockData.SystemOut) - int64(outStockData.CheckOut) - int64(allotOutData.AllotOut) + int64(allotInData.AllotIn) + int64(inStockData.PurchaseIn) + int64(inStockData.ProductIn) + int64(inStockData.CheckIn) if beginStock < 0 { beginStock = 0 // 确保库存不会为负 } // 计算期初金额 beginAmount := systemStartData.BeginAmount - outStockData.SoldOutAmount - outStockData.SystemOutAmount - outStockData.CheckOutAmount - allotOutData.AllotOutAmount + allotInData.AllotInAmount + inStockData.PurchaseInAmount + inStockData.ProductInAmount + inStockData.CheckInAmount if beginAmount < 0 { beginAmount = 0 // 确保库存不会为负 } reportData.BeginStock = uint32(beginStock) reportData.BeginAmount = beginAmount } else { //// 如果没有开始时间,直接获取系统入库数量作为期初库存 //qs := orm.Eloquent.Debug().Table("erp_stock_commodity"). // Select("SUM(count) as begin_stock, SUM(wholesale_price) as begin_amount"). // Where("storage_type = ?", SystemInventory) // //if len(req.StoreId) > 0 { // 门店复选 // var storeIDs []uint32 // for _, store := range req.StoreId { // storeIDs = append(storeIDs, store) // } // if len(storeIDs) == 1 { // qs = qs.Where("store_id IN = ?", storeIDs[0]) // } else { // qs = qs.Where("store_id IN (?)", storeIDs) // } //} // //if len(req.CommodityName) > 0 { // 商品名称 // var commodityNames []string // for _, commodityName := range req.CommodityName { // commodityNames = append(commodityNames, commodityName) // } // if len(commodityNames) == 1 { // qs = qs.Where("erp_commodity_name = ?", commodityNames[0]) // } else { // qs = qs.Where("erp_commodity_name IN (?)", commodityNames) // } //} // //if len(req.CategoryID) > 0 { // 商品分类id // var categoryIDs []uint32 // for _, category := range req.CategoryID { // categoryIDs = append(categoryIDs, category) // } // if len(categoryIDs) == 1 { // qs = qs.Where("erp_category_id = ?", categoryIDs[0]) // } else { // qs = qs.Where("erp_category_id IN (?)", categoryIDs) // } //} // //err := qs.Find(&reportData).Error //if err != nil { // return DecisionReportData{}, err //} } return reportData, nil } // 查询汇总数据:期末库存,期末金额 func getSumEndCount(req *ErpDecisionReportReq) (DecisionReportData, error) { var reportData DecisionReportData qs := orm.Eloquent.Debug().Table("erp_stock_commodity") es := orm.Eloquent.Debug().Table("erp_stock_commodity") if len(req.StoreId) > 0 { // 门店复选 var storeIDs []uint32 for _, store := range req.StoreId { storeIDs = append(storeIDs, store) } if len(storeIDs) == 1 { qs = qs.Where("store_id = ?", storeIDs[0]) es = es.Where("store_id = ?", storeIDs[0]) } else { qs = qs.Where("store_id IN (?)", storeIDs) es = es.Where("store_id IN (?)", storeIDs) } } if len(req.CommodityName) > 0 { // 商品名称 var commodityNames []string for _, commodityName := range req.CommodityName { commodityNames = append(commodityNames, commodityName) } if len(commodityNames) == 1 { qs = qs.Where("erp_commodity_name = ?", commodityNames[0]) es = es.Where("erp_commodity_name = ?", commodityNames[0]) } else { qs = qs.Where("erp_commodity_name IN (?)", commodityNames) es = es.Where("erp_commodity_name IN (?)", commodityNames) } } if len(req.CategoryID) > 0 { // 商品分类id var categoryIDs []uint32 for _, category := range req.CategoryID { categoryIDs = append(categoryIDs, category) } if len(categoryIDs) == 1 { qs = qs.Where("erp_category_id = ?", categoryIDs[0]) es = es.Where("erp_category_id = ?", categoryIDs[0]) } else { qs = qs.Where("erp_category_id IN (?)", categoryIDs) es = es.Where("erp_category_id IN (?)", categoryIDs) } } //if req.EndTime != "" { // 有结束时间 // endTime, err := time.Parse(QueryTimeFormat, req.EndTime) // if err != nil { // logger.Errorf("getSystemEndCount err:", err) // return DecisionReportData{}, err // } // // // 获取结束时间之前的所有入库数量(包括系统入库、采购入库、产品入库和盘点入库) // var inStockData struct { // SystemIn uint32 `json:"system_in"` // SystemInAmount float64 `json:"system_in_amount"` // PurchaseIn uint32 `json:"purchase_in"` // PurchaseInAmount float64 `json:"purchase_in_amount"` // ProductIn uint32 `json:"product_in"` // ProductInAmount float64 `json:"product_in_amount"` // CheckIn uint32 `json:"check_in"` // CheckInAmount float64 `json:"check_in_amount"` // } // qs = qs.Select("SUM(CASE WHEN storage_type = ? THEN count ELSE 0 END) AS system_in, "+ // "SUM(CASE WHEN storage_type = ? THEN wholesale_price ELSE 0 END) AS system_in_amount, "+ // "SUM(CASE WHEN storage_type = ? THEN count ELSE 0 END) AS purchase_in, "+ // "SUM(CASE WHEN storage_type = ? THEN wholesale_price ELSE 0 END) AS purchase_in_amount, "+ // "SUM(CASE WHEN storage_type = ? THEN count ELSE 0 END) AS product_in, "+ // "SUM(CASE WHEN storage_type = ? THEN wholesale_price ELSE 0 END) AS product_in_amount, "+ // "SUM(CASE WHEN storage_type = ? THEN count ELSE 0 END) AS check_in, "+ // "SUM(CASE WHEN storage_type = ? THEN wholesale_price ELSE 0 END) AS check_in_amount", // SystemInventory, SystemInventory, PurchaseInventory, PurchaseInventory, ProductInventory, ProductInventory, // CheckInventory, CheckInventory). // Where("updated_at <= ?", endTime) // // err = qs.Find(&inStockData).Error // if err != nil { // return DecisionReportData{}, err // } // // // 获取结束时间之前的所有出库数量(包括销售出库、系统出库和盘点出库) // var outStockData struct { // SoldOut uint32 `json:"sold_out"` // SoldOutAmount float64 `json:"sold_out_amount"` // SystemOut uint32 `json:"system_out"` // SystemOutAmount float64 `json:"system_out_amount"` // CheckOut uint32 `json:"check_out"` // CheckOutAmount float64 `json:"check_out_amount"` // } // es = es.Select("SUM(CASE WHEN state = ? THEN count ELSE 0 END) AS sold_out, "+ // "SUM(CASE WHEN state = ? THEN wholesale_price ELSE 0 END) AS sold_out_amount, "+ // "SUM(CASE WHEN state = ? THEN count ELSE 0 END) AS system_out, "+ // "SUM(CASE WHEN state = ? THEN wholesale_price ELSE 0 END) AS system_out_amount, "+ // "SUM(CASE WHEN state = ? THEN count ELSE 0 END) AS check_out, "+ // "SUM(CASE WHEN state = ? THEN wholesale_price ELSE 0 END) AS check_out_amount", // SoldOut, SoldOut, SystemOut, SystemOut, CheckOut, CheckOut). // Where("updated_at <= ?", endTime). // Where("state IN (?)", []int{SoldOut, SystemOut, CheckOut}) // // err = es.Find(&outStockData).Error // if err != nil { // return DecisionReportData{}, err // } // // // 计算期末库存 // endStock := int64(inStockData.SystemIn) + int64(inStockData.PurchaseIn) + int64(inStockData.ProductIn) + int64(inStockData.CheckIn) - // int64(outStockData.SoldOut) - int64(outStockData.SystemOut) - int64(outStockData.CheckOut) // // if endStock < 0 { // endStock = 0 // 确保库存不会为负 // } // // // 计算期末金额 // endAmount := inStockData.SystemInAmount + inStockData.PurchaseInAmount + inStockData.ProductInAmount + // inStockData.CheckInAmount - outStockData.SoldOutAmount - outStockData.SystemOutAmount - // outStockData.CheckOutAmount // if endAmount < 0 { // endAmount = 0 // } // // reportData.EndStock = uint32(endStock) // reportData.EndAmount = endAmount //} else { // // 如果没有结束时间,直接获取系统在库数量作为期末库存 // qs = qs.Select("SUM(count) as end_stock, SUM(wholesale_price) as end_amount"). // Where("state in (?)", []uint32{InStock, InAllot}).Find(&reportData) // // err := qs.Find(&reportData).Error // if err != nil { // return DecisionReportData{}, err // } //} // 直接获取系统在库数量作为期末库存 qs = qs.Select("SUM(count) as end_stock, SUM(wholesale_price) as end_amount"). Where("state in (?)", []uint32{InStock, InAllot}).Find(&reportData) err := qs.Find(&reportData).Error if err != nil { return DecisionReportData{}, err } return reportData, nil } // 查询库存汇总数据:采购退货数量、产品入库、系统入库、系统出库、在途库存(入库)数量 func getSumStockData(req *ErpDecisionReportReq, endTimeFlag bool) (DecisionReportData, error) { var reportData DecisionReportData qs := orm.Eloquent.Debug().Table("erp_stock_commodity") if req.StartTime != "" { parse, err := time.Parse(QueryTimeFormat, req.StartTime) if err != nil { logger.Errorf("getStockData err:", err) return DecisionReportData{}, err } qs = qs.Where("created_at > ?", parse) } if req.EndTime != "" && endTimeFlag { parse, err := time.Parse(QueryTimeFormat, req.EndTime) if err != nil { logger.Errorf("getStockData err:", err) return DecisionReportData{}, err } qs = qs.Where("created_at <= ?", parse) } if len(req.StoreId) > 0 { if len(req.StoreId) == 1 { qs = qs.Where("store_id = ?", req.StoreId[0]) } else { qs = qs.Where("store_id IN (?)", req.StoreId) } } if len(req.CommodityName) > 0 { // 商品名称 var commodityNames []string for _, commodityName := range req.CommodityName { commodityNames = append(commodityNames, commodityName) } if len(commodityNames) == 1 { qs = qs.Where("erp_commodity_name = ?", commodityNames[0]) } else { qs = qs.Where("erp_commodity_name IN (?)", commodityNames) } } if len(req.CategoryID) > 0 { // 商品分类id var categoryIDs []uint32 for _, category := range req.CategoryID { categoryIDs = append(categoryIDs, category) } if len(categoryIDs) == 1 { qs = qs.Where("erp_category_id = ?", categoryIDs[0]) } else { qs = qs.Where("erp_category_id IN (?)", categoryIDs) } } subQuery := qs.Select(` SUM(CASE WHEN state = ? THEN count ELSE 0 END) AS purchase_return, SUM(CASE WHEN state = ? THEN wholesale_price ELSE 0 END) AS purchase_return_amount, SUM(CASE WHEN storage_type = ? THEN count ELSE 0 END) AS product_in, SUM(CASE WHEN storage_type = ? THEN wholesale_price ELSE 0 END) AS product_in_amount, SUM(CASE WHEN storage_type = ? THEN count ELSE 0 END) AS system_in, SUM(CASE WHEN storage_type = ? THEN wholesale_price ELSE 0 END) AS system_in_amount, SUM(CASE WHEN state = ? THEN count ELSE 0 END) AS system_out, SUM(CASE WHEN state = ? THEN wholesale_price ELSE 0 END) AS system_out_amount, SUM(CASE WHEN state = ? THEN count ELSE 0 END) AS allot_wait_in, SUM(CASE WHEN state = ? THEN wholesale_price ELSE 0 END) AS allot_wait_in_amount `, PurchaseCancel, PurchaseCancel, ProductInventory, ProductInventory, SystemInventory, SystemInventory, SystemOut, SystemOut, InAllot, InAllot) err := subQuery.Scan(&reportData).Error if err != nil { logger.Errorf("getStockData err:", err) return DecisionReportData{}, err } return reportData, nil } // 查询采购进货数量 func getSumPurchaseData(req *ErpDecisionReportReq, endTimeFlag bool) (DecisionReportData, error) { var reportData DecisionReportData qs := orm.Eloquent.Debug().Table("erp_purchase_inventory") // 进行条件查询 if req.StartTime != "" { // 出入库开始时间 parse, err := time.Parse(QueryTimeFormat, req.StartTime) if err != nil { logger.Errorf("getPurchaseCount err:", err) return DecisionReportData{}, err } qs = qs.Where("erp_purchase_inventory.created_at > ?", parse) } if req.EndTime != "" && endTimeFlag { // 出入库结束时间 parse, err := time.Parse(QueryTimeFormat, req.EndTime) if err != nil { logger.Errorf("getPurchaseCount err:", err) return DecisionReportData{}, err } qs = qs.Where("erp_purchase_inventory.created_at <= ?", parse) } if len(req.StoreId) > 0 { if len(req.StoreId) == 1 { qs = qs.Where("store_id = ?", req.StoreId[0]) } else { qs = qs.Where("store_id IN (?)", req.StoreId) } } if len(req.CommodityName) > 0 { // 商品名称 var commodityNames []string for _, commodityName := range req.CommodityName { commodityNames = append(commodityNames, commodityName) } if len(commodityNames) == 1 { qs = qs.Where("erp_commodity_name = ?", commodityNames[0]) } else { qs = qs.Where("erp_commodity_name IN (?)", commodityNames) } } if len(req.CategoryID) > 0 { // 商品分类id var categoryIDs []uint32 for _, category := range req.CategoryID { categoryIDs = append(categoryIDs, category) } if len(categoryIDs) == 1 { qs = qs.Where("erp_category_id = ?", categoryIDs[0]) } else { qs = qs.Where("erp_category_id IN (?)", categoryIDs) } } var err error err = qs.Select("SUM(erp_purchase_inventory.count) AS purchase_stock,"+ "SUM(erp_purchase_inventory.amount) AS purchase_stock_amount"). Joins("JOIN erp_purchase_order ON erp_purchase_order.id = erp_purchase_inventory.erp_purchase_order_id"). Where("erp_purchase_inventory.purchase_type = ?", ErpProcureOrder). Find(&reportData).Error if err != nil { return DecisionReportData{}, err } return reportData, nil } // 查询零售汇总数据:零售销售数量、零售退货数量 func getSumSalesData(req *ErpDecisionReportReq, endTimeFlag bool) (DecisionReportData, error) { var reportData DecisionReportData qs := orm.Eloquent.Debug().Table("erp_order_commodity"). Joins("JOIN erp_order ON erp_order_commodity.erp_order_id = erp_order.id") if req.StartTime != "" { parse, err := time.Parse(QueryTimeFormat, req.StartTime) if err != nil { logger.Errorf("getSalesAndReturns err:", err) return DecisionReportData{}, err } qs = qs.Where("erp_order.audit_time > ?", parse) } if req.EndTime != "" && endTimeFlag { parse, err := time.Parse(QueryTimeFormat, req.EndTime) if err != nil { logger.Errorf("getSalesAndReturns err:", err) return DecisionReportData{}, err } qs = qs.Where("erp_order.audit_time <= ?", parse) } if len(req.StoreId) > 0 { if len(req.StoreId) == 1 { qs = qs.Where("store_id = ?", req.StoreId[0]) } else { qs = qs.Where("store_id IN (?)", req.StoreId) } } if len(req.CommodityName) > 0 { // 商品名称 var commodityNames []string for _, commodityName := range req.CommodityName { commodityNames = append(commodityNames, commodityName) } if len(commodityNames) == 1 { qs = qs.Where("erp_commodity_name = ?", commodityNames[0]) } else { qs = qs.Where("erp_commodity_name IN (?)", commodityNames) } } if len(req.CategoryID) > 0 { // 商品分类id var categoryIDs []uint32 for _, category := range req.CategoryID { categoryIDs = append(categoryIDs, category) } if len(categoryIDs) == 1 { qs = qs.Where("erp_category_id = ?", categoryIDs[0]) } else { qs = qs.Where("erp_category_id IN (?)", categoryIDs) } } subQuery := qs.Select(` SUM(CASE WHEN erp_order.retail_type = ? AND erp_order.state = ? AND erp_order.pay_status = ? THEN erp_order_commodity.count ELSE 0 END) AS order_sale, SUM(CASE WHEN erp_order.retail_type = ? AND erp_order.state = ? AND erp_order.pay_status = ? THEN erp_order_commodity.wholesale_price ELSE 0 END) AS order_sale_amount, SUM(CASE WHEN erp_order.retail_type = ? AND erp_order.state = ? THEN erp_order_commodity.count ELSE 0 END) AS order_reject, SUM(CASE WHEN erp_order.retail_type = ? AND erp_order.state = ? THEN erp_order_commodity.wholesale_price ELSE 0 END) AS order_reject_amount `, RetailTypeSale, ErpOrderStateAudited, HavePaid, RetailTypeSale, ErpOrderStateAudited, HavePaid, RetailTypeRejected, ErpOrderStateAudited, RetailTypeRejected, ErpOrderStateAudited) err := subQuery.Scan(&reportData).Error if err != nil { logger.Errorf("getSalesAndReturns err:", err) return DecisionReportData{}, err } return reportData, nil } // 查询盘点汇总数据:盘点入库数量、盘点出库数量 func getSumInventoryData(req *ErpDecisionReportReq, endTimeFlag bool) (DecisionReportData, error) { var reportData DecisionReportData qs := orm.Eloquent.Debug().Table("erp_inventory_change_commodity"). Joins("JOIN erp_inventory_change_order " + "ON erp_inventory_change_order.id = erp_inventory_change_commodity.change_order_id") if req.StartTime != "" { parse, err := time.Parse(QueryTimeFormat, req.StartTime) if err != nil { logger.Errorf("getInventoryChanges err:", err) return DecisionReportData{}, err } qs = qs.Where("erp_inventory_change_order.audit_time > ?", parse) } if req.EndTime != "" && endTimeFlag { parse, err := time.Parse(QueryTimeFormat, req.EndTime) if err != nil { logger.Errorf("getInventoryChanges err:", err) return DecisionReportData{}, err } qs = qs.Where("erp_inventory_change_order.audit_time <= ?", parse) } if len(req.StoreId) > 0 { if len(req.StoreId) == 1 { qs = qs.Where("erp_inventory_change_order.store_id = ?", req.StoreId[0]) } else { qs = qs.Where("erp_inventory_change_order.store_id IN (?)", req.StoreId) } } if len(req.CommodityName) > 0 { // 商品名称 var commodityNames []string for _, commodityName := range req.CommodityName { commodityNames = append(commodityNames, commodityName) } if len(commodityNames) == 1 { qs = qs.Where("erp_inventory_change_commodity.commodity_name = ?", commodityNames[0]) } else { qs = qs.Where("erp_inventory_change_commodity.commodity_name IN (?)", commodityNames) } } subQuery := qs.Select(` SUM(CASE WHEN erp_inventory_change_order.change_type = ? AND erp_inventory_change_order.state = ? THEN erp_inventory_change_commodity.count ELSE 0 END) AS check_in, SUM(CASE WHEN erp_inventory_change_order.change_type = ? AND erp_inventory_change_order.state = ? THEN erp_inventory_change_commodity.price ELSE 0 END) AS check_in_amount, SUM(CASE WHEN erp_inventory_change_order.change_type = ? AND erp_inventory_change_order.state = ? THEN erp_inventory_change_commodity.count ELSE 0 END) AS check_out, SUM(CASE WHEN erp_inventory_change_order.change_type = ? AND erp_inventory_change_order.state = ? THEN erp_inventory_change_commodity.price ELSE 0 END) AS check_out_amount `, AddChangeOrder, ErpInventoryChangeOrderFinished, AddChangeOrder, ErpInventoryChangeOrderFinished, ReduceChangeOrder, ErpInventoryChangeOrderFinished, ReduceChangeOrder, ErpInventoryChangeOrderFinished) err := subQuery.Scan(&reportData).Error if err != nil { logger.Errorf("getInventoryChanges err:", err) return DecisionReportData{}, err } return reportData, nil } // 查询调拨汇总数据:在途库存(出库)数量、调拨入库数量、调拨出库数量 func getSumAllotData(req *ErpDecisionReportReq, endTimeFlag bool) (DecisionReportData, error) { var reportData DecisionReportData qs := orm.Eloquent.Debug().Table("erp_inventory_allot_commodity"). Joins("JOIN erp_inventory_allot_order ON erp_inventory_allot_order.id = erp_inventory_allot_commodity.allot_order_id") // Apply time filters if provided if req.StartTime != "" { parse, err := time.Parse(QueryTimeFormat, req.StartTime) if err != nil { logger.Errorf("getAllotCounts err:", err) return DecisionReportData{}, err } qs = qs.Where("erp_inventory_allot_order.receive_time > ?", parse) } if req.EndTime != "" && endTimeFlag { parse, err := time.Parse(QueryTimeFormat, req.EndTime) if err != nil { logger.Errorf("getAllotCounts err:", err) return DecisionReportData{}, err } qs = qs.Where("erp_inventory_allot_order.receive_time <= ?", parse) } if len(req.CommodityName) > 0 { // 商品名称 var commodityNames []string for _, commodityName := range req.CommodityName { commodityNames = append(commodityNames, commodityName) } if len(commodityNames) == 1 { qs = qs.Where("erp_inventory_allot_commodity.commodity_name = ?", commodityNames[0]) } else { qs = qs.Where("erp_inventory_allot_commodity.commodity_name IN (?)", commodityNames) } } if len(req.CategoryID) > 0 { // 商品分类id var categoryIDs []uint32 for _, category := range req.CategoryID { categoryIDs = append(categoryIDs, category) } if len(categoryIDs) == 1 { qs = qs.Where("erp_inventory_allot_commodity.category_id = ?", categoryIDs[0]) } else { qs = qs.Where("erp_inventory_allot_commodity.category_id IN (?)", categoryIDs) } } // Apply store_id filter if provided if len(req.StoreId) > 1 { subQuery := qs.Select(` SUM(CASE WHEN erp_inventory_allot_order.state IN (?, ?) AND erp_inventory_allot_order.deliver_store_id IN (?) THEN erp_inventory_allot_commodity.count ELSE 0 END) AS allot_wait_out, SUM(CASE WHEN erp_inventory_allot_order.state IN (?, ?) AND erp_inventory_allot_order.deliver_store_id IN (?) THEN erp_inventory_allot_commodity.amount ELSE 0 END) AS allot_wait_out_amount, SUM(CASE WHEN erp_inventory_allot_order.state = ? AND erp_inventory_allot_order.receive_store_id IN (?) THEN erp_inventory_allot_commodity.count ELSE 0 END) AS allot_in, SUM(CASE WHEN erp_inventory_allot_order.state = ? AND erp_inventory_allot_order.receive_store_id IN (?) THEN erp_inventory_allot_commodity.amount ELSE 0 END) AS allot_in_amount, SUM(CASE WHEN erp_inventory_allot_order.state = ? AND erp_inventory_allot_order.deliver_store_id IN (?) THEN erp_inventory_allot_commodity.count ELSE 0 END) AS allot_out, SUM(CASE WHEN erp_inventory_allot_order.state = ? AND erp_inventory_allot_order.deliver_store_id IN (?) THEN erp_inventory_allot_commodity.amount ELSE 0 END) AS allot_out_amount `, ErpInventoryAllotOrderWaitSend, ErpInventoryAllotOrderWaitReceive, req.StoreId, ErpInventoryAllotOrderWaitSend, ErpInventoryAllotOrderWaitReceive, req.StoreId, ErpInventoryAllotOrderFinished, req.StoreId, ErpInventoryAllotOrderFinished, req.StoreId, ErpInventoryAllotOrderFinished, req.StoreId, ErpInventoryAllotOrderFinished, req.StoreId) err := subQuery.Scan(&reportData).Error if err != nil { logger.Errorf("getAllotCounts err:", err) return DecisionReportData{}, err } } else if len(req.StoreId) == 1 { subQuery := qs.Select(` SUM(CASE WHEN erp_inventory_allot_order.state IN (?, ?) AND erp_inventory_allot_order.deliver_store_id = ? THEN erp_inventory_allot_commodity.count ELSE 0 END) AS allot_wait_out, SUM(CASE WHEN erp_inventory_allot_order.state IN (?, ?) AND erp_inventory_allot_order.deliver_store_id = ? THEN erp_inventory_allot_commodity.amount ELSE 0 END) AS allot_wait_out_amount, SUM(CASE WHEN erp_inventory_allot_order.state = ? AND erp_inventory_allot_order.receive_store_id = ? THEN erp_inventory_allot_commodity.count ELSE 0 END) AS allot_in, SUM(CASE WHEN erp_inventory_allot_order.state = ? AND erp_inventory_allot_order.receive_store_id = ? THEN erp_inventory_allot_commodity.amount ELSE 0 END) AS allot_in_amount, SUM(CASE WHEN erp_inventory_allot_order.state = ? AND erp_inventory_allot_order.deliver_store_id = ? THEN erp_inventory_allot_commodity.count ELSE 0 END) AS allot_out, SUM(CASE WHEN erp_inventory_allot_order.state = ? AND erp_inventory_allot_order.deliver_store_id = ? THEN erp_inventory_allot_commodity.amount ELSE 0 END) AS allot_out_amount `, ErpInventoryAllotOrderWaitSend, ErpInventoryAllotOrderWaitReceive, req.StoreId[0], ErpInventoryAllotOrderWaitSend, ErpInventoryAllotOrderWaitReceive, req.StoreId[0], ErpInventoryAllotOrderFinished, req.StoreId[0], ErpInventoryAllotOrderFinished, req.StoreId[0], ErpInventoryAllotOrderFinished, req.StoreId[0], ErpInventoryAllotOrderFinished, req.StoreId[0]) err := subQuery.Scan(&reportData).Error if err != nil { logger.Errorf("getAllotCounts err:", err) return DecisionReportData{}, err } } else { // If StoreId is empty, query without deliver_store_id and receive_store_id conditions subQuery := qs.Select(` SUM(CASE WHEN erp_inventory_allot_order.state IN (?, ?) THEN erp_inventory_allot_commodity.count ELSE 0 END) AS allot_wait_out, SUM(CASE WHEN erp_inventory_allot_order.state IN (?, ?) THEN erp_inventory_allot_commodity.amount ELSE 0 END) AS allot_wait_out_amount, SUM(CASE WHEN erp_inventory_allot_order.state = ? THEN erp_inventory_allot_commodity.count ELSE 0 END) AS allot_in, SUM(CASE WHEN erp_inventory_allot_order.state = ? THEN erp_inventory_allot_commodity.amount ELSE 0 END) AS allot_in_amount, SUM(CASE WHEN erp_inventory_allot_order.state = ? THEN erp_inventory_allot_commodity.count ELSE 0 END) AS allot_out, SUM(CASE WHEN erp_inventory_allot_order.state = ? THEN erp_inventory_allot_commodity.amount ELSE 0 END) AS allot_out_amount `, ErpInventoryAllotOrderWaitSend, ErpInventoryAllotOrderWaitReceive, ErpInventoryAllotOrderWaitSend, ErpInventoryAllotOrderWaitReceive, ErpInventoryAllotOrderFinished, ErpInventoryAllotOrderFinished, ErpInventoryAllotOrderFinished, ErpInventoryAllotOrderFinished) err := subQuery.Scan(&reportData).Error if err != nil { logger.Errorf("getAllotCounts err:", err) return DecisionReportData{}, err } } return reportData, nil } // 查询进销存报表汇总数据 func getSumDecisionReportData(req *ErpDecisionReportReq) (DecisionSumData, error) { var sumData DecisionSumData // 期初库存 sumStartData, err := getSumStartData(req) if err != nil { return DecisionSumData{}, err } sumData.TotalBeginStock = sumStartData.BeginStock sumData.TotalBeginAmount = sumStartData.BeginAmount // 期末库存 sumEndData, err := getSumEndCount(req) if err != nil { return DecisionSumData{}, err } sumData.TotalEndStock = sumEndData.EndStock sumData.TotalEndAmount = sumEndData.EndAmount // 查询库存汇总数据:采购退货数量、产品入库、系统入库、系统出库、在途库存(入库)数量 sumStockData, err := getSumStockData(req, true) if err != nil { return DecisionSumData{}, err } sumData.TotalPurchaseReturn = sumStockData.PurchaseReturn sumData.TotalAllotWaitIn = sumStockData.AllotWaitIn sumData.TotalProductIn = sumStockData.ProductIn sumData.TotalSystemIn = sumStockData.SystemIn sumData.TotalSystemOut = sumStockData.SystemOut sumData.TotalReturnAmount = sumStockData.PurchaseReturnAmount sumData.TotalWaitInAmount = sumStockData.AllotWaitInAmount sumData.TotalProductInAmount = sumStockData.ProductInAmount sumData.TotalSystemInAmount = sumStockData.SystemInAmount sumData.TotalSystemOutAmount = sumStockData.SystemOutAmount // 查询采购进货数量 sumPurchaseData, err := getSumPurchaseData(req, true) if err != nil { return DecisionSumData{}, err } sumData.TotalPurchaseStock = sumPurchaseData.PurchaseStock sumData.TotalPurchaseAmount = sumPurchaseData.PurchaseStockAmount // 查询零售汇总数据:零售销售数量、零售退货数量 sumSalesData, err := getSumSalesData(req, true) if err != nil { return DecisionSumData{}, err } sumData.TotalOrderSale = sumSalesData.OrderSale sumData.TotalOrderReject = sumSalesData.OrderReject sumData.TotalSaleAmount = sumSalesData.OrderSaleAmount sumData.TotalRejectAmount = sumSalesData.OrderRejectAmount // 查询盘点汇总数据:盘点入库数量、盘点出库数量 sumInventoryData, err := getSumInventoryData(req, true) if err != nil { return DecisionSumData{}, err } sumData.TotalCheckIn = sumInventoryData.CheckIn sumData.TotalCheckOut = sumInventoryData.CheckOut sumData.TotalCheckInAmount = sumInventoryData.CheckInAmount sumData.TotalCheckOutAmount = sumInventoryData.CheckOutAmount // 查询调拨汇总数据:在途库存(出库)数量、调拨入库数量、调拨出库数量 sumAllotData, err := getSumAllotData(req, true) if err != nil { return DecisionSumData{}, err } sumData.TotalAllotWaitOut = sumAllotData.AllotWaitOut sumData.TotalAllotIn = sumAllotData.AllotIn sumData.TotalAllotOut = sumAllotData.AllotOut sumData.TotalWaitOutAmount = sumAllotData.AllotWaitOutAmount sumData.TotalAllotInAmount = sumAllotData.AllotInAmount sumData.TotalAllotOutAmount = sumAllotData.AllotOutAmount if req.EndTime != "" { // Step 4: 计算调整库存逻辑(期初+入库-出库) sumData.TotalEndStock = sumData.TotalBeginStock + sumData.TotalPurchaseStock + sumData.TotalAllotIn + sumData.TotalProductIn + sumData.TotalCheckIn + sumData.TotalOrderReject if sumData.TotalEndStock < (sumData.TotalPurchaseReturn + sumData.TotalOrderSale + sumData.TotalAllotOut + sumData.TotalSystemOut + sumData.TotalCheckOut) { sumData.TotalEndStock = 0 } else { sumData.TotalEndStock -= sumData.TotalPurchaseReturn + sumData.TotalOrderSale + sumData.TotalAllotOut + sumData.TotalSystemOut + sumData.TotalCheckOut } sumData.TotalEndAmount = sumData.TotalBeginAmount + sumData.TotalPurchaseAmount + sumData.TotalAllotInAmount + sumData.TotalProductInAmount + sumData.TotalCheckInAmount + sumData.TotalRejectAmount if sumData.TotalEndAmount < (sumData.TotalReturnAmount + sumData.TotalSaleAmount + sumData.TotalAllotOutAmount + sumData.TotalSystemOutAmount + sumData.TotalCheckOutAmount) { sumData.TotalEndAmount = 0 } else { sumData.TotalEndAmount -= sumData.TotalReturnAmount + sumData.TotalSaleAmount + sumData.TotalAllotOutAmount + sumData.TotalSystemOutAmount + sumData.TotalCheckOutAmount } } roundDecisionSumData(&sumData) return sumData, nil } // roundFloat64 rounds a float64 number to the specified decimal places. func roundFloat64(num float64, decimalPlaces int) float64 { precision := math.Pow(10, float64(decimalPlaces)) return math.Round(num*precision) / precision } // roundDecisionSumData rounds all float64 fields in DecisionSumData to 2 decimal places. func roundDecisionSumData(data *DecisionSumData) { data.TotalBeginAmount = roundFloat64(data.TotalBeginAmount, 2) data.TotalPurchaseAmount = roundFloat64(data.TotalPurchaseAmount, 2) data.TotalReturnAmount = roundFloat64(data.TotalReturnAmount, 2) data.TotalSaleAmount = roundFloat64(data.TotalSaleAmount, 2) data.TotalRejectAmount = roundFloat64(data.TotalRejectAmount, 2) data.TotalAllotInAmount = roundFloat64(data.TotalAllotInAmount, 2) data.TotalWaitInAmount = roundFloat64(data.TotalWaitInAmount, 2) data.TotalAllotOutAmount = roundFloat64(data.TotalAllotOutAmount, 2) data.TotalWaitOutAmount = roundFloat64(data.TotalWaitOutAmount, 2) data.TotalProductInAmount = roundFloat64(data.TotalProductInAmount, 2) data.TotalSystemInAmount = roundFloat64(data.TotalSystemInAmount, 2) data.TotalSystemOutAmount = roundFloat64(data.TotalSystemOutAmount, 2) data.TotalCheckInAmount = roundFloat64(data.TotalCheckInAmount, 2) data.TotalCheckOutAmount = roundFloat64(data.TotalCheckOutAmount, 2) data.TotalEndAmount = roundFloat64(data.TotalEndAmount, 2) } // reportDecisionExport 进销存报表导出excel func reportDecisionExport(req *ErpDecisionReportResp) (string, error) { file := excelize.NewFile() fSheet := "Sheet1" url := config.ExportConfig.Url fileName := time.Now().Format(TimeFormat) + "进销存报表" + ".xlsx" fmt.Println("url fileName:", url+fileName) // 组合标题栏数据 title := []interface{}{"商品名称", "商品分类", "期初库存", "期初金额", "采购进货", "采购退货", "零售销售", "零售退货", "调拨入库", "在途库存(入库)", "调拨出库", "在途库存(出库)", "产品入库", "系统出库", "盘点入库", "盘点出库", "期末数量", "期末金额"} for i, _ := range title { cell, _ := excelize.CoordinatesToCellName(1+i, 1) err := file.SetCellValue(fSheet, cell, title[i]) if err != nil { logger.Error("file set value err:", logger.Field("err", err)) } } var row1 []interface{} nExcelStartRow := 0 for _, reportData := range req.List { row1 = []interface{}{ reportData.CommodityName, // 商品名称 reportData.CategoryName, // 商品分类 reportData.BeginStock, reportData.BeginAmount, reportData.PurchaseStock, reportData.PurchaseReturn, reportData.OrderSale, reportData.OrderReject, reportData.AllotIn, reportData.AllotWaitIn, reportData.AllotOut, reportData.AllotWaitOut, reportData.ProductIn, reportData.SystemOut, reportData.CheckIn, reportData.CheckOut, reportData.EndStock, reportData.EndAmount, } for j, _ := range row1 { cell, _ := excelize.CoordinatesToCellName(1+j, nExcelStartRow+2) err := file.SetCellValue(fSheet, cell, row1[j]) if err != nil { logger.Error("file set value err:", logger.Field("err", err)) } } nExcelStartRow++ } totalData := "汇总 记录数:" + strconv.FormatInt(int64(req.Total), 10) end := []interface{}{totalData, "", req.SumData.TotalBeginStock, req.SumData.TotalBeginAmount, req.SumData.TotalPurchaseStock, req.SumData.TotalPurchaseReturn, req.SumData.TotalOrderSale, req.SumData.TotalOrderReject, req.SumData.TotalAllotIn, req.SumData.TotalAllotWaitIn, req.SumData.TotalAllotOut, req.SumData.TotalAllotWaitOut, req.SumData.TotalProductIn, req.SumData.TotalSystemOut, req.SumData.TotalCheckIn, req.SumData.TotalCheckOut, req.SumData.TotalEndStock, req.SumData.TotalEndAmount} for i, _ := range end { cell, _ := excelize.CoordinatesToCellName(1+i, nExcelStartRow+2) err := file.SetCellValue(fSheet, cell, end[i]) if err != nil { logger.Error("file set value err:", logger.Field("err", err)) } } // 设置所有单元格的样式: 居中、加边框 style, _ := file.NewStyle(`{"alignment":{"horizontal":"center","vertical":"center"}, "border":[{"type":"left","color":"000000","style":1}, {"type":"top","color":"000000","style":1}, {"type":"right","color":"000000","style":1}, {"type":"bottom","color":"000000","style":1}]}`) //设置单元格高度 file.SetRowHeight("Sheet1", 1, 20) // 设置单元格大小 file.SetColWidth("Sheet1", "A", "A", 15) endRow := fmt.Sprintf("R"+"%d", nExcelStartRow+2) // 应用样式到整个表格 _ = file.SetCellStyle("Sheet1", "A1", endRow, style) fmt.Println("save fileName:", config.ExportConfig.Path+fileName) if err := file.SaveAs(config.ExportConfig.Path + fileName); err != nil { fmt.Println(err) } return url + fileName, nil } // ErpStoreSalesDataReq 门店销售对比入参 type ErpStoreSalesDataReq 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 升序 } // ErpStoreSalesDataResp 门店销售对比出参 type ErpStoreSalesDataResp struct { List []StoreSalesData `json:"list"` Total int `json:"total"` // 总条数 PageIndex int `json:"pageIndex"` // 页码 PageSize int `json:"pageSize"` // 每页展示条数 ExportUrl string `json:"export_url"` TotalSalesAmount float64 `json:"total_sales_amount"` // 总销售额 TotalPromotionFee float64 `json:"total_promotion_fee"` // 总推广费 TotalSalesProfit float64 `json:"total_sales_profit"` // 总销售毛利 TotalStaffProfit float64 `json:"total_staff_profit"` // 总员工毛利 TotalCount int64 `json:"total_count"` // 总销售数量 } // StoreSalesData 门店销售数据 type StoreSalesData struct { StoreId uint32 `json:"store_id"` // 门店id StoreName string `json:"store_name"` // 门店名称 TotalSalesAmount float64 `json:"total_sales_amount"` // 销售额 PromotionFee float64 `json:"promotion_fee"` // 推广费 SalesProfit float64 `json:"sales_profit"` // 销售毛利 StaffProfit float64 `json:"staff_profit"` // 员工毛利 Count int64 `json:"count"` // 销售数量 } // QueryStoreSalesData 查询门店销售对比数据 func QueryStoreSalesData(req *ErpStoreSalesDataReq, c *gin.Context) (*ErpStoreSalesDataResp, error) { showConfig, err := GetErpOrderShowConfig() if err != nil { logger.Errorf("List err:", err) showConfig.ShowAll = "ON" } page := req.PageIndex - 1 if page < 0 { page = 0 } if req.PageSize == 0 { req.PageSize = 10 } resp := &ErpStoreSalesDataResp{ PageIndex: req.PageIndex, PageSize: req.PageSize, } var storeManageDataList []StoreSalesData // 构建查询条件 qs := orm.Eloquent.Model(&ErpOrder{}) if len(req.StoreId) != 0 { qs.Where("erp_order.store_id in ?", req.StoreId) } var storeList []uint32 // 非管理员才判断所属门店 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 { if len(storeList) == 1 { qs = qs.Where("store_id = ?", storeList[0]) } else { qs = qs.Where("store_id IN (?)", storeList) } } else { return nil, errors.New("用户未绑定门店") } } else { var allStoreList []Store err = orm.Eloquent.Table("store").Where("is_online = 1 and cooperative_business_id = 1"). Find(&allStoreList).Error if err != nil { return nil, err } for _, v := range allStoreList { storeList = append(storeList, v.ID) } } if showConfig.ShowAll == "OFF" { qs = qs.Where("is_print = ? or retail_type = ?", HavePrinted, RetailTypeRejected) } if req.StartTime != "" && req.EndTime != "" { startTime, err := time.Parse(QueryTimeFormat, req.StartTime) if err != nil { logger.Error("startTime parse err") } endTime, err := time.Parse(QueryTimeFormat, req.EndTime) if err != nil { logger.Error("endTime parse err") } qs = qs.Where("maker_time BETWEEN ? AND ?", startTime, endTime) } else { qs = qs.Where("maker_time IS NOT NULL") } qs.Where("state = ?", ErpOrderStateAudited) // 查询汇总数据 var summary struct { TotalSalesAmount float64 TotalPromotionFee float64 TotalSalesProfit float64 TotalStaffProfit float64 TotalCount int64 } err = qs.Select("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_discount ELSE -total_discount END) AS total_promotion_fee, " + "SUM(CASE WHEN retail_type = 'sale' THEN total_sales_profit ELSE -total_sales_profit END) AS total_sales_profit, " + "SUM(CASE WHEN retail_type = 'sale' THEN total_staff_profit ELSE -total_staff_profit END) AS total_staff_profit, " + "SUM(CASE WHEN retail_type = 'sale' THEN total_count ELSE -total_count END) AS total_count"). Find(&summary).Error if err != nil { logger.Error("QueryStoreManageData summary err:", logger.Field("err", err)) return nil, err } // 查询分页数据 按 store_id 进行汇总 var storeData []struct { StoreId uint32 `json:"store_id"` TotalSalesAmount float64 `json:"total_sales_amount"` PromotionFee float64 `json:"promotion_fee"` SalesProfit float64 `json:"sales_profit"` StaffProfit float64 `json:"staff_profit"` Count int64 `json:"count"` } err = qs.Select("store_id, " + "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("store_id"). Order("store_id"). Find(&storeData).Error if err != nil { logger.Error("QueryStoreManageData err:", logger.Field("err", err)) return nil, err } storeMap, err := GetAllStoreData() if err != nil { return nil, err } // 组合数据 for _, storeId := range storeList { flag := false for _, v := range storeData { if v.StoreId == storeId { flag = true storeManageDataList = append(storeManageDataList, StoreSalesData{ StoreId: v.StoreId, StoreName: storeMap[v.StoreId].Name, TotalSalesAmount: math.Round(v.TotalSalesAmount*100) / 100, PromotionFee: math.Round(v.PromotionFee*100) / 100, SalesProfit: math.Round(v.SalesProfit*100) / 100, StaffProfit: math.Round(v.StaffProfit*100) / 100, Count: v.Count, }) } else { continue } } if !flag { storeManageDataList = append(storeManageDataList, StoreSalesData{ StoreId: storeId, StoreName: storeMap[storeId].Name, TotalSalesAmount: 0, PromotionFee: 0, SalesProfit: 0, StaffProfit: 0, Count: 0, }) } } // 汇总数据赋值给响应 resp.TotalSalesAmount = math.Round(summary.TotalSalesAmount*100) / 100 resp.TotalPromotionFee = math.Round(summary.TotalPromotionFee*100) / 100 resp.TotalSalesProfit = math.Round(summary.TotalSalesProfit*100) / 100 resp.TotalStaffProfit = math.Round(summary.TotalStaffProfit*100) / 100 resp.TotalCount = summary.TotalCount if req.IsExport == 1 { //导出excel filePath, err := storeSalesDataExport(storeManageDataList, summary, c) if err != nil { logger.Error("StoreManageDataExport err:", logger.Field("err", err)) return nil, err } resp.ExportUrl = filePath } else { // 根据页码和页面条数截取结果 startIndex := page * req.PageSize endIndex := startIndex + req.PageSize if endIndex > len(storeManageDataList) { endIndex = len(storeManageDataList) } resp.List = storeManageDataList[startIndex:endIndex] resp.Total = len(storeManageDataList) } return resp, nil } // storeSalesDataExport 导出门店经营数据 func storeSalesDataExport(list []StoreSalesData, summary struct { TotalSalesAmount float64 TotalPromotionFee float64 TotalSalesProfit float64 TotalStaffProfit float64 TotalCount int64 }, c *gin.Context) (string, error) { file := excelize.NewFile() fSheet := "Sheet1" url := config.ExportConfig.Url fileName := time.Now().Format(TimeFormat) + "门店销售对比" + ".xlsx" fmt.Println("url fileName:", url+fileName) // 判断是否有入销售毛利、员工毛利的权限 flag1, _ := checkRoleMenu(c, SalesProfitMenu) flag2, _ := checkRoleMenu(c, StaffProfitMenu) fmt.Println("flag1 is:", flag1) fmt.Println("flag2 is:", flag2) logger.Info("flag1 is:", logger.Field("flag1", flag1)) logger.Info("flag2 is:", logger.Field("flag2", flag2)) nEndCount := 0 title := []interface{}{"店铺名称", "销售额", "推广费"} if flag1 { // 销售毛利 title = append(title, "销售毛利") nEndCount += 1 } if flag2 { // 员工毛利 title = append(title, "员工毛利") nEndCount += 1 } title = append(title, "销售数量") for i, _ := range title { cell, _ := excelize.CoordinatesToCellName(1+i, 1) err := file.SetCellValue(fSheet, cell, title[i]) if err != nil { logger.Errorf("file set value err:", err) } } var row []interface{} nExcelStartRow := 0 for rowId := 0; rowId < len(list); rowId++ { row = []interface{}{ list[rowId].StoreName, list[rowId].TotalSalesAmount, list[rowId].PromotionFee, } // 控制是否导出 if flag1 { // 销售毛利 row = append(row, list[rowId].SalesProfit) } if flag2 { // 员工毛利 row = append(row, list[rowId].StaffProfit) } row = append(row, list[rowId].Count) for j, _ := range row { cell, _ := excelize.CoordinatesToCellName(1+j, nExcelStartRow+2) err := file.SetCellValue(fSheet, cell, row[j]) if err != nil { logger.Error("file set value err:", logger.Field("err", err)) } } nExcelStartRow++ } totalData := "汇总 记录数:" + strconv.FormatInt(int64(len(list)), 10) end := []interface{}{totalData, summary.TotalSalesAmount, summary.TotalPromotionFee} if flag1 { // 销售毛利 end = append(end, summary.TotalSalesProfit) } if flag2 { // 员工毛利 end = append(end, summary.TotalStaffProfit) } end = append(end, summary.TotalCount) for i, _ := range end { cell, _ := excelize.CoordinatesToCellName(1+i, nExcelStartRow+2) err := file.SetCellValue(fSheet, cell, end[i]) if err != nil { logger.Error("file set value err:", logger.Field("err", err)) } } // 设置所有单元格的样式: 居中、加边框 style, _ := file.NewStyle(`{"alignment":{"horizontal":"center","vertical":"center"}, "border":[{"type":"left","color":"000000","style":1}, {"type":"top","color":"000000","style":1}, {"type":"right","color":"000000","style":1}, {"type":"bottom","color":"000000","style":1}]}`) //设置单元格高度 file.SetRowHeight("Sheet1", 1, 20) // 设置单元格大小 file.SetColWidth("Sheet1", "A", "A", 30) file.SetColWidth("Sheet1", "B", "B", 18) file.SetColWidth("Sheet1", "C", "C", 18) file.SetColWidth("Sheet1", "D", "D", 18) file.SetColWidth("Sheet1", "E", "E", 18) file.SetColWidth("Sheet1", "F", "F", 18) var endRow string switch nEndCount { case 1: endRow = fmt.Sprintf("E"+"%d", nExcelStartRow+2) case 2: endRow = fmt.Sprintf("F"+"%d", nExcelStartRow+2) default: endRow = fmt.Sprintf("D"+"%d", nExcelStartRow+2) } // 应用样式到整个表格 _ = file.SetCellStyle("Sheet1", "A1", endRow, style) fmt.Println("save fileName:", config.ExportConfig.Path+fileName) if err := file.SaveAs(config.ExportConfig.Path + fileName); err != nil { fmt.Println(err) } return url + fileName, nil }