make date_format a localized config option, #27276
authorMark Wells <mark@freeside.biz>
Wed, 29 Jan 2014 23:30:06 +0000 (15:30 -0800)
committerMark Wells <mark@freeside.biz>
Wed, 29 Jan 2014 23:30:06 +0000 (15:30 -0800)
FS/FS/Conf.pm
FS/FS/cust_bill.pm
FS/FS/cust_main_Mixin.pm

index 66b6f9b..1358215 100644 (file)
@@ -991,6 +991,7 @@ my @cdr_formats = (
                        '%d/%m/%Y' => 'DD/MM/YYYY',
                       '%Y/%m/%d' => 'YYYY/MM/DD',
                      ],
+    'per_locale'  => 1,
   },
 
   {
@@ -1002,6 +1003,7 @@ my @cdr_formats = (
                        '%b %o, %Y' => 'Mon DDth, YYYY',
                        '%e %b %Y'  => 'DD Mon YYYY',
                      ],
+    'per_locale'  => 1,
   },
 
   {
index 45f86ed..32e2a09 100644 (file)
@@ -2,7 +2,7 @@ package FS::cust_bill;
 
 use strict;
 use vars qw( @ISA $DEBUG $me 
-             $money_char $date_format $rdate_format $date_format_long );
+             $money_char );
              # but NOT $conf
 use vars qw( $invoice_lines @buf ); #yuck
 use Fcntl qw(:flock); #for spool_csv
@@ -55,9 +55,6 @@ $me = '[FS::cust_bill]';
 FS::UID->install_callback( sub { 
   my $conf = new FS::Conf; #global
   $money_char       = $conf->config('money_char')       || '$';  
-  $date_format      = $conf->config('date_format')      || '%x'; #/YY
-  $rdate_format     = $conf->config('date_format')      || '%m/%d/%Y';  #/YYYY
-  $date_format_long = $conf->config('date_format_long') || '%b %o, %Y';
 } );
 
 =head1 NAME
