1、优化零售批量导入商品,解决超时问题;
This commit is contained in:
parent
19e1647154
commit
429c5a203a
|
@ -122,7 +122,7 @@ func GetInventoryDetail(c *gin.Context) {
|
|||
// @Accept json
|
||||
// @Param request body models.NewErpStockCommodityListReq true "查询库存详情模型"
|
||||
// @Success 200 {object} models.ErpStockCommodityListResp
|
||||
// @Router /api/v1/inventory/detail [post]
|
||||
// @Router /api/v1/inventory/detail_new [post]
|
||||
func GetInventoryDetailNew(c *gin.Context) {
|
||||
req := &models.NewErpStockCommodityListReq{}
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
|
|
|
@ -310,7 +310,7 @@ type ErpCommodityListReq struct {
|
|||
IMEI string `json:"imei"` // 串码
|
||||
ErpBarcode string `json:"erp_barcode"` // 商品条码
|
||||
ErpSupplierId uint32 `json:"erp_supplier_id"` // 供应商id
|
||||
PurchaseType uint32 `json:"purchase_type"` // 0-全部,1-正常采购,2-停止采购
|
||||
PurchaseType uint32 `json:"purchase_type"` // 1-正常采购,2-停止采购
|
||||
PageIndex int `json:"pageIndex"` // 页码
|
||||
PageSize int `json:"pageSize"` // 每页展示数据条数
|
||||
IsExport uint32 `json:"is_export"` // 1-导出
|
||||
|
|
|
@ -15,6 +15,7 @@ import (
|
|||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
"unicode"
|
||||
"unicode/utf8"
|
||||
|
@ -612,6 +613,38 @@ func isInputTimeBeforeOrEqualNow(inputTimeString string) (bool, error) {
|
|||
return !isBeforeOrEqual, nil
|
||||
}
|
||||
|
||||
// 校验第5列门店名称是否相同
|
||||
func hasDuplicateStore(sheetCols [][]string) (string, bool) {
|
||||
storeMap := make(map[string]struct{})
|
||||
var storeName string
|
||||
|
||||
for row := 1; row < len(sheetCols); row++ {
|
||||
// 获取当前行的门店名称
|
||||
currentStore := sheetCols[4][row] // 第5列门店名称
|
||||
|
||||
if currentStore == "" {
|
||||
continue // 如果门店名称为空,跳过该行
|
||||
}
|
||||
|
||||
// 如果这是第一次遇到门店名称,记录下来
|
||||
if storeName == "" {
|
||||
storeName = currentStore
|
||||
}
|
||||
|
||||
// 检查当前门店名称是否与之前的名称一致
|
||||
if currentStore != storeName {
|
||||
// 找到不一致的门店名称,返回不一致的门店名称和标记为true
|
||||
return currentStore, true
|
||||
}
|
||||
|
||||
// 存储门店名称
|
||||
storeMap[currentStore] = struct{}{}
|
||||
}
|
||||
|
||||
// 如果没有发现不一致的门店名称,返回空字符串和false
|
||||
return "", false
|
||||
}
|
||||
|
||||
// 校验串码是否相同,有则false
|
||||
func hasDuplicateIMEI(sheetCols []string) (string, bool) {
|
||||
nameMap := make(map[string]struct{})
|
||||
|
@ -1360,139 +1393,346 @@ func IsExistingCommodity(commodityId uint32) bool {
|
|||
// 商品名称和串码是否对应
|
||||
// 串码商品数量只能为1
|
||||
// 是否有库存
|
||||
//func checkOrderExcel(sheetCols [][]string) error {
|
||||
// if len(sheetCols) != 8 {
|
||||
// return errors.New("模版错误,请检查文件")
|
||||
// }
|
||||
//
|
||||
// maxLength := findMaxLength(sheetCols)
|
||||
// nLow, nMax := determineLowAndMax(sheetCols)
|
||||
//
|
||||
// if nMax < maxLength {
|
||||
// return errors.New("第" + strconv.Itoa(nMax+1) + "行商品名称和商品编号不能同时为空")
|
||||
// }
|
||||
//
|
||||
// // 判断是否有重复串码
|
||||
// if duplicateName, nFlag := hasDuplicateIMEI(sheetCols[2]); nFlag {
|
||||
// return fmt.Errorf("商品串码不允许重复,请检查:[%v]", duplicateName)
|
||||
// }
|
||||
//
|
||||
// //先遍历第1列
|
||||
// for i := 1; i < nLow; i++ {
|
||||
// if sheetCols[0][i] == "" && sheetCols[1][i] == "" { // 商品名称和编号不能都为空
|
||||
// return errors.New("第" + strconv.Itoa(i+1) + "行商品名称和商品编号不能同时为空")
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// for i := 1; i < nMax; i++ {
|
||||
// if i < len(sheetCols[1]) {
|
||||
// if !IsExistingProduct(sheetCols[1][i]) {
|
||||
// return errors.New("第" + strconv.Itoa(i+1) + "行商品不存在")
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // 商品编号必须为纯数字
|
||||
// if i < len(sheetCols[0]) {
|
||||
// if sheetCols[0][i] != "" {
|
||||
// if _, err := strconv.Atoi(sheetCols[0][i]); err != nil {
|
||||
// return errors.New("第" + strconv.Itoa(i+1) + "行商品编号必须为纯数字")
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if !isExistingProductCode(sheetCols[0][i]) {
|
||||
// return errors.New("第" + strconv.Itoa(i+1) + "行商品编号不存在")
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // 所属门店不能为空
|
||||
// if i < len(sheetCols[4]) {
|
||||
// if sheetCols[4][i] == "" {
|
||||
// return errors.New("第" + strconv.Itoa(i+1) + "行所属门店不能为空")
|
||||
// }
|
||||
// if !isExistingStore(sheetCols[4][i]) {
|
||||
// return errors.New("第" + strconv.Itoa(i+1) + "行门店不存在")
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // 数量必须为正整数
|
||||
// if i < len(sheetCols[3]) {
|
||||
// if quantity, err := strconv.Atoi(sheetCols[3][i]); err != nil || quantity < 1 {
|
||||
// return errors.New("第" + strconv.Itoa(i+1) + "行数量必须是大于等于1的整数")
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // 串码商品数量只能为1
|
||||
// var nCount int
|
||||
// if i < len(sheetCols[3]) {
|
||||
// if i < len(sheetCols[3]) {
|
||||
// nCount, _ = strconv.Atoi(sheetCols[3][i])
|
||||
// }
|
||||
//
|
||||
// // 串码类商品数量只能为1
|
||||
// if sheetCols[2][i] != "" && nCount != 1 {
|
||||
// return errors.New("第" + strconv.Itoa(i+1) + "行串码类商品数量只能为1")
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // 判断商品是否赠送
|
||||
// if i < len(sheetCols[6]) {
|
||||
// if sheetCols[6][i] != "是" && sheetCols[6][i] != "" {
|
||||
// return errors.New("第" + strconv.Itoa(i+1) + "行商品是否赠送填写有误")
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // 查询商品是否有库存
|
||||
// if sheetCols[2][i] != "" { // 串码商品
|
||||
// var imeiStockCommodity ErpStockCommodity
|
||||
// err := orm.Eloquent.Table("erp_stock_commodity").Where("imei = ? and state = ?",
|
||||
// sheetCols[2][i], InStock).
|
||||
// Find(&imeiStockCommodity).Error
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
// if imeiStockCommodity.ID == 0 {
|
||||
// return errors.New("第" + strconv.Itoa(i+1) + "行商品不存在")
|
||||
// }
|
||||
// // 门店对比
|
||||
// if imeiStockCommodity.StoreName != sheetCols[4][i] {
|
||||
// return errors.New("第" + strconv.Itoa(i+1) + "行商品" +
|
||||
// "[" + imeiStockCommodity.ErpCommodityName + "]非所选门店库存,请检查")
|
||||
// }
|
||||
// // 零售价对比
|
||||
// var floatVal float64
|
||||
// if i < len(sheetCols[5]) {
|
||||
// if sheetCols[5][i] != "" {
|
||||
// floatVal, err = strconv.ParseFloat(sheetCols[5][i], 64)
|
||||
// if err != nil {
|
||||
// return errors.New("第" + strconv.Itoa(i+1) + "行零售价有误")
|
||||
// }
|
||||
// strMin := strconv.FormatFloat(imeiStockCommodity.MinRetailPrice, 'f', 2, 64)
|
||||
// if floatVal < imeiStockCommodity.MinRetailPrice {
|
||||
// return errors.New("第" + strconv.Itoa(i+1) + "行零售价有误,不能低于最低零售价[" + strMin + "]")
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// } else { // 非串码商品
|
||||
// var count int64
|
||||
// var err error
|
||||
// if sheetCols[0][i] != "" { // 商品编号不为空
|
||||
// err = orm.Eloquent.Table("erp_stock_commodity").
|
||||
// Where("commodity_serial_number = ? and store_name = ? and state = ? and imei_type = ?",
|
||||
// sheetCols[0][i], sheetCols[4][i], InStock, NoIMEICommodity).
|
||||
// Count(&count).Error
|
||||
// } else {
|
||||
// err = orm.Eloquent.Table("erp_stock_commodity").
|
||||
// Where("erp_commodity_name = ? and store_name = ? and state = ? and imei_type = ?",
|
||||
// sheetCols[1][i], sheetCols[4][i], InStock, NoIMEICommodity).
|
||||
// Count(&count).Error
|
||||
// }
|
||||
// if err != nil {
|
||||
// return errors.New("第" + strconv.Itoa(i+1) + "行商品不存在")
|
||||
// }
|
||||
//
|
||||
// if count < int64(nCount) {
|
||||
// // 获取商品名称
|
||||
// return errors.New("第" + strconv.Itoa(i+1) + "行商品" + "[" + sheetCols[1][i] + "]库存不足")
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// return nil
|
||||
//}
|
||||
|
||||
func checkOrderExcel(sheetCols [][]string) error {
|
||||
// 校验列数是否正确
|
||||
if len(sheetCols) != 8 {
|
||||
return errors.New("模版错误,请检查文件")
|
||||
}
|
||||
|
||||
maxLength := findMaxLength(sheetCols)
|
||||
nLow, nMax := determineLowAndMax(sheetCols)
|
||||
|
||||
if nMax < maxLength {
|
||||
return errors.New("第" + strconv.Itoa(nMax+1) + "行商品名称和商品编号不能同时为空")
|
||||
// 获取最大行数
|
||||
nMax := findMaxLength(sheetCols)
|
||||
if nMax == 0 {
|
||||
return errors.New("模版内容为空")
|
||||
}
|
||||
|
||||
// 判断是否有重复串码
|
||||
// 校验商品串码是否重复
|
||||
if duplicateName, nFlag := hasDuplicateIMEI(sheetCols[2]); nFlag {
|
||||
return fmt.Errorf("商品串码不允许重复,请检查:[%v]", duplicateName)
|
||||
}
|
||||
|
||||
//先遍历第1列
|
||||
for i := 1; i < nLow; i++ {
|
||||
if sheetCols[0][i] == "" && sheetCols[1][i] == "" { // 商品名称和编号不能都为空
|
||||
return errors.New("第" + strconv.Itoa(i+1) + "行商品名称和商品编号不能同时为空")
|
||||
// 判断门店名称是否有不同
|
||||
if duplicateName, nFlag := hasDuplicateStore(sheetCols); nFlag {
|
||||
return fmt.Errorf("门店名称不同,请检查:[%v]", duplicateName)
|
||||
}
|
||||
|
||||
// 缓存商品编号、商品名称和门店查询结果
|
||||
productCodeCache := make(map[string]bool)
|
||||
productNameCache := make(map[string]bool)
|
||||
storeCache := make(map[string]bool)
|
||||
|
||||
// 预加载所有商品编号、商品名称和门店
|
||||
loadAllProductsIntoCache(productCodeCache, productNameCache)
|
||||
loadAllStoresIntoCache(storeCache)
|
||||
|
||||
// 通道用于并发校验
|
||||
var wg sync.WaitGroup
|
||||
errCh := make(chan error, 10)
|
||||
|
||||
// 限制最大并发数量
|
||||
maxConcurrency := 10
|
||||
sem := make(chan struct{}, maxConcurrency)
|
||||
|
||||
for i := 1; i < nMax; i++ {
|
||||
// 校验行是否越界
|
||||
if !isRowValid(sheetCols, i) {
|
||||
continue
|
||||
}
|
||||
|
||||
// 等待一个空位
|
||||
sem <- struct{}{}
|
||||
wg.Add(1)
|
||||
go func(row int) {
|
||||
defer wg.Done()
|
||||
defer func() { <-sem }() // 完成任务后释放空位
|
||||
|
||||
if err := validateRow(sheetCols, row, productCodeCache, productNameCache, storeCache); err != nil {
|
||||
errCh <- fmt.Errorf("第 %d 行: %v", row+1, err)
|
||||
}
|
||||
}(i)
|
||||
}
|
||||
|
||||
wg.Wait()
|
||||
close(errCh)
|
||||
|
||||
// 返回第一个错误
|
||||
for err := range errCh {
|
||||
return err
|
||||
}
|
||||
|
||||
validateStock(sheetCols)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// 检查第 row 行是否所有列都有有效数据
|
||||
func isRowValid(sheetCols [][]string, row int) bool {
|
||||
for _, col := range sheetCols {
|
||||
if row >= len(col) { // 行数超出当前列的长度
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// 批量加载商品信息到缓存
|
||||
func loadAllProductsIntoCache(productCodeCache, productNameCache map[string]bool) {
|
||||
var products []ErpCommodity
|
||||
orm.Eloquent.Debug().Find(&products)
|
||||
for _, product := range products {
|
||||
productCodeCache[product.SerialNumber] = true
|
||||
productNameCache[product.Name] = true
|
||||
}
|
||||
}
|
||||
|
||||
// 批量加载门店信息到缓存
|
||||
func loadAllStoresIntoCache(storeCache map[string]bool) {
|
||||
var stores []Store
|
||||
orm.Eloquent.Debug().Find(&stores)
|
||||
for _, store := range stores {
|
||||
storeCache[store.Name] = true
|
||||
}
|
||||
}
|
||||
|
||||
// 校验单行数据
|
||||
func validateRow(sheetCols [][]string, row int, productCodeCache, productNameCache, storeCache map[string]bool) error {
|
||||
fmt.Println("row is:", row)
|
||||
// 校验商品名称和商品编号
|
||||
if sheetCols[0][row] == "" && sheetCols[1][row] == "" {
|
||||
return errors.New("商品名称和商品编号不能同时为空")
|
||||
}
|
||||
|
||||
// 校验商品编号是否存在
|
||||
if sheetCols[0][row] != "" {
|
||||
if _, err := strconv.Atoi(sheetCols[0][row]); err != nil {
|
||||
return errors.New("商品编号必须为纯数字")
|
||||
}
|
||||
if !productCodeCache[sheetCols[0][row]] {
|
||||
return errors.New("商品编号不存在")
|
||||
}
|
||||
}
|
||||
|
||||
for i := 1; i < nMax; i++ {
|
||||
if i < len(sheetCols[1]) {
|
||||
if !IsExistingProduct(sheetCols[1][i]) {
|
||||
return errors.New("第" + strconv.Itoa(i+1) + "行商品不存在")
|
||||
// 校验商品名称是否存在
|
||||
if sheetCols[1][row] != "" && !productNameCache[sheetCols[1][row]] {
|
||||
return errors.New("商品名称不存在")
|
||||
}
|
||||
|
||||
// 校验所属门店是否存在
|
||||
if sheetCols[4][row] == "" || !storeCache[sheetCols[4][row]] {
|
||||
return errors.New("所属门店不能为空或不存在")
|
||||
}
|
||||
|
||||
// 校验数量是否为正整数
|
||||
if quantity, err := strconv.Atoi(sheetCols[3][row]); err != nil || quantity < 1 {
|
||||
return errors.New("数量必须是大于等于1的整数")
|
||||
}
|
||||
|
||||
// 校验串码商品数量只能为1
|
||||
if sheetCols[2][row] != "" && sheetCols[3][row] != "1" {
|
||||
return errors.New("串码类商品数量只能为1")
|
||||
}
|
||||
|
||||
// 校验商品是否赠送
|
||||
if sheetCols[6][row] != "" && sheetCols[6][row] != "是" {
|
||||
return errors.New("商品是否赠送填写有误")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// validateStock 校验库存信息
|
||||
func validateStock(sheetCols [][]string) error {
|
||||
// 预加载所有库存数据,按门店 store_id 过滤
|
||||
var imeiStockCommodities []ErpStockCommodity
|
||||
err := orm.Eloquent.Table("erp_stock_commodity").
|
||||
Where("state = ? AND store_name = ?", InStock, sheetCols[4][1]).
|
||||
Find(&imeiStockCommodities).Error
|
||||
if err != nil {
|
||||
return fmt.Errorf("加载库存数据失败: %v", err)
|
||||
}
|
||||
|
||||
// 构建库存缓存:按 imei 和非串码商品分组
|
||||
imeiStockMap := make(map[string]ErpStockCommodity) // 串码商品缓存
|
||||
nonIMEIStockMap := make(map[string]map[string]int64) // 非串码商品库存,按 store -> commodity 分组
|
||||
for _, stock := range imeiStockCommodities {
|
||||
if stock.IMEI != "" {
|
||||
imeiStockMap[stock.IMEI] = stock
|
||||
} else {
|
||||
if _, exists := nonIMEIStockMap[stock.StoreName]; !exists {
|
||||
nonIMEIStockMap[stock.StoreName] = make(map[string]int64)
|
||||
}
|
||||
key := stock.CommoditySerialNumber
|
||||
if key == "" {
|
||||
key = stock.ErpCommodityName
|
||||
}
|
||||
nonIMEIStockMap[stock.StoreName][key]++
|
||||
}
|
||||
}
|
||||
|
||||
// 商品编号必须为纯数字
|
||||
if i < len(sheetCols[0]) {
|
||||
if sheetCols[0][i] != "" {
|
||||
if _, err := strconv.Atoi(sheetCols[0][i]); err != nil {
|
||||
return errors.New("第" + strconv.Itoa(i+1) + "行商品编号必须为纯数字")
|
||||
}
|
||||
// 校验库存信息
|
||||
for row := 1; row < len(sheetCols[0]); row++ {
|
||||
if sheetCols[2][row] != "" { // 串码商品
|
||||
stock, exists := imeiStockMap[sheetCols[2][row]]
|
||||
if !exists {
|
||||
return fmt.Errorf("第 %d 行: 串码商品不存在或无库存", row+1)
|
||||
}
|
||||
|
||||
if !isExistingProductCode(sheetCols[0][i]) {
|
||||
return errors.New("第" + strconv.Itoa(i+1) + "行商品编号不存在")
|
||||
if stock.StoreName != sheetCols[4][row] {
|
||||
return fmt.Errorf("第 %d 行: 商品[%s]非所选门店库存,请检查", row+1, stock.ErpCommodityName)
|
||||
}
|
||||
}
|
||||
|
||||
// 所属门店不能为空
|
||||
if i < len(sheetCols[4]) {
|
||||
if sheetCols[4][i] == "" {
|
||||
return errors.New("第" + strconv.Itoa(i+1) + "行所属门店不能为空")
|
||||
}
|
||||
if !isExistingStore(sheetCols[4][i]) {
|
||||
return errors.New("第" + strconv.Itoa(i+1) + "行门店不存在")
|
||||
}
|
||||
}
|
||||
|
||||
// 数量必须为正整数
|
||||
if i < len(sheetCols[3]) {
|
||||
if quantity, err := strconv.Atoi(sheetCols[3][i]); err != nil || quantity < 1 {
|
||||
return errors.New("第" + strconv.Itoa(i+1) + "行数量必须是大于等于1的整数")
|
||||
}
|
||||
}
|
||||
|
||||
// 串码商品数量只能为1
|
||||
var nCount int
|
||||
if i < len(sheetCols[3]) {
|
||||
if i < len(sheetCols[3]) {
|
||||
nCount, _ = strconv.Atoi(sheetCols[3][i])
|
||||
}
|
||||
|
||||
// 串码类商品数量只能为1
|
||||
if sheetCols[2][i] != "" && nCount != 1 {
|
||||
return errors.New("第" + strconv.Itoa(i+1) + "行串码类商品数量只能为1")
|
||||
}
|
||||
}
|
||||
|
||||
// 判断商品是否赠送
|
||||
if i < len(sheetCols[6]) {
|
||||
if sheetCols[6][i] != "是" && sheetCols[6][i] != "" {
|
||||
return errors.New("第" + strconv.Itoa(i+1) + "行商品是否赠送填写有误")
|
||||
}
|
||||
}
|
||||
|
||||
// 查询商品是否有库存
|
||||
if sheetCols[2][i] != "" { // 串码商品
|
||||
var imeiStockCommodity ErpStockCommodity
|
||||
err := orm.Eloquent.Table("erp_stock_commodity").Where("imei = ? and state = ?",
|
||||
sheetCols[2][i], InStock).
|
||||
Find(&imeiStockCommodity).Error
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if imeiStockCommodity.ID == 0 {
|
||||
return errors.New("第" + strconv.Itoa(i+1) + "行商品不存在")
|
||||
}
|
||||
// 门店对比
|
||||
if imeiStockCommodity.StoreName != sheetCols[4][i] {
|
||||
return errors.New("第" + strconv.Itoa(i+1) + "行商品" +
|
||||
"[" + imeiStockCommodity.ErpCommodityName + "]非所选门店库存,请检查")
|
||||
}
|
||||
// 零售价对比
|
||||
var floatVal float64
|
||||
if i < len(sheetCols[5]) {
|
||||
if sheetCols[5][i] != "" {
|
||||
floatVal, err = strconv.ParseFloat(sheetCols[5][i], 64)
|
||||
if err != nil {
|
||||
return errors.New("第" + strconv.Itoa(i+1) + "行零售价有误")
|
||||
}
|
||||
strMin := strconv.FormatFloat(imeiStockCommodity.MinRetailPrice, 'f', 2, 64)
|
||||
if floatVal < imeiStockCommodity.MinRetailPrice {
|
||||
return errors.New("第" + strconv.Itoa(i+1) + "行零售价有误,不能低于最低零售价[" + strMin + "]")
|
||||
}
|
||||
if sheetCols[5][row] != "" {
|
||||
price, err := strconv.ParseFloat(sheetCols[5][row], 64)
|
||||
if err != nil || price < stock.MinRetailPrice {
|
||||
return fmt.Errorf("第 %d 行: 零售价有误,不能低于最低零售价[%.2f]", row+1, stock.MinRetailPrice)
|
||||
}
|
||||
}
|
||||
} else { // 非串码商品
|
||||
var count int64
|
||||
var err error
|
||||
if sheetCols[0][i] != "" { // 商品编号不为空
|
||||
err = orm.Eloquent.Table("erp_stock_commodity").
|
||||
Where("commodity_serial_number = ? and store_name = ? and state = ? and imei_type = ?",
|
||||
sheetCols[0][i], sheetCols[4][i], InStock, NoIMEICommodity).
|
||||
Count(&count).Error
|
||||
} else {
|
||||
err = orm.Eloquent.Table("erp_stock_commodity").
|
||||
Where("erp_commodity_name = ? and store_name = ? and state = ? and imei_type = ?",
|
||||
sheetCols[1][i], sheetCols[4][i], InStock, NoIMEICommodity).
|
||||
Count(&count).Error
|
||||
storeName := sheetCols[4][row]
|
||||
commodityKey := sheetCols[0][row]
|
||||
if commodityKey == "" {
|
||||
commodityKey = sheetCols[1][row]
|
||||
}
|
||||
if err != nil {
|
||||
return errors.New("第" + strconv.Itoa(i+1) + "行商品不存在")
|
||||
}
|
||||
|
||||
if count < int64(nCount) {
|
||||
// 获取商品名称
|
||||
return errors.New("第" + strconv.Itoa(i+1) + "行商品" + "[" + sheetCols[1][i] + "]库存不足")
|
||||
storeStock, storeExists := nonIMEIStockMap[storeName]
|
||||
if !storeExists || storeStock[commodityKey] < 1 {
|
||||
return fmt.Errorf("第 %d 行: 商品[%s]库存不足", row+1, sheetCols[1][row])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1500,6 +1740,37 @@ func checkOrderExcel(sheetCols [][]string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
//// 校验库存信息
|
||||
//func validateStock(sheetCols [][]string, row int) error {
|
||||
// if sheetCols[2][row] != "" { // 串码商品
|
||||
// var imeiStockCommodity ErpStockCommodity
|
||||
// err := orm.Eloquent.Table("erp_stock_commodity").Where("imei = ? AND state = ?",
|
||||
// sheetCols[2][row], InStock).Find(&imeiStockCommodity).Error
|
||||
// if err != nil || imeiStockCommodity.ID == 0 {
|
||||
// return errors.New("串码商品不存在或无库存")
|
||||
// }
|
||||
// if imeiStockCommodity.StoreName != sheetCols[4][row] {
|
||||
// return fmt.Errorf("商品[%s]非所选门店库存,请检查", imeiStockCommodity.ErpCommodityName)
|
||||
// }
|
||||
// if sheetCols[5][row] != "" {
|
||||
// if price, err := strconv.ParseFloat(sheetCols[5][row], 64); err != nil || price < imeiStockCommodity.MinRetailPrice {
|
||||
// return fmt.Errorf("零售价有误,不能低于最低零售价[%.2f]", imeiStockCommodity.MinRetailPrice)
|
||||
// }
|
||||
// }
|
||||
// } else { // 非串码商品
|
||||
// var count int64
|
||||
// err := orm.Eloquent.Table("erp_stock_commodity").
|
||||
// Where("(commodity_serial_number = ? OR erp_commodity_name = ?) AND store_name = ? AND state = ? AND imei_type = ?",
|
||||
// sheetCols[0][row], sheetCols[1][row], sheetCols[4][row], InStock, NoIMEICommodity).
|
||||
// Count(&count).Error
|
||||
// if err != nil || count < 1 {
|
||||
// return fmt.Errorf("商品[%s]库存不足", sheetCols[1][row])
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// return nil
|
||||
//}
|
||||
|
||||
// 将读取的excel数据转换成OrderExcel struct
|
||||
func transOrderData(colsMap []map[string]interface{}) ([]OrderExcel, error) {
|
||||
var stockInfos []OrderExcel
|
||||
|
@ -1593,7 +1864,7 @@ func ImportOrderData(colsMap []map[string]interface{}) ([]ErpOrderCommodity, err
|
|||
orderCommodity.RetailPrice = imeiStockCommodity.RetailPrice
|
||||
orderCommodity.SalePrice = floatVal
|
||||
orderCommodity.ReceivedAmount = floatVal
|
||||
orderCommodity.SaleDiscount = floatVal - imeiStockCommodity.RetailPrice
|
||||
orderCommodity.SaleDiscount = imeiStockCommodity.RetailPrice - floatVal
|
||||
orderCommodity.WholesalePrice = imeiStockCommodity.WholesalePrice
|
||||
orderCommodity.StaffCostPrice = imeiStockCommodity.StaffCostPrice
|
||||
orderCommodity.MemberDiscount = imeiStockCommodity.MemberDiscount
|
||||
|
@ -1671,7 +1942,7 @@ func ImportOrderData(colsMap []map[string]interface{}) ([]ErpOrderCommodity, err
|
|||
orderCommodity.RetailPrice = imeiStockCommodities[0].RetailPrice
|
||||
orderCommodity.SalePrice = floatVal
|
||||
orderCommodity.ReceivedAmount = floatVal
|
||||
orderCommodity.SaleDiscount = floatVal - imeiStockCommodities[0].RetailPrice
|
||||
orderCommodity.SaleDiscount = imeiStockCommodities[0].RetailPrice - floatVal
|
||||
orderCommodity.WholesalePrice = imeiStockCommodities[0].WholesalePrice
|
||||
orderCommodity.StaffCostPrice = imeiStockCommodities[0].StaffCostPrice
|
||||
orderCommodity.MemberDiscount = imeiStockCommodities[0].MemberDiscount
|
||||
|
|
Loading…
Reference in New Issue
Block a user