0

I want to update three invoice data that belongs to a customer like below:

function updateInvoice($dbh, $id, $amount, $bal, $payer){
$q = $dbh->query("SELECT * FROM `zinvoice` WHERE `id`='$id' 
                  AND `status` IN ('Balance','Not Paid')");
$nrow = count($q->fetchAll());
$remain = 0;
if($nrow==1){
    //update the amount
    if($amount>$bal){
        $remain = $amount-$bal;
        $dbh->query("UPDATE zinvoice SET paidamount=(paidamount+$bal),
                     balanceamount='0', status='Paid'
                     WHERE id='$id'");
        //payment history update
    }else if($amount==$bal){
        $remain = 0;
        $dbh->query("UPDATE zinvoice SET paidamount=(paidamount+$bal),
                     balanceamount='0', status='Paid'
                     WHERE id='$id'");
        //payment history update
    }else{
        $newbal = $bal-$amount;
        $dbh->query("UPDATE zinvoice SET paidamount=(paidamount+$amount),
                     balanceamount='$newbal', status='Balance'
                     WHERE id='$id'");
        $remain = 0;
        //payment history update
    }
}else{
    //Nothing to update Because there is no Invoice with balance or not paid
} 
return $remain;

}

Now I want to update multiple invoices by a customer id=2. Customer with id=2 has three invoices with total amount of 1500, invoice id=1 has amount=500, invoice id=2 has amount=700, invoice id=3 has amount=300

 //Loop to update
  $q = $dbh->query("SELECT * FROM zinvoice WHERE customerid='$cid'");

  while($row =$q->fetch(PDO::FETCH_OBJ)):
    $remain = updateInvoice($dbh, $row->id, $amount, $row->balanceamount, $payer);
    if($remain>=1){
        updateInvoice($dbh, $row->id, $remain, $row->balanceamount, $payer);
    }else{
        //nothing
    }
endwhile;

$amount would come from a form//amount = 800
$cid would also come from a form//cid = 2
$payer would also come from a form//payer = john

The problem is that this code updated all the invoices to status=Paid. I want this code to update Invoice id=2 which has balance amount=700 and as there would be 100 amount remaining, it will continue to update the other invoices, say Invoice id=3. But Invoice id=3 has a balance amount=300, which is more than 100 amount, it will subtract 100from it and Invoice id=3 would have 200 balance amount. And there are no more amount left and would stop updating.

How would I achieve my desired output?

Note: I am not using prepared statement to avoid more codes here. And this code would be vulnerable to sql injection.

  • 4
    [Little Bobby](http://bobby-tables.com/) says ***[your script is at risk for SQL Injection Attacks.](http://stackoverflow.com/questions/60174/how-can-i-prevent-sql-injection-in-php)***. Even [escaping the string](http://stackoverflow.com/questions/5741187/sql-injection-that-gets-around-mysql-real-escape-string) is not safe! I saw that you noted this, but don't know why you're not using prepared statements. – Jay Blanchard Apr 13 '17 at 13:06
  • `SELECT id FROM zinvoice WHERE id='1' AND status='Balance'` shouldn't that use the real `id`, `$id`? – chris85 Apr 13 '17 at 13:09
  • pdo is nice when u are using it correctly – Masivuye Cokile Apr 13 '17 at 13:10
  • @JayBlanchard, The problem is not in the Little Bobby thing. It is in the question. I have to write more codes if I use prepared here. So to avoid it, I used the normal query which of course is vulnerable to injection. – Zone Security Apr 13 '17 at 13:13
  • Why have the PHP do the math/comparison? Just have one query and have mysql set the status based on the value in the row. Also per your function call `updateInvoice($dbh, $res->id, 800,` your `$amount` is always 800, not 100. – chris85 Apr 13 '17 at 13:22
  • @chris85, that's exactly my problem. how can I make the 800 not always 800? I need the math stuff here. Thanks for your insight. – Zone Security Apr 13 '17 at 13:28
  • @ZoneSecurity Put the real value in function's call, in your `while` loop. I don't know where the amount comes from but you have a static value currently. – chris85 Apr 13 '17 at 13:36
  • @chris85, the value will come from a form. – Zone Security Apr 13 '17 at 13:40
  • So use the form value, not the static, `$_POST['field_name']`. – chris85 Apr 13 '17 at 14:56
  • The loop updates all the three rows because it is looping as long as there are rows with that specified customer id=2. On the first loop, I want to put the remaining amount after updates in a variable and I want to use that variable on the second loop to update on the specified condition. It is not working with my code. – Zone Security Apr 13 '17 at 15:02

0 Answers0