mh_goadmin_server/app/admin/apis/basic/commodity.go
chenlin 9207440c53 1.修复缺陷,优化代码:
(1)库存调拨、库存变动中商品都拆分为单条数据;
(2)编辑商品资料时同步更新库存表和库存商品表的商品编号;
(3)租卡相关接口添加权限校验,只能查询对应门店权限的数据;
2024-05-31 17:51:41 +08:00

483 lines
14 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package basic
import (
"errors"
"fmt"
"github.com/gin-gonic/gin"
"go-admin/app/admin/middleware"
"go-admin/app/admin/models"
orm "go-admin/common/global"
"go-admin/logger"
"go-admin/tools/app"
"io"
"net/http"
)
// CommodityCreate 新增商品
// @Summary 新增商品
// @Tags 商品资料
// @Produce json
// @Accept json
// @Param request body models.CommodityCreateRequest true "商品新增模型"
// @Success 200 {object} models.ErpCommodity
// @Router /api/v1/commodity/create [post]
// 规则:商品名称/商品编号相同则为同一商品,创建的时候由于商品编号不重复,无需判断
func CommodityCreate(c *gin.Context) {
var req = new(models.CommodityCreateRequest)
err := c.ShouldBindJSON(&req)
if err != nil {
fmt.Println(err.Error())
app.Error(c, http.StatusBadRequest, errors.New("param err"), "参数错误:"+err.Error())
return
}
//brokerage1Float, err := models.StringToFloat(req.Brokerage1)
//if err != nil {
// //logger.Error("brokerage1 err:", err)
// app.Error(c, http.StatusBadRequest, errors.New("param err"), "参数错误")
// return
//}
//
//brokerage2Float, err := models.StringToFloat(req.Brokerage2)
//if err != nil {
// //logger.Error("brokerage1 err:", err)
// app.Error(c, http.StatusBadRequest, errors.New("param err"), "参数错误")
// return
//}
//
//memberDiscountFloat, err := models.StringToFloat(req.MemberDiscount)
//if err != nil {
// //logger.Error("brokerage1 err:", err)
// app.Error(c, http.StatusBadRequest, errors.New("param err"), "参数错误")
// return
//}
barCode := ""
if req.ErpBarcode != "" { // 条码不为空则校验
barCode, err = models.CheckAndConvertBarcode(req.ErpBarcode)
if err != nil {
app.Error(c, http.StatusBadRequest, errors.New("param err"), "参数错误:"+err.Error())
return
}
} else { // 条码为空则自动生成
barCode, err = models.GenerateBarcode(req.ErpCategoryId)
if err != nil {
app.Error(c, http.StatusBadRequest, errors.New("gen barcode err"), err.Error())
return
}
}
brokerage1Float := req.Brokerage1
brokerage2Float := req.Brokerage2
memberDiscountFloat := req.MemberDiscount
if models.IsExistingProduct(req.Name) {
app.Error(c, http.StatusBadRequest, errors.New("param err"), "商品名称已存在,不能重复")
return
}
if req.IsIMEI == 2 { // 是否串码1-串码类 2-非串码
req.IMEIType = 1 // 系统生成串码2-是(系统生成) 3-否(手动添加) 1表示非串码
}
commodity := &models.ErpCommodity{
Number: 1,
Name: req.Name,
ErpCategoryId: req.ErpCategoryId,
ErpCategoryName: "",
ErpBarcode: barCode,
IMEIType: req.IMEIType,
ErpSupplierId: req.ErpSupplierId,
ErpSupplierName: "",
RetailPrice: req.RetailPrice,
MinRetailPrice: req.MinRetailPrice,
//StaffCostPrice: req.StaffCostPrice + req.WholesalePrice,
StaffCostPrice: req.StaffCostPrice,
WholesalePrice: req.WholesalePrice,
Brokerage1: brokerage1Float,
Brokerage2: brokerage2Float,
MemberDiscount: memberDiscountFloat,
Origin: req.Origin,
Remark: req.Remark,
}
err = commodity.SetErpCategory()
if err != nil {
//logger.Error("set erp category err:", err)
app.Error(c, http.StatusInternalServerError, err, "创建失败")
return
}
err = commodity.IdInit()
if err != nil {
app.Error(c, http.StatusInternalServerError, err, "创建失败:"+err.Error())
return
}
commodity.SerialNumber, err = models.GenerateSerialNumber(req.ErpCategoryId)
if err != nil {
app.Error(c, http.StatusInternalServerError, err, err.Error())
return
}
err = orm.Eloquent.Create(commodity).Error
if err != nil {
//logger.Error("create commodity err:", err)
app.Error(c, http.StatusInternalServerError, err, "创建失败")
return
}
app.OK(c, commodity, "OK")
return
}
// CommodityList 商品列表
// @Summary 商品列表
// @Tags 商品资料
// @Produce json
// @Accept json
// @Param request body models.ErpCommodityListReq true "商品列表模型"
// @Success 200 {object} models.ErpCommodityListResp
// @Router /api/v1/commodity/list [post]
func CommodityList(c *gin.Context) {
req := &models.ErpCommodityListReq{}
if err := c.ShouldBindJSON(&req); err != nil {
//logger.Error(err)
app.Error(c, http.StatusBadRequest, errors.New("para err"), "参数错误")
return
}
resp, err := req.List()
if err != nil {
//logger.Error("erp commodity list err:", err)
app.Error(c, http.StatusInternalServerError, err, "获取失败")
return
}
app.OK(c, resp, "")
return
}
// CommodityDetail 商品详情
// @Summary 商品详情
// @Tags 商品资料
// @Produce json
// @Accept json
// @Param request body models.CommodityDetailRequest true "商品详情模型"
// @Success 200 {object} models.ErpCommodity
// @Router /api/v1/commodity/detail [post]
func CommodityDetail(c *gin.Context) {
var req = new(models.CommodityDetailRequest)
if err := c.ShouldBindJSON(&req); err != nil {
//logger.Error(err)
app.Error(c, http.StatusBadRequest, errors.New("para err"), "参数错误")
return
}
var commodity models.ErpCommodity
qs := orm.Eloquent.Table("erp_commodity")
if req.ErpCommodityId != 0 {
qs = qs.Where("id=?", req.ErpCommodityId)
}
if req.SerialNumber != "" {
qs = qs.Where("serial_number=?", req.SerialNumber)
}
err := qs.Find(&commodity).Error
if err != nil {
//logger.Error("erp commodity err:", err)
app.Error(c, http.StatusInternalServerError, err, "获取失败")
return
}
if commodity.IMEIType == 1 { //无串码
commodity.IsIMEI = 2 // 非串码
} else {
commodity.IsIMEI = 1 // 串码
}
// 查询是否有库存
var count int64
err = orm.Eloquent.Table("erp_stock_commodity").Where("erp_commodity_id = ? and state = ?",
commodity.ID, models.InStock).Count(&count).Error
if err != nil {
app.Error(c, http.StatusInternalServerError, err, "获取商品库存信息失败")
return
}
commodity.StockCount = uint32(count)
app.OK(c, commodity, "")
return
}
// CommodityEdit 编辑商品
// @Summary 编辑商品
// @Tags 商品资料
// @Produce json
// @Accept json
// @Param request body models.CommodityEditRequest true "编辑商品模型"
// @Success 200 {object} models.ErpCommodity
// @Router /api/v1/commodity/edit [post]
func CommodityEdit(c *gin.Context) {
var req = new(models.CommodityEditRequest)
err := c.ShouldBindJSON(&req)
if err != nil {
logger.Error("ShouldBindJSON err:", logger.Field("err", err))
app.Error(c, http.StatusBadRequest, errors.New("para err"), "参数错误:"+err.Error())
return
}
barCode := ""
if req.ErpBarcode != "" { // 条码不为空则校验
barCode, err = models.CheckBarcodeById(req.ErpBarcode, req.Id)
if err != nil {
app.Error(c, http.StatusBadRequest, errors.New("param err"), "参数错误:"+err.Error())
return
}
} else { // 条码为空则自动生成
barCode, err = models.GenerateBarcode(req.ErpCategoryId)
if err != nil {
app.Error(c, http.StatusBadRequest, errors.New("gen barcode err"), err.Error())
return
}
}
brokerage1Float := req.Brokerage1
brokerage2Float := req.Brokerage2
memberDiscountFloat := req.MemberDiscount
commodity := &models.ErpCommodity{
Name: req.Name,
ErpCategoryId: req.ErpCategoryId,
ErpCategoryName: "",
ErpBarcode: barCode,
IMEIType: req.IMEIType,
ErpSupplierId: req.ErpSupplierId,
ErpSupplierName: "",
RetailPrice: req.RetailPrice,
MinRetailPrice: req.MinRetailPrice,
//StaffCostPrice: req.StaffCostPrice + req.WholesalePrice,
StaffCostPrice: req.StaffCostPrice,
WholesalePrice: req.WholesalePrice,
Brokerage1: brokerage1Float,
Brokerage2: brokerage2Float,
MemberDiscount: memberDiscountFloat,
Origin: req.Origin,
Remark: req.Remark,
}
commodity.ID = req.Id
err = commodity.SetErpCategory()
if err != nil {
logger.Error("set erp category err:", logger.Field("err", err))
app.Error(c, http.StatusInternalServerError, err, "操作失败")
return
}
commodity.IdInit()
var catCommodity models.ErpCommodity
err = orm.Eloquent.Table("erp_commodity").Where("id=?", req.Id).Find(&catCommodity).Error
if err != nil {
logger.Error("cat erp commodity err:", logger.Field("err", err))
app.Error(c, http.StatusInternalServerError, err, "操作失败")
return
}
commodity.Number = catCommodity.Number
commodity.SerialNumber = catCommodity.SerialNumber
if commodity.ErpCategory != nil && commodity.ErpCategory.ID != 0 {
if commodity.ErpCategory.ID != catCommodity.ErpCategoryId { // 编辑时更换了分类ID
commodity.ErpCategoryId = commodity.ErpCategory.ID
commodity.ErpCategoryName = commodity.ErpCategory.Name
commodity.SerialNumber, err = models.GenerateSerialNumber(commodity.ErpCategoryId) // 更新商品编号
if err != nil {
app.Error(c, http.StatusInternalServerError, err, err.Error())
return
}
} else {
commodity.ErpCategory = nil
}
}
if req.IsIMEI == 2 { // 是否串码1-串码类 2-非串码
commodity.IMEIType = 1 // 系统生成串码2-是(系统生成) 3-否(手动添加) 1表示非串码
}
var sysIsIMEI uint32
switch catCommodity.IMEIType {
case 1:
sysIsIMEI = 2 // 非串码
case 2:
fallthrough
case 3:
sysIsIMEI = 1 // 串码
}
if req.IsIMEI != sysIsIMEI {
// 查询是否有库存
var count int64
err = orm.Eloquent.Table("erp_stock_commodity").Where("erp_commodity_id = ? and state = ?",
commodity.ID, models.InStock).Count(&count).Error
if err != nil {
app.Error(c, http.StatusInternalServerError, err, "获取商品库存信息失败")
return
}
if count > 0 {
app.Error(c, http.StatusInternalServerError, err, "该商品已有库存,不能修改串码/非串码选项")
return
}
}
begin := orm.Eloquent.Begin()
err = begin.Save(commodity).Error
if err != nil {
logger.Error("create commodity err:", logger.Field("err", err))
app.Error(c, http.StatusInternalServerError, err, "操作失败")
return
}
// 同步更新库存表和库存商品表的"指导零售价"和"最低零售价"、"分类id"、"分类名称"、"商品编号";库存商品表的"商品条码"
err = models.UpdateErpStockAmountInfo(begin, req, barCode, commodity.SerialNumber, commodity.ErpCategory)
if err != nil {
begin.Rollback()
logger.Error("UpdateErpStockAmountInfo err:", logger.Field("err", err))
app.Error(c, http.StatusInternalServerError, err, "操作失败")
return
}
err = begin.Commit().Error
if err != nil {
begin.Rollback()
logger.Error("commit err:", logger.Field("err", err))
app.Error(c, http.StatusInternalServerError, err, "操作失败")
return
}
app.OK(c, commodity, "")
return
}
// CommodityDel 删除商品
// @Summary 删除商品
// @Tags 商品资料
// @Produce json
// @Accept json
// @Param request body models.CommodityDelRequest true "删除商品模型"
// @Success 200 {object} app.Response
// @Router /api/v1/commodity/delete [post]
func CommodityDel(c *gin.Context) {
var req = new(models.CommodityDelRequest)
if err := c.ShouldBindJSON(&req); err != nil {
//logger.Error(err)
app.Error(c, http.StatusBadRequest, errors.New("para err"), "参数错误")
return
}
// 检查商品是否存在
if !models.IsExistingCommodity(req.ErpCommodityId) {
app.Error(c, http.StatusInternalServerError, errors.New("该商品不存在"), "该商品不存在")
return
}
// 删除商品之前需要判断该商品是否有库存
if models.CheckCommodityIsHavaStock(req.ErpCommodityId) {
app.Error(c, http.StatusInternalServerError, errors.New("该商品有库存不可删除"), "该商品有库存不可删除")
return
}
err := orm.Eloquent.Table("erp_commodity").Where("id=?", req.ErpCommodityId).Delete(&models.ErpCommodity{}).Error
if err != nil {
//logger.Error("erp commodity err:", err)
app.Error(c, http.StatusInternalServerError, err, "获取失败")
return
}
app.OK(c, nil, "删除成功")
return
}
// CommodityImportView 导入商品资料预览
// @Summary 导入商品资料预览
// @Tags 商品资料
// @Produce json
// @Accept json
// @Param file body string true "上传excel文件"
// @Success 200 {array} models.CommodityExcel
// @Router /api/v1/commodity/import_commodity_view [post]
func CommodityImportView(c *gin.Context) {
file, header, err := c.Request.FormFile("file")
if err != nil {
//logger.Error("form file err:", err)
app.Error(c, http.StatusInternalServerError, err, "预览失败")
return
}
readAll, err := io.ReadAll(file)
if err != nil {
//logger.Error("read all err:", err)
app.Error(c, http.StatusInternalServerError, err, "预览失败")
return
}
fmt.Println("header:", header.Filename)
_, colsMap, err := models.FileExcelReader([]byte(readAll), nil)
if err != nil {
//logger.Error("file excel reader err:", err)
app.Error(c, http.StatusInternalServerError, err, "预览失败")
return
}
fmt.Println("colsMap:", colsMap)
if len(colsMap) != 0 {
colsMap = colsMap[1:]
}
app.OK(c, &colsMap, "")
return
}
// CommodityImport 导入商品资料
// @Summary 导入商品资料
// @Tags 商品资料
// @Produce json
// @Accept json
// @Param file body string true "上传excel文件"
// @Success 200 {object} app.Response
// @Router /api/v1/commodity/import_commodity [post]
func CommodityImport(c *gin.Context) {
file, header, err := c.Request.FormFile("file")
if err != nil {
//logger.Error("form file err:", err)
app.Error(c, http.StatusInternalServerError, err, "预览失败")
return
}
readAll, err := io.ReadAll(file)
if err != nil {
//logger.Error("read all err:", err)
app.Error(c, http.StatusInternalServerError, err, "预览失败")
return
}
fmt.Println("header:", header.Filename)
_, colsMap, err := models.FileExcelImport([]byte(readAll), nil, 2)
if err != nil {
//logger.Error("file excel reader err:", err)
app.Error(c, http.StatusInternalServerError, err, err.Error())
return
}
fmt.Println("colsMap:", colsMap)
if len(colsMap) != 0 {
colsMap = colsMap[1:]
}
err = models.ImportCommodityData(colsMap, middleware.GetCooperativeBusinessId(c))
if err != nil {
//logger.Error("file excel reader err:", err)
app.Error(c, http.StatusInternalServerError, err, err.Error())
return
}
app.OK(c, nil, "导入成功")
return
}