feat: add idempotency support for settlement adjustments and payments, fix rebate handling
- Added idempotency_key parameter to settlement bill adjustment and payment endpoints to prevent duplicate operations - Fixed player rebate profile updates to preserve existing values when only one field is modified - Moved wallet player validation earlier in AdminPlayerStoreController to prevent unnecessary processing - Enhanced extra rebate calculation to include 'in_bill' and 'settled' statuses in AgentP
This commit is contained in:
@@ -46,57 +46,59 @@ final class AgentSettlementPeriodCloseService
|
||||
(string) $period->period_end,
|
||||
);
|
||||
|
||||
try {
|
||||
$aggregate = $this->aggregator->aggregate($adminSiteId, $periodStart, $periodEnd);
|
||||
} catch (\InvalidArgumentException $e) {
|
||||
if (str_starts_with($e->getMessage(), 'share_snapshot_missing')) {
|
||||
throw ValidationException::withMessages([
|
||||
'period' => ['share_snapshot_missing'],
|
||||
]);
|
||||
return DB::transaction(function () use ($periodId, $period, $adminSiteId, $periodStart, $periodEnd): array {
|
||||
try {
|
||||
$aggregate = $this->aggregator->aggregate($adminSiteId, $periodStart, $periodEnd);
|
||||
} catch (\InvalidArgumentException $e) {
|
||||
if (str_starts_with($e->getMessage(), 'share_snapshot_missing')) {
|
||||
throw ValidationException::withMessages([
|
||||
'period' => ['share_snapshot_missing'],
|
||||
]);
|
||||
}
|
||||
|
||||
throw $e;
|
||||
}
|
||||
|
||||
throw $e;
|
||||
}
|
||||
$billIds = $this->billGenerator->generate($periodId, $adminSiteId, $aggregate);
|
||||
|
||||
$billIds = $this->billGenerator->generate($periodId, $adminSiteId, $aggregate);
|
||||
$roundingDiff = $this->platformRounding->apply($periodId, $aggregate);
|
||||
|
||||
$roundingDiff = $this->platformRounding->apply($periodId, $aggregate);
|
||||
$rebateStats = $this->periodCloseRebate->dispatchAndAllocate($periodId, $adminSiteId, $periodStart, $periodEnd);
|
||||
|
||||
$rebateStats = $this->periodCloseRebate->dispatchAndAllocate($periodId, $periodStart, $periodEnd);
|
||||
$unsettled = $this->unsettledWarning->countForSite($adminSiteId, $periodStart, $periodEnd);
|
||||
|
||||
$unsettled = $this->unsettledWarning->countForSite($adminSiteId, $periodStart, $periodEnd);
|
||||
DB::table('settlement_periods')->where('id', $periodId)->update([
|
||||
'status' => 'closed',
|
||||
'updated_at' => now(),
|
||||
]);
|
||||
|
||||
DB::table('settlement_periods')->where('id', $periodId)->update([
|
||||
'status' => 'closed',
|
||||
'updated_at' => now(),
|
||||
]);
|
||||
$siteCode = (string) DB::table('admin_sites')->where('id', $adminSiteId)->value('code');
|
||||
|
||||
$siteCode = (string) DB::table('admin_sites')->where('id', $adminSiteId)->value('code');
|
||||
DB::table('share_ledger')
|
||||
->whereIn('id', function ($query) use ($siteCode, $periodStart, $periodEnd): void {
|
||||
$query->select('sl.id')
|
||||
->from('share_ledger as sl')
|
||||
->join('players as p', 'p.id', '=', 'sl.player_id')
|
||||
->where('p.site_code', $siteCode)
|
||||
->whereNull('sl.settlement_period_id')
|
||||
->whereBetween('sl.settled_at', [$periodStart, $periodEnd]);
|
||||
})
|
||||
->update(['settlement_period_id' => $periodId]);
|
||||
|
||||
DB::table('share_ledger')
|
||||
->whereIn('id', function ($query) use ($siteCode, $periodStart, $periodEnd): void {
|
||||
$query->select('sl.id')
|
||||
->from('share_ledger as sl')
|
||||
->join('players as p', 'p.id', '=', 'sl.player_id')
|
||||
->where('p.site_code', $siteCode)
|
||||
->whereNull('sl.settlement_period_id')
|
||||
->whereBetween('sl.settled_at', [$periodStart, $periodEnd]);
|
||||
})
|
||||
->update(['settlement_period_id' => $periodId]);
|
||||
$this->reconcileAllocatedCreditForSite($adminSiteId);
|
||||
|
||||
$this->reconcileAllocatedCreditForSite($adminSiteId);
|
||||
|
||||
return [
|
||||
'period_id' => $periodId,
|
||||
'bill_ids' => $billIds,
|
||||
'player_count' => count($aggregate['players']),
|
||||
'agent_edges' => $aggregate['agent_edges'],
|
||||
'rebate_dispatched' => $rebateStats['dispatched'],
|
||||
'rebate_allocations' => $rebateStats['allocations'],
|
||||
'unsettled_ticket_count' => $unsettled['count'],
|
||||
'unsettled_ticket_sample' => $unsettled['ticket_item_ids'],
|
||||
'platform_rounding_adjustment' => $roundingDiff,
|
||||
];
|
||||
return [
|
||||
'period_id' => $periodId,
|
||||
'bill_ids' => $billIds,
|
||||
'player_count' => count($aggregate['players']),
|
||||
'agent_edges' => $aggregate['agent_edges'],
|
||||
'rebate_dispatched' => $rebateStats['dispatched'],
|
||||
'rebate_allocations' => $rebateStats['allocations'],
|
||||
'unsettled_ticket_count' => $unsettled['count'],
|
||||
'unsettled_ticket_sample' => $unsettled['ticket_item_ids'],
|
||||
'platform_rounding_adjustment' => $roundingDiff,
|
||||
];
|
||||
});
|
||||
}
|
||||
|
||||
/** 关账后按真理源重算各代理「已下发额度」,避免与直属玩家/下级代理授信脱节。 */
|
||||
|
||||
Reference in New Issue
Block a user