From 7e7a48e008cce84dd7ee77b821ef6d3c698d95f5 Mon Sep 17 00:00:00 2001 From: chenlin Date: Tue, 19 Nov 2024 18:38:17 +0800 Subject: [PATCH] =?UTF-8?q?1=E3=80=81=E5=BA=93=E5=AD=98=E5=88=97=E8=A1=A8?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0excel=E5=AF=BC=E5=87=BA=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=EF=BC=9B=202=E3=80=81=E9=9B=B6=E5=94=AE=E6=98=8E=E7=BB=86?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3=E4=BC=98=E5=8C=96=EF=BC=8C=E5=B1=95=E7=A4=BA?= =?UTF-8?q?=E6=89=80=E6=9C=89=E6=94=AF=E4=BB=98=E6=96=B9=E5=BC=8F=EF=BC=9B?= =?UTF-8?q?=203=E3=80=81=E7=B3=BB=E7=BB=9F=E7=94=A8=E6=88=B7=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3=E4=BC=98=E5=8C=96=EF=BC=8C=E9=97=A8=E5=BA=97id?= =?UTF-8?q?=E6=94=B9=E6=88=90=E5=A4=8D=E9=80=89=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/admin/apis/system/sysuser.go | 23 +- app/admin/models/commodity.go | 204 ++++-- app/admin/models/erp_order.go | 1022 ++++++++++++++++++------------ app/admin/models/sysuser.go | 24 +- 4 files changed, 818 insertions(+), 455 deletions(-) diff --git a/app/admin/apis/system/sysuser.go b/app/admin/apis/system/sysuser.go index 24bddc1..d307441 100644 --- a/app/admin/apis/system/sysuser.go +++ b/app/admin/apis/system/sysuser.go @@ -12,6 +12,8 @@ import ( "go-admin/tools" "go-admin/tools/app" "net/http" + "strconv" + "strings" ) // GetSysUserList @@ -60,8 +62,23 @@ func GetSysUserList(c *gin.Context) { } data.RoleId, _ = tools.StringToInt(strRoleId) - nStoreId, _ := tools.StringToInt(strStoreId) - data.StoreId = uint32(nStoreId) + //nStoreId, _ := tools.StringToInt(strStoreId) + //data.StoreId = uint32(nStoreId) + + var ids []int + if strStoreId != "" { + // 将字符串按逗号分隔成字符串数组 + idsStrArray := strings.Split(strStoreId, ",") + + // 将每个字符串转换为整数,并添加到 ids 数组 + for _, idStr := range idsStrArray { + id, err := strconv.Atoi(idStr) + if err != nil { + tools.HasError(err, "门店id传参有误", -1) + } + ids = append(ids, id) + } + } postId := c.Request.FormValue("postId") data.PostId, _ = tools.StringToInt(postId) @@ -70,7 +87,7 @@ func GetSysUserList(c *gin.Context) { data.DeptId, _ = tools.StringToInt(deptId) data.DataScope = tools.GetUserIdStr(c) - result, count, exportUrl, err := data.GetPage(pageSize, pageIndex, export) + result, count, exportUrl, err := data.GetPage(pageSize, pageIndex, export, ids) tools.HasError(err, "", -1) var resp models.SysUserListResp resp.List = result diff --git a/app/admin/models/commodity.go b/app/admin/models/commodity.go index 6581537..d577b05 100644 --- a/app/admin/models/commodity.go +++ b/app/admin/models/commodity.go @@ -1626,7 +1626,7 @@ func checkRoleMenu(c *gin.Context, menuName string) (bool, error) { return exist, nil } -// InventoryDetailListExport 导出库存商品列表 +// InventoryDetailListExport 导出库存详情 func InventoryDetailListExport(list []ErpStockCommodity, c *gin.Context) (string, error) { file := excelize.NewFile() streamWriter, err := file.NewStreamWriter("Sheet1") @@ -1793,7 +1793,7 @@ type ErpStockListReq struct { StoreId uint32 `json:"store_id"` // 门店编号 PageIndex int `json:"pageIndex"` // 页码 PageSize int `json:"pageSize"` // 页面条数 - //IsExport uint32 `json:"is_export"` // 1-导出 + IsExport uint32 `json:"is_export"` // 1-导出 } type ErpStockListResp struct { @@ -2092,22 +2092,31 @@ func (m *ErpStockListReq) stockIsEmptyList(c *gin.Context) (*ErpStockListResp, e SortStockCommodities(stockList) - // Paginate results - startIndex := page * m.PageSize - endIndex := startIndex + m.PageSize - if endIndex > len(stockList) { - endIndex = len(stockList) + if m.IsExport == 1 { + filePath, err := InventoryListExport(stockList, m.StockType) + if err != nil { + return nil, err + } + resp = &ErpStockListResp{} + resp.ExportUrl = filePath + } else { + // Paginate results + startIndex := page * m.PageSize + endIndex := startIndex + m.PageSize + if endIndex > len(stockList) { + endIndex = len(stockList) + } + + // Slice the users based on pagination + pagedList := stockList[startIndex:endIndex] + + //跟之前保持一致 + resp.Total = len(stockList) + resp.PageIndex = page + 1 + resp.PageSize = m.PageSize + resp.List = pagedList } - // Slice the users based on pagination - pagedList := stockList[startIndex:endIndex] - - //跟之前保持一致 - resp.Total = len(stockList) - resp.PageIndex = page + 1 - resp.PageSize = m.PageSize - resp.List = pagedList - return resp, nil } @@ -2282,22 +2291,31 @@ func (m *ErpStockListReq) stockNoEmptyList(c *gin.Context) (*ErpStockListResp, e SortStockCommodities(stockList) - // Paginate results - startIndex := page * m.PageSize - endIndex := startIndex + m.PageSize - if endIndex > len(stockList) { - endIndex = len(stockList) + if m.IsExport == 1 { + filePath, err := InventoryListExport(stockList, m.StockType) + if err != nil { + return nil, err + } + resp = &ErpStockListResp{} + resp.ExportUrl = filePath + } else { + // Paginate results + startIndex := page * m.PageSize + endIndex := startIndex + m.PageSize + if endIndex > len(stockList) { + endIndex = len(stockList) + } + + // Slice the users based on pagination + pagedList := stockList[startIndex:endIndex] + + //跟之前保持一致 + resp.Total = len(stockList) + resp.PageIndex = page + 1 + resp.PageSize = m.PageSize + resp.List = pagedList } - // Slice the users based on pagination - pagedList := stockList[startIndex:endIndex] - - //跟之前保持一致 - resp.Total = len(stockList) - resp.PageIndex = page + 1 - resp.PageSize = m.PageSize - resp.List = pagedList - return resp, nil } @@ -2438,7 +2456,12 @@ func (m *ErpStockListReq) allCommodityList(c *gin.Context) (*ErpStockListResp, e return resp, err } - err = qs.Offset(page * m.PageSize).Limit(m.PageSize).Find(&commodities).Error + if m.IsExport == 1 { + err = qs.Find(&commodities).Error + } else { + err = qs.Offset(page * m.PageSize).Limit(m.PageSize).Find(&commodities).Error + } + if err != nil && err != RecordNotFound { logger.Error("commodityList err", logger.Field("err", err)) return resp, err @@ -2469,15 +2492,124 @@ func (m *ErpStockListReq) allCommodityList(c *gin.Context) (*ErpStockListResp, e SortStockCommodities(stockList) - //跟之前保持一致 - resp.Total = int(count) - resp.PageIndex = page + 1 - resp.PageSize = m.PageSize - resp.List = stockList + if m.IsExport == 1 { + filePath, err := InventoryListExport(stockList, m.StockType) + if err != nil { + return nil, err + } + resp = &ErpStockListResp{} + resp.ExportUrl = filePath + } else { + //跟之前保持一致 + resp.Total = int(count) + resp.PageIndex = page + 1 + resp.PageSize = m.PageSize + resp.List = stockList + } return resp, nil } +// InventoryListExport 导出库存列表 +func InventoryListExport(list []ErpStock, nType uint32) (string, error) { + file := excelize.NewFile() + fSheet := "Sheet1" + + var fileName string + switch nType { + case 2: // 有库存 + fileName = time.Now().Format(TimeFormat) + "库存列表(有库存)" + ".xlsx" + case 3: // 无库存 + fileName = time.Now().Format(TimeFormat) + "库存列表(无库存)" + ".xlsx" + default: // 全部 + fileName = time.Now().Format(TimeFormat) + "库存列表(全部)" + ".xlsx" + } + + url := config.ExportConfig.Url + fmt.Println("url fileName:", url+fileName) + + // 设置标题行 + title1 := []interface{}{"基础资料", "", "", "", "", "", "库存情况", ""} + title2 := []interface{}{"商品编号", "商品名称", "商品分类", "是否串码", "指导零售价", "最低零售价", "有效库存数量", "调出中数量"} + + for i, _ := range title1 { + cell, _ := excelize.CoordinatesToCellName(1+i, 1) + err := file.SetCellValue(fSheet, cell, title1[i]) + if err != nil { + logger.Errorf("file set value err:", err) + } + } + + for i, _ := range title2 { + cell, _ := excelize.CoordinatesToCellName(1+i, 2) + err := file.SetCellValue(fSheet, cell, title2[i]) + if err != nil { + logger.Errorf("file set value err:", err) + } + } + + nExcelStartRow := 0 + for rowId := 0; rowId < len(list); rowId++ { + isIMEIType := "是" + if list[rowId].IMEIType == 1 { + isIMEIType = "否" + } + + row := []interface{}{ + list[rowId].CommoditySerialNumber, + list[rowId].ErpCommodityName, + list[rowId].ErpCategoryName, + isIMEIType, + list[rowId].RetailPrice, + list[rowId].MinRetailPrice, + list[rowId].Count, + list[rowId].DispatchCount, + } + + for j, _ := range row { + cell, _ := excelize.CoordinatesToCellName(1+j, nExcelStartRow+3) + err := file.SetCellValue(fSheet, cell, row[j]) + if err != nil { + logger.Error("file set value err:", logger.Field("err", err)) + } + } + nExcelStartRow++ + } + + // 设置所有单元格的样式: 居中、加边框 + 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}]}`) + + // 合并单元格 + _ = file.MergeCell(fSheet, "A1", "F1") + _ = file.MergeCell(fSheet, "G1", "H1") + + //设置单元格高度 + file.SetRowHeight("Sheet1", 1, 20) + + // 设置单元格大小 + file.SetColWidth("Sheet1", "A", "A", 13) + file.SetColWidth("Sheet1", "B", "B", 40) + file.SetColWidth("Sheet1", "C", "C", 13) + file.SetColWidth("Sheet1", "E", "E", 13) + file.SetColWidth("Sheet1", "F", "F", 13) + file.SetColWidth("Sheet1", "G", "G", 13) + file.SetColWidth("Sheet1", "H", "H", 13) + + endRow := fmt.Sprintf("H"+"%d", nExcelStartRow+2) + // 应用样式到整个表格 + _ = file.SetCellStyle("Sheet1", "A1", endRow, style) + + 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 +} + func ErpStockCommodityListSetAge(commodities []ErpStockCommodity) { nowTime := time.Now() for i, _ := range commodities { diff --git a/app/admin/models/erp_order.go b/app/admin/models/erp_order.go index 1a60afe..367d510 100644 --- a/app/admin/models/erp_order.go +++ b/app/admin/models/erp_order.go @@ -384,9 +384,10 @@ type RetailDetailTotalData struct { TotalRetailPrice float64 `json:"total_retail_price"` // 订单总指导零售价 TotalDiscount float64 `json:"total_discount"` // 订单总优惠:订单所有商品零售优惠+会员优惠+会员积分抵扣之和 TotalAmount float64 `json:"total_amount"` // 订单实收金额 - TotalCashierData - TotalSalesProfit float64 `json:"total_sales_profit"` // 订单总销售毛利 - TotalStaffProfit float64 `json:"total_staff_profit"` // 订单总员工毛利 + //TotalCashierData + TotalCashierData []ErpOrderCashier `json:"total_cashier_data" gorm:"-"` // 订单实收金额 + TotalSalesProfit float64 `json:"total_sales_profit"` // 订单总销售毛利 + TotalStaffProfit float64 `json:"total_staff_profit"` // 订单总员工毛利 TotalPerData StorePer float64 `json:"store_per"` // 门店提成 } @@ -3502,270 +3503,270 @@ func QueryRetailDetail(req *ErpOrderRetailDetailReq, c *gin.Context) (*ErpOrderR return resp, nil } -// 导出零售明细报表excel-合并单元格版本 -func retailDetailExportBack(list []ErpOrder, sumData RetailDetailTotalData) (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", "客户手机号", "审核时间", "店铺", "销售员", "商品分类", "商品名称", - "供应商", "是否串码", "商品串码", "是否赠送", "销售数量", "指导零售价", "零售价", "零售优惠", "会员优惠", "实际零售价/退货价", - "采购单价", "员工成本价", "销售毛利", "员工毛利", "订单总指导零售价", "订单总优惠", "订单实收", "【扫码付", "现金收款", "pos机收款", - "商场积分抵扣", "其他付款方式】", "订单总销售毛利", "订单总员工毛利", "销售毛利提成", "员工毛利提成", "销售员提成", "门店提成", "备注"} - 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)) - } - } - - 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) - } - - commodityIdMap := make(map[uint32]bool) - // 先判断商品数量,确定要写几行数据 - 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 = "" // 目前零售退货订单暂时不展示各个方式的付款金额 - } - - isIMEIType := "是" - if list[i].Commodities[rowId].IMEIType == 1 { - isIMEIType = "否" - } - - strPresentType := "非赠送" - if list[i].Commodities[rowId].PresentType == 2 { - strPresentType = "赠送" - } - - // 组合销售员名称,提成数据 - salesMan := "" - strSalesProfitPer := "" - strStaffProfitPer := "" - strSalesmanPer := "" - //var salesList []ErpOrderSales - //err := json.Unmarshal([]byte(list[i].SalesmanList), &salesList) - //if err != nil { - // logger.Error("unmarshal err:", logger.Field("err", err)) - //} - for j, item := range list[i].Salesman { - salesMan += item.Name - // 将浮点数转换为字符串,保留两位小数 - strNumber1 := strconv.FormatFloat(item.SalesProfitPer, 'f', 2, 64) - strSalesProfitPer += strNumber1 - strNumber2 := strconv.FormatFloat(item.StaffProfitPer, 'f', 2, 64) - strStaffProfitPer += strNumber2 - strNumber3 := strconv.FormatFloat(item.SalesmanPer, 'f', 2, 64) - strSalesmanPer += strNumber3 - - if j < len(list[i].Salesman)-1 { - salesMan += "\n" - strSalesProfitPer += "\n" - strStaffProfitPer += "\n" - strSalesmanPer += "\n" - } - } - - // 组合支付相关信息 - var cashierData TotalCashierData - var cashiers []ErpOrderCashier - err := json.Unmarshal([]byte(list[i].CashierList), &cashiers) - if err != nil { - logger.Error("unmarshal err:", logger.Field("err", err)) - } - for _, item := range cashiers { - switch item.CashierId { - case 1: - cashierData.ScanAmount = item.Amount - case 2: - cashierData.CashAmount = item.Amount - case 3: - cashierData.PosAmount = item.Amount - case 4: - cashierData.StoreVmAmount = item.Amount - default: - cashierData.OtherAmount += item.Amount - } - } - - // 单个订单的汇总数据只记录一次 - var temp RetailDetailTotalData - if !commodityIdMap[list[i].Commodities[rowId].ErpCommodityId] { - commodityIdMap[list[i].Commodities[rowId].ErpCommodityId] = true - temp.TotalRetailPrice = list[i].TotalRetailPrice - temp.TotalDiscount = list[i].TotalDiscount - temp.TotalAmount = list[i].TotalAmount - temp.TotalSalesProfit = list[i].TotalSalesProfit - temp.TotalStaffProfit = list[i].TotalStaffProfit - temp.StorePer = list[i].StorePer - } - - row = []interface{}{ - list[i].BillSn, - saleType, - list[i].Uid, - list[i].Tel, - list[i].AuditTime, - list[i].StoreName, - salesMan, //销售员 - list[i].Commodities[rowId].ErpCategoryName, - list[i].Commodities[rowId].ErpCommodityName, - list[i].Commodities[rowId].ErpSupplierName, //供应商 - isIMEIType, - 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, - temp.TotalRetailPrice, - temp.TotalDiscount, - temp.TotalAmount, - cashierData.ScanAmount, // 扫码付 - cashierData.CashAmount, // 现金收款 - cashierData.PosAmount, // pos机收款 - cashierData.StoreVmAmount, // 商场积分抵扣 - cashierData.OtherAmount, // 其他付款方式 - temp.TotalSalesProfit, - temp.TotalStaffProfit, - strSalesProfitPer, // 销售毛利提成 - strStaffProfitPer, // 员工毛利提成 - strSalesmanPer, // 销售员提成 - temp.StorePer, - 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++ - } - - //合并单元格 - nRow := len(list[i].Commodities) - if nRow > 1 { - for j := 'A'; j <= 'G'; j++ { - colName := string(j) - str1 := fmt.Sprintf("%s%d", colName, nExcelStartRow-nRow+2) - str2 := fmt.Sprintf("%s%d", colName, nExcelStartRow+1) - _ = file.MergeCell(fSheet, str1, str2) - } - - for j := 'X'; j <= 'Z'; j++ { - colName := string(j) - str1 := fmt.Sprintf("%s%d", colName, nExcelStartRow-nRow+2) - str2 := fmt.Sprintf("%s%d", colName, nExcelStartRow+1) - _ = file.MergeCell(fSheet, str1, str2) - } - - for j := 'A'; j <= 'L'; j++ { - colName := string(j) - str1 := fmt.Sprintf("A%s%d", colName, nExcelStartRow-nRow+2) - str2 := fmt.Sprintf("A%s%d", colName, nExcelStartRow+1) - _ = file.MergeCell(fSheet, str1, str2) - } - } - } - - totalData := "订单数:" + strconv.FormatInt(int64(sumData.Count), 10) - end := []interface{}{totalData, "", "", "", "", "", "", "", "", "", "", "", "", - sumData.Count, - sumData.RetailPrice, - sumData.SalePrice, - sumData.SaleDiscount, - sumData.MemberDiscount, - sumData.Amount, - sumData.WholesalePrice, - sumData.StaffPrice, - sumData.SalesProfit, - sumData.StaffProfit, - sumData.TotalRetailPrice, - sumData.TotalDiscount, - sumData.TotalAmount, - sumData.ScanAmount, // 扫码付 - sumData.CashAmount, // 现金收款 - sumData.PosAmount, // pos机收款 - sumData.StoreVmAmount, // 商场积分抵扣 - sumData.OtherAmount, // 其他付款方式 - sumData.TotalSalesProfit, - sumData.TotalStaffProfit, - sumData.TotalSalesProfitPer, // 销售毛利提成 - sumData.TotalStaffProfitPer, // 员工毛利提成 - sumData.SalesmanPer, // 销售员提成 - sumData.StorePer, - ""} - - 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}]}`) - - // 设置单元格的样式: 居中、加边框、自动换行 - style1, _ := file.NewStyle(`{"alignment":{"horizontal":"center","vertical":"center","wrap_text":true}, - "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("AL%d", nExcelStartRow+2) - // 应用样式到整个表格 - _ = file.SetCellStyle("Sheet1", "A1", endRow, style) - - //需要自动换行的列 - endRow1 := fmt.Sprintf("G%d", nExcelStartRow+2) - endRow2 := fmt.Sprintf("AH%d", nExcelStartRow+2) - endRow3 := fmt.Sprintf("AI%d", nExcelStartRow+2) - endRow4 := fmt.Sprintf("AJ%d", nExcelStartRow+2) - _ = file.SetCellStyle("Sheet1", "A1", "AL1", style1) - _ = file.SetCellStyle("Sheet1", "G2", endRow1, style1) - _ = file.SetCellStyle("Sheet1", "AH2", endRow2, style1) - _ = file.SetCellStyle("Sheet1", "AI2", endRow3, style1) - _ = file.SetCellStyle("Sheet1", "AJ2", endRow4, style1) - - 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 -} +//// 导出零售明细报表excel-合并单元格版本 +//func retailDetailExportBack(list []ErpOrder, sumData RetailDetailTotalData) (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", "客户手机号", "审核时间", "店铺", "销售员", "商品分类", "商品名称", +// "供应商", "是否串码", "商品串码", "是否赠送", "销售数量", "指导零售价", "零售价", "零售优惠", "会员优惠", "实际零售价/退货价", +// "采购单价", "员工成本价", "销售毛利", "员工毛利", "订单总指导零售价", "订单总优惠", "订单实收", "【扫码付", "现金收款", "pos机收款", +// "商场积分抵扣", "其他付款方式】", "订单总销售毛利", "订单总员工毛利", "销售毛利提成", "员工毛利提成", "销售员提成", "门店提成", "备注"} +// 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)) +// } +// } +// +// 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) +// } +// +// commodityIdMap := make(map[uint32]bool) +// // 先判断商品数量,确定要写几行数据 +// 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 = "" // 目前零售退货订单暂时不展示各个方式的付款金额 +// } +// +// isIMEIType := "是" +// if list[i].Commodities[rowId].IMEIType == 1 { +// isIMEIType = "否" +// } +// +// strPresentType := "非赠送" +// if list[i].Commodities[rowId].PresentType == 2 { +// strPresentType = "赠送" +// } +// +// // 组合销售员名称,提成数据 +// salesMan := "" +// strSalesProfitPer := "" +// strStaffProfitPer := "" +// strSalesmanPer := "" +// //var salesList []ErpOrderSales +// //err := json.Unmarshal([]byte(list[i].SalesmanList), &salesList) +// //if err != nil { +// // logger.Error("unmarshal err:", logger.Field("err", err)) +// //} +// for j, item := range list[i].Salesman { +// salesMan += item.Name +// // 将浮点数转换为字符串,保留两位小数 +// strNumber1 := strconv.FormatFloat(item.SalesProfitPer, 'f', 2, 64) +// strSalesProfitPer += strNumber1 +// strNumber2 := strconv.FormatFloat(item.StaffProfitPer, 'f', 2, 64) +// strStaffProfitPer += strNumber2 +// strNumber3 := strconv.FormatFloat(item.SalesmanPer, 'f', 2, 64) +// strSalesmanPer += strNumber3 +// +// if j < len(list[i].Salesman)-1 { +// salesMan += "\n" +// strSalesProfitPer += "\n" +// strStaffProfitPer += "\n" +// strSalesmanPer += "\n" +// } +// } +// +// // 组合支付相关信息 +// var cashierData TotalCashierData +// var cashiers []ErpOrderCashier +// err := json.Unmarshal([]byte(list[i].CashierList), &cashiers) +// if err != nil { +// logger.Error("unmarshal err:", logger.Field("err", err)) +// } +// for _, item := range cashiers { +// switch item.CashierId { +// case 1: +// cashierData.ScanAmount = item.Amount +// case 2: +// cashierData.CashAmount = item.Amount +// case 3: +// cashierData.PosAmount = item.Amount +// case 4: +// cashierData.StoreVmAmount = item.Amount +// default: +// cashierData.OtherAmount += item.Amount +// } +// } +// +// // 单个订单的汇总数据只记录一次 +// var temp RetailDetailTotalData +// if !commodityIdMap[list[i].Commodities[rowId].ErpCommodityId] { +// commodityIdMap[list[i].Commodities[rowId].ErpCommodityId] = true +// temp.TotalRetailPrice = list[i].TotalRetailPrice +// temp.TotalDiscount = list[i].TotalDiscount +// temp.TotalAmount = list[i].TotalAmount +// temp.TotalSalesProfit = list[i].TotalSalesProfit +// temp.TotalStaffProfit = list[i].TotalStaffProfit +// temp.StorePer = list[i].StorePer +// } +// +// row = []interface{}{ +// list[i].BillSn, +// saleType, +// list[i].Uid, +// list[i].Tel, +// list[i].AuditTime, +// list[i].StoreName, +// salesMan, //销售员 +// list[i].Commodities[rowId].ErpCategoryName, +// list[i].Commodities[rowId].ErpCommodityName, +// list[i].Commodities[rowId].ErpSupplierName, //供应商 +// isIMEIType, +// 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, +// temp.TotalRetailPrice, +// temp.TotalDiscount, +// temp.TotalAmount, +// cashierData.ScanAmount, // 扫码付 +// cashierData.CashAmount, // 现金收款 +// cashierData.PosAmount, // pos机收款 +// cashierData.StoreVmAmount, // 商场积分抵扣 +// cashierData.OtherAmount, // 其他付款方式 +// temp.TotalSalesProfit, +// temp.TotalStaffProfit, +// strSalesProfitPer, // 销售毛利提成 +// strStaffProfitPer, // 员工毛利提成 +// strSalesmanPer, // 销售员提成 +// temp.StorePer, +// 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++ +// } +// +// //合并单元格 +// nRow := len(list[i].Commodities) +// if nRow > 1 { +// for j := 'A'; j <= 'G'; j++ { +// colName := string(j) +// str1 := fmt.Sprintf("%s%d", colName, nExcelStartRow-nRow+2) +// str2 := fmt.Sprintf("%s%d", colName, nExcelStartRow+1) +// _ = file.MergeCell(fSheet, str1, str2) +// } +// +// for j := 'X'; j <= 'Z'; j++ { +// colName := string(j) +// str1 := fmt.Sprintf("%s%d", colName, nExcelStartRow-nRow+2) +// str2 := fmt.Sprintf("%s%d", colName, nExcelStartRow+1) +// _ = file.MergeCell(fSheet, str1, str2) +// } +// +// for j := 'A'; j <= 'L'; j++ { +// colName := string(j) +// str1 := fmt.Sprintf("A%s%d", colName, nExcelStartRow-nRow+2) +// str2 := fmt.Sprintf("A%s%d", colName, nExcelStartRow+1) +// _ = file.MergeCell(fSheet, str1, str2) +// } +// } +// } +// +// totalData := "订单数:" + strconv.FormatInt(int64(sumData.Count), 10) +// end := []interface{}{totalData, "", "", "", "", "", "", "", "", "", "", "", "", +// sumData.Count, +// sumData.RetailPrice, +// sumData.SalePrice, +// sumData.SaleDiscount, +// sumData.MemberDiscount, +// sumData.Amount, +// sumData.WholesalePrice, +// sumData.StaffPrice, +// sumData.SalesProfit, +// sumData.StaffProfit, +// sumData.TotalRetailPrice, +// sumData.TotalDiscount, +// sumData.TotalAmount, +// sumData.ScanAmount, // 扫码付 +// sumData.CashAmount, // 现金收款 +// sumData.PosAmount, // pos机收款 +// sumData.StoreVmAmount, // 商场积分抵扣 +// sumData.OtherAmount, // 其他付款方式 +// sumData.TotalSalesProfit, +// sumData.TotalStaffProfit, +// sumData.TotalSalesProfitPer, // 销售毛利提成 +// sumData.TotalStaffProfitPer, // 员工毛利提成 +// sumData.SalesmanPer, // 销售员提成 +// sumData.StorePer, +// ""} +// +// 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}]}`) +// +// // 设置单元格的样式: 居中、加边框、自动换行 +// style1, _ := file.NewStyle(`{"alignment":{"horizontal":"center","vertical":"center","wrap_text":true}, +// "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("AL%d", nExcelStartRow+2) +// // 应用样式到整个表格 +// _ = file.SetCellStyle("Sheet1", "A1", endRow, style) +// +// //需要自动换行的列 +// endRow1 := fmt.Sprintf("G%d", nExcelStartRow+2) +// endRow2 := fmt.Sprintf("AH%d", nExcelStartRow+2) +// endRow3 := fmt.Sprintf("AI%d", nExcelStartRow+2) +// endRow4 := fmt.Sprintf("AJ%d", nExcelStartRow+2) +// _ = file.SetCellStyle("Sheet1", "A1", "AL1", style1) +// _ = file.SetCellStyle("Sheet1", "G2", endRow1, style1) +// _ = file.SetCellStyle("Sheet1", "AH2", endRow2, style1) +// _ = file.SetCellStyle("Sheet1", "AI2", endRow3, style1) +// _ = file.SetCellStyle("Sheet1", "AJ2", endRow4, style1) +// +// 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 +//} // 导出零售明细报表excel-不合并 func retailDetailExport(list []ErpOrder, sumData RetailDetailTotalData, c *gin.Context) (string, error) { @@ -3776,6 +3777,13 @@ func retailDetailExport(list []ErpOrder, sumData RetailDetailTotalData, c *gin.C fileName := time.Now().Format(TimeFormat) + "零售明细" + ".xlsx" fmt.Println("url fileName:", url+fileName) + // 查询所有支付方式 + var sysCashierList []ErpCashier + err := orm.Eloquent.Table("erp_cashier").Order("id ASC").Find(&sysCashierList).Error + if err != nil { + return "", err + } + // 判断是否有权限 flag1, _ := checkRoleMenu(c, DetailWholesalePriceMenu) flag2, _ := checkRoleMenu(c, DetailEmployeeCostMenu) @@ -3809,8 +3817,19 @@ func retailDetailExport(list []ErpOrder, sumData RetailDetailTotalData, c *gin.C nEndCount += 1 } - title = append(title, "订单总指导零售价", "订单总优惠", "订单实收", "【扫码付", "现金收款", "pos机收款", - "商场积分抵扣", "其他付款方式】") + title = append(title, "订单总指导零售价", "订单总优惠", "订单实收") + + for i, value := range sysCashierList { + if value.ID == 1 { + title = append(title, "【扫码付") + } else if i+1 == len(sysCashierList) { + title = append(title, value.Name+"】") + } else { + title = append(title, value.Name) + } + nEndCount += 1 + } + if flag5 { // 订单总销售毛利 title = append(title, "订单总销售毛利") nEndCount += 1 @@ -3875,7 +3894,7 @@ func retailDetailExport(list []ErpOrder, sumData RetailDetailTotalData, c *gin.C nAmount = list[i].Commodities[rowId].Amount } else if list[i].RetailType == RetailTypeRejected { nAmount = list[i].Commodities[rowId].RejectedAmount - list[i].CashierList = "" // 目前零售退货订单暂时不展示各个方式的付款金额 + //list[i].CashierList = "" // 目前零售退货订单暂时不展示各个方式的付款金额 } // 用户id @@ -3911,26 +3930,44 @@ func retailDetailExport(list []ErpOrder, sumData RetailDetailTotalData, c *gin.C } // 组合支付相关信息 - var cashierData TotalCashierData var cashiers []ErpOrderCashier err := json.Unmarshal([]byte(list[i].CashierList), &cashiers) if err != nil { logger.Error("unmarshal err:", logger.Field("err", err)) } - for _, item := range cashiers { - switch item.CashierId { - case 1: - cashierData.ScanAmount = item.Amount - case 2: - cashierData.CashAmount = item.Amount - case 3: - cashierData.PosAmount = item.Amount - case 4: - cashierData.StoreVmAmount = item.Amount - default: - cashierData.OtherAmount += item.Amount + + var cashierDataList []ErpOrderCashier + for _, value := range sysCashierList { + var orderCashier ErpOrderCashier + orderCashier.CashierId = value.ID + orderCashier.Name = value.Name + for _, item := range cashiers { + if value.ID == item.CashierId { + if list[i].RetailType == RetailTypeRejected { + orderCashier.Amount = -item.Amount + } else { + orderCashier.Amount = item.Amount + } + } else { + continue + } } + cashierDataList = append(cashierDataList, orderCashier) } + //for _, item := range cashiers { + // switch item.CashierId { + // case 1: + // cashierData.ScanAmount = item.Amount + // case 2: + // cashierData.CashAmount = item.Amount + // case 3: + // cashierData.PosAmount = item.Amount + // case 4: + // cashierData.StoreVmAmount = item.Amount + // default: + // cashierData.OtherAmount += item.Amount + // } + //} // 单个订单的汇总数据只记录一次 if !orderFlag { @@ -4013,11 +4050,15 @@ func retailDetailExport(list []ErpOrder, sumData RetailDetailTotalData, c *gin.C row = append(row, list[i].TotalRetailPrice) row = append(row, list[i].TotalDiscount) row = append(row, list[i].TotalAmount) - row = append(row, cashierData.ScanAmount) - row = append(row, cashierData.CashAmount) - row = append(row, cashierData.PosAmount) - row = append(row, cashierData.StoreVmAmount) - row = append(row, cashierData.OtherAmount) + //row = append(row, cashierData.ScanAmount) + //row = append(row, cashierData.CashAmount) + //row = append(row, cashierData.PosAmount) + //row = append(row, cashierData.StoreVmAmount) + //row = append(row, cashierData.OtherAmount) + + for _, value := range cashierDataList { + row = append(row, value.Amount) + } if flag5 { // 订单总销售毛利 row = append(row, list[i].TotalSalesProfit) @@ -4107,11 +4148,16 @@ func retailDetailExport(list []ErpOrder, sumData RetailDetailTotalData, c *gin.C row = append(row, "") row = append(row, "") row = append(row, "") - row = append(row, "") - row = append(row, "") - row = append(row, "") - row = append(row, "") - row = append(row, "") + + for _, value := range sysCashierList { + fmt.Println("cashier name:", value.Name) + row = append(row, "") + } + //row = append(row, "") + //row = append(row, "") + //row = append(row, "") + //row = append(row, "") + //row = append(row, "") if flag5 { // 订单总销售毛利 row = append(row, "") @@ -4200,11 +4246,16 @@ func retailDetailExport(list []ErpOrder, sumData RetailDetailTotalData, c *gin.C row = append(row, "") row = append(row, "") row = append(row, "") - row = append(row, "") - row = append(row, "") - row = append(row, "") - row = append(row, "") - row = append(row, "") + + for _, value := range sysCashierList { + fmt.Println("cashier name:", value.Name) + row = append(row, "") + } + //row = append(row, "") + //row = append(row, "") + //row = append(row, "") + //row = append(row, "") + //row = append(row, "") if flag5 { // 订单总销售毛利 row = append(row, "") @@ -4390,11 +4441,15 @@ func retailDetailExport(list []ErpOrder, sumData RetailDetailTotalData, c *gin.C end = append(end, sumData.TotalRetailPrice) end = append(end, sumData.TotalDiscount) end = append(end, sumData.TotalAmount) - end = append(end, sumData.ScanAmount) - end = append(end, sumData.CashAmount) - end = append(end, sumData.PosAmount) - end = append(end, sumData.StoreVmAmount) - end = append(end, sumData.OtherAmount) + + for _, value := range sumData.TotalCashierData { + end = append(end, value.Amount) + } + //end = append(end, sumData.ScanAmount) + //end = append(end, sumData.CashAmount) + //end = append(end, sumData.PosAmount) + //end = append(end, sumData.StoreVmAmount) + //end = append(end, sumData.OtherAmount) if flag5 { // 订单总销售毛利 end = append(end, sumData.TotalSalesProfit) @@ -4432,31 +4487,8 @@ func retailDetailExport(list []ErpOrder, sumData RetailDetailTotalData, c *gin.C {"type":"right","color":"000000","style":1}, {"type":"bottom","color":"000000","style":1}]}`) - var endRow string - switch nEndCount { - case 1: - endRow = fmt.Sprintf("AH"+"%d", nExcelStartRow+2) - case 2: - endRow = fmt.Sprintf("AI"+"%d", nExcelStartRow+2) - case 3: - endRow = fmt.Sprintf("AJ"+"%d", nExcelStartRow+2) - case 4: - endRow = fmt.Sprintf("AK"+"%d", nExcelStartRow+2) - case 5: - endRow = fmt.Sprintf("AL"+"%d", nExcelStartRow+2) - case 6: - endRow = fmt.Sprintf("AM"+"%d", nExcelStartRow+2) - case 7: - endRow = fmt.Sprintf("AN"+"%d", nExcelStartRow+2) - case 8: - endRow = fmt.Sprintf("AO"+"%d", nExcelStartRow+2) - case 9: - endRow = fmt.Sprintf("AP"+"%d", nExcelStartRow+2) - case 10: - endRow = fmt.Sprintf("AQ"+"%d", nExcelStartRow+2) - default: - endRow = fmt.Sprintf("AG"+"%d", nExcelStartRow+2) - } + endRow := getEndRow(nEndCount, nExcelStartRow) + fmt.Println(endRow) //endRow := fmt.Sprintf("AL%d", nExcelStartRow+2) // 应用样式到整个表格 _ = file.SetCellStyle("Sheet1", "A1", endRow, style) @@ -4493,6 +4525,23 @@ func retailDetailExport(list []ErpOrder, sumData RetailDetailTotalData, c *gin.C return url + fileName, nil } +func getEndRow(nEndCount, nExcelStartRow int) string { + // Excel列是26进制的,列A为1,B为2,... Z为26,AA为27,以此类推 + columnIndex := 28 + nEndCount // "AH" 是第33列 + + // 计算Excel列标 + columnLetter := "" + for columnIndex > 0 { + // 获取当前列的字母,并且列标从1开始,所以要减去1 + columnLetter = string(rune((columnIndex-1)%26+'A')) + columnLetter + columnIndex = (columnIndex - 1) / 26 + } + + // 生成最终的单元格位置 + endRow := fmt.Sprintf("%s%d", columnLetter, nExcelStartRow+2) + return endRow +} + // 生成Excel列名 func getExcelColumnName(index int) string { columnName := "" @@ -4693,10 +4742,51 @@ func queryRetailDetailByJoin(req *ErpOrderRetailDetailReq, c *gin.Context) (*Erp // 计算销售订单和退货订单汇总后的提成数据 totalPerData = subtractTotalPerData(totalPerData, rejectedTotalPerData) - // 销售订单支持汇总 - var cashier TotalCashierData + //// 销售订单支持汇总 + //var cashier TotalCashierData + //cashierQs := qs + //cashier, err = getTotalCashierData(cashierQs, RetailTypeSale) + //if err != nil { + // logger.Error("query erp_order_pay_way sum data err:", logger.Field("err", err)) + // return resp, err + //} + // + //// 支付方式筛选 + //if req.CashierId != 0 { + // var tempCashier TotalCashierData + // switch req.CashierId { + // case 1: + // tempCashier.ScanAmount = cashier.ScanAmount + // case 2: + // tempCashier.CashAmount = cashier.CashAmount + // case 3: + // tempCashier.PosAmount = cashier.PosAmount + // case 4: + // tempCashier.StoreVmAmount = cashier.StoreVmAmount + // default: + // tempCashier = cashier + // } + // cashier = tempCashier + //} + // + //// 退货订单支付汇总:目前零售退货订单暂时不展示各个方式的付款金额 + //var rejectedCashier TotalCashierData + //rejectedCashierQs := qs + //rejectedCashier, err = getTotalCashierData(rejectedCashierQs, RetailTypeRejected) + //if err != nil { + // logger.Error("query erp_order_pay_way sum data err:", logger.Field("err", err)) + // return resp, err + //} + //// 计算销售订单和退货订单汇总后的支付数据 + //cashier = subtractCashierData(cashier, rejectedCashier) + // + //// 处理汇总数据,四舍五入保留2位小数 + //roundValues(&sumData, &totalPerData, &cashier) + + // 销售订单支付汇总 + var cashierData []ErpOrderCashier cashierQs := qs - cashier, err = getTotalCashierData(cashierQs, RetailTypeSale) + cashierData, err = getTotalCashierData(cashierQs, RetailTypeSale) if err != nil { logger.Error("query erp_order_pay_way sum data err:", logger.Field("err", err)) return resp, err @@ -4704,35 +4794,29 @@ func queryRetailDetailByJoin(req *ErpOrderRetailDetailReq, c *gin.Context) (*Erp // 支付方式筛选 if req.CashierId != 0 { - var tempCashier TotalCashierData - switch req.CashierId { - case 1: - tempCashier.ScanAmount = cashier.ScanAmount - case 2: - tempCashier.CashAmount = cashier.CashAmount - case 3: - tempCashier.PosAmount = cashier.PosAmount - case 4: - tempCashier.StoreVmAmount = cashier.StoreVmAmount - default: - tempCashier = cashier + var filteredData []ErpOrderCashier + for _, cashier := range cashierData { + if cashier.CashierId == req.CashierId { + filteredData = append(filteredData, cashier) + } } - cashier = tempCashier + cashierData = filteredData } // 退货订单支付汇总:目前零售退货订单暂时不展示各个方式的付款金额 - var rejectedCashier TotalCashierData + var rejectedCashierData []ErpOrderCashier rejectedCashierQs := qs - rejectedCashier, err = getTotalCashierData(rejectedCashierQs, RetailTypeRejected) + rejectedCashierData, err = getTotalCashierData(rejectedCashierQs, RetailTypeRejected) if err != nil { logger.Error("query erp_order_pay_way sum data err:", logger.Field("err", err)) return resp, err } + // 计算销售订单和退货订单汇总后的支付数据 - cashier = subtractCashierData(cashier, rejectedCashier) + cashierData = subtractCashierData(cashierData, rejectedCashierData) // 处理汇总数据,四舍五入保留2位小数 - roundValues(&sumData, &totalPerData, &cashier) + roundValues(&sumData, &totalPerData) sumData.TotalSalesProfit = 0 // 订单总销售毛利 sumData.TotalStaffProfit = 0 // 订单总员工毛利 @@ -4740,6 +4824,7 @@ func queryRetailDetailByJoin(req *ErpOrderRetailDetailReq, c *gin.Context) (*Erp sumData.TotalDiscount = 0 // 订单总优惠 sumData.TotalAmount = 0 // 订单实收金额 sumData.StorePer = 0 // 门店提成 + sumData.TotalCashierData = nil //sumData.ScanAmount = cashier.ScanAmount //sumData.CashAmount = cashier.CashAmount @@ -4747,11 +4832,6 @@ func queryRetailDetailByJoin(req *ErpOrderRetailDetailReq, c *gin.Context) (*Erp //sumData.StoreVmAmount = cashier.StoreVmAmount //sumData.OtherAmount = cashier.OtherAmount - sumData.ScanAmount = 0 - sumData.CashAmount = 0 - sumData.PosAmount = 0 - sumData.StoreVmAmount = 0 - sumData.OtherAmount = 0 RoundRetailDetailTotalData(&sumData) var result []RetailDetailByJoin @@ -5091,10 +5171,51 @@ func queryRetailDetailCommon(req *ErpOrderRetailDetailReq, c *gin.Context) (*Erp // 计算销售订单和退货订单汇总后的提成数据 totalPerData = subtractTotalPerData(totalPerData, rejectedTotalPerData) + //// 销售订单支付汇总 + //var cashier TotalCashierData + //cashierQs := qs + //cashier, err = getTotalCashierData(cashierQs, RetailTypeSale) + //if err != nil { + // logger.Error("query erp_order_pay_way sum data err:", logger.Field("err", err)) + // return resp, err + //} + // + //// 支付方式筛选 + //if req.CashierId != 0 { + // var tempCashier TotalCashierData + // switch req.CashierId { + // case 1: + // tempCashier.ScanAmount = cashier.ScanAmount + // case 2: + // tempCashier.CashAmount = cashier.CashAmount + // case 3: + // tempCashier.PosAmount = cashier.PosAmount + // case 4: + // tempCashier.StoreVmAmount = cashier.StoreVmAmount + // default: + // tempCashier = cashier + // } + // cashier = tempCashier + //} + // + //// 退货订单支付汇总:目前零售退货订单暂时不展示各个方式的付款金额 + //var rejectedCashier TotalCashierData + //rejectedCashierQs := qs + //rejectedCashier, err = getTotalCashierData(rejectedCashierQs, RetailTypeRejected) + //if err != nil { + // logger.Error("query erp_order_pay_way sum data err:", logger.Field("err", err)) + // return resp, err + //} + //// 计算销售订单和退货订单汇总后的支付数据 + //cashier = subtractCashierData(cashier, rejectedCashier) + // + //// 处理汇总数据,四舍五入保留2位小数 + //roundValues(&sumData, &totalPerData, &cashier) + // 销售订单支付汇总 - var cashier TotalCashierData + var cashierData []ErpOrderCashier cashierQs := qs - cashier, err = getTotalCashierData(cashierQs, RetailTypeSale) + cashierData, err = getTotalCashierData(cashierQs, RetailTypeSale) if err != nil { logger.Error("query erp_order_pay_way sum data err:", logger.Field("err", err)) return resp, err @@ -5102,43 +5223,34 @@ func queryRetailDetailCommon(req *ErpOrderRetailDetailReq, c *gin.Context) (*Erp // 支付方式筛选 if req.CashierId != 0 { - var tempCashier TotalCashierData - switch req.CashierId { - case 1: - tempCashier.ScanAmount = cashier.ScanAmount - case 2: - tempCashier.CashAmount = cashier.CashAmount - case 3: - tempCashier.PosAmount = cashier.PosAmount - case 4: - tempCashier.StoreVmAmount = cashier.StoreVmAmount - default: - tempCashier = cashier + var filteredData []ErpOrderCashier + for _, cashier := range cashierData { + if cashier.CashierId == req.CashierId { + filteredData = append(filteredData, cashier) + } } - cashier = tempCashier + cashierData = filteredData } // 退货订单支付汇总:目前零售退货订单暂时不展示各个方式的付款金额 - var rejectedCashier TotalCashierData + var rejectedCashierData []ErpOrderCashier rejectedCashierQs := qs - rejectedCashier, err = getTotalCashierData(rejectedCashierQs, RetailTypeRejected) + rejectedCashierData, err = getTotalCashierData(rejectedCashierQs, RetailTypeRejected) if err != nil { logger.Error("query erp_order_pay_way sum data err:", logger.Field("err", err)) return resp, err } + // 计算销售订单和退货订单汇总后的支付数据 - cashier = subtractCashierData(cashier, rejectedCashier) + cashierData = subtractCashierData(cashierData, rejectedCashierData) // 处理汇总数据,四舍五入保留2位小数 - roundValues(&sumData, &totalPerData, &cashier) + roundValues(&sumData, &totalPerData) + sumData.TotalSalesProfitPer = totalPerData.TotalSalesProfitPer sumData.TotalStaffProfitPer = totalPerData.TotalStaffProfitPer sumData.SalesmanPer = totalPerData.SalesmanPer - sumData.ScanAmount = cashier.ScanAmount - sumData.CashAmount = cashier.CashAmount - sumData.PosAmount = cashier.PosAmount - sumData.StoreVmAmount = cashier.StoreVmAmount - sumData.OtherAmount = cashier.OtherAmount + sumData.TotalCashierData = cashierData RoundRetailDetailTotalData(&sumData) if req.IsExport == 1 { // 导出excel @@ -5205,17 +5317,12 @@ func queryRetailDetailCommon(req *ErpOrderRetailDetailReq, c *gin.Context) (*Erp } // 四舍五入保留2位小数 -func roundValues(data *RetailDetailTotalData, totalPerData *TotalPerData, cashier *TotalCashierData) { +func roundValues(data *RetailDetailTotalData, totalPerData *TotalPerData) { roundMap := map[*float64]*float64{ &data.StorePer: &data.StorePer, &totalPerData.TotalSalesProfitPer: &totalPerData.TotalSalesProfitPer, &totalPerData.TotalStaffProfitPer: &totalPerData.TotalStaffProfitPer, &totalPerData.SalesmanPer: &totalPerData.SalesmanPer, - &cashier.ScanAmount: &cashier.ScanAmount, - &cashier.CashAmount: &cashier.CashAmount, - &cashier.PosAmount: &cashier.PosAmount, - &cashier.StoreVmAmount: &cashier.StoreVmAmount, - &cashier.OtherAmount: &cashier.OtherAmount, } for original, rounded := range roundMap { @@ -5223,6 +5330,25 @@ func roundValues(data *RetailDetailTotalData, totalPerData *TotalPerData, cashie } } +//// 四舍五入保留2位小数 +//func roundValues(data *RetailDetailTotalData, totalPerData *TotalPerData, cashier *TotalCashierData) { +// roundMap := map[*float64]*float64{ +// &data.StorePer: &data.StorePer, +// &totalPerData.TotalSalesProfitPer: &totalPerData.TotalSalesProfitPer, +// &totalPerData.TotalStaffProfitPer: &totalPerData.TotalStaffProfitPer, +// &totalPerData.SalesmanPer: &totalPerData.SalesmanPer, +// &cashier.ScanAmount: &cashier.ScanAmount, +// &cashier.CashAmount: &cashier.CashAmount, +// &cashier.PosAmount: &cashier.PosAmount, +// &cashier.StoreVmAmount: &cashier.StoreVmAmount, +// &cashier.OtherAmount: &cashier.OtherAmount, +// } +// +// for original, rounded := range roundMap { +// *rounded = tools.RoundToTwoDecimalPlaces(*original) +// } +//} + // RoundRetailDetailTotalData 将 RetailDetailTotalData 中所有 float64 字段保留两位小数 func RoundRetailDetailTotalData(data *RetailDetailTotalData) { data.RetailPrice = tools.RoundToTwoDecimalPlaces(data.RetailPrice) @@ -5244,11 +5370,15 @@ func RoundRetailDetailTotalData(data *RetailDetailTotalData) { data.StorePer = tools.RoundToTwoDecimalPlaces(data.StorePer) // 处理TotalCashierData中的float64 - data.ScanAmount = tools.RoundToTwoDecimalPlaces(data.ScanAmount) - data.CashAmount = tools.RoundToTwoDecimalPlaces(data.CashAmount) - data.PosAmount = tools.RoundToTwoDecimalPlaces(data.PosAmount) - data.StoreVmAmount = tools.RoundToTwoDecimalPlaces(data.StoreVmAmount) - data.OtherAmount = tools.RoundToTwoDecimalPlaces(data.OtherAmount) + //data.ScanAmount = tools.RoundToTwoDecimalPlaces(data.ScanAmount) + //data.CashAmount = tools.RoundToTwoDecimalPlaces(data.CashAmount) + //data.PosAmount = tools.RoundToTwoDecimalPlaces(data.PosAmount) + //data.StoreVmAmount = tools.RoundToTwoDecimalPlaces(data.StoreVmAmount) + //data.OtherAmount = tools.RoundToTwoDecimalPlaces(data.OtherAmount) + + for i, value := range data.TotalCashierData { + data.TotalCashierData[i].Amount = tools.RoundToTwoDecimalPlaces(value.Amount) + } // 处理TotalPerData中的float64 data.TotalSalesProfitPer = tools.RoundToTwoDecimalPlaces(data.TotalSalesProfitPer) @@ -5403,22 +5533,61 @@ func getTotalPerData(qs *gorm.DB, retailType string) (TotalPerData, error) { return totalPerData, nil } +//// 查询零售订单的支付汇总数据 +//func getTotalCashierData(qs *gorm.DB, retailType string) (TotalCashierData, error) { +// var cashier TotalCashierData +// err := qs.Debug().Select( +// "SUM(CASE WHEN erp_order_pay_way.cashier_id = 1 THEN erp_order_pay_way.amount ELSE 0 END) AS scan_amount,"+ +// "SUM(CASE WHEN erp_order_pay_way.cashier_id = 2 THEN erp_order_pay_way.amount ELSE 0 END) AS cash_amount,"+ +// "SUM(CASE WHEN erp_order_pay_way.cashier_id = 3 THEN erp_order_pay_way.amount ELSE 0 END) AS pos_amount,"+ +// "SUM(CASE WHEN erp_order_pay_way.cashier_id = 4 THEN erp_order_pay_way.amount ELSE 0 END) AS store_vm_amount,"+ +// "SUM(CASE WHEN erp_order_pay_way.cashier_id not in (1,2,3,4) THEN erp_order_pay_way.amount ELSE 0 END) AS other_amount"). +// Joins("JOIN erp_order_pay_way ON erp_order_pay_way.erp_order_id = erp_order.id and erp_order.retail_type = ?", retailType). +// Scan(&cashier).Error +// if err != nil { +// logger.Error("query erp_order_pay_way sum data err:", logger.Field("err", err)) +// return cashier, err +// } +// return cashier, nil +//} + // 查询零售订单的支付汇总数据 -func getTotalCashierData(qs *gorm.DB, retailType string) (TotalCashierData, error) { - var cashier TotalCashierData - err := qs.Debug().Select( - "SUM(CASE WHEN erp_order_pay_way.cashier_id = 1 THEN erp_order_pay_way.amount ELSE 0 END) AS scan_amount,"+ - "SUM(CASE WHEN erp_order_pay_way.cashier_id = 2 THEN erp_order_pay_way.amount ELSE 0 END) AS cash_amount,"+ - "SUM(CASE WHEN erp_order_pay_way.cashier_id = 3 THEN erp_order_pay_way.amount ELSE 0 END) AS pos_amount,"+ - "SUM(CASE WHEN erp_order_pay_way.cashier_id = 4 THEN erp_order_pay_way.amount ELSE 0 END) AS store_vm_amount,"+ - "SUM(CASE WHEN erp_order_pay_way.cashier_id not in (1,2,3,4) THEN erp_order_pay_way.amount ELSE 0 END) AS other_amount"). - Joins("JOIN erp_order_pay_way ON erp_order_pay_way.erp_order_id = erp_order.id and erp_order.retail_type = ?", retailType). - Scan(&cashier).Error +func getTotalCashierData(qs *gorm.DB, retailType string) ([]ErpOrderCashier, error) { + var results []ErpOrderCashier + err := qs.Debug(). + Select("erp_order_pay_way.cashier_id AS cashier_id, erp_cashier.name AS name, SUM(erp_order_pay_way.amount) AS amount"). + Joins("JOIN erp_order_pay_way ON erp_order_pay_way.erp_order_id = erp_order.id AND erp_order.retail_type = ?", retailType). + Joins("JOIN erp_cashier ON erp_cashier.id = erp_order_pay_way.cashier_id"). + Group("erp_order_pay_way.cashier_id, erp_cashier.name"). + Scan(&results).Error if err != nil { logger.Error("query erp_order_pay_way sum data err:", logger.Field("err", err)) - return cashier, err + return nil, err } - return cashier, nil + + // 查询所有支付方式 + var sysCashierList []ErpCashier + err = orm.Eloquent.Table("erp_cashier").Order("id ASC").Find(&sysCashierList).Error + if err != nil { + return nil, err + } + + var resp []ErpOrderCashier + for _, value := range sysCashierList { + var data ErpOrderCashier + data.CashierId = value.ID + data.Name = value.Name + for _, item := range results { + if value.ID == item.CashierId { + data.Amount = item.Amount + } else { + continue + } + } + resp = append(resp, data) + } + + return resp, nil } // 计算销售订单和退货订单汇总后的销售数据 @@ -5467,15 +5636,41 @@ func subtractTotalPerData(totalPerData, rejectedTotalPerData TotalPerData) Total return result } -// 计算销售订单和退货订单汇总后的支付数据 -func subtractCashierData(cashier, rejectedCashier TotalCashierData) TotalCashierData { - result := TotalCashierData{ - ScanAmount: cashier.ScanAmount - rejectedCashier.ScanAmount, - CashAmount: cashier.CashAmount - rejectedCashier.CashAmount, - PosAmount: cashier.PosAmount - rejectedCashier.PosAmount, - StoreVmAmount: cashier.StoreVmAmount - rejectedCashier.StoreVmAmount, - OtherAmount: cashier.OtherAmount - rejectedCashier.OtherAmount, +//// 计算销售订单和退货订单汇总后的支付数据 +//func subtractCashierData(cashier, rejectedCashier TotalCashierData) TotalCashierData { +// result := TotalCashierData{ +// ScanAmount: cashier.ScanAmount - rejectedCashier.ScanAmount, +// CashAmount: cashier.CashAmount - rejectedCashier.CashAmount, +// PosAmount: cashier.PosAmount - rejectedCashier.PosAmount, +// StoreVmAmount: cashier.StoreVmAmount - rejectedCashier.StoreVmAmount, +// OtherAmount: cashier.OtherAmount - rejectedCashier.OtherAmount, +// } +// return result +//} + +// subtractCashierData 计算销售订单和退货订单汇总后的支付数据 +func subtractCashierData(cashierData, rejectedCashierData []ErpOrderCashier) []ErpOrderCashier { + // 将退货数据转换为 map 便于查找 + rejectedMap := make(map[uint32]float64) + for _, rejected := range rejectedCashierData { + rejectedMap[rejected.CashierId] = rejected.Amount } + + // 减去退货数据的金额 + var result []ErpOrderCashier + for _, cashier := range cashierData { + adjustedAmount := cashier.Amount - rejectedMap[cashier.CashierId] + // 如果金额为负数则视为零 + if adjustedAmount < 0 { + adjustedAmount = 0 + } + result = append(result, ErpOrderCashier{ + CashierId: cashier.CashierId, + Name: cashier.Name, + Amount: adjustedAmount, + }) + } + return result } @@ -7346,12 +7541,13 @@ func querySaleDetailByJoin(req *ErpOrderSaleDetailReq, c *gin.Context) (*ErpOrde sumData.TotalDiscount = 0 // 订单总优惠 sumData.TotalAmount = 0 // 订单实收金额 sumData.StorePer = 0 // 门店提成 + sumData.TotalCashierData = nil - sumData.ScanAmount = 0 - sumData.CashAmount = 0 - sumData.PosAmount = 0 - sumData.StoreVmAmount = 0 - sumData.OtherAmount = 0 + //sumData.ScanAmount = 0 + //sumData.CashAmount = 0 + //sumData.PosAmount = 0 + //sumData.StoreVmAmount = 0 + //sumData.OtherAmount = 0 RoundRetailDetailTotalData(&sumData) var result []RetailDetailByJoin diff --git a/app/admin/models/sysuser.go b/app/admin/models/sysuser.go index a1cb009..fe6e7e7 100644 --- a/app/admin/models/sysuser.go +++ b/app/admin/models/sysuser.go @@ -270,7 +270,7 @@ type SysUserListResp struct { List []SysUserPage `json:"list"` // 采购报表信息 } -func (e *SysUser) GetPage(pageSize int, pageIndex int, exportFlag int) ([]SysUserPage, int, string, error) { +func (e *SysUser) GetPage(pageSize int, pageIndex int, exportFlag int, storeList []int) ([]SysUserPage, int, string, error) { if e.ShopperCode != "" { var shopperCode ShopperPromotionCode err := orm.Eloquent.Table("shopper_promotion_code").Where("code = ?", e.ShopperCode).Find(&shopperCode).Error @@ -311,8 +311,26 @@ func (e *SysUser) GetPage(pageSize int, pageIndex int, exportFlag int) ([]SysUse table = table.Where("sys_user.nick_name = ?", e.NickName) } - if e.StoreId != 0 { - table = table.Where("JSON_CONTAINS(store_data, ?)", fmt.Sprintf(`{"storeId":%d}`, e.StoreId)) + //if e.StoreId != 0 { + // table = table.Where("JSON_CONTAINS(store_data, ?)", fmt.Sprintf(`{"storeId":%d}`, e.StoreId)) + //} + + // 假设 e.StoreId 是 []int 类型 + if len(storeList) > 0 { + // 在 SQL 查询中使用 JSON_CONTAINS + // 如果需要匹配多个 storeId,可以使用 OR 连接条件 + var conditions []string + for _, storeId := range storeList { + condition := fmt.Sprintf("JSON_CONTAINS(store_data, '{\"storeId\": %d}')", storeId) + conditions = append(conditions, condition) + } + + // 使用 OR 连接多个查询条件 + // 最终的查询条件形如:JSON_CONTAINS(store_data, '{"storeId": 13}') OR JSON_CONTAINS(store_data, '{"storeId": 19}') + queryCondition := strings.Join(conditions, " OR ") + + // 将构造好的条件传递给 WHERE 子句 + table = table.Where(queryCondition) } if e.DeptId != 0 {