[freeside-commits] branch FREESIDE_4_BRANCH updated. c02f0c21ed0fc1d3982135a909c380fa7bb634d4

Jonathan Prykop jonathan at 420.am
Wed Aug 31 20:12:25 PDT 2016


The branch, FREESIDE_4_BRANCH has been updated
       via  c02f0c21ed0fc1d3982135a909c380fa7bb634d4 (commit)
       via  979fd02b54579a289e62fcc93ef24490425f815a (commit)
       via  030f4ebf3f2fe98fa53606cb5e4bed6dc68560eb (commit)
      from  3182ddaae3900b8477f17fae7be74e2ae7b66c84 (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 c02f0c21ed0fc1d3982135a909c380fa7bb634d4
Author: Jonathan Prykop <jonathan at freeside.biz>
Date:   Wed Aug 31 21:49:04 2016 -0500

    71890: SelfService API: Return monthly recurring fee

diff --git a/FS/FS/ClientAPI/MyAccount.pm b/FS/FS/ClientAPI/MyAccount.pm
index 685821b..07b1be9 100644
--- a/FS/FS/ClientAPI/MyAccount.pm
+++ b/FS/FS/ClientAPI/MyAccount.pm
@@ -672,6 +672,29 @@ sub customer_info_short {
          };
 }
 
