1.库存详情导出excel时判断是否有入库采购价、入库员工成本价权限;

2.库存列表增加入参,支持查询不同串码类型;
3.采购入库时判断串码是否重复有缺陷,已优化;
4.采购相关报表金额四舍五入保留2位小数;
This commit is contained in:
chenlin 2024-07-12 15:54:31 +08:00
parent 17c8472e76
commit 0c6325bd2c
6 changed files with 112 additions and 24 deletions

View File

@ -35,6 +35,9 @@ const (
SystemOut = 5 // 系统出库
CheckOut = 6 // 盘点出库
OnSale = 7 // 销售锁定中
PurchasePrice = "erp:stock:stockDetails:list:purchasePrice" // 入库采购价
EmployeeCostPrice = "erp:stock:stockDetails:list:employeeCostPrice" // 入库员工成本价
)
// ErpStock 库存列表
@ -1142,7 +1145,7 @@ func GenerateSerialCode(categoryID uint32) (string, error) {
serialCode := categoryStr + dateStr + randomStr
// 检查生成的串码是否已存在 todo 是否需要判断状态,采购退货的可以重复?
exist, err := QueryRecordExist(fmt.Sprintf("SELECT * FROM erp_stock_commodity WHERE FIND_IN_SET(%s, imei) > 0 ", serialCode))
exist, err := QueryRecordExist(fmt.Sprintf("SELECT * FROM erp_stock_commodity WHERE FIND_IN_SET('%s', imei) > 0 ", serialCode))
if err != nil {
logger.Error("exist sn err")
}
@ -1446,25 +1449,62 @@ func ErpCommodityListExport(list []ErpCommodity) (string, error) {
return url + fileName, nil
}
// 判断是否有入库采购价、入库员工成本价的权限
func checkRoleMenu(c *gin.Context, menuName string) (bool, error) {
if tools.GetRoleName(c) == "admin" || tools.GetRoleName(c) == "系统管理员" {
return true, nil
}
var sysMenu Menu
err := orm.Eloquent.Table("sys_menu").Raw("select * from sys_menu where permission = ?",
menuName).Scan(&sysMenu).Error
if err != nil {
logger.Errorf("get sys_menu err:", err)
return false, err
}
roleId := tools.GetRoleId(c)
exist, err := QueryRecordExist(fmt.Sprintf("SELECT * FROM sys_role_menu WHERE `menu_id`='%d' "+
"and `role_id`='%d'", sysMenu.MenuId, roleId))
if err != nil {
logger.Errorf("checkRoleMenu QueryRecordExist err:", err)
return false, err
}
return exist, nil
}
// InventoryDetailListExport 导出库存商品列表
func InventoryDetailListExport(list []ErpStockCommodity) (string, error) {
func InventoryDetailListExport(list []ErpStockCommodity, exportPurchasePrice bool, exportStaffCostPrice bool) (string, error) {
file := excelize.NewFile()
streamWriter, err := file.NewStreamWriter("Sheet1")
if err != nil {
fmt.Println(err)
return "", err
}
url := ExportUrl
fileName := time.Now().Format(TimeFormat) + "商品" + ".xlsx"
fmt.Println("url fileName:", url+fileName)
// 设置标题行
title := []interface{}{"商品编号", "商品名称", "商品分类", "是否串码", "商品串码", "所属门店", "供应商", "首次入库时间", "首次入库方式",
"首次入库订单编号", "最近入库时间", "入库采购价", "入库员工成本价", "最近库龄", "总库龄", "当前状态", "备注"}
"首次入库订单编号", "最近入库时间"}
if exportPurchasePrice {
title = append(title, "入库采购价")
}
if exportStaffCostPrice {
title = append(title, "入库员工成本价")
}
title = append(title, "最近库龄", "总库龄", "当前状态", "备注")
cell, _ := excelize.CoordinatesToCellName(1, 1)
if err = streamWriter.SetRow(cell, title); err != nil {
fmt.Println(err)
return "", err
}
var row []interface{}
for rowId := 0; rowId < len(list); rowId++ {
isIMEIType := "是"
if list[rowId].IMEIType == 1 {
@ -1492,7 +1532,7 @@ func InventoryDetailListExport(list []ErpStockCommodity) (string, error) {
state = "盘点出库"
}
row = []interface{}{
row := []interface{}{
list[rowId].CommoditySerialNumber,
list[rowId].ErpCommodityName,
list[rowId].ErpCategoryName,
@ -1504,23 +1544,36 @@ func InventoryDetailListExport(list []ErpStockCommodity) (string, error) {
storageType,
list[rowId].OriginalSn,
list[rowId].StockTime,
list[rowId].WholesalePrice,
list[rowId].WholesalePrice + list[rowId].StaffCostPrice,
list[rowId].Age,
list[rowId].AllAge,
state,
list[rowId].Remark}
}
// 控制是否导出入库采购价和入库员工成本价
if exportPurchasePrice {
row = append(row, list[rowId].WholesalePrice)
}
if exportStaffCostPrice {
row = append(row, list[rowId].WholesalePrice+list[rowId].StaffCostPrice)
}
row = append(row, list[rowId].Age)
row = append(row, list[rowId].AllAge)
row = append(row, state)
row = append(row, list[rowId].Remark)
cell, _ := excelize.CoordinatesToCellName(1, rowId+2)
if err := streamWriter.SetRow(cell, row); err != nil {
fmt.Println(err)
return "", err
}
}
if err := streamWriter.Flush(); err != nil {
fmt.Println(err)
return "", err
}
fmt.Println("save fileName:", config.ExportConfig.Path+fileName)
if err := file.SaveAs(config.ExportConfig.Path + fileName); err != nil {
fmt.Println(err)
return "", err
}
return url + fileName, nil
}
@ -1573,6 +1626,7 @@ type ErpStockListReq struct {
SerialNumber string `json:"serial_number"` // 商品编号
CommodityName string `json:"commodity_name"` // 商品名称
ErpCategoryId uint32 `json:"erp_category_id"` // 商品分类
IsIMEI uint32 `json:"is_imei"` // 是否串码0-查全部 1-查串码类 2-查非串码
StockType uint32 `json:"stock_type"` // 库存情况:1-全部 2-有库存 3-无库存
StoreId uint32 `json:"store_id"` // 门店编号
PageIndex int `json:"pageIndex"` // 页码
@ -1944,11 +1998,11 @@ func (m *ErpStockListReq) stockNoEmptyList(c *gin.Context) (*ErpStockListResp, e
} else {
if len(storeList) > 0 {
if len(storeList) == 1 {
qs = qs.Where("store_id = ?", storeList[0])
es = es.Where("store_id = ?", storeList[0])
qs = qs.Where("erp_stock.store_id = ?", storeList[0])
es = es.Where("erp_stock.store_id = ?", storeList[0])
} else {
qs = qs.Where("store_id IN (?)", storeList)
es = es.Where("store_id IN (?)", storeList)
qs = qs.Where("erp_stock.store_id IN (?)", storeList)
es = es.Where("erp_stock.store_id IN (?)", storeList)
}
} else {
return nil, errors.New("用户未绑定门店")
@ -2011,6 +2065,14 @@ func (m *ErpStockListReq) stockNoEmptyList(c *gin.Context) (*ErpStockListResp, e
es = es.Where("erp_commodity.erp_category_id=?", m.ErpCategoryId)
}
if m.IsIMEI != 0 {
if m.IsIMEI == 1 { // 查串码数据
qs = qs.Where("erp_commodity.imei_type != ?", NoIMEICommodity)
} else if m.IsIMEI == 2 { // 查非串码数据
qs = qs.Where("erp_commodity.imei_type = ?", NoIMEICommodity)
}
}
var commodities []struct {
ErpCommodity
TotalCount int
@ -2365,11 +2427,18 @@ func (m *ErpStockCommodityListReq) GetDetailList(c *gin.Context, nType uint32) (
if m.IsExport == 1 {
err := qs.Find(&commodities).Order("stock_time DESC,id DESC").Error
if err != nil && !errors.Is(err, RecordNotFound) {
//logger.Error("dailys err:", err)
logger.Error("find err:", logger.Field("err", err))
return resp, err
}
ErpStockCommodityListSetAge(commodities)
listExport, err := InventoryDetailListExport(commodities)
// 判断是否有入库采购价、入库员工成本价的权限
purchasePriceFlag, _ := checkRoleMenu(c, PurchasePrice)
employeeCostPriceFlag, _ := checkRoleMenu(c, EmployeeCostPrice)
fmt.Println("purchasePriceFlag is:", purchasePriceFlag)
fmt.Println("employeeCostPriceFlag is:", employeeCostPriceFlag)
logger.Info("purchasePriceFlag is:", logger.Field("purchasePriceFlag", purchasePriceFlag))
logger.Info("employeeCostPriceFlag is:", logger.Field("employeeCostPriceFlag", purchasePriceFlag))
listExport, err := InventoryDetailListExport(commodities, purchasePriceFlag, employeeCostPriceFlag)
if err != nil {
//logger.Error("list export err:", err)
}
@ -2776,7 +2845,7 @@ func CheckAndConvertBarcode(input string) (string, error) {
// 4.判断逗号隔开的数据数据库是否已存在
for _, part := range parts {
// 检查生成的条码是否已存在
exist, err := QueryRecordExist(fmt.Sprintf("SELECT * FROM erp_commodity WHERE FIND_IN_SET(%s, erp_barcode) > 0", part))
exist, err := QueryRecordExist(fmt.Sprintf("SELECT * FROM erp_commodity WHERE FIND_IN_SET('%s', erp_barcode) > 0", part))
if err != nil {
logger.Error("exist sn err")
}
@ -2811,7 +2880,7 @@ func CheckBarcodeById(input string, commodityId uint32) (string, error) {
// 4.判断逗号隔开的数据数据库是否已存在
for _, part := range parts {
// 检查生成的条码是否已存在
exist, err := QueryRecordExist(fmt.Sprintf("SELECT * FROM erp_commodity WHERE FIND_IN_SET(%s, erp_barcode) > 0", part))
exist, err := QueryRecordExist(fmt.Sprintf("SELECT * FROM erp_commodity WHERE FIND_IN_SET('%s', erp_barcode) > 0", part))
if err != nil {
logger.Error("exist sn err")
}
@ -2859,7 +2928,7 @@ func GenerateBarcode(categoryCode uint32) (string, error) {
barcode := fmt.Sprintf("%03s%s%s", category.Number[:3], dateCode, randomNumber)
// 检查生成的条码是否已存在
exist, err := QueryRecordExist(fmt.Sprintf("SELECT * FROM erp_commodity WHERE FIND_IN_SET(%s, erp_barcode) > 0", barcode))
exist, err := QueryRecordExist(fmt.Sprintf("SELECT * FROM erp_commodity WHERE FIND_IN_SET('%s', erp_barcode) > 0", barcode))
if err != nil {
logger.Error("exist sn err")
}

View File

@ -3913,6 +3913,7 @@ func queryRetailDetailCommon(req *ErpOrderRetailDetailReq, c *gin.Context) (*Erp
}
if req.CashierId != 0 { // 支付方式
qs = qs.Where("JSON_CONTAINS(cashier_list, ?)", fmt.Sprintf(`{"cashier_id":%d}`, req.CashierId))
qs = qs.Where("retail_type=?", RetailTypeSale)
//totalPerQs = totalPerQs.Where("erp_order_pay_way.cashier_id = ?", req.CashierId)
}
if req.StartTime != "" { // 审核开始时间

View File

@ -1508,7 +1508,7 @@ func checkPurchaseInventory(req *ErpPurchaseInventoryReq, imeiCheckFlag bool) er
// 如果该商品是串码商品,判断其串码是否会重复
if inventory.IMEI != "" {
exist, err := QueryRecordExist(fmt.Sprintf("SELECT * FROM erp_stock_commodity WHERE FIND_IN_SET(%s, imei) > 0", inventory.IMEI))
exist, err := QueryRecordExist(fmt.Sprintf("SELECT * FROM erp_stock_commodity WHERE FIND_IN_SET('%s', imei) > 0", inventory.IMEI))
if err != nil {
logger.Error("exist sn err")
}
@ -3865,6 +3865,7 @@ func getReportByOrderFromCommon(req *ErpPurchaseReportByOrderReq, c *gin.Context
resp.List = reportByOrderDataList
}
nTotalAmount = math.Round(nTotalAmount*100) / 100
resp.Amount = nTotalAmount
resp.Count = nTotalCount
//resp.Total = int(count)
@ -5764,6 +5765,12 @@ func GetReportDetail(req *ErpPurchaseReportDetailReq, c *gin.Context) (*ErpPurch
resp.Total = int(count)
resp.Price, resp.EmployeePrice, resp.RejectPrice, resp.DifferencePrice = calculatePrices(reportList)
// 四舍五入保留2位小数
resp.Price = math.Round(resp.Price*100) / 100
resp.EmployeePrice = math.Round(resp.EmployeePrice*100) / 100
resp.RejectPrice = math.Round(resp.RejectPrice*100) / 100
resp.DifferencePrice = math.Round(resp.DifferencePrice*100) / 100
if req.IsExport == 1 {
resp.List = reportList
filePath, err := reportDetailExport(resp)

View File

@ -9441,7 +9441,7 @@ const docTemplate = `{
"type": "object",
"properties": {
"bank_trx_no": {
"description": "银流水号",
"description": "银流水号",
"type": "string"
},
"bill_sn": {
@ -11249,6 +11249,10 @@ const docTemplate = `{
"description": "商品分类",
"type": "integer"
},
"is_imei": {
"description": "是否串码0-查全部 1-查串码类 2-查非串码",
"type": "integer"
},
"pageIndex": {
"description": "页码",
"type": "integer"

View File

@ -9430,7 +9430,7 @@
"type": "object",
"properties": {
"bank_trx_no": {
"description": "银流水号",
"description": "银流水号",
"type": "string"
},
"bill_sn": {
@ -11238,6 +11238,10 @@
"description": "商品分类",
"type": "integer"
},
"is_imei": {
"description": "是否串码0-查全部 1-查串码类 2-查非串码",
"type": "integer"
},
"pageIndex": {
"description": "页码",
"type": "integer"

View File

@ -2413,7 +2413,7 @@ definitions:
models.ErpOrderRetailDetailReq:
properties:
bank_trx_no:
description: 流水号
description: 流水号
type: string
bill_sn:
description: 单据编号
@ -3730,6 +3730,9 @@ definitions:
erp_category_id:
description: 商品分类
type: integer
is_imei:
description: 是否串码0-查全部 1-查串码类 2-查非串码
type: integer
pageIndex:
description: 页码
type: integer