business.go 39 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255
  1. package proj
  2. import (
  3. "context"
  4. contractDao "dashoo.cn/micro/app/dao/contract"
  5. custDao "dashoo.cn/micro/app/dao/cust"
  6. projDao "dashoo.cn/micro/app/dao/proj"
  7. contractModel "dashoo.cn/micro/app/model/contract"
  8. model "dashoo.cn/micro/app/model/proj"
  9. workflowModel "dashoo.cn/micro/app/model/workflow"
  10. workflowService "dashoo.cn/micro/app/service/workflow"
  11. "dashoo.cn/micro/app/service"
  12. "dashoo.cn/opms_libary/multipart"
  13. "dashoo.cn/opms_libary/myerrors"
  14. "dashoo.cn/opms_libary/plugin/dingtalk"
  15. "dashoo.cn/opms_libary/plugin/dingtalk/message"
  16. "dashoo.cn/opms_libary/plugin/dingtalk/workflow"
  17. "dashoo.cn/opms_libary/utils"
  18. "fmt"
  19. "github.com/gogf/gf/database/gdb"
  20. "github.com/gogf/gf/frame/g"
  21. "github.com/gogf/gf/os/gtime"
  22. "github.com/gogf/gf/util/gconv"
  23. "github.com/shopspring/decimal"
  24. "strconv"
  25. "strings"
  26. )
  27. type businessService struct {
  28. *service.ContextService
  29. Dao *projDao.ProjBusinessDao
  30. }
  31. func NewBusinessService(ctx context.Context) (svc *businessService, err error) {
  32. svc = new(businessService)
  33. if svc.ContextService, err = svc.Init(ctx); err != nil {
  34. return nil, err
  35. }
  36. svc.Dao = projDao.NewProjBusinessDao(svc.Tenant)
  37. return svc, nil
  38. }
  39. func (p *businessService) GetList(req *model.ProjBusinessSearchReq) (total int, businessList []*model.ProjBusinessRes, err error) {
  40. db := p.Dao.As("proj").DataScope(p.Ctx, "sale_id")
  41. if req.NboName != "" {
  42. db = db.WhereLike("proj."+p.Dao.C.NboName, "%"+req.NboName+"%")
  43. }
  44. if req.CustName != "" {
  45. db = db.WhereLike("proj."+p.Dao.C.CustName, "%"+req.CustName+"%")
  46. }
  47. if req.SaleName != "" {
  48. db = db.WhereLike("proj."+p.Dao.C.SaleName, "%"+req.SaleName+"%")
  49. }
  50. if req.NboType != "" {
  51. db = db.Where("proj."+p.Dao.C.NboType, req.NboType)
  52. }
  53. if req.ProductLine != "" {
  54. db = db.Where("proj."+p.Dao.C.ProductLine, req.ProductLine)
  55. }
  56. if req.NboSource != "" {
  57. db = db.Where("proj."+p.Dao.C.NboSource, req.NboSource)
  58. }
  59. if req.DistributorName != "" {
  60. db = db.Where("proj."+p.Dao.C.DistributorName, "%"+req.DistributorName+"%")
  61. }
  62. if req.BeginTime != "" {
  63. db = db.WhereGTE("proj."+p.Dao.C.FilingTime, req.BeginTime)
  64. }
  65. if req.EndTime != "" {
  66. db = db.WhereLTE("proj."+p.Dao.C.FilingTime, req.EndTime)
  67. }
  68. total, err = db.Count()
  69. if err != nil {
  70. err = myerrors.DbError("获取总行数失败。")
  71. return
  72. }
  73. if req.NboType == StatusDeal {
  74. db = db.Unscoped().WhereNull(`proj.deleted_time`).
  75. LeftJoin(contractDao.CtrContract.Table, "contract", "`proj`.id=`contract`.nbo_id AND `contract`.`deleted_time` IS NULL ").
  76. Fields("`proj`.cust_city_id as cust_city_id,`contract`.contract_amount, `contract`.created_time as proj_closing_time")
  77. }
  78. db = db.Fields("`proj`.*")
  79. err = db.Page(req.PageNum, req.PageSize).OrderDesc("id").Scan(&businessList)
  80. return
  81. }
  82. func (p *businessService) GetEntityById(id int64) (business *model.ProjBusiness, err error) {
  83. err = p.Dao.Where(projDao.ProjBusiness.C.Id, id).Scan(&business)
  84. return
  85. }
  86. func (p *businessService) GetBusinessProduct(id int64) (productList []*model.ProjBusinessProduct, err error) {
  87. productDao := projDao.NewProjBusinessProductDao(p.Tenant)
  88. err = productDao.Where(productDao.ProjBusinessProductDao.C.BusId, id).Scan(&productList)
  89. return
  90. }
  91. func (p *businessService) GetBusinessDynamics(req *model.BusinessReq) (total int, result g.MapStrAny, err error) {
  92. result = make(g.MapStrAny, 0)
  93. dynamicsDao := projDao.NewProjBusinessDynamicsDao(p.Tenant).ProjBusinessDynamicsDao.Where(projDao.ProjBusinessDynamics.C.BusId, req.BusId)
  94. total, err = dynamicsDao.Count()
  95. if err != nil {
  96. g.Log().Error(err)
  97. return
  98. }
  99. dynamicsList, err := dynamicsDao.Page(req.GetPage()).Order("created_time desc").All()
  100. if err != nil || dynamicsList == nil {
  101. return
  102. }
  103. // 数据树格式转换
  104. opnDateFlag := gtime.New(dynamicsList[0].OpnDate).Format("Y-m-d")
  105. for k, v := range dynamicsList {
  106. opnDate := gtime.New(v.OpnDate).Format("Y-m-d")
  107. if opnDateFlag == opnDate && k != 0 {
  108. result[opnDate] = append(result[opnDate].(g.ListStrAny), g.Map{
  109. "opnPeople": v.OpnPeople,
  110. "opnDate": v.OpnDate,
  111. "opnType": v.OpnType,
  112. "remark": v.Remark,
  113. "opnContent": gconv.Map(v.OpnContent),
  114. })
  115. } else {
  116. temp := make(g.ListStrAny, 0)
  117. temp = append(temp, g.Map{
  118. "opnPeople": v.OpnPeople,
  119. "opnDate": v.OpnDate,
  120. "opnType": v.OpnType,
  121. "remark": v.Remark,
  122. "opnContent": gconv.Map(v.OpnContent),
  123. })
  124. result[opnDate] = temp
  125. }
  126. }
  127. return
  128. }
  129. func (p *businessService) GetBusinessDynamicsList(req *model.BusinessDynamicsReq) (total int, list []map[string]interface{}, err error) {
  130. dynamicsDao := projDao.NewProjBusinessDynamicsDao(p.Tenant).Where(projDao.ProjBusinessDynamics.C.BusId, req.BusId)
  131. if req.OpnType != "" {
  132. dynamicsDao = dynamicsDao.Where(projDao.ProjBusinessDynamics.C.OpnType+" = ?", req.OpnType)
  133. }
  134. total, err = dynamicsDao.Count()
  135. if err != nil {
  136. g.Log().Error(err)
  137. return
  138. }
  139. dynamicsList, err := dynamicsDao.Page(req.GetPage()).Order("created_time desc").All()
  140. for _, v := range dynamicsList {
  141. val := gconv.Map(v)
  142. val["opnContent"] = gconv.Map(v.OpnContent)
  143. list = append(list, val)
  144. }
  145. return
  146. }
  147. // 获取项目编号
  148. func (p *businessService) getNboCode(customerCode string) (string, error) {
  149. sequence, err := service.Sequence(p.Dao.DB, "nbo_code")
  150. if err != nil {
  151. return "", err
  152. }
  153. return customerCode + sequence, nil
  154. }
  155. func (p *businessService) Create(req *model.AddProjBusinessReq) (err error) {
  156. // 获取客户信息
  157. customer, err := custDao.NewCustCustomerDao(p.Tenant).WherePri(req.CustId).One()
  158. if err != nil {
  159. return err
  160. }
  161. if customer == nil {
  162. return myerrors.TipsError("客户不存在")
  163. }
  164. // 设置默认联系人
  165. contact := g.Map{
  166. projDao.ProjBusinessContact.C.ContactId: req.ContactId,
  167. }
  168. service.SetCreatedInfo(contact, p.GetCxtUserId(), p.GetCxtUserName())
  169. // 设置产品信息
  170. totalPrice, products, err := p.setProductInfo(0, req.Products)
  171. if err != nil {
  172. return err
  173. }
  174. // 获取项目编号
  175. nboCode, err := p.getNboCode(customer.CustCode)
  176. if err != nil {
  177. return err
  178. }
  179. // 初始化项目信息
  180. businessData := new(model.ProjBusiness)
  181. if err = gconv.Struct(req, businessData); err != nil {
  182. return
  183. }
  184. businessData.NboCode = nboCode
  185. //businessData.NboStatus = StatusOK
  186. businessData.NboType = StatusC
  187. businessData.ApproStatus = ApprovalNotSubmit
  188. businessData.EstTransPrice = totalPrice
  189. businessData.CustProvinceId = customer.CustProvinceId
  190. businessData.CustProvince = customer.CustProvince
  191. businessData.CustCityId = customer.CustCityId
  192. businessData.CustCity = customer.CustCity
  193. businessData.CustRegionId = customer.CustRegionId
  194. businessData.CustRegion = customer.CustRegion
  195. businessData.DeptId = p.GetCxtUserDeptId()
  196. service.SetCreatedInfo(businessData, p.GetCxtUserId(), p.GetCxtUserName())
  197. businessData.FilingTime = businessData.CreatedTime
  198. // 事务
  199. err = p.Dao.Transaction(context.TODO(), func(ctx context.Context, tx *gdb.TX) error {
  200. // 添加项目
  201. lastId, err := p.Dao.TX(tx).InsertAndGetId(businessData)
  202. if err != nil {
  203. return err
  204. }
  205. // 创建了联系人
  206. contact[projDao.ProjBusinessContact.C.BusId] = lastId
  207. _, err = projDao.NewProjBusinessContactDao(p.Tenant).TX(tx).Insert(contact)
  208. if err != nil {
  209. return err
  210. }
  211. // 处理项目产品信息
  212. for _, v := range products {
  213. v.BusId = int(lastId)
  214. }
  215. // 添加项目产品
  216. _, err = projDao.NewProjBusinessProductDao(p.Tenant).TX(tx).Insert(products)
  217. if err != nil {
  218. return err
  219. }
  220. // 添加项目动态
  221. dynamics := model.ProjBusinessDynamics{
  222. BusId: int(lastId),
  223. OpnType: OpnCreate,
  224. Remark: businessData.Remark,
  225. }
  226. _, err = p.CreateProjBusinessDynamics(tx, dynamics, businessData)
  227. return err
  228. })
  229. return
  230. }
  231. // setProductInfo 设置产品信息
  232. func (p *businessService) setProductInfo(busId int, productInfo []model.BusinessProduct) (total float64, products []*model.ProjBusinessProduct, err error) {
  233. products = make([]*model.ProjBusinessProduct, len(productInfo))
  234. if err = gconv.Structs(productInfo, &products); err != nil {
  235. return 0, nil, err
  236. }
  237. var totalPrice decimal.Decimal
  238. for _, v := range products {
  239. v.Id = 0
  240. v.BusId = busId
  241. v.TotalPrice = decimal.NewFromFloat(v.ProdPrice).Mul(decimal.NewFromInt(int64(v.ProdNum))).InexactFloat64()
  242. totalPrice = totalPrice.Add(decimal.NewFromFloat(v.TotalPrice))
  243. service.SetCreatedInfo(v, p.GetCxtUserId(), p.GetCxtUserName())
  244. }
  245. return totalPrice.InexactFloat64(), products, nil
  246. }
  247. func (p *businessService) UpdateById(req *model.UpdateProjBusinessReq) error {
  248. record, err := p.Dao.WherePri(req.Id).Count()
  249. if err != nil {
  250. return err
  251. }
  252. if record == 0 {
  253. return myerrors.TipsError("项目不存在。")
  254. }
  255. // 设置产品信息
  256. totalPrice, products, err := p.setProductInfo(req.Id, req.Products)
  257. if err != nil {
  258. return err
  259. }
  260. // 设置默认联系人
  261. contact := g.Map{
  262. projDao.ProjBusinessContact.C.BusId: req.Id,
  263. projDao.ProjBusinessContact.C.ContactId: req.ContactId,
  264. }
  265. contactFlag, err := projDao.NewProjBusinessContactDao(p.Tenant).Where(contact).Count()
  266. if err != nil {
  267. return err
  268. }
  269. if contactFlag == 0 {
  270. service.SetCreatedInfo(contact, p.GetCxtUserId(), p.GetCxtUserName())
  271. }
  272. // 设置项目信息
  273. req.EstTransPrice = totalPrice
  274. businessData := gconv.Map(req)
  275. service.SetUpdatedInfo(businessData, p.GetCxtUserId(), p.GetCxtUserName())
  276. err = p.Dao.Transaction(context.TODO(), func(ctx context.Context, tx *gdb.TX) error {
  277. // 更新项目
  278. _, err = p.Dao.TX(tx).FieldsEx(service.UpdateFieldEx...).WherePri(projDao.ProjBusiness.C.Id, req.Id).Update(businessData)
  279. if err != nil {
  280. return err
  281. }
  282. // 删除项目产品
  283. _, err = projDao.NewProjBusinessProductDao(p.Tenant).TX(tx).Where(projDao.ProjBusinessProduct.C.BusId, req.Id).Delete()
  284. if err != nil {
  285. return err
  286. }
  287. // 添加项目产品
  288. _, err = projDao.NewProjBusinessProductDao(p.Tenant).TX(tx).Insert(products)
  289. if err != nil {
  290. return err
  291. }
  292. // 关联联系人
  293. if contactFlag == 0 {
  294. _, err = projDao.NewProjBusinessContactDao(p.Tenant).TX(tx).Insert(contact)
  295. if err != nil {
  296. return err
  297. }
  298. }
  299. // 添加项目动态
  300. dynamics := model.ProjBusinessDynamics{
  301. BusId: req.Id,
  302. OpnType: OpnUpdate,
  303. Remark: req.Remark,
  304. }
  305. _, err = p.CreateProjBusinessDynamics(tx, dynamics, req)
  306. return err
  307. })
  308. return err
  309. }
  310. func (p *businessService) DeleteByIds(ids []int64) (err error) {
  311. _, err = p.Dao.WhereIn(projDao.ProjBusiness.C.Id, ids).Delete()
  312. return
  313. }
  314. // BusinessTransfer 项目转移
  315. func (p *businessService) BusinessTransfer(req *model.BusinessTransferReq) error {
  316. business, err := p.Dao.WherePri(req.Id).WhereNot(p.Dao.C.ApproStatus, ApprovalWaiting).One()
  317. if err != nil {
  318. return err
  319. }
  320. if business == nil {
  321. return myerrors.TipsError("项目已提交审批任务,无法重复提交。")
  322. }
  323. businessMap := g.Map{
  324. p.Dao.C.ApproStatus: ApprovalWaiting,
  325. }
  326. service.SetUpdatedInfo(businessMap, p.GetCxtUserId(), p.GetCxtUserName())
  327. opnContent := businessMap
  328. opnContent["origSaleId"] = business.SaleId
  329. opnContent["origSaleName"] = business.SaleName
  330. opnContent["saleId"] = req.UserId
  331. opnContent["saleName"] = req.UserName
  332. opnContent["remark"] = req.Remark
  333. // 审批流
  334. workflowSrv, _ := workflowService.NewFlowService(p.Ctx)
  335. err = p.Dao.Transaction(context.TODO(), func(ctx context.Context, tx *gdb.TX) error {
  336. // 更新项目
  337. _, err = p.Dao.TX(tx).WherePri(projDao.ProjBusiness.C.Id, req.Id).Data(businessMap).Update()
  338. if err != nil {
  339. return err
  340. }
  341. // 添加项目动态
  342. dynamics := model.ProjBusinessDynamics{
  343. BusId: req.Id,
  344. OpnType: OpnTransfer,
  345. Remark: req.Remark,
  346. }
  347. _, err = p.CreateProjBusinessDynamics(tx, dynamics, opnContent)
  348. if err != nil {
  349. g.Log().Error(err)
  350. return err
  351. }
  352. // OMS项目转移 审批
  353. bizCode := business.NboCode + ":" + strconv.Itoa(business.Id)
  354. _, err = workflowSrv.StartProcessInstance(bizCode, workflowModel.ProjectTransfer, "", &workflow.StartProcessInstanceRequest{
  355. ProcessCode: &BusinessTransferRequestProcessCode,
  356. FormComponentValues: []*workflow.StartProcessInstanceRequestFormComponentValues{
  357. {
  358. Id: utils.String("TextField-K2AD4O5B"),
  359. Name: utils.String("项目编码"),
  360. Value: utils.String(business.NboCode),
  361. },
  362. {
  363. Id: utils.String("TextField_7EFHRQ9DDF80"),
  364. Name: utils.String("项目名称"),
  365. Value: utils.String(business.NboName),
  366. },
  367. {
  368. Id: utils.String("TextField_1T3DEY5FWV7K0"),
  369. Name: utils.String("客户名称"),
  370. Value: utils.String(business.CustName),
  371. },
  372. {
  373. Id: utils.String("TextField_QDU06LXYKK00"),
  374. Name: utils.String("所在省"),
  375. Value: utils.String(business.CustProvince),
  376. },
  377. {
  378. Id: utils.String("TextField_MVSOO6EG6YO0"),
  379. Name: utils.String("所在市"),
  380. Value: utils.String(business.CustCity),
  381. },
  382. {
  383. Id: utils.String("TextField_1E1WOYGKRTDS0"),
  384. Name: utils.String("项目级别"),
  385. Value: utils.String(nboType[business.NboType]),
  386. },
  387. {
  388. Id: utils.String("TextField_NRQXWLJ17HC0"),
  389. Name: utils.String("申请人"),
  390. Value: utils.String(p.GetCxtUserName()),
  391. },
  392. {
  393. Id: utils.String("TextField_GHSQYDGD13K0"),
  394. Name: utils.String("转移原因"),
  395. Value: utils.String(req.Remark),
  396. },
  397. {
  398. Id: utils.String("TextField_76P8FPHH0UC0"),
  399. Name: utils.String("接收人"),
  400. Value: utils.String(req.UserName),
  401. },
  402. },
  403. })
  404. if err != nil {
  405. g.Log().Error(err)
  406. return err
  407. }
  408. return nil
  409. })
  410. return err
  411. }
  412. // BusinessTransferNotify 项目转移 审批结果通知
  413. func (p *businessService) BusinessTransferNotify(flow *workflowModel.PlatWorkflow, msg *message.MixMessage) error {
  414. business, err := p.checkDingTalkNotify(flow, msg)
  415. if err != nil {
  416. return err
  417. }
  418. var data = g.Map{}
  419. if msg.ProcessType == "terminate" {
  420. data[p.Dao.C.ApproStatus] = ApprovalReturn
  421. }
  422. if msg.ProcessType == "finish" && msg.Result == "refuse" {
  423. data[p.Dao.C.ApproStatus] = ApprovalRejection
  424. }
  425. if msg.ProcessType == "finish" && msg.Result == "agree" {
  426. // 从项目动态内获取变更信息
  427. var transferDynamics model.ProjBusinessDynamics
  428. dynamicsDao := projDao.NewProjBusinessDynamicsDao(p.Tenant).Where(projDao.ProjBusinessDynamics.C.BusId, business.Id)
  429. err = dynamicsDao.Where(projDao.ProjBusinessDynamics.C.OpnType, OpnTransfer).OrderDesc("created_time").Scan(&transferDynamics)
  430. if err != nil {
  431. return err
  432. }
  433. changeData := gconv.Map(transferDynamics.OpnContent)
  434. data[p.Dao.C.SaleId] = changeData["saleId"]
  435. data[p.Dao.C.SaleName] = changeData["saleName"]
  436. data[p.Dao.C.Remark] = changeData["remark"]
  437. data[p.Dao.C.ApproStatus] = ApprovalOK
  438. }
  439. // 项目修改
  440. _, err = p.Dao.WherePri(business.Id).FieldsEx(service.UpdateFieldEx...).Data(data).Update()
  441. if err != nil {
  442. return err
  443. }
  444. // 添加项目动态
  445. dynamics := model.ProjBusinessDynamics{
  446. BusId: business.Id,
  447. OpnType: OpnTransferApproval,
  448. }
  449. _, err = p.CreateProjBusinessDynamics(nil, dynamics, data)
  450. if err != nil {
  451. return err
  452. }
  453. return err
  454. }
  455. // BusinessGradation 项目调级
  456. func (p *businessService) BusinessGradation(busId int, nboType, busType string) (*model.ProjBusiness, error) {
  457. business, err := p.Dao.WherePri(busId).WhereNot(p.Dao.C.ApproStatus, ApprovalWaiting).One()
  458. if err != nil {
  459. return nil, err
  460. }
  461. if business == nil {
  462. return nil, myerrors.TipsError("项目已提交审批任务,无法重复提交。")
  463. }
  464. if business.NboType == nboType {
  465. return nil, myerrors.TipsError("同级别无法进行调级。")
  466. }
  467. if business.NboType == StatusDeal {
  468. return nil, myerrors.TipsError("成交项目无法进行调级。")
  469. }
  470. if business.NboType == StatusReserve && nboType == StatusDeal {
  471. return nil, myerrors.TipsError("储备项目无法直接转为成交项目。")
  472. }
  473. if busType == "up" && gconv.Int(business.NboType) < gconv.Int(nboType) {
  474. return nil, myerrors.TipsError("项目级别错误。")
  475. }
  476. if busType == "down" && gconv.Int(business.NboType) > gconv.Int(nboType) {
  477. return nil, myerrors.TipsError("项目级别错误。")
  478. }
  479. return business, err
  480. }
  481. // BusinessUpgrade 项目升级
  482. func (p *businessService) BusinessUpgrade(req *model.BusinessUpgradeReq, args *multipart.MultipartFile) error {
  483. business, err := p.BusinessGradation(req.Id, req.NboType, "up")
  484. if err != nil {
  485. return err
  486. }
  487. businessMap := g.Map{
  488. p.Dao.C.ApproStatus: ApprovalWaiting,
  489. }
  490. service.SetUpdatedInfo(businessMap, p.GetCxtUserId(), p.GetCxtUserName())
  491. opnContent := gconv.Map(req)
  492. opnContent["origNboType"] = business.NboType
  493. opnContent["approStatus"] = ApprovalWaiting
  494. service.SetUpdatedInfo(opnContent, p.GetCxtUserId(), p.GetCxtUserName())
  495. err = p.Dao.Transaction(context.TODO(), func(ctx context.Context, tx *gdb.TX) error {
  496. // 更新项目调级
  497. _, err = p.Dao.TX(tx).WherePri(req.Id).Data(businessMap).Update()
  498. if err != nil {
  499. return err
  500. }
  501. // 添加项目动态
  502. dynamics := model.ProjBusinessDynamics{
  503. BusId: business.Id,
  504. OpnType: OpnUpgrade,
  505. Remark: req.Remark,
  506. }
  507. _, err = p.CreateProjBusinessDynamics(tx, dynamics, opnContent)
  508. if err != nil {
  509. return err
  510. }
  511. err = p.BusUpgradeDingEvent(business, req, args)
  512. return err
  513. })
  514. return err
  515. }
  516. // 获取项目的钉钉审批的升级类型
  517. func (p *businessService) getBusDingUpgradeType(dbNboType, reqNboType string) string {
  518. var upgradeType string
  519. switch true {
  520. case dbNboType == StatusReserve && reqNboType == StatusC: // 储备转C/option_0
  521. upgradeType = "储备转C"
  522. case dbNboType == StatusReserve && reqNboType == StatusB: // 储备转B/option_1
  523. upgradeType = "储备转B"
  524. case dbNboType == StatusReserve && reqNboType == StatusA: // 储备转A/option_KTAX3Y9K5340
  525. upgradeType = "储备转A"
  526. case dbNboType == StatusC && reqNboType == StatusB: // C转B/option_0
  527. upgradeType = "C转B"
  528. case dbNboType == StatusC && reqNboType == StatusA: // C转A/option_0
  529. upgradeType = "C转A"
  530. case dbNboType == StatusB && reqNboType == StatusA: // B转A/option_1
  531. upgradeType = "B转A"
  532. default:
  533. }
  534. return upgradeType
  535. }
  536. // BusUpgradeDingEvent 项目升级钉钉审批流调用
  537. func (p *businessService) BusUpgradeDingEvent(business *model.ProjBusiness, req *model.BusinessUpgradeReq, args *multipart.MultipartFile) error {
  538. upgradeType := p.getBusDingUpgradeType(business.NboType, req.NboType)
  539. if upgradeType == "" {
  540. return myerrors.TipsError("错误的升级类型")
  541. }
  542. // 审批流
  543. workflowSrv, _ := workflowService.NewFlowService(p.Ctx)
  544. // OMS项目升级 审批
  545. var err error
  546. var dingReq *workflow.StartProcessInstanceRequest
  547. bizCode := business.NboCode + ":" + strconv.Itoa(business.Id)
  548. switch req.NboType {
  549. case StatusC:
  550. dingReq = &workflow.StartProcessInstanceRequest{
  551. ProcessCode: &BusinessUpgradeCRequestProcessCode,
  552. FormComponentValues: []*workflow.StartProcessInstanceRequestFormComponentValues{
  553. {
  554. Id: utils.String("TextField-K2AD4O5B"),
  555. Name: utils.String("项目编码"),
  556. Value: utils.String(business.NboCode),
  557. },
  558. {
  559. Id: utils.String("TextField_BDLSECETVSG0"),
  560. Name: utils.String("项目名称"),
  561. Value: utils.String(business.NboName),
  562. },
  563. {
  564. Id: utils.String("DDSelectField_VSA3U380ZK00"),
  565. Name: utils.String("升级类型"),
  566. Value: utils.String(upgradeType),
  567. },
  568. {
  569. Id: utils.String("TextField_1J9BJMOZ18F40"),
  570. Name: utils.String("客户名称"),
  571. Value: utils.String(business.CustName),
  572. },
  573. {
  574. Id: utils.String("TextField_AEUWH63LJ0O0"),
  575. Name: utils.String("销售工程师"),
  576. Value: utils.String(business.SaleName),
  577. },
  578. {
  579. Id: utils.String("TextareaField_1LO81IKHH91C0"),
  580. Name: utils.String("转化原因"),
  581. Value: utils.String(req.ProjConversionReason),
  582. },
  583. },
  584. }
  585. case StatusB:
  586. processCode := &BusinessUpgradeBRequestProcessCode
  587. dingReq = &workflow.StartProcessInstanceRequest{
  588. ProcessCode: processCode,
  589. FormComponentValues: []*workflow.StartProcessInstanceRequestFormComponentValues{
  590. {
  591. Id: utils.String("TextField-K2AD4O5B"),
  592. Name: utils.String("项目编码"),
  593. Value: utils.String(business.NboCode),
  594. },
  595. {
  596. Id: utils.String("TextField_BDLSECETVSG0"),
  597. Name: utils.String("项目名称"),
  598. Value: utils.String(business.NboName),
  599. },
  600. {
  601. Id: utils.String("DDSelectField_VSA3U380ZK00"),
  602. Name: utils.String("升级类型"),
  603. Value: utils.String(upgradeType),
  604. },
  605. {
  606. Id: utils.String("TextField_1J9BJMOZ18F40"),
  607. Name: utils.String("客户名称"),
  608. Value: utils.String(business.CustName),
  609. },
  610. {
  611. Id: utils.String("NumberField_1F88MCD0W8KG0"),
  612. Name: utils.String("项目预算"),
  613. Value: utils.String(gconv.String(req.NboBudget)),
  614. },
  615. {
  616. Id: utils.String("TextField_1PWK6WHMGITC0"),
  617. Name: utils.String("经销商/代理商"),
  618. Value: utils.String(req.DistributorName),
  619. },
  620. {
  621. Id: utils.String("TextField_X4D3QGARU7K0"),
  622. Name: utils.String("支持内容"),
  623. Value: utils.String(req.TechnicalSupportContent),
  624. },
  625. {
  626. Id: utils.String("TextField_AEUWH63LJ0O0"),
  627. Name: utils.String("销售工程师"),
  628. Value: utils.String(business.SaleName),
  629. },
  630. {
  631. Id: utils.String("DDDateField_1FW1QZQYBZVK0"),
  632. Name: utils.String("采购时间"),
  633. Value: utils.String(gconv.String(req.PurchasingTime.Format("Y-m-d"))),
  634. },
  635. {
  636. Id: utils.String("DDSelectField_21ASEWDIB3MO0"),
  637. Name: utils.String("采购方式"),
  638. Value: utils.String(gconv.String(purchasingWayType[req.PurchasingWay])),
  639. },
  640. {
  641. Id: utils.String("DDSelectField_5R11VVM6GI00"),
  642. Name: utils.String("是否我司参数"),
  643. Value: utils.String(gconv.String(yesOrNoType[req.IsAdoptDashoo])),
  644. },
  645. {
  646. Id: utils.String("TextareaField_1GEL8JJL3H5S0"),
  647. Name: utils.String("备注"),
  648. Value: utils.String(req.Remark),
  649. },
  650. },
  651. }
  652. case StatusA:
  653. resp, err := dingtalk.Client.GetStorage().UploadFile(spaceId, p.GetCxtUserDingtalkId(), args.FileName, args.File.Name())
  654. if err != nil {
  655. return fmt.Errorf("钉钉上传文件异常 %s", err.Error())
  656. }
  657. g.Log().Info("项目转A类提交大数参数文件", resp)
  658. file := []contractModel.DingFileInfo{{
  659. SpaceId: resp.Dentry.SpaceId,
  660. FileId: resp.Dentry.Id,
  661. FileName: resp.Dentry.Name,
  662. FileSize: resp.Dentry.Size,
  663. FileType: resp.Dentry.Extension,
  664. }}
  665. err = p.txCreateBusinessFile(business.Id, file)
  666. if err != nil {
  667. return err
  668. }
  669. processCode := &BusinessUpgradeARequestProcessCode
  670. dingReq = &workflow.StartProcessInstanceRequest{
  671. ProcessCode: processCode,
  672. FormComponentValues: []*workflow.StartProcessInstanceRequestFormComponentValues{
  673. {
  674. Id: utils.String("TextField-K2AD4O5B"),
  675. Name: utils.String("项目编码"),
  676. Value: utils.String(business.NboCode),
  677. },
  678. {
  679. Id: utils.String("TextField_BDLSECETVSG0"),
  680. Name: utils.String("项目名称"),
  681. Value: utils.String(business.NboName),
  682. },
  683. {
  684. Id: utils.String("DDSelectField_VSA3U380ZK00"),
  685. Name: utils.String("升级类型"),
  686. Value: utils.String(upgradeType),
  687. },
  688. {
  689. Id: utils.String("TextField_1J9BJMOZ18F40"),
  690. Name: utils.String("客户名称"),
  691. Value: utils.String(business.CustName),
  692. },
  693. {
  694. Id: utils.String("NumberField_1F88MCD0W8KG0"),
  695. Name: utils.String("项目预算"),
  696. Value: utils.String(gconv.String(req.NboBudget)),
  697. },
  698. {
  699. Id: utils.String("TextField_1PWK6WHMGITC0"),
  700. Name: utils.String("经销商/代理商"),
  701. Value: utils.String(req.DistributorName),
  702. },
  703. {
  704. Id: utils.String("TextField_X4D3QGARU7K0"),
  705. Name: utils.String("支持内容"),
  706. Value: utils.String(req.TechnicalSupportContent),
  707. },
  708. {
  709. Id: utils.String("TextField_AEUWH63LJ0O0"),
  710. Name: utils.String("销售工程师"),
  711. Value: utils.String(business.SaleName),
  712. },
  713. {
  714. Id: utils.String("DDDateField_1FW1QZQYBZVK0"),
  715. Name: utils.String("采购时间"),
  716. Value: utils.String(gconv.String(req.PurchasingTime.Format("Y-m-d"))),
  717. },
  718. {
  719. Id: utils.String("DDSelectField_21ASEWDIB3MO0"),
  720. Name: utils.String("采购方式"),
  721. Value: utils.String(gconv.String(purchasingWayType[req.PurchasingWay])),
  722. },
  723. {
  724. Id: utils.String("DDSelectField_5R11VVM6GI00"),
  725. Name: utils.String("是否我司参数"),
  726. Value: utils.String(gconv.String(yesOrNoType[req.IsAdoptDashoo])),
  727. },
  728. {
  729. Id: utils.String("DDAttachment_11Q7DBRKE6HC0"),
  730. Name: utils.String("附件"),
  731. Value: utils.String(gconv.String(file)),
  732. },
  733. {
  734. Id: utils.String("TextareaField_1GEL8JJL3H5S0"),
  735. Name: utils.String("备注"),
  736. Value: utils.String(req.Remark),
  737. },
  738. },
  739. }
  740. default:
  741. return nil
  742. }
  743. _, err = workflowSrv.StartProcessInstance(bizCode, workflowModel.ProjectUpGrade, "", dingReq)
  744. if err != nil {
  745. g.Log().Error(err)
  746. return err
  747. }
  748. return nil
  749. }
  750. // 采用大数参数文件记录
  751. func (p *businessService) txCreateBusinessFile(busId int, files []contractModel.DingFileInfo) error {
  752. dataList := make([]model.ProjBusinessFile, 0)
  753. for _, v := range files {
  754. data := new(model.ProjBusinessFile)
  755. data.BusId = busId
  756. data.FileName = v.FileName
  757. data.FileSource = "项目转为A类采用大数参数文件"
  758. data.FileSize = gconv.String(v.FileSize)
  759. data.FileUrl = strings.Join([]string{"dingtalk", v.SpaceId, v.FileId}, ":")
  760. service.SetCreatedInfo(data, p.GetCxtUserId(), p.GetCxtUserName())
  761. dataList = append(dataList)
  762. }
  763. _, err := projDao.NewProjBusinessFileDao(p.Tenant).Insert(&dataList)
  764. return err
  765. }
  766. // BusinessUpgradeNotify 项目升级 审批结果通知
  767. func (p *businessService) BusinessUpgradeNotify(flow *workflowModel.PlatWorkflow, msg *message.MixMessage) error {
  768. business, err := p.checkDingTalkNotify(flow, msg)
  769. if err != nil {
  770. return err
  771. }
  772. var data = g.Map{}
  773. if msg.ProcessType == "terminate" {
  774. data[p.Dao.C.ApproStatus] = ApprovalReturn
  775. }
  776. if msg.ProcessType == "finish" && msg.Result == "refuse" {
  777. data[p.Dao.C.ApproStatus] = ApprovalRejection
  778. }
  779. if msg.ProcessType == "finish" && msg.Result == "agree" {
  780. // 从项目动态内获取变更信息
  781. dynamics := new(model.ProjBusinessDynamics)
  782. dynamicsDao := projDao.NewProjBusinessDynamicsDao(p.Tenant).Where(projDao.ProjBusinessDynamics.C.BusId, business.Id)
  783. err = dynamicsDao.Where(projDao.ProjBusinessDynamics.C.OpnType, OpnUpgrade).OrderDesc("created_time").Scan(dynamics)
  784. if err != nil {
  785. return err
  786. }
  787. updateData := new(model.BusinessUpgradeReq)
  788. gconv.Struct(dynamics.OpnContent, updateData)
  789. data = gconv.Map(updateData)
  790. data[p.Dao.C.ApproStatus] = ApprovalOK
  791. }
  792. // 项目修改
  793. _, err = p.Dao.WherePri(business.Id).FieldsEx(service.UpdateFieldEx...).Data(data).Update()
  794. if err != nil {
  795. return err
  796. }
  797. // 添加项目动态
  798. dynamics := model.ProjBusinessDynamics{
  799. BusId: business.Id,
  800. OpnType: OpnUpgradeApproval,
  801. }
  802. _, err = p.CreateProjBusinessDynamics(nil, dynamics, data)
  803. if err != nil {
  804. return err
  805. }
  806. return nil
  807. }
  808. // 获取项目的钉钉审批的降级类型
  809. func (p *businessService) getBusDingDowngradeType(dbNboType, reqNboType string) string {
  810. var downgradeType string
  811. switch true {
  812. case dbNboType == StatusB && reqNboType == StatusC: // B转C/option_0
  813. downgradeType = "B转C"
  814. case dbNboType == StatusA && reqNboType == StatusB: // A转B/option_1
  815. downgradeType = "A转B"
  816. case dbNboType == StatusA && reqNboType == StatusC: // A转C/option_2
  817. downgradeType = "A转C"
  818. case dbNboType == StatusA && reqNboType == StatusReserve: // A转储备/option_YZMFJYQQK6O0
  819. downgradeType = "A转储备"
  820. case dbNboType == StatusB && reqNboType == StatusReserve: // B转储备/option_232GR5NMFCSG0
  821. downgradeType = "B转储备"
  822. case dbNboType == StatusC && reqNboType == StatusReserve: // C转储备/option_1ZV2GJLDKQOW0
  823. downgradeType = "C转储备"
  824. default:
  825. }
  826. return downgradeType
  827. }
  828. // BusinessDowngrade 项目降级
  829. func (p *businessService) BusinessDowngrade(req *model.BusinessDowngradeReq) error {
  830. business, err := p.BusinessGradation(req.Id, req.NboType, "down")
  831. if err != nil {
  832. return err
  833. }
  834. downgradeType := p.getBusDingDowngradeType(business.NboType, req.NboType)
  835. if downgradeType == "" {
  836. return myerrors.TipsError("错误的降级类型")
  837. }
  838. businessMap := g.Map{
  839. p.Dao.C.ApproStatus: ApprovalWaiting,
  840. }
  841. service.SetUpdatedInfo(businessMap, p.GetCxtUserId(), p.GetCxtUserName())
  842. opnContent := gconv.Map(req)
  843. opnContent["origNboType"] = business.NboType
  844. opnContent["approStatus"] = ApprovalWaiting
  845. service.SetUpdatedInfo(opnContent, p.GetCxtUserId(), p.GetCxtUserName())
  846. // 审批流
  847. workflowSrv, _ := workflowService.NewFlowService(p.Ctx)
  848. err = p.Dao.Transaction(context.TODO(), func(ctx context.Context, tx *gdb.TX) error {
  849. // 更新项目调级
  850. _, err = p.Dao.TX(tx).WherePri(req.Id).Data(businessMap).Update()
  851. if err != nil {
  852. return err
  853. }
  854. // 添加项目动态
  855. dynamics := model.ProjBusinessDynamics{
  856. BusId: business.Id,
  857. OpnType: OpnDowngrade,
  858. Remark: req.Remark,
  859. }
  860. _, err = p.CreateProjBusinessDynamics(tx, dynamics, opnContent)
  861. if err != nil {
  862. return err
  863. }
  864. // OMS项目降级 审批
  865. bizCode := business.NboCode + ":" + strconv.Itoa(business.Id)
  866. _, err = workflowSrv.StartProcessInstance(bizCode, workflowModel.ProjectDownGrade, "", &workflow.StartProcessInstanceRequest{
  867. ProcessCode: &BusinessDowngradeRequestProcessCode,
  868. FormComponentValues: []*workflow.StartProcessInstanceRequestFormComponentValues{
  869. {
  870. Id: utils.String("TextField-K2AD4O5B"),
  871. Name: utils.String("项目编码"),
  872. Value: utils.String(business.NboCode),
  873. },
  874. {
  875. Id: utils.String("TextField_BDLSECETVSG0"),
  876. Name: utils.String("项目名称"),
  877. Value: utils.String(business.NboName),
  878. },
  879. {
  880. Id: utils.String("TextField_1J9BJMOZ18F40"),
  881. Name: utils.String("客户名称"),
  882. Value: utils.String(business.CustName),
  883. },
  884. {
  885. Id: utils.String("TextField_GL7MQUB723K0"),
  886. Name: utils.String("所在省"),
  887. Value: utils.String(business.CustProvince),
  888. },
  889. {
  890. Id: utils.String("TextField_CFA88QQQUUO0"),
  891. Name: utils.String("所在市"),
  892. Value: utils.String(business.CustCity),
  893. },
  894. {
  895. Id: utils.String("DDSelectField_VSA3U380ZK00"),
  896. Name: utils.String("降级类型"),
  897. Value: utils.String(downgradeType),
  898. },
  899. {
  900. Id: utils.String("TextField_X4D3QGARU7K0"),
  901. Name: utils.String("支持内容"),
  902. Value: utils.String(req.TechnicalSupportContent),
  903. },
  904. {
  905. Id: utils.String("TextField_AEUWH63LJ0O0"),
  906. Name: utils.String("销售工程师"),
  907. Value: utils.String(business.SaleName),
  908. },
  909. {
  910. Id: utils.String("TextareaField_PTGJOKD3J7K0"),
  911. Name: utils.String("降级原因"),
  912. Value: utils.String(req.Remark),
  913. },
  914. },
  915. })
  916. if err != nil {
  917. g.Log().Error(err)
  918. return err
  919. }
  920. return nil
  921. })
  922. return err
  923. }
  924. // BusinessDowngradeNotify 项目降级 审批结果通知
  925. func (p *businessService) BusinessDowngradeNotify(flow *workflowModel.PlatWorkflow, msg *message.MixMessage) error {
  926. business, err := p.checkDingTalkNotify(flow, msg)
  927. if err != nil {
  928. return err
  929. }
  930. var data = g.Map{}
  931. if msg.ProcessType == "terminate" {
  932. data[p.Dao.C.ApproStatus] = ApprovalReturn
  933. }
  934. if msg.ProcessType == "finish" && msg.Result == "refuse" {
  935. data[p.Dao.C.ApproStatus] = ApprovalRejection
  936. }
  937. if msg.ProcessType == "finish" && msg.Result == "agree" {
  938. // 从项目动态内获取变更信息
  939. dynamics := new(model.ProjBusinessDynamics)
  940. dynamicsDao := projDao.NewProjBusinessDynamicsDao(p.Tenant).Where(projDao.ProjBusinessDynamics.C.BusId, business.Id)
  941. err = dynamicsDao.Where(projDao.ProjBusinessDynamics.C.OpnType, OpnDowngrade).OrderDesc("created_time").Scan(dynamics)
  942. if err != nil {
  943. return err
  944. }
  945. updateData := new(model.BusinessDowngradeReq)
  946. gconv.Struct(dynamics.OpnContent, updateData)
  947. data = gconv.Map(updateData)
  948. data[p.Dao.C.ApproStatus] = ApprovalOK
  949. }
  950. // 项目修改
  951. _, err = p.Dao.WherePri(business.Id).FieldsEx(service.UpdateFieldEx...).Data(data).Update()
  952. if err != nil {
  953. return err
  954. }
  955. // 添加项目动态
  956. dynamics := model.ProjBusinessDynamics{
  957. BusId: business.Id,
  958. OpnType: OpnDowngradeApproval,
  959. }
  960. _, err = p.CreateProjBusinessDynamics(nil, dynamics, data)
  961. if err != nil {
  962. return err
  963. }
  964. return nil
  965. }
  966. // SetPrimacyContact 项目设置首要联系人
  967. func (p *businessService) SetPrimacyContact(req *model.BusinessPrimacyContactReq) (err error) {
  968. business, err := p.Dao.Where(projDao.ProjBusiness.C.Id, req.Id).One()
  969. if err != nil {
  970. return err
  971. }
  972. if business == nil {
  973. return myerrors.TipsError("项目不存在。")
  974. }
  975. businessMap := g.Map{
  976. p.Dao.C.ContactId: req.ContactId,
  977. p.Dao.C.ContactName: req.ContactName,
  978. p.Dao.C.ContactPostion: req.ContactPostion,
  979. p.Dao.C.ContactTelephone: req.ContactTelephone,
  980. }
  981. service.SetUpdatedInfo(businessMap, p.GetCxtUserId(), p.GetCxtUserName())
  982. opnContent := businessMap
  983. opnContent["origContactId"] = business.ContactId
  984. opnContent["origContactName"] = business.ContactName
  985. opnContent["origContactPostion"] = business.ContactPostion
  986. opnContent["origContactTelephone"] = business.ContactTelephone
  987. err = p.Dao.Transaction(context.TODO(), func(ctx context.Context, tx *gdb.TX) error {
  988. // 更新项目
  989. _, err = p.Dao.TX(tx).WherePri(projDao.ProjBusiness.C.Id, req.Id).Data(businessMap).Update()
  990. if err != nil {
  991. return err
  992. }
  993. // 添加项目动态
  994. dynamics := model.ProjBusinessDynamics{
  995. BusId: req.Id,
  996. OpnType: OpnPrimacyContact,
  997. Remark: req.Remark,
  998. }
  999. _, err = p.CreateProjBusinessDynamics(tx, dynamics, opnContent)
  1000. return err
  1001. })
  1002. return err
  1003. }
  1004. // UpdateBusinessStatus 更新项目状态
  1005. func (p *businessService) UpdateBusinessStatus(req *model.UpdateBusinessStatusReq) error {
  1006. business, err := p.Dao.WherePri(req.Id).One()
  1007. if err != nil {
  1008. return err
  1009. }
  1010. if business == nil {
  1011. return myerrors.TipsError("项目不存在。")
  1012. }
  1013. businessMap := g.Map{
  1014. p.Dao.C.NboStatus: req.NboStatus,
  1015. p.Dao.C.Remark: req.Remark,
  1016. }
  1017. service.SetUpdatedInfo(businessMap, p.GetCxtUserId(), p.GetCxtUserName())
  1018. opnContent := businessMap
  1019. opnContent["origNboStatus"] = business.NboStatus
  1020. err = p.Dao.Transaction(context.TODO(), func(ctx context.Context, tx *gdb.TX) error {
  1021. // 更新项目
  1022. _, err = p.Dao.TX(tx).WherePri(projDao.ProjBusiness.C.Id, req.Id).Data(businessMap).Update()
  1023. if err != nil {
  1024. return err
  1025. }
  1026. // 添加项目动态
  1027. dynamics := model.ProjBusinessDynamics{
  1028. BusId: req.Id,
  1029. OpnType: OpnStatus,
  1030. Remark: req.Remark,
  1031. }
  1032. _, err = p.CreateProjBusinessDynamics(tx, dynamics, opnContent)
  1033. return err
  1034. })
  1035. return err
  1036. }
  1037. // CreateProjBusinessDynamics 创建项目动态
  1038. func (p *businessService) CreateProjBusinessDynamics(tx *gdb.TX, dynamics model.ProjBusinessDynamics, opnContent interface{}) (int64, error) {
  1039. if v, ok := opnContent.(g.Map); ok {
  1040. opnContent = utils.MapKeySnakeCamelCase(v)
  1041. }
  1042. // 添加项目动态
  1043. dynamics.OpnPeopleId = p.GetCxtUserId()
  1044. dynamics.OpnPeople = p.GetCxtUserName()
  1045. dynamics.OpnDate = gtime.Now()
  1046. dynamics.OpnContent = gconv.String(opnContent)
  1047. service.SetCreatedInfo(&dynamics, p.GetCxtUserId(), p.GetCxtUserName())
  1048. dao := projDao.NewProjBusinessDynamicsDao(p.Tenant).M
  1049. if tx != nil {
  1050. dao = dao.TX(tx)
  1051. }
  1052. lastId, err := dao.InsertAndGetId(&dynamics)
  1053. return lastId, err
  1054. }
  1055. // ConvertToReserve 转为储备项目
  1056. func (p *businessService) ConvertToReserve(req *model.BusinessToReserveReq) error {
  1057. business, err := p.Dao.WherePri(req.Id).WhereNot(p.Dao.C.ApproStatus, ApprovalWaiting).One()
  1058. if err != nil {
  1059. return err
  1060. }
  1061. if business == nil {
  1062. return myerrors.TipsError("项目已提交审批任务,无法重复提交。")
  1063. }
  1064. // 审批流
  1065. workflowSrv, _ := workflowService.NewFlowService(p.Ctx)
  1066. err = p.Dao.Transaction(context.TODO(), func(ctx context.Context, tx *gdb.TX) error {
  1067. // 更新项目
  1068. businessMap := g.Map{
  1069. p.Dao.C.ApproStatus: ApprovalWaiting,
  1070. p.Dao.C.ProjConversionTime: gtime.Now(),
  1071. p.Dao.C.ProjConversionReason: req.ProjConversionReason,
  1072. }
  1073. service.SetUpdatedInfo(businessMap, p.GetCxtUserId(), p.GetCxtUserName())
  1074. _, err = p.Dao.TX(tx).WherePri(business.Id).Data(businessMap).Update()
  1075. if err != nil {
  1076. return err
  1077. }
  1078. // 添加项目动态
  1079. dynamics := model.ProjBusinessDynamics{
  1080. BusId: business.Id,
  1081. OpnType: OpnToReserve,
  1082. Remark: req.ProjConversionReason,
  1083. }
  1084. _, err = p.CreateProjBusinessDynamics(tx, dynamics, businessMap)
  1085. if err != nil {
  1086. return err
  1087. }
  1088. // OMS项目转储备 审批
  1089. bizCode := business.NboCode + ":" + strconv.Itoa(business.Id)
  1090. _, err = workflowSrv.StartProcessInstance(bizCode, workflowModel.ProjectToReserve, "", &workflow.StartProcessInstanceRequest{
  1091. ProcessCode: &ConvertToReserveRequestProcessCode,
  1092. FormComponentValues: []*workflow.StartProcessInstanceRequestFormComponentValues{
  1093. {
  1094. Id: utils.String("TextField-K2AD4O5B"),
  1095. Name: utils.String("项目编码"),
  1096. Value: utils.String(business.NboCode),
  1097. },
  1098. {
  1099. Id: utils.String("TextField_CMH6TBXYR5S0"),
  1100. Name: utils.String("项目名称"),
  1101. Value: utils.String(business.NboName),
  1102. },
  1103. {
  1104. Id: utils.String("TextField_YQBGGYHQPS00"),
  1105. Name: utils.String("客户名称"),
  1106. Value: utils.String(business.CustName),
  1107. },
  1108. {
  1109. Id: utils.String("DDSelectField_VBY9YAIOK5C0"),
  1110. Name: utils.String("项目级别"),
  1111. Value: utils.String(convertToReserveType[business.NboType]),
  1112. },
  1113. {
  1114. Id: utils.String("TextField_1NDD3TY8KJB40"),
  1115. Name: utils.String("销售工程师"),
  1116. Value: utils.String(business.SaleName),
  1117. },
  1118. {
  1119. Id: utils.String("TextareaField_15KZFM4YHQ8W0"),
  1120. Name: utils.String("转化原因"),
  1121. Value: utils.String(req.ProjConversionReason),
  1122. },
  1123. },
  1124. })
  1125. if err != nil {
  1126. g.Log().Error(err)
  1127. return err
  1128. }
  1129. return nil
  1130. })
  1131. return err
  1132. }
  1133. // ConvertToReserveNotify 转为储备项目 审批结果通知
  1134. func (p *businessService) ConvertToReserveNotify(flow *workflowModel.PlatWorkflow, msg *message.MixMessage) error {
  1135. business, err := p.checkDingTalkNotify(flow, msg)
  1136. if err != nil {
  1137. return err
  1138. }
  1139. var data = g.Map{}
  1140. if msg.ProcessType == "terminate" {
  1141. data[p.Dao.C.ApproStatus] = ApprovalReturn
  1142. }
  1143. if msg.ProcessType == "finish" && msg.Result == "refuse" {
  1144. data[p.Dao.C.ApproStatus] = ApprovalRejection
  1145. }
  1146. if msg.ProcessType == "finish" && msg.Result == "agree" {
  1147. data[p.Dao.C.NboType] = StatusReserve
  1148. data[p.Dao.C.ApproStatus] = ApprovalOK
  1149. }
  1150. // 项目修改
  1151. _, err = p.Dao.WherePri(business.Id).FieldsEx(service.UpdateFieldEx...).Data(data).Update()
  1152. if err != nil {
  1153. return err
  1154. }
  1155. // 添加项目动态
  1156. dynamics := model.ProjBusinessDynamics{
  1157. BusId: business.Id,
  1158. OpnType: OpnToReserveApproval,
  1159. }
  1160. _, err = p.CreateProjBusinessDynamics(nil, dynamics, data)
  1161. if err != nil {
  1162. return err
  1163. }
  1164. return err
  1165. }
  1166. // 钉钉审批通知检查
  1167. func (p *businessService) checkDingTalkNotify(flow *workflowModel.PlatWorkflow, msg *message.MixMessage) (*model.ProjBusiness, error) {
  1168. bizCode := strings.Split(flow.BizCode, ":")
  1169. if len(bizCode) != 2 {
  1170. return nil, fmt.Errorf("项目转储备审批 bizCode 不合法:%s Id: %d", flow.BizCode, flow.Id)
  1171. }
  1172. nboCode := bizCode[0]
  1173. busId, err := strconv.Atoi(bizCode[1])
  1174. if err != nil {
  1175. return nil, fmt.Errorf("项目转储备审批 bizCode 不合法:%s Id: %d", flow.BizCode, flow.Id)
  1176. }
  1177. if msg.ProcessType != "finish" && msg.ProcessType != "terminate" {
  1178. return nil, fmt.Errorf("无法识别的 ProcessType :%s", msg.ProcessType)
  1179. }
  1180. if msg.Result != "agree" && msg.Result != "refuse" && msg.Result != "" {
  1181. return nil, fmt.Errorf("无法识别的 Result :%s", msg.Result)
  1182. }
  1183. fmt.Println(msg)
  1184. business, err := p.Dao.WherePri(busId).Where(p.Dao.C.NboCode, nboCode).One()
  1185. if err != nil {
  1186. return nil, err
  1187. }
  1188. if business == nil {
  1189. return nil, fmt.Errorf("项目不存在:%s Id: %d", flow.BizCode, flow.Id)
  1190. }
  1191. return business, nil
  1192. }