contract_register.go 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402
  1. package fms
  2. import (
  3. "errors"
  4. "fmt"
  5. "github.com/shopspring/decimal"
  6. "hongze/fms_api/models/base"
  7. "hongze/fms_api/models/crm"
  8. "hongze/fms_api/models/fms"
  9. "hongze/fms_api/services/alarm_msg"
  10. crmService "hongze/fms_api/services/crm"
  11. "hongze/fms_api/services/resource"
  12. "hongze/fms_api/utils"
  13. "os"
  14. "regexp"
  15. "sort"
  16. "strings"
  17. "time"
  18. )
  19. // CheckContractRegisterAmount 校验合同登记金额-判断是否需要更新合同登记状态
  20. func CheckContractRegisterAmount(registerId int) {
  21. var err error
  22. defer func() {
  23. if err != nil {
  24. alarm_msg.SendAlarmMsg("校验合同登记金额失败, ErrMsg: "+err.Error(), 3)
  25. }
  26. }()
  27. // 获取合同登记信息
  28. cr := new(fms.ContractRegister)
  29. item, e := cr.Fetch(registerId)
  30. if e != nil {
  31. err = errors.New("获取合同登记信息失败, Err: " + e.Error())
  32. return
  33. }
  34. amount := decimal.NewFromFloat(item.ContractAmount).Round(2)
  35. // 获取开票/到款信息
  36. invoiceCond := `contract_register_id = ?`
  37. invoicePars := make([]interface{}, 0)
  38. invoicePars = append(invoicePars, registerId)
  39. ci := new(fms.ContractInvoice)
  40. invoiceList, e := ci.List(invoiceCond, invoicePars, "")
  41. if e != nil {
  42. err = errors.New("获取开票到款信息失败, Err: " + e.Error())
  43. return
  44. }
  45. invoiceAmount := decimal.NewFromFloat(0).Round(2)
  46. paymentAmount := decimal.NewFromFloat(0).Round(2)
  47. for i := range invoiceList {
  48. a := decimal.NewFromFloat(invoiceList[i].OriginAmount).Round(2)
  49. if invoiceList[i].InvoiceType == fms.ContractInvoiceTypeMake {
  50. invoiceAmount = invoiceAmount.Add(a)
  51. }
  52. if invoiceList[i].InvoiceType == fms.ContractInvoiceTypePay {
  53. paymentAmount = paymentAmount.Add(a)
  54. }
  55. }
  56. status := fms.ContractRegisterStatusIng
  57. // 以下情况更新合同登记状态为已完成
  58. // 1.合同存在代付; 2.合同状态为已签回且合同金额=开票金额=到款金额; 3合同状态为已终止
  59. if item.HasPayment == 1 || (amount.Equal(invoiceAmount) && invoiceAmount.Equal(paymentAmount) && item.ContractStatus == fms.ContractStatusCheckedBack) || item.ContractStatus == fms.ContractStatusEnd {
  60. status = fms.ContractRegisterStatusComplete
  61. }
  62. updateCols := []string{"InvoicedAmount", "PaymentAmount", "RegisterStatus", "ModifyTime"}
  63. ia, _ := invoiceAmount.Round(2).Float64()
  64. pa, _ := paymentAmount.Round(2).Float64()
  65. item.InvoicedAmount = ia
  66. item.PaymentAmount = pa
  67. item.RegisterStatus = status
  68. item.ModifyTime = time.Now().Local()
  69. if e = item.Update(updateCols); e != nil {
  70. err = errors.New("更新合同登记金额及状态失败, Err: " + e.Error())
  71. return
  72. }
  73. return
  74. }
  75. // HandleContractServiceAndDetail 根据请求数据获取套餐服务详情信息
  76. func HandleContractServiceAndDetail(serviceList []fms.ContractServiceAddReq, base642Image bool, serviceAmountMap map[int]float64) (serviceDetailList []*fms.ContractServiceAndDetail, err error) {
  77. serviceDetailList = make([]*fms.ContractServiceAndDetail, 0)
  78. if len(serviceList) < 0 {
  79. err = errors.New("请至少选择一种套餐")
  80. return
  81. }
  82. // todo 如果权益套餐中只有行业套餐,需要均分套餐金额,否则无需均分
  83. for i := 0; i < len(serviceList); i++ {
  84. item := serviceList[i]
  85. hasDetail := "否"
  86. // 合同模板
  87. serviceTemp, e := fms.GetContractServiceTemplateById(item.ServiceTemplateId)
  88. if e != nil {
  89. err = errors.New("找不到该模板")
  90. return
  91. }
  92. serviceDetail := &fms.ContractServiceAndDetail{
  93. ServiceTemplateId: item.ServiceTemplateId,
  94. Title: item.Title,
  95. Value: item.Value,
  96. ProductId: serviceTemp.ProductId,
  97. HasDetail: hasDetail,
  98. TableValue: serviceTemp.TableValue,
  99. ChartPermissionId: serviceTemp.ChartPermissionId,
  100. ChartPermissionIds: item.ChartPermissionIds,
  101. //Detail: detailList,
  102. }
  103. serviceDetailList = append(serviceDetailList, serviceDetail)
  104. }
  105. return
  106. }
  107. // HandleContractServiceAmount 根据请求数据获取套餐金额详情信息
  108. func HandleContractServiceAmount(serviceAmountList []fms.ContractServiceAmountAddReq, serviceAmountMap map[int]float64, currencyUnit string) (list []*fms.ContractServiceAmount, err error) {
  109. if len(serviceAmountList) < 0 {
  110. err = errors.New("请至少输入一种套餐金额信息")
  111. return
  112. }
  113. for i := 0; i < len(serviceAmountList); i++ {
  114. item := serviceAmountList[i]
  115. serviceAmountMap[item.ProductId] = item.ServiceAmount
  116. serviceDetail := &fms.ContractServiceAmount{
  117. ProductId: item.ProductId,
  118. ServiceAmount: item.ServiceAmount,
  119. CurrencyUnit: currencyUnit,
  120. TimeBase: base.TimeBase{},
  121. }
  122. list = append(list, serviceDetail)
  123. }
  124. return
  125. }
  126. // GetContractServiceAndDetail 根据合同登记ID获取服务详情
  127. func GetContractServiceAndDetail(contractRegisterId int) (serviceList []*fms.ContractServiceAndDetail, err error) {
  128. list, e := fms.GetContractServiceAndDetailList(contractRegisterId)
  129. if e != nil {
  130. err = errors.New(fmt.Sprint("查找合同服务异常", e))
  131. return
  132. }
  133. serviceList = list
  134. //newLen := len(serviceList)
  135. //for i := 0; newLen > i; i++ {
  136. // if serviceList[i].HasDetail == "是" {
  137. // detail, e := fms.GetContractServiceDetailByServiceId(serviceList[i].ContractServiceId)
  138. // if e != nil {
  139. // err = errors.New(fmt.Sprint("查找合同服务详情异常", e))
  140. // return
  141. // }
  142. // serviceList[i].Detail = detail
  143. // }
  144. //}
  145. return
  146. }
  147. // UploadImageBase64 将base64的图片上传至oss
  148. func UploadImageBase64(base64Str string) (resourceUrl string, err error) {
  149. ext := ".png"
  150. uploadDir := "./static"
  151. randStr := utils.GetRandStringNoSpecialChar(28)
  152. fileName := randStr + ext
  153. fpath := uploadDir + "/" + fileName
  154. b, _ := regexp.MatchString(`^data:\s*image\/(\w+);base64,`, base64Str)
  155. if !b {
  156. err = errors.New("图片格式不正确")
  157. return
  158. }
  159. re, _ := regexp.Compile(`^data:\s*image\/(\w+);base64,`)
  160. base64Str = re.ReplaceAllString(base64Str, "")
  161. base64Str = strings.Replace(base64Str, " ", "", -1)
  162. base64Str = strings.Replace(base64Str, " ", "", -1)
  163. err = utils.SaveBase64ToFile(base64Str, fpath)
  164. if err != nil {
  165. return
  166. }
  167. defer os.Remove(fpath)
  168. savePath := utils.OssUploadImgDir + time.Now().Format("200601/20060102/")
  169. savePath += fileName
  170. // 上传到阿里云
  171. err = resource.UploadVideoAliyun(fileName, fpath, savePath)
  172. if err != nil {
  173. return
  174. }
  175. resourceUrl = utils.OssHost + savePath
  176. return
  177. }
  178. // FixContractInvoiceSellerInfo 修复开票登记销售相关信息(一次性)
  179. func FixContractInvoiceSellerInfo() {
  180. sellerList, e := crmService.GetSellerDepartmentListWithGroupAndTeam()
  181. if e != nil {
  182. fmt.Println("获取销售列表失败, Err: " + e.Error())
  183. return
  184. }
  185. sellerMap := make(map[int]*crm.SellerAdminWithGroupTeam)
  186. for i := range sellerList {
  187. sellerMap[sellerList[i].SellerId] = sellerList[i]
  188. }
  189. registerCond := ``
  190. registerPars := make([]interface{}, 0)
  191. registerOB := new(fms.ContractRegister)
  192. registerList, e := registerOB.List(registerCond, registerPars)
  193. if e != nil {
  194. fmt.Println("获取合同登记列表失败, Err: " + e.Error())
  195. return
  196. }
  197. invUpCols := []string{"SellerId", "SellerName", "SellerGroupId", "SellerGroupName", "SellerTeamId", "SellerTeamName"}
  198. fmt.Println("start 修复")
  199. for i := range registerList {
  200. registerId := registerList[i].ContractRegisterId
  201. sellerId := registerList[i].SellerId
  202. sellerItem := sellerMap[sellerId]
  203. if sellerItem == nil {
  204. fmt.Printf("ID-%d 无销售信息\n", registerId)
  205. continue
  206. }
  207. invOB := new(fms.ContractInvoice)
  208. invCond := `invoice_type = 1 AND contract_register_id = ?`
  209. invPars := make([]interface{}, 0)
  210. invPars = append(invPars, registerId)
  211. invList, e := invOB.List(invCond, invPars, "")
  212. if e != nil {
  213. fmt.Println("获取开票登记列表失败, Err: " + e.Error())
  214. return
  215. }
  216. for _, v := range invList {
  217. v.SellerId = sellerItem.SellerId
  218. v.SellerName = sellerItem.SellerName
  219. v.SellerGroupId = sellerItem.GroupId
  220. v.SellerGroupName = sellerItem.GroupName
  221. v.SellerTeamId = sellerItem.TeamId
  222. v.SellerTeamName = sellerItem.TeamName
  223. if e = v.Update(invUpCols); e != nil {
  224. fmt.Println("更新开票登记失败, Err: " + e.Error())
  225. return
  226. }
  227. fmt.Printf("ID-%d 修复成功\n", v.ContractInvoiceId)
  228. }
  229. }
  230. fmt.Println("end 修复")
  231. return
  232. }
  233. // FixContractInvoicePaymentType 修复历史到款登记付款方式(一次性)
  234. func FixContractInvoicePaymentType() {
  235. registerCond := ``
  236. registerPars := make([]interface{}, 0)
  237. registerOB := new(fms.ContractRegister)
  238. registerList, e := registerOB.List(registerCond, registerPars)
  239. if e != nil {
  240. fmt.Println("获取合同登记列表失败, Err: " + e.Error())
  241. return
  242. }
  243. invUpCols := []string{"PayType"}
  244. fmt.Println("start 修复")
  245. for i := range registerList {
  246. registerId := registerList[i].ContractRegisterId
  247. invOB := new(fms.ContractInvoice)
  248. invCond := `invoice_type = 2 AND contract_register_id = ?`
  249. invPars := make([]interface{}, 0)
  250. invPars = append(invPars, registerId)
  251. invList, e := invOB.List(invCond, invPars, "")
  252. if e != nil {
  253. fmt.Println("获取到款登记列表失败, Err: " + e.Error())
  254. return
  255. }
  256. dayDiff := registerList[i].EndDate.Sub(registerList[i].StartDate).Hours() / 24
  257. for _, v := range invList {
  258. v.PayType = CalculateContractPaymentType(v.Amount, registerList[i].ContractAmount, dayDiff)
  259. if e = v.Update(invUpCols); e != nil {
  260. fmt.Println("更新到款登记付款方式失败, Err: " + e.Error())
  261. return
  262. }
  263. fmt.Printf("ID-%d 修复成功\n", v.ContractInvoiceId)
  264. }
  265. }
  266. fmt.Println("end 修复")
  267. return
  268. }
  269. // FixContractSummaryData 修复开票到款汇总数据(一次性)
  270. func FixContractSummaryData() {
  271. registerCond := ``
  272. registerPars := make([]interface{}, 0)
  273. registerOB := new(fms.ContractRegister)
  274. registerList, e := registerOB.List(registerCond, registerPars)
  275. if e != nil {
  276. fmt.Println("获取合同登记列表失败, Err: " + e.Error())
  277. return
  278. }
  279. fmt.Println("start 修复")
  280. for i := range registerList {
  281. fmt.Printf("正在修复-%d", registerList[i].ContractRegisterId)
  282. SummaryInvoicePaymentByContractRegisterId(registerList[i].ContractRegisterId)
  283. }
  284. fmt.Println("end 修复")
  285. return
  286. }
  287. func GetContractServiceNameFormat(registerIds []int) (serviceNameMap map[int]string, serviceFormatMap map[int][]fms.ContractServiceTemplateFormat, err error) {
  288. serviceNameMap = make(map[int]string)
  289. serviceMap := make(map[int][]string, 0)
  290. serviceFormatMap = make(map[int][]fms.ContractServiceTemplateFormat, 0)
  291. serviceIndustryStr := "医药,消费,科技,智造"
  292. serviceIdMap := make(map[int]*fms.ContractServiceTemplateFullName, 0)
  293. serviceIndustryMap := make(map[int]map[string][]*fms.ContractServiceTemplateFullName, 0)
  294. allServiceList, e := fms.GetContractServiceTemplateFullName()
  295. if e != nil {
  296. err = fmt.Errorf("获取所有套餐失败, Err: "+e.Error())
  297. return
  298. }
  299. for _, v := range allServiceList {
  300. serviceIdMap[v.ServiceTemplateId] = v
  301. }
  302. // 获取服务套餐
  303. servicesList, e := fms.GetContractRegisterServicesByRegisterIds(registerIds)
  304. if e != nil {
  305. err = fmt.Errorf("获取套餐字符串失败, Err: "+e.Error())
  306. return
  307. }
  308. for i := range servicesList {
  309. item := servicesList[i]
  310. if item.Title == "行业套餐" || item.Title == "权益大套餐" {
  311. continue
  312. }
  313. if fullItem, ok := serviceIdMap[item.ServiceTemplateId]; ok {
  314. if fullItem.ParentTitle == "行业套餐" {
  315. continue
  316. }
  317. if fullItem.ParentTitle != "" {
  318. if strings.Contains(serviceIndustryStr, fullItem.ParentTitle) {
  319. if _, ok1 := serviceIndustryMap[item.ContractRegisterId]; !ok1 {
  320. serviceIndustryMap[item.ContractRegisterId] = make(map[string][]*fms.ContractServiceTemplateFullName)
  321. }
  322. serviceIndustryMap[item.ContractRegisterId][fullItem.ParentTitle] = append(serviceIndustryMap[item.ContractRegisterId][fullItem.ParentTitle], fullItem)
  323. } else {
  324. formatTitle := ""
  325. if fullItem.ParentTitle == "策略" {
  326. formatTitle = fullItem.Title
  327. }else{
  328. formatTitle = fullItem.ParentTitle+"("+fullItem.Title+")"
  329. }
  330. serviceMap[item.ContractRegisterId] = append(serviceMap[item.ContractRegisterId], formatTitle)
  331. tmp := fms.ContractServiceTemplateFormat{
  332. FormatTitle: formatTitle,
  333. ServiceTemplateId: fullItem.ServiceTemplateId,
  334. ServiceTemplatePid: fullItem.Pid,
  335. }
  336. serviceFormatMap[item.ContractRegisterId] = append(serviceFormatMap[item.ContractRegisterId], tmp)
  337. }
  338. }else{
  339. serviceMap[item.ContractRegisterId] = append(serviceMap[item.ContractRegisterId], fullItem.Title)
  340. tmp := fms.ContractServiceTemplateFormat{
  341. FormatTitle: fullItem.Title,
  342. ServiceTemplateId: fullItem.ServiceTemplateId,
  343. ServiceTemplatePid: fullItem.Pid,
  344. }
  345. serviceFormatMap[item.ContractRegisterId] = append(serviceFormatMap[item.ContractRegisterId], tmp)
  346. }
  347. }
  348. }
  349. for k, v := range serviceIndustryMap {
  350. for sk, sv := range v {
  351. formatTitle := ""
  352. templateId := 0
  353. pid := 0
  354. if len(sv) >= 2 {
  355. formatTitle = sk
  356. templateId = sv[0].Pid
  357. }else{
  358. formatTitle = sk+"("+sv[0].Title+")"
  359. templateId = sv[0].ServiceTemplateId
  360. pid = sv[0].Pid
  361. }
  362. serviceMap[k] = append(serviceMap[k], formatTitle)
  363. tmp := fms.ContractServiceTemplateFormat{
  364. FormatTitle: formatTitle,
  365. ServiceTemplateId: templateId,
  366. ServiceTemplatePid: pid,
  367. }
  368. serviceFormatMap[k] = append(serviceFormatMap[k], tmp)
  369. }
  370. }
  371. // 给套餐内容排序
  372. for k, v := range serviceFormatMap {
  373. sort.Sort(fms.ContractServiceTemplateFormatList(v))
  374. for _, sv := range v {
  375. serviceNameMap[k] += sv.FormatTitle+","
  376. }
  377. serviceNameMap[k] = strings.Trim(serviceNameMap[k], ",")
  378. }
  379. return
  380. }