feat: 增强代理结算和账单管理功能
- 在多个控制器中引入 SettlementPartyEnrichment 服务,以优化代理结算和账单的处理逻辑。 - 更新 AgentSettlementBillIndexController 和 AgentSettlementBillShowController,支持根据账单 ID 和关键字进行查询。 - 在 AgentSettlementPeriodCloseController 中添加对站点管理权限的验证,确保只有具备相应权限的管理员能够关闭账期。 - 在 AgentSettlementPeriodIndexController 中更新账期数据的返回格式,提升数据的完整性和可用性。 - 引入对相对占成比例的支持,增强代理资料的管理能力,确保数据一致性。
This commit is contained in:
@@ -4,8 +4,10 @@ namespace App\Services\AgentSettlement;
|
||||
|
||||
use App\Models\AgentNode;
|
||||
use App\Services\Agent\AgentCreditAllocatedSyncService;
|
||||
use App\Support\AgentSettlementPeriodWindow;
|
||||
use App\Support\AgentSettlementProductionGuard;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
|
||||
final class AgentSettlementPeriodCloseService
|
||||
{
|
||||
@@ -27,47 +29,58 @@ final class AgentSettlementPeriodCloseService
|
||||
|
||||
$period = DB::table('settlement_periods')->where('id', $periodId)->first();
|
||||
if ($period === null) {
|
||||
throw new \InvalidArgumentException('period_not_found');
|
||||
throw ValidationException::withMessages([
|
||||
'period' => ['period_not_found'],
|
||||
]);
|
||||
}
|
||||
|
||||
if ((string) $period->status === 'closed') {
|
||||
throw new \InvalidArgumentException('period_already_closed');
|
||||
if ((string) $period->status === 'closed' || (string) $period->status === 'completed') {
|
||||
throw ValidationException::withMessages([
|
||||
'period' => ['period_already_closed'],
|
||||
]);
|
||||
}
|
||||
|
||||
$adminSiteId = (int) $period->admin_site_id;
|
||||
$aggregate = $this->aggregator->aggregate(
|
||||
$adminSiteId,
|
||||
[$periodStart, $periodEnd] = AgentSettlementPeriodWindow::boundStrings(
|
||||
(string) $period->period_start,
|
||||
(string) $period->period_end,
|
||||
);
|
||||
|
||||
if ($aggregate['players'] === []) {
|
||||
throw new \InvalidArgumentException('period_no_ledger_rows');
|
||||
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;
|
||||
}
|
||||
|
||||
$billIds = $this->billGenerator->generate($periodId, $adminSiteId, $aggregate);
|
||||
|
||||
$roundingDiff = $this->platformRounding->apply($periodId, $aggregate);
|
||||
|
||||
$rebateStats = $this->periodCloseRebate->dispatchAndAllocate(
|
||||
$periodId,
|
||||
(string) $period->period_start,
|
||||
(string) $period->period_end,
|
||||
);
|
||||
$rebateStats = $this->periodCloseRebate->dispatchAndAllocate($periodId, $periodStart, $periodEnd);
|
||||
|
||||
$unsettled = $this->unsettledWarning->countForSite(
|
||||
$adminSiteId,
|
||||
(string) $period->period_start,
|
||||
(string) $period->period_end,
|
||||
);
|
||||
$unsettled = $this->unsettledWarning->countForSite($adminSiteId, $periodStart, $periodEnd);
|
||||
|
||||
DB::table('settlement_periods')->where('id', $periodId)->update([
|
||||
'status' => 'closed',
|
||||
'updated_at' => now(),
|
||||
]);
|
||||
|
||||
$siteCode = (string) DB::table('admin_sites')->where('id', $adminSiteId)->value('code');
|
||||
|
||||
DB::table('share_ledger')
|
||||
->whereBetween('settled_at', [$period->period_start, $period->period_end])
|
||||
->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)
|
||||
->whereBetween('sl.settled_at', [$periodStart, $periodEnd]);
|
||||
})
|
||||
->update(['settlement_period_id' => $periodId]);
|
||||
|
||||
$this->reconcileAllocatedCreditForSite($adminSiteId);
|
||||
|
||||
Reference in New Issue
Block a user