From 83f70978574fef3401020cb11cf651d12c139b3b Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Sat, 24 Mar 2012 18:47:07 -0700 Subject: [PATCH] better display/edit of contacts on customer view, RT#16819 --- FS/FS/cust_main.pm | 1 + httemplate/edit/cust_main-contacts.html | 100 ++++++++++++++++++++ httemplate/edit/process/cust_main-contacts.html | 20 ++++ httemplate/edit/process/elements/process.html | 96 ++++++++++--------- httemplate/elements/freeside.css | 30 +++++- httemplate/view/cust_main.cgi | 5 + httemplate/view/cust_main/billing.html | 16 ++-- httemplate/view/cust_main/contacts.html | 119 ++++++++++++------------ httemplate/view/cust_main/contacts_new.html | 37 +++++++- httemplate/view/cust_main/misc.html | 4 +- 10 files changed, 310 insertions(+), 118 deletions(-) create mode 100644 httemplate/edit/cust_main-contacts.html create mode 100644 httemplate/edit/process/cust_main-contacts.html diff --git a/FS/FS/cust_main.pm b/FS/FS/cust_main.pm index 069d5b6aa..7d1a15621 100644 --- a/FS/FS/cust_main.pm +++ b/FS/FS/cust_main.pm @@ -8,6 +8,7 @@ use base qw( FS::cust_main::Packages FS::cust_main::Status FS::cust_main::Billing_Discount FS::otaker_Mixin FS::payinfo_Mixin FS::cust_main_Mixin FS::geocode_Mixin + FS::o2m_Common FS::Record ); use vars qw( $DEBUG $me $conf diff --git a/httemplate/edit/cust_main-contacts.html b/httemplate/edit/cust_main-contacts.html new file mode 100644 index 000000000..bae58bd33 --- /dev/null +++ b/httemplate/edit/cust_main-contacts.html @@ -0,0 +1,100 @@ +<% include('elements/edit.html', + 'name_singular' => 'customer contacts', #yes, we're editing all of them + 'table' => 'cust_main', + 'post_url' => popurl(1). 'process/cust_main-contacts.html', + 'labels' => { 'custnum' => ' ', #XXX supress this line entirely, its being redundant + 'contactnum' => 'Contact', + #'locationnum' => ' ', + }, + 'fields' => [ + { 'field' => 'contactnum', + 'type' => 'contact', + 'colspan' => 6, + 'm2m_method' => 'cust_contact', + 'm2m_dstcol' => 'contactnum', + 'm2_label' => 'Contact', + 'm2_error_callback' => $m2_error_callback, + }, + ], + #'new_callback' => $new_callback, + #'edit_callback' => $edit_callback, + #'error_callback' => $error_callback, + 'agent_virt' => 1, + 'menubar' => [], #remove "view all" link + + #XXX it would be nice if this could instead be after the error but before + # the table + 'html_init' => include('/elements/small_custview.html', + $custnum, + $conf->config('countrydefault') || 'US', + 1, #no balance + ), + ) +%> +<%init> + +my $curuser = $FS::CurrentUser::CurrentUser; +my $conf = new FS::Conf; + +my $custnum; +if ( $cgi->param('error') ) { + $custnum = scalar($cgi->param('custnum')); + + die "access denied" + unless $curuser->access_right(($custnum ? 'Edit' : 'New'). ' customer'); #contacts? + +} elsif ( $cgi->keywords ) { #editing + $custnum = ($cgi->keywords)[0]; + + die "access denied" + unless $curuser->access_right('Edit customer'); + +} else { #new customer + + #this doesn't really work here, we're an edit only + die "guru meditation #32"; + + die "access denied" + unless $curuser->access_right('New customer'); + +} + +#my $new_callback = sub { +# my( $cgi, $prospect_main, $fields_listref, $opt_hashref ) = @_; +#}; + +#my $edit_callback = sub { +# my( $cgi, $prospect_main, $fields_listref, $opt_hashref ) = @_; +#}; + +#my $error_callback = sub { +# my( $cgi, $prospect_main, $fields_listref, $opt_hashref ) = @_; +#}; + +my $m2_error_callback = sub { + my($cgi, $object) = @_; + + #process_o2m fields in process/cust_main-contacts.html + my @fields = qw( first last title comment ); + my @gfields = ( '', map "_$_", @fields ); + + map { + if ( /^contactnum(\d+)$/ ) { + my $num = $1; + if ( grep $cgi->param("contactnum$num$_"), @gfields ) { + my $x = new FS::contact { + 'contactnum' => scalar($cgi->param("contactnum$num")), + map { $_ => scalar($cgi->param("contactnum${num}_$_")) } @fields, + }; + $x; + } else { + (); + } + } else { + (); + } + } + $cgi->param; +}; + + diff --git a/httemplate/edit/process/cust_main-contacts.html b/httemplate/edit/process/cust_main-contacts.html new file mode 100644 index 000000000..ed874a55e --- /dev/null +++ b/httemplate/edit/process/cust_main-contacts.html @@ -0,0 +1,20 @@ +<% include('elements/process.html', + 'table' => 'cust_main', + 'error_redirect' => popurl(3). 'edit/cust_main-contacts.html?', + 'agent_virt' => 1, + 'skip_process' => 1, #we don't want to make any changes to cust_main + 'process_o2m' => { + 'table' => 'contact', + 'fields' => \@contact_fields, + }, + 'redirect' => popurl(3). 'view/cust_main.cgi?', + ) +%> +<%init> + +my @contact_fields = qw( classnum first last title comment emailaddress ); +foreach my $phone_type ( qsearch({table=>'phone_type', order_by=>'weight'}) ) { + push @contact_fields, 'phonetypenum'.$phone_type->phonetypenum; +} + + diff --git a/httemplate/edit/process/elements/process.html b/httemplate/edit/process/elements/process.html index 636bae0ce..12b3bd94b 100644 --- a/httemplate/edit/process/elements/process.html +++ b/httemplate/edit/process/elements/process.html @@ -62,6 +62,10 @@ Example: 'fields' => [qw( fieldname fieldname2 )], }, + 'skip_process' => 0, #boolean, if set true, will skip the main table + #add/edit processing and only run any linked table + #process_ items + #checks CGI params and whatever else before much else runs #return an error string or empty for no error 'precheck_callback' => sub { my( $cgi ) = @_; }, @@ -204,62 +208,71 @@ my $new; my $new_pkey = ''; foreach my $value ( @values ) { - $new = $class->new( \%hash ); + if ($opt{'skip_process'}) { + + $new = $old; + $new_pkey = $old_pkey; + + } else { + + $new = $class->new( \%hash ); - $new->$bfield($value) if $bfield; + $new->$bfield($value) if $bfield; - if ($old && exists($opt{'copy_on_empty'})) { - foreach my $field (@{$opt{'copy_on_empty'}}) { - $new->set($field, $old->get($field)) - unless scalar($cgi->param($field)); + if ($old && exists($opt{'copy_on_empty'})) { + foreach my $field (@{$opt{'copy_on_empty'}}) { + $new->set($field, $old->get($field)) + unless scalar($cgi->param($field)); + } } - } - if ( $opt{'agent_virt'} ) { + if ( $opt{'agent_virt'} ) { - if ( ! $new->agentnum - && ( ! $opt{'agent_null_right'} - || ! $curuser->access_right($opt{'agent_null_right'}) - ) - ) - { + if ( ! $new->agentnum + && ( ! $opt{'agent_null_right'} + || ! $curuser->access_right($opt{'agent_null_right'}) + ) + ) + { - $error ||= 'Select an agent'; + $error ||= 'Select an agent'; - } else { + } else { - die "illegal agentnum" - unless $curuser->agentnums_href->{$new->agentnum} - or $curuser->access_right('View customers of all agents') - or $opt{'agent_null_right'} - && ! $new->agentnum - && $curuser->access_right($opt{'agent_null_right'}); + die "illegal agentnum" + unless $curuser->agentnums_href->{$new->agentnum} + or $curuser->access_right('View customers of all agents') + or $opt{'agent_null_right'} + && ! $new->agentnum + && $curuser->access_right($opt{'agent_null_right'}); - } + } - } + } - $error ||= $new->check; + $error ||= $new->check; - my @args = (); - if ( !$error && $opt{'args_callback'} ) { - @args = &{ $opt{'args_callback'} }( $cgi, $new ); - } + my @args = (); + if ( !$error && $opt{'args_callback'} ) { + @args = &{ $opt{'args_callback'} }( $cgi, $new ); + } - if ( !$error && $opt{'debug'} ) { - warn "$me updating record in $table table using $class class\n"; - warn Dumper(\%hash); - warn "with args: \n". Dumper(\@args) if @args; - } + if ( !$error && $opt{'debug'} ) { + warn "$me updating record in $table table using $class class\n"; + warn Dumper(\%hash); + warn "with args: \n". Dumper(\@args) if @args; + } - if ( !$error ) { - if ( $old_pkey ) { - $error = $new->replace($old, @args); - } else { - $error = $new->insert(@args); + if ( !$error ) { + if ( $old_pkey ) { + $error = $new->replace($old, @args); + } else { + $error = $new->insert(@args); + } + $new_pkey = $new->getfield($pkey); } - $new_pkey = $new->getfield($pkey); - } + + } #unless $opt{'skip_process'} if ( !$error && $opt{'process_m2m'} ) { @@ -344,5 +357,4 @@ foreach my $value ( @values ) { last if $error; } - diff --git a/httemplate/elements/freeside.css b/httemplate/elements/freeside.css index 79c98cdd9..44a4a3ca2 100644 --- a/httemplate/elements/freeside.css +++ b/httemplate/elements/freeside.css @@ -115,7 +115,7 @@ a.fstab { padding-right:12px;*/ padding-left:4px; padding-right:4px; - font-size:16px; + font-size:18px; font-weight:bold; text-decoration:none; overflow:visible; @@ -148,7 +148,7 @@ a.fstabselected { padding-right:12px;*/ padding-left:4px; padding-right:4px; - font-size:16px; + font-size:18px; font-weight:bold; text-decoration:none; overflow:visible; @@ -220,6 +220,32 @@ div.fstabcontainer { font-weight:bold; } +.fsinnerbox { + background-color:#cccccc; + padding:2px; + -moz-box-shadow: 1px 1px 2px #666666; + -webkit-box-shadow: 1px 1px 2px #666666; + box-shadow: 1px 1px 2px #666666; + filter: progid:DXImageTransform.Microsoft.Shadow(color='#666666', Direction=135, Strength=2); +} + +.fsinnerbox-title { + font-size:110%; + font-weight:bold; + background-color:#cccccc; + padding:2px; + -moz-border-radius-topleft:8px; + -moz-border-radius-topright:8px; + -webkit-border-radius-topleft:8px; + -webkit-border-radius-topright:8px; + border-radius-topleft:8px; + border-radius-topright:8px; + -moz-box-shadow: 1px 0px 1px #999999; + -webkit-box-shadow: 1px 0px 1px #999999; + box-shadow: 1px 0px 1px #999999; + filter: progid:DXImageTransform.Microsoft.Shadow(color='#999999', Direction=90, Strength=1); +} + .background { background-color:#f8f8f8; } diff --git a/httemplate/view/cust_main.cgi b/httemplate/view/cust_main.cgi index dcadf9912..fda4db0d9 100755 --- a/httemplate/view/cust_main.cgi +++ b/httemplate/view/cust_main.cgi @@ -150,6 +150,11 @@ function areyousure(href, message) { + + + <& cust_main/contacts_new.html, $cust_main &> + + % } diff --git a/httemplate/view/cust_main/billing.html b/httemplate/view/cust_main/billing.html index f1add6fcc..522c6db86 100644 --- a/httemplate/view/cust_main/billing.html +++ b/httemplate/view/cust_main/billing.html @@ -1,4 +1,4 @@ -<% mt('Billing information') |h %> +<% mt('Billing information') |h %> %# If we can't see the unencrypted card, then bill now is an exercise in %# frustration (without some sort of job queue magic to send it to a secure %# machine, anyway) @@ -6,14 +6,14 @@ % && ! $cust_main->is_encrypted($cust_main->payinfo) % ) { %# (<% mt('Bill now') |h %>) - (<& /elements/bill.html, - custnum => $cust_main->custnum, - label => emt('Bill now'), - url => $p.'view/cust_main.cgi?'.$cust_main->custnum, - &>) + <& /elements/bill.html, + custnum => $cust_main->custnum, + label => emt('Bill now'), + url => $p.'view/cust_main.cgi?'.$cust_main->custnum, + &> % } -<% ntable("#cccccc") %><% ntable("#cccccc",2) %> + %( my $balance = $cust_main->balance ) % =~ s/^(\-?)(.*)$/$1<\/FONT>$money_char$2/; @@ -285,7 +285,7 @@ % } -
+ <%once> my $paystate_label = FS::Msgcat::_gettext('paystate'); diff --git a/httemplate/view/cust_main/contacts.html b/httemplate/view/cust_main/contacts.html index 68e3b17ad..b3e52b556 100644 --- a/httemplate/view/cust_main/contacts.html +++ b/httemplate/view/cust_main/contacts.html @@ -5,8 +5,8 @@ % foreach my $which ( '', 'ship_' ) { % my $pre = $cust_main->get("${which}last") ? $which : ''; -<% $which{$which} %> <% mt('address') |h %> -<% ntable("#cccccc") %><% ntable("#cccccc",2) %> +<% $which{$which} %> <% mt('address') |h %> + % } + % if ( $conf->exists('cust-email-high-visibility') && $which eq '') { - - - - + + + + % } - - - - + +% if ( $cust_main->get("${pre}company") ) { + + + + +% } + @@ -74,42 +79,30 @@ &> % } - - - - - - - - - - - - - - - - +% foreach my $phone (grep $cust_main->get($pre.$_), qw( daytime night mobile )){ + + + + + + +% } + +% if ( $cust_main->get("${pre}fax") ) { + + + + +% } + % if ( $which eq '' && $conf->exists('show_stateid') ) { @@ -118,23 +111,31 @@ % } -
<% mt('Contact name') |h %> @@ -17,18 +17,23 @@ <% $cust_main->masked('ss') || ' ' %>
<% mt('Email invoices') |h %> - <% join(', ', grep { $_ !~ /^(POST|FAX)$/ } @invoicing_list ) || $no %> -
<% mt('Email invoices') |h %> + <% join(', ', grep { $_ !~ /^(POST|FAX)$/ } @invoicing_list ) || $no %> +
<% mt('Company') |h %><% $cust_main->get("${pre}company") |h %>
<% mt('Company') |h %><% $cust_main->get("${pre}company") |h %>
<% mt('Address') |h %> <% $cust_main->get("${pre}address1") |h %>
<% $daytime_label %> - <& /elements/phonenumber.html, - $cust_main->get("${pre}daytime"), - 'callable'=>1, - 'calling_list_exempt'=>$cust_main->calling_list_exempt, - &> -
<% $night_label %> - <& /elements/phonenumber.html, - $cust_main->get("${pre}night"), - 'callable'=>1, - 'calling_list_exempt'=>$cust_main->calling_list_exempt, - &> -
<% $mobile_label %> - <& /elements/phonenumber.html, - $cust_main->get("${pre}mobile"), - 'callable'=>1, - 'calling_list_exempt'=>$cust_main->calling_list_exempt, - &> -
<% mt('Fax') |h %> - <% $cust_main->get("${pre}fax") || ' ' %> -
<% $phone_label{$phone} %> + <& /elements/phonenumber.html, + $cust_main->get($pre.$phone), + 'callable'=>1, + 'calling_list_exempt'=>$cust_main->calling_list_exempt, + &> +
<% mt('Fax') |h %> + <% $cust_main->get("${pre}fax") || ' ' %> +
<% $stateid_label %><% $cust_main->stateid_state || ' ' %>
+ + % if ( $which ne 'ship_' ) {
% } % } -<& contacts_new.html, $cust_main &> <%once> -my $daytime_label = FS::Msgcat::_gettext('daytime') =~ /^(daytime)?$/ - ? 'Day Phone' - : FS::Msgcat::_gettext('daytime'); -my $night_label = FS::Msgcat::_gettext('night') =~ /^(night)?$/ - ? 'Night Phone' - : FS::Msgcat::_gettext('night'); -my $mobile_label = FS::Msgcat::_gettext('mobile') =~ /^(mobile)?$/ - ? 'Mobile Phone' - : FS::Msgcat::_gettext('Mobile'); +my %phone_label = ( + + 'daytime' => ( FS::Msgcat::_gettext('daytime') =~ /^(daytime)?$/ + ? 'Day Phone' + : FS::Msgcat::_gettext('daytime') + ), + + 'night' => ( FS::Msgcat::_gettext('night') =~ /^(night)?$/ + ? 'Night Phone' + : FS::Msgcat::_gettext('night') + ), + + 'mobile' => ( FS::Msgcat::_gettext('mobile') =~ /^(mobile)?$/ + ? 'Mobile Phone' + : FS::Msgcat::_gettext('Mobile') + ), +); my $stateid_label = FS::Msgcat::_gettext('stateid') =~ /^(stateid)?$/ ? 'Driver’s License' diff --git a/httemplate/view/cust_main/contacts_new.html b/httemplate/view/cust_main/contacts_new.html index bd812c7e7..155490fe1 100644 --- a/httemplate/view/cust_main/contacts_new.html +++ b/httemplate/view/cust_main/contacts_new.html @@ -1,17 +1,44 @@ -% if ( @contacts ) {
-Contacts -<% ntable("#cccccc",2) %> +Contacts +Edit contacts + % foreach my $contact ( @contacts ) { +% #XXX maybe this should be a table with alternating colors instead - + + +% my @contact_email = $contact->contact_email; +% if (@contact_email) { + + +% } + +% foreach my $phone_type (@phone_type) { +% my $contact_phone = +% qsearchs('contact_phone', { +% 'contactnum' => $contact->contactnum, +% 'phonetypenum' => $phone_type->phonetypenum, +% }) +% or next; + + +% } + +% if ( $contact->comment ) { + + + +% } + % }
Contact<% $contact->contact_classname %> Contact <% $contact->line %>   Email<% join(', ', map $_->emailaddress, @contact_email) %>   <% $phone_type->typename %> phone<% $contact_phone->phonenum |h %>   Comment<% $contact->comment |h %>
+<%once> -% } +my @phone_type = qsearch({table=>'phone_type', order_by=>'weight'}); + <%init> my( $cust_main ) = @_; diff --git a/httemplate/view/cust_main/misc.html b/httemplate/view/cust_main/misc.html index 28414ef2d..295328721 100644 --- a/httemplate/view/cust_main/misc.html +++ b/httemplate/view/cust_main/misc.html @@ -1,4 +1,4 @@ -<% ntable("#cccccc") %><% &ntable("#cccccc",2) %> + @@ -150,7 +150,7 @@ <% $cust_main->pvf($_)->widget('HTML', 'view', $cust_main->getfield($_)) %> % } -
<% mt('Customer number') |h %>
+ <%init> my( $cust_main ) = @_; -- 2.11.0