1.修复采购需求的缺陷;
2.优惠券Coupon增加规则字段rule;
This commit is contained in:
parent
1212d9dd1e
commit
596fd1dc44
|
@ -521,6 +521,44 @@ func (m *ErpCommodityListReq) List() (*ErpCommodityListResp, error) {
|
||||||
return resp, nil
|
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 对库存商品数组进行排序
|
// SortStockCommodities 对库存商品数组进行排序
|
||||||
func SortStockCommodities(commodities []ErpStock) {
|
func SortStockCommodities(commodities []ErpStock) {
|
||||||
// 定义排序函数
|
// 定义排序函数
|
||||||
|
|
|
@ -12,18 +12,19 @@ const (
|
||||||
type Coupon struct {
|
type Coupon struct {
|
||||||
Model
|
Model
|
||||||
|
|
||||||
Name string `json:"name"`
|
Name string `json:"name"` // 优惠券名称
|
||||||
Describe string `json:"describe" gorm:"type:text;"` // 描述
|
Describe string `json:"describe" gorm:"type:text"` // 优惠券简介
|
||||||
CouponType string `json:"coupon_type"`
|
Rule string `json:"rule" gorm:"type:text"` // 优惠券使用规则
|
||||||
ActivityType uint32 `json:"activity_type"` // 活动类型 1-会员续费
|
CouponType string `json:"coupon_type"` //
|
||||||
ActivityId uint32 `json:"activity_id" gorm:"index"`
|
ActivityType uint32 `json:"activity_type"` // 活动类型 1-会员续费
|
||||||
Value uint32 `json:"value"`
|
ActivityId uint32 `json:"activity_id" gorm:"index"` //
|
||||||
OutCount uint32 `json:"out_count"` // 用户已领取数量
|
Value uint32 `json:"value"` //
|
||||||
UsedCount uint32 `json:"used_count"` // 用户已使用数量
|
OutCount uint32 `json:"out_count"` // 用户已领取数量
|
||||||
ActiveStart time.Time `json:"active_start"` // 有效期开始
|
UsedCount uint32 `json:"used_count"` // 用户已使用数量
|
||||||
ActiveEnd time.Time `json:"active_end"` // 有效期结束 零值永不结束
|
ActiveStart time.Time `json:"active_start"` // 有效期开始
|
||||||
MemberLevel uint32 `json:"member_level"` // 会员等级 1-用户 2-会员
|
ActiveEnd time.Time `json:"active_end"` // 有效期结束 零值永不结束
|
||||||
IsDraw bool `json:"is_draw" gorm:"-"`
|
MemberLevel uint32 `json:"member_level"` // 会员等级 1-用户 2-会员
|
||||||
|
IsDraw bool `json:"is_draw" gorm:"-"` //
|
||||||
}
|
}
|
||||||
|
|
||||||
// gen:qs
|
// gen:qs
|
||||||
|
|
|
@ -2500,25 +2500,17 @@ func getErpPurchaseDemandAll(req *GetErpPurchaseDemandReq, c *gin.Context) (*Get
|
||||||
switch req.SortType {
|
switch req.SortType {
|
||||||
case "desc":
|
case "desc":
|
||||||
// 排序规则:主供应商id大
|
// 排序规则:主供应商id大
|
||||||
sort.Slice(commodities, func(i, j int) bool {
|
SortByErpSupplierId(commodities, true)
|
||||||
return commodities[i].ErpSupplierId > commodities[j].ErpSupplierId
|
|
||||||
})
|
|
||||||
case "asc":
|
case "asc":
|
||||||
// 排序规则:主供应商id小
|
// 排序规则:主供应商id小
|
||||||
sort.Slice(commodities, func(i, j int) bool {
|
SortByErpSupplierId(commodities, false)
|
||||||
return commodities[i].ErpSupplierId < commodities[j].ErpSupplierId
|
|
||||||
})
|
|
||||||
default:
|
default:
|
||||||
// 排序规则:主供应商id小
|
// 排序规则:主供应商id小
|
||||||
sort.Slice(commodities, func(i, j int) bool {
|
SortByErpSupplierId(commodities, false)
|
||||||
return commodities[i].ErpSupplierId < commodities[j].ErpSupplierId
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
} else if req.SortField == "" {
|
} else {
|
||||||
// 排序规则:主供应商id小
|
// 排序规则:主供应商id小
|
||||||
sort.Slice(commodities, func(i, j int) bool {
|
SortByErpSupplierId(commodities, false)
|
||||||
return commodities[i].ErpSupplierId < commodities[j].ErpSupplierId
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2549,7 +2541,7 @@ func getErpPurchaseDemandAll(req *GetErpPurchaseDemandReq, c *gin.Context) (*Get
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
go func(index int, commodity ErpCommodity) {
|
go func(index int, commodity ErpCommodity) {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
demandData, err := convertToDemandData(commodity, stores)
|
demandData, err := convertToDemandDataAll(commodity, stores)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// Handle error
|
// Handle error
|
||||||
return
|
return
|
||||||
|
@ -2588,230 +2580,8 @@ func getErpPurchaseDemandAll(req *GetErpPurchaseDemandReq, c *gin.Context) (*Get
|
||||||
return resp, nil
|
return resp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// 隐藏无采购需求的商品
|
// convertToDemandDataAll 将商品转换为采购需求数据
|
||||||
func getErpPurchaseDemandHide(req *GetErpPurchaseDemandReq, c *gin.Context) (*GetErpPurchaseDemandResp, error) {
|
func convertToDemandDataAll(commodity ErpCommodity, stores []Store) (DemandData, 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) {
|
|
||||||
// 查询采购商品的备注信息
|
// 查询采购商品的备注信息
|
||||||
var demandRemarkInfo ErpPurchaseDemandRemark
|
var demandRemarkInfo ErpPurchaseDemandRemark
|
||||||
err := orm.Eloquent.Table("erp_purchase_demand_remark").Where("erp_commodity_id = ? and state = 1",
|
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() {
|
go func() {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
stockCounts, err = GetCommodityStocksByStoreID(commodity.ID, stores)
|
stockCounts, err = GetCommodityStocksByStoreIDAll(commodity.ID, stores)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
lastMonthSales, err = GetCommodityLastMonthSales(commodity.ID, stores)
|
lastMonthSales, err = GetCommodityLastMonthSalesAll(commodity.ID, stores)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
|
@ -2908,6 +2678,291 @@ func convertToDemandData(commodity ErpCommodity, stores []Store) (DemandData, er
|
||||||
return demandData, nil
|
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 查询商品的采购需求单
|
// GetCommodityPurchaseDemands 查询商品的采购需求单
|
||||||
func GetCommodityPurchaseDemands(commodityID uint32, stores []Store) ([]ErpPurchaseDemand, error) {
|
func GetCommodityPurchaseDemands(commodityID uint32, stores []Store) ([]ErpPurchaseDemand, error) {
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
|
@ -2915,6 +2970,24 @@ func GetCommodityPurchaseDemands(commodityID uint32, stores []Store) ([]ErpPurch
|
||||||
var demands []ErpPurchaseDemand
|
var demands []ErpPurchaseDemand
|
||||||
wg.Add(len(stores))
|
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 {
|
for _, store := range stores {
|
||||||
go func(storeID uint32) {
|
go func(storeID uint32) {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
|
@ -2922,14 +2995,18 @@ func GetCommodityPurchaseDemands(commodityID uint32, stores []Store) ([]ErpPurch
|
||||||
err := orm.Eloquent.Table("erp_purchase_demand").
|
err := orm.Eloquent.Table("erp_purchase_demand").
|
||||||
Where("erp_commodity_id = ? AND state = 1 AND store_id = ?", commodityID, storeID).
|
Where("erp_commodity_id = ? AND state = 1 AND store_id = ?", commodityID, storeID).
|
||||||
First(&demand).Error
|
First(&demand).Error
|
||||||
if err != nil {
|
if err != nil && err != gorm.ErrRecordNotFound {
|
||||||
// Handle error
|
// 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
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
mu.Lock()
|
// If no record is found, err == gorm.ErrRecordNotFound, we ignore it and not append to demands
|
||||||
defer mu.Unlock()
|
if err == nil {
|
||||||
demands = append(demands, demand)
|
mu.Lock()
|
||||||
|
demands = append(demands, demand)
|
||||||
|
mu.Unlock()
|
||||||
|
}
|
||||||
}(store.ID)
|
}(store.ID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2964,7 +3041,85 @@ func GetCommodityLastWholesalePrices(commodityID uint32) (map[uint32]float64, er
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetCommodityStocksByStoreID 批量查询商品的库存情况
|
// 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
|
var wg sync.WaitGroup
|
||||||
wg.Add(len(stores))
|
wg.Add(len(stores))
|
||||||
|
@ -2992,20 +3147,8 @@ func GetCommodityStocksByStoreID(commodityID uint32, stores []Store) (map[uint32
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetCommodityStockByPurchaseId 查询入库商品实际库存详情处剩余有效数,不包含已出库的数量
|
// GetCommodityLastMonthSalesAll 批量查询商品的上月销售数量
|
||||||
func GetCommodityStockByPurchaseId(serialNumber string, orderId uint32) (uint32, error) {
|
func GetCommodityLastMonthSalesAll(commodityID uint32, stores []Store) (map[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) {
|
|
||||||
// 获取上个月的时间范围
|
// 获取上个月的时间范围
|
||||||
firstDay, lastDay := GetLastMonthRange()
|
firstDay, lastDay := GetLastMonthRange()
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user