plan-cost-excel.go 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568
  1. package api
  2. import (
  3. "fmt"
  4. "github.com/xuri/excelize/v2"
  5. )
  6. // 生产成本表
  7. type PlanCostExcel struct {
  8. Row int
  9. Title string
  10. Excel *excelize.File
  11. SheetName string
  12. AlignCenterStyle int
  13. Content *SupplierPlanSummary
  14. }
  15. func (b *PlanCostExcel) drawTitle() error {
  16. b.Row++
  17. startCell := fmt.Sprintf("A%d", b.Row)
  18. err := b.Excel.MergeCell(b.SheetName, startCell, fmt.Sprintf("O%d", b.Row))
  19. if err != nil {
  20. return err
  21. }
  22. style, err := b.Excel.NewStyle(&excelize.Style{
  23. Alignment: &excelize.Alignment{Horizontal: "center", Vertical: "center", WrapText: true},
  24. Font: &excelize.Font{Bold: true, Size: 18}})
  25. if err != nil {
  26. return err
  27. }
  28. err = b.Excel.SetCellStyle(b.SheetName, startCell, startCell, style)
  29. if err != nil {
  30. return err
  31. }
  32. b.Excel.SetRowHeight(b.SheetName, b.Row, 23)
  33. b.Excel.SetCellValue(b.SheetName, startCell, b.Title)
  34. return nil
  35. }
  36. func (b *PlanCostExcel) drawTableTitle() error {
  37. b.Row++
  38. var drawCol = func(prefix string, value string) error {
  39. left1Cell := fmt.Sprintf("%s%d", prefix, b.Row)
  40. left2Cell := fmt.Sprintf("%s%d", prefix, b.Row+1)
  41. err := b.Excel.MergeCell(b.SheetName, left1Cell, left2Cell)
  42. if err != nil {
  43. return err
  44. }
  45. err = b.Excel.SetCellStyle(b.SheetName, left1Cell, left2Cell, b.AlignCenterStyle)
  46. if err != nil {
  47. return err
  48. }
  49. return b.Excel.SetCellValue(b.SheetName, left1Cell, value)
  50. }
  51. var drawCol2 = func(prefix1 string, prefix2 string, value1 string, value2 string, value3 string) error {
  52. left1Cell := fmt.Sprintf("%s%d", prefix1, b.Row)
  53. left2Cell := fmt.Sprintf("%s%d", prefix2, b.Row)
  54. err := b.Excel.MergeCell(b.SheetName, left1Cell, left2Cell)
  55. if err != nil {
  56. return err
  57. }
  58. if err != nil {
  59. fmt.Println(err)
  60. return err
  61. }
  62. err = b.Excel.SetCellStyle(b.SheetName, left1Cell, left2Cell, b.AlignCenterStyle)
  63. if err != nil {
  64. return err
  65. }
  66. b.Excel.SetCellValue(b.SheetName, left1Cell, value1)
  67. val2Cel := fmt.Sprintf("%s%d", prefix1, b.Row+1)
  68. b.Excel.SetCellStyle(b.SheetName, val2Cel, val2Cel, b.AlignCenterStyle)
  69. b.Excel.SetCellValue(b.SheetName, val2Cel, value2)
  70. val3Cel := fmt.Sprintf("%s%d", prefix2, b.Row+1)
  71. b.Excel.SetCellStyle(b.SheetName, val3Cel, val3Cel, b.AlignCenterStyle)
  72. b.Excel.SetCellValue(b.SheetName, val3Cel, value3)
  73. return nil
  74. }
  75. var drawCol3 = func(prefix1 string, prefix2 string, prefix3 string, value1 string, value2 string, value3 string, value4 string) error {
  76. left1Cell := fmt.Sprintf("%s%d", prefix1, b.Row)
  77. left3Cell := fmt.Sprintf("%s%d", prefix3, b.Row)
  78. err := b.Excel.MergeCell(b.SheetName, left1Cell, left3Cell)
  79. if err != nil {
  80. return err
  81. }
  82. if err != nil {
  83. fmt.Println(err)
  84. return err
  85. }
  86. err = b.Excel.SetCellStyle(b.SheetName, left1Cell, left3Cell, b.AlignCenterStyle)
  87. if err != nil {
  88. return err
  89. }
  90. b.Excel.SetCellValue(b.SheetName, left1Cell, value1)
  91. val2Cel := fmt.Sprintf("%s%d", prefix1, b.Row+1)
  92. b.Excel.SetCellStyle(b.SheetName, val2Cel, val2Cel, b.AlignCenterStyle)
  93. b.Excel.SetCellValue(b.SheetName, val2Cel, value2)
  94. val3Cel := fmt.Sprintf("%s%d", prefix2, b.Row+1)
  95. b.Excel.SetCellStyle(b.SheetName, val3Cel, val3Cel, b.AlignCenterStyle)
  96. b.Excel.SetCellValue(b.SheetName, val3Cel, value3)
  97. val4Cel := fmt.Sprintf("%s%d", prefix3, b.Row+1)
  98. b.Excel.SetCellStyle(b.SheetName, val4Cel, val4Cel, b.AlignCenterStyle)
  99. b.Excel.SetCellValue(b.SheetName, val4Cel, value4)
  100. return nil
  101. }
  102. drawCol("A", "产品名称")
  103. drawCol("A", "产品部件名称")
  104. drawCol2("B", "C", "类型/项目", "类型", "项目")
  105. drawCol("D", "下单数量")
  106. drawCol("E", "实际数量")
  107. drawCol("F", "状态") // 生成订单状态 审核状态 发送状态 完成状态
  108. drawCol("G", "供应商名称")
  109. drawCol("H", "单价")
  110. drawCol3("I", "J", "K", "规格", "厚度(纸克)", "长", "宽")
  111. drawCol("L", "单位")
  112. drawCol("M", "下单单价")
  113. drawCol("N", "预算金额")
  114. drawCol("O", "实际金额")
  115. return nil
  116. }
  117. func (b *PlanCostExcel) drawRow(rowIndex int, values ...string) {
  118. charas := []string{"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O"}
  119. for i, c := range charas {
  120. v := ""
  121. if i < len(values) {
  122. v = values[i]
  123. }
  124. b.Excel.SetCellValue(b.SheetName, fmt.Sprintf("%s%d", c, rowIndex), v)
  125. val2Cel := fmt.Sprintf("%s%d", c, rowIndex)
  126. b.Excel.SetCellStyle(b.SheetName, val2Cel, val2Cel, b.AlignCenterStyle)
  127. b.Excel.SetRowHeight(b.SheetName, rowIndex, 32)
  128. }
  129. }
  130. func (b *PlanCostExcel) drawAllContent() error {
  131. b.Row += 2
  132. // summaryPlans
  133. // 预算金额汇总
  134. var totalBudgetPrice float64 = 0.00
  135. // 实际金额汇总
  136. var totalRealPrice float64 = 0.00
  137. for _, splan := range b.Content.Plans {
  138. plan := splan.Plan
  139. comps := plan.Pack.Components
  140. // 预算金额汇总
  141. var planBudgetPrice float64 = 0.00
  142. // 实际金额汇总
  143. var planRealPrice float64 = 0.00
  144. if len(comps) > 0 {
  145. for _, comp := range comps {
  146. var perBudgetPrice float64 = 0.00
  147. var perRealPrice float64 = 0.00
  148. if len(comp.Stages) > 0 {
  149. startRow := b.Row
  150. // cates := map[string][]int{}
  151. for _, stage := range comp.Stages {
  152. matHeigth := fmt.Sprintf("%d", stage.BatchSizeHeight)
  153. b.FormatToEmpty(&matHeigth)
  154. matWidth := fmt.Sprintf("%d", stage.BatchSizeWidth)
  155. b.FormatToEmpty(&matWidth)
  156. orderCount := fmt.Sprintf("%d", int(stage.OrderCount))
  157. b.FormatToEmpty(&orderCount)
  158. // 实际数量
  159. realCount := fmt.Sprintf("%d", stage.ConfirmCount)
  160. b.FormatToEmpty(&realCount)
  161. // 单价
  162. price := fmt.Sprintf("%.3f", stage.OrderPrice)
  163. b.FormatToEmpty(&price)
  164. // 预算金额
  165. budgetPrice := fmt.Sprintf("%.3f", stage.OrderPrice*float64(stage.OrderCount))
  166. perBudgetPrice += stage.OrderPrice * float64(stage.OrderCount)
  167. b.FormatToEmpty(&budgetPrice)
  168. // 实际金额
  169. // !10.27 如果是固定价格
  170. realPrice := fmt.Sprintf("%.3f", stage.OrderPrice*float64(stage.ConfirmCount))
  171. if stage.IsFix == nil {
  172. _fix := false
  173. stage.IsFix = &_fix
  174. }
  175. if *stage.IsFix {
  176. realPrice = budgetPrice
  177. perRealPrice += stage.OrderPrice * float64(stage.OrderCount)
  178. } else {
  179. perRealPrice += stage.OrderPrice * float64(stage.ConfirmCount)
  180. }
  181. b.FormatToEmpty(&realPrice)
  182. unit := stage.Unit
  183. if stage.Unit == "吨" || stage.Unit == "平方米" {
  184. unit = "张"
  185. }
  186. supplierName := ""
  187. if stage.SupplierInfo != nil {
  188. supplierName = stage.SupplierInfo.Name
  189. }
  190. stageType := ""
  191. if stage.BillType > 0 {
  192. stage.Type = stage.BillType
  193. }
  194. if stage.Type == 1 {
  195. stageType = "材料采购"
  196. }
  197. if stage.Type == 2 {
  198. stageType = "工艺"
  199. }
  200. if stage.Type == 3 {
  201. stageType = "成品采购"
  202. }
  203. // 状态
  204. stageStatus := ""
  205. if len(stage.BillId) < 1 {
  206. stageStatus = "未生成订单"
  207. } else {
  208. if splan.State[stage.BillId] == "created" {
  209. stageStatus = "进行中"
  210. // 审核状态
  211. if splan.Reviewed[stage.BillId] == 1 {
  212. stageStatus = "已审核"
  213. if splan.IsSend[stage.BillId] {
  214. stageStatus = "已发送"
  215. if splan.IsAck[stage.BillId] {
  216. stageStatus = "已接单"
  217. } else {
  218. stageStatus = "未接单"
  219. }
  220. } else {
  221. stageStatus = "未发送"
  222. }
  223. } else {
  224. stageStatus = "未审核"
  225. }
  226. } else if splan.State[stage.BillId] == "complete" {
  227. stageStatus = "已完成"
  228. } else {
  229. stageStatus = "未生成订单"
  230. }
  231. }
  232. b.drawRow(b.Row, "", stageType, stage.Name, orderCount, realCount, stageStatus, supplierName, fmt.Sprintf("%.3f元/%s", stage.Price, stage.Unit), stage.Norm, matHeigth, matWidth, unit, price, budgetPrice, realPrice)
  233. // if stage.SupplierInfo != nil {
  234. // cates[stage.SupplierInfo.Name] = append(cates[stage.SupplierInfo.Name], b.Row)
  235. // }
  236. b.Row++
  237. }
  238. // fmt.Println(cates)
  239. // for supplierName, cate := range cates {
  240. // mergeStartRow := cate[0]
  241. // mergeEndRow := cate[len(cate)-1]
  242. // b.Excel.MergeCell(b.SheetName, fmt.Sprintf("G%d", mergeStartRow), fmt.Sprintf("G%d", mergeEndRow))
  243. // b.Excel.SetCellValue(b.SheetName, fmt.Sprintf("G%d", mergeEndRow), supplierName)
  244. // }
  245. endRow := b.Row - 1
  246. // 组件名字
  247. startACell := fmt.Sprintf("%s%d", "A", startRow)
  248. endACell := fmt.Sprintf("%s%d", "A", endRow)
  249. b.Excel.MergeCell(b.SheetName, startACell, endACell)
  250. err := b.Excel.SetCellStyle(b.SheetName, startACell, endACell, b.AlignCenterStyle)
  251. if err != nil {
  252. return err
  253. }
  254. b.Excel.SetCellValue(b.SheetName, startACell, comp.Name)
  255. }
  256. // 预算
  257. planBudgetPrice += perBudgetPrice
  258. // 实际金额
  259. planRealPrice += perRealPrice
  260. }
  261. }
  262. totalBudgetPrice += planBudgetPrice
  263. totalRealPrice += planRealPrice
  264. }
  265. summaryEndRow := b.Row
  266. startACell := fmt.Sprintf("%s%d", "A", summaryEndRow)
  267. endMell := fmt.Sprintf("%s%d", "M", summaryEndRow)
  268. NCell := fmt.Sprintf("%s%d", "N", summaryEndRow)
  269. OCell := fmt.Sprintf("%s%d", "O", summaryEndRow)
  270. b.Excel.MergeCell(b.SheetName, startACell, endMell)
  271. b.Excel.SetCellStyle(b.SheetName, startACell, endMell, b.AlignCenterStyle)
  272. b.Excel.SetCellValue(b.SheetName, startACell, "生产计划汇总金额")
  273. // 生产预算汇总
  274. b.Excel.SetCellStyle(b.SheetName, NCell, NCell, b.AlignCenterStyle)
  275. totalOrderRealPrice := fmt.Sprintf("%.3f", totalBudgetPrice)
  276. b.FormatToEmpty(&totalOrderRealPrice)
  277. b.Excel.SetCellValue(b.SheetName, NCell, totalOrderRealPrice)
  278. // 生产实际汇总
  279. b.Excel.SetCellStyle(b.SheetName, OCell, OCell, b.AlignCenterStyle)
  280. totalRealPricef := fmt.Sprintf("%.3f", totalRealPrice)
  281. b.FormatToEmpty(&totalRealPricef)
  282. b.Excel.SetCellValue(b.SheetName, OCell, totalRealPricef)
  283. return nil
  284. }
  285. func (b *PlanCostExcel) drawSupplierContent() error {
  286. b.Row += 2
  287. supplier := ""
  288. // summaryPlans
  289. // 预算金额汇总
  290. var totalBudgetPrice float64 = 0.00
  291. // 实际金额汇总
  292. var totalRealPrice float64 = 0.00
  293. for _, splan := range b.Content.Plans {
  294. plan := splan.Plan
  295. comps := plan.Pack.Components
  296. // 预算金额汇总
  297. var planBudgetPrice float64 = 0.00
  298. // 实际金额汇总
  299. var planRealPrice float64 = 0.00
  300. if len(comps) > 0 {
  301. for _, comp := range comps {
  302. var perBudgetPrice float64 = 0.00
  303. var perRealPrice float64 = 0.00
  304. if len(comp.Stages) > 0 {
  305. startRow := 0
  306. // cates := map[string][]int{}
  307. for _, stage := range comp.Stages {
  308. if stage.SupplierInfo != nil {
  309. if b.Content.SupplierId == stage.SupplierInfo.Id {
  310. supplier = stage.SupplierInfo.Name
  311. // 材料
  312. if startRow == 0 {
  313. startRow = b.Row
  314. }
  315. matHeigth := fmt.Sprintf("%d", stage.BatchSizeHeight)
  316. b.FormatToEmpty(&matHeigth)
  317. matWidth := fmt.Sprintf("%d", stage.BatchSizeWidth)
  318. b.FormatToEmpty(&matWidth)
  319. orderCount := fmt.Sprintf("%d", int(stage.OrderCount))
  320. b.FormatToEmpty(&orderCount)
  321. // 实际数量
  322. realCount := fmt.Sprintf("%d", stage.ConfirmCount)
  323. b.FormatToEmpty(&realCount)
  324. // 单价
  325. price := fmt.Sprintf("%.3f", stage.OrderPrice)
  326. b.FormatToEmpty(&price)
  327. // 预算金额
  328. budgetPrice := fmt.Sprintf("%.3f", stage.OrderPrice*float64(stage.OrderCount))
  329. perBudgetPrice += stage.OrderPrice * float64(stage.OrderCount)
  330. b.FormatToEmpty(&budgetPrice)
  331. // 实际金额
  332. // !10.27 如果是固定价格
  333. realPrice := fmt.Sprintf("%.3f", stage.OrderPrice*float64(stage.ConfirmCount))
  334. if stage.IsFix == nil {
  335. _fix := false
  336. stage.IsFix = &_fix
  337. }
  338. if *stage.IsFix {
  339. realPrice = budgetPrice
  340. perRealPrice += stage.OrderPrice * float64(stage.OrderCount)
  341. } else {
  342. perRealPrice += stage.OrderPrice * float64(stage.ConfirmCount)
  343. }
  344. b.FormatToEmpty(&realPrice)
  345. unit := stage.Unit
  346. if stage.Unit == "吨" || stage.Unit == "平方米" {
  347. unit = "张"
  348. }
  349. supplierName := ""
  350. if stage.SupplierInfo != nil {
  351. supplierName = stage.SupplierInfo.Name
  352. }
  353. stageType := ""
  354. if stage.BillType > 0 {
  355. stage.Type = stage.BillType
  356. }
  357. if stage.Type == 1 {
  358. stageType = "材料采购"
  359. }
  360. if stage.Type == 2 {
  361. stageType = "工艺"
  362. }
  363. if stage.Type == 3 {
  364. stageType = "成品采购"
  365. }
  366. // 状态
  367. stageStatus := ""
  368. if len(stage.BillId) < 1 {
  369. stageStatus = "未生成订单"
  370. } else {
  371. if splan.State[stage.BillId] == "created" {
  372. stageStatus = "进行中"
  373. // 审核状态
  374. if splan.Reviewed[stage.BillId] == 1 {
  375. stageStatus = "已审核"
  376. if splan.IsSend[stage.BillId] {
  377. stageStatus = "已发送"
  378. if splan.IsAck[stage.BillId] {
  379. stageStatus = "已接单"
  380. } else {
  381. stageStatus = "未接单"
  382. }
  383. } else {
  384. stageStatus = "未发送"
  385. }
  386. } else {
  387. stageStatus = "未审核"
  388. }
  389. } else if splan.State[stage.BillId] == "complete" {
  390. stageStatus = "已完成"
  391. } else {
  392. stageStatus = "未生成订单"
  393. }
  394. }
  395. b.drawRow(b.Row, "", stageType, stage.Name, orderCount, realCount, stageStatus, supplierName, fmt.Sprintf("%.3f元/%s", stage.Price, stage.Unit), stage.Norm, matHeigth, matWidth, unit, price, budgetPrice, realPrice)
  396. b.Row++
  397. }
  398. }
  399. }
  400. if startRow != 0 {
  401. endRow := b.Row - 1
  402. // 组件名字
  403. startACell := fmt.Sprintf("%s%d", "A", startRow)
  404. endACell := fmt.Sprintf("%s%d", "A", endRow)
  405. b.Excel.MergeCell(b.SheetName, startACell, endACell)
  406. err := b.Excel.SetCellStyle(b.SheetName, startACell, endACell, b.AlignCenterStyle)
  407. if err != nil {
  408. return err
  409. }
  410. b.Excel.SetCellValue(b.SheetName, startACell, comp.Name)
  411. }
  412. }
  413. // 预算
  414. totalBudgetPrice += perBudgetPrice
  415. // 预算
  416. totalRealPrice += perRealPrice
  417. }
  418. }
  419. totalBudgetPrice += planBudgetPrice
  420. totalRealPrice += planRealPrice
  421. }
  422. summaryEndRow := b.Row
  423. startACell := fmt.Sprintf("%s%d", "A", summaryEndRow)
  424. endMell := fmt.Sprintf("%s%d", "M", summaryEndRow)
  425. NCell := fmt.Sprintf("%s%d", "N", summaryEndRow)
  426. OCell := fmt.Sprintf("%s%d", "O", summaryEndRow)
  427. b.Excel.MergeCell(b.SheetName, startACell, endMell)
  428. b.Excel.SetCellStyle(b.SheetName, startACell, endMell, b.AlignCenterStyle)
  429. b.Excel.SetCellValue(b.SheetName, startACell, "生产计划汇总金额")
  430. // 生产预算汇总
  431. b.Excel.SetCellStyle(b.SheetName, NCell, NCell, b.AlignCenterStyle)
  432. totalOrderRealPrice := fmt.Sprintf("%.3f", totalBudgetPrice)
  433. b.FormatToEmpty(&totalOrderRealPrice)
  434. b.Excel.SetCellValue(b.SheetName, NCell, totalOrderRealPrice)
  435. // 生产实际汇总
  436. b.Excel.SetCellStyle(b.SheetName, OCell, OCell, b.AlignCenterStyle)
  437. totalRealPricef := fmt.Sprintf("%.3f", totalRealPrice)
  438. b.FormatToEmpty(&totalRealPricef)
  439. b.Excel.SetCellValue(b.SheetName, OCell, totalRealPricef)
  440. // 供应商名字标题
  441. style, err := b.Excel.NewStyle(&excelize.Style{
  442. Alignment: &excelize.Alignment{Horizontal: "center", Vertical: "center", WrapText: true},
  443. })
  444. if err != nil {
  445. return err
  446. }
  447. err = b.Excel.SetCellStyle(b.SheetName, "A1", "G1", style)
  448. if err != nil {
  449. return err
  450. }
  451. b.Excel.SetRowHeight(b.SheetName, 1, 32)
  452. b.Excel.SetCellValue(b.SheetName, "A1", fmt.Sprintf("【%s】-生产成本表", supplier))
  453. return nil
  454. }
  455. func (b *PlanCostExcel) Draws() {
  456. b.drawTitle()
  457. b.drawTableTitle()
  458. if !b.Content.SupplierId.IsZero() {
  459. b.drawSupplierContent()
  460. } else {
  461. b.drawAllContent()
  462. }
  463. }
  464. func NewPlanCostExcel(f *excelize.File) *PlanCostExcel {
  465. border := []excelize.Border{
  466. {Type: "top", Style: 1, Color: "000000"},
  467. {Type: "left", Style: 1, Color: "000000"},
  468. {Type: "right", Style: 1, Color: "000000"},
  469. {Type: "bottom", Style: 1, Color: "000000"},
  470. }
  471. styleLeft, _ := f.NewStyle(&excelize.Style{
  472. Alignment: &excelize.Alignment{Horizontal: "center", Vertical: "center", WrapText: true},
  473. Border: border,
  474. Font: &excelize.Font{Size: 10},
  475. })
  476. b := &PlanCostExcel{
  477. Title: "生产成本表",
  478. SheetName: "Sheet1",
  479. Excel: f,
  480. AlignCenterStyle: styleLeft,
  481. }
  482. f.SetColWidth(b.SheetName, "A", "D", 16)
  483. f.SetColWidth(b.SheetName, "E", "F", 12)
  484. f.SetColWidth(b.SheetName, "G", "G", 25)
  485. f.SetColWidth(b.SheetName, "H", "K", 16)
  486. f.SetColWidth(b.SheetName, "L", "L", 10)
  487. f.SetColWidth(b.SheetName, "M", "O", 16)
  488. f.SetPageMargins(b.SheetName, excelize.PageMarginTop(0), excelize.PageMarginLeft(0), excelize.PageMarginRight(0))
  489. return b
  490. }
  491. func (b *PlanCostExcel) FormatToEmpty(str *string) {
  492. if *str == "0" || *str == "0.000" {
  493. *str = ""
  494. }
  495. }