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" ) type CommodityCreateRequest struct { Name string `json:"name" binding:"required"` // 商品名称 ErpCategoryId uint32 `json:"erp_category_id" binding:"required"` // 商品分类id IsIMEI uint32 `json:"is_imei" binding:"required"` // 是否串码:1-串码类 2-非串码 ErpBarcode string `json:"erp_barcode"` // 商品条码 IMEIType uint32 `json:"imei_type"` // 系统生成串码:2-是(系统生成) 3-否(手动添加) ErpSupplierId uint32 `json:"erp_supplier_id" binding:"required"` // 主供应商 RetailPrice uint32 `json:"retail_price" binding:"required"` // 指导零售价 MinRetailPrice uint32 `json:"min_retail_price" binding:"required"` // 最低零售价 StaffCostPrice uint32 `json:"staff_cost_price" binding:"required"` // 员工成本价加价 WholesalePrice uint32 `json:"wholesale_price" binding:"required"` // 指导采购价 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)"` // 备注 } // CommodityCreate 新增商品 // @Summary 新增商品 // @Tags 商品资料 // @Produce json // @Accept json // @Param request body CommodityCreateRequest true "商品新增模型" // @Success 200 {object} models.ErpCommodity // @Router /api/v1/commodity/create [post] // 规则:商品名称/商品编号相同则为同一商品,创建的时候由于商品编号不重复,无需判断 func CommodityCreate(c *gin.Context) { var req = new(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, 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 } type CommodityDetailRequest struct { ErpCommodityId uint32 `json:"erp_commodity_id"` // 商品id SerialNumber string `json:"serial_number"` // 商品编号 } // CommodityDetail 商品详情 // @Summary 商品详情 // @Tags 商品资料 // @Produce json // @Accept json // @Param request body CommodityDetailRequest true "商品详情模型" // @Success 200 {object} models.ErpCommodity // @Router /api/v1/commodity/detail [post] func CommodityDetail(c *gin.Context) { var req = new(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 // 串码 } app.OK(c, commodity, "") return } type CommodityEditRequest struct { Id uint32 `json:"id" binding:"required"` // 商品id Name string `json:"name" binding:"required"` // 商品名称 ErpCategoryId uint32 `json:"erp_category_id" binding:"required"` // 商品分类id ErpBarcode string `json:"erp_barcode"` // 商品条码 IMEIType uint32 `json:"imei_type" binding:"required"` // 1-无串码 2-串码(系统生成) 3-串码(手动添加) ErpSupplierId uint32 `json:"erp_supplier_id" binding:"required"` // 主供应商id RetailPrice uint32 `json:"retail_price" binding:"required"` // 指导零售价 MinRetailPrice uint32 `json:"min_retail_price" binding:"required"` // 最低零售价 StaffCostPrice uint32 `json:"staff_cost_price" binding:"required"` // 员工成本价加价 WholesalePrice uint32 `json:"wholesale_price" binding:"required"` // 指导采购价 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)"` // 备注 } // CommodityEdit 编辑商品 // @Summary 编辑商品 // @Tags 商品资料 // @Produce json // @Accept json // @Param request body CommodityEditRequest true "编辑商品模型" // @Success 200 {object} models.ErpCommodity // @Router /api/v1/commodity/edit [post] func CommodityEdit(c *gin.Context) { var req = new(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, 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 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 } // 同步更新库存表和库存商品表的"指导零售价"和"最低零售价";库存商品表的"商品条码" err = models.UpdateErpStockAmountInfo(begin, req.Id, req.RetailPrice, req.MinRetailPrice, barCode) 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 } type CommodityDelRequest struct { ErpCommodityId uint32 `json:"erp_commodity_id" binding:"required"` // 商品id } // CommodityDel 删除商品 // @Summary 删除商品 // @Tags 商品资料 // @Produce json // @Accept json // @Param request body CommodityDelRequest true "删除商品模型" // @Success 200 {object} app.Response // @Router /api/v1/commodity/delete [post] func CommodityDel(c *gin.Context) { var req = new(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 }