@@ -1999,7 +1996,7 @@ sub print_csv {
     my $taxtotal = 0;
     $taxtotal += $_->{'amount'} foreach $self->_items_tax;
 
-    my $duedate = $self->due_date2str('%m/%d/%Y'); #date_format?
+    my $duedate = $self->due_date2str('%m/%d/%Y'); # hardcoded, NOT date_format
 
     my( $previous_balance, @unused ) = $self->previous; #previous balance
 
@@ -2653,14 +2650,6 @@ sub print_generic {
   my $escape_function_nonbsp = ($format eq 'html')
                                  ? \&_html_escape : $escape_function;
 
-  my %date_formats = ( 'latex'    => $date_format_long,
-                       'html'     => $date_format_long,
-                       'template' => '%s',
-                     );
-  $date_formats{'html'} =~ s/ /&nbsp;/g;
-
-  my $date_format = $date_formats{$format};
-
   my %embolden_functions = ( 'latex'    => sub { return '\textbf{'. shift(). '}'
                                                },
                              'html'     => sub { return '<b>'. shift(). '</b>'
@@ -2747,13 +2736,13 @@ sub print_generic {
     #invoice info
     'invnum'          => $self->invnum,
     '_date'           => $self->_date,
-    'date'            => $self->time2str_local($date_format, $self->_date),
-    'today'           => $self->time2str_local($date_format_long, $today),
+    'date'            => $self->time2str_local('long', $self->_date, $format),
+    'today'           => $self->time2str_local('long', $today, $format),
     'terms'           => $self->terms,
     'template'        => $template, #params{'template'},
     'notice_name'     => ($params{'notice_name'} || 'Invoice'),#escape_function?
     'current_charges' => sprintf("%.2f", $self->charged),
-    'duedate'         => $self->due_date2str($rdate_format), #date_format?
+    'duedate'         => $self->due_date2str('rdate'),
 
     #customer info
     'custnum'         => $cust_main->display_custnum,
@@ -2794,7 +2783,7 @@ sub print_generic {
   #localization (see FS::cust_main_Mixin)
   $invoice_data{'emt'} = sub { &$escape_function($self->mt(@_)) };
   # prototype here to silence warnings
-  $invoice_data{'time2str'} = sub ($;$$) { $self->time2str_local(@_) };
+  $invoice_data{'time2str'} = sub ($;$$) { $self->time2str_local(@_, $format) };
 
   my $min_sdate = 999999999999;
   my $max_edate = 0;
@@ -2807,9 +2796,10 @@ sub print_generic {
   }
 
   $invoice_data{'bill_period'} = '';
-  $invoice_data{'bill_period'} = $self->time2str_local('%e %h', $min_sdate) 
-                                 . " to " .
-                                 $self->time2str_local('%e %h', $max_edate)
+  $invoice_data{'bill_period'} =
+      $self->time2str_local('%e %h', $min_sdate, $format) 
+      . " to " .
+      $self->time2str_local('%e %h', $max_edate, $format)
     if ($max_edate != 0 && $min_sdate != 999999999999);
 
   $invoice_data{finance_section} = '';
@@ -3833,7 +3823,7 @@ sub balance_due_msg {
   return $msg unless $self->terms;
   if ( $self->due_date ) {
     $msg .= ' - ' . $self->mt('Please pay by'). ' '.
-      $self->due_date2str($date_format);
+      $self->due_date2str('short');
   } elsif ( $self->terms ) {
     $msg .= ' - '. $self->terms;
   }
@@ -3846,7 +3836,7 @@ sub balance_due_date {
   my $duedate = '';
   if (    $conf->exists('invoice_default_terms') 
        && $conf->config('invoice_default_terms')=~ /^\s*Net\s*(\d+)\s*$/ ) {
-    $duedate = $self->time2str_local($rdate_format, $self->_date + ($1*86400) );
+    $duedate = $self->time2str_local('rdate', $self->_date + ($1*86400) );
   }
   $duedate;
 }
@@ -3876,7 +3866,7 @@ Returns a string with the date, for example: "3/20/2008"
 
 sub _date_pretty {
   my $self = shift;
-  $self->time2str_local($date_format, $self->_date);
+  $self->time2str_local('short', $self->_date);
 }
 
 =item _items_sections LATE SUMMARYPAGE ESCAPE EXTRA_SECTIONS FORMAT
@@ -4818,8 +4808,8 @@ sub _items_previous {
   my @b = ();
   foreach ( @pr_cust_bill ) {
     my $date = $conf->exists('invoice_show_prior_due_date')
-               ? 'due '. $_->due_date2str($date_format)
-               : $self->time2str_local($date_format, $_->_date);
+               ? 'due '. $_->due_date2str('short')
+               : $self->time2str_local('short', $_->_date);
     push @b, {
       'description' => $self->mt('Previous Balance, Invoice #'). $_->invnum. " ($date)",
       #'pkgpart'     => 'N/A',
@@ -5145,8 +5135,8 @@ sub _items_cust_bill_pkg {
               $desc .= ' ' unless $desc =~ /\s$/;
               $time_period = $desc. $self->time2str_local('%B', $cust_bill_pkg->sdate);
             } else {
-              $time_period =      $self->time2str_local($date_format, $cust_bill_pkg->sdate).
-                           " - ". $self->time2str_local($date_format, $cust_bill_pkg->edate);
+              $time_period =      $self->time2str_local('short', $cust_bill_pkg->sdate).
+                           " - ". $self->time2str_local('short', $cust_bill_pkg->edate);
             }
             $description .= " ($time_period)";
           }
@@ -5299,8 +5289,8 @@ sub _items_cust_bill_pkg {
         if ( $cust_bill_pkg->recur != 0 ) {
           push @b, {
             'description' => "$desc (".
-                             $self->time2str_local($date_format, $cust_bill_pkg->sdate). ' - '.
-                             $self->time2str_local($date_format, $cust_bill_pkg->edate). ')',
+                             $self->time2str_local('short', $cust_bill_pkg->sdate). ' - '.
+                             $self->time2str_local('short', $cust_bill_pkg->edate). ')',
             'amount'      => sprintf("%.2f", $cust_bill_pkg->recur),
           };
         }
@@ -5374,7 +5364,7 @@ sub _items_credits {
       #                 " (". time2str("%x",$_->cust_credit->_date) .")".
       #                 $reason,
       'description' => $self->mt('Credit applied').' '.
-                       $self->time2str_local($date_format,$obj->_date). $reason,
+                       $self->time2str_local('short', $obj->_date). $reason,
       'amount'      => sprintf("%.2f",$obj->amount),
     };
   }
@@ -5418,7 +5408,7 @@ sub _items_payments {
   foreach my $obj (@objects) {
     my $cust_pay = $obj->isa('FS::cust_pay') ? $obj : $obj->cust_pay;
     my $desc = $self->mt('Payment received').' '.
-               $self->time2str_local($date_format, $cust_pay->_date );
+               $self->time2str_local('short', $cust_pay->_date );
     $desc .= $self->mt(' via ') .
              $cust_pay->payby_payinfo_pretty( $self->cust_main->locale )
       if $detailed;
index 5a2eccd..a9c3af1 100644 (file)
@@ -7,6 +7,7 @@ use FS::UID qw(dbh);
 use FS::cust_main;
 use FS::Record qw( qsearch qsearchs );
 use FS::Misc qw( send_email generate_email );
+use HTML::Entities;
 
 $DEBUG = 0;
 $me = '[FS::cust_main_Mixin]';
@@ -578,16 +579,31 @@ sub mt {
   return $lh->maketext(@_);
 }
 
-=item time2str_local FORMAT, TIME
+=item time2str_local FORMAT, TIME[, ESCAPE]
 
 Localizes a date (see L<Date::Language>) for the customer's locale.
 
+FORMAT can be a L<Date::Format> string, or one of these special words:
+
+- "short": the value of the "date_format" config setting for the customer's 
+  locale, defaulting to "%x".
+- "rdate": the same as "short" except that the default has a four-digit year.
+- "long": the value of the "date_format_long" config setting for the 
+  customer's locale, defaulting to "%b %o, %Y".
+
+ESCAPE, if specified, is one of "latex" or "html", and will escape non-ASCII
+characters and convert spaces to nonbreaking spaces.
+
 =cut
 
 sub time2str_local {
   # renamed so that we don't have to change every single reference to 
   # time2str everywhere
   my $self = shift;
+  my ($format, $time, $escape) = @_;
+  return '' unless $time > 0; # work around time2str's traditional stupidity
+
+  $self->{_date_format} ||= {};
   if (!exists($self->{_dh})) {
     my $cust_main = $self->cust_main;
     my $locale = $cust_main->locale  if $cust_main;
@@ -597,7 +613,31 @@ sub time2str_local {
              Date::Language->new(); # fall back to English
     $self->{_dh} = $dh;
   }
-  $self->{_dh}->time2str(@_);
+
+  if ($format eq 'short') {
+    $format = $self->{_date_format}->{short}
+            ||= $self->conf->config('date_format') || '%x';
+  } elsif ($format eq 'rdate') {
+    $format = $self->{_date_format}->{rdate}
+            ||= $self->conf->config('date_format') || '%m/%d/%Y';
+  } elsif ($format eq 'long') {
+    $format = $self->{_date_format}->{long}
+            ||= $self->conf->config('date_format_long') || '%b %o, %Y';
+  }
+
+  # actually render the date
+  my $string = $self->{_dh}->time2str($format, $time);
+
+  if ($escape) {
+    if ($escape eq 'html') {
+      $string = encode_entities($string);
+      $string =~ s/ +/&nbsp;/g;
+    } elsif ($escape eq 'latex') { # just do nbsp's here
+      $string =~ s/ +/~/g;
+    }
+  }
+  
+  $string;
 }
 
 =back