广告平台(站长使用)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

435 lines
17 KiB

  1. package svc
  2. import (
  3. "applet/app/enum"
  4. "applet/app/md"
  5. "applet/app/utils"
  6. db "code.fnuoos.com/zhimeng/model.git/src"
  7. "code.fnuoos.com/zhimeng/model.git/src/super/implement"
  8. "code.fnuoos.com/zhimeng/model.git/src/super/model"
  9. "errors"
  10. "time"
  11. )
  12. func GenerateWxAdData(req md.GenerateWxAdData) (err error, generateWxAdData model.GenerateWxAdData) {
  13. //1、查找原始数据记录
  14. originalWxAdDataDb := implement.NewOriginalWxAdDataDb(db.Db)
  15. originalWxAdData, err := originalWxAdDataDb.GetOriginalWxAdData(req.OriginalDataId)
  16. if err != nil {
  17. return
  18. }
  19. if originalWxAdData == nil {
  20. err = errors.New("未查询到原始数据记录")
  21. return
  22. }
  23. //2、查询对应媒体、代理的分成策略
  24. mediumDivisionStrategyDb := implement.NewMediumDivisionStrategyDb(db.Db)
  25. mediumDivisionStrategy, err := mediumDivisionStrategyDb.GetOriginalWxAdDataByMediumId(originalWxAdData.MediumId)
  26. if err != nil {
  27. return
  28. }
  29. if mediumDivisionStrategy == nil {
  30. err = errors.New("未查询到对应代理的分成策略")
  31. return
  32. }
  33. mediumDivisionStrategyWithAgentFlowDb := implement.NewMediumDivisionStrategyWithAgentFlowDb(db.Db)
  34. mediumDivisionStrategyWithAgentFlows, err := mediumDivisionStrategyWithAgentFlowDb.FindMediumDivisionStrategyWithAgentFlowByStrategyId(mediumDivisionStrategy.MediumId)
  35. if err != nil {
  36. return
  37. }
  38. //3、计算媒体、代理收益、平台留存、佣金留存、协议分成、协议总分成
  39. publisherIncome := originalWxAdData.PublisherIncome
  40. mediaRevenue := publisherIncome * mediumDivisionStrategy.MediaRevenueRate / 100 //媒体收益
  41. agentRevenue := publisherIncome * mediumDivisionStrategy.AgentRevenueRate / 100 //代理收益
  42. platformRetention := publisherIncome * mediumDivisionStrategy.PlatformRetentionRate / 100 //平台留存
  43. commissionRetention := publisherIncome * mediumDivisionStrategy.CommissionRetentionRate / 100 //佣金留存
  44. agreementSharingTotal := (mediaRevenue + agentRevenue) / (100 - mediumDivisionStrategy.AgreementSharingRate) //协议总分成(倒推)
  45. agreementSharing := agreementSharingTotal - (mediaRevenue + agentRevenue) //协议分成
  46. //3、判断是否有调价留存
  47. var priceAdjustmentRetention int
  48. if req.NowEcpm != req.OriginalEcpm || req.NowExposureCount != req.OriginalExposureCount {
  49. tmpMediaRevenue := int(utils.StrToFloat64(req.NowEcpm) * float64(req.NowExposureCount) / 1000)
  50. priceAdjustmentRetention = tmpMediaRevenue - mediaRevenue
  51. mediaRevenue = tmpMediaRevenue
  52. }
  53. //4、计算各代理收益
  54. var extraRevenue int
  55. var agentRevenueFlows []struct {
  56. AgentId int `json:"agent_id"`
  57. AgentRevenueRate int `json:"agent_revenue_rate"`
  58. ExtraRevenueRate int `json:"extra_revenue_rate"`
  59. AgentRevenue int `json:"agent_revenue"`
  60. ExtraRevenue int `json:"extra_revenue"`
  61. }
  62. for _, v := range *mediumDivisionStrategyWithAgentFlows {
  63. tmpAgentRevenue := agentRevenue * v.AgentRevenueRate / 100
  64. tmpExtraRevenue := commissionRetention * v.ExtraRevenueRate / 100
  65. extraRevenue += tmpExtraRevenue
  66. agentRevenueFlows = append(agentRevenueFlows, struct {
  67. AgentId int `json:"agent_id"`
  68. AgentRevenueRate int `json:"agent_revenue_rate"`
  69. ExtraRevenueRate int `json:"extra_revenue_rate"`
  70. AgentRevenue int `json:"agent_revenue"`
  71. ExtraRevenue int `json:"extra_revenue"`
  72. }{
  73. AgentId: v.AgentId,
  74. AgentRevenueRate: v.AgentRevenueRate,
  75. ExtraRevenueRate: v.ExtraRevenueRate,
  76. AgentRevenue: tmpAgentRevenue,
  77. ExtraRevenue: tmpExtraRevenue,
  78. })
  79. }
  80. //5、插入 generate_wx_ad_data 、generate_wx_ad_data_with_agent_flow 数据
  81. session := db.Db.NewSession()
  82. defer session.Close()
  83. session.Begin()
  84. now := time.Now()
  85. generateWxAdData = model.GenerateWxAdData{
  86. Uuid: originalWxAdData.Uuid,
  87. Platform: originalWxAdData.Platform,
  88. AppId: originalWxAdData.AppId,
  89. OriginalDataId: originalWxAdData.Id,
  90. SlotId: originalWxAdData.SlotId,
  91. AdSlot: originalWxAdData.AdSlot,
  92. Date: originalWxAdData.Date,
  93. ReqSuccCount: originalWxAdData.ReqSuccCount,
  94. ExposureCount: req.NowExposureCount, //现-曝光量
  95. ExposureRate: originalWxAdData.ExposureRate,
  96. ClickCount: originalWxAdData.ClickCount,
  97. ClickRate: originalWxAdData.ClickRate,
  98. Ecpm: req.NowEcpm, //现-ecpm
  99. PlatformRetention: platformRetention,
  100. CommissionRetention: commissionRetention,
  101. PriceAdjustmentRetention: priceAdjustmentRetention,
  102. MediaRevenue: mediaRevenue,
  103. AgentRevenue: agentRevenue,
  104. ExtraRevenue: extraRevenue,
  105. AgreementSharing: agreementSharing,
  106. AgreementSharingTotal: agreementSharingTotal,
  107. PlatformRetentionRate: mediumDivisionStrategy.PlatformRetentionRate,
  108. CommissionRetentionRate: mediumDivisionStrategy.CommissionRetentionRate,
  109. MediaRevenueRate: mediumDivisionStrategy.MediaRevenueRate,
  110. AgentRevenueRate: mediumDivisionStrategy.AgentRevenueRate,
  111. ExtraRevenueRate: mediumDivisionStrategy.ExtraRevenueRate,
  112. AgreementSharingRate: mediumDivisionStrategy.AgreementSharingRate,
  113. IsGenerateReport: 0,
  114. CreateAt: now.Format("2006-01-02 15:04:05"),
  115. UpdateAt: now.Format("2006-01-02 15:04:05"),
  116. }
  117. generateWxAdDataDb := implement.NewGenerateWxAdDataDb(db.Db)
  118. _, err = generateWxAdDataDb.GenerateWxAdDataInsertBySession(session, &generateWxAdData)
  119. if err != nil {
  120. _ = session.Rollback()
  121. return
  122. }
  123. var generateWxAdDataWithAgentFlows []*model.GenerateWxAdDataWithAgentFlow
  124. for _, v := range agentRevenueFlows {
  125. generateWxAdDataWithAgentFlows = append(generateWxAdDataWithAgentFlows, &model.GenerateWxAdDataWithAgentFlow{
  126. Uuid: generateWxAdData.Uuid,
  127. AppId: generateWxAdData.AppId,
  128. AgentId: v.AgentId,
  129. GenerateDataId: generateWxAdData.Id,
  130. SlotId: generateWxAdData.SlotId,
  131. AdSlot: generateWxAdData.AdSlot,
  132. Date: generateWxAdData.Date,
  133. AgentRevenue: v.AgentRevenue,
  134. AgentRevenueRate: v.AgentRevenueRate,
  135. ExtraRevenue: v.ExtraRevenue,
  136. ExtraRevenueRate: v.ExtraRevenueRate,
  137. CreateAt: now.Format("2006-01-02 15:04:05"),
  138. UpdateAt: now.Format("2006-01-02 15:04:05"),
  139. })
  140. }
  141. generateWxAdDataWithAgentFlowDb := implement.NewGenerateWxAdDataWithAgentFlowDb(db.Db)
  142. _, err = generateWxAdDataWithAgentFlowDb.BatchAddGenerateWxAdDataWithAgentFlow(session, generateWxAdDataWithAgentFlows)
  143. if err != nil {
  144. _ = session.Rollback()
  145. return
  146. }
  147. //6、修改 original_wx_ad_data 记录中的 is_apply(是否已应用(0:未 1:已) )
  148. originalWxAdData.IsApply = 1
  149. _, err = originalWxAdDataDb.UpdateOriginalWxAdDataBySession(session, originalWxAdData, "is_apply")
  150. if err != nil {
  151. _ = session.Rollback()
  152. return
  153. }
  154. return session.Commit(), generateWxAdData
  155. }
  156. func ClacEcpm(req md.ClacEcpmReq) (err error, ecpm string) {
  157. //1、查找原始数据记录
  158. originalWxAdDataDb := implement.NewOriginalWxAdDataDb(db.Db)
  159. originalWxAdData, err := originalWxAdDataDb.GetOriginalWxAdData(req.GenerateDataId)
  160. if err != nil {
  161. return
  162. }
  163. if originalWxAdData == nil {
  164. err = errors.New("未查询到原始数据记录")
  165. return
  166. }
  167. //2、查询对应媒体分成策略
  168. mediumDivisionStrategyDb := implement.NewMediumDivisionStrategyDb(db.Db)
  169. mediumDivisionStrategy, err := mediumDivisionStrategyDb.GetOriginalWxAdDataByMediumId(originalWxAdData.MediumId)
  170. if err != nil {
  171. return
  172. }
  173. if mediumDivisionStrategy == nil {
  174. err = errors.New("未查询到对应代理的分成策略")
  175. return
  176. }
  177. //3、计算媒体、代理收益、协议总分成
  178. publisherIncome := originalWxAdData.PublisherIncome
  179. mediaRevenue := publisherIncome * mediumDivisionStrategy.MediaRevenueRate / 100 //媒体收益
  180. agentRevenue := publisherIncome * mediumDivisionStrategy.AgentRevenueRate / 100 //代理收益
  181. agreementSharingTotal := (mediaRevenue + agentRevenue) / (100 - mediumDivisionStrategy.AgreementSharingRate) //协议总分成(倒推)
  182. //4、倒退出当前ecpm值
  183. ecpm = utils.Float64ToStrPrec4(float64(agreementSharingTotal) / (float64(originalWxAdData.ExposureCount) / 1000))
  184. return
  185. }
  186. func SettlementWxAdData(req md.SettlementWxAdData) (err error) {
  187. //1、查找生成数据记录
  188. generateWxAdDataDb := implement.NewGenerateWxAdDataDb(db.Db)
  189. generateWxAdData, err := generateWxAdDataDb.GetGenerateWxAdData(req.GenerateDataId)
  190. if err != nil {
  191. return
  192. }
  193. if generateWxAdData == nil {
  194. err = errors.New("未查询到生成数据记录")
  195. return
  196. }
  197. originalWxAdDataDb := implement.NewOriginalWxAdDataDb(db.Db)
  198. originalWxAdData, err := originalWxAdDataDb.GetOriginalWxAdData(generateWxAdData.OriginalDataId)
  199. if err != nil {
  200. return
  201. }
  202. if originalWxAdData == nil {
  203. err = errors.New("未查询到原始数据记录")
  204. return
  205. }
  206. //2、查询 生成数据-代理明细 记录
  207. generateWxAdDataWithAgentFlowDb := implement.NewGenerateWxAdDataWithAgentFlowDb(db.Db)
  208. generateWxAdDataWithAgentFlow, err := generateWxAdDataWithAgentFlowDb.FindGenerateWxAdDataWithAgentFlowByStrategyId(generateWxAdData.Id)
  209. if err != nil {
  210. return
  211. }
  212. //3、查询 媒体、代理的结算方式
  213. mediumListDb := implement.NewMediumListDb(db.Db)
  214. medium, err := mediumListDb.GetMediumList(originalWxAdData.MediumId)
  215. if err != nil {
  216. return
  217. }
  218. if medium == nil {
  219. return errors.New("媒体:" + utils.IntToStr(originalWxAdData.MediumId) + "未查询到对应记录")
  220. }
  221. var agentMap = map[int]model.AgentList{}
  222. agentListDb := implement.NewAgentListDb(db.Db)
  223. for _, v := range *generateWxAdDataWithAgentFlow {
  224. agent, err1 := agentListDb.GetAgentList(v.AgentId)
  225. if err1 != nil {
  226. return err1
  227. }
  228. if agent == nil {
  229. return errors.New("代理:" + utils.IntToStr(v.AgentId) + "未查询到对应记录")
  230. }
  231. agentMap[v.AgentId] = *agent
  232. }
  233. //4、生成数据
  234. now := time.Now()
  235. session := db.Db.NewSession()
  236. defer session.Close()
  237. session.Begin()
  238. //4.1 新增/更新 medium_settlement 数据
  239. mediumSettlementDb := implement.NewMediumSettlementDb(db.Db)
  240. mediumSettlement, err := mediumSettlementDb.GetMediumSettlementForAvailable(originalWxAdData.MediumId)
  241. if err != nil {
  242. return
  243. }
  244. var basicIncomeBefore, mediumSettlementState, mediumSettlementPayState int
  245. //判断是否为预付结算类型
  246. if medium.SettlementType == enum.MediumSettlementTypeForPaymentInAdvance {
  247. mediumSettlementState = enum.MediumSettlementStateForCompleteSign
  248. mediumSettlementPayState = enum.MediumSettlementPayStateForPaymentAlready
  249. }
  250. if mediumSettlement == nil {
  251. //新增一条数据
  252. mediumSettlement = &model.MediumSettlement{
  253. Uuid: originalWxAdData.Uuid,
  254. MediumId: originalWxAdData.MediumId,
  255. AppId: originalWxAdData.AppId,
  256. BusinessKind: 1,
  257. Kind: medium.SettlementType,
  258. BasicIncome: generateWxAdData.MediaRevenue,
  259. OtherIncome: 0,
  260. State: mediumSettlementState,
  261. PayState: mediumSettlementPayState,
  262. StartDate: now.Format("2006-01-02"),
  263. EndDate: "",
  264. CreateAt: now.Format("2006-01-02 15:04:05"),
  265. UpdateAt: now.Format("2006-01-02 15:04:05"),
  266. }
  267. _, err = mediumSettlementDb.MediumSettlementInsertBySession(session, mediumSettlement)
  268. if err != nil {
  269. _ = session.Rollback()
  270. return
  271. }
  272. } else {
  273. //更新数据
  274. basicIncomeBefore = mediumSettlement.BasicIncome
  275. mediumSettlement.BasicIncome += generateWxAdData.MediaRevenue
  276. mediumSettlement.State = mediumSettlementState
  277. mediumSettlement.PayState = mediumSettlementPayState
  278. _, err = mediumSettlementDb.UpdateMediumSettlementBySession(session, mediumSettlement, "basic_income", "pay_state", "state")
  279. if err != nil {
  280. _ = session.Rollback()
  281. return
  282. }
  283. }
  284. if medium.SettlementType == enum.MediumSettlementTypeForPaymentInAdvance {
  285. err = DealMediumAmount(session, md.DealMediumAmount{
  286. Mid: utils.IntToStr(originalWxAdData.Uuid),
  287. Type: md.FinMediumFlowDirectionExpenditure,
  288. Kind: md.SettlementSubKindForMediumFlow,
  289. OrdId: utils.IntToStr(mediumSettlement.Id),
  290. MediumId: originalWxAdData.MediumId,
  291. Amount: float64(generateWxAdData.MediaRevenue) / 100,
  292. Memo: md.SettlementSubTitleForMediumFlow,
  293. })
  294. if err != nil {
  295. _ = session.Rollback()
  296. return
  297. }
  298. }
  299. //4.2 新增 medium_settlement_with_flow 数据
  300. mediumSettlementWithFlowDb := implement.NewMediumSettlementWithFlowDb(db.Db)
  301. _, err = mediumSettlementWithFlowDb.MediumSettlementWithFlowInsertBySession(session, &model.MediumSettlementWithFlow{
  302. SettlementId: mediumSettlement.Id,
  303. GenerateDataId: generateWxAdData.Id,
  304. Amount: generateWxAdData.MediaRevenue,
  305. BasicIncomeBefore: basicIncomeBefore,
  306. BasicIncomeAfter: mediumSettlement.BasicIncome,
  307. OtherIncomeBefore: 0,
  308. OtherIncomeAfter: 0,
  309. Kind: enum.MediumSettlementWithFlowKindForBasicIncome,
  310. CreateAt: now.Format("2006-01-02 15:04:05"),
  311. UpdateAt: now.Format("2006-01-02 15:04:05"),
  312. })
  313. if err != nil {
  314. _ = session.Rollback()
  315. return
  316. }
  317. //4.3 新增 agent_settlement、agent_settlement_with_flow 数据
  318. agentSettlementDb := implement.NewAgentSettlementDb(db.Db)
  319. agentSettlementWithFlowDb := implement.NewAgentSettlementWithFlowDb(db.Db)
  320. for _, v := range *generateWxAdDataWithAgentFlow {
  321. agentSettlement, err1 := agentSettlementDb.GetAgentSettlementForAvailable(v.AgentId)
  322. if err1 != nil {
  323. _ = session.Rollback()
  324. return err1
  325. }
  326. var agentBasicIncomeBefore, agentOtherIncomeBefore, agentSettlementState, agentSettlementPayState int
  327. //判断是否为预付结算类型
  328. if agentMap[v.AgentId].SettlementType == enum.AgentSettlementTypeForPaymentInAdvance {
  329. agentSettlementState = enum.AgentSettlementStateForCompleteSign
  330. agentSettlementPayState = enum.AgentSettlementPayStateForPaymentAlready
  331. }
  332. if agentSettlement == nil {
  333. //新增一条数据
  334. agentSettlement = &model.AgentSettlement{
  335. Uuid: v.Uuid,
  336. AgentId: v.AgentId,
  337. MediumId: originalWxAdData.MediumId,
  338. AppId: v.AppId,
  339. BusinessKind: 1,
  340. Kind: agentMap[v.AgentId].SettlementType,
  341. BasicIncome: v.AgentRevenue,
  342. OtherIncome: v.ExtraRevenue,
  343. State: agentSettlementState,
  344. PayState: agentSettlementPayState,
  345. StartDate: now.Format("2006-01-02"),
  346. EndDate: "",
  347. CreateAt: now.Format("2006-01-02 15:04:05"),
  348. UpdateAt: now.Format("2006-01-02 15:04:05"),
  349. }
  350. _, err = agentSettlementDb.AgentSettlementInsertBySession(session, agentSettlement)
  351. if err != nil {
  352. _ = session.Rollback()
  353. return
  354. }
  355. } else {
  356. //更新数据
  357. agentBasicIncomeBefore = agentSettlement.BasicIncome
  358. agentOtherIncomeBefore = agentSettlement.OtherIncome
  359. agentSettlement.BasicIncome += v.AgentRevenue
  360. agentSettlement.OtherIncome += v.ExtraRevenue
  361. agentSettlement.State += agentSettlementState
  362. agentSettlement.PayState += agentSettlementPayState
  363. _, err = agentSettlementDb.UpdateAgentSettlementBySession(session, agentSettlement, "basic_income", "other_income", "pay_state", "state")
  364. if err != nil {
  365. _ = session.Rollback()
  366. return
  367. }
  368. }
  369. if agentMap[v.AgentId].SettlementType == enum.AgentSettlementTypeForPaymentInAdvance {
  370. err = DealAgentAmount(session, md.DealAgentAmount{
  371. Mid: utils.IntToStr(originalWxAdData.Uuid),
  372. Type: md.FinAgentFlowDirectionExpenditure,
  373. Kind: md.SettlementSubKindForAgentFlow,
  374. OrdId: utils.IntToStr(v.Id),
  375. Amount: float64(v.AgentRevenue)/100 + float64(v.ExtraRevenue)/100,
  376. Memo: md.SettlementSubTitleForMediumFlow,
  377. })
  378. if err != nil {
  379. _ = session.Rollback()
  380. return
  381. }
  382. }
  383. _, err = agentSettlementWithFlowDb.AgentSettlementWithFlowInsertBySession(session, &model.AgentSettlementWithFlow{
  384. SettlementId: mediumSettlement.Id,
  385. GenerateDataId: generateWxAdData.Id,
  386. Amount: v.AgentRevenue,
  387. BasicIncomeBefore: agentBasicIncomeBefore,
  388. BasicIncomeAfter: agentSettlement.BasicIncome,
  389. OtherIncomeBefore: agentOtherIncomeBefore,
  390. OtherIncomeAfter: agentSettlement.OtherIncome,
  391. Kind: enum.AgentSettlementWithFlowKindForBasicIncome,
  392. CreateAt: now.Format("2006-01-02 15:04:05"),
  393. UpdateAt: now.Format("2006-01-02 15:04:05"),
  394. })
  395. if err != nil {
  396. _ = session.Rollback()
  397. return
  398. }
  399. }
  400. //4、修改 generate_wx_ad_data 记录中的 is_generate_report (是否已应用(0:未 1:已) )
  401. generateWxAdData.IsGenerateReport = 1
  402. _, err = generateWxAdDataDb.UpdateGenerateWxAdDataBySession(session, generateWxAdData, "is_generate_report")
  403. if err != nil {
  404. _ = session.Rollback()
  405. return
  406. }
  407. return session.Commit()
  408. }