From: Janusz Dobrowolski Date: Thu, 22 Oct 2009 10:34:22 +0000 (+0000) Subject: Added generic tags support; tags for dimensions/gl accounts. X-Git-Tag: v2.4.2~19^2~1104 X-Git-Url: https://delta.frontaccounting.com/gitweb/?a=commitdiff_plain;h=c67cb853142909aaa6dd27681a9bd5b62f1f7526;p=fa-stable.git Added generic tags support; tags for dimensions/gl accounts. --- diff --git a/admin/db/tags_db.inc b/admin/db/tags_db.inc new file mode 100644 index 00000000..2a72fd83 --- /dev/null +++ b/admin/db/tags_db.inc @@ -0,0 +1,184 @@ +. +***********************************************************************/ + +function add_tag($type, $name, $description) +{ + $sql = "INSERT INTO ".TB_PREF."tags (type, name, description) + VALUES (".db_escape($type).", ".db_escape($name).", ".db_escape($description).")"; + + return db_query($sql); +} + +//-------------------------------------------------------------------------------------- + +function update_tag($id, $name, $description, $type=null) +{ + $sql = "UPDATE ".TB_PREF."tags SET name=".db_escape($name).", + description=".db_escape($description); + if ($type != null) + $sql .= ", type=".db_escape($type); + + $sql .= " WHERE id = ".db_escape($id); + + return db_query($sql); +} + +//-------------------------------------------------------------------------------------- + +function get_tags($type, $all=false) +{ + $sql = "SELECT * FROM ".TB_PREF."tags WHERE type=".db_escape($type); + + if (!$all) $sql .= " AND !inactive"; + + $sql .= " ORDER BY name"; + + return db_query($sql, "could not get tags"); +} + +//-------------------------------------------------------------------------------------- + +function get_tag($id) +{ + $sql = "SELECT * FROM ".TB_PREF."tags WHERE id = ".db_escape($id); + + $result = db_query($sql, "could not get tag"); + + return db_fetch($result); +} + +//-------------------------------------------------------------------------------------- + +function get_tag_type($id) +{ + $sql = "SELECT type FROM ".TB_PREF."tags WHERE id = ".db_escape($id); + + $result = db_query($sql, "could not get tag type"); + + $row = db_fetch_row($result); + return $row[0]; +} + +//-------------------------------------------------------------------------------------- + +function get_tag_name($id) +{ + $sql = "SELECT name FROM ".TB_PREF."tags WHERE id = ".db_escape($id); + + $result = db_query($sql, "could not get tag name"); + + $row = db_fetch_row($result); + return $row[0]; +} + +//-------------------------------------------------------------------------------------- + +function get_tag_description($id) +{ + $sql = "SELECT description FROM ".TB_PREF."tags WHERE id = ".db_escape($id); + + $result = db_query($sql, "could not get tag description"); + + $row = db_fetch_row($result); + return $row[0]; +} + +//-------------------------------------------------------------------------------------- + +function delete_tag($id) +{ + $sql = "DELETE FROM ".TB_PREF."tags WHERE id = ".db_escape($id); + + db_query($sql, "could not delete tag"); +} + +//-------------------------------------------------------------------------------------- + +function add_tag_associations($recordid, $tagids) +{ + _vd($tagids); + foreach($tagids as $tagid) { + if (!$tagid) continue; + $sql = "INSERT INTO ".TB_PREF."tag_associations (record_id, tag_id) + VALUES (".db_escape($recordid).", ".db_escape($tagid).")"; + + db_query($sql, "could not add tag association"); + } +} + +//-------------------------------------------------------------------------------------- + +function update_tag_associations($type, $recordid, $tagids) +{ + // Delete the old associations + delete_tag_associations($type, $recordid, false); + // Add the new associations + add_tag_associations($recordid, $tagids); +} + +//-------------------------------------------------------------------------------------- + +// To delete tag associations, we need to specify the tag type. +// Otherwise we may inadvertantly delete records for another type of tag +function delete_tag_associations($type, $recordid, $all=false) +{ + $sql = "DELETE ta FROM ".TB_PREF."tag_associations AS ta + INNER JOIN ".TB_PREF."tags AS tags ON tags.id = ta.tag_id + WHERE tags.type = ".db_escape($type)." AND ta.record_id = ".db_escape($recordid); + + if (!$all) + $sql .= " AND tags.inactive = 0"; + + db_query($sql, "could not delete tag associations"); +} + +//-------------------------------------------------------------------------------------- + +function get_records_associated_with_tag($id) +{ + // Which table we query is based on the tag type + $type = get_tag_type($id); + + $table = $key = ''; + switch ($type) { + case TAG_ACCOUNT: + $table = TB_PREF."chart_master"; + $key = "account_code"; + break; + case TAG_DIMENSION: + $table = TB_PREF."dimensions"; + $key = "id"; + break; + } + + $sql = "SELECT $table.* FROM $table + INNER JOIN ".TB_PREF."tag_associations AS ta ON ta.record_id = $table.$key + INNER JOIN ".TB_PREF."tags AS tags ON ta.tag_id = tags.id + WHERE tags.id = ".db_escape($id); + + return db_query($sql, "could not get tag associations for tag"); +} + +//-------------------------------------------------------------------------------------- + +function get_tags_associated_with_record($type, $recordid) +{ + $sql = "SELECT tags.* FROM ".TB_PREF."tag_associations AS ta + INNER JOIN ".TB_PREF."tags AS tags ON tags.id = ta.tag_id + WHERE tags.type = $type AND ta.record_id = ".db_escape($recordid); + + return db_query($sql, "could not get tags associations for record"); +} + +//-------------------------------------------------------------------------------------- + +?> \ No newline at end of file diff --git a/admin/tags.php b/admin/tags.php new file mode 100644 index 00000000..9bb6c6d4 --- /dev/null +++ b/admin/tags.php @@ -0,0 +1,188 @@ +. +***********************************************************************/ +$path_to_root = ".."; +include_once($path_to_root . "/includes/types.inc"); // For tag constants + +// Set up page security based on what type of tags we're working with +if ($_GET['type'] == "account" || $_POST['type'] == TAG_ACCOUNT) { + $page_security = 'SA_GLACCOUNTTAGS'; +} else if($_GET['type'] == "dimension" || $_POST['type'] == TAG_DIMENSION) { + $page_security = 'SA_DIMTAGS'; +} + +include($path_to_root . "/includes/session.inc"); // Define session before using $_SESSION + +if (!isset($page_security)) { + // If GET & POST don't have the info, try getting it from the session. + $page_security = $_SESSION['tags_page_security']; +} +$_SESSION['tags_page_security'] = $page_security; + +// We use $_POST['type'] throughout this script, so convert $_GET vars +// if $_POST['type'] is not set. +if (!isset($_POST['type'])) { + if ($_GET['type'] == "account") + $_POST['type'] = TAG_ACCOUNT; + elseif ($_GET['type'] == "dimension") + $_POST['type'] = TAG_DIMENSION; + else + die(_("Unspecified tag type")); +} + +// Set up page based on what type of tags we're working with +// TODO: Set $_SESSION['sel_app'] to be relevant app (see /includes/page/header.inc::page_header() +switch ($_POST['type']) { + case TAG_ACCOUNT: + // Account tags + $_SESSION['page_title'] = _("Account Tags"); + break; + case TAG_DIMENSION: + // Dimension tags + $_SESSION['page_title'] = _("Dimension Tags"); +} + +page($_SESSION['page_title']); +include_once($path_to_root . "/admin/db/tags_db.inc"); + +include($path_to_root . "/includes/ui.inc"); + +simple_page_mode(true); + +//----------------------------------------------------------------------------------- + +function can_process() +{ + if (strlen($_POST['name']) == 0) + { + display_error( _("The tag name cannot be empty.")); + set_focus('name'); + return false; + } + return true; +} + +//----------------------------------------------------------------------------------- + +if ($Mode=='ADD_ITEM' || $Mode=='UPDATE_ITEM') +{ + if (can_process()) + { + if ($selected_id != -1) + { + if( $ret = update_tag($selected_id, $_POST['name'], $_POST['description'])) + display_notification(_('Selected tag settings have been updated')); + } + else + { + if( $ret = add_tag($_POST['type'], $_POST['name'], $_POST['description'])) + display_notification(_('New tag has been added')); + } + if ($ret) $Mode = 'RESET'; + } +} + +//----------------------------------------------------------------------------------- + +function can_delete($selected_id) +{ + if ($selected_id == -1) + return false; + $result = get_records_associated_with_tag($selected_id); + + if (db_num_rows($result) > 0) + { + display_error(_("Cannot delete this tag because records have been created referring to it.")); + return false; + } + + return true; +} + + +//----------------------------------------------------------------------------------- + +if ($Mode == 'Delete') +{ + if (can_delete($selected_id)) + { + delete_tag($selected_id); + display_notification(_('Selected tag has been deleted')); + } + $Mode = 'RESET'; +} + +//----------------------------------------------------------------------------------- + +if ($Mode == 'RESET') +{ + $selected_id = -1; + $_POST['name'] = $_POST['description'] = ''; +} + +//----------------------------------------------------------------------------------- + +$result = get_tags($_POST['type'], check_value('show_inactive')); + +start_form(); +start_table($table_style); +$th = array(_("Tag Name"), _("Tag Description"), "", ""); +inactive_control_column($th); +table_header($th); + +$k = 0; +while ($myrow = db_fetch($result)) +{ + alt_table_row_color($k); + + label_cell($myrow['name']); + label_cell($myrow['description']); + inactive_control_cell($myrow["id"], $myrow["inactive"], 'tags', 'id'); + edit_button_cell("Edit".$myrow["id"], _("Edit")); + delete_button_cell("Delete".$myrow["id"], _("Delete")); + end_row(); +} + +inactive_control_row($th); +end_table(1); + +//----------------------------------------------------------------------------------- + +start_table($table_style2); + +if ($selected_id != -1) // We've selected a tag +{ + if ($Mode == 'Edit') { + // Editing an existing tag + $myrow = get_tag($selected_id); + + $_POST['name'] = $myrow["name"]; + $_POST['description'] = $myrow["description"]; + } + // Note the selected tag + hidden('selected_id', $selected_id); +} + +text_row_ex(_("Tag Name:"), 'name', 15, 30); +text_row_ex(_("Tag Description:"), 'description', 40, 60); +hidden('type'); + +end_table(1); + +submit_add_or_update_center($selected_id == -1, '', 'both'); + +end_form(); + +//------------------------------------------------------------------------------------ + +end_page(); + +?> diff --git a/applications/dimensions.php b/applications/dimensions.php index 3a1cca71..39ab0a36 100644 --- a/applications/dimensions.php +++ b/applications/dimensions.php @@ -31,15 +31,17 @@ class dimensions_app extends application $this->add_rapp_function(1, _("Dimension &Reports"), "reporting/reports_main.php?Class=4", 'SA_DIMENSIONREP'); + + $this->add_module(_("Maintenance")); + $this->add_lapp_function(2, _("Dimension &Tags"), + "admin/tags.php?type=dimension", 'SA_DIMTAGS'); + if (count($installed_extensions) > 0) { - $i = 0; foreach ($installed_extensions as $mod) { if (@$mod['active'] && $mod['type'] == 'plugin' && $mod["tab"] == "proj") { - if ($i++ == 0) - $this->add_module(_("Maintenance")); $this->add_rapp_function(2, $mod["title"], "modules/".$mod["path"]."/".$mod["filename"]."?", isset($mod["access"]) ? $mod["access"] : 'SA_OPEN' ); diff --git a/applications/generalledger.php b/applications/generalledger.php index 062eef68..5a8a7612 100644 --- a/applications/generalledger.php +++ b/applications/generalledger.php @@ -52,6 +52,8 @@ class general_ledger_app extends application "gl/manage/bank_accounts.php?", 'SA_BANKACCOUNT'); $this->add_lapp_function(2, _("&Quick Entries"), "gl/manage/gl_quick_entries.php?", 'SA_QUICKENTRY'); + $this->add_lapp_function(2, _("Account &Tags"), + "admin/tags.php?type=account", 'SA_GLACCOUNTTAGS'); $this->add_lapp_function(2, "",""); $this->add_lapp_function(2, _("&Currencies"), "gl/manage/currencies.php?", 'SA_CURRENCY'); diff --git a/dimensions/dimension_entry.php b/dimensions/dimension_entry.php index 7b9bcb37..626d8466 100644 --- a/dimensions/dimension_entry.php +++ b/dimensions/dimension_entry.php @@ -17,6 +17,7 @@ include_once($path_to_root . "/includes/date_functions.inc"); include_once($path_to_root . "/includes/manufacturing.inc"); include_once($path_to_root . "/includes/data_checks.inc"); +include_once($path_to_root . "/admin/db/tags_db.inc"); include_once($path_to_root . "/dimensions/includes/dimensions_db.inc"); include_once($path_to_root . "/dimensions/includes/dimensions_ui.inc"); @@ -161,6 +162,7 @@ if (isset($_POST['ADD_ITEM']) || isset($_POST['UPDATE_ITEM'])) { $id = add_dimension($_POST['ref'], $_POST['name'], $_POST['type_'], $_POST['date_'], $_POST['due_date'], $_POST['memo_']); + add_tag_associations($id, $_POST['dimension_tags']); meta_forward($_SERVER['PHP_SELF'], "AddedID=$id"); } @@ -168,6 +170,7 @@ if (isset($_POST['ADD_ITEM']) || isset($_POST['UPDATE_ITEM'])) { update_dimension($selected_id, $_POST['name'], $_POST['type_'], $_POST['date_'], $_POST['due_date'], $_POST['memo_']); + update_tag_associations(TAG_DIMENSION, $selected_id, $_POST['dimension_tags']); meta_forward($_SERVER['PHP_SELF'], "UpdatedID=$selected_id"); } @@ -194,6 +197,7 @@ if (isset($_POST['delete'])) // delete delete_dimension($selected_id); + delete_tag_associations(TAG_DIMENSION,$selected_id, true); meta_forward($_SERVER['PHP_SELF'], "DeletedID=$selected_id"); } } @@ -245,6 +249,12 @@ if ($selected_id != -1) $_POST['date_'] = sql2date($myrow["date_"]); $_POST['due_date'] = sql2date($myrow["due_date"]); $_POST['memo_'] = get_comments_string(ST_DIMENSION, $selected_id); + + $tags_result = get_tags_associated_with_record(TAG_DIMENSION, $selected_id); + $tagids = array(); + while ($tag = db_fetch($tags_result)) + $tagids[] = $tag['id']; + $_POST['dimension_tags'] = $tagids; hidden('ref', $_POST['ref']); @@ -254,6 +264,7 @@ if ($selected_id != -1) } else { + $_POST['dimension_tags'] = array(); ref_row(_("Dimension Reference:"), 'ref', '', $Refs->get_next(ST_DIMENSION)); } @@ -267,6 +278,8 @@ date_row(_("Start Date") . ":", 'date_'); date_row(_("Date Required By") . ":", 'due_date', '', null, $SysPrefs->default_dimension_required_by()); +tag_list_row(_("Tags:"), 'dimension_tags', 5, TAG_DIMENSION, true); + textarea_row(_("Memo:"), 'memo_', null, 40, 5); end_table(1); @@ -277,7 +290,7 @@ if (isset($_POST['closed']) && $_POST['closed'] == 1) if ($selected_id != -1) { echo "
"; - submit_center_first('UPDATE_ITEM', _("Update"), _('Save changes to dimension'), 'default'); + submit_center_first('UPDATE_ITEM', _("Update"), _('Save changes to dimension'), false); if ($_POST['closed'] == 1) submit('reopen', _("Re-open This Dimension"), true, _('Mark this dimension as re-opened'), true); else @@ -286,7 +299,7 @@ if ($selected_id != -1) } else { - submit_center('ADD_ITEM', _("Add"), true, '', 'default'); + submit_center('ADD_ITEM', _("Add"), true, '', false); } end_form(); diff --git a/gl/manage/gl_accounts.php b/gl/manage/gl_accounts.php index 718be9bd..02a78bc7 100644 --- a/gl/manage/gl_accounts.php +++ b/gl/manage/gl_accounts.php @@ -17,6 +17,7 @@ page(_("Chart of Accounts")); include($path_to_root . "/includes/ui.inc"); include($path_to_root . "/gl/includes/gl_db.inc"); +include($path_to_root . "/admin/db/tags_db.inc"); include_once($path_to_root . "/includes/data_checks.inc"); check_db_has_gl_account_groups(_("There are no account groups defined. Please define at least one account group before entering accounts.")); @@ -39,7 +40,6 @@ elseif (isset($_GET['selected_account'])) } else $selected_account = ""; - //------------------------------------------------------------------------------------- if (isset($_POST['add']) || isset($_POST['update'])) @@ -70,12 +70,15 @@ if (isset($_POST['add']) || isset($_POST['update'])) { if ($accounts_alpha == 2) $_POST['account_code'] = strtoupper($_POST['account_code']); + if ($selected_account) { if (update_gl_account($_POST['account_code'], $_POST['account_name'], $_POST['account_type'], $_POST['account_code2'])) { update_record_status($_POST['account_code'], $_POST['inactive'], 'chart_master', 'account_code'); + update_tag_associations(TAG_ACCOUNT, $_POST['account_code'], + $_POST['account_tags']); $Ajax->activate('account_code'); // in case of status change display_notification(_("Account data has been updated.")); } @@ -85,6 +88,7 @@ if (isset($_POST['add']) || isset($_POST['update'])) if (add_gl_account($_POST['account_code'], $_POST['account_name'], $_POST['account_type'], $_POST['account_code2'])) { + add_tag_associations($_POST['account_code'], $_POST['account_tags']); display_notification(_("New account has been added.")); $selected_account = $_POST['AccountList'] = $_POST['account_code']; } @@ -214,6 +218,8 @@ if (isset($_POST['delete'])) { delete_gl_account($selected_account); $selected_account = $_POST['AccountList'] = ''; + delete_tag_associations(TAG_ACCOUNT,$selected_account, true); + $selected_account = $_POST['AccountList'] = ''; display_notification(_("Selected account has been deleted")); unset($_POST['account_code']); $Ajax->activate('_page_body'); @@ -252,6 +258,12 @@ if ($selected_account != "") $_POST['account_name'] = $myrow["account_name"]; $_POST['account_type'] = $myrow["account_type"]; $_POST['inactive'] = $myrow["inactive"]; + + $tags_result = get_tags_associated_with_record(TAG_ACCOUNT, $selected_account); + $tagids = array(); + while ($tag = db_fetch($tags_result)) + $tagids[] = $tag['id']; + $_POST['account_tags'] = $tagids; hidden('account_code', $_POST['account_code']); hidden('selected_account', $selected_account); @@ -261,6 +273,7 @@ if ($selected_account != "") else { if (!isset($_POST['account_code'])) { + $_POST['account_tags'] = array(); $_POST['account_code'] = $_POST['account_code2'] = ''; $_POST['account_name'] = $_POST['account_type'] = ''; $_POST['inactive'] = 0; @@ -274,16 +287,18 @@ text_row_ex(_("Account Name:"), 'account_name', 60); gl_account_types_list_row(_("Account Group:"), 'account_type', null); +tag_list_row(_("Account Tags:"), 'account_tags', 5, TAG_ACCOUNT, true); + record_status_list_row(_("Account status:"), 'inactive'); end_table(1); if ($selected_account == "") { - submit_center('add', _("Add Account"), true, '', 'default'); + submit_center('add', _("Add Account"), true, '', false); } else { - submit_center_first('update', _("Update Account"), '', 'default'); + submit_center_first('update', _("Update Account"), '', false); submit_center_last('delete', _("Delete account"), '',true); } end_form(); diff --git a/includes/data_checks.inc b/includes/data_checks.inc index 8e03d584..295a353e 100644 --- a/includes/data_checks.inc +++ b/includes/data_checks.inc @@ -428,6 +428,22 @@ function db_has_quick_entries() return check_empty_result("SELECT COUNT(*) FROM ".TB_PREF."quick_entries"); } +function db_has_tags($type) +{ + return check_empty_result("SELECT COUNT(*) FROM ".TB_PREF."tags WHERE type=$type"); +} + +function check_db_has_tags($type, $msg) +{ + global $path_to_root; + if (!db_has_tags($type)) + { + display_error($msg, true); + end_page(); + exit; + } +} + function check_empty_result($sql) { $result = db_query($sql, "could not do check empty query");