function execute() { // establish a new table object $this->obj_table = new table(); $this->obj_table->language = $_SESSION["user"]["lang"]; $this->obj_table->tablename = "name_servers_groups"; // define all the columns and structure $this->obj_table->add_column("standard", "group_name", ""); $this->obj_table->add_column("standard", "group_description", ""); $this->obj_table->add_column("standard", "group_members", "NONE"); // defaults $this->obj_table->columns = array("group_name", "group_description", "group_members"); $this->obj_table->columns_order = array("group_name"); $this->obj_table->columns_order_options = array("group_name"); $this->obj_table->sql_obj->prepare_sql_settable("name_servers_groups"); $this->obj_table->sql_obj->prepare_sql_addfield("id", ""); // load data $this->obj_table->generate_sql(); $this->obj_table->load_data_sql(); // fetch member list for ($i = 0; $i < $this->obj_table->data_num_rows; $i++) { $members = sql_get_singlecol("SELECT server_name AS value FROM name_servers WHERE id_group='" . $this->obj_table->data[$i]["id"] . "'"); $this->obj_table->data[$i]["group_members"] = format_arraytocommastring($members); } }
function load_data_ldap($filter, $base_dn = NULL) { log_write("debug", "inc_tables", "Executing load_data_ldap({$filter}, {$base_dn})"); $attributes = array(); // run through all the columns, and add their fields to the LDAP attribute query unless // the dbname is equal to NONE, in which case ignore. foreach ($this->columns as $column) { if ($this->structure[$column]["dbname"] != "NONE") { $attributes[] = $this->structure[$column]["dbname"]; } } // apply any LDAP filters that have been specified if ($this->filter) { foreach (array_keys($this->filter) as $fieldname) { // ignore input from text fields, text fields if ($this->filter[$fieldname]["type"] != "text") { // note: we only add the filter if a value has been saved to default value, otherwise // we assume the filter could break. if (!empty($this->filter[$fieldname]["defaultvalue"])) { // only apply ldap filters, ignore other types like SQL if (!empty($this->filter[$fieldname]["ldap"])) { $filter = str_replace("value", $this->filter[$fieldname]["defaultvalue"], $this->filter[$fieldname]["ldap"]); } } } } } // connect to LDAP server $this->obj_ldap->connect(); // set DN if ($base_dn) { $this->obj_ldap->srvcfg["base_dn"] = $base_dn; } // run query and process results if ($this->obj_ldap->search($filter, $attributes)) { // run through returned records $this->data_num_rows = $this->obj_ldap->data_num_rows; for ($i = 0; $i < $this->data_num_rows; $i++) { $tmparray = array(); // fetch values for each column foreach ($this->columns as $column) { if ($this->structure[$column]["dbname"] != "NONE") { if ($this->obj_ldap->data[$i][$this->structure[$column]["dbname"]]["count"] > 1) { // convert array of values to comma-deliminated string $values = array(); for ($j = 0; $j < $this->obj_ldap->data[$i][$this->structure[$column]["dbname"]]["count"]; $j++) { $values[] = $this->obj_ldap->data[$i][$this->structure[$column]["dbname"]][$j]; } $tmparray[$column] = format_arraytocommastring($values); } else { // single standard value $tmparray[$column] = $this->obj_ldap->data[$i][$this->structure[$column]["dbname"]][0]; } } } // save data to final results $this->data[] = $tmparray; } } else { // query failure or no rows returned $this->data_num_rows = 0; return 0; } }
function load_data() { log_debug("menu_main", "Executing load_data()"); /* Fetch an array of all the user permissions. */ log_debug("menu_main", "Fetching array of all the permissions the user has for displaying the menu"); $user_permissions = array(); if (user_online()) { // it's probably the first time we're checking for permissions // we should pre-load them all if needed if (!isset($GLOBALS["cache"]["user"]["perms"])) { $obj_user_auth = new user_auth(); $obj_user_auth->permissions_init(); } // fetch ID of all permissions $sql_obj = new sql_query(); $sql_obj->string = "SELECT id, value FROM permissions"; $sql_obj->execute(); $sql_obj->fetch_array(); // build array of all permissions IDs for the groups the user belongs to. foreach (array_keys($GLOBALS["cache"]["user"]["perms"]) as $type) { if ($GLOBALS["cache"]["user"]["perms"][$type] == 1) { foreach ($sql_obj->data as $data_permids) { if ($data_permids["value"] == $type) { $user_permissions[] = $data_permids["id"]; } } } } // (legacy) For system without a public permissions group, add the ID of 0 $user_permissions[] = "0"; } else { // user is not logged in - select public menu entries only $sql_obj = new sql_query(); $sql_obj->string = "SELECT id FROM `permissions` WHERE value='public' LIMIT 1"; $sql_obj->execute(); if ($sql_obj->num_rows()) { $sql_obj->fetch_array(); $user_permissions[] = $sql_obj->data[0]["id"]; } else { // (legacy) For system without a public permissions group, add the ID of 0 $user_permissionsp[] = "0"; } } // unable to display a menu if there are no permissions if (!$user_permissions) { log_write("debug", "main_menu", "User has no permissions public or private so menu options can not be queried"); return 0; } /* Fetch data for the entire menu from the database We fetch all the data at once, then run though it following the parent value as we run though all the items to determine what menu items need to be shown and in what order. We know that the single loop will match all the menu items correctly, since the menu items are ordered so we run though the order in the same direction. This saves us from having to do heaps of unnessacary loops. :-) */ log_debug("menu_main", "Loading menu from SQL database..."); $sql_menu_obj = new sql_query(); $sql_menu_obj->string = "SELECT link, topic, parent, config FROM menu WHERE permid IN (" . format_arraytocommastring($user_permissions) . ") ORDER BY priority DESC"; $sql_menu_obj->execute(); if (!$sql_menu_obj->num_rows()) { log_debug("menu_main", "No menu entires exist for the current user that they have permission to access"); return 0; } // fetch menu entires $sql_menu_obj->fetch_array(); // array to store the order of the menu items $this->menu_order = array(); // keep track of the topic we are looking for $target_topic = ""; /* Apply config filtering Some applications have the need to be able to enable/disable specific features using boolean options in the config table - by setting the name of the value in the config column on the menu entries, a check will be made, and if the menu entry config option is unset, the menu options will not be displayed. This is typically used for hiding disabled features where for whatever reason, the feature can not be disabled using permissions groups. */ for ($i = 0; $i < $sql_menu_obj->data_num_rows; $i++) { // check feature option (if set) if (!empty($sql_menu_obj->data[$i]["config"])) { @(list($config_name, $config_value) = explode('=', $sql_menu_obj->data[$i]["config"], 2)); if (!$GLOBALS["config"][$config_name]) { // config is disabled for this feature unset($sql_menu_obj->data[$i]); } else { if ($config_value) { // do value matching if ($GLOBALS["config"][$config_name] != $config_value) { // non match, failed unset($sql_menu_obj->data[$i]); } } // default is that menu item is enabled since config option exists } } } /* If the remember option is enabled, check if the page provided exists, if not then we will select the last known good page (from session variables). If it does exist, we set the session variable to the new page. */ if ($this->option_remember) { // check page foreach ($sql_menu_obj->data as $data) { if ($data["link"] == $this->page) { $_SESSION["amberphplib"]["menu"]["page"] = $this->page; } } // set page $this->page = $_SESSION["amberphplib"]["menu"]["page"]; } // loop though the menu items foreach ($sql_menu_obj->data as $data) { // add each item to menu array if ($target_topic != "top") { if (!$target_topic) { // use the page link to find the first target if ($data["link"] == $this->page) { $target_topic = $data["parent"]; $this->menu_order[] = $data["parent"]; } } else { // check the topic type if ($data["topic"] == $target_topic) { $target_topic = $data["parent"]; $this->menu_order[] = $data["parent"]; } } } } // now we reverse the order array, so we can // render the menus in the correct order if ($this->menu_order) { $this->menu_order = array_reverse($this->menu_order); } else { // if we have no sub-menu information, just set // to display the top menu only $this->menu_order = array("top"); } // sort the menu data in the opposite direction for correct rendering $this->menu_structure = array_reverse($sql_menu_obj->data); // return success return 1; }
*/ $sql_entries_obj = new sql_query(); $sql_entries_obj->prepare_sql_settable("timereg"); $sql_entries_obj->prepare_sql_addfield("id", ""); $sql_entries_obj->prepare_sql_addfield("locked", ""); $sql_entries_obj->prepare_sql_addfield("groupid", ""); $sql_entries_obj->prepare_sql_addfield("billable", ""); $sql_entries_obj->prepare_sql_addfield("time_booked", ""); if ($groupid) { $sql_entries_obj->prepare_sql_addwhere("(groupid='{$groupid}' OR !groupid)"); } else { $sql_entries_obj->prepare_sql_addwhere("!groupid"); } // if user has limited employee access, only process time records for those employees if ($access_staff_ids) { $sql_entries_obj->prepare_sql_addwhere("employeeid IN (" . format_arraytocommastring($access_staff_ids) . ")"); } $sql_entries_obj->generate_sql(); $sql_entries_obj->execute(); if ($sql_entries_obj->num_rows()) { $sql_entries_obj->fetch_array(); foreach ($sql_entries_obj->data as $entries_data) { // only get the data for selected time entries if ($_POST["time_" . $entries_data["id"] . "_bill"] == "on") { $data["time_entries"][$entries_data["id"]]["billable"] = 1; } elseif ($_POST["time_" . $entries_data["id"] . "_nobill"] == "on") { $data["time_entries"][$entries_data["id"]]["billable"] = 0; } // save to session array $_SESSION["error"]["time_" . $entries_data["id"] . "_bill"] = $_POST["time_" . $entries_data["id"] . "_bill"]; $_SESSION["error"]["time_" . $entries_data["id"] . "_nobill"] = $_POST["time_" . $entries_data["id"] . "_nobill"];
$data_modes[$data_row["id"]] = @security_form_input_predefined("checkbox", "billing_mode_" . $data_row["id"], 0, ""); // if marked inactive, check if it's inuse if ($data_modes[$data_row["id"]] == 0) { // we need to make sure this usage mode is not in use, since if it is, disabling // it would cause weird borkage. $obj_sql_check = new sql_query(); $obj_sql_check->string = "SELECT name_service FROM services WHERE billing_mode='" . $data_row["id"] . "'"; $obj_sql_check->execute(); if ($obj_sql_check->num_rows()) { $obj_sql_check->fetch_array(); $service_list = array(); foreach ($obj_sql_check->data as $data_check) { $service_list[] = $data_check["name_service"]; } // mode is in use log_write("error", "process", "Unable to disable mode " . $data_row["name"] . " due to it being used by service \"" . format_arraytocommastring($service_list) . "\"."); error_flag_field("billing_mode_" . $data_row["id"]); } // end if service mode in use } // end if disabled } // end of service mode loop } // end of if service modes /* Test Traffic Database */ if ($data["SERVICE_TRAFFIC_DB_TYPE"] == "mysql_netflow_daily" || $data["SERVICE_TRAFFIC_DB_TYPE"] == "mysql_traffic_summary") { $obj_sql = new sql_query(); if (!$obj_sql->session_init("mysql", $data["SERVICE_TRAFFIC_DB_HOST"], $data["SERVICE_TRAFFIC_DB_NAME"], $data["SERVICE_TRAFFIC_DB_USERNAME"], $data["SERVICE_TRAFFIC_DB_PASSWORD"])) {
<?php /* customers/ajax/get_attribute_key_list.php access: customers_write Get list of key names from database for autocomplete */ require "../../include/config.php"; require "../../include/amberphplib/main.php"; if (user_permissions_get('customers_write')) { //get keys from database $sql_obj = new sql_query(); $sql_obj->string = "SELECT DISTINCT `key` FROM attributes"; $sql_obj->execute(); //if any keys are returned, add them to an array if ($sql_obj->num_rows()) { $sql_obj->fetch_array(); foreach ($sql_obj->data as $data_row) { $values[] = $data_row["key"]; } } //change array to a string echo format_arraytocommastring($values, '"'); } exit(0);
function execute() { /* Define form structure */ $this->obj_form = new form_input(); $this->obj_form->formname = "config"; $this->obj_form->language = $_SESSION["user"]["lang"]; $this->obj_form->action = "admin/config-process.php"; $this->obj_form->method = "post"; /* // security options $structure = NULL; $structure["fieldname"] = "BLACKLIST_ENABLE"; $structure["type"] = "checkbox"; $structure["options"]["label"] = "Enable to prevent brute-force login attempts"; $structure["options"]["no_translate_fieldname"] = "yes"; $this->obj_form->add_input($structure); $structure = NULL; $structure["fieldname"] = "BLACKLIST_LIMIT"; $structure["type"] = "input"; $structure["options"]["no_translate_fieldname"] = "yes"; $this->obj_form->add_input($structure); */ // date/time configuration $structure = form_helper_prepare_timezonedropdown("TIMEZONE_DEFAULT"); $structure["options"]["no_translate_fieldname"] = "yes"; $this->obj_form->add_input($structure); $structure = NULL; $structure["fieldname"] = "DATEFORMAT"; $structure["type"] = "radio"; $structure["values"] = array("yyyy-mm-dd", "mm-dd-yyyy", "dd-mm-yyyy"); $structure["options"]["no_translate_fieldname"] = "yes"; $this->obj_form->add_input($structure); // default options $structure = NULL; $structure["fieldname"] = "DEFAULT_HOSTMASTER"; $structure["type"] = "input"; $structure["options"]["no_translate_fieldname"] = "yes"; $structure["options"]["help"] = "*****@*****.**"; $structure["options"]["label"] = " Email address for the DNS administrator."; $this->obj_form->add_input($structure); $structure = NULL; $structure["fieldname"] = "DEFAULT_TTL_SOA"; $structure["type"] = "input"; $structure["options"]["no_translate_fieldname"] = "yes"; $structure["options"]["autofill"] = "86400"; $this->obj_form->add_input($structure); $structure = NULL; $structure["fieldname"] = "DEFAULT_TTL_NS"; $structure["type"] = "input"; $structure["options"]["no_translate_fieldname"] = "yes"; $structure["options"]["label"] = " Default TTL for Name Server (NS) records."; $this->obj_form->add_input($structure); $structure = NULL; $structure["fieldname"] = "DEFAULT_TTL_MX"; $structure["type"] = "input"; $structure["options"]["no_translate_fieldname"] = "yes"; $structure["options"]["label"] = " Default TTL for MX records"; $this->obj_form->add_input($structure); $structure = NULL; $structure["fieldname"] = "DEFAULT_TTL_OTHER"; $structure["type"] = "input"; $structure["options"]["no_translate_fieldname"] = "yes"; $structure["options"]["label"] = " Default TTL for all other record types (A, AAAA, TXT, SPF, PTR, etc)"; $this->obj_form->add_input($structure); // zone database configuration $structure = NULL; $structure["fieldname"] = "ZONE_DB_TYPE"; $structure["type"] = "radio"; $structure["values"] = array("zone_internal"); // Long term plan is to support multiple backends, but we don't have this capability yet. //$structure["values"] = array("zone_internal", "powerdns_mysql"); $structure["options"]["autoselect"] = "yes"; $structure["options"]["no_translate_fieldname"] = "yes"; $this->obj_form->add_input($structure); $structure = NULL; $structure["fieldname"] = "ZONE_DB_HOST"; $structure["type"] = "input"; $structure["options"]["no_translate_fieldname"] = "yes"; $this->obj_form->add_input($structure); $structure = NULL; $structure["fieldname"] = "ZONE_DB_NAME"; $structure["type"] = "input"; $structure["options"]["no_translate_fieldname"] = "yes"; $this->obj_form->add_input($structure); $structure = NULL; $structure["fieldname"] = "ZONE_DB_USERNAME"; $structure["type"] = "input"; $structure["options"]["no_translate_fieldname"] = "yes"; $this->obj_form->add_input($structure); $structure = NULL; $structure["fieldname"] = "ZONE_DB_PASSWORD"; $structure["type"] = "input"; $structure["options"]["no_translate_fieldname"] = "yes"; $this->obj_form->add_input($structure); // logging options $structure = NULL; $structure["fieldname"] = "FEATURE_LOGS_ENABLE"; $structure["type"] = "checkbox"; $structure["options"]["no_translate_fieldname"] = "yes"; $structure["options"]["label"] = " Enable audit & name server logging functionality."; $this->obj_form->add_input($structure); $structure = NULL; $structure["fieldname"] = "FEATURE_LOGS_AUDIT"; $structure["type"] = "checkbox"; $structure["options"]["no_translate_fieldname"] = "yes"; $structure["options"]["label"] = " Enable audit trail logging - tracks changes made to DNS records & zones."; $this->obj_form->add_input($structure); $structure = NULL; $structure["fieldname"] = "FEATURE_LOGS_API"; $structure["type"] = "checkbox"; $structure["options"]["no_translate_fieldname"] = "yes"; $structure["options"]["label"] = " Enable logging via API from name servers."; $this->obj_form->add_input($structure); $structure = NULL; $structure["fieldname"] = "LOG_UPDATE_INTERVAL"; $structure["type"] = "input"; $structure["options"]["no_translate_fieldname"] = "yes"; $structure["options"]["label"] = " seconds"; $structure["options"]["width"] = "50"; $this->obj_form->add_input($structure); $structure = NULL; $structure["fieldname"] = "LOG_RETENTION_PERIOD"; $structure["type"] = "input"; $structure["options"]["no_translate_fieldname"] = "yes"; $structure["options"]["label"] = " Delete logs after defined number of days (0 to disable)."; $structure["options"]["width"] = "50"; $this->obj_form->add_input($structure); $this->obj_form->add_action("FEATURE_LOGS_ENABLE", "default", "FEATURE_LOGS_AUDIT", "hide"); $this->obj_form->add_action("FEATURE_LOGS_ENABLE", "default", "FEATURE_LOGS_API", "hide"); $this->obj_form->add_action("FEATURE_LOGS_ENABLE", "default", "LOG_UPDATE_INTERVAL", "hide"); $this->obj_form->add_action("FEATURE_LOGS_ENABLE", "default", "LOG_RETENTION_PERIOD", "hide"); $this->obj_form->add_action("FEATURE_LOGS_ENABLE", "1", "FEATURE_LOGS_AUDIT", "show"); $this->obj_form->add_action("FEATURE_LOGS_ENABLE", "1", "FEATURE_LOGS_API", "show"); $this->obj_form->add_action("FEATURE_LOGS_ENABLE", "1", "LOG_RETENTION_PERIOD", "show"); $this->obj_form->add_action("FEATURE_LOGS_ENABLE", "1", "LOG_UPDATE_INTERVAL", "show"); // miscellaneous configurations $max_input_vars = @ini_get('max_input_vars'); if (empty($max_input_vars)) { // PHP defaults if we can't query $max_input_vars = 1000; } $max_input_vars = sprintf("%d", $max_input_vars / 15); $structure = NULL; $structure["fieldname"] = "PAGINATION_DOMAIN_RECORDS"; $structure["type"] = "input"; $structure["options"]["no_translate_fieldname"] = "yes"; $structure["options"]["label"] = " records per page (recommend maximum of {$max_input_vars}, adjust PHP max_input_vars to support more if required. Some browsers may perform badly with high values here)"; $this->obj_form->add_input($structure); $this->obj_form->add_action("ZONE_DB_TYPE", "default", "ZONE_DB_HOST", "hide"); $this->obj_form->add_action("ZONE_DB_TYPE", "default", "ZONE_DB_NAME", "hide"); $this->obj_form->add_action("ZONE_DB_TYPE", "default", "ZONE_DB_USERNAME", "hide"); $this->obj_form->add_action("ZONE_DB_TYPE", "default", "ZONE_DB_PASSWORD", "hide"); $this->obj_form->add_action("ZONE_DB_TYPE", "powerdns_mysql", "ZONE_DB_HOST", "show"); $this->obj_form->add_action("ZONE_DB_TYPE", "powerdns_mysql", "ZONE_DB_NAME", "show"); $this->obj_form->add_action("ZONE_DB_TYPE", "powerdns_mysql", "ZONE_DB_USERNAME", "show"); $this->obj_form->add_action("ZONE_DB_TYPE", "powerdns_mysql", "ZONE_DB_PASSWORD", "show"); // admin API $structure = NULL; $structure["fieldname"] = "ADMIN_API_KEY"; $structure["type"] = "input"; $structure["options"]["no_translate_fieldname"] = "yes"; $structure["options"]["help"] = " Set me to a unique random string"; $structure["options"]["label"] = " API keys for scripts that interact with NamedManager"; $this->obj_form->add_input($structure); // amberstats phone home $structure = NULL; $structure["fieldname"] = "PHONE_HOME"; $structure["type"] = "checkbox"; $structure["options"]["label"] = "Report back to the developers with application, OS, PHP version and a random unique ID so we can better improve this software. (all information is anonymous, private and greatly appreciated. We use this information to focus development and packaging on the main platforms our users are running to better meet your needs."; $structure["options"]["no_translate_fieldname"] = "yes"; $this->obj_form->add_input($structure); $phone_home_info = new phone_home(); $phone_home_info->stats_generate(); $structure = NULL; $structure["fieldname"] = "PHONE_HOME_EXAMPLE"; $structure["type"] = "text"; $structure["defaultvalue"] = "<i>Actual information to be sent: " . format_arraytocommastring(array_values($phone_home_info->stats)) . "</i>"; $structure["options"]["no_fieldname"] = "yes"; $structure["options"]["no_shift"] = "yes"; $this->obj_form->add_input($structure); // submit section $structure = NULL; $structure["fieldname"] = "submit"; $structure["type"] = "submit"; $structure["defaultvalue"] = "Save Changes"; $this->obj_form->add_input($structure); // define subforms // $this->obj_form->subforms["config_security"] = array("BLACKLIST_ENABLE", "BLACKLIST_LIMIT"); $this->obj_form->subforms["config_zone_defaults"] = array("DEFAULT_HOSTMASTER", "DEFAULT_TTL_SOA", "DEFAULT_TTL_NS", "DEFAULT_TTL_MX", "DEFAULT_TTL_OTHER"); $this->obj_form->subforms["config_zone_database"] = array("ZONE_DB_TYPE", "ZONE_DB_HOST", "ZONE_DB_NAME", "ZONE_DB_USERNAME", "ZONE_DB_PASSWORD"); $this->obj_form->subforms["config_api"] = array("ADMIN_API_KEY"); $this->obj_form->subforms["config_dateandtime"] = array("DATEFORMAT", "TIMEZONE_DEFAULT"); $this->obj_form->subforms["config_logging"] = array("FEATURE_LOGS_ENABLE", "FEATURE_LOGS_AUDIT", "FEATURE_LOGS_API", "LOG_UPDATE_INTERVAL", "LOG_RETENTION_PERIOD"); $this->obj_form->subforms["config_miscellaneous"] = array("PAGINATION_DOMAIN_RECORDS"); $this->obj_form->subforms["config_amberstats"] = array("PHONE_HOME", "PHONE_HOME_EXAMPLE"); $this->obj_form->subforms["submit"] = array("submit"); if (error_check()) { // load error datas $this->obj_form->load_data_error(); } else { // fetch all the values from the database $sql_config_obj = new sql_query(); $sql_config_obj->string = "SELECT name, value FROM config ORDER BY name"; $sql_config_obj->execute(); $sql_config_obj->fetch_array(); foreach ($sql_config_obj->data as $data_config) { $this->obj_form->structure[$data_config["name"]]["defaultvalue"] = $data_config["value"]; } unset($sql_config_obj); } }
function render_html() { // calcuate next/previous week/year if ($this->date_selected_weekofyear == 1) { $date_option_previousyear = $this->date_selected_year - 1; $date_option_previousweek = 52; $date_option_nextyear = $this->date_selected_year; $date_option_nextweek = 2; } elseif ($this->date_selected_weekofyear == 52) { $date_option_previousyear = $this->date_selected_year; $date_option_previousweek = 51; $date_option_nextyear = $this->date_selected_year + 1; $date_option_nextweek = 1; } else { $date_option_previousyear = $this->date_selected_year; $date_option_previousweek = $this->date_selected_weekofyear - 1; $date_option_nextyear = $this->date_selected_year; $date_option_nextweek = $this->date_selected_weekofyear + 1; } // Week view header print "<h3>TIME REGISTRATION</h3><br><br>"; /* Unbilled Time */ if (user_permissions_get("projects_timegroup")) { /* Create an array of all unbilled time records. We need to do the following to create this list: 1. Exclude any internal_only projects. 2. Include time which belongs to a time_group, but ONLY if the time group has not been added to an invoice. */ $unbilled_ids = array(); // select non-internal projects $sql_projects_obj = new sql_query(); $sql_projects_obj->string = "SELECT projects.id as projectid, project_phases.id as phaseid FROM project_phases LEFT JOIN projects ON projects.id = project_phases.projectid WHERE projects.internal_only='0'"; $sql_projects_obj->execute(); if ($sql_projects_obj->num_rows()) { $sql_projects_obj->fetch_array(); foreach ($sql_projects_obj->data as $project_data) { // select non-group time records $sql_obj = new sql_query(); $sql_obj->string = "SELECT id FROM timereg WHERE groupid='0' AND phaseid='" . $project_data["phaseid"] . "'"; $sql_obj->execute(); if ($sql_obj->num_rows()) { $sql_obj->fetch_array(); foreach ($sql_obj->data as $data_tmp) { // we store the ID inside an array key, since they are unique // and this will prevent us needed to check for the existance of // the ID already. $unbilled_ids[$data_tmp["id"]] = "on"; } } unset($sql_obj); // select unpaid group IDs $sql_obj = new sql_query(); $sql_obj->string = "SELECT id FROM time_groups WHERE projectid='" . $project_data["projectid"] . "' AND invoiceid='0'"; $sql_obj->execute(); if ($sql_obj->num_rows()) { $sql_obj->fetch_array(); foreach ($sql_obj->data as $data_group) { // fetch all the time reg IDs belonging this group, but only select time entries marked as billable - we // don't want to report a timegroup with unbillable time as being billed! $sql_reg_obj = new sql_query(); $sql_reg_obj->string = "SELECT id FROM timereg WHERE groupid='" . $data_group["id"] . "' AND billable='1'"; $sql_reg_obj->execute(); if ($sql_reg_obj->num_rows()) { $sql_reg_obj->fetch_array(); foreach ($sql_reg_obj->data as $data_tmp) { // we store the ID inside an array key, since they are unique // and this will prevent us needed to check for the existance of // the ID already. $unbilled_ids[$data_tmp["id"]] = "on"; } } unset($sql_reg_obj); } } unset($sql_obj); } } // fetch amount of unbilled time $sql_obj = new sql_query(); $sql_obj->prepare_sql_settable("timereg"); $sql_obj->prepare_sql_addfield("timebooked", "SUM(timereg.time_booked)"); if ($this->access_staff_ids) { $sql_obj->prepare_sql_addwhere("employeeid IN (" . format_arraytocommastring($this->access_staff_ids) . ")"); } $sql_obj->prepare_sql_addjoin("LEFT JOIN time_groups ON timereg.groupid = time_groups.id"); // provide list of valid IDs $unbilled_ids_keys = array_keys($unbilled_ids); $unbilled_ids_count = count($unbilled_ids_keys); $unbilled_ids_sql = ""; if ($unbilled_ids_count) { $i = 0; foreach ($unbilled_ids_keys as $id) { $i++; if ($i == $unbilled_ids_count) { $unbilled_ids_sql .= "timereg.id='{$id}' "; } else { $unbilled_ids_sql .= "timereg.id='{$id}' OR "; } } $sql_obj->prepare_sql_addwhere("({$unbilled_ids_sql})"); $sql_obj->generate_sql(); $sql_obj->execute(); $sql_obj->fetch_array(); list($unbilled_time_hours, $unbilled_time_mins) = explode(":", time_format_hourmins($sql_obj->data[0]["timebooked"])); if ($unbilled_time_hours > 0 && $unbilled_time_mins > 0) { $message = "There are currently {$unbilled_time_hours} hours and {$unbilled_time_mins} minutes of unbilled time to be processed. Click here to view."; } elseif ($unbilled_time_hours > 0) { $message = "There are currently {$unbilled_time_hours} hours of unbilled time to be processed. Click here to view."; } elseif ($unbilled_time_mins > 0) { $message = "There are currently {$unbilled_time_mins} minutes of unbilled time to be processed. Click here to view."; } } else { $message = "There is no unbilled time to be processed."; } // display print "<br>"; format_linkbox("default", "index.php?page=timekeeping/unbilled.php", "<p><b>UNBILLED TIME</b></p><p>{$message}</p>"); } /*end unbilled time*/ print "<br />"; /* Time booked */ // fetch amount of time booked for today $sql_obj = new sql_query(); $sql_obj->prepare_sql_settable("timereg"); $sql_obj->prepare_sql_addfield("timebooked", "SUM(timereg.time_booked)"); $sql_obj->prepare_sql_addwhere("date='" . date("Y-m-d") . "'"); if ($this->access_staff_ids) { $sql_obj->prepare_sql_addwhere("employeeid IN (" . format_arraytocommastring($this->access_staff_ids) . ")"); } $sql_obj->generate_sql(); $sql_obj->execute(); $sql_obj->fetch_array(); list($booked_time_hours, $booked_time_mins) = explode(":", time_format_hourmins($sql_obj->data[0]["timebooked"])); if ($booked_time_hours > 0 && $booked_time_mins > 0) { $message = "<b>Time booked for today: {$booked_time_hours} hours and {$booked_time_mins} minutes.</b><br />Click here to add more time."; } elseif ($booked_time_hours > 0) { $message = "<b>Time booked for today: {$booked_time_hours} hours.</b><br />Click here to add more time."; } elseif ($booked_time_mins > 0) { $message = "<b>Time booked for today: {$booked_time_mins} minutes.</b><br />Click here to add more time."; } else { $message = "<b>No time has been booked for today</b><br />Click here to add time.</b>"; } format_linkbox("default", "index.php?page=timekeeping/timereg-day-edit.php", "<p>{$message}</p>"); print "<br />"; print "<table class=\"table_highlight\" width=\"100%\"><tr>"; // Week selection links print "<td width=\"70%\">"; print "<b>WEEK " . $this->date_selected_weekofyear . ", " . $this->date_selected_year . "</b><br>"; print "(" . time_format_humandate($this->date_selected_start) . " to " . time_format_humandate($this->date_selected_end) . ")<br>"; print "<br>"; print "<p><b>"; print "<a class=\"button\" href=\"index.php?page=timekeeping/timereg.php&employeeid=" . $this->employeeid . "&weekofyear=" . $date_option_previousweek . "&year=" . $date_option_previousyear . "\"><< Previous Week</a>"; // check for date in the future if ($this->config_timesheet_booktofuture == "disabled") { if (time_date_to_timestamp(time_calculate_weekstart($date_option_nextweek, $date_option_nextyear)) < time()) { // end date is in not in the future print " <a class=\"button\" href=\"index.php?page=timekeeping/timereg.php&employeeid=" . $this->employeeid . "&weekofyear=" . $date_option_nextweek . "&year=" . $date_option_nextyear . "\">Next Week >></a>"; } } else { print " <a class=\"button\" href=\"index.php?page=timekeeping/timereg.php&employeeid=" . $this->employeeid . "&weekofyear=" . $date_option_nextweek . "&year=" . $date_option_nextyear . "\">Next Week >></a>"; } print "</b></p>"; print "</td>"; // goto date form print "<td width=\"30%\">"; print "<form method=\"get\" action=\"index.php\" class=\"form_standard\">"; $this->obj_form_goto->render_field("date"); print "<br>"; $this->obj_form_goto->render_field("page"); $this->obj_form_goto->render_field("submit"); print "</form>"; print "</td>"; print "</tr></table><br>"; // Employee selection form // // we use a custom form display method here, since the normal form // class will draw a fully styled form in a table. // if ($this->employeeid) { print "<table class=\"table_highlight\" width=\"100%\"><tr><td width=\"100%\">"; } else { print "<table class=\"table_highlight_important\" width=\"100%\"><tr><td width=\"100%\">"; } print "<form method=\"get\" action=\"index.php\" class=\"form_standard\">"; print "<p><b>Select an employee to view:</b></p>"; $this->obj_form_employee->render_field("employeeid"); $this->obj_form_employee->render_field("weekofyear"); $this->obj_form_employee->render_field("year"); $this->obj_form_employee->render_field("page"); $this->obj_form_employee->render_field("submit"); print "</form>"; print "</td></tr></table><br>"; if ($this->employeeid) { // custom labels and links if ($this->config_timesheet_booktofuture == "disabled") { if (time_date_to_timestamp($this->date_selected_daysofweek[0]) < time()) { $this->obj_table_week->custom_column_link("monday", "index.php?page=timekeeping/timereg-day.php&date=" . $this->date_selected_daysofweek[0] . ""); } if (time_date_to_timestamp($this->date_selected_daysofweek[1]) < time()) { $this->obj_table_week->custom_column_link("tuesday", "index.php?page=timekeeping/timereg-day.php&date=" . $this->date_selected_daysofweek[1] . ""); } if (time_date_to_timestamp($this->date_selected_daysofweek[2]) < time()) { $this->obj_table_week->custom_column_link("wednesday", "index.php?page=timekeeping/timereg-day.php&date=" . $this->date_selected_daysofweek[2] . ""); } if (time_date_to_timestamp($this->date_selected_daysofweek[3]) < time()) { $this->obj_table_week->custom_column_link("thursday", "index.php?page=timekeeping/timereg-day.php&date=" . $this->date_selected_daysofweek[3] . ""); } if (time_date_to_timestamp($this->date_selected_daysofweek[4]) < time()) { $this->obj_table_week->custom_column_link("friday", "index.php?page=timekeeping/timereg-day.php&date=" . $this->date_selected_daysofweek[4] . ""); } if (time_date_to_timestamp($this->date_selected_daysofweek[5]) < time()) { $this->obj_table_week->custom_column_link("saturday", "index.php?page=timekeeping/timereg-day.php&date=" . $this->date_selected_daysofweek[5] . ""); } if (time_date_to_timestamp($this->date_selected_daysofweek[6]) < time()) { $this->obj_table_week->custom_column_link("sunday", "index.php?page=timekeeping/timereg-day.php&date=" . $this->date_selected_daysofweek[6] . ""); } } else { // add links $this->obj_table_week->custom_column_link("monday", "index.php?page=timekeeping/timereg-day.php&date=" . $this->date_selected_daysofweek[0] . ""); $this->obj_table_week->custom_column_link("tuesday", "index.php?page=timekeeping/timereg-day.php&date=" . $this->date_selected_daysofweek[1] . ""); $this->obj_table_week->custom_column_link("wednesday", "index.php?page=timekeeping/timereg-day.php&date=" . $this->date_selected_daysofweek[2] . ""); $this->obj_table_week->custom_column_link("thursday", "index.php?page=timekeeping/timereg-day.php&date=" . $this->date_selected_daysofweek[3] . ""); $this->obj_table_week->custom_column_link("friday", "index.php?page=timekeeping/timereg-day.php&date=" . $this->date_selected_daysofweek[4] . ""); $this->obj_table_week->custom_column_link("saturday", "index.php?page=timekeeping/timereg-day.php&date=" . $this->date_selected_daysofweek[5] . ""); $this->obj_table_week->custom_column_link("sunday", "index.php?page=timekeeping/timereg-day.php&date=" . $this->date_selected_daysofweek[6] . ""); } // column labels $this->obj_table_week->custom_column_label("monday", "Monday<br><font style=\"font-size: 8px;\">(" . time_format_humandate($this->date_selected_daysofweek[0]) . ")</font>"); $this->obj_table_week->custom_column_label("tuesday", "Tuesday<br><font style=\"font-size: 8px;\">(" . time_format_humandate($this->date_selected_daysofweek[1]) . ")</font>"); $this->obj_table_week->custom_column_label("wednesday", "Wednesday<br><font style=\"font-size: 8px;\">(" . time_format_humandate($this->date_selected_daysofweek[2]) . ")</font>"); $this->obj_table_week->custom_column_label("thursday", "Thursday<br><font style=\"font-size: 8px;\">(" . time_format_humandate($this->date_selected_daysofweek[3]) . ")</font>"); $this->obj_table_week->custom_column_label("friday", "Friday<br><font style=\"font-size: 8px;\">(" . time_format_humandate($this->date_selected_daysofweek[4]) . ")</font>"); $this->obj_table_week->custom_column_label("saturday", "Saturday<br><font style=\"font-size: 8px;\">(" . time_format_humandate($this->date_selected_daysofweek[5]) . ")</font>"); $this->obj_table_week->custom_column_label("sunday", "Sunday<br><font style=\"font-size: 8px;\">(" . time_format_humandate($this->date_selected_daysofweek[6]) . ")</font>"); // display week time table $this->obj_table_week->render_table_html(); print "<table width=\"100%\">"; // add time link if (user_permissions_staff_get("timereg_write", $this->employeeid)) { print "<td align=\"left\" valign=\"top\"><p><a class=\"button\" href=\"index.php?page=timekeeping/timereg-day-edit.php\">Add new time entry</a></p></td>"; } else { print "<p><i>You have read-only access to this employee and therefore can not add any more time.</i></p>"; } // display CSV/PDF download link print "<td align=\"right\">"; print "<p><a class=\"button_export\" href=\"index-export.php?mode=csv&page=timekeeping/timereg.php\">Export as CSV</a></p>"; print "<p><a class=\"button_export\" href=\"index-export.php?mode=pdf&page=timekeeping/timereg.php\">Export as PDF</a></p>"; print "</td>"; print "</table>"; } }
function execute() { /* Check if time entry can be adjusted */ if ($this->id) { $sql_obj = new sql_query(); $sql_obj->string = "SELECT locked, groupid FROM `timereg` WHERE id='" . $this->id . "' LIMIT 1"; $sql_obj->execute(); if ($sql_obj->num_rows()) { $sql_obj->fetch_array(); $this->locked = $sql_obj->data[0]["locked"]; // so we can tell if the time is locked $this->groupid = $sql_obj->data[0]["groupid"]; // tells us what group id the time belongs to } unset($sql_obj); } /* Input Form Allows the creation of a new entry for the day, or the adjustment of an existing one. */ $this->obj_form = new form_input(); $this->obj_form->formname = "timereg_day"; $this->obj_form->language = $_SESSION["user"]["lang"]; $this->obj_form->action = "timekeeping/timereg-day-edit-process.php"; $this->obj_form->method = "post"; // hidden stuff $structure = NULL; $structure["fieldname"] = "id_timereg"; $structure["type"] = "hidden"; $structure["defaultvalue"] = $this->id; $this->obj_form->add_input($structure); // employee selection box $sql_obj = new sql_query(); $sql_obj->prepare_sql_settable("staff"); $sql_obj->prepare_sql_addfield("id", "id"); $sql_obj->prepare_sql_addfield("label", "staff_code"); $sql_obj->prepare_sql_addfield("label1", "name_staff"); if ($this->access_staff_ids_write) { $sql_obj->prepare_sql_addwhere("id IN (" . format_arraytocommastring($this->access_staff_ids_write) . ")"); } $sql_obj->generate_sql(); $structure = form_helper_prepare_dropdownfromdb("employeeid", $sql_obj->string); // if there is currently no employee set, and there is only one // employee in the selection box, automatically select it and update // the session variables. if (!$this->employeeid && count($structure["values"]) == 1) { $this->employeeid = $structure["values"][0]; $_SESSION["form"]["timereg"]["employeeid"] = $structure["values"][0]; } $structure["options"]["autoselect"] = "on"; $structure["options"]["width"] = "600"; $structure["options"]["search_filter"] = "yes"; $structure["defaultvalue"] = $this->employeeid; $this->obj_form->add_input($structure); // general $structure = NULL; $structure["fieldname"] = "date"; $structure["type"] = "date"; $structure["defaultvalue"] = $this->date; $structure["options"]["req"] = "yes"; $this->obj_form->add_input($structure); $structure = NULL; $structure["fieldname"] = "time_booked"; $structure["type"] = "hourmins"; $structure["options"]["req"] = "yes"; $this->obj_form->add_input($structure); $structure = NULL; $structure["fieldname"] = "description"; $structure["type"] = "textarea"; $structure["options"]["req"] = "yes"; $structure["options"]["width"] = "600"; $structure["options"]["height"] = "60"; $this->obj_form->add_input($structure); //project dropdown $sql_struct_obj = new sql_query(); $sql_struct_obj->prepare_sql_settable("projects"); $sql_struct_obj->prepare_sql_addfield("id", "projects.id"); $sql_struct_obj->prepare_sql_addfield("label", "projects.code_project"); $sql_struct_obj->prepare_sql_addfield("label1", "projects.name_project"); $sql_struct_obj->prepare_sql_addorderby("code_project"); $sql_struct_obj->prepare_sql_addwhere("id = 'CURRENTID' OR date_end = '0000-00-00'"); $structure = form_helper_prepare_dropdownfromobj("projectid", $sql_struct_obj); $structure["options"]["autoselect"] = "on"; $structure["options"]["width"] = "600"; $structure["options"]["search_filter"] = "yes"; if (count($structure["values"]) == 0) { $structure["defaultvalue"] = "You need to create a project and add a phase to it in order to be able to book time."; $_SESSION["error"]["phaseid-error"] = 1; } $this->obj_form->add_input($structure); //phase dropdown $structure = NULL; $structure["fieldname"] = "phaseid"; $structure["type"] = "dropdown"; $structure["values"] = array(""); $structure["options"]["width"] = "600"; $structure["options"]["disabled"] = "yes"; $structure["options"]["search_filter"] = "yes"; $this->obj_form->add_input($structure); //add project field $structure = NULL; $structure["fieldname"] = "add_project"; $structure["type"] = "input"; $structure["options"]["no_fieldname"] = "yes"; $structure["options"]["no_shift"] = "yes"; $structure["options"]["prelabel"] = "<div id=\"add_project_box\"><span id=\"toggle_add_project\">\n\t\t\t\t\t\t\t\t<strong>Add New Project</strong>\n\t\t\t\t\t\t\t\t<div class=\"half_sized_break_line\"><br/></div>\n\t\t\t\t\t\t\t\tNew Project: "; $structure["options"]["label"] = " <a class=\"insert_project_phase button_small\" id=\"insert_project\" href=\"\">Add</a>\n\t\t\t\t\t\t\t\t</span><div class=\"half_sized_break_line\"><br/></div>\n\t\t\t\t\t\t\t\t<strong><a id=\"project_add_cancel\" class=\"add_link\" href=\"\">Add New Project</a></strong></div>"; $this->obj_form->add_input($structure); //add phase field $structure = NULL; $structure["fieldname"] = "add_phase"; $structure["type"] = "input"; $structure["options"]["no_fieldname"] = "yes"; $structure["options"]["no_shift"] = "yes"; $structure["options"]["prelabel"] = "<div id=\"add_phase_box\"><span id=\"toggle_add_phase\">\n\t\t\t\t\t\t\t\t<strong>Add Phase to Current Project</strong>\n\t\t\t\t\t\t\t\t<div class=\"half_sized_break_line\"><br/></div>\n\t\t\t\t\t\t\t\tNew Phase: "; $structure["options"]["label"] = " <a class=\"insert_project_phase button_small\" id=\"insert_phase\" href=\"\">Add</a>\n\t\t\t\t\t\t\t\t</span><div class=\"half_sized_break_line\"><br/></div>\n\t\t\t\t\t\t\t\t<strong><a id=\"phase_add_cancel\" class=\"add_link\" href=\"\">Add Phase to Current Project</a></strong></div>"; $this->obj_form->add_input($structure); // submit section $structure = NULL; $structure["fieldname"] = "submit"; $structure["type"] = "submit"; $structure["defaultvalue"] = "Save Changes"; $this->obj_form->add_input($structure); // define subforms if (user_permissions_get("projects_write")) { $this->obj_form->subforms["timereg_day"] = array("employeeid", "projectid", "phaseid", "add_project", "add_phase", "date", "time_booked", "description"); } else { $this->obj_form->subforms["timereg_day"] = array("employeeid", "projectid", "phaseid", "date", "time_booked", "description"); } $this->obj_form->subforms["hidden"] = array("id_timereg"); if ($this->locked) { $this->obj_form->subforms["submit"] = array(); } else { $this->obj_form->subforms["submit"] = array("submit"); } $sql_obj = new sql_query(); $sql_obj->string = "SELECT id FROM `timereg` WHERE id='" . $this->id . "' LIMIT 1"; $sql_obj->execute(); if ($sql_obj->num_rows()) { // fetch the form data $this->obj_form->sql_query = "SELECT * FROM `timereg` WHERE id='" . $this->id . "' LIMIT 1"; $this->obj_form->load_data(); $this->obj_form->structure['projectid']['defaultvalue'] = sql_get_singlevalue("SELECT project_phases.projectid AS value FROM timereg LEFT JOIN project_phases ON project_phases.id = timereg.phaseid WHERE timereg.id='" . $this->id . "'"); } else { // load any data returned due to errors $this->obj_form->load_data_error(); } }
function execute() { // establish a new table object $this->obj_table = new table(); $this->obj_table->language = $_SESSION["user"]["lang"]; $this->obj_table->tablename = "timereg_table"; // define all the columns and structure $this->obj_table->add_column("date", "date", "timereg.date"); $this->obj_table->add_column("standard", "name_phase", "project_phases.name_phase"); $this->obj_table->add_column("standard", "name_staff", "CONCAT_WS(' -- ', staff.staff_code, staff.name_staff)"); $this->obj_table->add_column("standard", "time_group", "time_groups.name_group"); $this->obj_table->add_column("standard", "description", "timereg.description"); $this->obj_table->add_column("hourmins", "time_booked", "timereg.time_booked"); // defaults $this->obj_table->columns = array("date", "name_phase", "name_staff", "time_group", "description", "time_booked"); $this->obj_table->columns_order = array("date", "name_phase"); $this->obj_table->columns_order_options = array("date", "name_phase", "name_staff", "time_group", "description", "time_booked"); // define SQL structure $this->obj_table->sql_obj->prepare_sql_settable("timereg"); $this->obj_table->sql_obj->prepare_sql_addfield("id", "timereg.id"); $this->obj_table->sql_obj->prepare_sql_addfield("employeeid", "timereg.employeeid"); $this->obj_table->sql_obj->prepare_sql_addjoin("LEFT JOIN staff ON timereg.employeeid = staff.id"); $this->obj_table->sql_obj->prepare_sql_addjoin("LEFT JOIN time_groups ON timereg.groupid = time_groups.id"); $this->obj_table->sql_obj->prepare_sql_addjoin("LEFT JOIN project_phases ON timereg.phaseid = project_phases.id"); $this->obj_table->sql_obj->prepare_sql_addjoin("LEFT JOIN projects ON project_phases.projectid = projects.id"); $this->obj_table->sql_obj->prepare_sql_addwhere("projects.id = '" . $this->id . "'"); if ($this->access_staff_ids) { $this->obj_table->sql_obj->prepare_sql_addwhere("timereg.employeeid IN (" . format_arraytocommastring($this->access_staff_ids) . ")"); } /// Filtering/Display Options // fixed options $this->obj_table->add_fixed_option("id", $this->id); // acceptable filter options $structure = NULL; $structure["fieldname"] = "date_start"; $structure["type"] = "date"; $structure["sql"] = "date >= 'value'"; $this->obj_table->add_filter($structure); $structure = NULL; $structure["fieldname"] = "date_end"; $structure["type"] = "date"; $structure["sql"] = "date <= 'value'"; $this->obj_table->add_filter($structure); $structure = form_helper_prepare_dropdownfromdb("phaseid", "SELECT id, name_phase as label FROM project_phases WHERE projectid='" . $this->id . "' ORDER BY name_phase ASC"); $structure["sql"] = "project_phases.id='value'"; $structure["options"]["search_filter"] = "yes"; $this->obj_table->add_filter($structure); $sql_obj = new sql_query(); $sql_obj->prepare_sql_settable("staff"); $sql_obj->prepare_sql_addfield("id", "id"); $sql_obj->prepare_sql_addfield("label", "staff_code"); $sql_obj->prepare_sql_addfield("label1", "name_staff"); if ($this->access_staff_ids) { $sql_obj->prepare_sql_addwhere("id IN (" . format_arraytocommastring($this->access_staff_ids) . ")"); } $sql_obj->generate_sql(); $structure = form_helper_prepare_dropdownfromdb("employeeid", $sql_obj->string); $structure["sql"] = "timereg.employeeid='value'"; $structure["options"]["search_filter"] = "yes"; $this->obj_table->add_filter($structure); $structure = NULL; $structure["fieldname"] = "no_group"; $structure["type"] = "checkbox"; $structure["sql"] = "groupid='0'"; $structure["options"]["label"] = "Only show unprocessed time"; $this->obj_table->add_filter($structure); $structure = NULL; $structure["fieldname"] = "searchbox"; $structure["type"] = "input"; $structure["sql"] = "(timereg.description LIKE '%value%' OR project_phases.name_phase LIKE '%value%' OR staff.name_staff LIKE '%value%')"; $this->obj_table->add_filter($structure); // create totals $this->obj_table->total_columns = array("time_booked"); // load options form $this->obj_table->load_options_form(); // generate & execute SQL query $this->obj_table->generate_sql(); $this->obj_table->load_data_sql(); }
function service_usage_alerts_generate($customerid = NULL) { log_debug("inc_services_usage", "Executing service_usage_alerts_generate({$customerid})"); /* Fetch configuration Options */ // check that email is enabled if (sql_get_singlevalue("SELECT value FROM config WHERE name='EMAIL_ENABLE' LIMIT 1") != "enabled") { log_write("error", "inc_services_usage", "Unable to email customer usage alerts, due to EMAIL_ENABLE being disabled"); return -1; } // fetch email address to send as. $email_sender = sql_get_singlevalue("SELECT value FROM config WHERE name='COMPANY_NAME'") . " <" . sql_get_singlevalue("SELECT value FROM config WHERE name='COMPANY_CONTACT_EMAIL'") . ">"; /* Run through all the active services */ $sql_custserv_obj = new sql_query(); $sql_custserv_obj->string = "SELECT id, customerid, serviceid, description, date_period_first, date_period_next, date_period_last FROM services_customers WHERE services_customers.active='1'"; if ($customerid) { $sql_custserv_obj->string .= " AND customerid='{$customerid}'"; } $sql_custserv_obj->execute(); if ($sql_custserv_obj->num_rows()) { $sql_custserv_obj->fetch_array(); foreach ($sql_custserv_obj->data as $customer_data) { /* Process each service that the customer has, provided that it is a usage service. Any non-usage services we can simply skip. */ // fetch service details $obj_service = new service_bundle(); $obj_service->option_type = "customer"; $obj_service->option_type_id = $customer_data["id"]; if (!$obj_service->verify_id_options()) { log_write("error", "customers_services", "Unable to verify service ID of " . $customer_data["id"] . " as being valid."); return 0; } $obj_service->load_data(); $obj_service->load_data_options(); // fetch customer details $sql_customer_obj = sql_get_singlerow("SELECT name_customer FROM customers WHERE id='" . $customer_data["customerid"] . "' LIMIT 1"); $arr_sql_contact = sql_get_singlerow("SELECT id, contact FROM customer_contacts WHERE customer_id = '" . $customer_data["customerid"] . "' AND role = 'accounts' LIMIT 1"); $arr_sql_contact_details = sql_get_singlerow("SELECT detail AS contact_email FROM customer_contact_records WHERE contact_id = '" . $arr_sql_contact["id"] . "' AND type = 'email' LIMIT 1"); // place the contact details into the customer details array. $sql_customer_obj["name_contact"] = $arr_sql_contact["contact"]; $sql_customer_obj["contact_email"] = $arr_sql_contact_details["contact_email"]; // check the service type $service_type = sql_get_singlevalue("SELECT name as value FROM service_types WHERE id='" . $obj_service->data["typeid"] . "'"); // only process data_traffic, time or generic_usage services // // (call services have usage, but we don't currently alert for those) // if ($service_type == "generic_with_usage" || $service_type == "time" || $service_type == "data_traffic") { log_debug("inc_services_usage", "Processing service " . $customer_data["id"] . " for customer " . $customer_data["customerid"] . ""); /* Fetch the customer's currently active period. */ $sql_periods_obj = new sql_query(); $sql_periods_obj->string = "SELECT " . "id, " . "date_start, " . "date_end, " . "usage_summary, " . "usage_alerted " . "FROM services_customers_periods " . "WHERE " . "id_service_customer='" . $customer_data["id"] . "' " . "AND invoiceid_usage = '0' " . "AND date_end >= '" . date("Y-m-d") . "' LIMIT 1"; $sql_periods_obj->execute(); if ($sql_periods_obj->num_rows()) { $sql_periods_obj->fetch_array(); $period_data = $sql_periods_obj->data[0]; // fetch billing mode $billing_mode = sql_get_singlevalue("SELECT name as value FROM billing_modes WHERE id='" . $obj_service->data["billing_mode"] . "'"); // fetch unit naming if ($service_type == "generic_with_usage") { $unitname = $obj_service->data["units"]; } else { $unitname = sql_get_singlevalue("SELECT name as value FROM service_units WHERE id='" . $obj_service->data["units"] . "'"); } /* Calculate number of included units TODO: This code is a replicant of the source in include/services/inc_service_invoicegen.php used for calculating partial periods and should really be functionalised as part of service usage continual improvements. Part of the issue is lack of service period OO handling functions - migrating the code to such a setup will make such ratio calculation functions far, far easier. */ // default ratio $ratio = 1; // calculate usage abnormal period if ($obj_service->data["billing_mode_string"] == "monthend" || $obj_service->data["billing_mode_string"] == "monthadvance" || $obj_service->data["billing_mode_string"] == "monthtelco") { log_debug("inc_services_usage", "Usage period service bills by month date"); if (time_calculate_daynum($period_data["date_start"]) != "01") { // very first billing month log_write("debug", "inc_services_usage", "First billing month for this usage period, adjusting pricing to suit days."); if ($GLOBALS["config"]["SERVICE_PARTPERIOD_MODE"] == "seporate") { log_write("debug", "inc_services_usage", "Adjusting for partial month period (SERVICE_PARTPERIOD_MODE == seporate)"); // work out the total number of days $short_month_days_total = time_calculate_daynum(time_calculate_monthdate_last($period_data["date_start"])); $short_month_days_short = $short_month_days_total - time_calculate_daynum($period_data["date_start"]); log_write("debug", "inc_services_usage", "Short initial billing period of {$short_month_days_short} days"); // calculate ratio $ratio = $short_month_days_short / $short_month_days_total; log_write("debug", "inc_services_usage", "Calculated service bill ratio of {$ratio} to handle short period."); } else { log_write("debug", "inc_services_usage", "Adjusting for extended month period (SERVICE_PARTPERIOD_MODE == merge"); // work out the number of days extra $extra_month_days_total = time_calculate_daynum(time_calculate_monthdate_last($period_data["date_start"])); $extra_month_days_extra = $extra_month_days_total - time_calculate_daynum($period_data["date_start"]); log_debug("inc_services_usage", "{$extra_month_days_extra} additional days ontop of started billing period"); // calculate ratio $ratio = ($extra_month_days_extra + $extra_month_days_total) / $extra_month_days_total; log_write("debug", "inc_services_usage", "Calculated service bill ratio of {$ratio} to handle extended period."); } } } // end of calculate usage abnormal period // calculate a final period if ($period_data["date_period_last"] != "0000-00-00") { log_write("debug", "inc_services_usage", "Service has a final period date set (" . $customer_data["date_period_last"] . ")"); if ($customer_data["date_period_last"] == $period_data["date_end"] || time_date_to_timestamp($customer_data["date_period_last"]) < time_date_to_timestamp($period_data["date_end"])) { log_write("debug", "inc_services_usage", "Service is a final period, checking for time adjustment (if any)"); // fetch the regular end date $orig_dates = service_period_dates_generate($period_data["date_start"], $obj_service->data["billing_cycle_string"], $obj_service->data["billing_mode_string"]); if ($orig_dates["end"] != $period_data["date_end"]) { // work out the total number of days $time = NULL; $time["start"] = time_date_to_timestamp($period_data["date_start"]); $time["end_orig"] = time_date_to_timestamp($orig_dates["end"]); $time["end_new"] = time_date_to_timestamp($period_data["date_end"]); $time["orig_days"] = sprintf("%d", ($time["end_orig"] - $time["start"]) / 86400); $time["new_days"] = sprintf("%d", ($time["end_new"] - $time["start"]) / 86400); log_write("debug", "inc_services_usage", "Short initial billing period of " . $time["new_days"] . " days rather than expected " . $time["orig_days"] . ""); // calculate ratio $ratio = $time["new_days"] / $time["orig_days"]; log_write("debug", "inc_services_usage", "Calculated service bill ratio of {$ratio} to handle short period."); unset($time); } else { log_write("debug", "inc_services_usage", "Final service period is regular size, no adjustment required."); } } } if ($billing_mode == "monthend" || $billing_mode == "monthadvance") { log_debug("inc_services_usage", "Service is billed by calender month"); /* Handle monthly billing Normally, monthly billing is easy, however the very first billing period is special, as it may span a more than 1 month. Eg: if a service is started on 2008-01-09, the end of the billing period will be 2008-02-29, which is 1 month + 21 day. To handle this, we increase the number of included units by the following method: ( standard_cost / normal_month_num_days ) * num_days_in_partial_month == extra_amount total_amount = (extra_amount + normal_amount) Note: This code is based off the section found for inc_services_usage.php. Could be worth creating a function? */ // check if the period is the very first period - the start and end dates will be in different months. if (time_calculate_monthnum($period_data["date_start"]) != time_calculate_monthnum($period_data["date_end"])) { // very first billing month log_debug("inc_services_usage", "Very first billing month - adjusting included units to suit the extra time included."); // work out the number of days extra $extra_month_days_total = time_calculate_daynum(time_calculate_monthdate_last($period_data["date_start"])); $extra_month_days_extra = $extra_month_days_total - time_calculate_daynum($period_data["date_start"]); log_debug("inc_services_usage", "{$extra_month_days_extra} additional days ontop of started billing period"); // calculate number of included units - round up to nearest full unit $ratio = ($extra_month_days_total + $extra_month_days_extra) / $extra_month_days_total; } } log_write("debug", "inc_services_usage", "Usage period ratio calculated as {$ratio}"); /* ^ End of Ratio Calculation - object orientation required around this */ /* Process usage for each service type - there are differences between particular platforms. */ switch ($service_type) { case "generic_with_usage": case "time": /* Fetch the amount of usage */ $usage_obj = new service_usage_generic(); $usage_obj->id_service_customer = $customer_data["id"]; $usage_obj->date_start = $period_data["date_start"]; $usage_obj->date_end = $period_data["date_end"]; if ($usage_obj->load_data_service()) { $usage_obj->fetch_usagedata(); if (isset($usage_obj->data["total_byunits"])) { $usage = $usage_obj->data["total_byunits"]; } else { $usage = $usage_obj->data["total"]; } } unset($usage_obj); /* Apply Ratio */ if ($ratio != "1") { $obj_service->data["included_units"] = sprintf("%d", $obj_service->data["included_units"] * $ratio); } /* Run usage notification logic */ if ($GLOBALS["config"]["SERVICES_USAGEALERTS_ENABLE"]) { $message = ""; if ($usage > $obj_service->data["included_units"]) { // usage is over 100% - check if we should report this log_debug("inc_service_usage", "Usage is over 100%"); if ($obj_service->data["alert_extraunits"]) { // check at what usage amount we last reported, and if // we have used alert_extraunits more usage since then, send // an alert to the customer. if ($usage - $period_data["usage_alerted"] >= $obj_service->data["alert_extraunits"]) { log_write("notification", "inc_service_usage", "Sending excess usage notification (over 100%)"); /* Send excess usage notification (over 100%) Message Example: This email has been sent to advise you that you have gone over the included usage on your plan. You have now used 70 excess ZZ on your Example Service plan. Used 120 ZZ out of 50 ZZ included in plan Excess usage of 70 ZZ charged at $5.00 per ZZ (exc taxes) Your current billing period ends on YYYY-MM-DD. */ // there is excess usage $usage_excess = $usage - $obj_service->data["included_units"]; // prepare message $message .= "This email has been sent to advise you that you have gone over the included usage on your plan\n"; $message .= "\n"; $message .= "You have now used {$usage_excess} excess {$unitname} on your " . $obj_service->data["name_service"] . " plan.\n"; $message .= "\n"; $message .= "Used {$usage} {$unitname} out of " . $obj_service->data["included_units"] . " {$unitname} included in plan.\n"; $message .= "Excess usage of {$usage_excess} {$unitname} charged at " . $obj_service->data["price_extraunits"] . " per {$unitname} (exc taxes).\n"; $message .= "\n"; $message .= "Your current billing period ends on " . $period_data["date_end"] . "\n"; $message .= "\n"; // send email if ($sql_customer_obj["contact_email"]) { $headers = "From: {$email_sender}\r\n"; mail($sql_customer_obj["name_contact"] . "<" . $sql_customer_obj["contact_email"] . ">", "Excess usage notification", $message, $headers); } else { log_write("error", "inc_service_usage", "Customer " . $sql_customer_obj["name_customer"] . " does not have an email address, unable to send usage notifications."); } // update alerted amount $sql_obj = new sql_query(); $sql_obj->string = "UPDATE services_customers_periods SET usage_alerted='{$usage}' WHERE id='" . $period_data["id"] . "' LIMIT 1"; $sql_obj->execute(); } } } else { // calculate 80% of the included usage $included_usage_80pc = $obj_service->data["included_units"] * 0.8; if ($usage == $obj_service->data["included_units"]) { log_debug("inc_service_usage", "Usage is at 100%"); // usage is at 100% // // make sure that: // 1. 100% usage alerting is enabled // 2. that we have not already sent this alert (by checking period_data["usage_summary"]) // if ($obj_service->data["alert_100pc"] && $period_data["usage_summary"] < $obj_service->data["included_units"]) { log_write("notification", "inc_service_usage", "Sending excess usage notification (100% reached)"); /* Send 100% usage notification Message Example: This email has been sent to advise you that you have used 100% of your included usage on your Example Service plan. Used 50 ZZ out of 50 ZZ included in plan Any excess usage will be charged at $5.00 per ZZ (exc taxes) Your current billing period ends on YYYY-MM-DD. */ // prepare message $message .= "This email has been sent to advise you that you have used 100% of your included usage on your " . $obj_service->data["name_service"] . " plan.\n"; $message .= "\n"; $message .= "Used {$usage} {$unitname} out of " . $obj_service->data["included_units"] . " {$unitname} included in plan.\n"; $message .= "Any excess usage will be charged at " . $obj_service->data["price_extraunits"] . " per {$unitname} (exc taxes).\n"; $message .= "\n"; $message .= "Your current billing period ends on " . $period_data["date_end"] . "\n"; $message .= "\n"; // send email if ($sql_customer_obj["contact_email"]) { $headers = "From: {$email_sender}\r\n"; mail($sql_customer_obj["name_contact"] . "<" . $sql_customer_obj["contact_email"] . ">", "100% usage notification", $message, $headers); } else { log_write("error", "inc_service_usage", "Customer " . $sql_customer_obj["name_customer"] . " does not have an email address, unable to send usage notifications."); } // update alerted amount $sql_obj = new sql_query(); $sql_obj->string = "UPDATE services_customers_periods SET usage_alerted='{$usage}' WHERE id='" . $period_data["id"] . "' LIMIT 1"; $sql_obj->execute(); } } elseif ($usage > $included_usage_80pc) { log_debug("inc_service_usage", "Usage is between 80% & 100%"); // usage is between 80 and 100% // // make sure that: // 1. 80% usage alerting is enabled // 2. that we have not already sent this alert (by checking period_data["usage_summary"]) // if ($obj_service->data["alert_80pc"] && $period_data["usage_summary"] < $included_usage_80pc) { log_write("notification", "inc_service_usage", "Sending excess usage notification (80% - 100%)"); /* Send 80% usage notification Message Example: This email has been sent to advise you that you have used over 80% of your included usage on your Example Service plan. Used 50 ZZ out of 50 ZZ included in plan Any excess usage will be charged at $5.00 per ZZ (exc taxes) Your current billing period ends on YYYY-MM-DD. */ // prepare message $message .= "This email has been sent to advise you that you have used over 80% of your included usage on your " . $obj_service->data["name_service"] . " plan.\n"; $message .= "\n"; $message .= "Used {$usage} {$unitname} out of " . $obj_service->data["included_units"] . " {$unitname} included in plan.\n"; $message .= "Any excess usage will be charged at " . $obj_service->data["price_extraunits"] . " per {$unitname} (exc taxes).\n"; $message .= "\n"; $message .= "Your current billing period ends on " . $period_data["date_end"] . "\n"; $message .= "\n"; // fetch email // send email if ($sql_customer_obj["contact_email"]) { $headers = "From: {$email_sender}\r\n"; mail($sql_customer_obj["name_contact"] . "<" . $sql_customer_obj["contact_email"] . ">", "80% usage notification", $message, $headers); } else { log_write("error", "inc_service_usage", "Customer " . $sql_customer_obj["name_customer"] . " does not have an email address, unable to send usage notifications."); } // update alerted amount $sql_obj = new sql_query(); $sql_obj->string = "UPDATE services_customers_periods SET usage_alerted='{$usage}' WHERE id='" . $period_data["id"] . "' LIMIT 1"; $sql_obj->execute(); } } } } else { log_write("notification", "inc_service_usage", "Not sending usage notification/reminder due to SERVICES_USAGEALERTS_ENABLE being disabled"); } /* Update Usage Summary - this used for various user interfaces and is the *total* transfer usage report. */ $sql_obj = new sql_query(); $sql_obj->string = "UPDATE services_customers_periods SET usage_summary='{$usage}' WHERE id='" . $period_data["id"] . "' LIMIT 1"; $sql_obj->execute(); break; case "data_traffic": /* DATA_TRAFFIC Data traffic services are more complex for usage checks and notifications than other services, due to the need to fetch usage amounts for each cap type and notify as appropiate. Some data services may also be uncapped/unlimited, in which case we want to record their current usage amount but won't need to ever send usage notifications. */ /* Fetch Traffic Caps & Details Returns all the traffic cap types including overrides. id_type, id_cap, type_name, type_label, cap_mode, cap_units_included, cap_units_price */ $traffic_types_obj = new traffic_caps(); $traffic_types_obj->id_service = $customer_data["serviceid"]; $traffic_types_obj->id_service_customer = $customer_data["id"]; $traffic_types_obj->load_data_traffic_caps(); $traffic_types_obj->load_data_override_caps(); /* Fetch the amount of usage */ $usage_obj = new service_usage_traffic(); $usage_obj->id_service_customer = $customer_data["id"]; $usage_obj->date_start = $period_data["date_start"]; $usage_obj->date_end = $period_data["date_end"]; if ($usage_obj->load_data_service()) { $usage_obj->fetch_usage_traffic(); } /* Update service usage database record for each cap Create a new usage alert summary record - this record defines the usage as at a certain date and tracks whether usage alerts were sent or not. */ $usage_alert_id = array(); // holds IDs of inserted rows foreach ($traffic_types_obj->data as $traffic_cap) { log_write("debug", "inc_service_usage", "Service " . $customer_data["id"] . " data usage for traffic type " . $traffic_type["type_name"] . " is " . $usage_obj->data["total_byunits"][$traffic_cap["type_label"]] . " units"); // create new record $sql_obj = new sql_query(); $sql_obj->string = "INSERT INTO service_usage_alerts\n\t\t\t\t\t\t\t\t\t\t\t\t(id_service_customer,\n\t\t\t\t\t\t\t\t\t\t\t\t id_service_period,\n\t\t\t\t\t\t\t\t\t\t\t\t id_type,\n\t\t\t\t\t\t\t\t\t\t\t\t date_update,\n\t\t\t\t\t\t\t\t\t\t\t\t usage_current)\n\t\t\t\t\t\t\t\t\t\t\t\tVALUES\n\t\t\t\t\t\t\t\t\t\t\t\t('" . $customer_data["id"] . "',\n\t\t\t\t\t\t\t\t\t\t\t\t '" . $period_data["id"] . "',\n\t\t\t\t\t\t\t\t\t\t\t\t '" . $traffic_cap["id_type"] . "',\n\t\t\t\t\t\t\t\t\t\t\t\t '" . date("Y-m-d") . "',\n\t\t\t\t\t\t\t\t\t\t\t\t '" . $usage_obj->data["total_byunits"][$traffic_cap["type_label"]] . "')"; $sql_obj->execute(); // record type label ID $usage_alert_id[$traffic_cap["type_label"]] = $sql_obj->fetch_insert_id(); } // Update Usage Summary - this used for various user interfaces and is the *total* transfer usage report. log_write("notification", "inc_service_usage", "Customer " . $sql_customer_obj["name_customer"] . " has used a total of " . $usage_obj->data["total_byunits"]["total"] . " {$unitname} traffic on service \"" . $obj_service->data["name_service"] . "\""); $sql_obj = new sql_query(); $sql_obj->string = "UPDATE services_customers_periods SET usage_summary='" . $usage_obj->data["total_byunits"]["total"] . "' WHERE id='" . $period_data["id"] . "' LIMIT 1"; $sql_obj->execute(); /* Run usage notification logic */ if ($GLOBALS["config"]["SERVICES_USAGEALERTS_ENABLE"]) { // fetch usage - in particular, the last usage amount that we alerted for. $usage = $usage_obj->data["total_byunits"][$traffic_cap["type_label"]]; $usage_alerted = 0; $sql_obj->string = "SELECT date_sent, usage_alerted FROM service_usage_alerts WHERE id_service_customer='" . $customer_data["id"] . "' AND id_service_period='" . $period_data["id"] . "' AND id_type='" . $traffic_cap["id_type"] . "' AND id!='" . $usage_alert_id[$traffic_cap["type_label"]] . "' ORDER BY date_sent DESC, id DESC LIMIT 1"; $sql_obj->execute(); if ($sql_obj->num_rows()) { $sql_obj->fetch_array(); if ($sql_obj->data[0]["date_sent"] != "0000-00-00") { $usage_alerted = $sql_obj->data[0]["usage_alerted"]; } } // used to flag the usage caps that need alerting $alert_80 = array(); $alert_100 = array(); $alert_extra = array(); $alert_none = array(); // run through current caps, flag all which need notifications. $j = 0; foreach ($traffic_types_obj->data as $traffic_cap) { // we don't care about unlimited traffic if ($traffic_cap["cap_mode"] != "capped") { // skip log_write("debug", "inc_service_usage", "Skipping traffic cap due to mode of " . $traffic_cap["cap_mode"] . ""); $alert_none[] = $traffic_cap["type_label"]; continue; } // determine caps if ($ratio != "1") { // recalculate for short or long months $cap_units_included = sprintf("%d", $traffic_cap["cap_units_included"] * $ratio); // save for rest of session $traffic_types_obj->data[$j]["cap_units_included"] = $cap_units_included; } else { // no changes $cap_units_included = $traffic_cap["cap_units_included"]; } // determine threshholds $cap_100 = $cap_units_included; $cap_80 = $cap_units_included * 0.8; if ($usage >= $cap_100) { // usage is at or over 100% if ($usage < $cap_100 + $obj_service->data["alert_extraunits"]) { // just over 100%, but less than the excess alert count - consider as 100% if ($usage_alerted < $cap_100) { $alert_100[] = $traffic_cap["type_label"]; } else { $alert_none[] = $traffic_cap["type_label"]; } } else { // well over 100% if ($obj_service->data["alert_extraunits"]) { // check at what usage amount we last reported, and if // we have used alert_extraunits+ more usage since then, send // an alert to the customer. if ($usage - $usage_alerted >= $obj_service->data["alert_extraunits"]) { // excess usage $alert_extra[] = $traffic_cap["type_label"]; } else { $alert_none[] = $traffic_cap["type_label"]; } } else { // no extra unit alerts configured, so we should not alert to excess // usage. $alert_none[] = $traffic_cap["type_label"]; } } } elseif ($usage >= $cap_80 && $usage < $cap_100) { // usage between 80% and 100% if ($obj_service->data["alert_80pc"] && $usage_alerted < $cap_80) { // we haven't alerted for this yet, so flag it $alert_80[] = $traffic_cap["type_label"]; } else { $alert_none[] = $traffic_cap["type_label"]; } } else { // usage is below 80% mark $alert_none[] = $traffic_cap["type_label"]; } $j++; } // end of traffic loops log_write("debug", "inc_service_usage", "Following data caps are at 80% alert: " . format_arraytocommastring($alert_80) . ""); log_write("debug", "inc_service_usage", "Following data caps are at 100% alert: " . format_arraytocommastring($alert_100) . ""); log_write("debug", "inc_service_usage", "Following data caps are at 100% + extra blocks alert: " . format_arraytocommastring($alert_extra) . ""); log_write("debug", "inc_service_usage", "Following data caps do not require alerting: " . format_arraytocommastring($alert_none) . ""); /* Process Usage Notifications Here we need to loop through all caps flagged for notifications and write a message to the customer for all overage caps */ if (!empty($alert_80) || !empty($alert_100) || !empty($alert_extra)) { log_write("debug", "inc_service_usage", "Alerting for service, preparing email message."); /* Now we run through all the alert flagged data caps and use it to assemble a usage notification warning email. Example Message --------------- DATA USAGE ADVISORY This email has been sent to advise you about your data service usage as of 18-05-2011. Service "My Example Internet Service" NATIONAL You have used 150% of your National data cap. Used 15GB out of 10GB included in plan. Excess usage of 5GB charged at $5.00 per GB (exc taxes) INTERNATIONAL You have used 84% of your International data cap. Used 84GB out of 100GB included in plan. Any future excess usage will be charged at $8.00 per GB (exc taxes) BILLING PERIOD Your current billing period ends on YYYY-MM-DD. {optional} Note: This billing period is longer/shorter than your regular billing period, this may mean your data cap allocations appear different to normal to refect the longer/shorter period. This typically occurs when you first signup to a service, upgrade a service or cancel a service. */ $message = "\n"; $message .= "DATA USAGE ADVISORY\n"; $message .= "\n"; $message .= "This email has been sent to advise you about your data service usage as of " . time_format_humandate() . "\n"; $message .= "\n"; $message .= "Service \"" . $obj_service->data["name_service"] . "\"\n"; $message .= "\n"; $message .= "\n"; $message .= "\n"; foreach ($traffic_types_obj->data as $traffic_cap) { log_write("debug", "inc_service_usage", "Preparing usage warning email messages for: \"" . $traffic_cap["type_label"] . "\""); // determine percentage used $percentage = sprintf("%d", $usage_obj->data["total_byunits"][$traffic_cap["type_label"]] / $traffic_cap["cap_units_included"] * 100); // if there is only one cap, adjust label if ($traffic_types_obj->data_num_rows == 1) { $traffic_cap["type_name"] = "All Traffic"; } // 80%-100% if (in_array($traffic_cap["type_label"], $alert_80)) { $message .= strtoupper($traffic_cap["type_name"]) . "\n"; $message .= "\n"; $message .= "You have used {$percentage}% of your " . $traffic_cap["type_name"] . " data cap\n"; $message .= "\n"; $message .= "Used " . $usage_obj->data["total_byunits"][$traffic_cap["type_label"]] . " {$unitname} out of " . $traffic_cap["cap_units_included"] . " {$unitname} included in plan.\n"; $message .= "Any future excess usage will be charged at " . format_money($traffic_cap["cap_units_price"]) . " per {$unitname} (exc taxes)\n"; $message .= "\n\n"; } // 100% if (in_array($traffic_cap["type_label"], $alert_100)) { $message .= strtoupper($traffic_cap["type_name"]) . "\n"; $message .= "\n"; $message .= "You have used {$percentage}% of your " . $traffic_cap["type_name"] . " data cap\n"; $message .= "\n"; $message .= "Used " . $usage_obj->data["total_byunits"][$traffic_cap["type_label"]] . " {$unitname} out of " . $traffic_cap["cap_units_included"] . " {$unitname} included in plan.\n"; $message .= "Any future excess usage will be charged at " . format_money($traffic_cap["cap_units_price"]) . " per {$unitname} (exc taxes)\n"; $message .= "\n\n"; } // 100% ++ excess if (in_array($traffic_cap["type_label"], $alert_extra)) { $usage_excess = $usage_obj->data["total_byunits"][$traffic_cap["type_label"]] - $traffic_cap["cap_units_included"]; $message .= strtoupper($traffic_cap["type_name"]) . "\n"; $message .= "\n"; $message .= "You have used {$percentage}% of your " . $traffic_cap["type_name"] . " data cap\n"; $message .= "\n"; $message .= "Used " . $usage_obj->data["total_byunits"][$traffic_cap["type_label"]] . " out of " . $traffic_cap["cap_units_included"] . " {$unitname} included in plan.\n"; $message .= "Excess usage of " . $usage_excess . " {$unitname} charged at " . format_money($traffic_cap["cap_units_price"]) . " per {$unitname} (exc taxes)\n"; $message .= "\n\n"; } } /* Footer */ $message .= "BILLING PERIOD\n"; $message .= "\n"; $message .= "Your current billing period ends on " . time_format_humandate($period_data["date_end"]) . "\n"; $message .= "\n"; /* Tell user about long/short periods to avoid inevidable accounts enquires relating to their usage */ if ($ratio < 1) { // shorter period $message .= "\n"; $message .= "Important Note: This billing period is shorter than your regular billing period, this may mean your data cap allocations appear smaller than normal to refect the shorter period. This typically occurs when you first signup to a service, upgrade a service or cancel a service.\n"; } elseif ($ratio > 1) { // longer period $message .= "\n"; $message .= "Important Note: This billing period is longer than your regular billing period, this may mean your data cap allocations appear larger than normal to refect the longer period. This typically occurs when you first signup to a service, upgrade a service or cancel a service.\n"; } /* Issue Email TODO: Future enhancements will include the capability to select a usage contact email address first, before falling back to the regular accounts email address. This will make it easier for companies to send bills to AR but usage alerts to staff. */ if ($sql_customer_obj["contact_email"]) { $headers = "From: {$email_sender}\r\n"; mail($sql_customer_obj["name_contact"] . "<" . $sql_customer_obj["contact_email"] . ">", "Service usage notification", $message, $headers); log_write("notification", "inc_service_usage", "Issuing usage notification email to " . $sql_customer_obj["name_contact"] . " at " . $sql_customer_obj["contact_email"] . ""); } else { log_write("error", "inc_service_usage", "Customer " . $sql_customer_obj["name_customer"] . " does not have an email address, unable to send usage notifications."); } /* Update alerted amount tracker */ $sql_obj = new sql_query(); $sql_obj->string = "UPDATE service_usage_alerts SET usage_alerted='" . $usage_obj->data["total_byunits"][$traffic_cap["type_label"]] . "', date_sent='" . date("Y-m-d") . "' WHERE id='" . $usage_alert_id[$traffic_cap["type_label"]] . "' LIMIT 1"; $sql_obj->execute(); } // end if usage notifications to process } // end if alerts enabled unset($traffic_types_obj); unset($usage_obj); break; } // end of switch service type } // end if usage periods exist } // end if a usage service } // end of loop through customer services } // end if customer(s) services exist }
function verify_upload_form($fieldname, $acceptable_formats = NULL) { log_write("debug", "file_storage", "Executing verify_upload_form({$fieldname}, Array)"); // make sure a file has been provided. if (!$_FILES[$fieldname]['size']) { // no file provided - maybe it hit the PHP max? switch ($_FILES[$fieldname]["error"]) { case UPLOAD_ERR_INI_SIZE: log_write("error", "file_storage", "File upload was in excess of maximum PHP limit of " . ini_get('upload_max_filesize') . ""); break; case UPLOAD_ERR_NO_FILE: log_write("error", "file_storage", "No file supplied for upload."); break; default: log_write("error", "file_storage", "Unexpected upload error: " . $_FILES[$fieldname]["error"] . ""); break; } // return failure $_SESSION["error"]["{$fieldname}-error"] = 1; return 0; } // check the filesize is less than or equal to the max upload size if ($_FILES[$fieldname]['size'] >= $this->config["upload_maxbytes"]) { $filesize_max_human = format_size_human($this->config["upload_maxbytes"]); $filesize_upload_human = format_size_human($_FILES[$fieldname]['size']); log_write("error", "file_storage", "Files must be no larger than {$filesize_max_human}. You attempted to upload a {$filesize_upload_human} file."); $_SESSION["error"]["{$fieldname}-error"] = 1; return 0; } // check if the upload format is acceptable if ($acceptable_formats) { if (!in_array(format_file_extension($_FILES[$fieldname]["name"]), $acceptable_formats)) { log_write("error", "file_storage", "Unsupported file format, only the following file formats are acceptable: " . format_arraytocommastring($acceptable_formats)); $_SESSION["error"]["{$fieldname}-error"] = 1; return 0; } } // no problems return 1; }
function execute() { /* Define form structure */ $this->obj_form = new form_input(); $this->obj_form->formname = "timebilled_view"; $this->obj_form->language = $_SESSION["user"]["lang"]; $this->obj_form->action = "projects/timebilled-edit-process.php"; $this->obj_form->method = "post"; // general $structure = NULL; $structure["fieldname"] = "name_group"; $structure["type"] = "input"; $structure["options"]["req"] = "yes"; $structure["defaultvalue"] = date("Y-m"); $this->obj_form->add_input($structure); $sql_struct_obj = new sql_query(); $sql_struct_obj->prepare_sql_settable("customers"); $sql_struct_obj->prepare_sql_addfield("id", "customers.id"); $sql_struct_obj->prepare_sql_addfield("label", "customers.code_customer"); $sql_struct_obj->prepare_sql_addfield("label1", "customers.name_customer"); $sql_struct_obj->prepare_sql_addorderby("code_customer"); $sql_struct_obj->prepare_sql_addwhere("id = 'CURRENTID' OR date_end = '0000-00-00'"); $structure = form_helper_prepare_dropdownfromobj("customerid", $sql_struct_obj); // $structure = form_helper_prepare_dropdownfromdb("customerid", "SELECT id, code_customer as label, name_customer as label1 FROM customers ORDER BY name_customer"); $structure["options"]["req"] = "yes"; $structure["options"]["width"] = "600"; $this->obj_form->add_input($structure); if ($this->groupid) { $structure = NULL; $structure["fieldname"] = "code_invoice"; $structure["type"] = "text"; $this->obj_form->add_input($structure); } $structure = NULL; $structure["fieldname"] = "description"; $structure["type"] = "textarea"; $structure["options"]["width"] = "600"; $structure["options"]["height"] = "60"; $this->obj_form->add_input($structure); // hidden values $structure = NULL; $structure["fieldname"] = "projectid"; $structure["type"] = "hidden"; $structure["defaultvalue"] = $this->id; $this->obj_form->add_input($structure); $structure = null; $structure["fieldname"] = "groupid"; $structure["type"] = "hidden"; $structure["defaultvalue"] = $this->groupid; $this->obj_form->add_input($structure); /* Define checkboxes for all unassigned time entries */ $this->obj_sql_entries = new sql_query(); $this->obj_sql_entries->prepare_sql_settable("timereg"); $this->obj_sql_entries->prepare_sql_addfield("id", "timereg.id"); $this->obj_sql_entries->prepare_sql_addfield("date", "timereg.date"); $this->obj_sql_entries->prepare_sql_addfield("name_phase", "project_phases.name_phase"); $this->obj_sql_entries->prepare_sql_addfield("name_staff", "CONCAT_WS(' -- ', staff.staff_code, staff.name_staff)"); $this->obj_sql_entries->prepare_sql_addfield("description", "timereg.description"); $this->obj_sql_entries->prepare_sql_addfield("time_booked", "timereg.time_booked"); $this->obj_sql_entries->prepare_sql_addfield("groupid", "timereg.groupid"); $this->obj_sql_entries->prepare_sql_addfield("billable", "timereg.billable"); $this->obj_sql_entries->prepare_sql_addjoin("LEFT JOIN staff ON timereg.employeeid = staff.id"); $this->obj_sql_entries->prepare_sql_addjoin("LEFT JOIN project_phases ON timereg.phaseid = project_phases.id"); $this->obj_sql_entries->prepare_sql_addwhere("project_phases.projectid='" . $this->id . "'"); if ($this->groupid) { $this->obj_sql_entries->prepare_sql_addwhere("(groupid='" . $this->groupid . "' OR !groupid)"); } else { $this->obj_sql_entries->prepare_sql_addwhere("!groupid"); } if ($this->access_staff_ids) { $this->obj_sql_entries->prepare_sql_addwhere("timereg.employeeid IN (" . format_arraytocommastring($this->access_staff_ids) . ")"); } $this->obj_sql_entries->generate_sql(); $this->obj_sql_entries->execute(); if ($this->obj_sql_entries->num_rows()) { $this->obj_sql_entries->fetch_array(); foreach ($this->obj_sql_entries->data as $data) { // define the billable check box $structure = NULL; $structure["fieldname"] = "time_" . $data["id"] . "_bill"; $structure["type"] = "checkbox"; $structure["options"]["label"] = " "; if ($data["groupid"] == $this->groupid && $data["billable"] == "1") { $structure["defaultvalue"] = "on"; } $this->obj_form->add_input($structure); // define the nobill check box $structure = NULL; $structure["fieldname"] = "time_" . $data["id"] . "_nobill"; $structure["type"] = "checkbox"; $structure["options"]["label"] = " "; if ($data["groupid"] == $this->groupid && $data["billable"] == "0") { $structure["defaultvalue"] = "on"; } $this->obj_form->add_input($structure); } } // submit button $structure = NULL; $structure["fieldname"] = "submit"; $structure["type"] = "submit"; if ($this->groupid) { $structure["defaultvalue"] = "Save Changes"; } else { $structure["defaultvalue"] = "Create Time Group"; } $this->obj_form->add_input($structure); // fetch the form data if editing if ($this->groupid) { $this->obj_form->sql_query = "SELECT time_groups.name_group, time_groups.customerid, time_groups.description, account_ar.code_invoice FROM time_groups LEFT JOIN account_ar ON account_ar.id = time_groups.invoiceid WHERE time_groups.id='" . $this->groupid . "' LIMIT 1"; $this->obj_form->load_data(); } else { // load any data returned due to errors $this->obj_form->load_data_error(); } }
function execute() { /* Create an array of all unbilled time records. We need to do the following to create this list: 1. Exclude any internal_only projects. 2. Include time which belongs to a time_group, but ONLY if the time group has not been added to an invoice. */ $unbilled_ids = array(); // select non-internal projects $sql_projects_obj = new sql_query(); $sql_projects_obj->string = "SELECT projects.id as projectid, project_phases.id as phaseid FROM project_phases LEFT JOIN projects ON projects.id = project_phases.projectid WHERE projects.internal_only='0'"; $sql_projects_obj->execute(); if ($sql_projects_obj->num_rows()) { $sql_projects_obj->fetch_array(); foreach ($sql_projects_obj->data as $project_data) { // select non-group time records $sql_obj = new sql_query(); $sql_obj->string = "SELECT id FROM timereg WHERE groupid='0' AND phaseid='" . $project_data["phaseid"] . "'"; $sql_obj->execute(); if ($sql_obj->num_rows()) { $sql_obj->fetch_array(); foreach ($sql_obj->data as $data_tmp) { // we store the ID inside an array key, since they are unique // and this will prevent us needed to check for the existance of // the ID already. $unbilled_ids[$data_tmp["id"]] = "on"; } } unset($sql_obj); // select unpaid group IDs $sql_obj = new sql_query(); $sql_obj->string = "SELECT id FROM time_groups WHERE projectid='" . $project_data["projectid"] . "' AND invoiceid='0'"; $sql_obj->execute(); if ($sql_obj->num_rows()) { $sql_obj->fetch_array(); foreach ($sql_obj->data as $data_group) { // fetch all the time reg IDs belonging this group, but only select time entries marked as billable - we // don't want to report a timegroup with unbillable time as being billed! $sql_reg_obj = new sql_query(); $sql_reg_obj->string = "SELECT id FROM timereg WHERE groupid='" . $data_group["id"] . "' AND billable='1'"; $sql_reg_obj->execute(); if ($sql_reg_obj->num_rows()) { $sql_reg_obj->fetch_array(); foreach ($sql_reg_obj->data as $data_tmp) { // we store the ID inside an array key, since they are unique // and this will prevent us needed to check for the existance of // the ID already. $unbilled_ids[$data_tmp["id"]] = "on"; } } unset($sql_reg_obj); } } unset($sql_obj); } } /* Define table */ // establish a new table object $this->obj_table = new table(); $this->obj_table->language = $_SESSION["user"]["lang"]; $this->obj_table->tablename = "timereg_unbilled"; // define all the columns and structure $this->obj_table->add_column("date", "date", "timereg.date"); $this->obj_table->add_column("standard", "name_phase", "CONCAT_WS(' -- ', projects.code_project, projects.name_project, project_phases.name_phase)"); $this->obj_table->add_column("standard", "name_staff", "CONCAT_WS(' -- ', staff.staff_code, staff.name_staff)"); $this->obj_table->add_column("standard", "time_group", "time_groups.name_group"); $this->obj_table->add_column("standard", "description", "timereg.description"); $this->obj_table->add_column("hourmins", "time_booked", "timereg.time_booked"); // defaults $this->obj_table->columns = array("date", "name_phase", "name_staff", "time_group", "description", "time_booked"); $this->obj_table->columns_order = array("date", "name_phase"); $this->obj_table->columns_order_options = array("date", "name_phase", "name_staff", "time_group", "description"); // define SQL structure $this->obj_table->sql_obj->prepare_sql_settable("timereg"); $this->obj_table->sql_obj->prepare_sql_addfield("id", "timereg.id"); $this->obj_table->sql_obj->prepare_sql_addfield("projectid", "projects.id"); $this->obj_table->sql_obj->prepare_sql_addfield("employeeid", "timereg.employeeid"); $this->obj_table->sql_obj->prepare_sql_addfield("timegroupid", "time_groups.id"); $this->obj_table->sql_obj->prepare_sql_addfield("timegroupinvoiceid", "time_groups.invoiceid"); $this->obj_table->sql_obj->prepare_sql_addjoin("LEFT JOIN staff ON timereg.employeeid = staff.id"); $this->obj_table->sql_obj->prepare_sql_addjoin("LEFT JOIN time_groups ON timereg.groupid = time_groups.id"); $this->obj_table->sql_obj->prepare_sql_addjoin("LEFT JOIN project_phases ON timereg.phaseid = project_phases.id"); $this->obj_table->sql_obj->prepare_sql_addjoin("LEFT JOIN projects ON project_phases.projectid = projects.id"); // provide list of valid IDs $unbilled_ids_keys = array_keys($unbilled_ids); $unbilled_ids_count = count($unbilled_ids_keys); $unbilled_ids_sql = ""; if ($unbilled_ids_count) { $this->obj_table->sql_obj->prepare_sql_addwhere("timereg.id IN (" . format_arraytocommastring($unbilled_ids_keys) . ")"); } // if the user only has access to specific staff, filter to these staff members if ($this->access_staff_ids) { $this->obj_table->sql_obj->prepare_sql_addwhere("timereg.employeeid IN (" . format_arraytocommastring($this->access_staff_ids) . ")"); } /// Filtering/Display Options // fixed options $this->obj_table->add_fixed_option("id", $this->id); // acceptable filter options $structure = NULL; $structure["fieldname"] = "date_start"; $structure["type"] = "date"; $structure["sql"] = "date >= 'value'"; $this->obj_table->add_filter($structure); $structure = NULL; $structure["fieldname"] = "date_end"; $structure["type"] = "date"; $structure["sql"] = "date <= 'value'"; $this->obj_table->add_filter($structure); $structure = form_helper_prepare_dropdownfromdb("phaseid", "SELECT \n\t\t\t\t\t\t\t\t\t\t\tprojects.code_project as label,\n\t\t\t\t\t\t\t\t\t\t\tprojects.name_project as label1,\n\t\t\t\t\t\t\t\t\t\t\tproject_phases.id as id, \n\t\t\t\t\t\t\t\t\t\t\tproject_phases.name_phase as label1\n\t\t\t\t\t\t\t\t\t\tFROM `projects` \n\t\t\t\t\t\t\t\t\t\tLEFT JOIN project_phases ON project_phases.projectid = projects.id\n\t\t\t\t\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\t\t\t\t\tprojects.internal_only='0'\n\t\t\t\t\t\t\t\t\t\tORDER BY\n\t\t\t\t\t\t\t\t\t\t\tprojects.name_project,\n\t\t\t\t\t\t\t\t\t\t\tproject_phases.name_phase"); $structure["sql"] = "project_phases.id='value'"; $structure["options"]["search_filter"] = "yes"; $this->obj_table->add_filter($structure); $sql_obj = new sql_query(); $sql_obj->prepare_sql_settable("staff"); $sql_obj->prepare_sql_addfield("id", "id"); $sql_obj->prepare_sql_addfield("label", "staff_code"); $sql_obj->prepare_sql_addfield("label1", "name_staff"); if ($this->access_staff_ids) { $sql_obj->prepare_sql_addwhere("id IN (" . format_arraytocommastring($this->access_staff_ids) . ")"); } $sql_obj->generate_sql(); $structure = form_helper_prepare_dropdownfromdb("employeeid", $sql_obj->string); $structure["sql"] = "timereg.employeeid='value'"; $structure["options"]["search_filter"] = "yes"; $this->obj_table->add_filter($structure); $structure = NULL; $structure["fieldname"] = "searchbox"; $structure["type"] = "input"; $structure["sql"] = "(timereg.description LIKE '%value%' OR project_phases.name_phase LIKE '%value%' OR staff.name_staff LIKE '%value%')"; $this->obj_table->add_filter($structure); $structure = NULL; $structure["fieldname"] = "groupby"; $structure["type"] = "radio"; $structure["values"] = array("none", "name_phase", "name_staff"); $structure["defaultvalue"] = "none"; $this->obj_table->add_filter($structure); // create totals $this->obj_table->total_columns = array("time_booked"); // load options form $this->obj_table->load_options_form(); // add group by options if ($this->obj_table->filter["filter_groupby"]["defaultvalue"] != "none") { $this->obj_table->sql_obj->prepare_sql_addgroupby($this->obj_table->filter["filter_groupby"]["defaultvalue"]); // replace timereg value with SUM query $this->obj_table->structure["time_booked"]["dbname"] = "SUM(timereg.time_booked)"; switch ($this->obj_table->filter["filter_groupby"]["defaultvalue"]) { case "name_staff": $this->obj_table->columns = array("name_staff", "time_booked"); $this->obj_table->columns_order = array(); $this->obj_table->columns_order_options = array("name_staff"); break; case "name_phase": $this->obj_table->columns = array("name_phase", "time_booked"); $this->obj_table->columns_order = array(); $this->obj_table->columns_order_options = array("name_phase"); break; } } // generate & execute SQL query (only if time entries exist) $this->obj_table->generate_sql(); if ($unbilled_ids_count) { $this->obj_table->load_data_sql(); } // delete any rows which belong to processed time groups for ($i = 0; $i < $this->obj_table->data_num_rows; $i++) { if ($this->obj_table->data[$i]["timegroupinvoiceid"]) { $this->obj_table->data[$i] = NULL; } } }
function render_javascript() { log_debug("form", "Executing render_javascript()"); print "<script type=\"text/javascript\">"; foreach (array_keys($this->structure) as $fieldname) { /* If any actions have been defined, process them */ if (!empty($this->actions[$fieldname])) { log_debug("form", "Processing action rules for {$fieldname} field"); foreach (array_keys($this->actions[$fieldname]) as $target_field) { if (isset($this->structure[$fieldname]["defaultvalue"]) && !empty($this->actions[$fieldname][$target_field][$this->structure[$fieldname]["defaultvalue"]])) { $action = $this->actions[$fieldname][$target_field][$this->structure[$fieldname]["defaultvalue"]]; } else { $action = $this->actions[$fieldname][$target_field]["default"]; } switch ($action) { case "show": print "obj_show('" . $target_field . "'); "; break; case "hide": print "obj_hide('" . $target_field . "'); "; break; } } } /* If the form type is input and has autocomplete, set a javascript value for the autocomplete feature. */ if (!empty($this->structure[$fieldname]["options"]["autocomplete"]) && $this->structure[$fieldname]["type"] == "input") { log_write("debug", "form", "Setting autocomplete dropdown values for form field {$fieldname}"); $values = array(); // load autocomplete data from SQL query if ($this->structure[$fieldname]["options"]["autocomplete"] == "sql") { log_write("debug", "form", "Fetching autocomplete data from SQL database"); $sql_obj = new sql_query(); $sql_obj->string = $this->structure[$fieldname]["options"]["autocomplete_sql"]; $sql_obj->execute(); if ($sql_obj->num_rows()) { $sql_obj->fetch_array(); foreach ($sql_obj->data as $data_row) { $values[] = $data_row["label"]; } } } // write javascript for autocomplete options print "\$(function() {\n"; print "\tvar autocomplete_{$fieldname} = [" . format_arraytocommastring($values, '"') . "];\n"; print "\t\$(\"#{$fieldname}\").autocomplete({\n"; print "\tsource: autocomplete_{$fieldname}\n"; print "\t});\n"; print "});\n"; } } print "</script>"; }
$new_input_structure[$i]['data_format'] = $data["format{$i}"]; $selected_fields[$i] = $data["column{$i}"]; } } if (in_array("amount", $selected_fields)) { $paired_value_state = true; } else { $paired_value_count = 0; foreach ($values_paired as $value_pair_key => $value_pair_value) { if (in_array($value_pair_key, $selected_fields) && in_array($value_pair_value, $selected_fields)) { $paired_value_count++; } } } if ($values_count != count($values_required) || $value_multi_requirement < 1 || count((array) $values_paired) != $paired_value_count && $paired_value_count > 0) { log_write("error", "page_output", "Make sure you have selected all the required column types (" . format_arraytocommastring($values_required) . ")"); } } /* * Process Data */ if (error_check()) { $_SESSION["error"]["form"]["bankstatement_csv"] = "failed"; header("Location: ../../index.php?page=accounts/import/bankstatement-csv.php"); exit(0); } else { // Process the editing of the selected input structure, if the ID is positive and numeric, edit, otherwise, add. if (count($new_input_structure) > 0) { if (isset($structure_name) && $structure_name != null) { //$structure_name //$structure_description
function page_execute($argv) { /* Input Options */ $option_date = NULL; $option_type = NULL; if (empty($argv[2])) { die("You must provide a date option in form of YYYY-MM-DD\n"); } if (preg_match('/^[0-9]{4}-[0-9]{2}-[0-9]{2}$/', $argv[2])) { $option_date = $argv[2]; } else { die("You must provide a date option in form of YYYY-MM-DD - wrong format supplied\n"); } if (empty($argv[3])) { die("Service Type must be set.\n"); } if (preg_match('/^\\S\\S*$/', $argv[3])) { $option_type = $argv[3]; $option_type_id = sql_get_singlevalue("SELECT id as value FROM service_types WHERE name='{$option_type}' LIMIT 1"); if (!$option_type_id) { die("Service type {$option_type} is unknown\n"); } } else { die("You must provide a service type\n"); } log_write("notification", "repair", "Executing usage charge rollback for invoices generated {$option_date} for service type {$option_type} (ID {$option_type_id})"); /* Fetch IDs of all sercices with selected option type */ $option_services = array(); $obj_sql_service = new sql_query(); $obj_sql_service->string = "SELECT id FROM services WHERE typeid='" . $option_type_id . "'"; $obj_sql_service->execute(); if ($obj_sql_service->num_rows()) { $obj_sql_service->fetch_array(); foreach ($obj_sql_service->data as $data) { $option_services[] = $data["id"]; } } unset($obj_sql_service); log_write("notification", "repair", "Returned ID of matching services, array of " . format_arraytocommastring($option_services, NULL) . ""); /* Start Transaction */ $obj_sql_trans = new sql_query(); $obj_sql_trans->trans_begin(); /* Fetch AR Invoices for selected period */ $obj_sql_ar = new sql_query(); $obj_sql_ar->string = "SELECT id, customerid, code_invoice, dest_account, amount_total, amount_paid FROM account_ar WHERE date_trans='{$option_date}'"; $obj_sql_ar->execute(); if ($obj_sql_ar->num_rows()) { $obj_sql_ar->fetch_array(); foreach ($obj_sql_ar->data as $data_ar) { $invoice_items = array(); // store item details /* Fetch Invoice Items */ $obj_sql_items = new sql_query(); $obj_sql_items->string = "SELECT id, customid, chartid, amount, description FROM account_items WHERE invoiceid='" . $data_ar["id"] . "' AND invoicetype='ar' AND type='service_usage'"; $obj_sql_items->execute(); if ($obj_sql_items->num_rows()) { $obj_sql_items->fetch_array(); /* For each item, check the service type and whether it is one of the items that we want to credit. */ foreach ($obj_sql_items->data as $data_item) { if (in_array($data_item["customid"], $option_services)) { // item is one of the target services, add details to array log_write("debug", "repair", "Invoice ID #" . $data_ar["id"] . ", (" . $data_ar["code_invoice"] . ") item ID #" . $data_item["id"] . " is a valid service usage item to refund."); // check if it's call charges if (!strpos($data_item["description"], "call charges")) { log_write("debug", "repair", "Skipping non-call charge usage item from credit"); continue; } // add invoice items $invoice_items_tmp = array(); $invoice_items_tmp["id"] = $data_item["id"]; $invoice_items_tmp["customid"] = $data_item["customid"]; $invoice_items_tmp["chartid"] = $data_item["chartid"]; $invoice_items_tmp["amount"] = $data_item["amount"]; $invoice_items_tmp["description"] = $data_item["description"]; // add to array $invoice_items[] = $invoice_items_tmp; } } } // end of AR invoice items loop /* If any items matched, we should create a credit note and add the items as credits */ if (!empty($invoice_items)) { /* Create Credit Note We have all the information needed for the credit note from the invoice. */ $credit = new credit(); $credit->type = "ar_credit"; $credit->prepare_set_defaults(); $credit->data["invoiceid"] = $data_ar["id"]; $credit->data["customerid"] = $data_ar["customerid"]; $credit->data["employeeid"] = "0"; $credit->data["date_trans"] = date("Y-m-d"); $credit->data["dest_account"] = $data_ar["dest_account"]; $credit->data["notes"] = "Automatically generated credit by repair process to cover service usage refund of invoice " . $data_ar["code_invoice"] . ""; // create a new credit if ($credit->action_create()) { log_write("notification", "repair", "Credit note successfully created"); journal_quickadd_event("account_ar_credit", $credit->id, "Credit Note successfully created"); } else { log_write("error", "repair", "An unexpected fault occured whilst attempting to create the credit note"); } /* Add Items We loop through each selected item and for each item, we create an appropiate credit note item. */ foreach ($invoice_items as $data_item) { // create credit item $item = new invoice_items(); $item->id_invoice = $credit->id; $item->type_invoice = "ar_credit"; $item->type_item = "credit"; // set item details $data = array(); $data["amount"] = $data_item["amount"]; $data["price"] = $data_item["amount"]; $data["chartid"] = $data_item["chartid"]; $data["description"] = "Credit For: " . $data_item["description"]; // fetch taxes for selected item $sql_tax_obj = new sql_query(); $sql_tax_obj->string = "SELECT taxid FROM services_taxes WHERE serviceid='" . $data_item["customid"] . "'"; $sql_tax_obj->execute(); if ($sql_tax_obj->num_rows()) { $sql_tax_obj->fetch_array(); foreach ($sql_tax_obj->data as $data_tax) { $sql_cust_tax_obj = new sql_query(); $sql_cust_tax_obj->string = "SELECT id FROM customers_taxes WHERE customerid='" . $credit->data["customerid"] . "' AND taxid='" . $data_tax["taxid"] . "'"; $sql_cust_tax_obj->execute(); if ($sql_cust_tax_obj->num_rows()) { $data["tax_" . $data_tax["taxid"]] = "on"; } } } unset($sql_tax_obj); if (!$item->prepare_data($data)) { log_write("error", "process", "An error was encountered whilst processing supplied data."); } else { $item->action_create(); $item->action_update(); } unset($data); } // end of items loop /* Re-calculate Credit Note Totals */ $item->action_update_tax(); $item->action_update_total(); $item->action_update_ledger(); // finsihed with credit items unset($item); /* Apply Credit Note against the invoice if it hasn't been paid in full. */ $amount_invoice = array(); if ($data_ar["amount_total"] != $data_ar["amount_paid"]) { // determine amount owing $amount_invoice["owing"] = $data_ar["amount_total"] - $data_ar["amount_paid"]; if ($amount_invoice["owing"] <= 0) { // nothing todo log_write("notification", "repair", "Ignoring overpaid invoice " . $data_ar["code_invoice"] . " and assigning credit note to customer account/pool instead"); } else { // determine credit amount $amount_invoice["credit"] = sql_get_singlevalue("SELECT amount_total as value FROM account_ar_credit WHERE id='" . $credit->id . "' LIMIT 1"); if ($amount_invoice["credit"] > $amount_invoice["owing"]) { // pay the amount owing which is less than the credit $amount_invoice["creditpay"] = $amount_invoice["owing"]; } else { // customer owes more than the credit is for, make credit payment amount maximum $amount_invoice["creditpay"] = $amount_invoice["credit"]; } // make credit payment against the invoice $item = new invoice_items(); $item->id_invoice = $data_ar["id"]; $item->type_invoice = "ar"; $item->type_item = "payment"; // set item details $data = array(); $data["date_trans"] = date("Y-m-d"); $data["amount"] = $amount_invoice["creditpay"]; $data["chartid"] = "credit"; $data["source"] = "CREDITED FUNDS (AUTOMATIC)"; $data["description"] = "Credit from credit note " . $credit->data["code_credit"] . " for service usage charge correction"; if (!$item->prepare_data($data)) { log_write("error", "process", "An error was encountered whilst processing supplied data for credit payment to invoice"); } else { // create & update payment item $item->action_create(); $item->action_update(); // update invoice totals & ledger $item->action_update_tax(); $item->action_update_total(); $item->action_update_ledger(); log_write("notification", "repair", "Applied credit of " . $amount_invoice["creditpay"] . ""); } unset($item); } // end if credit payment made } else { log_write("notification", "repair", "Credited invoice " . $data_ar["code_invoice"] . " has already been paid in full, assigning credit note to customer's credit pool for future use."); } /* Email PDF credit notes and message. */ if ($GLOBALS["config"]["ACCOUNTS_INVOICE_AUTOEMAIL"] == 1 || $GLOBALS["config"]["ACCOUNTS_INVOICE_AUTOEMAIL"] == "enabled") { $email = $credit->generate_email(); $credit->email_credit($email["sender"], $email["to"], $email["cc"], $email["bcc"], $email["subject"], $email["message"]); } else { log_write("notification", "repair", "No credit note email sent, ACCOUNTS_INVOICE_AUTOEMAIL is disabled."); } // unset the credit note unset($credit); /* Flag the refunded usage periods for re-billing. Now that we have refunded the usage on the selected invoice, we should then flag any service periods of the same service type and invoice ID, to cause the usge to be rebilled in the next service billing month. */ // fetch id_service_customer values from services where customer matches invoice $obj_sql_cust = new sql_query(); $obj_sql_cust->string = "SELECT id FROM services_customers WHERE customerid='" . $data_ar["customerid"] . "' AND serviceid IN (" . format_arraytocommastring($option_services, NULL) . ")"; $obj_sql_cust->execute(); if ($obj_sql_cust->num_rows()) { $obj_sql_cust->fetch_array(); foreach ($obj_sql_cust->data as $data_cust) { // update any periods for this customer-service which have the ID of the selected invoice as // the usage period invoice. // // these usage periods will then be re-invoiced at the next service invoicing run. // $obj_sql_period = new sql_query(); $obj_sql_period->string = "UPDATE services_customers_periods SET invoiceid_usage='0', rebill='1' WHERE invoiceid_usage='" . $data_ar["id"] . "' AND id_service_customer='" . $data_cust["id"] . "'"; $obj_sql_period->execute(); } log_write("notification", "repair", "Flagged services for customer " . $data_ar["customerid"] . " to bill for usage periods."); } else { log_write("warning", "repair", "No usage periods found to flag for rebilling for customer " . $data_ar["customerid"] . ", possibly the service has been deleted?"); } unset($obj_sql_cust); } // if creditable items exist on the selected invoice if (error_check()) { // there was an error, do not continue processing invoices. continue; } } } // end of AR invoice loop /* Close Transaction */ if (error_check()) { // rollback/failure log_write("error", "repair", "An error occured whilst executing, rolling back DB changes"); $obj_sql_trans->trans_rollback(); } else { // commit log_write("notification", "repair", "Successful execution, applying DB changes"); $obj_sql_trans->trans_commit(); } }
function execute() { /* Employee Selection Form */ $this->obj_form_employee = new form_input(); $this->obj_form_employee->formname = "timereg_employee"; $this->obj_form_employee->language = $_SESSION["user"]["lang"]; // employee selection box $sql_obj = new sql_query(); $sql_obj->prepare_sql_settable("staff"); $sql_obj->prepare_sql_addfield("id", "id"); $sql_obj->prepare_sql_addfield("label", "staff_code"); $sql_obj->prepare_sql_addfield("label1", "name_staff"); if ($this->access_staff_ids) { $sql_obj->prepare_sql_addwhere("id IN (" . format_arraytocommastring($this->access_staff_ids) . ")"); } $sql_obj->generate_sql(); $structure = form_helper_prepare_dropdownfromdb("employeeid", $sql_obj->string); // if there is currently no employee set, and there is only one // employee in the selection box, automatically select it and update // the session variables. if (!$this->employeeid && count($structure["values"]) == 1) { $this->employeeid = $structure["values"][0]; $_SESSION["form"]["timereg"]["employeeid"] = $structure["values"][0]; } $structure["options"]["autoselect"] = "on"; $structure["options"]["width"] = "600"; $structure["defaultvalue"] = $this->employeeid; $this->obj_form_employee->add_input($structure); // hidden values $structure = NULL; $structure["fieldname"] = "page"; $structure["type"] = "hidden"; $structure["defaultvalue"] = $_GET["page"]; $this->obj_form_employee->add_input($structure); $structure = NULL; $structure["fieldname"] = "date"; $structure["type"] = "hidden"; $structure["defaultvalue"] = $this->date; $this->obj_form_employee->add_input($structure); // submit button $structure = NULL; $structure["fieldname"] = "submit"; $structure["type"] = "submit"; $structure["defaultvalue"] = "Display"; $this->obj_form_employee->add_input($structure); if ($this->employeeid) { /* DRAW DAY TABLE We need to display a table showing all time booked for the currently selected day. */ // establish a new table object $this->obj_table_day = new table(); $this->obj_table_day->language = $_SESSION["user"]["lang"]; $this->obj_table_day->tablename = "timereg_table"; // define all the columns and structure $this->obj_table_day->add_column("standard", "name_project", "CONCAT_WS(' -- ', projects.code_project, projects.name_project)"); $this->obj_table_day->add_column("standard", "name_phase", "project_phases.name_phase"); $this->obj_table_day->add_column("hourmins", "time_booked", "timereg.time_booked"); $this->obj_table_day->add_column("standard", "description", "timereg.description"); // defaults $this->obj_table_day->columns = array("name_project", "name_phase", "description", "time_booked"); $this->obj_table_day->columns_order = array("name_project", "name_phase"); // create totals $this->obj_table_day->total_columns = array("time_booked"); // define SQL $this->obj_table_day->sql_obj->prepare_sql_settable("timereg"); $this->obj_table_day->sql_obj->prepare_sql_addfield("id", "timereg.id"); $this->obj_table_day->sql_obj->prepare_sql_addjoin("LEFT JOIN project_phases ON timereg.phaseid = project_phases.id"); $this->obj_table_day->sql_obj->prepare_sql_addjoin("LEFT JOIN projects ON project_phases.projectid = projects.id"); $this->obj_table_day->sql_obj->prepare_sql_addwhere("timereg.employeeid = '" . $this->employeeid . "'"); $this->obj_table_day->sql_obj->prepare_sql_addwhere("timereg.date = '" . $this->date . "'"); // execute SQL statement $this->obj_table_day->generate_sql(); $this->obj_table_day->load_data_sql(); } }
function execute() { /* Define form structure */ $this->obj_form = new form_input(); $this->obj_form->formname = "config_application"; $this->obj_form->language = $_SESSION["user"]["lang"]; $this->obj_form->action = "admin/config_application-process.php"; $this->obj_form->method = "post"; // default codes $structure = NULL; $structure["fieldname"] = "ACCOUNTS_AP_INVOICENUM"; $structure["type"] = "input"; $structure["options"]["no_translate_fieldname"] = "yes"; $this->obj_form->add_input($structure); $structure = NULL; $structure["fieldname"] = "ACCOUNTS_AR_INVOICENUM"; $structure["type"] = "input"; $structure["options"]["no_translate_fieldname"] = "yes"; $this->obj_form->add_input($structure); $structure = NULL; $structure["fieldname"] = "ACCOUNTS_GL_TRANSNUM"; $structure["type"] = "input"; $structure["options"]["no_translate_fieldname"] = "yes"; $this->obj_form->add_input($structure); $structure = NULL; $structure["fieldname"] = "ACCOUNTS_QUOTES_NUM"; $structure["type"] = "input"; $structure["options"]["no_translate_fieldname"] = "yes"; $this->obj_form->add_input($structure); $structure = NULL; $structure["fieldname"] = "ACCOUNTS_CREDIT_NUM"; $structure["type"] = "input"; $structure["options"]["no_translate_fieldname"] = "yes"; $this->obj_form->add_input($structure); $structure = NULL; $structure["fieldname"] = "CODE_ACCOUNT"; $structure["type"] = "input"; $structure["options"]["no_translate_fieldname"] = "yes"; $this->obj_form->add_input($structure); $structure = NULL; $structure["fieldname"] = "CODE_CUSTOMER"; $structure["type"] = "input"; $structure["options"]["no_translate_fieldname"] = "yes"; $this->obj_form->add_input($structure); $structure = NULL; $structure["fieldname"] = "CODE_PRODUCT"; $structure["type"] = "input"; $structure["options"]["no_translate_fieldname"] = "yes"; $this->obj_form->add_input($structure); $structure = NULL; $structure["fieldname"] = "CODE_PROJECT"; $structure["type"] = "input"; $structure["options"]["no_translate_fieldname"] = "yes"; $this->obj_form->add_input($structure); $structure = NULL; $structure["fieldname"] = "CODE_VENDOR"; $structure["type"] = "input"; $structure["options"]["no_translate_fieldname"] = "yes"; $this->obj_form->add_input($structure); $structure = NULL; $structure["fieldname"] = "CODE_STAFF"; $structure["type"] = "input"; $structure["options"]["no_translate_fieldname"] = "yes"; $this->obj_form->add_input($structure); // invoicing options $structure = NULL; $structure["fieldname"] = "ACCOUNTS_SERVICES_ADVANCEBILLING"; $structure["type"] = "input"; $structure["options"]["no_translate_fieldname"] = "yes"; $structure["options"]["width"] = "50"; $structure["options"]["label"] = " days"; $this->obj_form->add_input($structure); $structure = NULL; $structure["fieldname"] = "ACCOUNTS_SERVICES_DATESHIFT"; $structure["type"] = "input"; $structure["options"]["no_translate_fieldname"] = "yes"; $structure["options"]["width"] = "50"; $structure["options"]["label"] = " " . lang_trans("help_accounts_services_dateshift"); $this->obj_form->add_input($structure); $structure = NULL; $structure["fieldname"] = "ACCOUNTS_TERMS_DAYS"; $structure["type"] = "input"; $structure["options"]["no_translate_fieldname"] = "yes"; $this->obj_form->add_input($structure); $structure = NULL; $structure["fieldname"] = "ACCOUNTS_AUTOPAY"; $structure["type"] = "checkbox"; $structure["options"]["no_translate_fieldname"] = "yes"; $structure["options"]["label"] = " Check to have invoices automatically paid where there is credit or reoccuring billing details."; $this->obj_form->add_input($structure); // email options $structure = NULL; $structure["fieldname"] = "ACCOUNTS_EMAIL_ADDRESS"; $structure["type"] = "input"; $structure["options"]["label"] = " Internal email address to send billing system related emails to."; $structure["options"]["no_translate_fieldname"] = "yes"; $this->obj_form->add_input($structure); $structure = NULL; $structure["fieldname"] = "ACCOUNTS_INVOICE_AUTOEMAIL"; $structure["type"] = "checkbox"; $structure["options"]["label"] = "Tick to have service and order invoices automatically emailed to customers when created, from address will be COMPANY_EMAIL_ADDRESS"; $structure["options"]["no_translate_fieldname"] = "yes"; $this->obj_form->add_input($structure); $structure = NULL; $structure["fieldname"] = "ACCOUNTS_INVOICE_BATCHREPORT"; $structure["type"] = "checkbox"; $structure["options"]["label"] = "Tick to have an invoice batch report sent to ACCOUNTS_EMAIL_ADDRESS when invoices are automatically generated."; $structure["options"]["no_translate_fieldname"] = "yes"; $this->obj_form->add_input($structure); $structure = NULL; $structure["fieldname"] = "ACCOUNTS_EMAIL_AUTOBCC"; $structure["type"] = "checkbox"; $structure["options"]["label"] = "Always BCC outgoing invoice emails to ACCOUNTS_EMAIL_ADDRESS"; $structure["options"]["no_translate_fieldname"] = "yes"; $this->obj_form->add_input($structure); // service email options $structure = NULL; $structure["fieldname"] = "SERVICES_USAGEALERTS_ENABLE"; $structure["type"] = "checkbox"; $structure["options"]["label"] = "Tick to have service usage alerts delivered to customers (where customers/services are enabled for it)."; $structure["options"]["no_translate_fieldname"] = "yes"; $this->obj_form->add_input($structure); // orders options $structure = NULL; $structure["fieldname"] = "ORDERS_BILL_ONSERVICE"; $structure["type"] = "checkbox"; $structure["options"]["label"] = "Automatically bill customer orders when the next service bill is generated."; $structure["options"]["no_translate_fieldname"] = "yes"; $this->obj_form->add_input($structure); $structure = NULL; $structure["fieldname"] = "ORDERS_BILL_ENDOFMONTH"; $structure["type"] = "checkbox"; $structure["options"]["label"] = "Automatically bill customer orders at the end of the calender month."; $structure["options"]["no_translate_fieldname"] = "yes"; $this->obj_form->add_input($structure); // timesheet options $structure = NULL; $structure["fieldname"] = "TIMESHEET_BOOKTOFUTURE"; $structure["type"] = "checkbox"; $structure["options"]["label"] = "Allow users to book time to dates in the future"; $structure["options"]["no_translate_fieldname"] = "yes"; $this->obj_form->add_input($structure); // audit locking $structure = NULL; $structure["fieldname"] = "ACCOUNTS_INVOICE_LOCK"; $structure["type"] = "input"; $structure["options"]["no_translate_fieldname"] = "yes"; $this->obj_form->add_input($structure); $structure = NULL; $structure["fieldname"] = "ACCOUNTS_GL_LOCK"; $structure["type"] = "input"; $structure["options"]["no_translate_fieldname"] = "yes"; $this->obj_form->add_input($structure); $structure = NULL; $structure["fieldname"] = "JOURNAL_LOCK"; $structure["type"] = "input"; $structure["options"]["no_translate_fieldname"] = "yes"; $this->obj_form->add_input($structure); $structure = NULL; $structure["fieldname"] = "TIMESHEET_LOCK"; $structure["type"] = "input"; $structure["options"]["no_translate_fieldname"] = "yes"; $this->obj_form->add_input($structure); // misc $structure = NULL; $structure["fieldname"] = "UPLOAD_MAXBYTES"; $structure["type"] = "input"; $structure["options"]["no_translate_fieldname"] = "yes"; $structure["options"]["label"] = " Bytes. Server maximum is " . ini_get('upload_max_filesize') . ", to increase server limit, you must edit php.ini"; $this->obj_form->add_input($structure); $structure = NULL; $structure["fieldname"] = "API_URL"; $structure["type"] = "input"; $structure["options"]["no_translate_fieldname"] = "yes"; $structure["options"]["label"] = " This URL will be used in namespace and soap address URLS in the WSDL files."; $this->obj_form->add_input($structure); // amberstats phone home $structure = NULL; $structure["fieldname"] = "PHONE_HOME"; $structure["type"] = "checkbox"; $structure["options"]["label"] = "Report back to the developers with application, OS, PHP version and a random unique ID so we can better improve this software. (all information is anonymous, private and greatly appreciated. We use this information to focus development and packaging on the main platforms our users are running to better meet your needs."; $structure["options"]["no_translate_fieldname"] = "yes"; $this->obj_form->add_input($structure); $phone_home_info = new phone_home(); $phone_home_info->stats_generate(); $structure = NULL; $structure["fieldname"] = "PHONE_HOME_EXAMPLE"; $structure["type"] = "text"; $structure["defaultvalue"] = "<i>Actual information to be sent: " . format_arraytocommastring(array_values($phone_home_info->stats)) . "</i>"; $structure["options"]["no_fieldname"] = "yes"; $structure["options"]["no_shift"] = "yes"; $this->obj_form->add_input($structure); // security options $structure = NULL; $structure["fieldname"] = "SESSION_TIMEOUT"; $structure["type"] = "input"; $structure["options"]["label"] = " seconds idle before logging user out"; $structure["options"]["no_translate_fieldname"] = "yes"; $structure["defaultvalue"] = "7200"; $this->obj_form->add_input($structure); $structure = NULL; $structure["fieldname"] = "BLACKLIST_ENABLE"; $structure["type"] = "checkbox"; $structure["options"]["label"] = "Enable to prevent brute-force login attempts"; $structure["options"]["no_translate_fieldname"] = "yes"; $this->obj_form->add_input($structure); $structure = NULL; $structure["fieldname"] = "BLACKLIST_LIMIT"; $structure["type"] = "input"; $structure["options"]["no_translate_fieldname"] = "yes"; $this->obj_form->add_input($structure); // dangerous options if ($GLOBALS["config"]["dangerous_conf_options"] == "enabled") { $structure = NULL; $structure["fieldname"] = "EMAIL_ENABLE"; $structure["type"] = "checkbox"; $structure["options"]["label"] = "Enable or disable the ability to send emails. If you don't trust users not to try using the system to spam people (eg: if this is a demo system) then it is highly recommended to disable this option."; $structure["options"]["no_translate_fieldname"] = "yes"; $this->obj_form->add_input($structure); $structure = NULL; $structure["fieldname"] = "DATA_STORAGE_METHOD"; $structure["type"] = "radio"; $structure["values"] = array("database", "filesystem"); $structure["options"]["no_translate_fieldname"] = "yes"; $this->obj_form->add_input($structure); $structure = NULL; $structure["fieldname"] = "DATA_STORAGE_LOCATION"; $structure["type"] = "input"; $structure["options"]["no_translate_fieldname"] = "yes"; $this->obj_form->add_input($structure); $structure = NULL; $structure["fieldname"] = "PATH_TMPDIR"; $structure["type"] = "input"; $structure["options"]["no_translate_fieldname"] = "yes"; $this->obj_form->add_input($structure); $structure = NULL; $structure["fieldname"] = "APP_PDFLATEX"; $structure["type"] = "input"; $structure["options"]["no_translate_fieldname"] = "yes"; $this->obj_form->add_input($structure); $structure = NULL; $structure["fieldname"] = "APP_WKHTMLTOPDF"; $structure["type"] = "input"; $structure["options"]["no_translate_fieldname"] = "yes"; $this->obj_form->add_input($structure); $structure = NULL; $structure["fieldname"] = "APP_MYSQL_DUMP"; $structure["type"] = "input"; $structure["options"]["no_translate_fieldname"] = "yes"; $this->obj_form->add_input($structure); } // submit section $structure = NULL; $structure["fieldname"] = "submit"; $structure["type"] = "submit"; $structure["defaultvalue"] = "Save Changes"; $this->obj_form->add_input($structure); // define subforms $this->obj_form->subforms["config_defcodes"] = array("ACCOUNTS_AP_INVOICENUM", "ACCOUNTS_AR_INVOICENUM", "ACCOUNTS_GL_TRANSNUM", "ACCOUNTS_QUOTES_NUM", "ACCOUNTS_CREDIT_NUM", "CODE_ACCOUNT", "CODE_CUSTOMER", "CODE_VENDOR", "CODE_PRODUCT", "CODE_PROJECT", "CODE_STAFF"); $this->obj_form->subforms["config_accounts"] = array("ACCOUNTS_SERVICES_ADVANCEBILLING", "ACCOUNTS_SERVICES_DATESHIFT", "ACCOUNTS_TERMS_DAYS", "ACCOUNTS_AUTOPAY"); $this->obj_form->subforms["config_accounts_email"] = array("ACCOUNTS_EMAIL_ADDRESS", "ACCOUNTS_INVOICE_AUTOEMAIL", "ACCOUNTS_EMAIL_AUTOBCC", "ACCOUNTS_INVOICE_BATCHREPORT"); $this->obj_form->subforms["config_services_email"] = array("SERVICES_USAGEALERTS_ENABLE"); $this->obj_form->subforms["config_orders"] = array("ORDERS_BILL_ONSERVICE", "ORDERS_BILL_ENDOFMONTH"); $this->obj_form->subforms["config_timesheet"] = array("TIMESHEET_BOOKTOFUTURE"); $this->obj_form->subforms["config_auditlocking"] = array("ACCOUNTS_INVOICE_LOCK", "ACCOUNTS_GL_LOCK", "JOURNAL_LOCK", "TIMESHEET_LOCK"); $this->obj_form->subforms["config_contributions"] = array("PHONE_HOME", "PHONE_HOME_EXAMPLE"); $this->obj_form->subforms["config_security"] = array("SESSION_TIMEOUT", "BLACKLIST_ENABLE", "BLACKLIST_LIMIT"); $this->obj_form->subforms["config_misc"] = array("UPLOAD_MAXBYTES", "API_URL"); if ($GLOBALS["config"]["dangerous_conf_options"] == "enabled") { $this->obj_form->subforms["config_dangerous"] = array("PATH_TMPDIR", "APP_PDFLATEX", "APP_WKHTMLTOPDF", "APP_MYSQL_DUMP", "EMAIL_ENABLE", "DATA_STORAGE_LOCATION", "DATA_STORAGE_METHOD"); } $this->obj_form->subforms["submit"] = array("submit"); if (error_check()) { // load error datas $this->obj_form->load_data_error(); } else { // fetch all the values from the database $sql_config_obj = new sql_query(); $sql_config_obj->string = "SELECT name, value FROM config ORDER BY name"; $sql_config_obj->execute(); $sql_config_obj->fetch_array(); foreach ($sql_config_obj->data as $data_config) { $this->obj_form->structure[$data_config["name"]]["defaultvalue"] = $data_config["value"]; } unset($sql_config_obj); } }