1、商品资料增加"停止采购"按钮;

2、增加查询销售明细接口;
3、零售订单表增加"会员类别"字段;
4、创建零售订单的时候同步记录会员类别;
5、优化经营日报表接口,根据用户权限返回不同的数据;店长和店员看到的销售利润是员工毛利,店员只能看自己的业绩;
This commit is contained in:
chenlin 2024-11-13 15:49:57 +08:00
parent ae5b1a80eb
commit d33ea3a622
10 changed files with 1391 additions and 21 deletions

View File

@ -101,6 +101,7 @@ func CommodityCreate(c *gin.Context) {
Origin: req.Origin,
Remark: req.Remark,
Img: req.Img,
StopPurchase: req.StopPurchase,
}
err = commodity.SetErpCategory()
if err != nil {
@ -265,6 +266,7 @@ func CommodityEdit(c *gin.Context) {
Origin: req.Origin,
Remark: req.Remark,
Img: req.Img,
StopPurchase: req.StopPurchase,
}
commodity.ID = req.Id
err = commodity.SetErpCategory()

View File

@ -623,3 +623,36 @@ func ErpOrderDailyReport(c *gin.Context) {
app.OK(c, resp, "")
return
}
// ErpOrderSaleDetail 查询销售明细
// @Summary 查询销售明细
// @Tags 零售报表
// @Produce json
// @Accept json
// @Param request body models.ErpOrderSaleDetailReq true "查询销售明细数据模型"
// @Success 200 {object} models.ErpOrderRetailDetailResp
// @Router /api/v1/erp_order/sale_detail [post]
func ErpOrderSaleDetail(c *gin.Context) {
var req = new(model.ErpOrderSaleDetailReq)
if err := c.ShouldBindJSON(&req); err != nil {
logger.Error("ShouldBindJSON err:", logger.Field("err", err))
app.Error(c, http.StatusBadRequest, err, "参数错误:"+err.Error())
return
}
err := tools.Validate(req) //必填参数校验
if err != nil {
app.Error(c, http.StatusBadRequest, err, err.Error())
return
}
resp, err := model.QuerySaleDetail(req, c)
if err != nil {
logger.Error("QueryRetailDetail err:", logger.Field("err", err))
app.Error(c, http.StatusInternalServerError, err, "查询失败:"+err.Error())
return
}
app.OK(c, resp, "")
return
}

View File

@ -124,6 +124,7 @@ type ErpCommodity struct {
Remark string `json:"remark" gorm:"type:varchar(512)"` // 备注
StockCount uint32 `json:"stock_count" gorm:"-"` // 库存数量
Img string `json:"img"` // 图片
StopPurchase uint32 `json:"stop_purchase"` // 0-未勾选正常采购1-勾选,停止采购
ErpCategory *ErpCategory `json:"erp_category" gorm:"-"`
}
@ -2070,6 +2071,9 @@ func (m *ErpStockListReq) stockIsEmptyList(c *gin.Context) (*ErpStockListResp, e
var stockList []ErpStock
for _, commodity := range commodities {
if commodity.TotalCount == 0 {
if commodity.StopPurchase == 1 { // 停止采购且没有库存
continue
}
var stock ErpStock
stock.ErpCommodityId = commodity.ID
stock.ErpCommodityName = commodity.Name
@ -2443,6 +2447,10 @@ func (m *ErpStockListReq) allCommodityList(c *gin.Context) (*ErpStockListResp, e
//遍历商品资料,转换为库存列表数据
var stockList []ErpStock
for _, commodity := range commodities {
if commodity.StopPurchase == 1 && commodity.TotalCount == 0 { // 停止采购且没有库存
continue
}
var stock ErpStock
stock.ID = uint32(commodity.ErpStockId)
stock.ErpCommodityId = commodity.ID
@ -3240,6 +3248,7 @@ type CommodityCreateRequest struct {
Origin string `json:"origin"` // 产地
Remark string `json:"remark"` // 备注
Img string `json:"img"` // 图片
StopPurchase uint32 `json:"stop_purchase"` // 0-未勾选正常采购1-勾选,停止采购
}
type CommodityEditRequest struct {
@ -3260,6 +3269,7 @@ type CommodityEditRequest struct {
Origin string `json:"origin"` // 产地
Remark string `json:"remark"` // 备注
Img string `json:"img"` // 图片
StopPurchase uint32 `json:"stop_purchase"` // 0-未勾选正常采购1-勾选,停止采购
}
type CommodityDetailRequest struct {

View File

@ -55,6 +55,7 @@ type ErpOrder struct {
BillSn string `json:"bill_sn" gorm:"index"` // 单据编号
RetailType string `json:"retail_type"` // 销售类型:sale 零售销售; rejected 零售退货
Uid int `json:"uid"` // 用户id
UserType int `json:"user_type"` // 会员类别1-普通会员 2-黄金会员 4-白金会员 5-黑金会员 6-尊享会员 7-黄金&尊享 8-白金&尊享 9-黑金&尊享
Tel string `json:"tel" gorm:"index"` // 客户手机号
StoreId uint32 `json:"store_id" gorm:"index"` // 门店id
StoreName string `json:"store_name"` // 门店名称
@ -5645,6 +5646,11 @@ func CreateErpOrder(req *ErpOrderCreateReq, c *gin.Context) error {
}
}
// 记录用户会员类型
if erpOrder.Uid != 0 {
erpOrder.UserType, _ = GetUserType(erpOrder.Uid)
}
// 1-创建零售订单
err = begin.Create(erpOrder).Error
if err != nil {
@ -6539,7 +6545,9 @@ func QueryOrderDailyReport(req *ErpOrderDailyReportReq, c *gin.Context) (*ErpOrd
if err != nil {
return nil, err
}
if !(tools.GetRoleName(c) == "admin" || tools.GetRoleName(c) == "系统管理员") {
roleName := tools.GetRoleName(c)
if !(roleName == "admin" || roleName == "系统管理员") {
// 返回sysUser未过期的门店id列表
storeList = GetValidStoreIDs(sysUser.StoreData)
} else {
@ -6552,6 +6560,12 @@ func QueryOrderDailyReport(req *ErpOrderDailyReportReq, c *gin.Context) (*ErpOrd
return nil, errors.New("用户未绑定门店")
}
// 判断是否为店长和店员的账户,店长或员工展示员工成本和员工毛利
showFlag := false
if roleName == "store-manager" || roleName == "shopper" {
showFlag = true
}
storeMap, err := GetAllStoreData()
if err != nil {
return nil, err
@ -6559,7 +6573,11 @@ func QueryOrderDailyReport(req *ErpOrderDailyReportReq, c *gin.Context) (*ErpOrd
// 查询所有门店和分类的零售信息
var sumData []RetailDetailSumData
sumData, err = getSumDataByStoreAndCategory(req)
if roleName == "shopper" { //店员只查询自己的业绩
sumData, err = getSalesmanSumDataByStoreAndCategory(req, c)
} else {
sumData, err = getSumDataByStoreAndCategory(req)
}
if err != nil {
return nil, err
}
@ -6574,16 +6592,21 @@ func QueryOrderDailyReport(req *ErpOrderDailyReportReq, c *gin.Context) (*ErpOrd
displayCategories := getDisplayCategories(storeMap[store].Name)
for _, item := range sumData {
nTotalAmount += item.Amount
nTotalSalesProfit += item.SalesProfit
// 仅当门店ID匹配且分类ID在展示分类中时才添加分类数据
if item.StoreId == store && containsCategory(displayCategories, item.ErpCategoryId) {
nTotalAmount += item.Amount
nStoreAmount += item.Amount
nStoreSalesProfit += item.TotalSalesProfit
if showFlag { // 员工毛利
nTotalSalesProfit += item.StaffProfit
nStoreSalesProfit += item.StaffProfit
} else { // 销售毛利
nTotalSalesProfit += item.SalesProfit
nStoreSalesProfit += item.SalesProfit
}
// 处理单个分类数据
categoryData := processCategoryData(item)
categoryData := processCategoryData(item, showFlag)
categoryDataList = append(categoryDataList, categoryData)
}
}
@ -6636,7 +6659,7 @@ func getDisplayCategories(storeName string) []uint32 {
}
// 处理单个分类数据
func processCategoryData(item RetailDetailSumData) CategorySalesData {
func processCategoryData(item RetailDetailSumData, flag bool) CategorySalesData {
var categoryName string
switch item.ErpCategoryId {
case 1:
@ -6651,16 +6674,25 @@ func processCategoryData(item RetailDetailSumData) CategorySalesData {
categoryName = item.ErpCategoryName
}
return CategorySalesData{
CategoryID: item.ErpCategoryId,
CategoryName: item.ErpCategoryName,
SaleTitle: categoryName + "销售金额",
TotalSaleAmount: tools.RoundToTwoDecimalPlaces(item.Amount),
CostTitle: categoryName + "销售成本",
TotalCostAmount: tools.RoundToTwoDecimalPlaces(item.WholesalePrice),
ProfitTitle: categoryName + "销售利润",
TotalProfitAmount: tools.RoundToTwoDecimalPlaces(item.SalesProfit),
var saleData CategorySalesData
saleData.CategoryID = item.ErpCategoryId
saleData.CategoryName = item.ErpCategoryName
saleData.SaleTitle = categoryName + "销售金额"
saleData.TotalSaleAmount = tools.RoundToTwoDecimalPlaces(item.Amount)
if flag { // 店长或员工展示员工成本和员工毛利
saleData.CostTitle = categoryName + "销售成本"
saleData.TotalCostAmount = tools.RoundToTwoDecimalPlaces(item.StaffPrice)
saleData.ProfitTitle = categoryName + "销售利润"
saleData.TotalProfitAmount = tools.RoundToTwoDecimalPlaces(item.StaffProfit)
} else {
saleData.CostTitle = categoryName + "销售成本"
saleData.TotalCostAmount = tools.RoundToTwoDecimalPlaces(item.WholesalePrice)
saleData.ProfitTitle = categoryName + "销售利润"
saleData.TotalProfitAmount = tools.RoundToTwoDecimalPlaces(item.SalesProfit)
}
return saleData
}
// 补充缺失的分类数据
@ -6875,6 +6907,157 @@ func getSumDataByStoreAndCategory(req *ErpOrderDailyReportReq) ([]RetailDetailSu
return finalResult, nil
}
func getSalesmanSumDataByStoreAndCategory(req *ErpOrderDailyReportReq, c *gin.Context) ([]RetailDetailSumData, error) {
var result []RetailDetailSumData
// 解析开始时间
startTimeCondition := ""
if req.StartTime != "" {
parse, err := time.Parse(QueryTimeFormat, req.StartTime)
if err != nil {
logger.Errorf("开始时间解析错误: %v", err)
return result, err
}
startTimeCondition = fmt.Sprintf("AND eo.audit_time > '%s'", parse.Format(QueryTimeFormat))
}
// 解析结束时间
endTimeCondition := ""
if req.EndTime != "" {
parse, err := time.Parse(QueryTimeFormat, req.EndTime)
if err != nil {
logger.Errorf("结束时间解析错误: %v", err)
return result, err
}
endTimeCondition = fmt.Sprintf("AND eo.audit_time < '%s'", parse.Format(QueryTimeFormat))
}
// 销售员条件
salesmanCondition := fmt.Sprintf("AND JSON_CONTAINS(eo.salesman_list, '%s')", fmt.Sprintf(`{"userId":%d}`, tools.GetUserId(c)))
// 获取所有1级分类
firstCategories, err := GetAllFirstCategories()
if err != nil {
logger.Error("获取一级分类错误", logger.Field("err", err))
return result, err
}
// 获取所有一级分类对应的子分类IDs
categorySubIds := make(map[uint32][]uint32)
for _, category := range firstCategories {
subCategoryIDs, err := GetSubcategoryIds(category.ID)
if err != nil {
logger.Error("获取子分类ID错误", logger.Field("err", err), logger.Field("categoryID", category.ID))
return result, err
}
categorySubIds[category.ID] = subCategoryIDs
}
err = orm.Eloquent.Raw(fmt.Sprintf(`
SELECT
retail.store_id,
retail.store_name,
retail.erp_category_id,
retail.erp_category_name,
COALESCE(retail.count, 0) - COALESCE(rejected.count, 0) AS count,
COALESCE(retail.retail_price, 0) - COALESCE(rejected.retail_price, 0) AS retail_price,
COALESCE(retail.sale_price, 0) - COALESCE(rejected.sale_price, 0) AS sale_price,
COALESCE(retail.sale_discount, 0) - COALESCE(rejected.sale_discount, 0) AS sale_discount,
COALESCE(retail.member_discount, 0) - COALESCE(rejected.member_discount, 0) AS member_discount,
COALESCE(retail.amount, 0) - COALESCE(rejected.amount, 0) AS amount,
COALESCE(retail.wholesale_price, 0) - COALESCE(rejected.wholesale_price, 0) AS wholesale_price,
COALESCE(retail.staff_price, 0) - COALESCE(rejected.staff_price, 0) AS staff_price,
COALESCE(retail.sales_profit, 0) - COALESCE(rejected.sales_profit, 0) AS sales_profit,
COALESCE(retail.staff_profit, 0) - COALESCE(rejected.staff_profit, 0) AS staff_profit,
COALESCE(retail.total_amount, 0) - COALESCE(rejected.total_amount, 0) AS total_amount,
COALESCE(retail.total_sales_profit, 0) - COALESCE(rejected.total_sales_profit, 0) AS total_sales_profit,
COALESCE(retail.total_staff_profit, 0) - COALESCE(rejected.total_staff_profit, 0) AS total_staff_profit
FROM (
SELECT eo.store_id, eo.store_name, oc.erp_category_id, oc.erp_category_name,
SUM(oc.count) AS count,
SUM(oc.retail_price) AS retail_price,
SUM(oc.sale_price) AS sale_price,
SUM(oc.sale_discount) AS sale_discount,
SUM(oc.member_discount) AS member_discount,
SUM(oc.amount) AS amount,
SUM(oc.wholesale_price) AS wholesale_price,
(SUM(oc.wholesale_price) + SUM(oc.staff_cost_price)) AS staff_price,
(SUM(oc.amount) - SUM(oc.wholesale_price)) AS sales_profit,
(SUM(oc.amount) - SUM(oc.wholesale_price) - SUM(oc.staff_cost_price)) AS staff_profit,
SUM(eo.total_amount) as total_amount,
SUM(eo.total_sales_profit) as total_sales_profit,
SUM(eo.total_staff_profit) as total_staff_profit
FROM erp_order eo
JOIN erp_order_commodity oc ON eo.id = oc.erp_order_id
WHERE eo.retail_type = ? %s %s %s
GROUP BY eo.store_id, eo.store_name, oc.erp_category_id, oc.erp_category_name
) AS retail
LEFT JOIN (
SELECT eo.store_id, eo.store_name, oc.erp_category_id, oc.erp_category_name,
SUM(oc.count) AS count,
SUM(oc.retail_price) AS retail_price,
SUM(oc.sale_price) AS sale_price,
SUM(oc.sale_discount) AS sale_discount,
SUM(oc.member_discount) AS member_discount,
SUM(oc.rejected_amount) AS amount,
SUM(oc.wholesale_price) AS wholesale_price,
(SUM(oc.wholesale_price) + SUM(oc.staff_cost_price)) AS staff_price,
SUM(oc.sales_profit) AS sales_profit,
SUM(oc.staff_profit) AS staff_profit,
SUM(eo.total_amount) as total_amount,
SUM(eo.total_sales_profit) as total_sales_profit,
SUM(eo.total_staff_profit) as total_staff_profit
FROM erp_order eo
JOIN erp_order_commodity oc ON eo.id = oc.erp_order_id
WHERE eo.retail_type = ? %s %s %s
GROUP BY eo.store_id, eo.store_name, oc.erp_category_id, oc.erp_category_name
) AS rejected ON retail.store_id = rejected.store_id AND retail.erp_category_id = rejected.erp_category_id
`, startTimeCondition, endTimeCondition, salesmanCondition, startTimeCondition, endTimeCondition, salesmanCondition), RetailTypeSale, RetailTypeRejected).Scan(&result).Error
if err != nil {
logger.Error("query data with subtraction err:", logger.Field("err", err))
return result, err
}
// 合并子分类数据根据门店ID和父分类合并并累加金额
mergedResult := make(map[string]RetailDetailSumData)
for i := range result {
for parentID, subCategories := range categorySubIds {
if containsCategory(subCategories, result[i].ErpCategoryId) {
key := fmt.Sprintf("%d-%d", result[i].StoreId, parentID)
if existing, exists := mergedResult[key]; exists {
existing.Count += result[i].Count
existing.RetailPrice += result[i].RetailPrice
existing.SalePrice += result[i].SalePrice
existing.SaleDiscount += result[i].SaleDiscount
existing.MemberDiscount += result[i].MemberDiscount
existing.Amount += result[i].Amount
existing.WholesalePrice += result[i].WholesalePrice
existing.StaffPrice += result[i].StaffPrice
existing.SalesProfit += result[i].SalesProfit
existing.StaffProfit += result[i].StaffProfit
mergedResult[key] = existing
} else {
result[i].ErpCategoryId = parentID
//result[i].ErpCategoryName = getCategoryNameByCategoryID(parentID)
mergedResult[key] = result[i]
}
break
}
}
}
// 转换合并结果为切片
finalResult := make([]RetailDetailSumData, 0, len(mergedResult))
for _, v := range mergedResult {
finalResult = append(finalResult, v)
}
return finalResult, nil
}
// containsCategory 检查分类ID是否在子分类IDs列表中
func containsCategory(subCategoryIds []uint32, categoryId uint32) bool {
for _, id := range subCategoryIds {
@ -6894,3 +7077,716 @@ func containsCategorySalesData(categoryDataList []CategorySalesData, categoryId
}
return false
}
// ErpOrderSaleDetailReq 销售明细汇总入参
type ErpOrderSaleDetailReq struct {
BillSn string `json:"bill_sn"` // 单据编号
RetailType string `json:"retail_type"` // 销售类型sale 零售销售; rejected 零售退货
UserType []uint32 `json:"user_type"` // 会员类别0-未注册 1-普通会员 2-黄金会员 4-白金会员 5-黑金会员 6-尊享会员 7-黄金&尊享 8-白金&尊享 9-黑金&尊享
Uid int `json:"uid"` // 用户ID
Tel string `json:"tel"` // 客户手机号
StoreId uint32 `json:"store_id"` // 门店ID
ErpCategoryId []uint32 `json:"erp_category_id"` // 分类id
ErpCommodityName string `json:"erp_commodity_name"` // 商品名称
Salesman uint32 `json:"salesman"` // 销售人员ID
IMEI string `json:"imei"` // 串码
StartTime string `json:"start_time"` // 开始时间
EndTime string `json:"end_time"` // 结束时间
BankTrxNo string `json:"bank_trx_no"` // 银联流水号
PageIndex int `json:"pageIndex"` // 页码
PageSize int `json:"pageSize"` // 页面条数
IsExport uint32 `json:"is_export"` // 1-导出
}
// QuerySaleDetail 查询销售明细
func QuerySaleDetail(req *ErpOrderSaleDetailReq, c *gin.Context) (*ErpOrderRetailDetailResp, error) {
resp := &ErpOrderRetailDetailResp{}
// 通过银行流水号查询
if req.BankTrxNo != "" {
var orderPayWay ErpOrderRecord
err := orm.Eloquent.Table("erp_order_record").Where("bank_trx_no = ? and status = ?",
req.BankTrxNo, PayOk).Find(&orderPayWay).Error
if err != nil {
logger.Error("query erp_order_record err:", logger.Field("err", err))
return nil, err
}
req.BillSn = orderPayWay.BillSn
}
var err error
if (len(req.ErpCategoryId) != 0 || req.ErpCommodityName != "" || req.IMEI != "") && req.BillSn == "" { // 商品分类or商品名称不为空且订单编号为空
// 联表查询
resp, err = querySaleDetailByJoin(req, c)
} else {
// 普通单表查询,然后补充收款数据和商品数据
resp, err = querySaleDetailCommon(req, c)
}
if err != nil {
logger.Error("queryRetailDetailCommon err")
return nil, err
}
return resp, nil
}
// 联表查询
func querySaleDetailByJoin(req *ErpOrderSaleDetailReq, c *gin.Context) (*ErpOrderRetailDetailResp, error) {
showConfig, err := GetErpOrderShowConfig()
if err != nil {
logger.Errorf("List err:", err)
showConfig.ShowAll = "ON"
}
page := req.PageIndex - 1
if page < 0 {
page = 0
}
if req.PageSize == 0 {
req.PageSize = 10
}
resp := &ErpOrderRetailDetailResp{
PageIndex: page + 1,
PageSize: req.PageSize,
}
qs := orm.Eloquent.Debug().Table("erp_order_commodity").
Select("erp_order_commodity.*, erp_order.*").
Joins("JOIN erp_order ON erp_order_commodity.erp_order_id = erp_order.id")
es := orm.Eloquent.Debug().Table("erp_order_commodity").
Select("erp_order_commodity.*, erp_order.*").
Joins("JOIN erp_order ON erp_order_commodity.erp_order_id = erp_order.id")
orderSumQs := orm.Eloquent.Table("erp_order_commodity AS oc").Select("oc.*, eo.*").
Joins("JOIN erp_order AS eo ON oc.erp_order_id = eo.id")
rejectedOrderSumQs := orm.Eloquent.Table("erp_order_commodity AS oc").Select("oc.*, eo.*").
Joins("JOIN erp_order AS eo ON oc.erp_order_id = eo.id")
if len(req.ErpCategoryId) != 0 { // 商品分类
categoryList, err := TransformErpCategoryIds(req.ErpCategoryId)
if err != nil {
return nil, err
}
qs = qs.Where("erp_order_commodity.erp_category_id in ?", categoryList)
es = es.Where("erp_order_commodity.erp_category_id in ?", categoryList)
orderSumQs = orderSumQs.Where("oc.erp_category_id in ?", categoryList)
rejectedOrderSumQs = rejectedOrderSumQs.Where("oc.erp_category_id in ?", categoryList)
}
if req.ErpCommodityName != "" { // 商品名称
qs = qs.Where("erp_order_commodity.erp_commodity_name = ?", req.ErpCommodityName)
es = es.Where("erp_order_commodity.erp_commodity_name = ?", req.ErpCommodityName)
orderSumQs = orderSumQs.Where("oc.erp_commodity_name = ?", req.ErpCommodityName)
rejectedOrderSumQs = rejectedOrderSumQs.Where("oc.erp_commodity_name = ?", req.ErpCommodityName)
}
if req.RetailType != "" { // 销售类型
qs = qs.Where("erp_order.retail_type=?", req.RetailType)
es = es.Where("erp_order.retail_type=?", req.RetailType)
orderSumQs = orderSumQs.Where("eo.retail_type=?", req.RetailType)
rejectedOrderSumQs = rejectedOrderSumQs.Where("eo.retail_type=?", req.RetailType)
}
if req.Uid != 0 { // 用户ID
qs = qs.Where("erp_order.uid=?", req.Uid)
es = es.Where("erp_order.uid=?", req.Uid)
orderSumQs = orderSumQs.Where("eo.uid=?", req.Uid)
rejectedOrderSumQs = rejectedOrderSumQs.Where("eo.uid=?", req.Uid)
}
if len(req.UserType) != 0 { // 会员类别
qs = qs.Where("user_type in ?", req.UserType)
es = es.Where("user_type in ?", req.UserType)
orderSumQs = orderSumQs.Where("user_type in ?", req.UserType)
rejectedOrderSumQs = rejectedOrderSumQs.Where("user_type in ?", req.UserType)
}
if req.Tel != "" { // 用户手机号
qs = qs.Where("erp_order.tel=?", req.Tel)
es = es.Where("erp_order.tel=?", req.Tel)
orderSumQs = orderSumQs.Where("eo.tel=?", req.Tel)
rejectedOrderSumQs = rejectedOrderSumQs.Where("eo.tel=?", req.Tel)
}
if req.StoreId != 0 { // 门店ID
qs = qs.Where("erp_order.store_id=?", req.StoreId)
es = es.Where("erp_order.store_id=?", req.StoreId)
orderSumQs = orderSumQs.Where("eo.store_id=?", req.StoreId)
rejectedOrderSumQs = rejectedOrderSumQs.Where("eo.store_id=?", req.StoreId)
}
if req.IMEI != "" { // 串码
qs = qs.Where("erp_order_commodity.imei=?", req.IMEI)
es = es.Where("erp_order_commodity.imei=?", req.IMEI)
orderSumQs = orderSumQs.Where("oc.imei=?", req.IMEI)
rejectedOrderSumQs = rejectedOrderSumQs.Where("oc.imei=?", req.IMEI)
}
// 非管理员才判断所属门店
if !(tools.GetRoleName(c) == "admin" || tools.GetRoleName(c) == "系统管理员") {
sysUser, err := GetSysUserByCtx(c)
if err != nil {
return nil, errors.New("操作失败:" + err.Error())
}
// 返回sysUser未过期的门店id列表
storeList := GetValidStoreIDs(sysUser.StoreData)
if len(storeList) > 0 {
if len(storeList) == 1 {
qs = qs.Where("erp_order.store_id = ?", storeList[0])
es = es.Where("erp_order.store_id = ?", storeList[0])
orderSumQs = orderSumQs.Where("eo.store_id = ?", storeList[0])
rejectedOrderSumQs = rejectedOrderSumQs.Where("eo.store_id = ?", storeList[0])
} else {
qs = qs.Where("erp_order.store_id IN (?)", storeList)
es = es.Where("erp_order.store_id IN (?)", storeList)
orderSumQs = orderSumQs.Where("eo.store_id IN (?)", storeList)
rejectedOrderSumQs = rejectedOrderSumQs.Where("eo.store_id IN (?)", storeList)
}
} else {
return nil, errors.New("用户未绑定门店")
}
}
if req.Salesman != 0 { // 销售员
qs = qs.Where("JSON_CONTAINS(erp_order.salesman_list, ?)", fmt.Sprintf(`{"userId":%d}`, req.Salesman))
es = es.Where("JSON_CONTAINS(erp_order.salesman_list, ?)", fmt.Sprintf(`{"userId":%d}`, req.Salesman))
orderSumQs = orderSumQs.Where("JSON_CONTAINS(eo.salesman_list, ?)", fmt.Sprintf(`{"userId":%d}`, req.Salesman))
rejectedOrderSumQs = rejectedOrderSumQs.Where("JSON_CONTAINS(eo.salesman_list, ?)", fmt.Sprintf(`{"userId":%d}`, req.Salesman))
}
if req.StartTime != "" { // 审核开始时间
parse, err := time.Parse(QueryTimeFormat, req.StartTime)
if err != nil {
logger.Errorf("err:", err)
}
qs = qs.Where("erp_order.audit_time > ?", parse)
es = es.Where("erp_order.audit_time > ?", parse)
orderSumQs = orderSumQs.Where("eo.audit_time > ?", parse)
rejectedOrderSumQs = rejectedOrderSumQs.Where("eo.audit_time > ?", parse)
}
if req.EndTime != "" { // 审核结束时间
parse, err := time.Parse(QueryTimeFormat, req.EndTime)
if err != nil {
logger.Errorf("err:", err)
}
//parse = parse.AddDate(0, 0, 1)
qs = qs.Where("erp_order.audit_time < ?", parse)
es = es.Where("erp_order.audit_time < ?", parse)
orderSumQs = orderSumQs.Where("eo.audit_time < ?", parse)
rejectedOrderSumQs = rejectedOrderSumQs.Where("eo.audit_time < ?", parse)
}
if showConfig.ShowAll == "OFF" {
qs = qs.Where("erp_order.is_print = ? or erp_order.retail_type = ?", HavePrinted, RetailTypeRejected)
es = es.Where("erp_order.is_print = ? or erp_order.retail_type = ?", HavePrinted, RetailTypeRejected)
orderSumQs = orderSumQs.Where("eo.is_print = ? or eo.retail_type = ?", HavePrinted, RetailTypeRejected)
rejectedOrderSumQs = rejectedOrderSumQs.Where("eo.is_print = ? or eo.retail_type = ?", HavePrinted, RetailTypeRejected)
}
qs.Where("erp_order.pay_status = ? or (erp_order.retail_type = ? and erp_order.state != ?)",
HavePaid, RetailTypeRejected, ErpOrderStateUnAudit)
es.Where("erp_order.pay_status = ? or (erp_order.retail_type = ? and erp_order.state != ?)",
HavePaid, RetailTypeRejected, ErpOrderStateUnAudit)
orderSumQs.Where("eo.pay_status = ? or (eo.retail_type = ? and eo.state != ?)",
HavePaid, RetailTypeRejected, ErpOrderStateUnAudit)
rejectedOrderSumQs.Where("eo.pay_status = ? or (eo.retail_type = ? and eo.state != ?)",
HavePaid, RetailTypeRejected, ErpOrderStateUnAudit)
// 销售订单的汇总数据
var sumData RetailDetailTotalData
sumData, err = getRetailDetailTotalDataJoinErpOrderSale(orderSumQs, RetailTypeSale)
if err != nil {
logger.Error("query sum data err:", logger.Field("err", err))
return resp, err
}
// 退货订单的汇总数据
var rejectedSumData RetailDetailTotalData
rejectedSumData, err = getRetailDetailTotalDataJoinErpOrderRejected(rejectedOrderSumQs, RetailTypeRejected)
if err != nil {
logger.Error("query sum data err:", logger.Field("err", err))
return resp, err
}
// 计算销售订单和退货订单汇总后的销售数据
sumData = subtractRetailData(sumData, rejectedSumData)
// 销售订单提成汇总
var totalPerData TotalPerData
totalPerQs := qs
totalPerData, err = getTotalPerData(totalPerQs, RetailTypeSale)
if err != nil {
logger.Error("query erp_order_sales sum data err:", logger.Field("err", err))
return resp, err
}
// 退货订单提成汇总
var rejectedTotalPerData TotalPerData
rejectedTotalPerQs := qs
rejectedTotalPerData, err = getTotalPerData(rejectedTotalPerQs, RetailTypeRejected)
if err != nil {
logger.Error("query erp_order_sales sum data err:", logger.Field("err", err))
return resp, err
}
// 计算销售订单和退货订单汇总后的提成数据
totalPerData = subtractTotalPerData(totalPerData, rejectedTotalPerData)
// 处理汇总数据四舍五入保留2位小数
saleDetailRoundValues(&sumData, &totalPerData)
sumData.TotalSalesProfit = 0 // 订单总销售毛利
sumData.TotalStaffProfit = 0 // 订单总员工毛利
sumData.TotalRetailPrice = 0 // 订单总指导零售价
sumData.TotalDiscount = 0 // 订单总优惠
sumData.TotalAmount = 0 // 订单实收金额
sumData.StorePer = 0 // 门店提成
sumData.ScanAmount = 0
sumData.CashAmount = 0
sumData.PosAmount = 0
sumData.StoreVmAmount = 0
sumData.OtherAmount = 0
RoundRetailDetailTotalData(&sumData)
var result []RetailDetailByJoin
if req.IsExport == 1 { //导出excel
err = qs.Order("erp_order.audit_time DESC").Find(&result).Error
if err != nil && err != RecordNotFound {
logger.Error("erp commodity list err:", logger.Field("err", err))
return resp, err
}
var count int64
err = es.Count(&count).Error
if err != nil {
logger.Errorf("QueryRetailMargin count err:", err.Error())
return nil, err
}
orders := packData(result)
erpOrderSetBankTrxNo(orders)
fileUrl, err := saleDetailExport(orders, sumData, c)
if err != nil {
logger.Error("retailDetailExport err:", logger.Field("err", err))
return resp, err
}
resp.ExportUrl = fileUrl
} else {
//err = qs.Order("erp_order.audit_time DESC").Offset(page * req.PageSize).Limit(req.PageSize).Find(&result).Error
err = qs.Order("erp_order.audit_time DESC").Find(&result).Error
if err != nil && err != RecordNotFound {
logger.Error("erp commodity list err:", logger.Field("err", err))
return resp, err
}
var count int64
err = es.Count(&count).Error
if err != nil {
logger.Errorf("QueryRetailMargin count err:", err.Error())
return nil, err
}
orders := packData(result)
erpOrderListSetSalesman(orders)
erpOrderSetBankTrxNo(orders)
pagedOrders := paginate(orders, page, req.PageSize)
resp.List = pagedOrders
//跟之前保持一致
resp.Total = len(orders)
resp.PageIndex = page + 1
resp.PageSize = req.PageSize
resp.SumData = sumData
}
return resp, nil
}
// 普通单表查询,然后补充收款数据和商品数据
func querySaleDetailCommon(req *ErpOrderSaleDetailReq, c *gin.Context) (*ErpOrderRetailDetailResp, error) {
showConfig, err := GetErpOrderShowConfig()
if err != nil {
logger.Errorf("List err:", err)
showConfig.ShowAll = "ON"
}
page := req.PageIndex - 1
if page < 0 {
page = 0
}
if req.PageSize == 0 {
req.PageSize = 10
}
resp := &ErpOrderRetailDetailResp{
PageIndex: page + 1,
PageSize: req.PageSize,
}
qs := orm.Eloquent.Table("erp_order")
totalPerQs := orm.Eloquent.Table("erp_order")
if showConfig.ShowAll == "OFF" {
qs = qs.Where("is_print = ? or retail_type = ?", HavePrinted, RetailTypeRejected)
totalPerQs = totalPerQs.Where("is_print = ? or retail_type = ?", HavePrinted, RetailTypeRejected)
}
if req.BillSn != "" { // 订单编号
qs = qs.Where("bill_sn=?", req.BillSn)
totalPerQs = totalPerQs.Where("bill_sn=?", req.BillSn)
} else {
if req.RetailType != "" { // 销售类型
qs = qs.Where("retail_type=?", req.RetailType)
totalPerQs = totalPerQs.Where("retail_type=?", req.RetailType)
}
if req.Uid != 0 { // 用户ID
qs = qs.Where("erp_order.uid=?", req.Uid)
totalPerQs = totalPerQs.Where("erp_order.uid=?", req.Uid)
}
if req.Tel != "" { // 用户手机号
qs = qs.Where("tel=?", req.Tel)
totalPerQs = totalPerQs.Where("tel=?", req.Tel)
}
if req.StoreId != 0 { // 门店ID
qs = qs.Where("store_id=?", req.StoreId)
totalPerQs = totalPerQs.Where("store_id=?", req.StoreId)
}
// 非管理员才判断所属门店
if !(tools.GetRoleName(c) == "admin" || tools.GetRoleName(c) == "系统管理员") {
sysUser, err := GetSysUserByCtx(c)
if err != nil {
return nil, errors.New("操作失败:" + err.Error())
}
// 返回sysUser未过期的门店id列表
storeList := GetValidStoreIDs(sysUser.StoreData)
if len(storeList) > 0 {
if len(storeList) == 1 {
qs = qs.Where("store_id = ?", storeList[0])
totalPerQs = totalPerQs.Where("store_id = ?", storeList[0])
} else {
qs = qs.Where("store_id IN (?)", storeList)
totalPerQs = totalPerQs.Where("store_id IN (?)", storeList)
}
} else {
return nil, errors.New("用户未绑定门店")
}
}
if req.Salesman != 0 { // 销售员
qs = qs.Where("JSON_CONTAINS(salesman_list, ?)", fmt.Sprintf(`{"userId":%d}`, req.Salesman))
totalPerQs = totalPerQs.Where("erp_order_sales.uid = ?", req.Salesman)
}
if req.StartTime != "" { // 审核开始时间
parse, err := time.Parse(QueryTimeFormat, req.StartTime)
if err != nil {
logger.Errorf("err:", err)
}
qs = qs.Where("audit_time > ?", parse)
totalPerQs = totalPerQs.Where("audit_time > ?", parse)
}
if req.EndTime != "" { // 审核结束时间
parse, err := time.Parse(QueryTimeFormat, req.EndTime)
if err != nil {
logger.Errorf("err:", err)
}
//parse = parse.AddDate(0, 0, 1)
qs = qs.Where("audit_time < ?", parse)
totalPerQs = totalPerQs.Where("audit_time < ?", parse)
}
if len(req.UserType) != 0 {
qs = qs.Where("user_type in ?", req.UserType)
totalPerQs = totalPerQs.Where("user_type in ?", req.UserType)
}
}
qs.Where("erp_order.pay_status = ? or (erp_order.retail_type = ? and erp_order.state != ?)",
HavePaid, RetailTypeRejected, ErpOrderStateUnAudit)
totalPerQs.Where("erp_order.pay_status = ? or (erp_order.retail_type = ? and erp_order.state != ?)",
HavePaid, RetailTypeRejected, ErpOrderStateUnAudit)
es := qs
rejectedTotalPerQs := totalPerQs
// 销售订单的汇总数据
orderSumQs := qs
var sumData RetailDetailTotalData
sumData, err = getRetailDetailTotalDataSale(orderSumQs, RetailTypeSale)
if err != nil {
logger.Error("query sum data err:", logger.Field("err", err))
return resp, err
}
// 退货订单的汇总数据
var rejectedSumData RetailDetailTotalData
rejectedOrderSumQs := qs
rejectedSumData, err = getRetailDetailTotalDataRejected(rejectedOrderSumQs, RetailTypeRejected)
if err != nil {
logger.Error("query sum data err:", logger.Field("err", err))
return resp, err
}
// 计算销售订单和退货订单汇总后的销售数据
sumData = subtractRetailData(sumData, rejectedSumData)
// 销售订单提成汇总
var totalPerData TotalPerData
totalPerData, err = getTotalPerData(totalPerQs, RetailTypeSale)
if err != nil {
logger.Error("query erp_order_sales sum data err:", logger.Field("err", err))
return resp, err
}
// 退货订单提成汇总
var rejectedTotalPerData TotalPerData
rejectedTotalPerData, err = getTotalPerData(rejectedTotalPerQs, RetailTypeRejected)
if err != nil {
logger.Error("query erp_order_sales sum data err:", logger.Field("err", err))
return resp, err
}
// 计算销售订单和退货订单汇总后的提成数据
totalPerData = subtractTotalPerData(totalPerData, rejectedTotalPerData)
// 处理汇总数据四舍五入保留2位小数
saleDetailRoundValues(&sumData, &totalPerData)
sumData.TotalSalesProfitPer = totalPerData.TotalSalesProfitPer
sumData.TotalStaffProfitPer = totalPerData.TotalStaffProfitPer
sumData.SalesmanPer = totalPerData.SalesmanPer
RoundRetailDetailTotalData(&sumData)
if req.IsExport == 1 { // 导出excel
var orders []ErpOrder
err = qs.Order("audit_time DESC").Find(&orders).Error
if err != nil && err != RecordNotFound {
logger.Error("erp commodity list err:", logger.Field("err", err))
return resp, err
}
// 进行批量处理
var wg sync.WaitGroup
wg.Add(2)
go func() {
defer wg.Done()
ErpOrderRetailDetailSetCommodityAI(orders) // 商品信息处理
}()
go func() {
defer wg.Done()
erpOrderSetBankTrxNoAI(orders) // 银行交易号处理
}()
wg.Wait() // 等待所有处理完成
fileUrl, err := saleDetailExport(orders, sumData, c)
if err != nil {
logger.Error("retailDetailExport err:", logger.Field("err", err))
return resp, err
}
resp.ExportUrl = fileUrl
} else {
var count int64
err = es.Count(&count).Error
if err != nil {
logger.Error("count err:", logger.Field("err", err))
return resp, err
}
var orders []ErpOrder
err = qs.Order("audit_time DESC").Offset(page * req.PageSize).Limit(req.PageSize).Find(&orders).Error
if err != nil && err != RecordNotFound {
logger.Error("erp commodity list err:", logger.Field("err", err))
return resp, err
}
// 添加付款、销售员、商品信息
ErpOrderRetailDetailSetCommodity(orders)
erpOrderListSetSalesman(orders)
erpOrderSetBankTrxNo(orders)
resp.List = orders
//跟之前保持一致
resp.Total = int(count)
resp.PageIndex = page + 1
resp.PageSize = req.PageSize
resp.SumData = sumData
}
return resp, nil
}
// 四舍五入保留2位小数
func saleDetailRoundValues(data *RetailDetailTotalData, totalPerData *TotalPerData) {
roundMap := map[*float64]*float64{
&data.StorePer: &data.StorePer,
&totalPerData.TotalSalesProfitPer: &totalPerData.TotalSalesProfitPer,
&totalPerData.TotalStaffProfitPer: &totalPerData.TotalStaffProfitPer,
&totalPerData.SalesmanPer: &totalPerData.SalesmanPer,
}
for original, rounded := range roundMap {
*rounded = tools.RoundToTwoDecimalPlaces(*original)
}
}
// 导出销售明细报表excel
func saleDetailExport(list []ErpOrder, sumData RetailDetailTotalData, c *gin.Context) (string, error) {
file := excelize.NewFile()
fSheet := "Sheet1"
url := config.ExportConfig.Url
fileName := time.Now().Format(TimeFormat) + "销售明细" + ".xlsx"
fmt.Println("url fileName:", url+fileName)
title := []interface{}{"订单编号", "订单类型", "店铺", "会员类别", "用户ID", "日期", "审核时间", "销售员1", "销售员2",
"一级分类", "二级分类", "三级分类", "商品名称", "供应商", "商品串码", "是否赠送", "销售数量", "指导价", "零售价", "零售优惠",
"会员优惠", "销售金额", "采购单价", "员工成本", "销售毛利", "员工毛利", "银联流水", "联系电话", "备注"}
for i, _ := range title {
cell, _ := excelize.CoordinatesToCellName(1+i, 1)
err := file.SetCellValue(fSheet, cell, title[i])
if err != nil {
logger.Error("file set value err:", logger.Field("err", err))
}
}
categoryMap, err := GetAllCategories()
if err != nil {
// 处理错误
logger.Error("GetAllCategories err:", logger.Field("err", err))
}
var row []interface{}
nAmount := 0.0
nExcelStartRow := 0
for i := 0; i < len(list); i++ {
var saleType string
if list[i].RetailType == RetailTypeSale {
saleType = "零售销售"
} else if list[i].RetailType == RetailTypeRejected {
saleType = "零售退货"
} else {
logger.Error("订单类型异常")
return "", errors.New("RetailMarginDataExport, 订单类型异常:" + list[i].RetailType)
}
var salesMan1, salesMan2 string
// 先判断商品数量,确定要写几行数据
for rowId := 0; rowId < len(list[i].Commodities); rowId++ {
if list[i].RetailType == RetailTypeSale {
nAmount = list[i].Commodities[rowId].Amount
} else if list[i].RetailType == RetailTypeRejected {
nAmount = list[i].Commodities[rowId].RejectedAmount
list[i].CashierList = "" // 目前零售退货订单暂时不展示各个方式的付款金额
}
// 用户id会员类别
var userId, userType string
if list[i].Uid != 0 {
userId = strconv.Itoa(list[i].Uid)
userType = GetUserTypeString(list[i].UserType)
} else {
userId = ""
}
// 审核时间
var auditTime, auditDate string
if list[i].AuditTime != nil {
auditTime = list[i].AuditTime.Format(ExcelTimeFormat)
auditDate = list[i].AuditTime.Format(DateTimeFormat) // Extract date only
} else {
auditTime = ""
auditDate = ""
}
// 商品分类
categoryID := list[i].Commodities[rowId].ErpCategoryId
categoryLevels := GetCategoryLevelsFromMap(categoryID, categoryMap)
// 是否赠送
strPresentType := "非赠送"
if list[i].Commodities[rowId].PresentType == 2 {
strPresentType = "赠送"
}
if len(list[i].Salesman) > 0 {
salesMan1 = list[i].Salesman[0].Name
if len(list[i].Salesman) == 2 {
salesMan2 = list[i].Salesman[1].Name
}
}
row = []interface{}{
list[i].BillSn, // 订单编号
saleType, // 订单类型
list[i].StoreName, // 店铺
userType, // 会员类别
userId, // 用户ID
auditDate, // 日期
auditTime, // 审核时间
salesMan1, // 销售员1
salesMan2, // 销售员2
categoryLevels.Level1.Name, // 一级分类
categoryLevels.Level2.Name, // 二级分类
categoryLevels.Level3.Name, // 三级分类
list[i].Commodities[rowId].ErpCommodityName, // 商品名称
list[i].Commodities[rowId].ErpSupplierName, // 供应商
list[i].Commodities[rowId].IMEI, // 商品串码
strPresentType, // 是否赠送
list[i].Commodities[rowId].Count, // 销售数量
list[i].Commodities[rowId].RetailPrice, // 指导价
list[i].Commodities[rowId].SalePrice, // 零售价
list[i].Commodities[rowId].SaleDiscount, // 零售优惠
list[i].Commodities[rowId].MemberDiscount, // 会员优惠
nAmount, // 销售金额
list[i].Commodities[rowId].WholesalePrice, // 采购单价
list[i].Commodities[rowId].WholesalePrice + list[i].Commodities[rowId].StaffCostPrice, // 员工成本
list[i].Commodities[rowId].SalesProfit, // 销售毛利
list[i].Commodities[rowId].StaffProfit, // 员工毛利
list[i].BankTrxNo, // 银联流水
list[i].Tel, // 联系电话
list[i].Commodities[rowId].Remark, // 备注
}
for j, _ := range row {
cell, _ := excelize.CoordinatesToCellName(1+j, nExcelStartRow+2)
err = file.SetCellValue(fSheet, cell, row[j])
if err != nil {
logger.Error("file set value err:", logger.Field("err", err))
}
}
nExcelStartRow++
}
}
totalData := "订单数:" + strconv.FormatInt(int64(len(list)), 10)
end := []interface{}{totalData, "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
sumData.Count,
sumData.RetailPrice,
sumData.SalePrice,
sumData.SaleDiscount,
sumData.MemberDiscount,
sumData.Amount,
"",
}
for i, _ := range end {
cell, _ := excelize.CoordinatesToCellName(1+i, nExcelStartRow+2)
err := file.SetCellValue(fSheet, cell, end[i])
if err != nil {
logger.Error("file set value err:", logger.Field("err", err))
}
}
// 设置所有单元格的样式: 居中、加边框
style, _ := file.NewStyle(`{"alignment":{"horizontal":"center","vertical":"center"},
"border":[{"type":"left","color":"000000","style":1},
{"type":"top","color":"000000","style":1},
{"type":"right","color":"000000","style":1},
{"type":"bottom","color":"000000","style":1}]}`)
endRow := fmt.Sprintf("AC"+"%d", nExcelStartRow+2)
// 应用样式到整个表格
_ = file.SetCellStyle("Sheet1", "A1", endRow, style)
// 设置单元格大小
file.SetColWidth("Sheet1", "A", "A", 15)
file.SetColWidth("Sheet1", "C", "C", 25)
file.SetColWidth("Sheet1", "D", "D", 19)
file.SetColWidth("Sheet1", "F", "F", 15)
file.SetColWidth("Sheet1", "G", "G", 19)
file.SetColWidth("Sheet1", "M", "M", 25)
file.SetColWidth("Sheet1", "O", "O", 18)
file.SetColWidth("Sheet1", "AA", "AA", 30)
file.SetColWidth("Sheet1", "AB", "AB", 15)
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
}

View File

@ -1954,7 +1954,7 @@ func getErpPurchaseDemandAll(req *GetErpPurchaseDemandReq, c *gin.Context) (*Get
return nil, errors.New("无有效门店,请配置门店信息")
}
qs := orm.Eloquent.Debug().Table("erp_commodity")
qs := orm.Eloquent.Debug().Table("erp_commodity").Where("stop_purchase != 1")
if req.ErpCategoryId != 0 {
categoryInfo, err := GetErpCategory(req.ErpCategoryId)
if err != nil {

View File

@ -4672,3 +4672,72 @@ func (m *CancelPrivilegeMembersReq) CancelPrivilegeMembers() (*PrivilegeMember,
return &userInfo, nil
}
// GetUserType 获取会员类别1-普通会员 2-黄金会员 4-白金会员 5-黑金会员 6-尊享会员 7-黄金&尊享 8-白金&尊享 9-黑金&尊享
func GetUserType(uid int) (int, error) {
userType := 1 // 默认普通会员
// 获取尊享会员信息
var privilegeUserInfo PrivilegeMember
if err := orm.Eloquent.Table("privilege_member").Where("uid = ?", uid).Find(&privilegeUserInfo).Error; err != nil {
logger.Errorf("获取尊享会员信息出错:", logger.Field("err", err))
return userType, err
}
// 获取用户信息
var userInfo UserInfo
if err := orm.Eloquent.Table("user").Where("uid = ?", uid).Find(&userInfo).Error; err != nil {
logger.Errorf("获取用户信息出错:", logger.Field("err", err))
return userType, err
}
// 判断用户类别
switch userInfo.MemberLevel {
case MemberLevelGold, MemberLevelPeriod: // 黄金会员或短期会员
userType = 2
case MemberLevelPlatinum: // 白金会员
userType = 4
case MemberLevelBlackGold: // 黑金会员
userType = 5
}
// 如果是尊享会员,增加相应标志
if privilegeUserInfo.MemberLevel == MemberLevelPrivilege {
switch userType {
case 2: // 黄金会员 & 尊享会员
userType = 7
case 4: // 白金会员 & 尊享会员
userType = 8
case 5: // 黑金会员 & 尊享会员
userType = 9
default: // 仅尊享会员
userType = 6
}
}
return userType, nil
}
// GetUserTypeString 将userType转换为对应的简写字符串
func GetUserTypeString(userType int) string {
switch userType {
case 1:
return "普通会员"
case 2:
return "付费会员(黄金)"
case 4:
return "付费会员(白金)"
case 5:
return "付费会员(黑金)"
case 6:
return "付费会员(尊享)"
case 7:
return "付费会员(黄金&尊享)"
case 8:
return "付费会员(白金&尊享)"
case 9:
return "付费会员(黑金&尊享)"
default:
return "普通会员"
}
}

View File

@ -24,4 +24,5 @@ func registerErpOrderManageRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJW
r.POST("receipt_data", erpordermanage.ErpOrderReceiptData) // 查询小票数据
r.POST("show_all_data", erpordermanage.ErpOrderShowAllData) // 展示所有订单
r.POST("daily_report", erpordermanage.ErpOrderDailyReport) // 经营日报表
r.POST("sale_detail", erpordermanage.ErpOrderSaleDetail) // 查询销售明细
}

View File

@ -1853,7 +1853,7 @@ const docTemplate = `{
"application/json"
],
"tags": [
"零售订单"
"零售报表"
],
"summary": "经营日报表",
"parameters": [
@ -2141,6 +2141,39 @@ const docTemplate = `{
}
}
},
"/api/v1/erp_order/sale_detail": {
"post": {
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"零售报表"
],
"summary": "查询销售明细",
"parameters": [
{
"description": "查询销售明细数据模型",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/models.ErpOrderSaleDetailReq"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/models.ErpOrderRetailDetailResp"
}
}
}
}
},
"/api/v1/erp_order/show_all_data": {
"post": {
"consumes": [
@ -7139,6 +7172,10 @@ const docTemplate = `{
"description": "员工成本价加价",
"type": "number"
},
"stop_purchase": {
"description": "0-未勾选正常采购1-勾选,停止采购",
"type": "integer"
},
"wholesale_price": {
"description": "指导采购价",
"type": "number"
@ -7245,6 +7282,10 @@ const docTemplate = `{
"description": "员工成本价加价",
"type": "number"
},
"stop_purchase": {
"description": "0-未勾选正常采购1-勾选,停止采购",
"type": "integer"
},
"wholesale_price": {
"description": "指导采购价",
"type": "number"
@ -7785,6 +7826,10 @@ const docTemplate = `{
"$ref": "#/definitions/models.CategorySalesData"
}
},
"store_amount": {
"description": "门店销售金额",
"type": "number"
},
"store_id": {
"description": "门店ID",
"type": "integer"
@ -7792,6 +7837,10 @@ const docTemplate = `{
"store_name": {
"description": "门店名称",
"type": "string"
},
"store_sales_profit": {
"description": "门店销售毛利(销售毛利;店员看员工毛利)",
"type": "number"
}
}
},
@ -8473,6 +8522,10 @@ const docTemplate = `{
"description": "库存数量",
"type": "integer"
},
"stop_purchase": {
"description": "0-未勾选正常采购1-勾选,停止采购",
"type": "integer"
},
"updatedAt": {
"description": "更新时间",
"type": "string"
@ -9353,6 +9406,10 @@ const docTemplate = `{
"description": "更新时间",
"type": "string"
},
"user_type": {
"description": "会员类别1-普通会员 2-黄金会员 4-白金会员 5-黑金会员 6-尊享会员 7-黄金\u0026尊享 8-白金\u0026尊享 9-黑金\u0026尊享",
"type": "integer"
},
"vm_count": {
"description": "使用会员积分",
"type": "integer"
@ -10154,6 +10211,81 @@ const docTemplate = `{
}
}
},
"models.ErpOrderSaleDetailReq": {
"type": "object",
"properties": {
"bank_trx_no": {
"description": "银联流水号",
"type": "string"
},
"bill_sn": {
"description": "单据编号",
"type": "string"
},
"end_time": {
"description": "结束时间",
"type": "string"
},
"erp_category_id": {
"description": "分类id",
"type": "array",
"items": {
"type": "integer"
}
},
"erp_commodity_name": {
"description": "商品名称",
"type": "string"
},
"imei": {
"description": "串码",
"type": "string"
},
"is_export": {
"description": "1-导出",
"type": "integer"
},
"pageIndex": {
"description": "页码",
"type": "integer"
},
"pageSize": {
"description": "页面条数",
"type": "integer"
},
"retail_type": {
"description": "销售类型sale 零售销售; rejected 零售退货",
"type": "string"
},
"salesman": {
"description": "销售人员ID",
"type": "integer"
},
"start_time": {
"description": "开始时间",
"type": "string"
},
"store_id": {
"description": "门店ID",
"type": "integer"
},
"tel": {
"description": "客户手机号",
"type": "string"
},
"uid": {
"description": "用户ID",
"type": "integer"
},
"user_type": {
"description": "会员类别0-未注册 1-普通会员 2-黄金会员 4-白金会员 5-黑金会员 6-尊享会员 7-黄金\u0026尊享 8-白金\u0026尊享 9-黑金\u0026尊享",
"type": "array",
"items": {
"type": "integer"
}
}
}
},
"models.ErpOrderSales": {
"type": "object",
"required": [

View File

@ -1842,7 +1842,7 @@
"application/json"
],
"tags": [
"零售订单"
"零售报表"
],
"summary": "经营日报表",
"parameters": [
@ -2130,6 +2130,39 @@
}
}
},
"/api/v1/erp_order/sale_detail": {
"post": {
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"零售报表"
],
"summary": "查询销售明细",
"parameters": [
{
"description": "查询销售明细数据模型",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/models.ErpOrderSaleDetailReq"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/models.ErpOrderRetailDetailResp"
}
}
}
}
},
"/api/v1/erp_order/show_all_data": {
"post": {
"consumes": [
@ -7128,6 +7161,10 @@
"description": "员工成本价加价",
"type": "number"
},
"stop_purchase": {
"description": "0-未勾选正常采购1-勾选,停止采购",
"type": "integer"
},
"wholesale_price": {
"description": "指导采购价",
"type": "number"
@ -7234,6 +7271,10 @@
"description": "员工成本价加价",
"type": "number"
},
"stop_purchase": {
"description": "0-未勾选正常采购1-勾选,停止采购",
"type": "integer"
},
"wholesale_price": {
"description": "指导采购价",
"type": "number"
@ -7774,6 +7815,10 @@
"$ref": "#/definitions/models.CategorySalesData"
}
},
"store_amount": {
"description": "门店销售金额",
"type": "number"
},
"store_id": {
"description": "门店ID",
"type": "integer"
@ -7781,6 +7826,10 @@
"store_name": {
"description": "门店名称",
"type": "string"
},
"store_sales_profit": {
"description": "门店销售毛利(销售毛利;店员看员工毛利)",
"type": "number"
}
}
},
@ -8462,6 +8511,10 @@
"description": "库存数量",
"type": "integer"
},
"stop_purchase": {
"description": "0-未勾选正常采购1-勾选,停止采购",
"type": "integer"
},
"updatedAt": {
"description": "更新时间",
"type": "string"
@ -9342,6 +9395,10 @@
"description": "更新时间",
"type": "string"
},
"user_type": {
"description": "会员类别1-普通会员 2-黄金会员 4-白金会员 5-黑金会员 6-尊享会员 7-黄金\u0026尊享 8-白金\u0026尊享 9-黑金\u0026尊享",
"type": "integer"
},
"vm_count": {
"description": "使用会员积分",
"type": "integer"
@ -10143,6 +10200,81 @@
}
}
},
"models.ErpOrderSaleDetailReq": {
"type": "object",
"properties": {
"bank_trx_no": {
"description": "银联流水号",
"type": "string"
},
"bill_sn": {
"description": "单据编号",
"type": "string"
},
"end_time": {
"description": "结束时间",
"type": "string"
},
"erp_category_id": {
"description": "分类id",
"type": "array",
"items": {
"type": "integer"
}
},
"erp_commodity_name": {
"description": "商品名称",
"type": "string"
},
"imei": {
"description": "串码",
"type": "string"
},
"is_export": {
"description": "1-导出",
"type": "integer"
},
"pageIndex": {
"description": "页码",
"type": "integer"
},
"pageSize": {
"description": "页面条数",
"type": "integer"
},
"retail_type": {
"description": "销售类型sale 零售销售; rejected 零售退货",
"type": "string"
},
"salesman": {
"description": "销售人员ID",
"type": "integer"
},
"start_time": {
"description": "开始时间",
"type": "string"
},
"store_id": {
"description": "门店ID",
"type": "integer"
},
"tel": {
"description": "客户手机号",
"type": "string"
},
"uid": {
"description": "用户ID",
"type": "integer"
},
"user_type": {
"description": "会员类别0-未注册 1-普通会员 2-黄金会员 4-白金会员 5-黑金会员 6-尊享会员 7-黄金\u0026尊享 8-白金\u0026尊享 9-黑金\u0026尊享",
"type": "array",
"items": {
"type": "integer"
}
}
}
},
"models.ErpOrderSales": {
"type": "object",
"required": [

View File

@ -591,6 +591,9 @@ definitions:
staff_cost_price:
description: 员工成本价加价
type: number
stop_purchase:
description: 0-未勾选正常采购1-勾选,停止采购
type: integer
wholesale_price:
description: 指导采购价
type: number
@ -667,6 +670,9 @@ definitions:
staff_cost_price:
description: 员工成本价加价
type: number
stop_purchase:
description: 0-未勾选正常采购1-勾选,停止采购
type: integer
wholesale_price:
description: 指导采购价
type: number
@ -1068,12 +1074,18 @@ definitions:
items:
$ref: '#/definitions/models.CategorySalesData'
type: array
store_amount:
description: 门店销售金额
type: number
store_id:
description: 门店ID
type: integer
store_name:
description: 门店名称
type: string
store_sales_profit:
description: 门店销售毛利(销售毛利;店员看员工毛利)
type: number
type: object
models.DecisionReportData:
properties:
@ -1572,6 +1584,9 @@ definitions:
stock_count:
description: 库存数量
type: integer
stop_purchase:
description: 0-未勾选正常采购1-勾选,停止采购
type: integer
updatedAt:
description: 更新时间
type: string
@ -2218,6 +2233,9 @@ definitions:
updatedAt:
description: 更新时间
type: string
user_type:
description: 会员类别1-普通会员 2-黄金会员 4-白金会员 5-黑金会员 6-尊享会员 7-黄金&尊享 8-白金&尊享 9-黑金&尊享
type: integer
vm_count:
description: 使用会员积分
type: integer
@ -2800,6 +2818,62 @@ definitions:
description: 总销售毛利:销售/退货金额-销售成本
type: number
type: object
models.ErpOrderSaleDetailReq:
properties:
bank_trx_no:
description: 银联流水号
type: string
bill_sn:
description: 单据编号
type: string
end_time:
description: 结束时间
type: string
erp_category_id:
description: 分类id
items:
type: integer
type: array
erp_commodity_name:
description: 商品名称
type: string
imei:
description: 串码
type: string
is_export:
description: 1-导出
type: integer
pageIndex:
description: 页码
type: integer
pageSize:
description: 页面条数
type: integer
retail_type:
description: 销售类型sale 零售销售; rejected 零售退货
type: string
salesman:
description: 销售人员ID
type: integer
start_time:
description: 开始时间
type: string
store_id:
description: 门店ID
type: integer
tel:
description: 客户手机号
type: string
uid:
description: 用户ID
type: integer
user_type:
description: 会员类别0-未注册 1-普通会员 2-黄金会员 4-白金会员 5-黑金会员 6-尊享会员 7-黄金&尊享 8-白金&尊享
9-黑金&尊享
items:
type: integer
type: array
type: object
models.ErpOrderSales:
properties:
createdAt:
@ -9659,7 +9733,7 @@ paths:
$ref: '#/definitions/models.ErpOrderDailyReportResp'
summary: 经营日报表
tags:
- 零售订单
- 零售报表
/api/v1/erp_order/delete:
post:
consumes:
@ -9828,6 +9902,27 @@ paths:
summary: 查询商品零售毛利汇总
tags:
- 零售报表
/api/v1/erp_order/sale_detail:
post:
consumes:
- application/json
parameters:
- description: 查询销售明细数据模型
in: body
name: request
required: true
schema:
$ref: '#/definitions/models.ErpOrderSaleDetailReq'
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/models.ErpOrderRetailDetailResp'
summary: 查询销售明细
tags:
- 零售报表
/api/v1/erp_order/show_all_data:
post:
consumes: