function invoice_form_details_process($type, $mode, $returnpage_error, $returnpage_success)
{
    log_debug("inc_invoices_forms", "Executing invoice_form_details_process({$type}, {$mode}, {$returnpage_error}, {$returnpage_success})");
    // TODO: it seems this function requests the $mode, but then works it out itself anyway.
    // check out what is going on here.
    /*
    	Start the invoice
    */
    $invoice = new invoice();
    $invoice->type = $type;
    /*
    	Fetch all form data
    */
    // get the ID for an edit
    if ($mode == "edit") {
        $invoice->id = @security_form_input_predefined("int", "id_invoice", 1, "");
    }
    // general details
    if ($type == "ap") {
        $invoice->data["vendorid"] = @security_form_input_predefined("int", "vendorid", 1, "");
    } else {
        $invoice->data["customerid"] = @security_form_input_predefined("int", "customerid", 1, "");
    }
    $invoice->data["employeeid"] = @security_form_input_predefined("int", "employeeid", 1, "");
    $invoice->data["notes"] = @security_form_input_predefined("any", "notes", 0, "");
    $invoice->data["code_ordernumber"] = @security_form_input_predefined("any", "code_ordernumber", 0, "");
    $invoice->data["code_ponumber"] = @security_form_input_predefined("any", "code_ponumber", 0, "");
    $invoice->data["date_trans"] = @security_form_input_predefined("date", "date_trans", 1, "");
    $invoice->data["date_due"] = @security_form_input_predefined("date", "date_due", 1, "");
    // other
    $invoice->data["dest_account"] = @security_form_input_predefined("int", "dest_account", 1, "");
    // are we editing an existing invoice or adding a new one?
    if ($invoice->id) {
        $mode = "edit";
        // make sure the invoice actually exists
        if (!$invoice->verify_invoice()) {
            log_write("error", "process", "The invoice you have attempted to edit - " . $invoice->id . " - does not exist in this system.");
        }
        // check if invoice is locked or not
        if ($invoice->check_lock()) {
            log_write("error", "process", "The invoice can not be edited because it is locked.");
        }
    } else {
        $mode = "add";
    }
    // invoice must be provided by edit page, but not by add invoice, since we can just generate a new one
    if ($mode == "add") {
        $invoice->data["code_invoice"] = @security_form_input_predefined("any", "code_invoice", 0, "");
    } else {
        $invoice->data["code_invoice"] = @security_form_input_predefined("any", "code_invoice", 1, "");
    }
    //// ERROR CHECKING ///////////////////////
    // make sure we don't choose a invoice invoice number that is already in use
    if ($invoice->data["code_invoice"]) {
        $invoice->prepare_code_invoice($invoice->data["code_invoice"]);
    }
    /// if there was an error, go back to the entry page
    if ($_SESSION["error"]["message"]) {
        $_SESSION["error"]["form"][$type . "_invoice_" . $mode] = "failed";
        header("Location: ../../index.php?page={$returnpage_error}&id=" . $invoice->id . "");
        exit(0);
    } else {
        // GENERATE INVOICE ID
        // if no invoice ID has been supplied, we now need to generate a unique invoice id
        if (!$invoice->data["code_invoice"]) {
            $invoice->prepare_code_invoice();
        }
        // APPLY GENERAL OPTIONS
        if ($mode == "add") {
            // create a new invoice
            if ($invoice->action_create()) {
                $_SESSION["notification"]["message"][] = "Invoice successfully created.";
                journal_quickadd_event("account_" . $invoice->type . "", $invoice->id, "Invoice successfully created");
            } else {
                $_SESSION["error"]["message"] = "An error occured whilst attempting to create the invoice";
            }
            // display items page
            $returnpage_success = str_replace("view", "items", $returnpage_success);
            header("Location: ../../index.php?page={$returnpage_success}&id=" . $invoice->id . "");
        } else {
            // update an existing invoice
            if ($invoice->action_update()) {
                $_SESSION["notification"]["message"][] = "Invoice successfully updated.";
                journal_quickadd_event("account_" . $invoice->type . "", $invoice->id, "Invoice successfully updated");
            } else {
                $_SESSION["error"]["message"] = "An error occured whilst attempting to update the invoice";
            }
            // display updated details
            header("Location: ../../index.php?page={$returnpage_success}&id=" . $invoice->id . "");
        }
        exit(0);
    }
    // end if passed tests
}
 function set_invoice_details($id, $invoicetype, $locked, $orgid, $employeeid, $dest_account, $code_invoice, $code_ordernumber, $code_ponumber, $date_due, $date_trans, $date_sent, $sendmethod, $notes)
 {
     log_debug("accounts_invoices_manage", "Executing set_invoice_details({$id}, {$invoicetype}, values...)");
     // check the invoicetype
     if ($invoicetype != "ar" && $invoicetype != "ap") {
         throw new SoapFault("Sender", "INVALID_INVOICE_TYPE");
     }
     if (user_permissions_get("accounts_" . $invoicetype . "_write")) {
         $obj_invoice = new invoice();
         $obj_invoice->type = $invoicetype;
         /*
         	Load SOAP Data
         
         	TODO: a number of these options might just be ignored by the action_update command - look
         		into this possiblity
         */
         $obj_invoice->id = @security_script_input_predefined("int", $id);
         $obj_invoice->data["locked"] = @security_script_input_predefined("int", $locked);
         if ($invoicetype == "ap") {
             $obj_invoice->data["vendorid"] = @security_script_input_predefined("int", $orgid);
         } else {
             $obj_invoice->data["customerid"] = @security_script_input_predefined("int", $orgid);
         }
         $obj_invoice->data["employeeid"] = @security_script_input_predefined("int", $employeeid);
         $obj_invoice->data["dest_account"] = @security_script_input_predefined("int", $dest_account);
         $obj_invoice->data["code_invoice"] = @security_script_input_predefined("any", $code_invoice);
         $obj_invoice->data["code_ordernumber"] = @security_script_input_predefined("any", $code_ordernumber);
         $obj_invoice->data["code_ponumber"] = @security_script_input_predefined("any", $code_ponumber);
         $obj_invoice->data["date_due"] = @security_script_input_predefined("date", $date_due);
         $obj_invoice->data["date_trans"] = @security_script_input_predefined("date", $date_trans);
         $obj_invoice->data["date_sent"] = @security_script_input_predefined("date", $date_sent);
         $obj_invoice->data["sentmethod"] = @security_script_input_predefined("any", $sentmethod);
         $obj_invoice->data["notes"] = @security_script_input_predefined("any", $notes);
         foreach (array_keys($obj_invoice->data) as $key) {
             // TODO: what the f**k is wrong with php here???
             //
             // weird bug work around - without the != 0 statement, $obj_invoice->data["locked"] will
             // match "error", despite equaling 0.
             if ($obj_invoice->data[$key] == "error" && $obj_invoice->data[$key] != 0) {
                 throw new SoapFault("Sender", "INVALID_INPUT");
             }
         }
         /*
         	Error Handling
         */
         // verify invoice exisitance (if editing an existing one)
         if ($obj_invoice->id) {
             if (!$obj_invoice->verify_invoice()) {
                 throw new SoapFault("Sender", "INVALID_INVOICE");
             }
             // make sure invoice is not locked
             if ($obj_invoice->check_lock()) {
                 throw new SoapFault("Sender", "LOCKED");
             }
         }
         // make sure we don't choose a invoice code that has already been taken
         if (!$obj_invoice->prepare_code_invoice($obj_invoice->data["code_invoice"])) {
             throw new SoapFault("Sender", "DUPLICATE_CODE_INVOICE");
         }
         /*
         	Perform Changes
         */
         if ($obj_invoice->id) {
             // update existing invoice
             if ($obj_invoice->action_update()) {
                 return $obj_invoice->id;
             } else {
                 throw new SoapFault("Sender", "UNEXPECTED_ACTION_ERROR");
             }
         } else {
             // create new invoice
             if ($obj_invoice->action_create()) {
                 return $obj_invoice->id;
             } else {
                 throw new SoapFault("Sender", "UNEXPECTED_ACTION_ERROR");
             }
         }
     } else {
         throw new SoapFault("Sender", "ACCESS DENIED");
     }
 }