Search code examples
validationsalesforce

Salesforce field validation rule for IMEI


I have a field on an object in Salesforce representing the IMEI of a mobile device. I want to validate the input of users to ensure for a correct IMEI number and format. I know the IMEI is using a check digit as last digit.

How do I validate this with a validation rule on a field in Salesforce?


Solution

  • The IMEI is a 15-digit number with 14 relevant digits and a last check digit.

    (Note: there is also a 16-digit IMEISV format, which is not considered here)

    The check digit is calculated following the Luhn algorithm.

    Assuming your Salesforce object (here Asset) has a custom field IMEI__c of type Number, the following checks can be applied to validate the IMEI input.

    Length check (easy)

    A validation rule checks for the error state. Hence for the length check we need the following validation rule:

    LEN(TEXT(IMEI__c)) != 15
    

    If this condition is true, the error state is encountered and we can display an error message to the user and saving the record is blocked.

    You can also check the number is larger than 1x10^15, but I prefer this notation to understand directly I am checking for a 15 digit number.

    You can also include this easy check in the other check below, but I prefered to do it separately to provide the user with a more specific error message in case of an error.

    Length check validation rule

    Check digit validation (complex)

    For this check we need to calculate the check digit by ourselves and validate it against the last digit in the IMEI, representing the check digit.

    • If the number already contains the check digit, drop that digit to form the "payload". The check digit is the last digit.
    • With the payload, start from the rightmost digit. Moving left, double the value of every second digit (including the rightmost digit).
    • Sum the values of the resulting digits.
    • Calculate and validate the check digit

    We extract every single digit by: extract one (1) digit from the middle (MID) at position x from the IMEI converted to text, and convert it back to a number.

    VALUE(MID(TEXT(IMEI__c), x, 1))
    

    Starting from the rightmost digit (index=14) (excluding the check digit), we double every second digit.

    2*VALUE(MID(TEXT(IMEI__c), 14, 1))
    1*VALUE(MID(TEXT(IMEI__c), 13, 1))
    2*VALUE(MID(TEXT(IMEI__c), 12, 1))
    [...]
    2*VALUE(MID(TEXT(IMEI__c),  2, 1))
    1*VALUE(MID(TEXT(IMEI__c),  1, 1))
    

    If the number is larger than 9, we need to calculate the cross sum (e.g. 14 => 1 + 4 = 5). Since Salesforce does not provide a cross sum function in validation rules, we use a workaround. The maxmimum number we can encounter is 9x2=18. Hence we check if the number is larger than 9, if yes we substract 10 and add 1 to the sum.

    IF(
        2*VALUE(MID(TEXT(IMEI__c), 14, 1))>9,    # Check number larger than 9
        2*VALUE(MID(TEXT(IMEI__c), 14, 1))-10+1, # yes, substract 10 and add 1: 18 => 1+8 = 9 = 18-10+1
        2*VALUE(MID(TEXT(IMEI__c), 14, 1))       # no, use raw number
    )
    

    To calculate the check digit, we need to find the number to be added to the final sum to reach a multile of 10 (e.g. sum=52 => check digit = 8 => 52 + 8 = 60 = 6 * 10). Hence the check digit is

    MOD(
        10 - MOD(
            <SUMMED VALUES>,
            10
        ),
        10
    )
    

    Finally we validate this against the check digit from the provided IMEI

    VALUE(MID(TEXT(IMEI__c), 15, 1))
    

    The final validation rule then looks like

    MOD(
        10 - MOD(        
            IF(2*VALUE(MID(TEXT(IMEI__c), 14, 1))>9,2*VALUE(MID(TEXT(IMEI__c), 14, 1))-10+1,2*VALUE(MID(TEXT(IMEI__c), 14, 1)))+
            IF(1*VALUE(MID(TEXT(IMEI__c), 13, 1))>9,1*VALUE(MID(TEXT(IMEI__c), 13, 1))-10+1,1*VALUE(MID(TEXT(IMEI__c), 13, 1)))+
            IF(2*VALUE(MID(TEXT(IMEI__c), 12, 1))>9,2*VALUE(MID(TEXT(IMEI__c), 12, 1))-10+1,2*VALUE(MID(TEXT(IMEI__c), 12, 1)))+
            IF(1*VALUE(MID(TEXT(IMEI__c), 11, 1))>9,1*VALUE(MID(TEXT(IMEI__c), 11, 1))-10+1,1*VALUE(MID(TEXT(IMEI__c), 11, 1)))+
            IF(2*VALUE(MID(TEXT(IMEI__c), 10, 1))>9,2*VALUE(MID(TEXT(IMEI__c), 10, 1))-10+1,2*VALUE(MID(TEXT(IMEI__c), 10, 1)))+
            IF(1*VALUE(MID(TEXT(IMEI__c),  9, 1))>9,1*VALUE(MID(TEXT(IMEI__c),  9, 1))-10+1,1*VALUE(MID(TEXT(IMEI__c),  9, 1)))+
            IF(2*VALUE(MID(TEXT(IMEI__c),  8, 1))>9,2*VALUE(MID(TEXT(IMEI__c),  8, 1))-10+1,2*VALUE(MID(TEXT(IMEI__c),  8, 1)))+
            IF(1*VALUE(MID(TEXT(IMEI__c),  7, 1))>9,1*VALUE(MID(TEXT(IMEI__c),  7, 1))-10+1,1*VALUE(MID(TEXT(IMEI__c),  7, 1)))+
            IF(2*VALUE(MID(TEXT(IMEI__c),  6, 1))>9,2*VALUE(MID(TEXT(IMEI__c),  6, 1))-10+1,2*VALUE(MID(TEXT(IMEI__c),  6, 1)))+
            IF(1*VALUE(MID(TEXT(IMEI__c),  5, 1))>9,1*VALUE(MID(TEXT(IMEI__c),  5, 1))-10+1,1*VALUE(MID(TEXT(IMEI__c),  5, 1)))+
            IF(2*VALUE(MID(TEXT(IMEI__c),  4, 1))>9,2*VALUE(MID(TEXT(IMEI__c),  4, 1))-10+1,2*VALUE(MID(TEXT(IMEI__c),  4, 1)))+
            IF(1*VALUE(MID(TEXT(IMEI__c),  3, 1))>9,1*VALUE(MID(TEXT(IMEI__c),  3, 1))-10+1,1*VALUE(MID(TEXT(IMEI__c),  3, 1)))+
            IF(2*VALUE(MID(TEXT(IMEI__c),  2, 1))>9,2*VALUE(MID(TEXT(IMEI__c),  2, 1))-10+1,2*VALUE(MID(TEXT(IMEI__c),  2, 1)))+
            IF(1*VALUE(MID(TEXT(IMEI__c),  1, 1))>9,1*VALUE(MID(TEXT(IMEI__c),  1, 1))-10+1,1*VALUE(MID(TEXT(IMEI__c),  1, 1))),
            10
        ), 10
    ) != VALUE(MID(TEXT(IMEI__c), 15, 1))
    

    Validation rule for check digit

    Example

    INPUT: 123456789012347

    12345678901234 - check digit 7

    => 2*4 + 3 + 2*2 + 1 + 2*0 + 9 + 2*8 + 7 + 2*6 + 5 + 2*4 + 3 + 2*2 + 1
    => 8+3+4+1+0+9+(16)+7+(12)+5+8+3+4+1
    => 8+3+4+1+0+9+(16-10+1)+7+(12-10+1)+5+8+3+4+1
    => 8+3+4+1+0+9+(7)+7+(3)+5+8+3+4+1
    => 63
    

    Missing to next 10 multiple is 7 => IMEI OK!

    For an invalid IMEI it looks like

    Invalid IMEI encountered