function takeOrderFromDataBase($OID)
{
    $data = array();
    $data["OID"] = $OID;
    $order = dbGetOrder($OID);
    $data["customerONotes"] = $order["CustomerONotes"];
    $data["adminONotes"] = $order["AdminONotes"];
    $data["isExpedited"] = $order["IsExpedited"];
    $data["orderedDate"] = date("m/d/Y", $order["OrderedDate"]);
    // note that ShippingFee, ExpediteFee, and Discount are null
    // if not specified - to distinquish them from being 0.00
    // translate the null to a blank string here, then back to
    // null on the way out of the form.
    $data["shippingFee"] = $order["ShippingFee"];
    if ($data["shippingFee"] === null) {
        $data["shippingFee"] = "";
    }
    $data["expediteFee"] = $order["ExpediteFee"];
    if ($data["expediteFee"] === null) {
        $data["expediteFee"] = "";
    }
    $data["discount"] = $order["Discount"];
    if ($data["discount"] === null) {
        $data["discount"] = "";
    }
    $items = dbGetItems($OID);
    $i = 1;
    foreach ($items as $item) {
        $data["iid{$i}"] = $item["IID"];
        $data["personality{$i}"] = $item["Personality"];
        $data["packages{$i}"] = $item["PKID"];
        $data["quantity{$i}"] = $item["Quantity"];
        $i++;
    }
    return $data;
}
function lockInFees($oid)
{
    global $SETTINGS;
    $changed = false;
    $mod = array();
    $order = dbGetOrder($oid);
    if ($order["IsExpedited"] && $order["ExpediteFee"] === null) {
        $changed = true;
        $mod["ExpediteFee"] = $SETTINGS["ExpediteFeeDefault"];
    }
    if ($order["ShippingFee"] === null) {
        $changed = true;
        $items = dbGetItems($oid);
        // TODO - this isn't a GREAT way to calculate shipping because
        //        it will also count little things.
        $count = 0;
        foreach ($items as $item) {
            $count += $item["Quantity"];
        }
        $mod["ShippingFee"] = $count * $SETTINGS["ShippingPerChapR"];
    }
    dbOrderModify($oid, $mod);
}
function main($oid)
{
    // a packing list has all of the standard stuff on it, including
    // the order number, customer, address, but no price information.
    // it combines multiple items into one NUMBERED item along with the
    // stuff that should go into it.  It also includes a field for
    // notes that then need to be transcribed to shipping.
    $order = dbGetOrder($oid);
    $items = getItems($oid);
    $mapping = dbGetPVP();
    $pieces = dbGetPieces();
    if (!$order) {
        echo "Can't find order {$oid}\n";
        return;
    }
    $customer = dbGetCustomer($order["CID"]);
    if (!$customer) {
        echo "Can't find customer for order {$oid}\n";
        return;
    }
    // set-up the PDF output mechanism
    $pdf = pdfSetup();
    // and craft the coordinates of the different areas on the page
    $layout = layout();
    // draw the little boxes around the different areas
    plBoxes($pdf, $layout);
    // the go for all of the data
    titleArea($pdf, $layout["title"], $oid, $order, $customer, $items, $mapping, $pieces);
    customerArea($pdf, $layout["customer"], $oid, $order, $customer, $items, $mapping, $pieces);
    statusArea($pdf, $layout["status"], $oid, $order, $customer, $items, $mapping, $pieces);
    itemsArea($pdf, $layout["items"], $oid, $order, $customer, $items, $mapping, $pieces);
    shippingArea($pdf, $layout["shipping"], $oid, $order, $customer, $items, $mapping, $pieces);
    dateArea($pdf, $layout["date"], $oid, $order, $customer, $items, $mapping, $pieces);
    $pdf->lastPage();
    $pdf->Output('Order-$oid.pdf', 'I');
}
function dbOrderDuplicate($oid)
{
    $order = dbGetOrder($oid);
    if (!$order) {
        return null;
    }
    // remove the OID from $order, before insertion
    unset($order["OID"]);
    $newoid = dbInsertNewOrder($order["CID"], $order);
    if (!$newoid) {
        dbOrderDelete($newoid);
        return null;
    }
    $items = dbGetItems($oid);
    if ($items) {
        foreach ($items as $item) {
            unset($item["IID"]);
            $newiid = dbInsertNewItem($newoid, $item);
            if (!$newiid) {
                dbOrderDelete($newoid);
                // this still leaves orphan items
                return null;
            }
        }
    }
    return $newoid;
}
function paypalProcessIPN($fields, $goodTransaction)
{
    if ($goodTransaction) {
        // process the good transaction here - or at least it "looks" good for now
        // DEBUGGING CODE - useful...
        //         asyncDebug("here");
        //	  ob_start();
        //	  var_dump($fields);
        //	  $dfields = ob_get_contents();
        //	  ob_end_clean();
        //	  asyncDebug($dfields);
        if (array_key_exists("payment_status", $fields) && $fields["payment_status"] == "Completed") {
            $invoice = null;
            $date = null;
            if (array_key_exists("invoice_id", $fields)) {
                $invoice = $fields["invoice_id"];
            } else {
                // Sep 14, 2015 - while checking to see if the paypal switch to G5
                // was going to cause us problems, I found that the sandbox didn't
                // allow send of invoice_id.  I'm hoping that this is a sandbox
                // problem only...the following else allows it to work anyway.
                //		 if(array_key_exists("invoice",$fields)) {
                //		    $invoice = $fields["invoice"];
                //		 }
            }
            if (array_key_exists("payment_date", $fields)) {
                $date = strtotime($fields["payment_date"]);
            }
            if ($date !== null && $invoice !== null) {
                // now we have a completed payment for a particular invoice
                // see if we can track it down, and if we can, mark it as paid
                dbOrderMarkInvoicePaid($invoice, $date);
                // we'll get the following address fields in:
                // 'address_street' => may have a \r\n between two lines
                // 'address_zip' => may be 5/9 chars
                // 'address_country_code' => 'US',
                // 'address_name' => 'Eric Rothfus',
                // 'address_city' => 'AUSTIN',
                // 'address_state' => 'TX',
                // Paypal will come back with an address - for the old ChapR data, there is
                // no address, so we need to slam it into the address.  For the new records
                // the address may change (someone wants to ship to a different place).  If
                // that is the case, keep the old address but make a note in the order notes.
                // so we'll do a comparison, and if it changed, slam in the
                // new address - making a note about the change
                $street1 = "";
                $street2 = "";
                $streets = explode("\n", str_replace("\r", "", $fields["address_street"]));
                $street1 = $streets[0];
                if (count($streets) > 1) {
                    $street2 = $streets[1];
                }
                $country = $fields["address_country_code"];
                $state = $fields["address_state"];
                $zip = $fields["address_zip"];
                $name = $fields["address_name"];
                $city = $fields["address_city"];
                $oid = $fields["invoice_number"];
                $order = dbGetOrder($oid);
                $cid = $order["CID"];
                $customer = dbGetCustomer($cid);
                // we define no address as an address that is missing a street and city
                $noAddress = trim($customer["Street1"] . $customer["Street2"] . $customer["City"]) == "";
                if ($noAddress) {
                    $changes = array();
                    $changes["Street1"] = $street1;
                    $changes["Street2"] = $street2;
                    $changes["City"] = $city;
                    $changes["State"] = $state;
                    $changes["Zip"] = $zip;
                    $changes["Country"] = $country;
                    dbUpdate("customers", $changes, "CID", $cid);
                    $addOrderNote = "Paypal Inserted New Address.";
                    if (strtolower($name) != strtolower($customer["FirstName"] . " " . $customer["LastName"])) {
                        $addOrderNote .= "\n\tName: {$name}";
                    }
                    dbOrderAppendAdminONotes($oid, $addOrderNote);
                } else {
                    // here, check to see if it is a different address, make a note if so
                    if (strtolower($name) != strtolower($customer["FirstName"] . " " . $customer["LastName"]) || strtolower($street1) != strtolower($customer["Street1"]) || strtolower($street2) != strtolower($customer["Street2"]) || strtolower($city) != strtolower($customer["City"]) || strtolower($state) != strtolower($customer["State"]) || strtolower($country) != strtolower($customer["Country"]) || strtolower($zip) != strtolower($customer["Zip"])) {
                        $addOrderNote = "SHIPPING ADDRESS (from Paypal):\n\t{$name}\n\t{$street1}\n";
                        if ($street2) {
                            $addOrderNote .= "\t{$street2}\n";
                        }
                        $addOrderNote .= "\t{$city}, {$state} {$zip} {$country}\n";
                        dbOrderAppendAdminONotes($oid, $addOrderNote);
                    }
                }
                // TODO - need to be VERY CLEAR on our forms that the address
                //  that the user is supplying is the SHIPPING ADDRESS
            }
        }
    }
    // TODO - we silently fail for everything:
    //		- bad transaction
    //		- one with a different status     //		- one where an invoice was paid that we don't know about
}
function main($oid, $pdflink)
{
    // a packing list has all of the standard stuff on it, including
    // the order number, customer, address, but no price information.
    // it combines multiple items into one NUMBERED item along with the
    // stuff that should go into it.  It also includes a field for
    // notes that then need to be transcribed to shipping.
    $order = dbGetOrder($oid);
    $items = getItems($oid);
    $mapping = dbGetPVP();
    $pieces = dbGetPieces();
    if (!$order) {
        echo "Can't find order {$oid}\n";
        return;
    }
    $customer = dbGetCustomer($order["CID"]);
    if (!$customer) {
        echo "Can't find customer for order {$oid}\n";
        return;
    }
    echo "<div align=\"right\"><font size=\"-2\"><a href=\"{$pdflink}?oid={$oid}\">PDF Version</a></font></div>\n";
    // the whole thing is one big table
    echo "<table class=\"packinglist\">\n";
    // first, the header with "Order: XXX"
    echo "<tr><td class=\"ordertitle\" colspan=\"3\">";
    if ($order["IsExpedited"]) {
        echo standardIcon("expedite") . "&nbsp;&nbsp;";
    }
    if ($order["Charity"]) {
        echo standardIcon("charity") . "&nbsp;&nbsp;";
    }
    echo "Order: <strong>{$oid}</strong>";
    if ($order["Charity"]) {
        echo "&nbsp;&nbsp;" . standardIcon("charity");
    }
    if ($order["IsExpedited"]) {
        echo "&nbsp;&nbsp;" . standardIcon("expedite");
    }
    echo "</td></tr>\n";
    // now paint the "To:" and "Status"
    echo "<tr><td width=\"50%\">\n";
    echo "<table><tr><td class=\"title\" colspan=\"2\"><strong>Customer</strong></td></tr>\n";
    echo htmlCustomerAddress($customer);
    echo "</table></td>\n";
    echo "<td width=\"50%\">\n";
    echo "<table><tr><td class=\"title\" colspan=\"3\"><strong>Status</strong></td></tr>\n";
    //     echo("<tr><td>");
    echo htmlOrderStatus($order);
    //     echo("</td></tr>");
    echo "<tr><td class=\"title\" colspan=\"3\"><strong>Order Notes</strong></td></tr>\n";
    echo "<tr><td colspan=\"3\">" . htmlNotesFormat($order["CustomerONotes"]) . "</td></tr>\n";
    echo "<tr><td colspan=\"3\"><em>" . htmlNotesFormat($order["AdminONotes"]) . "</em></td></tr>\n";
    echo "</table></td>\n";
    echo "</tr>\n";
    // the middle part of the packing list is the actual list of items and components
    echo "<tr><td colspan=2>\n";
    echo "<table class=\"packingItems\">\n";
    echo "<tr><td class=\"title\" colspan=\"3\"><strong>Shipment Items</strong></td></tr>\n";
    echo "<tr><td style=\"border-bottom:1px solid; text-align:center;\"><strong>Count</strong></td>";
    echo "<td style=\"border-bottom:1px solid;\" width=\"50%\"><strong>Item</strong></td>";
    echo "<td style=\"border-bottom:1px solid;\" ><strong>Notes</strong> <em><font size=-1>(include ChapR number(s) if applicable)</font></em></td</tr>\n";
    echo "<tr><td>&nbsp;</td></tr>\n";
    foreach ($items as $item) {
        echo "<tr>";
        echo "<td class=\"qty\">" . $item["Quantity"] . " x</td>";
        echo "<td><p class=\"itemtitle\">" . $item["Name"] . "</p>";
        echo "<UL>";
        if ($item["Personality"]) {
            echo "<LI>" . $item["Personality"] . "</LI>";
        }
        // now get all of the pieces in the package
        foreach ($mapping as $map) {
            if ($map["PKID"] == $item["PKID"]) {
                echo "<LI>" . findPieceName($map["PID"], $pieces) . "</LI>\n";
            }
        }
        echo "</UL></td>";
        echo "<td></td>";
        echo "</tr>";
    }
    echo "</table></td></tr>\n";
    // the bottom part of the packing list is the shipment note section
    echo "<tr><td colspan=2>\n";
    echo "<table class=\"packingShipping\">\n";
    echo "<tr><td class=\"title\" colspan=\"6\"><strong>Shipment Details</strong></td></tr>\n";
    echo "<tr>";
    echo "<td class=\"fieldName\">Date Shipped: </td><td class=\"field\"></td>\n";
    echo "<td class=\"fieldName\">Carrier: </td><td class=\"field\"></td>\n";
    echo "<td class=\"fieldName\">Tracking #: </td><td class=\"field\"></td>\n";
    echo "</tr>";
    echo "</table></td></tr>\n";
    echo "</table>\n";
}