// The update function updates team information.
static function update($team_id, $fields)
{
- // We'll require team name to be always set.
- if (!isset($fields['name'])) return false;
+ // We'll require team name to be always set.
+ if (!isset($fields['name'])) return false;
- $mdb2 = getConnection();
- $name_part = 'name = '.$mdb2->quote($fields['name']);
+ $mdb2 = getConnection();
+ $name_part = 'name = '.$mdb2->quote($fields['name']);
$currency_part = '';
$addr_part = '';
$locktime_part = '';
}
return $result;
}
+
+ // isDateLocked checks whether a specifc date is locked for modifications.
+ function isDateLocked($date)
+ {
+ if ($this->isPluginEnabled('lk')) {
+ // Determine lock date. Entries earlier than lock date cannot be created or modified.
+ $lockdate = 0;
+ if ($this->lock_interval > 0) {
+ $lockdate = new DateAndTime();
+ $lockdate->decDay($this->lock_interval);
+ }
+ if($lockdate && $date->before($lockdate))
+ return true;
+ }
+ return false;
+ }
}
'title.cf_add_dropdown_option' => 'Adding Option',
'title.cf_edit_dropdown_option' => 'Editing Option',
'title.cf_delete_dropdown_option' => 'Deleting Option',
+// NOTE TO TRANSLATORS: Locking is a feature to lock records from modifications (ex: weekly on Mondays we lock all previous weeks).
+// It is also a name for the Locking plugin on the Team profile page.
+'title.locking' => 'Locking',
// 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.
'title.cf_add_dropdown_option' => 'Добавление опции',
'title.cf_edit_dropdown_option' => 'Редактирование опции',
'title.cf_delete_dropdown_option' => 'Удаление опции',
+'title.locking' => 'Блокировка',
// 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.
<br>
<table cellspacing="0" cellpadding="4" width="100%" border="0">
<tr>
- <td align="center"> Anuko Time Tracker 1.9.20.3463 | Copyright © <a href="https://www.anuko.com/lp/tt_3.htm" target="_blank">Anuko</a> |
+ <td align="center"> Anuko Time Tracker 1.9.21.3464 | Copyright © <a href="https://www.anuko.com/lp/tt_3.htm" target="_blank">Anuko</a> |
<a href="https://www.anuko.com/lp/tt_4.htm" target="_blank">{$i18n.footer.credits}</a> |
<a href="https://www.anuko.com/lp/tt_5.htm" target="_blank">{$i18n.footer.license}</a> |
<a href="https://www.anuko.com/lp/tt_7.htm" target="_blank">{$i18n.footer.improve}</a>
--- /dev/null
+{$forms.lockingForm.open}
+<table cellspacing="4" cellpadding="7" border="0">
+ <tr>
+ <td>
+ <table cellspacing="1" cellpadding="2" border="0">
+ <tr>
+ <td align="right" nowrap>{$i18n.label.lock_interval}:</td>
+ <td>{$forms.lockingForm.lock_interval.control}</td>
+ </tr>
+ <tr>
+ <td colspan="2"> </td>
+ </tr>
+ <tr>
+ <td colspan="2" height="50" align="center">{$forms.lockingForm.btn_save.control}</td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+</table>
+{$forms.lockingForm.close}
} else {
configureLabel.style.visibility = "hidden";
}
+
+ var lockingCheckbox = document.getElementById("locking");
+ configureLabel = document.getElementById("locking_config");
+ if (lockingCheckbox.checked) {
+ configureLabel.style.visibility = "visible";
+ } else {
+ configureLabel.style.visibility = "hidden";
+ }
}
</script>
<td align="right">{$i18n.label.currency}:</td>
<td>{$forms.profileForm.currency.control}</td>
</tr>
- <tr>
- <td align="right" nowrap>{$i18n.label.lock_interval}:</td>
- <td>{$forms.profileForm.lock_interval.control}</td>
- </tr>
<tr>
<td align="right" nowrap>{$i18n.label.language}:</td>
<td>{$forms.profileForm.lang.control}</td>
<td align="right" nowrap>{$forms.profileForm.notifications.control}</td>
<td><label for="notifications">{$i18n.title.notifications}</label> <span id="notifications_config"><a href="notifications.php">{$i18n.label.configure}</a></span></td>
</tr>
+ <tr>
+ <td align="right" nowrap>{$forms.profileForm.locking.control}</td>
+ <td><label for="notifications">{$i18n.title.locking}</label> <span id="locking_config"><a href="locking.php">{$i18n.label.configure}</a></span></td>
+ </tr>
{/if}
<tr>
if ($request->isPost()) {
if ($request->getParameter('delete_button')) { // Delete button pressed.
- // Determine if it's okay to delete the record.
-
- // Determine lock date.
- $lock_interval = $user->lock_interval;
- $lockdate = 0;
- if ($lock_interval > 0) {
- $lockdate = new DateAndTime();
- $lockdate->decDay($lock_interval);
- }
- if ($lockdate) {
- $item_date = new DateAndTime(DB_DATEFORMAT);
- $item_date->parseVal($expense_item['date'], DB_DATEFORMAT);
- if ($item_date->before($lockdate))
- $err->add($i18n->getKey('error.period_locked'));
- }
+ // Determine if it is okay to delete the record.
+ $item_date = new DateAndTime(DB_DATEFORMAT, $expense_item['date']);
+ if ($user->isDateLocked($item_date))
+ $err->add($i18n->getKey('error.period_locked'));
if ($err->no()) {
// Mark the record as deleted.
if (!ttValidFloat($cl_cost)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.cost'));
if (!ttValidDate($cl_date)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.date'));
- // Determine lock date.
- $lock_interval = $user->lock_interval;
- $lockdate = 0;
- if ($lock_interval > 0) {
- $lockdate = new DateAndTime();
- $lockdate->decDay($lock_interval);
- }
-
// This is a new date for the expense item.
$new_date = new DateAndTime($user->date_format, $cl_date);
// Save record.
if ($request->getParameter('btn_save')) {
// We need to:
- // 1) Prohibit updating locked entries (that are in locked interval).
- // 2) Prohibit saving unlocked entries into locked interval.
+ // 1) Prohibit updating locked entries (that are in locked range).
+ // 2) Prohibit saving unlocked entries into locked range.
// Now, step by step.
- // 1) Prohibit updating locked entries.
- if($lockdate && $item_date->before($lockdate))
+ // 1) Prohibit saving locked entries in any form.
+ if ($user->isDateLocked($item_date))
$err->add($i18n->getKey('error.period_locked'));
- // 2) Prohibit saving completed unlocked entries into locked interval.
- if($err->no() && $lockdate && $new_date->before($lockdate))
+
+ // 2) Prohibit saving unlocked entries into locked range.
+ if ($err->no() && $user->isDateLocked($new_date))
$err->add($i18n->getKey('error.period_locked'));
// Now, an update.
$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->getKey('button.submit')));
-// Determine lock date. Time entries earlier than lock date cannot be created or modified.
-$lock_interval = $user->lock_interval;
-$lockdate = 0;
-if ($lock_interval > 0) {
- $lockdate = new DateAndTime();
- $lockdate->decDay($lock_interval);
-}
-
// Submit.
if ($request->isPost()) {
if ($request->getParameter('btn_submit')) {
}
// Finished validating input data.
- // Prohibit creating time entries in locked interval.
- if($lockdate && $selected_date->before($lockdate))
+ // Prohibit creating entries in locked range.
+ if ($user->isDateLocked($selected_date))
$err->add($i18n->getKey('error.period_locked'));
// Insert record.
--- /dev/null
+<?php
+// +----------------------------------------------------------------------+
+// | Anuko Time Tracker
+// +----------------------------------------------------------------------+
+// | Copyright (c) Anuko International Ltd. (https://www.anuko.com)
+// +----------------------------------------------------------------------+
+// | LIBERAL FREEWARE LICENSE: This source code document may be used
+// | by anyone for any purpose, and freely redistributed alone or in
+// | combination with other software, provided that the license is obeyed.
+// |
+// | There are only two ways to violate the license:
+// |
+// | 1. To redistribute this code in source form, with the copyright
+// | notice or license removed or altered. (Distributing in compiled
+// | forms without embedded copyright notices is permitted).
+// |
+// | 2. To redistribute modified versions of this code in *any* form
+// | that bears insufficient indications that the modifications are
+// | not the work of the original author(s).
+// |
+// | This license applies to this document only, not any other software
+// | that it may be combined with.
+// |
+// +----------------------------------------------------------------------+
+// | Contributors:
+// | https://www.anuko.com/time_tracker/credits.htm
+// +----------------------------------------------------------------------+
+
+require_once('initialize.php');
+import('form.Form');
+import('ttTeamHelper');
+
+// Access check.
+if (!ttAccessCheck(right_manage_team)) {
+ header('Location: access_denied.php');
+ exit();
+}
+
+$cl_lock_interval = $request->isPost() ? $request->getParameter('lock_interval') : $user->lock_interval;
+
+$form = new Form('lockingForm');
+$form->addInput(array('type'=>'text','maxlength'=>'10','name'=>'lock_interval','value'=>$cl_lock_interval));
+$form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->getKey('button.save')));
+
+if ($request->isPost()) {
+ if ($cl_lock_interval == null || trim($cl_lock_interval) == '') $cl_lock_interval = 0;
+
+ if (ttTeamHelper::update($user->team_id, array(
+ 'name' => $user->team,
+ 'locktime' => $cl_lock_interval))) {
+ header('Location: time.php');
+ exit();
+ } else {
+ $err->add($i18n->getKey('error.db'));
+ }
+} // isPost
+
+$smarty->assign('forms', array($form->getName()=>$form->toArray()));
+$smarty->assign('title', $i18n->getKey('title.locking'));
+$smarty->assign('content_page_name', 'locking.tpl');
+$smarty->display('index.tpl');
}
}
-// Determine lock date. Time entries earlier than lock date cannot be created or modified.
-$lock_interval = $user->lock_interval;
-$lockdate = 0;
-if ($lock_interval > 0) {
- $lockdate = new DateAndTime();
- $lockdate->decDay($lock_interval);
-}
-
// Submit.
if ($request->isPost()) {
if ($request->getParameter('btn_submit')) {
$err->add($i18n->getKey('error.future_date'));
}
- // Prohibit creating time entries in locked interval.
- if($lockdate && $selected_date->before($lockdate))
+ // Prohibit creating entries in locked range.
+ if ($user->isDateLocked($selected_date))
$err->add($i18n->getKey('error.period_locked'));
// Prohibit creating another uncompleted record.
exit();
}
-// Use Custom Fields plugin if we have one.
-// if (file_exists("plugins/CustomFields.class.php")) {
-// require_once("plugins/CustomFields.class.php");
-// $custom_fields = new CustomFields($user->team_id);
-// }
-
$cl_id = $request->getParameter('id');
$time_rec = ttTimeHelper::getRecord($cl_id, $user->getActiveUser());
// Determine if it's okay to delete the record.
$item_date = new DateAndTime(DB_DATEFORMAT, $time_rec['date']);
- // Determine lock date.
- $lock_interval = $user->lock_interval;
- $lockdate = 0;
- if ($lock_interval > 0) {
- $lockdate = new DateAndTime();
- $lockdate->decDay($lock_interval);
- }
// Determine if the record is uncompleted.
$uncompleted = ($time_rec['duration'] == '0:00');
- if($lockdate && $item_date->before($lockdate) && !$uncompleted) {
+ if ($user->isDateLocked($item_date) && !$uncompleted)
$err->add($i18n->getKey('error.period_locked'));
- }
if ($err->no()) {
if (!ttValidString($cl_note, true)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.note'));
// Finished validating user input.
- // Determine lock date.
- $lock_interval = $user->lock_interval;
- $lockdate = 0;
- if ($lock_interval > 0) {
- $lockdate = new DateAndTime();
- $lockdate->decDay($lock_interval);
- }
-
// This is a new date for the time record.
$new_date = new DateAndTime($user->date_format, $cl_date);
// Save record.
if ($request->getParameter('btn_save')) {
// We need to:
- // 1) Prohibit saving locked time entries in any form.
- // 2) Prohibit saving completed unlocked entries into locked interval.
+ // 1) Prohibit saving locked entries in any form.
+ // 2) Prohibit saving completed unlocked entries into locked range.
// 3) Prohibit saving uncompleted unlocked entries when another uncompleted entry exists.
// Now, step by step.
if ($err->no()) {
- // 1) Prohibit saving locked time entries in any form.
- if($lockdate && $item_date->before($lockdate))
+ // 1) Prohibit saving locked entries in any form.
+ if ($user->isDateLocked($item_date))
$err->add($i18n->getKey('error.period_locked'));
- // 2) Prohibit saving completed unlocked entries into locked interval.
- if($err->no() && $lockdate && $new_date->before($lockdate))
+
+ // 2) Prohibit saving completed unlocked entries into locked range.
+ if ($err->no() && $user->isDateLocked($new_date))
$err->add($i18n->getKey('error.period_locked'));
+
// 3) Prohibit saving uncompleted unlocked entries when another uncompleted entry exists.
$uncompleted = ($cl_finish == '' && $cl_duration == '');
if ($uncompleted) {
$cl_address = trim($request->getParameter('address'));
$cl_currency = trim($request->getParameter('currency'));
if (!$cl_currency) $cl_currency = CURRENCY_DEFAULT;
- $cl_lock_interval = $request->getParameter('lock_interval');
$cl_lang = $request->getParameter('lang');
$cl_decimal_mark = $request->getParameter('decimal_mark');
$cl_custom_format_date = $request->getParameter('format_date');
$cl_expenses = $request->getParameter('expenses');
$cl_tax_expenses = $request->getParameter('tax_expenses');
$cl_notifications = $request->getParameter('notifications');
+ $cl_locking = $request->getParameter('locking');
}
} else {
$cl_name = $user->name;
$cl_team = $user->team;
$cl_address = $user->address;
$cl_currency = ($user->currency == ''? CURRENCY_DEFAULT : $user->currency);
- $cl_lock_interval = $user->lock_interval;
$cl_lang = $user->lang;
$cl_decimal_mark = $user->decimal_mark;
$cl_custom_format_date = $user->date_format;
$cl_expenses = in_array('ex', $plugins);
$cl_tax_expenses = in_array('et', $plugins);
$cl_notifications = in_array('no', $plugins);
+ $cl_locking = in_array('lk', $plugins);
}
}
$DECIMAL_MARK_OPTIONS = array(array('id'=>'.','name'=>'.'),array('id'=>',','name'=>','));
$form->addInput(array('type'=>'combobox','name'=>'decimal_mark','style'=>'width: 150px','data'=>$DECIMAL_MARK_OPTIONS,'datakeys'=>array('id','name'),'value'=>$cl_decimal_mark,
'onchange'=>'adjustDecimalPreview()'));
- $form->addInput(array('type'=>'text','maxlength'=>'10','name'=>'lock_interval','value'=>$cl_lock_interval));
// Prepare an array of available languages.
$lang_files = I18n::getLangFileList();
foreach ($lang_files as $lfile) {
$form->addInput(array('type'=>'checkbox','name'=>'expenses','data'=>1,'value'=>$cl_expenses,'onchange'=>'handlePluginCheckboxes()'));
$form->addInput(array('type'=>'checkbox','name'=>'tax_expenses','data'=>1,'value'=>$cl_tax_expenses));
$form->addInput(array('type'=>'checkbox','name'=>'notifications','data'=>1,'value'=>$cl_notifications,'onchange'=>'handlePluginCheckboxes()'));
+ $form->addInput(array('type'=>'checkbox','name'=>'locking','data'=>1,'value'=>$cl_locking,'onchange'=>'handlePluginCheckboxes()'));
}
$form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->getKey('button.save')));
$plugins .= ',et';
if ($cl_notifications)
$plugins .= ',no';
+ if ($cl_locking)
+ $plugins .= ',lk';
$plugins = trim($plugins, ',');
$update_result = ttTeamHelper::update($user->team_id, array(
'name' => $cl_team,
'address' => $cl_address,
'currency' => $cl_currency,
- 'locktime' => $cl_lock_interval,
'lang' => $cl_lang,
'decimal_mark' => $cl_decimal_mark,
'date_format' => $cl_custom_format_date,
}
}
-// Determine lock date. Time entries earlier than lock date cannot be created or modified.
-$lock_interval = $user->lock_interval;
-$lockdate = 0;
-if ($lock_interval > 0) {
- $lockdate = new DateAndTime();
- $lockdate->decDay($lock_interval);
-}
-
// Submit.
if ($request->isPost()) {
if ($request->getParameter('btn_submit')) {
$err->add($i18n->getKey('error.future_date'));
}
- // Prohibit creating time entries in locked interval.
- if($lockdate && $selected_date->before($lockdate))
+ // Prohibit creating entries in locked range.
+ if ($user->isDateLocked($selected_date))
$err->add($i18n->getKey('error.period_locked'));
// Prohibit creating another uncompleted record.
// Determine if it's okay to delete the record.
$item_date = new DateAndTime(DB_DATEFORMAT, $time_rec['date']);
- // Determine lock date.
- $lock_interval = $user->lock_interval;
- $lockdate = 0;
- if ($lock_interval > 0) {
- $lockdate = new DateAndTime();
- $lockdate->decDay($lock_interval);
- }
+
// Determine if the record is uncompleted.
$uncompleted = ($time_rec['duration'] == '0:00');
- if($lockdate && $item_date->before($lockdate) && !$uncompleted) {
+ if ($user->isDateLocked($item_date) && !$uncompleted)
$err->add($i18n->getKey('error.period_locked'));
- }
if ($err->no()) {
if (!ttValidString($cl_note, true)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.note'));
// Finished validating user input.
- // Determine lock date.
- $lock_interval = $user->lock_interval;
- $lockdate = 0;
- if ($lock_interval > 0) {
- $lockdate = new DateAndTime();
- $lockdate->decDay($lock_interval);
- }
-
// This is a new date for the time record.
$new_date = new DateAndTime($user->date_format, $cl_date);
// Now, step by step.
if ($err->no()) {
- // 1) Prohibit saving locked time entries in any form.
- if($lockdate && $item_date->before($lockdate))
+ // 1) Prohibit saving locked entries in any form.
+ if ($user->isDateLocked($item_date))
$err->add($i18n->getKey('error.period_locked'));
- // 2) Prohibit saving completed unlocked entries into locked interval.
- if($err->no() && $lockdate && $new_date->before($lockdate))
+
+ // 2) Prohibit saving completed unlocked entries into locked range.
+ if ($err->no() && $user->isDateLocked($new_date))
$err->add($i18n->getKey('error.period_locked'));
+
// 3) Prohibit saving uncompleted unlocked entries when another uncompleted entry exists.
$uncompleted = ($cl_finish == '' && $cl_duration == '');
if ($uncompleted) {
// Save as new record.
if ($request->getParameter('btn_copy')) {
// We need to:
- // 1) Prohibit saving into locked interval.
+ // 1) Prohibit saving into locked range.
// 2) Prohibit saving uncompleted unlocked entries when another uncompleted entry exists.
// Now, step by step.
if ($err->no()) {
- // 1) Prohibit saving into locked interval.
- if($lockdate && $new_date->before($lockdate))
+ // 1) Prohibit saving into locked range.
+ if ($user->isDateLocked($new_date))
$err->add($i18n->getKey('error.period_locked'));
+
// 2) Prohibit saving uncompleted unlocked entries when another uncompleted entry exists.
$uncompleted = ($cl_finish == '' && $cl_duration == '');
if ($uncompleted) {