<SCRIPT TYPE="text/javascript">
+ var num_open_invoices = new Array;
+
+ function clearhint_invnum() {
+
+ if ( this.value == 'Not found' || this.value == 'Multiple' ) {
+ this.value = '';
+ this.style.color = '#000000';
+ }
+
+ }
+
function clearhint_custnum() {
if ( this.value == 'Not found' || this.value == 'Multiple' ) {
}
- function <% $opt{prefix} %>search_custnum() {
+ function update_customer(searchrow, customerArray) {
+
+ var custnum_obj = document.getElementById('custnum'+searchrow);
+ var customer = document.getElementById('customer'+searchrow);
+ var customer_select = document.getElementById('cust_select'+searchrow);
+
+ custnum_obj.disabled = false;
+ custnum_obj.style.backgroundColor = '#ffffff';
+ customer.disabled = false;
+ customer.style.backgroundColor = '#ffffff';
+
+ if ( customerArray.length == 0 ) {
+
+ custnum_obj.value = 'Not found';
+ customer.value = 'Not found';
+ custnum_obj.style.color = '#ff0000';
+ customer.style.color = '#ff0000';
+
+ customer.style.display = '';
+ customer_select.style.display = 'none';
+ return false;
+
+ } else if ( customerArray.length == 6 ) {
+
+ custnum_obj.value = customerArray[0];
+ custnum_obj.style.color = '#000000';
+ customer.value = customerArray[1];
+
+ update_balance_text(searchrow, customerArray[2]);
+ update_status_text( searchrow, customerArray[3]);
+ update_status_color(searchrow, '#'+customerArray[4]);
+ update_num_open(searchrow, customerArray[5]);
+
+ customer.style.display = '';
+ customer_select.style.display = 'none';
+ return true;
+ }
+ }
+
+ function <% $opt{prefix} %>search_invnum() {
this.style.color = '#000000'
- var custnum_obj = this;
+ var invnum_obj = this;
var searchrow = this.getAttribute('rownum');
- var custnum = this.value;
+ var invnum = this.value;
- if ( custnum == 'searching...' || custnum == 'Not found' || custnum == '' )
+ if ( invnum == 'searching...' || invnum == 'Not found' || invnum == '' )
return;
if ( this.getAttribute('magic') == 'nosearch' ) {
customer.style.display = '';
customer_select.style.display = 'none';
+
+ var custnum_obj = document.getElementById('custnum'+searchrow);
+ update_balance_text(searchrow, '');
+ update_status_text(searchrow, '');
+ update_status_color(searchrow, '#000000');
+ update_num_open(searchrow, 0);
- function search_custnum_update(name) {
+ function search_invnum_update(customers) {
+
+ var customerArray = eval('(' + customers + ')');
+ update_customer(searchrow, customerArray);
- var name = eval('(' + name + ')' );
+% if ( $opt{invnum_update_callback} ) {
+ <% $opt{invnum_update_callback} %>(searchrow, '<% $opt{prefix} %>')
+% }
- customer.disabled = false;
- customer.style.backgroundColor = '#ffffff';
+ }
+
+ invnum_search( invnum, search_invnum_update );
+
+ }
+
+ function <% $opt{prefix} %>search_custnum() {
+
+ this.style.color = '#000000'
- if ( name.length > 0 ) {
- customer.value = name;
- customer.setAttribute('magic', 'nosearch');
+ 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_obj = document.getElementById('customer'+searchrow);
+ customer_obj.value = 'searching...';
+ customer_obj.disabled = true;
+ customer_obj.style.color = '#000000';
+ customer_obj.style.backgroundColor = '#dddddd';
+
+ var customer_select = document.getElementById('cust_select'+searchrow);
+
+ customer_obj.style.display = '';
+ customer_select.style.display = 'none';
+
+ var invnum = document.getElementById('invnum'+searchrow);
+ invnum.value = '';
+
+ update_balance_text(searchrow, '');
+ update_status_text( searchrow, '');
+ update_status_color(searchrow, '#000000');
+ update_num_open(searchrow, 0);
+
+ function search_custnum_update(customers) {
+
+ var customerArrayArray = eval('(' + customers + ')') || [];
+
+ if ( customerArrayArray.length == 0 ) {
+
+ update_customer(searchrow, []);
+
+ } else if ( customerArrayArray.length == 1 ) {
+
+ update_customer(searchrow, customerArrayArray[0]);
% if ( $opt{custnum_update_callback} ) {
- <% $opt{custnum_update_callback} %>(searchrow, '<% $opt{prefix} %>')
+ <% $opt{custnum_update_callback} %>(searchrow, '<% $opt{prefix} %>')
% }
+
} else {
- customer.value = 'Not found';
- customer.style.color = '#ff0000';
+
+ custnum_obj.value = 'Multiple'; // or something
custnum_obj.style.color = '#ff0000';
+ //blank the current list
+ customer_select.options.length = 0;
+
+ opt(customer_select, '', 'Multiple customers match "' + custnum + '" - select one', '#ff0000');
+ //add the multiple customers
+ for ( var s = 0; s < customerArrayArray.length; s++ ) {
+ opt(customer_select,
+ JSON.stringify(customerArrayArray[s]),
+ customerArrayArray[s][1],
+ '#000000');
+ }
+
+ opt(customer_select, 'cancel', '(Edit search string)', '#000000');
+
+ customer_obj.style.display = 'none';
+
+ customer_select.style.display = '';
+
}
}
- custnum_search( custnum, search_custnum_update );
+ custnum_search(custnum, search_custnum_update );
}
if ( ( <% $opt{prefix} %>rownum - searchrow ) == 1 ) {
<% $opt{prefix} %>addRow();
}
+
+ var invnum = document.getElementById('invnum'+searchrow);
+ invnum.value = '';
var custnum_obj = document.getElementById('custnum'+searchrow);
custnum_obj.value = 'searching...';
custnum_obj.style.backgroundColor = '#dddddd';
var customer_select = document.getElementById('cust_select'+searchrow);
-
+
function search_customer_update(customers) {
- var customerArray = eval('(' + customers + ')');
+ var customerArrayArray = 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';
-
+ if ( customerArrayArray.length == 0 ) {
- } else if ( customerArray.length == 1 ) {
+ update_customer(searchrow, []);
- custnum_obj.value = customerArray[0][0];
- customer_obj.value = customerArray[0][1];
-
- customer_obj.style.display = '';
- customer_select.style.display = 'none';
+ } else if ( customerArrayArray.length == 1 ) {
+ update_customer(searchrow, customerArrayArray[0]);
% if ( $opt{custnum_update_callback} ) {
<% $opt{custnum_update_callback} %>(searchrow, '<% $opt{prefix} %>')
% }
custnum_obj.style.color = '#ff0000';
//blank the current list
- for ( var i = customer_select.length; i >= 0; i-- )
- customer_select.options[i] = null;
+ customer_select.options.length = 0;
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');
+ for ( var s = 0; s < customerArrayArray.length; s++ ) {
+ opt(customer_select,
+ JSON.stringify(customerArrayArray[s]),
+ customerArrayArray[s][1],
+ '#000000');
+ }
opt(customer_select, 'cancel', '(Edit search string)', '#000000');
function select_customer() {
- var custnum = this.options[this.selectedIndex].value;
+ var custnum_balance_status = 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);
+ var balance_obj = document.getElementById('balance'+searchrow);
+ var status_obj = document.getElementById('status'+searchrow);
- if ( custnum == '' ) {
+ if ( custnum_balance_status == '' ) {
- } else if ( custnum == 'cancel' ) {
+ } else if ( custnum_balance_status == 'cancel' ) {
custnum_obj.value = '';
custnum_obj.style.color = '#000000';
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 = '';
+
+ update_customer(searchrow, JSON.parse(custnum_balance_status));
% if ( $opt{custnum_update_callback} ) {
<% $opt{custnum_update_callback} %>(searchrow, '<% $opt{prefix} %>')
what.options[length] = optionName;
}
+ function update_status_text(rownum, newval) {
+ document.getElementById('status'+rownum).value = newval;
+ document.getElementById('status'+rownum+'_text').innerHTML = newval;
+ }
+
+ function update_status_color(rownum, newval) {
+ document.getElementById('statuscolor'+rownum).value = newval;
+ document.getElementById('status'+rownum+'_text').style.color = newval;
+ }
+
+ function update_balance_text(rownum, newval) {
+ document.getElementById('balance'+rownum).value = newval;
+ document.getElementById('balance'+rownum+'_text').innerHTML = newval;
+ }
+
+ function update_num_open(rownum, newval) {
+ num_open_invoices[rownum] = newval;
+ }
+
+
</SCRIPT>
<TABLE ID="<% $opt{prefix} %>OneTrueTable" BGCOLOR="#cccccc" BORDER=0 CELLSPACING=0>
<TR>
+ <TH>Inv #</TH>
<TH>Cust #</TH>
+ <TH>Status</TH>
<TH>Customer</TH>
+ <TH>Balance</TH>
% foreach my $header ( @{$opt{header}} ) {
<TH><% $header %></TH>
% }
% my $row = 0;
% for ( $row = 0; exists($param->{"custnum$row"}); $row++ ) {
- <TR>
+ <TR id="row<%$row%>" rownum="<%$row%>">
+ <TD>
+ <INPUT TYPE = "text"
+ NAME = "invnum<% $row %>"
+ ID = "invnum<% $row %>"
+ SIZE = 8
+ MAXLENGTH = 12
+ STYLE = "text-align:right;"
+ VALUE = "<% $param->{"invnum$row"} %>"
+ rownum = "<% $row %>"
+ >
+ <SCRIPT TYPE="text/javascript">
+ var invnum_input<% $row %> = document.getElementById("invnum<% $row %>");
+ invnum_input<% $row %>.onfocus = clearhint_invnum;
+ invnum_input<% $row %>.onchange = <% $opt{prefix} %>search_invnum;
+ </SCRIPT>
+ </TD>
<TD>
<INPUT TYPE = "text"
custnum_input<% $row %>.onchange = <% $opt{prefix} %>search_custnum;
</SCRIPT>
</TD>
+
+ <TD STYLE="text-align: center">
+ <SPAN
+ ID = "status<% $row %>_text"
+ rownum = "<% $row %>"
+ STYLE = "font-weight: bold;
+ color: <%$param->{"statuscolor$row"} || '#000000'%>"
+
+ ><% $param->{"status$row"} %></SPAN>
+ <INPUT TYPE = "hidden"
+ NAME = "status<% $row %>"
+ ID = "status<% $row %>"
+ VALUE = "<% $param->{"status$row"} %>"
+ rownum = "<% $row %>"
+ >
+ <INPUT TYPE = "hidden"
+ NAME = "statuscolor<% $row %>"
+ ID = "statuscolor<% $row %>"
+ VALUE = "<% $param->{"statuscolor$row"} %>"
+ rownum = "<% $row %>"
+ >
+ </TD>
<TD>
<INPUT TYPE="text" NAME="customer<% $row %>" ID="customer<% $row %>" SIZE=64 VALUE="<% $param->{"customer$row"} %>" rownum="<% $row %>">
</SCRIPT>
</TD>
+ <TD STYLE="text-align:right">
+ <% $money_char %>
+ <SPAN
+ ID = "balance<% $row %>_text"
+ rownum = "<% $row %>"
+ ><% $param->{"balance$row"} %></SPAN>
+
+ <INPUT TYPE = "hidden"
+ NAME = "balance<% $row %>"
+ ID = "balance<% $row %>"
+ VALUE = "<% $param->{"balance$row"} %>"
+ rownum = "<% $row %>"
+ >
+ </TD>
+
% my $col = 0;
% foreach my $field ( @{$opt{fields}} ) {
% my $value;
% my $color = $opt{color}->[$col];
% my $font = $color ? qq(<FONT COLOR="$color">) : '';
% my $onchange = '';
-% if ( $opt{footer}->[$col] eq '_TOTAL' ) {
+% if ( $opt{onchange}->[$col] ) {
+% $onchange = 'onchange="'.$opt{onchange}->[$col].'"';
+% }
+% elsif ( $opt{footer}->[$col] eq '_TOTAL' ) {
% $total[$col] += $value;
% $onchange = $opt{prefix}. "calc_total$col();";
% $onchange = qq(onchange="$onchange" onkeyup="$onchange");
% }
<TD ALIGN="<% $align %>">
-% if (! $types->[$col] || $types->[$col] eq 'text') {
- <INPUT TYPE = "text"
+% my $type = $types->[$col] || 'text';
+% if ($type eq 'text' or $type eq 'checkbox') {
+ <INPUT TYPE = "<% $type %>"
NAME = "<% $name %>"
ID = "<% $name %>"
SIZE = "<% $size %>"
STYLE = "text-align: <% $align %>;"
VALUE = "<% $value %>"
+ rownum = "<% $row %>"
<% $onchange %>
>
% } elsif ($types->[$col] eq 'immutable') {
</TD>
% $col++;
% }
-
</TR>
% }
-<TR>
- <TH COLSPAN=2 ID="<% $opt{'prefix'} %>_TOTAL_TOTAL">
+<TR id="row_total">
+ <TH COLSPAN=5 ID="<% $opt{'prefix'} %>_TOTAL_TOTAL">
Total <% $row ? $row-1 : 0 %>
<% PL($opt{name_singular} || 'customer', ( $row ? $row-1 : 0 ) ) %>
</TH>
<% include('/elements/xmlhttp.html',
'url' => $p. 'misc/xmlhttp-cust_main-search.cgi',
- 'subs' => [qw( custnum_search smart_search )],
+ 'subs' => [qw( custnum_search smart_search invnum_search )],
)
%>
var table = document.getElementById('<% $opt{prefix} %>OneTrueTable');
var tablebody = table.getElementsByTagName('tbody').item(0);
- var row = table.insertRow(rownum+1);
+ var row = table.insertRow(table.rows.length - 1);
+ row.setAttribute('id', 'row'+rownum);
+
+ var invnum_cell = document.createElement('TD');
+
+ var invnum_input = document.createElement('INPUT');
+ invnum_input.setAttribute('name', 'invnum'+<% $opt{prefix} %>rownum);
+ invnum_input.setAttribute('id', 'invnum'+<% $opt{prefix} %>rownum);
+ invnum_input.style.textAlign = 'right';
+ invnum_input.setAttribute('size', 8);
+ invnum_input.setAttribute('maxlength', 12);
+ invnum_input.setAttribute('rownum', <% $opt{prefix} %>rownum);
+ invnum_input.onfocus = clearhint_invnum;
+ invnum_input.onchange = <% $opt{prefix} %>search_invnum;
+ invnum_cell.appendChild(invnum_input);
+
+ row.appendChild(invnum_cell);
var custnum_cell = document.createElement('TD');
custnum_cell.appendChild(custnum_input);
row.appendChild(custnum_cell);
+
+ var status_cell = document.createElement('TD');
+ status_cell.style.textAlign = 'center';
+
+ var status_span = document.createElement('SPAN');
+ status_span.setAttribute('id', 'status'+<% $opt{prefix} %>rownum+'_text');
+ status_span.style.fontWeight = 'bold';
+ status_span.setAttribute('rownum', <% $opt{prefix} %>rownum);
+ status_cell.appendChild(status_span);
+
+ var status_input = document.createElement('INPUT');
+ status_input.setAttribute('type', 'hidden');
+ status_input.setAttribute('name', 'status'+<% $opt{prefix} %>rownum);
+ status_input.setAttribute('id', 'status'+<% $opt{prefix} %>rownum);
+ status_input.setAttribute('rownum', <% $opt{prefix} %>rownum);
+ status_cell.appendChild(status_input);
+
+ var statuscolor_input = document.createElement('INPUT');
+ statuscolor_input.setAttribute('type', 'hidden');
+ statuscolor_input.setAttribute('name', 'statuscolor'+<% $opt{prefix} %>rownum);
+ statuscolor_input.setAttribute('id', 'statuscolor'+<% $opt{prefix} %>rownum);
+ statuscolor_input.setAttribute('rownum', <% $opt{prefix} %>rownum);
+ status_cell.appendChild(statuscolor_input);
+
+ row.appendChild(status_cell);
var customer_cell = document.createElement('TD');
customer_cell.appendChild(customer_select);
row.appendChild(customer_cell);
+
+ var balance_cell = document.createElement('TD');
+
+ balance_cell.style.textAlign = 'right';
+ balance_cell.appendChild(document.createTextNode('<%$money_char%>'));
+
+ var balance_span = document.createElement('SPAN');
+ balance_span.setAttribute('id', 'balance'+<% $opt{prefix} %>rownum+'_text');
+ balance_span.setAttribute('rownum', <% $opt{prefix} %>rownum);
+ balance_cell.appendChild(balance_span);
+
+ balance_cell.appendChild(
+ document.createTextNode(String.fromCharCode(160)) //
+ );
+
+ var balance_input = document.createElement('INPUT');
+ balance_input.setAttribute('type', 'hidden');
+ balance_input.setAttribute('name', 'balance'+<% $opt{prefix} %>rownum);
+ balance_input.setAttribute('id', 'balance'+<% $opt{prefix} %>rownum);
+ balance_input.setAttribute('rownum', <% $opt{prefix} %>rownum);
+ balance_cell.appendChild(balance_input);
+
+ row.appendChild(balance_cell);
% my $col = 0;
% foreach my $field ( @{$opt{fields}} ) {
% } else {
% $value = $param->{"$field$row"};
% }
- var my_text = document.createTextNode('<% $value %>');
+ var my_text = document.createTextNode(<% $value |js_string %>);
my_cell.appendChild(my_text);
% }
+% my $name = (ref($field) eq 'CODE') ? "column${col}_" : $field;
var my_input = document.createElement('INPUT');
- my_input.setAttribute('name', '<% $field %>'+<% $opt{prefix} %>rownum);
- my_input.setAttribute('id', '<% $field %>'+<% $opt{prefix} %>rownum);
+ my_input.setAttribute('name', '<% $name %>'+<% $opt{prefix} %>rownum);
+ my_input.setAttribute('id', '<% $name %>'+<% $opt{prefix} %>rownum);
my_input.style.textAlign = '<% $align{ $opt{align}->[$col] || 'l' } %>';
my_input.setAttribute('size', <% $sizes->[$col] || 10 %>);
-% if ($types->[$col] eq 'immutable') {
+ my_input.setAttribute('rownum', <% $opt{prefix} %>rownum);
+% if ( $types->[$col] eq 'immutable' ) {
my_input.setAttribute('type', 'hidden');
% }
-% if ( $opt{footer}->[$col] eq '_TOTAL' ) {
+% elsif ( $types->[$col] eq 'checkbox' ) {
+ my_input.setAttribute('type', 'checkbox');
+% }
+% if ( $opt{onchange}->[$col] ) {
+ my_input.onchange = <% $opt{onchange}->[$col] %>;
+% }
+% elsif ( $opt{footer}->[$col] eq '_TOTAL' ) {
my_input.onchange = <% $opt{prefix} %>calc_total<%$col%>;
my_input.onkeyup = <% $opt{prefix} %>calc_total<%$col%>;
% }
+ ' <% PL($opt{name_singular} || 'customer') %>';
}
+% if ( $opt{add_row_callback} ) {
+ <% $opt{add_row_callback} %>(<% $opt{prefix} %>rownum,
+ '<% $opt{prefix} %>');
+% }
+
<% $opt{prefix} %>rownum++;
}
<%init>
my(%opt) = @_;
+my $conf = new FS::Conf;
$opt{prefix} = '' unless defined $opt{prefix};
$opt{prefix} .= '_' if $opt{prefix};
-my $types = $opt{'types'} ? [ @{$opt{'types'}} ] : [];
+my $types = $opt{'type'} ? [ @{$opt{'type'}} ] : [];
my $sizes = $opt{'size'} ? [ @{$opt{'size'}} ] : [];
my $param = $opt{param};
'c' => 'center',
);
+my $money_char = $conf->config('money_char') || '$';
</%init>