add skip_dcontext_suffix to skip CDRs with dcontext ending in a definable string...
[freeside.git] / FS / FS / part_pkg / agent.pm
index e5bd163..1a5b615 100644 (file)
@@ -1,34 +1,23 @@
 package FS::part_pkg::agent;
+#use base qw(FS::part_pkg::recur_Common);
+use base qw(FS::part_pkg::prorate);
 
 use strict;
-use vars qw(@ISA $DEBUG $me %info);
+use vars qw($DEBUG $me %info);
 use Date::Format;
 use FS::Record qw( qsearch );
 use FS::agent;
 use FS::cust_main;
 
-#use FS::part_pkg::recur_Common;;
-#@ISA = qw(FS::part_pkg::recur_Common);
-use FS::part_pkg::prorate;
-@ISA = qw(FS::part_pkg::prorate);
-
 $DEBUG = 0;
 
 $me = '[FS::part_pkg::agent]';
 
 %info = (
-  'name'      => 'Wholesale bulk billing, for master customers of an agent.',
-  'shortname' => 'Wholesale bulk billing for agent.',
-
+  'name'      => 'Wholesale billing based on package prices, for master customers of an agent.',
+  'shortname' => 'Wholesale billing for agent (package prices)',
+  'inherit_fields' => [qw( prorate global_Mixin)],
   'fields' => {
-    'setup_fee'     => { 'name' => 'Setup fee for this package',
-                         'default' => 0,
-                       },
-    'recur_fee'     => { 'name' => 'Base recurring fee for this package',
-                         'default' => 0,
-                       },
-
-
     #'recur_method'  => { 'name' => 'Recurring fee method',
     #                     #'type' => 'radio',
     #                     #'options' => \%recur_method,
@@ -38,17 +27,28 @@ $me = '[FS::part_pkg::agent]';
     'cutoff_day'    => { 'name' => 'Billing Day (1 - 28)',
                          'default' => '1',
                        },
+    'add_full_period'=> { 'name' => 'When prorating first month, also bill '.
+                                    'for one full period after that',
+                          'type' => 'checkbox',
+                        },
 
     'no_pkg_prorate'   => { 'name' => 'Disable prorating bulk packages (charge full price for packages active only a portion of the month)',
                             'type' => 'checkbox',
                           },
 
+    'display_separate_cust'=> { 'name' => 'Separate customer from package display on invoices',
+                                'type' => 'checkbox',
+                              },
+
+    'cost_only' => { 'name' => 'Bill wholesale on cost only, disabling the price fallback',
+                     'type' => 'checkbox' 
+                   },
+
   },
 
-  #'fieldorder' => [qw( setup_fee recur_fee recur_method cutoff_day ) ],
-  'fieldorder' => [qw( setup_fee recur_fee cutoff_day no_pkg_prorate ) ],
+  'fieldorder' => [qw( cutoff_day add_full_period no_pkg_prorate display_separate_cust cost_only) ],
 
-  'weight' => 51,
+  'weight' => 52,
 
 );
 
