diff options
author | jeff <jeff> | 2007-08-16 13:40:46 +0000 |
---|---|---|
committer | jeff <jeff> | 2007-08-16 13:40:46 +0000 |
commit | 1293d137b061f097190eda53e4e78214e18832e6 (patch) | |
tree | ba1a26cd005b31a4e5cdf12ba1264d6cd06e736e /httemplate | |
parent | f20b5533fdb8f1f3510b5cf4efd1f4465f359420 (diff) |
support hours 'usage' tracking for our own internal use (#1733)
Diffstat (limited to 'httemplate')
-rw-r--r-- | httemplate/elements/menu.html | 2 | ||||
-rw-r--r-- | httemplate/misc/batch-cust_pay.html | 379 | ||||
-rw-r--r-- | httemplate/misc/elements/customer-table.html | 387 | ||||
-rw-r--r-- | httemplate/misc/process/timeworked.html | 47 | ||||
-rwxr-xr-x | httemplate/misc/timeworked.html | 77 | ||||
-rw-r--r-- | httemplate/search/timeworked.html | 74 | ||||
-rw-r--r-- | httemplate/view/cust_main/tickets.html | 27 |
7 files changed, 596 insertions, 397 deletions
diff --git a/httemplate/elements/menu.html b/httemplate/elements/menu.html index 616900c2d..455c7b364 100644 --- a/httemplate/elements/menu.html +++ b/httemplate/elements/menu.html @@ -214,6 +214,8 @@ $tools_menu{'Process payment batches'} = [ $fsurl.'search/pay_batch.cgi?magic=_d if $conf->exists('batch-enable') && $curuser->access_right('Process batches'); $tools_menu{'Job Queue'} = [ $fsurl.'search/queue.html', 'View pending job queue' ] if $curuser->access_right('Job queue'); +$tools_menu{'Time Queue'} = [ $fsurl.'search/timeworked.html', 'View pending support time' ] + if $curuser->access_right('Time queue'); $tools_menu{'Importing'} = [ \%tools_importing, 'Import tools' ] if $curuser->access_right('Import'); $tools_menu{'Exporting'} = [ \%tools_exporting, 'Export tools' ] diff --git a/httemplate/misc/batch-cust_pay.html b/httemplate/misc/batch-cust_pay.html index d85f3b6c3..f2f446001 100644 --- a/httemplate/misc/batch-cust_pay.html +++ b/httemplate/misc/batch-cust_pay.html @@ -1,8 +1,5 @@ <% include("/elements/header.html", 'Quick payment entry', - menubar( - 'Main Menu' => $p, #popurl(1), - ), - ( $cgi->param('error') ? '' : 'onload="addRow()"' ), + menubar( 'Main Menu' => $p ), ) %> % if ( $cgi->param('error') ) { @@ -16,284 +13,13 @@ <!-- <B>Batch</B> <INPUT TYPE="text" NAME="paybatch"><BR><BR> --> -<SCRIPT TYPE="text/javascript"> - - function clearhint_custnum() { - - //this.style.color = '#000000'; - - if ( this.value == 'Not found' || this.value == 'Multiple' ) { - this.value = ''; - this.style.color = '#000000'; - } - - } - - function clearhint_customer() { - - this.style.color = '#000000'; - - if ( this.value == '(last name or company)' || this.value == 'Not found' ) - this.value = ''; - - } - - function search_custnum() { - - this.style.color = '#000000' - - var custnum_obj = this; - var searchrow = this.getAttribute('rownum'); - var custnum = this.value; - - if ( custnum == 'searching...' || custnum == 'Not found' || custnum == '' ) - return; - - if ( this.getAttribute('magic') == 'nosearch' ) { - this.setAttribute('magic', ''); - return; - } - - if ( ( rownum - searchrow ) == 1 ) { - addRow(); - } - var customer = document.getElementById('customer'+searchrow); - customer.value = 'searching...'; - customer.disabled = true; - customer.style.color = '#000000'; - customer.style.backgroundColor = '#dddddd'; - - var customer_select = document.getElementById('cust_select'+searchrow); - - //alert('search for custnum ' + custnum + ', row#' + searchrow ); - - customer.style.display = ''; - customer_select.style.display = 'none'; - - function search_custnum_update(name) { - - var name = eval('(' + name + ')' ); - - customer.disabled = false; - customer.style.backgroundColor = '#ffffff'; - - if ( name.length > 0 ) { - //alert('custnum found: ' + name); - customer.value = name; - customer.setAttribute('magic', 'nosearch'); - } else { - customer.value = 'Not found'; - customer.style.color = '#ff0000'; - custnum_obj.style.color = '#ff0000'; - - } - - } - - custnum_search( custnum, search_custnum_update ); - - } - - function search_customer() { - - var customer_obj = this; - var searchrow = this.getAttribute('rownum'); - var customer = this.value; - - if ( customer == 'searching...' || customer == 'Not found' || customer == '' ) - return; - - if ( this.getAttribute('magic') == 'nosearch' ) { - this.setAttribute('magic', ''); - return; - } - - if ( ( rownum - searchrow ) == 1 ) { - addRow(); - } - - var custnum_obj = document.getElementById('custnum'+searchrow); - custnum_obj.value = 'searching...'; - custnum_obj.disabled = true; - custnum_obj.style.color = '#000000'; - custnum_obj.style.backgroundColor = '#dddddd'; - - var customer_select = document.getElementById('cust_select'+searchrow); - - //alert('search for customer ' + customer + ', row#' + searchrow ); - - function search_customer_update(customers) { - - //alert('customers returned: ' + customers); - - var customerArray = eval('(' + customers + ')'); - - custnum_obj.disabled = false; - custnum_obj.style.backgroundColor = '#ffffff'; - - if ( customerArray.length == 0 ) { - - custnum_obj.value = 'Not found'; - custnum_obj.style.color = '#ff0000'; - customer_obj.style.color = '#ff0000'; - - customer_obj.style.display = ''; - customer_select.style.display = 'none'; - - - } else if ( customerArray.length == 1 ) { - - //alert('one customer found: ' + customerArray[0]); - - custnum_obj.value = customerArray[0][0]; - customer_obj.value = customerArray[0][1]; - - customer_obj.style.display = ''; - customer_select.style.display = 'none'; - - - } else { - - custnum_obj.value = 'Multiple'; // or something - custnum_obj.style.color = '#ff0000'; - - //alert('multiple customers found, have to create select dropdown'); - - //blank the current list - for ( var i = customer_select.length; i >= 0; i-- ) - customer_select.options[i] = null; - - opt(customer_select, '', 'Multiple customers match "' + customer + '" - select one', '#ff0000'); - - //add the multiple customers - for ( var s = 0; s < customerArray.length; s++ ) - opt(customer_select, customerArray[s][0], customerArray[s][1], '#000000'); - - opt(customer_select, 'cancel', '(Edit search string)', '#000000'); - - customer_obj.style.display = 'none'; - - customer_select.style.display = ''; - - } - - } - - smart_search( customer, search_customer_update ); - - } - - function select_customer() { - - var custnum = this.options[this.selectedIndex].value; - var customer = this.options[this.selectedIndex].text; - - var searchrow = this.getAttribute('rownum'); - var custnum_obj = document.getElementById('custnum'+searchrow); - var customer_obj = document.getElementById('customer'+searchrow); - - if ( custnum == '' ) { - //this.style.color = '#ff0000'; - - } else if ( custnum == 'cancel' ) { - - custnum_obj.value = ''; - custnum_obj.style.color = '#000000'; - - this.style.display = 'none'; - customer_obj.style.display = ''; - customer_obj.focus(); - - } else { - - - custnum_obj.value = custnum; - custnum_obj.style.color = '#000000'; - - customer_obj.value = customer; - customer_obj.style.color = '#000000'; - - this.style.display = 'none'; - customer_obj.style.display = ''; - - } - - } - - function opt(what,value,text,color) { - var optionName = new Option(text, value, false, false); - optionName.style.color = color; - var length = what.length; - what.options[length] = optionName; - } - -</SCRIPT> - -<TABLE ID="OneTrueTable" BGCOLOR="#cccccc" BORDER=0 CELLSPACING=0> - -<TR> - <TH>Cust #</TH> - <TH>Customer</TH> - <TH>Amount</TH> - <TH>Check #</TH> - <TH BGCOLOR="#e8e8e8"></TH> -</TR> -% my $row = 0; -% if ( $cgi->param('error') ) { -% my $param = $cgi->Vars; -% -% for ( $row = 0; exists($param->{"custnum$row"}); $row++ ) { - - - <TR> - - <TD> - <INPUT TYPE="text" NAME="custnum<% $row %>" ID="custnum<% $row %>" SIZE=8 MAXLENGTH=12 VALUE="<% $param->{"custnum$row"} %>" rownum="<% $row %>"> - <SCRIPT TYPE="text/javascript"> - var custnum_input<% $row %> = document.getElementById("custnum<% $row %>"); - custnum_input<% $row %>.onfocus = clearhint_custnum; - custnum_input<% $row %>.onchange = search_custnum; - </SCRIPT> - </TD> - - <TD> - <INPUT TYPE="text" NAME="customer<% $row %>" ID="customer<% $row %>" SIZE=64 VALUE="<% $param->{"customer$row"} %>" rownum="<% $row %>"> - <SCRIPT TYPE="text/javascript"> - var customer_input<% $row %> = document.getElementById("customer<% $row %>"); - customer_input<% $row %>.onfocus = clearhint_customer; - customer_input<% $row %>.onclick = clearhint_customer; - customer_input<% $row %>.onchange = search_customer; - </SCRIPT> - <SELECT NAME="cust_select<% $row %>" ID="cust_select<% $row %>" rownum="<% $row %>" STYLE="color:#ff0000; display:none"> - </SELECT> - <SCRIPT TYPE="text/javascript"> - var customer_select<% $row %> = document.getElementById("cust_select<% $row %>"); - customer_select<% $row %>.onchange = select_customer; - </SCRIPT> - </TD> - - <TD> - $<INPUT TYPE="text" NAME="paid<% $row %>" SIZE=8 MAXLENGTH=8 VALUE="<% $param->{"paid$row"} %>" > - </TD> - - <TD> - <INPUT TYPE="text" NAME="payinfo<% $row %>" SIZE=10 VALUE="<% $param->{"payinfo$row"} %>" > - </TD> - - <TD BGCOLOR="#e8e8e8"> -% if ( $param->{"error$row"} ) { - - <FONT SIZE="-1" COLOR="#ff0000">Error: <% $param->{"error$row"} %></FONT> -% } - - </TD> - - </TR> -% } -% } - - -</TABLE> +<% include( "elements/customer-table.html", + header => [ '', 'Amount', 'Check #', '' ], + fields => [ sub {'$'}, 'paid', 'payinfo', 'error', ], + types => [ 'immutable', '', '', 'immutable', ], + sizes => [ 0, 8, 10, 0, ], + param => { () }, + ) %> <!-- <BR> <INPUT TYPE="button" VALUE="TEST addrow" onclick="addRow()"> --> @@ -302,94 +28,5 @@ <INPUT TYPE="submit" NAME="submit" VALUE="Post payment batch"> </FORM> - - -<% include('/elements/xmlhttp.html', - 'url' => $p. 'misc/xmlhttp-cust_main-search.cgi', - 'subs' => [qw( custnum_search smart_search )], - ) -%> - -<SCRIPT TYPE="text/javascript"> - - var rownum = <% $row %>; - - function addRow() { - - var table = document.getElementById('OneTrueTable'); - var tablebody = table.getElementsByTagName('tbody').item(0); - - var row = document.createElement('TR'); - - var custnum_cell = document.createElement('TD'); - - var custnum_input = document.createElement('INPUT'); - custnum_input.setAttribute('name', 'custnum'+rownum); - custnum_input.setAttribute('id', 'custnum'+rownum); - custnum_input.setAttribute('size', 8); - custnum_input.setAttribute('maxlength', 12); - custnum_input.setAttribute('rownum', rownum); - custnum_input.onfocus = clearhint_custnum; - custnum_input.onchange = search_custnum; - custnum_cell.appendChild(custnum_input); - - row.appendChild(custnum_cell); - - var customer_cell = document.createElement('TD'); - - var customer_input = document.createElement('INPUT'); - customer_input.setAttribute('name', 'customer'+rownum); - customer_input.setAttribute('id', 'customer'+rownum); - customer_input.setAttribute('size', 64); - customer_input.setAttribute('value', '(last name or company)' ); - customer_input.setAttribute('rownum', rownum); - customer_input.onfocus = clearhint_customer; - customer_input.onclick = clearhint_customer; - customer_input.onchange = search_customer; - customer_cell.appendChild(customer_input); - - var customer_select = document.createElement('SELECT'); - customer_select.setAttribute('name', 'cust_select'+rownum); - customer_select.setAttribute('id', 'cust_select'+rownum); - customer_select.setAttribute('rownum', rownum); - customer_select.style.color = '#ff0000'; - customer_select.style.display = 'none'; - customer_select.onchange = select_customer; - customer_cell.appendChild(customer_select); - - row.appendChild(customer_cell); - - var paid_cell = document.createElement('TD'); - - var paid_text = document.createTextNode('$'); - paid_cell.appendChild(paid_text); - - var paid_input = document.createElement('INPUT'); - paid_input.setAttribute('name', 'paid'+rownum); - paid_input.setAttribute('size', 8); - paid_input.setAttribute('maxlength', 8); - paid_cell.appendChild(paid_input); - - row.appendChild(paid_cell); - - var payinfo_cell = document.createElement('TD'); - var payinfo_input = document.createElement('INPUT'); - payinfo_input.setAttribute('name', 'payinfo'+rownum); - payinfo_input.setAttribute('size', 10); - payinfo_cell.appendChild(payinfo_input); - row.appendChild(payinfo_cell); - - var error_cell = document.createElement('TD'); - error_cell.style.backgroundColor = '#e8e8e8'; - row.appendChild(error_cell); - - tablebody.appendChild(row); - - rownum++; - - } - -</SCRIPT> - </BODY> </HTML> diff --git a/httemplate/misc/elements/customer-table.html b/httemplate/misc/elements/customer-table.html new file mode 100644 index 000000000..fc298b03e --- /dev/null +++ b/httemplate/misc/elements/customer-table.html @@ -0,0 +1,387 @@ +% # options example... +% # +% # #listrefs... +% # 'header' => [ '#', 'Item' ], +% # 'fields' => [ +% # 'column', +% # sub { my ($row,$param) = @_; $param->{"column$row"}; }, +% # ], +% # 'sizes' => [], # sizes ignored for immutable +% # 'types' => ['immutable', ''], # immutable or ''/text +% # 'param' => { column0 => 1 }, # preset column of row 0 to 1 +% # + +<SCRIPT TYPE="text/javascript"> + + function clearhint_custnum() { + + if ( this.value == 'Not found' || this.value == 'Multiple' ) { + this.value = ''; + this.style.color = '#000000'; + } + + } + + function clearhint_customer() { + + this.style.color = '#000000'; + + if ( this.value == '(last name or company)' || this.value == 'Not found' ) + this.value = ''; + + } + + function <% $opt{prefix} %>search_custnum() { + + this.style.color = '#000000' + + var custnum_obj = this; + var searchrow = this.getAttribute('rownum'); + var custnum = this.value; + + if ( custnum == 'searching...' || custnum == 'Not found' || custnum == '' ) + return; + + if ( this.getAttribute('magic') == 'nosearch' ) { + this.setAttribute('magic', ''); + return; + } + + if ( ( <% $opt{prefix} %>rownum - searchrow ) == 1 ) { + <% $opt{prefix} %>addRow(); + } + var customer = document.getElementById('customer'+searchrow); + customer.value = 'searching...'; + customer.disabled = true; + customer.style.color = '#000000'; + customer.style.backgroundColor = '#dddddd'; + + var customer_select = document.getElementById('cust_select'+searchrow); + + customer.style.display = ''; + customer_select.style.display = 'none'; + + function search_custnum_update(name) { + + var name = eval('(' + name + ')' ); + + customer.disabled = false; + customer.style.backgroundColor = '#ffffff'; + + if ( name.length > 0 ) { + customer.value = name; + customer.setAttribute('magic', 'nosearch'); + } else { + customer.value = 'Not found'; + customer.style.color = '#ff0000'; + custnum_obj.style.color = '#ff0000'; + + } + + } + + custnum_search( custnum, search_custnum_update ); + + } + + function <% $opt{prefix} %>search_customer() { + + var customer_obj = this; + var searchrow = this.getAttribute('rownum'); + var customer = this.value; + + if ( customer == 'searching...' || customer == 'Not found' || customer == '' ) + return; + + if ( this.getAttribute('magic') == 'nosearch' ) { + this.setAttribute('magic', ''); + return; + } + + if ( ( <% $opt{prefix} %>rownum - searchrow ) == 1 ) { + <% $opt{prefix} %>addRow(); + } + + var custnum_obj = document.getElementById('custnum'+searchrow); + custnum_obj.value = 'searching...'; + custnum_obj.disabled = true; + custnum_obj.style.color = '#000000'; + custnum_obj.style.backgroundColor = '#dddddd'; + + var customer_select = document.getElementById('cust_select'+searchrow); + + function search_customer_update(customers) { + + var customerArray = eval('(' + customers + ')'); + + custnum_obj.disabled = false; + custnum_obj.style.backgroundColor = '#ffffff'; + + if ( customerArray.length == 0 ) { + + custnum_obj.value = 'Not found'; + custnum_obj.style.color = '#ff0000'; + customer_obj.style.color = '#ff0000'; + + customer_obj.style.display = ''; + customer_select.style.display = 'none'; + + + } else if ( customerArray.length == 1 ) { + + custnum_obj.value = customerArray[0][0]; + customer_obj.value = customerArray[0][1]; + + customer_obj.style.display = ''; + customer_select.style.display = 'none'; + + + } else { + + custnum_obj.value = 'Multiple'; // or something + custnum_obj.style.color = '#ff0000'; + + //blank the current list + for ( var i = customer_select.length; i >= 0; i-- ) + customer_select.options[i] = null; + + opt(customer_select, '', 'Multiple customers match "' + customer + '" - select one', '#ff0000'); + + //add the multiple customers + for ( var s = 0; s < customerArray.length; s++ ) + opt(customer_select, customerArray[s][0], customerArray[s][1], '#000000'); + + opt(customer_select, 'cancel', '(Edit search string)', '#000000'); + + customer_obj.style.display = 'none'; + + customer_select.style.display = ''; + + } + + } + + smart_search( customer, search_customer_update ); + + } + + function select_customer() { + + var custnum = this.options[this.selectedIndex].value; + var customer = this.options[this.selectedIndex].text; + + var searchrow = this.getAttribute('rownum'); + var custnum_obj = document.getElementById('custnum'+searchrow); + var customer_obj = document.getElementById('customer'+searchrow); + + if ( custnum == '' ) { + + } else if ( custnum == 'cancel' ) { + + custnum_obj.value = ''; + custnum_obj.style.color = '#000000'; + + this.style.display = 'none'; + customer_obj.style.display = ''; + customer_obj.focus(); + + } else { + + custnum_obj.value = custnum; + custnum_obj.style.color = '#000000'; + + customer_obj.value = customer; + customer_obj.style.color = '#000000'; + + this.style.display = 'none'; + customer_obj.style.display = ''; + + } + + } + + function opt(what,value,text,color) { + var optionName = new Option(text, value, false, false); + optionName.style.color = color; + var length = what.length; + what.options[length] = optionName; + } + +</SCRIPT> + +<TABLE ID="<% $opt{prefix} %>OneTrueTable" BGCOLOR="#cccccc" BORDER=0 CELLSPACING=0> + +<TR> + <TH>Cust #</TH> + <TH>Customer</TH> +% foreach my $header ( @{$opt{header}} ) { + <TH><% $header %></TH> +% } +</TR> +% my $row = 0; +% for ( $row = 0; exists($param->{"custnum$row"}); $row++ ) { + + <TR> + + <TD> + <INPUT TYPE="text" NAME="custnum<% $row %>" ID="custnum<% $row %>" SIZE=8 MAXLENGTH=12 VALUE="<% $param->{"custnum$row"} %>" rownum="<% $row %>"> + <SCRIPT TYPE="text/javascript"> + var custnum_input<% $row %> = document.getElementById("custnum<% $row %>"); + custnum_input<% $row %>.onfocus = clearhint_custnum; + custnum_input<% $row %>.onchange = <% $opt{prefix} %>search_custnum; + </SCRIPT> + </TD> + + <TD> + <INPUT TYPE="text" NAME="customer<% $row %>" ID="customer<% $row %>" SIZE=64 VALUE="<% $param->{"customer$row"} %>" rownum="<% $row %>"> + <SCRIPT TYPE="text/javascript"> + var customer_input<% $row %> = document.getElementById("customer<% $row %>"); + customer_input<% $row %>.onfocus = clearhint_customer; + customer_input<% $row %>.onclick = clearhint_customer; + customer_input<% $row %>.onchange = <% $opt{prefix} %>search_customer; + </SCRIPT> + <SELECT NAME="cust_select<% $row %>" ID="cust_select<% $row %>" rownum="<% $row %>" STYLE="color:#ff0000; display:none"> + </SELECT> + <SCRIPT TYPE="text/javascript"> + var customer_select<% $row %> = document.getElementById("cust_select<% $row %>"); + customer_select<% $row %>.onchange = select_customer; + </SCRIPT> + </TD> + +% my $col = 0; +% foreach my $field ( @{$opt{fields}} ) { +% my $value; +% if ( ref($field) eq 'CODE' ) { +% $value = &{$field}($row,$param); +% } else { +% $value = $param->{"$field$row"}; +% } +% my $name = (ref($field) eq 'CODE') ? "column${col}_$row" : "$field$row"; +% my $size = $sizes->[$col] || 10; + <TD> +% if (! $types->[$col] || $types->[$col] eq 'text') { + <INPUT TYPE="text" NAME="<% $name %>" SIZE="<% $size %>" VALUE="<% $value %>" > +% } elsif ($types->[$col] eq 'immutable') { + <% $value %> + <INPUT TYPE="hidden" NAME="<% $name %>" VALUE="<% $value %>" > +% } else { + Cannot represent unknown type: <% $types->[$col] %> +% } + </TD> +% $col++; +% } + + </TR> +% } + + +</TABLE> + +<% include('/elements/xmlhttp.html', + 'url' => $p. 'misc/xmlhttp-cust_main-search.cgi', + 'subs' => [qw( custnum_search smart_search )], + ) +%> + +<SCRIPT TYPE="text/javascript"> + + var <% $opt{prefix} %>rownum = <% $row %>; + + function <% $opt{prefix} %>addRow() { + + var table = document.getElementById('<% $opt{prefix} %>OneTrueTable'); + var tablebody = table.getElementsByTagName('tbody').item(0); + + var row = document.createElement('TR'); + + var custnum_cell = document.createElement('TD'); + + var custnum_input = document.createElement('INPUT'); + custnum_input.setAttribute('name', 'custnum'+<% $opt{prefix} %>rownum); + custnum_input.setAttribute('id', 'custnum'+<% $opt{prefix} %>rownum); + custnum_input.setAttribute('size', 8); + custnum_input.setAttribute('maxlength', 12); + custnum_input.setAttribute('rownum', <% $opt{prefix} %>rownum); + custnum_input.onfocus = clearhint_custnum; + custnum_input.onchange = <% $opt{prefix} %>search_custnum; + custnum_cell.appendChild(custnum_input); + + row.appendChild(custnum_cell); + + var customer_cell = document.createElement('TD'); + + var customer_input = document.createElement('INPUT'); + customer_input.setAttribute('name', 'customer'+<% $opt{prefix} %>rownum); + customer_input.setAttribute('id', 'customer'+<% $opt{prefix} %>rownum); + customer_input.setAttribute('size', 64); + customer_input.setAttribute('value', '(last name or company)' ); + customer_input.setAttribute('rownum', <% $opt{prefix} %>rownum); + customer_input.onfocus = clearhint_customer; + customer_input.onclick = clearhint_customer; + customer_input.onchange = <% $opt{prefix} %>search_customer; + customer_cell.appendChild(customer_input); + + var customer_select = document.createElement('SELECT'); + customer_select.setAttribute('name', 'cust_select'+<% $opt{prefix} %>rownum); + customer_select.setAttribute('id', 'cust_select'+<% $opt{prefix} %>rownum); + customer_select.setAttribute('rownum', <% $opt{prefix} %>rownum); + customer_select.style.color = '#ff0000'; + customer_select.style.display = 'none'; + customer_select.onchange = select_customer; + customer_cell.appendChild(customer_select); + + row.appendChild(customer_cell); + +% my $col = 0; +% foreach my $field ( @{$opt{fields}} ) { + var my_cell = document.createElement('TD'); + +% if ($types->[$col] eq 'immutable') { +% my $value; +% if ( ref($field) eq 'CODE' ) { +% $value = &{$field}($row,$param); +% } else { +% $value = $param->{"$field$row"}; +% } + var my_text = document.createTextNode('<% $value %>'); + my_cell.appendChild(my_text); +% } + + var my_input = document.createElement('INPUT'); + my_input.setAttribute('name', '<% $field %>'+<% $opt{prefix} %>rownum); + my_input.setAttribute('size', <% $sizes->[$col] || 10 %>); +% if ($types->[$col] eq 'immutable') { + my_input.setAttribute('type', 'hidden'); +% } + my_cell.appendChild(my_input); + + row.appendChild(my_cell); + +% $col++; +% } + + tablebody.appendChild(row); + + <% $opt{prefix} %>rownum++; + + } + +% unless ($cgi->param('error')) { + <% $opt{prefix} %>addRow(); +% } +</SCRIPT> + +<%init> + +my(%opt) = @_; + +$opt{prefix} = '' unless defined $opt{prefix}; +$opt{prefix} .= '_' if $opt{prefix}; + +my $types = $opt{'types'} ? [ @{$opt{'types'}} ] : []; +my $sizes = $opt{'sizes'} ? [ @{$opt{'sizes'}} ] : []; + +my $param = $opt{param}; +$param = $cgi->Vars if $cgi->param('error'); + +</%init> diff --git a/httemplate/misc/process/timeworked.html b/httemplate/misc/process/timeworked.html new file mode 100644 index 000000000..078d645d1 --- /dev/null +++ b/httemplate/misc/process/timeworked.html @@ -0,0 +1,47 @@ +% if ($error) { +<% $cgi->redirect(popurl(2). "timeworked.html?". $cgi->query_string) %> +% } else { +<% $cgi->redirect(popurl(3). "search/timeworked.html") %> +% } +<%init> + +my %multipliers = map { /^custnum(\d+)$/; ($cgi->param("custnum$1") => $cgi->param("multiplier$1")); } + grep /^custnum\d+$/, $cgi->param; + +my @svc_acct_rt_transaction; +foreach my $transaction ( + map { /^transactionid(\d+)$/; $1; } grep /^transactionid\d+$/, $cgi->param +) { + my $seconds = $cgi->param("seconds$transaction"); + my %seconds = map { $_ => sprintf("%.0f", $seconds * $multipliers{$_}) } + (keys %multipliers); + my $sum = 0; + my $count = 0; + foreach (values %seconds) { + $sum += $_; + $count++; + } + + #fudge in some time if we're close + if (abs($seconds-$sum) <= $count) { + my $adjustment = $seconds-$sum; + foreach (keys %seconds) { # explicitly choose one? + $seconds{$_} += $adjustment; + last; + } + } + + foreach my $customer ( grep {$seconds{$_}} keys %seconds ) { + push @svc_acct_rt_transaction, new FS::svc_acct_rt_transaction { + 'custnum' => $customer, + 'transaction_id' => $transaction, + 'seconds' => $seconds{$customer}, + }; + } + +} + +my $error = FS::svc_acct_rt_transaction->batch_insert(@svc_acct_rt_transaction); +$cgi->param('error', $error) if $error; + +</%init> diff --git a/httemplate/misc/timeworked.html b/httemplate/misc/timeworked.html new file mode 100755 index 000000000..2b288f233 --- /dev/null +++ b/httemplate/misc/timeworked.html @@ -0,0 +1,77 @@ +<% include('/elements/header.html', $title, '' ) %> + +% if ( $cgi->param('error') ) { + <FONT SIZE="+1" COLOR="#ff0000">Error: <% $cgi->param('error') %></FONT> + <BR><BR> +% } + +<FORM NAME="timeworked_form" ACTION="<% popurl(1) %>process/timeworked.html" METHOD=POST> + +<BR><BR> +<% include("elements/customer-table.html", header => [ 'Multiplier' ], + fields => [ 'multiplier' ], + param => { %param }, + ) %> + +<BR> +<INPUT TYPE="submit" NAME="submit" VALUE="<% $title %>"> +<BR> +<BR> + +for transactions/tickets: +<TABLE> + +% foreach ( sort { $a <=> $b } keys %ticket ) { + + <TR><TD><% $_ %></TD><TD><% $ticket{$_} %></TD></TR> + <INPUT TYPE="hidden" NAME="transactionid<% $_ %>" VALUE="1" > + <INPUT TYPE="hidden" NAME="seconds<% $_ %>" VALUE="<% $cgi->param("seconds$_") %>" > + +% } + +</TABLE> +</FORM> +</BODY> +</HTML> + +<%init> + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Time queue'); + +my($svcnum, %ticket, %customers, %param); +my $title = 'Assign Time Worked'; + +RT::Init(); + +my $CurrentUser = RT::CurrentUser->new(); +$CurrentUser->LoadByName($FS::CurrentUser::CurrentUser->username); + +foreach my $id ( map { /^transactionid(\d+)$/; $1; } + grep /^transactionid\d+$/, $cgi->param) { + my $transaction = new RT::Transaction($CurrentUser); + $transaction->Load($id); + my $ticket = new RT::Ticket($CurrentUser); + $ticket->Load($transaction->ObjectId); + $ticket{$id} = $ticket->Subject; + foreach my $customerURI ( + grep { $_->Resolver->{'fstable'} eq 'cust_main' } + grep { $_->Scheme eq 'freeside' } + map { $_->TargetURI } + @{ $ticket->_Links('Base')->ItemsArrayRef } + ) { + $customers{$customerURI->Resolver->AsString} = 1; + } +} + +my $row = 0; +foreach ( keys %customers ) { + my ($number, $name) = split(':', $_, 2); + $param{"custnum$row"} = $number; + $param{"customer$row"} = $name; + $param{"multiplier$row"} = sprintf("%.2f", 1/scalar(keys(%customers))); + $row++; +} + +</%init> + diff --git a/httemplate/search/timeworked.html b/httemplate/search/timeworked.html new file mode 100644 index 000000000..18af74641 --- /dev/null +++ b/httemplate/search/timeworked.html @@ -0,0 +1,74 @@ +<% include( 'elements/search.html', + 'title' => 'Time Worked', + 'menubar' => [ 'Main menu' => $p, ], + 'name' => 'time', + 'html_form' => qq!<FORM NAME="timeForm" ACTION="${p}misc/timeworked.html" METHOD="POST">!, + 'query' => $query, + 'count_query' => $count_query, + 'header' => [ '#', + 'Ticket', + 'Date', + 'Time', + '', # checkbox column + ], + 'fields' => [ sub { shift->[0] }, + sub { shift->[1] }, + sub { shift->[2] }, + sub { my $seconds = shift->[3]; + (($seconds < 0) ? '-' : '') . + concise(duration($seconds)); + }, + sub { + my $row = shift; + my $seconds = $row->[3]; + my $id = $row->[4]; + qq!<INPUT NAME="transactionid$id" TYPE="checkbox" VALUE="1">!. + qq!<INPUT NAME="seconds$id" TYPE="hidden" VALUE="$seconds">!; + }, + ], + 'html_foot' => sub { + '<BR><INPUT TYPE="button" VALUE="select all" onClick="setAll(true)">'. + '<INPUT TYPE="button" VALUE="unselect all" onClick="setAll(false)">'. + '<BR><INPUT TYPE="submit" NAME="action" VALUE="Assign to accounts"><BR>'. + '<SCRIPT TYPE="text/javascript">'. + ' function setAll(setTo) { '. + ' theForm = document.timeForm;'. + ' for (i=0,n=theForm.elements.length;i<n;i++)'. + ' if (theForm.elements[i].name.indexOf("transactionid") != -1)'. + ' theForm.elements[i].checked = setTo;'. + ' }'. + '</SCRIPT>'; + }, + ) + +%> +<%init> + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Time queue'); + +my @groupby = (); + +my $transactiontime = "CASE transactions.type when 'Set' THEN (to_number(newvalue,'999999')-to_number(oldvalue, '999999')) * 60 ELSE timetaken*60 END"; +push @groupby, "transactions.type"; +push @groupby, "newvalue"; +push @groupby, "oldvalue"; +push @groupby, "timetaken"; + +my $appliedtimeclause = "coalesce (sum(svc_acct_rt_transaction.seconds), 0)"; + +my $appliedtimeselect = "SELECT sum(seconds) FROM svc_acct_rt_transaction where transaction_id = transactions.id"; +push @groupby, "transactions.id"; + +my $wheretimeleft = "($transactiontime != ($appliedtimeselect) OR ($appliedtimeselect) is NULL)"; + +push @groupby, "tickets.id"; +push @groupby, "tickets.subject"; +push @groupby, "transactions.created"; + +my $groupby = join(',', @groupby); + +my $query = "SELECT tickets.id,tickets.subject,to_char(transactions.created, 'Dy Mon DD HH24:MI:SS YYYY'),$transactiontime-$appliedtimeclause,transactions.id FROM transactions JOIN tickets ON transactions.objectid = tickets.id LEFT JOIN svc_acct_rt_transaction on transactions.id = svc_acct_rt_transaction.transaction_id WHERE objecttype='RT::Ticket' AND ((transactions.type='Set' AND field='TimeWorked') OR transactions.type='Comment' OR transactions.type='Correspond') AND ($wheretimeleft) GROUP BY $groupby ORDER BY transactions.created"; +my $count_query = "SELECT count(*) FROM transactions WHERE objecttype='RT::Ticket' AND ((transactions.type='Set' AND field='TimeWorked') OR transactions.type='Comment' OR transactions.type='Correspond') AND ($wheretimeleft)"; + +</%init> diff --git a/httemplate/view/cust_main/tickets.html b/httemplate/view/cust_main/tickets.html index 84cc90299..c4183ae55 100644 --- a/httemplate/view/cust_main/tickets.html +++ b/httemplate/view/cust_main/tickets.html @@ -1,31 +1,6 @@ % % my( $cust_main ) = @_; -% -% my $conf = new FS::Conf; -% my $num = $conf->config('cust_main-max_tickets') || 10; -% -% my @tickets = (); -% unless ( $conf->config('ticket_system-custom_priority_field') ) { -% -% @tickets = -% @{ FS::TicketSystem->customer_tickets($cust_main->custnum, $num) }; -% -% } else { -% -% foreach my $priority ( -% $conf->config('ticket_system-custom_priority_field-values'), '' -% ) { -% last if scalar(@tickets) >= $num; -% push @tickets, -% @{ FS::TicketSystem->customer_tickets( $cust_main->custnum, -% $num - scalar(@tickets), -% $priority, -% ) -% }; -% } -% -% } -% +% my( @tickets ) = $cust_main->tickets; % <A NAME="tickets"><FONT SIZE="+2">Tickets</FONT></A> |