[freeside-commits] branch FREESIDE_3_BRANCH updated. f4aa07316a23cbbd1db83cf1bceb1d59111ff0d6

Mark Wells mark at 420.am
Tue Aug 12 16:53:05 PDT 2014


The branch, FREESIDE_3_BRANCH has been updated
       via  f4aa07316a23cbbd1db83cf1bceb1d59111ff0d6 (commit)
       via  8171fd8de079cdfb23eb2b0dcc297e0e670b6e4e (commit)
      from  7e0eb79c2efc03e27a4e8207b92526a2ac436602 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit f4aa07316a23cbbd1db83cf1bceb1d59111ff0d6
Author: Mark Wells <mark at freeside.biz>
Date:   Tue Aug 12 16:01:28 2014 -0700

    popup view for collapsed packages, #25130, #27305

diff --git a/httemplate/view/cust_main/packages/contact.html b/httemplate/view/cust_main/packages/contact.html
index 0f0cde7..10c584c 100644
--- a/httemplate/view/cust_main/packages/contact.html
+++ b/httemplate/view/cust_main/packages/contact.html
@@ -10,10 +10,12 @@
           ( <%pkg_detach_link($cust_pkg)%> )
         </FONT>
 %    }
+    <BR>
 % } elsif ( $show_contact_link && ! $opt{no_links} ) {
     <FONT SIZE=-1>
       ( <%pkg_add_contact_link($cust_pkg)%> )
     </FONT>
+    <BR>
 % }
 <%init>
 
diff --git a/httemplate/view/cust_main/packages/hidden.html b/httemplate/view/cust_main/packages/hidden.html
new file mode 100644
index 0000000..35eda8c
--- /dev/null
+++ b/httemplate/view/cust_main/packages/hidden.html
@@ -0,0 +1,65 @@
+% if (!$iopt{noframe}) {
+%   # then start the block here, and assign a suitable ID (cust_pkgX_block)
+<TABLE CLASS="hiddenrows" STYLE="display: none" ID="<% $id %>_block">
+% }
+  <TR ID="<% $id %>">
+    <TD>
+      <A NAME="<% $id %>"/>
+      <% $pkgnum %>
+    </TD>
+    <TD>
+%     if ( $pkgpart_change and $location_change ) {
+      Package type and location change
+%     } elsif ( $pkgpart_change ) {
+      Package type change
+%     } elsif ( $location_change ) {
+      Location change
+%     } # or else what?
+      <B><% time2str('%b %o, %Y', $cust_pkg->get('cancel')) %></B>
+    </TD><TD>
+%     if ( $pkgpart_change ) {
+      from <% $popup_link |n %><B><% $part_pkg->pkg |h %></B> - <% $part_pkg->custom_comment |h %></A>
+%     }
+%     if ( $pkgpart_change and $location_change ) {
+      <BR>
+%     }
+%     if ( $location_change ) {
+      from <I><% $popup_link |n %><% $cust_pkg->location_label %></A></I>
+%     }
+    </TD>
+  </TR>
+% if ( $cust_pkg->get('changed_from_pkg') ) {
+<& hidden.html, $cust_pkg->get('changed_from_pkg'),
+                %iopt,
+                'next_pkg' => $cust_pkg,
+                'noframe' => 1
+&>
+% }
+% if ( !$iopt{noframe} ) {
+</TABLE>
+% }
+<%init>
+my $cust_pkg = shift;
+my $part_pkg = $cust_pkg->part_pkg;
+my %iopt = @_;
+my $next = delete($iopt{'next_pkg'});
+my $curuser = $FS::CurrentUser::CurrentUser;
+my $pkgnum = $curuser->option('show_pkgnum') ? $cust_pkg->pkgnum.': ' : '';
+
+my $id = "cust_pkg".$cust_pkg->pkgnum;
+
+my $pkgpart_change = ($next->pkgpart != $cust_pkg->pkgpart);
+my $location_change = ($next->locationnum != $cust_pkg->locationnum);
+my $both_change = $pkgpart_change && $location_change;
+
+my $onclick =
+  include('/elements/popup_link_onclick.html',
+    'action'      => $fsurl.'view/cust_pkg-popup.html?' . $cust_pkg->pkgnum,
+    'actionlabel' => 'Package #'.$cust_pkg->pkgnum,
+    'width'       => '1000',
+    'height'      => '310',
+    'color'       => $cust_pkg->statuscolor,
+  );
+my $popup_link = qq(<A HREF="#" onclick="$onclick">);
+
+</%init>
diff --git a/httemplate/view/cust_main/packages/section.html b/httemplate/view/cust_main/packages/section.html
index 11928ec..217e8c5 100755
--- a/httemplate/view/cust_main/packages/section.html
+++ b/httemplate/view/cust_main/packages/section.html
@@ -4,17 +4,22 @@
   <TH CLASS="grid" BGCOLOR="#cccccc"><% mt('Package') |h %></TH>
   <TH CLASS="grid" BGCOLOR="#cccccc"><% mt('Status') |h %></TH>
   <TH CLASS="grid" BGCOLOR="#cccccc"><% mt('Contact/Location') |h %></TH>
