register.go 33 KB

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