294 lines
12 KiB
TypeScript
294 lines
12 KiB
TypeScript
/**
|
|
* CreditNoteSAPModal Component
|
|
* Modal for Step 8: Credit Note from SAP
|
|
* Allows Finance team to review credit note details and send to dealer
|
|
*/
|
|
|
|
import { useState } from 'react';
|
|
import {
|
|
Dialog,
|
|
DialogContent,
|
|
DialogDescription,
|
|
DialogFooter,
|
|
DialogHeader,
|
|
DialogTitle,
|
|
} from '@/components/ui/dialog';
|
|
import { Button } from '@/components/ui/button';
|
|
import { Badge } from '@/components/ui/badge';
|
|
import { Label } from '@/components/ui/label';
|
|
import { Receipt, CircleCheckBig, Hash, Calendar, DollarSign, Building, FileText, Download, Send } from 'lucide-react';
|
|
import { toast } from 'sonner';
|
|
import { formatDateTime } from '@/utils/dateFormatter';
|
|
|
|
interface CreditNoteSAPModalProps {
|
|
isOpen: boolean;
|
|
onClose: () => void;
|
|
onDownload?: () => Promise<void>;
|
|
onSendToDealer?: () => Promise<void>;
|
|
creditNoteData?: {
|
|
creditNoteNumber?: string;
|
|
creditNoteDate?: string;
|
|
creditNoteAmount?: number;
|
|
status?: 'PENDING' | 'APPROVED' | 'ISSUED' | 'SENT';
|
|
};
|
|
dealerInfo?: {
|
|
dealerName?: string;
|
|
dealerCode?: string;
|
|
dealerEmail?: string;
|
|
};
|
|
activityName?: string;
|
|
requestNumber?: string;
|
|
requestId?: string;
|
|
dueDate?: string;
|
|
}
|
|
|
|
export function CreditNoteSAPModal({
|
|
isOpen,
|
|
onClose,
|
|
onDownload,
|
|
onSendToDealer,
|
|
creditNoteData,
|
|
dealerInfo,
|
|
activityName,
|
|
requestNumber,
|
|
requestId: _requestId,
|
|
dueDate,
|
|
}: CreditNoteSAPModalProps) {
|
|
const [downloading, setDownloading] = useState(false);
|
|
const [sending, setSending] = useState(false);
|
|
|
|
const hasCreditNote = creditNoteData?.creditNoteNumber && creditNoteData?.creditNoteNumber !== '';
|
|
const creditNoteNumber = creditNoteData?.creditNoteNumber || '';
|
|
const creditNoteDate = creditNoteData?.creditNoteDate
|
|
? formatDateTime(creditNoteData.creditNoteDate, { includeTime: false, format: 'short' })
|
|
: '';
|
|
const creditNoteAmount = creditNoteData?.creditNoteAmount || 0;
|
|
const status = creditNoteData?.status || 'PENDING';
|
|
|
|
const dealerName = dealerInfo?.dealerName || 'Jaipur Royal Enfield';
|
|
const dealerCode = dealerInfo?.dealerCode || 'RE-JP-009';
|
|
const activity = activityName || 'Activity';
|
|
const requestIdDisplay = requestNumber || 'RE-REQ-2024-CM-101';
|
|
const dueDateDisplay = dueDate
|
|
? formatDateTime(dueDate, { includeTime: false, format: 'short' })
|
|
: 'Jan 4, 2026';
|
|
|
|
const handleDownload = async () => {
|
|
if (onDownload) {
|
|
try {
|
|
setDownloading(true);
|
|
await onDownload();
|
|
toast.success('Credit note downloaded successfully');
|
|
} catch (error) {
|
|
console.error('Failed to download credit note:', error);
|
|
toast.error('Failed to download credit note. Please try again.');
|
|
} finally {
|
|
setDownloading(false);
|
|
}
|
|
} else {
|
|
// Default behavior: show info message
|
|
toast.info('Credit note will be automatically saved to Documents tab');
|
|
}
|
|
};
|
|
|
|
const handleSendToDealer = async () => {
|
|
if (onSendToDealer) {
|
|
try {
|
|
setSending(true);
|
|
await onSendToDealer();
|
|
toast.success('Credit note sent to dealer successfully');
|
|
onClose();
|
|
} catch (error) {
|
|
console.error('Failed to send credit note to dealer:', error);
|
|
toast.error('Failed to send credit note. Please try again.');
|
|
} finally {
|
|
setSending(false);
|
|
}
|
|
} else {
|
|
// Default behavior: show info message
|
|
toast.info('Email notification will be sent to dealer with credit note attachment');
|
|
}
|
|
};
|
|
|
|
const formatCurrency = (amount: number) => {
|
|
return `₹${amount.toLocaleString('en-IN', { minimumFractionDigits: 0, maximumFractionDigits: 0 })}`;
|
|
};
|
|
|
|
return (
|
|
<Dialog open={isOpen} onOpenChange={onClose}>
|
|
<DialogContent className="sm:max-w-lg max-w-4xl max-h-[90vh] overflow-y-auto">
|
|
<DialogHeader>
|
|
<DialogTitle className="font-semibold flex items-center gap-2 text-2xl">
|
|
<Receipt className="w-6 h-6 text-[--re-green]" />
|
|
Credit Note from SAP
|
|
</DialogTitle>
|
|
<DialogDescription className="text-base">
|
|
Review and send credit note to dealer
|
|
</DialogDescription>
|
|
</DialogHeader>
|
|
|
|
<div className="space-y-5 py-4">
|
|
{hasCreditNote ? (
|
|
<>
|
|
{/* Credit Note Document Card */}
|
|
<div className="bg-gradient-to-r from-green-50 to-emerald-50 border-2 border-green-200 rounded-lg p-6">
|
|
<div className="flex items-center justify-between mb-4">
|
|
<div>
|
|
<h3 className="font-semibold text-green-900 text-xl mb-1">Royal Enfield</h3>
|
|
<p className="text-sm text-green-700">Credit Note Document</p>
|
|
</div>
|
|
<Badge className="bg-green-600 text-white px-4 py-2 text-base">
|
|
<CircleCheckBig className="w-4 h-4 mr-2" />
|
|
{status === 'APPROVED' || status === 'CONFIRMED' ? 'Approved' : status === 'ISSUED' ? 'Issued' : status === 'SENT' ? 'Sent' : 'Pending'}
|
|
</Badge>
|
|
</div>
|
|
<div className="grid grid-cols-2 gap-4 mt-4">
|
|
<div className="bg-white rounded-lg p-3 border border-green-100">
|
|
<Label className="font-medium text-xs text-gray-600 uppercase tracking-wider flex items-center gap-1">
|
|
<Hash className="w-3 h-3" />
|
|
Credit Note Number
|
|
</Label>
|
|
<p className="font-bold text-gray-900 mt-1 text-lg">{creditNoteNumber}</p>
|
|
</div>
|
|
<div className="bg-white rounded-lg p-3 border border-green-100">
|
|
<Label className="font-medium text-xs text-gray-600 uppercase tracking-wider flex items-center gap-1">
|
|
<Calendar className="w-3 h-3" />
|
|
Issue Date
|
|
</Label>
|
|
<p className="font-semibold text-gray-900 mt-1">{creditNoteDate}</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Credit Note Amount */}
|
|
<div className="bg-blue-50 border-2 border-blue-200 rounded-lg p-5">
|
|
<Label className="font-medium text-xs text-gray-600 uppercase tracking-wider flex items-center gap-1 mb-3">
|
|
<DollarSign className="w-4 h-4" />
|
|
Credit Note Amount
|
|
</Label>
|
|
<p className="text-4xl font-bold text-blue-700">{formatCurrency(creditNoteAmount)}</p>
|
|
</div>
|
|
</>
|
|
) : (
|
|
/* No Credit Note Available */
|
|
<div className="bg-gray-50 border-2 border-gray-300 rounded-lg p-8 text-center">
|
|
<div className="flex flex-col items-center justify-center space-y-4">
|
|
<div className="w-16 h-16 bg-gray-200 rounded-full flex items-center justify-center">
|
|
<Receipt className="w-8 h-8 text-gray-400" />
|
|
</div>
|
|
<div>
|
|
<h3 className="text-lg font-semibold text-gray-700 mb-2">No Credit Note Available</h3>
|
|
<p className="text-sm text-gray-500">
|
|
Credit note has not been generated yet. Please wait for the credit note to be generated from DMS.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
)}
|
|
|
|
{/* Dealer Information */}
|
|
<div className="bg-purple-50 border-2 border-purple-200 rounded-lg p-5">
|
|
<h3 className="font-semibold text-purple-900 mb-4 flex items-center gap-2">
|
|
<Building className="w-5 h-5" />
|
|
Dealer Information
|
|
</h3>
|
|
<div className="grid grid-cols-2 gap-4">
|
|
<div className="bg-white rounded-lg p-3 border border-purple-100">
|
|
<Label className="flex items-center gap-2 font-medium text-xs text-gray-600 uppercase tracking-wider">
|
|
Dealer Name
|
|
</Label>
|
|
<p className="font-semibold text-gray-900 mt-1">{dealerName}</p>
|
|
</div>
|
|
<div className="bg-white rounded-lg p-3 border border-purple-100">
|
|
<Label className="flex items-center gap-2 font-medium text-xs text-gray-600 uppercase tracking-wider">
|
|
Dealer Code
|
|
</Label>
|
|
<p className="font-semibold text-gray-900 mt-1">{dealerCode}</p>
|
|
</div>
|
|
<div className="bg-white rounded-lg p-3 border border-purple-100">
|
|
<Label className="flex items-center gap-2 font-medium text-xs text-gray-600 uppercase tracking-wider">
|
|
Activity
|
|
</Label>
|
|
<p className="font-semibold text-gray-900 mt-1">{activity}</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Reference Details */}
|
|
<div className="bg-gray-50 border border-gray-200 rounded-lg p-4">
|
|
<h3 className="font-semibold text-gray-900 mb-3 flex items-center gap-2">
|
|
<FileText className="w-4 h-4" />
|
|
Reference Details
|
|
</h3>
|
|
<div className="grid grid-cols-2 gap-3 text-sm">
|
|
<div>
|
|
<Label className="flex items-center gap-2 font-medium text-xs text-gray-600">
|
|
Request ID
|
|
</Label>
|
|
<p className="font-medium text-gray-900 mt-1">{requestIdDisplay}</p>
|
|
</div>
|
|
<div>
|
|
<Label className="flex items-center gap-2 font-medium text-xs text-gray-600">
|
|
Due Date
|
|
</Label>
|
|
<p className="font-medium text-gray-900 mt-1">{dueDateDisplay}</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Available Actions Info */}
|
|
<div className="bg-blue-50 border border-blue-200 rounded-lg p-4 flex items-start gap-3">
|
|
<FileText className="w-5 h-5 text-blue-600 flex-shrink-0 mt-0.5" />
|
|
<div className="text-sm text-blue-800">
|
|
<p className="font-semibold mb-2">Available Actions</p>
|
|
<ul className="list-disc list-inside space-y-1 text-xs">
|
|
<li>
|
|
<strong>Download:</strong> Credit note will be automatically saved to Documents tab
|
|
</li>
|
|
<li>
|
|
<strong>Send to Dealer:</strong> Email notification will be sent to dealer with credit note attachment
|
|
</li>
|
|
<li>All actions will be recorded in activity trail for audit purposes</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<DialogFooter className="flex-col-reverse gap-2 sm:flex-row flex items-center justify-between sm:justify-between">
|
|
<Button
|
|
variant="outline"
|
|
onClick={onClose}
|
|
disabled={downloading || sending}
|
|
className="border-2"
|
|
>
|
|
Close
|
|
</Button>
|
|
<div className="flex gap-2">
|
|
{hasCreditNote && (
|
|
<>
|
|
<Button
|
|
variant="outline"
|
|
onClick={handleDownload}
|
|
disabled={downloading || sending}
|
|
className="border-blue-600 text-blue-600 hover:bg-blue-50"
|
|
>
|
|
<Download className="w-4 h-4 mr-2" />
|
|
{downloading ? 'Downloading...' : 'Download'}
|
|
</Button>
|
|
<Button
|
|
onClick={handleSendToDealer}
|
|
disabled={downloading || sending}
|
|
className="bg-green-600 hover:bg-green-700 text-white shadow-md"
|
|
>
|
|
<Send className="w-4 h-4 mr-2" />
|
|
{sending ? 'Sending...' : 'Send to Dealer'}
|
|
</Button>
|
|
</>
|
|
)}
|
|
</div>
|
|
</DialogFooter>
|
|
</DialogContent>
|
|
</Dialog>
|
|
);
|
|
}
|