+% if (!$opt{no_services}) {
   <TH CLASS="grid" BGCOLOR="#cccccc"><% mt('Services') |h %></TH>
+% }
 </TR>
 
 % #$FS::cust_pkg::DEBUG = 2;
 %   foreach my $cust_pkg (@$packages) {
+%    # if requested, this can override cust_pkg-group_by_location
     <& .packagerow, $cust_pkg,
+        %conf_opt,
         ( map { $_ => $opt{$_} } qw(
             cust_main bgcolor no_links cust_location_cache
             before_pkg_callback before_svc_callback after_svc_callback
+            cust_pkg-group_by_location
+            no_services
         )),
-        %conf_opt
     &>
 %   }
 % } else { # there are no packages
@@ -30,11 +35,32 @@
     <& package.html, %iopt &>
     <& status.html,  %iopt &>
     <TD CLASS="inv" BGCOLOR="<% $iopt{bgcolor} %>" WIDTH="20%" VALIGN="top">
-      <& contact.html, %iopt &><BR>
+      <& contact.html, %iopt &>
       <& location.html, %iopt &>
     </TD>
+%   if (!$iopt{no_services}) {
     <& services.html, %iopt &>
+%   }
+  </TR>
+% # insert hidden predecessors to this package, if any
+% # and a rolldown button to show them
+% # (we'll make it do something later)
+% if ( $cust_pkg->get('changed_from_pkg') ) {
+  <TR CLASS="row<% $row % 2 %>">
+    <TD COLSPAN=4>
+    <BUTTON CLASS="rolldown_button"
+            ID="rolldown_<% $cust_pkg->change_pkgnum %>">
+      History &#x2b07;
+    </BUTTON>
+% # the hidden block here has ID="cust_pkgX" where X is the first pkgnum
+% # it contains.
+    <& hidden.html, $cust_pkg->get('changed_from_pkg'),
+       %iopt,
+       'next_pkg' => $cust_pkg,
+    &>
+    </TD>
   </TR>
+% }
 % $row++;
 % # show the change target, if there is one
 % if ( $cust_pkg->change_to_pkg ) {
diff --git a/httemplate/view/cust_pkg-popup.html b/httemplate/view/cust_pkg-popup.html
new file mode 100644
index 0000000..96956c7
--- /dev/null
+++ b/httemplate/view/cust_pkg-popup.html
@@ -0,0 +1,27 @@
+<& /elements/header-popup.html &>
+<TABLE STYLE="width: 100%">
+<& cust_main/packages/section.html,
+  'cust_main' => $cust_main,
+  'packages'  => [ $cust_pkg ],
+  'cust_pkg-group_by_location' => 0,
+  'no_services' => 1,
+&>
+</TABLE>
+</BODY>
+</HTML>
+<%init>
+my $curuser = $FS::CurrentUser::CurrentUser;
+my ($pkgnum) = $cgi->keywords;
+$pkgnum =~ /^\d+$/ or die "bad pkgnum $pkgnum";
+
+my $cust_pkg = qsearchs({
+  'table'     => 'cust_pkg',
+  'addl_from' => 'JOIN cust_main USING (custnum)',
+  'hashref'   => { 'pkgnum' => $pkgnum },
+  'extra_sql' => ' AND '.$curuser->agentnums_sql,
+});
+die "Package not found" unless $cust_pkg;
+my $cust_main = $cust_pkg->cust_main;
+
+my $title = mt('Package [_1]', $pkgnum);
+</%init>

commit 8171fd8de079cdfb23eb2b0dcc297e0e670b6e4e
Author: Mark Wells <mark at freeside.biz>
Date:   Tue Aug 12 16:00:00 2014 -0700

    collapse display of location-changed packages, #25130, #27305

diff --git a/httemplate/pref/pref-process.html b/httemplate/pref/pref-process.html
index 8a826a7..85e2a34 100644
--- a/httemplate/pref/pref-process.html
+++ b/httemplate/pref/pref-process.html
@@ -58,6 +58,7 @@ unless ( $error ) { # if ($access_user) {
                       snom-ip snom-username snom-password
                       vonage-fromnumber vonage-username vonage-password
                       cust_pkg-display_times
+                      hide_package_changes
                       show_pkgnum show_confitem_counts export_getsettings
                       show_db_profile save_db_profile save_tmp_typesetting
                       height width availHeight availWidth colorDepth
diff --git a/httemplate/pref/pref.html b/httemplate/pref/pref.html
index 886046b..ab5baab 100644
--- a/httemplate/pref/pref.html
+++ b/httemplate/pref/pref.html
@@ -76,6 +76,22 @@ Interface
     </TD>
   </TR>
 
+  <TR>
+    <TH ALIGN="right">Hide package changes: </TH>
+    <TD>
+    <& /elements/select.html,
+      field   => 'hide_package_changes',
+      options => [ '', 'location', 'all' ],
+      labels  => { ''         => 'never',
+                   'location' => 'location changes',
+                   'all'      => 'all package changes',
+                 },
+      curr_value => ($cgi->param('hide_package_changes') 
+                      || $curuser->option('hide_package_changes')),
+    &>
+    </TD>
+  </TR>
+
 % my $history_order = $curuser->option('history_order') || 'oldest';
   <TR>
     <TH ALIGN="right">Customer history sort order: </TH>
diff --git a/httemplate/view/cust_main/packages.html b/httemplate/view/cust_main/packages.html
index 500632d..32a725d 100755
--- a/httemplate/view/cust_main/packages.html
+++ b/httemplate/view/cust_main/packages.html
@@ -22,8 +22,62 @@ table.usage {
 .row0 { background-color: #eeeeee; }
 .row1 { background-color: #ffffff; }
 
-</STYLE>
+table.hiddenrows {
+  width: 80%;
+  margin-left: 100px;
+  border: 1px solid #7E0079;
+  background-color: #cccccc;
+}
 
+.hiddenrows td {
+  text-align: center;
+}
+
+.rolldown_button {
+  min-width: 80px;
+  margin-left: 100px;
+  min-height: 20px;
+  background-color: #efefef;
+  border: 1px solid #7e0079;
+  z-index: 1;
+  text-align: center;
+}
+</STYLE>
+% # activate rolldown buttons for hidden package blocks
+<SCRIPT TYPE="text/javascript">
+function toggle_rolldown() {
+  var up_arrow = <% decode_entities('&#x2b06') |js_string %>;
+  var dn_arrow = <% decode_entities('&#x2b07') |js_string %>;
+  var pkgnum = this.id.replace('rolldown_', '');
+  var hidden = document.getElementById('cust_pkg'+pkgnum+'_block');
+  if (hidden.style.display == 'none') {
+    hidden.style.display = '';
+    this.textContent = this.textContent.replace(dn_arrow, up_arrow);
+  } else {
+    hidden.style.display = 'none';
+    this.textContent = this.textContent.replace(up_arrow, dn_arrow);
+  }
+}
+<&| /elements/onload.js &>
+var el;
+% if ( $cgi->param('fragment') =~ /^cust_pkg(\d+)$/ ) {
+% # IE-specific hack, but also unhide the row if it's in a hidden block
+el = document.getElementById('cust_pkg<% $1 %>');
+% }
+var all_buttons = document.getElementsByClassName('rolldown_button');
+for (var i = 0; i < all_buttons.length; i++) {
+  all_buttons[i].onclick = toggle_rolldown;
+  var block_id = all_buttons[i].id.replace('rolldown_', '');
+  if ( el && document.getElementById('cust_pkg'+block_id+'_block')
+                     .contains(el)
+     ) {
+    // then toggle it now
+    all_buttons[i].click();
+  }
+}
+if ( el ) el.scrollIntoView(true);
+</&>
+</SCRIPT>
 % unless ( $opt{no_links} ) {
 
 %   my $s = 0;
@@ -123,7 +177,7 @@ table.usage {
     <TD COLSPAN=2>
 
 %     $opt{cust_main} = $cust_main;
-%     $opt{packages}  = $packages;
+%     $opt{packages}  = \@packages;
 %     $opt{cust_location_cache} = {};
 %     if ( $conf->exists('cust_pkg-group_by_location') ) {
         <& locations.html, %opt &>
@@ -136,15 +190,6 @@ table.usage {
     </TD>
   </TR>
 
-% if ( $cgi->param('fragment') =~ /^cust_pkg(\d+)$/ ) {
-  <SCRIPT>
-    // IE-specific hack.  other browsers listen to #fragments
-    // is this even working?  or is the #target redirection just working cause
-    // we set the URL params differently?
-    var el = document.getElementById( 'cust_pkg<% $1 %>' );
-    if ( el ) el.scrollIntoView(true);
-  </SCRIPT>
-% }
 </TABLE>
 <%init>
 
@@ -154,110 +199,129 @@ my $conf = new FS::Conf;
 
 my $curuser = $FS::CurrentUser::CurrentUser;
 
-my( $packages, $num_old_packages ) = get_packages($cust_main, $conf);
-
 my $countrydefault = scalar($conf->config('countrydefault')) || 'US';
-#subroutines
-
-sub get_packages {
-  my $cust_main = shift or return undef;
-  my $conf = shift;
-
-  my $method;
-  if (  $cgi->param('showcancelledpackages') eq '0' #see if it was set by me
-     || ( $conf->exists('hidecancelledpackages')
-           && ! $cgi->param('showcancelledpackages') )
-     )
-  {
-    $method = 'ncancelled_pkgs';
-  } else {
-    $method = 'all_pkgs';
-  }
 
-  my $cust_pkg_fields =
-    join(', ', map { "cust_pkg.$_ AS $_"          } fields('cust_pkg') );
+my $hide_changed = $curuser->option('hide_package_changes');
+
+my $hide_cancelled = 0;
+if (  $cgi->param('showcancelledpackages') eq '0' #see if it was set by me
+   || ( $conf->exists('hidecancelledpackages')
+         && ! $cgi->param('showcancelledpackages') )
+   )
+{
+  $hide_cancelled = 1;
+}
+
+my $cust_pkg_fields =
+  join(', ', map { "cust_pkg.$_ AS $_"          } fields('cust_pkg') );
 
-  my $part_pkg_fields =
+my $part_pkg_fields =
   join(', ', ( map { "part_pkg.$_ AS part_pkg_$_" } fields('part_pkg') ),
              'setup_option.optionvalue AS part_pkg__setup_fee',
              'recur_option.optionvalue AS part_pkg__recur_fee',
       );
 
-  my $group_by =
-    join(', ', map "cust_pkg.$_", fields('cust_pkg') ). ', '.
-    join(', ', map "part_pkg.$_", fields('part_pkg') );
-
-  my $num_svcs = '( SELECT COUNT(*) FROM cust_svc '.
-                 '    WHERE cust_svc.pkgnum = cust_pkg.pkgnum ) AS num_svcs';
-
-  my @packages = $cust_main->$method( {
-    'select'    => "$cust_pkg_fields, $part_pkg_fields, $num_svcs",
-    'addl_from' => qq{
-      LEFT JOIN part_pkg USING ( pkgpart )
-      LEFT JOIN part_pkg_option AS setup_option
-        ON (     cust_pkg.pkgpart = setup_option.pkgpart
-             AND setup_option.optionname = 'setup_fee' )
-      LEFT JOIN part_pkg_option AS recur_option
-        ON (     cust_pkg.pkgpart = recur_option.pkgpart
-             AND recur_option.optionname = 'recur_fee' )
-    },
-  } );
-  my $num_old_packages = scalar(@packages);
-
-  my %change_to_from; # target pkgnum => current cust_pkg, for future changes
-
-  foreach my $cust_pkg ( @packages ) {
-    my %hash = $cust_pkg->hash;
-    my %part_pkg = map  { /^part_pkg_(.+)$/ or die; ( $1 => $hash{$_} ); }
-                   grep { /^part_pkg_/ } keys %hash;
-    $cust_pkg->{'_pkgpart'} = new FS::part_pkg \%part_pkg;
-    if ( $cust_pkg->change_to_pkgnum ) {
-      $change_to_from{$cust_pkg->change_to_pkgnum} = $cust_pkg;
-    }
+my $group_by =
+  join(', ', map "cust_pkg.$_", fields('cust_pkg') ). ', '.
+  join(', ', map "part_pkg.$_", fields('part_pkg') );
+
+my $num_svcs = '( SELECT COUNT(*) FROM cust_svc '.
+               '    WHERE cust_svc.pkgnum = cust_pkg.pkgnum ) AS num_svcs';
+
+# don't exclude cancelled packages at this stage
+my @packages = $cust_main->all_pkgs( {
+  'select'    => "$cust_pkg_fields, $part_pkg_fields, $num_svcs",
+  'addl_from' => qq{
+    LEFT JOIN part_pkg USING ( pkgpart )
+    LEFT JOIN part_pkg_option AS setup_option
+      ON (     cust_pkg.pkgpart = setup_option.pkgpart
+           AND setup_option.optionname = 'setup_fee' )
+    LEFT JOIN part_pkg_option AS recur_option
+      ON (     cust_pkg.pkgpart = recur_option.pkgpart
+           AND recur_option.optionname = 'recur_fee' )
+  },
+} );
+
+my %change_to_from; # target pkgnum => current cust_pkg, for future changes
+my %changed_from; # old pkgnum => new cust_pkg, for past changes
+
+foreach my $cust_pkg ( @packages ) {
+  my %hash = $cust_pkg->hash;
+  my %part_pkg = map  { /^part_pkg_(.+)$/ or die; ( $1 => $hash{$_} ); }
+                 grep { /^part_pkg_/ } keys %hash;
+  $cust_pkg->{'_pkgpart'} = new FS::part_pkg \%part_pkg;
+  if ( $cust_pkg->change_to_pkgnum ) {
+    $change_to_from{$cust_pkg->change_to_pkgnum} = $cust_pkg;
+  }
+  if ( $cust_pkg->change_pkgnum ) {
+    $changed_from{$cust_pkg->change_pkgnum} = $cust_pkg;
   }
+}
 
-  if ( keys %change_to_from ) {
-    my @not_future_packages;
-    foreach my $cust_pkg (@packages) {
-      if ( exists( $change_to_from{$cust_pkg->pkgnum} ) ) {
-        my $change_from = $change_to_from{ $cust_pkg->pkgnum };
-        $cust_pkg->set('change_from_pkg', $change_from);
-        $change_from->set('change_to_pkg', $cust_pkg);
-      } else {
-        push @not_future_packages, $cust_pkg;
+# filter out hidden package changes
+if ( keys %change_to_from or keys %changed_from ) {
+  my @displayable_packages;
+  foreach my $cust_pkg (@packages) {
+    if ( exists( $change_to_from{$cust_pkg->pkgnum} ) ) {
+      # $cust_pkg is an ordered, not-yet-active package change target
+      my $change_from = $change_to_from{ $cust_pkg->pkgnum };
+      $cust_pkg->set('change_from_pkg', $change_from);
+      $change_from->set('change_to_pkg', $cust_pkg);
+    } elsif ( exists( $changed_from{$cust_pkg->pkgnum} ) ) {
+      # $cust_pkg is a canceled package changed into another packge
+      my $changed_to = $changed_from{$cust_pkg->pkgnum};
+      if ( ( $hide_changed eq 'all' ) or
+           ( $hide_changed eq 'location' 
+              and $changed_to->pkgpart  == $cust_pkg->pkgpart
+              and $changed_to->refnum   == $cust_pkg->refnum
+              and $changed_to->quantity == $cust_pkg->quantity )
+      ) {
+        # then we're hiding it
+        $cust_pkg->set('changed_to_pkg', $changed_to);
+        $changed_to->set('changed_from_pkg', $cust_pkg);
+      } else { # show it anyway
+        push @displayable_packages, $cust_pkg;
       }
+    } else {
+      push @displayable_packages, $cust_pkg;
     }
-    @packages = @not_future_packages;
   }
+  @packages = @displayable_packages;
+}
 
-  unless ( $cgi->param('showoldpackages') ) {
-    my $years = $conf->config('cust_main-packages-years') || 2;
-    my $then = time - $years * 31556926; #60*60*24*365.2422 is close enough
-
-    my %hide = ( 'cancelled'       => 'cancel',
-                 'one-time charge' => 'setup',
-               );
-  
-    @packages =
-      grep { !exists($hide{$_->status}) or $_->get($hide{$_->status}) > $then
-             or $_->num_svcs #don't hide packages w/services
-           }
-           @packages;
-  }
+# filter all cancelled packages if the user wants
+if ( $hide_cancelled ) {
+  @packages = grep { !$_->get('cancel') } @packages;
+}
 
-  $num_old_packages -= scalar(@packages);
-  
-  # don't include supplemental packages in this list; they'll be found from
-  # their main packages
-  # (as will change-target packages)
-  @packages = grep !$_->main_pkgnum, @packages;
+# filter out 'old' packages
+my $num_old_packages = scalar(@packages);
 
-  foreach my $cust_pkg ( @packages ) {
-    $cust_pkg->{'_cust_pkg_discount_active'} =
-     [ $cust_pkg->cust_pkg_discount_active ];
-  }
+unless ( $cgi->param('showoldpackages') ) {
+  my $years = $conf->config('cust_main-packages-years') || 2;
+  my $then = time - $years * 31556926; #60*60*24*365.2422 is close enough
+
+  my %hide = ( 'cancelled'       => 'cancel',
+               'one-time charge' => 'setup',
+             );
+
+  @packages =
+    grep { !exists($hide{$_->status}) or $_->get($hide{$_->status}) > $then
+           or $_->num_svcs #don't hide packages w/services
+         }
+         @packages;
+}
+
+$num_old_packages -= scalar(@packages);
+
+# don't include supplemental packages in this list; they'll be found from
+# their main packages
+# (as will change-target packages)
+ at packages = grep !$_->main_pkgnum, @packages;
 
-  ( \@packages, $num_old_packages );
+foreach my $cust_pkg ( @packages ) {
+  $cust_pkg->{'_cust_pkg_discount_active'} =
+   [ $cust_pkg->cust_pkg_discount_active ];
 }
 
 </%init>

-----------------------------------------------------------------------

Summary of changes:
 httemplate/pref/pref-process.html               |    1 +
 httemplate/pref/pref.html                       |   16 ++
 httemplate/view/cust_main/packages.html         |  260 ++++++++++++++---------
 httemplate/view/cust_main/packages/contact.html |    2 +
 httemplate/view/cust_main/packages/hidden.html  |   65 ++++++
 httemplate/view/cust_main/packages/section.html |   30 ++-
 httemplate/view/cust_pkg-popup.html             |   27 +++
 7 files changed, 301 insertions(+), 100 deletions(-)
 create mode 100644 httemplate/view/cust_main/packages/hidden.html
 create mode 100644 httemplate/view/cust_pkg-popup.html




More information about the freeside-commits mailing list