function allocateStockToJob($jobcard_id, $stock_id, $units = 1)
{
    $refnum = getRefnum();
    $sysdate = date("Y-m-d");
    $stock_wh = getStore($stock_id);
    $production_wh = getProductionStore();
    $sql = "SELECT * FROM cubit.stock WHERE stkid='{$stock_id}'";
    $stock_rslt = db_exec($sql) or errDie("Unable to retrieve stock.");
    $stock_data = pg_fetch_array($stock_rslt);
    // Do we have this stock in the production store already
    $sql = "SELECT stkid FROM cubit.stock WHERE stkcod='{$stock_data['stkcod']}' AND whid='{$production_wh}'";
    $production_rslt = db_exec($sql) or errDie("Unable to retrieve production stock.");
    $production_id = pg_fetch_result($production_rslt, 0);
    if (!pg_num_rows($production_rslt)) {
        $sql = "\n\t\t\tINSERT INTO cubit.stock (\n\t\t\t\tstkcod, stkdes, prdcls, csamt, units, \n\t\t\t\tbuom, suom, rate, \n\t\t\t\tminlvl, whid, shelf, row, \n\t\t\t\ttype, catname, classname, \n\t\t\t\tcom, csprice, serd, \n\t\t\t\tlcsprice, vatcode, supplier1, \n\t\t\t\tsupplier2, supplier3, rfidfreq, \n\t\t\t\trfidrate, size, post_production, \n\t\t\t\ttreatment, div\n\t\t\t) VALUES (\n\t\t\t\t'{$stock_data['stkcod']}', '{$stock_data['stkdes']}', '{$stock_data['prdcls']}', '0', '0', \n\t\t\t\t'{$stock_data['buom']}', '{$stock_data['suom']}', '{$stock_data['rate']}', \n\t\t\t\t'{$stock_data['minlvl']}', '{$production_wh}', '{$stock_data['shelf']}', '{$stock_data['row']}', \n\t\t\t\t'{$stock_data['type']}', '{$stock_data['catname']}', '{$stock_data['classname']}', \n\t\t\t\t'{$stock_data['com']}', '{$stock_data['csprice']}', '{$stock_data['serd']}', \n\t\t\t\t'{$stock_data['lcsprice']}', '{$stock_data['vatcode']}', '{$stock_data['supplier1']}', \n\t\t\t\t'{$stock_data['supplier2']}', '{$stock_data['supplier3']}', '{$stock_data['rfidfreq']}', \n\t\t\t\t'{$stock_data['rfidrate']}', '{$stock_data['size']}', '{$stock_data['post_production']}', \n\t\t\t\t'{$stock_data['treatment']}', '" . USER_DIV . "'\n\t\t\t)";
        db_exec($sql) or errDie("Unable to create in stock store.");
        $production_id = pglib_lastid("cubit.stock", "stkid");
        for ($i = 1; $i <= 12; $i++) {
            $sql = "\n\t\t\t\tINSERT INTO \"{$i}\".stkledger (\n\t\t\t\t\tstkid, stkcod, stkdes, trantype, \n\t\t\t\t\tedate, qty, csamt, balance, bqty, details, div, yrdb\n\t\t\t\t) VALUES (\n\t\t\t\t\t'{$production_id}', '{$stock_data['stkcod']}', '{$stock_data['stkdes']}', 'bal', \n\t\t\t\t\t'{$sysdate}', '0', '0', '0', '0','Balance', '" . USER_DIV . "','" . YR_DB . "'\n\t\t\t\t)";
            db_exec($sql) or errDie("Unable to create ledger entries.");
        }
    }
    $details = "Stock allocated to job {$jobcard_id}";
    reduceStock($stock_id, $units, $details);
    increaseStock($production_id, $units, $details);
    $production_acc = qryAccountsName("Inventory in Production");
    $production_acc = $production_acc["accid"];
    $inventory_acc = qryAccountsName("Inventory");
    $inventory_acc = $inventory_acc["accid"];
    $amount = getStockCostPrice($stock_id) * $units;
    writetrans($production_acc, $inventory_acc, $sysdate, $refnum, $amount, $details);
    return;
}
function decrease_stock($stkid, $qty)
{
    $sysdate = date("Y-m-d");
    $sql = "\n\t\tSELECT stkcod, stkdes, csprice FROM cubit.stock\n\t\t\tWHERE stkid='{$stkid}'";
    $stock_rslt = db_exec($sql) or errDie("Unable to retrieve stock.");
    list($stkcod, $stkdes, $csprice) = pg_fetch_array($stock_rslt);
    $price = $csprice * $qty;
    $sql = "\n\t\tUPDATE cubit.stock SET units=(units-'{$qty}'), csamt=(csamt-'{$price}')\n\t\t\tWHERE stkid='{$stkid}'";
    db_exec($sql) or errDie("Unable to decrease stock.");
    $inventory_acc = qryAccountsName("Inventory");
    $inventory_acc = $inventory_acc["accid"];
    // Stock take suspense
    $inventory_suspense_acc = qryAccountsName("Stock Take Suspense Account");
    $inventory_suspense_acc = $inventory_suspense_acc["accid"];
    $refnum = getRefnum();
    stockrec($stkid, $stkcod, $stkdes, "ct", $sysdate, $qty, $price, "Stock Take Adjustment");
    writetrans($inventory_suspense_acc, $inventory_acc, $sysdate, $refnum, $price, "Stock Take Adjustment for ({$stkcod}) {$stkdes} - {$qty} Units");
    return;
}
function run()
{
    extract($_REQUEST);
    pglib_transaction("BEGIN");
    // Retrieve outstanding rentals
    $sql = "\n\tSELECT id, user_id, username, order_num, subtotal, vat, total, discount,\n\t\tdelivery, customers.cusnum, surname, addr1, addr2, addr3, accno,\n\t\tvatnum, tel, discount_perc, timestamp, deposit\n\tFROM cubit.hire_trans\n\t\tLEFT JOIN cubit.customers ON hire_trans.cusnum=customers.cusnum\n\t\tLEFT JOIN cubit.users ON hire_trans.user_id=users.userid\n\tWHERE user_id='{$user_id}' AND done='y'";
    $rental_rslt = db_exec($sql) or errDie("Unable to retrieve rentals.");
    $hire_nums = array();
    while ($rental_data = pg_fetch_array($rental_rslt)) {
        $deptid = 2;
        $time = strtotime($rental_data["timestamp"]);
        $sql = "SELECT deptname FROM exten.departments WHERE deptid='{$deptid}'";
        $deptname_rslt = db_exec($sql) or errDie("Unable to retrieve department.");
        $deptname = pg_fetch_result($deptname_rslt, 0);
        // Create hire note
        $sql = "\n\t\tINSERT INTO hire.hire_invoices (deptid, cusnum, cordno, ordno,\n\t\t\tchrgvat, terms, salespn, odate, printed, comm, done, username,\n\t\t\tdeptname, cusacc, cusname, surname, cusaddr, cusordno, cusvatno,\n\t\t\tprd, invnum, div, prints, disc, discp, delchrg, subtot, traddisc,\n\t\t\tbalance, vat, total, discount, delivery, nbal, rdelchrg, serd,\n\t\t\tpcash, pcheque, pcc, rounding, pchange, delvat, pcredit, vatnum,\n\t\t\ttelno, systime, deposit_type, deposit_amt, custom_txt, collection,\n\t\t\tbranch_addr, timestamp, hire_invid, revision)\n\t\tVALUES ('{$deptid}', '{$rental_data['cusnum']}', '', '', 'inc', '0', '2',\n\t\t\t'" . date("Y-m-d", $time) . "', 'y', '', 'y', '{$rental_data['username']}',\n\t\t\t'{$deptname}', '{$rental_data['accno']}', '', '{$rental_data['surname']}',\n\t\t\t'{$rental_data['addr1']}', '{$rental_data['order_num']}',\n\t\t\t'{$rental_data['vatnum']}', '" . PRD_DB . "', '{$rental_data['id']}',\n\t\t\t'" . USER_DIV . "', '0', '{$rental_data['discount']}',\n\t\t\t'{$rental_data['discount_perc']}', '{$rental_data['delivery']}',\n\t\t\t'{$rental_data['subtotal']}', '{$rental_data['discount']}', '0.00',\n\t\t\t'{$rental_data['vat']}', '{$rental_data['total']}',\n\t\t\t'{$rental_data['discount']}', '{$rental_data['delivery']}', '0.00', '0.00',\n\t\t\t'', '100', '100', '100', '100', '100', '0', '0.00',\n\t\t\t'{$rental_data['vatnum']}', '{$rental_data['tel']}',\n\t\t\t'{$rental_data['timestamp']}', 'CSH', '{$rental_data['deposit']}', '',\n\t\t\t'Client Collect', '0', current_timestamp, '0', '0')";
        db_exec($sql) or errDie("Unable to create hire note.");
        $invid = pglib_lastid("hire.hire_invoices", "invid");
        $hire_nums[$rental_data["id"]] = $invid;
        // Do deposit transaction if required
        if ($rental_data["deposit"] > 0) {
            $cash_on_hand = qryAccountsNum("7200", "000");
            $cash_on_hand = $cash_on_hand["accid"];
            $cust_control = qryAccountsNum("6400", "000");
            $cust_control = $cust_control["accid"];
            $refnum = getRefnum();
            writetrans($cash_on_hand, $cust_control, date("Y-m-d", $time), $refnum, $rental_data["deposit"], "Cash Receipt for " . CUR . "{$rental_data['deposit']} from " . "{$rental_data['surname']} for Deposit on Hire Note {$rental_data['id']}");
            $sql = "\n\t\t\tINSERT INTO hire.cash (invid, cash)\n\t\t\tVALUES ('{$invid}', '{$rental_data['deposit']}')";
            db_exec($sql) or errDie("Unable to add cash to hire.");
            // Make ledger record
            custledger($rental_data["cusnum"], $cust_control, date("Y-m-d", $time), $invid, "Cash Receipt for " . CUR . "{$rental_data['deposit']} from " . "{$rental_data['surname']} for Deposit on Hire Note {$rental_data['id']}", $rental_data["deposit"], "c");
            custCT($rental_data["deposit"], $rental_data["cusnum"], date("Y-m-d", $time));
            // Turn the amount around to a negative
            $stmnt_amt = $rental_data["deposit"] - $rental_data["deposit"] * 2;
            // Record the payment on the statement
            $sql = "\n\t\t\tINSERT INTO cubit.stmnt(cusnum, invid, docref, amount, date, type,\n\t\t\t\tdiv)\n\t\t\tVALUES('{$rental_data['cusnum']}', '{$invid}', '{$rental_data['id']}',\n\t\t\t\t'{$stmnt_amt}', '" . date("Y-m-d", $time) . "',\n\t\t\t\t'Cash Receipt for " . CUR . "{$rental_data['deposit']} from " . "{$rental_data['surname']} for Deposit on Hire Note {$rental_data['id']}',\n\t\t\t\t'" . USER_DIV . "')";
            $stmntRslt = db_exec($sql) or errDie("Unable to add deposit to statement");
            // Update customer balance
            $sql = "\n\t\t\tUPDATE cubit.customers SET balance=balance-'{$rental_data['deposit']}'\n\t\t\tWHERE cusnum='{$rental_data['cusnum']}'";
            db_exec($sql) or errDie("Unable to update customer balance.");
            $sql = "\n\t\t\tUPDATE hire.hire_invoices SET deposit_amt='0'\n\t\t\tWHERE invid='{$invid}'";
            db_exec($sql) or errDie("Unable to retrieve hire invoices.");
        }
        // Retrieve items on this invoice
        $sql = "\n\t\tSELECT asset_id, basis, from_date, to_date, half_day, qty,\n\t\t\tweekends, total_days, total\n\t\tFROM cubit.hire_trans_items\n\t\tWHERE hire_id='{$rental_data['id']}'";
        $item_rslt = db_exec($sql) or errDie("Unable to retrieve items.");
        while ($item_data = pg_fetch_array($item_rslt)) {
            $unitcost = $item_data["total"] / $item_data["qty"];
            // Decide which basis to use
            $hours = 0;
            $weeks = 0;
            $days = 0;
            $months = 0;
            $total_days = 0;
            switch ($item_data["basis"]) {
                case "per_hour":
                    $hours = $item_data["total_days"];
                    break;
                case "per_day":
                    $days = $item_data["total_days"];
                    $total_days = $item_data["total_days"];
                    break;
                case "per_week":
                    $week = $item_data["total_days"];
                    break;
                case "per_month":
                    $months = $item_data["total_days"];
                    break;
            }
            // Convert booleans into something we can use
            $half_day = $item_data["half_day"] == "t" ? 1 : 0;
            $weekends = $item_data["weekends"] == "t" ? 1 : 0;
            $sql = "\n\t\t\tINSERT INTO hire.hire_invitems (invid, qty, amt, unitcost,\n\t\t\t\tfrom_date, to_date, asset_id, basis, hours, weeks, days,\n\t\t\t\tmonths, half_day, weekends, total_days)\n\t\t\tVALUES ('{$invid}', '{$item_data['qty']}', '{$item_data['total']}',\n\t\t\t\t'{$unitcost}', '{$item_data['from_date']}', '{$item_data['to_date']}',\n\t\t\t\t'{$item_data['asset_id']}', '{$item_data['basis']}', '{$hours}',\n\t\t\t\t'{$weeks}', '{$days}', '{$months}', '{$half_day}', '{$weekends}',\n\t\t\t\t'{$total_days}')";
            db_exec($sql) or errDie("Unable to create rental items.");
            $item_id = pglib_lastid("hire.hire_invitems", "id");
            $sql = "\n\t\t\tINSERT INTO hire.assets_hired (invid, asset_id, qty, hired_time,\n\t\t\t\tcust_id, item_id, invnum, value, basis, discount, weekends)\n\t\t\tVALUES ('{$invid}', '{$item_data['asset_id']}', '{$item_data['qty']}',\n\t\t\t\t'{$rental_data['timestamp']}', '{$rental_data['cusnum']}', '{$item_id}',\n\t\t\t\t'{$rental_data['id']}', '{$item_data['total']}', '{$item_data['basis']}',\n\t\t\t\t'0.00', '{$weekends}')";
            db_exec($sql) or errDie("Unable to add to assets hired.");
        }
    }
    // Run invoices ----------------------------------------------------------
    $sql = "\n\tSELECT id, hire_id, customers.cusnum, order_num, discount_perc, discount,\n\t\tsubtotal, total, vat, timestamp, user_id, surname, addr1, vatnum,\n\t\tusername, delivery\n\tFROM cubit.hire_invoice_trans\n\t\tLEFT JOIN cubit.customers ON hire_invoice_trans.cusnum=customers.cusnum\n\t\tLEFT JOIN cubit.users ON hire_invoice_trans.user_id=users.userid\n\tWHERE done='y' AND user_id='{$user_id}' AND hire_id > 0";
    $inv_rslt = db_exec($sql) or errDie("Unable to retrieve invoices.");
    while ($inv_data = pg_fetch_array($inv_rslt)) {
        $hire_sales = qryAccountsNum("1050", "000");
        $cust_control = qryAccountsNum("6400", "000");
        $cash_on_hand = qryAccountsNum("7200", "000");
        $hire_sales = $hire_sales["accid"];
        $cust_control = $cust_control["accid"];
        $cash_on_hand = $cash_on_hand["accid"];
        $time = strtotime($inv_data["timestamp"]);
        $sql = "\n\t\tINSERT INTO cubit.nons_invoices (cusname, cusaddr, cusvatno,\n\t\t\tchrgvat, sdate, done, username, prd, invnum, div, remarks, cusid,\n\t\t\tage, typ, subtot, balance, vat, total, descrip, ctyp, accid,\n\t\t\tfbalance, fsubtot, cordno, terms, odate, systime, bankid,\n\t\t\tcusordno, ncdate, cusnum, discount, delivery, hire_invid,\n\t\t\tcash, cheque, credit)\n\t\tVALUES ('{$inv_data['surname']}', '{$inv_data['addr1']}', '{$inv_data['vatnum']}',\n\t\t\t'yes', '" . date("Y-m-d", $time) . "', 'y', '{$inv_data['username']}',\n\t\t\t'" . PRD_DB . "', '{$inv_data['id']}', '" . USER_DIV . "', '',\n\t\t\t'{$inv_data['cusnum']}', '0', 'inv', '{$inv_data['subtotal']}',\n\t\t\t'{$inv_data['total']}', '{$inv_data['vat']}', '{$inv_data['total']}', '', 's',\n\t\t\t'{$hire_sales}', '0.00', '0.00', '{$inv_data['order_num']}', '0',\n\t\t\t'" . date("Y-m-d", $time) . "', current_timestamp,\n\t\t\t'" . cust_bank_id($inv_data["cusnum"]) . "', '{$inv_data['order_num']}',\n\t\t\t'" . date("Y-m-d", $time) . "', '{$inv_data['cusnum']}',\n\t\t\t'{$inv_data['discount']}', '{$inv_data['delivery']}',\n\t\t\t'" . $hire_nums[$inv_data["hire_id"]] . "', '{$inv_data['total']}', '0', '0')";
        db_exec($sql) or errDie("Unable to create non stock invoice.");
        $invid = lastinvid();
        $sql = "\n\t\tSELECT hire_invoice_items_trans.id, asset_id, basis, from_date,\n\t\t\tto_date, half_day, qty, weekends, total_days, total,\n\t\t\tserial, des, grpid\n\t\tFROM cubit.hire_invoice_items_trans\n\t\t\tLEFT JOIN cubit.assets\n\t\t\t\tON hire_invoice_items_trans.asset_id=assets.id\n\t\tWHERE trans_id='{$inv_data['id']}'";
        $item_rslt = db_exec($sql) or errDie("Unable to retrieve items.");
        while ($item_data = pg_fetch_array($item_rslt)) {
            $unitcost = $item_data["total"] / $item_data["qty"];
            $item_id = 0;
            $sql = "\n\t\t\tSELECT {$item_data['basis']} FROM hire.basis_prices\n\t\t\tWHERE assetid='{$item_data['asset_id']}'";
            $rate_rslt = db_exec($sql) or errDie("Unable to retrieve rate.");
            $rate = pg_fetch_result($rate_rslt, 0);
            $rate = empty($rate) ? 0.0 : $rate;
            $sql = "\n\t\t\tSELECT serial, des FROM cubit.assets\n\t\t\tWHERE id='{$item_data['asset_id']}'";
            $asset_rslt = db_exec($sql) or errDie("Unable to retrieve assets.");
            $asset_data = pg_fetch_array($asset_rslt);
            $sql = "\n\t\t\tINSERT INTO hire.hire_nons_inv_items (invid, qty, description, div,\n\t\t\t\tamt, unitcost, accid, vatex, cunitcost, asset_id, item_id,\n\t\t\t\thired_days, rate)\n\t\t\tVALUES ('{$invid}', '{$item_data['qty']}', '({$asset_data['serial']}) " . "{$asset_data['des']} hired from {$item_data['from_date']} to " . "{$item_data['to_date']}.', '" . USER_DIV . "', '{$item_data['total']}',\n\t\t\t\t'{$unitcost}', '{$hire_sales}', '2', '{$unitcost}',\n\t\t\t\t'{$item_data['asset_id']}', '{$item_id}', '{$item_data['total_days']}',\n\t\t\t\t'{$rate}')";
            db_exec($sql) or errDie("Unable to create invoice item.");
            // Add up revenue
            $sql = "\n\t\t\tINSERT INTO hire.revenue (group_id, asset_id, total, discount,\n\t\t\t\thire_invnum, inv_invnum, cusname)\n\t\t\tVALUES ('{$item_data['grpid']}', '{$item_data['asset_id']}',\n\t\t\t\t'{$item_data['total']}', '0', '0',\n\t\t\t\t'0', '{$inv_data['surname']}')";
            db_exec($sql) or errDie("Unable to update revenue");
            $sql = "\n\t\t\tUPDATE hire.assets_hired SET return_time=CURRENT_TIMESTAMP\n\t\t\t\tWHERE item_id='{$item_data['id']}'";
            db_exec($sql) or errDie("Unable to update hired assets.");
            $sql = "\n\t\t\tSELECT serial2 FROM cubit.assets\n\t\t\tWHERE id='{$item_data['asset_id']}'";
            $asset_rslt = db_exec($sql) or errDie("Unable to retrieve asset");
            $asset_data = pg_fetch_array($asset_rslt);
            if (!isSerialized($item_data["asset_id"])) {
                $new_qty = $asset_data["serial2"] + $item_data["qty"];
                $sql = "\n\t\t\t\tUPDATE cubit.assets SET serial2=(serial2::numeric + '{$item_data['qty']}')\n\t\t\t\tWHERE id='{$item_data['asset_id']}'";
                db_exec($sql) or errDie("Unable to update asset qty.");
            }
        }
        $refnum = getRefnum();
        writetrans($cust_control, $hire_sales, date("Y-m-d", $time), $refnum, $inv_data["total"], "Non Stock Sales on invoice No. {$inv_data['id']} " . "customer {$inv_data['surname']}");
        // Sales record
        $sql = "\n\t\tINSERT INTO cubit.salesrec(edate, invid, invnum, debtacc, vat, total,\n\t\t\ttyp, div)\n\t\tVALUES('" . date("Y-m-d", $time) . "', '{$invid}', '{$inv_data['id']}',\n\t\t\t'{$cust_control}', '{$inv_data['vat']}', '{$inv_data['total']}', 'non',\n\t\t\t'" . USER_DIV . "')";
        db_exec($sql) or errDie("Unable to create sales record.");
        // Vat record
        vatr(2, date("Y-m-d", $time), "OUTPUT", '01', $refnum, "Non-Stock Sales, invoice No.{$inv_data['id']}", $inv_data["total"], $inv_data["vat"]);
        // Add to statement
        $sql = "\n\t\tINSERT INTO cubit.stmnt (cusnum, invid, docref, amount, date, type, div)\n\t\tVALUES ('{$inv_data['cusnum']}', '{$invid}', '{$inv_data['order_num']}',\n\t\t\t'{$inv_data['total']}', '" . date("Y-m-d", $time) . "',\n\t\t\t'Hire Invoice {$inv_data['id']}', '" . USER_DIV . "')";
        db_exec($sql) or errDie("Unable to add to statement.");
        // Update customer balance
        $sql = "\n\t\tUPDATE customers SET balance = (balance + '{$inv_data['total']}')\n\t\tWHERE cusnum='{$inv_data['cusnum']}' AND div='" . USER_DIV . "'";
        db_exec($sql) or errDie("Unable to update customer balance.");
        custledger($inv_data["cusnum"], $hire_sales, date("Y-m-d", $time), $invid, "Hire Invoice No. {$inv_data['id']}", $inv_data["total"], "d");
        custDT($inv_data["total"], $inv_data["cusnum"], date("Y-m-d", $time));
    }
    // Clear outstanding tables
    $sql = "DELETE FROM cubit.hire_trans";
    db_exec($sql) or errDie("Unable to remove outstanding (1)");
    $sql = "DELETE FROM cubit.hire_trans_items";
    db_exec($sql) or errDie("Unable to remove outstanding (2)");
    $sql = "DELETE FROM cubit.hire_invoice_trans";
    db_exec($sql) or errDie("Unable to remove outstanding (3)");
    $sql = "DELETE FROM cubit.hire_invoice_items_trans";
    db_exec($sql) or errDie("Unable to remove outstanding (4)");
    pglib_transaction("COMMIT");
    return enter();
}