'accountcode', #Account number
skip(2), #SERVICE LOC / BILL NUMBER
sub { my($cdr, $date) = @_;
-
+ $date;
}, #date
sub { my($cdr, $time) = @_;
# add part_svc_column records
my $svcdb = $self->svcdb;
-# my @rows = map { /^${svcdb}__(.*)$/; $1 }
-# grep ! /_flag$/,
-# grep /^${svcdb}__/,
-# fields('part_svc');
- foreach my $field (
- grep { $_ ne 'svcnum'
- && ( defined( $self->getfield($svcdb.'__'.$_.'_flag') )
- || defined($self->getfield($svcdb.'__'.$_.'_required'))
- || $self->getfield($svcdb.'__'.$_.'_label') !~ /^\s*$/ )
- } (fields($svcdb), @fields)
- ) {
- my $part_svc_column = $self->part_svc_column($field);
- my $previous = qsearchs('part_svc_column', {
- 'svcpart' => $self->svcpart,
- 'columnname' => $field,
- } );
+ foreach my $field (fields($svcdb), @fields) {
+ next if $field eq 'svcnum';
+ my $prefix = $svcdb.'__';
+ if ( defined( $self->getfield($prefix.$_.'_flag'))
+ or defined($self->getfield($prefix.$_.'_required'))
+ or length($self->getfield($prefix.$_.'_label'))
+ ) {
+ my $part_svc_column = $self->part_svc_column($field);
+ my $previous = qsearchs('part_svc_column', {
+ 'svcpart' => $self->svcpart,
+ 'columnname' => $field,
+ } );
- my $flag = $self->getfield($svcdb.'__'.$field.'_flag');
- my $label = $self->getfield($svcdb.'__'.$field.'_label');
- my $required = $self->getfield($svcdb.'__'.$field.'_required') ? 'Y' : '';
- if ( uc($flag) =~ /^([A-Z])$/ || $label !~ /^\s*$/ ) {
-
- if ( uc($flag) =~ /^([A-Z])$/ ) {
- my $parser = FS::part_svc->svc_table_fields($svcdb)->{$field}->{parse}
- || sub { shift };
- $part_svc_column->setfield('columnflag', $1);
- $part_svc_column->setfield('columnvalue',
- &$parser($self->getfield($svcdb.'__'.$field))
- );
- }
+ my $flag = $self->getfield($prefix.$field.'_flag');
+ my $label = $self->getfield($prefix.$field.'_label');
+ my $required = $self->getfield($prefix.$field.'_required') ? 'Y' : '';
+ if ( uc($flag) =~ /^([A-Z])$/ || $label !~ /^\s*$/ ) {
- $part_svc_column->setfield('columnlabel', $label)
- if $label !~ /^\s*$/;
+ if ( uc($flag) =~ /^([A-Z])$/ ) {
+ my $parser = FS::part_svc->svc_table_fields($svcdb)->{$field}->{parse}
+ || sub { shift };
+ $part_svc_column->setfield('columnflag', $1);
+ $part_svc_column->setfield('columnvalue',
+ &$parser($self->getfield($prefix.$field))
+ );
+ }
+
+ $part_svc_column->setfield('columnlabel', $label)
+ if $label !~ /^\s*$/;
- $part_svc_column->setfield('required', $required);
+ $part_svc_column->setfield('required', $required);
+
+ if ( $previous ) {
+ $error = $part_svc_column->replace($previous);
+ } else {
+ $error = $part_svc_column->insert;
+ }
- if ( $previous ) {
- $error = $part_svc_column->replace($previous);
} else {
- $error = $part_svc_column->insert;
+ $error = $previous ? $previous->delete : '';
+ }
+ if ( $error ) {
+ $dbh->rollback if $oldAutoCommit;
+ return $error;
}
- } else {
- $error = $previous ? $previous->delete : '';
- }
- if ( $error ) {
- $dbh->rollback if $oldAutoCommit;
- return $error;
}
-
}
# add export_svc records
# maintain part_svc_column records
my $svcdb = $new->svcdb;
- foreach my $field (
- grep { $_ ne 'svcnum'
- && ( defined( $new->getfield($svcdb.'__'.$_.'_flag') )
- || defined($new->getfield($svcdb.'__'.$_.'_required'))
- || $new->getfield($svcdb.'__'.$_.'_label') !~ /^\s*$/ )
- } (fields($svcdb),@fields)
- ) {
-
- my $part_svc_column = $new->part_svc_column($field);
- my $previous = qsearchs('part_svc_column', {
- 'svcpart' => $new->svcpart,
- 'columnname' => $field,
- } );
-
- my $flag = $new->getfield($svcdb.'__'.$field.'_flag');
- my $label = $new->getfield($svcdb.'__'.$field.'_label');
- my $required = $new->getfield($svcdb.'__'.$field.'_required') ? 'Y' : '';
+ foreach my $field (fields($svcdb),@fields) {
+ next if $field eq 'svcnum';
+ my $prefix = $svcdb.'__';
+ if ( defined( $new->getfield($prefix.$_.'_flag'))
+ or defined($new->getfield($prefix.$_.'_required'))
+ or length($new->getfield($prefix.$_.'_label'))
+ ) {
+ my $part_svc_column = $new->part_svc_column($field);
+ my $previous = qsearchs('part_svc_column', {
+ 'svcpart' => $new->svcpart,
+ 'columnname' => $field,
+ } );
+
+ my $flag = $new->getfield($svcdb.'__'.$field.'_flag');
+ my $label = $new->getfield($svcdb.'__'.$field.'_label');
+ my $required = $new->getfield($svcdb.'__'.$field.'_required') ? 'Y' : '';
- if ( uc($flag) =~ /^([A-Z])$/ || $label !~ /^\s*$/ ) {
-
- if ( uc($flag) =~ /^([A-Z])$/ ) {
- $part_svc_column->setfield('columnflag', $1);
- my $parser = FS::part_svc->svc_table_fields($svcdb)->{$field}->{parse}
- || sub { shift };
- $part_svc_column->setfield('columnvalue',
- &$parser($new->getfield($svcdb.'__'.$field))
- );
- } else {
- $part_svc_column->setfield('columnflag', '');
- $part_svc_column->setfield('columnvalue', '');
- }
+ if ( uc($flag) =~ /^([A-Z])$/ || $label !~ /^\s*$/ ) {
+
+ if ( uc($flag) =~ /^([A-Z])$/ ) {
+ $part_svc_column->setfield('columnflag', $1);
+ my $parser = FS::part_svc->svc_table_fields($svcdb)->{$field}->{parse}
+ || sub { shift };
+ $part_svc_column->setfield('columnvalue',
+ &$parser($new->getfield($svcdb.'__'.$field))
+ );
+ } else {
+ $part_svc_column->setfield('columnflag', '');
+ $part_svc_column->setfield('columnvalue', '');
+ }
- $part_svc_column->setfield('columnlabel', $label)
- if $label !~ /^\s*$/;
+ $part_svc_column->setfield('columnlabel', $label)
+ if $label !~ /^\s*$/;
- $part_svc_column->setfield('required', $required);
+ $part_svc_column->setfield('required', $required);
- if ( $previous ) {
- $error = $part_svc_column->replace($previous);
+ if ( $previous ) {
+ $error = $part_svc_column->replace($previous);
+ } else {
+ $error = $part_svc_column->insert;
+ }
} else {
- $error = $part_svc_column->insert;
+ $error = $previous ? $previous->delete : '';
+ }
+ if ( $error ) {
+ $dbh->rollback if $oldAutoCommit;
+ return $error;
}
- } else {
- $error = $previous ? $previous->delete : '';
- }
- if ( $error ) {
- $dbh->rollback if $oldAutoCommit;
- return $error;
}
}
=cut
my $svc_defs;
+my $svc_info;
sub _svc_defs {
return $svc_defs if $svc_defs; #cache
sort { $info{$a}->{'display_weight'} <=> $info{$b}->{'display_weight'} }
keys %info,
;
-
+
+ tie my %svc_info, 'Tie::IxHash',
+ map { $_ => $info{$_} }
+ sort { $info{$a}->{'display_weight'} <=> $info{$b}->{'display_weight'} }
+ keys %info,
+ ;
+
+ $svc_info = \%svc_info; #access via svc_table_info
$svc_defs = \%svc_defs; #cache
}
$def;
}
+=item svc_table_info TABLE
+
+Returns table_info for TABLE from cache, or empty
+hashref if none is found.
+
+Caution: caches table_info for ALL services when run;
+access a service's table_info directly unless you know
+you're loading them all.
+
+Caution: does not standardize fields into hashrefs;
+use L</svc_table_fields> to access fields.
+
+=cut
+
+sub svc_table_info {
+ my $class = shift;
+ my $table = shift;
+ $class->_svc_defs; #creates cache if needed
+ return $svc_info->{$table} || {};
+}
+
=back
=head1 SUBROUTINES
my $required = {};
my $labels = {};
my $tinfo = $self->can('table_info') ? $self->table_info : {};
- my $fields = $tinfo->{'fields'} || {};
- foreach my $field (keys %$fields) {
- if (ref($fields->{$field}) && $fields->{$field}->{'required'}) {
- $required->{$field} = 1;
- $labels->{$field} = $fields->{$field}->{'label'};
+ if ($tinfo->{'manual_require'}) {
+ my $fields = $tinfo->{'fields'} || {};
+ foreach my $field (keys %$fields) {
+ if (ref($fields->{$field}) && $fields->{$field}->{'required'}) {
+ $required->{$field} = 1;
+ $labels->{$field} = $fields->{$field}->{'label'};
+ }
}
- }
- # add fields marked as required in database
- foreach my $column (
- qsearch('part_svc_column',{
- 'svcpart' => $self->svcpart,
- 'required' => 'Y'
- })
- ) {
- $required->{$column->columnname} = 1;
- $labels->{$column->columnname} = $column->columnlabel;
- }
- # do the actual checking
- foreach my $field (keys %$required) {
- unless ($self->$field) {
- my $name = $labels->{$field} || $field;
- return "Field $name is required\n"
+ # add fields marked as required in database
+ foreach my $column (
+ qsearch('part_svc_column',{
+ 'svcpart' => $self->svcpart,
+ 'required' => 'Y'
+ })
+ ) {
+ $required->{$column->columnname} = 1;
+ $labels->{$column->columnname} = $column->columnlabel;
+ }
+ # do the actual checking
+ foreach my $field (keys %$required) {
+ unless (length($self->get($field)) > 0) {
+ my $name = $labels->{$field} || $field;
+ return "Field $name is required\n"
+ }
}
}
'display_weight' => 10,
'cancel_weight' => 50,
'ip_field' => 'slipip',
+ 'manual_require' => 1,
'fields' => {
'dir' => 'Home directory',
'uid' => {
'display_weight' => 50,
'cancel_weight' => 70,
'ip_field' => 'ip_addr',
+ 'manual_require' => 1,
'fields' => {
'svcnum' => 'Service',
'description' => 'Descriptive label',
'name' => 'Dish service',
'display_weight' => 58,
'cancel_weight' => 85,
+ 'manual_require' => 1,
'fields' => {
'svcnum' => { label => 'Service' },
- 'acctnum' => { label => 'DISH account#', %opts },
+ 'acctnum' => { label => 'DISH account#', required => 1, %opts },
'installdate' => { label => 'Install date', %opts },
'note' => { label => 'Installation notes', %opts },
}
'display_weight' => 20,
'cancel_weight' => 60,
'fields' => {
- 'domain' => {
- label => 'Domain',
- required => 1,
- },
+ 'domain' => 'Domain',
'parent_svcnum' => {
label => 'Parent domain / Communigate administrator domain',
type => 'select',
'name_plural' => 'Hardware',
'display_weight' => 59,
'cancel_weight' => 86,
+ 'manual_require' => 1,
'fields' => {
'svcnum' => { label => 'Service' },
'typenum' => { label => 'Device type',
disable_fixed => 1,
disable_default => 1,
disable_inventory => 1,
+ required => 1,
},
'serial' => { label => 'Serial number', %opts },
'hw_addr' => { label => 'Hardware address', %opts },
% 'value' => $opt{curr_value},
% 'label' => $label,
% 'noinit' => $f->{noinit},
+% 'required' => $f->{'required'},
% }
% );
% }
<TH BGCOLOR="#cccccc">Field</TH>
<TH BGCOLOR="#cccccc">Label</TH>
<TH BGCOLOR="#cccccc" COLSPAN=2>Modifier</TH>
- <TH BGCOLOR="#cccccc">Required?</TH>
+ <TH BGCOLOR="#cccccc"><% $manual_require ? 'Required?' : '' %></TH>
</TR>
% $part_svc->set('svcpart' => $opt{'clone'}) if $opt{'clone'}; # for now
% my $i = 0;
% }
</TD>
<TD>
-% if (!$def->{'type'} || !(grep {$_ eq $def->{'type'}} ('checkbox','disabled'))) {
+% if ($manual_require &&
+% (!$def->{'type'} || !(grep {$_ eq $def->{'type'}} ('checkbox','disabled')))
+% ) {
<INPUT ID="<% $name.'_required' %>" TYPE="checkbox" NAME="<% $svcdb %>__<% $field %>_required" VALUE="Y"
<% ($part_svc_column->required || $def->{'required'}) ? 'CHECKED' : '' %>
<% $def->{'required'} ? 'DISABLED' : '' %>
}
my @defs = map { FS::part_svc->svc_table_fields($svcdb)->{$_} } @fields;
+my $manual_require = FS::part_svc->svc_table_info($svcdb)->{'manual_require'};
</%init>
my $columndef = $part_svc->part_svc_column($f->{'field'});
my $flag = $columndef->columnflag;
+ $f->{'required'} = 1
+ if $columndef->required;
+
if ( $flag eq 'F' ) { #fixed
$f->{'value'} = $columndef->columnvalue;
if (length($columndef->columnvalue)) {
<TD BGCOLOR="#eeeeee"><% $part_svc->svc %></TD>
</TR>
-<TR>
- <TD ALIGN="right"><% mt('Username') |h %></TD>
+<% include('/elements/tr-td-label.html',
+ 'label' => mt('Username'),
+ 'required' => $part_svc->part_svc_column('username')->required ) %>
% if ( $svcnum && $conf->exists('svc_acct-no_edit_username') ) {
<TD BGCOLOR="#eeeeee"><% $svc_acct->username() %></TD>
<INPUT TYPE="hidden" NAME="username" VALUE="<% $username %>">
</TR>
%if ( $part_svc->part_svc_column('_password')->columnflag ne 'F' ) {
-<TR>
% #XXX eventually should require "Edit Password" ACL
- <TD ALIGN="right"><% mt('Password') |h %></TD>
+<% include('/elements/tr-td-label.html',
+ 'label' => mt('Password'),
+ 'required' => $part_svc->part_svc_column('_password')->required ) %>
<TD>
<INPUT TYPE="text" ID="clear_password" NAME="clear_password" VALUE="<% $password %>" SIZE=<% $pmax2 %> MAXLENGTH=<% $pmax %>>
<& /elements/random_pass.html, 'clear_password' &>
%if ( $conf->exists('security_phrase')
% && $part_svc->part_svc_column('sec_phrase')->columnflag ne 'F' ) {
- <TR>
- <TD ALIGN="right"><% mt('Security phrase') |h %></TD>
+<% include('/elements/tr-td-label.html',
+ 'label' => mt('Security phrase'),
+ 'required' => $part_svc->part_svc_column('sec_phrase')->required ) %>
<TD>
<INPUT TYPE="text" NAME="sec_phrase" VALUE="<% $sec_phrase %>" SIZE=32>
(<% mt('for forgotten passwords') |h %>)
% )
% );
- <TR>
- <TD ALIGN="right"><% mt('Domain') |h %></TD>
+<% include('/elements/tr-td-label.html',
+ 'label' => mt('Domain'),
+ 'required' => $part_svc->part_svc_column('domsvc')->required ) %>
<TD>
<SELECT NAME="domsvc" SIZE=1>
% foreach my $svcnum (
<INPUT TYPE="hidden" NAME="popnum" VALUE="<% $popnum %>">
% } else {
- <TR>
- <TD ALIGN="right"><% mt('Access number') |h %></TD>
+<% include('/elements/tr-td-label.html',
+ 'label' => mt('Access number'),
+ 'required' => $part_svc->part_svc_column('popnum')->required ) %>
<TD><% FS::svc_acct_pop::popselector($popnum) %></TD>
</TR>
% }
'curr_value' => $svc_acct->sectornum,
#'part_svc' => $part_svc,
#'cust_pkg' => $cust_pkg,
+ 'required' => $part_svc->part_svc_column('sectornum')->required,
&>
%} else {
<INPUT TYPE="hidden" NAME="sectornum" VALUE="<% $svc_acct->sectornum %>">
%
% if ( length($svc_acct->$xid()) ) {
+<% include('/elements/tr-td-label.html',
+ 'label' => uc($xid),
+ 'required' => $part_svc->part_svc_column($xid)->required ) %>
<TR>
<TD ALIGN="right"><% uc($xid) %></TD>
<TD BGCOLOR="#eeeeee"><% $svc_acct->$xid() %></TD>
<INPUT TYPE="hidden" NAME="<% $xid %>" VALUE="<% $svc_acct->$xid() %>">
% } else {
- <TR>
- <TD ALIGN="right"><% uc($xid) %></TD>
+<% include('/elements/tr-td-label.html',
+ 'label' => uc($xid),
+ 'required' => $part_svc->part_svc_column($xid)->required ) %>
<TD>
<INPUT TYPE="text" NAME="<% $xid %>" SIZE=8 MAXLENGTH=6 VALUE="<% $svc_acct->$xid() %>">
</TD>
% } else {
- <TR>
- <TD ALIGN="right"><% mt('Real Name') |h %></TD>
+<% include('/elements/tr-td-label.html',
+ 'label' => mt('Real Name'),
+ 'required' => $part_svc->part_svc_column('finger')->required ) %>
<TD>
<INPUT TYPE="text" NAME="finger" VALUE="<% $svc_acct->finger %>">
</TD>
% } else {
- <TR>
- <TD ALIGN="right"><% mt('Home directory') |h %></TD>
+<% include('/elements/tr-td-label.html',
+ 'label' => mt('Home directory'),
+ 'required' => $part_svc->part_svc_column('dir')->required ) %>
<TD><INPUT TYPE="text" NAME="dir" VALUE="<% $svc_acct->dir %>"></TD>
</TR>
% }
% } else {
- <TR>
- <TD ALIGN="right"><% mt('Shell') |h %></TD>
+<% include('/elements/tr-td-label.html',
+ 'label' => mt('Shell'),
+ 'required' => $part_svc->part_svc_column('shell')->required ) %>
<TD>
<SELECT NAME="shell" SIZE=1>
%
% # (should we show this if slipip is fixed?)
<& /elements/tr-select-router_block_ip.html,
'object' => $svc_acct,
- 'ip_field' => 'slipip'
+ 'ip_field' => 'slipip',
+ 'required' => $part_svc->part_svc_column('routernum')->required,
+ 'ip_addr_required' => $part_svc->part_svc_column('slipip')->required,
&>
% } else {
% # don't expose these to the user--they're only useful in the other case
% if ( $part_svc->part_svc_column('slipip')->columnflag =~ /^[FA]$/ ) {
<INPUT TYPE="hidden" NAME="slipip" VALUE="<% $svc_acct->slipip %>">
% } else {
- <TR>
- <TD ALIGN="right"><% mt('IP') |h %></TD>
+<% include('/elements/tr-td-label.html',
+ 'label' => mt('IP'),
+ 'required' => $part_svc->part_svc_column('slipip')->required ) %>
<TD><INPUT TYPE="text" NAME="slipip" VALUE="<% $svc_acct->slipip %>"></TD>
</TR>
% }
% }
-<TR>
- <TD ALIGN="right"><% mt('RADIUS groups') |h %></TD>
+<% include('/elements/tr-td-label.html',
+ 'label' => mt('RADIUS groups'),
+ 'required' => $part_svc->part_svc_column('usergroup')->required ) %>
% if ( $part_svc_usergroup->columnflag eq 'F' ) {
<TD BGCOLOR="#eeeeee"><% join('<BR>', @groupnames) %></TD>
% } else {
<INPUT TYPE="hidden" NAME="quota" VALUE="<% $svc_acct->quota %>">
% } else {
% my $quota_label = $communigate ? 'Mail storage limit' : 'Quota';
- <TR>
- <TD ALIGN="right"><% $quota_label %></TD>
+<% include('/elements/tr-td-label.html',
+ 'label' => $quota_label,
+ 'required' => $part_svc->part_svc_column('quota')->required ) %>
<TD><INPUT TYPE="text" NAME="quota" VALUE="<% $svc_acct->quota %>"></TD>
</TR>
% }
my @fields = (
qw( description speed_down speed_up ),
{ field=>'sectornum', type=>'select-tower_sector', },
- { field=>'routernum', type=>'select-router_block_ip' },
+ { field=>'routernum', type=>'select-router_block_ip',
+ include_opt_callback => sub {
+ my $svc_broadband = shift;
+ my $part_svc = $svc_broadband->part_svc;
+ return () unless $part_svc; #sanity check
+ my $col = $part_svc->part_svc_column('ip_addr');
+ return () unless $col; #sanity check
+ return ('ip_addr_required' => $col->required);
+ },
+ },
{ field=>'mac_addr' , type=>'input-mac_addr' },
qw(
latitude longitude altitude
'usedatetime' => 1, #use DateTime->strftime to format the date
# instead of Date::Format->time2str
'noinit' => 1, #first one on the page is enough
+ 'required' => 1,
},
&>
<SCRIPT TYPE="text/javascript" SRC="<%$fsurl%>elements/calendar-setup.js"></SCRIPT>
% }
-<TR>
- <TD ALIGN="right"><% $label %></TD>
+<% include('/elements/tr-td-label.html',
+ 'label' => $label,
+ 'required' => $required ) %>
<TD COLSPAN=<% $colspan %>>
<INPUT TYPE="text" NAME="<% $name %>" ID="<% $name %>_text" VALUE="<% $value %>">
<IMG SRC="<%$fsurl%>images/calendar.png" ID="<% $name %>_button" STYLE="cursor: pointer" TITLE="<% mt('Select date') |h %>">
<%init>
-my($name, $value, $label, $format, $usedatetime, $noinit, $colspan);
+my($name, $value, $label, $format, $usedatetime, $noinit, $colspan, $required);
if ( ref($_[0]) ) {
my $opt = shift;
$name = $opt->{'name'};
$usedatetime = $opt->{'usedatetime'};
$noinit = $opt->{'noinit'};
$colspan = $opt->{'colspan'} || 1;
+ $required = $opt->{'required'};
} else {
($name, $value, $label, $format, $usedatetime) = @_;
$colspan = 1;
-<TR>
- <TD ALIGN="right"><% $opt{'label'} || 'Device type: ' %></TD>
+<% include('/elements/tr-td-label.html',
+ 'label' => $opt{'label'} || 'Device type: ',
+ 'required' => $opt{'required'} ) %>
<TD><% include('select-hardware_type.html', %opt) %></TD>
</TR>
what.value = '';
}
</script>
-<& /elements/tr-td-label.html, label => ($opt{'label'} || 'Router') &>
+<& /elements/tr-td-label.html, label => ($opt{'label'} || 'Router'), required => $opt{'required'} &>
<td>
<& /elements/select-tiered.html, prefix => 'router_', tiers => [
{
]
&>
</td></tr>
-<& /elements/tr-td-label.html, label => 'IP address' &>
+<& /elements/tr-td-label.html, label => 'IP address', required => $opt{'ip_addr_required'} &>
<td>
-% warn Dumper \%fixed;
+% #warn Dumper \%fixed;
% if ( exists $fixed{$ip_field} ) {
<input type="hidden" id="input_ip_addr" name="<% $ip_field %>"
value="<% $opt{'ip_addr'} |h%>"><% $opt{'ip_addr'} || '' %>
enable_fuzzy_on_exact
disable_html_editor disable_enter_submit_onetimecharge
enable_mask_clipboard_hack dashboard_customers
+ customer_view_emails
email_address
snom-ip snom-username snom-password
vonage-fromnumber vonage-username vonage-password
</TD>
</TR>
+ <TR>
+ <TH ALIGN="right">How many recent outbound emails to show in customer view</TH>
+ <TD ALIGN="left" COLSPAN=2>
+ <INPUT TYPE="text" NAME="customer_view_emails" VALUE="<% $curuser->option('customer_view_emails') %>"></TD>
+ </TD>
+ </TR>
+
+
+
</TABLE>
<BR>
],
'html_init' => $html_init,
'really_disable_download' => 1,
- @_ #why?
+ 'order_by' => '_date DESC',
&>
<%init>
#hmm...
}
#order by override
-my $order_by = '';
-#if ( $cgi->param('order_by') =~ /^([\w\, ]+)$/ ) {
-# $order_by = $1;
-#}
+my $order_by = $opt{order_by} || '';
$order_by = $cgi->param('order_by') if $cgi->param('order_by');
# run the query
}
}
+ $opt{query}->{'order_by'} .= " $limit";
+
} elsif (ref($opt{query}) eq 'ARRAY') {
@query = @{ $opt{query} };
} else {
}
@query
],
- 'order_by' => $opt{order_by}. " ". $limit,
+ #'order_by' => $opt{order_by}. " ". $limit,
)
];
} else {
% if ( $curuser->access_right('View email logs')
% and FS::cust_msg->count("custnum = $custnum")) {
<BR>
-% if (!$cgi->param('order_by')) {
-% my $order_by = '_date';
-% $order_by .= ' DESC' if $curuser->option('history_order') eq 'newest';
-% $cgi->param('order_by', $order_by);
-% }
-<& /search/cust_msg.html,
- nohtmlheader => 1,
- html_init => mt('Mail sent to this customer: '),
-&>
+<& notes/email.html, 'cust_main' => $cust_main &>
+<BR>
% }
<%init>
--- /dev/null
+% if ( scalar(@rows) ) {
+<STYLE type="text/css">
+#cust_msg td.grid a:link {text-decoration: none}
+#cust_msg td.grid a:visited {text-decoration: none}
+#cust_msg td.grid a:hover {text-decoration: underline}
+#cust_msg th {background-color: #cccccc}
+.row0 {background-color: #eeeeee}
+.row1 {background-color: #ffffff}
+</STYLE>
+<DIV id="cust_msg">
+<FONT SIZE="+1"> <% mt('Email sent to this customer') %> </FONT><BR>
+% if ($maxrecords < $total) {
+<% mt('Showing [_1] most recent of [quant,_2,total message]', $maxrecords, $total) %>
+ <A HREF="<%$p%>search/cust_msg.html?custnum=<%$custnum%>">
+ <i>(<% mt('view all') %>)</i>
+ </A>
+% } else {
+<% mt('[quant,_1,total message]', $total) %>
+% }
+<BR>
+<& /elements/table-grid.html &>
+ <TR>
+ <TH CLASS="grid"><% mt('Date') %></TH>
+ <TH CLASS="grid"><% mt('Type') %></TH>
+ <TH CLASS="grid"><% mt('Destination') %></TH>
+ <TH CLASS="grid"><% mt('Subject') %></TH>
+ <TH CLASS="grid"></TH>
+ </TR>
+% my $i = 0;
+% foreach my $row (@rows) {
+% my $onclick = $sub_popup_link->($row);
+% my $link = qq!<A onclick="$onclick">!;
+ <TR CLASS="row<%$i%>">
+ <TD CLASS="grid"><% $link %>
+ <% $row->_date ? time2str('%Y-%m-%d %T', $row->_date) : '' %>
+ </A></TD>
+ <TD CLASS="grid" STYLE="color: <% $typecolor->($row) %>"><% $link %>
+ <% ucfirst($row->msgtype) || $row->msgname %>
+ </A></TD>
+ <TD CLASS="grid"><% $link %>
+ <% join('<BR>', split(/,\s*/, $row->env_to)) %>
+ </A></TD>
+ <TD CLASS="grid" STYLE="color: <% $statuscolor->($row) %>">
+ <% $row->status %>
+ </TD>
+ <TD CLASS="grid">
+ <% $row->error |h %>
+ </TD>
+ </TR>
+% $i = 1 - $i;
+% }
+</TABLE>
+</DIV>
+% }
+<%init>
+my %opt = @_;
+
+my $curuser = $FS::CurrentUser::CurrentUser;
+my $cust_main = $opt{'cust_main'}
+ or die "cust_main required";
+my $custnum = $cust_main->custnum;
+
+my $where = "WHERE cust_msg.custnum = $custnum";
+my $maxrecords = $curuser->option('customer_view_emails') || 10;
+
+my $order_by = '_date DESC';
+
+my $query = {
+ 'table' => 'cust_msg',
+ 'select' => join(', ',
+ 'cust_msg.*',
+ 'msg_template.msgname',
+ ),
+ 'addl_from' => ' LEFT JOIN msg_template USING ( msgnum ) ',
+ 'hashref' => {},
+ 'extra_sql' => $where,
+ 'order_by' => "ORDER BY $order_by LIMIT $maxrecords",
+};
+my $count_query = "SELECT COUNT(*) FROM cust_msg $where";
+
+my @rows = qsearch($query);
+my $total = FS::Record->scalar_sql($count_query);
+
+my $sub_popup_link = sub {
+ my $custmsgnum = $_[0]->custmsgnum;
+ include('/elements/popup_link_onclick.html',
+ 'action' => $p. 'view/cust_msg.html?' . $custmsgnum,
+ 'actionlabel' => 'Message detail',
+ 'width' => 680,
+ 'height' => 550,
+ );
+};
+
+my %color = (
+ 'failed' => '#FF0000',
+ 'sent' => '#000000',
+
+ 'invoice' => '#00CC00',
+ 'receipt' => '#0000CC',
+ 'admin' => '#CC0000',
+ '' => '#000000',
+);
+my $statuscolor = sub { $color{$_[0]->status} };
+my $typecolor = sub { $color{$_[0]->msgtype} };
+
+</%init>