@@ -64,6 +64,7 @@ sub calc_recur {
 
   my $conf = new FS::Conf;
   my $money_char = $conf->config('money_char') || '$';
+  my $date_format = $conf->config('date_format') || '%m/%d/%Y';
 
   my $total_agent_charge = 0;
 
@@ -93,46 +94,67 @@ sub calc_recur {
         if $DEBUG;
 
       #make sure setup dates are filled in
-      my $error = $cust_main->bill; #options don't propogate from freeside-daily
+      my $error = $cust_main->bill( time => $$sdate );
       die "Error pre-billing agent customer: $error" if $error;
 
       my @cust_pkg = grep { my $setup  = $_->get('setup');
                             my $cancel = $_->get('cancel');
 
+                            #$setup <= $$sdate  # ?
                             $setup < $$sdate  # END
                             && ( ! $cancel || $cancel > $last_bill ) #START
                           }
                      $cust_main->all_pkgs;
 
+      my $cust_details = 0;
+
       foreach my $cust_pkg ( @cust_pkg ) {
 
         warn "$me billing agent charges for pkgnum ". $cust_pkg->pkgnum. "\n"
           if $DEBUG;
 
-        my $pkg_details = $cust_main->name_short. ': '; #name?
+        my $pkg_details = '';
+
+        my $cust_location = $cust_pkg->cust_location;
+        $pkg_details .= $cust_location->locationname. ': '
+          if $cust_location->locationname;
+
+        my $part_pkg = $cust_pkg->part_pkg;
+
         # + something to identify package... primary service probably
+        # no... package def for now
+        $pkg_details .= $part_pkg->pkg. ': ';
 
         my $pkg_charge = 0;
 
-        my $part_pkg = $cust_pkg->part_pkg;
-        #option to not fallback? via options above
-        my $pkg_setup_fee  =
-          $part_pkg->setup_cost || $part_pkg->option('setup_fee');
-        my $pkg_base_recur =
-          $part_pkg->recur_cost || $part_pkg->base_recur_permonth($cust_pkg);
+        my $quantity = $cust_pkg->quantity || 1;
+
+        my $pkg_setup_fee  = $part_pkg->setup_cost;
+        $pkg_setup_fee ||= $part_pkg->option('setup_fee')
+          unless $self->option('cost_only');
+        $pkg_setup_fee ||= 0;
+
+        my $pkg_base_recur = $part_pkg->recur_cost;
+        $pkg_base_recur ||= $part_pkg->base_recur_permonth($cust_pkg)
+          unless $self->option('cost_only');
+        $pkg_base_recur ||= 0;
 
         my $pkg_start = $cust_pkg->get('setup');
         if ( $pkg_start < $last_bill ) {
           $pkg_start = $last_bill;
         } elsif ( $pkg_setup_fee ) {
-          $pkg_charge += $pkg_setup_fee;
-          $pkg_details .= $money_char. sprintf('%.2f setup, ', $pkg_setup_fee );
+          $pkg_charge += $quantity * $pkg_setup_fee;
+          $pkg_details .= $money_char.
+                          sprintf('%.2f setup', $quantity * $pkg_setup_fee );
+          $pkg_details .= sprintf(" ($quantity \@ $money_char". '%.2f)',
+                                  $pkg_setup_fee )
+            if $quantity > 1;
+          $pkg_details .= ', ';
         }
 
         my $pkg_end = $cust_pkg->get('cancel');
         $pkg_end = ( !$pkg_end || $pkg_end > $$sdate ) ? $$sdate : $pkg_end;
 
-
         my $pkg_recur_charge = $prorate_ratio * $pkg_base_recur;
         $pkg_recur_charge *= ( $pkg_end - $pkg_start )
                            / ( $$sdate  - $last_bill )
@@ -140,19 +162,33 @@ sub calc_recur {
 
         my $recur_charge += $pkg_recur_charge;
 
-        $pkg_details .= $money_char. sprintf('%.2f', $recur_charge ).
-                        ' ('.  time2str('%x', $pkg_start).
-                        ' - '. time2str('%x', $pkg_end  ). ')'
-          if $recur_charge;
+        if ( $recur_charge ) {
+          $pkg_details .= $money_char.
+                          sprintf('%.2f', $quantity * $recur_charge );
+          $pkg_details .= sprintf(" ($quantity \@ $money_char". '%.2f)',
+                                  $recur_charge )
+            if $quantity > 1;
+          $pkg_details .= ' ('.  time2str($date_format, $pkg_start).
+                          ' - '. time2str($date_format, $pkg_end  ). ')';
+        }
 
-        $pkg_charge += $recur_charge;
+        $pkg_charge += $quantity * $recur_charge;
+
+        if ( $pkg_charge ) {
+          if ( $self->option('display_separate_cust') ) {
+            push @$details, $cust_main->name.':' unless $cust_details++;
+            push @$details, '    '.$pkg_details;
+          } else {
+            push @$details, $cust_main->name_short.': '. $pkg_details;
+          }
+        };
 
-        push @$details, $pkg_details
-          if $pkg_charge;
         $total_agent_charge += $pkg_charge;
 
       } #foreach $cust_pkg
 
+      push @$details, ' ' if $cust_details;
+
     } #foreach $cust_main
 
   } #foreach $agent;
@@ -165,13 +201,11 @@ sub calc_recur {
 
 sub can_discount { 0; }
 
-sub hide_svc_detail {
-  1;
-}
+sub hide_svc_detail { 1; }
 
-sub is_free {
-  0;
-}
+sub is_free { 0; }
+
+sub can_usageprice { 0; }
 
 1;