mh_goadmin_server/app/admin/apis/basic/commodity.go
chenlin 4124d8862a 1.sys_user表增加uid字段;
2.优化新增/编辑商品资料接口,统一入参,新增商品条码字段;
3.修改库存详情接口,新增扫码字段,添加校验逻辑;
4.新增扫码模糊查询接口;
5.优化新增/编辑零售订单接口;
6.新增查询零售明细接口及excel导出逻辑;
7.新增查询小票数据接口;
8.优化用户登陆接口,内部员工小程序侧可使用erp功能;
2024-01-06 16:48:35 +08:00

442 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/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(err)
app.Error(c, http.StatusBadRequest, errors.New("para err"), "参数错误:"+err.Error())
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
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:", err)
app.Error(c, http.StatusInternalServerError, err, "操作失败")
return
}
commodity.IdInit()
var catCommodity models.ErpCommodity
//err = orm.Eloquent.Table("erp_commodity").Where("erp_category_id=?", req.Id).Limit(1).Find(&catCommodity).Error
err = orm.Eloquent.Table("erp_commodity").Where("id=?", req.Id).Find(&catCommodity).Error
if err != nil {
//logger.Error("cat erp commodity err:", err)
app.Error(c, http.StatusInternalServerError, err, "操作失败")
return
}
commodity.Number = catCommodity.Number
commodity.SerialNumber = catCommodity.SerialNumber
err = orm.Eloquent.Save(commodity).Error
if err != nil {
//logger.Error("create commodity 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
}
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
}