From 4e47b69ef122a094b4b7b5a41bb1742db6ac60d6 Mon Sep 17 00:00:00 2001 From: chenlin Date: Tue, 5 Nov 2024 15:51:30 +0800 Subject: [PATCH] =?UTF-8?q?1=E3=80=81=E9=9B=B6=E5=94=AE=E6=98=8E=E7=BB=86e?= =?UTF-8?q?xcel=E5=AF=BC=E5=87=BA=E4=BC=98=E5=8C=96=EF=BC=8C=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=E5=95=86=E5=93=81=E5=88=86=E7=B1=BB=E7=BA=A7=E5=88=AB?= =?UTF-8?q?=EF=BC=881=E7=BA=A7/2=E7=BA=A7/3=E7=BA=A7=EF=BC=89=EF=BC=8C?= =?UTF-8?q?=E5=A1=AB=E5=85=85=E7=A9=BA=E7=99=BD=E8=A1=8C=EF=BC=9B=202?= =?UTF-8?q?=E3=80=81=E4=BC=98=E5=8C=96=E9=87=87=E8=B4=AD=E6=8A=A5=E8=A1=A8?= =?UTF-8?q?=EF=BC=88=E6=8C=89=E5=8D=95=EF=BC=89=EF=BC=8C=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E5=85=A5=E5=BA=93=E6=97=B6=E9=97=B4=E5=AD=97=E6=AE=B5=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/admin/models/erp_order.go | 397 +++++++++++++++++++++------------- app/admin/models/purchase.go | 138 ++++++++---- app/admin/models/user.go | 1 + docs/docs.go | 45 +--- docs/swagger.json | 45 +--- docs/swagger.yaml | 35 +-- 6 files changed, 366 insertions(+), 295 deletions(-) diff --git a/app/admin/models/erp_order.go b/app/admin/models/erp_order.go index 25312d0..7801f86 100644 --- a/app/admin/models/erp_order.go +++ b/app/admin/models/erp_order.go @@ -3519,54 +3519,70 @@ func retailDetailExport(list []ErpOrder, sumData RetailDetailTotalData, c *gin.C flag10, _ := checkRoleMenu(c, DetailStorePerMenu) nEndCount := 0 - title := []interface{}{"订单编号", "订单类型", "用户ID", "客户手机号", "审核时间", "店铺", "银联流水号", "销售员", "商品分类", "商品名称", + title := []interface{}{"订单编号", "订单类型", "用户ID", "客户手机号", "审核时间", "店铺", "银联流水号", "销售员1", "销售员2", "商品分类", "", "", "商品名称", + "供应商", "是否串码", "商品串码", "是否赠送", "销售数量", "指导零售价", "零售价", "零售优惠", "会员优惠", "实际零售价/退货价"} + + title2 := []interface{}{"订单编号", "订单类型", "用户ID", "客户手机号", "审核时间", "店铺", "银联流水号", "销售员1", "销售员2", "一级分类", "二级分类", "三级分类", "商品名称", "供应商", "是否串码", "商品串码", "是否赠送", "销售数量", "指导零售价", "零售价", "零售优惠", "会员优惠", "实际零售价/退货价"} if flag1 { // 采购单价 title = append(title, "采购单价") + title2 = append(title2, "采购单价") nEndCount += 1 } if flag2 { // 员工成本价 title = append(title, "员工成本价") + title2 = append(title2, "员工成本价") nEndCount += 1 } if flag3 { // 销售毛利 title = append(title, "销售毛利") + title2 = append(title2, "销售毛利") nEndCount += 1 } if flag4 { // 员工毛利 title = append(title, "员工毛利") + title2 = append(title2, "员工毛利") nEndCount += 1 } title = append(title, "订单总指导零售价", "订单总优惠", "订单实收", "【扫码付", "现金收款", "pos机收款", "商场积分抵扣", "其他付款方式】") + title2 = append(title2, "订单总指导零售价", "订单总优惠", "订单实收", "【扫码付", "现金收款", "pos机收款", + "商场积分抵扣", "其他付款方式】") if flag5 { // 订单总销售毛利 title = append(title, "订单总销售毛利") + title2 = append(title2, "订单总销售毛利") nEndCount += 1 } if flag6 { // 订单总员工毛利 title = append(title, "订单总员工毛利") + title2 = append(title2, "订单总员工毛利") nEndCount += 1 } if flag7 { // 销售毛利提成 title = append(title, "销售毛利提成") + title2 = append(title2, "销售毛利提成") nEndCount += 1 } if flag8 { // 员工毛利提成 title = append(title, "员工毛利提成") + title2 = append(title2, "员工毛利提成") nEndCount += 1 } if flag9 { // 销售员提成 title = append(title, "销售员提成") + title2 = append(title2, "销售员提成") nEndCount += 1 } if flag10 { // 门店提成 title = append(title, "门店提成") + title2 = append(title2, "门店提成") nEndCount += 1 } title = append(title, "备注") + title2 = append(title2, "备注") for i, _ := range title { cell, _ := excelize.CoordinatesToCellName(1+i, 1) @@ -3576,6 +3592,14 @@ func retailDetailExport(list []ErpOrder, sumData RetailDetailTotalData, c *gin.C } } + for i, _ := range title2 { + cell, _ := excelize.CoordinatesToCellName(1+i, 2) + err := file.SetCellValue(fSheet, cell, title2[i]) + if err != nil { + logger.Error("file set value err:", logger.Field("err", err)) + } + } + var row []interface{} nAmount := 0.0 nExcelStartRow := 0 @@ -3600,6 +3624,25 @@ func retailDetailExport(list []ErpOrder, sumData RetailDetailTotalData, c *gin.C list[i].CashierList = "" // 目前零售退货订单暂时不展示各个方式的付款金额 } + // 用户id + var userId string + if list[i].Uid != 0 { + userId = strconv.Itoa(list[i].Uid) + } else { + userId = "" + } + + // 审核时间 + var auditTime string + if list[i].AuditTime != nil { + auditTime = list[i].AuditTime.Format(ExcelTimeFormat) + } else { + auditTime = "" + } + + // 商品分类 + categoryLevels, _ := GetCategoryLevels(list[i].Commodities[rowId].ErpCategoryId) + isIMEIType := "是" if list[i].Commodities[rowId].IMEIType == 1 { isIMEIType = "否" @@ -3635,12 +3678,16 @@ func retailDetailExport(list []ErpOrder, sumData RetailDetailTotalData, c *gin.C // 单个订单的汇总数据只记录一次 if !orderFlag { orderFlag = true - salesMan := "" + salesMan1 := "" + salesMan2 := "" nSalesProfitPer := 0.0 nStaffProfitPer := 0.0 nSalesmanPer := 0.0 if len(list[i].Salesman) > 0 { - salesMan = list[i].Salesman[0].Name + salesMan1 = list[i].Salesman[0].Name + if len(list[i].Salesman) == 2 { + salesMan2 = list[i].Salesman[1].Name + } nSalesProfitPer = math.Round(list[i].Salesman[0].SalesProfitPer*100) / 100 nStaffProfitPer = math.Round(list[i].Salesman[0].StaffProfitPer*100) / 100 nSalesmanPer = math.Round(list[i].Salesman[0].SalesmanPer*100) / 100 @@ -3648,13 +3695,16 @@ func retailDetailExport(list []ErpOrder, sumData RetailDetailTotalData, c *gin.C row = []interface{}{ list[i].BillSn, saleType, - list[i].Uid, + userId, list[i].Tel, - list[i].AuditTime, + auditTime, list[i].StoreName, list[i].BankTrxNo, - salesMan, //销售员 - list[i].Commodities[rowId].ErpCategoryName, + salesMan1, //销售员1 + salesMan2, //销售员2 + categoryLevels.Level1.Name, // 一级分类 + categoryLevels.Level2.Name, // 二级分类 + categoryLevels.Level3.Name, // 三级分类 list[i].Commodities[rowId].ErpCommodityName, list[i].Commodities[rowId].ErpSupplierName, //供应商 isIMEIType, @@ -3736,15 +3786,18 @@ func retailDetailExport(list []ErpOrder, sumData RetailDetailTotalData, c *gin.C } else { if len(list[i].Salesman) == 2 && rowId == 1 { row = []interface{}{ - "", - "", - "", - "", - "", - "", - "", - list[i].Salesman[1].Name, //销售员 - list[i].Commodities[rowId].ErpCategoryName, + list[i].BillSn, + saleType, + userId, + list[i].Tel, + auditTime, + list[i].StoreName, + list[i].BankTrxNo, + list[i].Salesman[0].Name, //销售员1 + list[i].Salesman[1].Name, //销售员2 + categoryLevels.Level1.Name, // 一级分类 + categoryLevels.Level2.Name, // 二级分类 + categoryLevels.Level3.Name, // 三级分类 list[i].Commodities[rowId].ErpCommodityName, list[i].Commodities[rowId].ErpSupplierName, //供应商 isIMEIType, @@ -3825,15 +3878,18 @@ func retailDetailExport(list []ErpOrder, sumData RetailDetailTotalData, c *gin.C row = append(row, "") } else { row = []interface{}{ - "", - "", - "", - "", - "", - "", - "", - "", //销售员 - list[i].Commodities[rowId].ErpCategoryName, + list[i].BillSn, + saleType, + userId, + list[i].Tel, + auditTime, + list[i].StoreName, + list[i].BankTrxNo, + list[i].Salesman[0].Name, //销售员1 + "", //销售员2 + categoryLevels.Level1.Name, // 一级分类 + categoryLevels.Level2.Name, // 二级分类 + categoryLevels.Level3.Name, // 三级分类 list[i].Commodities[rowId].ErpCommodityName, list[i].Commodities[rowId].ErpSupplierName, //供应商 isIMEIType, @@ -3916,7 +3972,7 @@ func retailDetailExport(list []ErpOrder, sumData RetailDetailTotalData, c *gin.C } for j, _ := range row { - cell, _ := excelize.CoordinatesToCellName(1+j, nExcelStartRow+2) + 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)) @@ -3924,110 +3980,110 @@ func retailDetailExport(list []ErpOrder, sumData RetailDetailTotalData, c *gin.C } nExcelStartRow++ - if len(list[i].Commodities) == 1 && len(list[i].Salesman) == 2 { - row = []interface{}{ - "", - "", - "", - "", - "", - "", - "", - list[i].Salesman[1].Name, //销售员 - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - - //"", - //"", - //"", - //"", - - //"", - //"", - //"", - //"", - //"", - //"", - //"", - //"", - - //"", - //"", - //math.Round(list[i].Salesman[1].SalesProfitPer*100) / 100, // 销售毛利提成 - //math.Round(list[i].Salesman[1].StaffProfitPer*100) / 100, // 员工毛利提成 - //math.Round(list[i].Salesman[1].SalesmanPer*100) / 100, // 销售员提成 - //"", - - //"", - } - // 控制是否导出 - if flag1 { // 采购单价 - row = append(row, "") - } - if flag2 { // 员工成本价 - row = append(row, "") - } - if flag3 { // 销售毛利 - row = append(row, "") - } - if flag4 { // 员工毛利 - row = append(row, "") - } - - row = append(row, "") - row = append(row, "") - row = append(row, "") - row = append(row, "") - row = append(row, "") - row = append(row, "") - row = append(row, "") - row = append(row, "") - - if flag5 { // 订单总销售毛利 - row = append(row, "") - } - if flag6 { // 订单总员工毛利 - row = append(row, "") - } - if flag7 { // 销售毛利提成 - row = append(row, math.Round(list[i].Salesman[1].SalesProfitPer*100)/100) - } - if flag8 { // 员工毛利提成 - row = append(row, math.Round(list[i].Salesman[1].StaffProfitPer*100)/100) - } - if flag9 { // 销售员提成 - row = append(row, math.Round(list[i].Salesman[1].SalesmanPer*100)/100) - } - if flag10 { // 门店提成 - row = append(row, "") - } - - row = append(row, "") - - 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++ - } + //if len(list[i].Commodities) == 1 && len(list[i].Salesman) == 2 { + // row = []interface{}{ + // "", + // "", + // "", + // "", + // "", + // "", + // "", + // list[i].Salesman[1].Name, //销售员 + // "", + // "", + // "", + // "", + // "", + // "", + // "", + // "", + // "", + // "", + // "", + // "", + // + // //"", + // //"", + // //"", + // //"", + // + // //"", + // //"", + // //"", + // //"", + // //"", + // //"", + // //"", + // //"", + // + // //"", + // //"", + // //math.Round(list[i].Salesman[1].SalesProfitPer*100) / 100, // 销售毛利提成 + // //math.Round(list[i].Salesman[1].StaffProfitPer*100) / 100, // 员工毛利提成 + // //math.Round(list[i].Salesman[1].SalesmanPer*100) / 100, // 销售员提成 + // //"", + // + // //"", + // } + // // 控制是否导出 + // if flag1 { // 采购单价 + // row = append(row, "") + // } + // if flag2 { // 员工成本价 + // row = append(row, "") + // } + // if flag3 { // 销售毛利 + // row = append(row, "") + // } + // if flag4 { // 员工毛利 + // row = append(row, "") + // } + // + // row = append(row, "") + // row = append(row, "") + // row = append(row, "") + // row = append(row, "") + // row = append(row, "") + // row = append(row, "") + // row = append(row, "") + // row = append(row, "") + // + // if flag5 { // 订单总销售毛利 + // row = append(row, "") + // } + // if flag6 { // 订单总员工毛利 + // row = append(row, "") + // } + // if flag7 { // 销售毛利提成 + // row = append(row, math.Round(list[i].Salesman[1].SalesProfitPer*100)/100) + // } + // if flag8 { // 员工毛利提成 + // row = append(row, math.Round(list[i].Salesman[1].StaffProfitPer*100)/100) + // } + // if flag9 { // 销售员提成 + // row = append(row, math.Round(list[i].Salesman[1].SalesmanPer*100)/100) + // } + // if flag10 { // 门店提成 + // row = append(row, "") + // } + // + // row = append(row, "") + // + // 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, "", "", "", "", "", "", "", "", "", "", "", "", "", + end := []interface{}{totalData, "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", sumData.Count, sumData.RetailPrice, sumData.SalePrice, @@ -4104,58 +4160,93 @@ func retailDetailExport(list []ErpOrder, sumData RetailDetailTotalData, c *gin.C end = append(end, "") for i, _ := range end { - cell, _ := excelize.CoordinatesToCellName(1+i, nExcelStartRow+2) + cell, _ := excelize.CoordinatesToCellName(1+i, nExcelStartRow+3) 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"}}`) - - // 设置单元格的样式: 居中、加边框、自动换行 - style1, _ := file.NewStyle(`{"alignment":{"horizontal":"center","vertical":"center","wrap_text":true}}`) + //style, _ := file.NewStyle(`{"alignment":{"horizontal":"center","vertical":"center"}}`) + 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}]}`) var endRow string switch nEndCount { case 1: - endRow = fmt.Sprintf("AD"+"%d", nExcelStartRow+2) + endRow = fmt.Sprintf("AG"+"%d", nExcelStartRow+3) case 2: - endRow = fmt.Sprintf("AE"+"%d", nExcelStartRow+2) + endRow = fmt.Sprintf("AH"+"%d", nExcelStartRow+3) case 3: - endRow = fmt.Sprintf("AF"+"%d", nExcelStartRow+2) + endRow = fmt.Sprintf("AI"+"%d", nExcelStartRow+3) case 4: - endRow = fmt.Sprintf("AG"+"%d", nExcelStartRow+2) + endRow = fmt.Sprintf("AJ"+"%d", nExcelStartRow+3) case 5: - endRow = fmt.Sprintf("AH"+"%d", nExcelStartRow+2) + endRow = fmt.Sprintf("AK"+"%d", nExcelStartRow+3) case 6: - endRow = fmt.Sprintf("AI"+"%d", nExcelStartRow+2) + endRow = fmt.Sprintf("AL"+"%d", nExcelStartRow+3) case 7: - endRow = fmt.Sprintf("AJ"+"%d", nExcelStartRow+2) + endRow = fmt.Sprintf("AM"+"%d", nExcelStartRow+3) case 8: - endRow = fmt.Sprintf("AK"+"%d", nExcelStartRow+2) + endRow = fmt.Sprintf("AN"+"%d", nExcelStartRow+3) case 9: - endRow = fmt.Sprintf("AL"+"%d", nExcelStartRow+2) + endRow = fmt.Sprintf("AO"+"%d", nExcelStartRow+3) case 10: - endRow = fmt.Sprintf("AM"+"%d", nExcelStartRow+2) + endRow = fmt.Sprintf("AP"+"%d", nExcelStartRow+3) default: - endRow = fmt.Sprintf("AC"+"%d", nExcelStartRow+2) + endRow = fmt.Sprintf("AF"+"%d", nExcelStartRow+3) } //endRow := fmt.Sprintf("AL%d", nExcelStartRow+2) // 应用样式到整个表格 _ = file.SetCellStyle("Sheet1", "A1", endRow, style) + // 设置单元格的样式: 居中、加边框、自动换行 + //style1, _ := file.NewStyle(`{"alignment":{"horizontal":"center","vertical":"center","wrap_text":true}}`) + 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}]}`) + //需要自动换行的列 - endRow1 := fmt.Sprintf("H%d", nExcelStartRow+2) - endRow2 := fmt.Sprintf("AI%d", nExcelStartRow+2) - endRow3 := fmt.Sprintf("AJ%d", nExcelStartRow+2) - endRow4 := fmt.Sprintf("AK%d", nExcelStartRow+2) - _ = file.SetCellStyle("Sheet1", "A1", "AM1", style1) - _ = file.SetCellStyle("Sheet1", "H2", endRow1, style1) + endRow2 := fmt.Sprintf("AI%d", nExcelStartRow+3) + endRow3 := fmt.Sprintf("AJ%d", nExcelStartRow+3) + endRow4 := fmt.Sprintf("AK%d", nExcelStartRow+3) + _ = file.SetCellStyle("Sheet1", "A1", "AN1", style1) _ = file.SetCellStyle("Sheet1", "AI2", endRow2, style1) _ = file.SetCellStyle("Sheet1", "AJ2", endRow3, style1) _ = file.SetCellStyle("Sheet1", "AK2", endRow4, style1) + // 合并单元格 + // 定义要排除的列 + excludeCols := map[string]bool{"J": true, "K": true, "L": true} + // 合并 J1-L1 + _ = file.MergeCell("Sheet1", "J1", "L1") + // 根据 nEndCount 动态合并列 + for i := 0; i < len(title); i++ { + // 获取当前列名 + currentCol := getExcelColumnName(i) + // 跳过 J、K、L 列(已通过 J1-L1 合并处理) + if excludeCols[currentCol] { + continue + } + + // 合并当前列的第 1 行和第 2 行 + startCell := fmt.Sprintf("%s1", currentCol) + endCell := fmt.Sprintf("%s2", currentCol) + _ = file.MergeCell("Sheet1", startCell, endCell) + } + + // 设置单元格大小 + file.SetColWidth("Sheet1", "A", "A", 15) + file.SetColWidth("Sheet1", "D", "D", 15) + file.SetColWidth("Sheet1", "E", "E", 18) + file.SetColWidth("Sheet1", "F", "F", 25) + file.SetColWidth("Sheet1", "G", "G", 25) + fmt.Println("save fileName:", config.ExportConfig.Path+fileName) if err := file.SaveAs(config.ExportConfig.Path + fileName); err != nil { fmt.Println(err) @@ -4163,6 +4254,16 @@ func retailDetailExport(list []ErpOrder, sumData RetailDetailTotalData, c *gin.C return url + fileName, nil } +// 生成Excel列名 +func getExcelColumnName(index int) string { + columnName := "" + for index >= 0 { + columnName = string(rune(index%26+'A')) + columnName + index = index/26 - 1 + } + return columnName +} + // RetailDetailByJoin 联表查询扫描参数 type RetailDetailByJoin struct { ErpOrderCommodity diff --git a/app/admin/models/purchase.go b/app/admin/models/purchase.go index 77901a5..423d154 100644 --- a/app/admin/models/purchase.go +++ b/app/admin/models/purchase.go @@ -399,9 +399,10 @@ type CommonData struct { // ErpPurchaseCommodityData 采购订单商品信息 type ErpPurchaseCommodityData struct { CommodityData - Amount float64 `json:"amount"` // 已执行金额 - Price float64 `json:"price"` // 已执行单价 - Count int32 `json:"count"` // 已执行数量 + Amount float64 `json:"amount"` // 已执行金额 + Price float64 `json:"price"` // 已执行单价 + Count int32 `json:"count"` // 已执行数量 + InventoryTime *time.Time `json:"inventory_time"` // 入库时间 } // ErpPurchaseReportByCommodityReq 采购报表(按商品)入参 @@ -3538,9 +3539,11 @@ func getReportByOrderFromCommon(req *ErpPurchaseReportByOrderReq, c *gin.Context //} reportByOrderData.Amount = nAmount + reportByOrderData.Amount = math.Round(reportByOrderData.Amount*100) / 100 reportByOrderData.Count = nCount if nCount != 0 { reportByOrderData.Price = nAmount / float64(nCount) + reportByOrderData.Price = math.Round(reportByOrderData.Price*100) / 100 } reportByOrderDataList = append(reportByOrderDataList, reportByOrderData) nTotalAmount += nAmount @@ -3681,12 +3684,17 @@ func getOrderInventoryInfo(req *ErpPurchaseReportByOrderReq, erpPurchaseOrderId //} // 使用 map 来组合相同 ErpCommodityId 的数据 - commodityMap := make(map[uint32]ErpPurchaseCommodityData) + //commodityMap := make(map[uint32]ErpPurchaseCommodityData) + commodityMap := make(map[uint32]map[time.Time]ErpPurchaseCommodityData) var nAmount float64 var nCount int32 // 遍历库存列表,组合相同 ErpCommodityId 的数据 for _, v := range inventoryList { + if _, exists := commodityMap[v.ErpCommodityId]; !exists { + commodityMap[v.ErpCommodityId] = make(map[time.Time]ErpPurchaseCommodityData) + } + var vCount int32 var vAmount float64 @@ -3706,24 +3714,26 @@ func getOrderInventoryInfo(req *ErpPurchaseReportByOrderReq, erpPurchaseOrderId vAmount = v.Amount } - if existingData, ok := commodityMap[v.ErpCommodityId]; ok { + if existingData, ok := commodityMap[v.ErpCommodityId][v.CreatedAt]; ok { // 如果已经存在相同 ErpCommodityId 的数据,则累加 Amount 和 Total existingData.Amount += vAmount existingData.Count += vCount existingData.Price = existingData.Amount / float64(existingData.Count) - commodityMap[v.ErpCommodityId] = existingData + commodityMap[v.ErpCommodityId][v.CreatedAt] = existingData } else { + inventoryTime := v.CreatedAt // 否则,创建新的数据 - commodityMap[v.ErpCommodityId] = ErpPurchaseCommodityData{ + commodityMap[v.ErpCommodityId][v.CreatedAt] = ErpPurchaseCommodityData{ CommodityData: CommodityData{ ErpCommodityId: v.ErpCommodityId, ErpCommodityName: v.ErpCommodityName, ErpCategoryID: v.ErpCategoryID, ErpCategoryName: v.ErpCategoryName, }, - Amount: vAmount, - Price: v.ImplementationPrice, - Count: vCount, + Amount: vAmount, + Price: v.ImplementationPrice, + Count: vCount, + InventoryTime: &inventoryTime, } } // 累加总金额和总数量 @@ -3753,7 +3763,11 @@ func getOrderInventoryInfo(req *ErpPurchaseReportByOrderReq, erpPurchaseOrderId } for _, v := range commodityList { - commodityMap[v.ErpCommodityId] = ErpPurchaseCommodityData{ + if _, exists := commodityMap[v.ErpCommodityId]; !exists { + commodityMap[v.ErpCommodityId] = make(map[time.Time]ErpPurchaseCommodityData) + } + + commodityMap[v.ErpCommodityId][v.CreatedAt] = ErpPurchaseCommodityData{ CommodityData: CommodityData{ ErpCommodityId: v.ErpCommodityId, ErpCommodityName: v.ErpCommodityName, @@ -3765,13 +3779,16 @@ func getOrderInventoryInfo(req *ErpPurchaseReportByOrderReq, erpPurchaseOrderId Count: 0, } } - } // 将 map 中的值转换为 slice var resp []ErpPurchaseCommodityData - for _, data := range commodityMap { - resp = append(resp, data) + for _, timeMap := range commodityMap { + for _, data := range timeMap { + data.Price = math.Round(data.Price*100) / 100 + data.Amount = math.Round(data.Amount*100) / 100 + resp = append(resp, data) + } } return resp, nAmount, nCount, nil @@ -3787,13 +3804,23 @@ func reportByOrderExport(req *ErpPurchaseReportByOrderResp) (string, error) { fmt.Println("url fileName:", url+fileName) // 组合标题栏数据 - title := []interface{}{"单据编号", "类型", "店铺名称", "备注", "供应商", "经手人", "制单人", "审核时间", "订单状态", - "商品名称", "商品分类", "已执行金额", "执行单价", "已执行数量"} - for i, _ := range title { + title1 := []interface{}{"单据编号", "类型", "店铺名称", "备注", "供应商", "经手人", "制单人", "审核时间", "订单状态", + "商品名称", "商品分类", "", "", "已执行金额", "执行单价", "已执行数量", "入库时间"} + title2 := []interface{}{"单据编号", "类型", "店铺名称", "备注", "供应商", "经手人", "制单人", "审核时间", "订单状态", + "商品名称", "一级分类", "二级分类", "三级分类", "已执行金额", "执行单价", "已执行数量", "入库时间"} + for i, _ := range title1 { cell, _ := excelize.CoordinatesToCellName(1+i, 1) - err := file.SetCellValue(fSheet, cell, title[i]) + err := file.SetCellValue(fSheet, cell, title1[i]) if err != nil { - logger.Error("file set value err:", logger.Field("err", err)) + 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) } } @@ -3825,9 +3852,9 @@ func reportByOrderExport(req *ErpPurchaseReportByOrderResp) (string, error) { var strTime string if orderData.AuditTime != nil { - strTime = orderData.AuditTime.Format(TimeFormat) + strTime = orderData.AuditTime.Format(ExcelTimeFormat) } else { - strTime = "--" + strTime = "" } row1 = []interface{}{ @@ -3840,15 +3867,18 @@ func reportByOrderExport(req *ErpPurchaseReportByOrderResp) (string, error) { orderData.MakerName, // 制单人 strTime, // 审核时间 orderStatus, // 订单状态 - "--", // 商品名称 - "--", // 商品分类 + "", // 商品名称 + "", // 一级分类 + "", // 二级分类 + "", // 三级分类 orderData.Amount, // 已执行金额 orderData.Price, // 执行单价 orderData.Count, // 已执行数量 + "", // 入库时间 } for j, _ := range row1 { - cell, _ := excelize.CoordinatesToCellName(1+j, nExcelStartRow+2) + cell, _ := excelize.CoordinatesToCellName(1+j, nExcelStartRow+3) err := file.SetCellValue(fSheet, cell, row1[j]) if err != nil { logger.Error("file set value err:", logger.Field("err", err)) @@ -3857,25 +3887,36 @@ func reportByOrderExport(req *ErpPurchaseReportByOrderResp) (string, error) { nExcelStartRow++ for _, commodity := range orderData.CommodityData { + var inventoryTime string + if commodity.InventoryTime != nil { + inventoryTime = commodity.InventoryTime.Format(ExcelTimeFormat) + } else { + inventoryTime = "" + } + + categoryLevels, _ := GetCategoryLevels(commodity.ErpCategoryID) row2 = []interface{}{ - "", // 单据编号 - "", // 类型 - "", // 店铺名称 - "", // 备注 - "", // 供应商 - "", // 经手人 - "", // 制单人 - "", // 审核时间 - "", // 订单状态 + orderData.SerialNumber, // 单据编号 + orderType, // 类型 + orderData.StoreName, // 店铺名称 + orderData.Remark, // 备注 + orderData.ErpSupplierName, // 供应商 + orderData.HandlerName, // 经手人 + orderData.MakerName, // 制单人 + strTime, // 审核时间 + orderStatus, // 订单状态 commodity.ErpCommodityName, // 商品名称 - commodity.ErpCategoryName, // 商品分类 + categoryLevels.Level1.Name, // 一级分类 + categoryLevels.Level2.Name, // 二级分类 + categoryLevels.Level3.Name, // 三级分类 commodity.Amount, // 已执行金额 commodity.Price, // 执行单价 commodity.Count, // 已执行数量 + inventoryTime, // 入库时间 } for j, _ := range row2 { - cell, _ := excelize.CoordinatesToCellName(1+j, nExcelStartRow+2) + cell, _ := excelize.CoordinatesToCellName(1+j, nExcelStartRow+3) err := file.SetCellValue(fSheet, cell, row2[j]) if err != nil { logger.Error("file set value err:", logger.Field("err", err)) @@ -3886,9 +3927,9 @@ func reportByOrderExport(req *ErpPurchaseReportByOrderResp) (string, error) { } totalData := "订单数:" + strconv.FormatInt(int64(req.Total), 10) - end := []interface{}{totalData, "", "", "", "", "", "", "", "", "", "", req.Amount, "--", req.Count} + end := []interface{}{totalData, "", "", "", "", "", "", "", "", "", "", "", "", req.Amount, "--", req.Count, ""} for i, _ := range end { - cell, _ := excelize.CoordinatesToCellName(1+i, nExcelStartRow+2) + cell, _ := excelize.CoordinatesToCellName(1+i, nExcelStartRow+3) err := file.SetCellValue(fSheet, cell, end[i]) if err != nil { logger.Error("file set value err:", logger.Field("err", err)) @@ -3902,6 +3943,24 @@ func reportByOrderExport(req *ErpPurchaseReportByOrderResp) (string, error) { {"type":"right","color":"000000","style":1}, {"type":"bottom","color":"000000","style":1}]}`) + // 合并单元格 + _ = file.MergeCell(fSheet, "A1", "A2") + _ = file.MergeCell(fSheet, "B1", "B2") + _ = file.MergeCell(fSheet, "C1", "C2") + _ = file.MergeCell(fSheet, "D1", "D2") + _ = file.MergeCell(fSheet, "E1", "E2") + _ = file.MergeCell(fSheet, "F1", "F2") + _ = file.MergeCell(fSheet, "G1", "G2") + _ = file.MergeCell(fSheet, "H1", "H2") + _ = file.MergeCell(fSheet, "I1", "I2") + _ = file.MergeCell(fSheet, "J1", "J2") + _ = file.MergeCell(fSheet, "N1", "N2") + _ = file.MergeCell(fSheet, "O1", "O2") + _ = file.MergeCell(fSheet, "P1", "P2") + _ = file.MergeCell(fSheet, "Q1", "Q2") + + _ = file.MergeCell(fSheet, "K1", "M1") + //设置单元格高度 file.SetRowHeight("Sheet1", 1, 20) @@ -3910,8 +3969,9 @@ func reportByOrderExport(req *ErpPurchaseReportByOrderResp) (string, error) { file.SetColWidth("Sheet1", "C", "C", 25) file.SetColWidth("Sheet1", "H", "H", 20) file.SetColWidth("Sheet1", "J", "J", 18) + file.SetColWidth("Sheet1", "Q", "Q", 20) - endRow := fmt.Sprintf("N"+"%d", nExcelStartRow+2) + endRow := fmt.Sprintf("Q"+"%d", nExcelStartRow+3) // 应用样式到整个表格 _ = file.SetCellStyle("Sheet1", "A1", endRow, style) @@ -4991,7 +5051,7 @@ func reportByCommodityExport(req *ErpPurchaseReportByCommodityResp) (string, err var strTime string if orderData.AuditTime != nil { - strTime = orderData.AuditTime.Format(TimeFormat) + strTime = orderData.AuditTime.Format(ExcelTimeFormat) } else { strTime = "--" } diff --git a/app/admin/models/user.go b/app/admin/models/user.go index 8a6d5ed..0abdca6 100644 --- a/app/admin/models/user.go +++ b/app/admin/models/user.go @@ -139,6 +139,7 @@ const ( const DateTimeFormat = "2006-01-02" const TimeFormat = "2006-01-02 15-04-05" +const ExcelTimeFormat = "2006-01-02 15:04:05" const QueryTimeFormat = "2006-01-02T15:04:05+08:00" const StoreDateTimeFormat = "2006.01.02" diff --git a/docs/docs.go b/docs/docs.go index 05f9236..94da3dc 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -9813,7 +9813,10 @@ const docTemplate = `{ }, "erp_category_id": { "description": "分类id", - "type": "integer" + "type": "array", + "items": { + "type": "integer" + } }, "erp_commodity_name": { "description": "商品名称", @@ -10299,25 +10302,13 @@ const docTemplate = `{ "description": "商品名称", "type": "string" }, - "first_erp_category_id": { - "description": "商品一级分类id", - "type": "integer" - }, - "first_erp_category_name": { - "description": "商品一级分类名称", + "inventory_time": { + "description": "入库时间", "type": "string" }, "price": { "description": "已执行单价", "type": "number" - }, - "second_erp_category_id": { - "description": "商品二级分类id", - "type": "integer" - }, - "second_erp_category_name": { - "description": "商品二级分类名称", - "type": "string" } } }, @@ -10885,10 +10876,6 @@ const docTemplate = `{ "type": "integer" } }, - "first_erp_category_id": { - "description": "商品一级分类id", - "type": "integer" - }, "handler_id": { "description": "经手人id", "type": "integer" @@ -10909,10 +10896,6 @@ const docTemplate = `{ "description": "采购类型:procure-采购 reject-退货", "type": "string" }, - "second_erp_category_id": { - "description": "商品二级分类id", - "type": "integer" - }, "serial_number": { "description": "单据编号", "type": "string" @@ -15383,14 +15366,6 @@ const docTemplate = `{ "description": "商品名称", "type": "string" }, - "first_erp_category_id": { - "description": "商品一级分类id", - "type": "integer" - }, - "first_erp_category_name": { - "description": "商品一级分类名称", - "type": "string" - }, "non_execution_amount": { "description": "未执行金额", "type": "number" @@ -15425,14 +15400,6 @@ const docTemplate = `{ "price": { "description": "已执行单价", "type": "number" - }, - "second_erp_category_id": { - "description": "商品二级分类id", - "type": "integer" - }, - "second_erp_category_name": { - "description": "商品二级分类名称", - "type": "string" } } }, diff --git a/docs/swagger.json b/docs/swagger.json index ac583b0..325a364 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -9802,7 +9802,10 @@ }, "erp_category_id": { "description": "分类id", - "type": "integer" + "type": "array", + "items": { + "type": "integer" + } }, "erp_commodity_name": { "description": "商品名称", @@ -10288,25 +10291,13 @@ "description": "商品名称", "type": "string" }, - "first_erp_category_id": { - "description": "商品一级分类id", - "type": "integer" - }, - "first_erp_category_name": { - "description": "商品一级分类名称", + "inventory_time": { + "description": "入库时间", "type": "string" }, "price": { "description": "已执行单价", "type": "number" - }, - "second_erp_category_id": { - "description": "商品二级分类id", - "type": "integer" - }, - "second_erp_category_name": { - "description": "商品二级分类名称", - "type": "string" } } }, @@ -10874,10 +10865,6 @@ "type": "integer" } }, - "first_erp_category_id": { - "description": "商品一级分类id", - "type": "integer" - }, "handler_id": { "description": "经手人id", "type": "integer" @@ -10898,10 +10885,6 @@ "description": "采购类型:procure-采购 reject-退货", "type": "string" }, - "second_erp_category_id": { - "description": "商品二级分类id", - "type": "integer" - }, "serial_number": { "description": "单据编号", "type": "string" @@ -15372,14 +15355,6 @@ "description": "商品名称", "type": "string" }, - "first_erp_category_id": { - "description": "商品一级分类id", - "type": "integer" - }, - "first_erp_category_name": { - "description": "商品一级分类名称", - "type": "string" - }, "non_execution_amount": { "description": "未执行金额", "type": "number" @@ -15414,14 +15389,6 @@ "price": { "description": "已执行单价", "type": "number" - }, - "second_erp_category_id": { - "description": "商品二级分类id", - "type": "integer" - }, - "second_erp_category_name": { - "description": "商品二级分类名称", - "type": "string" } } }, diff --git a/docs/swagger.yaml b/docs/swagger.yaml index 8ff1039..cfd4c02 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -2580,7 +2580,9 @@ definitions: type: string erp_category_id: description: 分类id - type: integer + items: + type: integer + type: array erp_commodity_name: description: 商品名称 type: string @@ -2931,21 +2933,12 @@ definitions: erp_commodity_name: description: 商品名称 type: string - first_erp_category_id: - description: 商品一级分类id - type: integer - first_erp_category_name: - description: 商品一级分类名称 + inventory_time: + description: 入库时间 type: string price: description: 已执行单价 type: number - second_erp_category_id: - description: 商品二级分类id - type: integer - second_erp_category_name: - description: 商品二级分类名称 - type: string type: object models.ErpPurchaseCreateReq: properties: @@ -3359,9 +3352,6 @@ definitions: items: type: integer type: array - first_erp_category_id: - description: 商品一级分类id - type: integer handler_id: description: 经手人id type: integer @@ -3377,9 +3367,6 @@ definitions: purchase_type: description: 采购类型:procure-采购 reject-退货 type: string - second_erp_category_id: - description: 商品二级分类id - type: integer serial_number: description: 单据编号 type: string @@ -6592,12 +6579,6 @@ definitions: erp_commodity_name: description: 商品名称 type: string - first_erp_category_id: - description: 商品一级分类id - type: integer - first_erp_category_name: - description: 商品一级分类名称 - type: string non_execution_amount: description: 未执行金额 type: number @@ -6624,12 +6605,6 @@ definitions: price: description: 已执行单价 type: number - second_erp_category_id: - description: 商品二级分类id - type: integer - second_erp_category_name: - description: 商品二级分类名称 - type: string type: object models.ReportByOrderData: properties: