From dae63a256124376c8379a7d366d6ab885be22ac6 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 29 May 2019 16:24:00 +0000 Subject: [PATCH 001/877] Fixed sorting of projects in dropdown on the reports.php page. --- WEB-INF/lib/ttProjectHelper.class.php | 6 +++--- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/WEB-INF/lib/ttProjectHelper.class.php b/WEB-INF/lib/ttProjectHelper.class.php index 22ef58a23..399cba2d2 100644 --- a/WEB-INF/lib/ttProjectHelper.class.php +++ b/WEB-INF/lib/ttProjectHelper.class.php @@ -45,7 +45,7 @@ static function getAssignedProjects($user_id) { // Do a query with inner join to get assigned projects. $sql = "select p.id, p.name, p.tasks, upb.rate from tt_projects p". " inner join tt_user_project_binds upb on (upb.user_id = $user_id and upb.project_id = p.id and upb.status = 1)". - " where p.group_id = $group_id and p.org_id = $org_id and p.status = 1 order by p.name"; + " where p.group_id = $group_id and p.org_id = $org_id and p.status = 1 order by upper(p.name)"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { while ($val = $res->fetchRow()) { @@ -87,7 +87,7 @@ static function getProjects() { $result = array(); $sql = "select id, name, tasks from tt_projects". - " where group_id = $group_id and org_id = $org_id and (status = 0 or status = 1) order by name"; + " where group_id = $group_id and org_id = $org_id and (status = 0 or status = 1) order by upper(name)"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { while ($val = $res->fetchRow()) { @@ -109,7 +109,7 @@ static function getProjectsForClient() { $sql = "select p.id, p.name, p.tasks from tt_projects p". " inner join tt_client_project_binds cpb on (cpb.client_id = $user->client_id and cpb.project_id = p.id)". " where p.group_id = $group_id and p.org_id = $org_id and (p.status = 0 or p.status = 1)". - " order by p.name"; + " order by upper(p.name)"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 49305b5ce..4c7e5cad9 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.19.4.5012 | Copyright © Anuko | +  Anuko Time Tracker 1.19.4.5013 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From ddbe45e8a1120c0a80032a0021613b9d1d9f3116 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 24 Jun 2019 13:38:52 +0000 Subject: [PATCH 002/877] Added a link explaining record type. --- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/group_edit.tpl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 4c7e5cad9..b34e2e885 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- - + From 9850e2eb4693a013ff10ba4b44c58c72e8501081 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 27 Jun 2019 14:34:24 +0000 Subject: [PATCH 003/877] Starting working on extending custom fields. --- WEB-INF/templates/footer.tpl | 2 +- dbinstall.php | 9 +++++---- mysql.sql | 3 ++- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index b34e2e885..8860978db 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.19.4.5013 | Copyright © Anuko | +  Anuko Time Tracker 1.19.4.5014 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/group_edit.tpl b/WEB-INF/templates/group_edit.tpl index 659e62472..67bddd9e5 100644 --- a/WEB-INF/templates/group_edit.tpl +++ b/WEB-INF/templates/group_edit.tpl @@ -78,7 +78,7 @@ function handleTaskRequiredCheckbox() {
{$i18n.form.group_edit.record_type}:{$forms.groupForm.record_type.control}{$forms.groupForm.record_type.control} {$i18n.label.what_is_it}
{$i18n.form.group_edit.punch_mode}:
- - - + +
 Anuko Time Tracker 1.19.4.5014 | Copyright © Anuko | +  Anuko Time Tracker 1.19.5.5015 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/dbinstall.php b/dbinstall.php index 5dc943f28..035cffc38 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -1161,7 +1161,7 @@ function ttGenerateKeys() { ttExecute("UPDATE `tt_site_config` SET param_value = '1.19.0', modified = now() where param_name = 'version_db' and param_value = '1.18.61'"); } - if ($_POST["convert11900to11904"]) { + if ($_POST["convert11900to11905"]) { ttExecute("CREATE TABLE `tt_work_currencies` (`id` int(10) unsigned NOT NULL,`name` varchar(10) NOT NULL,PRIMARY KEY (`id`))"); ttExecute("create unique index currency_idx on tt_work_currencies(`name`)"); ttExecute("INSERT INTO `tt_work_currencies` (`id`, `name`) VALUES ('1', 'USD'), ('2', 'CAD'), ('3', 'AUD'), ('4', 'EUR'), ('5', 'NZD')"); @@ -1173,6 +1173,7 @@ function ttGenerateKeys() { ttExecute("UPDATE `tt_site_config` SET param_value = '1.19.3', modified = now() where param_name = 'version_db' and param_value = '1.19.0'"); ttExecute("ALTER TABLE `tt_groups` ADD `holidays` text default null AFTER `lock_spec`"); ttExecute("UPDATE `tt_site_config` SET param_value = '1.19.4', modified = now() where param_name = 'version_db' and param_value = '1.19.3'"); + ttExecute("ALTER TABLE `tt_custom_fields` ADD `entity_type` varchar(32) NOT NULL default 'time' AFTER `org_id`"); } if ($_POST["cleanup"]) { @@ -1222,7 +1223,7 @@ function ttGenerateKeys() {

DB Install

-
Create database structure (v1.19.4) + Create database structure (v1.19.5)
(applies only to new installations, do not execute when updating)
@@ -1271,8 +1272,8 @@ function ttGenerateKeys() {
Update database structure (v1.19 to v1.19.4)Update database structure (v1.19 to v1.19.5)
diff --git a/mysql.sql b/mysql.sql index be0d7edf7..14d9021be 100644 --- a/mysql.sql +++ b/mysql.sql @@ -381,6 +381,7 @@ CREATE TABLE `tt_custom_fields` ( `id` int(11) NOT NULL auto_increment, # custom field id `group_id` int(11) NOT NULL, # group id `org_id` int(11) default NULL, # organization id + `entity_type` varchar(32) NOT NULL default 'time', # type of entity custom field is associated with (time, user, project, task, etc.) `type` tinyint(4) NOT NULL default 0, # custom field type (text or dropdown) `label` varchar(32) NOT NULL default '', # custom field label `required` tinyint(4) default 0, # whether this custom field is mandatory for time records @@ -610,4 +611,4 @@ CREATE TABLE `tt_site_config` ( PRIMARY KEY (`param_name`) ); -INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.19.4', now()); # TODO: change when structure changes. +INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.19.5', now()); # TODO: change when structure changes. From 5629a1c360655d5a09dc965004946bf65e3725b9 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 27 Jun 2019 15:50:04 +0000 Subject: [PATCH 004/877] Introduced label.entity into localization files, --- WEB-INF/resources/ca.lang.php | 1 + WEB-INF/resources/cs.lang.php | 1 + WEB-INF/resources/da.lang.php | 2 ++ WEB-INF/resources/de.lang.php | 2 ++ WEB-INF/resources/en.lang.php | 1 + WEB-INF/resources/es.lang.php | 1 + WEB-INF/resources/et.lang.php | 2 ++ WEB-INF/resources/fa.lang.php | 2 ++ WEB-INF/resources/fi.lang.php | 2 ++ WEB-INF/resources/fr.lang.php | 2 ++ WEB-INF/resources/gr.lang.php | 2 ++ WEB-INF/resources/he.lang.php | 1 + WEB-INF/resources/hu.lang.php | 1 + WEB-INF/resources/it.lang.php | 2 ++ WEB-INF/resources/ja.lang.php | 1 + WEB-INF/resources/ko.lang.php | 1 + WEB-INF/resources/nl.lang.php | 2 ++ WEB-INF/resources/no.lang.php | 1 + WEB-INF/resources/pl.lang.php | 2 ++ WEB-INF/resources/pt-br.lang.php | 2 ++ WEB-INF/resources/pt.lang.php | 1 + WEB-INF/resources/ro.lang.php | 1 + WEB-INF/resources/ru.lang.php | 1 + WEB-INF/resources/sk.lang.php | 2 ++ WEB-INF/resources/sl.lang.php | 1 + WEB-INF/resources/sr.lang.php | 2 ++ WEB-INF/resources/sv.lang.php | 2 ++ WEB-INF/resources/tr.lang.php | 1 + WEB-INF/resources/zh-cn.lang.php | 1 + WEB-INF/resources/zh-tw.lang.php | 1 + WEB-INF/templates/footer.tpl | 2 +- 31 files changed, 45 insertions(+), 1 deletion(-) diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index 89172f674..20d6cd19b 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -245,6 +245,7 @@ // TODO: translate the following. // 'label.custom_fields' => 'Custom fields', // 'label.monthly_quotas' => 'Monthly quotas', +// 'label.entity' => 'Entity', // 'label.type' => 'Type', // 'label.type_dropdown' => 'dropdown', // 'label.type_text' => 'text', diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index 4a3b90ac1..0bd49c6b4 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -255,6 +255,7 @@ // TODO: translate the following. // 'label.custom_fields' => 'Custom fields', // 'label.monthly_quotas' => 'Monthly quotas', +// 'label.entity' => 'Entity', // 'label.type' => 'Type', // 'label.type_dropdown' => 'dropdown', // 'label.type_text' => 'text', diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index cd7d54f45..ad2da4c5d 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -235,6 +235,8 @@ // Labels for plugins (extensions to Time Tracker that provide additional features). 'label.custom_fields' => 'Brugerdefineret felt', 'label.monthly_quotas' => 'Månedlig kvota', +// TODO: translate the following. +// 'label.entity' => 'Entity', 'label.type' => 'Type', 'label.type_dropdown' => 'Dropdown', 'label.type_text' => 'Tekst', diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index 5c9a7f064..e15874d8e 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -225,6 +225,8 @@ // Labels for plugins (extensions to Time Tracker that provide additional features). 'label.custom_fields' => 'Benutzerfelder', 'label.monthly_quotas' => 'Monatliche Quoten', +// TODO: translate the following. +// 'label.entity' => 'Entity', 'label.type' => 'Typ', 'label.type_dropdown' => 'Ausklappen', 'label.type_text' => 'Text', diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index add6c0b00..e7de74697 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -214,6 +214,7 @@ // Labels for plugins (extensions to Time Tracker that provide additional features). 'label.custom_fields' => 'Custom fields', 'label.monthly_quotas' => 'Monthly quotas', +'label.entity' => 'Entity', 'label.type' => 'Type', 'label.type_dropdown' => 'dropdown', 'label.type_text' => 'text', diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index 60b1adba0..d7abcdab5 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -249,6 +249,7 @@ // TODO: translate the following. // 'label.custom_fields' => 'Custom fields', // 'label.monthly_quotas' => 'Monthly quotas', +// 'label.entity' => 'Entity', // 'label.type' => 'Type', // 'label.type_dropdown' => 'dropdown', // 'label.type_text' => 'text', diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index d18ce5820..39a0a271c 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -241,6 +241,8 @@ // Labels for plugins (extensions to Time Tracker that provide additional features). 'label.custom_fields' => 'Eriväljad', 'label.monthly_quotas' => 'Kuu kvoot', +// TODO: translate the following. +// 'label.entity' => 'Entity', 'label.type' => 'Tüüp', 'label.type_dropdown' => 'rippmenüü', 'label.type_text' => 'tekst', diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index eaae09588..b2eaf91e3 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -247,6 +247,8 @@ 'label.custom_fields' => 'فیلدهای سفارشی', // Translate the following. // 'label.monthly_quotas' => 'Monthly quotas', +// TODO: translate the following. +// 'label.entity' => 'Entity', 'label.type' => 'نوع', 'label.type_dropdown' => 'منو کشویی', 'label.type_text' => 'متن', diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 8d1e44121..626d2c9be 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -239,6 +239,8 @@ 'label.custom_fields' => 'Omat kentät', // TODO: translate the following. // 'label.monthly_quotas' => 'Monthly quotas', +// TODO: translate the following. +// 'label.entity' => 'Entity', 'label.type' => 'Tyyppi', 'label.type_dropdown' => 'pudotusvalikko', 'label.type_text' => 'teksti', diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index 49714745c..005007e1b 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -234,6 +234,8 @@ // Labels for plugins (extensions to Time Tracker that provide additional features). 'label.custom_fields' => 'Champs personalisés', 'label.monthly_quotas' => 'Quotas mensuels', +// TODO: translate the following. +// 'label.entity' => 'Entity', 'label.type' => 'Type', 'label.type_dropdown' => 'Liste déroulante', 'label.type_text' => 'Texte', diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index ad0dcd2e0..4f9ec5723 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -227,6 +227,8 @@ // Labels for plugins (extensions to Time Tracker that provide additional features). 'label.custom_fields' => 'Προσαρμοσμένα πεδία', 'label.monthly_quotas' => 'Μηνιαίες ποσοστώσεις', +// TODO: translate the following. +// 'label.entity' => 'Entity', 'label.type' => 'Τύπος', 'label.type_dropdown' => 'Αναπτυσσόμενο', 'label.type_text' => 'Κείμενο', diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index aa9fafb28..5ac9ec477 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -255,6 +255,7 @@ 'label.custom_fields' => 'שדות אישיים', // Translate the following. // 'label.monthly_quotas' => 'Monthly quotas', +// 'label.entity' => 'Entity', 'label.type' => 'סוג', 'label.type_dropdown' => 'רשימה', 'label.type_text' => 'טקסט', diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index 9639f8fbc..3abdb70b9 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -253,6 +253,7 @@ // TODO: translate the following. // 'label.custom_fields' => 'Custom fields', // 'label.monthly_quotas' => 'Monthly quotas', +// 'label.entity' => 'Entity', // 'label.type' => 'Type', // 'label.type_dropdown' => 'dropdown', // 'label.type_text' => 'text', diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index d895558ef..94e059bf4 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -231,6 +231,8 @@ // Labels for plugins (extensions to Time Tracker that provide additional features). 'label.custom_fields' => 'Campi personalizzati', 'label.monthly_quotas' => 'Quote mensili', +// TODO: translate the following. +// 'label.entity' => 'Entity', 'label.type' => 'Tipo', 'label.type_dropdown' => 'menu a tendina', 'label.type_text' => 'testo', diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index 9a58c2d05..0c2b51cbd 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -256,6 +256,7 @@ // TODO: translate the following. // 'label.custom_fields' => 'Custom fields', // 'label.monthly_quotas' => 'Monthly quotas', +// 'label.entity' => 'Entity', // 'label.type' => 'Type', // 'label.type_dropdown' => 'dropdown', // 'label.type_text' => 'text', diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index 84e1cdf8a..d30e51d88 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -255,6 +255,7 @@ // TODO: translate the following. // 'label.custom_fields' => 'Custom fields', // 'label.monthly_quotas' => 'Monthly quotas', +// 'label.entity' => 'Entity', // 'label.type' => 'Type', // 'label.type_dropdown' => 'dropdown', // 'label.type_text' => 'text', diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 39cfaef59..ca96a0ccc 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -214,6 +214,8 @@ // Labels for plugins (extensions to Time Tracker that provide additional features). 'label.custom_fields' => 'Eigen velden', 'label.monthly_quotas' => 'Doelen per maand', +// TODO: translate the following. +// 'label.entity' => 'Entity', 'label.type' => 'Type', 'label.type_dropdown' => 'uitklapbaar', 'label.type_text' => 'tekst', diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index bfeabdd32..c59d5086e 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -254,6 +254,7 @@ // TODO: translate the following. // 'label.custom_fields' => 'Custom fields', // 'label.monthly_quotas' => 'Monthly quotas', +// 'label.entity' => 'Entity', // 'label.type' => 'Type', // 'label.type_dropdown' => 'dropdown', // 'label.type_text' => 'text', diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index 828af7823..427b1e6ad 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -241,6 +241,8 @@ 'label.custom_fields' => 'Niestandardowe pola', // Translate the following. // 'label.monthly_quotas' => 'Monthly quotas', +// TODO: translate the following. +// 'label.entity' => 'Entity', 'label.type' => 'Rodzaj', 'label.type_dropdown' => 'lista rozwijana', 'label.type_text' => 'tekst', diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index cb8d68f13..b7f3c38eb 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -238,6 +238,8 @@ 'label.custom_fields' => 'Campos personalizados', // Translate the following. // 'label.monthly_quotas' => 'Monthly quotas', +// TODO: translate the following. +// 'label.entity' => 'Entity', 'label.type' => 'Tipo', 'label.type_dropdown' => 'lista suspensa', 'label.type_text' => 'texto', diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index 9b87642db..d9c51bd2b 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -243,6 +243,7 @@ // TODO: translate the following. // 'label.custom_fields' => 'Custom fields', // 'label.monthly_quotas' => 'Monthly quotas', +// 'label.entity' => 'Entity', // 'label.type' => 'Type', // 'label.type_dropdown' => 'dropdown', // 'label.type_text' => 'text', diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index 057714eac..a747e5721 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -253,6 +253,7 @@ // TODO: translate the following. // 'label.custom_fields' => 'Custom fields', // 'label.monthly_quotas' => 'Monthly quotas', +// 'label.entity' => 'Entity', // 'label.type' => 'Type', // 'label.type_dropdown' => 'dropdown', // 'label.type_text' => 'text', diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index bc1963be1..ff20fc5e6 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -213,6 +213,7 @@ // Labels for plugins (extensions to Time Tracker that provide additional features). 'label.custom_fields' => 'Дополнительные поля', 'label.monthly_quotas' => 'Месячные квоты', +'label.entity' => 'Сущность', 'label.type' => 'Тип', 'label.type_dropdown' => 'комбо', 'label.type_text' => 'текст', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index e68107077..52a810c3a 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -244,6 +244,8 @@ 'label.custom_fields' => 'Vlastné polia', // Translate the following. // 'label.monthly_quotas' => 'Monthly quotas', +// TODO: translate the following. +// 'label.entity' => 'Entity', 'label.type' => 'Typ', 'label.type_dropdown' => 'rozbaľovacie pole', 'label.type_text' => 'text', diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index 2157ff512..578b81650 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -238,6 +238,7 @@ // TODO: translate the following. // 'label.custom_fields' => 'Custom fields', // 'label.monthly_quotas' => 'Monthly quotas', +// 'label.entity' => 'Entity', // 'label.type' => 'Type', // 'label.type_dropdown' => 'dropdown', // 'label.type_text' => 'text', diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index 63ec33097..94b9512ef 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -238,6 +238,8 @@ 'label.custom_fields' => 'Dodatna polja', // Translate the following. // 'label.monthly_quotas' => 'Monthly quotas', +// TODO: translate the following. +// 'label.entity' => 'Entity', 'label.type' => 'Tipovi', 'label.type_dropdown' => 'odaberi', 'label.type_text' => 'text', diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index 7d756a516..030806e85 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -234,6 +234,8 @@ // Labels for plugins (extensions to Time Tracker that provide additional features). 'label.custom_fields' => 'Egna fält', 'label.monthly_quotas' => 'Månadskvoter', +// TODO: translate the following. +// 'label.entity' => 'Entity', 'label.type' => 'Typ', 'label.type_dropdown' => 'Rullgardinsmeny', 'label.type_text' => 'Text', diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index 479c8cd49..9a4693b81 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -260,6 +260,7 @@ // TODO: translate the following. // 'label.custom_fields' => 'Custom fields', // 'label.monthly_quotas' => 'Monthly quotas', +// 'label.entity' => 'Entity', // 'label.type' => 'Type', // 'label.type_dropdown' => 'dropdown', // 'label.type_text' => 'text', diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index a1fc15d80..a6dfa62ce 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -246,6 +246,7 @@ // TODO: translate the following. // 'label.custom_fields' => 'Custom fields', // 'label.monthly_quotas' => 'Monthly quotas', +// 'label.entity' => 'Entity', // 'label.type' => 'Type', // 'label.type_dropdown' => 'dropdown', // 'label.type_text' => 'text', diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index 9c97297d0..1b88e9eab 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -252,6 +252,7 @@ // TODO: translate the following. // 'label.custom_fields' => 'Custom fields', // 'label.monthly_quotas' => 'Monthly quotas', +// 'label.entity' => 'Entity', // 'label.type' => 'Type', // 'label.type_dropdown' => 'dropdown', // 'label.type_text' => 'text', diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 8860978db..f01a172e6 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.19.5.5015 | Copyright © Anuko | +  Anuko Time Tracker 1.19.5.5016 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From a0ff02ec3fa7016404f3992710db57951e74e824 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 27 Jun 2019 17:02:18 +0000 Subject: [PATCH 005/877] Introduced dropdown.time to translation files. --- WEB-INF/resources/ca.lang.php | 1 + WEB-INF/resources/cs.lang.php | 2 ++ WEB-INF/resources/da.lang.php | 2 ++ WEB-INF/resources/de.lang.php | 2 ++ WEB-INF/resources/en.lang.php | 1 + WEB-INF/resources/es.lang.php | 1 + WEB-INF/resources/et.lang.php | 2 ++ WEB-INF/resources/fa.lang.php | 2 ++ WEB-INF/resources/fi.lang.php | 2 ++ WEB-INF/resources/fr.lang.php | 2 ++ WEB-INF/resources/gr.lang.php | 2 ++ WEB-INF/resources/he.lang.php | 2 ++ WEB-INF/resources/hu.lang.php | 1 + WEB-INF/resources/it.lang.php | 2 ++ WEB-INF/resources/ja.lang.php | 2 ++ WEB-INF/resources/ko.lang.php | 2 ++ WEB-INF/resources/nl.lang.php | 2 ++ WEB-INF/resources/no.lang.php | 2 ++ WEB-INF/resources/pl.lang.php | 2 ++ WEB-INF/resources/pt-br.lang.php | 2 ++ WEB-INF/resources/pt.lang.php | 2 ++ WEB-INF/resources/ro.lang.php | 1 + WEB-INF/resources/ru.lang.php | 1 + WEB-INF/resources/sk.lang.php | 2 ++ WEB-INF/resources/sl.lang.php | 1 + WEB-INF/resources/sr.lang.php | 2 ++ WEB-INF/resources/sv.lang.php | 2 ++ WEB-INF/resources/tr.lang.php | 2 ++ WEB-INF/resources/zh-cn.lang.php | 2 ++ WEB-INF/resources/zh-tw.lang.php | 2 ++ WEB-INF/templates/footer.tpl | 2 +- cf_custom_field_add.php | 5 +++++ plugins/CustomFields.class.php | 5 ++++- 33 files changed, 63 insertions(+), 2 deletions(-) diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index 20d6cd19b..960ed0b23 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -414,6 +414,7 @@ // 'dropdown.previous_year' => 'previous year', // 'dropdown.selected_year' => 'year', // 'dropdown.all_time' => 'all time', +// 'dropdown.time' => 'time', 'dropdown.projects' => 'projectes', // TODO: translate the following. // 'dropdown.tasks' => 'tasks', diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index 0bd49c6b4..1d1da5248 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -423,6 +423,8 @@ 'dropdown.previous_year' => 'minulý rok', 'dropdown.selected_year' => 'rok', 'dropdown.all_time' => 'od počátku', +// TODO: translate the following. +// 'dropdown.time' => 'time', 'dropdown.projects' => 'projekty', // TODO: translate the following. // 'dropdown.tasks' => 'tasks', diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index ad2da4c5d..b1afacb7b 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -396,6 +396,8 @@ // 'dropdown.previous_year' => 'previous year', 'dropdown.selected_year' => 'år', 'dropdown.all_time' => 'Alt', +// TODO: translate the following. +// 'dropdown.time' => 'time', 'dropdown.projects' => 'Projekter', 'dropdown.tasks' => 'Opgaver', 'dropdown.clients' => 'Klienter', diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index e15874d8e..9524dad63 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -378,6 +378,8 @@ 'dropdown.previous_year' => 'vorheriges Jahr', 'dropdown.selected_year' => 'Jahr', 'dropdown.all_time' => 'Gesamtzeitraum', +// TODO: translate the following. +// 'dropdown.time' => 'time', 'dropdown.projects' => 'Projekte', 'dropdown.tasks' => 'Aufgaben', 'dropdown.clients' => 'Kunden', diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index e7de74697..ef89c364b 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -363,6 +363,7 @@ 'dropdown.previous_year' => 'previous year', 'dropdown.selected_year' => 'year', 'dropdown.all_time' => 'all time', +'dropdown.time' => 'time', 'dropdown.projects' => 'projects', 'dropdown.tasks' => 'tasks', 'dropdown.clients' => 'clients', diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index d7abcdab5..5fd0ac430 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -414,6 +414,7 @@ 'dropdown.selected_year' => 'año', // TODO: translate the following. // 'dropdown.all_time' => 'all time', +// 'dropdown.time' => 'time', 'dropdown.projects' => 'proyectos', // TODO: translate the following. // 'dropdown.tasks' => 'tasks', diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index 39a0a271c..3eea2d0ed 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -401,6 +401,8 @@ 'dropdown.previous_year' => 'eelmine aasta', 'dropdown.selected_year' => 'aasta', 'dropdown.all_time' => 'kõik ajavahemikud', +// TODO: translate the following. +// 'dropdown.time' => 'time', 'dropdown.projects' => 'projektid', 'dropdown.tasks' => 'tööülesanded', 'dropdown.clients' => 'kliendid', diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index b2eaf91e3..3b6e9d81e 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -407,6 +407,8 @@ // 'dropdown.previous_year' => 'previous year', // 'dropdown.selected_year' => 'year', 'dropdown.all_time' => 'همه زمان ها', +// TODO: translate the following. +// 'dropdown.time' => 'time', 'dropdown.projects' => 'پروژه ها', 'dropdown.tasks' => 'وظایف', 'dropdown.clients' => 'مشتریان', diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 626d2c9be..1aa06d567 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -396,6 +396,8 @@ // 'dropdown.previous_year' => 'previous year', 'dropdown.selected_year' => 'vuosi', 'dropdown.all_time' => 'kaikki tunnit', +// TODO: translate the following. +// 'dropdown.time' => 'time', 'dropdown.projects' => 'projektit', 'dropdown.tasks' => 'tehtävät', 'dropdown.clients' => 'asiakkaat', diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index 005007e1b..cb4883726 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -388,6 +388,8 @@ 'dropdown.previous_year' => 'année dernière', 'dropdown.selected_year' => 'année', 'dropdown.all_time' => 'depuis toujours', +// TODO: translate the following. +// 'dropdown.time' => 'time', 'dropdown.projects' => 'Projets', 'dropdown.tasks' => 'Tâches', 'dropdown.clients' => 'Clients', diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index 4f9ec5723..c8a8ab088 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -386,6 +386,8 @@ 'dropdown.previous_year' => 'προηγούμενο έτος', 'dropdown.selected_year' => 'έτος', 'dropdown.all_time' => 'όλη την περίοδο', +// TODO: translate the following. +// 'dropdown.time' => 'time', 'dropdown.projects' => 'έργα', 'dropdown.tasks' => 'εργασίες', 'dropdown.clients' => 'πελάτες', diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index 5ac9ec477..10a40edcf 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -413,6 +413,8 @@ // 'dropdown.previous_year' => 'previous year', 'dropdown.selected_year' => 'שנה', 'dropdown.all_time' => 'הכל', +// TODO: translate the following. +// 'dropdown.time' => 'time', 'dropdown.projects' => 'פרוייקטים', 'dropdown.tasks' => 'משימות', 'dropdown.clients' => 'לקוחות', diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index 3abdb70b9..95d990466 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -416,6 +416,7 @@ // 'dropdown.previous_year' => 'previous year', // 'dropdown.selected_year' => 'year', // 'dropdown.all_time' => 'all time', +// 'dropdown.time' => 'time', 'dropdown.projects' => 'projektek', // TODO: translate the following. // 'dropdown.tasks' => 'tasks', diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index 94e059bf4..845b1d10f 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -396,6 +396,8 @@ 'dropdown.previous_year' => 'anno precedente', 'dropdown.selected_year' => 'anno', 'dropdown.all_time' => 'tutto il tempo', +// TODO: translate the following. +// 'dropdown.time' => 'time', 'dropdown.projects' => 'progetti', 'dropdown.tasks' => 'compiti', 'dropdown.clients' => 'clienti', diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index 0c2b51cbd..3b9c091ec 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -419,6 +419,8 @@ 'dropdown.previous_year' => '昨年', 'dropdown.selected_year' => '年', 'dropdown.all_time' => 'すべての時間', +// TODO: translate the following. +// 'dropdown.time' => 'time', 'dropdown.projects' => 'プロジェクト', // TODO: translate the following. // 'dropdown.tasks' => 'tasks', diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index d30e51d88..43d3f8ad1 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -422,6 +422,8 @@ // 'dropdown.previous_year' => 'previous year', // 'dropdown.selected_year' => 'year', 'dropdown.all_time' => '전시간', +// TODO: translate the following. +// 'dropdown.time' => 'time', 'dropdown.projects' => '프로젝트', // TODO: translate the following. // 'dropdown.tasks' => 'tasks', diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index ca96a0ccc..49125a648 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -363,6 +363,8 @@ 'dropdown.previous_year' => 'vorig jaar', 'dropdown.selected_year' => 'jaar', 'dropdown.all_time' => 'alles', +// TODO: translate the following. +// 'dropdown.time' => 'time', 'dropdown.projects' => 'projecten', 'dropdown.tasks' => 'taken', 'dropdown.clients' => 'klanten', diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index c59d5086e..04ccf3c64 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -417,6 +417,8 @@ // 'dropdown.previous_year' => 'previous year', // 'dropdown.selected_year' => 'year', // 'dropdown.all_time' => 'all time', +// TODO: translate the following. +// 'dropdown.time' => 'time', 'dropdown.projects' => 'prosjekter', // TODO: translate the following. // 'dropdown.tasks' => 'tasks', diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index 427b1e6ad..3f0d93bff 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -399,6 +399,8 @@ // 'dropdown.previous_year' => 'previous year', 'dropdown.selected_year' => 'rok', 'dropdown.all_time' => 'od początku', +// TODO: translate the following. +// 'dropdown.time' => 'time', 'dropdown.projects' => 'projekty', 'dropdown.tasks' => 'zadania', 'dropdown.clients' => 'klienci', diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index b7f3c38eb..ef6eacee2 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -394,6 +394,8 @@ // 'dropdown.previous_year' => 'previous year', 'dropdown.selected_year' => 'ano', 'dropdown.all_time' => 'todas as datas', +// TODO: translate the following. +// 'dropdown.time' => 'time', 'dropdown.projects' => 'projetos', 'dropdown.tasks' => 'tarefas', 'dropdown.clients' => 'clientes', diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index d9c51bd2b..79bbae1ce 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -402,6 +402,8 @@ // 'dropdown.previous_year' => 'previous year', // 'dropdown.selected_year' => 'year', // 'dropdown.all_time' => 'all time', +// TODO: translate the following. +// 'dropdown.time' => 'time', 'dropdown.projects' => 'projetos', // TODO: translate the following. // 'dropdown.tasks' => 'tasks', diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index a747e5721..fc9f67e56 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -420,6 +420,7 @@ // 'dropdown.previous_year' => 'previous year', // 'dropdown.selected_year' => 'year', // 'dropdown.all_time' => 'all time', +// 'dropdown.time' => 'time', 'dropdown.projects' => 'proiecte', // TODO: translate the following. // 'dropdown.tasks' => 'tasks', diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index ff20fc5e6..22c666fe2 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -360,6 +360,7 @@ 'dropdown.previous_year' => 'прошлый год', 'dropdown.selected_year' => 'год', 'dropdown.all_time' => 'всё время', +'dropdown.time' => 'время', 'dropdown.projects' => 'проекты', 'dropdown.tasks' => 'задачи', 'dropdown.clients' => 'клиенты', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index 52a810c3a..133f80f0c 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -403,6 +403,8 @@ // 'dropdown.previous_year' => 'previous year', 'dropdown.selected_year' => 'rok', 'dropdown.all_time' => 'celý čas', +// TODO: translate the following. +// 'dropdown.time' => 'time', 'dropdown.projects' => 'projekty', 'dropdown.tasks' => 'úlohy', // TODO: translate the following. diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index 578b81650..f02209963 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -394,6 +394,7 @@ // 'dropdown.previous_year' => 'previous year', // 'dropdown.selected_year' => 'year', // 'dropdown.all_time' => 'all time', +// 'dropdown.time' => 'time', 'dropdown.projects' => 'projekti', // TODO: translate the following. // 'dropdown.tasks' => 'tasks', diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index 94b9512ef..d8f8986e4 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -397,6 +397,8 @@ // 'dropdown.previous_year' => 'previous year', 'dropdown.selected_year' => 'godina', 'dropdown.all_time' => 'svi datumi', +// TODO: translate the following. +// 'dropdown.time' => 'time', 'dropdown.projects' => 'projekti', 'dropdown.tasks' => 'zadaci', 'dropdown.clients' => 'klijenti', diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index 030806e85..97392f9eb 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -396,6 +396,8 @@ 'dropdown.previous_year' => 'Föregående år', 'dropdown.selected_year' => 'År', 'dropdown.all_time' => 'Livstid', +// TODO: translate the following. +// 'dropdown.time' => 'time', 'dropdown.projects' => 'Projekt', 'dropdown.tasks' => 'Arbetsuppgifter', 'dropdown.clients' => 'Kunder', diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index 9a4693b81..39c39e8f4 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -428,6 +428,8 @@ // 'dropdown.previous_year' => 'previous year', // 'dropdown.selected_year' => 'year', 'dropdown.all_time' => 'tüm zamanlar', +// TODO: translate the following. +// 'dropdown.time' => 'time', 'dropdown.projects' => 'projeler', // TODO: translate the following. // 'dropdown.tasks' => 'tasks', diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index a6dfa62ce..7493be7a0 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -409,6 +409,8 @@ // 'dropdown.previous_year' => 'previous year', // 'dropdown.selected_year' => 'year', 'dropdown.all_time' => '全部时间', +// TODO: translate the following. +// 'dropdown.time' => 'time', 'dropdown.projects' => '项目', // TODO: translate the following. // 'dropdown.tasks' => 'tasks', diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index 1b88e9eab..b8d923b8d 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -414,6 +414,8 @@ // 'dropdown.previous_year' => 'previous year', 'dropdown.selected_year' => '年', 'dropdown.all_time' => '全部時間', +// TODO: translate the following. +// 'dropdown.time' => 'time', 'dropdown.projects' => '項目', // TODO: translate the following. // 'dropdown.tasks' => 'tasks', diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index f01a172e6..59b49cfe1 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- +{if isTrue('CF_DEBUG')} + + + + +{/if} diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 59b49cfe1..265b35fe2 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.19.5.5016 | Copyright © Anuko | +  Anuko Time Tracker 1.19.5.5017 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/cf_custom_field_add.php b/cf_custom_field_add.php index c0dc255f6..c22c10e5b 100644 --- a/cf_custom_field_add.php +++ b/cf_custom_field_add.php @@ -49,6 +49,7 @@ if ($request->isPost()) { $cl_field_name = trim($request->getParameter('name')); + $cl_field_entity = $request->getParameter('entity'); $cl_field_type = $request->getParameter('type'); $cl_required = $request->getParameter('required'); if (!$cl_required) @@ -57,6 +58,10 @@ $form = new Form('fieldForm'); $form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'name','value'=>'')); +$form->addInput(array('type'=>'combobox','name'=>'entity', + 'data'=>array(CustomFields::ENTITY_TIME=>$i18n->get('label.type_text'), + CustomFields::ENTITY_USER=>$i18n->get('label.user')) +)); $form->addInput(array('type'=>'combobox','name'=>'type', 'data'=>array(CustomFields::TYPE_TEXT=>$i18n->get('label.type_text'), CustomFields::TYPE_DROPDOWN=>$i18n->get('label.type_dropdown')) diff --git a/plugins/CustomFields.class.php b/plugins/CustomFields.class.php index d9762b58d..ce870a94d 100644 --- a/plugins/CustomFields.class.php +++ b/plugins/CustomFields.class.php @@ -29,7 +29,10 @@ class CustomFields { // Definitions of custom field types. - + const ENTITY_TIME = 1; // Field is associated with time entries. + const ENTITY_USER = 2; // Field is associated with users. + const ENTITY_PROJECT = 3; // Field is associated with projects. + const TYPE_TEXT = 1; // A text field. const TYPE_DROPDOWN = 2; // A dropdown field with pre-defined values. From e85347d56f89d7fcc5e68763038551687f291b5c Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 27 Jun 2019 20:10:14 +0000 Subject: [PATCH 006/877] More work in progress on custom fields extension. --- WEB-INF/resources/ca.lang.php | 1 + WEB-INF/resources/cs.lang.php | 1 + WEB-INF/resources/da.lang.php | 1 + WEB-INF/resources/de.lang.php | 1 + WEB-INF/resources/en.lang.php | 1 + WEB-INF/resources/es.lang.php | 1 + WEB-INF/resources/et.lang.php | 1 + WEB-INF/resources/fa.lang.php | 1 + WEB-INF/resources/fi.lang.php | 1 + WEB-INF/resources/fr.lang.php | 1 + WEB-INF/resources/gr.lang.php | 1 + WEB-INF/resources/he.lang.php | 1 + WEB-INF/resources/hu.lang.php | 1 + WEB-INF/resources/it.lang.php | 1 + WEB-INF/resources/ja.lang.php | 1 + WEB-INF/resources/ko.lang.php | 1 + WEB-INF/resources/nl.lang.php | 1 + WEB-INF/resources/no.lang.php | 1 + WEB-INF/resources/pl.lang.php | 1 + WEB-INF/resources/pt-br.lang.php | 1 + WEB-INF/resources/pt.lang.php | 1 + WEB-INF/resources/ro.lang.php | 1 + WEB-INF/resources/ru.lang.php | 1 + WEB-INF/resources/sk.lang.php | 1 + WEB-INF/resources/sl.lang.php | 1 + WEB-INF/resources/sr.lang.php | 1 + WEB-INF/resources/sv.lang.php | 1 + WEB-INF/resources/tr.lang.php | 1 + WEB-INF/resources/zh-cn.lang.php | 1 + WEB-INF/resources/zh-tw.lang.php | 1 + WEB-INF/templates/cf_custom_field_add.tpl | 6 ++++++ WEB-INF/templates/footer.tpl | 2 +- cf_custom_field_add.php | 8 ++++---- plugins/CustomFields.class.php | 4 ++-- 34 files changed, 43 insertions(+), 7 deletions(-) diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index 960ed0b23..0f0b4c7fc 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -415,6 +415,7 @@ // 'dropdown.selected_year' => 'year', // 'dropdown.all_time' => 'all time', // 'dropdown.time' => 'time', +// 'dropdown.user' => 'user', 'dropdown.projects' => 'projectes', // TODO: translate the following. // 'dropdown.tasks' => 'tasks', diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index 1d1da5248..9000b3b19 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -425,6 +425,7 @@ 'dropdown.all_time' => 'od počátku', // TODO: translate the following. // 'dropdown.time' => 'time', +// 'dropdown.user' => 'user', 'dropdown.projects' => 'projekty', // TODO: translate the following. // 'dropdown.tasks' => 'tasks', diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index b1afacb7b..c17676318 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -398,6 +398,7 @@ 'dropdown.all_time' => 'Alt', // TODO: translate the following. // 'dropdown.time' => 'time', +// 'dropdown.user' => 'user', 'dropdown.projects' => 'Projekter', 'dropdown.tasks' => 'Opgaver', 'dropdown.clients' => 'Klienter', diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index 9524dad63..9fe12dfca 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -380,6 +380,7 @@ 'dropdown.all_time' => 'Gesamtzeitraum', // TODO: translate the following. // 'dropdown.time' => 'time', +// 'dropdown.user' => 'user', 'dropdown.projects' => 'Projekte', 'dropdown.tasks' => 'Aufgaben', 'dropdown.clients' => 'Kunden', diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index ef89c364b..7d25fd690 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -364,6 +364,7 @@ 'dropdown.selected_year' => 'year', 'dropdown.all_time' => 'all time', 'dropdown.time' => 'time', +'dropdown.user' => 'user', 'dropdown.projects' => 'projects', 'dropdown.tasks' => 'tasks', 'dropdown.clients' => 'clients', diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index 5fd0ac430..44ed2567a 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -415,6 +415,7 @@ // TODO: translate the following. // 'dropdown.all_time' => 'all time', // 'dropdown.time' => 'time', +// 'dropdown.user' => 'user', 'dropdown.projects' => 'proyectos', // TODO: translate the following. // 'dropdown.tasks' => 'tasks', diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index 3eea2d0ed..34a7239b1 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -403,6 +403,7 @@ 'dropdown.all_time' => 'kõik ajavahemikud', // TODO: translate the following. // 'dropdown.time' => 'time', +// 'dropdown.user' => 'user', 'dropdown.projects' => 'projektid', 'dropdown.tasks' => 'tööülesanded', 'dropdown.clients' => 'kliendid', diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index 3b6e9d81e..3095a87e4 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -409,6 +409,7 @@ 'dropdown.all_time' => 'همه زمان ها', // TODO: translate the following. // 'dropdown.time' => 'time', +// 'dropdown.user' => 'user', 'dropdown.projects' => 'پروژه ها', 'dropdown.tasks' => 'وظایف', 'dropdown.clients' => 'مشتریان', diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 1aa06d567..752c6ffd4 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -398,6 +398,7 @@ 'dropdown.all_time' => 'kaikki tunnit', // TODO: translate the following. // 'dropdown.time' => 'time', +// 'dropdown.user' => 'user', 'dropdown.projects' => 'projektit', 'dropdown.tasks' => 'tehtävät', 'dropdown.clients' => 'asiakkaat', diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index cb4883726..ff7e4e6f7 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -390,6 +390,7 @@ 'dropdown.all_time' => 'depuis toujours', // TODO: translate the following. // 'dropdown.time' => 'time', +// 'dropdown.user' => 'user', 'dropdown.projects' => 'Projets', 'dropdown.tasks' => 'Tâches', 'dropdown.clients' => 'Clients', diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index c8a8ab088..1e3c8be97 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -388,6 +388,7 @@ 'dropdown.all_time' => 'όλη την περίοδο', // TODO: translate the following. // 'dropdown.time' => 'time', +// 'dropdown.user' => 'user', 'dropdown.projects' => 'έργα', 'dropdown.tasks' => 'εργασίες', 'dropdown.clients' => 'πελάτες', diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index 10a40edcf..2905e274a 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -415,6 +415,7 @@ 'dropdown.all_time' => 'הכל', // TODO: translate the following. // 'dropdown.time' => 'time', +// 'dropdown.user' => 'user', 'dropdown.projects' => 'פרוייקטים', 'dropdown.tasks' => 'משימות', 'dropdown.clients' => 'לקוחות', diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index 95d990466..d44c8d8a0 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -417,6 +417,7 @@ // 'dropdown.selected_year' => 'year', // 'dropdown.all_time' => 'all time', // 'dropdown.time' => 'time', +// 'dropdown.user' => 'user', 'dropdown.projects' => 'projektek', // TODO: translate the following. // 'dropdown.tasks' => 'tasks', diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index 845b1d10f..a1efcd521 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -398,6 +398,7 @@ 'dropdown.all_time' => 'tutto il tempo', // TODO: translate the following. // 'dropdown.time' => 'time', +// 'dropdown.user' => 'user', 'dropdown.projects' => 'progetti', 'dropdown.tasks' => 'compiti', 'dropdown.clients' => 'clienti', diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index 3b9c091ec..1fadd683e 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -421,6 +421,7 @@ 'dropdown.all_time' => 'すべての時間', // TODO: translate the following. // 'dropdown.time' => 'time', +// 'dropdown.user' => 'user', 'dropdown.projects' => 'プロジェクト', // TODO: translate the following. // 'dropdown.tasks' => 'tasks', diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index 43d3f8ad1..115a96a50 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -424,6 +424,7 @@ 'dropdown.all_time' => '전시간', // TODO: translate the following. // 'dropdown.time' => 'time', +// 'dropdown.user' => 'user', 'dropdown.projects' => '프로젝트', // TODO: translate the following. // 'dropdown.tasks' => 'tasks', diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 49125a648..58d3aaaa2 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -365,6 +365,7 @@ 'dropdown.all_time' => 'alles', // TODO: translate the following. // 'dropdown.time' => 'time', +// 'dropdown.user' => 'user', 'dropdown.projects' => 'projecten', 'dropdown.tasks' => 'taken', 'dropdown.clients' => 'klanten', diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index 04ccf3c64..27d6a91ba 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -419,6 +419,7 @@ // 'dropdown.all_time' => 'all time', // TODO: translate the following. // 'dropdown.time' => 'time', +// 'dropdown.user' => 'user', 'dropdown.projects' => 'prosjekter', // TODO: translate the following. // 'dropdown.tasks' => 'tasks', diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index 3f0d93bff..aa6a2ceff 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -401,6 +401,7 @@ 'dropdown.all_time' => 'od początku', // TODO: translate the following. // 'dropdown.time' => 'time', +// 'dropdown.user' => 'user', 'dropdown.projects' => 'projekty', 'dropdown.tasks' => 'zadania', 'dropdown.clients' => 'klienci', diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index ef6eacee2..3d1d0abe8 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -396,6 +396,7 @@ 'dropdown.all_time' => 'todas as datas', // TODO: translate the following. // 'dropdown.time' => 'time', +// 'dropdown.user' => 'user', 'dropdown.projects' => 'projetos', 'dropdown.tasks' => 'tarefas', 'dropdown.clients' => 'clientes', diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index 79bbae1ce..2720464a2 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -404,6 +404,7 @@ // 'dropdown.all_time' => 'all time', // TODO: translate the following. // 'dropdown.time' => 'time', +// 'dropdown.user' => 'user', 'dropdown.projects' => 'projetos', // TODO: translate the following. // 'dropdown.tasks' => 'tasks', diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index fc9f67e56..64b4551cc 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -421,6 +421,7 @@ // 'dropdown.selected_year' => 'year', // 'dropdown.all_time' => 'all time', // 'dropdown.time' => 'time', +// 'dropdown.user' => 'user', 'dropdown.projects' => 'proiecte', // TODO: translate the following. // 'dropdown.tasks' => 'tasks', diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index 22c666fe2..980aa466e 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -361,6 +361,7 @@ 'dropdown.selected_year' => 'год', 'dropdown.all_time' => 'всё время', 'dropdown.time' => 'время', +'dropdown.user' => 'пользователь', 'dropdown.projects' => 'проекты', 'dropdown.tasks' => 'задачи', 'dropdown.clients' => 'клиенты', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index 133f80f0c..56d14f665 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -405,6 +405,7 @@ 'dropdown.all_time' => 'celý čas', // TODO: translate the following. // 'dropdown.time' => 'time', +// 'dropdown.user' => 'user', 'dropdown.projects' => 'projekty', 'dropdown.tasks' => 'úlohy', // TODO: translate the following. diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index f02209963..db54f19e1 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -395,6 +395,7 @@ // 'dropdown.selected_year' => 'year', // 'dropdown.all_time' => 'all time', // 'dropdown.time' => 'time', +// 'dropdown.user' => 'user', 'dropdown.projects' => 'projekti', // TODO: translate the following. // 'dropdown.tasks' => 'tasks', diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index d8f8986e4..eb8f3ebf0 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -399,6 +399,7 @@ 'dropdown.all_time' => 'svi datumi', // TODO: translate the following. // 'dropdown.time' => 'time', +// 'dropdown.user' => 'user', 'dropdown.projects' => 'projekti', 'dropdown.tasks' => 'zadaci', 'dropdown.clients' => 'klijenti', diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index 97392f9eb..c17662baa 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -398,6 +398,7 @@ 'dropdown.all_time' => 'Livstid', // TODO: translate the following. // 'dropdown.time' => 'time', +// 'dropdown.user' => 'user', 'dropdown.projects' => 'Projekt', 'dropdown.tasks' => 'Arbetsuppgifter', 'dropdown.clients' => 'Kunder', diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index 39c39e8f4..5701f5621 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -430,6 +430,7 @@ 'dropdown.all_time' => 'tüm zamanlar', // TODO: translate the following. // 'dropdown.time' => 'time', +// 'dropdown.user' => 'user', 'dropdown.projects' => 'projeler', // TODO: translate the following. // 'dropdown.tasks' => 'tasks', diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index 7493be7a0..dce6df857 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -411,6 +411,7 @@ 'dropdown.all_time' => '全部时间', // TODO: translate the following. // 'dropdown.time' => 'time', +// 'dropdown.user' => 'user', 'dropdown.projects' => '项目', // TODO: translate the following. // 'dropdown.tasks' => 'tasks', diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index b8d923b8d..a18cb213b 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -416,6 +416,7 @@ 'dropdown.all_time' => '全部時間', // TODO: translate the following. // 'dropdown.time' => 'time', +// 'dropdown.user' => 'user', 'dropdown.projects' => '項目', // TODO: translate the following. // 'dropdown.tasks' => 'tasks', diff --git a/WEB-INF/templates/cf_custom_field_add.tpl b/WEB-INF/templates/cf_custom_field_add.tpl index 442f41bb8..4c343eec9 100644 --- a/WEB-INF/templates/cf_custom_field_add.tpl +++ b/WEB-INF/templates/cf_custom_field_add.tpl @@ -8,6 +8,12 @@ {$i18n.label.thing_name} (*): {$forms.fieldForm.name.control}
{$i18n.label.entity}:{$forms.fieldForm.entity.control} {$i18n.label.what_is_it}
{$i18n.label.type}: {$forms.fieldForm.type.control}
-
 Anuko Time Tracker 1.19.5.5017 | Copyright © Anuko | +  Anuko Time Tracker 1.19.5.5018 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/cf_custom_field_add.php b/cf_custom_field_add.php index c22c10e5b..e4a919eb5 100644 --- a/cf_custom_field_add.php +++ b/cf_custom_field_add.php @@ -49,7 +49,7 @@ if ($request->isPost()) { $cl_field_name = trim($request->getParameter('name')); - $cl_field_entity = $request->getParameter('entity'); + $cl_entity_type = $request->getParameter('entity'); $cl_field_type = $request->getParameter('type'); $cl_required = $request->getParameter('required'); if (!$cl_required) @@ -59,8 +59,8 @@ $form = new Form('fieldForm'); $form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'name','value'=>'')); $form->addInput(array('type'=>'combobox','name'=>'entity', - 'data'=>array(CustomFields::ENTITY_TIME=>$i18n->get('label.type_text'), - CustomFields::ENTITY_USER=>$i18n->get('label.user')) + 'data'=>array(CustomFields::ENTITY_TIME=>$i18n->get('dropdown.time'), + CustomFields::ENTITY_USER=>$i18n->get('dropdown.user')) )); $form->addInput(array('type'=>'combobox','name'=>'type', 'data'=>array(CustomFields::TYPE_TEXT=>$i18n->get('label.type_text'), @@ -74,7 +74,7 @@ if (!ttValidString($cl_field_name)) $err->add($i18n->get('error.field'), $i18n->get('label.thing_name')); if ($err->no()) { - $res = CustomFields::insertField($cl_field_name, $cl_field_type, $cl_required); + $res = CustomFields::insertField($cl_field_name, $cl_entity_type, $cl_field_type, $cl_required); if ($res) { header('Location: cf_custom_fields.php'); exit(); diff --git a/plugins/CustomFields.class.php b/plugins/CustomFields.class.php index ce870a94d..a0c49ec56 100644 --- a/plugins/CustomFields.class.php +++ b/plugins/CustomFields.class.php @@ -32,7 +32,7 @@ class CustomFields { const ENTITY_TIME = 1; // Field is associated with time entries. const ENTITY_USER = 2; // Field is associated with users. const ENTITY_PROJECT = 3; // Field is associated with projects. - + const TYPE_TEXT = 1; // A text field. const TYPE_DROPDOWN = 2; // A dropdown field with pre-defined values. @@ -301,7 +301,7 @@ static function getFieldIdForOption($option_id) { } // The insertField inserts a custom field for group. - static function insertField($field_name, $field_type, $required) { + static function insertField($field_name, $entity_type, $field_type, $required) { global $user; $mdb2 = getConnection(); From 691958794018beda9788e9bdb47d640a116af492 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 28 Jun 2019 13:12:29 +0000 Subject: [PATCH 007/877] Changed entity_type datatype in db to optimize things. --- WEB-INF/templates/footer.tpl | 2 +- dbinstall.php | 11 +++++++---- mysql.sql | 4 ++-- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 265b35fe2..11c4f8cbd 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- - - + +
 Anuko Time Tracker 1.19.5.5018 | Copyright © Anuko | +  Anuko Time Tracker 1.19.6.5019 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/dbinstall.php b/dbinstall.php index 035cffc38..6a65336ae 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -1161,7 +1161,7 @@ function ttGenerateKeys() { ttExecute("UPDATE `tt_site_config` SET param_value = '1.19.0', modified = now() where param_name = 'version_db' and param_value = '1.18.61'"); } - if ($_POST["convert11900to11905"]) { + if ($_POST["convert11900to11906"]) { ttExecute("CREATE TABLE `tt_work_currencies` (`id` int(10) unsigned NOT NULL,`name` varchar(10) NOT NULL,PRIMARY KEY (`id`))"); ttExecute("create unique index currency_idx on tt_work_currencies(`name`)"); ttExecute("INSERT INTO `tt_work_currencies` (`id`, `name`) VALUES ('1', 'USD'), ('2', 'CAD'), ('3', 'AUD'), ('4', 'EUR'), ('5', 'NZD')"); @@ -1174,6 +1174,9 @@ function ttGenerateKeys() { ttExecute("ALTER TABLE `tt_groups` ADD `holidays` text default null AFTER `lock_spec`"); ttExecute("UPDATE `tt_site_config` SET param_value = '1.19.4', modified = now() where param_name = 'version_db' and param_value = '1.19.3'"); ttExecute("ALTER TABLE `tt_custom_fields` ADD `entity_type` varchar(32) NOT NULL default 'time' AFTER `org_id`"); + ttExecute("update `tt_custom_fields` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.19.4') set entity_type = 1 where entity_type = 'time'"); + ttExecute("ALTER TABLE `tt_custom_fields` modify entity_type tinyint(4) NOT NULL default '1'"); + ttExecute("UPDATE `tt_site_config` SET param_value = '1.19.6', modified = now() where param_name = 'version_db' and param_value = '1.19.4'"); } if ($_POST["cleanup"]) { @@ -1223,7 +1226,7 @@ function ttGenerateKeys() {

DB Install

-
Create database structure (v1.19.5) + Create database structure (v1.19.6)
(applies only to new installations, do not execute when updating)
@@ -1272,8 +1275,8 @@ function ttGenerateKeys() {
Update database structure (v1.19 to v1.19.5)Update database structure (v1.19 to v1.19.6)
diff --git a/mysql.sql b/mysql.sql index 14d9021be..fc67b19f4 100644 --- a/mysql.sql +++ b/mysql.sql @@ -381,7 +381,7 @@ CREATE TABLE `tt_custom_fields` ( `id` int(11) NOT NULL auto_increment, # custom field id `group_id` int(11) NOT NULL, # group id `org_id` int(11) default NULL, # organization id - `entity_type` varchar(32) NOT NULL default 'time', # type of entity custom field is associated with (time, user, project, task, etc.) + `entity_type` tinyint(4) default 1, # type of entity custom field is associated with (time, user, project, task, etc.) `type` tinyint(4) NOT NULL default 0, # custom field type (text or dropdown) `label` varchar(32) NOT NULL default '', # custom field label `required` tinyint(4) default 0, # whether this custom field is mandatory for time records @@ -611,4 +611,4 @@ CREATE TABLE `tt_site_config` ( PRIMARY KEY (`param_name`) ); -INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.19.5', now()); # TODO: change when structure changes. +INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.19.6', now()); # TODO: change when structure changes. From 770d560338b34e0a869c78778d0cd838905fb192 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 28 Jun 2019 13:35:10 +0000 Subject: [PATCH 008/877] Adjusted export-import to work with entity type in custom fields. --- WEB-INF/lib/ttGroupExportHelper.class.php | 1 + WEB-INF/lib/ttOrgImportHelper.class.php | 6 ++++-- WEB-INF/templates/footer.tpl | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/WEB-INF/lib/ttGroupExportHelper.class.php b/WEB-INF/lib/ttGroupExportHelper.class.php index 8a7b7e770..cd38de9d7 100644 --- a/WEB-INF/lib/ttGroupExportHelper.class.php +++ b/WEB-INF/lib/ttGroupExportHelper.class.php @@ -406,6 +406,7 @@ function writeData() { fwrite($this->file, $this->indentation." \n"); foreach ($custom_fields as $custom_field) { $custom_field_part = $this->indentation.' '."customFieldMap[$custom_field['id']]."\""; + $custom_field_part .= " entity_type=\"".$custom_field['entity_type']."\""; $custom_field_part .= " type=\"".$custom_field['type']."\""; $custom_field_part .= " label=\"".htmlspecialchars($custom_field['label'])."\""; $custom_field_part .= " required=\"".$custom_field['required']."\""; diff --git a/WEB-INF/lib/ttOrgImportHelper.class.php b/WEB-INF/lib/ttOrgImportHelper.class.php index b9c76620f..20dd41764 100644 --- a/WEB-INF/lib/ttOrgImportHelper.class.php +++ b/WEB-INF/lib/ttOrgImportHelper.class.php @@ -352,6 +352,7 @@ function startElement($parser, $name, $attrs) { $custom_field_id = $this->insertCustomField(array( 'group_id' => $this->current_group_id, 'org_id' => $this->org_id, + 'entity_type' => $attrs['ENTITY_TYPE'], 'type' => $attrs['TYPE'], 'label' => $attrs['LABEL'], 'required' => $attrs['REQUIRED'], @@ -1114,14 +1115,15 @@ private function insertCustomField($fields) { $group_id = (int) $fields['group_id']; $org_id = (int) $fields['org_id']; + $entity_type = (int) $fields['entity_type']; $type = (int) $fields['type']; $label = $fields['label']; $required = (int) $fields['required']; $status = $fields['status']; $sql = "insert into tt_custom_fields". - " (group_id, org_id, type, label, required, status)". - " values($group_id, $org_id, $type, ".$mdb2->quote($label).", $required, ".$mdb2->quote($status).")"; + " (group_id, org_id, entity_type, type, label, required, status)". + " values($group_id, $org_id, $entity_type, $type, ".$mdb2->quote($label).", $required, ".$mdb2->quote($status).")"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 11c4f8cbd..3beac6413 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.19.6.5019 | Copyright © Anuko | +  Anuko Time Tracker 1.19.6.5020 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From db25f950841ee874795d4b9605f8ae2347aaf4f1 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 28 Jun 2019 14:42:30 +0000 Subject: [PATCH 009/877] Added entity column on cf_custom_fields.php page. --- WEB-INF/resources/ca.lang.php | 9 +++++++-- WEB-INF/resources/cs.lang.php | 10 +++++++--- WEB-INF/resources/da.lang.php | 10 +++++++--- WEB-INF/resources/de.lang.php | 10 +++++++--- WEB-INF/resources/en.lang.php | 8 ++++++-- WEB-INF/resources/es.lang.php | 9 +++++++-- WEB-INF/resources/et.lang.php | 10 +++++++--- WEB-INF/resources/fa.lang.php | 10 +++++++--- WEB-INF/resources/fi.lang.php | 10 +++++++--- WEB-INF/resources/fr.lang.php | 10 +++++++--- WEB-INF/resources/gr.lang.php | 10 +++++++--- WEB-INF/resources/he.lang.php | 10 +++++++--- WEB-INF/resources/hu.lang.php | 9 +++++++-- WEB-INF/resources/it.lang.php | 10 +++++++--- WEB-INF/resources/ja.lang.php | 10 +++++++--- WEB-INF/resources/ko.lang.php | 10 +++++++--- WEB-INF/resources/nl.lang.php | 10 +++++++--- WEB-INF/resources/no.lang.php | 10 +++++++--- WEB-INF/resources/pl.lang.php | 10 +++++++--- WEB-INF/resources/pt-br.lang.php | 10 +++++++--- WEB-INF/resources/pt.lang.php | 10 +++++++--- WEB-INF/resources/ro.lang.php | 9 +++++++-- WEB-INF/resources/ru.lang.php | 8 ++++++-- WEB-INF/resources/sk.lang.php | 10 +++++++--- WEB-INF/resources/sl.lang.php | 9 +++++++-- WEB-INF/resources/sr.lang.php | 10 +++++++--- WEB-INF/resources/sv.lang.php | 10 +++++++--- WEB-INF/resources/tr.lang.php | 10 +++++++--- WEB-INF/resources/zh-cn.lang.php | 10 +++++++--- WEB-INF/resources/zh-tw.lang.php | 10 +++++++--- WEB-INF/templates/cf_custom_fields.tpl | 10 +++++++++- WEB-INF/templates/footer.tpl | 2 +- cf_custom_field_add.php | 6 +++--- cf_custom_fields.php | 2 +- plugins/CustomFields.class.php | 8 ++++---- 35 files changed, 226 insertions(+), 93 deletions(-) diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index 0f0b4c7fc..42c637b1b 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -282,6 +282,13 @@ // 'label.active_users' => 'Active Users', // 'label.inactive_users' => 'Inactive Users', +// Entity names. We use lower case (in English) because they are used in dropdowns, too. +// They are used to associate a custom field with an entity type. +// TODO: translate the following. +// 'entity.time' => 'time', +// 'entity.user' => 'user', +// 'entity.project' => 'project', + // Form titles. // TODO: Improve titles for consistency, so that each title explains correctly what each // page is about and is "consistent" from page to page, meaning that correct grammar is used everywhere. @@ -414,8 +421,6 @@ // 'dropdown.previous_year' => 'previous year', // 'dropdown.selected_year' => 'year', // 'dropdown.all_time' => 'all time', -// 'dropdown.time' => 'time', -// 'dropdown.user' => 'user', 'dropdown.projects' => 'projectes', // TODO: translate the following. // 'dropdown.tasks' => 'tasks', diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index 9000b3b19..0f25aa666 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -292,6 +292,13 @@ // 'label.active_users' => 'Active Users', // 'label.inactive_users' => 'Inactive Users', +// Entity names. We use lower case (in English) because they are used in dropdowns, too. +// They are used to associate a custom field with an entity type. +// TODO: translate the following. +// 'entity.time' => 'time', +// 'entity.user' => 'user', +// 'entity.project' => 'project', + // Form titles. // TODO: Improve titles for consistency, so that each title explains correctly what each // page is about and is "consistent" from page to page, meaning that correct grammar is used everywhere. @@ -423,9 +430,6 @@ 'dropdown.previous_year' => 'minulý rok', 'dropdown.selected_year' => 'rok', 'dropdown.all_time' => 'od počátku', -// TODO: translate the following. -// 'dropdown.time' => 'time', -// 'dropdown.user' => 'user', 'dropdown.projects' => 'projekty', // TODO: translate the following. // 'dropdown.tasks' => 'tasks', diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index c17676318..0c59b52a3 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -272,6 +272,13 @@ 'label.active_users' => 'Aktive Brugere', 'label.inactive_users' => 'Inaktive Brugere', +// Entity names. We use lower case (in English) because they are used in dropdowns, too. +// They are used to associate a custom field with an entity type. +// TODO: translate the following. +// 'entity.time' => 'time', +// 'entity.user' => 'user', +// 'entity.project' => 'project', + // Form titles. 'title.error' => 'Fejl', // TODO: Translate the following. @@ -396,9 +403,6 @@ // 'dropdown.previous_year' => 'previous year', 'dropdown.selected_year' => 'år', 'dropdown.all_time' => 'Alt', -// TODO: translate the following. -// 'dropdown.time' => 'time', -// 'dropdown.user' => 'user', 'dropdown.projects' => 'Projekter', 'dropdown.tasks' => 'Opgaver', 'dropdown.clients' => 'Klienter', diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index 9fe12dfca..3b6c1a712 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -261,6 +261,13 @@ 'label.active_users' => 'Aktive Nutzer', 'label.inactive_users' => 'Inaktive Nutzer', +// Entity names. We use lower case (in English) because they are used in dropdowns, too. +// They are used to associate a custom field with an entity type. +// TODO: translate the following. +// 'entity.time' => 'time', +// 'entity.user' => 'user', +// 'entity.project' => 'project', + // Form titles. 'title.error' => 'Fehler', // TODO: Translate the following. @@ -378,9 +385,6 @@ 'dropdown.previous_year' => 'vorheriges Jahr', 'dropdown.selected_year' => 'Jahr', 'dropdown.all_time' => 'Gesamtzeitraum', -// TODO: translate the following. -// 'dropdown.time' => 'time', -// 'dropdown.user' => 'user', 'dropdown.projects' => 'Projekte', 'dropdown.tasks' => 'Aufgaben', 'dropdown.clients' => 'Kunden', diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index 7d25fd690..851c8f93c 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -248,6 +248,12 @@ 'label.active_users' => 'Active Users', 'label.inactive_users' => 'Inactive Users', +// Entity names. We use lower case (in English) because they are used in dropdowns, too. +// They are used to associate a custom field with an entity type. +'entity.time' => 'time', +'entity.user' => 'user', +'entity.project' => 'project', + // Form titles. 'title.error' => 'Error', 'title.success' => 'Success', @@ -363,8 +369,6 @@ 'dropdown.previous_year' => 'previous year', 'dropdown.selected_year' => 'year', 'dropdown.all_time' => 'all time', -'dropdown.time' => 'time', -'dropdown.user' => 'user', 'dropdown.projects' => 'projects', 'dropdown.tasks' => 'tasks', 'dropdown.clients' => 'clients', diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index 44ed2567a..cae029431 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -285,6 +285,13 @@ // 'label.active_users' => 'Active Users', // 'label.inactive_users' => 'Inactive Users', +// Entity names. We use lower case (in English) because they are used in dropdowns, too. +// They are used to associate a custom field with an entity type. +// TODO: translate the following. +// 'entity.time' => 'time', +// 'entity.user' => 'user', +// 'entity.project' => 'project', + // Form titles. // TODO: Translate the following. // 'title.error' => 'Error', @@ -414,8 +421,6 @@ 'dropdown.selected_year' => 'año', // TODO: translate the following. // 'dropdown.all_time' => 'all time', -// 'dropdown.time' => 'time', -// 'dropdown.user' => 'user', 'dropdown.projects' => 'proyectos', // TODO: translate the following. // 'dropdown.tasks' => 'tasks', diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index 34a7239b1..fbe2e88ce 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -278,6 +278,13 @@ 'label.active_users' => 'Aktiivsed kasutajad', 'label.inactive_users' => 'Mitteaktiivsed kasutajad', +// Entity names. We use lower case (in English) because they are used in dropdowns, too. +// They are used to associate a custom field with an entity type. +// TODO: translate the following. +// 'entity.time' => 'time', +// 'entity.user' => 'user', +// 'entity.project' => 'project', + // Form titles. // TODO: Improve titles for consistency, so that each title explains correctly what each // page is about and is "consistent" from page to page, meaning that correct grammar is used everywhere. @@ -401,9 +408,6 @@ 'dropdown.previous_year' => 'eelmine aasta', 'dropdown.selected_year' => 'aasta', 'dropdown.all_time' => 'kõik ajavahemikud', -// TODO: translate the following. -// 'dropdown.time' => 'time', -// 'dropdown.user' => 'user', 'dropdown.projects' => 'projektid', 'dropdown.tasks' => 'tööülesanded', 'dropdown.clients' => 'kliendid', diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index 3095a87e4..13a2d5f4e 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -283,6 +283,13 @@ 'label.active_users' => 'کاربران فعال', 'label.inactive_users' => 'کاربران غیرفعال', +// Entity names. We use lower case (in English) because they are used in dropdowns, too. +// They are used to associate a custom field with an entity type. +// TODO: translate the following. +// 'entity.time' => 'time', +// 'entity.user' => 'user', +// 'entity.project' => 'project', + // Form titles. 'title.error' => 'خطا', // TODO: Translate the following. @@ -407,9 +414,6 @@ // 'dropdown.previous_year' => 'previous year', // 'dropdown.selected_year' => 'year', 'dropdown.all_time' => 'همه زمان ها', -// TODO: translate the following. -// 'dropdown.time' => 'time', -// 'dropdown.user' => 'user', 'dropdown.projects' => 'پروژه ها', 'dropdown.tasks' => 'وظایف', 'dropdown.clients' => 'مشتریان', diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 752c6ffd4..4421b889c 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -276,6 +276,13 @@ 'label.active_users' => 'Aktiiviset käyttäjät', 'label.inactive_users' => 'Ei-aktiiviset käyttäjät', +// Entity names. We use lower case (in English) because they are used in dropdowns, too. +// They are used to associate a custom field with an entity type. +// TODO: translate the following. +// 'entity.time' => 'time', +// 'entity.user' => 'user', +// 'entity.project' => 'project', + // Form titles. 'title.error' => 'Virhe', // TODO: Translate the following. @@ -396,9 +403,6 @@ // 'dropdown.previous_year' => 'previous year', 'dropdown.selected_year' => 'vuosi', 'dropdown.all_time' => 'kaikki tunnit', -// TODO: translate the following. -// 'dropdown.time' => 'time', -// 'dropdown.user' => 'user', 'dropdown.projects' => 'projektit', 'dropdown.tasks' => 'tehtävät', 'dropdown.clients' => 'asiakkaat', diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index ff7e4e6f7..3a5ce78a3 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -270,6 +270,13 @@ 'label.active_users' => 'Utilisateurs actifs', 'label.inactive_users' => 'Utilisateurs inactifs', +// Entity names. We use lower case (in English) because they are used in dropdowns, too. +// They are used to associate a custom field with an entity type. +// TODO: translate the following. +// 'entity.time' => 'time', +// 'entity.user' => 'user', +// 'entity.project' => 'project', + // Form titles. 'title.error' => 'Erreur', // TODO: Translate the following. @@ -388,9 +395,6 @@ 'dropdown.previous_year' => 'année dernière', 'dropdown.selected_year' => 'année', 'dropdown.all_time' => 'depuis toujours', -// TODO: translate the following. -// 'dropdown.time' => 'time', -// 'dropdown.user' => 'user', 'dropdown.projects' => 'Projets', 'dropdown.tasks' => 'Tâches', 'dropdown.clients' => 'Clients', diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index 1e3c8be97..65e731800 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -265,6 +265,13 @@ 'label.active_users' => 'Ενεργοί χρήστες', 'label.inactive_users' => 'Ανενεργοί χρήστες', +// Entity names. We use lower case (in English) because they are used in dropdowns, too. +// They are used to associate a custom field with an entity type. +// TODO: translate the following. +// 'entity.time' => 'time', +// 'entity.user' => 'user', +// 'entity.project' => 'project', + // Form titles. 'title.error' => 'Σφάλμα', // TODO: Translate the following. @@ -386,9 +393,6 @@ 'dropdown.previous_year' => 'προηγούμενο έτος', 'dropdown.selected_year' => 'έτος', 'dropdown.all_time' => 'όλη την περίοδο', -// TODO: translate the following. -// 'dropdown.time' => 'time', -// 'dropdown.user' => 'user', 'dropdown.projects' => 'έργα', 'dropdown.tasks' => 'εργασίες', 'dropdown.clients' => 'πελάτες', diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index 2905e274a..3aee8065a 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -291,6 +291,13 @@ 'label.active_users' => 'משתמשים פעילים', 'label.inactive_users' => 'משתמשים לא פעילים', +// Entity names. We use lower case (in English) because they are used in dropdowns, too. +// They are used to associate a custom field with an entity type. +// TODO: translate the following. +// 'entity.time' => 'time', +// 'entity.user' => 'user', +// 'entity.project' => 'project', + // Form titles. 'title.error' => 'שגיאה', // TODO: Translate the following. @@ -413,9 +420,6 @@ // 'dropdown.previous_year' => 'previous year', 'dropdown.selected_year' => 'שנה', 'dropdown.all_time' => 'הכל', -// TODO: translate the following. -// 'dropdown.time' => 'time', -// 'dropdown.user' => 'user', 'dropdown.projects' => 'פרוייקטים', 'dropdown.tasks' => 'משימות', 'dropdown.clients' => 'לקוחות', diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index d44c8d8a0..a998dd869 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -288,6 +288,13 @@ // 'label.active_users' => 'Active Users', // 'label.inactive_users' => 'Inactive Users', +// Entity names. We use lower case (in English) because they are used in dropdowns, too. +// They are used to associate a custom field with an entity type. +// TODO: translate the following. +// 'entity.time' => 'time', +// 'entity.user' => 'user', +// 'entity.project' => 'project', + // Form titles. // TODO: Translate the following. // 'title.error' => 'Error', @@ -416,8 +423,6 @@ // 'dropdown.previous_year' => 'previous year', // 'dropdown.selected_year' => 'year', // 'dropdown.all_time' => 'all time', -// 'dropdown.time' => 'time', -// 'dropdown.user' => 'user', 'dropdown.projects' => 'projektek', // TODO: translate the following. // 'dropdown.tasks' => 'tasks', diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index a1efcd521..4f6368bd5 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -269,6 +269,13 @@ 'label.active_users' => 'Utenti attivi', 'label.inactive_users' => 'Utenti inattivi', +// Entity names. We use lower case (in English) because they are used in dropdowns, too. +// They are used to associate a custom field with an entity type. +// TODO: translate the following. +// 'entity.time' => 'time', +// 'entity.user' => 'user', +// 'entity.project' => 'project', + // Form titles. // TODO: Improve titles for consistency, so that each title explains correctly what each // page is about and is "consistent" from page to page, meaning that correct grammar is used everywhere. @@ -396,9 +403,6 @@ 'dropdown.previous_year' => 'anno precedente', 'dropdown.selected_year' => 'anno', 'dropdown.all_time' => 'tutto il tempo', -// TODO: translate the following. -// 'dropdown.time' => 'time', -// 'dropdown.user' => 'user', 'dropdown.projects' => 'progetti', 'dropdown.tasks' => 'compiti', 'dropdown.clients' => 'clienti', diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index 1fadd683e..8a723baef 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -292,6 +292,13 @@ // 'label.active_users' => 'Active Users', // 'label.inactive_users' => 'Inactive Users', +// Entity names. We use lower case (in English) because they are used in dropdowns, too. +// They are used to associate a custom field with an entity type. +// TODO: translate the following. +// 'entity.time' => 'time', +// 'entity.user' => 'user', +// 'entity.project' => 'project', + // Form titles. // TODO: Translate the following. // 'title.error' => 'Error', @@ -419,9 +426,6 @@ 'dropdown.previous_year' => '昨年', 'dropdown.selected_year' => '年', 'dropdown.all_time' => 'すべての時間', -// TODO: translate the following. -// 'dropdown.time' => 'time', -// 'dropdown.user' => 'user', 'dropdown.projects' => 'プロジェクト', // TODO: translate the following. // 'dropdown.tasks' => 'tasks', diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index 115a96a50..c2957e163 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -292,6 +292,13 @@ // 'label.active_users' => 'Active Users', // 'label.inactive_users' => 'Inactive Users', +// Entity names. We use lower case (in English) because they are used in dropdowns, too. +// They are used to associate a custom field with an entity type. +// TODO: translate the following. +// 'entity.time' => 'time', +// 'entity.user' => 'user', +// 'entity.project' => 'project', + // Form titles. // TODO: Translate the following. // 'title.error' => 'Error', @@ -422,9 +429,6 @@ // 'dropdown.previous_year' => 'previous year', // 'dropdown.selected_year' => 'year', 'dropdown.all_time' => '전시간', -// TODO: translate the following. -// 'dropdown.time' => 'time', -// 'dropdown.user' => 'user', 'dropdown.projects' => '프로젝트', // TODO: translate the following. // 'dropdown.tasks' => 'tasks', diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 58d3aaaa2..c8346553a 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -250,6 +250,13 @@ 'label.active_users' => 'Actieve medewerkers', 'label.inactive_users' => 'Inactieve medewerkers', +// Entity names. We use lower case (in English) because they are used in dropdowns, too. +// They are used to associate a custom field with an entity type. +// TODO: translate the following. +// 'entity.time' => 'time', +// 'entity.user' => 'user', +// 'entity.project' => 'project', + // Form titles. 'title.error' => 'Fout', 'title.success' => 'Succes', @@ -363,9 +370,6 @@ 'dropdown.previous_year' => 'vorig jaar', 'dropdown.selected_year' => 'jaar', 'dropdown.all_time' => 'alles', -// TODO: translate the following. -// 'dropdown.time' => 'time', -// 'dropdown.user' => 'user', 'dropdown.projects' => 'projecten', 'dropdown.tasks' => 'taken', 'dropdown.clients' => 'klanten', diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index 27d6a91ba..8fb7bf64f 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -289,6 +289,13 @@ // 'label.active_users' => 'Active Users', // 'label.inactive_users' => 'Inactive Users', +// Entity names. We use lower case (in English) because they are used in dropdowns, too. +// They are used to associate a custom field with an entity type. +// TODO: translate the following. +// 'entity.time' => 'time', +// 'entity.user' => 'user', +// 'entity.project' => 'project', + // Form titles. // TODO: Translate the following. // 'title.error' => 'Error', @@ -417,9 +424,6 @@ // 'dropdown.previous_year' => 'previous year', // 'dropdown.selected_year' => 'year', // 'dropdown.all_time' => 'all time', -// TODO: translate the following. -// 'dropdown.time' => 'time', -// 'dropdown.user' => 'user', 'dropdown.projects' => 'prosjekter', // TODO: translate the following. // 'dropdown.tasks' => 'tasks', diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index aa6a2ceff..d77a7b4a0 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -277,6 +277,13 @@ 'label.active_users' => 'Aktywni użytkownicy', 'label.inactive_users' => 'Nieaktywni użytkownicy', +// Entity names. We use lower case (in English) because they are used in dropdowns, too. +// They are used to associate a custom field with an entity type. +// TODO: translate the following. +// 'entity.time' => 'time', +// 'entity.user' => 'user', +// 'entity.project' => 'project', + // Form titles. 'title.error' => 'Błąd', // TODO: Translate the following. @@ -399,9 +406,6 @@ // 'dropdown.previous_year' => 'previous year', 'dropdown.selected_year' => 'rok', 'dropdown.all_time' => 'od początku', -// TODO: translate the following. -// 'dropdown.time' => 'time', -// 'dropdown.user' => 'user', 'dropdown.projects' => 'projekty', 'dropdown.tasks' => 'zadania', 'dropdown.clients' => 'klienci', diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index 3d1d0abe8..7165cb51e 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -274,6 +274,13 @@ 'label.active_users' => 'Usuários ativos', 'label.inactive_users' => 'Usuários inativos', +// Entity names. We use lower case (in English) because they are used in dropdowns, too. +// They are used to associate a custom field with an entity type. +// TODO: translate the following. +// 'entity.time' => 'time', +// 'entity.user' => 'user', +// 'entity.project' => 'project', + // Form titles. 'title.error' => 'Erro', // TODO: Translate the following. @@ -394,9 +401,6 @@ // 'dropdown.previous_year' => 'previous year', 'dropdown.selected_year' => 'ano', 'dropdown.all_time' => 'todas as datas', -// TODO: translate the following. -// 'dropdown.time' => 'time', -// 'dropdown.user' => 'user', 'dropdown.projects' => 'projetos', 'dropdown.tasks' => 'tarefas', 'dropdown.clients' => 'clientes', diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index 2720464a2..6c002439d 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -277,6 +277,13 @@ // 'label.active_users' => 'Active Users', // 'label.inactive_users' => 'Inactive Users', +// Entity names. We use lower case (in English) because they are used in dropdowns, too. +// They are used to associate a custom field with an entity type. +// TODO: translate the following. +// 'entity.time' => 'time', +// 'entity.user' => 'user', +// 'entity.project' => 'project', + // Form titles. // TODO: Translate the following. // 'title.error' => 'Error', @@ -402,9 +409,6 @@ // 'dropdown.previous_year' => 'previous year', // 'dropdown.selected_year' => 'year', // 'dropdown.all_time' => 'all time', -// TODO: translate the following. -// 'dropdown.time' => 'time', -// 'dropdown.user' => 'user', 'dropdown.projects' => 'projetos', // TODO: translate the following. // 'dropdown.tasks' => 'tasks', diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index 64b4551cc..a66f5e4e6 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -289,6 +289,13 @@ // 'label.active_users' => 'Active Users', // 'label.inactive_users' => 'Inactive Users', +// Entity names. We use lower case (in English) because they are used in dropdowns, too. +// They are used to associate a custom field with an entity type. +// TODO: translate the following. +// 'entity.time' => 'time', +// 'entity.user' => 'user', +// 'entity.project' => 'project', + // Form titles. // TODO: Improve titles for consistency, so that each title explains correctly what each // page is about and is "consistent" from page to page, meaning that correct grammar is used everywhere. @@ -420,8 +427,6 @@ // 'dropdown.previous_year' => 'previous year', // 'dropdown.selected_year' => 'year', // 'dropdown.all_time' => 'all time', -// 'dropdown.time' => 'time', -// 'dropdown.user' => 'user', 'dropdown.projects' => 'proiecte', // TODO: translate the following. // 'dropdown.tasks' => 'tasks', diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index 980aa466e..93c88dd83 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -247,6 +247,12 @@ 'label.active_users' => 'Активные пользователи', 'label.inactive_users' => 'Неактивные пользователи', +// Entity names. We use lower case (in English) because they are used in dropdowns, too. +// They are used to associate a custom field with an entity type. +'entity.time' => 'время', +'entity.user' => 'пользователь', +'entity.project' => 'проект', + // Form titles. 'title.error' => 'Ошибка', 'title.success' => 'Успех', @@ -360,8 +366,6 @@ 'dropdown.previous_year' => 'прошлый год', 'dropdown.selected_year' => 'год', 'dropdown.all_time' => 'всё время', -'dropdown.time' => 'время', -'dropdown.user' => 'пользователь', 'dropdown.projects' => 'проекты', 'dropdown.tasks' => 'задачи', 'dropdown.clients' => 'клиенты', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index 56d14f665..a1ebcb555 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -281,6 +281,13 @@ 'label.active_users' => 'Aktívny používatelia', 'label.inactive_users' => 'Neaktívny používatelia', +// Entity names. We use lower case (in English) because they are used in dropdowns, too. +// They are used to associate a custom field with an entity type. +// TODO: translate the following. +// 'entity.time' => 'time', +// 'entity.user' => 'user', +// 'entity.project' => 'project', + // Form titles. 'title.error' => 'Chyba', // TODO: Translate the following. @@ -403,9 +410,6 @@ // 'dropdown.previous_year' => 'previous year', 'dropdown.selected_year' => 'rok', 'dropdown.all_time' => 'celý čas', -// TODO: translate the following. -// 'dropdown.time' => 'time', -// 'dropdown.user' => 'user', 'dropdown.projects' => 'projekty', 'dropdown.tasks' => 'úlohy', // TODO: translate the following. diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index db54f19e1..0dac806e9 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -272,6 +272,13 @@ // 'label.active_users' => 'Active Users', // 'label.inactive_users' => 'Inactive Users', +// Entity names. We use lower case (in English) because they are used in dropdowns, too. +// They are used to associate a custom field with an entity type. +// TODO: translate the following. +// 'entity.time' => 'time', +// 'entity.user' => 'user', +// 'entity.project' => 'project', + // Form titles. // TODO: Translate the following. // 'title.error' => 'Error', @@ -394,8 +401,6 @@ // 'dropdown.previous_year' => 'previous year', // 'dropdown.selected_year' => 'year', // 'dropdown.all_time' => 'all time', -// 'dropdown.time' => 'time', -// 'dropdown.user' => 'user', 'dropdown.projects' => 'projekti', // TODO: translate the following. // 'dropdown.tasks' => 'tasks', diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index eb8f3ebf0..e73ae4648 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -275,6 +275,13 @@ 'label.active_users' => 'Aktivni korisnik', 'label.inactive_users' => 'Neaktivni korisnik', +// Entity names. We use lower case (in English) because they are used in dropdowns, too. +// They are used to associate a custom field with an entity type. +// TODO: translate the following. +// 'entity.time' => 'time', +// 'entity.user' => 'user', +// 'entity.project' => 'project', + // Form titles. 'title.error' => 'Greška', // TODO: Translate the following. @@ -397,9 +404,6 @@ // 'dropdown.previous_year' => 'previous year', 'dropdown.selected_year' => 'godina', 'dropdown.all_time' => 'svi datumi', -// TODO: translate the following. -// 'dropdown.time' => 'time', -// 'dropdown.user' => 'user', 'dropdown.projects' => 'projekti', 'dropdown.tasks' => 'zadaci', 'dropdown.clients' => 'klijenti', diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index c17662baa..c6bf2f413 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -272,6 +272,13 @@ 'label.active_users' => 'Aktiva användare', 'label.inactive_users' => 'Inaktiva användare', +// Entity names. We use lower case (in English) because they are used in dropdowns, too. +// They are used to associate a custom field with an entity type. +// TODO: translate the following. +// 'entity.time' => 'time', +// 'entity.user' => 'user', +// 'entity.project' => 'project', + // Rubriker för formulär 'title.error' => 'Fel', // TODO: Translate the following. @@ -396,9 +403,6 @@ 'dropdown.previous_year' => 'Föregående år', 'dropdown.selected_year' => 'År', 'dropdown.all_time' => 'Livstid', -// TODO: translate the following. -// 'dropdown.time' => 'time', -// 'dropdown.user' => 'user', 'dropdown.projects' => 'Projekt', 'dropdown.tasks' => 'Arbetsuppgifter', 'dropdown.clients' => 'Kunder', diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index 5701f5621..d07275ffc 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -296,6 +296,13 @@ // 'label.active_users' => 'Active Users', // 'label.inactive_users' => 'Inactive Users', +// Entity names. We use lower case (in English) because they are used in dropdowns, too. +// They are used to associate a custom field with an entity type. +// TODO: translate the following. +// 'entity.time' => 'time', +// 'entity.user' => 'user', +// 'entity.project' => 'project', + // Form titles. // Form titles. // TODO: Improve titles for consistency, so that each title explains correctly what each @@ -428,9 +435,6 @@ // 'dropdown.previous_year' => 'previous year', // 'dropdown.selected_year' => 'year', 'dropdown.all_time' => 'tüm zamanlar', -// TODO: translate the following. -// 'dropdown.time' => 'time', -// 'dropdown.user' => 'user', 'dropdown.projects' => 'projeler', // TODO: translate the following. // 'dropdown.tasks' => 'tasks', diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index dce6df857..e5244c073 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -281,6 +281,13 @@ // 'label.active_users' => 'Active Users', // 'label.inactive_users' => 'Inactive Users', +// Entity names. We use lower case (in English) because they are used in dropdowns, too. +// They are used to associate a custom field with an entity type. +// TODO: translate the following. +// 'entity.time' => 'time', +// 'entity.user' => 'user', +// 'entity.project' => 'project', + // Form titles. // TODO: Translate the following. // 'title.error' => 'Error', @@ -409,9 +416,6 @@ // 'dropdown.previous_year' => 'previous year', // 'dropdown.selected_year' => 'year', 'dropdown.all_time' => '全部时间', -// TODO: translate the following. -// 'dropdown.time' => 'time', -// 'dropdown.user' => 'user', 'dropdown.projects' => '项目', // TODO: translate the following. // 'dropdown.tasks' => 'tasks', diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index a18cb213b..f5d9e9b30 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -287,6 +287,13 @@ // 'label.active_users' => 'Active Users', // 'label.inactive_users' => 'Inactive Users', +// Entity names. We use lower case (in English) because they are used in dropdowns, too. +// They are used to associate a custom field with an entity type. +// TODO: translate the following. +// 'entity.time' => 'time', +// 'entity.user' => 'user', +// 'entity.project' => 'project', + // Form titles. // TODO: Translate the following. // 'title.error' => 'Error', @@ -414,9 +421,6 @@ // 'dropdown.previous_year' => 'previous year', 'dropdown.selected_year' => '年', 'dropdown.all_time' => '全部時間', -// TODO: translate the following. -// 'dropdown.time' => 'time', -// 'dropdown.user' => 'user', 'dropdown.projects' => '項目', // TODO: translate the following. // 'dropdown.tasks' => 'tasks', diff --git a/WEB-INF/templates/cf_custom_fields.tpl b/WEB-INF/templates/cf_custom_fields.tpl index 5d254e9cc..e64f18157 100644 --- a/WEB-INF/templates/cf_custom_fields.tpl +++ b/WEB-INF/templates/cf_custom_fields.tpl @@ -5,7 +5,8 @@ {if $user->can('manage_custom_fields')} - + + @@ -15,6 +16,13 @@ {foreach $custom_fields as $field} + {if CustomFields::ENTITY_TIME == $field['entity_type']} + + {elseif CustomFields::ENTITY_USER == $field['entity_type']} + + {else} + + {/if} {if CustomFields::TYPE_TEXT == $field['type']} diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 3beac6413..23519575d 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
{$i18n.label.thing_name}{$i18n.label.thing_name}{$i18n.label.entity} {$i18n.label.type} {$i18n.menu.options}
{$field['label']|escape}{$i18n.entity.time}{$i18n.entity.user}{$i18n.label.type_text}
-
 Anuko Time Tracker 1.19.6.5020 | Copyright © Anuko | +  Anuko Time Tracker 1.19.6.5021 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/cf_custom_field_add.php b/cf_custom_field_add.php index e4a919eb5..e8de69e7e 100644 --- a/cf_custom_field_add.php +++ b/cf_custom_field_add.php @@ -41,7 +41,7 @@ } $fields = CustomFields::getFields(); // Deny access when max number of custom fields is already set. -if (count($fields) >= 1) { +if (count($fields) >= 1 && !isTrue('CF_DEBUG')) { header('Location: access_denied.php'); exit(); } @@ -59,8 +59,8 @@ $form = new Form('fieldForm'); $form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'name','value'=>'')); $form->addInput(array('type'=>'combobox','name'=>'entity', - 'data'=>array(CustomFields::ENTITY_TIME=>$i18n->get('dropdown.time'), - CustomFields::ENTITY_USER=>$i18n->get('dropdown.user')) + 'data'=>array(CustomFields::ENTITY_TIME=>$i18n->get('entity.time'), + CustomFields::ENTITY_USER=>$i18n->get('entity.user')) )); $form->addInput(array('type'=>'combobox','name'=>'type', 'data'=>array(CustomFields::TYPE_TEXT=>$i18n->get('label.type_text'), diff --git a/cf_custom_fields.php b/cf_custom_fields.php index 6de626cc9..d877e7c46 100644 --- a/cf_custom_fields.php +++ b/cf_custom_fields.php @@ -54,7 +54,7 @@ $fields = CustomFields::getFields(); // At this time only one custom field is supported. Disable the Add button if we already have one or more custom fields. - if (count($fields) > 0) + if (count($fields) > 0 && !isTrue('CF_DEBUG')) $form->getElement('btn_add')->setEnabled(false); } diff --git a/plugins/CustomFields.class.php b/plugins/CustomFields.class.php index a0c49ec56..f36a42638 100644 --- a/plugins/CustomFields.class.php +++ b/plugins/CustomFields.class.php @@ -249,12 +249,12 @@ static function getFields() { $org_id = $user->org_id; $fields = array(); - $sql = "select id, type, label from tt_custom_fields". + $sql = "select id, entity_type, type, label from tt_custom_fields". " where group_id = $group_id and org_id = $org_id and status = 1 and type > 0"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { while ($val = $res->fetchRow()) { - $fields[] = array('id'=>$val['id'],'type'=>$val['type'],'label'=>$val['label']); + $fields[] = $val; // array('id'=>$val['id'],'type'=>$val['type'],'label'=>$val['label']); } return $fields; } @@ -308,8 +308,8 @@ static function insertField($field_name, $entity_type, $field_type, $required) { $group_id = $user->getGroup(); $org_id = $user->org_id; - $sql = "insert into tt_custom_fields (group_id, org_id, type, label, required, status)". - " values($group_id, $org_id, $field_type, ".$mdb2->quote($field_name).", $required, 1)"; + $sql = "insert into tt_custom_fields (group_id, org_id, entity_type, type, label, required, status)". + " values($group_id, $org_id, $entity_type, $field_type, ".$mdb2->quote($field_name).", $required, 1)"; $affected = $mdb2->exec($sql); return (!is_a($affected, 'PEAR_Error')); } From 066efce7ef712710e229308b6099f5af410aecb8 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 28 Jun 2019 16:37:21 +0000 Subject: [PATCH 010/877] Introduced tt_entity_custom_fields table. --- WEB-INF/templates/footer.tpl | 2 +- cf_custom_field_edit.php | 2 +- dbinstall.php | 11 +++++++---- mysql.sql | 32 +++++++++++++++++++++++++++++++- plugins/CustomFields.class.php | 2 +- 5 files changed, 41 insertions(+), 8 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 23519575d..9888b8675 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- - - + +
 Anuko Time Tracker 1.19.6.5021 | Copyright © Anuko | +  Anuko Time Tracker 1.19.7.5022 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/cf_custom_field_edit.php b/cf_custom_field_edit.php index 0bf5818d8..c5dd09040 100644 --- a/cf_custom_field_edit.php +++ b/cf_custom_field_edit.php @@ -51,10 +51,10 @@ if ($err->no()) { $form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'name','value'=>$field['label'])); $form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_id)); - $form->addInput(array('type'=>'checkbox','name'=>'required','value'=>$field['required'])); $form->addInput(array('type'=>'combobox','name'=>'type','value'=>$field['type'], 'data'=>array(CustomFields::TYPE_TEXT=>$i18n->get('label.type_text'), CustomFields::TYPE_DROPDOWN=>$i18n->get('label.type_dropdown')))); + $form->addInput(array('type'=>'checkbox','name'=>'required','value'=>$field['required'])); $form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); } diff --git a/dbinstall.php b/dbinstall.php index 6a65336ae..c2ce26180 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -1161,7 +1161,7 @@ function ttGenerateKeys() { ttExecute("UPDATE `tt_site_config` SET param_value = '1.19.0', modified = now() where param_name = 'version_db' and param_value = '1.18.61'"); } - if ($_POST["convert11900to11906"]) { + if ($_POST["convert11900to11907"]) { ttExecute("CREATE TABLE `tt_work_currencies` (`id` int(10) unsigned NOT NULL,`name` varchar(10) NOT NULL,PRIMARY KEY (`id`))"); ttExecute("create unique index currency_idx on tt_work_currencies(`name`)"); ttExecute("INSERT INTO `tt_work_currencies` (`id`, `name`) VALUES ('1', 'USD'), ('2', 'CAD'), ('3', 'AUD'), ('4', 'EUR'), ('5', 'NZD')"); @@ -1177,6 +1177,9 @@ function ttGenerateKeys() { ttExecute("update `tt_custom_fields` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.19.4') set entity_type = 1 where entity_type = 'time'"); ttExecute("ALTER TABLE `tt_custom_fields` modify entity_type tinyint(4) NOT NULL default '1'"); ttExecute("UPDATE `tt_site_config` SET param_value = '1.19.6', modified = now() where param_name = 'version_db' and param_value = '1.19.4'"); + ttExecute("CREATE TABLE `tt_entity_custom_fields` (`id` int(10) unsigned NOT NULL auto_increment,`group_id` int(10) unsigned NOT NULL,`org_id` int(10) unsigned NOT NULL,`entity_type` tinyint(4) NOT NULL,`entity_id` int(10) unsigned NOT NULL,`field_id` int(10) unsigned NOT NULL,`option_id` int(10) unsigned default NULL,`value` varchar(255) default NULL,`created` datetime default NULL,`created_ip` varchar(45) default NULL,`created_by` int(10) unsigned default NULL,`modified` datetime default NULL,`modified_ip` varchar(45) default NULL,`modified_by` int(10) unsigned default NULL,`status` tinyint(4) default 1,PRIMARY KEY (`id`))"); + ttExecute("create unique index entity_idx on tt_entity_custom_fields(entity_type, entity_id, field_id)"); + ttExecute("UPDATE `tt_site_config` SET param_value = '1.19.7', modified = now() where param_name = 'version_db' and param_value = '1.19.6'"); } if ($_POST["cleanup"]) { @@ -1226,7 +1229,7 @@ function ttGenerateKeys() {

DB Install

-
Create database structure (v1.19.6) + Create database structure (v1.19.7)
(applies only to new installations, do not execute when updating)
@@ -1275,8 +1278,8 @@ function ttGenerateKeys() {
Update database structure (v1.19 to v1.19.6)Update database structure (v1.19 to v1.19.7)
diff --git a/mysql.sql b/mysql.sql index fc67b19f4..b8d7e134c 100644 --- a/mysql.sql +++ b/mysql.sql @@ -423,6 +423,36 @@ CREATE TABLE `tt_custom_field_log` ( create index log_idx on tt_custom_field_log(log_id); +# +# Structure for table tt_entity_custom_fields. +# This table stores custom field values for entities such as users and projects +# except for "time" entity (and possibly "expense" in future). +# "time" custom fields are kept separately in tt_custom_field_log +# because tt_log (and tt_custom_field_log) can grow very large. +# +CREATE TABLE `tt_entity_custom_fields` ( + `id` int(10) unsigned NOT NULL auto_increment, # record id in this table + `group_id` int(10) unsigned NOT NULL, # group id + `org_id` int(10) unsigned NOT NULL, # organization id + `entity_type` tinyint(4) NOT NULL, # entity type + `entity_id` int(10) unsigned NOT NULL, # entity id this record corresponds to + `field_id` int(10) unsigned NOT NULL, # custom field id + `option_id` int(10) unsigned default NULL, # Option id. Used for dropdown custom fields. + `value` varchar(255) default NULL, # Text value. Used for text custom fields. + `created` datetime default NULL, # creation timestamp + `created_ip` varchar(45) default NULL, # creator ip + `created_by` int(10) unsigned default NULL, # creator user_id + `modified` datetime default NULL, # modification timestamp + `modified_ip` varchar(45) default NULL, # modifier ip + `modified_by` int(10) unsigned default NULL, # modifier user_id + `status` tinyint(4) default 1, # record status + PRIMARY KEY (`id`) +); + +# Create an index that guarantees unique custom fields per entity. +create unique index entity_idx on tt_entity_custom_fields(entity_type, entity_id, field_id); + + # # Structure for table tt_expense_items. # This table lists expense items. @@ -611,4 +641,4 @@ CREATE TABLE `tt_site_config` ( PRIMARY KEY (`param_name`) ); -INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.19.6', now()); # TODO: change when structure changes. +INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.19.7', now()); # TODO: change when structure changes. diff --git a/plugins/CustomFields.class.php b/plugins/CustomFields.class.php index f36a42638..125e100b4 100644 --- a/plugins/CustomFields.class.php +++ b/plugins/CustomFields.class.php @@ -254,7 +254,7 @@ static function getFields() { $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { while ($val = $res->fetchRow()) { - $fields[] = $val; // array('id'=>$val['id'],'type'=>$val['type'],'label'=>$val['label']); + $fields[] = $val; } return $fields; } From 19b674dca67d52e7ec2ea49046f31e68fc6facf4 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 29 Jun 2019 14:08:59 +0000 Subject: [PATCH 011/877] Refactoring custom fields in progress. --- WEB-INF/templates/footer.tpl | 2 +- mobile/time.php | 2 +- mobile/time_edit.php | 2 +- mobile/timer.php | 2 +- plugins/CustomFields.class.php | 32 +++++++++++++++----------------- reports.php | 4 ++-- time.php | 2 +- time_edit.php | 2 +- user_add.php | 12 ++++++++++++ week.php | 2 +- 10 files changed, 36 insertions(+), 26 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 9888b8675..47814a16b 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- + + + + diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 47814a16b..46167ca4c 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.19.7.5022 | Copyright © Anuko | +  Anuko Time Tracker 1.19.7.5023 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/mobile/time.php b/mobile/time.php index 5a5c054d6..996521691 100644 --- a/mobile/time.php +++ b/mobile/time.php @@ -223,7 +223,7 @@ $form->addInput(array('type'=>'combobox','name'=>'cf_1', 'style'=>'width: 250px;', 'value'=>$cl_cf_1, - 'data'=>$custom_fields->options, + 'data'=>CustomFields::getOptions($custom_fields->fields[0]['id']), 'empty'=>array(''=>$i18n->get('dropdown.select')))); } } diff --git a/mobile/time_edit.php b/mobile/time_edit.php index 364ebaf82..c3a7ccd78 100644 --- a/mobile/time_edit.php +++ b/mobile/time_edit.php @@ -199,7 +199,7 @@ 'name'=>'cf_1', 'style'=>'width: 250px;', 'value'=>$cl_cf_1, - 'data'=>$custom_fields->options, + 'data'=>CustomFields::getOptions($custom_fields->fields[0]['id']), 'empty' => array('' => $i18n->get('dropdown.select')))); } } diff --git a/mobile/timer.php b/mobile/timer.php index 667536324..d814637f6 100644 --- a/mobile/timer.php +++ b/mobile/timer.php @@ -173,7 +173,7 @@ $form->addInput(array('type'=>'combobox','name'=>'cf_1', 'style'=>'width: 250px;', 'value'=>$cl_cf_1, - 'data'=>$custom_fields->options, + 'data'=>CustomFields::getOptions($custom_fields->fields[0]['id']), 'empty'=>array(''=>$i18n->get('dropdown.select')) )); } diff --git a/plugins/CustomFields.class.php b/plugins/CustomFields.class.php index 125e100b4..4494d58e8 100644 --- a/plugins/CustomFields.class.php +++ b/plugins/CustomFields.class.php @@ -33,11 +33,16 @@ class CustomFields { const ENTITY_USER = 2; // Field is associated with users. const ENTITY_PROJECT = 3; // Field is associated with projects. - const TYPE_TEXT = 1; // A text field. - const TYPE_DROPDOWN = 2; // A dropdown field with pre-defined values. + const TYPE_TEXT = 1; // A text field. + const TYPE_DROPDOWN = 2; // A dropdown field with pre-defined values. + // TODO: replace $fields with entity-specific arrays: timeFields, userFields, etc. var $fields = array(); // Array of custom fields for group. - var $options = array(); // Array of options for a dropdown custom field. + + // Refactoring ongoing... + var $timeFields = null; + var $userFields = null; + var $projectFields = null; // Constructor. function __construct() { @@ -48,25 +53,18 @@ function __construct() { $org_id = $user->org_id; // Get fields. - $sql = "select id, type, label, required from tt_custom_fields". + $sql = "select id, entity_type, type, label, required from tt_custom_fields". " where group_id = $group_id and org_id = $org_id and status = 1 and type > 0"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { while ($val = $res->fetchRow()) { $this->fields[] = array('id'=>$val['id'],'type'=>$val['type'],'label'=>$val['label'],'required'=>$val['required'],'value'=>''); - } - } - - // If we have a dropdown obtain options for it. - if ((count($this->fields) > 0) && ($this->fields[0]['type'] == CustomFields::TYPE_DROPDOWN)) { - - $sql = "select id, value from tt_custom_field_options". - " where field_id = ".$this->fields[0]['id']." and group_id = $group_id and org_id = $org_id and status = 1 order by value"; - $res = $mdb2->query($sql); - if (!is_a($res, 'PEAR_Error')) { - while ($val = $res->fetchRow()) { - $this->options[$val['id']] = $val['value']; - } + if (CustomFields::ENTITY_TIME == $val['entity_type']) + $this->timeFields[] = $val; + else if (CustomFields::ENTITY_USER == $val['entity_type']) + $this->userFields[] = $val; + else if (CustomFields::ENTITY_PROJECT == $val['entity_type']) + $this->projectFields[] = $val; } } } diff --git a/reports.php b/reports.php index fe545b211..aa492061a 100644 --- a/reports.php +++ b/reports.php @@ -58,7 +58,7 @@ $showCustomFieldCheckbox = $custom_fields->fields[0]; $showCustomFieldDropdown = $custom_fields->fields[0] && $custom_fields->fields[0]['type'] == CustomFields::TYPE_DROPDOWN; if ($showCustomFieldDropdown) - $showCustomFieldDropdown &= count($custom_fields->options) > 0; + $showCustomFieldDropdown &= CustomFields::getOptions($custom_fields->fields[0]['id']); } $form = new Form('reportForm'); @@ -102,7 +102,7 @@ $form->addInput(array('type'=>'combobox','name'=>'option', 'style'=>'width: 250px;', 'value'=>$cl_cf_1, - 'data'=>$custom_fields->options, + 'data'=>CustomFields::getOptions($custom_fields->fields[0]['id']), 'empty'=>array(''=>$i18n->get('dropdown.all')))); } diff --git a/time.php b/time.php index 2dc8606d0..f058a21a5 100644 --- a/time.php +++ b/time.php @@ -280,7 +280,7 @@ $form->addInput(array('type'=>'combobox','name'=>'cf_1', 'style'=>'width: 250px;', 'value'=>$cl_cf_1, - 'data'=>$custom_fields->options, + 'data'=>CustomFields::getOptions($custom_fields->fields[0]['id']), 'empty'=>array(''=>$i18n->get('dropdown.select')))); } } diff --git a/time_edit.php b/time_edit.php index bb0457384..aceff0243 100644 --- a/time_edit.php +++ b/time_edit.php @@ -202,7 +202,7 @@ 'name'=>'cf_1', 'style'=>'width: 250px;', 'value'=>$cl_cf_1, - 'data'=>$custom_fields->options, + 'data'=>CustomFields::getOptions($custom_fields->fields[0]['id']), 'empty' => array('' => $i18n->get('dropdown.select')))); } } diff --git a/user_add.php b/user_add.php index 5696d28fa..56bd69b3c 100644 --- a/user_add.php +++ b/user_add.php @@ -50,6 +50,13 @@ if ($user->isPluginEnabled('cl')) $clients = ttGroupHelper::getActiveClients(); +// Use custom fields plugin if it is enabled. +if ($user->isPluginEnabled('cf')) { + require_once('plugins/CustomFields.class.php'); + $custom_fields = new CustomFields(); + $smarty->assign('custom_fields', $custom_fields); +} + $assigned_projects = array(); if ($request->isPost()) { $cl_name = trim($request->getParameter('name')); @@ -91,6 +98,11 @@ if ($user->isPluginEnabled('cl')) $form->addInput(array('type'=>'combobox','name'=>'client','value'=>$cl_client_id,'data'=>$clients,'datakeys'=>array('id', 'name'),'empty'=>array(''=>$i18n->get('dropdown.select')))); +// If we have custom fields - add controls for them. +if ($custom_fields && $custom_fields->userFields) { + // Coding in progress... +} + $form->addInput(array('type'=>'floatfield','maxlength'=>'10','name'=>'rate','format'=>'.2','value'=>$cl_rate)); if ($show_quota) $form->addInput(array('type'=>'floatfield','maxlength'=>'10','name'=>'quota_percent','format'=>'.2','value'=>$cl_quota_percent)); diff --git a/week.php b/week.php index 1c8efe75a..9af356441 100644 --- a/week.php +++ b/week.php @@ -338,7 +338,7 @@ function render(&$table, $value, $row, $column, $selected = false) { $form->addInput(array('type'=>'combobox','name'=>'cf_1', 'style'=>'width: 250px;', 'value'=>$cl_cf_1, - 'data'=>$custom_fields->options, + 'data'=>CustomFields::getOptions($custom_fields->fields[0]['id']), 'empty'=>array(''=>$i18n->get('dropdown.select')))); } } From 8b16d7c0b05921ad6d90c1e5342c02d62b093414 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 29 Jun 2019 15:58:39 +0000 Subject: [PATCH 012/877] Added entity type as read only field on custom field edit page. --- WEB-INF/templates/cf_custom_field_edit.tpl | 4 ++++ WEB-INF/templates/footer.tpl | 2 +- cf_custom_field_edit.php | 11 +++++++++++ plugins/CustomFields.class.php | 2 +- 4 files changed, 17 insertions(+), 2 deletions(-) diff --git a/WEB-INF/templates/cf_custom_field_edit.tpl b/WEB-INF/templates/cf_custom_field_edit.tpl index beabbe7dd..62e2a267e 100644 --- a/WEB-INF/templates/cf_custom_field_edit.tpl +++ b/WEB-INF/templates/cf_custom_field_edit.tpl @@ -8,6 +8,10 @@ {$i18n.label.thing_name} (*): {$forms.fieldForm.name.control}
{$i18n.label.entity}:{$forms.fieldForm.entity.control} {$i18n.label.what_is_it}
{$i18n.label.type}: {$forms.fieldForm.type.control}
-
 Anuko Time Tracker 1.19.7.5023 | Copyright © Anuko | +  Anuko Time Tracker 1.19.7.5024 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/cf_custom_field_edit.php b/cf_custom_field_edit.php index c5dd09040..79ce1310b 100644 --- a/cf_custom_field_edit.php +++ b/cf_custom_field_edit.php @@ -51,6 +51,17 @@ if ($err->no()) { $form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'name','value'=>$field['label'])); $form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_id)); + + // TODO: consider encapsulating this block in a function. + $entity_type = $field['entity_type']; + if (CustomFields::ENTITY_TIME == $entity_type) + $entity = $i18n->get('entity.time'); + else if (CustomFields::ENTITY_USER == $entity_type) + $entity = $i18n->get('entity.user'); + else if (CustomFields::ENTITY_PROJECT == $entity_type) + $entity = $i18n->get('entity.project'); + $form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'entity','value'=>$entity,'enable'=>false)); + $form->addInput(array('type'=>'combobox','name'=>'type','value'=>$field['type'], 'data'=>array(CustomFields::TYPE_TEXT=>$i18n->get('label.type_text'), CustomFields::TYPE_DROPDOWN=>$i18n->get('label.type_dropdown')))); diff --git a/plugins/CustomFields.class.php b/plugins/CustomFields.class.php index 4494d58e8..d58cbe539 100644 --- a/plugins/CustomFields.class.php +++ b/plugins/CustomFields.class.php @@ -267,7 +267,7 @@ static function getField($id) { $group_id = $user->getGroup(); $org_id = $user->org_id; - $sql = "select label, type, required from tt_custom_fields". + $sql = "select label, entity_type, type, required from tt_custom_fields". " where id = $id and group_id = $group_id and org_id = $org_id"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { From e5129e06ab4547945e1ad3097e4193930465f93f Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 30 Jun 2019 12:57:20 +0000 Subject: [PATCH 013/877] Added custom field controls on user_add.php. --- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/user_add.tpl | 11 +++++++++++ user_add.php | 12 +++++++++++- 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 46167ca4c..ab50afe50 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- {/if} +{if $custom_fields && $custom_fields->userFields} + {foreach $custom_fields->userFields as $userField} + + + {assign var="control_name" value='user_field_'|cat:$userField['id']} + + + {/foreach} +{/if} + + diff --git a/user_add.php b/user_add.php index 56bd69b3c..a3d956ea6 100644 --- a/user_add.php +++ b/user_add.php @@ -100,7 +100,17 @@ // If we have custom fields - add controls for them. if ($custom_fields && $custom_fields->userFields) { - // Coding in progress... + foreach ($custom_fields->userFields as $userField) { + $field_name = 'user_field_'.$userField['id']; + if ($userField['type'] == CustomFields::TYPE_TEXT) { + $form->addInput(array('type'=>'text','name'=>$field_name)); + } elseif ($userField['type'] == CustomFields::TYPE_DROPDOWN) { + $form->addInput(array('type'=>'combobox','name'=>$field_name, + 'style'=>'width: 250px;', + 'data'=>CustomFields::getOptions($userField['id']), + 'empty'=>array(''=>$i18n->get('dropdown.select')))); + } + } } $form->addInput(array('type'=>'floatfield','maxlength'=>'10','name'=>'rate','format'=>'.2','value'=>$cl_rate)); From e60cc9646c000aedf94c2845337532001fdb5520 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 30 Jun 2019 13:55:11 +0000 Subject: [PATCH 014/877] Added user input validation for custom fields on user_add.php. --- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/user_add.tpl | 2 -- user_add.php | 14 +++++++++++++- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index ab50afe50..8fe67f337 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.19.7.5024 | Copyright © Anuko | +  Anuko Time Tracker 1.19.7.5025 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/user_add.tpl b/WEB-INF/templates/user_add.tpl index 155bf11cc..3f00c3591 100644 --- a/WEB-INF/templates/user_add.tpl +++ b/WEB-INF/templates/user_add.tpl @@ -100,6 +100,17 @@ function handleClientControl() { {$forms.userForm.quota_percent.control} {$i18n.label.what_is_it}
{$userField['label']|escape}{if $userField['required']} (*){/if}:{$forms.userForm.$control_name.control}
{$i18n.form.users.default_rate} (0{$user->getDecimalMark()}00): {$forms.userForm.rate.control}
- {/foreach} {/if} - - diff --git a/user_add.php b/user_add.php index a3d956ea6..d6a24e3aa 100644 --- a/user_add.php +++ b/user_add.php @@ -172,8 +172,20 @@ function render(&$table, $value, $row, $column, $selected = false) { if (!ttValidEmail($cl_email, true)) $err->add($i18n->get('error.field'), $i18n->get('label.email')); // Require selection of a client for a client role. if ($user->isPluginEnabled('cl') && ttRoleHelper::isClientRole($cl_role_id) && !$cl_client_id) $err->add($i18n->get('error.client')); - if (!ttValidFloat($cl_rate, true)) $err->add($i18n->get('error.field'), $i18n->get('form.users.default_rate')); if (!ttValidFloat($cl_quota_percent, true)) $err->add($i18n->get('error.field'), $i18n->get('label.quota')); + // Validate input in user custom fields. + if ($custom_fields && $custom_fields->userFields) { + foreach ($custom_fields->userFields as $userField) { + $control_name = 'user_field_'.$userField['id']; + $field_label = htmlspecialchars($userField['label']); + $field_type = $userField['type']; + $required = $userField['required']; + $field_value = trim($request->getParameter($control_name)); + // Validation is the same for text and dropdown fields. + if (!ttValidString($field_value, !$required)) $err->add($i18n->get('error.field'), $field_label); + } + } + if (!ttValidFloat($cl_rate, true)) $err->add($i18n->get('error.field'), $i18n->get('form.users.default_rate')); if (!ttUserHelper::canAdd()) $err->add($i18n->get('error.user_count')); if ($err->no()) { From 6ec11c42ae150bf58d54aa9b64600156e0a608f0 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 30 Jun 2019 15:40:54 +0000 Subject: [PATCH 015/877] A bit of refactoring in user_add.php. --- WEB-INF/templates/footer.tpl | 2 +- user_add.php | 39 +++++++++++++++++++++++++++--------- 2 files changed, 30 insertions(+), 11 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 8fe67f337..f03277b8a 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.19.7.5025 | Copyright © Anuko | +  Anuko Time Tracker 1.19.7.5026 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/user_add.tpl b/WEB-INF/templates/user_add.tpl index 3f00c3591..35040f3c4 100644 --- a/WEB-INF/templates/user_add.tpl +++ b/WEB-INF/templates/user_add.tpl @@ -109,8 +109,6 @@ function handleClientControl() {
{$i18n.form.users.default_rate} (0{$user->getDecimalMark()}00): {$forms.userForm.rate.control}
-
 Anuko Time Tracker 1.19.7.5026 | Copyright © Anuko | +  Anuko Time Tracker 1.19.7.5027 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/user_add.php b/user_add.php index d6a24e3aa..83f3bbcb2 100644 --- a/user_add.php +++ b/user_add.php @@ -68,8 +68,20 @@ $cl_email = trim($request->getParameter('email')); $cl_role_id = $request->getParameter('role'); $cl_client_id = $request->getParameter('client'); - $cl_rate = $request->getParameter('rate'); $cl_quota_percent = $request->getParameter('quota_percent'); + // If we have user custom fields - collect input. + if ($custom_fields && $custom_fields->userFields) { + foreach ($custom_fields->userFields as $userField) { + $control_name = 'user_field_'.$userField['id']; + $userCustomFields[$userField['id']] = array('field_id' => $userField['id'], + 'control_name' => $control_name, + 'label' => $userField['label'], + 'type' => $userField['type'], + 'required' => $userField['required'], + 'value' => trim($request->getParameter($control_name))); + } + } + $cl_rate = $request->getParameter('rate'); $cl_projects = $request->getParameter('projects'); if (is_array($cl_projects)) { foreach ($cl_projects as $p) { @@ -103,11 +115,12 @@ foreach ($custom_fields->userFields as $userField) { $field_name = 'user_field_'.$userField['id']; if ($userField['type'] == CustomFields::TYPE_TEXT) { - $form->addInput(array('type'=>'text','name'=>$field_name)); + $form->addInput(array('type'=>'text','name'=>$field_name,'value'=>$userCustomFields[$userField['id']]['value'])); } elseif ($userField['type'] == CustomFields::TYPE_DROPDOWN) { $form->addInput(array('type'=>'combobox','name'=>$field_name, 'style'=>'width: 250px;', 'data'=>CustomFields::getOptions($userField['id']), + 'value'=>$userCustomFields[$userField['id']]['value'], 'empty'=>array(''=>$i18n->get('dropdown.select')))); } } @@ -175,14 +188,9 @@ function render(&$table, $value, $row, $column, $selected = false) { if (!ttValidFloat($cl_quota_percent, true)) $err->add($i18n->get('error.field'), $i18n->get('label.quota')); // Validate input in user custom fields. if ($custom_fields && $custom_fields->userFields) { - foreach ($custom_fields->userFields as $userField) { - $control_name = 'user_field_'.$userField['id']; - $field_label = htmlspecialchars($userField['label']); - $field_type = $userField['type']; - $required = $userField['required']; - $field_value = trim($request->getParameter($control_name)); + foreach ($userCustomFields as $userField) { // Validation is the same for text and dropdown fields. - if (!ttValidString($field_value, !$required)) $err->add($i18n->get('error.field'), $field_label); + if (!ttValidString($userField['value'], !$userField['required'])) $err->add($i18n->get('error.field'), htmlspecialchars($userField['label'])); } } if (!ttValidFloat($cl_rate, true)) $err->add($i18n->get('error.field'), $i18n->get('form.users.default_rate')); @@ -203,7 +211,18 @@ function render(&$table, $value, $row, $column, $selected = false) { 'projects' => $assigned_projects, 'email' => $cl_email); $user_id = ttUserHelper::insert($fields); - if ($user_id) { + + // Insert user custom fields if we have them. + $result = true; + if ($user_id && $custom_fields && $custom_fields->userFields) { + foreach($userCustomFields as $userField) { + if (!$result) break; + $result = true; // TODO: replace this with a function call that inserts a field. + // Perhaps the entire block should be in the function call? + } + } + + if ($user_id && $result) { if (!$user->exists()) { // We added a user to an empty subgroup. Set new user as on behalf user. // Needed for user-based things to work (such as notifications config). From 392a83f0d6d4cc2a9296bb4175345412ebbc125a Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 1 Jul 2019 14:03:44 +0000 Subject: [PATCH 016/877] Added code to insert user custom fields after user creation. --- WEB-INF/templates/footer.tpl | 2 +- plugins/CustomFields.class.php | 51 ++++++++++++++++++++++++++++++++++ user_add.php | 6 +--- 3 files changed, 53 insertions(+), 6 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index f03277b8a..5f090d994 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.19.7.5027 | Copyright © Anuko | +  Anuko Time Tracker 1.19.7.5028 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/plugins/CustomFields.class.php b/plugins/CustomFields.class.php index d58cbe539..0ab33c743 100644 --- a/plugins/CustomFields.class.php +++ b/plugins/CustomFields.class.php @@ -354,4 +354,55 @@ static function deleteField($field_id) { $affected = $mdb2->exec($sql); return (!is_a($affected, 'PEAR_Error')); } + + // insertEntityFields - inserts entity custom fields into tt_entity_custom_fields. + function insertEntityFields($entity_type, $entity_id, $entityFields) { + foreach ($entityFields as $entityField) { + if (!$this->insertEntityField($entity_type, $entity_id, $entityField)) + return false; + } + return true; + } + + // insertEntityField - inserts a single entity custom field into tt_entity_custom_fields. + function insertEntityField($entity_type, $entity_id, $entityField) { + global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $created = 'now(), '.$mdb2->quote($_SERVER['REMOTE_ADDR']).', '.$user->id; + + $field_id = (int) $entityField['field_id']; + + $option_id = $entityField['type'] == CustomFields::TYPE_DROPDOWN ? (int) $entityField['value'] : null; + $value = $entityField['type'] == CustomFields::TYPE_TEXT ? $entityField['value'] : null; + + // TODO: add a jon to protect from bogus option_ids in post. + $sql = "insert into tt_entity_custom_fields". + " (group_id, org_id, entity_type, entity_id, field_id, option_id, value, created, created_ip, created_by)". + " values($group_id, $org_id, $entity_type, $entity_id, $field_id, ".$mdb2->quote($option_id).", ".$mdb2->quote($value).", $created)"; + $affected = $mdb2->exec($sql); + return (!is_a($affected, 'PEAR_Error')); + } + + // deleteEntityFields - deletes entity custom fields (permanently). + // Note: deleting, rather than marking fields deleted is on purpose + // because we want to keep the table small after multiple entity edits. + function deleteEntityFields($entity_type, $entity_id) { + global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $modified_part = ', modified = now(), modified_ip = '.$mdb2->quote($_SERVER['REMOTE_ADDR']).', modified_by = '.$user->id; + + $sql = "delete from tt_entity_custom_fields". + " where entity_type = $entity_type and entity_id = $entity_id". + " and group_id = $group_id and org_id = $org_id"; + $affected = $mdb2->exec($sql); + return (!is_a($affected, 'PEAR_Error')); + } } diff --git a/user_add.php b/user_add.php index 83f3bbcb2..0cd71b0a4 100644 --- a/user_add.php +++ b/user_add.php @@ -215,11 +215,7 @@ function render(&$table, $value, $row, $column, $selected = false) { // Insert user custom fields if we have them. $result = true; if ($user_id && $custom_fields && $custom_fields->userFields) { - foreach($userCustomFields as $userField) { - if (!$result) break; - $result = true; // TODO: replace this with a function call that inserts a field. - // Perhaps the entire block should be in the function call? - } + $result = $custom_fields->insertEntityFields(CustomFields::ENTITY_USER, $user_id, $userCustomFields); } if ($user_id && $result) { From 9dab021e08d44f730564686bd9ef7856c7a3b4a0 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 1 Jul 2019 14:42:45 +0000 Subject: [PATCH 017/877] Improved ttUser::markUserDeleted by marking user custom fields as deleted also. --- WEB-INF/lib/ttUser.class.php | 14 +++++++++++++- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index 5498a996f..6db627884 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -708,14 +708,26 @@ function markUserDeleted($user_id) { if (is_a($affected, 'PEAR_Error')) return false; - // Mark user as deleted. + // Mark user custom fields as deleted, + require_once('plugins/CustomFields.class.php'); + $entity_type = CustomFields::ENTITY_USER; $modified_part = ', modified = now(), modified_ip = '.$mdb2->quote($_SERVER['REMOTE_ADDR']).', modified_by = '.$mdb2->quote($this->id); + $sql = "update tt_entity_custom_fields set status = null $modified_part". + " where entity_type = $entity_type and entity_id = $user_id". + " and group_id = $group_id and org_id = $org_id"; + $affected = $mdb2->exec($sql); + if (is_a($affected, 'PEAR_Error')) + return false; + + // Mark user as deleted. $sql = "update tt_users set status = null $modified_part where id = $user_id". " and group_id = $group_id and org_id = $org_id"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; + + return true; } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 5f090d994..39edd60cf 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- - +{if $custom_fields && $custom_fields->userFields} + + {foreach $custom_fields->userFields as $userField} + + + {assign var="control_name" value='user_field_'|cat:$userField['id']} + {assign var="checkbox_control_name" value='ch_user_field_'|cat:$userField['id']} + + + + {/foreach} +{/if} diff --git a/reports.php b/reports.php index aa492061a..9ad09c789 100644 --- a/reports.php +++ b/reports.php @@ -324,6 +324,25 @@ if ($showTimesheetCheckbox) $form->addInput(array('type'=>'hidden','name'=>'timesheet_user_id')); +// If we have user custom fields - add controls for them. +if ($custom_fields && $custom_fields->userFields) { + foreach ($custom_fields->userFields as $userField) { + $field_name = 'user_field_'.$userField['id']; + $checkbox_field_name = 'ch_'.$field_name; + if ($userField['type'] == CustomFields::TYPE_TEXT) { + $form->addInput(array('type'=>'text','name'=>$field_name,'style'=>'width: 250px;','value'=>$userCustomFields[$userField['id']]['value'])); + } elseif ($userField['type'] == CustomFields::TYPE_DROPDOWN) { + $form->addInput(array('type'=>'combobox','name'=>$field_name, + 'style'=>'width: 250px;', + 'data'=>CustomFields::getOptions($userField['id']), + 'value'=>$userCustomFields[$userField['id']]['value'], + 'empty'=>array(''=>$i18n->get('dropdown.all')))); + } + // Also add a checkbox (to print the field or not). + $form->addInput(array('type'=>'checkbox','name'=>$checkbox_field_name)); + } +} + // Add group by control. $group_by_options['no_grouping'] = $i18n->get('form.reports.group_by_no'); $group_by_options['date'] = $i18n->get('form.reports.group_by_date'); From 249df45db48a201776dc72018505c1615fc4ad38 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 4 Jul 2019 16:52:05 +0000 Subject: [PATCH 020/877] More progress on integratiung user custom fields in reports. --- WEB-INF/lib/ttReportHelper.class.php | 68 +++++++++++++++++++++++++++- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/report.tpl | 46 +++++++++++++++++++ WEB-INF/templates/reports.tpl | 2 +- reports.php | 2 +- 5 files changed, 116 insertions(+), 4 deletions(-) diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index 966865fbb..a725a39a2 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -162,6 +162,11 @@ static function getItems($options) { $canViewReports = $user->can('view_reports') || $user->can('view_all_reports'); $isClient = $user->isClient(); + if ($user->isPluginEnabled('cf')) { + require_once('plugins/CustomFields.class.php'); + $custom_fields = new CustomFields(); + } + $grouping = ttReportHelper::grouping($options); if ($grouping) { $grouping_by_date = ttReportHelper::groupingBy('date', $options); @@ -183,6 +188,24 @@ static function getItems($options) { array_push($fields, 'l.date'); if($canViewReports || $isClient) array_push($fields, 'u.name as user'); + // User custom fields. Note: 1 join required for each text field. + // 2 joins for each dropdown field. Query wil get messy with many fields. + // It is unclear how to optimize if we want flexibility with custom fields. + if ($custom_fields && $custom_fields->userFields) { + foreach ($custom_fields->userFields as $userField) { + $field_name = 'user_field_'.$userField['id']; + $checkbox_field_name = 'show_'.$field_name; + if ($options[$checkbox_field_name]) { + if ($userField['type'] == CustomFields::TYPE_TEXT) { + $ecfTableName = 'ecf'.$userField['id']; + array_push($fields, "$ecfTableName.value as $field_name"); + } elseif ($userField['type'] == CustomFields::TYPE_DROPDOWN) { + $cfoTableName = 'cfo'.$userField['id']; + array_push($fields, "$cfoTableName.value as $field_name"); + } + } + } + } // Add client name if it is selected. if ($options['show_client'] || $grouping_by_client) array_push($fields, 'c.name as client'); @@ -261,6 +284,30 @@ static function getItems($options) { // Prepare sql query part for left joins. $left_joins = null; + + // Left join block for custom fields. + // 1 join for each text field, 2 joins for each dropdown. + // How to optimize this mess and reduce query complexity? + if ($custom_fields && $custom_fields->userFields) { + foreach ($custom_fields->userFields as $userField) { + $field_name = 'user_field_'.$userField['id']; + $checkbox_field_name = 'show_'.$field_name; + if ($options[$checkbox_field_name]) { + if ($userField['type'] == CustomFields::TYPE_TEXT) { + $ecfTable = 'ecf'.$userField['id']; + // One extra join for each text field. + $left_joins .= " left join tt_entity_custom_fields $ecfTable on ($ecfTable.entity_type = 2 and $ecfTable.entity_id = l.user_id and $ecfTable.field_id = ".$userField['id'].")"; + } elseif ($userField['type'] == CustomFields::TYPE_DROPDOWN) { + $ecfTable = 'ecf'.$userField['id']; + $cfoTable = 'cfo'.$userField['id']; + // Two extra joins for each dropdown field. + $left_joins .= " left join tt_entity_custom_fields $ecfTable on ($ecfTable.entity_type = 2 and $ecfTable.entity_id = l.user_id and $ecfTable.field_id = ".$userField['id'].")"; + $left_joins .= " left join tt_custom_field_options $cfoTable on ($cfoTable.field_id = $ecfTable.field_id and $cfoTable.id = $ecfTable.option_id)"; + } + } + } + } + if ($options['show_client'] || $grouping_by_client) $left_joins .= " left join tt_clients c on (c.id = l.client_id)"; if (($canViewReports || $isClient) && $options['show_invoice']) @@ -1186,10 +1233,29 @@ static function getReportOptions($bean) { $options['show_work_units'] = $bean->getAttribute('chunits'); $options['show_timesheet'] = $bean->getAttribute('chtimesheet'); $options['show_files'] = $bean->getAttribute('chfiles'); - $options['show_totals_only'] = $bean->getAttribute('chtotalsonly'); + + // Prepare custom field options. + if ($user->isPluginEnabled('cf')) { + require_once('plugins/CustomFields.class.php'); + $custom_fields = new CustomFields(); + + // TODO: add time fields here. + + // User fields. + if ($custom_fields->userFields) { + foreach ($custom_fields->userFields as $userField) { + $control_name = 'user_field_'.$userField['id']; + $checkbox_control_name = 'show_'.$control_name; + $options[$control_name] = $bean->getAttribute($control_name); + $options[$checkbox_control_name] = $bean->getAttribute($checkbox_control_name); + } + } + } + $options['group_by1'] = $bean->getAttribute('group_by1'); $options['group_by2'] = $bean->getAttribute('group_by2'); $options['group_by3'] = $bean->getAttribute('group_by3'); + $options['show_totals_only'] = $bean->getAttribute('chtotalsonly'); return $options; } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index bc06f6af9..c690e3b61 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.19.7.5028 | Copyright © Anuko | +  Anuko Time Tracker 1.19.7.5029 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From c21d22cb9ed9674c218062770d520a327ece48cb Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 1 Jul 2019 21:37:37 +0000 Subject: [PATCH 018/877] Added user custom fields on user_edit.php page. --- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/user_edit.tpl | 9 +++++ plugins/CustomFields.class.php | 33 ++++++++++++++++ user_edit.php | 67 +++++++++++++++++++++++++++++++-- 4 files changed, 106 insertions(+), 5 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 39edd60cf..580639bad 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- +{/if} +{if $custom_fields && $custom_fields->userFields} + {foreach $custom_fields->userFields as $userField} + + + {assign var="control_name" value='user_field_'|cat:$userField['id']} + + + {/foreach} {/if} diff --git a/plugins/CustomFields.class.php b/plugins/CustomFields.class.php index 0ab33c743..f0ff0a4db 100644 --- a/plugins/CustomFields.class.php +++ b/plugins/CustomFields.class.php @@ -387,6 +387,15 @@ function insertEntityField($entity_type, $entity_id, $entityField) { return (!is_a($affected, 'PEAR_Error')); } + // updateEntityFields - updates entity custom fields in tt_entity_custom_fields table + // by doing a delete followed up by an insert. + function updateEntityFields($entity_type, $entity_id, $entityFields) { + $result = $this->deleteEntityFields($entity_type, $entity_id); + if (!$result) return false; + + return $this->insertEntityFields($entity_type, $entity_id, $entityFields); + } + // deleteEntityFields - deletes entity custom fields (permanently). // Note: deleting, rather than marking fields deleted is on purpose // because we want to keep the table small after multiple entity edits. @@ -405,4 +414,28 @@ function deleteEntityFields($entity_type, $entity_id) { $affected = $mdb2->exec($sql); return (!is_a($affected, 'PEAR_Error')); } + + // getEntityFieldValue - obtains entity custom field value from the database. + function getEntityFieldValue($entity_type, $entity_id, $field_id, $type) { + global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $sql = "select option_id, value from tt_entity_custom_fields". + " where entity_type = $entity_type and entity_id = $entity_id". + " and field_id = $field_id". + " and group_id = $group_id and org_id = $org_id and status = 1"; + $res = $mdb2->query($sql); + if (!is_a($res, 'PEAR_Error')) { + if ($val = $res->fetchRow()) { + if (CustomFields::TYPE_DROPDOWN == $type) + return $val['option_id']; + if (CustomFields::TYPE_TEXT == $type) + return $val['value']; + } + } + return null; + } } diff --git a/user_edit.php b/user_edit.php index cda9ab2d0..843383f42 100644 --- a/user_edit.php +++ b/user_edit.php @@ -53,6 +53,13 @@ if ($user->isPluginEnabled('cl')) $clients = ttGroupHelper::getActiveClients(); +// Use custom fields plugin if it is enabled. +if ($user->isPluginEnabled('cf')) { + require_once('plugins/CustomFields.class.php'); + $custom_fields = new CustomFields(); + $smarty->assign('custom_fields', $custom_fields); +} + $show_projects = MODE_PROJECTS == $user->getTrackingMode() || MODE_PROJECTS_AND_TASKS == $user->getTrackingMode(); if ($show_projects) { $projects = ttGroupHelper::getActiveProjects(); @@ -71,8 +78,20 @@ $cl_role_id = $request->getParameter('role'); $cl_client_id = $request->getParameter('client'); $cl_status = $request->getParameter('status'); - $cl_rate = $request->getParameter('rate'); $cl_quota_percent = $request->getParameter('quota_percent'); + // If we have user custom fields - collect input. + if ($custom_fields && $custom_fields->userFields) { + foreach ($custom_fields->userFields as $userField) { + $control_name = 'user_field_'.$userField['id']; + $userCustomFields[$userField['id']] = array('field_id' => $userField['id'], + 'control_name' => $control_name, + 'label' => $userField['label'], + 'type' => $userField['type'], + 'required' => $userField['required'], + 'value' => trim($request->getParameter($control_name))); + } + } + $cl_rate = $request->getParameter('rate'); $cl_projects = $request->getParameter('projects'); if (is_array($cl_projects)) { foreach ($cl_projects as $p) { @@ -89,8 +108,20 @@ $cl_name = $user_details['name']; $cl_login = $user_details['login']; $cl_email = $user_details['email']; - $cl_rate = str_replace('.', $user->getDecimalMark(), $user_details['rate']); $cl_quota_percent = str_replace('.', $user->getDecimalMark(), $user_details['quota_percent']); + // If we have user custom fields - collect vallues from database. + if ($custom_fields && $custom_fields->userFields) { + foreach ($custom_fields->userFields as $userField) { + $control_name = 'user_field_'.$userField['id']; + $userCustomFields[$userField['id']] = array('field_id' => $userField['id'], + 'control_name' => $control_name, + 'label' => $userField['label'], + 'type' => $userField['type'], + 'required' => $userField['required'], + 'value' => $custom_fields->getEntityFieldValue(CustomFields::ENTITY_USER, $user_id, $userField['id'], $userField['type'])); + } + } + $cl_rate = str_replace('.', $user->getDecimalMark(), $user_details['rate']); $cl_role_id = $user_details['role_id']; $cl_client_id = $user_details['client_id']; $cl_status = $user_details['status']; @@ -115,6 +146,22 @@ if ($user->isPluginEnabled('cl')) $form->addInput(array('type'=>'combobox','name'=>'client','value'=>$cl_client_id,'data'=>$clients,'datakeys'=>array('id', 'name'),'empty'=>array(''=>$i18n->get('dropdown.select')))); +// If we have custom fields - add controls for them. +if ($custom_fields && $custom_fields->userFields) { + foreach ($custom_fields->userFields as $userField) { + $field_name = 'user_field_'.$userField['id']; + if ($userField['type'] == CustomFields::TYPE_TEXT) { + $form->addInput(array('type'=>'text','name'=>$field_name,'value'=>$userCustomFields[$userField['id']]['value'])); + } elseif ($userField['type'] == CustomFields::TYPE_DROPDOWN) { + $form->addInput(array('type'=>'combobox','name'=>$field_name, + 'style'=>'width: 250px;', + 'data'=>CustomFields::getOptions($userField['id']), + 'value'=>$userCustomFields[$userField['id']]['value'], + 'empty'=>array(''=>$i18n->get('dropdown.select')))); + } + } +} + $form->addInput(array('type'=>'combobox','name'=>'status','value'=>$cl_status, 'data'=>array(ACTIVE=>$i18n->get('dropdown.status_active'),INACTIVE=>$i18n->get('dropdown.status_inactive')))); $form->addInput(array('type'=>'floatfield','maxlength'=>'10','name'=>'rate','format'=>'.2','value'=>$cl_rate)); @@ -172,8 +219,15 @@ function render(&$table, $value, $row, $column, $selected = false) { if (!ttValidEmail($cl_email, true)) $err->add($i18n->get('error.field'), $i18n->get('label.email')); // Require selection of a client for a client role. if ($user->isPluginEnabled('cl') && ttRoleHelper::isClientRole($cl_role_id) && !$cl_client_id) $err->add($i18n->get('error.client')); - if (!ttValidFloat($cl_rate, true)) $err->add($i18n->get('error.field'), $i18n->get('form.users.default_rate')); if (!ttValidFloat($cl_quota_percent, true)) $err->add($i18n->get('error.field'), $i18n->get('label.quota')); + // Validate input in user custom fields. + if ($custom_fields && $custom_fields->userFields) { + foreach ($userCustomFields as $userField) { + // Validation is the same for text and dropdown fields. + if (!ttValidString($userField['value'], !$userField['required'])) $err->add($i18n->get('error.field'), htmlspecialchars($userField['label'])); + } + } + if (!ttValidFloat($cl_rate, true)) $err->add($i18n->get('error.field'), $i18n->get('form.users.default_rate')); if ($err->no()) { $existing_user = ttUserHelper::getUserByLogin($cl_login); @@ -193,8 +247,13 @@ function render(&$table, $value, $row, $column, $selected = false) { $fields['client_id'] = $cl_client_id; } - if (ttUserHelper::update($user_id, $fields)) { + $result = ttUserHelper::update($user_id, $fields); + // Update user custom fields if we have them. + if ($result && $custom_fields && $custom_fields->userFields) { + $result = $custom_fields->updateEntityFields(CustomFields::ENTITY_USER, $user_id, $userCustomFields); + } + if ($result) { // If our own login changed, set new one in cookie to remember it. if (($user_id == $user->id) && ($user->login != $cl_login)) { setcookie('tt_login', $cl_login, time() + COOKIE_EXPIRE, '/'); From 8f373c507a90899485609be5b5a81626806059d5 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 2 Jul 2019 14:31:25 +0000 Subject: [PATCH 019/877] Work in progress adding user custom fields to reports. --- WEB-INF/resources/ca.lang.php | 2 ++ WEB-INF/resources/cs.lang.php | 2 ++ WEB-INF/resources/da.lang.php | 2 ++ WEB-INF/resources/de.lang.php | 2 ++ WEB-INF/resources/en.lang.php | 1 + WEB-INF/resources/es.lang.php | 2 ++ WEB-INF/resources/et.lang.php | 2 ++ WEB-INF/resources/fa.lang.php | 2 ++ WEB-INF/resources/fi.lang.php | 2 ++ WEB-INF/resources/fr.lang.php | 2 ++ WEB-INF/resources/gr.lang.php | 2 ++ WEB-INF/resources/he.lang.php | 2 ++ WEB-INF/resources/hu.lang.php | 1 + WEB-INF/resources/it.lang.php | 2 ++ WEB-INF/resources/ja.lang.php | 2 ++ WEB-INF/resources/ko.lang.php | 2 ++ WEB-INF/resources/nl.lang.php | 2 ++ WEB-INF/resources/no.lang.php | 2 ++ WEB-INF/resources/pl.lang.php | 2 ++ WEB-INF/resources/pt-br.lang.php | 2 ++ WEB-INF/resources/pt.lang.php | 2 ++ WEB-INF/resources/ro.lang.php | 2 ++ WEB-INF/resources/ru.lang.php | 1 + WEB-INF/resources/sk.lang.php | 1 + WEB-INF/resources/sl.lang.php | 1 + WEB-INF/resources/sr.lang.php | 2 ++ WEB-INF/resources/sv.lang.php | 2 ++ WEB-INF/resources/tr.lang.php | 2 ++ WEB-INF/resources/zh-cn.lang.php | 2 ++ WEB-INF/resources/zh-tw.lang.php | 2 ++ WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/reports.tpl | 13 ++++++++++++- reports.php | 19 +++++++++++++++++++ 33 files changed, 87 insertions(+), 2 deletions(-) diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index 42c637b1b..58ecdbe83 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -485,6 +485,8 @@ 'form.reports.select_period' => 'Seleccionar període de temps', 'form.reports.set_period' => 'o establir dates', 'form.reports.show_fields' => 'Mostrar camps', +// TODO: translate the following. +// 'form.reports.user_fields' => 'User fields', 'form.reports.group_by' => 'Agrupar per', 'form.reports.group_by_no' => '--- no agrupar ---', 'form.reports.group_by_date' => 'data', diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index 0f25aa666..7043206d8 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -494,6 +494,8 @@ 'form.reports.select_period' => 'Výberte období', 'form.reports.set_period' => 'nebo určete dny', 'form.reports.show_fields' => 'Zobrazit pole', +// TODO: translate the following. +// 'form.reports.user_fields' => 'User fields', 'form.reports.group_by' => 'Seskupit podle', // TODO: translate the following. // 'form.reports.group_by_no' => '--- no grouping ---', diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index 0c59b52a3..863ffcf0c 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -466,6 +466,8 @@ 'form.reports.select_period' => 'Vælg en periode', 'form.reports.set_period' => 'eller sæt datoer', 'form.reports.show_fields' => 'Vis felter', +// TODO: translate the following. +// 'form.reports.user_fields' => 'User fields', 'form.reports.group_by' => 'Gruppér ved', 'form.reports.group_by_no' => '--- Ingen gruppereing ---', 'form.reports.group_by_date' => 'Dato', diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index 3b6c1a712..1e23983a5 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -448,6 +448,8 @@ 'form.reports.select_period' => 'Zeitraum auswählen', 'form.reports.set_period' => 'oder Datum eingeben', 'form.reports.show_fields' => 'Felder anzeigen', +// TODO: translate the following. +// 'form.reports.user_fields' => 'User fields', 'form.reports.group_by' => 'Gruppieren nach', 'form.reports.group_by_no' => '--- keine Gruppierung ---', 'form.reports.group_by_date' => 'Datum', diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index 851c8f93c..0b48ae6ba 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -435,6 +435,7 @@ 'form.reports.select_period' => 'Select time period', 'form.reports.set_period' => 'or set dates', 'form.reports.show_fields' => 'Show fields', +'form.reports.user_fields' => 'User fields', 'form.reports.group_by' => 'Group by', 'form.reports.group_by_no' => '--- no grouping ---', 'form.reports.group_by_date' => 'date', diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index cae029431..e46c5f30a 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -498,6 +498,8 @@ 'form.reports.select_period' => 'Seleccionar período de tiempo', 'form.reports.set_period' => 'o establecer fechas', 'form.reports.show_fields' => 'Mostrar campos', +// TODO: translate the following. +// 'form.reports.user_fields' => 'User fields', 'form.reports.group_by' => 'Agrupar por', 'form.reports.group_by_no' => '--- no agrupar ---', 'form.reports.group_by_date' => 'fecha', diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index fbe2e88ce..07c2589b3 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -475,6 +475,8 @@ 'form.reports.select_period' => 'Vali ajaperiood', 'form.reports.set_period' => 'või märgi kuupäevad', 'form.reports.show_fields' => 'Näita välju', +// TODO: translate the following. +// 'form.reports.user_fields' => 'User fields', 'form.reports.group_by' => 'Grupeeri', 'form.reports.group_by_no' => '--- grupeerimata ---', 'form.reports.group_by_date' => 'kuupäev', diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index 13a2d5f4e..f81cef522 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -487,6 +487,8 @@ 'form.reports.select_period' => 'انتخاب بازه زمانی', 'form.reports.set_period' => 'یا تعیین تاریخ', 'form.reports.show_fields' => 'نمایش فیلدها', +// TODO: translate the following. +// 'form.reports.user_fields' => 'User fields', 'form.reports.group_by' => 'گروه بندی شده با', 'form.reports.group_by_no' => '--- بدون گروه ---', 'form.reports.group_by_date' => 'تاریخ', diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 4421b889c..020c34624 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -471,6 +471,8 @@ 'form.reports.select_period' => 'Valitse ajanjakso', 'form.reports.set_period' => 'tai aseta päivät', 'form.reports.show_fields' => 'Näytä kentät', +// TODO: translate the following. +// 'form.reports.user_fields' => 'User fields', 'form.reports.group_by' => 'Ryhmittelyperuste', 'form.reports.group_by_no' => '--- ei ryhmitystä ---', 'form.reports.group_by_date' => 'päivä', diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index 3a5ce78a3..04d092d2a 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -463,6 +463,8 @@ 'form.reports.select_period' => 'Sélectionner la période de temps', 'form.reports.set_period' => 'ou dates indiquées', 'form.reports.show_fields' => 'Afficher les champs', +// TODO: translate the following. +// 'form.reports.user_fields' => 'User fields', 'form.reports.group_by' => 'Regroupés par', 'form.reports.group_by_no' => '--- Aucun regroupement ---', 'form.reports.group_by_date' => 'Date', diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index 65e731800..66e349f0c 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -457,6 +457,8 @@ 'form.reports.select_period' => 'Επιλογή χρονικής περιόδου', 'form.reports.set_period' => 'ή εύρος ημερομηνιών', 'form.reports.show_fields' => 'Εμφάνιση πεδίων', +// TODO: translate the following. +// 'form.reports.user_fields' => 'User fields', 'form.reports.group_by' => 'Ομαδοποίηση με βάση', 'form.reports.group_by_no' => '--- χωρίς ομαδοποίηση ---', 'form.reports.group_by_date' => 'ημερομηνία', diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index 3aee8065a..5046f0b42 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -489,6 +489,8 @@ 'form.reports.select_period' => 'בחר תקופת זמן', 'form.reports.set_period' => 'או הגדר תאריכים', 'form.reports.show_fields' => 'הראה שדות', +// TODO: translate the following. +// 'form.reports.user_fields' => 'User fields', 'form.reports.group_by' => 'סדר לפי', 'form.reports.group_by_no' => '--- ללא סדר ---', 'form.reports.group_by_date' => 'תאריך', diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index a998dd869..dbdfc9334 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -490,6 +490,7 @@ 'form.reports.set_period' => 'vagy állíts be konkrét dátumot', // TODO: translate the following. // 'form.reports.show_fields' => 'Show fields', +// 'form.reports.user_fields' => 'User fields', 'form.reports.group_by' => 'Csoportosítva', 'form.reports.group_by_no' => '--- csoportosítás nélkül ---', 'form.reports.group_by_date' => 'dátum', diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index 4f6368bd5..1423b52f2 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -470,6 +470,8 @@ 'form.reports.select_period' => 'Seleziona il periodo di tempo', 'form.reports.set_period' => 'oppure setta le date', 'form.reports.show_fields' => 'Mostra i campi', +// TODO: translate the following. +// 'form.reports.user_fields' => 'User fields', 'form.reports.group_by' => 'Raggruppa per', 'form.reports.group_by_no' => '--- non raggruppare ---', 'form.reports.group_by_date' => 'data', diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index 8a723baef..a0182a327 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -494,6 +494,8 @@ 'form.reports.select_period' => '時間期間の選択', 'form.reports.set_period' => 'あるいは日付を設定', 'form.reports.show_fields' => 'フィールドの表示', +// TODO: translate the following. +// 'form.reports.user_fields' => 'User fields', 'form.reports.group_by' => '次のようにグループ化', 'form.reports.group_by_no' => '--- グループの機能がありません ---', 'form.reports.group_by_date' => '日付', diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index c2957e163..4d733a1ff 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -492,6 +492,8 @@ 'form.reports.select_period' => '시간 기간을 선택', 'form.reports.set_period' => '혹은 날짜를 설정', 'form.reports.show_fields' => '필드들을 보기', +// TODO: translate the following. +// 'form.reports.user_fields' => 'User fields', 'form.reports.group_by' => '다음것에 의한 그룹화', 'form.reports.group_by_no' => '--- 그룹화되지 않음 ---', 'form.reports.group_by_date' => '날짜', diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index c8346553a..4d088c4c6 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -430,6 +430,8 @@ 'form.reports.select_period' => 'Kies periode', 'form.reports.set_period' => 'of stel datums in', 'form.reports.show_fields' => 'Toon velden', +// TODO: translate the following. +// 'form.reports.user_fields' => 'User fields', 'form.reports.group_by' => 'Groeperen op', 'form.reports.group_by_no' => '--- niet groeperen ---', 'form.reports.group_by_date' => 'datum', diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index 8fb7bf64f..fbf1f7c44 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -491,6 +491,8 @@ 'form.reports.select_period' => 'Velg tidsperiode', 'form.reports.set_period' => 'eller sett dato', 'form.reports.show_fields' => 'Vis feltene', +// TODO: translate the following. +// 'form.reports.user_fields' => 'User fields', // 'form.reports.group_by' => 'Group by', // 'form.reports.group_by_no' => '--- no grouping ---', 'form.reports.group_by_date' => 'dato', diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index d77a7b4a0..215508768 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -474,6 +474,8 @@ 'form.reports.select_period' => 'Wybierz okres', 'form.reports.set_period' => 'lub ustaw daty', 'form.reports.show_fields' => 'Pokaż pola', +// TODO: translate the following. +// 'form.reports.user_fields' => 'User fields', 'form.reports.group_by' => 'Grupowanie wg', 'form.reports.group_by_no' => '--- bez grupowania ---', 'form.reports.group_by_date' => 'daty', diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index 7165cb51e..59ae7060b 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -469,6 +469,8 @@ 'form.reports.select_period' => 'Selecione o período de tempo', 'form.reports.set_period' => 'ou selecionar datas', 'form.reports.show_fields' => 'Exibir campos', +// TODO: translate the following. +// 'form.reports.user_fields' => 'User fields', 'form.reports.group_by' => 'Agrupar por', 'form.reports.group_by_no' => '--- sem agrupar ---', 'form.reports.group_by_date' => 'data', diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index 6c002439d..1ab616638 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -472,6 +472,8 @@ 'form.reports.select_period' => 'Selecione o período de tempo', 'form.reports.set_period' => 'ou selecionar datas', 'form.reports.show_fields' => 'Exibir campos', +// TODO: translate the following. +// 'form.reports.user_fields' => 'User fields', // 'form.reports.group_by' => 'Group by', // 'form.reports.group_by_no' => '--- no grouping ---', // 'form.reports.group_by_date' => 'date', diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index a66f5e4e6..aea10d080 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -493,6 +493,8 @@ 'form.reports.select_period' => 'Alege perioada', 'form.reports.set_period' => 'sau introdu intervalul de date', 'form.reports.show_fields' => 'Arata campuri', +// TODO: translate the following. +// 'form.reports.user_fields' => 'User fields', 'form.reports.group_by' => 'Grupat dupa', 'form.reports.group_by_no' => '--- fara grupare ---', 'form.reports.group_by_date' => 'data', diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index 93c88dd83..bf267018e 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -426,6 +426,7 @@ 'form.reports.select_period' => 'Выберите интервал времени', 'form.reports.set_period' => 'или укажите даты', 'form.reports.show_fields' => 'Показывать поля', +'form.reports.user_fields' => 'Поля пользователя', 'form.reports.group_by' => 'Группировать по', 'form.reports.group_by_no' => '--- без группировки ---', 'form.reports.group_by_date' => 'дате', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index a1ebcb555..c3d1dd247 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -480,6 +480,7 @@ 'form.reports.set_period' => 'alebo nastavte dátumy', 'form.reports.show_fields' => 'Zobraziť polia', // TODO: translate the following. +// 'form.reports.user_fields' => 'User fields', // 'form.reports.group_by' => 'Group by', // 'form.reports.group_by_no' => '--- no grouping ---', 'form.reports.group_by_date' => 'dátum', diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index 0dac806e9..4b6aae579 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -467,6 +467,7 @@ // 'form.reports.select_period' => 'Select time period', // 'form.reports.set_period' => 'or set dates', // 'form.reports.show_fields' => 'Show fields', +// 'form.reports.user_fields' => 'User fields', // 'form.reports.group_by' => 'Group by', // 'form.reports.group_by_no' => '--- no grouping ---', // 'form.reports.group_by_date' => 'date', diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index e73ae4648..08a9460e9 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -472,6 +472,8 @@ 'form.reports.select_period' => 'Odaberi vremenski raspon', 'form.reports.set_period' => 'ili podesi datum', 'form.reports.show_fields' => 'Prikaži polja u izveštaju', +// TODO: translate the following. +// 'form.reports.user_fields' => 'User fields', 'form.reports.group_by' => 'Grupiši po', 'form.reports.group_by_no' => '--- nemoj grupisati ---', 'form.reports.group_by_date' => 'datum', diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index c6bf2f413..adb883cb4 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -471,6 +471,8 @@ 'form.reports.select_period' => 'Välj intervall', 'form.reports.set_period' => 'eller ställ in datum', 'form.reports.show_fields' => 'Visa fält', +// TODO: translate the following. +// 'form.reports.user_fields' => 'User fields', 'form.reports.group_by' => 'Gruppera efter', 'form.reports.group_by_no' => '--- Ingen gruppering ---', 'form.reports.group_by_date' => 'Datum', diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index d07275ffc..abeb693e3 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -504,6 +504,8 @@ 'form.reports.select_period' => 'Zaman aralığını seç', 'form.reports.set_period' => 'ya da tarihleri belirle', 'form.reports.show_fields' => 'Alanları göster', +// TODO: translate the following. +// 'form.reports.user_fields' => 'User fields', 'form.reports.group_by' => 'Gruplandırma kıstas', 'form.reports.group_by_no' => '--- gruplama yok ---', 'form.reports.group_by_date' => 'tarih', diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index e5244c073..92f9ecd1c 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -478,6 +478,8 @@ 'form.reports.select_period' => '选择时间段', 'form.reports.set_period' => '或设定日期', 'form.reports.show_fields' => '显示栏目', +// TODO: translate the following. +// 'form.reports.user_fields' => 'User fields', 'form.reports.group_by' => '分组方式', 'form.reports.group_by_no' => '--- 没有分组 ---', 'form.reports.group_by_date' => '日期', diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index f5d9e9b30..def3a0acf 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -484,6 +484,8 @@ 'form.reports.select_period' => '選擇時間段', 'form.reports.set_period' => '或設定日期', 'form.reports.show_fields' => '顯示欄目', +// TODO: translate the following. +// 'form.reports.user_fields' => 'User fields', 'form.reports.group_by' => '分組方式', 'form.reports.group_by_no' => '--- 沒有分組 ---', 'form.reports.group_by_date' => '日期', diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 580639bad..bc06f6af9 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.19.7.5029 | Copyright © Anuko | +  Anuko Time Tracker 1.19.7.5030 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/user_edit.tpl b/WEB-INF/templates/user_edit.tpl index e17651b21..49fa4ae50 100644 --- a/WEB-INF/templates/user_edit.tpl +++ b/WEB-INF/templates/user_edit.tpl @@ -133,6 +133,15 @@ function handleClientControl() { {$i18n.label.quota} (%): {$forms.userForm.quota_percent.control} {$i18n.label.what_is_it}
{$userField['label']|escape}{if $userField['required']} (*){/if}:{$forms.userForm.$control_name.control}
{$i18n.form.users.default_rate} (0{$user->getDecimalMark()}00):
-
 Anuko Time Tracker 1.19.7.5030 | Copyright © Anuko | +  Anuko Time Tracker 1.19.7.5031 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/reports.tpl b/WEB-INF/templates/reports.tpl index 70f283780..fd77c2842 100644 --- a/WEB-INF/templates/reports.tpl +++ b/WEB-INF/templates/reports.tpl @@ -398,7 +398,18 @@ function handleCheckboxes() {
{$i18n.form.reports.user_fields}
{$userField['label']|escape}:{$forms.reportForm.$control_name.control}{$forms.reportForm.$checkbox_control_name.control}
{$i18n.form.reports.group_by}
{$forms.reportForm.group_by1.control}
- {if $user->can('view_reports') || $user->can('view_all_reports') || $user->isClient()}{/if} + + {* user custom fileds *} + {if $custom_fields && $custom_fields->userFields} + {foreach $custom_fields->userFields as $userField} + {assign var="checkbox_control_name" value='show_user_field_'|cat:$userField['id']} + {if $bean->getAttribute($checkbox_control_name)}{/if} + {/foreach} + {/if} + {if $bean->getAttribute('chclient')}{/if} {if $bean->getAttribute('chproject')}{/if} {if $bean->getAttribute('chtask')}{/if} @@ -66,6 +75,15 @@ {/if} + + {* user custom fileds *} + {if $custom_fields && $custom_fields->userFields} + {foreach $custom_fields->userFields as $userField} + {assign var="checkbox_control_name" value='show_user_field_'|cat:$userField['id']} + {if $bean->getAttribute($checkbox_control_name)}{/if} + {/foreach} + {/if} + {if $bean->getAttribute('chclient')}{/if} {if $bean->getAttribute('chproject')}{/if} {if $bean->getAttribute('chtask')}{/if} @@ -95,6 +113,16 @@ {if $user->can('view_reports') || $user->can('view_all_reports') || $user->isClient()}{/if} + + {* user custom fileds *} + {if $custom_fields && $custom_fields->userFields} + {foreach $custom_fields->userFields as $userField} + {assign var="control_name" value='user_field_'|cat:$userField['id']} + {assign var="checkbox_control_name" value='show_user_field_'|cat:$userField['id']} + {if $bean->getAttribute($checkbox_control_name)}{/if} + {/foreach} + {/if} + {if $bean->getAttribute('chclient')}{/if} {if $bean->getAttribute('chproject')}{/if} {if $bean->getAttribute('chtask')}{/if} @@ -130,6 +158,15 @@ {/if} + + {* user custom fileds *} + {if $custom_fields && $custom_fields->userFields} + {foreach $custom_fields->userFields as $userField} + {assign var="checkbox_control_name" value='show_user_field_'|cat:$userField['id']} + {if $bean->getAttribute($checkbox_control_name)}{/if} + {/foreach} + {/if} + {if $bean->getAttribute('chclient')}{/if} {if $bean->getAttribute('chproject')}{/if} {if $bean->getAttribute('chtask')}{/if} @@ -154,6 +191,15 @@ {if $user->can('view_reports') || $user->can('view_all_reports') || $user->isClient()}{/if} + + {* user custom fileds *} + {if $custom_fields && $custom_fields->userFields} + {foreach $custom_fields->userFields as $userField} + {assign var="checkbox_control_name" value='show_user_field_'|cat:$userField['id']} + {if $bean->getAttribute($checkbox_control_name)}{/if} + {/foreach} + {/if} + {if $bean->getAttribute('chclient')}{/if} {if $bean->getAttribute('chproject')}{/if} {if $bean->getAttribute('chtask')}{/if} diff --git a/WEB-INF/templates/reports.tpl b/WEB-INF/templates/reports.tpl index fd77c2842..5256dbb9a 100644 --- a/WEB-INF/templates/reports.tpl +++ b/WEB-INF/templates/reports.tpl @@ -404,7 +404,7 @@ function handleCheckboxes() { {assign var="control_name" value='user_field_'|cat:$userField['id']} - {assign var="checkbox_control_name" value='ch_user_field_'|cat:$userField['id']} + {assign var="checkbox_control_name" value='show_user_field_'|cat:$userField['id']} diff --git a/reports.php b/reports.php index 9ad09c789..95e79c636 100644 --- a/reports.php +++ b/reports.php @@ -328,7 +328,7 @@ if ($custom_fields && $custom_fields->userFields) { foreach ($custom_fields->userFields as $userField) { $field_name = 'user_field_'.$userField['id']; - $checkbox_field_name = 'ch_'.$field_name; + $checkbox_field_name = 'show_'.$field_name; if ($userField['type'] == CustomFields::TYPE_TEXT) { $form->addInput(array('type'=>'text','name'=>$field_name,'style'=>'width: 250px;','value'=>$userCustomFields[$userField['id']]['value'])); } elseif ($userField['type'] == CustomFields::TYPE_DROPDOWN) { From 99b6df5b35546aa7ee770384326133e1bc94110e Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 5 Jul 2019 13:54:38 +0000 Subject: [PATCH 021/877] Fixed reporting on user custom fields for expense items. --- WEB-INF/lib/ttReportHelper.class.php | 59 +++++++++++++++++++++------- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 46 insertions(+), 15 deletions(-) diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index a725a39a2..c5f14228d 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -188,9 +188,7 @@ static function getItems($options) { array_push($fields, 'l.date'); if($canViewReports || $isClient) array_push($fields, 'u.name as user'); - // User custom fields. Note: 1 join required for each text field. - // 2 joins for each dropdown field. Query wil get messy with many fields. - // It is unclear how to optimize if we want flexibility with custom fields. + // Add user custom fields. if ($custom_fields && $custom_fields->userFields) { foreach ($custom_fields->userFields as $userField) { $field_name = 'user_field_'.$userField['id']; @@ -284,30 +282,27 @@ static function getItems($options) { // Prepare sql query part for left joins. $left_joins = null; - - // Left join block for custom fields. - // 1 join for each text field, 2 joins for each dropdown. - // How to optimize this mess and reduce query complexity? + // Left joins for custom fields. + // 1 join is required for each text field, 2 joins for each dropdown. if ($custom_fields && $custom_fields->userFields) { foreach ($custom_fields->userFields as $userField) { $field_name = 'user_field_'.$userField['id']; $checkbox_field_name = 'show_'.$field_name; + $entity_type = CustomFields::ENTITY_USER; if ($options[$checkbox_field_name]) { + $ecfTable = 'ecf'.$userField['id']; if ($userField['type'] == CustomFields::TYPE_TEXT) { - $ecfTable = 'ecf'.$userField['id']; - // One extra join for each text field. - $left_joins .= " left join tt_entity_custom_fields $ecfTable on ($ecfTable.entity_type = 2 and $ecfTable.entity_id = l.user_id and $ecfTable.field_id = ".$userField['id'].")"; + // Add one join for each text field. + $left_joins .= " left join tt_entity_custom_fields $ecfTable on ($ecfTable.entity_type = $entity_type and $ecfTable.entity_id = l.user_id and $ecfTable.field_id = ".$userField['id'].")"; } elseif ($userField['type'] == CustomFields::TYPE_DROPDOWN) { - $ecfTable = 'ecf'.$userField['id']; $cfoTable = 'cfo'.$userField['id']; - // Two extra joins for each dropdown field. - $left_joins .= " left join tt_entity_custom_fields $ecfTable on ($ecfTable.entity_type = 2 and $ecfTable.entity_id = l.user_id and $ecfTable.field_id = ".$userField['id'].")"; + // Add two joins for each dropdown field. + $left_joins .= " left join tt_entity_custom_fields $ecfTable on ($ecfTable.entity_type = $entity_type and $ecfTable.entity_id = l.user_id and $ecfTable.field_id = ".$userField['id'].")"; $left_joins .= " left join tt_custom_field_options $cfoTable on ($cfoTable.field_id = $ecfTable.field_id and $cfoTable.id = $ecfTable.option_id)"; } } } } - if ($options['show_client'] || $grouping_by_client) $left_joins .= " left join tt_clients c on (c.id = l.client_id)"; if (($canViewReports || $isClient) && $options['show_invoice']) @@ -365,6 +360,22 @@ static function getItems($options) { array_push($fields, 'ei.date'); if($canViewReports || $isClient) array_push($fields, 'u.name as user'); + // Add user custom fields. + if ($custom_fields && $custom_fields->userFields) { + foreach ($custom_fields->userFields as $userField) { + $field_name = 'user_field_'.$userField['id']; + $checkbox_field_name = 'show_'.$field_name; + if ($options[$checkbox_field_name]) { + if ($userField['type'] == CustomFields::TYPE_TEXT) { + $ecfTableName = 'ecf'.$userField['id']; + array_push($fields, "$ecfTableName.value as $field_name"); + } elseif ($userField['type'] == CustomFields::TYPE_DROPDOWN) { + $cfoTableName = 'cfo'.$userField['id']; + array_push($fields, "$cfoTableName.value as $field_name"); + } + } + } + } // Add client name if it is selected. if ($options['show_client'] || $grouping_by_client) array_push($fields, 'c.name as client'); @@ -414,6 +425,26 @@ static function getItems($options) { // Prepare sql query part for left joins. $left_joins = null; + // Left joins for custom fields. + if ($custom_fields && $custom_fields->userFields) { + foreach ($custom_fields->userFields as $userField) { + $field_name = 'user_field_'.$userField['id']; + $checkbox_field_name = 'show_'.$field_name; + $entity_type = CustomFields::ENTITY_USER; + if ($options[$checkbox_field_name]) { + $ecfTable = 'ecf'.$userField['id']; + if ($userField['type'] == CustomFields::TYPE_TEXT) { + // Add one join for each text field. + $left_joins .= " left join tt_entity_custom_fields $ecfTable on ($ecfTable.entity_type = $entity_type and $ecfTable.entity_id = ei.user_id and $ecfTable.field_id = ".$userField['id'].")"; + } elseif ($userField['type'] == CustomFields::TYPE_DROPDOWN) { + $cfoTable = 'cfo'.$userField['id']; + // Add two joins for each dropdown field. + $left_joins .= " left join tt_entity_custom_fields $ecfTable on ($ecfTable.entity_type = $entity_type and $ecfTable.entity_id = ei.user_id and $ecfTable.field_id = ".$userField['id'].")"; + $left_joins .= " left join tt_custom_field_options $cfoTable on ($cfoTable.field_id = $ecfTable.field_id and $cfoTable.id = $ecfTable.option_id)"; + } + } + } + } if ($canViewReports || $isClient) $left_joins .= " left join tt_users u on (u.id = ei.user_id)"; if ($options['show_client'] || $grouping_by_client) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index c690e3b61..38d4596e9 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.19.7.5031 | Copyright © Anuko | +  Anuko Time Tracker 1.19.7.5032 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/report.tpl b/WEB-INF/templates/report.tpl index a98d71aa0..64c69c6c2 100644 --- a/WEB-INF/templates/report.tpl +++ b/WEB-INF/templates/report.tpl @@ -40,6 +40,15 @@
{$i18n.label.date}{$i18n.label.user}{{$userField['label']|escape}}{$i18n.label.client}{$i18n.label.project}{$i18n.label.task}
{$i18n.label.subtotal} {if $user->can('view_reports') || $user->can('view_all_reports') || $user->isClient()}{$subtotals[$prev_grouped_by]['user']|escape}{$subtotals[$prev_grouped_by]['client']|escape}{$subtotals[$prev_grouped_by]['project']|escape}{$subtotals[$prev_grouped_by]['task']|escape}
{$item.date}{$item.user|escape}{$item.$control_name|escape}{$item.client|escape}{$item.project|escape}{$item.task|escape}
{$i18n.label.subtotal} {if $user->can('view_reports') || $user->can('view_all_reports') || $user->isClient()}{$subtotals[$cur_grouped_by]['user']|escape}{$subtotals[$cur_grouped_by]['client']|escape}{$subtotals[$cur_grouped_by]['project']|escape}{$subtotals[$cur_grouped_by]['task']|escape}
{$i18n.label.total}
{$userField['label']|escape}:{$forms.reportForm.$control_name.control} {$forms.reportForm.$checkbox_control_name.control}
-
 Anuko Time Tracker 1.19.7.5032 | Copyright © Anuko | +  Anuko Time Tracker 1.19.7.5033 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 75b0c59010ec13db587fb240c5be3c2c1b89fa13 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 5 Jul 2019 15:35:50 +0000 Subject: [PATCH 022/877] More progress on user custom fields in reports. Dropdown custom field selectors are now working. --- WEB-INF/lib/ttReportHelper.class.php | 202 ++++++++++++++++++++++++--- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 184 insertions(+), 20 deletions(-) diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index c5f14228d..ea335cacf 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -52,6 +52,14 @@ static function getWhere($options) { $group_id = $user->getGroup(); $org_id = $user->org_id; + if ($user->isPluginEnabled('cf')) { + global $custom_fields; + if (!$custom_fields) { + require_once('plugins/CustomFields.class.php'); + $custom_fields = new CustomFields(); + } + } // TODO: reconsider the need for construction for fav report emailing (debug). + // A shortcut for timesheets. if ($options['timesheet_id']) { $where = " where l.timesheet_id = ".$options['timesheet_id']." and l.group_id = $group_id and l.org_id = $org_id"; @@ -77,6 +85,17 @@ static function getWhere($options) { if ($options['approved']=='2') $dropdown_parts .= ' and l.approved = 0'; if ($options['paid_status']=='1') $dropdown_parts .= ' and l.paid = 1'; if ($options['paid_status']=='2') $dropdown_parts .= ' and l.paid = 0'; + // Add user custom fields. + if ($custom_fields && $custom_fields->userFields) { + foreach ($custom_fields->userFields as $userField) { + $field_name = 'user_field_'.$userField['id']; + $selected_option_id = $options[$field_name]; + if ($userField['type'] == CustomFields::TYPE_DROPDOWN && $selected_option_id) { + $cfoTable = 'cfo'.$userField['id']; + $dropdown_parts .= " and $cfoTable.id = $selected_option_id"; + } + } + } // Prepare sql query part for user list. $userlist = $options['users'] ? $options['users'] : '-1'; @@ -108,6 +127,14 @@ static function getExpenseWhere($options) { $group_id = $user->getGroup(); $org_id = $user->org_id; + if ($user->isPluginEnabled('cf')) { + global $custom_fields; + if (!$custom_fields) { + require_once('plugins/CustomFields.class.php'); + $custom_fields = new CustomFields(); + } + } // TODO: reconsider the need for construction for fav report emailing (debug). + // Prepare dropdown parts. $dropdown_parts = ''; if ($options['client_id']) @@ -124,6 +151,17 @@ static function getExpenseWhere($options) { if ($options['approved']=='2') $dropdown_parts .= ' and ei.approved = 0'; if ($options['paid_status']=='1') $dropdown_parts .= ' and ei.paid = 1'; if ($options['paid_status']=='2') $dropdown_parts .= ' and ei.paid = 0'; + // Add user custom fields. + if ($custom_fields && $custom_fields->userFields) { + foreach ($custom_fields->userFields as $userField) { + $field_name = 'user_field_'.$userField['id']; + $selected_option_id = $options[$field_name]; + if ($userField['type'] == CustomFields::TYPE_DROPDOWN && $selected_option_id) { + $cfoTable = 'cfo'.$userField['id']; + $dropdown_parts .= " and $cfoTable.id = $selected_option_id"; + } + } + } // Prepare sql query part for user list. $userlist = $options['users'] ? $options['users'] : '-1'; @@ -163,9 +201,12 @@ static function getItems($options) { $isClient = $user->isClient(); if ($user->isPluginEnabled('cf')) { - require_once('plugins/CustomFields.class.php'); - $custom_fields = new CustomFields(); - } + global $custom_fields; + if (!$custom_fields) { + require_once('plugins/CustomFields.class.php'); + $custom_fields = new CustomFields(); + } + } // TODO: reconsider the need for construction for fav report emailing (debug). $grouping = ttReportHelper::grouping($options); if ($grouping) { @@ -613,6 +654,15 @@ static function getTotals($options) global $user; $mdb2 = getConnection(); + // Add user custom fields. + if ($user->isPluginEnabled('cf')) { + global $custom_fields; + if (!$custom_fields) { + require_once('plugins/CustomFields.class.php'); + $custom_fields = new CustomFields(); + } + } // TODO: reconsider the need for construction for fav report emailing (debug). + $trackingMode = $user->getTrackingMode(); $decimalMark = $user->getDecimalMark(); $where = ttReportHelper::getWhere($options); @@ -633,11 +683,35 @@ static function getTotals($options) } else { $cost_part = ", null as cost, null as expenses"; } + + // Prepare left joins. + $left_joins = null; + // Left joins for custom fields. + if ($custom_fields && $custom_fields->userFields) { + foreach ($custom_fields->userFields as $userField) { + $field_name = 'user_field_'.$userField['id']; + $field_value = $options[$field_name]; + $entity_type = CustomFields::ENTITY_USER; + if ($field_value) { + // We need to add left joins when input is not null. + $ecfTable = 'ecf'.$userField['id']; + if ($userField['type'] == CustomFields::TYPE_TEXT) { + // Add one join for each text field. + $left_joins .= " left join tt_entity_custom_fields $ecfTable on ($ecfTable.entity_type = $entity_type and $ecfTable.entity_id = l.user_id and $ecfTable.field_id = ".$userField['id'].")"; + } elseif ($userField['type'] == CustomFields::TYPE_DROPDOWN) { + $cfoTable = 'cfo'.$userField['id']; + // Add two joins for each dropdown field. + $left_joins .= " left join tt_entity_custom_fields $ecfTable on ($ecfTable.entity_type = $entity_type and $ecfTable.entity_id = l.user_id and $ecfTable.field_id = ".$userField['id'].")"; + $left_joins .= " left join tt_custom_field_options $cfoTable on ($cfoTable.field_id = $ecfTable.field_id and $cfoTable.id = $ecfTable.option_id)"; + } + } + } + } if ($options['show_cost']) { if (MODE_TIME == $trackingMode) { - $left_joins = "left join tt_users u on (l.user_id = u.id)"; + $left_joins .= " left join tt_users u on (l.user_id = u.id)"; } else { - $left_joins = "left join tt_user_project_binds upb on (l.user_id = upb.user_id and l.project_id = upb.project_id)"; + $left_joins .= " left join tt_user_project_binds upb on (l.user_id = upb.user_id and l.project_id = upb.project_id)"; } } // Prepare sql query part for inner joins. @@ -659,7 +733,32 @@ static function getTotals($options) $where = ttReportHelper::getExpenseWhere($options); $sql_for_expenses = "select null as time"; if ($options['show_work_units']) $sql_for_expenses .= ", null as units"; - $sql_for_expenses .= ", sum(cost) as cost, sum(cost) as expenses from tt_expense_items ei $where"; + + // Prepate left joins. + $left_joins = null; + // Left joins for custom fields. + if ($custom_fields && $custom_fields->userFields) { + foreach ($custom_fields->userFields as $userField) { + $field_name = 'user_field_'.$userField['id']; + $field_value = $options[$field_name]; + $entity_type = CustomFields::ENTITY_USER; + if ($field_value) { + // We need to add left joins when input is not null. + $ecfTable = 'ecf'.$userField['id']; + if ($userField['type'] == CustomFields::TYPE_TEXT) { + // Add one join for each text field. + $left_joins .= " left join tt_entity_custom_fields $ecfTable on ($ecfTable.entity_type = $entity_type and $ecfTable.entity_id = eil.user_id and $ecfTable.field_id = ".$userField['id'].")"; + } elseif ($userField['type'] == CustomFields::TYPE_DROPDOWN) { + $cfoTable = 'cfo'.$userField['id']; + // Add two joins for each dropdown field. + $left_joins .= " left join tt_entity_custom_fields $ecfTable on ($ecfTable.entity_type = $entity_type and $ecfTable.entity_id = ei.user_id and $ecfTable.field_id = ".$userField['id'].")"; + $left_joins .= " left join tt_custom_field_options $cfoTable on ($cfoTable.field_id = $ecfTable.field_id and $cfoTable.id = $ecfTable.option_id)"; + } + } + } + } + + $sql_for_expenses .= ", sum(cost) as cost, sum(cost) as expenses from tt_expense_items ei $left_joins $where"; // Create a combined query. $combined = "select sum(time) as time"; @@ -1740,29 +1839,61 @@ static function makeCombinedSelectPart($options) { static function makeJoinPart($options) { global $user; + // Add user custom fields. + if ($user->isPluginEnabled('cf')) { + global $custom_fields; + if (!$custom_fields) { + require_once('plugins/CustomFields.class.php'); + $custom_fields = new CustomFields(); + } + } // TODO: reconsider the need for construction for fav report emailing (debug). + $trackingMode = $user->getTrackingMode(); + $left_joins = null; if (ttReportHelper::groupingBy('user', $options) || MODE_TIME == $trackingMode) { - $join .= ' left join tt_users u on (l.user_id = u.id)'; + $left_joins .= ' left join tt_users u on (l.user_id = u.id)'; } if (ttReportHelper::groupingBy('client', $options)) { - $join .= ' left join tt_clients c on (l.client_id = c.id)'; + $left_joins .= ' left join tt_clients c on (l.client_id = c.id)'; } if (ttReportHelper::groupingBy('project', $options)) { - $join .= ' left join tt_projects p on (l.project_id = p.id)'; + $left_joins .= ' left join tt_projects p on (l.project_id = p.id)'; } if (ttReportHelper::groupingBy('task', $options)) { - $join .= ' left join tt_tasks t on (l.task_id = t.id)'; + $left_joins .= ' left join tt_tasks t on (l.task_id = t.id)'; } if (ttReportHelper::groupingBy('cf_1', $options)) { $custom_fields = new CustomFields(); if ($custom_fields->fields[0]['type'] == CustomFields::TYPE_TEXT) - $join .= ' left join tt_custom_field_log cfl on (l.id = cfl.log_id and cfl.status = 1) left join tt_custom_field_options cfo on (cfl.value = cfo.id)'; + $left_joins .= ' left join tt_custom_field_log cfl on (l.id = cfl.log_id and cfl.status = 1) left join tt_custom_field_options cfo on (cfl.value = cfo.id)'; elseif ($custom_fields->fields[0]['type'] == CustomFields::TYPE_DROPDOWN) - $join .= ' left join tt_custom_field_log cfl on (l.id = cfl.log_id and cfl.status = 1) left join tt_custom_field_options cfo on (cfl.option_id = cfo.id)'; + $left_joins .= ' left join tt_custom_field_log cfl on (l.id = cfl.log_id and cfl.status = 1) left join tt_custom_field_options cfo on (cfl.option_id = cfo.id)'; } if ($options['show_cost'] && $trackingMode != MODE_TIME) { - $join .= ' left join tt_user_project_binds upb on (l.user_id = upb.user_id and l.project_id = upb.project_id)'; + $left_joins .= ' left join tt_user_project_binds upb on (l.user_id = upb.user_id and l.project_id = upb.project_id)'; } + // Left joins for custom fields. + if ($custom_fields && $custom_fields->userFields) { + foreach ($custom_fields->userFields as $userField) { + $field_name = 'user_field_'.$userField['id']; + $field_value = $options[$field_name]; + $entity_type = CustomFields::ENTITY_USER; + if ($field_value) { + // We need to add left joins when input is not null. + $ecfTable = 'ecf'.$userField['id']; + if ($userField['type'] == CustomFields::TYPE_TEXT) { + // Add one join for each text field. + $left_joins .= " left join tt_entity_custom_fields $ecfTable on ($ecfTable.entity_type = $entity_type and $ecfTable.entity_id = l.user_id and $ecfTable.field_id = ".$userField['id'].")"; + } elseif ($userField['type'] == CustomFields::TYPE_DROPDOWN) { + $cfoTable = 'cfo'.$userField['id']; + // Add two joins for each dropdown field. + $left_joins .= " left join tt_entity_custom_fields $ecfTable on ($ecfTable.entity_type = $entity_type and $ecfTable.entity_id = l.user_id and $ecfTable.field_id = ".$userField['id'].")"; + $left_joins .= " left join tt_custom_field_options $cfoTable on ($cfoTable.field_id = $ecfTable.field_id and $cfoTable.id = $ecfTable.option_id)"; + } + } + } + } + // Prepare inner joins. $inner_joins = null; if ($user->isPluginEnabled('ts') && $options['timesheet']) { @@ -1774,8 +1905,9 @@ static function makeJoinPart($options) { else if ($timesheet_option == TIMESHEET_NOT_APPROVED) $inner_joins .= " inner join tt_timesheets ts on (l.timesheet_id = ts.id and ts.approve_status = 0)"; } - $join .= $inner_joins; - return $join; + + $join_part = $left_joins.$inner_joins; + return $join_part; } // makeWorkUnitPart builds an sql part for work units for time items. @@ -1812,16 +1944,48 @@ static function makeCostPart($options) { static function makeJoinExpensesPart($options) { global $user; + // Add user custom fields. + if ($user->isPluginEnabled('cf')) { + global $custom_fields; + if (!$custom_fields) { + require_once('plugins/CustomFields.class.php'); + $custom_fields = new CustomFields(); + } + } // TODO: reconsider the need for construction for fav report emailing (debug). + + $left_joins = null; if (ttReportHelper::groupingBy('user', $options)) { - $join .= ' left join tt_users u on (ei.user_id = u.id)'; + $left_joins .= ' left join tt_users u on (ei.user_id = u.id)'; } if (ttReportHelper::groupingBy('client', $options)) { - $join .= ' left join tt_clients c on (ei.client_id = c.id)'; + $left_joins .= ' left join tt_clients c on (ei.client_id = c.id)'; } if (ttReportHelper::groupingBy('project', $options)) { - $join .= ' left join tt_projects p on (ei.project_id = p.id)'; + $left_joins .= ' left join tt_projects p on (ei.project_id = p.id)'; + } + // Left joins for custom fields. + if ($custom_fields && $custom_fields->userFields) { + foreach ($custom_fields->userFields as $userField) { + $field_name = 'user_field_'.$userField['id']; + $field_value = $options[$field_name]; + $entity_type = CustomFields::ENTITY_USER; + if ($field_value) { + // We need to add left joins when input is not null. + $ecfTable = 'ecf'.$userField['id']; + if ($userField['type'] == CustomFields::TYPE_TEXT) { + // Add one join for each text field. + $left_joins .= " left join tt_entity_custom_fields $ecfTable on ($ecfTable.entity_type = $entity_type and $ecfTable.entity_id = ei.user_id and $ecfTable.field_id = ".$userField['id'].")"; + } elseif ($userField['type'] == CustomFields::TYPE_DROPDOWN) { + $cfoTable = 'cfo'.$userField['id']; + // Add two joins for each dropdown field. + $left_joins .= " left join tt_entity_custom_fields $ecfTable on ($ecfTable.entity_type = $entity_type and $ecfTable.entity_id = ei.user_id and $ecfTable.field_id = ".$userField['id'].")"; + $left_joins .= " left join tt_custom_field_options $cfoTable on ($cfoTable.field_id = $ecfTable.field_id and $cfoTable.id = $ecfTable.option_id)"; + } + } + } } - return $join; + + return $left_joins; } // grouping determines if we are grouping the report by either group_by1, diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 38d4596e9..9ad4ba665 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.19.7.5033 | Copyright © Anuko | +  Anuko Time Tracker 1.19.7.5034 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 28940b9d9c48a895cd6222760fcb4ad5ba67a3db Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 5 Jul 2019 16:09:30 +0000 Subject: [PATCH 023/877] Added filtering for user custom fields of type text in reports. --- WEB-INF/lib/ttReportHelper.class.php | 46 ++++++++++++++++++++++------ WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 38 insertions(+), 10 deletions(-) diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index ea335cacf..3b5b9cd3e 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -48,6 +48,7 @@ class ttReportHelper { // getWhere prepares a WHERE clause for a report query. static function getWhere($options) { global $user; + $mdb2 = getConnection(); $group_id = $user->getGroup(); $org_id = $user->org_id; @@ -89,10 +90,23 @@ static function getWhere($options) { if ($custom_fields && $custom_fields->userFields) { foreach ($custom_fields->userFields as $userField) { $field_name = 'user_field_'.$userField['id']; - $selected_option_id = $options[$field_name]; - if ($userField['type'] == CustomFields::TYPE_DROPDOWN && $selected_option_id) { + $field_value = $options[$field_name]; + if ($userField['type'] == CustomFields::TYPE_DROPDOWN && $field_value) { $cfoTable = 'cfo'.$userField['id']; - $dropdown_parts .= " and $cfoTable.id = $selected_option_id"; + $dropdown_parts .= " and $cfoTable.id = $field_value"; + } + } + } + + // Prepare part for text custom fields using LIKE operator. + $cf_text_parts = null; + if ($custom_fields && $custom_fields->userFields) { + foreach ($custom_fields->userFields as $userField) { + $field_name = 'user_field_'.$userField['id']; + $field_value = $options[$field_name]; + if ($userField['type'] == CustomFields::TYPE_TEXT && $field_value) { + $ecfTableName = 'ecf'.$userField['id']; + $cf_text_parts .= " and $ecfTableName.value like ".$mdb2->quote("%$field_value%"); } } } @@ -116,13 +130,14 @@ static function getWhere($options) { new DateAndTime($dateFormat, $options['period_end'])); } $where = " where l.status = 1 and l.date >= '".$period->getStartDate(DB_DATEFORMAT)."' and l.date <= '".$period->getEndDate(DB_DATEFORMAT)."'". - " $user_list_part $dropdown_parts"; + " $user_list_part $dropdown_parts $cf_text_parts"; return $where; } // getExpenseWhere prepares WHERE clause for expenses query in a report. static function getExpenseWhere($options) { global $user; + $mdb2 = getConnection(); $group_id = $user->getGroup(); $org_id = $user->org_id; @@ -155,10 +170,23 @@ static function getExpenseWhere($options) { if ($custom_fields && $custom_fields->userFields) { foreach ($custom_fields->userFields as $userField) { $field_name = 'user_field_'.$userField['id']; - $selected_option_id = $options[$field_name]; - if ($userField['type'] == CustomFields::TYPE_DROPDOWN && $selected_option_id) { + $field_value = $options[$field_name]; + if ($userField['type'] == CustomFields::TYPE_DROPDOWN && $field_value) { $cfoTable = 'cfo'.$userField['id']; - $dropdown_parts .= " and $cfoTable.id = $selected_option_id"; + $dropdown_parts .= " and $cfoTable.id = $field_value"; + } + } + } + + // Prepare part for text custom fields using LIKE operator. + $cf_text_parts = null; + if ($custom_fields && $custom_fields->userFields) { + foreach ($custom_fields->userFields as $userField) { + $field_name = 'user_field_'.$userField['id']; + $field_value = $options[$field_name]; + if ($userField['type'] == CustomFields::TYPE_TEXT && $field_value) { + $ecfTableName = 'ecf'.$userField['id']; + $cf_text_parts .= " and $ecfTableName.value like ".$mdb2->quote("%$field_value%"); } } } @@ -182,7 +210,7 @@ static function getExpenseWhere($options) { new DateAndTime($dateFormat, $options['period_end'])); } $where = " where ei.status = 1 and ei.date >= '".$period->getStartDate(DB_DATEFORMAT)."' and ei.date <= '".$period->getEndDate(DB_DATEFORMAT)."'". - " $user_list_part $dropdown_parts"; + " $user_list_part $dropdown_parts $cf_text_parts"; return $where; } @@ -747,7 +775,7 @@ static function getTotals($options) $ecfTable = 'ecf'.$userField['id']; if ($userField['type'] == CustomFields::TYPE_TEXT) { // Add one join for each text field. - $left_joins .= " left join tt_entity_custom_fields $ecfTable on ($ecfTable.entity_type = $entity_type and $ecfTable.entity_id = eil.user_id and $ecfTable.field_id = ".$userField['id'].")"; + $left_joins .= " left join tt_entity_custom_fields $ecfTable on ($ecfTable.entity_type = $entity_type and $ecfTable.entity_id = ei.user_id and $ecfTable.field_id = ".$userField['id'].")"; } elseif ($userField['type'] == CustomFields::TYPE_DROPDOWN) { $cfoTable = 'cfo'.$userField['id']; // Add two joins for each dropdown field. diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 9ad4ba665..e32c1b4ec 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.19.7.5034 | Copyright © Anuko | +  Anuko Time Tracker 1.19.7.5035 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 94c65ebc6d0ca1032675ba0ec9415bfdbe4527c1 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 5 Jul 2019 18:22:06 +0000 Subject: [PATCH 024/877] Starting to work on multiple time custom fields. --- WEB-INF/resources/ca.lang.php | 1 + WEB-INF/resources/cs.lang.php | 1 + WEB-INF/resources/da.lang.php | 1 + WEB-INF/resources/de.lang.php | 1 + WEB-INF/resources/en.lang.php | 1 + WEB-INF/resources/es.lang.php | 1 + WEB-INF/resources/et.lang.php | 1 + WEB-INF/resources/fa.lang.php | 1 + WEB-INF/resources/fi.lang.php | 1 + WEB-INF/resources/fr.lang.php | 1 + WEB-INF/resources/gr.lang.php | 1 + WEB-INF/resources/he.lang.php | 1 + WEB-INF/resources/hu.lang.php | 1 + WEB-INF/resources/it.lang.php | 1 + WEB-INF/resources/ja.lang.php | 1 + WEB-INF/resources/ko.lang.php | 1 + WEB-INF/resources/nl.lang.php | 1 + WEB-INF/resources/no.lang.php | 1 + WEB-INF/resources/pl.lang.php | 1 + WEB-INF/resources/pt-br.lang.php | 1 + WEB-INF/resources/pt.lang.php | 1 + WEB-INF/resources/ro.lang.php | 1 + WEB-INF/resources/ru.lang.php | 3 ++- WEB-INF/resources/sk.lang.php | 1 + WEB-INF/resources/sl.lang.php | 1 + WEB-INF/resources/sr.lang.php | 1 + WEB-INF/resources/sv.lang.php | 1 + WEB-INF/resources/tr.lang.php | 1 + WEB-INF/resources/zh-cn.lang.php | 1 + WEB-INF/resources/zh-tw.lang.php | 1 + WEB-INF/templates/footer.tpl | 2 +- 31 files changed, 32 insertions(+), 2 deletions(-) diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index 58ecdbe83..d82477c93 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -486,6 +486,7 @@ 'form.reports.set_period' => 'o establir dates', 'form.reports.show_fields' => 'Mostrar camps', // TODO: translate the following. +// 'form.reports.time_fields' => 'Time fields', // 'form.reports.user_fields' => 'User fields', 'form.reports.group_by' => 'Agrupar per', 'form.reports.group_by_no' => '--- no agrupar ---', diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index 7043206d8..08649ff02 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -495,6 +495,7 @@ 'form.reports.set_period' => 'nebo určete dny', 'form.reports.show_fields' => 'Zobrazit pole', // TODO: translate the following. +// 'form.reports.time_fields' => 'Time fields', // 'form.reports.user_fields' => 'User fields', 'form.reports.group_by' => 'Seskupit podle', // TODO: translate the following. diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index 863ffcf0c..c33097402 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -467,6 +467,7 @@ 'form.reports.set_period' => 'eller sæt datoer', 'form.reports.show_fields' => 'Vis felter', // TODO: translate the following. +// 'form.reports.time_fields' => 'Time fields', // 'form.reports.user_fields' => 'User fields', 'form.reports.group_by' => 'Gruppér ved', 'form.reports.group_by_no' => '--- Ingen gruppereing ---', diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index 1e23983a5..8c9e47b73 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -449,6 +449,7 @@ 'form.reports.set_period' => 'oder Datum eingeben', 'form.reports.show_fields' => 'Felder anzeigen', // TODO: translate the following. +// 'form.reports.time_fields' => 'Time fields', // 'form.reports.user_fields' => 'User fields', 'form.reports.group_by' => 'Gruppieren nach', 'form.reports.group_by_no' => '--- keine Gruppierung ---', diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index 0b48ae6ba..b00abf288 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -435,6 +435,7 @@ 'form.reports.select_period' => 'Select time period', 'form.reports.set_period' => 'or set dates', 'form.reports.show_fields' => 'Show fields', +'form.reports.time_fields' => 'Time fields', 'form.reports.user_fields' => 'User fields', 'form.reports.group_by' => 'Group by', 'form.reports.group_by_no' => '--- no grouping ---', diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index e46c5f30a..7165bd7ba 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -499,6 +499,7 @@ 'form.reports.set_period' => 'o establecer fechas', 'form.reports.show_fields' => 'Mostrar campos', // TODO: translate the following. +// 'form.reports.time_fields' => 'Time fields', // 'form.reports.user_fields' => 'User fields', 'form.reports.group_by' => 'Agrupar por', 'form.reports.group_by_no' => '--- no agrupar ---', diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index 07c2589b3..8584fc085 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -476,6 +476,7 @@ 'form.reports.set_period' => 'või märgi kuupäevad', 'form.reports.show_fields' => 'Näita välju', // TODO: translate the following. +// 'form.reports.time_fields' => 'Time fields', // 'form.reports.user_fields' => 'User fields', 'form.reports.group_by' => 'Grupeeri', 'form.reports.group_by_no' => '--- grupeerimata ---', diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index f81cef522..4f6573105 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -488,6 +488,7 @@ 'form.reports.set_period' => 'یا تعیین تاریخ', 'form.reports.show_fields' => 'نمایش فیلدها', // TODO: translate the following. +// 'form.reports.time_fields' => 'Time fields', // 'form.reports.user_fields' => 'User fields', 'form.reports.group_by' => 'گروه بندی شده با', 'form.reports.group_by_no' => '--- بدون گروه ---', diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 020c34624..c7d99e007 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -472,6 +472,7 @@ 'form.reports.set_period' => 'tai aseta päivät', 'form.reports.show_fields' => 'Näytä kentät', // TODO: translate the following. +// 'form.reports.time_fields' => 'Time fields', // 'form.reports.user_fields' => 'User fields', 'form.reports.group_by' => 'Ryhmittelyperuste', 'form.reports.group_by_no' => '--- ei ryhmitystä ---', diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index 04d092d2a..870eb67bf 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -464,6 +464,7 @@ 'form.reports.set_period' => 'ou dates indiquées', 'form.reports.show_fields' => 'Afficher les champs', // TODO: translate the following. +// 'form.reports.time_fields' => 'Time fields', // 'form.reports.user_fields' => 'User fields', 'form.reports.group_by' => 'Regroupés par', 'form.reports.group_by_no' => '--- Aucun regroupement ---', diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index 66e349f0c..d5a305c26 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -458,6 +458,7 @@ 'form.reports.set_period' => 'ή εύρος ημερομηνιών', 'form.reports.show_fields' => 'Εμφάνιση πεδίων', // TODO: translate the following. +// 'form.reports.time_fields' => 'Time fields', // 'form.reports.user_fields' => 'User fields', 'form.reports.group_by' => 'Ομαδοποίηση με βάση', 'form.reports.group_by_no' => '--- χωρίς ομαδοποίηση ---', diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index 5046f0b42..2a8b16084 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -490,6 +490,7 @@ 'form.reports.set_period' => 'או הגדר תאריכים', 'form.reports.show_fields' => 'הראה שדות', // TODO: translate the following. +// 'form.reports.time_fields' => 'Time fields', // 'form.reports.user_fields' => 'User fields', 'form.reports.group_by' => 'סדר לפי', 'form.reports.group_by_no' => '--- ללא סדר ---', diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index dbdfc9334..4bf29d59d 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -490,6 +490,7 @@ 'form.reports.set_period' => 'vagy állíts be konkrét dátumot', // TODO: translate the following. // 'form.reports.show_fields' => 'Show fields', +// 'form.reports.time_fields' => 'Time fields', // 'form.reports.user_fields' => 'User fields', 'form.reports.group_by' => 'Csoportosítva', 'form.reports.group_by_no' => '--- csoportosítás nélkül ---', diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index 1423b52f2..50d9af909 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -471,6 +471,7 @@ 'form.reports.set_period' => 'oppure setta le date', 'form.reports.show_fields' => 'Mostra i campi', // TODO: translate the following. +// 'form.reports.time_fields' => 'Time fields', // 'form.reports.user_fields' => 'User fields', 'form.reports.group_by' => 'Raggruppa per', 'form.reports.group_by_no' => '--- non raggruppare ---', diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index a0182a327..b57a92398 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -495,6 +495,7 @@ 'form.reports.set_period' => 'あるいは日付を設定', 'form.reports.show_fields' => 'フィールドの表示', // TODO: translate the following. +// 'form.reports.time_fields' => 'Time fields', // 'form.reports.user_fields' => 'User fields', 'form.reports.group_by' => '次のようにグループ化', 'form.reports.group_by_no' => '--- グループの機能がありません ---', diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index 4d733a1ff..db58959f5 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -493,6 +493,7 @@ 'form.reports.set_period' => '혹은 날짜를 설정', 'form.reports.show_fields' => '필드들을 보기', // TODO: translate the following. +// 'form.reports.time_fields' => 'Time fields', // 'form.reports.user_fields' => 'User fields', 'form.reports.group_by' => '다음것에 의한 그룹화', 'form.reports.group_by_no' => '--- 그룹화되지 않음 ---', diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 4d088c4c6..8ede3f3f6 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -431,6 +431,7 @@ 'form.reports.set_period' => 'of stel datums in', 'form.reports.show_fields' => 'Toon velden', // TODO: translate the following. +// 'form.reports.time_fields' => 'Time fields', // 'form.reports.user_fields' => 'User fields', 'form.reports.group_by' => 'Groeperen op', 'form.reports.group_by_no' => '--- niet groeperen ---', diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index fbf1f7c44..72812e4f3 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -492,6 +492,7 @@ 'form.reports.set_period' => 'eller sett dato', 'form.reports.show_fields' => 'Vis feltene', // TODO: translate the following. +// 'form.reports.time_fields' => 'Time fields', // 'form.reports.user_fields' => 'User fields', // 'form.reports.group_by' => 'Group by', // 'form.reports.group_by_no' => '--- no grouping ---', diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index 215508768..8e7684f21 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -475,6 +475,7 @@ 'form.reports.set_period' => 'lub ustaw daty', 'form.reports.show_fields' => 'Pokaż pola', // TODO: translate the following. +// 'form.reports.time_fields' => 'Time fields', // 'form.reports.user_fields' => 'User fields', 'form.reports.group_by' => 'Grupowanie wg', 'form.reports.group_by_no' => '--- bez grupowania ---', diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index 59ae7060b..9f31b6a57 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -470,6 +470,7 @@ 'form.reports.set_period' => 'ou selecionar datas', 'form.reports.show_fields' => 'Exibir campos', // TODO: translate the following. +// 'form.reports.time_fields' => 'Time fields', // 'form.reports.user_fields' => 'User fields', 'form.reports.group_by' => 'Agrupar por', 'form.reports.group_by_no' => '--- sem agrupar ---', diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index 1ab616638..bfd153a25 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -473,6 +473,7 @@ 'form.reports.set_period' => 'ou selecionar datas', 'form.reports.show_fields' => 'Exibir campos', // TODO: translate the following. +// 'form.reports.time_fields' => 'Time fields', // 'form.reports.user_fields' => 'User fields', // 'form.reports.group_by' => 'Group by', // 'form.reports.group_by_no' => '--- no grouping ---', diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index aea10d080..0a8b16bcc 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -494,6 +494,7 @@ 'form.reports.set_period' => 'sau introdu intervalul de date', 'form.reports.show_fields' => 'Arata campuri', // TODO: translate the following. +// 'form.reports.time_fields' => 'Time fields', // 'form.reports.user_fields' => 'User fields', 'form.reports.group_by' => 'Grupat dupa', 'form.reports.group_by_no' => '--- fara grupare ---', diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index bf267018e..05d3693ac 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -426,7 +426,8 @@ 'form.reports.select_period' => 'Выберите интервал времени', 'form.reports.set_period' => 'или укажите даты', 'form.reports.show_fields' => 'Показывать поля', -'form.reports.user_fields' => 'Поля пользователя', +'form.reports.time_fields' => 'Time fields', +'form.reports.user_fields' => 'Поля времени', 'form.reports.group_by' => 'Группировать по', 'form.reports.group_by_no' => '--- без группировки ---', 'form.reports.group_by_date' => 'дате', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index c3d1dd247..834adf5b8 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -480,6 +480,7 @@ 'form.reports.set_period' => 'alebo nastavte dátumy', 'form.reports.show_fields' => 'Zobraziť polia', // TODO: translate the following. +// 'form.reports.time_fields' => 'Time fields', // 'form.reports.user_fields' => 'User fields', // 'form.reports.group_by' => 'Group by', // 'form.reports.group_by_no' => '--- no grouping ---', diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index 4b6aae579..b8363b6ae 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -467,6 +467,7 @@ // 'form.reports.select_period' => 'Select time period', // 'form.reports.set_period' => 'or set dates', // 'form.reports.show_fields' => 'Show fields', +// 'form.reports.time_fields' => 'Time fields', // 'form.reports.user_fields' => 'User fields', // 'form.reports.group_by' => 'Group by', // 'form.reports.group_by_no' => '--- no grouping ---', diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index 08a9460e9..ff68be79a 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -473,6 +473,7 @@ 'form.reports.set_period' => 'ili podesi datum', 'form.reports.show_fields' => 'Prikaži polja u izveštaju', // TODO: translate the following. +// 'form.reports.time_fields' => 'Time fields', // 'form.reports.user_fields' => 'User fields', 'form.reports.group_by' => 'Grupiši po', 'form.reports.group_by_no' => '--- nemoj grupisati ---', diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index adb883cb4..3c108e18f 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -472,6 +472,7 @@ 'form.reports.set_period' => 'eller ställ in datum', 'form.reports.show_fields' => 'Visa fält', // TODO: translate the following. +// 'form.reports.time_fields' => 'Time fields', // 'form.reports.user_fields' => 'User fields', 'form.reports.group_by' => 'Gruppera efter', 'form.reports.group_by_no' => '--- Ingen gruppering ---', diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index abeb693e3..1f88bf79e 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -505,6 +505,7 @@ 'form.reports.set_period' => 'ya da tarihleri belirle', 'form.reports.show_fields' => 'Alanları göster', // TODO: translate the following. +// 'form.reports.time_fields' => 'Time fields', // 'form.reports.user_fields' => 'User fields', 'form.reports.group_by' => 'Gruplandırma kıstas', 'form.reports.group_by_no' => '--- gruplama yok ---', diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index 92f9ecd1c..0f6ac781e 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -479,6 +479,7 @@ 'form.reports.set_period' => '或设定日期', 'form.reports.show_fields' => '显示栏目', // TODO: translate the following. +// 'form.reports.time_fields' => 'Time fields', // 'form.reports.user_fields' => 'User fields', 'form.reports.group_by' => '分组方式', 'form.reports.group_by_no' => '--- 没有分组 ---', diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index def3a0acf..6168289fc 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -485,6 +485,7 @@ 'form.reports.set_period' => '或設定日期', 'form.reports.show_fields' => '顯示欄目', // TODO: translate the following. +// 'form.reports.time_fields' => 'Time fields', // 'form.reports.user_fields' => 'User fields', 'form.reports.group_by' => '分組方式', 'form.reports.group_by_no' => '--- 沒有分組 ---', diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index e32c1b4ec..c00ac59b2 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- -{if isTrue('CF_DEBUG')} {if $custom_fields && $custom_fields->timeFields} {foreach $custom_fields->timeFields as $timeField} @@ -411,7 +403,6 @@ function handleCheckboxes() { {/foreach} {/if} -{/if} {if $custom_fields && $custom_fields->userFields} {foreach $custom_fields->userFields as $userField} diff --git a/WEB-INF/templates/time.tpl b/WEB-INF/templates/time.tpl index e3266076b..94be028b3 100644 --- a/WEB-INF/templates/time.tpl +++ b/WEB-INF/templates/time.tpl @@ -36,10 +36,14 @@ {/if} -{if ($custom_fields && $custom_fields->fields[0])} - - - +{if $custom_fields && $custom_fields->timeFields} + {foreach $custom_fields->timeFields as $timeField} + + + {assign var="control_name" value='time_field_'|cat:$timeField['id']} + + + {/foreach} {/if} {if $show_project} @@ -112,9 +116,6 @@ {if $show_client} {/if} - {if $show_cf_1} - - {/if} {if $show_project} {/if} @@ -142,9 +143,6 @@ {if $show_client} {/if} - {if $show_cf_1} - - {/if} {if $show_project} {/if} diff --git a/WEB-INF/templates/time_edit.tpl b/WEB-INF/templates/time_edit.tpl index 42b1674d4..5b0e3e2de 100644 --- a/WEB-INF/templates/time_edit.tpl +++ b/WEB-INF/templates/time_edit.tpl @@ -40,10 +40,14 @@ function confirmSave() { {/if} -{if ($custom_fields && $custom_fields->fields[0])} +{if $custom_fields && $custom_fields->timeFields} + {foreach $custom_fields->timeFields as $timeField} - + + {assign var="control_name" value='time_field_'|cat:$timeField['id']} + + {/foreach} {/if} {if ($smarty.const.MODE_PROJECTS == $user->tracking_mode || $smarty.const.MODE_PROJECTS_AND_TASKS == $user->tracking_mode)} diff --git a/WEB-INF/templates/week.tpl b/WEB-INF/templates/week.tpl index 6f97c4d2a..fbf512ceb 100644 --- a/WEB-INF/templates/week.tpl +++ b/WEB-INF/templates/week.tpl @@ -51,10 +51,14 @@ function fillDropdowns() { {/if} -{if ($custom_fields && $custom_fields->fields[0])} - - - +{if $custom_fields && $custom_fields->timeFields} + {foreach $custom_fields->timeFields as $timeField} + + + {assign var="control_name" value='time_field_'|cat:$timeField['id']} + + + {/foreach} {/if} {if $show_project} diff --git a/cf_custom_field_add.php b/cf_custom_field_add.php index e8de69e7e..961bdd69a 100644 --- a/cf_custom_field_add.php +++ b/cf_custom_field_add.php @@ -40,11 +40,6 @@ exit(); } $fields = CustomFields::getFields(); -// Deny access when max number of custom fields is already set. -if (count($fields) >= 1 && !isTrue('CF_DEBUG')) { - header('Location: access_denied.php'); - exit(); -} // End of access checks. if ($request->isPost()) { diff --git a/cf_custom_fields.php b/cf_custom_fields.php index d877e7c46..cf14f25eb 100644 --- a/cf_custom_fields.php +++ b/cf_custom_fields.php @@ -53,9 +53,6 @@ $form->addInput(array('type'=>'submit','name'=>'btn_add','value'=>$i18n->get('button.add'))); $fields = CustomFields::getFields(); - // At this time only one custom field is supported. Disable the Add button if we already have one or more custom fields. - if (count($fields) > 0 && !isTrue('CF_DEBUG')) - $form->getElement('btn_add')->setEnabled(false); } $smarty->assign('forms', array($form->getName()=>$form->toArray())); diff --git a/mobile/time.php b/mobile/time.php index 996521691..04c25060f 100644 --- a/mobile/time.php +++ b/mobile/time.php @@ -110,6 +110,22 @@ $cl_task = $request->getParameter('task', ($request->isPost() ? null : @$_SESSION['task'])); $_SESSION['task'] = $cl_task; +$timeCustomFields = array(); +// If we have time custom fields - collect input. +if ($request->isPost()) { + if ($custom_fields && $custom_fields->timeFields) { + foreach ($custom_fields->timeFields as $timeField) { + $control_name = 'time_field_'.$timeField['id']; + $timeCustomFields[$timeField['id']] = array('field_id' => $timeField['id'], + 'control_name' => $control_name, + 'label' => $timeField['label'], + 'type' => $timeField['type'], + 'required' => $timeField['required'], + 'value' => trim($request->getParameter($control_name))); + } + } +} + // Elements of timeRecordForm. $form = new Form('timeRecordForm'); if ($user->can('track_time')) { @@ -214,17 +230,19 @@ $form->addInput(array('type'=>'hidden','name'=>'browser_today','value'=>'')); // User current date, which gets filled in on btn_submit click. $form->addInput(array('type'=>'submit','name'=>'btn_submit','onclick'=>'browser_today.value=get_date()','value'=>$i18n->get('button.submit'))); -// If we have custom fields - add controls for them. -if ($custom_fields && $custom_fields->fields[0]) { - // Only one custom field is supported at this time. - if ($custom_fields->fields[0]['type'] == CustomFields::TYPE_TEXT) { - $form->addInput(array('type'=>'text','name'=>'cf_1','value'=>$cl_cf_1)); - } elseif ($custom_fields->fields[0]['type'] == CustomFields::TYPE_DROPDOWN) { - $form->addInput(array('type'=>'combobox','name'=>'cf_1', +// If we have time custom fields - add controls for them. +if ($custom_fields && $custom_fields->timeFields) { + foreach ($custom_fields->timeFields as $timeField) { + $field_name = 'time_field_'.$timeField['id']; + if ($timeField['type'] == CustomFields::TYPE_TEXT) { + $form->addInput(array('type'=>'text','name'=>$field_name,'style'=>'width: 250px;','value'=>$timeCustomFields[$timeField['id']]['value'])); + } elseif ($timeField['type'] == CustomFields::TYPE_DROPDOWN) { + $form->addInput(array('type'=>'combobox','name'=>$field_name, 'style'=>'width: 250px;', - 'value'=>$cl_cf_1, - 'data'=>CustomFields::getOptions($custom_fields->fields[0]['id']), + 'data'=>CustomFields::getOptions($timeField['id']), + 'value'=>$timeCustomFields[$timeField['id']]['value'], 'empty'=>array(''=>$i18n->get('dropdown.select')))); + } } } @@ -251,8 +269,12 @@ // Validate user input. if ($user->isPluginEnabled('cl') && $user->isOptionEnabled('client_required') && !$cl_client) $err->add($i18n->get('error.client')); - if ($custom_fields) { - if (!ttValidString($cl_cf_1, !$custom_fields->fields[0]['required'])) $err->add($i18n->get('error.field'), $custom_fields->fields[0]['label']); + // Validate input in time custom fields. + if ($custom_fields && $custom_fields->timeFields) { + foreach ($timeCustomFields as $timeField) { + // Validation is the same for text and dropdown fields. + if (!ttValidString($timeField['value'], !$timeField['required'])) $err->add($i18n->get('error.field'), htmlspecialchars($timeField['label'])); + } } if (MODE_PROJECTS == $user->getTrackingMode() || MODE_PROJECTS_AND_TASKS == $user->getTrackingMode()) { if (!$cl_project) $err->add($i18n->get('error.project')); @@ -327,13 +349,10 @@ 'note' => $cl_note, 'billable' => $cl_billable)); - // Insert a custom field if we have it. + // Insert time custom fields if we have them. $result = true; - if ($id && $custom_fields && $cl_cf_1) { - if ($custom_fields->fields[0]['type'] == CustomFields::TYPE_TEXT) - $result = $custom_fields->insert($id, $custom_fields->fields[0]['id'], null, $cl_cf_1); - elseif ($custom_fields->fields[0]['type'] == CustomFields::TYPE_DROPDOWN) - $result = $custom_fields->insert($id, $custom_fields->fields[0]['id'], $cl_cf_1, null); + if ($id && $custom_fields && $custom_fields->timeFields) { + $result = $custom_fields->insertTimeFields($id, $timeCustomFields); } if ($id && $result) { diff --git a/mobile/time_edit.php b/mobile/time_edit.php index c3a7ccd78..bce156661 100644 --- a/mobile/time_edit.php +++ b/mobile/time_edit.php @@ -68,7 +68,18 @@ $cl_duration = trim($request->getParameter('duration')); $cl_date = $request->getParameter('date'); $cl_note = trim($request->getParameter('note')); - $cl_cf_1 = trim($request->getParameter('cf_1')); + // If we have user custom fields - collect input. + if ($custom_fields && $custom_fields->timeFields) { + foreach ($custom_fields->timeFields as $timeField) { + $control_name = 'time_field_'.$timeField['id']; + $timeCustomFields[$timeField['id']] = array('field_id' => $timeField['id'], + 'control_name' => $control_name, + 'label' => $timeField['label'], + 'type' => $timeField['type'], + 'required' => $timeField['required'], + 'value' => trim($request->getParameter($control_name))); + } + } $cl_client = $request->getParameter('client'); $cl_project = $request->getParameter('project'); $cl_task = $request->getParameter('task'); @@ -85,14 +96,17 @@ $cl_date = $item_date->toString($user->date_format); $cl_note = $time_rec['comment']; - // If we have custom fields - obtain values for them. - if ($custom_fields) { - // Get custom field value for time record. - $fields = $custom_fields->get($time_rec['id']); - if ($custom_fields->fields[0]['type'] == CustomFields::TYPE_TEXT) - $cl_cf_1 = $fields[0]['value']; - elseif ($custom_fields->fields[0]['type'] == CustomFields::TYPE_DROPDOWN) - $cl_cf_1 = $fields[0]['option_id']; + // If we have time custom fields - collect values from database. + if ($custom_fields && $custom_fields->timeFields) { + foreach ($custom_fields->timeFields as $timeField) { + $control_name = 'time_field_'.$timeField['id']; + $timeCustomFields[$timeField['id']] = array('field_id' => $timeField['id'], + 'control_name' => $control_name, + 'label' => $timeField['label'], + 'type' => $timeField['type'], + 'required' => $timeField['required'], + 'value' => $custom_fields->getTimeFieldValue($cl_id, $timeField['id'], $timeField['type'])); + } } $cl_billable = $time_rec['billable']; @@ -189,18 +203,19 @@ $form->addInput(array('type'=>'datefield','name'=>'date','maxlength'=>'20','value'=>$cl_date)); $form->addInput(array('type'=>'textarea','name'=>'note','class'=>'mobile-textarea','value'=>$cl_note)); -// If we have custom fields - add controls for them. -if ($custom_fields && $custom_fields->fields[0]) { - // Only one custom field is supported at this time. - if ($custom_fields->fields[0]['type'] == CustomFields::TYPE_TEXT) { - $form->addInput(array('type'=>'text','name'=>'cf_1','value'=>$cl_cf_1)); - } elseif ($custom_fields->fields[0]['type'] == CustomFields::TYPE_DROPDOWN) { - $form->addInput(array('type'=>'combobox', - 'name'=>'cf_1', +// If we have time custom fields - add controls for them. +if ($custom_fields && $custom_fields->timeFields) { + foreach ($custom_fields->timeFields as $timeField) { + $field_name = 'time_field_'.$timeField['id']; + if ($timeField['type'] == CustomFields::TYPE_TEXT) { + $form->addInput(array('type'=>'text','name'=>$field_name,'value'=>$timeCustomFields[$timeField['id']]['value'])); + } elseif ($timeField['type'] == CustomFields::TYPE_DROPDOWN) { + $form->addInput(array('type'=>'combobox','name'=>$field_name, 'style'=>'width: 250px;', - 'value'=>$cl_cf_1, - 'data'=>CustomFields::getOptions($custom_fields->fields[0]['id']), - 'empty' => array('' => $i18n->get('dropdown.select')))); + 'data'=>CustomFields::getOptions($timeField['id']), + 'value'=>$timeCustomFields[$timeField['id']]['value'], + 'empty'=>array(''=>$i18n->get('dropdown.select')))); + } } } @@ -236,8 +251,12 @@ // Validate user input. if ($user->isPluginEnabled('cl') && $user->isOptionEnabled('client_required') && !$cl_client) $err->add($i18n->get('error.client')); - if ($custom_fields) { - if (!ttValidString($cl_cf_1, !$custom_fields->fields[0]['required'])) $err->add($i18n->get('error.field'), $custom_fields->fields[0]['label']); + // Validate input in time custom fields. + if ($custom_fields && $custom_fields->timeFields) { + foreach ($timeCustomFields as $timeField) { + // Validation is the same for text and dropdown fields. + if (!ttValidString($timeField['value'], !$timeField['required'])) $err->add($i18n->get('error.field'), htmlspecialchars($timeField['label'])); + } } if (MODE_PROJECTS == $user->tracking_mode || MODE_PROJECTS_AND_TASKS == $user->tracking_mode) { if (!$cl_project) $err->add($i18n->get('error.project')); @@ -336,12 +355,9 @@ 'note'=>$cl_note, 'billable'=>$cl_billable)); - // If we have custom fields - update values. - if ($res && $custom_fields) { - if ($custom_fields->fields[0]['type'] == CustomFields::TYPE_TEXT) - $res = $custom_fields->update($cl_id, $custom_fields->fields[0]['id'], null, $cl_cf_1); - elseif ($custom_fields->fields[0]['type'] == CustomFields::TYPE_DROPDOWN) - $res = $custom_fields->update($cl_id, $custom_fields->fields[0]['id'], $cl_cf_1, null); + // Update time custom fields if we have them. + if ($res && $custom_fields && $custom_fields->timeFields) { + $res = $custom_fields->updateTimeFields($cl_id, $timeCustomFields); } if ($res) { @@ -398,13 +414,10 @@ 'billable'=>$cl_billable, 'paid'=>$cl_paid)); - // Insert a custom field if we have it. + // Insert time custom fields if we have them. $res = true; - if ($id && $custom_fields && $cl_cf_1) { - if ($custom_fields->fields[0]['type'] == CustomFields::TYPE_TEXT) - $res = $custom_fields->insert($id, $custom_fields->fields[0]['id'], null, $cl_cf_1); - elseif ($custom_fields->fields[0]['type'] == CustomFields::TYPE_DROPDOWN) - $res = $custom_fields->insert($id, $custom_fields->fields[0]['id'], $cl_cf_1, null); + if ($id && $custom_fields && $custom_fields->timeFields) { + $res = $custom_fields->insertTimeFields($id, $timeCustomFields); } if ($id && $res) { header('Location: time.php?date='.$new_date->toString(DB_DATEFORMAT)); diff --git a/plugins/CustomFields.class.php b/plugins/CustomFields.class.php index f0ff0a4db..a11e40a32 100644 --- a/plugins/CustomFields.class.php +++ b/plugins/CustomFields.class.php @@ -1,4 +1,5 @@ getGroup(); - $org_id = $user->org_id; - - // Get fields. - $sql = "select id, entity_type, type, label, required from tt_custom_fields". - " where group_id = $group_id and org_id = $org_id and status = 1 and type > 0"; - $res = $mdb2->query($sql); - if (!is_a($res, 'PEAR_Error')) { - while ($val = $res->fetchRow()) { - $this->fields[] = array('id'=>$val['id'],'type'=>$val['type'],'label'=>$val['label'],'required'=>$val['required'],'value'=>''); - if (CustomFields::ENTITY_TIME == $val['entity_type']) - $this->timeFields[] = $val; - else if (CustomFields::ENTITY_USER == $val['entity_type']) - $this->userFields[] = $val; - else if (CustomFields::ENTITY_PROJECT == $val['entity_type']) - $this->projectFields[] = $val; - } + // Definitions of custom field types. + const ENTITY_TIME = 1; // Field is associated with time entries. + const ENTITY_USER = 2; // Field is associated with users. + const ENTITY_PROJECT = 3; // Field is associated with projects. + const TYPE_TEXT = 1; // A text field. + const TYPE_DROPDOWN = 2; // A dropdown field with pre-defined values. + + // TODO: replace $fields with entity-specific arrays: timeFields, userFields, etc. + + var $fields = array(); // Array of custom fields for group. + // Refactoring ongoing... + var $timeFields = null; + var $userFields = null; + var $projectFields = null; + + // Constructor. + function __construct() { + global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + // Get fields. + $sql = "select id, entity_type, type, label, required from tt_custom_fields" . + " where group_id = $group_id and org_id = $org_id and status = 1 and type > 0"; + $res = $mdb2->query($sql); + if (!is_a($res, 'PEAR_Error')) { + while ($val = $res->fetchRow()) { + $this->fields[] = array('id' => $val['id'], 'type' => $val['type'], 'label' => $val['label'], 'required' => $val['required'], 'value' => ''); + if (CustomFields::ENTITY_TIME == $val['entity_type']) + $this->timeFields[] = $val; + else if (CustomFields::ENTITY_USER == $val['entity_type']) + $this->userFields[] = $val; + else if (CustomFields::ENTITY_PROJECT == $val['entity_type']) + $this->projectFields[] = $val; + } + } + } + + function insert($log_id, $field_id, $option_id, $value) { + global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $sql = "insert into tt_custom_field_log (group_id, org_id, log_id, field_id, option_id, value)" . + " values($group_id, $org_id, $log_id, $field_id, " . $mdb2->quote($option_id) . ", " . $mdb2->quote($value) . ")"; + $affected = $mdb2->exec($sql); + return (!is_a($affected, 'PEAR_Error')); + } + + function update($log_id, $field_id, $option_id, $value) { + if (!$field_id) + return true; // Nothing to update. + + // Remove older custom field values. + $res = $this->delete($log_id); + if (!$res) + return false; + + if (!$value && !$option_id) + return true; // Do not insert NULL values. + + return $this->insert($log_id, $field_id, $option_id, $value); } - } - - function insert($log_id, $field_id, $option_id, $value) { - global $user; - $mdb2 = getConnection(); - - $group_id = $user->getGroup(); - $org_id = $user->org_id; - - $sql = "insert into tt_custom_field_log (group_id, org_id, log_id, field_id, option_id, value)". - " values($group_id, $org_id, $log_id, $field_id, ".$mdb2->quote($option_id).", ".$mdb2->quote($value).")"; - $affected = $mdb2->exec($sql); - return (!is_a($affected, 'PEAR_Error')); - } - - function update($log_id, $field_id, $option_id, $value) { - if (!$field_id) - return true; // Nothing to update. - - // Remove older custom field values, if any. - $res = $this->delete($log_id); - if (!$res) - return false; - - if (!$value && !$option_id) - return true; // Do not insert NULL values. - - return $this->insert($log_id, $field_id, $option_id, $value); - } - - function delete($log_id) { - global $user; - $mdb2 = getConnection(); - - $group_id = $user->getGroup(); - $org_id = $user->org_id; - - $sql = "update tt_custom_field_log set status = null". - " where log_id = $log_id and group_id = $group_id and org_id = $org_id"; - $affected = $mdb2->exec($sql); - return (!is_a($affected, 'PEAR_Error')); - } - - function get($log_id) { - global $user; - $mdb2 = getConnection(); - - $group_id = $user->getGroup(); - $org_id = $user->org_id; - - $sql = "select id, field_id, option_id, value from tt_custom_field_log". - " where log_id = $log_id and group_id = $group_id and org_id = $org_id and status = 1"; - $res = $mdb2->query($sql); - if (!is_a($res, 'PEAR_Error')) { - $fields = array(); - while ($val = $res->fetchRow()) { - $fields[] = $val; - } - return $fields; + + function delete($log_id) { + global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $sql = "update tt_custom_field_log set status = null" . + " where log_id = $log_id and group_id = $group_id and org_id = $org_id"; + $affected = $mdb2->exec($sql); + return (!is_a($affected, 'PEAR_Error')); } - return false; - } - - // insertOption adds a new option to a custom field. - static function insertOption($field_id, $option_name) { - global $user; - $mdb2 = getConnection(); - - $group_id = $user->getGroup(); - $org_id = $user->org_id; - - // Check if the option exists. - $id = 0; - $sql = "select id from tt_custom_field_options". - " where field_id = $field_id and group_id = $group_id and org_id = $org_id and value = ".$mdb2->quote($option_name); - $res = $mdb2->query($sql); - if (is_a($res, 'PEAR_Error')) - return false; - if ($val = $res->fetchRow()) $id = $val['id']; - - // Insert option. - if (!$id) { - $sql = "insert into tt_custom_field_options (group_id, org_id, field_id, value)". - " values($group_id, $org_id, $field_id, ".$mdb2->quote($option_name).")"; - $affected = $mdb2->exec($sql); - if (is_a($affected, 'PEAR_Error')) + + function get($log_id) { + global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $sql = "select id, field_id, option_id, value from tt_custom_field_log" . + " where log_id = $log_id and group_id = $group_id and org_id = $org_id and status = 1"; + $res = $mdb2->query($sql); + if (!is_a($res, 'PEAR_Error')) { + $fields = array(); + while ($val = $res->fetchRow()) { + $fields[] = $val; + } + return $fields; + } return false; } - return true; - } - - // updateOption updates option name. - static function updateOption($id, $option_name) { - global $user; - $mdb2 = getConnection(); - - $group_id = $user->getGroup(); - $org_id = $user->org_id; - - $sql = "update tt_custom_field_options set value = ".$mdb2->quote($option_name). - " where id = $id and group_id = $group_id and org_id = $org_id"; - $affected = $mdb2->exec($sql); - return (!is_a($affected, 'PEAR_Error')); - } - - // delete Option deletes an option and all custom field log entries that used it. - static function deleteOption($id) { - global $user; - $mdb2 = getConnection(); - - $group_id = $user->getGroup(); - $org_id = $user->org_id; - - $field_id = CustomFields::getFieldIdForOption($id); - if (!$field_id) return false; - - // Delete log entries with this option. TODO: why? Research impact. - $sql = "update tt_custom_field_log set status = null". - " where field_id = $field_id and group_id = $group_id and org_id = $org_id and value = ".$mdb2->quote($id); - $affected = $mdb2->exec($sql); - if (is_a($affected, 'PEAR_Error')) - return false; - - // Delete the option. - $sql = "update tt_custom_field_options set status = null". - " where id = $id and group_id = $group_id and org_id = $org_id"; - $affected = $mdb2->exec($sql); - return (!is_a($affected, 'PEAR_Error')); - } - - // getOptions returns an array of options for a custom field. - static function getOptions($field_id) { - global $user; - $mdb2 = getConnection(); - - $group_id = $user->getGroup(); - $org_id = $user->org_id; - - // Get options. - $sql = "select id, value from tt_custom_field_options". - " where field_id = $field_id and group_id = $group_id and org_id = $org_id and status = 1 order by value"; - $res = $mdb2->query($sql); - if (!is_a($res, 'PEAR_Error')) { - $options = array(); - while ($val = $res->fetchRow()) { - $options[$val['id']] = $val['value']; - } - return $options; + + // insertOption adds a new option to a custom field. + static function insertOption($field_id, $option_name) { + global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + // Check if the option exists. + $id = 0; + $sql = "select id from tt_custom_field_options" . + " where field_id = $field_id and group_id = $group_id and org_id = $org_id and value = " . $mdb2->quote($option_name); + $res = $mdb2->query($sql); + if (is_a($res, 'PEAR_Error')) + return false; + if ($val = $res->fetchRow()) + $id = $val['id']; + + // Insert option. + if (!$id) { + $sql = "insert into tt_custom_field_options (group_id, org_id, field_id, value)" . + " values($group_id, $org_id, $field_id, " . $mdb2->quote($option_name) . ")"; + $affected = $mdb2->exec($sql); + if (is_a($affected, 'PEAR_Error')) + return false; + } + return true; + } + + // updateOption updates option name. + static function updateOption($id, $option_name) { + global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $sql = "update tt_custom_field_options set value = " . $mdb2->quote($option_name) . + " where id = $id and group_id = $group_id and org_id = $org_id"; + $affected = $mdb2->exec($sql); + return (!is_a($affected, 'PEAR_Error')); + } + + // delete Option deletes an option and all custom field log entries that used it. + static function deleteOption($id) { + global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $field_id = CustomFields::getFieldIdForOption($id); + if (!$field_id) + return false; + + // Delete log entries with this option. TODO: why? Research impact. + $sql = "update tt_custom_field_log set status = null" . + " where field_id = $field_id and group_id = $group_id and org_id = $org_id and value = " . $mdb2->quote($id); + $affected = $mdb2->exec($sql); + if (is_a($affected, 'PEAR_Error')) + return false; + + // Delete the option. + $sql = "update tt_custom_field_options set status = null" . + " where id = $id and group_id = $group_id and org_id = $org_id"; + $affected = $mdb2->exec($sql); + return (!is_a($affected, 'PEAR_Error')); } - return false; - } - - // getOptionName returns an option name for a custom field. - static function getOptionName($id) { - global $user; - $mdb2 = getConnection(); - - $group_id = $user->getGroup(); - $org_id = $user->org_id; - - $sql = "select value from tt_custom_field_options". - " where id = $id and group_id = $group_id and org_id = $org_id and status = 1"; - $res = $mdb2->query($sql); - if (!is_a($res, 'PEAR_Error')) { - $val = $res->fetchRow(); - $name = $val['value']; - return $name; + + // getOptions returns an array of options for a custom field. + static function getOptions($field_id) { + global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + // Get options. + $sql = "select id, value from tt_custom_field_options" . + " where field_id = $field_id and group_id = $group_id and org_id = $org_id and status = 1 order by value"; + $res = $mdb2->query($sql); + if (!is_a($res, 'PEAR_Error')) { + $options = array(); + while ($val = $res->fetchRow()) { + $options[$val['id']] = $val['value']; + } + return $options; + } + return false; } - return false; - } - - // getFields returns an array of custom fields for group. - static function getFields() { - global $user; - $mdb2 = getConnection(); - - $group_id = $user->getGroup(); - $org_id = $user->org_id; - - $fields = array(); - $sql = "select id, entity_type, type, label from tt_custom_fields". - " where group_id = $group_id and org_id = $org_id and status = 1 and type > 0"; - $res = $mdb2->query($sql); - if (!is_a($res, 'PEAR_Error')) { - while ($val = $res->fetchRow()) { - $fields[] = $val; - } - return $fields; + + // getOptionName returns an option name for a custom field. + static function getOptionName($id) { + global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $sql = "select value from tt_custom_field_options" . + " where id = $id and group_id = $group_id and org_id = $org_id and status = 1"; + $res = $mdb2->query($sql); + if (!is_a($res, 'PEAR_Error')) { + $val = $res->fetchRow(); + $name = $val['value']; + return $name; + } + return false; } - return false; - } - - // getField returns a custom field. - static function getField($id) { - global $user; - $mdb2 = getConnection(); - - $group_id = $user->getGroup(); - $org_id = $user->org_id; - - $sql = "select label, entity_type, type, required from tt_custom_fields". - " where id = $id and group_id = $group_id and org_id = $org_id"; - $res = $mdb2->query($sql); - if (!is_a($res, 'PEAR_Error')) { - $val = $res->fetchRow(); - if (!$val) + + // getFields returns an array of custom fields for group. + static function getFields() { + global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $fields = array(); + $sql = "select id, entity_type, type, label from tt_custom_fields" . + " where group_id = $group_id and org_id = $org_id and status = 1 and type > 0"; + $res = $mdb2->query($sql); + if (!is_a($res, 'PEAR_Error')) { + while ($val = $res->fetchRow()) { + $fields[] = $val; + } + return $fields; + } return false; - return $val; } - return false; - } - - // getFieldIdForOption returns field id from an associated option id. - static function getFieldIdForOption($option_id) { - global $user; - $mdb2 = getConnection(); - - $group_id = $user->getGroup(); - $org_id = $user->org_id; - - $sql = "select field_id from tt_custom_field_options". - " where id = $option_id and group_id = $group_id and org_id = $org_id"; - $res = $mdb2->query($sql); - if (!is_a($res, 'PEAR_Error')) { - $val = $res->fetchRow(); - $field_id = $val['field_id']; - return $field_id; + + // getField returns a custom field. + static function getField($id) { + global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $sql = "select label, entity_type, type, required from tt_custom_fields" . + " where id = $id and group_id = $group_id and org_id = $org_id"; + $res = $mdb2->query($sql); + if (!is_a($res, 'PEAR_Error')) { + $val = $res->fetchRow(); + if (!$val) + return false; + return $val; + } + return false; } - return false; - } - - // The insertField inserts a custom field for group. - static function insertField($field_name, $entity_type, $field_type, $required) { - global $user; - $mdb2 = getConnection(); - - $group_id = $user->getGroup(); - $org_id = $user->org_id; - - $sql = "insert into tt_custom_fields (group_id, org_id, entity_type, type, label, required, status)". - " values($group_id, $org_id, $entity_type, $field_type, ".$mdb2->quote($field_name).", $required, 1)"; - $affected = $mdb2->exec($sql); - return (!is_a($affected, 'PEAR_Error')); - } - - // The updateField updates custom field for group. - static function updateField($id, $name, $type, $required) { - global $user; - $mdb2 = getConnection(); - - $group_id = $user->getGroup(); - $org_id = $user->org_id; - - $sql = "update tt_custom_fields set label = ".$mdb2->quote($name).", type = $type, required = $required". - " where id = $id and group_id = $group_id and org_id = $org_id"; - $affected = $mdb2->exec($sql); - return (!is_a($affected, 'PEAR_Error')); - } - - // The deleteField deletes a custom field, its options and log entries for group. - static function deleteField($field_id) { - global $user; - $mdb2 = getConnection(); - - $group_id = $user->getGroup(); - $org_id = $user->org_id; - - // Mark log entries as deleted. TODO: why are we doing this? Research impact. - $sql = "update tt_custom_field_log set status = null". - " where field_id = $field_id and group_id = $group_id and org_id = $org_id"; - $affected = $mdb2->exec($sql); - if (is_a($affected, 'PEAR_Error')) - return false; - - // Mark field options as deleted. - $sql = "update tt_custom_field_options set status = null". - " where field_id = $field_id and group_id = $group_id and org_id = $org_id"; - $affected = $mdb2->exec($sql); - if (is_a($affected, 'PEAR_Error')) - return false; - - // Mark custom field as deleted. - $sql = "update tt_custom_fields set status = null". - " where id = $field_id and group_id = $group_id and org_id = $org_id"; - $affected = $mdb2->exec($sql); - return (!is_a($affected, 'PEAR_Error')); - } - - // insertEntityFields - inserts entity custom fields into tt_entity_custom_fields. - function insertEntityFields($entity_type, $entity_id, $entityFields) { - foreach ($entityFields as $entityField) { - if (!$this->insertEntityField($entity_type, $entity_id, $entityField)) + + // getFieldIdForOption returns field id from an associated option id. + static function getFieldIdForOption($option_id) { + global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $sql = "select field_id from tt_custom_field_options" . + " where id = $option_id and group_id = $group_id and org_id = $org_id"; + $res = $mdb2->query($sql); + if (!is_a($res, 'PEAR_Error')) { + $val = $res->fetchRow(); + $field_id = $val['field_id']; + return $field_id; + } return false; } - return true; - } - - // insertEntityField - inserts a single entity custom field into tt_entity_custom_fields. - function insertEntityField($entity_type, $entity_id, $entityField) { - global $user; - $mdb2 = getConnection(); - - $group_id = $user->getGroup(); - $org_id = $user->org_id; - - $created = 'now(), '.$mdb2->quote($_SERVER['REMOTE_ADDR']).', '.$user->id; - - $field_id = (int) $entityField['field_id']; - - $option_id = $entityField['type'] == CustomFields::TYPE_DROPDOWN ? (int) $entityField['value'] : null; - $value = $entityField['type'] == CustomFields::TYPE_TEXT ? $entityField['value'] : null; - - // TODO: add a jon to protect from bogus option_ids in post. - $sql = "insert into tt_entity_custom_fields". - " (group_id, org_id, entity_type, entity_id, field_id, option_id, value, created, created_ip, created_by)". - " values($group_id, $org_id, $entity_type, $entity_id, $field_id, ".$mdb2->quote($option_id).", ".$mdb2->quote($value).", $created)"; - $affected = $mdb2->exec($sql); - return (!is_a($affected, 'PEAR_Error')); - } - - // updateEntityFields - updates entity custom fields in tt_entity_custom_fields table - // by doing a delete followed up by an insert. - function updateEntityFields($entity_type, $entity_id, $entityFields) { - $result = $this->deleteEntityFields($entity_type, $entity_id); - if (!$result) return false; - - return $this->insertEntityFields($entity_type, $entity_id, $entityFields); - } - - // deleteEntityFields - deletes entity custom fields (permanently). - // Note: deleting, rather than marking fields deleted is on purpose - // because we want to keep the table small after multiple entity edits. - function deleteEntityFields($entity_type, $entity_id) { - global $user; - $mdb2 = getConnection(); - - $group_id = $user->getGroup(); - $org_id = $user->org_id; - - $modified_part = ', modified = now(), modified_ip = '.$mdb2->quote($_SERVER['REMOTE_ADDR']).', modified_by = '.$user->id; - - $sql = "delete from tt_entity_custom_fields". - " where entity_type = $entity_type and entity_id = $entity_id". - " and group_id = $group_id and org_id = $org_id"; - $affected = $mdb2->exec($sql); - return (!is_a($affected, 'PEAR_Error')); - } - - // getEntityFieldValue - obtains entity custom field value from the database. - function getEntityFieldValue($entity_type, $entity_id, $field_id, $type) { - global $user; - $mdb2 = getConnection(); - - $group_id = $user->getGroup(); - $org_id = $user->org_id; - - $sql = "select option_id, value from tt_entity_custom_fields". - " where entity_type = $entity_type and entity_id = $entity_id". - " and field_id = $field_id". - " and group_id = $group_id and org_id = $org_id and status = 1"; - $res = $mdb2->query($sql); - if (!is_a($res, 'PEAR_Error')) { - if ($val = $res->fetchRow()) { - if (CustomFields::TYPE_DROPDOWN == $type) - return $val['option_id']; - if (CustomFields::TYPE_TEXT == $type) - return $val['value']; - } + + // The insertField inserts a custom field for group. + static function insertField($field_name, $entity_type, $field_type, $required) { + global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + // TODO: refactor this. + if (!$entity_type) $entity_type = CustomFields::ENTITY_TIME; + + $sql = "insert into tt_custom_fields (group_id, org_id, entity_type, type, label, required, status)" . + " values($group_id, $org_id, $entity_type, $field_type, " . $mdb2->quote($field_name) . ", $required, 1)"; + $affected = $mdb2->exec($sql); + return (!is_a($affected, 'PEAR_Error')); + } + + // The updateField updates custom field for group. + static function updateField($id, $name, $type, $required) { + global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $sql = "update tt_custom_fields set label = " . $mdb2->quote($name) . ", type = $type, required = $required" . + " where id = $id and group_id = $group_id and org_id = $org_id"; + $affected = $mdb2->exec($sql); + return (!is_a($affected, 'PEAR_Error')); + } + + // The deleteField deletes a custom field, its options and log entries for group. + static function deleteField($field_id) { + global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + // Mark log entries as deleted. TODO: why are we doing this? Research impact. + $sql = "update tt_custom_field_log set status = null" . + " where field_id = $field_id and group_id = $group_id and org_id = $org_id"; + $affected = $mdb2->exec($sql); + if (is_a($affected, 'PEAR_Error')) + return false; + + // Mark field options as deleted. + $sql = "update tt_custom_field_options set status = null" . + " where field_id = $field_id and group_id = $group_id and org_id = $org_id"; + $affected = $mdb2->exec($sql); + if (is_a($affected, 'PEAR_Error')) + return false; + + // Mark custom field as deleted. + $sql = "update tt_custom_fields set status = null" . + " where id = $field_id and group_id = $group_id and org_id = $org_id"; + $affected = $mdb2->exec($sql); + return (!is_a($affected, 'PEAR_Error')); + } + + // insertTimeFields - inserts time custom fields into tt_custom_field_log. + function insertTimeFields($log_id, $timeFields) { + foreach ($timeFields as $timeField) { + if (!$this->insertTimeField($log_id, $timeField)) + return false; + } + return true; + } + + // insertTimeField - inserts a single time custom field into tt_custom_field_log. + function insertTimeField($log_id, $timeField) { + global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $field_id = $timeField['field_id']; + $type = $timeField['type']; + $option_id = $type == CustomFields::TYPE_DROPDOWN ? (int) $timeField['value'] : null; + $value = $type == CustomFields::TYPE_TEXT ? $timeField['value'] : null; + + // Do not insert empty fields. + if (($type == CustomFields::TYPE_DROPDOWN && !$option_id) || ($type == CustomFields::TYPE_TEXT && !$value)) + return true; + + // TODO: add a join to protect from bogus option_ids in post. + + $sql = "insert into tt_custom_field_log (group_id, org_id, log_id, field_id, option_id, value)" . + " values($group_id, $org_id, $log_id, $field_id, " . $mdb2->quote($option_id) . ", " . $mdb2->quote($value) . ")"; + $affected = $mdb2->exec($sql); + return (!is_a($affected, 'PEAR_Error')); + } + + // insertEntityFields - inserts entity custom fields into tt_entity_custom_fields. + function insertEntityFields($entity_type, $entity_id, $entityFields) { + foreach ($entityFields as $entityField) { + if (!$this->insertEntityField($entity_type, $entity_id, $entityField)) + return false; + } + return true; + } + + // insertEntityField - inserts a single entity custom field into tt_entity_custom_fields. + function insertEntityField($entity_type, $entity_id, $entityField) { + global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $created = 'now(), ' . $mdb2->quote($_SERVER['REMOTE_ADDR']) . ', ' . $user->id; + + $field_id = (int) $entityField['field_id']; + $type = $entityField['type']; + $option_id = $type == CustomFields::TYPE_DROPDOWN ? (int) $entityField['value'] : null; + $value = $type == CustomFields::TYPE_TEXT ? $entityField['value'] : null; + + // Do not insert empty fields. + if (($type == CustomFields::TYPE_DROPDOWN && !$option_id) || ($type == CustomFields::TYPE_TEXT && !$value)) + return true; + + // TODO: add a join to protect from bogus option_ids in post. + $sql = "insert into tt_entity_custom_fields" . + " (group_id, org_id, entity_type, entity_id, field_id, option_id, value, created, created_ip, created_by)" . + " values($group_id, $org_id, $entity_type, $entity_id, $field_id, " . $mdb2->quote($option_id) . ", " . $mdb2->quote($value) . ", $created)"; + $affected = $mdb2->exec($sql); + return (!is_a($affected, 'PEAR_Error')); + } + + // updateEntityFields - updates entity custom fields in tt_entity_custom_fields table + // by doing a delete followed up by an insert. + function updateEntityFields($entity_type, $entity_id, $entityFields) { + $result = $this->deleteEntityFields($entity_type, $entity_id); + if (!$result) + return false; + + return $this->insertEntityFields($entity_type, $entity_id, $entityFields); + } + + // deleteEntityFields - deletes entity custom fields (permanently). + // Note: deleting, rather than marking fields deleted is on purpose + // because we want to keep the table small after multiple entity edits. + function deleteEntityFields($entity_type, $entity_id) { + global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $sql = "delete from tt_entity_custom_fields" . + " where entity_type = $entity_type and entity_id = $entity_id" . + " and group_id = $group_id and org_id = $org_id"; + $affected = $mdb2->exec($sql); + return (!is_a($affected, 'PEAR_Error')); + } + + // deleteTimeFields - deletes time custom fields (permanently). + // Note: deleting, rather than marking fields deleted is on purpose + // because we want to keep the table small after multiple edits. + function deleteTimeFields($log_id) { + global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $sql = "delete from tt_custom_field_log" . + " where log_id = $log_id" . + " and group_id = $group_id and org_id = $org_id"; + $affected = $mdb2->exec($sql); + return (!is_a($affected, 'PEAR_Error')); + } + + // getEntityFieldValue - obtains entity custom field value from the database. + function getEntityFieldValue($entity_type, $entity_id, $field_id, $type) { + global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $sql = "select option_id, value from tt_entity_custom_fields" . + " where entity_type = $entity_type and entity_id = $entity_id" . + " and field_id = $field_id" . + " and group_id = $group_id and org_id = $org_id and status = 1"; + $res = $mdb2->query($sql); + if (!is_a($res, 'PEAR_Error')) { + if ($val = $res->fetchRow()) { + if (CustomFields::TYPE_DROPDOWN == $type) + return $val['option_id']; + if (CustomFields::TYPE_TEXT == $type) + return $val['value']; + } + } + return null; + } + + // getTimeFieldValue - obtains time custom field value from the database. + function getTimeFieldValue($log_id, $field_id, $type) { + global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $sql = "select option_id, value from tt_custom_field_log" . + " where log_id = $log_id" . + " and field_id = $field_id" . + " and group_id = $group_id and org_id = $org_id and status = 1"; + $res = $mdb2->query($sql); + if (!is_a($res, 'PEAR_Error')) { + if ($val = $res->fetchRow()) { + if (CustomFields::TYPE_DROPDOWN == $type) + return $val['option_id']; + if (CustomFields::TYPE_TEXT == $type) + return $val['value']; + } + } + return null; } - return null; - } + + // updateTimeFields - updates time custom fields in tt_custom_field_log table + // by doing a delete followed up by an insert. + function updateTimeFields($log_id, $timeFields) { + $result = $this->deleteTimeFields($log_id); + if (!$result) + return false; + + return $this->insertTimeFields($log_id, $timeFields); + } + } diff --git a/reports.php b/reports.php index d3a70dc64..0f0cb11ab 100644 --- a/reports.php +++ b/reports.php @@ -55,10 +55,6 @@ require_once('plugins/CustomFields.class.php'); $custom_fields = new CustomFields(); $smarty->assign('custom_fields', $custom_fields); - $showCustomFieldCheckbox = $custom_fields->fields[0]; - $showCustomFieldDropdown = $custom_fields->fields[0] && $custom_fields->fields[0]['type'] == CustomFields::TYPE_DROPDOWN; - if ($showCustomFieldDropdown) - $showCustomFieldDropdown &= CustomFields::getOptions($custom_fields->fields[0]['id']); } $form = new Form('reportForm'); @@ -97,15 +93,6 @@ 'empty'=>array(''=>$i18n->get('dropdown.all')))); } -// If we have a TYPE_DROPDOWN custom field - add a control to select an option. -if ($showCustomFieldDropdown) { - $form->addInput(array('type'=>'combobox','name'=>'option', - 'style'=>'width: 250px;', - 'value'=>$cl_cf_1, - 'data'=>CustomFields::getOptions($custom_fields->fields[0]['id']), - 'empty'=>array(''=>$i18n->get('dropdown.all')))); -} - // Add project dropdown. $showProject = MODE_PROJECTS == $trackingMode || MODE_PROJECTS_AND_TASKS == $trackingMode; if ($showProject) { @@ -290,8 +277,6 @@ $form->addInput(array('type'=>'checkbox','name'=>'chproject')); if ($showTask) $form->addInput(array('type'=>'checkbox','name'=>'chtask')); -if ($showCustomFieldCheckbox) - $form->addInput(array('type'=>'checkbox','name'=>'chcf_1')); if ($showInvoiceCheckbox) $form->addInput(array('type'=>'checkbox','name'=>'chinvoice')); if ($showPaidStatus) @@ -371,9 +356,6 @@ $group_by_options['project'] = $i18n->get('form.reports.group_by_project'); if (MODE_PROJECTS_AND_TASKS == $trackingMode) $group_by_options['task'] = $i18n->get('form.reports.group_by_task'); -if ($custom_fields && $custom_fields->fields[0] && $custom_fields->fields[0]['type'] == CustomFields::TYPE_DROPDOWN) { - $group_by_options['cf_1'] = $custom_fields->fields[0]['label']; -} $group_by_options_size = sizeof($group_by_options); $form->addInput(array('type'=>'combobox','onchange'=>'handleCheckboxes();','name'=>'group_by1','data'=>$group_by_options)); if ($group_by_options_size > 2) $form->addInput(array('type'=>'combobox','onchange'=>'handleCheckboxes();','name'=>'group_by2','data'=>$group_by_options)); @@ -413,7 +395,6 @@ $form->setValueByElement('chapproved', '0'); $form->setValueByElement('chpaid', '0'); - $form->setValueByElement('chcf_1', '0'); $form->setValueByElement('chunits', '0'); $form->setValueByElement('chinvoice', '0'); $form->setValueByElement('chfiles', '1'); @@ -509,8 +490,6 @@ $smarty->assign('client_list', $client_list); $smarty->assign('show_client', $showClient); -$smarty->assign('show_cf_1_dropdown', $showCustomFieldDropdown); -$smarty->assign('show_cf_1_checkbox', $showCustomFieldCheckbox); $smarty->assign('show_project', $showProject); $smarty->assign('show_task', $showTask); $smarty->assign('show_billable', $showBillable); diff --git a/time.php b/time.php index f058a21a5..a06773e72 100644 --- a/time.php +++ b/time.php @@ -101,7 +101,6 @@ // Determine column span for note field. $colspan = 0; if ($showClient) $colspan++; - if ($user->isPluginEnabled('cf')) $colspan++; if ($showProject) $colspan++; if ($showTask) $colspan++; if ($showStart) $colspan++; @@ -156,6 +155,22 @@ $cl_task = $request->getParameter('task', ($request->isPost() ? null : @$_SESSION['task'])); $_SESSION['task'] = $cl_task; +$timeCustomFields = array(); +// If we have time custom fields - collect input. +if ($request->isPost()) { + if ($custom_fields && $custom_fields->timeFields) { + foreach ($custom_fields->timeFields as $timeField) { + $control_name = 'time_field_'.$timeField['id']; + $timeCustomFields[$timeField['id']] = array('field_id' => $timeField['id'], + 'control_name' => $control_name, + 'label' => $timeField['label'], + 'type' => $timeField['type'], + 'required' => $timeField['required'], + 'value' => trim($request->getParameter($control_name))); + } + } +} + // Elements of timeRecordForm. $form = new Form('timeRecordForm'); if ($user->can('track_time')) { @@ -271,17 +286,19 @@ $form->addInput(array('type'=>'hidden','name'=>'browser_today','value'=>'')); // User current date, which gets filled in on btn_submit click. $form->addInput(array('type'=>'submit','name'=>'btn_submit','onclick'=>'browser_today.value=get_date()','value'=>$i18n->get('button.submit'))); -// If we have custom fields - add controls for them. -if ($custom_fields && $custom_fields->fields[0]) { - // Only one custom field is supported at this time. - if ($custom_fields->fields[0]['type'] == CustomFields::TYPE_TEXT) { - $form->addInput(array('type'=>'text','name'=>'cf_1','value'=>$cl_cf_1)); - } elseif ($custom_fields->fields[0]['type'] == CustomFields::TYPE_DROPDOWN) { - $form->addInput(array('type'=>'combobox','name'=>'cf_1', +// If we have time custom fields - add controls for them. +if ($custom_fields && $custom_fields->timeFields) { + foreach ($custom_fields->timeFields as $timeField) { + $field_name = 'time_field_'.$timeField['id']; + if ($timeField['type'] == CustomFields::TYPE_TEXT) { + $form->addInput(array('type'=>'text','name'=>$field_name,'style'=>'width: 250px;','value'=>$timeCustomFields[$timeField['id']]['value'])); + } elseif ($timeField['type'] == CustomFields::TYPE_DROPDOWN) { + $form->addInput(array('type'=>'combobox','name'=>$field_name, 'style'=>'width: 250px;', - 'value'=>$cl_cf_1, - 'data'=>CustomFields::getOptions($custom_fields->fields[0]['id']), + 'data'=>CustomFields::getOptions($timeField['id']), + 'value'=>$timeCustomFields[$timeField['id']]['value'], 'empty'=>array(''=>$i18n->get('dropdown.select')))); + } } } @@ -308,8 +325,12 @@ // Validate user input. if ($showClient && $user->isOptionEnabled('client_required') && !$cl_client) $err->add($i18n->get('error.client')); - if ($custom_fields) { - if (!ttValidString($cl_cf_1, !$custom_fields->fields[0]['required'])) $err->add($i18n->get('error.field'), $custom_fields->fields[0]['label']); + // Validate input in time custom fields. + if ($custom_fields && $custom_fields->timeFields) { + foreach ($timeCustomFields as $timeField) { + // Validation is the same for text and dropdown fields. + if (!ttValidString($timeField['value'], !$timeField['required'])) $err->add($i18n->get('error.field'), htmlspecialchars($timeField['label'])); + } } if (MODE_PROJECTS == $user->getTrackingMode() || MODE_PROJECTS_AND_TASKS == $user->getTrackingMode()) { if (!$cl_project) $err->add($i18n->get('error.project')); @@ -385,13 +406,10 @@ 'note' => $cl_note, 'billable' => $cl_billable)); - // Insert a custom field if we have it. + // Insert time custom fields if we have them. $result = true; - if ($id && $custom_fields && $cl_cf_1) { - if ($custom_fields->fields[0]['type'] == CustomFields::TYPE_TEXT) - $result = $custom_fields->insert($id, $custom_fields->fields[0]['id'], null, $cl_cf_1); - elseif ($custom_fields->fields[0]['type'] == CustomFields::TYPE_DROPDOWN) - $result = $custom_fields->insert($id, $custom_fields->fields[0]['id'], $cl_cf_1, null); + if ($id && $custom_fields && $custom_fields->timeFields) { + $result = $custom_fields->insertTimeFields($id, $timeCustomFields); } // Put a new file in storage if we have it. @@ -450,7 +468,7 @@ $smarty->assign('time_records', $timeRecords); $smarty->assign('show_navigation', $user->isPluginEnabled('wv') && !$user->isOptionEnabled('week_menu')); $smarty->assign('show_client', $showClient); -$smarty->assign('show_cf_1', $user->isPluginEnabled('cf')); +// $smarty->assign('show_cf_1', $user->isPluginEnabled('cf')); $smarty->assign('show_project', $showProject); $smarty->assign('show_task', $showTask); $smarty->assign('show_start', $showStart); diff --git a/time_edit.php b/time_edit.php index aceff0243..f6ee7de1e 100644 --- a/time_edit.php +++ b/time_edit.php @@ -68,7 +68,18 @@ $cl_duration = trim($request->getParameter('duration')); $cl_date = $request->getParameter('date'); $cl_note = trim($request->getParameter('note')); - $cl_cf_1 = trim($request->getParameter('cf_1')); + // If we have user custom fields - collect input. + if ($custom_fields && $custom_fields->timeFields) { + foreach ($custom_fields->timeFields as $timeField) { + $control_name = 'time_field_'.$timeField['id']; + $timeCustomFields[$timeField['id']] = array('field_id' => $timeField['id'], + 'control_name' => $control_name, + 'label' => $timeField['label'], + 'type' => $timeField['type'], + 'required' => $timeField['required'], + 'value' => trim($request->getParameter($control_name))); + } + } $cl_client = $request->getParameter('client'); $cl_project = $request->getParameter('project'); $cl_task = $request->getParameter('task'); @@ -87,14 +98,17 @@ $cl_date = $item_date->toString($user->date_format); $cl_note = $time_rec['comment']; - // If we have custom fields - obtain values for them. - if ($custom_fields) { - // Get custom field value for time record. - $fields = $custom_fields->get($time_rec['id']); - if ($custom_fields->fields[0]['type'] == CustomFields::TYPE_TEXT) - $cl_cf_1 = $fields[0]['value']; - elseif ($custom_fields->fields[0]['type'] == CustomFields::TYPE_DROPDOWN) - $cl_cf_1 = $fields[0]['option_id']; + // If we have time custom fields - collect values from database. + if ($custom_fields && $custom_fields->timeFields) { + foreach ($custom_fields->timeFields as $timeField) { + $control_name = 'time_field_'.$timeField['id']; + $timeCustomFields[$timeField['id']] = array('field_id' => $timeField['id'], + 'control_name' => $control_name, + 'label' => $timeField['label'], + 'type' => $timeField['type'], + 'required' => $timeField['required'], + 'value' => $custom_fields->getTimeFieldValue($cl_id, $timeField['id'], $timeField['type'])); + } } $cl_billable = $time_rec['billable']; @@ -192,18 +206,19 @@ $form->addInput(array('type'=>'datefield','name'=>'date','maxlength'=>'20','value'=>$cl_date)); $form->addInput(array('type'=>'textarea','name'=>'note','style'=>'width: 250px; height: 200px;','value'=>$cl_note)); -// If we have custom fields - add controls for them. -if ($custom_fields && $custom_fields->fields[0]) { - // Only one custom field is supported at this time. - if ($custom_fields->fields[0]['type'] == CustomFields::TYPE_TEXT) { - $form->addInput(array('type'=>'text','name'=>'cf_1','value'=>$cl_cf_1)); - } elseif ($custom_fields->fields[0]['type'] == CustomFields::TYPE_DROPDOWN) { - $form->addInput(array('type'=>'combobox', - 'name'=>'cf_1', +// If we have time custom fields - add controls for them. +if ($custom_fields && $custom_fields->timeFields) { + foreach ($custom_fields->timeFields as $timeField) { + $field_name = 'time_field_'.$timeField['id']; + if ($timeField['type'] == CustomFields::TYPE_TEXT) { + $form->addInput(array('type'=>'text','name'=>$field_name,'value'=>$timeCustomFields[$timeField['id']]['value'])); + } elseif ($timeField['type'] == CustomFields::TYPE_DROPDOWN) { + $form->addInput(array('type'=>'combobox','name'=>$field_name, 'style'=>'width: 250px;', - 'value'=>$cl_cf_1, - 'data'=>CustomFields::getOptions($custom_fields->fields[0]['id']), - 'empty' => array('' => $i18n->get('dropdown.select')))); + 'data'=>CustomFields::getOptions($timeField['id']), + 'value'=>$timeCustomFields[$timeField['id']]['value'], + 'empty'=>array(''=>$i18n->get('dropdown.select')))); + } } } @@ -241,8 +256,12 @@ // Validate user input. if ($user->isPluginEnabled('cl') && $user->isOptionEnabled('client_required') && !$cl_client) $err->add($i18n->get('error.client')); - if ($custom_fields) { - if (!ttValidString($cl_cf_1, !$custom_fields->fields[0]['required'])) $err->add($i18n->get('error.field'), $custom_fields->fields[0]['label']); + // Validate input in time custom fields. + if ($custom_fields && $custom_fields->timeFields) { + foreach ($timeCustomFields as $timeField) { + // Validation is the same for text and dropdown fields. + if (!ttValidString($timeField['value'], !$timeField['required'])) $err->add($i18n->get('error.field'), htmlspecialchars($timeField['label'])); + } } if (MODE_PROJECTS == $user->tracking_mode || MODE_PROJECTS_AND_TASKS == $user->tracking_mode) { if (!$cl_project) $err->add($i18n->get('error.project')); @@ -342,12 +361,9 @@ 'billable'=>$cl_billable, 'paid'=>$cl_paid)); - // If we have custom fields - update values. - if ($res && $custom_fields) { - if ($custom_fields->fields[0]['type'] == CustomFields::TYPE_TEXT) - $res = $custom_fields->update($cl_id, $custom_fields->fields[0]['id'], null, $cl_cf_1); - elseif ($custom_fields->fields[0]['type'] == CustomFields::TYPE_DROPDOWN) - $res = $custom_fields->update($cl_id, $custom_fields->fields[0]['id'], $cl_cf_1, null); + // Update time custom fields if we have them. + if ($res && $custom_fields && $custom_fields->timeFields) { + $res = $custom_fields->updateTimeFields($cl_id, $timeCustomFields); } if ($res) { @@ -404,13 +420,10 @@ 'billable'=>$cl_billable, 'paid'=>$cl_paid)); - // Insert a custom field if we have it. + // Insert time custom fields if we have them. $res = true; - if ($id && $custom_fields && $cl_cf_1) { - if ($custom_fields->fields[0]['type'] == CustomFields::TYPE_TEXT) - $res = $custom_fields->insert($id, $custom_fields->fields[0]['id'], null, $cl_cf_1); - elseif ($custom_fields->fields[0]['type'] == CustomFields::TYPE_DROPDOWN) - $res = $custom_fields->insert($id, $custom_fields->fields[0]['id'], $cl_cf_1, null); + if ($id && $custom_fields && $custom_fields->timeFields) { + $res = $custom_fields->insertTimeFields($id, $timeCustomFields); } if ($id && $res) { header('Location: time.php?date='.$new_date->toString(DB_DATEFORMAT)); diff --git a/user_edit.php b/user_edit.php index 843383f42..195e87a34 100644 --- a/user_edit.php +++ b/user_edit.php @@ -109,7 +109,7 @@ $cl_login = $user_details['login']; $cl_email = $user_details['email']; $cl_quota_percent = str_replace('.', $user->getDecimalMark(), $user_details['quota_percent']); - // If we have user custom fields - collect vallues from database. + // If we have user custom fields - collect values from database. if ($custom_fields && $custom_fields->userFields) { foreach ($custom_fields->userFields as $userField) { $control_name = 'user_field_'.$userField['id']; @@ -248,7 +248,7 @@ function render(&$table, $value, $row, $column, $selected = false) { } $result = ttUserHelper::update($user_id, $fields); - // Update user custom fields if we have them. + // Update user custom fields if we have them. if ($result && $custom_fields && $custom_fields->userFields) { $result = $custom_fields->updateEntityFields(CustomFields::ENTITY_USER, $user_id, $userCustomFields); } diff --git a/week.php b/week.php index 9af356441..0fe376cc3 100644 --- a/week.php +++ b/week.php @@ -107,9 +107,22 @@ } // Initialize variables. -// Custom field. -$cl_cf_1 = trim($request->getParameter('cf_1', ($request->isPost() ? null : @$_SESSION['cf_1']))); -$_SESSION['cf_1'] = $cl_cf_1; +$timeCustomFields = array(); +// If we have time custom fields - collect input. +if ($request->isPost()) { + if ($custom_fields && $custom_fields->timeFields) { + foreach ($custom_fields->timeFields as $timeField) { + $control_name = 'time_field_'.$timeField['id']; + $timeCustomFields[$timeField['id']] = array('field_id' => $timeField['id'], + 'control_name' => $control_name, + 'label' => $timeField['label'], + 'type' => $timeField['type'], + 'required' => $timeField['required'], + 'value' => trim($request->getParameter($control_name))); + } + } +} + $cl_billable = 1; if ($user->isPluginEnabled('iv')) { if ($request->isPost()) { @@ -329,17 +342,19 @@ function render(&$table, $value, $row, $column, $selected = false) { $form->addInput(array('type'=>'hidden','name'=>'browser_today','value'=>'get_date()')); // User current date, which gets filled in on btn_submit click. $form->addInput(array('type'=>'submit','name'=>'btn_submit','onclick'=>'browser_today.value=get_date()','value'=>$i18n->get('button.submit'))); -// If we have custom fields - add controls for them. -if ($custom_fields && $custom_fields->fields[0]) { - // Only one custom field is supported at this time. - if ($custom_fields->fields[0]['type'] == CustomFields::TYPE_TEXT) { - $form->addInput(array('type'=>'text','name'=>'cf_1','value'=>$cl_cf_1)); - } elseif ($custom_fields->fields[0]['type'] == CustomFields::TYPE_DROPDOWN) { - $form->addInput(array('type'=>'combobox','name'=>'cf_1', +// If we have time custom fields - add controls for them. +if ($custom_fields && $custom_fields->timeFields) { + foreach ($custom_fields->timeFields as $timeField) { + $field_name = 'time_field_'.$timeField['id']; + if ($timeField['type'] == CustomFields::TYPE_TEXT) { + $form->addInput(array('type'=>'text','name'=>$field_name,'style'=>'width: 250px;','value'=>$timeCustomFields[$timeField['id']]['value'])); + } elseif ($timeField['type'] == CustomFields::TYPE_DROPDOWN) { + $form->addInput(array('type'=>'combobox','name'=>$field_name, 'style'=>'width: 250px;', - 'value'=>$cl_cf_1, - 'data'=>CustomFields::getOptions($custom_fields->fields[0]['id']), + 'data'=>CustomFields::getOptions($timeField['id']), + 'value'=>$timeCustomFields[$timeField['id']]['value'], 'empty'=>array(''=>$i18n->get('dropdown.select')))); + } } } @@ -359,8 +374,12 @@ function render(&$table, $value, $row, $column, $selected = false) { if ($newEntryPosted) { if ($user->isPluginEnabled('cl') && $user->isOptionEnabled('client_required') && !$cl_client) $err->add($i18n->get('error.client')); - if ($custom_fields) { - if (!ttValidString($cl_cf_1, !$custom_fields->fields[0]['required'])) $err->add($i18n->get('error.field'), $custom_fields->fields[0]['label']); + // Validate input in time custom fields. + if ($custom_fields && $custom_fields->timeFields) { + foreach ($timeCustomFields as $timeField) { + // Validation is the same for text and dropdown fields. + if (!ttValidString($timeField['value'], !$timeField['required'])) $err->add($i18n->get('error.field'), htmlspecialchars($timeField['label'])); + } } if (MODE_PROJECTS == $user->tracking_mode || MODE_PROJECTS_AND_TASKS == $user->tracking_mode) { if (!$cl_project) $err->add($i18n->get('error.project')); @@ -422,7 +441,12 @@ function render(&$table, $value, $row, $column, $selected = false) { $record['billable'] = $cl_billable ? '1' : '0'; $record['project_id'] = $cl_project; $record['task_id'] = $cl_task; - $record['cf_1_value'] = $cl_cf_1; + if ($custom_fields && $custom_fields->timeFields) { + foreach ($custom_fields->timeFields as $timeField) { + $field_name = 'time_field_'.$timeField['id']; + $record[$field_name] = $timeCustomFields[$timeField['id']]['value']; + } + } $fields['row_id'] = ttWeekViewHelper::makeRowIdentifier($record).'_0'; // Note: no need to check for a possible conflict with an already existing row // because we are doing an insert that does not affect already existing data. From 895dd669e8fb21490e3e357570ac78d88b771e08 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 14 Jul 2019 15:51:14 +0000 Subject: [PATCH 029/877] Fixed left joins for reporting on multiple time custom fields. --- WEB-INF/lib/ttReportHelper.class.php | 4 ++-- WEB-INF/templates/footer.tpl | 2 +- tofile.php | 9 +++++++++ 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index f08a09b25..f0ce800b1 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -422,11 +422,11 @@ static function getItems($options) { $cflTable = 'cfl'.$timeField['id']; if ($timeField['type'] == CustomFields::TYPE_TEXT) { // Add one join for each text field. - $left_joins .= " left join tt_custom_field_log $cflTable on ($cflTable.log_id = l.id and $cflTable.status = 1)"; + $left_joins .= " left join tt_custom_field_log $cflTable on ($cflTable.log_id = l.id and $cflTable.status = 1 and $cflTable.field_id = ".$timeField['id'].')'; } elseif ($timeField['type'] == CustomFields::TYPE_DROPDOWN) { $cfoTable = 'cfo'.$timeField['id']; // Add two joins for each dropdown field. - $left_joins .= " left join tt_custom_field_log $cflTable on ($cflTable.log_id = l.id and $cflTable.status = 1)"; + $left_joins .= " left join tt_custom_field_log $cflTable on ($cflTable.log_id = l.id and $cflTable.status = 1 and $cflTable.field_id = ".$timeField['id'].')'; $left_joins .= " left join tt_custom_field_options $cfoTable on ($cfoTable.field_id = $cflTable.field_id and $cfoTable.id = $cflTable.option_id)"; } } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 347e9afe0..10ca1f60e 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.19.7.5035 | Copyright © Anuko | +  Anuko Time Tracker 1.19.7.5036 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 442e649d5fa5962447ce12df7b0a29cba4d77e9b Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 5 Jul 2019 19:39:34 +0000 Subject: [PATCH 025/877] Fixed left joins in reports for user custom fields. --- WEB-INF/lib/ttReportHelper.class.php | 4 ++-- WEB-INF/templates/footer.tpl | 2 +- reports.php | 19 +++++++++++++++++++ 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index 3b5b9cd3e..65d72d833 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -358,7 +358,7 @@ static function getItems($options) { $field_name = 'user_field_'.$userField['id']; $checkbox_field_name = 'show_'.$field_name; $entity_type = CustomFields::ENTITY_USER; - if ($options[$checkbox_field_name]) { + if ($options[$field_name] || $options[$checkbox_field_name]) { $ecfTable = 'ecf'.$userField['id']; if ($userField['type'] == CustomFields::TYPE_TEXT) { // Add one join for each text field. @@ -500,7 +500,7 @@ static function getItems($options) { $field_name = 'user_field_'.$userField['id']; $checkbox_field_name = 'show_'.$field_name; $entity_type = CustomFields::ENTITY_USER; - if ($options[$checkbox_field_name]) { + if ($options[$field_name] || $options[$checkbox_field_name]) { $ecfTable = 'ecf'.$userField['id']; if ($userField['type'] == CustomFields::TYPE_TEXT) { // Add one join for each text field. diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index c00ac59b2..27af3ae2c 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- +{if isTrue('CF_DEBUG')} +{if $custom_fields && $custom_fields->timeFields} + + {foreach $custom_fields->timeFields as $timeField} + + + {assign var="control_name" value='time_field_'|cat:$timeField['id']} + {assign var="checkbox_control_name" value='show_time_field_'|cat:$timeField['id']} + + + + {/foreach} +{/if} +{/if} {if $custom_fields && $custom_fields->userFields} {foreach $custom_fields->userFields as $userField} diff --git a/reports.php b/reports.php index b48ec0a9d..d3a70dc64 100644 --- a/reports.php +++ b/reports.php @@ -330,12 +330,11 @@ $field_name = 'time_field_'.$timeField['id']; $checkbox_field_name = 'show_'.$field_name; if ($timeField['type'] == CustomFields::TYPE_TEXT) { - $form->addInput(array('type'=>'text','name'=>$field_name,'style'=>'width: 250px;','value'=>$timeCustomFields[$userField['id']]['value'])); + $form->addInput(array('type'=>'text','name'=>$field_name,'style'=>'width: 250px;')); } elseif ($timeField['type'] == CustomFields::TYPE_DROPDOWN) { $form->addInput(array('type'=>'combobox','name'=>$field_name, 'style'=>'width: 250px;', 'data'=>CustomFields::getOptions($timeField['id']), - 'value'=>$timeCustomFields[$timeField['id']]['value'], 'empty'=>array(''=>$i18n->get('dropdown.all')))); } // Also add a checkbox (to print the field or not). @@ -349,12 +348,11 @@ $field_name = 'user_field_'.$userField['id']; $checkbox_field_name = 'show_'.$field_name; if ($userField['type'] == CustomFields::TYPE_TEXT) { - $form->addInput(array('type'=>'text','name'=>$field_name,'style'=>'width: 250px;','value'=>$userCustomFields[$userField['id']]['value'])); + $form->addInput(array('type'=>'text','name'=>$field_name,'style'=>'width: 250px;')); } elseif ($userField['type'] == CustomFields::TYPE_DROPDOWN) { $form->addInput(array('type'=>'combobox','name'=>$field_name, 'style'=>'width: 250px;', 'data'=>CustomFields::getOptions($userField['id']), - 'value'=>$userCustomFields[$userField['id']]['value'], 'empty'=>array(''=>$i18n->get('dropdown.all')))); } // Also add a checkbox (to print the field or not). From d0a79bc40068548ec871c7c775bd1e1d16add28c Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 6 Jul 2019 15:09:33 +0000 Subject: [PATCH 027/877] Added code to support multiple time custom fields to reports. --- WEB-INF/lib/ttReportHelper.class.php | 122 +++++++++++++++++++++++++-- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/report.tpl | 46 ++++++++++ 3 files changed, 164 insertions(+), 6 deletions(-) diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index 65d72d833..6fcb747cf 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -86,6 +86,17 @@ static function getWhere($options) { if ($options['approved']=='2') $dropdown_parts .= ' and l.approved = 0'; if ($options['paid_status']=='1') $dropdown_parts .= ' and l.paid = 1'; if ($options['paid_status']=='2') $dropdown_parts .= ' and l.paid = 0'; + // Add time custom fields. + if ($custom_fields && $custom_fields->timeFields) { + foreach ($custom_fields->timeFields as $timeField) { + $field_name = 'time_field_'.$timeField['id']; + $field_value = $options[$field_name]; + if ($timeField['type'] == CustomFields::TYPE_DROPDOWN && $field_value) { + $cfoTable = 'cfo'.$timeField['id']; + $dropdown_parts .= " and $cfoTable.id = $field_value"; + } + } + } // Add user custom fields. if ($custom_fields && $custom_fields->userFields) { foreach ($custom_fields->userFields as $userField) { @@ -166,6 +177,11 @@ static function getExpenseWhere($options) { if ($options['approved']=='2') $dropdown_parts .= ' and ei.approved = 0'; if ($options['paid_status']=='1') $dropdown_parts .= ' and ei.paid = 1'; if ($options['paid_status']=='2') $dropdown_parts .= ' and ei.paid = 0'; + + // Not adding conditions for time custom fields by design because expenses are not associated with them. + // Whether or not this is proper, we'll know eventually if users complain. + // This means that filtering by custom fields applies only to time items, not expenses. + // Add user custom fields. if ($custom_fields && $custom_fields->userFields) { foreach ($custom_fields->userFields as $userField) { @@ -293,6 +309,22 @@ static function getItems($options) { array_push($fields, 'cfo.value as cf_1'); } } + // Add time custom fields. + if ($custom_fields && $custom_fields->timeFields) { + foreach ($custom_fields->timeFields as $timeField) { + $field_name = 'time_field_'.$timeField['id']; + $checkbox_field_name = 'show_'.$field_name; + if ($options[$checkbox_field_name]) { + if ($timeField['type'] == CustomFields::TYPE_TEXT) { + $cflTable = 'cfl'.$timeField['id']; + array_push($fields, "$cflTable.value as $field_name"); + } elseif ($timeField['type'] == CustomFields::TYPE_DROPDOWN) { + $cfoTable = 'cfo'.$timeField['id']; + array_push($fields, "$cfoTable.value as $field_name"); + } + } + } + } // Add start time. if ($options['show_start']) { array_push($fields, "l.start as unformatted_start"); @@ -390,6 +422,25 @@ static function getItems($options) { " left join tt_custom_field_options cfo on (cfl.option_id = cfo.id)"; } } + // Left joins for time custom fields. + if ($custom_fields && $custom_fields->timeFields) { + foreach ($custom_fields->timeFields as $timeField) { + $field_name = 'time_field_'.$timeField['id']; + $checkbox_field_name = 'show_'.$field_name; + if ($options[$field_name] || $options[$checkbox_field_name]) { + $cflTable = 'cfl'.$timeField['id']; + if ($timeField['type'] == CustomFields::TYPE_TEXT) { + // Add one join for each text field. + $left_joins .= " left join tt_custom_field_log $cflTable on ($cflTable.log_id = l.id and $cflTable.status = 1)"; + } elseif ($timeField['type'] == CustomFields::TYPE_DROPDOWN) { + $cfoTable = 'cfo'.$timeField['id']; + // Add two joins for each dropdown field. + $left_joins .= " left join tt_custom_field_log $cflTable on ($cflTable.log_id = l.id and $cflTable.status = 1)"; + $left_joins .= " left join tt_custom_field_options $cfoTable on ($cfoTable.field_id = $cflTable.field_id and $cfoTable.id = $cflTable.option_id)"; + } + } + } + } if ($includeCost && MODE_TIME != $trackingMode) $left_joins .= " left join tt_user_project_binds upb on (l.user_id = upb.user_id and l.project_id = upb.project_id)"; if ($options['show_files']) { @@ -455,6 +506,16 @@ static function getItems($options) { array_push($fields, 'null'); // null for task name. We need to match column count for union. if ($options['show_custom_field_1'] || $grouping_by_cf_1) array_push($fields, 'null'); // null for cf_1. + // Add null values for time custom fields. + if ($custom_fields && $custom_fields->timeFields) { + foreach ($custom_fields->timeFields as $timeField) { + $field_name = 'time_field_'.$timeField['id']; + $checkbox_field_name = 'show_'.$field_name; + if ($options[$checkbox_field_name]) { + array_push($fields, "null as $field_name"); // null for each time custom field. + } + } + } if ($options['show_start']) { array_push($fields, 'null'); // null for unformatted_start. array_push($fields, 'null'); // null for start. @@ -715,6 +776,24 @@ static function getTotals($options) // Prepare left joins. $left_joins = null; // Left joins for custom fields. + if ($custom_fields && $custom_fields->timeFields) { + foreach ($custom_fields->timeFields as $timeField) { + $field_name = 'time_field_'.$timeField['id']; + $field_value = $options[$field_name]; + if ($field_value) { + $cflTable = 'cfl'.$timeField['id']; + if ($timeField['type'] == CustomFields::TYPE_TEXT) { + // Add one join for each text field. + $left_joins .= " left join tt_custom_field_log $cflTable on ($cflTable.log_id = l.id and $cflTable.status = 1)"; + } elseif ($timeField['type'] == CustomFields::TYPE_DROPDOWN) { + $cfoTable = 'cfo'.$timeField['id']; + // Add two joins for each dropdown field. + $left_joins .= " left join tt_custom_field_log $cflTable on ($cflTable.log_id = l.id and $cflTable.status = 1)"; + $left_joins .= " left join tt_custom_field_options $cfoTable on ($cfoTable.field_id = $cflTable.field_id and $cfoTable.id = $cflTable.option_id)"; + } + } + } + } if ($custom_fields && $custom_fields->userFields) { foreach ($custom_fields->userFields as $userField) { $field_name = 'user_field_'.$userField['id']; @@ -1394,10 +1473,21 @@ static function getReportOptions($bean) { // Prepare custom field options. if ($user->isPluginEnabled('cf')) { - require_once('plugins/CustomFields.class.php'); - $custom_fields = new CustomFields(); + global $custom_fields; + if (!$custom_fields) { + require_once('plugins/CustomFields.class.php'); + $custom_fields = new CustomFields(); + } // TODO: reconsider the need for construction for fav report emailing (debug). - // TODO: add time fields here. + // Time fields. + if ($custom_fields->timeFields) { + foreach ($custom_fields->timeFields as $timeField) { + $control_name = 'time_field_'.$timeField['id']; + $checkbox_control_name = 'show_'.$control_name; + $options[$control_name] = $bean->getAttribute($control_name); + $options[$checkbox_control_name] = $bean->getAttribute($checkbox_control_name); + } + } // User fields. if ($custom_fields->userFields) { @@ -1408,6 +1498,8 @@ static function getReportOptions($bean) { $options[$checkbox_control_name] = $bean->getAttribute($checkbox_control_name); } } + + // TODO: add project fields here. } $options['group_by1'] = $bean->getAttribute('group_by1'); @@ -1900,7 +1992,26 @@ static function makeJoinPart($options) { if ($options['show_cost'] && $trackingMode != MODE_TIME) { $left_joins .= ' left join tt_user_project_binds upb on (l.user_id = upb.user_id and l.project_id = upb.project_id)'; } - // Left joins for custom fields. + // Left joins for time custom fields. + if ($custom_fields && $custom_fields->timeFields) { + foreach ($custom_fields->timeFields as $timeField) { + $field_name = 'time_field_'.$timeField['id']; + $field_value = $options[$field_name]; + if ($field_value) { + $cflTable = 'cfl'.$timeField['id']; + if ($timeField['type'] == CustomFields::TYPE_TEXT) { + // Add one join for each text field. + $left_joins .= " left join tt_custom_field_log $cflTable on ($cflTable.log_id = l.id and $cflTable.status = 1)"; + } elseif ($timeField['type'] == CustomFields::TYPE_DROPDOWN) { + $cfoTable = 'cfo'.$timeField['id']; + // Add two joins for each dropdown field. + $left_joins .= " left join tt_custom_field_log $cflTable on ($cflTable.log_id = l.id and $cflTable.status = 1)"; + $left_joins .= " left join tt_custom_field_options $cfoTable on ($cfoTable.field_id = $cflTable.field_id and $cfoTable.id = $cflTable.option_id)"; + } + } + } + } + // Left joins for user custom fields. if ($custom_fields && $custom_fields->userFields) { foreach ($custom_fields->userFields as $userField) { $field_name = 'user_field_'.$userField['id']; @@ -1991,7 +2102,8 @@ static function makeJoinExpensesPart($options) { if (ttReportHelper::groupingBy('project', $options)) { $left_joins .= ' left join tt_projects p on (ei.project_id = p.id)'; } - // Left joins for custom fields. + // Not adding left joins for time custom fiels by design. + // Left joins for user custom fields. if ($custom_fields && $custom_fields->userFields) { foreach ($custom_fields->userFields as $userField) { $field_name = 'user_field_'.$userField['id']; diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 42b54855a..2b002293e 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.19.7.5036 | Copyright © Anuko | +  Anuko Time Tracker 1.19.7.5037 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/reports.php b/reports.php index 95e79c636..b48ec0a9d 100644 --- a/reports.php +++ b/reports.php @@ -324,6 +324,25 @@ if ($showTimesheetCheckbox) $form->addInput(array('type'=>'hidden','name'=>'timesheet_user_id')); +// If we have time custom fields - add controls for them. +if ($custom_fields && $custom_fields->timeFields) { + foreach ($custom_fields->timeFields as $timeField) { + $field_name = 'time_field_'.$timeField['id']; + $checkbox_field_name = 'show_'.$field_name; + if ($timeField['type'] == CustomFields::TYPE_TEXT) { + $form->addInput(array('type'=>'text','name'=>$field_name,'style'=>'width: 250px;','value'=>$timeCustomFields[$userField['id']]['value'])); + } elseif ($timeField['type'] == CustomFields::TYPE_DROPDOWN) { + $form->addInput(array('type'=>'combobox','name'=>$field_name, + 'style'=>'width: 250px;', + 'data'=>CustomFields::getOptions($timeField['id']), + 'value'=>$timeCustomFields[$timeField['id']]['value'], + 'empty'=>array(''=>$i18n->get('dropdown.all')))); + } + // Also add a checkbox (to print the field or not). + $form->addInput(array('type'=>'checkbox','name'=>$checkbox_field_name)); + } +} + // If we have user custom fields - add controls for them. if ($custom_fields && $custom_fields->userFields) { foreach ($custom_fields->userFields as $userField) { From 8cf6a7eb406f8603a6d88b4f038e84bcf996d271 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 5 Jul 2019 20:04:52 +0000 Subject: [PATCH 026/877] Added controls on reports.php for multiple time custom fields. --- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/reports.tpl | 14 ++++++++++++++ reports.php | 6 ++---- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 27af3ae2c..42b54855a 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.19.7.5037 | Copyright © Anuko | +  Anuko Time Tracker 1.19.7.5038 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/reports.tpl b/WEB-INF/templates/reports.tpl index 5256dbb9a..616282e29 100644 --- a/WEB-INF/templates/reports.tpl +++ b/WEB-INF/templates/reports.tpl @@ -398,6 +398,20 @@ function handleCheckboxes() {
{$i18n.form.reports.time_fields}
{$timeField['label']|escape}:{$forms.reportForm.$control_name.control}{$forms.reportForm.$checkbox_control_name.control}
{$i18n.form.reports.user_fields}
- {/if} {if $bean->getAttribute('chtask')}{/if} {if $bean->getAttribute('chcf_1')}{/if} + + {* time custom fileds *} + {if $custom_fields && $custom_fields->timeFields} + {foreach $custom_fields->timeFields as $timeField} + {assign var="checkbox_control_name" value='show_time_field_'|cat:$timeField['id']} + {if $bean->getAttribute($checkbox_control_name)}{/if} + {/foreach} + {/if} + {if $bean->getAttribute('chstart')}{/if} {if $bean->getAttribute('chfinish')}{/if} {if $bean->getAttribute('chduration')}{/if} @@ -88,6 +97,15 @@ {if $bean->getAttribute('chproject')}{/if} {if $bean->getAttribute('chtask')}{/if} {if $bean->getAttribute('chcf_1')}{/if} + + {* time custom fileds *} + {if $custom_fields && $custom_fields->timeFields} + {foreach $custom_fields->timeFields as $timeField} + {assign var="checkbox_control_name" value='show_time_field_'|cat:$timeField['id']} + {if $bean->getAttribute($checkbox_control_name)}{/if} + {/foreach} + {/if} + {if $bean->getAttribute('chstart')}{/if} {if $bean->getAttribute('chfinish')}{/if} {if $bean->getAttribute('chduration')}{/if} @@ -127,6 +145,16 @@ {if $bean->getAttribute('chproject')}{/if} {if $bean->getAttribute('chtask')}{/if} {if $bean->getAttribute('chcf_1')}{/if} + + {* time custom fileds *} + {if $custom_fields && $custom_fields->timeFields} + {foreach $custom_fields->timeFields as $timeField} + {assign var="control_name" value='time_field_'|cat:$timeField['id']} + {assign var="checkbox_control_name" value='show_time_field_'|cat:$timeField['id']} + {if $bean->getAttribute($checkbox_control_name)}{/if} + {/foreach} + {/if} + {if $bean->getAttribute('chstart')}{/if} {if $bean->getAttribute('chfinish')}{/if} {if $bean->getAttribute('chduration')}{/if} @@ -171,6 +199,15 @@ {if $bean->getAttribute('chproject')}{/if} {if $bean->getAttribute('chtask')}{/if} {if $bean->getAttribute('chcf_1')}{/if} + + {* time custom fileds *} + {if $custom_fields && $custom_fields->timeFields} + {foreach $custom_fields->timeFields as $timeField} + {assign var="checkbox_control_name" value='show_time_field_'|cat:$timeField['id']} + {if $bean->getAttribute($checkbox_control_name)}{/if} + {/foreach} + {/if} + {if $bean->getAttribute('chstart')}{/if} {if $bean->getAttribute('chfinish')}{/if} {if $bean->getAttribute('chduration')}{/if} @@ -204,6 +241,15 @@ {if $bean->getAttribute('chproject')}{/if} {if $bean->getAttribute('chtask')}{/if} {if $bean->getAttribute('chcf_1')}{/if} + + {* time custom fileds *} + {if $custom_fields && $custom_fields->timeFields} + {foreach $custom_fields->timeFields as $timeField} + {assign var="checkbox_control_name" value='show_time_field_'|cat:$timeField['id']} + {if $bean->getAttribute($checkbox_control_name)}{/if} + {/foreach} + {/if} + {if $bean->getAttribute('chstart')}{/if} {if $bean->getAttribute('chfinish')}{/if} {if $bean->getAttribute('chduration')}{/if} From f32696b09bfbb9951419d2849004b4db552fa5a0 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 14 Jul 2019 15:07:01 +0000 Subject: [PATCH 028/877] Initial release of multiple custom fields for user testing. --- WEB-INF/lib/ttReportHelper.class.php | 52 +- WEB-INF/lib/ttTimeHelper.class.php | 8 +- WEB-INF/lib/ttWeekViewHelper.class.php | 131 +++- WEB-INF/templates/cf_custom_field_add.tpl | 2 - WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/mobile/time.tpl | 10 +- WEB-INF/templates/mobile/time_edit.tpl | 9 +- WEB-INF/templates/reports.tpl | 9 - WEB-INF/templates/time.tpl | 18 +- WEB-INF/templates/time_edit.tpl | 8 +- WEB-INF/templates/week.tpl | 12 +- cf_custom_field_add.php | 5 - cf_custom_fields.php | 3 - mobile/time.php | 53 +- mobile/time_edit.php | 81 +- plugins/CustomFields.class.php | 888 ++++++++++++---------- reports.php | 21 - time.php | 56 +- time_edit.php | 81 +- user_edit.php | 4 +- week.php | 54 +- 21 files changed, 843 insertions(+), 664 deletions(-) diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index 6fcb747cf..f08a09b25 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -55,11 +55,8 @@ static function getWhere($options) { if ($user->isPluginEnabled('cf')) { global $custom_fields; - if (!$custom_fields) { - require_once('plugins/CustomFields.class.php'); - $custom_fields = new CustomFields(); - } - } // TODO: reconsider the need for construction for fav report emailing (debug). + if (!$custom_fields) $custom_fields = new CustomFields(); + } // A shortcut for timesheets. if ($options['timesheet_id']) { @@ -155,11 +152,8 @@ static function getExpenseWhere($options) { if ($user->isPluginEnabled('cf')) { global $custom_fields; - if (!$custom_fields) { - require_once('plugins/CustomFields.class.php'); - $custom_fields = new CustomFields(); - } - } // TODO: reconsider the need for construction for fav report emailing (debug). + if (!$custom_fields) $custom_fields = new CustomFields(); + } // Prepare dropdown parts. $dropdown_parts = ''; @@ -180,7 +174,7 @@ static function getExpenseWhere($options) { // Not adding conditions for time custom fields by design because expenses are not associated with them. // Whether or not this is proper, we'll know eventually if users complain. - // This means that filtering by custom fields applies only to time items, not expenses. + // This means that filtering by time custom fields applies only to time items, not expenses. // Add user custom fields. if ($custom_fields && $custom_fields->userFields) { @@ -246,11 +240,8 @@ static function getItems($options) { if ($user->isPluginEnabled('cf')) { global $custom_fields; - if (!$custom_fields) { - require_once('plugins/CustomFields.class.php'); - $custom_fields = new CustomFields(); - } - } // TODO: reconsider the need for construction for fav report emailing (debug). + if (!$custom_fields) $custom_fields = new CustomFields(); + } $grouping = ttReportHelper::grouping($options); if ($grouping) { @@ -743,14 +734,10 @@ static function getTotals($options) global $user; $mdb2 = getConnection(); - // Add user custom fields. if ($user->isPluginEnabled('cf')) { global $custom_fields; - if (!$custom_fields) { - require_once('plugins/CustomFields.class.php'); - $custom_fields = new CustomFields(); - } - } // TODO: reconsider the need for construction for fav report emailing (debug). + if (!$custom_fields) $custom_fields = new CustomFields(); + } $trackingMode = $user->getTrackingMode(); $decimalMark = $user->getDecimalMark(); @@ -1474,10 +1461,7 @@ static function getReportOptions($bean) { // Prepare custom field options. if ($user->isPluginEnabled('cf')) { global $custom_fields; - if (!$custom_fields) { - require_once('plugins/CustomFields.class.php'); - $custom_fields = new CustomFields(); - } // TODO: reconsider the need for construction for fav report emailing (debug). + if (!$custom_fields) $custom_fields = new CustomFields(); // Time fields. if ($custom_fields->timeFields) { @@ -1959,14 +1943,10 @@ static function makeCombinedSelectPart($options) { static function makeJoinPart($options) { global $user; - // Add user custom fields. if ($user->isPluginEnabled('cf')) { global $custom_fields; - if (!$custom_fields) { - require_once('plugins/CustomFields.class.php'); - $custom_fields = new CustomFields(); - } - } // TODO: reconsider the need for construction for fav report emailing (debug). + if (!$custom_fields) $custom_fields = new CustomFields(); + } $trackingMode = $user->getTrackingMode(); $left_joins = null; @@ -2083,14 +2063,10 @@ static function makeCostPart($options) { static function makeJoinExpensesPart($options) { global $user; - // Add user custom fields. if ($user->isPluginEnabled('cf')) { global $custom_fields; - if (!$custom_fields) { - require_once('plugins/CustomFields.class.php'); - $custom_fields = new CustomFields(); - } - } // TODO: reconsider the need for construction for fav report emailing (debug). + if (!$custom_fields) $custom_fields = new CustomFields(); + } $left_joins = null; if (ttReportHelper::groupingBy('user', $options)) { diff --git a/WEB-INF/lib/ttTimeHelper.class.php b/WEB-INF/lib/ttTimeHelper.class.php index d7278c69e..29010036c 100644 --- a/WEB-INF/lib/ttTimeHelper.class.php +++ b/WEB-INF/lib/ttTimeHelper.class.php @@ -859,6 +859,7 @@ static function getRecords($date, $includeFiles = false) { if ($user->isPluginEnabled('cl')) $client_field = ", c.name as client"; + /* $include_cf_1 = $user->isPluginEnabled('cf'); if ($include_cf_1) { $custom_fields = new CustomFields(); @@ -868,7 +869,7 @@ static function getRecords($date, $includeFiles = false) { } elseif ($cf_1_type == CustomFields::TYPE_DROPDOWN) { $custom_field = ", cfo.value as cf_1"; } - } + }*/ if ($includeFiles) { $filePart = ', if(Sub1.entity_id is null, 0, 1) as has_files'; @@ -881,14 +882,15 @@ static function getRecords($date, $includeFiles = false) { " left join tt_tasks t on (l.task_id = t.id)"; if ($user->isPluginEnabled('cl')) $left_joins .= " left join tt_clients c on (l.client_id = c.id)"; - if ($include_cf_1) { + /* Multiple left joins are now required, probably with config options which fields to show. + * if ($include_cf_1) { if ($cf_1_type == CustomFields::TYPE_TEXT) $left_joins .= " left join tt_custom_field_log cfl on (l.id = cfl.log_id and cfl.status = 1)"; elseif ($cf_1_type == CustomFields::TYPE_DROPDOWN) { $left_joins .= " left join tt_custom_field_log cfl on (l.id = cfl.log_id and cfl.status = 1)". " left join tt_custom_field_options cfo on (cfl.option_id = cfo.id)"; } - } + }*/ $left_joins .= $fileJoin; $result = array(); diff --git a/WEB-INF/lib/ttWeekViewHelper.class.php b/WEB-INF/lib/ttWeekViewHelper.class.php index 348648163..42815e31b 100644 --- a/WEB-INF/lib/ttWeekViewHelper.class.php +++ b/WEB-INF/lib/ttWeekViewHelper.class.php @@ -44,45 +44,70 @@ static function getRecordsForInterval($start_date, $end_date, $includeFiles = fa $result = array(); $mdb2 = getConnection(); - $client_field = null; - if ($user->isPluginEnabled('cl')) - $client_field = ', c.id as client_id, c.name as client'; - - $custom_field_1 = null; - if ($user->isPluginEnabled('cf')) { - $custom_fields = new CustomFields(); - $cf_1_type = $custom_fields->fields[0]['type']; - if ($cf_1_type == CustomFields::TYPE_TEXT) { - $custom_field_1 = ', cfl.value as cf_1_value'; - } elseif ($cf_1_type == CustomFields::TYPE_DROPDOWN) { - $custom_field_1 = ', cfo.id as cf_1_id, cfo.value as cf_1_value'; + $fields = array(); // An array of fields for database query. + array_push($fields, 'l.id as id'); + array_push($fields, 'l.date as date'); + array_push($fields, "TIME_FORMAT(l.start, $sql_time_format) as start"); + array_push($fields, "TIME_FORMAT(sec_to_time(time_to_sec(l.start) + time_to_sec(l.duration)), $sql_time_format) as finish"); + array_push($fields, "TIME_FORMAT(l.duration, '%k:%i') as duration"); + array_push($fields, "p.id as project_id"); + array_push($fields, "p.name as project"); + array_push($fields, "t.id as task_id"); + array_push($fields, "t.name as task"); + array_push($fields, "l.comment"); + array_push($fields, "l.billable"); + array_push($fields, "l.invoice_id"); + if ($user->isPluginEnabled('cl')) { + array_push($fields, "c.id as client_id"); + array_push($fields, "c.name as client"); + } + // Add time custom fields. + global $custom_fields; + if ($custom_fields && $custom_fields->timeFields) { + foreach ($custom_fields->timeFields as $timeField) { + $field_name = 'time_field_'.$timeField['id']; + if ($timeField['type'] == CustomFields::TYPE_TEXT) { + $cflTable = 'cfl'.$timeField['id']; + array_push($fields, "$cflTable.value as $field_name"); + } elseif ($timeField['type'] == CustomFields::TYPE_DROPDOWN) { + $cfoTable = 'cfo'.$timeField['id']; + array_push($fields, "$cfoTable.id as $field_name".'_option_id'); + array_push($fields, "$cfoTable.value as $field_name"); + } } } - if ($includeFiles) { - $filePart = ', if(Sub1.entity_id is null, 0, 1) as has_files'; - $fileJoin = " left join (select distinct entity_id from tt_files". - " where entity_type = 'time' and group_id = $group_id and org_id = $org_id and status = 1) Sub1". - " on (l.id = Sub1.entity_id)"; + array_push($fields, 'if(Sub1.entity_id is null, 0, 1) as has_files'); } $left_joins = " left join tt_projects p on (l.project_id = p.id)". " left join tt_tasks t on (l.task_id = t.id)"; if ($user->isPluginEnabled('cl')) $left_joins .= " left join tt_clients c on (l.client_id = c.id)"; - if ($user->isPluginEnabled('cf')) { - if ($custom_fields->fields[0]['type'] == CustomFields::TYPE_TEXT) - $left_joins .= 'left join tt_custom_field_log cfl on (l.id = cfl.log_id and cfl.status = 1) left join tt_custom_field_options cfo on (cfl.value = cfo.id) '; - elseif ($custom_fields->fields[0]['type'] == CustomFields::TYPE_DROPDOWN) - $left_joins .= 'left join tt_custom_field_log cfl on (l.id = cfl.log_id and cfl.status = 1) left join tt_custom_field_options cfo on (cfl.option_id = cfo.id) '; + + // Left joins for time custom fields. + if ($custom_fields && $custom_fields->timeFields) { + foreach ($custom_fields->timeFields as $timeField) { + $field_name = 'time_field_'.$timeField['id']; + $cflTable = 'cfl'.$timeField['id']; + if ($timeField['type'] == CustomFields::TYPE_TEXT) { + // Add one join for each text field. + $left_joins .= " left join tt_custom_field_log $cflTable on ($cflTable.log_id = l.id and $cflTable.status = 1 and $cflTable.field_id = ".$timeField['id'].')'; + } elseif ($timeField['type'] == CustomFields::TYPE_DROPDOWN) { + $cfoTable = 'cfo'.$timeField['id']; + // Add two joins for each dropdown field. + $left_joins .= " left join tt_custom_field_log $cflTable on ($cflTable.log_id = l.id and $cflTable.status = 1 and $cflTable.field_id = ".$timeField['id'].')'; + $left_joins .= " left join tt_custom_field_options $cfoTable on ($cfoTable.field_id = $cflTable.field_id and $cfoTable.id = $cflTable.option_id)"; + } + } + } + if ($includeFiles) { + $left_joins .= " left join (select distinct entity_id from tt_files". + " where entity_type = 'time' and group_id = $group_id and org_id = $org_id and status = 1) Sub1". + " on (l.id = Sub1.entity_id)"; } - $left_joins .= $fileJoin; - $sql = "select l.id as id, l.date as date, TIME_FORMAT(l.start, $sql_time_format) as start,". - " TIME_FORMAT(sec_to_time(time_to_sec(l.start) + time_to_sec(l.duration)), $sql_time_format) as finish,". - " TIME_FORMAT(l.duration, '%k:%i') as duration, p.id as project_id, p.name as project,". - " t.id as task_id, t.name as task, l.comment, l.billable, l.invoice_id $client_field $custom_field_1 $filePart". - " from tt_log l $left_joins". + $sql = "select ".join(', ', $fields)." from tt_log l $left_joins". " where l.date >= '$start_date' and l.date <= '$end_date'". " and l.user_id = $user_id and l.group_id = $group_id and l.org_id = $org_id and l.status = 1". " order by l.date, p.name, t.name, l.start, l.id"; @@ -414,14 +439,18 @@ static function makeRowIdentifier($record) { $row_identifier .= $record['project_id'] ? ',pr:'.$record['project_id'] : ''; // Add task. $row_identifier .= $record['task_id'] ? ',ts:'.$record['task_id'] : ''; - // Add custom field 1. - if ($user->isPluginEnabled('cf')) { - if ($record['cf_1_id']) - $row_identifier .= ',cf_1:'.$record['cf_1_id']; - else if ($record['cf_1_value']) - $row_identifier .= ',cf_1:'.$record['cf_1_value']; + // Add custom field parts. + global $custom_fields; + if ($custom_fields && $custom_fields->timeFields) { + foreach ($custom_fields->timeFields as $timeField) { + $field_name = 'time_field_'.$timeField['id']; + if ($timeField['type'] == CustomFields::TYPE_TEXT) + $field_value = $record[$field_name]; + else if ($timeField['type'] == CustomFields::TYPE_DROPDOWN) + $field_value = $record[$field_name.'_option_id']; + $row_identifier .= ',cf_'.$timeField['id'].":$field_value"; + } } - return $row_identifier; } @@ -450,6 +479,17 @@ static function makeRowLabel($record) { $label .= $record['cf_1_value']; } + // Add custom field parts. + global $custom_fields; + if ($custom_fields && $custom_fields->timeFields) { + foreach ($custom_fields->timeFields as $timeField) { + $field_name = 'time_field_'.$timeField['id']; + $field_value = $record[$field_name]; + if (!empty($label) && !empty($field_value)) $label .= ' - '; + $label .= $field_value; + } + } + return $label; } @@ -526,14 +566,21 @@ static function insertDurationFromWeekView($fields, $custom_fields, $err) { $id = ttTimeHelper::insert($fields4insert); if (!$id) return false; // Something failed. - // Insert custom field if we have it. + // Insert time custom fields if we have them. $result = true; - $cf_1 = ttWeekViewHelper::parseFromWeekViewRow($fields['row_id'], 'cf_1'); - if ($custom_fields && $cf_1) { - if ($custom_fields->fields[0]['type'] == CustomFields::TYPE_TEXT) - $result = $custom_fields->insert($id, $custom_fields->fields[0]['id'], null, $cf_1); - elseif ($custom_fields->fields[0]['type'] == CustomFields::TYPE_DROPDOWN) - $result = $custom_fields->insert($id, $custom_fields->fields[0]['id'], $cf_1, null); + if ($id && $custom_fields && $custom_fields->timeFields) { + if ($fields['row_id']) { + foreach ($custom_fields->timeFields as $timeField) { +// $control_name = 'time_field_'.$timeField['id']; + $timeCustomFields[$timeField['id']] = array('field_id' => $timeField['id'], +// 'control_name' => $control_name, +// 'label' => $timeField['label'], + 'type' => $timeField['type'], +// 'required' => $timeField['required'], + 'value' => ttWeekViewHelper::parseFromWeekViewRow($fields['row_id'], 'cf_'.$timeField['id'])); + } + } + $result = $custom_fields->insertTimeFields($id, $timeCustomFields); // TODO: fix this. } return $result; diff --git a/WEB-INF/templates/cf_custom_field_add.tpl b/WEB-INF/templates/cf_custom_field_add.tpl index 4c343eec9..089e4b681 100644 --- a/WEB-INF/templates/cf_custom_field_add.tpl +++ b/WEB-INF/templates/cf_custom_field_add.tpl @@ -8,12 +8,10 @@ -{if isTrue('CF_DEBUG')} -{/if} diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 2b002293e..347e9afe0 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.19.7.5038 | Copyright © Anuko | +  Anuko Time Tracker 1.19.7.5039 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/report.tpl b/WEB-INF/templates/report.tpl index 64c69c6c2..03d8d4497 100644 --- a/WEB-INF/templates/report.tpl +++ b/WEB-INF/templates/report.tpl @@ -53,6 +53,15 @@ {if $bean->getAttribute('chproject')}{$i18n.label.project}{$i18n.label.task}{$custom_fields->fields[0]['label']|escape}{{$timeField['label']|escape}}{$i18n.label.start}{$i18n.label.finish}{$i18n.label.duration}{$subtotals[$prev_grouped_by]['project']|escape}{$subtotals[$prev_grouped_by]['task']|escape}{$subtotals[$prev_grouped_by]['cf_1']|escape}{$subtotals[$prev_grouped_by]['time']}{$item.project|escape}{$item.task|escape}{$item.cf_1|escape}{$item.$control_name|escape}{$item.start}{$item.finish}{$item.duration}{$subtotals[$cur_grouped_by]['project']|escape}{$subtotals[$cur_grouped_by]['task']|escape}{$subtotals[$cur_grouped_by]['cf_1']|escape}{$subtotals[$cur_grouped_by]['time']}{$totals['time']}{$i18n.label.thing_name} (*): {$forms.fieldForm.name.control}
{$i18n.label.entity}: {$forms.fieldForm.entity.control} {$i18n.label.what_is_it}
{$i18n.label.type}: {$forms.fieldForm.type.control}
- {/if} -{if ($custom_fields && $custom_fields->fields[0])} - - +{if $custom_fields && $custom_fields->timeFields} + {foreach $custom_fields->timeFields as $timeField} + + {assign var="control_name" value='time_field_'|cat:$timeField['id']} + + + {/foreach} {/if} {if ($smarty.const.MODE_PROJECTS == $user->tracking_mode || $smarty.const.MODE_PROJECTS_AND_TASKS == $user->tracking_mode)} diff --git a/WEB-INF/templates/mobile/time_edit.tpl b/WEB-INF/templates/mobile/time_edit.tpl index 472d0dd30..a93c0a60a 100644 --- a/WEB-INF/templates/mobile/time_edit.tpl +++ b/WEB-INF/templates/mobile/time_edit.tpl @@ -29,9 +29,12 @@ function confirmSave() { {if $user->isPluginEnabled('iv')} {/if} -{if ($custom_fields && $custom_fields->fields[0])} - - +{if $custom_fields && $custom_fields->timeFields} + {foreach $custom_fields->timeFields as $timeField} + + {assign var="control_name" value='time_field_'|cat:$timeField['id']} + + {/foreach} {/if} {if ($smarty.const.MODE_PROJECTS == $user->tracking_mode || $smarty.const.MODE_PROJECTS_AND_TASKS == $user->tracking_mode)} diff --git a/WEB-INF/templates/reports.tpl b/WEB-INF/templates/reports.tpl index 616282e29..f21150949 100644 --- a/WEB-INF/templates/reports.tpl +++ b/WEB-INF/templates/reports.tpl @@ -277,10 +277,6 @@ function handleCheckboxes() { @@ -398,7 +391,6 @@ function handleCheckboxes() {
 Anuko Time Tracker 1.19.7.5039 | Copyright © Anuko | +  Anuko Time Tracker 1.19.7.5040 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/mobile/time.tpl b/WEB-INF/templates/mobile/time.tpl index 38ec1914c..79398703b 100644 --- a/WEB-INF/templates/mobile/time.tpl +++ b/WEB-INF/templates/mobile/time.tpl @@ -60,9 +60,13 @@ {if $user->isPluginEnabled('iv')}
{$custom_fields->fields[0]['label']|escape}:
{$forms.timeRecordForm.cf_1.control}
{$timeField['label']|escape}{if $timeField['required']} (*){/if}:
{$forms.timeRecordForm.$control_name.control}
{$i18n.label.project}:
{$custom_fields->fields[0]['label']|escape}:
{$forms.timeRecordForm.cf_1.control}
{$timeField['label']|escape}{if $timeField['required']} (*){/if}:
{$forms.timeRecordForm.$control_name.control}
{$i18n.label.project}:
-{if $show_cf_1_dropdown} - - -{/if} {if $show_task} @@ -346,9 +342,6 @@ function handleCheckboxes() { {/if} {if $show_timesheet_checkbox} -{/if} -{if $show_cf_1_checkbox} - {/if}
{$i18n.label.option}
{$forms.reportForm.option.control}
{$i18n.label.task}
{$forms.reportForm.task.control}
{$i18n.form.reports.time_fields}
{$i18n.form.reports.user_fields}
{$custom_fields->fields[0]['label']|escape}{if $custom_fields->fields[0]['required']} (*){/if}:{$forms.timeRecordForm.cf_1.control}
{$timeField['label']|escape}{if $timeField['required']} (*){/if}:{$forms.timeRecordForm.$control_name.control}
{$i18n.label.client}{$custom_fields->fields[0]['label']|escape}{$i18n.label.project}{$record.client|escape}{$record.cf_1|escape}{$record.project|escape}
{$custom_fields->fields[0]['label']|escape}{if $custom_fields->fields[0]['required']} (*){/if}:{$forms.timeRecordForm.cf_1.control}{$timeField['label']|escape}{if $timeField['required']} (*){/if}:{$forms.timeRecordForm.$control_name.control}
{$custom_fields->fields[0]['label']|escape}{if $custom_fields->fields[0]['required']} (*){/if}:{$forms.weekTimeForm.cf_1.control}
{$timeField['label']|escape}{if $timeField['required']} (*){/if}:{$forms.weekTimeForm.$control_name.control}
-
 Anuko Time Tracker 1.19.7.5040 | Copyright © Anuko | +  Anuko Time Tracker 1.19.7.5041 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/tofile.php b/tofile.php index 9399c787c..324b852e3 100644 --- a/tofile.php +++ b/tofile.php @@ -121,6 +121,15 @@ if ($bean->getAttribute('chclient')) print "\t\n"; if ($bean->getAttribute('chproject')) print "\t\n"; if ($bean->getAttribute('chtask')) print "\t\n"; + // Time custom fields. + if ($custom_fields && $custom_fields->timeFields) { + foreach ($custom_fields->timeFields as $timeField) { + $field_name = 'time_field_'.$timeField['id']; + $checkbox_control_name = 'show_'.$field_name; + if ($bean->getAttribute($checkbox_control_name)) print "\t<$field_name>\n"; + } + } + // TODO: add user custom fields, too. if ($bean->getAttribute('chcf_1')) print "\t\n"; if ($bean->getAttribute('chstart')) print "\t\n"; if ($bean->getAttribute('chfinish')) print "\t\n"; From f6e11c1b80c34c2cdf95b1e3d6e400ae88848f3c Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 14 Jul 2019 16:59:58 +0000 Subject: [PATCH 030/877] Fixed exporting reports to xml and csv by adding multiple custom fields output. --- WEB-INF/templates/footer.tpl | 2 +- tofile.php | 48 +++++++++++++++++++++++++++++++----- 2 files changed, 43 insertions(+), 7 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 10ca1f60e..4dac71793 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.19.7.5041 | Copyright © Anuko | +  Anuko Time Tracker 1.19.7.5042 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/tofile.php b/tofile.php index 324b852e3..8b3ae2302 100644 --- a/tofile.php +++ b/tofile.php @@ -54,7 +54,7 @@ $type = $request->getParameter('type'); // Also, there are 2 variations of report: totals only, or normal. Totals only means that the report -// is grouped by (either date, user, client, project, task, or cf_1) and user only needs to see subtotals by group. +// is grouped by (either date, user, client, project, or task) and user only needs to see subtotals by group. $totals_only = $bean->getAttribute('chtotalsonly'); // Obtain items. @@ -117,7 +117,15 @@ print "\n"; print "\t\n"; - if ($user->can('view_reports') || $user->can('view_all_reports') || $user->isClient()) print "\t\n"; + if ($user->can('view_reports') || $user->can('view_all_reports') || $user->isClient()) print "\t\n"; + // User custom fields. + if ($custom_fields && $custom_fields->userFields) { + foreach ($custom_fields->userFields as $userField) { + $field_name = 'user_field_'.$userField['id']; + $checkbox_control_name = 'show_'.$field_name; + if ($bean->getAttribute($checkbox_control_name)) print "\t<$field_name>\n"; + } + } if ($bean->getAttribute('chclient')) print "\t\n"; if ($bean->getAttribute('chproject')) print "\t\n"; if ($bean->getAttribute('chtask')) print "\t\n"; @@ -129,8 +137,6 @@ if ($bean->getAttribute($checkbox_control_name)) print "\t<$field_name>\n"; } } - // TODO: add user custom fields, too. - if ($bean->getAttribute('chcf_1')) print "\t\n"; if ($bean->getAttribute('chstart')) print "\t\n"; if ($bean->getAttribute('chfinish')) print "\t\n"; if ($bean->getAttribute('chduration')) { @@ -207,10 +213,25 @@ // Normal report. Print headers. print '"'.$i18n->get('label.date').'"'; if ($user->can('view_reports') || $user->can('view_all_reports') || $user->isClient()) print ',"'.$i18n->get('label.user').'"'; + // User custom field labels. + if ($custom_fields && $custom_fields->userFields) { + foreach ($custom_fields->userFields as $userField) { + $field_name = 'user_field_'.$userField['id']; + $checkbox_control_name = 'show_'.$field_name; + if ($bean->getAttribute($checkbox_control_name)) print ',"'.str_replace('"','""',$userField['label']).'"'; + } + } if ($bean->getAttribute('chclient')) print ',"'.$i18n->get('label.client').'"'; if ($bean->getAttribute('chproject')) print ',"'.$i18n->get('label.project').'"'; if ($bean->getAttribute('chtask')) print ',"'.$i18n->get('label.task').'"'; - if ($bean->getAttribute('chcf_1')) print ',"'.$custom_fields->fields[0]['label'].'"'; + // Time custom field labels. + if ($custom_fields && $custom_fields->timeFields) { + foreach ($custom_fields->timeFields as $timeField) { + $field_name = 'time_field_'.$timeField['id']; + $checkbox_control_name = 'show_'.$field_name; + if ($bean->getAttribute($checkbox_control_name)) print ',"'.str_replace('"','""',$timeField['label']).'"'; + } + } if ($bean->getAttribute('chstart')) print ',"'.$i18n->get('label.start').'"'; if ($bean->getAttribute('chfinish')) print ',"'.$i18n->get('label.finish').'"'; if ($bean->getAttribute('chduration')) print ',"'.$i18n->get('label.duration').'"'; @@ -228,10 +249,25 @@ foreach ($items as $item) { print '"'.$item['date'].'"'; if ($user->can('view_reports') || $user->can('view_all_reports') || $user->isClient()) print ',"'.str_replace('"','""',$item['user']).'"'; + // User custom fields. + if ($custom_fields && $custom_fields->userFields) { + foreach ($custom_fields->userFields as $userField) { + $field_name = 'user_field_'.$userField['id']; + $checkbox_control_name = 'show_'.$field_name; + if ($bean->getAttribute($checkbox_control_name)) print ',"'.str_replace('"','""',$item[$field_name]).'"'; + } + } if ($bean->getAttribute('chclient')) print ',"'.str_replace('"','""',$item['client']).'"'; if ($bean->getAttribute('chproject')) print ',"'.str_replace('"','""',$item['project']).'"'; if ($bean->getAttribute('chtask')) print ',"'.str_replace('"','""',$item['task']).'"'; - if ($bean->getAttribute('chcf_1')) print ',"'.str_replace('"','""',$item['cf_1']).'"'; + // Time custom fields. + if ($custom_fields && $custom_fields->timeFields) { + foreach ($custom_fields->timeFields as $timeField) { + $field_name = 'time_field_'.$timeField['id']; + $checkbox_control_name = 'show_'.$field_name; + if ($bean->getAttribute($checkbox_control_name)) print ',"'.str_replace('"','""',$item[$field_name]).'"'; + } + } if ($bean->getAttribute('chstart')) print ',"'.$item['start'].'"'; if ($bean->getAttribute('chfinish')) print ',"'.$item['finish'].'"'; if ($bean->getAttribute('chduration')) { From 97d1cb16b9cb85c8e8f7e01456cdec08c50315a8 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 14 Jul 2019 17:24:17 +0000 Subject: [PATCH 031/877] Fixed exporting reports to pdf by adding multiple custom fields to output. --- WEB-INF/templates/footer.tpl | 2 +- topdf.php | 91 +++++++++++++++++++++++++++++++----- 2 files changed, 80 insertions(+), 13 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 4dac71793..393d367f3 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- "; $html .= ''; if ($user->can('view_reports') || $user->can('view_all_reports') || $user->isClient()) { $colspan++; $html .= ''; } + // User custom field labels. + if ($custom_fields && $custom_fields->userFields) { + foreach ($custom_fields->userFields as $userField) { + $field_name = 'user_field_'.$userField['id']; + $checkbox_control_name = 'show_'.$field_name; + if ($bean->getAttribute($checkbox_control_name)) { $colspan++; $html .= ''; } + } + } if ($bean->getAttribute('chclient')) { $colspan++; $html .= ''; } if ($bean->getAttribute('chproject')) { $colspan++; $html .= ''; } if ($bean->getAttribute('chtask')) { $colspan++; $html .= ''; } - if ($bean->getAttribute('chcf_1')) { $colspan++; $html .= ''; } + // Time custom field labels. + if ($custom_fields && $custom_fields->timeFields) { + foreach ($custom_fields->timeFields as $timeField) { + $field_name = 'time_field_'.$timeField['id']; + $checkbox_control_name = 'show_'.$field_name; + if ($bean->getAttribute($checkbox_control_name)) { $colspan++; $html .= ''; } + } + } if ($bean->getAttribute('chstart')) { $colspan++; $html .= "'; } if ($bean->getAttribute('chfinish')) { $colspan++; $html .= "'; } if ($bean->getAttribute('chduration')) { $colspan++; $html .= "'; } @@ -182,6 +197,14 @@ $html .= htmlspecialchars($subtotals[$prev_grouped_by]['user']); $html .= ''; } + // User custom fields. + if ($custom_fields && $custom_fields->userFields) { + foreach ($custom_fields->userFields as $userField) { + $field_name = 'user_field_'.$userField['id']; + $checkbox_control_name = 'show_'.$field_name; + if ($bean->getAttribute($checkbox_control_name)) $html .= ''; + } + } if ($bean->getAttribute('chclient')) { $html .= ''; } - if ($bean->getAttribute('chcf_1')) { - $html .= ''; + // Time custom fields. + if ($custom_fields && $custom_fields->timeFields) { + foreach ($custom_fields->timeFields as $timeField) { + $field_name = 'time_field_'.$timeField['id']; + $checkbox_control_name = 'show_'.$field_name; + if ($bean->getAttribute($checkbox_control_name)) $html .= ''; + } } if ($bean->getAttribute('chstart')) $html .= ''; if ($bean->getAttribute('chfinish')) $html .= ''; @@ -239,10 +265,25 @@ $html .= ''; $html .= ''; if ($user->can('view_reports') || $user->can('view_all_reports') || $user->isClient()) $html .= ''; + // User custom fields. + if ($custom_fields && $custom_fields->userFields) { + foreach ($custom_fields->userFields as $userField) { + $field_name = 'user_field_'.$userField['id']; + $checkbox_control_name = 'show_'.$field_name; + if ($bean->getAttribute($checkbox_control_name)) $html .= ''; + } + } if ($bean->getAttribute('chclient')) $html .= ''; if ($bean->getAttribute('chproject')) $html .= ''; if ($bean->getAttribute('chtask')) $html .= ''; - if ($bean->getAttribute('chcf_1')) $html .= ''; + // Time custom fields. + if ($custom_fields && $custom_fields->timeFields) { + foreach ($custom_fields->timeFields as $timeField) { + $field_name = 'time_field_'.$timeField['id']; + $checkbox_control_name = 'show_'.$field_name; + if ($bean->getAttribute($checkbox_control_name)) $html .= ''; + } + } if ($bean->getAttribute('chstart')) $html .= "'; if ($bean->getAttribute('chfinish')) $html .= "'; if ($bean->getAttribute('chduration')) $html .= "'; @@ -296,6 +337,14 @@ $html .= htmlspecialchars($subtotals[$prev_grouped_by]['user']); $html .= ''; } + // User custom fields. + if ($custom_fields && $custom_fields->userFields) { + foreach ($custom_fields->userFields as $userField) { + $field_name = 'user_field_'.$userField['id']; + $checkbox_control_name = 'show_'.$field_name; + if ($bean->getAttribute($checkbox_control_name)) $html .= ''; + } + } if ($bean->getAttribute('chclient')) { $html .= ''; } - if ($bean->getAttribute('chcf_1')) { - $html .= ''; + // Time custom fields. + if ($custom_fields && $custom_fields->timeFields) { + foreach ($custom_fields->timeFields as $timeField) { + $field_name = 'time_field_'.$timeField['id']; + $checkbox_control_name = 'show_'.$field_name; + if ($bean->getAttribute($checkbox_control_name)) $html .= ''; + } } if ($bean->getAttribute('chstart')) $html .= ''; if ($bean->getAttribute('chfinish')) $html .= ''; @@ -342,10 +394,25 @@ $html .= ''; $html .= ''; if ($user->can('view_reports') || $user->can('view_all_reports') || $user->isClient()) $html .= ''; + // User custom fields. + if ($custom_fields && $custom_fields->userFields) { + foreach ($custom_fields->userFields as $userField) { + $field_name = 'user_field_'.$userField['id']; + $checkbox_control_name = 'show_'.$field_name; + if ($bean->getAttribute($checkbox_control_name)) $html .= ''; + } + } if ($bean->getAttribute('chclient')) $html .= ''; if ($bean->getAttribute('chproject')) $html .= ''; if ($bean->getAttribute('chtask')) $html .= ''; - if ($bean->getAttribute('chcf_1')) $html .= ''; + // Time custom fields. + if ($custom_fields && $custom_fields->timeFields) { + foreach ($custom_fields->timeFields as $timeField) { + $field_name = 'time_field_'.$timeField['id']; + $checkbox_control_name = 'show_'.$field_name; + if ($bean->getAttribute($checkbox_control_name)) $html .= ''; + } + } if ($bean->getAttribute('chstart')) $html .= ''; if ($bean->getAttribute('chfinish')) $html .= ''; if ($bean->getAttribute('chduration')) $html .= "'; From f9d19b18d10d5945d25a392dffd0d3e1fe8c8566 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 21 Jul 2019 13:50:57 +0000 Subject: [PATCH 032/877] Made progress on including custom field settings in fav reports. --- WEB-INF/lib/ttCronJobHelper.class.php | 1 - WEB-INF/lib/ttFavReportHelper.class.php | 186 ++++++++++++++++++------ WEB-INF/templates/footer.tpl | 2 +- 3 files changed, 146 insertions(+), 43 deletions(-) diff --git a/WEB-INF/lib/ttCronJobHelper.class.php b/WEB-INF/lib/ttCronJobHelper.class.php index 5dcc0b69b..8c44756c7 100644 --- a/WEB-INF/lib/ttCronJobHelper.class.php +++ b/WEB-INF/lib/ttCronJobHelper.class.php @@ -103,7 +103,6 @@ private function getReportOptions($id) { // Drop things we don't need. unset($val['id']); - unset($val['report_spec']); unset($val['status']); return $val; diff --git a/WEB-INF/lib/ttFavReportHelper.class.php b/WEB-INF/lib/ttFavReportHelper.class.php index a3e130c30..6ad729f0d 100644 --- a/WEB-INF/lib/ttFavReportHelper.class.php +++ b/WEB-INF/lib/ttFavReportHelper.class.php @@ -120,15 +120,16 @@ static function insertReport($fields) { $org_id = $user->org_id; $sql = "insert into tt_fav_reports". - " (name, user_id, group_id, org_id, client_id, cf_1_option_id, project_id, task_id,". + " (name, user_id, group_id, org_id, report_spec, client_id, project_id, task_id,". " billable, approved, invoice, timesheet, paid_status, users, period, period_start,". " period_end, show_client, show_invoice, show_paid, show_ip,". " show_project, show_timesheet, show_start, show_duration, show_cost,". - " show_task, show_end, show_note, show_approved, show_custom_field_1, show_work_units,". + " show_task, show_end, show_note, show_approved, show_work_units,". " group_by1, group_by2, group_by3, show_totals_only)". " values(". $mdb2->quote($fields['name']).", $user_id, $group_id, $org_id, ". - $mdb2->quote($fields['client']).", ".$mdb2->quote($fields['option']).", ". + $mdb2->quote($fields['report_spec']).", ". + $mdb2->quote($fields['client']).", ". $mdb2->quote($fields['project']).", ".$mdb2->quote($fields['task']).", ". $mdb2->quote($fields['billable']).", ".$mdb2->quote($fields['approved']).", ". $mdb2->quote($fields['invoice']).", ".$mdb2->quote($fields['timesheet']).", ". @@ -137,7 +138,7 @@ static function insertReport($fields) { $mdb2->quote($fields['from']).", ".$mdb2->quote($fields['to']).", ". $fields['chclient'].", ".$fields['chinvoice'].", ".$fields['chpaid'].", ".$fields['chip'].", ". $fields['chproject'].", ".$fields['chtimesheet'].", ".$fields['chstart'].", ".$fields['chduration'].", ".$fields['chcost'].", ". - $fields['chtask'].", ".$fields['chfinish'].", ".$fields['chnote'].", ".$fields['chapproved'].", ".$fields['chcf_1'].", ".$fields['chunits'].", ". + $fields['chtask'].", ".$fields['chfinish'].", ".$fields['chnote'].", ".$fields['chapproved'].", ".$fields['chunits'].", ". $mdb2->quote($fields['group_by1']).", ".$mdb2->quote($fields['group_by2']).", ". $mdb2->quote($fields['group_by3']).", ".$fields['chtotalsonly'].")"; $affected = $mdb2->exec($sql); @@ -159,8 +160,8 @@ static function updateReport($fields) { $sql = "update tt_fav_reports set ". "name = ".$mdb2->quote($fields['name']).", ". + "report_spec = ".$mdb2->quote($fields['report_spec']).", ". "client_id = ".$mdb2->quote($fields['client']).", ". - "cf_1_option_id = ".$mdb2->quote($fields['option']).", ". "project_id = ".$mdb2->quote($fields['project']).", ". "task_id = ".$mdb2->quote($fields['task']).", ". "billable = ".$mdb2->quote($fields['billable']).", ". @@ -185,7 +186,6 @@ static function updateReport($fields) { "show_end = ".$fields['chfinish'].", ". "show_note = ".$fields['chnote'].", ". "show_approved = ".$fields['chapproved'].", ". - "show_custom_field_1 = ".$fields['chcf_1'].", ". "show_work_units = ".$fields['chunits'].", ". "group_by1 = ".$mdb2->quote($fields['group_by1']).", ". "group_by2 = ".$mdb2->quote($fields['group_by2']).", ". @@ -220,7 +220,6 @@ static function saveReport($bean) { if (!$bean->getAttribute('chapproved')) $bean->setAttribute('chapproved', 0); if (!$bean->getAttribute('chpaid')) $bean->setAttribute('chpaid', 0); - if (!$bean->getAttribute('chcf_1')) $bean->setAttribute('chcf_1', 0); if (!$bean->getAttribute('chunits')) $bean->setAttribute('chunits', 0); if (!$bean->getAttribute('chinvoice')) $bean->setAttribute('chinvoice', 0); @@ -247,6 +246,7 @@ static function saveReport($bean) { $fields = array( 'name'=>$bean->getAttribute('new_fav_report'), + 'report_spec'=>ttFavReportHelper::makeReportSpec($bean), 'client'=>$bean->getAttribute('client'), 'option'=>$bean->getAttribute('option'), 'project'=>$bean->getAttribute('project'), @@ -272,7 +272,6 @@ static function saveReport($bean) { 'chip'=>$bean->getAttribute('chip'), 'chapproved'=>$bean->getAttribute('chapproved'), 'chpaid'=>$bean->getAttribute('chpaid'), - 'chcf_1'=>$bean->getAttribute('chcf_1'), 'chunits'=>$bean->getAttribute('chunits'), 'chinvoice'=>$bean->getAttribute('chinvoice'), 'group_by1'=>$bean->getAttribute('group_by1'), @@ -316,10 +315,42 @@ static function deleteReport($id) { // loadReport - loads report options from database into a bean. static function loadReport(&$bean) { global $user; + // Custom fields. + if ($user->isPluginEnabled('cf')) { + global $custom_fields; + if (!$custom_fields) $custom_fields = new CustomFields(); + } $user_id = $user->getUser(); $val = ttFavReportHelper::get($bean->getAttribute('favorite_report')); if ($val) { + // Custom field settings. + if ($val['report_spec']) { + $report_spec = $val['report_spec']; + // Time custom field settings. + if ($custom_fields && $custom_fields->timeFields) { + foreach ($custom_fields->timeFields as $timeField) { + $field_name = 'time_field_'.$timeField['id']; + $checkbox_field_name = 'show_'.$field_name; + $field_value = ttFavReportHelper::getFieldSettingFromReportSpec($field_name, $report_spec); + $bean->setAttribute($field_name, $field_value); + $checkbox_value = ttFavReportHelper::getFieldSettingFromReportSpec($checkbox_field_name, $report_spec); + $bean->setAttribute($checkbox_field_name, $checkbox_value); + } + } + // User custom field settings. + if ($custom_fields && $custom_fields->userFields) { + foreach ($custom_fields->userFields as $userField) { + $field_name = 'user_field_'.$userField['id']; + $checkbox_field_name = 'show_'.$field_name; + $field_value = ttFavReportHelper::getFieldSettingFromReportSpec($field_name, $report_spec); + $bean->setAttribute($field_name, $field_value); + $checkbox_value = ttFavReportHelper::getFieldSettingFromReportSpec($checkbox_field_name, $report_spec); + $bean->setAttribute($checkbox_field_name, $checkbox_value); + } + } + } + $bean->setAttribute('client', $val['client_id']); $bean->setAttribute('option', $val['cf_1_option_id']); $bean->setAttribute('project', $val['project_id']); @@ -353,7 +384,6 @@ static function loadReport(&$bean) { $bean->setAttribute('chfinish', $val['show_end']); $bean->setAttribute('chnote', $val['show_note']); $bean->setAttribute('chapproved', $val['show_approved']); - $bean->setAttribute('chcf_1', $val['show_custom_field_1']); $bean->setAttribute('chunits', $val['show_work_units']); $bean->setAttribute('group_by1', $val['group_by1']); $bean->setAttribute('group_by2', $val['group_by2']); @@ -363,37 +393,54 @@ static function loadReport(&$bean) { } else { $attrs = $bean->getAttributes(); $attrs = array_merge($attrs, array( - 'client'=>'', - 'option'=>'', - 'project'=>'', - 'task'=>'', - 'include_records'=>'', - 'approved'=>'', - 'paid_status'=>'', - 'invoice'=>'', - 'timesheet'=>'', - 'users'=>$user_id, - 'period'=>'', - 'chclient'=>'1', - 'chstart'=>'1', - 'chfinish'=>'1', - 'chduration'=>'1', - 'chproject'=>'1', - 'chtask'=>'1', - 'chnote'=>'1', - 'chcost'=>'', - 'chtimesheet'=>'', - 'chip'=>'', - 'chapproved'=>'', - 'chpaid'=>'', - 'chcf_1'=>'', - 'chunits'=>'', - 'chinvoice'=>'', - 'group_by1'=>'', - 'group_by2'=>'', - 'group_by3'=>'', - 'chtotalsonly'=>'', - 'new_fav_report'=>'')); + 'client' => null, + 'project'=> null, + 'task' => null, + 'include_records' => null, + 'approved' => null, + 'paid_status' => null, + 'invoice' => null, + 'timesheet' => null, + 'users' => $user_id, + 'period' => null, + 'chclient' => '1', + 'chstart' => '1', + 'chfinish' => '1', + 'chduration' => '1', + 'chproject' => '1', + 'chtask' => '1', + 'chnote' => '1', + 'chcost' => null, + 'chtimesheet' => null, + 'chip' => null, + 'chapproved' => null, + 'chpaid' => null, + 'chunits' => null, + 'chinvoice' => null, + 'group_by1' => null, + 'group_by2' => null, + 'group_by3' => null, + 'chtotalsonly' => null, + 'new_fav_report' => null)); + // Time custom fields. + if ($custom_fields && $custom_fields->timeFields) { + foreach ($custom_fields->timeFields as $timeField) { + $field_name = 'time_field_'.$timeField['id']; + $checkbox_field_name = 'show_'.$field_name; + $custom_field_attrs[$field_name] = null; + $custom_field_attrs[$checkbox_field_name] = null; + } + } + // User custom fields. + if ($custom_fields && $custom_fields->userFields) { + foreach ($custom_fields->userFields as $userField) { + $field_name = 'user_field_'.$userField['id']; + $checkbox_field_name = 'show_'.$field_name; + $custom_field_attrs[$field_name] = null; + $custom_field_attrs[$checkbox_field_name] = null; + } + } + $attrs = array_merge($attrs, $custom_field_attrs); $bean->setAttributes($attrs); } } @@ -413,7 +460,6 @@ static function getReportOptions($id) { $options = $db_fields; // For now, use db field names as options. // Drop things we don't need in reports. unset($options['id']); - unset($options['report_spec']); // Currently not used. unset($options['status']); // Note: special handling for NULL users field is done in cron.php @@ -470,4 +516,62 @@ static function adjustOptions($options) { return $options; } + + // makeReportSpec - prepares a value for report_spec field. + // + // Currently, only custom field settings go there. + // Format: + // time_field_25:117,show_time_field_25:1,time_field_28:qwerty,show_time_field_28:0 + static function makeReportSpec($bean) { + global $user; + + if ($user->isPluginEnabled('cf')) { + global $custom_fields; + if (!$custom_fields) $custom_fields = new CustomFields(); + } + + // Add time custom field settings. + if ($custom_fields && $custom_fields->timeFields) { + foreach ($custom_fields->timeFields as $timeField) { + $field_name = 'time_field_'.$timeField['id']; + $field_value = str_replace(',',',',$bean->getAttribute($field_name)); + $checkbox_field_name = 'show_'.$field_name; + $checkbox_field_value = (int) $bean->getAttribute($checkbox_field_name); + if ($field_value) $reportSpecArray[] = $field_name.':'.$field_value; + if ($checkbox_field_value) $reportSpecArray[] = $checkbox_field_name.':1'; + } + } + + // Add user custom field settings. + if ($custom_fields && $custom_fields->userFields) { + foreach ($custom_fields->userFields as $userField) { + $field_name = 'user_field_'.$userField['id']; + $field_value = str_replace(',',',',$bean->getAttribute($field_name)); + $checkbox_field_name = 'show_'.$field_name; + $checkbox_field_value = (int) $bean->getAttribute($checkbox_field_name); + if ($field_value) $reportSpecArray[] = $field_name.':'.$field_value; + if ($checkbox_field_value) $reportSpecArray[] = $checkbox_field_name.':1'; + } + } + + $reportSpec = implode(',', $reportSpecArray); + return $reportSpec; + } + + // getFieldSettingFromReportSpec - obtains custom field setting from report_spec string. + // See makeReportSpec above. + // + // $fieldKey is something like "time_field_26", "show_time_field_26", or + // "user_field_765", "show_user_field_765". + static function getFieldSettingFromReportSpec($fieldKey, $report_spec) { + $reportSpecArray = explode(',', $report_spec); + foreach ($reportSpecArray as $fieldSetting) { + if (ttStartsWith($fieldSetting, $fieldKey.':')) { + $value = substr($fieldSetting, strlen($fieldKey)+1); + $value = str_replace(',',',',$value); // Restore commas. + return $value; + } + } + return null; // Not found. + } } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 393d367f3..775db9c49 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.19.7.5042 | Copyright © Anuko | +  Anuko Time Tracker 1.19.7.5043 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/topdf.php b/topdf.php index c9120fcf7..337a05a41 100644 --- a/topdf.php +++ b/topdf.php @@ -64,7 +64,7 @@ $show_note_row = $bean->getAttribute('chnote') && $config->getDefinedValue('report_note_on_separate_row'); // There are 2 variations of report: totals only, or normal. Totals only means that the report -// is grouped by either date, user, client, project, task or cf_1 and user only needs to see subtotals by group. +// is grouped by either date, user, client, project, or task and user only needs to see subtotals by group. $totals_only = ($bean->getAttribute('chtotalsonly') == '1'); // Obtain items for report. @@ -151,10 +151,25 @@ $html .= "
'.$i18n->get('label.date').''.$i18n->get('label.user').''.htmlspecialchars($userField['label']).''.$i18n->get('label.client').''.$i18n->get('label.project').''.$i18n->get('label.task').''.htmlspecialchars($custom_fields->fields[0]['label']).''.htmlspecialchars($timeField['label']).'".$i18n->get('label.start').'".$i18n->get('label.finish').'".$i18n->get('label.duration').''; $html .= htmlspecialchars($subtotals[$prev_grouped_by]['client']); @@ -197,10 +220,13 @@ $html .= htmlspecialchars($subtotals[$prev_grouped_by]['task']); $html .= ''; - $html .= htmlspecialchars($subtotals[$prev_grouped_by]['cf_1']); - $html .= '
'.$item['date'].''.htmlspecialchars($item['user']).''.htmlspecialchars($item[$field_name]).''.htmlspecialchars($item['client']).''.htmlspecialchars($item['project']).''.htmlspecialchars($item['task']).''.htmlspecialchars($item['cf_1']).''.htmlspecialchars($item[$field_name]).'".$item['start'].'".$item['finish'].'".$item['duration'].''; $html .= htmlspecialchars($subtotals[$prev_grouped_by]['client']); @@ -311,10 +360,13 @@ $html .= htmlspecialchars($subtotals[$prev_grouped_by]['task']); $html .= ''; - $html .= htmlspecialchars($subtotals[$prev_grouped_by]['cf_1']); - $html .= '
'.$i18n->get('label.total').'".$totals['time'].'
- '; if ($canViewReports || $isClient) $body .= ''; + // User custom fields. + if ($custom_fields && $custom_fields->userFields) { + foreach ($custom_fields->userFields as $userField) { + $field_name = 'user_field_'.$userField['id']; + $checkbox_control_name = 'show_'.$field_name; + if ($options[$checkbox_control_name]) $body .= ''; + } + } if ($options['show_client']) $body .= ''; if ($options['show_project']) $body .= ''; if ($options['show_task']) $body .= ''; - if ($options['show_custom_field_1']) - $body .= ''; + // Time custom fields. + if ($custom_fields && $custom_fields->timeFields) { + foreach ($custom_fields->timeFields as $timeField) { + $field_name = 'time_field_'.$timeField['id']; + $checkbox_control_name = 'show_'.$field_name; + if ($options[$checkbox_control_name]) $body .= ''; + } + } if ($options['show_start']) $body .= ''; if ($options['show_end']) @@ -1184,10 +1213,25 @@ static function prepareReportBody($options, $comment = null) $body .= ''; $subtotal_name = htmlspecialchars($subtotals[$prev_grouped_by]['name']); if ($canViewReports || $isClient) $body .= ''; + // User custom fields. + if ($custom_fields && $custom_fields->userFields) { + foreach ($custom_fields->userFields as $userField) { + $field_name = 'user_field_'.$userField['id']; + $checkbox_control_name = 'show_'.$field_name; + if ($options[$checkbox_control_name]) $body .= ''; + } + } if ($options['show_client']) $body .= ''; if ($options['show_project']) $body .= ''; if ($options['show_task']) $body .= ''; - if ($options['show_custom_field_1']) $body .= ''; + // Time custom fields. + if ($custom_fields && $custom_fields->timeFields) { + foreach ($custom_fields->timeFields as $timeField) { + $field_name = 'time_field_'.$timeField['id']; + $checkbox_control_name = 'show_'.$field_name; + if ($options[$checkbox_control_name]) $body .= ''; + } + } if ($options['show_start']) $body .= ''; if ($options['show_end']) $body .= ''; if ($options['show_duration']) $body .= ''; @@ -1216,14 +1260,28 @@ static function prepareReportBody($options, $comment = null) $body .= ''; if ($canViewReports || $isClient) $body .= ''; + // User custom fields. + if ($custom_fields && $custom_fields->userFields) { + foreach ($custom_fields->userFields as $userField) { + $field_name = 'user_field_'.$userField['id']; + $checkbox_control_name = 'show_'.$field_name; + if ($options[$checkbox_control_name]) $body .= ''; + } + } if ($options['show_client']) $body .= ''; if ($options['show_project']) $body .= ''; if ($options['show_task']) $body .= ''; - if ($options['show_custom_field_1']) - $body .= ''; + // Time custom fields. + if ($custom_fields && $custom_fields->timeFields) { + foreach ($custom_fields->timeFields as $timeField) { + $field_name = 'time_field_'.$timeField['id']; + $checkbox_control_name = 'show_'.$field_name; + if ($options[$checkbox_control_name]) $body .= ''; + } + } if ($options['show_start']) $body .= ''; if ($options['show_end']) @@ -1274,9 +1332,25 @@ static function prepareReportBody($options, $comment = null) $body .= ''; $subtotal_name = htmlspecialchars($subtotals[$cur_grouped_by]['name']); if ($canViewReports || $isClient) $body .= ''; + // User custom fields. + if ($custom_fields && $custom_fields->userFields) { + foreach ($custom_fields->userFields as $userField) { + $field_name = 'user_field_'.$userField['id']; + $checkbox_control_name = 'show_'.$field_name; + if ($options[$checkbox_control_name]) $body .= ''; + } + } if ($options['show_client']) $body .= ''; if ($options['show_project']) $body .= ''; if ($options['show_task']) $body .= ''; + // Time custom fields. + if ($custom_fields && $custom_fields->timeFields) { + foreach ($custom_fields->timeFields as $timeField) { + $field_name = 'time_field_'.$timeField['id']; + $checkbox_control_name = 'show_'.$field_name; + if ($options[$checkbox_control_name]) $body .= ''; + } + } if ($options['show_custom_field_1']) $body .= ''; if ($options['show_start']) $body .= ''; if ($options['show_end']) $body .= ''; @@ -1301,9 +1375,25 @@ static function prepareReportBody($options, $comment = null) $body .= ''; $body .= ''; if ($canViewReports || $isClient) $body .= ''; + // User custom fields. + if ($custom_fields && $custom_fields->userFields) { + foreach ($custom_fields->userFields as $userField) { + $field_name = 'user_field_'.$userField['id']; + $checkbox_control_name = 'show_'.$field_name; + if ($options[$checkbox_control_name]) $body .= ''; + } + } if ($options['show_client']) $body .= ''; if ($options['show_project']) $body .= ''; if ($options['show_task']) $body .= ''; + // Time custom fields. + if ($custom_fields && $custom_fields->timeFields) { + foreach ($custom_fields->timeFields as $timeField) { + $field_name = 'time_field_'.$timeField['id']; + $checkbox_control_name = 'show_'.$field_name; + if ($options[$checkbox_control_name]) $body .= ''; + } + } if ($options['show_custom_field_1']) $body .= ''; if ($options['show_start']) $body .= ''; if ($options['show_end']) $body .= ''; diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 775db9c49..ba4178b53 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.19.7.5043 | Copyright © Anuko | +  Anuko Time Tracker 1.19.7.5044 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 86886803a8ce268cbe64a1937c05df79d645d9ec Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 21 Jul 2019 15:10:59 +0000 Subject: [PATCH 033/877] Fixed emailed reports to include multiple custom fields. --- WEB-INF/lib/ttFavReportHelper.class.php | 1 + WEB-INF/lib/ttReportHelper.class.php | 102 ++++++++++++++++++++++-- WEB-INF/templates/footer.tpl | 2 +- 3 files changed, 98 insertions(+), 7 deletions(-) diff --git a/WEB-INF/lib/ttFavReportHelper.class.php b/WEB-INF/lib/ttFavReportHelper.class.php index 6ad729f0d..d118edbbb 100644 --- a/WEB-INF/lib/ttFavReportHelper.class.php +++ b/WEB-INF/lib/ttFavReportHelper.class.php @@ -417,6 +417,7 @@ static function loadReport(&$bean) { 'chpaid' => null, 'chunits' => null, 'chinvoice' => null, + 'chfiles' => '1', 'group_by1' => null, 'group_by2' => null, 'group_by3' => null, diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index f0ce800b1..a9831f307 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -1036,10 +1036,25 @@ static function prepareReportBody($options, $comment = null) // Determine column span for note field. $colspan = 1; if ($user->can('view_reports') || $user->can('view_all_reports') || $user->isClient()) $colspan++; + // User custom fields. + if ($custom_fields && $custom_fields->userFields) { + foreach ($custom_fields->userFields as $userField) { + $field_name = 'user_field_'.$userField['id']; + $checkbox_control_name = 'show_'.$field_name; + if ($options[$checkbox_control_name]) $colspan++; + } + } if ($options['show_client']) $colspan++; if ($options['show_project']) $colspan++; if ($options['show_task']) $colspan++; - if ($options['show_custom_field_1']) $colspan++; + // Time custom fields. + if ($custom_fields && $custom_fields->timeFields) { + foreach ($custom_fields->timeFields as $timeField) { + $field_name = 'time_field_'.$timeField['id']; + $checkbox_control_name = 'show_'.$field_name; + if ($options[$checkbox_control_name]) $colspan++; + } + } if ($options['show_start']) $colspan++; if ($options['show_end']) $colspan++; if ($options['show_duration']) $colspan++; @@ -1128,14 +1143,28 @@ static function prepareReportBody($options, $comment = null) $body .= ''.$i18n->get('label.date').''.$i18n->get('label.user').''.htmlspecialchars($userField['label']).''.$i18n->get('label.client').''.$i18n->get('label.project').''.$i18n->get('label.task').''.htmlspecialchars($custom_fields->fields[0]['label']).''.htmlspecialchars($timeField['label']).''.$i18n->get('label.start').''.$i18n->get('label.subtotal').''.$subtotals[$prev_grouped_by]['user'].''.$subtotals[$prev_grouped_by]['client'].''.$subtotals[$prev_grouped_by]['project'].''.$subtotals[$prev_grouped_by]['task'].''.$subtotals[$prev_grouped_by]['cf_1'].''.$subtotals[$prev_grouped_by]['time'].''.$record['date'].''.htmlspecialchars($record['user']).''.htmlspecialchars($record[$field_name]).''.htmlspecialchars($record['client']).''.htmlspecialchars($record['project']).''.htmlspecialchars($record['task']).''.htmlspecialchars($record['cf_1']).''.htmlspecialchars($record[$field_name]).''.$record['start'].''.$i18n->get('label.subtotal').''.$subtotals[$prev_grouped_by]['user'].''.$subtotals[$prev_grouped_by]['client'].''.$subtotals[$prev_grouped_by]['project'].''.$subtotals[$prev_grouped_by]['task'].''.$subtotals[$prev_grouped_by]['cf_1'].'
'.$i18n->get('label.total').'
-
 Anuko Time Tracker 1.19.7.5044 | Copyright © Anuko | +  Anuko Time Tracker 1.19.7.5045 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From b029d2cfa6611d060549f9a4cefd75a84f2b80f2 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 21 Jul 2019 15:59:54 +0000 Subject: [PATCH 034/877] Fixed emailed reports by cron by including multiple custom fields. --- WEB-INF/lib/ttFavReportHelper.class.php | 29 +++++++++++++++++++++++++ WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/WEB-INF/lib/ttFavReportHelper.class.php b/WEB-INF/lib/ttFavReportHelper.class.php index d118edbbb..05b863fba 100644 --- a/WEB-INF/lib/ttFavReportHelper.class.php +++ b/WEB-INF/lib/ttFavReportHelper.class.php @@ -515,6 +515,35 @@ static function adjustOptions($options) { if ($user->isPluginEnabled('ap') && $user->isClient() && !$user->can('view_client_unapproved')) $options['approved'] = 1; // Restrict clients to approved records only. + // Prepare custom field options. + if ($user->isPluginEnabled('cf') && $options['report_spec']) { + $custom_fields = new CustomFields(); + $report_spec = $options['report_spec']; + // Time fields. + if ($custom_fields && $custom_fields->timeFields) { + foreach ($custom_fields->timeFields as $timeField) { + $field_name = 'time_field_'.$timeField['id']; + $checkbox_field_name = 'show_'.$field_name; + $field_value = ttFavReportHelper::getFieldSettingFromReportSpec($field_name, $report_spec); + $options[$field_name] = $field_value; + $checkbox_value = ttFavReportHelper::getFieldSettingFromReportSpec($checkbox_field_name, $report_spec); + $options[$checkbox_field_name] = $checkbox_value; + } + } + // User fields. + if ($custom_fields && $custom_fields->userFields) { + foreach ($custom_fields->userFields as $userField) { + $field_name = 'user_field_'.$userField['id']; + $checkbox_field_name = 'show_'.$field_name; + $field_value = ttFavReportHelper::getFieldSettingFromReportSpec($field_name, $report_spec); + $options[$field_name] = $field_value; + $checkbox_value = ttFavReportHelper::getFieldSettingFromReportSpec($checkbox_field_name, $report_spec); + $options[$checkbox_field_name] = $checkbox_value; + } + } + // TODO: add project fields here. + } + return $options; } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index ba4178b53..f59e89fb3 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.19.7.5045 | Copyright © Anuko | +  Anuko Time Tracker 1.19.7.5046 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 52c1eec33de6aac3771283b2055ac9067dead992 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 21 Aug 2019 19:56:31 +0000 Subject: [PATCH 035/877] Fixed export of large tables by operating on smaller chunks at a time. --- WEB-INF/lib/ttGroupExportHelper.class.php | 68 +++++++++++++++-------- WEB-INF/lib/ttReportHelper.class.php | 1 + WEB-INF/lib/ttTeamHelper.class.php | 34 ------------ WEB-INF/templates/footer.tpl | 2 +- reports.php | 16 ++++++ 5 files changed, 63 insertions(+), 58 deletions(-) diff --git a/WEB-INF/lib/ttGroupExportHelper.class.php b/WEB-INF/lib/ttGroupExportHelper.class.php index cd38de9d7..b76c790fc 100644 --- a/WEB-INF/lib/ttGroupExportHelper.class.php +++ b/WEB-INF/lib/ttGroupExportHelper.class.php @@ -105,7 +105,6 @@ function getRecordsFromTable($table_name) { global $user; $mdb2 = getConnection(); - $result = array(); $sql = "select * from $table_name where group_id = $this->group_id and org_id = $user->org_id"; $res = $mdb2->query($sql); $result = array(); @@ -118,6 +117,24 @@ function getRecordsFromTable($table_name) { return false; } + // getRecordsChunkFromTable - obtains a subset of records from a given table for a group. + // It is a workaround for out of memory condition when a table such as tt_log becomes too large + // and we can no longer use the getRecordsFromTable. + function getRecordsChunkFromTable($table_name, $limit, $offset) { + global $user; + $mdb2 = getConnection(); + + $sql = "select * from $table_name where group_id = $this->group_id and org_id = $user->org_id order by id limit $limit offset $offset"; + $res = $mdb2->query($sql); + $result = false; + if (!is_a($res, 'PEAR_Error')) { + while ($val = $res->fetchRow()) { + $result[] = $val; + } + } + return $result; + } + // writeData writes group data into file. function writeData() { @@ -367,14 +384,12 @@ function writeData() { } // Write time log entries and build logMap at the same time. - // TODO: big data sets get us out of memory error. - // We need to optimize this by working on smaller result sets at a time. - // tt_log is one potentially large table, but so may be others. - // Refactor this during next round of work here. - $records = $this->getRecordsFromTable('tt_log'); - if (count($records) > 0) { - fwrite($this->file, $this->indentation." \n"); - $key = 0; + // We use getRecordsChunkFromTable here to avoid out of memory condition for large tables. + fwrite($this->file, $this->indentation." \n"); + $offset = 0; + $limit = 1000; + $key = 0; + while ($records = $this->getRecordsChunkFromTable('tt_log', $limit, $offset)) { foreach ($records as $record) { $key++; $this->logMap[$record['id']] = $key; @@ -396,10 +411,11 @@ function writeData() { $log_part .= ">\n"; fwrite($this->file, $log_part); } - fwrite($this->file, $this->indentation." \n"); unset($records); unset($log_part); - } + $offset += $limit; + } + fwrite($this->file, $this->indentation." \n"); // Write custom fields. if (count($custom_fields) > 0) { @@ -435,9 +451,11 @@ function writeData() { } // Write custom field log. - $custom_field_log = ttTeamHelper::getCustomFieldLog($this->group_id); - if (count($custom_field_log) > 0) { - fwrite($this->file, $this->indentation." \n"); + // We use getRecordsChunkFromTable here to avoid out of memory condition for large tables. + fwrite($this->file, $this->indentation." \n"); + $offset = 0; + $limit = 1000; + while ($custom_field_log = $this->getRecordsChunkFromTable('tt_custom_field_log', $limit, $offset)) { foreach ($custom_field_log as $entry) { $custom_field_log_part = $this->indentation.' '."logMap[$entry['log_id']]."\""; $custom_field_log_part .= " field_id=\"".$this->customFieldMap[$entry['field_id']]."\""; @@ -447,15 +465,18 @@ function writeData() { $custom_field_log_part .= ">\n"; fwrite($this->file, $custom_field_log_part); } - fwrite($this->file, $this->indentation." \n"); unset($custom_field_log); unset($custom_field_log_part); - } - - // Write expense items. - $expense_items = ttTeamHelper::getExpenseItems($this->group_id); - if (count($expense_items) > 0) { - fwrite($this->file, $this->indentation." \n"); + $offset += $limit; + } + fwrite($this->file, $this->indentation." \n"); + + // Write expense otems. + // We use getRecordsChunkFromTable here to avoid out of memory condition for large tables. + fwrite($this->file, $this->indentation." \n"); + $offset = 0; + $limit = 1000; + while ($expense_items = $this->getRecordsChunkFromTable('tt_expense_items', $limit, $offset)) { foreach ($expense_items as $expense_item) { $expense_item_part = $this->indentation.' '."userMap[$expense_item['user_id']]."\""; @@ -470,10 +491,11 @@ function writeData() { $expense_item_part .= ">\n"; fwrite($this->file, $expense_item_part); } - fwrite($this->file, $this->indentation." \n"); unset($expense_items); unset($expense_item_part); - } + $offset += $limit; + } + fwrite($this->file, $this->indentation." getRecordsFromTable('tt_predefined_expenses'); diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index a9831f307..8ba393b25 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -1651,6 +1651,7 @@ static function makeGroupByPart($options) { $group_by2 = $options['group_by2']; $group_by3 = $options['group_by3']; + // TODO: redo this using the if instead so that we can include custom fields properly. switch ($group_by1) { case 'date': $group_by_parts .= ', l.date'; diff --git a/WEB-INF/lib/ttTeamHelper.class.php b/WEB-INF/lib/ttTeamHelper.class.php index b94f6434c..651226e49 100644 --- a/WEB-INF/lib/ttTeamHelper.class.php +++ b/WEB-INF/lib/ttTeamHelper.class.php @@ -308,23 +308,6 @@ static function getAllCustomFieldOptions($group_id) { return false; } - // The getCustomFieldLog obtains all custom field log entries for a group. - static function getCustomFieldLog($group_id) { - $mdb2 = getConnection(); - - $sql = "select * from tt_custom_field_log where field_id in (select id from tt_custom_fields where group_id = $group_id) order by id"; - - $res = $mdb2->query($sql); - $result = array(); - if (!is_a($res, 'PEAR_Error')) { - while ($val = $res->fetchRow()) { - $result[] = $val; - } - return $result; - } - return false; - } - // getFavReports - obtains all favorite reports for all users in a group. static function getFavReports($group_id) { $mdb2 = getConnection(); @@ -342,23 +325,6 @@ static function getFavReports($group_id) { return false; } - // getExpenseItems - obtains all expense items for all users in a group. - static function getExpenseItems($group_id) { - $mdb2 = getConnection(); - - $result = array(); - $sql = "select * from tt_expense_items where user_id in (select id from tt_users where group_id = $group_id)"; - $res = $mdb2->query($sql); - $result = array(); - if (!is_a($res, 'PEAR_Error')) { - while ($val = $res->fetchRow()) { - $result[] = $val; - } - return $result; - } - return false; - } - // getMonthlyQuotas - obtains monthly quotas for a group. static function getMonthlyQuotas($group_id) { $mdb2 = getConnection(); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index f59e89fb3..b74764280 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.19.7.5046 | Copyright © Anuko | +  Anuko Time Tracker 1.19.7.5047 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/reports.php b/reports.php index 0f0cb11ab..66a6608b4 100644 --- a/reports.php +++ b/reports.php @@ -356,6 +356,22 @@ $group_by_options['project'] = $i18n->get('form.reports.group_by_project'); if (MODE_PROJECTS_AND_TASKS == $trackingMode) $group_by_options['task'] = $i18n->get('form.reports.group_by_task'); +// If we have time custom fields - add group by options for them. +/* + * This is unfinished work in progress. +if ($custom_fields && $custom_fields->timeFields) { + foreach ($custom_fields->timeFields as $timeField) { + $field_name = 'time_field_'.$timeField['id']; + $group_by_options[$field_name] = $timeField['label']; + } +} +// If we have user custom fields - add group by options for them. +if ($custom_fields && $custom_fields->userFields) { + foreach ($custom_fields->userFields as $userField) { + $field_name = 'user_field_'.$userField['id']; + $group_by_options[$field_name] = $userField['label']; + } +}*/ $group_by_options_size = sizeof($group_by_options); $form->addInput(array('type'=>'combobox','onchange'=>'handleCheckboxes();','name'=>'group_by1','data'=>$group_by_options)); if ($group_by_options_size > 2) $form->addInput(array('type'=>'combobox','onchange'=>'handleCheckboxes();','name'=>'group_by2','data'=>$group_by_options)); From b5834a3c786be7c5a788eb78b3ed7466b20a2f92 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 21 Aug 2019 20:04:18 +0000 Subject: [PATCH 036/877] Fixed export. --- WEB-INF/lib/ttGroupExportHelper.class.php | 2 +- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/WEB-INF/lib/ttGroupExportHelper.class.php b/WEB-INF/lib/ttGroupExportHelper.class.php index b76c790fc..0bd55030e 100644 --- a/WEB-INF/lib/ttGroupExportHelper.class.php +++ b/WEB-INF/lib/ttGroupExportHelper.class.php @@ -495,7 +495,7 @@ function writeData() { unset($expense_item_part); $offset += $limit; } - fwrite($this->file, $this->indentation." file, $this->indentation." \n"); // Write predefined expenses. $predefined_expenses = $this->getRecordsFromTable('tt_predefined_expenses'); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index b74764280..017fb6699 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.19.7.5047 | Copyright © Anuko | +  Anuko Time Tracker 1.19.7.5048 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From bc36522589cbd884a50e581696f7638d92944782 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 21 Aug 2019 21:26:27 +0000 Subject: [PATCH 037/877] Added label.sort_by to translation files as part of adding sorting to invoices.php (ongoing work). --- WEB-INF/resources/ca.lang.php | 1 + WEB-INF/resources/cs.lang.php | 1 + WEB-INF/resources/da.lang.php | 1 + WEB-INF/resources/de.lang.php | 2 ++ WEB-INF/resources/en.lang.php | 1 + WEB-INF/resources/es.lang.php | 1 + WEB-INF/resources/et.lang.php | 2 ++ WEB-INF/resources/fa.lang.php | 1 + WEB-INF/resources/fi.lang.php | 1 + WEB-INF/resources/fr.lang.php | 1 + WEB-INF/resources/gr.lang.php | 2 ++ WEB-INF/resources/he.lang.php | 1 + WEB-INF/resources/hu.lang.php | 1 + WEB-INF/resources/it.lang.php | 2 ++ WEB-INF/resources/ja.lang.php | 1 + WEB-INF/resources/ko.lang.php | 1 + WEB-INF/resources/nl.lang.php | 2 ++ WEB-INF/resources/no.lang.php | 1 + WEB-INF/resources/pl.lang.php | 1 + WEB-INF/resources/pt-br.lang.php | 1 + WEB-INF/resources/pt.lang.php | 1 + WEB-INF/resources/ro.lang.php | 1 + WEB-INF/resources/ru.lang.php | 1 + WEB-INF/resources/sk.lang.php | 1 + WEB-INF/resources/sl.lang.php | 1 + WEB-INF/resources/sr.lang.php | 1 + WEB-INF/resources/sv.lang.php | 1 + WEB-INF/resources/tr.lang.php | 1 + WEB-INF/resources/zh-cn.lang.php | 1 + WEB-INF/resources/zh-tw.lang.php | 1 + WEB-INF/templates/footer.tpl | 2 +- 31 files changed, 36 insertions(+), 1 deletion(-) diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index d82477c93..867bd48f0 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -241,6 +241,7 @@ // 'label.condition' => 'Condition', // 'label.yes' => 'yes', // 'label.no' => 'no', +// 'label.sort_by' => 'Sort by', // Labels for plugins (extensions to Time Tracker that provide additional features). // TODO: translate the following. // 'label.custom_fields' => 'Custom fields', diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index 08649ff02..1a3c8c073 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -251,6 +251,7 @@ // 'label.condition' => 'Condition', // 'label.yes' => 'yes', // 'label.no' => 'no', +// 'label.sort_by' => 'Sort by', // Labels for plugins (extensions to Time Tracker that provide additional features). // TODO: translate the following. // 'label.custom_fields' => 'Custom fields', diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index c33097402..1023187dc 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -232,6 +232,7 @@ // TODO: translate the following. // 'label.yes' => 'yes', // 'label.no' => 'no', +// 'label.sort_by' => 'Sort by', // Labels for plugins (extensions to Time Tracker that provide additional features). 'label.custom_fields' => 'Brugerdefineret felt', 'label.monthly_quotas' => 'Månedlig kvota', diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index 8c9e47b73..64ddc84e0 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -222,6 +222,8 @@ 'label.condition' => 'Bedingung', 'label.yes' => 'Ja', 'label.no' => 'Nein', +// TODO: translate the following. +// 'label.sort_by' => 'Sort by', // Labels for plugins (extensions to Time Tracker that provide additional features). 'label.custom_fields' => 'Benutzerfelder', 'label.monthly_quotas' => 'Monatliche Quoten', diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index b00abf288..90ec6044e 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -211,6 +211,7 @@ 'label.condition' => 'Condition', 'label.yes' => 'yes', 'label.no' => 'no', +'label.sort_by' => 'Sort by', // Labels for plugins (extensions to Time Tracker that provide additional features). 'label.custom_fields' => 'Custom fields', 'label.monthly_quotas' => 'Monthly quotas', diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index 7165bd7ba..8ac7de2a4 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -245,6 +245,7 @@ // 'label.condition' => 'Condition', // 'label.yes' => 'yes', // 'label.no' => 'no', +// 'label.sort_by' => 'Sort by', // Labels for plugins (extensions to Time Tracker that provide additional features). // TODO: translate the following. // 'label.custom_fields' => 'Custom fields', diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index 8584fc085..e20712fca 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -238,6 +238,8 @@ 'label.condition' => 'Tingimus', 'label.yes' => 'jah', 'label.no' => 'ei', +// TODO: translate the following. +// 'label.sort_by' => 'Sort by', // Labels for plugins (extensions to Time Tracker that provide additional features). 'label.custom_fields' => 'Eriväljad', 'label.monthly_quotas' => 'Kuu kvoot', diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index 4f6573105..365ebaad2 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -243,6 +243,7 @@ // 'label.condition' => 'Condition', // 'label.yes' => 'yes', // 'label.no' => 'no', +// 'label.sort_by' => 'Sort by', // Labels for plugins (extensions to Time Tracker that provide additional features). 'label.custom_fields' => 'فیلدهای سفارشی', // Translate the following. diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index c7d99e007..1201c26b4 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -235,6 +235,7 @@ // 'label.condition' => 'Condition', // 'label.yes' => 'yes', // 'label.no' => 'no', +// 'label.sort_by' => 'Sort by', // Labels for plugins (extensions to Time Tracker that provide additional features). 'label.custom_fields' => 'Omat kentät', // TODO: translate the following. diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index 870eb67bf..3118f891a 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -231,6 +231,7 @@ // TODO: translate the following. // 'label.yes' => 'yes', // 'label.no' => 'no', +// 'label.sort_by' => 'Sort by', // Labels for plugins (extensions to Time Tracker that provide additional features). 'label.custom_fields' => 'Champs personalisés', 'label.monthly_quotas' => 'Quotas mensuels', diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index d5a305c26..11c4b459c 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -224,6 +224,8 @@ 'label.condition' => 'Κατάσταση', 'label.yes' => 'ναι', 'label.no' => 'όχι', +// TODO: translate the following. +// 'label.sort_by' => 'Sort by', // Labels for plugins (extensions to Time Tracker that provide additional features). 'label.custom_fields' => 'Προσαρμοσμένα πεδία', 'label.monthly_quotas' => 'Μηνιαίες ποσοστώσεις', diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index 2a8b16084..8528ba8f3 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -251,6 +251,7 @@ // 'label.condition' => 'Condition', // 'label.yes' => 'yes', // 'label.no' => 'no', +// 'label.sort_by' => 'Sort by', // Labels for plugins (extensions to Time Tracker that provide additional features). 'label.custom_fields' => 'שדות אישיים', // Translate the following. diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index 4bf29d59d..5c20c1d9d 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -249,6 +249,7 @@ // 'label.condition' => 'Condition', // 'label.yes' => 'yes', // 'label.no' => 'no', +// 'label.sort_by' => 'Sort by', // Labels for plugins (extensions to Time Tracker that provide additional features). // TODO: translate the following. // 'label.custom_fields' => 'Custom fields', diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index 50d9af909..d90592ab0 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -228,6 +228,8 @@ 'label.condition' => 'Condizione', 'label.yes' => 'si', 'label.no' => 'no', +// TODO: translate the following. +// 'label.sort_by' => 'Sort by', // Labels for plugins (extensions to Time Tracker that provide additional features). 'label.custom_fields' => 'Campi personalizzati', 'label.monthly_quotas' => 'Quote mensili', diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index b57a92398..a24a9a9cd 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -252,6 +252,7 @@ // 'label.condition' => 'Condition', // 'label.yes' => 'yes', // 'label.no' => 'no', +// 'label.sort_by' => 'Sort by', // Labels for plugins (extensions to Time Tracker that provide additional features). // TODO: translate the following. // 'label.custom_fields' => 'Custom fields', diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index db58959f5..94e965b8d 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -251,6 +251,7 @@ // 'label.condition' => 'Condition', // 'label.yes' => 'yes', // 'label.no' => 'no', +// 'label.sort_by' => 'Sort by', // Labels for plugins (extensions to Time Tracker that provide additional features). // TODO: translate the following. // 'label.custom_fields' => 'Custom fields', diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 8ede3f3f6..27683ed1c 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -211,6 +211,8 @@ 'label.condition' => 'Voorwaarde', 'label.yes' => 'ja', 'label.no' => 'nee', +// TODO: translate the following. +// 'label.sort_by' => 'Sort by', // Labels for plugins (extensions to Time Tracker that provide additional features). 'label.custom_fields' => 'Eigen velden', 'label.monthly_quotas' => 'Doelen per maand', diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index 72812e4f3..ff06b799b 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -250,6 +250,7 @@ // 'label.condition' => 'Condition', // 'label.yes' => 'yes', // 'label.no' => 'no', +// 'label.sort_by' => 'Sort by', // Labels for plugins (extensions to Time Tracker that provide additional features). // TODO: translate the following. // 'label.custom_fields' => 'Custom fields', diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index 8e7684f21..7886fb4cc 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -237,6 +237,7 @@ // 'label.condition' => 'Condition', // 'label.yes' => 'yes', // 'label.no' => 'no', +// 'label.sort_by' => 'Sort by', // Labels for plugins (extensions to Time Tracker that provide additional features). 'label.custom_fields' => 'Niestandardowe pola', // Translate the following. diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index 9f31b6a57..d9e5dc218 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -234,6 +234,7 @@ // 'label.condition' => 'Condition', // 'label.yes' => 'yes', // 'label.no' => 'no', +// 'label.sort_by' => 'Sort by', // Labels for plugins (extensions to Time Tracker that provide additional features). 'label.custom_fields' => 'Campos personalizados', // Translate the following. diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index bfd153a25..d80272c7b 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -239,6 +239,7 @@ // 'label.condition' => 'Condition', // 'label.yes' => 'yes', // 'label.no' => 'no', +// 'label.sort_by' => 'Sort by', // Labels for plugins (extensions to Time Tracker that provide additional features). // TODO: translate the following. // 'label.custom_fields' => 'Custom fields', diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index 0a8b16bcc..426f86032 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -249,6 +249,7 @@ // 'label.condition' => 'Condition', // 'label.yes' => 'yes', // 'label.no' => 'no', +// 'label.sort_by' => 'Sort by', // Labels for plugins (extensions to Time Tracker that provide additional features). // TODO: translate the following. // 'label.custom_fields' => 'Custom fields', diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index 05d3693ac..c4f76cdd4 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -210,6 +210,7 @@ 'label.condition' => 'Условие', 'label.yes' => 'да', 'label.no' => 'нет', +'label.sort_by' => 'Сортировать по', // Labels for plugins (extensions to Time Tracker that provide additional features). 'label.custom_fields' => 'Дополнительные поля', 'label.monthly_quotas' => 'Месячные квоты', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index 834adf5b8..75c6550d0 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -240,6 +240,7 @@ // 'label.condition' => 'Condition', // 'label.yes' => 'yes', // 'label.no' => 'no', +// 'label.sort_by' => 'Sort by', // Labels for plugins (extensions to Time Tracker that provide additional features). 'label.custom_fields' => 'Vlastné polia', // Translate the following. diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index b8363b6ae..32da0b5bf 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -234,6 +234,7 @@ // 'label.condition' => 'Condition', // 'label.yes' => 'yes', // 'label.no' => 'no', +// 'label.sort_by' => 'Sort by', // Labels for plugins (extensions to Time Tracker that provide additional features). // TODO: translate the following. // 'label.custom_fields' => 'Custom fields', diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index ff68be79a..4b7b459bc 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -234,6 +234,7 @@ // 'label.condition' => 'Condition', // 'label.yes' => 'yes', // 'label.no' => 'no', +// 'label.sort_by' => 'Sort by', // Labels for plugins (extensions to Time Tracker that provide additional features). 'label.custom_fields' => 'Dodatna polja', // Translate the following. diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index 3c108e18f..22780dc8a 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -231,6 +231,7 @@ // TODO: translate the following. // 'label.yes' => 'yes', // 'label.no' => 'no', +// 'label.sort_by' => 'Sort by', // Labels for plugins (extensions to Time Tracker that provide additional features). 'label.custom_fields' => 'Egna fält', 'label.monthly_quotas' => 'Månadskvoter', diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index 1f88bf79e..951de7b58 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -256,6 +256,7 @@ // 'label.condition' => 'Condition', // 'label.yes' => 'yes', // 'label.no' => 'no', +// 'label.sort_by' => 'Sort by', // Labels for plugins (extensions to Time Tracker that provide additional features). // TODO: translate the following. // 'label.custom_fields' => 'Custom fields', diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index 0f6ac781e..4484df603 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -242,6 +242,7 @@ // 'label.condition' => 'Condition', // 'label.yes' => 'yes', // 'label.no' => 'no', +// 'label.sort_by' => 'Sort by', // Labels for plugins (extensions to Time Tracker that provide additional features). // TODO: translate the following. // 'label.custom_fields' => 'Custom fields', diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index 6168289fc..553c70fe4 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -248,6 +248,7 @@ // 'label.condition' => 'Condition', // 'label.yes' => 'yes', // 'label.no' => 'no', +// 'label.sort_by' => 'Sort by', // Labels for plugins (extensions to Time Tracker that provide additional features). // TODO: translate the following. // 'label.custom_fields' => 'Custom fields', diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 017fb6699..dbf728695 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.19.7.5048 | Copyright © Anuko | +  Anuko Time Tracker 1.19.7.5049 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 1a3f9ca3aae51d91704c9f3f5cc25a6a1dc3a9b8 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 24 Aug 2019 18:04:02 +0000 Subject: [PATCH 038/877] Added sort options on invoices.php page. --- WEB-INF/lib/ttGroupHelper.class.php | 20 ++++++-- WEB-INF/lib/ttInvoiceHelper.class.php | 16 +++++++ WEB-INF/resources/ca.lang.php | 4 +- WEB-INF/resources/cs.lang.php | 4 +- WEB-INF/resources/da.lang.php | 4 +- WEB-INF/resources/de.lang.php | 5 +- WEB-INF/resources/en.lang.php | 5 +- WEB-INF/resources/es.lang.php | 4 +- WEB-INF/resources/et.lang.php | 5 +- WEB-INF/resources/fa.lang.php | 4 +- WEB-INF/resources/fi.lang.php | 4 +- WEB-INF/resources/fr.lang.php | 4 +- WEB-INF/resources/gr.lang.php | 5 +- WEB-INF/resources/he.lang.php | 4 +- WEB-INF/resources/hu.lang.php | 4 +- WEB-INF/resources/it.lang.php | 5 +- WEB-INF/resources/ja.lang.php | 4 +- WEB-INF/resources/ko.lang.php | 4 +- WEB-INF/resources/nl.lang.php | 5 +- WEB-INF/resources/no.lang.php | 4 +- WEB-INF/resources/pl.lang.php | 4 +- WEB-INF/resources/pt-br.lang.php | 4 +- WEB-INF/resources/pt.lang.php | 4 +- WEB-INF/resources/ro.lang.php | 4 +- WEB-INF/resources/ru.lang.php | 4 +- WEB-INF/resources/sk.lang.php | 4 +- WEB-INF/resources/sl.lang.php | 4 +- WEB-INF/resources/sr.lang.php | 4 +- WEB-INF/resources/sv.lang.php | 4 +- WEB-INF/resources/tr.lang.php | 4 +- WEB-INF/resources/zh-cn.lang.php | 4 +- WEB-INF/resources/zh-tw.lang.php | 4 +- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/invoices.tpl | 18 +++++++- invoices.php | 66 +++++++++++++++++++++++++++ 35 files changed, 212 insertions(+), 36 deletions(-) diff --git a/WEB-INF/lib/ttGroupHelper.class.php b/WEB-INF/lib/ttGroupHelper.class.php index 05a31562a..c429f2bf3 100644 --- a/WEB-INF/lib/ttGroupHelper.class.php +++ b/WEB-INF/lib/ttGroupHelper.class.php @@ -411,7 +411,7 @@ static function getPredefinedExpenses() { } // The getActiveInvoices returns an array of active invoices for a group. - static function getActiveInvoices() + static function getActiveInvoices($sort_options = false) { global $user; $mdb2 = getConnection(); @@ -425,9 +425,23 @@ static function getActiveInvoices() if ($user->isClient()) $client_part = "and i.client_id = $user->client_id"; - $sql = "select i.id, i.name, i.date, i.client_id, i.status, c.name as client_name from tt_invoices i". + // Prepare order by part. + $order_by_part = 'order by '; + if (!$sort_options) + $order_by_part .= 'i.name'; + else { + $order_by_part .= $sort_options['sort_option_1']; + if ($sort_options['sort_order_1'] == 'descending') $order_by_part .= ' desc'; + + if ($sort_options['sort_option_2']) { + $order_by_part .= ', '.$sort_options['sort_option_2']; + if ($sort_options['sort_order_2'] == 'descending') $order_by_part .= ' desc'; + } + } + + $sql = "select i.id, i.name, i.date, i.client_id, i.status, c.name as client from tt_invoices i". " left join tt_clients c on (c.id = i.client_id)". - " where i.status = 1 and i.group_id = $group_id and i.org_id = $org_id $client_part order by i.name"; + " where i.status = 1 and i.group_id = $group_id and i.org_id = $org_id $client_part $order_by_part"; $res = $mdb2->query($sql); $result = array(); if (!is_a($res, 'PEAR_Error')) { diff --git a/WEB-INF/lib/ttInvoiceHelper.class.php b/WEB-INF/lib/ttInvoiceHelper.class.php index 4c1bd2b06..a766a0f3e 100644 --- a/WEB-INF/lib/ttInvoiceHelper.class.php +++ b/WEB-INF/lib/ttInvoiceHelper.class.php @@ -504,4 +504,20 @@ static function prepareInvoiceBody($invoice_id, $comment) return $body; } + + // validSortOption validates user input for sort option. + static function validSortOption($option, $emptyValid = false) { + if (!$option) + return ($emptyValid ? true : false); + + $valid_options = array('name', 'client', 'date'); + + return (in_array($option, $valid_options) ? true : false); + } + + // validSortOrder validates user input for sort order. + static function validSortOrder($order) { + $valid_options = array('ascending', 'descending'); + return (in_array($order, $valid_options) ? true : false); + } } diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index 867bd48f0..2a31abea6 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -241,7 +241,7 @@ // 'label.condition' => 'Condition', // 'label.yes' => 'yes', // 'label.no' => 'no', -// 'label.sort_by' => 'Sort by', +// 'label.sort' => 'Sort', // Labels for plugins (extensions to Time Tracker that provide additional features). // TODO: translate the following. // 'label.custom_fields' => 'Custom fields', @@ -439,6 +439,8 @@ // 'dropdown.not_approved' => 'not approved', // 'dropdown.paid' => 'paid', // 'dropdown.not_paid' => 'not paid', +// 'dropdown.ascending' => 'ascending', +// 'dropdown.descending' => 'descending', // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => '¿Ha oblidat la seva paraula de pas?', diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index 1a3c8c073..1f10377c5 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -251,7 +251,7 @@ // 'label.condition' => 'Condition', // 'label.yes' => 'yes', // 'label.no' => 'no', -// 'label.sort_by' => 'Sort by', +// 'label.sort' => 'Sort', // Labels for plugins (extensions to Time Tracker that provide additional features). // TODO: translate the following. // 'label.custom_fields' => 'Custom fields', @@ -447,6 +447,8 @@ // 'dropdown.not_approved' => 'not approved', // 'dropdown.paid' => 'paid', // 'dropdown.not_paid' => 'not paid', +// 'dropdown.ascending' => 'ascending', +// 'dropdown.descending' => 'descending', // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'Zapomenuté heslo?', diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index 1023187dc..ce0eea403 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -232,7 +232,7 @@ // TODO: translate the following. // 'label.yes' => 'yes', // 'label.no' => 'no', -// 'label.sort_by' => 'Sort by', +// 'label.sort' => 'Sort', // Labels for plugins (extensions to Time Tracker that provide additional features). 'label.custom_fields' => 'Brugerdefineret felt', 'label.monthly_quotas' => 'Månedlig kvota', @@ -420,6 +420,8 @@ // 'dropdown.not_approved' => 'not approved', // 'dropdown.paid' => 'paid', // 'dropdown.not_paid' => 'not paid', +// 'dropdown.ascending' => 'ascending', +// 'dropdown.descending' => 'descending', // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'Har du glemt din adgangskode?', diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index 64ddc84e0..1ca50d172 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -223,7 +223,7 @@ 'label.yes' => 'Ja', 'label.no' => 'Nein', // TODO: translate the following. -// 'label.sort_by' => 'Sort by', +// 'label.sort' => 'Sort', // Labels for plugins (extensions to Time Tracker that provide additional features). 'label.custom_fields' => 'Benutzerfelder', 'label.monthly_quotas' => 'Monatliche Quoten', @@ -403,6 +403,9 @@ // 'dropdown.not_approved' => 'not approved', 'dropdown.paid' => 'bezahlt', 'dropdown.not_paid' => 'nicht bezahlt', +// TODO: translate the following. +// 'dropdown.ascending' => 'ascending', +// 'dropdown.descending' => 'descending', // Below is a section for strings that are used on individual forms. When a string is used only on one form it should be placed here. // One exception is for closely related forms such as "Time" and "Editing Time Record" with similar controls. In such cases diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index 90ec6044e..af621e467 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -211,7 +211,7 @@ 'label.condition' => 'Condition', 'label.yes' => 'yes', 'label.no' => 'no', -'label.sort_by' => 'Sort by', +'label.sort' => 'Sort', // Labels for plugins (extensions to Time Tracker that provide additional features). 'label.custom_fields' => 'Custom fields', 'label.monthly_quotas' => 'Monthly quotas', @@ -384,7 +384,8 @@ 'dropdown.not_approved' => 'not approved', 'dropdown.paid' => 'paid', 'dropdown.not_paid' => 'not paid', - +'dropdown.ascending' => 'ascending', +'dropdown.descending' => 'descending', // Below is a section for strings that are used on individual forms. When a string is used only on one form it should be placed here. // One exception is for closely related forms such as "Time" and "Editing Time Record" with similar controls. In such cases diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index 8ac7de2a4..3c10065e2 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -245,7 +245,7 @@ // 'label.condition' => 'Condition', // 'label.yes' => 'yes', // 'label.no' => 'no', -// 'label.sort_by' => 'Sort by', +// 'label.sort' => 'Sort', // Labels for plugins (extensions to Time Tracker that provide additional features). // TODO: translate the following. // 'label.custom_fields' => 'Custom fields', @@ -438,6 +438,8 @@ // 'dropdown.not_approved' => 'not approved', // 'dropdown.paid' => 'paid', // 'dropdown.not_paid' => 'not paid', +// 'dropdown.ascending' => 'ascending', +// 'dropdown.descending' => 'descending', // Below is a section for strings that are used on individual forms. When a string is used only on one form it should be placed here. // One exception is for closely related forms such as "Time" and "Editing Time Record" with similar controls. In such cases diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index e20712fca..2ac7b9d56 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -239,7 +239,7 @@ 'label.yes' => 'jah', 'label.no' => 'ei', // TODO: translate the following. -// 'label.sort_by' => 'Sort by', +// 'label.sort' => 'Sort', // Labels for plugins (extensions to Time Tracker that provide additional features). 'label.custom_fields' => 'Eriväljad', 'label.monthly_quotas' => 'Kuu kvoot', @@ -426,6 +426,9 @@ // 'dropdown.not_approved' => 'not approved', 'dropdown.paid' => 'makstud', 'dropdown.not_paid' => 'mitte makstud', +// TODO: translate the following. +// 'dropdown.ascending' => 'ascending', +// 'dropdown.descending' => 'descending', // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'Unustasid salasõna?', diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index 365ebaad2..37a9907d0 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -243,7 +243,7 @@ // 'label.condition' => 'Condition', // 'label.yes' => 'yes', // 'label.no' => 'no', -// 'label.sort_by' => 'Sort by', +// 'label.sort' => 'Sort', // Labels for plugins (extensions to Time Tracker that provide additional features). 'label.custom_fields' => 'فیلدهای سفارشی', // Translate the following. @@ -432,6 +432,8 @@ // 'dropdown.not_approved' => 'not approved', // 'dropdown.paid' => 'paid', // 'dropdown.not_paid' => 'not paid', +// 'dropdown.ascending' => 'ascending', +// 'dropdown.descending' => 'descending', // Below is a section for strings that are used on individual forms. When a string is used only on one form it should be placed here. // One exception is for closely related forms such as "Time" and "Editing Time Record" with similar controls. In such cases diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 1201c26b4..94b76fcee 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -235,7 +235,7 @@ // 'label.condition' => 'Condition', // 'label.yes' => 'yes', // 'label.no' => 'no', -// 'label.sort_by' => 'Sort by', +// 'label.sort' => 'Sort', // Labels for plugins (extensions to Time Tracker that provide additional features). 'label.custom_fields' => 'Omat kentät', // TODO: translate the following. @@ -420,6 +420,8 @@ // 'dropdown.not_approved' => 'not approved', // 'dropdown.paid' => 'paid', // 'dropdown.not_paid' => 'not paid', +// 'dropdown.ascending' => 'ascending', +// 'dropdown.descending' => 'descending', // Below is a section for strings that are used on individual forms. When a string is used only on one form it should be placed here. // One exception is for closely related forms such as "Time" and "Editing Time Record" with similar controls. In such cases diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index 3118f891a..3f562efed 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -231,7 +231,7 @@ // TODO: translate the following. // 'label.yes' => 'yes', // 'label.no' => 'no', -// 'label.sort_by' => 'Sort by', +// 'label.sort' => 'Sort', // Labels for plugins (extensions to Time Tracker that provide additional features). 'label.custom_fields' => 'Champs personalisés', 'label.monthly_quotas' => 'Quotas mensuels', @@ -412,6 +412,8 @@ // 'dropdown.not_approved' => 'not approved', // 'dropdown.paid' => 'paid', // 'dropdown.not_paid' => 'not paid', +// 'dropdown.ascending' => 'ascending', +// 'dropdown.descending' => 'descending', // Below is a section for strings that are used on individual forms. When a string is used only on one form it should be placed here. // One exception is for closely related forms such as "Time" and "Editing Time Record" with similar controls. In such cases diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index 11c4b459c..d44acd4ac 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -225,7 +225,7 @@ 'label.yes' => 'ναι', 'label.no' => 'όχι', // TODO: translate the following. -// 'label.sort_by' => 'Sort by', +// 'label.sort' => 'Sort', // Labels for plugins (extensions to Time Tracker that provide additional features). 'label.custom_fields' => 'Προσαρμοσμένα πεδία', 'label.monthly_quotas' => 'Μηνιαίες ποσοστώσεις', @@ -411,6 +411,9 @@ // 'dropdown.not_approved' => 'not approved', 'dropdown.paid' => 'εξοφλημένο', 'dropdown.not_paid' => 'δεν έχει εξοφληθεί', +// TODO: translate the following. +// 'dropdown.ascending' => 'ascending', +// 'dropdown.descending' => 'descending', // Below is a section for strings that are used on individual forms. When a string is used only on one form it should be placed here. // One exception is for closely related forms such as "Time" and "Editing Time Record" with similar controls. In such cases diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index 8528ba8f3..6086b6611 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -251,7 +251,7 @@ // 'label.condition' => 'Condition', // 'label.yes' => 'yes', // 'label.no' => 'no', -// 'label.sort_by' => 'Sort by', +// 'label.sort' => 'Sort', // Labels for plugins (extensions to Time Tracker that provide additional features). 'label.custom_fields' => 'שדות אישיים', // Translate the following. @@ -438,6 +438,8 @@ // 'dropdown.not_approved' => 'not approved', // 'dropdown.paid' => 'paid', // 'dropdown.not_paid' => 'not paid', +// 'dropdown.ascending' => 'ascending', +// 'dropdown.descending' => 'descending', // Below is a section for strings that are used on individual forms. When a string is used only on one form it should be placed here. // One exception is for closely related forms such as "Time" and "Editing Time Record" with similar controls. In such cases diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index 5c20c1d9d..d02e27084 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -249,7 +249,7 @@ // 'label.condition' => 'Condition', // 'label.yes' => 'yes', // 'label.no' => 'no', -// 'label.sort_by' => 'Sort by', +// 'label.sort' => 'Sort', // Labels for plugins (extensions to Time Tracker that provide additional features). // TODO: translate the following. // 'label.custom_fields' => 'Custom fields', @@ -441,6 +441,8 @@ // 'dropdown.not_approved' => 'not approved', // 'dropdown.paid' => 'paid', // 'dropdown.not_paid' => 'not paid', +// 'dropdown.ascending' => 'ascending', +// 'dropdown.descending' => 'descending', // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'Elfelejtetted a jelszót?', diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index d90592ab0..f9ad30966 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -229,7 +229,7 @@ 'label.yes' => 'si', 'label.no' => 'no', // TODO: translate the following. -// 'label.sort_by' => 'Sort by', +// 'label.sort' => 'Sort', // Labels for plugins (extensions to Time Tracker that provide additional features). 'label.custom_fields' => 'Campi personalizzati', 'label.monthly_quotas' => 'Quote mensili', @@ -421,6 +421,9 @@ // 'dropdown.not_approved' => 'not approved', 'dropdown.paid' => 'pagato', 'dropdown.not_paid' => 'non pagato', +// TODO: translate the following. +// 'dropdown.ascending' => 'ascending', +// 'dropdown.descending' => 'descending', // Below is a section for strings that are used on individual forms. When a string is used only on one form it should be placed here. // One exception is for closely related forms such as "Time" and "Editing Time Record" with similar controls. In such cases diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index a24a9a9cd..c0c50c39a 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -252,7 +252,7 @@ // 'label.condition' => 'Condition', // 'label.yes' => 'yes', // 'label.no' => 'no', -// 'label.sort_by' => 'Sort by', +// 'label.sort' => 'Sort', // Labels for plugins (extensions to Time Tracker that provide additional features). // TODO: translate the following. // 'label.custom_fields' => 'Custom fields', @@ -442,6 +442,8 @@ // 'dropdown.not_approved' => 'not approved', // 'dropdown.paid' => 'paid', // 'dropdown.not_paid' => 'not paid', +// 'dropdown.ascending' => 'ascending', +// 'dropdown.descending' => 'descending', // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'パスワードを忘れましたか?', diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index 94e965b8d..c98462c73 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -251,7 +251,7 @@ // 'label.condition' => 'Condition', // 'label.yes' => 'yes', // 'label.no' => 'no', -// 'label.sort_by' => 'Sort by', +// 'label.sort' => 'Sort', // Labels for plugins (extensions to Time Tracker that provide additional features). // TODO: translate the following. // 'label.custom_fields' => 'Custom fields', @@ -446,6 +446,8 @@ // 'dropdown.not_approved' => 'not approved', // 'dropdown.paid' => 'paid', // 'dropdown.not_paid' => 'not paid', +// 'dropdown.ascending' => 'ascending', +// 'dropdown.descending' => 'descending', // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => '암호를 잊으셨습니까?', diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 27683ed1c..b71883ca7 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -212,7 +212,7 @@ 'label.yes' => 'ja', 'label.no' => 'nee', // TODO: translate the following. -// 'label.sort_by' => 'Sort by', +// 'label.sort' => 'Sort', // Labels for plugins (extensions to Time Tracker that provide additional features). 'label.custom_fields' => 'Eigen velden', 'label.monthly_quotas' => 'Doelen per maand', @@ -386,6 +386,9 @@ 'dropdown.not_approved' => 'afgekeurd', 'dropdown.paid' => 'betaald', 'dropdown.not_paid' => 'niet betaald', +// TODO: translate the following. +// 'dropdown.ascending' => 'ascending', +// 'dropdown.descending' => 'descending', // Below is a section for strings that are used on individual forms. When a string is used only on one form it should be placed here. // One exception is for closely related forms such as "Time" and "Editing Time Record" with similar controls. In such cases diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index ff06b799b..b15650585 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -250,7 +250,7 @@ // 'label.condition' => 'Condition', // 'label.yes' => 'yes', // 'label.no' => 'no', -// 'label.sort_by' => 'Sort by', +// 'label.sort' => 'Sort', // Labels for plugins (extensions to Time Tracker that provide additional features). // TODO: translate the following. // 'label.custom_fields' => 'Custom fields', @@ -442,6 +442,8 @@ // 'dropdown.not_approved' => 'not approved', // 'dropdown.paid' => 'paid', // 'dropdown.not_paid' => 'not paid', +// 'dropdown.ascending' => 'ascending', +// 'dropdown.descending' => 'descending', // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'Glemt passordet?', diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index 7886fb4cc..c6795211f 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -237,7 +237,7 @@ // 'label.condition' => 'Condition', // 'label.yes' => 'yes', // 'label.no' => 'no', -// 'label.sort_by' => 'Sort by', +// 'label.sort' => 'Sort', // Labels for plugins (extensions to Time Tracker that provide additional features). 'label.custom_fields' => 'Niestandardowe pola', // Translate the following. @@ -423,6 +423,8 @@ // 'dropdown.not_approved' => 'not approved', // 'dropdown.paid' => 'paid', // 'dropdown.not_paid' => 'not paid', +// 'dropdown.ascending' => 'ascending', +// 'dropdown.descending' => 'descending', // Below is a section for strings that are used on individual forms. When a string is used only on one form it should be placed here. // One exception is for closely related forms such as "Time" and "Editing Time Record" with similar controls. In such cases diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index d9e5dc218..6ab30f3a1 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -234,7 +234,7 @@ // 'label.condition' => 'Condition', // 'label.yes' => 'yes', // 'label.no' => 'no', -// 'label.sort_by' => 'Sort by', +// 'label.sort' => 'Sort', // Labels for plugins (extensions to Time Tracker that provide additional features). 'label.custom_fields' => 'Campos personalizados', // Translate the following. @@ -418,6 +418,8 @@ // 'dropdown.not_approved' => 'not approved', // 'dropdown.paid' => 'paid', // 'dropdown.not_paid' => 'not paid', +// 'dropdown.ascending' => 'ascending', +// 'dropdown.descending' => 'descending', // Below is a section for strings that are used on individual forms. When a string is used only on one form it should be placed here. // One exception is for closely related forms such as "Time" and "Editing Time Record" with similar controls. In such cases diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index d80272c7b..96996831e 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -239,7 +239,7 @@ // 'label.condition' => 'Condition', // 'label.yes' => 'yes', // 'label.no' => 'no', -// 'label.sort_by' => 'Sort by', +// 'label.sort' => 'Sort', // Labels for plugins (extensions to Time Tracker that provide additional features). // TODO: translate the following. // 'label.custom_fields' => 'Custom fields', @@ -425,6 +425,8 @@ // 'dropdown.not_approved' => 'not approved', // 'dropdown.paid' => 'paid', // 'dropdown.not_paid' => 'not paid', +// 'dropdown.ascending' => 'ascending', +// 'dropdown.descending' => 'descending', // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'Esqueceu a senha?', diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index 426f86032..c61cef471 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -249,7 +249,7 @@ // 'label.condition' => 'Condition', // 'label.yes' => 'yes', // 'label.no' => 'no', -// 'label.sort_by' => 'Sort by', +// 'label.sort' => 'Sort', // Labels for plugins (extensions to Time Tracker that provide additional features). // TODO: translate the following. // 'label.custom_fields' => 'Custom fields', @@ -445,6 +445,8 @@ // 'dropdown.not_approved' => 'not approved', // 'dropdown.paid' => 'paid', // 'dropdown.not_paid' => 'not paid', +// 'dropdown.ascending' => 'ascending', +// 'dropdown.descending' => 'descending', // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'Parola pierduta?', diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index c4f76cdd4..44a829745 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -210,7 +210,7 @@ 'label.condition' => 'Условие', 'label.yes' => 'да', 'label.no' => 'нет', -'label.sort_by' => 'Сортировать по', +'label.sort' => 'Сортировать', // Labels for plugins (extensions to Time Tracker that provide additional features). 'label.custom_fields' => 'Дополнительные поля', 'label.monthly_quotas' => 'Месячные квоты', @@ -381,6 +381,8 @@ 'dropdown.not_approved' => 'не одобрено', 'dropdown.paid' => 'оплачено', 'dropdown.not_paid' => 'не оплачено', +'dropdown.ascending' => 'возрастает', +'dropdown.descending' => 'убывает', // Below is a section for strings that are used on individual forms. When a string is used only on one form it should be placed here. // One exception is for closely related forms such as "Time" and "Editing Time Record" with similar controls. In such cases diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index 75c6550d0..e6c2562c5 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -240,7 +240,7 @@ // 'label.condition' => 'Condition', // 'label.yes' => 'yes', // 'label.no' => 'no', -// 'label.sort_by' => 'Sort by', +// 'label.sort' => 'Sort', // Labels for plugins (extensions to Time Tracker that provide additional features). 'label.custom_fields' => 'Vlastné polia', // Translate the following. @@ -428,6 +428,8 @@ // 'dropdown.not_approved' => 'not approved', // 'dropdown.paid' => 'paid', // 'dropdown.not_paid' => 'not paid', +// 'dropdown.ascending' => 'ascending', +// 'dropdown.descending' => 'descending', // Below is a section for strings that are used on individual forms. When a string is used only on one form it should be placed here. // One exception is for closely related forms such as "Time" and "Editing Time Record" with similar controls. In such cases diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index 32da0b5bf..c9e4a1e2a 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -234,7 +234,7 @@ // 'label.condition' => 'Condition', // 'label.yes' => 'yes', // 'label.no' => 'no', -// 'label.sort_by' => 'Sort by', +// 'label.sort' => 'Sort', // Labels for plugins (extensions to Time Tracker that provide additional features). // TODO: translate the following. // 'label.custom_fields' => 'Custom fields', @@ -417,6 +417,8 @@ // 'dropdown.not_approved' => 'not approved', // 'dropdown.paid' => 'paid', // 'dropdown.not_paid' => 'not paid', +// 'dropdown.ascending' => 'ascending', +// 'dropdown.descending' => 'descending', // Login form. See example at https://timetracker.anuko.com/login.php. // TODO: translate the following. diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index 4b7b459bc..ffe29b970 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -234,7 +234,7 @@ // 'label.condition' => 'Condition', // 'label.yes' => 'yes', // 'label.no' => 'no', -// 'label.sort_by' => 'Sort by', +// 'label.sort' => 'Sort', // Labels for plugins (extensions to Time Tracker that provide additional features). 'label.custom_fields' => 'Dodatna polja', // Translate the following. @@ -421,6 +421,8 @@ // 'dropdown.not_approved' => 'not approved', // 'dropdown.paid' => 'paid', // 'dropdown.not_paid' => 'not paid', +// 'dropdown.ascending' => 'ascending', +// 'dropdown.descending' => 'descending', // Below is a section for strings that are used on individual forms. When a string is used only on one form it should be placed here. // One exception is for closely related forms such as "Time" and "Editing Time Record" with similar controls. In such cases diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index 22780dc8a..1c3f5c541 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -231,7 +231,7 @@ // TODO: translate the following. // 'label.yes' => 'yes', // 'label.no' => 'no', -// 'label.sort_by' => 'Sort by', +// 'label.sort' => 'Sort', // Labels for plugins (extensions to Time Tracker that provide additional features). 'label.custom_fields' => 'Egna fält', 'label.monthly_quotas' => 'Månadskvoter', @@ -420,6 +420,8 @@ // 'dropdown.not_approved' => 'not approved', // 'dropdown.paid' => 'paid', // 'dropdown.not_paid' => 'not paid', +// 'dropdown.ascending' => 'ascending', +// 'dropdown.descending' => 'descending', // Below is a section for strings that are used on individual forms. When a string is used only on one form it should be placed here. // One exception is for closely related forms such as "Time" and "Editing Time Record" with similar controls. In such cases diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index 951de7b58..e2754a688 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -256,7 +256,7 @@ // 'label.condition' => 'Condition', // 'label.yes' => 'yes', // 'label.no' => 'no', -// 'label.sort_by' => 'Sort by', +// 'label.sort' => 'Sort', // Labels for plugins (extensions to Time Tracker that provide additional features). // TODO: translate the following. // 'label.custom_fields' => 'Custom fields', @@ -453,6 +453,8 @@ // 'dropdown.not_approved' => 'not approved', // 'dropdown.paid' => 'paid', // 'dropdown.not_paid' => 'not paid', +// 'dropdown.ascending' => 'ascending', +// 'dropdown.descending' => 'descending', // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'Parolanızı unuttunuz mu?', diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index 4484df603..cb49aef3c 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -242,7 +242,7 @@ // 'label.condition' => 'Condition', // 'label.yes' => 'yes', // 'label.no' => 'no', -// 'label.sort_by' => 'Sort by', +// 'label.sort' => 'Sort', // Labels for plugins (extensions to Time Tracker that provide additional features). // TODO: translate the following. // 'label.custom_fields' => 'Custom fields', @@ -433,6 +433,8 @@ // 'dropdown.not_approved' => 'not approved', // 'dropdown.paid' => 'paid', // 'dropdown.not_paid' => 'not paid', +// 'dropdown.ascending' => 'ascending', +// 'dropdown.descending' => 'descending', // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => '忘记密码?', diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index 553c70fe4..f6249638d 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -248,7 +248,7 @@ // 'label.condition' => 'Condition', // 'label.yes' => 'yes', // 'label.no' => 'no', -// 'label.sort_by' => 'Sort by', +// 'label.sort' => 'Sort', // Labels for plugins (extensions to Time Tracker that provide additional features). // TODO: translate the following. // 'label.custom_fields' => 'Custom fields', @@ -438,6 +438,8 @@ // 'dropdown.not_approved' => 'not approved', // 'dropdown.paid' => 'paid', // 'dropdown.not_paid' => 'not paid', +// 'dropdown.ascending' => 'ascending', +// 'dropdown.descending' => 'descending', // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => '忘記密碼?', diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index dbf728695..e04e0c242 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.19.7.5049 | Copyright © Anuko | +  Anuko Time Tracker 1.19.7.5050 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/invoices.tpl b/WEB-INF/templates/invoices.tpl index 5960790c1..2df35a8ce 100644 --- a/WEB-INF/templates/invoices.tpl +++ b/WEB-INF/templates/invoices.tpl @@ -2,6 +2,22 @@ function chLocation(newLocation) { document.location = newLocation; } +{if $show_sorting_options} + {$forms.invoicesForm.open} +
+ + + + +
+ + +
{$i18n.label.sort}:{$forms.invoicesForm.sort_option_1.control}{$forms.invoicesForm.sort_order_1.control}{$forms.invoicesForm.sort_option_2.control}{$forms.invoicesForm.sort_order_2.control}
+
+
+ {$forms.invoicesForm.close} +{/if} + - + {if $user->isPluginEnabled('ps')} diff --git a/invoices.php b/invoices.php index de51b5366..d07935b83 100644 --- a/invoices.php +++ b/invoices.php @@ -41,9 +41,75 @@ } // End of access checks. +if ($request->isPost()) { + $sort_option_1 = $request->getParameter('sort_option_1'); + $sort_order_1 = $request->getParameter('sort_order_1'); + $sort_option_2 = $request->getParameter('sort_option_2'); + $sort_order_2 = $request->getParameter('sort_order_2'); +} + $invoices = ttGroupHelper::getActiveInvoices(); +$form = new Form('invoicesForm'); + +// Prepare an array of sort options. +$sort_options['name'] = $i18n->get('label.thing_name'); +$sort_options['client'] = $i18n->get('label.client'); +$sort_options['date'] = $i18n->get('label.date'); + +$form->addInput(array('type'=>'combobox', + 'name'=>'sort_option_1', + 'onchange'=>'this.form.sorting_changed.value=1;this.form.submit();', + //'style'=>'width: 250px;', + 'data'=>$sort_options, + 'value'=>$sort_option_1)); +$form->addInput(array('type'=>'combobox', + 'name'=>'sort_option_2', + 'onchange'=>'this.form.sorting_changed.value=1;this.form.submit();', + //'style'=>'width: 250px;', + 'data'=>$sort_options, + 'value'=>$sort_option_2, + 'empty'=>array(''=>$i18n->get('dropdown.no')))); + +// Prepare an array of sort order. +$sort_order['ascending'] = $i18n->get('dropdown.ascending'); +$sort_order['descending'] = $i18n->get('dropdown.descending'); + +$form->addInput(array('type'=>'combobox', + 'name'=>'sort_order_1', + 'onchange'=>'this.form.sorting_changed.value=1;this.form.submit();', + 'data'=>$sort_order, + 'value'=>$sort_order_1)); +$form->addInput(array('type'=>'combobox', + 'name'=>'sort_order_2', + 'onchange'=>'this.form.sorting_changed.value=1;this.form.submit();', + 'data'=>$sort_order, + 'value'=>$sort_order_2)); + + +$form->addInput(array('type'=>'hidden','name'=>'sorting_changed')); + +if ($request->isPost()) { + // Validate user input. + if (!ttInvoiceHelper::validSortOption($sort_option_1)) $err->add($i18n->get('error.field'), $i18n->get('label.sort')); + if (!ttInvoiceHelper::validSortOption($sort_option_2, true)) $err->add($i18n->get('error.field'), $i18n->get('label.sort')); + if (!ttInvoiceHelper::validSortOrder($sort_order_1)) $err->add($i18n->get('error.field'), $i18n->get('label.sort')); + if (!ttInvoiceHelper::validSortOrder($sort_order_2)) $err->add($i18n->get('error.field'), $i18n->get('label.sort')); + if ($sort_option_1 == $sort_option_2) $err->add($i18n->get('error.field'), $i18n->get('label.sort')); + + if($request->getParameter('sorting_changed')) { + // User changed sorting. Get invoices sorted accordingly. + $sort_options = array('sort_option_1'=>$sort_option_1, + 'sort_order_1'=>$sort_order_1, + 'sort_option_2'=>$sort_option_2, + 'sort_order_2'=>$sort_order_2); + $invoices = ttGroupHelper::getActiveInvoices($sort_options); + } +} + $smarty->assign('invoices', $invoices); +$smarty->assign('show_sorting_options', count($invoices) > 1); +$smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('title', $i18n->get('title.invoices')); $smarty->assign('content_page_name', 'invoices.tpl'); $smarty->display('index.tpl'); From a35264c37d5d5e8c34dbb360738643f7b1768e59 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 25 Aug 2019 12:00:37 +0000 Subject: [PATCH 039/877] Increased chunk size for exports to speed things up. --- WEB-INF/lib/ttGroupExportHelper.class.php | 4 +--- WEB-INF/lib/ttGroupHelper.class.php | 2 +- WEB-INF/templates/footer.tpl | 2 +- invoices.php | 2 +- 4 files changed, 4 insertions(+), 6 deletions(-) diff --git a/WEB-INF/lib/ttGroupExportHelper.class.php b/WEB-INF/lib/ttGroupExportHelper.class.php index 0bd55030e..79938f803 100644 --- a/WEB-INF/lib/ttGroupExportHelper.class.php +++ b/WEB-INF/lib/ttGroupExportHelper.class.php @@ -387,7 +387,7 @@ function writeData() { // We use getRecordsChunkFromTable here to avoid out of memory condition for large tables. fwrite($this->file, $this->indentation." \n"); $offset = 0; - $limit = 1000; + $limit = 5000; $key = 0; while ($records = $this->getRecordsChunkFromTable('tt_log', $limit, $offset)) { foreach ($records as $record) { @@ -454,7 +454,6 @@ function writeData() { // We use getRecordsChunkFromTable here to avoid out of memory condition for large tables. fwrite($this->file, $this->indentation." \n"); $offset = 0; - $limit = 1000; while ($custom_field_log = $this->getRecordsChunkFromTable('tt_custom_field_log', $limit, $offset)) { foreach ($custom_field_log as $entry) { $custom_field_log_part = $this->indentation.' '."logMap[$entry['log_id']]."\""; @@ -475,7 +474,6 @@ function writeData() { // We use getRecordsChunkFromTable here to avoid out of memory condition for large tables. fwrite($this->file, $this->indentation." \n"); $offset = 0; - $limit = 1000; while ($expense_items = $this->getRecordsChunkFromTable('tt_expense_items', $limit, $offset)) { foreach ($expense_items as $expense_item) { $expense_item_part = $this->indentation.' '."
@@ -21,7 +37,7 @@ {foreach $invoices as $invoice}
{$invoice.name|escape}{$invoice.client_name|escape}{$invoice.client|escape} {$invoice.date}{if $invoice.paid}{$i18n.label.yes}{else}{$i18n.label.no}{/if}
-
 Anuko Time Tracker 1.19.7.5050 | Copyright © Anuko | +  Anuko Time Tracker 1.19.7.5051 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/invoices.php b/invoices.php index d07935b83..3b6fdc0da 100644 --- a/invoices.php +++ b/invoices.php @@ -53,7 +53,7 @@ $form = new Form('invoicesForm'); // Prepare an array of sort options. -$sort_options['name'] = $i18n->get('label.thing_name'); +$sort_options['name'] = $i18n->get('label.invoice'); $sort_options['client'] = $i18n->get('label.client'); $sort_options['date'] = $i18n->get('label.date'); From 0f315cab20bbfc98923c0a50de8dfe28f6241562 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 1 Sep 2019 23:12:36 +0000 Subject: [PATCH 040/877] Backticked rank in sql queries as it is now a reserved word in MySQL. --- WEB-INF/lib/ttOrgImportHelper.class.php | 4 +- WEB-INF/lib/ttRoleHelper.class.php | 34 ++++++++-------- WEB-INF/lib/ttTeamHelper.class.php | 10 ++--- WEB-INF/templates/footer.tpl | 2 +- dbinstall.php | 54 ++++++++++++------------- mysql.sql | 4 +- 6 files changed, 54 insertions(+), 54 deletions(-) diff --git a/WEB-INF/lib/ttOrgImportHelper.class.php b/WEB-INF/lib/ttOrgImportHelper.class.php index 20dd41764..8549b9022 100644 --- a/WEB-INF/lib/ttOrgImportHelper.class.php +++ b/WEB-INF/lib/ttOrgImportHelper.class.php @@ -928,7 +928,7 @@ private function insertRole($fields) $rights = $fields['rights']; $status = $fields['status']; - $sql = "insert into tt_roles (group_id, org_id, name, rank, description, rights, status) + $sql = "insert into tt_roles (group_id, org_id, name, `rank`, description, rights, status) values ($group_id, $org_id, ".$mdb2->quote($name).", $rank, ".$mdb2->quote($description).", ".$mdb2->quote($rights).", ".$mdb2->quote($status).")"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) @@ -1221,7 +1221,7 @@ private function insertCustomFieldLogEntry($fields) { private function getTopRole() { $mdb2 = getConnection(); - $sql = "select id from tt_roles where group_id = 0 and rank = ".MAX_RANK." and status = 1"; + $sql = "select id from tt_roles where group_id = 0 and `rank` = ".MAX_RANK." and status = 1"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { diff --git a/WEB-INF/lib/ttRoleHelper.class.php b/WEB-INF/lib/ttRoleHelper.class.php index 326d0faf5..7fa9f8fb2 100644 --- a/WEB-INF/lib/ttRoleHelper.class.php +++ b/WEB-INF/lib/ttRoleHelper.class.php @@ -36,7 +36,7 @@ static function get($id) $mdb2 = getConnection(); - $sql = "select id, name, description, rank, rights, status from tt_roles + $sql = "select id, name, description, `rank`, rights, status from tt_roles where id = $id and group_id = ".$user->getGroup()." and (status = 0 or status = 1)"; $res = $mdb2->query($sql); @@ -72,7 +72,7 @@ static function getRoleByName($role_name) { static function getTopManagerRoleID() { $mdb2 = getConnection(); - $sql = "select id from tt_roles where group_id = 0 and rank = 512"; + $sql = "select id from tt_roles where group_id = 0 and `rank` = 512"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { @@ -110,7 +110,7 @@ static function getRoleByRank($rank) { $org_id = $user->org_id; $rank = (int) $rank; // Cast to int just in case. - $sql = "select id from tt_roles where group_id = $group_id and org_id = $org_id and rank = $rank and (status = 1 or status = 0)"; + $sql = "select id from tt_roles where group_id = $group_id and org_id = $org_id and `rank` = $rank and (status = 1 or status = 0)"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { @@ -131,7 +131,7 @@ static function update($fields) { $id = (int)$fields['id']; if (isset($fields['name'])) $name_part = 'name = '.$mdb2->quote($fields['name']); - if (isset($fields['rank'])) $rank_part = ', rank = '.(int)$fields['rank']; + if (isset($fields['rank'])) $rank_part = ', `rank` = '.(int)$fields['rank']; if (isset($fields['description'])) $descr_part = ', description = '.$mdb2->quote($fields['description']); if (isset($fields['status'])) $status_part = ', status = '.(int)$fields['status']; if (isset($fields['rights'])) $rights_part = ', rights = '.$mdb2->quote($fields['rights']); @@ -169,7 +169,7 @@ static function insert($fields) $rights = $fields['rights']; $status = $fields['status']; - $sql = "insert into tt_roles (group_id, org_id, name, rank, description, rights, status) + $sql = "insert into tt_roles (group_id, org_id, name, `rank`, description, rights, status) values ($group_id, $org_id, ".$mdb2->quote($name).", $rank, ".$mdb2->quote($description).", ".$mdb2->quote($rights).", ".$mdb2->quote($status).")"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) @@ -199,7 +199,7 @@ static function createPredefinedRoles($group_id, $lang) $name = $mdb2->quote($i18n->get('role.user.label')); $description = $mdb2->quote($i18n->get('role.user.description')); $rights = $mdb2->quote($rights_user); - $sql = "insert into tt_roles (group_id, org_id, name, description, rank, rights, status) values($group_id, $group_id, $name, $description, 4, $rights, 1)"; + $sql = "insert into tt_roles (group_id, org_id, name, description, `rank`, rights, status) values($group_id, $group_id, $name, $description, 4, $rights, 1)"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; @@ -207,7 +207,7 @@ static function createPredefinedRoles($group_id, $lang) $name = $mdb2->quote($i18n->get('role.client.label')); $description = $mdb2->quote($i18n->get('role.client.description')); $rights = $mdb2->quote($rights_client); - $sql = "insert into tt_roles (group_id, org_id, name, description, rank, rights, status) values($group_id, $group_id, $name, $description, 16, $rights, 1)"; + $sql = "insert into tt_roles (group_id, org_id, name, description, `rank`, rights, status) values($group_id, $group_id, $name, $description, 16, $rights, 1)"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; @@ -215,7 +215,7 @@ static function createPredefinedRoles($group_id, $lang) $name = $mdb2->quote($i18n->get('role.comanager.label')); $description = $mdb2->quote($i18n->get('role.comanager.description')); $rights = $mdb2->quote($rights_comanager); - $sql = "insert into tt_roles (group_id, org_id, name, description, rank, rights, status) values($group_id, $group_id, $name, $description, 68, $rights, 1)"; + $sql = "insert into tt_roles (group_id, org_id, name, description, `rank`, rights, status) values($group_id, $group_id, $name, $description, 68, $rights, 1)"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; @@ -223,7 +223,7 @@ static function createPredefinedRoles($group_id, $lang) $name = $mdb2->quote($i18n->get('role.manager.label')); $description = $mdb2->quote($i18n->get('role.manager.description')); $rights = $mdb2->quote($rights_manager); - $sql = "insert into tt_roles (group_id, org_id, name, description, rank, rights, status) values($group_id, $group_id, $name, $description, 324, $rights, 1)"; + $sql = "insert into tt_roles (group_id, org_id, name, description, `rank`, rights, status) values($group_id, $group_id, $name, $description, 324, $rights, 1)"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; @@ -232,7 +232,7 @@ static function createPredefinedRoles($group_id, $lang) $name = $mdb2->quote($i18n->get('role.supervisor.label')); $description = $mdb2->quote($i18n->get('role.supervisor.description')); $rights = $mdb2->quote($rights_supervisor); - $sql = "insert into tt_roles (group_id, org_id, name, description, rank, rights, status) values($group_id, $group_id, $name, $description, 12, $rights, 0)"; + $sql = "insert into tt_roles (group_id, org_id, name, description, `rank`, rights, status) values($group_id, $group_id, $name, $description, 12, $rights, 0)"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; @@ -260,7 +260,7 @@ static function createPredefinedRoles_1_17_44($group_id, $lang) $name = $mdb2->quote($i18n->get('role.user.label')); $description = $mdb2->quote($i18n->get('role.user.description')); $rights = $mdb2->quote($rights_user); - $sql = "insert into tt_roles (team_id, name, description, rank, rights, status) values($group_id, $name, $description, 4, $rights, 1)"; + $sql = "insert into tt_roles (team_id, name, description, `rank`, rights, status) values($group_id, $name, $description, 4, $rights, 1)"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; @@ -268,7 +268,7 @@ static function createPredefinedRoles_1_17_44($group_id, $lang) $name = $mdb2->quote($i18n->get('role.client.label')); $description = $mdb2->quote($i18n->get('role.client.description')); $rights = $mdb2->quote($rights_client); - $sql = "insert into tt_roles (team_id, name, description, rank, rights, status) values($group_id, $name, $description, 16, $rights, 1)"; + $sql = "insert into tt_roles (team_id, name, description, `rank`, rights, status) values($group_id, $name, $description, 16, $rights, 1)"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; @@ -276,7 +276,7 @@ static function createPredefinedRoles_1_17_44($group_id, $lang) $name = $mdb2->quote($i18n->get('role.comanager.label')); $description = $mdb2->quote($i18n->get('role.comanager.description')); $rights = $mdb2->quote($rights_comanager); - $sql = "insert into tt_roles (team_id, name, description, rank, rights, status) values($group_id, $name, $description, 68, $rights, 1)"; + $sql = "insert into tt_roles (team_id, name, description, `rank`, rights, status) values($group_id, $name, $description, 68, $rights, 1)"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; @@ -284,7 +284,7 @@ static function createPredefinedRoles_1_17_44($group_id, $lang) $name = $mdb2->quote($i18n->get('role.manager.label')); $description = $mdb2->quote($i18n->get('role.manager.description')); $rights = $mdb2->quote($rights_manager); - $sql = "insert into tt_roles (team_id, name, description, rank, rights, status) values($group_id, $name, $description, 324, $rights, 1)"; + $sql = "insert into tt_roles (team_id, name, description, `rank`, rights, status) values($group_id, $name, $description, 324, $rights, 1)"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; @@ -293,7 +293,7 @@ static function createPredefinedRoles_1_17_44($group_id, $lang) $name = $mdb2->quote($i18n->get('role.supervisor.label')); $description = $mdb2->quote($i18n->get('role.supervisor.description')); $rights = $mdb2->quote($rights_supervisor); - $sql = "insert into tt_roles (team_id, name, description, rank, rights, status) values($group_id, $name, $description, 12, $rights, 0)"; + $sql = "insert into tt_roles (team_id, name, description, `rank`, rights, status) values($group_id, $name, $description, 12, $rights, 0)"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) return false; @@ -308,7 +308,7 @@ static function getRoleByRank_1_17_44($rank, $group_id) { $rank = (int) $rank; // Cast to int just in case for better security. - $sql = "select id from tt_roles where team_id = $group_id and rank = $rank and (status = 1 or status = 0)"; + $sql = "select id from tt_roles where team_id = $group_id and `rank` = $rank and (status = 1 or status = 0)"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { @@ -325,7 +325,7 @@ static function copyRolesToGroup($group_id) { $mdb2 = getConnection(); $org_id = $user->org_id; - $columns = '(group_id, org_id, name, description, rank, rights, status)'; + $columns = '(group_id, org_id, name, description, `rank`, rights, status)'; $roles = ttGroupHelper::getRoles(); // Roles in current on behalf group. foreach ($roles as $role) { diff --git a/WEB-INF/lib/ttTeamHelper.class.php b/WEB-INF/lib/ttTeamHelper.class.php index 651226e49..9bb538912 100644 --- a/WEB-INF/lib/ttTeamHelper.class.php +++ b/WEB-INF/lib/ttTeamHelper.class.php @@ -136,7 +136,7 @@ static function getActiveRolesForUser() // then rank restriction does not apply. $max_rank = $user->behalfGroup ? MAX_RANK : $user->rank; - $sql = "select id, name, description, rank, rights from tt_roles where group_id = $group_id and org_id = $org_id and rank < $max_rank and status = 1 order by rank"; + $sql = "select id, name, description, `rank`, rights from tt_roles where group_id = $group_id and org_id = $org_id and `rank` < $max_rank and status = 1 order by `rank`"; $res = $mdb2->query($sql); $result = array(); if (!is_a($res, 'PEAR_Error')) { @@ -156,7 +156,7 @@ static function getActiveRoles($group_id) $result = array(); $mdb2 = getConnection(); - $sql = "select id, name, description, rank, rights from tt_roles where group_id = $group_id and status = 1 order by rank"; + $sql = "select id, name, description, `rank`, rights from tt_roles where group_id = $group_id and status = 1 order by `rank`"; $res = $mdb2->query($sql); $result = array(); if (!is_a($res, 'PEAR_Error')) { @@ -174,8 +174,8 @@ static function getInactiveRoles($group_id) $result = array(); $mdb2 = getConnection(); - $sql = "select id, name, rank, description from tt_roles - where group_id = $group_id and status = 0 order by rank"; + $sql = "select id, name, `rank`, description from tt_roles + where group_id = $group_id and status = 0 order by `rank`"; $res = $mdb2->query($sql); $result = array(); if (!is_a($res, 'PEAR_Error')) { @@ -201,7 +201,7 @@ static function getInactiveRolesForUser() // then rank restriction does not apply. $max_rank = $user->behalfGroup ? MAX_RANK : $user->rank; - $sql = "select id, name, description, rank, rights from tt_roles where group_id = $group_id and org_id = $org_id and rank < $max_rank and status = 0 order by rank"; + $sql = "select id, name, description, `rank`, rights from tt_roles where group_id = $group_id and org_id = $org_id and `rank` < $max_rank and status = 0 order by `rank`"; $res = $mdb2->query($sql); $result = array(); if (!is_a($res, 'PEAR_Error')) { diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 80c5ea9e8..66edba20d 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.19.7.5051 | Copyright © Anuko | +  Anuko Time Tracker 1.19.8.5052 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/dbinstall.php b/dbinstall.php index c2ce26180..28eb9646c 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -782,7 +782,7 @@ function ttGenerateKeys() { ttExecute("ALTER TABLE `tt_log` MODIFY `timestamp` timestamp default CURRENT_TIMESTAMP"); ttExecute("ALTER TABLE `tt_tmp_refs` MODIFY `timestamp` timestamp default CURRENT_TIMESTAMP"); ttExecute("CREATE TABLE `tt_roles` (`id` int(11) NOT NULL auto_increment, `team_id` int(11) NOT NULL, `name` varchar(80) default NULL, `rank` int(11) default 0, `rights` text default NULL, `status` tinyint(4) default 1, PRIMARY KEY (`id`))"); - ttExecute("create unique index role_idx on tt_roles(team_id, rank, status)"); + ttExecute("create unique index role_idx on tt_roles(team_id, `rank`, status)"); ttExecute("ALTER TABLE `tt_roles` ADD `description` varchar(255) default NULL AFTER `name`"); ttExecute("ALTER TABLE `tt_users` ADD `role_id` int(11) default NULL AFTER `role`"); ttExecute("CREATE TABLE `tt_site_config` (`param_name` varchar(32) NOT NULL, `param_value` text default NULL, `created` datetime default NULL, `updated` datetime default NULL, PRIMARY KEY (`param_name`))"); @@ -790,11 +790,11 @@ function ttGenerateKeys() { ttExecute("INSERT INTO `tt_roles` (`team_id`, `name`, `rank`, `rights`) VALUES (0, 'Site administrator', 1024, 'administer_site')"); ttExecute("INSERT INTO `tt_roles` (`team_id`, `name`, `rank`, `rights`) VALUES (0, 'Top manager', 512, 'data_entry,view_own_data,manage_own_settings,view_users,on_behalf_data_entry,view_data,override_punch_mode,swap_roles,approve_timesheets,manage_users,manage_projects,manage_tasks,manage_custom_fields,manage_clients,manage_invoices,manage_features,manage_basic_settings,manage_advanced_settings,manage_roles,export_data,manage_subgroups')"); ttExecute("UPDATE `tt_site_config` SET `param_value` = '1.17.35' where param_name = 'version_db'"); - ttExecute("update `tt_users` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.35') set role_id = (select id from tt_roles where rank = 1024) where role = 1024"); - ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.35') set rights = 'data_entry,view_own_reports,view_own_charts,view_own_invoices,manage_own_settings,view_users,on_behalf_data_entry,view_reports,view_charts,override_punch_mode,swap_roles,approve_timesheets,manage_users,manage_projects,manage_tasks,manage_custom_fields,manage_clients,manage_invoices,manage_features,manage_basic_settings,manage_advanced_settings,manage_roles,export_data,manage_subgroups' where team_id = 0 and rank = 512"); + ttExecute("update `tt_users` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.35') set role_id = (select id from tt_roles where `rank` = 1024) where role = 1024"); + ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.35') set rights = 'data_entry,view_own_reports,view_own_charts,view_own_invoices,manage_own_settings,view_users,on_behalf_data_entry,view_reports,view_charts,override_punch_mode,swap_roles,approve_timesheets,manage_users,manage_projects,manage_tasks,manage_custom_fields,manage_clients,manage_invoices,manage_features,manage_basic_settings,manage_advanced_settings,manage_roles,export_data,manage_subgroups' where team_id = 0 and `rank` = 512"); ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.35') set rights = replace(rights, 'view_own_data', 'view_own_reports,view_own_charts') where team_id > 0"); ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.35') set rights = replace(rights, 'view_data', 'view_reports,view_charts') where team_id > 0"); - ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.35') set rights = replace(rights, 'view_own_charts,manage_own_settings', 'view_own_charts,view_own_invoices,manage_own_settings') where team_id > 0 and rank = 16"); + ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.35') set rights = replace(rights, 'view_own_charts,manage_own_settings', 'view_own_charts,view_own_invoices,manage_own_settings') where team_id > 0 and `rank` = 16"); ttExecute("UPDATE `tt_site_config` SET `param_value` = '1.17.40' where param_name = 'version_db'"); ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.40') set rights = replace(rights, 'on_behalf_data_entry', 'track_time,track_expenses')"); ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.40') set rights = replace(rights, 'data_entry', 'track_own_time,track_own_expenses')"); @@ -846,7 +846,7 @@ function ttGenerateKeys() { if ($_POST["convert11744to11797"]) { ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.44') set rights = replace(rights, 'override_punch_mode,override_date_lock', 'override_punch_mode,override_own_punch_mode,override_date_lock')"); ttExecute("UPDATE `tt_site_config` SET param_value = '1.17.48' where param_name = 'version_db' and param_value = '1.17.44'"); - ttExecute("update `tt_users` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.48') set role_id = (select id from tt_roles where team_id = 0 and rank = 512) where role = 324"); + ttExecute("update `tt_users` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.48') set role_id = (select id from tt_roles where team_id = 0 and `rank` = 512) where role = 324"); ttExecute("UPDATE `tt_site_config` SET param_value = '1.17.49' where param_name = 'version_db' and param_value = '1.17.48'"); ttExecute("ALTER TABLE `tt_users` drop role"); ttExecute("UPDATE `tt_site_config` SET param_value = '1.17.50' where param_name = 'version_db' and param_value = '1.17.49'"); @@ -935,7 +935,7 @@ function ttGenerateKeys() { ttExecute("UPDATE `tt_site_config` SET param_value = '1.17.86', modified = now() where param_name = 'version_db' and param_value = '1.17.85'"); ttExecute("ALTER TABLE `tt_groups` ADD `password_complexity` varchar(64) default NULL AFTER `allow_ip`"); ttExecute("UPDATE `tt_site_config` SET param_value = '1.17.87', modified = now() where param_name = 'version_db' and param_value = '1.17.86'"); - ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.87') set rights = replace(rights, 'manage_subgroups', 'manage_subgroups,delete_group') where rank = 512"); + ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.87') set rights = replace(rights, 'manage_subgroups', 'manage_subgroups,delete_group') where `rank` = 512"); ttExecute("UPDATE `tt_site_config` SET param_value = '1.17.88', modified = now() where param_name = 'version_db' and param_value = '1.17.87'"); ttExecute("ALTER TABLE `tt_fav_reports` ADD `show_work_units` tinyint(4) NOT NULL DEFAULT '0' AFTER `show_custom_field_1`"); ttExecute("UPDATE `tt_site_config` SET param_value = '1.17.92', modified = now() where param_name = 'version_db' and param_value = '1.17.88'"); @@ -1089,33 +1089,33 @@ function ttGenerateKeys() { ttExecute("ALTER TABLE `tt_expense_items` ADD `timesheet_id` int(11) default NULL AFTER `project_id`"); ttExecute("create index timesheet_idx on tt_expense_items(timesheet_id)"); ttExecute("UPDATE `tt_site_config` SET param_value = '1.18.37', modified = now() where param_name = 'version_db' and param_value = '1.18.36'"); - ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.37') set rights = 'track_own_time,track_own_expenses,view_own_reports,view_own_timesheets,manage_own_timesheets,view_own_charts,view_own_invoices,view_own_projects,view_own_tasks,manage_own_settings,view_users,track_time,track_expenses,view_reports,view_timesheets,manage_timesheets,approve_timesheets,view_charts,view_own_clients,override_punch_mode,override_own_punch_mode,override_date_lock,override_own_date_lock,swap_roles,manage_own_account,manage_users,manage_projects,manage_tasks,manage_custom_fields,manage_clients,manage_invoices,override_allow_ip,manage_basic_settings,view_all_reports,manage_features,manage_advanced_settings,manage_roles,export_data,manage_subgroups,delete_group' where rank = 512"); - ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.37') set rights = replace(rights, 'view_own_reports,view_own_charts', 'view_own_reports,view_own_timesheets,view_own_charts') where rank = 16"); - ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.37') set rights = replace(rights, 'view_own_reports,view_own_charts', 'view_own_reports,view_own_timesheets,manage_own_timesheets,view_own_charts') where rank = 4 or rank = 12 or rank = 68 or rank = 324"); - ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.37') set rights = replace(rights, 'view_reports,view_charts', 'view_reports,view_timesheets,manage_timesheets,approve_timesheets,view_charts') where rank = 12 or rank = 68 or rank = 324"); - ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.37') set rights = replace(rights, 'swap_roles,approve_timesheets', 'swap_roles') where rank = 12 or rank = 68 or rank = 324"); + ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.37') set rights = 'track_own_time,track_own_expenses,view_own_reports,view_own_timesheets,manage_own_timesheets,view_own_charts,view_own_invoices,view_own_projects,view_own_tasks,manage_own_settings,view_users,track_time,track_expenses,view_reports,view_timesheets,manage_timesheets,approve_timesheets,view_charts,view_own_clients,override_punch_mode,override_own_punch_mode,override_date_lock,override_own_date_lock,swap_roles,manage_own_account,manage_users,manage_projects,manage_tasks,manage_custom_fields,manage_clients,manage_invoices,override_allow_ip,manage_basic_settings,view_all_reports,manage_features,manage_advanced_settings,manage_roles,export_data,manage_subgroups,delete_group' where `rank` = 512"); + ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.37') set rights = replace(rights, 'view_own_reports,view_own_charts', 'view_own_reports,view_own_timesheets,view_own_charts') where `rank` = 16"); + ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.37') set rights = replace(rights, 'view_own_reports,view_own_charts', 'view_own_reports,view_own_timesheets,manage_own_timesheets,view_own_charts') where `rank` = 4 or `rank` = 12 or `rank` = 68 or `rank` = 324"); + ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.37') set rights = replace(rights, 'view_reports,view_charts', 'view_reports,view_timesheets,manage_timesheets,approve_timesheets,view_charts') where `rank` = 12 or `rank` = 68 or `rank` = 324"); + ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.37') set rights = replace(rights, 'swap_roles,approve_timesheets', 'swap_roles') where `rank` = 12 or `rank` = 68 or `rank` = 324"); ttExecute("UPDATE `tt_site_config` SET param_value = '1.18.38', modified = now() where param_name = 'version_db' and param_value = '1.18.37'"); - ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.38') set rights = 'track_own_time,track_own_expenses,view_own_reports,view_own_timesheets,manage_own_timesheets,view_own_charts,view_own_invoices,view_own_projects,view_own_tasks,manage_own_settings,view_users,track_time,track_expenses,view_reports,view_timesheets,manage_timesheets,approve_timesheets,view_charts,view_own_clients,override_punch_mode,override_own_punch_mode,override_date_lock,override_own_date_lock,swap_roles,manage_own_account,manage_users,manage_projects,manage_tasks,manage_custom_fields,manage_clients,manage_invoices,override_allow_ip,manage_basic_settings,view_all_reports,view_all_timesheets,manage_all_timesheets,manage_features,manage_advanced_settings,manage_roles,export_data,approve_all_timesheets,manage_subgroups,delete_group' where rank = 512"); - ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.38') set rights = replace(rights, 'view_all_reports', 'view_all_reports,view_all_timesheets,manage_all_timesheets') where rank = 68 or rank = 324"); - ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.38') set rights = replace(rights, 'export_data,manage_subgroups', 'export_data,approve_all_timesheets,manage_subgroups') where rank = 324"); + ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.38') set rights = 'track_own_time,track_own_expenses,view_own_reports,view_own_timesheets,manage_own_timesheets,view_own_charts,view_own_invoices,view_own_projects,view_own_tasks,manage_own_settings,view_users,track_time,track_expenses,view_reports,view_timesheets,manage_timesheets,approve_timesheets,view_charts,view_own_clients,override_punch_mode,override_own_punch_mode,override_date_lock,override_own_date_lock,swap_roles,manage_own_account,manage_users,manage_projects,manage_tasks,manage_custom_fields,manage_clients,manage_invoices,override_allow_ip,manage_basic_settings,view_all_reports,view_all_timesheets,manage_all_timesheets,manage_features,manage_advanced_settings,manage_roles,export_data,approve_all_timesheets,manage_subgroups,delete_group' where `rank` = 512"); + ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.38') set rights = replace(rights, 'view_all_reports', 'view_all_reports,view_all_timesheets,manage_all_timesheets') where `rank` = 68 or `rank` = 324"); + ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.38') set rights = replace(rights, 'export_data,manage_subgroups', 'export_data,approve_all_timesheets,manage_subgroups') where `rank` = 324"); ttExecute("UPDATE `tt_site_config` SET param_value = '1.18.39', modified = now() where param_name = 'version_db' and param_value = '1.18.38'"); - ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.39') set rights = 'track_own_time,track_own_expenses,view_own_reports,view_own_timesheets,manage_own_timesheets,view_own_charts,view_own_projects,view_own_tasks,manage_own_settings,view_users,view_client_reports,view_client_timesheets,view_client_invoices,track_time,track_expenses,view_reports,view_timesheets,manage_timesheets,approve_timesheets,view_charts,view_own_clients,override_punch_mode,override_own_punch_mode,override_date_lock,override_own_date_lock,swap_roles,manage_own_account,manage_users,manage_projects,manage_tasks,manage_custom_fields,manage_clients,manage_invoices,override_allow_ip,manage_basic_settings,view_all_reports,view_all_timesheets,manage_all_timesheets,manage_features,manage_advanced_settings,manage_roles,export_data,approve_all_timesheets,manage_subgroups,delete_group' where rank = 512"); - ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.39') set rights = replace(rights, 'view_own_reports', 'view_client_reports') where rank = 16"); - ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.39') set rights = replace(rights, 'view_own_charts,', '') where rank = 16"); - ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.39') set rights = replace(rights, 'view_own_timesheets', 'view_client_timesheets') where rank = 16"); - ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.39') set rights = replace(rights, 'view_own_invoices', 'view_client_invoices') where rank = 16"); + ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.39') set rights = 'track_own_time,track_own_expenses,view_own_reports,view_own_timesheets,manage_own_timesheets,view_own_charts,view_own_projects,view_own_tasks,manage_own_settings,view_users,view_client_reports,view_client_timesheets,view_client_invoices,track_time,track_expenses,view_reports,view_timesheets,manage_timesheets,approve_timesheets,view_charts,view_own_clients,override_punch_mode,override_own_punch_mode,override_date_lock,override_own_date_lock,swap_roles,manage_own_account,manage_users,manage_projects,manage_tasks,manage_custom_fields,manage_clients,manage_invoices,override_allow_ip,manage_basic_settings,view_all_reports,view_all_timesheets,manage_all_timesheets,manage_features,manage_advanced_settings,manage_roles,export_data,approve_all_timesheets,manage_subgroups,delete_group' where `rank` = 512"); + ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.39') set rights = replace(rights, 'view_own_reports', 'view_client_reports') where `rank` = 16"); + ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.39') set rights = replace(rights, 'view_own_charts,', '') where `rank` = 16"); + ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.39') set rights = replace(rights, 'view_own_timesheets', 'view_client_timesheets') where `rank` = 16"); + ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.39') set rights = replace(rights, 'view_own_invoices', 'view_client_invoices') where `rank` = 16"); ttExecute("UPDATE `tt_site_config` SET param_value = '1.18.40', modified = now() where param_name = 'version_db' and param_value = '1.18.39'"); - ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.40') set rights = replace(rights, 'view_client_timesheets,view_client_invoices', 'view_client_timesheets,view_client_unapproved,view_client_invoices') where rank = 16"); + ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.40') set rights = replace(rights, 'view_client_timesheets,view_client_invoices', 'view_client_timesheets,view_client_unapproved,view_client_invoices') where `rank` = 16"); ttExecute("UPDATE `tt_site_config` SET param_value = '1.18.41', modified = now() where param_name = 'version_db' and param_value = '1.18.40'"); ttExecute("ALTER TABLE `tt_log` ADD `approved` tinyint(4) default 0 AFTER `billable`"); ttExecute("ALTER TABLE `tt_expense_items` ADD `approved` tinyint(4) default 0 AFTER `invoice_id`"); ttExecute("UPDATE `tt_site_config` SET param_value = '1.18.42', modified = now() where param_name = 'version_db' and param_value = '1.18.41'"); - ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.42') set rights = 'track_own_time,track_own_expenses,view_own_reports,view_own_timesheets,manage_own_timesheets,view_own_charts,view_own_projects,view_own_tasks,manage_own_settings,view_users,view_client_reports,view_client_timesheets,view_client_unapproved,view_client_invoices,track_time,track_expenses,view_reports,approve_reports,view_timesheets,manage_timesheets,approve_timesheets,view_charts,view_own_clients,override_punch_mode,override_own_punch_mode,override_date_lock,override_own_date_lock,swap_roles,manage_own_account,manage_users,manage_projects,manage_tasks,manage_custom_fields,manage_clients,manage_invoices,override_allow_ip,manage_basic_settings,view_all_reports,view_all_timesheets,manage_all_timesheets,manage_features,manage_advanced_settings,manage_roles,export_data,approve_all_reports,approve_all_timesheets,manage_subgroups,delete_group' where rank = 512"); - ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.42') set rights = replace(rights, 'view_reports,view_timesheets', 'view_reports,approve_reports,view_timesheets') where rank = 12 or rank = 68 or rank = 324"); - ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.42') set rights = replace(rights, 'export_data,approve_all_timesheets', 'export_data,approve_all_reports,approve_all_timesheets') where rank = 324"); + ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.42') set rights = 'track_own_time,track_own_expenses,view_own_reports,view_own_timesheets,manage_own_timesheets,view_own_charts,view_own_projects,view_own_tasks,manage_own_settings,view_users,view_client_reports,view_client_timesheets,view_client_unapproved,view_client_invoices,track_time,track_expenses,view_reports,approve_reports,view_timesheets,manage_timesheets,approve_timesheets,view_charts,view_own_clients,override_punch_mode,override_own_punch_mode,override_date_lock,override_own_date_lock,swap_roles,manage_own_account,manage_users,manage_projects,manage_tasks,manage_custom_fields,manage_clients,manage_invoices,override_allow_ip,manage_basic_settings,view_all_reports,view_all_timesheets,manage_all_timesheets,manage_features,manage_advanced_settings,manage_roles,export_data,approve_all_reports,approve_all_timesheets,manage_subgroups,delete_group' where `rank` = 512"); + ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.42') set rights = replace(rights, 'view_reports,view_timesheets', 'view_reports,approve_reports,view_timesheets') where `rank` = 12 or `rank` = 68 or `rank` = 324"); + ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.42') set rights = replace(rights, 'export_data,approve_all_timesheets', 'export_data,approve_all_reports,approve_all_timesheets') where `rank` = 324"); ttExecute("UPDATE `tt_site_config` SET param_value = '1.18.43', modified = now() where param_name = 'version_db' and param_value = '1.18.42'"); - ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.43') set rights = 'track_own_time,track_own_expenses,view_own_reports,view_own_timesheets,manage_own_timesheets,view_own_charts,view_own_projects,view_own_tasks,manage_own_settings,view_users,view_client_reports,view_client_timesheets,view_client_invoices,track_time,track_expenses,view_reports,approve_reports,view_timesheets,manage_timesheets,approve_timesheets,view_charts,view_own_clients,override_punch_mode,override_own_punch_mode,override_date_lock,override_own_date_lock,swap_roles,manage_own_account,manage_users,manage_projects,manage_tasks,manage_custom_fields,manage_clients,manage_invoices,override_allow_ip,manage_basic_settings,view_all_reports,view_all_timesheets,manage_all_timesheets,manage_features,manage_advanced_settings,manage_roles,export_data,approve_all_reports,approve_all_timesheets,manage_subgroups,view_client_unapproved,delete_group' where rank = 512"); - ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.43') set rights = replace(rights, 'view_client_timesheets,view_client_unapproved,view_client_invoices', 'view_client_timesheets,view_client_invoices') where rank = 16"); + ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.43') set rights = 'track_own_time,track_own_expenses,view_own_reports,view_own_timesheets,manage_own_timesheets,view_own_charts,view_own_projects,view_own_tasks,manage_own_settings,view_users,view_client_reports,view_client_timesheets,view_client_invoices,track_time,track_expenses,view_reports,approve_reports,view_timesheets,manage_timesheets,approve_timesheets,view_charts,view_own_clients,override_punch_mode,override_own_punch_mode,override_date_lock,override_own_date_lock,swap_roles,manage_own_account,manage_users,manage_projects,manage_tasks,manage_custom_fields,manage_clients,manage_invoices,override_allow_ip,manage_basic_settings,view_all_reports,view_all_timesheets,manage_all_timesheets,manage_features,manage_advanced_settings,manage_roles,export_data,approve_all_reports,approve_all_timesheets,manage_subgroups,view_client_unapproved,delete_group' where `rank` = 512"); + ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.43') set rights = replace(rights, 'view_client_timesheets,view_client_unapproved,view_client_invoices', 'view_client_timesheets,view_client_invoices') where `rank` = 16"); ttExecute("UPDATE `tt_site_config` SET param_value = '1.18.44', modified = now() where param_name = 'version_db' and param_value = '1.18.43'"); ttExecute("ALTER TABLE `tt_fav_reports` ADD `approved` tinyint(4) default NULL AFTER `billable`"); ttExecute("ALTER TABLE `tt_fav_reports` ADD `timesheet` tinyint(4) default NULL AFTER `invoice`"); @@ -1156,8 +1156,8 @@ function ttGenerateKeys() { ttExecute("ALTER TABLE `tt_groups` ADD `group_key` varchar(32) AFTER `org_id`"); ttExecute("UPDATE `tt_site_config` SET param_value = '1.18.61', modified = now() where param_name = 'version_db' and param_value = '1.18.60'"); ttGenerateKeys(); - ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.61') set rights = replace(rights, 'swap_roles', 'swap_roles,update_work') where rank >= 12"); - ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.61') set rights = replace(rights, 'view_all_reports', 'view_all_reports,manage_work,bid_on_work') where rank >= 68"); + ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.61') set rights = replace(rights, 'swap_roles', 'swap_roles,update_work') where `rank` >= 12"); + ttExecute("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.18.61') set rights = replace(rights, 'view_all_reports', 'view_all_reports,manage_work,bid_on_work') where `rank` >= 68"); ttExecute("UPDATE `tt_site_config` SET param_value = '1.19.0', modified = now() where param_name = 'version_db' and param_value = '1.18.61'"); } diff --git a/mysql.sql b/mysql.sql index b8d7e134c..ec9c207df 100644 --- a/mysql.sql +++ b/mysql.sql @@ -73,7 +73,7 @@ CREATE TABLE `tt_roles` ( ); # Create an index that guarantees unique active and inactive role ranks in each group. -create unique index role_idx on tt_roles(group_id, rank, status); +create unique index role_idx on tt_roles(group_id, `rank`, status); # Insert site-wide roles - site administrator and top manager. INSERT INTO `tt_roles` (`group_id`, `name`, `rank`, `rights`) VALUES (0, 'Site administrator', 1024, 'administer_site'); @@ -112,7 +112,7 @@ create unique index login_idx on tt_users(login, status); # Create admin account with password 'secret'. Admin is a superuser who can create groups. DELETE from `tt_users` WHERE login = 'admin'; -INSERT INTO `tt_users` (`login`, `password`, `name`, `group_id`, `role_id`) VALUES ('admin', md5('secret'), 'Admin', '0', (select id from tt_roles where rank = 1024)); +INSERT INTO `tt_users` (`login`, `password`, `name`, `group_id`, `role_id`) VALUES ('admin', md5('secret'), 'Admin', '0', (select id from tt_roles where `rank` = 1024)); # From 5a9b4121b878f297f359c65f4b7d0cf77bf9c0e0 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 4 Sep 2019 15:39:35 +0000 Subject: [PATCH 041/877] Fixed filling dropdowns on reports.php page load. --- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/reports.tpl | 9 +++++++++ reports.php | 2 +- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 66edba20d..3d91e6db0 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.19.8.5052 | Copyright © Anuko | +  Anuko Time Tracker 1.19.8.5053 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/reports.tpl b/WEB-INF/templates/reports.tpl index f21150949..41c625602 100644 --- a/WEB-INF/templates/reports.tpl +++ b/WEB-INF/templates/reports.tpl @@ -163,6 +163,15 @@ function fillTaskDropdown(project_id) { } } +// The fillDropdowns function populates the "project" and "task" dropdown controls +// with relevant values. +function fillDropdowns() { + if(document.body.contains(document.reportForm.client)) + fillProjectDropdown(document.reportForm.client.value); + + fillTaskDropdown(document.reportForm.project.value); +} + // Build JavaScript array for assigned projects out of passed in PHP array. var assigned_projects = new Array(); {if $assigned_projects} diff --git a/reports.php b/reports.php index 66a6608b4..84d8bde08 100644 --- a/reports.php +++ b/reports.php @@ -526,7 +526,7 @@ $smarty->assign('task_list', $task_list); $smarty->assign('assigned_projects', $assigned_projects); $smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('onload', 'onLoad="handleCheckboxes()"'); +$smarty->assign('onload', 'onLoad="handleCheckboxes();fillDropdowns()"'); $smarty->assign('title', $i18n->get('title.reports')); $smarty->assign('content_page_name', 'reports.tpl'); $smarty->display('index.tpl'); From 286dfd36e9bbd98488c45a74ad811157eb7a0335 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 8 Sep 2019 17:40:32 +0000 Subject: [PATCH 042/877] Added d-m-Y date format as an option. --- WEB-INF/config.php.dist | 14 -------------- WEB-INF/templates/footer.tpl | 2 +- group_edit.php | 1 + 3 files changed, 2 insertions(+), 15 deletions(-) diff --git a/WEB-INF/config.php.dist b/WEB-INF/config.php.dist index 1785336fe..473840e08 100644 --- a/WEB-INF/config.php.dist +++ b/WEB-INF/config.php.dist @@ -114,20 +114,6 @@ define('DEFAULT_CSS', 'default.css'); define('RTL_CSS', 'rtl.css'); // For right to left languages. -// Default date format. Behaviour with not included formats is undefined. Possible values: -// '%Y-%m-%d' -// '%m/%d/%Y' -// '%d.%m.%Y' -// '%d.%m.%Y %a' -define('DATE_FORMAT_DEFAULT', '%Y-%m-%d'); - - -// Default time format. Behaviour with not included formats is undefined. Possible values: -// '%H:%M' -// '%I:%M %p' -define('TIME_FORMAT_DEFAULT', '%H:%M'); - - // Default week start day. // Possible values: 0 - 6. 0 means Sunday. // diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 3d91e6db0..769a9f1fe 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.19.8.5053 | Copyright © Anuko | +  Anuko Time Tracker 1.19.9.5054 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/group_edit.php b/group_edit.php index 1df99a1c5..c4fdc2174 100644 --- a/group_edit.php +++ b/group_edit.php @@ -151,6 +151,7 @@ $DATE_FORMAT_OPTIONS = array( array('id'=>'%Y-%m-%d','name'=>'Y-m-d'), array('id'=>'%m/%d/%Y','name'=>'m/d/Y'), + array('id'=>'%d-%m-%Y','name'=>'d-m-Y'), array('id'=>'%d.%m.%Y','name'=>'d.m.Y'), array('id'=>'%d.%m.%Y %a','name'=>'d.m.Y a')); $form->addInput(array('type'=>'combobox','name'=>'date_format','style'=>'width: 150px;','data'=>$DATE_FORMAT_OPTIONS,'datakeys'=>array('id','name'),'value'=>$cl_date_format, From 3da25fb7bb9906ed193896f6521cf161dbc983a9 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 8 Sep 2019 17:53:41 +0000 Subject: [PATCH 043/877] Removed no longer used WEEK_START_DEFAULT from config.php.dist. --- WEB-INF/config.php.dist | 6 ------ WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/WEB-INF/config.php.dist b/WEB-INF/config.php.dist index 473840e08..87cd5bf11 100644 --- a/WEB-INF/config.php.dist +++ b/WEB-INF/config.php.dist @@ -114,12 +114,6 @@ define('DEFAULT_CSS', 'default.css'); define('RTL_CSS', 'rtl.css'); // For right to left languages. -// Default week start day. -// Possible values: 0 - 6. 0 means Sunday. -// -define('WEEK_START_DEFAULT', 0); - - // Default language of the application. // Possible values: en, fr, nl, etc. Empty string means the language is defined by user browser. // diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 769a9f1fe..545081133 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.19.9.5054 | Copyright © Anuko | +  Anuko Time Tracker 1.19.9.5055 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 758c2c62c05e87b60d4197b6c2c48e714f9927f6 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 8 Sep 2019 22:25:05 +0000 Subject: [PATCH 044/877] Resuming work on remote work plugin. --- WEB-INF/lib/ttFileHelper.class.php | 4 +- WEB-INF/lib/ttOfferHelper.class.php | 536 ++++++++++++++++++++++++++++ WEB-INF/resources/ca.lang.php | 1 + WEB-INF/resources/cs.lang.php | 1 + WEB-INF/resources/da.lang.php | 1 + WEB-INF/resources/de.lang.php | 1 + WEB-INF/resources/en.lang.php | 1 + WEB-INF/resources/es.lang.php | 1 + WEB-INF/resources/et.lang.php | 1 + WEB-INF/resources/fa.lang.php | 1 + WEB-INF/resources/fi.lang.php | 1 + WEB-INF/resources/fr.lang.php | 1 + WEB-INF/resources/gr.lang.php | 1 + WEB-INF/resources/he.lang.php | 1 + WEB-INF/resources/hu.lang.php | 1 + WEB-INF/resources/it.lang.php | 1 + WEB-INF/resources/ja.lang.php | 1 + WEB-INF/resources/ko.lang.php | 1 + WEB-INF/resources/nl.lang.php | 2 + WEB-INF/resources/no.lang.php | 1 + WEB-INF/resources/pl.lang.php | 1 + WEB-INF/resources/pt-br.lang.php | 1 + WEB-INF/resources/pt.lang.php | 1 + WEB-INF/resources/ro.lang.php | 1 + WEB-INF/resources/ru.lang.php | 1 + WEB-INF/resources/sk.lang.php | 1 + WEB-INF/resources/sl.lang.php | 1 + WEB-INF/resources/sr.lang.php | 1 + WEB-INF/resources/sv.lang.php | 1 + WEB-INF/resources/tr.lang.php | 1 + WEB-INF/resources/zh-cn.lang.php | 1 + WEB-INF/resources/zh-tw.lang.php | 1 + WEB-INF/templates/footer.tpl | 2 +- 33 files changed, 570 insertions(+), 3 deletions(-) create mode 100644 WEB-INF/lib/ttOfferHelper.class.php diff --git a/WEB-INF/lib/ttFileHelper.class.php b/WEB-INF/lib/ttFileHelper.class.php index 61dd60285..07d0ad085 100644 --- a/WEB-INF/lib/ttFileHelper.class.php +++ b/WEB-INF/lib/ttFileHelper.class.php @@ -279,7 +279,7 @@ function deleteEntityFiles($entity_id, $entity_type) { if (!$this->entityHasFiles($entity_id, $entity_type)) return true; // No files to delete. - + global $i18n; global $user; $mdb2 = getConnection(); @@ -415,7 +415,7 @@ static function getEntityFiles($id, $type) { return $result; } - // get - obtains file details from local database. + // get - obtains file details from local database. static function get($id) { global $user; $mdb2 = getConnection(); diff --git a/WEB-INF/lib/ttOfferHelper.class.php b/WEB-INF/lib/ttOfferHelper.class.php new file mode 100644 index 000000000..c2ceefa32 --- /dev/null +++ b/WEB-INF/lib/ttOfferHelper.class.php @@ -0,0 +1,536 @@ +errors = &$errors; + + if (defined('REMOTE_WORK_URI')) { + $this->remote_work_uri = REMOTE_WORK_URI; + $this->register_uri = $this->remote_work_uri.'register'; + $this->create_offer_uri = $this->remote_work_uri.'createoffer'; + $this->get_offer_uri = $this->remote_work_uri.'getoffer'; + $this->get_offers_uri = $this->remote_work_uri.'getoffers'; + $this->delete_offer_uri = $this->remote_work_uri.'deleteoffer'; + $this->delete_offers_uri = $this->remote_work_uri.'deleteoffers'; + $this->update_offer_uri = $this->remote_work_uri.'updateoffer'; + $this->checkSiteRegistration(); + } + } + + // checkSiteRegistration - obtains site id and key from local database. + // If not found, it tries to register with remote work server. + function checkSiteRegistration() { + + global $i18n; + $mdb2 = getConnection(); + + // Obtain site id. + $sql = "select param_value as id from tt_site_config where param_name = 'worksite_id'"; + $res = $mdb2->query($sql); + $val = $res->fetchRow(); + if (!$val) { + // No site id found, need to register. + $fields = array('name' => urlencode('time tracker'), + 'origin' => urlencode('time tracker source')); + + // Urlify the data for the POST. + foreach($fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; } + $fields_string = rtrim($fields_string, '&'); + + // Open connection. + $ch = curl_init(); + + // Set the url, number of POST vars, POST data. + curl_setopt($ch, CURLOPT_URL, $this->register_uri); + curl_setopt($ch, CURLOPT_POST, true); + curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + + // Execute a post request. + $result = curl_exec($ch); + + // Close connection. + curl_close($ch); + + $result_array = json_decode($result, true); + if (!$result_array) { + $this->errors->add($i18n->get('error.remote_work')); + } + else if ($result_array['error']) { + // Add an error from remote work server if we have it. + $this->errors->add($result_array['error']); + } + else if ($result_array['id'] && $result_array['key']) { + $this->site_id = $result_array['id']; + $this->site_key = $result_array['key']; + + // Registration successful. Store id and key locally for future use. + $sql = "insert into tt_site_config values('worksite_id', $this->site_id, now(), null)"; + $mdb2->exec($sql); + $sql = "insert into tt_site_config values('worksite_key', ".$mdb2->quote($this->site_key).", now(), null)"; + $mdb2->exec($sql); + } else { + $this->errors->add($i18n->get('error.remote_work')); + } + } else { + // Site id found. + $this->site_id = $val['id']; + + // Obtain site key. + $sql = "select param_value as site_key from tt_site_config where param_name = 'worksite_key'"; + $res = $mdb2->query($sql); + $val = $res->fetchRow(); + $this->site_key = $val['site_key']; + } + } + + + + // The following code is originally from ttFileHelper an needs to be redone. + + // putFile - puts uploaded file in remote storage. + function putFile($fields) { + global $i18n; + global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $curl_fields = array('site_id' => urlencode($this->site_id), + 'site_key' => urlencode($this->site_key), + 'org_id' => urlencode($org_id), + 'org_key' => urlencode($this->getOrgKey()), + 'group_id' => urlencode($group_id), + 'group_key' => urlencode($this->getGroupKey()), + 'entity_type' => urlencode($fields['entity_type']), + 'entity_id' => urlencode($fields['entity_id']), + 'file_name' => urlencode($fields['file_name']), + 'description' => urlencode($fields['description']), + 'content' => urlencode(base64_encode(file_get_contents($_FILES['newfile']['tmp_name']))) + ); + + // url-ify the data for the POST. + foreach($curl_fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; } + $fields_string = rtrim($fields_string, '&'); + + // Open connection. + $ch = curl_init(); + + // Set the url, number of POST vars, POST data. + curl_setopt($ch, CURLOPT_URL, $this->putfile_uri); + curl_setopt($ch, CURLOPT_POST, true); + curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + + // Execute a post request. + $result = curl_exec($ch); + + // Close connection. + curl_close($ch); + + // Delete uploaded file. + unlink($_FILES['newfile']['tmp_name']); + + if (!$result) { + $this->errors->add($i18n->get('error.file_storage')); + return false; + } + + $result_array = json_decode($result, true); + $file_id = (int) $result_array['file_id']; + $file_key = $result_array['file_key']; + $error = $result_array['error']; + + if ($error || !$file_id || !$file_key) { + if ($error) { + // Add an error from file storage facility if we have it. + $this->errors->add($error); + } + return false; + } + + // File put was successful. Store file attributes locally. + $file_key = $mdb2->quote($file_key); + $entity_type = $mdb2->quote($fields['entity_type']); + $entity_id = (int) $fields['entity_id']; + $file_name = $mdb2->quote($fields['file_name']); + $description = $mdb2->quote($fields['description']); + $created = 'now()'; + $created_ip = $mdb2->quote($_SERVER['REMOTE_ADDR']); + $created_by = $user->id; + + $columns = '(group_id, org_id, remote_id, file_key, entity_type, entity_id, file_name, description, created, created_ip, created_by)'; + $values = "values($group_id, $org_id, $file_id, $file_key, $entity_type, $entity_id, $file_name, $description, $created, $created_ip, $created_by)"; + $sql = "insert into tt_files $columns $values"; + $affected = $mdb2->exec($sql); + return (!is_a($affected, 'PEAR_Error')); + } + + // deleteFile - deletes a file from remote storage and its details from local database. + function deleteFile($fields) { + global $i18n; + global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $curl_fields = array('site_id' => urlencode($this->site_id), + 'site_key' => urlencode($this->site_key), + 'org_id' => urlencode($org_id), + 'org_key' => urlencode($this->getOrgKey()), + 'group_id' => urlencode($group_id), + 'group_key' => urlencode($this->getGroupKey()), + 'entity_type' => urlencode($fields['entity_type']), + 'entity_id' => urlencode($fields['entity_id']), + 'file_id' => urlencode($fields['remote_id']), + 'file_key' => urlencode($fields['file_key']), + 'file_name' => urlencode($fields['file_name'])); + + // url-ify the data for the POST. + foreach($curl_fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; } + $fields_string = rtrim($fields_string, '&'); + + // Open connection. + $ch = curl_init(); + + // Set the url, number of POST vars, POST data. + curl_setopt($ch, CURLOPT_URL, $this->deletefile_uri); + curl_setopt($ch, CURLOPT_POST, true); + curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + + // Execute a post request. + $result = curl_exec($ch); + + // Close connection. + curl_close($ch); + + if (!$result) { + $this->errors->add($i18n->get('error.file_storage')); + return false; + } + + $result_array = json_decode($result, true); + $status = (int) $result_array['status']; + $error = $result_array['error']; + + if ($error) { + // Add an error from file storage facility if we have it. + $this->errors->add($error); + } + if ($status != 1) { + // There is no explicit error message, but still something not right. + $this->errors->add($i18n->get('error.file_storage')); + } + + // Delete file reference from database even when remote file storage call fails. + // This is by design to keep things simple. + $file_id = (int) $fields['id']; + $entity_id = (int) $fields['entity_id']; + $sql = "delete from tt_files". + " where id = $file_id and org_id = $org_id and group_id = $group_id and entity_id = $entity_id"; + $affected = $mdb2->exec($sql); + if (is_a($affected, 'PEAR_Error')) { + $this->errors->add($i18n->get('error.db')); + return false; + } + + // File successfully deleted from both file storage and database. + return true; + } + + // deleteEntityFiles - deletes all files associated with an entity. + function deleteEntityFiles($entity_id, $entity_type) { + + if (!$this->entityHasFiles($entity_id, $entity_type)) + return true; // No files to delete. + + global $i18n; + global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $curl_fields = array('site_id' => urlencode($this->site_id), + 'site_key' => urlencode($this->site_key), + 'org_id' => urlencode($org_id), + 'org_key' => urlencode($this->getOrgKey()), + 'group_id' => urlencode($group_id), + 'group_key' => urlencode($this->getGroupKey()), + 'entity_type' => urlencode($entity_type), + 'entity_id' => urlencode($entity_id)); + + // url-ify the data for the POST. + foreach($curl_fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; } + $fields_string = rtrim($fields_string, '&'); + + // Open connection. + $ch = curl_init(); + + // Set the url, number of POST vars, POST data. + curl_setopt($ch, CURLOPT_URL, $this->deletefiles_uri); + curl_setopt($ch, CURLOPT_POST, true); + curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + + // Execute a post request. + $result = curl_exec($ch); + + // Close connection. + curl_close($ch); + + if (!$result) { + $this->errors->add($i18n->get('error.file_storage')); + return false; + } + + $result_array = json_decode($result, true); + $status = (int) $result_array['status']; + $error = $result_array['error']; + + if ($error) { + // Add an error from file storage facility if we have it. + $this->errors->add($error); + } + if ($status != 1) { + // There is no explicit error message, but still something not right. + $this->errors->add($i18n->get('error.file_storage')); + } + + // Many things can go wrong with a remote call to file storage facility. + // By design, we ignore such errors, and proceed with removal of entity + // records from the database. + + // Delete all entity records from the database. + $file_id = $fields['id']; + $sql = "delete from tt_files". + " where entity_id = $entity_id". + " and entity_type = ".$mdb2->quote($entity_type). + " and org_id = $org_id and group_id = $group_id"; + $affected = $mdb2->exec($sql); + if (is_a($affected, 'PEAR_Error')) { + $this->errors->add($i18n->get('error.db')); + return false; + } + + return true; + } + + // entityHasFiles determines if an entity has any files referenced in database. + private function entityHasFiles($entity_id, $entity_type) { + global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $sql = "select id from tt_files where org_id = $org_id and group_id = $group_id". + " and entity_type = ".$mdb2->quote($entity_type)." and entity_id = $entity_id limit 1"; + $res = $mdb2->query($sql); + $val = $res->fetchRow(); + return $val['id'] > 0; + } + + // getOrgKey obtains organization key from the database. + private function getOrgKey() { + global $user; + $mdb2 = getConnection(); + + $org_id = $user->org_id; + $sql = "select group_key from tt_groups where id = $org_id and status = 1"; + $res = $mdb2->query($sql); + $val = $res->fetchRow(); + return $val['group_key']; + } + + // getGrtoupKey obtains group key from the database. + private function getGroupKey() { + global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $sql = "select group_key from tt_groups where id = $group_id and org_id = $org_id and status = 1"; + $res = $mdb2->query($sql); + $val = $res->fetchRow(); + return $val['group_key']; + } + + // getEntityFiles obtains a list of files for an entity. + static function getEntityFiles($id, $type) { + global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $result = array(); + $entity_type = $mdb2->quote($type); + $sql = "select id, remote_id, file_key, file_name as name, description from tt_files". + " where entity_type = $entity_type and entity_id = $id". + " and group_id = $group_id and org_id = $org_id and status = 1 order by id"; + $res = $mdb2->query($sql); + if (!is_a($res, 'PEAR_Error')) { + while ($val = $res->fetchRow()) { + $result[] = $val; + } + } + return $result; + } + + // get - obtains file details from local database. + static function get($id) { + global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $sql = "select id, remote_id, file_key, entity_type, entity_id, file_name, description, status from tt_files". + " where id = $id and group_id = $group_id and org_id = $org_id and (status = 0 or status = 1)"; + $res = $mdb2->query($sql); + if (!is_a($res, 'PEAR_Error')) { + $val = $res->fetchRow(); + if ($val && $val['id']) + return $val; + } + return false; + } + + // update - updates file details in local database. + static function update($fields) { + global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $file_id = (int) $fields['id']; + $description = $mdb2->quote($fields['description']); + + $sql = "update tt_files set description = $description where id = $file_id". + " and group_id = $group_id and org_id = $org_id and (status = 0 or status = 1)"; + $affected = $mdb2->exec($sql); + return !is_a($affected, 'PEAR_Error'); + } + + + // getFile - downloads file from remote storage to memory. + function getFile($fields) { + global $i18n; + global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $curl_fields = array('site_id' => urlencode($this->site_id), + 'site_key' => urlencode($this->site_key), + 'org_id' => urlencode($org_id), + 'org_key' => urlencode($this->getOrgKey()), + 'group_id' => urlencode($group_id), + 'group_key' => urlencode($this->getGroupKey()), + 'entity_type' => urlencode($fields['entity_type']), + 'entity_id' => urlencode($fields['entity_id']), + 'file_id' => urlencode($fields['remote_id']), + 'file_key' => urlencode($fields['file_key']), + 'file_name' => urlencode($fields['file_name'])); + + // url-ify the data for the POST. + foreach($curl_fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; } + $fields_string = rtrim($fields_string, '&'); + + // Open connection. + $ch = curl_init(); + + // Set the url, number of POST vars, POST data. + curl_setopt($ch, CURLOPT_URL, $this->getfile_uri); + curl_setopt($ch, CURLOPT_POST, true); + curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + + // Execute a post request. + $result = curl_exec($ch); + + $error = curl_error(); + $result_array2 = json_decode($result, true); + + // Close connection. + curl_close($ch); + + if (!$result) { + $this->errors->add($i18n->get('error.file_storage')); + return false; + } + + $result_array = json_decode($result, true); + $status = (int) $result_array['status']; + $error = $result_array['error']; + + if ($error) { + // Add an error from file storage facility if we have it. + $this->errors->add($error); + return false; + } + if ($status != 1) { + // There is no explicit error message, but still something not right. + $this->errors->add($i18n->get('error.file_storage')); + return false; + } + + $this->file_data = $result_array['content']; + return true; + } + + + // getFileData - returns file data from memory. + function getFileData() { + return base64_decode($this->file_data); + } +} diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index 2a31abea6..93f7b66b7 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -120,6 +120,7 @@ // 'error.user_count' => 'Limit on user count.', // 'error.expired' => 'Expiration date reached.', // 'error.file_storage' => 'File storage error.', +// 'error.remote_work' => 'Remote work server error.', // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index 1f10377c5..9ca5f2153 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -122,6 +122,7 @@ // 'error.user_count' => 'Limit on user count.', // 'error.expired' => 'Expiration date reached.', // 'error.file_storage' => 'File storage error.', +// 'error.remote_work' => 'Remote work server error.', // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index ce0eea403..b4f29f19b 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -117,6 +117,7 @@ // 'error.user_count' => 'Limit on user count.', // 'error.expired' => 'Expiration date reached.', // 'error.file_storage' => 'File storage error.', +// 'error.remote_work' => 'Remote work server error.', // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index 1ca50d172..14f2c5097 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -112,6 +112,7 @@ // 'error.user_count' => 'Limit on user count.', // 'error.expired' => 'Expiration date reached.', // 'error.file_storage' => 'File storage error.', +// 'error.remote_work' => 'Remote work server error.', // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index af621e467..45e8b8b12 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -105,6 +105,7 @@ 'error.user_count' => 'Limit on user count.', 'error.expired' => 'Expiration date reached.', 'error.file_storage' => 'File storage error.', +'error.remote_work' => 'Remote work server error.', // Warning messages. 'warn.sure' => 'Are you sure?', diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index 3c10065e2..ce4d0693f 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -118,6 +118,7 @@ // 'error.user_count' => 'Limit on user count.', // 'error.expired' => 'Expiration date reached.', // 'error.file_storage' => 'File storage error.', +// 'error.remote_work' => 'Remote work server error.', // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index 2ac7b9d56..7121ee449 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -129,6 +129,7 @@ 'error.expired' => 'Kehtivusaeg on lõppenud.', // TODO: translate the following. // 'error.file_storage' => 'File storage error.', +// 'error.remote_work' => 'Remote work server error.', // Warning messages. 'warn.sure' => 'Oled kindel?', diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index 37a9907d0..404eb6463 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -125,6 +125,7 @@ // 'error.expired' => 'Expiration date reached.', // TODO: translate the following. // 'error.file_storage' => 'File storage error.', +// 'error.remote_work' => 'Remote work server error.', // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 94b76fcee..592dfab2c 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -119,6 +119,7 @@ // 'error.user_count' => 'Limit on user count.', // 'error.expired' => 'Expiration date reached.', // 'error.file_storage' => 'File storage error.', +// 'error.remote_work' => 'Remote work server error.', // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index 3f562efed..a5974fafc 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -117,6 +117,7 @@ // 'error.user_count' => 'Limit on user count.', // 'error.expired' => 'Expiration date reached.', // 'error.file_storage' => 'File storage error.', +// 'error.remote_work' => 'Remote work server error.', // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index d44acd4ac..a362fc7d8 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -113,6 +113,7 @@ // 'error.user_count' => 'Limit on user count.', // 'error.expired' => 'Expiration date reached.', // 'error.file_storage' => 'File storage error.', +// 'error.remote_work' => 'Remote work server error.', // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index 6086b6611..e18d474b2 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -133,6 +133,7 @@ // 'error.user_count' => 'Limit on user count.', // 'error.expired' => 'Expiration date reached.', // 'error.file_storage' => 'File storage error.', +// 'error.remote_work' => 'Remote work server error.', // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index d02e27084..4bd340fff 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -122,6 +122,7 @@ // 'error.user_count' => 'Limit on user count.', // 'error.expired' => 'Expiration date reached.', // 'error.file_storage' => 'File storage error.', +// 'error.remote_work' => 'Remote work server error.', // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index f9ad30966..91177ed08 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -117,6 +117,7 @@ // 'error.user_count' => 'Limit on user count.', // 'error.expired' => 'Expiration date reached.', // 'error.file_storage' => 'File storage error.', +// 'error.remote_work' => 'Remote work server error.', // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index c0c50c39a..a627219ff 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -124,6 +124,7 @@ // 'error.user_count' => 'Limit on user count.', // 'error.expired' => 'Expiration date reached.', // 'error.file_storage' => 'File storage error.', +// 'error.remote_work' => 'Remote work server error.', // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index c98462c73..c8656b94d 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -123,6 +123,7 @@ // 'error.user_count' => 'Limit on user count.', // 'error.expired' => 'Expiration date reached.', // 'error.file_storage' => 'File storage error.', +// 'error.remote_work' => 'Remote work server error.', // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index b71883ca7..0726b427d 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -105,6 +105,8 @@ 'error.user_count' => 'Limiet op aantal gebruikers.', 'error.expired' => 'Verloop datum is bereikt.', 'error.file_storage' => 'Fout bij het opslaan van het bestand.', +// TODO: translate the following. +// 'error.remote_work' => 'Remote work server error.', // Warning messages. 'warn.sure' => 'Ben je er zeker van?', diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index b15650585..78f7d0583 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -124,6 +124,7 @@ // 'error.user_count' => 'Limit on user count.', // 'error.expired' => 'Expiration date reached.', // 'error.file_storage' => 'File storage error.', +// 'error.remote_work' => 'Remote work server error.', // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index c6795211f..e2a807246 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -121,6 +121,7 @@ // 'error.user_count' => 'Limit on user count.', // 'error.expired' => 'Expiration date reached.', // 'error.file_storage' => 'File storage error.', +// 'error.remote_work' => 'Remote work server error.', // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index 6ab30f3a1..7bff5c1ff 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -118,6 +118,7 @@ // 'error.user_count' => 'Limit on user count.', // 'error.expired' => 'Expiration date reached.', // 'error.file_storage' => 'File storage error.', +// 'error.remote_work' => 'Remote work server error.', // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index 96996831e..9dd84ea19 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -117,6 +117,7 @@ // 'error.user_count' => 'Limit on user count.', // 'error.expired' => 'Expiration date reached.', // 'error.file_storage' => 'File storage error.', +// 'error.remote_work' => 'Remote work server error.', // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index c61cef471..537b64885 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -124,6 +124,7 @@ // 'error.user_count' => 'Limit on user count.', // 'error.expired' => 'Expiration date reached.', // 'error.file_storage' => 'File storage error.', +// 'error.remote_work' => 'Remote work server error.', // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index 44a829745..6e9aef1b4 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -104,6 +104,7 @@ 'error.user_count' => 'Ограничение на количество пользователей.', 'error.expired' => 'Достигнута дата экспирации.', 'error.file_storage' => 'Ошибка файлохранилища.', +'error.remote_work' => 'Ошибка сервера удаленной работы.', // Warning messages. 'warn.sure' => 'Вы уверены?', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index e6c2562c5..6a54b2649 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -122,6 +122,7 @@ // 'error.user_count' => 'Limit on user count.', // 'error.expired' => 'Expiration date reached.', // 'error.file_storage' => 'File storage error.', +// 'error.remote_work' => 'Remote work server error.', // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index c9e4a1e2a..579646eb0 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -114,6 +114,7 @@ // 'error.user_count' => 'Limit on user count.', // 'error.expired' => 'Expiration date reached.', // 'error.file_storage' => 'File storage error.', +// 'error.remote_work' => 'Remote work server error.', // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index ffe29b970..8591a93cf 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -118,6 +118,7 @@ // 'error.user_count' => 'Limit on user count.', // 'error.expired' => 'Expiration date reached.', // 'error.file_storage' => 'File storage error.', +// 'error.remote_work' => 'Remote work server error.', // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index 1c3f5c541..d43ebc7f0 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -117,6 +117,7 @@ // 'error.user_count' => 'Limit on user count.', // 'error.expired' => 'Expiration date reached.', // 'error.file_storage' => 'File storage error.', +// 'error.remote_work' => 'Remote work server error.', // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index e2754a688..d37fde559 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -127,6 +127,7 @@ // 'error.user_count' => 'Limit on user count.', // 'error.expired' => 'Expiration date reached.', // 'error.file_storage' => 'File storage error.', +// 'error.remote_work' => 'Remote work server error.', // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index cb49aef3c..64724ed31 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -117,6 +117,7 @@ // 'error.user_count' => 'Limit on user count.', // 'error.expired' => 'Expiration date reached.', // 'error.file_storage' => 'File storage error.', +// 'error.remote_work' => 'Remote work server error.', // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index f6249638d..cfde64db6 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -121,6 +121,7 @@ // 'error.user_count' => 'Limit on user count.', // 'error.expired' => 'Expiration date reached.', // 'error.file_storage' => 'File storage error.', +// 'error.remote_work' => 'Remote work server error.', // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 545081133..02eadcc7b 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.19.9.5055 | Copyright © Anuko | +  Anuko Time Tracker 1.19.9.5056 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From de56f6aea96471f0beaa29ccc1a2fc277288cce3 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 8 Sep 2019 23:01:38 +0000 Subject: [PATCH 045/877] Ongoing coding of remote work plugin. --- WEB-INF/lib/ttOfferHelper.class.php | 231 +++++++++++----------------- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 93 insertions(+), 140 deletions(-) diff --git a/WEB-INF/lib/ttOfferHelper.class.php b/WEB-INF/lib/ttOfferHelper.class.php index c2ceefa32..f6f9cf5aa 100644 --- a/WEB-INF/lib/ttOfferHelper.class.php +++ b/WEB-INF/lib/ttOfferHelper.class.php @@ -126,12 +126,8 @@ function checkSiteRegistration() { } } - - - // The following code is originally from ttFileHelper an needs to be redone. - - // putFile - puts uploaded file in remote storage. - function putFile($fields) { + // createOffer - publishes an offer in remote work server. + function createOffer($fields) { global $i18n; global $user; $mdb2 = getConnection(); @@ -145,11 +141,12 @@ function putFile($fields) { 'org_key' => urlencode($this->getOrgKey()), 'group_id' => urlencode($group_id), 'group_key' => urlencode($this->getGroupKey()), - 'entity_type' => urlencode($fields['entity_type']), - 'entity_id' => urlencode($fields['entity_id']), - 'file_name' => urlencode($fields['file_name']), - 'description' => urlencode($fields['description']), - 'content' => urlencode(base64_encode(file_get_contents($_FILES['newfile']['tmp_name']))) + 'offer_lang' => urlencode($fields['offer_lang']), + 'offer_subject' => urlencode($fields['offer_subject']), + 'offer_descr_short' => urlencode($fields['offer_descr_short']), + 'offer_descr_long' => urlencode($fields['offer_descr_long']), + 'offer_currency' => urlencode($fields['offer_currency']), + 'offer_amount' => urlencode($fields['offer_amount']) ); // url-ify the data for the POST. @@ -160,7 +157,7 @@ function putFile($fields) { $ch = curl_init(); // Set the url, number of POST vars, POST data. - curl_setopt($ch, CURLOPT_URL, $this->putfile_uri); + curl_setopt($ch, CURLOPT_URL, $this->create_offer_uri); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); @@ -171,44 +168,104 @@ function putFile($fields) { // Close connection. curl_close($ch); - // Delete uploaded file. - unlink($_FILES['newfile']['tmp_name']); - if (!$result) { - $this->errors->add($i18n->get('error.file_storage')); + $this->errors->add($i18n->get('error.remote_work')); return false; } $result_array = json_decode($result, true); - $file_id = (int) $result_array['file_id']; - $file_key = $result_array['file_key']; + $offer_id = (int) $result_array['offer_id']; + $offer_key = $result_array['offer_key']; $error = $result_array['error']; - if ($error || !$file_id || !$file_key) { + if ($error || !$offer_id || !$offer_key) { if ($error) { - // Add an error from file storage facility if we have it. + // Add an error from remote work server if we have it. $this->errors->add($error); } return false; } - // File put was successful. Store file attributes locally. - $file_key = $mdb2->quote($file_key); - $entity_type = $mdb2->quote($fields['entity_type']); - $entity_id = (int) $fields['entity_id']; - $file_name = $mdb2->quote($fields['file_name']); - $description = $mdb2->quote($fields['description']); - $created = 'now()'; - $created_ip = $mdb2->quote($_SERVER['REMOTE_ADDR']); - $created_by = $user->id; - - $columns = '(group_id, org_id, remote_id, file_key, entity_type, entity_id, file_name, description, created, created_ip, created_by)'; - $values = "values($group_id, $org_id, $file_id, $file_key, $entity_type, $entity_id, $file_name, $description, $created, $created_ip, $created_by)"; - $sql = "insert into tt_files $columns $values"; - $affected = $mdb2->exec($sql); - return (!is_a($affected, 'PEAR_Error')); + return true; } + + // getOffer - gets offer details from remote work server. + function getOffer($fields) { + global $i18n; + global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $curl_fields = array('site_id' => urlencode($this->site_id), + 'site_key' => urlencode($this->site_key), +// Do we need these here? +// 'org_id' => urlencode($org_id), +// 'org_key' => urlencode($this->getOrgKey()), +// 'group_id' => urlencode($group_id), +// 'group_key' => urlencode($this->getGroupKey()), + 'offer_id' => urlencode($fields['remote_id'])); + + // url-ify the data for the POST. + foreach($curl_fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; } + $fields_string = rtrim($fields_string, '&'); + + // Open connection. + $ch = curl_init(); + + // Set the url, number of POST vars, POST data. + curl_setopt($ch, CURLOPT_URL, $this->get_offer_uri); + curl_setopt($ch, CURLOPT_POST, true); + curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + + // Execute a post request. + $result = curl_exec($ch); + + $error = curl_error(); + $result_array2 = json_decode($result, true); + + // Close connection. + curl_close($ch); + + if (!$result) { + $this->errors->add($i18n->get('error.remote_work')); + return false; + } + + $result_array = json_decode($result, true); + $status = (int) $result_array['status']; + $error = $result_array['error']; + + if ($error) { + // Add an error from remote work server if we have it. + $this->errors->add($error); + return false; + } + if ($status != 1) { + // There is no explicit error message, but still something not right. + $this->errors->add($i18n->get('error.remote_work')); + return false; + } + + // TODO: construct and return an array of fields here... + return true; + } + + // TODO: redo the function above. + // Concerns: 1) why $result_array2 + // 2) We need to return an array of fields. + + + + + + + + // The following code is originally from ttFileHelper an needs to be redone. + // // deleteFile - deletes a file from remote storage and its details from local database. function deleteFile($fields) { global $i18n; @@ -424,110 +481,6 @@ static function getEntityFiles($id, $type) { return $result; } - // get - obtains file details from local database. - static function get($id) { - global $user; - $mdb2 = getConnection(); - - $group_id = $user->getGroup(); - $org_id = $user->org_id; - - $sql = "select id, remote_id, file_key, entity_type, entity_id, file_name, description, status from tt_files". - " where id = $id and group_id = $group_id and org_id = $org_id and (status = 0 or status = 1)"; - $res = $mdb2->query($sql); - if (!is_a($res, 'PEAR_Error')) { - $val = $res->fetchRow(); - if ($val && $val['id']) - return $val; - } - return false; - } - - // update - updates file details in local database. - static function update($fields) { - global $user; - $mdb2 = getConnection(); - - $group_id = $user->getGroup(); - $org_id = $user->org_id; - - $file_id = (int) $fields['id']; - $description = $mdb2->quote($fields['description']); - - $sql = "update tt_files set description = $description where id = $file_id". - " and group_id = $group_id and org_id = $org_id and (status = 0 or status = 1)"; - $affected = $mdb2->exec($sql); - return !is_a($affected, 'PEAR_Error'); - } - - - // getFile - downloads file from remote storage to memory. - function getFile($fields) { - global $i18n; - global $user; - $mdb2 = getConnection(); - - $group_id = $user->getGroup(); - $org_id = $user->org_id; - - $curl_fields = array('site_id' => urlencode($this->site_id), - 'site_key' => urlencode($this->site_key), - 'org_id' => urlencode($org_id), - 'org_key' => urlencode($this->getOrgKey()), - 'group_id' => urlencode($group_id), - 'group_key' => urlencode($this->getGroupKey()), - 'entity_type' => urlencode($fields['entity_type']), - 'entity_id' => urlencode($fields['entity_id']), - 'file_id' => urlencode($fields['remote_id']), - 'file_key' => urlencode($fields['file_key']), - 'file_name' => urlencode($fields['file_name'])); - - // url-ify the data for the POST. - foreach($curl_fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; } - $fields_string = rtrim($fields_string, '&'); - - // Open connection. - $ch = curl_init(); - - // Set the url, number of POST vars, POST data. - curl_setopt($ch, CURLOPT_URL, $this->getfile_uri); - curl_setopt($ch, CURLOPT_POST, true); - curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - - // Execute a post request. - $result = curl_exec($ch); - - $error = curl_error(); - $result_array2 = json_decode($result, true); - - // Close connection. - curl_close($ch); - - if (!$result) { - $this->errors->add($i18n->get('error.file_storage')); - return false; - } - - $result_array = json_decode($result, true); - $status = (int) $result_array['status']; - $error = $result_array['error']; - - if ($error) { - // Add an error from file storage facility if we have it. - $this->errors->add($error); - return false; - } - if ($status != 1) { - // There is no explicit error message, but still something not right. - $this->errors->add($i18n->get('error.file_storage')); - return false; - } - - $this->file_data = $result_array['content']; - return true; - } - // getFileData - returns file data from memory. function getFileData() { diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 02eadcc7b..07c502626 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.19.9.5056 | Copyright © Anuko | +  Anuko Time Tracker 1.19.9.5057 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 1817dfb91ad4aed4ae1b54763df91045549d08be Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 10 Sep 2019 12:42:55 +0000 Subject: [PATCH 046/877] Added localization strings for remote work plugin. --- WEB-INF/resources/ca.lang.php | 5 +++++ WEB-INF/resources/cs.lang.php | 5 +++++ WEB-INF/resources/da.lang.php | 6 +++++- WEB-INF/resources/en.lang.php | 4 ++++ WEB-INF/resources/es.lang.php | 5 +++++ WEB-INF/resources/et.lang.php | 5 +++++ WEB-INF/resources/fa.lang.php | 5 +++++ WEB-INF/resources/fi.lang.php | 5 +++++ WEB-INF/resources/fr.lang.php | 5 +++++ WEB-INF/resources/gr.lang.php | 5 +++++ WEB-INF/resources/he.lang.php | 5 +++++ WEB-INF/resources/hu.lang.php | 5 +++++ WEB-INF/resources/it.lang.php | 5 +++++ WEB-INF/resources/ja.lang.php | 5 +++++ WEB-INF/resources/ko.lang.php | 5 +++++ WEB-INF/resources/nl.lang.php | 5 +++++ WEB-INF/resources/no.lang.php | 5 +++++ WEB-INF/resources/pl.lang.php | 5 +++++ WEB-INF/resources/pt-br.lang.php | 5 +++++ WEB-INF/resources/pt.lang.php | 5 +++++ WEB-INF/resources/ro.lang.php | 5 +++++ WEB-INF/resources/ru.lang.php | 4 ++++ WEB-INF/resources/sk.lang.php | 5 +++++ WEB-INF/resources/sl.lang.php | 5 +++++ WEB-INF/resources/sr.lang.php | 5 +++++ WEB-INF/resources/sv.lang.php | 5 +++++ WEB-INF/resources/tr.lang.php | 5 +++++ WEB-INF/resources/zh-cn.lang.php | 5 +++++ WEB-INF/resources/zh-tw.lang.php | 5 +++++ WEB-INF/templates/footer.tpl | 2 +- 30 files changed, 144 insertions(+), 2 deletions(-) diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index 93f7b66b7..066274cd0 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -682,4 +682,9 @@ // TODO: translate the following. // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', + +// Work form. See example at https://timetracker.anuko.com/work.php +// TODO: translate the following. +// 'form.work.work_items' => 'Work Items', +// 'form.work.offers' => 'Offers', ); diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index 9ca5f2153..a948e11d6 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -695,4 +695,9 @@ // TODO: translate the following. // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', + +// Work form. See example at https://timetracker.anuko.com/work.php +// TODO: translate the following. +// 'form.work.work_items' => 'Work Items', +// 'form.work.offers' => 'Offers', ); diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index b4f29f19b..cd52e5a0f 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -655,5 +655,9 @@ // TODO: translate the following. // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', -); +// Work form. See example at https://timetracker.anuko.com/work.php +// TODO: translate the following. +// 'form.work.work_items' => 'Work Items', +// 'form.work.offers' => 'Offers', +); diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index 45e8b8b12..545a48bf1 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -605,4 +605,8 @@ // Display Options form. See example at https://timetracker.anuko.com/display_options.php. 'form.display_options.menu' => 'Menu', 'form.display_options.note_on_separate_row' => 'Note on separate row', + +// Work form. See example at https://timetracker.anuko.com/work.php +'form.work.work_items' => 'Work Items', +'form.work.offers' => 'Offers', ); diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index ce4d0693f..7162c6602 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -697,4 +697,9 @@ // TODO: translate the following. // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', + +// Work form. See example at https://timetracker.anuko.com/work.php +// TODO: translate the following. +// 'form.work.work_items' => 'Work Items', +// 'form.work.offers' => 'Offers', ); diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index 7121ee449..2167bd313 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -662,4 +662,9 @@ // TODO: translate the following. // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', + +// Work form. See example at https://timetracker.anuko.com/work.php +// TODO: translate the following. +// 'form.work.work_items' => 'Work Items', +// 'form.work.offers' => 'Offers', ); diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index 404eb6463..4fc605a31 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -679,4 +679,9 @@ // TODO: translate the following. // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', + +// Work form. See example at https://timetracker.anuko.com/work.php +// TODO: translate the following. +// 'form.work.work_items' => 'Work Items', +// 'form.work.offers' => 'Offers', ); diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 592dfab2c..4621b9fa0 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -661,4 +661,9 @@ // TODO: translate the following. // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', + +// Work form. See example at https://timetracker.anuko.com/work.php +// TODO: translate the following. +// 'form.work.work_items' => 'Work Items', +// 'form.work.offers' => 'Offers', ); diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index a5974fafc..e2a9489e8 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -651,4 +651,9 @@ // TODO: translate the following. // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', + +// Work form. See example at https://timetracker.anuko.com/work.php +// TODO: translate the following. +// 'form.work.work_items' => 'Work Items', +// 'form.work.offers' => 'Offers', ); diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index a362fc7d8..cc10a876d 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -644,4 +644,9 @@ // TODO: translate the following. // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', + +// Work form. See example at https://timetracker.anuko.com/work.php +// TODO: translate the following. +// 'form.work.work_items' => 'Work Items', +// 'form.work.offers' => 'Offers', ); diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index e18d474b2..a9ab58f8d 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -681,4 +681,9 @@ // TODO: translate the following. // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', + +// Work form. See example at https://timetracker.anuko.com/work.php +// TODO: translate the following. +// 'form.work.work_items' => 'Work Items', +// 'form.work.offers' => 'Offers', ); diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index 4bd340fff..b76ce4096 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -687,4 +687,9 @@ // TODO: translate the following. // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', + +// Work form. See example at https://timetracker.anuko.com/work.php +// TODO: translate the following. +// 'form.work.work_items' => 'Work Items', +// 'form.work.offers' => 'Offers', ); diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index 91177ed08..fab45d0fd 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -658,4 +658,9 @@ // TODO: translate the following. // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', + +// Work form. See example at https://timetracker.anuko.com/work.php +// TODO: translate the following. +// 'form.work.work_items' => 'Work Items', +// 'form.work.offers' => 'Offers', ); diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index a627219ff..be759566c 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -690,4 +690,9 @@ // TODO: translate the following. // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', + +// Work form. See example at https://timetracker.anuko.com/work.php +// TODO: translate the following. +// 'form.work.work_items' => 'Work Items', +// 'form.work.offers' => 'Offers', ); diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index c8656b94d..569aac303 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -688,4 +688,9 @@ // TODO: translate the following. // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', + +// Work form. See example at https://timetracker.anuko.com/work.php +// TODO: translate the following. +// 'form.work.work_items' => 'Work Items', +// 'form.work.offers' => 'Offers', ); diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 0726b427d..5819c5d43 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -606,4 +606,9 @@ // Display Options form. See example at https://timetracker.anuko.com/display_options.php. 'form.display_options.menu' => 'Menu', 'form.display_options.note_on_separate_row' => 'Notitie in aparte kolom', + +// Work form. See example at https://timetracker.anuko.com/work.php +// TODO: translate the following. +// 'form.work.work_items' => 'Work Items', +// 'form.work.offers' => 'Offers', ); diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index 78f7d0583..d87c68fd9 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -687,4 +687,9 @@ // TODO: translate the following. // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', + +// Work form. See example at https://timetracker.anuko.com/work.php +// TODO: translate the following. +// 'form.work.work_items' => 'Work Items', +// 'form.work.offers' => 'Offers', ); diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index e2a807246..f26b35875 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -664,4 +664,9 @@ // TODO: translate the following. // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', + +// Work form. See example at https://timetracker.anuko.com/work.php +// TODO: translate the following. +// 'form.work.work_items' => 'Work Items', +// 'form.work.offers' => 'Offers', ); diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index 7bff5c1ff..bd6c6b9f0 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -659,4 +659,9 @@ // TODO: translate the following. // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', + +// Work form. See example at https://timetracker.anuko.com/work.php +// TODO: translate the following. +// 'form.work.work_items' => 'Work Items', +// 'form.work.offers' => 'Offers', ); diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index 9dd84ea19..43f0e5feb 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -669,4 +669,9 @@ // TODO: translate the following. // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', + +// Work form. See example at https://timetracker.anuko.com/work.php +// TODO: translate the following. +// 'form.work.work_items' => 'Work Items', +// 'form.work.offers' => 'Offers', ); diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index 537b64885..3162a7e12 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -690,4 +690,9 @@ // TODO: translate the following. // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', + +// Work form. See example at https://timetracker.anuko.com/work.php +// TODO: translate the following. +// 'form.work.work_items' => 'Work Items', +// 'form.work.offers' => 'Offers', ); diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index 6e9aef1b4..65aa01b70 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -597,4 +597,8 @@ // Display Options form. See example at https://timetracker.anuko.com/display_options.php. 'form.display_options.menu' => 'Меню', 'form.display_options.note_on_separate_row' => 'Комментарий в отдельном ряду', + +// Work form. See example at https://timetracker.anuko.com/work.php +'form.work.work_items' => 'Единицы работы', +'form.work.offers' => 'Предложения', ); diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index 6a54b2649..b3d1adb04 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -670,4 +670,9 @@ // TODO: translate the following. // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', + +// Work form. See example at https://timetracker.anuko.com/work.php +// TODO: translate the following. +// 'form.work.work_items' => 'Work Items', +// 'form.work.offers' => 'Offers', ); diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index 579646eb0..9dd668d49 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -663,4 +663,9 @@ // TODO: translate the following. // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', + +// Work form. See example at https://timetracker.anuko.com/work.php +// TODO: translate the following. +// 'form.work.work_items' => 'Work Items', +// 'form.work.offers' => 'Offers', ); diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index 8591a93cf..c0936c1a5 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -662,4 +662,9 @@ // TODO: translate the following. // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', + +// Work form. See example at https://timetracker.anuko.com/work.php +// TODO: translate the following. +// 'form.work.work_items' => 'Work Items', +// 'form.work.offers' => 'Offers', ); diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index d43ebc7f0..ade86f7d4 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -660,4 +660,9 @@ // TODO: translate the following. // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', + +// Work form. See example at https://timetracker.anuko.com/work.php +// TODO: translate the following. +// 'form.work.work_items' => 'Work Items', +// 'form.work.offers' => 'Offers', ); diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index d37fde559..2935878fe 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -703,4 +703,9 @@ // TODO: translate the following. // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', + +// Work form. See example at https://timetracker.anuko.com/work.php +// TODO: translate the following. +// 'form.work.work_items' => 'Work Items', +// 'form.work.offers' => 'Offers', ); diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index 64724ed31..5d87497ce 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -674,4 +674,9 @@ // TODO: translate the following. // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', + +// Work form. See example at https://timetracker.anuko.com/work.php +// TODO: translate the following. +// 'form.work.work_items' => 'Work Items', +// 'form.work.offers' => 'Offers', ); diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index cfde64db6..aabfbc9dc 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -680,4 +680,9 @@ // TODO: translate the following. // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', + +// Work form. See example at https://timetracker.anuko.com/work.php +// TODO: translate the following. +// 'form.work.work_items' => 'Work Items', +// 'form.work.offers' => 'Offers', ); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 07c502626..2fcd9677a 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.19.9.5057 | Copyright © Anuko | +  Anuko Time Tracker 1.19.9.5058 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From a9abc90ac8ee59759088cf554e23f8443eb0f804 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 12 Sep 2019 17:34:42 +0000 Subject: [PATCH 047/877] Dutch translation improved. --- WEB-INF/resources/nl.lang.php | 54 +++++++++++++++++------------------ WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/work.tpl | 4 +-- work.php | 3 ++ 4 files changed, 32 insertions(+), 31 deletions(-) diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 5819c5d43..a80b80f0e 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -42,8 +42,7 @@ 'menu.logout' => 'Afmelden', 'menu.forum' => 'Forum', 'menu.help' => 'Help', -// TODO: translate the following. -// 'menu.register' => 'Register', +'menu.register' => 'Registreren', 'menu.profile' => 'Profiel', 'menu.group' => 'Groep', 'menu.plugins' => 'Plugins', @@ -104,9 +103,17 @@ 'error.format' => 'Bestandsformaat niet valide.', 'error.user_count' => 'Limiet op aantal gebruikers.', 'error.expired' => 'Verloop datum is bereikt.', +// TODO: improve translations of both error.file_storage and error.remote_work. +// Both file starage and remote work (freelance) are implemented in external facilities, +// which are standalone applications out of scope of Time Tracker itseld. +// +// error.file_storage means that something happened in a remote file storage server. +// error.remote_work means that something happened in a remote work server +// see documentation for remote work plugin, currently under development). +// Remote work plugin is designed to outsource work to other groups, when one group +// hires another group to do something (under development at the moment). 'error.file_storage' => 'Fout bij het opslaan van het bestand.', -// TODO: translate the following. -// 'error.remote_work' => 'Remote work server error.', +'error.remote_work' => 'Fout in de server.', // Warning messages. 'warn.sure' => 'Ben je er zeker van?', @@ -213,27 +220,24 @@ 'label.condition' => 'Voorwaarde', 'label.yes' => 'ja', 'label.no' => 'nee', -// TODO: translate the following. -// 'label.sort' => 'Sort', +'label.sort' => 'Sorteren', // Labels for plugins (extensions to Time Tracker that provide additional features). 'label.custom_fields' => 'Eigen velden', 'label.monthly_quotas' => 'Doelen per maand', -// TODO: translate the following. -// 'label.entity' => 'Entity', +'label.entity' => 'Entiteit', 'label.type' => 'Type', 'label.type_dropdown' => 'uitklapbaar', 'label.type_text' => 'tekst', 'label.required' => 'Verplicht veld', 'label.fav_report' => 'Standaard rapport', 'label.schedule' => 'Planning', -'label.what_is_it' => 'Wat betekent dit?', +'label.what_is_it' => 'Meer informatie', 'label.expense' => 'Kosten', 'label.quantity' => 'Hoeveelheid', 'label.paid_status' => 'Status van betaling', 'label.paid' => 'Betaald', 'label.mark_paid' => 'Markeer als betaald', -// TODO: translate the following. -// 'label.week_menu' => 'Week menu', +'label.week_menu' => 'Week menu', 'label.week_note' => 'Week aantekening', 'label.week_list' => 'Week overzicht', 'label.work_units' => 'Werk eenheid', @@ -254,12 +258,10 @@ 'label.active_users' => 'Actieve medewerkers', 'label.inactive_users' => 'Inactieve medewerkers', -// Entity names. We use lower case (in English) because they are used in dropdowns, too. -// They are used to associate a custom field with an entity type. -// TODO: translate the following. -// 'entity.time' => 'time', -// 'entity.user' => 'user', -// 'entity.project' => 'project', +// Entity names. +'entity.time' => 'tijd', +'entity.user' => 'medewerker', +'entity.project' => 'project', // Form titles. 'title.error' => 'Fout', @@ -388,9 +390,8 @@ 'dropdown.not_approved' => 'afgekeurd', 'dropdown.paid' => 'betaald', 'dropdown.not_paid' => 'niet betaald', -// TODO: translate the following. -// 'dropdown.ascending' => 'ascending', -// 'dropdown.descending' => 'descending', +'dropdown.ascending' => 'oplopend', +'dropdown.descending' => 'aflopend', // Below is a section for strings that are used on individual forms. When a string is used only on one form it should be placed here. // One exception is for closely related forms such as "Time" and "Editing Time Record" with similar controls. In such cases @@ -437,9 +438,8 @@ 'form.reports.select_period' => 'Kies periode', 'form.reports.set_period' => 'of stel datums in', 'form.reports.show_fields' => 'Toon velden', -// TODO: translate the following. -// 'form.reports.time_fields' => 'Time fields', -// 'form.reports.user_fields' => 'User fields', +'form.reports.time_fields' => 'Tijd velden', +'form.reports.user_fields' => 'Mederwerker velden', 'form.reports.group_by' => 'Groeperen op', 'form.reports.group_by_no' => '--- niet groeperen ---', 'form.reports.group_by_date' => 'datum', @@ -544,8 +544,7 @@ 'form.group_edit.uncompleted_indicators' => 'Onvolledige indicatoren', 'form.group_edit.confirm_save' => 'Bevestigen dat je wilt opslaan', 'form.group_edit.allow_ip' => 'Toegestane IP adressen', -// TODO: translate the following. -// 'form.group_edit.advanced_settings' => 'Advanced settings', +'form.group_edit.advanced_settings' => 'Geavanceerde instellingen', // Deleting Group form. See example at https://timetracker.anuko.com/delete_group.php 'form.group_delete.hint' => 'Bent u er zeker van dat u de hele groep wilt verwijderen?', @@ -608,7 +607,6 @@ 'form.display_options.note_on_separate_row' => 'Notitie in aparte kolom', // Work form. See example at https://timetracker.anuko.com/work.php -// TODO: translate the following. -// 'form.work.work_items' => 'Work Items', -// 'form.work.offers' => 'Offers', +'form.work.work_items' => 'Onderdelen werk', +'form.work.offers' => 'Aanbiedingen', ); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 2fcd9677a..fcc5d5b9d 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.19.9.5058 | Copyright © Anuko | +  Anuko Time Tracker 1.19.9.5059 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/work.tpl b/WEB-INF/templates/work.tpl index af2a7c420..447b5b2a7 100644 --- a/WEB-INF/templates/work.tpl +++ b/WEB-INF/templates/work.tpl @@ -7,8 +7,8 @@ {if $user->can('manage_work')} - {if $inactive_work} - + {if !$inactive_work} + {/if} {if $active_work} diff --git a/work.php b/work.php index 60a8f7c8b..da7b20c18 100644 --- a/work.php +++ b/work.php @@ -51,12 +51,15 @@ // $in_progress_work = ttWorkHelper::getInProgressWork(); // Work items in progress for other groups. // $completed_work = ttWorkHelper::getCompletedWork(); // Completed work items for other groups. } +// $available_offers = ttWorkHelper::getAvailableOffers(); // Currently available offers to do work. +// TODO: review access rights for the code above. $smarty->assign('active_work', $active_work); $smarty->assign('inactive_work', $inactive_work); $smarty->assign('available_work', $available_work); $smarty->assign('in_progress_work', $in_progress_work); $smarty->assign('completed_work', $completed_work); +$smarty->assign('available_offers', $available_offers); $smarty->assign('title', $i18n->get('title.work')); $smarty->assign('content_page_name', 'work.tpl'); $smarty->display('index.tpl'); From 0ac0111a64ea1452ed5ccc8290f3de3b328940ba Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 12 Sep 2019 17:38:23 +0000 Subject: [PATCH 048/877] Fixed a typo. --- WEB-INF/resources/nl.lang.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index a80b80f0e..c0264d5cc 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -105,7 +105,7 @@ 'error.expired' => 'Verloop datum is bereikt.', // TODO: improve translations of both error.file_storage and error.remote_work. // Both file starage and remote work (freelance) are implemented in external facilities, -// which are standalone applications out of scope of Time Tracker itseld. +// which are standalone applications out of scope of Time Tracker itself. // // error.file_storage means that something happened in a remote file storage server. // error.remote_work means that something happened in a remote work server From ee76734a38a171461a0996dde349e6365ec9f995 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 12 Sep 2019 18:08:57 +0000 Subject: [PATCH 049/877] Fixed a typo. --- WEB-INF/resources/nl.lang.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index c0264d5cc..14f08bb77 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -104,7 +104,7 @@ 'error.user_count' => 'Limiet op aantal gebruikers.', 'error.expired' => 'Verloop datum is bereikt.', // TODO: improve translations of both error.file_storage and error.remote_work. -// Both file starage and remote work (freelance) are implemented in external facilities, +// Both file storage and remote work (freelance) are implemented in external facilities, // which are standalone applications out of scope of Time Tracker itself. // // error.file_storage means that something happened in a remote file storage server. From b0e334e90797f1c4faeaa3b67284b96e80a4f40b Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 12 Sep 2019 23:53:27 +0000 Subject: [PATCH 050/877] Some progress on remote work plugin. --- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/work.tpl | 63 +++++++----------------------------- 2 files changed, 13 insertions(+), 52 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index fcc5d5b9d..63eaecb4c 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
{$i18n.title.active_work}
{$i18n.form.work.offers}
-
 Anuko Time Tracker 1.19.9.5059 | Copyright © Anuko | +  Anuko Time Tracker 1.19.9.5060 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/work.tpl b/WEB-INF/templates/work.tpl index 447b5b2a7..164600a52 100644 --- a/WEB-INF/templates/work.tpl +++ b/WEB-INF/templates/work.tpl @@ -5,11 +5,8 @@
-{if $user->can('manage_work')} - {if !$inactive_work} - - {/if} + {if $active_work} @@ -23,15 +20,8 @@ {foreach $active_work as $work_item} - {if $show_files} - {if $project.has_files} - - {else} - - {/if} - {/if} - - + + {/foreach} {/if} @@ -45,9 +35,9 @@
{$i18n.form.work.offers}
{$i18n.title.active_work}
{$i18n.label.thing_name}
{$work_item.name|escape}{$i18n.label.files}{$i18n.label.files}{$i18n.label.edit}{$i18n.label.delete}{$i18n.label.edit}{$i18n.label.delete}
- {if $inactive_projects} - + + {if $available_offers} @@ -57,53 +47,24 @@ - {foreach $inactive_projects as $project} + {foreach $available_offers as $offer} - - - {if $show_files} - {if $project.has_files} - - {else} - - {/if} - {/if} - - + + + {/foreach} + {/if}
{$i18n.form.projects.inactive_projects}
{$i18n.form.work.offers}
{$i18n.label.thing_name} {$i18n.label.description}
{$project.name|escape}{$project.description|escape}{$i18n.label.files}{$i18n.label.files}{$i18n.label.edit}{$i18n.label.delete}{$offer.name|escape}{$i18n.label.edit}{$i18n.label.delete}

-
+
- {/if} -{else} - - - - - {if $show_files} - - {/if} - - {if $active_projects} - {foreach $active_projects as $project} - - - - {if $show_files && $project.has_files} - - {/if} - - {/foreach} - {/if} -
{$i18n.label.thing_name}{$i18n.label.description}
{$project.name|escape}{$project.description|escape}{$i18n.label.files}
-{/if} +
From c20de83bc9b0b370070afa935bffd39fcaae3a03 Mon Sep 17 00:00:00 2001 From: danklee19 <49231594+danklee19@users.noreply.github.com> Date: Sat, 14 Sep 2019 20:31:34 +0200 Subject: [PATCH 051/877] Update ttTimeHelper.class.php (#77) For showing custom field on 'time' page modified SQL-Statements --- WEB-INF/lib/ttTimeHelper.class.php | 63 +++++++++++++++++++++++++++++- 1 file changed, 62 insertions(+), 1 deletion(-) diff --git a/WEB-INF/lib/ttTimeHelper.class.php b/WEB-INF/lib/ttTimeHelper.class.php index 29010036c..6f4906646 100644 --- a/WEB-INF/lib/ttTimeHelper.class.php +++ b/WEB-INF/lib/ttTimeHelper.class.php @@ -859,6 +859,45 @@ static function getRecords($date, $includeFiles = false) { if ($user->isPluginEnabled('cl')) $client_field = ", c.name as client"; + if ($user->isPluginEnabled('cf')) { +// require_once('plugins/CustomFields.class.php'); + global $custom_fields; + if (!$custom_fields) $custom_fields = new CustomFields(); + } + $fields = array(); + +// print_r($custom_fields); + + if ($custom_fields && $custom_fields->timeFields) { + foreach ($custom_fields->timeFields as $timeField) { +// print_r($timeField); + $field_name = 'time_field_'.$timeField['id']; +// $checkbox_field_name = 'show_'.$field_name; +// if ($options[$checkbox_field_name]) { + if ($timeField['type'] == CustomFields::TYPE_TEXT) { + $cflTable = 'cfl'.$timeField['id']; + array_push($fields, "$cflTable.value as $field_name"); + } elseif ($timeField['type'] == CustomFields::TYPE_DROPDOWN) { + $cfoTable = 'cfo'.$timeField['id']; + array_push($fields, "$cfoTable.value as $field_name"); + } +// } + } + } + +// print_r($fields); + + +/* if ($custom_fields && $custom_fields->timeFields) { + foreach ($custom_fields->timeFields as $timeField) { + $field_name = 'time_field_'.$timeField['id']; + $checkbox_field_name = 'show_'.$field_name; + if ($options[$checkbox_field_name]) { + array_push($fields, "null as $field_name"); // null for each time custom field. + } + } + } +*/ /* $include_cf_1 = $user->isPluginEnabled('cf'); if ($include_cf_1) { @@ -882,6 +921,27 @@ static function getRecords($date, $includeFiles = false) { " left join tt_tasks t on (l.task_id = t.id)"; if ($user->isPluginEnabled('cl')) $left_joins .= " left join tt_clients c on (l.client_id = c.id)"; + + if ($custom_fields && $custom_fields->timeFields) { + foreach ($custom_fields->timeFields as $timeField) { + $field_name = 'time_field_'.$timeField['id']; +// $checkbox_field_name = 'show_'.$field_name; +// if ($options[$field_name] || $options[$checkbox_field_name]) { + $cflTable = 'cfl'.$timeField['id']; + if ($timeField['type'] == CustomFields::TYPE_TEXT) { + // Add one join for each text field. + $left_joins .= " left join tt_custom_field_log $cflTable on ($cflTable.log_id = l.id and $cflTable.status = 1 and $cflTable.field_id = ".$timeField['id'].')'; + } elseif ($timeField['type'] == CustomFields::TYPE_DROPDOWN) { + $cfoTable = 'cfo'.$timeField['id']; + // Add two joins for each dropdown field. + $left_joins .= " left join tt_custom_field_log $cflTable on ($cflTable.log_id = l.id and $cflTable.status = 1 and $cflTable.field_id = ".$timeField['id'].')'; + $left_joins .= " left join tt_custom_field_options $cfoTable on ($cfoTable.field_id = $cflTable.field_id and $cfoTable.id = $cflTable.option_id)"; + } +// } + } + } +// print_r($cfoTable); + /* Multiple left joins are now required, probably with config options which fields to show. * if ($include_cf_1) { if ($cf_1_type == CustomFields::TYPE_TEXT) @@ -897,9 +957,10 @@ static function getRecords($date, $includeFiles = false) { $sql = "select l.id as id, TIME_FORMAT(l.start, $sql_time_format) as start,". " TIME_FORMAT(sec_to_time(time_to_sec(l.start) + time_to_sec(l.duration)), $sql_time_format) as finish,". " TIME_FORMAT(l.duration, '%k:%i') as duration, p.name as project, t.name as task, l.comment,". - " l.billable, l.approved, l.timesheet_id, l.invoice_id $client_field $custom_field $filePart from tt_log l $left_joins". + " l.billable, l.approved, l.timesheet_id, l.invoice_id $client_field ,".join(', ', $fields)." $filePart from tt_log l $left_joins". " where l.date = '$date' and l.user_id = $user_id and l.group_id = $group_id and l.org_id = $org_id and l.status = 1". " order by l.start, l.id"; +// echo $sql; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { while ($val = $res->fetchRow()) { From aaf6e4129e253cc9fc092390aade86dff0e565e5 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 14 Sep 2019 18:55:09 +0000 Subject: [PATCH 052/877] Fixed SQL query broken in pr#77 (ttTimeHelper::getRecords when Custom Fields plugin is disabled). --- WEB-INF/lib/ttTimeHelper.class.php | 87 ++++++++---------------------- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 22 insertions(+), 67 deletions(-) diff --git a/WEB-INF/lib/ttTimeHelper.class.php b/WEB-INF/lib/ttTimeHelper.class.php index 6f4906646..043e43462 100644 --- a/WEB-INF/lib/ttTimeHelper.class.php +++ b/WEB-INF/lib/ttTimeHelper.class.php @@ -860,56 +860,25 @@ static function getRecords($date, $includeFiles = false) { $client_field = ", c.name as client"; if ($user->isPluginEnabled('cf')) { -// require_once('plugins/CustomFields.class.php'); global $custom_fields; if (!$custom_fields) $custom_fields = new CustomFields(); + $time_fields_array = array(); } - $fields = array(); - -// print_r($custom_fields); if ($custom_fields && $custom_fields->timeFields) { foreach ($custom_fields->timeFields as $timeField) { -// print_r($timeField); $field_name = 'time_field_'.$timeField['id']; -// $checkbox_field_name = 'show_'.$field_name; -// if ($options[$checkbox_field_name]) { - if ($timeField['type'] == CustomFields::TYPE_TEXT) { - $cflTable = 'cfl'.$timeField['id']; - array_push($fields, "$cflTable.value as $field_name"); - } elseif ($timeField['type'] == CustomFields::TYPE_DROPDOWN) { - $cfoTable = 'cfo'.$timeField['id']; - array_push($fields, "$cfoTable.value as $field_name"); - } -// } + if ($timeField['type'] == CustomFields::TYPE_TEXT) { + $cflTable = 'cfl'.$timeField['id']; + array_push($time_fields_array, "$cflTable.value as $field_name"); + } elseif ($timeField['type'] == CustomFields::TYPE_DROPDOWN) { + $cfoTable = 'cfo'.$timeField['id']; + array_push($time_fields_array, "$cfoTable.value as $field_name"); + } } + $time_fields = ", ".join(', ', $time_fields_array); } -// print_r($fields); - - -/* if ($custom_fields && $custom_fields->timeFields) { - foreach ($custom_fields->timeFields as $timeField) { - $field_name = 'time_field_'.$timeField['id']; - $checkbox_field_name = 'show_'.$field_name; - if ($options[$checkbox_field_name]) { - array_push($fields, "null as $field_name"); // null for each time custom field. - } - } - } -*/ - /* - $include_cf_1 = $user->isPluginEnabled('cf'); - if ($include_cf_1) { - $custom_fields = new CustomFields(); - $cf_1_type = $custom_fields->fields[0]['type']; - if ($cf_1_type == CustomFields::TYPE_TEXT) { - $custom_field = ", cfl.value as cf_1"; - } elseif ($cf_1_type == CustomFields::TYPE_DROPDOWN) { - $custom_field = ", cfo.value as cf_1"; - } - }*/ - if ($includeFiles) { $filePart = ', if(Sub1.entity_id is null, 0, 1) as has_files'; $fileJoin = " left join (select distinct entity_id from tt_files". @@ -925,42 +894,28 @@ static function getRecords($date, $includeFiles = false) { if ($custom_fields && $custom_fields->timeFields) { foreach ($custom_fields->timeFields as $timeField) { $field_name = 'time_field_'.$timeField['id']; -// $checkbox_field_name = 'show_'.$field_name; -// if ($options[$field_name] || $options[$checkbox_field_name]) { - $cflTable = 'cfl'.$timeField['id']; - if ($timeField['type'] == CustomFields::TYPE_TEXT) { - // Add one join for each text field. - $left_joins .= " left join tt_custom_field_log $cflTable on ($cflTable.log_id = l.id and $cflTable.status = 1 and $cflTable.field_id = ".$timeField['id'].')'; - } elseif ($timeField['type'] == CustomFields::TYPE_DROPDOWN) { - $cfoTable = 'cfo'.$timeField['id']; - // Add two joins for each dropdown field. - $left_joins .= " left join tt_custom_field_log $cflTable on ($cflTable.log_id = l.id and $cflTable.status = 1 and $cflTable.field_id = ".$timeField['id'].')'; - $left_joins .= " left join tt_custom_field_options $cfoTable on ($cfoTable.field_id = $cflTable.field_id and $cfoTable.id = $cflTable.option_id)"; - } -// } + $cflTable = 'cfl'.$timeField['id']; + if ($timeField['type'] == CustomFields::TYPE_TEXT) { + // Add one join for each text field. + $left_joins .= " left join tt_custom_field_log $cflTable on ($cflTable.log_id = l.id and $cflTable.status = 1 and $cflTable.field_id = ".$timeField['id'].')'; + } elseif ($timeField['type'] == CustomFields::TYPE_DROPDOWN) { + $cfoTable = 'cfo'.$timeField['id']; + // Add two joins for each dropdown field. + $left_joins .= " left join tt_custom_field_log $cflTable on ($cflTable.log_id = l.id and $cflTable.status = 1 and $cflTable.field_id = ".$timeField['id'].')'; + $left_joins .= " left join tt_custom_field_options $cfoTable on ($cfoTable.field_id = $cflTable.field_id and $cfoTable.id = $cflTable.option_id)"; + } } } -// print_r($cfoTable); - - /* Multiple left joins are now required, probably with config options which fields to show. - * if ($include_cf_1) { - if ($cf_1_type == CustomFields::TYPE_TEXT) - $left_joins .= " left join tt_custom_field_log cfl on (l.id = cfl.log_id and cfl.status = 1)"; - elseif ($cf_1_type == CustomFields::TYPE_DROPDOWN) { - $left_joins .= " left join tt_custom_field_log cfl on (l.id = cfl.log_id and cfl.status = 1)". - " left join tt_custom_field_options cfo on (cfl.option_id = cfo.id)"; - } - }*/ + $left_joins .= $fileJoin; $result = array(); $sql = "select l.id as id, TIME_FORMAT(l.start, $sql_time_format) as start,". " TIME_FORMAT(sec_to_time(time_to_sec(l.start) + time_to_sec(l.duration)), $sql_time_format) as finish,". " TIME_FORMAT(l.duration, '%k:%i') as duration, p.name as project, t.name as task, l.comment,". - " l.billable, l.approved, l.timesheet_id, l.invoice_id $client_field ,".join(', ', $fields)." $filePart from tt_log l $left_joins". + " l.billable, l.approved, l.timesheet_id, l.invoice_id $client_field $time_fields $filePart from tt_log l $left_joins". " where l.date = '$date' and l.user_id = $user_id and l.group_id = $group_id and l.org_id = $org_id and l.status = 1". " order by l.start, l.id"; -// echo $sql; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { while ($val = $res->fetchRow()) { diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 63eaecb4c..aa57f3dcb 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.19.9.5060 | Copyright © Anuko | +  Anuko Time Tracker 1.19.9.5061 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From c96ec4a581b6733e7ae2a9bf7d5fc1344b1022f9 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 14 Sep 2019 21:08:47 +0000 Subject: [PATCH 053/877] Added label.details to translation files for Remote Work plugin. --- WEB-INF/resources/ca.lang.php | 1 + WEB-INF/resources/cs.lang.php | 1 + WEB-INF/resources/da.lang.php | 2 ++ WEB-INF/resources/de.lang.php | 2 ++ WEB-INF/resources/en.lang.php | 1 + WEB-INF/resources/es.lang.php | 1 + WEB-INF/resources/et.lang.php | 2 ++ WEB-INF/resources/fa.lang.php | 2 ++ WEB-INF/resources/fi.lang.php | 2 ++ WEB-INF/resources/fr.lang.php | 2 ++ WEB-INF/resources/gr.lang.php | 2 ++ WEB-INF/resources/he.lang.php | 2 ++ WEB-INF/resources/hu.lang.php | 1 + WEB-INF/resources/it.lang.php | 2 ++ WEB-INF/resources/ja.lang.php | 1 + WEB-INF/resources/ko.lang.php | 1 + WEB-INF/resources/nl.lang.php | 2 ++ WEB-INF/resources/no.lang.php | 1 + WEB-INF/resources/pl.lang.php | 2 ++ WEB-INF/resources/pt-br.lang.php | 2 ++ WEB-INF/resources/pt.lang.php | 1 + WEB-INF/resources/ro.lang.php | 1 + WEB-INF/resources/ru.lang.php | 1 + WEB-INF/resources/sk.lang.php | 2 ++ WEB-INF/resources/sl.lang.php | 1 + WEB-INF/resources/sr.lang.php | 2 ++ WEB-INF/resources/sv.lang.php | 2 ++ WEB-INF/resources/tr.lang.php | 1 + WEB-INF/resources/zh-cn.lang.php | 1 + WEB-INF/resources/zh-tw.lang.php | 1 + WEB-INF/templates/footer.tpl | 2 +- 31 files changed, 46 insertions(+), 1 deletion(-) diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index 066274cd0..166c7b928 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -283,6 +283,7 @@ // 'label.download' => 'Download', // 'label.active_users' => 'Active Users', // 'label.inactive_users' => 'Inactive Users', +// 'label.details' => 'Details', // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index a948e11d6..527d14b95 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -293,6 +293,7 @@ // 'label.download' => 'Download', // 'label.active_users' => 'Active Users', // 'label.inactive_users' => 'Inactive Users', +// 'label.details' => 'Details', // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index cd52e5a0f..52236c9f7 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -273,6 +273,8 @@ // 'label.download' => 'Download', 'label.active_users' => 'Aktive Brugere', 'label.inactive_users' => 'Inaktive Brugere', +// TODO: translate the following. +// 'label.details' => 'Details', // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index 14f2c5097..66428e55e 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -263,6 +263,8 @@ // 'label.download' => 'Download', 'label.active_users' => 'Aktive Nutzer', 'label.inactive_users' => 'Inaktive Nutzer', +// TODO: translate the following. +// 'label.details' => 'Details', // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index 545a48bf1..0e10f3620 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -249,6 +249,7 @@ 'label.download' => 'Download', 'label.active_users' => 'Active Users', 'label.inactive_users' => 'Inactive Users', +'label.details' => 'Details', // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index 7162c6602..08e3f818c 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -286,6 +286,7 @@ // 'label.download' => 'Download', // 'label.active_users' => 'Active Users', // 'label.inactive_users' => 'Inactive Users', +// 'label.details' => 'Details', // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index 2167bd313..c93641a1c 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -280,6 +280,8 @@ // 'label.download' => 'Download', 'label.active_users' => 'Aktiivsed kasutajad', 'label.inactive_users' => 'Mitteaktiivsed kasutajad', +// TODO: translate the following. +// 'label.details' => 'Details', // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index 4fc605a31..ed9ea5b1c 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -284,6 +284,8 @@ // 'label.download' => 'Download', 'label.active_users' => 'کاربران فعال', 'label.inactive_users' => 'کاربران غیرفعال', +// TODO: translate the following. +// 'label.details' => 'Details', // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 4621b9fa0..718f53ce2 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -277,6 +277,8 @@ // 'label.download' => 'Download', 'label.active_users' => 'Aktiiviset käyttäjät', 'label.inactive_users' => 'Ei-aktiiviset käyttäjät', +// TODO: translate the following. +// 'label.details' => 'Details', // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index e2a9489e8..52c6f6b9e 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -271,6 +271,8 @@ // 'label.download' => 'Download', 'label.active_users' => 'Utilisateurs actifs', 'label.inactive_users' => 'Utilisateurs inactifs', +// TODO: translate the following. +// 'label.details' => 'Details', // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index cc10a876d..b6ae5e4d3 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -267,6 +267,8 @@ // 'label.download' => 'Download', 'label.active_users' => 'Ενεργοί χρήστες', 'label.inactive_users' => 'Ανενεργοί χρήστες', +// TODO: translate the following. +// 'label.details' => 'Details', // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index a9ab58f8d..6f47aa884 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -292,6 +292,8 @@ // 'label.download' => 'Download', 'label.active_users' => 'משתמשים פעילים', 'label.inactive_users' => 'משתמשים לא פעילים', +// TODO: translate the following. +// 'label.details' => 'Details', // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index b76ce4096..aa95b94c0 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -289,6 +289,7 @@ // 'label.download' => 'Download', // 'label.active_users' => 'Active Users', // 'label.inactive_users' => 'Inactive Users', +// 'label.details' => 'Details', // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index fab45d0fd..fc4c65219 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -271,6 +271,8 @@ // 'label.download' => 'Download', 'label.active_users' => 'Utenti attivi', 'label.inactive_users' => 'Utenti inattivi', +// TODO: translate the following. +// 'label.details' => 'Details', // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index be759566c..90a9d79c6 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -293,6 +293,7 @@ // 'label.download' => 'Download', // 'label.active_users' => 'Active Users', // 'label.inactive_users' => 'Inactive Users', +// 'label.details' => 'Details', // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index 569aac303..1cd6bf540 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -293,6 +293,7 @@ // 'label.download' => 'Download', // 'label.active_users' => 'Active Users', // 'label.inactive_users' => 'Inactive Users', +// 'label.details' => 'Details', // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 14f08bb77..a2b566772 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -257,6 +257,8 @@ 'label.download' => 'Download', 'label.active_users' => 'Actieve medewerkers', 'label.inactive_users' => 'Inactieve medewerkers', +// TODO: translate the following. +// 'label.details' => 'Details', // Entity names. 'entity.time' => 'tijd', diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index d87c68fd9..08d7b7f09 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -290,6 +290,7 @@ // 'label.download' => 'Download', // 'label.active_users' => 'Active Users', // 'label.inactive_users' => 'Inactive Users', +// 'label.details' => 'Details', // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index f26b35875..c7f88c94d 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -278,6 +278,8 @@ // 'label.download' => 'Download', 'label.active_users' => 'Aktywni użytkownicy', 'label.inactive_users' => 'Nieaktywni użytkownicy', +// TODO: translate the following. +// 'label.details' => 'Details', // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index bd6c6b9f0..70c1132b8 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -275,6 +275,8 @@ // 'label.download' => 'Download', 'label.active_users' => 'Usuários ativos', 'label.inactive_users' => 'Usuários inativos', +// TODO: translate the following. +// 'label.details' => 'Details', // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index 43f0e5feb..5e7959818 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -278,6 +278,7 @@ // 'label.download' => 'Download', // 'label.active_users' => 'Active Users', // 'label.inactive_users' => 'Inactive Users', +// 'label.details' => 'Details', // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index 3162a7e12..619c07c62 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -290,6 +290,7 @@ // 'label.download' => 'Download', // 'label.active_users' => 'Active Users', // 'label.inactive_users' => 'Inactive Users', +// 'label.details' => 'Details', // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index 65aa01b70..80f5f2bcf 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -248,6 +248,7 @@ 'label.download' => 'Скачать', 'label.active_users' => 'Активные пользователи', 'label.inactive_users' => 'Неактивные пользователи', +'label.details' => 'Детали', // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index b3d1adb04..f3d999153 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -282,6 +282,8 @@ // 'label.download' => 'Download', 'label.active_users' => 'Aktívny používatelia', 'label.inactive_users' => 'Neaktívny používatelia', +// TODO: translate the following. +// 'label.details' => 'Details', // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index 9dd668d49..d015bdbac 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -273,6 +273,7 @@ // 'label.download' => 'Download', // 'label.active_users' => 'Active Users', // 'label.inactive_users' => 'Inactive Users', +// 'label.details' => 'Details', // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index c0936c1a5..0cf827cfe 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -276,6 +276,8 @@ // 'label.download' => 'Download', 'label.active_users' => 'Aktivni korisnik', 'label.inactive_users' => 'Neaktivni korisnik', +// TODO: translate the following. +// 'label.details' => 'Details', // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index ade86f7d4..99baea978 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -273,6 +273,8 @@ // 'label.download' => 'Download', 'label.active_users' => 'Aktiva användare', 'label.inactive_users' => 'Inaktiva användare', +// TODO: translate the following. +// 'label.details' => 'Details', // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index 2935878fe..d8ec797ee 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -297,6 +297,7 @@ // 'label.download' => 'Download', // 'label.active_users' => 'Active Users', // 'label.inactive_users' => 'Inactive Users', +// 'label.details' => 'Details', // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index 5d87497ce..7121beb89 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -282,6 +282,7 @@ // 'label.download' => 'Download', // 'label.active_users' => 'Active Users', // 'label.inactive_users' => 'Inactive Users', +// 'label.details' => 'Details', // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index aabfbc9dc..f3e732765 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -288,6 +288,7 @@ // 'label.download' => 'Download', // 'label.active_users' => 'Active Users', // 'label.inactive_users' => 'Inactive Users', +// 'label.details' => 'Details', // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index aa57f3dcb..ecbe45ae3 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.19.9.5061 | Copyright © Anuko | +  Anuko Time Tracker 1.19.9.5062 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From c66cf20bcc6c6b1110103cc83a5f254b8a1bb227 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 14 Sep 2019 21:23:36 +0000 Subject: [PATCH 054/877] Added label.budget to translation files. --- WEB-INF/resources/ca.lang.php | 1 + WEB-INF/resources/cs.lang.php | 1 + WEB-INF/resources/da.lang.php | 1 + WEB-INF/resources/de.lang.php | 1 + WEB-INF/resources/en.lang.php | 1 + WEB-INF/resources/es.lang.php | 1 + WEB-INF/resources/et.lang.php | 1 + WEB-INF/resources/fa.lang.php | 1 + WEB-INF/resources/fi.lang.php | 1 + WEB-INF/resources/fr.lang.php | 1 + WEB-INF/resources/gr.lang.php | 1 + WEB-INF/resources/he.lang.php | 1 + WEB-INF/resources/hu.lang.php | 1 + WEB-INF/resources/it.lang.php | 1 + WEB-INF/resources/ja.lang.php | 1 + WEB-INF/resources/ko.lang.php | 1 + WEB-INF/resources/nl.lang.php | 1 + WEB-INF/resources/no.lang.php | 1 + WEB-INF/resources/pl.lang.php | 1 + WEB-INF/resources/pt-br.lang.php | 1 + WEB-INF/resources/pt.lang.php | 1 + WEB-INF/resources/ro.lang.php | 1 + WEB-INF/resources/ru.lang.php | 1 + WEB-INF/resources/sk.lang.php | 1 + WEB-INF/resources/sl.lang.php | 1 + WEB-INF/resources/sr.lang.php | 1 + WEB-INF/resources/sv.lang.php | 1 + WEB-INF/resources/tr.lang.php | 1 + WEB-INF/resources/zh-cn.lang.php | 1 + WEB-INF/resources/zh-tw.lang.php | 1 + WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/work_add.tpl | 4 ++++ work_add.php | 2 ++ 33 files changed, 37 insertions(+), 1 deletion(-) diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index 166c7b928..2730902a0 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -284,6 +284,7 @@ // 'label.active_users' => 'Active Users', // 'label.inactive_users' => 'Inactive Users', // 'label.details' => 'Details', +// 'label.budget' => 'Budget', // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index 527d14b95..1ba723029 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -294,6 +294,7 @@ // 'label.active_users' => 'Active Users', // 'label.inactive_users' => 'Inactive Users', // 'label.details' => 'Details', +// 'label.budget' => 'Budget', // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index 52236c9f7..de3b796be 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -275,6 +275,7 @@ 'label.inactive_users' => 'Inaktive Brugere', // TODO: translate the following. // 'label.details' => 'Details', +// 'label.budget' => 'Budget', // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index 66428e55e..54321626f 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -265,6 +265,7 @@ 'label.inactive_users' => 'Inaktive Nutzer', // TODO: translate the following. // 'label.details' => 'Details', +// 'label.budget' => 'Budget', // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index 0e10f3620..c95b60eeb 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -250,6 +250,7 @@ 'label.active_users' => 'Active Users', 'label.inactive_users' => 'Inactive Users', 'label.details' => 'Details', +'label.budget' => 'Budget', // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index 08e3f818c..d36d6421e 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -287,6 +287,7 @@ // 'label.active_users' => 'Active Users', // 'label.inactive_users' => 'Inactive Users', // 'label.details' => 'Details', +// 'label.budget' => 'Budget', // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index c93641a1c..39c447848 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -282,6 +282,7 @@ 'label.inactive_users' => 'Mitteaktiivsed kasutajad', // TODO: translate the following. // 'label.details' => 'Details', +// 'label.budget' => 'Budget', // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index ed9ea5b1c..33b0e6847 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -286,6 +286,7 @@ 'label.inactive_users' => 'کاربران غیرفعال', // TODO: translate the following. // 'label.details' => 'Details', +// 'label.budget' => 'Budget', // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 718f53ce2..59fca15fa 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -279,6 +279,7 @@ 'label.inactive_users' => 'Ei-aktiiviset käyttäjät', // TODO: translate the following. // 'label.details' => 'Details', +// 'label.budget' => 'Budget', // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index 52c6f6b9e..a1a50a9e9 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -273,6 +273,7 @@ 'label.inactive_users' => 'Utilisateurs inactifs', // TODO: translate the following. // 'label.details' => 'Details', +// 'label.budget' => 'Budget', // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index b6ae5e4d3..e40932a29 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -269,6 +269,7 @@ 'label.inactive_users' => 'Ανενεργοί χρήστες', // TODO: translate the following. // 'label.details' => 'Details', +// 'label.budget' => 'Budget', // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index 6f47aa884..2412d630a 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -294,6 +294,7 @@ 'label.inactive_users' => 'משתמשים לא פעילים', // TODO: translate the following. // 'label.details' => 'Details', +// 'label.budget' => 'Budget', // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index aa95b94c0..2c81071f7 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -290,6 +290,7 @@ // 'label.active_users' => 'Active Users', // 'label.inactive_users' => 'Inactive Users', // 'label.details' => 'Details', +// 'label.budget' => 'Budget', // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index fc4c65219..86843eb05 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -273,6 +273,7 @@ 'label.inactive_users' => 'Utenti inattivi', // TODO: translate the following. // 'label.details' => 'Details', +// 'label.budget' => 'Budget', // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index 90a9d79c6..2a4568ec3 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -294,6 +294,7 @@ // 'label.active_users' => 'Active Users', // 'label.inactive_users' => 'Inactive Users', // 'label.details' => 'Details', +// 'label.budget' => 'Budget', // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index 1cd6bf540..b9a39d3bf 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -294,6 +294,7 @@ // 'label.active_users' => 'Active Users', // 'label.inactive_users' => 'Inactive Users', // 'label.details' => 'Details', +// 'label.budget' => 'Budget', // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index a2b566772..a2f3cd1ad 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -259,6 +259,7 @@ 'label.inactive_users' => 'Inactieve medewerkers', // TODO: translate the following. // 'label.details' => 'Details', +// 'label.budget' => 'Budget', // Entity names. 'entity.time' => 'tijd', diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index 08d7b7f09..bb3bd2511 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -291,6 +291,7 @@ // 'label.active_users' => 'Active Users', // 'label.inactive_users' => 'Inactive Users', // 'label.details' => 'Details', +// 'label.budget' => 'Budget', // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index c7f88c94d..be92051e6 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -280,6 +280,7 @@ 'label.inactive_users' => 'Nieaktywni użytkownicy', // TODO: translate the following. // 'label.details' => 'Details', +// 'label.budget' => 'Budget', // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index 70c1132b8..d479a4d65 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -277,6 +277,7 @@ 'label.inactive_users' => 'Usuários inativos', // TODO: translate the following. // 'label.details' => 'Details', +// 'label.budget' => 'Budget', // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index 5e7959818..46e1d6eac 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -279,6 +279,7 @@ // 'label.active_users' => 'Active Users', // 'label.inactive_users' => 'Inactive Users', // 'label.details' => 'Details', +// 'label.budget' => 'Budget', // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index 619c07c62..e2221d7cb 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -291,6 +291,7 @@ // 'label.active_users' => 'Active Users', // 'label.inactive_users' => 'Inactive Users', // 'label.details' => 'Details', +// 'label.budget' => 'Budget', // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index 80f5f2bcf..aeb571010 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -249,6 +249,7 @@ 'label.active_users' => 'Активные пользователи', 'label.inactive_users' => 'Неактивные пользователи', 'label.details' => 'Детали', +'label.budget' => 'Бюджет', // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index f3d999153..d853bafc7 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -284,6 +284,7 @@ 'label.inactive_users' => 'Neaktívny používatelia', // TODO: translate the following. // 'label.details' => 'Details', +// 'label.budget' => 'Budget', // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index d015bdbac..bb139505e 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -274,6 +274,7 @@ // 'label.active_users' => 'Active Users', // 'label.inactive_users' => 'Inactive Users', // 'label.details' => 'Details', +// 'label.budget' => 'Budget', // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index 0cf827cfe..318eb0ffe 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -278,6 +278,7 @@ 'label.inactive_users' => 'Neaktivni korisnik', // TODO: translate the following. // 'label.details' => 'Details', +// 'label.budget' => 'Budget', // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index 99baea978..8fd08e23a 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -275,6 +275,7 @@ 'label.inactive_users' => 'Inaktiva användare', // TODO: translate the following. // 'label.details' => 'Details', +// 'label.budget' => 'Budget', // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index d8ec797ee..4bbaff7e8 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -298,6 +298,7 @@ // 'label.active_users' => 'Active Users', // 'label.inactive_users' => 'Inactive Users', // 'label.details' => 'Details', +// 'label.budget' => 'Budget', // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index 7121beb89..29206c3b4 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -283,6 +283,7 @@ // 'label.active_users' => 'Active Users', // 'label.inactive_users' => 'Inactive Users', // 'label.details' => 'Details', +// 'label.budget' => 'Budget', // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index f3e732765..6745e889d 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -289,6 +289,7 @@ // 'label.active_users' => 'Active Users', // 'label.inactive_users' => 'Inactive Users', // 'label.details' => 'Details', +// 'label.budget' => 'Budget', // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index ecbe45ae3..f7f5cca8f 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- + + + + {if $show_files} diff --git a/work_add.php b/work_add.php index 452e515b3..8eecdd291 100644 --- a/work_add.php +++ b/work_add.php @@ -49,12 +49,14 @@ if ($request->isPost()) { $cl_name = trim($request->getParameter('work_name')); $cl_description = trim($request->getParameter('description')); + $cl_details = trim($request->getParameter('details')); $cl_currency = $request->getParameter('currency'); } $form = new Form('workForm'); $form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'work_name','style'=>'width: 250px;','value'=>$cl_name)); $form->addInput(array('type'=>'textarea','name'=>'description','style'=>'width: 250px; height: 40px;','value'=>$cl_description)); +$form->addInput(array('type'=>'textarea','name'=>'details','style'=>'width: 250px; height: 80px;','value'=>$cl_details)); if ($showFiles) $form->addInput(array('type'=>'upload','name'=>'newfile','value'=>$i18n->get('button.submit'))); // Add a dropdown for currency. From 93eeca2e6d4cfa17238d6273bc680856b6ebd37f Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 14 Sep 2019 22:44:02 +0000 Subject: [PATCH 055/877] More progress on Remote Work plugin. --- WEB-INF/lib/ttOfferHelper.class.php | 10 +- WEB-INF/lib/ttWorkHelper.class.php | 188 ++++++++++++++++++++++++++++ WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/work_add.tpl | 4 + work_add.php | 40 +++--- 5 files changed, 212 insertions(+), 32 deletions(-) diff --git a/WEB-INF/lib/ttOfferHelper.class.php b/WEB-INF/lib/ttOfferHelper.class.php index f6f9cf5aa..85cba6542 100644 --- a/WEB-INF/lib/ttOfferHelper.class.php +++ b/WEB-INF/lib/ttOfferHelper.class.php @@ -33,7 +33,7 @@ class ttOfferHelper { var $errors = null; // Errors go here. Set in constructor by reference. var $remote_work_uri = null; // Location of remote work server. var $register_uri = null; // URI to register with remote work server. - var $create_offer_uri = null; // URI to publish offer. + var $put_offer_uri = null; // URI to publish offer. var $get_offer_uri = null; // URI to get offer details. var $get_offers_uri = null; // URI to get a list of offers. var $delete_offer_uri = null; // URI to delete offer. @@ -49,7 +49,7 @@ function __construct(&$errors) { if (defined('REMOTE_WORK_URI')) { $this->remote_work_uri = REMOTE_WORK_URI; $this->register_uri = $this->remote_work_uri.'register'; - $this->create_offer_uri = $this->remote_work_uri.'createoffer'; + $this->put_offer_uri = $this->remote_work_uri.'putoffer'; $this->get_offer_uri = $this->remote_work_uri.'getoffer'; $this->get_offers_uri = $this->remote_work_uri.'getoffers'; $this->delete_offer_uri = $this->remote_work_uri.'deleteoffer'; @@ -126,8 +126,8 @@ function checkSiteRegistration() { } } - // createOffer - publishes an offer in remote work server. - function createOffer($fields) { + // putOffer - publishes an offer in remote work server. + function putOffer($fields) { global $i18n; global $user; $mdb2 = getConnection(); @@ -157,7 +157,7 @@ function createOffer($fields) { $ch = curl_init(); // Set the url, number of POST vars, POST data. - curl_setopt($ch, CURLOPT_URL, $this->create_offer_uri); + curl_setopt($ch, CURLOPT_URL, $this->put_offer_uri); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); diff --git a/WEB-INF/lib/ttWorkHelper.class.php b/WEB-INF/lib/ttWorkHelper.class.php index b8d2fde8c..4f6fb7feb 100644 --- a/WEB-INF/lib/ttWorkHelper.class.php +++ b/WEB-INF/lib/ttWorkHelper.class.php @@ -29,6 +29,194 @@ // Class ttWorkHelper is used to help with operations with the Remote work plugin. class ttWorkHelper { + var $errors = null; // Errors go here. Set in constructor by reference. + var $remote_work_uri = null; // Location of remote work server. + var $register_uri = null; // URI to register with remote work server. + var $put_work_uri = null; // URI to publish offer. + var $get_work_uri = null; // URI to get offer details. + var $get_active_work_uri = null; // URI to get active work for group. + var $get_available_work_uri = null; // URI to get available work for group. + var $delete_work_uri = null; // URI to delete eotk. + // TODO: design how (and what) to delete when a group is deleted. + var $update_work_uri = null; // URI to update work. + var $site_id = null; // Site id for remote work server. + var $site_key = null; // Site key for remote work server. + + // Constructor. + function __construct(&$errors) { + $this->errors = &$errors; + + if (defined('REMOTE_WORK_URI')) { + $this->remote_work_uri = REMOTE_WORK_URI; + $this->register_uri = $this->remote_work_uri.'register'; + $this->put_work_uri = $this->remote_work_uri.'putwork'; + $this->get_work_uri = $this->remote_work_uri.'getwork'; + $this->get_active_work_uri = $this->remote_work_uri.'getactivework'; + $this->get_avaialable_work_uri = $this->remote_work_uri.'getavailablework'; + + $this->delete_work_uri = $this->remote_work_uri.'deletework'; + $this->update_work_uri = $this->remote_work_uri.'updatework'; + $this->checkSiteRegistration(); + } + } + + // TODO: identical function is in ttOfferHelper. Reduce code duplication. + // checkSiteRegistration - obtains site id and key from local database. + // If not found, it tries to register with remote work server. + function checkSiteRegistration() { + + global $i18n; + $mdb2 = getConnection(); + + // Obtain site id. + $sql = "select param_value as id from tt_site_config where param_name = 'worksite_id'"; + $res = $mdb2->query($sql); + $val = $res->fetchRow(); + if (!$val) { + // No site id found, need to register. + $fields = array('name' => urlencode('time tracker'), + 'origin' => urlencode('time tracker source')); + + // Urlify the data for the POST. + foreach($fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; } + $fields_string = rtrim($fields_string, '&'); + + // Open connection. + $ch = curl_init(); + + // Set the url, number of POST vars, POST data. + curl_setopt($ch, CURLOPT_URL, $this->register_uri); + curl_setopt($ch, CURLOPT_POST, true); + curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + + // Execute a post request. + $result = curl_exec($ch); + + // Close connection. + curl_close($ch); + + $result_array = json_decode($result, true); + if (!$result_array) { + $this->errors->add($i18n->get('error.remote_work')); + } + else if ($result_array['error']) { + // Add an error from remote work server if we have it. + $this->errors->add($result_array['error']); + } + else if ($result_array['id'] && $result_array['key']) { + $this->site_id = $result_array['id']; + $this->site_key = $result_array['key']; + + // Registration successful. Store id and key locally for future use. + $sql = "insert into tt_site_config values('worksite_id', $this->site_id, now(), null)"; + $mdb2->exec($sql); + $sql = "insert into tt_site_config values('worksite_key', ".$mdb2->quote($this->site_key).", now(), null)"; + $mdb2->exec($sql); + } else { + $this->errors->add($i18n->get('error.remote_work')); + } + } else { + // Site id found. + $this->site_id = $val['id']; + + // Obtain site key. + $sql = "select param_value as site_key from tt_site_config where param_name = 'worksite_key'"; + $res = $mdb2->query($sql); + $val = $res->fetchRow(); + $this->site_key = $val['site_key']; + } + } + + // putWork - publishes a work item in remote work server. + function putWork($fields) { + global $i18n; + global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $curl_fields = array('site_id' => urlencode($this->site_id), + 'site_key' => urlencode($this->site_key), + 'org_id' => urlencode($org_id), + 'org_key' => urlencode($this->getOrgKey()), + 'group_id' => urlencode($group_id), + 'group_key' => urlencode($this->getGroupKey()), + 'lang' => urlencode($user->lang), + 'subject' => urlencode($fields['subject']), + 'descr_short' => urlencode($fields['descr_short']), + 'descr_long' => urlencode($fields['descr_long']), + 'currency' => urlencode($fields['currency']), + 'amount' => urlencode($fields['amount']) + ); + + // url-ify the data for the POST. + foreach($curl_fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; } + $fields_string = rtrim($fields_string, '&'); + + // Open connection. + $ch = curl_init(); + + // Set the url, number of POST vars, POST data. + curl_setopt($ch, CURLOPT_URL, $this->put_work_uri); + curl_setopt($ch, CURLOPT_POST, true); + curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + + // Execute a post request. + $result = curl_exec($ch); + + // Close connection. + curl_close($ch); + + if (!$result) { + $this->errors->add($i18n->get('error.remote_work')); + return false; + } + + $result_array = json_decode($result, true); + $work_id = (int) $result_array['work_id']; + $error = $result_array['error']; + + if ($error || !$work_id) { + if ($error) { + // Add an error from remote work server if we have it. + $this->errors->add($error); + } + return false; + } + + return true; + } + + // TODO: identical function is in ttOfferHelper. Redesign. + // getOrgKey obtains organization key from the database. + private function getOrgKey() { + global $user; + $mdb2 = getConnection(); + + $org_id = $user->org_id; + $sql = "select group_key from tt_groups where id = $org_id and status = 1"; + $res = $mdb2->query($sql); + $val = $res->fetchRow(); + return $val['group_key']; + } + + // TODO: identical function is in ttOfferHelper. Redesign. + // getGrtoupKey obtains group key from the database. + private function getGroupKey() { + global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $sql = "select group_key from tt_groups where id = $group_id and org_id = $org_id and status = 1"; + $res = $mdb2->query($sql); + $val = $res->fetchRow(); + return $val['group_key']; + } // getCurrencies - obtains a list of supported currencies. static function getCurrencies() { diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index f7f5cca8f..d3524d0e6 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.19.9.5062 | Copyright © Anuko | +  Anuko Time Tracker 1.19.9.5063 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/work_add.tpl b/WEB-INF/templates/work_add.tpl index 757a4e224..0cc81fa53 100644 --- a/WEB-INF/templates/work_add.tpl +++ b/WEB-INF/templates/work_add.tpl @@ -11,6 +11,10 @@ {$i18n.label.description}: {$forms.workForm.description.control}
{$i18n.label.details}:{$forms.workForm.details.control}
{$i18n.label.file}:
- + + + + diff --git a/work_add.php b/work_add.php index 8eecdd291..d98ed8242 100644 --- a/work_add.php +++ b/work_add.php @@ -51,6 +51,7 @@ $cl_description = trim($request->getParameter('description')); $cl_details = trim($request->getParameter('details')); $cl_currency = $request->getParameter('currency'); + $cl_budget = $request->getParameter('budget'); } $form = new Form('workForm'); @@ -62,6 +63,8 @@ // Add a dropdown for currency. $currencies = ttWorkHelper::getCurrencies(); $form->addInput(array('type'=>'combobox','name'=>'currency','data'=>$currencies,'datakeys'=>array('id','name'),'value'=>$cl_currency)); +$form->addInput(array('type'=>'floatfield','maxlength'=>'10','name'=>'budget','format'=>'.2','value'=>$cl_budget)); +$form->addInput(array('type'=>'submit','name'=>'btn_add','value'=>$i18n->get('button.add'))); // TODO: design how to handle one-time vs ongoing work. Apparently, with a conditional display of relevant controls. // Ongoing work - rate per hour control. @@ -71,39 +74,24 @@ // TODO: design how to handle categories and sub-categories. // One major complication is localization of names. -// Coding and design are currently ongoing. - - if ($request->isPost()) { // Validate user input. if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.thing_name')); if (!ttValidString($cl_description, true)) $err->add($i18n->get('error.field'), $i18n->get('label.description')); - if (!ttGroupHelper::validateCheckboxGroupInput($cl_users, 'tt_users')) $err->add($i18n->get('error.field'), $i18n->get('label.users')); - if (!ttGroupHelper::validateCheckboxGroupInput($cl_tasks, 'tt_tasks')) $err->add($i18n->get('error.field'), $i18n->get('label.tasks')); + if (!ttValidString($cl_details, true)) $err->add($i18n->get('error.field'), $i18n->get('label.details')); if ($err->no()) { - if (!ttProjectHelper::getProjectByName($cl_name)) { - $id = ttProjectHelper::insert(array('name' => $cl_name, - 'description' => $cl_description, - 'users' => $cl_users, - 'tasks' => $cl_tasks, - 'status' => ACTIVE)); - - // Put a new file in storage if we have it. - if ($id && $showFiles && $_FILES['newfile']['name']) { - $fileHelper = new ttFileHelper($err); - $fields = array('entity_type'=>'project', - 'entity_id' => $id, - 'file_name' => $_FILES['newfile']['name']); - $fileHelper->putFile($fields); - } - if ($id) { - header('Location: projects.php'); + $workHelper = new ttWorkHelper($err); + $fields = array('subject'=>$cl_name, + 'short_description' => $cl_description, + 'long_description' => $cl_details, + 'currency' => $cl_currency, + 'amount' => $cl_budget); + $id = $workHelper->putWork($fields); + if ($id) { + header('Location: work.php'); exit(); - } else - $err->add($i18n->get('error.db')); - } else - $err->add($i18n->get('error.object_exists')); + } } } // isPost From 43a2c748a410588b6b02d481d34f43d985ff526c Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 15 Sep 2019 12:21:03 +0000 Subject: [PATCH 056/877] Refactoring. Put getGroupKey function into ttUser class. --- WEB-INF/lib/ttGroup.class.php | 2 ++ WEB-INF/lib/ttUser.class.php | 9 ++++++++- WEB-INF/lib/ttWorkHelper.class.php | 17 +---------------- WEB-INF/templates/footer.tpl | 2 +- 4 files changed, 12 insertions(+), 18 deletions(-) diff --git a/WEB-INF/lib/ttGroup.class.php b/WEB-INF/lib/ttGroup.class.php index 2a5eb1dcf..5e1885af9 100644 --- a/WEB-INF/lib/ttGroup.class.php +++ b/WEB-INF/lib/ttGroup.class.php @@ -33,6 +33,7 @@ // We use it in ttUser class to have acces to "on behalf" group properties. class ttGroup { var $id = null; // Group id. + var $group_key = null; // Group key. var $parent_id = null; // Paerent group id. var $org_id = null; // Organization id. var $name = null; // Group name. @@ -80,6 +81,7 @@ function __construct($id, $org_id) { $val = $res->fetchRow(); if ($val['id'] > 0) { $this->id = $val['id']; + $this->group_key = $val['group_key']; $this->parent_id = $val['parent_id']; $this->org_id = $val['org_id']; $this->name = $val['name']; diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index 6db627884..4084aa0bc 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -39,6 +39,7 @@ class ttUser { var $id = null; // User id. var $org_id = null; // Organization id. var $group_id = null; // Group id. + var $group_key = null; // Group key. var $role_id = null; // Role id. var $role_name = null; // Role name. var $rank = null; // User role rank. @@ -92,7 +93,7 @@ function __construct($login, $id = null) { $mdb2 = getConnection(); $sql = "SELECT u.id, u.login, u.name, u.group_id, u.role_id, r.rank, r.name as role_name, r.rights, u.client_id,". - " u.quota_percent, u.email, g.org_id, g.name as group_name, g.currency, g.lang, g.decimal_mark, g.date_format,". + " u.quota_percent, u.email, g.org_id, g.group_key, g.name as group_name, g.currency, g.lang, g.decimal_mark, g.date_format,". " g.time_format, g.week_start, g.tracking_mode, g.project_required, g.task_required, g.record_type,". " g.bcc_email, g.allow_ip, g.password_complexity, g.plugins, g.config, g.lock_spec, g.holidays, g.workday_minutes, g.custom_logo". " FROM tt_users u LEFT JOIN tt_groups g ON (u.group_id = g.id) LEFT JOIN tt_roles r on (r.id = u.role_id) WHERE "; @@ -114,6 +115,7 @@ function __construct($login, $id = null) { $this->id = $val['id']; $this->org_id = $val['org_id']; $this->group_id = $val['group_id']; + $this->group_key = $val['group_key']; $this->role_id = $val['role_id']; $this->role_name = $val['role_name']; $this->rights = explode(',', $val['rights']); @@ -188,6 +190,11 @@ function getGroup() { return ($this->behalfGroup ? $this->behalfGroup->id : $this->group_id); } + // getGroupKey returns group key for active group. + function getGroupKey() { + return ($this->behalfGroup ? $this->behalfGroup->group_key : $this->group_key); + } + // getDecimalMark returns decimal mark for active group. function getDecimalMark() { return ($this->behalfGroup ? $this->behalfGroup->decimal_mark : $this->decimal_mark); diff --git a/WEB-INF/lib/ttWorkHelper.class.php b/WEB-INF/lib/ttWorkHelper.class.php index 4f6fb7feb..66b01e552 100644 --- a/WEB-INF/lib/ttWorkHelper.class.php +++ b/WEB-INF/lib/ttWorkHelper.class.php @@ -142,7 +142,7 @@ function putWork($fields) { 'org_id' => urlencode($org_id), 'org_key' => urlencode($this->getOrgKey()), 'group_id' => urlencode($group_id), - 'group_key' => urlencode($this->getGroupKey()), + 'group_key' => urlencode($user->getGroupKey()), 'lang' => urlencode($user->lang), 'subject' => urlencode($fields['subject']), 'descr_short' => urlencode($fields['descr_short']), @@ -203,21 +203,6 @@ private function getOrgKey() { return $val['group_key']; } - // TODO: identical function is in ttOfferHelper. Redesign. - // getGrtoupKey obtains group key from the database. - private function getGroupKey() { - global $user; - $mdb2 = getConnection(); - - $group_id = $user->getGroup(); - $org_id = $user->org_id; - - $sql = "select group_key from tt_groups where id = $group_id and org_id = $org_id and status = 1"; - $res = $mdb2->query($sql); - $val = $res->fetchRow(); - return $val['group_key']; - } - // getCurrencies - obtains a list of supported currencies. static function getCurrencies() { $mdb2 = getConnection(); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index d3524d0e6..ed5e5150b 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.19.9.5063 | Copyright © Anuko | +  Anuko Time Tracker 1.19.9.5064 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/work_add.tpl b/WEB-INF/templates/work_add.tpl index 0cc81fa53..3e2b00695 100644 --- a/WEB-INF/templates/work_add.tpl +++ b/WEB-INF/templates/work_add.tpl @@ -25,6 +25,10 @@ {$i18n.label.currency}: {$forms.workForm.currency.control}
{$i18n.label.budget} (*):{$forms.workForm.budget.control}
{$i18n.label.required_fields}
-
 Anuko Time Tracker 1.19.9.5064 | Copyright © Anuko | +  Anuko Time Tracker 1.19.9.5065 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 4d5bf4e4824f7fc3a5abf98152494d7dbed64de7 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 15 Sep 2019 12:36:14 +0000 Subject: [PATCH 057/877] A bit more refactoring with ttUser::getGroupKey() function. --- WEB-INF/lib/ttFileHelper.class.php | 22 ++++------------------ WEB-INF/lib/ttOfferHelper.class.php | 22 ++++------------------ WEB-INF/templates/footer.tpl | 2 +- 3 files changed, 9 insertions(+), 37 deletions(-) diff --git a/WEB-INF/lib/ttFileHelper.class.php b/WEB-INF/lib/ttFileHelper.class.php index 07d0ad085..02830474a 100644 --- a/WEB-INF/lib/ttFileHelper.class.php +++ b/WEB-INF/lib/ttFileHelper.class.php @@ -135,7 +135,7 @@ function putFile($fields) { 'org_id' => urlencode($org_id), 'org_key' => urlencode($this->getOrgKey()), 'group_id' => urlencode($group_id), - 'group_key' => urlencode($this->getGroupKey()), + 'group_key' => urlencode($user->getGroupKey()), 'entity_type' => urlencode($fields['entity_type']), 'entity_id' => urlencode($fields['entity_id']), 'file_name' => urlencode($fields['file_name']), @@ -214,7 +214,7 @@ function deleteFile($fields) { 'org_id' => urlencode($org_id), 'org_key' => urlencode($this->getOrgKey()), 'group_id' => urlencode($group_id), - 'group_key' => urlencode($this->getGroupKey()), + 'group_key' => urlencode($user->getGroupKey()), 'entity_type' => urlencode($fields['entity_type']), 'entity_id' => urlencode($fields['entity_id']), 'file_id' => urlencode($fields['remote_id']), @@ -292,7 +292,7 @@ function deleteEntityFiles($entity_id, $entity_type) { 'org_id' => urlencode($org_id), 'org_key' => urlencode($this->getOrgKey()), 'group_id' => urlencode($group_id), - 'group_key' => urlencode($this->getGroupKey()), + 'group_key' => urlencode($user->getGroupKey()), 'entity_type' => urlencode($entity_type), 'entity_id' => urlencode($entity_id)); @@ -379,20 +379,6 @@ private function getOrgKey() { return $val['group_key']; } - // getGrtoupKey obtains group key from the database. - private function getGroupKey() { - global $user; - $mdb2 = getConnection(); - - $group_id = $user->getGroup(); - $org_id = $user->org_id; - - $sql = "select group_key from tt_groups where id = $group_id and org_id = $org_id and status = 1"; - $res = $mdb2->query($sql); - $val = $res->fetchRow(); - return $val['group_key']; - } - // getEntityFiles obtains a list of files for an entity. static function getEntityFiles($id, $type) { global $user; @@ -466,7 +452,7 @@ function getFile($fields) { 'org_id' => urlencode($org_id), 'org_key' => urlencode($this->getOrgKey()), 'group_id' => urlencode($group_id), - 'group_key' => urlencode($this->getGroupKey()), + 'group_key' => urlencode($user->getGroupKey()), 'entity_type' => urlencode($fields['entity_type']), 'entity_id' => urlencode($fields['entity_id']), 'file_id' => urlencode($fields['remote_id']), diff --git a/WEB-INF/lib/ttOfferHelper.class.php b/WEB-INF/lib/ttOfferHelper.class.php index 85cba6542..0a7578771 100644 --- a/WEB-INF/lib/ttOfferHelper.class.php +++ b/WEB-INF/lib/ttOfferHelper.class.php @@ -140,7 +140,7 @@ function putOffer($fields) { 'org_id' => urlencode($org_id), 'org_key' => urlencode($this->getOrgKey()), 'group_id' => urlencode($group_id), - 'group_key' => urlencode($this->getGroupKey()), + 'group_key' => urlencode($user->getGroupKey()), 'offer_lang' => urlencode($fields['offer_lang']), 'offer_subject' => urlencode($fields['offer_subject']), 'offer_descr_short' => urlencode($fields['offer_descr_short']), @@ -205,7 +205,7 @@ function getOffer($fields) { // 'org_id' => urlencode($org_id), // 'org_key' => urlencode($this->getOrgKey()), // 'group_id' => urlencode($group_id), -// 'group_key' => urlencode($this->getGroupKey()), +// 'group_key' => urlencode($user->getGroupKey()), 'offer_id' => urlencode($fields['remote_id'])); // url-ify the data for the POST. @@ -280,7 +280,7 @@ function deleteFile($fields) { 'org_id' => urlencode($org_id), 'org_key' => urlencode($this->getOrgKey()), 'group_id' => urlencode($group_id), - 'group_key' => urlencode($this->getGroupKey()), + 'group_key' => urlencode($user->getGroupKey()), 'entity_type' => urlencode($fields['entity_type']), 'entity_id' => urlencode($fields['entity_id']), 'file_id' => urlencode($fields['remote_id']), @@ -358,7 +358,7 @@ function deleteEntityFiles($entity_id, $entity_type) { 'org_id' => urlencode($org_id), 'org_key' => urlencode($this->getOrgKey()), 'group_id' => urlencode($group_id), - 'group_key' => urlencode($this->getGroupKey()), + 'group_key' => urlencode($user->getGroupKey()), 'entity_type' => urlencode($entity_type), 'entity_id' => urlencode($entity_id)); @@ -445,20 +445,6 @@ private function getOrgKey() { return $val['group_key']; } - // getGrtoupKey obtains group key from the database. - private function getGroupKey() { - global $user; - $mdb2 = getConnection(); - - $group_id = $user->getGroup(); - $org_id = $user->org_id; - - $sql = "select group_key from tt_groups where id = $group_id and org_id = $org_id and status = 1"; - $res = $mdb2->query($sql); - $val = $res->fetchRow(); - return $val['group_key']; - } - // getEntityFiles obtains a list of files for an entity. static function getEntityFiles($id, $type) { global $user; diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index ed5e5150b..97c6fcb73 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.19.9.5065 | Copyright © Anuko | +  Anuko Time Tracker 1.19.9.5066 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From f28b097244b9eab15b7e5f08029091c6ac52b090 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 15 Sep 2019 12:58:04 +0000 Subject: [PATCH 058/877] Refactoring. Put getOrgKey() function into ttUser class. --- WEB-INF/lib/ttFileHelper.class.php | 20 ++++---------------- WEB-INF/lib/ttOfferHelper.class.php | 20 ++++---------------- WEB-INF/lib/ttUser.class.php | 18 ++++++++++++++++++ WEB-INF/lib/ttWorkHelper.class.php | 15 +-------------- WEB-INF/templates/footer.tpl | 2 +- 5 files changed, 28 insertions(+), 47 deletions(-) diff --git a/WEB-INF/lib/ttFileHelper.class.php b/WEB-INF/lib/ttFileHelper.class.php index 02830474a..a38162706 100644 --- a/WEB-INF/lib/ttFileHelper.class.php +++ b/WEB-INF/lib/ttFileHelper.class.php @@ -133,7 +133,7 @@ function putFile($fields) { $curl_fields = array('site_id' => urlencode($this->site_id), 'site_key' => urlencode($this->site_key), 'org_id' => urlencode($org_id), - 'org_key' => urlencode($this->getOrgKey()), + 'org_key' => urlencode($user->getOrgKey()), 'group_id' => urlencode($group_id), 'group_key' => urlencode($user->getGroupKey()), 'entity_type' => urlencode($fields['entity_type']), @@ -212,7 +212,7 @@ function deleteFile($fields) { $curl_fields = array('site_id' => urlencode($this->site_id), 'site_key' => urlencode($this->site_key), 'org_id' => urlencode($org_id), - 'org_key' => urlencode($this->getOrgKey()), + 'org_key' => urlencode($user->getOrgKey()), 'group_id' => urlencode($group_id), 'group_key' => urlencode($user->getGroupKey()), 'entity_type' => urlencode($fields['entity_type']), @@ -290,7 +290,7 @@ function deleteEntityFiles($entity_id, $entity_type) { $curl_fields = array('site_id' => urlencode($this->site_id), 'site_key' => urlencode($this->site_key), 'org_id' => urlencode($org_id), - 'org_key' => urlencode($this->getOrgKey()), + 'org_key' => urlencode($user->getOrgKey()), 'group_id' => urlencode($group_id), 'group_key' => urlencode($user->getGroupKey()), 'entity_type' => urlencode($entity_type), @@ -367,18 +367,6 @@ private function entityHasFiles($entity_id, $entity_type) { return $val['id'] > 0; } - // getOrgKey obtains organization key from the database. - private function getOrgKey() { - global $user; - $mdb2 = getConnection(); - - $org_id = $user->org_id; - $sql = "select group_key from tt_groups where id = $org_id and status = 1"; - $res = $mdb2->query($sql); - $val = $res->fetchRow(); - return $val['group_key']; - } - // getEntityFiles obtains a list of files for an entity. static function getEntityFiles($id, $type) { global $user; @@ -450,7 +438,7 @@ function getFile($fields) { $curl_fields = array('site_id' => urlencode($this->site_id), 'site_key' => urlencode($this->site_key), 'org_id' => urlencode($org_id), - 'org_key' => urlencode($this->getOrgKey()), + 'org_key' => urlencode($user->getOrgKey()), 'group_id' => urlencode($group_id), 'group_key' => urlencode($user->getGroupKey()), 'entity_type' => urlencode($fields['entity_type']), diff --git a/WEB-INF/lib/ttOfferHelper.class.php b/WEB-INF/lib/ttOfferHelper.class.php index 0a7578771..97a36e6aa 100644 --- a/WEB-INF/lib/ttOfferHelper.class.php +++ b/WEB-INF/lib/ttOfferHelper.class.php @@ -138,7 +138,7 @@ function putOffer($fields) { $curl_fields = array('site_id' => urlencode($this->site_id), 'site_key' => urlencode($this->site_key), 'org_id' => urlencode($org_id), - 'org_key' => urlencode($this->getOrgKey()), + 'org_key' => urlencode($user->getOrgKey()), 'group_id' => urlencode($group_id), 'group_key' => urlencode($user->getGroupKey()), 'offer_lang' => urlencode($fields['offer_lang']), @@ -203,7 +203,7 @@ function getOffer($fields) { 'site_key' => urlencode($this->site_key), // Do we need these here? // 'org_id' => urlencode($org_id), -// 'org_key' => urlencode($this->getOrgKey()), +// 'org_key' => urlencode($user->getOrgKey()), // 'group_id' => urlencode($group_id), // 'group_key' => urlencode($user->getGroupKey()), 'offer_id' => urlencode($fields['remote_id'])); @@ -278,7 +278,7 @@ function deleteFile($fields) { $curl_fields = array('site_id' => urlencode($this->site_id), 'site_key' => urlencode($this->site_key), 'org_id' => urlencode($org_id), - 'org_key' => urlencode($this->getOrgKey()), + 'org_key' => urlencode($user->getOrgKey()), 'group_id' => urlencode($group_id), 'group_key' => urlencode($user->getGroupKey()), 'entity_type' => urlencode($fields['entity_type']), @@ -356,7 +356,7 @@ function deleteEntityFiles($entity_id, $entity_type) { $curl_fields = array('site_id' => urlencode($this->site_id), 'site_key' => urlencode($this->site_key), 'org_id' => urlencode($org_id), - 'org_key' => urlencode($this->getOrgKey()), + 'org_key' => urlencode($user->getOrgKey()), 'group_id' => urlencode($group_id), 'group_key' => urlencode($user->getGroupKey()), 'entity_type' => urlencode($entity_type), @@ -433,18 +433,6 @@ private function entityHasFiles($entity_id, $entity_type) { return $val['id'] > 0; } - // getOrgKey obtains organization key from the database. - private function getOrgKey() { - global $user; - $mdb2 = getConnection(); - - $org_id = $user->org_id; - $sql = "select group_key from tt_groups where id = $org_id and status = 1"; - $res = $mdb2->query($sql); - $val = $res->fetchRow(); - return $val['group_key']; - } - // getEntityFiles obtains a list of files for an entity. static function getEntityFiles($id, $type) { global $user; diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index 4084aa0bc..83751360a 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -38,6 +38,7 @@ class ttUser { var $name = null; // User name. var $id = null; // User id. var $org_id = null; // Organization id. + var $org_key = null; // Organization key. var $group_id = null; // Group id. var $group_key = null; // Group key. var $role_id = null; // Role id. @@ -116,6 +117,7 @@ function __construct($login, $id = null) { $this->org_id = $val['org_id']; $this->group_id = $val['group_id']; $this->group_key = $val['group_key']; + if ($this->org_id == $this->group_key) $this->org_key = $val['group_key']; $this->role_id = $val['role_id']; $this->role_name = $val['role_name']; $this->rights = explode(',', $val['rights']); @@ -195,6 +197,22 @@ function getGroupKey() { return ($this->behalfGroup ? $this->behalfGroup->group_key : $this->group_key); } + // getOrgKey returns org key. + function getOrgKey() { + if ($this->org_key) { + return $this->org_key; + } + + // Org key is not set because we are in a subgroup. Obtain it. + $mdb2 = getConnection(); + $org_id = $this->org_id; + $sql = "select group_key from tt_groups where id = $org_id and status = 1"; + $res = $mdb2->query($sql); + $val = $res->fetchRow(); + $this->org_key = $val['group_key']; + return $this->org_key; + } + // getDecimalMark returns decimal mark for active group. function getDecimalMark() { return ($this->behalfGroup ? $this->behalfGroup->decimal_mark : $this->decimal_mark); diff --git a/WEB-INF/lib/ttWorkHelper.class.php b/WEB-INF/lib/ttWorkHelper.class.php index 66b01e552..061834645 100644 --- a/WEB-INF/lib/ttWorkHelper.class.php +++ b/WEB-INF/lib/ttWorkHelper.class.php @@ -140,7 +140,7 @@ function putWork($fields) { $curl_fields = array('site_id' => urlencode($this->site_id), 'site_key' => urlencode($this->site_key), 'org_id' => urlencode($org_id), - 'org_key' => urlencode($this->getOrgKey()), + 'org_key' => urlencode($user->getOrgKey()), 'group_id' => urlencode($group_id), 'group_key' => urlencode($user->getGroupKey()), 'lang' => urlencode($user->lang), @@ -190,19 +190,6 @@ function putWork($fields) { return true; } - // TODO: identical function is in ttOfferHelper. Redesign. - // getOrgKey obtains organization key from the database. - private function getOrgKey() { - global $user; - $mdb2 = getConnection(); - - $org_id = $user->org_id; - $sql = "select group_key from tt_groups where id = $org_id and status = 1"; - $res = $mdb2->query($sql); - $val = $res->fetchRow(); - return $val['group_key']; - } - // getCurrencies - obtains a list of supported currencies. static function getCurrencies() { $mdb2 = getConnection(); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 97c6fcb73..081233f4b 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.19.9.5066 | Copyright © Anuko | +  Anuko Time Tracker 1.19.9.5067 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 43aaee1470aa4088737c8d31a57d3eb76d9811c8 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 15 Sep 2019 16:27:44 +0000 Subject: [PATCH 059/877] Some progress on Remote Work plugin - initial implementation of getting active work items. --- WEB-INF/lib/ttWorkHelper.class.php | 63 +++++++++++++++++++++++++++++- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/work.tpl | 5 ++- work.php | 6 ++- work_add.php | 4 +- 5 files changed, 73 insertions(+), 7 deletions(-) diff --git a/WEB-INF/lib/ttWorkHelper.class.php b/WEB-INF/lib/ttWorkHelper.class.php index 061834645..80bf43587 100644 --- a/WEB-INF/lib/ttWorkHelper.class.php +++ b/WEB-INF/lib/ttWorkHelper.class.php @@ -60,7 +60,6 @@ function __construct(&$errors) { } } - // TODO: identical function is in ttOfferHelper. Reduce code duplication. // checkSiteRegistration - obtains site id and key from local database. // If not found, it tries to register with remote work server. function checkSiteRegistration() { @@ -190,6 +189,68 @@ function putWork($fields) { return true; } + // getActiveWork - obtains a list of work items this group is currently oputsourcing. + function getActiveWork() { + global $i18n; + global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $curl_fields = array('site_id' => urlencode($this->site_id), + 'site_key' => urlencode($this->site_key), + 'org_id' => urlencode($org_id), + 'org_key' => urlencode($user->getOrgKey()), + 'group_id' => urlencode($group_id), + 'group_key' => urlencode($user->getGroupKey()) + ); + + // url-ify the data for the POST. + foreach($curl_fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; } + $fields_string = rtrim($fields_string, '&'); + + // Open connection. + $ch = curl_init(); + + // Set the url, number of POST vars, POST data. + curl_setopt($ch, CURLOPT_URL, $this->get_active_work_uri); + curl_setopt($ch, CURLOPT_POST, true); + curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + + // Execute a post request. + $result = curl_exec($ch); + + // Close connection. + curl_close($ch); + + if (!$result) { + $this->errors->add($i18n->get('error.remote_work')); + return false; + } + + $result_array = json_decode($result, true); + + // TODO: check for errors here. + + $active_work = $result_array['active_work']; + + // TODO: construct a list of active work items to return. + //$work_id = (int) $result_array['work_id']; + //$error = $result_array['error']; +/* + if ($error || !$work_id) { + if ($error) { + // Add an error from remote work server if we have it. + $this->errors->add($error); + } + return false; + } +*/ + return $active_work; + } + // getCurrencies - obtains a list of supported currencies. static function getCurrencies() { $mdb2 = getConnection(); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 081233f4b..9d8f436f4 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- + {if $show_files} {/if} @@ -19,7 +20,9 @@ {foreach $active_work as $work_item} - + + + diff --git a/work.php b/work.php index da7b20c18..a124ee68e 100644 --- a/work.php +++ b/work.php @@ -27,7 +27,7 @@ // +----------------------------------------------------------------------+ require_once('initialize.php'); -import('ttGroupHelper'); +import('ttWorkHelper'); // Access checks. if (!(ttAccessAllowed('update_work') || ttAccessAllowed('bid_on_work') || ttAccessAllowed('manage_work'))) { @@ -40,8 +40,10 @@ } // End of access checks. +$workHelper = new ttWorkHelper($err); + if($user->can('manage_work')) { - // $active_work = ttWorkHelper::getActiveWork(); // Active work items this group is outsourcing. + $active_work = $workHelper->getActiveWork(); // Active work items this group is outsourcing. // $inactive_work = ttWorkHelper::getInactiveWork(); // Inactive work items this group was outsourcing. } if($user->can('bid_on_work')) { diff --git a/work_add.php b/work_add.php index d98ed8242..646368aeb 100644 --- a/work_add.php +++ b/work_add.php @@ -83,8 +83,8 @@ if ($err->no()) { $workHelper = new ttWorkHelper($err); $fields = array('subject'=>$cl_name, - 'short_description' => $cl_description, - 'long_description' => $cl_details, + 'descr_short' => $cl_description, + 'descr_long' => $cl_details, 'currency' => $cl_currency, 'amount' => $cl_budget); $id = $workHelper->putWork($fields); From fc97c6d187f13c762dabcf9d446bf6e33adc6fd1 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 15 Sep 2019 18:10:16 +0000 Subject: [PATCH 060/877] Some progress on delete work feature. --- WEB-INF/lib/ttWorkHelper.class.php | 64 ++++++++++++++++++++++++ WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/work.tpl | 2 +- work_add.php | 2 +- work_delete.php | 79 ++++++++++++++++++++++++++++++ 5 files changed, 146 insertions(+), 3 deletions(-) create mode 100644 work_delete.php diff --git a/WEB-INF/lib/ttWorkHelper.class.php b/WEB-INF/lib/ttWorkHelper.class.php index 80bf43587..5d591aa86 100644 --- a/WEB-INF/lib/ttWorkHelper.class.php +++ b/WEB-INF/lib/ttWorkHelper.class.php @@ -251,6 +251,70 @@ function getActiveWork() { return $active_work; } + // getWork - gets work item details from remote work server. + function getWork($work_id) { + global $i18n; + global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $curl_fields = array('site_id' => urlencode($this->site_id), + 'site_key' => urlencode($this->site_key), + 'org_id' => urlencode($org_id), + 'org_key' => urlencode($user->getOrgKey()), + 'group_id' => urlencode($group_id), + 'group_key' => urlencode($user->getGroupKey()), + 'work_id' => urlencode($work_id)); + + // url-ify the data for the POST. + foreach($curl_fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; } + $fields_string = rtrim($fields_string, '&'); + + // Open connection. + $ch = curl_init(); + + // Set the url, number of POST vars, POST data. + curl_setopt($ch, CURLOPT_URL, $this->get_work_uri); + curl_setopt($ch, CURLOPT_POST, true); + curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + + // Execute a post request. + $result = curl_exec($ch); + + $error = curl_error(); + $result_array2 = json_decode($result, true); + + // Close connection. + curl_close($ch); + + if (!$result) { + $this->errors->add($i18n->get('error.file_storage')); + return false; + } + + $result_array = json_decode($result, true); + $status = (int) $result_array['status']; + $error = $result_array['error']; + + if ($error) { + // Add an error from file storage facility if we have it. + $this->errors->add($error); + return false; + } + if ($status != 1) { + // There is no explicit error message, but still something not right. + $this->errors->add($i18n->get('error.remote_work')); + return false; + } + + $this->file_data = $result_array['content']; + return true; + } + + // getCurrencies - obtains a list of supported currencies. static function getCurrencies() { $mdb2 = getConnection(); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 9d8f436f4..1873202f0 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.19.9.5067 | Copyright © Anuko | +  Anuko Time Tracker 1.19.9.5068 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/work.tpl b/WEB-INF/templates/work.tpl index 164600a52..3494b66a9 100644 --- a/WEB-INF/templates/work.tpl +++ b/WEB-INF/templates/work.tpl @@ -11,6 +11,7 @@
{$i18n.label.thing_name} {$i18n.label.description}{$i18n.label.budget}
{$work_item.name|escape}{$work_item.subject|escape}{$work_item.description|escape}{$work_item.amount} {$i18n.label.edit} {$i18n.label.delete}
- - + diff --git a/work_add.php b/work_add.php index 646368aeb..ed879ef52 100644 --- a/work_add.php +++ b/work_add.php @@ -85,7 +85,7 @@ $fields = array('subject'=>$cl_name, 'descr_short' => $cl_description, 'descr_long' => $cl_details, - 'currency' => $cl_currency, + 'currency' => $currencies[$cl_currency - 1]['name'], 'amount' => $cl_budget); $id = $workHelper->putWork($fields); if ($id) { diff --git a/work_delete.php b/work_delete.php new file mode 100644 index 000000000..23dbcf1de --- /dev/null +++ b/work_delete.php @@ -0,0 +1,79 @@ +isPluginEnabled('wk')) { + header('Location: feature_disabled.php'); + exit(); +} +$cl_work_id = (int)$request->getParameter('id'); +$workHelper = new ttWorkHelper($err); +$work_item = $workHelper->getWork($cl_work_id); +if (!$work_item) { + header('Location: access_denied.php'); + exit(); +} +// End of access checks. + +$task_to_delete = $task['name']; + +$form = new Form('taskDeleteForm'); +$form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_task_id)); +$form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->get('label.delete'))); +$form->addInput(array('type'=>'submit','name'=>'btn_cancel','value'=>$i18n->get('button.cancel'))); + +if ($request->isPost()) { + if ($request->getParameter('btn_delete')) { + if(ttTaskHelper::get($cl_task_id)) { + if (ttTaskHelper::delete($cl_task_id)) { + header('Location: tasks.php'); + exit(); + } else + $err->add($i18n->get('error.db')); + } else + $err->add($i18n->get('error.db')); + } elseif ($request->getParameter('btn_cancel')) { + header('Location: tasks.php'); + exit(); + } +} // isPost + +$smarty->assign('task_to_delete', $task_to_delete); +$smarty->assign('forms', array($form->getName()=>$form->toArray())); +$smarty->assign('onload', 'onLoad="document.taskDeleteForm.btn_cancel.focus()"'); +$smarty->assign('title', $i18n->get('title.delete_task')); +$smarty->assign('content_page_name', 'task_delete.tpl'); +$smarty->display('index.tpl'); From 7f96e371a1dcced881245725976edc5246e1665a Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 16 Sep 2019 12:12:06 +0000 Subject: [PATCH 061/877] Fixed reports by adding filtering for text custom field values. --- WEB-INF/lib/ttReportHelper.class.php | 18 ++++++++++++++++-- WEB-INF/templates/footer.tpl | 2 +- work_delete.php | 2 ++ 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index 8ba393b25..5d36b6b8e 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -83,6 +83,7 @@ static function getWhere($options) { if ($options['approved']=='2') $dropdown_parts .= ' and l.approved = 0'; if ($options['paid_status']=='1') $dropdown_parts .= ' and l.paid = 1'; if ($options['paid_status']=='2') $dropdown_parts .= ' and l.paid = 0'; + // Add time custom fields. if ($custom_fields && $custom_fields->timeFields) { foreach ($custom_fields->timeFields as $timeField) { @@ -94,6 +95,20 @@ static function getWhere($options) { } } } + + // Prepare part for text custom fields using LIKE operator. + $cf_text_parts = null; + if ($custom_fields && $custom_fields->timeFields) { + foreach ($custom_fields->timeFields as $timeField) { + $field_name = 'time_field_'.$timeField['id']; + $field_value = $options[$field_name]; + if ($timeField['type'] == CustomFields::TYPE_TEXT && $field_value) { + $cflTableName = 'cfl'.$timeField['id']; + $cf_text_parts .= " and $cflTableName.value like ".$mdb2->quote("%$field_value%"); + } + } + } + // Add user custom fields. if ($custom_fields && $custom_fields->userFields) { foreach ($custom_fields->userFields as $userField) { @@ -106,8 +121,7 @@ static function getWhere($options) { } } - // Prepare part for text custom fields using LIKE operator. - $cf_text_parts = null; + // Continue preparing part for text custom fields using LIKE operator. if ($custom_fields && $custom_fields->userFields) { foreach ($custom_fields->userFields as $userField) { $field_name = 'user_field_'.$userField['id']; diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 1873202f0..fbb5c31b1 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.19.9.5068 | Copyright © Anuko | +  Anuko Time Tracker 1.19.9.5069 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/work.tpl b/WEB-INF/templates/work.tpl index 3494b66a9..64c14ed53 100644 --- a/WEB-INF/templates/work.tpl +++ b/WEB-INF/templates/work.tpl @@ -22,7 +22,7 @@
{$work_item.subject|escape} {$work_item.description|escape}{$work_item.amount}{$work_item.currency} {$work_item.amount} {$i18n.label.edit} {$i18n.label.delete}
-
 Anuko Time Tracker 1.19.9.5069 | Copyright © Anuko | +  Anuko Time Tracker 1.19.10.5070 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/work_delete.php b/work_delete.php index 23dbcf1de..63acf327b 100644 --- a/work_delete.php +++ b/work_delete.php @@ -48,6 +48,8 @@ } // End of access checks. +// TODO: coding ongoing down from here... + $task_to_delete = $task['name']; $form = new Form('taskDeleteForm'); From 39c8e8311de0b1c993c742e232ec6b0e20424bdc Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 17 Sep 2019 15:01:37 +0000 Subject: [PATCH 062/877] Wrote deleteWork part for Remote Work plugin. --- WEB-INF/lib/ttWorkHelper.class.php | 99 ++++++++++++++++++++++-------- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/work_delete.tpl | 20 ++++++ work_delete.php | 26 ++++---- 4 files changed, 104 insertions(+), 43 deletions(-) create mode 100644 WEB-INF/templates/work_delete.tpl diff --git a/WEB-INF/lib/ttWorkHelper.class.php b/WEB-INF/lib/ttWorkHelper.class.php index 5d591aa86..c8d8944c1 100644 --- a/WEB-INF/lib/ttWorkHelper.class.php +++ b/WEB-INF/lib/ttWorkHelper.class.php @@ -26,6 +26,7 @@ // | https://www.anuko.com/time_tracker/credits.htm // +----------------------------------------------------------------------+ +define('TT_CURL_SUCCESS', 1); // Class ttWorkHelper is used to help with operations with the Remote work plugin. class ttWorkHelper { @@ -232,22 +233,15 @@ function getActiveWork() { $result_array = json_decode($result, true); - // TODO: check for errors here. - - $active_work = $result_array['active_work']; - - // TODO: construct a list of active work items to return. - //$work_id = (int) $result_array['work_id']; - //$error = $result_array['error']; -/* - if ($error || !$work_id) { - if ($error) { - // Add an error from remote work server if we have it. - $this->errors->add($error); - } + // Check for error. + $error = $result_array['error']; + if ($error) { + // Add an error from remote work server. + $this->errors->add($error); return false; } -*/ + + $active_work = $result_array['active_work']; return $active_work; } @@ -284,37 +278,88 @@ function getWork($work_id) { // Execute a post request. $result = curl_exec($ch); - $error = curl_error(); - $result_array2 = json_decode($result, true); - // Close connection. curl_close($ch); if (!$result) { - $this->errors->add($i18n->get('error.file_storage')); + $this->errors->add($i18n->get('error.remote_work')); return false; } $result_array = json_decode($result, true); - $status = (int) $result_array['status']; - $error = $result_array['error']; - if ($error) { - // Add an error from file storage facility if we have it. - $this->errors->add($error); + // Check for errors. + $call_status = $result_array['call_status']; + if (!$call_status) { + $this->errors->add($i18n->get('error.remote_work')); return false; } - if ($status != 1) { - // There is no explicit error message, but still something not right. + if ($call_status['code'] != TT_CURL_SUCCESS) { + $this->errors->add($call_status['error_localized'] ? $call_status['error_localized'] : $call_status['error']); + return false; + } + + $work_item = $result_array['work_item']; + return $work_item; + } + + // deleteWork - deletes work item from remote work server. + function deleteWork($work_id) { + global $i18n; + global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $curl_fields = array('site_id' => urlencode($this->site_id), + 'site_key' => urlencode($this->site_key), + 'org_id' => urlencode($org_id), + 'org_key' => urlencode($user->getOrgKey()), + 'group_id' => urlencode($group_id), + 'group_key' => urlencode($user->getGroupKey()), + 'work_id' => urlencode($work_id)); + + // url-ify the data for the POST. + foreach($curl_fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; } + $fields_string = rtrim($fields_string, '&'); + + // Open connection. + $ch = curl_init(); + + // Set the url, number of POST vars, POST data. + curl_setopt($ch, CURLOPT_URL, $this->delete_work_uri); + curl_setopt($ch, CURLOPT_POST, true); + curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + + // Execute a post request. + $result = curl_exec($ch); + + // Close connection. + curl_close($ch); + + if (!$result) { + $this->errors->add($i18n->get('error.remote_work')); + return false; + } + + $result_array = json_decode($result, true); + + // Check for errors. + $call_status = $result_array['call_status']; + if (!$call_status) { $this->errors->add($i18n->get('error.remote_work')); return false; } + if ($call_status['code'] != TT_CURL_SUCCESS) { + $this->errors->add($call_status['error_localized'] ? $call_status['error_localized'] : $call_status['error']); + return false; + } - $this->file_data = $result_array['content']; return true; } - // getCurrencies - obtains a list of supported currencies. static function getCurrencies() { $mdb2 = getConnection(); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index fbb5c31b1..8d5555820 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.19.10.5070 | Copyright © Anuko | +  Anuko Time Tracker 1.19.10.5071 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/work_delete.tpl b/WEB-INF/templates/work_delete.tpl new file mode 100644 index 000000000..2831b0f15 --- /dev/null +++ b/WEB-INF/templates/work_delete.tpl @@ -0,0 +1,20 @@ +{$forms.workDeleteForm.open} + + + + +
+ + + + + + + + + + + +
{$work_to_delete|escape}
 
{$forms.workDeleteForm.btn_delete.control}  {$forms.workDeleteForm.btn_cancel.control}
+
+{$forms.workDeleteForm.close} diff --git a/work_delete.php b/work_delete.php index 63acf327b..9ba7b9a87 100644 --- a/work_delete.php +++ b/work_delete.php @@ -50,32 +50,28 @@ // TODO: coding ongoing down from here... -$task_to_delete = $task['name']; +$work_to_delete = $work_item['subject']; -$form = new Form('taskDeleteForm'); -$form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_task_id)); +$form = new Form('workDeleteForm'); +$form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_work_id)); $form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->get('label.delete'))); $form->addInput(array('type'=>'submit','name'=>'btn_cancel','value'=>$i18n->get('button.cancel'))); if ($request->isPost()) { if ($request->getParameter('btn_delete')) { - if(ttTaskHelper::get($cl_task_id)) { - if (ttTaskHelper::delete($cl_task_id)) { - header('Location: tasks.php'); - exit(); - } else - $err->add($i18n->get('error.db')); - } else - $err->add($i18n->get('error.db')); + if ($workHelper->deleteWork($cl_work_id)) { + header('Location: work.php'); + exit(); + } } elseif ($request->getParameter('btn_cancel')) { - header('Location: tasks.php'); + header('Location: work.php'); exit(); } } // isPost -$smarty->assign('task_to_delete', $task_to_delete); +$smarty->assign('work_to_delete', $work_to_delete); $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="document.taskDeleteForm.btn_cancel.focus()"'); -$smarty->assign('title', $i18n->get('title.delete_task')); -$smarty->assign('content_page_name', 'task_delete.tpl'); +$smarty->assign('title', $i18n->get('title.delete_work')); +$smarty->assign('content_page_name', 'work_delete.tpl'); $smarty->display('index.tpl'); From 2d530728037081f274d188137f11bbd0c60889ea Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 17 Sep 2019 16:27:08 +0000 Subject: [PATCH 063/877] Added a check for non-empty budget on work_add.php. --- WEB-INF/lib/ttWorkHelper.class.php | 28 ++++++++++++++++------------ WEB-INF/templates/footer.tpl | 2 +- work_add.php | 1 + 3 files changed, 18 insertions(+), 13 deletions(-) diff --git a/WEB-INF/lib/ttWorkHelper.class.php b/WEB-INF/lib/ttWorkHelper.class.php index c8d8944c1..fc20994a7 100644 --- a/WEB-INF/lib/ttWorkHelper.class.php +++ b/WEB-INF/lib/ttWorkHelper.class.php @@ -176,14 +176,15 @@ function putWork($fields) { } $result_array = json_decode($result, true); - $work_id = (int) $result_array['work_id']; - $error = $result_array['error']; - if ($error || !$work_id) { - if ($error) { - // Add an error from remote work server if we have it. - $this->errors->add($error); - } + // Check for errors. + $call_status = $result_array['call_status']; + if (!$call_status) { + $this->errors->add($i18n->get('error.remote_work')); + return false; + } + if ($call_status['code'] != TT_CURL_SUCCESS) { + $this->errors->add($call_status['error_localized'] ? $call_status['error_localized'] : $call_status['error']); return false; } @@ -233,11 +234,14 @@ function getActiveWork() { $result_array = json_decode($result, true); - // Check for error. - $error = $result_array['error']; - if ($error) { - // Add an error from remote work server. - $this->errors->add($error); + // Check for errors. + $call_status = $result_array['call_status']; + if (!$call_status) { + $this->errors->add($i18n->get('error.remote_work')); + return false; + } + if ($call_status['code'] != TT_CURL_SUCCESS) { + $this->errors->add($call_status['error_localized'] ? $call_status['error_localized'] : $call_status['error']); return false; } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 8d5555820..36caaefe6 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.19.10.5071 | Copyright © Anuko | +  Anuko Time Tracker 1.19.10.5072 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/work_add.php b/work_add.php index ed879ef52..b40e15f95 100644 --- a/work_add.php +++ b/work_add.php @@ -79,6 +79,7 @@ if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.thing_name')); if (!ttValidString($cl_description, true)) $err->add($i18n->get('error.field'), $i18n->get('label.description')); if (!ttValidString($cl_details, true)) $err->add($i18n->get('error.field'), $i18n->get('label.details')); + if (!ttValidString($cl_budget)) $err->add($i18n->get('error.field'), $i18n->get('label.budget')); if ($err->no()) { $workHelper = new ttWorkHelper($err); From b9f0941a16201dc88eea9e7d39e0de2a7da5ec69 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 17 Sep 2019 17:28:35 +0000 Subject: [PATCH 064/877] Refactored registration code with Remote Work server. --- WEB-INF/lib/ttWorkHelper.class.php | 25 ++++++++++++++++++------- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/WEB-INF/lib/ttWorkHelper.class.php b/WEB-INF/lib/ttWorkHelper.class.php index fc20994a7..f9cb0ba74 100644 --- a/WEB-INF/lib/ttWorkHelper.class.php +++ b/WEB-INF/lib/ttWorkHelper.class.php @@ -96,17 +96,28 @@ function checkSiteRegistration() { // Close connection. curl_close($ch); + if (!$result) { + $this->errors->add($i18n->get('error.remote_work')); + return false; + } + $result_array = json_decode($result, true); - if (!$result_array) { + + // Check for errors. + $call_status = $result_array['call_status']; + if (!$call_status) { $this->errors->add($i18n->get('error.remote_work')); + return false; } - else if ($result_array['error']) { - // Add an error from remote work server if we have it. - $this->errors->add($result_array['error']); + if ($call_status['code'] != TT_CURL_SUCCESS) { + $this->errors->add($call_status['error_localized'] ? $call_status['error_localized'] : $call_status['error']); + return false; } - else if ($result_array['id'] && $result_array['key']) { - $this->site_id = $result_array['id']; - $this->site_key = $result_array['key']; + + $reg_status = $result_array['reg_status']; // Registration status. + if ($reg_status['site_id'] && $reg_status['site_key']) { + $this->site_id = $reg_status['site_id']; + $this->site_key = $reg_status['site_key']; // Registration successful. Store id and key locally for future use. $sql = "insert into tt_site_config values('worksite_id', $this->site_id, now(), null)"; diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 36caaefe6..299e87d1e 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.19.10.5072 | Copyright © Anuko | +  Anuko Time Tracker 1.19.10.5073 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From c055372b354325440b2dc235dd6961be8736e4dc Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 17 Sep 2019 20:25:19 +0000 Subject: [PATCH 065/877] Added language to an API call. --- WEB-INF/lib/ttWorkHelper.class.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/WEB-INF/lib/ttWorkHelper.class.php b/WEB-INF/lib/ttWorkHelper.class.php index f9cb0ba74..b30f04d37 100644 --- a/WEB-INF/lib/ttWorkHelper.class.php +++ b/WEB-INF/lib/ttWorkHelper.class.php @@ -64,8 +64,8 @@ function __construct(&$errors) { // checkSiteRegistration - obtains site id and key from local database. // If not found, it tries to register with remote work server. function checkSiteRegistration() { - global $i18n; + global $user; $mdb2 = getConnection(); // Obtain site id. @@ -74,7 +74,8 @@ function checkSiteRegistration() { $val = $res->fetchRow(); if (!$val) { // No site id found, need to register. - $fields = array('name' => urlencode('time tracker'), + $fields = array('lang' => urlencode($user->lang), + 'name' => urlencode('time tracker'), 'origin' => urlencode('time tracker source')); // Urlify the data for the POST. From 46307636f3f7d4906b789d17c7b6e37f01b266ca Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 17 Sep 2019 23:30:22 +0000 Subject: [PATCH 066/877] Integrated some German strings from pr#81, the ones that seemed okay to do. Put clarifying comments for others. --- WEB-INF/resources/de.lang.php | 44 +++++++++++++++++------------------ WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 22 insertions(+), 24 deletions(-) diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index 54321626f..4920b8bc7 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -38,6 +38,7 @@ // Menus - short selection strings that are displayed on top of application web pages. // Example: https://timetracker.anuko.com (black menu on top). +// Note to translators: try to keep menu strings short so that we don't run out of display room. 'menu.login' => 'Anmelden', 'menu.logout' => 'Abmelden', 'menu.forum' => 'Forum', @@ -48,8 +49,7 @@ 'menu.group' => 'Gruppe', 'menu.plugins' => 'Erweiterungen', 'menu.time' => 'Zeiten', -// TODO: translate the following. -// 'menu.week' => 'Week', +'menu.week' => 'Woche', 'menu.expenses' => 'Kosten', 'menu.reports' => 'Berichte', // TODO: translate the following. @@ -115,13 +115,12 @@ // 'error.remote_work' => 'Remote work server error.', // Warning messages. +'warn.sure' => 'Sind Sie sicher?', // TODO: translate the following. -// 'warn.sure' => 'Are you sure?', // 'warn.confirm_save' => 'Date has changed. Confirm saving, not copying this item.', // Success messages. -// TODO: translate the following. -// 'msg.success' => 'Operation completed successfully.', +'msg.success' => 'Operation vollständig abgeschlossen.', // Labels for buttons. 'button.login' => 'Anmelden', @@ -142,7 +141,9 @@ 'button.close' => 'Schließen', 'button.stop' => 'Stop', // TODO: translate the following. -// 'button.approve' => 'Approve', +// (PR#81 suggested 'Freigeben / Genehmigen' for 'Approve' and 'Freigabe zurücknehmen' for 'Disapprove'. +// The problem is they do not appear precise, deviate from the meaning of approval / disaproval of report items.) +// 'button.approve' => 'Approve', (suggested 'Freigeben / Genehmigen' does not appear precise) // 'button.disapprove' => 'Disapprove', // Labels for controls on forms. Labels in this section are used on multiple forms. @@ -223,8 +224,7 @@ 'label.condition' => 'Bedingung', 'label.yes' => 'Ja', 'label.no' => 'Nein', -// TODO: translate the following. -// 'label.sort' => 'Sort', +'label.sort' => 'Sortieren', // Labels for plugins (extensions to Time Tracker that provide additional features). 'label.custom_fields' => 'Benutzerfelder', 'label.monthly_quotas' => 'Monatliche Quoten', @@ -242,7 +242,7 @@ 'label.paid_status' => 'Bezahlstatus', 'label.paid' => 'Bezahlt', 'label.mark_paid' => 'Als bezahlt setzen', -// 'label.week_menu' => 'Week menu', +'label.week_menu' => 'Wochenansicht im Menü', 'label.week_note' => 'Wochennotiz', 'label.week_list' => 'Wochenliste', 'label.work_units' => 'Arbeitseinheiten', @@ -263,9 +263,12 @@ // 'label.download' => 'Download', 'label.active_users' => 'Aktive Nutzer', 'label.inactive_users' => 'Inaktive Nutzer', -// TODO: translate the following. +// TODO: translate the following or confirm that "Details" is also correct for German (exactly as the English string). +// label.details is used to identify a field for LONG DESCRIPTION of a work item used in Remote Work plugin. +// For example, a work item could be "Design a logo", and the Details hold EXACT anfd PRECISE specs of what a customer needs. +// Another use is with offers with Remote Work plugin, where details hold a long, precise, and complete description of the offer. // 'label.details' => 'Details', -// 'label.budget' => 'Budget', +'label.budget' => 'Budget', // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. @@ -276,8 +279,7 @@ // Form titles. 'title.error' => 'Fehler', -// TODO: Translate the following. -// 'title.success' => 'Success', +'title.success' => 'Erfol', 'title.login' => 'Anmelden', 'title.groups' => 'Gruppen', // TODO: translate the following. @@ -306,8 +308,7 @@ 'title.send_invoice' => 'Rechnung senden', 'title.charts' => 'Diagramme', 'title.projects' => 'Projekte', -// TODO: translate the following. -// 'title.project_files' => 'Project Files', +'title.project_files' => 'Projekt-Dateien', 'title.add_project' => 'Projekt anlegen', 'title.edit_project' => 'Projekt bearbeiten', 'title.delete_project' => 'Projekt löschen', @@ -343,8 +344,7 @@ 'title.export' => 'Daten exportieren', 'title.import' => 'Daten importieren', 'title.options' => 'Optionen', -// TODO: translate the following. -// 'title.display_options' => 'Display Options', +'title.display_options' => 'Anzeige-Optionen', 'title.profile' => 'Profil', 'title.plugins' => 'Erweiterungen', 'title.cf_custom_fields' => 'Benutzerfelder', @@ -551,9 +551,8 @@ // Group Settings form. See example at https://timetracker.anuko.com/group_edit.php. 'form.group_edit.12_hours' => '12 Stunden', 'form.group_edit.24_hours' => '24 Stunden', -// TODO: translate the following. -// 'form.group_edit.display_options' => 'Display options', -// 'form.group_edit.holidays' => 'Holidays', +'form.group_edit.display_options' => 'Anzeige-Optionen', +'form.group_edit.holidays' => 'Feiertage', 'form.group_edit.tracking_mode' => 'Nachverfolgung', 'form.group_edit.mode_time' => 'Zeit', 'form.group_edit.mode_projects' => 'Projekte', @@ -566,8 +565,7 @@ 'form.group_edit.allow_overlap' => 'Erlaube Überschneidung', 'form.group_edit.future_entries' => 'Einträge in der Zukunft', 'form.group_edit.uncompleted_indicators' => 'Zeige unfertige Einträge', -// TODO: translate the following. -// 'form.group_edit.confirm_save' => 'Confirm saving', +'form.group_edit.confirm_save' => 'Speichern bestätigen', 'form.group_edit.allow_ip' => 'Erlaube IP', // TODO: translate the following. // 'form.group_edit.advanced_settings' => 'Advanced settings', @@ -634,5 +632,5 @@ // Display Options form. See example at https://timetracker.anuko.com/display_options.php. // TODO: translate the following. // 'form.display_options.menu' => 'Menu', -// 'form.display_options.note_on_separate_row' => 'Note on separate row', +'form.display_options.note_on_separate_row' => 'Beschreibung in separater Zeile', ); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 299e87d1e..23932842c 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.19.10.5073 | Copyright © Anuko | +  Anuko Time Tracker 1.19.10.5074 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From be00bf4ec152de93bd24cbbead8c205c8f4233cb Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 18 Sep 2019 12:38:40 +0000 Subject: [PATCH 067/877] Added language identifier to API calls for localized error messages back. --- WEB-INF/lib/ttWorkHelper.class.php | 13 ++++++++----- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/WEB-INF/lib/ttWorkHelper.class.php b/WEB-INF/lib/ttWorkHelper.class.php index b30f04d37..5c83eabcc 100644 --- a/WEB-INF/lib/ttWorkHelper.class.php +++ b/WEB-INF/lib/ttWorkHelper.class.php @@ -149,13 +149,13 @@ function putWork($fields) { $group_id = $user->getGroup(); $org_id = $user->org_id; - $curl_fields = array('site_id' => urlencode($this->site_id), + $curl_fields = array('lang' => urlencode($user->lang), + 'site_id' => urlencode($this->site_id), 'site_key' => urlencode($this->site_key), 'org_id' => urlencode($org_id), 'org_key' => urlencode($user->getOrgKey()), 'group_id' => urlencode($group_id), 'group_key' => urlencode($user->getGroupKey()), - 'lang' => urlencode($user->lang), 'subject' => urlencode($fields['subject']), 'descr_short' => urlencode($fields['descr_short']), 'descr_long' => urlencode($fields['descr_long']), @@ -212,7 +212,8 @@ function getActiveWork() { $group_id = $user->getGroup(); $org_id = $user->org_id; - $curl_fields = array('site_id' => urlencode($this->site_id), + $curl_fields = array('lang' => urlencode($user->lang), + 'site_id' => urlencode($this->site_id), 'site_key' => urlencode($this->site_key), 'org_id' => urlencode($org_id), 'org_key' => urlencode($user->getOrgKey()), @@ -270,7 +271,8 @@ function getWork($work_id) { $group_id = $user->getGroup(); $org_id = $user->org_id; - $curl_fields = array('site_id' => urlencode($this->site_id), + $curl_fields = array('lang' => urlencode($user->lang), + 'site_id' => urlencode($this->site_id), 'site_key' => urlencode($this->site_key), 'org_id' => urlencode($org_id), 'org_key' => urlencode($user->getOrgKey()), @@ -328,7 +330,8 @@ function deleteWork($work_id) { $group_id = $user->getGroup(); $org_id = $user->org_id; - $curl_fields = array('site_id' => urlencode($this->site_id), + $curl_fields = array('lang' => urlencode($user->lang), + 'site_id' => urlencode($this->site_id), 'site_key' => urlencode($this->site_key), 'org_id' => urlencode($org_id), 'org_key' => urlencode($user->getOrgKey()), diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 23932842c..5a1d83f4d 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.19.10.5074 | Copyright © Anuko | +  Anuko Time Tracker 1.19.10.5075 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 85e51ff5f889333e5f8e61639545bfa490350230 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 18 Sep 2019 12:48:19 +0000 Subject: [PATCH 068/877] A bit more refactoring. --- WEB-INF/lib/ttWorkHelper.class.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/WEB-INF/lib/ttWorkHelper.class.php b/WEB-INF/lib/ttWorkHelper.class.php index 5c83eabcc..3406ea0aa 100644 --- a/WEB-INF/lib/ttWorkHelper.class.php +++ b/WEB-INF/lib/ttWorkHelper.class.php @@ -111,7 +111,7 @@ function checkSiteRegistration() { return false; } if ($call_status['code'] != TT_CURL_SUCCESS) { - $this->errors->add($call_status['error_localized'] ? $call_status['error_localized'] : $call_status['error']); + $this->errors->add($call_status['error']); return false; } @@ -196,7 +196,7 @@ function putWork($fields) { return false; } if ($call_status['code'] != TT_CURL_SUCCESS) { - $this->errors->add($call_status['error_localized'] ? $call_status['error_localized'] : $call_status['error']); + $this->errors->add($call_status['error']); return false; } @@ -254,7 +254,7 @@ function getActiveWork() { return false; } if ($call_status['code'] != TT_CURL_SUCCESS) { - $this->errors->add($call_status['error_localized'] ? $call_status['error_localized'] : $call_status['error']); + $this->errors->add($call_status['error']); return false; } @@ -313,7 +313,7 @@ function getWork($work_id) { return false; } if ($call_status['code'] != TT_CURL_SUCCESS) { - $this->errors->add($call_status['error_localized'] ? $call_status['error_localized'] : $call_status['error']); + $this->errors->add($call_status['error']); return false; } @@ -372,7 +372,7 @@ function deleteWork($work_id) { return false; } if ($call_status['code'] != TT_CURL_SUCCESS) { - $this->errors->add($call_status['error_localized'] ? $call_status['error_localized'] : $call_status['error']); + $this->errors->add($call_status['error']); return false; } From 829e4d4ac734c1489dbc67b1740d1baa99711f4e Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 19 Sep 2019 12:13:27 +0000 Subject: [PATCH 069/877] More progress on Remote Work plugin, implemented update work. --- WEB-INF/lib/ttWorkHelper.class.php | 97 ++++++++++++++++++++++++-- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/work_edit.tpl | 47 +++++++++++++ work_add.php | 17 ++--- work_delete.php | 2 +- work_edit.php | 107 +++++++++++++++++++++++++++++ 6 files changed, 250 insertions(+), 22 deletions(-) create mode 100644 WEB-INF/templates/work_edit.tpl create mode 100644 work_edit.php diff --git a/WEB-INF/lib/ttWorkHelper.class.php b/WEB-INF/lib/ttWorkHelper.class.php index 3406ea0aa..7cc868c33 100644 --- a/WEB-INF/lib/ttWorkHelper.class.php +++ b/WEB-INF/lib/ttWorkHelper.class.php @@ -28,7 +28,8 @@ define('TT_CURL_SUCCESS', 1); -// Class ttWorkHelper is used to help with operations with the Remote work plugin. +// Class ttWorkHelper is used to help with operations with the Remote Work plugin. +// It does everything via curl calls to a Remote Work server using its API. class ttWorkHelper { var $errors = null; // Errors go here. Set in constructor by reference. var $remote_work_uri = null; // Location of remote work server. @@ -47,9 +48,14 @@ class ttWorkHelper { function __construct(&$errors) { $this->errors = &$errors; + // Note: at some point a need will arise for API versioning. + // When this happens, we will append an API version number to the end of URI, + // for example: register_0_1 instead of register. + // This should theoretically allow a remote work server to be able to work with + // a complete variety of deployed clients, including those without versions. if (defined('REMOTE_WORK_URI')) { $this->remote_work_uri = REMOTE_WORK_URI; - $this->register_uri = $this->remote_work_uri.'register'; + $this->register_uri = $this->remote_work_uri.'register'; // register_0_0 $this->put_work_uri = $this->remote_work_uri.'putwork'; $this->get_work_uri = $this->remote_work_uri.'getwork'; $this->get_active_work_uri = $this->remote_work_uri.'getactivework'; @@ -141,6 +147,20 @@ function checkSiteRegistration() { } // putWork - publishes a work item in remote work server. + // + // Note about some fields using additional base64 encoding. + // There is a problem with data posted by curl calls on the server side for + // some languages. Data arrives corrupted. + // + // For example: consider a case for a single Russian letter ф in the subject field. + // UTF-8 encoding for ф: 0xD1 0x84 (2 bytes). + // urlencoded ф: %D1%84 - a string of 6 characters. + // If we use a curl call like here with only urlencoded ф, what arrives on the server in POST is "C3 91 C2 84" + // no idea what it is. + // + // A workaround for now is to use use an additional base64 encoding for all text fields, + // which are decoded back to utf-8 strings on the server side. + function putWork($fields) { global $i18n; global $user; @@ -148,7 +168,6 @@ function putWork($fields) { $group_id = $user->getGroup(); $org_id = $user->org_id; - $curl_fields = array('lang' => urlencode($user->lang), 'site_id' => urlencode($this->site_id), 'site_key' => urlencode($this->site_key), @@ -156,9 +175,9 @@ function putWork($fields) { 'org_key' => urlencode($user->getOrgKey()), 'group_id' => urlencode($group_id), 'group_key' => urlencode($user->getGroupKey()), - 'subject' => urlencode($fields['subject']), - 'descr_short' => urlencode($fields['descr_short']), - 'descr_long' => urlencode($fields['descr_long']), + 'subject' => urlencode(base64_encode($fields['subject'])), + 'descr_short' => urlencode(base64_encode($fields['descr_short'])), + 'descr_long' => urlencode(base64_encode($fields['descr_long'])), 'currency' => urlencode($fields['currency']), 'amount' => urlencode($fields['amount']) ); @@ -203,6 +222,70 @@ function putWork($fields) { return true; } + // updateWork - updates a work item in remote work server. + function updateWork($fields) { + global $i18n; + global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $curl_fields = array('lang' => urlencode($user->lang), + 'site_id' => urlencode($this->site_id), + 'site_key' => urlencode($this->site_key), + 'org_id' => urlencode($org_id), + 'org_key' => urlencode($user->getOrgKey()), + 'group_id' => urlencode($group_id), + 'group_key' => urlencode($user->getGroupKey()), + 'work_id' => urlencode($fields['work_id']), + 'subject' => urlencode(base64_encode($fields['subject'])), + 'descr_short' => urlencode(base64_encode($fields['descr_short'])), + 'descr_long' => urlencode(base64_encode($fields['descr_long'])), + 'currency' => urlencode($fields['currency']), + 'amount' => urlencode($fields['amount']) + ); + + // url-ify the data for the POST. + foreach($curl_fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; } + $fields_string = rtrim($fields_string, '&'); + + // Open connection. + $ch = curl_init(); + + // Set the url, number of POST vars, POST data. + curl_setopt($ch, CURLOPT_URL, $this->update_work_uri); + curl_setopt($ch, CURLOPT_POST, true); + curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + + // Execute a post request. + $result = curl_exec($ch); + + // Close connection. + curl_close($ch); + + if (!$result) { + $this->errors->add($i18n->get('error.remote_work')); + return false; + } + + $result_array = json_decode($result, true); + + // Check for errors. + $call_status = $result_array['call_status']; + if (!$call_status) { + $this->errors->add($i18n->get('error.remote_work')); + return false; + } + if ($call_status['code'] != TT_CURL_SUCCESS) { + $this->errors->add($call_status['error']); + return false; + } + + return true; + } + // getActiveWork - obtains a list of work items this group is currently oputsourcing. function getActiveWork() { global $i18n; @@ -388,7 +471,7 @@ static function getCurrencies() { if (is_a($res, 'PEAR_Error')) return false; while ($val = $res->fetchRow()) { - $result[] = $val; + $result[] = $val['name']; } return $result; } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 5a1d83f4d..d287e2253 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.19.10.5075 | Copyright © Anuko | +  Anuko Time Tracker 1.19.10.5076 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/work_edit.tpl b/WEB-INF/templates/work_edit.tpl new file mode 100644 index 000000000..792457226 --- /dev/null +++ b/WEB-INF/templates/work_edit.tpl @@ -0,0 +1,47 @@ +{$forms.workForm.open} + + + + +
+ + + + + + + + + + + + + +{if $show_files} + + + + +{/if} + + + + + + + + + + + + + + + + + + + +
{$i18n.label.thing_name} (*):{$forms.workForm.work_name.control}
{$i18n.label.description}:{$forms.workForm.description.control}
{$i18n.label.details}:{$forms.workForm.details.control}
{$i18n.label.file}:{$forms.workForm.newfile.control}
{$i18n.label.currency}:{$forms.workForm.currency.control}
{$i18n.label.budget} (*):{$forms.workForm.budget.control}
{$i18n.label.required_fields}
 
{$forms.workForm.btn_save.control}
+
+{$forms.workForm.close} diff --git a/work_add.php b/work_add.php index b40e15f95..413546864 100644 --- a/work_add.php +++ b/work_add.php @@ -28,9 +28,6 @@ require_once('initialize.php'); import('form.Form'); -import('ttProjectHelper'); -import('ttGroupHelper'); -import('ttFileHelper'); import('ttWorkHelper'); // Access checks. @@ -58,11 +55,9 @@ $form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'work_name','style'=>'width: 250px;','value'=>$cl_name)); $form->addInput(array('type'=>'textarea','name'=>'description','style'=>'width: 250px; height: 40px;','value'=>$cl_description)); $form->addInput(array('type'=>'textarea','name'=>'details','style'=>'width: 250px; height: 80px;','value'=>$cl_details)); -if ($showFiles) - $form->addInput(array('type'=>'upload','name'=>'newfile','value'=>$i18n->get('button.submit'))); // Add a dropdown for currency. $currencies = ttWorkHelper::getCurrencies(); -$form->addInput(array('type'=>'combobox','name'=>'currency','data'=>$currencies,'datakeys'=>array('id','name'),'value'=>$cl_currency)); +$form->addInput(array('type'=>'combobox','name'=>'currency','data'=>$currencies,'value'=>$cl_currency)); $form->addInput(array('type'=>'floatfield','maxlength'=>'10','name'=>'budget','format'=>'.2','value'=>$cl_budget)); $form->addInput(array('type'=>'submit','name'=>'btn_add','value'=>$i18n->get('button.add'))); @@ -86,10 +81,9 @@ $fields = array('subject'=>$cl_name, 'descr_short' => $cl_description, 'descr_long' => $cl_details, - 'currency' => $currencies[$cl_currency - 1]['name'], + 'currency' => $currencies[$cl_currency], 'amount' => $cl_budget); - $id = $workHelper->putWork($fields); - if ($id) { + if ($workHelper->putWork($fields)) { header('Location: work.php'); exit(); } @@ -97,10 +91,7 @@ } // isPost $smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('onload', 'onLoad="document.projectForm.project_name.focus()"'); -$smarty->assign('show_files', $showFiles); -$smarty->assign('show_users', count($users) > 0); -$smarty->assign('show_tasks', $show_tasks); +$smarty->assign('onload', 'onLoad="document.workForm.work_name.focus()"'); $smarty->assign('title', $i18n->get('title.add_work')); $smarty->assign('content_page_name', 'work_add.tpl'); $smarty->display('index.tpl'); diff --git a/work_delete.php b/work_delete.php index 9ba7b9a87..c0cd443d2 100644 --- a/work_delete.php +++ b/work_delete.php @@ -71,7 +71,7 @@ $smarty->assign('work_to_delete', $work_to_delete); $smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('onload', 'onLoad="document.taskDeleteForm.btn_cancel.focus()"'); +$smarty->assign('onload', 'onLoad="document.workDeleteForm.btn_cancel.focus()"'); $smarty->assign('title', $i18n->get('title.delete_work')); $smarty->assign('content_page_name', 'work_delete.tpl'); $smarty->display('index.tpl'); diff --git a/work_edit.php b/work_edit.php new file mode 100644 index 000000000..094e2058b --- /dev/null +++ b/work_edit.php @@ -0,0 +1,107 @@ +isPluginEnabled('wk')) { + header('Location: feature_disabled.php'); + exit(); +} +$cl_work_id = (int)$request->getParameter('id'); +$workHelper = new ttWorkHelper($err); +$work_item = $workHelper->getWork($cl_work_id); +if (!$work_item) { + header('Location: access_denied.php'); + exit(); +} +// End of access checks. + +$currencies = ttWorkHelper::getCurrencies(); + +if ($request->isPost()) { + $cl_name = trim($request->getParameter('work_name')); + $cl_description = trim($request->getParameter('description')); + $cl_details = trim($request->getParameter('details')); + $cl_currency = $request->getParameter('currency'); + $cl_budget = $request->getParameter('budget'); +} else { + $cl_name = $work_item['subject']; + $cl_description = $work_item['descr_short']; + $cl_details = $work_item['descr_long']; + $currency = $work_item['currency']; + $cl_currency = array_search($currency, $currencies); + $cl_budget = $work_item['amount']; +} + +$form = new Form('workForm'); +$form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_work_id)); +$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'work_name','style'=>'width: 250px;','value'=>$cl_name)); +$form->addInput(array('type'=>'textarea','name'=>'description','style'=>'width: 250px; height: 40px;','value'=>$cl_description)); +$form->addInput(array('type'=>'textarea','name'=>'details','style'=>'width: 250px; height: 80px;','value'=>$cl_details)); +$form->addInput(array('type'=>'combobox','name'=>'currency','data'=>$currencies,'value'=>$cl_currency)); +$form->addInput(array('type'=>'floatfield','maxlength'=>'10','name'=>'budget','format'=>'.2','value'=>$cl_budget)); +$form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); + +// TODO: coding ongoing down from here... + + +if ($request->isPost()) { + // Validate user input. + if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.thing_name')); + if (!ttValidString($cl_description, true)) $err->add($i18n->get('error.field'), $i18n->get('label.description')); + if (!ttValidString($cl_details, true)) $err->add($i18n->get('error.field'), $i18n->get('label.details')); + if (!ttValidString($cl_budget)) $err->add($i18n->get('error.field'), $i18n->get('label.budget')); + + if ($err->no()) { + if ($request->getParameter('btn_save')) { + // Update work information. + $fields = array('work_id'=>$cl_work_id, + 'subject'=>$cl_name, + 'descr_short' => $cl_description, + 'descr_long' => $cl_details, + 'currency' => $currencies[$cl_currency], + 'amount' => $cl_budget); + if ($workHelper->updateWork($fields)) { + header('Location: work.php'); + exit(); + } + } + } +} // isPost + +$smarty->assign('forms', array($form->getName()=>$form->toArray())); +$smarty->assign('title', $i18n->get('title.edit_work')); +$smarty->assign('content_page_name', 'work_edit.tpl'); +$smarty->display('index.tpl'); From 400e8952256f8506c87d8253d757798309106d84 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 19 Sep 2019 13:37:51 +0000 Subject: [PATCH 070/877] Added offer_add.php and code to support it. --- WEB-INF/lib/ttWorkHelper.class.php | 80 +++++++++++++++++++++++++-- WEB-INF/resources/ca.lang.php | 3 ++ WEB-INF/resources/cs.lang.php | 3 ++ WEB-INF/resources/da.lang.php | 3 ++ WEB-INF/resources/de.lang.php | 3 ++ WEB-INF/resources/en.lang.php | 3 ++ WEB-INF/resources/es.lang.php | 3 ++ WEB-INF/resources/et.lang.php | 3 ++ WEB-INF/resources/fa.lang.php | 3 ++ WEB-INF/resources/fi.lang.php | 3 ++ WEB-INF/resources/fr.lang.php | 3 ++ WEB-INF/resources/gr.lang.php | 3 ++ WEB-INF/resources/he.lang.php | 3 ++ WEB-INF/resources/hu.lang.php | 3 ++ WEB-INF/resources/it.lang.php | 3 ++ WEB-INF/resources/ja.lang.php | 3 ++ WEB-INF/resources/ko.lang.php | 3 ++ WEB-INF/resources/nl.lang.php | 4 ++ WEB-INF/resources/no.lang.php | 3 ++ WEB-INF/resources/pl.lang.php | 3 ++ WEB-INF/resources/pt-br.lang.php | 3 ++ WEB-INF/resources/pt.lang.php | 3 ++ WEB-INF/resources/ro.lang.php | 3 ++ WEB-INF/resources/ru.lang.php | 3 ++ WEB-INF/resources/sk.lang.php | 3 ++ WEB-INF/resources/sl.lang.php | 3 ++ WEB-INF/resources/sr.lang.php | 3 ++ WEB-INF/resources/sv.lang.php | 3 ++ WEB-INF/resources/tr.lang.php | 3 ++ WEB-INF/resources/zh-cn.lang.php | 3 ++ WEB-INF/resources/zh-tw.lang.php | 3 ++ WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/offer_add.tpl | 47 ++++++++++++++++ offer_add.php | 87 ++++++++++++++++++++++++++++++ work_add.php | 2 - 35 files changed, 302 insertions(+), 7 deletions(-) create mode 100644 WEB-INF/templates/offer_add.tpl create mode 100644 offer_add.php diff --git a/WEB-INF/lib/ttWorkHelper.class.php b/WEB-INF/lib/ttWorkHelper.class.php index 7cc868c33..465f06cbf 100644 --- a/WEB-INF/lib/ttWorkHelper.class.php +++ b/WEB-INF/lib/ttWorkHelper.class.php @@ -34,13 +34,19 @@ class ttWorkHelper { var $errors = null; // Errors go here. Set in constructor by reference. var $remote_work_uri = null; // Location of remote work server. var $register_uri = null; // URI to register with remote work server. - var $put_work_uri = null; // URI to publish offer. - var $get_work_uri = null; // URI to get offer details. + var $put_work_uri = null; // URI to publish work. + var $get_work_uri = null; // URI to get work details. var $get_active_work_uri = null; // URI to get active work for group. var $get_available_work_uri = null; // URI to get available work for group. - var $delete_work_uri = null; // URI to delete eotk. + var $delete_work_uri = null; // URI to delete work. // TODO: design how (and what) to delete when a group is deleted. var $update_work_uri = null; // URI to update work. + var $put_offer_uri = null; // URI to publish offer. + var $get_offer_uri = null; // URI to get offer details. + var $get_active_offers_uri = null; // URI to get active offers. + var $get_available_offers_uri = null; // URI to get available offers. + var $delete_offer_uri = null; // URI to delete offer. + var $delete_offers_uri = null; // URI to delete multiple offers. var $site_id = null; // Site id for remote work server. var $site_key = null; // Site key for remote work server. @@ -60,9 +66,14 @@ function __construct(&$errors) { $this->get_work_uri = $this->remote_work_uri.'getwork'; $this->get_active_work_uri = $this->remote_work_uri.'getactivework'; $this->get_avaialable_work_uri = $this->remote_work_uri.'getavailablework'; - $this->delete_work_uri = $this->remote_work_uri.'deletework'; $this->update_work_uri = $this->remote_work_uri.'updatework'; + $this->put_offer_uri = $this->remote_work_uri.'putoffer'; + $this->get_offer_uri = $this->remote_work_uri.'getoffer'; + $this->get_active_offers_uri = $this->remote_work_uri.'getactiveoffers'; + $this->get_avaialable_offers_uri = $this->remote_work_uri.'getavailableoffers'; + $this->delete_offer_uri = $this->remote_work_uri.'deleteoffer'; + $this->update_offer_uri = $this->remote_work_uri.'updateoffer'; $this->checkSiteRegistration(); } } @@ -462,6 +473,67 @@ function deleteWork($work_id) { return true; } + function putOffer($fields) { + global $i18n; + global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + $curl_fields = array('lang' => urlencode($user->lang), + 'site_id' => urlencode($this->site_id), + 'site_key' => urlencode($this->site_key), + 'org_id' => urlencode($org_id), + 'org_key' => urlencode($user->getOrgKey()), + 'group_id' => urlencode($group_id), + 'group_key' => urlencode($user->getGroupKey()), + 'subject' => urlencode(base64_encode($fields['subject'])), + 'descr_short' => urlencode(base64_encode($fields['descr_short'])), + 'descr_long' => urlencode(base64_encode($fields['descr_long'])), + 'currency' => urlencode($fields['currency']), + 'amount' => urlencode($fields['amount']) + ); + + // url-ify the data for the POST. + foreach($curl_fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; } + $fields_string = rtrim($fields_string, '&'); + + // Open connection. + $ch = curl_init(); + + // Set the url, number of POST vars, POST data. + curl_setopt($ch, CURLOPT_URL, $this->put_offer_uri); + curl_setopt($ch, CURLOPT_POST, true); + curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + + // Execute a post request. + $result = curl_exec($ch); + + // Close connection. + curl_close($ch); + + if (!$result) { + $this->errors->add($i18n->get('error.remote_work')); + return false; + } + + $result_array = json_decode($result, true); + + // Check for errors. + $call_status = $result_array['call_status']; + if (!$call_status) { + $this->errors->add($i18n->get('error.remote_work')); + return false; + } + if ($call_status['code'] != TT_CURL_SUCCESS) { + $this->errors->add($call_status['error']); + return false; + } + + return true; + } + // getCurrencies - obtains a list of supported currencies. static function getCurrencies() { $mdb2 = getConnection(); diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index 2730902a0..1a7c60d95 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -406,6 +406,9 @@ // 'title.delete_work' => 'Deleting Work', // 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. +// 'title.add_offer' => 'Adding Offer', +// 'title.edit_offer' => 'Editing Offer', +// 'title.delete_offer' => 'Deleting Offer', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index 1ba723029..26d23341d 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -416,6 +416,9 @@ // 'title.delete_work' => 'Deleting Work', // 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. +// 'title.add_offer' => 'Adding Offer', +// 'title.edit_offer' => 'Editing Offer', +// 'title.delete_offer' => 'Deleting Offer', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index de3b796be..7baf95e85 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -388,6 +388,9 @@ // 'title.delete_work' => 'Deleting Work', // 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. +// 'title.add_offer' => 'Adding Offer', +// 'title.edit_offer' => 'Editing Offer', +// 'title.delete_offer' => 'Deleting Offer', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index 4920b8bc7..74095a635 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -373,6 +373,9 @@ // 'title.delete_work' => 'Deleting Work', // 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. +// 'title.add_offer' => 'Adding Offer', +// 'title.edit_offer' => 'Editing Offer', +// 'title.delete_offer' => 'Deleting Offer', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index c95b60eeb..5789f8fc2 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -355,6 +355,9 @@ 'title.delete_work' => 'Deleting Work', 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. +'title.add_offer' => 'Adding Offer', +'title.edit_offer' => 'Editing Offer', +'title.delete_offer' => 'Deleting Offer', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index d36d6421e..55c2875f8 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -405,6 +405,9 @@ // 'title.delete_work' => 'Deleting Work', // 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. +// 'title.add_offer' => 'Adding Offer', +// 'title.edit_offer' => 'Editing Offer', +// 'title.delete_offer' => 'Deleting Offer', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index 39c447848..ce318aaa3 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -396,6 +396,9 @@ // 'title.delete_work' => 'Deleting Work', // 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. +// 'title.add_offer' => 'Adding Offer', +// 'title.edit_offer' => 'Editing Offer', +// 'title.delete_offer' => 'Deleting Offer', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index 33b0e6847..d3a5aa285 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -397,6 +397,9 @@ // 'title.delete_work' => 'Deleting Work', // 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. +// 'title.add_offer' => 'Adding Offer', +// 'title.edit_offer' => 'Editing Offer', +// 'title.delete_offer' => 'Deleting Offer', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 59fca15fa..695401a2b 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -388,6 +388,9 @@ // 'title.delete_work' => 'Deleting Work', // 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. +// 'title.add_offer' => 'Adding Offer', +// 'title.edit_offer' => 'Editing Offer', +// 'title.delete_offer' => 'Deleting Offer', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index a1a50a9e9..fa9cfc391 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -382,6 +382,9 @@ // 'title.delete_work' => 'Deleting Work', // 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. +// 'title.add_offer' => 'Adding Offer', +// 'title.edit_offer' => 'Editing Offer', +// 'title.delete_offer' => 'Deleting Offer', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index e40932a29..7e871bcd2 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -381,6 +381,9 @@ // 'title.delete_work' => 'Deleting Work', // 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. +// 'title.add_offer' => 'Adding Offer', +// 'title.edit_offer' => 'Editing Offer', +// 'title.delete_offer' => 'Deleting Offer', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index 2412d630a..ea67f691b 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -405,6 +405,9 @@ // 'title.delete_work' => 'Deleting Work', // 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. +// 'title.add_offer' => 'Adding Offer', +// 'title.edit_offer' => 'Editing Offer', +// 'title.delete_offer' => 'Deleting Offer', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index 2c81071f7..e596323c8 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -406,6 +406,9 @@ // 'title.delete_work' => 'Deleting Work', // 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. +// 'title.add_offer' => 'Adding Offer', +// 'title.edit_offer' => 'Editing Offer', +// 'title.delete_offer' => 'Deleting Offer', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index 86843eb05..c3c7c25f5 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -391,6 +391,9 @@ // 'title.delete_work' => 'Deleting Work', // 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. +// 'title.add_offer' => 'Adding Offer', +// 'title.edit_offer' => 'Editing Offer', +// 'title.delete_offer' => 'Deleting Offer', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index 2a4568ec3..a0ad03dca 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -412,6 +412,9 @@ // 'title.delete_work' => 'Deleting Work', // 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. +// 'title.add_offer' => 'Adding Offer', +// 'title.edit_offer' => 'Editing Offer', +// 'title.delete_offer' => 'Deleting Offer', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index b9a39d3bf..cd245b045 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -413,6 +413,9 @@ // 'title.delete_work' => 'Deleting Work', // 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. +// 'title.add_offer' => 'Adding Offer', +// 'title.edit_offer' => 'Editing Offer', +// 'title.delete_offer' => 'Deleting Offer', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index a2f3cd1ad..e1a2b62d4 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -361,6 +361,10 @@ 'title.delete_work' => 'Werk verwijderen', 'title.active_work' => 'Actief werk', 'title.inactive_work' => 'Inactief werk', +// TODO: translate the following. +// 'title.add_offer' => 'Adding Offer', +// 'title.edit_offer' => 'Editing Offer', +// 'title.delete_offer' => 'Deleting Offer', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index bb3bd2511..66ea8f183 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -409,6 +409,9 @@ // 'title.delete_work' => 'Deleting Work', // 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. +// 'title.add_offer' => 'Adding Offer', +// 'title.edit_offer' => 'Editing Offer', +// 'title.delete_offer' => 'Deleting Offer', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index be92051e6..ef55444c8 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -391,6 +391,9 @@ // 'title.delete_work' => 'Deleting Work', // 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. +// 'title.add_offer' => 'Adding Offer', +// 'title.edit_offer' => 'Editing Offer', +// 'title.delete_offer' => 'Deleting Offer', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index d479a4d65..02a29d94e 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -386,6 +386,9 @@ // 'title.delete_work' => 'Deleting Work', // 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. +// 'title.add_offer' => 'Adding Offer', +// 'title.edit_offer' => 'Editing Offer', +// 'title.delete_offer' => 'Deleting Offer', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index 46e1d6eac..4c295c61b 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -393,6 +393,9 @@ // 'title.delete_work' => 'Deleting Work', // 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. +// 'title.add_offer' => 'Adding Offer', +// 'title.edit_offer' => 'Editing Offer', +// 'title.delete_offer' => 'Deleting Offer', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index e2221d7cb..38f2a9f1d 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -411,6 +411,9 @@ // 'title.delete_work' => 'Deleting Work', // 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. +// 'title.add_offer' => 'Adding Offer', +// 'title.edit_offer' => 'Editing Offer', +// 'title.delete_offer' => 'Deleting Offer', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index aeb571010..71197becb 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -352,6 +352,9 @@ 'title.delete_work' => 'Удаление работы', 'title.active_work' => 'Активная работа', 'title.inactive_work' => 'Неактивная работа', +'title.add_offer' => 'Добавление предложения', +'title.edit_offer' => 'Редактирование предложения', +'title.delete_offer' => 'Удаление предложения', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index d853bafc7..2bd2d1c7c 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -395,6 +395,9 @@ // 'title.delete_work' => 'Deleting Work', // 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. +// 'title.add_offer' => 'Adding Offer', +// 'title.edit_offer' => 'Editing Offer', +// 'title.delete_offer' => 'Deleting Offer', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index bb139505e..ba79fb985 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -386,6 +386,9 @@ // 'title.delete_work' => 'Deleting Work', // 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. +// 'title.add_offer' => 'Adding Offer', +// 'title.edit_offer' => 'Editing Offer', +// 'title.delete_offer' => 'Deleting Offer', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index 318eb0ffe..c3ab03bf3 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -389,6 +389,9 @@ // 'title.delete_work' => 'Deleting Work', // 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. +// 'title.add_offer' => 'Adding Offer', +// 'title.edit_offer' => 'Editing Offer', +// 'title.delete_offer' => 'Deleting Offer', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index 8fd08e23a..297ae5235 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -390,6 +390,9 @@ // 'title.delete_work' => 'Deleting Work', // 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. +// 'title.add_offer' => 'Adding Offer', +// 'title.edit_offer' => 'Editing Offer', +// 'title.delete_offer' => 'Deleting Offer', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index 4bbaff7e8..2ba7259a9 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -420,6 +420,9 @@ // 'title.delete_work' => 'Deleting Work', // 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. +// 'title.add_offer' => 'Adding Offer', +// 'title.edit_offer' => 'Editing Offer', +// 'title.delete_offer' => 'Deleting Offer', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index 29206c3b4..a4fb87c76 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -401,6 +401,9 @@ // 'title.delete_work' => 'Deleting Work', // 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. +// 'title.add_offer' => 'Adding Offer', +// 'title.edit_offer' => 'Editing Offer', +// 'title.delete_offer' => 'Deleting Offer', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index 6745e889d..08e2e1efc 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -406,6 +406,9 @@ // 'title.delete_work' => 'Deleting Work', // 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. +// 'title.add_offer' => 'Adding Offer', +// 'title.edit_offer' => 'Editing Offer', +// 'title.delete_offer' => 'Deleting Offer', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index d287e2253..3b7960b8d 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.19.10.5076 | Copyright © Anuko | +  Anuko Time Tracker 1.19.10.5077 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/offer_add.tpl b/WEB-INF/templates/offer_add.tpl new file mode 100644 index 000000000..3051e9664 --- /dev/null +++ b/WEB-INF/templates/offer_add.tpl @@ -0,0 +1,47 @@ +{$forms.offerForm.open} + + + + +
+ + + + + + + + + + + + + +{if $show_files} + + + + +{/if} + + + + + + + + + + + + + + + + + + + +
{$i18n.label.thing_name} (*):{$forms.offerForm.offer_name.control}
{$i18n.label.description}:{$forms.offerForm.description.control}
{$i18n.label.details}:{$forms.offerForm.details.control}
{$i18n.label.file}:{$forms.offerForm.newfile.control}
{$i18n.label.currency}:{$forms.offerForm.currency.control}
{$i18n.label.budget} (*):{$forms.offerForm.budget.control}
{$i18n.label.required_fields}
 
{$forms.offerForm.btn_add.control}
+
+{$forms.offerForm.close} diff --git a/offer_add.php b/offer_add.php new file mode 100644 index 000000000..0eeb04536 --- /dev/null +++ b/offer_add.php @@ -0,0 +1,87 @@ +isPluginEnabled('wk')) { + header('Location: feature_disabled.php'); + exit(); +} +// End of access checks. + +if ($request->isPost()) { + $cl_name = trim($request->getParameter('offer_name')); + $cl_description = trim($request->getParameter('description')); + $cl_details = trim($request->getParameter('details')); + $cl_currency = $request->getParameter('currency'); + $cl_budget = $request->getParameter('budget'); +} + +$form = new Form('offerForm'); +$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'offer_name','style'=>'width: 250px;','value'=>$cl_name)); +$form->addInput(array('type'=>'textarea','name'=>'description','style'=>'width: 250px; height: 40px;','value'=>$cl_description)); +$form->addInput(array('type'=>'textarea','name'=>'details','style'=>'width: 250px; height: 80px;','value'=>$cl_details)); +// Add a dropdown for currency. +$currencies = ttWorkHelper::getCurrencies(); +$form->addInput(array('type'=>'combobox','name'=>'currency','data'=>$currencies,'value'=>$cl_currency)); +$form->addInput(array('type'=>'floatfield','maxlength'=>'10','name'=>'budget','format'=>'.2','value'=>$cl_budget)); +$form->addInput(array('type'=>'submit','name'=>'btn_add','value'=>$i18n->get('button.add'))); + +if ($request->isPost()) { + // Validate user input. + if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.thing_name')); + if (!ttValidString($cl_description, true)) $err->add($i18n->get('error.field'), $i18n->get('label.description')); + if (!ttValidString($cl_details, true)) $err->add($i18n->get('error.field'), $i18n->get('label.details')); + if (!ttValidString($cl_budget)) $err->add($i18n->get('error.field'), $i18n->get('label.budget')); + + if ($err->no()) { + $workHelper = new ttWorkHelper($err); + $fields = array('subject'=>$cl_name, + 'descr_short' => $cl_description, + 'descr_long' => $cl_details, + 'currency' => $currencies[$cl_currency], + 'amount' => $cl_budget); + if ($workHelper->putOffer($fields)) { + header('Location: work.php'); + exit(); + } + } +} // isPost + +$smarty->assign('forms', array($form->getName()=>$form->toArray())); +$smarty->assign('onload', 'onLoad="document.offerForm.work_name.focus()"'); +$smarty->assign('title', $i18n->get('title.add_offer')); +$smarty->assign('content_page_name', 'offer_add.tpl'); +$smarty->display('index.tpl'); diff --git a/work_add.php b/work_add.php index 413546864..211ac13a7 100644 --- a/work_add.php +++ b/work_add.php @@ -41,8 +41,6 @@ } // End of access checks. -$showFiles = $user->isPluginEnabled('at'); - if ($request->isPost()) { $cl_name = trim($request->getParameter('work_name')); $cl_description = trim($request->getParameter('description')); From 76e46e2defece391363e29c5a1e22b116faca8af Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 19 Sep 2019 13:59:17 +0000 Subject: [PATCH 071/877] Added more strings in translation files for Remote Work plugin. --- WEB-INF/lib/ttOfferHelper.class.php | 463 ---------------------------- WEB-INF/resources/ca.lang.php | 2 + WEB-INF/resources/cs.lang.php | 2 + WEB-INF/resources/da.lang.php | 2 + WEB-INF/resources/de.lang.php | 2 + WEB-INF/resources/en.lang.php | 4 +- WEB-INF/resources/es.lang.php | 2 + WEB-INF/resources/et.lang.php | 2 + WEB-INF/resources/fa.lang.php | 2 + WEB-INF/resources/fi.lang.php | 2 + WEB-INF/resources/fr.lang.php | 2 + WEB-INF/resources/gr.lang.php | 2 + WEB-INF/resources/he.lang.php | 2 + WEB-INF/resources/hu.lang.php | 2 + WEB-INF/resources/it.lang.php | 2 + WEB-INF/resources/ja.lang.php | 2 + WEB-INF/resources/ko.lang.php | 2 + WEB-INF/resources/nl.lang.php | 2 + WEB-INF/resources/no.lang.php | 2 + WEB-INF/resources/pl.lang.php | 2 + WEB-INF/resources/pt-br.lang.php | 2 + WEB-INF/resources/pt.lang.php | 2 + WEB-INF/resources/ro.lang.php | 2 + WEB-INF/resources/ru.lang.php | 2 + WEB-INF/resources/sk.lang.php | 2 + WEB-INF/resources/sl.lang.php | 2 + WEB-INF/resources/sr.lang.php | 2 + WEB-INF/resources/sv.lang.php | 2 + WEB-INF/resources/tr.lang.php | 2 + WEB-INF/resources/zh-cn.lang.php | 2 + WEB-INF/resources/zh-tw.lang.php | 2 + WEB-INF/templates/footer.tpl | 2 +- 32 files changed, 62 insertions(+), 465 deletions(-) delete mode 100644 WEB-INF/lib/ttOfferHelper.class.php diff --git a/WEB-INF/lib/ttOfferHelper.class.php b/WEB-INF/lib/ttOfferHelper.class.php deleted file mode 100644 index 97a36e6aa..000000000 --- a/WEB-INF/lib/ttOfferHelper.class.php +++ /dev/null @@ -1,463 +0,0 @@ -errors = &$errors; - - if (defined('REMOTE_WORK_URI')) { - $this->remote_work_uri = REMOTE_WORK_URI; - $this->register_uri = $this->remote_work_uri.'register'; - $this->put_offer_uri = $this->remote_work_uri.'putoffer'; - $this->get_offer_uri = $this->remote_work_uri.'getoffer'; - $this->get_offers_uri = $this->remote_work_uri.'getoffers'; - $this->delete_offer_uri = $this->remote_work_uri.'deleteoffer'; - $this->delete_offers_uri = $this->remote_work_uri.'deleteoffers'; - $this->update_offer_uri = $this->remote_work_uri.'updateoffer'; - $this->checkSiteRegistration(); - } - } - - // checkSiteRegistration - obtains site id and key from local database. - // If not found, it tries to register with remote work server. - function checkSiteRegistration() { - - global $i18n; - $mdb2 = getConnection(); - - // Obtain site id. - $sql = "select param_value as id from tt_site_config where param_name = 'worksite_id'"; - $res = $mdb2->query($sql); - $val = $res->fetchRow(); - if (!$val) { - // No site id found, need to register. - $fields = array('name' => urlencode('time tracker'), - 'origin' => urlencode('time tracker source')); - - // Urlify the data for the POST. - foreach($fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; } - $fields_string = rtrim($fields_string, '&'); - - // Open connection. - $ch = curl_init(); - - // Set the url, number of POST vars, POST data. - curl_setopt($ch, CURLOPT_URL, $this->register_uri); - curl_setopt($ch, CURLOPT_POST, true); - curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - - // Execute a post request. - $result = curl_exec($ch); - - // Close connection. - curl_close($ch); - - $result_array = json_decode($result, true); - if (!$result_array) { - $this->errors->add($i18n->get('error.remote_work')); - } - else if ($result_array['error']) { - // Add an error from remote work server if we have it. - $this->errors->add($result_array['error']); - } - else if ($result_array['id'] && $result_array['key']) { - $this->site_id = $result_array['id']; - $this->site_key = $result_array['key']; - - // Registration successful. Store id and key locally for future use. - $sql = "insert into tt_site_config values('worksite_id', $this->site_id, now(), null)"; - $mdb2->exec($sql); - $sql = "insert into tt_site_config values('worksite_key', ".$mdb2->quote($this->site_key).", now(), null)"; - $mdb2->exec($sql); - } else { - $this->errors->add($i18n->get('error.remote_work')); - } - } else { - // Site id found. - $this->site_id = $val['id']; - - // Obtain site key. - $sql = "select param_value as site_key from tt_site_config where param_name = 'worksite_key'"; - $res = $mdb2->query($sql); - $val = $res->fetchRow(); - $this->site_key = $val['site_key']; - } - } - - // putOffer - publishes an offer in remote work server. - function putOffer($fields) { - global $i18n; - global $user; - $mdb2 = getConnection(); - - $group_id = $user->getGroup(); - $org_id = $user->org_id; - - $curl_fields = array('site_id' => urlencode($this->site_id), - 'site_key' => urlencode($this->site_key), - 'org_id' => urlencode($org_id), - 'org_key' => urlencode($user->getOrgKey()), - 'group_id' => urlencode($group_id), - 'group_key' => urlencode($user->getGroupKey()), - 'offer_lang' => urlencode($fields['offer_lang']), - 'offer_subject' => urlencode($fields['offer_subject']), - 'offer_descr_short' => urlencode($fields['offer_descr_short']), - 'offer_descr_long' => urlencode($fields['offer_descr_long']), - 'offer_currency' => urlencode($fields['offer_currency']), - 'offer_amount' => urlencode($fields['offer_amount']) - ); - - // url-ify the data for the POST. - foreach($curl_fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; } - $fields_string = rtrim($fields_string, '&'); - - // Open connection. - $ch = curl_init(); - - // Set the url, number of POST vars, POST data. - curl_setopt($ch, CURLOPT_URL, $this->put_offer_uri); - curl_setopt($ch, CURLOPT_POST, true); - curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - - // Execute a post request. - $result = curl_exec($ch); - - // Close connection. - curl_close($ch); - - if (!$result) { - $this->errors->add($i18n->get('error.remote_work')); - return false; - } - - $result_array = json_decode($result, true); - $offer_id = (int) $result_array['offer_id']; - $offer_key = $result_array['offer_key']; - $error = $result_array['error']; - - if ($error || !$offer_id || !$offer_key) { - if ($error) { - // Add an error from remote work server if we have it. - $this->errors->add($error); - } - return false; - } - - return true; - } - - - // getOffer - gets offer details from remote work server. - function getOffer($fields) { - global $i18n; - global $user; - $mdb2 = getConnection(); - - $group_id = $user->getGroup(); - $org_id = $user->org_id; - - $curl_fields = array('site_id' => urlencode($this->site_id), - 'site_key' => urlencode($this->site_key), -// Do we need these here? -// 'org_id' => urlencode($org_id), -// 'org_key' => urlencode($user->getOrgKey()), -// 'group_id' => urlencode($group_id), -// 'group_key' => urlencode($user->getGroupKey()), - 'offer_id' => urlencode($fields['remote_id'])); - - // url-ify the data for the POST. - foreach($curl_fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; } - $fields_string = rtrim($fields_string, '&'); - - // Open connection. - $ch = curl_init(); - - // Set the url, number of POST vars, POST data. - curl_setopt($ch, CURLOPT_URL, $this->get_offer_uri); - curl_setopt($ch, CURLOPT_POST, true); - curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - - // Execute a post request. - $result = curl_exec($ch); - - $error = curl_error(); - $result_array2 = json_decode($result, true); - - // Close connection. - curl_close($ch); - - if (!$result) { - $this->errors->add($i18n->get('error.remote_work')); - return false; - } - - $result_array = json_decode($result, true); - $status = (int) $result_array['status']; - $error = $result_array['error']; - - if ($error) { - // Add an error from remote work server if we have it. - $this->errors->add($error); - return false; - } - if ($status != 1) { - // There is no explicit error message, but still something not right. - $this->errors->add($i18n->get('error.remote_work')); - return false; - } - - // TODO: construct and return an array of fields here... - return true; - } - - // TODO: redo the function above. - // Concerns: 1) why $result_array2 - // 2) We need to return an array of fields. - - - - - - - - // The following code is originally from ttFileHelper an needs to be redone. - // - // deleteFile - deletes a file from remote storage and its details from local database. - function deleteFile($fields) { - global $i18n; - global $user; - $mdb2 = getConnection(); - - $group_id = $user->getGroup(); - $org_id = $user->org_id; - - $curl_fields = array('site_id' => urlencode($this->site_id), - 'site_key' => urlencode($this->site_key), - 'org_id' => urlencode($org_id), - 'org_key' => urlencode($user->getOrgKey()), - 'group_id' => urlencode($group_id), - 'group_key' => urlencode($user->getGroupKey()), - 'entity_type' => urlencode($fields['entity_type']), - 'entity_id' => urlencode($fields['entity_id']), - 'file_id' => urlencode($fields['remote_id']), - 'file_key' => urlencode($fields['file_key']), - 'file_name' => urlencode($fields['file_name'])); - - // url-ify the data for the POST. - foreach($curl_fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; } - $fields_string = rtrim($fields_string, '&'); - - // Open connection. - $ch = curl_init(); - - // Set the url, number of POST vars, POST data. - curl_setopt($ch, CURLOPT_URL, $this->deletefile_uri); - curl_setopt($ch, CURLOPT_POST, true); - curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - - // Execute a post request. - $result = curl_exec($ch); - - // Close connection. - curl_close($ch); - - if (!$result) { - $this->errors->add($i18n->get('error.file_storage')); - return false; - } - - $result_array = json_decode($result, true); - $status = (int) $result_array['status']; - $error = $result_array['error']; - - if ($error) { - // Add an error from file storage facility if we have it. - $this->errors->add($error); - } - if ($status != 1) { - // There is no explicit error message, but still something not right. - $this->errors->add($i18n->get('error.file_storage')); - } - - // Delete file reference from database even when remote file storage call fails. - // This is by design to keep things simple. - $file_id = (int) $fields['id']; - $entity_id = (int) $fields['entity_id']; - $sql = "delete from tt_files". - " where id = $file_id and org_id = $org_id and group_id = $group_id and entity_id = $entity_id"; - $affected = $mdb2->exec($sql); - if (is_a($affected, 'PEAR_Error')) { - $this->errors->add($i18n->get('error.db')); - return false; - } - - // File successfully deleted from both file storage and database. - return true; - } - - // deleteEntityFiles - deletes all files associated with an entity. - function deleteEntityFiles($entity_id, $entity_type) { - - if (!$this->entityHasFiles($entity_id, $entity_type)) - return true; // No files to delete. - - global $i18n; - global $user; - $mdb2 = getConnection(); - - $group_id = $user->getGroup(); - $org_id = $user->org_id; - - $curl_fields = array('site_id' => urlencode($this->site_id), - 'site_key' => urlencode($this->site_key), - 'org_id' => urlencode($org_id), - 'org_key' => urlencode($user->getOrgKey()), - 'group_id' => urlencode($group_id), - 'group_key' => urlencode($user->getGroupKey()), - 'entity_type' => urlencode($entity_type), - 'entity_id' => urlencode($entity_id)); - - // url-ify the data for the POST. - foreach($curl_fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; } - $fields_string = rtrim($fields_string, '&'); - - // Open connection. - $ch = curl_init(); - - // Set the url, number of POST vars, POST data. - curl_setopt($ch, CURLOPT_URL, $this->deletefiles_uri); - curl_setopt($ch, CURLOPT_POST, true); - curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - - // Execute a post request. - $result = curl_exec($ch); - - // Close connection. - curl_close($ch); - - if (!$result) { - $this->errors->add($i18n->get('error.file_storage')); - return false; - } - - $result_array = json_decode($result, true); - $status = (int) $result_array['status']; - $error = $result_array['error']; - - if ($error) { - // Add an error from file storage facility if we have it. - $this->errors->add($error); - } - if ($status != 1) { - // There is no explicit error message, but still something not right. - $this->errors->add($i18n->get('error.file_storage')); - } - - // Many things can go wrong with a remote call to file storage facility. - // By design, we ignore such errors, and proceed with removal of entity - // records from the database. - - // Delete all entity records from the database. - $file_id = $fields['id']; - $sql = "delete from tt_files". - " where entity_id = $entity_id". - " and entity_type = ".$mdb2->quote($entity_type). - " and org_id = $org_id and group_id = $group_id"; - $affected = $mdb2->exec($sql); - if (is_a($affected, 'PEAR_Error')) { - $this->errors->add($i18n->get('error.db')); - return false; - } - - return true; - } - - // entityHasFiles determines if an entity has any files referenced in database. - private function entityHasFiles($entity_id, $entity_type) { - global $user; - $mdb2 = getConnection(); - - $group_id = $user->getGroup(); - $org_id = $user->org_id; - - $sql = "select id from tt_files where org_id = $org_id and group_id = $group_id". - " and entity_type = ".$mdb2->quote($entity_type)." and entity_id = $entity_id limit 1"; - $res = $mdb2->query($sql); - $val = $res->fetchRow(); - return $val['id'] > 0; - } - - // getEntityFiles obtains a list of files for an entity. - static function getEntityFiles($id, $type) { - global $user; - $mdb2 = getConnection(); - - $group_id = $user->getGroup(); - $org_id = $user->org_id; - - $result = array(); - $entity_type = $mdb2->quote($type); - $sql = "select id, remote_id, file_key, file_name as name, description from tt_files". - " where entity_type = $entity_type and entity_id = $id". - " and group_id = $group_id and org_id = $org_id and status = 1 order by id"; - $res = $mdb2->query($sql); - if (!is_a($res, 'PEAR_Error')) { - while ($val = $res->fetchRow()) { - $result[] = $val; - } - } - return $result; - } - - - // getFileData - returns file data from memory. - function getFileData() { - return base64_decode($this->file_data); - } -} diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index 1a7c60d95..39b4881a1 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -409,6 +409,8 @@ // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', +// 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. +// 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index 26d23341d..46b5c6559 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -419,6 +419,8 @@ // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', +// 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. +// 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index 7baf95e85..2448eb183 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -391,6 +391,8 @@ // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', +// 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. +// 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index 74095a635..835ffa1a6 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -376,6 +376,8 @@ // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', +// 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. +// 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index 5789f8fc2..6bf197ec1 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -354,10 +354,12 @@ 'title.edit_work' => 'Editing Work', 'title.delete_work' => 'Deleting Work', 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. -'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. +'title.inactive_work' => 'Inactive Work', // Inactive work items for group. 'title.add_offer' => 'Adding Offer', 'title.edit_offer' => 'Editing Offer', 'title.delete_offer' => 'Deleting Offer', +'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. +'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index 55c2875f8..163c1af7d 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -408,6 +408,8 @@ // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', +// 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. +// 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index ce318aaa3..ee7d347be 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -399,6 +399,8 @@ // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', +// 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. +// 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index d3a5aa285..6f9d89c61 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -400,6 +400,8 @@ // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', +// 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. +// 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 695401a2b..1854b5377 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -391,6 +391,8 @@ // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', +// 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. +// 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index fa9cfc391..3a75fbd46 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -385,6 +385,8 @@ // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', +// 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. +// 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index 7e871bcd2..191b3922a 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -384,6 +384,8 @@ // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', +// 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. +// 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index ea67f691b..22707536f 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -408,6 +408,8 @@ // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', +// 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. +// 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index e596323c8..e2dfad562 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -409,6 +409,8 @@ // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', +// 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. +// 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index c3c7c25f5..d43a11ca6 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -394,6 +394,8 @@ // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', +// 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. +// 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index a0ad03dca..f75c758fa 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -415,6 +415,8 @@ // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', +// 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. +// 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index cd245b045..68a41f67f 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -416,6 +416,8 @@ // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', +// 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. +// 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index e1a2b62d4..f4e907f9b 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -365,6 +365,8 @@ // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', +// 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. +// 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index 66ea8f183..36ac91f18 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -412,6 +412,8 @@ // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', +// 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. +// 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index ef55444c8..ad340131b 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -394,6 +394,8 @@ // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', +// 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. +// 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index 02a29d94e..755a225a1 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -389,6 +389,8 @@ // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', +// 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. +// 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index 4c295c61b..c5f6ed04d 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -396,6 +396,8 @@ // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', +// 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. +// 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index 38f2a9f1d..3089e1cef 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -414,6 +414,8 @@ // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', +// 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. +// 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index 71197becb..c94f08238 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -355,6 +355,8 @@ 'title.add_offer' => 'Добавление предложения', 'title.edit_offer' => 'Редактирование предложения', 'title.delete_offer' => 'Удаление предложения', +'title.active_offers' => 'Активные предложения', +'title.inactive_offers' => 'Неактивные предложения', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index 2bd2d1c7c..c997a4c5b 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -398,6 +398,8 @@ // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', +// 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. +// 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index ba79fb985..c7bc00e3d 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -389,6 +389,8 @@ // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', +// 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. +// 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index c3ab03bf3..1ab52e1d4 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -392,6 +392,8 @@ // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', +// 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. +// 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index 297ae5235..bd73925ea 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -393,6 +393,8 @@ // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', +// 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. +// 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index 2ba7259a9..15e175b39 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -423,6 +423,8 @@ // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', +// 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. +// 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index a4fb87c76..b92c48bb2 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -404,6 +404,8 @@ // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', +// 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. +// 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index 08e2e1efc..675f4bfcd 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -409,6 +409,8 @@ // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', +// 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. +// 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 3b7960b8d..b49044624 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.19.10.5077 | Copyright © Anuko | +  Anuko Time Tracker 1.19.10.5078 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From e1062654e68e3c7aa33a41c5ce0c64ef44b865d9 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 19 Sep 2019 15:07:56 +0000 Subject: [PATCH 072/877] Added display of active offers on work.php. --- WEB-INF/lib/ttWorkHelper.class.php | 63 +++++++++++++++++++++++++++++- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/work.tpl | 17 ++++---- work.php | 2 + 4 files changed, 71 insertions(+), 13 deletions(-) diff --git a/WEB-INF/lib/ttWorkHelper.class.php b/WEB-INF/lib/ttWorkHelper.class.php index 465f06cbf..97aa08275 100644 --- a/WEB-INF/lib/ttWorkHelper.class.php +++ b/WEB-INF/lib/ttWorkHelper.class.php @@ -171,7 +171,6 @@ function checkSiteRegistration() { // // A workaround for now is to use use an additional base64 encoding for all text fields, // which are decoded back to utf-8 strings on the server side. - function putWork($fields) { global $i18n; global $user; @@ -297,7 +296,7 @@ function updateWork($fields) { return true; } - // getActiveWork - obtains a list of work items this group is currently oputsourcing. + // getActiveWork - obtains a list of work items this group is currently outsourcing. function getActiveWork() { global $i18n; global $user; @@ -473,6 +472,7 @@ function deleteWork($work_id) { return true; } + // putOffer - publishes an offer in remote work server. function putOffer($fields) { global $i18n; global $user; @@ -534,6 +534,65 @@ function putOffer($fields) { return true; } + // getActiveOffers - obtains a list of offers this group made available to other groups. + function getActiveOffers() { + global $i18n; + global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $curl_fields = array('lang' => urlencode($user->lang), + 'site_id' => urlencode($this->site_id), + 'site_key' => urlencode($this->site_key), + 'org_id' => urlencode($org_id), + 'org_key' => urlencode($user->getOrgKey()), + 'group_id' => urlencode($group_id), + 'group_key' => urlencode($user->getGroupKey()) + ); + + // url-ify the data for the POST. + foreach($curl_fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; } + $fields_string = rtrim($fields_string, '&'); + + // Open connection. + $ch = curl_init(); + + // Set the url, number of POST vars, POST data. + curl_setopt($ch, CURLOPT_URL, $this->get_active_offers_uri); + curl_setopt($ch, CURLOPT_POST, true); + curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + + // Execute a post request. + $result = curl_exec($ch); + + // Close connection. + curl_close($ch); + + if (!$result) { + $this->errors->add($i18n->get('error.remote_work')); + return false; + } + + $result_array = json_decode($result, true); + + // Check for errors. + $call_status = $result_array['call_status']; + if (!$call_status) { + $this->errors->add($i18n->get('error.remote_work')); + return false; + } + if ($call_status['code'] != TT_CURL_SUCCESS) { + $this->errors->add($call_status['error']); + return false; + } + + $active_offers = $result_array['active_offers']; + return $active_offers; + } + // getCurrencies - obtains a list of supported currencies. static function getCurrencies() { $mdb2 = getConnection(); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index b49044624..59fabd896 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- - {if $show_files} - - {/if} @@ -39,20 +36,20 @@
 Anuko Time Tracker 1.19.10.5078 | Copyright © Anuko | +  Anuko Time Tracker 1.19.10.5079 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/work.tpl b/WEB-INF/templates/work.tpl index 64c14ed53..2da8ee7a2 100644 --- a/WEB-INF/templates/work.tpl +++ b/WEB-INF/templates/work.tpl @@ -12,9 +12,6 @@ {$i18n.label.thing_name} {$i18n.label.description} {$i18n.label.budget}
- - {if $available_offers} + + {if $active_offers} - {if $show_files} - - {/if} + - {foreach $available_offers as $offer} + {foreach $active_offers as $offer} - + + + diff --git a/work.php b/work.php index a124ee68e..b8a1795b6 100644 --- a/work.php +++ b/work.php @@ -47,6 +47,7 @@ // $inactive_work = ttWorkHelper::getInactiveWork(); // Inactive work items this group was outsourcing. } if($user->can('bid_on_work')) { + $active_offers = $workHelper->getActiveOffers(); // Active offers this group makes available to other groups. // $available_work = ttWorkHelper::getAvailableWork(); // Currently available work items from other groups. } if($user->can('update_work')) { @@ -61,6 +62,7 @@ $smarty->assign('available_work', $available_work); $smarty->assign('in_progress_work', $in_progress_work); $smarty->assign('completed_work', $completed_work); +$smarty->assign('active_offers', $active_offers); $smarty->assign('available_offers', $available_offers); $smarty->assign('title', $i18n->get('title.work')); $smarty->assign('content_page_name', 'work.tpl'); From cbadf79d662c7e2a9833106ae5334207429d5655 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 19 Sep 2019 15:53:07 +0000 Subject: [PATCH 073/877] Added code to edit offers. --- WEB-INF/lib/ttWorkHelper.class.php | 123 +++++++++++++++++++++++++++++ WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/offer_edit.tpl | 41 ++++++++++ offer_edit.php | 104 ++++++++++++++++++++++++ work_edit.php | 3 - 5 files changed, 269 insertions(+), 4 deletions(-) create mode 100644 WEB-INF/templates/offer_edit.tpl create mode 100644 offer_edit.php diff --git a/WEB-INF/lib/ttWorkHelper.class.php b/WEB-INF/lib/ttWorkHelper.class.php index 97aa08275..fbbdbbf19 100644 --- a/WEB-INF/lib/ttWorkHelper.class.php +++ b/WEB-INF/lib/ttWorkHelper.class.php @@ -593,6 +593,129 @@ function getActiveOffers() { return $active_offers; } + // getOffer - gets offer details from remote work server. + function getOffer($offer_id) { + global $i18n; + global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $curl_fields = array('lang' => urlencode($user->lang), + 'site_id' => urlencode($this->site_id), + 'site_key' => urlencode($this->site_key), + 'org_id' => urlencode($org_id), + 'org_key' => urlencode($user->getOrgKey()), + 'group_id' => urlencode($group_id), + 'group_key' => urlencode($user->getGroupKey()), + 'offer_id' => urlencode($offer_id)); + + // url-ify the data for the POST. + foreach($curl_fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; } + $fields_string = rtrim($fields_string, '&'); + + // Open connection. + $ch = curl_init(); + + // Set the url, number of POST vars, POST data. + curl_setopt($ch, CURLOPT_URL, $this->get_offer_uri); + curl_setopt($ch, CURLOPT_POST, true); + curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + + // Execute a post request. + $result = curl_exec($ch); + + // Close connection. + curl_close($ch); + + if (!$result) { + $this->errors->add($i18n->get('error.remote_work')); + return false; + } + + $result_array = json_decode($result, true); + + // Check for errors. + $call_status = $result_array['call_status']; + if (!$call_status) { + $this->errors->add($i18n->get('error.remote_work')); + return false; + } + if ($call_status['code'] != TT_CURL_SUCCESS) { + $this->errors->add($call_status['error']); + return false; + } + + $offer = $result_array['offer']; + return $offer; + } + + // updateOffer - updates an offer in remote work server. + function updateOffer($fields) { + global $i18n; + global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $curl_fields = array('lang' => urlencode($user->lang), + 'site_id' => urlencode($this->site_id), + 'site_key' => urlencode($this->site_key), + 'org_id' => urlencode($org_id), + 'org_key' => urlencode($user->getOrgKey()), + 'group_id' => urlencode($group_id), + 'group_key' => urlencode($user->getGroupKey()), + 'work_id' => urlencode($fields['work_id']), + 'subject' => urlencode(base64_encode($fields['subject'])), + 'descr_short' => urlencode(base64_encode($fields['descr_short'])), + 'descr_long' => urlencode(base64_encode($fields['descr_long'])), + 'currency' => urlencode($fields['currency']), + 'amount' => urlencode($fields['amount']) + ); + + // url-ify the data for the POST. + foreach($curl_fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; } + $fields_string = rtrim($fields_string, '&'); + + // Open connection. + $ch = curl_init(); + + // Set the url, number of POST vars, POST data. + curl_setopt($ch, CURLOPT_URL, $this->update_offer_uri); + curl_setopt($ch, CURLOPT_POST, true); + curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + + // Execute a post request. + $result = curl_exec($ch); + + // Close connection. + curl_close($ch); + + if (!$result) { + $this->errors->add($i18n->get('error.remote_work')); + return false; + } + + $result_array = json_decode($result, true); + + // Check for errors. + $call_status = $result_array['call_status']; + if (!$call_status) { + $this->errors->add($i18n->get('error.remote_work')); + return false; + } + if ($call_status['code'] != TT_CURL_SUCCESS) { + $this->errors->add($call_status['error']); + return false; + } + + return true; + } + // getCurrencies - obtains a list of supported currencies. static function getCurrencies() { $mdb2 = getConnection(); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 59fabd896..899fecc56 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
{$i18n.form.work.offers}
{$i18n.title.active_offers}
{$i18n.label.thing_name} {$i18n.label.description}{$i18n.label.budget}
{$offer.name|escape}{$offer.subject|escape}{$offer.description|escape}{$offer.currency} {$offer.amount} {$i18n.label.edit} {$i18n.label.delete}
-
 Anuko Time Tracker 1.19.10.5079 | Copyright © Anuko | +  Anuko Time Tracker 1.19.10.5080 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/offer_edit.tpl b/WEB-INF/templates/offer_edit.tpl new file mode 100644 index 000000000..a80c82d79 --- /dev/null +++ b/WEB-INF/templates/offer_edit.tpl @@ -0,0 +1,41 @@ +{$forms.offerForm.open} + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
{$i18n.label.thing_name} (*):{$forms.offerForm.offer_name.control}
{$i18n.label.description}:{$forms.offerForm.description.control}
{$i18n.label.details}:{$forms.offerForm.details.control}
{$i18n.label.currency}:{$forms.offerForm.currency.control}
{$i18n.label.budget} (*):{$forms.offerForm.budget.control}
{$i18n.label.required_fields}
 
{$forms.offerForm.btn_save.control}
+
+{$forms.offerForm.close} diff --git a/offer_edit.php b/offer_edit.php new file mode 100644 index 000000000..5fc0010ed --- /dev/null +++ b/offer_edit.php @@ -0,0 +1,104 @@ +isPluginEnabled('wk')) { + header('Location: feature_disabled.php'); + exit(); +} +$cl_offer_id = (int)$request->getParameter('id'); +$workHelper = new ttWorkHelper($err); +$offer = $workHelper->getOffer($cl_offer_id); +if (!$offer) { + header('Location: access_denied.php'); + exit(); +} +// End of access checks. + +$currencies = ttWorkHelper::getCurrencies(); + +if ($request->isPost()) { + $cl_name = trim($request->getParameter('offer_name')); + $cl_description = trim($request->getParameter('description')); + $cl_details = trim($request->getParameter('details')); + $cl_currency = $request->getParameter('currency'); + $cl_budget = $request->getParameter('budget'); +} else { + $cl_name = $offer['subject']; + $cl_description = $offer['descr_short']; + $cl_details = $offer['descr_long']; + $currency = $offer['currency']; + $cl_currency = array_search($currency, $currencies); + $cl_budget = $offer['amount']; +} + +$form = new Form('offerForm'); +$form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_offer_id)); +$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'offer_name','style'=>'width: 250px;','value'=>$cl_name)); +$form->addInput(array('type'=>'textarea','name'=>'description','style'=>'width: 250px; height: 40px;','value'=>$cl_description)); +$form->addInput(array('type'=>'textarea','name'=>'details','style'=>'width: 250px; height: 80px;','value'=>$cl_details)); +$form->addInput(array('type'=>'combobox','name'=>'currency','data'=>$currencies,'value'=>$cl_currency)); +$form->addInput(array('type'=>'floatfield','maxlength'=>'10','name'=>'budget','format'=>'.2','value'=>$cl_budget)); +$form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); + +if ($request->isPost()) { + // Validate user input. + if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.thing_name')); + if (!ttValidString($cl_description, true)) $err->add($i18n->get('error.field'), $i18n->get('label.description')); + if (!ttValidString($cl_details, true)) $err->add($i18n->get('error.field'), $i18n->get('label.details')); + if (!ttValidString($cl_budget)) $err->add($i18n->get('error.field'), $i18n->get('label.budget')); + + if ($err->no()) { + if ($request->getParameter('btn_save')) { + // Update offer information. + $fields = array('work_id'=>$cl_offer_id, + 'subject'=>$cl_name, + 'descr_short' => $cl_description, + 'descr_long' => $cl_details, + 'currency' => $currencies[$cl_currency], + 'amount' => $cl_budget); + if ($workHelper->updateOffer($fields)) { + header('Location: work.php'); + exit(); + } + } + } +} // isPost + +$smarty->assign('forms', array($form->getName()=>$form->toArray())); +$smarty->assign('title', $i18n->get('title.edit_offer')); +$smarty->assign('content_page_name', 'offer_edit.tpl'); +$smarty->display('index.tpl'); diff --git a/work_edit.php b/work_edit.php index 094e2058b..ac7a8b190 100644 --- a/work_edit.php +++ b/work_edit.php @@ -74,9 +74,6 @@ $form->addInput(array('type'=>'floatfield','maxlength'=>'10','name'=>'budget','format'=>'.2','value'=>$cl_budget)); $form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); -// TODO: coding ongoing down from here... - - if ($request->isPost()) { // Validate user input. if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.thing_name')); From 29f9ab1698af584dfdead22b956f48984b8ef8bc Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 19 Sep 2019 16:10:09 +0000 Subject: [PATCH 074/877] Added code to delete offers for Remote Work plugin. --- WEB-INF/lib/ttWorkHelper.class.php | 58 +++++++++++++++++++++++ WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/offer_delete.tpl | 20 ++++++++ offer_delete.php | 75 ++++++++++++++++++++++++++++++ work_delete.php | 2 - 5 files changed, 154 insertions(+), 3 deletions(-) create mode 100644 WEB-INF/templates/offer_delete.tpl create mode 100644 offer_delete.php diff --git a/WEB-INF/lib/ttWorkHelper.class.php b/WEB-INF/lib/ttWorkHelper.class.php index fbbdbbf19..1fa72036b 100644 --- a/WEB-INF/lib/ttWorkHelper.class.php +++ b/WEB-INF/lib/ttWorkHelper.class.php @@ -716,6 +716,64 @@ function updateOffer($fields) { return true; } + // deleteOffer - deletes an offer from remote work server. + function deleteOffer($offer_id) { + global $i18n; + global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $curl_fields = array('lang' => urlencode($user->lang), + 'site_id' => urlencode($this->site_id), + 'site_key' => urlencode($this->site_key), + 'org_id' => urlencode($org_id), + 'org_key' => urlencode($user->getOrgKey()), + 'group_id' => urlencode($group_id), + 'group_key' => urlencode($user->getGroupKey()), + 'offer_id' => urlencode($offer_id)); + + // url-ify the data for the POST. + foreach($curl_fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; } + $fields_string = rtrim($fields_string, '&'); + + // Open connection. + $ch = curl_init(); + + // Set the url, number of POST vars, POST data. + curl_setopt($ch, CURLOPT_URL, $this->delete_offer_uri); + curl_setopt($ch, CURLOPT_POST, true); + curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + + // Execute a post request. + $result = curl_exec($ch); + + // Close connection. + curl_close($ch); + + if (!$result) { + $this->errors->add($i18n->get('error.remote_work')); + return false; + } + + $result_array = json_decode($result, true); + + // Check for errors. + $call_status = $result_array['call_status']; + if (!$call_status) { + $this->errors->add($i18n->get('error.remote_work')); + return false; + } + if ($call_status['code'] != TT_CURL_SUCCESS) { + $this->errors->add($call_status['error']); + return false; + } + + return true; + } + // getCurrencies - obtains a list of supported currencies. static function getCurrencies() { $mdb2 = getConnection(); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 899fecc56..7034b34f7 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.19.10.5080 | Copyright © Anuko | +  Anuko Time Tracker 1.19.10.5081 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/offer_delete.tpl b/WEB-INF/templates/offer_delete.tpl new file mode 100644 index 000000000..7d8954cfb --- /dev/null +++ b/WEB-INF/templates/offer_delete.tpl @@ -0,0 +1,20 @@ +{$forms.offerDeleteForm.open} + + + + +
+ + + + + + + + + + + +
{$offer_to_delete|escape}
 
{$forms.offerDeleteForm.btn_delete.control}  {$forms.offerDeleteForm.btn_cancel.control}
+
+{$forms.offerDeleteForm.close} diff --git a/offer_delete.php b/offer_delete.php new file mode 100644 index 000000000..f08c82a04 --- /dev/null +++ b/offer_delete.php @@ -0,0 +1,75 @@ +isPluginEnabled('wk')) { + header('Location: feature_disabled.php'); + exit(); +} +$cl_offer_id = (int)$request->getParameter('id'); +$workHelper = new ttWorkHelper($err); +$offer = $workHelper->getOffer($cl_offer_id); +if (!$offer) { + header('Location: access_denied.php'); + exit(); +} +// End of access checks. + +$offer_to_delete = $offer['subject']; + +$form = new Form('offerDeleteForm'); +$form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_offer_id)); +$form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->get('label.delete'))); +$form->addInput(array('type'=>'submit','name'=>'btn_cancel','value'=>$i18n->get('button.cancel'))); + +if ($request->isPost()) { + if ($request->getParameter('btn_delete')) { + if ($workHelper->deleteOffer($cl_offer_id)) { + header('Location: work.php'); + exit(); + } + } elseif ($request->getParameter('btn_cancel')) { + header('Location: work.php'); + exit(); + } +} // isPost + +$smarty->assign('offer_to_delete', $offer_to_delete); +$smarty->assign('forms', array($form->getName()=>$form->toArray())); +$smarty->assign('onload', 'onLoad="document.offerDeleteForm.btn_cancel.focus()"'); +$smarty->assign('title', $i18n->get('title.delete_offer')); +$smarty->assign('content_page_name', 'offer_delete.tpl'); +$smarty->display('index.tpl'); diff --git a/work_delete.php b/work_delete.php index c0cd443d2..e4a5e24d9 100644 --- a/work_delete.php +++ b/work_delete.php @@ -48,8 +48,6 @@ } // End of access checks. -// TODO: coding ongoing down from here... - $work_to_delete = $work_item['subject']; $form = new Form('workDeleteForm'); From 17613c3e4d39279ffb447420377a3a55776724a8 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 19 Sep 2019 17:39:27 +0000 Subject: [PATCH 075/877] Added available work items from other orgs on the work.php page. --- WEB-INF/lib/ttWorkHelper.class.php | 58 +++++++++++++++++++++++++++++- WEB-INF/resources/ca.lang.php | 1 + WEB-INF/resources/cs.lang.php | 1 + WEB-INF/resources/da.lang.php | 1 + WEB-INF/resources/de.lang.php | 1 + WEB-INF/resources/en.lang.php | 2 ++ WEB-INF/resources/es.lang.php | 1 + WEB-INF/resources/et.lang.php | 1 + WEB-INF/resources/fa.lang.php | 1 + WEB-INF/resources/fi.lang.php | 1 + WEB-INF/resources/fr.lang.php | 1 + WEB-INF/resources/gr.lang.php | 1 + WEB-INF/resources/he.lang.php | 1 + WEB-INF/resources/hu.lang.php | 1 + WEB-INF/resources/it.lang.php | 1 + WEB-INF/resources/ja.lang.php | 1 + WEB-INF/resources/ko.lang.php | 1 + WEB-INF/resources/nl.lang.php | 2 ++ WEB-INF/resources/no.lang.php | 1 + WEB-INF/resources/pl.lang.php | 1 + WEB-INF/resources/pt-br.lang.php | 1 + WEB-INF/resources/pt.lang.php | 1 + WEB-INF/resources/ro.lang.php | 1 + WEB-INF/resources/ru.lang.php | 1 + WEB-INF/resources/sk.lang.php | 1 + WEB-INF/resources/sl.lang.php | 1 + WEB-INF/resources/sr.lang.php | 1 + WEB-INF/resources/sv.lang.php | 1 + WEB-INF/resources/tr.lang.php | 1 + WEB-INF/resources/zh-cn.lang.php | 1 + WEB-INF/resources/zh-tw.lang.php | 1 + WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/work.tpl | 30 ++++++++++++++++ work.php | 2 +- 34 files changed, 121 insertions(+), 3 deletions(-) diff --git a/WEB-INF/lib/ttWorkHelper.class.php b/WEB-INF/lib/ttWorkHelper.class.php index 1fa72036b..e7ed5ff42 100644 --- a/WEB-INF/lib/ttWorkHelper.class.php +++ b/WEB-INF/lib/ttWorkHelper.class.php @@ -65,7 +65,7 @@ function __construct(&$errors) { $this->put_work_uri = $this->remote_work_uri.'putwork'; $this->get_work_uri = $this->remote_work_uri.'getwork'; $this->get_active_work_uri = $this->remote_work_uri.'getactivework'; - $this->get_avaialable_work_uri = $this->remote_work_uri.'getavailablework'; + $this->get_available_work_uri = $this->remote_work_uri.'getavailablework'; $this->delete_work_uri = $this->remote_work_uri.'deletework'; $this->update_work_uri = $this->remote_work_uri.'updatework'; $this->put_offer_uri = $this->remote_work_uri.'putoffer'; @@ -355,6 +355,62 @@ function getActiveWork() { return $active_work; } + // getAvailableWork - obtains a list of available work items this group can bid on. + function getAvailableWork() { + global $i18n; + global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $curl_fields = array('lang' => urlencode($user->lang), + 'site_id' => urlencode($this->site_id), + 'site_key' => urlencode($this->site_key), + 'org_id' => urlencode($org_id) + ); + + // url-ify the data for the POST. + foreach($curl_fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; } + $fields_string = rtrim($fields_string, '&'); + + // Open connection. + $ch = curl_init(); + + // Set the url, number of POST vars, POST data. + curl_setopt($ch, CURLOPT_URL, $this->get_available_work_uri); + curl_setopt($ch, CURLOPT_POST, true); + curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + + // Execute a post request. + $result = curl_exec($ch); + + // Close connection. + curl_close($ch); + + if (!$result) { + $this->errors->add($i18n->get('error.remote_work')); + return false; + } + + $result_array = json_decode($result, true); + + // Check for errors. + $call_status = $result_array['call_status']; + if (!$call_status) { + $this->errors->add($i18n->get('error.remote_work')); + return false; + } + if ($call_status['code'] != TT_CURL_SUCCESS) { + $this->errors->add($call_status['error']); + return false; + } + + $available_work = $result_array['available_work']; + return $available_work; + } + // getWork - gets work item details from remote work server. function getWork($work_id) { global $i18n; diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index 39b4881a1..9aae6d221 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -405,6 +405,7 @@ // 'title.edit_work' => 'Editing Work', // 'title.delete_work' => 'Deleting Work', // 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. +// 'title.available_work' => 'Available Work', // Available work items from other organizations. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index 46b5c6559..73d8db9cf 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -415,6 +415,7 @@ // 'title.edit_work' => 'Editing Work', // 'title.delete_work' => 'Deleting Work', // 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. +// 'title.available_work' => 'Available Work', // Available work items from other organizations. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index 2448eb183..84dfab641 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -387,6 +387,7 @@ // 'title.edit_work' => 'Editing Work', // 'title.delete_work' => 'Deleting Work', // 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. +// 'title.available_work' => 'Available Work', // Available work items from other organizations. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index 835ffa1a6..eb797cd87 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -372,6 +372,7 @@ // 'title.edit_work' => 'Editing Work', // 'title.delete_work' => 'Deleting Work', // 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. +// 'title.available_work' => 'Available Work', // Available work items from other organizations. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index 6bf197ec1..115d0957c 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -354,11 +354,13 @@ 'title.edit_work' => 'Editing Work', 'title.delete_work' => 'Deleting Work', 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. +'title.available_work' => 'Available Work', // Available work items from other organizations. 'title.inactive_work' => 'Inactive Work', // Inactive work items for group. 'title.add_offer' => 'Adding Offer', 'title.edit_offer' => 'Editing Offer', 'title.delete_offer' => 'Deleting Offer', 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. +'title.active_offers' => 'Available Offers', // Available offers from other organizations. 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index 163c1af7d..f0a8f6557 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -404,6 +404,7 @@ // 'title.edit_work' => 'Editing Work', // 'title.delete_work' => 'Deleting Work', // 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. +// 'title.available_work' => 'Available Work', // Available work items from other organizations. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index ee7d347be..c8edc899b 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -395,6 +395,7 @@ // 'title.edit_work' => 'Editing Work', // 'title.delete_work' => 'Deleting Work', // 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. +// 'title.available_work' => 'Available Work', // Available work items from other organizations. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index 6f9d89c61..3726a3b11 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -396,6 +396,7 @@ // 'title.edit_work' => 'Editing Work', // 'title.delete_work' => 'Deleting Work', // 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. +// 'title.available_work' => 'Available Work', // Available work items from other organizations. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 1854b5377..714b7ffdd 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -387,6 +387,7 @@ // 'title.edit_work' => 'Editing Work', // 'title.delete_work' => 'Deleting Work', // 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. +// 'title.available_work' => 'Available Work', // Available work items from other organizations. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index 3a75fbd46..3db3dcfb3 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -381,6 +381,7 @@ // 'title.edit_work' => 'Editing Work', // 'title.delete_work' => 'Deleting Work', // 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. +// 'title.available_work' => 'Available Work', // Available work items from other organizations. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index 191b3922a..21abe0efe 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -380,6 +380,7 @@ // 'title.edit_work' => 'Editing Work', // 'title.delete_work' => 'Deleting Work', // 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. +// 'title.available_work' => 'Available Work', // Available work items from other organizations. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index 22707536f..2d32c6805 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -404,6 +404,7 @@ // 'title.edit_work' => 'Editing Work', // 'title.delete_work' => 'Deleting Work', // 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. +// 'title.available_work' => 'Available Work', // Available work items from other organizations. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index e2dfad562..96040480a 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -405,6 +405,7 @@ // 'title.edit_work' => 'Editing Work', // 'title.delete_work' => 'Deleting Work', // 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. +// 'title.available_work' => 'Available Work', // Available work items from other organizations. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index d43a11ca6..b0092312c 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -390,6 +390,7 @@ // 'title.edit_work' => 'Editing Work', // 'title.delete_work' => 'Deleting Work', // 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. +// 'title.available_work' => 'Available Work', // Available work items from other organizations. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index f75c758fa..476a115c5 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -411,6 +411,7 @@ // 'title.edit_work' => 'Editing Work', // 'title.delete_work' => 'Deleting Work', // 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. +// 'title.available_work' => 'Available Work', // Available work items from other organizations. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index 68a41f67f..776264b1a 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -412,6 +412,7 @@ // 'title.edit_work' => 'Editing Work', // 'title.delete_work' => 'Deleting Work', // 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. +// 'title.available_work' => 'Available Work', // Available work items from other organizations. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index f4e907f9b..28e12d49e 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -360,6 +360,8 @@ 'title.edit_work' => 'Werk bewerken', 'title.delete_work' => 'Werk verwijderen', 'title.active_work' => 'Actief werk', +// TODO: translate the following. +// 'title.available_work' => 'Available Work', // Available work items from other organizations. 'title.inactive_work' => 'Inactief werk', // TODO: translate the following. // 'title.add_offer' => 'Adding Offer', diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index 36ac91f18..6e4fd0493 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -408,6 +408,7 @@ // 'title.edit_work' => 'Editing Work', // 'title.delete_work' => 'Deleting Work', // 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. +// 'title.available_work' => 'Available Work', // Available work items from other organizations. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index ad340131b..e71fd5f5a 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -390,6 +390,7 @@ // 'title.edit_work' => 'Editing Work', // 'title.delete_work' => 'Deleting Work', // 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. +// 'title.available_work' => 'Available Work', // Available work items from other organizations. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index 755a225a1..3003233d1 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -385,6 +385,7 @@ // 'title.edit_work' => 'Editing Work', // 'title.delete_work' => 'Deleting Work', // 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. +// 'title.available_work' => 'Available Work', // Available work items from other organizations. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index c5f6ed04d..9b98f023c 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -392,6 +392,7 @@ // 'title.edit_work' => 'Editing Work', // 'title.delete_work' => 'Deleting Work', // 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. +// 'title.available_work' => 'Available Work', // Available work items from other organizations. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index 3089e1cef..df09632dd 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -410,6 +410,7 @@ // 'title.edit_work' => 'Editing Work', // 'title.delete_work' => 'Deleting Work', // 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. +// 'title.available_work' => 'Available Work', // Available work items from other organizations. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index c94f08238..12f42420e 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -351,6 +351,7 @@ 'title.edit_work' => 'Редактирование работы', 'title.delete_work' => 'Удаление работы', 'title.active_work' => 'Активная работа', +'title.available_work' => 'Имеющаяся работа', 'title.inactive_work' => 'Неактивная работа', 'title.add_offer' => 'Добавление предложения', 'title.edit_offer' => 'Редактирование предложения', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index c997a4c5b..f652d086a 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -394,6 +394,7 @@ // 'title.edit_work' => 'Editing Work', // 'title.delete_work' => 'Deleting Work', // 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. +// 'title.available_work' => 'Available Work', // Available work items from other organizations. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index c7bc00e3d..19c675168 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -385,6 +385,7 @@ // 'title.edit_work' => 'Editing Work', // 'title.delete_work' => 'Deleting Work', // 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. +// 'title.available_work' => 'Available Work', // Available work items from other organizations. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index 1ab52e1d4..7244d08fd 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -388,6 +388,7 @@ // 'title.edit_work' => 'Editing Work', // 'title.delete_work' => 'Deleting Work', // 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. +// 'title.available_work' => 'Available Work', // Available work items from other organizations. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index bd73925ea..0b23571f6 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -389,6 +389,7 @@ // 'title.edit_work' => 'Editing Work', // 'title.delete_work' => 'Deleting Work', // 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. +// 'title.available_work' => 'Available Work', // Available work items from other organizations. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index 15e175b39..cf0ba1094 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -419,6 +419,7 @@ // 'title.edit_work' => 'Editing Work', // 'title.delete_work' => 'Deleting Work', // 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. +// 'title.available_work' => 'Available Work', // Available work items from other organizations. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index b92c48bb2..dd2440aa3 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -400,6 +400,7 @@ // 'title.edit_work' => 'Editing Work', // 'title.delete_work' => 'Deleting Work', // 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. +// 'title.available_work' => 'Available Work', // Available work items from other organizations. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index 675f4bfcd..a7c5a4fdf 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -405,6 +405,7 @@ // 'title.edit_work' => 'Editing Work', // 'title.delete_work' => 'Deleting Work', // 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. +// 'title.available_work' => 'Available Work', // Available work items from other organizations. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 7034b34f7..549dd7469 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.19.10.5081 | Copyright © Anuko | +  Anuko Time Tracker 1.19.10.5082 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/work.tpl b/WEB-INF/templates/work.tpl index 2da8ee7a2..82af33a13 100644 --- a/WEB-INF/templates/work.tpl +++ b/WEB-INF/templates/work.tpl @@ -35,6 +35,36 @@
+ + + {if $available_work} + + + + + + + + {foreach $available_work as $work_item} + + + + + + + + {/foreach} + {/if} +
{$i18n.title.available_work}
{$i18n.label.thing_name}{$i18n.label.description}{$i18n.label.budget}
{$work_item.subject|escape}{$work_item.description|escape}{$work_item.currency} {$work_item.amount}
+ + + + + +

+
+
+ {if $active_offers} diff --git a/work.php b/work.php index b8a1795b6..bbbd88241 100644 --- a/work.php +++ b/work.php @@ -47,8 +47,8 @@ // $inactive_work = ttWorkHelper::getInactiveWork(); // Inactive work items this group was outsourcing. } if($user->can('bid_on_work')) { + $available_work = $workHelper->getAvailableWork(); // Currently available work items from other orgs. $active_offers = $workHelper->getActiveOffers(); // Active offers this group makes available to other groups. - // $available_work = ttWorkHelper::getAvailableWork(); // Currently available work items from other groups. } if($user->can('update_work')) { // $in_progress_work = ttWorkHelper::getInProgressWork(); // Work items in progress for other groups. From 81fc7b902dffeaca8227894756532d4070a911f5 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 19 Sep 2019 17:54:53 +0000 Subject: [PATCH 076/877] Added title.available_offers to translation files. --- WEB-INF/resources/ca.lang.php | 1 + WEB-INF/resources/cs.lang.php | 1 + WEB-INF/resources/da.lang.php | 1 + WEB-INF/resources/de.lang.php | 1 + WEB-INF/resources/en.lang.php | 2 +- WEB-INF/resources/es.lang.php | 1 + WEB-INF/resources/et.lang.php | 1 + WEB-INF/resources/fa.lang.php | 1 + WEB-INF/resources/fi.lang.php | 1 + WEB-INF/resources/fr.lang.php | 1 + WEB-INF/resources/gr.lang.php | 1 + WEB-INF/resources/he.lang.php | 1 + WEB-INF/resources/hu.lang.php | 1 + WEB-INF/resources/it.lang.php | 1 + WEB-INF/resources/ja.lang.php | 1 + WEB-INF/resources/ko.lang.php | 1 + WEB-INF/resources/nl.lang.php | 1 + WEB-INF/resources/no.lang.php | 1 + WEB-INF/resources/pl.lang.php | 1 + WEB-INF/resources/pt-br.lang.php | 1 + WEB-INF/resources/pt.lang.php | 1 + WEB-INF/resources/ro.lang.php | 1 + WEB-INF/resources/ru.lang.php | 1 + WEB-INF/resources/sk.lang.php | 1 + WEB-INF/resources/sl.lang.php | 1 + WEB-INF/resources/sr.lang.php | 1 + WEB-INF/resources/sv.lang.php | 1 + WEB-INF/resources/tr.lang.php | 1 + WEB-INF/resources/zh-cn.lang.php | 1 + WEB-INF/resources/zh-tw.lang.php | 1 + WEB-INF/templates/footer.tpl | 2 +- 31 files changed, 31 insertions(+), 2 deletions(-) diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index 9aae6d221..141437e2a 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -411,6 +411,7 @@ // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', // 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. +// 'title.available_offers' => 'Available Offers', // Available offers from other organizations. // 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index 73d8db9cf..8bc4cbb42 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -421,6 +421,7 @@ // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', // 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. +// 'title.available_offers' => 'Available Offers', // Available offers from other organizations. // 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index 84dfab641..4993fc631 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -393,6 +393,7 @@ // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', // 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. +// 'title.available_offers' => 'Available Offers', // Available offers from other organizations. // 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index eb797cd87..99de29942 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -378,6 +378,7 @@ // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', // 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. +// 'title.available_offers' => 'Available Offers', // Available offers from other organizations. // 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index 115d0957c..e94859f6a 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -360,7 +360,7 @@ 'title.edit_offer' => 'Editing Offer', 'title.delete_offer' => 'Deleting Offer', 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. -'title.active_offers' => 'Available Offers', // Available offers from other organizations. +'title.available_offers' => 'Available Offers', // Available offers from other organizations. 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index f0a8f6557..b1657b392 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -410,6 +410,7 @@ // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', // 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. +// 'title.available_offers' => 'Available Offers', // Available offers from other organizations. // 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index c8edc899b..0edb5fef8 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -401,6 +401,7 @@ // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', // 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. +// 'title.available_offers' => 'Available Offers', // Available offers from other organizations. // 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index 3726a3b11..a135ed6ec 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -402,6 +402,7 @@ // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', // 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. +// 'title.available_offers' => 'Available Offers', // Available offers from other organizations. // 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 714b7ffdd..333f9bdce 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -393,6 +393,7 @@ // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', // 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. +// 'title.available_offers' => 'Available Offers', // Available offers from other organizations. // 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index 3db3dcfb3..0cbb48ea5 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -387,6 +387,7 @@ // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', // 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. +// 'title.available_offers' => 'Available Offers', // Available offers from other organizations. // 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index 21abe0efe..7e89f6f56 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -386,6 +386,7 @@ // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', // 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. +// 'title.available_offers' => 'Available Offers', // Available offers from other organizations. // 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index 2d32c6805..76d8c4a08 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -410,6 +410,7 @@ // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', // 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. +// 'title.available_offers' => 'Available Offers', // Available offers from other organizations. // 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index 96040480a..e2657f493 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -411,6 +411,7 @@ // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', // 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. +// 'title.available_offers' => 'Available Offers', // Available offers from other organizations. // 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index b0092312c..cb78d281e 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -396,6 +396,7 @@ // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', // 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. +// 'title.available_offers' => 'Available Offers', // Available offers from other organizations. // 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index 476a115c5..417289d0d 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -417,6 +417,7 @@ // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', // 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. +// 'title.available_offers' => 'Available Offers', // Available offers from other organizations. // 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index 776264b1a..ae02d30f3 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -418,6 +418,7 @@ // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', // 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. +// 'title.available_offers' => 'Available Offers', // Available offers from other organizations. // 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 28e12d49e..b002e38ae 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -368,6 +368,7 @@ // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', // 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. +// 'title.available_offers' => 'Available Offers', // Available offers from other organizations. // 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index 6e4fd0493..77b8d7506 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -414,6 +414,7 @@ // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', // 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. +// 'title.available_offers' => 'Available Offers', // Available offers from other organizations. // 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index e71fd5f5a..9bcf32ff5 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -396,6 +396,7 @@ // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', // 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. +// 'title.available_offers' => 'Available Offers', // Available offers from other organizations. // 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index 3003233d1..55ad505f7 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -391,6 +391,7 @@ // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', // 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. +// 'title.available_offers' => 'Available Offers', // Available offers from other organizations. // 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index 9b98f023c..eb5b1c00e 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -398,6 +398,7 @@ // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', // 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. +// 'title.available_offers' => 'Available Offers', // Available offers from other organizations. // 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index df09632dd..cbbf77231 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -416,6 +416,7 @@ // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', // 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. +// 'title.available_offers' => 'Available Offers', // Available offers from other organizations. // 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index 12f42420e..560f75174 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -357,6 +357,7 @@ 'title.edit_offer' => 'Редактирование предложения', 'title.delete_offer' => 'Удаление предложения', 'title.active_offers' => 'Активные предложения', +'title.available_offers' => 'Имеющиеся предложения', 'title.inactive_offers' => 'Неактивные предложения', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index f652d086a..f767d1b0c 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -400,6 +400,7 @@ // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', // 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. +// 'title.available_offers' => 'Available Offers', // Available offers from other organizations. // 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index 19c675168..3cf66b8cb 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -391,6 +391,7 @@ // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', // 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. +// 'title.available_offers' => 'Available Offers', // Available offers from other organizations. // 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index 7244d08fd..4f38b914a 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -394,6 +394,7 @@ // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', // 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. +// 'title.available_offers' => 'Available Offers', // Available offers from other organizations. // 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index 0b23571f6..6ee292f2a 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -395,6 +395,7 @@ // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', // 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. +// 'title.available_offers' => 'Available Offers', // Available offers from other organizations. // 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index cf0ba1094..1c36dbb66 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -425,6 +425,7 @@ // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', // 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. +// 'title.available_offers' => 'Available Offers', // Available offers from other organizations. // 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index dd2440aa3..0570609ed 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -406,6 +406,7 @@ // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', // 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. +// 'title.available_offers' => 'Available Offers', // Available offers from other organizations. // 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index a7c5a4fdf..55bbcc21d 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -411,6 +411,7 @@ // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', // 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. +// 'title.available_offers' => 'Available Offers', // Available offers from other organizations. // 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 549dd7469..eb2f7864c 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
{$i18n.title.active_offers}
-
 Anuko Time Tracker 1.19.10.5082 | Copyright © Anuko | +  Anuko Time Tracker 1.19.10.5083 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From f2d99439128e7b7d021b873044bb9cb469bee0b9 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 19 Sep 2019 18:37:23 +0000 Subject: [PATCH 077/877] Addedd code to list available offers on work.php. --- WEB-INF/lib/ttWorkHelper.class.php | 58 +++++++++++++++++++++++++++++- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/work.tpl | 30 ++++++++++++++++ work.php | 5 +-- 4 files changed, 89 insertions(+), 6 deletions(-) diff --git a/WEB-INF/lib/ttWorkHelper.class.php b/WEB-INF/lib/ttWorkHelper.class.php index e7ed5ff42..c83c9c90f 100644 --- a/WEB-INF/lib/ttWorkHelper.class.php +++ b/WEB-INF/lib/ttWorkHelper.class.php @@ -71,7 +71,7 @@ function __construct(&$errors) { $this->put_offer_uri = $this->remote_work_uri.'putoffer'; $this->get_offer_uri = $this->remote_work_uri.'getoffer'; $this->get_active_offers_uri = $this->remote_work_uri.'getactiveoffers'; - $this->get_avaialable_offers_uri = $this->remote_work_uri.'getavailableoffers'; + $this->get_available_offers_uri = $this->remote_work_uri.'getavailableoffers'; $this->delete_offer_uri = $this->remote_work_uri.'deleteoffer'; $this->update_offer_uri = $this->remote_work_uri.'updateoffer'; $this->checkSiteRegistration(); @@ -649,6 +649,62 @@ function getActiveOffers() { return $active_offers; } + // getAvailableOffers - obtains a list of available offers from other organizations. + function getAvailableOffers() { + global $i18n; + global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $curl_fields = array('lang' => urlencode($user->lang), + 'site_id' => urlencode($this->site_id), + 'site_key' => urlencode($this->site_key), + 'org_id' => urlencode($org_id) + ); + + // url-ify the data for the POST. + foreach($curl_fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; } + $fields_string = rtrim($fields_string, '&'); + + // Open connection. + $ch = curl_init(); + + // Set the url, number of POST vars, POST data. + curl_setopt($ch, CURLOPT_URL, $this->get_available_offers_uri); + curl_setopt($ch, CURLOPT_POST, true); + curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + + // Execute a post request. + $result = curl_exec($ch); + + // Close connection. + curl_close($ch); + + if (!$result) { + $this->errors->add($i18n->get('error.remote_work')); + return false; + } + + $result_array = json_decode($result, true); + + // Check for errors. + $call_status = $result_array['call_status']; + if (!$call_status) { + $this->errors->add($i18n->get('error.remote_work')); + return false; + } + if ($call_status['code'] != TT_CURL_SUCCESS) { + $this->errors->add($call_status['error']); + return false; + } + + $available_offers = $result_array['available_offers']; + return $available_offers; + } + // getOffer - gets offer details from remote work server. function getOffer($offer_id) { global $i18n; diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index eb2f7864c..b7fe89987 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.19.10.5083 | Copyright © Anuko | +  Anuko Time Tracker 1.19.10.5084 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/work.tpl b/WEB-INF/templates/work.tpl index 82af33a13..a0ff3d14b 100644 --- a/WEB-INF/templates/work.tpl +++ b/WEB-INF/templates/work.tpl @@ -95,6 +95,36 @@
+ + + {if $available_offers} + + + + + + + + {foreach $available_offers as $offer} + + + + + + + + {/foreach} + {/if} +
{$i18n.title.available_offers}
{$i18n.label.thing_name}{$i18n.label.description}{$i18n.label.budget}
{$offer.subject|escape}{$offer.description|escape}{$offer.currency} {$offer.amount}
+ + + + + +

+
+
+
diff --git a/work.php b/work.php index bbbd88241..fab8ccb0d 100644 --- a/work.php +++ b/work.php @@ -44,7 +44,7 @@ if($user->can('manage_work')) { $active_work = $workHelper->getActiveWork(); // Active work items this group is outsourcing. - // $inactive_work = ttWorkHelper::getInactiveWork(); // Inactive work items this group was outsourcing. + $available_offers = $workHelper->getAvailableOffers(); // Available offers from other organizations. } if($user->can('bid_on_work')) { $available_work = $workHelper->getAvailableWork(); // Currently available work items from other orgs. @@ -58,10 +58,7 @@ // TODO: review access rights for the code above. $smarty->assign('active_work', $active_work); -$smarty->assign('inactive_work', $inactive_work); $smarty->assign('available_work', $available_work); -$smarty->assign('in_progress_work', $in_progress_work); -$smarty->assign('completed_work', $completed_work); $smarty->assign('active_offers', $active_offers); $smarty->assign('available_offers', $available_offers); $smarty->assign('title', $i18n->get('title.work')); From 98a19a89339916b32396a1b62137b887968e74b6 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 20 Sep 2019 11:56:07 +0000 Subject: [PATCH 078/877] Added getGroupName function to ttUser class. --- WEB-INF/lib/ttUser.class.php | 5 +++++ WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index 83751360a..47b69139b 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -192,6 +192,11 @@ function getGroup() { return ($this->behalfGroup ? $this->behalfGroup->id : $this->group_id); } + // getGroupName returns group name on behalf of which the current user is operating. + function getGroupName() { + return ($this->behalfGroup ? $this->behalfGroup->name : $this->group_name); + } + // getGroupKey returns group key for active group. function getGroupKey() { return ($this->behalfGroup ? $this->behalfGroup->group_key : $this->group_key); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index b7fe89987..59ab19d1b 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.19.10.5084 | Copyright © Anuko | +  Anuko Time Tracker 1.19.10.5085 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 3fbdd85e65be8894188d61162fc2e79beae03aa8 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 20 Sep 2019 12:37:09 +0000 Subject: [PATCH 079/877] Added getEmail function to ttUser class. --- WEB-INF/lib/ttBehalfUser.class.php | 7 ++++--- WEB-INF/lib/ttUser.class.php | 5 +++++ WEB-INF/templates/footer.tpl | 2 +- offer_add.php | 3 +++ offer_edit.php | 3 +++ work_add.php | 3 +++ work_edit.php | 3 +++ 7 files changed, 22 insertions(+), 4 deletions(-) diff --git a/WEB-INF/lib/ttBehalfUser.class.php b/WEB-INF/lib/ttBehalfUser.class.php index 7f7a5ffa9..408602a10 100644 --- a/WEB-INF/lib/ttBehalfUser.class.php +++ b/WEB-INF/lib/ttBehalfUser.class.php @@ -33,18 +33,18 @@ // An instance in kept in ttUser class when user is working on behalf of someone. class ttBehalfUser { // Work in progress, build on when need arises. - // Currently, we need it for quota_percent work (and perhaps in profile_edit.php). var $name = null; // User name. var $id = null; // User id. var $quota_percent = 100.0; // Time quota percent for quotas plugin. + var $email = null; // User email. // Constructor. - // Note: org_id isneeded because we may construct an object in + // Note: org_id is needed because we may construct an object in // ttUser constructor, when global $user object does not yet exist. function __construct($id, $org_id) { $mdb2 = getConnection(); - $sql = "select u.name, u.id, u.quota_percent". + $sql = "select u.name, u.id, u.quota_percent, u.email". " from tt_users u". " where u.id = $id and u.org_id = $org_id and u.status = 1"; @@ -56,6 +56,7 @@ function __construct($id, $org_id) { $this->name = $val['name']; $this->id = $val['id']; if ($val['quota_percent']) $this->quota_percent = $val['quota_percent']; + $this->email = $val['email']; } } } diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index 47b69139b..59616f12b 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -187,6 +187,11 @@ function getQuotaPercent() { return ($this->behalfUser ? $this->behalfUser->quota_percent : $this->quota_percent); } + // getEmail returns email for active user. + function getEmail() { + return ($this->behalfUser ? $this->behalfUser->email : $this->email); + } + // The getGroup returns group id on behalf of which the current user is operating. function getGroup() { return ($this->behalfGroup ? $this->behalfGroup->id : $this->group_id); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 59ab19d1b..a04fa3cd5 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.19.10.5085 | Copyright © Anuko | +  Anuko Time Tracker 1.19.10.5086 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/offer_add.php b/offer_add.php index 0eeb04536..e3efeaa45 100644 --- a/offer_add.php +++ b/offer_add.php @@ -66,6 +66,9 @@ if (!ttValidString($cl_details, true)) $err->add($i18n->get('error.field'), $i18n->get('label.details')); if (!ttValidString($cl_budget)) $err->add($i18n->get('error.field'), $i18n->get('label.budget')); + // Ensure user email exists (required for workflow). + if (!$user->getEmail()) $err->add($i18n->get('error.no_email')); + if ($err->no()) { $workHelper = new ttWorkHelper($err); $fields = array('subject'=>$cl_name, diff --git a/offer_edit.php b/offer_edit.php index 5fc0010ed..23c3c37c6 100644 --- a/offer_edit.php +++ b/offer_edit.php @@ -81,6 +81,9 @@ if (!ttValidString($cl_details, true)) $err->add($i18n->get('error.field'), $i18n->get('label.details')); if (!ttValidString($cl_budget)) $err->add($i18n->get('error.field'), $i18n->get('label.budget')); + // Ensure user email exists (required for workflow). + if (!$user->getEmail()) $err->add($i18n->get('error.no_email')); + if ($err->no()) { if ($request->getParameter('btn_save')) { // Update offer information. diff --git a/work_add.php b/work_add.php index 211ac13a7..c07ed98b1 100644 --- a/work_add.php +++ b/work_add.php @@ -74,6 +74,9 @@ if (!ttValidString($cl_details, true)) $err->add($i18n->get('error.field'), $i18n->get('label.details')); if (!ttValidString($cl_budget)) $err->add($i18n->get('error.field'), $i18n->get('label.budget')); + // Ensure user email exists. + if (!$user->getEmail()) $err->add($i18n->get('error.no_email')); + if ($err->no()) { $workHelper = new ttWorkHelper($err); $fields = array('subject'=>$cl_name, diff --git a/work_edit.php b/work_edit.php index ac7a8b190..43d793e7f 100644 --- a/work_edit.php +++ b/work_edit.php @@ -81,6 +81,9 @@ if (!ttValidString($cl_details, true)) $err->add($i18n->get('error.field'), $i18n->get('label.details')); if (!ttValidString($cl_budget)) $err->add($i18n->get('error.field'), $i18n->get('label.budget')); + // Ensure user email exists (required for workflow). + if (!$user->getEmail()) $err->add($i18n->get('error.no_email')); + if ($err->no()) { if ($request->getParameter('btn_save')) { // Update work information. From 454942cd518f707fe3cb1ef3782826d1e125080e Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 20 Sep 2019 14:20:16 +0000 Subject: [PATCH 080/877] Added audit info to some API calls for Remote Work plugin. --- WEB-INF/lib/ttWorkHelper.class.php | 20 +++++++++++++++++--- WEB-INF/templates/footer.tpl | 2 +- work_add.php | 2 +- 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/WEB-INF/lib/ttWorkHelper.class.php b/WEB-INF/lib/ttWorkHelper.class.php index c83c9c90f..8a25185a1 100644 --- a/WEB-INF/lib/ttWorkHelper.class.php +++ b/WEB-INF/lib/ttWorkHelper.class.php @@ -184,12 +184,17 @@ function putWork($fields) { 'org_id' => urlencode($org_id), 'org_key' => urlencode($user->getOrgKey()), 'group_id' => urlencode($group_id), + 'group_name' => urlencode(base64_encode($user->getGroupName())), 'group_key' => urlencode($user->getGroupKey()), 'subject' => urlencode(base64_encode($fields['subject'])), 'descr_short' => urlencode(base64_encode($fields['descr_short'])), 'descr_long' => urlencode(base64_encode($fields['descr_long'])), 'currency' => urlencode($fields['currency']), - 'amount' => urlencode($fields['amount']) + 'amount' => urlencode($fields['amount']), + 'created_ip' => urlencode($_SERVER['REMOTE_ADDR']), + 'created_by' => urlencode($user->getUser()), + 'created_by_name' => urlencode(base64_encode($user->getName())), + 'created_by_email' => urlencode(base64_encode($user->getEmail())) ); // url-ify the data for the POST. @@ -247,13 +252,18 @@ function updateWork($fields) { 'org_id' => urlencode($org_id), 'org_key' => urlencode($user->getOrgKey()), 'group_id' => urlencode($group_id), + 'group_name' => urlencode(base64_encode($user->getGroupName())), 'group_key' => urlencode($user->getGroupKey()), 'work_id' => urlencode($fields['work_id']), 'subject' => urlencode(base64_encode($fields['subject'])), 'descr_short' => urlencode(base64_encode($fields['descr_short'])), 'descr_long' => urlencode(base64_encode($fields['descr_long'])), 'currency' => urlencode($fields['currency']), - 'amount' => urlencode($fields['amount']) + 'amount' => urlencode($fields['amount']), + 'modified_ip' => urlencode($_SERVER['REMOTE_ADDR']), + 'modified_by' => urlencode($user->getUser()), + 'modified_by_name' => urlencode(base64_encode($user->getName())), + 'modified_by_email' => urlencode(base64_encode($user->getEmail())) ); // url-ify the data for the POST. @@ -486,7 +496,11 @@ function deleteWork($work_id) { 'org_key' => urlencode($user->getOrgKey()), 'group_id' => urlencode($group_id), 'group_key' => urlencode($user->getGroupKey()), - 'work_id' => urlencode($work_id)); + 'work_id' => urlencode($work_id), + 'modified_ip' => urlencode($_SERVER['REMOTE_ADDR']), + 'modified_by' => urlencode($user->getUser()), + 'modified_by_name' => urlencode(base64_encode($user->getName())), + 'modified_by_email' => urlencode(base64_encode($user->getEmail()))); // url-ify the data for the POST. foreach($curl_fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index a04fa3cd5..119c2761c 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.19.10.5086 | Copyright © Anuko | +  Anuko Time Tracker 1.19.10.5087 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/work_add.php b/work_add.php index c07ed98b1..c085ce7cc 100644 --- a/work_add.php +++ b/work_add.php @@ -74,7 +74,7 @@ if (!ttValidString($cl_details, true)) $err->add($i18n->get('error.field'), $i18n->get('label.details')); if (!ttValidString($cl_budget)) $err->add($i18n->get('error.field'), $i18n->get('label.budget')); - // Ensure user email exists. + // Ensure user email exists (required for workflow). if (!$user->getEmail()) $err->add($i18n->get('error.no_email')); if ($err->no()) { From dd759a74fff16aaea198af1ce4adb450178ccd70 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 20 Sep 2019 14:49:30 +0000 Subject: [PATCH 081/877] Added audit info to API calls to Remote Work server. --- WEB-INF/lib/ttWorkHelper.class.php | 22 ++++++++++++++++++---- WEB-INF/templates/footer.tpl | 2 +- offer_edit.php | 2 +- 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/WEB-INF/lib/ttWorkHelper.class.php b/WEB-INF/lib/ttWorkHelper.class.php index 8a25185a1..5f68387c3 100644 --- a/WEB-INF/lib/ttWorkHelper.class.php +++ b/WEB-INF/lib/ttWorkHelper.class.php @@ -556,12 +556,17 @@ function putOffer($fields) { 'org_id' => urlencode($org_id), 'org_key' => urlencode($user->getOrgKey()), 'group_id' => urlencode($group_id), + 'group_name' => urlencode(base64_encode($user->getGroupName())), 'group_key' => urlencode($user->getGroupKey()), 'subject' => urlencode(base64_encode($fields['subject'])), 'descr_short' => urlencode(base64_encode($fields['descr_short'])), 'descr_long' => urlencode(base64_encode($fields['descr_long'])), 'currency' => urlencode($fields['currency']), - 'amount' => urlencode($fields['amount']) + 'amount' => urlencode($fields['amount']), + 'created_ip' => urlencode($_SERVER['REMOTE_ADDR']), + 'created_by' => urlencode($user->getUser()), + 'created_by_name' => urlencode(base64_encode($user->getName())), + 'created_by_email' => urlencode(base64_encode($user->getEmail())) ); // url-ify the data for the POST. @@ -793,13 +798,18 @@ function updateOffer($fields) { 'org_id' => urlencode($org_id), 'org_key' => urlencode($user->getOrgKey()), 'group_id' => urlencode($group_id), + 'group_name' => urlencode(base64_encode($user->getGroupName())), 'group_key' => urlencode($user->getGroupKey()), - 'work_id' => urlencode($fields['work_id']), + 'offer_id' => urlencode($fields['offer_id']), 'subject' => urlencode(base64_encode($fields['subject'])), 'descr_short' => urlencode(base64_encode($fields['descr_short'])), 'descr_long' => urlencode(base64_encode($fields['descr_long'])), 'currency' => urlencode($fields['currency']), - 'amount' => urlencode($fields['amount']) + 'amount' => urlencode($fields['amount']), + 'modified_ip' => urlencode($_SERVER['REMOTE_ADDR']), + 'modified_by' => urlencode($user->getUser()), + 'modified_by_name' => urlencode(base64_encode($user->getName())), + 'modified_by_email' => urlencode(base64_encode($user->getEmail())) ); // url-ify the data for the POST. @@ -858,7 +868,11 @@ function deleteOffer($offer_id) { 'org_key' => urlencode($user->getOrgKey()), 'group_id' => urlencode($group_id), 'group_key' => urlencode($user->getGroupKey()), - 'offer_id' => urlencode($offer_id)); + 'offer_id' => urlencode($offer_id), + 'modified_ip' => urlencode($_SERVER['REMOTE_ADDR']), + 'modified_by' => urlencode($user->getUser()), + 'modified_by_name' => urlencode(base64_encode($user->getName())), + 'modified_by_email' => urlencode(base64_encode($user->getEmail()))); // url-ify the data for the POST. foreach($curl_fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 119c2761c..b6538fa53 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.19.10.5087 | Copyright © Anuko | +  Anuko Time Tracker 1.19.10.5088 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/offer_edit.php b/offer_edit.php index 23c3c37c6..d6b1ea94d 100644 --- a/offer_edit.php +++ b/offer_edit.php @@ -87,7 +87,7 @@ if ($err->no()) { if ($request->getParameter('btn_save')) { // Update offer information. - $fields = array('work_id'=>$cl_offer_id, + $fields = array('offer_id'=>$cl_offer_id, 'subject'=>$cl_name, 'descr_short' => $cl_description, 'descr_long' => $cl_details, From d00165d9a02be7c22e6a0e77cc94e72902debc7c Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 20 Sep 2019 15:10:41 +0000 Subject: [PATCH 082/877] Made Remote Work plugin available to start user testing and feedback. --- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/plugins.tpl | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index b6538fa53..824cd8be9 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- -{if isTrue('WORK_DEBUG')} -{/if} From e335ce3b60006535b51ec53054f67d56d0b4ecc1 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 20 Sep 2019 15:42:33 +0000 Subject: [PATCH 083/877] Fixed ttWorkHelper constructor for not defined REMOTE_WORK_URI situation. --- WEB-INF/lib/ttWorkHelper.class.php | 33 +++++++++++++++--------------- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 17 insertions(+), 18 deletions(-) diff --git a/WEB-INF/lib/ttWorkHelper.class.php b/WEB-INF/lib/ttWorkHelper.class.php index 5f68387c3..cbf81136e 100644 --- a/WEB-INF/lib/ttWorkHelper.class.php +++ b/WEB-INF/lib/ttWorkHelper.class.php @@ -54,28 +54,27 @@ class ttWorkHelper { function __construct(&$errors) { $this->errors = &$errors; + $this->remote_work_uri = defined('REMOTE_WORK_URI') ? REMOTE_WORK_URI : "https://www.anuko.com/work/"; + // Note: at some point a need will arise for API versioning. // When this happens, we will append an API version number to the end of URI, // for example: register_0_1 instead of register. // This should theoretically allow a remote work server to be able to work with // a complete variety of deployed clients, including those without versions. - if (defined('REMOTE_WORK_URI')) { - $this->remote_work_uri = REMOTE_WORK_URI; - $this->register_uri = $this->remote_work_uri.'register'; // register_0_0 - $this->put_work_uri = $this->remote_work_uri.'putwork'; - $this->get_work_uri = $this->remote_work_uri.'getwork'; - $this->get_active_work_uri = $this->remote_work_uri.'getactivework'; - $this->get_available_work_uri = $this->remote_work_uri.'getavailablework'; - $this->delete_work_uri = $this->remote_work_uri.'deletework'; - $this->update_work_uri = $this->remote_work_uri.'updatework'; - $this->put_offer_uri = $this->remote_work_uri.'putoffer'; - $this->get_offer_uri = $this->remote_work_uri.'getoffer'; - $this->get_active_offers_uri = $this->remote_work_uri.'getactiveoffers'; - $this->get_available_offers_uri = $this->remote_work_uri.'getavailableoffers'; - $this->delete_offer_uri = $this->remote_work_uri.'deleteoffer'; - $this->update_offer_uri = $this->remote_work_uri.'updateoffer'; - $this->checkSiteRegistration(); - } + $this->register_uri = $this->remote_work_uri.'register'; // register_0_0 + $this->put_work_uri = $this->remote_work_uri.'putwork'; + $this->get_work_uri = $this->remote_work_uri.'getwork'; + $this->get_active_work_uri = $this->remote_work_uri.'getactivework'; + $this->get_available_work_uri = $this->remote_work_uri.'getavailablework'; + $this->delete_work_uri = $this->remote_work_uri.'deletework'; + $this->update_work_uri = $this->remote_work_uri.'updatework'; + $this->put_offer_uri = $this->remote_work_uri.'putoffer'; + $this->get_offer_uri = $this->remote_work_uri.'getoffer'; + $this->get_active_offers_uri = $this->remote_work_uri.'getactiveoffers'; + $this->get_available_offers_uri = $this->remote_work_uri.'getavailableoffers'; + $this->delete_offer_uri = $this->remote_work_uri.'deleteoffer'; + $this->update_offer_uri = $this->remote_work_uri.'updateoffer'; + $this->checkSiteRegistration(); } // checkSiteRegistration - obtains site id and key from local database. diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 824cd8be9..34def14b9 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.19.10.5088 | Copyright © Anuko | +  Anuko Time Tracker 1.19.10.5089 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/plugins.tpl b/WEB-INF/templates/plugins.tpl index 56868a6b7..97f7cdb95 100644 --- a/WEB-INF/templates/plugins.tpl +++ b/WEB-INF/templates/plugins.tpl @@ -162,12 +162,10 @@ function handlePluginCheckboxes() { {$forms.pluginsForm.attachments.control} {$i18n.label.what_is_it}
{$forms.pluginsForm.work.control} {$i18n.label.what_is_it}
 
-
 Anuko Time Tracker 1.19.10.5089 | Copyright © Anuko | +  Anuko Time Tracker 1.19.10.5090 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 70c4546fffbcb320c6da8928574f064ecec0e861 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 20 Sep 2019 16:49:47 +0000 Subject: [PATCH 084/877] Removed FILE_STORAGE_URI from config.php.dist and set its default value. --- WEB-INF/config.php.dist | 5 ----- WEB-INF/lib/ttAdmin.class.php | 7 +++---- WEB-INF/lib/ttFileHelper.class.php | 16 +++++++--------- WEB-INF/lib/ttGroupHelper.class.php | 7 +++---- WEB-INF/lib/ttOrgHelper.class.php | 7 +++---- WEB-INF/templates/footer.tpl | 2 +- 6 files changed, 17 insertions(+), 27 deletions(-) diff --git a/WEB-INF/config.php.dist b/WEB-INF/config.php.dist index 87cd5bf11..6ffdff08e 100644 --- a/WEB-INF/config.php.dist +++ b/WEB-INF/config.php.dist @@ -178,11 +178,6 @@ define('AUTH_MODULE', 'db'); // Height in pixels for the note input field in time.php. Defaults to 40. // define('NOTE_INPUT_HEIGHT', 100); -// File storage facility location for attachments. -// This feature requires a subscription or a locally installed appliance. -// define('FILE_STORAGE_URI', 'localhost'); -define('FILE_STORAGE_URI', 'https://www.anuko.com/files/'); - // A comma-separated list of default plugins for new group registrations. // Example below enables charts and attachments. // define('DEFAULT_PLUGINS', 'ch,at'); diff --git a/WEB-INF/lib/ttAdmin.class.php b/WEB-INF/lib/ttAdmin.class.php index 16ff3b599..74d789d12 100644 --- a/WEB-INF/lib/ttAdmin.class.php +++ b/WEB-INF/lib/ttAdmin.class.php @@ -348,10 +348,9 @@ static function deleteGroupFiles($group_id) { if ($affected == 0) return true; // Do not call file storage utility. - // Try to make a call to file storage facility. - if (!defined('FILE_STORAGE_URI')) return true; // Nothing to do. - - $deletegroupfiles_uri = FILE_STORAGE_URI.'deletegroupfiles'; + // Try to make a call to file storage server. + $storage_uri = defined('FILE_STORAGE_URI') ? FILE_STORAGE_URI : "https://www.anuko.com/files/"; + $deletegroupfiles_uri = $storage_uri.'deletegroupfiles'; // Obtain site id. $sql = "select param_value as site_id from tt_site_config where param_name = 'locker_id'"; diff --git a/WEB-INF/lib/ttFileHelper.class.php b/WEB-INF/lib/ttFileHelper.class.php index a38162706..48105e417 100644 --- a/WEB-INF/lib/ttFileHelper.class.php +++ b/WEB-INF/lib/ttFileHelper.class.php @@ -43,15 +43,13 @@ class ttFileHelper { function __construct(&$errors) { $this->errors = &$errors; - if (defined('FILE_STORAGE_URI')) { - $this->storage_uri = FILE_STORAGE_URI; - $this->register_uri = $this->storage_uri.'register'; - $this->putfile_uri = $this->storage_uri.'putfile'; - $this->deletefile_uri = $this->storage_uri.'deletefile'; - $this->deletefiles_uri = $this->storage_uri.'deletefiles'; - $this->getfile_uri = $this->storage_uri.'getfile'; - $this->checkSiteRegistration(); - } + $this->storage_uri = defined('FILE_STORAGE_URI') ? FILE_STORAGE_URI : "https://www.anuko.com/files/"; + $this->register_uri = $this->storage_uri.'register'; + $this->putfile_uri = $this->storage_uri.'putfile'; + $this->deletefile_uri = $this->storage_uri.'deletefile'; + $this->deletefiles_uri = $this->storage_uri.'deletefiles'; + $this->getfile_uri = $this->storage_uri.'getfile'; + $this->checkSiteRegistration(); } // checkSiteRegistration - obtains site id and key from local database. diff --git a/WEB-INF/lib/ttGroupHelper.class.php b/WEB-INF/lib/ttGroupHelper.class.php index 182d2e1f5..48e4de724 100644 --- a/WEB-INF/lib/ttGroupHelper.class.php +++ b/WEB-INF/lib/ttGroupHelper.class.php @@ -717,10 +717,9 @@ static function deleteGroupFiles($group_id) { if ($affected == 0) return true; // Do not call file storage utility. - // Try to make a call to file storage facility. - if (!defined('FILE_STORAGE_URI')) return true; // Nothing to do. - - $deletegroupfiles_uri = FILE_STORAGE_URI.'deletegroupfiles'; + // Try to make a call to file storage server. + $storage_uri = defined('FILE_STORAGE_URI') ? FILE_STORAGE_URI : "https://www.anuko.com/files/"; + $deletegroupfiles_uri = $storage_uri.'deletegroupfiles'; // Obtain site id. $sql = "select param_value as site_id from tt_site_config where param_name = 'locker_id'"; diff --git a/WEB-INF/lib/ttOrgHelper.class.php b/WEB-INF/lib/ttOrgHelper.class.php index 1893379d3..60126420a 100644 --- a/WEB-INF/lib/ttOrgHelper.class.php +++ b/WEB-INF/lib/ttOrgHelper.class.php @@ -137,10 +137,9 @@ static function deleteOrgFiles($org_id) { if ($affected == 0) return true; // Do not call file storage utility. - // Try to make a call to file storage facility. - if (!defined('FILE_STORAGE_URI')) return true; // Nothing to do. - - $deleteorgfiles_uri = FILE_STORAGE_URI.'deleteorgfiles'; + // Try to make a call to file storage server. + $storage_uri = defined('FILE_STORAGE_URI') ? FILE_STORAGE_URI : "https://www.anuko.com/files/"; + $deleteorgfiles_uri = $storage_uri.'deleteorgfiles'; // Obtain site id. $sql = "select param_value as site_id from tt_site_config where param_name = 'locker_id'"; diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 34def14b9..df31d30d6 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.19.10.5090 | Copyright © Anuko | +  Anuko Time Tracker 1.19.10.5091 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 5fbdf6925be78230d81b19bdd9d7b596b871607f Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 20 Sep 2019 18:18:46 +0000 Subject: [PATCH 085/877] Added a clarifying comment for translators for error.file_storage and error.remote_work. --- WEB-INF/resources/ca.lang.php | 4 ++-- WEB-INF/resources/cs.lang.php | 4 ++-- WEB-INF/resources/da.lang.php | 4 ++-- WEB-INF/resources/de.lang.php | 4 ++-- WEB-INF/resources/en.lang.php | 10 +++++++++- WEB-INF/resources/es.lang.php | 4 ++-- WEB-INF/resources/et.lang.php | 4 ++-- WEB-INF/resources/fa.lang.php | 4 ++-- WEB-INF/resources/fi.lang.php | 4 ++-- WEB-INF/resources/fr.lang.php | 4 ++-- WEB-INF/resources/gr.lang.php | 4 ++-- WEB-INF/resources/he.lang.php | 4 ++-- WEB-INF/resources/hu.lang.php | 4 ++-- WEB-INF/resources/it.lang.php | 4 ++-- WEB-INF/resources/ja.lang.php | 4 ++-- WEB-INF/resources/ko.lang.php | 4 ++-- WEB-INF/resources/nl.lang.php | 27 ++++++++++++++++----------- WEB-INF/resources/no.lang.php | 4 ++-- WEB-INF/resources/pl.lang.php | 4 ++-- WEB-INF/resources/pt-br.lang.php | 4 ++-- WEB-INF/resources/pt.lang.php | 4 ++-- WEB-INF/resources/ro.lang.php | 4 ++-- WEB-INF/resources/ru.lang.php | 2 +- WEB-INF/resources/sk.lang.php | 4 ++-- WEB-INF/resources/sl.lang.php | 4 ++-- WEB-INF/resources/sr.lang.php | 4 ++-- WEB-INF/resources/sv.lang.php | 4 ++-- WEB-INF/resources/tr.lang.php | 4 ++-- WEB-INF/resources/zh-cn.lang.php | 4 ++-- WEB-INF/resources/zh-tw.lang.php | 4 ++-- WEB-INF/templates/footer.tpl | 2 +- 31 files changed, 81 insertions(+), 68 deletions(-) diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index 141437e2a..c50eb2fff 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -119,8 +119,8 @@ // 'error.format' => 'Invalid file format.', // 'error.user_count' => 'Limit on user count.', // 'error.expired' => 'Expiration date reached.', -// 'error.file_storage' => 'File storage error.', -// 'error.remote_work' => 'Remote work server error.', +// 'error.file_storage' => 'File storage server error.', // See comment in English file. +// 'error.remote_work' => 'Remote work server error.', // See comment in English file. // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index 8bc4cbb42..7eb333d46 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -121,8 +121,8 @@ // 'error.format' => 'Invalid file format.', // 'error.user_count' => 'Limit on user count.', // 'error.expired' => 'Expiration date reached.', -// 'error.file_storage' => 'File storage error.', -// 'error.remote_work' => 'Remote work server error.', +// 'error.file_storage' => 'File storage server error.', // See comment in English file. +// 'error.remote_work' => 'Remote work server error.', // See comment in English file. // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index 4993fc631..450bb31ec 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -116,8 +116,8 @@ // 'error.format' => 'Invalid file format.', // 'error.user_count' => 'Limit on user count.', // 'error.expired' => 'Expiration date reached.', -// 'error.file_storage' => 'File storage error.', -// 'error.remote_work' => 'Remote work server error.', +// 'error.file_storage' => 'File storage server error.', // See comment in English file. +// 'error.remote_work' => 'Remote work server error.', // See comment in English file. // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index 99de29942..4fffe05c0 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -111,8 +111,8 @@ // 'error.format' => 'Invalid file format.', // 'error.user_count' => 'Limit on user count.', // 'error.expired' => 'Expiration date reached.', -// 'error.file_storage' => 'File storage error.', -// 'error.remote_work' => 'Remote work server error.', +// 'error.file_storage' => 'File storage server error.', // See comment in English file. +// 'error.remote_work' => 'Remote work server error.', // See comment in English file. // Warning messages. 'warn.sure' => 'Sind Sie sicher?', diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index e94859f6a..248176e97 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -104,7 +104,15 @@ 'error.format' => 'Invalid file format.', 'error.user_count' => 'Limit on user count.', 'error.expired' => 'Expiration date reached.', -'error.file_storage' => 'File storage error.', +// Meaning of error.file_storage: an (unspecified) error occurred when trying to communicate with remote +// file storage server (the one that handles attachments). It is a generic message telling us that +// "something went wrong" when trying to do some operation with attachments. +// For example, File Storage server could be offline, or Time Tracker config option is wrong, etc. +'error.file_storage' => 'File storage server error.', +// Meaning of error.remote_work: an (unspecified) error occurred when trying to communicate with +// "Remote Work" server, the one that supports the "Work" plugin, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm +// It is a generic message telling us that "something went wrong" when trying to do some operation with Work plugin. +// For example, Remote Work server could be offline, among other things. 'error.remote_work' => 'Remote work server error.', // Warning messages. diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index b1657b392..be8996221 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -117,8 +117,8 @@ // 'error.format' => 'Invalid file format.', // 'error.user_count' => 'Limit on user count.', // 'error.expired' => 'Expiration date reached.', -// 'error.file_storage' => 'File storage error.', -// 'error.remote_work' => 'Remote work server error.', +// 'error.file_storage' => 'File storage server error.', // See comment in English file. +// 'error.remote_work' => 'Remote work server error.', // See comment in English file. // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index 0edb5fef8..369224cdb 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -128,8 +128,8 @@ 'error.user_count' => 'Kasutajate arvu piirang.', 'error.expired' => 'Kehtivusaeg on lõppenud.', // TODO: translate the following. -// 'error.file_storage' => 'File storage error.', -// 'error.remote_work' => 'Remote work server error.', +// 'error.file_storage' => 'File storage server error.', // See comment in English file. +// 'error.remote_work' => 'Remote work server error.', // See comment in English file. // Warning messages. 'warn.sure' => 'Oled kindel?', diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index a135ed6ec..30b6adbe2 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -124,8 +124,8 @@ // 'error.user_count' => 'Limit on user count.', // 'error.expired' => 'Expiration date reached.', // TODO: translate the following. -// 'error.file_storage' => 'File storage error.', -// 'error.remote_work' => 'Remote work server error.', +// 'error.file_storage' => 'File storage server error.', // See comment in English file. +// 'error.remote_work' => 'Remote work server error.', // See comment in English file. // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 333f9bdce..4e74f6675 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -118,8 +118,8 @@ // 'error.format' => 'Invalid file format.', // 'error.user_count' => 'Limit on user count.', // 'error.expired' => 'Expiration date reached.', -// 'error.file_storage' => 'File storage error.', -// 'error.remote_work' => 'Remote work server error.', +// 'error.file_storage' => 'File storage server error.', // See comment in English file. +// 'error.remote_work' => 'Remote work server error.', // See comment in English file. // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index 0cbb48ea5..baf8e5ccb 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -116,8 +116,8 @@ // 'error.format' => 'Invalid file format.', // 'error.user_count' => 'Limit on user count.', // 'error.expired' => 'Expiration date reached.', -// 'error.file_storage' => 'File storage error.', -// 'error.remote_work' => 'Remote work server error.', +// 'error.file_storage' => 'File storage server error.', // See comment in English file. +// 'error.remote_work' => 'Remote work server error.', // See comment in English file. // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index 7e89f6f56..56e493ab6 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -112,8 +112,8 @@ // 'error.format' => 'Invalid file format.', // 'error.user_count' => 'Limit on user count.', // 'error.expired' => 'Expiration date reached.', -// 'error.file_storage' => 'File storage error.', -// 'error.remote_work' => 'Remote work server error.', +// 'error.file_storage' => 'File storage server error.', // See comment in English file. +// 'error.remote_work' => 'Remote work server error.', // See comment in English file. // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index 76d8c4a08..adf734a8d 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -132,8 +132,8 @@ // 'error.format' => 'Invalid file format.', // 'error.user_count' => 'Limit on user count.', // 'error.expired' => 'Expiration date reached.', -// 'error.file_storage' => 'File storage error.', -// 'error.remote_work' => 'Remote work server error.', +// 'error.file_storage' => 'File storage server error.', // See comment in English file. +// 'error.remote_work' => 'Remote work server error.', // See comment in English file. // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index e2657f493..924d6e033 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -121,8 +121,8 @@ // 'error.format' => 'Invalid file format.', // 'error.user_count' => 'Limit on user count.', // 'error.expired' => 'Expiration date reached.', -// 'error.file_storage' => 'File storage error.', -// 'error.remote_work' => 'Remote work server error.', +// 'error.file_storage' => 'File storage server error.', // See comment in English file. +// 'error.remote_work' => 'Remote work server error.', // See comment in English file. // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index cb78d281e..2829898f7 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -116,8 +116,8 @@ // 'error.format' => 'Invalid file format.', // 'error.user_count' => 'Limit on user count.', // 'error.expired' => 'Expiration date reached.', -// 'error.file_storage' => 'File storage error.', -// 'error.remote_work' => 'Remote work server error.', +// 'error.file_storage' => 'File storage server error.', // See comment in English file. +// 'error.remote_work' => 'Remote work server error.', // See comment in English file. // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index 417289d0d..3eebba753 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -123,8 +123,8 @@ // 'error.format' => 'Invalid file format.', // 'error.user_count' => 'Limit on user count.', // 'error.expired' => 'Expiration date reached.', -// 'error.file_storage' => 'File storage error.', -// 'error.remote_work' => 'Remote work server error.', +// 'error.file_storage' => 'File storage server error.', // See comment in English file. +// 'error.remote_work' => 'Remote work server error.', // See comment in English file. // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index ae02d30f3..c698461c5 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -122,8 +122,8 @@ // 'error.format' => 'Invalid file format.', // 'error.user_count' => 'Limit on user count.', // 'error.expired' => 'Expiration date reached.', -// 'error.file_storage' => 'File storage error.', -// 'error.remote_work' => 'Remote work server error.', +// 'error.file_storage' => 'File storage server error.', // See comment in English file. +// 'error.remote_work' => 'Remote work server error.', // See comment in English file. // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index b002e38ae..08127fd36 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -103,17 +103,22 @@ 'error.format' => 'Bestandsformaat niet valide.', 'error.user_count' => 'Limiet op aantal gebruikers.', 'error.expired' => 'Verloop datum is bereikt.', -// TODO: improve translations of both error.file_storage and error.remote_work. -// Both file storage and remote work (freelance) are implemented in external facilities, -// which are standalone applications out of scope of Time Tracker itself. -// -// error.file_storage means that something happened in a remote file storage server. -// error.remote_work means that something happened in a remote work server -// see documentation for remote work plugin, currently under development). -// Remote work plugin is designed to outsource work to other groups, when one group -// hires another group to do something (under development at the moment). -'error.file_storage' => 'Fout bij het opslaan van het bestand.', -'error.remote_work' => 'Fout in de server.', + +// TODO: translate error.file_storage and error.remote_work. + +// Meaning of error.file_storage: an (unspecified) error occurred when trying to communicate with remote +// file storage server (the one that handles attachments). It is a generic message telling us that +// "something went wrong" when trying to do some operation with attachments. +// For example, File Storage server could be offline, or Time Tracker config option is wrong, etc. + +// 'error.file_storage' => 'File storage server error.', // See comment in English file. + +// Meaning of error.remote_work: an (unspecified) error occurred when trying to communicate with +// "Remote Work" server, the one that supports the "Work" plugin, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm +// It is a generic message telling us that "something went wrong" when trying to do some operation with Work plugin. +// For example, Remote Work server could be offline, among other things. + +// 'error.remote_work' => 'Remote work server error.', // See comment in English file. // Warning messages. 'warn.sure' => 'Ben je er zeker van?', diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index 77b8d7506..cc67415e3 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -123,8 +123,8 @@ // 'error.format' => 'Invalid file format.', // 'error.user_count' => 'Limit on user count.', // 'error.expired' => 'Expiration date reached.', -// 'error.file_storage' => 'File storage error.', -// 'error.remote_work' => 'Remote work server error.', +// 'error.file_storage' => 'File storage server error.', // See comment in English file. +// 'error.remote_work' => 'Remote work server error.', // See comment in English file. // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index 9bcf32ff5..37a70eddf 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -120,8 +120,8 @@ // 'error.format' => 'Invalid file format.', // 'error.user_count' => 'Limit on user count.', // 'error.expired' => 'Expiration date reached.', -// 'error.file_storage' => 'File storage error.', -// 'error.remote_work' => 'Remote work server error.', +// 'error.file_storage' => 'File storage server error.', // See comment in English file. +// 'error.remote_work' => 'Remote work server error.', // See comment in English file. // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index 55ad505f7..78fee2655 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -117,8 +117,8 @@ // 'error.format' => 'Invalid file format.', // 'error.user_count' => 'Limit on user count.', // 'error.expired' => 'Expiration date reached.', -// 'error.file_storage' => 'File storage error.', -// 'error.remote_work' => 'Remote work server error.', +// 'error.file_storage' => 'File storage server error.', // See comment in English file. +// 'error.remote_work' => 'Remote work server error.', // See comment in English file. // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index eb5b1c00e..ce488a0e4 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -116,8 +116,8 @@ // 'error.format' => 'Invalid file format.', // 'error.user_count' => 'Limit on user count.', // 'error.expired' => 'Expiration date reached.', -// 'error.file_storage' => 'File storage error.', -// 'error.remote_work' => 'Remote work server error.', +// 'error.file_storage' => 'File storage server error.', // See comment in English file. +// 'error.remote_work' => 'Remote work server error.', // See comment in English file. // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index cbbf77231..fe224447c 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -123,8 +123,8 @@ // 'error.format' => 'Invalid file format.', // 'error.user_count' => 'Limit on user count.', // 'error.expired' => 'Expiration date reached.', -// 'error.file_storage' => 'File storage error.', -// 'error.remote_work' => 'Remote work server error.', +// 'error.file_storage' => 'File storage server error.', // See comment in English file. +// 'error.remote_work' => 'Remote work server error.', // See comment in English file. // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index 560f75174..3ce7c652f 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -103,7 +103,7 @@ 'error.format' => 'Неверный формат файла.', 'error.user_count' => 'Ограничение на количество пользователей.', 'error.expired' => 'Достигнута дата экспирации.', -'error.file_storage' => 'Ошибка файлохранилища.', +'error.file_storage' => 'Ошибка сервера для хранения файлов.', 'error.remote_work' => 'Ошибка сервера удаленной работы.', // Warning messages. diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index f767d1b0c..8f6bc8ec4 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -121,8 +121,8 @@ // 'error.format' => 'Invalid file format.', // 'error.user_count' => 'Limit on user count.', // 'error.expired' => 'Expiration date reached.', -// 'error.file_storage' => 'File storage error.', -// 'error.remote_work' => 'Remote work server error.', +// 'error.file_storage' => 'File storage server error.', // See comment in English file. +// 'error.remote_work' => 'Remote work server error.', // See comment in English file. // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index 3cf66b8cb..f6bda9246 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -113,8 +113,8 @@ // 'error.format' => 'Invalid file format.', // 'error.user_count' => 'Limit on user count.', // 'error.expired' => 'Expiration date reached.', -// 'error.file_storage' => 'File storage error.', -// 'error.remote_work' => 'Remote work server error.', +// 'error.file_storage' => 'File storage server error.', // See comment in English file. +// 'error.remote_work' => 'Remote work server error.', // See comment in English file. // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index 4f38b914a..0d8b1ada1 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -117,8 +117,8 @@ // 'error.format' => 'Invalid file format.', // 'error.user_count' => 'Limit on user count.', // 'error.expired' => 'Expiration date reached.', -// 'error.file_storage' => 'File storage error.', -// 'error.remote_work' => 'Remote work server error.', +// 'error.file_storage' => 'File storage server error.', // See comment in English file. +// 'error.remote_work' => 'Remote work server error.', // See comment in English file. // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index 6ee292f2a..a791f5453 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -116,8 +116,8 @@ // 'error.format' => 'Invalid file format.', // 'error.user_count' => 'Limit on user count.', // 'error.expired' => 'Expiration date reached.', -// 'error.file_storage' => 'File storage error.', -// 'error.remote_work' => 'Remote work server error.', +// 'error.file_storage' => 'File storage server error.', // See comment in English file. +// 'error.remote_work' => 'Remote work server error.', // See comment in English file. // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index 1c36dbb66..6d0a119bd 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -126,8 +126,8 @@ // 'error.format' => 'Invalid file format.', // 'error.user_count' => 'Limit on user count.', // 'error.expired' => 'Expiration date reached.', -// 'error.file_storage' => 'File storage error.', -// 'error.remote_work' => 'Remote work server error.', +// 'error.file_storage' => 'File storage server error.', // See comment in English file. +// 'error.remote_work' => 'Remote work server error.', // See comment in English file. // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index 0570609ed..0bf85186a 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -116,8 +116,8 @@ // 'error.format' => 'Invalid file format.', // 'error.user_count' => 'Limit on user count.', // 'error.expired' => 'Expiration date reached.', -// 'error.file_storage' => 'File storage error.', -// 'error.remote_work' => 'Remote work server error.', +// 'error.file_storage' => 'File storage server error.', // See comment in English file. +// 'error.remote_work' => 'Remote work server error.', // See comment in English file. // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index 55bbcc21d..e49fc98a3 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -120,8 +120,8 @@ // 'error.format' => 'Invalid file format.', // 'error.user_count' => 'Limit on user count.', // 'error.expired' => 'Expiration date reached.', -// 'error.file_storage' => 'File storage error.', -// 'error.remote_work' => 'Remote work server error.', +// 'error.file_storage' => 'File storage server error.', // See comment in English file. +// 'error.remote_work' => 'Remote work server error.', // See comment in English file. // Warning messages. // TODO: translate the following. diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index df31d30d6..6f373b3ec 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.19.10.5091 | Copyright © Anuko | +  Anuko Time Tracker 1.19.10.5092 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 526391e485ddf8ee32469ec9c11a41ceccd3fe15 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 20 Sep 2019 18:36:49 +0000 Subject: [PATCH 086/877] Dutch translation improved. --- WEB-INF/resources/nl.lang.php | 25 +++++++++++-------------- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 12 insertions(+), 15 deletions(-) diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 08127fd36..69e34a45f 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -253,7 +253,7 @@ 'label.submitted' => 'Verzonden', 'label.approved' => 'Goedgekeurd', 'label.approval' => 'Rapport goedkeuring', -'label.mark_approved' => 'Markeer goegkeuring', +'label.mark_approved' => 'Markeer goedkeuring', 'label.template' => 'Sjabloon', 'label.attachments' => 'Bijlagen', 'label.files' => 'Bestanden', @@ -262,9 +262,8 @@ 'label.download' => 'Download', 'label.active_users' => 'Actieve medewerkers', 'label.inactive_users' => 'Inactieve medewerkers', -// TODO: translate the following. -// 'label.details' => 'Details', -// 'label.budget' => 'Budget', +'label.details' => 'Details', +'label.budget' => 'Budget', // Entity names. 'entity.time' => 'tijd', @@ -365,16 +364,14 @@ 'title.edit_work' => 'Werk bewerken', 'title.delete_work' => 'Werk verwijderen', 'title.active_work' => 'Actief werk', -// TODO: translate the following. -// 'title.available_work' => 'Available Work', // Available work items from other organizations. +'title.available_work' => 'Beschikbaar werk', 'title.inactive_work' => 'Inactief werk', -// TODO: translate the following. -// 'title.add_offer' => 'Adding Offer', -// 'title.edit_offer' => 'Editing Offer', -// 'title.delete_offer' => 'Deleting Offer', -// 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. -// 'title.available_offers' => 'Available Offers', // Available offers from other organizations. -// 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. +'title.add_offer' => 'Aanbieding toevoegen', +'title.edit_offer' => 'Aanbieding bewerken', +'title.delete_offer' => 'Aanbieding verwijderen', +'title.active_offers' => 'Actieve aanbiedingen', +'title.available_offers' => 'Beschikbare aanbiedingen', +'title.inactive_offers' => 'Inactieve aanbiedingen', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. @@ -456,7 +453,7 @@ 'form.reports.set_period' => 'of stel datums in', 'form.reports.show_fields' => 'Toon velden', 'form.reports.time_fields' => 'Tijd velden', -'form.reports.user_fields' => 'Mederwerker velden', +'form.reports.user_fields' => 'Medewerker velden', 'form.reports.group_by' => 'Groeperen op', 'form.reports.group_by_no' => '--- niet groeperen ---', 'form.reports.group_by_date' => 'datum', diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 6f373b3ec..262d606d1 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- {if $active_work} - + @@ -39,7 +39,7 @@ {if $available_work} - + @@ -69,7 +69,7 @@ {if $active_offers} - + @@ -99,7 +99,7 @@ {if $available_offers} - + From 115e9b4f1c81b8090c72218315bba0d9e9430f6b Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 20 Sep 2019 19:29:32 +0000 Subject: [PATCH 088/877] Renamed labels on work/offer add/edit pages for clarity. --- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/offer_add.tpl | 2 +- WEB-INF/templates/offer_edit.tpl | 2 +- WEB-INF/templates/work_add.tpl | 2 +- WEB-INF/templates/work_edit.tpl | 2 +- offer_add.php | 2 +- offer_edit.php | 2 +- work_add.php | 2 +- work_edit.php | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 262d606d1..93ae8580c 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.19.10.5092 | Copyright © Anuko | +  Anuko Time Tracker 1.19.10.5093 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From ed238d889bf63631778355395aa3f83bc5716154 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 20 Sep 2019 19:04:27 +0000 Subject: [PATCH 087/877] Redoing some labels on work.php page. --- WEB-INF/resources/ca.lang.php | 2 ++ WEB-INF/resources/cs.lang.php | 2 ++ WEB-INF/resources/da.lang.php | 2 ++ WEB-INF/resources/de.lang.php | 3 +++ WEB-INF/resources/en.lang.php | 2 ++ WEB-INF/resources/es.lang.php | 2 ++ WEB-INF/resources/et.lang.php | 2 ++ WEB-INF/resources/fa.lang.php | 2 ++ WEB-INF/resources/fi.lang.php | 2 ++ WEB-INF/resources/fr.lang.php | 2 ++ WEB-INF/resources/gr.lang.php | 2 ++ WEB-INF/resources/he.lang.php | 2 ++ WEB-INF/resources/hu.lang.php | 2 ++ WEB-INF/resources/it.lang.php | 2 ++ WEB-INF/resources/ja.lang.php | 2 ++ WEB-INF/resources/ko.lang.php | 2 ++ WEB-INF/resources/nl.lang.php | 3 +++ WEB-INF/resources/no.lang.php | 2 ++ WEB-INF/resources/pl.lang.php | 2 ++ WEB-INF/resources/pt-br.lang.php | 2 ++ WEB-INF/resources/pt.lang.php | 2 ++ WEB-INF/resources/ro.lang.php | 2 ++ WEB-INF/resources/ru.lang.php | 2 ++ WEB-INF/resources/sk.lang.php | 2 ++ WEB-INF/resources/sl.lang.php | 2 ++ WEB-INF/resources/sr.lang.php | 2 ++ WEB-INF/resources/sv.lang.php | 2 ++ WEB-INF/resources/tr.lang.php | 2 ++ WEB-INF/resources/zh-cn.lang.php | 2 ++ WEB-INF/resources/zh-tw.lang.php | 2 ++ WEB-INF/templates/work.tpl | 8 ++++---- 31 files changed, 66 insertions(+), 4 deletions(-) diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index c50eb2fff..5137cb7cd 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -285,6 +285,8 @@ // 'label.inactive_users' => 'Inactive Users', // 'label.details' => 'Details', // 'label.budget' => 'Budget', +// 'label.work' => 'Work', // Table column header for work items, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm +// 'label.offer' => 'Offer', // Table column header for offers, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index 7eb333d46..157dc4ad2 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -295,6 +295,8 @@ // 'label.inactive_users' => 'Inactive Users', // 'label.details' => 'Details', // 'label.budget' => 'Budget', +// 'label.work' => 'Work', // Table column header for work items, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm +// 'label.offer' => 'Offer', // Table column header for offers, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index 450bb31ec..3088d3bf2 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -276,6 +276,8 @@ // TODO: translate the following. // 'label.details' => 'Details', // 'label.budget' => 'Budget', +// 'label.work' => 'Work', // Table column header for work items, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm +// 'label.offer' => 'Offer', // Table column header for offers, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index 4fffe05c0..9233c74d4 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -269,6 +269,9 @@ // Another use is with offers with Remote Work plugin, where details hold a long, precise, and complete description of the offer. // 'label.details' => 'Details', 'label.budget' => 'Budget', +// TODO: translate the following. +// 'label.work' => 'Work', // Table column header for work items, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm +// 'label.offer' => 'Offer', // Table column header for offers, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index 248176e97..5e534452c 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -259,6 +259,8 @@ 'label.inactive_users' => 'Inactive Users', 'label.details' => 'Details', 'label.budget' => 'Budget', +'label.work' => 'Work', // Table column header for work items, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm +'label.offer' => 'Offer', // Table column header for offers, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index be8996221..d5bc4b2b9 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -288,6 +288,8 @@ // 'label.inactive_users' => 'Inactive Users', // 'label.details' => 'Details', // 'label.budget' => 'Budget', +// 'label.work' => 'Work', // Table column header for work items, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm +// 'label.offer' => 'Offer', // Table column header for offers, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index 369224cdb..ef957582f 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -283,6 +283,8 @@ // TODO: translate the following. // 'label.details' => 'Details', // 'label.budget' => 'Budget', +// 'label.work' => 'Work', // Table column header for work items, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm +// 'label.offer' => 'Offer', // Table column header for offers, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index 30b6adbe2..8c21340c5 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -287,6 +287,8 @@ // TODO: translate the following. // 'label.details' => 'Details', // 'label.budget' => 'Budget', +// 'label.work' => 'Work', // Table column header for work items, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm +// 'label.offer' => 'Offer', // Table column header for offers, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 4e74f6675..a2c65200f 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -280,6 +280,8 @@ // TODO: translate the following. // 'label.details' => 'Details', // 'label.budget' => 'Budget', +// 'label.work' => 'Work', // Table column header for work items, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm +// 'label.offer' => 'Offer', // Table column header for offers, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index baf8e5ccb..0e39cd0c9 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -274,6 +274,8 @@ // TODO: translate the following. // 'label.details' => 'Details', // 'label.budget' => 'Budget', +// 'label.work' => 'Work', // Table column header for work items, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm +// 'label.offer' => 'Offer', // Table column header for offers, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index 56e493ab6..72bed0b56 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -270,6 +270,8 @@ // TODO: translate the following. // 'label.details' => 'Details', // 'label.budget' => 'Budget', +// 'label.work' => 'Work', // Table column header for work items, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm +// 'label.offer' => 'Offer', // Table column header for offers, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index adf734a8d..4f2a8c243 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -295,6 +295,8 @@ // TODO: translate the following. // 'label.details' => 'Details', // 'label.budget' => 'Budget', +// 'label.work' => 'Work', // Table column header for work items, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm +// 'label.offer' => 'Offer', // Table column header for offers, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index 924d6e033..9ff87b14b 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -291,6 +291,8 @@ // 'label.inactive_users' => 'Inactive Users', // 'label.details' => 'Details', // 'label.budget' => 'Budget', +// 'label.work' => 'Work', // Table column header for work items, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm +// 'label.offer' => 'Offer', // Table column header for offers, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index 2829898f7..64d4809de 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -274,6 +274,8 @@ // TODO: translate the following. // 'label.details' => 'Details', // 'label.budget' => 'Budget', +// 'label.work' => 'Work', // Table column header for work items, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm +// 'label.offer' => 'Offer', // Table column header for offers, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index 3eebba753..030470f3b 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -295,6 +295,8 @@ // 'label.inactive_users' => 'Inactive Users', // 'label.details' => 'Details', // 'label.budget' => 'Budget', +// 'label.work' => 'Work', // Table column header for work items, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm +// 'label.offer' => 'Offer', // Table column header for offers, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index c698461c5..90e7f6bc5 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -295,6 +295,8 @@ // 'label.inactive_users' => 'Inactive Users', // 'label.details' => 'Details', // 'label.budget' => 'Budget', +// 'label.work' => 'Work', // Table column header for work items, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm +// 'label.offer' => 'Offer', // Table column header for offers, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 69e34a45f..cfd826e0f 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -264,6 +264,9 @@ 'label.inactive_users' => 'Inactieve medewerkers', 'label.details' => 'Details', 'label.budget' => 'Budget', +// TODO: translate the following. +// 'label.work' => 'Work', // Table column header for work items, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm +// 'label.offer' => 'Offer', // Table column header for offers, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm // Entity names. 'entity.time' => 'tijd', diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index cc67415e3..2d01997ba 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -292,6 +292,8 @@ // 'label.inactive_users' => 'Inactive Users', // 'label.details' => 'Details', // 'label.budget' => 'Budget', +// 'label.work' => 'Work', // Table column header for work items, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm +// 'label.offer' => 'Offer', // Table column header for offers, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index 37a70eddf..9c20449b1 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -281,6 +281,8 @@ // TODO: translate the following. // 'label.details' => 'Details', // 'label.budget' => 'Budget', +// 'label.work' => 'Work', // Table column header for work items, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm +// 'label.offer' => 'Offer', // Table column header for offers, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index 78fee2655..bcba4bad2 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -278,6 +278,8 @@ // TODO: translate the following. // 'label.details' => 'Details', // 'label.budget' => 'Budget', +// 'label.work' => 'Work', // Table column header for work items, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm +// 'label.offer' => 'Offer', // Table column header for offers, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index ce488a0e4..f1eccf1f7 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -280,6 +280,8 @@ // 'label.inactive_users' => 'Inactive Users', // 'label.details' => 'Details', // 'label.budget' => 'Budget', +// 'label.work' => 'Work', // Table column header for work items, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm +// 'label.offer' => 'Offer', // Table column header for offers, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index fe224447c..4820beec1 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -292,6 +292,8 @@ // 'label.inactive_users' => 'Inactive Users', // 'label.details' => 'Details', // 'label.budget' => 'Budget', +// 'label.work' => 'Work', // Table column header for work items, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm +// 'label.offer' => 'Offer', // Table column header for offers, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index 3ce7c652f..39d7e4017 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -250,6 +250,8 @@ 'label.inactive_users' => 'Неактивные пользователи', 'label.details' => 'Детали', 'label.budget' => 'Бюджет', +'label.work' => 'Работа', +'label.offer' => 'Предложение', // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index 8f6bc8ec4..dbfbe6250 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -285,6 +285,8 @@ // TODO: translate the following. // 'label.details' => 'Details', // 'label.budget' => 'Budget', +// 'label.work' => 'Work', // Table column header for work items, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm +// 'label.offer' => 'Offer', // Table column header for offers, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index f6bda9246..b39e2ab99 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -275,6 +275,8 @@ // 'label.inactive_users' => 'Inactive Users', // 'label.details' => 'Details', // 'label.budget' => 'Budget', +// 'label.work' => 'Work', // Table column header for work items, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm +// 'label.offer' => 'Offer', // Table column header for offers, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index 0d8b1ada1..9c47bb180 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -279,6 +279,8 @@ // TODO: translate the following. // 'label.details' => 'Details', // 'label.budget' => 'Budget', +// 'label.work' => 'Work', // Table column header for work items, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm +// 'label.offer' => 'Offer', // Table column header for offers, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index a791f5453..64e3dc236 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -276,6 +276,8 @@ // TODO: translate the following. // 'label.details' => 'Details', // 'label.budget' => 'Budget', +// 'label.work' => 'Work', // Table column header for work items, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm +// 'label.offer' => 'Offer', // Table column header for offers, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index 6d0a119bd..17f160b0d 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -299,6 +299,8 @@ // 'label.inactive_users' => 'Inactive Users', // 'label.details' => 'Details', // 'label.budget' => 'Budget', +// 'label.work' => 'Work', // Table column header for work items, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm +// 'label.offer' => 'Offer', // Table column header for offers, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index 0bf85186a..fce1c9ea3 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -284,6 +284,8 @@ // 'label.inactive_users' => 'Inactive Users', // 'label.details' => 'Details', // 'label.budget' => 'Budget', +// 'label.work' => 'Work', // Table column header for work items, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm +// 'label.offer' => 'Offer', // Table column header for offers, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index e49fc98a3..6372c071e 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -290,6 +290,8 @@ // 'label.inactive_users' => 'Inactive Users', // 'label.details' => 'Details', // 'label.budget' => 'Budget', +// 'label.work' => 'Work', // Table column header for work items, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm +// 'label.offer' => 'Offer', // Table column header for offers, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/templates/work.tpl b/WEB-INF/templates/work.tpl index a0ff3d14b..250038bcd 100644 --- a/WEB-INF/templates/work.tpl +++ b/WEB-INF/templates/work.tpl @@ -9,7 +9,7 @@
{$i18n.title.active_work}
{$i18n.label.thing_name}{$i18n.label.work} {$i18n.label.description} {$i18n.label.budget}
{$i18n.title.available_work}
{$i18n.label.thing_name}{$i18n.label.work} {$i18n.label.description} {$i18n.label.budget}
{$i18n.title.active_offers}
{$i18n.label.thing_name}{$i18n.label.offer} {$i18n.label.description} {$i18n.label.budget}
{$i18n.title.available_offers}
{$i18n.label.thing_name}{$i18n.label.offer} {$i18n.label.description} {$i18n.label.budget}
-
 Anuko Time Tracker 1.19.10.5093 | Copyright © Anuko | +  Anuko Time Tracker 1.19.10.5094 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/offer_add.tpl b/WEB-INF/templates/offer_add.tpl index 3051e9664..764ab924f 100644 --- a/WEB-INF/templates/offer_add.tpl +++ b/WEB-INF/templates/offer_add.tpl @@ -4,7 +4,7 @@ - + diff --git a/WEB-INF/templates/offer_edit.tpl b/WEB-INF/templates/offer_edit.tpl index a80c82d79..2494ae9ad 100644 --- a/WEB-INF/templates/offer_edit.tpl +++ b/WEB-INF/templates/offer_edit.tpl @@ -4,7 +4,7 @@
{$i18n.label.thing_name} (*):{$i18n.label.offer} (*): {$forms.offerForm.offer_name.control}
- + diff --git a/WEB-INF/templates/work_add.tpl b/WEB-INF/templates/work_add.tpl index 3e2b00695..13bb385ad 100644 --- a/WEB-INF/templates/work_add.tpl +++ b/WEB-INF/templates/work_add.tpl @@ -4,7 +4,7 @@
{$i18n.label.thing_name} (*):{$i18n.label.offer} (*): {$forms.offerForm.offer_name.control}
- + diff --git a/WEB-INF/templates/work_edit.tpl b/WEB-INF/templates/work_edit.tpl index 792457226..76bb42c1a 100644 --- a/WEB-INF/templates/work_edit.tpl +++ b/WEB-INF/templates/work_edit.tpl @@ -4,7 +4,7 @@
{$i18n.label.thing_name} (*):{$i18n.label.work} (*): {$forms.workForm.work_name.control}
- + diff --git a/offer_add.php b/offer_add.php index e3efeaa45..87a35f9aa 100644 --- a/offer_add.php +++ b/offer_add.php @@ -61,7 +61,7 @@ if ($request->isPost()) { // Validate user input. - if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.thing_name')); + if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.offer')); if (!ttValidString($cl_description, true)) $err->add($i18n->get('error.field'), $i18n->get('label.description')); if (!ttValidString($cl_details, true)) $err->add($i18n->get('error.field'), $i18n->get('label.details')); if (!ttValidString($cl_budget)) $err->add($i18n->get('error.field'), $i18n->get('label.budget')); diff --git a/offer_edit.php b/offer_edit.php index d6b1ea94d..b2e337904 100644 --- a/offer_edit.php +++ b/offer_edit.php @@ -76,7 +76,7 @@ if ($request->isPost()) { // Validate user input. - if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.thing_name')); + if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.offer')); if (!ttValidString($cl_description, true)) $err->add($i18n->get('error.field'), $i18n->get('label.description')); if (!ttValidString($cl_details, true)) $err->add($i18n->get('error.field'), $i18n->get('label.details')); if (!ttValidString($cl_budget)) $err->add($i18n->get('error.field'), $i18n->get('label.budget')); diff --git a/work_add.php b/work_add.php index c085ce7cc..9fe73d206 100644 --- a/work_add.php +++ b/work_add.php @@ -69,7 +69,7 @@ if ($request->isPost()) { // Validate user input. - if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.thing_name')); + if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.work')); if (!ttValidString($cl_description, true)) $err->add($i18n->get('error.field'), $i18n->get('label.description')); if (!ttValidString($cl_details, true)) $err->add($i18n->get('error.field'), $i18n->get('label.details')); if (!ttValidString($cl_budget)) $err->add($i18n->get('error.field'), $i18n->get('label.budget')); diff --git a/work_edit.php b/work_edit.php index 43d793e7f..74c9d08fa 100644 --- a/work_edit.php +++ b/work_edit.php @@ -76,7 +76,7 @@ if ($request->isPost()) { // Validate user input. - if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.thing_name')); + if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.work')); if (!ttValidString($cl_description, true)) $err->add($i18n->get('error.field'), $i18n->get('label.description')); if (!ttValidString($cl_details, true)) $err->add($i18n->get('error.field'), $i18n->get('label.details')); if (!ttValidString($cl_budget)) $err->add($i18n->get('error.field'), $i18n->get('label.budget')); From d58de239a5073063107ec45f6ac7ff79b9263a2c Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 20 Sep 2019 19:39:27 +0000 Subject: [PATCH 089/877] Usability improvements on work.php page. --- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/work.tpl | 33 +++++++++++++++++---------------- 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 93ae8580c..333c7ad8f 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
{$i18n.label.thing_name} (*):{$i18n.label.work} (*): {$forms.workForm.work_name.control}
- - + @@ -29,41 +29,9 @@
 Anuko Time Tracker 1.19.10.5094 | Copyright © Anuko | +  Anuko Time Tracker 1.19.10.5095 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/work.tpl b/WEB-INF/templates/work.tpl index 250038bcd..54dd95d8f 100644 --- a/WEB-INF/templates/work.tpl +++ b/WEB-INF/templates/work.tpl @@ -5,9 +5,9 @@
+{if $active_work} - {if $active_work} @@ -15,7 +15,7 @@ - {foreach $active_work as $work_item} + {foreach $active_work as $work_item} @@ -23,8 +23,8 @@ - {/foreach} - {/if} + {/foreach} +
{$i18n.title.active_work}
{$i18n.label.work} {$i18n.label.description}
{$work_item.subject|escape} {$work_item.description|escape}{$i18n.label.edit} {$i18n.label.delete}
@@ -34,10 +34,11 @@
+{/if} - {if $available_work} +{if $available_work} @@ -45,7 +46,7 @@ - {foreach $available_work as $work_item} + {foreach $available_work as $work_item} @@ -53,8 +54,8 @@ - {/foreach} - {/if} + {/foreach} +{/if}
{$i18n.title.available_work}
{$i18n.label.work} {$i18n.label.description}
{$work_item.subject|escape} {$work_item.description|escape}
@@ -65,9 +66,9 @@
+{if $active_offers} - {if $active_offers} @@ -75,7 +76,7 @@ - {foreach $active_offers as $offer} + {foreach $active_offers as $offer} @@ -83,8 +84,7 @@ - {/foreach} - {/if} + {/foreach}
{$i18n.title.active_offers}
{$i18n.label.offer} {$i18n.label.description}
{$offer.subject|escape} {$offer.description|escape}{$i18n.label.edit} {$i18n.label.delete}
@@ -94,10 +94,11 @@
+{/if} - {if $available_offers} +{if $available_offers} @@ -105,7 +106,7 @@ - {foreach $available_offers as $offer} + {foreach $available_offers as $offer} @@ -113,8 +114,8 @@ - {/foreach} - {/if} + {/foreach} +{/if}
{$i18n.title.available_offers}
{$i18n.label.offer} {$i18n.label.description}
{$offer.subject|escape} {$offer.description|escape}
From 6262668684364c8f1406044e382913a2bd6566de Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 20 Sep 2019 20:14:55 +0000 Subject: [PATCH 090/877] Added contractor column for offers on work.php page. --- WEB-INF/resources/ca.lang.php | 3 +++ WEB-INF/resources/cs.lang.php | 3 +++ WEB-INF/resources/da.lang.php | 3 +++ WEB-INF/resources/de.lang.php | 3 +++ WEB-INF/resources/en.lang.php | 3 +++ WEB-INF/resources/es.lang.php | 3 +++ WEB-INF/resources/et.lang.php | 3 +++ WEB-INF/resources/fa.lang.php | 3 +++ WEB-INF/resources/fi.lang.php | 3 +++ WEB-INF/resources/fr.lang.php | 3 +++ WEB-INF/resources/gr.lang.php | 3 +++ WEB-INF/resources/he.lang.php | 3 +++ WEB-INF/resources/hu.lang.php | 3 +++ WEB-INF/resources/it.lang.php | 3 +++ WEB-INF/resources/ja.lang.php | 3 +++ WEB-INF/resources/ko.lang.php | 3 +++ WEB-INF/resources/nl.lang.php | 3 +++ WEB-INF/resources/no.lang.php | 3 +++ WEB-INF/resources/pl.lang.php | 3 +++ WEB-INF/resources/pt-br.lang.php | 3 +++ WEB-INF/resources/pt.lang.php | 3 +++ WEB-INF/resources/ro.lang.php | 3 +++ WEB-INF/resources/ru.lang.php | 1 + WEB-INF/resources/sk.lang.php | 3 +++ WEB-INF/resources/sl.lang.php | 3 +++ WEB-INF/resources/sr.lang.php | 3 +++ WEB-INF/resources/sv.lang.php | 3 +++ WEB-INF/resources/tr.lang.php | 3 +++ WEB-INF/resources/zh-cn.lang.php | 3 +++ WEB-INF/resources/zh-tw.lang.php | 3 +++ WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/work.tpl | 4 ++++ 32 files changed, 93 insertions(+), 1 deletion(-) diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index 5137cb7cd..a1372bda4 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -287,6 +287,9 @@ // 'label.budget' => 'Budget', // 'label.work' => 'Work', // Table column header for work items, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm // 'label.offer' => 'Offer', // Table column header for offers, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm +// 'label.contractor' => 'Contractor', // Table column header for offers (contractor is someone who offers to do work). + // Technically, it is either an org name or a combination of org and group names + // because both work items and offers are owned by Time Tracker groups of users. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index 157dc4ad2..d6fc6ff57 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -297,6 +297,9 @@ // 'label.budget' => 'Budget', // 'label.work' => 'Work', // Table column header for work items, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm // 'label.offer' => 'Offer', // Table column header for offers, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm +// 'label.contractor' => 'Contractor', // Table column header for offers (contractor is someone who offers to do work). + // Technically, it is either an org name or a combination of org and group names + // because both work items and offers are owned by Time Tracker groups of users. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index 3088d3bf2..4fdb4b96f 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -278,6 +278,9 @@ // 'label.budget' => 'Budget', // 'label.work' => 'Work', // Table column header for work items, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm // 'label.offer' => 'Offer', // Table column header for offers, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm +// 'label.contractor' => 'Contractor', // Table column header for offers (contractor is someone who offers to do work). + // Technically, it is either an org name or a combination of org and group names + // because both work items and offers are owned by Time Tracker groups of users. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index 9233c74d4..524a18d64 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -272,6 +272,9 @@ // TODO: translate the following. // 'label.work' => 'Work', // Table column header for work items, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm // 'label.offer' => 'Offer', // Table column header for offers, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm +// 'label.contractor' => 'Contractor', // Table column header for offers (contractor is someone who offers to do work). + // Technically, it is either an org name or a combination of org and group names + // because both work items and offers are owned by Time Tracker groups of users. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index 5e534452c..821e3236d 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -261,6 +261,9 @@ 'label.budget' => 'Budget', 'label.work' => 'Work', // Table column header for work items, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm 'label.offer' => 'Offer', // Table column header for offers, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm +'label.contractor' => 'Contractor', // Table column header for offers (contractor is someone who offers to do work). + // Technically, it is either an org name or a combination of org and group names + // because both work items and offers are owned by Time Tracker groups of users. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index d5bc4b2b9..6c86e23b7 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -290,6 +290,9 @@ // 'label.budget' => 'Budget', // 'label.work' => 'Work', // Table column header for work items, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm // 'label.offer' => 'Offer', // Table column header for offers, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm +// 'label.contractor' => 'Contractor', // Table column header for offers (contractor is someone who offers to do work). + // Technically, it is either an org name or a combination of org and group names + // because both work items and offers are owned by Time Tracker groups of users. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index ef957582f..0493cd560 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -285,6 +285,9 @@ // 'label.budget' => 'Budget', // 'label.work' => 'Work', // Table column header for work items, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm // 'label.offer' => 'Offer', // Table column header for offers, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm +// 'label.contractor' => 'Contractor', // Table column header for offers (contractor is someone who offers to do work). + // Technically, it is either an org name or a combination of org and group names + // because both work items and offers are owned by Time Tracker groups of users. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index 8c21340c5..0e6cb3f53 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -289,6 +289,9 @@ // 'label.budget' => 'Budget', // 'label.work' => 'Work', // Table column header for work items, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm // 'label.offer' => 'Offer', // Table column header for offers, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm +// 'label.contractor' => 'Contractor', // Table column header for offers (contractor is someone who offers to do work). + // Technically, it is either an org name or a combination of org and group names + // because both work items and offers are owned by Time Tracker groups of users. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index a2c65200f..b2c91b1ec 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -282,6 +282,9 @@ // 'label.budget' => 'Budget', // 'label.work' => 'Work', // Table column header for work items, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm // 'label.offer' => 'Offer', // Table column header for offers, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm +// 'label.contractor' => 'Contractor', // Table column header for offers (contractor is someone who offers to do work). + // Technically, it is either an org name or a combination of org and group names + // because both work items and offers are owned by Time Tracker groups of users. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index 0e39cd0c9..f98a575da 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -276,6 +276,9 @@ // 'label.budget' => 'Budget', // 'label.work' => 'Work', // Table column header for work items, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm // 'label.offer' => 'Offer', // Table column header for offers, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm +// 'label.contractor' => 'Contractor', // Table column header for offers (contractor is someone who offers to do work). + // Technically, it is either an org name or a combination of org and group names + // because both work items and offers are owned by Time Tracker groups of users. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index 72bed0b56..a64100e49 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -272,6 +272,9 @@ // 'label.budget' => 'Budget', // 'label.work' => 'Work', // Table column header for work items, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm // 'label.offer' => 'Offer', // Table column header for offers, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm +// 'label.contractor' => 'Contractor', // Table column header for offers (contractor is someone who offers to do work). + // Technically, it is either an org name or a combination of org and group names + // because both work items and offers are owned by Time Tracker groups of users. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index 4f2a8c243..928ea1a9a 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -297,6 +297,9 @@ // 'label.budget' => 'Budget', // 'label.work' => 'Work', // Table column header for work items, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm // 'label.offer' => 'Offer', // Table column header for offers, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm +// 'label.contractor' => 'Contractor', // Table column header for offers (contractor is someone who offers to do work). + // Technically, it is either an org name or a combination of org and group names + // because both work items and offers are owned by Time Tracker groups of users. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index 9ff87b14b..805f81732 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -293,6 +293,9 @@ // 'label.budget' => 'Budget', // 'label.work' => 'Work', // Table column header for work items, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm // 'label.offer' => 'Offer', // Table column header for offers, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm +// 'label.contractor' => 'Contractor', // Table column header for offers (contractor is someone who offers to do work). + // Technically, it is either an org name or a combination of org and group names + // because both work items and offers are owned by Time Tracker groups of users. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index 64d4809de..26cd4e8ba 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -276,6 +276,9 @@ // 'label.budget' => 'Budget', // 'label.work' => 'Work', // Table column header for work items, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm // 'label.offer' => 'Offer', // Table column header for offers, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm +// 'label.contractor' => 'Contractor', // Table column header for offers (contractor is someone who offers to do work). + // Technically, it is either an org name or a combination of org and group names + // because both work items and offers are owned by Time Tracker groups of users. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index 030470f3b..acb74fe7b 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -297,6 +297,9 @@ // 'label.budget' => 'Budget', // 'label.work' => 'Work', // Table column header for work items, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm // 'label.offer' => 'Offer', // Table column header for offers, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm +// 'label.contractor' => 'Contractor', // Table column header for offers (contractor is someone who offers to do work). + // Technically, it is either an org name or a combination of org and group names + // because both work items and offers are owned by Time Tracker groups of users. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index 90e7f6bc5..43eb93ffa 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -297,6 +297,9 @@ // 'label.budget' => 'Budget', // 'label.work' => 'Work', // Table column header for work items, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm // 'label.offer' => 'Offer', // Table column header for offers, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm +// 'label.contractor' => 'Contractor', // Table column header for offers (contractor is someone who offers to do work). + // Technically, it is either an org name or a combination of org and group names + // because both work items and offers are owned by Time Tracker groups of users. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index cfd826e0f..b961adcf2 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -267,6 +267,9 @@ // TODO: translate the following. // 'label.work' => 'Work', // Table column header for work items, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm // 'label.offer' => 'Offer', // Table column header for offers, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm +// 'label.contractor' => 'Contractor', // Table column header for offers (contractor is someone who offers to do work). + // Technically, it is either an org name or a combination of org and group names + // because both work items and offers are owned by Time Tracker groups of users. // Entity names. 'entity.time' => 'tijd', diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index 2d01997ba..a194d3337 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -294,6 +294,9 @@ // 'label.budget' => 'Budget', // 'label.work' => 'Work', // Table column header for work items, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm // 'label.offer' => 'Offer', // Table column header for offers, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm +// 'label.contractor' => 'Contractor', // Table column header for offers (contractor is someone who offers to do work). + // Technically, it is either an org name or a combination of org and group names + // because both work items and offers are owned by Time Tracker groups of users. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index 9c20449b1..61168a4c3 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -283,6 +283,9 @@ // 'label.budget' => 'Budget', // 'label.work' => 'Work', // Table column header for work items, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm // 'label.offer' => 'Offer', // Table column header for offers, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm +// 'label.contractor' => 'Contractor', // Table column header for offers (contractor is someone who offers to do work). + // Technically, it is either an org name or a combination of org and group names + // because both work items and offers are owned by Time Tracker groups of users. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index bcba4bad2..bc679de80 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -280,6 +280,9 @@ // 'label.budget' => 'Budget', // 'label.work' => 'Work', // Table column header for work items, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm // 'label.offer' => 'Offer', // Table column header for offers, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm +// 'label.contractor' => 'Contractor', // Table column header for offers (contractor is someone who offers to do work). + // Technically, it is either an org name or a combination of org and group names + // because both work items and offers are owned by Time Tracker groups of users. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index f1eccf1f7..191c31db9 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -282,6 +282,9 @@ // 'label.budget' => 'Budget', // 'label.work' => 'Work', // Table column header for work items, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm // 'label.offer' => 'Offer', // Table column header for offers, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm +// 'label.contractor' => 'Contractor', // Table column header for offers (contractor is someone who offers to do work). + // Technically, it is either an org name or a combination of org and group names + // because both work items and offers are owned by Time Tracker groups of users. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index 4820beec1..bdbd5a918 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -294,6 +294,9 @@ // 'label.budget' => 'Budget', // 'label.work' => 'Work', // Table column header for work items, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm // 'label.offer' => 'Offer', // Table column header for offers, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm +// 'label.contractor' => 'Contractor', // Table column header for offers (contractor is someone who offers to do work). + // Technically, it is either an org name or a combination of org and group names + // because both work items and offers are owned by Time Tracker groups of users. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index 39d7e4017..66f8491a4 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -252,6 +252,7 @@ 'label.budget' => 'Бюджет', 'label.work' => 'Работа', 'label.offer' => 'Предложение', +'label.contractor' => 'Подрядчик', // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index dbfbe6250..e6b12a115 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -287,6 +287,9 @@ // 'label.budget' => 'Budget', // 'label.work' => 'Work', // Table column header for work items, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm // 'label.offer' => 'Offer', // Table column header for offers, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm +// 'label.contractor' => 'Contractor', // Table column header for offers (contractor is someone who offers to do work). + // Technically, it is either an org name or a combination of org and group names + // because both work items and offers are owned by Time Tracker groups of users. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index b39e2ab99..ddc87beb9 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -277,6 +277,9 @@ // 'label.budget' => 'Budget', // 'label.work' => 'Work', // Table column header for work items, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm // 'label.offer' => 'Offer', // Table column header for offers, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm +// 'label.contractor' => 'Contractor', // Table column header for offers (contractor is someone who offers to do work). + // Technically, it is either an org name or a combination of org and group names + // because both work items and offers are owned by Time Tracker groups of users. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index 9c47bb180..2ec381e53 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -281,6 +281,9 @@ // 'label.budget' => 'Budget', // 'label.work' => 'Work', // Table column header for work items, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm // 'label.offer' => 'Offer', // Table column header for offers, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm +// 'label.contractor' => 'Contractor', // Table column header for offers (contractor is someone who offers to do work). + // Technically, it is either an org name or a combination of org and group names + // because both work items and offers are owned by Time Tracker groups of users. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index 64e3dc236..e8bb43197 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -278,6 +278,9 @@ // 'label.budget' => 'Budget', // 'label.work' => 'Work', // Table column header for work items, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm // 'label.offer' => 'Offer', // Table column header for offers, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm +// 'label.contractor' => 'Contractor', // Table column header for offers (contractor is someone who offers to do work). + // Technically, it is either an org name or a combination of org and group names + // because both work items and offers are owned by Time Tracker groups of users. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index 17f160b0d..5212a81cf 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -301,6 +301,9 @@ // 'label.budget' => 'Budget', // 'label.work' => 'Work', // Table column header for work items, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm // 'label.offer' => 'Offer', // Table column header for offers, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm +// 'label.contractor' => 'Contractor', // Table column header for offers (contractor is someone who offers to do work). + // Technically, it is either an org name or a combination of org and group names + // because both work items and offers are owned by Time Tracker groups of users. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index fce1c9ea3..70612f20c 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -286,6 +286,9 @@ // 'label.budget' => 'Budget', // 'label.work' => 'Work', // Table column header for work items, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm // 'label.offer' => 'Offer', // Table column header for offers, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm +// 'label.contractor' => 'Contractor', // Table column header for offers (contractor is someone who offers to do work). + // Technically, it is either an org name or a combination of org and group names + // because both work items and offers are owned by Time Tracker groups of users. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index 6372c071e..080802a79 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -292,6 +292,9 @@ // 'label.budget' => 'Budget', // 'label.work' => 'Work', // Table column header for work items, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm // 'label.offer' => 'Offer', // Table column header for offers, see https://www.anuko.com/time_tracker/what_is/work_plugin.htm +// 'label.contractor' => 'Contractor', // Table column header for offers (contractor is someone who offers to do work). + // Technically, it is either an org name or a combination of org and group names + // because both work items and offers are owned by Time Tracker groups of users. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 333c7ad8f..87fd3ed30 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- + @@ -80,6 +81,7 @@ + @@ -102,6 +104,7 @@ + @@ -110,6 +113,7 @@ + From ea1662bd668c41a20fe2caa67e8abcc288a9ff86 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 20 Sep 2019 20:39:23 +0000 Subject: [PATCH 091/877] Added client column to work tables on work.php. --- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/work.tpl | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 87fd3ed30..d2d613624 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.19.10.5095 | Copyright © Anuko | +  Anuko Time Tracker 1.19.10.5096 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/work.tpl b/WEB-INF/templates/work.tpl index 54dd95d8f..51632578e 100644 --- a/WEB-INF/templates/work.tpl +++ b/WEB-INF/templates/work.tpl @@ -72,6 +72,7 @@
{$i18n.label.offer} {$i18n.label.description}{$i18n.label.contractor} {$i18n.label.budget}
{$offer.subject|escape} {$offer.description|escape}{$offer.group_name|escape} {$offer.currency} {$offer.amount} {$i18n.label.edit} {$i18n.label.delete}
{$i18n.label.offer} {$i18n.label.description}{$i18n.label.contractor} {$i18n.label.budget}
{$offer.subject|escape} {$offer.description|escape}{$offer.group_name|escape} {$offer.currency} {$offer.amount}
- + @@ -19,6 +20,7 @@ + @@ -42,6 +44,7 @@ + @@ -50,6 +53,7 @@ + From bcfb910316ef66cb8578050cfa79f11661adc846 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 21 Sep 2019 15:10:24 +0000 Subject: [PATCH 092/877] Added payment information to offers. --- WEB-INF/lib/ttWorkHelper.class.php | 2 ++ WEB-INF/resources/ca.lang.php | 2 ++ WEB-INF/resources/cs.lang.php | 2 ++ WEB-INF/resources/da.lang.php | 2 ++ WEB-INF/resources/de.lang.php | 2 ++ WEB-INF/resources/en.lang.php | 2 ++ WEB-INF/resources/es.lang.php | 2 ++ WEB-INF/resources/et.lang.php | 2 ++ WEB-INF/resources/fa.lang.php | 2 ++ WEB-INF/resources/fi.lang.php | 2 ++ WEB-INF/resources/fr.lang.php | 2 ++ WEB-INF/resources/gr.lang.php | 2 ++ WEB-INF/resources/he.lang.php | 2 ++ WEB-INF/resources/hu.lang.php | 2 ++ WEB-INF/resources/it.lang.php | 2 ++ WEB-INF/resources/ja.lang.php | 2 ++ WEB-INF/resources/ko.lang.php | 2 ++ WEB-INF/resources/nl.lang.php | 2 ++ WEB-INF/resources/no.lang.php | 2 ++ WEB-INF/resources/pl.lang.php | 2 ++ WEB-INF/resources/pt-br.lang.php | 2 ++ WEB-INF/resources/pt.lang.php | 2 ++ WEB-INF/resources/ro.lang.php | 2 ++ WEB-INF/resources/ru.lang.php | 1 + WEB-INF/resources/sk.lang.php | 2 ++ WEB-INF/resources/sl.lang.php | 2 ++ WEB-INF/resources/sr.lang.php | 2 ++ WEB-INF/resources/sv.lang.php | 2 ++ WEB-INF/resources/tr.lang.php | 2 ++ WEB-INF/resources/zh-cn.lang.php | 2 ++ WEB-INF/resources/zh-tw.lang.php | 2 ++ WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/offer_add.tpl | 4 ++++ WEB-INF/templates/offer_edit.tpl | 4 ++++ offer_add.php | 6 +++++- offer_edit.php | 7 ++++++- 36 files changed, 81 insertions(+), 3 deletions(-) diff --git a/WEB-INF/lib/ttWorkHelper.class.php b/WEB-INF/lib/ttWorkHelper.class.php index cbf81136e..fdf80cab7 100644 --- a/WEB-INF/lib/ttWorkHelper.class.php +++ b/WEB-INF/lib/ttWorkHelper.class.php @@ -562,6 +562,7 @@ function putOffer($fields) { 'descr_long' => urlencode(base64_encode($fields['descr_long'])), 'currency' => urlencode($fields['currency']), 'amount' => urlencode($fields['amount']), + 'payment_info' => urlencode(base64_encode($fields['payment_info'])), 'created_ip' => urlencode($_SERVER['REMOTE_ADDR']), 'created_by' => urlencode($user->getUser()), 'created_by_name' => urlencode(base64_encode($user->getName())), @@ -805,6 +806,7 @@ function updateOffer($fields) { 'descr_long' => urlencode(base64_encode($fields['descr_long'])), 'currency' => urlencode($fields['currency']), 'amount' => urlencode($fields['amount']), + 'payment_info' => urlencode(base64_encode($fields['payment_info'])), 'modified_ip' => urlencode($_SERVER['REMOTE_ADDR']), 'modified_by' => urlencode($user->getUser()), 'modified_by_name' => urlencode(base64_encode($user->getName())), diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index a1372bda4..ef585b672 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -290,6 +290,8 @@ // 'label.contractor' => 'Contractor', // Table column header for offers (contractor is someone who offers to do work). // Technically, it is either an org name or a combination of org and group names // because both work items and offers are owned by Time Tracker groups of users. +// 'label.how_to_pay' => 'How to pay', // Label for the "How to pay" field on offers, which allows contractors to specify + // how to pay them, for example: paypal email, check by mail to a specific address, etc. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index d6fc6ff57..d493145a6 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -300,6 +300,8 @@ // 'label.contractor' => 'Contractor', // Table column header for offers (contractor is someone who offers to do work). // Technically, it is either an org name or a combination of org and group names // because both work items and offers are owned by Time Tracker groups of users. +// 'label.how_to_pay' => 'How to pay', // Label for the "How to pay" field on offers, which allows contractors to specify + // how to pay them, for example: paypal email, check by mail to a specific address, etc. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index 4fdb4b96f..8d92afc76 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -281,6 +281,8 @@ // 'label.contractor' => 'Contractor', // Table column header for offers (contractor is someone who offers to do work). // Technically, it is either an org name or a combination of org and group names // because both work items and offers are owned by Time Tracker groups of users. +// 'label.how_to_pay' => 'How to pay', // Label for the "How to pay" field on offers, which allows contractors to specify + // how to pay them, for example: paypal email, check by mail to a specific address, etc. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index 524a18d64..c38691866 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -275,6 +275,8 @@ // 'label.contractor' => 'Contractor', // Table column header for offers (contractor is someone who offers to do work). // Technically, it is either an org name or a combination of org and group names // because both work items and offers are owned by Time Tracker groups of users. +// 'label.how_to_pay' => 'How to pay', // Label for the "How to pay" field on offers, which allows contractors to specify + // how to pay them, for example: paypal email, check by mail to a specific address, etc. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index 821e3236d..71b33c740 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -264,6 +264,8 @@ 'label.contractor' => 'Contractor', // Table column header for offers (contractor is someone who offers to do work). // Technically, it is either an org name or a combination of org and group names // because both work items and offers are owned by Time Tracker groups of users. +'label.how_to_pay' => 'How to pay', // Label for the "How to pay" field on offers, which allows contractors to specify + // how to pay them, for example: paypal email, check by mail to a specific address, etc. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index 6c86e23b7..0955af863 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -293,6 +293,8 @@ // 'label.contractor' => 'Contractor', // Table column header for offers (contractor is someone who offers to do work). // Technically, it is either an org name or a combination of org and group names // because both work items and offers are owned by Time Tracker groups of users. +// 'label.how_to_pay' => 'How to pay', // Label for the "How to pay" field on offers, which allows contractors to specify + // how to pay them, for example: paypal email, check by mail to a specific address, etc. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index 0493cd560..be0b4d60d 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -288,6 +288,8 @@ // 'label.contractor' => 'Contractor', // Table column header for offers (contractor is someone who offers to do work). // Technically, it is either an org name or a combination of org and group names // because both work items and offers are owned by Time Tracker groups of users. +// 'label.how_to_pay' => 'How to pay', // Label for the "How to pay" field on offers, which allows contractors to specify + // how to pay them, for example: paypal email, check by mail to a specific address, etc. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index 0e6cb3f53..a1f25ce9c 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -292,6 +292,8 @@ // 'label.contractor' => 'Contractor', // Table column header for offers (contractor is someone who offers to do work). // Technically, it is either an org name or a combination of org and group names // because both work items and offers are owned by Time Tracker groups of users. +// 'label.how_to_pay' => 'How to pay', // Label for the "How to pay" field on offers, which allows contractors to specify + // how to pay them, for example: paypal email, check by mail to a specific address, etc. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index b2c91b1ec..bed26efc2 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -285,6 +285,8 @@ // 'label.contractor' => 'Contractor', // Table column header for offers (contractor is someone who offers to do work). // Technically, it is either an org name or a combination of org and group names // because both work items and offers are owned by Time Tracker groups of users. +// 'label.how_to_pay' => 'How to pay', // Label for the "How to pay" field on offers, which allows contractors to specify + // how to pay them, for example: paypal email, check by mail to a specific address, etc. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index f98a575da..98deacf82 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -279,6 +279,8 @@ // 'label.contractor' => 'Contractor', // Table column header for offers (contractor is someone who offers to do work). // Technically, it is either an org name or a combination of org and group names // because both work items and offers are owned by Time Tracker groups of users. +// 'label.how_to_pay' => 'How to pay', // Label for the "How to pay" field on offers, which allows contractors to specify + // how to pay them, for example: paypal email, check by mail to a specific address, etc. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index a64100e49..1c5197d63 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -275,6 +275,8 @@ // 'label.contractor' => 'Contractor', // Table column header for offers (contractor is someone who offers to do work). // Technically, it is either an org name or a combination of org and group names // because both work items and offers are owned by Time Tracker groups of users. +// 'label.how_to_pay' => 'How to pay', // Label for the "How to pay" field on offers, which allows contractors to specify + // how to pay them, for example: paypal email, check by mail to a specific address, etc. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index 928ea1a9a..d4306e1b2 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -300,6 +300,8 @@ // 'label.contractor' => 'Contractor', // Table column header for offers (contractor is someone who offers to do work). // Technically, it is either an org name or a combination of org and group names // because both work items and offers are owned by Time Tracker groups of users. +// 'label.how_to_pay' => 'How to pay', // Label for the "How to pay" field on offers, which allows contractors to specify + // how to pay them, for example: paypal email, check by mail to a specific address, etc. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index 805f81732..1c41a48b4 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -296,6 +296,8 @@ // 'label.contractor' => 'Contractor', // Table column header for offers (contractor is someone who offers to do work). // Technically, it is either an org name or a combination of org and group names // because both work items and offers are owned by Time Tracker groups of users. +// 'label.how_to_pay' => 'How to pay', // Label for the "How to pay" field on offers, which allows contractors to specify + // how to pay them, for example: paypal email, check by mail to a specific address, etc. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index 26cd4e8ba..04a83aa2b 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -279,6 +279,8 @@ // 'label.contractor' => 'Contractor', // Table column header for offers (contractor is someone who offers to do work). // Technically, it is either an org name or a combination of org and group names // because both work items and offers are owned by Time Tracker groups of users. +// 'label.how_to_pay' => 'How to pay', // Label for the "How to pay" field on offers, which allows contractors to specify + // how to pay them, for example: paypal email, check by mail to a specific address, etc. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index acb74fe7b..afcc53d39 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -300,6 +300,8 @@ // 'label.contractor' => 'Contractor', // Table column header for offers (contractor is someone who offers to do work). // Technically, it is either an org name or a combination of org and group names // because both work items and offers are owned by Time Tracker groups of users. +// 'label.how_to_pay' => 'How to pay', // Label for the "How to pay" field on offers, which allows contractors to specify + // how to pay them, for example: paypal email, check by mail to a specific address, etc. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index 43eb93ffa..bd30ed0de 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -300,6 +300,8 @@ // 'label.contractor' => 'Contractor', // Table column header for offers (contractor is someone who offers to do work). // Technically, it is either an org name or a combination of org and group names // because both work items and offers are owned by Time Tracker groups of users. +// 'label.how_to_pay' => 'How to pay', // Label for the "How to pay" field on offers, which allows contractors to specify + // how to pay them, for example: paypal email, check by mail to a specific address, etc. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index b961adcf2..224ff08b3 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -270,6 +270,8 @@ // 'label.contractor' => 'Contractor', // Table column header for offers (contractor is someone who offers to do work). // Technically, it is either an org name or a combination of org and group names // because both work items and offers are owned by Time Tracker groups of users. +// 'label.how_to_pay' => 'How to pay', // Label for the "How to pay" field on offers, which allows contractors to specify + // how to pay them, for example: paypal email, check by mail to a specific address, etc.S // Entity names. 'entity.time' => 'tijd', diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index a194d3337..2c0f03625 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -297,6 +297,8 @@ // 'label.contractor' => 'Contractor', // Table column header for offers (contractor is someone who offers to do work). // Technically, it is either an org name or a combination of org and group names // because both work items and offers are owned by Time Tracker groups of users. +// 'label.how_to_pay' => 'How to pay', // Label for the "How to pay" field on offers, which allows contractors to specify + // how to pay them, for example: paypal email, check by mail to a specific address, etc. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index 61168a4c3..f8b0ebf5f 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -286,6 +286,8 @@ // 'label.contractor' => 'Contractor', // Table column header for offers (contractor is someone who offers to do work). // Technically, it is either an org name or a combination of org and group names // because both work items and offers are owned by Time Tracker groups of users. +// 'label.how_to_pay' => 'How to pay', // Label for the "How to pay" field on offers, which allows contractors to specify + // how to pay them, for example: paypal email, check by mail to a specific address, etc. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index bc679de80..af31f68c0 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -283,6 +283,8 @@ // 'label.contractor' => 'Contractor', // Table column header for offers (contractor is someone who offers to do work). // Technically, it is either an org name or a combination of org and group names // because both work items and offers are owned by Time Tracker groups of users. +// 'label.how_to_pay' => 'How to pay', // Label for the "How to pay" field on offers, which allows contractors to specify + // how to pay them, for example: paypal email, check by mail to a specific address, etc. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index 191c31db9..7f7d7d17d 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -285,6 +285,8 @@ // 'label.contractor' => 'Contractor', // Table column header for offers (contractor is someone who offers to do work). // Technically, it is either an org name or a combination of org and group names // because both work items and offers are owned by Time Tracker groups of users. +// 'label.how_to_pay' => 'How to pay', // Label for the "How to pay" field on offers, which allows contractors to specify + // how to pay them, for example: paypal email, check by mail to a specific address, etc. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index bdbd5a918..124a5b826 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -297,6 +297,8 @@ // 'label.contractor' => 'Contractor', // Table column header for offers (contractor is someone who offers to do work). // Technically, it is either an org name or a combination of org and group names // because both work items and offers are owned by Time Tracker groups of users. +// 'label.how_to_pay' => 'How to pay', // Label for the "How to pay" field on offers, which allows contractors to specify + // how to pay them, for example: paypal email, check by mail to a specific address, etc. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index 66f8491a4..5941310ee 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -253,6 +253,7 @@ 'label.work' => 'Работа', 'label.offer' => 'Предложение', 'label.contractor' => 'Подрядчик', +'label.how_to_pay' => 'Как оплатить', // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index e6b12a115..14ba25056 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -290,6 +290,8 @@ // 'label.contractor' => 'Contractor', // Table column header for offers (contractor is someone who offers to do work). // Technically, it is either an org name or a combination of org and group names // because both work items and offers are owned by Time Tracker groups of users. +// 'label.how_to_pay' => 'How to pay', // Label for the "How to pay" field on offers, which allows contractors to specify + // how to pay them, for example: paypal email, check by mail to a specific address, etc. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index ddc87beb9..2db2a2713 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -280,6 +280,8 @@ // 'label.contractor' => 'Contractor', // Table column header for offers (contractor is someone who offers to do work). // Technically, it is either an org name or a combination of org and group names // because both work items and offers are owned by Time Tracker groups of users. +// 'label.how_to_pay' => 'How to pay', // Label for the "How to pay" field on offers, which allows contractors to specify + // how to pay them, for example: paypal email, check by mail to a specific address, etc. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index 2ec381e53..63c6623b1 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -284,6 +284,8 @@ // 'label.contractor' => 'Contractor', // Table column header for offers (contractor is someone who offers to do work). // Technically, it is either an org name or a combination of org and group names // because both work items and offers are owned by Time Tracker groups of users. +// 'label.how_to_pay' => 'How to pay', // Label for the "How to pay" field on offers, which allows contractors to specify + // how to pay them, for example: paypal email, check by mail to a specific address, etc. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index e8bb43197..08376bed7 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -281,6 +281,8 @@ // 'label.contractor' => 'Contractor', // Table column header for offers (contractor is someone who offers to do work). // Technically, it is either an org name or a combination of org and group names // because both work items and offers are owned by Time Tracker groups of users. +// 'label.how_to_pay' => 'How to pay', // Label for the "How to pay" field on offers, which allows contractors to specify + // how to pay them, for example: paypal email, check by mail to a specific address, etc. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index 5212a81cf..8eb67f053 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -304,6 +304,8 @@ // 'label.contractor' => 'Contractor', // Table column header for offers (contractor is someone who offers to do work). // Technically, it is either an org name or a combination of org and group names // because both work items and offers are owned by Time Tracker groups of users. +// 'label.how_to_pay' => 'How to pay', // Label for the "How to pay" field on offers, which allows contractors to specify + // how to pay them, for example: paypal email, check by mail to a specific address, etc. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index 70612f20c..090945d7b 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -289,6 +289,8 @@ // 'label.contractor' => 'Contractor', // Table column header for offers (contractor is someone who offers to do work). // Technically, it is either an org name or a combination of org and group names // because both work items and offers are owned by Time Tracker groups of users. +// 'label.how_to_pay' => 'How to pay', // Label for the "How to pay" field on offers, which allows contractors to specify + // how to pay them, for example: paypal email, check by mail to a specific address, etc. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index 080802a79..81e300507 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -295,6 +295,8 @@ // 'label.contractor' => 'Contractor', // Table column header for offers (contractor is someone who offers to do work). // Technically, it is either an org name or a combination of org and group names // because both work items and offers are owned by Time Tracker groups of users. +// 'label.how_to_pay' => 'How to pay', // Label for the "How to pay" field on offers, which allows contractors to specify + // how to pay them, for example: paypal email, check by mail to a specific address, etc. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index d2d613624..1cd0d9a45 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.19.10.5096 | Copyright © Anuko | +  Anuko Time Tracker 1.19.10.5097 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/work.tpl b/WEB-INF/templates/work.tpl index 51632578e..96f891fc9 100644 --- a/WEB-INF/templates/work.tpl +++ b/WEB-INF/templates/work.tpl @@ -11,6 +11,7 @@
{$i18n.label.work} {$i18n.label.description}{$i18n.label.client} {$i18n.label.budget}
{$work_item.subject|escape} {$work_item.description|escape}{$work_item.group_name|escape} {$work_item.currency} {$work_item.amount} {$i18n.label.edit} {$i18n.label.delete}
{$i18n.label.work} {$i18n.label.description}{$i18n.label.client} {$i18n.label.budget}
{$work_item.subject|escape} {$work_item.description|escape}{$work_item.group_name|escape} {$work_item.currency} {$work_item.amount}
- + + + + diff --git a/WEB-INF/templates/offer_edit.tpl b/WEB-INF/templates/offer_edit.tpl index 2494ae9ad..b860341fa 100644 --- a/WEB-INF/templates/offer_edit.tpl +++ b/WEB-INF/templates/offer_edit.tpl @@ -23,6 +23,10 @@ + + + + diff --git a/offer_add.php b/offer_add.php index 87a35f9aa..a61f6b658 100644 --- a/offer_add.php +++ b/offer_add.php @@ -47,6 +47,7 @@ $cl_details = trim($request->getParameter('details')); $cl_currency = $request->getParameter('currency'); $cl_budget = $request->getParameter('budget'); + $cl_payment_info = $request->getParameter('payment_info'); } $form = new Form('offerForm'); @@ -57,6 +58,7 @@ $currencies = ttWorkHelper::getCurrencies(); $form->addInput(array('type'=>'combobox','name'=>'currency','data'=>$currencies,'value'=>$cl_currency)); $form->addInput(array('type'=>'floatfield','maxlength'=>'10','name'=>'budget','format'=>'.2','value'=>$cl_budget)); +$form->addInput(array('type'=>'textarea','name'=>'payment_info','style'=>'width: 250px; height: 40px;vertical-align: middle','value'=>$cl_payment_info)); $form->addInput(array('type'=>'submit','name'=>'btn_add','value'=>$i18n->get('button.add'))); if ($request->isPost()) { @@ -65,6 +67,7 @@ if (!ttValidString($cl_description, true)) $err->add($i18n->get('error.field'), $i18n->get('label.description')); if (!ttValidString($cl_details, true)) $err->add($i18n->get('error.field'), $i18n->get('label.details')); if (!ttValidString($cl_budget)) $err->add($i18n->get('error.field'), $i18n->get('label.budget')); + if (!ttValidString($cl_payment_info)) $err->add($i18n->get('error.field'), $i18n->get('label.how_to_pay')); // Ensure user email exists (required for workflow). if (!$user->getEmail()) $err->add($i18n->get('error.no_email')); @@ -75,7 +78,8 @@ 'descr_short' => $cl_description, 'descr_long' => $cl_details, 'currency' => $currencies[$cl_currency], - 'amount' => $cl_budget); + 'amount' => $cl_budget, + 'payment_info' => $cl_payment_info); if ($workHelper->putOffer($fields)) { header('Location: work.php'); exit(); diff --git a/offer_edit.php b/offer_edit.php index b2e337904..abdb195d5 100644 --- a/offer_edit.php +++ b/offer_edit.php @@ -56,6 +56,7 @@ $cl_details = trim($request->getParameter('details')); $cl_currency = $request->getParameter('currency'); $cl_budget = $request->getParameter('budget'); + $cl_payment_info = $request->getParameter('payment_info'); } else { $cl_name = $offer['subject']; $cl_description = $offer['descr_short']; @@ -63,6 +64,7 @@ $currency = $offer['currency']; $cl_currency = array_search($currency, $currencies); $cl_budget = $offer['amount']; + $cl_payment_info = $offer['payment_info']; } $form = new Form('offerForm'); @@ -72,6 +74,7 @@ $form->addInput(array('type'=>'textarea','name'=>'details','style'=>'width: 250px; height: 80px;','value'=>$cl_details)); $form->addInput(array('type'=>'combobox','name'=>'currency','data'=>$currencies,'value'=>$cl_currency)); $form->addInput(array('type'=>'floatfield','maxlength'=>'10','name'=>'budget','format'=>'.2','value'=>$cl_budget)); +$form->addInput(array('type'=>'textarea','name'=>'payment_info','style'=>'width: 250px; height: 40px;vertical-align: middle','value'=>$cl_payment_info)); $form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); if ($request->isPost()) { @@ -80,6 +83,7 @@ if (!ttValidString($cl_description, true)) $err->add($i18n->get('error.field'), $i18n->get('label.description')); if (!ttValidString($cl_details, true)) $err->add($i18n->get('error.field'), $i18n->get('label.details')); if (!ttValidString($cl_budget)) $err->add($i18n->get('error.field'), $i18n->get('label.budget')); + if (!ttValidString($cl_payment_info)) $err->add($i18n->get('error.field'), $i18n->get('label.how_to_pay')); // Ensure user email exists (required for workflow). if (!$user->getEmail()) $err->add($i18n->get('error.no_email')); @@ -92,7 +96,8 @@ 'descr_short' => $cl_description, 'descr_long' => $cl_details, 'currency' => $currencies[$cl_currency], - 'amount' => $cl_budget); + 'amount' => $cl_budget, + 'payment_info' => $cl_payment_info); if ($workHelper->updateOffer($fields)) { header('Location: work.php'); exit(); From 97f52acc6ce9b33c0d340ee75140470aa823cc9c Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 21 Sep 2019 16:54:29 +0000 Subject: [PATCH 093/877] Added a what_is_it link for the budget field on work items for Work plugin. --- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/work_add.tpl | 2 +- WEB-INF/templates/work_edit.tpl | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 1cd0d9a45..43352aa3f 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.19.10.5097 | Copyright © Anuko | +  Anuko Time Tracker 1.19.10.5098 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/offer_add.tpl b/WEB-INF/templates/offer_add.tpl index 764ab924f..292a2a7bb 100644 --- a/WEB-INF/templates/offer_add.tpl +++ b/WEB-INF/templates/offer_add.tpl @@ -29,6 +29,10 @@ {$i18n.label.budget} (*): {$forms.offerForm.budget.control}
{$i18n.label.how_to_pay} (*):{$forms.offerForm.payment_info.control} {$i18n.label.what_is_it}
{$i18n.label.required_fields}{$i18n.label.budget} (*): {$forms.offerForm.budget.control}
{$i18n.label.how_to_pay} (*):{$forms.offerForm.payment_info.control} {$i18n.label.what_is_it}
{$i18n.label.required_fields}
- - + diff --git a/WEB-INF/templates/work_edit.tpl b/WEB-INF/templates/work_edit.tpl index 76bb42c1a..a5cb6e6b5 100644 --- a/WEB-INF/templates/work_edit.tpl +++ b/WEB-INF/templates/work_edit.tpl @@ -27,7 +27,7 @@ - + From 4a29c9d86ebe143f12f4686f574e8c36cf837a59 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 21 Sep 2019 17:00:09 +0000 Subject: [PATCH 094/877] Fixed a budget explaining link, also added them on the offer pages. --- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/offer_add.tpl | 2 +- WEB-INF/templates/offer_edit.tpl | 2 +- WEB-INF/templates/work_edit.tpl | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 43352aa3f..2a4aa0e54 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.19.10.5098 | Copyright © Anuko | +  Anuko Time Tracker 1.19.10.5099 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/work_add.tpl b/WEB-INF/templates/work_add.tpl index 13bb385ad..fd7beea40 100644 --- a/WEB-INF/templates/work_add.tpl +++ b/WEB-INF/templates/work_add.tpl @@ -27,7 +27,7 @@
{$i18n.label.budget} (*):{$forms.workForm.budget.control}{$forms.workForm.budget.control} {$i18n.label.what_is_it}
{$i18n.label.budget} (*):{$forms.workForm.budget.control}{$forms.workForm.budget.control} {$i18n.label.what_is_it}
- - + diff --git a/WEB-INF/templates/offer_edit.tpl b/WEB-INF/templates/offer_edit.tpl index b860341fa..fb406d1b0 100644 --- a/WEB-INF/templates/offer_edit.tpl +++ b/WEB-INF/templates/offer_edit.tpl @@ -21,7 +21,7 @@ - + diff --git a/WEB-INF/templates/work_edit.tpl b/WEB-INF/templates/work_edit.tpl index a5cb6e6b5..9aaaa85f7 100644 --- a/WEB-INF/templates/work_edit.tpl +++ b/WEB-INF/templates/work_edit.tpl @@ -27,7 +27,7 @@ - + From 2246dfb5be7f29bb2593d306c3bdbf459363bc19 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 22 Sep 2019 17:41:34 +0000 Subject: [PATCH 095/877] Work in progress on admin pages for Remote Work plugin. --- WEB-INF/lib/ttAdminWorkHelper.class.php | 192 ++++++++++++++++++++++++ WEB-INF/lib/ttWorkHelper.class.php | 1 + WEB-INF/resources/ca.lang.php | 1 + WEB-INF/resources/cs.lang.php | 1 + WEB-INF/resources/da.lang.php | 1 + WEB-INF/resources/de.lang.php | 1 + WEB-INF/resources/en.lang.php | 1 + WEB-INF/resources/es.lang.php | 1 + WEB-INF/resources/et.lang.php | 1 + WEB-INF/resources/fa.lang.php | 1 + WEB-INF/resources/fi.lang.php | 1 + WEB-INF/resources/fr.lang.php | 1 + WEB-INF/resources/gr.lang.php | 1 + WEB-INF/resources/he.lang.php | 1 + WEB-INF/resources/hu.lang.php | 1 + WEB-INF/resources/it.lang.php | 1 + WEB-INF/resources/ja.lang.php | 1 + WEB-INF/resources/ko.lang.php | 1 + WEB-INF/resources/nl.lang.php | 2 + WEB-INF/resources/no.lang.php | 1 + WEB-INF/resources/pl.lang.php | 1 + WEB-INF/resources/pt-br.lang.php | 1 + WEB-INF/resources/pt.lang.php | 1 + WEB-INF/resources/ro.lang.php | 1 + WEB-INF/resources/ru.lang.php | 1 + WEB-INF/resources/sk.lang.php | 1 + WEB-INF/resources/sl.lang.php | 1 + WEB-INF/resources/sr.lang.php | 1 + WEB-INF/resources/sv.lang.php | 1 + WEB-INF/resources/tr.lang.php | 1 + WEB-INF/resources/zh-cn.lang.php | 1 + WEB-INF/resources/zh-tw.lang.php | 1 + WEB-INF/templates/admin_work.tpl | 130 ++++++++++++++++ WEB-INF/templates/header.tpl | 3 + admin_work.php | 46 ++++++ 35 files changed, 403 insertions(+) create mode 100644 WEB-INF/lib/ttAdminWorkHelper.class.php create mode 100644 WEB-INF/templates/admin_work.tpl create mode 100644 admin_work.php diff --git a/WEB-INF/lib/ttAdminWorkHelper.class.php b/WEB-INF/lib/ttAdminWorkHelper.class.php new file mode 100644 index 000000000..2e71b8b20 --- /dev/null +++ b/WEB-INF/lib/ttAdminWorkHelper.class.php @@ -0,0 +1,192 @@ +errors = &$errors; + + $this->remote_work_uri = defined('REMOTE_WORK_URI') ? REMOTE_WORK_URI : "https://www.anuko.com/work/"; + $this->register_uri = $this->remote_work_uri.'register'; + $this->get_work_uri = $this->remote_work_uri.'admin_getwork'; + $this->update_work_uri = $this->remote_work_uri.'admin_updatework'; + $this->get_offer_uri = $this->remote_work_uri.'admin_getoffer'; + $this->update_offer_uri = $this->remote_work_uri.'admin_updateoffer'; + $this->get_pending_work_uri = $this->remote_work_uri.'admin_getpendingwork'; + $this->get_pending_offers_uri = $this->remote_work_uri.'admin_getpendingoffers'; + $this->checkSiteRegistration(); + } + + // checkSiteRegistration - obtains site id and key from local database. + // If not found, it tries to register with remote work server. + function checkSiteRegistration() { + global $i18n; + global $user; + $mdb2 = getConnection(); + + // Obtain site id. + $sql = "select param_value as id from tt_site_config where param_name = 'worksite_id'"; + $res = $mdb2->query($sql); + $val = $res->fetchRow(); + if (!$val) { + // No site id found, need to register. + $fields = array('lang' => urlencode($user->lang), + 'name' => urlencode('time tracker'), + 'origin' => urlencode('time tracker source')); + + // Urlify the data for the POST. + foreach($fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; } + $fields_string = rtrim($fields_string, '&'); + + // Open connection. + $ch = curl_init(); + + // Set the url, number of POST vars, POST data. + curl_setopt($ch, CURLOPT_URL, $this->register_uri); + curl_setopt($ch, CURLOPT_POST, true); + curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + + // Execute a post request. + $result = curl_exec($ch); + + // Close connection. + curl_close($ch); + + if (!$result) { + $this->errors->add($i18n->get('error.remote_work')); + return false; + } + + $result_array = json_decode($result, true); + + // Check for errors. + $call_status = $result_array['call_status']; + if (!$call_status) { + $this->errors->add($i18n->get('error.remote_work')); + return false; + } + if ($call_status['code'] != TT_CURL_SUCCESS) { + $this->errors->add($call_status['error']); + return false; + } + + $reg_status = $result_array['reg_status']; // Registration status. + if ($reg_status['site_id'] && $reg_status['site_key']) { + $this->site_id = $reg_status['site_id']; + $this->site_key = $reg_status['site_key']; + + // Registration successful. Store id and key locally for future use. + $sql = "insert into tt_site_config values('worksite_id', $this->site_id, now(), null)"; + $mdb2->exec($sql); + $sql = "insert into tt_site_config values('worksite_key', ".$mdb2->quote($this->site_key).", now(), null)"; + $mdb2->exec($sql); + } else { + $this->errors->add($i18n->get('error.remote_work')); + } + } else { + // Site id found. + $this->site_id = $val['id']; + + // Obtain site key. + $sql = "select param_value as site_key from tt_site_config where param_name = 'worksite_key'"; + $res = $mdb2->query($sql); + $val = $res->fetchRow(); + $this->site_key = $val['site_key']; + } + } + + // getPendingWork - obtains a list of work items pending approval. + function getPendingWork() { + global $i18n; + global $user; + $mdb2 = getConnection(); + + $curl_fields = array('lang' => urlencode($user->lang), + 'site_id' => urlencode($this->site_id), + 'site_key' => urlencode($this->site_key), + 'user_id' => urlencode($user->id) + ); + + // url-ify the data for the POST. + foreach($curl_fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; } + $fields_string = rtrim($fields_string, '&'); + + // Open connection. + $ch = curl_init(); + + // Set the url, number of POST vars, POST data. + curl_setopt($ch, CURLOPT_URL, $this->get_pending_work_uri); + curl_setopt($ch, CURLOPT_POST, true); + curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + + // Execute a post request. + $result = curl_exec($ch); + + // Close connection. + curl_close($ch); + + if (!$result) { + $this->errors->add($i18n->get('error.remote_work')); + return false; + } + + $result_array = json_decode($result, true); + + // Check for errors. + $call_status = $result_array['call_status']; + if (!$call_status) { + $this->errors->add($i18n->get('error.remote_work')); + return false; + } + if ($call_status['code'] != TT_CURL_SUCCESS) { + $this->errors->add($call_status['error']); + return false; + } + + $pending_work = $result_array['pending_work']; + return $pending_work; + } +} diff --git a/WEB-INF/lib/ttWorkHelper.class.php b/WEB-INF/lib/ttWorkHelper.class.php index fdf80cab7..8eee2da0f 100644 --- a/WEB-INF/lib/ttWorkHelper.class.php +++ b/WEB-INF/lib/ttWorkHelper.class.php @@ -47,6 +47,7 @@ class ttWorkHelper { var $get_available_offers_uri = null; // URI to get available offers. var $delete_offer_uri = null; // URI to delete offer. var $delete_offers_uri = null; // URI to delete multiple offers. + var $update_offer_uri = null; // URI to update offer. var $site_id = null; // Site id for remote work server. var $site_key = null; // Site key for remote work server. diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index ef585b672..524752eff 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -414,6 +414,7 @@ // 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. // 'title.available_work' => 'Available Work', // Available work items from other organizations. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. +// 'title.pending_work' => 'Pending Work', // Work items pending moderator approval. // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index d493145a6..50e5d04fa 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -424,6 +424,7 @@ // 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. // 'title.available_work' => 'Available Work', // Available work items from other organizations. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. +// 'title.pending_work' => 'Pending Work', // Work items pending moderator approval. // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index 8d92afc76..2bd598c69 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -396,6 +396,7 @@ // 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. // 'title.available_work' => 'Available Work', // Available work items from other organizations. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. +// 'title.pending_work' => 'Pending Work', // Work items pending moderator approval. // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index c38691866..9e1557c5b 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -382,6 +382,7 @@ // 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. // 'title.available_work' => 'Available Work', // Available work items from other organizations. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. +// 'title.pending_work' => 'Pending Work', // Work items pending moderator approval. // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index 71b33c740..e2c45fc23 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -371,6 +371,7 @@ 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. 'title.available_work' => 'Available Work', // Available work items from other organizations. 'title.inactive_work' => 'Inactive Work', // Inactive work items for group. +'title.pending_work' => 'Pending Work', // Work items pending moderator approval. 'title.add_offer' => 'Adding Offer', 'title.edit_offer' => 'Editing Offer', 'title.delete_offer' => 'Deleting Offer', diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index 0955af863..9a2b0638e 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -413,6 +413,7 @@ // 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. // 'title.available_work' => 'Available Work', // Available work items from other organizations. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. +// 'title.pending_work' => 'Pending Work', // Work items pending moderator approval. // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index be0b4d60d..01ef4ef7a 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -404,6 +404,7 @@ // 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. // 'title.available_work' => 'Available Work', // Available work items from other organizations. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. +// 'title.pending_work' => 'Pending Work', // Work items pending moderator approval. // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index a1f25ce9c..2dbe6891a 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -405,6 +405,7 @@ // 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. // 'title.available_work' => 'Available Work', // Available work items from other organizations. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. +// 'title.pending_work' => 'Pending Work', // Work items pending moderator approval. // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index bed26efc2..e81d07c10 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -396,6 +396,7 @@ // 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. // 'title.available_work' => 'Available Work', // Available work items from other organizations. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. +// 'title.pending_work' => 'Pending Work', // Work items pending moderator approval. // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index 98deacf82..61a0ddecf 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -390,6 +390,7 @@ // 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. // 'title.available_work' => 'Available Work', // Available work items from other organizations. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. +// 'title.pending_work' => 'Pending Work', // Work items pending moderator approval. // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index 1c5197d63..04aa4f3b3 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -389,6 +389,7 @@ // 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. // 'title.available_work' => 'Available Work', // Available work items from other organizations. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. +// 'title.pending_work' => 'Pending Work', // Work items pending moderator approval. // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index d4306e1b2..284f8a863 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -413,6 +413,7 @@ // 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. // 'title.available_work' => 'Available Work', // Available work items from other organizations. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. +// 'title.pending_work' => 'Pending Work', // Work items pending moderator approval. // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index 1c41a48b4..de16d61c2 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -414,6 +414,7 @@ // 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. // 'title.available_work' => 'Available Work', // Available work items from other organizations. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. +// 'title.pending_work' => 'Pending Work', // Work items pending moderator approval. // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index 04a83aa2b..77da3cd23 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -399,6 +399,7 @@ // 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. // 'title.available_work' => 'Available Work', // Available work items from other organizations. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. +// 'title.pending_work' => 'Pending Work', // Work items pending moderator approval. // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index afcc53d39..3a27314f8 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -420,6 +420,7 @@ // 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. // 'title.available_work' => 'Available Work', // Available work items from other organizations. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. +// 'title.pending_work' => 'Pending Work', // Work items pending moderator approval. // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index bd30ed0de..289b60b37 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -421,6 +421,7 @@ // 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. // 'title.available_work' => 'Available Work', // Available work items from other organizations. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. +// 'title.pending_work' => 'Pending Work', // Work items pending moderator approval. // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 224ff08b3..0e34c82f0 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -374,6 +374,8 @@ 'title.active_work' => 'Actief werk', 'title.available_work' => 'Beschikbaar werk', 'title.inactive_work' => 'Inactief werk', +// TODO: translate the following. +// 'title.pending_work' => 'Pending Work', // Work items pending moderator approval. 'title.add_offer' => 'Aanbieding toevoegen', 'title.edit_offer' => 'Aanbieding bewerken', 'title.delete_offer' => 'Aanbieding verwijderen', diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index 2c0f03625..eaa5eb45f 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -417,6 +417,7 @@ // 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. // 'title.available_work' => 'Available Work', // Available work items from other organizations. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. +// 'title.pending_work' => 'Pending Work', // Work items pending moderator approval. // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index f8b0ebf5f..d9fd94e55 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -399,6 +399,7 @@ // 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. // 'title.available_work' => 'Available Work', // Available work items from other organizations. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. +// 'title.pending_work' => 'Pending Work', // Work items pending moderator approval. // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index af31f68c0..15ac573aa 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -394,6 +394,7 @@ // 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. // 'title.available_work' => 'Available Work', // Available work items from other organizations. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. +// 'title.pending_work' => 'Pending Work', // Work items pending moderator approval. // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index 7f7d7d17d..30e61902b 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -401,6 +401,7 @@ // 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. // 'title.available_work' => 'Available Work', // Available work items from other organizations. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. +// 'title.pending_work' => 'Pending Work', // Work items pending moderator approval. // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index 124a5b826..17dd1c1b1 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -419,6 +419,7 @@ // 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. // 'title.available_work' => 'Available Work', // Available work items from other organizations. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. +// 'title.pending_work' => 'Pending Work', // Work items pending moderator approval. // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index 5941310ee..ac2b73fa8 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -357,6 +357,7 @@ 'title.active_work' => 'Активная работа', 'title.available_work' => 'Имеющаяся работа', 'title.inactive_work' => 'Неактивная работа', +'title.pending_work' => 'Работа в ожидании', 'title.add_offer' => 'Добавление предложения', 'title.edit_offer' => 'Редактирование предложения', 'title.delete_offer' => 'Удаление предложения', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index 14ba25056..64f6a6803 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -403,6 +403,7 @@ // 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. // 'title.available_work' => 'Available Work', // Available work items from other organizations. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. +// 'title.pending_work' => 'Pending Work', // Work items pending moderator approval. // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index 2db2a2713..ce5ba8e76 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -394,6 +394,7 @@ // 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. // 'title.available_work' => 'Available Work', // Available work items from other organizations. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. +// 'title.pending_work' => 'Pending Work', // Work items pending moderator approval. // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index 63c6623b1..c9c7e3733 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -397,6 +397,7 @@ // 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. // 'title.available_work' => 'Available Work', // Available work items from other organizations. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. +// 'title.pending_work' => 'Pending Work', // Work items pending moderator approval. // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index 08376bed7..b2090a764 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -398,6 +398,7 @@ // 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. // 'title.available_work' => 'Available Work', // Available work items from other organizations. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. +// 'title.pending_work' => 'Pending Work', // Work items pending moderator approval. // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index 8eb67f053..96c2fa2a2 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -428,6 +428,7 @@ // 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. // 'title.available_work' => 'Available Work', // Available work items from other organizations. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. +// 'title.pending_work' => 'Pending Work', // Work items pending moderator approval. // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index 090945d7b..77d4cfef8 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -409,6 +409,7 @@ // 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. // 'title.available_work' => 'Available Work', // Available work items from other organizations. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. +// 'title.pending_work' => 'Pending Work', // Work items pending moderator approval. // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index 81e300507..27beb296b 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -414,6 +414,7 @@ // 'title.active_work' => 'Active Work', // Active work items this group outsources to other groups. // 'title.available_work' => 'Available Work', // Available work items from other organizations. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. +// 'title.pending_work' => 'Pending Work', // Work items pending moderator approval. // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', diff --git a/WEB-INF/templates/admin_work.tpl b/WEB-INF/templates/admin_work.tpl new file mode 100644 index 000000000..58d847454 --- /dev/null +++ b/WEB-INF/templates/admin_work.tpl @@ -0,0 +1,130 @@ + + +
 Anuko Time Tracker 1.19.10.5099 | Copyright © Anuko | +  Anuko Time Tracker 1.19.10.5100 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/offer_add.tpl b/WEB-INF/templates/offer_add.tpl index 292a2a7bb..da7e05574 100644 --- a/WEB-INF/templates/offer_add.tpl +++ b/WEB-INF/templates/offer_add.tpl @@ -27,7 +27,7 @@
{$i18n.label.budget} (*):{$forms.offerForm.budget.control}{$forms.offerForm.budget.control} {$i18n.label.what_is_it}
{$i18n.label.how_to_pay} (*):
{$i18n.label.budget} (*):{$forms.offerForm.budget.control}{$forms.offerForm.budget.control} {$i18n.label.what_is_it}
{$i18n.label.how_to_pay} (*):
{$i18n.label.budget} (*):{$forms.workForm.budget.control} {$i18n.label.what_is_it}{$forms.workForm.budget.control} {$i18n.label.what_is_it}
+ + + +
+{if $pending_work} + + + + + + + + + + + {foreach $pending_work as $work_item} + + + + + + + + + {/foreach} +
{$i18n.title.pending_work}
{$i18n.label.work}{$i18n.label.description}{$i18n.label.client}{$i18n.label.budget}
{$work_item.subject|escape}{$work_item.description|escape}{$work_item.group_name|escape} ({$work_item.site_id}.{$work_item.group_id}){$work_item.currency} {$work_item.amount}{$i18n.label.edit}{$i18n.label.delete}
+{/if} + + + +{if $available_work} + + + + + + + + + {foreach $available_work as $work_item} + + + + + + + + + {/foreach} +{/if} +
{$i18n.title.available_work}
{$i18n.label.work}{$i18n.label.description}{$i18n.label.client}{$i18n.label.budget}
{$work_item.subject|escape}{$work_item.description|escape}{$work_item.group_name|escape}{$work_item.currency} {$work_item.amount}
+ + + + + +

+
+
+ +{if $active_offers} + + + + + + + + + + + {foreach $active_offers as $offer} + + + + + + + + + {/foreach} +
{$i18n.title.active_offers}
{$i18n.label.offer}{$i18n.label.description}{$i18n.label.contractor}{$i18n.label.budget}
{$offer.subject|escape}{$offer.description|escape}{$offer.group_name|escape}{$offer.currency} {$offer.amount}{$i18n.label.edit}{$i18n.label.delete}
+ + + + + +

+
+
+{/if} + + + +{if $available_offers} + + + + + + + + + {foreach $available_offers as $offer} + + + + + + + + + {/foreach} +{/if} +
{$i18n.title.available_offers}
{$i18n.label.offer}{$i18n.label.description}{$i18n.label.contractor}{$i18n.label.budget}
{$offer.subject|escape}{$offer.description|escape}{$offer.group_name|escape}{$offer.currency} {$offer.amount}
+ + + + + +

+
+
+ +
diff --git a/WEB-INF/templates/header.tpl b/WEB-INF/templates/header.tpl index d9ceab91d..fa66c6190 100644 --- a/WEB-INF/templates/header.tpl +++ b/WEB-INF/templates/header.tpl @@ -73,6 +73,9 @@
  {$i18n.menu.groups} {$i18n.menu.options} + {if isTrue('REMOTE_WORK_DEBUG')} + {$i18n.label.work} + {/if}
diff --git a/admin_work.php b/admin_work.php new file mode 100644 index 000000000..dee7edc24 --- /dev/null +++ b/admin_work.php @@ -0,0 +1,46 @@ +getPendingWork(); + +$smarty->assign('pending_work', $pending_work); +$smarty->assign('title', $i18n->get('title.work')); +$smarty->assign('content_page_name', 'admin_work.tpl'); +$smarty->display('index.tpl'); From 2265fff018c4594a47167fd047f8870e2a3daee0 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 22 Sep 2019 18:05:46 +0000 Subject: [PATCH 096/877] Initial implementation of admin_work.php. --- WEB-INF/lib/ttAdminWorkHelper.class.php | 55 +++++++++++++++- WEB-INF/resources/ca.lang.php | 1 + WEB-INF/resources/cs.lang.php | 1 + WEB-INF/resources/da.lang.php | 1 + WEB-INF/resources/de.lang.php | 1 + WEB-INF/resources/en.lang.php | 1 + WEB-INF/resources/es.lang.php | 1 + WEB-INF/resources/et.lang.php | 1 + WEB-INF/resources/fa.lang.php | 1 + WEB-INF/resources/fi.lang.php | 1 + WEB-INF/resources/fr.lang.php | 1 + WEB-INF/resources/gr.lang.php | 1 + WEB-INF/resources/he.lang.php | 1 + WEB-INF/resources/hu.lang.php | 1 + WEB-INF/resources/it.lang.php | 1 + WEB-INF/resources/ja.lang.php | 1 + WEB-INF/resources/ko.lang.php | 1 + WEB-INF/resources/nl.lang.php | 2 + WEB-INF/resources/no.lang.php | 1 + WEB-INF/resources/pl.lang.php | 1 + WEB-INF/resources/pt-br.lang.php | 1 + WEB-INF/resources/pt.lang.php | 1 + WEB-INF/resources/ro.lang.php | 1 + WEB-INF/resources/ru.lang.php | 1 + WEB-INF/resources/sk.lang.php | 1 + WEB-INF/resources/sl.lang.php | 1 + WEB-INF/resources/sr.lang.php | 1 + WEB-INF/resources/sv.lang.php | 1 + WEB-INF/resources/tr.lang.php | 1 + WEB-INF/resources/zh-cn.lang.php | 1 + WEB-INF/resources/zh-tw.lang.php | 1 + WEB-INF/templates/admin_work.tpl | 88 +++---------------------- WEB-INF/templates/footer.tpl | 2 +- admin_work.php | 2 + 34 files changed, 96 insertions(+), 82 deletions(-) diff --git a/WEB-INF/lib/ttAdminWorkHelper.class.php b/WEB-INF/lib/ttAdminWorkHelper.class.php index 2e71b8b20..728354d4e 100644 --- a/WEB-INF/lib/ttAdminWorkHelper.class.php +++ b/WEB-INF/lib/ttAdminWorkHelper.class.php @@ -137,7 +137,60 @@ function checkSiteRegistration() { } } - // getPendingWork - obtains a list of work items pending approval. + // getPendingOffers - obtains a list of offers pending approval. + function getPendingOffers() { + global $i18n; + global $user; + $mdb2 = getConnection(); + + $curl_fields = array('lang' => urlencode($user->lang), + 'site_id' => urlencode($this->site_id), + 'site_key' => urlencode($this->site_key), + 'user_id' => urlencode($user->id) + ); + + // url-ify the data for the POST. + foreach($curl_fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; } + $fields_string = rtrim($fields_string, '&'); + + // Open connection. + $ch = curl_init(); + + // Set the url, number of POST vars, POST data. + curl_setopt($ch, CURLOPT_URL, $this->get_pending_offers_uri); + curl_setopt($ch, CURLOPT_POST, true); + curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + + // Execute a post request. + $result = curl_exec($ch); + + // Close connection. + curl_close($ch); + + if (!$result) { + $this->errors->add($i18n->get('error.remote_work')); + return false; + } + + $result_array = json_decode($result, true); + + // Check for errors. + $call_status = $result_array['call_status']; + if (!$call_status) { + $this->errors->add($i18n->get('error.remote_work')); + return false; + } + if ($call_status['code'] != TT_CURL_SUCCESS) { + $this->errors->add($call_status['error']); + return false; + } + + $pending_offers = $result_array['pending_offers']; + return $pending_offers; + } + + // getPendingWork - obtains a list of work items pending approval. function getPendingWork() { global $i18n; global $user; diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index 524752eff..3e38c19a2 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -421,6 +421,7 @@ // 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. // 'title.available_offers' => 'Available Offers', // Available offers from other organizations. // 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. +// 'title.pending_offers' => 'Pending Offers', // Offers pending moderator approval. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index 50e5d04fa..fb8b502d2 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -431,6 +431,7 @@ // 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. // 'title.available_offers' => 'Available Offers', // Available offers from other organizations. // 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. +// 'title.pending_offers' => 'Pending Offers', // Offers pending moderator approval. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index 2bd598c69..5b03bf338 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -403,6 +403,7 @@ // 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. // 'title.available_offers' => 'Available Offers', // Available offers from other organizations. // 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. +// 'title.pending_offers' => 'Pending Offers', // Offers pending moderator approval. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index 9e1557c5b..d47c19e9c 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -389,6 +389,7 @@ // 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. // 'title.available_offers' => 'Available Offers', // Available offers from other organizations. // 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. +// 'title.pending_offers' => 'Pending Offers', // Offers pending moderator approval. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index e2c45fc23..459b250b4 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -378,6 +378,7 @@ 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. 'title.available_offers' => 'Available Offers', // Available offers from other organizations. 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. +'title.pending_offers' => 'Pending Offers', // Offers pending moderator approval. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index 9a2b0638e..61cbaa337 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -420,6 +420,7 @@ // 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. // 'title.available_offers' => 'Available Offers', // Available offers from other organizations. // 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. +// 'title.pending_offers' => 'Pending Offers', // Offers pending moderator approval. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index 01ef4ef7a..5a199bf81 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -411,6 +411,7 @@ // 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. // 'title.available_offers' => 'Available Offers', // Available offers from other organizations. // 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. +// 'title.pending_offers' => 'Pending Offers', // Offers pending moderator approval. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index 2dbe6891a..79547fc89 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -412,6 +412,7 @@ // 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. // 'title.available_offers' => 'Available Offers', // Available offers from other organizations. // 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. +// 'title.pending_offers' => 'Pending Offers', // Offers pending moderator approval. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index e81d07c10..a1cdac1e9 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -403,6 +403,7 @@ // 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. // 'title.available_offers' => 'Available Offers', // Available offers from other organizations. // 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. +// 'title.pending_offers' => 'Pending Offers', // Offers pending moderator approval. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index 61a0ddecf..9228c6834 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -397,6 +397,7 @@ // 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. // 'title.available_offers' => 'Available Offers', // Available offers from other organizations. // 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. +// 'title.pending_offers' => 'Pending Offers', // Offers pending moderator approval. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index 04aa4f3b3..300dc3c22 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -396,6 +396,7 @@ // 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. // 'title.available_offers' => 'Available Offers', // Available offers from other organizations. // 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. +// 'title.pending_offers' => 'Pending Offers', // Offers pending moderator approval. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index 284f8a863..6d593c9dc 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -420,6 +420,7 @@ // 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. // 'title.available_offers' => 'Available Offers', // Available offers from other organizations. // 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. +// 'title.pending_offers' => 'Pending Offers', // Offers pending moderator approval. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index de16d61c2..a8bbe719d 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -421,6 +421,7 @@ // 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. // 'title.available_offers' => 'Available Offers', // Available offers from other organizations. // 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. +// 'title.pending_offers' => 'Pending Offers', // Offers pending moderator approval. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index 77da3cd23..f439ba700 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -406,6 +406,7 @@ // 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. // 'title.available_offers' => 'Available Offers', // Available offers from other organizations. // 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. +// 'title.pending_offers' => 'Pending Offers', // Offers pending moderator approval. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index 3a27314f8..5dc4d757d 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -427,6 +427,7 @@ // 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. // 'title.available_offers' => 'Available Offers', // Available offers from other organizations. // 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. +// 'title.pending_offers' => 'Pending Offers', // Offers pending moderator approval. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index 289b60b37..a9c2abaed 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -428,6 +428,7 @@ // 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. // 'title.available_offers' => 'Available Offers', // Available offers from other organizations. // 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. +// 'title.pending_offers' => 'Pending Offers', // Offers pending moderator approval. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 0e34c82f0..18bc14052 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -382,6 +382,8 @@ 'title.active_offers' => 'Actieve aanbiedingen', 'title.available_offers' => 'Beschikbare aanbiedingen', 'title.inactive_offers' => 'Inactieve aanbiedingen', +// TODO: translate the following. +// 'title.pending_offers' => 'Pending Offers', // Offers pending moderator approval. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index eaa5eb45f..2b02c84e4 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -424,6 +424,7 @@ // 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. // 'title.available_offers' => 'Available Offers', // Available offers from other organizations. // 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. +// 'title.pending_offers' => 'Pending Offers', // Offers pending moderator approval. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index d9fd94e55..ef438e984 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -406,6 +406,7 @@ // 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. // 'title.available_offers' => 'Available Offers', // Available offers from other organizations. // 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. +// 'title.pending_offers' => 'Pending Offers', // Offers pending moderator approval. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index 15ac573aa..08d92193c 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -401,6 +401,7 @@ // 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. // 'title.available_offers' => 'Available Offers', // Available offers from other organizations. // 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. +// 'title.pending_offers' => 'Pending Offers', // Offers pending moderator approval. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index 30e61902b..beafbf92d 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -408,6 +408,7 @@ // 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. // 'title.available_offers' => 'Available Offers', // Available offers from other organizations. // 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. +// 'title.pending_offers' => 'Pending Offers', // Offers pending moderator approval. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index 17dd1c1b1..98ccd4ae7 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -426,6 +426,7 @@ // 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. // 'title.available_offers' => 'Available Offers', // Available offers from other organizations. // 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. +// 'title.pending_offers' => 'Pending Offers', // Offers pending moderator approval. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index ac2b73fa8..3b0fafbc9 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -364,6 +364,7 @@ 'title.active_offers' => 'Активные предложения', 'title.available_offers' => 'Имеющиеся предложения', 'title.inactive_offers' => 'Неактивные предложения', +'title.pending_offers' => 'Предложения в ожидании', // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index 64f6a6803..3f2955f3c 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -410,6 +410,7 @@ // 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. // 'title.available_offers' => 'Available Offers', // Available offers from other organizations. // 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. +// 'title.pending_offers' => 'Pending Offers', // Offers pending moderator approval. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index ce5ba8e76..1ff3fe338 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -401,6 +401,7 @@ // 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. // 'title.available_offers' => 'Available Offers', // Available offers from other organizations. // 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. +// 'title.pending_offers' => 'Pending Offers', // Offers pending moderator approval. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index c9c7e3733..b3c2eb573 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -404,6 +404,7 @@ // 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. // 'title.available_offers' => 'Available Offers', // Available offers from other organizations. // 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. +// 'title.pending_offers' => 'Pending Offers', // Offers pending moderator approval. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index b2090a764..c95d42326 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -405,6 +405,7 @@ // 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. // 'title.available_offers' => 'Available Offers', // Available offers from other organizations. // 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. +// 'title.pending_offers' => 'Pending Offers', // Offers pending moderator approval. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index 96c2fa2a2..e8aef3b47 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -435,6 +435,7 @@ // 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. // 'title.available_offers' => 'Available Offers', // Available offers from other organizations. // 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. +// 'title.pending_offers' => 'Pending Offers', // Offers pending moderator approval. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index 77d4cfef8..e401aded7 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -416,6 +416,7 @@ // 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. // 'title.available_offers' => 'Available Offers', // Available offers from other organizations. // 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. +// 'title.pending_offers' => 'Pending Offers', // Offers pending moderator approval. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index 27beb296b..7aa36b577 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -421,6 +421,7 @@ // 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. // 'title.available_offers' => 'Available Offers', // Available offers from other organizations. // 'title.inactive_offers' => 'Inactive Offers', // Inactive offers for group. +// 'title.pending_offers' => 'Pending Offers', // Offers pending moderator approval. // Section for common strings inside combo boxes on forms. Strings shared between forms shall be placed here. // Strings that are used in a single form must go to the specific form section. diff --git a/WEB-INF/templates/admin_work.tpl b/WEB-INF/templates/admin_work.tpl index 58d847454..569b09ace 100644 --- a/WEB-INF/templates/admin_work.tpl +++ b/WEB-INF/templates/admin_work.tpl @@ -21,7 +21,7 @@
{$work_item.subject|escape} {$work_item.description|escape} {$work_item.group_name|escape} ({$work_item.site_id}.{$work_item.group_id}){$work_item.currency} {$work_item.amount}{$work_item.currency} {$work_item.amount} {$i18n.label.edit} {$i18n.label.delete}
{/if} +{if $pending_offers} - -{if $available_work} - - - - - - - - - {foreach $available_work as $work_item} - - - - - - - - - {/foreach} -{/if} -
{$i18n.title.available_work}
{$i18n.label.work}{$i18n.label.description}{$i18n.label.client}{$i18n.label.budget}
{$work_item.subject|escape}{$work_item.description|escape}{$work_item.group_name|escape}{$work_item.currency} {$work_item.amount}
- - - - - -

-
-
- -{if $active_offers} - - + @@ -72,59 +40,19 @@ - {foreach $active_offers as $offer} + {foreach $pending_offers as $offer} - - - - + + + + {/foreach}
{$i18n.title.active_offers}
{$i18n.title.pending_offers}
{$i18n.label.offer} {$i18n.label.description}
{$offer.subject|escape} {$offer.description|escape}{$offer.group_name|escape}{$offer.currency} {$offer.amount}{$i18n.label.edit}{$i18n.label.delete}{$offer.group_name|escape} ({$work_item.site_id}.{$work_item.group_id}){$offer.currency} {$offer.amount}{$i18n.label.edit}{$i18n.label.delete}
- - - - - -

-
-
{/if} - - -{if $available_offers} - - - - - - - - - {foreach $available_offers as $offer} - - - - - - - - - {/foreach} -{/if} -
{$i18n.title.available_offers}
{$i18n.label.offer}{$i18n.label.description}{$i18n.label.contractor}{$i18n.label.budget}
{$offer.subject|escape}{$offer.description|escape}{$offer.group_name|escape}{$offer.currency} {$offer.amount}
- - - - - -

-
-
-
diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 2a4aa0e54..a803745a4 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.19.10.5100 | Copyright © Anuko | +  Anuko Time Tracker 1.19.10.5101 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/admin_work.php b/admin_work.php index dee7edc24..b1723912d 100644 --- a/admin_work.php +++ b/admin_work.php @@ -39,8 +39,10 @@ $adminWorkHelper = new ttAdminWorkHelper($err); $pending_work = $adminWorkHelper->getPendingWork(); +$pending_offers = $adminWorkHelper->getPendingOffers(); $smarty->assign('pending_work', $pending_work); +$smarty->assign('pending_offers', $pending_offers); $smarty->assign('title', $i18n->get('title.work')); $smarty->assign('content_page_name', 'admin_work.tpl'); $smarty->display('index.tpl'); From 0a3094c24226bc2e2452070d48c1f20cb8f15288 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 22 Sep 2019 20:01:12 +0000 Subject: [PATCH 097/877] Implemented admin_work_delete.php. --- WEB-INF/lib/ttAdminWorkHelper.class.php | 113 ++++++++++++++++++++++++ WEB-INF/templates/footer.tpl | 2 +- admin_work_delete.php | 71 +++++++++++++++ 3 files changed, 185 insertions(+), 1 deletion(-) create mode 100644 admin_work_delete.php diff --git a/WEB-INF/lib/ttAdminWorkHelper.class.php b/WEB-INF/lib/ttAdminWorkHelper.class.php index 728354d4e..cded106a1 100644 --- a/WEB-INF/lib/ttAdminWorkHelper.class.php +++ b/WEB-INF/lib/ttAdminWorkHelper.class.php @@ -36,8 +36,10 @@ class ttAdminWorkHelper { var $register_uri = null; // URI to register with remote work server. var $get_work_uri = null; // URI to get work details. var $update_work_uri = null; // URI to update work. + var $delete_work_uri = null; // URI to delete work. var $get_offer_uri = null; // URI to get offer details. var $update_offer_uri = null; // URI to update offer. + var $delete_offer_uri = null; // URI to delete offer. var $get_pending_work_uri = null; // URI to get work pending approval. var $get_pending_offers_uri = null; // URI to get offers pending approval. var $site_id = null; // Site id for remote work server. @@ -51,8 +53,10 @@ function __construct(&$errors) { $this->register_uri = $this->remote_work_uri.'register'; $this->get_work_uri = $this->remote_work_uri.'admin_getwork'; $this->update_work_uri = $this->remote_work_uri.'admin_updatework'; + $this->delete_work_uri = $this->remote_work_uri.'admin_deletework'; $this->get_offer_uri = $this->remote_work_uri.'admin_getoffer'; $this->update_offer_uri = $this->remote_work_uri.'admin_updateoffer'; + $this->delete_offer_uri = $this->remote_work_uri.'admin_deleteoffer'; $this->get_pending_work_uri = $this->remote_work_uri.'admin_getpendingwork'; $this->get_pending_offers_uri = $this->remote_work_uri.'admin_getpendingoffers'; $this->checkSiteRegistration(); @@ -242,4 +246,113 @@ function getPendingWork() { $pending_work = $result_array['pending_work']; return $pending_work; } + + // getWork - gets work item details from remote work server. + function getWork($work_id) { + global $i18n; + global $user; + $mdb2 = getConnection(); + + $curl_fields = array('lang' => urlencode($user->lang), + 'site_id' => urlencode($this->site_id), + 'site_key' => urlencode($this->site_key), + 'user_id' => urlencode($user->id), + 'work_id' => urlencode($work_id)); + + // url-ify the data for the POST. + foreach($curl_fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; } + $fields_string = rtrim($fields_string, '&'); + + // Open connection. + $ch = curl_init(); + + // Set the url, number of POST vars, POST data. + curl_setopt($ch, CURLOPT_URL, $this->get_work_uri); + curl_setopt($ch, CURLOPT_POST, true); + curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + + // Execute a post request. + $result = curl_exec($ch); + + // Close connection. + curl_close($ch); + + if (!$result) { + $this->errors->add($i18n->get('error.remote_work')); + return false; + } + + $result_array = json_decode($result, true); + + // Check for errors. + $call_status = $result_array['call_status']; + if (!$call_status) { + $this->errors->add($i18n->get('error.remote_work')); + return false; + } + if ($call_status['code'] != TT_CURL_SUCCESS) { + $this->errors->add($call_status['error']); + return false; + } + + $work_item = $result_array['work_item']; + return $work_item; + } + + // deleteWork - deletes work item from remote work server. + function deleteWork($work_id) { + global $i18n; + global $user; + $mdb2 = getConnection(); + + $curl_fields = array('lang' => urlencode($user->lang), + 'site_id' => urlencode($this->site_id), + 'site_key' => urlencode($this->site_key), + 'user_id' => urlencode($user->id), + 'work_id' => urlencode($work_id), + 'modified_ip' => urlencode($_SERVER['REMOTE_ADDR']), + 'modified_by' => urlencode($user->getUser()), + 'modified_by_name' => urlencode(base64_encode($user->getName())), + 'modified_by_email' => urlencode(base64_encode($user->getEmail()))); + + // url-ify the data for the POST. + foreach($curl_fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; } + $fields_string = rtrim($fields_string, '&'); + + // Open connection. + $ch = curl_init(); + + // Set the url, number of POST vars, POST data. + curl_setopt($ch, CURLOPT_URL, $this->delete_work_uri); + curl_setopt($ch, CURLOPT_POST, true); + curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + + // Execute a post request. + $result = curl_exec($ch); + + // Close connection. + curl_close($ch); + + if (!$result) { + $this->errors->add($i18n->get('error.remote_work')); + return false; + } + + $result_array = json_decode($result, true); + + // Check for errors. + $call_status = $result_array['call_status']; + if (!$call_status) { + $this->errors->add($i18n->get('error.remote_work')); + return false; + } + if ($call_status['code'] != TT_CURL_SUCCESS) { + $this->errors->add($call_status['error']); + return false; + } + + return true; + } } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index a803745a4..c08a66a25 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- - + diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index c08a66a25..ef72a489e 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.19.10.5101 | Copyright © Anuko | +  Anuko Time Tracker 1.19.10.5102 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/admin_work_delete.php b/admin_work_delete.php new file mode 100644 index 000000000..d64b9fb9c --- /dev/null +++ b/admin_work_delete.php @@ -0,0 +1,71 @@ +getParameter('id'); +$adminWorkHelper = new ttAdminWorkHelper($err); +$work_item = $adminWorkHelper->getWork($cl_work_id); +if (!$work_item) { + header('Location: access_denied.php'); + exit(); +} +// End of access checks. + +$work_to_delete = $work_item['subject']; + +$form = new Form('workDeleteForm'); +$form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_work_id)); +$form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->get('label.delete'))); +$form->addInput(array('type'=>'submit','name'=>'btn_cancel','value'=>$i18n->get('button.cancel'))); + +if ($request->isPost()) { + if ($request->getParameter('btn_delete')) { + if ($adminWorkHelper->deleteWork($cl_work_id)) { + header('Location: admin_work.php'); + exit(); + } + } elseif ($request->getParameter('btn_cancel')) { + header('Location: admin_work.php'); + exit(); + } +} // isPost + +$smarty->assign('work_to_delete', $work_to_delete); +$smarty->assign('forms', array($form->getName()=>$form->toArray())); +$smarty->assign('onload', 'onLoad="document.workDeleteForm.btn_cancel.focus()"'); +$smarty->assign('title', $i18n->get('title.delete_work')); +$smarty->assign('content_page_name', 'work_delete.tpl'); +$smarty->display('index.tpl'); From a759105d9cd256d0212f9982e6aeb9addcb5fe77 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 22 Sep 2019 21:13:00 +0000 Subject: [PATCH 098/877] Implemented admin_offer_delete.php. --- WEB-INF/lib/ttAdminWorkHelper.class.php | 109 ++++++++++++++++++++++++ WEB-INF/templates/admin_work.tpl | 2 +- WEB-INF/templates/footer.tpl | 2 +- admin_offer_delete.php | 71 +++++++++++++++ 4 files changed, 182 insertions(+), 2 deletions(-) create mode 100644 admin_offer_delete.php diff --git a/WEB-INF/lib/ttAdminWorkHelper.class.php b/WEB-INF/lib/ttAdminWorkHelper.class.php index cded106a1..e28cb581b 100644 --- a/WEB-INF/lib/ttAdminWorkHelper.class.php +++ b/WEB-INF/lib/ttAdminWorkHelper.class.php @@ -355,4 +355,113 @@ function deleteWork($work_id) { return true; } + + // deleteOffer - deletes an offer from remote work server. + function deleteOffer($offer_id) { + global $i18n; + global $user; + $mdb2 = getConnection(); + + $curl_fields = array('lang' => urlencode($user->lang), + 'site_id' => urlencode($this->site_id), + 'site_key' => urlencode($this->site_key), + 'user_id' => urlencode($user->id), + 'offer_id' => urlencode($offer_id), + 'modified_ip' => urlencode($_SERVER['REMOTE_ADDR']), + 'modified_by' => urlencode($user->getUser()), + 'modified_by_name' => urlencode(base64_encode($user->getName())), + 'modified_by_email' => urlencode(base64_encode($user->getEmail()))); + + // url-ify the data for the POST. + foreach($curl_fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; } + $fields_string = rtrim($fields_string, '&'); + + // Open connection. + $ch = curl_init(); + + // Set the url, number of POST vars, POST data. + curl_setopt($ch, CURLOPT_URL, $this->delete_offer_uri); + curl_setopt($ch, CURLOPT_POST, true); + curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + + // Execute a post request. + $result = curl_exec($ch); + + // Close connection. + curl_close($ch); + + if (!$result) { + $this->errors->add($i18n->get('error.remote_work')); + return false; + } + + $result_array = json_decode($result, true); + + // Check for errors. + $call_status = $result_array['call_status']; + if (!$call_status) { + $this->errors->add($i18n->get('error.remote_work')); + return false; + } + if ($call_status['code'] != TT_CURL_SUCCESS) { + $this->errors->add($call_status['error']); + return false; + } + + return true; + } + + // getOffer - gets offer details from remote work server. + function getOffer($offer_id) { + global $i18n; + global $user; + $mdb2 = getConnection(); + + $curl_fields = array('lang' => urlencode($user->lang), + 'site_id' => urlencode($this->site_id), + 'site_key' => urlencode($this->site_key), + 'user_id' => urlencode($user->id), + 'offer_id' => urlencode($offer_id)); + + // url-ify the data for the POST. + foreach($curl_fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; } + $fields_string = rtrim($fields_string, '&'); + + // Open connection. + $ch = curl_init(); + + // Set the url, number of POST vars, POST data. + curl_setopt($ch, CURLOPT_URL, $this->get_offer_uri); + curl_setopt($ch, CURLOPT_POST, true); + curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + + // Execute a post request. + $result = curl_exec($ch); + + // Close connection. + curl_close($ch); + + if (!$result) { + $this->errors->add($i18n->get('error.remote_work')); + return false; + } + + $result_array = json_decode($result, true); + + // Check for errors. + $call_status = $result_array['call_status']; + if (!$call_status) { + $this->errors->add($i18n->get('error.remote_work')); + return false; + } + if ($call_status['code'] != TT_CURL_SUCCESS) { + $this->errors->add($call_status['error']); + return false; + } + + $offer = $result_array['offer']; + return $offer; + } } diff --git a/WEB-INF/templates/admin_work.tpl b/WEB-INF/templates/admin_work.tpl index 569b09ace..b96865887 100644 --- a/WEB-INF/templates/admin_work.tpl +++ b/WEB-INF/templates/admin_work.tpl @@ -44,7 +44,7 @@
{$offer.subject|escape} {$offer.description|escape}{$offer.group_name|escape} ({$work_item.site_id}.{$work_item.group_id}){$offer.group_name|escape} ({$offer.site_id}.{$offer.group_id}) {$offer.currency} {$offer.amount} {$i18n.label.edit} {$i18n.label.delete}
-
 Anuko Time Tracker 1.19.10.5102 | Copyright © Anuko | +  Anuko Time Tracker 1.19.10.5103 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/admin_offer_delete.php b/admin_offer_delete.php new file mode 100644 index 000000000..05e9b39b6 --- /dev/null +++ b/admin_offer_delete.php @@ -0,0 +1,71 @@ +getParameter('id'); +$adminWorkHelper = new ttAdminWorkHelper($err); +$offer = $adminWorkHelper->getOffer($cl_offer_id); +if (!$offer) { + header('Location: access_denied.php'); + exit(); +} +// End of access checks. + +$offer_to_delete = $offer['subject']; + +$form = new Form('offerDeleteForm'); +$form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_offer_id)); +$form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->get('label.delete'))); +$form->addInput(array('type'=>'submit','name'=>'btn_cancel','value'=>$i18n->get('button.cancel'))); + +if ($request->isPost()) { + if ($request->getParameter('btn_delete')) { + if ($adminWorkHelper->deleteOffer($cl_offer_id)) { + header('Location: admin_work.php'); + exit(); + } + } elseif ($request->getParameter('btn_cancel')) { + header('Location: admin_work.php'); + exit(); + } +} // isPost + +$smarty->assign('offer_to_delete', $offer_to_delete); +$smarty->assign('forms', array($form->getName()=>$form->toArray())); +$smarty->assign('onload', 'onLoad="document.offerDeleteForm.btn_cancel.focus()"'); +$smarty->assign('title', $i18n->get('title.delete_offer')); +$smarty->assign('content_page_name', 'offer_delete.tpl'); +$smarty->display('index.tpl'); From e73c59458fa2965b31e1c95057634d05391bd249 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 23 Sep 2019 13:30:06 +0000 Subject: [PATCH 099/877] Added a table divider div and admin_work.php for better presentation. --- WEB-INF/templates/admin_work.tpl | 2 ++ WEB-INF/templates/footer.tpl | 2 +- default.css | 5 ++--- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/WEB-INF/templates/admin_work.tpl b/WEB-INF/templates/admin_work.tpl index b96865887..ddbf5071e 100644 --- a/WEB-INF/templates/admin_work.tpl +++ b/WEB-INF/templates/admin_work.tpl @@ -29,6 +29,8 @@
{/if} +
+ {if $pending_offers} diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index ef72a489e..ed64b1d30 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
{$i18n.title.pending_offers}
- - + @@ -47,7 +47,7 @@ - + diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index ed64b1d30..00971ce14 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.19.10.5103 | Copyright © Anuko | +  Anuko Time Tracker 1.19.10.5104 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/default.css b/default.css index d744c66e7..cf448abcf 100644 --- a/default.css +++ b/default.css @@ -143,9 +143,8 @@ input[type=checkbox], label { .divider { background-color: #efefef; } -table.divider { - width: 720px; -} + +div#TableDivider { height: 30px; } div#LoginAboutText { width: 400px; } From a561a9d46eafa5159795a9b53df00a7b5ff1813d Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 23 Sep 2019 14:39:03 +0000 Subject: [PATCH 100/877] Improved presentation of budget field. --- WEB-INF/templates/admin_work.tpl | 4 ++-- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/work.tpl | 9 ++++----- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/WEB-INF/templates/admin_work.tpl b/WEB-INF/templates/admin_work.tpl index ddbf5071e..b3ec7f4b4 100644 --- a/WEB-INF/templates/admin_work.tpl +++ b/WEB-INF/templates/admin_work.tpl @@ -21,7 +21,7 @@ {$work_item.subject|escape} {$work_item.description|escape} {$work_item.group_name|escape} ({$work_item.site_id}.{$work_item.group_id}){$work_item.currency} {$work_item.amount}{$work_item.amount_with_currency} {$i18n.label.edit} {$i18n.label.delete}
{$offer.subject|escape} {$offer.description|escape} {$offer.group_name|escape} ({$offer.site_id}.{$offer.group_id}){$offer.currency} {$offer.amount}{$offer.amount_with_currency} {$i18n.label.edit} {$i18n.label.delete}
- - + {/foreach} -
 Anuko Time Tracker 1.19.10.5104 | Copyright © Anuko | +  Anuko Time Tracker 1.19.10.5105 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/work.tpl b/WEB-INF/templates/work.tpl index 96f891fc9..7a76975c0 100644 --- a/WEB-INF/templates/work.tpl +++ b/WEB-INF/templates/work.tpl @@ -21,12 +21,11 @@ {$work_item.subject|escape} {$work_item.description|escape} {$work_item.group_name|escape}{$work_item.currency} {$work_item.amount}{$work_item.amount_with_currency} {$i18n.label.edit} {$i18n.label.delete}
@@ -54,7 +53,7 @@ - + @@ -86,7 +85,7 @@ - + @@ -118,7 +117,7 @@ - + From e96779caea59a03c5570ef80b559db72fc5dd9fa Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 23 Sep 2019 16:19:55 +0000 Subject: [PATCH 101/877] Starting to work on admin_work_edit.php. --- WEB-INF/lib/ttUser.class.php | 8 +-- WEB-INF/templates/footer.tpl | 2 +- admin_work_edit.php | 104 +++++++++++++++++++++++++++++++++++ 3 files changed, 109 insertions(+), 5 deletions(-) create mode 100644 admin_work_edit.php diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index 59616f12b..89a1973fb 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -52,8 +52,8 @@ class ttUser { var $group_name = null; // Group name. var $behalf_group_name = null;// Group name, on behalf of which we are working. var $email = null; // User email. - var $lang = null; // Language. - var $decimal_mark = null; // Decimal separator. + var $lang = 'en'; // Language. + var $decimal_mark = '.'; // Decimal separator. var $date_format = null; // Date format. var $time_format = null; // Time format. var $week_start = 0; // Week start day. @@ -126,8 +126,8 @@ function __construct($login, $id = null) { $this->is_client = $this->client_id && !in_array('track_own_time', $this->rights); if ($val['quota_percent']) $this->quota_percent = $val['quota_percent']; $this->email = $val['email']; - $this->lang = $val['lang']; - $this->decimal_mark = $val['decimal_mark']; + if ($val['lang']) $this->lang = $val['lang']; + if ($val['decimal_mark']) $this->decimal_mark = $val['decimal_mark']; $this->date_format = $val['date_format']; $this->time_format = $val['time_format']; $this->week_start = $val['week_start']; diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 00971ce14..685e01d19 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
{$work_item.subject|escape} {$work_item.description|escape} {$work_item.group_name|escape}{$work_item.currency} {$work_item.amount}{$work_item.amount_with_currency}
{$offer.subject|escape} {$offer.description|escape} {$offer.group_name|escape}{$offer.currency} {$offer.amount}{$offer.amount_with_currency} {$i18n.label.edit} {$i18n.label.delete}
{$offer.subject|escape} {$offer.description|escape} {$offer.group_name|escape}{$offer.currency} {$offer.amount}{$offer.amount_with_currency}
- - + diff --git a/admin_work_edit.php b/admin_work_edit.php index 285965b2e..0eb38f887 100644 --- a/admin_work_edit.php +++ b/admin_work_edit.php @@ -45,6 +45,12 @@ } // End of access checks. +// Status definitions. +define("STATUS_PENDING_APPROVAL", 4); +define("STATUS_DISAPPROVED", 8); +define("STATUS_APPROVED", 12); + +$existingStatus = $work_item['status']; $currencies = ttWorkHelper::getCurrencies(); if ($request->isPost()) { @@ -53,6 +59,7 @@ $cl_details = trim($request->getParameter('details')); $cl_currency = $request->getParameter('currency'); $cl_budget = $request->getParameter('budget'); + $cl_status = $request->getParameter('status'); $cl_moderator_comment = $request->getParameter('moderator_comment'); } else { $cl_name = $work_item['subject']; @@ -61,6 +68,7 @@ $currency = $work_item['currency']; $cl_currency = array_search($currency, $currencies); $cl_budget = $work_item['amount']; + $cl_status = $work_item['status']; $cl_moderator_comment = $work_item['moderator_comment']; } @@ -71,8 +79,14 @@ $form->addInput(array('type'=>'textarea','name'=>'details','style'=>'width: 250px; height: 80px;','value'=>$cl_details)); $form->addInput(array('type'=>'combobox','name'=>'currency','data'=>$currencies,'value'=>$cl_currency)); $form->addInput(array('type'=>'floatfield','maxlength'=>'10','name'=>'budget','format'=>'.2','value'=>$cl_budget)); -$form->addInput(array('type'=>'combobox','name'=>'status','value'=>$cl_status, - 'data'=>array(ACTIVE=>$i18n->get('dropdown.approved'),INACTIVE=>$i18n->get('dropdown.not_approved')))); + +// Prepare status choices. +$status_options = array(); +$status_options[STATUS_PENDING_APPROVAL] = $i18n->get('dropdown.pending_approval'); +$status_options[STATUS_DISAPPROVED] = $i18n->get('dropdown.not_approved'); +$status_options[STATUS_APPROVED] = $i18n->get('dropdown.approved'); + +$form->addInput(array('type'=>'combobox','name'=>'status','value'=>$cl_status,'data'=>$status_options)); $form->addInput(array('type'=>'textarea','name'=>'moderator_comment','style'=>'width: 250px; height: 80px;','value'=>$cl_moderator_comment)); $form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); @@ -89,16 +103,33 @@ if ($err->no()) { if ($request->getParameter('btn_save')) { - // Update work information. $fields = array('work_id'=>$cl_work_id, 'subject'=>$cl_name, 'descr_short' => $cl_description, 'descr_long' => $cl_details, 'currency' => $currencies[$cl_currency], - 'amount' => $cl_budget); - if ($workHelper->updateWork($fields)) { - header('Location: work.php'); - exit(); + 'amount' => $cl_budget, + 'moderator_comment' => $cl_moderator_comment); + + // Do things differently, depending on status control value. + if ($existingStatus == $cl_status) { + // Status not changed. Update work information. + if ($adminWorkHelper->updateWork($fields)) { + header('Location: admin_work.php'); + exit(); + } + } else if ($cl_status == STATUS_DISAPPROVED) { + // Status changed to "not approved". Disapprove work. + if ($adminWorkHelper->disapproveWork($fields)) { + header('Location: admin_work.php'); + exit(); + } + } else if ($cl_status == STATUS_APPROVED) { + // Status changed to "approved". Approve work. + if ($adminWorkHelper->approveWork($fields)) { + header('Location: admin_work.php'); + exit(); + } } } } From 078e2657fef518e71a6e2b5b96301192c6aba505 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 25 Sep 2019 14:40:50 +0000 Subject: [PATCH 104/877] Fixed disapproveWork function. --- WEB-INF/lib/ttAdminWorkHelper.class.php | 2 +- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/WEB-INF/lib/ttAdminWorkHelper.class.php b/WEB-INF/lib/ttAdminWorkHelper.class.php index 6adbdd4ad..29f41280d 100644 --- a/WEB-INF/lib/ttAdminWorkHelper.class.php +++ b/WEB-INF/lib/ttAdminWorkHelper.class.php @@ -599,7 +599,7 @@ function approveWork($work_id) { } // disapproveWork - disapproves work item in remote work server. - function disapproveWork($work_id) { + function disapproveWork($fields) { global $i18n; global $user; $mdb2 = getConnection(); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 685e01d19..370602519 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.19.10.5105 | Copyright © Anuko | +  Anuko Time Tracker 1.19.10.5106 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/admin_work_edit.php b/admin_work_edit.php new file mode 100644 index 000000000..bf9a02593 --- /dev/null +++ b/admin_work_edit.php @@ -0,0 +1,104 @@ +getParameter('id'); +$adminWorkHelper = new ttAdminWorkHelper($err); +$work_item = $adminWorkHelper->getWork($cl_work_id); +if (!$work_item) { + header('Location: access_denied.php'); + exit(); +} +// End of access checks. + +$currencies = ttWorkHelper::getCurrencies(); + +if ($request->isPost()) { + $cl_name = trim($request->getParameter('work_name')); + $cl_description = trim($request->getParameter('description')); + $cl_details = trim($request->getParameter('details')); + $cl_currency = $request->getParameter('currency'); + $cl_budget = $request->getParameter('budget'); +} else { + $cl_name = $work_item['subject']; + $cl_description = $work_item['descr_short']; + $cl_details = $work_item['descr_long']; + $currency = $work_item['currency']; + $cl_currency = array_search($currency, $currencies); + $cl_budget = $work_item['amount']; +} + +$form = new Form('workForm'); +$form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_work_id)); +$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'work_name','style'=>'width: 250px;','value'=>$cl_name)); +$form->addInput(array('type'=>'textarea','name'=>'description','style'=>'width: 250px; height: 40px;','value'=>$cl_description)); +$form->addInput(array('type'=>'textarea','name'=>'details','style'=>'width: 250px; height: 80px;','value'=>$cl_details)); +$form->addInput(array('type'=>'combobox','name'=>'currency','data'=>$currencies,'value'=>$cl_currency)); +$form->addInput(array('type'=>'floatfield','maxlength'=>'10','name'=>'budget','format'=>'.2','value'=>$cl_budget)); +$form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); + +if ($request->isPost()) { + // Validate user input. + if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.work')); + if (!ttValidString($cl_description, true)) $err->add($i18n->get('error.field'), $i18n->get('label.description')); + if (!ttValidString($cl_details, true)) $err->add($i18n->get('error.field'), $i18n->get('label.details')); + if (!ttValidString($cl_budget)) $err->add($i18n->get('error.field'), $i18n->get('label.budget')); + + // Ensure user email exists (required for workflow). + if (!$user->getEmail()) $err->add($i18n->get('error.no_email')); + + if ($err->no()) { + if ($request->getParameter('btn_save')) { + // Update work information. + $fields = array('work_id'=>$cl_work_id, + 'subject'=>$cl_name, + 'descr_short' => $cl_description, + 'descr_long' => $cl_details, + 'currency' => $currencies[$cl_currency], + 'amount' => $cl_budget); + if ($workHelper->updateWork($fields)) { + header('Location: work.php'); + exit(); + } + } + } +} // isPost + +$smarty->assign('forms', array($form->getName()=>$form->toArray())); +$smarty->assign('title', $i18n->get('title.edit_work')); +$smarty->assign('content_page_name', 'work_edit.tpl'); +$smarty->display('index.tpl'); From 15b716bb3090329d872bc4fadfd450b8b6ab6ddb Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 23 Sep 2019 17:15:37 +0000 Subject: [PATCH 102/877] Work in progress on admin_work_edit.php. --- WEB-INF/resources/ca.lang.php | 1 + WEB-INF/resources/cs.lang.php | 1 + WEB-INF/resources/da.lang.php | 1 + WEB-INF/resources/de.lang.php | 1 + WEB-INF/resources/en.lang.php | 2 + WEB-INF/resources/es.lang.php | 1 + WEB-INF/resources/et.lang.php | 1 + WEB-INF/resources/fa.lang.php | 1 + WEB-INF/resources/fi.lang.php | 1 + WEB-INF/resources/fr.lang.php | 1 + WEB-INF/resources/gr.lang.php | 1 + WEB-INF/resources/he.lang.php | 1 + WEB-INF/resources/hu.lang.php | 1 + WEB-INF/resources/it.lang.php | 1 + WEB-INF/resources/ja.lang.php | 1 + WEB-INF/resources/ko.lang.php | 1 + WEB-INF/resources/nl.lang.php | 3 +- WEB-INF/resources/no.lang.php | 1 + WEB-INF/resources/pl.lang.php | 1 + WEB-INF/resources/pt-br.lang.php | 1 + WEB-INF/resources/pt.lang.php | 1 + WEB-INF/resources/ro.lang.php | 1 + WEB-INF/resources/ru.lang.php | 1 + WEB-INF/resources/sk.lang.php | 1 + WEB-INF/resources/sl.lang.php | 1 + WEB-INF/resources/sr.lang.php | 1 + WEB-INF/resources/sv.lang.php | 1 + WEB-INF/resources/tr.lang.php | 1 + WEB-INF/resources/zh-cn.lang.php | 1 + WEB-INF/resources/zh-tw.lang.php | 1 + WEB-INF/templates/admin_work_edit.tpl | 55 +++++++++++++++++++++++++++ admin_work_edit.php | 8 +++- 32 files changed, 94 insertions(+), 2 deletions(-) create mode 100644 WEB-INF/templates/admin_work_edit.tpl diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index 3e38c19a2..6ac795cb5 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -292,6 +292,7 @@ // because both work items and offers are owned by Time Tracker groups of users. // 'label.how_to_pay' => 'How to pay', // Label for the "How to pay" field on offers, which allows contractors to specify // how to pay them, for example: paypal email, check by mail to a specific address, etc. +// 'label.moderator_comment' => 'Moderator comment', // Label for "Moderator comment" field that explains something. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index fb8b502d2..ff6fff3ea 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -302,6 +302,7 @@ // because both work items and offers are owned by Time Tracker groups of users. // 'label.how_to_pay' => 'How to pay', // Label for the "How to pay" field on offers, which allows contractors to specify // how to pay them, for example: paypal email, check by mail to a specific address, etc. +// 'label.moderator_comment' => 'Moderator comment', // Label for "Moderator comment" field that explains something. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index 5b03bf338..cc0db9d58 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -283,6 +283,7 @@ // because both work items and offers are owned by Time Tracker groups of users. // 'label.how_to_pay' => 'How to pay', // Label for the "How to pay" field on offers, which allows contractors to specify // how to pay them, for example: paypal email, check by mail to a specific address, etc. +// 'label.moderator_comment' => 'Moderator comment', // Label for "Moderator comment" field that explains something. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index d47c19e9c..511c06d31 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -277,6 +277,7 @@ // because both work items and offers are owned by Time Tracker groups of users. // 'label.how_to_pay' => 'How to pay', // Label for the "How to pay" field on offers, which allows contractors to specify // how to pay them, for example: paypal email, check by mail to a specific address, etc. +// 'label.moderator_comment' => 'Moderator comment', // Label for "Moderator comment" field that explains something. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index 459b250b4..d741c9d0b 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -266,6 +266,7 @@ // because both work items and offers are owned by Time Tracker groups of users. 'label.how_to_pay' => 'How to pay', // Label for the "How to pay" field on offers, which allows contractors to specify // how to pay them, for example: paypal email, check by mail to a specific address, etc. +'label.moderator_comment' => 'Moderator comment', // Label for "Moderator comment" field that explains something. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. @@ -407,6 +408,7 @@ 'dropdown.status_inactive' => 'inactive', 'dropdown.delete' => 'delete', 'dropdown.do_not_delete' => 'do not delete', +'dropdown.pending_approval' => 'pending approval', 'dropdown.approved' => 'approved', 'dropdown.not_approved' => 'not approved', 'dropdown.paid' => 'paid', diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index 61cbaa337..c9807ba64 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -295,6 +295,7 @@ // because both work items and offers are owned by Time Tracker groups of users. // 'label.how_to_pay' => 'How to pay', // Label for the "How to pay" field on offers, which allows contractors to specify // how to pay them, for example: paypal email, check by mail to a specific address, etc. +// 'label.moderator_comment' => 'Moderator comment', // Label for "Moderator comment" field that explains something. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index 5a199bf81..c80e1536d 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -290,6 +290,7 @@ // because both work items and offers are owned by Time Tracker groups of users. // 'label.how_to_pay' => 'How to pay', // Label for the "How to pay" field on offers, which allows contractors to specify // how to pay them, for example: paypal email, check by mail to a specific address, etc. +// 'label.moderator_comment' => 'Moderator comment', // Label for "Moderator comment" field that explains something. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index 79547fc89..e8520e0c6 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -294,6 +294,7 @@ // because both work items and offers are owned by Time Tracker groups of users. // 'label.how_to_pay' => 'How to pay', // Label for the "How to pay" field on offers, which allows contractors to specify // how to pay them, for example: paypal email, check by mail to a specific address, etc. +// 'label.moderator_comment' => 'Moderator comment', // Label for "Moderator comment" field that explains something. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index a1cdac1e9..eb3bc9104 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -287,6 +287,7 @@ // because both work items and offers are owned by Time Tracker groups of users. // 'label.how_to_pay' => 'How to pay', // Label for the "How to pay" field on offers, which allows contractors to specify // how to pay them, for example: paypal email, check by mail to a specific address, etc. +// 'label.moderator_comment' => 'Moderator comment', // Label for "Moderator comment" field that explains something. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index 9228c6834..b82004365 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -281,6 +281,7 @@ // because both work items and offers are owned by Time Tracker groups of users. // 'label.how_to_pay' => 'How to pay', // Label for the "How to pay" field on offers, which allows contractors to specify // how to pay them, for example: paypal email, check by mail to a specific address, etc. +// 'label.moderator_comment' => 'Moderator comment', // Label for "Moderator comment" field that explains something. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index 300dc3c22..1b3a9c52f 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -277,6 +277,7 @@ // because both work items and offers are owned by Time Tracker groups of users. // 'label.how_to_pay' => 'How to pay', // Label for the "How to pay" field on offers, which allows contractors to specify // how to pay them, for example: paypal email, check by mail to a specific address, etc. +// 'label.moderator_comment' => 'Moderator comment', // Label for "Moderator comment" field that explains something. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index 6d593c9dc..d67e28d94 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -302,6 +302,7 @@ // because both work items and offers are owned by Time Tracker groups of users. // 'label.how_to_pay' => 'How to pay', // Label for the "How to pay" field on offers, which allows contractors to specify // how to pay them, for example: paypal email, check by mail to a specific address, etc. +// 'label.moderator_comment' => 'Moderator comment', // Label for "Moderator comment" field that explains something. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index a8bbe719d..e2f12d62f 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -298,6 +298,7 @@ // because both work items and offers are owned by Time Tracker groups of users. // 'label.how_to_pay' => 'How to pay', // Label for the "How to pay" field on offers, which allows contractors to specify // how to pay them, for example: paypal email, check by mail to a specific address, etc. +// 'label.moderator_comment' => 'Moderator comment', // Label for "Moderator comment" field that explains something. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index f439ba700..58fbe9265 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -281,6 +281,7 @@ // because both work items and offers are owned by Time Tracker groups of users. // 'label.how_to_pay' => 'How to pay', // Label for the "How to pay" field on offers, which allows contractors to specify // how to pay them, for example: paypal email, check by mail to a specific address, etc. +// 'label.moderator_comment' => 'Moderator comment', // Label for "Moderator comment" field that explains something. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index 5dc4d757d..c40944d53 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -302,6 +302,7 @@ // because both work items and offers are owned by Time Tracker groups of users. // 'label.how_to_pay' => 'How to pay', // Label for the "How to pay" field on offers, which allows contractors to specify // how to pay them, for example: paypal email, check by mail to a specific address, etc. +// 'label.moderator_comment' => 'Moderator comment', // Label for "Moderator comment" field that explains something. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index a9c2abaed..a21f62571 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -302,6 +302,7 @@ // because both work items and offers are owned by Time Tracker groups of users. // 'label.how_to_pay' => 'How to pay', // Label for the "How to pay" field on offers, which allows contractors to specify // how to pay them, for example: paypal email, check by mail to a specific address, etc. +// 'label.moderator_comment' => 'Moderator comment', // Label for "Moderator comment" field that explains something. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 18bc14052..e99954c44 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -271,7 +271,8 @@ // Technically, it is either an org name or a combination of org and group names // because both work items and offers are owned by Time Tracker groups of users. // 'label.how_to_pay' => 'How to pay', // Label for the "How to pay" field on offers, which allows contractors to specify - // how to pay them, for example: paypal email, check by mail to a specific address, etc.S + // how to pay them, for example: paypal email, check by mail to a specific address, etc. +// 'label.moderator_comment' => 'Moderator comment', // Label for "Moderator comment" field that explains something. // Entity names. 'entity.time' => 'tijd', diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index 2b02c84e4..88a94a854 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -299,6 +299,7 @@ // because both work items and offers are owned by Time Tracker groups of users. // 'label.how_to_pay' => 'How to pay', // Label for the "How to pay" field on offers, which allows contractors to specify // how to pay them, for example: paypal email, check by mail to a specific address, etc. +// 'label.moderator_comment' => 'Moderator comment', // Label for "Moderator comment" field that explains something. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index ef438e984..3e92fe18d 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -288,6 +288,7 @@ // because both work items and offers are owned by Time Tracker groups of users. // 'label.how_to_pay' => 'How to pay', // Label for the "How to pay" field on offers, which allows contractors to specify // how to pay them, for example: paypal email, check by mail to a specific address, etc. +// 'label.moderator_comment' => 'Moderator comment', // Label for "Moderator comment" field that explains something. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index 08d92193c..50fcec669 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -285,6 +285,7 @@ // because both work items and offers are owned by Time Tracker groups of users. // 'label.how_to_pay' => 'How to pay', // Label for the "How to pay" field on offers, which allows contractors to specify // how to pay them, for example: paypal email, check by mail to a specific address, etc. +// 'label.moderator_comment' => 'Moderator comment', // Label for "Moderator comment" field that explains something. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index beafbf92d..ca1813de9 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -287,6 +287,7 @@ // because both work items and offers are owned by Time Tracker groups of users. // 'label.how_to_pay' => 'How to pay', // Label for the "How to pay" field on offers, which allows contractors to specify // how to pay them, for example: paypal email, check by mail to a specific address, etc. +// 'label.moderator_comment' => 'Moderator comment', // Label for "Moderator comment" field that explains something. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index 98ccd4ae7..3d0bace62 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -299,6 +299,7 @@ // because both work items and offers are owned by Time Tracker groups of users. // 'label.how_to_pay' => 'How to pay', // Label for the "How to pay" field on offers, which allows contractors to specify // how to pay them, for example: paypal email, check by mail to a specific address, etc. +// 'label.moderator_comment' => 'Moderator comment', // Label for "Moderator comment" field that explains something. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index 3b0fafbc9..f12aed108 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -254,6 +254,7 @@ 'label.offer' => 'Предложение', 'label.contractor' => 'Подрядчик', 'label.how_to_pay' => 'Как оплатить', +'label.moderator_comment' => 'Комментарий модератора', // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index 3f2955f3c..63e2b6809 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -292,6 +292,7 @@ // because both work items and offers are owned by Time Tracker groups of users. // 'label.how_to_pay' => 'How to pay', // Label for the "How to pay" field on offers, which allows contractors to specify // how to pay them, for example: paypal email, check by mail to a specific address, etc. +// 'label.moderator_comment' => 'Moderator comment', // Label for "Moderator comment" field that explains something. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index 1ff3fe338..e62892ba3 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -282,6 +282,7 @@ // because both work items and offers are owned by Time Tracker groups of users. // 'label.how_to_pay' => 'How to pay', // Label for the "How to pay" field on offers, which allows contractors to specify // how to pay them, for example: paypal email, check by mail to a specific address, etc. +// 'label.moderator_comment' => 'Moderator comment', // Label for "Moderator comment" field that explains something. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index b3c2eb573..dc4124373 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -286,6 +286,7 @@ // because both work items and offers are owned by Time Tracker groups of users. // 'label.how_to_pay' => 'How to pay', // Label for the "How to pay" field on offers, which allows contractors to specify // how to pay them, for example: paypal email, check by mail to a specific address, etc. +// 'label.moderator_comment' => 'Moderator comment', // Label for "Moderator comment" field that explains something. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index c95d42326..645f0c4d2 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -283,6 +283,7 @@ // because both work items and offers are owned by Time Tracker groups of users. // 'label.how_to_pay' => 'How to pay', // Label for the "How to pay" field on offers, which allows contractors to specify // how to pay them, for example: paypal email, check by mail to a specific address, etc. +// 'label.moderator_comment' => 'Moderator comment', // Label for "Moderator comment" field that explains something. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index e8aef3b47..6cf2edb11 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -306,6 +306,7 @@ // because both work items and offers are owned by Time Tracker groups of users. // 'label.how_to_pay' => 'How to pay', // Label for the "How to pay" field on offers, which allows contractors to specify // how to pay them, for example: paypal email, check by mail to a specific address, etc. +// 'label.moderator_comment' => 'Moderator comment', // Label for "Moderator comment" field that explains something. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index e401aded7..62ebffef4 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -291,6 +291,7 @@ // because both work items and offers are owned by Time Tracker groups of users. // 'label.how_to_pay' => 'How to pay', // Label for the "How to pay" field on offers, which allows contractors to specify // how to pay them, for example: paypal email, check by mail to a specific address, etc. +// 'label.moderator_comment' => 'Moderator comment', // Label for "Moderator comment" field that explains something. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index 7aa36b577..1b518ef36 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -297,6 +297,7 @@ // because both work items and offers are owned by Time Tracker groups of users. // 'label.how_to_pay' => 'How to pay', // Label for the "How to pay" field on offers, which allows contractors to specify // how to pay them, for example: paypal email, check by mail to a specific address, etc. +// 'label.moderator_comment' => 'Moderator comment', // Label for "Moderator comment" field that explains something. // Entity names. We use lower case (in English) because they are used in dropdowns, too. // They are used to associate a custom field with an entity type. diff --git a/WEB-INF/templates/admin_work_edit.tpl b/WEB-INF/templates/admin_work_edit.tpl new file mode 100644 index 000000000..eb71e1171 --- /dev/null +++ b/WEB-INF/templates/admin_work_edit.tpl @@ -0,0 +1,55 @@ +{$forms.workForm.open} + + + + +
+ + + + + + + + + + + + + +{if $show_files} + + + + +{/if} + + + + + + + + + + + + + + + + + + + + + + + + + + + +
{$i18n.label.work} (*):{$forms.workForm.work_name.control}
{$i18n.label.description}:{$forms.workForm.description.control}
{$i18n.label.details}:{$forms.workForm.details.control}
{$i18n.label.file}:{$forms.workForm.newfile.control}
{$i18n.label.currency}:{$forms.workForm.currency.control}
{$i18n.label.budget} (*):{$forms.workForm.budget.control} {$i18n.label.what_is_it}
{$i18n.label.status}:{$forms.workForm.status.control}
{$i18n.label.moderator_comment}:{$forms.workForm.moderator_comment.control}
{$i18n.label.required_fields}
 
{$forms.workForm.btn_save.control}
+
+{$forms.workForm.close} diff --git a/admin_work_edit.php b/admin_work_edit.php index bf9a02593..285965b2e 100644 --- a/admin_work_edit.php +++ b/admin_work_edit.php @@ -53,6 +53,7 @@ $cl_details = trim($request->getParameter('details')); $cl_currency = $request->getParameter('currency'); $cl_budget = $request->getParameter('budget'); + $cl_moderator_comment = $request->getParameter('moderator_comment'); } else { $cl_name = $work_item['subject']; $cl_description = $work_item['descr_short']; @@ -60,6 +61,7 @@ $currency = $work_item['currency']; $cl_currency = array_search($currency, $currencies); $cl_budget = $work_item['amount']; + $cl_moderator_comment = $work_item['moderator_comment']; } $form = new Form('workForm'); @@ -69,6 +71,9 @@ $form->addInput(array('type'=>'textarea','name'=>'details','style'=>'width: 250px; height: 80px;','value'=>$cl_details)); $form->addInput(array('type'=>'combobox','name'=>'currency','data'=>$currencies,'value'=>$cl_currency)); $form->addInput(array('type'=>'floatfield','maxlength'=>'10','name'=>'budget','format'=>'.2','value'=>$cl_budget)); +$form->addInput(array('type'=>'combobox','name'=>'status','value'=>$cl_status, + 'data'=>array(ACTIVE=>$i18n->get('dropdown.approved'),INACTIVE=>$i18n->get('dropdown.not_approved')))); +$form->addInput(array('type'=>'textarea','name'=>'moderator_comment','style'=>'width: 250px; height: 80px;','value'=>$cl_moderator_comment)); $form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); if ($request->isPost()) { @@ -77,6 +82,7 @@ if (!ttValidString($cl_description, true)) $err->add($i18n->get('error.field'), $i18n->get('label.description')); if (!ttValidString($cl_details, true)) $err->add($i18n->get('error.field'), $i18n->get('label.details')); if (!ttValidString($cl_budget)) $err->add($i18n->get('error.field'), $i18n->get('label.budget')); + if (!ttValidString($cl_moderator_comment, true)) $err->add($i18n->get('error.field'), $i18n->get('label.moderator_comment')); // Ensure user email exists (required for workflow). if (!$user->getEmail()) $err->add($i18n->get('error.no_email')); @@ -100,5 +106,5 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('title', $i18n->get('title.edit_work')); -$smarty->assign('content_page_name', 'work_edit.tpl'); +$smarty->assign('content_page_name', 'admin_work_edit.tpl'); $smarty->display('index.tpl'); From 5e063d7908c7291d45636af8f218f5a6e18585b2 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 24 Sep 2019 13:01:55 +0000 Subject: [PATCH 103/877] Work in progress on moderator approval workflow for Remote Work plugin. --- WEB-INF/lib/ttAdminWorkHelper.class.php | 195 ++++++++++++++++++++++++ WEB-INF/resources/ca.lang.php | 1 + WEB-INF/resources/cs.lang.php | 1 + WEB-INF/resources/da.lang.php | 1 + WEB-INF/resources/de.lang.php | 1 + WEB-INF/resources/es.lang.php | 1 + WEB-INF/resources/et.lang.php | 1 + WEB-INF/resources/fa.lang.php | 1 + WEB-INF/resources/fi.lang.php | 1 + WEB-INF/resources/fr.lang.php | 1 + WEB-INF/resources/gr.lang.php | 1 + WEB-INF/resources/he.lang.php | 1 + WEB-INF/resources/hu.lang.php | 1 + WEB-INF/resources/it.lang.php | 1 + WEB-INF/resources/ja.lang.php | 1 + WEB-INF/resources/ko.lang.php | 1 + WEB-INF/resources/nl.lang.php | 2 + WEB-INF/resources/no.lang.php | 1 + WEB-INF/resources/pl.lang.php | 1 + WEB-INF/resources/pt-br.lang.php | 1 + WEB-INF/resources/pt.lang.php | 1 + WEB-INF/resources/ro.lang.php | 1 + WEB-INF/resources/ru.lang.php | 1 + WEB-INF/resources/sk.lang.php | 1 + WEB-INF/resources/sl.lang.php | 1 + WEB-INF/resources/sr.lang.php | 1 + WEB-INF/resources/sv.lang.php | 1 + WEB-INF/resources/tr.lang.php | 1 + WEB-INF/resources/zh-cn.lang.php | 1 + WEB-INF/resources/zh-tw.lang.php | 1 + WEB-INF/templates/admin_work_edit.tpl | 2 +- admin_work_edit.php | 45 +++++- 32 files changed, 264 insertions(+), 8 deletions(-) diff --git a/WEB-INF/lib/ttAdminWorkHelper.class.php b/WEB-INF/lib/ttAdminWorkHelper.class.php index e28cb581b..6adbdd4ad 100644 --- a/WEB-INF/lib/ttAdminWorkHelper.class.php +++ b/WEB-INF/lib/ttAdminWorkHelper.class.php @@ -37,9 +37,13 @@ class ttAdminWorkHelper { var $get_work_uri = null; // URI to get work details. var $update_work_uri = null; // URI to update work. var $delete_work_uri = null; // URI to delete work. + var $approve_work_uri = null; // URI to approved work. + var $disapprove_work_uri = null; // URI to disapprove work. var $get_offer_uri = null; // URI to get offer details. var $update_offer_uri = null; // URI to update offer. var $delete_offer_uri = null; // URI to delete offer. + var $approve_offer_uri = null; // URI to approved offer. + var $disapprove_offer_uri = null; // URI to disapprove offer. var $get_pending_work_uri = null; // URI to get work pending approval. var $get_pending_offers_uri = null; // URI to get offers pending approval. var $site_id = null; // Site id for remote work server. @@ -54,9 +58,13 @@ function __construct(&$errors) { $this->get_work_uri = $this->remote_work_uri.'admin_getwork'; $this->update_work_uri = $this->remote_work_uri.'admin_updatework'; $this->delete_work_uri = $this->remote_work_uri.'admin_deletework'; + $this->approve_work_uri = $this->remote_work_uri.'admin_approvework'; + $this->disapprove_work_uri = $this->remote_work_uri.'admin_disapprovework'; $this->get_offer_uri = $this->remote_work_uri.'admin_getoffer'; $this->update_offer_uri = $this->remote_work_uri.'admin_updateoffer'; $this->delete_offer_uri = $this->remote_work_uri.'admin_deleteoffer'; + $this->approve_offer_uri = $this->remote_work_uri.'admin_approveoffer'; + $this->disapprove_offer_uri = $this->remote_work_uri.'admin_disapproveoffer'; $this->get_pending_work_uri = $this->remote_work_uri.'admin_getpendingwork'; $this->get_pending_offers_uri = $this->remote_work_uri.'admin_getpendingoffers'; $this->checkSiteRegistration(); @@ -464,4 +472,191 @@ function getOffer($offer_id) { $offer = $result_array['offer']; return $offer; } + + // updateWork - updates a work item in remote work server. + function updateWork($fields) { + global $i18n; + global $user; + $mdb2 = getConnection(); + + $curl_fields = array('lang' => urlencode($user->lang), + 'site_id' => urlencode($this->site_id), + 'site_key' => urlencode($this->site_key), + 'user_id' => urlencode($user->id), + 'work_id' => urlencode($fields['work_id']), + 'subject' => urlencode(base64_encode($fields['subject'])), + 'descr_short' => urlencode(base64_encode($fields['descr_short'])), + 'descr_long' => urlencode(base64_encode($fields['descr_long'])), + 'currency' => urlencode($fields['currency']), + 'amount' => urlencode($fields['amount']), + 'moderator_comment' => urlencode(base64_encode($fields['moderator_comment'])), + 'modified_ip' => urlencode($_SERVER['REMOTE_ADDR']), + 'modified_by' => urlencode($user->getUser()), + 'modified_by_name' => urlencode(base64_encode($user->getName())), + 'modified_by_email' => urlencode(base64_encode($user->getEmail())) + ); + + // url-ify the data for the POST. + foreach($curl_fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; } + $fields_string = rtrim($fields_string, '&'); + + // Open connection. + $ch = curl_init(); + + // Set the url, number of POST vars, POST data. + curl_setopt($ch, CURLOPT_URL, $this->update_work_uri); + curl_setopt($ch, CURLOPT_POST, true); + curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + + // Execute a post request. + $result = curl_exec($ch); + + // Close connection. + curl_close($ch); + + if (!$result) { + $this->errors->add($i18n->get('error.remote_work')); + return false; + } + + $result_array = json_decode($result, true); + + // Check for errors. + $call_status = $result_array['call_status']; + if (!$call_status) { + $this->errors->add($i18n->get('error.remote_work')); + return false; + } + if ($call_status['code'] != TT_CURL_SUCCESS) { + $this->errors->add($call_status['error']); + return false; + } + + return true; + } + + // approveWork - approves work item in remote work server. + function approveWork($work_id) { + global $i18n; + global $user; + $mdb2 = getConnection(); + + $curl_fields = array('lang' => urlencode($user->lang), + 'site_id' => urlencode($this->site_id), + 'site_key' => urlencode($this->site_key), + 'user_id' => urlencode($user->id), + 'work_id' => urlencode($fields['work_id']), + 'subject' => urlencode(base64_encode($fields['subject'])), + 'descr_short' => urlencode(base64_encode($fields['descr_short'])), + 'descr_long' => urlencode(base64_encode($fields['descr_long'])), + 'currency' => urlencode($fields['currency']), + 'amount' => urlencode($fields['amount']), + 'moderator_comment' => urlencode(base64_encode($fields['moderator_comment'])), + 'modified_ip' => urlencode($_SERVER['REMOTE_ADDR']), + 'modified_by' => urlencode($user->getUser()), + 'modified_by_name' => urlencode(base64_encode($user->getName())), + 'modified_by_email' => urlencode(base64_encode($user->getEmail()))); + + // url-ify the data for the POST. + foreach($curl_fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; } + $fields_string = rtrim($fields_string, '&'); + + // Open connection. + $ch = curl_init(); + + // Set the url, number of POST vars, POST data. + curl_setopt($ch, CURLOPT_URL, $this->approve_work_uri); + curl_setopt($ch, CURLOPT_POST, true); + curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + + // Execute a post request. + $result = curl_exec($ch); + + // Close connection. + curl_close($ch); + + if (!$result) { + $this->errors->add($i18n->get('error.remote_work')); + return false; + } + + $result_array = json_decode($result, true); + + // Check for errors. + $call_status = $result_array['call_status']; + if (!$call_status) { + $this->errors->add($i18n->get('error.remote_work')); + return false; + } + if ($call_status['code'] != TT_CURL_SUCCESS) { + $this->errors->add($call_status['error']); + return false; + } + + return true; + } + + // disapproveWork - disapproves work item in remote work server. + function disapproveWork($work_id) { + global $i18n; + global $user; + $mdb2 = getConnection(); + + $curl_fields = array('lang' => urlencode($user->lang), + 'site_id' => urlencode($this->site_id), + 'site_key' => urlencode($this->site_key), + 'user_id' => urlencode($user->id), + 'work_id' => urlencode($fields['work_id']), + 'subject' => urlencode(base64_encode($fields['subject'])), + 'descr_short' => urlencode(base64_encode($fields['descr_short'])), + 'descr_long' => urlencode(base64_encode($fields['descr_long'])), + 'currency' => urlencode($fields['currency']), + 'amount' => urlencode($fields['amount']), + 'moderator_comment' => urlencode(base64_encode($fields['moderator_comment'])), + 'modified_ip' => urlencode($_SERVER['REMOTE_ADDR']), + 'modified_by' => urlencode($user->getUser()), + 'modified_by_name' => urlencode(base64_encode($user->getName())), + 'modified_by_email' => urlencode(base64_encode($user->getEmail()))); + + // url-ify the data for the POST. + foreach($curl_fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; } + $fields_string = rtrim($fields_string, '&'); + + // Open connection. + $ch = curl_init(); + + // Set the url, number of POST vars, POST data. + curl_setopt($ch, CURLOPT_URL, $this->disapprove_work_uri); + curl_setopt($ch, CURLOPT_POST, true); + curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + + // Execute a post request. + $result = curl_exec($ch); + + // Close connection. + curl_close($ch); + + if (!$result) { + $this->errors->add($i18n->get('error.remote_work')); + return false; + } + + $result_array = json_decode($result, true); + + // Check for errors. + $call_status = $result_array['call_status']; + if (!$call_status) { + $this->errors->add($i18n->get('error.remote_work')); + return false; + } + if ($call_status['code'] != TT_CURL_SUCCESS) { + $this->errors->add($call_status['error']); + return false; + } + + return true; + } } diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index 6ac795cb5..0f237e21c 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -455,6 +455,7 @@ // 'dropdown.status_inactive' => 'inactive', // 'dropdown.delete' => 'delete', // 'dropdown.do_not_delete' => 'do not delete', +// 'dropdown.pending_approval' => 'pending approval', // 'dropdown.approved' => 'approved', // 'dropdown.not_approved' => 'not approved', // 'dropdown.paid' => 'paid', diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index ff6fff3ea..e52d1b9f6 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -463,6 +463,7 @@ // 'dropdown.status_inactive' => 'inactive', // 'dropdown.delete' => 'delete', // 'dropdown.do_not_delete' => 'do not delete', +// 'dropdown.pending_approval' => 'pending approval', // 'dropdown.approved' => 'approved', // 'dropdown.not_approved' => 'not approved', // 'dropdown.paid' => 'paid', diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index cc0db9d58..9d77c6aec 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -437,6 +437,7 @@ 'dropdown.delete' => 'Slet', 'dropdown.do_not_delete' => 'Slet ikke', // TODO: translate the following. +// 'dropdown.pending_approval' => 'pending approval', // 'dropdown.approved' => 'approved', // 'dropdown.not_approved' => 'not approved', // 'dropdown.paid' => 'paid', diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index 511c06d31..6766407f6 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -421,6 +421,7 @@ 'dropdown.delete' => 'löschen', 'dropdown.do_not_delete' => 'nicht löschen', // TODO: translate the following. +// 'dropdown.pending_approval' => 'pending approval', // 'dropdown.approved' => 'approved', // 'dropdown.not_approved' => 'not approved', 'dropdown.paid' => 'bezahlt', diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index c9807ba64..5c2da7972 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -454,6 +454,7 @@ // 'dropdown.status_inactive' => 'inactive', // 'dropdown.delete' => 'delete', // 'dropdown.do_not_delete' => 'do not delete', +// 'dropdown.pending_approval' => 'pending approval', // 'dropdown.approved' => 'approved', // 'dropdown.not_approved' => 'not approved', // 'dropdown.paid' => 'paid', diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index c80e1536d..d72720e24 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -443,6 +443,7 @@ 'dropdown.delete' => 'kustuta', 'dropdown.do_not_delete' => 'ära kustuta', // TODO: translate the following. +// 'dropdown.pending_approval' => 'pending approval', // 'dropdown.approved' => 'approved', // 'dropdown.not_approved' => 'not approved', 'dropdown.paid' => 'makstud', diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index e8520e0c6..ebb799567 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -449,6 +449,7 @@ // TODO: translate the following. // 'dropdown.delete' => 'delete', // 'dropdown.do_not_delete' => 'do not delete', +// 'dropdown.pending_approval' => 'pending approval', // 'dropdown.approved' => 'approved', // 'dropdown.not_approved' => 'not approved', // 'dropdown.paid' => 'paid', diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index eb3bc9104..6a923b4a1 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -437,6 +437,7 @@ 'dropdown.delete' => 'poista', 'dropdown.do_not_delete' => 'älä poista', // TODO: translate the following. +// 'dropdown.pending_approval' => 'pending approval', // 'dropdown.approved' => 'approved', // 'dropdown.not_approved' => 'not approved', // 'dropdown.paid' => 'paid', diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index b82004365..2d0a4892d 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -429,6 +429,7 @@ 'dropdown.delete' => 'supprimer', 'dropdown.do_not_delete' => 'ne pas supprimer', // TODO: translate the following. +// 'dropdown.pending_approval' => 'pending approval', // 'dropdown.approved' => 'approved', // 'dropdown.not_approved' => 'not approved', // 'dropdown.paid' => 'paid', diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index 1b3a9c52f..ccd10e059 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -428,6 +428,7 @@ 'dropdown.delete' => 'διαγραφή', 'dropdown.do_not_delete' => 'μη το διαγράψετε', // TODO: translate the following. +// 'dropdown.pending_approval' => 'pending approval', // 'dropdown.approved' => 'approved', // 'dropdown.not_approved' => 'not approved', 'dropdown.paid' => 'εξοφλημένο', diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index d67e28d94..7c1c90572 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -455,6 +455,7 @@ // TODO: translate the following. // 'dropdown.delete' => 'delete', // 'dropdown.do_not_delete' => 'do not delete', +// 'dropdown.pending_approval' => 'pending approval', // 'dropdown.approved' => 'approved', // 'dropdown.not_approved' => 'not approved', // 'dropdown.paid' => 'paid', diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index e2f12d62f..585723101 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -457,6 +457,7 @@ // 'dropdown.status_inactive' => 'inactive', // 'dropdown.delete' => 'delete', // 'dropdown.do_not_delete' => 'do not delete', +// 'dropdown.pending_approval' => 'pending approval', // 'dropdown.approved' => 'approved', // 'dropdown.not_approved' => 'not approved', // 'dropdown.paid' => 'paid', diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index 58fbe9265..4277c6bfc 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -438,6 +438,7 @@ 'dropdown.delete' => 'elimina', 'dropdown.do_not_delete' => 'non eliminare', // TODO: translate the following. +// 'dropdown.pending_approval' => 'pending approval', // 'dropdown.approved' => 'approved', // 'dropdown.not_approved' => 'not approved', 'dropdown.paid' => 'pagato', diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index c40944d53..0d1a7a2b8 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -458,6 +458,7 @@ // 'dropdown.status_inactive' => 'inactive', // 'dropdown.delete' => 'delete', // 'dropdown.do_not_delete' => 'do not delete', +// 'dropdown.pending_approval' => 'pending approval', // 'dropdown.approved' => 'approved', // 'dropdown.not_approved' => 'not approved', // 'dropdown.paid' => 'paid', diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index a21f62571..fe4599f9b 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -462,6 +462,7 @@ // 'dropdown.status_inactive' => 'inactive', // 'dropdown.delete' => 'delete', // 'dropdown.do_not_delete' => 'do not delete', +// 'dropdown.pending_approval' => 'pending approval', // 'dropdown.approved' => 'approved', // 'dropdown.not_approved' => 'not approved', // 'dropdown.paid' => 'paid', diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index e99954c44..4179add13 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -413,6 +413,8 @@ 'dropdown.status_inactive' => 'inactief', 'dropdown.delete' => 'verwijderen', 'dropdown.do_not_delete' => 'niet verwijderen', +// TODO: translate the following. +// 'dropdown.pending_approval' => 'pending approval', 'dropdown.approved' => 'goedgekeurd', 'dropdown.not_approved' => 'afgekeurd', 'dropdown.paid' => 'betaald', diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index 88a94a854..ba3734aa9 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -458,6 +458,7 @@ // TODO: translate the following. // 'dropdown.delete' => 'delete', // 'dropdown.do_not_delete' => 'do not delete', +// 'dropdown.pending_approval' => 'pending approval', // 'dropdown.approved' => 'approved', // 'dropdown.not_approved' => 'not approved', // 'dropdown.paid' => 'paid', diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index 3e92fe18d..669a3a5ed 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -440,6 +440,7 @@ 'dropdown.delete' => 'usuń', 'dropdown.do_not_delete' => 'nie usuwaj', // TODO: translate the following. +// 'dropdown.pending_approval' => 'pending approval', // 'dropdown.approved' => 'approved', // 'dropdown.not_approved' => 'not approved', // 'dropdown.paid' => 'paid', diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index 50fcec669..8adcf4aa9 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -435,6 +435,7 @@ 'dropdown.delete' => 'apagar', 'dropdown.do_not_delete' => 'não apagar', // TODO: translate the following. +// 'dropdown.pending_approval' => 'pending approval', // 'dropdown.approved' => 'approved', // 'dropdown.not_approved' => 'not approved', // 'dropdown.paid' => 'paid', diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index ca1813de9..9312fe181 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -441,6 +441,7 @@ // 'dropdown.status_inactive' => 'inactive', // 'dropdown.delete' => 'delete', // 'dropdown.do_not_delete' => 'do not delete', +// 'dropdown.pending_approval' => 'pending approval', // 'dropdown.approved' => 'approved', // 'dropdown.not_approved' => 'not approved', // 'dropdown.paid' => 'paid', diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index 3d0bace62..e8b7dadfd 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -461,6 +461,7 @@ // TODO: translate the following. // 'dropdown.delete' => 'delete', // 'dropdown.do_not_delete' => 'do not delete', +// 'dropdown.pending_approval' => 'pending approval', // 'dropdown.approved' => 'approved', // 'dropdown.not_approved' => 'not approved', // 'dropdown.paid' => 'paid', diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index f12aed108..4ee3aec21 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -394,6 +394,7 @@ 'dropdown.status_inactive' => 'неактивный', 'dropdown.delete' => 'удалить', 'dropdown.do_not_delete' => 'не удалять', +'dropdown.pending_approval' => 'в ожидании одобрения', 'dropdown.approved' => 'одобрено', 'dropdown.not_approved' => 'не одобрено', 'dropdown.paid' => 'оплачено', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index 63e2b6809..a378df653 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -445,6 +445,7 @@ // TODO: translate the following. // 'dropdown.delete' => 'delete', // 'dropdown.do_not_delete' => 'do not delete', +// 'dropdown.pending_approval' => 'pending approval', // 'dropdown.approved' => 'approved', // 'dropdown.not_approved' => 'not approved', // 'dropdown.paid' => 'paid', diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index e62892ba3..82fbc21b2 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -433,6 +433,7 @@ // 'dropdown.status_inactive' => 'inactive', // 'dropdown.delete' => 'delete', // 'dropdown.do_not_delete' => 'do not delete', +// 'dropdown.pending_approval' => 'pending approval', // 'dropdown.approved' => 'approved', // 'dropdown.not_approved' => 'not approved', // 'dropdown.paid' => 'paid', diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index dc4124373..02da7646c 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -438,6 +438,7 @@ 'dropdown.delete' => 'obriši', 'dropdown.do_not_delete' => 'nemoj obrisati', // TODO: translate the following. +// 'dropdown.pending_approval' => 'pending approval', // 'dropdown.approved' => 'approved', // 'dropdown.not_approved' => 'not approved', // 'dropdown.paid' => 'paid', diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index 645f0c4d2..1b6891fd9 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -437,6 +437,7 @@ 'dropdown.delete' => 'Ta bort', 'dropdown.do_not_delete' => 'Ta inte bort', // TODO: translate the following. +// 'dropdown.pending_approval' => 'pending approval', // 'dropdown.approved' => 'approved', // 'dropdown.not_approved' => 'not approved', // 'dropdown.paid' => 'paid', diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index 6cf2edb11..7f2af552e 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -469,6 +469,7 @@ // 'dropdown.status_inactive' => 'inactive', // 'dropdown.delete' => 'delete', // 'dropdown.do_not_delete' => 'do not delete', +// 'dropdown.pending_approval' => 'pending approval', // 'dropdown.approved' => 'approved', // 'dropdown.not_approved' => 'not approved', // 'dropdown.paid' => 'paid', diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index 62ebffef4..47bbae4ba 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -449,6 +449,7 @@ // 'dropdown.status_inactive' => 'inactive', // 'dropdown.delete' => 'delete', // 'dropdown.do_not_delete' => 'do not delete', +// 'dropdown.pending_approval' => 'pending approval', // 'dropdown.approved' => 'approved', // 'dropdown.not_approved' => 'not approved', // 'dropdown.paid' => 'paid', diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index 1b518ef36..8764492c3 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -454,6 +454,7 @@ // 'dropdown.status_inactive' => 'inactive', // 'dropdown.delete' => 'delete', // 'dropdown.do_not_delete' => 'do not delete', +// 'dropdown.pending_approval' => 'pending approval', // 'dropdown.approved' => 'approved', // 'dropdown.not_approved' => 'not approved', // 'dropdown.paid' => 'paid', diff --git a/WEB-INF/templates/admin_work_edit.tpl b/WEB-INF/templates/admin_work_edit.tpl index eb71e1171..8b7613e1d 100644 --- a/WEB-INF/templates/admin_work_edit.tpl +++ b/WEB-INF/templates/admin_work_edit.tpl @@ -27,7 +27,7 @@
{$i18n.label.budget} (*):{$forms.workForm.budget.control} {$i18n.label.what_is_it}{$forms.workForm.budget.control}
{$i18n.label.status}:
-
 Anuko Time Tracker 1.19.10.5106 | Copyright © Anuko | +  Anuko Time Tracker 1.19.10.5107 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 786dd793abe6c533d1824c009643b7857c458f44 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 25 Sep 2019 16:56:07 +0000 Subject: [PATCH 105/877] Fixed ttAdminWorkHelper::approveWork call. --- WEB-INF/lib/ttAdminWorkHelper.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WEB-INF/lib/ttAdminWorkHelper.class.php b/WEB-INF/lib/ttAdminWorkHelper.class.php index 29f41280d..7bf4171a5 100644 --- a/WEB-INF/lib/ttAdminWorkHelper.class.php +++ b/WEB-INF/lib/ttAdminWorkHelper.class.php @@ -537,7 +537,7 @@ function updateWork($fields) { } // approveWork - approves work item in remote work server. - function approveWork($work_id) { + function approveWork($fields) { global $i18n; global $user; $mdb2 = getConnection(); From fbab42d88779bcd346840722cd54511c5a1e714b Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 25 Sep 2019 18:50:29 +0000 Subject: [PATCH 106/877] Added admin_offer_edit.php. --- WEB-INF/lib/ttAdminWorkHelper.class.php | 190 +++++++++++++++++++++++- WEB-INF/templates/admin_offer_edit.tpl | 55 +++++++ WEB-INF/templates/footer.tpl | 2 +- admin_offer_edit.php | 141 ++++++++++++++++++ 4 files changed, 386 insertions(+), 2 deletions(-) create mode 100644 WEB-INF/templates/admin_offer_edit.tpl create mode 100644 admin_offer_edit.php diff --git a/WEB-INF/lib/ttAdminWorkHelper.class.php b/WEB-INF/lib/ttAdminWorkHelper.class.php index 7bf4171a5..446d741fe 100644 --- a/WEB-INF/lib/ttAdminWorkHelper.class.php +++ b/WEB-INF/lib/ttAdminWorkHelper.class.php @@ -473,7 +473,7 @@ function getOffer($offer_id) { return $offer; } - // updateWork - updates a work item in remote work server. + // updateWork - updates a work item in remote work server. function updateWork($fields) { global $i18n; global $user; @@ -659,4 +659,192 @@ function disapproveWork($fields) { return true; } + + // updateOffer - updates an offer in remote work server. + function updateOffer($fields) { + global $i18n; + global $user; + $mdb2 = getConnection(); + + $curl_fields = array('lang' => urlencode($user->lang), + 'site_id' => urlencode($this->site_id), + 'site_key' => urlencode($this->site_key), + 'user_id' => urlencode($user->id), + 'offer_id' => urlencode($fields['offer_id']), + 'subject' => urlencode(base64_encode($fields['subject'])), + 'descr_short' => urlencode(base64_encode($fields['descr_short'])), + 'descr_long' => urlencode(base64_encode($fields['descr_long'])), + 'currency' => urlencode($fields['currency']), + 'amount' => urlencode($fields['amount']), + 'moderator_comment' => urlencode(base64_encode($fields['moderator_comment'])), + 'modified_ip' => urlencode($_SERVER['REMOTE_ADDR']), + 'modified_by' => urlencode($user->getUser()), + 'modified_by_name' => urlencode(base64_encode($user->getName())), + 'modified_by_email' => urlencode(base64_encode($user->getEmail())) + ); + + // url-ify the data for the POST. + foreach($curl_fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; } + $fields_string = rtrim($fields_string, '&'); + + // Open connection. + $ch = curl_init(); + + // Set the url, number of POST vars, POST data. + curl_setopt($ch, CURLOPT_URL, $this->update_offer_uri); + curl_setopt($ch, CURLOPT_POST, true); + curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + + // Execute a post request. + $result = curl_exec($ch); + + // Close connection. + curl_close($ch); + + if (!$result) { + $this->errors->add($i18n->get('error.remote_work')); + return false; + } + + $result_array = json_decode($result, true); + + // Check for errors. + $call_status = $result_array['call_status']; + if (!$call_status) { + $this->errors->add($i18n->get('error.remote_work')); + return false; + } + if ($call_status['code'] != TT_CURL_SUCCESS) { + $this->errors->add($call_status['error']); + return false; + } + + return true; + } + + // approveOffer - approves offer in remote work server. + function approveOffer($fields) { + global $i18n; + global $user; + $mdb2 = getConnection(); + + $curl_fields = array('lang' => urlencode($user->lang), + 'site_id' => urlencode($this->site_id), + 'site_key' => urlencode($this->site_key), + 'user_id' => urlencode($user->id), + 'offer_id' => urlencode($fields['offer_id']), + 'subject' => urlencode(base64_encode($fields['subject'])), + 'descr_short' => urlencode(base64_encode($fields['descr_short'])), + 'descr_long' => urlencode(base64_encode($fields['descr_long'])), + 'currency' => urlencode($fields['currency']), + 'amount' => urlencode($fields['amount']), + 'moderator_comment' => urlencode(base64_encode($fields['moderator_comment'])), + 'modified_ip' => urlencode($_SERVER['REMOTE_ADDR']), + 'modified_by' => urlencode($user->getUser()), + 'modified_by_name' => urlencode(base64_encode($user->getName())), + 'modified_by_email' => urlencode(base64_encode($user->getEmail()))); + + // url-ify the data for the POST. + foreach($curl_fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; } + $fields_string = rtrim($fields_string, '&'); + + // Open connection. + $ch = curl_init(); + + // Set the url, number of POST vars, POST data. + curl_setopt($ch, CURLOPT_URL, $this->approve_offer_uri); + curl_setopt($ch, CURLOPT_POST, true); + curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + + // Execute a post request. + $result = curl_exec($ch); + + // Close connection. + curl_close($ch); + + if (!$result) { + $this->errors->add($i18n->get('error.remote_work')); + return false; + } + + $result_array = json_decode($result, true); + + // Check for errors. + $call_status = $result_array['call_status']; + if (!$call_status) { + $this->errors->add($i18n->get('error.remote_work')); + return false; + } + if ($call_status['code'] != TT_CURL_SUCCESS) { + $this->errors->add($call_status['error']); + return false; + } + + return true; + } + + + // disapproveOffer - disapproves offer in remote work server. + function disapproveOffer($fields) { + global $i18n; + global $user; + $mdb2 = getConnection(); + + $curl_fields = array('lang' => urlencode($user->lang), + 'site_id' => urlencode($this->site_id), + 'site_key' => urlencode($this->site_key), + 'user_id' => urlencode($user->id), + 'offer_id' => urlencode($fields['offer_id']), + 'subject' => urlencode(base64_encode($fields['subject'])), + 'descr_short' => urlencode(base64_encode($fields['descr_short'])), + 'descr_long' => urlencode(base64_encode($fields['descr_long'])), + 'currency' => urlencode($fields['currency']), + 'amount' => urlencode($fields['amount']), + 'moderator_comment' => urlencode(base64_encode($fields['moderator_comment'])), + 'modified_ip' => urlencode($_SERVER['REMOTE_ADDR']), + 'modified_by' => urlencode($user->getUser()), + 'modified_by_name' => urlencode(base64_encode($user->getName())), + 'modified_by_email' => urlencode(base64_encode($user->getEmail()))); + + // url-ify the data for the POST. + foreach($curl_fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; } + $fields_string = rtrim($fields_string, '&'); + + // Open connection. + $ch = curl_init(); + + // Set the url, number of POST vars, POST data. + curl_setopt($ch, CURLOPT_URL, $this->disapprove_offer_uri); + curl_setopt($ch, CURLOPT_POST, true); + curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + + // Execute a post request. + $result = curl_exec($ch); + + // Close connection. + curl_close($ch); + + if (!$result) { + $this->errors->add($i18n->get('error.remote_work')); + return false; + } + + $result_array = json_decode($result, true); + + // Check for errors. + $call_status = $result_array['call_status']; + if (!$call_status) { + $this->errors->add($i18n->get('error.remote_work')); + return false; + } + if ($call_status['code'] != TT_CURL_SUCCESS) { + $this->errors->add($call_status['error']); + return false; + } + + return true; + } } diff --git a/WEB-INF/templates/admin_offer_edit.tpl b/WEB-INF/templates/admin_offer_edit.tpl new file mode 100644 index 000000000..edf3e5328 --- /dev/null +++ b/WEB-INF/templates/admin_offer_edit.tpl @@ -0,0 +1,55 @@ +{$forms.offerForm.open} + + + + +
+ + + + + + + + + + + + + +{if $show_files} + + + + +{/if} + + + + + + + + + + + + + + + + + + + + + + + + + + + +
{$i18n.label.offer} (*):{$forms.offerForm.offer_name.control}
{$i18n.label.description}:{$forms.offerForm.description.control}
{$i18n.label.details}:{$forms.offerForm.details.control}
{$i18n.label.file}:{$forms.offerForm.newfile.control}
{$i18n.label.currency}:{$forms.offerForm.currency.control}
{$i18n.label.budget} (*):{$forms.offerForm.budget.control}
{$i18n.label.status}:{$forms.offerForm.status.control}
{$i18n.label.moderator_comment}:{$forms.offerForm.moderator_comment.control}
{$i18n.label.required_fields}
 
{$forms.offerForm.btn_save.control}
+
+{$forms.offerForm.close} diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 370602519..6a1b9a036 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.19.10.5107 | Copyright © Anuko | +  Anuko Time Tracker 1.19.10.5108 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/admin_offer_edit.php b/admin_offer_edit.php new file mode 100644 index 000000000..c47f3f1fa --- /dev/null +++ b/admin_offer_edit.php @@ -0,0 +1,141 @@ +getParameter('id'); +$adminWorkHelper = new ttAdminWorkHelper($err); +$offer = $adminWorkHelper->getOffer($cl_offer_id); +if (!$offer) { + header('Location: access_denied.php'); + exit(); +} +// End of access checks. + +// Status definitions. +define("STATUS_PENDING_APPROVAL", 4); +define("STATUS_DISAPPROVED", 8); +define("STATUS_APPROVED", 12); + +$existingStatus = $offer['status']; +$currencies = ttWorkHelper::getCurrencies(); + +if ($request->isPost()) { + $cl_name = trim($request->getParameter('offer_name')); + $cl_description = trim($request->getParameter('description')); + $cl_details = trim($request->getParameter('details')); + $cl_currency = $request->getParameter('currency'); + $cl_budget = $request->getParameter('budget'); + $cl_status = $request->getParameter('status'); + $cl_moderator_comment = $request->getParameter('moderator_comment'); +} else { + $cl_name = $offer['subject']; + $cl_description = $offer['descr_short']; + $cl_details = $offer['descr_long']; + $currency = $offer['currency']; + $cl_currency = array_search($currency, $currencies); + $cl_budget = $offer['amount']; + $cl_status = $offer['status']; + $cl_moderator_comment = $offer['moderator_comment']; +} + +$form = new Form('offerForm'); +$form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_offer_id)); +$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'offer_name','style'=>'width: 250px;','value'=>$cl_name)); +$form->addInput(array('type'=>'textarea','name'=>'description','style'=>'width: 250px; height: 40px;','value'=>$cl_description)); +$form->addInput(array('type'=>'textarea','name'=>'details','style'=>'width: 250px; height: 80px;','value'=>$cl_details)); +$form->addInput(array('type'=>'combobox','name'=>'currency','data'=>$currencies,'value'=>$cl_currency)); +$form->addInput(array('type'=>'floatfield','maxlength'=>'10','name'=>'budget','format'=>'.2','value'=>$cl_budget)); + +// Prepare status choices. +$status_options = array(); +$status_options[STATUS_PENDING_APPROVAL] = $i18n->get('dropdown.pending_approval'); +$status_options[STATUS_DISAPPROVED] = $i18n->get('dropdown.not_approved'); +$status_options[STATUS_APPROVED] = $i18n->get('dropdown.approved'); + +$form->addInput(array('type'=>'combobox','name'=>'status','value'=>$cl_status,'data'=>$status_options)); +$form->addInput(array('type'=>'textarea','name'=>'moderator_comment','style'=>'width: 250px; height: 80px;','value'=>$cl_moderator_comment)); +$form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); + +if ($request->isPost()) { + // Validate user input. + if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.work')); + if (!ttValidString($cl_description, true)) $err->add($i18n->get('error.field'), $i18n->get('label.description')); + if (!ttValidString($cl_details, true)) $err->add($i18n->get('error.field'), $i18n->get('label.details')); + if (!ttValidString($cl_budget)) $err->add($i18n->get('error.field'), $i18n->get('label.budget')); + if (!ttValidString($cl_moderator_comment, true)) $err->add($i18n->get('error.field'), $i18n->get('label.moderator_comment')); + + // Ensure user email exists (required for workflow). + if (!$user->getEmail()) $err->add($i18n->get('error.no_email')); + + if ($err->no()) { + if ($request->getParameter('btn_save')) { + $fields = array('offer_id'=>$cl_offer_id, + 'subject'=>$cl_name, + 'descr_short' => $cl_description, + 'descr_long' => $cl_details, + 'currency' => $currencies[$cl_currency], + 'amount' => $cl_budget, + 'moderator_comment' => $cl_moderator_comment); + + // Do things differently, depending on status control value. + if ($existingStatus == $cl_status) { + // Status not changed. Update work information. + if ($adminWorkHelper->updateOffer($fields)) { + header('Location: admin_work.php'); + exit(); + } + } else if ($cl_status == STATUS_DISAPPROVED) { + // Status changed to "not approved". Disapprove work. + if ($adminWorkHelper->disapproveOffer($fields)) { + header('Location: admin_work.php'); + exit(); + } + } else if ($cl_status == STATUS_APPROVED) { + // Status changed to "approved". Approve work. + if ($adminWorkHelper->approveOffer($fields)) { + header('Location: admin_work.php'); + exit(); + } + } + } + } +} // isPost + +$smarty->assign('forms', array($form->getName()=>$form->toArray())); +$smarty->assign('title', $i18n->get('title.edit_offer')); +$smarty->assign('content_page_name', 'admin_offer_edit.tpl'); +$smarty->display('index.tpl'); From 13d27f3b0d26a288240b592c1f476a4fd862c852 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 26 Sep 2019 10:54:16 +0000 Subject: [PATCH 107/877] Added audit info to some delete operations. --- WEB-INF/lib/ttExpenseHelper.class.php | 4 +++- WEB-INF/lib/ttInvoiceHelper.class.php | 10 ++++++---- WEB-INF/lib/ttTimeHelper.class.php | 4 +++- WEB-INF/templates/footer.tpl | 2 +- week.php | 2 +- 5 files changed, 14 insertions(+), 8 deletions(-) diff --git a/WEB-INF/lib/ttExpenseHelper.class.php b/WEB-INF/lib/ttExpenseHelper.class.php index e7da92cbb..b191fe379 100644 --- a/WEB-INF/lib/ttExpenseHelper.class.php +++ b/WEB-INF/lib/ttExpenseHelper.class.php @@ -95,7 +95,9 @@ static function markDeleted($id) { $group_id = $user->getGroup(); $org_id = $user->org_id; - $sql = "update tt_expense_items set status = null". + $modified_part = ', modified = now(), modified_ip = '.$mdb2->quote($_SERVER['REMOTE_ADDR']).', modified_by = '.$user->id; + + $sql = "update tt_expense_items set status = null".$modified_part. " where id = $id and user_id = $user_id and group_id = $group_id and org_id = $org_id"; $affected = $mdb2->exec($sql); return (!is_a($affected, 'PEAR_Error')); diff --git a/WEB-INF/lib/ttInvoiceHelper.class.php b/WEB-INF/lib/ttInvoiceHelper.class.php index a766a0f3e..833f15c3d 100644 --- a/WEB-INF/lib/ttInvoiceHelper.class.php +++ b/WEB-INF/lib/ttInvoiceHelper.class.php @@ -199,6 +199,8 @@ static function delete($invoice_id, $delete_invoice_items) { $group_id = $user->getGroup(); $org_id = $user->org_id; + $modified_part = ', modified = now(), modified_ip = '.$mdb2->quote($_SERVER['REMOTE_ADDR']).', modified_by = '.$user->id; + // Handle custom field log records. if ($delete_invoice_items) { $sql = "update tt_custom_field_log set status = null". @@ -210,10 +212,10 @@ static function delete($invoice_id, $delete_invoice_items) { // Handle time records. if ($delete_invoice_items) { - $sql = "update tt_log set status = null". + $sql = "update tt_log set status = null".$modified_part. " where invoice_id = $invoice_id and group_id = $group_id and org_id = $org_id"; } else { - $sql = "update tt_log set invoice_id = null". + $sql = "update tt_log set invoice_id = null".$modified_part. " where invoice_id = $invoice_id and group_id = $group_id and org_id = $org_id"; } $affected = $mdb2->exec($sql); @@ -221,10 +223,10 @@ static function delete($invoice_id, $delete_invoice_items) { // Handle expense items. if ($delete_invoice_items) { - $sql = "update tt_expense_items set status = null". + $sql = "update tt_expense_items set status = null".$modified_part. " where invoice_id = $invoice_id and group_id = $group_id and org_id = $org_id"; } else { - $sql = "update tt_expense_items set invoice_id = null". + $sql = "update tt_expense_items set invoice_id = null".$modified_part. " where invoice_id = $invoice_id and group_id = $group_id and org_id = $org_id"; } $affected = $mdb2->exec($sql); diff --git a/WEB-INF/lib/ttTimeHelper.class.php b/WEB-INF/lib/ttTimeHelper.class.php index 043e43462..6ed1721ee 100644 --- a/WEB-INF/lib/ttTimeHelper.class.php +++ b/WEB-INF/lib/ttTimeHelper.class.php @@ -567,7 +567,9 @@ static function delete($id) { $group_id = $user->getGroup(); $org_id = $user->org_id; - $sql = "update tt_log set status = null". + $modified_part = ', modified = now(), modified_ip = '.$mdb2->quote($_SERVER['REMOTE_ADDR']).', modified_by = '.$user->id; + + $sql = "update tt_log set status = null".$modified_part. " where id = $id and user_id = $user_id and group_id = $group_id and org_id = $org_id"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 6a1b9a036..39aa5caec 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.19.10.5108 | Copyright © Anuko | +  Anuko Time Tracker 1.19.10.5109 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/week.php b/week.php index 0fe376cc3..6b7cb1d90 100644 --- a/week.php +++ b/week.php @@ -468,7 +468,7 @@ function render(&$table, $value, $row, $column, $selected = false) { $result = ttWeekViewHelper::insertDurationFromWeekView($fields, $custom_fields, $err); } elseif ($postedDuration == null || 0 == ttTimeHelper::toMinutes($postedDuration)) { // Delete an already existing record here. - $result = ttTimeHelper::delete($dataArray[$rowNumber][$dayHeader]['tt_log_id'], $user->getUser()); + $result = ttTimeHelper::delete($dataArray[$rowNumber][$dayHeader]['tt_log_id']); } else { $fields = array(); $fields['tt_log_id'] = $dataArray[$rowNumber][$dayHeader]['tt_log_id']; From b681346e24bbbd487066e41cb8d618cbf7e3029e Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 26 Sep 2019 15:14:27 +0000 Subject: [PATCH 108/877] Added status output for active work and offers on work.php. --- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/work.tpl | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 39aa5caec..929798e3d 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- - + @@ -20,7 +20,7 @@ - + @@ -75,7 +75,7 @@ - + @@ -84,7 +84,7 @@ - + From e8847234f36b28d926dfbe5a4c134173894d152c Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 26 Sep 2019 17:04:37 +0000 Subject: [PATCH 109/877] Combined 4 API calls into 1. --- WEB-INF/lib/ttWorkHelper.class.php | 60 ++++++++++++++++++++++++++++++ WEB-INF/templates/footer.tpl | 2 +- work.php | 11 +++--- 3 files changed, 66 insertions(+), 7 deletions(-) diff --git a/WEB-INF/lib/ttWorkHelper.class.php b/WEB-INF/lib/ttWorkHelper.class.php index 8eee2da0f..151af26b1 100644 --- a/WEB-INF/lib/ttWorkHelper.class.php +++ b/WEB-INF/lib/ttWorkHelper.class.php @@ -45,6 +45,7 @@ class ttWorkHelper { var $get_offer_uri = null; // URI to get offer details. var $get_active_offers_uri = null; // URI to get active offers. var $get_available_offers_uri = null; // URI to get available offers. + var $get_group_items_uri = null; // URI to get all group items in one API call. var $delete_offer_uri = null; // URI to delete offer. var $delete_offers_uri = null; // URI to delete multiple offers. var $update_offer_uri = null; // URI to update offer. @@ -73,6 +74,7 @@ function __construct(&$errors) { $this->get_offer_uri = $this->remote_work_uri.'getoffer'; $this->get_active_offers_uri = $this->remote_work_uri.'getactiveoffers'; $this->get_available_offers_uri = $this->remote_work_uri.'getavailableoffers'; + $this->get_group_items_uri = $this->remote_work_uri.'getgroupitems'; $this->delete_offer_uri = $this->remote_work_uri.'deleteoffer'; $this->update_offer_uri = $this->remote_work_uri.'updateoffer'; $this->checkSiteRegistration(); @@ -929,4 +931,62 @@ static function getCurrencies() { } return $result; } + + // getGroupItems - obtains a list of all items relevant to group in one API call to Remote Work Server. + function getGroupItems() { + global $i18n; + global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $curl_fields = array('lang' => urlencode($user->lang), + 'site_id' => urlencode($this->site_id), + 'site_key' => urlencode($this->site_key), + 'org_id' => urlencode($org_id), + 'org_key' => urlencode($user->getOrgKey()), + 'group_id' => urlencode($group_id), + 'group_key' => urlencode($user->getGroupKey()) + ); + + // url-ify the data for the POST. + foreach($curl_fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; } + $fields_string = rtrim($fields_string, '&'); + + // Open connection. + $ch = curl_init(); + + // Set the url, number of POST vars, POST data. + curl_setopt($ch, CURLOPT_URL, $this->get_group_items_uri); + curl_setopt($ch, CURLOPT_POST, true); + curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + + // Execute a post request. + $result = curl_exec($ch); + + // Close connection. + curl_close($ch); + + if (!$result) { + $this->errors->add($i18n->get('error.remote_work')); + return false; + } + + $result_array = json_decode($result, true); + + // Check for errors. + $call_status = $result_array['call_status']; + if (!$call_status) { + $this->errors->add($i18n->get('error.remote_work')); + return false; + } + if ($call_status['code'] != TT_CURL_SUCCESS) { + $this->errors->add($call_status['error']); + return false; + } + + return $result_array; // Also contains 'call_status' element, probably okay to pass it to caller with useful payload. + } } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 929798e3d..3ee10fa1f 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.19.10.5109 | Copyright © Anuko | +  Anuko Time Tracker 1.19.10.5110 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/work.tpl b/WEB-INF/templates/work.tpl index 7a76975c0..9e9007c3c 100644 --- a/WEB-INF/templates/work.tpl +++ b/WEB-INF/templates/work.tpl @@ -11,7 +11,7 @@
{$i18n.label.work} {$i18n.label.description}{$i18n.label.client}{$i18n.label.status} {$i18n.label.budget}
{$work_item.subject|escape} {$work_item.description|escape}{$work_item.group_name|escape}{$work_item.status_label} {$work_item.amount_with_currency} {$i18n.label.edit} {$i18n.label.delete}
{$i18n.label.offer} {$i18n.label.description}{$i18n.label.contractor}{$i18n.label.status} {$i18n.label.budget}
{$offer.subject|escape} {$offer.description|escape}{$offer.group_name|escape}{$offer.status_label} {$offer.amount_with_currency} {$i18n.label.edit} {$i18n.label.delete}
-
 Anuko Time Tracker 1.19.10.5110 | Copyright © Anuko | +  Anuko Time Tracker 1.19.10.5111 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/work.php b/work.php index fab8ccb0d..606f8fbf9 100644 --- a/work.php +++ b/work.php @@ -41,20 +41,19 @@ // End of access checks. $workHelper = new ttWorkHelper($err); - +$groupItems = $workHelper->getGroupItems(); // All group items. if($user->can('manage_work')) { - $active_work = $workHelper->getActiveWork(); // Active work items this group is outsourcing. - $available_offers = $workHelper->getAvailableOffers(); // Available offers from other organizations. + $active_work = $groupItems['active_work']; // Active work items this group is outsourcing. + $available_offers = $groupItems['available_offers']; // Available offers from other organizations. } if($user->can('bid_on_work')) { - $available_work = $workHelper->getAvailableWork(); // Currently available work items from other orgs. - $active_offers = $workHelper->getActiveOffers(); // Active offers this group makes available to other groups. + $available_work = $groupItems['available_work']; // Currently available work items from other orgs. + $active_offers = $groupItems['active_offers']; // Active offers this group makes available to other groups. } if($user->can('update_work')) { // $in_progress_work = ttWorkHelper::getInProgressWork(); // Work items in progress for other groups. // $completed_work = ttWorkHelper::getCompletedWork(); // Completed work items for other groups. } -// $available_offers = ttWorkHelper::getAvailableOffers(); // Currently available offers to do work. // TODO: review access rights for the code above. $smarty->assign('active_work', $active_work); From 6c4f7b401d85c06d79838a0f2f4de6a2739f18ec Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 26 Sep 2019 18:10:09 +0000 Subject: [PATCH 110/877] Combined several API calls into one, added available work and offers on admin_work.php. --- WEB-INF/lib/ttAdminWorkHelper.class.php | 57 +++++++++++++++++++++++++ WEB-INF/templates/admin_work.tpl | 52 ++++++++++++++++++++++ WEB-INF/templates/footer.tpl | 2 +- admin_work.php | 9 +++- 4 files changed, 117 insertions(+), 3 deletions(-) diff --git a/WEB-INF/lib/ttAdminWorkHelper.class.php b/WEB-INF/lib/ttAdminWorkHelper.class.php index 446d741fe..db9f124df 100644 --- a/WEB-INF/lib/ttAdminWorkHelper.class.php +++ b/WEB-INF/lib/ttAdminWorkHelper.class.php @@ -46,6 +46,7 @@ class ttAdminWorkHelper { var $disapprove_offer_uri = null; // URI to disapprove offer. var $get_pending_work_uri = null; // URI to get work pending approval. var $get_pending_offers_uri = null; // URI to get offers pending approval. + var $get_admin_items_uri = null; // URI to get all admin items in one API call. var $site_id = null; // Site id for remote work server. var $site_key = null; // Site key for remote work server. @@ -67,6 +68,7 @@ function __construct(&$errors) { $this->disapprove_offer_uri = $this->remote_work_uri.'admin_disapproveoffer'; $this->get_pending_work_uri = $this->remote_work_uri.'admin_getpendingwork'; $this->get_pending_offers_uri = $this->remote_work_uri.'admin_getpendingoffers'; + $this->get_admin_items_uri = $this->remote_work_uri.'admin_getitems'; $this->checkSiteRegistration(); } @@ -847,4 +849,59 @@ function disapproveOffer($fields) { return true; } + + // getAdminItems - obtains a list of all items relevant to admin in one API call to Remote Work Server. + function getAdminItems() { + global $i18n; + global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $curl_fields = array('lang' => urlencode($user->lang), + 'site_id' => urlencode($this->site_id), + 'site_key' => urlencode($this->site_key), + 'user_id' => urlencode($user->id) + ); + + // url-ify the data for the POST. + foreach($curl_fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; } + $fields_string = rtrim($fields_string, '&'); + + // Open connection. + $ch = curl_init(); + + // Set the url, number of POST vars, POST data. + curl_setopt($ch, CURLOPT_URL, $this->get_admin_items_uri); + curl_setopt($ch, CURLOPT_POST, true); + curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + + // Execute a post request. + $result = curl_exec($ch); + + // Close connection. + curl_close($ch); + + if (!$result) { + $this->errors->add($i18n->get('error.remote_work')); + return false; + } + + $result_array = json_decode($result, true); + + // Check for errors. + $call_status = $result_array['call_status']; + if (!$call_status) { + $this->errors->add($i18n->get('error.remote_work')); + return false; + } + if ($call_status['code'] != TT_CURL_SUCCESS) { + $this->errors->add($call_status['error']); + return false; + } + + return $result_array; // Also contains 'call_status' element, probably okay to pass it to caller with useful payload. + } } diff --git a/WEB-INF/templates/admin_work.tpl b/WEB-INF/templates/admin_work.tpl index b3ec7f4b4..bcc77e88b 100644 --- a/WEB-INF/templates/admin_work.tpl +++ b/WEB-INF/templates/admin_work.tpl @@ -55,6 +55,58 @@
{/if} +
+ + + +{if $available_work} + + + + + + + + + {foreach $available_work as $work_item} + + + + + + + + + {/foreach} +{/if} +
{$i18n.title.available_work}
{$i18n.label.work}{$i18n.label.description}{$i18n.label.client}{$i18n.label.budget}
{$work_item.subject|escape}{$work_item.description|escape}{$work_item.group_name|escape}{$work_item.amount_with_currency}
+ +
+ + + +{if $available_offers} + + + + + + + + + {foreach $active_offers as $offer} + + + + + + + + + {/foreach} +{/if} +
{$i18n.title.available_offers}
{$i18n.label.offer}{$i18n.label.description}{$i18n.label.status}{$i18n.label.budget}
{$offer.subject|escape}{$offer.description|escape}{$offer.status_label}{$offer.amount_with_currency}{$i18n.label.edit}{$i18n.label.delete}
+
diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 3ee10fa1f..7ff0bc104 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- - {foreach $active_offers as $offer} + {foreach $available_offers as $offer} From 63d0aa73172c267c8320fd0b1416c18c4adb960d Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 26 Sep 2019 18:24:11 +0000 Subject: [PATCH 112/877] Presentation fixed on admin_work.php. --- WEB-INF/templates/admin_work.tpl | 8 ++++---- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/WEB-INF/templates/admin_work.tpl b/WEB-INF/templates/admin_work.tpl index cbc015c30..5bb4e4297 100644 --- a/WEB-INF/templates/admin_work.tpl +++ b/WEB-INF/templates/admin_work.tpl @@ -89,7 +89,7 @@ - + @@ -98,10 +98,10 @@ - + - - + + {/foreach} {/if} diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 7ff0bc104..559dc8418 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.19.10.5111 | Copyright © Anuko | +  Anuko Time Tracker 1.19.10.5112 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/admin_work.php b/admin_work.php index b1723912d..f85a1f99e 100644 --- a/admin_work.php +++ b/admin_work.php @@ -38,11 +38,16 @@ $adminWorkHelper = new ttAdminWorkHelper($err); -$pending_work = $adminWorkHelper->getPendingWork(); -$pending_offers = $adminWorkHelper->getPendingOffers(); +$adminItems = $adminWorkHelper->getAdminItems(); +$pending_work = $adminItems['pending_work']; +$pending_offers = $adminItems['pending_offers']; +$available_work = $adminItems['available_work']; +$available_offers = $adminItems['available_offers']; $smarty->assign('pending_work', $pending_work); $smarty->assign('pending_offers', $pending_offers); +$smarty->assign('available_work', $available_work); +$smarty->assign('available_offers', $available_offers); $smarty->assign('title', $i18n->get('title.work')); $smarty->assign('content_page_name', 'admin_work.tpl'); $smarty->display('index.tpl'); From d7c4b9e7fb5202646f90a296ad53676f68835f70 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 26 Sep 2019 18:17:44 +0000 Subject: [PATCH 111/877] Fixed presentation of available offers on admin_work.php. --- WEB-INF/templates/admin_work.tpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WEB-INF/templates/admin_work.tpl b/WEB-INF/templates/admin_work.tpl index bcc77e88b..cbc015c30 100644 --- a/WEB-INF/templates/admin_work.tpl +++ b/WEB-INF/templates/admin_work.tpl @@ -94,7 +94,7 @@
{$offer.subject|escape} {$offer.description|escape}
{$i18n.label.offer} {$i18n.label.description}{$i18n.label.status}{$i18n.label.contractor} {$i18n.label.budget}
{$offer.subject|escape} {$offer.description|escape}{$offer.status_label}{$offer.group_name|escape} {$offer.amount_with_currency}{$i18n.label.edit}{$i18n.label.delete}
-
 Anuko Time Tracker 1.19.10.5112 | Copyright © Anuko | +  Anuko Time Tracker 1.19.10.5113 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From cb96f3ea7430df12bba172c1457a5ae97782be9b Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 26 Sep 2019 19:24:11 +0000 Subject: [PATCH 113/877] A bit of refactoring. --- WEB-INF/lib/ttAdminWorkHelper.class.php | 10 +++++----- WEB-INF/templates/footer.tpl | 2 +- admin_work.php | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/WEB-INF/lib/ttAdminWorkHelper.class.php b/WEB-INF/lib/ttAdminWorkHelper.class.php index db9f124df..474f124c0 100644 --- a/WEB-INF/lib/ttAdminWorkHelper.class.php +++ b/WEB-INF/lib/ttAdminWorkHelper.class.php @@ -46,7 +46,7 @@ class ttAdminWorkHelper { var $disapprove_offer_uri = null; // URI to disapprove offer. var $get_pending_work_uri = null; // URI to get work pending approval. var $get_pending_offers_uri = null; // URI to get offers pending approval. - var $get_admin_items_uri = null; // URI to get all admin items in one API call. + var $get_items_uri = null; // URI to get all admin items in one API call. var $site_id = null; // Site id for remote work server. var $site_key = null; // Site key for remote work server. @@ -68,7 +68,7 @@ function __construct(&$errors) { $this->disapprove_offer_uri = $this->remote_work_uri.'admin_disapproveoffer'; $this->get_pending_work_uri = $this->remote_work_uri.'admin_getpendingwork'; $this->get_pending_offers_uri = $this->remote_work_uri.'admin_getpendingoffers'; - $this->get_admin_items_uri = $this->remote_work_uri.'admin_getitems'; + $this->get_items_uri = $this->remote_work_uri.'admin_getitems'; $this->checkSiteRegistration(); } @@ -850,8 +850,8 @@ function disapproveOffer($fields) { return true; } - // getAdminItems - obtains a list of all items relevant to admin in one API call to Remote Work Server. - function getAdminItems() { + // getItems - obtains a list of all items relevant to admin in one API call to Remote Work Server. + function getItems() { global $i18n; global $user; $mdb2 = getConnection(); @@ -873,7 +873,7 @@ function getAdminItems() { $ch = curl_init(); // Set the url, number of POST vars, POST data. - curl_setopt($ch, CURLOPT_URL, $this->get_admin_items_uri); + curl_setopt($ch, CURLOPT_URL, $this->get_items_uri); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 559dc8418..63aeda8a0 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.19.10.5113 | Copyright © Anuko | +  Anuko Time Tracker 1.19.10.5114 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/admin_work.php b/admin_work.php index f85a1f99e..fd0b7b05c 100644 --- a/admin_work.php +++ b/admin_work.php @@ -38,7 +38,7 @@ $adminWorkHelper = new ttAdminWorkHelper($err); -$adminItems = $adminWorkHelper->getAdminItems(); +$adminItems = $adminWorkHelper->getItems(); $pending_work = $adminItems['pending_work']; $pending_offers = $adminItems['pending_offers']; $available_work = $adminItems['available_work']; From 950409abe22615155a5587fd9ba057d4cf528296 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 26 Sep 2019 19:51:09 +0000 Subject: [PATCH 114/877] Removed call_status element from arrays that 2 functions return. --- WEB-INF/lib/ttWorkHelper.class.php | 3 ++- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/WEB-INF/lib/ttWorkHelper.class.php b/WEB-INF/lib/ttWorkHelper.class.php index 151af26b1..a4ef1f6e2 100644 --- a/WEB-INF/lib/ttWorkHelper.class.php +++ b/WEB-INF/lib/ttWorkHelper.class.php @@ -987,6 +987,7 @@ function getGroupItems() { return false; } - return $result_array; // Also contains 'call_status' element, probably okay to pass it to caller with useful payload. + unset($result_array['call_status']); // Remove call_status element, + return $result_array; } } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 63aeda8a0..6858bebba 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.19.10.5114 | Copyright © Anuko | +  Anuko Time Tracker 1.19.10.5115 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 6071c383750c11836c9cd90d958f5f960620f21e Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 26 Sep 2019 19:54:28 +0000 Subject: [PATCH 115/877] Forgot to check in one file. --- WEB-INF/lib/ttAdminWorkHelper.class.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/WEB-INF/lib/ttAdminWorkHelper.class.php b/WEB-INF/lib/ttAdminWorkHelper.class.php index 474f124c0..cdd517c40 100644 --- a/WEB-INF/lib/ttAdminWorkHelper.class.php +++ b/WEB-INF/lib/ttAdminWorkHelper.class.php @@ -902,6 +902,7 @@ function getItems() { return false; } - return $result_array; // Also contains 'call_status' element, probably okay to pass it to caller with useful payload. + unset($result_array['call_status']); // Remove call_status element. + return $result_array; } } From f1da282b00744172e9877a76462263871badb457 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 26 Sep 2019 20:52:18 +0000 Subject: [PATCH 116/877] Added status and moderator comment on work_edit.php. --- WEB-INF/lib/form/TextArea.class.php | 2 +- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/work_edit.tpl | 8 ++++++++ work_edit.php | 6 ++++++ 4 files changed, 16 insertions(+), 2 deletions(-) diff --git a/WEB-INF/lib/form/TextArea.class.php b/WEB-INF/lib/form/TextArea.class.php index be884f0d8..ee68fcb87 100644 --- a/WEB-INF/lib/form/TextArea.class.php +++ b/WEB-INF/lib/form/TextArea.class.php @@ -57,7 +57,7 @@ function getHtml() { if ($this->mOnKeyPress) { $html .= " onkeypress=\"$this->mOnKeyPress\""; } - + if(!$this->isEnabled()) $html .= " readonly"; $html .= ">".htmlspecialchars($this->getValue()).""; return $html; diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 6858bebba..3786693b8 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- + + + + + + + + diff --git a/work_edit.php b/work_edit.php index 74c9d08fa..3d057770c 100644 --- a/work_edit.php +++ b/work_edit.php @@ -63,6 +63,8 @@ $currency = $work_item['currency']; $cl_currency = array_search($currency, $currencies); $cl_budget = $work_item['amount']; + $cl_status = $work_item['status_label']; + $cl_moderator_comment = $work_item['moderator_comment']; } $form = new Form('workForm'); @@ -72,6 +74,10 @@ $form->addInput(array('type'=>'textarea','name'=>'details','style'=>'width: 250px; height: 80px;','value'=>$cl_details)); $form->addInput(array('type'=>'combobox','name'=>'currency','data'=>$currencies,'value'=>$cl_currency)); $form->addInput(array('type'=>'floatfield','maxlength'=>'10','name'=>'budget','format'=>'.2','value'=>$cl_budget)); +$form->addInput(array('type'=>'text','name'=>'status','value'=>$cl_status)); +$form->getElement('status')->setEnabled(false); +$form->addInput(array('type'=>'textarea','name'=>'moderator_comment','style'=>'width: 250px; height: 80px;','value'=>$cl_moderator_comment)); +$form->getElement('moderator_comment')->setEnabled(false); $form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); if ($request->isPost()) { From ee4bec8160ae2cad5611c299372ff06ecec8f74c Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 27 Sep 2019 11:41:45 +0000 Subject: [PATCH 117/877] Added status and moderator comment on offer_edit.php. --- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/offer_edit.tpl | 10 ++++++++++ WEB-INF/templates/work_edit.tpl | 2 ++ offer_edit.php | 9 +++++++++ work_edit.php | 3 +++ 5 files changed, 25 insertions(+), 1 deletion(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 3786693b8..2552ec237 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.19.10.5115 | Copyright © Anuko | +  Anuko Time Tracker 1.19.10.5116 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/work_edit.tpl b/WEB-INF/templates/work_edit.tpl index 9aaaa85f7..eb71e1171 100644 --- a/WEB-INF/templates/work_edit.tpl +++ b/WEB-INF/templates/work_edit.tpl @@ -29,6 +29,14 @@ {$i18n.label.budget} (*): {$forms.workForm.budget.control} {$i18n.label.what_is_it}
{$i18n.label.status}:{$forms.workForm.status.control}
{$i18n.label.moderator_comment}:{$forms.workForm.moderator_comment.control}
{$i18n.label.required_fields}
- + + + + +{if $show_moderator_comment} + + + + +{/if} diff --git a/WEB-INF/templates/work_edit.tpl b/WEB-INF/templates/work_edit.tpl index eb71e1171..48e4456fb 100644 --- a/WEB-INF/templates/work_edit.tpl +++ b/WEB-INF/templates/work_edit.tpl @@ -33,10 +33,12 @@ +{if $show_moderator_comment} +{/if} diff --git a/offer_edit.php b/offer_edit.php index abdb195d5..729b79d03 100644 --- a/offer_edit.php +++ b/offer_edit.php @@ -65,8 +65,12 @@ $cl_currency = array_search($currency, $currencies); $cl_budget = $offer['amount']; $cl_payment_info = $offer['payment_info']; + $cl_status = $offer['status_label']; + $cl_moderator_comment = $offer['moderator_comment']; } +$show_moderator_comment = $cl_moderator_comment != null; + $form = new Form('offerForm'); $form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_offer_id)); $form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'offer_name','style'=>'width: 250px;','value'=>$cl_name)); @@ -75,6 +79,10 @@ $form->addInput(array('type'=>'combobox','name'=>'currency','data'=>$currencies,'value'=>$cl_currency)); $form->addInput(array('type'=>'floatfield','maxlength'=>'10','name'=>'budget','format'=>'.2','value'=>$cl_budget)); $form->addInput(array('type'=>'textarea','name'=>'payment_info','style'=>'width: 250px; height: 40px;vertical-align: middle','value'=>$cl_payment_info)); +$form->addInput(array('type'=>'text','name'=>'status','value'=>$cl_status)); +$form->getElement('status')->setEnabled(false); +$form->addInput(array('type'=>'textarea','name'=>'moderator_comment','style'=>'width: 250px; height: 80px;','value'=>$cl_moderator_comment)); +$form->getElement('moderator_comment')->setEnabled(false); $form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); if ($request->isPost()) { @@ -106,6 +114,7 @@ } } // isPost +$smarty->assign('show_moderator_comment', $show_moderator_comment); $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('title', $i18n->get('title.edit_offer')); $smarty->assign('content_page_name', 'offer_edit.tpl'); diff --git a/work_edit.php b/work_edit.php index 3d057770c..eda443716 100644 --- a/work_edit.php +++ b/work_edit.php @@ -67,6 +67,8 @@ $cl_moderator_comment = $work_item['moderator_comment']; } +$show_moderator_comment = $cl_moderator_comment != null; + $form = new Form('workForm'); $form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_work_id)); $form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'work_name','style'=>'width: 250px;','value'=>$cl_name)); @@ -107,6 +109,7 @@ } } // isPost +$smarty->assign('show_moderator_comment', $show_moderator_comment); $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('title', $i18n->get('title.edit_work')); $smarty->assign('content_page_name', 'work_edit.tpl'); From 48f53308625e6d2a79df941405287cc3c2a20536 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 27 Sep 2019 17:46:52 +0000 Subject: [PATCH 118/877] Cosmetic, removed unused columns. --- WEB-INF/templates/admin_work.tpl | 12 ++---------- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/work.tpl | 16 ++++------------ 3 files changed, 7 insertions(+), 23 deletions(-) diff --git a/WEB-INF/templates/admin_work.tpl b/WEB-INF/templates/admin_work.tpl index 5bb4e4297..656899261 100644 --- a/WEB-INF/templates/admin_work.tpl +++ b/WEB-INF/templates/admin_work.tpl @@ -65,17 +65,13 @@ - - {foreach $available_work as $work_item} - - - + {/foreach} {/if} @@ -91,17 +87,13 @@ - - {foreach $available_offers as $offer} - - - + {/foreach} {/if} diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 2552ec237..053b8ade1 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.19.10.5116 | Copyright © Anuko | +  Anuko Time Tracker 1.19.10.5117 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/offer_edit.tpl b/WEB-INF/templates/offer_edit.tpl index fb406d1b0..75f7a0532 100644 --- a/WEB-INF/templates/offer_edit.tpl +++ b/WEB-INF/templates/offer_edit.tpl @@ -27,6 +27,16 @@ {$i18n.label.how_to_pay} (*): {$forms.offerForm.payment_info.control} {$i18n.label.what_is_it}
{$i18n.label.status}:{$forms.offerForm.status.control}
{$i18n.label.moderator_comment}:{$forms.offerForm.moderator_comment.control}
{$i18n.label.required_fields}{$i18n.label.status}: {$forms.workForm.status.control}
{$i18n.label.moderator_comment}: {$forms.workForm.moderator_comment.control}
{$i18n.label.required_fields}{$i18n.label.description} {$i18n.label.client} {$i18n.label.budget}
{$work_item.subject|escape} {$work_item.description|escape} {$work_item.group_name|escape}{$work_item.amount_with_currency}{$work_item.amount_with_currency}
{$i18n.label.description} {$i18n.label.contractor} {$i18n.label.budget}
{$offer.subject|escape} {$offer.description|escape} {$offer.group_name|escape}{$offer.amount_with_currency}{$offer.amount_with_currency}
- - + @@ -45,17 +45,13 @@ - - {foreach $available_work as $work_item} - - - + {/foreach} {/if} @@ -85,7 +81,7 @@ - + @@ -109,17 +105,13 @@ - - {foreach $available_offers as $offer} - - - + {/foreach} {/if} From 854157742719af47505be8fb4cc191bec5c00ae8 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 27 Sep 2019 17:53:29 +0000 Subject: [PATCH 119/877] Improved styling for table divider div. --- WEB-INF/templates/admin_work.tpl | 6 +++--- WEB-INF/templates/footer.tpl | 2 +- default.css | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/WEB-INF/templates/admin_work.tpl b/WEB-INF/templates/admin_work.tpl index 656899261..16b4d4434 100644 --- a/WEB-INF/templates/admin_work.tpl +++ b/WEB-INF/templates/admin_work.tpl @@ -29,7 +29,7 @@
 Anuko Time Tracker 1.19.10.5117 | Copyright © Anuko | +  Anuko Time Tracker 1.19.10.5118 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/work.tpl b/WEB-INF/templates/work.tpl index 9e9007c3c..f371eb8af 100644 --- a/WEB-INF/templates/work.tpl +++ b/WEB-INF/templates/work.tpl @@ -21,7 +21,7 @@ {$work_item.subject|escape} {$work_item.description|escape} {$work_item.status_label}{$work_item.amount_with_currency}{$work_item.amount_with_currency} {$i18n.label.edit} {$i18n.label.delete}
{$i18n.label.description} {$i18n.label.client} {$i18n.label.budget}
{$work_item.subject|escape} {$work_item.description|escape} {$work_item.group_name|escape}{$work_item.amount_with_currency}{$work_item.amount_with_currency}
{$offer.subject|escape} {$offer.description|escape} {$offer.status_label}{$offer.amount_with_currency}{$offer.amount_with_currency} {$i18n.label.edit} {$i18n.label.delete}
{$i18n.label.description} {$i18n.label.contractor} {$i18n.label.budget}
{$offer.subject|escape} {$offer.description|escape} {$offer.group_name|escape}{$offer.amount_with_currency}{$offer.amount_with_currency}
{/if} -
+
{if $pending_offers} @@ -55,7 +55,7 @@
{/if} -
+
@@ -77,7 +77,7 @@ {/if}
{$i18n.title.available_work}
-
+
diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 053b8ade1..9432194d3 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
{$i18n.title.available_offers}
-
 Anuko Time Tracker 1.19.10.5118 | Copyright © Anuko | +  Anuko Time Tracker 1.19.10.5119 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/default.css b/default.css index cf448abcf..89b3fa645 100644 --- a/default.css +++ b/default.css @@ -144,7 +144,7 @@ input[type=checkbox], label { background-color: #efefef; } -div#TableDivider { height: 30px; } +div.table-divider { height: 30px; } div#LoginAboutText { width: 400px; } From 6421067fb119007de8d461f85def1e6bc2d98795 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 27 Sep 2019 18:22:46 +0000 Subject: [PATCH 120/877] Introduced work_constants.php file for status definitions. --- WEB-INF/templates/footer.tpl | 2 +- admin_offer_edit.php | 6 +----- admin_work_edit.php | 5 +---- plugins/work_constants.php | 36 ++++++++++++++++++++++++++++++++++++ 4 files changed, 39 insertions(+), 10 deletions(-) create mode 100644 plugins/work_constants.php diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 9432194d3..c557d4200 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.19.10.5119 | Copyright © Anuko | +  Anuko Time Tracker 1.19.10.5120 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/admin_offer_edit.php b/admin_offer_edit.php index c47f3f1fa..15afe8ae6 100644 --- a/admin_offer_edit.php +++ b/admin_offer_edit.php @@ -27,6 +27,7 @@ // +----------------------------------------------------------------------+ require_once('initialize.php'); +require 'plugins/work_constants.php'; import('form.Form'); import('ttWorkHelper'); import('ttAdminWorkHelper'); @@ -45,11 +46,6 @@ } // End of access checks. -// Status definitions. -define("STATUS_PENDING_APPROVAL", 4); -define("STATUS_DISAPPROVED", 8); -define("STATUS_APPROVED", 12); - $existingStatus = $offer['status']; $currencies = ttWorkHelper::getCurrencies(); diff --git a/admin_work_edit.php b/admin_work_edit.php index 0eb38f887..d158b8037 100644 --- a/admin_work_edit.php +++ b/admin_work_edit.php @@ -27,6 +27,7 @@ // +----------------------------------------------------------------------+ require_once('initialize.php'); +require 'plugins/work_constants.php'; import('form.Form'); import('ttWorkHelper'); import('ttAdminWorkHelper'); @@ -45,10 +46,6 @@ } // End of access checks. -// Status definitions. -define("STATUS_PENDING_APPROVAL", 4); -define("STATUS_DISAPPROVED", 8); -define("STATUS_APPROVED", 12); $existingStatus = $work_item['status']; $currencies = ttWorkHelper::getCurrencies(); diff --git a/plugins/work_constants.php b/plugins/work_constants.php new file mode 100644 index 000000000..207ca5d35 --- /dev/null +++ b/plugins/work_constants.php @@ -0,0 +1,36 @@ + Date: Fri, 27 Sep 2019 21:17:50 +0000 Subject: [PATCH 121/877] Started on work_view.php. --- WEB-INF/lib/ttWorkHelper.class.php | 58 +++++++++++++++++++++++++ WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/work.tpl | 2 +- WEB-INF/templates/work_view.tpl | 32 ++++++++++++++ work_view.php | 70 ++++++++++++++++++++++++++++++ 5 files changed, 162 insertions(+), 2 deletions(-) create mode 100644 WEB-INF/templates/work_view.tpl create mode 100644 work_view.php diff --git a/WEB-INF/lib/ttWorkHelper.class.php b/WEB-INF/lib/ttWorkHelper.class.php index a4ef1f6e2..5d235bca7 100644 --- a/WEB-INF/lib/ttWorkHelper.class.php +++ b/WEB-INF/lib/ttWorkHelper.class.php @@ -38,6 +38,7 @@ class ttWorkHelper { var $get_work_uri = null; // URI to get work details. var $get_active_work_uri = null; // URI to get active work for group. var $get_available_work_uri = null; // URI to get available work for group. + var $get_available_work_item_uri = null; // URI to get a single available work item. var $delete_work_uri = null; // URI to delete work. // TODO: design how (and what) to delete when a group is deleted. var $update_work_uri = null; // URI to update work. @@ -68,6 +69,7 @@ function __construct(&$errors) { $this->get_work_uri = $this->remote_work_uri.'getwork'; $this->get_active_work_uri = $this->remote_work_uri.'getactivework'; $this->get_available_work_uri = $this->remote_work_uri.'getavailablework'; + $this->get_available_work_item_uri = $this->remote_work_uri.'getavailableworkitem'; $this->delete_work_uri = $this->remote_work_uri.'deletework'; $this->update_work_uri = $this->remote_work_uri.'updatework'; $this->put_offer_uri = $this->remote_work_uri.'putoffer'; @@ -990,4 +992,60 @@ function getGroupItems() { unset($result_array['call_status']); // Remove call_status element, return $result_array; } + + // getAvailableWorkItem - gets available work item details from remote work server. + function getAvailableWorkItem($work_id) { + global $i18n; + global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $curl_fields = array('lang' => urlencode($user->lang), + 'site_id' => urlencode($this->site_id), + 'site_key' => urlencode($this->site_key), + 'org_id' => urlencode($org_id), + 'work_id' => urlencode($work_id)); + + // url-ify the data for the POST. + foreach($curl_fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; } + $fields_string = rtrim($fields_string, '&'); + + // Open connection. + $ch = curl_init(); + + // Set the url, number of POST vars, POST data. + curl_setopt($ch, CURLOPT_URL, $this->get_available_work_item_uri); + curl_setopt($ch, CURLOPT_POST, true); + curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + + // Execute a post request. + $result = curl_exec($ch); + + // Close connection. + curl_close($ch); + + if (!$result) { + $this->errors->add($i18n->get('error.remote_work')); + return false; + } + + $result_array = json_decode($result, true); + + // Check for errors. + $call_status = $result_array['call_status']; + if (!$call_status) { + $this->errors->add($i18n->get('error.remote_work')); + return false; + } + if ($call_status['code'] != TT_CURL_SUCCESS) { + $this->errors->add($call_status['error']); + return false; + } + + $work_item = $result_array['work_item']; + return $work_item; + } } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index c557d4200..0497df220 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- {foreach $available_work as $work_item} - + diff --git a/WEB-INF/templates/work_view.tpl b/WEB-INF/templates/work_view.tpl new file mode 100644 index 000000000..8c2edb6ae --- /dev/null +++ b/WEB-INF/templates/work_view.tpl @@ -0,0 +1,32 @@ +{$forms.workForm.open} +
 Anuko Time Tracker 1.19.10.5120 | Copyright © Anuko | +  Anuko Time Tracker 1.19.10.5121 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/work.tpl b/WEB-INF/templates/work.tpl index f371eb8af..c0c516bde 100644 --- a/WEB-INF/templates/work.tpl +++ b/WEB-INF/templates/work.tpl @@ -48,7 +48,7 @@
{$work_item.subject|escape}{$work_item.subject|escape} {$work_item.description|escape} {$work_item.group_name|escape} {$work_item.amount_with_currency}
+ + + +
+ + + + + + + + + + + + + +{if $show_files} + + + + +{/if} + + + + +
{$i18n.label.work}:{$forms.workForm.work_name.control}
{$i18n.label.description}:{$forms.workForm.description.control}
{$i18n.label.details}:{$forms.workForm.details.control}
{$i18n.label.file}:{$forms.workForm.newfile.control}
{$i18n.label.budget}:{$forms.workForm.budget.control}
+
+{$forms.workForm.close} diff --git a/work_view.php b/work_view.php new file mode 100644 index 000000000..5c9ff06dd --- /dev/null +++ b/work_view.php @@ -0,0 +1,70 @@ +isPluginEnabled('wk')) { + header('Location: feature_disabled.php'); + exit(); +} +if (!ttAccessAllowed('bid_on_work')) { + header('Location: access_denied.php'); + exit(); +} +$cl_work_id = (int)$request->getParameter('id'); +$workHelper = new ttWorkHelper($err); +$work_item = $workHelper->getAvailableWorkItem($cl_work_id); +if (!$work_item) { + header('Location: access_denied.php'); + exit(); +} +// End of access checks. + +$cl_name = $work_item['subject']; +$cl_description = $work_item['descr_short']; +$cl_details = $work_item['descr_long']; +$cl_budget = $work_item['amount_with_currency']; + +$form = new Form('workForm'); +$form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_work_id)); +$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'work_name','style'=>'width: 250px;','value'=>$cl_name)); +$form->getElement('work_name')->setEnabled(false); +$form->addInput(array('type'=>'textarea','name'=>'description','style'=>'width: 250px; height: 40px;','value'=>$cl_description)); +$form->getElement('description')->setEnabled(false); +$form->addInput(array('type'=>'textarea','name'=>'details','style'=>'width: 250px; height: 80px;','value'=>$cl_details)); +$form->getElement('details')->setEnabled(false); +$form->addInput(array('type'=>'text','name'=>'budget','value'=>$cl_budget)); +$form->getElement('budget')->setEnabled(false); + +$smarty->assign('forms', array($form->getName()=>$form->toArray())); +$smarty->assign('title', $i18n->get('title.work')); +$smarty->assign('content_page_name', 'work_view.tpl'); +$smarty->display('index.tpl'); From 9e6aaeec1c26a4442cdc711a6b7b0727d4ba4c53 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 27 Sep 2019 22:24:18 +0000 Subject: [PATCH 122/877] Added offer_view.php. --- WEB-INF/lib/ttWorkHelper.class.php | 58 ++++++++++++++++++++++++ WEB-INF/resources/ca.lang.php | 1 + WEB-INF/resources/cs.lang.php | 1 + WEB-INF/resources/da.lang.php | 1 + WEB-INF/resources/de.lang.php | 1 + WEB-INF/resources/en.lang.php | 1 + WEB-INF/resources/es.lang.php | 1 + WEB-INF/resources/et.lang.php | 1 + WEB-INF/resources/fa.lang.php | 1 + WEB-INF/resources/fi.lang.php | 1 + WEB-INF/resources/fr.lang.php | 1 + WEB-INF/resources/gr.lang.php | 1 + WEB-INF/resources/he.lang.php | 1 + WEB-INF/resources/hu.lang.php | 1 + WEB-INF/resources/it.lang.php | 1 + WEB-INF/resources/ja.lang.php | 1 + WEB-INF/resources/ko.lang.php | 1 + WEB-INF/resources/nl.lang.php | 1 + WEB-INF/resources/no.lang.php | 1 + WEB-INF/resources/pl.lang.php | 1 + WEB-INF/resources/pt-br.lang.php | 1 + WEB-INF/resources/pt.lang.php | 1 + WEB-INF/resources/ro.lang.php | 1 + WEB-INF/resources/ru.lang.php | 1 + WEB-INF/resources/sk.lang.php | 1 + WEB-INF/resources/sl.lang.php | 1 + WEB-INF/resources/sr.lang.php | 1 + WEB-INF/resources/sv.lang.php | 1 + WEB-INF/resources/tr.lang.php | 1 + WEB-INF/resources/zh-cn.lang.php | 1 + WEB-INF/resources/zh-tw.lang.php | 1 + WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/offer_view.tpl | 36 +++++++++++++++ WEB-INF/templates/work.tpl | 2 +- WEB-INF/templates/work_view.tpl | 4 ++ offer_view.php | 73 ++++++++++++++++++++++++++++++ work_view.php | 3 ++ 37 files changed, 206 insertions(+), 2 deletions(-) create mode 100644 WEB-INF/templates/offer_view.tpl create mode 100644 offer_view.php diff --git a/WEB-INF/lib/ttWorkHelper.class.php b/WEB-INF/lib/ttWorkHelper.class.php index 5d235bca7..dae457933 100644 --- a/WEB-INF/lib/ttWorkHelper.class.php +++ b/WEB-INF/lib/ttWorkHelper.class.php @@ -46,6 +46,7 @@ class ttWorkHelper { var $get_offer_uri = null; // URI to get offer details. var $get_active_offers_uri = null; // URI to get active offers. var $get_available_offers_uri = null; // URI to get available offers. + var $get_available_offer_uri = null; // URI to get a single available offer. var $get_group_items_uri = null; // URI to get all group items in one API call. var $delete_offer_uri = null; // URI to delete offer. var $delete_offers_uri = null; // URI to delete multiple offers. @@ -76,6 +77,7 @@ function __construct(&$errors) { $this->get_offer_uri = $this->remote_work_uri.'getoffer'; $this->get_active_offers_uri = $this->remote_work_uri.'getactiveoffers'; $this->get_available_offers_uri = $this->remote_work_uri.'getavailableoffers'; + $this->get_available_offer_uri = $this->remote_work_uri.'getavailableoffer'; $this->get_group_items_uri = $this->remote_work_uri.'getgroupitems'; $this->delete_offer_uri = $this->remote_work_uri.'deleteoffer'; $this->update_offer_uri = $this->remote_work_uri.'updateoffer'; @@ -1048,4 +1050,60 @@ function getAvailableWorkItem($work_id) { $work_item = $result_array['work_item']; return $work_item; } + + // getAvailableOffer - gets available offer details from remote work server. + function getAvailableOffer($offer_id) { + global $i18n; + global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $curl_fields = array('lang' => urlencode($user->lang), + 'site_id' => urlencode($this->site_id), + 'site_key' => urlencode($this->site_key), + 'org_id' => urlencode($org_id), + 'offer_id' => urlencode($offer_id)); + + // url-ify the data for the POST. + foreach($curl_fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; } + $fields_string = rtrim($fields_string, '&'); + + // Open connection. + $ch = curl_init(); + + // Set the url, number of POST vars, POST data. + curl_setopt($ch, CURLOPT_URL, $this->get_available_offer_uri); + curl_setopt($ch, CURLOPT_POST, true); + curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + + // Execute a post request. + $result = curl_exec($ch); + + // Close connection. + curl_close($ch); + + if (!$result) { + $this->errors->add($i18n->get('error.remote_work')); + return false; + } + + $result_array = json_decode($result, true); + + // Check for errors. + $call_status = $result_array['call_status']; + if (!$call_status) { + $this->errors->add($i18n->get('error.remote_work')); + return false; + } + if ($call_status['code'] != TT_CURL_SUCCESS) { + $this->errors->add($call_status['error']); + return false; + } + + $offer = $result_array['offer']; + return $offer; + } } diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index 0f237e21c..05ea0188b 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -416,6 +416,7 @@ // 'title.available_work' => 'Available Work', // Available work items from other organizations. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. // 'title.pending_work' => 'Pending Work', // Work items pending moderator approval. +// 'title.offer' => 'Offer', // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index e52d1b9f6..632ceca9a 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -426,6 +426,7 @@ // 'title.available_work' => 'Available Work', // Available work items from other organizations. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. // 'title.pending_work' => 'Pending Work', // Work items pending moderator approval. +// 'title.offer' => 'Offer', // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index 9d77c6aec..299149356 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -398,6 +398,7 @@ // 'title.available_work' => 'Available Work', // Available work items from other organizations. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. // 'title.pending_work' => 'Pending Work', // Work items pending moderator approval. +// 'title.offer' => 'Offer', // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index 6766407f6..0f58ba784 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -384,6 +384,7 @@ // 'title.available_work' => 'Available Work', // Available work items from other organizations. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. // 'title.pending_work' => 'Pending Work', // Work items pending moderator approval. +// 'title.offer' => 'Offer', // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index d741c9d0b..72106f11f 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -373,6 +373,7 @@ 'title.available_work' => 'Available Work', // Available work items from other organizations. 'title.inactive_work' => 'Inactive Work', // Inactive work items for group. 'title.pending_work' => 'Pending Work', // Work items pending moderator approval. +'title.offer' => 'Offer', 'title.add_offer' => 'Adding Offer', 'title.edit_offer' => 'Editing Offer', 'title.delete_offer' => 'Deleting Offer', diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index 5c2da7972..d6be47ad2 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -415,6 +415,7 @@ // 'title.available_work' => 'Available Work', // Available work items from other organizations. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. // 'title.pending_work' => 'Pending Work', // Work items pending moderator approval. +// 'title.offer' => 'Offer', // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index d72720e24..53183f3c1 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -406,6 +406,7 @@ // 'title.available_work' => 'Available Work', // Available work items from other organizations. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. // 'title.pending_work' => 'Pending Work', // Work items pending moderator approval. +// 'title.offer' => 'Offer', // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index ebb799567..f38760cc2 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -407,6 +407,7 @@ // 'title.available_work' => 'Available Work', // Available work items from other organizations. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. // 'title.pending_work' => 'Pending Work', // Work items pending moderator approval. +// 'title.offer' => 'Offer', // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 6a923b4a1..379182dc1 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -398,6 +398,7 @@ // 'title.available_work' => 'Available Work', // Available work items from other organizations. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. // 'title.pending_work' => 'Pending Work', // Work items pending moderator approval. +// 'title.offer' => 'Offer', // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index 2d0a4892d..cf374646c 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -392,6 +392,7 @@ // 'title.available_work' => 'Available Work', // Available work items from other organizations. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. // 'title.pending_work' => 'Pending Work', // Work items pending moderator approval. +// 'title.offer' => 'Offer', // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index ccd10e059..67068faa9 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -391,6 +391,7 @@ // 'title.available_work' => 'Available Work', // Available work items from other organizations. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. // 'title.pending_work' => 'Pending Work', // Work items pending moderator approval. +// 'title.offer' => 'Offer', // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index 7c1c90572..743077d90 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -415,6 +415,7 @@ // 'title.available_work' => 'Available Work', // Available work items from other organizations. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. // 'title.pending_work' => 'Pending Work', // Work items pending moderator approval. +// 'title.offer' => 'Offer', // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index 585723101..d6fc4b4e9 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -416,6 +416,7 @@ // 'title.available_work' => 'Available Work', // Available work items from other organizations. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. // 'title.pending_work' => 'Pending Work', // Work items pending moderator approval. +// 'title.offer' => 'Offer', // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index 4277c6bfc..7dbc055ba 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -401,6 +401,7 @@ // 'title.available_work' => 'Available Work', // Available work items from other organizations. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. // 'title.pending_work' => 'Pending Work', // Work items pending moderator approval. +// 'title.offer' => 'Offer', // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index 0d1a7a2b8..17a18e9df 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -422,6 +422,7 @@ // 'title.available_work' => 'Available Work', // Available work items from other organizations. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. // 'title.pending_work' => 'Pending Work', // Work items pending moderator approval. +// 'title.offer' => 'Offer', // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index fe4599f9b..c1d03180f 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -423,6 +423,7 @@ // 'title.available_work' => 'Available Work', // Available work items from other organizations. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. // 'title.pending_work' => 'Pending Work', // Work items pending moderator approval. +// 'title.offer' => 'Offer', // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 4179add13..cc4fa139c 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -377,6 +377,7 @@ 'title.inactive_work' => 'Inactief werk', // TODO: translate the following. // 'title.pending_work' => 'Pending Work', // Work items pending moderator approval. +// 'title.offer' => 'Offer', 'title.add_offer' => 'Aanbieding toevoegen', 'title.edit_offer' => 'Aanbieding bewerken', 'title.delete_offer' => 'Aanbieding verwijderen', diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index ba3734aa9..f6e1170a8 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -419,6 +419,7 @@ // 'title.available_work' => 'Available Work', // Available work items from other organizations. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. // 'title.pending_work' => 'Pending Work', // Work items pending moderator approval. +// 'title.offer' => 'Offer', // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index 669a3a5ed..8499ffba7 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -401,6 +401,7 @@ // 'title.available_work' => 'Available Work', // Available work items from other organizations. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. // 'title.pending_work' => 'Pending Work', // Work items pending moderator approval. +// 'title.offer' => 'Offer', // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index 8adcf4aa9..c0097c711 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -396,6 +396,7 @@ // 'title.available_work' => 'Available Work', // Available work items from other organizations. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. // 'title.pending_work' => 'Pending Work', // Work items pending moderator approval. +// 'title.offer' => 'Offer', // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index 9312fe181..ae217cd4a 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -403,6 +403,7 @@ // 'title.available_work' => 'Available Work', // Available work items from other organizations. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. // 'title.pending_work' => 'Pending Work', // Work items pending moderator approval. +// 'title.offer' => 'Offer', // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index e8b7dadfd..5f5dd12e2 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -422,6 +422,7 @@ // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. // 'title.pending_work' => 'Pending Work', // Work items pending moderator approval. // 'title.add_offer' => 'Adding Offer', +// 'title.offer' => 'Offer', // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', // 'title.active_offers' => 'Active Offers', // Active offers this group makes available to other groups. diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index 4ee3aec21..ffdee0d66 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -359,6 +359,7 @@ 'title.available_work' => 'Имеющаяся работа', 'title.inactive_work' => 'Неактивная работа', 'title.pending_work' => 'Работа в ожидании', +'title.offer' => 'Предложение', 'title.add_offer' => 'Добавление предложения', 'title.edit_offer' => 'Редактирование предложения', 'title.delete_offer' => 'Удаление предложения', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index a378df653..5abde75eb 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -405,6 +405,7 @@ // 'title.available_work' => 'Available Work', // Available work items from other organizations. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. // 'title.pending_work' => 'Pending Work', // Work items pending moderator approval. +// 'title.offer' => 'Offer', // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index 82fbc21b2..e7e8f273f 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -396,6 +396,7 @@ // 'title.available_work' => 'Available Work', // Available work items from other organizations. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. // 'title.pending_work' => 'Pending Work', // Work items pending moderator approval. +// 'title.offer' => 'Offer', // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index 02da7646c..7e92a5b5a 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -399,6 +399,7 @@ // 'title.available_work' => 'Available Work', // Available work items from other organizations. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. // 'title.pending_work' => 'Pending Work', // Work items pending moderator approval. +// 'title.offer' => 'Offer', // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index 1b6891fd9..e08a183c3 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -400,6 +400,7 @@ // 'title.available_work' => 'Available Work', // Available work items from other organizations. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. // 'title.pending_work' => 'Pending Work', // Work items pending moderator approval. +// 'title.offer' => 'Offer', // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index 7f2af552e..27a37e3c0 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -430,6 +430,7 @@ // 'title.available_work' => 'Available Work', // Available work items from other organizations. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. // 'title.pending_work' => 'Pending Work', // Work items pending moderator approval. +// 'title.offer' => 'Offer', // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index 47bbae4ba..50bfdfb60 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -411,6 +411,7 @@ // 'title.available_work' => 'Available Work', // Available work items from other organizations. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. // 'title.pending_work' => 'Pending Work', // Work items pending moderator approval. +// 'title.offer' => 'Offer', // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index 8764492c3..39d6afa07 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -416,6 +416,7 @@ // 'title.available_work' => 'Available Work', // Available work items from other organizations. // 'title.inactive_work' => 'Inactive Work', // Inactive work items this group was outsourcing to other groups. // 'title.pending_work' => 'Pending Work', // Work items pending moderator approval. +// 'title.offer' => 'Offer', // 'title.add_offer' => 'Adding Offer', // 'title.edit_offer' => 'Editing Offer', // 'title.delete_offer' => 'Deleting Offer', diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 0497df220..8e19e2adc 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- {foreach $available_offers as $offer} - + diff --git a/WEB-INF/templates/work_view.tpl b/WEB-INF/templates/work_view.tpl index 8c2edb6ae..d34b936a6 100644 --- a/WEB-INF/templates/work_view.tpl +++ b/WEB-INF/templates/work_view.tpl @@ -3,6 +3,10 @@
 Anuko Time Tracker 1.19.10.5121 | Copyright © Anuko | +  Anuko Time Tracker 1.19.10.5122 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/offer_view.tpl b/WEB-INF/templates/offer_view.tpl new file mode 100644 index 000000000..b6baaed28 --- /dev/null +++ b/WEB-INF/templates/offer_view.tpl @@ -0,0 +1,36 @@ +{$forms.offerForm.open} + + + + +
+ + + + + + + + + + + + + + + + + +{if $show_files} + + + + +{/if} + + + + +
{$i18n.label.contractor}:{$forms.offerForm.contractor.control}
{$i18n.label.offer}:{$forms.offerForm.offer_name.control}
{$i18n.label.description}:{$forms.offerForm.description.control}
{$i18n.label.details}:{$forms.offerForm.details.control}
{$i18n.label.file}:{$forms.offerForm.newfile.control}
{$i18n.label.budget}:{$forms.offerForm.budget.control}
+
+{$forms.offerForm.close} diff --git a/WEB-INF/templates/work.tpl b/WEB-INF/templates/work.tpl index c0c516bde..03ab18bf6 100644 --- a/WEB-INF/templates/work.tpl +++ b/WEB-INF/templates/work.tpl @@ -108,7 +108,7 @@
{$offer.subject|escape}{$offer.subject|escape} {$offer.description|escape} {$offer.group_name|escape} {$offer.amount_with_currency}
+ + + + diff --git a/offer_view.php b/offer_view.php new file mode 100644 index 000000000..1422de09b --- /dev/null +++ b/offer_view.php @@ -0,0 +1,73 @@ +isPluginEnabled('wk')) { + header('Location: feature_disabled.php'); + exit(); +} +if (!ttAccessAllowed('manage_work')) { + header('Location: access_denied.php'); + exit(); +} +$cl_offer_id = (int)$request->getParameter('id'); +$workHelper = new ttWorkHelper($err); +$offer = $workHelper->getAvailableOffer($cl_offer_id); +if (!$offer) { + header('Location: access_denied.php'); + exit(); +} +// End of access checks. + +$cl_contractor = $offer['group_name']; +$cl_name = $offer['subject']; +$cl_description = $offer['descr_short']; +$cl_details = $offer['descr_long']; +$cl_budget = $offer['amount_with_currency']; + +$form = new Form('offerForm'); +$form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_offer_id)); +$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'contractor','style'=>'width: 250px;','value'=>$cl_contractor)); +$form->getElement('contractor')->setEnabled(false); +$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'offer_name','style'=>'width: 250px;','value'=>$cl_name)); +$form->getElement('offer_name')->setEnabled(false); +$form->addInput(array('type'=>'textarea','name'=>'description','style'=>'width: 250px; height: 40px;','value'=>$cl_description)); +$form->getElement('description')->setEnabled(false); +$form->addInput(array('type'=>'textarea','name'=>'details','style'=>'width: 250px; height: 80px;','value'=>$cl_details)); +$form->getElement('details')->setEnabled(false); +$form->addInput(array('type'=>'text','name'=>'budget','value'=>$cl_budget)); +$form->getElement('budget')->setEnabled(false); + +$smarty->assign('forms', array($form->getName()=>$form->toArray())); +$smarty->assign('title', $i18n->get('title.offer')); +$smarty->assign('content_page_name', 'offer_view.tpl'); +$smarty->display('index.tpl'); diff --git a/work_view.php b/work_view.php index 5c9ff06dd..08b8815d3 100644 --- a/work_view.php +++ b/work_view.php @@ -48,6 +48,7 @@ } // End of access checks. +$cl_client = $work_item['group_name']; $cl_name = $work_item['subject']; $cl_description = $work_item['descr_short']; $cl_details = $work_item['descr_long']; @@ -55,6 +56,8 @@ $form = new Form('workForm'); $form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_work_id)); +$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'client','style'=>'width: 250px;','value'=>$cl_client)); +$form->getElement('client')->setEnabled(false); $form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'work_name','style'=>'width: 250px;','value'=>$cl_name)); $form->getElement('work_name')->setEnabled(false); $form->addInput(array('type'=>'textarea','name'=>'description','style'=>'width: 250px; height: 40px;','value'=>$cl_description)); From 40fd3ed32d58c08b5b81cbd122ff78ca59ac91b5 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 28 Sep 2019 09:41:39 +0000 Subject: [PATCH 123/877] Made controls on work_view.php and offer_view.php larger to provide more room. --- WEB-INF/templates/footer.tpl | 2 +- offer_view.php | 8 ++++---- work_view.php | 8 ++++---- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 8e19e2adc..45ceb893a 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
{$i18n.label.client}:{$forms.workForm.client.control}
{$i18n.label.work}: {$forms.workForm.work_name.control}
-
 Anuko Time Tracker 1.19.10.5122 | Copyright © Anuko | +  Anuko Time Tracker 1.19.10.5123 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/offer_view.php b/offer_view.php index 1422de09b..2556703ee 100644 --- a/offer_view.php +++ b/offer_view.php @@ -56,13 +56,13 @@ $form = new Form('offerForm'); $form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_offer_id)); -$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'contractor','style'=>'width: 250px;','value'=>$cl_contractor)); +$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'contractor','value'=>$cl_contractor)); $form->getElement('contractor')->setEnabled(false); -$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'offer_name','style'=>'width: 250px;','value'=>$cl_name)); +$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'offer_name','style'=>'width: 400px;','value'=>$cl_name)); $form->getElement('offer_name')->setEnabled(false); -$form->addInput(array('type'=>'textarea','name'=>'description','style'=>'width: 250px; height: 40px;','value'=>$cl_description)); +$form->addInput(array('type'=>'textarea','name'=>'description','style'=>'width: 400px; height: 80px;','value'=>$cl_description)); $form->getElement('description')->setEnabled(false); -$form->addInput(array('type'=>'textarea','name'=>'details','style'=>'width: 250px; height: 80px;','value'=>$cl_details)); +$form->addInput(array('type'=>'textarea','name'=>'details','style'=>'width: 400px; height: 160px;','value'=>$cl_details)); $form->getElement('details')->setEnabled(false); $form->addInput(array('type'=>'text','name'=>'budget','value'=>$cl_budget)); $form->getElement('budget')->setEnabled(false); diff --git a/work_view.php b/work_view.php index 08b8815d3..6e9266c61 100644 --- a/work_view.php +++ b/work_view.php @@ -56,13 +56,13 @@ $form = new Form('workForm'); $form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_work_id)); -$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'client','style'=>'width: 250px;','value'=>$cl_client)); +$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'client','value'=>$cl_client)); $form->getElement('client')->setEnabled(false); -$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'work_name','style'=>'width: 250px;','value'=>$cl_name)); +$form->addInput(array('type'=>'textarea','maxlength'=>'100','name'=>'work_name','style'=>'width: 400px;','value'=>$cl_name)); $form->getElement('work_name')->setEnabled(false); -$form->addInput(array('type'=>'textarea','name'=>'description','style'=>'width: 250px; height: 40px;','value'=>$cl_description)); +$form->addInput(array('type'=>'textarea','name'=>'description','style'=>'width: 400px; height: 80px;','value'=>$cl_description)); $form->getElement('description')->setEnabled(false); -$form->addInput(array('type'=>'textarea','name'=>'details','style'=>'width: 250px; height: 80px;','value'=>$cl_details)); +$form->addInput(array('type'=>'textarea','name'=>'details','style'=>'width: 400px; height: 200px;','value'=>$cl_details)); $form->getElement('details')->setEnabled(false); $form->addInput(array('type'=>'text','name'=>'budget','value'=>$cl_budget)); $form->getElement('budget')->setEnabled(false); From 3f468aaf3bfffe861088b59dc48f939b86c9de2e Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 28 Sep 2019 10:06:03 +0000 Subject: [PATCH 124/877] Renamed a couple of URIs for clarity of purpose. --- WEB-INF/lib/ttWorkHelper.class.php | 20 ++++++++++---------- WEB-INF/templates/footer.tpl | 2 +- offer_edit.php | 2 +- work_edit.php | 2 +- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/WEB-INF/lib/ttWorkHelper.class.php b/WEB-INF/lib/ttWorkHelper.class.php index dae457933..aa65db299 100644 --- a/WEB-INF/lib/ttWorkHelper.class.php +++ b/WEB-INF/lib/ttWorkHelper.class.php @@ -35,7 +35,7 @@ class ttWorkHelper { var $remote_work_uri = null; // Location of remote work server. var $register_uri = null; // URI to register with remote work server. var $put_work_uri = null; // URI to publish work. - var $get_work_uri = null; // URI to get work details. + var $get_own_work_item_uri = null; // URI to get own work item details. var $get_active_work_uri = null; // URI to get active work for group. var $get_available_work_uri = null; // URI to get available work for group. var $get_available_work_item_uri = null; // URI to get a single available work item. @@ -43,7 +43,7 @@ class ttWorkHelper { // TODO: design how (and what) to delete when a group is deleted. var $update_work_uri = null; // URI to update work. var $put_offer_uri = null; // URI to publish offer. - var $get_offer_uri = null; // URI to get offer details. + var $get_own_offer_uri = null; // URI to get own offer details. var $get_active_offers_uri = null; // URI to get active offers. var $get_available_offers_uri = null; // URI to get available offers. var $get_available_offer_uri = null; // URI to get a single available offer. @@ -67,14 +67,14 @@ function __construct(&$errors) { // a complete variety of deployed clients, including those without versions. $this->register_uri = $this->remote_work_uri.'register'; // register_0_0 $this->put_work_uri = $this->remote_work_uri.'putwork'; - $this->get_work_uri = $this->remote_work_uri.'getwork'; + $this->get_own_work_item_uri = $this->remote_work_uri.'getownworkitem'; $this->get_active_work_uri = $this->remote_work_uri.'getactivework'; $this->get_available_work_uri = $this->remote_work_uri.'getavailablework'; $this->get_available_work_item_uri = $this->remote_work_uri.'getavailableworkitem'; $this->delete_work_uri = $this->remote_work_uri.'deletework'; $this->update_work_uri = $this->remote_work_uri.'updatework'; $this->put_offer_uri = $this->remote_work_uri.'putoffer'; - $this->get_offer_uri = $this->remote_work_uri.'getoffer'; + $this->get_own_offer_uri = $this->remote_work_uri.'getownoffer'; $this->get_active_offers_uri = $this->remote_work_uri.'getactiveoffers'; $this->get_available_offers_uri = $this->remote_work_uri.'getavailableoffers'; $this->get_available_offer_uri = $this->remote_work_uri.'getavailableoffer'; @@ -427,8 +427,8 @@ function getAvailableWork() { return $available_work; } - // getWork - gets work item details from remote work server. - function getWork($work_id) { + // getOwnWorkItem - gets work item details from remote work server. + function getOwnWorkItem($work_id) { global $i18n; global $user; $mdb2 = getConnection(); @@ -453,7 +453,7 @@ function getWork($work_id) { $ch = curl_init(); // Set the url, number of POST vars, POST data. - curl_setopt($ch, CURLOPT_URL, $this->get_work_uri); + curl_setopt($ch, CURLOPT_URL, $this->get_own_work_item_uri); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); @@ -731,8 +731,8 @@ function getAvailableOffers() { return $available_offers; } - // getOffer - gets offer details from remote work server. - function getOffer($offer_id) { + // getOwnOffer - gets offer details from remote work server. + function getOwnOffer($offer_id) { global $i18n; global $user; $mdb2 = getConnection(); @@ -757,7 +757,7 @@ function getOffer($offer_id) { $ch = curl_init(); // Set the url, number of POST vars, POST data. - curl_setopt($ch, CURLOPT_URL, $this->get_offer_uri); + curl_setopt($ch, CURLOPT_URL, $this->get_own_offer_uri); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 45ceb893a..e8cc4b406 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.19.10.5123 | Copyright © Anuko | +  Anuko Time Tracker 1.19.10.5124 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/offer_edit.php b/offer_edit.php index 729b79d03..f39c6cb5c 100644 --- a/offer_edit.php +++ b/offer_edit.php @@ -41,7 +41,7 @@ } $cl_offer_id = (int)$request->getParameter('id'); $workHelper = new ttWorkHelper($err); -$offer = $workHelper->getOffer($cl_offer_id); +$offer = $workHelper->getOwnOffer($cl_offer_id); if (!$offer) { header('Location: access_denied.php'); exit(); diff --git a/work_edit.php b/work_edit.php index eda443716..dc38e5696 100644 --- a/work_edit.php +++ b/work_edit.php @@ -41,7 +41,7 @@ } $cl_work_id = (int)$request->getParameter('id'); $workHelper = new ttWorkHelper($err); -$work_item = $workHelper->getWork($cl_work_id); +$work_item = $workHelper->getOwnWorkItem($cl_work_id); if (!$work_item) { header('Location: access_denied.php'); exit(); From 6f98d4bfd9af051432c3300273abd3057aba364a Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 28 Sep 2019 14:23:51 +0000 Subject: [PATCH 125/877] Refactoring in progress for Work Plugin. --- WEB-INF/lib/ttAdminWorkHelper.class.php | 42 +++++++++++++------------ WEB-INF/lib/ttWorkHelper.class.php | 36 ++++++++++----------- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/header.tpl | 2 +- admin_work_edit.php | 2 +- 5 files changed, 43 insertions(+), 41 deletions(-) diff --git a/WEB-INF/lib/ttAdminWorkHelper.class.php b/WEB-INF/lib/ttAdminWorkHelper.class.php index cdd517c40..06b3bb4fb 100644 --- a/WEB-INF/lib/ttAdminWorkHelper.class.php +++ b/WEB-INF/lib/ttAdminWorkHelper.class.php @@ -32,9 +32,10 @@ // It does everything via curl calls to a Remote Work server using its API. class ttAdminWorkHelper { var $errors = null; // Errors go here. Set in constructor by reference. - var $remote_work_uri = null; // Location of remote work server. + var $work_server_uri = null; // Location of remote work server. var $register_uri = null; // URI to register with remote work server. - var $get_work_uri = null; // URI to get work details. + var $get_work_item_uri = null; // URI to get work item details. + var $update_work_uri = null; // URI to update work. var $delete_work_uri = null; // URI to delete work. var $approve_work_uri = null; // URI to approved work. @@ -54,21 +55,22 @@ class ttAdminWorkHelper { function __construct(&$errors) { $this->errors = &$errors; - $this->remote_work_uri = defined('REMOTE_WORK_URI') ? REMOTE_WORK_URI : "https://www.anuko.com/work/"; - $this->register_uri = $this->remote_work_uri.'register'; - $this->get_work_uri = $this->remote_work_uri.'admin_getwork'; - $this->update_work_uri = $this->remote_work_uri.'admin_updatework'; - $this->delete_work_uri = $this->remote_work_uri.'admin_deletework'; - $this->approve_work_uri = $this->remote_work_uri.'admin_approvework'; - $this->disapprove_work_uri = $this->remote_work_uri.'admin_disapprovework'; - $this->get_offer_uri = $this->remote_work_uri.'admin_getoffer'; - $this->update_offer_uri = $this->remote_work_uri.'admin_updateoffer'; - $this->delete_offer_uri = $this->remote_work_uri.'admin_deleteoffer'; - $this->approve_offer_uri = $this->remote_work_uri.'admin_approveoffer'; - $this->disapprove_offer_uri = $this->remote_work_uri.'admin_disapproveoffer'; - $this->get_pending_work_uri = $this->remote_work_uri.'admin_getpendingwork'; - $this->get_pending_offers_uri = $this->remote_work_uri.'admin_getpendingoffers'; - $this->get_items_uri = $this->remote_work_uri.'admin_getitems'; + $this->work_server_uri = defined('WORK_SERVER_URI') ? WORK_SERVER_URI : "https://www.anuko.com/work/"; + $this->register_uri = $this->work_server_uri.'register'; + $this->get_work_item_uri = $this->work_server_uri.'admin_getworkitem'; + + $this->update_work_uri = $this->work_server_uri.'admin_updatework'; + $this->delete_work_uri = $this->work_server_uri.'admin_deletework'; + $this->approve_work_uri = $this->work_server_uri.'admin_approvework'; + $this->disapprove_work_uri = $this->work_server_uri.'admin_disapprovework'; + $this->get_offer_uri = $this->work_server_uri.'admin_getoffer'; + $this->update_offer_uri = $this->work_server_uri.'admin_updateoffer'; + $this->delete_offer_uri = $this->work_server_uri.'admin_deleteoffer'; + $this->approve_offer_uri = $this->work_server_uri.'admin_approveoffer'; + $this->disapprove_offer_uri = $this->work_server_uri.'admin_disapproveoffer'; + $this->get_pending_work_uri = $this->work_server_uri.'admin_getpendingwork'; + $this->get_pending_offers_uri = $this->work_server_uri.'admin_getpendingoffers'; + $this->get_items_uri = $this->work_server_uri.'admin_getitems'; $this->checkSiteRegistration(); } @@ -257,8 +259,8 @@ function getPendingWork() { return $pending_work; } - // getWork - gets work item details from remote work server. - function getWork($work_id) { + // getWorkItem - gets work item details from remote work server. + function getWorkItem($work_id) { global $i18n; global $user; $mdb2 = getConnection(); @@ -277,7 +279,7 @@ function getWork($work_id) { $ch = curl_init(); // Set the url, number of POST vars, POST data. - curl_setopt($ch, CURLOPT_URL, $this->get_work_uri); + curl_setopt($ch, CURLOPT_URL, $this->get_work_item_uri); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); diff --git a/WEB-INF/lib/ttWorkHelper.class.php b/WEB-INF/lib/ttWorkHelper.class.php index aa65db299..d91252e2a 100644 --- a/WEB-INF/lib/ttWorkHelper.class.php +++ b/WEB-INF/lib/ttWorkHelper.class.php @@ -32,7 +32,7 @@ // It does everything via curl calls to a Remote Work server using its API. class ttWorkHelper { var $errors = null; // Errors go here. Set in constructor by reference. - var $remote_work_uri = null; // Location of remote work server. + var $work_server_uri = null; // URI of work server. var $register_uri = null; // URI to register with remote work server. var $put_work_uri = null; // URI to publish work. var $get_own_work_item_uri = null; // URI to get own work item details. @@ -58,29 +58,29 @@ class ttWorkHelper { function __construct(&$errors) { $this->errors = &$errors; - $this->remote_work_uri = defined('REMOTE_WORK_URI') ? REMOTE_WORK_URI : "https://www.anuko.com/work/"; + $this->work_server_uri = defined('WORK_SERVER_URI') ? WORK_SERVER_URI : "https://www.anuko.com/work/"; // Note: at some point a need will arise for API versioning. // When this happens, we will append an API version number to the end of URI, // for example: register_0_1 instead of register. // This should theoretically allow a remote work server to be able to work with // a complete variety of deployed clients, including those without versions. - $this->register_uri = $this->remote_work_uri.'register'; // register_0_0 - $this->put_work_uri = $this->remote_work_uri.'putwork'; - $this->get_own_work_item_uri = $this->remote_work_uri.'getownworkitem'; - $this->get_active_work_uri = $this->remote_work_uri.'getactivework'; - $this->get_available_work_uri = $this->remote_work_uri.'getavailablework'; - $this->get_available_work_item_uri = $this->remote_work_uri.'getavailableworkitem'; - $this->delete_work_uri = $this->remote_work_uri.'deletework'; - $this->update_work_uri = $this->remote_work_uri.'updatework'; - $this->put_offer_uri = $this->remote_work_uri.'putoffer'; - $this->get_own_offer_uri = $this->remote_work_uri.'getownoffer'; - $this->get_active_offers_uri = $this->remote_work_uri.'getactiveoffers'; - $this->get_available_offers_uri = $this->remote_work_uri.'getavailableoffers'; - $this->get_available_offer_uri = $this->remote_work_uri.'getavailableoffer'; - $this->get_group_items_uri = $this->remote_work_uri.'getgroupitems'; - $this->delete_offer_uri = $this->remote_work_uri.'deleteoffer'; - $this->update_offer_uri = $this->remote_work_uri.'updateoffer'; + $this->register_uri = $this->work_server_uri.'register'; // register_0_0 + $this->put_work_uri = $this->work_server_uri.'putwork'; + $this->get_own_work_item_uri = $this->work_server_uri.'getownworkitem'; + $this->get_active_work_uri = $this->work_server_uri.'getactivework'; + $this->get_available_work_uri = $this->work_server_uri.'getavailablework'; + $this->get_available_work_item_uri = $this->work_server_uri.'getavailableworkitem'; + $this->delete_work_uri = $this->work_server_uri.'deletework'; + $this->update_work_uri = $this->work_server_uri.'updatework'; + $this->put_offer_uri = $this->work_server_uri.'putoffer'; + $this->get_own_offer_uri = $this->work_server_uri.'getownoffer'; + $this->get_active_offers_uri = $this->work_server_uri.'getactiveoffers'; + $this->get_available_offers_uri = $this->work_server_uri.'getavailableoffers'; + $this->get_available_offer_uri = $this->work_server_uri.'getavailableoffer'; + $this->get_group_items_uri = $this->work_server_uri.'getgroupitems'; + $this->delete_offer_uri = $this->work_server_uri.'deleteoffer'; + $this->update_offer_uri = $this->work_server_uri.'updateoffer'; $this->checkSiteRegistration(); } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index e8cc4b406..e13050a3d 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- diff --git a/admin_work_edit.php b/admin_work_edit.php index d158b8037..336b7780b 100644 --- a/admin_work_edit.php +++ b/admin_work_edit.php @@ -39,7 +39,7 @@ } $cl_work_id = (int)$request->getParameter('id'); $adminWorkHelper = new ttAdminWorkHelper($err); -$work_item = $adminWorkHelper->getWork($cl_work_id); +$work_item = $adminWorkHelper->getWorkItem($cl_work_id); if (!$work_item) { header('Location: access_denied.php'); exit(); From 426d131468dbe38b242b394df796ecda59deaf46 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 28 Sep 2019 14:48:53 +0000 Subject: [PATCH 126/877] Refactoring in progress. --- WEB-INF/lib/ttAdminWorkHelper.class.php | 22 +++++++++++----------- WEB-INF/templates/footer.tpl | 2 +- admin_work_delete.php | 4 ++-- admin_work_edit.php | 10 +++++----- offer_view.php | 2 +- 5 files changed, 20 insertions(+), 20 deletions(-) diff --git a/WEB-INF/lib/ttAdminWorkHelper.class.php b/WEB-INF/lib/ttAdminWorkHelper.class.php index 06b3bb4fb..ff098b7b5 100644 --- a/WEB-INF/lib/ttAdminWorkHelper.class.php +++ b/WEB-INF/lib/ttAdminWorkHelper.class.php @@ -35,10 +35,10 @@ class ttAdminWorkHelper { var $work_server_uri = null; // Location of remote work server. var $register_uri = null; // URI to register with remote work server. var $get_work_item_uri = null; // URI to get work item details. + var $update_work_item_uri = null; // URI to update work item. + var $delete_work_item_uri = null; // URI to delete work item. - var $update_work_uri = null; // URI to update work. - var $delete_work_uri = null; // URI to delete work. - var $approve_work_uri = null; // URI to approved work. + var $approve_work_uri = null; // URI to approve work. var $disapprove_work_uri = null; // URI to disapprove work. var $get_offer_uri = null; // URI to get offer details. var $update_offer_uri = null; // URI to update offer. @@ -58,9 +58,9 @@ function __construct(&$errors) { $this->work_server_uri = defined('WORK_SERVER_URI') ? WORK_SERVER_URI : "https://www.anuko.com/work/"; $this->register_uri = $this->work_server_uri.'register'; $this->get_work_item_uri = $this->work_server_uri.'admin_getworkitem'; + $this->update_work_item_uri = $this->work_server_uri.'admin_updateworkitem'; + $this->delete_work_item_uri = $this->work_server_uri.'admin_deleteworkitem'; - $this->update_work_uri = $this->work_server_uri.'admin_updatework'; - $this->delete_work_uri = $this->work_server_uri.'admin_deletework'; $this->approve_work_uri = $this->work_server_uri.'admin_approvework'; $this->disapprove_work_uri = $this->work_server_uri.'admin_disapprovework'; $this->get_offer_uri = $this->work_server_uri.'admin_getoffer'; @@ -312,8 +312,8 @@ function getWorkItem($work_id) { return $work_item; } - // deleteWork - deletes work item from remote work server. - function deleteWork($work_id) { + // deleteWorkItem - deletes work item from remote work server. + function deleteWorkItem($work_id) { global $i18n; global $user; $mdb2 = getConnection(); @@ -336,7 +336,7 @@ function deleteWork($work_id) { $ch = curl_init(); // Set the url, number of POST vars, POST data. - curl_setopt($ch, CURLOPT_URL, $this->delete_work_uri); + curl_setopt($ch, CURLOPT_URL, $this->delete_work_item_uri); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); @@ -477,8 +477,8 @@ function getOffer($offer_id) { return $offer; } - // updateWork - updates a work item in remote work server. - function updateWork($fields) { + // updateWorkItem - updates a work item in remote work server. + function updateWorkItem($fields) { global $i18n; global $user; $mdb2 = getConnection(); @@ -508,7 +508,7 @@ function updateWork($fields) { $ch = curl_init(); // Set the url, number of POST vars, POST data. - curl_setopt($ch, CURLOPT_URL, $this->update_work_uri); + curl_setopt($ch, CURLOPT_URL, $this->update_work_item_uri); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index e13050a3d..aadc6a379 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.19.10.5124 | Copyright © Anuko | +  Anuko Time Tracker 1.19.10.5125 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/header.tpl b/WEB-INF/templates/header.tpl index fa66c6190..fbb3e88a4 100644 --- a/WEB-INF/templates/header.tpl +++ b/WEB-INF/templates/header.tpl @@ -73,7 +73,7 @@   {$i18n.menu.groups} {$i18n.menu.options} - {if isTrue('REMOTE_WORK_DEBUG')} + {if isTrue('WORK_SERVER_ADMINISTRATION')} {$i18n.label.work} {/if}
-
 Anuko Time Tracker 1.19.10.5125 | Copyright © Anuko | +  Anuko Time Tracker 1.19.10.5126 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/admin_work_delete.php b/admin_work_delete.php index d64b9fb9c..0700b912c 100644 --- a/admin_work_delete.php +++ b/admin_work_delete.php @@ -37,7 +37,7 @@ } $cl_work_id = (int)$request->getParameter('id'); $adminWorkHelper = new ttAdminWorkHelper($err); -$work_item = $adminWorkHelper->getWork($cl_work_id); +$work_item = $adminWorkHelper->getWorkItem($cl_work_id); if (!$work_item) { header('Location: access_denied.php'); exit(); @@ -53,7 +53,7 @@ if ($request->isPost()) { if ($request->getParameter('btn_delete')) { - if ($adminWorkHelper->deleteWork($cl_work_id)) { + if ($adminWorkHelper->deleteWorkItem($cl_work_id)) { header('Location: admin_work.php'); exit(); } diff --git a/admin_work_edit.php b/admin_work_edit.php index 336b7780b..89017b7fd 100644 --- a/admin_work_edit.php +++ b/admin_work_edit.php @@ -71,9 +71,9 @@ $form = new Form('workForm'); $form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_work_id)); -$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'work_name','style'=>'width: 250px;','value'=>$cl_name)); -$form->addInput(array('type'=>'textarea','name'=>'description','style'=>'width: 250px; height: 40px;','value'=>$cl_description)); -$form->addInput(array('type'=>'textarea','name'=>'details','style'=>'width: 250px; height: 80px;','value'=>$cl_details)); +$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'work_name','style'=>'width: 400px;','value'=>$cl_name)); +$form->addInput(array('type'=>'textarea','name'=>'description','style'=>'width: 400px; height: 80px;','value'=>$cl_description)); +$form->addInput(array('type'=>'textarea','name'=>'details','style'=>'width: 400px; height: 200px;','value'=>$cl_details)); $form->addInput(array('type'=>'combobox','name'=>'currency','data'=>$currencies,'value'=>$cl_currency)); $form->addInput(array('type'=>'floatfield','maxlength'=>'10','name'=>'budget','format'=>'.2','value'=>$cl_budget)); @@ -84,7 +84,7 @@ $status_options[STATUS_APPROVED] = $i18n->get('dropdown.approved'); $form->addInput(array('type'=>'combobox','name'=>'status','value'=>$cl_status,'data'=>$status_options)); -$form->addInput(array('type'=>'textarea','name'=>'moderator_comment','style'=>'width: 250px; height: 80px;','value'=>$cl_moderator_comment)); +$form->addInput(array('type'=>'textarea','name'=>'moderator_comment','style'=>'width: 400px; height: 80px;','value'=>$cl_moderator_comment)); $form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); if ($request->isPost()) { @@ -111,7 +111,7 @@ // Do things differently, depending on status control value. if ($existingStatus == $cl_status) { // Status not changed. Update work information. - if ($adminWorkHelper->updateWork($fields)) { + if ($adminWorkHelper->updateWorkItem($fields)) { header('Location: admin_work.php'); exit(); } diff --git a/offer_view.php b/offer_view.php index 2556703ee..cbf400db4 100644 --- a/offer_view.php +++ b/offer_view.php @@ -62,7 +62,7 @@ $form->getElement('offer_name')->setEnabled(false); $form->addInput(array('type'=>'textarea','name'=>'description','style'=>'width: 400px; height: 80px;','value'=>$cl_description)); $form->getElement('description')->setEnabled(false); -$form->addInput(array('type'=>'textarea','name'=>'details','style'=>'width: 400px; height: 160px;','value'=>$cl_details)); +$form->addInput(array('type'=>'textarea','name'=>'details','style'=>'width: 400px; height: 200px;','value'=>$cl_details)); $form->getElement('details')->setEnabled(false); $form->addInput(array('type'=>'text','name'=>'budget','value'=>$cl_budget)); $form->getElement('budget')->setEnabled(false); From c3000b0b42334b37227a850b55eb0b9bc49d0591 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 28 Sep 2019 15:19:57 +0000 Subject: [PATCH 127/877] Finished refactoring URIs for worok server administration. --- WEB-INF/lib/ttAdminWorkHelper.class.php | 33 +++++++++++-------------- WEB-INF/templates/footer.tpl | 2 +- admin_work_edit.php | 4 +-- 3 files changed, 18 insertions(+), 21 deletions(-) diff --git a/WEB-INF/lib/ttAdminWorkHelper.class.php b/WEB-INF/lib/ttAdminWorkHelper.class.php index ff098b7b5..871bd8d38 100644 --- a/WEB-INF/lib/ttAdminWorkHelper.class.php +++ b/WEB-INF/lib/ttAdminWorkHelper.class.php @@ -37,15 +37,14 @@ class ttAdminWorkHelper { var $get_work_item_uri = null; // URI to get work item details. var $update_work_item_uri = null; // URI to update work item. var $delete_work_item_uri = null; // URI to delete work item. - - var $approve_work_uri = null; // URI to approve work. - var $disapprove_work_uri = null; // URI to disapprove work. + var $approve_work_item_uri = null; // URI to approve work item. + var $disapprove_work_item_uri = null; // URI to disapprove work item. var $get_offer_uri = null; // URI to get offer details. var $update_offer_uri = null; // URI to update offer. var $delete_offer_uri = null; // URI to delete offer. var $approve_offer_uri = null; // URI to approved offer. var $disapprove_offer_uri = null; // URI to disapprove offer. - var $get_pending_work_uri = null; // URI to get work pending approval. + var $get_pending_work_items_uri = null; // URI to get work items pending approval. var $get_pending_offers_uri = null; // URI to get offers pending approval. var $get_items_uri = null; // URI to get all admin items in one API call. var $site_id = null; // Site id for remote work server. @@ -60,15 +59,14 @@ function __construct(&$errors) { $this->get_work_item_uri = $this->work_server_uri.'admin_getworkitem'; $this->update_work_item_uri = $this->work_server_uri.'admin_updateworkitem'; $this->delete_work_item_uri = $this->work_server_uri.'admin_deleteworkitem'; - - $this->approve_work_uri = $this->work_server_uri.'admin_approvework'; - $this->disapprove_work_uri = $this->work_server_uri.'admin_disapprovework'; + $this->approve_work_item_uri = $this->work_server_uri.'admin_approveworkitem'; + $this->disapprove_work_item_uri = $this->work_server_uri.'admin_disapproveworkitem'; $this->get_offer_uri = $this->work_server_uri.'admin_getoffer'; $this->update_offer_uri = $this->work_server_uri.'admin_updateoffer'; $this->delete_offer_uri = $this->work_server_uri.'admin_deleteoffer'; $this->approve_offer_uri = $this->work_server_uri.'admin_approveoffer'; $this->disapprove_offer_uri = $this->work_server_uri.'admin_disapproveoffer'; - $this->get_pending_work_uri = $this->work_server_uri.'admin_getpendingwork'; + $this->get_pending_work_items_uri = $this->work_server_uri.'admin_getpendingworkitems'; $this->get_pending_offers_uri = $this->work_server_uri.'admin_getpendingoffers'; $this->get_items_uri = $this->work_server_uri.'admin_getitems'; $this->checkSiteRegistration(); @@ -206,8 +204,8 @@ function getPendingOffers() { return $pending_offers; } - // getPendingWork - obtains a list of work items pending approval. - function getPendingWork() { + // getPendingWorkItems - obtains a list of work items pending approval. + function getPendingWorkItems() { global $i18n; global $user; $mdb2 = getConnection(); @@ -226,7 +224,7 @@ function getPendingWork() { $ch = curl_init(); // Set the url, number of POST vars, POST data. - curl_setopt($ch, CURLOPT_URL, $this->get_pending_work_uri); + curl_setopt($ch, CURLOPT_URL, $this->get_pending_work_items_uri); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); @@ -540,8 +538,8 @@ function updateWorkItem($fields) { return true; } - // approveWork - approves work item in remote work server. - function approveWork($fields) { + // approveWorkItem - approves work item in remote work server. + function approveWorkItem($fields) { global $i18n; global $user; $mdb2 = getConnection(); @@ -570,7 +568,7 @@ function approveWork($fields) { $ch = curl_init(); // Set the url, number of POST vars, POST data. - curl_setopt($ch, CURLOPT_URL, $this->approve_work_uri); + curl_setopt($ch, CURLOPT_URL, $this->approve_work_item_uri); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); @@ -602,8 +600,8 @@ function approveWork($fields) { return true; } - // disapproveWork - disapproves work item in remote work server. - function disapproveWork($fields) { + // disapproveWorkItem - disapproves work item in remote work server. + function disapproveWorkItem($fields) { global $i18n; global $user; $mdb2 = getConnection(); @@ -627,12 +625,11 @@ function disapproveWork($fields) { // url-ify the data for the POST. foreach($curl_fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; } $fields_string = rtrim($fields_string, '&'); - // Open connection. $ch = curl_init(); // Set the url, number of POST vars, POST data. - curl_setopt($ch, CURLOPT_URL, $this->disapprove_work_uri); + curl_setopt($ch, CURLOPT_URL, $this->disapprove_work_item_uri); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index aadc6a379..4e1d7771d 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.19.10.5126 | Copyright © Anuko | +  Anuko Time Tracker 1.19.10.5127 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/admin_work_edit.php b/admin_work_edit.php index 89017b7fd..9700b05d9 100644 --- a/admin_work_edit.php +++ b/admin_work_edit.php @@ -117,13 +117,13 @@ } } else if ($cl_status == STATUS_DISAPPROVED) { // Status changed to "not approved". Disapprove work. - if ($adminWorkHelper->disapproveWork($fields)) { + if ($adminWorkHelper->disapproveWorkItem($fields)) { header('Location: admin_work.php'); exit(); } } else if ($cl_status == STATUS_APPROVED) { // Status changed to "approved". Approve work. - if ($adminWorkHelper->approveWork($fields)) { + if ($adminWorkHelper->approveWorkItem($fields)) { header('Location: admin_work.php'); exit(); } From 879f749fce4379d8a7ef5786f6a06b2e12034d16 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 28 Sep 2019 16:58:44 +0000 Subject: [PATCH 128/877] Refactoring of URIs for Work Plugin in progress. --- WEB-INF/lib/ttAdminWorkHelper.class.php | 2 +- WEB-INF/lib/ttWorkHelper.class.php | 34 +++++++++++++------------ WEB-INF/templates/footer.tpl | 2 +- work_add.php | 2 +- 4 files changed, 21 insertions(+), 19 deletions(-) diff --git a/WEB-INF/lib/ttAdminWorkHelper.class.php b/WEB-INF/lib/ttAdminWorkHelper.class.php index 871bd8d38..d809cb35f 100644 --- a/WEB-INF/lib/ttAdminWorkHelper.class.php +++ b/WEB-INF/lib/ttAdminWorkHelper.class.php @@ -32,7 +32,7 @@ // It does everything via curl calls to a Remote Work server using its API. class ttAdminWorkHelper { var $errors = null; // Errors go here. Set in constructor by reference. - var $work_server_uri = null; // Location of remote work server. + var $work_server_uri = null; // Location of work server. var $register_uri = null; // URI to register with remote work server. var $get_work_item_uri = null; // URI to get work item details. var $update_work_item_uri = null; // URI to update work item. diff --git a/WEB-INF/lib/ttWorkHelper.class.php b/WEB-INF/lib/ttWorkHelper.class.php index d91252e2a..aa0d584ef 100644 --- a/WEB-INF/lib/ttWorkHelper.class.php +++ b/WEB-INF/lib/ttWorkHelper.class.php @@ -32,12 +32,13 @@ // It does everything via curl calls to a Remote Work server using its API. class ttWorkHelper { var $errors = null; // Errors go here. Set in constructor by reference. - var $work_server_uri = null; // URI of work server. + var $work_server_uri = null; // Location of work server. var $register_uri = null; // URI to register with remote work server. - var $put_work_uri = null; // URI to publish work. + var $put_work_item_uri = null; // URI to publish work item. var $get_own_work_item_uri = null; // URI to get own work item details. - var $get_active_work_uri = null; // URI to get active work for group. - var $get_available_work_uri = null; // URI to get available work for group. + var $get_own_work_items_uri = null; // URI to get own work items for group. + var $get_available_work_items_uri = null; // URI to get available work items for group. + var $get_available_work_item_uri = null; // URI to get a single available work item. var $delete_work_uri = null; // URI to delete work. // TODO: design how (and what) to delete when a group is deleted. @@ -66,10 +67,11 @@ function __construct(&$errors) { // This should theoretically allow a remote work server to be able to work with // a complete variety of deployed clients, including those without versions. $this->register_uri = $this->work_server_uri.'register'; // register_0_0 - $this->put_work_uri = $this->work_server_uri.'putwork'; + $this->put_work_item_uri = $this->work_server_uri.'putworkitem'; $this->get_own_work_item_uri = $this->work_server_uri.'getownworkitem'; - $this->get_active_work_uri = $this->work_server_uri.'getactivework'; - $this->get_available_work_uri = $this->work_server_uri.'getavailablework'; + $this->get_own_work_items_uri = $this->work_server_uri.'getownworkitems'; + $this->get_available_work_items_uri = $this->work_server_uri.'getavailableworkitems'; + $this->get_available_work_item_uri = $this->work_server_uri.'getavailableworkitem'; $this->delete_work_uri = $this->work_server_uri.'deletework'; $this->update_work_uri = $this->work_server_uri.'updatework'; @@ -163,7 +165,7 @@ function checkSiteRegistration() { } } - // putWork - publishes a work item in remote work server. + // putWorkItem - publishes a work item in remote work server. // // Note about some fields using additional base64 encoding. // There is a problem with data posted by curl calls on the server side for @@ -177,7 +179,7 @@ function checkSiteRegistration() { // // A workaround for now is to use use an additional base64 encoding for all text fields, // which are decoded back to utf-8 strings on the server side. - function putWork($fields) { + function putWorkItem($fields) { global $i18n; global $user; $mdb2 = getConnection(); @@ -211,7 +213,7 @@ function putWork($fields) { $ch = curl_init(); // Set the url, number of POST vars, POST data. - curl_setopt($ch, CURLOPT_URL, $this->put_work_uri); + curl_setopt($ch, CURLOPT_URL, $this->put_work_item_uri); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); @@ -312,8 +314,8 @@ function updateWork($fields) { return true; } - // getActiveWork - obtains a list of work items this group is currently outsourcing. - function getActiveWork() { + // getOwnWorkItems - obtains a list of work items this group is currently outsourcing. + function getOwnWorkItems() { global $i18n; global $user; $mdb2 = getConnection(); @@ -338,7 +340,7 @@ function getActiveWork() { $ch = curl_init(); // Set the url, number of POST vars, POST data. - curl_setopt($ch, CURLOPT_URL, $this->get_active_work_uri); + curl_setopt($ch, CURLOPT_URL, $this->get_own_work_items_iri); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); @@ -371,8 +373,8 @@ function getActiveWork() { return $active_work; } - // getAvailableWork - obtains a list of available work items this group can bid on. - function getAvailableWork() { + // getAvailableWorkItems - obtains a list of available work items this group can bid on. + function getAvailableWorkItems() { global $i18n; global $user; $mdb2 = getConnection(); @@ -394,7 +396,7 @@ function getAvailableWork() { $ch = curl_init(); // Set the url, number of POST vars, POST data. - curl_setopt($ch, CURLOPT_URL, $this->get_available_work_uri); + curl_setopt($ch, CURLOPT_URL, $this->get_available_work_items_uri); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 4e1d7771d..8977cddff 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.19.10.5127 | Copyright © Anuko | +  Anuko Time Tracker 1.19.10.5128 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/work_add.php b/work_add.php index 9fe73d206..9bc6d3414 100644 --- a/work_add.php +++ b/work_add.php @@ -84,7 +84,7 @@ 'descr_long' => $cl_details, 'currency' => $currencies[$cl_currency], 'amount' => $cl_budget); - if ($workHelper->putWork($fields)) { + if ($workHelper->putWorkItem($fields)) { header('Location: work.php'); exit(); } From 25232ad91f66cab254f6e6222badfd3dfc3537d1 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 28 Sep 2019 18:31:15 +0000 Subject: [PATCH 129/877] Ongoing refactoring of URIs for Work plugin. --- WEB-INF/lib/ttWorkHelper.class.php | 58 +++++++++++++++--------------- WEB-INF/templates/footer.tpl | 2 +- offer_add.php | 2 +- offer_delete.php | 2 +- work_add.php | 2 +- work_delete.php | 4 +-- work_edit.php | 2 +- 7 files changed, 36 insertions(+), 36 deletions(-) diff --git a/WEB-INF/lib/ttWorkHelper.class.php b/WEB-INF/lib/ttWorkHelper.class.php index aa0d584ef..3e277d6ec 100644 --- a/WEB-INF/lib/ttWorkHelper.class.php +++ b/WEB-INF/lib/ttWorkHelper.class.php @@ -34,18 +34,18 @@ class ttWorkHelper { var $errors = null; // Errors go here. Set in constructor by reference. var $work_server_uri = null; // Location of work server. var $register_uri = null; // URI to register with remote work server. - var $put_work_item_uri = null; // URI to publish work item. + var $put_own_work_item_uri = null; // URI to publish own work item. var $get_own_work_item_uri = null; // URI to get own work item details. var $get_own_work_items_uri = null; // URI to get own work items for group. var $get_available_work_items_uri = null; // URI to get available work items for group. - - var $get_available_work_item_uri = null; // URI to get a single available work item. - var $delete_work_uri = null; // URI to delete work. + var $get_available_work_item_uri = null; // URI to get a single available work item. + var $delete_own_work_item_uri = null; // URI to delete own work item. // TODO: design how (and what) to delete when a group is deleted. - var $update_work_uri = null; // URI to update work. - var $put_offer_uri = null; // URI to publish offer. - var $get_own_offer_uri = null; // URI to get own offer details. - var $get_active_offers_uri = null; // URI to get active offers. + var $update_own_work_item_uri = null; // URI to update own work item. + var $put_own_offer_uri = null; // URI to publish own offer. + var $get_own_offer_uri = null; // URI to get own offer details. + var $get_own_offers_uri = null; // URI to get own offers. + var $get_available_offers_uri = null; // URI to get available offers. var $get_available_offer_uri = null; // URI to get a single available offer. var $get_group_items_uri = null; // URI to get all group items in one API call. @@ -67,17 +67,17 @@ function __construct(&$errors) { // This should theoretically allow a remote work server to be able to work with // a complete variety of deployed clients, including those without versions. $this->register_uri = $this->work_server_uri.'register'; // register_0_0 - $this->put_work_item_uri = $this->work_server_uri.'putworkitem'; + $this->put_own_work_item_uri = $this->work_server_uri.'putownworkitem'; $this->get_own_work_item_uri = $this->work_server_uri.'getownworkitem'; $this->get_own_work_items_uri = $this->work_server_uri.'getownworkitems'; $this->get_available_work_items_uri = $this->work_server_uri.'getavailableworkitems'; - $this->get_available_work_item_uri = $this->work_server_uri.'getavailableworkitem'; - $this->delete_work_uri = $this->work_server_uri.'deletework'; - $this->update_work_uri = $this->work_server_uri.'updatework'; - $this->put_offer_uri = $this->work_server_uri.'putoffer'; + $this->delete_own_work_item_uri = $this->work_server_uri.'deleteownworkitem'; + $this->update_own_work_item_uri = $this->work_server_uri.'updateownworkitem'; + $this->put_own_offer_uri = $this->work_server_uri.'putownoffer'; $this->get_own_offer_uri = $this->work_server_uri.'getownoffer'; - $this->get_active_offers_uri = $this->work_server_uri.'getactiveoffers'; + $this->get_own_offers_uri = $this->work_server_uri.'getownoffers'; + $this->get_available_offers_uri = $this->work_server_uri.'getavailableoffers'; $this->get_available_offer_uri = $this->work_server_uri.'getavailableoffer'; $this->get_group_items_uri = $this->work_server_uri.'getgroupitems'; @@ -165,7 +165,7 @@ function checkSiteRegistration() { } } - // putWorkItem - publishes a work item in remote work server. + // putOwnWorkItem - publishes a work item in remote work server. // // Note about some fields using additional base64 encoding. // There is a problem with data posted by curl calls on the server side for @@ -179,7 +179,7 @@ function checkSiteRegistration() { // // A workaround for now is to use use an additional base64 encoding for all text fields, // which are decoded back to utf-8 strings on the server side. - function putWorkItem($fields) { + function putOwnWorkItem($fields) { global $i18n; global $user; $mdb2 = getConnection(); @@ -213,7 +213,7 @@ function putWorkItem($fields) { $ch = curl_init(); // Set the url, number of POST vars, POST data. - curl_setopt($ch, CURLOPT_URL, $this->put_work_item_uri); + curl_setopt($ch, CURLOPT_URL, $this->put_own_work_item_uri); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); @@ -245,8 +245,8 @@ function putWorkItem($fields) { return true; } - // updateWork - updates a work item in remote work server. - function updateWork($fields) { + // updateOwnWorkItem - updates a work item in remote work server. + function updateOwnWorkItem($fields) { global $i18n; global $user; $mdb2 = getConnection(); @@ -282,7 +282,7 @@ function updateWork($fields) { $ch = curl_init(); // Set the url, number of POST vars, POST data. - curl_setopt($ch, CURLOPT_URL, $this->update_work_uri); + curl_setopt($ch, CURLOPT_URL, $this->update_own_work_item_uri); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); @@ -488,8 +488,8 @@ function getOwnWorkItem($work_id) { return $work_item; } - // deleteWork - deletes work item from remote work server. - function deleteWork($work_id) { + // deleteOwnWorkItem - deletes work item from remote work server. + function deleteOwnWorkItem($work_id) { global $i18n; global $user; $mdb2 = getConnection(); @@ -518,7 +518,7 @@ function deleteWork($work_id) { $ch = curl_init(); // Set the url, number of POST vars, POST data. - curl_setopt($ch, CURLOPT_URL, $this->delete_work_uri); + curl_setopt($ch, CURLOPT_URL, $this->delete_own_work_item_uri); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); @@ -550,8 +550,8 @@ function deleteWork($work_id) { return true; } - // putOffer - publishes an offer in remote work server. - function putOffer($fields) { + // putOwnOffer - publishes an offer in remote work server. + function putOwnOffer($fields) { global $i18n; global $user; $mdb2 = getConnection(); @@ -586,7 +586,7 @@ function putOffer($fields) { $ch = curl_init(); // Set the url, number of POST vars, POST data. - curl_setopt($ch, CURLOPT_URL, $this->put_offer_uri); + curl_setopt($ch, CURLOPT_URL, $this->put_own_offer_uri); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); @@ -618,8 +618,8 @@ function putOffer($fields) { return true; } - // getActiveOffers - obtains a list of offers this group made available to other groups. - function getActiveOffers() { + // getOwnOffers - obtains a list of offers this group made available to other groups. + function getOwnOffers() { global $i18n; global $user; $mdb2 = getConnection(); @@ -644,7 +644,7 @@ function getActiveOffers() { $ch = curl_init(); // Set the url, number of POST vars, POST data. - curl_setopt($ch, CURLOPT_URL, $this->get_active_offers_uri); + curl_setopt($ch, CURLOPT_URL, $this->get_own_offers_uri); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 8977cddff..4df8f6172 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.19.10.5128 | Copyright © Anuko | +  Anuko Time Tracker 1.19.10.5129 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/offer_add.php b/offer_add.php index a61f6b658..9ee2bf15e 100644 --- a/offer_add.php +++ b/offer_add.php @@ -80,7 +80,7 @@ 'currency' => $currencies[$cl_currency], 'amount' => $cl_budget, 'payment_info' => $cl_payment_info); - if ($workHelper->putOffer($fields)) { + if ($workHelper->putOwnOffer($fields)) { header('Location: work.php'); exit(); } diff --git a/offer_delete.php b/offer_delete.php index f08c82a04..91d84ff20 100644 --- a/offer_delete.php +++ b/offer_delete.php @@ -41,7 +41,7 @@ } $cl_offer_id = (int)$request->getParameter('id'); $workHelper = new ttWorkHelper($err); -$offer = $workHelper->getOffer($cl_offer_id); +$offer = $workHelper->getOwnOffer($cl_offer_id); if (!$offer) { header('Location: access_denied.php'); exit(); diff --git a/work_add.php b/work_add.php index 9bc6d3414..4e183f41f 100644 --- a/work_add.php +++ b/work_add.php @@ -84,7 +84,7 @@ 'descr_long' => $cl_details, 'currency' => $currencies[$cl_currency], 'amount' => $cl_budget); - if ($workHelper->putWorkItem($fields)) { + if ($workHelper->putOwnWorkItem($fields)) { header('Location: work.php'); exit(); } diff --git a/work_delete.php b/work_delete.php index e4a5e24d9..87d7bd7c0 100644 --- a/work_delete.php +++ b/work_delete.php @@ -41,7 +41,7 @@ } $cl_work_id = (int)$request->getParameter('id'); $workHelper = new ttWorkHelper($err); -$work_item = $workHelper->getWork($cl_work_id); +$work_item = $workHelper->getOwnWorkItem($cl_work_id); if (!$work_item) { header('Location: access_denied.php'); exit(); @@ -57,7 +57,7 @@ if ($request->isPost()) { if ($request->getParameter('btn_delete')) { - if ($workHelper->deleteWork($cl_work_id)) { + if ($workHelper->deleteOwnWorkItem($cl_work_id)) { header('Location: work.php'); exit(); } diff --git a/work_edit.php b/work_edit.php index dc38e5696..9ac0abd1b 100644 --- a/work_edit.php +++ b/work_edit.php @@ -101,7 +101,7 @@ 'descr_long' => $cl_details, 'currency' => $currencies[$cl_currency], 'amount' => $cl_budget); - if ($workHelper->updateWork($fields)) { + if ($workHelper->updateOwnWorkItem($fields)) { header('Location: work.php'); exit(); } From 39ceb8311f982c6e3708f92d5a76b51b685b0e5b Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 28 Sep 2019 19:01:11 +0000 Subject: [PATCH 130/877] Finished refactoring URIs for Work server. --- WEB-INF/lib/ttWorkHelper.class.php | 26 ++++++++++++-------------- WEB-INF/templates/footer.tpl | 2 +- offer_delete.php | 2 +- offer_edit.php | 2 +- 4 files changed, 15 insertions(+), 17 deletions(-) diff --git a/WEB-INF/lib/ttWorkHelper.class.php b/WEB-INF/lib/ttWorkHelper.class.php index 3e277d6ec..98cf6631e 100644 --- a/WEB-INF/lib/ttWorkHelper.class.php +++ b/WEB-INF/lib/ttWorkHelper.class.php @@ -45,15 +45,13 @@ class ttWorkHelper { var $put_own_offer_uri = null; // URI to publish own offer. var $get_own_offer_uri = null; // URI to get own offer details. var $get_own_offers_uri = null; // URI to get own offers. - var $get_available_offers_uri = null; // URI to get available offers. var $get_available_offer_uri = null; // URI to get a single available offer. var $get_group_items_uri = null; // URI to get all group items in one API call. - var $delete_offer_uri = null; // URI to delete offer. - var $delete_offers_uri = null; // URI to delete multiple offers. - var $update_offer_uri = null; // URI to update offer. - var $site_id = null; // Site id for remote work server. - var $site_key = null; // Site key for remote work server. + var $delete_own_offer_uri = null; // URI to delete own offer. + var $update_own_offer_uri = null; // URI to update own offer. + var $site_id = null; // Site id for work server. + var $site_key = null; // Site key for work server. // Constructor. function __construct(&$errors) { @@ -81,8 +79,8 @@ function __construct(&$errors) { $this->get_available_offers_uri = $this->work_server_uri.'getavailableoffers'; $this->get_available_offer_uri = $this->work_server_uri.'getavailableoffer'; $this->get_group_items_uri = $this->work_server_uri.'getgroupitems'; - $this->delete_offer_uri = $this->work_server_uri.'deleteoffer'; - $this->update_offer_uri = $this->work_server_uri.'updateoffer'; + $this->delete_own_offer_uri = $this->work_server_uri.'deleteownoffer'; + $this->update_own_offer_uri = $this->work_server_uri.'updateownoffer'; $this->checkSiteRegistration(); } @@ -792,8 +790,8 @@ function getOwnOffer($offer_id) { return $offer; } - // updateOffer - updates an offer in remote work server. - function updateOffer($fields) { + // updateOwnOffer - updates an offer in remote work server. + function updateOwnOffer($fields) { global $i18n; global $user; $mdb2 = getConnection(); @@ -830,7 +828,7 @@ function updateOffer($fields) { $ch = curl_init(); // Set the url, number of POST vars, POST data. - curl_setopt($ch, CURLOPT_URL, $this->update_offer_uri); + curl_setopt($ch, CURLOPT_URL, $this->update_own_offer_uri); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); @@ -862,8 +860,8 @@ function updateOffer($fields) { return true; } - // deleteOffer - deletes an offer from remote work server. - function deleteOffer($offer_id) { + // deleteOwnOffer - deletes an offer from remote work server. + function deleteOwnOffer($offer_id) { global $i18n; global $user; $mdb2 = getConnection(); @@ -892,7 +890,7 @@ function deleteOffer($offer_id) { $ch = curl_init(); // Set the url, number of POST vars, POST data. - curl_setopt($ch, CURLOPT_URL, $this->delete_offer_uri); + curl_setopt($ch, CURLOPT_URL, $this->delete_own_offer_uri); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 4df8f6172..752bd7d92 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.19.10.5129 | Copyright © Anuko | +  Anuko Time Tracker 1.19.10.5130 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/offer_delete.php b/offer_delete.php index 91d84ff20..897248365 100644 --- a/offer_delete.php +++ b/offer_delete.php @@ -57,7 +57,7 @@ if ($request->isPost()) { if ($request->getParameter('btn_delete')) { - if ($workHelper->deleteOffer($cl_offer_id)) { + if ($workHelper->deleteOwnOffer($cl_offer_id)) { header('Location: work.php'); exit(); } diff --git a/offer_edit.php b/offer_edit.php index f39c6cb5c..0f17f7dae 100644 --- a/offer_edit.php +++ b/offer_edit.php @@ -106,7 +106,7 @@ 'currency' => $currencies[$cl_currency], 'amount' => $cl_budget, 'payment_info' => $cl_payment_info); - if ($workHelper->updateOffer($fields)) { + if ($workHelper->updateOwnOffer($fields)) { header('Location: work.php'); exit(); } From d02c087e6f1d54c6f2d6e6037ff868d019d0dd4c Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 28 Sep 2019 19:48:10 +0000 Subject: [PATCH 131/877] Added more parameters to a remote call. --- WEB-INF/lib/ttWorkHelper.class.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/WEB-INF/lib/ttWorkHelper.class.php b/WEB-INF/lib/ttWorkHelper.class.php index 98cf6631e..465fa5f26 100644 --- a/WEB-INF/lib/ttWorkHelper.class.php +++ b/WEB-INF/lib/ttWorkHelper.class.php @@ -1008,6 +1008,12 @@ function getAvailableWorkItem($work_id) { 'site_id' => urlencode($this->site_id), 'site_key' => urlencode($this->site_key), 'org_id' => urlencode($org_id), + 'group_id' => urlencode($group_id), + 'group_name' => urlencode(base64_encode($user->getGroupName())), + 'user_id' => urlencode($user->getUser()), + 'user_name' => urlencode(base64_encode($user->getName())), + 'user_email' => urlencode(base64_encode($user->getEmail())), + 'user_ip' => urlencode($_SERVER['REMOTE_ADDR']), 'work_id' => urlencode($work_id)); // url-ify the data for the POST. From 40aa318e6cb727d98fac9ea3944ef53d940b302d Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 28 Sep 2019 21:57:26 +0000 Subject: [PATCH 132/877] Added more parameters to a remote call. --- WEB-INF/lib/ttWorkHelper.class.php | 6 ++++++ WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/WEB-INF/lib/ttWorkHelper.class.php b/WEB-INF/lib/ttWorkHelper.class.php index 465fa5f26..071d2c2a5 100644 --- a/WEB-INF/lib/ttWorkHelper.class.php +++ b/WEB-INF/lib/ttWorkHelper.class.php @@ -1070,6 +1070,12 @@ function getAvailableOffer($offer_id) { 'site_id' => urlencode($this->site_id), 'site_key' => urlencode($this->site_key), 'org_id' => urlencode($org_id), + 'group_id' => urlencode($group_id), + 'group_name' => urlencode(base64_encode($user->getGroupName())), + 'user_id' => urlencode($user->getUser()), + 'user_name' => urlencode(base64_encode($user->getName())), + 'user_email' => urlencode(base64_encode($user->getEmail())), + 'user_ip' => urlencode($_SERVER['REMOTE_ADDR']), 'offer_id' => urlencode($offer_id)); // url-ify the data for the POST. diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 752bd7d92..859571278 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.19.10.5130 | Copyright © Anuko | +  Anuko Time Tracker 1.19.10.5131 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 9ab93b73bd21c9607f75b55e5fc16002067e4584 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 29 Sep 2019 12:12:24 +0000 Subject: [PATCH 133/877] Starting to work on messaging mechanism in Work plugin. --- WEB-INF/resources/ca.lang.php | 7 ++++--- WEB-INF/resources/cs.lang.php | 7 ++++--- WEB-INF/resources/da.lang.php | 7 ++++--- WEB-INF/resources/de.lang.php | 6 ++++++ WEB-INF/resources/en.lang.php | 7 ++++--- WEB-INF/resources/es.lang.php | 7 ++++--- WEB-INF/resources/et.lang.php | 7 ++++--- WEB-INF/resources/fa.lang.php | 7 ++++--- WEB-INF/resources/fi.lang.php | 7 ++++--- WEB-INF/resources/fr.lang.php | 7 ++++--- WEB-INF/resources/gr.lang.php | 7 ++++--- WEB-INF/resources/he.lang.php | 7 ++++--- WEB-INF/resources/hu.lang.php | 7 ++++--- WEB-INF/resources/it.lang.php | 7 ++++--- WEB-INF/resources/ja.lang.php | 7 ++++--- WEB-INF/resources/ko.lang.php | 7 ++++--- WEB-INF/resources/nl.lang.php | 8 +++++--- WEB-INF/resources/no.lang.php | 7 ++++--- WEB-INF/resources/pl.lang.php | 7 ++++--- WEB-INF/resources/pt-br.lang.php | 7 ++++--- WEB-INF/resources/pt.lang.php | 7 ++++--- WEB-INF/resources/ro.lang.php | 7 ++++--- WEB-INF/resources/ru.lang.php | 7 ++++--- WEB-INF/resources/sk.lang.php | 7 ++++--- WEB-INF/resources/sl.lang.php | 7 ++++--- WEB-INF/resources/sr.lang.php | 7 ++++--- WEB-INF/resources/sv.lang.php | 7 ++++--- WEB-INF/resources/tr.lang.php | 7 ++++--- WEB-INF/resources/zh-cn.lang.php | 7 ++++--- WEB-INF/resources/zh-tw.lang.php | 7 ++++--- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/work_view.tpl | 18 ++++++++++++++++++ 32 files changed, 142 insertions(+), 88 deletions(-) diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index 05ea0188b..97e61cd6e 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -704,8 +704,9 @@ // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', -// Work form. See example at https://timetracker.anuko.com/work.php +// Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. -// 'form.work.work_items' => 'Work Items', -// 'form.work.offers' => 'Offers', +// 'work.button.send_message' => 'Send message', +// 'work.button.make_offer' => 'Make offer', +// 'work.button.accept_offer' => 'Accept offer', ); diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index 632ceca9a..e2b7ebfe9 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -717,8 +717,9 @@ // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', -// Work form. See example at https://timetracker.anuko.com/work.php +// Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. -// 'form.work.work_items' => 'Work Items', -// 'form.work.offers' => 'Offers', +// 'work.button.send_message' => 'Send message', +// 'work.button.make_offer' => 'Make offer', +// 'work.button.accept_offer' => 'Accept offer', ); diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index 299149356..7db1e3451 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -678,8 +678,9 @@ // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', -// Work form. See example at https://timetracker.anuko.com/work.php +// Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. -// 'form.work.work_items' => 'Work Items', -// 'form.work.offers' => 'Offers', +// 'work.button.send_message' => 'Send message', +// 'work.button.make_offer' => 'Make offer', +// 'work.button.accept_offer' => 'Accept offer', ); diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index 0f58ba784..b41ec4dcc 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -653,4 +653,10 @@ // TODO: translate the following. // 'form.display_options.menu' => 'Menu', 'form.display_options.note_on_separate_row' => 'Beschreibung in separater Zeile', + +// Work plugin strings. See example at https://timetracker.anuko.com/work.php +// TODO: translate the following. +// 'work.button.send_message' => 'Send message', +// 'work.button.make_offer' => 'Make offer', +// 'work.button.accept_offer' => 'Accept offer', ); diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index 72106f11f..51d294297 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -635,7 +635,8 @@ 'form.display_options.menu' => 'Menu', 'form.display_options.note_on_separate_row' => 'Note on separate row', -// Work form. See example at https://timetracker.anuko.com/work.php -'form.work.work_items' => 'Work Items', -'form.work.offers' => 'Offers', +// Work plugin strings. See example at https://timetracker.anuko.com/work.php +'work.button.send_message' => 'Send message', +'work.button.make_offer' => 'Make offer', +'work.button.accept_offer' => 'Accept offer', ); diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index d6be47ad2..5e3c11cf3 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -719,8 +719,9 @@ // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', -// Work form. See example at https://timetracker.anuko.com/work.php +// Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. -// 'form.work.work_items' => 'Work Items', -// 'form.work.offers' => 'Offers', +// 'work.button.send_message' => 'Send message', +// 'work.button.make_offer' => 'Make offer', +// 'work.button.accept_offer' => 'Accept offer', ); diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index 53183f3c1..799e69149 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -685,8 +685,9 @@ // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', -// Work form. See example at https://timetracker.anuko.com/work.php +// Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. -// 'form.work.work_items' => 'Work Items', -// 'form.work.offers' => 'Offers', +// 'work.button.send_message' => 'Send message', +// 'work.button.make_offer' => 'Make offer', +// 'work.button.accept_offer' => 'Accept offer', ); diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index f38760cc2..f5ed5a229 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -702,8 +702,9 @@ // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', -// Work form. See example at https://timetracker.anuko.com/work.php +// Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. -// 'form.work.work_items' => 'Work Items', -// 'form.work.offers' => 'Offers', +// 'work.button.send_message' => 'Send message', +// 'work.button.make_offer' => 'Make offer', +// 'work.button.accept_offer' => 'Accept offer', ); diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 379182dc1..8b09ee696 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -684,8 +684,9 @@ // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', -// Work form. See example at https://timetracker.anuko.com/work.php +// Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. -// 'form.work.work_items' => 'Work Items', -// 'form.work.offers' => 'Offers', +// 'work.button.send_message' => 'Send message', +// 'work.button.make_offer' => 'Make offer', +// 'work.button.accept_offer' => 'Accept offer', ); diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index cf374646c..96ef09afe 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -674,8 +674,9 @@ // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', -// Work form. See example at https://timetracker.anuko.com/work.php +// Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. -// 'form.work.work_items' => 'Work Items', -// 'form.work.offers' => 'Offers', +// 'work.button.send_message' => 'Send message', +// 'work.button.make_offer' => 'Make offer', +// 'work.button.accept_offer' => 'Accept offer', ); diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index 67068faa9..be02aaf57 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -667,8 +667,9 @@ // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', -// Work form. See example at https://timetracker.anuko.com/work.php +// Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. -// 'form.work.work_items' => 'Work Items', -// 'form.work.offers' => 'Offers', +// 'work.button.send_message' => 'Send message', +// 'work.button.make_offer' => 'Make offer', +// 'work.button.accept_offer' => 'Accept offer', ); diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index 743077d90..a2c364e74 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -704,8 +704,9 @@ // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', -// Work form. See example at https://timetracker.anuko.com/work.php +// Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. -// 'form.work.work_items' => 'Work Items', -// 'form.work.offers' => 'Offers', +// 'work.button.send_message' => 'Send message', +// 'work.button.make_offer' => 'Make offer', +// 'work.button.accept_offer' => 'Accept offer', ); diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index d6fc4b4e9..c6e210bd6 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -709,8 +709,9 @@ // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', -// Work form. See example at https://timetracker.anuko.com/work.php +// Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. -// 'form.work.work_items' => 'Work Items', -// 'form.work.offers' => 'Offers', +// 'work.button.send_message' => 'Send message', +// 'work.button.make_offer' => 'Make offer', +// 'work.button.accept_offer' => 'Accept offer', ); diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index 7dbc055ba..0bc1a0c9c 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -681,8 +681,9 @@ // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', -// Work form. See example at https://timetracker.anuko.com/work.php +// Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. -// 'form.work.work_items' => 'Work Items', -// 'form.work.offers' => 'Offers', +// 'work.button.send_message' => 'Send message', +// 'work.button.make_offer' => 'Make offer', +// 'work.button.accept_offer' => 'Accept offer', ); diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index 17a18e9df..29fc181f0 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -712,8 +712,9 @@ // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', -// Work form. See example at https://timetracker.anuko.com/work.php +// Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. -// 'form.work.work_items' => 'Work Items', -// 'form.work.offers' => 'Offers', +// 'work.button.send_message' => 'Send message', +// 'work.button.make_offer' => 'Make offer', +// 'work.button.accept_offer' => 'Accept offer', ); diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index c1d03180f..136f2d9b0 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -710,8 +710,9 @@ // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', -// Work form. See example at https://timetracker.anuko.com/work.php +// Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. -// 'form.work.work_items' => 'Work Items', -// 'form.work.offers' => 'Offers', +// 'work.button.send_message' => 'Send message', +// 'work.button.make_offer' => 'Make offer', +// 'work.button.accept_offer' => 'Accept offer', ); diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index cc4fa139c..4487b0ba5 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -636,7 +636,9 @@ 'form.display_options.menu' => 'Menu', 'form.display_options.note_on_separate_row' => 'Notitie in aparte kolom', -// Work form. See example at https://timetracker.anuko.com/work.php -'form.work.work_items' => 'Onderdelen werk', -'form.work.offers' => 'Aanbiedingen', +// Work plugin strings. See example at https://timetracker.anuko.com/work.php +// TODO: translate the following. +// 'work.button.send_message' => 'Send message', +// 'work.button.make_offer' => 'Make offer', +// 'work.button.accept_offer' => 'Accept offer', ); diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index f6e1170a8..bbae702a1 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -709,8 +709,9 @@ // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', -// Work form. See example at https://timetracker.anuko.com/work.php +// Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. -// 'form.work.work_items' => 'Work Items', -// 'form.work.offers' => 'Offers', +// 'work.button.send_message' => 'Send message', +// 'work.button.make_offer' => 'Make offer', +// 'work.button.accept_offer' => 'Accept offer', ); diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index 8499ffba7..d3e2054bb 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -687,8 +687,9 @@ // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', -// Work form. See example at https://timetracker.anuko.com/work.php +// Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. -// 'form.work.work_items' => 'Work Items', -// 'form.work.offers' => 'Offers', +// 'work.button.send_message' => 'Send message', +// 'work.button.make_offer' => 'Make offer', +// 'work.button.accept_offer' => 'Accept offer', ); diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index c0097c711..9fddafbce 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -682,8 +682,9 @@ // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', -// Work form. See example at https://timetracker.anuko.com/work.php +// Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. -// 'form.work.work_items' => 'Work Items', -// 'form.work.offers' => 'Offers', +// 'work.button.send_message' => 'Send message', +// 'work.button.make_offer' => 'Make offer', +// 'work.button.accept_offer' => 'Accept offer', ); diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index ae217cd4a..84bd54c78 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -691,8 +691,9 @@ // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', -// Work form. See example at https://timetracker.anuko.com/work.php +// Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. -// 'form.work.work_items' => 'Work Items', -// 'form.work.offers' => 'Offers', +// 'work.button.send_message' => 'Send message', +// 'work.button.make_offer' => 'Make offer', +// 'work.button.accept_offer' => 'Accept offer', ); diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index 5f5dd12e2..ef709251e 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -712,8 +712,9 @@ // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', -// Work form. See example at https://timetracker.anuko.com/work.php +// Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. -// 'form.work.work_items' => 'Work Items', -// 'form.work.offers' => 'Offers', +// 'work.button.send_message' => 'Send message', +// 'work.button.make_offer' => 'Make offer', +// 'work.button.accept_offer' => 'Accept offer', ); diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index ffdee0d66..32899de1f 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -616,7 +616,8 @@ 'form.display_options.menu' => 'Меню', 'form.display_options.note_on_separate_row' => 'Комментарий в отдельном ряду', -// Work form. See example at https://timetracker.anuko.com/work.php -'form.work.work_items' => 'Единицы работы', -'form.work.offers' => 'Предложения', +// Work plugin strings. See example at https://timetracker.anuko.com/work.php +'work.button.send_message' => 'Отправить сообщение', +'work.button.make_offer' => 'Сделать предложение', +'work.button.accept_offer' => 'Принять предложение', ); diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index 5abde75eb..a9bebd6e6 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -693,8 +693,9 @@ // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', -// Work form. See example at https://timetracker.anuko.com/work.php +// Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. -// 'form.work.work_items' => 'Work Items', -// 'form.work.offers' => 'Offers', +// 'work.button.send_message' => 'Send message', +// 'work.button.make_offer' => 'Make offer', +// 'work.button.accept_offer' => 'Accept offer', ); diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index e7e8f273f..4f95eaa45 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -685,8 +685,9 @@ // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', -// Work form. See example at https://timetracker.anuko.com/work.php +// Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. -// 'form.work.work_items' => 'Work Items', -// 'form.work.offers' => 'Offers', +// 'work.button.send_message' => 'Send message', +// 'work.button.make_offer' => 'Make offer', +// 'work.button.accept_offer' => 'Accept offer', ); diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index 7e92a5b5a..b156243dd 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -685,8 +685,9 @@ // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', -// Work form. See example at https://timetracker.anuko.com/work.php +// Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. -// 'form.work.work_items' => 'Work Items', -// 'form.work.offers' => 'Offers', +// 'work.button.send_message' => 'Send message', +// 'work.button.make_offer' => 'Make offer', +// 'work.button.accept_offer' => 'Accept offer', ); diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index e08a183c3..157990d3e 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -683,8 +683,9 @@ // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', -// Work form. See example at https://timetracker.anuko.com/work.php +// Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. -// 'form.work.work_items' => 'Work Items', -// 'form.work.offers' => 'Offers', +// 'work.button.send_message' => 'Send message', +// 'work.button.make_offer' => 'Make offer', +// 'work.button.accept_offer' => 'Accept offer', ); diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index 27a37e3c0..8bee9061c 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -725,8 +725,9 @@ // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', -// Work form. See example at https://timetracker.anuko.com/work.php +// Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. -// 'form.work.work_items' => 'Work Items', -// 'form.work.offers' => 'Offers', +// 'work.button.send_message' => 'Send message', +// 'work.button.make_offer' => 'Make offer', +// 'work.button.accept_offer' => 'Accept offer', ); diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index 50bfdfb60..02e60b0ba 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -696,8 +696,9 @@ // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', -// Work form. See example at https://timetracker.anuko.com/work.php +// Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. -// 'form.work.work_items' => 'Work Items', -// 'form.work.offers' => 'Offers', +// 'work.button.send_message' => 'Send message', +// 'work.button.make_offer' => 'Make offer', +// 'work.button.accept_offer' => 'Accept offer', ); diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index 39d6afa07..4834c7e99 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -702,8 +702,9 @@ // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', -// Work form. See example at https://timetracker.anuko.com/work.php +// Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. -// 'form.work.work_items' => 'Work Items', -// 'form.work.offers' => 'Offers', +// 'work.button.send_message' => 'Send message', +// 'work.button.make_offer' => 'Make offer', +// 'work.button.accept_offer' => 'Accept offer', ); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 859571278..6c6d48d8a 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.19.10.5131 | Copyright © Anuko | +  Anuko Time Tracker 1.19.10.5132 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/work_view.tpl b/WEB-INF/templates/work_view.tpl index d34b936a6..ab55a4c00 100644 --- a/WEB-INF/templates/work_view.tpl +++ b/WEB-INF/templates/work_view.tpl @@ -1,3 +1,7 @@ + + {$forms.workForm.open} @@ -34,3 +38,17 @@
{$forms.workForm.close} + +{if isTrue('WORK_DEBUG')} + + + + +
+ + + + +
+
+{/if} From ceee8d5924467b10289b8ebec6e28b5316fc1881 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 29 Sep 2019 19:00:03 +0000 Subject: [PATCH 134/877] Some work in progress on making offers for Work plugin. --- WEB-INF/lib/ttWorkHelper.class.php | 33 +++++++++++++++++++++++- WEB-INF/resources/ca.lang.php | 4 +++ WEB-INF/resources/cs.lang.php | 4 +++ WEB-INF/resources/da.lang.php | 4 +++ WEB-INF/resources/de.lang.php | 4 +++ WEB-INF/resources/en.lang.php | 4 +++ WEB-INF/resources/es.lang.php | 4 +++ WEB-INF/resources/et.lang.php | 4 +++ WEB-INF/resources/fa.lang.php | 4 +++ WEB-INF/resources/fi.lang.php | 4 +++ WEB-INF/resources/fr.lang.php | 4 +++ WEB-INF/resources/gr.lang.php | 4 +++ WEB-INF/resources/he.lang.php | 4 +++ WEB-INF/resources/hu.lang.php | 4 +++ WEB-INF/resources/it.lang.php | 4 +++ WEB-INF/resources/ja.lang.php | 4 +++ WEB-INF/resources/ko.lang.php | 4 +++ WEB-INF/resources/nl.lang.php | 4 +++ WEB-INF/resources/no.lang.php | 4 +++ WEB-INF/resources/pl.lang.php | 4 +++ WEB-INF/resources/pt-br.lang.php | 4 +++ WEB-INF/resources/pt.lang.php | 4 +++ WEB-INF/resources/ro.lang.php | 4 +++ WEB-INF/resources/ru.lang.php | 4 +++ WEB-INF/resources/sk.lang.php | 4 +++ WEB-INF/resources/sl.lang.php | 4 +++ WEB-INF/resources/sr.lang.php | 4 +++ WEB-INF/resources/sv.lang.php | 4 +++ WEB-INF/resources/tr.lang.php | 4 +++ WEB-INF/resources/zh-cn.lang.php | 4 +++ WEB-INF/resources/zh-tw.lang.php | 4 +++ WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/work.tpl | 8 ++++-- WEB-INF/templates/work_view.tpl | 3 ++- admin_offer_edit.php | 15 ++++++++--- admin_work_edit.php | 8 +++--- offer_add.php | 40 +++++++++++++++++++++++------- offer_edit.php | 27 +++++++++++++------- work_add.php | 6 ++--- work_edit.php | 9 +++---- work_view.php | 1 + 41 files changed, 233 insertions(+), 39 deletions(-) diff --git a/WEB-INF/lib/ttWorkHelper.class.php b/WEB-INF/lib/ttWorkHelper.class.php index 071d2c2a5..ff979c2af 100644 --- a/WEB-INF/lib/ttWorkHelper.class.php +++ b/WEB-INF/lib/ttWorkHelper.class.php @@ -564,6 +564,7 @@ function putOwnOffer($fields) { 'group_id' => urlencode($group_id), 'group_name' => urlencode(base64_encode($user->getGroupName())), 'group_key' => urlencode($user->getGroupKey()), + 'work_id' => urlencode($fields['work_id']), 'subject' => urlencode(base64_encode($fields['subject'])), 'descr_short' => urlencode(base64_encode($fields['descr_short'])), 'descr_long' => urlencode(base64_encode($fields['descr_long'])), @@ -931,11 +932,41 @@ static function getCurrencies() { if (is_a($res, 'PEAR_Error')) return false; while ($val = $res->fetchRow()) { - $result[] = $val['name']; + $result[] = array('id'=>$val['id'], 'name'=>$val['name']); } return $result; } + // getCurrencyID - obtains an ID for currency. + static function getCurrencyID($currency) { + $mdb2 = getConnection(); + + $currency_id = null; + $sql = "select id from tt_work_currencies where name = ".$mdb2->quote($currency); + $res = $mdb2->query($sql); + if (is_a($res, 'PEAR_Error')) return null; + + if($val = $res->fetchRow()) { + $currency_id = $val['id']; + } + return $currency_id; + } + + // getCurrencyName - obtains currency name using its id. + static function getCurrencyName($currency_id) { + $mdb2 = getConnection(); + + $currency_name = null; + $sql = "select name from tt_work_currencies where id = $currency_id"; + $res = $mdb2->query($sql); + if (is_a($res, 'PEAR_Error')) return null; + + if($val = $res->fetchRow()) { + $currency_name = $val['name']; + } + return $currency_name; + } + // getGroupItems - obtains a list of all items relevant to group in one API call to Remote Work Server. function getGroupItems() { global $i18n; diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index 97e61cd6e..9813ca780 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -706,6 +706,10 @@ // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. +// 'work.error.work_not_available' => 'Work item is not available.', +// 'work.error.offer_not_available' => 'Offer is not available.', +// 'work.label.our_work' => 'Our work', +// 'work.label.our_offers' => 'Our offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', // 'work.button.accept_offer' => 'Accept offer', diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index e2b7ebfe9..6607ed5bb 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -719,6 +719,10 @@ // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. +// 'work.error.work_not_available' => 'Work item is not available.', +// 'work.error.offer_not_available' => 'Offer is not available.', +// 'work.label.our_work' => 'Our work', +// 'work.label.our_offers' => 'Our offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', // 'work.button.accept_offer' => 'Accept offer', diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index 7db1e3451..948b591e2 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -680,6 +680,10 @@ // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. +// 'work.error.work_not_available' => 'Work item is not available.', +// 'work.error.offer_not_available' => 'Offer is not available.', +// 'work.label.our_work' => 'Our work', +// 'work.label.our_offers' => 'Our offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', // 'work.button.accept_offer' => 'Accept offer', diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index b41ec4dcc..045533702 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -656,6 +656,10 @@ // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. +// 'work.error.work_not_available' => 'Work item is not available.', +// 'work.error.offer_not_available' => 'Offer is not available.', +// 'work.label.our_work' => 'Our work', +// 'work.label.our_offers' => 'Our offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', // 'work.button.accept_offer' => 'Accept offer', diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index 51d294297..0bc5fba16 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -636,6 +636,10 @@ 'form.display_options.note_on_separate_row' => 'Note on separate row', // Work plugin strings. See example at https://timetracker.anuko.com/work.php +'work.error.work_not_available' => 'Work item is not available.', +'work.error.offer_not_available' => 'Offer is not available.', +'work.label.our_work' => 'Our work', +'work.label.our_offers' => 'Our offers', 'work.button.send_message' => 'Send message', 'work.button.make_offer' => 'Make offer', 'work.button.accept_offer' => 'Accept offer', diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index 5e3c11cf3..61c466635 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -721,6 +721,10 @@ // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. +// 'work.error.work_not_available' => 'Work item is not available.', +// 'work.error.offer_not_available' => 'Offer is not available.', +// 'work.label.our_work' => 'Our work', +// 'work.label.our_offers' => 'Our offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', // 'work.button.accept_offer' => 'Accept offer', diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index 799e69149..f6a6d5c7b 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -687,6 +687,10 @@ // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. +// 'work.error.work_not_available' => 'Work item is not available.', +// 'work.error.offer_not_available' => 'Offer is not available.', +// 'work.label.our_work' => 'Our work', +// 'work.label.our_offers' => 'Our offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', // 'work.button.accept_offer' => 'Accept offer', diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index f5ed5a229..1866a21ed 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -704,6 +704,10 @@ // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. +// 'work.error.work_not_available' => 'Work item is not available.', +// 'work.error.offer_not_available' => 'Offer is not available.', +// 'work.label.our_work' => 'Our work', +// 'work.label.our_offers' => 'Our offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', // 'work.button.accept_offer' => 'Accept offer', diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 8b09ee696..d7136aaee 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -686,6 +686,10 @@ // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. +// 'work.error.work_not_available' => 'Work item is not available.', +// 'work.error.offer_not_available' => 'Offer is not available.', +// 'work.label.our_work' => 'Our work', +// 'work.label.our_offers' => 'Our offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', // 'work.button.accept_offer' => 'Accept offer', diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index 96ef09afe..b8f22e0a8 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -676,6 +676,10 @@ // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. +// 'work.error.work_not_available' => 'Work item is not available.', +// 'work.error.offer_not_available' => 'Offer is not available.', +// 'work.label.our_work' => 'Our work', +// 'work.label.our_offers' => 'Our offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', // 'work.button.accept_offer' => 'Accept offer', diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index be02aaf57..4b5ab0e7b 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -669,6 +669,10 @@ // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. +// 'work.error.work_not_available' => 'Work item is not available.', +// 'work.error.offer_not_available' => 'Offer is not available.', +// 'work.label.our_work' => 'Our work', +// 'work.label.our_offers' => 'Our offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', // 'work.button.accept_offer' => 'Accept offer', diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index a2c364e74..b8ff35a60 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -706,6 +706,10 @@ // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. +// 'work.error.work_not_available' => 'Work item is not available.', +// 'work.error.offer_not_available' => 'Offer is not available.', +// 'work.label.our_work' => 'Our work', +// 'work.label.our_offers' => 'Our offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', // 'work.button.accept_offer' => 'Accept offer', diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index c6e210bd6..5339cd133 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -711,6 +711,10 @@ // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. +// 'work.error.work_not_available' => 'Work item is not available.', +// 'work.error.offer_not_available' => 'Offer is not available.', +// 'work.label.our_work' => 'Our work', +// 'work.label.our_offers' => 'Our offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', // 'work.button.accept_offer' => 'Accept offer', diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index 0bc1a0c9c..1f287cfd1 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -683,6 +683,10 @@ // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. +// 'work.error.work_not_available' => 'Work item is not available.', +// 'work.error.offer_not_available' => 'Offer is not available.', +// 'work.label.our_work' => 'Our work', +// 'work.label.our_offers' => 'Our offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', // 'work.button.accept_offer' => 'Accept offer', diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index 29fc181f0..f8b18e60c 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -714,6 +714,10 @@ // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. +// 'work.error.work_not_available' => 'Work item is not available.', +// 'work.error.offer_not_available' => 'Offer is not available.', +// 'work.label.our_work' => 'Our work', +// 'work.label.our_offers' => 'Our offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', // 'work.button.accept_offer' => 'Accept offer', diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index 136f2d9b0..d23d8b728 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -712,6 +712,10 @@ // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. +// 'work.error.work_not_available' => 'Work item is not available.', +// 'work.error.offer_not_available' => 'Offer is not available.', +// 'work.label.our_work' => 'Our work', +// 'work.label.our_offers' => 'Our offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', // 'work.button.accept_offer' => 'Accept offer', diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 4487b0ba5..71ca76659 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -638,6 +638,10 @@ // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. +// 'work.error.work_not_available' => 'Work item is not available.', +// 'work.error.offer_not_available' => 'Offer is not available.', +// 'work.label.our_work' => 'Our work', +// 'work.label.our_offers' => 'Our offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', // 'work.button.accept_offer' => 'Accept offer', diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index bbae702a1..4c55fbca4 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -711,6 +711,10 @@ // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. +// 'work.error.work_not_available' => 'Work item is not available.', +// 'work.error.offer_not_available' => 'Offer is not available.', +// 'work.label.our_work' => 'Our work', +// 'work.label.our_offers' => 'Our offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', // 'work.button.accept_offer' => 'Accept offer', diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index d3e2054bb..90b8ade2e 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -689,6 +689,10 @@ // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. +// 'work.error.work_not_available' => 'Work item is not available.', +// 'work.error.offer_not_available' => 'Offer is not available.', +// 'work.label.our_work' => 'Our work', +// 'work.label.our_offers' => 'Our offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', // 'work.button.accept_offer' => 'Accept offer', diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index 9fddafbce..1108dbddf 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -684,6 +684,10 @@ // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. +// 'work.error.work_not_available' => 'Work item is not available.', +// 'work.error.offer_not_available' => 'Offer is not available.', +// 'work.label.our_work' => 'Our work', +// 'work.label.our_offers' => 'Our offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', // 'work.button.accept_offer' => 'Accept offer', diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index 84bd54c78..f3c9e9b46 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -693,6 +693,10 @@ // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. +// 'work.error.work_not_available' => 'Work item is not available.', +// 'work.error.offer_not_available' => 'Offer is not available.', +// 'work.label.our_work' => 'Our work', +// 'work.label.our_offers' => 'Our offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', // 'work.button.accept_offer' => 'Accept offer', diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index ef709251e..c1ab74e33 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -714,6 +714,10 @@ // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. +// 'work.error.work_not_available' => 'Work item is not available.', +// 'work.error.offer_not_available' => 'Offer is not available.', +// 'work.label.our_work' => 'Our work', +// 'work.label.our_offers' => 'Our offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', // 'work.button.accept_offer' => 'Accept offer', diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index 32899de1f..9cf026772 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -617,6 +617,10 @@ 'form.display_options.note_on_separate_row' => 'Комментарий в отдельном ряду', // Work plugin strings. See example at https://timetracker.anuko.com/work.php +'work.error.work_not_available' => 'Работа отсутствует.', +'work.error.offer_not_available' => 'Предложение отсутствует.', +'work.label.our_work' => 'Наша работа', +'work.label.our_offers' => 'Наши предложения', 'work.button.send_message' => 'Отправить сообщение', 'work.button.make_offer' => 'Сделать предложение', 'work.button.accept_offer' => 'Принять предложение', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index a9bebd6e6..0620b34d5 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -695,6 +695,10 @@ // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. +// 'work.error.work_not_available' => 'Work item is not available.', +// 'work.error.offer_not_available' => 'Offer is not available.', +// 'work.label.our_work' => 'Our work', +// 'work.label.our_offers' => 'Our offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', // 'work.button.accept_offer' => 'Accept offer', diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index 4f95eaa45..5ec29ac97 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -687,6 +687,10 @@ // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. +// 'work.error.work_not_available' => 'Work item is not available.', +// 'work.error.offer_not_available' => 'Offer is not available.', +// 'work.label.our_work' => 'Our work', +// 'work.label.our_offers' => 'Our offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', // 'work.button.accept_offer' => 'Accept offer', diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index b156243dd..d1056c260 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -687,6 +687,10 @@ // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. +// 'work.error.work_not_available' => 'Work item is not available.', +// 'work.error.offer_not_available' => 'Offer is not available.', +// 'work.label.our_work' => 'Our work', +// 'work.label.our_offers' => 'Our offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', // 'work.button.accept_offer' => 'Accept offer', diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index 157990d3e..750065efa 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -685,6 +685,10 @@ // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. +// 'work.error.work_not_available' => 'Work item is not available.', +// 'work.error.offer_not_available' => 'Offer is not available.', +// 'work.label.our_work' => 'Our work', +// 'work.label.our_offers' => 'Our offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', // 'work.button.accept_offer' => 'Accept offer', diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index 8bee9061c..4127780f9 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -727,6 +727,10 @@ // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. +// 'work.error.work_not_available' => 'Work item is not available.', +// 'work.error.offer_not_available' => 'Offer is not available.', +// 'work.label.our_work' => 'Our work', +// 'work.label.our_offers' => 'Our offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', // 'work.button.accept_offer' => 'Accept offer', diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index 02e60b0ba..739f23db4 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -698,6 +698,10 @@ // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. +// 'work.error.work_not_available' => 'Work item is not available.', +// 'work.error.offer_not_available' => 'Offer is not available.', +// 'work.label.our_work' => 'Our work', +// 'work.label.our_offers' => 'Our offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', // 'work.button.accept_offer' => 'Accept offer', diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index 4834c7e99..2c0928ae3 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -704,6 +704,10 @@ // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. +// 'work.error.work_not_available' => 'Work item is not available.', +// 'work.error.offer_not_available' => 'Offer is not available.', +// 'work.label.our_work' => 'Our work', +// 'work.label.our_offers' => 'Our offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', // 'work.button.accept_offer' => 'Accept offer', diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 6c6d48d8a..a7fe25978 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.19.10.5132 | Copyright © Anuko | +  Anuko Time Tracker 1.19.10.5133 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/work.tpl b/WEB-INF/templates/work.tpl index 03ab18bf6..f790c2420 100644 --- a/WEB-INF/templates/work.tpl +++ b/WEB-INF/templates/work.tpl @@ -7,7 +7,7 @@ {if $active_work} - + @@ -67,7 +67,7 @@ {if $active_offers}
{$i18n.title.active_work}
{$i18n.work.label.our_work}
{$i18n.label.work} {$i18n.label.description}
- + @@ -78,7 +78,11 @@ {foreach $active_offers as $offer} + {if $offer.work_id} + + {else} + {/if} diff --git a/WEB-INF/templates/work_view.tpl b/WEB-INF/templates/work_view.tpl index ab55a4c00..90ca1b8b0 100644 --- a/WEB-INF/templates/work_view.tpl +++ b/WEB-INF/templates/work_view.tpl @@ -45,7 +45,8 @@ diff --git a/admin_offer_edit.php b/admin_offer_edit.php index 15afe8ae6..7c66a7a83 100644 --- a/admin_offer_edit.php +++ b/admin_offer_edit.php @@ -46,6 +46,13 @@ } // End of access checks. +// Is this offer associated with a work item? +$work_id = $offer['work_id']; +if ($work_id) { + $work_item = $adminWorkHelper->getWorkItem($work_id); + if (!$work_item) $err->add($i18n->get('work.error.work_not_available')); +} + $existingStatus = $offer['status']; $currencies = ttWorkHelper::getCurrencies(); @@ -53,7 +60,7 @@ $cl_name = trim($request->getParameter('offer_name')); $cl_description = trim($request->getParameter('description')); $cl_details = trim($request->getParameter('details')); - $cl_currency = $request->getParameter('currency'); + $cl_currency_id = $request->getParameter('currency'); $cl_budget = $request->getParameter('budget'); $cl_status = $request->getParameter('status'); $cl_moderator_comment = $request->getParameter('moderator_comment'); @@ -62,7 +69,7 @@ $cl_description = $offer['descr_short']; $cl_details = $offer['descr_long']; $currency = $offer['currency']; - $cl_currency = array_search($currency, $currencies); + $cl_currency_id = ttWorkHelper::getCurrencyID($offer['currency']); $cl_budget = $offer['amount']; $cl_status = $offer['status']; $cl_moderator_comment = $offer['moderator_comment']; @@ -73,7 +80,7 @@ $form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'offer_name','style'=>'width: 250px;','value'=>$cl_name)); $form->addInput(array('type'=>'textarea','name'=>'description','style'=>'width: 250px; height: 40px;','value'=>$cl_description)); $form->addInput(array('type'=>'textarea','name'=>'details','style'=>'width: 250px; height: 80px;','value'=>$cl_details)); -$form->addInput(array('type'=>'combobox','name'=>'currency','data'=>$currencies,'value'=>$cl_currency)); +$form->addInput(array('type'=>'combobox','name'=>'currency','data'=>$currencies,'datakeys'=>array('id','name'),'value'=>$cl_currency_id)); $form->addInput(array('type'=>'floatfield','maxlength'=>'10','name'=>'budget','format'=>'.2','value'=>$cl_budget)); // Prepare status choices. @@ -103,7 +110,7 @@ 'subject'=>$cl_name, 'descr_short' => $cl_description, 'descr_long' => $cl_details, - 'currency' => $currencies[$cl_currency], + 'currency' => ttWorkHelper::getCurrencyName($cl_currency_id), 'amount' => $cl_budget, 'moderator_comment' => $cl_moderator_comment); diff --git a/admin_work_edit.php b/admin_work_edit.php index 9700b05d9..5f5a75cc8 100644 --- a/admin_work_edit.php +++ b/admin_work_edit.php @@ -54,7 +54,7 @@ $cl_name = trim($request->getParameter('work_name')); $cl_description = trim($request->getParameter('description')); $cl_details = trim($request->getParameter('details')); - $cl_currency = $request->getParameter('currency'); + $cl_currency_id = $request->getParameter('currency'); $cl_budget = $request->getParameter('budget'); $cl_status = $request->getParameter('status'); $cl_moderator_comment = $request->getParameter('moderator_comment'); @@ -63,7 +63,7 @@ $cl_description = $work_item['descr_short']; $cl_details = $work_item['descr_long']; $currency = $work_item['currency']; - $cl_currency = array_search($currency, $currencies); + $cl_currency_id = ttWorkHelper::getCurrencyID($offer['currency']); $cl_budget = $work_item['amount']; $cl_status = $work_item['status']; $cl_moderator_comment = $work_item['moderator_comment']; @@ -74,7 +74,7 @@ $form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'work_name','style'=>'width: 400px;','value'=>$cl_name)); $form->addInput(array('type'=>'textarea','name'=>'description','style'=>'width: 400px; height: 80px;','value'=>$cl_description)); $form->addInput(array('type'=>'textarea','name'=>'details','style'=>'width: 400px; height: 200px;','value'=>$cl_details)); -$form->addInput(array('type'=>'combobox','name'=>'currency','data'=>$currencies,'value'=>$cl_currency)); +$form->addInput(array('type'=>'combobox','name'=>'currency','data'=>$currencies,'datakeys'=>array('id','name'),'value'=>$cl_currency_id)); $form->addInput(array('type'=>'floatfield','maxlength'=>'10','name'=>'budget','format'=>'.2','value'=>$cl_budget)); // Prepare status choices. @@ -104,7 +104,7 @@ 'subject'=>$cl_name, 'descr_short' => $cl_description, 'descr_long' => $cl_details, - 'currency' => $currencies[$cl_currency], + 'currency' => ttWorkHelper::getCurrencyName($cl_currency_id), 'amount' => $cl_budget, 'moderator_comment' => $cl_moderator_comment); diff --git a/offer_add.php b/offer_add.php index 9ee2bf15e..4a652a1b9 100644 --- a/offer_add.php +++ b/offer_add.php @@ -39,26 +39,47 @@ header('Location: feature_disabled.php'); exit(); } +// Do we have work_id? +$cl_work_id = (int)$request->getParameter('work_id'); +if ($cl_work_id) { + $workHelper = new ttWorkHelper($err); + $work_item = $workHelper->getAvailableWorkItem($cl_work_id); + if (!$work_item) { + header('Location: access_denied.php'); + exit(); + } +} // End of access checks. +if ($work_item) $cl_name = $work_item['subject']; if ($request->isPost()) { - $cl_name = trim($request->getParameter('offer_name')); + if (!$work_item) + $cl_name = trim($request->getParameter('offer_name')); $cl_description = trim($request->getParameter('description')); $cl_details = trim($request->getParameter('details')); - $cl_currency = $request->getParameter('currency'); + $cl_currency_id = $request->getParameter('currency'); + if (!$cl_currency_id && $work_item) $cl_currency_id = ttWorkHelper::getCurrencyID($work_item['currency']); $cl_budget = $request->getParameter('budget'); $cl_payment_info = $request->getParameter('payment_info'); +} else { + if ($work_item) { + $cl_currency_id = ttWorkHelper::getCurrencyID($work_item['currency']); + } } $form = new Form('offerForm'); -$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'offer_name','style'=>'width: 250px;','value'=>$cl_name)); -$form->addInput(array('type'=>'textarea','name'=>'description','style'=>'width: 250px; height: 40px;','value'=>$cl_description)); -$form->addInput(array('type'=>'textarea','name'=>'details','style'=>'width: 250px; height: 80px;','value'=>$cl_details)); +$form->addInput(array('type'=>'hidden','name'=>'work_id','value'=>$cl_work_id)); +$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'offer_name','style'=>'width: 400px;','value'=>$cl_name)); +if ($work_item) $form->getElement('offer_name')->setEnabled(false); + +$form->addInput(array('type'=>'textarea','name'=>'description','style'=>'width: 400px; height: 80px;','value'=>$cl_description)); +$form->addInput(array('type'=>'textarea','name'=>'details','style'=>'width: 400px; height: 200px;','value'=>$cl_details)); // Add a dropdown for currency. $currencies = ttWorkHelper::getCurrencies(); -$form->addInput(array('type'=>'combobox','name'=>'currency','data'=>$currencies,'value'=>$cl_currency)); +$form->addInput(array('type'=>'combobox','name'=>'currency','data'=>$currencies,'datakeys'=>array('id','name'),'value'=>$cl_currency_id)); +if ($work_item) $form->getElement('currency')->setEnabled(false); // Do not allow changing currency for offers on existing work items. $form->addInput(array('type'=>'floatfield','maxlength'=>'10','name'=>'budget','format'=>'.2','value'=>$cl_budget)); -$form->addInput(array('type'=>'textarea','name'=>'payment_info','style'=>'width: 250px; height: 40px;vertical-align: middle','value'=>$cl_payment_info)); +$form->addInput(array('type'=>'textarea','name'=>'payment_info','style'=>'width: 400px; height: 40px;vertical-align: middle','value'=>$cl_payment_info)); $form->addInput(array('type'=>'submit','name'=>'btn_add','value'=>$i18n->get('button.add'))); if ($request->isPost()) { @@ -74,10 +95,11 @@ if ($err->no()) { $workHelper = new ttWorkHelper($err); - $fields = array('subject'=>$cl_name, + $fields = array('work_id'=>$cl_work_id, + 'subject'=>$cl_name, 'descr_short' => $cl_description, 'descr_long' => $cl_details, - 'currency' => $currencies[$cl_currency], + 'currency' => ttWorkHelper::getCurrencyName($cl_currency_id), 'amount' => $cl_budget, 'payment_info' => $cl_payment_info); if ($workHelper->putOwnOffer($fields)) { diff --git a/offer_edit.php b/offer_edit.php index 0f17f7dae..e4afd3078 100644 --- a/offer_edit.php +++ b/offer_edit.php @@ -48,21 +48,28 @@ } // End of access checks. +// Is this offer associated with a work item? +$work_id = $offer['work_id']; +if ($work_id) { + $work_item = $workHelper->getAvailableWorkItem($work_id); + if (!$work_item) $err->add($i18n->get('work.error.work_not_available')); +} + $currencies = ttWorkHelper::getCurrencies(); if ($request->isPost()) { $cl_name = trim($request->getParameter('offer_name')); $cl_description = trim($request->getParameter('description')); $cl_details = trim($request->getParameter('details')); - $cl_currency = $request->getParameter('currency'); + $cl_currency_id = $request->getParameter('currency'); + if (!$cl_currency_id && $work_item) $cl_currency_id = ttWorkHelper::getCurrencyID($work_item['currency']); $cl_budget = $request->getParameter('budget'); $cl_payment_info = $request->getParameter('payment_info'); } else { $cl_name = $offer['subject']; $cl_description = $offer['descr_short']; $cl_details = $offer['descr_long']; - $currency = $offer['currency']; - $cl_currency = array_search($currency, $currencies); + $cl_currency_id = ttWorkHelper::getCurrencyID($offer['currency']); $cl_budget = $offer['amount']; $cl_payment_info = $offer['payment_info']; $cl_status = $offer['status_label']; @@ -73,12 +80,14 @@ $form = new Form('offerForm'); $form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_offer_id)); -$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'offer_name','style'=>'width: 250px;','value'=>$cl_name)); -$form->addInput(array('type'=>'textarea','name'=>'description','style'=>'width: 250px; height: 40px;','value'=>$cl_description)); -$form->addInput(array('type'=>'textarea','name'=>'details','style'=>'width: 250px; height: 80px;','value'=>$cl_details)); -$form->addInput(array('type'=>'combobox','name'=>'currency','data'=>$currencies,'value'=>$cl_currency)); +$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'offer_name','style'=>'width: 400px;','value'=>$cl_name)); +if ($work_id) $form->getElement('offer_name')->setEnabled(false); +$form->addInput(array('type'=>'textarea','name'=>'description','style'=>'width: 400px; height: 80px;','value'=>$cl_description)); +$form->addInput(array('type'=>'textarea','name'=>'details','style'=>'width: 400px; height: 200px;','value'=>$cl_details)); +$form->addInput(array('type'=>'combobox','name'=>'currency','data'=>$currencies,'datakeys'=>array('id','name'),'value'=>$cl_currency_id)); +if ($work_id) $form->getElement('currency')->setEnabled(false); $form->addInput(array('type'=>'floatfield','maxlength'=>'10','name'=>'budget','format'=>'.2','value'=>$cl_budget)); -$form->addInput(array('type'=>'textarea','name'=>'payment_info','style'=>'width: 250px; height: 40px;vertical-align: middle','value'=>$cl_payment_info)); +$form->addInput(array('type'=>'textarea','name'=>'payment_info','style'=>'width: 400px; height: 40px;vertical-align: middle','value'=>$cl_payment_info)); $form->addInput(array('type'=>'text','name'=>'status','value'=>$cl_status)); $form->getElement('status')->setEnabled(false); $form->addInput(array('type'=>'textarea','name'=>'moderator_comment','style'=>'width: 250px; height: 80px;','value'=>$cl_moderator_comment)); @@ -103,7 +112,7 @@ 'subject'=>$cl_name, 'descr_short' => $cl_description, 'descr_long' => $cl_details, - 'currency' => $currencies[$cl_currency], + 'currency' => ttWorkHelper::getCurrencyName($cl_currency_id), 'amount' => $cl_budget, 'payment_info' => $cl_payment_info); if ($workHelper->updateOwnOffer($fields)) { diff --git a/work_add.php b/work_add.php index 4e183f41f..8645891f1 100644 --- a/work_add.php +++ b/work_add.php @@ -45,7 +45,7 @@ $cl_name = trim($request->getParameter('work_name')); $cl_description = trim($request->getParameter('description')); $cl_details = trim($request->getParameter('details')); - $cl_currency = $request->getParameter('currency'); + $cl_currency_id = $request->getParameter('currency'); $cl_budget = $request->getParameter('budget'); } @@ -55,7 +55,7 @@ $form->addInput(array('type'=>'textarea','name'=>'details','style'=>'width: 250px; height: 80px;','value'=>$cl_details)); // Add a dropdown for currency. $currencies = ttWorkHelper::getCurrencies(); -$form->addInput(array('type'=>'combobox','name'=>'currency','data'=>$currencies,'value'=>$cl_currency)); +$form->addInput(array('type'=>'combobox','name'=>'currency','data'=>$currencies,'datakeys'=>array('id','name'),'value'=>$cl_currency_id)); $form->addInput(array('type'=>'floatfield','maxlength'=>'10','name'=>'budget','format'=>'.2','value'=>$cl_budget)); $form->addInput(array('type'=>'submit','name'=>'btn_add','value'=>$i18n->get('button.add'))); @@ -82,7 +82,7 @@ $fields = array('subject'=>$cl_name, 'descr_short' => $cl_description, 'descr_long' => $cl_details, - 'currency' => $currencies[$cl_currency], + 'currency' => ttWorkHelper::getCurrencyName($cl_currency_id), 'amount' => $cl_budget); if ($workHelper->putOwnWorkItem($fields)) { header('Location: work.php'); diff --git a/work_edit.php b/work_edit.php index 9ac0abd1b..9adc12f1d 100644 --- a/work_edit.php +++ b/work_edit.php @@ -54,14 +54,13 @@ $cl_name = trim($request->getParameter('work_name')); $cl_description = trim($request->getParameter('description')); $cl_details = trim($request->getParameter('details')); - $cl_currency = $request->getParameter('currency'); + $cl_currency_id = $request->getParameter('currency'); $cl_budget = $request->getParameter('budget'); } else { $cl_name = $work_item['subject']; $cl_description = $work_item['descr_short']; $cl_details = $work_item['descr_long']; - $currency = $work_item['currency']; - $cl_currency = array_search($currency, $currencies); + $cl_currency_id = ttWorkHelper::getCurrencyID($work_item['currency']); $cl_budget = $work_item['amount']; $cl_status = $work_item['status_label']; $cl_moderator_comment = $work_item['moderator_comment']; @@ -74,7 +73,7 @@ $form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'work_name','style'=>'width: 250px;','value'=>$cl_name)); $form->addInput(array('type'=>'textarea','name'=>'description','style'=>'width: 250px; height: 40px;','value'=>$cl_description)); $form->addInput(array('type'=>'textarea','name'=>'details','style'=>'width: 250px; height: 80px;','value'=>$cl_details)); -$form->addInput(array('type'=>'combobox','name'=>'currency','data'=>$currencies,'value'=>$cl_currency)); +$form->addInput(array('type'=>'combobox','name'=>'currency','data'=>$currencies,'datakeys'=>array('id','name'),'value'=>$cl_currency_id)); $form->addInput(array('type'=>'floatfield','maxlength'=>'10','name'=>'budget','format'=>'.2','value'=>$cl_budget)); $form->addInput(array('type'=>'text','name'=>'status','value'=>$cl_status)); $form->getElement('status')->setEnabled(false); @@ -99,7 +98,7 @@ 'subject'=>$cl_name, 'descr_short' => $cl_description, 'descr_long' => $cl_details, - 'currency' => $currencies[$cl_currency], + 'currency' => ttWorkHelper::getCurrencyName($cl_currency_id), 'amount' => $cl_budget); if ($workHelper->updateOwnWorkItem($fields)) { header('Location: work.php'); diff --git a/work_view.php b/work_view.php index 6e9266c61..d3addcc06 100644 --- a/work_view.php +++ b/work_view.php @@ -67,6 +67,7 @@ $form->addInput(array('type'=>'text','name'=>'budget','value'=>$cl_budget)); $form->getElement('budget')->setEnabled(false); +$smarty->assign('work_id', $cl_work_id); $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('title', $i18n->get('title.work')); $smarty->assign('content_page_name', 'work_view.tpl'); From 3999488d456d2384ec13f48af3b0063948037ff9 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 6 Oct 2019 18:00:01 +0000 Subject: [PATCH 135/877] Allowed comma-separated recipients in notifications. --- WEB-INF/templates/admin_offer_edit.tpl | 17 +++++++++++++++++ WEB-INF/templates/footer.tpl | 2 +- admin_offer_edit.php | 17 +++++++++++++---- admin_work_edit.php | 2 +- notification_add.php | 4 ++-- notification_edit.php | 4 ++-- 6 files changed, 36 insertions(+), 10 deletions(-) diff --git a/WEB-INF/templates/admin_offer_edit.tpl b/WEB-INF/templates/admin_offer_edit.tpl index edf3e5328..5831ae0c8 100644 --- a/WEB-INF/templates/admin_offer_edit.tpl +++ b/WEB-INF/templates/admin_offer_edit.tpl @@ -3,6 +3,23 @@
{$i18n.title.active_offers}
{$i18n.work.label.our_offers}
{$i18n.label.offer} {$i18n.label.description}
{$offer.subject|escape}{$offer.subject|escape}{$offer.description|escape} {$offer.status_label} {$offer.amount_with_currency} - + +
+{if $work_id} + + + + + + + + + {if $work_details} + + + + + {/if} + +{/if} diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index a7fe25978..c3926c690 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
{$i18n.label.work}:{$work_name}
{$i18n.label.description}:{$work_description}
{$i18n.label.details}:{$work_details}
 
{$i18n.label.offer} (*): {$forms.offerForm.offer_name.control}
-
 Anuko Time Tracker 1.19.10.5133 | Copyright © Anuko | +  Anuko Time Tracker 1.19.10.5134 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/admin_offer_edit.php b/admin_offer_edit.php index 7c66a7a83..d47b6a40c 100644 --- a/admin_offer_edit.php +++ b/admin_offer_edit.php @@ -61,6 +61,7 @@ $cl_description = trim($request->getParameter('description')); $cl_details = trim($request->getParameter('details')); $cl_currency_id = $request->getParameter('currency'); + if (!$cl_currency_id && $work_item) $cl_currency_id = ttWorkHelper::getCurrencyID($work_item['currency']); $cl_budget = $request->getParameter('budget'); $cl_status = $request->getParameter('status'); $cl_moderator_comment = $request->getParameter('moderator_comment'); @@ -77,10 +78,12 @@ $form = new Form('offerForm'); $form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_offer_id)); -$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'offer_name','style'=>'width: 250px;','value'=>$cl_name)); -$form->addInput(array('type'=>'textarea','name'=>'description','style'=>'width: 250px; height: 40px;','value'=>$cl_description)); -$form->addInput(array('type'=>'textarea','name'=>'details','style'=>'width: 250px; height: 80px;','value'=>$cl_details)); +$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'offer_name','style'=>'width: 400px;','value'=>$cl_name)); +if ($work_id) $form->getElement('offer_name')->setEnabled(false); +$form->addInput(array('type'=>'textarea','name'=>'description','style'=>'width: 400px; height: 80px;','value'=>$cl_description)); +$form->addInput(array('type'=>'textarea','name'=>'details','style'=>'width: 400px; height: 200px;','value'=>$cl_details)); $form->addInput(array('type'=>'combobox','name'=>'currency','data'=>$currencies,'datakeys'=>array('id','name'),'value'=>$cl_currency_id)); +if ($work_id) $form->getElement('currency')->setEnabled(false); $form->addInput(array('type'=>'floatfield','maxlength'=>'10','name'=>'budget','format'=>'.2','value'=>$cl_budget)); // Prepare status choices. @@ -90,7 +93,7 @@ $status_options[STATUS_APPROVED] = $i18n->get('dropdown.approved'); $form->addInput(array('type'=>'combobox','name'=>'status','value'=>$cl_status,'data'=>$status_options)); -$form->addInput(array('type'=>'textarea','name'=>'moderator_comment','style'=>'width: 250px; height: 80px;','value'=>$cl_moderator_comment)); +$form->addInput(array('type'=>'textarea','name'=>'moderator_comment','style'=>'width: 400px; height: 80px;','value'=>$cl_moderator_comment)); $form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); if ($request->isPost()) { @@ -138,6 +141,12 @@ } } // isPost +if ($work_id) { + $smarty->assign('work_id', $work_id); + $smarty->assign('work_name', $work_item['subject']); + $smarty->assign('work_description', $work_item['descr_short']); + $smarty->assign('work_details', $work_item['descr_long']); +} $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('title', $i18n->get('title.edit_offer')); $smarty->assign('content_page_name', 'admin_offer_edit.tpl'); diff --git a/admin_work_edit.php b/admin_work_edit.php index 5f5a75cc8..c1d8a257a 100644 --- a/admin_work_edit.php +++ b/admin_work_edit.php @@ -63,7 +63,7 @@ $cl_description = $work_item['descr_short']; $cl_details = $work_item['descr_long']; $currency = $work_item['currency']; - $cl_currency_id = ttWorkHelper::getCurrencyID($offer['currency']); + $cl_currency_id = ttWorkHelper::getCurrencyID($work_item['currency']); $cl_budget = $work_item['amount']; $cl_status = $work_item['status']; $cl_moderator_comment = $work_item['moderator_comment']; diff --git a/notification_add.php b/notification_add.php index 05a095468..c6b37fe65 100644 --- a/notification_add.php +++ b/notification_add.php @@ -87,8 +87,8 @@ // Validate user input. if (!$cl_fav_report_id) $err->add($i18n->get('error.report')); if (!ttValidCronSpec($cl_cron_spec)) $err->add($i18n->get('error.field'), $i18n->get('label.schedule')); - if (!ttValidEmail($cl_email)) $err->add($i18n->get('error.field'), $i18n->get('label.email')); - if (!ttValidEmail($cl_cc, true)) $err->add($i18n->get('error.field'), $i18n->get('label.cc')); + if (!ttValidEmailList($cl_email)) $err->add($i18n->get('error.field'), $i18n->get('form.email')); + if (!ttValidEmailList($cl_cc, true)) $err->add($i18n->get('error.field'), $i18n->get('label.cc')); if (!ttValidString($cl_subject, true)) $err->add($i18n->get('error.field'), $i18n->get('label.subject')); if (!ttValidCondition($cl_report_condition)) $err->add($i18n->get('error.field'), $i18n->get('label.condition')); diff --git a/notification_edit.php b/notification_edit.php index 90b84e5a3..8af8dc8c4 100644 --- a/notification_edit.php +++ b/notification_edit.php @@ -99,8 +99,8 @@ // Validate user input. if (!$cl_fav_report_id) $err->add($i18n->get('error.report')); if (!ttValidCronSpec($cl_cron_spec)) $err->add($i18n->get('error.field'), $i18n->get('label.schedule')); - if (!ttValidEmail($cl_email)) $err->add($i18n->get('error.field'), $i18n->get('label.email')); - if (!ttValidEmail($cl_cc, true)) $err->add($i18n->get('error.field'), $i18n->get('label.cc')); + if (!ttValidEmailList($cl_email)) $err->add($i18n->get('error.field'), $i18n->get('form.email')); + if (!ttValidEmailList($cl_cc, true)) $err->add($i18n->get('error.field'), $i18n->get('label.cc')); if (!ttValidString($cl_subject, true)) $err->add($i18n->get('error.field'), $i18n->get('label.subject')); if (!ttValidCondition($cl_report_condition)) $err->add($i18n->get('error.field'), $i18n->get('label.condition')); From 346f642be712b394227003e0121ae926af967de2 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 6 Oct 2019 19:25:58 +0000 Subject: [PATCH 136/877] Fixed fav reports sent in notifications for custom date formats. --- WEB-INF/lib/ttFavReportHelper.class.php | 6 ++++++ WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/WEB-INF/lib/ttFavReportHelper.class.php b/WEB-INF/lib/ttFavReportHelper.class.php index 05b863fba..4cc1b0614 100644 --- a/WEB-INF/lib/ttFavReportHelper.class.php +++ b/WEB-INF/lib/ttFavReportHelper.class.php @@ -544,6 +544,12 @@ static function adjustOptions($options) { // TODO: add project fields here. } + // Adjust period_start and period_end to user date format. + if ($options['period_start']) + $options['period_start'] = ttDateToUserFormat($options['period_start']); + if ($options['period_end']) + $options['period_end'] = ttDateToUserFormat($options['period_end']); + return $options; } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index c3926c690..587d9af04 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.19.10.5134 | Copyright © Anuko | +  Anuko Time Tracker 1.19.11.5135 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From eefb68aa9f23f65f255f78479fa0a1409266b19d Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 8 Oct 2019 14:18:27 +0000 Subject: [PATCH 137/877] Added max length attribute to some work plugin related controls. --- WEB-INF/lib/form/TextArea.class.php | 1 - WEB-INF/templates/footer.tpl | 2 +- admin_offer_edit.php | 4 ++-- admin_work_edit.php | 4 ++-- offer_add.php | 5 ++--- offer_edit.php | 4 ++-- offer_view.php | 4 ++-- work_add.php | 4 ++-- work_edit.php | 4 ++-- work_view.php | 4 ++-- 10 files changed, 17 insertions(+), 19 deletions(-) diff --git a/WEB-INF/lib/form/TextArea.class.php b/WEB-INF/lib/form/TextArea.class.php index ee68fcb87..715a6ea95 100644 --- a/WEB-INF/lib/form/TextArea.class.php +++ b/WEB-INF/lib/form/TextArea.class.php @@ -47,7 +47,6 @@ function getHtml() { if ($this->max_length!="") { if ($this->mOnKeyPress) $this->mOnKeyPress .= ";"; - $this->mOnKeyPress .= "return validateMaxLenght_".$this->name."(this, event);"; $html .= " maxlength=\"$this->max_length\""; } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 587d9af04..f696c4d73 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- + + + + diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index f696c4d73..66400b0b8 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.19.11.5135 | Copyright © Anuko | +  Anuko Time Tracker 1.19.11.5136 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/admin_offer_edit.php b/admin_offer_edit.php index d47b6a40c..185255c82 100644 --- a/admin_offer_edit.php +++ b/admin_offer_edit.php @@ -78,9 +78,9 @@ $form = new Form('offerForm'); $form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_offer_id)); -$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'offer_name','style'=>'width: 400px;','value'=>$cl_name)); +$form->addInput(array('type'=>'text','name'=>'offer_name','maxlength'=>'128','style'=>'width: 400px;','value'=>$cl_name)); if ($work_id) $form->getElement('offer_name')->setEnabled(false); -$form->addInput(array('type'=>'textarea','name'=>'description','style'=>'width: 400px; height: 80px;','value'=>$cl_description)); +$form->addInput(array('type'=>'textarea','name'=>'description','maxlength'=>'512','style'=>'width: 400px; height: 80px;','value'=>$cl_description)); $form->addInput(array('type'=>'textarea','name'=>'details','style'=>'width: 400px; height: 200px;','value'=>$cl_details)); $form->addInput(array('type'=>'combobox','name'=>'currency','data'=>$currencies,'datakeys'=>array('id','name'),'value'=>$cl_currency_id)); if ($work_id) $form->getElement('currency')->setEnabled(false); diff --git a/admin_work_edit.php b/admin_work_edit.php index c1d8a257a..c66906d61 100644 --- a/admin_work_edit.php +++ b/admin_work_edit.php @@ -71,8 +71,8 @@ $form = new Form('workForm'); $form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_work_id)); -$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'work_name','style'=>'width: 400px;','value'=>$cl_name)); -$form->addInput(array('type'=>'textarea','name'=>'description','style'=>'width: 400px; height: 80px;','value'=>$cl_description)); +$form->addInput(array('type'=>'text','name'=>'work_name','maxlength'=>'128','style'=>'width: 400px;','value'=>$cl_name)); +$form->addInput(array('type'=>'textarea','name'=>'description','maxlength'=>'512','style'=>'width: 400px; height: 80px;','value'=>$cl_description)); $form->addInput(array('type'=>'textarea','name'=>'details','style'=>'width: 400px; height: 200px;','value'=>$cl_details)); $form->addInput(array('type'=>'combobox','name'=>'currency','data'=>$currencies,'datakeys'=>array('id','name'),'value'=>$cl_currency_id)); $form->addInput(array('type'=>'floatfield','maxlength'=>'10','name'=>'budget','format'=>'.2','value'=>$cl_budget)); diff --git a/offer_add.php b/offer_add.php index 4a652a1b9..b28516df7 100644 --- a/offer_add.php +++ b/offer_add.php @@ -69,10 +69,9 @@ $form = new Form('offerForm'); $form->addInput(array('type'=>'hidden','name'=>'work_id','value'=>$cl_work_id)); -$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'offer_name','style'=>'width: 400px;','value'=>$cl_name)); +$form->addInput(array('type'=>'text','name'=>'offer_name','maxlength'=>'128','style'=>'width: 400px;','value'=>$cl_name)); if ($work_item) $form->getElement('offer_name')->setEnabled(false); - -$form->addInput(array('type'=>'textarea','name'=>'description','style'=>'width: 400px; height: 80px;','value'=>$cl_description)); +$form->addInput(array('type'=>'textarea','name'=>'description','maxlength'=>'512','style'=>'width: 400px; height: 80px;','value'=>$cl_description)); $form->addInput(array('type'=>'textarea','name'=>'details','style'=>'width: 400px; height: 200px;','value'=>$cl_details)); // Add a dropdown for currency. $currencies = ttWorkHelper::getCurrencies(); diff --git a/offer_edit.php b/offer_edit.php index e4afd3078..24a02df21 100644 --- a/offer_edit.php +++ b/offer_edit.php @@ -80,9 +80,9 @@ $form = new Form('offerForm'); $form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_offer_id)); -$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'offer_name','style'=>'width: 400px;','value'=>$cl_name)); +$form->addInput(array('type'=>'text','name'=>'offer_name','maxlength'=>'128','style'=>'width: 400px;','value'=>$cl_name)); if ($work_id) $form->getElement('offer_name')->setEnabled(false); -$form->addInput(array('type'=>'textarea','name'=>'description','style'=>'width: 400px; height: 80px;','value'=>$cl_description)); +$form->addInput(array('type'=>'textarea','name'=>'description','maxlength'=>'512','style'=>'width: 400px; height: 80px;','value'=>$cl_description)); $form->addInput(array('type'=>'textarea','name'=>'details','style'=>'width: 400px; height: 200px;','value'=>$cl_details)); $form->addInput(array('type'=>'combobox','name'=>'currency','data'=>$currencies,'datakeys'=>array('id','name'),'value'=>$cl_currency_id)); if ($work_id) $form->getElement('currency')->setEnabled(false); diff --git a/offer_view.php b/offer_view.php index cbf400db4..6fd2057c1 100644 --- a/offer_view.php +++ b/offer_view.php @@ -56,9 +56,9 @@ $form = new Form('offerForm'); $form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_offer_id)); -$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'contractor','value'=>$cl_contractor)); +$form->addInput(array('type'=>'text','name'=>'contractor','value'=>$cl_contractor)); $form->getElement('contractor')->setEnabled(false); -$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'offer_name','style'=>'width: 400px;','value'=>$cl_name)); +$form->addInput(array('type'=>'text','name'=>'offer_name','style'=>'width: 400px;','value'=>$cl_name)); $form->getElement('offer_name')->setEnabled(false); $form->addInput(array('type'=>'textarea','name'=>'description','style'=>'width: 400px; height: 80px;','value'=>$cl_description)); $form->getElement('description')->setEnabled(false); diff --git a/work_add.php b/work_add.php index 8645891f1..fe5937af0 100644 --- a/work_add.php +++ b/work_add.php @@ -50,8 +50,8 @@ } $form = new Form('workForm'); -$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'work_name','style'=>'width: 250px;','value'=>$cl_name)); -$form->addInput(array('type'=>'textarea','name'=>'description','style'=>'width: 250px; height: 40px;','value'=>$cl_description)); +$form->addInput(array('type'=>'text','name'=>'work_name','maxlength'=>'128','style'=>'width: 250px;','value'=>$cl_name)); +$form->addInput(array('type'=>'textarea','name'=>'description','maxlength'=>'512','style'=>'width: 250px; height: 40px;','value'=>$cl_description)); $form->addInput(array('type'=>'textarea','name'=>'details','style'=>'width: 250px; height: 80px;','value'=>$cl_details)); // Add a dropdown for currency. $currencies = ttWorkHelper::getCurrencies(); diff --git a/work_edit.php b/work_edit.php index 9adc12f1d..fc84d5c13 100644 --- a/work_edit.php +++ b/work_edit.php @@ -70,8 +70,8 @@ $form = new Form('workForm'); $form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_work_id)); -$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'work_name','style'=>'width: 250px;','value'=>$cl_name)); -$form->addInput(array('type'=>'textarea','name'=>'description','style'=>'width: 250px; height: 40px;','value'=>$cl_description)); +$form->addInput(array('type'=>'text','name'=>'work_name','maxlength'=>'128','style'=>'width: 250px;','value'=>$cl_name)); +$form->addInput(array('type'=>'textarea','name'=>'description','maxlength'=>'512','style'=>'width: 250px; height: 40px;','value'=>$cl_description)); $form->addInput(array('type'=>'textarea','name'=>'details','style'=>'width: 250px; height: 80px;','value'=>$cl_details)); $form->addInput(array('type'=>'combobox','name'=>'currency','data'=>$currencies,'datakeys'=>array('id','name'),'value'=>$cl_currency_id)); $form->addInput(array('type'=>'floatfield','maxlength'=>'10','name'=>'budget','format'=>'.2','value'=>$cl_budget)); diff --git a/work_view.php b/work_view.php index d3addcc06..03995e646 100644 --- a/work_view.php +++ b/work_view.php @@ -56,9 +56,9 @@ $form = new Form('workForm'); $form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_work_id)); -$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'client','value'=>$cl_client)); +$form->addInput(array('type'=>'text','name'=>'client','value'=>$cl_client)); $form->getElement('client')->setEnabled(false); -$form->addInput(array('type'=>'textarea','maxlength'=>'100','name'=>'work_name','style'=>'width: 400px;','value'=>$cl_name)); +$form->addInput(array('type'=>'textarea','name'=>'work_name','style'=>'width: 400px;','value'=>$cl_name)); $form->getElement('work_name')->setEnabled(false); $form->addInput(array('type'=>'textarea','name'=>'description','style'=>'width: 400px; height: 80px;','value'=>$cl_description)); $form->getElement('description')->setEnabled(false); From 59b5f66a4dfa7e4a6711dcbe24136636ab15032d Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 8 Oct 2019 15:02:26 +0000 Subject: [PATCH 138/877] Work in progress on Remote Work plugin. --- WEB-INF/templates/admin_offer_edit.tpl | 4 ++++ WEB-INF/templates/footer.tpl | 2 +- admin_offer_edit.php | 3 +++ offer_add.php | 2 +- offer_edit.php | 2 +- 5 files changed, 10 insertions(+), 3 deletions(-) diff --git a/WEB-INF/templates/admin_offer_edit.tpl b/WEB-INF/templates/admin_offer_edit.tpl index 5831ae0c8..b79739171 100644 --- a/WEB-INF/templates/admin_offer_edit.tpl +++ b/WEB-INF/templates/admin_offer_edit.tpl @@ -46,6 +46,10 @@ {$i18n.label.budget} (*): {$forms.offerForm.budget.control}
{$i18n.label.how_to_pay} (*):{$forms.offerForm.payment_info.control}
{$i18n.label.status}: {$forms.offerForm.status.control}
-
 Anuko Time Tracker 1.19.11.5136 | Copyright © Anuko | +  Anuko Time Tracker 1.19.11.5137 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/admin_offer_edit.php b/admin_offer_edit.php index 185255c82..3dcbe0823 100644 --- a/admin_offer_edit.php +++ b/admin_offer_edit.php @@ -63,6 +63,7 @@ $cl_currency_id = $request->getParameter('currency'); if (!$cl_currency_id && $work_item) $cl_currency_id = ttWorkHelper::getCurrencyID($work_item['currency']); $cl_budget = $request->getParameter('budget'); + $cl_payment_info = $request->getParameter('payment_info'); $cl_status = $request->getParameter('status'); $cl_moderator_comment = $request->getParameter('moderator_comment'); } else { @@ -72,6 +73,7 @@ $currency = $offer['currency']; $cl_currency_id = ttWorkHelper::getCurrencyID($offer['currency']); $cl_budget = $offer['amount']; + $cl_payment_info = $offer['payment_info']; $cl_status = $offer['status']; $cl_moderator_comment = $offer['moderator_comment']; } @@ -85,6 +87,7 @@ $form->addInput(array('type'=>'combobox','name'=>'currency','data'=>$currencies,'datakeys'=>array('id','name'),'value'=>$cl_currency_id)); if ($work_id) $form->getElement('currency')->setEnabled(false); $form->addInput(array('type'=>'floatfield','maxlength'=>'10','name'=>'budget','format'=>'.2','value'=>$cl_budget)); +$form->addInput(array('type'=>'textarea','name'=>'payment_info','maxlength'=>'256','style'=>'width: 400px; height: 40px;vertical-align: middle','value'=>$cl_payment_info)); // Prepare status choices. $status_options = array(); diff --git a/offer_add.php b/offer_add.php index b28516df7..c98565fe3 100644 --- a/offer_add.php +++ b/offer_add.php @@ -78,7 +78,7 @@ $form->addInput(array('type'=>'combobox','name'=>'currency','data'=>$currencies,'datakeys'=>array('id','name'),'value'=>$cl_currency_id)); if ($work_item) $form->getElement('currency')->setEnabled(false); // Do not allow changing currency for offers on existing work items. $form->addInput(array('type'=>'floatfield','maxlength'=>'10','name'=>'budget','format'=>'.2','value'=>$cl_budget)); -$form->addInput(array('type'=>'textarea','name'=>'payment_info','style'=>'width: 400px; height: 40px;vertical-align: middle','value'=>$cl_payment_info)); +$form->addInput(array('type'=>'textarea','name'=>'payment_info','maxlength'=>'256','style'=>'width: 400px; height: 40px;vertical-align: middle','value'=>$cl_payment_info)); $form->addInput(array('type'=>'submit','name'=>'btn_add','value'=>$i18n->get('button.add'))); if ($request->isPost()) { diff --git a/offer_edit.php b/offer_edit.php index 24a02df21..f5686cde8 100644 --- a/offer_edit.php +++ b/offer_edit.php @@ -87,7 +87,7 @@ $form->addInput(array('type'=>'combobox','name'=>'currency','data'=>$currencies,'datakeys'=>array('id','name'),'value'=>$cl_currency_id)); if ($work_id) $form->getElement('currency')->setEnabled(false); $form->addInput(array('type'=>'floatfield','maxlength'=>'10','name'=>'budget','format'=>'.2','value'=>$cl_budget)); -$form->addInput(array('type'=>'textarea','name'=>'payment_info','style'=>'width: 400px; height: 40px;vertical-align: middle','value'=>$cl_payment_info)); +$form->addInput(array('type'=>'textarea','name'=>'payment_info','maxlength'=>'256','style'=>'width: 400px; height: 40px;vertical-align: middle','value'=>$cl_payment_info)); $form->addInput(array('type'=>'text','name'=>'status','value'=>$cl_status)); $form->getElement('status')->setEnabled(false); $form->addInput(array('type'=>'textarea','name'=>'moderator_comment','style'=>'width: 250px; height: 80px;','value'=>$cl_moderator_comment)); From 5b44185b1f92a0b3d9ab3ed62cb6559a42b6a5b6 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 8 Oct 2019 15:52:41 +0000 Subject: [PATCH 139/877] Some styling improvements for Work plugin. --- WEB-INF/templates/footer.tpl | 2 +- offer_edit.php | 4 ++-- work_add.php | 6 +++--- work_edit.php | 8 ++++---- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 66400b0b8..b56d63bf2 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- - + - {if $work_details} - - - - - {/if} {/if} diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index b56d63bf2..8f21157b7 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.19.11.5137 | Copyright © Anuko | +  Anuko Time Tracker 1.19.11.5138 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/offer_edit.php b/offer_edit.php index f5686cde8..3880b1819 100644 --- a/offer_edit.php +++ b/offer_edit.php @@ -87,10 +87,10 @@ $form->addInput(array('type'=>'combobox','name'=>'currency','data'=>$currencies,'datakeys'=>array('id','name'),'value'=>$cl_currency_id)); if ($work_id) $form->getElement('currency')->setEnabled(false); $form->addInput(array('type'=>'floatfield','maxlength'=>'10','name'=>'budget','format'=>'.2','value'=>$cl_budget)); -$form->addInput(array('type'=>'textarea','name'=>'payment_info','maxlength'=>'256','style'=>'width: 400px; height: 40px;vertical-align: middle','value'=>$cl_payment_info)); +$form->addInput(array('type'=>'textarea','name'=>'payment_info','maxlength'=>'256','style'=>'width: 400px; height: 40px; vertical-align: middle','value'=>$cl_payment_info)); $form->addInput(array('type'=>'text','name'=>'status','value'=>$cl_status)); $form->getElement('status')->setEnabled(false); -$form->addInput(array('type'=>'textarea','name'=>'moderator_comment','style'=>'width: 250px; height: 80px;','value'=>$cl_moderator_comment)); +$form->addInput(array('type'=>'textarea','name'=>'moderator_comment','style'=>'width: 400px; height: 80px;','value'=>$cl_moderator_comment)); $form->getElement('moderator_comment')->setEnabled(false); $form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); diff --git a/work_add.php b/work_add.php index fe5937af0..4e7ba1ba3 100644 --- a/work_add.php +++ b/work_add.php @@ -50,9 +50,9 @@ } $form = new Form('workForm'); -$form->addInput(array('type'=>'text','name'=>'work_name','maxlength'=>'128','style'=>'width: 250px;','value'=>$cl_name)); -$form->addInput(array('type'=>'textarea','name'=>'description','maxlength'=>'512','style'=>'width: 250px; height: 40px;','value'=>$cl_description)); -$form->addInput(array('type'=>'textarea','name'=>'details','style'=>'width: 250px; height: 80px;','value'=>$cl_details)); +$form->addInput(array('type'=>'text','name'=>'work_name','maxlength'=>'128','style'=>'width: 400px;','value'=>$cl_name)); +$form->addInput(array('type'=>'textarea','name'=>'description','maxlength'=>'512','style'=>'width: 400px; height: 80px;','value'=>$cl_description)); +$form->addInput(array('type'=>'textarea','name'=>'details','style'=>'width: 400px; height: 200px;','value'=>$cl_details)); // Add a dropdown for currency. $currencies = ttWorkHelper::getCurrencies(); $form->addInput(array('type'=>'combobox','name'=>'currency','data'=>$currencies,'datakeys'=>array('id','name'),'value'=>$cl_currency_id)); diff --git a/work_edit.php b/work_edit.php index fc84d5c13..0c53f7ae4 100644 --- a/work_edit.php +++ b/work_edit.php @@ -70,14 +70,14 @@ $form = new Form('workForm'); $form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_work_id)); -$form->addInput(array('type'=>'text','name'=>'work_name','maxlength'=>'128','style'=>'width: 250px;','value'=>$cl_name)); -$form->addInput(array('type'=>'textarea','name'=>'description','maxlength'=>'512','style'=>'width: 250px; height: 40px;','value'=>$cl_description)); -$form->addInput(array('type'=>'textarea','name'=>'details','style'=>'width: 250px; height: 80px;','value'=>$cl_details)); +$form->addInput(array('type'=>'text','name'=>'work_name','maxlength'=>'128','style'=>'width: 400px;','value'=>$cl_name)); +$form->addInput(array('type'=>'textarea','name'=>'description','maxlength'=>'512','style'=>'width: 400px; height: 80px;','value'=>$cl_description)); +$form->addInput(array('type'=>'textarea','name'=>'details','style'=>'width: 400px; height: 200px;','value'=>$cl_details)); $form->addInput(array('type'=>'combobox','name'=>'currency','data'=>$currencies,'datakeys'=>array('id','name'),'value'=>$cl_currency_id)); $form->addInput(array('type'=>'floatfield','maxlength'=>'10','name'=>'budget','format'=>'.2','value'=>$cl_budget)); $form->addInput(array('type'=>'text','name'=>'status','value'=>$cl_status)); $form->getElement('status')->setEnabled(false); -$form->addInput(array('type'=>'textarea','name'=>'moderator_comment','style'=>'width: 250px; height: 80px;','value'=>$cl_moderator_comment)); +$form->addInput(array('type'=>'textarea','name'=>'moderator_comment','style'=>'width: 400px; height: 80px;','value'=>$cl_moderator_comment)); $form->getElement('moderator_comment')->setEnabled(false); $form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); From e69f7a0cdfcd555b45b57fc522a9cc90cb68041b Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 8 Oct 2019 16:35:53 +0000 Subject: [PATCH 140/877] Added work details on make offer page. --- WEB-INF/templates/admin_offer_edit.tpl | 8 +------- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/offer_add.tpl | 11 +++++++++++ WEB-INF/templates/work_view.tpl | 2 ++ offer_add.php | 11 ++++++++++- 5 files changed, 25 insertions(+), 9 deletions(-) diff --git a/WEB-INF/templates/admin_offer_edit.tpl b/WEB-INF/templates/admin_offer_edit.tpl index b79739171..88fd3cc68 100644 --- a/WEB-INF/templates/admin_offer_edit.tpl +++ b/WEB-INF/templates/admin_offer_edit.tpl @@ -9,15 +9,9 @@ {$work_name}
{$i18n.label.description}: {$work_description}
{$i18n.label.details}:{$work_details}
 
- diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 8f21157b7..0bef6cca3 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.19.11.5138 | Copyright © Anuko | +  Anuko Time Tracker 1.19.11.5139 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/offer_add.tpl b/WEB-INF/templates/offer_add.tpl index da7e05574..d31fb1753 100644 --- a/WEB-INF/templates/offer_add.tpl +++ b/WEB-INF/templates/offer_add.tpl @@ -3,6 +3,17 @@
+{if $work_id} + + + + + + + + + +{/if} diff --git a/WEB-INF/templates/work_view.tpl b/WEB-INF/templates/work_view.tpl index 90ca1b8b0..37207a72c 100644 --- a/WEB-INF/templates/work_view.tpl +++ b/WEB-INF/templates/work_view.tpl @@ -45,7 +45,9 @@ - + {/if} @@ -61,7 +61,7 @@ - +
{$i18n.label.work}:{$work_name}
{$forms.offerForm.work_description.control}
 
{$i18n.label.offer} (*): {$forms.offerForm.offer_name.control} + {if false} + {/if}
diff --git a/offer_add.php b/offer_add.php index c98565fe3..42925fd59 100644 --- a/offer_add.php +++ b/offer_add.php @@ -68,7 +68,11 @@ } $form = new Form('offerForm'); -$form->addInput(array('type'=>'hidden','name'=>'work_id','value'=>$cl_work_id)); +if ($cl_work_id) { + $form->addInput(array('type'=>'hidden','name'=>'work_id','value'=>$cl_work_id)); + $form->addInput(array('type'=>'textarea','name'=>'work_description','style'=>'width: 400px; height: 80px;','value'=>$work_item['descr_short'])); + $form->getElement('work_description')->setEnabled(false); +} $form->addInput(array('type'=>'text','name'=>'offer_name','maxlength'=>'128','style'=>'width: 400px;','value'=>$cl_name)); if ($work_item) $form->getElement('offer_name')->setEnabled(false); $form->addInput(array('type'=>'textarea','name'=>'description','maxlength'=>'512','style'=>'width: 400px; height: 80px;','value'=>$cl_description)); @@ -108,6 +112,11 @@ } } // isPost +if ($cl_work_id) { + $smarty->assign('work_id', $cl_work_id); + $smarty->assign('work_name', $work_item['subject']); + $smarty->assign('work_description', $work_item['descr_short']); +} $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="document.offerForm.work_name.focus()"'); $smarty->assign('title', $i18n->get('title.add_offer')); From d5a3b4c54c2147b05ae76bc2ff5b59e536a66e3c Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 8 Oct 2019 20:00:14 +0000 Subject: [PATCH 141/877] A bit more progress on making offers workflow. --- WEB-INF/templates/admin_offer_edit.tpl | 4 +- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/offer_edit.tpl | 11 ++++ admin_offer_edit.php | 73 +++++++++++++++----------- offer_edit.php | 11 +++- work_edit.php | 2 +- 6 files changed, 68 insertions(+), 35 deletions(-) diff --git a/WEB-INF/templates/admin_offer_edit.tpl b/WEB-INF/templates/admin_offer_edit.tpl index 88fd3cc68..bd9a6542b 100644 --- a/WEB-INF/templates/admin_offer_edit.tpl +++ b/WEB-INF/templates/admin_offer_edit.tpl @@ -10,7 +10,7 @@
{$work_description}{$forms.offerForm.work_description.control}
 
 
{$forms.offerForm.btn_save.control}{$forms.offerForm.btn_approve.control} {$forms.offerForm.btn_save.control} {$forms.offerForm.btn_disapprove.control}
- diff --git a/invoice_view.php b/invoice_view.php index 605a53020..5e11781c3 100644 --- a/invoice_view.php +++ b/invoice_view.php @@ -95,13 +95,14 @@ // Hidden control for invoice id. $form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_invoice_id)); // invoiceForm only contains controls for "Mark paid" block below invoice table. -if ($user->isPluginEnabled('ps')) { +if ($user->isPluginEnabled('ps') && !$user->isClient()) { $mark_paid_action_options = array('1'=>$i18n->get('dropdown.paid'),'2'=>$i18n->get('dropdown.not_paid')); $form->addInput(array('type'=>'combobox', 'name'=>'mark_paid_action_options', 'data'=>$mark_paid_action_options, 'value'=>$cl_mark_paid_action_option)); $form->addInput(array('type'=>'submit','name'=>'btn_mark_paid','value'=>$i18n->get('button.submit'))); + $smarty->assign('show_mark_paid', true); } if ($request->isPost()) { From 8605afa6f00e97f97798064041b297843a200d94 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 9 Oct 2019 17:38:19 +0000 Subject: [PATCH 143/877] Added offers column on work.php. --- WEB-INF/resources/en.lang.php | 1 + WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/work.tpl | 2 ++ default.css | 4 ++++ 4 files changed, 8 insertions(+), 1 deletion(-) diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index 0bc5fba16..b7228d133 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -640,6 +640,7 @@ 'work.error.offer_not_available' => 'Offer is not available.', 'work.label.our_work' => 'Our work', 'work.label.our_offers' => 'Our offers', +'work.label.offers' => 'Offers', 'work.button.send_message' => 'Send message', 'work.button.make_offer' => 'Make offer', 'work.button.accept_offer' => 'Accept offer', diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 194b24e65..8d1ec8a60 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.19.11.5139 | Copyright © Anuko | +  Anuko Time Tracker 1.19.11.5140 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/offer_edit.tpl b/WEB-INF/templates/offer_edit.tpl index 75f7a0532..ba1555e44 100644 --- a/WEB-INF/templates/offer_edit.tpl +++ b/WEB-INF/templates/offer_edit.tpl @@ -3,6 +3,17 @@
+{if $work_id} + + + + + + + + + +{/if} diff --git a/admin_offer_edit.php b/admin_offer_edit.php index 3dcbe0823..208c08438 100644 --- a/admin_offer_edit.php +++ b/admin_offer_edit.php @@ -64,7 +64,7 @@ if (!$cl_currency_id && $work_item) $cl_currency_id = ttWorkHelper::getCurrencyID($work_item['currency']); $cl_budget = $request->getParameter('budget'); $cl_payment_info = $request->getParameter('payment_info'); - $cl_status = $request->getParameter('status'); + // $cl_status = $request->getParameter('status'); $cl_moderator_comment = $request->getParameter('moderator_comment'); } else { $cl_name = $offer['subject']; @@ -74,13 +74,18 @@ $cl_currency_id = ttWorkHelper::getCurrencyID($offer['currency']); $cl_budget = $offer['amount']; $cl_payment_info = $offer['payment_info']; - $cl_status = $offer['status']; + $status = $offer['status']; + $status_label = $offer['status_label']; $cl_moderator_comment = $offer['moderator_comment']; } $form = new Form('offerForm'); $form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_offer_id)); -$form->addInput(array('type'=>'text','name'=>'offer_name','maxlength'=>'128','style'=>'width: 400px;','value'=>$cl_name)); +if ($work_id) { + $form->addInput(array('type'=>'textarea','name'=>'work_description','style'=>'width: 400px; height: 80px;','value'=>$work_item['descr_short'])); + $form->getElement('work_description')->setEnabled(false); +} +$form->addInput(array('type'=>'text','name'=>'offer_name','style'=>'width: 400px;','value'=>$cl_name)); if ($work_id) $form->getElement('offer_name')->setEnabled(false); $form->addInput(array('type'=>'textarea','name'=>'description','maxlength'=>'512','style'=>'width: 400px; height: 80px;','value'=>$cl_description)); $form->addInput(array('type'=>'textarea','name'=>'details','style'=>'width: 400px; height: 200px;','value'=>$cl_details)); @@ -88,16 +93,24 @@ if ($work_id) $form->getElement('currency')->setEnabled(false); $form->addInput(array('type'=>'floatfield','maxlength'=>'10','name'=>'budget','format'=>'.2','value'=>$cl_budget)); $form->addInput(array('type'=>'textarea','name'=>'payment_info','maxlength'=>'256','style'=>'width: 400px; height: 40px;vertical-align: middle','value'=>$cl_payment_info)); +$form->addInput(array('type'=>'text','name'=>'status','style'=>'width: 400px;','value'=>$status_label)); +$form->getElement('status')->setEnabled(false); // Prepare status choices. +/* $status_options = array(); $status_options[STATUS_PENDING_APPROVAL] = $i18n->get('dropdown.pending_approval'); $status_options[STATUS_DISAPPROVED] = $i18n->get('dropdown.not_approved'); $status_options[STATUS_APPROVED] = $i18n->get('dropdown.approved'); $form->addInput(array('type'=>'combobox','name'=>'status','value'=>$cl_status,'data'=>$status_options)); +*/ $form->addInput(array('type'=>'textarea','name'=>'moderator_comment','style'=>'width: 400px; height: 80px;','value'=>$cl_moderator_comment)); $form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); +if ($status == STATUS_PENDING_APPROVAL) { + $form->addInput(array('type'=>'submit','name'=>'btn_approve','value'=>$i18n->get('button.approve'))); + $form->addInput(array('type'=>'submit','name'=>'btn_disapprove','value'=>$i18n->get('button.disapprove'))); +} if ($request->isPost()) { // Validate user input. @@ -110,35 +123,36 @@ // Ensure user email exists (required for workflow). if (!$user->getEmail()) $err->add($i18n->get('error.no_email')); + $fields = array('offer_id'=>$cl_offer_id, + 'subject'=>$cl_name, + 'descr_short' => $cl_description, + 'descr_long' => $cl_details, + 'currency' => ttWorkHelper::getCurrencyName($cl_currency_id), + 'amount' => $cl_budget, + 'moderator_comment' => $cl_moderator_comment); + if ($err->no()) { + if ($request->getParameter('btn_approve')) { + // Approve offer. + if ($adminWorkHelper->approveOffer($fields)) { + header('Location: admin_work.php'); + exit(); + } + } + if ($request->getParameter('btn_save')) { - $fields = array('offer_id'=>$cl_offer_id, - 'subject'=>$cl_name, - 'descr_short' => $cl_description, - 'descr_long' => $cl_details, - 'currency' => ttWorkHelper::getCurrencyName($cl_currency_id), - 'amount' => $cl_budget, - 'moderator_comment' => $cl_moderator_comment); + // Update offer without changing its status. + if ($adminWorkHelper->updateOffer($fields)) { + header('Location: admin_work.php'); + exit(); + } + } - // Do things differently, depending on status control value. - if ($existingStatus == $cl_status) { - // Status not changed. Update work information. - if ($adminWorkHelper->updateOffer($fields)) { - header('Location: admin_work.php'); - exit(); - } - } else if ($cl_status == STATUS_DISAPPROVED) { - // Status changed to "not approved". Disapprove work. - if ($adminWorkHelper->disapproveOffer($fields)) { - header('Location: admin_work.php'); - exit(); - } - } else if ($cl_status == STATUS_APPROVED) { - // Status changed to "approved". Approve work. - if ($adminWorkHelper->approveOffer($fields)) { - header('Location: admin_work.php'); - exit(); - } + if ($request->getParameter('btn_disapprove')) { + // Dispprove offer. + if ($adminWorkHelper->disapproveOffer($fields)) { + header('Location: admin_work.php'); + exit(); } } } @@ -148,7 +162,6 @@ $smarty->assign('work_id', $work_id); $smarty->assign('work_name', $work_item['subject']); $smarty->assign('work_description', $work_item['descr_short']); - $smarty->assign('work_details', $work_item['descr_long']); } $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('title', $i18n->get('title.edit_offer')); diff --git a/offer_edit.php b/offer_edit.php index 3880b1819..7c695ee1c 100644 --- a/offer_edit.php +++ b/offer_edit.php @@ -80,6 +80,10 @@ $form = new Form('offerForm'); $form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_offer_id)); +if ($work_id) { + $form->addInput(array('type'=>'textarea','name'=>'work_description','style'=>'width: 400px; height: 80px;','value'=>$work_item['descr_short'])); + $form->getElement('work_description')->setEnabled(false); +} $form->addInput(array('type'=>'text','name'=>'offer_name','maxlength'=>'128','style'=>'width: 400px;','value'=>$cl_name)); if ($work_id) $form->getElement('offer_name')->setEnabled(false); $form->addInput(array('type'=>'textarea','name'=>'description','maxlength'=>'512','style'=>'width: 400px; height: 80px;','value'=>$cl_description)); @@ -88,7 +92,7 @@ if ($work_id) $form->getElement('currency')->setEnabled(false); $form->addInput(array('type'=>'floatfield','maxlength'=>'10','name'=>'budget','format'=>'.2','value'=>$cl_budget)); $form->addInput(array('type'=>'textarea','name'=>'payment_info','maxlength'=>'256','style'=>'width: 400px; height: 40px; vertical-align: middle','value'=>$cl_payment_info)); -$form->addInput(array('type'=>'text','name'=>'status','value'=>$cl_status)); +$form->addInput(array('type'=>'text','name'=>'status','style'=>'width: 400px;','value'=>$cl_status)); $form->getElement('status')->setEnabled(false); $form->addInput(array('type'=>'textarea','name'=>'moderator_comment','style'=>'width: 400px; height: 80px;','value'=>$cl_moderator_comment)); $form->getElement('moderator_comment')->setEnabled(false); @@ -123,6 +127,11 @@ } } // isPost +if ($work_id) { + $smarty->assign('work_id', $work_id); + $smarty->assign('work_name', $work_item['subject']); + $smarty->assign('work_description', $work_item['descr_short']); +} $smarty->assign('show_moderator_comment', $show_moderator_comment); $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('title', $i18n->get('title.edit_offer')); diff --git a/work_edit.php b/work_edit.php index 0c53f7ae4..dffe185c7 100644 --- a/work_edit.php +++ b/work_edit.php @@ -75,7 +75,7 @@ $form->addInput(array('type'=>'textarea','name'=>'details','style'=>'width: 400px; height: 200px;','value'=>$cl_details)); $form->addInput(array('type'=>'combobox','name'=>'currency','data'=>$currencies,'datakeys'=>array('id','name'),'value'=>$cl_currency_id)); $form->addInput(array('type'=>'floatfield','maxlength'=>'10','name'=>'budget','format'=>'.2','value'=>$cl_budget)); -$form->addInput(array('type'=>'text','name'=>'status','value'=>$cl_status)); +$form->addInput(array('type'=>'text','name'=>'status','style'=>'width: 400px;','value'=>$cl_status)); $form->getElement('status')->setEnabled(false); $form->addInput(array('type'=>'textarea','name'=>'moderator_comment','style'=>'width: 400px; height: 80px;','value'=>$cl_moderator_comment)); $form->getElement('moderator_comment')->setEnabled(false); From 34398e6db0f4d84016e0dc10d8738e1f4a11bded Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 9 Oct 2019 01:06:55 +0000 Subject: [PATCH 142/877] Fixed issue #82 - clients can mark their invoices paid/not paid. --- WEB-INF/lib/ttInvoiceHelper.class.php | 3 ++- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/invoice_view.tpl | 4 ++-- invoice_view.php | 3 ++- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/WEB-INF/lib/ttInvoiceHelper.class.php b/WEB-INF/lib/ttInvoiceHelper.class.php index 833f15c3d..0afd0c9aa 100644 --- a/WEB-INF/lib/ttInvoiceHelper.class.php +++ b/WEB-INF/lib/ttInvoiceHelper.class.php @@ -107,8 +107,9 @@ static function isPaid($invoice_id) { // markPaid marks invoice items as paid. static function markPaid($invoice_id, $mark_paid = true) { global $user; - $mdb2 = getConnection(); + if ($user->isClient()) return false; // Not for clients. + $mdb2 = getConnection(); $group_id = $user->getGroup(); $org_id = $user->org_id; diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 0bef6cca3..194b24e65 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
{$i18n.label.work}:{$work_name}
{$forms.offerForm.work_description.control}
 
{$i18n.label.offer} (*): {$forms.offerForm.offer_name.control}
-
 Anuko Time Tracker 1.19.11.5140 | Copyright © Anuko | +  Anuko Time Tracker 1.19.12.5141 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/invoice_view.tpl b/WEB-INF/templates/invoice_view.tpl index 6441b44db..0d8c31ffe 100644 --- a/WEB-INF/templates/invoice_view.tpl +++ b/WEB-INF/templates/invoice_view.tpl @@ -68,8 +68,8 @@
+ {if $show_mark_paid} {$forms.invoiceForm.open} - {if $user->isPluginEnabled('ps')}
@@ -79,8 +79,8 @@
- {/if} {$forms.invoiceForm.close} + {/if} {/if}
- + @@ -21,6 +22,7 @@ + diff --git a/default.css b/default.css index 89b3fa645..77559c330 100644 --- a/default.css +++ b/default.css @@ -123,6 +123,10 @@ input[type=checkbox], label { vertical-align: top; } +.midAligned { + text-align: center; +} + .sectionHeader { font-weight: bold; border-bottom: 1px solid lightgray; From 09ca0762a80fea4f9e6e2b54e35e8efab72a8fc5 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 9 Oct 2019 18:19:39 +0000 Subject: [PATCH 144/877] Added work.label.offers in ocalization files. --- WEB-INF/resources/ca.lang.php | 1 + WEB-INF/resources/cs.lang.php | 1 + WEB-INF/resources/da.lang.php | 1 + WEB-INF/resources/de.lang.php | 1 + WEB-INF/resources/es.lang.php | 1 + WEB-INF/resources/et.lang.php | 1 + WEB-INF/resources/fa.lang.php | 1 + WEB-INF/resources/fi.lang.php | 1 + WEB-INF/resources/fr.lang.php | 1 + WEB-INF/resources/gr.lang.php | 1 + WEB-INF/resources/he.lang.php | 1 + WEB-INF/resources/hu.lang.php | 1 + WEB-INF/resources/it.lang.php | 1 + WEB-INF/resources/ja.lang.php | 1 + WEB-INF/resources/ko.lang.php | 1 + WEB-INF/resources/nl.lang.php | 1 + WEB-INF/resources/no.lang.php | 1 + WEB-INF/resources/pl.lang.php | 1 + WEB-INF/resources/pt-br.lang.php | 1 + WEB-INF/resources/pt.lang.php | 1 + WEB-INF/resources/ro.lang.php | 1 + WEB-INF/resources/ru.lang.php | 1 + WEB-INF/resources/sk.lang.php | 1 + WEB-INF/resources/sl.lang.php | 1 + WEB-INF/resources/sr.lang.php | 1 + WEB-INF/resources/sv.lang.php | 1 + WEB-INF/resources/tr.lang.php | 1 + WEB-INF/resources/zh-cn.lang.php | 1 + WEB-INF/resources/zh-tw.lang.php | 1 + WEB-INF/templates/footer.tpl | 2 +- 30 files changed, 30 insertions(+), 1 deletion(-) diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index 9813ca780..3628ae032 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -710,6 +710,7 @@ // 'work.error.offer_not_available' => 'Offer is not available.', // 'work.label.our_work' => 'Our work', // 'work.label.our_offers' => 'Our offers', +// 'work.label.offers' => 'Offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', // 'work.button.accept_offer' => 'Accept offer', diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index 6607ed5bb..22ce44e37 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -723,6 +723,7 @@ // 'work.error.offer_not_available' => 'Offer is not available.', // 'work.label.our_work' => 'Our work', // 'work.label.our_offers' => 'Our offers', +// 'work.label.offers' => 'Offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', // 'work.button.accept_offer' => 'Accept offer', diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index 948b591e2..a41817c94 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -684,6 +684,7 @@ // 'work.error.offer_not_available' => 'Offer is not available.', // 'work.label.our_work' => 'Our work', // 'work.label.our_offers' => 'Our offers', +// 'work.label.offers' => 'Offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', // 'work.button.accept_offer' => 'Accept offer', diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index 045533702..a4367f344 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -660,6 +660,7 @@ // 'work.error.offer_not_available' => 'Offer is not available.', // 'work.label.our_work' => 'Our work', // 'work.label.our_offers' => 'Our offers', +// 'work.label.offers' => 'Offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', // 'work.button.accept_offer' => 'Accept offer', diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index 61c466635..b96aed296 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -725,6 +725,7 @@ // 'work.error.offer_not_available' => 'Offer is not available.', // 'work.label.our_work' => 'Our work', // 'work.label.our_offers' => 'Our offers', +// 'work.label.offers' => 'Offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', // 'work.button.accept_offer' => 'Accept offer', diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index f6a6d5c7b..0dbd6c9ca 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -691,6 +691,7 @@ // 'work.error.offer_not_available' => 'Offer is not available.', // 'work.label.our_work' => 'Our work', // 'work.label.our_offers' => 'Our offers', +// 'work.label.offers' => 'Offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', // 'work.button.accept_offer' => 'Accept offer', diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index 1866a21ed..0bb19d259 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -708,6 +708,7 @@ // 'work.error.offer_not_available' => 'Offer is not available.', // 'work.label.our_work' => 'Our work', // 'work.label.our_offers' => 'Our offers', +// 'work.label.offers' => 'Offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', // 'work.button.accept_offer' => 'Accept offer', diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index d7136aaee..6ec926d97 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -690,6 +690,7 @@ // 'work.error.offer_not_available' => 'Offer is not available.', // 'work.label.our_work' => 'Our work', // 'work.label.our_offers' => 'Our offers', +// 'work.label.offers' => 'Offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', // 'work.button.accept_offer' => 'Accept offer', diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index b8f22e0a8..735bb2d07 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -680,6 +680,7 @@ // 'work.error.offer_not_available' => 'Offer is not available.', // 'work.label.our_work' => 'Our work', // 'work.label.our_offers' => 'Our offers', +// 'work.label.offers' => 'Offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', // 'work.button.accept_offer' => 'Accept offer', diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index 4b5ab0e7b..8fce19af8 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -673,6 +673,7 @@ // 'work.error.offer_not_available' => 'Offer is not available.', // 'work.label.our_work' => 'Our work', // 'work.label.our_offers' => 'Our offers', +// 'work.label.offers' => 'Offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', // 'work.button.accept_offer' => 'Accept offer', diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index b8ff35a60..f04bbf00c 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -710,6 +710,7 @@ // 'work.error.offer_not_available' => 'Offer is not available.', // 'work.label.our_work' => 'Our work', // 'work.label.our_offers' => 'Our offers', +// 'work.label.offers' => 'Offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', // 'work.button.accept_offer' => 'Accept offer', diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index 5339cd133..099c6f2fe 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -715,6 +715,7 @@ // 'work.error.offer_not_available' => 'Offer is not available.', // 'work.label.our_work' => 'Our work', // 'work.label.our_offers' => 'Our offers', +// 'work.label.offers' => 'Offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', // 'work.button.accept_offer' => 'Accept offer', diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index 1f287cfd1..7c28ee423 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -687,6 +687,7 @@ // 'work.error.offer_not_available' => 'Offer is not available.', // 'work.label.our_work' => 'Our work', // 'work.label.our_offers' => 'Our offers', +// 'work.label.offers' => 'Offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', // 'work.button.accept_offer' => 'Accept offer', diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index f8b18e60c..1f4cc51e8 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -718,6 +718,7 @@ // 'work.error.offer_not_available' => 'Offer is not available.', // 'work.label.our_work' => 'Our work', // 'work.label.our_offers' => 'Our offers', +// 'work.label.offers' => 'Offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', // 'work.button.accept_offer' => 'Accept offer', diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index d23d8b728..0c18572e2 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -716,6 +716,7 @@ // 'work.error.offer_not_available' => 'Offer is not available.', // 'work.label.our_work' => 'Our work', // 'work.label.our_offers' => 'Our offers', +// 'work.label.offers' => 'Offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', // 'work.button.accept_offer' => 'Accept offer', diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 71ca76659..40bd8f416 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -642,6 +642,7 @@ // 'work.error.offer_not_available' => 'Offer is not available.', // 'work.label.our_work' => 'Our work', // 'work.label.our_offers' => 'Our offers', +// 'work.label.offers' => 'Offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', // 'work.button.accept_offer' => 'Accept offer', diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index 4c55fbca4..7d165b5a2 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -715,6 +715,7 @@ // 'work.error.offer_not_available' => 'Offer is not available.', // 'work.label.our_work' => 'Our work', // 'work.label.our_offers' => 'Our offers', +// 'work.label.offers' => 'Offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', // 'work.button.accept_offer' => 'Accept offer', diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index 90b8ade2e..df26f2726 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -693,6 +693,7 @@ // 'work.error.offer_not_available' => 'Offer is not available.', // 'work.label.our_work' => 'Our work', // 'work.label.our_offers' => 'Our offers', +// 'work.label.offers' => 'Offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', // 'work.button.accept_offer' => 'Accept offer', diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index 1108dbddf..aeeeb00b8 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -688,6 +688,7 @@ // 'work.error.offer_not_available' => 'Offer is not available.', // 'work.label.our_work' => 'Our work', // 'work.label.our_offers' => 'Our offers', +// 'work.label.offers' => 'Offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', // 'work.button.accept_offer' => 'Accept offer', diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index f3c9e9b46..ea4f09d33 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -697,6 +697,7 @@ // 'work.error.offer_not_available' => 'Offer is not available.', // 'work.label.our_work' => 'Our work', // 'work.label.our_offers' => 'Our offers', +// 'work.label.offers' => 'Offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', // 'work.button.accept_offer' => 'Accept offer', diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index c1ab74e33..6c117ae2e 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -718,6 +718,7 @@ // 'work.error.offer_not_available' => 'Offer is not available.', // 'work.label.our_work' => 'Our work', // 'work.label.our_offers' => 'Our offers', +// 'work.label.offers' => 'Offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', // 'work.button.accept_offer' => 'Accept offer', diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index 9cf026772..fa6ebc8ce 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -621,6 +621,7 @@ 'work.error.offer_not_available' => 'Предложение отсутствует.', 'work.label.our_work' => 'Наша работа', 'work.label.our_offers' => 'Наши предложения', + 'work.label.offers' => 'Предложения', 'work.button.send_message' => 'Отправить сообщение', 'work.button.make_offer' => 'Сделать предложение', 'work.button.accept_offer' => 'Принять предложение', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index 0620b34d5..2507d3bd9 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -699,6 +699,7 @@ // 'work.error.offer_not_available' => 'Offer is not available.', // 'work.label.our_work' => 'Our work', // 'work.label.our_offers' => 'Our offers', +// 'work.label.offers' => 'Offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', // 'work.button.accept_offer' => 'Accept offer', diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index 5ec29ac97..dadd1e233 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -691,6 +691,7 @@ // 'work.error.offer_not_available' => 'Offer is not available.', // 'work.label.our_work' => 'Our work', // 'work.label.our_offers' => 'Our offers', +// 'work.label.offers' => 'Offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', // 'work.button.accept_offer' => 'Accept offer', diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index d1056c260..628345254 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -691,6 +691,7 @@ // 'work.error.offer_not_available' => 'Offer is not available.', // 'work.label.our_work' => 'Our work', // 'work.label.our_offers' => 'Our offers', +// 'work.label.offers' => 'Offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', // 'work.button.accept_offer' => 'Accept offer', diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index 750065efa..a0103675a 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -689,6 +689,7 @@ // 'work.error.offer_not_available' => 'Offer is not available.', // 'work.label.our_work' => 'Our work', // 'work.label.our_offers' => 'Our offers', +// 'work.label.offers' => 'Offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', // 'work.button.accept_offer' => 'Accept offer', diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index 4127780f9..601f537d0 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -731,6 +731,7 @@ // 'work.error.offer_not_available' => 'Offer is not available.', // 'work.label.our_work' => 'Our work', // 'work.label.our_offers' => 'Our offers', +// 'work.label.offers' => 'Offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', // 'work.button.accept_offer' => 'Accept offer', diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index 739f23db4..bd278ca10 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -702,6 +702,7 @@ // 'work.error.offer_not_available' => 'Offer is not available.', // 'work.label.our_work' => 'Our work', // 'work.label.our_offers' => 'Our offers', +// 'work.label.offers' => 'Offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', // 'work.button.accept_offer' => 'Accept offer', diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index 2c0928ae3..1ee672aa6 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -708,6 +708,7 @@ // 'work.error.offer_not_available' => 'Offer is not available.', // 'work.label.our_work' => 'Our work', // 'work.label.our_offers' => 'Our offers', +// 'work.label.offers' => 'Offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', // 'work.button.accept_offer' => 'Accept offer', diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 8d1ec8a60..bf4e69ccd 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.19.12.5141 | Copyright © Anuko | +  Anuko Time Tracker 1.19.12.5142 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/work.tpl b/WEB-INF/templates/work.tpl index f790c2420..034785190 100644 --- a/WEB-INF/templates/work.tpl +++ b/WEB-INF/templates/work.tpl @@ -12,6 +12,7 @@ {$i18n.label.work} {$i18n.label.description} {$i18n.label.status}{$i18n.work.label.offers} {$i18n.label.budget} {$work_item.subject|escape} {$work_item.description|escape} {$work_item.status_label}{if $work_item.num_offers}{$work_item.num_offers}{/if} {$work_item.amount_with_currency} {$i18n.label.edit} {$i18n.label.delete}
-
 Anuko Time Tracker 1.19.12.5142 | Copyright © Anuko | +  Anuko Time Tracker 1.19.12.5143 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From be1649efb25436c3abfd31143f295832c7893fc1 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 9 Oct 2019 19:30:21 +0000 Subject: [PATCH 145/877] Made progress on viewing offers on own work items. --- WEB-INF/lib/ttWorkHelper.class.php | 61 ++++++++++++++++++++++++++++++ WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/work.tpl | 2 +- WEB-INF/templates/work_offers.tpl | 30 +++++++++++++++ work_offers.php | 55 +++++++++++++++++++++++++++ 5 files changed, 148 insertions(+), 2 deletions(-) create mode 100644 WEB-INF/templates/work_offers.tpl create mode 100644 work_offers.php diff --git a/WEB-INF/lib/ttWorkHelper.class.php b/WEB-INF/lib/ttWorkHelper.class.php index ff979c2af..16d3ddd74 100644 --- a/WEB-INF/lib/ttWorkHelper.class.php +++ b/WEB-INF/lib/ttWorkHelper.class.php @@ -36,6 +36,7 @@ class ttWorkHelper { var $register_uri = null; // URI to register with remote work server. var $put_own_work_item_uri = null; // URI to publish own work item. var $get_own_work_item_uri = null; // URI to get own work item details. + var $get_own_work_item_offers_uri = null; // URI to get offers on own work item. var $get_own_work_items_uri = null; // URI to get own work items for group. var $get_available_work_items_uri = null; // URI to get available work items for group. var $get_available_work_item_uri = null; // URI to get a single available work item. @@ -67,6 +68,7 @@ function __construct(&$errors) { $this->register_uri = $this->work_server_uri.'register'; // register_0_0 $this->put_own_work_item_uri = $this->work_server_uri.'putownworkitem'; $this->get_own_work_item_uri = $this->work_server_uri.'getownworkitem'; + $this->get_own_work_item_offers_uri = $this->work_server_uri.'getownworkitemoffers'; $this->get_own_work_items_uri = $this->work_server_uri.'getownworkitems'; $this->get_available_work_items_uri = $this->work_server_uri.'getavailableworkitems'; $this->get_available_work_item_uri = $this->work_server_uri.'getavailableworkitem'; @@ -486,6 +488,65 @@ function getOwnWorkItem($work_id) { return $work_item; } + // getOwnWorkItemOffers - gets offers on own work item from remote work server. + function getOwnWorkItemOffers($work_id) { + global $i18n; + global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $curl_fields = array('lang' => urlencode($user->lang), + 'site_id' => urlencode($this->site_id), + 'site_key' => urlencode($this->site_key), + 'org_id' => urlencode($org_id), + 'org_key' => urlencode($user->getOrgKey()), + 'group_id' => urlencode($group_id), + 'group_key' => urlencode($user->getGroupKey()), + 'work_id' => urlencode($work_id)); + + // url-ify the data for the POST. + foreach($curl_fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; } + $fields_string = rtrim($fields_string, '&'); + + // Open connection. + $ch = curl_init(); + + // Set the url, number of POST vars, POST data. + curl_setopt($ch, CURLOPT_URL, $this->get_own_work_item_offers_uri); + curl_setopt($ch, CURLOPT_POST, true); + curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + + // Execute a post request. + $result = curl_exec($ch); + + // Close connection. + curl_close($ch); + + if (!$result) { + $this->errors->add($i18n->get('error.remote_work')); + return false; + } + + $result_array = json_decode($result, true); + + // Check for errors. + $call_status = $result_array['call_status']; + if (!$call_status) { + $this->errors->add($i18n->get('error.remote_work')); + return false; + } + if ($call_status['code'] != TT_CURL_SUCCESS) { + $this->errors->add($call_status['error']); + return false; + } + + $work_item_offers = $result_array['work_item_offers']; + return $work_item_offers; + } + // deleteOwnWorkItem - deletes work item from remote work server. function deleteOwnWorkItem($work_id) { global $i18n; diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index bf4e69ccd..b903120bd 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- - + diff --git a/WEB-INF/templates/work_offers.tpl b/WEB-INF/templates/work_offers.tpl new file mode 100644 index 000000000..07a253d90 --- /dev/null +++ b/WEB-INF/templates/work_offers.tpl @@ -0,0 +1,30 @@ + + +
 Anuko Time Tracker 1.19.12.5143 | Copyright © Anuko | +  Anuko Time Tracker 1.19.12.5144 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/work.tpl b/WEB-INF/templates/work.tpl index 034785190..1d5e40413 100644 --- a/WEB-INF/templates/work.tpl +++ b/WEB-INF/templates/work.tpl @@ -22,7 +22,7 @@ {$work_item.subject|escape} {$work_item.description|escape} {$work_item.status_label}{if $work_item.num_offers}{$work_item.num_offers}{/if}{if $work_item.num_offers}{$work_item.num_offers}{/if} {$work_item.amount_with_currency} {$i18n.label.edit} {$i18n.label.delete}
+ + + +
+ +{if $work_item_offers} + + + + + + + + {foreach $work_item_offers as $offer} + + + + + + + {/foreach} +
{$i18n.label.offer}{$i18n.label.description}{$i18n.label.status}{$i18n.label.budget}
{$offer.subject|escape}{$offer.description|escape}{$offer.status_label}{$offer.amount_with_currency}
+{/if} + +
diff --git a/work_offers.php b/work_offers.php new file mode 100644 index 000000000..39ab03a62 --- /dev/null +++ b/work_offers.php @@ -0,0 +1,55 @@ +isPluginEnabled('wk')) { + header('Location: feature_disabled.php'); + exit(); +} +$work_id = (int)$request->getParameter('id'); +$workHelper = new ttWorkHelper($err); +$work_item = $workHelper->getOwnWorkItem($work_id); +if (!$work_item) { + header('Location: access_denied.php'); + exit(); +} +// End of access checks. + +$work_item_offers = $workHelper->getOwnWorkItemOffers($work_id); + +$smarty->assign('work_item_offers', $work_item_offers); +$smarty->assign('title', $i18n->get('work.label.offers')); +$smarty->assign('content_page_name', 'work_offers.tpl'); +$smarty->display('index.tpl'); From e6ab3854fe252c00a25da7aa65656d4386cf7709 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 9 Oct 2019 21:22:48 +0000 Subject: [PATCH 146/877] Provided work details on work_offers.php to improve the UI. --- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/work_offers.tpl | 16 +++++++++++++--- work_offers.php | 1 + 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index b903120bd..3de58c5a9 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.19.12.5144 | Copyright © Anuko | +  Anuko Time Tracker 1.19.12.5145 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/work_offers.tpl b/WEB-INF/templates/work_offers.tpl index 07a253d90..d4ecfbbd3 100644 --- a/WEB-INF/templates/work_offers.tpl +++ b/WEB-INF/templates/work_offers.tpl @@ -3,20 +3,30 @@ + + + +
+ + + + +
{$i18n.label.work}: {$work_item.subject}
{$i18n.label.description}: {$work_item.descr_short|escape}
{$i18n.label.budget}: {$work_item.amount_with_currency}
+
{if $work_item_offers} - - + + {foreach $work_item_offers as $offer} - + diff --git a/work_offers.php b/work_offers.php index 39ab03a62..9da3930aa 100644 --- a/work_offers.php +++ b/work_offers.php @@ -49,6 +49,7 @@ $work_item_offers = $workHelper->getOwnWorkItemOffers($work_id); +$smarty->assign('work_item', $work_item); $smarty->assign('work_item_offers', $work_item_offers); $smarty->assign('title', $i18n->get('work.label.offers')); $smarty->assign('content_page_name', 'work_offers.tpl'); From 317ec89a0967ccb0dd5c833786a4db0c2915b4ff Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 11 Oct 2019 17:38:31 +0000 Subject: [PATCH 147/877] A bit more work in progress on Work plugin. --- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/offer_add.tpl | 14 +++++++++++++- WEB-INF/templates/offer_edit.tpl | 25 +++++++++++++------------ offer_add.php | 6 +----- offer_edit.php | 6 +----- offer_view.php | 7 +++++++ 6 files changed, 36 insertions(+), 24 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 3de58c5a9..3997e5d18 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
{$i18n.label.offer}{$i18n.label.description}{$i18n.label.contractor}{$i18n.label.description} {$i18n.label.status} {$i18n.label.budget}
{$offer.subject|escape}{$offer.group_name|escape} {$offer.description|escape} {$offer.status_label} {$offer.amount_with_currency}
-
 Anuko Time Tracker 1.19.12.5145 | Copyright © Anuko | +  Anuko Time Tracker 1.19.12.5146 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/offer_add.tpl b/WEB-INF/templates/offer_add.tpl index d31fb1753..80e07d803 100644 --- a/WEB-INF/templates/offer_add.tpl +++ b/WEB-INF/templates/offer_add.tpl @@ -1,5 +1,17 @@ {$forms.offerForm.open} - +
+{if $work_item} + + + +{/if} +
+ + + + +
{$i18n.label.work}: {$work_item.subject}
{$i18n.label.description}: {$work_item.descr_short|escape}
{$i18n.label.budget}: {$work_item.amount_with_currency}
+
diff --git a/WEB-INF/templates/offer_edit.tpl b/WEB-INF/templates/offer_edit.tpl index ba1555e44..5c1e89a33 100644 --- a/WEB-INF/templates/offer_edit.tpl +++ b/WEB-INF/templates/offer_edit.tpl @@ -1,19 +1,20 @@ {$forms.offerForm.open} -
+
+{if $work_item} + + + +{/if} +
+ + + + +
{$i18n.label.work}: {$work_item.subject}
{$i18n.label.description}: {$work_item.descr_short|escape}
{$i18n.label.budget}: {$work_item.amount_with_currency}
+
-{if $work_id} - - - - - - - - - -{/if} diff --git a/offer_add.php b/offer_add.php index 42925fd59..ba430060c 100644 --- a/offer_add.php +++ b/offer_add.php @@ -112,11 +112,7 @@ } } // isPost -if ($cl_work_id) { - $smarty->assign('work_id', $cl_work_id); - $smarty->assign('work_name', $work_item['subject']); - $smarty->assign('work_description', $work_item['descr_short']); -} +$smarty->assign('work_item', $work_item); $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="document.offerForm.work_name.focus()"'); $smarty->assign('title', $i18n->get('title.add_offer')); diff --git a/offer_edit.php b/offer_edit.php index 7c695ee1c..436f31b37 100644 --- a/offer_edit.php +++ b/offer_edit.php @@ -127,11 +127,7 @@ } } // isPost -if ($work_id) { - $smarty->assign('work_id', $work_id); - $smarty->assign('work_name', $work_item['subject']); - $smarty->assign('work_description', $work_item['descr_short']); -} +$smarty->assign('work_item', $work_item); $smarty->assign('show_moderator_comment', $show_moderator_comment); $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('title', $i18n->get('title.edit_offer')); diff --git a/offer_view.php b/offer_view.php index 6fd2057c1..482d1c4ab 100644 --- a/offer_view.php +++ b/offer_view.php @@ -48,6 +48,13 @@ } // End of access checks. +// Is this offer associated with a work item? +$work_id = $offer['work_id']; +if ($work_id) { + $work_item = $workHelper->getAvailableWorkItem($work_id); + if (!$work_item) $err->add($i18n->get('work.error.work_not_available')); +} + $cl_contractor = $offer['group_name']; $cl_name = $offer['subject']; $cl_description = $offer['descr_short']; From db1fcbec8994970c5e2f3e308b01c85e205e49d5 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 11 Oct 2019 19:04:15 +0000 Subject: [PATCH 148/877] Starting coding accepting / declining offers workflow. --- WEB-INF/lib/ttWorkHelper.class.php | 64 +++++++++++++++++++- WEB-INF/resources/ca.lang.php | 3 +- WEB-INF/resources/cs.lang.php | 3 +- WEB-INF/resources/da.lang.php | 3 +- WEB-INF/resources/de.lang.php | 3 +- WEB-INF/resources/en.lang.php | 3 +- WEB-INF/resources/es.lang.php | 3 +- WEB-INF/resources/et.lang.php | 3 +- WEB-INF/resources/fa.lang.php | 3 +- WEB-INF/resources/fi.lang.php | 3 +- WEB-INF/resources/fr.lang.php | 3 +- WEB-INF/resources/gr.lang.php | 3 +- WEB-INF/resources/he.lang.php | 3 +- WEB-INF/resources/hu.lang.php | 3 +- WEB-INF/resources/it.lang.php | 3 +- WEB-INF/resources/ja.lang.php | 3 +- WEB-INF/resources/ko.lang.php | 3 +- WEB-INF/resources/nl.lang.php | 3 +- WEB-INF/resources/no.lang.php | 3 +- WEB-INF/resources/pl.lang.php | 3 +- WEB-INF/resources/pt-br.lang.php | 3 +- WEB-INF/resources/pt.lang.php | 3 +- WEB-INF/resources/ro.lang.php | 3 +- WEB-INF/resources/ru.lang.php | 3 +- WEB-INF/resources/sk.lang.php | 3 +- WEB-INF/resources/sl.lang.php | 3 +- WEB-INF/resources/sr.lang.php | 3 +- WEB-INF/resources/sv.lang.php | 3 +- WEB-INF/resources/tr.lang.php | 3 +- WEB-INF/resources/zh-cn.lang.php | 3 +- WEB-INF/resources/zh-tw.lang.php | 3 +- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/work_offer_view.tpl | 44 ++++++++++++++ WEB-INF/templates/work_offers.tpl | 2 +- work_offer_view.php | 86 +++++++++++++++++++++++++++ 35 files changed, 255 insertions(+), 33 deletions(-) create mode 100644 WEB-INF/templates/work_offer_view.tpl create mode 100644 work_offer_view.php diff --git a/WEB-INF/lib/ttWorkHelper.class.php b/WEB-INF/lib/ttWorkHelper.class.php index 16d3ddd74..5b809696b 100644 --- a/WEB-INF/lib/ttWorkHelper.class.php +++ b/WEB-INF/lib/ttWorkHelper.class.php @@ -36,7 +36,8 @@ class ttWorkHelper { var $register_uri = null; // URI to register with remote work server. var $put_own_work_item_uri = null; // URI to publish own work item. var $get_own_work_item_uri = null; // URI to get own work item details. - var $get_own_work_item_offers_uri = null; // URI to get offers on own work item. + var $get_own_work_item_offer_uri = null; // URI to get own work item offer. + var $get_own_work_item_offers_uri = null; // URI to get offers on own work item. var $get_own_work_items_uri = null; // URI to get own work items for group. var $get_available_work_items_uri = null; // URI to get available work items for group. var $get_available_work_item_uri = null; // URI to get a single available work item. @@ -68,6 +69,7 @@ function __construct(&$errors) { $this->register_uri = $this->work_server_uri.'register'; // register_0_0 $this->put_own_work_item_uri = $this->work_server_uri.'putownworkitem'; $this->get_own_work_item_uri = $this->work_server_uri.'getownworkitem'; + $this->get_own_work_item_offer_uri = $this->work_server_uri.'getownworkitemoffer'; $this->get_own_work_item_offers_uri = $this->work_server_uri.'getownworkitemoffers'; $this->get_own_work_items_uri = $this->work_server_uri.'getownworkitems'; $this->get_available_work_items_uri = $this->work_server_uri.'getavailableworkitems'; @@ -984,6 +986,66 @@ function deleteOwnOffer($offer_id) { return true; } + // getOwnWorkItemOffer - gets offer details from remote work server + // for an offer posted on own work item. + function getOwnWorkItemOffer($offer_id) { + global $i18n; + global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $curl_fields = array('lang' => urlencode($user->lang), + 'site_id' => urlencode($this->site_id), + 'site_key' => urlencode($this->site_key), + 'org_id' => urlencode($org_id), + 'org_key' => urlencode($user->getOrgKey()), + 'group_id' => urlencode($group_id), + 'group_key' => urlencode($user->getGroupKey()), + 'offer_id' => urlencode($offer_id)); + + // url-ify the data for the POST. + foreach($curl_fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; } + $fields_string = rtrim($fields_string, '&'); + + // Open connection. + $ch = curl_init(); + + // Set the url, number of POST vars, POST data. + curl_setopt($ch, CURLOPT_URL, $this->get_own_work_item_offer_uri); + curl_setopt($ch, CURLOPT_POST, true); + curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + + // Execute a post request. + $result = curl_exec($ch); + + // Close connection. + curl_close($ch); + + if (!$result) { + $this->errors->add($i18n->get('error.remote_work')); + return false; + } + + $result_array = json_decode($result, true); + + // Check for errors. + $call_status = $result_array['call_status']; + if (!$call_status) { + $this->errors->add($i18n->get('error.remote_work')); + return false; + } + if ($call_status['code'] != TT_CURL_SUCCESS) { + $this->errors->add($call_status['error']); + return false; + } + + $offer = $result_array['offer']; + return $offer; + } + // getCurrencies - obtains a list of supported currencies. static function getCurrencies() { $mdb2 = getConnection(); diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index 3628ae032..679013a76 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -713,5 +713,6 @@ // 'work.label.offers' => 'Offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', -// 'work.button.accept_offer' => 'Accept offer', +// 'work.button.accept' => 'Accept', +// 'work.button.decline' => 'Decline', ); diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index 22ce44e37..e401828d2 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -726,5 +726,6 @@ // 'work.label.offers' => 'Offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', -// 'work.button.accept_offer' => 'Accept offer', +// 'work.button.accept' => 'Accept', +// 'work.button.decline' => 'Decline', ); diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index a41817c94..3995be64d 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -687,5 +687,6 @@ // 'work.label.offers' => 'Offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', -// 'work.button.accept_offer' => 'Accept offer', +// 'work.button.accept' => 'Accept', +// 'work.button.decline' => 'Decline', ); diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index a4367f344..6c0201924 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -663,5 +663,6 @@ // 'work.label.offers' => 'Offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', -// 'work.button.accept_offer' => 'Accept offer', +// 'work.button.accept' => 'Accept', +// 'work.button.decline' => 'Decline', ); diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index b7228d133..08b35fe6e 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -643,5 +643,6 @@ 'work.label.offers' => 'Offers', 'work.button.send_message' => 'Send message', 'work.button.make_offer' => 'Make offer', -'work.button.accept_offer' => 'Accept offer', +'work.button.accept' => 'Accept', +'work.button.decline' => 'Decline', ); diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index b96aed296..d0cc8ede0 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -728,5 +728,6 @@ // 'work.label.offers' => 'Offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', -// 'work.button.accept_offer' => 'Accept offer', +// 'work.button.accept' => 'Accept', +// 'work.button.decline' => 'Decline', ); diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index 0dbd6c9ca..026d1077c 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -694,5 +694,6 @@ // 'work.label.offers' => 'Offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', -// 'work.button.accept_offer' => 'Accept offer', +// 'work.button.accept' => 'Accept', +// 'work.button.decline' => 'Decline', ); diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index 0bb19d259..90b9d86d9 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -711,5 +711,6 @@ // 'work.label.offers' => 'Offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', -// 'work.button.accept_offer' => 'Accept offer', +// 'work.button.accept' => 'Accept', +// 'work.button.decline' => 'Decline', ); diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 6ec926d97..598bc016a 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -693,5 +693,6 @@ // 'work.label.offers' => 'Offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', -// 'work.button.accept_offer' => 'Accept offer', +// 'work.button.accept' => 'Accept', +// 'work.button.decline' => 'Decline', ); diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index 735bb2d07..8fc272280 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -683,5 +683,6 @@ // 'work.label.offers' => 'Offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', -// 'work.button.accept_offer' => 'Accept offer', +// 'work.button.accept' => 'Accept', +// 'work.button.decline' => 'Decline', ); diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index 8fce19af8..3eb0f705f 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -676,5 +676,6 @@ // 'work.label.offers' => 'Offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', -// 'work.button.accept_offer' => 'Accept offer', +// 'work.button.accept' => 'Accept', +// 'work.button.decline' => 'Decline', ); diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index f04bbf00c..b392596a3 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -713,5 +713,6 @@ // 'work.label.offers' => 'Offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', -// 'work.button.accept_offer' => 'Accept offer', +// 'work.button.accept' => 'Accept', +// 'work.button.decline' => 'Decline', ); diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index 099c6f2fe..3b702a824 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -718,5 +718,6 @@ // 'work.label.offers' => 'Offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', -// 'work.button.accept_offer' => 'Accept offer', +// 'work.button.accept' => 'Accept', +// 'work.button.decline' => 'Decline', ); diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index 7c28ee423..0eb8d42f9 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -690,5 +690,6 @@ // 'work.label.offers' => 'Offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', -// 'work.button.accept_offer' => 'Accept offer', +// 'work.button.accept' => 'Accept', +// 'work.button.decline' => 'Decline', ); diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index 1f4cc51e8..8c04cac8a 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -721,5 +721,6 @@ // 'work.label.offers' => 'Offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', -// 'work.button.accept_offer' => 'Accept offer', +// 'work.button.accept' => 'Accept', +// 'work.button.decline' => 'Decline', ); diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index 0c18572e2..59940530e 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -719,5 +719,6 @@ // 'work.label.offers' => 'Offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', -// 'work.button.accept_offer' => 'Accept offer', +// 'work.button.accept' => 'Accept', +// 'work.button.decline' => 'Decline', ); diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 40bd8f416..464f3a57e 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -645,5 +645,6 @@ // 'work.label.offers' => 'Offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', -// 'work.button.accept_offer' => 'Accept offer', +// 'work.button.accept' => 'Accept', +// 'work.button.decline' => 'Decline', ); diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index 7d165b5a2..d04dbad7a 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -718,5 +718,6 @@ // 'work.label.offers' => 'Offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', -// 'work.button.accept_offer' => 'Accept offer', +// 'work.button.accept' => 'Accept', +// 'work.button.decline' => 'Decline', ); diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index df26f2726..337f867dd 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -696,5 +696,6 @@ // 'work.label.offers' => 'Offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', -// 'work.button.accept_offer' => 'Accept offer', +// 'work.button.accept' => 'Accept', +// 'work.button.decline' => 'Decline', ); diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index aeeeb00b8..adda37da4 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -691,5 +691,6 @@ // 'work.label.offers' => 'Offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', -// 'work.button.accept_offer' => 'Accept offer', +// 'work.button.accept' => 'Accept', +// 'work.button.decline' => 'Decline', ); diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index ea4f09d33..36ace36d9 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -700,5 +700,6 @@ // 'work.label.offers' => 'Offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', -// 'work.button.accept_offer' => 'Accept offer', +// 'work.button.accept' => 'Accept', +// 'work.button.decline' => 'Decline', ); diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index 6c117ae2e..3b0c588b0 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -721,5 +721,6 @@ // 'work.label.offers' => 'Offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', -// 'work.button.accept_offer' => 'Accept offer', +// 'work.button.accept' => 'Accept', +// 'work.button.decline' => 'Decline', ); diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index fa6ebc8ce..6a7359f83 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -624,5 +624,6 @@ 'work.label.offers' => 'Предложения', 'work.button.send_message' => 'Отправить сообщение', 'work.button.make_offer' => 'Сделать предложение', -'work.button.accept_offer' => 'Принять предложение', +'work.button.accept' => 'Принять', +'work.button.decline' => 'Отклонить', ); diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index 2507d3bd9..113beb835 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -702,5 +702,6 @@ // 'work.label.offers' => 'Offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', -// 'work.button.accept_offer' => 'Accept offer', +// 'work.button.accept' => 'Accept', +// 'work.button.decline' => 'Decline', ); diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index dadd1e233..60ed86cd2 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -694,5 +694,6 @@ // 'work.label.offers' => 'Offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', -// 'work.button.accept_offer' => 'Accept offer', +// 'work.button.accept' => 'Accept', +// 'work.button.decline' => 'Decline', ); diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index 628345254..8c559955d 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -694,5 +694,6 @@ // 'work.label.offers' => 'Offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', -// 'work.button.accept_offer' => 'Accept offer', +// 'work.button.accept' => 'Accept', +// 'work.button.decline' => 'Decline', ); diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index a0103675a..a1b6f719c 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -692,5 +692,6 @@ // 'work.label.offers' => 'Offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', -// 'work.button.accept_offer' => 'Accept offer', +// 'work.button.accept' => 'Accept', +// 'work.button.decline' => 'Decline', ); diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index 601f537d0..8adc4f5d1 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -734,5 +734,6 @@ // 'work.label.offers' => 'Offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', -// 'work.button.accept_offer' => 'Accept offer', +// 'work.button.accept' => 'Accept', +// 'work.button.decline' => 'Decline', ); diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index bd278ca10..7c2f697eb 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -705,5 +705,6 @@ // 'work.label.offers' => 'Offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', -// 'work.button.accept_offer' => 'Accept offer', +// 'work.button.accept' => 'Accept', +// 'work.button.decline' => 'Decline', ); diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index 1ee672aa6..deada9f15 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -711,5 +711,6 @@ // 'work.label.offers' => 'Offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', -// 'work.button.accept_offer' => 'Accept offer', +// 'work.button.accept' => 'Accept', +// 'work.button.decline' => 'Decline', ); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 3997e5d18..a91bfe49c 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
{$i18n.label.work}:{$work_name}
{$forms.offerForm.work_description.control}
 
{$i18n.label.offer} (*): {$forms.offerForm.offer_name.control}
- {foreach $work_item_offers as $offer} - + diff --git a/work_offer_view.php b/work_offer_view.php new file mode 100644 index 000000000..e0b8e5d80 --- /dev/null +++ b/work_offer_view.php @@ -0,0 +1,86 @@ +isPluginEnabled('wk')) { + header('Location: feature_disabled.php'); + exit(); +} +if (!ttAccessAllowed('manage_work')) { + header('Location: access_denied.php'); + exit(); +} +$cl_offer_id = (int)$request->getParameter('id'); +$workHelper = new ttWorkHelper($err); +$offer = $workHelper->getOwnWorkItemOffer($cl_offer_id); +if (!$offer) { + header('Location: access_denied.php'); + exit(); +} +// End of access checks. + +// Get an associated work item. +$work_item = $workHelper->getOwnWorkItem($offer['work_id']); +if (!$work_item) $err->add($i18n->get('work.error.work_not_available')); + +$cl_contractor = $offer['group_name']; +$cl_name = $offer['subject']; +$cl_description = $offer['descr_short']; +$cl_details = $offer['descr_long']; +$cl_budget = $offer['amount_with_currency']; +$cl_status = $offer['status_label']; + +// TODO: coding ongoing down from here... +$form = new Form('offerForm'); +$form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_offer_id)); +$form->addInput(array('type'=>'text','name'=>'contractor','value'=>$cl_contractor)); +$form->getElement('contractor')->setEnabled(false); +$form->addInput(array('type'=>'text','name'=>'offer_name','style'=>'width: 400px;','value'=>$cl_name)); +$form->getElement('offer_name')->setEnabled(false); +$form->addInput(array('type'=>'textarea','name'=>'description','style'=>'width: 400px; height: 80px;','value'=>$cl_description)); +$form->getElement('description')->setEnabled(false); +$form->addInput(array('type'=>'textarea','name'=>'details','style'=>'width: 400px; height: 200px;','value'=>$cl_details)); +$form->getElement('details')->setEnabled(false); +$form->addInput(array('type'=>'text','name'=>'budget','value'=>$cl_budget)); +$form->getElement('budget')->setEnabled(false); +$form->addInput(array('type'=>'text','name'=>'status','style'=>'width: 400px;','value'=>$cl_status)); +$form->getElement('status')->setEnabled(false); +if ($offer['status'] == STATUS_APPROVED) { + $form->addInput(array('type'=>'submit','name'=>'btn_accept','value'=>$i18n->get('work.button.accept'))); + $form->addInput(array('type'=>'submit','name'=>'btn_decline','value'=>$i18n->get('work.button.decline'))); +} + +$smarty->assign('forms', array($form->getName()=>$form->toArray())); +$smarty->assign('title', $i18n->get('title.offer')); +$smarty->assign('content_page_name', 'work_offer_view.tpl'); +$smarty->display('index.tpl'); From 67ea03443be54301664f7e9571a79ad35f1e4ad0 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 11 Oct 2019 22:44:48 +0000 Subject: [PATCH 149/877] Coded declining an offer feature. --- WEB-INF/lib/ttWorkHelper.class.php | 65 +++++++++++++++++++++++++++ WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/work_offer_view.tpl | 18 +++++++- work_offer_view.php | 40 ++++++++++++++++- 4 files changed, 122 insertions(+), 3 deletions(-) diff --git a/WEB-INF/lib/ttWorkHelper.class.php b/WEB-INF/lib/ttWorkHelper.class.php index 5b809696b..af4922024 100644 --- a/WEB-INF/lib/ttWorkHelper.class.php +++ b/WEB-INF/lib/ttWorkHelper.class.php @@ -37,6 +37,7 @@ class ttWorkHelper { var $put_own_work_item_uri = null; // URI to publish own work item. var $get_own_work_item_uri = null; // URI to get own work item details. var $get_own_work_item_offer_uri = null; // URI to get own work item offer. + var $decline_own_work_item_offer_uri = null; // URI to decline own work item offer. var $get_own_work_item_offers_uri = null; // URI to get offers on own work item. var $get_own_work_items_uri = null; // URI to get own work items for group. var $get_available_work_items_uri = null; // URI to get available work items for group. @@ -75,6 +76,7 @@ function __construct(&$errors) { $this->get_available_work_items_uri = $this->work_server_uri.'getavailableworkitems'; $this->get_available_work_item_uri = $this->work_server_uri.'getavailableworkitem'; $this->delete_own_work_item_uri = $this->work_server_uri.'deleteownworkitem'; + $this->decline_own_work_item_offer_uri = $this->work_server_uri.'declineownworkitemoffer'; $this->update_own_work_item_uri = $this->work_server_uri.'updateownworkitem'; $this->put_own_offer_uri = $this->work_server_uri.'putownoffer'; $this->get_own_offer_uri = $this->work_server_uri.'getownoffer'; @@ -1046,6 +1048,69 @@ function getOwnWorkItemOffer($offer_id) { return $offer; } + // declineOwnWorkItemOffer - declines an offer posted on own work item in remote work server. + function declineOwnWorkItemOffer($fields) { + global $i18n; + global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $curl_fields = array('lang' => urlencode($user->lang), + 'site_id' => urlencode($this->site_id), + 'site_key' => urlencode($this->site_key), + 'org_id' => urlencode($org_id), + 'org_key' => urlencode($user->getOrgKey()), + 'group_id' => urlencode($group_id), + 'group_key' => urlencode($user->getGroupKey()), + 'offer_id' => urlencode($fields['offer_id']), + 'client_comment' => urlencode(base64_encode($fields['client_comment']))); + //'modified_ip' => urlencode($_SERVER['REMOTE_ADDR']), + //'modified_by' => urlencode($user->getUser()), + //'modified_by_name' => urlencode(base64_encode($user->getName())), + //'modified_by_email' => urlencode(base64_encode($user->getEmail()))); + + // url-ify the data for the POST. + foreach($curl_fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; } + $fields_string = rtrim($fields_string, '&'); + + // Open connection. + $ch = curl_init(); + + // Set the url, number of POST vars, POST data. + curl_setopt($ch, CURLOPT_URL, $this->decline_own_work_item_offer_uri); + curl_setopt($ch, CURLOPT_POST, true); + curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + + // Execute a post request. + $result = curl_exec($ch); + + // Close connection. + curl_close($ch); + + if (!$result) { + $this->errors->add($i18n->get('error.remote_work')); + return false; + } + + $result_array = json_decode($result, true); + + // Check for errors. + $call_status = $result_array['call_status']; + if (!$call_status) { + $this->errors->add($i18n->get('error.remote_work')); + return false; + } + if ($call_status['code'] != TT_CURL_SUCCESS) { + $this->errors->add($call_status['error']); + return false; + } + + return true; + } + // getCurrencies - obtains a list of supported currencies. static function getCurrencies() { $mdb2 = getConnection(); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index a91bfe49c..c9b0814a4 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.19.12.5146 | Copyright © Anuko | +  Anuko Time Tracker 1.19.12.5147 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/work_offer_view.tpl b/WEB-INF/templates/work_offer_view.tpl new file mode 100644 index 000000000..79fa8a161 --- /dev/null +++ b/WEB-INF/templates/work_offer_view.tpl @@ -0,0 +1,44 @@ +{$forms.offerForm.open} + + + + +
+ + + + + + + + + + + + + + + + + +{if $show_files} + + + + +{/if} + + + + + + + + +{if isTrue('WORK_DEBUG')} + + +{/if} +
{$i18n.label.contractor}:{$forms.offerForm.contractor.control}
{$i18n.label.offer}:{$forms.offerForm.offer_name.control}
{$i18n.label.description}:{$forms.offerForm.description.control}
{$i18n.label.details}:{$forms.offerForm.details.control}
{$i18n.label.file}:{$forms.offerForm.newfile.control}
{$i18n.label.budget}:{$forms.offerForm.budget.control}
{$i18n.label.status}:{$forms.offerForm.status.control}
{$forms.offerForm.btn_accept.control} {$forms.offerForm.btn_decline.control}
+
+{$forms.offerForm.close} diff --git a/WEB-INF/templates/work_offers.tpl b/WEB-INF/templates/work_offers.tpl index d4ecfbbd3..bd867a9f4 100644 --- a/WEB-INF/templates/work_offers.tpl +++ b/WEB-INF/templates/work_offers.tpl @@ -26,7 +26,7 @@
{$offer.group_name|escape}{$offer.group_name|escape} {$offer.description|escape} {$offer.status_label} {$offer.amount_with_currency}
-
 Anuko Time Tracker 1.19.12.5147 | Copyright © Anuko | +  Anuko Time Tracker 1.19.12.5148 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/work_offer_view.tpl b/WEB-INF/templates/work_offer_view.tpl index 79fa8a161..0dfa4158c 100644 --- a/WEB-INF/templates/work_offer_view.tpl +++ b/WEB-INF/templates/work_offer_view.tpl @@ -1,5 +1,17 @@ {$forms.offerForm.open} - +
+{if $work_item} + + + +{/if} +
+ + + + +
{$i18n.label.work}: {$work_item.subject}
{$i18n.label.description}: {$work_item.descr_short|escape}
{$i18n.label.budget}: {$work_item.amount_with_currency}
+
@@ -33,6 +45,10 @@ + + + + {if isTrue('WORK_DEBUG')} diff --git a/work_offer_view.php b/work_offer_view.php index e0b8e5d80..c221b9292 100644 --- a/work_offer_view.php +++ b/work_offer_view.php @@ -53,6 +53,12 @@ $work_item = $workHelper->getOwnWorkItem($offer['work_id']); if (!$work_item) $err->add($i18n->get('work.error.work_not_available')); +if ($request->isPost()) { + $cl_client_comment = $request->getParameter('client_comment'); +} else { + $cl_client_comment = $offer['client_comment']; +} + $cl_contractor = $offer['group_name']; $cl_name = $offer['subject']; $cl_description = $offer['descr_short']; @@ -60,7 +66,6 @@ $cl_budget = $offer['amount_with_currency']; $cl_status = $offer['status_label']; -// TODO: coding ongoing down from here... $form = new Form('offerForm'); $form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_offer_id)); $form->addInput(array('type'=>'text','name'=>'contractor','value'=>$cl_contractor)); @@ -75,11 +80,44 @@ $form->getElement('budget')->setEnabled(false); $form->addInput(array('type'=>'text','name'=>'status','style'=>'width: 400px;','value'=>$cl_status)); $form->getElement('status')->setEnabled(false); +$form->addInput(array('type'=>'textarea','name'=>'client_comment','style'=>'width: 400px; height: 80px;','value'=>$cl_client_comment)); if ($offer['status'] == STATUS_APPROVED) { $form->addInput(array('type'=>'submit','name'=>'btn_accept','value'=>$i18n->get('work.button.accept'))); $form->addInput(array('type'=>'submit','name'=>'btn_decline','value'=>$i18n->get('work.button.decline'))); } +if ($request->isPost()) { + // Validate user input. + if (!ttValidString($cl_client_comment)) $err->add($i18n->get('error.field'), $i18n->get('label.comment')); + + // Ensure user email exists (required for workflow). + if (!$user->getEmail()) $err->add($i18n->get('error.no_email')); + + if ($err->no()) { + $workHelper = new ttWorkHelper($err); + $fields = array('offer_id'=>$cl_offer_id, + 'client_comment'=>$cl_client_comment); + + if ($request->getParameter('btn_accept')) { + die ("not yet implemented... sorry"); + // Accept offer. + if ($workHelper->acceptOwnWorkItemOffer($fields)) { + header('Location: work_offer_view.php?id='.$cl_offer_id); + exit(); + } + } + + if ($request->getParameter('btn_decline')) { + // Decline offer. + if ($workHelper->declineOwnWorkItemOffer($fields)) { + header('Location: work_offer_view.php?id='.$cl_offer_id); + exit(); + } + } + } +} // isPost + +$smarty->assign('work_item', $work_item); $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('title', $i18n->get('title.offer')); $smarty->assign('content_page_name', 'work_offer_view.tpl'); From 7637464ff5809a0c3038a5fc318786a0528429c7 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 12 Oct 2019 16:27:45 +0000 Subject: [PATCH 150/877] Partial progress on accepting offers in Work plugin. --- WEB-INF/lib/ttWorkHelper.class.php | 65 ++++++++++++++++++++++++++++++ WEB-INF/templates/footer.tpl | 2 +- work_offer_view.php | 1 - 3 files changed, 66 insertions(+), 2 deletions(-) diff --git a/WEB-INF/lib/ttWorkHelper.class.php b/WEB-INF/lib/ttWorkHelper.class.php index af4922024..2f1deb40a 100644 --- a/WEB-INF/lib/ttWorkHelper.class.php +++ b/WEB-INF/lib/ttWorkHelper.class.php @@ -37,6 +37,7 @@ class ttWorkHelper { var $put_own_work_item_uri = null; // URI to publish own work item. var $get_own_work_item_uri = null; // URI to get own work item details. var $get_own_work_item_offer_uri = null; // URI to get own work item offer. + var $accept_own_work_item_offer_uri = null; // URI to accept own work item offer. var $decline_own_work_item_offer_uri = null; // URI to decline own work item offer. var $get_own_work_item_offers_uri = null; // URI to get offers on own work item. var $get_own_work_items_uri = null; // URI to get own work items for group. @@ -76,6 +77,7 @@ function __construct(&$errors) { $this->get_available_work_items_uri = $this->work_server_uri.'getavailableworkitems'; $this->get_available_work_item_uri = $this->work_server_uri.'getavailableworkitem'; $this->delete_own_work_item_uri = $this->work_server_uri.'deleteownworkitem'; + $this->accept_own_work_item_offer_uri = $this->work_server_uri.'acceptownworkitemoffer'; $this->decline_own_work_item_offer_uri = $this->work_server_uri.'declineownworkitemoffer'; $this->update_own_work_item_uri = $this->work_server_uri.'updateownworkitem'; $this->put_own_offer_uri = $this->work_server_uri.'putownoffer'; @@ -1111,6 +1113,69 @@ function declineOwnWorkItemOffer($fields) { return true; } + // acceptOwnWorkItemOffer - accepts an offer posted on own work item in remote work server. + function acceptOwnWorkItemOffer($fields) { + global $i18n; + global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $curl_fields = array('lang' => urlencode($user->lang), + 'site_id' => urlencode($this->site_id), + 'site_key' => urlencode($this->site_key), + 'org_id' => urlencode($org_id), + 'org_key' => urlencode($user->getOrgKey()), + 'group_id' => urlencode($group_id), + 'group_key' => urlencode($user->getGroupKey()), + 'offer_id' => urlencode($fields['offer_id']), + 'client_comment' => urlencode(base64_encode($fields['client_comment'])), + 'accepted_ip' => urlencode($_SERVER['REMOTE_ADDR']), + 'accepted_by' => urlencode($user->getUser()), + 'accepted_by_name' => urlencode(base64_encode($user->getName())), + 'accepted_by_email' => urlencode(base64_encode($user->getEmail()))); + + // url-ify the data for the POST. + foreach($curl_fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; } + $fields_string = rtrim($fields_string, '&'); + + // Open connection. + $ch = curl_init(); + + // Set the url, number of POST vars, POST data. + curl_setopt($ch, CURLOPT_URL, $this->accept_own_work_item_offer_uri); + curl_setopt($ch, CURLOPT_POST, true); + curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + + // Execute a post request. + $result = curl_exec($ch); + + // Close connection. + curl_close($ch); + + if (!$result) { + $this->errors->add($i18n->get('error.remote_work')); + return false; + } + + $result_array = json_decode($result, true); + + // Check for errors. + $call_status = $result_array['call_status']; + if (!$call_status) { + $this->errors->add($i18n->get('error.remote_work')); + return false; + } + if ($call_status['code'] != TT_CURL_SUCCESS) { + $this->errors->add($call_status['error']); + return false; + } + + return true; + } + // getCurrencies - obtains a list of supported currencies. static function getCurrencies() { $mdb2 = getConnection(); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index c9b0814a4..e0d3b5a1b 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
{$i18n.label.status}: {$forms.offerForm.status.control}
{$i18n.label.comment} (*):{$forms.offerForm.client_comment.control}
{$forms.offerForm.btn_accept.control} {$forms.offerForm.btn_decline.control}
-
 Anuko Time Tracker 1.19.12.5148 | Copyright © Anuko | +  Anuko Time Tracker 1.19.12.5149 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/work_offer_view.php b/work_offer_view.php index c221b9292..d14084457 100644 --- a/work_offer_view.php +++ b/work_offer_view.php @@ -99,7 +99,6 @@ 'client_comment'=>$cl_client_comment); if ($request->getParameter('btn_accept')) { - die ("not yet implemented... sorry"); // Accept offer. if ($workHelper->acceptOwnWorkItemOffer($fields)) { header('Location: work_offer_view.php?id='.$cl_offer_id); From ae1f39b44c791be6fbf61acc3261b14e96b95daa Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 13 Oct 2019 11:29:31 +0000 Subject: [PATCH 151/877] Some refactoring related to Work plugin. --- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/work.tpl | 16 ++++++++++++---- work.php | 12 ++++++------ 3 files changed, 19 insertions(+), 11 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index e0d3b5a1b..320f1c6f7 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.19.12.5149 | Copyright © Anuko | +  Anuko Time Tracker 1.19.12.5150 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/work.tpl b/WEB-INF/templates/work.tpl index 1d5e40413..cd72498f4 100644 --- a/WEB-INF/templates/work.tpl +++ b/WEB-INF/templates/work.tpl @@ -5,7 +5,7 @@
-{if $active_work} +{if $own_work_items} @@ -17,15 +17,23 @@ - {foreach $active_work as $work_item} + {foreach $own_work_items as $work_item} + {if $work_item.can_edit} + {else} + + {/if} + {if $work_item.can_delete} + {else} + + {/if} {/foreach}
{$i18n.work.label.our_work}
{$work_item.subject|escape} {$work_item.description|escape} {$work_item.status_label} {if $work_item.num_offers}{$work_item.num_offers}{/if} {$work_item.amount_with_currency}{$i18n.label.edit}{$i18n.label.delete}
@@ -41,14 +49,14 @@ -{if $available_work} +{if $available_work_items} - {foreach $available_work as $work_item} + {foreach $available_work_items as $work_item} diff --git a/work.php b/work.php index 606f8fbf9..f7cfeb91e 100644 --- a/work.php +++ b/work.php @@ -43,12 +43,12 @@ $workHelper = new ttWorkHelper($err); $groupItems = $workHelper->getGroupItems(); // All group items. if($user->can('manage_work')) { - $active_work = $groupItems['active_work']; // Active work items this group is outsourcing. + $own_work_items = $groupItems['own_work_items']; // Own work items this group is outsourcing. $available_offers = $groupItems['available_offers']; // Available offers from other organizations. } if($user->can('bid_on_work')) { - $available_work = $groupItems['available_work']; // Currently available work items from other orgs. - $active_offers = $groupItems['active_offers']; // Active offers this group makes available to other groups. + $available_work_items = $groupItems['available_work_items']; // Currently available work items from other orgs. + $own_offers = $groupItems['own_offers']; // Own offers this group makes available to other groups. } if($user->can('update_work')) { // $in_progress_work = ttWorkHelper::getInProgressWork(); // Work items in progress for other groups. @@ -56,9 +56,9 @@ } // TODO: review access rights for the code above. -$smarty->assign('active_work', $active_work); -$smarty->assign('available_work', $available_work); -$smarty->assign('active_offers', $active_offers); +$smarty->assign('own_work_items', $own_work_items); +$smarty->assign('available_work_items', $available_work_items); +$smarty->assign('own_offers', $own_offers); $smarty->assign('available_offers', $available_offers); $smarty->assign('title', $i18n->get('title.work')); $smarty->assign('content_page_name', 'work.tpl'); From 4e69e042945f0586cda96f50c164924c6d6de454 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 13 Oct 2019 11:42:43 +0000 Subject: [PATCH 152/877] Fixed displaying own offers. --- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/work.tpl | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 320f1c6f7..5ee395b41 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
{$i18n.title.available_work}
{$i18n.label.work} {$i18n.label.description} {$i18n.label.client} {$i18n.label.budget}
{$work_item.subject|escape} {$work_item.description|escape}
-
 Anuko Time Tracker 1.19.12.5150 | Copyright © Anuko | +  Anuko Time Tracker 1.19.12.5151 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/work.tpl b/WEB-INF/templates/work.tpl index cd72498f4..dcfb2945a 100644 --- a/WEB-INF/templates/work.tpl +++ b/WEB-INF/templates/work.tpl @@ -75,7 +75,7 @@
-{if $active_offers} +{if $own_offers} @@ -86,7 +86,7 @@ - {foreach $active_offers as $offer} + {foreach $own_offers as $offer} {if $offer.work_id} From 71b20397009d3a14b68a62ab144a9f4ce77778d2 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 13 Oct 2019 17:00:59 +0000 Subject: [PATCH 153/877] Introduced work type string in translaton files. --- WEB-INF/resources/cs.lang.php | 2 ++ WEB-INF/resources/da.lang.php | 2 ++ WEB-INF/resources/de.lang.php | 2 ++ WEB-INF/resources/es.lang.php | 2 ++ WEB-INF/resources/et.lang.php | 2 ++ WEB-INF/resources/fa.lang.php | 2 ++ WEB-INF/resources/fi.lang.php | 2 ++ WEB-INF/resources/fr.lang.php | 2 ++ WEB-INF/resources/gr.lang.php | 2 ++ WEB-INF/resources/he.lang.php | 2 ++ WEB-INF/resources/hu.lang.php | 2 ++ WEB-INF/resources/it.lang.php | 2 ++ WEB-INF/resources/ja.lang.php | 2 ++ WEB-INF/resources/ko.lang.php | 2 ++ WEB-INF/resources/nl.lang.php | 2 ++ WEB-INF/resources/no.lang.php | 2 ++ WEB-INF/resources/pl.lang.php | 2 ++ WEB-INF/resources/pt-br.lang.php | 2 ++ WEB-INF/resources/pt.lang.php | 2 ++ WEB-INF/resources/ro.lang.php | 2 ++ WEB-INF/resources/ru.lang.php | 2 ++ WEB-INF/resources/sk.lang.php | 2 ++ WEB-INF/resources/sl.lang.php | 2 ++ WEB-INF/resources/sr.lang.php | 2 ++ WEB-INF/resources/sv.lang.php | 2 ++ WEB-INF/resources/tr.lang.php | 2 ++ WEB-INF/resources/zh-cn.lang.php | 2 ++ WEB-INF/resources/zh-tw.lang.php | 2 ++ WEB-INF/templates/footer.tpl | 2 +- 29 files changed, 57 insertions(+), 1 deletion(-) diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index e401828d2..a1803742f 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -721,6 +721,8 @@ // TODO: translate the following. // 'work.error.work_not_available' => 'Work item is not available.', // 'work.error.offer_not_available' => 'Offer is not available.', +// 'work.type.one_time' => 'one time', // Work type is "one time job" for well defined work ("do exactly this"). +// 'work.type.ongoing' => 'ongoing', // Work type is "ongoing" for complex jobs (billed by the hour, multiple contractors, etc.) // 'work.label.our_work' => 'Our work', // 'work.label.our_offers' => 'Our offers', // 'work.label.offers' => 'Offers', diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index 3995be64d..fd692dabb 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -682,6 +682,8 @@ // TODO: translate the following. // 'work.error.work_not_available' => 'Work item is not available.', // 'work.error.offer_not_available' => 'Offer is not available.', +// 'work.type.one_time' => 'one time', // Work type is "one time job" for well defined work ("do exactly this"). +// 'work.type.ongoing' => 'ongoing', // Work type is "ongoing" for complex jobs (billed by the hour, multiple contractors, etc.) // 'work.label.our_work' => 'Our work', // 'work.label.our_offers' => 'Our offers', // 'work.label.offers' => 'Offers', diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index 6c0201924..691a73187 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -658,6 +658,8 @@ // TODO: translate the following. // 'work.error.work_not_available' => 'Work item is not available.', // 'work.error.offer_not_available' => 'Offer is not available.', +// 'work.type.one_time' => 'one time', // Work type is "one time job" for well defined work ("do exactly this"). +// 'work.type.ongoing' => 'ongoing', // Work type is "ongoing" for complex jobs (billed by the hour, multiple contractors, etc.) // 'work.label.our_work' => 'Our work', // 'work.label.our_offers' => 'Our offers', // 'work.label.offers' => 'Offers', diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index d0cc8ede0..edbc5bc12 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -723,6 +723,8 @@ // TODO: translate the following. // 'work.error.work_not_available' => 'Work item is not available.', // 'work.error.offer_not_available' => 'Offer is not available.', +// 'work.type.one_time' => 'one time', // Work type is "one time job" for well defined work ("do exactly this"). +// 'work.type.ongoing' => 'ongoing', // Work type is "ongoing" for complex jobs (billed by the hour, multiple contractors, etc.) // 'work.label.our_work' => 'Our work', // 'work.label.our_offers' => 'Our offers', // 'work.label.offers' => 'Offers', diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index 026d1077c..4cc562843 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -689,6 +689,8 @@ // TODO: translate the following. // 'work.error.work_not_available' => 'Work item is not available.', // 'work.error.offer_not_available' => 'Offer is not available.', +// 'work.type.one_time' => 'one time', // Work type is "one time job" for well defined work ("do exactly this"). +// 'work.type.ongoing' => 'ongoing', // Work type is "ongoing" for complex jobs (billed by the hour, multiple contractors, etc.) // 'work.label.our_work' => 'Our work', // 'work.label.our_offers' => 'Our offers', // 'work.label.offers' => 'Offers', diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index 90b9d86d9..5643669bf 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -706,6 +706,8 @@ // TODO: translate the following. // 'work.error.work_not_available' => 'Work item is not available.', // 'work.error.offer_not_available' => 'Offer is not available.', +// 'work.type.one_time' => 'one time', // Work type is "one time job" for well defined work ("do exactly this"). +// 'work.type.ongoing' => 'ongoing', // Work type is "ongoing" for complex jobs (billed by the hour, multiple contractors, etc.) // 'work.label.our_work' => 'Our work', // 'work.label.our_offers' => 'Our offers', // 'work.label.offers' => 'Offers', diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 598bc016a..05de8ed92 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -688,6 +688,8 @@ // TODO: translate the following. // 'work.error.work_not_available' => 'Work item is not available.', // 'work.error.offer_not_available' => 'Offer is not available.', +// 'work.type.one_time' => 'one time', // Work type is "one time job" for well defined work ("do exactly this"). +// 'work.type.ongoing' => 'ongoing', // Work type is "ongoing" for complex jobs (billed by the hour, multiple contractors, etc.) // 'work.label.our_work' => 'Our work', // 'work.label.our_offers' => 'Our offers', // 'work.label.offers' => 'Offers', diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index 8fc272280..b66100bb9 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -678,6 +678,8 @@ // TODO: translate the following. // 'work.error.work_not_available' => 'Work item is not available.', // 'work.error.offer_not_available' => 'Offer is not available.', +// 'work.type.one_time' => 'one time', // Work type is "one time job" for well defined work ("do exactly this"). +// 'work.type.ongoing' => 'ongoing', // Work type is "ongoing" for complex jobs (billed by the hour, multiple contractors, etc.) // 'work.label.our_work' => 'Our work', // 'work.label.our_offers' => 'Our offers', // 'work.label.offers' => 'Offers', diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index 3eb0f705f..fa549557c 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -671,6 +671,8 @@ // TODO: translate the following. // 'work.error.work_not_available' => 'Work item is not available.', // 'work.error.offer_not_available' => 'Offer is not available.', +// 'work.type.one_time' => 'one time', // Work type is "one time job" for well defined work ("do exactly this"). +// 'work.type.ongoing' => 'ongoing', // Work type is "ongoing" for complex jobs (billed by the hour, multiple contractors, etc.) // 'work.label.our_work' => 'Our work', // 'work.label.our_offers' => 'Our offers', // 'work.label.offers' => 'Offers', diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index b392596a3..3841cbf1c 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -708,6 +708,8 @@ // TODO: translate the following. // 'work.error.work_not_available' => 'Work item is not available.', // 'work.error.offer_not_available' => 'Offer is not available.', +// 'work.type.one_time' => 'one time', // Work type is "one time job" for well defined work ("do exactly this"). +// 'work.type.ongoing' => 'ongoing', // Work type is "ongoing" for complex jobs (billed by the hour, multiple contractors, etc.) // 'work.label.our_work' => 'Our work', // 'work.label.our_offers' => 'Our offers', // 'work.label.offers' => 'Offers', diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index 3b702a824..16a996544 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -713,6 +713,8 @@ // TODO: translate the following. // 'work.error.work_not_available' => 'Work item is not available.', // 'work.error.offer_not_available' => 'Offer is not available.', +// 'work.type.one_time' => 'one time', // Work type is "one time job" for well defined work ("do exactly this"). +// 'work.type.ongoing' => 'ongoing', // Work type is "ongoing" for complex jobs (billed by the hour, multiple contractors, etc.) // 'work.label.our_work' => 'Our work', // 'work.label.our_offers' => 'Our offers', // 'work.label.offers' => 'Offers', diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index 0eb8d42f9..17316bb71 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -685,6 +685,8 @@ // TODO: translate the following. // 'work.error.work_not_available' => 'Work item is not available.', // 'work.error.offer_not_available' => 'Offer is not available.', +// 'work.type.one_time' => 'one time', // Work type is "one time job" for well defined work ("do exactly this"). +// 'work.type.ongoing' => 'ongoing', // Work type is "ongoing" for complex jobs (billed by the hour, multiple contractors, etc.) // 'work.label.our_work' => 'Our work', // 'work.label.our_offers' => 'Our offers', // 'work.label.offers' => 'Offers', diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index 8c04cac8a..a7dde05cd 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -716,6 +716,8 @@ // TODO: translate the following. // 'work.error.work_not_available' => 'Work item is not available.', // 'work.error.offer_not_available' => 'Offer is not available.', +// 'work.type.one_time' => 'one time', // Work type is "one time job" for well defined work ("do exactly this"). +// 'work.type.ongoing' => 'ongoing', // Work type is "ongoing" for complex jobs (billed by the hour, multiple contractors, etc.) // 'work.label.our_work' => 'Our work', // 'work.label.our_offers' => 'Our offers', // 'work.label.offers' => 'Offers', diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index 59940530e..6e4898705 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -714,6 +714,8 @@ // TODO: translate the following. // 'work.error.work_not_available' => 'Work item is not available.', // 'work.error.offer_not_available' => 'Offer is not available.', +// 'work.type.one_time' => 'one time', // Work type is "one time job" for well defined work ("do exactly this"). +// 'work.type.ongoing' => 'ongoing', // Work type is "ongoing" for complex jobs (billed by the hour, multiple contractors, etc.) // 'work.label.our_work' => 'Our work', // 'work.label.our_offers' => 'Our offers', // 'work.label.offers' => 'Offers', diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 464f3a57e..182a5e41d 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -640,6 +640,8 @@ // TODO: translate the following. // 'work.error.work_not_available' => 'Work item is not available.', // 'work.error.offer_not_available' => 'Offer is not available.', +// 'work.type.one_time' => 'one time', // Work type is "one time job" for well defined work ("do exactly this"). +// 'work.type.ongoing' => 'ongoing', // Work type is "ongoing" for complex jobs (billed by the hour, multiple contractors, etc.) // 'work.label.our_work' => 'Our work', // 'work.label.our_offers' => 'Our offers', // 'work.label.offers' => 'Offers', diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index d04dbad7a..46407620a 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -713,6 +713,8 @@ // TODO: translate the following. // 'work.error.work_not_available' => 'Work item is not available.', // 'work.error.offer_not_available' => 'Offer is not available.', +// 'work.type.one_time' => 'one time', // Work type is "one time job" for well defined work ("do exactly this"). +// 'work.type.ongoing' => 'ongoing', // Work type is "ongoing" for complex jobs (billed by the hour, multiple contractors, etc.) // 'work.label.our_work' => 'Our work', // 'work.label.our_offers' => 'Our offers', // 'work.label.offers' => 'Offers', diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index 337f867dd..918ebec4d 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -691,6 +691,8 @@ // TODO: translate the following. // 'work.error.work_not_available' => 'Work item is not available.', // 'work.error.offer_not_available' => 'Offer is not available.', +// 'work.type.one_time' => 'one time', // Work type is "one time job" for well defined work ("do exactly this"). +// 'work.type.ongoing' => 'ongoing', // Work type is "ongoing" for complex jobs (billed by the hour, multiple contractors, etc.) // 'work.label.our_work' => 'Our work', // 'work.label.our_offers' => 'Our offers', // 'work.label.offers' => 'Offers', diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index adda37da4..f68014942 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -686,6 +686,8 @@ // TODO: translate the following. // 'work.error.work_not_available' => 'Work item is not available.', // 'work.error.offer_not_available' => 'Offer is not available.', +// 'work.type.one_time' => 'one time', // Work type is "one time job" for well defined work ("do exactly this"). +// 'work.type.ongoing' => 'ongoing', // Work type is "ongoing" for complex jobs (billed by the hour, multiple contractors, etc.) // 'work.label.our_work' => 'Our work', // 'work.label.our_offers' => 'Our offers', // 'work.label.offers' => 'Offers', diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index 36ace36d9..c1276e8ff 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -695,6 +695,8 @@ // TODO: translate the following. // 'work.error.work_not_available' => 'Work item is not available.', // 'work.error.offer_not_available' => 'Offer is not available.', +// 'work.type.one_time' => 'one time', // Work type is "one time job" for well defined work ("do exactly this"). +// 'work.type.ongoing' => 'ongoing', // Work type is "ongoing" for complex jobs (billed by the hour, multiple contractors, etc.) // 'work.label.our_work' => 'Our work', // 'work.label.our_offers' => 'Our offers', // 'work.label.offers' => 'Offers', diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index 3b0c588b0..a59fbcf23 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -716,6 +716,8 @@ // TODO: translate the following. // 'work.error.work_not_available' => 'Work item is not available.', // 'work.error.offer_not_available' => 'Offer is not available.', +// 'work.type.one_time' => 'one time', // Work type is "one time job" for well defined work ("do exactly this"). +// 'work.type.ongoing' => 'ongoing', // Work type is "ongoing" for complex jobs (billed by the hour, multiple contractors, etc.) // 'work.label.our_work' => 'Our work', // 'work.label.our_offers' => 'Our offers', // 'work.label.offers' => 'Offers', diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index 6a7359f83..de88cb6e5 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -619,6 +619,8 @@ // Work plugin strings. See example at https://timetracker.anuko.com/work.php 'work.error.work_not_available' => 'Работа отсутствует.', 'work.error.offer_not_available' => 'Предложение отсутствует.', +'work.type.one_time' => 'одноразовая', +'work.type.ongoing' => 'постоянная', 'work.label.our_work' => 'Наша работа', 'work.label.our_offers' => 'Наши предложения', 'work.label.offers' => 'Предложения', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index 113beb835..83246514b 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -697,6 +697,8 @@ // TODO: translate the following. // 'work.error.work_not_available' => 'Work item is not available.', // 'work.error.offer_not_available' => 'Offer is not available.', +// 'work.type.one_time' => 'one time', // Work type is "one time job" for well defined work ("do exactly this"). +// 'work.type.ongoing' => 'ongoing', // Work type is "ongoing" for complex jobs (billed by the hour, multiple contractors, etc.) // 'work.label.our_work' => 'Our work', // 'work.label.our_offers' => 'Our offers', // 'work.label.offers' => 'Offers', diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index 60ed86cd2..1f99fca52 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -689,6 +689,8 @@ // TODO: translate the following. // 'work.error.work_not_available' => 'Work item is not available.', // 'work.error.offer_not_available' => 'Offer is not available.', +// 'work.type.one_time' => 'one time', // Work type is "one time job" for well defined work ("do exactly this"). +// 'work.type.ongoing' => 'ongoing', // Work type is "ongoing" for complex jobs (billed by the hour, multiple contractors, etc.) // 'work.label.our_work' => 'Our work', // 'work.label.our_offers' => 'Our offers', // 'work.label.offers' => 'Offers', diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index 8c559955d..cbd369c3b 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -689,6 +689,8 @@ // TODO: translate the following. // 'work.error.work_not_available' => 'Work item is not available.', // 'work.error.offer_not_available' => 'Offer is not available.', +// 'work.type.one_time' => 'one time', // Work type is "one time job" for well defined work ("do exactly this"). +// 'work.type.ongoing' => 'ongoing', // Work type is "ongoing" for complex jobs (billed by the hour, multiple contractors, etc.) // 'work.label.our_work' => 'Our work', // 'work.label.our_offers' => 'Our offers', // 'work.label.offers' => 'Offers', diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index a1b6f719c..bdaa99bb2 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -687,6 +687,8 @@ // TODO: translate the following. // 'work.error.work_not_available' => 'Work item is not available.', // 'work.error.offer_not_available' => 'Offer is not available.', +// 'work.type.one_time' => 'one time', // Work type is "one time job" for well defined work ("do exactly this"). +// 'work.type.ongoing' => 'ongoing', // Work type is "ongoing" for complex jobs (billed by the hour, multiple contractors, etc.) // 'work.label.our_work' => 'Our work', // 'work.label.our_offers' => 'Our offers', // 'work.label.offers' => 'Offers', diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index 8adc4f5d1..aad1932d0 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -729,6 +729,8 @@ // TODO: translate the following. // 'work.error.work_not_available' => 'Work item is not available.', // 'work.error.offer_not_available' => 'Offer is not available.', +// 'work.type.one_time' => 'one time', // Work type is "one time job" for well defined work ("do exactly this"). +// 'work.type.ongoing' => 'ongoing', // Work type is "ongoing" for complex jobs (billed by the hour, multiple contractors, etc.) // 'work.label.our_work' => 'Our work', // 'work.label.our_offers' => 'Our offers', // 'work.label.offers' => 'Offers', diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index 7c2f697eb..0ed2f282f 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -700,6 +700,8 @@ // TODO: translate the following. // 'work.error.work_not_available' => 'Work item is not available.', // 'work.error.offer_not_available' => 'Offer is not available.', +// 'work.type.one_time' => 'one time', // Work type is "one time job" for well defined work ("do exactly this"). +// 'work.type.ongoing' => 'ongoing', // Work type is "ongoing" for complex jobs (billed by the hour, multiple contractors, etc.) // 'work.label.our_work' => 'Our work', // 'work.label.our_offers' => 'Our offers', // 'work.label.offers' => 'Offers', diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index deada9f15..42ac20e95 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -706,6 +706,8 @@ // TODO: translate the following. // 'work.error.work_not_available' => 'Work item is not available.', // 'work.error.offer_not_available' => 'Offer is not available.', +// 'work.type.one_time' => 'one time', // Work type is "one time job" for well defined work ("do exactly this"). +// 'work.type.ongoing' => 'ongoing', // Work type is "ongoing" for complex jobs (billed by the hour, multiple contractors, etc.) // 'work.label.our_work' => 'Our work', // 'work.label.our_offers' => 'Our offers', // 'work.label.offers' => 'Offers', diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 5ee395b41..b2d1ad569 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
{$i18n.work.label.our_offers}
{$offer.subject|escape}
- diff --git a/work_offer_view.php b/work_offer_view.php index d14084457..84fdc1cd0 100644 --- a/work_offer_view.php +++ b/work_offer_view.php @@ -80,15 +80,15 @@ $form->getElement('budget')->setEnabled(false); $form->addInput(array('type'=>'text','name'=>'status','style'=>'width: 400px;','value'=>$cl_status)); $form->getElement('status')->setEnabled(false); -$form->addInput(array('type'=>'textarea','name'=>'client_comment','style'=>'width: 400px; height: 80px;','value'=>$cl_client_comment)); if ($offer['status'] == STATUS_APPROVED) { $form->addInput(array('type'=>'submit','name'=>'btn_accept','value'=>$i18n->get('work.button.accept'))); $form->addInput(array('type'=>'submit','name'=>'btn_decline','value'=>$i18n->get('work.button.decline'))); } +$form->addInput(array('type'=>'textarea','name'=>'client_comment','style'=>'width: 400px; height: 80px;','value'=>$cl_client_comment)); if ($request->isPost()) { // Validate user input. - if (!ttValidString($cl_client_comment)) $err->add($i18n->get('error.field'), $i18n->get('label.comment')); + if (!ttValidString($cl_client_comment, true)) $err->add($i18n->get('error.field'), $i18n->get('label.comment')); // Ensure user email exists (required for workflow). if (!$user->getEmail()) $err->add($i18n->get('error.no_email')); From 275d3424b2258f1aa24805efb10d2612ff771388 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 15 Oct 2019 16:28:12 +0000 Subject: [PATCH 157/877] Added work_view_own.php to allow viewing details of non-editable own work items. --- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/work.tpl | 2 +- WEB-INF/templates/work_view_own.tpl | 26 +++++++++++ work_view_own.php | 69 +++++++++++++++++++++++++++++ 4 files changed, 97 insertions(+), 2 deletions(-) create mode 100644 WEB-INF/templates/work_view_own.tpl create mode 100644 work_view_own.php diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 5e47b2060..7e8a39eff 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.19.12.5151 | Copyright © Anuko | +  Anuko Time Tracker 1.19.12.5152 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 4106b7c65a8f669472b60bd027fe1cdfba52a8b5 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 13 Oct 2019 17:02:23 +0000 Subject: [PATCH 154/877] Forgot to check in a couple of files. --- WEB-INF/resources/ca.lang.php | 2 ++ WEB-INF/resources/en.lang.php | 2 ++ 2 files changed, 4 insertions(+) diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index 679013a76..0244845a2 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -708,6 +708,8 @@ // TODO: translate the following. // 'work.error.work_not_available' => 'Work item is not available.', // 'work.error.offer_not_available' => 'Offer is not available.', +// 'work.type.one_time' => 'one time', // Work type is "one time job" for well defined work ("do exactly this"). +// 'work.type.ongoing' => 'ongoing', // Work type is "ongoing" for complex jobs (billed by the hour, multiple contractors, etc.) // 'work.label.our_work' => 'Our work', // 'work.label.our_offers' => 'Our offers', // 'work.label.offers' => 'Offers', diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index 08b35fe6e..5bc5821e6 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -638,6 +638,8 @@ // Work plugin strings. See example at https://timetracker.anuko.com/work.php 'work.error.work_not_available' => 'Work item is not available.', 'work.error.offer_not_available' => 'Offer is not available.', +'work.type.one_time' => 'one time', // Work type is "one time job" for well defined work ("do exactly this"). +'work.type.ongoing' => 'ongoing', // Work type is "ongoing" for complex jobs (billed by the hour, multiple contractors, etc.) 'work.label.our_work' => 'Our work', 'work.label.our_offers' => 'Our offers', 'work.label.offers' => 'Offers', From 437d580892d7b3dabd651db45b94d23675ef6df5 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 13 Oct 2019 18:41:15 +0000 Subject: [PATCH 155/877] Added work type control on work_add.php anf work_edit.php. --- WEB-INF/lib/ttWorkHelper.class.php | 2 ++ WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/work_add.tpl | 4 ++++ WEB-INF/templates/work_edit.tpl | 4 ++++ work_add.php | 11 +++++------ work_edit.php | 5 +++++ 6 files changed, 21 insertions(+), 7 deletions(-) diff --git a/WEB-INF/lib/ttWorkHelper.class.php b/WEB-INF/lib/ttWorkHelper.class.php index 2f1deb40a..77037711d 100644 --- a/WEB-INF/lib/ttWorkHelper.class.php +++ b/WEB-INF/lib/ttWorkHelper.class.php @@ -200,6 +200,7 @@ function putOwnWorkItem($fields) { 'group_id' => urlencode($group_id), 'group_name' => urlencode(base64_encode($user->getGroupName())), 'group_key' => urlencode($user->getGroupKey()), + 'type' => urlencode($fields['type']), 'subject' => urlencode(base64_encode($fields['subject'])), 'descr_short' => urlencode(base64_encode($fields['descr_short'])), 'descr_long' => urlencode(base64_encode($fields['descr_long'])), @@ -269,6 +270,7 @@ function updateOwnWorkItem($fields) { 'group_name' => urlencode(base64_encode($user->getGroupName())), 'group_key' => urlencode($user->getGroupKey()), 'work_id' => urlencode($fields['work_id']), + 'type' => urlencode($fields['type']), 'subject' => urlencode(base64_encode($fields['subject'])), 'descr_short' => urlencode(base64_encode($fields['descr_short'])), 'descr_long' => urlencode(base64_encode($fields['descr_long'])), diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index b2d1ad569..488a620af 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- + + + + diff --git a/WEB-INF/templates/work_edit.tpl b/WEB-INF/templates/work_edit.tpl index 48e4456fb..96959b189 100644 --- a/WEB-INF/templates/work_edit.tpl +++ b/WEB-INF/templates/work_edit.tpl @@ -7,6 +7,10 @@ + + + + diff --git a/work_add.php b/work_add.php index 4e7ba1ba3..f12aef8f5 100644 --- a/work_add.php +++ b/work_add.php @@ -42,6 +42,7 @@ // End of access checks. if ($request->isPost()) { + $cl_work_type = $request->getParameter('work_type'); $cl_name = trim($request->getParameter('work_name')); $cl_description = trim($request->getParameter('description')); $cl_details = trim($request->getParameter('details')); @@ -51,6 +52,8 @@ $form = new Form('workForm'); $form->addInput(array('type'=>'text','name'=>'work_name','maxlength'=>'128','style'=>'width: 400px;','value'=>$cl_name)); +$WORK_TYPE_OPTIONS = array('0'=>$i18n->get('work.type.one_time'),'1'=>$i18n->get('work.type.ongoing')); +$form->addInput(array('type'=>'combobox','name'=>'work_type','data'=>$WORK_TYPE_OPTIONS,'value'=>$cl_work_type)); $form->addInput(array('type'=>'textarea','name'=>'description','maxlength'=>'512','style'=>'width: 400px; height: 80px;','value'=>$cl_description)); $form->addInput(array('type'=>'textarea','name'=>'details','style'=>'width: 400px; height: 200px;','value'=>$cl_details)); // Add a dropdown for currency. @@ -59,11 +62,6 @@ $form->addInput(array('type'=>'floatfield','maxlength'=>'10','name'=>'budget','format'=>'.2','value'=>$cl_budget)); $form->addInput(array('type'=>'submit','name'=>'btn_add','value'=>$i18n->get('button.add'))); -// TODO: design how to handle one-time vs ongoing work. Apparently, with a conditional display of relevant controls. -// Ongoing work - rate per hour control. -// One-time work - budget dropdown control. -// When selection changes, we hide and show required controls. - // TODO: design how to handle categories and sub-categories. // One major complication is localization of names. @@ -79,7 +77,8 @@ if ($err->no()) { $workHelper = new ttWorkHelper($err); - $fields = array('subject'=>$cl_name, + $fields = array('type'=>$cl_work_type, + 'subject'=>$cl_name, 'descr_short' => $cl_description, 'descr_long' => $cl_details, 'currency' => ttWorkHelper::getCurrencyName($cl_currency_id), diff --git a/work_edit.php b/work_edit.php index dffe185c7..e99ca9dcf 100644 --- a/work_edit.php +++ b/work_edit.php @@ -52,12 +52,14 @@ if ($request->isPost()) { $cl_name = trim($request->getParameter('work_name')); + $cl_work_type = $request->getParameter('work_type'); $cl_description = trim($request->getParameter('description')); $cl_details = trim($request->getParameter('details')); $cl_currency_id = $request->getParameter('currency'); $cl_budget = $request->getParameter('budget'); } else { $cl_name = $work_item['subject']; + $cl_work_type = $work_item['type']; $cl_description = $work_item['descr_short']; $cl_details = $work_item['descr_long']; $cl_currency_id = ttWorkHelper::getCurrencyID($work_item['currency']); @@ -71,6 +73,8 @@ $form = new Form('workForm'); $form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_work_id)); $form->addInput(array('type'=>'text','name'=>'work_name','maxlength'=>'128','style'=>'width: 400px;','value'=>$cl_name)); +$WORK_TYPE_OPTIONS = array('0'=>$i18n->get('work.type.one_time'),'1'=>$i18n->get('work.type.ongoing')); +$form->addInput(array('type'=>'combobox','name'=>'work_type','data'=>$WORK_TYPE_OPTIONS,'value'=>$cl_work_type)); $form->addInput(array('type'=>'textarea','name'=>'description','maxlength'=>'512','style'=>'width: 400px; height: 80px;','value'=>$cl_description)); $form->addInput(array('type'=>'textarea','name'=>'details','style'=>'width: 400px; height: 200px;','value'=>$cl_details)); $form->addInput(array('type'=>'combobox','name'=>'currency','data'=>$currencies,'datakeys'=>array('id','name'),'value'=>$cl_currency_id)); @@ -95,6 +99,7 @@ if ($request->getParameter('btn_save')) { // Update work information. $fields = array('work_id'=>$cl_work_id, + 'type'=>$cl_work_type, 'subject'=>$cl_name, 'descr_short' => $cl_description, 'descr_long' => $cl_details, From aec8154c1023fb37d413c164724fd46398c05186 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 15 Oct 2019 15:25:41 +0000 Subject: [PATCH 156/877] Made client comment optional when accepting or declining offers. --- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/work_offer_view.tpl | 13 ++++++++----- work_offer_view.php | 4 ++-- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 488a620af..5e47b2060 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.19.12.5152 | Copyright © Anuko | +  Anuko Time Tracker 1.19.12.5153 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/work_add.tpl b/WEB-INF/templates/work_add.tpl index fd7beea40..15b430b59 100644 --- a/WEB-INF/templates/work_add.tpl +++ b/WEB-INF/templates/work_add.tpl @@ -7,6 +7,10 @@ {$i18n.label.work} (*): {$forms.workForm.work_name.control}
{$i18n.label.type}:{$forms.workForm.work_type.control}
{$i18n.label.description}: {$forms.workForm.description.control}{$i18n.label.work} (*): {$forms.workForm.work_name.control}
{$i18n.label.type}:{$forms.workForm.work_type.control}
{$i18n.label.description}: {$forms.workForm.description.control}
- +{if isTrue('WORK_DEBUG')} + - - + + -{if isTrue('WORK_DEBUG')} - -{/if} + + + +{/if}
 Anuko Time Tracker 1.19.12.5153 | Copyright © Anuko | +  Anuko Time Tracker 1.19.12.5154 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/work_offer_view.tpl b/WEB-INF/templates/work_offer_view.tpl index 0dfa4158c..00af0aafc 100644 --- a/WEB-INF/templates/work_offer_view.tpl +++ b/WEB-INF/templates/work_offer_view.tpl @@ -45,14 +45,17 @@ {$i18n.label.status}: {$forms.offerForm.status.control}
 
{$i18n.label.comment} (*):{$forms.offerForm.client_comment.control}{$forms.offerForm.btn_accept.control} {$forms.offerForm.btn_decline.control}
{$forms.offerForm.btn_accept.control} {$forms.offerForm.btn_decline.control}
{$i18n.label.comment}:{$forms.offerForm.client_comment.control}
- {foreach $own_work_items as $work_item} - + diff --git a/WEB-INF/templates/work_view_own.tpl b/WEB-INF/templates/work_view_own.tpl new file mode 100644 index 000000000..51e825929 --- /dev/null +++ b/WEB-INF/templates/work_view_own.tpl @@ -0,0 +1,26 @@ +{$forms.workForm.open} +
 Anuko Time Tracker 1.19.12.5154 | Copyright © Anuko | +  Anuko Time Tracker 1.19.12.5155 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/work.tpl b/WEB-INF/templates/work.tpl index dcfb2945a..2e7f5ef79 100644 --- a/WEB-INF/templates/work.tpl +++ b/WEB-INF/templates/work.tpl @@ -19,7 +19,7 @@
{$work_item.subject|escape}{$work_item.subject|escape} {$work_item.description|escape} {$work_item.status_label} {if $work_item.num_offers}{$work_item.num_offers}{/if}
+ + + +
+ + + + + + + + + + + + + + + + + +
{$i18n.label.work}:{$forms.workForm.work_name.control}
{$i18n.label.description}:{$forms.workForm.description.control}
{$i18n.label.details}:{$forms.workForm.details.control}
{$i18n.label.budget}:{$forms.workForm.budget.control}
+
+{$forms.workForm.close} diff --git a/work_view_own.php b/work_view_own.php new file mode 100644 index 000000000..19a809b31 --- /dev/null +++ b/work_view_own.php @@ -0,0 +1,69 @@ +isPluginEnabled('wk')) { + header('Location: feature_disabled.php'); + exit(); +} +if (!ttAccessAllowed('manage_work')) { + header('Location: access_denied.php'); + exit(); +} +$work_id = (int)$request->getParameter('id'); +$workHelper = new ttWorkHelper($err); +$work_item = $workHelper->getOwnWorkItem($work_id); +if (!$work_item) { + header('Location: access_denied.php'); + exit(); +} +// End of access checks. + +$cl_name = $work_item['subject']; +$cl_description = $work_item['descr_short']; +$cl_details = $work_item['descr_long']; +$cl_budget = $work_item['amount_with_currency']; + +$form = new Form('workForm'); +$form->addInput(array('type'=>'textarea','name'=>'work_name','style'=>'width: 400px;','value'=>$cl_name)); +$form->getElement('work_name')->setEnabled(false); +$form->addInput(array('type'=>'textarea','name'=>'description','style'=>'width: 400px; height: 80px;','value'=>$cl_description)); +$form->getElement('description')->setEnabled(false); +$form->addInput(array('type'=>'textarea','name'=>'details','style'=>'width: 400px; height: 200px;','value'=>$cl_details)); +$form->getElement('details')->setEnabled(false); +$form->addInput(array('type'=>'text','name'=>'budget','value'=>$cl_budget)); +$form->getElement('budget')->setEnabled(false); + +$smarty->assign('forms', array($form->getName()=>$form->toArray())); +$smarty->assign('title', $i18n->get('title.work')); +$smarty->assign('content_page_name', 'work_view_own.tpl'); +$smarty->display('index.tpl'); From be2f528937bcbebd7714cdd03bc00e53cb95ee71 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 15 Oct 2019 16:33:40 +0000 Subject: [PATCH 158/877] Some renaming. --- WEB-INF/resources/ca.lang.php | 4 ++-- WEB-INF/resources/cs.lang.php | 4 ++-- WEB-INF/resources/da.lang.php | 4 ++-- WEB-INF/resources/de.lang.php | 4 ++-- WEB-INF/resources/en.lang.php | 4 ++-- WEB-INF/resources/es.lang.php | 4 ++-- WEB-INF/resources/et.lang.php | 4 ++-- WEB-INF/resources/fa.lang.php | 4 ++-- WEB-INF/resources/fi.lang.php | 4 ++-- WEB-INF/resources/fr.lang.php | 4 ++-- WEB-INF/resources/gr.lang.php | 4 ++-- WEB-INF/resources/he.lang.php | 4 ++-- WEB-INF/resources/hu.lang.php | 4 ++-- WEB-INF/resources/it.lang.php | 4 ++-- WEB-INF/resources/ja.lang.php | 4 ++-- WEB-INF/resources/ko.lang.php | 4 ++-- WEB-INF/resources/nl.lang.php | 4 ++-- WEB-INF/resources/no.lang.php | 4 ++-- WEB-INF/resources/pl.lang.php | 4 ++-- WEB-INF/resources/pt-br.lang.php | 4 ++-- WEB-INF/resources/pt.lang.php | 4 ++-- WEB-INF/resources/ro.lang.php | 4 ++-- WEB-INF/resources/ru.lang.php | 6 +++--- WEB-INF/resources/sk.lang.php | 4 ++-- WEB-INF/resources/sl.lang.php | 4 ++-- WEB-INF/resources/sr.lang.php | 4 ++-- WEB-INF/resources/sv.lang.php | 4 ++-- WEB-INF/resources/tr.lang.php | 4 ++-- WEB-INF/resources/zh-cn.lang.php | 4 ++-- WEB-INF/resources/zh-tw.lang.php | 4 ++-- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/work.tpl | 4 ++-- 32 files changed, 64 insertions(+), 64 deletions(-) diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index 0244845a2..cb0de346a 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -710,8 +710,8 @@ // 'work.error.offer_not_available' => 'Offer is not available.', // 'work.type.one_time' => 'one time', // Work type is "one time job" for well defined work ("do exactly this"). // 'work.type.ongoing' => 'ongoing', // Work type is "ongoing" for complex jobs (billed by the hour, multiple contractors, etc.) -// 'work.label.our_work' => 'Our work', -// 'work.label.our_offers' => 'Our offers', +// 'work.label.own_work' => 'Own work', +// 'work.label.own_offers' => 'Own offers', // 'work.label.offers' => 'Offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index a1803742f..8a7c3c7bd 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -723,8 +723,8 @@ // 'work.error.offer_not_available' => 'Offer is not available.', // 'work.type.one_time' => 'one time', // Work type is "one time job" for well defined work ("do exactly this"). // 'work.type.ongoing' => 'ongoing', // Work type is "ongoing" for complex jobs (billed by the hour, multiple contractors, etc.) -// 'work.label.our_work' => 'Our work', -// 'work.label.our_offers' => 'Our offers', +// 'work.label.own_work' => 'Own work', +// 'work.label.own_offers' => 'Own offers', // 'work.label.offers' => 'Offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index fd692dabb..161ef01d5 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -684,8 +684,8 @@ // 'work.error.offer_not_available' => 'Offer is not available.', // 'work.type.one_time' => 'one time', // Work type is "one time job" for well defined work ("do exactly this"). // 'work.type.ongoing' => 'ongoing', // Work type is "ongoing" for complex jobs (billed by the hour, multiple contractors, etc.) -// 'work.label.our_work' => 'Our work', -// 'work.label.our_offers' => 'Our offers', +// 'work.label.own_work' => 'Own work', +// 'work.label.own_offers' => 'Own offers', // 'work.label.offers' => 'Offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index 691a73187..f29576f27 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -660,8 +660,8 @@ // 'work.error.offer_not_available' => 'Offer is not available.', // 'work.type.one_time' => 'one time', // Work type is "one time job" for well defined work ("do exactly this"). // 'work.type.ongoing' => 'ongoing', // Work type is "ongoing" for complex jobs (billed by the hour, multiple contractors, etc.) -// 'work.label.our_work' => 'Our work', -// 'work.label.our_offers' => 'Our offers', +// 'work.label.own_work' => 'Own work', +// 'work.label.own_offers' => 'Own offers', // 'work.label.offers' => 'Offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index 5bc5821e6..9d9788f23 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -640,8 +640,8 @@ 'work.error.offer_not_available' => 'Offer is not available.', 'work.type.one_time' => 'one time', // Work type is "one time job" for well defined work ("do exactly this"). 'work.type.ongoing' => 'ongoing', // Work type is "ongoing" for complex jobs (billed by the hour, multiple contractors, etc.) -'work.label.our_work' => 'Our work', -'work.label.our_offers' => 'Our offers', +'work.label.own_work' => 'Own work', +'work.label.own_offers' => 'Own offers', 'work.label.offers' => 'Offers', 'work.button.send_message' => 'Send message', 'work.button.make_offer' => 'Make offer', diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index edbc5bc12..0622e8d12 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -725,8 +725,8 @@ // 'work.error.offer_not_available' => 'Offer is not available.', // 'work.type.one_time' => 'one time', // Work type is "one time job" for well defined work ("do exactly this"). // 'work.type.ongoing' => 'ongoing', // Work type is "ongoing" for complex jobs (billed by the hour, multiple contractors, etc.) -// 'work.label.our_work' => 'Our work', -// 'work.label.our_offers' => 'Our offers', +// 'work.label.own_work' => 'Own work', +// 'work.label.own_offers' => 'Own offers', // 'work.label.offers' => 'Offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index 4cc562843..bf358d4c2 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -691,8 +691,8 @@ // 'work.error.offer_not_available' => 'Offer is not available.', // 'work.type.one_time' => 'one time', // Work type is "one time job" for well defined work ("do exactly this"). // 'work.type.ongoing' => 'ongoing', // Work type is "ongoing" for complex jobs (billed by the hour, multiple contractors, etc.) -// 'work.label.our_work' => 'Our work', -// 'work.label.our_offers' => 'Our offers', +// 'work.label.own_work' => 'Own work', +// 'work.label.own_offers' => 'Own offers', // 'work.label.offers' => 'Offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index 5643669bf..80b1781e0 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -708,8 +708,8 @@ // 'work.error.offer_not_available' => 'Offer is not available.', // 'work.type.one_time' => 'one time', // Work type is "one time job" for well defined work ("do exactly this"). // 'work.type.ongoing' => 'ongoing', // Work type is "ongoing" for complex jobs (billed by the hour, multiple contractors, etc.) -// 'work.label.our_work' => 'Our work', -// 'work.label.our_offers' => 'Our offers', +// 'work.label.own_work' => 'Own work', +// 'work.label.own_offers' => 'Own offers', // 'work.label.offers' => 'Offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 05de8ed92..4e4864ff8 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -690,8 +690,8 @@ // 'work.error.offer_not_available' => 'Offer is not available.', // 'work.type.one_time' => 'one time', // Work type is "one time job" for well defined work ("do exactly this"). // 'work.type.ongoing' => 'ongoing', // Work type is "ongoing" for complex jobs (billed by the hour, multiple contractors, etc.) -// 'work.label.our_work' => 'Our work', -// 'work.label.our_offers' => 'Our offers', +// 'work.label.own_work' => 'Own work', +// 'work.label.own_offers' => 'Own offers', // 'work.label.offers' => 'Offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index b66100bb9..417c3093a 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -680,8 +680,8 @@ // 'work.error.offer_not_available' => 'Offer is not available.', // 'work.type.one_time' => 'one time', // Work type is "one time job" for well defined work ("do exactly this"). // 'work.type.ongoing' => 'ongoing', // Work type is "ongoing" for complex jobs (billed by the hour, multiple contractors, etc.) -// 'work.label.our_work' => 'Our work', -// 'work.label.our_offers' => 'Our offers', +// 'work.label.own_work' => 'Own work', +// 'work.label.own_offers' => 'Own offers', // 'work.label.offers' => 'Offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index fa549557c..56b6c8a42 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -673,8 +673,8 @@ // 'work.error.offer_not_available' => 'Offer is not available.', // 'work.type.one_time' => 'one time', // Work type is "one time job" for well defined work ("do exactly this"). // 'work.type.ongoing' => 'ongoing', // Work type is "ongoing" for complex jobs (billed by the hour, multiple contractors, etc.) -// 'work.label.our_work' => 'Our work', -// 'work.label.our_offers' => 'Our offers', +// 'work.label.own_work' => 'Own work', +// 'work.label.own_offers' => 'Own offers', // 'work.label.offers' => 'Offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index 3841cbf1c..79ad5059e 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -710,8 +710,8 @@ // 'work.error.offer_not_available' => 'Offer is not available.', // 'work.type.one_time' => 'one time', // Work type is "one time job" for well defined work ("do exactly this"). // 'work.type.ongoing' => 'ongoing', // Work type is "ongoing" for complex jobs (billed by the hour, multiple contractors, etc.) -// 'work.label.our_work' => 'Our work', -// 'work.label.our_offers' => 'Our offers', +// 'work.label.own_work' => 'Own work', +// 'work.label.own_offers' => 'Own offers', // 'work.label.offers' => 'Offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index 16a996544..529a73968 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -715,8 +715,8 @@ // 'work.error.offer_not_available' => 'Offer is not available.', // 'work.type.one_time' => 'one time', // Work type is "one time job" for well defined work ("do exactly this"). // 'work.type.ongoing' => 'ongoing', // Work type is "ongoing" for complex jobs (billed by the hour, multiple contractors, etc.) -// 'work.label.our_work' => 'Our work', -// 'work.label.our_offers' => 'Our offers', +// 'work.label.own_work' => 'Own work', +// 'work.label.own_offers' => 'Own offers', // 'work.label.offers' => 'Offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index 17316bb71..f07c9a00d 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -687,8 +687,8 @@ // 'work.error.offer_not_available' => 'Offer is not available.', // 'work.type.one_time' => 'one time', // Work type is "one time job" for well defined work ("do exactly this"). // 'work.type.ongoing' => 'ongoing', // Work type is "ongoing" for complex jobs (billed by the hour, multiple contractors, etc.) -// 'work.label.our_work' => 'Our work', -// 'work.label.our_offers' => 'Our offers', +// 'work.label.own_work' => 'Own work', +// 'work.label.own_offers' => 'Own offers', // 'work.label.offers' => 'Offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index a7dde05cd..86e860d66 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -718,8 +718,8 @@ // 'work.error.offer_not_available' => 'Offer is not available.', // 'work.type.one_time' => 'one time', // Work type is "one time job" for well defined work ("do exactly this"). // 'work.type.ongoing' => 'ongoing', // Work type is "ongoing" for complex jobs (billed by the hour, multiple contractors, etc.) -// 'work.label.our_work' => 'Our work', -// 'work.label.our_offers' => 'Our offers', +// 'work.label.own_work' => 'Own work', +// 'work.label.own_offers' => 'Own offers', // 'work.label.offers' => 'Offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index 6e4898705..2276102a4 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -716,8 +716,8 @@ // 'work.error.offer_not_available' => 'Offer is not available.', // 'work.type.one_time' => 'one time', // Work type is "one time job" for well defined work ("do exactly this"). // 'work.type.ongoing' => 'ongoing', // Work type is "ongoing" for complex jobs (billed by the hour, multiple contractors, etc.) -// 'work.label.our_work' => 'Our work', -// 'work.label.our_offers' => 'Our offers', +// 'work.label.own_work' => 'Own work', +// 'work.label.own_offers' => 'Own offers', // 'work.label.offers' => 'Offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 182a5e41d..44f1dc5b9 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -642,8 +642,8 @@ // 'work.error.offer_not_available' => 'Offer is not available.', // 'work.type.one_time' => 'one time', // Work type is "one time job" for well defined work ("do exactly this"). // 'work.type.ongoing' => 'ongoing', // Work type is "ongoing" for complex jobs (billed by the hour, multiple contractors, etc.) -// 'work.label.our_work' => 'Our work', -// 'work.label.our_offers' => 'Our offers', +// 'work.label.own_work' => 'Own work', +// 'work.label.own_offers' => 'Own offers', // 'work.label.offers' => 'Offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index 46407620a..5feaab8f8 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -715,8 +715,8 @@ // 'work.error.offer_not_available' => 'Offer is not available.', // 'work.type.one_time' => 'one time', // Work type is "one time job" for well defined work ("do exactly this"). // 'work.type.ongoing' => 'ongoing', // Work type is "ongoing" for complex jobs (billed by the hour, multiple contractors, etc.) -// 'work.label.our_work' => 'Our work', -// 'work.label.our_offers' => 'Our offers', +// 'work.label.own_work' => 'Own work', +// 'work.label.own_offers' => 'Own offers', // 'work.label.offers' => 'Offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index 918ebec4d..b6a5fe62b 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -693,8 +693,8 @@ // 'work.error.offer_not_available' => 'Offer is not available.', // 'work.type.one_time' => 'one time', // Work type is "one time job" for well defined work ("do exactly this"). // 'work.type.ongoing' => 'ongoing', // Work type is "ongoing" for complex jobs (billed by the hour, multiple contractors, etc.) -// 'work.label.our_work' => 'Our work', -// 'work.label.our_offers' => 'Our offers', +// 'work.label.own_work' => 'Own work', +// 'work.label.own_offers' => 'Own offers', // 'work.label.offers' => 'Offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index f68014942..b6123d0c2 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -688,8 +688,8 @@ // 'work.error.offer_not_available' => 'Offer is not available.', // 'work.type.one_time' => 'one time', // Work type is "one time job" for well defined work ("do exactly this"). // 'work.type.ongoing' => 'ongoing', // Work type is "ongoing" for complex jobs (billed by the hour, multiple contractors, etc.) -// 'work.label.our_work' => 'Our work', -// 'work.label.our_offers' => 'Our offers', +// 'work.label.own_work' => 'Own work', +// 'work.label.own_offers' => 'Own offers', // 'work.label.offers' => 'Offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index c1276e8ff..c2711ab07 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -697,8 +697,8 @@ // 'work.error.offer_not_available' => 'Offer is not available.', // 'work.type.one_time' => 'one time', // Work type is "one time job" for well defined work ("do exactly this"). // 'work.type.ongoing' => 'ongoing', // Work type is "ongoing" for complex jobs (billed by the hour, multiple contractors, etc.) -// 'work.label.our_work' => 'Our work', -// 'work.label.our_offers' => 'Our offers', +// 'work.label.own_work' => 'Own work', +// 'work.label.own_offers' => 'Own offers', // 'work.label.offers' => 'Offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index a59fbcf23..f4f231939 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -718,8 +718,8 @@ // 'work.error.offer_not_available' => 'Offer is not available.', // 'work.type.one_time' => 'one time', // Work type is "one time job" for well defined work ("do exactly this"). // 'work.type.ongoing' => 'ongoing', // Work type is "ongoing" for complex jobs (billed by the hour, multiple contractors, etc.) -// 'work.label.our_work' => 'Our work', -// 'work.label.our_offers' => 'Our offers', +// 'work.label.own_work' => 'Own work', +// 'work.label.own_offers' => 'Own offers', // 'work.label.offers' => 'Offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index de88cb6e5..84562d7cd 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -621,9 +621,9 @@ 'work.error.offer_not_available' => 'Предложение отсутствует.', 'work.type.one_time' => 'одноразовая', 'work.type.ongoing' => 'постоянная', -'work.label.our_work' => 'Наша работа', -'work.label.our_offers' => 'Наши предложения', - 'work.label.offers' => 'Предложения', +'work.label.own_work' => 'Своя работа', +'work.label.own_offers' => 'Свои предложения', +'work.label.offers' => 'Предложения', 'work.button.send_message' => 'Отправить сообщение', 'work.button.make_offer' => 'Сделать предложение', 'work.button.accept' => 'Принять', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index 83246514b..1991075d0 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -699,8 +699,8 @@ // 'work.error.offer_not_available' => 'Offer is not available.', // 'work.type.one_time' => 'one time', // Work type is "one time job" for well defined work ("do exactly this"). // 'work.type.ongoing' => 'ongoing', // Work type is "ongoing" for complex jobs (billed by the hour, multiple contractors, etc.) -// 'work.label.our_work' => 'Our work', -// 'work.label.our_offers' => 'Our offers', +// 'work.label.own_work' => 'Own work', +// 'work.label.own_offers' => 'Own offers', // 'work.label.offers' => 'Offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index 1f99fca52..4e27dcaeb 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -691,8 +691,8 @@ // 'work.error.offer_not_available' => 'Offer is not available.', // 'work.type.one_time' => 'one time', // Work type is "one time job" for well defined work ("do exactly this"). // 'work.type.ongoing' => 'ongoing', // Work type is "ongoing" for complex jobs (billed by the hour, multiple contractors, etc.) -// 'work.label.our_work' => 'Our work', -// 'work.label.our_offers' => 'Our offers', +// 'work.label.own_work' => 'Own work', +// 'work.label.own_offers' => 'Own offers', // 'work.label.offers' => 'Offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index cbd369c3b..68d9faac3 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -691,8 +691,8 @@ // 'work.error.offer_not_available' => 'Offer is not available.', // 'work.type.one_time' => 'one time', // Work type is "one time job" for well defined work ("do exactly this"). // 'work.type.ongoing' => 'ongoing', // Work type is "ongoing" for complex jobs (billed by the hour, multiple contractors, etc.) -// 'work.label.our_work' => 'Our work', -// 'work.label.our_offers' => 'Our offers', +// 'work.label.own_work' => 'Own work', +// 'work.label.own_offers' => 'Own offers', // 'work.label.offers' => 'Offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index bdaa99bb2..9f9858dac 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -689,8 +689,8 @@ // 'work.error.offer_not_available' => 'Offer is not available.', // 'work.type.one_time' => 'one time', // Work type is "one time job" for well defined work ("do exactly this"). // 'work.type.ongoing' => 'ongoing', // Work type is "ongoing" for complex jobs (billed by the hour, multiple contractors, etc.) -// 'work.label.our_work' => 'Our work', -// 'work.label.our_offers' => 'Our offers', +// 'work.label.own_work' => 'Own work', +// 'work.label.own_offers' => 'Own offers', // 'work.label.offers' => 'Offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index aad1932d0..1bb3d793b 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -731,8 +731,8 @@ // 'work.error.offer_not_available' => 'Offer is not available.', // 'work.type.one_time' => 'one time', // Work type is "one time job" for well defined work ("do exactly this"). // 'work.type.ongoing' => 'ongoing', // Work type is "ongoing" for complex jobs (billed by the hour, multiple contractors, etc.) -// 'work.label.our_work' => 'Our work', -// 'work.label.our_offers' => 'Our offers', +// 'work.label.own_work' => 'Own work', +// 'work.label.own_offers' => 'Own offers', // 'work.label.offers' => 'Offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index 0ed2f282f..c0e9fb5bd 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -702,8 +702,8 @@ // 'work.error.offer_not_available' => 'Offer is not available.', // 'work.type.one_time' => 'one time', // Work type is "one time job" for well defined work ("do exactly this"). // 'work.type.ongoing' => 'ongoing', // Work type is "ongoing" for complex jobs (billed by the hour, multiple contractors, etc.) -// 'work.label.our_work' => 'Our work', -// 'work.label.our_offers' => 'Our offers', +// 'work.label.own_work' => 'Own work', +// 'work.label.own_offers' => 'Own offers', // 'work.label.offers' => 'Offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index 42ac20e95..37c55d4b7 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -708,8 +708,8 @@ // 'work.error.offer_not_available' => 'Offer is not available.', // 'work.type.one_time' => 'one time', // Work type is "one time job" for well defined work ("do exactly this"). // 'work.type.ongoing' => 'ongoing', // Work type is "ongoing" for complex jobs (billed by the hour, multiple contractors, etc.) -// 'work.label.our_work' => 'Our work', -// 'work.label.our_offers' => 'Our offers', +// 'work.label.own_work' => 'Own work', +// 'work.label.own_offers' => 'Own offers', // 'work.label.offers' => 'Offers', // 'work.button.send_message' => 'Send message', // 'work.button.make_offer' => 'Make offer', diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 7e8a39eff..f0bacb5d2 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.19.12.5155 | Copyright © Anuko | +  Anuko Time Tracker 1.19.12.5156 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/work.tpl b/WEB-INF/templates/work.tpl index 2e7f5ef79..9c40f0304 100644 --- a/WEB-INF/templates/work.tpl +++ b/WEB-INF/templates/work.tpl @@ -7,7 +7,7 @@ {if $own_work_items} - + @@ -77,7 +77,7 @@ {if $own_offers}
{$i18n.work.label.our_work}
{$i18n.work.label.own_work}
{$i18n.label.work} {$i18n.label.description}
- + From 322b65359b35c82c5e0e236d27c3a3eb155808de Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 15 Oct 2019 20:34:21 +0000 Subject: [PATCH 159/877] Making progress on accepting available offers for the Work plugin. --- WEB-INF/lib/ttWorkHelper.class.php | 1 + WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/offer_view.tpl | 24 ++++++++++++++----- WEB-INF/templates/work_add.tpl | 13 ++++++++++- WEB-INF/templates/work_view.tpl | 6 ----- offer_add.php | 2 +- offer_view.php | 7 +++--- work_add.php | 37 +++++++++++++++++++++++++----- 8 files changed, 68 insertions(+), 24 deletions(-) diff --git a/WEB-INF/lib/ttWorkHelper.class.php b/WEB-INF/lib/ttWorkHelper.class.php index 77037711d..8c2e25fb0 100644 --- a/WEB-INF/lib/ttWorkHelper.class.php +++ b/WEB-INF/lib/ttWorkHelper.class.php @@ -200,6 +200,7 @@ function putOwnWorkItem($fields) { 'group_id' => urlencode($group_id), 'group_name' => urlencode(base64_encode($user->getGroupName())), 'group_key' => urlencode($user->getGroupKey()), + 'offer_id' => urlencode($fields['offer_id']), 'type' => urlencode($fields['type']), 'subject' => urlencode(base64_encode($fields['subject'])), 'descr_short' => urlencode(base64_encode($fields['descr_short'])), diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index f0bacb5d2..99a558a58 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
{$i18n.work.label.our_offers}
{$i18n.work.label.own_offers}
{$i18n.label.offer} {$i18n.label.description}
- diff --git a/WEB-INF/templates/work_view.tpl b/WEB-INF/templates/work_view.tpl index c779b507f..92614d911 100644 --- a/WEB-INF/templates/work_view.tpl +++ b/WEB-INF/templates/work_view.tpl @@ -33,19 +33,14 @@
 Anuko Time Tracker 1.19.12.5156 | Copyright © Anuko | +  Anuko Time Tracker 1.19.12.5157 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/offer_view.tpl b/WEB-INF/templates/offer_view.tpl index b6baaed28..138547613 100644 --- a/WEB-INF/templates/offer_view.tpl +++ b/WEB-INF/templates/offer_view.tpl @@ -1,3 +1,7 @@ + + {$forms.offerForm.open} @@ -19,12 +23,6 @@ -{if $show_files} - - - - -{/if} @@ -34,3 +32,17 @@
{$i18n.label.details}: {$forms.offerForm.details.control}
{$i18n.label.file}:{$forms.offerForm.newfile.control}
{$i18n.label.budget}: {$forms.offerForm.budget.control}
{$forms.offerForm.close} + +{if isTrue('WORK_DEBUG')} + + + + +
+ + + + +
+
+{/if} diff --git a/WEB-INF/templates/work_add.tpl b/WEB-INF/templates/work_add.tpl index 15b430b59..eca0ba799 100644 --- a/WEB-INF/templates/work_add.tpl +++ b/WEB-INF/templates/work_add.tpl @@ -1,5 +1,16 @@ {$forms.workForm.open} - +
+{if $offer} + + + +{/if} -{if $show_files} - - - - -{/if} @@ -45,7 +39,7 @@ -{if isTrue('WORK_DEBUG')} + @@ -55,7 +49,7 @@ -{/if} +
+ + + + +
{$i18n.label.offer}: {$offer.subject}
{$i18n.label.description}: {$offer.descr_short|escape}
{$i18n.label.budget}: {$offer.amount_with_currency}
+
diff --git a/WEB-INF/templates/work_view.tpl b/WEB-INF/templates/work_view.tpl index 37207a72c..c779b507f 100644 --- a/WEB-INF/templates/work_view.tpl +++ b/WEB-INF/templates/work_view.tpl @@ -23,12 +23,6 @@ -{if $show_files} - - - - -{/if} diff --git a/offer_add.php b/offer_add.php index ba430060c..8fc1b20b5 100644 --- a/offer_add.php +++ b/offer_add.php @@ -46,7 +46,7 @@ $work_item = $workHelper->getAvailableWorkItem($cl_work_id); if (!$work_item) { header('Location: access_denied.php'); - exit(); + exit(); } } // End of access checks. diff --git a/offer_view.php b/offer_view.php index 482d1c4ab..ec3a98da5 100644 --- a/offer_view.php +++ b/offer_view.php @@ -39,9 +39,9 @@ header('Location: access_denied.php'); exit(); } -$cl_offer_id = (int)$request->getParameter('id'); +$offer_id = (int)$request->getParameter('id'); $workHelper = new ttWorkHelper($err); -$offer = $workHelper->getAvailableOffer($cl_offer_id); +$offer = $workHelper->getAvailableOffer($offer_id); if (!$offer) { header('Location: access_denied.php'); exit(); @@ -62,7 +62,6 @@ $cl_budget = $offer['amount_with_currency']; $form = new Form('offerForm'); -$form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_offer_id)); $form->addInput(array('type'=>'text','name'=>'contractor','value'=>$cl_contractor)); $form->getElement('contractor')->setEnabled(false); $form->addInput(array('type'=>'text','name'=>'offer_name','style'=>'width: 400px;','value'=>$cl_name)); @@ -74,6 +73,8 @@ $form->addInput(array('type'=>'text','name'=>'budget','value'=>$cl_budget)); $form->getElement('budget')->setEnabled(false); + +$smarty->assign('offer_id', $offer_id); $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('title', $i18n->get('title.offer')); $smarty->assign('content_page_name', 'offer_view.tpl'); diff --git a/work_add.php b/work_add.php index f12aef8f5..68bfe06ea 100644 --- a/work_add.php +++ b/work_add.php @@ -39,18 +39,37 @@ header('Location: feature_disabled.php'); exit(); } +// Do we have offer_id? +$cl_offer_id = (int)$request->getParameter('offer_id'); +if ($cl_offer_id) { + $workHelper = new ttWorkHelper($err); + $offer = $workHelper->getAvailableOffer($cl_offer_id); + if (!$offer) { + header('Location: access_denied.php'); + exit(); + } +} // End of access checks. if ($request->isPost()) { - $cl_work_type = $request->getParameter('work_type'); $cl_name = trim($request->getParameter('work_name')); + $cl_work_type = $request->getParameter('work_type'); $cl_description = trim($request->getParameter('description')); $cl_details = trim($request->getParameter('details')); $cl_currency_id = $request->getParameter('currency'); $cl_budget = $request->getParameter('budget'); } +// Override some fields for work being created on an available offer. +if ($offer) { + $cl_name = $offer['subject']; + $cl_work_type = 0; // one-time work + $cl_currency_id = ttWorkHelper::getCurrencyID($offer['currency']); + $cl_budget = $offer['amount']; +} $form = new Form('workForm'); +if ($offer) + $form->addInput(array('type'=>'hidden','name'=>'offer_id','value'=>$cl_offer_id)); $form->addInput(array('type'=>'text','name'=>'work_name','maxlength'=>'128','style'=>'width: 400px;','value'=>$cl_name)); $WORK_TYPE_OPTIONS = array('0'=>$i18n->get('work.type.one_time'),'1'=>$i18n->get('work.type.ongoing')); $form->addInput(array('type'=>'combobox','name'=>'work_type','data'=>$WORK_TYPE_OPTIONS,'value'=>$cl_work_type)); @@ -61,9 +80,13 @@ $form->addInput(array('type'=>'combobox','name'=>'currency','data'=>$currencies,'datakeys'=>array('id','name'),'value'=>$cl_currency_id)); $form->addInput(array('type'=>'floatfield','maxlength'=>'10','name'=>'budget','format'=>'.2','value'=>$cl_budget)); $form->addInput(array('type'=>'submit','name'=>'btn_add','value'=>$i18n->get('button.add'))); - -// TODO: design how to handle categories and sub-categories. -// One major complication is localization of names. +// Disable some controls for work being created on an available offer. +if ($offer) { + $form->getElement('work_name')->setEnabled(false); + $form->getElement('work_type')->setEnabled(false); + $form->getElement('currency')->setEnabled(false); + $form->getElement('budget')->setEnabled(false); +} if ($request->isPost()) { // Validate user input. @@ -77,8 +100,9 @@ if ($err->no()) { $workHelper = new ttWorkHelper($err); - $fields = array('type'=>$cl_work_type, - 'subject'=>$cl_name, + $fields = array('offer_id' => $cl_offer_id, + 'subject' => $cl_name, + 'type' => $cl_work_type, 'descr_short' => $cl_description, 'descr_long' => $cl_details, 'currency' => ttWorkHelper::getCurrencyName($cl_currency_id), @@ -90,6 +114,7 @@ } } // isPost +$smarty->assign('offer', $offer); $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="document.workForm.work_name.focus()"'); $smarty->assign('title', $i18n->get('title.add_work')); From 93450ef5b971ce080c57018b619cac5b4ddda85d Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 16 Oct 2019 11:45:45 +0000 Subject: [PATCH 160/877] Removed WORK_DEBUG conditions to hopefully start user testing of Work plugin features. --- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/offer_view.tpl | 2 -- WEB-INF/templates/work_offer_view.tpl | 10 ++-------- WEB-INF/templates/work_view.tpl | 5 ----- 4 files changed, 3 insertions(+), 16 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 99a558a58..9e1861c6e 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
{$i18n.label.details}: {$forms.workForm.details.control}
{$i18n.label.file}:{$forms.workForm.newfile.control}
{$i18n.label.budget}: {$forms.workForm.budget.control}
-
 Anuko Time Tracker 1.19.12.5157 | Copyright © Anuko | +  Anuko Time Tracker 1.19.12.5158 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/offer_view.tpl b/WEB-INF/templates/offer_view.tpl index 138547613..ad0b385f2 100644 --- a/WEB-INF/templates/offer_view.tpl +++ b/WEB-INF/templates/offer_view.tpl @@ -33,7 +33,6 @@
{$forms.offerForm.close} -{if isTrue('WORK_DEBUG')}
@@ -45,4 +44,3 @@
-{/if} diff --git a/WEB-INF/templates/work_offer_view.tpl b/WEB-INF/templates/work_offer_view.tpl index 00af0aafc..874856237 100644 --- a/WEB-INF/templates/work_offer_view.tpl +++ b/WEB-INF/templates/work_offer_view.tpl @@ -31,12 +31,6 @@
{$i18n.label.details}: {$forms.offerForm.details.control}
{$i18n.label.file}:{$forms.offerForm.newfile.control}
{$i18n.label.budget}: {$forms.offerForm.budget.control}{$i18n.label.status}: {$forms.offerForm.status.control}
 
{$i18n.label.comment}: {$forms.offerForm.client_comment.control}
{$forms.workForm.close} -{if isTrue('WORK_DEBUG')}
- {if false} - - {/if}
-{/if} From e47d89289096fb7a3f737db3a73813af0de87bad Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 16 Oct 2019 16:43:23 +0000 Subject: [PATCH 161/877] Got rid of a PHP warning when generating reports with 0 inactive users. --- WEB-INF/lib/ttReportHelper.class.php | 4 ++-- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index 5d36b6b8e..1c2387148 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -1602,8 +1602,8 @@ static function verifyBean($bean) { global $user; // Check users. - $active_users_in_bean = $bean->getAttribute('users_active'); - $inactive_users_in_bean = $bean->getAttribute('users_inactive'); + $active_users_in_bean = (array) $bean->getAttribute('users_active'); + $inactive_users_in_bean = (array) $bean->getAttribute('users_inactive'); if (is_array($active_users_in_bean) || is_array($inactive_users_in_bean)) { $users_in_group = ttGroupHelper::getUsers(); foreach ($users_in_group as $user_in_group) { diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 9e1861c6e..5440d2010 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.19.12.5158 | Copyright © Anuko | +  Anuko Time Tracker 1.19.12.5159 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 94e11c5568c42b1b11cd7dfc526928fd164b7da9 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 16 Oct 2019 21:51:54 +0000 Subject: [PATCH 162/877] Added audit info to a registration call to Work server. --- WEB-INF/lib/ttWorkHelper.class.php | 11 ++++++++++- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/WEB-INF/lib/ttWorkHelper.class.php b/WEB-INF/lib/ttWorkHelper.class.php index 8c2e25fb0..1b5297b4e 100644 --- a/WEB-INF/lib/ttWorkHelper.class.php +++ b/WEB-INF/lib/ttWorkHelper.class.php @@ -105,9 +105,18 @@ function checkSiteRegistration() { $val = $res->fetchRow(); if (!$val) { // No site id found, need to register. + $group_id = $user->getGroup(); + $org_id = $user->org_id; $fields = array('lang' => urlencode($user->lang), 'name' => urlencode('time tracker'), - 'origin' => urlencode('time tracker source')); + 'origin' => urlencode('time tracker source'), + 'org_id' => urlencode($org_id), + 'group_id' => urlencode($group_id), + 'group_name' => urlencode(base64_encode($user->getGroupName())), + 'user_id' => urlencode($user->getUser()), + 'user_name' => urlencode(base64_encode($user->getName())), + 'user_email' => urlencode(base64_encode($user->getEmail())), + 'user_ip' => urlencode($_SERVER['REMOTE_ADDR'])); // Urlify the data for the POST. foreach($fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 5440d2010..01a55b6ab 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.19.12.5159 | Copyright © Anuko | +  Anuko Time Tracker 1.19.12.5160 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 2e5bde98edf7cada432e372640f82b9b3133deda Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 17 Oct 2019 20:33:42 +0000 Subject: [PATCH 163/877] Improved work_edit.php for work items on offers. --- WEB-INF/templates/footer.tpl | 2 +- work_edit.php | 23 +++++++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 01a55b6ab..14f1830bc 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.19.12.5160 | Copyright © Anuko | +  Anuko Time Tracker 1.19.12.5161 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/work_edit.php b/work_edit.php index e99ca9dcf..c6ffd4ce7 100644 --- a/work_edit.php +++ b/work_edit.php @@ -46,6 +46,15 @@ header('Location: access_denied.php'); exit(); } +// Do we have offer_id? +$offer_id = $work_item['offer_id']; +if ($offer_id) { + $offer = $workHelper->getAvailableOffer($offer_id); + if (!$offer) { + header('Location: access_denied.php'); + exit(); + } +} // End of access checks. $currencies = ttWorkHelper::getCurrencies(); @@ -67,6 +76,13 @@ $cl_status = $work_item['status_label']; $cl_moderator_comment = $work_item['moderator_comment']; } +// Override some fields for work on an available offer. +if ($offer) { + $cl_name = $offer['subject']; + $cl_work_type = 0; // one-time work + $cl_currency_id = ttWorkHelper::getCurrencyID($offer['currency']); + $cl_budget = $offer['amount']; +} $show_moderator_comment = $cl_moderator_comment != null; @@ -84,6 +100,13 @@ $form->addInput(array('type'=>'textarea','name'=>'moderator_comment','style'=>'width: 400px; height: 80px;','value'=>$cl_moderator_comment)); $form->getElement('moderator_comment')->setEnabled(false); $form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); +// Disable some controls for work on an available offer. +if ($offer) { + $form->getElement('work_name')->setEnabled(false); + $form->getElement('work_type')->setEnabled(false); + $form->getElement('currency')->setEnabled(false); + $form->getElement('budget')->setEnabled(false); +} if ($request->isPost()) { // Validate user input. From 3e0594949439bc20414dcab71889f5fbd2dd3ad7 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 18 Oct 2019 18:42:43 +0000 Subject: [PATCH 164/877] Some progress on updating work items on offers for Work plugin. --- WEB-INF/lib/ttWorkHelper.class.php | 68 ++++++++++++++++++++++++++++++ WEB-INF/templates/footer.tpl | 2 +- work_edit.php | 13 ++++-- 3 files changed, 79 insertions(+), 4 deletions(-) diff --git a/WEB-INF/lib/ttWorkHelper.class.php b/WEB-INF/lib/ttWorkHelper.class.php index 1b5297b4e..55a8dfced 100644 --- a/WEB-INF/lib/ttWorkHelper.class.php +++ b/WEB-INF/lib/ttWorkHelper.class.php @@ -46,6 +46,7 @@ class ttWorkHelper { var $delete_own_work_item_uri = null; // URI to delete own work item. // TODO: design how (and what) to delete when a group is deleted. var $update_own_work_item_uri = null; // URI to update own work item. + var $update_own_work_item_on_offer_uri = null; // URI to update own work item posted on offer. var $put_own_offer_uri = null; // URI to publish own offer. var $get_own_offer_uri = null; // URI to get own offer details. var $get_own_offers_uri = null; // URI to get own offers. @@ -80,6 +81,7 @@ function __construct(&$errors) { $this->accept_own_work_item_offer_uri = $this->work_server_uri.'acceptownworkitemoffer'; $this->decline_own_work_item_offer_uri = $this->work_server_uri.'declineownworkitemoffer'; $this->update_own_work_item_uri = $this->work_server_uri.'updateownworkitem'; + $this->update_own_work_item_on_offer_uri = $this->work_server_uri.'updateownworkitemonoffer'; $this->put_own_offer_uri = $this->work_server_uri.'putownoffer'; $this->get_own_offer_uri = $this->work_server_uri.'getownoffer'; $this->get_own_offers_uri = $this->work_server_uri.'getownoffers'; @@ -332,6 +334,72 @@ function updateOwnWorkItem($fields) { return true; } + // updateOwnWorkItemOnOffer - updates own work item posted on offer in remote work server. + function updateOwnWorkItemOnOffer($fields) { + global $i18n; + global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $curl_fields = array('lang' => urlencode($user->lang), + 'site_id' => urlencode($this->site_id), + 'site_key' => urlencode($this->site_key), + 'org_id' => urlencode($org_id), + 'org_key' => urlencode($user->getOrgKey()), + 'group_id' => urlencode($group_id), + 'group_name' => urlencode(base64_encode($user->getGroupName())), + 'group_key' => urlencode($user->getGroupKey()), + 'work_id' => urlencode($fields['work_id']), + 'descr_short' => urlencode(base64_encode($fields['descr_short'])), + 'descr_long' => urlencode(base64_encode($fields['descr_long'])), + 'modified_ip' => urlencode($_SERVER['REMOTE_ADDR']), + 'modified_by' => urlencode($user->getUser()), + 'modified_by_name' => urlencode(base64_encode($user->getName())), + 'modified_by_email' => urlencode(base64_encode($user->getEmail())) + ); + + // url-ify the data for the POST. + foreach($curl_fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; } + $fields_string = rtrim($fields_string, '&'); + + // Open connection. + $ch = curl_init(); + + // Set the url, number of POST vars, POST data. + curl_setopt($ch, CURLOPT_URL, $this->update_own_work_item_on_offer_uri); + curl_setopt($ch, CURLOPT_POST, true); + curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + + // Execute a post request. + $result = curl_exec($ch); + + // Close connection. + curl_close($ch); + + if (!$result) { + $this->errors->add($i18n->get('error.remote_work')); + return false; + } + + $result_array = json_decode($result, true); + + // Check for errors. + $call_status = $result_array['call_status']; + if (!$call_status) { + $this->errors->add($i18n->get('error.remote_work')); + return false; + } + if ($call_status['code'] != TT_CURL_SUCCESS) { + $this->errors->add($call_status['error']); + return false; + } + + return true; + } + // getOwnWorkItems - obtains a list of work items this group is currently outsourcing. function getOwnWorkItems() { global $i18n; diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 14f1830bc..6089e5496 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.19.12.5161 | Copyright © Anuko | +  Anuko Time Tracker 1.19.12.5162 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/work_edit.php b/work_edit.php index c6ffd4ce7..4512ed2fc 100644 --- a/work_edit.php +++ b/work_edit.php @@ -128,9 +128,16 @@ 'descr_long' => $cl_details, 'currency' => ttWorkHelper::getCurrencyName($cl_currency_id), 'amount' => $cl_budget); - if ($workHelper->updateOwnWorkItem($fields)) { - header('Location: work.php'); - exit(); + if ($offer_id > 0) { + if ($workHelper->updateOwnWorkItemOnOffer($fields)) { + header('Location: work.php'); + exit(); + } + } else { + if ($workHelper->updateOwnWorkItem($fields)) { + header('Location: work.php'); + exit(); + } } } } From 9107d1af1942b375585f7ced4647dafe0b9e133c Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 18 Oct 2019 21:13:32 +0000 Subject: [PATCH 165/877] Work in progress on disapproving work item on offers in Work plugin. --- WEB-INF/lib/ttAdminWorkHelper.class.php | 62 +++++++++++++++++++++++++ WEB-INF/templates/admin_work_edit.tpl | 14 +++++- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/work_edit.tpl | 14 +++++- WEB-INF/templates/work_offer_view.tpl | 2 +- WEB-INF/templates/work_offers.tpl | 1 + WEB-INF/templates/work_view_own.tpl | 14 +++++- admin_work_edit.php | 23 +++++++-- work_edit.php | 1 + work_view_own.php | 10 ++++ 10 files changed, 135 insertions(+), 8 deletions(-) diff --git a/WEB-INF/lib/ttAdminWorkHelper.class.php b/WEB-INF/lib/ttAdminWorkHelper.class.php index d809cb35f..5e51fc316 100644 --- a/WEB-INF/lib/ttAdminWorkHelper.class.php +++ b/WEB-INF/lib/ttAdminWorkHelper.class.php @@ -38,7 +38,9 @@ class ttAdminWorkHelper { var $update_work_item_uri = null; // URI to update work item. var $delete_work_item_uri = null; // URI to delete work item. var $approve_work_item_uri = null; // URI to approve work item. + var $approve_work_item_on_offer_uri = null; // URI to approve work item posted on offer. var $disapprove_work_item_uri = null; // URI to disapprove work item. + var $disapprove_work_item_on_offer_uri = null; // URI to disapprove work item posted on offer. var $get_offer_uri = null; // URI to get offer details. var $update_offer_uri = null; // URI to update offer. var $delete_offer_uri = null; // URI to delete offer. @@ -60,7 +62,9 @@ function __construct(&$errors) { $this->update_work_item_uri = $this->work_server_uri.'admin_updateworkitem'; $this->delete_work_item_uri = $this->work_server_uri.'admin_deleteworkitem'; $this->approve_work_item_uri = $this->work_server_uri.'admin_approveworkitem'; + $this->approve_work_item_on_offer_uri = $this->work_server_uri.'admin_approveworkitemonoffer'; $this->disapprove_work_item_uri = $this->work_server_uri.'admin_disapproveworkitem'; + $this->disapprove_work_item_on_offer_uri = $this->work_server_uri.'admin_disapproveworkitemonoffer'; $this->get_offer_uri = $this->work_server_uri.'admin_getoffer'; $this->update_offer_uri = $this->work_server_uri.'admin_updateoffer'; $this->delete_offer_uri = $this->work_server_uri.'admin_deleteoffer'; @@ -661,6 +665,64 @@ function disapproveWorkItem($fields) { return true; } + // disapproveWorkItemOnOffer - disapproves work item posted on offer in remote work server. + function disapproveWorkItemOnOffer($fields) { + global $i18n; + global $user; + $mdb2 = getConnection(); + + $curl_fields = array('lang' => urlencode($user->lang), + 'site_id' => urlencode($this->site_id), + 'site_key' => urlencode($this->site_key), + 'user_id' => urlencode($user->id), + 'work_id' => urlencode($fields['work_id']), + 'descr_short' => urlencode(base64_encode($fields['descr_short'])), + 'descr_long' => urlencode(base64_encode($fields['descr_long'])), + 'moderator_comment' => urlencode(base64_encode($fields['moderator_comment'])), + 'modified_ip' => urlencode($_SERVER['REMOTE_ADDR']), + 'modified_by' => urlencode($user->getUser()), + 'modified_by_name' => urlencode(base64_encode($user->getName())), + 'modified_by_email' => urlencode(base64_encode($user->getEmail()))); + + // url-ify the data for the POST. + foreach($curl_fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; } + $fields_string = rtrim($fields_string, '&'); + // Open connection. + $ch = curl_init(); + + // Set the url, number of POST vars, POST data. + curl_setopt($ch, CURLOPT_URL, $this->disapprove_work_item_on_offer_uri); + curl_setopt($ch, CURLOPT_POST, true); + curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + + // Execute a post request. + $result = curl_exec($ch); + + // Close connection. + curl_close($ch); + + if (!$result) { + $this->errors->add($i18n->get('error.remote_work')); + return false; + } + + $result_array = json_decode($result, true); + + // Check for errors. + $call_status = $result_array['call_status']; + if (!$call_status) { + $this->errors->add($i18n->get('error.remote_work')); + return false; + } + if ($call_status['code'] != TT_CURL_SUCCESS) { + $this->errors->add($call_status['error']); + return false; + } + + return true; + } + // updateOffer - updates an offer in remote work server. function updateOffer($fields) { global $i18n; diff --git a/WEB-INF/templates/admin_work_edit.tpl b/WEB-INF/templates/admin_work_edit.tpl index 8b7613e1d..1ae59a6fe 100644 --- a/WEB-INF/templates/admin_work_edit.tpl +++ b/WEB-INF/templates/admin_work_edit.tpl @@ -1,5 +1,17 @@ {$forms.workForm.open} - +
+{if $offer} + + + +{/if}
+ + + + + +
{$i18n.label.offer}: {$offer.subject}
{$i18n.label.contractor}: {$offer.group_name}
{$i18n.label.description}: {$offer.descr_short|escape}
{$i18n.label.budget}: {$offer.amount_with_currency}
+
diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 6089e5496..f996fc690 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.19.12.5162 | Copyright © Anuko | +  Anuko Time Tracker 1.19.12.5163 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/work_edit.tpl b/WEB-INF/templates/work_edit.tpl index 96959b189..7165d5e19 100644 --- a/WEB-INF/templates/work_edit.tpl +++ b/WEB-INF/templates/work_edit.tpl @@ -1,5 +1,17 @@ {$forms.workForm.open} - +
+{if $offer} + + + +{/if}
+ + + + + +
{$i18n.label.offer}: {$offer.subject}
{$i18n.label.contractor}: {$offer.group_name}
{$i18n.label.description}: {$offer.descr_short|escape}
{$i18n.label.budget}: {$offer.amount_with_currency}
+
diff --git a/WEB-INF/templates/work_offer_view.tpl b/WEB-INF/templates/work_offer_view.tpl index 874856237..e2afe0003 100644 --- a/WEB-INF/templates/work_offer_view.tpl +++ b/WEB-INF/templates/work_offer_view.tpl @@ -5,13 +5,13 @@ {/if} -
+
{$i18n.label.work}: {$work_item.subject}
{$i18n.label.client}: {$work_item.group_name}
{$i18n.label.description}: {$work_item.descr_short|escape}
{$i18n.label.budget}: {$work_item.amount_with_currency}
diff --git a/WEB-INF/templates/work_offers.tpl b/WEB-INF/templates/work_offers.tpl index bd867a9f4..ea0d8816f 100644 --- a/WEB-INF/templates/work_offers.tpl +++ b/WEB-INF/templates/work_offers.tpl @@ -7,6 +7,7 @@
+
{$i18n.label.work}: {$work_item.subject}
{$i18n.label.client}: {$work_item.group_name}
{$i18n.label.description}: {$work_item.descr_short|escape}
{$i18n.label.budget}: {$work_item.amount_with_currency}
diff --git a/WEB-INF/templates/work_view_own.tpl b/WEB-INF/templates/work_view_own.tpl index 51e825929..61e270b4b 100644 --- a/WEB-INF/templates/work_view_own.tpl +++ b/WEB-INF/templates/work_view_own.tpl @@ -1,5 +1,17 @@ {$forms.workForm.open} - +
+{if $offer} + + + +{/if}
+ + + + + +
{$i18n.label.offer}: {$offer.subject}
{$i18n.label.contractor}: {$offer.group_name}
{$i18n.label.description}: {$offer.descr_short|escape}
{$i18n.label.budget}: {$offer.amount_with_currency}
+
diff --git a/admin_work_edit.php b/admin_work_edit.php index c66906d61..d8fbd65c2 100644 --- a/admin_work_edit.php +++ b/admin_work_edit.php @@ -44,6 +44,15 @@ header('Location: access_denied.php'); exit(); } +// Do we have offer_id? +$offer_id = $work_item['offer_id']; +if ($offer_id) { + $offer = $adminWorkHelper->getOffer($offer_id); + if (!$offer) { + header('Location: access_denied.php'); + exit(); + } +} // End of access checks. @@ -117,9 +126,16 @@ } } else if ($cl_status == STATUS_DISAPPROVED) { // Status changed to "not approved". Disapprove work. - if ($adminWorkHelper->disapproveWorkItem($fields)) { - header('Location: admin_work.php'); - exit(); + if ($offer_id) { + if ($adminWorkHelper->disapproveWorkItemOnOffer($fields)) { + header('Location: admin_work.php'); + exit(); + } + } else { + if ($adminWorkHelper->disapproveWorkItem($fields)) { + header('Location: admin_work.php'); + exit(); + } } } else if ($cl_status == STATUS_APPROVED) { // Status changed to "approved". Approve work. @@ -132,6 +148,7 @@ } } // isPost +$smarty->assign('offer', $offer); $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('title', $i18n->get('title.edit_work')); $smarty->assign('content_page_name', 'admin_work_edit.tpl'); diff --git a/work_edit.php b/work_edit.php index 4512ed2fc..916a9aeef 100644 --- a/work_edit.php +++ b/work_edit.php @@ -143,6 +143,7 @@ } } // isPost +$smarty->assign('offer', $offer); $smarty->assign('show_moderator_comment', $show_moderator_comment); $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('title', $i18n->get('title.edit_work')); diff --git a/work_view_own.php b/work_view_own.php index 19a809b31..15e57632b 100644 --- a/work_view_own.php +++ b/work_view_own.php @@ -46,6 +46,15 @@ header('Location: access_denied.php'); exit(); } +// Do we have offer_id? +$offer_id = $work_item['offer_id']; +if ($offer_id) { + $offer = $workHelper->getAvailableOffer($offer_id); + if (!$offer) { + header('Location: access_denied.php'); + exit(); + } +} // End of access checks. $cl_name = $work_item['subject']; @@ -63,6 +72,7 @@ $form->addInput(array('type'=>'text','name'=>'budget','value'=>$cl_budget)); $form->getElement('budget')->setEnabled(false); +$smarty->assign('offer', $offer); $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('title', $i18n->get('title.work')); $smarty->assign('content_page_name', 'work_view_own.tpl'); From 9f6cdb5ec955efcab37d859564f69f2e7b45a689 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 18 Oct 2019 21:52:51 +0000 Subject: [PATCH 166/877] Made progress on approving work items on offers for Work plugin. --- WEB-INF/lib/ttAdminWorkHelper.class.php | 58 +++++++++++++++++++++++++ WEB-INF/templates/footer.tpl | 2 +- admin_work_edit.php | 13 ++++-- 3 files changed, 69 insertions(+), 4 deletions(-) diff --git a/WEB-INF/lib/ttAdminWorkHelper.class.php b/WEB-INF/lib/ttAdminWorkHelper.class.php index 5e51fc316..ce8d0f76f 100644 --- a/WEB-INF/lib/ttAdminWorkHelper.class.php +++ b/WEB-INF/lib/ttAdminWorkHelper.class.php @@ -723,6 +723,64 @@ function disapproveWorkItemOnOffer($fields) { return true; } + // approveWorkItemOnOffer - approves work item posted on offer in remote work server. + function approveWorkItemOnOffer($fields) { + global $i18n; + global $user; + $mdb2 = getConnection(); + + $curl_fields = array('lang' => urlencode($user->lang), + 'site_id' => urlencode($this->site_id), + 'site_key' => urlencode($this->site_key), + 'user_id' => urlencode($user->id), + 'work_id' => urlencode($fields['work_id']), + 'descr_short' => urlencode(base64_encode($fields['descr_short'])), + 'descr_long' => urlencode(base64_encode($fields['descr_long'])), + 'moderator_comment' => urlencode(base64_encode($fields['moderator_comment'])), + 'modified_ip' => urlencode($_SERVER['REMOTE_ADDR']), + 'modified_by' => urlencode($user->getUser()), + 'modified_by_name' => urlencode(base64_encode($user->getName())), + 'modified_by_email' => urlencode(base64_encode($user->getEmail()))); + + // url-ify the data for the POST. + foreach($curl_fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; } + $fields_string = rtrim($fields_string, '&'); + // Open connection. + $ch = curl_init(); + + // Set the url, number of POST vars, POST data. + curl_setopt($ch, CURLOPT_URL, $this->approve_work_item_on_offer_uri); + curl_setopt($ch, CURLOPT_POST, true); + curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + + // Execute a post request. + $result = curl_exec($ch); + + // Close connection. + curl_close($ch); + + if (!$result) { + $this->errors->add($i18n->get('error.remote_work')); + return false; + } + + $result_array = json_decode($result, true); + + // Check for errors. + $call_status = $result_array['call_status']; + if (!$call_status) { + $this->errors->add($i18n->get('error.remote_work')); + return false; + } + if ($call_status['code'] != TT_CURL_SUCCESS) { + $this->errors->add($call_status['error']); + return false; + } + + return true; + } + // updateOffer - updates an offer in remote work server. function updateOffer($fields) { global $i18n; diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index f996fc690..f5a9f1870 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.19.12.5163 | Copyright © Anuko | +  Anuko Time Tracker 1.19.12.5164 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/admin_work_edit.php b/admin_work_edit.php index d8fbd65c2..56003b1ac 100644 --- a/admin_work_edit.php +++ b/admin_work_edit.php @@ -139,9 +139,16 @@ } } else if ($cl_status == STATUS_APPROVED) { // Status changed to "approved". Approve work. - if ($adminWorkHelper->approveWorkItem($fields)) { - header('Location: admin_work.php'); - exit(); + if ($offer_id) { + if ($adminWorkHelper->approveWorkItemOnOffer($fields)) { + header('Location: admin_work.php'); + exit(); + } + } else { + if ($adminWorkHelper->approveWorkItem($fields)) { + header('Location: admin_work.php'); + exit(); + } } } } From 32144f905c26b025ecacb59391fa9df82e26ed27 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 19 Oct 2019 13:35:46 +0000 Subject: [PATCH 167/877] Work in progress on Work plugin. Disabled some controls. --- WEB-INF/templates/footer.tpl | 2 +- admin_work_edit.php | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index f5a9f1870..613af6afc 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.19.12.5164 | Copyright © Anuko | +  Anuko Time Tracker 1.19.12.5165 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/admin_work_edit.php b/admin_work_edit.php index 56003b1ac..5b4d47e3d 100644 --- a/admin_work_edit.php +++ b/admin_work_edit.php @@ -55,7 +55,6 @@ } // End of access checks. - $existingStatus = $work_item['status']; $currencies = ttWorkHelper::getCurrencies(); @@ -85,6 +84,13 @@ $form->addInput(array('type'=>'textarea','name'=>'details','style'=>'width: 400px; height: 200px;','value'=>$cl_details)); $form->addInput(array('type'=>'combobox','name'=>'currency','data'=>$currencies,'datakeys'=>array('id','name'),'value'=>$cl_currency_id)); $form->addInput(array('type'=>'floatfield','maxlength'=>'10','name'=>'budget','format'=>'.2','value'=>$cl_budget)); +// Disable some controls for work on an available offer. +if ($offer) { + $form->getElement('work_name')->setEnabled(false); + // $form->getElement('work_type')->setEnabled(false); + $form->getElement('currency')->setEnabled(false); + $form->getElement('budget')->setEnabled(false); +} // Prepare status choices. $status_options = array(); From 7553f3a716b0ac58407904b6ab5a841f04bb2710 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 26 Oct 2019 23:04:05 +0000 Subject: [PATCH 168/877] Starting on messaging mechanism between users in Work plugin. --- WEB-INF/lib/ttWorkHelper.class.php | 66 ++++++++++++++++++++ WEB-INF/resources/ca.lang.php | 1 + WEB-INF/resources/cs.lang.php | 1 + WEB-INF/resources/da.lang.php | 1 + WEB-INF/resources/de.lang.php | 1 + WEB-INF/resources/en.lang.php | 3 + WEB-INF/resources/es.lang.php | 1 + WEB-INF/resources/et.lang.php | 1 + WEB-INF/resources/fa.lang.php | 1 + WEB-INF/resources/fi.lang.php | 1 + WEB-INF/resources/fr.lang.php | 1 + WEB-INF/resources/gr.lang.php | 1 + WEB-INF/resources/he.lang.php | 1 + WEB-INF/resources/hu.lang.php | 1 + WEB-INF/resources/it.lang.php | 1 + WEB-INF/resources/ja.lang.php | 1 + WEB-INF/resources/ko.lang.php | 1 + WEB-INF/resources/nl.lang.php | 1 + WEB-INF/resources/no.lang.php | 1 + WEB-INF/resources/pl.lang.php | 1 + WEB-INF/resources/pt-br.lang.php | 1 + WEB-INF/resources/pt.lang.php | 1 + WEB-INF/resources/ro.lang.php | 1 + WEB-INF/resources/ru.lang.php | 1 + WEB-INF/resources/sk.lang.php | 1 + WEB-INF/resources/sl.lang.php | 1 + WEB-INF/resources/sr.lang.php | 1 + WEB-INF/resources/sv.lang.php | 1 + WEB-INF/resources/tr.lang.php | 1 + WEB-INF/resources/zh-cn.lang.php | 1 + WEB-INF/resources/zh-tw.lang.php | 1 + WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/work_message.tpl | 32 ++++++++++ WEB-INF/templates/work_view.tpl | 1 + work_message.php | 97 ++++++++++++++++++++++++++++++ 35 files changed, 229 insertions(+), 1 deletion(-) create mode 100644 WEB-INF/templates/work_message.tpl create mode 100644 work_message.php diff --git a/WEB-INF/lib/ttWorkHelper.class.php b/WEB-INF/lib/ttWorkHelper.class.php index 55a8dfced..bcdd8a37a 100644 --- a/WEB-INF/lib/ttWorkHelper.class.php +++ b/WEB-INF/lib/ttWorkHelper.class.php @@ -55,6 +55,7 @@ class ttWorkHelper { var $get_group_items_uri = null; // URI to get all group items in one API call. var $delete_own_offer_uri = null; // URI to delete own offer. var $update_own_offer_uri = null; // URI to update own offer. + var $send_message_uri = null; // URI to send message. var $site_id = null; // Site id for work server. var $site_key = null; // Site key for work server. @@ -91,6 +92,7 @@ function __construct(&$errors) { $this->get_group_items_uri = $this->work_server_uri.'getgroupitems'; $this->delete_own_offer_uri = $this->work_server_uri.'deleteownoffer'; $this->update_own_offer_uri = $this->work_server_uri.'updateownoffer'; + $this->send_message_uri = $this->work_server_uri.'sendmessage'; $this->checkSiteRegistration(); } @@ -1482,4 +1484,68 @@ function getAvailableOffer($offer_id) { $offer = $result_array['offer']; return $offer; } + + // sendMessage - sends a message via remote work server. + function sendMessage($fields) { + global $i18n; + global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $curl_fields = array('lang' => urlencode($user->lang), + 'site_id' => urlencode($this->site_id), + 'site_key' => urlencode($this->site_key), + 'org_id' => urlencode($org_id), + 'org_key' => urlencode($user->getOrgKey()), + 'group_id' => urlencode($group_id), + 'group_name' => urlencode(base64_encode($user->getGroupName())), + 'group_key' => urlencode($user->getGroupKey()), + 'work_id' => urlencode($fields['work_id']), + 'sender_ip' => urlencode($_SERVER['REMOTE_ADDR']), + 'sender_user_id' => urlencode($user->getUser()), + 'sender_name' => urlencode(base64_encode($user->getName())), + 'sender_email' => urlencode(base64_encode($user->getEmail())), + 'message_body' => urlencode(base64_encode($fields['message_body']))); + + // url-ify the data for the POST. + foreach($curl_fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; } + $fields_string = rtrim($fields_string, '&'); + + // Open connection. + $ch = curl_init(); + + // Set the url, number of POST vars, POST data. + curl_setopt($ch, CURLOPT_URL, $this->send_message_uri); + curl_setopt($ch, CURLOPT_POST, true); + curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + + // Execute a post request. + $result = curl_exec($ch); + + // Close connection. + curl_close($ch); + + if (!$result) { + $this->errors->add($i18n->get('error.remote_work')); + return false; + } + + $result_array = json_decode($result, true); + + // Check for errors. + $call_status = $result_array['call_status']; + if (!$call_status) { + $this->errors->add($i18n->get('error.remote_work')); + return false; + } + if ($call_status['code'] != TT_CURL_SUCCESS) { + $this->errors->add($call_status['error']); + return false; + } + + return true; + } } diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index cb0de346a..5816fd6a6 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -717,4 +717,5 @@ // 'work.button.make_offer' => 'Make offer', // 'work.button.accept' => 'Accept', // 'work.button.decline' => 'Decline', +// 'work.title.send_message' => 'Sending Message', ); diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index 8a7c3c7bd..a3f3c0e8d 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -730,4 +730,5 @@ // 'work.button.make_offer' => 'Make offer', // 'work.button.accept' => 'Accept', // 'work.button.decline' => 'Decline', +// 'work.title.send_message' => 'Sending Message', ); diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index 161ef01d5..750a4dab6 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -691,4 +691,5 @@ // 'work.button.make_offer' => 'Make offer', // 'work.button.accept' => 'Accept', // 'work.button.decline' => 'Decline', +// 'work.title.send_message' => 'Sending Message', ); diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index f29576f27..ce5e07171 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -667,4 +667,5 @@ // 'work.button.make_offer' => 'Make offer', // 'work.button.accept' => 'Accept', // 'work.button.decline' => 'Decline', +// 'work.title.send_message' => 'Sending Message', ); diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index 9d9788f23..6376660d5 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -643,8 +643,11 @@ 'work.label.own_work' => 'Own work', 'work.label.own_offers' => 'Own offers', 'work.label.offers' => 'Offers', +'work.label.message' => 'Message', 'work.button.send_message' => 'Send message', 'work.button.make_offer' => 'Make offer', 'work.button.accept' => 'Accept', 'work.button.decline' => 'Decline', +'work.title.send_message' => 'Sending Message', +'work.msg.message_sent' => 'Message sent.', ); diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index 0622e8d12..8a967089f 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -732,4 +732,5 @@ // 'work.button.make_offer' => 'Make offer', // 'work.button.accept' => 'Accept', // 'work.button.decline' => 'Decline', +// 'work.title.send_message' => 'Sending Message', ); diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index bf358d4c2..aa9afe003 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -698,4 +698,5 @@ // 'work.button.make_offer' => 'Make offer', // 'work.button.accept' => 'Accept', // 'work.button.decline' => 'Decline', +// 'work.title.send_message' => 'Sending Message', ); diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index 80b1781e0..d5e8da92c 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -715,4 +715,5 @@ // 'work.button.make_offer' => 'Make offer', // 'work.button.accept' => 'Accept', // 'work.button.decline' => 'Decline', +// 'work.title.send_message' => 'Sending Message', ); diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 4e4864ff8..60621b769 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -697,4 +697,5 @@ // 'work.button.make_offer' => 'Make offer', // 'work.button.accept' => 'Accept', // 'work.button.decline' => 'Decline', +// 'work.title.send_message' => 'Sending Message', ); diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index 417c3093a..ad82e88e8 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -687,4 +687,5 @@ // 'work.button.make_offer' => 'Make offer', // 'work.button.accept' => 'Accept', // 'work.button.decline' => 'Decline', +// 'work.title.send_message' => 'Sending Message', ); diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index 56b6c8a42..25e3f5976 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -680,4 +680,5 @@ // 'work.button.make_offer' => 'Make offer', // 'work.button.accept' => 'Accept', // 'work.button.decline' => 'Decline', +// 'work.title.send_message' => 'Sending Message', ); diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index 79ad5059e..dd7c3bd14 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -717,4 +717,5 @@ // 'work.button.make_offer' => 'Make offer', // 'work.button.accept' => 'Accept', // 'work.button.decline' => 'Decline', +// 'work.title.send_message' => 'Sending Message', ); diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index 529a73968..f566a3283 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -722,4 +722,5 @@ // 'work.button.make_offer' => 'Make offer', // 'work.button.accept' => 'Accept', // 'work.button.decline' => 'Decline', +// 'work.title.send_message' => 'Sending Message', ); diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index f07c9a00d..73945b376 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -694,4 +694,5 @@ // 'work.button.make_offer' => 'Make offer', // 'work.button.accept' => 'Accept', // 'work.button.decline' => 'Decline', +// 'work.title.send_message' => 'Sending Message', ); diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index 86e860d66..f56deb6ea 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -725,4 +725,5 @@ // 'work.button.make_offer' => 'Make offer', // 'work.button.accept' => 'Accept', // 'work.button.decline' => 'Decline', +// 'work.title.send_message' => 'Sending Message', ); diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index 2276102a4..ff8470e4a 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -723,4 +723,5 @@ // 'work.button.make_offer' => 'Make offer', // 'work.button.accept' => 'Accept', // 'work.button.decline' => 'Decline', +// 'work.title.send_message' => 'Sending Message', ); diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 44f1dc5b9..5cf619605 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -649,4 +649,5 @@ // 'work.button.make_offer' => 'Make offer', // 'work.button.accept' => 'Accept', // 'work.button.decline' => 'Decline', +// 'work.title.send_message' => 'Sending Message', ); diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index 5feaab8f8..623854bc2 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -722,4 +722,5 @@ // 'work.button.make_offer' => 'Make offer', // 'work.button.accept' => 'Accept', // 'work.button.decline' => 'Decline', +// 'work.title.send_message' => 'Sending Message', ); diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index b6a5fe62b..98eed22b0 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -700,4 +700,5 @@ // 'work.button.make_offer' => 'Make offer', // 'work.button.accept' => 'Accept', // 'work.button.decline' => 'Decline', +// 'work.title.send_message' => 'Sending Message', ); diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index b6123d0c2..68fdbd34a 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -695,4 +695,5 @@ // 'work.button.make_offer' => 'Make offer', // 'work.button.accept' => 'Accept', // 'work.button.decline' => 'Decline', +// 'work.title.send_message' => 'Sending Message', ); diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index c2711ab07..aeec2cc79 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -704,4 +704,5 @@ // 'work.button.make_offer' => 'Make offer', // 'work.button.accept' => 'Accept', // 'work.button.decline' => 'Decline', +// 'work.title.send_message' => 'Sending Message', ); diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index f4f231939..18c40dd69 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -725,4 +725,5 @@ // 'work.button.make_offer' => 'Make offer', // 'work.button.accept' => 'Accept', // 'work.button.decline' => 'Decline', +// 'work.title.send_message' => 'Sending Message', ); diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index 84562d7cd..692fcd208 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -628,4 +628,5 @@ 'work.button.make_offer' => 'Сделать предложение', 'work.button.accept' => 'Принять', 'work.button.decline' => 'Отклонить', +'work.title.send_message' => 'Отсылка сообщения', ); diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index 1991075d0..23bca6631 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -706,4 +706,5 @@ // 'work.button.make_offer' => 'Make offer', // 'work.button.accept' => 'Accept', // 'work.button.decline' => 'Decline', +// 'work.title.send_message' => 'Sending Message', ); diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index 4e27dcaeb..e6cb48db7 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -698,4 +698,5 @@ // 'work.button.make_offer' => 'Make offer', // 'work.button.accept' => 'Accept', // 'work.button.decline' => 'Decline', +// 'work.title.send_message' => 'Sending Message', ); diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index 68d9faac3..6d5e3876b 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -698,4 +698,5 @@ // 'work.button.make_offer' => 'Make offer', // 'work.button.accept' => 'Accept', // 'work.button.decline' => 'Decline', +// 'work.title.send_message' => 'Sending Message', ); diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index 9f9858dac..2d03e4240 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -696,4 +696,5 @@ // 'work.button.make_offer' => 'Make offer', // 'work.button.accept' => 'Accept', // 'work.button.decline' => 'Decline', +// 'work.title.send_message' => 'Sending Message', ); diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index 1bb3d793b..d9967b8bb 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -738,4 +738,5 @@ // 'work.button.make_offer' => 'Make offer', // 'work.button.accept' => 'Accept', // 'work.button.decline' => 'Decline', +// 'work.title.send_message' => 'Sending Message', ); diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index c0e9fb5bd..7b3d7f2a6 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -709,4 +709,5 @@ // 'work.button.make_offer' => 'Make offer', // 'work.button.accept' => 'Accept', // 'work.button.decline' => 'Decline', +// 'work.title.send_message' => 'Sending Message', ); diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index 37c55d4b7..dd3bde5b6 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -715,4 +715,5 @@ // 'work.button.make_offer' => 'Make offer', // 'work.button.accept' => 'Accept', // 'work.button.decline' => 'Decline', +// 'work.title.send_message' => 'Sending Message', ); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 613af6afc..2b68640b0 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.19.12.5165 | Copyright © Anuko | +  Anuko Time Tracker 1.19.12.5166 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/work_message.tpl b/WEB-INF/templates/work_message.tpl new file mode 100644 index 000000000..3f237659c --- /dev/null +++ b/WEB-INF/templates/work_message.tpl @@ -0,0 +1,32 @@ + + +{$forms.messageForm.open} + +{if $work_item} + + + +{/if} + + + +
+ + + + +
{$i18n.label.work}: {$work_item.subject}
{$i18n.label.description}: {$work_item.descr_short|escape}
{$i18n.label.budget}: {$work_item.amount_with_currency}
+
+ + + + + + + + +
{$i18n.work.label.message}:{$forms.messageForm.message_body.control}
{$forms.messageForm.btn_send.control}
+
+{$forms.messageForm.close} diff --git a/WEB-INF/templates/work_view.tpl b/WEB-INF/templates/work_view.tpl index 92614d911..468cb9ddd 100644 --- a/WEB-INF/templates/work_view.tpl +++ b/WEB-INF/templates/work_view.tpl @@ -38,6 +38,7 @@
+
diff --git a/work_message.php b/work_message.php new file mode 100644 index 000000000..1a06143e6 --- /dev/null +++ b/work_message.php @@ -0,0 +1,97 @@ +isPluginEnabled('wk')) { + header('Location: feature_disabled.php'); + exit(); +} +// Do we have work_id? +$cl_work_id = (int)$request->getParameter('work_id'); +if ($cl_work_id) { + $workHelper = new ttWorkHelper($err); + $work_item = $workHelper->getAvailableWorkItem($cl_work_id); + if (!$work_item) { + header('Location: access_denied.php'); + exit(); + } +} +// End of access checks. +if ($work_item) $cl_name = $work_item['subject']; + +if ($request->isPost()) { + $cl_message_body = trim($request->getParameter('message_body')); +} + + + + + + + + +$form = new Form('messageForm'); +if ($cl_work_id) { + $form->addInput(array('type'=>'hidden','name'=>'work_id','value'=>$cl_work_id)); +} +$form->addInput(array('type'=>'textarea','name'=>'message_body','style'=>'width: 400px; height: 80px;vertical-align: middle','value'=>$cl_message_body)); +$form->addInput(array('type'=>'submit','name'=>'btn_send','value'=>$i18n->get('work.button.send_message'))); + +if ($request->isPost()) { + // Validate user input. + if (!ttValidString($cl_message_body)) $err->add($i18n->get('error.field'), $i18n->get('work.label.message')); + + // Ensure user email exists (required for workflow). + if (!$user->getEmail()) $err->add($i18n->get('error.no_email')); + + if ($err->no()) { + $workHelper = new ttWorkHelper($err); + $fields = array('work_id'=>$cl_work_id, + 'message_body' => $cl_message_body); + if ($workHelper->sendMessage($fields)) { + $msg->add($i18n->get('work.msg.message_sent')); + // header('Location: work.php'); // TODO: where to redirect? + // exit(); + } + } +} // isPost + +$smarty->assign('work_item', $work_item); +$smarty->assign('forms', array($form->getName()=>$form->toArray())); +$smarty->assign('onload', 'onLoad="document.offerForm.work_name.focus()"'); +$smarty->assign('title', $i18n->get('work.title.send_message')); +$smarty->assign('content_page_name', 'work_message.tpl'); +$smarty->display('index.tpl'); From a9366912b9e33239b61fed09180bd4bf0063cb67 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 27 Oct 2019 13:26:42 +0000 Subject: [PATCH 169/877] Updated localization files. --- WEB-INF/resources/cs.lang.php | 1 + WEB-INF/resources/da.lang.php | 1 + WEB-INF/resources/de.lang.php | 1 + WEB-INF/resources/es.lang.php | 1 + WEB-INF/resources/et.lang.php | 1 + WEB-INF/resources/fa.lang.php | 1 + WEB-INF/resources/fi.lang.php | 1 + WEB-INF/resources/fr.lang.php | 1 + WEB-INF/resources/gr.lang.php | 1 + WEB-INF/resources/he.lang.php | 1 + WEB-INF/resources/hu.lang.php | 1 + WEB-INF/resources/it.lang.php | 1 + WEB-INF/resources/ja.lang.php | 1 + WEB-INF/resources/ko.lang.php | 1 + WEB-INF/resources/nl.lang.php | 1 + WEB-INF/resources/no.lang.php | 1 + WEB-INF/resources/pl.lang.php | 1 + WEB-INF/resources/pt-br.lang.php | 1 + WEB-INF/resources/pt.lang.php | 1 + WEB-INF/resources/ro.lang.php | 1 + WEB-INF/resources/ru.lang.php | 1 + WEB-INF/resources/sk.lang.php | 1 + WEB-INF/resources/sl.lang.php | 1 + WEB-INF/resources/sr.lang.php | 1 + WEB-INF/resources/sv.lang.php | 1 + WEB-INF/resources/tr.lang.php | 1 + WEB-INF/resources/zh-cn.lang.php | 1 + WEB-INF/resources/zh-tw.lang.php | 1 + WEB-INF/templates/footer.tpl | 2 +- 29 files changed, 29 insertions(+), 1 deletion(-) diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index a3f3c0e8d..633595e7e 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -731,4 +731,5 @@ // 'work.button.accept' => 'Accept', // 'work.button.decline' => 'Decline', // 'work.title.send_message' => 'Sending Message', +// 'work.msg.message_sent' => 'Message sent.', ); diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index 750a4dab6..bf4a88e65 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -692,4 +692,5 @@ // 'work.button.accept' => 'Accept', // 'work.button.decline' => 'Decline', // 'work.title.send_message' => 'Sending Message', +// 'work.msg.message_sent' => 'Message sent.', ); diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index ce5e07171..ee486f688 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -668,4 +668,5 @@ // 'work.button.accept' => 'Accept', // 'work.button.decline' => 'Decline', // 'work.title.send_message' => 'Sending Message', +// 'work.msg.message_sent' => 'Message sent.', ); diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index 8a967089f..53a0bd5c4 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -733,4 +733,5 @@ // 'work.button.accept' => 'Accept', // 'work.button.decline' => 'Decline', // 'work.title.send_message' => 'Sending Message', +// 'work.msg.message_sent' => 'Message sent.', ); diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index aa9afe003..562d6528f 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -699,4 +699,5 @@ // 'work.button.accept' => 'Accept', // 'work.button.decline' => 'Decline', // 'work.title.send_message' => 'Sending Message', +// 'work.msg.message_sent' => 'Message sent.', ); diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index d5e8da92c..c24d01f80 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -716,4 +716,5 @@ // 'work.button.accept' => 'Accept', // 'work.button.decline' => 'Decline', // 'work.title.send_message' => 'Sending Message', +// 'work.msg.message_sent' => 'Message sent.', ); diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 60621b769..62a542a1a 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -698,4 +698,5 @@ // 'work.button.accept' => 'Accept', // 'work.button.decline' => 'Decline', // 'work.title.send_message' => 'Sending Message', +// 'work.msg.message_sent' => 'Message sent.', ); diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index ad82e88e8..a08c65515 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -688,4 +688,5 @@ // 'work.button.accept' => 'Accept', // 'work.button.decline' => 'Decline', // 'work.title.send_message' => 'Sending Message', +// 'work.msg.message_sent' => 'Message sent.', ); diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index 25e3f5976..1b3fc2081 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -681,4 +681,5 @@ // 'work.button.accept' => 'Accept', // 'work.button.decline' => 'Decline', // 'work.title.send_message' => 'Sending Message', +// 'work.msg.message_sent' => 'Message sent.', ); diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index dd7c3bd14..a5c59998d 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -718,4 +718,5 @@ // 'work.button.accept' => 'Accept', // 'work.button.decline' => 'Decline', // 'work.title.send_message' => 'Sending Message', +// 'work.msg.message_sent' => 'Message sent.', ); diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index f566a3283..f333de5f2 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -723,4 +723,5 @@ // 'work.button.accept' => 'Accept', // 'work.button.decline' => 'Decline', // 'work.title.send_message' => 'Sending Message', +// 'work.msg.message_sent' => 'Message sent.', ); diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index 73945b376..474878f2f 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -695,4 +695,5 @@ // 'work.button.accept' => 'Accept', // 'work.button.decline' => 'Decline', // 'work.title.send_message' => 'Sending Message', +// 'work.msg.message_sent' => 'Message sent.', ); diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index f56deb6ea..ec3a4c754 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -726,4 +726,5 @@ // 'work.button.accept' => 'Accept', // 'work.button.decline' => 'Decline', // 'work.title.send_message' => 'Sending Message', +// 'work.msg.message_sent' => 'Message sent.', ); diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index ff8470e4a..bdcf6d18a 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -724,4 +724,5 @@ // 'work.button.accept' => 'Accept', // 'work.button.decline' => 'Decline', // 'work.title.send_message' => 'Sending Message', +// 'work.msg.message_sent' => 'Message sent.', ); diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 5cf619605..71c7ed4c3 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -650,4 +650,5 @@ // 'work.button.accept' => 'Accept', // 'work.button.decline' => 'Decline', // 'work.title.send_message' => 'Sending Message', +// 'work.msg.message_sent' => 'Message sent.', ); diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index 623854bc2..8ef8f168e 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -723,4 +723,5 @@ // 'work.button.accept' => 'Accept', // 'work.button.decline' => 'Decline', // 'work.title.send_message' => 'Sending Message', +// 'work.msg.message_sent' => 'Message sent.', ); diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index 98eed22b0..dd712827b 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -701,4 +701,5 @@ // 'work.button.accept' => 'Accept', // 'work.button.decline' => 'Decline', // 'work.title.send_message' => 'Sending Message', +// 'work.msg.message_sent' => 'Message sent.', ); diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index 68fdbd34a..52577c71d 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -696,4 +696,5 @@ // 'work.button.accept' => 'Accept', // 'work.button.decline' => 'Decline', // 'work.title.send_message' => 'Sending Message', +// 'work.msg.message_sent' => 'Message sent.', ); diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index aeec2cc79..195c2a773 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -705,4 +705,5 @@ // 'work.button.accept' => 'Accept', // 'work.button.decline' => 'Decline', // 'work.title.send_message' => 'Sending Message', +// 'work.msg.message_sent' => 'Message sent.', ); diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index 18c40dd69..3da5b1fb3 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -726,4 +726,5 @@ // 'work.button.accept' => 'Accept', // 'work.button.decline' => 'Decline', // 'work.title.send_message' => 'Sending Message', +// 'work.msg.message_sent' => 'Message sent.', ); diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index 692fcd208..1b753b2a3 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -629,4 +629,5 @@ 'work.button.accept' => 'Принять', 'work.button.decline' => 'Отклонить', 'work.title.send_message' => 'Отсылка сообщения', +'work.msg.message_sent' => 'Сообщение отослано.', ); diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index 23bca6631..ffbf5894b 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -707,4 +707,5 @@ // 'work.button.accept' => 'Accept', // 'work.button.decline' => 'Decline', // 'work.title.send_message' => 'Sending Message', +// 'work.msg.message_sent' => 'Message sent.', ); diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index e6cb48db7..8ecf0bcfc 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -699,4 +699,5 @@ // 'work.button.accept' => 'Accept', // 'work.button.decline' => 'Decline', // 'work.title.send_message' => 'Sending Message', +// 'work.msg.message_sent' => 'Message sent.', ); diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index 6d5e3876b..9996d9a5e 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -699,4 +699,5 @@ // 'work.button.accept' => 'Accept', // 'work.button.decline' => 'Decline', // 'work.title.send_message' => 'Sending Message', +// 'work.msg.message_sent' => 'Message sent.', ); diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index 2d03e4240..3bae63b5f 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -697,4 +697,5 @@ // 'work.button.accept' => 'Accept', // 'work.button.decline' => 'Decline', // 'work.title.send_message' => 'Sending Message', +// 'work.msg.message_sent' => 'Message sent.', ); diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index d9967b8bb..948e9ad5b 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -739,4 +739,5 @@ // 'work.button.accept' => 'Accept', // 'work.button.decline' => 'Decline', // 'work.title.send_message' => 'Sending Message', +// 'work.msg.message_sent' => 'Message sent.', ); diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index 7b3d7f2a6..a5cfe24b3 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -710,4 +710,5 @@ // 'work.button.accept' => 'Accept', // 'work.button.decline' => 'Decline', // 'work.title.send_message' => 'Sending Message', +// 'work.msg.message_sent' => 'Message sent.', ); diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index dd3bde5b6..22694ddfa 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -716,4 +716,5 @@ // 'work.button.accept' => 'Accept', // 'work.button.decline' => 'Decline', // 'work.title.send_message' => 'Sending Message', +// 'work.msg.message_sent' => 'Message sent.', ); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 2b68640b0..5f764e769 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.19.12.5166 | Copyright © Anuko | +  Anuko Time Tracker 1.19.12.5167 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From d1af7a1aa5e2fbba09f04dbcb80c2c497c490f09 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 9 Nov 2019 13:31:12 +0000 Subject: [PATCH 170/877] Resuming development of Work plugin. --- WEB-INF/resources/ca.lang.php | 1 + WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/offer_view_own.tpl | 42 +++++++++++++++ WEB-INF/templates/work.tpl | 6 +-- offer_view_own.php | 77 ++++++++++++++++++++++++++++ 5 files changed, 122 insertions(+), 6 deletions(-) create mode 100644 WEB-INF/templates/offer_view_own.tpl create mode 100644 offer_view_own.php diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index 5816fd6a6..c52298ccf 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -718,4 +718,5 @@ // 'work.button.accept' => 'Accept', // 'work.button.decline' => 'Decline', // 'work.title.send_message' => 'Sending Message', +// 'work.msg.message_sent' => 'Message sent.', ); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 5f764e769..a7cf644bb 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- {foreach $own_offers as $offer} - {if $offer.work_id} - - {else} - - {/if} + diff --git a/offer_view_own.php b/offer_view_own.php new file mode 100644 index 000000000..4f3c7b7a2 --- /dev/null +++ b/offer_view_own.php @@ -0,0 +1,77 @@ +isPluginEnabled('wk')) { + header('Location: feature_disabled.php'); + exit(); +} +if (!ttAccessAllowed('manage_work')) { + header('Location: access_denied.php'); + exit(); +} +$offer_id = (int)$request->getParameter('id'); +$workHelper = new ttWorkHelper($err); +$offer = $workHelper->getOwnOffer($offer_id); +if (!$offer) { + header('Location: access_denied.php'); + exit(); +} +// End of access checks. + +// Is this offer associated with a work item? +$work_id = $offer['work_id']; +if ($work_id) { + $work_item = $workHelper->getAvailableWorkItem($work_id); + if (!$work_item) $err->add($i18n->get('work.error.work_not_available')); +} + +$cl_name = $offer['subject']; +$cl_description = $offer['descr_short']; +$cl_details = $offer['descr_long']; +$cl_budget = $offer['amount_with_currency']; + +$form = new Form('offerForm'); +$form->addInput(array('type'=>'text','name'=>'offer_name','style'=>'width: 400px;','value'=>$cl_name)); +$form->getElement('offer_name')->setEnabled(false); +$form->addInput(array('type'=>'textarea','name'=>'description','style'=>'width: 400px; height: 80px;','value'=>$cl_description)); +$form->getElement('description')->setEnabled(false); +$form->addInput(array('type'=>'textarea','name'=>'details','style'=>'width: 400px; height: 200px;','value'=>$cl_details)); +$form->getElement('details')->setEnabled(false); +$form->addInput(array('type'=>'text','name'=>'budget','value'=>$cl_budget)); +$form->getElement('budget')->setEnabled(false); + +$smarty->assign('work_item', $work_item); +$smarty->assign('forms', array($form->getName()=>$form->toArray())); +$smarty->assign('title', $i18n->get('title.offer')); +$smarty->assign('content_page_name', 'offer_view_own.tpl'); +$smarty->display('index.tpl'); From e9f7a2a68011473764c39a2979c9ba7e190c3716 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 9 Nov 2019 15:25:21 +0000 Subject: [PATCH 171/877] Organized work plugin files into separate directorires. --- WEB-INF/templates/work/admin_offer_edit.tpl | 70 +++++++ WEB-INF/templates/work/admin_work.tpl | 104 ++++++++++ WEB-INF/templates/work/admin_work_edit.tpl | 67 +++++++ WEB-INF/templates/work/header.tpl | 207 ++++++++++++++++++++ WEB-INF/templates/work/index.tpl | 5 + WEB-INF/templates/work/offer_add.tpl | 74 +++++++ WEB-INF/templates/work/offer_delete.tpl | 20 ++ WEB-INF/templates/work/offer_edit.tpl | 67 +++++++ WEB-INF/templates/work/offer_view.tpl | 46 +++++ WEB-INF/templates/work/offer_view_own.tpl | 42 ++++ WEB-INF/templates/work/work.tpl | 140 +++++++++++++ WEB-INF/templates/work/work_add.tpl | 62 ++++++ WEB-INF/templates/work/work_delete.tpl | 20 ++ WEB-INF/templates/work/work_edit.tpl | 73 +++++++ WEB-INF/templates/work/work_message.tpl | 32 +++ WEB-INF/templates/work/work_offer_view.tpl | 57 ++++++ WEB-INF/templates/work/work_offers.tpl | 41 ++++ WEB-INF/templates/work/work_view.tpl | 47 +++++ WEB-INF/templates/work/work_view_own.tpl | 38 ++++ work/admin_offer_delete.php | 71 +++++++ work/admin_offer_edit.php | 171 ++++++++++++++++ work/admin_work.php | 53 +++++ work/admin_work_delete.php | 71 +++++++ work/admin_work_edit.php | 168 ++++++++++++++++ work/offer_add.php | 120 ++++++++++++ work/offer_delete.php | 75 +++++++ work/offer_edit.php | 135 +++++++++++++ work/offer_view.php | 81 ++++++++ work/offer_view_own.php | 77 ++++++++ work/work.php | 65 ++++++ work/work_add.php | 122 ++++++++++++ work/work_delete.php | 75 +++++++ work/work_edit.php | 151 ++++++++++++++ work/work_message.php | 97 +++++++++ work/work_offer_view.php | 123 ++++++++++++ work/work_offers.php | 56 ++++++ work/work_view.php | 74 +++++++ work/work_view_own.php | 79 ++++++++ 38 files changed, 3076 insertions(+) create mode 100644 WEB-INF/templates/work/admin_offer_edit.tpl create mode 100644 WEB-INF/templates/work/admin_work.tpl create mode 100644 WEB-INF/templates/work/admin_work_edit.tpl create mode 100644 WEB-INF/templates/work/header.tpl create mode 100644 WEB-INF/templates/work/index.tpl create mode 100644 WEB-INF/templates/work/offer_add.tpl create mode 100644 WEB-INF/templates/work/offer_delete.tpl create mode 100644 WEB-INF/templates/work/offer_edit.tpl create mode 100644 WEB-INF/templates/work/offer_view.tpl create mode 100644 WEB-INF/templates/work/offer_view_own.tpl create mode 100644 WEB-INF/templates/work/work.tpl create mode 100644 WEB-INF/templates/work/work_add.tpl create mode 100644 WEB-INF/templates/work/work_delete.tpl create mode 100644 WEB-INF/templates/work/work_edit.tpl create mode 100644 WEB-INF/templates/work/work_message.tpl create mode 100644 WEB-INF/templates/work/work_offer_view.tpl create mode 100644 WEB-INF/templates/work/work_offers.tpl create mode 100644 WEB-INF/templates/work/work_view.tpl create mode 100644 WEB-INF/templates/work/work_view_own.tpl create mode 100644 work/admin_offer_delete.php create mode 100644 work/admin_offer_edit.php create mode 100644 work/admin_work.php create mode 100644 work/admin_work_delete.php create mode 100644 work/admin_work_edit.php create mode 100644 work/offer_add.php create mode 100644 work/offer_delete.php create mode 100644 work/offer_edit.php create mode 100644 work/offer_view.php create mode 100644 work/offer_view_own.php create mode 100644 work/work.php create mode 100644 work/work_add.php create mode 100644 work/work_delete.php create mode 100644 work/work_edit.php create mode 100644 work/work_message.php create mode 100644 work/work_offer_view.php create mode 100644 work/work_offers.php create mode 100644 work/work_view.php create mode 100644 work/work_view_own.php diff --git a/WEB-INF/templates/work/admin_offer_edit.tpl b/WEB-INF/templates/work/admin_offer_edit.tpl new file mode 100644 index 000000000..bd9a6542b --- /dev/null +++ b/WEB-INF/templates/work/admin_offer_edit.tpl @@ -0,0 +1,70 @@ +{$forms.offerForm.open} +
 Anuko Time Tracker 1.19.12.5167 | Copyright © Anuko | +  Anuko Time Tracker 1.19.12.5168 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/offer_view_own.tpl b/WEB-INF/templates/offer_view_own.tpl new file mode 100644 index 000000000..d00ae7ea1 --- /dev/null +++ b/WEB-INF/templates/offer_view_own.tpl @@ -0,0 +1,42 @@ + + +{$forms.offerForm.open} + +{if $work_item} + + + +{/if} + + + + +
+ + + + +
{$i18n.label.work}: {$work_item.subject}
{$i18n.label.description}: {$work_item.descr_short|escape}
{$i18n.label.budget}: {$work_item.amount_with_currency}
+
+ + + + + + + + + + + + + + + + + +
{$i18n.label.offer}:{$forms.offerForm.offer_name.control}
{$i18n.label.description}:{$forms.offerForm.description.control}
{$i18n.label.details}:{$forms.offerForm.details.control}
{$i18n.label.budget}:{$forms.offerForm.budget.control}
+
+{$forms.offerForm.close} diff --git a/WEB-INF/templates/work.tpl b/WEB-INF/templates/work.tpl index 9c40f0304..7b00383d5 100644 --- a/WEB-INF/templates/work.tpl +++ b/WEB-INF/templates/work.tpl @@ -88,11 +88,7 @@
{$offer.subject|escape}{$offer.subject|escape}{$offer.subject|escape} {$offer.description|escape} {$offer.status_label} {$offer.amount_with_currency}
+ + + +
+ +{if $work_id} + + + + + + + + + +{/if} + + + + + + + + + + + + +{if $show_files} + + + + +{/if} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
{$i18n.label.work}:{$work_name}
{$forms.offerForm.work_description.control}
 
{$i18n.label.offer} (*):{$forms.offerForm.offer_name.control}
{$i18n.label.description}:{$forms.offerForm.description.control}
{$i18n.label.details}:{$forms.offerForm.details.control}
{$i18n.label.file}:{$forms.offerForm.newfile.control}
{$i18n.label.currency}:{$forms.offerForm.currency.control}
{$i18n.label.budget} (*):{$forms.offerForm.budget.control}
{$i18n.label.how_to_pay} (*):{$forms.offerForm.payment_info.control}
{$i18n.label.status}:{$forms.offerForm.status.control}
{$i18n.label.moderator_comment}:{$forms.offerForm.moderator_comment.control}
{$i18n.label.required_fields}
 
{$forms.offerForm.btn_approve.control} {$forms.offerForm.btn_save.control} {$forms.offerForm.btn_disapprove.control}
+
+{$forms.offerForm.close} diff --git a/WEB-INF/templates/work/admin_work.tpl b/WEB-INF/templates/work/admin_work.tpl new file mode 100644 index 000000000..39050ab3e --- /dev/null +++ b/WEB-INF/templates/work/admin_work.tpl @@ -0,0 +1,104 @@ + + + + + + +
+{if $pending_work} + + + + + + + + + + + {foreach $pending_work as $work_item} + + + + + + + + + {/foreach} +
{$i18n.title.pending_work}
{$i18n.label.work}{$i18n.label.description}{$i18n.label.client}{$i18n.label.budget}
{$work_item.subject|escape}{$work_item.description|escape}{$work_item.group_name|escape} ({$work_item.site_id}.{$work_item.group_id}){$work_item.amount_with_currency}{$i18n.label.edit}{$i18n.label.delete}
+{/if} + +
+ +{if $pending_offers} + + + + + + + + + + + {foreach $pending_offers as $offer} + + + + + + + + + {/foreach} +
{$i18n.title.pending_offers}
{$i18n.label.offer}{$i18n.label.description}{$i18n.label.contractor}{$i18n.label.budget}
{$offer.subject|escape}{$offer.description|escape}{$offer.group_name|escape} ({$offer.site_id}.{$offer.group_id}){$offer.amount_with_currency}{$i18n.label.edit}{$i18n.label.delete}
+{/if} + +
+ + + +{if $available_work} + + + + + + + {foreach $available_work as $work_item} + + + + + + + {/foreach} +{/if} +
{$i18n.title.available_work}
{$i18n.label.work}{$i18n.label.description}{$i18n.label.client}{$i18n.label.budget}
{$work_item.subject|escape}{$work_item.description|escape}{$work_item.group_name|escape}{$work_item.amount_with_currency}
+ +
+ + + +{if $available_offers} + + + + + + + {foreach $available_offers as $offer} + + + + + + + {/foreach} +{/if} +
{$i18n.title.available_offers}
{$i18n.label.offer}{$i18n.label.description}{$i18n.label.contractor}{$i18n.label.budget}
{$offer.subject|escape}{$offer.description|escape}{$offer.group_name|escape}{$offer.amount_with_currency}
+ +
diff --git a/WEB-INF/templates/work/admin_work_edit.tpl b/WEB-INF/templates/work/admin_work_edit.tpl new file mode 100644 index 000000000..1ae59a6fe --- /dev/null +++ b/WEB-INF/templates/work/admin_work_edit.tpl @@ -0,0 +1,67 @@ +{$forms.workForm.open} + +{if $offer} + + + +{/if} + + + +
+ + + + + +
{$i18n.label.offer}: {$offer.subject}
{$i18n.label.contractor}: {$offer.group_name}
{$i18n.label.description}: {$offer.descr_short|escape}
{$i18n.label.budget}: {$offer.amount_with_currency}
+
+ + + + + + + + + + + + + +{if $show_files} + + + + +{/if} + + + + + + + + + + + + + + + + + + + + + + + + + + + +
{$i18n.label.work} (*):{$forms.workForm.work_name.control}
{$i18n.label.description}:{$forms.workForm.description.control}
{$i18n.label.details}:{$forms.workForm.details.control}
{$i18n.label.file}:{$forms.workForm.newfile.control}
{$i18n.label.currency}:{$forms.workForm.currency.control}
{$i18n.label.budget} (*):{$forms.workForm.budget.control}
{$i18n.label.status}:{$forms.workForm.status.control}
{$i18n.label.moderator_comment}:{$forms.workForm.moderator_comment.control}
{$i18n.label.required_fields}
 
{$forms.workForm.btn_save.control}
+
+{$forms.workForm.close} diff --git a/WEB-INF/templates/work/header.tpl b/WEB-INF/templates/work/header.tpl new file mode 100644 index 000000000..084870958 --- /dev/null +++ b/WEB-INF/templates/work/header.tpl @@ -0,0 +1,207 @@ + + + + + + +{if $i18n.language.rtl} + +{/if} + Time Tracker{if $title} - {$title}{/if} + + + + + + + +{assign var="tab_width" value="700"} + + + +
+ + + + +{if $user->custom_logo} + + +
+{else} + +{/if} + + + + +
+ + + +{if $user->custom_logo} + +{else} + +{/if} + + +
+
+ + +{if $authenticated} + {if $user->can('administer_site')} + + + + + +
  + {$i18n.menu.logout} + {$i18n.menu.forum} + {$i18n.menu.help} +
+ + + + + + + + + + {else} + + + + + +
  + {$i18n.menu.logout} + {if $user->exists() && $user->can('manage_own_settings')} + {$i18n.menu.profile} + {/if} + {if $user->can('manage_basic_settings')} + {$i18n.menu.group} + {/if} + {if $user->can('manage_features')} + {$i18n.menu.plugins} + {/if} + {$i18n.menu.forum} + {$i18n.menu.help} +
+ + + + + + + + + + {/if} +{else} + + + + + +
  + {$i18n.menu.login} + {if isTrue('MULTIORG_MODE') && $smarty.const.AUTH_MODULE == 'db'} + {$i18n.menu.register} + {/if} + {$i18n.menu.forum} + {$i18n.menu.help} +
+{/if} +
+ + +{if $title} + + + {* No need to escape as it is done in the class. *} +
{$title}{if $timestring}: {$timestring}{/if}
{$user->getUserPartForHeader()}
+{/if} + + + +{if $err->yes()} + + + + +
+ {foreach $err->getErrors() as $error} + {$error.message}
{* No need to escape as they are not coming from user and may contain a link. *} + {/foreach} +
+{/if} + + + +{if $msg->yes()} + + + + +
+ {foreach $msg->getErrors() as $message} + {$message.message}
{* No need to escape. *} + {/foreach} +
+{/if} + diff --git a/WEB-INF/templates/work/index.tpl b/WEB-INF/templates/work/index.tpl new file mode 100644 index 000000000..6817f3963 --- /dev/null +++ b/WEB-INF/templates/work/index.tpl @@ -0,0 +1,5 @@ +{include file="work/header.tpl"} + +{if $content_page_name}{include file="$content_page_name"}{/if} + +{include file="footer.tpl"} diff --git a/WEB-INF/templates/work/offer_add.tpl b/WEB-INF/templates/work/offer_add.tpl new file mode 100644 index 000000000..80e07d803 --- /dev/null +++ b/WEB-INF/templates/work/offer_add.tpl @@ -0,0 +1,74 @@ +{$forms.offerForm.open} + +{if $work_item} + + + +{/if} + + + + +
+ + + + +
{$i18n.label.work}: {$work_item.subject}
{$i18n.label.description}: {$work_item.descr_short|escape}
{$i18n.label.budget}: {$work_item.amount_with_currency}
+
+ +{if $work_id} + + + + + + + + + +{/if} + + + + + + + + + + + + +{if $show_files} + + + + +{/if} + + + + + + + + + + + + + + + + + + + + + + + +
{$i18n.label.work}:{$work_name}
{$forms.offerForm.work_description.control}
 
{$i18n.label.offer} (*):{$forms.offerForm.offer_name.control}
{$i18n.label.description}:{$forms.offerForm.description.control}
{$i18n.label.details}:{$forms.offerForm.details.control}
{$i18n.label.file}:{$forms.offerForm.newfile.control}
{$i18n.label.currency}:{$forms.offerForm.currency.control}
{$i18n.label.budget} (*):{$forms.offerForm.budget.control} {$i18n.label.what_is_it}
{$i18n.label.how_to_pay} (*):{$forms.offerForm.payment_info.control} {$i18n.label.what_is_it}
{$i18n.label.required_fields}
 
{$forms.offerForm.btn_add.control}
+
+{$forms.offerForm.close} diff --git a/WEB-INF/templates/work/offer_delete.tpl b/WEB-INF/templates/work/offer_delete.tpl new file mode 100644 index 000000000..7d8954cfb --- /dev/null +++ b/WEB-INF/templates/work/offer_delete.tpl @@ -0,0 +1,20 @@ +{$forms.offerDeleteForm.open} + + + + +
+ + + + + + + + + + + +
{$offer_to_delete|escape}
 
{$forms.offerDeleteForm.btn_delete.control}  {$forms.offerDeleteForm.btn_cancel.control}
+
+{$forms.offerDeleteForm.close} diff --git a/WEB-INF/templates/work/offer_edit.tpl b/WEB-INF/templates/work/offer_edit.tpl new file mode 100644 index 000000000..5c1e89a33 --- /dev/null +++ b/WEB-INF/templates/work/offer_edit.tpl @@ -0,0 +1,67 @@ +{$forms.offerForm.open} + +{if $work_item} + + + +{/if} + + + + +
+ + + + +
{$i18n.label.work}: {$work_item.subject}
{$i18n.label.description}: {$work_item.descr_short|escape}
{$i18n.label.budget}: {$work_item.amount_with_currency}
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +{if $show_moderator_comment} + + + + +{/if} + + + + + + + + + + + +
{$i18n.label.offer} (*):{$forms.offerForm.offer_name.control}
{$i18n.label.description}:{$forms.offerForm.description.control}
{$i18n.label.details}:{$forms.offerForm.details.control}
{$i18n.label.currency}:{$forms.offerForm.currency.control}
{$i18n.label.budget} (*):{$forms.offerForm.budget.control} {$i18n.label.what_is_it}
{$i18n.label.how_to_pay} (*):{$forms.offerForm.payment_info.control} {$i18n.label.what_is_it}
{$i18n.label.status}:{$forms.offerForm.status.control}
{$i18n.label.moderator_comment}:{$forms.offerForm.moderator_comment.control}
{$i18n.label.required_fields}
 
{$forms.offerForm.btn_save.control}
+
+{$forms.offerForm.close} diff --git a/WEB-INF/templates/work/offer_view.tpl b/WEB-INF/templates/work/offer_view.tpl new file mode 100644 index 000000000..ad0b385f2 --- /dev/null +++ b/WEB-INF/templates/work/offer_view.tpl @@ -0,0 +1,46 @@ + + +{$forms.offerForm.open} + + + + +
+ + + + + + + + + + + + + + + + + + + + + +
{$i18n.label.contractor}:{$forms.offerForm.contractor.control}
{$i18n.label.offer}:{$forms.offerForm.offer_name.control}
{$i18n.label.description}:{$forms.offerForm.description.control}
{$i18n.label.details}:{$forms.offerForm.details.control}
{$i18n.label.budget}:{$forms.offerForm.budget.control}
+
+{$forms.offerForm.close} + + + + + +
+ + + + +
+
diff --git a/WEB-INF/templates/work/offer_view_own.tpl b/WEB-INF/templates/work/offer_view_own.tpl new file mode 100644 index 000000000..d00ae7ea1 --- /dev/null +++ b/WEB-INF/templates/work/offer_view_own.tpl @@ -0,0 +1,42 @@ + + +{$forms.offerForm.open} + +{if $work_item} + + + +{/if} + + + + +
+ + + + +
{$i18n.label.work}: {$work_item.subject}
{$i18n.label.description}: {$work_item.descr_short|escape}
{$i18n.label.budget}: {$work_item.amount_with_currency}
+
+ + + + + + + + + + + + + + + + + +
{$i18n.label.offer}:{$forms.offerForm.offer_name.control}
{$i18n.label.description}:{$forms.offerForm.description.control}
{$i18n.label.details}:{$forms.offerForm.details.control}
{$i18n.label.budget}:{$forms.offerForm.budget.control}
+
+{$forms.offerForm.close} diff --git a/WEB-INF/templates/work/work.tpl b/WEB-INF/templates/work/work.tpl new file mode 100644 index 000000000..3397dc6a1 --- /dev/null +++ b/WEB-INF/templates/work/work.tpl @@ -0,0 +1,140 @@ + + + + + + +
+{if $own_work_items} + + + + + + + + + + + + {foreach $own_work_items as $work_item} + + + + + + + {if $work_item.can_edit} + + {else} + + {/if} + {if $work_item.can_delete} + + {else} + + {/if} + + {/foreach} +
{$i18n.work.label.own_work}
{$i18n.label.work}{$i18n.label.description}{$i18n.label.status}{$i18n.work.label.offers}{$i18n.label.budget}
{$work_item.subject|escape}{$work_item.description|escape}{$work_item.status_label}{if $work_item.num_offers}{$work_item.num_offers}{/if}{$work_item.amount_with_currency}{$i18n.label.edit}{$i18n.label.delete}
+ + + + + +

+
+
+{/if} + + + +{if $available_work_items} + + + + + + + {foreach $available_work_items as $work_item} + + + + + + + {/foreach} +{/if} +
{$i18n.title.available_work}
{$i18n.label.work}{$i18n.label.description}{$i18n.label.client}{$i18n.label.budget}
{$work_item.subject|escape}{$work_item.description|escape}{$work_item.group_name|escape}{$work_item.amount_with_currency}
+ + + + + +

+
+
+ +{if $own_offers} + + + + + + + + + + + {foreach $own_offers as $offer} + + + + + + + + + {/foreach} +
{$i18n.work.label.own_offers}
{$i18n.label.offer}{$i18n.label.description}{$i18n.label.status}{$i18n.label.budget}
{$offer.subject|escape}{$offer.description|escape}{$offer.status_label}{$offer.amount_with_currency}{$i18n.label.edit}{$i18n.label.delete}
+ + + + + +

+
+
+{/if} + + + +{if $available_offers} + + + + + + + {foreach $available_offers as $offer} + + + + + + + {/foreach} +{/if} +
{$i18n.title.available_offers}
{$i18n.label.offer}{$i18n.label.description}{$i18n.label.contractor}{$i18n.label.budget}
{$offer.subject|escape}{$offer.description|escape}{$offer.group_name|escape}{$offer.amount_with_currency}
+ + + + + +

+
+
+ +
diff --git a/WEB-INF/templates/work/work_add.tpl b/WEB-INF/templates/work/work_add.tpl new file mode 100644 index 000000000..eca0ba799 --- /dev/null +++ b/WEB-INF/templates/work/work_add.tpl @@ -0,0 +1,62 @@ +{$forms.workForm.open} + +{if $offer} + + + +{/if} + + + +
+ + + + +
{$i18n.label.offer}: {$offer.subject}
{$i18n.label.description}: {$offer.descr_short|escape}
{$i18n.label.budget}: {$offer.amount_with_currency}
+
+ + + + + + + + + + + + + + + + + +{if $show_files} + + + + +{/if} + + + + + + + + + + + + + + + + + + + +
{$i18n.label.work} (*):{$forms.workForm.work_name.control}
{$i18n.label.type}:{$forms.workForm.work_type.control}
{$i18n.label.description}:{$forms.workForm.description.control}
{$i18n.label.details}:{$forms.workForm.details.control}
{$i18n.label.file}:{$forms.workForm.newfile.control}
{$i18n.label.currency}:{$forms.workForm.currency.control}
{$i18n.label.budget} (*):{$forms.workForm.budget.control} {$i18n.label.what_is_it}
{$i18n.label.required_fields}
 
{$forms.workForm.btn_add.control}
+
+{$forms.workForm.close} diff --git a/WEB-INF/templates/work/work_delete.tpl b/WEB-INF/templates/work/work_delete.tpl new file mode 100644 index 000000000..2831b0f15 --- /dev/null +++ b/WEB-INF/templates/work/work_delete.tpl @@ -0,0 +1,20 @@ +{$forms.workDeleteForm.open} + + + + +
+ + + + + + + + + + + +
{$work_to_delete|escape}
 
{$forms.workDeleteForm.btn_delete.control}  {$forms.workDeleteForm.btn_cancel.control}
+
+{$forms.workDeleteForm.close} diff --git a/WEB-INF/templates/work/work_edit.tpl b/WEB-INF/templates/work/work_edit.tpl new file mode 100644 index 000000000..7165d5e19 --- /dev/null +++ b/WEB-INF/templates/work/work_edit.tpl @@ -0,0 +1,73 @@ +{$forms.workForm.open} + +{if $offer} + + + +{/if} + + + +
+ + + + + +
{$i18n.label.offer}: {$offer.subject}
{$i18n.label.contractor}: {$offer.group_name}
{$i18n.label.description}: {$offer.descr_short|escape}
{$i18n.label.budget}: {$offer.amount_with_currency}
+
+ + + + + + + + + + + + + + + + + +{if $show_files} + + + + +{/if} + + + + + + + + + + + + +{if $show_moderator_comment} + + + + +{/if} + + + + + + + + + + + +
{$i18n.label.work} (*):{$forms.workForm.work_name.control}
{$i18n.label.type}:{$forms.workForm.work_type.control}
{$i18n.label.description}:{$forms.workForm.description.control}
{$i18n.label.details}:{$forms.workForm.details.control}
{$i18n.label.file}:{$forms.workForm.newfile.control}
{$i18n.label.currency}:{$forms.workForm.currency.control}
{$i18n.label.budget} (*):{$forms.workForm.budget.control} {$i18n.label.what_is_it}
{$i18n.label.status}:{$forms.workForm.status.control}
{$i18n.label.moderator_comment}:{$forms.workForm.moderator_comment.control}
{$i18n.label.required_fields}
 
{$forms.workForm.btn_save.control}
+
+{$forms.workForm.close} diff --git a/WEB-INF/templates/work/work_message.tpl b/WEB-INF/templates/work/work_message.tpl new file mode 100644 index 000000000..3f237659c --- /dev/null +++ b/WEB-INF/templates/work/work_message.tpl @@ -0,0 +1,32 @@ + + +{$forms.messageForm.open} + +{if $work_item} + + + +{/if} + + + +
+ + + + +
{$i18n.label.work}: {$work_item.subject}
{$i18n.label.description}: {$work_item.descr_short|escape}
{$i18n.label.budget}: {$work_item.amount_with_currency}
+
+ + + + + + + + +
{$i18n.work.label.message}:{$forms.messageForm.message_body.control}
{$forms.messageForm.btn_send.control}
+
+{$forms.messageForm.close} diff --git a/WEB-INF/templates/work/work_offer_view.tpl b/WEB-INF/templates/work/work_offer_view.tpl new file mode 100644 index 000000000..e2afe0003 --- /dev/null +++ b/WEB-INF/templates/work/work_offer_view.tpl @@ -0,0 +1,57 @@ +{$forms.offerForm.open} + +{if $work_item} + + + +{/if} + + + +
+ + + + + +
{$i18n.label.work}: {$work_item.subject}
{$i18n.label.client}: {$work_item.group_name}
{$i18n.label.description}: {$work_item.descr_short|escape}
{$i18n.label.budget}: {$work_item.amount_with_currency}
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
{$i18n.label.contractor}:{$forms.offerForm.contractor.control}
{$i18n.label.offer}:{$forms.offerForm.offer_name.control}
{$i18n.label.description}:{$forms.offerForm.description.control}
{$i18n.label.details}:{$forms.offerForm.details.control}
{$i18n.label.budget}:{$forms.offerForm.budget.control}
{$i18n.label.status}:{$forms.offerForm.status.control}
 
{$forms.offerForm.btn_accept.control} {$forms.offerForm.btn_decline.control}
{$i18n.label.comment}:{$forms.offerForm.client_comment.control}
+
+{$forms.offerForm.close} diff --git a/WEB-INF/templates/work/work_offers.tpl b/WEB-INF/templates/work/work_offers.tpl new file mode 100644 index 000000000..ea0d8816f --- /dev/null +++ b/WEB-INF/templates/work/work_offers.tpl @@ -0,0 +1,41 @@ + + + + + + + + + + +
+ + + + + +
{$i18n.label.work}: {$work_item.subject}
{$i18n.label.client}: {$work_item.group_name}
{$i18n.label.description}: {$work_item.descr_short|escape}
{$i18n.label.budget}: {$work_item.amount_with_currency}
+
+ +{if $work_item_offers} + + + + + + + + {foreach $work_item_offers as $offer} + + + + + + + {/foreach} +
{$i18n.label.contractor}{$i18n.label.description}{$i18n.label.status}{$i18n.label.budget}
{$offer.group_name|escape}{$offer.description|escape}{$offer.status_label}{$offer.amount_with_currency}
+{/if} + +
diff --git a/WEB-INF/templates/work/work_view.tpl b/WEB-INF/templates/work/work_view.tpl new file mode 100644 index 000000000..468cb9ddd --- /dev/null +++ b/WEB-INF/templates/work/work_view.tpl @@ -0,0 +1,47 @@ + + +{$forms.workForm.open} + + + + +
+ + + + + + + + + + + + + + + + + + + + + +
{$i18n.label.client}:{$forms.workForm.client.control}
{$i18n.label.work}:{$forms.workForm.work_name.control}
{$i18n.label.description}:{$forms.workForm.description.control}
{$i18n.label.details}:{$forms.workForm.details.control}
{$i18n.label.budget}:{$forms.workForm.budget.control}
+
+{$forms.workForm.close} + + + + + +
+ + + + + +
+
diff --git a/WEB-INF/templates/work/work_view_own.tpl b/WEB-INF/templates/work/work_view_own.tpl new file mode 100644 index 000000000..61e270b4b --- /dev/null +++ b/WEB-INF/templates/work/work_view_own.tpl @@ -0,0 +1,38 @@ +{$forms.workForm.open} + +{if $offer} + + + +{/if} + + + +
+ + + + + +
{$i18n.label.offer}: {$offer.subject}
{$i18n.label.contractor}: {$offer.group_name}
{$i18n.label.description}: {$offer.descr_short|escape}
{$i18n.label.budget}: {$offer.amount_with_currency}
+
+ + + + + + + + + + + + + + + + + +
{$i18n.label.work}:{$forms.workForm.work_name.control}
{$i18n.label.description}:{$forms.workForm.description.control}
{$i18n.label.details}:{$forms.workForm.details.control}
{$i18n.label.budget}:{$forms.workForm.budget.control}
+
+{$forms.workForm.close} diff --git a/work/admin_offer_delete.php b/work/admin_offer_delete.php new file mode 100644 index 000000000..51c46fce3 --- /dev/null +++ b/work/admin_offer_delete.php @@ -0,0 +1,71 @@ +getParameter('id'); +$adminWorkHelper = new ttAdminWorkHelper($err); +$offer = $adminWorkHelper->getOffer($cl_offer_id); +if (!$offer) { + header('Location: access_denied.php'); + exit(); +} +// End of access checks. + +$offer_to_delete = $offer['subject']; + +$form = new Form('offerDeleteForm'); +$form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_offer_id)); +$form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->get('label.delete'))); +$form->addInput(array('type'=>'submit','name'=>'btn_cancel','value'=>$i18n->get('button.cancel'))); + +if ($request->isPost()) { + if ($request->getParameter('btn_delete')) { + if ($adminWorkHelper->deleteOffer($cl_offer_id)) { + header('Location: admin_work.php'); + exit(); + } + } elseif ($request->getParameter('btn_cancel')) { + header('Location: admin_work.php'); + exit(); + } +} // isPost + +$smarty->assign('offer_to_delete', $offer_to_delete); +$smarty->assign('forms', array($form->getName()=>$form->toArray())); +$smarty->assign('onload', 'onLoad="document.offerDeleteForm.btn_cancel.focus()"'); +$smarty->assign('title', $i18n->get('title.delete_offer')); +$smarty->assign('content_page_name', 'work/offer_delete.tpl'); +$smarty->display('work/index.tpl'); diff --git a/work/admin_offer_edit.php b/work/admin_offer_edit.php new file mode 100644 index 000000000..32ed2a8ed --- /dev/null +++ b/work/admin_offer_edit.php @@ -0,0 +1,171 @@ +getParameter('id'); +$adminWorkHelper = new ttAdminWorkHelper($err); +$offer = $adminWorkHelper->getOffer($cl_offer_id); +if (!$offer) { + header('Location: access_denied.php'); + exit(); +} +// End of access checks. + +// Is this offer associated with a work item? +$work_id = $offer['work_id']; +if ($work_id) { + $work_item = $adminWorkHelper->getWorkItem($work_id); + if (!$work_item) $err->add($i18n->get('work.error.work_not_available')); +} + +$existingStatus = $offer['status']; +$currencies = ttWorkHelper::getCurrencies(); + +if ($request->isPost()) { + $cl_name = trim($request->getParameter('offer_name')); + $cl_description = trim($request->getParameter('description')); + $cl_details = trim($request->getParameter('details')); + $cl_currency_id = $request->getParameter('currency'); + if (!$cl_currency_id && $work_item) $cl_currency_id = ttWorkHelper::getCurrencyID($work_item['currency']); + $cl_budget = $request->getParameter('budget'); + $cl_payment_info = $request->getParameter('payment_info'); + // $cl_status = $request->getParameter('status'); + $cl_moderator_comment = $request->getParameter('moderator_comment'); +} else { + $cl_name = $offer['subject']; + $cl_description = $offer['descr_short']; + $cl_details = $offer['descr_long']; + $currency = $offer['currency']; + $cl_currency_id = ttWorkHelper::getCurrencyID($offer['currency']); + $cl_budget = $offer['amount']; + $cl_payment_info = $offer['payment_info']; + $status = $offer['status']; + $status_label = $offer['status_label']; + $cl_moderator_comment = $offer['moderator_comment']; +} + +$form = new Form('offerForm'); +$form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_offer_id)); +if ($work_id) { + $form->addInput(array('type'=>'textarea','name'=>'work_description','style'=>'width: 400px; height: 80px;','value'=>$work_item['descr_short'])); + $form->getElement('work_description')->setEnabled(false); +} +$form->addInput(array('type'=>'text','name'=>'offer_name','style'=>'width: 400px;','value'=>$cl_name)); +if ($work_id) $form->getElement('offer_name')->setEnabled(false); +$form->addInput(array('type'=>'textarea','name'=>'description','maxlength'=>'512','style'=>'width: 400px; height: 80px;','value'=>$cl_description)); +$form->addInput(array('type'=>'textarea','name'=>'details','style'=>'width: 400px; height: 200px;','value'=>$cl_details)); +$form->addInput(array('type'=>'combobox','name'=>'currency','data'=>$currencies,'datakeys'=>array('id','name'),'value'=>$cl_currency_id)); +if ($work_id) $form->getElement('currency')->setEnabled(false); +$form->addInput(array('type'=>'floatfield','maxlength'=>'10','name'=>'budget','format'=>'.2','value'=>$cl_budget)); +$form->addInput(array('type'=>'textarea','name'=>'payment_info','maxlength'=>'256','style'=>'width: 400px; height: 40px;vertical-align: middle','value'=>$cl_payment_info)); +$form->addInput(array('type'=>'text','name'=>'status','style'=>'width: 400px;','value'=>$status_label)); +$form->getElement('status')->setEnabled(false); + +// Prepare status choices. +/* +$status_options = array(); +$status_options[STATUS_PENDING_APPROVAL] = $i18n->get('dropdown.pending_approval'); +$status_options[STATUS_DISAPPROVED] = $i18n->get('dropdown.not_approved'); +$status_options[STATUS_APPROVED] = $i18n->get('dropdown.approved'); + +$form->addInput(array('type'=>'combobox','name'=>'status','value'=>$cl_status,'data'=>$status_options)); +*/ +$form->addInput(array('type'=>'textarea','name'=>'moderator_comment','style'=>'width: 400px; height: 80px;','value'=>$cl_moderator_comment)); +$form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); +if ($status == STATUS_PENDING_APPROVAL) { + $form->addInput(array('type'=>'submit','name'=>'btn_approve','value'=>$i18n->get('button.approve'))); + $form->addInput(array('type'=>'submit','name'=>'btn_disapprove','value'=>$i18n->get('button.disapprove'))); +} + +if ($request->isPost()) { + // Validate user input. + if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.work')); + if (!ttValidString($cl_description, true)) $err->add($i18n->get('error.field'), $i18n->get('label.description')); + if (!ttValidString($cl_details, true)) $err->add($i18n->get('error.field'), $i18n->get('label.details')); + if (!ttValidString($cl_budget)) $err->add($i18n->get('error.field'), $i18n->get('label.budget')); + if (!ttValidString($cl_payment_info)) $err->add($i18n->get('error.field'), $i18n->get('label.how_to_pay')); + if (!ttValidString($cl_moderator_comment, true)) $err->add($i18n->get('error.field'), $i18n->get('label.moderator_comment')); + + // Ensure user email exists (required for workflow). + if (!$user->getEmail()) $err->add($i18n->get('error.no_email')); + + $fields = array('offer_id'=>$cl_offer_id, + 'subject'=>$cl_name, + 'descr_short' => $cl_description, + 'descr_long' => $cl_details, + 'currency' => ttWorkHelper::getCurrencyName($cl_currency_id), + 'amount' => $cl_budget, + 'payment_info' => $cl_payment_info, + 'moderator_comment' => $cl_moderator_comment); + + if ($err->no()) { + if ($request->getParameter('btn_approve')) { + // Approve offer. + if ($adminWorkHelper->approveOffer($fields)) { + header('Location: admin_work.php'); + exit(); + } + } + + if ($request->getParameter('btn_save')) { + // Update offer without changing its status. + if ($adminWorkHelper->updateOffer($fields)) { + header('Location: admin_work.php'); + exit(); + } + } + + if ($request->getParameter('btn_disapprove')) { + // Dispprove offer. + if ($adminWorkHelper->disapproveOffer($fields)) { + header('Location: admin_work.php'); + exit(); + } + } + } +} // isPost + +if ($work_id) { + $smarty->assign('work_id', $work_id); + $smarty->assign('work_name', $work_item['subject']); + $smarty->assign('work_description', $work_item['descr_short']); +} +$smarty->assign('forms', array($form->getName()=>$form->toArray())); +$smarty->assign('title', $i18n->get('title.edit_offer')); +$smarty->assign('content_page_name', 'work/admin_offer_edit.tpl'); +$smarty->display('work/index.tpl'); diff --git a/work/admin_work.php b/work/admin_work.php new file mode 100644 index 000000000..19b420987 --- /dev/null +++ b/work/admin_work.php @@ -0,0 +1,53 @@ +getItems(); +$pending_work = $adminItems['pending_work']; +$pending_offers = $adminItems['pending_offers']; +$available_work = $adminItems['available_work']; +$available_offers = $adminItems['available_offers']; + +$smarty->assign('pending_work', $pending_work); +$smarty->assign('pending_offers', $pending_offers); +$smarty->assign('available_work', $available_work); +$smarty->assign('available_offers', $available_offers); +$smarty->assign('title', $i18n->get('title.work')); +$smarty->assign('content_page_name', 'work/admin_work.tpl'); +$smarty->display('work/index.tpl'); diff --git a/work/admin_work_delete.php b/work/admin_work_delete.php new file mode 100644 index 000000000..38084e565 --- /dev/null +++ b/work/admin_work_delete.php @@ -0,0 +1,71 @@ +getParameter('id'); +$adminWorkHelper = new ttAdminWorkHelper($err); +$work_item = $adminWorkHelper->getWorkItem($cl_work_id); +if (!$work_item) { + header('Location: access_denied.php'); + exit(); +} +// End of access checks. + +$work_to_delete = $work_item['subject']; + +$form = new Form('workDeleteForm'); +$form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_work_id)); +$form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->get('label.delete'))); +$form->addInput(array('type'=>'submit','name'=>'btn_cancel','value'=>$i18n->get('button.cancel'))); + +if ($request->isPost()) { + if ($request->getParameter('btn_delete')) { + if ($adminWorkHelper->deleteWorkItem($cl_work_id)) { + header('Location: admin_work.php'); + exit(); + } + } elseif ($request->getParameter('btn_cancel')) { + header('Location: admin_work.php'); + exit(); + } +} // isPost + +$smarty->assign('work_to_delete', $work_to_delete); +$smarty->assign('forms', array($form->getName()=>$form->toArray())); +$smarty->assign('onload', 'onLoad="document.workDeleteForm.btn_cancel.focus()"'); +$smarty->assign('title', $i18n->get('title.delete_work')); +$smarty->assign('content_page_name', 'work/work_delete.tpl'); +$smarty->display('work/index.tpl'); diff --git a/work/admin_work_edit.php b/work/admin_work_edit.php new file mode 100644 index 000000000..626b1a77e --- /dev/null +++ b/work/admin_work_edit.php @@ -0,0 +1,168 @@ +getParameter('id'); +$adminWorkHelper = new ttAdminWorkHelper($err); +$work_item = $adminWorkHelper->getWorkItem($cl_work_id); +if (!$work_item) { + header('Location: access_denied.php'); + exit(); +} +// Do we have offer_id? +$offer_id = $work_item['offer_id']; +if ($offer_id) { + $offer = $adminWorkHelper->getOffer($offer_id); + if (!$offer) { + header('Location: access_denied.php'); + exit(); + } +} +// End of access checks. + +$existingStatus = $work_item['status']; +$currencies = ttWorkHelper::getCurrencies(); + +if ($request->isPost()) { + $cl_name = trim($request->getParameter('work_name')); + $cl_description = trim($request->getParameter('description')); + $cl_details = trim($request->getParameter('details')); + $cl_currency_id = $request->getParameter('currency'); + $cl_budget = $request->getParameter('budget'); + $cl_status = $request->getParameter('status'); + $cl_moderator_comment = $request->getParameter('moderator_comment'); +} else { + $cl_name = $work_item['subject']; + $cl_description = $work_item['descr_short']; + $cl_details = $work_item['descr_long']; + $currency = $work_item['currency']; + $cl_currency_id = ttWorkHelper::getCurrencyID($work_item['currency']); + $cl_budget = $work_item['amount']; + $cl_status = $work_item['status']; + $cl_moderator_comment = $work_item['moderator_comment']; +} + +$form = new Form('workForm'); +$form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_work_id)); +$form->addInput(array('type'=>'text','name'=>'work_name','maxlength'=>'128','style'=>'width: 400px;','value'=>$cl_name)); +$form->addInput(array('type'=>'textarea','name'=>'description','maxlength'=>'512','style'=>'width: 400px; height: 80px;','value'=>$cl_description)); +$form->addInput(array('type'=>'textarea','name'=>'details','style'=>'width: 400px; height: 200px;','value'=>$cl_details)); +$form->addInput(array('type'=>'combobox','name'=>'currency','data'=>$currencies,'datakeys'=>array('id','name'),'value'=>$cl_currency_id)); +$form->addInput(array('type'=>'floatfield','maxlength'=>'10','name'=>'budget','format'=>'.2','value'=>$cl_budget)); +// Disable some controls for work on an available offer. +if ($offer) { + $form->getElement('work_name')->setEnabled(false); + // $form->getElement('work_type')->setEnabled(false); + $form->getElement('currency')->setEnabled(false); + $form->getElement('budget')->setEnabled(false); +} + +// Prepare status choices. +$status_options = array(); +$status_options[STATUS_PENDING_APPROVAL] = $i18n->get('dropdown.pending_approval'); +$status_options[STATUS_DISAPPROVED] = $i18n->get('dropdown.not_approved'); +$status_options[STATUS_APPROVED] = $i18n->get('dropdown.approved'); + +$form->addInput(array('type'=>'combobox','name'=>'status','value'=>$cl_status,'data'=>$status_options)); +$form->addInput(array('type'=>'textarea','name'=>'moderator_comment','style'=>'width: 400px; height: 80px;','value'=>$cl_moderator_comment)); +$form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); + +if ($request->isPost()) { + // Validate user input. + if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.work')); + if (!ttValidString($cl_description, true)) $err->add($i18n->get('error.field'), $i18n->get('label.description')); + if (!ttValidString($cl_details, true)) $err->add($i18n->get('error.field'), $i18n->get('label.details')); + if (!ttValidString($cl_budget)) $err->add($i18n->get('error.field'), $i18n->get('label.budget')); + if (!ttValidString($cl_moderator_comment, true)) $err->add($i18n->get('error.field'), $i18n->get('label.moderator_comment')); + + // Ensure user email exists (required for workflow). + if (!$user->getEmail()) $err->add($i18n->get('error.no_email')); + + if ($err->no()) { + if ($request->getParameter('btn_save')) { + $fields = array('work_id'=>$cl_work_id, + 'subject'=>$cl_name, + 'descr_short' => $cl_description, + 'descr_long' => $cl_details, + 'currency' => ttWorkHelper::getCurrencyName($cl_currency_id), + 'amount' => $cl_budget, + 'moderator_comment' => $cl_moderator_comment); + + // Do things differently, depending on status control value. + if ($existingStatus == $cl_status) { + // Status not changed. Update work information. + if ($adminWorkHelper->updateWorkItem($fields)) { + header('Location: admin_work.php'); + exit(); + } + } else if ($cl_status == STATUS_DISAPPROVED) { + // Status changed to "not approved". Disapprove work. + if ($offer_id) { + if ($adminWorkHelper->disapproveWorkItemOnOffer($fields)) { + header('Location: admin_work.php'); + exit(); + } + } else { + if ($adminWorkHelper->disapproveWorkItem($fields)) { + header('Location: admin_work.php'); + exit(); + } + } + } else if ($cl_status == STATUS_APPROVED) { + // Status changed to "approved". Approve work. + if ($offer_id) { + if ($adminWorkHelper->approveWorkItemOnOffer($fields)) { + header('Location: admin_work.php'); + exit(); + } + } else { + if ($adminWorkHelper->approveWorkItem($fields)) { + header('Location: admin_work.php'); + exit(); + } + } + } + } + } +} // isPost + +$smarty->assign('offer', $offer); +$smarty->assign('forms', array($form->getName()=>$form->toArray())); +$smarty->assign('title', $i18n->get('title.edit_work')); +$smarty->assign('content_page_name', 'work/admin_work_edit.tpl'); +$smarty->display('work/index.tpl'); diff --git a/work/offer_add.php b/work/offer_add.php new file mode 100644 index 000000000..159bc3241 --- /dev/null +++ b/work/offer_add.php @@ -0,0 +1,120 @@ +isPluginEnabled('wk')) { + header('Location: feature_disabled.php'); + exit(); +} +// Do we have work_id? +$cl_work_id = (int)$request->getParameter('work_id'); +if ($cl_work_id) { + $workHelper = new ttWorkHelper($err); + $work_item = $workHelper->getAvailableWorkItem($cl_work_id); + if (!$work_item) { + header('Location: access_denied.php'); + exit(); + } +} +// End of access checks. +if ($work_item) $cl_name = $work_item['subject']; + +if ($request->isPost()) { + if (!$work_item) + $cl_name = trim($request->getParameter('offer_name')); + $cl_description = trim($request->getParameter('description')); + $cl_details = trim($request->getParameter('details')); + $cl_currency_id = $request->getParameter('currency'); + if (!$cl_currency_id && $work_item) $cl_currency_id = ttWorkHelper::getCurrencyID($work_item['currency']); + $cl_budget = $request->getParameter('budget'); + $cl_payment_info = $request->getParameter('payment_info'); +} else { + if ($work_item) { + $cl_currency_id = ttWorkHelper::getCurrencyID($work_item['currency']); + } +} + +$form = new Form('offerForm'); +if ($cl_work_id) { + $form->addInput(array('type'=>'hidden','name'=>'work_id','value'=>$cl_work_id)); + $form->addInput(array('type'=>'textarea','name'=>'work_description','style'=>'width: 400px; height: 80px;','value'=>$work_item['descr_short'])); + $form->getElement('work_description')->setEnabled(false); +} +$form->addInput(array('type'=>'text','name'=>'offer_name','maxlength'=>'128','style'=>'width: 400px;','value'=>$cl_name)); +if ($work_item) $form->getElement('offer_name')->setEnabled(false); +$form->addInput(array('type'=>'textarea','name'=>'description','maxlength'=>'512','style'=>'width: 400px; height: 80px;','value'=>$cl_description)); +$form->addInput(array('type'=>'textarea','name'=>'details','style'=>'width: 400px; height: 200px;','value'=>$cl_details)); +// Add a dropdown for currency. +$currencies = ttWorkHelper::getCurrencies(); +$form->addInput(array('type'=>'combobox','name'=>'currency','data'=>$currencies,'datakeys'=>array('id','name'),'value'=>$cl_currency_id)); +if ($work_item) $form->getElement('currency')->setEnabled(false); // Do not allow changing currency for offers on existing work items. +$form->addInput(array('type'=>'floatfield','maxlength'=>'10','name'=>'budget','format'=>'.2','value'=>$cl_budget)); +$form->addInput(array('type'=>'textarea','name'=>'payment_info','maxlength'=>'256','style'=>'width: 400px; height: 40px;vertical-align: middle','value'=>$cl_payment_info)); +$form->addInput(array('type'=>'submit','name'=>'btn_add','value'=>$i18n->get('button.add'))); + +if ($request->isPost()) { + // Validate user input. + if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.offer')); + if (!ttValidString($cl_description, true)) $err->add($i18n->get('error.field'), $i18n->get('label.description')); + if (!ttValidString($cl_details, true)) $err->add($i18n->get('error.field'), $i18n->get('label.details')); + if (!ttValidString($cl_budget)) $err->add($i18n->get('error.field'), $i18n->get('label.budget')); + if (!ttValidString($cl_payment_info)) $err->add($i18n->get('error.field'), $i18n->get('label.how_to_pay')); + + // Ensure user email exists (required for workflow). + if (!$user->getEmail()) $err->add($i18n->get('error.no_email')); + + if ($err->no()) { + $workHelper = new ttWorkHelper($err); + $fields = array('work_id'=>$cl_work_id, + 'subject'=>$cl_name, + 'descr_short' => $cl_description, + 'descr_long' => $cl_details, + 'currency' => ttWorkHelper::getCurrencyName($cl_currency_id), + 'amount' => $cl_budget, + 'payment_info' => $cl_payment_info); + if ($workHelper->putOwnOffer($fields)) { + header('Location: work.php'); + exit(); + } + } +} // isPost + +$smarty->assign('work_item', $work_item); +$smarty->assign('forms', array($form->getName()=>$form->toArray())); +$smarty->assign('onload', 'onLoad="document.offerForm.work_name.focus()"'); +$smarty->assign('title', $i18n->get('title.add_offer')); +$smarty->assign('content_page_name', 'work/offer_add.tpl'); +$smarty->display('work/index.tpl'); diff --git a/work/offer_delete.php b/work/offer_delete.php new file mode 100644 index 000000000..c8772599a --- /dev/null +++ b/work/offer_delete.php @@ -0,0 +1,75 @@ +isPluginEnabled('wk')) { + header('Location: feature_disabled.php'); + exit(); +} +$cl_offer_id = (int)$request->getParameter('id'); +$workHelper = new ttWorkHelper($err); +$offer = $workHelper->getOwnOffer($cl_offer_id); +if (!$offer) { + header('Location: access_denied.php'); + exit(); +} +// End of access checks. + +$offer_to_delete = $offer['subject']; + +$form = new Form('offerDeleteForm'); +$form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_offer_id)); +$form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->get('label.delete'))); +$form->addInput(array('type'=>'submit','name'=>'btn_cancel','value'=>$i18n->get('button.cancel'))); + +if ($request->isPost()) { + if ($request->getParameter('btn_delete')) { + if ($workHelper->deleteOwnOffer($cl_offer_id)) { + header('Location: work.php'); + exit(); + } + } elseif ($request->getParameter('btn_cancel')) { + header('Location: work.php'); + exit(); + } +} // isPost + +$smarty->assign('offer_to_delete', $offer_to_delete); +$smarty->assign('forms', array($form->getName()=>$form->toArray())); +$smarty->assign('onload', 'onLoad="document.offerDeleteForm.btn_cancel.focus()"'); +$smarty->assign('title', $i18n->get('title.delete_offer')); +$smarty->assign('content_page_name', 'work/offer_delete.tpl'); +$smarty->display('work/index.tpl'); diff --git a/work/offer_edit.php b/work/offer_edit.php new file mode 100644 index 000000000..5eba66378 --- /dev/null +++ b/work/offer_edit.php @@ -0,0 +1,135 @@ +isPluginEnabled('wk')) { + header('Location: feature_disabled.php'); + exit(); +} +$cl_offer_id = (int)$request->getParameter('id'); +$workHelper = new ttWorkHelper($err); +$offer = $workHelper->getOwnOffer($cl_offer_id); +if (!$offer) { + header('Location: access_denied.php'); + exit(); +} +// End of access checks. + +// Is this offer associated with a work item? +$work_id = $offer['work_id']; +if ($work_id) { + $work_item = $workHelper->getAvailableWorkItem($work_id); + if (!$work_item) $err->add($i18n->get('work.error.work_not_available')); +} + +$currencies = ttWorkHelper::getCurrencies(); + +if ($request->isPost()) { + $cl_name = trim($request->getParameter('offer_name')); + $cl_description = trim($request->getParameter('description')); + $cl_details = trim($request->getParameter('details')); + $cl_currency_id = $request->getParameter('currency'); + if (!$cl_currency_id && $work_item) $cl_currency_id = ttWorkHelper::getCurrencyID($work_item['currency']); + $cl_budget = $request->getParameter('budget'); + $cl_payment_info = $request->getParameter('payment_info'); +} else { + $cl_name = $offer['subject']; + $cl_description = $offer['descr_short']; + $cl_details = $offer['descr_long']; + $cl_currency_id = ttWorkHelper::getCurrencyID($offer['currency']); + $cl_budget = $offer['amount']; + $cl_payment_info = $offer['payment_info']; + $cl_status = $offer['status_label']; + $cl_moderator_comment = $offer['moderator_comment']; +} + +$show_moderator_comment = $cl_moderator_comment != null; + +$form = new Form('offerForm'); +$form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_offer_id)); +if ($work_id) { + $form->addInput(array('type'=>'textarea','name'=>'work_description','style'=>'width: 400px; height: 80px;','value'=>$work_item['descr_short'])); + $form->getElement('work_description')->setEnabled(false); +} +$form->addInput(array('type'=>'text','name'=>'offer_name','maxlength'=>'128','style'=>'width: 400px;','value'=>$cl_name)); +if ($work_id) $form->getElement('offer_name')->setEnabled(false); +$form->addInput(array('type'=>'textarea','name'=>'description','maxlength'=>'512','style'=>'width: 400px; height: 80px;','value'=>$cl_description)); +$form->addInput(array('type'=>'textarea','name'=>'details','style'=>'width: 400px; height: 200px;','value'=>$cl_details)); +$form->addInput(array('type'=>'combobox','name'=>'currency','data'=>$currencies,'datakeys'=>array('id','name'),'value'=>$cl_currency_id)); +if ($work_id) $form->getElement('currency')->setEnabled(false); +$form->addInput(array('type'=>'floatfield','maxlength'=>'10','name'=>'budget','format'=>'.2','value'=>$cl_budget)); +$form->addInput(array('type'=>'textarea','name'=>'payment_info','maxlength'=>'256','style'=>'width: 400px; height: 40px; vertical-align: middle','value'=>$cl_payment_info)); +$form->addInput(array('type'=>'text','name'=>'status','style'=>'width: 400px;','value'=>$cl_status)); +$form->getElement('status')->setEnabled(false); +$form->addInput(array('type'=>'textarea','name'=>'moderator_comment','style'=>'width: 400px; height: 80px;','value'=>$cl_moderator_comment)); +$form->getElement('moderator_comment')->setEnabled(false); +$form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); + +if ($request->isPost()) { + // Validate user input. + if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.offer')); + if (!ttValidString($cl_description, true)) $err->add($i18n->get('error.field'), $i18n->get('label.description')); + if (!ttValidString($cl_details, true)) $err->add($i18n->get('error.field'), $i18n->get('label.details')); + if (!ttValidString($cl_budget)) $err->add($i18n->get('error.field'), $i18n->get('label.budget')); + if (!ttValidString($cl_payment_info)) $err->add($i18n->get('error.field'), $i18n->get('label.how_to_pay')); + + // Ensure user email exists (required for workflow). + if (!$user->getEmail()) $err->add($i18n->get('error.no_email')); + + if ($err->no()) { + if ($request->getParameter('btn_save')) { + // Update offer information. + $fields = array('offer_id'=>$cl_offer_id, + 'subject'=>$cl_name, + 'descr_short' => $cl_description, + 'descr_long' => $cl_details, + 'currency' => ttWorkHelper::getCurrencyName($cl_currency_id), + 'amount' => $cl_budget, + 'payment_info' => $cl_payment_info); + if ($workHelper->updateOwnOffer($fields)) { + header('Location: work.php'); + exit(); + } + } + } +} // isPost + +$smarty->assign('work_item', $work_item); +$smarty->assign('show_moderator_comment', $show_moderator_comment); +$smarty->assign('forms', array($form->getName()=>$form->toArray())); +$smarty->assign('title', $i18n->get('title.edit_offer')); +$smarty->assign('content_page_name', 'work/offer_edit.tpl'); +$smarty->display('work/index.tpl'); diff --git a/work/offer_view.php b/work/offer_view.php new file mode 100644 index 000000000..614b93188 --- /dev/null +++ b/work/offer_view.php @@ -0,0 +1,81 @@ +isPluginEnabled('wk')) { + header('Location: feature_disabled.php'); + exit(); +} +if (!ttAccessAllowed('manage_work')) { + header('Location: access_denied.php'); + exit(); +} +$offer_id = (int)$request->getParameter('id'); +$workHelper = new ttWorkHelper($err); +$offer = $workHelper->getAvailableOffer($offer_id); +if (!$offer) { + header('Location: access_denied.php'); + exit(); +} +// End of access checks. + +// Is this offer associated with a work item? +$work_id = $offer['work_id']; +if ($work_id) { + $work_item = $workHelper->getAvailableWorkItem($work_id); + if (!$work_item) $err->add($i18n->get('work.error.work_not_available')); +} + +$cl_contractor = $offer['group_name']; +$cl_name = $offer['subject']; +$cl_description = $offer['descr_short']; +$cl_details = $offer['descr_long']; +$cl_budget = $offer['amount_with_currency']; + +$form = new Form('offerForm'); +$form->addInput(array('type'=>'text','name'=>'contractor','value'=>$cl_contractor)); +$form->getElement('contractor')->setEnabled(false); +$form->addInput(array('type'=>'text','name'=>'offer_name','style'=>'width: 400px;','value'=>$cl_name)); +$form->getElement('offer_name')->setEnabled(false); +$form->addInput(array('type'=>'textarea','name'=>'description','style'=>'width: 400px; height: 80px;','value'=>$cl_description)); +$form->getElement('description')->setEnabled(false); +$form->addInput(array('type'=>'textarea','name'=>'details','style'=>'width: 400px; height: 200px;','value'=>$cl_details)); +$form->getElement('details')->setEnabled(false); +$form->addInput(array('type'=>'text','name'=>'budget','value'=>$cl_budget)); +$form->getElement('budget')->setEnabled(false); + + +$smarty->assign('offer_id', $offer_id); +$smarty->assign('forms', array($form->getName()=>$form->toArray())); +$smarty->assign('title', $i18n->get('title.offer')); +$smarty->assign('content_page_name', 'work/offer_view.tpl'); +$smarty->display('work/index.tpl'); diff --git a/work/offer_view_own.php b/work/offer_view_own.php new file mode 100644 index 000000000..c87013d08 --- /dev/null +++ b/work/offer_view_own.php @@ -0,0 +1,77 @@ +isPluginEnabled('wk')) { + header('Location: feature_disabled.php'); + exit(); +} +if (!ttAccessAllowed('manage_work')) { + header('Location: access_denied.php'); + exit(); +} +$offer_id = (int)$request->getParameter('id'); +$workHelper = new ttWorkHelper($err); +$offer = $workHelper->getOwnOffer($offer_id); +if (!$offer) { + header('Location: access_denied.php'); + exit(); +} +// End of access checks. + +// Is this offer associated with a work item? +$work_id = $offer['work_id']; +if ($work_id) { + $work_item = $workHelper->getAvailableWorkItem($work_id); + if (!$work_item) $err->add($i18n->get('work.error.work_not_available')); +} + +$cl_name = $offer['subject']; +$cl_description = $offer['descr_short']; +$cl_details = $offer['descr_long']; +$cl_budget = $offer['amount_with_currency']; + +$form = new Form('offerForm'); +$form->addInput(array('type'=>'text','name'=>'offer_name','style'=>'width: 400px;','value'=>$cl_name)); +$form->getElement('offer_name')->setEnabled(false); +$form->addInput(array('type'=>'textarea','name'=>'description','style'=>'width: 400px; height: 80px;','value'=>$cl_description)); +$form->getElement('description')->setEnabled(false); +$form->addInput(array('type'=>'textarea','name'=>'details','style'=>'width: 400px; height: 200px;','value'=>$cl_details)); +$form->getElement('details')->setEnabled(false); +$form->addInput(array('type'=>'text','name'=>'budget','value'=>$cl_budget)); +$form->getElement('budget')->setEnabled(false); + +$smarty->assign('work_item', $work_item); +$smarty->assign('forms', array($form->getName()=>$form->toArray())); +$smarty->assign('title', $i18n->get('title.offer')); +$smarty->assign('content_page_name', 'work/offer_view_own.tpl'); +$smarty->display('work/index.tpl'); diff --git a/work/work.php b/work/work.php new file mode 100644 index 000000000..4f40e4ca9 --- /dev/null +++ b/work/work.php @@ -0,0 +1,65 @@ +isPluginEnabled('wk')) { + header('Location: feature_disabled.php'); + exit(); +} +// End of access checks. + +$workHelper = new ttWorkHelper($err); +$groupItems = $workHelper->getGroupItems(); // All group items. +if($user->can('manage_work')) { + $own_work_items = $groupItems['own_work_items']; // Own work items this group is outsourcing. + $available_offers = $groupItems['available_offers']; // Available offers from other organizations. +} +if($user->can('bid_on_work')) { + $available_work_items = $groupItems['available_work_items']; // Currently available work items from other orgs. + $own_offers = $groupItems['own_offers']; // Own offers this group makes available to other groups. +} +if($user->can('update_work')) { + // $in_progress_work = ttWorkHelper::getInProgressWork(); // Work items in progress for other groups. + // $completed_work = ttWorkHelper::getCompletedWork(); // Completed work items for other groups. +} +// TODO: review access rights for the code above. + +$smarty->assign('own_work_items', $own_work_items); +$smarty->assign('available_work_items', $available_work_items); +$smarty->assign('own_offers', $own_offers); +$smarty->assign('available_offers', $available_offers); +$smarty->assign('title', $i18n->get('title.work')); +$smarty->assign('content_page_name', 'work/work.tpl'); +$smarty->display('work/index.tpl'); diff --git a/work/work_add.php b/work/work_add.php new file mode 100644 index 000000000..c0b8795fd --- /dev/null +++ b/work/work_add.php @@ -0,0 +1,122 @@ +isPluginEnabled('wk')) { + header('Location: feature_disabled.php'); + exit(); +} +// Do we have offer_id? +$cl_offer_id = (int)$request->getParameter('offer_id'); +if ($cl_offer_id) { + $workHelper = new ttWorkHelper($err); + $offer = $workHelper->getAvailableOffer($cl_offer_id); + if (!$offer) { + header('Location: access_denied.php'); + exit(); + } +} +// End of access checks. + +if ($request->isPost()) { + $cl_name = trim($request->getParameter('work_name')); + $cl_work_type = $request->getParameter('work_type'); + $cl_description = trim($request->getParameter('description')); + $cl_details = trim($request->getParameter('details')); + $cl_currency_id = $request->getParameter('currency'); + $cl_budget = $request->getParameter('budget'); +} +// Override some fields for work being created on an available offer. +if ($offer) { + $cl_name = $offer['subject']; + $cl_work_type = 0; // one-time work + $cl_currency_id = ttWorkHelper::getCurrencyID($offer['currency']); + $cl_budget = $offer['amount']; +} + +$form = new Form('workForm'); +if ($offer) + $form->addInput(array('type'=>'hidden','name'=>'offer_id','value'=>$cl_offer_id)); +$form->addInput(array('type'=>'text','name'=>'work_name','maxlength'=>'128','style'=>'width: 400px;','value'=>$cl_name)); +$WORK_TYPE_OPTIONS = array('0'=>$i18n->get('work.type.one_time'),'1'=>$i18n->get('work.type.ongoing')); +$form->addInput(array('type'=>'combobox','name'=>'work_type','data'=>$WORK_TYPE_OPTIONS,'value'=>$cl_work_type)); +$form->addInput(array('type'=>'textarea','name'=>'description','maxlength'=>'512','style'=>'width: 400px; height: 80px;','value'=>$cl_description)); +$form->addInput(array('type'=>'textarea','name'=>'details','style'=>'width: 400px; height: 200px;','value'=>$cl_details)); +// Add a dropdown for currency. +$currencies = ttWorkHelper::getCurrencies(); +$form->addInput(array('type'=>'combobox','name'=>'currency','data'=>$currencies,'datakeys'=>array('id','name'),'value'=>$cl_currency_id)); +$form->addInput(array('type'=>'floatfield','maxlength'=>'10','name'=>'budget','format'=>'.2','value'=>$cl_budget)); +$form->addInput(array('type'=>'submit','name'=>'btn_add','value'=>$i18n->get('button.add'))); +// Disable some controls for work being created on an available offer. +if ($offer) { + $form->getElement('work_name')->setEnabled(false); + $form->getElement('work_type')->setEnabled(false); + $form->getElement('currency')->setEnabled(false); + $form->getElement('budget')->setEnabled(false); +} + +if ($request->isPost()) { + // Validate user input. + if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.work')); + if (!ttValidString($cl_description, true)) $err->add($i18n->get('error.field'), $i18n->get('label.description')); + if (!ttValidString($cl_details, true)) $err->add($i18n->get('error.field'), $i18n->get('label.details')); + if (!ttValidString($cl_budget)) $err->add($i18n->get('error.field'), $i18n->get('label.budget')); + + // Ensure user email exists (required for workflow). + if (!$user->getEmail()) $err->add($i18n->get('error.no_email')); + + if ($err->no()) { + $workHelper = new ttWorkHelper($err); + $fields = array('offer_id' => $cl_offer_id, + 'subject' => $cl_name, + 'type' => $cl_work_type, + 'descr_short' => $cl_description, + 'descr_long' => $cl_details, + 'currency' => ttWorkHelper::getCurrencyName($cl_currency_id), + 'amount' => $cl_budget); + if ($workHelper->putOwnWorkItem($fields)) { + header('Location: work.php'); + exit(); + } + } +} // isPost + +$smarty->assign('offer', $offer); +$smarty->assign('forms', array($form->getName()=>$form->toArray())); +$smarty->assign('onload', 'onLoad="document.workForm.work_name.focus()"'); +$smarty->assign('title', $i18n->get('title.add_work')); +$smarty->assign('content_page_name', 'work/work_add.tpl'); +$smarty->display('work/index.tpl'); diff --git a/work/work_delete.php b/work/work_delete.php new file mode 100644 index 000000000..75a111da3 --- /dev/null +++ b/work/work_delete.php @@ -0,0 +1,75 @@ +isPluginEnabled('wk')) { + header('Location: feature_disabled.php'); + exit(); +} +$cl_work_id = (int)$request->getParameter('id'); +$workHelper = new ttWorkHelper($err); +$work_item = $workHelper->getOwnWorkItem($cl_work_id); +if (!$work_item) { + header('Location: access_denied.php'); + exit(); +} +// End of access checks. + +$work_to_delete = $work_item['subject']; + +$form = new Form('workDeleteForm'); +$form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_work_id)); +$form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->get('label.delete'))); +$form->addInput(array('type'=>'submit','name'=>'btn_cancel','value'=>$i18n->get('button.cancel'))); + +if ($request->isPost()) { + if ($request->getParameter('btn_delete')) { + if ($workHelper->deleteOwnWorkItem($cl_work_id)) { + header('Location: work.php'); + exit(); + } + } elseif ($request->getParameter('btn_cancel')) { + header('Location: work.php'); + exit(); + } +} // isPost + +$smarty->assign('work_to_delete', $work_to_delete); +$smarty->assign('forms', array($form->getName()=>$form->toArray())); +$smarty->assign('onload', 'onLoad="document.workDeleteForm.btn_cancel.focus()"'); +$smarty->assign('title', $i18n->get('title.delete_work')); +$smarty->assign('content_page_name', 'work/work_delete.tpl'); +$smarty->display('work/index.tpl'); diff --git a/work/work_edit.php b/work/work_edit.php new file mode 100644 index 000000000..f265da859 --- /dev/null +++ b/work/work_edit.php @@ -0,0 +1,151 @@ +isPluginEnabled('wk')) { + header('Location: feature_disabled.php'); + exit(); +} +$cl_work_id = (int)$request->getParameter('id'); +$workHelper = new ttWorkHelper($err); +$work_item = $workHelper->getOwnWorkItem($cl_work_id); +if (!$work_item) { + header('Location: access_denied.php'); + exit(); +} +// Do we have offer_id? +$offer_id = $work_item['offer_id']; +if ($offer_id) { + $offer = $workHelper->getAvailableOffer($offer_id); + if (!$offer) { + header('Location: access_denied.php'); + exit(); + } +} +// End of access checks. + +$currencies = ttWorkHelper::getCurrencies(); + +if ($request->isPost()) { + $cl_name = trim($request->getParameter('work_name')); + $cl_work_type = $request->getParameter('work_type'); + $cl_description = trim($request->getParameter('description')); + $cl_details = trim($request->getParameter('details')); + $cl_currency_id = $request->getParameter('currency'); + $cl_budget = $request->getParameter('budget'); +} else { + $cl_name = $work_item['subject']; + $cl_work_type = $work_item['type']; + $cl_description = $work_item['descr_short']; + $cl_details = $work_item['descr_long']; + $cl_currency_id = ttWorkHelper::getCurrencyID($work_item['currency']); + $cl_budget = $work_item['amount']; + $cl_status = $work_item['status_label']; + $cl_moderator_comment = $work_item['moderator_comment']; +} +// Override some fields for work on an available offer. +if ($offer) { + $cl_name = $offer['subject']; + $cl_work_type = 0; // one-time work + $cl_currency_id = ttWorkHelper::getCurrencyID($offer['currency']); + $cl_budget = $offer['amount']; +} + +$show_moderator_comment = $cl_moderator_comment != null; + +$form = new Form('workForm'); +$form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_work_id)); +$form->addInput(array('type'=>'text','name'=>'work_name','maxlength'=>'128','style'=>'width: 400px;','value'=>$cl_name)); +$WORK_TYPE_OPTIONS = array('0'=>$i18n->get('work.type.one_time'),'1'=>$i18n->get('work.type.ongoing')); +$form->addInput(array('type'=>'combobox','name'=>'work_type','data'=>$WORK_TYPE_OPTIONS,'value'=>$cl_work_type)); +$form->addInput(array('type'=>'textarea','name'=>'description','maxlength'=>'512','style'=>'width: 400px; height: 80px;','value'=>$cl_description)); +$form->addInput(array('type'=>'textarea','name'=>'details','style'=>'width: 400px; height: 200px;','value'=>$cl_details)); +$form->addInput(array('type'=>'combobox','name'=>'currency','data'=>$currencies,'datakeys'=>array('id','name'),'value'=>$cl_currency_id)); +$form->addInput(array('type'=>'floatfield','maxlength'=>'10','name'=>'budget','format'=>'.2','value'=>$cl_budget)); +$form->addInput(array('type'=>'text','name'=>'status','style'=>'width: 400px;','value'=>$cl_status)); +$form->getElement('status')->setEnabled(false); +$form->addInput(array('type'=>'textarea','name'=>'moderator_comment','style'=>'width: 400px; height: 80px;','value'=>$cl_moderator_comment)); +$form->getElement('moderator_comment')->setEnabled(false); +$form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); +// Disable some controls for work on an available offer. +if ($offer) { + $form->getElement('work_name')->setEnabled(false); + $form->getElement('work_type')->setEnabled(false); + $form->getElement('currency')->setEnabled(false); + $form->getElement('budget')->setEnabled(false); +} + +if ($request->isPost()) { + // Validate user input. + if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.work')); + if (!ttValidString($cl_description, true)) $err->add($i18n->get('error.field'), $i18n->get('label.description')); + if (!ttValidString($cl_details, true)) $err->add($i18n->get('error.field'), $i18n->get('label.details')); + if (!ttValidString($cl_budget)) $err->add($i18n->get('error.field'), $i18n->get('label.budget')); + + // Ensure user email exists (required for workflow). + if (!$user->getEmail()) $err->add($i18n->get('error.no_email')); + + if ($err->no()) { + if ($request->getParameter('btn_save')) { + // Update work information. + $fields = array('work_id'=>$cl_work_id, + 'type'=>$cl_work_type, + 'subject'=>$cl_name, + 'descr_short' => $cl_description, + 'descr_long' => $cl_details, + 'currency' => ttWorkHelper::getCurrencyName($cl_currency_id), + 'amount' => $cl_budget); + if ($offer_id > 0) { + if ($workHelper->updateOwnWorkItemOnOffer($fields)) { + header('Location: work.php'); + exit(); + } + } else { + if ($workHelper->updateOwnWorkItem($fields)) { + header('Location: work.php'); + exit(); + } + } + } + } +} // isPost + +$smarty->assign('offer', $offer); +$smarty->assign('show_moderator_comment', $show_moderator_comment); +$smarty->assign('forms', array($form->getName()=>$form->toArray())); +$smarty->assign('title', $i18n->get('title.edit_work')); +$smarty->assign('content_page_name', 'work/work_edit.tpl'); +$smarty->display('work/index.tpl'); diff --git a/work/work_message.php b/work/work_message.php new file mode 100644 index 000000000..ca74915d4 --- /dev/null +++ b/work/work_message.php @@ -0,0 +1,97 @@ +isPluginEnabled('wk')) { + header('Location: feature_disabled.php'); + exit(); +} +// Do we have work_id? +$cl_work_id = (int)$request->getParameter('work_id'); +if ($cl_work_id) { + $workHelper = new ttWorkHelper($err); + $work_item = $workHelper->getAvailableWorkItem($cl_work_id); + if (!$work_item) { + header('Location: access_denied.php'); + exit(); + } +} +// End of access checks. +if ($work_item) $cl_name = $work_item['subject']; + +if ($request->isPost()) { + $cl_message_body = trim($request->getParameter('message_body')); +} + + + + + + + + +$form = new Form('messageForm'); +if ($cl_work_id) { + $form->addInput(array('type'=>'hidden','name'=>'work_id','value'=>$cl_work_id)); +} +$form->addInput(array('type'=>'textarea','name'=>'message_body','style'=>'width: 400px; height: 80px;vertical-align: middle','value'=>$cl_message_body)); +$form->addInput(array('type'=>'submit','name'=>'btn_send','value'=>$i18n->get('work.button.send_message'))); + +if ($request->isPost()) { + // Validate user input. + if (!ttValidString($cl_message_body)) $err->add($i18n->get('error.field'), $i18n->get('work.label.message')); + + // Ensure user email exists (required for workflow). + if (!$user->getEmail()) $err->add($i18n->get('error.no_email')); + + if ($err->no()) { + $workHelper = new ttWorkHelper($err); + $fields = array('work_id'=>$cl_work_id, + 'message_body' => $cl_message_body); + if ($workHelper->sendMessage($fields)) { + $msg->add($i18n->get('work.msg.message_sent')); + // header('Location: work.php'); // TODO: where to redirect? + // exit(); + } + } +} // isPost + +$smarty->assign('work_item', $work_item); +$smarty->assign('forms', array($form->getName()=>$form->toArray())); +$smarty->assign('onload', 'onLoad="document.offerForm.work_name.focus()"'); +$smarty->assign('title', $i18n->get('work.title.send_message')); +$smarty->assign('content_page_name', 'work/work_message.tpl'); +$smarty->display('work/index.tpl'); diff --git a/work/work_offer_view.php b/work/work_offer_view.php new file mode 100644 index 000000000..dc1074942 --- /dev/null +++ b/work/work_offer_view.php @@ -0,0 +1,123 @@ +isPluginEnabled('wk')) { + header('Location: feature_disabled.php'); + exit(); +} +if (!ttAccessAllowed('manage_work')) { + header('Location: access_denied.php'); + exit(); +} +$cl_offer_id = (int)$request->getParameter('id'); +$workHelper = new ttWorkHelper($err); +$offer = $workHelper->getOwnWorkItemOffer($cl_offer_id); +if (!$offer) { + header('Location: access_denied.php'); + exit(); +} +// End of access checks. + +// Get an associated work item. +$work_item = $workHelper->getOwnWorkItem($offer['work_id']); +if (!$work_item) $err->add($i18n->get('work.error.work_not_available')); + +if ($request->isPost()) { + $cl_client_comment = $request->getParameter('client_comment'); +} else { + $cl_client_comment = $offer['client_comment']; +} + +$cl_contractor = $offer['group_name']; +$cl_name = $offer['subject']; +$cl_description = $offer['descr_short']; +$cl_details = $offer['descr_long']; +$cl_budget = $offer['amount_with_currency']; +$cl_status = $offer['status_label']; + +$form = new Form('offerForm'); +$form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_offer_id)); +$form->addInput(array('type'=>'text','name'=>'contractor','value'=>$cl_contractor)); +$form->getElement('contractor')->setEnabled(false); +$form->addInput(array('type'=>'text','name'=>'offer_name','style'=>'width: 400px;','value'=>$cl_name)); +$form->getElement('offer_name')->setEnabled(false); +$form->addInput(array('type'=>'textarea','name'=>'description','style'=>'width: 400px; height: 80px;','value'=>$cl_description)); +$form->getElement('description')->setEnabled(false); +$form->addInput(array('type'=>'textarea','name'=>'details','style'=>'width: 400px; height: 200px;','value'=>$cl_details)); +$form->getElement('details')->setEnabled(false); +$form->addInput(array('type'=>'text','name'=>'budget','value'=>$cl_budget)); +$form->getElement('budget')->setEnabled(false); +$form->addInput(array('type'=>'text','name'=>'status','style'=>'width: 400px;','value'=>$cl_status)); +$form->getElement('status')->setEnabled(false); +if ($offer['status'] == STATUS_APPROVED) { + $form->addInput(array('type'=>'submit','name'=>'btn_accept','value'=>$i18n->get('work.button.accept'))); + $form->addInput(array('type'=>'submit','name'=>'btn_decline','value'=>$i18n->get('work.button.decline'))); +} +$form->addInput(array('type'=>'textarea','name'=>'client_comment','style'=>'width: 400px; height: 80px;','value'=>$cl_client_comment)); + +if ($request->isPost()) { + // Validate user input. + if (!ttValidString($cl_client_comment, true)) $err->add($i18n->get('error.field'), $i18n->get('label.comment')); + + // Ensure user email exists (required for workflow). + if (!$user->getEmail()) $err->add($i18n->get('error.no_email')); + + if ($err->no()) { + $workHelper = new ttWorkHelper($err); + $fields = array('offer_id'=>$cl_offer_id, + 'client_comment'=>$cl_client_comment); + + if ($request->getParameter('btn_accept')) { + // Accept offer. + if ($workHelper->acceptOwnWorkItemOffer($fields)) { + header('Location: work_offer_view.php?id='.$cl_offer_id); + exit(); + } + } + + if ($request->getParameter('btn_decline')) { + // Decline offer. + if ($workHelper->declineOwnWorkItemOffer($fields)) { + header('Location: work_offer_view.php?id='.$cl_offer_id); + exit(); + } + } + } +} // isPost + +$smarty->assign('work_item', $work_item); +$smarty->assign('forms', array($form->getName()=>$form->toArray())); +$smarty->assign('title', $i18n->get('title.offer')); +$smarty->assign('content_page_name', 'work/work_offer_view.tpl'); +$smarty->display('work/index.tpl'); diff --git a/work/work_offers.php b/work/work_offers.php new file mode 100644 index 000000000..e045892ea --- /dev/null +++ b/work/work_offers.php @@ -0,0 +1,56 @@ +isPluginEnabled('wk')) { + header('Location: feature_disabled.php'); + exit(); +} +$work_id = (int)$request->getParameter('id'); +$workHelper = new ttWorkHelper($err); +$work_item = $workHelper->getOwnWorkItem($work_id); +if (!$work_item) { + header('Location: access_denied.php'); + exit(); +} +// End of access checks. + +$work_item_offers = $workHelper->getOwnWorkItemOffers($work_id); + +$smarty->assign('work_item', $work_item); +$smarty->assign('work_item_offers', $work_item_offers); +$smarty->assign('title', $i18n->get('work.label.offers')); +$smarty->assign('content_page_name', 'work/work_offers.tpl'); +$smarty->display('work/index.tpl'); diff --git a/work/work_view.php b/work/work_view.php new file mode 100644 index 000000000..2bd8d3fd3 --- /dev/null +++ b/work/work_view.php @@ -0,0 +1,74 @@ +isPluginEnabled('wk')) { + header('Location: feature_disabled.php'); + exit(); +} +if (!ttAccessAllowed('bid_on_work')) { + header('Location: access_denied.php'); + exit(); +} +$cl_work_id = (int)$request->getParameter('id'); +$workHelper = new ttWorkHelper($err); +$work_item = $workHelper->getAvailableWorkItem($cl_work_id); +if (!$work_item) { + header('Location: access_denied.php'); + exit(); +} +// End of access checks. + +$cl_client = $work_item['group_name']; +$cl_name = $work_item['subject']; +$cl_description = $work_item['descr_short']; +$cl_details = $work_item['descr_long']; +$cl_budget = $work_item['amount_with_currency']; + +$form = new Form('workForm'); +$form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_work_id)); +$form->addInput(array('type'=>'text','name'=>'client','value'=>$cl_client)); +$form->getElement('client')->setEnabled(false); +$form->addInput(array('type'=>'textarea','name'=>'work_name','style'=>'width: 400px;','value'=>$cl_name)); +$form->getElement('work_name')->setEnabled(false); +$form->addInput(array('type'=>'textarea','name'=>'description','style'=>'width: 400px; height: 80px;','value'=>$cl_description)); +$form->getElement('description')->setEnabled(false); +$form->addInput(array('type'=>'textarea','name'=>'details','style'=>'width: 400px; height: 200px;','value'=>$cl_details)); +$form->getElement('details')->setEnabled(false); +$form->addInput(array('type'=>'text','name'=>'budget','value'=>$cl_budget)); +$form->getElement('budget')->setEnabled(false); + +$smarty->assign('work_id', $cl_work_id); +$smarty->assign('forms', array($form->getName()=>$form->toArray())); +$smarty->assign('title', $i18n->get('title.work')); +$smarty->assign('content_page_name', 'work/work_view.tpl'); +$smarty->display('work/index.tpl'); diff --git a/work/work_view_own.php b/work/work_view_own.php new file mode 100644 index 000000000..9930eaf99 --- /dev/null +++ b/work/work_view_own.php @@ -0,0 +1,79 @@ +isPluginEnabled('wk')) { + header('Location: feature_disabled.php'); + exit(); +} +if (!ttAccessAllowed('manage_work')) { + header('Location: access_denied.php'); + exit(); +} +$work_id = (int)$request->getParameter('id'); +$workHelper = new ttWorkHelper($err); +$work_item = $workHelper->getOwnWorkItem($work_id); +if (!$work_item) { + header('Location: access_denied.php'); + exit(); +} +// Do we have offer_id? +$offer_id = $work_item['offer_id']; +if ($offer_id) { + $offer = $workHelper->getAvailableOffer($offer_id); + if (!$offer) { + header('Location: access_denied.php'); + exit(); + } +} +// End of access checks. + +$cl_name = $work_item['subject']; +$cl_description = $work_item['descr_short']; +$cl_details = $work_item['descr_long']; +$cl_budget = $work_item['amount_with_currency']; + +$form = new Form('workForm'); +$form->addInput(array('type'=>'textarea','name'=>'work_name','style'=>'width: 400px;','value'=>$cl_name)); +$form->getElement('work_name')->setEnabled(false); +$form->addInput(array('type'=>'textarea','name'=>'description','style'=>'width: 400px; height: 80px;','value'=>$cl_description)); +$form->getElement('description')->setEnabled(false); +$form->addInput(array('type'=>'textarea','name'=>'details','style'=>'width: 400px; height: 200px;','value'=>$cl_details)); +$form->getElement('details')->setEnabled(false); +$form->addInput(array('type'=>'text','name'=>'budget','value'=>$cl_budget)); +$form->getElement('budget')->setEnabled(false); + +$smarty->assign('offer', $offer); +$smarty->assign('forms', array($form->getName()=>$form->toArray())); +$smarty->assign('title', $i18n->get('title.work')); +$smarty->assign('content_page_name', 'work/work_view_own.tpl'); +$smarty->display('work/index.tpl'); From a6950a55683617d3155756b055d52b2b955cec4e Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 9 Nov 2019 16:06:24 +0000 Subject: [PATCH 172/877] Fixed redirects on Work plugin pages. --- WEB-INF/lib/ttAdminWorkHelper.class.php | 1 + WEB-INF/templates/admin_offer_edit.tpl | 70 ---------- WEB-INF/templates/admin_work.tpl | 104 --------------- WEB-INF/templates/admin_work_edit.tpl | 67 ---------- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/header.tpl | 4 +- WEB-INF/templates/offer_add.tpl | 74 ----------- WEB-INF/templates/offer_delete.tpl | 20 --- WEB-INF/templates/offer_edit.tpl | 67 ---------- WEB-INF/templates/offer_view.tpl | 46 ------- WEB-INF/templates/offer_view_own.tpl | 42 ------ WEB-INF/templates/work.tpl | 140 -------------------- WEB-INF/templates/work_add.tpl | 62 --------- WEB-INF/templates/work_delete.tpl | 20 --- WEB-INF/templates/work_edit.tpl | 73 ---------- WEB-INF/templates/work_message.tpl | 32 ----- WEB-INF/templates/work_offer_view.tpl | 57 -------- WEB-INF/templates/work_offers.tpl | 41 ------ WEB-INF/templates/work_view.tpl | 47 ------- WEB-INF/templates/work_view_own.tpl | 38 ------ admin_offer_delete.php | 71 ---------- admin_offer_edit.php | 169 ------------------------ admin_work.php | 53 -------- admin_work_delete.php | 71 ---------- admin_work_edit.php | 168 ----------------------- offer_add.php | 120 ----------------- offer_delete.php | 75 ----------- offer_edit.php | 135 ------------------- offer_view.php | 81 ------------ offer_view_own.php | 77 ----------- work.php | 65 --------- work/admin_offer_delete.php | 4 +- work/admin_offer_edit.php | 4 +- work/admin_work.php | 2 +- work/admin_work_delete.php | 4 +- work/admin_work_edit.php | 6 +- work/offer_add.php | 6 +- work/offer_delete.php | 6 +- work/offer_edit.php | 6 +- work/offer_view.php | 6 +- work/offer_view_own.php | 6 +- work/work.php | 4 +- work/work_add.php | 6 +- work/work_delete.php | 6 +- work/work_edit.php | 8 +- work/work_message.php | 6 +- work/work_offer_view.php | 6 +- work/work_offers.php | 6 +- work/work_view.php | 6 +- work/work_view_own.php | 8 +- work_add.php | 122 ----------------- work_delete.php | 75 ----------- work_edit.php | 151 --------------------- work_message.php | 97 -------------- work_offer_view.php | 123 ----------------- work_offers.php | 56 -------- work_view.php | 74 ----------- work_view_own.php | 79 ----------- 58 files changed, 57 insertions(+), 2918 deletions(-) delete mode 100644 WEB-INF/templates/admin_offer_edit.tpl delete mode 100644 WEB-INF/templates/admin_work.tpl delete mode 100644 WEB-INF/templates/admin_work_edit.tpl delete mode 100644 WEB-INF/templates/offer_add.tpl delete mode 100644 WEB-INF/templates/offer_delete.tpl delete mode 100644 WEB-INF/templates/offer_edit.tpl delete mode 100644 WEB-INF/templates/offer_view.tpl delete mode 100644 WEB-INF/templates/offer_view_own.tpl delete mode 100644 WEB-INF/templates/work.tpl delete mode 100644 WEB-INF/templates/work_add.tpl delete mode 100644 WEB-INF/templates/work_delete.tpl delete mode 100644 WEB-INF/templates/work_edit.tpl delete mode 100644 WEB-INF/templates/work_message.tpl delete mode 100644 WEB-INF/templates/work_offer_view.tpl delete mode 100644 WEB-INF/templates/work_offers.tpl delete mode 100644 WEB-INF/templates/work_view.tpl delete mode 100644 WEB-INF/templates/work_view_own.tpl delete mode 100644 admin_offer_delete.php delete mode 100644 admin_offer_edit.php delete mode 100644 admin_work.php delete mode 100644 admin_work_delete.php delete mode 100644 admin_work_edit.php delete mode 100644 offer_add.php delete mode 100644 offer_delete.php delete mode 100644 offer_edit.php delete mode 100644 offer_view.php delete mode 100644 offer_view_own.php delete mode 100644 work.php delete mode 100644 work_add.php delete mode 100644 work_delete.php delete mode 100644 work_edit.php delete mode 100644 work_message.php delete mode 100644 work_offer_view.php delete mode 100644 work_offers.php delete mode 100644 work_view.php delete mode 100644 work_view_own.php diff --git a/WEB-INF/lib/ttAdminWorkHelper.class.php b/WEB-INF/lib/ttAdminWorkHelper.class.php index ce8d0f76f..22098b277 100644 --- a/WEB-INF/lib/ttAdminWorkHelper.class.php +++ b/WEB-INF/lib/ttAdminWorkHelper.class.php @@ -797,6 +797,7 @@ function updateOffer($fields) { 'descr_long' => urlencode(base64_encode($fields['descr_long'])), 'currency' => urlencode($fields['currency']), 'amount' => urlencode($fields['amount']), + 'payment_info' => urlencode(base64_encode($fields['payment_info'])), 'moderator_comment' => urlencode(base64_encode($fields['moderator_comment'])), 'modified_ip' => urlencode($_SERVER['REMOTE_ADDR']), 'modified_by' => urlencode($user->getUser()), diff --git a/WEB-INF/templates/admin_offer_edit.tpl b/WEB-INF/templates/admin_offer_edit.tpl deleted file mode 100644 index bd9a6542b..000000000 --- a/WEB-INF/templates/admin_offer_edit.tpl +++ /dev/null @@ -1,70 +0,0 @@ -{$forms.offerForm.open} - - - - -
- -{if $work_id} - - - - - - - - - -{/if} - - - - - - - - - - - - -{if $show_files} - - - - -{/if} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
{$i18n.label.work}:{$work_name}
{$forms.offerForm.work_description.control}
 
{$i18n.label.offer} (*):{$forms.offerForm.offer_name.control}
{$i18n.label.description}:{$forms.offerForm.description.control}
{$i18n.label.details}:{$forms.offerForm.details.control}
{$i18n.label.file}:{$forms.offerForm.newfile.control}
{$i18n.label.currency}:{$forms.offerForm.currency.control}
{$i18n.label.budget} (*):{$forms.offerForm.budget.control}
{$i18n.label.how_to_pay} (*):{$forms.offerForm.payment_info.control}
{$i18n.label.status}:{$forms.offerForm.status.control}
{$i18n.label.moderator_comment}:{$forms.offerForm.moderator_comment.control}
{$i18n.label.required_fields}
 
{$forms.offerForm.btn_approve.control} {$forms.offerForm.btn_save.control} {$forms.offerForm.btn_disapprove.control}
-
-{$forms.offerForm.close} diff --git a/WEB-INF/templates/admin_work.tpl b/WEB-INF/templates/admin_work.tpl deleted file mode 100644 index 16b4d4434..000000000 --- a/WEB-INF/templates/admin_work.tpl +++ /dev/null @@ -1,104 +0,0 @@ - - - - - - -
-{if $pending_work} - - - - - - - - - - - {foreach $pending_work as $work_item} - - - - - - - - - {/foreach} -
{$i18n.title.pending_work}
{$i18n.label.work}{$i18n.label.description}{$i18n.label.client}{$i18n.label.budget}
{$work_item.subject|escape}{$work_item.description|escape}{$work_item.group_name|escape} ({$work_item.site_id}.{$work_item.group_id}){$work_item.amount_with_currency}{$i18n.label.edit}{$i18n.label.delete}
-{/if} - -
- -{if $pending_offers} - - - - - - - - - - - {foreach $pending_offers as $offer} - - - - - - - - - {/foreach} -
{$i18n.title.pending_offers}
{$i18n.label.offer}{$i18n.label.description}{$i18n.label.contractor}{$i18n.label.budget}
{$offer.subject|escape}{$offer.description|escape}{$offer.group_name|escape} ({$offer.site_id}.{$offer.group_id}){$offer.amount_with_currency}{$i18n.label.edit}{$i18n.label.delete}
-{/if} - -
- - - -{if $available_work} - - - - - - - {foreach $available_work as $work_item} - - - - - - - {/foreach} -{/if} -
{$i18n.title.available_work}
{$i18n.label.work}{$i18n.label.description}{$i18n.label.client}{$i18n.label.budget}
{$work_item.subject|escape}{$work_item.description|escape}{$work_item.group_name|escape}{$work_item.amount_with_currency}
- -
- - - -{if $available_offers} - - - - - - - {foreach $available_offers as $offer} - - - - - - - {/foreach} -{/if} -
{$i18n.title.available_offers}
{$i18n.label.offer}{$i18n.label.description}{$i18n.label.contractor}{$i18n.label.budget}
{$offer.subject|escape}{$offer.description|escape}{$offer.group_name|escape}{$offer.amount_with_currency}
- -
diff --git a/WEB-INF/templates/admin_work_edit.tpl b/WEB-INF/templates/admin_work_edit.tpl deleted file mode 100644 index 1ae59a6fe..000000000 --- a/WEB-INF/templates/admin_work_edit.tpl +++ /dev/null @@ -1,67 +0,0 @@ -{$forms.workForm.open} - -{if $offer} - - - -{/if} - - - -
- - - - - -
{$i18n.label.offer}: {$offer.subject}
{$i18n.label.contractor}: {$offer.group_name}
{$i18n.label.description}: {$offer.descr_short|escape}
{$i18n.label.budget}: {$offer.amount_with_currency}
-
- - - - - - - - - - - - - -{if $show_files} - - - - -{/if} - - - - - - - - - - - - - - - - - - - - - - - - - - - -
{$i18n.label.work} (*):{$forms.workForm.work_name.control}
{$i18n.label.description}:{$forms.workForm.description.control}
{$i18n.label.details}:{$forms.workForm.details.control}
{$i18n.label.file}:{$forms.workForm.newfile.control}
{$i18n.label.currency}:{$forms.workForm.currency.control}
{$i18n.label.budget} (*):{$forms.workForm.budget.control}
{$i18n.label.status}:{$forms.workForm.status.control}
{$i18n.label.moderator_comment}:{$forms.workForm.moderator_comment.control}
{$i18n.label.required_fields}
 
{$forms.workForm.btn_save.control}
-
-{$forms.workForm.close} diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index a7cf644bb..6b904f8b2 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- @@ -142,7 +142,7 @@ {$i18n.menu.clients} {/if} {if $user->isPluginEnabled('wk') && ($user->can('update_work') || $user->can('bid_on_work') || $user->can('manage_work')) && $user->exists()} - {$i18n.title.work} + {$i18n.title.work} {/if} {if $user->can('export_data')} {$i18n.menu.export} diff --git a/WEB-INF/templates/offer_add.tpl b/WEB-INF/templates/offer_add.tpl deleted file mode 100644 index 80e07d803..000000000 --- a/WEB-INF/templates/offer_add.tpl +++ /dev/null @@ -1,74 +0,0 @@ -{$forms.offerForm.open} -
 Anuko Time Tracker 1.19.12.5168 | Copyright © Anuko | +  Anuko Time Tracker 1.19.12.5170 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/header.tpl b/WEB-INF/templates/header.tpl index fbb3e88a4..837ef05b3 100644 --- a/WEB-INF/templates/header.tpl +++ b/WEB-INF/templates/header.tpl @@ -74,7 +74,7 @@ {$i18n.menu.groups} {$i18n.menu.options} {if isTrue('WORK_SERVER_ADMINISTRATION')} - {$i18n.label.work} + {$i18n.label.work} {/if}
-{if $work_item} - - - -{/if} - - - - -
- - - - -
{$i18n.label.work}: {$work_item.subject}
{$i18n.label.description}: {$work_item.descr_short|escape}
{$i18n.label.budget}: {$work_item.amount_with_currency}
-
- -{if $work_id} - - - - - - - - - -{/if} - - - - - - - - - - - - -{if $show_files} - - - - -{/if} - - - - - - - - - - - - - - - - - - - - - - - -
{$i18n.label.work}:{$work_name}
{$forms.offerForm.work_description.control}
 
{$i18n.label.offer} (*):{$forms.offerForm.offer_name.control}
{$i18n.label.description}:{$forms.offerForm.description.control}
{$i18n.label.details}:{$forms.offerForm.details.control}
{$i18n.label.file}:{$forms.offerForm.newfile.control}
{$i18n.label.currency}:{$forms.offerForm.currency.control}
{$i18n.label.budget} (*):{$forms.offerForm.budget.control} {$i18n.label.what_is_it}
{$i18n.label.how_to_pay} (*):{$forms.offerForm.payment_info.control} {$i18n.label.what_is_it}
{$i18n.label.required_fields}
 
{$forms.offerForm.btn_add.control}
-
-{$forms.offerForm.close} diff --git a/WEB-INF/templates/offer_delete.tpl b/WEB-INF/templates/offer_delete.tpl deleted file mode 100644 index 7d8954cfb..000000000 --- a/WEB-INF/templates/offer_delete.tpl +++ /dev/null @@ -1,20 +0,0 @@ -{$forms.offerDeleteForm.open} - - - - -
- - - - - - - - - - - -
{$offer_to_delete|escape}
 
{$forms.offerDeleteForm.btn_delete.control}  {$forms.offerDeleteForm.btn_cancel.control}
-
-{$forms.offerDeleteForm.close} diff --git a/WEB-INF/templates/offer_edit.tpl b/WEB-INF/templates/offer_edit.tpl deleted file mode 100644 index 5c1e89a33..000000000 --- a/WEB-INF/templates/offer_edit.tpl +++ /dev/null @@ -1,67 +0,0 @@ -{$forms.offerForm.open} - -{if $work_item} - - - -{/if} - - - - -
- - - - -
{$i18n.label.work}: {$work_item.subject}
{$i18n.label.description}: {$work_item.descr_short|escape}
{$i18n.label.budget}: {$work_item.amount_with_currency}
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -{if $show_moderator_comment} - - - - -{/if} - - - - - - - - - - - -
{$i18n.label.offer} (*):{$forms.offerForm.offer_name.control}
{$i18n.label.description}:{$forms.offerForm.description.control}
{$i18n.label.details}:{$forms.offerForm.details.control}
{$i18n.label.currency}:{$forms.offerForm.currency.control}
{$i18n.label.budget} (*):{$forms.offerForm.budget.control} {$i18n.label.what_is_it}
{$i18n.label.how_to_pay} (*):{$forms.offerForm.payment_info.control} {$i18n.label.what_is_it}
{$i18n.label.status}:{$forms.offerForm.status.control}
{$i18n.label.moderator_comment}:{$forms.offerForm.moderator_comment.control}
{$i18n.label.required_fields}
 
{$forms.offerForm.btn_save.control}
-
-{$forms.offerForm.close} diff --git a/WEB-INF/templates/offer_view.tpl b/WEB-INF/templates/offer_view.tpl deleted file mode 100644 index ad0b385f2..000000000 --- a/WEB-INF/templates/offer_view.tpl +++ /dev/null @@ -1,46 +0,0 @@ - - -{$forms.offerForm.open} - - - - -
- - - - - - - - - - - - - - - - - - - - - -
{$i18n.label.contractor}:{$forms.offerForm.contractor.control}
{$i18n.label.offer}:{$forms.offerForm.offer_name.control}
{$i18n.label.description}:{$forms.offerForm.description.control}
{$i18n.label.details}:{$forms.offerForm.details.control}
{$i18n.label.budget}:{$forms.offerForm.budget.control}
-
-{$forms.offerForm.close} - - - - - -
- - - - -
-
diff --git a/WEB-INF/templates/offer_view_own.tpl b/WEB-INF/templates/offer_view_own.tpl deleted file mode 100644 index d00ae7ea1..000000000 --- a/WEB-INF/templates/offer_view_own.tpl +++ /dev/null @@ -1,42 +0,0 @@ - - -{$forms.offerForm.open} - -{if $work_item} - - - -{/if} - - - - -
- - - - -
{$i18n.label.work}: {$work_item.subject}
{$i18n.label.description}: {$work_item.descr_short|escape}
{$i18n.label.budget}: {$work_item.amount_with_currency}
-
- - - - - - - - - - - - - - - - - -
{$i18n.label.offer}:{$forms.offerForm.offer_name.control}
{$i18n.label.description}:{$forms.offerForm.description.control}
{$i18n.label.details}:{$forms.offerForm.details.control}
{$i18n.label.budget}:{$forms.offerForm.budget.control}
-
-{$forms.offerForm.close} diff --git a/WEB-INF/templates/work.tpl b/WEB-INF/templates/work.tpl deleted file mode 100644 index 7b00383d5..000000000 --- a/WEB-INF/templates/work.tpl +++ /dev/null @@ -1,140 +0,0 @@ - - - - - - -
-{if $own_work_items} - - - - - - - - - - - - {foreach $own_work_items as $work_item} - - - - - - - {if $work_item.can_edit} - - {else} - - {/if} - {if $work_item.can_delete} - - {else} - - {/if} - - {/foreach} -
{$i18n.work.label.own_work}
{$i18n.label.work}{$i18n.label.description}{$i18n.label.status}{$i18n.work.label.offers}{$i18n.label.budget}
{$work_item.subject|escape}{$work_item.description|escape}{$work_item.status_label}{if $work_item.num_offers}{$work_item.num_offers}{/if}{$work_item.amount_with_currency}{$i18n.label.edit}{$i18n.label.delete}
- - - - - -

-
-
-{/if} - - - -{if $available_work_items} - - - - - - - {foreach $available_work_items as $work_item} - - - - - - - {/foreach} -{/if} -
{$i18n.title.available_work}
{$i18n.label.work}{$i18n.label.description}{$i18n.label.client}{$i18n.label.budget}
{$work_item.subject|escape}{$work_item.description|escape}{$work_item.group_name|escape}{$work_item.amount_with_currency}
- - - - - -

-
-
- -{if $own_offers} - - - - - - - - - - - {foreach $own_offers as $offer} - - - - - - - - - {/foreach} -
{$i18n.work.label.own_offers}
{$i18n.label.offer}{$i18n.label.description}{$i18n.label.status}{$i18n.label.budget}
{$offer.subject|escape}{$offer.description|escape}{$offer.status_label}{$offer.amount_with_currency}{$i18n.label.edit}{$i18n.label.delete}
- - - - - -

-
-
-{/if} - - - -{if $available_offers} - - - - - - - {foreach $available_offers as $offer} - - - - - - - {/foreach} -{/if} -
{$i18n.title.available_offers}
{$i18n.label.offer}{$i18n.label.description}{$i18n.label.contractor}{$i18n.label.budget}
{$offer.subject|escape}{$offer.description|escape}{$offer.group_name|escape}{$offer.amount_with_currency}
- - - - - -

-
-
- -
diff --git a/WEB-INF/templates/work_add.tpl b/WEB-INF/templates/work_add.tpl deleted file mode 100644 index eca0ba799..000000000 --- a/WEB-INF/templates/work_add.tpl +++ /dev/null @@ -1,62 +0,0 @@ -{$forms.workForm.open} - -{if $offer} - - - -{/if} - - - -
- - - - -
{$i18n.label.offer}: {$offer.subject}
{$i18n.label.description}: {$offer.descr_short|escape}
{$i18n.label.budget}: {$offer.amount_with_currency}
-
- - - - - - - - - - - - - - - - - -{if $show_files} - - - - -{/if} - - - - - - - - - - - - - - - - - - - -
{$i18n.label.work} (*):{$forms.workForm.work_name.control}
{$i18n.label.type}:{$forms.workForm.work_type.control}
{$i18n.label.description}:{$forms.workForm.description.control}
{$i18n.label.details}:{$forms.workForm.details.control}
{$i18n.label.file}:{$forms.workForm.newfile.control}
{$i18n.label.currency}:{$forms.workForm.currency.control}
{$i18n.label.budget} (*):{$forms.workForm.budget.control} {$i18n.label.what_is_it}
{$i18n.label.required_fields}
 
{$forms.workForm.btn_add.control}
-
-{$forms.workForm.close} diff --git a/WEB-INF/templates/work_delete.tpl b/WEB-INF/templates/work_delete.tpl deleted file mode 100644 index 2831b0f15..000000000 --- a/WEB-INF/templates/work_delete.tpl +++ /dev/null @@ -1,20 +0,0 @@ -{$forms.workDeleteForm.open} - - - - -
- - - - - - - - - - - -
{$work_to_delete|escape}
 
{$forms.workDeleteForm.btn_delete.control}  {$forms.workDeleteForm.btn_cancel.control}
-
-{$forms.workDeleteForm.close} diff --git a/WEB-INF/templates/work_edit.tpl b/WEB-INF/templates/work_edit.tpl deleted file mode 100644 index 7165d5e19..000000000 --- a/WEB-INF/templates/work_edit.tpl +++ /dev/null @@ -1,73 +0,0 @@ -{$forms.workForm.open} - -{if $offer} - - - -{/if} - - - -
- - - - - -
{$i18n.label.offer}: {$offer.subject}
{$i18n.label.contractor}: {$offer.group_name}
{$i18n.label.description}: {$offer.descr_short|escape}
{$i18n.label.budget}: {$offer.amount_with_currency}
-
- - - - - - - - - - - - - - - - - -{if $show_files} - - - - -{/if} - - - - - - - - - - - - -{if $show_moderator_comment} - - - - -{/if} - - - - - - - - - - - -
{$i18n.label.work} (*):{$forms.workForm.work_name.control}
{$i18n.label.type}:{$forms.workForm.work_type.control}
{$i18n.label.description}:{$forms.workForm.description.control}
{$i18n.label.details}:{$forms.workForm.details.control}
{$i18n.label.file}:{$forms.workForm.newfile.control}
{$i18n.label.currency}:{$forms.workForm.currency.control}
{$i18n.label.budget} (*):{$forms.workForm.budget.control} {$i18n.label.what_is_it}
{$i18n.label.status}:{$forms.workForm.status.control}
{$i18n.label.moderator_comment}:{$forms.workForm.moderator_comment.control}
{$i18n.label.required_fields}
 
{$forms.workForm.btn_save.control}
-
-{$forms.workForm.close} diff --git a/WEB-INF/templates/work_message.tpl b/WEB-INF/templates/work_message.tpl deleted file mode 100644 index 3f237659c..000000000 --- a/WEB-INF/templates/work_message.tpl +++ /dev/null @@ -1,32 +0,0 @@ - - -{$forms.messageForm.open} - -{if $work_item} - - - -{/if} - - - -
- - - - -
{$i18n.label.work}: {$work_item.subject}
{$i18n.label.description}: {$work_item.descr_short|escape}
{$i18n.label.budget}: {$work_item.amount_with_currency}
-
- - - - - - - - -
{$i18n.work.label.message}:{$forms.messageForm.message_body.control}
{$forms.messageForm.btn_send.control}
-
-{$forms.messageForm.close} diff --git a/WEB-INF/templates/work_offer_view.tpl b/WEB-INF/templates/work_offer_view.tpl deleted file mode 100644 index e2afe0003..000000000 --- a/WEB-INF/templates/work_offer_view.tpl +++ /dev/null @@ -1,57 +0,0 @@ -{$forms.offerForm.open} - -{if $work_item} - - - -{/if} - - - -
- - - - - -
{$i18n.label.work}: {$work_item.subject}
{$i18n.label.client}: {$work_item.group_name}
{$i18n.label.description}: {$work_item.descr_short|escape}
{$i18n.label.budget}: {$work_item.amount_with_currency}
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
{$i18n.label.contractor}:{$forms.offerForm.contractor.control}
{$i18n.label.offer}:{$forms.offerForm.offer_name.control}
{$i18n.label.description}:{$forms.offerForm.description.control}
{$i18n.label.details}:{$forms.offerForm.details.control}
{$i18n.label.budget}:{$forms.offerForm.budget.control}
{$i18n.label.status}:{$forms.offerForm.status.control}
 
{$forms.offerForm.btn_accept.control} {$forms.offerForm.btn_decline.control}
{$i18n.label.comment}:{$forms.offerForm.client_comment.control}
-
-{$forms.offerForm.close} diff --git a/WEB-INF/templates/work_offers.tpl b/WEB-INF/templates/work_offers.tpl deleted file mode 100644 index ea0d8816f..000000000 --- a/WEB-INF/templates/work_offers.tpl +++ /dev/null @@ -1,41 +0,0 @@ - - - - - - - - - - -
- - - - - -
{$i18n.label.work}: {$work_item.subject}
{$i18n.label.client}: {$work_item.group_name}
{$i18n.label.description}: {$work_item.descr_short|escape}
{$i18n.label.budget}: {$work_item.amount_with_currency}
-
- -{if $work_item_offers} - - - - - - - - {foreach $work_item_offers as $offer} - - - - - - - {/foreach} -
{$i18n.label.contractor}{$i18n.label.description}{$i18n.label.status}{$i18n.label.budget}
{$offer.group_name|escape}{$offer.description|escape}{$offer.status_label}{$offer.amount_with_currency}
-{/if} - -
diff --git a/WEB-INF/templates/work_view.tpl b/WEB-INF/templates/work_view.tpl deleted file mode 100644 index 468cb9ddd..000000000 --- a/WEB-INF/templates/work_view.tpl +++ /dev/null @@ -1,47 +0,0 @@ - - -{$forms.workForm.open} - - - - -
- - - - - - - - - - - - - - - - - - - - - -
{$i18n.label.client}:{$forms.workForm.client.control}
{$i18n.label.work}:{$forms.workForm.work_name.control}
{$i18n.label.description}:{$forms.workForm.description.control}
{$i18n.label.details}:{$forms.workForm.details.control}
{$i18n.label.budget}:{$forms.workForm.budget.control}
-
-{$forms.workForm.close} - - - - - -
- - - - - -
-
diff --git a/WEB-INF/templates/work_view_own.tpl b/WEB-INF/templates/work_view_own.tpl deleted file mode 100644 index 61e270b4b..000000000 --- a/WEB-INF/templates/work_view_own.tpl +++ /dev/null @@ -1,38 +0,0 @@ -{$forms.workForm.open} - -{if $offer} - - - -{/if} - - - -
- - - - - -
{$i18n.label.offer}: {$offer.subject}
{$i18n.label.contractor}: {$offer.group_name}
{$i18n.label.description}: {$offer.descr_short|escape}
{$i18n.label.budget}: {$offer.amount_with_currency}
-
- - - - - - - - - - - - - - - - - -
{$i18n.label.work}:{$forms.workForm.work_name.control}
{$i18n.label.description}:{$forms.workForm.description.control}
{$i18n.label.details}:{$forms.workForm.details.control}
{$i18n.label.budget}:{$forms.workForm.budget.control}
-
-{$forms.workForm.close} diff --git a/admin_offer_delete.php b/admin_offer_delete.php deleted file mode 100644 index 05e9b39b6..000000000 --- a/admin_offer_delete.php +++ /dev/null @@ -1,71 +0,0 @@ -getParameter('id'); -$adminWorkHelper = new ttAdminWorkHelper($err); -$offer = $adminWorkHelper->getOffer($cl_offer_id); -if (!$offer) { - header('Location: access_denied.php'); - exit(); -} -// End of access checks. - -$offer_to_delete = $offer['subject']; - -$form = new Form('offerDeleteForm'); -$form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_offer_id)); -$form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->get('label.delete'))); -$form->addInput(array('type'=>'submit','name'=>'btn_cancel','value'=>$i18n->get('button.cancel'))); - -if ($request->isPost()) { - if ($request->getParameter('btn_delete')) { - if ($adminWorkHelper->deleteOffer($cl_offer_id)) { - header('Location: admin_work.php'); - exit(); - } - } elseif ($request->getParameter('btn_cancel')) { - header('Location: admin_work.php'); - exit(); - } -} // isPost - -$smarty->assign('offer_to_delete', $offer_to_delete); -$smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('onload', 'onLoad="document.offerDeleteForm.btn_cancel.focus()"'); -$smarty->assign('title', $i18n->get('title.delete_offer')); -$smarty->assign('content_page_name', 'offer_delete.tpl'); -$smarty->display('index.tpl'); diff --git a/admin_offer_edit.php b/admin_offer_edit.php deleted file mode 100644 index 208c08438..000000000 --- a/admin_offer_edit.php +++ /dev/null @@ -1,169 +0,0 @@ -getParameter('id'); -$adminWorkHelper = new ttAdminWorkHelper($err); -$offer = $adminWorkHelper->getOffer($cl_offer_id); -if (!$offer) { - header('Location: access_denied.php'); - exit(); -} -// End of access checks. - -// Is this offer associated with a work item? -$work_id = $offer['work_id']; -if ($work_id) { - $work_item = $adminWorkHelper->getWorkItem($work_id); - if (!$work_item) $err->add($i18n->get('work.error.work_not_available')); -} - -$existingStatus = $offer['status']; -$currencies = ttWorkHelper::getCurrencies(); - -if ($request->isPost()) { - $cl_name = trim($request->getParameter('offer_name')); - $cl_description = trim($request->getParameter('description')); - $cl_details = trim($request->getParameter('details')); - $cl_currency_id = $request->getParameter('currency'); - if (!$cl_currency_id && $work_item) $cl_currency_id = ttWorkHelper::getCurrencyID($work_item['currency']); - $cl_budget = $request->getParameter('budget'); - $cl_payment_info = $request->getParameter('payment_info'); - // $cl_status = $request->getParameter('status'); - $cl_moderator_comment = $request->getParameter('moderator_comment'); -} else { - $cl_name = $offer['subject']; - $cl_description = $offer['descr_short']; - $cl_details = $offer['descr_long']; - $currency = $offer['currency']; - $cl_currency_id = ttWorkHelper::getCurrencyID($offer['currency']); - $cl_budget = $offer['amount']; - $cl_payment_info = $offer['payment_info']; - $status = $offer['status']; - $status_label = $offer['status_label']; - $cl_moderator_comment = $offer['moderator_comment']; -} - -$form = new Form('offerForm'); -$form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_offer_id)); -if ($work_id) { - $form->addInput(array('type'=>'textarea','name'=>'work_description','style'=>'width: 400px; height: 80px;','value'=>$work_item['descr_short'])); - $form->getElement('work_description')->setEnabled(false); -} -$form->addInput(array('type'=>'text','name'=>'offer_name','style'=>'width: 400px;','value'=>$cl_name)); -if ($work_id) $form->getElement('offer_name')->setEnabled(false); -$form->addInput(array('type'=>'textarea','name'=>'description','maxlength'=>'512','style'=>'width: 400px; height: 80px;','value'=>$cl_description)); -$form->addInput(array('type'=>'textarea','name'=>'details','style'=>'width: 400px; height: 200px;','value'=>$cl_details)); -$form->addInput(array('type'=>'combobox','name'=>'currency','data'=>$currencies,'datakeys'=>array('id','name'),'value'=>$cl_currency_id)); -if ($work_id) $form->getElement('currency')->setEnabled(false); -$form->addInput(array('type'=>'floatfield','maxlength'=>'10','name'=>'budget','format'=>'.2','value'=>$cl_budget)); -$form->addInput(array('type'=>'textarea','name'=>'payment_info','maxlength'=>'256','style'=>'width: 400px; height: 40px;vertical-align: middle','value'=>$cl_payment_info)); -$form->addInput(array('type'=>'text','name'=>'status','style'=>'width: 400px;','value'=>$status_label)); -$form->getElement('status')->setEnabled(false); - -// Prepare status choices. -/* -$status_options = array(); -$status_options[STATUS_PENDING_APPROVAL] = $i18n->get('dropdown.pending_approval'); -$status_options[STATUS_DISAPPROVED] = $i18n->get('dropdown.not_approved'); -$status_options[STATUS_APPROVED] = $i18n->get('dropdown.approved'); - -$form->addInput(array('type'=>'combobox','name'=>'status','value'=>$cl_status,'data'=>$status_options)); -*/ -$form->addInput(array('type'=>'textarea','name'=>'moderator_comment','style'=>'width: 400px; height: 80px;','value'=>$cl_moderator_comment)); -$form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); -if ($status == STATUS_PENDING_APPROVAL) { - $form->addInput(array('type'=>'submit','name'=>'btn_approve','value'=>$i18n->get('button.approve'))); - $form->addInput(array('type'=>'submit','name'=>'btn_disapprove','value'=>$i18n->get('button.disapprove'))); -} - -if ($request->isPost()) { - // Validate user input. - if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.work')); - if (!ttValidString($cl_description, true)) $err->add($i18n->get('error.field'), $i18n->get('label.description')); - if (!ttValidString($cl_details, true)) $err->add($i18n->get('error.field'), $i18n->get('label.details')); - if (!ttValidString($cl_budget)) $err->add($i18n->get('error.field'), $i18n->get('label.budget')); - if (!ttValidString($cl_moderator_comment, true)) $err->add($i18n->get('error.field'), $i18n->get('label.moderator_comment')); - - // Ensure user email exists (required for workflow). - if (!$user->getEmail()) $err->add($i18n->get('error.no_email')); - - $fields = array('offer_id'=>$cl_offer_id, - 'subject'=>$cl_name, - 'descr_short' => $cl_description, - 'descr_long' => $cl_details, - 'currency' => ttWorkHelper::getCurrencyName($cl_currency_id), - 'amount' => $cl_budget, - 'moderator_comment' => $cl_moderator_comment); - - if ($err->no()) { - if ($request->getParameter('btn_approve')) { - // Approve offer. - if ($adminWorkHelper->approveOffer($fields)) { - header('Location: admin_work.php'); - exit(); - } - } - - if ($request->getParameter('btn_save')) { - // Update offer without changing its status. - if ($adminWorkHelper->updateOffer($fields)) { - header('Location: admin_work.php'); - exit(); - } - } - - if ($request->getParameter('btn_disapprove')) { - // Dispprove offer. - if ($adminWorkHelper->disapproveOffer($fields)) { - header('Location: admin_work.php'); - exit(); - } - } - } -} // isPost - -if ($work_id) { - $smarty->assign('work_id', $work_id); - $smarty->assign('work_name', $work_item['subject']); - $smarty->assign('work_description', $work_item['descr_short']); -} -$smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('title', $i18n->get('title.edit_offer')); -$smarty->assign('content_page_name', 'admin_offer_edit.tpl'); -$smarty->display('index.tpl'); diff --git a/admin_work.php b/admin_work.php deleted file mode 100644 index fd0b7b05c..000000000 --- a/admin_work.php +++ /dev/null @@ -1,53 +0,0 @@ -getItems(); -$pending_work = $adminItems['pending_work']; -$pending_offers = $adminItems['pending_offers']; -$available_work = $adminItems['available_work']; -$available_offers = $adminItems['available_offers']; - -$smarty->assign('pending_work', $pending_work); -$smarty->assign('pending_offers', $pending_offers); -$smarty->assign('available_work', $available_work); -$smarty->assign('available_offers', $available_offers); -$smarty->assign('title', $i18n->get('title.work')); -$smarty->assign('content_page_name', 'admin_work.tpl'); -$smarty->display('index.tpl'); diff --git a/admin_work_delete.php b/admin_work_delete.php deleted file mode 100644 index 0700b912c..000000000 --- a/admin_work_delete.php +++ /dev/null @@ -1,71 +0,0 @@ -getParameter('id'); -$adminWorkHelper = new ttAdminWorkHelper($err); -$work_item = $adminWorkHelper->getWorkItem($cl_work_id); -if (!$work_item) { - header('Location: access_denied.php'); - exit(); -} -// End of access checks. - -$work_to_delete = $work_item['subject']; - -$form = new Form('workDeleteForm'); -$form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_work_id)); -$form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->get('label.delete'))); -$form->addInput(array('type'=>'submit','name'=>'btn_cancel','value'=>$i18n->get('button.cancel'))); - -if ($request->isPost()) { - if ($request->getParameter('btn_delete')) { - if ($adminWorkHelper->deleteWorkItem($cl_work_id)) { - header('Location: admin_work.php'); - exit(); - } - } elseif ($request->getParameter('btn_cancel')) { - header('Location: admin_work.php'); - exit(); - } -} // isPost - -$smarty->assign('work_to_delete', $work_to_delete); -$smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('onload', 'onLoad="document.workDeleteForm.btn_cancel.focus()"'); -$smarty->assign('title', $i18n->get('title.delete_work')); -$smarty->assign('content_page_name', 'work_delete.tpl'); -$smarty->display('index.tpl'); diff --git a/admin_work_edit.php b/admin_work_edit.php deleted file mode 100644 index 5b4d47e3d..000000000 --- a/admin_work_edit.php +++ /dev/null @@ -1,168 +0,0 @@ -getParameter('id'); -$adminWorkHelper = new ttAdminWorkHelper($err); -$work_item = $adminWorkHelper->getWorkItem($cl_work_id); -if (!$work_item) { - header('Location: access_denied.php'); - exit(); -} -// Do we have offer_id? -$offer_id = $work_item['offer_id']; -if ($offer_id) { - $offer = $adminWorkHelper->getOffer($offer_id); - if (!$offer) { - header('Location: access_denied.php'); - exit(); - } -} -// End of access checks. - -$existingStatus = $work_item['status']; -$currencies = ttWorkHelper::getCurrencies(); - -if ($request->isPost()) { - $cl_name = trim($request->getParameter('work_name')); - $cl_description = trim($request->getParameter('description')); - $cl_details = trim($request->getParameter('details')); - $cl_currency_id = $request->getParameter('currency'); - $cl_budget = $request->getParameter('budget'); - $cl_status = $request->getParameter('status'); - $cl_moderator_comment = $request->getParameter('moderator_comment'); -} else { - $cl_name = $work_item['subject']; - $cl_description = $work_item['descr_short']; - $cl_details = $work_item['descr_long']; - $currency = $work_item['currency']; - $cl_currency_id = ttWorkHelper::getCurrencyID($work_item['currency']); - $cl_budget = $work_item['amount']; - $cl_status = $work_item['status']; - $cl_moderator_comment = $work_item['moderator_comment']; -} - -$form = new Form('workForm'); -$form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_work_id)); -$form->addInput(array('type'=>'text','name'=>'work_name','maxlength'=>'128','style'=>'width: 400px;','value'=>$cl_name)); -$form->addInput(array('type'=>'textarea','name'=>'description','maxlength'=>'512','style'=>'width: 400px; height: 80px;','value'=>$cl_description)); -$form->addInput(array('type'=>'textarea','name'=>'details','style'=>'width: 400px; height: 200px;','value'=>$cl_details)); -$form->addInput(array('type'=>'combobox','name'=>'currency','data'=>$currencies,'datakeys'=>array('id','name'),'value'=>$cl_currency_id)); -$form->addInput(array('type'=>'floatfield','maxlength'=>'10','name'=>'budget','format'=>'.2','value'=>$cl_budget)); -// Disable some controls for work on an available offer. -if ($offer) { - $form->getElement('work_name')->setEnabled(false); - // $form->getElement('work_type')->setEnabled(false); - $form->getElement('currency')->setEnabled(false); - $form->getElement('budget')->setEnabled(false); -} - -// Prepare status choices. -$status_options = array(); -$status_options[STATUS_PENDING_APPROVAL] = $i18n->get('dropdown.pending_approval'); -$status_options[STATUS_DISAPPROVED] = $i18n->get('dropdown.not_approved'); -$status_options[STATUS_APPROVED] = $i18n->get('dropdown.approved'); - -$form->addInput(array('type'=>'combobox','name'=>'status','value'=>$cl_status,'data'=>$status_options)); -$form->addInput(array('type'=>'textarea','name'=>'moderator_comment','style'=>'width: 400px; height: 80px;','value'=>$cl_moderator_comment)); -$form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); - -if ($request->isPost()) { - // Validate user input. - if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.work')); - if (!ttValidString($cl_description, true)) $err->add($i18n->get('error.field'), $i18n->get('label.description')); - if (!ttValidString($cl_details, true)) $err->add($i18n->get('error.field'), $i18n->get('label.details')); - if (!ttValidString($cl_budget)) $err->add($i18n->get('error.field'), $i18n->get('label.budget')); - if (!ttValidString($cl_moderator_comment, true)) $err->add($i18n->get('error.field'), $i18n->get('label.moderator_comment')); - - // Ensure user email exists (required for workflow). - if (!$user->getEmail()) $err->add($i18n->get('error.no_email')); - - if ($err->no()) { - if ($request->getParameter('btn_save')) { - $fields = array('work_id'=>$cl_work_id, - 'subject'=>$cl_name, - 'descr_short' => $cl_description, - 'descr_long' => $cl_details, - 'currency' => ttWorkHelper::getCurrencyName($cl_currency_id), - 'amount' => $cl_budget, - 'moderator_comment' => $cl_moderator_comment); - - // Do things differently, depending on status control value. - if ($existingStatus == $cl_status) { - // Status not changed. Update work information. - if ($adminWorkHelper->updateWorkItem($fields)) { - header('Location: admin_work.php'); - exit(); - } - } else if ($cl_status == STATUS_DISAPPROVED) { - // Status changed to "not approved". Disapprove work. - if ($offer_id) { - if ($adminWorkHelper->disapproveWorkItemOnOffer($fields)) { - header('Location: admin_work.php'); - exit(); - } - } else { - if ($adminWorkHelper->disapproveWorkItem($fields)) { - header('Location: admin_work.php'); - exit(); - } - } - } else if ($cl_status == STATUS_APPROVED) { - // Status changed to "approved". Approve work. - if ($offer_id) { - if ($adminWorkHelper->approveWorkItemOnOffer($fields)) { - header('Location: admin_work.php'); - exit(); - } - } else { - if ($adminWorkHelper->approveWorkItem($fields)) { - header('Location: admin_work.php'); - exit(); - } - } - } - } - } -} // isPost - -$smarty->assign('offer', $offer); -$smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('title', $i18n->get('title.edit_work')); -$smarty->assign('content_page_name', 'admin_work_edit.tpl'); -$smarty->display('index.tpl'); diff --git a/offer_add.php b/offer_add.php deleted file mode 100644 index 8fc1b20b5..000000000 --- a/offer_add.php +++ /dev/null @@ -1,120 +0,0 @@ -isPluginEnabled('wk')) { - header('Location: feature_disabled.php'); - exit(); -} -// Do we have work_id? -$cl_work_id = (int)$request->getParameter('work_id'); -if ($cl_work_id) { - $workHelper = new ttWorkHelper($err); - $work_item = $workHelper->getAvailableWorkItem($cl_work_id); - if (!$work_item) { - header('Location: access_denied.php'); - exit(); - } -} -// End of access checks. -if ($work_item) $cl_name = $work_item['subject']; - -if ($request->isPost()) { - if (!$work_item) - $cl_name = trim($request->getParameter('offer_name')); - $cl_description = trim($request->getParameter('description')); - $cl_details = trim($request->getParameter('details')); - $cl_currency_id = $request->getParameter('currency'); - if (!$cl_currency_id && $work_item) $cl_currency_id = ttWorkHelper::getCurrencyID($work_item['currency']); - $cl_budget = $request->getParameter('budget'); - $cl_payment_info = $request->getParameter('payment_info'); -} else { - if ($work_item) { - $cl_currency_id = ttWorkHelper::getCurrencyID($work_item['currency']); - } -} - -$form = new Form('offerForm'); -if ($cl_work_id) { - $form->addInput(array('type'=>'hidden','name'=>'work_id','value'=>$cl_work_id)); - $form->addInput(array('type'=>'textarea','name'=>'work_description','style'=>'width: 400px; height: 80px;','value'=>$work_item['descr_short'])); - $form->getElement('work_description')->setEnabled(false); -} -$form->addInput(array('type'=>'text','name'=>'offer_name','maxlength'=>'128','style'=>'width: 400px;','value'=>$cl_name)); -if ($work_item) $form->getElement('offer_name')->setEnabled(false); -$form->addInput(array('type'=>'textarea','name'=>'description','maxlength'=>'512','style'=>'width: 400px; height: 80px;','value'=>$cl_description)); -$form->addInput(array('type'=>'textarea','name'=>'details','style'=>'width: 400px; height: 200px;','value'=>$cl_details)); -// Add a dropdown for currency. -$currencies = ttWorkHelper::getCurrencies(); -$form->addInput(array('type'=>'combobox','name'=>'currency','data'=>$currencies,'datakeys'=>array('id','name'),'value'=>$cl_currency_id)); -if ($work_item) $form->getElement('currency')->setEnabled(false); // Do not allow changing currency for offers on existing work items. -$form->addInput(array('type'=>'floatfield','maxlength'=>'10','name'=>'budget','format'=>'.2','value'=>$cl_budget)); -$form->addInput(array('type'=>'textarea','name'=>'payment_info','maxlength'=>'256','style'=>'width: 400px; height: 40px;vertical-align: middle','value'=>$cl_payment_info)); -$form->addInput(array('type'=>'submit','name'=>'btn_add','value'=>$i18n->get('button.add'))); - -if ($request->isPost()) { - // Validate user input. - if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.offer')); - if (!ttValidString($cl_description, true)) $err->add($i18n->get('error.field'), $i18n->get('label.description')); - if (!ttValidString($cl_details, true)) $err->add($i18n->get('error.field'), $i18n->get('label.details')); - if (!ttValidString($cl_budget)) $err->add($i18n->get('error.field'), $i18n->get('label.budget')); - if (!ttValidString($cl_payment_info)) $err->add($i18n->get('error.field'), $i18n->get('label.how_to_pay')); - - // Ensure user email exists (required for workflow). - if (!$user->getEmail()) $err->add($i18n->get('error.no_email')); - - if ($err->no()) { - $workHelper = new ttWorkHelper($err); - $fields = array('work_id'=>$cl_work_id, - 'subject'=>$cl_name, - 'descr_short' => $cl_description, - 'descr_long' => $cl_details, - 'currency' => ttWorkHelper::getCurrencyName($cl_currency_id), - 'amount' => $cl_budget, - 'payment_info' => $cl_payment_info); - if ($workHelper->putOwnOffer($fields)) { - header('Location: work.php'); - exit(); - } - } -} // isPost - -$smarty->assign('work_item', $work_item); -$smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('onload', 'onLoad="document.offerForm.work_name.focus()"'); -$smarty->assign('title', $i18n->get('title.add_offer')); -$smarty->assign('content_page_name', 'offer_add.tpl'); -$smarty->display('index.tpl'); diff --git a/offer_delete.php b/offer_delete.php deleted file mode 100644 index 897248365..000000000 --- a/offer_delete.php +++ /dev/null @@ -1,75 +0,0 @@ -isPluginEnabled('wk')) { - header('Location: feature_disabled.php'); - exit(); -} -$cl_offer_id = (int)$request->getParameter('id'); -$workHelper = new ttWorkHelper($err); -$offer = $workHelper->getOwnOffer($cl_offer_id); -if (!$offer) { - header('Location: access_denied.php'); - exit(); -} -// End of access checks. - -$offer_to_delete = $offer['subject']; - -$form = new Form('offerDeleteForm'); -$form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_offer_id)); -$form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->get('label.delete'))); -$form->addInput(array('type'=>'submit','name'=>'btn_cancel','value'=>$i18n->get('button.cancel'))); - -if ($request->isPost()) { - if ($request->getParameter('btn_delete')) { - if ($workHelper->deleteOwnOffer($cl_offer_id)) { - header('Location: work.php'); - exit(); - } - } elseif ($request->getParameter('btn_cancel')) { - header('Location: work.php'); - exit(); - } -} // isPost - -$smarty->assign('offer_to_delete', $offer_to_delete); -$smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('onload', 'onLoad="document.offerDeleteForm.btn_cancel.focus()"'); -$smarty->assign('title', $i18n->get('title.delete_offer')); -$smarty->assign('content_page_name', 'offer_delete.tpl'); -$smarty->display('index.tpl'); diff --git a/offer_edit.php b/offer_edit.php deleted file mode 100644 index 436f31b37..000000000 --- a/offer_edit.php +++ /dev/null @@ -1,135 +0,0 @@ -isPluginEnabled('wk')) { - header('Location: feature_disabled.php'); - exit(); -} -$cl_offer_id = (int)$request->getParameter('id'); -$workHelper = new ttWorkHelper($err); -$offer = $workHelper->getOwnOffer($cl_offer_id); -if (!$offer) { - header('Location: access_denied.php'); - exit(); -} -// End of access checks. - -// Is this offer associated with a work item? -$work_id = $offer['work_id']; -if ($work_id) { - $work_item = $workHelper->getAvailableWorkItem($work_id); - if (!$work_item) $err->add($i18n->get('work.error.work_not_available')); -} - -$currencies = ttWorkHelper::getCurrencies(); - -if ($request->isPost()) { - $cl_name = trim($request->getParameter('offer_name')); - $cl_description = trim($request->getParameter('description')); - $cl_details = trim($request->getParameter('details')); - $cl_currency_id = $request->getParameter('currency'); - if (!$cl_currency_id && $work_item) $cl_currency_id = ttWorkHelper::getCurrencyID($work_item['currency']); - $cl_budget = $request->getParameter('budget'); - $cl_payment_info = $request->getParameter('payment_info'); -} else { - $cl_name = $offer['subject']; - $cl_description = $offer['descr_short']; - $cl_details = $offer['descr_long']; - $cl_currency_id = ttWorkHelper::getCurrencyID($offer['currency']); - $cl_budget = $offer['amount']; - $cl_payment_info = $offer['payment_info']; - $cl_status = $offer['status_label']; - $cl_moderator_comment = $offer['moderator_comment']; -} - -$show_moderator_comment = $cl_moderator_comment != null; - -$form = new Form('offerForm'); -$form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_offer_id)); -if ($work_id) { - $form->addInput(array('type'=>'textarea','name'=>'work_description','style'=>'width: 400px; height: 80px;','value'=>$work_item['descr_short'])); - $form->getElement('work_description')->setEnabled(false); -} -$form->addInput(array('type'=>'text','name'=>'offer_name','maxlength'=>'128','style'=>'width: 400px;','value'=>$cl_name)); -if ($work_id) $form->getElement('offer_name')->setEnabled(false); -$form->addInput(array('type'=>'textarea','name'=>'description','maxlength'=>'512','style'=>'width: 400px; height: 80px;','value'=>$cl_description)); -$form->addInput(array('type'=>'textarea','name'=>'details','style'=>'width: 400px; height: 200px;','value'=>$cl_details)); -$form->addInput(array('type'=>'combobox','name'=>'currency','data'=>$currencies,'datakeys'=>array('id','name'),'value'=>$cl_currency_id)); -if ($work_id) $form->getElement('currency')->setEnabled(false); -$form->addInput(array('type'=>'floatfield','maxlength'=>'10','name'=>'budget','format'=>'.2','value'=>$cl_budget)); -$form->addInput(array('type'=>'textarea','name'=>'payment_info','maxlength'=>'256','style'=>'width: 400px; height: 40px; vertical-align: middle','value'=>$cl_payment_info)); -$form->addInput(array('type'=>'text','name'=>'status','style'=>'width: 400px;','value'=>$cl_status)); -$form->getElement('status')->setEnabled(false); -$form->addInput(array('type'=>'textarea','name'=>'moderator_comment','style'=>'width: 400px; height: 80px;','value'=>$cl_moderator_comment)); -$form->getElement('moderator_comment')->setEnabled(false); -$form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); - -if ($request->isPost()) { - // Validate user input. - if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.offer')); - if (!ttValidString($cl_description, true)) $err->add($i18n->get('error.field'), $i18n->get('label.description')); - if (!ttValidString($cl_details, true)) $err->add($i18n->get('error.field'), $i18n->get('label.details')); - if (!ttValidString($cl_budget)) $err->add($i18n->get('error.field'), $i18n->get('label.budget')); - if (!ttValidString($cl_payment_info)) $err->add($i18n->get('error.field'), $i18n->get('label.how_to_pay')); - - // Ensure user email exists (required for workflow). - if (!$user->getEmail()) $err->add($i18n->get('error.no_email')); - - if ($err->no()) { - if ($request->getParameter('btn_save')) { - // Update offer information. - $fields = array('offer_id'=>$cl_offer_id, - 'subject'=>$cl_name, - 'descr_short' => $cl_description, - 'descr_long' => $cl_details, - 'currency' => ttWorkHelper::getCurrencyName($cl_currency_id), - 'amount' => $cl_budget, - 'payment_info' => $cl_payment_info); - if ($workHelper->updateOwnOffer($fields)) { - header('Location: work.php'); - exit(); - } - } - } -} // isPost - -$smarty->assign('work_item', $work_item); -$smarty->assign('show_moderator_comment', $show_moderator_comment); -$smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('title', $i18n->get('title.edit_offer')); -$smarty->assign('content_page_name', 'offer_edit.tpl'); -$smarty->display('index.tpl'); diff --git a/offer_view.php b/offer_view.php deleted file mode 100644 index ec3a98da5..000000000 --- a/offer_view.php +++ /dev/null @@ -1,81 +0,0 @@ -isPluginEnabled('wk')) { - header('Location: feature_disabled.php'); - exit(); -} -if (!ttAccessAllowed('manage_work')) { - header('Location: access_denied.php'); - exit(); -} -$offer_id = (int)$request->getParameter('id'); -$workHelper = new ttWorkHelper($err); -$offer = $workHelper->getAvailableOffer($offer_id); -if (!$offer) { - header('Location: access_denied.php'); - exit(); -} -// End of access checks. - -// Is this offer associated with a work item? -$work_id = $offer['work_id']; -if ($work_id) { - $work_item = $workHelper->getAvailableWorkItem($work_id); - if (!$work_item) $err->add($i18n->get('work.error.work_not_available')); -} - -$cl_contractor = $offer['group_name']; -$cl_name = $offer['subject']; -$cl_description = $offer['descr_short']; -$cl_details = $offer['descr_long']; -$cl_budget = $offer['amount_with_currency']; - -$form = new Form('offerForm'); -$form->addInput(array('type'=>'text','name'=>'contractor','value'=>$cl_contractor)); -$form->getElement('contractor')->setEnabled(false); -$form->addInput(array('type'=>'text','name'=>'offer_name','style'=>'width: 400px;','value'=>$cl_name)); -$form->getElement('offer_name')->setEnabled(false); -$form->addInput(array('type'=>'textarea','name'=>'description','style'=>'width: 400px; height: 80px;','value'=>$cl_description)); -$form->getElement('description')->setEnabled(false); -$form->addInput(array('type'=>'textarea','name'=>'details','style'=>'width: 400px; height: 200px;','value'=>$cl_details)); -$form->getElement('details')->setEnabled(false); -$form->addInput(array('type'=>'text','name'=>'budget','value'=>$cl_budget)); -$form->getElement('budget')->setEnabled(false); - - -$smarty->assign('offer_id', $offer_id); -$smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('title', $i18n->get('title.offer')); -$smarty->assign('content_page_name', 'offer_view.tpl'); -$smarty->display('index.tpl'); diff --git a/offer_view_own.php b/offer_view_own.php deleted file mode 100644 index 4f3c7b7a2..000000000 --- a/offer_view_own.php +++ /dev/null @@ -1,77 +0,0 @@ -isPluginEnabled('wk')) { - header('Location: feature_disabled.php'); - exit(); -} -if (!ttAccessAllowed('manage_work')) { - header('Location: access_denied.php'); - exit(); -} -$offer_id = (int)$request->getParameter('id'); -$workHelper = new ttWorkHelper($err); -$offer = $workHelper->getOwnOffer($offer_id); -if (!$offer) { - header('Location: access_denied.php'); - exit(); -} -// End of access checks. - -// Is this offer associated with a work item? -$work_id = $offer['work_id']; -if ($work_id) { - $work_item = $workHelper->getAvailableWorkItem($work_id); - if (!$work_item) $err->add($i18n->get('work.error.work_not_available')); -} - -$cl_name = $offer['subject']; -$cl_description = $offer['descr_short']; -$cl_details = $offer['descr_long']; -$cl_budget = $offer['amount_with_currency']; - -$form = new Form('offerForm'); -$form->addInput(array('type'=>'text','name'=>'offer_name','style'=>'width: 400px;','value'=>$cl_name)); -$form->getElement('offer_name')->setEnabled(false); -$form->addInput(array('type'=>'textarea','name'=>'description','style'=>'width: 400px; height: 80px;','value'=>$cl_description)); -$form->getElement('description')->setEnabled(false); -$form->addInput(array('type'=>'textarea','name'=>'details','style'=>'width: 400px; height: 200px;','value'=>$cl_details)); -$form->getElement('details')->setEnabled(false); -$form->addInput(array('type'=>'text','name'=>'budget','value'=>$cl_budget)); -$form->getElement('budget')->setEnabled(false); - -$smarty->assign('work_item', $work_item); -$smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('title', $i18n->get('title.offer')); -$smarty->assign('content_page_name', 'offer_view_own.tpl'); -$smarty->display('index.tpl'); diff --git a/work.php b/work.php deleted file mode 100644 index f7cfeb91e..000000000 --- a/work.php +++ /dev/null @@ -1,65 +0,0 @@ -isPluginEnabled('wk')) { - header('Location: feature_disabled.php'); - exit(); -} -// End of access checks. - -$workHelper = new ttWorkHelper($err); -$groupItems = $workHelper->getGroupItems(); // All group items. -if($user->can('manage_work')) { - $own_work_items = $groupItems['own_work_items']; // Own work items this group is outsourcing. - $available_offers = $groupItems['available_offers']; // Available offers from other organizations. -} -if($user->can('bid_on_work')) { - $available_work_items = $groupItems['available_work_items']; // Currently available work items from other orgs. - $own_offers = $groupItems['own_offers']; // Own offers this group makes available to other groups. -} -if($user->can('update_work')) { - // $in_progress_work = ttWorkHelper::getInProgressWork(); // Work items in progress for other groups. - // $completed_work = ttWorkHelper::getCompletedWork(); // Completed work items for other groups. -} -// TODO: review access rights for the code above. - -$smarty->assign('own_work_items', $own_work_items); -$smarty->assign('available_work_items', $available_work_items); -$smarty->assign('own_offers', $own_offers); -$smarty->assign('available_offers', $available_offers); -$smarty->assign('title', $i18n->get('title.work')); -$smarty->assign('content_page_name', 'work.tpl'); -$smarty->display('index.tpl'); diff --git a/work/admin_offer_delete.php b/work/admin_offer_delete.php index 51c46fce3..a1bd5fac1 100644 --- a/work/admin_offer_delete.php +++ b/work/admin_offer_delete.php @@ -32,14 +32,14 @@ // Access checks. if (!ttAccessAllowed('administer_site')) { - header('Location: access_denied.php'); + header('Location: ../access_denied.php'); exit(); } $cl_offer_id = (int)$request->getParameter('id'); $adminWorkHelper = new ttAdminWorkHelper($err); $offer = $adminWorkHelper->getOffer($cl_offer_id); if (!$offer) { - header('Location: access_denied.php'); + header('Location: ../access_denied.php'); exit(); } // End of access checks. diff --git a/work/admin_offer_edit.php b/work/admin_offer_edit.php index 32ed2a8ed..ab795c136 100644 --- a/work/admin_offer_edit.php +++ b/work/admin_offer_edit.php @@ -34,14 +34,14 @@ // Access checks. if (!ttAccessAllowed('administer_site')) { - header('Location: access_denied.php'); + header('Location: ../access_denied.php'); exit(); } $cl_offer_id = (int)$request->getParameter('id'); $adminWorkHelper = new ttAdminWorkHelper($err); $offer = $adminWorkHelper->getOffer($cl_offer_id); if (!$offer) { - header('Location: access_denied.php'); + header('Location: ../access_denied.php'); exit(); } // End of access checks. diff --git a/work/admin_work.php b/work/admin_work.php index 19b420987..86a029a4a 100644 --- a/work/admin_work.php +++ b/work/admin_work.php @@ -31,7 +31,7 @@ // Access checks. if (!ttAccessAllowed('administer_site')) { - header('Location: access_denied.php'); + header('Location: ../access_denied.php'); exit(); } // End of access checks. diff --git a/work/admin_work_delete.php b/work/admin_work_delete.php index 38084e565..11b599430 100644 --- a/work/admin_work_delete.php +++ b/work/admin_work_delete.php @@ -32,14 +32,14 @@ // Access checks. if (!ttAccessAllowed('administer_site')) { - header('Location: access_denied.php'); + header('Location: ../access_denied.php'); exit(); } $cl_work_id = (int)$request->getParameter('id'); $adminWorkHelper = new ttAdminWorkHelper($err); $work_item = $adminWorkHelper->getWorkItem($cl_work_id); if (!$work_item) { - header('Location: access_denied.php'); + header('Location: ../access_denied.php'); exit(); } // End of access checks. diff --git a/work/admin_work_edit.php b/work/admin_work_edit.php index 626b1a77e..51169325c 100644 --- a/work/admin_work_edit.php +++ b/work/admin_work_edit.php @@ -34,14 +34,14 @@ // Access checks. if (!ttAccessAllowed('administer_site')) { - header('Location: access_denied.php'); + header('Location: ../access_denied.php'); exit(); } $cl_work_id = (int)$request->getParameter('id'); $adminWorkHelper = new ttAdminWorkHelper($err); $work_item = $adminWorkHelper->getWorkItem($cl_work_id); if (!$work_item) { - header('Location: access_denied.php'); + header('Location: ../access_denied.php'); exit(); } // Do we have offer_id? @@ -49,7 +49,7 @@ if ($offer_id) { $offer = $adminWorkHelper->getOffer($offer_id); if (!$offer) { - header('Location: access_denied.php'); + header('Location: ../access_denied.php'); exit(); } } diff --git a/work/offer_add.php b/work/offer_add.php index 159bc3241..bafdae216 100644 --- a/work/offer_add.php +++ b/work/offer_add.php @@ -32,11 +32,11 @@ // Access checks. if (!ttAccessAllowed('manage_work')) { - header('Location: access_denied.php'); + header('Location: ../access_denied.php'); exit(); } if (!$user->isPluginEnabled('wk')) { - header('Location: feature_disabled.php'); + header('Location: ../feature_disabled.php'); exit(); } // Do we have work_id? @@ -45,7 +45,7 @@ $workHelper = new ttWorkHelper($err); $work_item = $workHelper->getAvailableWorkItem($cl_work_id); if (!$work_item) { - header('Location: access_denied.php'); + header('Location: ../access_denied.php'); exit(); } } diff --git a/work/offer_delete.php b/work/offer_delete.php index c8772599a..fd3d2e7d1 100644 --- a/work/offer_delete.php +++ b/work/offer_delete.php @@ -32,18 +32,18 @@ // Access checks. if (!ttAccessAllowed('bid_on_work')) { - header('Location: access_denied.php'); + header('Location: ../access_denied.php'); exit(); } if (!$user->isPluginEnabled('wk')) { - header('Location: feature_disabled.php'); + header('Location: ../feature_disabled.php'); exit(); } $cl_offer_id = (int)$request->getParameter('id'); $workHelper = new ttWorkHelper($err); $offer = $workHelper->getOwnOffer($cl_offer_id); if (!$offer) { - header('Location: access_denied.php'); + header('Location: ../access_denied.php'); exit(); } // End of access checks. diff --git a/work/offer_edit.php b/work/offer_edit.php index 5eba66378..bd2172210 100644 --- a/work/offer_edit.php +++ b/work/offer_edit.php @@ -32,18 +32,18 @@ // Access checks. if (!ttAccessAllowed('bid_on_work')) { - header('Location: access_denied.php'); + header('Location: ../access_denied.php'); exit(); } if (!$user->isPluginEnabled('wk')) { - header('Location: feature_disabled.php'); + header('Location: ../feature_disabled.php'); exit(); } $cl_offer_id = (int)$request->getParameter('id'); $workHelper = new ttWorkHelper($err); $offer = $workHelper->getOwnOffer($cl_offer_id); if (!$offer) { - header('Location: access_denied.php'); + header('Location: ../access_denied.php'); exit(); } // End of access checks. diff --git a/work/offer_view.php b/work/offer_view.php index 614b93188..1e045bf20 100644 --- a/work/offer_view.php +++ b/work/offer_view.php @@ -32,18 +32,18 @@ // Access checks. if (!$user->isPluginEnabled('wk')) { - header('Location: feature_disabled.php'); + header('Location: ../feature_disabled.php'); exit(); } if (!ttAccessAllowed('manage_work')) { - header('Location: access_denied.php'); + header('Location: ../access_denied.php'); exit(); } $offer_id = (int)$request->getParameter('id'); $workHelper = new ttWorkHelper($err); $offer = $workHelper->getAvailableOffer($offer_id); if (!$offer) { - header('Location: access_denied.php'); + header('Location: ../access_denied.php'); exit(); } // End of access checks. diff --git a/work/offer_view_own.php b/work/offer_view_own.php index c87013d08..57b1b95b3 100644 --- a/work/offer_view_own.php +++ b/work/offer_view_own.php @@ -32,18 +32,18 @@ // Access checks. if (!$user->isPluginEnabled('wk')) { - header('Location: feature_disabled.php'); + header('Location: ../feature_disabled.php'); exit(); } if (!ttAccessAllowed('manage_work')) { - header('Location: access_denied.php'); + header('Location: ../access_denied.php'); exit(); } $offer_id = (int)$request->getParameter('id'); $workHelper = new ttWorkHelper($err); $offer = $workHelper->getOwnOffer($offer_id); if (!$offer) { - header('Location: access_denied.php'); + header('Location: ../access_denied.php'); exit(); } // End of access checks. diff --git a/work/work.php b/work/work.php index 4f40e4ca9..b043690b4 100644 --- a/work/work.php +++ b/work/work.php @@ -31,11 +31,11 @@ // Access checks. if (!(ttAccessAllowed('update_work') || ttAccessAllowed('bid_on_work') || ttAccessAllowed('manage_work'))) { - header('Location: access_denied.php'); + header('Location: ../access_denied.php'); exit(); } if (!$user->isPluginEnabled('wk')) { - header('Location: feature_disabled.php'); + header('Location: ../feature_disabled.php'); exit(); } // End of access checks. diff --git a/work/work_add.php b/work/work_add.php index c0b8795fd..df12c9155 100644 --- a/work/work_add.php +++ b/work/work_add.php @@ -32,11 +32,11 @@ // Access checks. if (!ttAccessAllowed('manage_work')) { - header('Location: access_denied.php'); + header('Location: ../access_denied.php'); exit(); } if (!$user->isPluginEnabled('wk')) { - header('Location: feature_disabled.php'); + header('Location: ../feature_disabled.php'); exit(); } // Do we have offer_id? @@ -45,7 +45,7 @@ $workHelper = new ttWorkHelper($err); $offer = $workHelper->getAvailableOffer($cl_offer_id); if (!$offer) { - header('Location: access_denied.php'); + header('Location: ../access_denied.php'); exit(); } } diff --git a/work/work_delete.php b/work/work_delete.php index 75a111da3..1d94603ab 100644 --- a/work/work_delete.php +++ b/work/work_delete.php @@ -32,18 +32,18 @@ // Access checks. if (!ttAccessAllowed('manage_work')) { - header('Location: access_denied.php'); + header('Location: ../access_denied.php'); exit(); } if (!$user->isPluginEnabled('wk')) { - header('Location: feature_disabled.php'); + header('Location: ../feature_disabled.php'); exit(); } $cl_work_id = (int)$request->getParameter('id'); $workHelper = new ttWorkHelper($err); $work_item = $workHelper->getOwnWorkItem($cl_work_id); if (!$work_item) { - header('Location: access_denied.php'); + header('Location: ../access_denied.php'); exit(); } // End of access checks. diff --git a/work/work_edit.php b/work/work_edit.php index f265da859..7e27106b8 100644 --- a/work/work_edit.php +++ b/work/work_edit.php @@ -32,18 +32,18 @@ // Access checks. if (!ttAccessAllowed('manage_work')) { - header('Location: access_denied.php'); + header('Location: ../access_denied.php'); exit(); } if (!$user->isPluginEnabled('wk')) { - header('Location: feature_disabled.php'); + header('Location: ../feature_disabled.php'); exit(); } $cl_work_id = (int)$request->getParameter('id'); $workHelper = new ttWorkHelper($err); $work_item = $workHelper->getOwnWorkItem($cl_work_id); if (!$work_item) { - header('Location: access_denied.php'); + header('Location: ../access_denied.php'); exit(); } // Do we have offer_id? @@ -51,7 +51,7 @@ if ($offer_id) { $offer = $workHelper->getAvailableOffer($offer_id); if (!$offer) { - header('Location: access_denied.php'); + header('Location: ../access_denied.php'); exit(); } } diff --git a/work/work_message.php b/work/work_message.php index ca74915d4..9a009aa82 100644 --- a/work/work_message.php +++ b/work/work_message.php @@ -32,11 +32,11 @@ // Access checks. if (!ttAccessAllowed('manage_work')) { - header('Location: access_denied.php'); + header('Location: ../access_denied.php'); exit(); } if (!$user->isPluginEnabled('wk')) { - header('Location: feature_disabled.php'); + header('Location: ../feature_disabled.php'); exit(); } // Do we have work_id? @@ -45,7 +45,7 @@ $workHelper = new ttWorkHelper($err); $work_item = $workHelper->getAvailableWorkItem($cl_work_id); if (!$work_item) { - header('Location: access_denied.php'); + header('Location: ../access_denied.php'); exit(); } } diff --git a/work/work_offer_view.php b/work/work_offer_view.php index dc1074942..c0dd5ee1a 100644 --- a/work/work_offer_view.php +++ b/work/work_offer_view.php @@ -33,18 +33,18 @@ // Access checks. if (!$user->isPluginEnabled('wk')) { - header('Location: feature_disabled.php'); + header('Location: ../feature_disabled.php'); exit(); } if (!ttAccessAllowed('manage_work')) { - header('Location: access_denied.php'); + header('Location: ../access_denied.php'); exit(); } $cl_offer_id = (int)$request->getParameter('id'); $workHelper = new ttWorkHelper($err); $offer = $workHelper->getOwnWorkItemOffer($cl_offer_id); if (!$offer) { - header('Location: access_denied.php'); + header('Location: ../access_denied.php'); exit(); } // End of access checks. diff --git a/work/work_offers.php b/work/work_offers.php index e045892ea..eae9841bb 100644 --- a/work/work_offers.php +++ b/work/work_offers.php @@ -31,18 +31,18 @@ // Access checks. if (!ttAccessAllowed('manage_work')) { - header('Location: access_denied.php'); + header('Location: ../access_denied.php'); exit(); } if (!$user->isPluginEnabled('wk')) { - header('Location: feature_disabled.php'); + header('Location: ../feature_disabled.php'); exit(); } $work_id = (int)$request->getParameter('id'); $workHelper = new ttWorkHelper($err); $work_item = $workHelper->getOwnWorkItem($work_id); if (!$work_item) { - header('Location: access_denied.php'); + header('Location: ../access_denied.php'); exit(); } // End of access checks. diff --git a/work/work_view.php b/work/work_view.php index 2bd8d3fd3..cb73f2eed 100644 --- a/work/work_view.php +++ b/work/work_view.php @@ -32,18 +32,18 @@ // Access checks. if (!$user->isPluginEnabled('wk')) { - header('Location: feature_disabled.php'); + header('Location: ../feature_disabled.php'); exit(); } if (!ttAccessAllowed('bid_on_work')) { - header('Location: access_denied.php'); + header('Location: ../access_denied.php'); exit(); } $cl_work_id = (int)$request->getParameter('id'); $workHelper = new ttWorkHelper($err); $work_item = $workHelper->getAvailableWorkItem($cl_work_id); if (!$work_item) { - header('Location: access_denied.php'); + header('Location: ../access_denied.php'); exit(); } // End of access checks. diff --git a/work/work_view_own.php b/work/work_view_own.php index 9930eaf99..c4b887e7e 100644 --- a/work/work_view_own.php +++ b/work/work_view_own.php @@ -32,18 +32,18 @@ // Access checks. if (!$user->isPluginEnabled('wk')) { - header('Location: feature_disabled.php'); + header('Location: ../feature_disabled.php'); exit(); } if (!ttAccessAllowed('manage_work')) { - header('Location: access_denied.php'); + header('Location: ../access_denied.php'); exit(); } $work_id = (int)$request->getParameter('id'); $workHelper = new ttWorkHelper($err); $work_item = $workHelper->getOwnWorkItem($work_id); if (!$work_item) { - header('Location: access_denied.php'); + header('Location: ../access_denied.php'); exit(); } // Do we have offer_id? @@ -51,7 +51,7 @@ if ($offer_id) { $offer = $workHelper->getAvailableOffer($offer_id); if (!$offer) { - header('Location: access_denied.php'); + header('Location: ../access_denied.php'); exit(); } } diff --git a/work_add.php b/work_add.php deleted file mode 100644 index 68bfe06ea..000000000 --- a/work_add.php +++ /dev/null @@ -1,122 +0,0 @@ -isPluginEnabled('wk')) { - header('Location: feature_disabled.php'); - exit(); -} -// Do we have offer_id? -$cl_offer_id = (int)$request->getParameter('offer_id'); -if ($cl_offer_id) { - $workHelper = new ttWorkHelper($err); - $offer = $workHelper->getAvailableOffer($cl_offer_id); - if (!$offer) { - header('Location: access_denied.php'); - exit(); - } -} -// End of access checks. - -if ($request->isPost()) { - $cl_name = trim($request->getParameter('work_name')); - $cl_work_type = $request->getParameter('work_type'); - $cl_description = trim($request->getParameter('description')); - $cl_details = trim($request->getParameter('details')); - $cl_currency_id = $request->getParameter('currency'); - $cl_budget = $request->getParameter('budget'); -} -// Override some fields for work being created on an available offer. -if ($offer) { - $cl_name = $offer['subject']; - $cl_work_type = 0; // one-time work - $cl_currency_id = ttWorkHelper::getCurrencyID($offer['currency']); - $cl_budget = $offer['amount']; -} - -$form = new Form('workForm'); -if ($offer) - $form->addInput(array('type'=>'hidden','name'=>'offer_id','value'=>$cl_offer_id)); -$form->addInput(array('type'=>'text','name'=>'work_name','maxlength'=>'128','style'=>'width: 400px;','value'=>$cl_name)); -$WORK_TYPE_OPTIONS = array('0'=>$i18n->get('work.type.one_time'),'1'=>$i18n->get('work.type.ongoing')); -$form->addInput(array('type'=>'combobox','name'=>'work_type','data'=>$WORK_TYPE_OPTIONS,'value'=>$cl_work_type)); -$form->addInput(array('type'=>'textarea','name'=>'description','maxlength'=>'512','style'=>'width: 400px; height: 80px;','value'=>$cl_description)); -$form->addInput(array('type'=>'textarea','name'=>'details','style'=>'width: 400px; height: 200px;','value'=>$cl_details)); -// Add a dropdown for currency. -$currencies = ttWorkHelper::getCurrencies(); -$form->addInput(array('type'=>'combobox','name'=>'currency','data'=>$currencies,'datakeys'=>array('id','name'),'value'=>$cl_currency_id)); -$form->addInput(array('type'=>'floatfield','maxlength'=>'10','name'=>'budget','format'=>'.2','value'=>$cl_budget)); -$form->addInput(array('type'=>'submit','name'=>'btn_add','value'=>$i18n->get('button.add'))); -// Disable some controls for work being created on an available offer. -if ($offer) { - $form->getElement('work_name')->setEnabled(false); - $form->getElement('work_type')->setEnabled(false); - $form->getElement('currency')->setEnabled(false); - $form->getElement('budget')->setEnabled(false); -} - -if ($request->isPost()) { - // Validate user input. - if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.work')); - if (!ttValidString($cl_description, true)) $err->add($i18n->get('error.field'), $i18n->get('label.description')); - if (!ttValidString($cl_details, true)) $err->add($i18n->get('error.field'), $i18n->get('label.details')); - if (!ttValidString($cl_budget)) $err->add($i18n->get('error.field'), $i18n->get('label.budget')); - - // Ensure user email exists (required for workflow). - if (!$user->getEmail()) $err->add($i18n->get('error.no_email')); - - if ($err->no()) { - $workHelper = new ttWorkHelper($err); - $fields = array('offer_id' => $cl_offer_id, - 'subject' => $cl_name, - 'type' => $cl_work_type, - 'descr_short' => $cl_description, - 'descr_long' => $cl_details, - 'currency' => ttWorkHelper::getCurrencyName($cl_currency_id), - 'amount' => $cl_budget); - if ($workHelper->putOwnWorkItem($fields)) { - header('Location: work.php'); - exit(); - } - } -} // isPost - -$smarty->assign('offer', $offer); -$smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('onload', 'onLoad="document.workForm.work_name.focus()"'); -$smarty->assign('title', $i18n->get('title.add_work')); -$smarty->assign('content_page_name', 'work_add.tpl'); -$smarty->display('index.tpl'); diff --git a/work_delete.php b/work_delete.php deleted file mode 100644 index 87d7bd7c0..000000000 --- a/work_delete.php +++ /dev/null @@ -1,75 +0,0 @@ -isPluginEnabled('wk')) { - header('Location: feature_disabled.php'); - exit(); -} -$cl_work_id = (int)$request->getParameter('id'); -$workHelper = new ttWorkHelper($err); -$work_item = $workHelper->getOwnWorkItem($cl_work_id); -if (!$work_item) { - header('Location: access_denied.php'); - exit(); -} -// End of access checks. - -$work_to_delete = $work_item['subject']; - -$form = new Form('workDeleteForm'); -$form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_work_id)); -$form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->get('label.delete'))); -$form->addInput(array('type'=>'submit','name'=>'btn_cancel','value'=>$i18n->get('button.cancel'))); - -if ($request->isPost()) { - if ($request->getParameter('btn_delete')) { - if ($workHelper->deleteOwnWorkItem($cl_work_id)) { - header('Location: work.php'); - exit(); - } - } elseif ($request->getParameter('btn_cancel')) { - header('Location: work.php'); - exit(); - } -} // isPost - -$smarty->assign('work_to_delete', $work_to_delete); -$smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('onload', 'onLoad="document.workDeleteForm.btn_cancel.focus()"'); -$smarty->assign('title', $i18n->get('title.delete_work')); -$smarty->assign('content_page_name', 'work_delete.tpl'); -$smarty->display('index.tpl'); diff --git a/work_edit.php b/work_edit.php deleted file mode 100644 index 916a9aeef..000000000 --- a/work_edit.php +++ /dev/null @@ -1,151 +0,0 @@ -isPluginEnabled('wk')) { - header('Location: feature_disabled.php'); - exit(); -} -$cl_work_id = (int)$request->getParameter('id'); -$workHelper = new ttWorkHelper($err); -$work_item = $workHelper->getOwnWorkItem($cl_work_id); -if (!$work_item) { - header('Location: access_denied.php'); - exit(); -} -// Do we have offer_id? -$offer_id = $work_item['offer_id']; -if ($offer_id) { - $offer = $workHelper->getAvailableOffer($offer_id); - if (!$offer) { - header('Location: access_denied.php'); - exit(); - } -} -// End of access checks. - -$currencies = ttWorkHelper::getCurrencies(); - -if ($request->isPost()) { - $cl_name = trim($request->getParameter('work_name')); - $cl_work_type = $request->getParameter('work_type'); - $cl_description = trim($request->getParameter('description')); - $cl_details = trim($request->getParameter('details')); - $cl_currency_id = $request->getParameter('currency'); - $cl_budget = $request->getParameter('budget'); -} else { - $cl_name = $work_item['subject']; - $cl_work_type = $work_item['type']; - $cl_description = $work_item['descr_short']; - $cl_details = $work_item['descr_long']; - $cl_currency_id = ttWorkHelper::getCurrencyID($work_item['currency']); - $cl_budget = $work_item['amount']; - $cl_status = $work_item['status_label']; - $cl_moderator_comment = $work_item['moderator_comment']; -} -// Override some fields for work on an available offer. -if ($offer) { - $cl_name = $offer['subject']; - $cl_work_type = 0; // one-time work - $cl_currency_id = ttWorkHelper::getCurrencyID($offer['currency']); - $cl_budget = $offer['amount']; -} - -$show_moderator_comment = $cl_moderator_comment != null; - -$form = new Form('workForm'); -$form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_work_id)); -$form->addInput(array('type'=>'text','name'=>'work_name','maxlength'=>'128','style'=>'width: 400px;','value'=>$cl_name)); -$WORK_TYPE_OPTIONS = array('0'=>$i18n->get('work.type.one_time'),'1'=>$i18n->get('work.type.ongoing')); -$form->addInput(array('type'=>'combobox','name'=>'work_type','data'=>$WORK_TYPE_OPTIONS,'value'=>$cl_work_type)); -$form->addInput(array('type'=>'textarea','name'=>'description','maxlength'=>'512','style'=>'width: 400px; height: 80px;','value'=>$cl_description)); -$form->addInput(array('type'=>'textarea','name'=>'details','style'=>'width: 400px; height: 200px;','value'=>$cl_details)); -$form->addInput(array('type'=>'combobox','name'=>'currency','data'=>$currencies,'datakeys'=>array('id','name'),'value'=>$cl_currency_id)); -$form->addInput(array('type'=>'floatfield','maxlength'=>'10','name'=>'budget','format'=>'.2','value'=>$cl_budget)); -$form->addInput(array('type'=>'text','name'=>'status','style'=>'width: 400px;','value'=>$cl_status)); -$form->getElement('status')->setEnabled(false); -$form->addInput(array('type'=>'textarea','name'=>'moderator_comment','style'=>'width: 400px; height: 80px;','value'=>$cl_moderator_comment)); -$form->getElement('moderator_comment')->setEnabled(false); -$form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); -// Disable some controls for work on an available offer. -if ($offer) { - $form->getElement('work_name')->setEnabled(false); - $form->getElement('work_type')->setEnabled(false); - $form->getElement('currency')->setEnabled(false); - $form->getElement('budget')->setEnabled(false); -} - -if ($request->isPost()) { - // Validate user input. - if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.work')); - if (!ttValidString($cl_description, true)) $err->add($i18n->get('error.field'), $i18n->get('label.description')); - if (!ttValidString($cl_details, true)) $err->add($i18n->get('error.field'), $i18n->get('label.details')); - if (!ttValidString($cl_budget)) $err->add($i18n->get('error.field'), $i18n->get('label.budget')); - - // Ensure user email exists (required for workflow). - if (!$user->getEmail()) $err->add($i18n->get('error.no_email')); - - if ($err->no()) { - if ($request->getParameter('btn_save')) { - // Update work information. - $fields = array('work_id'=>$cl_work_id, - 'type'=>$cl_work_type, - 'subject'=>$cl_name, - 'descr_short' => $cl_description, - 'descr_long' => $cl_details, - 'currency' => ttWorkHelper::getCurrencyName($cl_currency_id), - 'amount' => $cl_budget); - if ($offer_id > 0) { - if ($workHelper->updateOwnWorkItemOnOffer($fields)) { - header('Location: work.php'); - exit(); - } - } else { - if ($workHelper->updateOwnWorkItem($fields)) { - header('Location: work.php'); - exit(); - } - } - } - } -} // isPost - -$smarty->assign('offer', $offer); -$smarty->assign('show_moderator_comment', $show_moderator_comment); -$smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('title', $i18n->get('title.edit_work')); -$smarty->assign('content_page_name', 'work_edit.tpl'); -$smarty->display('index.tpl'); diff --git a/work_message.php b/work_message.php deleted file mode 100644 index 1a06143e6..000000000 --- a/work_message.php +++ /dev/null @@ -1,97 +0,0 @@ -isPluginEnabled('wk')) { - header('Location: feature_disabled.php'); - exit(); -} -// Do we have work_id? -$cl_work_id = (int)$request->getParameter('work_id'); -if ($cl_work_id) { - $workHelper = new ttWorkHelper($err); - $work_item = $workHelper->getAvailableWorkItem($cl_work_id); - if (!$work_item) { - header('Location: access_denied.php'); - exit(); - } -} -// End of access checks. -if ($work_item) $cl_name = $work_item['subject']; - -if ($request->isPost()) { - $cl_message_body = trim($request->getParameter('message_body')); -} - - - - - - - - -$form = new Form('messageForm'); -if ($cl_work_id) { - $form->addInput(array('type'=>'hidden','name'=>'work_id','value'=>$cl_work_id)); -} -$form->addInput(array('type'=>'textarea','name'=>'message_body','style'=>'width: 400px; height: 80px;vertical-align: middle','value'=>$cl_message_body)); -$form->addInput(array('type'=>'submit','name'=>'btn_send','value'=>$i18n->get('work.button.send_message'))); - -if ($request->isPost()) { - // Validate user input. - if (!ttValidString($cl_message_body)) $err->add($i18n->get('error.field'), $i18n->get('work.label.message')); - - // Ensure user email exists (required for workflow). - if (!$user->getEmail()) $err->add($i18n->get('error.no_email')); - - if ($err->no()) { - $workHelper = new ttWorkHelper($err); - $fields = array('work_id'=>$cl_work_id, - 'message_body' => $cl_message_body); - if ($workHelper->sendMessage($fields)) { - $msg->add($i18n->get('work.msg.message_sent')); - // header('Location: work.php'); // TODO: where to redirect? - // exit(); - } - } -} // isPost - -$smarty->assign('work_item', $work_item); -$smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('onload', 'onLoad="document.offerForm.work_name.focus()"'); -$smarty->assign('title', $i18n->get('work.title.send_message')); -$smarty->assign('content_page_name', 'work_message.tpl'); -$smarty->display('index.tpl'); diff --git a/work_offer_view.php b/work_offer_view.php deleted file mode 100644 index 84fdc1cd0..000000000 --- a/work_offer_view.php +++ /dev/null @@ -1,123 +0,0 @@ -isPluginEnabled('wk')) { - header('Location: feature_disabled.php'); - exit(); -} -if (!ttAccessAllowed('manage_work')) { - header('Location: access_denied.php'); - exit(); -} -$cl_offer_id = (int)$request->getParameter('id'); -$workHelper = new ttWorkHelper($err); -$offer = $workHelper->getOwnWorkItemOffer($cl_offer_id); -if (!$offer) { - header('Location: access_denied.php'); - exit(); -} -// End of access checks. - -// Get an associated work item. -$work_item = $workHelper->getOwnWorkItem($offer['work_id']); -if (!$work_item) $err->add($i18n->get('work.error.work_not_available')); - -if ($request->isPost()) { - $cl_client_comment = $request->getParameter('client_comment'); -} else { - $cl_client_comment = $offer['client_comment']; -} - -$cl_contractor = $offer['group_name']; -$cl_name = $offer['subject']; -$cl_description = $offer['descr_short']; -$cl_details = $offer['descr_long']; -$cl_budget = $offer['amount_with_currency']; -$cl_status = $offer['status_label']; - -$form = new Form('offerForm'); -$form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_offer_id)); -$form->addInput(array('type'=>'text','name'=>'contractor','value'=>$cl_contractor)); -$form->getElement('contractor')->setEnabled(false); -$form->addInput(array('type'=>'text','name'=>'offer_name','style'=>'width: 400px;','value'=>$cl_name)); -$form->getElement('offer_name')->setEnabled(false); -$form->addInput(array('type'=>'textarea','name'=>'description','style'=>'width: 400px; height: 80px;','value'=>$cl_description)); -$form->getElement('description')->setEnabled(false); -$form->addInput(array('type'=>'textarea','name'=>'details','style'=>'width: 400px; height: 200px;','value'=>$cl_details)); -$form->getElement('details')->setEnabled(false); -$form->addInput(array('type'=>'text','name'=>'budget','value'=>$cl_budget)); -$form->getElement('budget')->setEnabled(false); -$form->addInput(array('type'=>'text','name'=>'status','style'=>'width: 400px;','value'=>$cl_status)); -$form->getElement('status')->setEnabled(false); -if ($offer['status'] == STATUS_APPROVED) { - $form->addInput(array('type'=>'submit','name'=>'btn_accept','value'=>$i18n->get('work.button.accept'))); - $form->addInput(array('type'=>'submit','name'=>'btn_decline','value'=>$i18n->get('work.button.decline'))); -} -$form->addInput(array('type'=>'textarea','name'=>'client_comment','style'=>'width: 400px; height: 80px;','value'=>$cl_client_comment)); - -if ($request->isPost()) { - // Validate user input. - if (!ttValidString($cl_client_comment, true)) $err->add($i18n->get('error.field'), $i18n->get('label.comment')); - - // Ensure user email exists (required for workflow). - if (!$user->getEmail()) $err->add($i18n->get('error.no_email')); - - if ($err->no()) { - $workHelper = new ttWorkHelper($err); - $fields = array('offer_id'=>$cl_offer_id, - 'client_comment'=>$cl_client_comment); - - if ($request->getParameter('btn_accept')) { - // Accept offer. - if ($workHelper->acceptOwnWorkItemOffer($fields)) { - header('Location: work_offer_view.php?id='.$cl_offer_id); - exit(); - } - } - - if ($request->getParameter('btn_decline')) { - // Decline offer. - if ($workHelper->declineOwnWorkItemOffer($fields)) { - header('Location: work_offer_view.php?id='.$cl_offer_id); - exit(); - } - } - } -} // isPost - -$smarty->assign('work_item', $work_item); -$smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('title', $i18n->get('title.offer')); -$smarty->assign('content_page_name', 'work_offer_view.tpl'); -$smarty->display('index.tpl'); diff --git a/work_offers.php b/work_offers.php deleted file mode 100644 index 9da3930aa..000000000 --- a/work_offers.php +++ /dev/null @@ -1,56 +0,0 @@ -isPluginEnabled('wk')) { - header('Location: feature_disabled.php'); - exit(); -} -$work_id = (int)$request->getParameter('id'); -$workHelper = new ttWorkHelper($err); -$work_item = $workHelper->getOwnWorkItem($work_id); -if (!$work_item) { - header('Location: access_denied.php'); - exit(); -} -// End of access checks. - -$work_item_offers = $workHelper->getOwnWorkItemOffers($work_id); - -$smarty->assign('work_item', $work_item); -$smarty->assign('work_item_offers', $work_item_offers); -$smarty->assign('title', $i18n->get('work.label.offers')); -$smarty->assign('content_page_name', 'work_offers.tpl'); -$smarty->display('index.tpl'); diff --git a/work_view.php b/work_view.php deleted file mode 100644 index 03995e646..000000000 --- a/work_view.php +++ /dev/null @@ -1,74 +0,0 @@ -isPluginEnabled('wk')) { - header('Location: feature_disabled.php'); - exit(); -} -if (!ttAccessAllowed('bid_on_work')) { - header('Location: access_denied.php'); - exit(); -} -$cl_work_id = (int)$request->getParameter('id'); -$workHelper = new ttWorkHelper($err); -$work_item = $workHelper->getAvailableWorkItem($cl_work_id); -if (!$work_item) { - header('Location: access_denied.php'); - exit(); -} -// End of access checks. - -$cl_client = $work_item['group_name']; -$cl_name = $work_item['subject']; -$cl_description = $work_item['descr_short']; -$cl_details = $work_item['descr_long']; -$cl_budget = $work_item['amount_with_currency']; - -$form = new Form('workForm'); -$form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_work_id)); -$form->addInput(array('type'=>'text','name'=>'client','value'=>$cl_client)); -$form->getElement('client')->setEnabled(false); -$form->addInput(array('type'=>'textarea','name'=>'work_name','style'=>'width: 400px;','value'=>$cl_name)); -$form->getElement('work_name')->setEnabled(false); -$form->addInput(array('type'=>'textarea','name'=>'description','style'=>'width: 400px; height: 80px;','value'=>$cl_description)); -$form->getElement('description')->setEnabled(false); -$form->addInput(array('type'=>'textarea','name'=>'details','style'=>'width: 400px; height: 200px;','value'=>$cl_details)); -$form->getElement('details')->setEnabled(false); -$form->addInput(array('type'=>'text','name'=>'budget','value'=>$cl_budget)); -$form->getElement('budget')->setEnabled(false); - -$smarty->assign('work_id', $cl_work_id); -$smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('title', $i18n->get('title.work')); -$smarty->assign('content_page_name', 'work_view.tpl'); -$smarty->display('index.tpl'); diff --git a/work_view_own.php b/work_view_own.php deleted file mode 100644 index 15e57632b..000000000 --- a/work_view_own.php +++ /dev/null @@ -1,79 +0,0 @@ -isPluginEnabled('wk')) { - header('Location: feature_disabled.php'); - exit(); -} -if (!ttAccessAllowed('manage_work')) { - header('Location: access_denied.php'); - exit(); -} -$work_id = (int)$request->getParameter('id'); -$workHelper = new ttWorkHelper($err); -$work_item = $workHelper->getOwnWorkItem($work_id); -if (!$work_item) { - header('Location: access_denied.php'); - exit(); -} -// Do we have offer_id? -$offer_id = $work_item['offer_id']; -if ($offer_id) { - $offer = $workHelper->getAvailableOffer($offer_id); - if (!$offer) { - header('Location: access_denied.php'); - exit(); - } -} -// End of access checks. - -$cl_name = $work_item['subject']; -$cl_description = $work_item['descr_short']; -$cl_details = $work_item['descr_long']; -$cl_budget = $work_item['amount_with_currency']; - -$form = new Form('workForm'); -$form->addInput(array('type'=>'textarea','name'=>'work_name','style'=>'width: 400px;','value'=>$cl_name)); -$form->getElement('work_name')->setEnabled(false); -$form->addInput(array('type'=>'textarea','name'=>'description','style'=>'width: 400px; height: 80px;','value'=>$cl_description)); -$form->getElement('description')->setEnabled(false); -$form->addInput(array('type'=>'textarea','name'=>'details','style'=>'width: 400px; height: 200px;','value'=>$cl_details)); -$form->getElement('details')->setEnabled(false); -$form->addInput(array('type'=>'text','name'=>'budget','value'=>$cl_budget)); -$form->getElement('budget')->setEnabled(false); - -$smarty->assign('offer', $offer); -$smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('title', $i18n->get('title.work')); -$smarty->assign('content_page_name', 'work_view_own.tpl'); -$smarty->display('index.tpl'); From 036e6675223e9685f5218c76a368a1ac16db23d8 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 9 Nov 2019 18:01:57 +0000 Subject: [PATCH 173/877] Add a capability to send messages to offer owners. --- WEB-INF/lib/ttWorkHelper.class.php | 76 ++++++++++++++++++-- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/work/offer_message.tpl | 32 +++++++++ WEB-INF/templates/work/offer_view.tpl | 1 + work/offer_message.php | 90 ++++++++++++++++++++++++ work/work_message.php | 35 ++++----- 6 files changed, 209 insertions(+), 27 deletions(-) create mode 100644 WEB-INF/templates/work/offer_message.tpl create mode 100644 work/offer_message.php diff --git a/WEB-INF/lib/ttWorkHelper.class.php b/WEB-INF/lib/ttWorkHelper.class.php index bcdd8a37a..6ddf87513 100644 --- a/WEB-INF/lib/ttWorkHelper.class.php +++ b/WEB-INF/lib/ttWorkHelper.class.php @@ -55,7 +55,8 @@ class ttWorkHelper { var $get_group_items_uri = null; // URI to get all group items in one API call. var $delete_own_offer_uri = null; // URI to delete own offer. var $update_own_offer_uri = null; // URI to update own offer. - var $send_message_uri = null; // URI to send message. + var $send_message_to_work_owner_uri = null; // URI to send message to work owner. + var $send_message_to_offer_owner_uri = null; // URI to send message to offer owner. var $site_id = null; // Site id for work server. var $site_key = null; // Site key for work server. @@ -92,7 +93,8 @@ function __construct(&$errors) { $this->get_group_items_uri = $this->work_server_uri.'getgroupitems'; $this->delete_own_offer_uri = $this->work_server_uri.'deleteownoffer'; $this->update_own_offer_uri = $this->work_server_uri.'updateownoffer'; - $this->send_message_uri = $this->work_server_uri.'sendmessage'; + $this->send_message_to_work_owner_uri = $this->work_server_uri.'sendmessagetoworkowner'; + $this->send_message_to_offer_owner_uri = $this->work_server_uri.'sendmessagetoofferowner'; $this->checkSiteRegistration(); } @@ -1485,8 +1487,8 @@ function getAvailableOffer($offer_id) { return $offer; } - // sendMessage - sends a message via remote work server. - function sendMessage($fields) { + // sendMessageToWorkOwner - sends a message to work owner via remote work server. + function sendMessageToWorkOwner($fields) { global $i18n; global $user; $mdb2 = getConnection(); @@ -1517,7 +1519,71 @@ function sendMessage($fields) { $ch = curl_init(); // Set the url, number of POST vars, POST data. - curl_setopt($ch, CURLOPT_URL, $this->send_message_uri); + curl_setopt($ch, CURLOPT_URL, $this->send_message_to_work_owner_uri); + curl_setopt($ch, CURLOPT_POST, true); + curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + + // Execute a post request. + $result = curl_exec($ch); + + // Close connection. + curl_close($ch); + + if (!$result) { + $this->errors->add($i18n->get('error.remote_work')); + return false; + } + + $result_array = json_decode($result, true); + + // Check for errors. + $call_status = $result_array['call_status']; + if (!$call_status) { + $this->errors->add($i18n->get('error.remote_work')); + return false; + } + if ($call_status['code'] != TT_CURL_SUCCESS) { + $this->errors->add($call_status['error']); + return false; + } + + return true; + } + + // sendMessageToOfferOwner - sends a message to offer owner via remote work server. + function sendMessageToOfferOwner($fields) { + global $i18n; + global $user; + $mdb2 = getConnection(); + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $curl_fields = array('lang' => urlencode($user->lang), + 'site_id' => urlencode($this->site_id), + 'site_key' => urlencode($this->site_key), + 'org_id' => urlencode($org_id), + 'org_key' => urlencode($user->getOrgKey()), + 'group_id' => urlencode($group_id), + 'group_name' => urlencode(base64_encode($user->getGroupName())), + 'group_key' => urlencode($user->getGroupKey()), + 'offer_id' => urlencode($fields['offer_id']), + 'sender_ip' => urlencode($_SERVER['REMOTE_ADDR']), + 'sender_user_id' => urlencode($user->getUser()), + 'sender_name' => urlencode(base64_encode($user->getName())), + 'sender_email' => urlencode(base64_encode($user->getEmail())), + 'message_body' => urlencode(base64_encode($fields['message_body']))); + + // url-ify the data for the POST. + foreach($curl_fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; } + $fields_string = rtrim($fields_string, '&'); + + // Open connection. + $ch = curl_init(); + + // Set the url, number of POST vars, POST data. + curl_setopt($ch, CURLOPT_URL, $this->send_message_to_offer_owner_uri); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 6b904f8b2..eff84a8a3 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- + {if $show_files} + + {/if} @@ -196,6 +205,13 @@ function recalculateCost() { {/if} + {if $show_files} + {if $item.has_files} + + {else} + + {/if} + {/if}
 Anuko Time Tracker 1.19.12.5170 | Copyright © Anuko | +  Anuko Time Tracker 1.19.12.5171 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/work/offer_message.tpl b/WEB-INF/templates/work/offer_message.tpl new file mode 100644 index 000000000..c97a3db91 --- /dev/null +++ b/WEB-INF/templates/work/offer_message.tpl @@ -0,0 +1,32 @@ + + +{$forms.messageForm.open} + +{if $offer} + + + +{/if} + + + +
+ + + + +
{$i18n.label.offer}: {$offer.subject}
{$i18n.label.description}: {$offer.descr_short|escape}
{$i18n.label.budget}: {$offer.amount_with_currency}
+
+ + + + + + + + +
{$i18n.work.label.message}:{$forms.messageForm.message_body.control}
{$forms.messageForm.btn_send.control}
+
+{$forms.messageForm.close} diff --git a/WEB-INF/templates/work/offer_view.tpl b/WEB-INF/templates/work/offer_view.tpl index ad0b385f2..3d9d7d0c5 100644 --- a/WEB-INF/templates/work/offer_view.tpl +++ b/WEB-INF/templates/work/offer_view.tpl @@ -38,6 +38,7 @@
+
diff --git a/work/offer_message.php b/work/offer_message.php new file mode 100644 index 000000000..ff324808e --- /dev/null +++ b/work/offer_message.php @@ -0,0 +1,90 @@ +isPluginEnabled('wk')) { + header('Location: ../feature_disabled.php'); + exit(); +} +$cl_offer_id = (int)$request->getParameter('offer_id'); +if (!$cl_offer_id) { + header('Location: ../access_denied.php'); + exit(); +} +$workHelper = new ttWorkHelper($err); +$offer = $workHelper->getAvailableOffer($cl_offer_id); +if (!$offer) { + header('Location: ../access_denied.php'); + exit(); +} +// End of access checks. + +$cl_name = $offer['subject']; + +if ($request->isPost()) { + $cl_message_body = trim($request->getParameter('message_body')); +} + +$form = new Form('messageForm'); +$form->addInput(array('type'=>'hidden','name'=>'offer_id','value'=>$cl_offer_id)); +$form->addInput(array('type'=>'textarea','name'=>'message_body','style'=>'width: 400px; height: 80px;vertical-align: middle','value'=>$cl_message_body)); +$form->addInput(array('type'=>'submit','name'=>'btn_send','value'=>$i18n->get('work.button.send_message'))); + +if ($request->isPost()) { + // Validate user input. + if (!ttValidString($cl_message_body)) $err->add($i18n->get('error.field'), $i18n->get('work.label.message')); + + // Ensure user email exists (required for workflow). + if (!$user->getEmail()) $err->add($i18n->get('error.no_email')); + + if ($err->no()) { + $workHelper = new ttWorkHelper($err); + $fields = array('offer_id'=>$cl_offer_id, + 'message_body' => $cl_message_body); + if ($workHelper->sendMessageToOfferOwner($fields)) { + $msg->add($i18n->get('work.msg.message_sent')); + // header('Location: work.php'); // TODO: where to redirect? + // exit(); + } + } +} // isPost + +$smarty->assign('offer', $offer); +$smarty->assign('forms', array($form->getName()=>$form->toArray())); +$smarty->assign('onload', 'onLoad="document.offerForm.work_name.focus()"'); +$smarty->assign('title', $i18n->get('work.title.send_message')); +$smarty->assign('content_page_name', 'work/offer_message.tpl'); +$smarty->display('work/index.tpl'); diff --git a/work/work_message.php b/work/work_message.php index 9a009aa82..984b2665b 100644 --- a/work/work_message.php +++ b/work/work_message.php @@ -39,34 +39,27 @@ header('Location: ../feature_disabled.php'); exit(); } -// Do we have work_id? $cl_work_id = (int)$request->getParameter('work_id'); -if ($cl_work_id) { - $workHelper = new ttWorkHelper($err); - $work_item = $workHelper->getAvailableWorkItem($cl_work_id); - if (!$work_item) { - header('Location: ../access_denied.php'); - exit(); - } +if (!$cl_work_id) { + header('Location: ../access_denied.php'); + exit(); +} +$workHelper = new ttWorkHelper($err); +$work_item = $workHelper->getAvailableWorkItem($cl_work_id); +if (!$work_item) { + header('Location: ../access_denied.php'); + exit(); } // End of access checks. -if ($work_item) $cl_name = $work_item['subject']; + +$cl_name = $work_item['subject']; if ($request->isPost()) { $cl_message_body = trim($request->getParameter('message_body')); } - - - - - - - $form = new Form('messageForm'); -if ($cl_work_id) { - $form->addInput(array('type'=>'hidden','name'=>'work_id','value'=>$cl_work_id)); -} +$form->addInput(array('type'=>'hidden','name'=>'work_id','value'=>$cl_work_id)); $form->addInput(array('type'=>'textarea','name'=>'message_body','style'=>'width: 400px; height: 80px;vertical-align: middle','value'=>$cl_message_body)); $form->addInput(array('type'=>'submit','name'=>'btn_send','value'=>$i18n->get('work.button.send_message'))); @@ -79,9 +72,9 @@ if ($err->no()) { $workHelper = new ttWorkHelper($err); - $fields = array('work_id'=>$cl_work_id, + $fields = array('work_id'=>$work_id, 'message_body' => $cl_message_body); - if ($workHelper->sendMessage($fields)) { + if ($workHelper->sendMessageToWorkOwner($fields)) { $msg->add($i18n->get('work.msg.message_sent')); // header('Location: work.php'); // TODO: where to redirect? // exit(); From 0137a7040ede0fa5081906a43529b428cd0d2b32 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 9 Nov 2019 18:11:33 +0000 Subject: [PATCH 174/877] Fixed sending messages to work owners. --- WEB-INF/templates/footer.tpl | 2 +- work/work_message.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index eff84a8a3..3eb2d745c 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- +{if $show_files} + + + + +{/if}
 Anuko Time Tracker 1.19.12.5171 | Copyright © Anuko | +  Anuko Time Tracker 1.19.12.5172 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/work/work_message.php b/work/work_message.php index 984b2665b..91d02b5cb 100644 --- a/work/work_message.php +++ b/work/work_message.php @@ -72,7 +72,7 @@ if ($err->no()) { $workHelper = new ttWorkHelper($err); - $fields = array('work_id'=>$work_id, + $fields = array('work_id'=>$cl_work_id, 'message_body' => $cl_message_body); if ($workHelper->sendMessageToWorkOwner($fields)) { $msg->add($i18n->get('work.msg.message_sent')); From a260f5f197167f71f28a1df6a9b760e4bc784847 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 30 Nov 2019 16:42:16 +0000 Subject: [PATCH 175/877] Added attachments to expense items. --- WEB-INF/lib/ttExpenseHelper.class.php | 104 +++++++++++++++++++++++++- WEB-INF/resources/ca.lang.php | 1 + WEB-INF/resources/cs.lang.php | 1 + WEB-INF/resources/da.lang.php | 2 + WEB-INF/resources/de.lang.php | 2 + WEB-INF/resources/en.lang.php | 1 + WEB-INF/resources/es.lang.php | 1 + WEB-INF/resources/et.lang.php | 2 + WEB-INF/resources/fa.lang.php | 2 + WEB-INF/resources/fi.lang.php | 2 + WEB-INF/resources/fr.lang.php | 2 + WEB-INF/resources/gr.lang.php | 2 + WEB-INF/resources/he.lang.php | 1 + WEB-INF/resources/hu.lang.php | 1 + WEB-INF/resources/it.lang.php | 2 + WEB-INF/resources/ja.lang.php | 1 + WEB-INF/resources/ko.lang.php | 1 + WEB-INF/resources/nl.lang.php | 2 + WEB-INF/resources/no.lang.php | 1 + WEB-INF/resources/pl.lang.php | 2 + WEB-INF/resources/pt-br.lang.php | 2 + WEB-INF/resources/pt.lang.php | 1 + WEB-INF/resources/ro.lang.php | 1 + WEB-INF/resources/ru.lang.php | 1 + WEB-INF/resources/sk.lang.php | 1 + WEB-INF/resources/sl.lang.php | 1 + WEB-INF/resources/sr.lang.php | 2 + WEB-INF/resources/sv.lang.php | 2 + WEB-INF/resources/tr.lang.php | 1 + WEB-INF/resources/zh-cn.lang.php | 1 + WEB-INF/resources/zh-tw.lang.php | 1 + WEB-INF/templates/expenses.tpl | 16 ++++ WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/report.tpl | 5 +- expense_files.php | 89 ++++++++++++++++++++++ expenses.php | 22 +++++- file_delete.php | 30 +++++++- file_download.php | 11 ++- file_edit.php | 24 +++++- 39 files changed, 332 insertions(+), 14 deletions(-) create mode 100644 expense_files.php diff --git a/WEB-INF/lib/ttExpenseHelper.class.php b/WEB-INF/lib/ttExpenseHelper.class.php index b191fe379..303ca5767 100644 --- a/WEB-INF/lib/ttExpenseHelper.class.php +++ b/WEB-INF/lib/ttExpenseHelper.class.php @@ -52,7 +52,11 @@ static function insert($fields) { " values (".$mdb2->quote($date).", $user_id, $group_id, $org_id, ".$mdb2->quote($client_id).", ".$mdb2->quote($project_id). ", ".$mdb2->quote($name).", ".$mdb2->quote($cost).", ".$mdb2->quote($invoice_id).", $paid $created, ".$mdb2->quote($status).")"; $affected = $mdb2->exec($sql); - return (!is_a($affected, 'PEAR_Error')); + if (is_a($affected, 'PEAR_Error')) + return false; + + $id = $mdb2->lastInsertID('tt_expense_items', 'id'); + return $id; } // update - updates a record in tt_expense_items table. @@ -91,6 +95,15 @@ static function markDeleted($id) { global $user; $mdb2 = getConnection(); + // Delete associated files. + if ($user->isPluginEnabled('at')) { + import('ttFileHelper'); + global $err; + $fileHelper = new ttFileHelper($err); + if (!$fileHelper->deleteEntityFiles($id, 'expense')) + return false; + } + $user_id = $user->getUser(); $group_id = $user->getGroup(); $org_id = $user->org_id; @@ -159,8 +172,84 @@ static function getItem($id) { return false; } + // getItemForFileView - retrieves an expense item identified by its id for + // attachment view operation. + // + // It is different from getItem, as we want users with appropriate rights + // to be able to see other users files, without changing "on behalf" user. + // For example, viewing reports for all users and their attached files + // from report links. + static function getItemForFileView($id) { + // There are several possible situations: + // + // Record is ours. Check "view_own_reports" or "view_all_reports". + // Record is for the current on behalf user. Check "view_reports" or "view_all_reports". + // Record is for someone else. Check "view_reports" or "view_all_reports" and rank. + // + // It looks like the best way is to use 2 queries, obtain user_id first, then check rank. + + global $user; + $mdb2 = getConnection(); + + $user_id = $user->getUser(); + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + // Obtain user_id for the expense item. + $sql = "select ei.id, ei.user_id, ei.invoice_id, ei.approved from tt_expense_items ei ". + " where ei.id = $id and ei.group_id = $group_id and ei.org_id = $org_id and ei.status = 1"; + $res = $mdb2->query($sql); + if (is_a($res, 'PEAR_Error')) return false; + if (!$res->numRows()) return false; + + $val = $res->fetchRow(); + $user_id = $val['user_id']; + + // If record is ours. + if ($user_id == $user->id) { + if ($user->can('view_own_reports') || $user->can('view_all_reports')) { + $val['can_edit'] = !($val['invoice_id'] || $val['approved']); + return $val; + } + return false; // No rights. + } + + // If record belongs to a user we impersonate. + if ($user->behalfUser && $user_id == $user->behalfUser->id) { + if ($user->can('view_reports') || $user->can('view_all_reports')) { + $val['can_edit'] = !($val['invoice_id'] || $val['approved']); + return $val; + } + return false; // No rights. + } + + // Record belongs to someone else. We need to check user rank. + if (!($user->can('view_reports') || $user->can('view_all_reports'))) return false; + $max_rank = $user->can('view_all_reports') ? MAX_RANK : $user->getMaxRankForGroup($group_id); + + $left_joins = ' left join tt_users u on (ei.user_id = u.id)'; + $left_joins .= ' left join tt_roles r on (u.role_id = r.id)'; + + $where_part = " where ei.id = $id and ei.group_id = $group_id and ei.org_id = $org_id and ei.status = 1". + $where_part .= " and r.rank <= $max_rank"; + + $sql = "select ei.id, ei.user_id, ei.invoice_id, ei.approved". + " from tt_expense_items ei $left_joins $where_part"; + $res = $mdb2->query($sql); + if (!is_a($res, 'PEAR_Error')) { + if (!$res->numRows()) { + return false; + } + if ($val = $res->fetchRow()) { + $val['can_edit'] = false; + return $val; + } + } + return false; + } + // getItems - returns expense items for a user for a given date. - static function getItems($date) { + static function getItems($date, $includeFiles = false) { global $user; $mdb2 = getConnection(); @@ -174,13 +263,22 @@ static function getItems($date) { if ($user->isPluginEnabled('cl')) $client_field = ", c.name as client"; + if ($includeFiles) { + $filePart = ', if(Sub1.entity_id is null, 0, 1) as has_files'; + $fileJoin = " left join (select distinct entity_id from tt_files". + " where entity_type = 'expense' and group_id = $group_id and org_id = $org_id and status = 1) Sub1". + " on (ei.id = Sub1.entity_id)"; + } + $left_joins = ""; $left_joins = " left join tt_projects p on (ei.project_id = p.id)"; if ($user->isPluginEnabled('cl')) $left_joins .= " left join tt_clients c on (ei.client_id = c.id)"; + $left_joins .= $fileJoin; + $sql = "select ei.id as id $client_field, p.name as project, ei.name as item, ei.cost as cost,". - " ei.invoice_id, ei.approved from tt_expense_items ei $left_joins". + " ei.invoice_id, ei.approved $filePart from tt_expense_items ei $left_joins". " where ei.date = ".$mdb2->quote($date)." and ei.user_id = $user_id". " and ei.group_id = $group_id and ei.org_id = $org_id and ei.status = 1 order by ei.id"; diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index c52298ccf..f49ce3025 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -327,6 +327,7 @@ // 'title.expenses' => 'Expenses', // 'title.edit_expense' => 'Editing Expense Item', // 'title.delete_expense' => 'Deleting Expense Item', +// 'title.expense_files' => 'Expense Item Files', // 'title.predefined_expenses' => 'Predefined Expenses', // 'title.add_predefined_expense' => 'Adding Predefined Expense', // 'title.edit_predefined_expense' => 'Editing Predefined Expense', diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index 633595e7e..6459cc953 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -337,6 +337,7 @@ // 'title.expenses' => 'Expenses', // 'title.edit_expense' => 'Editing Expense Item', // 'title.delete_expense' => 'Deleting Expense Item', +// 'title.expense_files' => 'Expense Item Files', // 'title.predefined_expenses' => 'Predefined Expenses', // 'title.add_predefined_expense' => 'Adding Predefined Expense', // 'title.edit_predefined_expense' => 'Editing Predefined Expense', diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index bf4a88e65..e03d73d43 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -313,6 +313,8 @@ 'title.expenses' => 'Udgifter', 'title.edit_expense' => 'Redigér Udgift', 'title.delete_expense' => 'Slet Udgift', +// TODO: translate the following. +// 'title.expense_files' => 'Expense Item Files', 'title.predefined_expenses' => 'Predefinerede Udgifter', 'title.add_predefined_expense' => 'Tilføj Predefinerede Udgifter', 'title.edit_predefined_expense' => 'Redigér Predefinerede Udgifter', diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index ee486f688..b4663d1b3 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -306,6 +306,8 @@ 'title.expenses' => 'Kosten', 'title.edit_expense' => 'Kostenposition ändern', 'title.delete_expense' => 'Kostenposition löschen', +// TODO: translate the following. +// 'title.expense_files' => 'Expense Item Files', 'title.reports' => 'Berichte', 'title.report' => 'Bericht', 'title.send_report' => 'Bericht senden', diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index 6376660d5..0c1b8e0a9 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -292,6 +292,7 @@ 'title.expenses' => 'Expenses', 'title.edit_expense' => 'Editing Expense Item', 'title.delete_expense' => 'Deleting Expense Item', +'title.expense_files' => 'Expense Item Files', 'title.predefined_expenses' => 'Predefined Expenses', 'title.add_predefined_expense' => 'Adding Predefined Expense', 'title.edit_predefined_expense' => 'Editing Predefined Expense', diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index 53a0bd5c4..a8faaf364 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -326,6 +326,7 @@ // 'title.expenses' => 'Expenses', // 'title.edit_expense' => 'Editing Expense Item', // 'title.delete_expense' => 'Deleting Expense Item', +// 'title.expense_files' => 'Expense Item Files', // 'title.predefined_expenses' => 'Predefined Expenses', // 'title.add_predefined_expense' => 'Adding Predefined Expense', // 'title.edit_predefined_expense' => 'Editing Predefined Expense', diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index 562d6528f..ecb4a1e20 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -322,6 +322,8 @@ 'title.expenses' => 'Kulud', 'title.edit_expense' => 'Kulukirje muutmine', 'title.delete_expense' => 'Kulukirje kustutamine', +// TODO: translate the following. +// 'title.expense_files' => 'Expense Item Files', 'title.predefined_expenses' => 'Eelmääratud kulukirje', 'title.add_predefined_expense' => 'Lisa eelmääratud kulukirje', 'title.edit_predefined_expense' => 'Muuda eelmääratut kulukirjet', diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index c24d01f80..33776560a 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -324,6 +324,8 @@ 'title.expenses' => 'هزینه ها', 'title.edit_expense' => 'ویرایش آیتم هزینه ها', 'title.delete_expense' => 'حذف آیتم هزینه ها', +// TODO: translate the following. +// 'title.expense_files' => 'Expense Item Files', 'title.reports' => 'گزارشات', 'title.report' => 'گزارش', 'title.send_report' => 'ارسال گزارش', diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 62a542a1a..d8d477d15 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -317,6 +317,8 @@ 'title.expenses' => 'Kulut', 'title.edit_expense' => 'Kulutietojen muokkaus', 'title.delete_expense' => 'Kulutiedon poisto', +// TODO: translate the following. +// 'title.expense_files' => 'Expense Item Files', 'title.reports' => 'Raportit', 'title.report' => 'Raportti', 'title.send_report' => 'Raportin lähetys', diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index a08c65515..39755c50c 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -311,6 +311,8 @@ 'title.expenses' => 'Dépenses', 'title.edit_expense' => 'Modification d\\\'une dépense', 'title.delete_expense' => 'Suppression d\\\'une dépense', +// TODO: translate the following. +// 'title.expense_files' => 'Expense Item Files', 'title.reports' => 'Rapports', 'title.report' => 'Rapport', 'title.send_report' => 'Envoi du rapport', diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index 1b3fc2081..16baaf28c 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -307,6 +307,8 @@ 'title.expenses' => 'Δαπάνες', 'title.edit_expense' => 'Επεξεργασία δαπάνης', 'title.delete_expense' => 'Διαγραφή δαπάνης', +// TODO: translate the following. +// 'title.expense_files' => 'Expense Item Files', 'title.predefined_expenses' => 'Προκαθορισμένες δαπάνες', 'title.add_predefined_expense' => 'Προσθήκη προκαθορισμένης δαπάνης', 'title.edit_predefined_expense' => 'Επεξεργασία προκαθορισμένης δαπάνης', diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index a5c59998d..706be9cae 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -332,6 +332,7 @@ // 'title.expenses' => 'Expenses', // 'title.edit_expense' => 'Editing Expense Item', // 'title.delete_expense' => 'Deleting Expense Item', +// 'title.expense_files' => 'Expense Item Files', 'title.reports' => 'דוחות', 'title.report' => 'דוח', 'title.send_report' => 'שליחת דוח', diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index f333de5f2..8176a45c8 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -328,6 +328,7 @@ // 'title.expenses' => 'Expenses', // 'title.edit_expense' => 'Editing Expense Item', // 'title.delete_expense' => 'Deleting Expense Item', +// 'title.expense_files' => 'Expense Item Files', // 'title.predefined_expenses' => 'Predefined Expenses', // 'title.add_predefined_expense' => 'Adding Predefined Expense', // 'title.edit_predefined_expense' => 'Editing Predefined Expense', diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index 474878f2f..7f667b445 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -315,6 +315,8 @@ 'title.expenses' => 'Spese', 'title.edit_expense' => 'Modifica voce di spesa', 'title.delete_expense' => 'Eliminezione voce di spesa', +// TODO: translate the following. +// 'title.expense_files' => 'Expense Item Files', 'title.predefined_expenses' => 'Spese predefinite', 'title.add_predefined_expense' => 'Aggiunta spese predefinite', 'title.edit_predefined_expense' => 'Modifica spese predefinite', diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index ec3a4c754..fb0fd6fcb 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -333,6 +333,7 @@ // 'title.expenses' => 'Expenses', // 'title.edit_expense' => 'Editing Expense Item', // 'title.delete_expense' => 'Deleting Expense Item', +// 'title.expense_files' => 'Expense Item Files', // 'title.predefined_expenses' => 'Predefined Expenses', // 'title.add_predefined_expense' => 'Adding Predefined Expense', // 'title.edit_predefined_expense' => 'Editing Predefined Expense', diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index bdcf6d18a..8414edb52 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -333,6 +333,7 @@ // 'title.expenses' => 'Expenses', // 'title.edit_expense' => 'Editing Expense Item', // 'title.delete_expense' => 'Deleting Expense Item', +// 'title.expense_files' => 'Expense Item Files', // 'title.predefined_expenses' => 'Predefined Expenses', // 'title.add_predefined_expense' => 'Adding Predefined Expense', // 'title.edit_predefined_expense' => 'Editing Predefined Expense', diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 71c7ed4c3..fc7aeb361 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -297,6 +297,8 @@ 'title.expenses' => 'Kosten', 'title.edit_expense' => 'Bewerk kosten artikel', 'title.delete_expense' => 'Verwijder kosten artikel', +// TODO: translate the following. +// 'title.expense_files' => 'Expense Item Files', 'title.predefined_expenses' => 'Vaste kosten', 'title.add_predefined_expense' => 'Vaste kosten toevoegen', 'title.edit_predefined_expense' => 'Vaste kosten bewerken', diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index 8ef8f168e..b0dc2ead0 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -330,6 +330,7 @@ // 'title.expenses' => 'Expenses', // 'title.edit_expense' => 'Editing Expense Item', // 'title.delete_expense' => 'Deleting Expense Item', +// 'title.expense_files' => 'Expense Item Files', // 'title.predefined_expenses' => 'Predefined Expenses', // 'title.add_predefined_expense' => 'Adding Predefined Expense', // 'title.edit_predefined_expense' => 'Editing Predefined Expense', diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index dd712827b..de6ded99a 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -318,6 +318,8 @@ 'title.expenses' => 'Wydatki', 'title.edit_expense' => 'Edytowanie wpisu', 'title.delete_expense' => 'Usuwanie wpisu', +// TODO: translate the following. +// 'title.expense_files' => 'Expense Item Files', 'title.reports' => 'Raporty', 'title.report' => 'Raport', 'title.send_report' => 'Wysyłanie raportu', diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index 52577c71d..fafb843bb 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -315,6 +315,8 @@ 'title.expenses' => 'Gastos', 'title.edit_expense' => 'Editando item de gasto', 'title.delete_expense' => 'Apagando item de gasto', +// TODO: translate the following. +// 'title.expense_files' => 'Expense Item Files', 'title.reports' => 'Relatórios', 'title.report' => 'Report', 'title.send_report' => 'Enviando relatório', diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index 195c2a773..3c6ecefd9 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -316,6 +316,7 @@ // 'title.expenses' => 'Expenses', // 'title.edit_expense' => 'Editing Expense Item', // 'title.delete_expense' => 'Deleting Expense Item', +// 'title.expense_files' => 'Expense Item Files', // 'title.predefined_expenses' => 'Predefined Expenses', // 'title.add_predefined_expense' => 'Adding Predefined Expense', // 'title.edit_predefined_expense' => 'Editing Predefined Expense', diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index 3da5b1fb3..9b6fc1750 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -333,6 +333,7 @@ // 'title.expenses' => 'Expenses', // 'title.edit_expense' => 'Editing Expense Item', // 'title.delete_expense' => 'Deleting Expense Item', +// 'title.expense_files' => 'Expense Item Files', // 'title.predefined_expenses' => 'Predefined Expenses', // 'title.add_predefined_expense' => 'Adding Predefined Expense', // 'title.edit_predefined_expense' => 'Editing Predefined Expense', diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index 1b753b2a3..a08157191 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -280,6 +280,7 @@ 'title.expenses' => 'Расходы', 'title.edit_expense' => 'Редактирование предмета расхода', 'title.delete_expense' => 'Удаление предмета расхода', +'title.expense_files' => 'Файлы предмета расхода', 'title.predefined_expenses' => 'Предопределенные расходы', 'title.add_predefined_expense' => 'Добавление предопределенного расхода', 'title.edit_predefined_expense' => 'Редактирование предопределенного расхода', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index ffbf5894b..88d310e12 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -322,6 +322,7 @@ // 'title.expenses' => 'Expenses', // 'title.edit_expense' => 'Editing Expense Item', // 'title.delete_expense' => 'Deleting Expense Item', +// 'title.expense_files' => 'Expense Item Files', 'title.reports' => 'Zostavy', 'title.report' => 'Zostava', 'title.send_report' => 'Odosielanie zostavy', diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index 8ecf0bcfc..ae9d8ab8c 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -312,6 +312,7 @@ // 'title.expenses' => 'Expenses', // 'title.edit_expense' => 'Editing Expense Item', // 'title.delete_expense' => 'Deleting Expense Item', +// 'title.expense_files' => 'Expense Item Files', // 'title.predefined_expenses' => 'Predefined Expenses', // 'title.add_predefined_expense' => 'Adding Predefined Expense', // 'title.edit_predefined_expense' => 'Editing Predefined Expense', diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index 9996d9a5e..b29f81bca 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -316,6 +316,8 @@ 'title.expenses' => 'Troškovi', 'title.edit_expense' => 'Izmeni stavke troškova', 'title.delete_expense' => 'Obriši stavke troškova', +// TODO: translate the following. +// 'title.expense_files' => 'Expense Item Files', 'title.reports' => 'Izveštaji', 'title.report' => 'Izveštaj', 'title.send_report' => 'Slanje izveštaja', diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index 3bae63b5f..41dea480e 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -313,6 +313,8 @@ 'title.expenses' => 'Kostnader', 'title.edit_expense' => 'Redigera kostnad', 'title.delete_expense' => 'Ta bort kostnad', +// TODO: translate the following. +// 'title.expense_files' => 'Expense Item Files', 'title.predefined_expenses' => 'Fördefinierade kostnader', 'title.add_predefined_expense' => 'Lägg till fördefinierad kostnad', 'title.edit_predefined_expense' => 'Redigera fördefinierad kostnad', diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index 948e9ad5b..4ac00f1c1 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -342,6 +342,7 @@ // 'title.expenses' => 'Expenses', // 'title.edit_expense' => 'Editing Expense Item', // 'title.delete_expense' => 'Deleting Expense Item', +// 'title.expense_files' => 'Expense Item Files', // 'title.predefined_expenses' => 'Predefined Expenses', // 'title.add_predefined_expense' => 'Adding Predefined Expense', // 'title.edit_predefined_expense' => 'Editing Predefined Expense', diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index a5cfe24b3..8d96b36ee 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -322,6 +322,7 @@ // 'title.expenses' => 'Expenses', // 'title.edit_expense' => 'Editing Expense Item', // 'title.delete_expense' => 'Deleting Expense Item', +// 'title.expense_files' => 'Expense Item Files', // 'title.predefined_expenses' => 'Predefined Expenses', // 'title.add_predefined_expense' => 'Adding Predefined Expense', // 'title.edit_predefined_expense' => 'Editing Predefined Expense', diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index 22694ddfa..77acaecad 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -328,6 +328,7 @@ // 'title.expenses' => 'Expenses', // 'title.edit_expense' => 'Editing Expense Item', // 'title.delete_expense' => 'Deleting Expense Item', +// 'title.expense_files' => 'Expense Item Files', // 'title.predefined_expenses' => 'Predefined Expenses', // 'title.add_predefined_expense' => 'Adding Predefined Expense', // 'title.edit_predefined_expense' => 'Editing Predefined Expense', diff --git a/WEB-INF/templates/expenses.tpl b/WEB-INF/templates/expenses.tpl index 7272f01fe..c064b13de 100644 --- a/WEB-INF/templates/expenses.tpl +++ b/WEB-INF/templates/expenses.tpl @@ -153,6 +153,12 @@ function recalculateCost() { {$i18n.label.cost} (*): {$forms.expensesForm.cost.control} {$user->getCurrency()|escape}
{$i18n.label.file}:{$forms.expensesForm.newfile.control}
@@ -183,6 +189,9 @@ function recalculateCost() { {/if} {$i18n.label.item} {$i18n.label.cost}
{$item.item|escape} {$item.cost}{$i18n.label.files}{$i18n.label.files} {if $item.approved || $item.invoice_id}   diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 3eb2d745c..323328bb4 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- {/if} {if $bean->getAttribute('chinvoice')}{/if} {if $bean->getAttribute('chtimesheet')}{/if} - {if $bean->getAttribute('chfiles')}{/if} + {if $bean->getAttribute('chfiles')} + {if 1 == $item.type}{/if} + {if 2 == $item.type}{/if} + {/if} {if $use_checkboxes} {if 1 == $item.type}{/if} {if 2 == $item.type}{/if} diff --git a/expense_files.php b/expense_files.php new file mode 100644 index 000000000..feab9b611 --- /dev/null +++ b/expense_files.php @@ -0,0 +1,89 @@ +isPluginEnabled('at')) { + header('Location: feature_disabled.php'); + exit(); +} +$cl_id = (int)$request->getParameter('id'); +$item = ttExpenseHelper::getItemForFileView($cl_id); +if (!$item) { + header('Location: access_denied.php'); + exit(); +} +// End of access checks. + +if ($request->isPost()) { + $cl_description = trim($request->getParameter('description')); +} + +$fileHelper = new ttFileHelper($err); +$files = $fileHelper::getEntityFiles($cl_id, 'expense'); + +$form = new Form('fileUploadForm'); +$form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_id)); +$form->addInput(array('type'=>'upload','name'=>'newfile','value'=>$i18n->get('button.submit'))); +$form->addInput(array('type'=>'textarea','name'=>'description','style'=>'width: 250px; height: 40px;','value'=>$cl_description)); +$form->addInput(array('type'=>'submit','name'=>'btn_submit','value'=>$i18n->get('button.add'))); + +if ($request->isPost()) { + // We are adding a new file. + + // Validate user input. + if (!$_FILES['newfile']['name']) $err->add($i18n->get('error.upload')); + if (!ttValidString($cl_description, true)) $err->add($i18n->get('error.field'), $i18n->get('label.description')); + // Finished validating user input. + + if ($err->no()) { + $fields = array('entity_type'=>'expense', + 'entity_id' => $cl_id, + 'file_name' => $_FILES['newfile']['name'], + 'description'=>$cl_description); + if ($fileHelper->putFile($fields)) { + header('Location: expense_files.php?id='.$cl_id); + exit(); + } + } +} // isPost + +$smarty->assign('can_edit', $item['can_edit']); +$smarty->assign('forms', array($form->getName()=>$form->toArray())); +$smarty->assign('files', $files); +$smarty->assign('title', $i18n->get('title.expense_files')); +$smarty->assign('content_page_name', 'entity_files.tpl'); +$smarty->display('index.tpl'); diff --git a/expenses.php b/expenses.php index 2c25bde66..2b7a15bc4 100644 --- a/expenses.php +++ b/expenses.php @@ -33,6 +33,7 @@ import('DateAndTime'); import('ttTimeHelper'); import('ttExpenseHelper'); +import('ttFileHelper'); // Access checks. if (!(ttAccessAllowed('track_own_expenses') || ttAccessAllowed('track_expenses'))) { @@ -83,6 +84,7 @@ $tracking_mode = $user->getTrackingMode(); $show_project = MODE_PROJECTS == $tracking_mode || MODE_PROJECTS_AND_TASKS == $tracking_mode; +$showFiles = $user->isPluginEnabled('at'); // Initialize variables. $cl_client = $request->getParameter('client', ($request->isPost() ? null : @$_SESSION['client'])); @@ -182,6 +184,8 @@ } $form->addInput(array('type'=>'textarea','maxlength'=>'800','name'=>'item_name','style'=>'width: 250px; height:'.NOTE_INPUT_HEIGHT.'px;','value'=>$cl_item_name)); $form->addInput(array('type'=>'text','maxlength'=>'40','name'=>'cost','style'=>'width: 100px;','value'=>$cl_cost)); +if ($showFiles) + $form->addInput(array('type'=>'upload','name'=>'newfile','value'=>$i18n->get('button.submit'))); $form->addInput(array('type'=>'calendar','name'=>'date','highlight'=>'expenses','value'=>$cl_date)); // calendar $form->addInput(array('type'=>'hidden','name'=>'browser_today','value'=>'')); // User current date, which gets filled in on btn_submit click. $form->addInput(array('type'=>'submit','name'=>'btn_submit','onclick'=>'browser_today.value=get_date()','value'=>$i18n->get('button.submit'))); @@ -212,8 +216,19 @@ // Insert record. if ($err->no()) { - if (ttExpenseHelper::insert(array('date'=>$cl_date,'client_id'=>$cl_client, - 'project_id'=>$cl_project,'name'=>$cl_item_name,'cost'=>$cl_cost,'status'=>1))) { + $id = ttExpenseHelper::insert(array('date'=>$cl_date,'client_id'=>$cl_client, + 'project_id'=>$cl_project,'name'=>$cl_item_name,'cost'=>$cl_cost,'status'=>1)); + + // Put a new file in storage if we have it. + if ($id && $showFiles && $_FILES['newfile']['name']) { + $fileHelper = new ttFileHelper($err); + $fields = array('entity_type'=>'expense', + 'entity_id' => $id, + 'file_name' => $_FILES['newfile']['name']); + $fileHelper->putFile($fields); + } + + if ($id) { header('Location: expenses.php'); exit(); } else @@ -224,8 +239,9 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('show_project', $show_project); +$smarty->assign('show_files', $showFiles); $smarty->assign('day_total', ttExpenseHelper::getTotalForDay($cl_date)); -$smarty->assign('expense_items', ttExpenseHelper::getItems($cl_date)); +$smarty->assign('expense_items', ttExpenseHelper::getItems($cl_date, $showFiles)); $smarty->assign('predefined_expenses', $predefined_expenses); $smarty->assign('client_list', $client_list); $smarty->assign('project_list', $project_list); diff --git a/file_delete.php b/file_delete.php index 3ef22aead..ff56f118b 100644 --- a/file_delete.php +++ b/file_delete.php @@ -30,6 +30,8 @@ import('form.Form'); import('ttFileHelper'); import('ttTimeHelper'); +import('ttExpenseHelper'); +import('ttTimesheetHelper'); import('ttProjectHelper'); // Access checks. @@ -47,14 +49,26 @@ exit(); } } +if ($entity_type == 'expense') { + if (!(ttAccessAllowed('track_own_expenses') || ttAccessAllowed('track_expenses')) || !ttExpenseHelper::getItemForFileView($file['entity_id'])) { + header('Location: access_denied.php'); + exit(); + } +} +if ($entity_type == 'timesheet') { + if (!(ttAccessAllowed('track_own_time') || ttAccessAllowed('track_time')) || !ttTimesheetHelper::getTimesheet($file['entity_id'])) { + header('Location: access_denied.php'); + exit(); + } +} if ($entity_type == 'project') { if (!ttAccessAllowed('manage_projects') || !ttProjectHelper::get($file['entity_id'])) { header('Location: access_denied.php'); exit(); } } -if ($entity_type != 'project' && $entity_type != 'time') { - // Currently, files are only associated with time records and projects. +if (!($entity_type == 'time' || $entity_type != 'expense' || $entity_type != 'timesheet' || $entity_type == 'project')) { + // Currently, files are only associated with time records, expense items, timesheets, and projects. // Improve access checks when the feature evolves. header('Location: access_denied.php'); exit(); @@ -76,6 +90,12 @@ if ($entity_type == 'time') { header('Location: time_files.php?id='.$file['entity_id']); } + if ($entity_type == 'expense') { + header('Location: expense_files.php?id='.$file['entity_id']); + } + if ($entity_type == 'timesheet') { + header('Location: timesheet_files.php?id='.$file['entity_id']); + } if ($entity_type == 'project') { header('Location: project_files.php?id='.$file['entity_id']); } @@ -85,6 +105,12 @@ if ($entity_type == 'time') { header('Location: time_files.php?id='.$file['entity_id']); } + if ($entity_type == 'expense') { + header('Location: expense_files.php?id='.$file['entity_id']); + } + if ($entity_type == 'timesheet') { + header('Location: timesheet_files.php?id='.$file['entity_id']); + } if ($entity_type == 'project') { header('Location: project_files.php?id='.$file['entity_id']); } diff --git a/file_download.php b/file_download.php index e4d35c705..ac076b27e 100644 --- a/file_download.php +++ b/file_download.php @@ -30,6 +30,7 @@ import('form.Form'); import('ttFileHelper'); import('ttTimeHelper'); +import('ttExpenseHelper'); import('ttProjectHelper'); // Access checks. @@ -47,14 +48,20 @@ exit(); } } +if ($entity_type == 'expense') { + if (!(ttAccessAllowed('track_own_expenses') || ttAccessAllowed('track_expenses')) || !ttExpenseHelper::getItemForFileView($file['entity_id'])) { + header('Location: access_denied.php'); + exit(); + } +} if ($entity_type == 'project') { if (!(ttAccessAllowed('view_own_projects') || ttAccessAllowed('manage_projects')) || !ttProjectHelper::get($file['entity_id'])) { header('Location: access_denied.php'); exit(); } } -if ($entity_type != 'project' && $entity_type != 'time') { - // Currently, files are only associated with time records and projects. +if ($entity_type != 'project' && $entity_type != 'time' && $entity_type != 'expense') { + // Currently, files are only associated with time records, expense items, and projects. // Improve access checks when the feature evolves. header('Location: access_denied.php'); exit(); diff --git a/file_edit.php b/file_edit.php index 4a675a502..d2c8f2990 100644 --- a/file_edit.php +++ b/file_edit.php @@ -30,6 +30,8 @@ import('form.Form'); import('ttFileHelper'); import('ttTimeHelper'); +import('ttExpenseHelper'); +import('ttTimesheetHelper'); import('ttProjectHelper'); // Access checks. @@ -47,14 +49,26 @@ exit(); } } +if ($entity_type == 'expense') { + if (!(ttAccessAllowed('track_own_expenses') || ttAccessAllowed('track_expenses')) || !ttExpenseHelper::getItemForFileView($file['entity_id'])) { + header('Location: access_denied.php'); + exit(); + } +} +if ($entity_type == 'timesheet') { + if (!(ttAccessAllowed('track_own_time') || ttAccessAllowed('track_time')) || !ttTimesheetHelper::getTimesheet($file['entity_id'])) { + header('Location: access_denied.php'); + exit(); + } +} if ($entity_type == 'project') { if (!ttAccessAllowed('manage_projects') || !ttProjectHelper::get($file['entity_id'])) { header('Location: access_denied.php'); exit(); } } -if ($entity_type != 'project' && $entity_type != 'time') { - // Currently, files are only associated with time records and projects. +if (!($entity_type == 'time' || $entity_type != 'expense' || $entity_type != 'timesheet' || $entity_type == 'project')) { + // Currently, files are only associated with time records, expense items, timesheets, and projects. // Improve access checks when the feature evolves. header('Location: access_denied.php'); exit(); @@ -87,6 +101,12 @@ if ($entity_type == 'time') { header('Location: time_files.php?id='.$file['entity_id']); } + if ($entity_type == 'expense') { + header('Location: expense_files.php?id='.$file['entity_id']); + } + if ($entity_type == 'timesheet') { + header('Location: timesheet_files.php?id='.$file['entity_id']); + } if ($entity_type == 'project') { header('Location: project_files.php?id='.$file['entity_id']); } From 1e8b19c543f518ad77d649922b0f1665acf2581c Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 30 Nov 2019 19:38:34 +0000 Subject: [PATCH 176/877] Fixing export of fav reports by including properly mapped report_spec field. --- WEB-INF/lib/ttGroupExportHelper.class.php | 69 ++++++++++++++++++++++- WEB-INF/lib/ttOrgImportHelper.class.php | 1 - WEB-INF/templates/footer.tpl | 2 +- 3 files changed, 67 insertions(+), 5 deletions(-) diff --git a/WEB-INF/lib/ttGroupExportHelper.class.php b/WEB-INF/lib/ttGroupExportHelper.class.php index 79938f803..91d463542 100644 --- a/WEB-INF/lib/ttGroupExportHelper.class.php +++ b/WEB-INF/lib/ttGroupExportHelper.class.php @@ -556,10 +556,10 @@ function writeData() { } } $fav_report_part = $this->indentation.' '."favReportMap[$fav_report['id']]."\""; - $fav_report_part .= " user_id=\"".$this->userMap[$fav_report['user_id']]."\""; $fav_report_part .= " name=\"".htmlspecialchars($fav_report['name'])."\""; + $fav_report_part .= " user_id=\"".$this->userMap[$fav_report['user_id']]."\""; + $fav_report_part .= " report_spec=\"".$this->remapReportSpec($fav_report['report_spec'])."\""; $fav_report_part .= " client_id=\"".$this->clientMap[$fav_report['client_id']]."\""; - $fav_report_part .= " cf_1_option_id=\"".$this->customFieldOptionMap[$fav_report['cf_1_option_id']]."\""; $fav_report_part .= " project_id=\"".$this->projectMap[$fav_report['project_id']]."\""; $fav_report_part .= " task_id=\"".$this->taskMap[$fav_report['task_id']]."\""; $fav_report_part .= " billable=\"".$fav_report['billable']."\""; @@ -585,7 +585,6 @@ function writeData() { $fav_report_part .= " show_note=\"".$fav_report['show_note']."\""; $fav_report_part .= " show_approved=\"".$fav_report['show_approved']."\""; $fav_report_part .= " show_totals_only=\"".$fav_report['show_totals_only']."\""; - $fav_report_part .= " show_custom_field_1=\"".$fav_report['show_custom_field_1']."\""; $fav_report_part .= " show_work_units=\"".$fav_report['show_work_units']."\""; $fav_report_part .= " group_by1=\"".$fav_report['group_by1']."\""; $fav_report_part .= " group_by2=\"".$fav_report['group_by2']."\""; @@ -670,4 +669,68 @@ private function encodeLineBreaks($source) { $result = str_replace ("\r", ' ', $result); return $result; } + + // isDropdownCustomField is a helper function for remapReportSpecPart. + // It deteremines if a custom field is of dropdown type. + private function isDropdownCustomField($field_id) { + global $user; + $mdb2 = getConnection(); + + $sql = "select type from tt_custom_fields where group_id = $this->group_id and org_id = $user->org_id and id = $field_id"; + $res = $mdb2->query($sql); + $isDropdown = false; + if (!is_a($res, 'PEAR_Error')) { + while ($val = $res->fetchRow()) { + $isDropdown = $val['type'] == 2; // TYPE_DROPDOWN, see CustomFields.class.php. + break; + } + } + return $isDropdown; + } + + // remapReportSpecPart is a helper function remapReportSpec below. + // It remaps a single report spec part. + private function remapReportSpecPart($report_spec_part, $prefix) { + // Strip prefix. + $remainder = substr($report_spec_part, strlen($prefix)); + // Find colon, which separates field id from its value. + $pos = strpos($remainder, ':'); + $field_id = substr($remainder, 0, $pos); + $field_value = substr($remainder, $pos + 1); + $mapped_field_id = $this->customFieldMap[$field_id]; + + // Do we need to map option id? + if (!ttStartsWith($prefix, 'show_') && $this->isDropdownCustomField($field_id)) { + $mapped_field_value = $this->customFieldOptionMap[$field_value]; + } else { + $mapped_field_value = $field_value; + } + + $mappedPart = $prefix.$mapped_field_id.':'.$mapped_field_value; + return $mappedPart; + } + + // remapReportSpec takes the source report spec as a parameter. + // It remaps it with new custom field and option ids so that it can be used for import. + private function remapReportSpec($report_spec) { + $remappedSpec = null; + $report_spec_parts = explode(',', $report_spec); + foreach ($report_spec_parts as $report_spec_part) { + if (ttStartsWith($report_spec_part, 'time_field_')) { + $remappedSpec .= ','.$this->remapReportSpecPart($report_spec_part, 'time_field_'); + } elseif (ttStartsWith($report_spec_part, 'show_time_field_')) { + $remappedSpec .= ','.$this->remapReportSpecPart($report_spec_part, 'show_time_field_'); + } elseif (ttStartsWith($report_spec_part, 'user_field_')) { + $remappedSpec .= ','.$this->remapReportSpecPart($report_spec_part, 'user_field_'); + } elseif (ttStartsWith($report_spec_part, 'show_user_field_')) { + $remappedSpec .= ','.$this->remapReportSpecPart($report_spec_part, 'show_user_field_'); + } else { + // Use the part as is. + $remappedSpec .= ','.$report_spec_part; + } + } + // Trim comma from the beginning. + $remappedSpec = ltrim($remappedSpec, ','); + return $remappedSpec; + } } diff --git a/WEB-INF/lib/ttOrgImportHelper.class.php b/WEB-INF/lib/ttOrgImportHelper.class.php index 8549b9022..2d2f48d3e 100644 --- a/WEB-INF/lib/ttOrgImportHelper.class.php +++ b/WEB-INF/lib/ttOrgImportHelper.class.php @@ -487,7 +487,6 @@ function startElement($parser, $name, $attrs) { 'chfinish' => (int) $attrs['SHOW_END'], 'chnote' => (int) $attrs['SHOW_NOTE'], 'chapproved' => (int) $attrs['SHOW_APPROVED'], - 'chcf_1' => (int) $attrs['SHOW_CUSTOM_FIELD_1'], 'chunits' => (int) $attrs['SHOW_WORK_UNITS'], 'group_by1' => $attrs['GROUP_BY1'], 'group_by2' => $attrs['GROUP_BY2'], diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 323328bb4..640f0444b 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.19.12.5172 | Copyright © Anuko | +  Anuko Time Tracker 1.19.13.5173 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/report.tpl b/WEB-INF/templates/report.tpl index 03d8d4497..e2207f1c7 100644 --- a/WEB-INF/templates/report.tpl +++ b/WEB-INF/templates/report.tpl @@ -166,7 +166,10 @@ {if $bean->getAttribute('chip')}{if $item.modified}{$item.modified_ip} {$item.modified}{else}{$item.created_ip} {$item.created}{/if}{$item.invoice|escape}{$item.timesheet_name|escape}{if $item.has_files}{$i18n.label.files}{/if}{if $item.has_files}{$i18n.label.files}{/if}{if $item.has_files}{$i18n.label.files}{/if}
-
 Anuko Time Tracker 1.19.13.5173 | Copyright © Anuko | +  Anuko Time Tracker 1.19.13.5174 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From c6f8b562679212a775131c220648547fdc34d023 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 30 Nov 2019 20:48:39 +0000 Subject: [PATCH 177/877] Fixed import of report_spec field for fav reports. --- WEB-INF/lib/ttOrgImportHelper.class.php | 74 +++++++++++++++++++++++-- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 70 insertions(+), 6 deletions(-) diff --git a/WEB-INF/lib/ttOrgImportHelper.class.php b/WEB-INF/lib/ttOrgImportHelper.class.php index 2d2f48d3e..a3287a403 100644 --- a/WEB-INF/lib/ttOrgImportHelper.class.php +++ b/WEB-INF/lib/ttOrgImportHelper.class.php @@ -461,8 +461,8 @@ function startElement($parser, $name, $attrs) { 'user_id' => $this->currentGroupUserMap[$attrs['USER_ID']], 'group_id' => $this->current_group_id, 'org_id' => $this->org_id, + 'report_spec' => $this->remapReportSpec($attrs['REPORT_SPEC']), 'client' => $this->currentGroupClientMap[$attrs['CLIENT_ID']], - 'option' => $this->currentGroupCustomFieldOptionMap[$attrs['CF_1_OPTION_ID']], 'project' => $this->currentGroupProjectMap[$attrs['PROJECT_ID']], 'task' => $this->currentGroupTaskMap[$attrs['TASK_ID']], 'billable' => $attrs['BILLABLE'], @@ -1038,15 +1038,15 @@ private function insertFavReport($fields) { $org_id = (int) $fields['org_id']; $sql = "insert into tt_fav_reports". - " (name, user_id, group_id, org_id, client_id, cf_1_option_id, project_id, task_id,". + " (name, user_id, group_id, org_id, report_spec, client_id, project_id, task_id,". " billable, approved, invoice, timesheet, paid_status, users, period, period_start, period_end,". " show_client, show_invoice, show_paid, show_ip,". " show_project, show_timesheet, show_start, show_duration, show_cost,". - " show_task, show_end, show_note, show_approved, show_custom_field_1, show_work_units,". + " show_task, show_end, show_note, show_approved, show_work_units,". " group_by1, group_by2, group_by3, show_totals_only)". " values(". $mdb2->quote($fields['name']).", ".$fields['user_id'].", $group_id, $org_id, ". - $mdb2->quote($fields['client']).", ".$mdb2->quote($fields['option']).", ". + $mdb2->quote($fields['report_spec']).", ".$mdb2->quote($fields['client']).", ". $mdb2->quote($fields['project']).", ".$mdb2->quote($fields['task']).", ". $mdb2->quote($fields['billable']).", ".$mdb2->quote($fields['approved']).", ". $mdb2->quote($fields['invoice']).", ".$mdb2->quote($fields['timesheet']).", ". @@ -1056,7 +1056,7 @@ private function insertFavReport($fields) { $fields['chclient'].", ".$fields['chinvoice'].", ".$fields['chpaid'].", ".$fields['chip'].", ". $fields['chproject'].", ".$fields['chtimesheet'].", ".$fields['chstart'].", ".$fields['chduration'].", ". $fields['chcost'].", ".$fields['chtask'].", ".$fields['chfinish'].", ".$fields['chnote'].", ". - $fields['chapproved'].", ".$fields['chcf_1'].", ".$fields['chunits'].", ". + $fields['chapproved'].", ".$fields['chunits'].", ". $mdb2->quote($fields['group_by1']).", ".$mdb2->quote($fields['group_by2']).", ". $mdb2->quote($fields['group_by3']).", ".$fields['chtotalsonly'].")"; $affected = $mdb2->exec($sql); @@ -1244,4 +1244,68 @@ private function loginExists($login) { } return false; } + + // isDropdownCustomField is a helper function for remapReportSpecPart. + // It deteremines if a custom field is of dropdown type. + private function isDropdownCustomField($field_id) { + global $user; + $mdb2 = getConnection(); + + $sql = "select type from tt_custom_fields where id = $field_id"; + $res = $mdb2->query($sql); + $isDropdown = false; + if (!is_a($res, 'PEAR_Error')) { + while ($val = $res->fetchRow()) { + $isDropdown = $val['type'] == 2; // TYPE_DROPDOWN, see CustomFields.class.php. + break; + } + } + return $isDropdown; + } + + // remapReportSpecPart is a helper function remapReportSpec below. + // It remaps a single report spec part. + private function remapReportSpecPart($report_spec_part, $prefix) { + // Strip prefix. + $remainder = substr($report_spec_part, strlen($prefix)); + // Find colon, which separates field id from its value. + $pos = strpos($remainder, ':'); + $field_id = substr($remainder, 0, $pos); + $field_value = substr($remainder, $pos + 1); + $mapped_field_id = $this->currentGroupCustomFieldMap[$field_id]; + + // Do we need to map option id? + if (!ttStartsWith($prefix, 'show_') && $this->isDropdownCustomField($mapped_field_id)) { + $mapped_field_value = $this->currentGroupCustomFieldOptionMap[$field_value]; + } else { + $mapped_field_value = $field_value; + } + + $mappedPart = $prefix.$mapped_field_id.':'.$mapped_field_value; + return $mappedPart; + } + + // remapReportSpec takes the source report spec as a parameter. + // It remaps it with new custom field and option ids so that it can be used for import. + private function remapReportSpec($report_spec) { + $remappedSpec = null; + $report_spec_parts = explode(',', $report_spec); + foreach ($report_spec_parts as $report_spec_part) { + if (ttStartsWith($report_spec_part, 'time_field_')) { + $remappedSpec .= ','.$this->remapReportSpecPart($report_spec_part, 'time_field_'); + } elseif (ttStartsWith($report_spec_part, 'show_time_field_')) { + $remappedSpec .= ','.$this->remapReportSpecPart($report_spec_part, 'show_time_field_'); + } elseif (ttStartsWith($report_spec_part, 'user_field_')) { + $remappedSpec .= ','.$this->remapReportSpecPart($report_spec_part, 'user_field_'); + } elseif (ttStartsWith($report_spec_part, 'show_user_field_')) { + $remappedSpec .= ','.$this->remapReportSpecPart($report_spec_part, 'show_user_field_'); + } else { + // Use the part as is. + $remappedSpec .= ','.$report_spec_part; + } + } + // Trim comma from the beginning. + $remappedSpec = ltrim($remappedSpec, ','); + return $remappedSpec; + } } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 640f0444b..3284d0f1b 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- '; } } - if ($options['show_custom_field_1']) $body .= ''; if ($options['show_start']) $body .= ''; if ($options['show_end']) $body .= ''; if ($options['show_duration']) $body .= ''; @@ -1408,7 +1384,6 @@ static function prepareReportBody($options, $comment = null) if ($options[$checkbox_control_name]) $body .= ''; } } - if ($options['show_custom_field_1']) $body .= ''; if ($options['show_start']) $body .= ''; if ($options['show_end']) $body .= ''; if ($options['show_duration']) $body .= ''; @@ -1557,7 +1532,6 @@ static function getReportOptions($bean) { $options['show_task'] = $bean->getAttribute('chtask'); $options['show_end'] = $bean->getAttribute('chfinish'); $options['show_note'] = $bean->getAttribute('chnote'); - $options['show_custom_field_1'] = $bean->getAttribute('chcf_1'); $options['show_work_units'] = $bean->getAttribute('chunits'); $options['show_timesheet'] = $bean->getAttribute('chtimesheet'); $options['show_files'] = $bean->getAttribute('chfiles'); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 3284d0f1b..3645de481 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.19.13.5174 | Copyright © Anuko | +  Anuko Time Tracker 1.19.13.5175 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 4c73ffe1308c8a82dcaa462596e0897632978ddc Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 30 Nov 2019 21:13:39 +0000 Subject: [PATCH 178/877] A bit of cleanup. --- WEB-INF/lib/ttFavReportHelper.class.php | 1 - WEB-INF/lib/ttReportHelper.class.php | 32 +++---------------------- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/report.tpl | 5 ---- report.php | 1 - 5 files changed, 4 insertions(+), 37 deletions(-) diff --git a/WEB-INF/lib/ttFavReportHelper.class.php b/WEB-INF/lib/ttFavReportHelper.class.php index 4cc1b0614..2707fd2b1 100644 --- a/WEB-INF/lib/ttFavReportHelper.class.php +++ b/WEB-INF/lib/ttFavReportHelper.class.php @@ -352,7 +352,6 @@ static function loadReport(&$bean) { } $bean->setAttribute('client', $val['client_id']); - $bean->setAttribute('option', $val['cf_1_option_id']); $bean->setAttribute('project', $val['project_id']); $bean->setAttribute('task', $val['task_id']); $bean->setAttribute('include_records', $val['billable']); diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index 1c2387148..9ca76e63e 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -70,7 +70,6 @@ static function getWhere($options) { $dropdown_parts .= ' and l.client_id = '.$options['client_id']; elseif ($user->isClient() && $user->client_id) $dropdown_parts .= ' and l.client_id = '.$user->client_id; - if ($options['cf_1_option_id']) $dropdown_parts .= ' and l.id in(select log_id from tt_custom_field_log where status = 1 and option_id = '.$options['cf_1_option_id'].')'; if ($options['project_id']) $dropdown_parts .= ' and l.project_id = '.$options['project_id']; if ($options['task_id']) $dropdown_parts .= ' and l.task_id = '.$options['task_id']; if ($options['billable']=='1') $dropdown_parts .= ' and l.billable = 1'; @@ -264,7 +263,6 @@ static function getItems($options) { $grouping_by_project = ttReportHelper::groupingBy('project', $options); $grouping_by_task = ttReportHelper::groupingBy('task', $options); $grouping_by_user = ttReportHelper::groupingBy('user', $options); - $grouping_by_cf_1 = ttReportHelper::groupingBy('cf_1', $options); } $convertTo12Hour = ('%I:%M %p' == $user->getTimeFormat()) && ($options['show_start'] || $options['show_end']); $trackingMode = $user->getTrackingMode(); @@ -303,17 +301,6 @@ static function getItems($options) { // Add task name if it is selected. if ($options['show_task'] || $grouping_by_task) array_push($fields, 't.name as task'); - // Add custom field. - $include_cf_1 = $options['show_custom_field_1'] || $grouping_by_cf_1; - if ($include_cf_1) { - $custom_fields = new CustomFields(); - $cf_1_type = $custom_fields->fields[0]['type']; - if ($cf_1_type == CustomFields::TYPE_TEXT) { - array_push($fields, 'cfl.value as cf_1'); - } elseif ($cf_1_type == CustomFields::TYPE_DROPDOWN) { - array_push($fields, 'cfo.value as cf_1'); - } - } // Add time custom fields. if ($custom_fields && $custom_fields->timeFields) { foreach ($custom_fields->timeFields as $timeField) { @@ -419,14 +406,6 @@ static function getItems($options) { $left_joins .= " left join tt_projects p on (p.id = l.project_id)"; if ($options['show_task'] || $grouping_by_task) $left_joins .= " left join tt_tasks t on (t.id = l.task_id)"; - if ($include_cf_1) { - if ($cf_1_type == CustomFields::TYPE_TEXT) - $left_joins .= " left join tt_custom_field_log cfl on (l.id = cfl.log_id and cfl.status = 1)"; - elseif ($cf_1_type == CustomFields::TYPE_DROPDOWN) { - $left_joins .= " left join tt_custom_field_log cfl on (l.id = cfl.log_id and cfl.status = 1)". - " left join tt_custom_field_options cfo on (cfl.option_id = cfo.id)"; - } - } // Left joins for time custom fields. if ($custom_fields && $custom_fields->timeFields) { foreach ($custom_fields->timeFields as $timeField) { @@ -509,8 +488,6 @@ static function getItems($options) { array_push($fields, 'p.name as project'); if ($options['show_task'] || $grouping_by_task) array_push($fields, 'null'); // null for task name. We need to match column count for union. - if ($options['show_custom_field_1'] || $grouping_by_cf_1) - array_push($fields, 'null'); // null for cf_1. // Add null values for time custom fields. if ($custom_fields && $custom_fields->timeFields) { foreach ($custom_fields->timeFields as $timeField) { @@ -668,7 +645,7 @@ static function putInSession($report_items) { $report_item_ids = trim($report_item_ids, ','); $report_item_expense_ids = trim($report_item_expense_ids, ','); - // The lists are reqdy. Put them in session. + // The lists are ready. Put them in session. if ($report_item_ids) $_SESSION['report_item_ids'] = $report_item_ids; if ($report_item_expense_ids) $_SESSION['report_item_expense_ids'] = $report_item_expense_ids; } @@ -734,9 +711,9 @@ static function getSubtotals($options) { $val['cost'] = str_replace('.', $decimalMark, $val['cost']); $val['expenses'] = str_replace('.', $decimalMark, $val['expenses']); } - $subtotals[$val['group_field']] = array('name'=>$rowLabel,'user'=>$val['user'],'project'=>$val['project'],'task'=>$val['task'],'client'=>$val['client'],'cf_1'=>$val['cf_1'],'time'=>$time,'units'=> $val['units'],'cost'=>$val['cost'],'expenses'=>$val['expenses']); + $subtotals[$val['group_field']] = array('name'=>$rowLabel,'user'=>$val['user'],'project'=>$val['project'],'task'=>$val['task'],'client'=>$val['client'],'time'=>$time,'units'=> $val['units'],'cost'=>$val['cost'],'expenses'=>$val['expenses']); } else - $subtotals[$val['group_field']] = array('name'=>$rowLabel,'user'=>$val['user'],'project'=>$val['project'],'task'=>$val['task'],'client'=>$val['client'],'cf_1'=>$val['cf_1'],'time'=>$time, 'units'=> $val['units']); + $subtotals[$val['group_field']] = array('name'=>$rowLabel,'user'=>$val['user'],'project'=>$val['project'],'task'=>$val['task'],'client'=>$val['client'],'time'=>$time, 'units'=> $val['units']); } return $subtotals; @@ -1365,7 +1342,6 @@ static function prepareReportBody($options, $comment = null) if ($options[$checkbox_control_name]) $body .= ''.$subtotals[$prev_grouped_by]['cf_1'].''.$subtotals[$cur_grouped_by]['time'].''.$totals['time'].'
- {/if} {if $bean->getAttribute('chproject')}{/if} {if $bean->getAttribute('chtask')}{/if} - {if $bean->getAttribute('chcf_1')}{/if} {* time custom fileds *} {if $custom_fields && $custom_fields->timeFields} @@ -96,7 +95,6 @@ {if $bean->getAttribute('chclient')}{/if} {if $bean->getAttribute('chproject')}{/if} {if $bean->getAttribute('chtask')}{/if} - {if $bean->getAttribute('chcf_1')}{/if} {* time custom fileds *} {if $custom_fields && $custom_fields->timeFields} @@ -144,7 +142,6 @@ {if $bean->getAttribute('chclient')}{/if} {if $bean->getAttribute('chproject')}{/if} {if $bean->getAttribute('chtask')}{/if} - {if $bean->getAttribute('chcf_1')}{/if} {* time custom fileds *} {if $custom_fields && $custom_fields->timeFields} @@ -201,7 +198,6 @@ {if $bean->getAttribute('chclient')}{/if} {if $bean->getAttribute('chproject')}{/if} {if $bean->getAttribute('chtask')}{/if} - {if $bean->getAttribute('chcf_1')}{/if} {* time custom fileds *} {if $custom_fields && $custom_fields->timeFields} @@ -243,7 +239,6 @@ {if $bean->getAttribute('chclient')}{/if} {if $bean->getAttribute('chproject')}{/if} {if $bean->getAttribute('chtask')}{/if} - {if $bean->getAttribute('chcf_1')}{/if} {* time custom fileds *} {if $custom_fields && $custom_fields->timeFields} diff --git a/report.php b/report.php index 53c73ee1c..da035fca7 100644 --- a/report.php +++ b/report.php @@ -291,7 +291,6 @@ if ($bean->getAttribute('chclient')) $colspan++; if ($bean->getAttribute('chproject')) $colspan++; if ($bean->getAttribute('chtask')) $colspan++; -if ($bean->getAttribute('chcf_1')) $colspan++; if ($bean->getAttribute('chstart')) $colspan++; if ($bean->getAttribute('chfinish')) $colspan++; if ($bean->getAttribute('chduration')) $colspan++; From 4bb7513dea9e74af838160b33908f4d8145f69f0 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 1 Dec 2019 14:47:45 +0000 Subject: [PATCH 179/877] A bit more cleanup. --- WEB-INF/lib/ttReportHelper.class.php | 86 ++-------------------------- WEB-INF/templates/footer.tpl | 2 +- mobile/time.php | 3 - time.php | 3 - 4 files changed, 7 insertions(+), 87 deletions(-) diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index 9ca76e63e..fa7519a05 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -1495,7 +1495,6 @@ static function getReportOptions($bean) { $options['name'] = null; // No name required. $options['user_id'] = $user->id; // Not sure if we need user_id here. Fav reports use it to recycle $user object in cron.php. $options['client_id'] = $bean->getAttribute('client'); - $options['cf_1_option_id'] = $bean->getAttribute('option'); $options['project_id'] = $bean->getAttribute('project'); $options['task_id'] = $bean->getAttribute('task'); $options['billable'] = $bean->getAttribute('include_records'); @@ -1656,9 +1655,6 @@ static function makeGroupByPart($options) { case 'task': $group_by_parts .= ', t.name'; break; - case 'cf_1': - $group_by_parts .= ', cfo.value'; - break; } switch ($group_by2) { case 'date': @@ -1676,9 +1672,6 @@ static function makeGroupByPart($options) { case 'task': $group_by_parts .= ', t.name'; break; - case 'cf_1': - $group_by_parts .= ', cfo.value'; - break; } switch ($group_by3) { case 'date': @@ -1696,9 +1689,6 @@ static function makeGroupByPart($options) { case 'task': $group_by_parts .= ', t.name'; break; - case 'cf_1': - $group_by_parts .= ', cfo.value'; - break; } // Remove garbage from the beginning. $group_by_parts = ltrim($group_by_parts, ', '); @@ -1793,10 +1783,6 @@ static function makeConcatPart($options) { $what_to_concat .= ", ' - ', coalesce(t.name, 'Null')"; $fields_part .= ', t.name as task'; break; - case 'cf_1': - $what_to_concat .= ", ' - ', coalesce(cfo.value, 'Null')"; - $fields_part .= ', cfo.value as cf_1'; - break; } switch ($group_by2) { case 'date': @@ -1818,10 +1804,6 @@ static function makeConcatPart($options) { $what_to_concat .= ", ' - ', coalesce(t.name, 'Null')"; $fields_part .= ', t.name as task'; break; - case 'cf_1': - $what_to_concat .= ", ' - ', coalesce(cfo.value, 'Null')"; - $fields_part .= ', cfo.value as cf_1'; - break; } switch ($group_by3) { case 'date': @@ -1843,10 +1825,6 @@ static function makeConcatPart($options) { $what_to_concat .= ", ' - ', coalesce(t.name, 'Null')"; $fields_part .= ', t.name as task'; break; - case 'cf_1': - $what_to_concat .= ", ' - ', coalesce(cfo.value, 'Null')"; - $fields_part .= ', cfo.value as cf_1'; - break; } // Remove garbage from both ends. $what_to_concat = trim($what_to_concat, "', -"); @@ -1877,16 +1855,10 @@ static function makeConcatExpensesPart($options) { $what_to_concat .= ", ' - ', coalesce(p.name, 'Null')"; $fields_part .= ', p.name as project'; break; - case 'task': $what_to_concat .= ", ' - ', 'Null'"; $fields_part .= ', null as task'; break; - - case 'cf_1': - $what_to_concat .= ", ' - ', 'Null'"; - $fields_part .= ', null as cf_1'; - break; } switch ($group_by2) { case 'date': @@ -1904,16 +1876,10 @@ static function makeConcatExpensesPart($options) { $what_to_concat .= ", ' - ', coalesce(p.name, 'Null')"; $fields_part .= ', p.name as project'; break; - case 'task': $what_to_concat .= ", ' - ', 'Null'"; $fields_part .= ', null as task'; break; - - case 'cf_1': - $what_to_concat .= ", ' - ', 'Null'"; - $fields_part .= ', null as cf_1'; - break; } switch ($group_by3) { case 'date': @@ -1931,16 +1897,10 @@ static function makeConcatExpensesPart($options) { $what_to_concat .= ", ' - ', coalesce(p.name, 'Null')"; $fields_part .= ', p.name as project'; break; - case 'task': $what_to_concat .= ", ' - ', 'Null'"; $fields_part .= ', null as task'; break; - - case 'cf_1': - $what_to_concat .= ", ' - ', 'Null'"; - $fields_part .= ', null as cf_1'; - break; } // Remove garbage from the beginning. if ($what_to_concat) @@ -1968,14 +1928,9 @@ static function makeCombinedSelectPart($options) { case 'project': $fields .= ', project'; break; - case 'task': $fields .= ', task'; break; - - case 'cf_1': - $fields .= ', cf_1'; - break; } switch ($group_by2) { case 'user': @@ -1987,14 +1942,9 @@ static function makeCombinedSelectPart($options) { case 'project': $fields .= ', project'; break; - case 'task': $fields .= ', task'; break; - - case 'cf_1': - $fields .= ', cf_1'; - break; } switch ($group_by3) { case 'user': @@ -2006,14 +1956,9 @@ static function makeCombinedSelectPart($options) { case 'project': $fields .= ', project'; break; - case 'task': $fields .= ', task'; break; - - case 'cf_1': - $fields .= ', cf_1'; - break; } return $fields; } @@ -2041,13 +1986,6 @@ static function makeJoinPart($options) { if (ttReportHelper::groupingBy('task', $options)) { $left_joins .= ' left join tt_tasks t on (l.task_id = t.id)'; } - if (ttReportHelper::groupingBy('cf_1', $options)) { - $custom_fields = new CustomFields(); - if ($custom_fields->fields[0]['type'] == CustomFields::TYPE_TEXT) - $left_joins .= ' left join tt_custom_field_log cfl on (l.id = cfl.log_id and cfl.status = 1) left join tt_custom_field_options cfo on (cfl.value = cfo.id)'; - elseif ($custom_fields->fields[0]['type'] == CustomFields::TYPE_DROPDOWN) - $left_joins .= ' left join tt_custom_field_log cfl on (l.id = cfl.log_id and cfl.status = 1) left join tt_custom_field_options cfo on (cfl.option_id = cfo.id)'; - } if ($options['show_cost'] && $trackingMode != MODE_TIME) { $left_joins .= ' left join tt_user_project_binds upb on (l.user_id = upb.user_id and l.project_id = upb.project_id)'; } @@ -2214,32 +2152,20 @@ static function makeGroupByHeader($options) { if ($options['group_by1'] != null && $options['group_by1'] != 'no_grouping') { // We have group_by1. $group_by1 = $options['group_by1']; - if ('cf_1' == $group_by1) - $group_by_header .= ' - '.$custom_fields->fields[0]['label']; - else { - $key = 'label.'.$group_by1; - $group_by_header .= ' - '.$i18n->get($key); - } + $key = 'label.'.$group_by1; + $group_by_header .= ' - '.$i18n->get($key); } if ($options['group_by2'] != null && $options['group_by2'] != 'no_grouping') { // We have group_by2. $group_by2 = $options['group_by2']; - if ('cf_1' == $group_by2) - $group_by_header .= ' - '.$custom_fields->fields[0]['label']; - else { - $key = 'label.'.$group_by2; - $group_by_header .= ' - '.$i18n->get($key); - } + $key = 'label.'.$group_by2; + $group_by_header .= ' - '.$i18n->get($key); } if ($options['group_by3'] != null && $options['group_by3'] != 'no_grouping') { // We have group_by3. $group_by3 = $options['group_by3']; - if ('cf_1' == $group_by3) - $group_by_header .= ' - '.$custom_fields->fields[0]['label']; - else { - $key = 'label.'.$group_by3; - $group_by_header .= ' - '.$i18n->get($key); - } + $key = 'label.'.$group_by3; + $group_by_header .= ' - '.$i18n->get($key); } $group_by_header = ltrim($group_by_header, ' -'); return $group_by_header; diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 3645de481..fe5bcc009 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.19.13.5175 | Copyright © Anuko | +  Anuko Time Tracker 1.19.13.5176 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/report.tpl b/WEB-INF/templates/report.tpl index e2207f1c7..b65d0dfa9 100644 --- a/WEB-INF/templates/report.tpl +++ b/WEB-INF/templates/report.tpl @@ -52,7 +52,6 @@ {if $bean->getAttribute('chclient')}{$i18n.label.client}{$i18n.label.project}{$i18n.label.task}{$custom_fields->fields[0]['label']|escape}{$subtotals[$prev_grouped_by]['client']|escape}{$subtotals[$prev_grouped_by]['project']|escape}{$subtotals[$prev_grouped_by]['task']|escape}{$subtotals[$prev_grouped_by]['cf_1']|escape}{$item.client|escape}{$item.project|escape}{$item.task|escape}{$item.cf_1|escape}{$subtotals[$cur_grouped_by]['client']|escape}{$subtotals[$cur_grouped_by]['project']|escape}{$subtotals[$cur_grouped_by]['task']|escape}{$subtotals[$cur_grouped_by]['cf_1']|escape}
-
 Anuko Time Tracker 1.19.13.5176 | Copyright © Anuko | +  Anuko Time Tracker 1.19.13.5177 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/mobile/time.php b/mobile/time.php index 04c25060f..c5fb0ea75 100644 --- a/mobile/time.php +++ b/mobile/time.php @@ -91,9 +91,6 @@ $cl_finish = trim($request->getParameter('finish')); $cl_duration = trim($request->getParameter('duration')); $cl_note = trim($request->getParameter('note')); -// Custom field. -$cl_cf_1 = trim($request->getParameter('cf_1', ($request->isPost() ? null : @$_SESSION['cf_1']))); -$_SESSION['cf_1'] = $cl_cf_1; $cl_billable = 1; if ($user->isPluginEnabled('iv')) { if ($request->isPost()) { diff --git a/time.php b/time.php index a06773e72..4ee881e0c 100644 --- a/time.php +++ b/time.php @@ -136,9 +136,6 @@ $cl_finish = trim($request->getParameter('finish')); $cl_duration = trim($request->getParameter('duration')); $cl_note = trim($request->getParameter('note')); -// Custom field. -$cl_cf_1 = trim($request->getParameter('cf_1', ($request->isPost() ? null : @$_SESSION['cf_1']))); -$_SESSION['cf_1'] = $cl_cf_1; $cl_billable = 1; if ($user->isPluginEnabled('iv')) { if ($request->isPost()) { From ccf40a11f0f5265322d92f53cf756eaf76ff2052 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 1 Dec 2019 15:12:51 +0000 Subject: [PATCH 180/877] Fixed mobile timer.php page to display multiple custom fields. --- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/mobile/timer.tpl | 10 +++-- mobile/timer.php | 63 ++++++++++++++++++------------ time.php | 1 - 4 files changed, 45 insertions(+), 31 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index fe5bcc009..0dcc6c0ec 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- {/if} -{if ($custom_fields && $custom_fields->fields[0])} - - +{if $custom_fields && $custom_fields->timeFields} + {foreach $custom_fields->timeFields as $timeField} + + {assign var="control_name" value='time_field_'|cat:$timeField['id']} + + + {/foreach} {/if} {if ($smarty.const.MODE_PROJECTS == $user->tracking_mode || $smarty.const.MODE_PROJECTS_AND_TASKS == $user->tracking_mode)} diff --git a/mobile/timer.php b/mobile/timer.php index d814637f6..2df6c73cc 100644 --- a/mobile/timer.php +++ b/mobile/timer.php @@ -60,9 +60,6 @@ // Initialize variables. $cl_start = trim($request->getParameter('browser_time')); $cl_finish = trim($request->getParameter('browser_time')); -// Custom field. -$cl_cf_1 = trim($request->getParameter('cf_1', ($request->isPost() ? null : @$_SESSION['cf_1']))); -$_SESSION['cf_1'] = $cl_cf_1; $cl_billable = 1; if ($user->isPluginEnabled('iv')) { if ($request->isPost()) { @@ -79,6 +76,22 @@ $cl_task = $request->getParameter('task', @$_SESSION['task']); $_SESSION['task'] = $cl_task; +$timeCustomFields = array(); +// If we have time custom fields - collect input. +if ($request->isPost()) { + if ($custom_fields && $custom_fields->timeFields) { + foreach ($custom_fields->timeFields as $timeField) { + $control_name = 'time_field_'.$timeField['id']; + $timeCustomFields[$timeField['id']] = array('field_id' => $timeField['id'], + 'control_name' => $control_name, + 'label' => $timeField['label'], + 'type' => $timeField['type'], + 'required' => $timeField['required'], + 'value' => trim($request->getParameter($control_name))); + } + } +} + // Obtain uncompleted record. Assumtion is that only 1 uncompleted record is allowed. $uncompleted = ttTimeHelper::getUncompleted($user->getUser()); $enable_controls = ($uncompleted == null); @@ -164,18 +177,19 @@ else $form->addInput(array('type'=>'submit','name'=>'btn_stop','onclick'=>'browser_time.value=get_time()','value'=>$i18n->get('label.finish'),'enable'=>!$enable_start)); -// If we have custom fields - add controls for them. -if ($custom_fields && $custom_fields->fields[0]) { - // Only one custom field is supported at this time. - if ($custom_fields->fields[0]['type'] == CustomFields::TYPE_TEXT) { - $form->addInput(array('type'=>'text','name'=>'cf_1','value'=>$cl_cf_1)); - } elseif ($custom_fields->fields[0]['type'] == CustomFields::TYPE_DROPDOWN) { - $form->addInput(array('type'=>'combobox','name'=>'cf_1', +// If we have time custom fields - add controls for them. +if ($custom_fields && $custom_fields->timeFields) { + foreach ($custom_fields->timeFields as $timeField) { + $field_name = 'time_field_'.$timeField['id']; + if ($timeField['type'] == CustomFields::TYPE_TEXT) { + $form->addInput(array('type'=>'text','name'=>$field_name,'style'=>'width: 250px;','value'=>$timeCustomFields[$timeField['id']]['value'])); + } elseif ($timeField['type'] == CustomFields::TYPE_DROPDOWN) { + $form->addInput(array('type'=>'combobox','name'=>$field_name, 'style'=>'width: 250px;', - 'value'=>$cl_cf_1, - 'data'=>CustomFields::getOptions($custom_fields->fields[0]['id']), - 'empty'=>array(''=>$i18n->get('dropdown.select')) - )); + 'data'=>CustomFields::getOptions($timeField['id']), + 'value'=>$timeCustomFields[$timeField['id']]['value'], + 'empty'=>array(''=>$i18n->get('dropdown.select')))); + } } } @@ -188,8 +202,12 @@ // Validate user input. if ($user->isPluginEnabled('cl') && $user->isOptionEnabled('client_required') && !$cl_client) $err->add($i18n->get('error.client')); - if ($custom_fields) { - if (!ttValidString($cl_cf_1, !$custom_fields->fields[0]['required'])) $err->add($i18n->get('error.field'), $custom_fields->fields[0]['label']); + // Validate input in time custom fields. + if ($custom_fields && $custom_fields->timeFields) { + foreach ($timeCustomFields as $timeField) { + // Validation is the same for text and dropdown fields. + if (!ttValidString($timeField['value'], !$timeField['required'])) $err->add($i18n->get('error.field'), htmlspecialchars($timeField['label'])); + } } if (MODE_PROJECTS == $user->tracking_mode || MODE_PROJECTS_AND_TASKS == $user->tracking_mode) { if (!$cl_project) $err->add($i18n->get('error.project')); @@ -236,13 +254,10 @@ 'note' => $cl_note, 'billable' => $cl_billable)); - // Insert a custom field if we have it. + // Insert time custom fields if we have them. $result = true; - if ($id && $custom_fields && $cl_cf_1) { - if ($custom_fields->fields[0]['type'] == CustomFields::TYPE_TEXT) - $result = $custom_fields->insert($id, $custom_fields->fields[0]['id'], null, $cl_cf_1); - elseif ($custom_fields->fields[0]['type'] == CustomFields::TYPE_DROPDOWN) - $result = $custom_fields->insert($id, $custom_fields->fields[0]['id'], $cl_cf_1, null); + if ($id && $custom_fields && $custom_fields->timeFields) { + $result = $custom_fields->insertTimeFields($id, $timeCustomFields); } if ($id && $result) { @@ -285,11 +300,7 @@ $week_total = ttTimeHelper::getTimeForWeek($cl_date); $smarty->assign('week_total', $week_total); - $smarty->assign('uncompleted', $uncompleted); - - - $smarty->assign('time_records', ttTimeHelper::getRecords($cl_date)); $smarty->assign('day_total', ttTimeHelper::getTimeForDay($cl_date)); $smarty->assign('client_list', $client_list); diff --git a/time.php b/time.php index 4ee881e0c..8b1c0926f 100644 --- a/time.php +++ b/time.php @@ -465,7 +465,6 @@ $smarty->assign('time_records', $timeRecords); $smarty->assign('show_navigation', $user->isPluginEnabled('wv') && !$user->isOptionEnabled('week_menu')); $smarty->assign('show_client', $showClient); -// $smarty->assign('show_cf_1', $user->isPluginEnabled('cf')); $smarty->assign('show_project', $showProject); $smarty->assign('show_task', $showTask); $smarty->assign('show_start', $showStart); From 32e7a079dfa9b6c21ff46e9aafc5a435aadf797c Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 1 Dec 2019 15:23:32 +0000 Subject: [PATCH 181/877] Removed no longer used fields from tt_fav_reports table. --- WEB-INF/templates/footer.tpl | 2 +- dbinstall.php | 11 +++++++---- mysql.sql | 4 +--- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 0dcc6c0ec..820cf9c40 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.19.13.5177 | Copyright © Anuko | +  Anuko Time Tracker 1.19.13.5178 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/mobile/timer.tpl b/WEB-INF/templates/mobile/timer.tpl index 631f4977d..ea52f6b6b 100644 --- a/WEB-INF/templates/mobile/timer.tpl +++ b/WEB-INF/templates/mobile/timer.tpl @@ -71,9 +71,13 @@ startTimer(); {if $user->isPluginEnabled('iv')}
{$custom_fields->fields[0]['label']|escape}:
{$forms.timeRecordForm.cf_1.control}
{$timeField['label']|escape}{if $timeField['required']} (*){/if}:
{$forms.timeRecordForm.$control_name.control}
{$i18n.label.project}:
- - - + +
 Anuko Time Tracker 1.19.13.5178 | Copyright © Anuko | +  Anuko Time Tracker 1.19.14.5179 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/dbinstall.php b/dbinstall.php index 28eb9646c..ea476d403 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -1161,7 +1161,7 @@ function ttGenerateKeys() { ttExecute("UPDATE `tt_site_config` SET param_value = '1.19.0', modified = now() where param_name = 'version_db' and param_value = '1.18.61'"); } - if ($_POST["convert11900to11907"]) { + if ($_POST["convert11900to11914"]) { ttExecute("CREATE TABLE `tt_work_currencies` (`id` int(10) unsigned NOT NULL,`name` varchar(10) NOT NULL,PRIMARY KEY (`id`))"); ttExecute("create unique index currency_idx on tt_work_currencies(`name`)"); ttExecute("INSERT INTO `tt_work_currencies` (`id`, `name`) VALUES ('1', 'USD'), ('2', 'CAD'), ('3', 'AUD'), ('4', 'EUR'), ('5', 'NZD')"); @@ -1180,6 +1180,9 @@ function ttGenerateKeys() { ttExecute("CREATE TABLE `tt_entity_custom_fields` (`id` int(10) unsigned NOT NULL auto_increment,`group_id` int(10) unsigned NOT NULL,`org_id` int(10) unsigned NOT NULL,`entity_type` tinyint(4) NOT NULL,`entity_id` int(10) unsigned NOT NULL,`field_id` int(10) unsigned NOT NULL,`option_id` int(10) unsigned default NULL,`value` varchar(255) default NULL,`created` datetime default NULL,`created_ip` varchar(45) default NULL,`created_by` int(10) unsigned default NULL,`modified` datetime default NULL,`modified_ip` varchar(45) default NULL,`modified_by` int(10) unsigned default NULL,`status` tinyint(4) default 1,PRIMARY KEY (`id`))"); ttExecute("create unique index entity_idx on tt_entity_custom_fields(entity_type, entity_id, field_id)"); ttExecute("UPDATE `tt_site_config` SET param_value = '1.19.7', modified = now() where param_name = 'version_db' and param_value = '1.19.6'"); + ttExecute("ALTER TABLE `tt_fav_reports` drop `cf_1_option_id`"); + ttExecute("ALTER TABLE `tt_fav_reports` drop `show_custom_field_1`"); + ttExecute("UPDATE `tt_site_config` SET param_value = '1.19.14', modified = now() where param_name = 'version_db' and param_value = '1.19.7'"); } if ($_POST["cleanup"]) { @@ -1229,7 +1232,7 @@ function ttGenerateKeys() {

DB Install

-
Create database structure (v1.19.7) + Create database structure (v1.19.14)
(applies only to new installations, do not execute when updating)
@@ -1278,8 +1281,8 @@ function ttGenerateKeys() {
Update database structure (v1.19 to v1.19.7)Update database structure (v1.19 to v1.19.14)
diff --git a/mysql.sql b/mysql.sql index ec9c207df..3e9df4a1b 100644 --- a/mysql.sql +++ b/mysql.sql @@ -265,7 +265,6 @@ CREATE TABLE `tt_fav_reports` ( `org_id` int(11) default NULL, # organization id `report_spec` text default NULL, # future replacement field for all report settings `client_id` int(11) default NULL, # client id (if selected) - `cf_1_option_id` int(11) default NULL, # custom field 1 option id (if selected) `project_id` int(11) default NULL, # project id (if selected) `task_id` int(11) default NULL, # task id (if selected) `billable` tinyint(4) default NULL, # whether to include billable, not billable, or all records @@ -290,7 +289,6 @@ CREATE TABLE `tt_fav_reports` ( `show_end` tinyint(4) NOT NULL default 0, # whether to show end field `show_note` tinyint(4) NOT NULL default 0, # whether to show note column `show_approved` tinyint(4) NOT NULL default 0, # whether to show approved column - `show_custom_field_1` tinyint(4) NOT NULL default 0, # whether to show custom field 1 `show_work_units` tinyint(4) NOT NULL default 0, # whether to show work units `show_totals_only` tinyint(4) NOT NULL default 0, # whether to show totals only `group_by1` varchar(20) default NULL, # group by field 1 @@ -641,4 +639,4 @@ CREATE TABLE `tt_site_config` ( PRIMARY KEY (`param_name`) ); -INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.19.7', now()); # TODO: change when structure changes. +INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.19.14', now()); # TODO: change when structure changes. From 5ff83cbed9ba642dae03995ee318b3de11c72b69 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 1 Dec 2019 18:15:26 +0000 Subject: [PATCH 182/877] Fixed week view for multiple custom fields. --- WEB-INF/lib/ttWeekViewHelper.class.php | 53 +++++++++++--------------- WEB-INF/templates/footer.tpl | 2 +- display_options.php | 1 - week.php | 5 ++- 4 files changed, 28 insertions(+), 33 deletions(-) diff --git a/WEB-INF/lib/ttWeekViewHelper.class.php b/WEB-INF/lib/ttWeekViewHelper.class.php index 42815e31b..857626041 100644 --- a/WEB-INF/lib/ttWeekViewHelper.class.php +++ b/WEB-INF/lib/ttWeekViewHelper.class.php @@ -126,13 +126,12 @@ static function getRecordsForInterval($start_date, $end_date, $includeFiles = fa // getDataForWeekView - builds an array to render a table of durations and comments for a week view. // In a week view we want one row representing the same attributes to have 7 values for each day of week. // We identify similar records by a combination of client, billable, project, task, and custom field values. - // This will allow us to extend the feature when more custom fields are added. // - // "cl:546,bl:1,pr:23456,ts:27464,cf_1:example text" - // The above means client 546, billable, project 23456, task 27464, custom field text "example text". + // "cl:546,bl:1,pr:23456,ts:27464,time_field_856:BASE64ENCODEDtext,time_field_857:2345" + // The above means client 546, billable, project 23456, task 27464, custom time_field_856 is base64 encoded, + // custom time_field_857 option id is 2345". // - // "cl:546,bl:0,pr:23456,ts:27464,cf_1:7623" - // The above means client 546, not billable, project 23456, task 27464, custom field option id 7623. + // We use base64 encoding for text fields to make parsing of such things possible when text contains commas, etc. // // Daily comments are implemented as alternate rows following week durations (when enabled). // For example: row_0 - new entry durations, row_1 - new entry daily comments, @@ -165,7 +164,7 @@ static function getRecordsForInterval($start_date, $end_date, $includeFiles = fa // ), // // array( // Row 2. - // 'row_id' => 'cl:546,bl:1,pr:23456,ts:27464,cf_1:7623_0', + // 'row_id' => 'cl:546,bl:1,pr:23456,ts:27464,time_field_857:7623_0', // 'label' => 'Anuko - Time Tracker - Coding - Option 2', // 'day_0' => array('control_id' => '2_day_0', 'tt_log_id' => 12345, 'duration' => '00:00'), // 'day_1' => array('control_id' => '2_day_1', 'tt_log_id' => 12346, 'duration' => '01:00'), @@ -176,7 +175,7 @@ static function getRecordsForInterval($start_date, $end_date, $includeFiles = fa // 'day_6' => array('control_id' => '2_day_6', 'tt_log_id' => null, 'duration' => null) // ), // array( // Row 3. - // 'row_id' => 'cl:546,bl:1,pr:23456,ts:27464,cf_1:7623_0_notes', + // 'row_id' => 'cl:546,bl:1,pr:23456,ts:27464,time_field_857:7623_0_notes', // 'label' => 'Notes:', // 'day_0' => array('control_id' => '3_day_0', 'tt_log_id' => 12345, 'note' => 'Comment one'), // 'day_1' => array('control_id' => '3_day_1', 'tt_log_id' => 12346, 'note' => 'Comment two'), @@ -425,8 +424,7 @@ static function getLockedDaysForWeek($start_date) { // makeRowIdentifier - builds a string identifying a row for a week view from a single record properties. // Note that the return value is without a suffix. // For example: - // "cl:546,bl:0,pr:23456,ts:27464,cf_1:example text" - // "cl:546,bl:1,pr:23456,ts:27464,cf_1:7623" + // "cl:546,bl:0,pr:23456,ts:27464,time_field_856:example text,time_field_857:7623" static function makeRowIdentifier($record) { global $user; // Start with client. @@ -445,10 +443,10 @@ static function makeRowIdentifier($record) { foreach ($custom_fields->timeFields as $timeField) { $field_name = 'time_field_'.$timeField['id']; if ($timeField['type'] == CustomFields::TYPE_TEXT) - $field_value = $record[$field_name]; + $field_value = base64_encode($record[$field_name]); else if ($timeField['type'] == CustomFields::TYPE_DROPDOWN) $field_value = $record[$field_name.'_option_id']; - $row_identifier .= ',cf_'.$timeField['id'].":$field_value"; + $row_identifier .= ",$field_name:$field_value"; } } return $row_identifier; @@ -473,12 +471,6 @@ static function makeRowLabel($record) { if (!empty($label) && !empty($record['task'])) $label .= ' - '; $label .= $record['task']; - // Add custom field 1. - if ($user->isPluginEnabled('cf')) { - if (!empty($label) && !empty($record['cf_1_value'])) $label .= ' - '; - $label .= $record['cf_1_value']; - } - // Add custom field parts. global $custom_fields; if ($custom_fields && $custom_fields->timeFields) { @@ -494,9 +486,9 @@ static function makeRowLabel($record) { } // parseFromWeekViewRow - obtains field value encoded in row identifier. - // For example, for a row id like "cl:546,bl:0,pr:23456,ts:27464,cf_1:example text" + // For example, for a row id like "cl:546,bl:0,pr:23456,ts:27464,time_field_856:example text,time_field_857:2345" // requesting a client "cl" should return 546. - static function parseFromWeekViewRow($row_id, $field_label) { + static function parseFromWeekViewRow($row_id, $field_label, $base64decode = false) { // Find beginning of label. $pos = strpos($row_id, $field_label); if ($pos === false) return null; // Not found. @@ -504,15 +496,19 @@ static function parseFromWeekViewRow($row_id, $field_label) { // Strip suffix from row id. $suffixPos = strrpos($row_id, '_'); if ($suffixPos) - $remaninder = substr($row_id, 0, $suffixPos); + $remainder = substr($row_id, 0, $suffixPos); // Find beginning of value. - $posBegin = 1 + strpos($remaninder, ':', $pos); + $posBegin = 1 + strpos($remainder, ':', $pos); // Find end of value. - $posEnd = strpos($remaninder, ',', $posBegin); - if ($posEnd === false) $posEnd = strlen($remaninder); - // Return value. - return substr($remaninder, $posBegin, $posEnd - $posBegin); + $posEnd = strpos($remainder, ',', $posBegin); + if ($posEnd === false) $posEnd = strlen($remainder); + + $result = substr($remainder, $posBegin, $posEnd - $posBegin); + if ($base64decode) + $result = base64_decode($result); + + return $result; } // dateFromDayHeader calculates date from start date and day header in week view. @@ -571,13 +567,10 @@ static function insertDurationFromWeekView($fields, $custom_fields, $err) { if ($id && $custom_fields && $custom_fields->timeFields) { if ($fields['row_id']) { foreach ($custom_fields->timeFields as $timeField) { -// $control_name = 'time_field_'.$timeField['id']; + $base64decode = $timeField['type'] == CustomFields::TYPE_TEXT; // Decode all text fields back to clear text. $timeCustomFields[$timeField['id']] = array('field_id' => $timeField['id'], -// 'control_name' => $control_name, -// 'label' => $timeField['label'], 'type' => $timeField['type'], -// 'required' => $timeField['required'], - 'value' => ttWeekViewHelper::parseFromWeekViewRow($fields['row_id'], 'cf_'.$timeField['id'])); + 'value' => ttWeekViewHelper::parseFromWeekViewRow($fields['row_id'], 'time_field_'.$timeField['id'], $base64decode)); } } $result = $custom_fields->insertTimeFields($id, $timeCustomFields); // TODO: fix this. diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 820cf9c40..b00f04392 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.19.14.5179 | Copyright © Anuko | +  Anuko Time Tracker 1.19.14.5180 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/display_options.php b/display_options.php index ec4ddd95a..d65f15ab3 100644 --- a/display_options.php +++ b/display_options.php @@ -51,7 +51,6 @@ // Time page. // $form->addInput(array('type'=>'checkbox','name'=>'time_client','value'=>$cl_time_client)); -// $form->addInput(array('type'=>'checkbox','name'=>'time_cf_1','value'=>$cl_time_cf_1)); // $form->addInput(array('type'=>'checkbox','name'=>'time_project','value'=>$cl_time_project)); // $form->addInput(array('type'=>'checkbox','name'=>'time_task','value'=>$cl_time_task)); // $form->addInput(array('type'=>'checkbox','name'=>'time_start','value'=>$cl_time_start)); diff --git a/week.php b/week.php index 6b7cb1d90..b0d609d13 100644 --- a/week.php +++ b/week.php @@ -444,7 +444,10 @@ function render(&$table, $value, $row, $column, $selected = false) { if ($custom_fields && $custom_fields->timeFields) { foreach ($custom_fields->timeFields as $timeField) { $field_name = 'time_field_'.$timeField['id']; - $record[$field_name] = $timeCustomFields[$timeField['id']]['value']; + if ($timeField['type'] == CustomFields::TYPE_TEXT) + $record[$field_name] = $timeCustomFields[$timeField['id']]['value']; + else if ($timeField['type'] == CustomFields::TYPE_DROPDOWN) + $record[$field_name.'_option_id'] = $timeCustomFields[$timeField['id']]['value']; } } $fields['row_id'] = ttWeekViewHelper::makeRowIdentifier($record).'_0'; From 99cfa872fb82c5939be1dc8d4bc2ab0bd5c220cd Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 13 Mar 2020 16:36:52 +0000 Subject: [PATCH 183/877] Fixed timesheet approval workflow. --- WEB-INF/templates/footer.tpl | 2 +- timesheet_view.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index b00f04392..e2fee92b3 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.19.14.5180 | Copyright © Anuko | +  Anuko Time Tracker 1.19.15.5181 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/timesheet_view.php b/timesheet_view.php index c8d7048a4..a1ee74d26 100644 --- a/timesheet_view.php +++ b/timesheet_view.php @@ -65,7 +65,7 @@ $showApprovers = count($approvers) >= 1; } $canApprove = $user->can('approve_timesheets') || $user->can('approve_own_timesheets'); -$showApprove = $timesheet['submit_status'] && $timesheet['approve_status'] == null; +$showApprove = $timesheet['submit_status'] && $timesheet['approve_status'] == null && $canApprove; // Add a form with controls. $form = new Form('timesheetForm'); From 789503c8ec404352b316cf4302e29f9d729d67e4 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 17 Mar 2020 18:05:54 +0000 Subject: [PATCH 184/877] Removed a PHP warning condition. --- WEB-INF/templates/footer.tpl | 2 +- reports.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index e2fee92b3..1da155dcb 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.19.15.5181 | Copyright © Anuko | +  Anuko Time Tracker 1.19.15.5182 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/reports.php b/reports.php index 84d8bde08..253652b94 100644 --- a/reports.php +++ b/reports.php @@ -391,7 +391,7 @@ if ($request->isGet() && !$bean->isSaved()) { // No previous form data were found in session. Use the following default values. - $form->setValueByElement('users_active', array_keys($user_list_active)); + $form->setValueByElement('users_active', array_keys((array)$user_list_active)); $period = new Period(INTERVAL_THIS_MONTH, new DateAndTime($user->getDateFormat())); $form->setValueByElement('start_date', $period->getStartDate()); $form->setValueByElement('end_date', $period->getEndDate()); From 8762873a1eb28de2d927fad1a5906a6541b2a3c0 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 17 Mar 2020 18:31:48 +0000 Subject: [PATCH 185/877] Got rid of another PHP warning. --- WEB-INF/lib/ttUser.class.php | 2 +- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index 89a1973fb..1bdb1c19f 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -571,7 +571,7 @@ function addGroupToDropdown(&$groups, $group_id, $subgroup_level) { $groups[] = array('id'=>$group_id, 'name'=>$name); - $subgroups = $this->getSubgroups($group_id); + $subgroups = (array) $this->getSubgroups($group_id); foreach($subgroups as $subgroup) { $this->addGroupToDropdown($groups, $subgroup['id'], $subgroup_level+1); } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 1da155dcb..6a17b0185 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.19.15.5182 | Copyright © Anuko | +  Anuko Time Tracker 1.19.15.5183 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From a5e16a489f2021c9d709f59b34fa2ab611540d2f Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 17 Mar 2020 18:37:16 +0000 Subject: [PATCH 186/877] Got rid of another PHP warning. --- WEB-INF/lib/ttGroupHelper.class.php | 2 +- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/WEB-INF/lib/ttGroupHelper.class.php b/WEB-INF/lib/ttGroupHelper.class.php index 48e4de724..83ffe648c 100644 --- a/WEB-INF/lib/ttGroupHelper.class.php +++ b/WEB-INF/lib/ttGroupHelper.class.php @@ -157,7 +157,7 @@ static function markGroupDeleted($group_id) { // Keep the logic simple by returning false on first error. // Obtain subgroups and call self recursively on them. - $subgroups = $user->getSubgroups($group_id); + $subgroups = (array) $user->getSubgroups($group_id); foreach($subgroups as $subgroup) { if (!ttGroupHelper::markGroupDeleted($subgroup['id'])) return false; diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 6a17b0185..f682fe618 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.19.15.5183 | Copyright © Anuko | +  Anuko Time Tracker 1.19.15.5184 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 402edebfaefcf41f70e3c9e9b8223a32e5575416 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 17 Mar 2020 23:49:40 +0000 Subject: [PATCH 187/877] Eliminated one more PHP warning. --- WEB-INF/templates/footer.tpl | 2 +- charts.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index f682fe618..e49e3ff34 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.19.15.5184 | Copyright © Anuko | +  Anuko Time Tracker 1.19.15.5185 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/charts.php b/charts.php index 862a2fad6..4ca91a151 100644 --- a/charts.php +++ b/charts.php @@ -205,7 +205,7 @@ $file_name = $img_dir.$file_name; // Full file name. // Clean up the file system from older images. -$img_files = glob($img_dir.'chart_*.png'); +$img_files = (array) glob($img_dir.'chart_*.png'); foreach($img_files as $file) { // If the create time of file is older than 1 minute, delete it. if (filemtime($file) < (time() - 60)) { From 5a1c585bdc0633e871a1c2af81df22dfb28f314e Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 18 Mar 2020 01:36:13 +0000 Subject: [PATCH 188/877] Got rid of one more PHP warning. --- WEB-INF/templates/footer.tpl | 2 +- charts.php | 12 +++++++----- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index e49e3ff34..94fc6e34f 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.19.15.5185 | Copyright © Anuko | +  Anuko Time Tracker 1.19.15.5186 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/charts.php b/charts.php index 4ca91a151..942b5ce7b 100644 --- a/charts.php +++ b/charts.php @@ -205,11 +205,13 @@ $file_name = $img_dir.$file_name; // Full file name. // Clean up the file system from older images. -$img_files = (array) glob($img_dir.'chart_*.png'); -foreach($img_files as $file) { - // If the create time of file is older than 1 minute, delete it. - if (filemtime($file) < (time() - 60)) { - unlink($file); +$img_files = glob($img_dir.'chart_*.png'); +if (is_array($img_files)) { + foreach($img_files as $file) { + // If file creation time is older than 1 minute, delete it. + if (filemtime($file) < (time() - 60)) { + unlink($file); + } } } From 93e14dc4da46515c90b86d0330f1d3588f3c4ac0 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 13 May 2020 18:10:26 +0000 Subject: [PATCH 189/877] Fixed ttValidDate function to handle DD-MM-YYYY date format. --- WEB-INF/lib/common.lib.php | 3 ++- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/WEB-INF/lib/common.lib.php b/WEB-INF/lib/common.lib.php index b19feacdc..1f2829442 100644 --- a/WEB-INF/lib/common.lib.php +++ b/WEB-INF/lib/common.lib.php @@ -245,9 +245,10 @@ function ttValidDate($val) if (strlen($val) == 0) return false; - // This should accept a string in format 'YYYY-MM-DD', 'MM/DD/YYYY', 'DD.MM.YYYY', or 'DD.MM.YYYY whatever'. + // This should accept a string in format 'YYYY-MM-DD', 'MM/DD/YYYY', 'DD-MM-YYYY', 'DD.MM.YYYY', or 'DD.MM.YYYY whatever'. if (!preg_match('/^\d\d\d\d-\d\d-\d\d$/', $val) && !preg_match('/^\d\d\/\d\d\/\d\d\d\d$/', $val) && + !preg_match('/^\d\d\-\d\d\-\d\d\d\d$/', $val) && !preg_match('/^\d\d\.\d\d\.\d\d\d\d$/', $val) && !preg_match('/^\d\d\.\d\d\.\d\d\d\d .+$/', $val)) return false; diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 94fc6e34f..9af4352eb 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.19.15.5186 | Copyright © Anuko | +  Anuko Time Tracker 1.19.16.5187 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 355dfcff28334a24ab0d6f02535072a152ccf592 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 2 Jun 2020 17:51:50 +0000 Subject: [PATCH 190/877] Improved bot protection slightly. --- WEB-INF/lib/ttRegistrator.class.php | 10 +++++----- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/WEB-INF/lib/ttRegistrator.class.php b/WEB-INF/lib/ttRegistrator.class.php index e054fe001..936bb4ffd 100644 --- a/WEB-INF/lib/ttRegistrator.class.php +++ b/WEB-INF/lib/ttRegistrator.class.php @@ -217,7 +217,7 @@ private function setCreatedBy($user_id) { // registeredRecently determines if we already have successful recent registration(s) from user IP. // "recent" means the following: - // - 2 or more registrations during last 10 minutes, or + // - 2 or more registrations during last 15 minutes, or // - 1 registration during last minute. // // This offers some level of protection from bot registrations. @@ -225,17 +225,17 @@ function registeredRecently() { $mdb2 = getConnection(); $ip_part = ' created_ip = '.$mdb2->quote($_SERVER['REMOTE_ADDR']); - $sql = 'select count(*) as cnt from tt_groups where '.$ip_part.' and created > now() - interval 10 minute'; + $sql = 'select count(*) as cnt from tt_groups where '.$ip_part.' and created > now() - interval 15 minute'; $res = $mdb2->query($sql); if (is_a($res, 'PEAR_Error')) return false; $val = $res->fetchRow(); if ($val['cnt'] == 0) - return false; // No registrations in last 10 minutes. + return false; // No registrations in last 15 minutes. if ($val['cnt'] >= 2) - return true; // 2 or more registrations in last 10 mintes. + return true; // 2 or more registrations in last 15 mintes. - // If we are here, there was exactly one registration during last 10 minutes. + // If we are here, there was exactly one registration during last 15 minutes. // Determine if it occurred within the last minute in a separate query. $sql = 'select created from tt_groups where '.$ip_part.' and created > now() - interval 1 minute'; $res = $mdb2->query($sql); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 9af4352eb..72e375036 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.19.16.5187 | Copyright © Anuko | +  Anuko Time Tracker 1.19.16.5188 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 3540c71810375d32fbddfdcd40ba90f87d423bec Mon Sep 17 00:00:00 2001 From: Juergen Neumann Date: Thu, 11 Jun 2020 22:23:51 +0200 Subject: [PATCH 191/877] patched openldap to work with member_of groups (#90) Co-authored-by: Juergen Neumann --- WEB-INF/lib/auth/Auth_ldap.class.php | 45 +++++++++++++++++----------- 1 file changed, 28 insertions(+), 17 deletions(-) diff --git a/WEB-INF/lib/auth/Auth_ldap.class.php b/WEB-INF/lib/auth/Auth_ldap.class.php index 5fb3dcf3d..b2138e67c 100644 --- a/WEB-INF/lib/auth/Auth_ldap.class.php +++ b/WEB-INF/lib/auth/Auth_ldap.class.php @@ -199,12 +199,6 @@ function authenticate($login, $password) echo '$login_oldap='; var_dump($login_oldap); echo '
'; } - // check if the user specified full login - if (strpos($login, '@') === false) { - // append default domain - $login .= '@' . $this->params['default_domain']; - } - $lb = @ldap_bind($lc, $login_oldap, $password); if (isTrue('DEBUG')) { @@ -221,11 +215,18 @@ function authenticate($login, $password) // TODO: Fix this for OpenLDAP, as samaccountname has nothing to do with it. // get groups - $filter = 'samaccountname='.Auth_ldap::ldap_escape($login_oldap); - $fields = array('samaccountname', 'mail', 'memberof', 'department', 'displayname', 'telephonenumber', 'primarygroupid'); + if (isTrue('DEBUG')) { + echo '$member_of : '; var_dump($member_of); echo '
'; + } + + $filter = 'uid='.$login; // ldap search filter + $fields = array('memberof'); // ldap search attributes + // $fields = 'uid'; $sr = @ldap_search($lc, $this->params['base_dn'], $filter, $fields); if (isTrue('DEBUG')) { + echo '$filter='; var_dump($filter); echo '
'; + echo '$fields='; var_dump($fields); echo '
'; echo '$sr='; var_dump($sr); echo '
'; echo 'ldap_error()='; echo ldap_error($lc); echo '
'; } @@ -248,24 +249,28 @@ function authenticate($login, $password) return false; } - $groups = array(); + $groups = array(); // existing ldap group memberships - // extract group names from - // assuming the groups are in format: CN=,... for ($i = 0; $i < @$entries[0]['memberof']['count']; $i++) { - $grp = $entries[0]['memberof'][$i]; - $grp_fields = explode(',', $grp); - $groups[] = substr($grp_fields[0], 3); - } + $grp = $entries[0]['memberof'][$i]; + $groups[] = $grp; // append group to array + if (isTrue('DEBUG')) { + var_dump($grp); echo ' appended to $groups
'; + }; - if (isTrue('DEBUG')) { - echo '$member_of'; var_dump($member_of); echo '
'; } + // check for group membership foreach ($member_of as $check_grp) { + if (isTrue('DEBUG')) { + echo '$check_grp:'; var_dump($check_grp); echo '
'; + }; if (!in_array($check_grp, $groups)) { ldap_unbind($lc); + if (isTrue('DEBUG')) { + echo '=> '.$login.' is not a member of '.$check_grp.'
'; + }; return false; } } @@ -273,6 +278,12 @@ function authenticate($login, $password) ldap_unbind($lc); + // check if the user specified full login + if (strpos($login, '@') === false) { + // append default domain + $login .= '@' . $this->params['default_domain']; + } + return array('login' => $login, 'data' => $entries, 'member_of' => $groups); } From cf6afd523f46b24e4b08fd50ec2e6c3fc849bcf0 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 11 Jun 2020 20:38:13 +0000 Subject: [PATCH 192/877] Cleaned up some comments and styles, hopefully without breaking stuff. --- WEB-INF/lib/auth/Auth_ldap.class.php | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/WEB-INF/lib/auth/Auth_ldap.class.php b/WEB-INF/lib/auth/Auth_ldap.class.php index b2138e67c..59a539389 100644 --- a/WEB-INF/lib/auth/Auth_ldap.class.php +++ b/WEB-INF/lib/auth/Auth_ldap.class.php @@ -38,10 +38,6 @@ // In April 2012, a previously mandatory search for group membership was put in a conditional block (if ($member_of) - // when mandatory membership in groups is actually defined in config.php). // This made the module work with Sun Directory Server when NO GROUP MEMBERSHIP is specified. -// Note 1: search is likely to fail with Sun DS if 'member_of' => array()); is used in config.php. -// Note 2: search is likely to not work properly with OpenLDAP as well because of Windows specific filtering code in there -// (we are looking for matches for Windows-specific samaccountname property). Search needs to be redone during the next -// refactoring effort. /** @@ -212,8 +208,6 @@ function authenticate($login, $password) } if ($member_of) { - // TODO: Fix this for OpenLDAP, as samaccountname has nothing to do with it. - // get groups if (isTrue('DEBUG')) { echo '$member_of : '; var_dump($member_of); echo '
'; @@ -221,7 +215,6 @@ function authenticate($login, $password) $filter = 'uid='.$login; // ldap search filter $fields = array('memberof'); // ldap search attributes - // $fields = 'uid'; $sr = @ldap_search($lc, $this->params['base_dn'], $filter, $fields); if (isTrue('DEBUG')) { @@ -256,21 +249,19 @@ function authenticate($login, $password) $groups[] = $grp; // append group to array if (isTrue('DEBUG')) { var_dump($grp); echo ' appended to $groups
'; - }; - + } } - // check for group membership foreach ($member_of as $check_grp) { if (isTrue('DEBUG')) { echo '$check_grp:'; var_dump($check_grp); echo '
'; - }; + } if (!in_array($check_grp, $groups)) { ldap_unbind($lc); if (isTrue('DEBUG')) { - echo '=> '.$login.' is not a member of '.$check_grp.'
'; - }; + echo '=> '.$login.' is not a member of '.$check_grp.'
'; + } return false; } } From a1cd3a3e2d443a0aaca4109d64cbb2665bfb386d Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 13 Jun 2020 14:32:16 +0000 Subject: [PATCH 193/877] Included an improvement as per issue #89. --- WEB-INF/templates/footer.tpl | 2 +- initialize.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 72e375036..36c85f355 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.19.16.5188 | Copyright © Anuko | +  Anuko Time Tracker 1.19.16.5189 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/initialize.php b/initialize.php index 241d72334..404872936 100644 --- a/initialize.php +++ b/initialize.php @@ -85,8 +85,8 @@ // Set lifetime for garbage collection. ini_set('session.gc_maxlifetime', $phpsessid_ttl); // Set PHP session path, if defined to avoid garbage collection interference from other scripts. -if (defined('PHP_SESSION_PATH')) { - ini_set('session.save_path', PHP_SESSION_PATH); +if (defined('PHP_SESSION_PATH') && realpath(PHP_SESSION_PATH)) { + ini_set('session.save_path', realpath(PHP_SESSION_PATH)); ini_set('session.gc_probability', 1); } From 908e119d978dcfd26b126036ce4514c39a00c8a4 Mon Sep 17 00:00:00 2001 From: BTR Naidu Date: Tue, 16 Jun 2020 16:25:28 +0200 Subject: [PATCH 194/877] File permission error while loading the landing page (#92) --- dockerfile-tt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dockerfile-tt b/dockerfile-tt index 8902cbf7e..2b102f1ff 100644 --- a/dockerfile-tt +++ b/dockerfile-tt @@ -34,3 +34,5 @@ RUN cp /var/www/html/WEB-INF/config.php.dist /var/www/html/WEB-INF/config.php RUN sed -i "s|mysqli://root:no@localhost/dbname|mysqli://anuko_user:anuko_pw@anuko_db/timetracker|g" /var/www/html/WEB-INF/config.php # Note that db is defined as anuko_db/timetracker where anuko_db is service name and timetracker is db name. # See docker-compose.yml for details. + +RUN chown -R www-data /var/www/html/ From 88a5ef90c0a639efa0b9b140325beb3dd9f6a01f Mon Sep 17 00:00:00 2001 From: Juergen Neumann Date: Tue, 16 Jun 2020 16:59:16 +0200 Subject: [PATCH 195/877] Applying .Auth_ldap::ldap_escape($login) to openldap. (#93) * Applying .Auth_ldap::ldap_escape($login) to openldap. * added $user_login_attribute to config for openldap authentication Co-authored-by: Juergen Neumann --- WEB-INF/config.php.dist | 3 ++- WEB-INF/lib/auth/Auth_ldap.class.php | 14 +++++++++++--- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/WEB-INF/config.php.dist b/WEB-INF/config.php.dist index 6ffdff08e..a288ec0bf 100644 --- a/WEB-INF/config.php.dist +++ b/WEB-INF/config.php.dist @@ -150,7 +150,8 @@ define('AUTH_MODULE', 'db'); // 'server' => '127.0.0.1', // OpenLDAP server address or name. For secure LDAP use ldaps://hostname:port here. // 'type' => 'openldap', // Type of server. openldap type should also work with Sun Directory Server when member_of is empty. // It may work with other (non Windows AD) LDAP servers. For Windows AD use the 'ad' type. -// 'base_dn' => 'ou=People,dc=example,dc=com', // Base distinguished name in LDAP catalog. +// 'base_dn' => 'ou=People,dc=example,dc=com', // Path of user's base distinguished name in LDAP catalog. +// 'user_login_attribute' => 'uid', // LDAP attribute used for login // 'default_domain' => 'example.com', // Default domain. // 'member_of' => array()); // List of groups, membership in which is required for user to be authenticated. diff --git a/WEB-INF/lib/auth/Auth_ldap.class.php b/WEB-INF/lib/auth/Auth_ldap.class.php index 59a539389..3c43fd3a3 100644 --- a/WEB-INF/lib/auth/Auth_ldap.class.php +++ b/WEB-INF/lib/auth/Auth_ldap.class.php @@ -189,7 +189,15 @@ function authenticate($login, $password) if ($this->params['type'] == 'openldap') { // Assuming OpenLDAP server. - $login_oldap = 'uid='.$login.','.$this->params['base_dn']; + + if (empty($this->params['user_login_attribute'])) { + $user_login_attribute = 'uid'; + } else { + $user_login_attribute = @$this->params['user_login_attribute']; + + } + + $login_oldap = $user_login_attribute.'='.Auth_ldap::ldap_escape($login).','.$this->params['base_dn']; if (isTrue('DEBUG')) { echo '$login_oldap='; var_dump($login_oldap); echo '
'; @@ -213,8 +221,8 @@ function authenticate($login, $password) echo '$member_of : '; var_dump($member_of); echo '
'; } - $filter = 'uid='.$login; // ldap search filter - $fields = array('memberof'); // ldap search attributes + $filter = $user_login_attribute.'='.Auth_ldap::ldap_escape($login); // ldap search filter + $fields = array('memberof'); // ldap search attributes $sr = @ldap_search($lc, $this->params['base_dn'], $filter, $fields); if (isTrue('DEBUG')) { From fe25e6cf65c4cfda4ec5726a71c48ce7e7b36dde Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 16 Jun 2020 15:11:34 +0000 Subject: [PATCH 196/877] Some cleanup after pr #93 merge. --- WEB-INF/lib/auth/Auth_ldap.class.php | 3 +-- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/WEB-INF/lib/auth/Auth_ldap.class.php b/WEB-INF/lib/auth/Auth_ldap.class.php index 3c43fd3a3..7f3495737 100644 --- a/WEB-INF/lib/auth/Auth_ldap.class.php +++ b/WEB-INF/lib/auth/Auth_ldap.class.php @@ -193,8 +193,7 @@ function authenticate($login, $password) if (empty($this->params['user_login_attribute'])) { $user_login_attribute = 'uid'; } else { - $user_login_attribute = @$this->params['user_login_attribute']; - + $user_login_attribute = $this->params['user_login_attribute']; } $login_oldap = $user_login_attribute.'='.Auth_ldap::ldap_escape($login).','.$this->params['base_dn']; diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 36c85f355..fc42d9df4 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.19.16.5189 | Copyright © Anuko | +  Anuko Time Tracker 1.19.16.5190 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 74c23e14f9c755aef8139a0e7f01ac9c67500532 Mon Sep 17 00:00:00 2001 From: BTR Naidu Date: Sat, 20 Jun 2020 17:24:22 +0200 Subject: [PATCH 197/877] missing freetype library causes chart from loading (#95) --- dockerfile-tt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/dockerfile-tt b/dockerfile-tt index 2b102f1ff..9c79f4786 100644 --- a/dockerfile-tt +++ b/dockerfile-tt @@ -11,8 +11,9 @@ RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini" RUN docker-php-ext-install mysqli # Install gd extension. -RUN apt-get update && apt-get install libpng-dev -y \ - && docker-php-ext-install gd +RUN apt-get update && apt-get install libpng-dev libfreetype6-dev -y \ + && docker-php-ext-configure gd --with-freetype-dir=/usr/include/ \ + && docker-php-ext-install gd # Install ldap extension. RUN apt-get install libldap2-dev -y \ From b525c77813327c06b2d005e00b81dbfa8231e740 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 29 Jun 2020 20:55:36 +0000 Subject: [PATCH 198/877] Started to work on binding templates to projects. --- WEB-INF/templates/footer.tpl | 2 +- dbinstall.php | 14 ++++++++++---- mysql.sql | 18 +++++++++++++++++- 3 files changed, 28 insertions(+), 6 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index fc42d9df4..05c0feed6 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- - - + +
 Anuko Time Tracker 1.19.16.5190 | Copyright © Anuko | +  Anuko Time Tracker 1.19.17.5191 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/dbinstall.php b/dbinstall.php index ea476d403..f596a05e6 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -1161,7 +1161,7 @@ function ttGenerateKeys() { ttExecute("UPDATE `tt_site_config` SET param_value = '1.19.0', modified = now() where param_name = 'version_db' and param_value = '1.18.61'"); } - if ($_POST["convert11900to11914"]) { + if ($_POST["convert11900to11917"]) { ttExecute("CREATE TABLE `tt_work_currencies` (`id` int(10) unsigned NOT NULL,`name` varchar(10) NOT NULL,PRIMARY KEY (`id`))"); ttExecute("create unique index currency_idx on tt_work_currencies(`name`)"); ttExecute("INSERT INTO `tt_work_currencies` (`id`, `name`) VALUES ('1', 'USD'), ('2', 'CAD'), ('3', 'AUD'), ('4', 'EUR'), ('5', 'NZD')"); @@ -1183,6 +1183,11 @@ function ttGenerateKeys() { ttExecute("ALTER TABLE `tt_fav_reports` drop `cf_1_option_id`"); ttExecute("ALTER TABLE `tt_fav_reports` drop `show_custom_field_1`"); ttExecute("UPDATE `tt_site_config` SET param_value = '1.19.14', modified = now() where param_name = 'version_db' and param_value = '1.19.7'"); + ttExecute("CREATE TABLE `tt_project_template_binds` (`project_id` int(10) unsigned NOT NULL,`template_id` int(10) unsigned NOT NULL,`group_id` int(10) unsigned NOT NULL,`org_id` int(10) unsigned NOT NULL)"); + ttExecute("create index project_idx on tt_project_template_binds(project_id);"); + ttExecute("create index template_idx on tt_project_template_binds(template_id)"); + ttExecute("create unique index project_template_idx on tt_project_template_binds(project_id, template_id)"); + ttExecute("UPDATE `tt_site_config` SET param_value = '1.19.17', modified = now() where param_name = 'version_db' and param_value = '1.19.14'"); } if ($_POST["cleanup"]) { @@ -1210,6 +1215,7 @@ function ttGenerateKeys() { ttExecute("OPTIMIZE TABLE tt_log"); ttExecute("OPTIMIZE TABLE tt_monthly_quotas"); ttExecute("OPTIMIZE TABLE tt_templates"); + ttExecute("OPTIMIZE TABLE tt_project_template_binds"); ttExecute("OPTIMIZE TABLE tt_predefined_expenses"); ttExecute("OPTIMIZE TABLE tt_project_task_binds"); ttExecute("OPTIMIZE TABLE tt_projects"); @@ -1232,7 +1238,7 @@ function ttGenerateKeys() {

DB Install

-
Create database structure (v1.19.14) + Create database structure (v1.19.17)
(applies only to new installations, do not execute when updating)
@@ -1281,8 +1287,8 @@ function ttGenerateKeys() {
Update database structure (v1.19 to v1.19.14)Update database structure (v1.19 to v1.19.17)
diff --git a/mysql.sql b/mysql.sql index 3e9df4a1b..ae31890b5 100644 --- a/mysql.sql +++ b/mysql.sql @@ -565,6 +565,22 @@ CREATE TABLE `tt_templates` ( ); +# +# Structure for table tt_project_template_binds. This table maps projects to templates. +# +CREATE TABLE `tt_project_template_binds` ( + `project_id` int(10) unsigned NOT NULL, # project id + `template_id` int(10) unsigned NOT NULL, # template id + `group_id` int(10) unsigned NOT NULL, # group id + `org_id` int(10) unsigned NOT NULL # organization id +); + +# Indexes for tt_project_template_binds. +create index project_idx on tt_project_template_binds(project_id); +create index template_idx on tt_project_template_binds(template_id); +create unique index project_template_idx on tt_project_template_binds(project_id, template_id); + + # # Structure for table tt_files. # This table keeps file attachment information. @@ -639,4 +655,4 @@ CREATE TABLE `tt_site_config` ( PRIMARY KEY (`param_name`) ); -INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.19.14', now()); # TODO: change when structure changes. +INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.19.17', now()); # TODO: change when structure changes. From 625b4e3d69fe52e2b5affd9ed2d6ae616020053d Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 30 Jun 2020 14:30:38 +0000 Subject: [PATCH 199/877] Work in progress on associating templates with projects. --- WEB-INF/lib/ttOrgHelper.class.php | 1 + WEB-INF/lib/ttTemplateHelper.class.php | 23 +++++++++++++++++++++++ WEB-INF/templates/footer.tpl | 2 +- template_edit.php | 6 ++++++ 4 files changed, 31 insertions(+), 1 deletion(-) diff --git a/WEB-INF/lib/ttOrgHelper.class.php b/WEB-INF/lib/ttOrgHelper.class.php index 60126420a..ffb39beb4 100644 --- a/WEB-INF/lib/ttOrgHelper.class.php +++ b/WEB-INF/lib/ttOrgHelper.class.php @@ -98,6 +98,7 @@ static function deleteOrg($org_id) { 'tt_config', 'tt_cron', 'tt_fav_reports', + 'tt_project_template_binds', 'tt_templates', 'tt_monthly_quotas', 'tt_predefined_expenses', diff --git a/WEB-INF/lib/ttTemplateHelper.class.php b/WEB-INF/lib/ttTemplateHelper.class.php index e3a935646..e963877cc 100644 --- a/WEB-INF/lib/ttTemplateHelper.class.php +++ b/WEB-INF/lib/ttTemplateHelper.class.php @@ -118,4 +118,27 @@ static function update($fields) { $affected = $mdb2->exec($sql); return (!is_a($affected, 'PEAR_Error')); } + + // getAssignedProjects - returns an array of projects associatied with a template. + static function getAssignedProjects($template_id) + { + global $user; + + $result = array(); + $mdb2 = getConnection(); + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + // Do a query with inner join to get assigned projects. + $sql = "select p.id, p.name from tt_projects p + inner join tt_project_template_binds ptb on (ptb.project_id = p.id and ptb.template_id = $template_id) + where p.group_id = $group_id and p.org_id = $org_id and p.status = 1 order by p.name"; + $res = $mdb2->query($sql); + if (!is_a($res, 'PEAR_Error')) { + while ($val = $res->fetchRow()) { + $result[] = $val; + } + } + return $result; + } } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 05c0feed6..cbfce2f69 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.19.17.5191 | Copyright © Anuko | +  Anuko Time Tracker 1.19.17.5192 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/template_edit.php b/template_edit.php index 90e5f5655..568d9dbbb 100644 --- a/template_edit.php +++ b/template_edit.php @@ -47,16 +47,22 @@ } // End of access checks. +$projects = ttGroupHelper::getActiveProjects(); + if ($request->isPost()) { $cl_name = trim($request->getParameter('name')); $cl_description = trim($request->getParameter('description')); $cl_content = trim($request->getParameter('content')); $cl_status = $request->getParameter('status'); + $cl_projects = $request->getParameter('projects'); } else { $cl_name = $template['name']; $cl_description = $template['description']; $cl_content = $template['content']; $cl_status = $template['status']; + $assigned_projects = ttTemplateHelper::getAssignedProjects($cl_template_id); + foreach ($assigned_projects as $project_item) + $cl_projects[] = $project_item['id']; } $form = new Form('templateForm'); From dcfe5eb3b0e95d80cd4854d5244c16a8ef9e0ddb Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 30 Jun 2020 15:37:59 +0000 Subject: [PATCH 200/877] Added project selector on template_edit.php. --- WEB-INF/lib/ttTemplateHelper.class.php | 20 +++++++++++++++++++- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/task_add.tpl | 2 +- WEB-INF/templates/task_edit.tpl | 2 +- WEB-INF/templates/template_edit.tpl | 7 +++++++ template_edit.php | 5 ++++- 6 files changed, 33 insertions(+), 5 deletions(-) diff --git a/WEB-INF/lib/ttTemplateHelper.class.php b/WEB-INF/lib/ttTemplateHelper.class.php index e963877cc..33839d58e 100644 --- a/WEB-INF/lib/ttTemplateHelper.class.php +++ b/WEB-INF/lib/ttTemplateHelper.class.php @@ -109,6 +109,7 @@ static function update($fields) { $content = $fields['content']; $modified_part = ', modified = now(), modified_ip = '.$mdb2->quote($_SERVER['REMOTE_ADDR']).', modified_by = '.$user->id; $status = (int) $fields['status']; + $projects = $fields['projects']; $sql = "update tt_templates set name = ".$mdb2->quote($name). ", description = ".$mdb2->quote($description). @@ -116,7 +117,24 @@ static function update($fields) { ", status = ".$status. " where id = $template_id and group_id = $group_id and org_id = $org_id"; $affected = $mdb2->exec($sql); - return (!is_a($affected, 'PEAR_Error')); + if (is_a($affected, 'PEAR_Error')) + die($affected->getMessage()); + + // Insert project binds into tt_project_template_binds table. + $sql = "delete from tt_project_template_binds where template_id = $template_id"; + $affected = $mdb2->exec($sql); + if (is_a($affected, 'PEAR_Error')) + die($affected->getMessage()); + if (count($projects) > 0) + foreach ($projects as $p_id) { + $sql = "insert into tt_project_template_binds (project_id, template_id, group_id, org_id)". + " values($p_id, $template_id, $group_id, $org_id)"; + $affected = $mdb2->exec($sql); + if (is_a($affected, 'PEAR_Error')) + die($affected->getMessage()); + } + + return true; } // getAssignedProjects - returns an array of projects associatied with a template. diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index cbfce2f69..903c257ac 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- {if $show_projects} - + diff --git a/WEB-INF/templates/task_edit.tpl b/WEB-INF/templates/task_edit.tpl index 0bf189bba..0c2b1a555 100644 --- a/WEB-INF/templates/task_edit.tpl +++ b/WEB-INF/templates/task_edit.tpl @@ -17,7 +17,7 @@ {if $show_projects} - + diff --git a/WEB-INF/templates/template_edit.tpl b/WEB-INF/templates/template_edit.tpl index 6f3e406f8..f4db77878 100644 --- a/WEB-INF/templates/template_edit.tpl +++ b/WEB-INF/templates/template_edit.tpl @@ -19,6 +19,13 @@ +{if $show_projects} + + + + + +{/if} diff --git a/template_edit.php b/template_edit.php index 568d9dbbb..1bff1a3bf 100644 --- a/template_edit.php +++ b/template_edit.php @@ -72,6 +72,7 @@ $form->addInput(array('type'=>'textarea','name'=>'content','style'=>'width: 250px; height: 80px;','value'=>$cl_content)); $form->addInput(array('type'=>'combobox','name'=>'status','value'=>$cl_status, 'data'=>array(ACTIVE=>$i18n->get('dropdown.status_active'),INACTIVE=>$i18n->get('dropdown.status_inactive')))); +$form->addInput(array('type'=>'checkboxgroup','name'=>'projects','layout'=>'H','data'=>$projects,'datakeys'=>array('id','name'),'value'=>$cl_projects)); $form->addInput(array('type'=>'submit','name'=>'btn_submit','value'=>$i18n->get('button.submit'))); if ($request->isPost()) { @@ -87,7 +88,8 @@ 'name' => $cl_name, 'description' => $cl_description, 'content' => $cl_content, - 'status' => $cl_status))) { + 'status' => $cl_status, + 'projects' => $cl_projects))) { header('Location: templates.php'); exit(); } else @@ -96,6 +98,7 @@ } // isPost $smarty->assign('forms', array($form->getName()=>$form->toArray())); +$smarty->assign('show_projects', count($projects) > 0 && defined('TEMPLATES_DEBUG')); $smarty->assign('title', $i18n->get('title.edit_template')); $smarty->assign('content_page_name', 'template_edit.tpl'); $smarty->display('index.tpl'); From 6942f78f7bfe309b368e8243f715d4381e6ccd9d Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 30 Jun 2020 16:13:15 +0000 Subject: [PATCH 201/877] Added project selector on template_add.php. --- WEB-INF/lib/ttTemplateHelper.class.php | 16 +++++++++++++++- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/template_add.tpl | 7 +++++++ WEB-INF/templates/templates.tpl | 2 +- template_add.php | 11 ++++++++++- 5 files changed, 34 insertions(+), 4 deletions(-) diff --git a/WEB-INF/lib/ttTemplateHelper.class.php b/WEB-INF/lib/ttTemplateHelper.class.php index 33839d58e..6aec08c73 100644 --- a/WEB-INF/lib/ttTemplateHelper.class.php +++ b/WEB-INF/lib/ttTemplateHelper.class.php @@ -81,6 +81,7 @@ static function insert($fields) { $name = $fields['name']; $description = $fields['description']; $content = $fields['content']; + $projects = $fields['projects']; $created_part = ', now(), '.$mdb2->quote($_SERVER['REMOTE_ADDR']).', '.$user->id; @@ -89,10 +90,23 @@ static function insert($fields) { " values ($group_id, $org_id, ".$mdb2->quote($name). ", ".$mdb2->quote($description).", ".$mdb2->quote($content).$created_part.")"; $affected = $mdb2->exec($sql); + $last_id = 0; if (is_a($affected, 'PEAR_Error')) return false; - return true; + $last_id = $mdb2->lastInsertID('tt_templates', 'id'); + + if (is_array($projects)) { + foreach ($projects as $p_id) { + // Insert project binds into tt_project_template_binds table. + $sql = "insert into tt_project_template_binds (project_id, template_id, group_id, org_id)". + " values($p_id, $last_id, $group_id, $org_id)"; + $affected = $mdb2->exec($sql); + if (is_a($affected, 'PEAR_Error')) + return false; + } + } + return $last_id; } // update function - updates a template in database. diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 903c257ac..a232aa149 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.19.17.5192 | Copyright © Anuko | +  Anuko Time Tracker 1.19.17.5193 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/task_add.tpl b/WEB-INF/templates/task_add.tpl index 8e7f7882f..d1892709a 100644 --- a/WEB-INF/templates/task_add.tpl +++ b/WEB-INF/templates/task_add.tpl @@ -13,7 +13,7 @@
 
{$i18n.label.projects}: {$forms.taskForm.projects.control}
 
{$i18n.label.projects}: {$forms.taskForm.projects.control}
{$i18n.label.status}: {$forms.templateForm.status.control}
 
{$i18n.label.projects}:{$forms.templateForm.projects.control}
{$i18n.label.required_fields}
- +{if $show_projects} + + + + + +{/if} diff --git a/WEB-INF/templates/templates.tpl b/WEB-INF/templates/templates.tpl index 2e388b491..c0a74422d 100644 --- a/WEB-INF/templates/templates.tpl +++ b/WEB-INF/templates/templates.tpl @@ -26,7 +26,7 @@
 Anuko Time Tracker 1.19.17.5193 | Copyright © Anuko | +  Anuko Time Tracker 1.19.17.5194 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/template_add.tpl b/WEB-INF/templates/template_add.tpl index 2a52cec32..bfd624028 100644 --- a/WEB-INF/templates/template_add.tpl +++ b/WEB-INF/templates/template_add.tpl @@ -15,6 +15,13 @@ {$i18n.label.template} (*): {$forms.templateForm.content.control}
 
{$i18n.label.projects}:{$forms.templateForm.projects.control}
{$i18n.label.required_fields}
{if $inactive_templates} - + diff --git a/template_add.php b/template_add.php index 6fb0238e4..e7e828444 100644 --- a/template_add.php +++ b/template_add.php @@ -41,16 +41,23 @@ } // End of access checks. +$projects = ttGroupHelper::getActiveProjects(); + if ($request->isPost()) { $cl_name = trim($request->getParameter('name')); $cl_description = trim($request->getParameter('description')); $cl_content = trim($request->getParameter('content')); + $cl_projects = $request->getParameter('projects'); +} else { + foreach ($projects as $project_item) + $cl_projects[] = $project_item['id']; } $form = new Form('templateForm'); $form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'name','style'=>'width: 250px;','value'=>$cl_name)); $form->addInput(array('type'=>'textarea','name'=>'description','style'=>'width: 250px; height: 40px;','value'=>$cl_description)); $form->addInput(array('type'=>'textarea','name'=>'content','style'=>'width: 250px; height: 80px;','value'=>$cl_content)); +$form->addInput(array('type'=>'checkboxgroup','name'=>'projects','layout'=>'H','data'=>$projects,'datakeys'=>array('id','name'),'value'=>$cl_projects)); $form->addInput(array('type'=>'submit','name'=>'btn_add','value'=>$i18n->get('button.add'))); if ($request->isPost()) { @@ -64,7 +71,8 @@ if (ttTemplateHelper::insert(array( 'name' => $cl_name, 'description' => $cl_description, - 'content' => $cl_content))) { + 'content' => $cl_content, + 'projects' => $cl_projects))) { header('Location: templates.php'); exit(); } else @@ -73,6 +81,7 @@ } // isPost $smarty->assign('forms', array($form->getName()=>$form->toArray())); +$smarty->assign('show_projects', count($projects) > 0 && defined('TEMPLATES_DEBUG')); $smarty->assign('title', $i18n->get('title.add_template')); $smarty->assign('content_page_name', 'template_add.tpl'); $smarty->display('index.tpl'); From 9fbacfa36e86370d8c71ef7a282c769e4d7d6710 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 30 Jun 2020 21:42:05 +0000 Subject: [PATCH 202/877] More progress towards associating templates with projects. --- WEB-INF/lib/ttProjectHelper.class.php | 6 ++++++ WEB-INF/lib/ttTemplateHelper.class.php | 28 ++++++++++++++++++++++++++ WEB-INF/lib/ttUser.class.php | 11 ++++++++-- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/time.tpl | 4 ++-- WEB-INF/templates/time_script.tpl | 1 + projects.php | 6 ++++-- time.php | 20 +++++++++++------- 8 files changed, 64 insertions(+), 14 deletions(-) diff --git a/WEB-INF/lib/ttProjectHelper.class.php b/WEB-INF/lib/ttProjectHelper.class.php index 399cba2d2..d456c3110 100644 --- a/WEB-INF/lib/ttProjectHelper.class.php +++ b/WEB-INF/lib/ttProjectHelper.class.php @@ -204,6 +204,12 @@ static function delete($id) { if (is_a($affected, 'PEAR_Error')) return false; + // Delete template binds to this project. + $sql = "delete from tt_project_template_binds where project_id = $id and group_id = $group_id and org_id = $org_id"; + $affected = $mdb2->exec($sql); + if (is_a($affected, 'PEAR_Error')) + return false; + // Finally, delete the project from the projects field in tt_clients table. $result = ttClientHelper::deleteProject($id); return $result; diff --git a/WEB-INF/lib/ttTemplateHelper.class.php b/WEB-INF/lib/ttTemplateHelper.class.php index 6aec08c73..cedda1671 100644 --- a/WEB-INF/lib/ttTemplateHelper.class.php +++ b/WEB-INF/lib/ttTemplateHelper.class.php @@ -67,6 +67,12 @@ static function delete($id) { if (is_a($affected, 'PEAR_Error')) return false; + // Delete project binds to this template. + $sql = "delete from tt_project_template_binds where template_id = $id and group_id = $group_id and org_id = $org_id"; + $affected = $mdb2->exec($sql); + if (is_a($affected, 'PEAR_Error')) + return false; + return true; } @@ -173,4 +179,26 @@ static function getAssignedProjects($template_id) } return $result; } + + // getAssignedTemplates - returns a comma-separated list of template ids assigned to a project. + static function getAssignedTemplates($project_id) + { + global $user; + + $result = array(); + $mdb2 = getConnection(); + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $sql = "select template_id from tt_project_template_binds + where project_id = $project_id and group_id = $group_id and org_id = $org_id" ; + $res = $mdb2->query($sql); + if (!is_a($res, 'PEAR_Error')) { + while ($val = $res->fetchRow()) { + $result[] = $val['template_id']; + } + } + $comma_separated = implode(',', $result); // This is a comma-separated list of associated template ids. + return $comma_separated; + } } diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index 1bdb1c19f..42f9b0d90 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -32,6 +32,7 @@ import('ttGroup'); import('form.Form'); import('form.ActionForm'); +import('ttTemplateHelper'); class ttUser { var $login = null; // User login. @@ -333,7 +334,7 @@ function setOption($option, $enable = true) } // getAssignedProjects - returns an array of assigned projects. - function getAssignedProjects($includeFiles = false) + function getAssignedProjects($options = null) { $result = array(); $mdb2 = getConnection(); @@ -342,7 +343,7 @@ function getAssignedProjects($includeFiles = false) $group_id = $this->getGroup(); $org_id = $this->org_id; - if ($includeFiles) { + if ($options['include_files']) { $filePart = ', if(Sub1.entity_id is null, 0, 1) as has_files'; $fileJoin = " left join (select distinct entity_id from tt_files". " where entity_type = 'project' and group_id = $group_id and org_id = $org_id and status = 1) Sub1". @@ -356,6 +357,12 @@ function getAssignedProjects($includeFiles = false) $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { while ($val = $res->fetchRow()) { + // If we have to include templates, get them in a separate query for each project. + // Although, theoretically, we could use mysql group_concat, but this requires grouping by, which makes + // maintenance of this code more complex. + if ($options['include_templates']) { + $val['templates'] = ttTemplateHelper::getAssignedTemplates($val['id']); + } $result[] = $val; } } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index a232aa149..4ec458529 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
{$i18n.form.tasks.inactive_tasks}
{$i18n.form.templates.inactive_templates}
{$i18n.label.thing_name} {$i18n.label.description}
- {/if} -{if $user->isPluginEnabled('iv')} +{if $show_billable} @@ -81,7 +81,7 @@ {/if} -{if $template_dropdown} +{if $show_templates} diff --git a/WEB-INF/templates/time_script.tpl b/WEB-INF/templates/time_script.tpl index 3e8a02024..529acfe5a 100644 --- a/WEB-INF/templates/time_script.tpl +++ b/WEB-INF/templates/time_script.tpl @@ -13,6 +13,7 @@ // project_names[325] = "Time Tracker"; // Project name. // task_ids[325] = "100,101,302,303,304"; // Comma-separated list ot task ids for project. // task_names[100] = "Coding"; // Task name. +// template_ids[325] = "17,21"; // Comma-separated list ot template ids for project. NOT YET IMPLEMENTED. // Prepare an array of project ids for clients. var project_ids = new Array(); diff --git a/projects.php b/projects.php index 1b137895e..0075c038f 100644 --- a/projects.php +++ b/projects.php @@ -45,8 +45,10 @@ if($user->can('manage_projects')) { $active_projects = ttGroupHelper::getActiveProjects($showFiles); $inactive_projects = ttGroupHelper::getInactiveProjects($showFiles); -} else - $active_projects = $user->getAssignedProjects($showFiles); +} else { + $options['include_files'] = $showFiles; + $active_projects = $user->getAssignedProjects($options); +} $smarty->assign('active_projects', $active_projects); $smarty->assign('inactive_projects', $inactive_projects); diff --git a/time.php b/time.php index 8b1c0926f..5e24904a5 100644 --- a/time.php +++ b/time.php @@ -69,6 +69,7 @@ $group_id = $user->getGroup(); $showClient = $user->isPluginEnabled('cl'); +$showBillable = $user->isPluginEnabled('iv'); $trackingMode = $user->getTrackingMode(); $showProject = MODE_PROJECTS == $trackingMode || MODE_PROJECTS_AND_TASKS == $trackingMode; $showTask = MODE_PROJECTS_AND_TASKS == $trackingMode; @@ -76,6 +77,7 @@ $showStart = TYPE_START_FINISH == $recordType || TYPE_ALL == $recordType; $showFinish = $showStart; $showDuration = TYPE_DURATION == $recordType || TYPE_ALL == $recordType; +$showTemplates = $user->isPluginEnabled('tp'); $showFiles = $user->isPluginEnabled('at'); // Initialize and store date in session. @@ -206,7 +208,8 @@ if ($showProject) { // Dropdown for projects assigned to user. - $project_list = $user->getAssignedProjects(); + $options['include_templates'] = $showTemplates; + $project_list = $user->getAssignedProjects($options); $form->addInput(array('type'=>'combobox', 'onchange'=>'fillTaskDropdown(this.value);', 'name'=>'project', @@ -245,6 +248,9 @@ } } +if ($showBillable) + $form->addInput(array('type'=>'checkbox','name'=>'billable','value'=>$cl_billable)); + if ($showTask) { $task_list = ttGroupHelper::getActiveTasks(); $form->addInput(array('type'=>'combobox', @@ -277,9 +283,7 @@ -// TODO: refactoring ongoing down from here. Use $showBillable, perhaps? -if ($user->isPluginEnabled('iv')) - $form->addInput(array('type'=>'checkbox','name'=>'billable','value'=>$cl_billable)); +// TODO: refactoring ongoing down from here. $form->addInput(array('type'=>'hidden','name'=>'browser_today','value'=>'')); // User current date, which gets filled in on btn_submit click. $form->addInput(array('type'=>'submit','name'=>'btn_submit','onclick'=>'browser_today.value=get_date()','value'=>$i18n->get('button.submit'))); @@ -300,7 +304,7 @@ } // If we have templates, add a dropdown to select one. -if ($user->isPluginEnabled('tp')){ +if ($showTemplates){ $templates = ttGroupHelper::getActiveTemplates(); if (count($templates) >= 1) { $form->addInput(array('type'=>'combobox', @@ -310,7 +314,7 @@ 'data'=>$templates, 'datakeys'=>array('id','name'), 'empty'=>array(''=>$i18n->get('dropdown.select')))); - $smarty->assign('template_dropdown', 1); + $smarty->assign('show_templates', 1); $smarty->assign('templates', $templates); } } @@ -358,7 +362,7 @@ $err->add($i18n->get('error.field'), $i18n->get('label.duration')); } if (!ttValidString($cl_note, true)) $err->add($i18n->get('error.field'), $i18n->get('label.note')); - if ($user->isPluginEnabled('tp') && !ttValidTemplateText($cl_note)) { + if ($showTemplates && !ttValidTemplateText($cl_note)) { $err->add($i18n->get('error.field'), $i18n->get('label.note')); } if (!ttTimeHelper::canAdd()) $err->add($i18n->get('error.expired')); @@ -465,11 +469,13 @@ $smarty->assign('time_records', $timeRecords); $smarty->assign('show_navigation', $user->isPluginEnabled('wv') && !$user->isOptionEnabled('week_menu')); $smarty->assign('show_client', $showClient); +$smarty->assign('show_billable', $showBillable); $smarty->assign('show_project', $showProject); $smarty->assign('show_task', $showTask); $smarty->assign('show_start', $showStart); $smarty->assign('show_finish', $showFinish); $smarty->assign('show_duration', $showDuration); +$smarty->assign('show_templates', $showTemplates); $smarty->assign('show_note_column', $showNoteColumn); $smarty->assign('show_note_row', $showNoteRow); $smarty->assign('show_files', $showFiles); From 4128cf13931abaa84cbe57ca1d094a183124ca1d Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 30 Jun 2020 21:57:04 +0000 Subject: [PATCH 203/877] Fixed template content population - broken in previous commit. --- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/time.tpl | 2 +- time.php | 7 +++---- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 4ec458529..3794de8f5 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.19.17.5194 | Copyright © Anuko | +  Anuko Time Tracker 1.19.17.5195 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/time.tpl b/WEB-INF/templates/time.tpl index 94be028b3..5663d89b7 100644 --- a/WEB-INF/templates/time.tpl +++ b/WEB-INF/templates/time.tpl @@ -30,7 +30,7 @@ {$forms.timeRecordForm.client.control}
  {$forms.timeRecordForm.newfile.control}
{$i18n.label.template}: {$forms.timeRecordForm.template.control}
- {/if} -{if $show_templates} +{if $template_dropdown} diff --git a/time.php b/time.php index 5e24904a5..3a9e582aa 100644 --- a/time.php +++ b/time.php @@ -77,7 +77,6 @@ $showStart = TYPE_START_FINISH == $recordType || TYPE_ALL == $recordType; $showFinish = $showStart; $showDuration = TYPE_DURATION == $recordType || TYPE_ALL == $recordType; -$showTemplates = $user->isPluginEnabled('tp'); $showFiles = $user->isPluginEnabled('at'); // Initialize and store date in session. @@ -304,7 +303,7 @@ } // If we have templates, add a dropdown to select one. -if ($showTemplates){ +if ($user->isPluginEnabled('tp')){ $templates = ttGroupHelper::getActiveTemplates(); if (count($templates) >= 1) { $form->addInput(array('type'=>'combobox', @@ -314,7 +313,7 @@ 'data'=>$templates, 'datakeys'=>array('id','name'), 'empty'=>array(''=>$i18n->get('dropdown.select')))); - $smarty->assign('show_templates', 1); + $smarty->assign('template_dropdown', 1); $smarty->assign('templates', $templates); } } @@ -362,7 +361,7 @@ $err->add($i18n->get('error.field'), $i18n->get('label.duration')); } if (!ttValidString($cl_note, true)) $err->add($i18n->get('error.field'), $i18n->get('label.note')); - if ($showTemplates && !ttValidTemplateText($cl_note)) { + if ($user->isPluginEnabled('tp') && !ttValidTemplateText($cl_note)) { $err->add($i18n->get('error.field'), $i18n->get('label.note')); } if (!ttTimeHelper::canAdd()) $err->add($i18n->get('error.expired')); From df5542ddf3de5aa8051f551a8a05ec88cd8d6aad Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 2 Jul 2020 17:51:19 +0000 Subject: [PATCH 204/877] Work in progress adding bind templates with projects option. --- WEB-INF/resources/ca.lang.php | 1 + WEB-INF/resources/cs.lang.php | 1 + WEB-INF/resources/da.lang.php | 1 + WEB-INF/resources/de.lang.php | 1 + WEB-INF/resources/en.lang.php | 1 + WEB-INF/resources/es.lang.php | 1 + WEB-INF/resources/et.lang.php | 1 + WEB-INF/resources/fa.lang.php | 1 + WEB-INF/resources/fi.lang.php | 1 + WEB-INF/resources/fr.lang.php | 1 + WEB-INF/resources/gr.lang.php | 1 + WEB-INF/resources/he.lang.php | 1 + WEB-INF/resources/hu.lang.php | 1 + WEB-INF/resources/it.lang.php | 1 + WEB-INF/resources/ja.lang.php | 1 + WEB-INF/resources/ko.lang.php | 1 + WEB-INF/resources/nl.lang.php | 2 ++ WEB-INF/resources/no.lang.php | 1 + WEB-INF/resources/pl.lang.php | 1 + WEB-INF/resources/pt-br.lang.php | 1 + WEB-INF/resources/pt.lang.php | 1 + WEB-INF/resources/ro.lang.php | 1 + WEB-INF/resources/ru.lang.php | 1 + WEB-INF/resources/sk.lang.php | 1 + WEB-INF/resources/sl.lang.php | 1 + WEB-INF/resources/sr.lang.php | 1 + WEB-INF/resources/sv.lang.php | 1 + WEB-INF/resources/tr.lang.php | 1 + WEB-INF/resources/zh-cn.lang.php | 1 + WEB-INF/resources/zh-tw.lang.php | 1 + WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/templates.tpl | 6 ++++++ templates.php | 10 ++++++++++ 33 files changed, 48 insertions(+), 1 deletion(-) diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index f49ce3025..658a19318 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -276,6 +276,7 @@ // 'label.approval' => 'Report approval', // 'label.mark_approved' => 'Mark approved', // 'label.template' => 'Template', +// 'label.bind_templates_with_projects' => 'Bind templates with projects', // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index 6459cc953..4ec5d0093 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -286,6 +286,7 @@ // 'label.approval' => 'Report approval', // 'label.mark_approved' => 'Mark approved', // 'label.template' => 'Template', +// 'label.bind_templates_with_projects' => 'Bind templates with projects', // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index e03d73d43..3905d8950 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -266,6 +266,7 @@ // 'label.approval' => 'Report approval', // 'label.mark_approved' => 'Mark approved', // 'label.template' => 'Template', +// 'label.bind_templates_with_projects' => 'Bind templates with projects', // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index b4663d1b3..b0e8c4af5 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -256,6 +256,7 @@ // 'label.approval' => 'Report approval', // 'label.mark_approved' => 'Mark approved', // 'label.template' => 'Template', +// 'label.bind_templates_with_projects' => 'Bind templates with projects', // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index 0c1b8e0a9..b52195d6b 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -250,6 +250,7 @@ 'label.approval' => 'Report approval', 'label.mark_approved' => 'Mark approved', 'label.template' => 'Template', +'label.bind_templates_with_projects' => 'Bind templates with projects', 'label.attachments' => 'Attachments', 'label.files' => 'Files', 'label.file' => 'File', diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index a8faaf364..30fb2803d 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -279,6 +279,7 @@ // 'label.approval' => 'Report approval', // 'label.mark_approved' => 'Mark approved', // 'label.template' => 'Template', +// 'label.bind_templates_with_projects' => 'Bind templates with projects', // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index ecb4a1e20..1539d26e3 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -273,6 +273,7 @@ // 'label.approval' => 'Report approval', // 'label.mark_approved' => 'Mark approved', // 'label.template' => 'Template', +// 'label.bind_templates_with_projects' => 'Bind templates with projects', // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index 33776560a..eb5f095e5 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -277,6 +277,7 @@ // 'label.approval' => 'Report approval', // 'label.mark_approved' => 'Mark approved', // 'label.template' => 'Template', +// 'label.bind_templates_with_projects' => 'Bind templates with projects', // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index d8d477d15..1b0f0bc9a 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -270,6 +270,7 @@ // 'label.approval' => 'Report approval', // 'label.mark_approved' => 'Mark approved', // 'label.template' => 'Template', +// 'label.bind_templates_with_projects' => 'Bind templates with projects', // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index 39755c50c..e84e6f9fc 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -264,6 +264,7 @@ // 'label.approval' => 'Report approval', // 'label.mark_approved' => 'Mark approved', // 'label.template' => 'Template', +// 'label.bind_templates_with_projects' => 'Bind templates with projects', // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index 16baaf28c..46a18d53e 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -260,6 +260,7 @@ // 'label.approval' => 'Report approval', // 'label.mark_approved' => 'Mark approved', // 'label.template' => 'Template', +// 'label.bind_templates_with_projects' => 'Bind templates with projects', // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index 706be9cae..c1697904a 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -285,6 +285,7 @@ // 'label.approval' => 'Report approval', // 'label.mark_approved' => 'Mark approved', // 'label.template' => 'Template', +// 'label.bind_templates_with_projects' => 'Bind templates with projects', // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index 8176a45c8..b136dc1fd 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -282,6 +282,7 @@ // 'label.approval' => 'Report approval', // 'label.mark_approved' => 'Mark approved', // 'label.template' => 'Template', +// 'label.bind_templates_with_projects' => 'Bind templates with projects', // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index 7f667b445..0805dcbe3 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -264,6 +264,7 @@ // 'label.approval' => 'Report approval', // 'label.mark_approved' => 'Mark approved', // 'label.template' => 'Template', +// 'label.bind_templates_with_projects' => 'Bind templates with projects', // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index fb0fd6fcb..5826460b8 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -286,6 +286,7 @@ // 'label.approval' => 'Report approval', // 'label.mark_approved' => 'Mark approved', // 'label.template' => 'Template', +// 'label.bind_templates_with_projects' => 'Bind templates with projects', // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index 8414edb52..0b2b51b1d 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -286,6 +286,7 @@ // 'label.approval' => 'Report approval', // 'label.mark_approved' => 'Mark approved', // 'label.template' => 'Template', +// 'label.bind_templates_with_projects' => 'Bind templates with projects', // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index fc7aeb361..29826bcd2 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -255,6 +255,8 @@ 'label.approval' => 'Rapport goedkeuring', 'label.mark_approved' => 'Markeer goedkeuring', 'label.template' => 'Sjabloon', +// TODO: translate the following. +// 'label.bind_templates_with_projects' => 'Bind templates with projects', 'label.attachments' => 'Bijlagen', 'label.files' => 'Bestanden', 'label.file' => 'Bestand', diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index b0dc2ead0..c1696fc11 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -283,6 +283,7 @@ // 'label.approval' => 'Report approval', // 'label.mark_approved' => 'Mark approved', // 'label.template' => 'Template', +// 'label.bind_templates_with_projects' => 'Bind templates with projects', // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index de6ded99a..046fa922c 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -271,6 +271,7 @@ // 'label.approval' => 'Report approval', // 'label.mark_approved' => 'Mark approved', // 'label.template' => 'Template', +// 'label.bind_templates_with_projects' => 'Bind templates with projects', // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index fafb843bb..5e97cf7ac 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -268,6 +268,7 @@ // 'label.approval' => 'Report approval', // 'label.mark_approved' => 'Mark approved', // 'label.template' => 'Template', +// 'label.bind_templates_with_projects' => 'Bind templates with projects', // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index 3c6ecefd9..01751f8e5 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -271,6 +271,7 @@ // 'label.approval' => 'Report approval', // 'label.mark_approved' => 'Mark approved', // 'label.template' => 'Template', +// 'label.bind_templates_with_projects' => 'Bind templates with projects', // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index 9b6fc1750..9756a1cea 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -283,6 +283,7 @@ // 'label.approval' => 'Report approval', // 'label.mark_approved' => 'Mark approved', // 'label.template' => 'Template', +// 'label.bind_templates_with_projects' => 'Bind templates with projects', // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index a08157191..48795ca22 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -241,6 +241,7 @@ 'label.approval' => 'Одобрение отчётов', 'label.mark_approved' => 'Отметить одобрение', 'label.template' => 'Шаблон', +'label.bind_templates_with_projects' => 'Связать шаблоны с проектамиЫ', 'label.attachments' => 'Приложения', 'label.files' => 'Файлы', 'label.file' => 'Файл', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index 88d310e12..159b6ce45 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -275,6 +275,7 @@ // 'label.approval' => 'Report approval', // 'label.mark_approved' => 'Mark approved', // 'label.template' => 'Template', +// 'label.bind_templates_with_projects' => 'Bind templates with projects', // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index ae9d8ab8c..6ffa74b57 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -266,6 +266,7 @@ // 'label.approval' => 'Report approval', // 'label.mark_approved' => 'Mark approved', // 'label.template' => 'Template', +// 'label.bind_templates_with_projects' => 'Bind templates with projects', // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index b29f81bca..523277b32 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -269,6 +269,7 @@ // 'label.approval' => 'Report approval', // 'label.mark_approved' => 'Mark approved', // 'label.template' => 'Template', +// 'label.bind_templates_with_projects' => 'Bind templates with projects', // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index 41dea480e..4112465f2 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -266,6 +266,7 @@ // 'label.approval' => 'Report approval', // 'label.mark_approved' => 'Mark approved', // 'label.template' => 'Template', +// 'label.bind_templates_with_projects' => 'Bind templates with projects', // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index 4ac00f1c1..ab1d51bae 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -290,6 +290,7 @@ // 'label.approval' => 'Report approval', // 'label.mark_approved' => 'Mark approved', // 'label.template' => 'Template', +// 'label.bind_templates_with_projects' => 'Bind templates with projects', // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index 8d96b36ee..7b6dbef6d 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -275,6 +275,7 @@ // 'label.approval' => 'Report approval', // 'label.mark_approved' => 'Mark approved', // 'label.template' => 'Template', +// 'label.bind_templates_with_projects' => 'Bind templates with projects', // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index 77acaecad..454b000c1 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -281,6 +281,7 @@ // 'label.approval' => 'Report approval', // 'label.mark_approved' => 'Mark approved', // 'label.template' => 'Template', +// 'label.bind_templates_with_projects' => 'Bind templates with projects', // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 3794de8f5..fdcbd866b 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.19.17.5195 | Copyright © Anuko | +  Anuko Time Tracker 1.19.17.5196 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/time.tpl b/WEB-INF/templates/time.tpl index 5663d89b7..d153dc96d 100644 --- a/WEB-INF/templates/time.tpl +++ b/WEB-INF/templates/time.tpl @@ -81,7 +81,7 @@ {$forms.timeRecordForm.newfile.control}
{$i18n.label.template}: {$forms.timeRecordForm.template.control}
-
 Anuko Time Tracker 1.19.17.5196 | Copyright © Anuko | +  Anuko Time Tracker 1.19.17.5197 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/templates.tpl b/WEB-INF/templates/templates.tpl index c0a74422d..80991537e 100644 --- a/WEB-INF/templates/templates.tpl +++ b/WEB-INF/templates/templates.tpl @@ -3,6 +3,12 @@
+{if defined('TEMPLATES_DEBUG')} + + + + +{/if} {if $inactive_templates} {/if} diff --git a/templates.php b/templates.php index 6bf6ae393..0b1f312fb 100644 --- a/templates.php +++ b/templates.php @@ -41,7 +41,17 @@ } // End of access checks. +$config = $user->getConfigHelper(); + +if ($request->isPost()) { + $cl_bind_templates_with_projects = $request->getParameter('bind_templates_with_projects'); +} else { + $cl_bind_templates_with_projects = $config->getDefinedValue('bind_templates_with_projects'); +} + + $form = new Form('templatesForm'); +$form->addInput(array('type'=>'checkbox','name'=>'bind_templates_with_projects','value'=>$cl_bind_templates_with_projects)); if ($request->isPost()) { if ($request->getParameter('btn_add')) { From 70a998d4a2a235a44e64dda3d96b0cda71e5df1c Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 2 Jul 2020 20:51:50 +0000 Subject: [PATCH 205/877] Some more work in progress on binding templates with projects. --- WEB-INF/lib/ttUser.class.php | 3 ++- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/templates.tpl | 3 +++ template_edit.php | 18 ++++++++++++------ templates.php | 17 ++++++++++++----- time.php | 2 +- 6 files changed, 31 insertions(+), 14 deletions(-) diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index 42f9b0d90..4ef5d26e0 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -356,11 +356,12 @@ function getAssignedProjects($options = null) " where p.group_id = $group_id and p.org_id = $org_id and p.status = 1 order by p.name"; $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { + $bindTemplatesWithProjects = $options['include_templates']; while ($val = $res->fetchRow()) { // If we have to include templates, get them in a separate query for each project. // Although, theoretically, we could use mysql group_concat, but this requires grouping by, which makes // maintenance of this code more complex. - if ($options['include_templates']) { + if ($bindTemplatesWithProjects) { $val['templates'] = ttTemplateHelper::getAssignedTemplates($val['id']); } $result[] = $val; diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index fdcbd866b..9580c3c07 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
{$forms.templatesForm.bind_templates_with_projects.control} {$i18n.label.what_is_it}
{$i18n.form.templates.active_templates}
- + + + {/if} {if $inactive_templates} diff --git a/template_edit.php b/template_edit.php index 1bff1a3bf..da8485047 100644 --- a/template_edit.php +++ b/template_edit.php @@ -47,22 +47,28 @@ } // End of access checks. -$projects = ttGroupHelper::getActiveProjects(); +$config = $user->getConfigHelper(); +$bindTemplatesWithProjects = $config->getDefinedValue('bind_templates_with_projects'); +if ($bindTemplatesWithProjects) + $projects = ttGroupHelper::getActiveProjects(); if ($request->isPost()) { $cl_name = trim($request->getParameter('name')); $cl_description = trim($request->getParameter('description')); $cl_content = trim($request->getParameter('content')); $cl_status = $request->getParameter('status'); - $cl_projects = $request->getParameter('projects'); + if ($bindTemplatesWithProjects) + $cl_projects = $request->getParameter('projects'); } else { $cl_name = $template['name']; $cl_description = $template['description']; $cl_content = $template['content']; $cl_status = $template['status']; - $assigned_projects = ttTemplateHelper::getAssignedProjects($cl_template_id); - foreach ($assigned_projects as $project_item) - $cl_projects[] = $project_item['id']; + if ($bindTemplatesWithProjects) { + $assigned_projects = ttTemplateHelper::getAssignedProjects($cl_template_id); + foreach ($assigned_projects as $project_item) + $cl_projects[] = $project_item['id']; + } } $form = new Form('templateForm'); @@ -98,7 +104,7 @@ } // isPost $smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('show_projects', count($projects) > 0 && defined('TEMPLATES_DEBUG')); +$smarty->assign('show_projects', $bindTemplatesWithProjects && count($projects) > 0 && defined('TEMPLATES_DEBUG')); $smarty->assign('title', $i18n->get('title.edit_template')); $smarty->assign('content_page_name', 'template_edit.tpl'); $smarty->display('index.tpl'); diff --git a/templates.php b/templates.php index 0b1f312fb..cf315d085 100644 --- a/templates.php +++ b/templates.php @@ -49,20 +49,27 @@ $cl_bind_templates_with_projects = $config->getDefinedValue('bind_templates_with_projects'); } - $form = new Form('templatesForm'); $form->addInput(array('type'=>'checkbox','name'=>'bind_templates_with_projects','value'=>$cl_bind_templates_with_projects)); +$form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); +$form->addInput(array('type'=>'submit','name'=>'btn_add','value'=>$i18n->get('button.add'))); +$activeTemplates = ttGroupHelper::getActiveTemplates(); +$inactiveTemplates = ttGroupHelper::getInactiveTemplates(); if ($request->isPost()) { + if ($request->getParameter('btn_save')) { + // Save button clicked. Update config. + $config->setDefinedValue('bind_templates_with_projects', $cl_bind_templates_with_projects); + if (!$user->updateGroup(array('config' => $config->getConfig()))) { + $err->add($i18n->get('error.db')); + } + } + if ($request->getParameter('btn_add')) { // The Add button clicked. Redirect to template_add.php page. header('Location: template_add.php'); exit(); } -} else { - $form->addInput(array('type'=>'submit','name'=>'btn_add','value'=>$i18n->get('button.add'))); - $activeTemplates = ttGroupHelper::getActiveTemplates(); - $inactiveTemplates = ttGroupHelper::getInactiveTemplates(); } $smarty->assign('forms', array($form->getName()=>$form->toArray())); diff --git a/time.php b/time.php index 3a9e582aa..a48458add 100644 --- a/time.php +++ b/time.php @@ -207,7 +207,7 @@ if ($showProject) { // Dropdown for projects assigned to user. - $options['include_templates'] = $showTemplates; + $options['include_templates'] = $user->isPluginEnabled('tp') && $config->getDefinedValue('bind_templates_with_projects'); $project_list = $user->getAssignedProjects($options); $form->addInput(array('type'=>'combobox', 'onchange'=>'fillTaskDropdown(this.value);', From 9cbb307079829d2c3660fd7900a71b7b1eb9f62e Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 3 Jul 2020 16:28:48 +0000 Subject: [PATCH 206/877] Initial implementation of template binds to projects. --- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/templates.tpl | 19 ++++---- WEB-INF/templates/time_script.tpl | 75 ++++++++++++++++++++++++++++--- mobile/time.php | 16 ++++--- mobile/time_edit.php | 16 ++++--- template_add.php | 3 +- template_edit.php | 2 +- time.php | 13 +++--- time_edit.php | 16 ++++--- 9 files changed, 119 insertions(+), 43 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 9580c3c07..930618e50 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.19.17.5197 | Copyright © Anuko | +  Anuko Time Tracker 1.19.17.5199 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/templates.tpl b/WEB-INF/templates/templates.tpl index 80991537e..3a7da2b7e 100644 --- a/WEB-INF/templates/templates.tpl +++ b/WEB-INF/templates/templates.tpl @@ -8,6 +8,9 @@ {$forms.templatesForm.bind_templates_with_projects.control} {$i18n.label.what_is_it}
{$forms.templatesForm.btn_save.control}
{$i18n.form.templates.active_templates}
-
 Anuko Time Tracker 1.19.17.5199 | Copyright © Anuko | +  Anuko Time Tracker 1.19.17.5200 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/templates.tpl b/WEB-INF/templates/templates.tpl index 3a7da2b7e..d4532873d 100644 --- a/WEB-INF/templates/templates.tpl +++ b/WEB-INF/templates/templates.tpl @@ -3,15 +3,6 @@
-{if defined('TEMPLATES_DEBUG')} - - - - - - - -{/if} {if $inactive_templates} {/if} @@ -55,6 +46,16 @@
{$forms.templatesForm.bind_templates_with_projects.control} {$i18n.label.what_is_it}
{$forms.templatesForm.btn_save.control}
{$i18n.form.templates.active_templates}

{$forms.templatesForm.btn_add.control}
{/if} +
+ + + + + + + + +
{$forms.templatesForm.bind_templates_with_projects.control} {$i18n.label.what_is_it}
{$forms.templatesForm.btn_save.control}
diff --git a/WEB-INF/templates/time_script.tpl b/WEB-INF/templates/time_script.tpl index 529acfe5a..495a16aee 100644 --- a/WEB-INF/templates/time_script.tpl +++ b/WEB-INF/templates/time_script.tpl @@ -44,32 +44,47 @@ var task_names = new Array(); task_names[{$task.id}] = "{$task.name|escape:'javascript'}"; {/foreach} -{if $template_dropdown} -var templates = new Array(); -{foreach $templates as $template} - templates[{$template.id}] = "{$template.content|escape:'javascript'}"; +// Prepare an array of template ids for projects. +var template_ids = new Array(); +{if $bind_templates_with_projects} + {foreach $project_list as $project} + template_ids[{$project.id}] = "{$project.templates}"; + {/foreach} +{/if} +// Prepare an array of template names. +var template_names = new Array(); +{if $bind_templates_with_projects} + {foreach $template_list as $template} + template_names[{$template.id}] = "{$template.name|escape:'javascript'}"; + {/foreach} +{/if} +// Prepare an array of template bodies. +var template_bodies = new Array(); +{foreach $template_list as $template} + template_bodies[{$template.id}] = "{$template.content|escape:'javascript'}"; {/foreach} // The fillNote function populates the Note field with a selected template body. function fillNote(id) { if (!id) return; // Do nothing. - var template_body = templates[id]; + var template_body = template_bodies[id]; var note = document.getElementById("note"); note.value = template_body; } -{/if} // Mandatory top options for project and task dropdowns. var empty_label_project = "{$i18n.dropdown.select|escape:'javascript'}"; var empty_label_task = "{$i18n.dropdown.select|escape:'javascript'}"; +var empty_label_template = "{$i18n.dropdown.select|escape:'javascript'}"; -// The fillDropdowns function populates the "project" and "task" dropdown controls +// The fillDropdowns function populates the "project", "task", and "template" dropdown controls // with relevant values. function fillDropdowns() { if(document.body.contains(document.timeRecordForm.client)) fillProjectDropdown(document.timeRecordForm.client.value); fillTaskDropdown(document.timeRecordForm.project.value); + fillTemplateDropdown(document.timeRecordForm.project.value); } // The fillProjectDropdown function populates the project combo box with @@ -167,6 +182,52 @@ function fillTaskDropdown(id) { } } +// The fillTemplateDropdown function populates the template combo box with +// templates associated with a selected project (project id is passed here as id). +function fillTemplateDropdown(id) { +{if !$bind_templates_with_projects} + return; // Do nothing if we are not binding templates with projects, +{/if} + + var str_ids = template_ids[id]; + + var dropdown = document.getElementById("template"); + if (dropdown == null) return; // Nothing to do. + + // Determine previously selected item. + var selected_item = dropdown.options[dropdown.selectedIndex].value; + + // Remove existing content. + dropdown.length = 0; + // Add mandatory top option. + dropdown.options[0] = new Option(empty_label_template, '', true); + + // Populate the dropdown from the template_names array. + if (str_ids) { + var ids = new Array(); + ids = str_ids.split(","); + var len = ids.length; + + var idx = 1; + for (var i = 0; i < len; i++) { + var t_id = ids[i]; + if (template_names[t_id]) { + dropdown.options[idx] = new Option(template_names[t_id], t_id); + idx++; + } + } + + // If a previously selected item is still in dropdown - select it. + if (dropdown.options.length > 0) { + for (var i = 0; i < dropdown.options.length; i++) { + if (dropdown.options[i].value == selected_item) { + dropdown.options[i].selected = true; + } + } + } + } +} + // The formDisable function disables some fields depending on what we have in other fields. function formDisable(formField) { var formFieldValue = eval("document.timeRecordForm." + formField + ".value"); diff --git a/mobile/time.php b/mobile/time.php index c5fb0ea75..b37a0a959 100644 --- a/mobile/time.php +++ b/mobile/time.php @@ -31,6 +31,7 @@ import('ttUserHelper'); import('ttGroupHelper'); import('ttClientHelper'); +import('ttConfigHelper'); import('ttTimeHelper'); import('DateAndTime'); @@ -65,6 +66,7 @@ } $group_id = $user->getGroup(); +$config = new ttConfigHelper($user->getConfig()); // Initialize and store date in session. $cl_date = $request->getParameter('date', @$_SESSION['date']); @@ -161,9 +163,10 @@ if (MODE_PROJECTS == $user->getTrackingMode() || MODE_PROJECTS_AND_TASKS == $user->getTrackingMode()) { // Dropdown for projects assigned to user. - $project_list = $user->getAssignedProjects(); + $options['include_templates'] = $user->isPluginEnabled('tp') && $config->getDefinedValue('bind_templates_with_projects'); + $project_list = $user->getAssignedProjects($options); $form->addInput(array('type'=>'combobox', - 'onchange'=>'fillTaskDropdown(this.value);', + 'onchange'=>'fillTaskDropdown(this.value);fillTemplateDropdown(this.value);', 'name'=>'project', 'style'=>'width: 250px;', 'value'=>$cl_project, @@ -245,17 +248,18 @@ // If we have templates, add a dropdown to select one. if ($user->isPluginEnabled('tp')){ - $templates = ttGroupHelper::getActiveTemplates(); - if (count($templates) >= 1) { + $template_list = ttGroupHelper::getActiveTemplates(); + if (count($template_list) >= 1) { $form->addInput(array('type'=>'combobox', 'onchange'=>'fillNote(this.value);', 'name'=>'template', 'style'=>'width: 250px;', - 'data'=>$templates, + 'data'=>$template_list, 'datakeys'=>array('id','name'), 'empty'=>array(''=>$i18n->get('dropdown.select')))); $smarty->assign('template_dropdown', 1); - $smarty->assign('templates', $templates); + $smarty->assign('bind_templates_with_projects', $config->getDefinedValue('bind_templates_with_projects')); + $smarty->assign('template_list', $template_list); } } diff --git a/mobile/time_edit.php b/mobile/time_edit.php index bce156661..18acb98b4 100644 --- a/mobile/time_edit.php +++ b/mobile/time_edit.php @@ -32,6 +32,7 @@ import('ttGroupHelper'); import('ttClientHelper'); import('ttTimeHelper'); +import('ttConfigHelper'); import('DateAndTime'); // Access checks. @@ -49,6 +50,7 @@ // End of access checks. $user_id = $user->getUser(); +$config = new ttConfigHelper($user->getConfig()); // Use custom fields plugin if it is enabled. if ($user->isPluginEnabled('cf')) { @@ -138,9 +140,10 @@ if (MODE_PROJECTS == $user->tracking_mode || MODE_PROJECTS_AND_TASKS == $user->tracking_mode) { // Dropdown for projects assigned to user. - $project_list = $user->getAssignedProjects(); + $options['include_templates'] = $user->isPluginEnabled('tp') && $config->getDefinedValue('bind_templates_with_projects'); + $project_list = $user->getAssignedProjects($options); $form->addInput(array('type'=>'combobox', - 'onchange'=>'fillTaskDropdown(this.value);', + 'onchange'=>'fillTaskDropdown(this.value);fillTemplateDropdown(this.value);', 'name'=>'project', 'style'=>'width: 250px;', 'value'=>$cl_project, @@ -221,17 +224,18 @@ // If we have templates, add a dropdown to select one. if ($user->isPluginEnabled('tp')){ - $templates = ttGroupHelper::getActiveTemplates(); - if (count($templates) >= 1) { + $template_list = ttGroupHelper::getActiveTemplates(); + if (count($template_list) >= 1) { $form->addInput(array('type'=>'combobox', 'onchange'=>'fillNote(this.value);', 'name'=>'template', 'style'=>'width: 250px;', - 'data'=>$templates, + 'data'=>$template_list, 'datakeys'=>array('id','name'), 'empty'=>array(''=>$i18n->get('dropdown.select')))); $smarty->assign('template_dropdown', 1); - $smarty->assign('templates', $templates); + $smarty->assign('bind_templates_with_projects', $config->getDefinedValue('bind_templates_with_projects')); + $smarty->assign('template_list', $template_list); } } diff --git a/template_add.php b/template_add.php index e7e828444..98dd41430 100644 --- a/template_add.php +++ b/template_add.php @@ -41,6 +41,7 @@ } // End of access checks. +$config = new ttConfigHelper($user->getConfig()); $projects = ttGroupHelper::getActiveProjects(); if ($request->isPost()) { @@ -81,7 +82,7 @@ } // isPost $smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('show_projects', count($projects) > 0 && defined('TEMPLATES_DEBUG')); +$smarty->assign('show_projects', count($projects) > 0 && $config->getDefinedValue('bind_templates_with_projects')); $smarty->assign('title', $i18n->get('title.add_template')); $smarty->assign('content_page_name', 'template_add.tpl'); $smarty->display('index.tpl'); diff --git a/template_edit.php b/template_edit.php index da8485047..7619e7378 100644 --- a/template_edit.php +++ b/template_edit.php @@ -104,7 +104,7 @@ } // isPost $smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('show_projects', $bindTemplatesWithProjects && count($projects) > 0 && defined('TEMPLATES_DEBUG')); +$smarty->assign('show_projects', $bindTemplatesWithProjects && count($projects) > 0 && $bindTemplatesWithProjects); $smarty->assign('title', $i18n->get('title.edit_template')); $smarty->assign('content_page_name', 'template_edit.tpl'); $smarty->display('index.tpl'); diff --git a/time.php b/time.php index a48458add..823cd8287 100644 --- a/time.php +++ b/time.php @@ -67,6 +67,7 @@ } $group_id = $user->getGroup(); +$config = new ttConfigHelper($user->getConfig()); $showClient = $user->isPluginEnabled('cl'); $showBillable = $user->isPluginEnabled('iv'); @@ -95,7 +96,6 @@ $smarty->assign('custom_fields', $custom_fields); } -$config = new ttConfigHelper($user->getConfig()); $showNoteColumn = !$config->getDefinedValue('time_note_on_separate_row'); $showNoteRow = $config->getDefinedValue('time_note_on_separate_row'); if ($showNoteRow) { @@ -210,7 +210,7 @@ $options['include_templates'] = $user->isPluginEnabled('tp') && $config->getDefinedValue('bind_templates_with_projects'); $project_list = $user->getAssignedProjects($options); $form->addInput(array('type'=>'combobox', - 'onchange'=>'fillTaskDropdown(this.value);', + 'onchange'=>'fillTaskDropdown(this.value);fillTemplateDropdown(this.value);', 'name'=>'project', 'style'=>'width: 250px;', 'value'=>$cl_project, @@ -304,17 +304,18 @@ // If we have templates, add a dropdown to select one. if ($user->isPluginEnabled('tp')){ - $templates = ttGroupHelper::getActiveTemplates(); - if (count($templates) >= 1) { + $template_list = ttGroupHelper::getActiveTemplates(); + if (count($template_list) >= 1) { $form->addInput(array('type'=>'combobox', 'onchange'=>'fillNote(this.value);', 'name'=>'template', 'style'=>'width: 250px;', - 'data'=>$templates, + 'data'=>$template_list, 'datakeys'=>array('id','name'), 'empty'=>array(''=>$i18n->get('dropdown.select')))); $smarty->assign('template_dropdown', 1); - $smarty->assign('templates', $templates); + $smarty->assign('bind_templates_with_projects', $config->getDefinedValue('bind_templates_with_projects')); + $smarty->assign('template_list', $template_list); } } diff --git a/time_edit.php b/time_edit.php index f6ee7de1e..8734d2ab8 100644 --- a/time_edit.php +++ b/time_edit.php @@ -32,6 +32,7 @@ import('ttGroupHelper'); import('ttClientHelper'); import('ttTimeHelper'); +import('ttConfigHelper'); import('DateAndTime'); // Access checks. @@ -49,6 +50,7 @@ // End of access checks. $user_id = $user->getUser(); +$config = new ttConfigHelper($user->getConfig()); // Use custom fields plugin if it is enabled. if ($user->isPluginEnabled('cf')) { @@ -141,9 +143,10 @@ if (MODE_PROJECTS == $user->tracking_mode || MODE_PROJECTS_AND_TASKS == $user->tracking_mode) { // Dropdown for projects assigned to user. - $project_list = $user->getAssignedProjects(); + $options['include_templates'] = $user->isPluginEnabled('tp') && $config->getDefinedValue('bind_templates_with_projects'); + $project_list = $user->getAssignedProjects($options); $form->addInput(array('type'=>'combobox', - 'onchange'=>'fillTaskDropdown(this.value);', + 'onchange'=>'fillTaskDropdown(this.value);fillTemplateDropdown(this.value);', 'name'=>'project', 'style'=>'width: 250px;', 'value'=>$cl_project, @@ -224,17 +227,18 @@ // If we have templates, add a dropdown to select one. if ($user->isPluginEnabled('tp')){ - $templates = ttGroupHelper::getActiveTemplates(); - if (count($templates) >= 1) { + $template_list = ttGroupHelper::getActiveTemplates(); + if (count($template_list) >= 1) { $form->addInput(array('type'=>'combobox', 'onchange'=>'fillNote(this.value);', 'name'=>'template', 'style'=>'width: 250px;', - 'data'=>$templates, + 'data'=>$template_list, 'datakeys'=>array('id','name'), 'empty'=>array(''=>$i18n->get('dropdown.select')))); $smarty->assign('template_dropdown', 1); - $smarty->assign('templates', $templates); + $smarty->assign('bind_templates_with_projects', $config->getDefinedValue('bind_templates_with_projects')); + $smarty->assign('template_list', $template_list); } } From 3deb102003dcfb43b1594d713fd942eb782c6ca6 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 4 Jul 2020 13:05:25 +0000 Subject: [PATCH 207/877] Introduced label.prepopulate_empty_note string in translation files. --- WEB-INF/resources/ca.lang.php | 1 + WEB-INF/resources/cs.lang.php | 1 + WEB-INF/resources/da.lang.php | 1 + WEB-INF/resources/de.lang.php | 1 + WEB-INF/resources/en.lang.php | 1 + WEB-INF/resources/es.lang.php | 1 + WEB-INF/resources/et.lang.php | 1 + WEB-INF/resources/fa.lang.php | 1 + WEB-INF/resources/fi.lang.php | 1 + WEB-INF/resources/fr.lang.php | 1 + WEB-INF/resources/gr.lang.php | 1 + WEB-INF/resources/he.lang.php | 1 + WEB-INF/resources/hu.lang.php | 1 + WEB-INF/resources/it.lang.php | 1 + WEB-INF/resources/ja.lang.php | 1 + WEB-INF/resources/ko.lang.php | 1 + WEB-INF/resources/nl.lang.php | 1 + WEB-INF/resources/no.lang.php | 1 + WEB-INF/resources/pl.lang.php | 1 + WEB-INF/resources/pt-br.lang.php | 1 + WEB-INF/resources/pt.lang.php | 1 + WEB-INF/resources/ro.lang.php | 1 + WEB-INF/resources/ru.lang.php | 3 ++- WEB-INF/resources/sk.lang.php | 1 + WEB-INF/resources/sl.lang.php | 1 + WEB-INF/resources/sr.lang.php | 1 + WEB-INF/resources/sv.lang.php | 1 + WEB-INF/resources/tr.lang.php | 1 + WEB-INF/resources/zh-cn.lang.php | 1 + WEB-INF/resources/zh-tw.lang.php | 1 + WEB-INF/templates/footer.tpl | 2 +- 31 files changed, 32 insertions(+), 2 deletions(-) diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index 658a19318..63bc3123f 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -277,6 +277,7 @@ // 'label.mark_approved' => 'Mark approved', // 'label.template' => 'Template', // 'label.bind_templates_with_projects' => 'Bind templates with projects', +// 'label.prepopulate_empty_note' => 'Prepopulate empty Note field', // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index 4ec5d0093..d79763485 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -287,6 +287,7 @@ // 'label.mark_approved' => 'Mark approved', // 'label.template' => 'Template', // 'label.bind_templates_with_projects' => 'Bind templates with projects', +// 'label.prepopulate_empty_note' => 'Prepopulate empty Note field', // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index 3905d8950..53e73200c 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -267,6 +267,7 @@ // 'label.mark_approved' => 'Mark approved', // 'label.template' => 'Template', // 'label.bind_templates_with_projects' => 'Bind templates with projects', +// 'label.prepopulate_empty_note' => 'Prepopulate empty Note field', // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index b0e8c4af5..b7e3b2efd 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -257,6 +257,7 @@ // 'label.mark_approved' => 'Mark approved', // 'label.template' => 'Template', // 'label.bind_templates_with_projects' => 'Bind templates with projects', +// 'label.prepopulate_empty_note' => 'Prepopulate empty Note field', // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index b52195d6b..b7f3a21f2 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -251,6 +251,7 @@ 'label.mark_approved' => 'Mark approved', 'label.template' => 'Template', 'label.bind_templates_with_projects' => 'Bind templates with projects', +'label.prepopulate_empty_note' => 'Prepopulate empty Note field', 'label.attachments' => 'Attachments', 'label.files' => 'Files', 'label.file' => 'File', diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index 30fb2803d..9867273e3 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -280,6 +280,7 @@ // 'label.mark_approved' => 'Mark approved', // 'label.template' => 'Template', // 'label.bind_templates_with_projects' => 'Bind templates with projects', +// 'label.prepopulate_empty_note' => 'Prepopulate empty Note field', // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index 1539d26e3..573689a57 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -274,6 +274,7 @@ // 'label.mark_approved' => 'Mark approved', // 'label.template' => 'Template', // 'label.bind_templates_with_projects' => 'Bind templates with projects', +// 'label.prepopulate_empty_note' => 'Prepopulate empty Note field', // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index eb5f095e5..de9fefe1d 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -278,6 +278,7 @@ // 'label.mark_approved' => 'Mark approved', // 'label.template' => 'Template', // 'label.bind_templates_with_projects' => 'Bind templates with projects', +// 'label.prepopulate_empty_note' => 'Prepopulate empty Note field', // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 1b0f0bc9a..3f45c2752 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -271,6 +271,7 @@ // 'label.mark_approved' => 'Mark approved', // 'label.template' => 'Template', // 'label.bind_templates_with_projects' => 'Bind templates with projects', +// 'label.prepopulate_empty_note' => 'Prepopulate empty Note field', // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index e84e6f9fc..769006928 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -265,6 +265,7 @@ // 'label.mark_approved' => 'Mark approved', // 'label.template' => 'Template', // 'label.bind_templates_with_projects' => 'Bind templates with projects', +// 'label.prepopulate_empty_note' => 'Prepopulate empty Note field', // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index 46a18d53e..661a31697 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -261,6 +261,7 @@ // 'label.mark_approved' => 'Mark approved', // 'label.template' => 'Template', // 'label.bind_templates_with_projects' => 'Bind templates with projects', +// 'label.prepopulate_empty_note' => 'Prepopulate empty Note field', // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index c1697904a..8e72b7c93 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -286,6 +286,7 @@ // 'label.mark_approved' => 'Mark approved', // 'label.template' => 'Template', // 'label.bind_templates_with_projects' => 'Bind templates with projects', +// 'label.prepopulate_empty_note' => 'Prepopulate empty Note field', // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index b136dc1fd..03d54e4f2 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -283,6 +283,7 @@ // 'label.mark_approved' => 'Mark approved', // 'label.template' => 'Template', // 'label.bind_templates_with_projects' => 'Bind templates with projects', +// 'label.prepopulate_empty_note' => 'Prepopulate empty Note field', // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index 0805dcbe3..d9c6023e9 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -265,6 +265,7 @@ // 'label.mark_approved' => 'Mark approved', // 'label.template' => 'Template', // 'label.bind_templates_with_projects' => 'Bind templates with projects', +// 'label.prepopulate_empty_note' => 'Prepopulate empty Note field', // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index 5826460b8..afc001282 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -287,6 +287,7 @@ // 'label.mark_approved' => 'Mark approved', // 'label.template' => 'Template', // 'label.bind_templates_with_projects' => 'Bind templates with projects', +// 'label.prepopulate_empty_note' => 'Prepopulate empty Note field', // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index 0b2b51b1d..23ba28957 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -287,6 +287,7 @@ // 'label.mark_approved' => 'Mark approved', // 'label.template' => 'Template', // 'label.bind_templates_with_projects' => 'Bind templates with projects', +// 'label.prepopulate_empty_note' => 'Prepopulate empty Note field', // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 29826bcd2..5c9516b2e 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -257,6 +257,7 @@ 'label.template' => 'Sjabloon', // TODO: translate the following. // 'label.bind_templates_with_projects' => 'Bind templates with projects', +// 'label.prepopulate_empty_note' => 'Prepopulate empty Note field', 'label.attachments' => 'Bijlagen', 'label.files' => 'Bestanden', 'label.file' => 'Bestand', diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index c1696fc11..6059ed09c 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -284,6 +284,7 @@ // 'label.mark_approved' => 'Mark approved', // 'label.template' => 'Template', // 'label.bind_templates_with_projects' => 'Bind templates with projects', +// 'label.prepopulate_empty_note' => 'Prepopulate empty Note field', // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index 046fa922c..6c7adf0f6 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -272,6 +272,7 @@ // 'label.mark_approved' => 'Mark approved', // 'label.template' => 'Template', // 'label.bind_templates_with_projects' => 'Bind templates with projects', +// 'label.prepopulate_empty_note' => 'Prepopulate empty Note field', // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index 5e97cf7ac..daf8fc1d3 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -269,6 +269,7 @@ // 'label.mark_approved' => 'Mark approved', // 'label.template' => 'Template', // 'label.bind_templates_with_projects' => 'Bind templates with projects', +// 'label.prepopulate_empty_note' => 'Prepopulate empty Note field', // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index 01751f8e5..204a72e31 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -272,6 +272,7 @@ // 'label.mark_approved' => 'Mark approved', // 'label.template' => 'Template', // 'label.bind_templates_with_projects' => 'Bind templates with projects', +// 'label.prepopulate_empty_note' => 'Prepopulate empty Note field', // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index 9756a1cea..01a0f37f4 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -284,6 +284,7 @@ // 'label.mark_approved' => 'Mark approved', // 'label.template' => 'Template', // 'label.bind_templates_with_projects' => 'Bind templates with projects', +// 'label.prepopulate_empty_note' => 'Prepopulate empty Note field', // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index 48795ca22..f40becac9 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -241,7 +241,8 @@ 'label.approval' => 'Одобрение отчётов', 'label.mark_approved' => 'Отметить одобрение', 'label.template' => 'Шаблон', -'label.bind_templates_with_projects' => 'Связать шаблоны с проектамиЫ', +'label.bind_templates_with_projects' => 'Связать шаблоны с проектами', +'label.prepopulate_empty_note' => 'Подставлять шаблон в пустое поле', 'label.attachments' => 'Приложения', 'label.files' => 'Файлы', 'label.file' => 'Файл', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index 159b6ce45..313fcfd2d 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -276,6 +276,7 @@ // 'label.mark_approved' => 'Mark approved', // 'label.template' => 'Template', // 'label.bind_templates_with_projects' => 'Bind templates with projects', +// 'label.prepopulate_empty_note' => 'Prepopulate empty Note field', // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index 6ffa74b57..19cceabca 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -267,6 +267,7 @@ // 'label.mark_approved' => 'Mark approved', // 'label.template' => 'Template', // 'label.bind_templates_with_projects' => 'Bind templates with projects', +// 'label.prepopulate_empty_note' => 'Prepopulate empty Note field', // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index 523277b32..19f6d345e 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -270,6 +270,7 @@ // 'label.mark_approved' => 'Mark approved', // 'label.template' => 'Template', // 'label.bind_templates_with_projects' => 'Bind templates with projects', +// 'label.prepopulate_empty_note' => 'Prepopulate empty Note field', // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index 4112465f2..72113f964 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -267,6 +267,7 @@ // 'label.mark_approved' => 'Mark approved', // 'label.template' => 'Template', // 'label.bind_templates_with_projects' => 'Bind templates with projects', +// 'label.prepopulate_empty_note' => 'Prepopulate empty Note field', // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index ab1d51bae..2d509b658 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -291,6 +291,7 @@ // 'label.mark_approved' => 'Mark approved', // 'label.template' => 'Template', // 'label.bind_templates_with_projects' => 'Bind templates with projects', +// 'label.prepopulate_empty_note' => 'Prepopulate empty Note field', // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index 7b6dbef6d..9dccc6b25 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -276,6 +276,7 @@ // 'label.mark_approved' => 'Mark approved', // 'label.template' => 'Template', // 'label.bind_templates_with_projects' => 'Bind templates with projects', +// 'label.prepopulate_empty_note' => 'Prepopulate empty Note field', // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index 454b000c1..0d0ad29f8 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -282,6 +282,7 @@ // 'label.mark_approved' => 'Mark approved', // 'label.template' => 'Template', // 'label.bind_templates_with_projects' => 'Bind templates with projects', +// 'label.prepopulate_empty_note' => 'Prepopulate empty Note field', // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 930618e50..e3d6cad82 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.19.17.5200 | Copyright © Anuko | +  Anuko Time Tracker 1.19.17.5201 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 0b1455a77e7fd2d543b843edf2f6dcc863699118 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 4 Jul 2020 13:43:56 +0000 Subject: [PATCH 208/877] Introduced a handler for prepopulate_empty_note option. --- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/templates.tpl | 4 ++++ WEB-INF/templates/time_script.tpl | 10 ++++++++++ mobile/time.php | 1 + templates.php | 4 ++++ time.php | 1 + 6 files changed, 21 insertions(+), 1 deletion(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index e3d6cad82..96a499dd4 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- + + + + diff --git a/WEB-INF/templates/time_script.tpl b/WEB-INF/templates/time_script.tpl index 495a16aee..d6c48a833 100644 --- a/WEB-INF/templates/time_script.tpl +++ b/WEB-INF/templates/time_script.tpl @@ -226,6 +226,16 @@ function fillTemplateDropdown(id) { } } } + + // Do things for prepopulate_empty_note. + if ({$prepopulate_empty_note} && dropdown.options.length >= 2) { // 2 because of mandatory top option. + var note = document.getElementById("note"); + if (note.value == "") { + // We have an empty Note field. + dropdown.options[1].selected = true; // Select first template. + note.value = template_bodies[dropdown.options[1].value]; // Pre-polulate note with first template body. + } + } } // The formDisable function disables some fields depending on what we have in other fields. diff --git a/mobile/time.php b/mobile/time.php index b37a0a959..0293574dc 100644 --- a/mobile/time.php +++ b/mobile/time.php @@ -259,6 +259,7 @@ 'empty'=>array(''=>$i18n->get('dropdown.select')))); $smarty->assign('template_dropdown', 1); $smarty->assign('bind_templates_with_projects', $config->getDefinedValue('bind_templates_with_projects')); + $smarty->assign('prepopulate_empty_note', $config->getDefinedValue('prepopulate_empty_note')); $smarty->assign('template_list', $template_list); } } diff --git a/templates.php b/templates.php index cf315d085..1a643e8f3 100644 --- a/templates.php +++ b/templates.php @@ -45,12 +45,15 @@ if ($request->isPost()) { $cl_bind_templates_with_projects = $request->getParameter('bind_templates_with_projects'); + $cl_prepopulate_empty_note = $request->getParameter('prepopulate_empty_note'); } else { $cl_bind_templates_with_projects = $config->getDefinedValue('bind_templates_with_projects'); + $cl_prepopulate_empty_note = $config->getDefinedValue('prepopulate_empty_note'); } $form = new Form('templatesForm'); $form->addInput(array('type'=>'checkbox','name'=>'bind_templates_with_projects','value'=>$cl_bind_templates_with_projects)); +$form->addInput(array('type'=>'checkbox','name'=>'prepopulate_empty_note','value'=>$cl_prepopulate_empty_note)); $form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); $form->addInput(array('type'=>'submit','name'=>'btn_add','value'=>$i18n->get('button.add'))); $activeTemplates = ttGroupHelper::getActiveTemplates(); @@ -60,6 +63,7 @@ if ($request->getParameter('btn_save')) { // Save button clicked. Update config. $config->setDefinedValue('bind_templates_with_projects', $cl_bind_templates_with_projects); + $config->setDefinedValue('prepopulate_empty_note', $cl_prepopulate_empty_note); if (!$user->updateGroup(array('config' => $config->getConfig()))) { $err->add($i18n->get('error.db')); } diff --git a/time.php b/time.php index 823cd8287..44d895a5b 100644 --- a/time.php +++ b/time.php @@ -315,6 +315,7 @@ 'empty'=>array(''=>$i18n->get('dropdown.select')))); $smarty->assign('template_dropdown', 1); $smarty->assign('bind_templates_with_projects', $config->getDefinedValue('bind_templates_with_projects')); + $smarty->assign('prepopulate_empty_note', $config->getDefinedValue('prepopulate_empty_note')); $smarty->assign('template_list', $template_list); } } From da251bb9b537cdf266ba905493c96d8a20690d5b Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 5 Jul 2020 15:03:23 +0000 Subject: [PATCH 209/877] Changed prepopulate_empty_note to prepopulate_note logic. --- WEB-INF/resources/ca.lang.php | 2 +- WEB-INF/resources/cs.lang.php | 2 +- WEB-INF/resources/da.lang.php | 2 +- WEB-INF/resources/de.lang.php | 2 +- WEB-INF/resources/en.lang.php | 2 +- WEB-INF/resources/es.lang.php | 2 +- WEB-INF/resources/et.lang.php | 2 +- WEB-INF/resources/fa.lang.php | 2 +- WEB-INF/resources/fi.lang.php | 2 +- WEB-INF/resources/fr.lang.php | 2 +- WEB-INF/resources/gr.lang.php | 2 +- WEB-INF/resources/he.lang.php | 2 +- WEB-INF/resources/hu.lang.php | 2 +- WEB-INF/resources/it.lang.php | 2 +- WEB-INF/resources/ja.lang.php | 2 +- WEB-INF/resources/ko.lang.php | 2 +- WEB-INF/resources/nl.lang.php | 2 +- WEB-INF/resources/no.lang.php | 2 +- WEB-INF/resources/pl.lang.php | 2 +- WEB-INF/resources/pt-br.lang.php | 2 +- WEB-INF/resources/pt.lang.php | 2 +- WEB-INF/resources/ro.lang.php | 2 +- WEB-INF/resources/ru.lang.php | 2 +- WEB-INF/resources/sk.lang.php | 2 +- WEB-INF/resources/sl.lang.php | 2 +- WEB-INF/resources/sr.lang.php | 2 +- WEB-INF/resources/sv.lang.php | 2 +- WEB-INF/resources/tr.lang.php | 2 +- WEB-INF/resources/zh-cn.lang.php | 2 +- WEB-INF/resources/zh-tw.lang.php | 2 +- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/templates.tpl | 4 ++-- WEB-INF/templates/time_script.tpl | 11 ++++------- mobile/time.php | 2 +- mobile/time_edit.php | 1 + templates.php | 8 ++++---- time.php | 2 +- time_edit.php | 1 + 38 files changed, 45 insertions(+), 46 deletions(-) diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index 63bc3123f..9893ad523 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -277,7 +277,7 @@ // 'label.mark_approved' => 'Mark approved', // 'label.template' => 'Template', // 'label.bind_templates_with_projects' => 'Bind templates with projects', -// 'label.prepopulate_empty_note' => 'Prepopulate empty Note field', +// 'label.prepopulate_note' => 'Prepopulate Note field', // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index d79763485..59756d1b5 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -287,7 +287,7 @@ // 'label.mark_approved' => 'Mark approved', // 'label.template' => 'Template', // 'label.bind_templates_with_projects' => 'Bind templates with projects', -// 'label.prepopulate_empty_note' => 'Prepopulate empty Note field', +// 'label.prepopulate_note' => 'Prepopulate Note field', // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index 53e73200c..a8a14b53d 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -267,7 +267,7 @@ // 'label.mark_approved' => 'Mark approved', // 'label.template' => 'Template', // 'label.bind_templates_with_projects' => 'Bind templates with projects', -// 'label.prepopulate_empty_note' => 'Prepopulate empty Note field', +// 'label.prepopulate_note' => 'Prepopulate Note field', // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index b7e3b2efd..a8f1d165a 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -257,7 +257,7 @@ // 'label.mark_approved' => 'Mark approved', // 'label.template' => 'Template', // 'label.bind_templates_with_projects' => 'Bind templates with projects', -// 'label.prepopulate_empty_note' => 'Prepopulate empty Note field', +// 'label.prepopulate_note' => 'Prepopulate Note field', // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index b7f3a21f2..2beefaa1c 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -251,7 +251,7 @@ 'label.mark_approved' => 'Mark approved', 'label.template' => 'Template', 'label.bind_templates_with_projects' => 'Bind templates with projects', -'label.prepopulate_empty_note' => 'Prepopulate empty Note field', +'label.prepopulate_note' => 'Prepopulate Note field', 'label.attachments' => 'Attachments', 'label.files' => 'Files', 'label.file' => 'File', diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index 9867273e3..1cf3ce768 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -280,7 +280,7 @@ // 'label.mark_approved' => 'Mark approved', // 'label.template' => 'Template', // 'label.bind_templates_with_projects' => 'Bind templates with projects', -// 'label.prepopulate_empty_note' => 'Prepopulate empty Note field', +// 'label.prepopulate_note' => 'Prepopulate Note field', // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index 573689a57..5e2e78caa 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -274,7 +274,7 @@ // 'label.mark_approved' => 'Mark approved', // 'label.template' => 'Template', // 'label.bind_templates_with_projects' => 'Bind templates with projects', -// 'label.prepopulate_empty_note' => 'Prepopulate empty Note field', +// 'label.prepopulate_note' => 'Prepopulate Note field', // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index de9fefe1d..e078a0a34 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -278,7 +278,7 @@ // 'label.mark_approved' => 'Mark approved', // 'label.template' => 'Template', // 'label.bind_templates_with_projects' => 'Bind templates with projects', -// 'label.prepopulate_empty_note' => 'Prepopulate empty Note field', +// 'label.prepopulate_note' => 'Prepopulate Note field', // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 3f45c2752..575dc04f6 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -271,7 +271,7 @@ // 'label.mark_approved' => 'Mark approved', // 'label.template' => 'Template', // 'label.bind_templates_with_projects' => 'Bind templates with projects', -// 'label.prepopulate_empty_note' => 'Prepopulate empty Note field', +// 'label.prepopulate_note' => 'Prepopulate Note field', // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index 769006928..5fe0f76d7 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -265,7 +265,7 @@ // 'label.mark_approved' => 'Mark approved', // 'label.template' => 'Template', // 'label.bind_templates_with_projects' => 'Bind templates with projects', -// 'label.prepopulate_empty_note' => 'Prepopulate empty Note field', +// 'label.prepopulate_note' => 'Prepopulate Note field', // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index 661a31697..5d0dd6bde 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -261,7 +261,7 @@ // 'label.mark_approved' => 'Mark approved', // 'label.template' => 'Template', // 'label.bind_templates_with_projects' => 'Bind templates with projects', -// 'label.prepopulate_empty_note' => 'Prepopulate empty Note field', +// 'label.prepopulate_note' => 'Prepopulate Note field', // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index 8e72b7c93..199e26533 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -286,7 +286,7 @@ // 'label.mark_approved' => 'Mark approved', // 'label.template' => 'Template', // 'label.bind_templates_with_projects' => 'Bind templates with projects', -// 'label.prepopulate_empty_note' => 'Prepopulate empty Note field', +// 'label.prepopulate_note' => 'Prepopulate Note field', // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index 03d54e4f2..a4a4dd005 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -283,7 +283,7 @@ // 'label.mark_approved' => 'Mark approved', // 'label.template' => 'Template', // 'label.bind_templates_with_projects' => 'Bind templates with projects', -// 'label.prepopulate_empty_note' => 'Prepopulate empty Note field', +// 'label.prepopulate_note' => 'Prepopulate Note field', // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index d9c6023e9..b10575302 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -265,7 +265,7 @@ // 'label.mark_approved' => 'Mark approved', // 'label.template' => 'Template', // 'label.bind_templates_with_projects' => 'Bind templates with projects', -// 'label.prepopulate_empty_note' => 'Prepopulate empty Note field', +// 'label.prepopulate_note' => 'Prepopulate Note field', // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index afc001282..8ebec5955 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -287,7 +287,7 @@ // 'label.mark_approved' => 'Mark approved', // 'label.template' => 'Template', // 'label.bind_templates_with_projects' => 'Bind templates with projects', -// 'label.prepopulate_empty_note' => 'Prepopulate empty Note field', +// 'label.prepopulate_note' => 'Prepopulate Note field', // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index 23ba28957..76c159472 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -287,7 +287,7 @@ // 'label.mark_approved' => 'Mark approved', // 'label.template' => 'Template', // 'label.bind_templates_with_projects' => 'Bind templates with projects', -// 'label.prepopulate_empty_note' => 'Prepopulate empty Note field', +// 'label.prepopulate_note' => 'Prepopulate Note field', // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 5c9516b2e..06f764d4c 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -257,7 +257,7 @@ 'label.template' => 'Sjabloon', // TODO: translate the following. // 'label.bind_templates_with_projects' => 'Bind templates with projects', -// 'label.prepopulate_empty_note' => 'Prepopulate empty Note field', +// 'label.prepopulate_note' => 'Prepopulate Note field', 'label.attachments' => 'Bijlagen', 'label.files' => 'Bestanden', 'label.file' => 'Bestand', diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index 6059ed09c..ad95bd7e3 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -284,7 +284,7 @@ // 'label.mark_approved' => 'Mark approved', // 'label.template' => 'Template', // 'label.bind_templates_with_projects' => 'Bind templates with projects', -// 'label.prepopulate_empty_note' => 'Prepopulate empty Note field', +// 'label.prepopulate_note' => 'Prepopulate Note field', // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index 6c7adf0f6..f988df4a4 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -272,7 +272,7 @@ // 'label.mark_approved' => 'Mark approved', // 'label.template' => 'Template', // 'label.bind_templates_with_projects' => 'Bind templates with projects', -// 'label.prepopulate_empty_note' => 'Prepopulate empty Note field', +// 'label.prepopulate_note' => 'Prepopulate Note field', // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index daf8fc1d3..5c9d89a32 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -269,7 +269,7 @@ // 'label.mark_approved' => 'Mark approved', // 'label.template' => 'Template', // 'label.bind_templates_with_projects' => 'Bind templates with projects', -// 'label.prepopulate_empty_note' => 'Prepopulate empty Note field', +// 'label.prepopulate_note' => 'Prepopulate Note field', // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index 204a72e31..3043e8bba 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -272,7 +272,7 @@ // 'label.mark_approved' => 'Mark approved', // 'label.template' => 'Template', // 'label.bind_templates_with_projects' => 'Bind templates with projects', -// 'label.prepopulate_empty_note' => 'Prepopulate empty Note field', +// 'label.prepopulate_note' => 'Prepopulate Note field', // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index 01a0f37f4..add70a4ea 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -284,7 +284,7 @@ // 'label.mark_approved' => 'Mark approved', // 'label.template' => 'Template', // 'label.bind_templates_with_projects' => 'Bind templates with projects', -// 'label.prepopulate_empty_note' => 'Prepopulate empty Note field', +// 'label.prepopulate_note' => 'Prepopulate Note field', // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index f40becac9..fb050a1a0 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -242,7 +242,7 @@ 'label.mark_approved' => 'Отметить одобрение', 'label.template' => 'Шаблон', 'label.bind_templates_with_projects' => 'Связать шаблоны с проектами', -'label.prepopulate_empty_note' => 'Подставлять шаблон в пустое поле', +'label.prepopulate_note' => 'Подставлять шаблон в поле', 'label.attachments' => 'Приложения', 'label.files' => 'Файлы', 'label.file' => 'Файл', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index 313fcfd2d..cf0b8432b 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -276,7 +276,7 @@ // 'label.mark_approved' => 'Mark approved', // 'label.template' => 'Template', // 'label.bind_templates_with_projects' => 'Bind templates with projects', -// 'label.prepopulate_empty_note' => 'Prepopulate empty Note field', +// 'label.prepopulate_note' => 'Prepopulate Note field', // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index 19cceabca..f4aa21b58 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -267,7 +267,7 @@ // 'label.mark_approved' => 'Mark approved', // 'label.template' => 'Template', // 'label.bind_templates_with_projects' => 'Bind templates with projects', -// 'label.prepopulate_empty_note' => 'Prepopulate empty Note field', +// 'label.prepopulate_note' => 'Prepopulate Note field', // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index 19f6d345e..be5739b6e 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -270,7 +270,7 @@ // 'label.mark_approved' => 'Mark approved', // 'label.template' => 'Template', // 'label.bind_templates_with_projects' => 'Bind templates with projects', -// 'label.prepopulate_empty_note' => 'Prepopulate empty Note field', +// 'label.prepopulate_note' => 'Prepopulate Note field', // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index 72113f964..43b0d92b6 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -267,7 +267,7 @@ // 'label.mark_approved' => 'Mark approved', // 'label.template' => 'Template', // 'label.bind_templates_with_projects' => 'Bind templates with projects', -// 'label.prepopulate_empty_note' => 'Prepopulate empty Note field', +// 'label.prepopulate_note' => 'Prepopulate Note field', // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index 2d509b658..e241cace8 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -291,7 +291,7 @@ // 'label.mark_approved' => 'Mark approved', // 'label.template' => 'Template', // 'label.bind_templates_with_projects' => 'Bind templates with projects', -// 'label.prepopulate_empty_note' => 'Prepopulate empty Note field', +// 'label.prepopulate_note' => 'Prepopulate Note field', // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index 9dccc6b25..b1d81418b 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -276,7 +276,7 @@ // 'label.mark_approved' => 'Mark approved', // 'label.template' => 'Template', // 'label.bind_templates_with_projects' => 'Bind templates with projects', -// 'label.prepopulate_empty_note' => 'Prepopulate empty Note field', +// 'label.prepopulate_note' => 'Prepopulate Note field', // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index 0d0ad29f8..05615586d 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -282,7 +282,7 @@ // 'label.mark_approved' => 'Mark approved', // 'label.template' => 'Template', // 'label.bind_templates_with_projects' => 'Bind templates with projects', -// 'label.prepopulate_empty_note' => 'Prepopulate empty Note field', +// 'label.prepopulate_note' => 'Prepopulate Note field', // 'label.attachments' => 'Attachments', // 'label.files' => 'Files', // 'label.file' => 'File', diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 96a499dd4..6743bb1ee 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.19.17.5201 | Copyright © Anuko | +  Anuko Time Tracker 1.19.18.5202 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/templates.tpl b/WEB-INF/templates/templates.tpl index d4532873d..eb1b2027f 100644 --- a/WEB-INF/templates/templates.tpl +++ b/WEB-INF/templates/templates.tpl @@ -52,6 +52,10 @@ {$forms.templatesForm.bind_templates_with_projects.control} {$i18n.label.what_is_it}
{$forms.templatesForm.prepopulate_empty_note.control} {$i18n.label.what_is_it}
{$forms.templatesForm.btn_save.control}
- - - + + diff --git a/WEB-INF/templates/time_script.tpl b/WEB-INF/templates/time_script.tpl index d6c48a833..14157a932 100644 --- a/WEB-INF/templates/time_script.tpl +++ b/WEB-INF/templates/time_script.tpl @@ -227,14 +227,11 @@ function fillTemplateDropdown(id) { } } - // Do things for prepopulate_empty_note. - if ({$prepopulate_empty_note} && dropdown.options.length >= 2) { // 2 because of mandatory top option. + // Prepopulate note if we have to. + if ({$prepopulate_note} && dropdown.options.length >= 2) { // 2 because of mandatory top option. var note = document.getElementById("note"); - if (note.value == "") { - // We have an empty Note field. - dropdown.options[1].selected = true; // Select first template. - note.value = template_bodies[dropdown.options[1].value]; // Pre-polulate note with first template body. - } + dropdown.options[1].selected = true; // Select first template. + note.value = template_bodies[dropdown.options[1].value]; // Pre-polulate note with first template body. } } diff --git a/mobile/time.php b/mobile/time.php index 0293574dc..427d22aa3 100644 --- a/mobile/time.php +++ b/mobile/time.php @@ -259,7 +259,7 @@ 'empty'=>array(''=>$i18n->get('dropdown.select')))); $smarty->assign('template_dropdown', 1); $smarty->assign('bind_templates_with_projects', $config->getDefinedValue('bind_templates_with_projects')); - $smarty->assign('prepopulate_empty_note', $config->getDefinedValue('prepopulate_empty_note')); + $smarty->assign('prepopulate_note', $config->getDefinedValue('prepopulate_note')); $smarty->assign('template_list', $template_list); } } diff --git a/mobile/time_edit.php b/mobile/time_edit.php index 18acb98b4..f901952cf 100644 --- a/mobile/time_edit.php +++ b/mobile/time_edit.php @@ -235,6 +235,7 @@ 'empty'=>array(''=>$i18n->get('dropdown.select')))); $smarty->assign('template_dropdown', 1); $smarty->assign('bind_templates_with_projects', $config->getDefinedValue('bind_templates_with_projects')); + $smarty->assign('prepopulate_note', $config->getDefinedValue('prepopulate_note')); $smarty->assign('template_list', $template_list); } } diff --git a/templates.php b/templates.php index 1a643e8f3..fec66b599 100644 --- a/templates.php +++ b/templates.php @@ -45,15 +45,15 @@ if ($request->isPost()) { $cl_bind_templates_with_projects = $request->getParameter('bind_templates_with_projects'); - $cl_prepopulate_empty_note = $request->getParameter('prepopulate_empty_note'); + $cl_prepopulate_note = $request->getParameter('prepopulate_note'); } else { $cl_bind_templates_with_projects = $config->getDefinedValue('bind_templates_with_projects'); - $cl_prepopulate_empty_note = $config->getDefinedValue('prepopulate_empty_note'); + $cl_prepopulate_note = $config->getDefinedValue('prepopulate_note'); } $form = new Form('templatesForm'); $form->addInput(array('type'=>'checkbox','name'=>'bind_templates_with_projects','value'=>$cl_bind_templates_with_projects)); -$form->addInput(array('type'=>'checkbox','name'=>'prepopulate_empty_note','value'=>$cl_prepopulate_empty_note)); +$form->addInput(array('type'=>'checkbox','name'=>'prepopulate_note','value'=>$cl_prepopulate_note)); $form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); $form->addInput(array('type'=>'submit','name'=>'btn_add','value'=>$i18n->get('button.add'))); $activeTemplates = ttGroupHelper::getActiveTemplates(); @@ -63,7 +63,7 @@ if ($request->getParameter('btn_save')) { // Save button clicked. Update config. $config->setDefinedValue('bind_templates_with_projects', $cl_bind_templates_with_projects); - $config->setDefinedValue('prepopulate_empty_note', $cl_prepopulate_empty_note); + $config->setDefinedValue('prepopulate_note', $cl_prepopulate_note); if (!$user->updateGroup(array('config' => $config->getConfig()))) { $err->add($i18n->get('error.db')); } diff --git a/time.php b/time.php index 44d895a5b..1a9a07b4c 100644 --- a/time.php +++ b/time.php @@ -315,7 +315,7 @@ 'empty'=>array(''=>$i18n->get('dropdown.select')))); $smarty->assign('template_dropdown', 1); $smarty->assign('bind_templates_with_projects', $config->getDefinedValue('bind_templates_with_projects')); - $smarty->assign('prepopulate_empty_note', $config->getDefinedValue('prepopulate_empty_note')); + $smarty->assign('prepopulate_note', $config->getDefinedValue('prepopulate_note')); $smarty->assign('template_list', $template_list); } } diff --git a/time_edit.php b/time_edit.php index 8734d2ab8..bbf55d086 100644 --- a/time_edit.php +++ b/time_edit.php @@ -238,6 +238,7 @@ 'empty'=>array(''=>$i18n->get('dropdown.select')))); $smarty->assign('template_dropdown', 1); $smarty->assign('bind_templates_with_projects', $config->getDefinedValue('bind_templates_with_projects')); + $smarty->assign('prepopulate_note', $config->getDefinedValue('prepopulate_note')); $smarty->assign('template_list', $template_list); } } From 0d1cbcf045d46d6fac66bed2a141c72620bd7651 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 5 Jul 2020 15:57:14 +0000 Subject: [PATCH 210/877] Implemented prepopulateNote as a separate function. --- WEB-INF/templates/time_script.tpl | 18 ++++++++++++------ mobile/time.php | 2 +- mobile/time_edit.php | 2 +- time.php | 2 +- time_edit.php | 2 +- 5 files changed, 16 insertions(+), 10 deletions(-) diff --git a/WEB-INF/templates/time_script.tpl b/WEB-INF/templates/time_script.tpl index 14157a932..c64131d5e 100644 --- a/WEB-INF/templates/time_script.tpl +++ b/WEB-INF/templates/time_script.tpl @@ -85,6 +85,7 @@ function fillDropdowns() { fillTaskDropdown(document.timeRecordForm.project.value); fillTemplateDropdown(document.timeRecordForm.project.value); + prepopulateNote(); } // The fillProjectDropdown function populates the project combo box with @@ -226,13 +227,18 @@ function fillTemplateDropdown(id) { } } } +} - // Prepopulate note if we have to. - if ({$prepopulate_note} && dropdown.options.length >= 2) { // 2 because of mandatory top option. - var note = document.getElementById("note"); - dropdown.options[1].selected = true; // Select first template. - note.value = template_bodies[dropdown.options[1].value]; // Pre-polulate note with first template body. - } +// The prepopulateNote function populates the note field with first found template body in Template dropdown. +function prepopulateNote() { + var dropdown = document.getElementById("template"); + if (dropdown == null) return; // Nothing to do. + + if (!{$prepopulate_note} || dropdown.options.length <= 1) return ; // 1 because of mandatory top option. + + dropdown.options[1].selected = true; // Select first template. + var note = document.getElementById("note"); + note.value = template_bodies[dropdown.options[1].value]; // Prepolulate note with first template body. } // The formDisable function disables some fields depending on what we have in other fields. diff --git a/mobile/time.php b/mobile/time.php index 427d22aa3..c361fbe0d 100644 --- a/mobile/time.php +++ b/mobile/time.php @@ -166,7 +166,7 @@ $options['include_templates'] = $user->isPluginEnabled('tp') && $config->getDefinedValue('bind_templates_with_projects'); $project_list = $user->getAssignedProjects($options); $form->addInput(array('type'=>'combobox', - 'onchange'=>'fillTaskDropdown(this.value);fillTemplateDropdown(this.value);', + 'onchange'=>'fillTaskDropdown(this.value);fillTemplateDropdown(this.value);prepopulateNote();', 'name'=>'project', 'style'=>'width: 250px;', 'value'=>$cl_project, diff --git a/mobile/time_edit.php b/mobile/time_edit.php index f901952cf..e6e790827 100644 --- a/mobile/time_edit.php +++ b/mobile/time_edit.php @@ -143,7 +143,7 @@ $options['include_templates'] = $user->isPluginEnabled('tp') && $config->getDefinedValue('bind_templates_with_projects'); $project_list = $user->getAssignedProjects($options); $form->addInput(array('type'=>'combobox', - 'onchange'=>'fillTaskDropdown(this.value);fillTemplateDropdown(this.value);', + 'onchange'=>'fillTaskDropdown(this.value);fillTemplateDropdown(this.value);prepopulateNote();', 'name'=>'project', 'style'=>'width: 250px;', 'value'=>$cl_project, diff --git a/time.php b/time.php index 1a9a07b4c..0f30eac7c 100644 --- a/time.php +++ b/time.php @@ -210,7 +210,7 @@ $options['include_templates'] = $user->isPluginEnabled('tp') && $config->getDefinedValue('bind_templates_with_projects'); $project_list = $user->getAssignedProjects($options); $form->addInput(array('type'=>'combobox', - 'onchange'=>'fillTaskDropdown(this.value);fillTemplateDropdown(this.value);', + 'onchange'=>'fillTaskDropdown(this.value);fillTemplateDropdown(this.value);prepopulateNote();', 'name'=>'project', 'style'=>'width: 250px;', 'value'=>$cl_project, diff --git a/time_edit.php b/time_edit.php index bbf55d086..2a0a02357 100644 --- a/time_edit.php +++ b/time_edit.php @@ -146,7 +146,7 @@ $options['include_templates'] = $user->isPluginEnabled('tp') && $config->getDefinedValue('bind_templates_with_projects'); $project_list = $user->getAssignedProjects($options); $form->addInput(array('type'=>'combobox', - 'onchange'=>'fillTaskDropdown(this.value);fillTemplateDropdown(this.value);', + 'onchange'=>'fillTaskDropdown(this.value);fillTemplateDropdown(this.value);prepopulateNote();', 'name'=>'project', 'style'=>'width: 250px;', 'value'=>$cl_project, From c44d8fd50bf6211a266df402fb979a7e5aefcf86 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 6 Jul 2020 01:04:30 +0000 Subject: [PATCH 211/877] Fixed the script for Now buttons to work again. --- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/time_script.tpl | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 6743bb1ee..0571b5a74 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.19.18.5202 | Copyright © Anuko | +  Anuko Time Tracker 1.19.18.5203 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/templates.tpl b/WEB-INF/templates/templates.tpl index eb1b2027f..71b7daebc 100644 --- a/WEB-INF/templates/templates.tpl +++ b/WEB-INF/templates/templates.tpl @@ -53,8 +53,8 @@ {$i18n.label.what_is_it}
{$forms.templatesForm.prepopulate_empty_note.control} {$i18n.label.what_is_it}{$forms.templatesForm.prepopulate_note.control} {$i18n.label.what_is_it}
{$forms.templatesForm.btn_save.control}
-
 Anuko Time Tracker 1.19.18.5203 | Copyright © Anuko | +  Anuko Time Tracker 1.19.18.5204 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/time_script.tpl b/WEB-INF/templates/time_script.tpl index c64131d5e..707121128 100644 --- a/WEB-INF/templates/time_script.tpl +++ b/WEB-INF/templates/time_script.tpl @@ -231,10 +231,13 @@ function fillTemplateDropdown(id) { // The prepopulateNote function populates the note field with first found template body in Template dropdown. function prepopulateNote() { + {if !prepopulate_note} + return; + {/if} var dropdown = document.getElementById("template"); if (dropdown == null) return; // Nothing to do. - if (!{$prepopulate_note} || dropdown.options.length <= 1) return ; // 1 because of mandatory top option. + if (dropdown.options.length <= 1) return ; // 1 because of mandatory top option. dropdown.options[1].selected = true; // Select first template. var note = document.getElementById("note"); From b4de969043705a34ebf68e0af33a23a8c71dbce7 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 6 Jul 2020 01:07:54 +0000 Subject: [PATCH 212/877] A better fix for previous commit. --- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/time_script.tpl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 0571b5a74..e5f70cfbd 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.19.18.5204 | Copyright © Anuko | +  Anuko Time Tracker 1.19.18.5205 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/time_script.tpl b/WEB-INF/templates/time_script.tpl index 707121128..84ff653d2 100644 --- a/WEB-INF/templates/time_script.tpl +++ b/WEB-INF/templates/time_script.tpl @@ -231,7 +231,7 @@ function fillTemplateDropdown(id) { // The prepopulateNote function populates the note field with first found template body in Template dropdown. function prepopulateNote() { - {if !prepopulate_note} + {if !$prepopulate_note} return; {/if} var dropdown = document.getElementById("template"); From 014dcc496cb0e4385213a6d3a9f75d6fa77c4fcc Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 7 Jul 2020 17:51:54 +0000 Subject: [PATCH 213/877] Cosmetic improvements in comments. --- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/time_script.tpl | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index e5f70cfbd..9a047ba35 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.19.18.5205 | Copyright © Anuko | +  Anuko Time Tracker 1.19.18.5206 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/time_script.tpl b/WEB-INF/templates/time_script.tpl index 84ff653d2..709a7cff7 100644 --- a/WEB-INF/templates/time_script.tpl +++ b/WEB-INF/templates/time_script.tpl @@ -78,7 +78,7 @@ var empty_label_task = "{$i18n.dropdown.select|escape:'javascript'}"; var empty_label_template = "{$i18n.dropdown.select|escape:'javascript'}"; // The fillDropdowns function populates the "project", "task", and "template" dropdown controls -// with relevant values. +// with relevant values, and also prepopulates the Note field, if required. function fillDropdowns() { if(document.body.contains(document.timeRecordForm.client)) fillProjectDropdown(document.timeRecordForm.client.value); @@ -239,9 +239,9 @@ function prepopulateNote() { if (dropdown.options.length <= 1) return ; // 1 because of mandatory top option. - dropdown.options[1].selected = true; // Select first template. + dropdown.options[1].selected = true; // Select first available template. var note = document.getElementById("note"); - note.value = template_bodies[dropdown.options[1].value]; // Prepolulate note with first template body. + note.value = template_bodies[dropdown.options[1].value]; // Prepolulate the Note field with first template body. } // The formDisable function disables some fields depending on what we have in other fields. From 531fba94204370984d817fa7f7543d7d59e3fbfe Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 7 Jul 2020 18:09:47 +0000 Subject: [PATCH 214/877] Made coding of template_add.php and template_edit.php more consistent. --- WEB-INF/templates/footer.tpl | 2 +- template_add.php | 12 ++++++++---- template_edit.php | 2 +- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 9a047ba35..3cdabc241 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.19.18.5206 | Copyright © Anuko | +  Anuko Time Tracker 1.19.18.5207 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/template_add.php b/template_add.php index 98dd41430..cc2dc83b6 100644 --- a/template_add.php +++ b/template_add.php @@ -42,7 +42,9 @@ // End of access checks. $config = new ttConfigHelper($user->getConfig()); -$projects = ttGroupHelper::getActiveProjects(); +$bindTemplatesWithProjects = $config->getDefinedValue('bind_templates_with_projects'); +if ($bindTemplatesWithProjects) + $projects = ttGroupHelper::getActiveProjects(); if ($request->isPost()) { $cl_name = trim($request->getParameter('name')); @@ -50,8 +52,10 @@ $cl_content = trim($request->getParameter('content')); $cl_projects = $request->getParameter('projects'); } else { - foreach ($projects as $project_item) - $cl_projects[] = $project_item['id']; + if ($bindTemplatesWithProjects) { + foreach ($projects as $project_item) + $cl_projects[] = $project_item['id']; + } } $form = new Form('templateForm'); @@ -82,7 +86,7 @@ } // isPost $smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('show_projects', count($projects) > 0 && $config->getDefinedValue('bind_templates_with_projects')); +$smarty->assign('show_projects', $bindTemplatesWithProjects && count($projects) > 0); $smarty->assign('title', $i18n->get('title.add_template')); $smarty->assign('content_page_name', 'template_add.tpl'); $smarty->display('index.tpl'); diff --git a/template_edit.php b/template_edit.php index 7619e7378..ef2b38cf1 100644 --- a/template_edit.php +++ b/template_edit.php @@ -104,7 +104,7 @@ } // isPost $smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('show_projects', $bindTemplatesWithProjects && count($projects) > 0 && $bindTemplatesWithProjects); +$smarty->assign('show_projects', $bindTemplatesWithProjects && count($projects) > 0); $smarty->assign('title', $i18n->get('title.edit_template')); $smarty->assign('content_page_name', 'template_edit.tpl'); $smarty->display('index.tpl'); From c7fb55551bd14b7d9f649a085c7fff11d18de768 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 7 Jul 2020 20:00:46 +0000 Subject: [PATCH 215/877] Some usability fixes for templates plugin. --- WEB-INF/lib/ttGroupHelper.class.php | 5 +++-- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/templates.tpl | 7 +++++-- WEB-INF/templates/time_script.tpl | 6 ++++-- templates.php | 5 ++++- 5 files changed, 17 insertions(+), 8 deletions(-) diff --git a/WEB-INF/lib/ttGroupHelper.class.php b/WEB-INF/lib/ttGroupHelper.class.php index 83ffe648c..af8d55345 100644 --- a/WEB-INF/lib/ttGroupHelper.class.php +++ b/WEB-INF/lib/ttGroupHelper.class.php @@ -174,7 +174,8 @@ static function markGroupDeleted($group_id) { 'tt_config', 'tt_predefined_expenses', 'tt_client_project_binds', - 'tt_project_task_binds' + 'tt_project_task_binds', + 'tt_project_template_binds' ); foreach($tables_to_delete_from as $table) { if (!ttGroupHelper::deleteGroupEntriesFromTable($group_id, $table)) @@ -187,7 +188,7 @@ static function markGroupDeleted($group_id) { // // 1) Users may mark some of them deleted during their work. // If we mark all of them deleted here, we can't recover nicely - // as we'll lose track of what was accidentally deleted by user. + // as we'll lose track of what was deleted by users. // // 2) DB maintenance script (Clean up DB from inactive groups) should // get rid of these items permanently eventually. diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 3cdabc241..25f44c0e6 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
 Anuko Time Tracker 1.19.18.5207 | Copyright © Anuko | +  Anuko Time Tracker 1.19.18.5208 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/templates.tpl b/WEB-INF/templates/templates.tpl index 71b7daebc..a22325788 100644 --- a/WEB-INF/templates/templates.tpl +++ b/WEB-INF/templates/templates.tpl @@ -48,12 +48,15 @@ {/if}
+ +{if $show_bind_with_projects_checkbox} - + +{/if} - + diff --git a/WEB-INF/templates/time_script.tpl b/WEB-INF/templates/time_script.tpl index 709a7cff7..2c6364305 100644 --- a/WEB-INF/templates/time_script.tpl +++ b/WEB-INF/templates/time_script.tpl @@ -83,8 +83,10 @@ function fillDropdowns() { if(document.body.contains(document.timeRecordForm.client)) fillProjectDropdown(document.timeRecordForm.client.value); - fillTaskDropdown(document.timeRecordForm.project.value); - fillTemplateDropdown(document.timeRecordForm.project.value); + if(document.body.contains(document.timeRecordForm.project)) { + fillTaskDropdown(document.timeRecordForm.project.value); + fillTemplateDropdown(document.timeRecordForm.project.value); + } prepopulateNote(); } diff --git a/templates.php b/templates.php index fec66b599..45ea2e477 100644 --- a/templates.php +++ b/templates.php @@ -42,6 +42,8 @@ // End of access checks. $config = $user->getConfigHelper(); +$trackingMode = $user->getTrackingMode(); +$showBindWithProjectsCheckbox = $trackingMode != MODE_TIME; if ($request->isPost()) { $cl_bind_templates_with_projects = $request->getParameter('bind_templates_with_projects'); @@ -52,7 +54,7 @@ } $form = new Form('templatesForm'); -$form->addInput(array('type'=>'checkbox','name'=>'bind_templates_with_projects','value'=>$cl_bind_templates_with_projects)); +if ($showBindWithProjectsCheckbox) $form->addInput(array('type'=>'checkbox','name'=>'bind_templates_with_projects','value'=>$cl_bind_templates_with_projects)); $form->addInput(array('type'=>'checkbox','name'=>'prepopulate_note','value'=>$cl_prepopulate_note)); $form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); $form->addInput(array('type'=>'submit','name'=>'btn_add','value'=>$i18n->get('button.add'))); @@ -79,6 +81,7 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('active_templates', $activeTemplates); $smarty->assign('inactive_templates', $inactiveTemplates); +$smarty->assign('show_bind_with_projects_checkbox', $showBindWithProjectsCheckbox); $smarty->assign('title', $i18n->get('title.templates')); $smarty->assign('content_page_name', 'templates.tpl'); $smarty->display('index.tpl'); From 79d5bdaa98570c812069ff57bfe185e5d74a73ef Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 7 Jul 2020 20:58:44 +0000 Subject: [PATCH 216/877] Cosmetic. --- WEB-INF/lib/ttGroupExportHelper.class.php | 2 +- WEB-INF/templates/templates.tpl | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/WEB-INF/lib/ttGroupExportHelper.class.php b/WEB-INF/lib/ttGroupExportHelper.class.php index 91d463542..9b23edbee 100644 --- a/WEB-INF/lib/ttGroupExportHelper.class.php +++ b/WEB-INF/lib/ttGroupExportHelper.class.php @@ -470,7 +470,7 @@ function writeData() { } fwrite($this->file, $this->indentation." \n"); - // Write expense otems. + // Write expense items. // We use getRecordsChunkFromTable here to avoid out of memory condition for large tables. fwrite($this->file, $this->indentation." \n"); $offset = 0; diff --git a/WEB-INF/templates/templates.tpl b/WEB-INF/templates/templates.tpl index a22325788..c1ffff729 100644 --- a/WEB-INF/templates/templates.tpl +++ b/WEB-INF/templates/templates.tpl @@ -48,7 +48,6 @@ {/if}
{$forms.templatesForm.bind_templates_with_projects.control}{$forms.templatesForm.bind_templates_with_projects.control} {$i18n.label.what_is_it}
{$forms.templatesForm.prepopulate_note.control}{$forms.templatesForm.prepopulate_note.control} {$i18n.label.what_is_it}
- {if $show_bind_with_projects_checkbox} From c72ff82cccba42b7a4fcaea557db86b5068228bc Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 9 Jul 2020 15:47:10 +0000 Subject: [PATCH 217/877] Added project to template binds to export. --- WEB-INF/lib/ttGroupExportHelper.class.php | 27 +++++++++++++++++++++-- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/WEB-INF/lib/ttGroupExportHelper.class.php b/WEB-INF/lib/ttGroupExportHelper.class.php index 9b23edbee..843fe84f4 100644 --- a/WEB-INF/lib/ttGroupExportHelper.class.php +++ b/WEB-INF/lib/ttGroupExportHelper.class.php @@ -48,6 +48,7 @@ class ttGroupExportHelper { var $customFieldMap = array(); var $customFieldOptionMap = array(); var $favReportMap = array(); + var $templateMap = array(); // Constructor. function __construct($group_id, $file, $indentation) { @@ -218,6 +219,11 @@ function writeData() { foreach ($fav_reports as $key=>$fav_report) $this->favReportMap[$fav_report['id']] = $key + 1; + // Prepare template map. + $templates = $this->getRecordsFromTable('tt_templates'); + foreach ($templates as $key=>$template) + $this->templateMap[$template['id']] = $key + 1; + // Write roles. fwrite($this->file, $this->indentation." \n"); foreach ($roles as $role) { @@ -511,11 +517,11 @@ function writeData() { } // Write templates. - $templates = $this->getRecordsFromTable('tt_templates'); if (count($templates) > 0) { fwrite($this->file, $this->indentation." \n"); foreach ($templates as $template) { - $template_part = $this->indentation.' '."
{$forms.templatesForm.bind_templates_with_projects.control}