UNPKG

omnipay-savings-sdk

Version:

Omnipay Savings SDK

260 lines (228 loc) 7.83 kB
import { FrequencyType, getFrequencyEnum, DeductionNameType, TypesOfDeductionType, TypesOfDeductionFrequencyType, } from '../../../utils'; import {SavingsDetailType} from '../../../utils/types'; import {UpdateSavingsParams} from '../../../services/types'; // Common types and constants export const typesOfDeduction: TypesOfDeductionType[] = [ { name: 'Percentage', id: '0', }, { name: 'Flat rate', id: '1', }, ]; export const frequencies: TypesOfDeductionFrequencyType[] = [ { name: 'One-time', id: '0', }, { name: 'Reoccurring', id: '1', }, ]; // Helper function to convert frequency ID to FrequencyType export const getFrequencyTypeFromId = (frequencyId: number): FrequencyType => { switch (frequencyId) { case 1: return 'Daily'; case 2: return 'Weekly'; case 3: return 'Monthly'; case 4: return 'Save as you collect'; default: return '' as FrequencyType; } }; // Helper function to check if there are actual changes between new data and existing data export const checkForChanges = (newData: UpdateSavingsParams, existingData: SavingsDetailType): boolean => { // Helper function to format dates for comparison const formatDateForComparison = (dateString: string) => { if (!dateString) {return '';} const date = new Date(dateString); return date.toISOString().split('T')[0]; // YYYY-MM-DD format }; // Check basic fields if (newData.accountName !== existingData.accountName) {return true;} if (newData.savingTarget !== existingData.savingTarget * 100) {return true;} if (newData.narration !== (existingData.narration || '')) {return true;} if (newData.autoSave !== existingData.autoSave) {return true;} if (newData.isInterestDisabled !== existingData.isInterestDisabled) {return true;} // Check color change (case-insensitive) const newColor = (newData.savingsPlanColor || '').toLowerCase(); const existingColor = (existingData.savingsPlanColor || '').toLowerCase(); if (newColor !== existingColor) {return true;} // Check frequency if auto-save is enabled if (newData.autoSave) { if (newData.frequency !== existingData.savingsFrequencyId) {return true;} // Check periodic amount for non-SaveAsYouCollect frequencies if (newData.frequency !== 4 && newData.periodicSavingsAmount) { if (newData.periodicSavingsAmount !== existingData.periodicSavingsAmount * 100) {return true;} } // Check dates if (newData.startDate && existingData.startDate && formatDateForComparison(newData.startDate) !== formatDateForComparison(existingData.startDate)) {return true;} if (newData.endDate && existingData.endDate && formatDateForComparison(newData.endDate) !== formatDateForComparison(existingData.endDate)) {return true;} } return false; // No changes detected }; // Helper function to ensure the color exists in available options export const getValidSavingsColor = (color?: string, editMode?: boolean, availableColors?: string[]) => { if (!color || !editMode) {return '';} // Import savingsOptionsColors here to avoid circular dependency const {savingsOptionsColors} = require('../../../utils'); const colorsToCheck = availableColors || savingsOptionsColors; // Check if the color exists in the available options (case-insensitive) const foundColor = colorsToCheck.find((option: string) => option.toLowerCase() === color.toLowerCase() ); if (foundColor) { return foundColor; } // If not found, use the first option as fallback return colorsToCheck[0]; // Fallback to first available color }; // Common validation errors type export interface ValidationError { field: string; message: string; } // Base validation for common fields export const validateCommonFields = ( name: string, amount: string, savingsColor: string ): ValidationError[] => { const validationErrors: ValidationError[] = []; // Color validation (first in form order) if (savingsColor.trim().length < 1) { validationErrors.push({ field: 'savingsColor', message: 'Please select a color for your savings', }); } // Name validation if (name.trim().length < 1) { validationErrors.push({ field: 'name', message: 'Please enter a name', }); } // Amount validation if (Number(amount) <= 0 || isNaN(Number(amount))) { validationErrors.push({ field: 'amount', message: 'Please enter a valid amount', }); } return validationErrors; }; // Flexible savings specific validation export const validateFlexibleSavings = ( autoSave: boolean, selectedFrequency: FrequencyType, periodicSavingsAmount: string, amountPercentage: string, selectedTypeOfDeduction: DeductionNameType, startDate: any, endDate: any ): ValidationError[] => { const validationErrors: ValidationError[] = []; if (autoSave) { // Frequency validation if (selectedFrequency.length < 1) { validationErrors.push({ field: 'frequency', message: 'Please select a frequency', }); } // Periodic amount validation for non-SaveAsYouCollect frequencies if (getFrequencyEnum(selectedFrequency) !== 4) { if ( Number(periodicSavingsAmount) <= 0 || isNaN(Number(periodicSavingsAmount)) ) { validationErrors.push({ field: 'periodicSavingsAmount', message: 'Please enter a valid amount', }); } } else { // SaveAsYouCollect specific validation if (!amountPercentage) { validationErrors.push({ field: 'amountPercentage', message: selectedTypeOfDeduction === 'Flat rate' ? 'Please enter a valid amount' : 'Please enter a valid percentage', }); } } // Date validations (only required when autoSave is enabled) if (!startDate) { validationErrors.push({ field: 'startDate', message: 'Please select a start date', }); } if (!endDate) { validationErrors.push({ field: 'endDate', message: 'Please select an end date', }); } } return validationErrors; }; // Locked savings specific validation export const validateLockedSavings = ( lockDurationDays: number, minimumLockDurationDays: number, editMode?: boolean, selectedTier?: any, maxDaysAvailable?: number ): ValidationError[] => { const validationErrors: ValidationError[] = []; if (!editMode) { // First check if a tier is selected if (!selectedTier) { validationErrors.push({ field: 'tierSelection', message: 'Please choose how long you want to save for', }); return validationErrors; // Return early if no tier selected } // Lock duration validation if (!lockDurationDays || lockDurationDays <= 0) { validationErrors.push({ field: 'lockDurationDays', message: 'Please enter a valid lock duration', }); } else if (maxDaysAvailable && lockDurationDays > maxDaysAvailable) { // Prevent values above maximum available range validationErrors.push({ field: 'lockDurationDays', message: `Lock duration cannot exceed ${maxDaysAvailable} days`, }); } else if (lockDurationDays < selectedTier.minDays || lockDurationDays > selectedTier.maxDays) { validationErrors.push({ field: 'lockDurationDays', message: `Duration must be between ${selectedTier.minDays} and ${selectedTier.maxDays} days for the selected duration range`, }); } else if (lockDurationDays < minimumLockDurationDays) { validationErrors.push({ field: 'lockDurationDays', message: `Lock duration must be at least ${minimumLockDurationDays} days`, }); } } return validationErrors; };