RT# 82094 - updated UI for bulk emailing from advanced customer reports
[freeside.git] / FS / FS / UI / Web.pm
index 6655f27..8a1d502 100644 (file)
@@ -15,15 +15,87 @@ use FS::cust_main;  # are sql_balance and sql_date_balance in the right module?
 #@ISA = qw( FS::UI );
 @ISA = qw( Exporter );
 
-@EXPORT_OK = qw( svc_url );
+@EXPORT_OK = qw( get_page_pref set_page_pref svc_url random_id );
 
 $DEBUG = 0;
 $me = '[FS::UID::Web]';
 
+our $NO_RANDOM_IDS;
+
+###
+# user prefs
+###
+
+=item get_page_pref NAME, TABLENUM
+
+Returns the user's page preference named NAME for the current page. If the
+page is a view or edit page or otherwise shows a single record at a time,
+it should use TABLENUM to link the preference to that record.
+
+=cut
+
+sub get_page_pref {
+  my ($prefname, $tablenum) = @_;
+
+  my $m = $HTML::Mason::Commands::m
+    or die "can't get page pref when running outside the UI";
+  # what's more useful: to tie prefs to the base_comp (usually where
+  # code is executing right now), or to the request_comp (approximately the
+  # one in the URL)? not sure.
+  $FS::CurrentUser::CurrentUser->get_page_pref( $m->request_comp->path,
+                                                $prefname,
+                                                $tablenum
+                                              );
+}
+
+=item set_page_pref NAME, TABLENUM, VALUE
+
+Sets the user's page preference named NAME for the current page. Use TABLENUM
+as for get_page_pref.
+
+If VALUE is an empty string, the preference will be deleted (and
+C<get_page_pref> will return an empty string).
+
+  my $mypref = set_page_pref('mypref', '', 100);
+
+=cut
+
+sub set_page_pref {
+  my ($prefname, $tablenum, $prefvalue) = @_;
+
+  my $m = $HTML::Mason::Commands::m
+    or die "can't set page pref when running outside the UI";
+  $FS::CurrentUser::CurrentUser->set_page_pref( $m->request_comp->path,
+                                                $prefname,
+                                                $tablenum,
+                                                $prefvalue );
+}
+
 ###
 # date parsing
 ###
 
+=item parse_beginning_ending CGI [, PREFIX ]
+
+Parses a beginning/ending date range, as used on many reports. This function
+recognizes two sets of CGI params: "begin" and "end", the integer timestamp
+values, and "beginning" and "ending", the user-readable date fields.
+
+If "begin" contains an integer, that's passed through as the beginning date.
+Otherwise, "beginning" is passed to L<DateTime::Format::Natural> and turned
+into an integer. If this fails or it doesn't have a value, zero is used as the
+beginning date.
+
+The same happens for "end" and "ending", except that if "ending" contains a
+date without a time, it gets moved to the end of that day, and if there's no
+value, the value returned is the highest unsigned 32-bit time value (some time
+in 2037).
+
+PREFIX is optionally a string to prepend (with '_' as a delimiter) to the form
+field names.
+
+=cut
+
 use Date::Parse;
 sub parse_beginning_ending {
   my($cgi, $prefix) = @_;
@@ -228,7 +300,7 @@ sub cust_header {
   my %header2method = (
     'Customer'                 => 'name',
     'Cust. Status'             => 'cust_status_label',
-    'Cust#'                    => 'custnum',
+    'Cust#'                    => 'display_custnum',
     'Name'                     => 'contact',
     'Company'                  => 'company',
 
@@ -271,9 +343,16 @@ sub cust_header {
     '(service) Latitude'       => 'ship_latitude',
     '(service) Longitude'      => 'ship_longitude',
     'Invoicing email(s)'       => 'invoicing_list_emailonly_scalar',
-    'Payment Type'             => 'payby',
+    'Contact email(s)'         => 'contact_list_emailonly',
+    'Invoices'                 => 'contact_list_cust_invoice_only',
+    'Messages'                 => 'contact_list_cust_message_only',
+# FS::Upgrade::upgrade_config removes this from existing cust-fields settings
+#    'Payment Type'             => 'cust_payby',
     'Current Balance'          => 'current_balance',
     'Agent Cust#'              => 'agent_custid',
+    'Agent'                    => 'agent_name',
+    'Agent Cust# or Cust#'     => 'display_custnum',
+    'Advertising Source'       => 'referral',
   );
   $header2method{'Cust#'} = 'display_custnum'
     if $conf->exists('cust_main-default_agent_custid');
@@ -371,16 +450,21 @@ sub cust_sql_fields {
     }
   }
 
-  foreach my $field (qw(daytime night mobile fax payby)) {
+  foreach my $field (qw(daytime night mobile fax )) {
     push @fields, $field if (grep { $_ eq $field } @cust_fields);
   }
   push @fields, 'agent_custid';
 
+  push @fields, 'agentnum' if grep { $_ eq 'agent_name' } @cust_fields;
+
   my @extra_fields = ();
   if (grep { $_ eq 'current_balance' } @cust_fields) {
     push @extra_fields, FS::cust_main->balance_sql . " AS current_balance";
   }
 
+  push @extra_fields, 'part_referral_x.referral AS referral'
+    if grep { $_ eq 'referral' } @cust_fields;
+
   map("cust_main.$_", @fields), @location_fields, @extra_fields;
 }
 
@@ -445,6 +529,10 @@ sub join_cust_main {
             " ON (ship_location.locationnum = $location_table.$locationnum) ";
   }
 
+  if ( !@cust_fields or grep { $_ eq 'referral' } @cust_fields ) {
+    $sql .= ' LEFT JOIN (select refnum, referral from part_referral) AS part_referral_x ON (cust_main.refnum = part_referral_x.refnum) ';
+  }
+
   $sql;
 }
 
@@ -608,6 +696,36 @@ sub is_mobile {
   return 0;
 }
 
+=item random_id [ DIGITS ]
+
+Returns a random number of length DIGITS, or if unspecified, a long random 
+identifier consisting of the timestamp, process ID, and a random number.
+Anything in the UI that needs a random identifier should use this.
+
+=cut
+
+sub random_id {
+  my $digits = shift;
+  if (!defined $NO_RANDOM_IDS) {
+    my $conf = FS::Conf->new;
+    $NO_RANDOM_IDS = $conf->exists('no_random_ids') ? 1 : 0;
+    warn "TEST MODE--RANDOM ID NUMBERS DISABLED\n" if $NO_RANDOM_IDS;
+  }
+  if ( $NO_RANDOM_IDS ) {
+    if ( $digits > 0 ) {
+      return 0;
+    } else {
+      return '0000000000-0000-000000000.000000';
+    }
+  } else {
+    if ($digits > 0) {
+      return int(rand(10 ** $digits));
+    } else {
+      return time . "-$$-" . rand() * 2**32;
+    }
+  }
+}
+
 =back
 
 =cut
@@ -623,11 +741,12 @@ use vars qw($DEBUG);
 use Carp;
 use Storable qw(nfreeze);
 use MIME::Base64;
-use JSON::XS;
+use Cpanel::JSON::XS;
 use FS::CurrentUser;
 use FS::Record qw(qsearchs);
 use FS::queue;
 use FS::CGI qw(rooturl);
+use FS::Report::Queued::FutureAutobill;
 
 $DEBUG = 0;