2023-11-08 03:51:33 +00:00
|
|
|
|
package models
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"errors"
|
|
|
|
|
"fmt"
|
|
|
|
|
"github.com/xuri/excelize/v2"
|
|
|
|
|
orm "go-admin/common/global"
|
|
|
|
|
"go-admin/logger"
|
2023-11-23 12:38:11 +00:00
|
|
|
|
"go-admin/tools/config"
|
2023-11-08 03:51:33 +00:00
|
|
|
|
"golang.org/x/sync/errgroup"
|
|
|
|
|
"gorm.io/gorm"
|
|
|
|
|
"strconv"
|
|
|
|
|
"strings"
|
|
|
|
|
"sync"
|
|
|
|
|
"time"
|
|
|
|
|
)
|
|
|
|
|
|
2023-11-23 12:38:11 +00:00
|
|
|
|
// ErpStock 库存列表
|
2023-11-08 03:51:33 +00:00
|
|
|
|
type ErpStock struct {
|
|
|
|
|
Model
|
|
|
|
|
|
2023-11-16 10:09:11 +00:00
|
|
|
|
StoreId uint32 `json:"store_id" gorm:"index"` // 门店编号
|
|
|
|
|
StoreName string `json:"store_name"` // 门店名称
|
|
|
|
|
ErpCommodityId uint32 `json:"erp_commodity_id" gorm:"index"` // 商品id
|
|
|
|
|
ErpCommodityName string `json:"erp_commodity_name"` // 商品名称
|
|
|
|
|
ErpCategoryId uint32 `json:"erp_category_id" gorm:"index"` // 分类id
|
|
|
|
|
ErpCategoryName string `json:"erp_category_name"` // 分类名称
|
|
|
|
|
CommoditySerialNumber string `json:"commodity_serial_number" gorm:"index"` // 商品编码/串码
|
|
|
|
|
IMEIType uint32 `json:"imei_type"` // 1-无串码 2-串码(系统生成) 3-串码(手动添加)
|
|
|
|
|
RetailPrice uint32 `json:"retail_price"` // 指导零售价
|
|
|
|
|
MinRetailPrice uint32 `json:"min_retail_price"` // 最低零售价
|
|
|
|
|
Count uint32 `json:"count"` // 数量
|
|
|
|
|
DispatchCount uint32 `json:"dispatch_count"` // 调拨中数量
|
|
|
|
|
Commodities []ErpStockCommodity `json:"commodities" gorm:"-"`
|
2023-11-08 03:51:33 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-11-16 10:09:11 +00:00
|
|
|
|
// ErpStockCommodity 库存详情
|
2023-11-08 03:51:33 +00:00
|
|
|
|
type ErpStockCommodity struct {
|
|
|
|
|
Model
|
|
|
|
|
|
2023-11-16 10:09:11 +00:00
|
|
|
|
ErpStockId uint32 `json:"erp_stock_id" gorm:"index"` // 库存id
|
|
|
|
|
StoreId uint32 `json:"store_id" gorm:"index"` // 门店id
|
|
|
|
|
StoreName string `json:"store_name"` // 门店名称
|
|
|
|
|
ErpCommodityId uint32 `json:"erp_commodity_id" gorm:"index"` // 商品id
|
|
|
|
|
ErpCommodityName string `json:"erp_commodity_name"` // 商品名称
|
|
|
|
|
CommoditySerialNumber string `json:"commodity_serial_number" gorm:"index"` // 商品编号
|
|
|
|
|
ErpCategoryId uint32 `json:"erp_category_id" gorm:"index"` // 分类id
|
|
|
|
|
ErpCategoryName string `json:"erp_category_name"` // 分类名称
|
|
|
|
|
IMEIType uint32 `json:"imei_type"` // 是否串码:1-无串码 2-串码(系统生成) 3-串码(手动添加)
|
|
|
|
|
IMEI string `json:"imei"` // 商品串码
|
|
|
|
|
ErpSupplierId uint32 `json:"erp_supplier_id" gorm:"index"` // 供应商id
|
|
|
|
|
ErpSupplierName string `json:"erp_supplier_name"` // 供应商名称
|
|
|
|
|
StockTime time.Time `json:"stock_time"` // 最近入库时间
|
|
|
|
|
RetailPrice uint32 `json:"retail_price"` // 指导零售价
|
|
|
|
|
MinRetailPrice uint32 `json:"min_retail_price"` // 最低零售价
|
|
|
|
|
StaffCostPrice uint32 `json:"staff_cost_price"` // 员工成本价加价
|
|
|
|
|
WholesalePrice uint32 `json:"wholesale_price"` // 指导采购价
|
|
|
|
|
State uint32 `json:"state"` // 状态:1-在库 2-已售 3-采购退货 4-调拨中
|
|
|
|
|
Count uint32 `json:"count"` // 数量
|
|
|
|
|
StorageType uint32 `json:"storage_type"` // 入库方式:1-系统入库 2-采购入库
|
|
|
|
|
FirstStockTime time.Time `json:"first_stock_time"` // 首次入库时间
|
|
|
|
|
StockSn string `json:"stock_sn"` // 库存订单编号
|
|
|
|
|
OriginalSn string `json:"original_sn" gorm:"index"` // 首次入库订单编号
|
|
|
|
|
StockStartTime time.Time `json:"stock_start_time" gorm:"-"` // 最近入库开始时间
|
|
|
|
|
StockEndTime time.Time `json:"stock_end_time" gorm:"-"` // 最近入库结束时间
|
|
|
|
|
Age uint32 `json:"age" gorm:"-"` // 最近库龄
|
|
|
|
|
AllAge uint32 `json:"all_age" gorm:"-"` // 总库龄
|
2023-11-24 09:09:24 +00:00
|
|
|
|
Remark string `json:"remark"` // 备注
|
2023-11-16 10:09:11 +00:00
|
|
|
|
//Commodity ErpCommodity `json:"commodity" gorm:"-"`
|
2023-11-08 03:51:33 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-11-16 10:09:11 +00:00
|
|
|
|
// ErpCommodity 商品表
|
2023-11-08 03:51:33 +00:00
|
|
|
|
type ErpCommodity struct {
|
|
|
|
|
Model
|
|
|
|
|
|
|
|
|
|
SerialNumber string `json:"serial_number"` // 商品编号
|
|
|
|
|
Number uint32 `json:"number"` // 商品数量
|
|
|
|
|
Name string `json:"name"` // 商品名称
|
|
|
|
|
ErpCategoryId uint32 `json:"erp_category_id" gorm:"index"` // 商品分类id
|
|
|
|
|
ErpCategoryName string `json:"erp_category_name"` // 商品分类名称
|
2023-11-24 09:09:24 +00:00
|
|
|
|
IsIMEI uint32 `json:"is_imei" gorm:"-"` // 是否串码:1-串码类 2-非串码
|
2023-11-09 10:26:19 +00:00
|
|
|
|
IMEIType uint32 `json:"imei_type"` // 1-无串码 2-串码(系统生成) 3-串码(手动添加)
|
2023-11-08 03:51:33 +00:00
|
|
|
|
IMEI string `json:"imei"` // 串码
|
|
|
|
|
ErpSupplierId uint32 `json:"erp_supplier_id" gorm:"index"` // 主供应商id
|
|
|
|
|
ErpSupplierName string `json:"erp_supplier_name"` // 主供应商名称
|
|
|
|
|
RetailPrice uint32 `json:"retail_price"` // 指导零售价
|
|
|
|
|
MinRetailPrice uint32 `json:"min_retail_price"` // 最低零售价
|
|
|
|
|
StaffCostPrice uint32 `json:"staff_cost_price"` // 员工成本价加价
|
|
|
|
|
WholesalePrice uint32 `json:"wholesale_price"` // 指导采购价
|
|
|
|
|
Brokerage1 float64 `json:"brokerage_1"` // 销售毛利提成
|
|
|
|
|
Brokerage2 float64 `json:"brokerage_2"` // 员工毛利提成
|
|
|
|
|
MemberDiscount float64 `json:"member_discount"` // 会员优惠
|
|
|
|
|
Origin string `json:"origin"` // 产地
|
|
|
|
|
Remark string `json:"remark" gorm:"type:varchar(512)"` // 备注
|
|
|
|
|
|
|
|
|
|
ErpCategory *ErpCategory `json:"erp_category" gorm:"-"`
|
|
|
|
|
}
|
|
|
|
|
|
2023-11-23 12:38:11 +00:00
|
|
|
|
// ErpCategory 商品分类
|
2023-11-08 03:51:33 +00:00
|
|
|
|
type ErpCategory struct {
|
|
|
|
|
Model
|
|
|
|
|
|
|
|
|
|
Name string `json:"name"` // 名称
|
|
|
|
|
Priority string `json:"priority"` // 分类
|
|
|
|
|
Number uint32 `json:"number"`
|
|
|
|
|
FullNum uint32 `json:"full_num"`
|
|
|
|
|
State uint32 `json:"state"` // 1-未使用 2-使用 3-隐藏
|
|
|
|
|
Level uint32 `json:"level"` // 分类层级
|
|
|
|
|
Pid uint32 `json:"pid" gorm:"index"`
|
|
|
|
|
Sort uint32 `json:"sort"`
|
|
|
|
|
SubCats []ErpCategory `json:"sub_cats" gorm:"-"` // 子列表
|
|
|
|
|
// erp_category
|
|
|
|
|
}
|
|
|
|
|
|
2023-11-23 12:38:11 +00:00
|
|
|
|
// ErpSupplier 供应商
|
2023-11-08 03:51:33 +00:00
|
|
|
|
type ErpSupplier struct {
|
|
|
|
|
Model
|
|
|
|
|
|
|
|
|
|
Number string `json:"number" gorm:"index"`
|
|
|
|
|
Name string `json:"name"`
|
|
|
|
|
Contact string `json:"contact"`
|
|
|
|
|
Tel string `json:"tel"`
|
|
|
|
|
Address string `json:"address"`
|
|
|
|
|
OpeningBank string `json:"opening_bank"`
|
|
|
|
|
BankAccount string `json:"bank_account"`
|
|
|
|
|
PaymentCycle uint32 `json:"payment_cycle"`
|
|
|
|
|
TaxNumber string `json:"tax_number"`
|
|
|
|
|
StoreIds string `json:"store_ids"`
|
|
|
|
|
Landline string `json:"landline"`
|
|
|
|
|
Email string `json:"email"`
|
|
|
|
|
CompanyWebsite string `json:"company_website"`
|
|
|
|
|
// erp_supplier
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type ErpInventoryStock struct {
|
|
|
|
|
Model
|
|
|
|
|
|
|
|
|
|
StoreId uint32 `json:"store_id" gorm:"index"`
|
|
|
|
|
StoreName string `json:"store_name"`
|
|
|
|
|
ErpCommodityId uint32 `json:"erp_commodity_id" gorm:"index"`
|
|
|
|
|
ErpCommodityName string `json:"erp_commodity_name"`
|
|
|
|
|
ErpCategoryId uint32 `json:"erp_category_id" gorm:"index"`
|
|
|
|
|
ErpCategoryName string `json:"erp_category_name"`
|
|
|
|
|
CommoditySerialNumber string `json:"commodity_serial_number" gorm:"index"`
|
2023-11-09 10:26:19 +00:00
|
|
|
|
IMEIType uint32 `json:"imei_type"` // 1-无串码 2-串码(系统生成) 3-串码(手动添加)
|
2023-11-08 03:51:33 +00:00
|
|
|
|
RetailPrice uint32 `json:"retail_price"`
|
|
|
|
|
MinRetailPrice uint32 `json:"min_retail_price"`
|
|
|
|
|
Count uint32 `json:"count"`
|
|
|
|
|
Sn string `json:"sn" gorm:"index"`
|
|
|
|
|
//ErpSupplierId uint32 `json:"erp_supplier_id" gorm:"index"`
|
|
|
|
|
//ErpSupplierName string `json:"erp_supplier_name"`
|
|
|
|
|
//IMEI string `json:"imei"`
|
|
|
|
|
//StockTime time.Time `json:"stock_time"`
|
|
|
|
|
//StaffCostPrice uint32 `json:"staff_cost_price"`
|
|
|
|
|
//WholesalePrice uint32 `json:"wholesale_price"`
|
|
|
|
|
// erp_inventory_stock
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type ErpInventoryStockCommodity struct {
|
|
|
|
|
Model
|
|
|
|
|
|
|
|
|
|
ErpInventoryStockId uint32 `json:"erp_inventory_stock_id" gorm:"index"`
|
|
|
|
|
ErpCommodityId uint32 `json:"erp_commodity_id" gorm:"index"`
|
|
|
|
|
ErpCommodityName string `json:"erp_commodity_name"`
|
|
|
|
|
CommoditySerialNumber string `json:"commodity_serial_number" gorm:"index"`
|
2023-11-09 10:26:19 +00:00
|
|
|
|
IMEIType uint32 `json:"imei_type"` // 1-无串码 2-串码(系统生成) 3-串码(手动添加)
|
2023-11-08 03:51:33 +00:00
|
|
|
|
IMEI string `json:"imei"`
|
|
|
|
|
ErpSupplierId uint32 `json:"erp_supplier_id" gorm:"index"`
|
|
|
|
|
ErpSupplierName string `json:"erp_supplier_name"`
|
|
|
|
|
StockTime time.Time `json:"stock_time"`
|
|
|
|
|
RetailPrice uint32 `json:"retail_price"`
|
|
|
|
|
MinRetailPrice uint32 `json:"min_retail_price"`
|
|
|
|
|
StaffCostPrice uint32 `json:"staff_cost_price"`
|
|
|
|
|
WholesalePrice uint32 `json:"wholesale_price"`
|
|
|
|
|
Count uint32 `json:"count"`
|
|
|
|
|
StorageType uint32 `json:"storage_type"`
|
|
|
|
|
Sn string `json:"sn" gorm:"index"`
|
|
|
|
|
//StoreId uint32 `json:"store_id" gorm:"index"`
|
|
|
|
|
//StoreName string `json:"store_name"`
|
|
|
|
|
//ErpCategoryId uint32 `json:"erp_category_id" gorm:"index"`
|
|
|
|
|
//ErpCategoryName string `json:"erp_category_name"`
|
|
|
|
|
// erp_inventory_stock_commodity
|
|
|
|
|
}
|
|
|
|
|
|
2023-11-23 12:38:11 +00:00
|
|
|
|
// IdInit 新增/编辑商品时获取分类和供应商信息
|
2023-11-08 03:51:33 +00:00
|
|
|
|
func (c *ErpCommodity) IdInit() {
|
|
|
|
|
if c.ErpCategoryId != 0 {
|
|
|
|
|
if c.ErpCategory == nil {
|
|
|
|
|
category, err := GetErpCategory(c.ErpCategoryId)
|
|
|
|
|
if err != nil {
|
|
|
|
|
//logger.Error("get erp category err:", err)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
c.ErpCategory = category
|
|
|
|
|
}
|
|
|
|
|
c.ErpCategoryName = c.ErpCategory.Name
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if c.ErpSupplierId != 0 {
|
|
|
|
|
supplier, err := GetErpSupplier(c.ErpSupplierId)
|
|
|
|
|
if err != nil {
|
|
|
|
|
//logger.Error("get erp category err:", err)
|
|
|
|
|
} else {
|
|
|
|
|
c.ErpSupplierName = supplier.Name
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-11-23 12:38:11 +00:00
|
|
|
|
// GetErpCategory 根据id查询分类信息
|
2023-11-08 03:51:33 +00:00
|
|
|
|
func GetErpCategory(id uint32) (*ErpCategory, error) {
|
|
|
|
|
category := new(ErpCategory)
|
|
|
|
|
err := orm.Eloquent.Table("erp_category").Where("id=?", id).Find(category).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
//logger.Error("category err:", err)
|
|
|
|
|
return category, err
|
|
|
|
|
}
|
|
|
|
|
return category, nil
|
|
|
|
|
}
|
|
|
|
|
|
2023-11-23 12:38:11 +00:00
|
|
|
|
// GetErpSupplier 根据id查询供应商
|
2023-11-08 03:51:33 +00:00
|
|
|
|
func GetErpSupplier(id uint32) (*ErpSupplier, error) {
|
|
|
|
|
supplier := new(ErpSupplier)
|
|
|
|
|
err := orm.Eloquent.Table("erp_supplier").Where("id=?", id).Find(supplier).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
//logger.Error("category err:", err)
|
|
|
|
|
return supplier, err
|
|
|
|
|
}
|
|
|
|
|
return supplier, err
|
|
|
|
|
}
|
|
|
|
|
|
2023-11-23 12:38:11 +00:00
|
|
|
|
// SetErpCategory 新增/编辑商品时设置分类信息
|
2023-11-08 03:51:33 +00:00
|
|
|
|
func (c *ErpCommodity) SetErpCategory() error {
|
|
|
|
|
if c.ErpCategoryId != 0 {
|
|
|
|
|
category, err := GetErpCategory(c.ErpCategoryId)
|
|
|
|
|
if err != nil {
|
|
|
|
|
//logger.Error("get erp category err:", err)
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
c.ErpCategory = category
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
return errors.New("erp category id null")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type ErpCommodityListReq struct {
|
2023-11-09 10:26:19 +00:00
|
|
|
|
SerialNumber string `json:"serial_number"` // 商品编号
|
|
|
|
|
ErpCommodityName string `json:"erp_commodity_name"` // 商品名称
|
|
|
|
|
ErpCategoryId uint32 `json:"erp_category_id"` // 商品分类id
|
|
|
|
|
IMEI string `json:"imei"` // 串码
|
|
|
|
|
ErpSupplierId uint32 `json:"erp_supplier_id"` // 供应商id
|
2023-11-28 09:33:38 +00:00
|
|
|
|
PageIndex int `json:"pageIndex"` // 页码
|
|
|
|
|
PageSize int `json:"pageSize"` // 每页展示数据条数
|
2023-11-09 10:26:19 +00:00
|
|
|
|
IsExport uint32 `json:"is_export"` // 1-导出
|
2023-11-08 03:51:33 +00:00
|
|
|
|
}
|
|
|
|
|
type ErpCommodityListResp struct {
|
|
|
|
|
List []ErpCommodity `json:"list"`
|
2023-11-28 09:33:38 +00:00
|
|
|
|
Total int `json:"count"` // 数据总条数
|
|
|
|
|
PageIndex int `json:"pageIndex"` // 页码
|
|
|
|
|
PageSize int `json:"pageSize"` // 每页展示条数
|
2023-11-09 10:26:19 +00:00
|
|
|
|
ExportUrl string `json:"export_url"` // 1-导出
|
2023-11-08 03:51:33 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (m *ErpCommodityListReq) List() (*ErpCommodityListResp, error) {
|
|
|
|
|
resp := &ErpCommodityListResp{
|
2023-11-28 09:33:38 +00:00
|
|
|
|
PageIndex: m.PageIndex,
|
|
|
|
|
PageSize: m.PageSize,
|
2023-11-08 03:51:33 +00:00
|
|
|
|
}
|
2023-11-28 09:33:38 +00:00
|
|
|
|
page := m.PageIndex - 1
|
2023-11-08 03:51:33 +00:00
|
|
|
|
if page < 0 {
|
|
|
|
|
page = 0
|
|
|
|
|
}
|
|
|
|
|
if m.PageSize == 0 {
|
|
|
|
|
m.PageSize = 10
|
|
|
|
|
}
|
|
|
|
|
qs := orm.Eloquent.Debug().Table("erp_commodity")
|
|
|
|
|
if m.SerialNumber != "" {
|
|
|
|
|
qs = qs.Where("serial_number=?", m.SerialNumber)
|
|
|
|
|
}
|
|
|
|
|
if m.ErpCommodityName != "" {
|
|
|
|
|
qs = qs.Where("name Like '%" + m.ErpCommodityName + "%'")
|
|
|
|
|
//qs = qs.Where("name LIKE ?", m.Name)
|
|
|
|
|
}
|
|
|
|
|
if m.IMEI != "" {
|
|
|
|
|
qs = qs.Where("imei=?", m.IMEI)
|
|
|
|
|
}
|
|
|
|
|
if m.ErpCategoryId != 0 {
|
|
|
|
|
qs = qs.Where("erp_category_id=?", m.ErpCategoryId)
|
|
|
|
|
}
|
|
|
|
|
if m.ErpSupplierId != 0 {
|
|
|
|
|
qs = qs.Where("erp_supplier_id=?", m.ErpSupplierId)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var count int64
|
|
|
|
|
err := qs.Count(&count).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
//logger.Error("count err:", err)
|
|
|
|
|
return resp, err
|
|
|
|
|
}
|
2023-11-28 09:33:38 +00:00
|
|
|
|
//resp.Total = int(count)/m.PageSize + 1
|
2023-11-08 03:51:33 +00:00
|
|
|
|
var commodities []ErpCommodity
|
|
|
|
|
|
|
|
|
|
if m.IsExport == 1 {
|
|
|
|
|
err = qs.Order("id DESC").Find(&commodities).Error
|
|
|
|
|
if err != nil && err != RecordNotFound {
|
|
|
|
|
//logger.Error("dailys err:", err)
|
|
|
|
|
return resp, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
listExport, err := ErpCommodityListExport(commodities)
|
|
|
|
|
if err != nil {
|
|
|
|
|
//logger.Error("list export err:", err)
|
|
|
|
|
}
|
|
|
|
|
resp.ExportUrl = listExport
|
|
|
|
|
} else {
|
|
|
|
|
err = qs.Order("id DESC").Offset(page * m.PageSize).Limit(m.PageSize).Find(&commodities).Error
|
|
|
|
|
if err != nil && err != RecordNotFound {
|
|
|
|
|
//logger.Error("erp commodity list err:", err)
|
|
|
|
|
return resp, err
|
|
|
|
|
}
|
|
|
|
|
resp.List = commodities
|
|
|
|
|
}
|
|
|
|
|
|
2023-11-24 09:09:24 +00:00
|
|
|
|
for i, v := range resp.List {
|
|
|
|
|
if v.IMEIType == 1 { //无串码
|
|
|
|
|
resp.List[i].IsIMEI = 2 // 非串码
|
|
|
|
|
} else {
|
|
|
|
|
resp.List[i].IsIMEI = 1 // 串码
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-11-28 09:33:38 +00:00
|
|
|
|
//跟之前保持一致
|
|
|
|
|
resp.Total = int(count)
|
|
|
|
|
resp.PageIndex = page + 1
|
|
|
|
|
resp.PageSize = m.PageSize
|
|
|
|
|
|
2023-11-08 03:51:33 +00:00
|
|
|
|
return resp, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type ErpCategoryListReq struct {
|
|
|
|
|
ErpCategoryId uint32 `json:"erp_category_id"`
|
|
|
|
|
Pid uint32 `json:"pid"`
|
|
|
|
|
Level uint32 `json:"level"` // 分类层级
|
|
|
|
|
State uint32 `json:"state"` // 1-未使用 2-使用 3-隐藏
|
|
|
|
|
PageNum int `json:"page_num"`
|
|
|
|
|
PageSize int `json:"page_size"`
|
|
|
|
|
IsExport uint32 `json:"is_export"` // 1-导出
|
|
|
|
|
}
|
|
|
|
|
type ErpCategoryListResp struct {
|
|
|
|
|
List []ErpCategory `json:"list"`
|
|
|
|
|
Total int `json:"total"`
|
|
|
|
|
PageNum int `json:"page_num"`
|
|
|
|
|
PageSize int `json:"page_size"`
|
|
|
|
|
ExportUrl string `json:"export_url"`
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (m *ErpCategoryListReq) List() (*ErpCategoryListResp, error) {
|
|
|
|
|
resp := &ErpCategoryListResp{
|
|
|
|
|
PageNum: m.PageNum,
|
|
|
|
|
PageSize: m.PageSize,
|
|
|
|
|
}
|
|
|
|
|
//page := m.PageNum - 1
|
|
|
|
|
//if page < 0 {
|
|
|
|
|
// page = 0
|
|
|
|
|
//}
|
|
|
|
|
//if m.PageSize == 0 {
|
|
|
|
|
// m.PageSize = 10
|
|
|
|
|
//}
|
|
|
|
|
//qs := orm.Eloquent.Table("erp_category")
|
|
|
|
|
//if m.Level != 0 {
|
|
|
|
|
// qs = qs.Where("level=?", m.Level)
|
|
|
|
|
//}
|
|
|
|
|
////if m.ErpCategoryId != 0 {
|
|
|
|
|
//// qs = qs.IDEq(m.ErpCategoryId)
|
|
|
|
|
////}
|
|
|
|
|
//if m.Pid != 0 {
|
|
|
|
|
// qs = qs.Where("pid", m.Pid)
|
|
|
|
|
//}
|
|
|
|
|
//var count int64
|
|
|
|
|
//err := qs.Count(&count).Error
|
|
|
|
|
//if err != nil {
|
|
|
|
|
// logger.Error("count err:", err)
|
|
|
|
|
// return resp, err
|
|
|
|
|
//}
|
|
|
|
|
//resp.Total = int(count)/m.PageSize + 1
|
|
|
|
|
//var categories []ErpCategory
|
|
|
|
|
//err = qs.Order("id DESC").Offset(page * m.PageSize).Limit(m.PageSize).Find(&categories).Error
|
|
|
|
|
//if err != nil && err != RecordNotFound {
|
|
|
|
|
// logger.Error("erp commodity list err:", err)
|
|
|
|
|
// return resp, err
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
var categories []ErpCategory
|
|
|
|
|
qs := orm.Eloquent.Table("erp_category").Where("level=?", 1)
|
|
|
|
|
if m.Pid != 0 {
|
|
|
|
|
qs = qs.Where("id=?", m.Pid)
|
|
|
|
|
}
|
|
|
|
|
if m.State != 0 {
|
|
|
|
|
qs.Where("state=?", m.State)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
err := qs.Order("sort DESC").Find(&categories).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
//logger.Error("erp commodity list err:", err)
|
|
|
|
|
return resp, err
|
|
|
|
|
}
|
|
|
|
|
pids := make([]uint32, 0)
|
|
|
|
|
for i, _ := range categories {
|
|
|
|
|
pids = append(pids, categories[i].ID)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var subCat []ErpCategory
|
|
|
|
|
subQs := orm.Eloquent.Table("erp_category").Where("pid in (?)", pids)
|
|
|
|
|
if m.State != 0 {
|
|
|
|
|
subQs.Where("state=?", m.State)
|
|
|
|
|
}
|
|
|
|
|
err = subQs.Order("sort DESC").Find(&subCat).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Errorf("pCat err:%#v", err)
|
|
|
|
|
return resp, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pCatMap := make(map[uint32][]ErpCategory, 0)
|
|
|
|
|
for i, _ := range subCat {
|
|
|
|
|
pCatMap[subCat[i].Pid] = append(pCatMap[subCat[i].Pid], subCat[i])
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for i, _ := range categories {
|
|
|
|
|
v, ok := pCatMap[categories[i].ID]
|
|
|
|
|
|
|
|
|
|
if ok {
|
|
|
|
|
categories[i].SubCats = v
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if m.IsExport == 1 {
|
|
|
|
|
listExport, err := ErpCategoryListExport(categories)
|
|
|
|
|
if err != nil {
|
|
|
|
|
//logger.Error("list export err:", err)
|
|
|
|
|
}
|
|
|
|
|
resp.ExportUrl = listExport
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
resp.List = categories
|
|
|
|
|
return resp, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type CommodityNumberCount struct {
|
|
|
|
|
NumberMap map[uint32]uint32 `json:"number_map"`
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (m *CommodityNumberCount) GetErpCommodityNumberByCategoryId(categoryId uint32) (uint32, error) {
|
|
|
|
|
v, ok := m.NumberMap[categoryId]
|
|
|
|
|
if ok {
|
|
|
|
|
m.NumberMap[categoryId] = v + 1
|
|
|
|
|
return v + 1, nil
|
|
|
|
|
}
|
|
|
|
|
var commodity ErpCommodity
|
|
|
|
|
err := orm.Eloquent.Raw(fmt.Sprintf(
|
|
|
|
|
"SELECT number FROM erp_commodity WHERE erp_category_id=%d ORDER BY id DESC LIMIT 0,1;", categoryId)).Scan(&commodity).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
//logger.Error("all categories map err:", err)
|
|
|
|
|
return 0, err
|
|
|
|
|
}
|
|
|
|
|
m.NumberMap[categoryId] = commodity.Number + 1
|
|
|
|
|
return commodity.Number + 1, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var EsStockLock sync.Mutex
|
|
|
|
|
|
|
|
|
|
type StockImporter struct {
|
|
|
|
|
CensusMap map[uint32]map[uint32]uint32
|
|
|
|
|
CommodityMap map[uint32]*ErpCommodity
|
|
|
|
|
StoreMap map[uint32]string
|
|
|
|
|
Inventories []*ErpInventoryStock
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type ErpStockFileExcel struct {
|
|
|
|
|
StockTimeString string `json:"stock_time_string"`
|
|
|
|
|
IsIMEI string `json:"is_imei"`
|
|
|
|
|
|
|
|
|
|
RetailPriceString string `json:"retail_price_string"`
|
|
|
|
|
MinRetailPriceString string `json:"min_retail_price_string"`
|
2023-11-23 12:38:11 +00:00
|
|
|
|
StaffCostPriceString string `json:"staff_cost_price_string"` // 员工成本价加价
|
|
|
|
|
WholesalePriceString string `json:"wholesale_price_string"` // 指导采购价
|
|
|
|
|
CountString string `json:"count_string"` // 数量
|
2023-11-08 03:51:33 +00:00
|
|
|
|
|
|
|
|
|
//StoreName string `json:"store_name"`
|
|
|
|
|
//ErpCommodityName string `json:"erp_commodity_name"`
|
|
|
|
|
//ErpCategoryName string `json:"erp_category_name"`
|
|
|
|
|
//SerialNumber string `json:"serial_number"`
|
|
|
|
|
//IMEIType uint32 `json:"imei_type"` // 1-无串码 2-串码
|
|
|
|
|
//IMEI string `json:"imei"`
|
|
|
|
|
//ErpSupplierName string `json:"erp_supplier_name"`
|
|
|
|
|
|
|
|
|
|
ErpStockCommodity
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (e *ErpStockFileExcel) Processing() {
|
|
|
|
|
e.Count = IntStringToUin32(e.CountString)
|
|
|
|
|
if e.IsIMEI == "是" {
|
|
|
|
|
e.IMEIType = 2
|
|
|
|
|
e.Count = 1
|
|
|
|
|
} else if e.IsIMEI == "否" {
|
|
|
|
|
e.IMEIType = 1
|
|
|
|
|
}
|
|
|
|
|
//parseTime, err := time.Parse(DateTimeFormat, e.StockTimeString)
|
|
|
|
|
//fmt.Println("StockTimeString:", e.StockTimeString)
|
|
|
|
|
//parseTime, err := time.Parse("01-02-06", e.StockTimeString)
|
|
|
|
|
format := "2006/01/02"
|
|
|
|
|
parseTime, err := time.Parse(format, e.StockTimeString)
|
|
|
|
|
if err != nil {
|
|
|
|
|
//logger.Error("parse err:", err)
|
|
|
|
|
parseTime = time.Now()
|
|
|
|
|
}
|
|
|
|
|
e.StockTime = parseTime
|
|
|
|
|
|
|
|
|
|
e.RetailPrice = PercentFloatStringToUin32(e.RetailPriceString)
|
|
|
|
|
e.MinRetailPrice = PercentFloatStringToUin32(e.MinRetailPriceString)
|
|
|
|
|
e.StaffCostPrice = PercentFloatStringToUin32(e.StaffCostPriceString)
|
|
|
|
|
e.WholesalePrice = PercentFloatStringToUin32(e.WholesalePriceString)
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
2023-11-24 09:09:24 +00:00
|
|
|
|
// ImportStockData 库存导入
|
|
|
|
|
// 更新库存表和商品表
|
|
|
|
|
// 库存表:插入对应的库存数据
|
|
|
|
|
// 库存商品表:插入对应库存商品的数据;供应商只需判断是否在供应商列表即可 todo 库存商品表未插入库存id
|
|
|
|
|
func (m *StockImporter) ImportStockData(colsMap []map[string]interface{}) error {
|
2023-11-23 12:38:11 +00:00
|
|
|
|
list, err := transStockData(colsMap)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var erpStockCommodity []ErpStockCommodity
|
2023-11-08 03:51:33 +00:00
|
|
|
|
storeNameMap := make(map[string]uint32, 0)
|
|
|
|
|
erpCommodityMap := make(map[string]*ErpCommodity, 0)
|
|
|
|
|
erpSupplierNameMap := make(map[string]uint32, 0)
|
|
|
|
|
|
|
|
|
|
storeNames := make([]string, 0, len(list))
|
|
|
|
|
erpCommodityNames := make([]string, 0, len(list))
|
|
|
|
|
erpSupplierNames := make([]string, 0, len(list))
|
|
|
|
|
|
|
|
|
|
for i, _ := range list {
|
|
|
|
|
_, ok1 := storeNameMap[list[i].StoreName]
|
|
|
|
|
if !ok1 {
|
|
|
|
|
storeNames = append(storeNames, list[i].StoreName)
|
|
|
|
|
}
|
2023-11-23 12:38:11 +00:00
|
|
|
|
_, ok2 := erpCommodityMap[list[i].Name]
|
2023-11-08 03:51:33 +00:00
|
|
|
|
if !ok2 {
|
2023-11-23 12:38:11 +00:00
|
|
|
|
erpCommodityNames = append(erpCommodityNames, list[i].Name)
|
2023-11-08 03:51:33 +00:00
|
|
|
|
}
|
2023-11-23 12:38:11 +00:00
|
|
|
|
_, ok3 := erpSupplierNameMap[list[i].SupplierName]
|
2023-11-08 03:51:33 +00:00
|
|
|
|
if !ok3 {
|
2023-11-23 12:38:11 +00:00
|
|
|
|
erpSupplierNames = append(erpSupplierNames, list[i].SupplierName)
|
2023-11-08 03:51:33 +00:00
|
|
|
|
}
|
|
|
|
|
storeNameMap[list[i].StoreName] = uint32(0)
|
2023-11-23 12:38:11 +00:00
|
|
|
|
erpCommodityMap[list[i].Name] = nil
|
|
|
|
|
erpSupplierNameMap[list[i].SupplierName] = uint32(0)
|
2023-11-08 03:51:33 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var stores []Store
|
2023-11-23 12:38:11 +00:00
|
|
|
|
err = orm.Eloquent.Table("store").Where("name IN (?)", storeNames).Find(&stores).Error
|
2023-11-08 03:51:33 +00:00
|
|
|
|
if err != nil {
|
|
|
|
|
//logger.Error("stores err:", err)
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
var erpCommodities []ErpCommodity
|
|
|
|
|
err = orm.Eloquent.Table("erp_commodity").Where("name IN (?)", erpCommodityNames).Find(&erpCommodities).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
//logger.Error("stores err:", err)
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
var erpSuppliers []ErpSupplier
|
|
|
|
|
err = orm.Eloquent.Table("erp_supplier").Debug().Where("name IN (?)", erpSupplierNames).Find(&erpSuppliers).Error
|
2023-11-23 12:38:11 +00:00
|
|
|
|
if err != nil && !errors.Is(err, RecordNotFound) {
|
2023-11-08 03:51:33 +00:00
|
|
|
|
//logger.Error("stores err:", err)
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for i, _ := range stores {
|
|
|
|
|
storeNameMap[stores[i].Name] = stores[i].ID
|
|
|
|
|
m.StoreMap[stores[i].ID] = stores[i].Name
|
|
|
|
|
}
|
|
|
|
|
for i, _ := range erpCommodities {
|
|
|
|
|
erpCommodityMap[erpCommodities[i].Name] = &erpCommodities[i]
|
|
|
|
|
m.CommodityMap[erpCommodities[i].ID] = &erpCommodities[i]
|
|
|
|
|
}
|
|
|
|
|
for i, _ := range erpSuppliers {
|
|
|
|
|
erpSupplierNameMap[erpSuppliers[i].Name] = erpSuppliers[i].ID
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nowTime := time.Now()
|
|
|
|
|
for i, _ := range list {
|
|
|
|
|
v1, ok1 := storeNameMap[list[i].StoreName]
|
|
|
|
|
if !ok1 {
|
|
|
|
|
logger.Error("store name err")
|
|
|
|
|
return errors.New("store name err")
|
|
|
|
|
}
|
2023-11-23 12:38:11 +00:00
|
|
|
|
v2, ok2 := erpCommodityMap[list[i].Name]
|
|
|
|
|
if !ok2 || v2 == nil {
|
2023-11-08 03:51:33 +00:00
|
|
|
|
logger.Error("erp commodity name err")
|
|
|
|
|
return errors.New("erp commodity name err")
|
|
|
|
|
}
|
2023-11-23 12:38:11 +00:00
|
|
|
|
v3, ok3 := erpSupplierNameMap[list[i].SupplierName]
|
2023-11-08 03:51:33 +00:00
|
|
|
|
if !ok3 {
|
|
|
|
|
logger.Error("erp supplier name err")
|
|
|
|
|
return errors.New("erp supplier name err")
|
|
|
|
|
}
|
|
|
|
|
|
2023-11-23 12:38:11 +00:00
|
|
|
|
// 注意:表格导入是员工成本价,数据库存储是员工成本价加价=员工成本价-指导采购价
|
|
|
|
|
nStaffCostPrice, err := strconv.ParseUint(list[i].StaffCostPrice, 10, 32)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return fmt.Errorf("员工成本价转换有误:[%v]", err)
|
|
|
|
|
}
|
|
|
|
|
nWholesalePrice, err := strconv.ParseUint(list[i].WholesalePrice, 10, 32) // 指导采购价
|
|
|
|
|
if err != nil {
|
|
|
|
|
return fmt.Errorf("指导采购价转换有误:[%v]", err)
|
|
|
|
|
}
|
|
|
|
|
if nStaffCostPrice < nWholesalePrice {
|
|
|
|
|
return fmt.Errorf("导入价格有误,员工成本价低于指导采购价")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nCount, err := strconv.ParseUint(list[i].Count, 10, 32)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return fmt.Errorf("数量转换有误:[%v]", err)
|
|
|
|
|
}
|
|
|
|
|
|
2023-11-24 09:09:24 +00:00
|
|
|
|
for j := 0; j < int(nCount); j++ { // 商品库存表都是单笔数据,如果非串码商品有多个,需要插入多条数据
|
|
|
|
|
stockCommodity := ErpStockCommodity{
|
|
|
|
|
StoreId: v1,
|
|
|
|
|
StoreName: list[i].StoreName,
|
|
|
|
|
ErpCommodityId: v2.ID,
|
|
|
|
|
ErpCommodityName: v2.Name,
|
|
|
|
|
CommoditySerialNumber: list[i].SerialNum,
|
|
|
|
|
ErpCategoryId: v2.ErpCategoryId,
|
|
|
|
|
ErpCategoryName: v2.ErpCategoryName,
|
|
|
|
|
ErpSupplierId: v3,
|
|
|
|
|
ErpSupplierName: list[i].SupplierName,
|
|
|
|
|
StaffCostPrice: uint32(nStaffCostPrice - nWholesalePrice),
|
|
|
|
|
WholesalePrice: uint32(nWholesalePrice),
|
|
|
|
|
State: 1,
|
|
|
|
|
StorageType: 1,
|
|
|
|
|
FirstStockTime: nowTime,
|
|
|
|
|
StockTime: nowTime,
|
|
|
|
|
Count: 1,
|
|
|
|
|
IMEIType: v2.IMEIType,
|
|
|
|
|
IMEI: v2.IMEI,
|
|
|
|
|
Remark: "",
|
|
|
|
|
}
|
|
|
|
|
if list[i].SysGenerate != "" { //导入串码不为空,则默认为3手动添加
|
|
|
|
|
stockCommodity.IMEIType = 3
|
|
|
|
|
stockCommodity.IMEI = list[i].SysGenerate
|
|
|
|
|
}
|
|
|
|
|
erpStockCommodity = append(erpStockCommodity, stockCommodity)
|
2023-11-08 03:51:33 +00:00
|
|
|
|
|
2023-11-24 09:09:24 +00:00
|
|
|
|
_, ok4 := m.CensusMap[stockCommodity.StoreId]
|
|
|
|
|
if ok4 {
|
|
|
|
|
m.CensusMap[stockCommodity.StoreId][stockCommodity.ErpCommodityId] += stockCommodity.Count
|
|
|
|
|
} else {
|
|
|
|
|
m.CensusMap[stockCommodity.StoreId] = map[uint32]uint32{stockCommodity.ErpCommodityId: stockCommodity.Count}
|
|
|
|
|
}
|
2023-11-23 12:38:11 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if err = m.processErpStocks(erpStockCommodity); err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (m *StockImporter) processErpStocks(erpStocks []ErpStockCommodity) error {
|
|
|
|
|
begin := orm.Eloquent.Begin()
|
|
|
|
|
total := len(erpStocks)
|
|
|
|
|
size := 200
|
|
|
|
|
page := (total + size - 1) / size
|
|
|
|
|
|
|
|
|
|
errGroup := errgroup.Group{}
|
|
|
|
|
|
|
|
|
|
for i := 0; i < page; i++ {
|
|
|
|
|
start := i * size
|
|
|
|
|
end := (i + 1) * size
|
|
|
|
|
if end > total {
|
|
|
|
|
end = total
|
2023-11-08 03:51:33 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-11-23 12:38:11 +00:00
|
|
|
|
stockList := erpStocks[start:end]
|
|
|
|
|
errGroup.Go(func() error {
|
|
|
|
|
return createStockList(begin, stockList)
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
err := m.ErpStockCountUpdate(begin)
|
|
|
|
|
if err != nil {
|
|
|
|
|
begin.Rollback()
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
err = errGroup.Wait()
|
|
|
|
|
if err != nil {
|
|
|
|
|
begin.Rollback()
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
err = begin.Commit().Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
begin.Rollback()
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func createStockList(begin *gorm.DB, stockList []ErpStockCommodity) error {
|
|
|
|
|
err := begin.Create(&stockList).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
begin.Rollback()
|
|
|
|
|
return err
|
2023-11-08 03:51:33 +00:00
|
|
|
|
}
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (m *StockImporter) ErpStockCountUpdate(gdb *gorm.DB) error {
|
|
|
|
|
for k1, v1 := range m.CensusMap {
|
|
|
|
|
for k2, v2 := range v1 {
|
|
|
|
|
exist, err := QueryRecordExist(fmt.Sprintf("SELECT * FROM erp_stock WHERE store_id=%d AND erp_commodity_id=%d", k1, k2))
|
|
|
|
|
if err != nil {
|
|
|
|
|
//logger.Error("exist err:", err)
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
v, ok := m.CommodityMap[k2]
|
|
|
|
|
fmt.Println("CommodityMap", m.CommodityMap)
|
|
|
|
|
fmt.Println("ok", ok)
|
|
|
|
|
fmt.Println("v", v)
|
|
|
|
|
if exist {
|
|
|
|
|
err = gdb.Exec(fmt.Sprintf(
|
|
|
|
|
"UPDATE erp_stock SET count=count+%d WHERE store_id=%d AND erp_commodity_id=%d;", v2, k1, k2)).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
//logger.Error("update stock err:", err)
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
if ok && v != nil {
|
|
|
|
|
stock := &ErpStock{
|
|
|
|
|
StoreId: k1,
|
|
|
|
|
StoreName: m.StoreMap[k1],
|
|
|
|
|
ErpCommodityId: v.ID,
|
|
|
|
|
ErpCommodityName: v.Name,
|
|
|
|
|
ErpCategoryId: v.ErpCategoryId,
|
|
|
|
|
ErpCategoryName: v.ErpCategoryName,
|
|
|
|
|
CommoditySerialNumber: v.SerialNumber,
|
|
|
|
|
IMEIType: v.IMEIType,
|
|
|
|
|
RetailPrice: v.RetailPrice,
|
|
|
|
|
MinRetailPrice: v.MinRetailPrice,
|
|
|
|
|
Count: v2,
|
|
|
|
|
DispatchCount: 0,
|
|
|
|
|
}
|
|
|
|
|
err = gdb.Create(stock).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
//logger.Error("create stock err:", err)
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
if ok && v != nil {
|
|
|
|
|
inventoryStock := &ErpInventoryStock{
|
|
|
|
|
StoreId: k1,
|
|
|
|
|
StoreName: m.StoreMap[k1],
|
|
|
|
|
ErpCommodityId: v.ID,
|
|
|
|
|
ErpCommodityName: v.Name,
|
|
|
|
|
ErpCategoryId: v.ErpCategoryId,
|
|
|
|
|
ErpCategoryName: v.ErpCategoryName,
|
|
|
|
|
CommoditySerialNumber: v.SerialNumber,
|
|
|
|
|
IMEIType: v.IMEIType,
|
|
|
|
|
RetailPrice: v.RetailPrice,
|
|
|
|
|
MinRetailPrice: v.MinRetailPrice,
|
|
|
|
|
Count: v2,
|
|
|
|
|
}
|
|
|
|
|
fmt.Println("inventoryStock", inventoryStock.Count)
|
|
|
|
|
m.Inventories = append(m.Inventories, inventoryStock)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
2023-11-23 12:38:11 +00:00
|
|
|
|
func (m *StockImporter) ErpInventoryStockCreate(gdb *gorm.DB, list []ErpStockCommodity) error {
|
2023-11-08 03:51:33 +00:00
|
|
|
|
defer func() {
|
|
|
|
|
if err := recover(); err != nil {
|
|
|
|
|
//logger.Error("err:", err)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
}()
|
|
|
|
|
|
|
|
|
|
inventoryStockIdMap := make(map[string]uint32, 0)
|
|
|
|
|
for _, inventory := range m.Inventories {
|
2023-11-17 10:07:01 +00:00
|
|
|
|
//err := gdb.Create(inventorymanage).Error
|
2023-11-08 03:51:33 +00:00
|
|
|
|
err := orm.Eloquent.Create(inventory).Error
|
|
|
|
|
if err != nil {
|
2023-11-17 10:07:01 +00:00
|
|
|
|
//logger.Error("create erp inventorymanage stock err:", err)
|
2023-11-08 03:51:33 +00:00
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
inventoryStockIdMap[fmt.Sprintf("%d_%d", inventory.StoreId, inventory.ErpCommodityId)] = inventory.ID
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
begin := orm.Eloquent.Begin()
|
|
|
|
|
total := len(list)
|
|
|
|
|
size := 500
|
|
|
|
|
page := total / size
|
|
|
|
|
if total%size != 0 {
|
|
|
|
|
page += 1
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
errGroup := errgroup.Group{}
|
|
|
|
|
for i := 0; i < page; i++ {
|
|
|
|
|
if i == page-1 {
|
|
|
|
|
stockList := ErpStockCommodityToInventory(inventoryStockIdMap, list[i*size:])
|
|
|
|
|
err := begin.Create(&stockList).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
begin.Rollback()
|
|
|
|
|
//logger.Error("create commodity err:", err)
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
errGroup.Go(func() error {
|
|
|
|
|
//stockList := list[i*size : (i+1)*size]
|
|
|
|
|
stockList := ErpStockCommodityToInventory(inventoryStockIdMap, list[i*size:(i+1)*size])
|
|
|
|
|
err := begin.Create(&stockList).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
begin.Rollback()
|
|
|
|
|
//logger.Error("create commodity err:", err)
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
return nil
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
err := errGroup.Wait()
|
|
|
|
|
if err != nil {
|
|
|
|
|
//logger.Error("wait err:", err)
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
err = begin.Commit().Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
//logger.Error("commit err:", err)
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
2023-11-23 12:38:11 +00:00
|
|
|
|
func ErpStockCommodityToInventory(inventoryStockIdMap map[string]uint32, list []ErpStockCommodity) []*ErpInventoryStockCommodity {
|
2023-11-08 03:51:33 +00:00
|
|
|
|
inventoryList := make([]*ErpInventoryStockCommodity, 0, len(list))
|
|
|
|
|
for i, _ := range list {
|
|
|
|
|
v, ok := inventoryStockIdMap[fmt.Sprintf("%d_%d", list[i].StoreId, list[i].ErpCommodityId)]
|
|
|
|
|
if ok {
|
|
|
|
|
inventoryCommodity := &ErpInventoryStockCommodity{
|
|
|
|
|
ErpInventoryStockId: v,
|
|
|
|
|
ErpCommodityId: list[i].ErpCommodityId,
|
|
|
|
|
ErpCommodityName: list[i].ErpCommodityName,
|
|
|
|
|
CommoditySerialNumber: list[i].CommoditySerialNumber,
|
|
|
|
|
IMEIType: list[i].IMEIType,
|
|
|
|
|
IMEI: list[i].IMEI,
|
|
|
|
|
ErpSupplierId: list[i].ErpSupplierId,
|
|
|
|
|
ErpSupplierName: list[i].ErpSupplierName,
|
|
|
|
|
StockTime: list[i].StockTime,
|
|
|
|
|
RetailPrice: list[i].RetailPrice,
|
|
|
|
|
MinRetailPrice: list[i].MinRetailPrice,
|
|
|
|
|
StaffCostPrice: list[i].StaffCostPrice,
|
|
|
|
|
WholesalePrice: list[i].WholesalePrice,
|
|
|
|
|
Count: list[i].Count,
|
|
|
|
|
}
|
|
|
|
|
//err := gdb.Create(inventoryCommodity).Error
|
|
|
|
|
inventoryList = append(inventoryList, inventoryCommodity)
|
|
|
|
|
//err := orm.Eloquent.Create(inventoryCommodity).Error
|
|
|
|
|
//if err != nil {
|
2023-11-17 10:07:01 +00:00
|
|
|
|
// logger.Error("create erp inventorymanage stock commodity err:", err)
|
2023-11-08 03:51:33 +00:00
|
|
|
|
// return inventoryList
|
|
|
|
|
//}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return inventoryList
|
|
|
|
|
}
|
|
|
|
|
|
2023-11-23 12:38:11 +00:00
|
|
|
|
// ErpCommodityListExport 导出商品列表
|
2023-11-08 03:51:33 +00:00
|
|
|
|
func ErpCommodityListExport(list []ErpCommodity) (string, error) {
|
|
|
|
|
file := excelize.NewFile()
|
|
|
|
|
streamWriter, err := file.NewStreamWriter("Sheet1")
|
|
|
|
|
if err != nil {
|
|
|
|
|
fmt.Println(err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
url := "http://39.108.188.218:8000/img/export/"
|
|
|
|
|
fileName := time.Now().Format(TimeFormat) + "商品" + ".xlsx"
|
|
|
|
|
|
|
|
|
|
//title := []interface{}{"供应商编号", "供应商名称", "联系人", "手机号", "地址", "开户银行", "银行账号", "付款周期/天"}
|
|
|
|
|
title := []interface{}{"商品编号", "商品名称", "商品分类", "是否串码", "主供应商", "零售价", "最低零售价", "员工成本价",
|
|
|
|
|
"采购价", "提成等级1", "提成等级2", "产地", "备注", "会员折扣(零售价的百分比)"}
|
|
|
|
|
cell, _ := excelize.CoordinatesToCellName(1, 1)
|
|
|
|
|
if err = streamWriter.SetRow(cell, title); err != nil {
|
|
|
|
|
fmt.Println(err)
|
|
|
|
|
}
|
|
|
|
|
var row []interface{}
|
|
|
|
|
for rowId := 0; rowId < len(list); rowId++ {
|
|
|
|
|
isIMEI := "否"
|
|
|
|
|
if list[rowId].IMEIType == 2 {
|
|
|
|
|
isIMEI = "是"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
row = []interface{}{list[rowId].SerialNumber, list[rowId].Name, list[rowId].ErpCategoryName,
|
|
|
|
|
isIMEI, list[rowId].ErpSupplierName, list[rowId].RetailPrice,
|
|
|
|
|
list[rowId].MinRetailPrice, list[rowId].StaffCostPrice, list[rowId].WholesalePrice, list[rowId].Brokerage1,
|
|
|
|
|
list[rowId].Brokerage2, list[rowId].Origin, list[rowId].Remark, list[rowId].MemberDiscount}
|
|
|
|
|
cell, _ := excelize.CoordinatesToCellName(1, rowId+2)
|
|
|
|
|
if err := streamWriter.SetRow(cell, row); err != nil {
|
|
|
|
|
fmt.Println(err)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if err := streamWriter.Flush(); err != nil {
|
|
|
|
|
fmt.Println(err)
|
|
|
|
|
}
|
|
|
|
|
if err := file.SaveAs("/www/server/images/export/" + fileName); err != nil {
|
|
|
|
|
//if err := file.SaveAs("./" + fileName); err != nil {
|
|
|
|
|
fmt.Println(err)
|
|
|
|
|
}
|
|
|
|
|
return url + fileName, nil
|
|
|
|
|
}
|
|
|
|
|
|
2023-11-23 12:38:11 +00:00
|
|
|
|
// InventoryDetailListExport 导出库存商品列表
|
|
|
|
|
func InventoryDetailListExport(list []ErpStockCommodity) (string, error) {
|
|
|
|
|
file := excelize.NewFile()
|
|
|
|
|
streamWriter, err := file.NewStreamWriter("Sheet1")
|
|
|
|
|
if err != nil {
|
|
|
|
|
fmt.Println(err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
url := config.ExportConfig.Url
|
|
|
|
|
fileName := time.Now().Format(TimeFormat) + "商品" + ".xlsx"
|
|
|
|
|
fmt.Println("url fileName:", url+fileName)
|
|
|
|
|
|
|
|
|
|
title := []interface{}{"商品编号", "商品名称", "商品分类", "是否串码", "商品串码", "所属门店", "供应商", "首次入库时间", "首次入库方式",
|
|
|
|
|
"首次入库订单编号", "最近入库时间", "入库采购价", "入库员工成本价", "最近库龄", "总库龄", "当前状态", "备注"}
|
|
|
|
|
cell, _ := excelize.CoordinatesToCellName(1, 1)
|
|
|
|
|
if err = streamWriter.SetRow(cell, title); err != nil {
|
|
|
|
|
fmt.Println(err)
|
|
|
|
|
}
|
|
|
|
|
var row []interface{}
|
|
|
|
|
for rowId := 0; rowId < len(list); rowId++ {
|
|
|
|
|
isIMEIType := "是"
|
|
|
|
|
if list[rowId].IMEIType == 1 {
|
|
|
|
|
isIMEIType = "否"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
storageType := "系统入库"
|
|
|
|
|
if list[rowId].StorageType == 2 {
|
|
|
|
|
storageType = "采购入库"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
state := "库存中"
|
|
|
|
|
switch list[rowId].State {
|
|
|
|
|
case 1:
|
|
|
|
|
state = "库存中"
|
|
|
|
|
case 2:
|
|
|
|
|
state = "已售"
|
|
|
|
|
case 3:
|
|
|
|
|
state = "采购退货"
|
|
|
|
|
case 4:
|
|
|
|
|
state = "调拨中"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
row = []interface{}{
|
|
|
|
|
list[rowId].CommoditySerialNumber,
|
|
|
|
|
list[rowId].ErpCommodityName,
|
|
|
|
|
list[rowId].ErpCategoryName,
|
|
|
|
|
isIMEIType,
|
|
|
|
|
list[rowId].IMEI,
|
|
|
|
|
list[rowId].StoreName,
|
|
|
|
|
list[rowId].ErpSupplierName,
|
|
|
|
|
list[rowId].FirstStockTime,
|
|
|
|
|
storageType,
|
|
|
|
|
list[rowId].StockSn,
|
|
|
|
|
list[rowId].StockTime,
|
|
|
|
|
list[rowId].WholesalePrice,
|
|
|
|
|
list[rowId].StaffCostPrice,
|
|
|
|
|
list[rowId].Age,
|
|
|
|
|
list[rowId].AllAge,
|
|
|
|
|
state,
|
|
|
|
|
list[rowId].Remark}
|
|
|
|
|
cell, _ := excelize.CoordinatesToCellName(1, rowId+2)
|
|
|
|
|
if err := streamWriter.SetRow(cell, row); err != nil {
|
|
|
|
|
fmt.Println(err)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if err := streamWriter.Flush(); err != nil {
|
|
|
|
|
fmt.Println(err)
|
|
|
|
|
}
|
|
|
|
|
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
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ErpCategoryListExport 导出商品分类
|
2023-11-08 03:51:33 +00:00
|
|
|
|
func ErpCategoryListExport(list []ErpCategory) (string, error) {
|
|
|
|
|
file := excelize.NewFile()
|
|
|
|
|
streamWriter, err := file.NewStreamWriter("Sheet1")
|
|
|
|
|
if err != nil {
|
|
|
|
|
fmt.Println(err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
url := "http://39.108.188.218:8000/img/export/"
|
|
|
|
|
fileName := time.Now().Format(TimeFormat) + "分类列表数据" + ".xlsx"
|
|
|
|
|
|
|
|
|
|
//title := []interface{}{"门店", "用户ID", "订单编号", "下单时间", "卡带", "说明", "回收价", "闲麦价", "审核时间", "审核人", "操作", "复核时间", "复核状态"}
|
|
|
|
|
title := []interface{}{"一级分类", "二级分类"}
|
|
|
|
|
cell, _ := excelize.CoordinatesToCellName(1, 1)
|
|
|
|
|
if err = streamWriter.SetRow(cell, title); err != nil {
|
|
|
|
|
fmt.Println(err)
|
|
|
|
|
}
|
|
|
|
|
rowIdx := 2
|
|
|
|
|
var row []interface{}
|
|
|
|
|
for rowId := 0; rowId < len(list); rowId++ {
|
|
|
|
|
cats := list[rowId].SubCats
|
|
|
|
|
for i := 0; i < len(cats); i++ {
|
|
|
|
|
rowName := list[rowId].Name
|
|
|
|
|
if i != 0 {
|
|
|
|
|
rowName = ""
|
|
|
|
|
}
|
|
|
|
|
row = []interface{}{rowName, cats[i].Name}
|
|
|
|
|
cell, _ := excelize.CoordinatesToCellName(1, rowIdx)
|
|
|
|
|
if err := streamWriter.SetRow(cell, row); err != nil {
|
|
|
|
|
fmt.Println(err)
|
|
|
|
|
}
|
|
|
|
|
rowIdx++
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if err := streamWriter.Flush(); err != nil {
|
|
|
|
|
fmt.Println(err)
|
|
|
|
|
}
|
|
|
|
|
if err := file.SaveAs("/www/server/images/export/" + fileName); err != nil {
|
|
|
|
|
//if err := file.SaveAs("./" + fileName); err != nil {
|
|
|
|
|
fmt.Println(err)
|
|
|
|
|
}
|
|
|
|
|
return url + fileName, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type ErpStockListReq struct {
|
2023-11-16 10:09:11 +00:00
|
|
|
|
SerialNumber string `json:"serial_number"` // 商品编号
|
|
|
|
|
CommodityName string `json:"commodity_name"` // 商品名称
|
|
|
|
|
ErpCategoryId uint32 `json:"erp_category_id"` // 商品分类
|
|
|
|
|
StockType uint32 `json:"stock_type"` // 库存情况:1-全部 2-有库存 3-无库存
|
|
|
|
|
StoreId uint32 `json:"store_id"` // 门店编号
|
2023-11-28 09:33:38 +00:00
|
|
|
|
PageIndex int `json:"pageIndex"` // 页码
|
|
|
|
|
PageSize int `json:"pageSize"` // 页面条数
|
2023-11-16 10:09:11 +00:00
|
|
|
|
//IsExport uint32 `json:"is_export"` // 1-导出
|
2023-11-08 03:51:33 +00:00
|
|
|
|
}
|
2023-11-23 12:38:11 +00:00
|
|
|
|
|
2023-11-08 03:51:33 +00:00
|
|
|
|
type ErpStockListResp struct {
|
|
|
|
|
List []ErpStock `json:"list"`
|
2023-11-28 09:33:38 +00:00
|
|
|
|
Total int `json:"count"` // 数据总条数
|
|
|
|
|
PageIndex int `json:"pageIndex"` // 页码
|
|
|
|
|
PageSize int `json:"pageSize"` // 每页展示条数
|
2023-11-08 03:51:33 +00:00
|
|
|
|
ExportUrl string `json:"export_url"`
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (m *ErpStockListReq) List() (*ErpStockListResp, error) {
|
|
|
|
|
resp := &ErpStockListResp{
|
2023-11-28 09:33:38 +00:00
|
|
|
|
PageIndex: m.PageIndex,
|
|
|
|
|
PageSize: m.PageSize,
|
2023-11-08 03:51:33 +00:00
|
|
|
|
}
|
2023-11-28 09:33:38 +00:00
|
|
|
|
page := m.PageIndex - 1
|
2023-11-08 03:51:33 +00:00
|
|
|
|
if page < 0 {
|
|
|
|
|
page = 0
|
|
|
|
|
}
|
|
|
|
|
if m.PageSize == 0 {
|
|
|
|
|
m.PageSize = 10
|
|
|
|
|
}
|
|
|
|
|
qs := orm.Eloquent.Table("erp_stock")
|
|
|
|
|
if m.SerialNumber != "" {
|
|
|
|
|
qs = qs.Where("commodity_serial_number=?", m.SerialNumber)
|
|
|
|
|
}
|
|
|
|
|
if m.CommodityName != "" {
|
2023-11-17 10:07:01 +00:00
|
|
|
|
qs = qs.Where("erp_commodity_name LIKE ?", "%"+m.CommodityName+"%")
|
2023-11-08 03:51:33 +00:00
|
|
|
|
}
|
|
|
|
|
if m.ErpCategoryId != 0 {
|
|
|
|
|
qs = qs.Where("erp_category_id=?", m.ErpCategoryId)
|
|
|
|
|
}
|
2023-11-16 10:09:11 +00:00
|
|
|
|
if m.StoreId != 0 {
|
|
|
|
|
qs = qs.Where("store_id=?", m.StoreId)
|
2023-11-08 03:51:33 +00:00
|
|
|
|
}
|
2023-11-16 10:09:11 +00:00
|
|
|
|
switch m.StockType {
|
|
|
|
|
case 2:
|
|
|
|
|
qs = qs.Where("count > 0")
|
|
|
|
|
case 3:
|
|
|
|
|
qs = qs.Where("count = 0")
|
|
|
|
|
}
|
|
|
|
|
|
2023-11-08 03:51:33 +00:00
|
|
|
|
var count int64
|
2023-11-16 10:09:11 +00:00
|
|
|
|
if err := qs.Count(&count).Error; err != nil {
|
2023-11-08 03:51:33 +00:00
|
|
|
|
//logger.Error("count err:", err)
|
|
|
|
|
return resp, err
|
|
|
|
|
}
|
|
|
|
|
|
2023-11-16 10:09:11 +00:00
|
|
|
|
var commodities []ErpStock
|
|
|
|
|
err := qs.Order("id DESC").Offset(page * m.PageSize).Limit(m.PageSize).Find(&commodities).Error
|
|
|
|
|
if err != nil && !errors.Is(err, RecordNotFound) {
|
|
|
|
|
//logger.Error("erp commodity list err:", err)
|
|
|
|
|
return resp, err
|
2023-11-08 03:51:33 +00:00
|
|
|
|
}
|
2023-11-16 10:09:11 +00:00
|
|
|
|
resp.List = commodities
|
2023-11-08 03:51:33 +00:00
|
|
|
|
|
2023-11-28 09:33:38 +00:00
|
|
|
|
//跟之前保持一致
|
|
|
|
|
resp.Total = int(count)
|
|
|
|
|
resp.PageIndex = page + 1
|
|
|
|
|
resp.PageSize = m.PageSize
|
|
|
|
|
|
2023-11-08 03:51:33 +00:00
|
|
|
|
return resp, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func ErpStockCommodityListSetAge(commodities []ErpStockCommodity) {
|
|
|
|
|
nowTime := time.Now()
|
|
|
|
|
for i, _ := range commodities {
|
|
|
|
|
commodities[i].Age = uint32(nowTime.Sub(commodities[i].StockTime).Hours()) / 24
|
|
|
|
|
commodities[i].AllAge = uint32(nowTime.Sub(commodities[i].FirstStockTime).Hours()) / 24
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-11-16 10:09:11 +00:00
|
|
|
|
// ErpStockCommodityListReq 库存详情接口请求参数
|
2023-11-08 03:51:33 +00:00
|
|
|
|
type ErpStockCommodityListReq struct {
|
2023-11-16 10:09:11 +00:00
|
|
|
|
ErpStockId uint32 `json:"erp_stock_id"` // 库存id
|
|
|
|
|
ErpCommodityId uint32 `json:"erp_commodity_id"` // 商品id
|
|
|
|
|
SerialNumber string `json:"serial_number"` // 商品编号
|
|
|
|
|
CommodityName string `json:"commodity_name"` // 商品名称
|
|
|
|
|
ErpCategoryId uint32 `json:"erp_category_id"` // 商品分类Id
|
|
|
|
|
IMEI string `json:"imei"` // 串码
|
|
|
|
|
StoreId uint32 `json:"store_id"` // 门店编号
|
|
|
|
|
SupplierId uint32 `json:"supplier_id"` // 供应商id
|
|
|
|
|
State uint32 `json:"state"` // 库存状态:1-在库 2-已售 3-采购退货 4-调拨中
|
|
|
|
|
Sn string `json:"sn"` // 首次入库订单编号
|
|
|
|
|
StorageType uint32 `json:"storage_type"` // 首次入库方式:1-系统入库 2-采购入库
|
|
|
|
|
StockTimeStart string `json:"stock_time_start"` // 最近入库开始时间
|
|
|
|
|
StockTimeEnd string `json:"stock_time_end"` // 最近入库结束时间
|
|
|
|
|
Age uint32 `json:"age"` // 最近库龄
|
|
|
|
|
AllAge uint32 `json:"all_age"` // 总库龄
|
2023-11-28 09:33:38 +00:00
|
|
|
|
PageIndex int `json:"pageIndex"` // 页码
|
|
|
|
|
PageSize int `json:"pageSize"` // 每页展示数据条数
|
2023-11-16 10:09:11 +00:00
|
|
|
|
IsExport uint32 `json:"is_export"` // 是否导出excel:1-导出
|
2023-11-08 03:51:33 +00:00
|
|
|
|
}
|
2023-11-24 09:09:24 +00:00
|
|
|
|
|
|
|
|
|
// ErpStockCommodityListResp 库存详情接口响应参数
|
2023-11-08 03:51:33 +00:00
|
|
|
|
type ErpStockCommodityListResp struct {
|
|
|
|
|
List []ErpStockCommodity `json:"list"`
|
2023-11-28 09:33:38 +00:00
|
|
|
|
Total int `json:"count"` // 数据总条数
|
|
|
|
|
PageIndex int `json:"pageIndex"` // 页码
|
|
|
|
|
PageSize int `json:"pageSize"` // 每页展示条数
|
2023-11-08 03:51:33 +00:00
|
|
|
|
ExportUrl string `json:"export_url"`
|
|
|
|
|
}
|
|
|
|
|
|
2023-11-24 09:09:24 +00:00
|
|
|
|
// GetDetailList 查看库存详情
|
2023-11-16 10:09:11 +00:00
|
|
|
|
func (m *ErpStockCommodityListReq) GetDetailList() (*ErpStockCommodityListResp, error) {
|
2023-11-08 03:51:33 +00:00
|
|
|
|
resp := &ErpStockCommodityListResp{
|
2023-11-28 09:33:38 +00:00
|
|
|
|
PageIndex: m.PageIndex,
|
|
|
|
|
PageSize: m.PageSize,
|
2023-11-08 03:51:33 +00:00
|
|
|
|
}
|
2023-11-28 09:33:38 +00:00
|
|
|
|
page := m.PageIndex - 1
|
2023-11-08 03:51:33 +00:00
|
|
|
|
if page < 0 {
|
|
|
|
|
page = 0
|
|
|
|
|
}
|
|
|
|
|
if m.PageSize == 0 {
|
|
|
|
|
m.PageSize = 10
|
|
|
|
|
}
|
2023-11-16 10:09:11 +00:00
|
|
|
|
|
|
|
|
|
qs := orm.Eloquent.Table("erp_stock_commodity").Order("id DESC")
|
|
|
|
|
|
|
|
|
|
// 构建查询条件
|
|
|
|
|
m.buildQueryConditions(qs)
|
|
|
|
|
|
|
|
|
|
var count int64
|
|
|
|
|
if err := qs.Count(&count).Error; err != nil {
|
|
|
|
|
//logger.Error("count err:", err)
|
|
|
|
|
return resp, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//获取库存商品列表
|
|
|
|
|
var commodities []ErpStockCommodity
|
|
|
|
|
if m.IsExport == 1 {
|
|
|
|
|
err := qs.Find(&commodities).Error
|
|
|
|
|
if err != nil && !errors.Is(err, RecordNotFound) {
|
|
|
|
|
//logger.Error("dailys err:", err)
|
|
|
|
|
return resp, err
|
|
|
|
|
}
|
|
|
|
|
|
2023-11-23 12:38:11 +00:00
|
|
|
|
listExport, err := InventoryDetailListExport(commodities)
|
|
|
|
|
if err != nil {
|
|
|
|
|
//logger.Error("list export err:", err)
|
|
|
|
|
}
|
|
|
|
|
resp.ExportUrl = listExport
|
2023-11-16 10:09:11 +00:00
|
|
|
|
} else {
|
|
|
|
|
err := qs.Offset(page * m.PageSize).Limit(m.PageSize).Find(&commodities).Error
|
|
|
|
|
if err != nil && !errors.Is(err, RecordNotFound) {
|
|
|
|
|
//logger.Error("erp commodity list err:", err)
|
|
|
|
|
return resp, err
|
|
|
|
|
}
|
|
|
|
|
ErpStockCommodityListSetAge(commodities)
|
|
|
|
|
resp.List = commodities
|
|
|
|
|
}
|
|
|
|
|
|
2023-11-28 09:33:38 +00:00
|
|
|
|
////正常返回
|
|
|
|
|
//resp.Total = int(count)/m.PageSize + 1
|
|
|
|
|
//resp.PageNum = page + 1
|
|
|
|
|
//resp.PageSize = len(resp.List)
|
|
|
|
|
|
|
|
|
|
//跟之前保持一致
|
|
|
|
|
resp.Total = int(count)
|
|
|
|
|
resp.PageIndex = page + 1
|
|
|
|
|
resp.PageSize = m.PageSize
|
|
|
|
|
|
2023-11-16 10:09:11 +00:00
|
|
|
|
return resp, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// buildQueryConditions 根据请求参数构建查询条件
|
|
|
|
|
func (m *ErpStockCommodityListReq) buildQueryConditions(qs *gorm.DB) {
|
|
|
|
|
if m.ErpStockId != 0 { //库存id
|
|
|
|
|
qs = qs.Where("erp_stock_id=?", m.ErpStockId)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if m.ErpCommodityId != 0 { //商品id
|
|
|
|
|
qs = qs.Where("erp_commodity_id=?", m.ErpCommodityId)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if m.SerialNumber != "" { //商品编号
|
2023-11-08 03:51:33 +00:00
|
|
|
|
qs = qs.Where("commodity_serial_number=?", m.SerialNumber)
|
|
|
|
|
}
|
2023-11-16 10:09:11 +00:00
|
|
|
|
|
|
|
|
|
if m.CommodityName != "" { //商品名称
|
|
|
|
|
qs = qs.Where("erp_commodity_name LIKE ?", "%"+m.CommodityName+"%")
|
2023-11-08 03:51:33 +00:00
|
|
|
|
}
|
2023-11-16 10:09:11 +00:00
|
|
|
|
|
|
|
|
|
if m.ErpCategoryId != 0 { //商品分类id
|
2023-11-08 03:51:33 +00:00
|
|
|
|
qs = qs.Where("erp_category_id=?", m.ErpCategoryId)
|
|
|
|
|
}
|
2023-11-16 10:09:11 +00:00
|
|
|
|
|
|
|
|
|
if m.IMEI != "" { //商品串码
|
2023-11-08 03:51:33 +00:00
|
|
|
|
qs = qs.Where("imei=?", m.IMEI)
|
|
|
|
|
}
|
2023-11-16 10:09:11 +00:00
|
|
|
|
|
|
|
|
|
if m.StoreId != 0 { //门店编号
|
2023-11-08 03:51:33 +00:00
|
|
|
|
qs = qs.Where("store_id=?", m.StoreId)
|
|
|
|
|
}
|
2023-11-16 10:09:11 +00:00
|
|
|
|
|
2023-11-24 09:09:24 +00:00
|
|
|
|
if m.SupplierId != 0 { //供应商id
|
|
|
|
|
qs = qs.Where("supplier_id=?", m.SupplierId)
|
|
|
|
|
}
|
|
|
|
|
|
2023-11-16 10:09:11 +00:00
|
|
|
|
if m.State != 0 { //库存状态
|
2023-11-08 03:51:33 +00:00
|
|
|
|
qs = qs.Where("state=?", m.State)
|
|
|
|
|
}
|
2023-11-16 10:09:11 +00:00
|
|
|
|
|
|
|
|
|
if m.Sn != "" { //首次入库订单编号
|
2023-11-08 03:51:33 +00:00
|
|
|
|
qs = qs.Where("stock_sn=?", m.Sn)
|
|
|
|
|
}
|
2023-11-16 10:09:11 +00:00
|
|
|
|
|
|
|
|
|
if m.StorageType != 0 { //首次入库方式
|
2023-11-08 03:51:33 +00:00
|
|
|
|
qs = qs.Where("storage_type=?", m.StorageType)
|
|
|
|
|
}
|
2023-11-16 10:09:11 +00:00
|
|
|
|
|
|
|
|
|
if m.StockTimeStart != "" { //最近入库开始时间
|
2023-11-08 03:51:33 +00:00
|
|
|
|
startTime, err := time.Parse(DateTimeFormat, m.StockTimeStart)
|
2023-11-16 10:09:11 +00:00
|
|
|
|
if err == nil {
|
2023-11-08 03:51:33 +00:00
|
|
|
|
qs = qs.Where("first_stock_time>?", startTime)
|
2023-11-16 10:09:11 +00:00
|
|
|
|
} else {
|
|
|
|
|
//logger.Error("stock time start parse err:", err)
|
2023-11-08 03:51:33 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2023-11-16 10:09:11 +00:00
|
|
|
|
|
|
|
|
|
if m.StockTimeEnd != "" { //最近入库结束时间
|
2023-11-08 03:51:33 +00:00
|
|
|
|
endTime, err := time.Parse(DateTimeFormat, m.StockTimeEnd)
|
2023-11-16 10:09:11 +00:00
|
|
|
|
if err == nil {
|
2023-11-08 03:51:33 +00:00
|
|
|
|
qs = qs.Where("first_stock_time<?", endTime)
|
2023-11-16 10:09:11 +00:00
|
|
|
|
} else {
|
|
|
|
|
//logger.Error("stock time end parse err:", err)
|
2023-11-08 03:51:33 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2023-11-16 10:09:11 +00:00
|
|
|
|
|
|
|
|
|
if m.Age != 0 { //最近库龄
|
2023-11-08 03:51:33 +00:00
|
|
|
|
qs = qs.Where("stock_time<?", time.Now().AddDate(0, 0, int(m.Age)*(-1)))
|
|
|
|
|
}
|
|
|
|
|
|
2023-11-16 10:09:11 +00:00
|
|
|
|
if m.AllAge != 0 { //总库龄
|
|
|
|
|
qs = qs.Where("first_stock_time<?", time.Now().AddDate(0, 0, int(m.AllAge)*(-1)))
|
2023-11-08 03:51:33 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2023-11-17 10:07:01 +00:00
|
|
|
|
|
2023-11-24 09:09:24 +00:00
|
|
|
|
// SetStockCommodityState 更新库存状态
|
2023-11-17 10:07:01 +00:00
|
|
|
|
func SetStockCommodityState(id, state uint32) error {
|
|
|
|
|
if state != 4 {
|
|
|
|
|
state = 4
|
|
|
|
|
}
|
|
|
|
|
if err := orm.Eloquent.Model(&ErpStockCommodity{}).Where("id=?", id).Updates(map[string]interface{}{
|
|
|
|
|
"state": state}).Error; err != nil {
|
|
|
|
|
return fmt.Errorf("[update err]:%v", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type BatchPrintInfo struct {
|
|
|
|
|
ErpCommodityName string `json:"erp_commodity_name" binding:"required"` // 商品名称
|
|
|
|
|
RetailPrice uint32 `json:"retail_price" binding:"required"` // 指导零售价
|
|
|
|
|
IMEI string `json:"imei" binding:"required"` // 商品串码
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type BatchPrintInfoReq struct {
|
|
|
|
|
PrintListInfo []*BatchPrintInfo `json:"print_list_info" binding:"required"`
|
|
|
|
|
}
|
|
|
|
|
|
2023-11-24 09:09:24 +00:00
|
|
|
|
// BatchPrint 批量打印标签
|
2023-11-17 10:07:01 +00:00
|
|
|
|
func BatchPrint(req *BatchPrintInfoReq) error {
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func StringToFloat(req string) (float64, error) {
|
|
|
|
|
if req == "" {
|
|
|
|
|
return 0, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return strconv.ParseFloat(req, 64)
|
|
|
|
|
}
|
2023-11-23 12:38:11 +00:00
|
|
|
|
|
2023-11-24 09:09:24 +00:00
|
|
|
|
func PercentFloatStringToUin32(s string) uint32 {
|
|
|
|
|
u := uint32(0)
|
|
|
|
|
if s != "" {
|
|
|
|
|
s = strings.ReplaceAll(s, "%", "")
|
|
|
|
|
}
|
|
|
|
|
f, err := strconv.ParseFloat(s, 64)
|
|
|
|
|
if err != nil {
|
|
|
|
|
//logger.Error("parse float err:", err)
|
|
|
|
|
return u
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
u = uint32(f * 100)
|
|
|
|
|
return u
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func IntStringToUin32(s string) uint32 {
|
|
|
|
|
u := uint32(0)
|
|
|
|
|
if s != "" {
|
|
|
|
|
s = strings.ReplaceAll(s, "%", "")
|
|
|
|
|
}
|
|
|
|
|
i, err := strconv.Atoi(s)
|
|
|
|
|
if err != nil {
|
|
|
|
|
//logger.Error("parse float err:", err)
|
|
|
|
|
return u
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
u = uint32(i)
|
|
|
|
|
return u
|
2023-11-23 12:38:11 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func NewStockImporter() *StockImporter {
|
|
|
|
|
return &StockImporter{
|
|
|
|
|
CensusMap: make(map[uint32]map[uint32]uint32, 0),
|
|
|
|
|
CommodityMap: make(map[uint32]*ErpCommodity),
|
|
|
|
|
StoreMap: make(map[uint32]string, 0),
|
|
|
|
|
Inventories: make([]*ErpInventoryStock, 0),
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-11-24 09:09:24 +00:00
|
|
|
|
|
|
|
|
|
// UpdateStockCommodityRemark 更新库存商品备注信息
|
|
|
|
|
func UpdateStockCommodityRemark(id int, remark string) error {
|
|
|
|
|
if remark == "" {
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
if err := orm.Eloquent.Model(&ErpStockCommodity{}).Where("id=?", id).Updates(map[string]interface{}{
|
|
|
|
|
"remark": remark}).Error; err != nil {
|
|
|
|
|
return fmt.Errorf("[update err]:%v", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|