Kavvson Empcraft
Kavvson Empcraft

Reputation: 443

Loop subtraction, which invoices can be paid based on user input

I am creating a script that would calculate which invoices can be paid within the given user budget/input.

In the following scenario we have 3 invoices which are total of 5328.00, but the user want's to pay only 1000. The script is supposed to assign the 1000 to the invoices the order of payment isn't important here. So basic idea for this example is invoice[1] would get fully paid ( 523.00 ), and the invoice[2] would get paid 500, and due 3283 - 500.

I am struggling with this code for quite some while and I got really no idea how to accordingly update the due/paid amounts. For any further information don't hesitate to ask, it seems to be a quite easy example, but maybe I over complicate this. The result should be displayed as is in the $invoiceUpdate array

$invoice = array();

$invoice['1']['id'] = 1;
$invoice['1']['total'] = 523.00;
$invoice['1']['due'] = 500.00;
$invoice['1']['paid'] = 23.00;

$invoice['2']['id'] = 2;
$invoice['2']['total'] = 3283.00;
$invoice['2']['due'] = 3283.00;
$invoice['2']['paid'] = 0.00;

$invoice['3']['id'] = 3;
$invoice['3']['total'] = 1545.00;
$invoice['3']['due'] = 1545.00;
$invoice['3']['paid'] = 0.00;


$userBalanceInput = 1000; // user input
$invoiceUpdate = array();

foreach($invoice as $i){
     $left = $userBalanceInput - $i['due'];
     if($left > 0){
         // fully paid
          echo "INV".$i['id']." Total : ".$i['total']. " Due : ".$i['due']. " Paid : ".$i['paid']. " LoopLeft : ".$left." STATUS : Paid \n";
          $invoiceUpdate[] = array(
              'id' => $i['id'],
              'newDue' => '?',
              'newPaid' => 0 + $i['paid'], // calculate newPaid and add the old Paid value
              'oldTotal' => $i['total']
          );
     }
      if($left < 0){
          // partialy paid or not affected
          echo "INV".$i['id']." Total : ".$i['total']. " Due : ".$i['due']. " Paid : ".$i['paid']. " LoopLeft : ".$left." STATUS : UNPAID \n";
          $invoiceUpdate[] = array(
              'id' => $i['id'],
              'newDue' => '?',
              'newPaid' => 0 + $i['paid'], // calculate newPaid and add the old Paid value
              'oldTotal' => $i['total']
          );
      }
     // $userBalanceInput = $left;

}

var_dump($invoice);
echo "---------";
var_dump($invoiceUpdate);

MCVE http://sandbox.onlinephpfunctions.com/code/c09805db45c4dd241e16a9db5061ba57b7051b93

Thanks in advance

Upvotes: 0

Views: 108

Answers (1)

Philipp
Philipp

Reputation: 15629

In this simple case without any pay logic given (pay many invoices, pay oldest first, pay bigest first, ...) you could simply loop over the invoices and calculate the remaining amount you could pay.

$invoiceUpdate = array_map(function($item) use (&$userBalanceInput) {
    $newItem = ['id' => $item['id']];
    $amount = $userBalanceInput > $item['due'] ? $item['due'] : $userBalanceInput;
    $userBalanceInput -= $amount;

    return [
        'id' => $item['id'],
        'newDue' => $item['due'] - $amount,
        'newPaid' => $item['paid'] + $amount,
        'oldTotal' => $item['total']
    ];
}, $invoice);

Upvotes: 1

Related Questions