AgentPeriodReportTest.php 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. <?php
  2. namespace Tests\Integration;
  3. use App\Http\Controllers\agent\MemberController;
  4. use App\Http\Controllers\agent\ReportController;
  5. use App\Models\Agent\Agent;
  6. use App\Services\Agent\AgentPeriodReportService;
  7. use App\Services\MemberDailyReportService;
  8. use Illuminate\Database\Schema\Blueprint;
  9. use Illuminate\Http\Request;
  10. use Illuminate\Support\Facades\DB;
  11. use Illuminate\Support\Facades\Schema;
  12. use PHPUnit\Framework\TestCase;
  13. use Tests\Support\AgentTestEnvironment;
  14. /** 代理周期报表 GET /agent/reports/period(按日/周/月),入股代理不能看会员明细。今天是 2026-09-07(周一)。 */
  15. class AgentPeriodReportTest extends TestCase
  16. {
  17. use AgentTestEnvironment;
  18. private Agent $joint;
  19. private Agent $equity;
  20. private function seed(): void
  21. {
  22. if (!Schema::hasColumn('users', 'from')) Schema::table('users', fn (Blueprint $t) => $t->integer('from')->nullable());
  23. $this->joint = $this->agent();
  24. $this->equity = $this->agent(Agent::TYPE_EQUITY);
  25. $ids = [];
  26. foreach (['m1' => [$this->joint->id, 1, '2026-09-01 08:00:00'], 'm2' => [null, 1, '2026-09-02 08:00:00'],
  27. 'demo' => [null, 2, '2026-09-02 09:00:00']] as $memberId => [$agentId, $from, $at]) {
  28. $ids[$memberId] = DB::table('users')->insertGetId(['member_id' => $memberId, 'username' => $memberId,
  29. 'agent_id' => $agentId, 'from' => $from, 'created_at' => $at]);
  30. }
  31. foreach ([['m1', '2026-09-01', 100, 2, -50, 5], ['m1', '2026-09-07', 50, 1, 10, 0], ['m2', '2026-09-02', 200, 3, 20, 0],
  32. ['m2', '2026-09-03', 0, 1, 0, 0], ['demo', '2026-09-02', 999, 9, 0, 0]] as [$m, $date, $deposit, $bets, $winLoss, $share]) {
  33. DB::table('member_daily_reports')->insert(['report_date' => $date, 'user_id' => $ids[$m], 'member_id' => $m,
  34. 'agent_id' => $m === 'm1' ? $this->joint->id : null, 'deposit_amount' => $deposit, 'bonus_amount' => $m === 'm2' && $date === '2026-09-02' ? 10 : 0,
  35. 'bet_count' => $bets, 'bet_amount' => $bets * 10, 'win_loss' => $winLoss, 'agent_share' => $share,
  36. 'categories' => '{}', 'created_at' => now(), 'updated_at' => '2026-09-07 11:50:00']);
  37. }
  38. DB::table('share_bet_facts')->insert(['source' => 't', 'source_id' => '1', 'user_id' => $ids['m2'], 'member_id' => 'm2',
  39. 'category' => 'self:lottery', 'bet_at' => '2026-09-02 10:00:00', 'bet_date' => '2026-09-02', 'settled_at' => '2026-09-02 10:05:00',
  40. 'bet_amount' => 30, 'effective_amount' => 30, 'net_profit' => 20, 'settled' => 1, 'voided' => 0]);
  41. }
  42. public function test_equity_shareholder_gets_platform_totals_by_week_without_demo_accounts(): void
  43. {
  44. $this->seed();
  45. $report = (new AgentPeriodReportService())->report($this->equity, ['period' => 'week', 'start_date' => '2026-08-31', 'end_date' => '2026-09-07']);
  46. $this->assertSame(['platform', 'week', '2026-09-07 11:50:00'], [$report['scope'], $report['period'], $report['refreshed_at']]);
  47. $this->assertSame(['2026-W37', '2026-W36'], array_column($report['list'], 'period_key'), 'newest period first');
  48. [$current, $previous] = $report['list'];
  49. $this->assertSame(['2026-09-07', '2026-09-07', '09-07 ~ 09-07'], [$current['start_date'], $current['end_date'], $current['label']]);
  50. $this->assertSame(['2026-08-31', '2026-09-06'], [$previous['start_date'], $previous['end_date']]);
  51. $this->assertSame(['300.0000', 6, 2, 2], [$previous['deposit_amount'], $previous['bet_count'], $previous['active_members'], $previous['new_members']],
  52. 'demo account excluded; m2 bet on two days but counts once');
  53. $this->assertSame('290.0000', $previous['company_profit'], '300 deposit - 10 bonus');
  54. $this->assertSame([['category' => 'self:lottery', 'name' => $previous['categories'][0]['name'], 'bet_count' => 1,
  55. 'bet_amount' => '30.0000', 'valid_bet_amount' => '30.0000', 'win_loss' => '20.0000']], $previous['categories']);
  56. $this->assertSame(['50.0000', 1], [$current['deposit_amount'], $current['active_members']]);
  57. $this->assertSame(['350.0000', 2, 7], [$report['totals']['deposit_amount'], $report['totals']['active_members'], $report['totals']['bet_count']]);
  58. $this->assertArrayNotHasKey('agent_share', $report['totals'], 'shareholders do not see joint-venture share');
  59. }
  60. public function test_joint_agent_sees_own_members_by_day_and_month_with_share(): void
  61. {
  62. $this->seed();
  63. $service = new AgentPeriodReportService();
  64. $days = $service->report($this->joint, ['period' => 'day', 'start_date' => '2026-09-01', 'end_date' => '2026-09-02']);
  65. $this->assertSame('own', $days['scope']);
  66. $this->assertSame(['2026-09-02', '2026-09-01'], array_column($days['list'], 'period_key'), 'empty days are still listed');
  67. $this->assertSame(['0.0000', 0], [$days['list'][0]['deposit_amount'], $days['list'][0]['new_members']]);
  68. $this->assertSame(['100.0000', '-50.0000', '5.0000', 1, 1], [$days['list'][1]['deposit_amount'], $days['list'][1]['win_loss'],
  69. $days['list'][1]['agent_share'], $days['list'][1]['active_members'], $days['list'][1]['new_members']]);
  70. $months = $service->report($this->joint, ['period' => 'month', 'start_date' => '2026-08-15', 'end_date' => '2026-09-07']);
  71. $this->assertSame(['2026-09', '2026-08'], array_column($months['list'], 'period_key'));
  72. $this->assertSame(['2026年09月', '2026-09-01', '150.0000'], [$months['list'][0]['label'], $months['list'][0]['start_date'], $months['list'][0]['deposit_amount']]);
  73. $this->assertSame('2026-08-15', $months['list'][1]['start_date'], 'first month is clipped to the query range');
  74. foreach ([['period' => 'year'], ['end_date' => '2026-09-08'], ['start_date' => '2025-01-01', 'end_date' => '2026-09-07']] as $bad) {
  75. try { $service->report($this->joint, $bad); $this->fail(json_encode($bad)); } catch (\InvalidArgumentException) { $this->addToAssertionCount(1); }
  76. }
  77. }
  78. public function test_equity_agents_cannot_open_member_level_pages(): void
  79. {
  80. $this->seed();
  81. $request = Request::create('/agent/members', 'GET');
  82. $request->attributes->set('agent', $this->equity);
  83. $this->app->instance('request', $request);
  84. $data = (new MemberController())->dailyReport($request, new MemberDailyReportService())->getData(true);
  85. $this->assertSame('入股代理不能查看会员明细,请使用周期报表', $data['msg']);
  86. $this->assertSame('入股代理不能查看会员明细,请使用周期报表', (new MemberController())->index($request)->getData(true)['msg']);
  87. $request = Request::create('/agent/reports/period', 'GET', ['period' => 'month']);
  88. $request->attributes->set('agent', $this->equity);
  89. $this->app->instance('request', $request);
  90. $result = (new ReportController())->period($request, new AgentPeriodReportService())->getData(true);
  91. $this->assertSame(0, $result['code'], (string) $result['msg']);
  92. $this->assertSame('platform', $result['data']['scope']);
  93. }
  94. }