contract.go 63 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853
  1. package contract
  2. import (
  3. "encoding/json"
  4. "errors"
  5. "fmt"
  6. "github.com/beego/beego/v2/client/orm"
  7. "github.com/shopspring/decimal"
  8. "hongze/hz_crm_api/models"
  9. "hongze/hz_crm_api/models/company"
  10. "hongze/hz_crm_api/models/contract"
  11. "hongze/hz_crm_api/models/contract/request"
  12. "hongze/hz_crm_api/models/system"
  13. "hongze/hz_crm_api/services"
  14. "hongze/hz_crm_api/utils"
  15. "mime/multipart"
  16. "os"
  17. "reflect"
  18. "regexp"
  19. "sort"
  20. "strconv"
  21. "strings"
  22. "time"
  23. )
  24. // AddContract 新增合同
  25. func AddContract(req request.AddContractReq, sellerId, productId int, sellerName string) (newContract *contract.Contract, err error, errMsg string) {
  26. originalPrice := req.OriginalPrice
  27. price := req.Price
  28. if originalPrice < 0 {
  29. err = errors.New("合同金额不能小于0")
  30. return
  31. }
  32. //如果优惠后金额小于等于0,那么就是等于优惠前的金额
  33. if price <= 0 {
  34. price = originalPrice
  35. }
  36. //合同日期
  37. var startDate, endDate time.Time
  38. if req.ContractBusinessType == "代付合同" {
  39. businessContractInfo, tmpErr := contract.GetContractById(req.RelationContractId)
  40. if tmpErr != nil {
  41. err = tmpErr
  42. return
  43. }
  44. startDate = businessContractInfo.StartDate
  45. endDate = businessContractInfo.EndDate
  46. ok, tmpErr := CheckContractPrice(businessContractInfo, price)
  47. if tmpErr != nil {
  48. err = tmpErr
  49. return
  50. }
  51. if !ok {
  52. err = errors.New("合同金额异常,不能高于业务合同金额")
  53. errMsg = "合同金额异常,不能高于业务合同金额"
  54. return
  55. }
  56. } else {
  57. tmpStartDate, tmpErr := time.ParseInLocation(utils.FormatDate, req.StartDate, time.Local)
  58. if tmpErr != nil {
  59. err = errors.New(fmt.Sprint("合同开始日期转换失败:", tmpErr))
  60. return
  61. }
  62. startDate = tmpStartDate
  63. tmpEndDate, tmpErr := time.ParseInLocation(utils.FormatDate, req.EndDate, time.Local)
  64. if tmpErr != nil {
  65. err = errors.New(fmt.Sprint("合同结束日期转换失败:", tmpErr))
  66. return
  67. }
  68. endDate = tmpEndDate
  69. }
  70. companyName := req.CompanyName
  71. if companyName == "" {
  72. err = errors.New("客户名称必填")
  73. return
  74. }
  75. creditCode := req.CreditCode
  76. if companyName == "" {
  77. err = errors.New("社会统一信用代码必填")
  78. return
  79. }
  80. contractCode, err := contract.GetCompanyContractCode(productId, req.ContractBusinessType)
  81. if err != nil {
  82. err = errors.New(fmt.Sprint("合同编号生成异常,Err:", err))
  83. return
  84. }
  85. //权益的新签合同重新定义,如果合同起始时间在第一份新签合同起始日期 1年之内的,仍为新签合同。
  86. if productId == utils.COMPANY_PRODUCT_RAI_ID && req.ContractType == "" {
  87. //根据社会信用码获取客户信息
  88. companyInfo, tmpErr := company.GetCompanyByCreditCode(creditCode)
  89. //如果查询异常,且并不是在系统中找不到该社会信用码,那么就异常返回
  90. if tmpErr != nil {
  91. err = errors.New(fmt.Sprint("根据社会信用码获取客户信息,Err:", tmpErr))
  92. return
  93. }
  94. totalLastYear, tmpErr := GetCompanyContractCountRaiByLastYear(companyInfo.CompanyId, req.StartDate)
  95. if tmpErr != nil {
  96. err = errors.New(fmt.Sprint("获取第一份新签合同起始日期是否1年之内失败,Err:", tmpErr))
  97. return
  98. }
  99. if totalLastYear > 0 {
  100. req.ContractType = "新签合同"
  101. } else {
  102. req.ContractType = "续约合同"
  103. }
  104. }
  105. contractInfo := &contract.Contract{
  106. ContractCode: contractCode,
  107. SellerId: sellerId,
  108. SellerName: sellerName,
  109. ProductId: productId,
  110. ContractType: req.ContractType,
  111. ContractBusinessType: req.ContractBusinessType,
  112. Status: "待提交",
  113. StartDate: startDate,
  114. EndDate: endDate,
  115. OriginalPrice: originalPrice,
  116. Price: price,
  117. PayRemark: utils.TrimStr(req.PayRemark), //付款方式说明,长度255位
  118. PayChannel: utils.TrimStr(req.PayChannel), //付款渠道,长度255位
  119. CompanyName: utils.TrimStr(companyName),
  120. CreditCode: utils.TrimStr(creditCode),
  121. ProvinceId: req.ProvinceId,
  122. Province: utils.TrimStr(req.Province),
  123. CityId: req.CityId,
  124. City: utils.TrimStr(req.City),
  125. Address: utils.TrimStr(req.Address),
  126. Fax: utils.TrimStr(req.Fax),
  127. Phone: utils.TrimStr(req.Phone),
  128. Postcode: utils.TrimStr(req.Postcode),
  129. Remark: req.Remark,
  130. SellerRemark: req.SellerRemark, //销售备注
  131. TemplateId: req.TemplateId,
  132. SourceId: req.SourceId, //来源合同id
  133. ModifyTime: time.Now(),
  134. CreateTime: time.Now(),
  135. }
  136. contractServiceSlice, err := getContractServiceAndDetail(contractInfo.ProductId, req.Service, true)
  137. if err != nil {
  138. return
  139. }
  140. newContract, err = contract.AddContract(contractInfo, contractServiceSlice, req.RelationContractId)
  141. if err != nil {
  142. return
  143. }
  144. //添加操作日志
  145. remark := "新增合同模板"
  146. if newContract.SourceId > 0 {
  147. remark = "复制模板"
  148. }
  149. _ = contract.AddContractOperationRecord(newContract.ContractId, newContract.SellerId, 0, "add", newContract.SellerName, remark)
  150. return
  151. }
  152. // EditContract 编辑合同
  153. func EditContract(req request.EditContractReq, opUser *system.Admin) (newContract *contract.Contract, err error, errMsg string) {
  154. //查询当前合同信息
  155. nowContract, err := contract.GetContractById(req.ContractId)
  156. if err != nil {
  157. if err.Error() == utils.ErrNoRow() {
  158. err = errors.New(fmt.Sprint("根据合同编号:", req.ContractId, " 找不到初始合同"))
  159. }
  160. return
  161. }
  162. if nowContract.SellerId != opUser.AdminId {
  163. err = errors.New("当前账号无操作权限")
  164. return
  165. }
  166. ignoreStatus := []string{"待提交", "已撤回", "已驳回", "已审批"}
  167. if !strings.Contains(strings.Join(ignoreStatus, ","), nowContract.Status) {
  168. err = errors.New("合同状态异常,不允许修改,当前合同状态:" + nowContract.Status)
  169. return
  170. }
  171. originalPrice := req.OriginalPrice
  172. price := req.Price
  173. if originalPrice < 0 {
  174. err = errors.New("合同金额不能小于0")
  175. return
  176. }
  177. //如果优惠后金额小于等于0,那么就是等于优惠前的金额
  178. if price <= 0 {
  179. price = originalPrice
  180. }
  181. checkPrice := price //代付合同,需要检查的需要支付的余额
  182. // 是否更新业务合同金额
  183. updateBusinessContractPrice := 0.0
  184. if nowContract.Status == "已审批" && nowContract.ContractBusinessType == "代付合同" {
  185. updateBusinessContractPrice = nowContract.Price
  186. //因为当前代付合同是已审批的,所以修改重审的时候:
  187. //需要检查的需要支付的余额 = 当前提交的金额 - 之前提交的金额
  188. checkPrice = price - nowContract.Price
  189. }
  190. //合同日期
  191. var startDate, endDate time.Time
  192. if nowContract.ContractBusinessType == "代付合同" {
  193. businessContractInfo, tmpErr := contract.GetContractById(req.RelationContractId)
  194. if tmpErr != nil {
  195. err = tmpErr
  196. return
  197. }
  198. startDate = businessContractInfo.StartDate
  199. endDate = businessContractInfo.EndDate
  200. ok, tmpErr := CheckContractPrice(businessContractInfo, checkPrice)
  201. if tmpErr != nil {
  202. err = tmpErr
  203. return
  204. }
  205. if !ok {
  206. err = errors.New("合同金额异常,不能高于业务合同金额")
  207. errMsg = "合同金额异常,不能高于业务合同金额"
  208. return
  209. }
  210. } else {
  211. tmpStartDate, tmpErr := time.ParseInLocation(utils.FormatDate, req.StartDate, time.Local)
  212. if tmpErr != nil {
  213. err = errors.New(fmt.Sprint("合同开始日期转换失败:", tmpErr))
  214. return
  215. }
  216. startDate = tmpStartDate
  217. tmpEndDate, tmpErr := time.ParseInLocation(utils.FormatDate, req.EndDate, time.Local)
  218. if tmpErr != nil {
  219. err = errors.New(fmt.Sprint("合同结束日期转换失败:", tmpErr))
  220. return
  221. }
  222. endDate = tmpEndDate
  223. }
  224. companyName := utils.TrimStr(req.CompanyName)
  225. if companyName == "" {
  226. err = errors.New("客户名称必填")
  227. return
  228. }
  229. creditCode := utils.TrimStr(req.CreditCode)
  230. if companyName == "" {
  231. err = errors.New("社会统一信用代码必填")
  232. return
  233. }
  234. modifyContent := "" //变更记录
  235. nowContract.ContractType = req.ContractType //合同类型
  236. nowContract.StartDate = startDate //合同开始日期
  237. nowContract.EndDate = endDate //合同结束日期
  238. nowContract.OriginalPrice = originalPrice //原始金额
  239. nowContract.Price = price //优惠后的金额
  240. nowContract.PayRemark = utils.TrimStr(req.PayRemark) //付款方式说明,长度255位
  241. nowContract.PayChannel = utils.TrimStr(req.PayChannel) //付款渠道,长度255位
  242. nowContract.CompanyName = companyName //企业客户名称
  243. nowContract.CreditCode = creditCode //组织社会信用代码
  244. nowContract.ProvinceId = req.ProvinceId //省级id
  245. nowContract.Province = utils.TrimStr(req.Province) //省
  246. nowContract.CityId = req.CityId //市级id
  247. nowContract.City = utils.TrimStr(req.City) //市
  248. nowContract.Address = utils.TrimStr(req.Address) //详细地址
  249. nowContract.Fax = utils.TrimStr(req.Fax) //传真
  250. nowContract.Phone = utils.TrimStr(req.Phone) //电话
  251. nowContract.FileUrl = "" //修改合同后,需要移除原有的合同附件
  252. nowContract.Postcode = utils.TrimStr(req.Postcode) //邮编
  253. nowContract.Remark = req.Remark //补充说明
  254. nowContract.SellerRemark = req.SellerRemark //销售备注
  255. nowContract.ModifyTime = time.Now() //更新时间
  256. nowContract.Status = "待提交" //合同状态
  257. //获取服务信息
  258. contractServiceSlice, err := getContractServiceAndDetail(nowContract.ProductId, req.Service, true)
  259. if err != nil {
  260. return
  261. }
  262. //最近一次审批通过或者驳回的申请单
  263. lastContractApproval, err := contract.GetLastContractApprovalByContractIdAndStatus(nowContract.ContractId, "contract")
  264. if err != nil && err.Error() != utils.ErrNoRow() {
  265. return
  266. }
  267. //如果有申请记录,且申请单的状态是已审批,那么审核内容是:修改重审
  268. if lastContractApproval != nil {
  269. //旧的合同信息
  270. var snapshotContract contract.ContractDetail
  271. jsonErr := json.Unmarshal([]byte(lastContractApproval.ContractDetail), &snapshotContract)
  272. if jsonErr != nil {
  273. err = jsonErr
  274. return
  275. }
  276. //applyContent = "修改重审"
  277. modifyContentStrList := make([]string, 0)
  278. //客户信息
  279. updateCompanyInfoStrList := contrastCompanyInfo(snapshotContract, *nowContract)
  280. if len(updateCompanyInfoStrList) > 0 {
  281. updateCompanyInfoStr := ``
  282. if len(updateCompanyInfoStrList) == 1 {
  283. updateCompanyInfoStr = fmt.Sprint("客户信息发生了变化:" + updateCompanyInfoStrList[0])
  284. } else {
  285. updateCompanyInfoStr = fmt.Sprint("客户信息发生了变化:</n>", strings.Join(updateCompanyInfoStrList, "</n>"))
  286. }
  287. modifyContentStrList = append(modifyContentStrList, updateCompanyInfoStr)
  288. }
  289. //金额、付款、合同日期方式
  290. updatePayInfoStrList := contrastPayInfo(snapshotContract, *nowContract)
  291. modifyContentStrList = append(modifyContentStrList, updatePayInfoStrList...)
  292. if len(modifyContentStrList) > 0 {
  293. modifyContent = strings.Join(updatePayInfoStrList, "<br/>")
  294. }
  295. //服务内容
  296. updateServiceStr, tmpErr := contrastServiceInfo(snapshotContract, contractServiceSlice)
  297. if tmpErr != nil {
  298. err = tmpErr
  299. return
  300. }
  301. if updateServiceStr != "" {
  302. modifyContentStrList = append(modifyContentStrList, updateServiceStr)
  303. }
  304. //补充内容
  305. if nowContract.Remark != snapshotContract.Remark {
  306. snapshotContractRemark := snapshotContract.Remark
  307. if snapshotContractRemark == "" {
  308. snapshotContractRemark = "无"
  309. }
  310. nowContractRemark := nowContract.Remark
  311. if nowContractRemark == "" {
  312. nowContractRemark = "无"
  313. }
  314. updateStr := fmt.Sprint("原补充内容:", snapshotContractRemark, "</n>现补充内容:", nowContractRemark)
  315. modifyContentStrList = append(modifyContentStrList, updateStr)
  316. }
  317. if len(modifyContentStrList) > 0 {
  318. modifyContent = strings.Join(modifyContentStrList, "<br/>")
  319. }
  320. }
  321. nowContract.ModifyContent = modifyContent //修改信息
  322. updateDetailCol := []string{"ContractType", "StartDate", "EndDate", "OriginalPrice", "Price", "PayRemark", "PayChannel", "CompanyName", "CreditCode", "ProvinceId", "Province", "CityId", "City", "Address", "Fax", "Phone", "FileUrl", "Postcode", "Remark", "SellerRemark", "ModifyContent", "ModifyTime", "Status"}
  323. //修改合同
  324. err = contract.EditContract(nowContract, updateDetailCol, contractServiceSlice, req.RelationContractId)
  325. //添加操作日志
  326. remark := "编辑合同模板"
  327. _ = contract.AddContractOperationRecord(nowContract.ContractId, nowContract.SellerId, 0, "edit", nowContract.SellerName, remark)
  328. //修改业务合同的已支付金额
  329. if updateBusinessContractPrice > 0 {
  330. go updateContractPaidPriceByPaymentOnBehalfContractId(nowContract.ContractId, -nowContract.Price)
  331. }
  332. //赋值返回
  333. newContract = nowContract
  334. return
  335. }
  336. // contrastCompanyInfo 比对客户信息是否变更
  337. func contrastCompanyInfo(snapshotContract contract.ContractDetail, nowContract contract.Contract) (updateStrList []string) {
  338. //客户信息比对
  339. if nowContract.CompanyName != snapshotContract.CompanyName {
  340. updateStrList = append(updateStrList, fmt.Sprint("原客户名称:", snapshotContract.CompanyName, "</n>现客户名称:", nowContract.CompanyName))
  341. }
  342. if nowContract.CreditCode != snapshotContract.CreditCode {
  343. updateStrList = append(updateStrList, fmt.Sprint("原社会信用码:", snapshotContract.CreditCode, "</n>现社会信用码:", nowContract.CreditCode))
  344. }
  345. if nowContract.Province != snapshotContract.Province || nowContract.City != snapshotContract.City {
  346. updateStrList = append(updateStrList, fmt.Sprint("原公司地址:", snapshotContract.Province, snapshotContract.City, "</n>现公司地址:", nowContract.Province, nowContract.City))
  347. }
  348. if nowContract.Address != snapshotContract.Address {
  349. snapshotContractAddress := snapshotContract.Address
  350. if snapshotContractAddress == "" {
  351. snapshotContractAddress = `无`
  352. }
  353. nowContractAddress := nowContract.Address
  354. if nowContractAddress == "" {
  355. nowContractAddress = `无`
  356. }
  357. updateStrList = append(updateStrList, fmt.Sprint("原详细地址:", snapshotContractAddress, "</n>现详细地址:", nowContractAddress))
  358. }
  359. if nowContract.Fax != snapshotContract.Fax {
  360. snapshotContractFax := snapshotContract.Fax
  361. if snapshotContractFax == "" {
  362. snapshotContractFax = `无`
  363. }
  364. nowContractFax := nowContract.Fax
  365. if nowContractFax == "" {
  366. nowContractFax = `无`
  367. }
  368. updateStrList = append(updateStrList, fmt.Sprint("原传真:", snapshotContractFax, "</n>现传真:", nowContractFax))
  369. }
  370. if nowContract.Phone != snapshotContract.Phone {
  371. snapshotContractPhone := snapshotContract.Phone
  372. if snapshotContractPhone == "" {
  373. snapshotContractPhone = `无`
  374. }
  375. nowContractPhone := nowContract.Phone
  376. if nowContractPhone == "" {
  377. nowContractPhone = `无`
  378. }
  379. updateStrList = append(updateStrList, fmt.Sprint("原电话:", snapshotContractPhone, "</n>现电话:", nowContractPhone))
  380. }
  381. if nowContract.Postcode != snapshotContract.Postcode {
  382. snapshotContractPostcode := snapshotContract.Postcode
  383. if snapshotContractPostcode == "" {
  384. snapshotContractPostcode = `无`
  385. }
  386. nowContractPostcode := nowContract.Postcode
  387. if nowContractPostcode == "" {
  388. nowContractPostcode = `无`
  389. }
  390. updateStrList = append(updateStrList, fmt.Sprint("原邮编:", snapshotContractPostcode, "</n>现邮编:", nowContractPostcode))
  391. }
  392. return
  393. }
  394. // contrastPayInfo 比对合同金额、付款方式是否变更
  395. func contrastPayInfo(snapshotContract contract.ContractDetail, nowContract contract.Contract) (updateStrList []string) {
  396. //合同信息比对
  397. if nowContract.StartDate != snapshotContract.StartDate || nowContract.EndDate != snapshotContract.EndDate {
  398. updateStrList = append(updateStrList, fmt.Sprint("原合同期限:", snapshotContract.StartDate.Format(utils.FormatDate), " ~ ", snapshotContract.EndDate.Format(utils.FormatDate), "</n>现合同期限:", nowContract.StartDate.Format(utils.FormatDate), " ~ ", nowContract.EndDate.Format(utils.FormatDate)))
  399. }
  400. if nowContract.ContractBusinessType == "代付合同" {
  401. if nowContract.Price != snapshotContract.Price {
  402. updateStrList = append(updateStrList, fmt.Sprint("原代付金额:", decimal.NewFromFloat(snapshotContract.Price).String(), "</n>现代付金额:", decimal.NewFromFloat(nowContract.Price).String()))
  403. }
  404. } else {
  405. if nowContract.OriginalPrice != snapshotContract.OriginalPrice {
  406. updateStrList = append(updateStrList, fmt.Sprint("原合同金额:", decimal.NewFromFloat(snapshotContract.OriginalPrice).String(), "</n>现合同金额:", decimal.NewFromFloat(nowContract.OriginalPrice).String()))
  407. }
  408. if nowContract.Price != snapshotContract.Price {
  409. updateStrList = append(updateStrList, fmt.Sprint("原优惠后金额:", decimal.NewFromFloat(snapshotContract.Price).String(), "</n>现优惠后金额:", decimal.NewFromFloat(nowContract.Price).String()))
  410. }
  411. }
  412. if nowContract.PayRemark != snapshotContract.PayRemark {
  413. snapshotContractInfo := snapshotContract.PayRemark
  414. if snapshotContractInfo == "" {
  415. snapshotContractInfo = "无"
  416. }
  417. nowContractInfo := nowContract.PayRemark
  418. if nowContractInfo == "" {
  419. nowContractInfo = "无"
  420. }
  421. updateStrList = append(updateStrList, fmt.Sprint("原付款方式:", snapshotContractInfo, "</n>现付款方式:", nowContractInfo))
  422. }
  423. if nowContract.PayChannel != snapshotContract.PayChannel {
  424. snapshotContractInfo := snapshotContract.PayChannel
  425. if snapshotContractInfo == "" {
  426. snapshotContractInfo = "无"
  427. }
  428. nowContractInfo := nowContract.PayChannel
  429. if nowContractInfo == "" {
  430. nowContractInfo = "无"
  431. }
  432. updateStrList = append(updateStrList, fmt.Sprint("原付款方:", snapshotContractInfo, "</n>现付款方:", nowContractInfo))
  433. }
  434. return
  435. }
  436. // contrastServiceInfo 比对合同服务内容是否变更
  437. func contrastServiceInfo(snapshotContract contract.ContractDetail, contractServiceSlice []*contract.ContractServiceAndDetail) (updateStr string, err error) {
  438. serviceList := snapshotContract.Service
  439. nowServiceList := contractServiceSlice
  440. // CRM8.8-权益的合同服务主客观合并
  441. if snapshotContract.ProductId == 2 {
  442. updateStr = handleRaiContractModifyContentByServices(serviceList, nowServiceList)
  443. return
  444. }
  445. snapshotPermissionList, err := GetPermissionByContractService(snapshotContract.ProductId, serviceList)
  446. if err != nil {
  447. return
  448. }
  449. allPermissionMap := make(map[int]string)
  450. snapshotPermissionIdList := make([]int, 0)
  451. for _, permissionItem := range snapshotPermissionList {
  452. for _, permission := range permissionItem.Items {
  453. allPermissionMap[permission.ChartPermissionId] = permission.PermissionName
  454. if snapshotContract.ProductId == 2 {
  455. allPermissionMap[permission.ChartPermissionId] = permission.Remark
  456. }
  457. }
  458. snapshotPermissionIdList = append(snapshotPermissionIdList, permissionItem.CheckList...)
  459. }
  460. if len(snapshotPermissionIdList) > 0 {
  461. sort.Ints(snapshotPermissionIdList)
  462. }
  463. nowPermissionList, err := GetPermissionByContractService(snapshotContract.ProductId, nowServiceList)
  464. if err != nil {
  465. return
  466. }
  467. nowPermissionIdList := make([]int, 0)
  468. for _, permissionItem := range nowPermissionList {
  469. nowPermissionIdList = append(nowPermissionIdList, permissionItem.CheckList...)
  470. }
  471. if len(nowPermissionIdList) > 0 {
  472. sort.Ints(nowPermissionIdList)
  473. }
  474. //长度不等
  475. if len(snapshotPermissionIdList) != len(nowPermissionIdList) {
  476. goto FalseContrast
  477. }
  478. for i := 0; i < len(snapshotPermissionIdList); i++ {
  479. if snapshotPermissionIdList[i] != nowPermissionIdList[i] {
  480. //权限id不匹配
  481. goto FalseContrast
  482. }
  483. }
  484. return
  485. FalseContrast:
  486. snapshotContractServiceStrList := make([]string, 0)
  487. for _, id := range snapshotPermissionIdList {
  488. if permissionName, ok := allPermissionMap[id]; ok {
  489. snapshotContractServiceStrList = append(snapshotContractServiceStrList, permissionName)
  490. }
  491. }
  492. nowContractServiceStrList := make([]string, 0)
  493. for _, id := range nowPermissionIdList {
  494. if permissionName, ok := allPermissionMap[id]; ok {
  495. nowContractServiceStrList = append(nowContractServiceStrList, permissionName)
  496. }
  497. }
  498. snapshotContractServiceStr := `无`
  499. if len(snapshotContractServiceStrList) > 0 {
  500. snapshotContractServiceStr = strings.Join(snapshotContractServiceStrList, ",")
  501. }
  502. nowContractServiceStr := `无`
  503. if len(nowContractServiceStrList) > 0 {
  504. nowContractServiceStr = strings.Join(nowContractServiceStrList, ",")
  505. }
  506. updateStr = fmt.Sprint("原服务内容:", snapshotContractServiceStr, "</n>现服务内容:", nowContractServiceStr)
  507. return
  508. }
  509. // DeleteContract 删除合同
  510. func DeleteContract(contractId int, opUser *system.Admin) (err error) {
  511. //查询当前合同信息
  512. nowContract, err := contract.GetContractById(contractId)
  513. if err != nil {
  514. if err.Error() == utils.ErrNoRow() {
  515. err = errors.New(fmt.Sprint("根据合同编号:", contractId, " 找不到初始合同"))
  516. }
  517. return
  518. }
  519. if nowContract.SellerId != opUser.AdminId {
  520. err = errors.New("当前账号无操作权限")
  521. return
  522. }
  523. ignoreStatus := []string{"已审批", "待审批"}
  524. if strings.Contains(strings.Join(ignoreStatus, ","), nowContract.Status) {
  525. err = errors.New("合同状态异常,不允许删除,当前合同状态:" + nowContract.Status)
  526. return
  527. }
  528. //如果删除状态 >0,那么代表已经被删除了
  529. if nowContract.IsDelete > 0 {
  530. err = errors.New("该合同已删除")
  531. return
  532. }
  533. //假删除
  534. err = contract.DeleteContract(nowContract)
  535. if err != nil {
  536. return
  537. }
  538. //添加操作日志
  539. //remark := "编辑合同模板"
  540. //_ = contract.AddContractOperationRecord(nowContract.ContractId, nowContract.SellerId, 0, "edit", nowContract.SellerName, remark)
  541. return
  542. }
  543. // InvalidContract 作废合同
  544. func InvalidContract(contractId int, opUser *system.Admin) (err error) {
  545. //查询当前合同信息
  546. nowContract, err := contract.GetContractById(contractId)
  547. if err != nil {
  548. if err.Error() == utils.ErrNoRow() {
  549. err = errors.New(fmt.Sprint("根据合同编号:", contractId, " 找不到初始合同"))
  550. }
  551. return
  552. }
  553. if nowContract.SellerId != opUser.AdminId && opUser.RoleTypeCode != utils.ROLE_TYPE_CODE_COMPLIANCE {
  554. err = errors.New("当前账号无操作权限")
  555. return
  556. }
  557. if nowContract.Status != "已审批" {
  558. err = errors.New("合同状态异常,不允许作废,当前合同状态:" + nowContract.Status)
  559. return
  560. }
  561. //如果删除状态 >0,那么代表已经被删除了
  562. if nowContract.IsDelete > 0 {
  563. err = errors.New("该合同已删除")
  564. return
  565. }
  566. //合同作废
  567. err = contract.InvalidContract(nowContract)
  568. if err != nil {
  569. return
  570. }
  571. //添加操作日志
  572. remark := "作废合同模板"
  573. _ = contract.AddContractOperationRecord(nowContract.ContractId, opUser.AdminId, 0, "invalid", opUser.AdminName, remark)
  574. //修改业务合同的已支付金额
  575. if nowContract.ContractBusinessType == "代付合同" {
  576. go updateContractPaidPriceByPaymentOnBehalfContractId(nowContract.ContractId, -nowContract.Price)
  577. }
  578. return
  579. }
  580. // UploadFile 上传更新合同附件
  581. func UploadFile(contractId int, ext string, fileMulti multipart.File, opUser *system.Admin) (err error) {
  582. //获取合同信息
  583. contractInfo, err := contract.GetContractById(contractId)
  584. if err != nil {
  585. return
  586. }
  587. //合同状态判断
  588. if contractInfo.Status != "已审批" {
  589. err = errors.New("合同状态异常,不允许更新合同附件,当前合同状态:" + contractInfo.Status)
  590. return
  591. }
  592. if contractInfo.SellerId != opUser.AdminId {
  593. err = errors.New("合同异常,只允许本人更新合同附件")
  594. return
  595. }
  596. //保存的文件名
  597. fileName := contractInfo.CompanyName + "_" + contractInfo.ContractCode
  598. //非正式环境下,文件名上面还是加上随机数
  599. if utils.RunMode != "release" {
  600. fileName += "_" + utils.GetRandStringNoSpecialChar(10)
  601. }
  602. fileName += ext
  603. //上传到阿里云
  604. resourceUrl, err := services.UploadToOssAndFileName(fileMulti, fileName)
  605. if err != nil {
  606. err = errors.New("文件保存失败,Err:" + err.Error())
  607. return
  608. }
  609. contractInfo.FileUrl = resourceUrl
  610. contractInfo.ModifyTime = time.Now()
  611. err = contractInfo.Update([]string{"FileUrl", "ModifyTime"})
  612. if err != nil {
  613. return
  614. }
  615. //添加操作日志
  616. remark := "更新合同附件"
  617. _ = contract.AddContractOperationRecord(contractInfo.ContractId, opUser.AdminId, 0, "update_file", opUser.RealName, remark)
  618. return
  619. }
  620. // UploadCheckBackFile 上传签回合同附件
  621. func UploadCheckBackFile(contractId int, ext string, fileMulti multipart.File, opUser *system.Admin) (resourceUrl string, err error) {
  622. //获取合同信息
  623. contractInfo, err := contract.GetContractById(contractId)
  624. if err != nil {
  625. return
  626. }
  627. //合同状态判断
  628. if contractInfo.Status != "已审批" && contractInfo.Status != "已签回" {
  629. err = errors.New("合同状态异常,不允许上传签回合同附件,当前合同状态:" + contractInfo.Status)
  630. return
  631. }
  632. //保存的文件名
  633. fileName := contractInfo.CompanyName + "_" + contractInfo.ContractCode + "(签回)"
  634. //非正式环境下,文件名上面还是加上随机数
  635. if utils.RunMode != "release" {
  636. fileName += "_" + utils.GetRandStringNoSpecialChar(10)
  637. }
  638. fileName += ext
  639. //上传到阿里云
  640. resourceUrl, err = services.UploadToOssAndFileName(fileMulti, fileName)
  641. if err != nil {
  642. err = errors.New("文件保存失败,Err:" + err.Error())
  643. return
  644. }
  645. contractInfo.CheckBackFileUrl = resourceUrl
  646. contractInfo.Status = "已签回"
  647. contractInfo.ModifyTime = time.Now()
  648. contractInfo.CheckBackFileTime = time.Now()
  649. err = contractInfo.Update([]string{"CheckBackFileUrl", "Status", "ModifyTime", "CheckBackFileTime"})
  650. if err != nil {
  651. return
  652. }
  653. //同步更新客户那边提交审批的合同
  654. o := orm.NewOrm()
  655. sql := `update company_contract set img_url = ? where contract_code=? and source="系统合同" `
  656. _, err = o.Raw(sql, contractInfo.CheckBackFileUrl, contractInfo.ContractCode).Exec()
  657. //添加操作日志
  658. remark := "上传签回合同附件"
  659. _ = contract.AddContractOperationRecord(contractInfo.ContractId, opUser.AdminId, 0, "upload", opUser.RealName, remark)
  660. return
  661. }
  662. // UploadRescindFile 上传解约合同附件
  663. func UploadRescindFile(contractId int, ext string, fileMulti multipart.File, opUser *system.Admin) (err error) {
  664. //获取合同信息
  665. contractInfo, err := contract.GetContractById(contractId)
  666. if err != nil {
  667. return
  668. }
  669. //合同状态判断
  670. if contractInfo.Status != "已签回" {
  671. err = errors.New("合同状态异常,不允许上传解约合同附件,当前合同状态:" + contractInfo.Status)
  672. return
  673. }
  674. //保存的文件名
  675. fileName := contractInfo.CompanyName + "_" + contractInfo.ContractCode + "(解约)"
  676. //非正式环境下,文件名上面还是加上随机数
  677. if utils.RunMode != "release" {
  678. fileName += "_" + utils.GetRandStringNoSpecialChar(10)
  679. }
  680. fileName += ext
  681. //上传到阿里云
  682. resourceUrl, err := services.UploadToOssAndFileName(fileMulti, fileName)
  683. if err != nil {
  684. err = errors.New("文件保存失败,Err:" + err.Error())
  685. return
  686. }
  687. contractInfo.RescindFileUrl = resourceUrl
  688. contractInfo.Status = "已解约"
  689. contractInfo.ModifyTime = time.Now()
  690. contractInfo.RescindTime = time.Now()
  691. err = contractInfo.Update([]string{"RescindFileUrl", "Status", "ModifyTime", "RescindTime"})
  692. if err != nil {
  693. return
  694. }
  695. //添加操作日志
  696. remark := "上传解约合同附件"
  697. _ = contract.AddContractOperationRecord(contractInfo.ContractId, opUser.AdminId, 0, "rescind", opUser.RealName, remark)
  698. //修改业务合同的已支付金额
  699. if contractInfo.ContractBusinessType == "代付合同" {
  700. go updateContractPaidPriceByPaymentOnBehalfContractId(contractInfo.ContractId, -contractInfo.Price)
  701. }
  702. return
  703. }
  704. // 根据id获取合同详情(包含服务)
  705. func GetContractDetail(contractId int) (contractDetail *contract.ContractDetail, err error) {
  706. contractDetail, err = getContractDetail(contractId)
  707. if err != nil {
  708. if err.Error() == utils.ErrNoRow() {
  709. err = errors.New("找不到该合同")
  710. }
  711. return
  712. }
  713. relationContractDetailList := make([]*contract.ContractDetail, 0)
  714. switch contractDetail.ContractBusinessType {
  715. case "业务合同":
  716. tmpList, tmpErr := contract.GetContractRelationListByRelationContractId(contractDetail.ContractId)
  717. if tmpErr != nil {
  718. err = errors.New("查询业务关联合同异常:" + tmpErr.Error())
  719. return
  720. }
  721. //获取所有关联合同详情
  722. for _, relationContract := range tmpList {
  723. tmpContractDetail, tmpErr := getContractDetail(relationContract.PaymentOnBehalfContractId)
  724. if tmpErr != nil {
  725. err = errors.New("查询业务关联合同详情异常:" + tmpErr.Error())
  726. return
  727. }
  728. relationContractDetailList = append(relationContractDetailList, tmpContractDetail)
  729. }
  730. case "代付合同":
  731. tmpList, tmpErr := contract.GetContractRelationListByPaymentOnBehalfContractId(contractDetail.ContractId)
  732. if tmpErr != nil {
  733. err = errors.New("查询代付关联合同异常:" + tmpErr.Error())
  734. return
  735. }
  736. //获取所有关联合同详情
  737. for _, relationContract := range tmpList {
  738. tmpContractDetail, tmpErr := getContractDetail(relationContract.ContractId)
  739. if tmpErr != nil {
  740. err = errors.New("查询业务关联合同详情异常:" + tmpErr.Error())
  741. return
  742. }
  743. relationContractDetailList = append(relationContractDetailList, tmpContractDetail)
  744. }
  745. }
  746. contractDetail.RelationContractDetailList = relationContractDetailList
  747. return
  748. }
  749. // getContractDetail 根据id获取合同详情(包含服务)
  750. func getContractDetail(contractId int) (contractDetail *contract.ContractDetail, err error) {
  751. //获取合同基础信息详情
  752. contractDetail, err = contract.GetContractDetailById(contractId)
  753. if err != nil {
  754. if err.Error() == utils.ErrNoRow() {
  755. err = errors.New("找不到该合同")
  756. }
  757. return
  758. }
  759. //获取合同服务内容详情
  760. serviceList, err := getContractServiceAndDetailList(contractId)
  761. if err != nil {
  762. err = errors.New(fmt.Sprint("查找合同服务异常", err))
  763. return
  764. }
  765. contractDetail.Service = serviceList
  766. return
  767. }
  768. // getContractServiceAndDetailList 根据合同Id获取服务详情列表
  769. func getContractServiceAndDetailList(contractId int) (serviceList []*contract.ContractServiceAndDetail, err error) {
  770. serviceList, err = contract.GetContractServiceAndDetailList(contractId)
  771. if err != nil {
  772. err = errors.New(fmt.Sprint("查找合同服务异常", err))
  773. return
  774. }
  775. // 权益合同主客观合并
  776. //if mergeEquity && len(serviceList) > 0 && serviceList[0].ProductId == 2 {
  777. // mergeList, e := EquityMergeSubjectAndObject(serviceList)
  778. // if e != nil {
  779. // err = errors.New(fmt.Sprint("合并权益合同服务异常", err))
  780. // return
  781. // }
  782. // serviceList = mergeList
  783. //}
  784. newLen := len(serviceList)
  785. for i := 0; newLen > i; i++ {
  786. if serviceList[i].HasDetail == "是" {
  787. list, detailErr := contract.GetContractServiceDetailListByServiceId(serviceList[i].ContractServiceId)
  788. if detailErr != nil {
  789. err = errors.New(fmt.Sprint("查找合同服务详情异常", detailErr))
  790. return
  791. }
  792. serviceList[i].DetailList = list
  793. }
  794. }
  795. return
  796. }
  797. // GetContractDetailByAddContractReq 根据请求参数获取合同详情结构体数据
  798. func GetContractDetailByAddContractReq(req request.AddContractReq, sellerId, productId int, sellerName string) (contractDetail *contract.ContractDetail, err error) {
  799. originalPrice := req.OriginalPrice
  800. price := req.Price
  801. if originalPrice < 0 {
  802. err = errors.New("合同金额不能小于0")
  803. return
  804. }
  805. //如果优惠后金额小于等于0,那么就是等于优惠前的金额
  806. if price <= 0 {
  807. price = originalPrice
  808. }
  809. companyName := req.CompanyName
  810. if companyName == "" {
  811. err = errors.New("客户名称必填")
  812. return
  813. }
  814. creditCode := req.CreditCode
  815. if companyName == "" {
  816. err = errors.New("社会统一信用代码必填")
  817. return
  818. }
  819. contractCode, err := contract.GetCompanyContractCode(productId, req.ContractBusinessType)
  820. if err != nil {
  821. err = errors.New(fmt.Sprint("合同编号生成异常,Err:", err))
  822. return
  823. }
  824. //校验合同模板类型
  825. contractTemplate, err := contract.GetContractTemplateByTemplateId(req.TemplateId)
  826. if err != nil {
  827. return
  828. }
  829. if contractTemplate.ProductId != productId {
  830. err = errors.New("模板类型与当前账户类型不符")
  831. return
  832. }
  833. contractDetail = &contract.ContractDetail{
  834. ContractId: int(time.Now().Unix()),
  835. ContractCode: contractCode,
  836. SellerId: sellerId,
  837. SellerName: sellerName,
  838. ProductId: productId,
  839. ContractBusinessType: req.ContractBusinessType,
  840. ContractType: req.ContractType,
  841. Status: "待提交",
  842. OriginalPrice: originalPrice,
  843. Price: price,
  844. PayRemark: req.PayRemark, //付款方式说明,长度255位
  845. PayChannel: req.PayChannel, //付款渠道,长度255位
  846. CompanyName: companyName,
  847. CreditCode: creditCode,
  848. ProvinceId: req.ProvinceId,
  849. Province: req.Province,
  850. CityId: req.CityId,
  851. City: req.City,
  852. Address: req.Address,
  853. Fax: req.Fax,
  854. Phone: req.Phone,
  855. Postcode: req.Postcode,
  856. Remark: req.Remark,
  857. TemplateId: req.TemplateId,
  858. SourceId: req.SourceId, //来源合同id
  859. ModifyTime: time.Now(),
  860. CreateTime: time.Now(),
  861. }
  862. //合同日期
  863. if req.ContractBusinessType == "代付合同" {
  864. //关联合同
  865. relationContractDetailList := make([]*contract.ContractDetail, 0)
  866. tmpContractDetail, tmpErr := getContractDetail(req.RelationContractId)
  867. if tmpErr != nil {
  868. err = errors.New("查询业务关联合同详情异常:" + tmpErr.Error())
  869. return
  870. }
  871. relationContractDetailList = append(relationContractDetailList, tmpContractDetail)
  872. contractDetail.RelationContractDetailList = relationContractDetailList
  873. } else {
  874. tmpStartDate, tmpErr := time.Parse(utils.FormatDate, req.StartDate)
  875. if tmpErr != nil {
  876. err = errors.New(fmt.Sprint("合同开始日期转换失败:", tmpErr))
  877. return
  878. }
  879. contractDetail.StartDate = tmpStartDate
  880. tmpEndDate, tmpErr := time.Parse(utils.FormatDate, req.EndDate)
  881. if tmpErr != nil {
  882. err = errors.New(fmt.Sprint("合同结束日期转换失败:", tmpErr))
  883. return
  884. }
  885. contractDetail.EndDate = tmpEndDate
  886. contractServiceSlice, tmpErr := getContractServiceAndDetail(productId, req.Service, false)
  887. if tmpErr != nil {
  888. err = tmpErr
  889. return
  890. }
  891. contractDetail.Service = contractServiceSlice
  892. }
  893. return
  894. }
  895. // 根据请求数据获取套餐服务详情信息
  896. func getContractServiceAndDetail(productId int, reqService []request.AddContractServiceReq, base642Image bool) (contractServiceSlice []*contract.ContractServiceAndDetail, err error) {
  897. contractServiceSlice = make([]*contract.ContractServiceAndDetail, 0)
  898. if len(reqService) < 0 {
  899. err = errors.New("请至少选择一种套餐")
  900. return
  901. }
  902. for i := 0; i < len(reqService); i++ {
  903. item := reqService[i]
  904. detail := item.Detail
  905. contractServiceDetailSlice := make([]*contract.ContractServiceDetail, 0)
  906. if len(detail) > 0 {
  907. for j := 0; j < len(detail); j++ {
  908. detailItem := detail[j]
  909. cellMap := make(map[string]string)
  910. for k := 0; k < len(detailItem); k++ {
  911. key := fmt.Sprint("cell_", k+1)
  912. tmpVal, jsonErr := json.Marshal(detailItem[k])
  913. if jsonErr != nil {
  914. err = errors.New(fmt.Sprint("json转换失败:", jsonErr))
  915. return
  916. }
  917. cellMap[key] = string(tmpVal)
  918. }
  919. contractServiceDetail := &contract.ContractServiceDetail{
  920. Col1: func(cellMap map[string]string) string {
  921. tmpVal, ok := cellMap["cell_1"]
  922. if ok {
  923. return tmpVal
  924. } else {
  925. return ""
  926. }
  927. }(cellMap),
  928. Col2: func(cellMap map[string]string) string {
  929. tmpVal, ok := cellMap["cell_2"]
  930. if ok {
  931. return tmpVal
  932. } else {
  933. return ""
  934. }
  935. }(cellMap),
  936. Col3: func(cellMap map[string]string) string {
  937. tmpVal, ok := cellMap["cell_3"]
  938. if ok {
  939. return tmpVal
  940. } else {
  941. return ""
  942. }
  943. }(cellMap),
  944. Col4: func(cellMap map[string]string) string {
  945. tmpVal, ok := cellMap["cell_4"]
  946. if ok {
  947. return tmpVal
  948. } else {
  949. return ""
  950. }
  951. }(cellMap),
  952. Col5: func(cellMap map[string]string) string {
  953. tmpVal, ok := cellMap["cell_5"]
  954. if ok {
  955. return tmpVal
  956. } else {
  957. return ""
  958. }
  959. }(cellMap),
  960. Col6: func(cellMap map[string]string) string {
  961. tmpVal, ok := cellMap["cell_6"]
  962. if ok {
  963. return tmpVal
  964. } else {
  965. return ""
  966. }
  967. }(cellMap),
  968. Col7: func(cellMap map[string]string) string {
  969. tmpVal, ok := cellMap["cell_7"]
  970. if ok {
  971. return tmpVal
  972. } else {
  973. return ""
  974. }
  975. }(cellMap),
  976. ServiceTemplateId: item.ServiceTemplateId,
  977. CreateTime: time.Now(),
  978. }
  979. contractServiceDetailSlice = append(contractServiceDetailSlice, contractServiceDetail)
  980. }
  981. }
  982. hasDetail := "否"
  983. if len(contractServiceDetailSlice) > 0 {
  984. hasDetail = "是"
  985. }
  986. //报价单图片地址
  987. valueStr := item.Value
  988. if base642Image {
  989. b, _ := regexp.MatchString(`^data:\s*image\/(\w+);base64,`, valueStr)
  990. if b {
  991. imageUrl, uploadErr := UploadImageBase64(valueStr)
  992. if uploadErr != nil {
  993. err = errors.New(fmt.Sprint("base64图片上传失败:", uploadErr))
  994. return
  995. }
  996. valueStr = imageUrl
  997. }
  998. }
  999. //寻找该系统模板
  1000. systemContractServiceTem, tmpErr := contract.GetContractServiceTemplateById(item.ServiceTemplateId)
  1001. if tmpErr != nil {
  1002. err = errors.New("找不到该模板")
  1003. return
  1004. }
  1005. tmpContractService := &contract.ContractServiceAndDetail{
  1006. ServiceTemplateId: item.ServiceTemplateId,
  1007. Title: item.Title,
  1008. Value: valueStr,
  1009. ProductId: productId,
  1010. //CreateTime: time.Now(),
  1011. HasDetail: hasDetail,
  1012. TableValue: systemContractServiceTem.TableValue,
  1013. DetailList: contractServiceDetailSlice,
  1014. ChartPermissionId: systemContractServiceTem.ChartPermissionId,
  1015. }
  1016. contractServiceSlice = append(contractServiceSlice, tmpContractService)
  1017. }
  1018. return
  1019. }
  1020. // 获取品种列数据(因为前端可以随意插入列数据,所以需要根据列名来搜索对应的品种列)
  1021. func GetProductCelData(detail contract.ContractServiceDetail, tableCel *request.AddContractServiceDetailReq) (err error) {
  1022. t := reflect.TypeOf(detail)
  1023. v := reflect.ValueOf(detail)
  1024. for k := 0; k < t.NumField(); k++ {
  1025. //获取结构体的参数名
  1026. tmpName := t.Field(k).Name
  1027. if strings.Contains(tmpName, "Col") {
  1028. //获取结构体该参数名的值
  1029. tmpValue := v.Field(k).String()
  1030. //如果值不为空的话,那么做下json转换
  1031. if tmpValue != "" {
  1032. tmpErr := json.Unmarshal([]byte(tmpValue), tableCel)
  1033. if tmpErr != nil {
  1034. err = tmpErr
  1035. continue
  1036. }
  1037. if tableCel.HeadName == "品种" {
  1038. err = nil
  1039. return
  1040. }
  1041. }
  1042. }
  1043. }
  1044. return
  1045. }
  1046. // 将base64的图片上传至oss
  1047. func UploadImageBase64(base64Str string) (resourceUrl string, err error) {
  1048. ext := ".png"
  1049. uploadDir := "./static"
  1050. randStr := utils.GetRandStringNoSpecialChar(28)
  1051. fileName := randStr + ext
  1052. fpath := uploadDir + "/" + fileName
  1053. b, _ := regexp.MatchString(`^data:\s*image\/(\w+);base64,`, base64Str)
  1054. if !b {
  1055. err = errors.New("图片格式不正确")
  1056. return
  1057. }
  1058. re, _ := regexp.Compile(`^data:\s*image\/(\w+);base64,`)
  1059. base64Str = re.ReplaceAllString(base64Str, "")
  1060. base64Str = strings.Replace(base64Str, " ", "", -1)
  1061. base64Str = strings.Replace(base64Str, " ", "", -1)
  1062. //imgByte, err := base64.StdEncoding.DecodeString(base64Str)
  1063. //err=ioutil.WriteFile(fpath,imgByte,os.ModeAppend)
  1064. //if err!=nil {
  1065. // br.Msg = "图片保存失败"
  1066. // br.ErrMsg = "图片保存失败,Err:"+err.Error()
  1067. // return
  1068. //}
  1069. err = utils.SaveBase64ToFile(base64Str, fpath)
  1070. if err != nil {
  1071. return
  1072. }
  1073. fmt.Println("end")
  1074. defer os.Remove(fpath)
  1075. savePath := utils.Upload_Audio_Dir + time.Now().Format("200601/20060102/")
  1076. savePath += fileName
  1077. //上传到阿里云
  1078. err = services.UploadVideoAliyun(fileName, fpath, savePath)
  1079. if err != nil {
  1080. return
  1081. }
  1082. utils.FileLog.Info("%s:", time.Now().Format(utils.FormatDateTime))
  1083. utils.FileLog.Info("end update oss ")
  1084. resourceUrl = utils.Imghost + savePath
  1085. item := new(models.Resource)
  1086. item.ResourceUrl = resourceUrl
  1087. item.ResourceType = 1
  1088. item.CreateTime = time.Now()
  1089. _, err = models.AddResource(item)
  1090. if err != nil {
  1091. return
  1092. }
  1093. return
  1094. }
  1095. // GetPermissionByContractService 通过合同服务,获取权限id列表
  1096. func GetPermissionByContractService(productId int, serviceList []*contract.ContractServiceAndDetail) (permissionList []*company.PermissionLookList, err error) {
  1097. //获取已经勾选的的权限
  1098. checkPermissionIdMap, err := GetServicePermissionMap(serviceList)
  1099. if err != nil {
  1100. return
  1101. }
  1102. permissionList, err = GetPermissionByPermissionIdMap(productId, checkPermissionIdMap)
  1103. return
  1104. }
  1105. // GetPermissionByPermissionIdMap 通过权限id的map,获取权限列表
  1106. func GetPermissionByPermissionIdMap(productId int, checkPermissionIdMap map[int]int) (permissionList []*company.PermissionLookList, err error) {
  1107. //子权限切片集合
  1108. allPermissions, err := company.GetPermissionLookItemsByProductId(productId)
  1109. if err != nil {
  1110. err = fmt.Errorf("获取权限失败,Err:%s", err.Error())
  1111. return
  1112. }
  1113. permissionMap := make(map[int][]*company.PermissionLookItem, 0)
  1114. for _, v := range allPermissions {
  1115. if v.ParentId > 0 {
  1116. permissionMap[v.ParentId] = append(permissionMap[v.ParentId], v)
  1117. }
  1118. }
  1119. //遍历获取
  1120. for _, v := range allPermissions {
  1121. if v.ParentId == 0 {
  1122. checkList := make([]int, 0)
  1123. plist := new(company.PermissionLookList)
  1124. plist.Items = make([]*company.PermissionLookItem, 0)
  1125. items, ok1 := permissionMap[v.ChartPermissionId]
  1126. if ok1 {
  1127. for _, n := range items {
  1128. if _, ok := checkPermissionIdMap[n.ChartPermissionId]; ok {
  1129. checkList = append(checkList, n.ChartPermissionId)
  1130. } else if _, ok2 := checkPermissionIdMap[n.ChartPermissionId+utils.PERMISSION_ID_UPGRADE]; ok2 {
  1131. checkList = append(checkList, n.ChartPermissionId)
  1132. n.IsUpgrade = 1
  1133. }
  1134. }
  1135. plist.Items = items
  1136. }
  1137. plist.ClassifyName = v.PermissionName
  1138. plist.CheckList = checkList
  1139. permissionList = append(permissionList, plist)
  1140. }
  1141. }
  1142. return
  1143. }
  1144. // GetServicePermissionMap 获取合同服务中的权限id map
  1145. func GetServicePermissionMap(serviceList []*contract.ContractServiceAndDetail) (checkPermissionIdMap map[int]int, err error) {
  1146. checkPermissionIdMap = make(map[int]int)
  1147. //获取已经勾选的的权限
  1148. for _, contractService := range serviceList {
  1149. //如果是权益,那么研选必要(2022-07-06 10:29:11移除)
  1150. //if contractService.ProductId == 2 {
  1151. // chartPermissionId := 31 //研选服务
  1152. // checkPermissionIdMap[chartPermissionId] = chartPermissionId
  1153. //}
  1154. //看看系统中有没有映射对应的权限,如果有的话,那么直接返回,没有那么可能是特殊服务,需要去遍历
  1155. if contractService.ChartPermissionId > 0 {
  1156. checkPermissionIdMap[contractService.ChartPermissionId] = contractService.ChartPermissionId
  1157. continue
  1158. }
  1159. switch contractService.ServiceTemplateId {
  1160. case 1: //ficc 大套餐
  1161. allFiccPermissions, e := company.GetPermissionLookItemsByProductId(utils.COMPANY_PRODUCT_FICC_ID)
  1162. if e != nil {
  1163. err = fmt.Errorf("获取权限失败 Err:%v", e)
  1164. return
  1165. }
  1166. permissionMap := make(map[int][]*company.PermissionLookItem, 0)
  1167. for _, v := range allFiccPermissions {
  1168. if v.ParentId > 0 {
  1169. permissionMap[v.ParentId] = append(permissionMap[v.ParentId], v)
  1170. }
  1171. }
  1172. for _, v := range allFiccPermissions {
  1173. if v.ParentId == 0 {
  1174. //合同这边市场策略不需要体现出来,所以调整返回
  1175. if v.PermissionName == "市场策略" {
  1176. continue
  1177. }
  1178. items, ok := permissionMap[v.ChartPermissionId]
  1179. if ok {
  1180. for _, n := range items {
  1181. checkPermissionIdMap[n.ChartPermissionId] = n.ChartPermissionId
  1182. }
  1183. }
  1184. }
  1185. }
  1186. case 2: //ficc小套餐
  1187. permissionValues := []string{
  1188. "FICC周报", "商品双周报+线上电话会讨论会<br/>(由弘则的研究员主持线上讨论)", "数据点评",
  1189. }
  1190. for _, detail := range contractService.DetailList {
  1191. var tableCel request.AddContractServiceDetailReq
  1192. tmpErr := json.Unmarshal([]byte(detail.Col1), &tableCel)
  1193. if tmpErr != nil {
  1194. err = tmpErr
  1195. return
  1196. }
  1197. if strings.Contains(strings.Join(permissionValues, ","), tableCel.Value) {
  1198. //获取品种列数据
  1199. var tableCel2 request.AddContractServiceDetailReq
  1200. tmpErr := GetProductCelData(*detail, &tableCel2)
  1201. if tmpErr != nil {
  1202. err = tmpErr
  1203. return
  1204. }
  1205. for _, serviceId := range tableCel2.ValueId {
  1206. checkPermissionIdMap[serviceId] = serviceId
  1207. }
  1208. }
  1209. }
  1210. case 4, 5, 6: //权益大套餐
  1211. permissionFiccClassifyArr := []string{"权益"}
  1212. permissionFilterrr := []string{"固收", "路演服务", "研选扣点包", "调研", "专家", "研选订阅"} //不在大套餐中展示的权益权限
  1213. for _, v := range permissionFiccClassifyArr {
  1214. items, tmpErr := company.GetPermissionLookItems(2, v)
  1215. if tmpErr != nil {
  1216. err = tmpErr
  1217. return
  1218. }
  1219. for _, n := range items {
  1220. //如果是专家行业,那么 结束当前循环,进入下一循环(产品需求:专家行业不在里面)
  1221. //if n.ChartPermissionId == 29 || n.ChartPermissionId == 31 {
  1222. // continue
  1223. //}
  1224. if utils.InArrayByStr(permissionFilterrr, n.PermissionName) {
  1225. continue
  1226. }
  1227. checkPermissionIdMap[n.ChartPermissionId] = n.ChartPermissionId
  1228. }
  1229. }
  1230. }
  1231. }
  1232. return
  1233. }
  1234. // GetServicePackageType 获取合同服务中的 大小套餐类型
  1235. func GetServicePackageType(serviceList []*contract.ContractServiceAndDetail) (packageType int, err error) {
  1236. //获取已经勾选的的权限
  1237. for _, contractService := range serviceList {
  1238. switch contractService.ServiceTemplateId {
  1239. case 1: //ficc 大套餐
  1240. packageType = 1
  1241. case 2: //ficc小套餐
  1242. packageType = 2
  1243. case 4, 5, 6: //权益大套餐
  1244. //packageType = 1
  1245. }
  1246. }
  1247. return
  1248. }
  1249. // GetRaiServicePackageType 获取合同服务中的 权益的大小套餐类型
  1250. func GetRaiServicePackageType(serviceList []*contract.ContractServiceAndDetail) (raiPackageType int) {
  1251. for _, contractService := range serviceList {
  1252. switch contractService.ServiceTemplateId {
  1253. case 5: // 45w大套餐
  1254. raiPackageType = 2
  1255. case 6: // 70w大套餐
  1256. raiPackageType = 1
  1257. }
  1258. if raiPackageType > 0 {
  1259. break
  1260. }
  1261. }
  1262. return
  1263. }
  1264. // CheckContractPrice 校验代付合同金额是否 大于 业务合同金额(可能存在多份合同,需要遍历,如果大于的话,校验不通过,需要驳回)
  1265. func CheckContractPrice(contractInfo *contract.Contract, price float64) (ok bool, err error) {
  1266. list, err := contract.GetContractRelationListByContractId(contractInfo.ContractId)
  1267. if err != nil {
  1268. return
  1269. }
  1270. payedPrice := 0.0
  1271. for _, v := range list {
  1272. payedPrice += v.Price
  1273. }
  1274. if (contractInfo.Price - payedPrice) < price {
  1275. return
  1276. }
  1277. ok = true
  1278. return
  1279. }
  1280. // UploadCheckBackFileFromSeal 更新用印上传签回合同附件
  1281. func UploadCheckBackFileFromSeal(contractId int, fileUrl string, opUser *system.Admin) (err error) {
  1282. // 获取合同信息
  1283. contractInfo, err := contract.GetContractById(contractId)
  1284. if err != nil {
  1285. return
  1286. }
  1287. // 合同状态判断
  1288. if contractInfo.Status != "已审批" && contractInfo.Status != "已签回" {
  1289. err = errors.New("合同状态异常,不允许上传签回合同附件,当前合同状态:" + contractInfo.Status)
  1290. return
  1291. }
  1292. contractInfo.CheckBackFileUrl = fileUrl
  1293. contractInfo.Status = "已签回"
  1294. contractInfo.ModifyTime = time.Now()
  1295. contractInfo.CheckBackFileTime = time.Now()
  1296. err = contractInfo.Update([]string{"CheckBackFileUrl", "Status", "ModifyTime", "CheckBackFileTime"})
  1297. if err != nil {
  1298. return
  1299. }
  1300. // 同步更新客户那边提交审批的合同
  1301. o := orm.NewOrm()
  1302. sql := `update company_contract set img_url = ? where contract_code=? and source = "系统合同" `
  1303. _, err = o.Raw(sql, contractInfo.CheckBackFileUrl, contractInfo.ContractCode).Exec()
  1304. // 添加操作日志
  1305. remark := "上传签回合同附件"
  1306. _ = contract.AddContractOperationRecord(contractInfo.ContractId, opUser.AdminId, 0, "upload", opUser.RealName, remark)
  1307. return
  1308. }
  1309. //func init() {
  1310. // fmt.Println("contract init start")
  1311. // go FixEquityContractService()
  1312. // fmt.Println("contract init end")
  1313. //}
  1314. // FixEquityContractService 修复权益合同服务内容-CRM8.8
  1315. func FixEquityContractService() (err error) {
  1316. defer func() {
  1317. if err != nil {
  1318. fmt.Println("FixEquityContractService Err: " + err.Error())
  1319. }
  1320. }()
  1321. // 获取所有权益的合同(不考虑状态)
  1322. productId := 2
  1323. contractList, e := contract.GetContractListByProductId(productId)
  1324. if e != nil {
  1325. err = errors.New("获取权益合同列表失败")
  1326. return
  1327. }
  1328. contractLen := len(contractList)
  1329. if contractLen == 0 {
  1330. fmt.Println("无合同需要修复")
  1331. return
  1332. }
  1333. fmt.Println("待修复权益合同数", contractLen)
  1334. //return
  1335. // 合同IDs
  1336. contractIdArr := make([]string, 0)
  1337. contractIdServices := make(map[int][]*contract.ContractService, 0)
  1338. for i := 0; i < contractLen; i++ {
  1339. contractIdArr = append(contractIdArr, strconv.Itoa(contractList[i].ContractId))
  1340. newServices := make([]*contract.ContractService, 0)
  1341. contractIdServices[contractList[i].ContractId] = newServices
  1342. }
  1343. contractIds := strings.Join(contractIdArr, ",")
  1344. // 合同服务内容
  1345. serviceList, e := contract.GetContractServiceListByIds(contractIds)
  1346. if e != nil {
  1347. err = errors.New("获取权益合同服务内容列表失败")
  1348. return
  1349. }
  1350. servicesLen := len(serviceList)
  1351. if servicesLen == 0 {
  1352. fmt.Println("无合同服务需要修复")
  1353. return
  1354. }
  1355. for i := 0; i < servicesLen; i++ {
  1356. contractIdServices[serviceList[i].ContractId] = append(contractIdServices[serviceList[i].ContractId], serviceList[i])
  1357. }
  1358. // 服务套餐模板
  1359. templateList, e := contract.GetAllContractServiceTemplateList()
  1360. if e != nil {
  1361. err = errors.New("获取服务套餐模板列表失败")
  1362. return
  1363. }
  1364. // 主客观服务套餐
  1365. titleArr := []string{"医药", "消费", "科技", "智造"}
  1366. subTempMap := make(map[string]*contract.ContractServiceTemplate, 0)
  1367. objTempMap := make(map[string]*contract.ContractServiceTemplate, 0)
  1368. templateIdMap := make(map[int]*contract.ContractServiceTemplate, 0)
  1369. templateLen := len(templateList)
  1370. for i := 0; i < templateLen; i++ {
  1371. templateIdMap[templateList[i].ServiceTemplateId] = templateList[i]
  1372. }
  1373. for i := 0; i < templateLen; i++ {
  1374. if templateList[i].Title == "主观" {
  1375. parentTemp := templateIdMap[templateList[i].Pid]
  1376. subTempMap[parentTemp.Title] = templateList[i]
  1377. continue
  1378. }
  1379. if templateList[i].Title == "客观" {
  1380. parentTemp := templateIdMap[templateList[i].Pid]
  1381. objTempMap[parentTemp.Title] = templateList[i]
  1382. continue
  1383. }
  1384. }
  1385. // 遍历合同
  1386. for i := 0; i < contractLen; i++ {
  1387. contractId := contractList[i].ContractId
  1388. fmt.Printf("正在修复第%d个, 合同ID: %d\n", i+1, contractId)
  1389. // 合同服务内容
  1390. contractServices := contractIdServices[contractId]
  1391. insertArr := make([]*contract.ContractService, 0)
  1392. serviceLen := len(contractServices)
  1393. // 是否含有医药、消费、科技、智造
  1394. for _, v := range titleArr {
  1395. for ii := 0; ii < serviceLen; ii++ {
  1396. createTime := contractServices[ii].CreateTime
  1397. // 含有四种套餐之一
  1398. if contractServices[ii].Title == v {
  1399. template := templateIdMap[contractServices[ii].ServiceTemplateId]
  1400. pid := template.ServiceTemplateId
  1401. insertSubject := true
  1402. insertObject := true
  1403. // 去重, 校验是否已存在主客观
  1404. for iii := 0; iii < serviceLen; iii++ {
  1405. t := templateIdMap[contractServices[iii].ServiceTemplateId]
  1406. if t.Pid == pid && t.Title == "主观" {
  1407. insertSubject = false
  1408. continue
  1409. }
  1410. if t.Pid == pid && t.Title == "客观" {
  1411. insertObject = false
  1412. continue
  1413. }
  1414. }
  1415. if insertSubject {
  1416. subTemp := subTempMap[v]
  1417. title := v + "(" + subTemp.Title + ")"
  1418. insertArr = append(insertArr, &contract.ContractService{
  1419. ContractId: contractId,
  1420. ProductId: productId,
  1421. ServiceTemplateId: subTemp.ServiceTemplateId,
  1422. Title: title,
  1423. Value: subTemp.Value,
  1424. TableValue: subTemp.TableValue,
  1425. HasDetail: "否",
  1426. ChartPermissionId: subTemp.ChartPermissionId,
  1427. CreateTime: createTime,
  1428. })
  1429. }
  1430. if insertObject {
  1431. objTemp := objTempMap[v]
  1432. title := v + "(" + objTemp.Title + ")"
  1433. insertArr = append(insertArr, &contract.ContractService{
  1434. ContractId: contractId,
  1435. ProductId: productId,
  1436. ServiceTemplateId: objTemp.ServiceTemplateId,
  1437. Title: title,
  1438. Value: objTemp.Value,
  1439. TableValue: objTemp.TableValue,
  1440. HasDetail: "否",
  1441. ChartPermissionId: objTemp.ChartPermissionId,
  1442. CreateTime: createTime,
  1443. })
  1444. }
  1445. break
  1446. }
  1447. }
  1448. }
  1449. // 新增主客观
  1450. if len(insertArr) > 0 {
  1451. if e := contract.MultiCreateContractService(insertArr); e != nil {
  1452. fmt.Printf("第%d个修复失败, 合同ID: %d, Err: %s\n", i+1, contractId, e.Error())
  1453. return
  1454. }
  1455. fmt.Printf("第%d个修复成功, 合同ID: %d\n", i+1, contractId)
  1456. } else {
  1457. fmt.Printf("第%d个已修复过, 忽略合同ID: %d\n", i+1, contractId)
  1458. }
  1459. }
  1460. return
  1461. }
  1462. // CRM8.8-权益合同主客观套餐合并
  1463. func EquityMergeSubjectAndObject(serviceList []*contract.ContractServiceAndDetail) (mergeList []*contract.ContractServiceAndDetail) {
  1464. serviceLen := len(serviceList)
  1465. if serviceLen == 0 {
  1466. return serviceList
  1467. }
  1468. mergeArr := []string{"医药", "消费", "科技", "智造"}
  1469. // 获取模板列表
  1470. templateList, e := contract.GetAllContractServiceTemplateList()
  1471. if e != nil {
  1472. return serviceList
  1473. }
  1474. parentTempMap := make(map[string]int, 0)
  1475. templateMap := make(map[int]*contract.ContractServiceTemplate, 0)
  1476. for _, v := range templateList {
  1477. if utils.InArrayByStr(mergeArr, v.Title) {
  1478. parentTempMap[v.Title] = v.ServiceTemplateId
  1479. }
  1480. templateMap[v.ServiceTemplateId] = v
  1481. }
  1482. // 计算每个行业的子套餐数, 并判断所有套餐所属行业
  1483. countIndustryMap := make(map[string]int, 0)
  1484. serviceIndustryMap := make(map[int]string, 0)
  1485. industryServiceMap := make(map[string]*contract.ContractServiceAndDetail, 0)
  1486. childrenServiceMap := make(map[string]*contract.ContractServiceAndDetail, 0)
  1487. for i := 0; i < serviceLen; i++ {
  1488. temp := templateMap[serviceList[i].ServiceTemplateId]
  1489. if temp == nil {
  1490. continue
  1491. }
  1492. // 行业套餐
  1493. if utils.InArrayByStr(mergeArr, temp.Title) {
  1494. serviceIndustryMap[i] = temp.Title
  1495. industryServiceMap[temp.Title] = serviceList[i]
  1496. continue
  1497. }
  1498. // 主/客观
  1499. parentTemp := templateMap[temp.Pid]
  1500. if parentTemp != nil && utils.InArrayByStr(mergeArr, parentTemp.Title) {
  1501. countIndustryMap[parentTemp.Title] += 1
  1502. serviceIndustryMap[i] = parentTemp.Title
  1503. childrenServiceMap[parentTemp.Title] = serviceList[i]
  1504. }
  1505. }
  1506. mergeList = make([]*contract.ContractServiceAndDetail, 0)
  1507. // 遍历每一个套餐, 取出所属的行业, 不属于合并的行业则直接加入数组
  1508. // 属于合并的行业, 则校验行业子套餐数, 若子套餐数为1, 则取取主/客观套餐, 否则取行业套餐
  1509. mergeIndustryMap := make(map[string]int, 0)
  1510. for i := 0; i < serviceLen; i++ {
  1511. industryName := serviceIndustryMap[i]
  1512. // 不需要合并的行业
  1513. if industryName == "" {
  1514. mergeList = append(mergeList, serviceList[i])
  1515. continue
  1516. }
  1517. // 未合并则进行合并
  1518. if mergeIndustryMap[industryName] > 0 {
  1519. continue
  1520. }
  1521. count := countIndustryMap[industryName]
  1522. if count == 1 {
  1523. // 取主/客观套餐
  1524. mergeList = append(mergeList, childrenServiceMap[industryName])
  1525. } else {
  1526. // 0或者2都取行业套餐
  1527. mergeList = append(mergeList, industryServiceMap[industryName])
  1528. }
  1529. mergeIndustryMap[industryName] += 1
  1530. }
  1531. return
  1532. }
  1533. // CRM8.8-权益合同主客观权限的合并
  1534. func EquityMergeSubjectAndObjectPermission(list []*company.CompanyContractPermissionName) (newList []*company.CompanyContractPermissionName) {
  1535. if len(list) == 0 {
  1536. return list
  1537. }
  1538. // contractPermissionMap示例:
  1539. // map[
  1540. // 665:map[
  1541. // 专家:[0xc0002e24d0]
  1542. // 买方研选:[0xc0002e2630]
  1543. // 医药:[0xc0002e2370 0xc0002e28f0]
  1544. // 智造:[0xc0002e2160 0xc0002e26e0]
  1545. // 消费:[0xc0002e22c0 0xc0002e2840]
  1546. // 科技:[0xc0002e2210 0xc0002e2790]
  1547. // 策略:[0xc0002e2420]
  1548. // 路演服务:[0xc0002e2580]
  1549. // ]
  1550. // 666:map[
  1551. // 智造:[0xc0002e29a0 0xc0002e2b00]
  1552. // 科技:[0xc0002e2a50 0xc0002e2bb0]
  1553. // ]
  1554. // ]
  1555. contractPermissionMap := make(map[int]map[string][]*company.CompanyContractPermissionName)
  1556. for _, v := range list {
  1557. permissionMap, ok := contractPermissionMap[v.CompanyContractId]
  1558. if ok {
  1559. permissionItemMap, ok2 := permissionMap[v.ChartPermissionName]
  1560. if !ok2 {
  1561. permissionItemMap = make([]*company.CompanyContractPermissionName, 0)
  1562. }
  1563. permissionItemMap = append(permissionItemMap, v)
  1564. permissionMap[v.ChartPermissionName] = permissionItemMap
  1565. } else {
  1566. permissionMap = make(map[string][]*company.CompanyContractPermissionName)
  1567. permissionMap[v.ChartPermissionName] = append(permissionMap[v.ChartPermissionName], v)
  1568. }
  1569. contractPermissionMap[v.CompanyContractId] = permissionMap
  1570. }
  1571. newList = make([]*company.CompanyContractPermissionName, 0)
  1572. for _, v := range contractPermissionMap {
  1573. for _, p := range v {
  1574. if len(p) == 1 {
  1575. p[0].ChartPermissionName = p[0].PermissionRemark
  1576. }
  1577. newList = append(newList, p[0])
  1578. }
  1579. }
  1580. return
  1581. }
  1582. // HandleEquityPermissionLookList 权益-PermissionLookList主客观合并
  1583. func HandleEquityPermissionLookList(permissionLookList []*company.PermissionLookList) []*company.PermissionLookList {
  1584. if len(permissionLookList) == 0 {
  1585. return permissionLookList
  1586. }
  1587. checkList := permissionLookList[0].CheckList
  1588. permissionList := permissionLookList[0].Items
  1589. newPermissionList := HandleEquityPermissionLookItem(checkList, permissionList)
  1590. permissionLookList[0].Items = newPermissionList
  1591. return permissionLookList
  1592. }
  1593. // HandleEquityContractPermissionList 权益-ContractPermissionList主客观合并
  1594. func HandleEquityContractPermissionList(contractPermissionList []*company.ContractPermissionList) []*company.ContractPermissionList {
  1595. if len(contractPermissionList) == 0 {
  1596. return contractPermissionList
  1597. }
  1598. checkList := contractPermissionList[0].CheckList
  1599. permissionList := contractPermissionList[0].Items
  1600. newPermissionList := HandleEquityPermissionLookItem(checkList, permissionList)
  1601. contractPermissionList[0].Items = newPermissionList
  1602. return contractPermissionList
  1603. }
  1604. // HandleEquityPermissionLookItem 权益-权限展示的主客观合并处理
  1605. func HandleEquityPermissionLookItem(checkList []int, permissionList []*company.PermissionLookItem) (newPermissionList []*company.PermissionLookItem) {
  1606. permissionLen := len(permissionList)
  1607. if len(checkList) <= 0 || permissionLen <= 0 {
  1608. return permissionList
  1609. }
  1610. // 若某个行业的主客观权限均被满足,则只留其中一个权限
  1611. // 1.取出每个行业对应的其中一个权限
  1612. industryName := []string{"医药", "消费", "科技", "智造"}
  1613. namePermissionMap := make(map[string]*company.PermissionLookItem)
  1614. for i := 0; i < permissionLen; i++ {
  1615. pName := permissionList[i].PermissionName
  1616. if utils.InArrayByStr(industryName, pName) && namePermissionMap[pName] != nil {
  1617. namePermissionMap[pName] = permissionList[i]
  1618. }
  1619. }
  1620. // 2.计算哪些行业主客观权限都有
  1621. countIndustryMap := make(map[string]int, 0)
  1622. for i := 0; i < permissionLen; i++ {
  1623. p := permissionList[i]
  1624. if utils.InArrayByStr(industryName, p.PermissionName) && utils.InArrayByInt(checkList, p.ChartPermissionId) {
  1625. countIndustryMap[p.PermissionName] += 1
  1626. }
  1627. }
  1628. // 3.重新组成一个权限列表
  1629. mergeIndustryMap := make(map[string]int, 0)
  1630. newPermissionList = make([]*company.PermissionLookItem, 0)
  1631. for i := 0; i < permissionLen; i++ {
  1632. item := permissionList[i]
  1633. if utils.InArrayByStr(industryName, item.PermissionName) {
  1634. // 只有主客观之一, permissionName取remark
  1635. if countIndustryMap[item.PermissionName] == 1 {
  1636. // CRM13.2 标准合同新增升级套餐
  1637. if item.IsUpgrade == 1 {
  1638. item.PermissionName += "(升级)"
  1639. newPermissionList = append(newPermissionList, item)
  1640. } else {
  1641. item.PermissionName = item.Remark
  1642. newPermissionList = append(newPermissionList, item)
  1643. }
  1644. continue
  1645. }
  1646. // 主客观都有
  1647. if countIndustryMap[item.PermissionName] > 1 && mergeIndustryMap[item.PermissionName] == 0 {
  1648. mergeIndustryMap[item.PermissionName] += 1
  1649. // CRM13.2 标准合同新增升级套餐
  1650. if item.IsUpgrade == 1 {
  1651. item.PermissionName += "(升级)"
  1652. }
  1653. newPermissionList = append(newPermissionList, item)
  1654. }
  1655. } else {
  1656. newPermissionList = append(newPermissionList, item)
  1657. }
  1658. }
  1659. return
  1660. }
  1661. // handleRaiContractModifyContentByServices 权益合同-服务内容变更内容
  1662. func handleRaiContractModifyContentByServices(originService []*contract.ContractServiceAndDetail, newService []*contract.ContractServiceAndDetail) (tips string) {
  1663. if originService == nil || newService == nil {
  1664. return
  1665. }
  1666. oldArr := make([]string, 0)
  1667. newArr := make([]string, 0)
  1668. oldStr := "无"
  1669. newStr := "无"
  1670. o := EquityMergeSubjectAndObject(originService)
  1671. n := EquityMergeSubjectAndObject(newService)
  1672. for i := range o {
  1673. oldArr = append(oldArr, o[i].Title)
  1674. }
  1675. if len(oldArr) > 0 {
  1676. oldStr = strings.Join(oldArr, ",")
  1677. }
  1678. for i := range n {
  1679. newArr = append(newArr, n[i].Title)
  1680. }
  1681. if len(newArr) > 0 {
  1682. newStr = strings.Join(newArr, ",")
  1683. }
  1684. tips = fmt.Sprint("原服务内容:", oldStr, "</n>现服务内容:", newStr)
  1685. return
  1686. }
  1687. // 获取权益近一年是否有新签合同
  1688. func GetCompanyContractCountRaiByLastYear(companyId int, startDate string) (total int, err error) {
  1689. firstContractRai, err := company.GetFirstContractRai(companyId)
  1690. if err != nil && err.Error() != utils.ErrNoRow() {
  1691. return
  1692. }
  1693. //没有合同这第一份合同就属于新签合同
  1694. if firstContractRai == nil {
  1695. err = nil
  1696. total = 1
  1697. return
  1698. }
  1699. //判断是否是在一年以内
  1700. startDateTime, _ := time.Parse(utils.FormatDate, startDate)
  1701. startDateTime = startDateTime.AddDate(-1, 0, 0)
  1702. startDateTimeFirst, _ := time.Parse(utils.FormatDate, firstContractRai.StartDate)
  1703. if startDateTime.Before(startDateTimeFirst) {
  1704. total = 1
  1705. }
  1706. return
  1707. }
  1708. func initCRM15_5() {
  1709. var condition string
  1710. var pars []interface{}
  1711. condition = " AND rai_contract_type = '新签合同' AND product_id = 2 "
  1712. companyContractList, e := company.GetCompanyContractList(condition, pars)
  1713. if e != nil && e.Error() != utils.ErrNoRow() {
  1714. fmt.Println(e)
  1715. return
  1716. }
  1717. var CompanyContractIdS []int
  1718. for k, v := range companyContractList {
  1719. fmt.Println(k)
  1720. firstContractRai, err := company.GetFirstContractRai(v.CompanyId)
  1721. if err != nil {
  1722. fmt.Println(err)
  1723. continue
  1724. }
  1725. if firstContractRai.CompanyContractId == v.CompanyContractId {
  1726. continue
  1727. }
  1728. //判断是否是在一年以内
  1729. startDateTime, _ := time.Parse(utils.FormatDate, v.StartDate)
  1730. startDateTime = startDateTime.AddDate(-1, 0, 0)
  1731. startDateTimeFirst, _ := time.Parse(utils.FormatDate, firstContractRai.StartDate)
  1732. if !startDateTime.Before(startDateTimeFirst) {
  1733. CompanyContractIdS = append(CompanyContractIdS, v.CompanyContractId)
  1734. }
  1735. }
  1736. fmt.Println("companyContractIds", len(CompanyContractIdS))
  1737. fmt.Println("companyContractIds", (CompanyContractIdS))
  1738. //
  1739. //fmt.Println(strings.Join(companyContractIds, ","))
  1740. //err := company.UpdateCompanyContractRaiContractTypeInit(strings.Join(companyContractIds, ","))
  1741. //fmt.Println(err)
  1742. return
  1743. }