Not sure if this will help or not, but with my site, I insert transactions into the invoicedetails table with a flag of 'invoiced=0' to show it hasn't been invoiced yet. Then the cutom button runs through all of them, groups the debits and credits together by account, and creates the invoices for each account:
// Select all transactions that aren't invoiced yet //$transactionsearch = DB::PrepareSQL("SELECT id, account_id FROM invoicedetails WHERE invoiced='0' OR (invoice_id = '' AND price > '0') GROUP BY account_id", '0'); $transactions = DB::Query("SELECT id, account_id FROM invoicedetails WHERE invoiced='0' GROUP BY account_id"); while($data = $transactions->fetchAssoc()){ $arr = explode(",",$data["id"]); for ($i=0;$i<count($arr);$i++){ foreach ($data AS $invoice) { // Select the account_id for processing from transaction $newid = DB::DBLookup("SELECT account_id FROM invoicedetails WHERE id='".$arr[$i]."'"); $oldid = $oldid; $idlookup = $idlookup; // Check if there is a credit on file $creditamount = DB::DBLookup("SELECT balance FROM account_data WHERE id = ".$newid.""); // If going to new account_id, create a new invoice and update invoice number. if ($newid != $oldid){ // Update invoice number $invoiceid = DB::DBLookup("SELECT invnumber FROM invoice_number"); $invnum = $invoiceid + 1; DB::Exec("UPDATE invoice_number SET invnumber='".$invnum."'"); //Get total and create hash $charges = DBLookup("SELECT sum(price) FROM invoicedetails WHERE (account_id='".$newid."' AND invoiced='0' AND price > '0.00')"); $temphash = md5(now().'_'.$charges); if ($creditamount < '0'){ // If credit is larger than/equal to invoice total if (ABS($creditamount) >= $charges){ // Insert invoice data $remaining_credit = $creditamount + $charges; DB::Exec("INSERT INTO invoices SET account_id='".$newid."', total='".$charges."', total_paid='".$charges."', balance='0.00', hash='".$temphash."', invoice_number='".$invnum."', date=curdate(), due_date=curdate()+1"); DB::Exec("INSERT INTO
invoicedetails(
account_id,
item,
price,
invoiced,
creationdate) VALUES ('".$newid."','Credit Applied','".$charges."','0',CURDATE())"); DB::Exec("UPDATE account_data SET balance = ".$remaining_credit." WHERE id='".$newid."'"); // If credit is less than invoice total } else if (ABS($creditamount) < $charges) { $invbalance = $creditamount + $charges; DB::Exec("INSERT INTO invoices SET account_id='".$newid."', total='".$charges."', total_paid='".$creditamount."', balance='".$invbalance."', hash='".$temphash."', invoice_number='".$invnum."', date=curdate(), due_date=curdate()+1"); DB::Exec("INSERT INTO
invoicedetails(
account_id,
item,
price,
invoiced,
creationdate) VALUES ('".$newid."','Credit Applied','".$creditamount."','0',CURDATE())"); DB::Exec("UPDATE account_data SET balance = balance + ".$charges." WHERE id='".$newid."'"); } //No credit on file } else { // Insert invoice data DB::Exec("INSERT INTO invoices SET account_id='".$newid."', total='".$charges."', total_paid='0.00', balance='".$charges."', hash='".$temphash."', invoice_number='".$invnum."', date=curdate(), due_date=curdate()+1"); DB::Exec("UPDATE account_data SET balance = balance + ".$charges." WHERE id='".$newid."'"); } // Update hash $idlookup = DB::DBLookup("SELECT id FROM invoices WHERE hash='".$temphash."'"); $hash = md5($idlookup.'_'.$charges); DB::Exec("UPDATE invoices SET hash='".$hash."' WHERE id='".$idlookup."'"); $oldid = $newid; } // Update details to be marked as invoiced, and add the invoice_id to it. $data = array(); $data["id_invoice"] = $idlookup; $data["invoiced"] = "1"; DB::Update("invoicedetails", $data, "account_id=".$newid."" ); } } }