report.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366
  1. package api
  2. import (
  3. "box-cost/db/model"
  4. "box-cost/db/repo"
  5. "errors"
  6. "fmt"
  7. "github.com/gin-gonic/gin"
  8. "github.com/xuri/excelize/v2"
  9. "go.mongodb.org/mongo-driver/bson"
  10. "go.mongodb.org/mongo-driver/bson/primitive"
  11. )
  12. // 统计报表
  13. func Report(r *GinRouter) {
  14. // 加工列表
  15. r.GET("/report/produce/list", ReportProduceList)
  16. // 采购列表
  17. r.GET("/report/purchase/list", ReportPurchaseList)
  18. r.GET("/report/produce/download", ReportProduceDownload)
  19. r.GET("/report/purchase/download", ReportPurchaseDownload)
  20. }
  21. type ReportListReq struct {
  22. SupplierId primitive.ObjectID
  23. TimeRange []string
  24. PlanIds []primitive.ObjectID
  25. Page int64
  26. Size int64
  27. }
  28. // 加工单
  29. func ReportProduceList(c *gin.Context, apictx *ApiSession) (interface{}, error) {
  30. // 财务管理】 添加统计报表功能。按 时间范围, 供应商(单选) 包装(多选) 计划(多选) 四个维度进行过滤,形成报表。可以下载
  31. page, size, query := UtilQueryPageSize(c)
  32. // 条件处理
  33. query["status"] = "complete"
  34. if _supplierId, ok := query["supplierId"]; ok {
  35. supplierId, _ := primitive.ObjectIDFromHex(_supplierId.(string))
  36. if !supplierId.IsZero() {
  37. query["supplierId"] = supplierId
  38. }
  39. }
  40. if _timeRange, ok := query["timeRange"]; ok {
  41. timeRange, _ := _timeRange.([]interface{})
  42. if len(timeRange) == 2 {
  43. start, end := getTimeRange(timeRange[0].(string), timeRange[1].(string))
  44. query["updateTime"] = bson.M{"$gte": start, "$lte": end}
  45. }
  46. delete(query, "timeRange")
  47. }
  48. if _planIds, ok := query["planIds"]; ok {
  49. if len(_planIds.([]interface{})) > 0 {
  50. planQuery := bson.A{}
  51. for _, _planId := range _planIds.([]interface{}) {
  52. planId, _ := primitive.ObjectIDFromHex(_planId.(string))
  53. planQuery = append(planQuery, bson.M{"planId": planId})
  54. }
  55. query["$or"] = planQuery
  56. }
  57. delete(query, "planIds")
  58. }
  59. fmt.Println(query)
  60. // 获取采购单符合条件的信息
  61. return repo.RepoPageSearch(apictx.CreateRepoCtx(), &repo.PageSearchOptions{
  62. CollectName: repo.CollectionBillProduce,
  63. Query: query,
  64. Page: page,
  65. Size: size,
  66. })
  67. }
  68. // 采购单
  69. func ReportPurchaseList(c *gin.Context, apictx *ApiSession) (interface{}, error) {
  70. // 财务管理】 添加统计报表功能。按 时间范围, 供应商(单选) 包装(多选) 计划(多选) 四个维度进行过滤,形成报表。可以下载
  71. page, size, query := UtilQueryPageSize(c)
  72. // 条件处理
  73. query["status"] = "complete"
  74. if _supplierId, ok := query["supplierId"]; ok {
  75. supplierId, _ := primitive.ObjectIDFromHex(_supplierId.(string))
  76. if !supplierId.IsZero() {
  77. query["supplierId"] = supplierId
  78. }
  79. }
  80. if _timeRange, ok := query["timeRange"]; ok {
  81. timeRange, _ := _timeRange.([]interface{})
  82. if len(timeRange) == 2 {
  83. start, end := getTimeRange(timeRange[0].(string), timeRange[1].(string))
  84. query["updateTime"] = bson.M{"$gte": start, "$lte": end}
  85. }
  86. delete(query, "timeRange")
  87. }
  88. if _planIds, ok := query["planIds"]; ok {
  89. if len(_planIds.([]interface{})) > 0 {
  90. planQuery := bson.A{}
  91. for _, _planId := range _planIds.([]interface{}) {
  92. planId, _ := primitive.ObjectIDFromHex(_planId.(string))
  93. planQuery = append(planQuery, bson.M{"planId": planId})
  94. }
  95. query["$or"] = planQuery
  96. }
  97. delete(query, "planIds")
  98. }
  99. // 获取采购单符合条件的信息
  100. return repo.RepoPageSearch(apictx.CreateRepoCtx(), &repo.PageSearchOptions{
  101. CollectName: repo.CollectionBillPurchase,
  102. Query: query,
  103. Page: page,
  104. Size: size,
  105. })
  106. }
  107. func ReportProduceDownload(c *gin.Context, apictx *ApiSession) (interface{}, error) {
  108. _, _, query := UtilQueryPageSize(c)
  109. // 条件处理
  110. query["status"] = "complete"
  111. if _supplierId, ok := query["supplierId"]; ok {
  112. supplierId, _ := primitive.ObjectIDFromHex(_supplierId.(string))
  113. if !supplierId.IsZero() {
  114. query["supplierId"] = supplierId
  115. }
  116. }
  117. if _timeRange, ok := query["timeRange"]; ok {
  118. timeRange, _ := _timeRange.([]interface{})
  119. if len(timeRange) == 2 {
  120. start, end := getTimeRange(timeRange[0].(string), timeRange[1].(string))
  121. query["updateTime"] = bson.M{"$gte": start, "$lte": end}
  122. }
  123. delete(query, "timeRange")
  124. }
  125. if _planIds, ok := query["planIds"]; ok {
  126. if len(_planIds.([]interface{})) > 0 {
  127. planQuery := bson.A{}
  128. for _, _planId := range _planIds.([]interface{}) {
  129. planId, _ := primitive.ObjectIDFromHex(_planId.(string))
  130. planQuery = append(planQuery, bson.M{"planId": planId})
  131. }
  132. query["$or"] = planQuery
  133. }
  134. delete(query, "planIds")
  135. }
  136. // 获取采符合条件的信息
  137. produces := []model.ProduceBill{}
  138. err := repo.RepoDocsSearch(apictx.CreateRepoCtx(), &repo.PageSearchOptions{
  139. CollectName: repo.CollectionBillProduce,
  140. Query: query,
  141. }, &produces)
  142. if err != nil || len(produces) < 1 {
  143. return nil, errors.New("数据不存在")
  144. }
  145. f := excelize.NewFile()
  146. index := f.NewSheet("Sheet1")
  147. sheetName := f.GetSheetName(index)
  148. f.SetActiveSheet(index)
  149. f.SetDefaultFont("宋体")
  150. border := []excelize.Border{
  151. {Type: "top", Style: 1, Color: "000000"},
  152. {Type: "left", Style: 1, Color: "000000"},
  153. {Type: "right", Style: 1, Color: "000000"},
  154. {Type: "bottom", Style: 1, Color: "000000"},
  155. }
  156. alignCenterStyle, _ := f.NewStyle(&excelize.Style{
  157. Alignment: &excelize.Alignment{Horizontal: "center", Vertical: "center"},
  158. Border: border,
  159. })
  160. offset := 0
  161. info := model.Setting{}
  162. repo.RepoSeachDoc(apictx.CreateRepoCtx(), &repo.DocSearchOptions{
  163. CollectName: "infos",
  164. }, &info)
  165. var budgetCount float64 = 0
  166. var realCount float64 = 0
  167. var row int = 0
  168. for _, produce := range produces {
  169. produceExcel := NewReportProduceExcel(f)
  170. produceExcel.Content = &produce
  171. produceExcel.Title = fmt.Sprintf("%s加工单", info.CompanyName)
  172. //设置对应的数据
  173. produceExcel.Offset = offset
  174. produceExcel.Draws()
  175. budgetCount += produceExcel.BudgetCount
  176. realCount += produceExcel.RealCount
  177. offset += 15
  178. row = produceExcel.Row
  179. }
  180. row++
  181. startCell := fmt.Sprintf("%s%d", "A", row)
  182. endCell := fmt.Sprintf("%s%d", "H", row)
  183. f.MergeCell(sheetName, startCell, endCell)
  184. f.SetCellStyle(sheetName, startCell, endCell, alignCenterStyle)
  185. f.SetCellValue(sheetName, startCell, "汇总金额")
  186. // 预算金额汇总
  187. budgetCountCell := fmt.Sprintf("%s%d", "I", row)
  188. budgetCountStr := ""
  189. if realCount > 0 {
  190. budgetCountStr = fmt.Sprintf("%.2f", budgetCount)
  191. }
  192. f.SetCellValue(sheetName, budgetCountCell, budgetCountStr)
  193. f.SetCellStyle(sheetName, budgetCountCell, budgetCountCell, alignCenterStyle)
  194. // 实际金额汇总
  195. RealCountCell := fmt.Sprintf("%s%d", "J", row)
  196. realCountStr := ""
  197. if realCount > 0 {
  198. realCountStr = fmt.Sprintf("%.2f", realCount)
  199. }
  200. f.SetCellValue(sheetName, RealCountCell, realCountStr)
  201. f.SetCellStyle(sheetName, RealCountCell, RealCountCell, alignCenterStyle)
  202. f.SetRowHeight(sheetName, row, 21)
  203. c.Header("Content-Type", "application/octet-stream")
  204. c.Header("Content-Disposition", "attachment; filename="+"reportProduce.xlsx")
  205. c.Header("Content-Transfer-Encoding", "binary")
  206. err = f.Write(c.Writer)
  207. if err != nil {
  208. return nil, err
  209. }
  210. return nil, nil
  211. }
  212. func ReportPurchaseDownload(c *gin.Context, apictx *ApiSession) (interface{}, error) {
  213. _, _, query := UtilQueryPageSize(c)
  214. // 条件处理
  215. query["status"] = "complete"
  216. if _supplierId, ok := query["supplierId"]; ok {
  217. supplierId, _ := primitive.ObjectIDFromHex(_supplierId.(string))
  218. if !supplierId.IsZero() {
  219. query["supplierId"] = supplierId
  220. }
  221. }
  222. if _timeRange, ok := query["timeRange"]; ok {
  223. timeRange, _ := _timeRange.([]interface{})
  224. if len(timeRange) == 2 {
  225. start, end := getTimeRange(timeRange[0].(string), timeRange[1].(string))
  226. query["updateTime"] = bson.M{"$gte": start, "$lte": end}
  227. }
  228. delete(query, "timeRange")
  229. }
  230. if _planIds, ok := query["planIds"]; ok {
  231. if len(_planIds.([]interface{})) > 0 {
  232. planQuery := bson.A{}
  233. for _, _planId := range _planIds.([]interface{}) {
  234. planId, _ := primitive.ObjectIDFromHex(_planId.(string))
  235. planQuery = append(planQuery, bson.M{"planId": planId})
  236. }
  237. query["$or"] = planQuery
  238. }
  239. delete(query, "planIds")
  240. }
  241. // 获取符合条件的信息
  242. purchases := []model.PurchaseBill{}
  243. err := repo.RepoDocsSearch(apictx.CreateRepoCtx(), &repo.PageSearchOptions{
  244. CollectName: repo.CollectionBillPurchase,
  245. Query: query,
  246. }, &purchases)
  247. if err != nil || len(purchases) < 1 {
  248. return nil, errors.New("数据不存在")
  249. }
  250. f := excelize.NewFile()
  251. index := f.NewSheet("Sheet1")
  252. sheetName := f.GetSheetName(index)
  253. f.SetActiveSheet(index)
  254. f.SetDefaultFont("宋体")
  255. border := []excelize.Border{
  256. {Type: "top", Style: 1, Color: "000000"},
  257. {Type: "left", Style: 1, Color: "000000"},
  258. {Type: "right", Style: 1, Color: "000000"},
  259. {Type: "bottom", Style: 1, Color: "000000"},
  260. }
  261. alignCenterStyle, _ := f.NewStyle(&excelize.Style{
  262. Alignment: &excelize.Alignment{Horizontal: "center", Vertical: "center"},
  263. Border: border,
  264. })
  265. offset := 0
  266. info := model.Setting{}
  267. repo.RepoSeachDoc(apictx.CreateRepoCtx(), &repo.DocSearchOptions{
  268. CollectName: "infos",
  269. }, &info)
  270. var budgetCount float64 = 0
  271. var realCount float64 = 0
  272. var row int = 0
  273. for _, purchase := range purchases {
  274. purchaseExcel := NewReportPurchaseExcel(f)
  275. purchaseExcel.Content = &purchase
  276. purchaseExcel.Title = fmt.Sprintf("%s原材料采购单", info.CompanyName)
  277. //设置对应的数据
  278. purchaseExcel.Offset = offset
  279. purchaseExcel.Draws()
  280. budgetCount += purchaseExcel.BudgetCount
  281. realCount += purchaseExcel.RealCount
  282. offset += 15
  283. row = purchaseExcel.Row
  284. }
  285. row++
  286. startCell := fmt.Sprintf("%s%d", "A", row)
  287. endCell := fmt.Sprintf("%s%d", "H", row)
  288. f.MergeCell(sheetName, startCell, endCell)
  289. f.SetCellStyle(sheetName, startCell, endCell, alignCenterStyle)
  290. f.SetCellValue(sheetName, startCell, "汇总金额")
  291. // 预算金额汇总
  292. budgetCountCell := fmt.Sprintf("%s%d", "I", row)
  293. budgetCountStr := ""
  294. if realCount > 0 {
  295. budgetCountStr = fmt.Sprintf("%.2f", budgetCount)
  296. }
  297. f.SetCellValue(sheetName, budgetCountCell, budgetCountStr)
  298. f.SetCellStyle(sheetName, budgetCountCell, budgetCountCell, alignCenterStyle)
  299. // 实际金额汇总
  300. RealCountCell := fmt.Sprintf("%s%d", "J", row)
  301. realCountStr := ""
  302. if realCount > 0 {
  303. realCountStr = fmt.Sprintf("%.2f", realCount)
  304. }
  305. f.SetCellValue(sheetName, RealCountCell, realCountStr)
  306. f.SetCellStyle(sheetName, RealCountCell, RealCountCell, alignCenterStyle)
  307. f.SetRowHeight(sheetName, row, 21)
  308. c.Header("Content-Type", "application/octet-stream")
  309. c.Header("Content-Disposition", "attachment; filename="+"reportPurchase.xlsx")
  310. c.Header("Content-Transfer-Encoding", "binary")
  311. err = f.Write(c.Writer)
  312. if err != nil {
  313. return nil, err
  314. }
  315. return nil, nil
  316. }