SAP team asked to map credit posting on based on the item group Vehicle/Spares have been implemented also points like delare code pading and nomenclature changes added
This commit is contained in:
parent
ef95d4af09
commit
85ddb72143
@ -48,7 +48,8 @@ export function ActivityTypeManager() {
|
||||
title: '',
|
||||
itemCode: '',
|
||||
taxationType: '',
|
||||
sapRefNo: ''
|
||||
sapRefNo: '',
|
||||
creditPostingOn: ''
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
@ -75,7 +76,8 @@ export function ActivityTypeManager() {
|
||||
title: '',
|
||||
itemCode: '',
|
||||
taxationType: '',
|
||||
sapRefNo: ''
|
||||
sapRefNo: '',
|
||||
creditPostingOn: ''
|
||||
});
|
||||
setEditingActivityType(null);
|
||||
setShowAddDialog(true);
|
||||
@ -86,7 +88,8 @@ export function ActivityTypeManager() {
|
||||
title: activityType.title,
|
||||
itemCode: activityType.itemCode || '',
|
||||
taxationType: activityType.taxationType || '',
|
||||
sapRefNo: activityType.sapRefNo || ''
|
||||
sapRefNo: activityType.sapRefNo || '',
|
||||
creditPostingOn: activityType.creditPostingOn || ''
|
||||
});
|
||||
setEditingActivityType(activityType);
|
||||
setShowAddDialog(true);
|
||||
@ -96,8 +99,8 @@ export function ActivityTypeManager() {
|
||||
try {
|
||||
setError(null);
|
||||
|
||||
if (!formData.title.trim() || !formData.taxationType.trim() || !formData.sapRefNo.trim()) {
|
||||
setError('Title, Taxation Type, and Claim Document Type (SAP Ref) are required');
|
||||
if (!formData.title.trim() || !formData.taxationType.trim() || !formData.sapRefNo.trim() || !formData.creditPostingOn.trim()) {
|
||||
setError('Title, Taxation Type, Credit Posting On, and Claim Document Type (SAP Ref) are required');
|
||||
toast.error('Please fill in all mandatory fields');
|
||||
return;
|
||||
}
|
||||
@ -106,7 +109,8 @@ export function ActivityTypeManager() {
|
||||
title: formData.title.trim(),
|
||||
itemCode: formData.itemCode.trim() || null,
|
||||
taxationType: formData.taxationType.trim(),
|
||||
sapRefNo: formData.sapRefNo.trim()
|
||||
sapRefNo: formData.sapRefNo.trim(),
|
||||
creditPostingOn: formData.creditPostingOn.trim()
|
||||
};
|
||||
|
||||
if (editingActivityType) {
|
||||
@ -270,7 +274,10 @@ export function ActivityTypeManager() {
|
||||
{activityType.sapRefNo && (
|
||||
<span className="font-medium">SAP Ref: <span className="text-slate-900">{activityType.sapRefNo}</span></span>
|
||||
)}
|
||||
{!activityType.itemCode && !activityType.taxationType && !activityType.sapRefNo && (
|
||||
{activityType.creditPostingOn && (
|
||||
<span className="font-medium">Credit Posting On: <Badge variant="secondary" className="ml-1 bg-slate-200 text-slate-800">{activityType.creditPostingOn}</Badge></span>
|
||||
)}
|
||||
{!activityType.itemCode && !activityType.taxationType && !activityType.sapRefNo && !activityType.creditPostingOn && (
|
||||
<span className="text-slate-500 italic">No additional details</span>
|
||||
)}
|
||||
</div>
|
||||
@ -433,6 +440,28 @@ export function ActivityTypeManager() {
|
||||
/>
|
||||
<p className="text-xs text-slate-500">Required SAP reference number for CSV generation</p>
|
||||
</div>
|
||||
|
||||
{/* Credit Posting On Field */}
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="creditPostingOn" className="text-sm font-semibold text-slate-900 flex items-center gap-1">
|
||||
Credit Posting On <span className="text-red-500">*</span>
|
||||
</Label>
|
||||
<Select
|
||||
value={formData.creditPostingOn}
|
||||
onValueChange={(value) => setFormData({ ...formData, creditPostingOn: value })}
|
||||
>
|
||||
<SelectTrigger id="creditPostingOn" className="h-11 border-slate-300 focus:border-re-green focus:ring-2 focus:ring-re-green/20 rounded-lg transition-all shadow-sm">
|
||||
<SelectValue placeholder="Select Credit Posting Group" />
|
||||
</SelectTrigger>
|
||||
<SelectContent className="rounded-lg">
|
||||
<SelectItem value="Vehicle" className="p-3">Vehicle</SelectItem>
|
||||
<SelectItem value="Spares" className="p-3">Spares</SelectItem>
|
||||
<SelectItem value="GMA" className="p-3">GMA</SelectItem>
|
||||
<SelectItem value="Apparel" className="p-3">Apparel</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<p className="text-xs text-slate-500">Categorize for dealer validation (Vehicle, Spares, GMA, or Apparel)</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<DialogFooter className="gap-3 pt-4 border-t border-slate-100 px-6 pb-6 flex-shrink-0">
|
||||
@ -445,7 +474,7 @@ export function ActivityTypeManager() {
|
||||
</Button>
|
||||
<Button
|
||||
onClick={handleSave}
|
||||
disabled={!formData.title.trim() || !formData.taxationType || !formData.sapRefNo.trim()}
|
||||
disabled={!formData.title.trim() || !formData.taxationType || !formData.sapRefNo.trim() || !formData.creditPostingOn}
|
||||
className="h-11 bg-re-green hover:bg-re-green/90 text-white shadow-md hover:shadow-lg transition-all disabled:opacity-50 disabled:cursor-not-allowed"
|
||||
>
|
||||
<FileText className="w-4 h-4 mr-2" />
|
||||
|
||||
@ -149,6 +149,7 @@ export function ClaimManagementWizard({ onBack, onSubmit }: ClaimManagementWizar
|
||||
dealerEmail: '',
|
||||
dealerPhone: '',
|
||||
dealerAddress: '',
|
||||
dealerItemGroup: '', // For validation
|
||||
activityDate: undefined as Date | undefined,
|
||||
location: '',
|
||||
requestDescription: '',
|
||||
@ -227,25 +228,57 @@ export function ClaimManagementWizard({ onBack, onSubmit }: ClaimManagementWizar
|
||||
|
||||
// Validate period dates
|
||||
if (field === 'periodStartDate') {
|
||||
// If start date is selected and end date exists, validate end date
|
||||
if (value && updated.periodEndDate && value > updated.periodEndDate) {
|
||||
// Clear end date if it's before the new start date
|
||||
updated.periodEndDate = undefined;
|
||||
toast.error('End date must be on or after the start date. End date has been cleared.');
|
||||
}
|
||||
} else if (field === 'periodEndDate') {
|
||||
// If end date is selected and start date exists, validate end date
|
||||
if (value && updated.periodStartDate && value < updated.periodStartDate) {
|
||||
toast.error('End date must be on or after the start date.');
|
||||
// Don't update the end date if it's invalid
|
||||
return prev;
|
||||
}
|
||||
}
|
||||
|
||||
// 1b. Validate Activity Type change against already selected Dealer
|
||||
if (field === 'activityType' && updated.dealerCode) {
|
||||
const selectedActivity = activityTypes.find(t => t.title === value);
|
||||
if (selectedActivity) {
|
||||
if (selectedActivity.creditPostingOn) {
|
||||
const activityCategory = selectedActivity.creditPostingOn.toLowerCase();
|
||||
const dealerGroup = (updated.dealerItemGroup || '').toLowerCase();
|
||||
|
||||
// If we have a dealer group, validate it
|
||||
if (dealerGroup) {
|
||||
let isMatch = false;
|
||||
if (activityCategory === 'vehicle' && dealerGroup === 'vehicle') isMatch = true;
|
||||
else if (activityCategory === 'spares' && dealerGroup === 'spares') isMatch = true;
|
||||
else if (activityCategory === 'gma' && dealerGroup === 'gma') isMatch = true;
|
||||
else if (activityCategory === 'apparel' && dealerGroup === 'apparel') isMatch = true;
|
||||
else if (activityCategory === dealerGroup) isMatch = true;
|
||||
|
||||
if (!isMatch) {
|
||||
toast.error(`incorrect Delercode for selected service group`, {
|
||||
description: `Activity requires ${selectedActivity.creditPostingOn}, but already selected dealer is ${updated.dealerItemGroup}`,
|
||||
duration: 6000
|
||||
});
|
||||
return prev;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
console.warn(`[ClaimWizard] Activity type "${value}" is missing creditPostingOn configuration.`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return updated;
|
||||
});
|
||||
};
|
||||
|
||||
// Helper to update multiple fields at once
|
||||
const updateMultipleFormData = (updates: Record<string, any>) => {
|
||||
setFormData(prev => ({ ...prev, ...updates }));
|
||||
};
|
||||
|
||||
const isStepValid = () => {
|
||||
switch (currentStep) {
|
||||
case 1:
|
||||
@ -331,12 +364,58 @@ export function ClaimManagementWizard({ onBack, onSubmit }: ClaimManagementWizar
|
||||
return;
|
||||
}
|
||||
|
||||
// Dealer is logged in, update form data
|
||||
updateFormData('dealerCode', verifiedDealer.dealerCode);
|
||||
updateFormData('dealerName', verifiedDealer.dealerName || verifiedDealer.displayName);
|
||||
updateFormData('dealerEmail', verifiedDealer.email || '');
|
||||
updateFormData('dealerPhone', verifiedDealer.phone || '');
|
||||
updateFormData('dealerAddress', ''); // Address not available in API response
|
||||
// 1a. Validate Category Match (Frontend UX)
|
||||
if (formData.activityType) {
|
||||
const selectedActivity = activityTypes.find(t => t.title === formData.activityType);
|
||||
if (selectedActivity && selectedActivity.creditPostingOn) {
|
||||
const activityCategory = selectedActivity.creditPostingOn.toLowerCase();
|
||||
const dealerGroup = (verifiedDealer.itemGroup || '').toLowerCase();
|
||||
|
||||
let isMatch = false;
|
||||
// Vehicle matches Vehicle
|
||||
if (activityCategory === 'vehicle' && dealerGroup === 'vehicle') {
|
||||
isMatch = true;
|
||||
}
|
||||
// Spares matches Spares (Strict)
|
||||
else if (activityCategory === 'spares' && dealerGroup === 'spares') {
|
||||
isMatch = true;
|
||||
}
|
||||
// GMA matches GMA (Strict)
|
||||
else if (activityCategory === 'gma' && dealerGroup === 'gma') {
|
||||
isMatch = true;
|
||||
}
|
||||
// Apparel matches Apparel (Strict)
|
||||
else if (activityCategory === 'apparel' && dealerGroup === 'apparel') {
|
||||
isMatch = true;
|
||||
}
|
||||
// Direct match fallback
|
||||
else if (activityCategory === dealerGroup) {
|
||||
isMatch = true;
|
||||
}
|
||||
|
||||
if (!isMatch) {
|
||||
toast.error(`incorrect Delercode for selected service group`, {
|
||||
description: `Activity requires ${selectedActivity.creditPostingOn}, but dealer is ${verifiedDealer.itemGroup || 'N/A'}`,
|
||||
duration: 6000
|
||||
});
|
||||
// Clear the selection
|
||||
setDealerSearchInput('');
|
||||
setDealerSearchResults([]);
|
||||
setVerifyingDealer(false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Dealer is logged in, update form data in one batch
|
||||
updateMultipleFormData({
|
||||
dealerCode: verifiedDealer.dealerCode,
|
||||
dealerName: verifiedDealer.dealerName || verifiedDealer.displayName,
|
||||
dealerEmail: verifiedDealer.email || '',
|
||||
dealerPhone: verifiedDealer.phone || '',
|
||||
dealerAddress: '',
|
||||
dealerItemGroup: verifiedDealer.itemGroup || ''
|
||||
});
|
||||
|
||||
// Clear search input and results
|
||||
setDealerSearchInput(verifiedDealer.dealerName || verifiedDealer.displayName);
|
||||
|
||||
@ -44,6 +44,7 @@ export interface ActivityType {
|
||||
itemCode?: string | null;
|
||||
taxationType?: string | null;
|
||||
sapRefNo?: string | null;
|
||||
creditPostingOn?: string | null;
|
||||
isActive?: boolean;
|
||||
}
|
||||
|
||||
|
||||
@ -26,6 +26,7 @@ export interface DealerInfo {
|
||||
city?: string | null;
|
||||
dealerPrincipalName?: string | null;
|
||||
dealerPrincipalEmailId?: string | null;
|
||||
itemGroup?: string | null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Loading…
Reference in New Issue
Block a user