1.优化进销存报表接口查询慢的问题;

This commit is contained in:
chenlin 2024-07-16 18:30:46 +08:00
parent 87c55b0cda
commit b7472787c0
2 changed files with 669 additions and 103 deletions

View File

@ -56,7 +56,8 @@ type ErpStock struct {
MinRetailPrice float64 `json:"min_retail_price"` // 最低零售价
Count uint32 `json:"count"` // 数量
DispatchCount uint32 `json:"dispatch_count"` // 调拨中数量(调拨中调入)
Commodities []ErpStockCommodity `json:"commodities" gorm:"-"`
Commodities []ErpStockCommodity `json:"commodities" gorm:"-"` //
DecisionStoreId []uint32 `json:"decision_store_id" gorm:"-"` // 门店编号列表(查询进销存的时候使用)
}
// ErpStockCommodity 库存详情

View File

@ -149,17 +149,51 @@ func (m *ErpDecisionReportReq) DecisionReportList(c *gin.Context) (*ErpDecisionR
}
var commodities []ErpStock
err = qs.Order("erp_commodity_id, store_id desc").Find(&commodities).Error
//if m.IsExport == 1 { // 导出excel
// err = qs.Order("erp_commodity_id, store_id desc").Find(&commodities).Error
//} else {
// err = qs.Order("erp_commodity_id, store_id desc").Offset(page * m.PageSize).Limit(m.PageSize).Find(&commodities).Error
//}
if len(m.StoreId) == 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 { // 查询所有门店数据
// 剔除商品id重复的数据
var trimCommodities []ErpStock
tempCommodityMap := make(map[uint32]ErpStock)
for i, item := range commodities {
if _, found := tempCommodityMap[item.ErpCommodityId]; found {
commodities[i].DecisionStoreId = append(commodities[i].DecisionStoreId, item.StoreId)
continue
} else {
if len(m.StoreId) != 0 {
commodities[i].StoreId = 0
}
commodities[i].DecisionStoreId = append(commodities[i].DecisionStoreId, item.StoreId)
tempCommodityMap[item.ErpCommodityId] = commodities[i]
trimCommodities = append(trimCommodities, commodities[i])
}
}
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))
@ -232,7 +266,6 @@ func (m *ErpDecisionReportReq) DecisionReportList(c *gin.Context) (*ErpDecisionR
}()
// 从通道中接收结果
var sumData DecisionSumData
commodityMap := make(map[uint32]DecisionReportData)
for data := range ch {
if existing, found := commodityMap[data.CommodityId]; found {
@ -262,36 +295,22 @@ func (m *ErpDecisionReportReq) DecisionReportList(c *gin.Context) (*ErpDecisionR
}
for _, data := range commodityMap {
sumData.TotalBeginStock += data.BeginStock
sumData.TotalBeginAmount += data.BeginAmount
sumData.TotalPurchaseStock += data.PurchaseStock
sumData.TotalPurchaseReturn += data.PurchaseReturn
sumData.TotalOrderSale += data.OrderSale
sumData.TotalOrderReject += data.OrderReject
sumData.TotalAllotIn += data.AllotIn
sumData.TotalAllotWaitIn += data.AllotWaitIn
sumData.TotalAllotOut += data.AllotOut
sumData.TotalAllotWaitOut += data.AllotWaitOut
sumData.TotalProductIn += data.ProductIn
sumData.TotalSystemOut += data.SystemOut
sumData.TotalCheckIn += data.CheckIn
sumData.TotalCheckOut += data.CheckOut
sumData.TotalEndStock += data.EndStock
sumData.TotalEndAmount += data.EndAmount
sumData.TotalBeginAmount = math.Round(sumData.TotalBeginAmount*100) / 100
sumData.TotalEndAmount = math.Round(sumData.TotalEndAmount*100) / 100
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
resp.Total = len(reportList)
if m.IsExport == 1 {
resp.Total = len(reportList)
resp.List = reportList
resp.ExportUrl, err = reportDecisionExport(resp)
if err != nil {
@ -301,17 +320,11 @@ func (m *ErpDecisionReportReq) DecisionReportList(c *gin.Context) (*ErpDecisionR
resp.List = nil
resp.SumData = DecisionSumData{}
} else {
// 分页处理
startIdx := (resp.PageIndex - 1) * resp.PageSize
endIdx := resp.PageIndex * resp.PageSize
// 确保不超出索引范围
if startIdx >= len(reportList) {
resp.List = []DecisionReportData{}
} else if endIdx > len(reportList) {
resp.List = reportList[startIdx:]
if len(m.StoreId) == 1 {
resp.Total = int(count)
resp.List = reportList
} else {
resp.List = reportList[startIdx:endIdx]
resp.List = reportList
}
}
@ -343,9 +356,22 @@ func getSystemStartCount(req *ErpDecisionReportReq, stock ErpStock) (DecisionRep
qs = qs.Where("first_stock_time > ?", parse)
}
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
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
}
@ -378,11 +404,28 @@ func getPurchaseStockCount(req *ErpDecisionReportReq, stock ErpStock) (DecisionR
qs = qs.Where("first_stock_time > ?", parse)
}
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
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
}
@ -415,8 +458,19 @@ func getPurchaseReturnCount(req *ErpDecisionReportReq, stock ErpStock) (Decision
qs = qs.Where("first_stock_time > ?", parse)
}
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
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
}
@ -446,10 +500,25 @@ func getSaleOutCount(req *ErpDecisionReportReq, stock ErpStock) (DecisionReportD
qs = qs.Where("erp_order.audit_time < ?", parse)
}
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
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
}
@ -482,12 +551,28 @@ func getSaleReturnCount(req *ErpDecisionReportReq, stock ErpStock) (DecisionRepo
qs = qs.Where("erp_order.audit_time > ?", parse)
}
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
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
}
@ -520,8 +605,19 @@ func getProductCount(req *ErpDecisionReportReq, stock ErpStock) (DecisionReportD
qs = qs.Where("first_stock_time > ?", parse)
}
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
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
}
@ -554,13 +650,34 @@ func getChangeAddCount(req *ErpDecisionReportReq, stock ErpStock) (DecisionRepor
qs = qs.Where("erp_inventory_change_order.audit_time > ?", parse)
}
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
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
}
@ -593,13 +710,34 @@ func getChangeReduceCount(req *ErpDecisionReportReq, stock ErpStock) (DecisionRe
qs = qs.Where("erp_inventory_change_order.audit_time > ?", parse)
}
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
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
}
@ -632,8 +770,19 @@ func getSystemOutCount(req *ErpDecisionReportReq, stock ErpStock) (DecisionRepor
qs = qs.Where("first_stock_time > ?", parse)
}
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
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
}
@ -666,8 +815,19 @@ func getAllotWaitInCount(req *ErpDecisionReportReq, stock ErpStock) (DecisionRep
qs = qs.Where("updated_at > ?", parse)
}
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
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
}
@ -700,13 +860,34 @@ func getAllotWaitOutCount(req *ErpDecisionReportReq, stock ErpStock) (DecisionRe
qs = qs.Where("erp_inventory_allot_commodity.audit_time > ?", parse)
}
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
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
}
@ -739,13 +920,34 @@ func getAllotInCount(req *ErpDecisionReportReq, stock ErpStock) (DecisionReportD
qs = qs.Where("erp_inventory_allot_commodity.audit_time > ?", parse)
}
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
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
}
@ -778,13 +980,34 @@ func getAllotOutCount(req *ErpDecisionReportReq, stock ErpStock) (DecisionReport
qs = qs.Where("erp_inventory_allot_commodity.audit_time > ?", parse)
}
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
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
}
@ -817,9 +1040,22 @@ func getSystemEndCount(req *ErpDecisionReportReq, stock ErpStock) (DecisionRepor
qs = qs.Where("first_stock_time > ?", parse)
}
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
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
}
@ -827,6 +1063,335 @@ func getSystemEndCount(req *ErpDecisionReportReq, stock ErpStock) (DecisionRepor
return reportData, nil
}
// 查询库存汇总数据:期初库存、期初金额、采购退货数量、产品入库、系统出库、在途库存(入库)数量、期末库存、期末金额
func getSumStockData(req *ErpDecisionReportReq) (DecisionReportData, error) {
var reportData DecisionReportData
qs := orm.Eloquent.Debug().Table("erp_stock_commodity")
if req.StartTime != "" {
parse, err := time.Parse(QueryTimeFormat, req.StartTime)
if err != nil {
logger.Errorf("getStockData err:", err)
return DecisionReportData{}, err
}
qs = qs.Where("first_stock_time > ?", parse)
}
if req.EndTime != "" {
parse, err := time.Parse(QueryTimeFormat, req.EndTime)
if err != nil {
logger.Errorf("getStockData err:", err)
return DecisionReportData{}, err
}
qs = qs.Where("first_stock_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)
}
}
subQuery := qs.Select(`
SUM(CASE WHEN storage_type = ? THEN count ELSE 0 END) AS begin_stock,
SUM(CASE WHEN storage_type = ? THEN wholesale_price ELSE 0 END) AS begin_amount,
SUM(CASE WHEN state = ? THEN count ELSE 0 END) AS purchase_return,
SUM(CASE WHEN storage_type = ? THEN count ELSE 0 END) AS product_in,
SUM(CASE WHEN state = ? THEN count ELSE 0 END) AS system_out,
SUM(CASE WHEN state = ? THEN count ELSE 0 END) AS allot_wait_in,
SUM(CASE WHEN state IN (?) THEN count ELSE 0 END) AS end_stock,
SUM(CASE WHEN state IN (?) THEN wholesale_price ELSE 0 END) AS end_amount
`, SystemInventory, SystemInventory, PurchaseReturn,
ProductInventory, SystemOut, InAllot,
[]uint32{InStock, InAllot}, []uint32{InStock, InAllot})
err := subQuery.Scan(&reportData).Error
if err != nil {
logger.Errorf("getStockData err:", err)
return DecisionReportData{}, err
}
return reportData, nil
}
// 查询采购进货数量
func getSumPurchaseData(req *ErpDecisionReportReq) (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("first_stock_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("first_stock_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)
}
}
var err error
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.purchase_type = ?", ErpProcureOrder).
Find(&reportData).Error
if err != nil {
return DecisionReportData{}, err
}
return reportData, nil
}
// 查询零售汇总数据:零售销售数量、零售退货数量
func getSumSalesData(req *ErpDecisionReportReq) (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 != "" {
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)
}
}
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 = ? THEN erp_order_commodity.count ELSE 0 END) AS order_reject
`, RetailTypeSale, ErpOrderStateAudited, HavePaid, 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) (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 != "" {
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("store_id = ?", req.StoreId[0])
} else {
qs = qs.Where("store_id IN (?)", req.StoreId)
}
}
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.count ELSE 0 END) AS check_out
`, AddChangeOrder, 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) (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_commodity.audit_time > ?", parse)
}
if req.EndTime != "" {
parse, err := time.Parse(QueryTimeFormat, req.EndTime)
if err != nil {
logger.Errorf("getAllotCounts err:", err)
return DecisionReportData{}, err
}
qs = qs.Where("erp_inventory_allot_commodity.audit_time < ?", parse)
}
// 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 = ? 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.deliver_store_id IN (?) THEN erp_inventory_allot_commodity.count ELSE 0 END) AS allot_out
`, ErpInventoryAllotOrderWaitSend, ErpInventoryAllotOrderWaitReceive, 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 = ? 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.deliver_store_id = ? THEN erp_inventory_allot_commodity.count ELSE 0 END) AS allot_out
`, ErpInventoryAllotOrderWaitSend, ErpInventoryAllotOrderWaitReceive, 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 = ? 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.count ELSE 0 END) AS allot_out
`, ErpInventoryAllotOrderWaitSend, ErpInventoryAllotOrderWaitReceive,
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
sumStockData, err := getSumStockData(req)
if err != nil {
return DecisionSumData{}, err
}
sumData.TotalBeginStock = sumStockData.BeginStock
sumData.TotalBeginAmount = sumStockData.BeginAmount
sumData.TotalPurchaseReturn = sumStockData.PurchaseReturn
sumData.TotalAllotWaitIn = sumStockData.AllotWaitIn
sumData.TotalProductIn = sumStockData.ProductIn
sumData.TotalSystemOut = sumStockData.SystemOut
sumData.TotalEndStock = sumStockData.EndStock
sumData.TotalEndAmount = sumStockData.EndAmount
sumPurchaseData, err := getSumPurchaseData(req)
if err != nil {
return DecisionSumData{}, err
}
sumData.TotalPurchaseStock = sumPurchaseData.PurchaseStock
sumSalesData, err := getSumSalesData(req)
if err != nil {
return DecisionSumData{}, err
}
sumData.TotalOrderSale = sumSalesData.OrderSale
sumData.TotalOrderReject = sumSalesData.OrderReject
sumInventoryData, err := getSumInventoryData(req)
if err != nil {
return DecisionSumData{}, err
}
sumData.TotalCheckIn = sumInventoryData.CheckIn
sumData.TotalCheckOut = sumInventoryData.CheckOut
sumAllotData, err := getSumAllotData(req)
if err != nil {
return DecisionSumData{}, err
}
sumData.TotalAllotWaitOut = sumAllotData.AllotWaitOut
sumData.TotalAllotIn = sumAllotData.AllotIn
sumData.TotalAllotOut = sumAllotData.AllotOut
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.TotalEndAmount = roundFloat64(data.TotalEndAmount, 2)
}
// reportDecisionExport 进销存报表导出excel
func reportDecisionExport(req *ErpDecisionReportResp) (string, error) {
file := excelize.NewFile()