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
	}

	// 查询采购退货数量
	sumPurchaseReturnData, err := getSumPurchaseReturnData(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 - sumPurchaseReturnData.PurchaseReturn) - sumAllotData.AllotIn -
		sumStockData.ProductIn - sumInventoryData.CheckIn

	respData.BeginAmount = sumEndData.EndAmount + ((sumSalesData.OrderSaleAmount - sumSalesData.OrderRejectAmount) +
		sumAllotData.AllotOutAmount + sumStockData.SystemOutAmount + sumInventoryData.CheckOutAmount) -
		((sumPurchaseData.PurchaseStockAmount - sumPurchaseReturnData.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")
	es := orm.Eloquent.Debug().Table("erp_stock_commodity")

	// 构建用于筛选storage_type的数据子查询
	storageTypeQuery := qs
	if req.StartTime != "" {
		parse, err := time.Parse(QueryTimeFormat, req.StartTime)
		if err != nil {
			logger.Errorf("getStockData storage_type parse error: %v", err)
			return DecisionReportData{}, err
		}
		storageTypeQuery = storageTypeQuery.Where("created_at > ?", parse)
	}
	if req.EndTime != "" && endTimeFlag {
		parse, err := time.Parse(QueryTimeFormat, req.EndTime)
		if err != nil {
			logger.Errorf("getStockData storage_type parse error: %v", err)
			return DecisionReportData{}, err
		}
		storageTypeQuery = storageTypeQuery.Where("created_at <= ?", parse)
	}

	// 构建用于筛选state的数据子查询
	stateQuery := es
	if req.StartTime != "" {
		parse, err := time.Parse(QueryTimeFormat, req.StartTime)
		if err != nil {
			logger.Errorf("getStockData state parse error: %v", err)
			return DecisionReportData{}, err
		}
		stateQuery = stateQuery.Where("updated_at > ?", parse)
	}
	if req.EndTime != "" && endTimeFlag {
		parse, err := time.Parse(QueryTimeFormat, req.EndTime)
		if err != nil {
			logger.Errorf("getStockData state parse error: %v", err)
			return DecisionReportData{}, err
		}
		stateQuery = stateQuery.Where("updated_at <= ?", parse)
	}

	// 公共条件
	if len(req.StoreId) > 0 {
		if len(req.StoreId) == 1 {
			storageTypeQuery = storageTypeQuery.Where("store_id = ?", req.StoreId[0])
			stateQuery = stateQuery.Where("store_id = ?", req.StoreId[0])
		} else {
			storageTypeQuery = storageTypeQuery.Where("store_id IN (?)", req.StoreId)
			stateQuery = stateQuery.Where("store_id IN (?)", req.StoreId)
		}
	}

	if len(req.CommodityName) > 0 {
		if len(req.CommodityName) == 1 {
			storageTypeQuery = storageTypeQuery.Where("erp_commodity_name = ?", req.CommodityName[0])
			stateQuery = stateQuery.Where("erp_commodity_name = ?", req.CommodityName[0])
		} else {
			storageTypeQuery = storageTypeQuery.Where("erp_commodity_name IN (?)", req.CommodityName)
			stateQuery = stateQuery.Where("erp_commodity_name IN (?)", req.CommodityName)
		}
	}

	if len(req.CategoryID) > 0 {
		if len(req.CategoryID) == 1 {
			storageTypeQuery = storageTypeQuery.Where("erp_category_id = ?", req.CategoryID[0])
			stateQuery = stateQuery.Where("erp_category_id = ?", req.CategoryID[0])
		} else {
			storageTypeQuery = storageTypeQuery.Where("erp_category_id IN (?)", req.CategoryID)
			stateQuery = stateQuery.Where("erp_category_id IN (?)", req.CategoryID)
		}
	}

	// 分别查询 storage_type 相关的数据
	var storageTypeData struct {
		ProductIn       uint32
		ProductInAmount float64
		SystemIn        uint32
		SystemInAmount  float64
	}
	err := storageTypeQuery.Select(`
		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
	`, ProductInventory, ProductInventory, SystemInventory, SystemInventory).Scan(&storageTypeData).Error
	if err != nil {
		logger.Errorf("getStockData storage_type query error: %v", err)
		return DecisionReportData{}, err
	}

	// 查询 state 相关的数据
	var stateData struct {
		SystemOut         uint32
		SystemOutAmount   float64
		AllotWaitIn       uint32
		AllotWaitInAmount float64
	}
	err = stateQuery.Select(`
		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
	`, SystemOut, SystemOut, InAllot, InAllot).Scan(&stateData).Error
	if err != nil {
		logger.Errorf("getStockData state query error: %v", err)
		return DecisionReportData{}, err
	}

	// 合并结果
	reportData.ProductIn = storageTypeData.ProductIn
	reportData.ProductInAmount = storageTypeData.ProductInAmount
	reportData.SystemIn = storageTypeData.SystemIn
	reportData.SystemInAmount = storageTypeData.SystemInAmount
	reportData.SystemOut = stateData.SystemOut
	reportData.SystemOutAmount = stateData.SystemOutAmount
	reportData.AllotWaitIn = stateData.AllotWaitIn
	reportData.AllotWaitInAmount = stateData.AllotWaitInAmount

	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 getSumPurchaseReturnData(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_return,"+
		"SUM(erp_purchase_inventory.amount) AS purchase_return_amount").
		Joins("JOIN erp_purchase_order ON erp_purchase_order.id = erp_purchase_inventory.erp_purchase_order_id").
		Where("erp_purchase_inventory.purchase_type = ?", ErpRejectOrder).
		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.TotalAllotWaitIn = sumStockData.AllotWaitIn
	sumData.TotalProductIn = sumStockData.ProductIn
	sumData.TotalSystemIn = sumStockData.SystemIn
	sumData.TotalSystemOut = sumStockData.SystemOut

	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

	// 查询采购退货数量
	sumPurchaseReturnData, err := getSumPurchaseReturnData(req, true)
	if err != nil {
		return DecisionSumData{}, err
	}
	sumData.TotalPurchaseReturn = sumPurchaseReturnData.PurchaseReturn
	sumData.TotalReturnAmount = sumPurchaseReturnData.PurchaseReturnAmount

	// 查询零售汇总数据：零售销售数量、零售退货数量
	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("audit_time BETWEEN ? AND ?", startTime, endTime)
	} else {
		qs = qs.Where("audit_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
}
