| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485 |
- <?php
- namespace App\Services\Agent;
- use App\Models\Agent\Agent;
- use App\Models\Agent\AgentCommission;
- use App\Models\Agent\AgentProfitCommissionAssignment;
- use App\Models\Agent\AgentProfitCommissionProfile;
- use App\Models\Agent\AgentRebateRecord;
- use Carbon\Carbon;
- use Illuminate\Support\Facades\DB;
- class AgentProfitCommissionAssignmentService
- {
- public function at(Agent $agent, string $date): AgentProfitCommissionAssignment
- {
- $day = Carbon::parse($date)->toDateString();
- $assignment = AgentProfitCommissionAssignment::query()
- ->where('agent_id', $agent->id)
- ->where('effective_from', '<=', $day)
- ->orderByDesc('effective_from')
- ->orderByDesc('id')
- ->first();
- if (!$assignment) {
- throw new \RuntimeException("代理 {$agent->id} 缺少 {$day} 可用的盈亏佣金比例历史");
- }
- return $assignment;
- }
- public function assign(
- Agent $agent,
- AgentProfitCommissionProfile $profile,
- string $effectiveFrom,
- ?int $createdBy = null
- ): AgentProfitCommissionAssignment {
- $this->assignMany([(int) $agent->id], $profile, $effectiveFrom, $createdBy);
- return AgentProfitCommissionAssignment::query()
- ->where('agent_id', $agent->id)
- ->where('effective_from', Carbon::parse($effectiveFrom)->toDateString())
- ->firstOrFail();
- }
- public function assignMany(
- array $agentIds,
- AgentProfitCommissionProfile $profile,
- string $effectiveFrom,
- ?int $createdBy = null
- ): void {
- $agentIds = array_values(array_unique(array_map('intval', $agentIds)));
- if ($agentIds === []) return;
- $day = Carbon::parse($effectiveFrom)->toDateString();
- $this->assertMutable($agentIds, $day);
- $values = array_merge($profile->rateSnapshot(), [
- 'profit_commission_profile_id' => (int) $profile->id,
- 'profile_name' => (string) $profile->name,
- 'created_by' => $createdBy,
- ]);
- DB::transaction(function () use ($agentIds, $day, $values) {
- foreach (array_chunk($agentIds, 500) as $chunk) {
- foreach ($chunk as $agentId) {
- AgentProfitCommissionAssignment::query()->updateOrCreate(
- ['agent_id' => $agentId, 'effective_from' => $day],
- $values
- );
- }
- }
- });
- }
- private function assertMutable(array $agentIds, string $day): void
- {
- $newCredited = AgentRebateRecord::query()->whereIn('agent_id', $agentIds)
- ->where('settlement_date', '>=', $day)
- ->where('profit_status', AgentRebateRecord::STATUS_CREDITED)
- ->exists();
- $legacyCredited = AgentCommission::query()->whereIn('agent_id', $agentIds)
- ->where('type', 'profit')
- ->where('settlement_date', '>=', $day)
- ->where('status', AgentRebateRecord::STATUS_CREDITED)
- ->exists();
- if ($newCredited || $legacyCredited) {
- throw new \RuntimeException('生效日期已有盈亏佣金入账,不能修改比例方案');
- }
- }
- }
|