+sub customer_recurring {
+  my $p = shift;
+
+  my($context, $session, $custnum) = _custoragent_session_custnum($p);
+  return { 'error' => $session } if $context eq 'error';
+
+  my %return;
+
+  my $conf = new FS::Conf;
+
+  my $search = { 'custnum' => $custnum };
+  $search->{'agentnum'} = $session->{'agentnum'} if $context eq 'agent';
+  my $cust_main = qsearchs('cust_main', $search )
+    or return { 'error' => "customer_info_short: unknown custnum $custnum" };
+
+  $return{'display_recurring'} = [ $cust_main->display_recurring ];
+
+  return { 'error'          => '',
+           'custnum'        => $custnum,
+           %return,
+         };
+}
+
 sub billing_history {
   my $p = shift;
 
diff --git a/FS/FS/ClientAPI_XMLRPC.pm b/FS/FS/ClientAPI_XMLRPC.pm
index 3ffb378..4dc2f8e 100644
--- a/FS/FS/ClientAPI_XMLRPC.pm
+++ b/FS/FS/ClientAPI_XMLRPC.pm
@@ -112,6 +112,7 @@ sub ss2clientapi {
   'switch_cust'               => 'MyAccount/switch_cust',
   'customer_info'             => 'MyAccount/customer_info',
   'customer_info_short'       => 'MyAccount/customer_info_short',
+  'customer_recurring'        => 'MyAccount/customer_recurring',
 
   'contact_passwd'            => 'MyAccount/contact/contact_passwd',
   'list_contacts'             => 'MyAccount/contact/list_contacts',
diff --git a/bin/xmlrpc-customer_recurring b/bin/xmlrpc-customer_recurring
new file mode 100755
index 0000000..18dd3e8
--- /dev/null
+++ b/bin/xmlrpc-customer_recurring
@@ -0,0 +1,30 @@
+#!/usr/bin/perl
+
+use strict;
+use Frontier::Client;
+use Data::Dumper;
+
+my( $email, $password ) = @ARGV;
+die "Usage: xmlrpc-customer_recurring email password\n"
+  unless $email && length($password);
+
+my $uri = new URI 'http://localhost:8080/';
+
+my $server = new Frontier::Client ( 'url' => $uri );
+
+my $login_result = $server->call(
+  'FS.ClientAPI_XMLRPC.login',
+    'email'    => $email,
+    'password' => $password,
+);
+die $login_result->{'error'}."\n" if $login_result->{'error'};
+
+my $list_result = $server->call(
+  'FS.ClientAPI_XMLRPC.customer_recurring',
+    'session_id'   => $login_result->{'session_id'},
+);
+die $list_result->{'error'}."\n" if $list_result->{'error'};
+
+print Dumper($list_result);
+
+1;
diff --git a/fs_selfservice/FS-SelfService/SelfService.pm b/fs_selfservice/FS-SelfService/SelfService.pm
index b068c3b..43a605d 100644
--- a/fs_selfservice/FS-SelfService/SelfService.pm
+++ b/fs_selfservice/FS-SelfService/SelfService.pm
@@ -33,6 +33,7 @@ $socket .= '.'.$tag if defined $tag && length($tag);
   'switch_cust'               => 'MyAccount/switch_cust',
   'customer_info'             => 'MyAccount/customer_info',
   'customer_info_short'       => 'MyAccount/customer_info_short',
+  'customer_recurring'        => 'MyAccount/customer_recurring',
 
   'contact_passwd'            => 'MyAccount/contact/contact_passwd',
   'list_contacts'             => 'MyAccount/contact/list_contacts',
@@ -507,6 +508,31 @@ first last company address1 address2 city county state zip country daytime night
 
 =back
 
+=item customer_recurring HASHREF
+
+Takes a hash reference as parameter with a single key B<session_id>
+or keys B<agent_session_id> and B<custnum>.
+
+Returns a hash reference with the keys error, custnum and display_recurring.
+
+display_recurring is an arrayref of hashrefs with the following keys:
+
+=over 4
+
+=item freq
+
+frequency of charge, in months unless units are specified
+
+=item freq_pretty
+
+frequency of charge, suitable for display
+
+=item amount
+
+amount charged at this frequency
+
+=back
+
 =item edit_info HASHREF
 
 Takes a hash reference as parameter with any of the following keys:

commit 979fd02b54579a289e62fcc93ef24490425f815a
Author: Jonathan Prykop <jonathan at freeside.biz>
Date:   Wed Aug 31 21:58:58 2016 -0500

    RT#71890: SelfService API: Return monthly recurring fee [display_recurring, v4 reconcile bug fix]

diff --git a/FS/FS/cust_main/Packages.pm b/FS/FS/cust_main/Packages.pm
index ace30d3..83ad7db 100644
--- a/FS/FS/cust_main/Packages.pm
+++ b/FS/FS/cust_main/Packages.pm
@@ -882,7 +882,6 @@ sub display_recurring {
   } #foreach $freq
 
   return @out;
->>>>>>> 4b56fbb... RT#71890: SelfService API: Return monthly recurring fee [display_recurring]
 }
 
 =back

commit 030f4ebf3f2fe98fa53606cb5e4bed6dc68560eb
Author: Jonathan Prykop <jonathan at freeside.biz>
Date:   Tue Aug 9 00:55:45 2016 -0500

    RT#71890: SelfService API: Return monthly recurring fee [display_recurring, v4 reconcile]

diff --git a/FS/FS/cust_main/Packages.pm b/FS/FS/cust_main/Packages.pm
index ca6a965..ace30d3 100644
--- a/FS/FS/cust_main/Packages.pm
+++ b/FS/FS/cust_main/Packages.pm
@@ -786,6 +786,105 @@ sub num_usage_pkgs {
   FS::Record->scalar_sql($sql, $self->custnum);
 }
 
+=item display_recurring
+
+Returns an array of hash references, one for each recurring freq
+on billable customer packages, with keys of freq, freq_pretty and amount
+(the amount that this customer will next be charged at the given frequency.)
+
+Results will be numerically sorted by freq.
+
+Only intended for display purposes, not used for actual billing.
+
+=cut
+
+sub display_recurring {
+  my $cust_main = shift;
+
+  my $sth = dbh->prepare("
+    SELECT DISTINCT freq FROM cust_pkg LEFT JOIN part_pkg USING (pkgpart)
+      WHERE freq IS NOT NULL AND freq != '0'
+        AND ( cancel IS NULL OR cancel = 0 )
+        AND custnum = ?
+  ") or die $DBI::errstr;
+
+  $sth->execute($cust_main->custnum) or die $sth->errstr;
+
+  #not really a numeric sort because freqs can actually be all sorts of things
+  # but good enough for the 99% cases of ordering monthly quarterly annually
+  my @freqs = sort { $a <=> $b } map { $_->[0] } @{ $sth->fetchall_arrayref };
+
+  $sth->finish;
+
+  my @out;
+
+  foreach my $freq (@freqs) {
+
+    my @cust_pkg = qsearch({
+      'table'     => 'cust_pkg',
+      'addl_from' => 'LEFT JOIN part_pkg USING (pkgpart)',
+      'hashref'   => { 'custnum' => $cust_main->custnum, },
+      'extra_sql' => 'AND ( cancel IS NULL OR cancel = 0 )
+                      AND freq = '. dbh->quote($freq),
+      'order_by'  => 'ORDER BY COALESCE(start_date,0), pkgnum', # to ensure old pkgs come before change_to_pkg
+    }) or next;
+
+    my $freq_pretty = $cust_pkg[0]->part_pkg->freq_pretty;
+
+    my $amount = 0;
+    my $skip_pkg = {};
+    foreach my $cust_pkg (@cust_pkg) {
+      my $part_pkg = $cust_pkg->part_pkg;
+      next if $cust_pkg->susp
+           && ! $cust_pkg->option('suspend_bill')
+           && ( ! $part_pkg->option('suspend_bill')
+                || $cust_pkg->option('no_suspend_bill')
+              );
+
+      #pkg change handling
+      next if $skip_pkg->{$cust_pkg->pkgnum};
+      if ($cust_pkg->change_to_pkgnum) {
+        #if change is on or before next bill date, use new pkg
+        next if $cust_pkg->expire <= $cust_pkg->bill;
+        #if change is after next bill date, use old (this) pkg
+        $skip_pkg->{$cust_pkg->change_to_pkgnum} = 1;
+      }
+
+      my $pkg_amount = 0;
+
+      #add recurring amounts for this package and its billing add-ons
+      foreach my $l_part_pkg ( $part_pkg->self_and_bill_linked ) {
+        $pkg_amount += $l_part_pkg->base_recur($cust_pkg);
+      }
+
+      #subtract amounts for any active discounts
+      #(there should only be one at the moment, otherwise this makes no sense)
+      foreach my $cust_pkg_discount ( $cust_pkg->cust_pkg_discount_active ) {
+        my $discount = $cust_pkg_discount->discount;
+        #and only one of these for each
+        $pkg_amount -= $discount->amount;
+        $pkg_amount -= $amount * $discount->percent/100;
+      }
+
+      $pkg_amount *= ( $cust_pkg->quantity || 1 );
+
+      $amount += $pkg_amount;
+
+    } #foreach $cust_pkg
+
+    next unless $amount;
+    push @out, {
+      'freq'        => $freq,
+      'freq_pretty' => $freq_pretty,
+      'amount'      => $amount,
+    };
+
+  } #foreach $freq
+
+  return @out;
+>>>>>>> 4b56fbb... RT#71890: SelfService API: Return monthly recurring fee [display_recurring]
+}
+
 =back
 
 =head1 BUGS
diff --git a/httemplate/view/cust_main/billing.html b/httemplate/view/cust_main/billing.html
index 08b4323..894b2df 100644
--- a/httemplate/view/cust_main/billing.html
+++ b/httemplate/view/cust_main/billing.html
@@ -26,79 +26,12 @@
 % # customer base, and compare it to a graph of the overhead for generating this
 % # information.  (and optimize it better, we could get it more from SQL)
 % if ( $cust_main->num_ncancelled_pkgs < 54 ) {
-%   my $sth = dbh->prepare("
-%     SELECT DISTINCT freq FROM cust_pkg LEFT JOIN part_pkg USING (pkgpart)
-%       WHERE freq IS NOT NULL AND freq != '0'
-%         AND ( cancel IS NULL OR cancel = 0 )
-%         AND custnum = ?
-%   ") or die $DBI::errstr;
-% 
-%   $sth->execute($cust_main->custnum) or die $sth->errstr;
-
-%   #not really a numeric sort because freqs can actually be all sorts of things
-%   # but good enough for the 99% cases of ordering monthly quarterly annually
-%   my @freqs = sort { $a <=> $b } map { $_->[0] } @{ $sth->fetchall_arrayref };
-% 
-%   foreach my $freq (@freqs) {
-%     my @cust_pkg = qsearch({
-%       'table'     => 'cust_pkg',
-%       'addl_from' => 'LEFT JOIN part_pkg USING (pkgpart)',
-%       'hashref'   => { 'custnum' => $cust_main->custnum, },
-%       'extra_sql' => 'AND ( cancel IS NULL OR cancel = 0 )
-%                       AND freq = '. dbh->quote($freq),
-%       'order_by'  => 'ORDER BY COALESCE(start_date,0), pkgnum', # to ensure old pkgs come before change_to_pkg
-%     }) or next;
-% 
-%     my $freq_pretty = $cust_pkg[0]->part_pkg->freq_pretty;
-%
-%     my $amount = 0;
-%     my $skip_pkg = {};
-%     foreach my $cust_pkg (@cust_pkg) {
-%       my $part_pkg = $cust_pkg->part_pkg;
-%       next if $cust_pkg->susp
-%            && ! $cust_pkg->option('suspend_bill')
-%            && ( ! $part_pkg->option('suspend_bill')
-%                 || $cust_pkg->option('no_suspend_bill')
-%               );
-%
-%       #pkg change handling
-%       next if $skip_pkg->{$cust_pkg->pkgnum};
-%       if ($cust_pkg->change_to_pkgnum) {
-%         #if change is on or before next bill date, use new pkg
-%         next if $cust_pkg->expire <= $cust_pkg->bill;
-%         #if change is after next bill date, use old (this) pkg
-%         $skip_pkg->{$cust_pkg->change_to_pkgnum} = 1;
-%       }
-%
-%       my $pkg_amount = 0;
-%
-%       #add recurring amounts for this package and its billing add-ons
-%       foreach my $l_part_pkg ( $part_pkg->self_and_bill_linked ) {
-%         $pkg_amount += $l_part_pkg->base_recur($cust_pkg);
-%       }
-%
-%       #subtract amounts for any active discounts
-%       #(there should only be one at the moment, otherwise this makes no sense)
-%       foreach my $cust_pkg_discount ( $cust_pkg->cust_pkg_discount_active ) {
-%         my $discount = $cust_pkg_discount->discount;
-%         #and only one of these for each
-%         $pkg_amount -= $discount->amount;
-%         $pkg_amount -= $amount * $discount->percent/100;
-%       }
-%
-%       $pkg_amount *= ( $cust_pkg->quantity || 1 );
-%
-%       $amount += $pkg_amount;
-%
-%     }
-   
+%   foreach my $freq_info ($cust_main->display_recurring) {
       <TR>
-        <TH ALIGN="right"><% emt( ucfirst($freq_pretty). ' recurring' ) %></TH>
-        <TD><% $money_char. sprintf('%.2f', $amount) %></TD>
-        </TD>
+        <TH ALIGN="right"><% emt( ucfirst($freq_info->{'freq_pretty'}). ' recurring' ) %></TH>
+        <TD><% $money_char. sprintf('%.2f', $freq_info->{'amount'}) %></TD>
       </TR>
 %   }
-
 % }
 
 % if ( $conf->exists('cust_main-select-prorate_day') ) {

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

Summary of changes:
 FS/FS/ClientAPI/MyAccount.pm                       |   23 +++++
 FS/FS/ClientAPI_XMLRPC.pm                          |    1 +
 FS/FS/cust_main/Packages.pm                        |   98 ++++++++++++++++++++
 ...xmlrpc-list_payby => xmlrpc-customer_recurring} |    4 +-
 fs_selfservice/FS-SelfService/SelfService.pm       |   26 ++++++
 httemplate/view/cust_main/billing.html             |   73 +--------------
 6 files changed, 153 insertions(+), 72 deletions(-)
 copy bin/{xmlrpc-list_payby => xmlrpc-customer_recurring} (85%)




More information about the freeside-commits mailing list