register.go 32 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060
  1. package contract
  2. import (
  3. "bytes"
  4. "encoding/json"
  5. "fmt"
  6. "github.com/gin-gonic/gin"
  7. "github.com/go-playground/validator/v10"
  8. "github.com/tealeg/xlsx"
  9. "hongze/fms_api/controller/resp"
  10. "hongze/fms_api/global"
  11. "hongze/fms_api/models/base"
  12. "hongze/fms_api/models/crm"
  13. "hongze/fms_api/models/fms"
  14. "hongze/fms_api/models/system"
  15. fmsService "hongze/fms_api/services/fms"
  16. "hongze/fms_api/utils"
  17. "net/http"
  18. "time"
  19. )
  20. // RegisterController 合同登记
  21. type RegisterController struct{}
  22. // List
  23. // @Title 合同登记列表
  24. // @Description 合同登记列表
  25. // @Param Keyword query string false "关键词"
  26. // @Param StartDate query string false "合同开始日期"
  27. // @Param EndDate query string false "合同结束日期"
  28. // @Param ServiceType query int false "套餐类型"
  29. // @Param ContractType query int false "合同类型"
  30. // @Param RegisterStatus query int false "登记状态"
  31. // @Success 200 {object} fms.ContractRegisterItem
  32. // @router /contract/register/list [get]
  33. func (rg *RegisterController) List(c *gin.Context) {
  34. var req fms.ContractRegisterListReq
  35. if e := c.BindQuery(&req); e != nil {
  36. err, ok := e.(validator.ValidationErrors)
  37. if !ok {
  38. resp.FailData("参数解析失败", "Err:"+e.Error(), c)
  39. return
  40. }
  41. resp.FailData("参数解析失败", err.Translate(global.Trans), c)
  42. return
  43. }
  44. cond := `1 = 1`
  45. pars := make([]interface{}, 0)
  46. if req.Keyword != "" {
  47. kw := "%" + req.Keyword + "%"
  48. cond += ` AND (company_name LIKE ? OR contract_code LIKE ? OR seller_name LIKE ?)`
  49. pars = append(pars, kw, kw, kw)
  50. }
  51. if req.StartDate != "" && req.EndDate != "" {
  52. cond += ` AND (create_time BETWEEN ? AND ?)`
  53. pars = append(pars, req.StartDate, req.EndDate)
  54. }
  55. if req.ContractType != 0 {
  56. cond += ` AND contract_type = ?`
  57. pars = append(pars, req.ContractType)
  58. }
  59. if req.RegisterStatus != 0 {
  60. cond += ` AND register_status = ?`
  61. pars = append(pars, req.RegisterStatus)
  62. }
  63. // 套餐筛选
  64. if req.ServiceType != 0 {
  65. registerIds, e := fms.GetContractRegisterIdsByTempId(req.ServiceType)
  66. if e != nil {
  67. resp.FailMsg("获取失败", "获取合同登记IDs失败, Err: "+e.Error(), c)
  68. return
  69. }
  70. if len(registerIds) > 0 {
  71. cond += ` AND contract_register_id IN ?`
  72. pars = append(pars, registerIds)
  73. } else {
  74. cond += ` AND 1 = 2`
  75. }
  76. }
  77. page := new(base.Page)
  78. page.SetPageSize(req.PageSize)
  79. page.SetCurrent(req.Current)
  80. page.AddOrderItem(base.OrderItem{Column: "create_time", Asc: false})
  81. total, list, e := fms.GetContractRegisterItemPageList(page, cond, pars)
  82. if e != nil {
  83. resp.FailMsg("获取失败", "获取合同登记列表失败, Err: "+e.Error(), c)
  84. return
  85. }
  86. registerIds := make([]int, 0)
  87. for i := range list {
  88. registerIds = append(registerIds, list[i].ContractRegisterId)
  89. }
  90. serviceMap := make(map[int]string, 0)
  91. invoiceMap := make(map[int][]*fms.ContractInvoiceItem, 0)
  92. paymentMap := make(map[int][]*fms.ContractInvoiceItem, 0)
  93. if len(registerIds) > 0 {
  94. // 获取服务套餐
  95. servicesNameList, e := fms.GetContractRegisterServicesNameByRegisterIds(registerIds)
  96. if e != nil {
  97. resp.FailMsg("获取失败", "获取套餐拼接字符串失败, Err: "+e.Error(), c)
  98. return
  99. }
  100. for i := range servicesNameList {
  101. serviceMap[servicesNameList[i].ContractRegisterId] = servicesNameList[i].ServicesName
  102. }
  103. // 获取开票/到款列表
  104. invoiceCond := `contract_register_id IN ?`
  105. invoicePars := make([]interface{}, 0)
  106. invoicePars = append(invoicePars, registerIds)
  107. invoiceList, e := fms.GetContractInvoiceItemList(invoiceCond, invoicePars)
  108. if e != nil {
  109. resp.FailMsg("获取失败", "获取开票/到款列表失败, Err: "+e.Error(), c)
  110. return
  111. }
  112. for i := range invoiceList {
  113. if invoiceMap[invoiceList[i].ContractRegisterId] == nil {
  114. invoiceMap[invoiceList[i].ContractRegisterId] = make([]*fms.ContractInvoiceItem, 0)
  115. }
  116. if paymentMap[invoiceList[i].ContractRegisterId] == nil {
  117. paymentMap[invoiceList[i].ContractRegisterId] = make([]*fms.ContractInvoiceItem, 0)
  118. }
  119. if invoiceList[i].InvoiceType == fms.ContractInvoiceTypeMake {
  120. invoiceMap[invoiceList[i].ContractRegisterId] = append(invoiceMap[invoiceList[i].ContractRegisterId], invoiceList[i])
  121. }
  122. if invoiceList[i].InvoiceType == fms.ContractInvoiceTypePay {
  123. paymentMap[invoiceList[i].ContractRegisterId] = append(paymentMap[invoiceList[i].ContractRegisterId], invoiceList[i])
  124. }
  125. }
  126. }
  127. respList := make([]*fms.ContractRegisterList, 0)
  128. for i := range list {
  129. v := new(fms.ContractRegisterList)
  130. v.ContractRegisterItem = list[i]
  131. v.ServicesName = serviceMap[list[i].ContractRegisterId]
  132. v.InvoiceList = invoiceMap[list[i].ContractRegisterId]
  133. v.PaymentList = paymentMap[list[i].ContractRegisterId]
  134. respList = append(respList, v)
  135. }
  136. page.SetTotal(total)
  137. baseData := new(base.BaseData)
  138. baseData.SetPage(page)
  139. baseData.SetList(respList)
  140. resp.OkData("获取成功", baseData, c)
  141. }
  142. // Add
  143. // @Title 新增合同登记
  144. // @Description 新增合同登记
  145. // @Param request body fms.ContractRegisterAddReq true "type json string"
  146. // @Success 200 string "操作成功"
  147. // @router /contract/register/add [post]
  148. func (rg *RegisterController) Add(c *gin.Context) {
  149. req := new(fms.ContractRegisterAddReq)
  150. err := c.ShouldBind(&req)
  151. if err != nil {
  152. errs, ok := err.(validator.ValidationErrors)
  153. if !ok {
  154. resp.FailData("参数解析失败", "Err:"+err.Error(), c)
  155. return
  156. }
  157. resp.FailData("参数解析失败", errs.Translate(global.Trans), c)
  158. return
  159. }
  160. claims, _ := c.Get("adminInfo")
  161. adminInfo := claims.(*system.SysAdmin)
  162. // 日期校验
  163. startDate, e := time.ParseInLocation(utils.FormatDate, req.StartDate, time.Local)
  164. if e != nil {
  165. resp.FailMsg("合同开始日期格式有误", "合同开始日期格式有误, Err: "+e.Error(), c)
  166. return
  167. }
  168. endDate, e := time.ParseInLocation(utils.FormatDate, req.EndDate, time.Local)
  169. if e != nil {
  170. resp.FailMsg("合同结束日期格式有误", "合同结束日期格式有误, Err: "+e.Error(), c)
  171. return
  172. }
  173. signDate, e := time.ParseInLocation(utils.FormatDate, req.SignDate, time.Local)
  174. if e != nil {
  175. resp.FailMsg("合同签订日期格式有误", "合同签订日期格式有误, Err: "+e.Error(), c)
  176. return
  177. }
  178. // 是否存在相同合同编号的登记
  179. ob := new(fms.ContractRegister)
  180. existCond := `contract_code = ?`
  181. existPars := make([]interface{}, 0)
  182. existPars = append(existPars, req.ContractCode)
  183. exist, e := ob.FetchByCondition(existCond, existPars)
  184. if e != nil && e != utils.ErrNoRow {
  185. resp.FailMsg("操作失败", "获取相同登记号失败, Err: "+e.Error(), c)
  186. return
  187. }
  188. if exist != nil && exist.ContractRegisterId > 0 {
  189. resp.Fail("合同编号已存在", c)
  190. return
  191. }
  192. nowTime := time.Now().Local()
  193. ob.ContractCode = req.ContractCode
  194. ob.CrmContractId = req.CrmContractId
  195. ob.ContractSource = req.ContractSource
  196. ob.CompanyName = req.CompanyName
  197. ob.ProductId = req.ProductId
  198. ob.SellerId = req.SellerId
  199. ob.SellerName = req.SellerName
  200. ob.ContractType = req.ContractType
  201. ob.ContractAmount = req.ContractAmount
  202. ob.StartDate = startDate
  203. ob.EndDate = endDate
  204. ob.SignDate = signDate
  205. ob.AgreedPayTime = req.AgreedPayTime
  206. ob.ContractStatus = req.ContractStatus
  207. ob.RegisterStatus = fms.ContractRegisterStatusIng
  208. ob.Remark = req.Remark
  209. ob.Set()
  210. // 套餐信息
  211. serviceList, e := fmsService.HandleContractServiceAndDetail(req.ProductId, req.Services, true)
  212. if e != nil {
  213. resp.FailMsg("操作失败", "获取合同套餐详情失败, Err: "+e.Error(), c)
  214. return
  215. }
  216. // 新增合同及套餐
  217. if e = fms.CreateContractRegisterAndServices(ob, serviceList); e != nil {
  218. resp.FailMsg("操作失败", "新增合同及套餐失败, Err: "+e.Error(), c)
  219. return
  220. }
  221. // 操作日志
  222. go func() {
  223. opData := ""
  224. opDataByte, e := json.Marshal(req)
  225. if e != nil {
  226. return
  227. }
  228. opData = string(opDataByte)
  229. logItem := new(fms.ContractRegisterLog)
  230. logItem.ContractRegisterId = ob.ContractRegisterId
  231. logItem.AdminId = int(adminInfo.AdminId)
  232. logItem.AdminName = adminInfo.RealName
  233. logItem.OpData = opData
  234. logItem.OpType = fms.ContractRegisterOpTypeSave
  235. logItem.CreateTime = nowTime
  236. if e = logItem.Create(); e != nil {
  237. return
  238. }
  239. }()
  240. resp.Ok("操作成功", c)
  241. }
  242. // Edit
  243. // @Title 编辑合同登记
  244. // @Description 编辑合同登记
  245. // @Param request body fms.ContractRegisterEditReq true "type json string"
  246. // @Success 200 string "操作成功"
  247. // @router /contract/register/edit [post]
  248. func (rg *RegisterController) Edit(c *gin.Context) {
  249. req := new(fms.ContractRegisterEditReq)
  250. err := c.ShouldBind(&req)
  251. if err != nil {
  252. errs, ok := err.(validator.ValidationErrors)
  253. if !ok {
  254. resp.FailData("参数解析失败", "Err:"+err.Error(), c)
  255. return
  256. }
  257. resp.FailData("参数解析失败", errs.Translate(global.Trans), c)
  258. return
  259. }
  260. claims, _ := c.Get("adminInfo")
  261. adminInfo := claims.(*system.SysAdmin)
  262. // 日期校验
  263. startDate, e := time.ParseInLocation(utils.FormatDate, req.StartDate, time.Local)
  264. if e != nil {
  265. resp.FailMsg("合同开始日期格式有误", "合同开始日期格式有误, Err: "+e.Error(), c)
  266. return
  267. }
  268. endDate, e := time.ParseInLocation(utils.FormatDate, req.EndDate, time.Local)
  269. if e != nil {
  270. resp.FailMsg("合同结束日期格式有误", "合同结束日期格式有误, Err: "+e.Error(), c)
  271. return
  272. }
  273. signDate, e := time.ParseInLocation(utils.FormatDate, req.SignDate, time.Local)
  274. if e != nil {
  275. resp.FailMsg("合同签订日期格式有误", "合同签订日期格式有误, Err: "+e.Error(), c)
  276. return
  277. }
  278. ob := new(fms.ContractRegister)
  279. item, e := ob.Fetch(req.ContractRegisterId)
  280. if e != nil {
  281. if e == utils.ErrNoRow {
  282. resp.Fail("登记记录不存在或已被删除", c)
  283. return
  284. }
  285. resp.FailMsg("操作失败", "获取合同登记信息失败, Err:"+e.Error(), c)
  286. return
  287. }
  288. // 是否存在相同合同编号的登记
  289. existCond := `contract_code = ?`
  290. existPars := make([]interface{}, 0)
  291. existPars = append(existPars, req.ContractCode)
  292. exist, e := ob.FetchByCondition(existCond, existPars)
  293. if e != nil && e != utils.ErrNoRow {
  294. resp.FailMsg("操作失败", "获取相同登记号失败, Err: "+e.Error(), c)
  295. return
  296. }
  297. if exist != nil && exist.ContractRegisterId > 0 && exist.ContractRegisterId != item.ContractRegisterId {
  298. resp.Fail("合同编号已存在", c)
  299. return
  300. }
  301. nowTime := time.Now().Local()
  302. item.ContractCode = req.ContractCode
  303. item.CrmContractId = req.CrmContractId
  304. item.ContractSource = req.ContractSource
  305. item.CompanyName = req.CompanyName
  306. item.SellerId = req.SellerId
  307. item.SellerName = req.SellerName
  308. item.ContractType = req.ContractType
  309. item.ContractAmount = req.ContractAmount
  310. item.StartDate = startDate
  311. item.EndDate = endDate
  312. item.SignDate = signDate
  313. item.AgreedPayTime = req.AgreedPayTime
  314. item.ContractStatus = req.ContractStatus
  315. item.RegisterStatus = fms.ContractRegisterStatusIng
  316. item.Remark = req.Remark
  317. item.ModifyTime = nowTime
  318. updateCols := []string{
  319. "ContractCode", "CrmContractId", "ContractSource", "CompanyName", "SellerId", "SellerName",
  320. "ContractType", "ContractAmount", "StartDate", "EndDate", "SignDate", "AgreedPayTime", "ContractStatus",
  321. "RegisterStatus", "Remark", "ModifyTime",
  322. }
  323. // 套餐信息
  324. serviceList, e := fmsService.HandleContractServiceAndDetail(req.ProductId, req.Services, true)
  325. if e != nil {
  326. resp.FailMsg("操作失败", "获取合同套餐详情失败, Err: "+e.Error(), c)
  327. return
  328. }
  329. // 更新合同及套餐
  330. if e = fms.UpdateContractRegisterAndServices(item, updateCols, serviceList); e != nil {
  331. resp.FailMsg("操作失败", "更新合同及套餐失败, Err: "+e.Error(), c)
  332. return
  333. }
  334. // 校验金额-是否修改状态
  335. go fmsService.CheckContractRegisterAmount(item.ContractRegisterId)
  336. // 操作日志
  337. go func() {
  338. opData := ""
  339. opDataByte, e := json.Marshal(req)
  340. if e != nil {
  341. return
  342. }
  343. opData = string(opDataByte)
  344. logItem := new(fms.ContractRegisterLog)
  345. logItem.ContractRegisterId = item.ContractRegisterId
  346. logItem.AdminId = int(adminInfo.AdminId)
  347. logItem.AdminName = adminInfo.RealName
  348. logItem.OpData = opData
  349. logItem.OpType = fms.ContractRegisterOpTypeSave
  350. logItem.CreateTime = nowTime
  351. if e = logItem.Create(); e != nil {
  352. return
  353. }
  354. }()
  355. resp.Ok("操作成功", c)
  356. }
  357. // Del
  358. // @Title 删除合同登记
  359. // @Description 删除合同登记
  360. // @Param request body fms.ContractRegisterDelReq true "type json string"
  361. // @Success 200 string "操作成功"
  362. // @router /contract/register/del [post]
  363. func (rg *RegisterController) Del(c *gin.Context) {
  364. req := new(fms.ContractRegisterDelReq)
  365. err := c.ShouldBind(&req)
  366. if err != nil {
  367. errs, ok := err.(validator.ValidationErrors)
  368. if !ok {
  369. resp.FailData("参数解析失败", "Err:"+err.Error(), c)
  370. return
  371. }
  372. resp.FailData("参数解析失败", errs.Translate(global.Trans), c)
  373. return
  374. }
  375. claims, _ := c.Get("adminInfo")
  376. adminInfo := claims.(*system.SysAdmin)
  377. ob := new(fms.ContractRegister)
  378. item, e := ob.Fetch(req.ContractRegisterId)
  379. if e != nil {
  380. if e == utils.ErrNoRow {
  381. resp.Fail("合同登记不存在或已被删除", c)
  382. return
  383. }
  384. resp.FailMsg("获取合同登记失败", "Err:"+e.Error(), c)
  385. return
  386. }
  387. nowTime := time.Now().Local()
  388. item.IsDeleted = 1
  389. item.ModifyTime = nowTime
  390. updateCols := []string{"IsDeleted", "ModifyTime"}
  391. if e = item.Update(updateCols); e != nil {
  392. resp.FailMsg("操作失败", "更新合同登记失败, Err:"+e.Error(), c)
  393. return
  394. }
  395. // 操作日志
  396. go func() {
  397. opData := ""
  398. opDataByte, e := json.Marshal(req)
  399. if e != nil {
  400. return
  401. }
  402. opData = string(opDataByte)
  403. logItem := new(fms.ContractRegisterLog)
  404. logItem.ContractRegisterId = req.ContractRegisterId
  405. logItem.AdminId = int(adminInfo.AdminId)
  406. logItem.AdminName = adminInfo.RealName
  407. logItem.OpData = opData
  408. logItem.OpType = fms.ContractRegisterOpTypeDel
  409. logItem.CreateTime = nowTime
  410. if e = logItem.Create(); e != nil {
  411. return
  412. }
  413. }()
  414. resp.Ok("操作成功", c)
  415. }
  416. // Detail
  417. // @Title 合同登记详情
  418. // @Description 合同登记详情
  419. // @Param ContractRegisterId query int false "合同登记ID"
  420. // @Success 200 {object} fms.ContractRegisterDetail
  421. // @router /contract/register/detail [get]
  422. func (rg *RegisterController) Detail(c *gin.Context) {
  423. var req fms.ContractRegisterDetailReq
  424. if e := c.BindQuery(&req); e != nil {
  425. err, ok := e.(validator.ValidationErrors)
  426. if !ok {
  427. resp.FailData("参数解析失败", "Err:"+e.Error(), c)
  428. return
  429. }
  430. resp.FailData("参数解析失败", err.Translate(global.Trans), c)
  431. return
  432. }
  433. result := new(fms.ContractRegisterDetail)
  434. // 合同登记信息
  435. item, e := fms.GetContractRegisterItemById(req.ContractRegisterId)
  436. if e != nil {
  437. resp.FailData("获取失败", "获取合同登记详情失败, Err:"+e.Error(), c)
  438. return
  439. }
  440. result.ContractRegisterItem = item
  441. // 套餐信息
  442. serviceList, e := fmsService.GetContractServiceAndDetail(req.ContractRegisterId)
  443. if e != nil {
  444. resp.FailData("获取失败", "获取合同套餐信息失败, Err: "+e.Error(), c)
  445. return
  446. }
  447. result.ServiceList = serviceList
  448. // 开票/到款信息
  449. invoiceCond := `contract_register_id = ?`
  450. invoicePars := make([]interface{}, 0)
  451. invoicePars = append(invoicePars, req.ContractRegisterId)
  452. invoiceList, e := fms.GetContractInvoiceItemList(invoiceCond, invoicePars)
  453. if e != nil {
  454. resp.FailData("获取失败", "获取合同开票/到款信息失败, Err: "+e.Error(), c)
  455. return
  456. }
  457. result.InvoiceList = make([]*fms.ContractInvoiceItem, 0)
  458. result.PaymentList = make([]*fms.ContractInvoiceItem, 0)
  459. for i := range invoiceList {
  460. if invoiceList[i].InvoiceType == fms.ContractInvoiceTypeMake {
  461. result.InvoiceList = append(result.InvoiceList, invoiceList[i])
  462. continue
  463. }
  464. if invoiceList[i].InvoiceType == fms.ContractInvoiceTypePay {
  465. result.PaymentList = append(result.PaymentList, invoiceList[i])
  466. }
  467. }
  468. // 合同登记进度
  469. logCond := `contract_register_id = ?`
  470. logPars := make([]interface{}, 0)
  471. logPars = append(logPars, req.ContractRegisterId)
  472. logList, e := fms.GetContractRegisterLogItemList(logCond, logPars)
  473. if e != nil {
  474. resp.FailData("获取失败", "获取合同登记进度失败, Err: "+e.Error(), c)
  475. return
  476. }
  477. result.Logs = logList
  478. resp.OkData("获取成功", result, c)
  479. }
  480. // UpdateStatus
  481. // @Title 修改合同状态
  482. // @Description 修改合同状态
  483. // @Param request body fms.ContractRegisterUpdateStatusReq true "type json string"
  484. // @Success 200 string "操作成功"
  485. // @router /contract/register/update_status [post]
  486. func (rg *RegisterController) UpdateStatus(c *gin.Context) {
  487. req := new(fms.ContractRegisterUpdateStatusReq)
  488. err := c.ShouldBind(&req)
  489. if err != nil {
  490. errs, ok := err.(validator.ValidationErrors)
  491. if !ok {
  492. resp.FailData("参数解析失败", "Err:"+err.Error(), c)
  493. return
  494. }
  495. resp.FailData("参数解析失败", errs.Translate(global.Trans), c)
  496. return
  497. }
  498. claims, _ := c.Get("adminInfo")
  499. adminInfo := claims.(*system.SysAdmin)
  500. ob := new(fms.ContractRegister)
  501. item, e := ob.Fetch(req.ContractRegisterId)
  502. if e != nil {
  503. if e == utils.ErrNoRow {
  504. resp.Fail("合同登记不存在或已被删除", c)
  505. return
  506. }
  507. resp.FailMsg("获取合同登记失败", "Err:"+e.Error(), c)
  508. return
  509. }
  510. nowTime := time.Now().Local()
  511. item.ContractStatus = req.ContractStatus
  512. item.ModifyTime = nowTime
  513. updateCols := []string{"ContractStatus", "ModifyTime"}
  514. if e = item.Update(updateCols); e != nil {
  515. resp.FailMsg("操作失败", "更新合同登记失败, Err:"+e.Error(), c)
  516. return
  517. }
  518. // 校验金额-是否修改状态
  519. go fmsService.CheckContractRegisterAmount(req.ContractRegisterId)
  520. // 操作日志
  521. go func() {
  522. opData := ""
  523. opDataByte, e := json.Marshal(req)
  524. if e != nil {
  525. return
  526. }
  527. opData = string(opDataByte)
  528. logItem := new(fms.ContractRegisterLog)
  529. logItem.ContractRegisterId = req.ContractRegisterId
  530. logItem.AdminId = int(adminInfo.AdminId)
  531. logItem.AdminName = adminInfo.RealName
  532. logItem.OpData = opData
  533. logItem.OpType = fms.ContractRegisterOpTypeStatus
  534. logItem.CreateTime = nowTime
  535. if e = logItem.Create(); e != nil {
  536. return
  537. }
  538. }()
  539. resp.Ok("操作成功", c)
  540. }
  541. // Invoice
  542. // @Title 开票/到款登记
  543. // @Description 开票/到款登记
  544. // @Param request body fms.ContractInvoiceSaveReq true "type json string"
  545. // @Success 200 string "操作成功"
  546. // @router /contract/register/invoice [post]
  547. func (rg *RegisterController) Invoice(c *gin.Context) {
  548. req := new(fms.ContractInvoiceSaveReq)
  549. err := c.ShouldBind(&req)
  550. if err != nil {
  551. errs, ok := err.(validator.ValidationErrors)
  552. if !ok {
  553. resp.FailData("参数解析失败", "Err:"+err.Error(), c)
  554. return
  555. }
  556. resp.FailData("参数解析失败", errs.Translate(global.Trans), c)
  557. return
  558. }
  559. claims, _ := c.Get("adminInfo")
  560. adminInfo := claims.(*system.SysAdmin)
  561. newInvoice := make([]*fms.ContractInvoice, 0)
  562. if len(req.AmountList) > 0 {
  563. for i := range req.AmountList {
  564. if req.AmountList[i].Amount <= 0 {
  565. resp.Fail("登记金额有误", c)
  566. return
  567. }
  568. if req.AmountList[i].InvoiceDate == "" {
  569. resp.Fail("请选择日期", c)
  570. return
  571. }
  572. t, e := time.ParseInLocation(utils.FormatDate, req.AmountList[i].InvoiceDate, time.Local)
  573. if e != nil {
  574. resp.FailData("日期格式有误", "Err:"+e.Error(), c)
  575. return
  576. }
  577. v := &fms.ContractInvoice{
  578. ContractRegisterId: req.ContractRegisterId,
  579. Amount: req.AmountList[i].Amount,
  580. InvoiceType: req.InvoiceType,
  581. InvoiceDate: t,
  582. AdminId: int(adminInfo.AdminId),
  583. AdminName: adminInfo.AdminName,
  584. }
  585. v.Set()
  586. newInvoice = append(newInvoice, v)
  587. }
  588. }
  589. // 删除并新增登记
  590. ob := new(fms.ContractInvoice)
  591. if e := ob.DeleteAndCreateNewInvoice(req.ContractRegisterId, req.InvoiceType, newInvoice); e != nil {
  592. resp.FailData("日期格式有误", "Err:"+e.Error(), c)
  593. return
  594. }
  595. // 校验金额-是否修改状态
  596. go fmsService.CheckContractRegisterAmount(req.ContractRegisterId)
  597. // 操作日志
  598. go func() {
  599. opData := ""
  600. opDataByte, e := json.Marshal(req)
  601. if e != nil {
  602. return
  603. }
  604. opData = string(opDataByte)
  605. opType := fms.ContractRegisterOpTypeInvoice
  606. if req.InvoiceType == fms.ContractInvoiceTypePay {
  607. opType = fms.ContractRegisterOpTypePayment
  608. }
  609. logItem := new(fms.ContractRegisterLog)
  610. logItem.ContractRegisterId = req.ContractRegisterId
  611. logItem.AdminId = int(adminInfo.AdminId)
  612. logItem.AdminName = adminInfo.RealName
  613. logItem.OpData = opData
  614. logItem.OpType = opType
  615. logItem.CreateTime = time.Now().Local()
  616. if e = logItem.Create(); e != nil {
  617. return
  618. }
  619. }()
  620. resp.Ok("操作成功", c)
  621. }
  622. // Export
  623. // @Title 合同登记-导出
  624. // @Description 合同登记-导出
  625. // @Param Keyword query string false "关键词"
  626. // @Param StartDate query string false "合同开始日期"
  627. // @Param EndDate query string false "合同结束日期"
  628. // @Param ServiceType query int false "套餐类型"
  629. // @Param ContractType query int false "合同类型"
  630. // @Param RegisterStatus query int false "登记状态"
  631. // @Success 200 string "操作成功"
  632. // @router /contract/register/export [get]
  633. func (rg *RegisterController) Export(c *gin.Context) {
  634. var req fms.ContractRegisterListReq
  635. if e := c.BindQuery(&req); e != nil {
  636. err, ok := e.(validator.ValidationErrors)
  637. if !ok {
  638. resp.FailData("参数解析失败", "Err:"+e.Error(), c)
  639. return
  640. }
  641. resp.FailData("参数解析失败", err.Translate(global.Trans), c)
  642. return
  643. }
  644. cond := `1 = 1`
  645. pars := make([]interface{}, 0)
  646. if req.Keyword != "" {
  647. kw := "%" + req.Keyword + "%"
  648. cond += ` AND (company_name LIKE ? OR contract_code LIKE ? OR seller_name LIKE ?)`
  649. pars = append(pars, kw, kw, kw)
  650. }
  651. if req.StartDate != "" && req.EndDate != "" {
  652. cond += ` AND (create_time BETWEEN ? AND ?)`
  653. pars = append(pars, req.StartDate, req.EndDate)
  654. }
  655. if req.ContractType != 0 {
  656. cond += ` AND contract_type = ?`
  657. pars = append(pars, req.ContractType)
  658. }
  659. if req.RegisterStatus != 0 {
  660. cond += ` AND register_status = ?`
  661. pars = append(pars, req.RegisterStatus)
  662. }
  663. if req.ServiceType != 0 {
  664. registerIds, e := fms.GetContractRegisterIdsByTempId(req.ServiceType)
  665. if e != nil {
  666. resp.FailMsg("获取失败", "获取合同登记IDs失败, Err: "+e.Error(), c)
  667. return
  668. }
  669. if len(registerIds) > 0 {
  670. cond += ` AND contract_register_id IN ?`
  671. pars = append(pars, registerIds)
  672. } else {
  673. cond += ` AND 1 = 2`
  674. }
  675. }
  676. // 获取列表数据
  677. cr := new(fms.ContractRegister)
  678. list, e := cr.List(cond, pars)
  679. if e != nil {
  680. resp.FailData("获取合同列表失败", "Err:"+e.Error(), c)
  681. return
  682. }
  683. if len(list) == 0 {
  684. resp.Fail("无有效数据可导出", c)
  685. return
  686. }
  687. registerIds := make([]int, 0)
  688. for i := range list {
  689. registerIds = append(registerIds, list[i].ContractRegisterId)
  690. }
  691. // 获取小套餐品种
  692. cpCond := `product_id = ? AND permission_name <> ?`
  693. cpPars := make([]interface{}, 0)
  694. cpPars = append(cpPars, crm.CompanyProductFicc, crm.ChartPermissionStrategyName)
  695. cp := new(crm.ChartPermission)
  696. permissionList, e := cp.List(cpCond, cpPars)
  697. if e != nil {
  698. resp.FailData("获取小套餐品种失败", "Err:"+e.Error(), c)
  699. return
  700. }
  701. permissionLen := len(permissionList)
  702. permissionNameIdMap := make(map[string]int)
  703. for i := range permissionList {
  704. permissionNameIdMap[permissionList[i].PermissionName] = permissionList[i].ChartPermissionId
  705. }
  706. // 获取套餐服务
  707. //serviceList, e := fms.GetContractServiceTemplateMapByProductId(crm.CompanyProductFicc)
  708. //if e != nil {
  709. // resp.FailData("获取套餐服务失败", "Err:"+e.Error(), c)
  710. // return
  711. //}
  712. // 套餐/开票/到款列表
  713. serviceMap := make(map[int][]*fms.ContractService)
  714. serviceChartPermissionsMap := make(map[int][]int)
  715. invoiceMap := make(map[int][]*fms.ContractInvoice)
  716. paymentMap := make(map[int][]*fms.ContractInvoice)
  717. maxInvoice := 0
  718. maxPayment := 0
  719. if len(registerIds) > 0 {
  720. // 获取套餐信息
  721. csCond := `contract_register_id IN ?`
  722. csPars := make([]interface{}, 0)
  723. csPars = append(csPars, registerIds)
  724. cs := new(fms.ContractService)
  725. serviceList, e := cs.List(csCond, csPars)
  726. if e != nil {
  727. resp.FailData("获取合同套餐列表失败", "Err:"+e.Error(), c)
  728. return
  729. }
  730. for i := range serviceList {
  731. cid := serviceList[i].ContractRegisterId
  732. if serviceMap[cid] == nil {
  733. serviceMap[cid] = make([]*fms.ContractService, 0)
  734. }
  735. serviceMap[cid] = append(serviceMap[cid], serviceList[i])
  736. // 小套餐权限
  737. if serviceChartPermissionsMap[cid] == nil {
  738. serviceChartPermissionsMap[cid] = make([]int, 0)
  739. }
  740. if serviceList[i].ChartPermissionIds != "" {
  741. ids := utils.JoinStr2IntArr(serviceList[i].ChartPermissionIds, ",")
  742. serviceChartPermissionsMap[cid] = append(serviceChartPermissionsMap[cid], ids...)
  743. }
  744. }
  745. // 获取开票/到款详情, 并取最大的开票/到款数(用于动态扩展第二列表头)
  746. ci := new(fms.ContractInvoice)
  747. invoiceList, e := ci.List(csCond, csPars)
  748. if e != nil {
  749. resp.FailData("获取开票/到款列表失败", "Err:"+e.Error(), c)
  750. return
  751. }
  752. for k := range invoiceList {
  753. cid := invoiceList[k].ContractRegisterId
  754. if invoiceMap[cid] == nil {
  755. invoiceMap[cid] = make([]*fms.ContractInvoice, 0)
  756. }
  757. if paymentMap[cid] == nil {
  758. paymentMap[cid] = make([]*fms.ContractInvoice, 0)
  759. }
  760. if invoiceList[k].InvoiceType == fms.ContractInvoiceTypeMake {
  761. invoiceMap[cid] = append(invoiceMap[cid], invoiceList[k])
  762. continue
  763. }
  764. if invoiceList[k].InvoiceType == fms.ContractInvoiceTypePay {
  765. paymentMap[cid] = append(paymentMap[cid], invoiceList[k])
  766. continue
  767. }
  768. }
  769. // 取最大开票/到款数
  770. for j := range invoiceMap {
  771. if len(invoiceMap[j]) > maxInvoice {
  772. maxInvoice = len(invoiceMap[j])
  773. }
  774. }
  775. for p := range paymentMap {
  776. if len(paymentMap[p]) > maxPayment {
  777. maxPayment = len(paymentMap[p])
  778. }
  779. }
  780. }
  781. // 生成Excel文件
  782. //dir, err := os.Executable()
  783. //exPath := filepath.Dir(dir)
  784. //filePath := exPath + "/" + time.Now().Format(utils.FormatDateTimeUnSpace) + ".xlsx"
  785. xlsxFile := xlsx.NewFile()
  786. //if err != nil {
  787. // resp.FailData("生成文件失败", "Err:"+err.Error(), c)
  788. // return
  789. //}
  790. style := xlsx.NewStyle()
  791. alignment := xlsx.Alignment{
  792. Horizontal: "center",
  793. Vertical: "center",
  794. WrapText: true,
  795. }
  796. style.Alignment = alignment
  797. style.ApplyAlignment = true
  798. sheet, err := xlsxFile.AddSheet("合同登记")
  799. if err != nil {
  800. resp.FailData("新增Sheet失败", "Err:"+err.Error(), c)
  801. return
  802. }
  803. //_ = sheet.SetColWidth(0, 0, 60)
  804. //_ = sheet.SetColWidth(4, 10, 60)
  805. // 1行表头
  806. titleRow := sheet.AddRow()
  807. titleRow.SetHeight(40)
  808. // 1行1列-右合并两格
  809. cell1 := titleRow.AddCell()
  810. cell1.HMerge = 2
  811. cell1.SetValue("FICC客户签约表 2022")
  812. cell1.SetStyle(style)
  813. // 右增两列空白格用于第一列合并, 否则后续单元格合并会有问题
  814. titleRow.AddCell().SetValue("")
  815. titleRow.AddCell().SetValue("")
  816. // 1行2列
  817. cell2 := titleRow.AddCell()
  818. cell2.SetValue("商品大套餐")
  819. cell2.SetStyle(style)
  820. // 1行3列-右合并小套餐数
  821. if permissionLen >= 1 {
  822. cell3 := titleRow.AddCell()
  823. cell3.HMerge = permissionLen - 1
  824. cell3.SetValue("商品小套餐")
  825. cell3.SetStyle(style)
  826. // 同上右增单元格小套餐数-1的空白单元格用于合并
  827. for i := 0; i < permissionLen-1; i++ {
  828. titleRow.AddCell().SetValue("")
  829. }
  830. }
  831. cell4 := titleRow.AddCell()
  832. cell4.SetValue("市场策略")
  833. cell4.SetStyle(style)
  834. cell5 := titleRow.AddCell()
  835. cell5.SetValue("财富管理")
  836. cell5.SetStyle(style)
  837. // 第二行表头
  838. titleRow2 := sheet.AddRow()
  839. titleRow2.SetHeight(60)
  840. row2Title := make([]string, 0)
  841. row2Title = append(row2Title, "客户名称", "续约-0\n新增-1", "销售", "商品大套餐")
  842. for i := range permissionList {
  843. row2Title = append(row2Title, permissionList[i].PermissionName)
  844. }
  845. row2Title = append(row2Title, "市场策略", "财富管理", "开始时间", "到期时间", "2022年合同金额", "约定付款时间", "签订日",
  846. "签订月", "合同状态", "合同编号", "备注")
  847. for i := range row2Title {
  848. v := titleRow2.AddCell()
  849. v.SetValue(row2Title[i])
  850. v.SetStyle(style)
  851. }
  852. // 第二行表头-开票/收款(动态添加)
  853. for i := 0; i < maxInvoice; i++ {
  854. n := i + 1
  855. c1 := titleRow2.AddCell()
  856. t1 := fmt.Sprintf("%s%d", "开票日", n)
  857. c1.SetValue(t1)
  858. c1.SetStyle(style)
  859. c2 := titleRow2.AddCell()
  860. t2 := fmt.Sprintf("%s%d", "开票金额", n)
  861. c2.SetValue(t2)
  862. c2.SetStyle(style)
  863. row2Title = append(row2Title, t1, t2)
  864. }
  865. for i := 0; i < maxPayment; i++ {
  866. n := i + 1
  867. c1 := titleRow2.AddCell()
  868. t1 := fmt.Sprintf("%s%d", "收款月", n)
  869. c1.SetValue(t1)
  870. c1.SetStyle(style)
  871. c2 := titleRow2.AddCell()
  872. t2 := fmt.Sprintf("%s%d", "收款金额", n)
  873. c2.SetValue(t2)
  874. c2.SetStyle(style)
  875. row2Title = append(row2Title, t1, t2)
  876. }
  877. // 此处取第二行标题NameKeyMap, 后面的动态匹配
  878. row2NameKeyMap := make(map[string]int)
  879. for i := range row2Title {
  880. row2NameKeyMap[row2Title[i]] = i
  881. }
  882. contractTMap := map[int]int{
  883. fms.ContractTypeNew: 1,
  884. fms.ContractTypeRenew: 0,
  885. }
  886. for _, v := range list {
  887. k := -1
  888. dataRow := sheet.AddRow()
  889. dataRow.SetHeight(20)
  890. k += 3
  891. dataRow.AddCell().SetString(v.CompanyName)
  892. dataRow.AddCell().SetString(fmt.Sprint(contractTMap[v.ContractType]))
  893. dataRow.AddCell().SetString(v.SellerName)
  894. // 大套餐
  895. k += 1
  896. col4Name := row2Title[k]
  897. svList := serviceMap[v.ContractRegisterId]
  898. col4 := ""
  899. if svList != nil && len(svList) > 0 {
  900. for isv := range svList {
  901. if svList[isv].Title == col4Name {
  902. col4 = "是"
  903. break
  904. }
  905. }
  906. }
  907. dataRow.AddCell().SetString(col4)
  908. // 小套餐
  909. serviceChartPermissionIds := serviceChartPermissionsMap[v.ContractRegisterId]
  910. for i := 0; i < permissionLen; i++ {
  911. k += 1
  912. colName := row2Title[k]
  913. chartPermissionId := permissionNameIdMap[colName]
  914. if utils.InArray(chartPermissionId, serviceChartPermissionIds) {
  915. dataRow.AddCell().SetString("是")
  916. } else {
  917. dataRow.AddCell().SetString("")
  918. }
  919. }
  920. // 财富管理/市场策略(处理方式其实跟上面的大套餐一样, 只是中间隔了小套餐按照顺序要这么处理=_=!)
  921. k += 1
  922. col5Name := row2Title[k]
  923. col5 := ""
  924. if svList != nil && len(svList) > 0 {
  925. for isv := range svList {
  926. if svList[isv].Title == col5Name {
  927. col5 = "是"
  928. break
  929. }
  930. }
  931. }
  932. dataRow.AddCell().SetString(col5)
  933. k += 1
  934. col6Name := row2Title[k]
  935. col6 := ""
  936. if svList != nil && len(svList) > 0 {
  937. for isv := range svList {
  938. if svList[isv].Title == col6Name {
  939. col6 = "是"
  940. break
  941. }
  942. }
  943. }
  944. dataRow.AddCell().SetString(col6)
  945. // 其他信息
  946. dataRow.AddCell().SetString(utils.TimeTransferString("2006/01/02", v.StartDate)) // 开始时间
  947. dataRow.AddCell().SetString(utils.TimeTransferString("2006/01/02", v.EndDate)) // 到期时间
  948. dataRow.AddCell().SetString(fmt.Sprint("¥", v.ContractAmount)) // 2022年合同金额
  949. dataRow.AddCell().SetString(v.AgreedPayTime) // 约定付款时间
  950. dataRow.AddCell().SetString(utils.TimeTransferString("2006/01/02", v.SignDate)) // 签订日
  951. dataRow.AddCell().SetString(utils.TimeTransferString("2006/01", v.SignDate)) // 签订月
  952. dataRow.AddCell().SetString(fms.ContractStatusKeyNameMap[v.ContractStatus]) // 合同状态
  953. dataRow.AddCell().SetString(v.ContractCode) // 合同编号
  954. dataRow.AddCell().SetString(v.Remark) // 备注
  955. // 开票/到款信息
  956. ivList := invoiceMap[v.ContractRegisterId]
  957. if ivList != nil && len(ivList) > 0 {
  958. for ia := range ivList {
  959. dataRow.AddCell().SetString(utils.TimeTransferString("2006/01/02", ivList[ia].InvoiceDate)) // 开票日
  960. dataRow.AddCell().SetString(fmt.Sprint(ivList[ia].Amount)) // 开票金额
  961. }
  962. }
  963. pyList := paymentMap[v.ContractRegisterId]
  964. if pyList != nil && len(pyList) > 0 {
  965. for ib := range pyList {
  966. dataRow.AddCell().SetString(utils.TimeTransferString("2006年01月", pyList[ib].InvoiceDate)) // 收款月
  967. dataRow.AddCell().SetString(fmt.Sprint(pyList[ib].Amount)) // 收款金额
  968. }
  969. }
  970. }
  971. // 输出文件
  972. var buffer bytes.Buffer
  973. _ = xlsxFile.Write(&buffer)
  974. content := bytes.NewReader(buffer.Bytes())
  975. //err = xlsxFile.Save(filePath)
  976. //if err != nil {
  977. // resp.FailData("保存文件失败", "Err:"+err.Error(), c)
  978. // return
  979. //}
  980. //defer func() {
  981. // _ = os.Remove(filePath)
  982. //}()
  983. randStr := time.Now().Format(utils.FormatDateTimeUnSpace)
  984. fileName := "财务列表_" + randStr + ".xlsx"
  985. c.Writer.Header().Add("Content-Disposition", fmt.Sprintf(`attachment; filename="%s"`, fileName))
  986. c.Writer.Header().Add("Content-Type", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
  987. http.ServeContent(c.Writer, c.Request, fileName, time.Now(), content)
  988. }