68 lines
2.5 KiB
PHP
68 lines
2.5 KiB
PHP
<?php
|
|
|
|
namespace App\Services\AiEditing;
|
|
|
|
use App\Models\AiEditRequest;
|
|
use App\Models\AiUsageLedger;
|
|
use App\Models\Event;
|
|
use Illuminate\Support\Facades\DB;
|
|
|
|
class AiUsageLedgerService
|
|
{
|
|
public function __construct(private readonly AiStylingEntitlementService $entitlements) {}
|
|
|
|
/**
|
|
* @param array<string, mixed> $metadata
|
|
*/
|
|
public function recordDebitForRequest(AiEditRequest $request, ?float $costUsd = null, array $metadata = []): AiUsageLedger
|
|
{
|
|
return DB::transaction(function () use ($request, $costUsd, $metadata): AiUsageLedger {
|
|
$lockedRequest = AiEditRequest::query()
|
|
->whereKey($request->id)
|
|
->lockForUpdate()
|
|
->firstOrFail();
|
|
|
|
$existing = AiUsageLedger::query()
|
|
->where('request_id', $lockedRequest->id)
|
|
->where('entry_type', AiUsageLedger::TYPE_DEBIT)
|
|
->first();
|
|
if ($existing) {
|
|
return $existing;
|
|
}
|
|
|
|
$resolvedCost = $costUsd;
|
|
if ($resolvedCost === null || $resolvedCost < 0) {
|
|
$resolvedCost = (float) config('ai-editing.billing.default_unit_cost_usd', 0.01);
|
|
}
|
|
|
|
$event = Event::query()->find($lockedRequest->event_id);
|
|
$entitlement = $event ? $this->entitlements->resolveForEvent($event) : [
|
|
'allowed' => false,
|
|
'granted_by' => null,
|
|
];
|
|
|
|
$packageContext = $entitlement['granted_by'] === 'package'
|
|
? 'package_included'
|
|
: ($entitlement['granted_by'] === 'addon' ? 'addon_unlock' : 'unentitled');
|
|
|
|
return AiUsageLedger::query()->create([
|
|
'tenant_id' => $lockedRequest->tenant_id,
|
|
'event_id' => $lockedRequest->event_id,
|
|
'request_id' => $lockedRequest->id,
|
|
'entry_type' => AiUsageLedger::TYPE_DEBIT,
|
|
'quantity' => 1,
|
|
'unit_cost_usd' => $resolvedCost,
|
|
'amount_usd' => $resolvedCost,
|
|
'currency' => 'USD',
|
|
'package_context' => $packageContext,
|
|
'recorded_at' => now(),
|
|
'metadata' => array_merge([
|
|
'provider' => $lockedRequest->provider,
|
|
'provider_model' => $lockedRequest->provider_model,
|
|
'granted_by' => $entitlement['granted_by'],
|
|
], $metadata),
|
|
]);
|
|
});
|
|
}
|
|
}
|