Skip to content

Cancellation Scenarios

How to calculate refunds for different cancellation types.


Cancellation Types

  1. Full Refund - Within cooling-off period (14 days)
  2. Pro-Rata Refund - After cooling-off, refund unused time
  3. No Refund - Post-expiry or specific business rules

Scenario 1: Cooling-Off Cancellation

Customer cancels within 14 days of policy start.

// Policy details
let Policy = {
    InceptionDate: $ToDate("2024-03-01"),
    ExpiryDate: $ToDate("2025-02-28"),
    Premium: 566.59
};

let CancellationDate = $ToDate("2024-03-10");  // 9 days after inception
let CancellationReason = "Cooling Off Period - Customer changed mind";

// Check if within cooling-off
let daysSinceInception = $DifferenceInDays(CancellationDate, Policy.InceptionDate);
let withinCoolingOff = daysSinceInception <= 14;

if (withinCoolingOff) {
    // Full refund, no cancellation fee, refund admin fee
    $CalculateFullCancellation(0.00, true);

    let refund = Cancellation.RefundAmount;
    $Log("Full refund due: £" + $ToString(refund));
    $Log(Cancellation.RefundMessage);
    // "A refund is due as the policy lies within the 14 day cooling off period."
}

Result:

  • Refund: £566.59 (full premium)
  • Cancellation Fee: £0.00
  • Admin Fee: Refunded

Scenario 2: Pro-Rata Cancellation

Customer cancels mid-policy after cooling-off period.

// Policy details
let Policy = {
    InceptionDate: $ToDate("2024-01-15"),
    ExpiryDate: $ToDate("2025-01-14"),
    Premium: 566.59
};

let CancellationDate = $ToDate("2024-07-01");  // 168 days into policy
let CancellationReason = "Customer Request - No Longer Needed";

// Calculate days
let totalDays = $DifferenceInDays(Policy.ExpiryDate, Policy.InceptionDate);
let daysCovered = $DifferenceInDays(CancellationDate, Policy.InceptionDate);
let daysRemaining = totalDays - daysCovered;

// Pro-rata refund with £25 cancellation fee, no admin fee refund
$CalculateProRataCancellation(25.00, false);

let refund = Cancellation.RefundAmount;
let proRataPercentage = (daysRemaining / totalDays) * 100;

$Log("Days covered: " + $ToString(daysCovered) + " of " + $ToString(totalDays));
$Log("Pro-rata refund: " + $ToString(proRataPercentage) + "% of premium");
$Log("Refund amount: £" + $ToString(refund));

Calculation:

Total policy days: 365
Days covered: 168
Days remaining: 197

Pro-rata factor: 197 / 365 = 0.5397 (54%)

Premium refund: £566.59 × 0.5397 = £305.79
Less cancellation fee: £305.79 - £25.00 = £280.79

Total refund: £280.79

Scenario 3: No Refund Cancellation

Policy cancelled after expiry or under no-refund terms.

let Policy = {
    InceptionDate: $ToDate("2024-01-15"),
    ExpiryDate: $ToDate("2025-01-14")
};

let CancellationDate = $ToDate("2025-01-20");  // After expiry
let CancellationReason = "Policy Expired - Customer did not renew";

// No refund
$CalculateNoRefundCancellation(0.00);

let refund = Cancellation.RefundAmount;  // 0.00
$Log("No refund due - policy expired");

Complete Cancellation Workflow

fn ProcessCancellation(cancellationDate, reason) {
    let CancellationDate = cancellationDate;
    let CancellationReason = reason;

    // Validate cancellation date
    if (cancellationDate < Policy.InceptionDate) {
        return {
            Success: false,
            Message: "Cannot cancel before policy starts"
        };
    }

    // Calculate days since inception
    let daysSinceInception = $DifferenceInDays(cancellationDate, Policy.InceptionDate);
    let withinCoolingOff = daysSinceInception <= 14;

    // Post-expiry check
    let afterExpiry = cancellationDate > Policy.ExpiryDate;

    if (afterExpiry) {
        // No refund after expiry
        $CalculateNoRefundCancellation(0.00);

        return {
            Success: true,
            Type: "NoRefund",
            Refund: 0.00,
            Message: "Policy expired - no refund due"
        };
    }
    else if (withinCoolingOff) {
        // Full refund within cooling-off
        $CalculateFullCancellation(0.00, true);

        return {
            Success: true,
            Type: "CoolingOff",
            Refund: Cancellation.RefundAmount,
            Message: "Full refund - cooling-off period"
        };
    }
    else {
        // Pro-rata refund
        $CalculateProRataCancellation(25.00, false);

        let totalDays = $DifferenceInDays(Policy.ExpiryDate, Policy.InceptionDate);
        let daysCovered = $DifferenceInDays(cancellationDate, Policy.InceptionDate);
        let daysRemaining = totalDays - daysCovered;

        return {
            Success: true,
            Type: "ProRata",
            Refund: Cancellation.RefundAmount,
            DaysCovered: daysCovered,
            DaysRemaining: daysRemaining,
            CancellationFee: 25.00,
            Message: "Pro-rata refund calculated"
        };
    }
}

