/** * DMSPushModal Component * Modal for Step 6: Push to DMS Verification * Allows user to verify completion details and expenses before pushing to DMS */ import { useState, useMemo } from 'react'; import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, } from '@/components/ui/dialog'; import { Button } from '@/components/ui/button'; import { Textarea } from '@/components/ui/textarea'; import { Label } from '@/components/ui/label'; import { Badge } from '@/components/ui/badge'; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; import { Receipt, DollarSign, TriangleAlert, Activity, CheckCircle2, } from 'lucide-react'; import { toast } from 'sonner'; interface ExpenseItem { description: string; amount: number; } interface CompletionDetails { activityCompletionDate?: string; numberOfParticipants?: number; closedExpenses?: ExpenseItem[]; totalClosedExpenses?: number; completionDescription?: string; } interface IODetails { ioNumber?: string; blockedAmount?: number; availableBalance?: number; remainingBalance?: number; } interface DMSPushModalProps { isOpen: boolean; onClose: () => void; onPush: (comments: string) => Promise; completionDetails?: CompletionDetails | null; ioDetails?: IODetails | null; requestTitle?: string; requestNumber?: string; } export function DMSPushModal({ isOpen, onClose, onPush, completionDetails, ioDetails, requestTitle, requestNumber, }: DMSPushModalProps) { const [comments, setComments] = useState(''); const [submitting, setSubmitting] = useState(false); const commentsChars = comments.length; const maxCommentsChars = 500; // Calculate total closed expenses const totalClosedExpenses = useMemo(() => { if (completionDetails?.totalClosedExpenses) { return completionDetails.totalClosedExpenses; } if (completionDetails?.closedExpenses && Array.isArray(completionDetails.closedExpenses)) { return completionDetails.closedExpenses.reduce((sum, item) => { const amount = typeof item === 'object' ? (item.amount || 0) : 0; return sum + (Number(amount) || 0); }, 0); } return 0; }, [completionDetails]); // Format date const formatDate = (dateString?: string) => { if (!dateString) return '—'; try { const date = new Date(dateString); return date.toLocaleDateString('en-IN', { year: 'numeric', month: 'long', day: 'numeric', }); } catch { return dateString; } }; // Format currency const formatCurrency = (amount: number) => { return `₹${amount.toLocaleString('en-IN', { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`; }; const handleSubmit = async () => { if (!comments.trim()) { toast.error('Please provide comments before pushing to DMS'); return; } try { setSubmitting(true); await onPush(comments.trim()); handleReset(); onClose(); } catch (error) { console.error('Failed to push to DMS:', error); toast.error('Failed to push to DMS. Please try again.'); } finally { setSubmitting(false); } }; const handleReset = () => { setComments(''); }; const handleClose = () => { if (!submitting) { handleReset(); onClose(); } }; return (
Push to DMS - Verification Review completion details and expenses before pushing to DMS for e-invoice generation
{/* Request Info Card */}
Workflow Step: Step 6
{requestNumber && (
Request Number:

{requestNumber}

)}
Title:

{requestTitle || '—'}

Action: PUSH TO DMS
{/* Completion Details Card */} {completionDetails && ( Completion Details Review activity completion information {completionDetails.activityCompletionDate && (
Activity Completion Date: {formatDate(completionDetails.activityCompletionDate)}
)} {completionDetails.numberOfParticipants !== undefined && (
Number of Participants: {completionDetails.numberOfParticipants}
)} {completionDetails.completionDescription && (

Completion Description:

{completionDetails.completionDescription}

)}
)} {/* Expense Breakdown Card */} {completionDetails?.closedExpenses && completionDetails.closedExpenses.length > 0 && ( Expense Breakdown Review closed expenses before pushing to DMS
{completionDetails.closedExpenses.map((expense, index) => (

{expense.description || `Expense ${index + 1}`}

{formatCurrency(typeof expense === 'object' ? (expense.amount || 0) : 0)}

))}
Total Closed Expenses: {formatCurrency(totalClosedExpenses)}
)} {/* IO Details Card */} {ioDetails && ioDetails.ioNumber && ( IO Details Internal Order information for budget reference
IO Number: {ioDetails.ioNumber}
{ioDetails.blockedAmount !== undefined && ioDetails.blockedAmount > 0 && (
Blocked Amount: {formatCurrency(ioDetails.blockedAmount)}
)} {ioDetails.remainingBalance !== undefined && ioDetails.remainingBalance !== null && (
Remaining Balance: {formatCurrency(ioDetails.remainingBalance)}
)}
)} {/* Verification Warning */}

Please verify all details before pushing to DMS

Once pushed, the system will automatically generate an e-invoice and the workflow will proceed to Step 7.

{/* Comments & Remarks */}