广告平台(站长使用)
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.
 
 
 
 
 

606 lines
25 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. "fmt"
  11. "github.com/shopspring/decimal"
  12. "time"
  13. )
  14. func GenerateWxAdData(req md.GenerateWxAdData) (err error, generateWxAdData model.GenerateWxAdData) {
  15. // 1、查找原始数据记录
  16. originalWxAdDataDb := implement.NewOriginalWxAdDataDb(db.Db)
  17. originalWxAdData, err := originalWxAdDataDb.GetOriginalWxAdData(req.OriginalDataId)
  18. if err != nil {
  19. return
  20. }
  21. if originalWxAdData == nil {
  22. err = errors.New("未查询到原始数据记录")
  23. return
  24. }
  25. // 2、查询对应媒体、代理的分成策略
  26. mediumDivisionStrategyDb := implement.NewMediumDivisionStrategyDb(db.Db)
  27. mediumDivisionStrategy, err := mediumDivisionStrategyDb.GetOriginalWxAdDataByMediumId(originalWxAdData.MediumId)
  28. if err != nil {
  29. return
  30. }
  31. if mediumDivisionStrategy == nil {
  32. err = errors.New("未查询到对应代理的分成策略")
  33. return
  34. }
  35. mediumDivisionStrategyWithAgentFlowDb := implement.NewMediumDivisionStrategyWithAgentFlowDb(db.Db)
  36. mediumDivisionStrategyWithAgentFlows, err := mediumDivisionStrategyWithAgentFlowDb.FindMediumDivisionStrategyWithAgentFlowByStrategyId(mediumDivisionStrategy.Id)
  37. if err != nil {
  38. return
  39. }
  40. // 3、计算媒体、代理收益、平台留存、佣金留存、协议分成、协议总分成
  41. publisherIncome := float64(originalWxAdData.PublisherIncome)
  42. mediaRevenue := utils.RoundToTwoDecimalPlaces(publisherIncome * float64(mediumDivisionStrategy.MediaRevenueRate) / 100) // 媒体收益
  43. agentRevenue := utils.RoundToTwoDecimalPlaces(publisherIncome * float64(mediumDivisionStrategy.AgentRevenueRate) / 100) // 代理收益
  44. platformRetention := publisherIncome * float64(mediumDivisionStrategy.PlatformRetentionRate) / 100 // 平台留存
  45. commissionRetention := publisherIncome * float64(mediumDivisionStrategy.CommissionRetentionRate) / 100 // 佣金留存
  46. agreementSharingTotal := (mediaRevenue + agentRevenue) / ((100 - float64(mediumDivisionStrategy.AgreementSharingRate)) / 100) // 协议总分成(倒推)
  47. agreementSharing := agreementSharingTotal - (mediaRevenue + agentRevenue) // 协议分成
  48. // 3、判断是否有调价留存
  49. var priceAdjustmentRetention int
  50. ecpmReq := md.ClacEcpmReq{
  51. OriginalExposureCount: originalWxAdData.ExposureCount,
  52. OriginalEcpm: originalWxAdData.Ecpm,
  53. GenerateDataId: originalWxAdData.Id,
  54. }
  55. _, ecpm := ClacEcpm(ecpmReq)
  56. fmt.Println(utils.Float64ToStr(utils.StrToFloat64(ecpm) / 100))
  57. if req.NowEcpm != utils.Float64ToStr(utils.StrToFloat64(ecpm)/100) || req.NowExposureCount != req.OriginalExposureCount {
  58. tmpMediaRevenue := int(utils.StrToFloat64(req.NowEcpm) * float64(req.NowExposureCount) / 1000)
  59. priceAdjustmentRetention = int(mediaRevenue - float64(tmpMediaRevenue))
  60. mediaRevenue = float64(tmpMediaRevenue)
  61. }
  62. // 4、计算各代理收益
  63. var extraRevenue float64
  64. var agentRevenueFlows []struct {
  65. AgentId int `json:"agent_id"`
  66. AgentRevenueRate int `json:"agent_revenue_rate"`
  67. ExtraRevenueRate int `json:"extra_revenue_rate"`
  68. AgentRevenue int `json:"agent_revenue"`
  69. ExtraRevenue int `json:"extra_revenue"`
  70. }
  71. for _, v := range *mediumDivisionStrategyWithAgentFlows {
  72. tmpAgentRevenue := utils.RoundToTwoDecimalPlaces(agentRevenue * float64(v.AgentRevenueRate) / 100)
  73. tmpExtraRevenue := commissionRetention * float64(v.ExtraRevenueRate) / 100
  74. extraRevenue += tmpExtraRevenue
  75. agentRevenueFlows = append(agentRevenueFlows, struct {
  76. AgentId int `json:"agent_id"`
  77. AgentRevenueRate int `json:"agent_revenue_rate"`
  78. ExtraRevenueRate int `json:"extra_revenue_rate"`
  79. AgentRevenue int `json:"agent_revenue"`
  80. ExtraRevenue int `json:"extra_revenue"`
  81. }{
  82. AgentId: v.AgentId,
  83. AgentRevenueRate: v.AgentRevenueRate,
  84. ExtraRevenueRate: v.ExtraRevenueRate,
  85. AgentRevenue: int(tmpAgentRevenue),
  86. ExtraRevenue: int(tmpExtraRevenue),
  87. })
  88. }
  89. // 5、插入 generate_wx_ad_data 、generate_wx_ad_data_with_agent_flow 数据
  90. session := db.Db.NewSession()
  91. defer session.Close()
  92. session.Begin()
  93. now := time.Now()
  94. generateWxAdData = model.GenerateWxAdData{
  95. MediumId: originalWxAdData.MediumId,
  96. Uuid: originalWxAdData.Uuid,
  97. AppId: originalWxAdData.AppId,
  98. PlatformAppId: originalWxAdData.PlatformAppId,
  99. OriginalDataId: originalWxAdData.Id,
  100. SlotId: originalWxAdData.SlotId,
  101. AdSlot: originalWxAdData.AdSlot,
  102. Date: originalWxAdData.Date,
  103. ReqSuccCount: originalWxAdData.ReqSuccCount,
  104. ExposureCount: req.NowExposureCount, // 现-曝光量
  105. ExposureRate: originalWxAdData.ExposureRate,
  106. ClickCount: originalWxAdData.ClickCount,
  107. ClickRate: originalWxAdData.ClickRate,
  108. Ecpm: req.NowEcpm, // 现-ecpm
  109. PlatformRetention: int(platformRetention),
  110. CommissionRetention: int(commissionRetention),
  111. PriceAdjustmentRetention: priceAdjustmentRetention,
  112. MediaRevenue: int(mediaRevenue),
  113. AgentRevenue: int(agentRevenue),
  114. ExtraRevenue: int(extraRevenue),
  115. AgreementSharing: int(agreementSharing),
  116. AgreementSharingTotal: int(agreementSharingTotal),
  117. PlatformRetentionRate: mediumDivisionStrategy.PlatformRetentionRate,
  118. CommissionRetentionRate: mediumDivisionStrategy.CommissionRetentionRate,
  119. MediaRevenueRate: mediumDivisionStrategy.MediaRevenueRate,
  120. AgentRevenueRate: mediumDivisionStrategy.AgentRevenueRate,
  121. ExtraRevenueRate: mediumDivisionStrategy.ExtraRevenueRate,
  122. AgreementSharingRate: mediumDivisionStrategy.AgreementSharingRate,
  123. IsGenerateReport: 0,
  124. CreateAt: now.Format("2006-01-02 15:04:05"),
  125. UpdateAt: now.Format("2006-01-02 15:04:05"),
  126. Platform: originalWxAdData.Platform,
  127. }
  128. generateWxAdDataDb := implement.NewGenerateWxAdDataDb(db.Db)
  129. _, err = generateWxAdDataDb.GenerateWxAdDataInsertBySession(session, &generateWxAdData)
  130. if err != nil {
  131. _ = session.Rollback()
  132. return
  133. }
  134. var generateWxAdDataWithAgentFlows []*model.GenerateWxAdDataWithAgentFlow
  135. for _, v := range agentRevenueFlows {
  136. generateWxAdDataWithAgentFlows = append(generateWxAdDataWithAgentFlows, &model.GenerateWxAdDataWithAgentFlow{
  137. Uuid: generateWxAdData.Uuid,
  138. AppId: generateWxAdData.AppId,
  139. PlatformAppId: generateWxAdData.PlatformAppId,
  140. AgentId: v.AgentId,
  141. GenerateDataId: generateWxAdData.Id,
  142. SlotId: generateWxAdData.SlotId,
  143. AdSlot: generateWxAdData.AdSlot,
  144. Date: generateWxAdData.Date,
  145. AgentRevenue: v.AgentRevenue,
  146. AgentRevenueRate: v.AgentRevenueRate,
  147. ExtraRevenue: v.ExtraRevenue,
  148. ExtraRevenueRate: v.ExtraRevenueRate,
  149. CreateAt: now.Format("2006-01-02 15:04:05"),
  150. UpdateAt: now.Format("2006-01-02 15:04:05"),
  151. })
  152. }
  153. if len(generateWxAdDataWithAgentFlows) > 0 {
  154. generateWxAdDataWithAgentFlowDb := implement.NewGenerateWxAdDataWithAgentFlowDb(db.Db)
  155. _, err = generateWxAdDataWithAgentFlowDb.BatchAddGenerateWxAdDataWithAgentFlow(session, generateWxAdDataWithAgentFlows)
  156. if err != nil {
  157. _ = session.Rollback()
  158. return
  159. }
  160. }
  161. // 6、修改 original_wx_ad_data 记录中的 is_apply(是否已应用(0:未 1:已) )
  162. originalWxAdData.IsApply = 1
  163. _, err = originalWxAdDataDb.UpdateOriginalWxAdDataBySession(session, originalWxAdData, "is_apply")
  164. if err != nil {
  165. _ = session.Rollback()
  166. return
  167. }
  168. return session.Commit(), generateWxAdData
  169. }
  170. func ClacEcpm(req md.ClacEcpmReq) (err error, ecpm string) {
  171. // 1、查找原始数据记录
  172. originalWxAdDataDb := implement.NewOriginalWxAdDataDb(db.Db)
  173. originalWxAdData, err := originalWxAdDataDb.GetOriginalWxAdData(req.GenerateDataId)
  174. if err != nil {
  175. return
  176. }
  177. if originalWxAdData == nil {
  178. err = errors.New("未查询到原始数据记录")
  179. return
  180. }
  181. // 2、查询对应媒体分成策略
  182. mediumDivisionStrategyDb := implement.NewMediumDivisionStrategyDb(db.Db)
  183. mediumDivisionStrategy, err := mediumDivisionStrategyDb.GetOriginalWxAdDataByMediumId(originalWxAdData.MediumId)
  184. if err != nil {
  185. return
  186. }
  187. if mediumDivisionStrategy == nil {
  188. err = errors.New("未查询到对应代理的分成策略")
  189. return
  190. }
  191. // 3、计算媒体、代理收益、协议总分成
  192. publisherIncome := decimal.NewFromInt(int64(originalWxAdData.PublisherIncome))
  193. mediaRevenueRate := decimal.NewFromInt(int64(mediumDivisionStrategy.MediaRevenueRate))
  194. agentRevenueRate := decimal.NewFromInt(int64(mediumDivisionStrategy.AgentRevenueRate))
  195. agreementSharingRate := decimal.NewFromInt(int64(mediumDivisionStrategy.AgreementSharingRate))
  196. exposureCount := decimal.NewFromInt(int64(originalWxAdData.ExposureCount))
  197. rateValue := decimal.NewFromInt(100)
  198. thousandRateValue := decimal.NewFromInt(1000)
  199. mediaRevenue := publisherIncome.Mul(mediaRevenueRate.Div(rateValue)) // 媒体收益
  200. agentRevenue := publisherIncome.Mul(agentRevenueRate.Div(rateValue)) // 代理收益
  201. agreementSharingTotal := mediaRevenue.Add(agentRevenue).Div(rateValue.Sub(agreementSharingRate).Div(rateValue)) // 协议总分成(倒推)
  202. fmt.Println(mediaRevenue, agentRevenue, agreementSharingRate, rateValue.Sub(agreementSharingRate), agreementSharingTotal)
  203. // 4、倒退出当前ecpm值
  204. ecpm = agreementSharingTotal.Div(exposureCount.Div(thousandRateValue)).Round(2).String()
  205. return
  206. }
  207. func SettlementWxAdData(req md.SettlementWxAdData) (err error) {
  208. // 1、查找生成数据记录
  209. generateWxAdDataDb := implement.NewGenerateWxAdDataDb(db.Db)
  210. generateWxAdData, err := generateWxAdDataDb.GetGenerateWxAdData(req.GenerateDataId)
  211. if err != nil {
  212. return
  213. }
  214. if generateWxAdData == nil {
  215. err = errors.New("未查询到生成数据记录")
  216. return
  217. }
  218. originalWxAdDataDb := implement.NewOriginalWxAdDataDb(db.Db)
  219. originalWxAdData, err := originalWxAdDataDb.GetOriginalWxAdData(generateWxAdData.OriginalDataId)
  220. if err != nil {
  221. return
  222. }
  223. if originalWxAdData == nil {
  224. err = errors.New("未查询到原始数据记录")
  225. return
  226. }
  227. // 2、查询 生成数据-代理明细 记录
  228. generateWxAdDataWithAgentFlowDb := implement.NewGenerateWxAdDataWithAgentFlowDb(db.Db)
  229. generateWxAdDataWithAgentFlow, err := generateWxAdDataWithAgentFlowDb.FindGenerateWxAdDataWithAgentFlowByStrategyId(generateWxAdData.Id)
  230. if err != nil {
  231. return
  232. }
  233. // 3、查询 媒体、代理的结算方式
  234. mediumListDb := implement.NewMediumListDb(db.Db)
  235. medium, err := mediumListDb.GetMediumList(originalWxAdData.MediumId)
  236. if err != nil {
  237. return
  238. }
  239. if medium == nil {
  240. return errors.New("媒体:" + utils.IntToStr(originalWxAdData.MediumId) + "未查询到对应记录")
  241. }
  242. var agentMap = map[int]model.AgentList{}
  243. agentListDb := implement.NewAgentListDb(db.Db)
  244. for _, v := range *generateWxAdDataWithAgentFlow {
  245. agent, err1 := agentListDb.GetAgentList(v.AgentId)
  246. if err1 != nil {
  247. return err1
  248. }
  249. if agent == nil {
  250. return errors.New("代理:" + utils.IntToStr(v.AgentId) + "未查询到对应记录")
  251. }
  252. agentMap[v.AgentId] = *agent
  253. }
  254. // 4、生成数据
  255. now := time.Now()
  256. session := db.Db.NewSession()
  257. defer session.Close()
  258. session.Begin()
  259. // 4.1 新增/更新 medium_settlement 数据
  260. mediumSettlementDb := implement.NewMediumSettlementDb(db.Db)
  261. mediumSettlement, err := mediumSettlementDb.GetMediumSettlementForAvailable(originalWxAdData.MediumId)
  262. if err != nil {
  263. return
  264. }
  265. var basicIncomeBefore, mediumSettlementState, mediumSettlementPayState int
  266. // 判断是否为预付结算类型
  267. if medium.SettlementType == enum.MediumSettlementTypeForPaymentInAdvance {
  268. mediumSettlementState = enum.MediumSettlementStateForCompleteSign
  269. mediumSettlementPayState = enum.MediumSettlementPayStateForPaymentAlready
  270. }
  271. if mediumSettlement == nil {
  272. // 新增一条数据
  273. mediumSettlement = &model.MediumSettlement{
  274. Uuid: originalWxAdData.Uuid,
  275. MediumId: originalWxAdData.MediumId,
  276. AppId: originalWxAdData.AppId,
  277. PlatformAppId: originalWxAdData.PlatformAppId,
  278. BusinessKind: 1,
  279. Kind: medium.SettlementType,
  280. BasicIncome: generateWxAdData.MediaRevenue,
  281. OtherIncome: 0,
  282. OriginalIncome: originalWxAdData.PublisherIncome,
  283. PlatformRetention: generateWxAdData.PlatformRetention,
  284. CommissionRetention: generateWxAdData.CommissionRetention,
  285. PriceAdjustmentRetention: generateWxAdData.PriceAdjustmentRetention,
  286. State: mediumSettlementState,
  287. PayState: mediumSettlementPayState,
  288. StartDate: now.Format("2006-01-02"),
  289. EndDate: "",
  290. CreateAt: now.Format("2006-01-02 15:04:05"),
  291. UpdateAt: now.Format("2006-01-02 15:04:05"),
  292. SettleFile: "",
  293. }
  294. _, err = mediumSettlementDb.MediumSettlementInsertBySession(session, mediumSettlement)
  295. if err != nil {
  296. _ = session.Rollback()
  297. return
  298. }
  299. } else {
  300. // 更新数据
  301. if medium.SettlementType != mediumSettlement.Kind {
  302. // TODO::前后结算类型不一致,之前结算单状态自动变成"核算中"
  303. mediumSettlement.State = enum.MediumSettlementStateForAccountingInProgress
  304. // mediumSettlement.PayState = mediumSettlementPayState
  305. _, err = mediumSettlementDb.UpdateMediumSettlementBySession(session, mediumSettlement, "state")
  306. if err != nil {
  307. _ = session.Rollback()
  308. return
  309. }
  310. // 新增一条数据
  311. mediumSettlement = &model.MediumSettlement{
  312. Uuid: originalWxAdData.Uuid,
  313. MediumId: originalWxAdData.MediumId,
  314. AppId: originalWxAdData.AppId,
  315. PlatformAppId: originalWxAdData.PlatformAppId,
  316. BusinessKind: 1,
  317. Kind: medium.SettlementType,
  318. BasicIncome: generateWxAdData.MediaRevenue,
  319. OtherIncome: 0,
  320. OriginalIncome: originalWxAdData.PublisherIncome,
  321. PlatformRetention: generateWxAdData.PlatformRetention,
  322. CommissionRetention: generateWxAdData.CommissionRetention,
  323. PriceAdjustmentRetention: generateWxAdData.PriceAdjustmentRetention,
  324. State: mediumSettlementState,
  325. PayState: mediumSettlementPayState,
  326. StartDate: now.Format("2006-01-02"),
  327. EndDate: "",
  328. CreateAt: now.Format("2006-01-02 15:04:05"),
  329. UpdateAt: now.Format("2006-01-02 15:04:05"),
  330. SettleFile: "",
  331. }
  332. _, err = mediumSettlementDb.MediumSettlementInsertBySession(session, mediumSettlement)
  333. if err != nil {
  334. _ = session.Rollback()
  335. return
  336. }
  337. } else {
  338. basicIncomeBefore = mediumSettlement.BasicIncome
  339. mediumSettlement.BasicIncome += generateWxAdData.MediaRevenue
  340. mediumSettlement.OriginalIncome += originalWxAdData.PublisherIncome
  341. mediumSettlement.PlatformRetention += generateWxAdData.PlatformRetention
  342. mediumSettlement.CommissionRetention += generateWxAdData.CommissionRetention
  343. mediumSettlement.PriceAdjustmentRetention += generateWxAdData.PriceAdjustmentRetention
  344. _, err = mediumSettlementDb.UpdateMediumSettlementBySession(session, mediumSettlement, "basic_income", "original_income", "platform_retention", "commission_retention", "price_adjustment_retention")
  345. if err != nil {
  346. _ = session.Rollback()
  347. return
  348. }
  349. }
  350. }
  351. if medium.SettlementType == enum.MediumSettlementTypeForPaymentInAdvance {
  352. err = DealMediumAmount(session, md.DealMediumAmount{
  353. Mid: utils.IntToStr(originalWxAdData.Uuid),
  354. Type: md.FinMediumFlowDirectionExpenditure,
  355. Kind: md.SettlementSubKindForMediumFlow,
  356. OrdId: utils.IntToStr(mediumSettlement.Id),
  357. MediumId: originalWxAdData.MediumId,
  358. Amount: float64(generateWxAdData.MediaRevenue) / 100,
  359. Memo: md.SettlementSubTitleForMediumFlow,
  360. })
  361. if err != nil {
  362. _ = session.Rollback()
  363. return
  364. }
  365. }
  366. // 4.2 新增 medium_settlement_with_flow 数据
  367. mediumSettlementWithFlowDb := implement.NewMediumSettlementWithFlowDb(db.Db)
  368. _, err = mediumSettlementWithFlowDb.MediumSettlementWithFlowInsertBySession(session, &model.MediumSettlementWithFlow{
  369. SettlementId: mediumSettlement.Id,
  370. GenerateDataId: generateWxAdData.Id,
  371. Amount: generateWxAdData.MediaRevenue,
  372. BasicIncomeBefore: basicIncomeBefore,
  373. BasicIncomeAfter: mediumSettlement.BasicIncome,
  374. OtherIncomeBefore: 0,
  375. OtherIncomeAfter: 0,
  376. Kind: enum.MediumSettlementWithFlowKindForBasicIncome,
  377. CreateAt: now.Format("2006-01-02 15:04:05"),
  378. UpdateAt: now.Format("2006-01-02 15:04:05"),
  379. })
  380. if err != nil {
  381. _ = session.Rollback()
  382. return
  383. }
  384. // 4.3 新增 agent_settlement、agent_settlement_with_flow 数据
  385. agentSettlementDb := implement.NewAgentSettlementDb(db.Db)
  386. agentSettlementWithFlowDb := implement.NewAgentSettlementWithFlowDb(db.Db)
  387. for _, v := range *generateWxAdDataWithAgentFlow {
  388. agentSettlement, err1 := agentSettlementDb.GetAgentSettlementForAvailable(v.AgentId)
  389. if err1 != nil {
  390. _ = session.Rollback()
  391. return err1
  392. }
  393. var agentBasicIncomeBefore, agentOtherIncomeBefore, agentSettlementState, agentSettlementPayState int
  394. // 判断是否为预付结算类型
  395. if agentMap[v.AgentId].SettlementType == enum.AgentSettlementTypeForPaymentInAdvance {
  396. agentSettlementState = enum.AgentSettlementStateForCompleteSign
  397. agentSettlementPayState = enum.AgentSettlementPayStateForPaymentAlready
  398. }
  399. if agentSettlement == nil {
  400. // 新增一条数据
  401. agentSettlement = &model.AgentSettlement{
  402. Uuid: v.Uuid,
  403. AgentId: v.AgentId,
  404. MediumId: originalWxAdData.MediumId,
  405. AppId: v.AppId,
  406. PlatformAppId: v.PlatformAppId,
  407. BusinessKind: 1,
  408. Kind: agentMap[v.AgentId].SettlementType,
  409. BasicIncome: v.AgentRevenue,
  410. OtherIncome: v.ExtraRevenue,
  411. State: agentSettlementState,
  412. PayState: agentSettlementPayState,
  413. StartDate: now.Format("2006-01-02"),
  414. EndDate: "",
  415. CreateAt: now.Format("2006-01-02 15:04:05"),
  416. UpdateAt: now.Format("2006-01-02 15:04:05"),
  417. }
  418. _, err = agentSettlementDb.AgentSettlementInsertBySession(session, agentSettlement)
  419. if err != nil {
  420. _ = session.Rollback()
  421. return
  422. }
  423. } else {
  424. // 更新数据
  425. if agentMap[v.AgentId].SettlementType != agentSettlement.Kind {
  426. // TODO::前后结算类型不一致,之前结算单状态自动变成"核算中"
  427. agentSettlement.State = enum.AgentSettlementStateForAccountingInProgress
  428. _, err = agentSettlementDb.UpdateAgentSettlementBySession(session, agentSettlement, "state")
  429. if err != nil {
  430. _ = session.Rollback()
  431. return
  432. }
  433. // 新增一条数据
  434. agentSettlement = &model.AgentSettlement{
  435. Uuid: v.Uuid,
  436. AgentId: v.AgentId,
  437. MediumId: originalWxAdData.MediumId,
  438. AppId: v.AppId,
  439. PlatformAppId: v.PlatformAppId,
  440. BusinessKind: 1,
  441. Kind: agentMap[v.AgentId].SettlementType,
  442. BasicIncome: v.AgentRevenue,
  443. OtherIncome: v.ExtraRevenue,
  444. State: agentSettlementState,
  445. PayState: agentSettlementPayState,
  446. StartDate: now.Format("2006-01-02"),
  447. EndDate: "",
  448. CreateAt: now.Format("2006-01-02 15:04:05"),
  449. UpdateAt: now.Format("2006-01-02 15:04:05"),
  450. }
  451. _, err = agentSettlementDb.AgentSettlementInsertBySession(session, agentSettlement)
  452. if err != nil {
  453. _ = session.Rollback()
  454. return
  455. }
  456. } else {
  457. agentBasicIncomeBefore = agentSettlement.BasicIncome
  458. agentOtherIncomeBefore = agentSettlement.OtherIncome
  459. agentSettlement.BasicIncome += v.AgentRevenue
  460. agentSettlement.OtherIncome += v.ExtraRevenue
  461. _, err = agentSettlementDb.UpdateAgentSettlementBySession(session, agentSettlement, "basic_income", "other_income")
  462. if err != nil {
  463. _ = session.Rollback()
  464. return
  465. }
  466. }
  467. }
  468. if agentMap[v.AgentId].SettlementType == enum.AgentSettlementTypeForPaymentInAdvance {
  469. err = DealAgentAmount(session, md.DealAgentAmount{
  470. Mid: utils.IntToStr(originalWxAdData.Uuid),
  471. Type: md.FinAgentFlowDirectionExpenditure,
  472. Kind: md.SettlementSubKindForAgentFlow,
  473. OrdId: utils.IntToStr(v.Id),
  474. Amount: float64(v.AgentRevenue)/100 + float64(v.ExtraRevenue)/100,
  475. Memo: md.SettlementSubTitleForMediumFlow,
  476. })
  477. if err != nil {
  478. _ = session.Rollback()
  479. return
  480. }
  481. }
  482. _, err = agentSettlementWithFlowDb.AgentSettlementWithFlowInsertBySession(session, &model.AgentSettlementWithFlow{
  483. SettlementId: mediumSettlement.Id,
  484. GenerateDataId: generateWxAdData.Id,
  485. Amount: v.AgentRevenue,
  486. BasicIncomeBefore: agentBasicIncomeBefore,
  487. BasicIncomeAfter: agentSettlement.BasicIncome,
  488. OtherIncomeBefore: agentOtherIncomeBefore,
  489. OtherIncomeAfter: agentSettlement.OtherIncome,
  490. Kind: enum.AgentSettlementWithFlowKindForBasicIncome,
  491. CreateAt: now.Format("2006-01-02 15:04:05"),
  492. UpdateAt: now.Format("2006-01-02 15:04:05"),
  493. })
  494. if err != nil {
  495. _ = session.Rollback()
  496. return
  497. }
  498. }
  499. // 4、修改 generate_wx_ad_data 记录中的 is_generate_report (是否已应用(0:未 1:已) )
  500. generateWxAdData.IsGenerateReport = 1
  501. _, err = generateWxAdDataDb.UpdateGenerateWxAdDataBySession(session, generateWxAdData, "is_generate_report")
  502. if err != nil {
  503. _ = session.Rollback()
  504. return
  505. }
  506. return session.Commit()
  507. }
  508. func CalcApplicationData(req md.CalcApplicationDataReq) (err error, resp md.CalcApplicationDataResp) {
  509. // 1、查找原始数据记录
  510. originalWxAdDataDb := implement.NewOriginalWxAdDataDb(db.Db)
  511. originalWxAdData, err := originalWxAdDataDb.GetOriginalWxAdData(req.OriginalDataId)
  512. if err != nil {
  513. return
  514. }
  515. if originalWxAdData == nil {
  516. err = errors.New("未查询到原始数据记录")
  517. return
  518. }
  519. // 2、查询对应媒体、代理的分成策略
  520. mediumDivisionStrategyDb := implement.NewMediumDivisionStrategyDb(db.Db)
  521. mediumDivisionStrategy, err := mediumDivisionStrategyDb.GetOriginalWxAdDataByMediumId(originalWxAdData.MediumId)
  522. if err != nil {
  523. return
  524. }
  525. if mediumDivisionStrategy == nil {
  526. err = errors.New("未查询到对应代理的分成策略")
  527. return
  528. }
  529. mediumDivisionStrategyWithAgentFlowDb := implement.NewMediumDivisionStrategyWithAgentFlowDb(db.Db)
  530. mediumDivisionStrategyWithAgentFlows, err := mediumDivisionStrategyWithAgentFlowDb.FindMediumDivisionStrategyWithAgentFlowByStrategyId(mediumDivisionStrategy.Id)
  531. if err != nil {
  532. return
  533. }
  534. // 3、计算媒体、代理收益、平台留存、佣金留存、协议分成、协议总分成
  535. publisherIncome := float64(originalWxAdData.PublisherIncome)
  536. mediaRevenue := publisherIncome * float64(mediumDivisionStrategy.MediaRevenueRate) / 100 // 媒体收益
  537. agentRevenue := publisherIncome * float64(mediumDivisionStrategy.AgentRevenueRate) / 100 // 代理收益
  538. platformRetention := publisherIncome * float64(mediumDivisionStrategy.PlatformRetentionRate) / 100 // 平台留存
  539. commissionRetention := publisherIncome * float64(mediumDivisionStrategy.CommissionRetentionRate) / 100 // 佣金留存
  540. agreementSharingTotal := (mediaRevenue + agentRevenue) / ((100 - float64(mediumDivisionStrategy.AgreementSharingRate)) / 100) // 协议总分成(倒推)
  541. agreementSharing := agreementSharingTotal - (mediaRevenue + agentRevenue) // 协议分成
  542. // 3、判断是否有调价留存
  543. ecpmReq := md.ClacEcpmReq{
  544. OriginalExposureCount: originalWxAdData.ExposureCount,
  545. OriginalEcpm: originalWxAdData.Ecpm,
  546. GenerateDataId: originalWxAdData.Id,
  547. }
  548. _, ecpm := ClacEcpm(ecpmReq)
  549. fmt.Println(utils.Float64ToStr(utils.StrToFloat64(ecpm) / 100))
  550. if req.NowEcpm != utils.Float64ToStr(utils.StrToFloat64(ecpm)/100) || req.NowExposureCount != req.OriginalExposureCount {
  551. tmpMediaRevenue := int(utils.StrToFloat64(req.NowEcpm) * float64(req.NowExposureCount) / 1000)
  552. mediaRevenue = float64(tmpMediaRevenue)
  553. }
  554. // 4、计算各代理收益
  555. var extraRevenue float64
  556. for _, v := range *mediumDivisionStrategyWithAgentFlows {
  557. tmpExtraRevenue := commissionRetention * float64(v.ExtraRevenueRate) / 100
  558. extraRevenue += tmpExtraRevenue
  559. }
  560. resp = md.CalcApplicationDataResp{
  561. PlatformRetention: platformRetention,
  562. CommissionRetention: commissionRetention,
  563. MediaRevenue: mediaRevenue,
  564. AgentRevenue: agentRevenue,
  565. ExtraRevenue: extraRevenue,
  566. AgreementSharing: agreementSharing,
  567. }
  568. return
  569. }