// Execute cancellation
let result = ProcessCancellation($ToDate("2024-07-01"), "Customer request");

if (result.Success) {
    $Log("Cancellation processed: " + result.Type);
    $Log("Refund: £" + $ToString(result.Refund));
}

Finance Agreement Considerations

When policy paid via finance:

let FinanceDetails = {
    IsPaidByFinance: true,
    IsValidFinanceAgreement: true,
    Deposit: 112.00,
    EarlySettlementAmount: 150.00  // Outstanding finance balance
};

// Calculate cancellation
$CalculateProRataCancellation(25.00, false);

// Refund calculation considers finance
// If finance agreement active, refund goes to finance company
// Customer receives: pro-rata refund - early settlement amount

let grossRefund = Cancellation.RefundAmount;  // e.g., £280.79
let customerRefund = grossRefund - FinanceDetails.EarlySettlementAmount;

if (customerRefund < 0) {
    // Customer owes finance company
    $Log("Customer owes: £" + $ToString($Abs(customerRefund)));
} else {
    // Customer receives refund
    $Log("Customer refund: £" + $ToString(customerRefund));
}

Ledger Analysis After Cancellation

$CalculateProRataCancellation(25.00, false);

// Ledger contains cancellation entries
let cancellationEntries = $Filter(Ledger, fn(e) =>
    e.LedgerSection == "Cancellation"
);

// Show refund breakdown
for (let entry in cancellationEntries) {
    $Log(entry.Description + ": £" + $ToString(entry.GrossAmount));
}

// Example ledger output:
// "Cancellation Fee: £25.00"
// "Policy Refund: -£280.79"  (negative = refund)
// "Net Refund: £255.79"

Business Rules Examples

No Refund for Specific Products

if (Product.Code == "EVENT_INSURANCE") {
    // Event insurance typically no refund
    $CalculateNoRefundCancellation(0.00);
    $Log("Event insurance - no refund as per policy terms");
}

Minimum Retained Premium

fn CalculateWithMinimumRetained(cancellationDate) {
    // Calculate normal pro-rata
    $CalculateProRataCancellation(25.00, false);

    let calculatedRefund = Cancellation.RefundAmount;
    let minimumRetainedPremium = 100.00;
    let premiumPaid = Policy.Premium;

    // Ensure minimum retained
    let maxRefund = premiumPaid - minimumRetainedPremium;

    if (calculatedRefund > maxRefund) {
        // Adjust refund to retain minimum
        let adjustedRefund = maxRefund;
        $Log("Refund capped - minimum premium retained");
        return adjustedRefund;
    }

    return calculatedRefund;
}

Testing Cancellation Logic

// Test cooling-off boundary
fn TestCoolingOffBoundary() {
    let inceptionDate = $ToDate("2024-01-01");

    // Day 14 - should be full refund
    let day14 = $AddDays(inceptionDate, 14);
    let days14 = $DifferenceInDays(day14, inceptionDate);
    $Log("Day 14: " + $ToString(days14) + " days - " + (days14 <= 14 ? "COOLING OFF" : "PRO-RATA"));

    // Day 15 - should be pro-rata
    let day15 = $AddDays(inceptionDate, 15);
    let days15 = $DifferenceInDays(day15, inceptionDate);
    $Log("Day 15: " + $ToString(days15) + " days - " + (days15 <= 14 ? "COOLING OFF" : "PRO-RATA"));
}

TestCoolingOffBoundary();

Next Steps