skip to Main Content

How to turn this "reference number" formula in a working PHP code?

I drop the fromula here if someone could help me!

In my case:

Customer number is default 1 everytime /always.

Invoice number is determinated by user

Verification number is calculated with formula:

The verification digit of the reference number is calculated by multiplying the digits that serve as its basis from right to left with weights of 7, 3, 1, 7, 3, 1… and summing up these products. The sum of the products is then subtracted from the next full ten, resulting in the verification digit. If the result is 10, the digit 0 is used instead.

Example of a Reference Number Calculation: Customer number: 1

Invoice number: 25 (invoice number has minimum 4 digits and if the inserted invoice number is smaller than 4 digits like 25 it needs zeros (0) added to it to equal that 4 digits. All zeros will be added left site. On this example 25 -> 0025. If the customer number is 4 digits like 1234 then that is the number)

Reference number base: 10025

5 -> 5 * 7 = 35

2 -> 2 * 3 = 6

0 -> 0 * 1 = 0

0 -> 0 * 7 = 0

1 -> 1 * 3 = 3

The sum of the products (35 + 6 + 0 + 0 + 3) is 44. The next full ten is 50. Therefore, the verification digit is 50 – 44 = 6.

The final reference number is: 100256

Here is what I have tryed:

<?php
$customerNumber = 1;
$invoiceNumber = 765;

$baseReferenceNumber = "{$customerNumber} 0 {$invoiceNumber}";

$entries = str_split(str_replace(' ', '', $baseReferenceNumber));
$sum = 0;

foreach ($entries as $entry) {
    $sum += $entry * (($sum % 2) + 1);
}

$totalSum = $sum;
$nextFullTen = ceil($totalSum / 10) * 10;
$checkNumber = $nextFullTen - $totalSum;

$finalReferenceNumber = "{$baseReferenceNumber} {$checkNumber}";

echo "Final Reference Number: {$finalReferenceNumber}";
?>

But this gives me result 107653, when the real answer is 1 07657

2

Answers


  1. After declaring the constant values and user input variables/constants, there are basically 5 subtasks.

    1. Assemble the reference base string with padded zeros (your padding wasn’t dynamic).
    2. Split and reverse the reference base string into an array of integers (your iteration was from the front).
    3. Perform the weighted arithmetic and sum the results (see my math with the modulus operator).
    4. Round the total to the nearest 10 and subtract the total from that number.
    5. Append that result to the reference base.

    Code: (Demo)

    define('WEIGHTS', [7, 3, 1]);
    define('WEIGHTS_COUNT', count(WEIGHTS));
    
    $customerNumber = 1;
    $invoiceNumber = 25;
    
    $refBase = sprintf('%d%04s', $customerNumber, $invoiceNumber);
    
    $weightedSum = array_reduce(
                       array_reverse(str_split($refBase)),
                       function($result, $v) {
                           static $i;
                           $i ??= 0;
                           return $result + ($v * WEIGHTS[$i++ % WEIGHTS_COUNT]);
                       },   
                       0
                   );
    
    echo $refBase . (ceil($weightedSum / 10) * 10 - $weightedSum);
    

    Alternatively, if you favor classic loop structures, a for() loop will allow you to iterate characters from the back of the string. (Demo)

    $refBase = sprintf('%d%04s', $customerNumber, $invoiceNumber);
    
    $weightedSum = 0;
    for ($x = 0, $i = strlen($refBase) - 1; $i >=0; --$i, ++$x) {
        $weightedSum += $refBase[$i] * WEIGHTS[$x % WEIGHTS_COUNT];
    }
    
    echo $refBase . (ceil($weightedSum / 10) * 10 - $weightedSum);
    
    Login or Signup to reply.
  2. Here is one of the solution and I tried to make it very simple and easily understandable.

        $basis = [7, 3, 1, 7, 3, 1];
        $customer_number = 1;
        $invoice_number = 25;
        $padded_invoice_number = '';
        $padded_invoice_number = str_pad($invoice_number,4,"0", STR_PAD_LEFT);
        $reference_number_base = ( $customer_number . $padded_invoice_number);
        $reference_number_base_reversed = strrev($reference_number_base);
        $sum_of_the_products = 0;
    
        for ($i=0; $i < strlen($reference_number_base_reversed); $i++) { 
            $sum_of_the_products +=  (int) $reference_number_base_reversed[$i] * $basis[$i];
        }
        
        $next_full_ten = ceil($sum_of_the_products/10) * 10;
        $verification_digit = $next_full_ten - $sum_of_the_products;
        $final_reference_number  =  ($reference_number_base . $verification_digit);
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search