mh_goadmin_server/app/admin/models/decision.go
2025-01-14 18:07:06 +08:00

3125 lines
118 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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