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: '',
|
title: '',
|
||||||
itemCode: '',
|
itemCode: '',
|
||||||
taxationType: '',
|
taxationType: '',
|
||||||
sapRefNo: ''
|
sapRefNo: '',
|
||||||
|
creditPostingOn: ''
|
||||||
});
|
});
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -75,7 +76,8 @@ export function ActivityTypeManager() {
|
|||||||
title: '',
|
title: '',
|
||||||
itemCode: '',
|
itemCode: '',
|
||||||
taxationType: '',
|
taxationType: '',
|
||||||
sapRefNo: ''
|
sapRefNo: '',
|
||||||
|
creditPostingOn: ''
|
||||||
});
|
});
|
||||||
setEditingActivityType(null);
|
setEditingActivityType(null);
|
||||||
setShowAddDialog(true);
|
setShowAddDialog(true);
|
||||||
@ -86,7 +88,8 @@ export function ActivityTypeManager() {
|
|||||||
title: activityType.title,
|
title: activityType.title,
|
||||||
itemCode: activityType.itemCode || '',
|
itemCode: activityType.itemCode || '',
|
||||||
taxationType: activityType.taxationType || '',
|
taxationType: activityType.taxationType || '',
|
||||||
sapRefNo: activityType.sapRefNo || ''
|
sapRefNo: activityType.sapRefNo || '',
|
||||||
|
creditPostingOn: activityType.creditPostingOn || ''
|
||||||
});
|
});
|
||||||
setEditingActivityType(activityType);
|
setEditingActivityType(activityType);
|
||||||
setShowAddDialog(true);
|
setShowAddDialog(true);
|
||||||
@ -96,8 +99,8 @@ export function ActivityTypeManager() {
|
|||||||
try {
|
try {
|
||||||
setError(null);
|
setError(null);
|
||||||
|
|
||||||
if (!formData.title.trim() || !formData.taxationType.trim() || !formData.sapRefNo.trim()) {
|
if (!formData.title.trim() || !formData.taxationType.trim() || !formData.sapRefNo.trim() || !formData.creditPostingOn.trim()) {
|
||||||
setError('Title, Taxation Type, and Claim Document Type (SAP Ref) are required');
|
setError('Title, Taxation Type, Credit Posting On, and Claim Document Type (SAP Ref) are required');
|
||||||
toast.error('Please fill in all mandatory fields');
|
toast.error('Please fill in all mandatory fields');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -106,7 +109,8 @@ export function ActivityTypeManager() {
|
|||||||
title: formData.title.trim(),
|
title: formData.title.trim(),
|
||||||
itemCode: formData.itemCode.trim() || null,
|
itemCode: formData.itemCode.trim() || null,
|
||||||
taxationType: formData.taxationType.trim(),
|
taxationType: formData.taxationType.trim(),
|
||||||
sapRefNo: formData.sapRefNo.trim()
|
sapRefNo: formData.sapRefNo.trim(),
|
||||||
|
creditPostingOn: formData.creditPostingOn.trim()
|
||||||
};
|
};
|
||||||
|
|
||||||
if (editingActivityType) {
|
if (editingActivityType) {
|
||||||
@ -270,7 +274,10 @@ export function ActivityTypeManager() {
|
|||||||
{activityType.sapRefNo && (
|
{activityType.sapRefNo && (
|
||||||
<span className="font-medium">SAP Ref: <span className="text-slate-900">{activityType.sapRefNo}</span></span>
|
<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>
|
<span className="text-slate-500 italic">No additional details</span>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
@ -433,6 +440,28 @@ export function ActivityTypeManager() {
|
|||||||
/>
|
/>
|
||||||
<p className="text-xs text-slate-500">Required SAP reference number for CSV generation</p>
|
<p className="text-xs text-slate-500">Required SAP reference number for CSV generation</p>
|
||||||
</div>
|
</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>
|
</div>
|
||||||
|
|
||||||
<DialogFooter className="gap-3 pt-4 border-t border-slate-100 px-6 pb-6 flex-shrink-0">
|
<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>
|
||||||
<Button
|
<Button
|
||||||
onClick={handleSave}
|
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"
|
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" />
|
<FileText className="w-4 h-4 mr-2" />
|
||||||
|
|||||||
@ -149,6 +149,7 @@ export function ClaimManagementWizard({ onBack, onSubmit }: ClaimManagementWizar
|
|||||||
dealerEmail: '',
|
dealerEmail: '',
|
||||||
dealerPhone: '',
|
dealerPhone: '',
|
||||||
dealerAddress: '',
|
dealerAddress: '',
|
||||||
|
dealerItemGroup: '', // For validation
|
||||||
activityDate: undefined as Date | undefined,
|
activityDate: undefined as Date | undefined,
|
||||||
location: '',
|
location: '',
|
||||||
requestDescription: '',
|
requestDescription: '',
|
||||||
@ -227,25 +228,57 @@ export function ClaimManagementWizard({ onBack, onSubmit }: ClaimManagementWizar
|
|||||||
|
|
||||||
// Validate period dates
|
// Validate period dates
|
||||||
if (field === 'periodStartDate') {
|
if (field === 'periodStartDate') {
|
||||||
// If start date is selected and end date exists, validate end date
|
|
||||||
if (value && updated.periodEndDate && value > updated.periodEndDate) {
|
if (value && updated.periodEndDate && value > updated.periodEndDate) {
|
||||||
// Clear end date if it's before the new start date
|
|
||||||
updated.periodEndDate = undefined;
|
updated.periodEndDate = undefined;
|
||||||
toast.error('End date must be on or after the start date. End date has been cleared.');
|
toast.error('End date must be on or after the start date. End date has been cleared.');
|
||||||
}
|
}
|
||||||
} else if (field === 'periodEndDate') {
|
} else if (field === 'periodEndDate') {
|
||||||
// If end date is selected and start date exists, validate end date
|
|
||||||
if (value && updated.periodStartDate && value < updated.periodStartDate) {
|
if (value && updated.periodStartDate && value < updated.periodStartDate) {
|
||||||
toast.error('End date must be on or after the start date.');
|
toast.error('End date must be on or after the start date.');
|
||||||
// Don't update the end date if it's invalid
|
|
||||||
return prev;
|
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;
|
return updated;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Helper to update multiple fields at once
|
||||||
|
const updateMultipleFormData = (updates: Record<string, any>) => {
|
||||||
|
setFormData(prev => ({ ...prev, ...updates }));
|
||||||
|
};
|
||||||
|
|
||||||
const isStepValid = () => {
|
const isStepValid = () => {
|
||||||
switch (currentStep) {
|
switch (currentStep) {
|
||||||
case 1:
|
case 1:
|
||||||
@ -331,12 +364,58 @@ export function ClaimManagementWizard({ onBack, onSubmit }: ClaimManagementWizar
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dealer is logged in, update form data
|
// 1a. Validate Category Match (Frontend UX)
|
||||||
updateFormData('dealerCode', verifiedDealer.dealerCode);
|
if (formData.activityType) {
|
||||||
updateFormData('dealerName', verifiedDealer.dealerName || verifiedDealer.displayName);
|
const selectedActivity = activityTypes.find(t => t.title === formData.activityType);
|
||||||
updateFormData('dealerEmail', verifiedDealer.email || '');
|
if (selectedActivity && selectedActivity.creditPostingOn) {
|
||||||
updateFormData('dealerPhone', verifiedDealer.phone || '');
|
const activityCategory = selectedActivity.creditPostingOn.toLowerCase();
|
||||||
updateFormData('dealerAddress', ''); // Address not available in API response
|
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
|
// Clear search input and results
|
||||||
setDealerSearchInput(verifiedDealer.dealerName || verifiedDealer.displayName);
|
setDealerSearchInput(verifiedDealer.dealerName || verifiedDealer.displayName);
|
||||||
|
|||||||
@ -44,6 +44,7 @@ export interface ActivityType {
|
|||||||
itemCode?: string | null;
|
itemCode?: string | null;
|
||||||
taxationType?: string | null;
|
taxationType?: string | null;
|
||||||
sapRefNo?: string | null;
|
sapRefNo?: string | null;
|
||||||
|
creditPostingOn?: string | null;
|
||||||
isActive?: boolean;
|
isActive?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -26,6 +26,7 @@ export interface DealerInfo {
|
|||||||
city?: string | null;
|
city?: string | null;
|
||||||
dealerPrincipalName?: string | null;
|
dealerPrincipalName?: string | null;
|
||||||
dealerPrincipalEmailId?: string | null;
|
dealerPrincipalEmailId?: string | null;
|
||||||
|
itemGroup?: string | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user