1.修复采购需求的缺陷;

2.优惠券Coupon增加规则字段rule;
This commit is contained in:
chenlin 2024-07-23 10:28:53 +08:00
parent 1212d9dd1e
commit 596fd1dc44
3 changed files with 454 additions and 272 deletions

View File

@ -521,6 +521,44 @@ func (m *ErpCommodityListReq) List() (*ErpCommodityListResp, error) {
return resp, nil
}
// SortByErpSupplierId 对商品数组进行排序先按供应商ID排序如果相同则按商品编号排序升序
func SortByErpSupplierId(commodities []ErpCommodity, supplierIDDesc bool) {
// 定义排序函数
less := func(i, j int) bool {
// 按照供应商ID排序
if commodities[i].ErpSupplierId != commodities[j].ErpSupplierId {
if supplierIDDesc { // 降序 DESC
return commodities[i].ErpSupplierId > commodities[j].ErpSupplierId
}
return commodities[i].ErpSupplierId < commodities[j].ErpSupplierId // 升序 ASC
}
// 解析商品编号,提取分类编号和商品编号的数字部分
catNumI, subCatNumI, threeSubCatNumI, itemNumI := parseSerialNumber(commodities[i].SerialNumber)
catNumJ, subCatNumJ, threeSubCatNumJ, itemNumJ := parseSerialNumber(commodities[j].SerialNumber)
// 按照分类编号从小到大排序
if catNumI != catNumJ {
return catNumI < catNumJ
}
// 如果分类编号相同,按照具体分类下的商品编号递增排序
if subCatNumI != subCatNumJ {
return subCatNumI < subCatNumJ
}
if threeSubCatNumI != threeSubCatNumJ {
return threeSubCatNumI < threeSubCatNumJ
}
// 如果具体分类编号也相同,按照商品编号递增排序
return itemNumI < itemNumJ
}
// 调用排序函数进行排序
sort.SliceStable(commodities, less)
}
// SortStockCommodities 对库存商品数组进行排序
func SortStockCommodities(commodities []ErpStock) {
// 定义排序函数

View File

@ -12,18 +12,19 @@ const (
type Coupon struct {
Model
Name string `json:"name"`
Describe string `json:"describe" gorm:"type:text;"` // 描述
CouponType string `json:"coupon_type"`
ActivityType uint32 `json:"activity_type"` // 活动类型 1-会员续费
ActivityId uint32 `json:"activity_id" gorm:"index"`
Value uint32 `json:"value"`
OutCount uint32 `json:"out_count"` // 用户已领取数量
UsedCount uint32 `json:"used_count"` // 用户已使用数量
ActiveStart time.Time `json:"active_start"` // 有效期开始
ActiveEnd time.Time `json:"active_end"` // 有效期结束 零值永不结束
MemberLevel uint32 `json:"member_level"` // 会员等级 1-用户 2-会员
IsDraw bool `json:"is_draw" gorm:"-"`
Name string `json:"name"` // 优惠券名称
Describe string `json:"describe" gorm:"type:text"` // 优惠券简介
Rule string `json:"rule" gorm:"type:text"` // 优惠券使用规则
CouponType string `json:"coupon_type"` //
ActivityType uint32 `json:"activity_type"` // 活动类型 1-会员续费
ActivityId uint32 `json:"activity_id" gorm:"index"` //
Value uint32 `json:"value"` //
OutCount uint32 `json:"out_count"` // 用户已领取数量
UsedCount uint32 `json:"used_count"` // 用户已使用数量
ActiveStart time.Time `json:"active_start"` // 有效期开始
ActiveEnd time.Time `json:"active_end"` // 有效期结束 零值永不结束
MemberLevel uint32 `json:"member_level"` // 会员等级 1-用户 2-会员
IsDraw bool `json:"is_draw" gorm:"-"` //
}
// gen:qs

View File

@ -2500,25 +2500,17 @@ func getErpPurchaseDemandAll(req *GetErpPurchaseDemandReq, c *gin.Context) (*Get
switch req.SortType {
case "desc":
// 排序规则主供应商id大
sort.Slice(commodities, func(i, j int) bool {
return commodities[i].ErpSupplierId > commodities[j].ErpSupplierId
})
SortByErpSupplierId(commodities, true)
case "asc":
// 排序规则主供应商id小
sort.Slice(commodities, func(i, j int) bool {
return commodities[i].ErpSupplierId < commodities[j].ErpSupplierId
})
SortByErpSupplierId(commodities, false)
default:
// 排序规则主供应商id小
sort.Slice(commodities, func(i, j int) bool {
return commodities[i].ErpSupplierId < commodities[j].ErpSupplierId
})
SortByErpSupplierId(commodities, false)
}
} else if req.SortField == "" {
} else {
// 排序规则主供应商id小
sort.Slice(commodities, func(i, j int) bool {
return commodities[i].ErpSupplierId < commodities[j].ErpSupplierId
})
SortByErpSupplierId(commodities, false)
}
}
@ -2549,7 +2541,7 @@ func getErpPurchaseDemandAll(req *GetErpPurchaseDemandReq, c *gin.Context) (*Get
wg.Add(1)
go func(index int, commodity ErpCommodity) {
defer wg.Done()
demandData, err := convertToDemandData(commodity, stores)
demandData, err := convertToDemandDataAll(commodity, stores)
if err != nil {
// Handle error
return
@ -2588,230 +2580,8 @@ func getErpPurchaseDemandAll(req *GetErpPurchaseDemandReq, c *gin.Context) (*Get
return resp, nil
}
// 隐藏无采购需求的商品
func getErpPurchaseDemandHide(req *GetErpPurchaseDemandReq, c *gin.Context) (*GetErpPurchaseDemandResp, error) {
page := req.PageIndex - 1
if page < 0 {
page = 0
}
if req.PageSize == 0 {
req.PageSize = 10
}
resp := &GetErpPurchaseDemandResp{
PageIndex: page + 1,
PageSize: req.PageSize,
}
// 查询采购需求单信息筛选出有采购需求的商品id
var demand []ErpPurchaseDemand
demandQs := orm.Eloquent.Table("erp_purchase_demand").
Where("state = 1")
// 非管理员才判断所属门店
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) > 0 {
if len(storeList) == 1 {
demandQs = demandQs.Where("store_id = ?", storeList[0])
} else {
demandQs = demandQs.Where("store_id IN (?)", storeList)
}
}
} else {
return nil, errors.New("用户未绑定门店")
}
}
err := demandQs.Find(&demand).Error
if err != nil {
return nil, err
}
// 用 map 存储已经出现过的 ErpCommodityId
commodityIds := make(map[uint32]bool)
var uniqueCommodityIds []uint32
for _, d := range demand {
if _, ok := commodityIds[d.ErpCommodityId]; !ok {
commodityIds[d.ErpCommodityId] = true
uniqueCommodityIds = append(uniqueCommodityIds, d.ErpCommodityId)
}
}
// 查询商品信息
qs := orm.Eloquent.Debug().Table("erp_commodity")
if req.ErpCategoryId != 0 {
//qs = qs.Where("erp_category_id=?", req.ErpCategoryId)
categoryInfo, err := GetErpCategory(req.ErpCategoryId)
if err != nil {
return nil, err
}
qs = qs.Where("serial_number like ?", categoryInfo.Number+"%")
}
if req.ErpCommoditySerialNumber != "" {
qs = qs.Where("serial_number=?", req.ErpCommoditySerialNumber)
}
if req.ErpCommodityName != "" {
qs = qs.Where("name=?", req.ErpCommodityName)
}
if req.ErpSupplierId != 0 {
qs = qs.Where("erp_supplier_id=?", req.ErpSupplierId)
}
var count int64
if err := qs.Count(&count).Error; err != nil {
logger.Error("count err:", logger.Field("err", err))
return resp, err
}
var commodities []ErpCommodity
//if req.IsExport == 1 { // 导出excel
// err := qs.Order("id DESC").Find(&commodities).Error
// if err != nil && err != RecordNotFound {
// return resp, err
// }
//} else {
// err := qs.Order("id DESC").Offset(page * req.PageSize).Limit(req.PageSize).Find(&commodities).Error
// if err != nil && err != RecordNotFound {
// return resp, err
// }
//}
err = qs.Order("id DESC").Find(&commodities).Error
if err != nil && err != RecordNotFound {
return resp, err
}
// 匹配商品id有则继续查询返回数据没有则不返回
var matchedCommodities []ErpCommodity
for _, c := range commodities {
for _, uniqueID := range uniqueCommodityIds {
if c.ID == uniqueID {
matchedCommodities = append(matchedCommodities, c)
break // 找到匹配的商品后跳出内层循环,继续下一个商品
}
}
}
if len(matchedCommodities) == 0 {
resp.List = nil
} else {
// 排序
if req.SortField == "erp_commodity_serial_number" {
switch req.SortType {
case "desc":
SortCommoditiesDesc(matchedCommodities)
case "asc":
SortCommoditiesAsc(matchedCommodities)
default:
SortCommoditiesAsc(matchedCommodities)
}
} else {
// 商品编号排序
SortCommoditiesAsc(matchedCommodities)
}
if req.CallType != 2 {
if req.SortField == "erp_supplier_id" {
switch req.SortType {
case "desc":
// 排序规则主供应商id大
sort.Slice(matchedCommodities, func(i, j int) bool {
return matchedCommodities[i].ErpSupplierId > matchedCommodities[j].ErpSupplierId
})
case "asc":
// 排序规则主供应商id小
sort.Slice(matchedCommodities, func(i, j int) bool {
return matchedCommodities[i].ErpSupplierId < matchedCommodities[j].ErpSupplierId
})
default:
// 排序规则主供应商id小
sort.Slice(matchedCommodities, func(i, j int) bool {
return matchedCommodities[i].ErpSupplierId < matchedCommodities[j].ErpSupplierId
})
}
} else {
// 排序规则主供应商id小
sort.Slice(matchedCommodities, func(i, j int) bool {
return matchedCommodities[i].ErpSupplierId < matchedCommodities[j].ErpSupplierId
})
}
}
// 批量查询门店信息
stores, err := GetOnlineStores(c)
if err != nil {
return nil, err
}
// 并行查询需求数据
var wg sync.WaitGroup
var tempCommodities []ErpCommodity
if req.IsExport == 1 {
tempCommodities = matchedCommodities
} else {
// 计算分页
startIndex := page * req.PageSize
endIndex := (page + 1) * req.PageSize
if endIndex > len(matchedCommodities) {
endIndex = len(matchedCommodities)
}
tempCommodities = matchedCommodities[startIndex:endIndex]
}
demandDataList := make([]DemandData, len(tempCommodities))
for i, v := range tempCommodities {
wg.Add(1)
go func(index int, commodity ErpCommodity) {
defer wg.Done()
demandData, err := convertToDemandData(commodity, stores)
if err != nil {
// Handle error
return
}
demandDataList[index] = demandData
}(i, v)
}
wg.Wait()
if req.IsExport == 1 { // 导出excel
if len(demandDataList) == 0 {
return nil, errors.New("未查询到数据")
}
if req.CallType == 2 { // 店员视角
resp.ExportUrl, err = demandDataExportOnShopAssistant(demandDataList)
} else { // 采购视角
resp.ExportUrl, err = demandDataExport(demandDataList)
}
if err != nil {
return nil, err
}
} else {
// 计算分页所需的切片索引
//startIndex := page * req.PageSize
//endIndex := (page + 1) * req.PageSize
//if endIndex > len(demandDataList) {
// endIndex = len(demandDataList)
//}
//resp.List = demandDataList[startIndex:endIndex]
resp.List = demandDataList
resp.Total = int64(len(matchedCommodities))
}
}
return resp, nil
}
// convertToDemandData 将商品转换为采购需求数据
func convertToDemandData(commodity ErpCommodity, stores []Store) (DemandData, error) {
// convertToDemandDataAll 将商品转换为采购需求数据
func convertToDemandDataAll(commodity ErpCommodity, stores []Store) (DemandData, error) {
// 查询采购商品的备注信息
var demandRemarkInfo ErpPurchaseDemandRemark
err := orm.Eloquent.Table("erp_purchase_demand_remark").Where("erp_commodity_id = ? and state = 1",
@ -2858,12 +2628,12 @@ func convertToDemandData(commodity ErpCommodity, stores []Store) (DemandData, er
go func() {
defer wg.Done()
stockCounts, err = GetCommodityStocksByStoreID(commodity.ID, stores)
stockCounts, err = GetCommodityStocksByStoreIDAll(commodity.ID, stores)
}()
go func() {
defer wg.Done()
lastMonthSales, err = GetCommodityLastMonthSales(commodity.ID, stores)
lastMonthSales, err = GetCommodityLastMonthSalesAll(commodity.ID, stores)
}()
wg.Wait()
@ -2908,6 +2678,291 @@ func convertToDemandData(commodity ErpCommodity, stores []Store) (DemandData, er
return demandData, nil
}
// 隐藏无采购需求的商品
func getErpPurchaseDemandHide(req *GetErpPurchaseDemandReq, c *gin.Context) (*GetErpPurchaseDemandResp, error) {
page := req.PageIndex - 1
if page < 0 {
page = 0
}
if req.PageSize == 0 {
req.PageSize = 10
}
resp := &GetErpPurchaseDemandResp{
PageIndex: page + 1,
PageSize: req.PageSize,
}
// 查询采购需求单信息筛选出有采购需求的商品id
var demand []ErpPurchaseDemand
var demandRemarkInfo []ErpPurchaseDemandRemark
demandQs := orm.Eloquent.Table("erp_purchase_demand").
Where("state = 1").Where("count <> 0")
demandRemarkQs := orm.Eloquent.Table("erp_purchase_demand_remark").
Where("state = 1").
Where("remark IS NOT NULL").
Where("remark <> ''")
// 非管理员才判断所属门店
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 {
demandQs = demandQs.Where("store_id = ?", storeList[0])
demandRemarkQs = demandRemarkQs.Where("store_id = ?", storeList[0])
} else {
demandQs = demandQs.Where("store_id IN (?)", storeList)
demandRemarkQs = demandRemarkQs.Where("store_id IN (?)", storeList)
}
} else {
return nil, errors.New("用户未绑定门店")
}
}
err := demandQs.Find(&demand).Error
if err != nil {
return nil, err
}
err = demandRemarkQs.Find(&demandRemarkInfo).Error
if err != nil {
return nil, err
}
demandsMap := make(map[string]ErpPurchaseDemand)
storesMap := make(map[uint32][]uint32)
demandRemarksMap := make(map[uint32]ErpPurchaseDemandRemark)
// 用 sync.Map 存储已经出现过的 ErpCommodityId
commodityIds := sync.Map{}
var uniqueCommodityIds []uint32
for _, d := range demand {
if _, ok := commodityIds.Load(d.ErpCommodityId); !ok {
commodityIds.Store(d.ErpCommodityId, true)
uniqueCommodityIds = append(uniqueCommodityIds, d.ErpCommodityId)
}
key := fmt.Sprintf("%d-%d", d.ErpCommodityId, d.StoreId)
demandsMap[key] = d
// 更新 storesMap
if _, exists := storesMap[d.ErpCommodityId]; !exists {
storesMap[d.ErpCommodityId] = []uint32{d.StoreId}
} else {
storesMap[d.ErpCommodityId] = append(storesMap[d.ErpCommodityId], d.StoreId)
}
}
for _, r := range demandRemarkInfo {
demandRemarksMap[r.ErpCommodityId] = r
}
// 查询商品信息
qs := orm.Eloquent.Debug().Table("erp_commodity")
if req.ErpCategoryId != 0 {
categoryInfo, err := GetErpCategory(req.ErpCategoryId)
if err != nil {
return nil, err
}
qs = qs.Where("serial_number like ?", categoryInfo.Number+"%")
}
if req.ErpCommoditySerialNumber != "" {
qs = qs.Where("serial_number=?", req.ErpCommoditySerialNumber)
}
if req.ErpCommodityName != "" {
qs = qs.Where("name=?", req.ErpCommodityName)
}
if req.ErpSupplierId != 0 {
qs = qs.Where("erp_supplier_id=?", req.ErpSupplierId)
}
var count int64
if err := qs.Count(&count).Error; err != nil {
logger.Error("count err:", logger.Field("err", err))
return resp, err
}
var commodities []ErpCommodity
err = qs.Order("id DESC").Find(&commodities).Error
if err != nil && err != RecordNotFound {
return resp, err
}
// 匹配商品id有则继续查询返回数据没有则不返回
var matchedCommodities []ErpCommodity
for _, item := range commodities {
if _, ok := commodityIds.Load(item.ID); ok {
matchedCommodities = append(matchedCommodities, item)
}
}
if len(matchedCommodities) == 0 {
resp.List = nil
} else {
// 排序
if req.SortField == "erp_commodity_serial_number" {
switch req.SortType {
case "desc":
SortCommoditiesDesc(matchedCommodities)
case "asc":
SortCommoditiesAsc(matchedCommodities)
default:
SortCommoditiesAsc(matchedCommodities)
}
} else {
// 商品编号排序
SortCommoditiesAsc(matchedCommodities)
}
if req.CallType != 2 {
if req.SortField == "erp_supplier_id" {
switch req.SortType {
case "desc":
// 排序规则主供应商id大
SortByErpSupplierId(matchedCommodities, true)
case "asc":
// 排序规则主供应商id小
SortByErpSupplierId(matchedCommodities, false)
default:
// 排序规则主供应商id小
SortByErpSupplierId(matchedCommodities, false)
}
} else {
// 排序规则主供应商id小
SortByErpSupplierId(matchedCommodities, false)
}
}
// 批量查询门店信息
stores, err := GetOnlineStores(c)
if err != nil {
return nil, err
}
// 并行查询需求数据
var wg sync.WaitGroup
var tempCommodities []ErpCommodity
if req.IsExport == 1 {
tempCommodities = matchedCommodities
} else {
// 计算分页
startIndex := page * req.PageSize
endIndex := (page + 1) * req.PageSize
if endIndex > len(matchedCommodities) {
endIndex = len(matchedCommodities)
}
tempCommodities = matchedCommodities[startIndex:endIndex]
}
demandDataList := make([]DemandData, len(tempCommodities))
for i, v := range tempCommodities {
wg.Add(1)
go func(index int, commodity ErpCommodity) {
defer wg.Done()
demandData, err := convertToDemandData(commodity, storesMap[commodity.ID], stores, demandRemarksMap, demandsMap)
if err != nil {
// Handle error
return
}
demandDataList[index] = demandData
}(i, v)
}
wg.Wait()
if req.IsExport == 1 { // 导出excel
if len(demandDataList) == 0 {
return nil, errors.New("未查询到数据")
}
if req.CallType == 2 { // 店员视角
resp.ExportUrl, err = demandDataExportOnShopAssistant(demandDataList)
} else { // 采购视角
resp.ExportUrl, err = demandDataExport(demandDataList)
}
if err != nil {
return nil, err
}
} else {
resp.List = demandDataList
resp.Total = int64(len(matchedCommodities))
}
}
return resp, nil
}
// convertToDemandData 将商品转换为采购需求数据
func convertToDemandData(commodity ErpCommodity, usedStore []uint32, stores []Store, demandRemarksMap map[uint32]ErpPurchaseDemandRemark, demandMap map[string]ErpPurchaseDemand) (DemandData, error) {
demandData := DemandData{
ErpSupplierId: commodity.ErpSupplierId,
ErpSupplierName: commodity.ErpSupplierName,
ErpCommodityID: commodity.ID,
ErpCommoditySerialNumber: commodity.SerialNumber,
ErpCommodityName: commodity.Name,
ErpCategoryID: commodity.ErpCategoryId,
ErpCategoryName: commodity.ErpCategoryName,
RetailPrice: commodity.RetailPrice,
Remark: demandRemarksMap[commodity.ID].Remark,
}
var demands []ErpPurchaseDemand
for _, store := range usedStore {
key := fmt.Sprintf("%d-%d", commodity.ID, store)
v, ok := demandMap[key]
if !ok {
continue
}
demands = append(demands, v)
}
var lastWholesalePrices map[uint32]float64
var stockCounts map[uint32]uint32
var lastMonthSales map[uint32]uint32
lastWholesalePrices, _ = GetCommodityLastWholesalePrices(commodity.ID)
stockCounts, _ = GetCommodityStocksByStoreID(commodity.ID, usedStore)
lastMonthSales, _ = GetCommodityLastMonthSales(commodity.ID, usedStore)
var totalCount uint32
demandData.StoreList = make([]struct {
StoreID uint32 `json:"store_id"`
StoreName string `json:"store_name"`
LastMonthSales uint32 `json:"last_month_sales"`
StockCount uint32 `json:"stock_count"`
NeedCount uint32 `json:"need_count"`
}, len(stores))
for i, store := range stores {
demandData.StoreList[i].StoreID = store.ID
demandData.StoreList[i].StoreName = store.Name
demandData.StoreList[i].StockCount = stockCounts[store.ID]
demandData.StoreList[i].LastMonthSales = lastMonthSales[store.ID]
demandData.LastWholesalePrice = lastWholesalePrices[commodity.ID]
for _, demand := range demands {
if demand.StoreId == store.ID {
demandData.StoreList[i].NeedCount = demand.Count
totalCount += demand.Count
break
}
}
}
demandData.TotalCount = totalCount
demandData.TotalAmount = float64(totalCount) * demandData.LastWholesalePrice
return demandData, nil
}
// GetCommodityPurchaseDemands 查询商品的采购需求单
func GetCommodityPurchaseDemands(commodityID uint32, stores []Store) ([]ErpPurchaseDemand, error) {
var wg sync.WaitGroup
@ -2915,6 +2970,24 @@ func GetCommodityPurchaseDemands(commodityID uint32, stores []Store) ([]ErpPurch
var demands []ErpPurchaseDemand
wg.Add(len(stores))
//for _, store := range stores {
// go func(storeID uint32) {
// defer wg.Done()
// var demand ErpPurchaseDemand
// err := orm.Eloquent.Table("erp_purchase_demand").
// Where("erp_commodity_id = ? AND state = 1 AND store_id = ?", commodityID, storeID).
// First(&demand).Error
// if err != nil {
// // Handle error
// return
// }
//
// mu.Lock()
// defer mu.Unlock()
// demands = append(demands, demand)
// }(store.ID)
//}
for _, store := range stores {
go func(storeID uint32) {
defer wg.Done()
@ -2922,14 +2995,18 @@ func GetCommodityPurchaseDemands(commodityID uint32, stores []Store) ([]ErpPurch
err := orm.Eloquent.Table("erp_purchase_demand").
Where("erp_commodity_id = ? AND state = 1 AND store_id = ?", commodityID, storeID).
First(&demand).Error
if err != nil {
// Handle error
if err != nil && err != gorm.ErrRecordNotFound {
// Log the error but do not return it, to ensure other goroutines complete
logger.Error("query erp_purchase_demand err:", logger.Field("err", err))
return
}
mu.Lock()
defer mu.Unlock()
demands = append(demands, demand)
// If no record is found, err == gorm.ErrRecordNotFound, we ignore it and not append to demands
if err == nil {
mu.Lock()
demands = append(demands, demand)
mu.Unlock()
}
}(store.ID)
}
@ -2964,7 +3041,85 @@ func GetCommodityLastWholesalePrices(commodityID uint32) (map[uint32]float64, er
}
// GetCommodityStocksByStoreID 批量查询商品的库存情况
func GetCommodityStocksByStoreID(commodityID uint32, stores []Store) (map[uint32]uint32, error) {
func GetCommodityStocksByStoreID(commodityID uint32, stores []uint32) (map[uint32]uint32, error) {
// 并行查询库存情况
var wg sync.WaitGroup
wg.Add(len(stores))
result := make(map[uint32]uint32)
for _, store := range stores {
go func(storeID uint32) {
defer wg.Done()
// 查询库存情况
var stockCount int64
err := orm.Eloquent.Table("erp_stock_commodity").
Where("erp_commodity_id = ? AND store_id = ? AND state = 1", commodityID, storeID).
Count(&stockCount).Error
if err != nil {
// Handle error
return
}
result[storeID] = uint32(stockCount)
}(store)
}
wg.Wait()
return result, nil
}
// GetCommodityStockByPurchaseId 查询入库商品实际库存详情处剩余有效数,不包含已出库的数量
func GetCommodityStockByPurchaseId(serialNumber string, orderId uint32) (uint32, error) {
var count int64
err := orm.Eloquent.Table("erp_stock_commodity").Where("original_sn = ? and erp_commodity_id = ? and state = ?",
serialNumber, orderId, InStock).Count(&count).Error
if err != nil {
return 0, err
}
return uint32(count), nil
}
// GetCommodityLastMonthSales 批量查询商品的上月销售数量
func GetCommodityLastMonthSales(commodityID uint32, stores []uint32) (map[uint32]uint32, error) {
// 获取上个月的时间范围
firstDay, lastDay := GetLastMonthRange()
// 并行查询上月销售数量
var wg sync.WaitGroup
wg.Add(len(stores))
result := make(map[uint32]uint32)
var mu sync.Mutex // 用于保护 totalSales 的并发访问
for _, store := range stores {
go func(storeID uint32) {
defer wg.Done()
// 查询上月销售数量
var sales int64
err := orm.Eloquent.Table("erp_stock_commodity").
Where("state = ? AND erp_commodity_id = ? AND store_id = ? AND updated_at BETWEEN ? AND ?",
SoldOut, commodityID, storeID, firstDay, lastDay).Count(&sales).Error
if err != nil {
// Handle error
return
}
// 保护 totalSales 的并发访问
mu.Lock()
defer mu.Unlock()
result[storeID] = uint32(sales)
}(store)
}
wg.Wait()
return result, nil
}
// GetCommodityStocksByStoreIDAll 批量查询商品的库存情况
func GetCommodityStocksByStoreIDAll(commodityID uint32, stores []Store) (map[uint32]uint32, error) {
// 并行查询库存情况
var wg sync.WaitGroup
wg.Add(len(stores))
@ -2992,20 +3147,8 @@ func GetCommodityStocksByStoreID(commodityID uint32, stores []Store) (map[uint32
return result, nil
}
// GetCommodityStockByPurchaseId 查询入库商品实际库存详情处剩余有效数,不包含已出库的数量
func GetCommodityStockByPurchaseId(serialNumber string, orderId uint32) (uint32, error) {
var count int64
err := orm.Eloquent.Table("erp_stock_commodity").Where("original_sn = ? and erp_commodity_id = ? and state = ?",
serialNumber, orderId, InStock).Count(&count).Error
if err != nil {
return 0, err
}
return uint32(count), nil
}
// GetCommodityLastMonthSales 批量查询商品的上月销售数量
func GetCommodityLastMonthSales(commodityID uint32, stores []Store) (map[uint32]uint32, error) {
// GetCommodityLastMonthSalesAll 批量查询商品的上月销售数量
func GetCommodityLastMonthSalesAll(commodityID uint32, stores []Store) (map[uint32]uint32, error) {
// 获取上个月的时间范围
firstDay, lastDay := GetLastMonthRange()