Example #1
0
 function render_html()
 {
     // Title + Summary
     print "<h3>TRANSACTION DETAILS</h3><br>";
     print "<p>This page allows you to view and adjust the selected transaction.</p>";
     /*
     	Display the form
     
     	We have to do this manually in order to be able to handle all the transaction rows
     */
     // start form/table structure
     print "<form method=\"" . $this->obj_form->method . "\" action=\"" . $this->obj_form->action . "\" class=\"form_standard\">";
     print "<table class=\"form_table\" width=\"100%\">";
     // general form fields
     print "<tr class=\"header\">";
     print "<td colspan=\"2\"><b>" . language_translate_string($_SESSION["user"]["lang"], "general_ledger_transaction_details") . "</b></td>";
     print "</tr>";
     $this->obj_form->render_row("code_gl");
     $this->obj_form->render_row("date_trans");
     $this->obj_form->render_row("employeeid");
     $this->obj_form->render_row("description");
     $this->obj_form->render_row("description_useall");
     $this->obj_form->render_row("notes");
     print "</tr>";
     /*
     	Transaction Rows
     
     	This section is the most complex part of the form, where we add new rows to the form
     	for each transactions.
     */
     print "<tr class=\"header\">";
     print "<td colspan=\"2\"><b>" . language_translate_string($_SESSION["user"]["lang"], "general_ledger_transaction_rows") . "</b></td>";
     print "</tr>";
     print "<tr>";
     print "<td colspan=\"2\">";
     // header
     print "<table width=\"100%\">";
     print "<tr>";
     print "<td width=\"100%\" colspan=\"5\"><p>Enter all the parts of the transaction in the fields below. Because this is a double-entry accounting system, remember that you need to credit the source account and then debit the destination account, and that the totals for both the credit and debit accounts needs to match.</p></td>";
     print "</tr>";
     print "<tr>";
     print "<td width=\"20%\"><b>Account</b></td>";
     print "<td width=\"15%\"><b>Debit (dest)</b></td>";
     print "<td width=\"15%\"><b>Credit (src)</b></td>";
     print "<td width=\"15%\"><b>Source</b></td>";
     print "<td width=\"35%\"><b>Description</b></td>";
     print "</tr>";
     // display all the rows
     for ($i = 0; $i < $this->num_trans; $i++) {
         if (isset($_SESSION["error"]["trans_" . $i . "-error"])) {
             print "<tr class=\"form_error\">";
         } else {
             print "<tr class=\"table_highlight\">";
         }
         // account
         print "<td width=\"20%\" valign=\"top\">";
         $this->obj_form->render_field("trans_" . $i . "_account");
         print "</td>";
         // debit
         print "<td width=\"15%\" valign=\"top\">";
         $this->obj_form->render_field("trans_" . $i . "_debit");
         print "</td>";
         // credit
         print "<td width=\"15%\" valign=\"top\">";
         $this->obj_form->render_field("trans_" . $i . "_credit");
         print "</td>";
         // source
         print "<td width=\"15%\" valign=\"top\">";
         $this->obj_form->render_field("trans_" . $i . "_source");
         print "</td>";
         // description
         print "<td width=\"35%\" valign=\"top\">";
         $this->obj_form->render_field("trans_" . $i . "_description");
         print "</td>";
         print "</tr>";
     }
     /*
     	Totals Display
     */
     print "<tr class=\"table_highlight\">";
     // joining/filler columns
     print "<td width=\"20%\"></td>";
     // total debit
     print "<td width=\"15%\">";
     $this->obj_form->render_field("total_debit");
     print "</td>";
     // total credit
     print "<td width=\"15%\">";
     $this->obj_form->render_field("total_credit");
     print "</td>";
     // joining/filler columns
     print "<td width=\"15%\"></td>";
     print "<td width=\"35%\"></td>";
     print "</tr>";
     print "</table>";
     print "</td>";
     print "</tr>";
     // hidden fields
     $this->obj_form->render_field("id_transaction");
     $this->obj_form->render_field("num_trans");
     $this->obj_form->render_field("money_format");
     // form submit
     print "<tr class=\"header\">";
     print "<td colspan=\"2\"><b>" . language_translate_string($_SESSION["user"]["lang"], "general_ledger_transaction_submit") . "</b></td>";
     print "</tr>";
     if (user_permissions_get("accounts_gl_write") && !$this->locked) {
         $this->obj_form->render_row("submit");
     }
     // end table + form
     print "</table>";
     print "</form>";
     if (!user_permissions_get("accounts_gl_write")) {
         format_msgbox("locked", "<p>Sorry, you do not have permission to adjust this transaction</p>");
     } elseif ($this->locked) {
         format_msgbox("locked", "<p>This transaction has been locked and can no longer be adjusted.</p>");
     }
 }
