mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-30 09:58:12 +00:00
Boarding, payment methods, journey direction on seat hold, and more updates
This commit is contained in:
@@ -0,0 +1,178 @@
|
||||
import { apiClient } from '@/lib/api-client';
|
||||
|
||||
export interface FareConfiguration {
|
||||
id: string;
|
||||
name: string;
|
||||
description?: string;
|
||||
effective_date: string;
|
||||
expiry_date?: string;
|
||||
is_active: boolean;
|
||||
is_default: boolean;
|
||||
created_by?: string;
|
||||
approved_by?: string;
|
||||
approved_at?: string;
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
rate_rules_count: number;
|
||||
components_count: number;
|
||||
age_rules_count: number;
|
||||
rateRules?: any[];
|
||||
components?: any[];
|
||||
ageRules?: any[];
|
||||
}
|
||||
|
||||
export interface CreateFareConfigurationRequest {
|
||||
name: string;
|
||||
description?: string;
|
||||
effectiveDate: string;
|
||||
expiryDate?: string;
|
||||
rateRules: RateRule[];
|
||||
components: FareComponent[];
|
||||
ageRules: AgeRule[];
|
||||
isDefault?: boolean;
|
||||
}
|
||||
|
||||
export interface RateRule {
|
||||
nationalityType: 'LOCAL' | 'INTERNATIONAL';
|
||||
coachType: 'REGULAR_SEAT' | 'ECONOMY_BED' | 'VIP_BED';
|
||||
bedPosition?: 'UPPER' | 'MIDDLE' | 'LOWER';
|
||||
ratePerKmMinor: number;
|
||||
isActive?: boolean;
|
||||
}
|
||||
|
||||
export interface FareComponent {
|
||||
componentType: 'INSURANCE' | 'PREMIUM' | 'SERVICE_CHARGE' | 'TAX' | 'DEMAND';
|
||||
componentName: string;
|
||||
calculationMethod: 'MULTIPLIER' | 'PERCENTAGE' | 'FIXED_AMOUNT';
|
||||
valueMinor?: number;
|
||||
percentageValue?: number;
|
||||
appliesTo: 'BASE_FARE' | 'SUBTOTAL' | 'TOTAL';
|
||||
applyOrder: number;
|
||||
isActive?: boolean;
|
||||
}
|
||||
|
||||
export interface AgeRule {
|
||||
ruleName: string;
|
||||
minAge: number;
|
||||
maxAge?: number;
|
||||
pricingType: 'FREE' | 'FULL_FARE' | 'DISCOUNTED';
|
||||
discountPercentage?: number;
|
||||
maxFreePassengers?: number;
|
||||
appliesToComponents?: boolean;
|
||||
isActive?: boolean;
|
||||
}
|
||||
|
||||
export interface TestScenario {
|
||||
distanceKm: number;
|
||||
nationality: string;
|
||||
coachType: 'REGULAR_SEAT' | 'ECONOMY_BED' | 'VIP_BED';
|
||||
bedPosition?: 'UPPER' | 'MIDDLE' | 'LOWER';
|
||||
adultCount: number;
|
||||
childCount?: number;
|
||||
promoCode?: string;
|
||||
loyaltyPoints?: number;
|
||||
}
|
||||
|
||||
export interface CalculationResult {
|
||||
baseFareMinor: number;
|
||||
componentsTotal: number;
|
||||
totalBeforeDiscounts: number;
|
||||
discountsTotal: number;
|
||||
finalTotalMinor: number;
|
||||
breakdown: Array<{
|
||||
step: string;
|
||||
description: string;
|
||||
amount: number;
|
||||
runningTotal: number;
|
||||
}>;
|
||||
currency: string;
|
||||
calculationTimestamp: string;
|
||||
}
|
||||
|
||||
export interface SystemStatus {
|
||||
configurableFaresEnabled: boolean;
|
||||
rolloutPercentage: number;
|
||||
totalConfigurations: number;
|
||||
activeConfiguration: string | null;
|
||||
activeConfigurationName: string | null;
|
||||
systemReady: boolean;
|
||||
}
|
||||
|
||||
export const configurableFareApi = {
|
||||
// Configuration Management
|
||||
getAllConfigurations: (): Promise<FareConfiguration[]> =>
|
||||
apiClient.get('/admin/fare-configurations'),
|
||||
|
||||
getConfigurationById: (id: string): Promise<FareConfiguration> =>
|
||||
apiClient.get(`/admin/fare-configurations/${id}`),
|
||||
|
||||
createConfiguration: (data: CreateFareConfigurationRequest): Promise<FareConfiguration> =>
|
||||
apiClient.post('/admin/fare-configurations', data),
|
||||
|
||||
updateConfiguration: (id: string, data: Partial<CreateFareConfigurationRequest>): Promise<FareConfiguration> =>
|
||||
apiClient.put(`/admin/fare-configurations/${id}`, data),
|
||||
|
||||
activateConfiguration: (id: string): Promise<{ success: boolean; message: string }> =>
|
||||
apiClient.post(`/admin/fare-configurations/${id}/activate`),
|
||||
|
||||
deleteConfiguration: (id: string): Promise<{ success: boolean; message: string }> =>
|
||||
apiClient.delete(`/admin/fare-configurations/${id}`),
|
||||
|
||||
testConfiguration: (id: string, scenario: TestScenario): Promise<CalculationResult> =>
|
||||
apiClient.post(`/admin/fare-configurations/${id}/test`, scenario),
|
||||
|
||||
getAuditTrail: (id: string): Promise<any[]> =>
|
||||
apiClient.get(`/admin/fare-configurations/${id}/audit`),
|
||||
|
||||
// Migration & Setup
|
||||
migrateLegacySystem: (dryRun: boolean = false): Promise<{
|
||||
scheduleFareRules: number;
|
||||
segmentFareRules: number;
|
||||
configurationsCreated: number;
|
||||
dryRun: boolean;
|
||||
}> =>
|
||||
apiClient.post('/admin/fare-migration/migrate-legacy', { dryRun }),
|
||||
|
||||
createNewFormulaConfiguration: (data: {
|
||||
name: string;
|
||||
description?: string;
|
||||
activateImmediately?: boolean;
|
||||
}): Promise<FareConfiguration> =>
|
||||
apiClient.post('/admin/fare-migration/create-new-formula', data),
|
||||
|
||||
completeSetup: (options: {
|
||||
activateNewFormula?: boolean;
|
||||
enableFeature?: boolean;
|
||||
} = {}): Promise<{
|
||||
migration: any;
|
||||
newConfiguration: FareConfiguration;
|
||||
featureEnabled: boolean;
|
||||
message: string;
|
||||
}> =>
|
||||
apiClient.post('/admin/fare-migration/complete-setup', options),
|
||||
|
||||
getSystemStatus: (): Promise<SystemStatus> =>
|
||||
apiClient.get('/admin/fare-migration/status'),
|
||||
|
||||
// System Control
|
||||
getFeatureStatus: (featureName: string = 'USE_CONFIGURABLE_FARES'): Promise<{
|
||||
enabled: boolean;
|
||||
config: Record<string, any>;
|
||||
}> =>
|
||||
apiClient.get(`/admin/fare-configurations/system/feature-status?feature=${featureName}`),
|
||||
|
||||
toggleFeature: (data: {
|
||||
featureName: string;
|
||||
enabled: boolean;
|
||||
config?: Record<string, any>;
|
||||
}): Promise<{ success: boolean; message: string }> =>
|
||||
apiClient.post('/admin/fare-configurations/system/toggle-feature', data),
|
||||
|
||||
enableConfigurableFares: (rolloutPercentage: number = 100): Promise<{ success: boolean; message: string }> =>
|
||||
apiClient.post('/admin/fare-configurations/system/enable-configurable-fares', { rolloutPercentage }),
|
||||
|
||||
disableConfigurableFares: (): Promise<{ success: boolean; message: string }> =>
|
||||
apiClient.post('/admin/fare-configurations/system/disable-configurable-fares'),
|
||||
};
|
||||
|
||||
export default configurableFareApi;
|
||||
@@ -113,6 +113,7 @@ export const fleetApi = {
|
||||
createCoach: (data: any) => apiClient.post<any>('/fleet/coaches', data),
|
||||
updateCoach: (id: string, data: any) => apiClient.patch<any>(`/fleet/coaches/${id}`, data),
|
||||
deleteCoach: (id: string) => apiClient.delete(`/fleet/coaches/${id}`),
|
||||
generateSeatMap: (data: any) => apiClient.post<any>('/fleet/seatmap/generate', data),
|
||||
};
|
||||
|
||||
// Schedules API
|
||||
@@ -165,6 +166,13 @@ export const paymentsApi = {
|
||||
getById: (id: string) => apiClient.get<any>(`/payments/${id}`),
|
||||
refund: (id: string, data: any) => apiClient.post<any>(`/payments/${id}/refund`, data),
|
||||
getProviders: () => apiClient.get<any[]>('/payments/providers'),
|
||||
getMethods: async () => {
|
||||
const response = await apiClient.get('/payments/methods');
|
||||
return (response as any)?.data || response || [];
|
||||
},
|
||||
addMethod: (data: any) => apiClient.post('/payments/methods', data),
|
||||
updateMethod: (id: string, data: any) => apiClient.patch(`/payments/methods/${id}`, data),
|
||||
deleteMethod: (id: string) => apiClient.delete(`/payments/methods/${id}`),
|
||||
};
|
||||
|
||||
// Tickets API
|
||||
@@ -182,6 +190,7 @@ export const ticketsApi = {
|
||||
},
|
||||
getById: (id: string) => apiClient.get<any>(`/tickets/${id}`),
|
||||
validate: (ticketId: string, data: any) => apiClient.post<any>(`/tickets/${ticketId}/validate`, data),
|
||||
scanAndBoard: (qrCodeOrRef: string, data: any) => apiClient.post<any>(`/tickets/scan-board/${encodeURIComponent(qrCodeOrRef)}`, data),
|
||||
regenerate: (ticketId: string) => apiClient.post<any>(`/tickets/${ticketId}/regenerate`),
|
||||
};
|
||||
|
||||
@@ -371,7 +380,7 @@ export const reportsApi = {
|
||||
const query = reportType ? `?type=${reportType}` : '';
|
||||
const response = await apiClient.get<any>(`/reports${query}`);
|
||||
if (Array.isArray(response)) return { items: response };
|
||||
return response?.data ? (Array.isArray(response.data) ? { items: response.data } : response) : { items: [] };
|
||||
return (response as any)?.data ? (Array.isArray((response as any).data) ? { items: (response as any).data } : response) : { items: [] };
|
||||
},
|
||||
};
|
||||
|
||||
@@ -383,7 +392,7 @@ export const packagesApi = {
|
||||
) as Record<string, string>;
|
||||
const query = new URLSearchParams(cleanParams).toString();
|
||||
const response = await apiClient.get<any>(`/packages/all${query ? `?${query}` : ''}`);
|
||||
if (response?.data) return Array.isArray(response.data) ? { items: response.data } : response;
|
||||
if ((response as any)?.data) return Array.isArray((response as any).data) ? { items: (response as any).data } : response;
|
||||
return Array.isArray(response) ? { items: response } : response;
|
||||
},
|
||||
getById: (id: string) => apiClient.get<any>(`/packages/${id}`),
|
||||
@@ -405,7 +414,7 @@ export const packageInquiriesApi = {
|
||||
) as Record<string, string>;
|
||||
const query = new URLSearchParams(cleanParams).toString();
|
||||
const response = await apiClient.get<any>(`/packages/inquiries${query ? `?${query}` : ''}`);
|
||||
if (response?.data) return Array.isArray(response.data) ? { items: response.data } : response;
|
||||
if ((response as any)?.data) return Array.isArray((response as any).data) ? { items: (response as any).data } : response;
|
||||
return Array.isArray(response) ? { items: response } : response;
|
||||
},
|
||||
create: (data: any) => apiClient.post<any>('/packages/inquiries', data),
|
||||
@@ -423,11 +432,12 @@ export const excessBaggageApi = {
|
||||
) as Record<string, string>;
|
||||
const query = new URLSearchParams(cleanParams).toString();
|
||||
const response = await apiClient.get<any>(`/agents/excess-baggage${query ? `?${query}` : ''}`);
|
||||
if (response?.data) return Array.isArray(response.data) ? { items: response.data } : response;
|
||||
if ((response as any)?.data) return Array.isArray((response as any).data) ? { items: (response as any).data } : response;
|
||||
return Array.isArray(response) ? { items: response } : response;
|
||||
},
|
||||
resendLink: (id: string) => apiClient.post<any>(`/agents/excess-baggage/${id}/resend`, {}),
|
||||
waive: (id: string, data: any) => apiClient.patch<any>(`/agents/excess-baggage/${id}/waive`, data),
|
||||
delete: (id: string) => apiClient.delete(`/agents/excess-baggage/${id}`),
|
||||
};
|
||||
|
||||
// System Config API
|
||||
|
||||
Reference in New Issue
Block a user