@extends('layouts.dashboard')
@section('title', 'PDF workflow | kView INVESTOR')
@section('content')
@php
$statusTone = fn (?string $status) => match ($status) {
\App\Models\RayDocImport::STATUS_COMPLETED, \App\Models\RayDocImport::STATUS_APPROVED => 'positive',
\App\Models\RayDocImport::STATUS_REJECTED, \App\Models\RayDocImport::STATUS_FAILED => 'negative',
\App\Models\RayDocImport::STATUS_PROCESSING, \App\Models\RayDocImport::STATUS_SENT_TO_RAYDOCS => 'primary',
default => 'neutral',
};
$jobStatusTone = fn (?string $status) => match ($status) {
\App\Models\RayJob::STATUS_FAILED => 'negative',
\App\Models\RayJob::STATUS_COMPLETED => 'positive',
\App\Models\RayJob::STATUS_UPLOADING, \App\Models\RayJob::STATUS_PROCESSING, \App\Models\RayJob::STATUS_SENT => 'primary',
default => 'neutral',
};
$formatLabel = fn (?string $value) => $value ? ucfirst(str_replace('_', ' ', $value)) : '-';
$formatIdentifier = fn (?string $value) => $value ? str($value)->limit(18) : '-';
$formatBytes = function (?int $bytes): string {
if ($bytes === null) {
return '-';
}
$units = ['B', 'KB', 'MB', 'GB'];
$value = (float) $bytes;
$unitIndex = 0;
while ($value >= 1024 && $unitIndex < count($units) - 1) {
$value /= 1024;
$unitIndex++;
}
return number_format($value, $unitIndex === 0 ? 0 : 2).' '.$units[$unitIndex];
};
$metadata = collect($import->metadata ?? []);
$latestJob = $import->latestJob;
$completedJob = $import->jobs->first(
fn ($job) => $job->status === \App\Models\RayJob::STATUS_COMPLETED
&& filled(data_get($job->response_payload, 'extraction.data'))
);
$displayStatus = $completedJob
? \App\Models\RayDocImport::STATUS_COMPLETED
: $import->status;
$extractedData = data_get($completedJob?->response_payload, 'extraction.data');
$normalizedData = data_get($reviewTask?->extractedData?->data, 'normalized', []);
$controlChecks = $reviewTask?->controlResults?->map(fn ($control) => [
'code' => $control->control_type,
'status' => $control->status,
'message' => $control->message,
'details' => $control->data,
])->all() ?? [];
$controlTone = fn (?string $status) => match ($status) {
'passed' => 'positive',
'warning' => 'warning',
'error' => 'negative',
default => 'neutral',
};
$canApprove = $reviewTask
&& $reviewTask->state === \App\Models\RayDocReviewTask::STATUS_READY
&& filled(data_get($reviewTask->data, 'resolution_validated_at'))
&& ! $reviewTask->controlResults->contains('status', 'error');
$isReviewTerminal = $reviewTask && in_array($reviewTask->state, [
\App\Models\RayDocReviewTask::STATUS_APPROVED,
\App\Models\RayDocReviewTask::STATUS_REJECTED,
], true);
$resolutionValidated = $reviewTask
&& $reviewTask->state === \App\Models\RayDocReviewTask::STATUS_READY
&& filled(data_get($reviewTask->data, 'resolution_validated_at'));
$hasControlErrors = collect($controlChecks)->contains(
fn (array $check): bool => ($check['status'] ?? null) === 'error'
);
$duplicatePdfLinkAvailable = $duplicatePdfRecord !== null
&& collect($controlChecks)->contains(
fn (array $check): bool => ($check['code'] ?? null) === 'duplicate'
&& ($check['status'] ?? null) === 'error'
);
$rejectIsPrimary = $hasControlErrors && ! $duplicatePdfLinkAvailable;
$investmentPairKeys = collect($investmentPairs)->map(
fn (array $pair) => $pair['fund_id'].'|'.$pair['investor_id']
)->all();
@endphp
Status
{{ $formatLabel($displayStatus) }}
Size
{{ $formatBytes($import->file_size) }}
Storage
{{ $fileExists ? 'OK' : 'Missing' }}
Disk
{{ $import->storage_disk }}
Source
Uploaded by
{{ $import->uploader?->name ?? '-' }}
Received
{{ $import->received_at?->format('Y-m-d H:i') ?? '-' }}
MIME type
{{ $import->mime_type ?: '-' }}
Storage path
{{ $import->storage_path }}
SHA-256
{{ $import->sha256 }}
Created
{{ $import->created_at?->format('Y-m-d H:i:s') ?? '-' }}
Updated
{{ $import->updated_at?->format('Y-m-d H:i:s') ?? '-' }}
@if ($completedJob)
@if ($reviewTask)
Extracted key figures
Document type
{{ $formatLabel($normalizedData['document_type'] ?? null) }}
Fund
{{ $normalizedData['fund_name'] ?? '-' }}
Investor
{{ $normalizedData['investor_name'] ?? '-' }}
Due date
{{ $normalizedData['due_date'] ?? '-' }}
Call amount
{{ $normalizedData['call_amount'] ?? '-' }} {{ $normalizedData['currency'] ?? '' }}
Distribution amount
{{ $normalizedData['distribution_amount'] ?? '-' }} {{ $normalizedData['currency'] ?? '' }}
@if ($fileExists)
Open PDF
@else
The stored PDF is unavailable.
@endif
Fund and investor resolution
@if ($isReviewTerminal)
Fund
{{ $reviewTask->extractedData?->fund?->full_name ?: $reviewTask->extractedData?->fund?->name ?: '-' }}
Investor
{{ $reviewTask->extractedData?->investor?->full_name ?: $reviewTask->extractedData?->investor?->name ?: '-' }}
Review
{{ $formatLabel($reviewTask->approval_status) }}
@if ($reviewTask->approved_record_type === 'call_distrib' && $reviewTask->approved_record_id)
@endif
@if ($reviewTask->rejection_reason)
Rejection reason
{{ $reviewTask->rejection_reason }}
@endif
@else
Fund
{{ $reviewTask->extractedData?->fund?->full_name ?: $reviewTask->extractedData?->fund?->name ?: 'Not selected' }}
Investor
{{ $reviewTask->extractedData?->investor?->full_name ?: $reviewTask->extractedData?->investor?->name ?: 'Not selected' }}
@endif
@if ($resolutionValidated || $isReviewTerminal)
Automatic controls
@forelse ($controlChecks as $check)
{{ $formatLabel($check['status'] ?? null) }}
{{ $formatLabel($check['code'] ?? null) }}
{{ $check['message'] ?? '-' }}
@if (($check['code'] ?? null) === 'duplicate' && $duplicatePdfLinkAvailable)
The existing Call / Distribution has no PDF reference.
@endif
@empty
No controls are available.
@endforelse
@endif
@if (! $isReviewTerminal && $resolutionValidated)
@if ($duplicatePdfLinkAvailable)
@endif
@endif
@if (! $isReviewTerminal && ! $resolutionValidated)
@endif
@else
The completed extraction has not produced a review task yet.
@endif
@endif
@if ($latestJob)
Status
{{ $formatLabel($latestJob->status) }}
Workspace
{{ $latestJob->raydocs_workspace_id ?: '-' }}
Template
{{ $latestJob->raydocs_template_id ?: '-' }}
Session
{{ $latestJob->raydocs_session_id ?: '-' }}
Document
{{ $latestJob->raydocs_document_id ?: '-' }}
Result
{{ $latestJob->raydocs_result_id ?: '-' }}
Raydocs job
{{ $latestJob->raydocs_job_id ?: '-' }}
S3 upload key
{{ $latestJob->upload_key ?: '-' }}
Started
{{ $latestJob->started_at?->format('Y-m-d H:i:s') ?? '-' }}
@if ($latestJob->error)
Error
{{ $latestJob->error }}
@endif
@endif
@if ($import->jobs->isNotEmpty())
| Created |
Status |
Session |
Document |
Result |
Error |
@foreach ($import->jobs as $job)
| {{ $job->created_at?->format('Y-m-d H:i') ?? '-' }} |
{{ $formatLabel($job->status) }}
|
{{ $job->raydocs_session_id ?: '-' }} |
{{ $job->raydocs_document_id ?: '-' }} |
{{ $job->raydocs_result_id ?: '-' }} |
{{ $job->error ?: '-' }} |
@endforeach
@endif
@if ($metadata->isNotEmpty())
@foreach ($metadata as $key => $value)
{{ $formatLabel((string) $key) }}
{{ is_scalar($value) || $value === null ? ($value ?? '-') : json_encode($value) }}
@endforeach
@else
No additional metadata recorded.
@endif
@if (! $isReviewTerminal && ! $resolutionValidated)
@endif
@endsection