Example #2
0
function security_form_input_predefined($type, $valuename, $numchar, $errormsg)
{
    $expression = NULL;
    // run through the actions for each item type
    switch ($type) {
        case "any":
            $expression = "/^[\\S\\s]*\$/";
            break;
        case "date":
            // TODO: audit the error handling in this function, seems like it's generating
            // messages which are used for no reason.
            // if there is no errormsg supplied, set a default one by looking
            // up the translation of the fieldname and reporting it.
            if ($errormsg == "") {
                $translation = language_translate_string($_SESSION["user"]["lang"], $valuename);
                $errormsg = "Invalid {$translation} supplied, please correct.";
            }
            // dates are a special field, since they have to be passed
            // from the form as 3 different inputs, but we want to re-assemble them
            // into a single YYYY-MM-DD format
            $date_dd = intval($_POST[$valuename . "_dd"]);
            $date_mm = intval($_POST[$valuename . "_mm"]);
            $date_yyyy = intval($_POST[$valuename . "_yyyy"]);
            // make sure a date has been provided
            if ($numchar) {
                if ($date_dd < 1 || $date_dd > 31) {
                    $errormsg_tmp = "Invalid date input";
                }
                if ($date_mm < 1 || $date_mm > 12) {
                    $errormsg_tmp = "Invalid date input";
                }
                if ($date_yyyy < 1600 || $date_yyyy > 2999) {
                    $errormsg_tmp = "Invalid date input";
                }
            } else {
                // the date is not a required field, but we need to make sure any input is valid
                if ($date_dd > 31) {
                    $errormsg_tmp = "Invalid date input";
                }
                if ($date_mm > 12) {
                    $errormsg_tmp = "Invalid date input";
                }
                if ($date_yyyy > 2999) {
                    $errormsg_tmp = "Invalid date input";
                }
            }
            // make sure user has filled in all 3 date fields
            if ($date_dd && (!$date_mm || !$date_yyyy)) {
                $errormsg_tmp = "Invalid date input";
            }
            if ($date_mm && (!$date_dd || !$date_yyyy)) {
                $errormsg_tmp = "Invalid date input";
            }
            if ($date_yyyy && (!$date_dd || !$date_mm)) {
                $errormsg_tmp = "Invalid date input";
            }
            // pad dates
            $date_dd = sprintf("%02d", $date_dd);
            $date_mm = sprintf("%02d", $date_mm);
            $date_yyyy = sprintf("%04d", $date_yyyy);
            // join the dates
            $date_final = "{$date_yyyy}-{$date_mm}-{$date_dd}";
            if ($errormsg_tmp) {
                // there has been an error - flag the hourmins field as being incorrect input
                $_SESSION["error"]["message"][] = $errormsg;
                $_SESSION["error"]["" . $valuename . "-error"] = 1;
                $_SESSION["error"][$valuename] = 0;
            } else {
                // save value incase of errors
                $_SESSION["error"][$valuename] = $date_final;
            }
            // return the value
            return $date_final;
            break;
        case "hourmins":
            // hourmins is a special field - we want to take
            // two fields (hours + mins) and add then together
            // to produce the number of seconds.
            // if there is no errormsg supplied, set a default one by looking
            // up the translation of the fieldname and reporting it.
            if ($errormsg == "") {
                $translation = language_translate_string($_SESSION["user"]["lang"], $valuename);
                $errormsg = "Invalid {$translation} supplied, please correct.";
            }
            $time_hh = intval($_POST[$valuename . "_hh"]);
            $time_mm = intval($_POST[$valuename . "_mm"]);
            // caclulate the time in seconds
            $timestamp = $time_mm * 60 + $time_hh * 60 * 60;
            // make sure a value has been provided
            if ($numchar && $timestamp == 0) {
                $_SESSION["error"]["message"][] = $errormsg;
                $_SESSION["error"]["" . $valuename . "-error"] = 1;
                $_SESSION["error"][$valuename] = 0;
            } else {
                $_SESSION["error"][$valuename] = $timestamp;
            }
            return $timestamp;
            break;
        case "date_string":
            $expression = "/^[0-9]*-[0-9]*-[0-9]*\$/";
            break;
        case "int":
            $expression = "/^[0-9]*\$/";
            break;
        case "money":
            // if there is no errormsg supplied, set a default one by looking
            // up the translation of the fieldname and reporting it.
            if ($errormsg == "") {
                $translation = language_translate_string($_SESSION["user"]["lang"], $valuename);
                $errormsg = "Invalid {$translation} supplied, please correct.";
            }
            // replace configs with standard symbols for processing
            $config_array = array($GLOBALS["config"]["CURRENCY_DEFAULT_SYMBOL"], $GLOBALS["config"]["CURRENCY_DEFAULT_THOUSANDS_SEPARATOR"], $GLOBALS["config"]["CURRENCY_DEFAULT_DECIMAL_SEPARATOR"]);
            $default_array = array("", "", ".");
            $formatted_string = str_replace($config_array, $default_array, $_POST[$valuename]);
            $_POST[$valuename] = $formatted_string;
            // verify as a floating point number
            $expression = "/^[0-9]*.[0-9]*\$/";
            $value = security_form_input($expression, $valuename, $numchar, $errormsg);
            // perform padding
            if ($value != "error") {
                $value = sprintf("%0.2f", $value);
            }
            // trigger error if value is 0.00
            if ($numchar && $value == "0.00") {
                $_SESSION["error"]["message"][] = $errormsg;
                $_SESSION["error"]["" . $valuename . "-error"] = 1;
                $_SESSION["error"][$valuename] = 0;
            }
            return $value;
            break;
        case "float":
            // value could be a float, or an integer - we need to check for either
            if (preg_match("/^[0-9]*\$/", $_POST[$valuename])) {
                // is an int
                $expression = "/^[0-9]*\$/";
            } else {
                // either float or invalid - run check for int
                $expression = "/^[0-9]*.[0-9]*\$/";
            }
            break;
        case "email":
            $expression = "/^([A-Za-z0-9._-])+\\@(([A-Za-z0-9-])+\\.)+([A-Za-z0-9])+\$/";
            break;
        case "multiple_email":
            // Single email address
            $email_regex = "/^<?(([A-Za-z0-9._-])+\\@(([A-Za-z0-9-])+\\.)+([A-Za-z0-9])+)>?\$/";
            // Whole email address string
            $expression = "/^(([A-Za-z0-9._-])+\\@(([A-Za-z0-9-])+\\.)+([A-Za-z0-9])+,?\\s?)+\$/";
            // grab submitted data from $_POST
            $unsafe_email_addresses = $_POST[$valuename];
            // split at spaces and commas
            $email_address_string_parts = preg_split("/[\\s,]+/", $unsafe_email_addresses);
            $email_addresses = array();
            foreach ($email_address_string_parts as $email_address_string_part) {
                // check each item against the email address regex, capture the email address
                preg_match($email_regex, $email_address_string_part, $matches);
                // if we have an email address, add it to the array
                if ($matches[1] != '') {
                    $email_addresses[] = $matches[1];
                }
            }
            // implode the email addresses using a comma and a space
            $new_email_address_string = implode(", ", $email_addresses);
            // recheck the string., if it passes, return it
            preg_match($expression, $new_email_address_string, $matches);
            if ($matches[0] == $new_email_address_string) {
                return $matches[0];
            } else {
                return "error";
            }
            break;
        case "ipv4":
            $expression = "/^(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)(?:[.](?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)){3}\$/";
            break;
        case "ipv4_cidr":
            $expression = "/^(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)(?:[.](?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)){3}[\\/]*[1-9]*\$/";
            break;
        case "ipv6":
            if (filter_var($_POST[$valuename], FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) {
                return $_POST[$valuename];
            } else {
                // there has been an error - flag the hourmins field as being incorrect input
                $_SESSION["error"]["message"][] = "Provided address is not a valid IPv6 address";
                $_SESSION["error"]["" . $valuename . "-error"] = 1;
                $_SESSION["error"][$valuename] = 0;
                return "error";
            }
            break;
        case "ipv6_cidr":
            list($network, $cidr) = split("/", $_POST[$valuename]);
            if (filter_var($network, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) {
                return "{$network}/{$cidr}";
            } else {
                // there has been an error - flag the hourmins field as being incorrect input
                $_SESSION["error"]["message"][] = "Provided address is not a valid IPv6 address";
                $_SESSION["error"]["" . $valuename . "-error"] = 1;
                $_SESSION["error"][$valuename] = 0;
                return "error";
            }
            break;
        case "checkbox":
            if ($_POST[$valuename]) {
                $_SESSION["error"][$valuename] = 1;
                return 1;
            } else {
                $_SESSION["error"][$valuename] = 0;
                return 0;
            }
            break;
        default:
            print "Warning: No such security check for type {$type}<br>";
            $expression = "/^[\\S\\s]*\$/";
            break;
    }
    return security_form_input($expression, $valuename, $numchar, $errormsg);
}
Example #3
0
 function render_form()
 {
     log_debug("form", "Executing render_form()");
     if (!$this->action || !$this->method) {
         log_write("warning", "inc_form", "No form action or method defined for form class");
     }
     // if we have not choosen to use subforms, then add all values to a single form.
     if (!$this->subforms) {
         $this->subforms[$this->formname] = array_keys($this->structure);
     }
     // start form
     print "<form enctype=\"multipart/form-data\" method=\"" . $this->method . "\" action=\"" . $this->action . "\" class=\"form_standard\" name=\"" . $this->formname . "\">";
     // draw session form box
     if ($this->sessionform) {
         $this->render_sessionform_messagebox();
     }
     // draw each sub form
     $num_subforms = count(array_keys($this->subforms));
     $count = 0;
     foreach (array_keys($this->subforms) as $form_label) {
         log_write("debug", "inc_form", "Processing subform: {$form_label}");
         $count++;
         if ($form_label == "hidden") {
             /*
             	Form contains hidden fields, we don't want to create table rows
             */
             foreach ($this->subforms[$form_label] as $fieldname) {
                 $this->render_field($fieldname);
             }
         } else {
             // start table
             print "<table class=\"form_table\" width=\"100%\">";
             // form header
             print "<tr class=\"header\">";
             print "<td colspan=\"2\"><b>" . language_translate_string($this->language, $form_label) . "</b></td>";
             print "</tr>";
             // standard vs grouped subform
             if (isset($this->subforms_grouped[$form_label])) {
                 log_write("debug", "inc_form", "Subform {$form_logic} is grouped - running additional logic");
                 /*
                 	Grouped subforms add additional logic to Amberphplib - a subform can be defined as normal
                 	with a placeholder fieldname.
                 
                 	This placeholder then matches to a subforms_grouped configuration that defines that fields
                 	should belong to that group - once added, when the form is drawn, any fields that are grouped
                 	will be drawn on a single row.
                 
                 	This feature is ideal for drawing complex charts/table-like forms without having to write
                 	custom rendering code every time.
                 
                 	eg:
                 	$obj_form->subforms["example"] 				= array("group1", "group2", "notgrouped");
                 	$obj_form->subforms_grouped["example"]["group1"] 	= array("standard_field1", "standard_field2");
                 	$obj_form->subforms_grouped["example"]["group2"] 	= array("standard_field3", "standard_field4");
                 */
                 $grouped_counter = 0;
                 foreach ($this->subforms[$form_label] as $fieldname) {
                     if (isset($this->subforms_grouped[$form_label][$fieldname])) {
                         /*
                         	We have determined that $fieldname is a grouped field - from here, we
                         	now loop through and put grouped fields together.
                         	
                         	We track the table status with $grouped_counter, if we run into a regular
                         	field, we close the table, process that field and then restume the table for
                         	the next block of grouped fields.
                         
                         	eg:
                         			/---------------------\
                         		group1: |  field1  |  field2  |
                         		group2: |  field1  |  field2  |
                         			\---------------------/
                         
                         			/---------------------\
                         			| normal_field ...... |
                         			\---------------------/
                         		
                         			/---------------------\
                         		group3: |  field4  |  field5  |
                         			\---------------------/
                         
                         
                         	TODO: There is a limitation to be cautious of, the logic here does not count
                         		the number of columns to make sure all groups in the subform are the
                         		same length.
                         
                         		General rule: don't mess with the number of columns - OR make sure there
                         		is a regular field between them to cause the table to be re-drawn.
                         */
                         log_write("debug", "inc_form", "Processing field {$fieldname} as a group field");
                         // container table
                         if ($grouped_counter == 0) {
                             print "<tr>";
                             print "<td colspan=\"2\">";
                             print "<table class=\"table_highlight\">";
                             $grouped_counter = 1;
                         }
                         // grouped field
                         $num_fields = count($this->subforms_grouped[$form_label][$fieldname]);
                         // check for errors
                         $error = 0;
                         foreach ($this->subforms_grouped[$form_label][$fieldname] as $fieldname2) {
                             if (isset($_SESSION["error"]["{$fieldname2}-error"])) {
                                 $error = 1;
                             }
                         }
                         // run through group members
                         if ($error) {
                             print "<tr class=\"form_error\">";
                         } else {
                             print "<tr>";
                         }
                         foreach ($this->subforms_grouped[$form_label][$fieldname] as $fieldname2) {
                             // render field
                             print "<td>";
                             $this->render_field($fieldname2);
                             print "</td>";
                         }
                         print "</tr>";
                     } else {
                         if ($grouped_counter == 1) {
                             // close container table
                             print "</table>";
                             print "</td></tr>";
                             $grouped_counter = 0;
                         }
                         // display row as normal
                         log_write("debug", "inc_form", "Processing field {$fieldname} as a regular field");
                         $this->render_row($fieldname);
                     }
                 }
                 if ($grouped_counter == 1) {
                     // close container table
                     print "</table>";
                     print "</td></tr>";
                     $grouped_counter = 0;
                 }
             } else {
                 log_write("debug", "inc_form", "Form subgroup {$form_label} is not grouped");
                 // display all the rows
                 foreach ($this->subforms[$form_label] as $fieldname) {
                     $this->render_row($fieldname);
                 }
             }
             // end table
             print "</table>";
             if ($count != $num_subforms) {
                 print "<br>";
             }
         }
     }
     // end form
     print "</form>";
     // render javascript components
     $this->render_javascript();
 }
 function render_html()
 {
     log_debug("invoice_list_items", "Executing render_html()");
     /*
     	Display custom table, combining the table data from the standard items and adding tax data
     
     	The following code is based off the tables class.
     */
     if (!$this->obj_table_standard->data_num_rows) {
         if ($this->type == "ar" || $this->type == "ap" || $this->type == "quotes") {
             // regular invoice item
             print "<table class=\"table_highlight_info\" width=\"100%\">";
             print "<tr><td width=\"100%\">";
             print "<p>This invoice has no items and is currently empty.</p>";
             print "<div class=\"invoice_button_area\">";
             print "<a href=\"index.php?page=" . $this->page_view . "&id=" . $this->invoiceid . "&type=standard\">\n\t\t\t\t\t\t\t<img src=\"images/icons/plus.gif\" height=\"15\" width=\"15\"/>&nbsp;&nbsp;<strong>Basic Transaction</strong></a>\n\t\t\t\t\t\t\t<br />";
             if ($this->type == "ar") {
                 print "<a href=\"index.php?page=" . $this->page_view . "&id=" . $this->invoiceid . "&type=time\">\n\t\t\t\t\t\t\t\t<img src=\"images/icons/plus.gif\" height=\"15\" width=\"15\"/>&nbsp;&nbsp;<strong>Time Item</strong></a><br />";
             }
             print "<a href=\"index.php?page=" . $this->page_view . "&id=" . $this->invoiceid . "&type=product\">\n\t\t\t\t\t\t\t<img src=\"images/icons/plus.gif\" height=\"15\" width=\"15\"/>&nbsp;&nbsp;<strong>Product</strong></a>";
             print "</div>";
             print "</td></tr>";
             print "</table>";
         } elseif ($this->type == "ar_credit" || $this->type == "ap_credit") {
             // credit
             // nothing todo
         }
     } else {
         print "<table width=\"100%\" class=\"table_content\" style=\"border-bottom: 0px;\" cellspacing=\"0\">";
         /*
         	Display standard invoice items
         */
         print "<tr>";
         // heading
         foreach ($this->obj_table_standard->columns as $column) {
             print "<td class=\"header\"><b>" . $this->obj_table_standard->render_columns[$column] . "</b></td>";
         }
         // filler for optional link column
         print "<td class=\"header\">&nbsp;</td>";
         print "</tr>";
         // display invoice items
         for ($i = 0; $i < $this->obj_table_standard->data_num_rows; $i++) {
             print "<tr>";
             // content for columns
             foreach ($this->obj_table_standard->columns as $columns) {
                 $content = $this->obj_table_standard->data_render[$i][$columns];
                 if (!$content) {
                     $content = "&nbsp;";
                 }
                 // display
                 print "<td valign=\"top\">{$content}</td>";
             }
             // links
             if (!empty($this->obj_table_standard->links)) {
                 print "<td align=\"right\">";
                 $links = array_keys($this->obj_table_standard->links);
                 $links_count = count($links);
                 $count = 0;
                 foreach ($links as $link) {
                     $count++;
                     $linkname = language_translate_string($this->obj_table_standard->language, $link);
                     // link to page
                     // There are two ways:
                     // 1. (default) Link to index.php
                     // 2. Set the ["options]["full_link"] value to yes to force a full link
                     if (isset($this->obj_table_standard->links[$link]["options"]["full_link"]) && $this->obj_table_standard->links[$link]["options"]["full_link"] == "yes") {
                         print "<a class=\"button_small\" href=\"" . $this->obj_table_standard->links[$link]["page"] . "?libfiller=n";
                     } else {
                         print "<a class=\"button_small\" href=\"index.php?page=" . $this->obj_table_standard->links[$link]["page"] . "";
                     }
                     // add each option
                     foreach (array_keys($this->obj_table_standard->links[$link]["options"]) as $getfield) {
                         /*
                         	There are two methods for setting the value of the variable:
                         	1. The value has been passed.
                         	2. The name of a column to take the value from has been passed
                         */
                         if (isset($this->obj_table_standard->links[$link]["options"][$getfield]["value"])) {
                             print "&{$getfield}=" . $this->obj_table_standard->links[$link]["options"][$getfield]["value"];
                         } else {
                             print "&{$getfield}=" . $this->obj_table_standard->data[$i][$this->obj_table_standard->links[$link]["options"][$getfield]["column"]];
                         }
                     }
                     // finish link
                     print "\">{$linkname}</a>";
                     // if required, add seporator
                     if ($count < $links_count) {
                         print " ";
                     }
                 }
                 print "</tr>";
             }
         }
         /*
          * Add buttons
          */
         //calculate number of rows buttons can cover
         $footer_rows = $this->obj_table_taxes->data_num_rows + 2;
         print "<tr>";
         print "<td class=\"blank\" colspan=\"4\" rowspan=\"{$footer_rows}\">";
         if (user_permissions_get("accounts_" . $this->type . "_write") && !$this->locked) {
             print "<p><strong>Add new items to invoice:<strong></p>";
             print "<div class=\"invoice_button_area\">";
             print "<a href=\"index.php?page=" . $this->page_view . "&id=" . $this->invoiceid . "&type=standard\">\n\t\t\t\t\t\t\t<img src=\"images/icons/plus.gif\" height=\"15\" width=\"15\"/>&nbsp;&nbsp;<strong>Basic Transaction</strong></a>\n\t\t\t\t\t\t\t<br />";
             if ($this->type == "ar") {
                 print "<a href=\"index.php?page=" . $this->page_view . "&id=" . $this->invoiceid . "&type=time\">\n\t\t\t\t\t\t\t\t<img src=\"images/icons/plus.gif\" height=\"15\" width=\"15\"/>&nbsp;&nbsp;<strong>Time Item</strong></a><br />";
             }
             print "<a href=\"index.php?page=" . $this->page_view . "&id=" . $this->invoiceid . "&type=product\">\n\t\t\t\t\t\t\t<img src=\"images/icons/plus.gif\" height=\"15\" width=\"15\"/>&nbsp;&nbsp;<strong>Product</strong></a>";
             print "</div>";
         }
         print "</td>";
         /*
         	Subtotal
         
         	Display total of all items without tax
         */
         //			print "<tr>";
         //				print "<td class=\"blank\" colspan=\"4\"></td>";
         print "<td class=\"footer\" valign=\"top\" colspan=\"2\"><b>Subtotal:</b></td>";
         print "<td class=\"footer\" valign=\"top\"><b>" . $this->obj_table_standard->data_render["total"]["amount"] . "</b></td>";
         print "<td class=\"footer\">&nbsp;</td>";
         print "</tr>";
         /*
         	Display taxes
         
         	For AR invoices and quotes we only display a read-only total, but for AP
         	invoices we create a form for each tax, which users can use to override the
         	automatically calculate tax amount.
         
         	This override function is provided to deal with vendors who send invoices with
         	incorrect rounding - a common example is $0.01 rounding errors.
         */
         for ($i = 0; $i < $this->obj_table_taxes->data_num_rows; $i++) {
             print "<tr>";
             // padding
             //				print "<td class=\"blank\" colspan=\"4\"></td>";
             // tax name
             print "<td valign=\"center\" colspan=\"2\">" . $this->obj_table_taxes->data_render[$i]["name_tax"] . "</td>";
             if ($this->type == "ap" && user_permissions_get("accounts_" . $this->type . "_write") && !$this->locked) {
                 // amount
                 print "<td valign=\"top\">";
                 print "<form method=\"post\" action=\"accounts/ap/invoice-items-tax-override-process.php\" class=\"form_standard\">";
                 print "<input type=\"hidden\" name=\"invoiceid\" value=\"" . $this->invoiceid . "\">";
                 print "<input type=\"hidden\" name=\"itemid\" value=\"" . $this->obj_table_taxes->data[$i]["id"] . "\">";
                 $position = sql_get_singlevalue("SELECT value FROM config WHERE name='CURRENCY_DEFAULT_SYMBOL_POSITION'");
                 if ($position == "after") {
                     print "<input name=\"amount\" value=\"" . $this->obj_table_taxes->data[$i]["amount"] . "\" style=\"width: 100px; font-size: 10px;\"> ";
                     print sql_get_singlevalue("SELECT value FROM config WHERE name='CURRENCY_DEFAULT_SYMBOL'");
                 } else {
                     print sql_get_singlevalue("SELECT value FROM config WHERE name='CURRENCY_DEFAULT_SYMBOL'");
                     print "<input name=\"amount\" value=\"" . $this->obj_table_taxes->data[$i]["amount"] . "\" style=\"width: 100px; font-size: 10px;\">";
                 }
                 print "</td>";
                 // links
                 print "<td align=\"right\">";
                 // use specifc inline CSS here to override default large button sizes
                 print "<input type=\"submit\" value=\"adjust\" style=\"\n\t\t\t\t\t\tfont-size:\t\t8px !important;\n\t\t\t\t\t\tline-height:\t\t10px;\n\t\t\t\t\t\tpadding: \t\t2px 10px;\n\t\t\t\t\t\tcursor:\t\t\tpointer;\n\n\t\t\t\t\t\tcolor:\t\t\t#ffffff;\n\t\t\t\t\t\tfont-style:\t\tnormal;\n\t\t\t\t\t\tfont-weight:\t\tnormal;\n\n\t\t\t\t\t\tborder-width:\t\t0px;\n\t\t\t\t\t\tborder-style:\t\tsolid;\n\n\t\t\t\t\t\t-moz-border-radius:\t5px;\n\t\t\t\t\t\t-khtml-border-radius:\t5px;\n\t\t\t\t\t\t-webkit-border-radius:\t5px;\n\t\t\t\t\t\tborder-radius:\t\t5px;\n\t\t\t\t\t\">";
                 print "</form>";
                 print "</td>";
             } else {
                 // amount
                 print "<td valign=\"top\">" . $this->obj_table_taxes->data_render[$i]["amount"] . "</td>";
                 // links
                 print "<td>&nbsp;</td>";
             }
             print "</tr>";
         }
         /*
         	Invoice Total
         
         	Items + Taxes totaled together
         */
         $invoice_total = $this->obj_table_standard->data["total"]["amount"] + $this->obj_table_taxes->data["total"]["amount"];
         $invoice_total = format_money($invoice_total);
         print "<tr>";
         //				print "<td class=\"blank\" colspan=\"4\"></td>";
         print "<td class=\"footer\" valign=\"top\" colspan=\"2\"><b>Invoice Total:</b></td>";
         print "<td class=\"footer\" valign=\"top\"><b>{$invoice_total}</b></td>";
         print "<td class=\"footer\">&nbsp;</td>";
         print "</tr>";
         print "</table>";
     }
     // end if items exist
     //		if (user_permissions_get("accounts_". $this->type ."_write") && !$this->locked)
     //		{
     //			/*
     //				Display the new item form
     //			*/
     //
     //
     //			$form = New form_input;
     //			$form->formname		= $this->type ."_invoice_". $this->mode;
     //			$form->language		= $_SESSION["user"]["lang"];
     //
     //			$form->action		= str_replace("edit", "add-process", $this->page_view);
     //			$form->method		= "POST";
     //
     //			// basic details
     //			$structure = NULL;
     //			$structure["fieldname"] 	= "id";
     //			$structure["type"]		= "hidden";
     //			$structure["defaultvalue"]	= $this->invoiceid;
     //			$form->add_input($structure);
     //
     //
     //			// item dropdown
     //			$structure = NULL;
     //			$structure["fieldname"] 	= "item";
     //			$structure["type"]		= "dropdown";
     //			$structure["options"]["width"]	= "600";
     //
     //			$structure["values"][]			= "standard";
     //			$structure["translations"]["standard"]	= "Basic Transaction";
     //
     //			if ($this->type == "ar")
     //			{
     //				$structure["values"][]			= "time";
     //				$structure["translations"]["time"]	= "Time Item";
     //			}
     //
     //			// fetch all the products for the drop down
     //			$sql_products_obj		= New sql_query;
     //			$sql_products_obj->string	= "SELECT id, code_product, name_product FROM products ORDER BY name_product";
     //			$sql_products_obj->execute();
     //
     //			if ($sql_products_obj->num_rows())
     //			{
     //				$sql_products_obj->fetch_array();
     //
     //				foreach ($sql_products_obj->data as $data)
     //				{
     //					$structure["values"][]				= $data["id"];
     //					$structure["translations"][ $data["id"] ]	= $data["code_product"] ."--". $data["name_product"];
     //				}
     //			}
     //
     //
     //			$form->add_input($structure);
     //
     //
     //			// submit support
     //			$structure = NULL;
     //			$structure["fieldname"] 	= "submit";
     //			$structure["type"]		= "submit";
     //			$structure["defaultvalue"]	= "Add";
     //			$form->add_input($structure);
     //
     //
     //
     //			// display the form
     //			print "<br><table class=\"table_highlight_info\" width=\"100%\"><tr><td>";
     //			print "<p>Add new items to invoice:</p>";
     //
     //			print "<form method=\"". $form->method ."\" action=\"". $form->action ."\">";
     //			print "<table><tr>";
     //
     //				print "<td>";
     //				$form->render_field("item");
     //				print "</td>";
     //
     //				print "<td>";
     //				$form->render_field("submit");
     //				print "</td>";
     //
     //			print "</tr></table>";
     //
     //			$form->render_field("id");
     //
     //			print "</form>";
     //
     //			print "</td></tr></table>";
     //
     //		} // end if items
     return 1;
 }
 function render_html()
 {
     // Title + Summary
     if ($this->groupid) {
         print "<h3>EDIT TIME GROUP</h3><br>";
         print "<p>This page allows you to modify a time grouping.</p>";
     } else {
         print "<h3>ADD NEW TIME GROUP</h3><br>";
         print "<p>This page allows you to add a new time group entry to a project.</p>";
     }
     /*
     	Display the form
     
     	Because we need all the columns for the different time items, we have to do
     	a custom display for this form.
     */
     if ($this->obj_sql_entries->num_rows()) {
         // start form
         print "<form enctype=\"multipart/form-data\" method=\"" . $this->obj_form->method . "\" action=\"" . $this->obj_form->action . "\" class=\"form_standard\">";
         // GENERAL INPUTS
         // start table
         print "<table class=\"form_table\" width=\"100%\" cellspacing=\"0\">";
         // form header
         print "<tr class=\"header\">";
         print "<td colspan=\"2\"><b>" . language_translate_string($this->obj_form->language, "timebilled_details") . "</b></td>";
         print "</tr>";
         // display all the rows
         $this->obj_form->render_row("name_group");
         $this->obj_form->render_row("customerid");
         if ($this->groupid) {
             $this->obj_form->render_row("code_invoice");
         }
         $this->obj_form->render_row("description");
         // end table
         print "</table><br>";
         // TIME SELECTION
         print "<table class=\"form_table\" width=\"100%\" cellspacing=\"0\">";
         print "<tr class=\"header\">";
         print "<td colspan=\"2\"><b>" . language_translate_string($this->obj_form->language, "timebilled_selection") . "</b></td>";
         print "</tr>";
         print "</table>";
         // start table
         print "<p>Select all the time that should belong to this group from the list below - this list only shows time currently unassigned to any group.</p>";
         print "<p>You can choose whether to add the time as billable or as unbillable. This is used to group hours that are unbilled, eg: internal paper work\n\t\t\tfor the customer's account or other administrative overheads so that they won't continue to show in this list.</p>";
         // display notice about limited access if suitable
         if ($this->access_staff_ids) {
             $sql_obj = new sql_query();
             $sql_obj->string = "SELECT id FROM staff";
             $sql_obj->execute();
             $sql_obj->num_rows();
             if (count($this->access_staff_ids) != $sql_obj->num_rows()) {
                 format_msgbox("info", "<p>Please note that the following list of hours only includes the specific employees whom you have been configured to view - to view all employees, ask your admin to enable the timekeeping_all_view permission.</p>");
                 print "<br>";
             }
         }
         print "<table class=\"table_content\" width=\"100%\" cellspacing=\"0\">";
         // form header
         print "<tr class=\"header\">";
         print "<td><b>" . language_translate_string($this->obj_form->language, "date") . "</b></td>";
         print "<td><b>" . language_translate_string($this->obj_form->language, "name_phase") . "</b></td>";
         print "<td><b>" . language_translate_string($this->obj_form->language, "name_staff") . "</b></td>";
         print "<td><b>" . language_translate_string($this->obj_form->language, "description") . "</b></td>";
         print "<td><b>" . language_translate_string($this->obj_form->language, "time_booked") . "</b></td>";
         print "<td><b>" . language_translate_string($this->obj_form->language, "time_bill") . "</b></td>";
         print "<td><b>" . language_translate_string($this->obj_form->language, "time_nobill") . "</b></td>";
         print "</tr>";
         // display all the rows
         foreach ($this->obj_sql_entries->data as $data) {
             print "<tr>";
             print "<td>" . time_format_humandate($data["date"]) . "</td>";
             print "<td>" . $data["name_phase"] . "</td>";
             print "<td>" . $data["name_staff"] . "</td>";
             print "<td>" . $data["description"] . "</td>";
             print "<td>" . time_format_hourmins($data["time_booked"]) . "</td>";
             print "<td>";
             $this->obj_form->render_field("time_" . $data["id"] . "_bill");
             print "</td>";
             print "<td>";
             $this->obj_form->render_field("time_" . $data["id"] . "_nobill");
             print "</td>";
             print "</tr>";
         }
         // end table
         print "</table><br>";
         // HIDDEN FIELDS
         $this->obj_form->render_field("projectid");
         $this->obj_form->render_field("groupid");
         // SUBMIT
         // start table
         print "<table class=\"form_table\" width=\"100%\" cellspacing=\"0\">";
         // form header
         print "<tr class=\"header\">";
         print "<td colspan=\"2\"><b>" . language_translate_string($this->obj_form->language, "submit") . "</b></td>";
         print "</tr>";
         // display all the rows
         if (!$this->locked) {
             $this->obj_form->render_row("submit");
         }
         // end table
         print "</table>";
         // end form
         print "</form>";
         // locked
         if ($this->locked) {
             format_msgbox("locked", "<p>This time group has now been locked and can no longer be adjusted.</p>");
         }
     } else {
         format_msgbox("important", "<p>There is currently no un-grouped time that can be selected.</p>");
     }
 }