ctr_contract_sale_target.go 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340
  1. package service
  2. import (
  3. "bytes"
  4. "context"
  5. dao "dashoo.cn/micro/app/dao/contract"
  6. model "dashoo.cn/micro/app/model/contract"
  7. "dashoo.cn/micro/app/service/partner"
  8. "dashoo.cn/opms_libary/micro_srv"
  9. "dashoo.cn/opms_libary/myerrors"
  10. "dashoo.cn/opms_libary/request"
  11. "fmt"
  12. "github.com/gogf/gf/frame/g"
  13. "github.com/gogf/gf/os/gtime"
  14. "github.com/gogf/gf/util/gconv"
  15. "github.com/gogf/gf/util/gvalid"
  16. "github.com/xuri/excelize/v2"
  17. )
  18. type CtrContractSaleTargetService struct {
  19. Dao *dao.CtrContractSaleTargetDao
  20. Tenant string
  21. userInfo request.UserInfo
  22. DataScope g.Map `json:"dataScope"`
  23. }
  24. func NewCtrContractSaleTargetService(ctx context.Context) (*CtrContractSaleTargetService, error) {
  25. tenant, err := micro_srv.GetTenant(ctx)
  26. if err != nil {
  27. return nil, myerrors.TipsError(fmt.Sprintf("获取租户码异常:%s", err.Error())) //fmt.Errorf("获取租户码异常:%s", err.Error())
  28. }
  29. // 获取用户信息
  30. userInfo, err := micro_srv.GetUserInfo(ctx)
  31. if err != nil {
  32. return nil, myerrors.TipsError(fmt.Sprintf("获取用户信息异常:%s", err.Error())) //fmt.Errorf("获取用户信息异常:%s", err.Error())
  33. }
  34. if err != nil {
  35. return nil, err
  36. }
  37. return &CtrContractSaleTargetService{
  38. Dao: dao.NewCtrContractSaleTargetDao(tenant),
  39. Tenant: tenant,
  40. userInfo: userInfo,
  41. DataScope: userInfo.DataScope,
  42. }, nil
  43. }
  44. // List 获取列表
  45. func (s CtrContractSaleTargetService) List(ctx context.Context, req *model.SaleTargetReq) (int, []*model.CtrContractSaleTarget, error) {
  46. saleTargetDao := s.Dao.As("ctr_contract_sale_target")
  47. if req.Year != "" {
  48. saleTargetDao = saleTargetDao.Where("year = ?", req.Year)
  49. }
  50. if req.SaleName != "" {
  51. likeStr := fmt.Sprintf("%%%s%%", req.SaleName)
  52. saleTargetDao = saleTargetDao.Where("sale_name like ?", likeStr)
  53. }
  54. total, err := saleTargetDao.Count()
  55. if err != nil {
  56. return 0, nil, err
  57. }
  58. if req.PageNum != 0 {
  59. saleTargetDao = saleTargetDao.Page(req.GetPage())
  60. }
  61. orderBy := "id ASC"
  62. if req.OrderBy != "" {
  63. orderBy = req.OrderBy
  64. }
  65. saleTargetDao = saleTargetDao.Order(orderBy)
  66. results, err := saleTargetDao.FindAll()
  67. return total, results, err
  68. }
  69. // Edit 销售计划编辑(需要修改对应季度、年度计划,进而修改完成率)
  70. func (s CtrContractSaleTargetService) Edit(ctx context.Context, req *model.EditTargetReq) error {
  71. if req.Target.Id == 0 {
  72. return myerrors.TipsError("Id为空,操作失败")
  73. }
  74. // 统计 人/年度/月度金额
  75. // 第一季度
  76. req.Target.QuarterPlan1 = req.Target.Plan1 + req.Target.Plan2 + req.Target.Plan3
  77. if req.Target.QuarterPlan1 != 0 {
  78. req.Target.QuarterCompleteRatio1 = req.Target.QuarterComplete1 / req.Target.QuarterPlan1 * 100
  79. }
  80. // 第二季度
  81. req.Target.QuarterPlan2 = req.Target.Plan4 + req.Target.Plan5 + req.Target.Plan6
  82. if req.Target.QuarterPlan2 != 0 {
  83. req.Target.QuarterCompleteRatio2 = req.Target.QuarterComplete2 / req.Target.QuarterPlan2 * 100
  84. }
  85. // 第三季度
  86. req.Target.QuarterPlan3 = req.Target.Plan7 + req.Target.Plan8 + req.Target.Plan9
  87. if req.Target.QuarterPlan3 != 0 {
  88. req.Target.QuarterCompleteRatio3 = req.Target.QuarterComplete3 / req.Target.QuarterPlan3 * 100
  89. }
  90. // 年度
  91. req.Target.YearPlan = req.Target.QuarterPlan1 + req.Target.QuarterPlan2 + req.Target.QuarterPlan3 + req.Target.Plan10 + req.Target.Plan11 + req.Target.Plan12
  92. if req.Target.YearPlan != 0 {
  93. req.Target.YearCompleteRatio = req.Target.YearComplete / req.Target.YearPlan * 100
  94. }
  95. // 更新数据
  96. data := g.Map{
  97. "plan1": req.Target.Plan1,
  98. "plan2": req.Target.Plan2,
  99. "plan3": req.Target.Plan3,
  100. "plan4": req.Target.Plan4,
  101. "plan5": req.Target.Plan5,
  102. "plan6": req.Target.Plan6,
  103. "plan7": req.Target.Plan7,
  104. "plan8": req.Target.Plan8,
  105. "plan9": req.Target.Plan9,
  106. "plan10": req.Target.Plan10,
  107. "plan11": req.Target.Plan11,
  108. "plan12": req.Target.Plan12,
  109. "quarter_plan1": req.Target.QuarterPlan1,
  110. "quarter_plan2": req.Target.QuarterPlan2,
  111. "quarter_plan3": req.Target.QuarterPlan3,
  112. "year_plan": req.Target.YearPlan,
  113. "quarter_complete_ratio1": req.Target.QuarterCompleteRatio1,
  114. "quarter_complete_ratio2": req.Target.QuarterCompleteRatio2,
  115. "quarter_complete_ratio3": req.Target.QuarterCompleteRatio3,
  116. "year_complete_ratio": req.Target.YearCompleteRatio,
  117. "updated_by": s.userInfo.Id,
  118. "updated_name": s.userInfo.NickName,
  119. "updated_time": gtime.Now(),
  120. }
  121. _, err := s.Dao.Update(data, fmt.Sprintf("id='%v'", req.Target.Id))
  122. return err
  123. }
  124. // Import excel数据导入
  125. func (s CtrContractSaleTargetService) Import(ctx context.Context, req *model.ExcelImportReq) error {
  126. validErr := gvalid.CheckStruct(ctx, req, nil)
  127. if validErr != nil {
  128. return myerrors.TipsError(validErr.Current().Error())
  129. }
  130. // 下载文件
  131. buf, err := partner.DownFile(req.ExcelUrl)
  132. if err != nil {
  133. return myerrors.TipsError(fmt.Sprintf("下载 excel 异常 %s", err.Error()))
  134. }
  135. // 解析excel,构造销售目标数据
  136. saleTargets, minYear, err := s.parseExcel(buf)
  137. if err != nil {
  138. return myerrors.TipsError(fmt.Sprintf("解析 excel 异常 %s", err.Error()))
  139. }
  140. // 获取销售分成数据 人/年/月份
  141. shareMap := make(map[string]map[string]map[string]float64)
  142. var shares []*model.Share
  143. err = s.Dao.DB.Model("ctr_contract a").LeftJoin("ctr_contract_share b", "a.id=b.contract_id").Where(fmt.Sprintf("a.contract_sign_time >= '%v'", minYear)).Fields("a.contract_amount, a.incharge_id, a.incharge_name, a.contract_sign_time, b.id, b.sale_id, b.sale_name, b.share_amount").Scan(&shares)
  144. if err != nil {
  145. return err
  146. }
  147. // 统计 人/年度/月度金额
  148. for _, share := range shares {
  149. name := ""
  150. amount := float64(0)
  151. year := share.ContractSignTime.Format("Y")
  152. month := share.ContractSignTime.Format("m")
  153. if share.Id == 0 {
  154. name = share.InchargeName
  155. amount = share.ContractAmount
  156. } else {
  157. name = share.SaleName
  158. amount = share.ShareAmount
  159. }
  160. if _, ok := shareMap[name]; !ok {
  161. shareMap[name] = make(map[string]map[string]float64)
  162. }
  163. if _, ok := shareMap[name][year]; !ok {
  164. shareMap[name][year] = make(map[string]float64)
  165. }
  166. shareMap[name][year][month] += amount
  167. }
  168. // 获取用户信息
  169. saleMap := make(map[string]int)
  170. users, err := s.Dao.DB.Model("sys_user").FindAll()
  171. if err != nil {
  172. return err
  173. }
  174. for _, user := range users {
  175. saleMap[user["nick_name"].String()] = user["id"].Int()
  176. }
  177. // 获取历史销售目标信息
  178. targetMap := make(map[string]map[string]*model.CtrContractSaleTarget)
  179. targets, err := s.Dao.Where(fmt.Sprintf("year >= '%v'", minYear)).FindAll()
  180. if err != nil {
  181. return err
  182. }
  183. for index, target := range targets {
  184. if _, ok := targetMap[target.SaleName]; !ok {
  185. targetMap[target.SaleName] = make(map[string]*model.CtrContractSaleTarget)
  186. }
  187. targetMap[target.SaleName][target.Year] = targets[index]
  188. }
  189. for _, target := range saleTargets {
  190. updateTargetInfo(target, targetMap, saleMap, shareMap)
  191. }
  192. // 保存销售目标数据
  193. if len(saleTargets) > 0 {
  194. _, err = s.Dao.Save(saleTargets)
  195. }
  196. return err
  197. }
  198. // excel解构为数据
  199. func (s CtrContractSaleTargetService) parseExcel(b []byte) ([]*model.CtrContractSaleTarget, string, error) {
  200. f, err := excelize.OpenReader(bytes.NewBuffer(b))
  201. if err != nil {
  202. return nil, "", err
  203. }
  204. sheet := "销售指标"
  205. rows, err := f.GetRows(sheet)
  206. if err != nil {
  207. return nil, "", err
  208. }
  209. minYear := "9999"
  210. // 序号 销售 年度 1月计划 1月达成 2月计划 2月达成 3月计划 3月达成 第一季度计划 第一季度达成 第一季度完成率 4月计划 4月达成 5月计划 5月达成 6月计划 6月达成 第二季度计划 第二季度达成 第二季度完成率 7月计划 7月达成 8月计划 8月达成 9月计划 9月达成 第三季度计划 第三季度达成 第三季度完成率 10月计划 10月达成 11月计划 11月达成 12月计划 12月达成 年度计划 年度达成 年度完成率
  211. var saleTargets []*model.CtrContractSaleTarget
  212. for _, row := range rows[1:] {
  213. temp := &model.CtrContractSaleTarget{
  214. SaleName: row[1],
  215. Year: row[2],
  216. Plan1: gconv.Float64(row[3]),
  217. Plan2: gconv.Float64(row[5]),
  218. Plan3: gconv.Float64(row[7]),
  219. Plan4: gconv.Float64(row[12]),
  220. Plan5: gconv.Float64(row[14]),
  221. Plan6: gconv.Float64(row[16]),
  222. Plan7: gconv.Float64(row[21]),
  223. Plan8: gconv.Float64(row[23]),
  224. Plan9: gconv.Float64(row[25]),
  225. Plan10: gconv.Float64(row[30]),
  226. Plan11: gconv.Float64(row[32]),
  227. Plan12: gconv.Float64(row[34]),
  228. Remark: "",
  229. CreatedBy: s.userInfo.Id,
  230. CreatedName: s.userInfo.NickName,
  231. CreatedTime: gtime.Now(),
  232. UpdatedBy: s.userInfo.Id,
  233. UpdatedName: s.userInfo.NickName,
  234. UpdatedTime: gtime.Now(),
  235. }
  236. if temp.Year < minYear {
  237. minYear = temp.Year
  238. }
  239. temp.QuarterPlan1 = temp.Plan1 + temp.Plan2 + temp.Plan3
  240. temp.QuarterPlan2 = temp.Plan4 + temp.Plan5 + temp.Plan6
  241. temp.QuarterPlan3 = temp.Plan7 + temp.Plan8 + temp.Plan9
  242. temp.YearPlan = temp.QuarterPlan1 + temp.QuarterPlan2 + temp.QuarterPlan3 + temp.Plan10 + temp.Plan11 + temp.Plan12
  243. saleTargets = append(saleTargets, temp)
  244. }
  245. return saleTargets, minYear, nil
  246. }
  247. func updateTargetInfo(target *model.CtrContractSaleTarget, targetMap map[string]map[string]*model.CtrContractSaleTarget, saleMap map[string]int, shareMap map[string]map[string]map[string]float64) {
  248. // 有则更新
  249. if targetMap[target.SaleName] != nil && targetMap[target.SaleName][target.Year] != nil {
  250. target.Id = targetMap[target.SaleName][target.Year].Id
  251. target.CreatedBy = targetMap[target.SaleName][target.Year].CreatedBy
  252. target.CreatedName = targetMap[target.SaleName][target.Year].CreatedName
  253. target.CreatedTime = targetMap[target.SaleName][target.Year].CreatedTime
  254. } else {
  255. target.SaleId = saleMap[target.SaleName]
  256. }
  257. if shareMap[target.SaleName] != nil && shareMap[target.SaleName][target.Year] != nil {
  258. for month, amount := range shareMap[target.SaleName][target.Year] {
  259. switch month {
  260. case "01":
  261. target.Complete1 = amount
  262. break
  263. case "02":
  264. target.Complete2 = amount
  265. break
  266. case "03":
  267. target.Complete3 = amount
  268. break
  269. case "04":
  270. target.Complete4 = amount
  271. break
  272. case "05":
  273. target.Complete5 = amount
  274. break
  275. case "06":
  276. target.Complete6 = amount
  277. break
  278. case "07":
  279. target.Complete7 = amount
  280. break
  281. case "08":
  282. target.Complete8 = amount
  283. break
  284. case "09":
  285. target.Complete9 = amount
  286. break
  287. case "10":
  288. target.Complete10 = amount
  289. break
  290. case "11":
  291. target.Complete11 = amount
  292. break
  293. case "12":
  294. target.Complete12 = amount
  295. break
  296. }
  297. }
  298. }
  299. target.QuarterComplete1 = target.Complete1 + target.Complete2 + target.Complete3
  300. target.QuarterComplete2 = target.Complete4 + target.Complete5 + target.Complete6
  301. target.QuarterComplete3 = target.Complete7 + target.Complete8 + target.Complete9
  302. target.YearComplete = target.QuarterComplete1 + target.QuarterComplete2 + target.QuarterComplete3 + target.Complete10 + target.Complete11 + target.Complete12
  303. if target.QuarterPlan1 != 0 {
  304. target.QuarterCompleteRatio1 = target.QuarterComplete1 / target.QuarterPlan1 * 100
  305. }
  306. if target.QuarterPlan2 != 0 {
  307. target.QuarterCompleteRatio2 = target.QuarterComplete2 / target.QuarterPlan2 * 100
  308. }
  309. if target.QuarterPlan3 != 0 {
  310. target.QuarterCompleteRatio3 = target.QuarterComplete3 / target.QuarterPlan3 * 100
  311. }
  312. if target.YearPlan != 0 {
  313. target.YearCompleteRatio = target.YearComplete / target.YearPlan * 100
  314. }
  315. }