@php $workspace = $appraisalWorkspace ?? []; $workflow = $appraisalWorkflow ?? []; $appraisal = $workspace['appraisal'] ?? null; $canEdit = (bool) ($workspace['canEdit'] ?? false); $editLockReason = filled($workspace['editLockReason'] ?? null) ? (string) $workspace['editLockReason'] : null; $canComplete = (bool) ($workspace['canComplete'] ?? false); $officerComplete = (bool) ($appraisal?->isOfficerWorkComplete() ?? false); // Signature + Complete must be available while editable. Readiness may require // the officer signature, so gating the pad on canComplete creates a deadlock. $canSignAndFinish = $canEdit && ! $officerComplete; $readOnlyBrowse = ! $canEdit; $collateralSummary = $workspace['collateralSummary'] ?? []; $tableItems = $workspace['collateralTableItems'] ?? []; $completionErrors = (array) ($workspace['completionErrors'] ?? []); $investigation = $workspace['field_investigation'] ?? []; $repeatBorrowerHistory = $workspace['repeat_borrower_history'] ?? []; $pastCollateralCatalog = $workspace['past_collateral_catalog'] ?? ['applicant' => [], 'guarantor' => [], 'is_repeat_borrower' => false]; $workspaceGuidance = $workspace['workspace_guidance'] ?? []; $verificationPhotos = $investigation['verification_photos'] ?? []; $businessGpsReady = (bool) ($investigation['business_gps_ready'] ?? false); $fieldPhotoCount = (int) ($investigation['verification_photo_count'] ?? count($verificationPhotos)); $hasInitialCollateral = collect($tableItems)->contains(function ($row) { return filled($row['item'] ?? null) || filled($row['description'] ?? null) || filled($row['identification'] ?? null) || filled($row['value'] ?? null); }); $policyPayload = $workspace['policy'] ?? []; $guarantorSignatureRequired = (bool) data_get($policyPayload, 'appraisal.guarantor_signature_required', false); $officerSignatureRequired = (bool) data_get($policyPayload, 'appraisal.officer_signature_required', true); $requirementDefs = []; if ($guarantorSignatureRequired) { $requirementDefs['guarantor_signature'] = 'Guarantor signature'; } if ($officerSignatureRequired) { $requirementDefs['officer_signature'] = 'Loan officer signature'; } $requirementItems = []; foreach ($requirementDefs as $errorKey => $label) { $anchor = match ($errorKey) { 'guarantor_signature' => 'appraisal-guarantors', 'officer_signature' => 'appraisal-officer-signature', default => 'appraisal-collateral', }; $requirementItems[] = [ 'key' => $errorKey, 'label' => $label, 'status' => array_key_exists($errorKey, $completionErrors) ? 'incomplete' : 'complete', 'anchor' => $anchor, ]; } $incompleteRequirements = collect($requirementItems)->where('status', 'incomplete')->values(); $firstIncompleteAnchor = $incompleteRequirements->first()['anchor'] ?? ''; $fieldInvestigationDone = filled($investigation['findings'] ?? null) || ! empty($investigation['visits']); $fieldVisitRequired = (bool) data_get($policyPayload, 'appraisal.visit_required', false) || (bool) data_get($policyPayload, 'appraisal.field_investigation_required', false); if (! $fieldInvestigationDone && ! $fieldVisitRequired) { $fieldInvestigationDone = filled($investigation['visit_date'] ?? null); } $repeatBorrowerReviewRequired = $repeatBorrowerHistory !== []; $repeatBorrowerReviewDone = ! $repeatBorrowerReviewRequired || collect($repeatBorrowerHistory)->every(fn (array $row): bool => (bool) ($row['review_submitted'] ?? false)); // Appraisal workspace is Security → Field visit → Sign-off. Open on the first workflow // step that still needs input — not on sign-off just because the officer signature is missing. $collateralRequired = (bool) data_get($policyPayload, 'collateral.required', false); $initialStep = match (true) { $readOnlyBrowse && $officerComplete => 1, $officerComplete => 3, $collateralRequired && ! $hasInitialCollateral => 1, ! $fieldInvestigationDone => 2, default => 3, }; $initialSecurityTab = ($readOnlyBrowse && $officerComplete) || ! in_array($firstIncompleteAnchor, ['appraisal-guarantors', 'appraisal-guarantor-signature'], true) ? 'collateral' : 'guarantors'; // Always present the register table when editable so resume-from-register is not an empty state. $showCollateralEditor = $canEdit || $hasInitialCollateral; $visitingOfficer = old('visiting_officer', $investigation['visiting_officer'] ?? ''); $canPickVisitingOfficer = (bool) ($investigation['can_pick_visiting_officer'] ?? false); $visitingOfficerOptions = $investigation['visiting_officer_options'] ?? []; $coAppraiserEmployeeId = (int) old('co_appraiser_employee_id', $investigation['co_appraiser_employee_id'] ?? 0); $coAppraiserOptions = $investigation['co_appraiser_options'] ?? []; $originationSummary = $workspace['origination_summary'] ?? []; $clientSum = $originationSummary['client'] ?? []; $gpsRaw = (string) ($clientSum['gps'] ?? '—'); $gpsReady = $gpsRaw !== '' && $gpsRaw !== '—' && ! str_contains(strtolower($gpsRaw), 'not captured'); $kycLabel = (string) ($clientSum['kyc'] ?? '—'); $officerSignatures = app(\App\Services\LoanBook\Appraisal\LoanBookAppraisalOfficerSignatureService::class); $hasOfficerSignature = $officerSignatures->hasSignature($appraisal); @endphp