AgentEquityOrderAdminTest.php 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. <?php
  2. namespace Tests\Integration;
  3. use App\Http\Controllers\admin\Agent as AdminAgent;
  4. use App\Models\Agent\Agent;
  5. use App\Models\Agent\AgentEquityOrder;
  6. use App\Models\Agent\AgentSetting;
  7. use App\Services\Agent\AgentEquityService;
  8. use App\Services\Agent\AgentWalletService;
  9. use Illuminate\Http\Request;
  10. use PHPUnit\Framework\TestCase;
  11. use Tests\Support\AgentTestEnvironment;
  12. /** 总后台入股购买记录:列表筛选、汇总、取消待付款订单。 */
  13. class AgentEquityOrderAdminTest extends TestCase
  14. {
  15. use AgentTestEnvironment;
  16. private function call(string $method, array $params)
  17. {
  18. $request = Request::create('/admin/agent/equity-orders', $method === 'cancelEquityOrder' ? 'POST' : 'GET', $params);
  19. $request->user = (object) ['id' => 7];
  20. $this->app->instance('request', $request);
  21. return (new AdminAgent())->{$method}($request, new AgentEquityService(new AgentWalletService()))->getData(true);
  22. }
  23. public function test_admin_lists_all_purchases_with_summary_and_cancels_pending_orders(): void
  24. {
  25. AgentSetting::current()->update(['equity_enabled' => 1, 'equity_price_per_percent' => 10000,
  26. 'equity_min_percent' => 0.1, 'equity_max_percent' => 1]);
  27. $equity = new AgentEquityService(new AgentWalletService());
  28. $rich = $this->agent(Agent::TYPE_EQUITY);
  29. Agent::query()->whereKey($rich->id)->update(['balance' => 5000, 'realtime_balance' => 5000]);
  30. $poor = $this->agent(Agent::TYPE_EQUITY);
  31. $done = $equity->order($rich->fresh(), '0.3'); // 3000,余额够,直接开通
  32. $pending = $equity->order($poor, '0.5'); // 5000,待付款
  33. $this->assertSame(AgentEquityOrder::STATUS_COMPLETED, $done->status);
  34. $all = $this->call('equityOrders', []);
  35. $this->assertSame(0, $all['code'], (string) $all['msg']);
  36. $this->assertSame(2, $all['data']['total']);
  37. $this->assertSame(['0.3000', '3000.0000', 1, '5000.0000', '0.3000'], [
  38. $all['data']['summary']['completed_percent'], $all['data']['summary']['completed_amount'],
  39. $all['data']['summary']['pending_count'], $all['data']['summary']['pending_amount'], $all['data']['summary']['total_equity_percent'],
  40. ]);
  41. $first = $all['data']['list'][0];
  42. $this->assertSame($pending->id, $first['id']);
  43. $this->assertSame($poor->username, $first['agent']['username']);
  44. $this->assertSame('待付款', $first['status_text']);
  45. $this->assertSame(1, $this->call('equityOrders', ['username' => $rich->username])['data']['total']);
  46. $this->assertSame(1, $this->call('equityOrders', ['status' => 'completed'])['data']['total']);
  47. $this->assertSame(0, $this->call('equityOrders', ['date_type' => 'completed_at', 'start_date' => '2026-09-08'])['data']['total']);
  48. $this->assertNotSame(0, $this->call('cancelEquityOrder', ['id' => $pending->id])['code'], 'remark required');
  49. $this->assertSame('只有待付款订单可以取消', $this->call('cancelEquityOrder', ['id' => $done->id, 'remark' => 'x'])['msg']);
  50. $cancelled = $this->call('cancelEquityOrder', ['id' => $pending->id, 'remark' => '长期未充值']);
  51. $this->assertSame(0, $cancelled['code']);
  52. $this->assertSame(['cancelled', 7, '长期未充值'], [$cancelled['data']['status'], $cancelled['data']['cancelled_by'], $cancelled['data']['cancel_remark']]);
  53. $own = $equity->order($poor, '0.2');
  54. $this->assertNull($equity->cancel($poor, $own->id)->cancelled_by, 'agent self-cancel has no admin');
  55. }
  56. public function test_company_equity_setting_accounts_for_completed_and_pending_formal_purchases(): void
  57. {
  58. $admin = new AdminAgent();
  59. $this->assertSame('0.0000', $admin->settings()->getData(true)['data']['company_equity_percent']);
  60. $saved = $this->saveSettings(['company_equity_percent' => '98.5000']);
  61. $this->assertSame(0, $saved['code'], $saved['msg']);
  62. $this->assertSame('98.5000', $saved['data']['company_equity_percent']);
  63. $this->assertSame('98.5000', $this->saveSettings([])['data']['company_equity_percent']);
  64. $this->assertNotSame(0, $this->saveSettings(['company_equity_percent' => '100.0001'])['code']);
  65. $this->assertNotSame(0, $this->saveSettings(['company_equity_percent' => '0.00001'])['code']);
  66. $equity = new AgentEquityService(new AgentWalletService());
  67. $holder = $this->agent(Agent::TYPE_EQUITY);
  68. $buyer = $this->agent(Agent::TYPE_EQUITY);
  69. $another = $this->agent(Agent::TYPE_EQUITY);
  70. Agent::query()->whereKey($holder->id)->update(['balance' => 1000, 'realtime_balance' => 1000]);
  71. $this->assertSame(AgentEquityOrder::STATUS_COMPLETED, $equity->order($holder, '1')->status);
  72. $pending = $equity->order($buyer, '0.5');
  73. $this->assertSame(AgentEquityOrder::STATUS_PENDING, $pending->status);
  74. $this->assertSame('0.0000', $equity->overview($another)['remaining_percent']);
  75. $this->assertNotSame(0, $this->saveSettings(['company_equity_percent' => '98.5001'])['code']);
  76. try {
  77. $equity->order($another, '0.1');
  78. $this->fail('Pending purchases reserve the remaining allocation.');
  79. } catch (\RuntimeException $e) {
  80. $this->assertSame('可购买股份不足', $e->getMessage());
  81. }
  82. $equity->cancel($buyer, $pending->id);
  83. $this->assertSame('99.0000', $this->saveSettings(['company_equity_percent' => '99'])['data']['company_equity_percent']);
  84. $legacyOrder = $pending->replicate(['status', 'cancel_remark']);
  85. $legacyOrder->forceFill(['order_no' => 'legacy-overbooked', 'status' => AgentEquityOrder::STATUS_PENDING])->save();
  86. Agent::query()->whereKey($buyer->id)->update(['balance' => 1000, 'realtime_balance' => 1000]);
  87. $this->assertSame(0, $equity->fulfillPending($buyer->id));
  88. $this->assertSame('1000.0000', $buyer->fresh()->balance);
  89. $this->assertSame(AgentEquityOrder::STATUS_PENDING, $legacyOrder->fresh()->status);
  90. }
  91. private function saveSettings(array $params): array
  92. {
  93. $request = new class([], $params + [
  94. 'margin_stop_percent' => 10,
  95. 'equity_enabled' => 1,
  96. 'equity_price_per_percent' => 1000,
  97. 'equity_min_percent' => '0.1',
  98. 'equity_max_percent' => '1',
  99. ]) extends Request {
  100. public object $user;
  101. };
  102. $request->setMethod('POST');
  103. $request->user = (object) ['id' => 7];
  104. $this->app->instance('request', $request);
  105. return (new AdminAgent())->saveSettings($request)->getData(true);
  106. }
  107. }