diff --git a/src/hooks/useRequestDetails.ts b/src/hooks/useRequestDetails.ts
index 95ef983..460200d 100644
--- a/src/hooks/useRequestDetails.ts
+++ b/src/hooks/useRequestDetails.ts
@@ -264,6 +264,19 @@ export function useRequestDetails(
proposalDetails = claimData.proposalDetails || claimData.proposal_details;
completionDetails = claimData.completionDetails || claimData.completion_details;
internalOrder = claimData.internalOrder || claimData.internal_order || null;
+ // New normalized tables
+ const budgetTracking = claimData.budgetTracking || claimData.budget_tracking || null;
+ const invoice = claimData.invoice || null;
+ const creditNote = claimData.creditNote || claimData.credit_note || null;
+ const completionExpenses = claimData.completionExpenses || claimData.completion_expenses || null;
+
+ // Store new fields in claimDetails for backward compatibility and easy access
+ if (claimDetails) {
+ (claimDetails as any).budgetTracking = budgetTracking;
+ (claimDetails as any).invoice = invoice;
+ (claimDetails as any).creditNote = creditNote;
+ (claimDetails as any).completionExpenses = completionExpenses;
+ }
console.debug('[useRequestDetails] Extracted details:', {
claimDetails: claimDetails ? {
@@ -278,6 +291,10 @@ export function useRequestDetails(
hasProposalDetails: !!proposalDetails,
hasCompletionDetails: !!completionDetails,
hasInternalOrder: !!internalOrder,
+ hasBudgetTracking: !!budgetTracking,
+ hasInvoice: !!invoice,
+ hasCreditNote: !!creditNote,
+ hasCompletionExpenses: Array.isArray(completionExpenses) && completionExpenses.length > 0,
});
} else {
console.warn('[useRequestDetails] No claimData found in response');
@@ -337,6 +354,11 @@ export function useRequestDetails(
proposalDetails: proposalDetails || null,
completionDetails: completionDetails || null,
internalOrder: internalOrder || null,
+ // New normalized tables (also available via claimDetails for backward compatibility)
+ budgetTracking: (claimDetails as any)?.budgetTracking || null,
+ invoice: (claimDetails as any)?.invoice || null,
+ creditNote: (claimDetails as any)?.creditNote || null,
+ completionExpenses: (claimDetails as any)?.completionExpenses || null,
};
setApiRequest(updatedRequest);
diff --git a/src/pages/RequestDetail/RequestDetail.tsx b/src/pages/RequestDetail/RequestDetail.tsx
index 7c0e6c3..dbd8aa7 100644
--- a/src/pages/RequestDetail/RequestDetail.tsx
+++ b/src/pages/RequestDetail/RequestDetail.tsx
@@ -26,6 +26,7 @@ import {
ShieldX,
RefreshCw,
ArrowLeft,
+ DollarSign,
} from 'lucide-react';
import { Badge } from '@/components/ui/badge';
@@ -51,7 +52,9 @@ import { DocumentsTab } from './components/tabs/DocumentsTab';
import { ActivityTab } from './components/tabs/ActivityTab';
import { WorkNotesTab } from './components/tabs/WorkNotesTab';
import { SummaryTab } from './components/tabs/SummaryTab';
+import { IOTab } from './components/tabs/IOTab';
import { isClaimManagementRequest } from '@/utils/claimRequestUtils';
+import { determineUserRole } from '@/utils/claimDataMapper';
import { QuickActionsSidebar } from './components/QuickActionsSidebar';
import { RequestDetailModals } from './components/RequestDetailModals';
import { RequestDetailProps } from './types/requestDetail.types';
@@ -133,6 +136,42 @@ function RequestDetailInner({ requestId: propRequestId, onBack, dynamicRequests
accessDenied,
} = useRequestDetails(requestIdentifier, dynamicRequests, user);
+ // Determine if user is initiator (from overview tab initiator info)
+ const currentUserId = (user as any)?.userId || '';
+ const currentUserEmail = (user as any)?.email?.toLowerCase() || '';
+ const initiatorUserId = apiRequest?.initiator?.userId;
+ const initiatorEmail = apiRequest?.initiator?.email?.toLowerCase();
+ const isUserInitiator = apiRequest?.initiator && (
+ (initiatorUserId && initiatorUserId === currentUserId) ||
+ (initiatorEmail && initiatorEmail === currentUserEmail)
+ );
+
+ // Determine if user is department lead (whoever is in step 3 / approval level 3)
+ const approvalLevels = apiRequest?.approvalLevels || [];
+ const step3Level = approvalLevels.find((level: any) =>
+ (level.levelNumber || level.level_number) === 3
+ );
+ const deptLeadUserId = step3Level?.approverId || step3Level?.approver?.userId;
+ const isDeptLead = deptLeadUserId && deptLeadUserId === currentUserId;
+
+ // Check if IO tab should be visible (for initiator and department lead in claim management requests)
+ const showIOTab = isClaimManagementRequest(apiRequest) &&
+ (isUserInitiator || isDeptLead);
+
+ // Debug logging for troubleshooting
+ console.debug('[RequestDetail] IO Tab visibility:', {
+ isClaimManagement: isClaimManagementRequest(apiRequest),
+ isUserInitiator,
+ isDeptLead,
+ currentUserId,
+ currentUserEmail,
+ initiatorUserId,
+ initiatorEmail,
+ step3Level: step3Level ? { levelNumber: step3Level.levelNumber || step3Level.level_number, approverId: step3Level.approverId || step3Level.approver?.userId } : null,
+ deptLeadUserId,
+ showIOTab,
+ });
+
const {
mergedMessages,
unreadWorkNotes,
@@ -433,6 +472,16 @@ function RequestDetailInner({ requestId: propRequestId, onBack, dynamicRequests