feat: 切换 schema dump 基线并增强返点结算与管理校验
This commit is contained in:
@@ -910,6 +910,70 @@ test('ticket place sold out for second player after first consumes shared pool',
|
||||
expect((int) $pool->remaining_amount)->toBe(2000);
|
||||
});
|
||||
|
||||
test('ticket preview and place apply base rebate plus player add-on rebate for wallet player', function (): void {
|
||||
$player = ticketPlayerWithWallet(500_000);
|
||||
ticketOpenDraw();
|
||||
|
||||
$oddsVersionId = OddsVersion::query()
|
||||
->where('status', ConfigVersionStatus::Active->value)
|
||||
->value('id');
|
||||
expect($oddsVersionId)->not->toBeNull();
|
||||
|
||||
DB::table('odds_items')
|
||||
->where('version_id', $oddsVersionId)
|
||||
->where('play_code', 'big')
|
||||
->update(['rebate_rate' => 0.01]);
|
||||
|
||||
DB::table('player_rebate_profiles')->insert([
|
||||
'player_id' => $player->id,
|
||||
'game_type' => 'big',
|
||||
'rebate_rate' => 0.005,
|
||||
'extra_rebate_rate' => 0.002,
|
||||
'inherit_from_agent' => false,
|
||||
'created_at' => now(),
|
||||
'updated_at' => now(),
|
||||
]);
|
||||
|
||||
$payload = [
|
||||
'draw_id' => '20260511-001',
|
||||
'currency_code' => 'NPR',
|
||||
'client_trace_id' => 'trace-wallet-rebate-stack',
|
||||
'lines' => [
|
||||
['number' => '1234', 'play_code' => 'big', 'amount' => 10_000],
|
||||
],
|
||||
];
|
||||
|
||||
$this->withHeader('Authorization', 'Bearer dev:'.$player->id)
|
||||
->postJson('/api/v1/ticket/preview', $payload)
|
||||
->assertOk()
|
||||
->assertJsonPath('data.summary.total_bet_amount', 10_000)
|
||||
->assertJsonPath('data.summary.total_actual_deduct', 9_830)
|
||||
->assertJsonPath('data.summary.total_rebate_amount', 170)
|
||||
->assertJsonPath('data.lines.0.rebate_rate', '0.0170')
|
||||
->assertJsonPath('data.lines.0.rebate_amount', 170)
|
||||
->assertJsonPath('data.lines.0.actual_deduct_amount', 9_830)
|
||||
->assertJsonPath('data.lines.0.rule_snapshot_json.base_rebate_rate', '0.0100')
|
||||
->assertJsonPath('data.lines.0.rule_snapshot_json.player_addon_rebate_rate', '0.0070')
|
||||
->assertJsonPath('data.lines.0.rule_snapshot_json.rebate_inherited_from_agent', false);
|
||||
|
||||
$this->withHeader('Authorization', 'Bearer dev:'.$player->id)
|
||||
->postJson('/api/v1/ticket/place', $payload)
|
||||
->assertOk()
|
||||
->assertJsonPath('data.summary.total_bet_amount', 10_000)
|
||||
->assertJsonPath('data.summary.total_actual_deduct', 9_830);
|
||||
|
||||
$item = TicketItem::query()->where('play_code', 'big')->firstOrFail();
|
||||
$ruleSnapshot = is_array($item->rule_snapshot_json) ? $item->rule_snapshot_json : [];
|
||||
|
||||
expect((string) $item->rebate_rate_snapshot)->toBe('0.0170')
|
||||
->and((int) $item->actual_deduct_amount)->toBe(9_830)
|
||||
->and($ruleSnapshot['base_rebate_rate'] ?? null)->toBe('0.0100')
|
||||
->and($ruleSnapshot['player_addon_rebate_rate'] ?? null)->toBe('0.0070');
|
||||
|
||||
$wallet = PlayerWallet::query()->where('player_id', $player->id)->firstOrFail();
|
||||
expect((int) $wallet->balance)->toBe(500_000 - 9_830);
|
||||
});
|
||||
|
||||
test('ticket pending confirmation reconcile releases risk when wallet deduction is missing', function (): void {
|
||||
$draw = ticketOpenDraw();
|
||||
$player = ticketPlayerWithWallet();
|
||||
|
||||
Reference in New Issue
Block a user