bugzilla-4intranet/template/en/default/worktime/supertime.html.tmpl

326 lines
12 KiB
Cheetah
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

[%# "Dry run" of SuperWorktime
# License: Dual-license GPL 3.0+ or MPL 1.1+
# Author: Vitaliy Filippov <vitalif@mail.ru>
#%]
[% title = "Массовый ввод трудозатрат" %]
[% PROCESS global/header.html.tmpl
title = title
javascript_urls = [ "js/calendar.js", "js/change-columns.js" ]
style_urls = [ "skins/standard/calendar.css", "skins/standard/buglist.css" ]
%]
<p>
Данная форма используется для массового ввода трудозатрат[% IF wt_admin %],
в том числе задним числом и от имени нескольких пользователей[% END %].<br />
Для введения трудозатрат задним числом и от имени других пользователей
требуется членство в группе <b>worktimeadmin</b>.
</p>
[% hidden_fields = {
'chfieldfrom' => 1
'chfieldto' => 1
'chfieldwho' => 1
'worktime_user' => 3
'worktime_date' => 3
'save_worktime' => 3
'token' => 3
'format' => 3
'comment' => 2
'divide_min_inc' => 2
'divide_other_bug_id' => 2
} %]
[% for_all_users = "за всех участников" %]
[% MACRO hidden_inputs BLOCK %]
[% FOR k = query_params.keys %]
[% IF !hidden_fields.$k || hidden_fields.$k == HideIndex %]
[% IF query_params.$k.size %]
[% FOR vk = query_params.${k} %]
<input type="hidden" name="[% k | html %]" value="[% vk | html %]" />
[% END %]
[% ELSE %]
<input type="hidden" name="[% k | html %]" value="[% query_params.${k} | html %]" />
[% END %]
[% END %]
[% END %]
[% END %]
<fieldset>
<legend>Выборка трудозатрат:</legend>
<form action="?" method="POST">
<input type="hidden" name="format" value="superworktime" />
[% hidden_inputs(HideIndex=2) %]
<p style="margin: 8px 0">
Баг изменён:
с <input type="text" name="chfieldfrom" id="chfieldfrom" value="[% query_params.chfieldfrom | html %]" onchange="check_who_enabled()" />
по <input type="text" name="chfieldto" id="chfieldto" value="[% query_params.chfieldto | html %]" onchange="check_who_enabled()" />
<span style="color: #aaa">(YYYY-MM-DD HH:MM:SS)</span> &nbsp; &nbsp;
пользователем: <input type="text" name="chfieldwho" id="chfieldwho" value="[% query_params.chfieldwho | html %]" />
</p>
<p style="margin: 0">
Period Worktime:
с <input type="text" name="period_from" id="period_from" value="[% query_params.period_from || query_params.period_to || query_params.period_who ? query_params.period_from : query_params.chfieldfrom | html %]" />
по <input type="text" name="period_to" id="period_to" value="[% query_params.period_from || query_params.period_to || query_params.period_who ? query_params.period_to : query_params.chfieldto | html %]" />
<span style="color: #aaa">(YYYY-MM-DD HH:MM:SS)</span> &nbsp; &nbsp;
пользователь: <input type="text" name="period_who" id="period_who" value="[% query_params.period_from || query_params.period_to || query_params.period_who ? query_params.period_who : query_params.chfieldwho | html %]" /> &nbsp;
<input type="submit" value=" Показать трудозатраты " />
</p>
</form>
</fieldset>
[% search_description %]
<hr />
[% IF bugs.size > 9 %]
<p class="bz_result_count">
[% bugs.size %] [%+ terms.bugs %] found.
</p>
[% END %]
<form action="?" method="POST" onsubmit="wt_user_check()">
<input type="hidden" name="format" value="superworktime" />
<input type="hidden" name="save_worktime" value="1" />
<input type="hidden" name="token" value="[% token | html %]" />
[% hidden_inputs(HideIndex=1) %]
[% BLOCK worktime_th %]
<th>Списать время</th>
[% END %]
[% BLOCK worktime_td %]
<td[% IF bug.product_notimetracking %] style="background-color: #FFC0C0"[% END %]>
<input type="text" style="text-align: right" name="wtime_[% bug.bug_id %]"
id="wtime_[% bug.bug_id %]" value="[% worktimes.${bug.bug_id} || '' %]"
onkeypress="refresh_total_wt()" onchange="refresh_total_wt()" />
</td>
[% END %]
[% BLOCK worktime_total %]
<td id="wtime_total" class="bz_total">0</td>
[% END %]
[% SET bug_table_callback = "worktime_td" %]
[% SET bug_header_callback = "worktime_th" %]
[% SET bug_time_summary_line_callback = "worktime_total" %]
[% PROCESS list/table.html.tmpl %]
<fieldset>
<legend>Списать время:</legend>
[% IF wt_admin %]
На дату: <input type="text" name="worktime_date" value="[% worktime_date | html %]" /> <span style="color: #aaa">(YYYY-MM-DD HH:MM:SS)</span> &nbsp;
За пользователя:
<input type="hidden" name="worktime_user" id="worktime_user_real" value="" />
<input type="text" id="worktime_user" value="[% worktime_user | html %]"
onfocus="wt_user_focus()" onblur="wt_user_blur()" /> &nbsp;
[% ELSE %]
На дату: <b>[% worktime_date | html %]</b> &nbsp;
За пользователя: <b>[%+ Bugzilla.user.login | html %]</b> &nbsp;
[% END %]
<input value=" Списать время " type="submit" style="font-weight: bold" />
<input type="hidden" name="dry_run" id="dry_run" value="" />
<input value=" Предпросмотр " type="button" onclick="do_dry_run(this.form)" />
<br />
Добавить комментарий: <input type="text" name="comment" value="[% comment | html %]" size="50" />
[% IF wt_admin %]
<p style="margin: 8px 0 0 0">
<span id="divide_other_bug_id_text">Распределить пропорционально участию в одном баге:</span>
<input type="text" name="divide_other_bug_id" id="divide_other_bug_id" size="6" value="" />
<span id="divide_other_bug_id_text_2">(пропорционально участию в каждом, если пусто)</span>
</p>
<p style="margin: 8px 0 0 0">
<input type="checkbox" name="move_time" id="move_time" value="1" onclick="check_move(this)" />
<label for="move_time">
Перенести время с указанного бага на баги в списке &ndash; на баги списка будет списано
в сумме ровно столько часов, сколько было затрачено за заданный период на баг, с которого переносится время,
пропорционально введённым значениям времени.
</label>
</p>
[% END %]
</fieldset>
<fieldset id="divide_hours_cont">
<legend>Распределение часов по багам:</legend>
Сумма: <input type="text" id="divide_hours" onchange="divide_hours_check()" onkeypress="divide_hours_check()" /> &nbsp;
минимум&nbsp;по: <input type="text" id="divide_min_inc" name="divide_min_inc" value="0.1" /> &nbsp;
<input value=" Распределить часы " type="button" onclick="divide_hours_click()" />
(пропорционально / равномерно, будут добавлены к значениям в таблице)
</fieldset>
</form>
<script type="text/javascript">
<!--
var period_times = { [% FOREACH bug = bugs %][% IF NOT loop.first %],[% END %]'[% bug.bug_id %]':[% bug.interval_time || 0 %][% END %] };
var period_times_sorted;
function divide_hours_click()
{
var min_inc = bzParseTime(document.getElementById('divide_min_inc').value);
var sum = bzParseTime(document.getElementById('divide_hours').value);
if (!sum || sum != sum)
{
alert('Нечего распределять! Введите число, время в формате HH:MM, или в днях 1d, 2d, 3d и т.п.');
return;
}
if (!period_times_sorted)
{
// Чтобы сумма списываемых часов сходилась, а результаты были логичными
// (т.е. чтобы в баг с бОльшим временем попадало большее время),
// пропорциональное распределение лучше делать в порядке от меньших
// значений к бОльшим. Посему сортируем список багов.
period_times_sorted = [];
for (var i in period_times)
{
period_times_sorted.push(i);
}
period_times_sorted.sort(function(a, b)
{
return period_times[a] < period_times[b] ? -1 : (period_times[a] > period_times[b] ? 1 : 0);
});
}
var period_sum = 0, period_count = 0;
for (var i in period_times)
{
period_sum += period_times[i];
period_count++;
}
var cur, inc, ed, i;
var total_inc = 0;
for (var ii in period_times_sorted)
{
i = period_times_sorted[ii];
ed = document.getElementById('wtime_'+i);
cur = bzParseTime(ed.value);
if (!cur || cur != cur)
cur = 0;
if (period_sum == 0)
inc = sum/period_count;
else
inc = sum*period_times[i]/period_sum;
inc = Math.round(inc*100)/100;
if (inc < min_inc && inc > -min_inc)
{
// не списываем время совсем уж мелкими суммами
period_count--;
if (period_sum != 0)
period_sum -= period_times[i];
continue;
}
// Следующие строчки - извратик, призванный корректировать
// возникающую ошибку округления, чтобы реальная сумма
// списываемых часов была более близка к заданной
sum -= inc;
period_count--;
period_sum -= period_times[i];
cur += inc;
total_inc += inc;
cur = Math.round(cur*100)/100;
ed.value = cur;
}
refresh_total_wt();
}
function divide_hours_check()
{
var val = document.getElementById('divide_hours').value;
var sum = bzParseTime(val);
var incorrect = val !== '' && (sum != sum || sum === null || sum === undefined);
document.getElementById('divide_hours_cont').style.backgroundColor = incorrect ? '#ffe0e0' : '';
}
function wt_user_blur()
{
var ed = document.getElementById('worktime_user');
if (!ed.value)
{
ed.value = '[% for_all_users %]';
ed.style.color = 'red';
document.getElementById('divide_other_bug_id').value = '';
}
document.getElementById('divide_other_bug_id_text').style.color = ed.value ? 'gray' : '';
document.getElementById('divide_other_bug_id_text_2').style.color = ed.value ? 'gray' : '';
document.getElementById('divide_other_bug_id').disabled = ed.value ? true : false;
}
function wt_user_focus()
{
var ed = document.getElementById('worktime_user');
if (ed.value == '[% for_all_users %]')
{
ed.value = '';
ed.style.color = '';
}
}
function wt_user_check()
{
var ed = document.getElementById('worktime_user');
document.getElementById('worktime_user_real').value = ed.value == '[% for_all_users %]' ? '' : ed.value;
}
function refresh_total_wt()
{
var sum = 0;
for (var i in period_times)
{
ed = document.getElementById('wtime_'+i);
cur = bzParseTime(ed.value);
if (cur == cur && cur)
sum += cur;
}
sum = Math.round(sum*100)/100;
document.getElementById('wtime_total').innerHTML = sum;
}
function check_who_enabled()
{
var f = document.getElementById('chfieldfrom');
var t = document.getElementById('chfieldto');
var w = document.getElementById('chfieldwho');
var enab = f.value != '' || t.value != '';
w.style.backgroundColor = enab ? '' : '#f0f0f0';
w.disabled = !enab;
}
function check_move(c)
{
if (c.checked)
{
var e = true;
for (var i in period_times)
{
if (document.getElementById('wtime_'+i).value != '')
{
e = false;
break;
}
}
if (e)
{
for (var i in period_times)
{
document.getElementById('wtime_'+i).value = '1';
}
}
}
}
function do_dry_run(frm)
{
wt_user_check();
frm.dry_run.value = '1';
frm.target = '_blank';
frm.submit();
frm.dry_run.value = '';
frm.target = '';
}
wt_user_blur();
check_who_enabled();
Calendar.set('chfieldfrom');
Calendar.set('chfieldto');
new SimpleAutocomplete("chfieldwho", userAutocomplete, { emptyText: 'No users found' });
Calendar.set('period_from');
Calendar.set('period_to');
new SimpleAutocomplete("period_who", userAutocomplete, { emptyText: 'No users found' });
//-->
</script>
[% PROCESS global/footer.html.tmpl %]