part_pkg option inheritance, part 1
authormark <mark>
Fri, 24 Dec 2010 09:49:32 +0000 (09:49 +0000)
committermark <mark>
Fri, 24 Dec 2010 09:49:32 +0000 (09:49 +0000)
27 files changed:
FS/FS/part_pkg.pm
FS/FS/part_pkg/agent.pm
FS/FS/part_pkg/base_delayed.pm
FS/FS/part_pkg/base_rate.pm
FS/FS/part_pkg/bulk.pm
FS/FS/part_pkg/cdr_termination.pm
FS/FS/part_pkg/flat.pm
FS/FS/part_pkg/flat_comission.pm
FS/FS/part_pkg/flat_comission_cust.pm
FS/FS/part_pkg/flat_comission_pkg.pm
FS/FS/part_pkg/flat_delayed.pm
FS/FS/part_pkg/flat_introrate.pm
FS/FS/part_pkg/global_Mixin.pm [new file with mode: 0644]
FS/FS/part_pkg/prepaid.pm
FS/FS/part_pkg/prorate.pm
FS/FS/part_pkg/prorate_delayed.pm
FS/FS/part_pkg/rt_time.pm
FS/FS/part_pkg/sesmon_hour.pm
FS/FS/part_pkg/sesmon_minute.pm
FS/FS/part_pkg/sql_external.pm
FS/FS/part_pkg/sql_generic.pm
FS/FS/part_pkg/sqlradacct_hour.pm
FS/FS/part_pkg/subscription.pm
FS/FS/part_pkg/usage_Mixin.pm [new file with mode: 0644]
FS/FS/part_pkg/voip_cdr.pm
FS/FS/part_pkg/voip_inbound.pm
FS/FS/part_pkg/voip_sqlradacct.pm

index 5c67ed9..58f7071 100644 (file)
@@ -1545,19 +1545,48 @@ foreach my $INC ( @INC ) {
       next;
     }
     warn "got plan info from FS::part_pkg::$mod: $info\n" if $DEBUG;
-    if ( exists($info->{'disabled'}) && $info->{'disabled'} ) {
-      warn "skipping disabled plan FS::part_pkg::$mod" if $DEBUG;
-      next;
-    }
+    #if ( exists($info->{'disabled'}) && $info->{'disabled'} ) {
+    #  warn "skipping disabled plan FS::part_pkg::$mod" if $DEBUG;
+    #  next;
+    #}
     $info{$mod} = $info;
+    $info->{'weight'} ||= 0; # quiet warnings
   }
 }
 
+# copy one level deep to allow replacement of fields and fieldorder
 tie %plans, 'Tie::IxHash',
-  map  { $_ => $info{$_} }
+  map  { my %infohash = %{ $info{$_} }; 
+          $_ => \%infohash }
   sort { $info{$a}->{'weight'} <=> $info{$b}->{'weight'} }
   keys %info;
 
+# inheritance of plan options
+foreach my $name (keys(%info)) {
+  if (exists($info{$name}->{'disabled'}) and $info{$name}->{'disabled'}) {
+    warn "skipping disabled plan FS::part_pkg::$name" if $DEBUG;
+    delete $plans{$name};
+    next;
+  }
+  my $parents = $info{$name}->{'inherit_fields'} || [];
+  my (%fields, %field_exists, @fieldorder);
+  foreach my $parent ($name, @$parents) {
+    %fields = ( # avoid replacing existing fields
+      %{ $info{$parent}->{'fields'} || {} },
+      %fields
+    );
+    foreach (@{ $info{$parent}->{'fieldorder'} || [] }) {
+      # avoid duplicates
+      next if $field_exists{$_};
+      $field_exists{$_} = 1;
+      # allow inheritors to remove inherited fields from the fieldorder
+      push @fieldorder, $_ if !exists($fields{$_}->{'disabled'});
+    }
+  }
+  $plans{$name}->{'fields'} = \%fields;
+  $plans{$name}->{'fieldorder'} = \@fieldorder;
+}
+
 sub plan_info {
   \%plans;
 }
index 69ecf77..6ab21d6 100644 (file)
@@ -19,16 +19,8 @@ $me = '[FS::part_pkg::agent]';
 %info = (
   'name'      => 'Wholesale bulk billing, for master customers of an agent.',
   'shortname' => 'Wholesale bulk billing for agent.',
-
+  '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,
@@ -49,8 +41,7 @@ $me = '[FS::part_pkg::agent]';
 
   },
 
-  #'fieldorder' => [qw( setup_fee recur_fee recur_method cutoff_day ) ],
-  'fieldorder' => [qw( setup_fee recur_fee cutoff_day add_full_period no_pkg_prorate ) ],
+  'fieldorder' => [qw( cutoff_day add_full_period no_pkg_prorate ) ],
 
   'weight' => 51,
 
index df50376..c6864a6 100644 (file)
@@ -11,28 +11,18 @@ use FS::part_pkg::base_rate;
   'name' => 'Free (or setup fee) for X days, then base rate'.
             ' (anniversary billing)',
   'shortname' => 'Bulk (manual from "units" option), w/intro period',
+  'inherit_fields' => [ 'global_Mixin' ],
   'fields' =>  {
-    'setup_fee' => { 'name' => 'Setup fee for this package',
-                     'default' => 0,
-                   },
     'free_days' => { 'name' => 'Initial free days',
                      'default' => 0,
                    },
-    'recur_fee' => { 'name' => 'Recurring base fee for this package',
-                     'default' => 0,
-                    },
     'recur_notify' => { 'name' => 'Number of days before recurring billing'.
                                   ' commences to notify customer. (0 means'.
                                   ' no warning)',
                      'default' => 0,
                     },
-    'unused_credit' => { 'name' => 'Credit the customer for the unused portion'.
-                                   ' of service at cancellation',
-                         'type' => 'checkbox',
-                       },
   },
-  'fieldorder' => [ 'free_days', 'setup_fee', 'recur_fee', 'recur_notify',
-                    'unused_credit'
+  'fieldorder' => [ 'free_days', 'recur_notify',
                   ],
   #'setup' => '\'my $d = $cust_pkg->bill || $time; $d += 86400 * \' + what.free_days.value + \'; $cust_pkg->bill($d); $cust_pkg_mod_flag=1; \' + what.setup_fee.value',
   #'recur' => 'what.recur_fee.value',
index 440e985..6781977 100644 (file)
@@ -12,23 +12,13 @@ use FS::part_pkg;
             # XXX it multiplies recurring fee by cust_pkg option "units", how to
             # express that
   'shortname' => 'Bulk (manual from "units" option)',
+  'inherit_fields' => [ 'global_Mixin' ],
   'fields' => {
-    'setup_fee'     => { 'name' => 'Setup fee for this package',
-                         'default' => 0,
-                       },
-    'recur_fee'     => { 'name' => 'Recurring Base fee for this package',
-                         'default' => 0,
-                       },
-    'unused_credit' => { 'name' => 'Credit the customer for the unused portion'.
-                                   ' of service at cancellation',
-                         'type' => 'checkbox',
-                       },
-    'externalid' => { 'name'   => 'Optional External ID',
+    'externalid' => { 'name'    => 'Optional External ID',
                       'default' => '',
                     },
   },
-  'fieldorder' => [ 'setup_fee', 'recur_fee', 'unused_credit', 
-                    'externalid' ],
+  'fieldorder' => [ qw( externalid ) ],
   'weight' => 52,
 );
 
@@ -59,13 +49,10 @@ sub base_recur {
 }
 
 sub calc_remain {
-  my ($self, $cust_pkg) = @_;
-  my $time = time;  #should be able to pass this in for credit calculation
+  my ($self, $cust_pkg, %options) = @_;
+  my $time = $options{'time'} || time;
   my $next_bill = $cust_pkg->getfield('bill') || 0;
-  my $last_bill = $cust_pkg->last_bill || 0;
-  return 0 if    ! $self->base_recur($cust_pkg)
-              || ! $self->option('unused_credit', 1)
-              || ! $last_bill
+  return 0 if  ! $self->base_recur($cust_pkg)
               || ! $next_bill
               || $next_bill < $time;
 
index b28fd30..0df929e 100644 (file)
@@ -12,23 +12,14 @@ $me = '[FS::part_pkg::bulk]';
 
 %info = (
   'name' => 'Bulk billing based on number of active services',
+  'inherit_fields' => [ 'global_Mixin' ],
   'fields' => {
-    'setup_fee' => { 'name'    => 'Setup fee for the entire bulk package',
-                     'default' => 0,
-                   },
-    'recur_fee' => { 'name'    => 'Recurring fee for the entire bulk package',
-                     'default' => 0,
-                   },
     'svc_setup_fee' => { 'name'    => 'Setup fee for each new service',
                          'default' => 0,
                        },
     'svc_recur_fee' => { 'name'    => 'Recurring fee for each service',
                          'default' => 0,
                        },
-    'unused_credit' => { 'name' => 'Credit the customer for the unused portion'.
-                                   ' of service at cancellation',
-                         'type' => 'checkbox',
-                       },
     'summarize_svcs'=> { 'name' => 'Show a count of services on the invoice, '.
                                    'instead of a detailed list',
                          'type' => 'checkbox',
@@ -38,8 +29,8 @@ $me = '[FS::part_pkg::bulk]';
                          'type' => 'checkbox',
                        },
   },
-  'fieldorder' => [ 'setup_fee', 'recur_fee', 'svc_setup_fee', 'svc_recur_fee',
-                    'unused_credit', 'summarize_svcs', 'no_prorate' ],
+  'fieldorder' => [ 'svc_setup_fee', 'svc_recur_fee',
+                    'summarize_svcs', 'no_prorate' ],
   'weight' => 50,
 );
 
index 0666d79..840da82 100644 (file)
@@ -16,15 +16,8 @@ tie my %temporalities, 'Tie::IxHash',
 %info = (
   'name' => 'VoIP rating of CDR records for termination partners.',
   'shortname' => 'VoIP/telco CDR termination',
+  'inherit_fields' => [ 'global_Mixin' ],
   'fields' => {
-
-    'setup_fee'     => { 'name' => 'Setup fee for this package',
-                         'default' => 0,
-                       },
-    'recur_fee'     => { 'name' => 'Base recurring fee for this package',
-                         'default' => 0,
-                       },
-
     #'cdr_column'    => { 'name' => 'Column from CDR records',
     #                     'type' => 'select',
     #                     'select_enum' => [qw(
@@ -49,11 +42,6 @@ tie my %temporalities, 'Tie::IxHash',
                              'select_options' => \%temporalities,
                            },
 
-    'unused_credit' => { 'name' => 'Credit the customer for the unused portion'.
-                                   ' of service at cancellation',
-                         'type' => 'checkbox',
-                       },
-
     'cutoff_day'    => { 'name' => 'Billing Day (1 - 28) for prorating or '.
                                    'subscription',
                          'default' => '1',
@@ -92,8 +80,7 @@ tie my %temporalities, 'Tie::IxHash',
   },
                        #cdr_column
   'fieldorder' => [qw(
-                       setup_fee recur_fee
-                       recur_temporality unused_credit recur_method cutoff_day
+                       recur_temporality recur_method cutoff_day
                        add_full_period
                        output_format usage_section summarize_usage usage_mandate
                      )
index e8f54d1..b5e0fa0 100644 (file)
@@ -2,8 +2,7 @@ package FS::part_pkg::flat;
 
 use strict;
 use vars qw( @ISA %info
-             %usage_fields %usage_recharge_fields
-             @usage_fieldorder @usage_recharge_fieldorder
+             %usage_recharge_fields @usage_recharge_fieldorder
            );
 use Tie::IxHash;
 use List::Util qw(min); # max);
@@ -26,97 +25,16 @@ tie my %contract_years, 'Tie::IxHash', (
   map { $_*12 => $_ } (1..5),
 );
 
-%usage_fields = (
-
-    'seconds'       => { 'name' => 'Time limit for this package',
-                         'default' => '',
-                         'check' => sub { shift =~ /^\d*$/ },
-                       },
-    'upbytes'       => { 'name' => 'Upload limit for this package',
-                         'default' => '',
-                         'check' => sub { shift =~ /^\d*$/ },
-                         'format' => \&FS::UI::bytecount::display_bytecount,
-                         'parse' => \&FS::UI::bytecount::parse_bytecount,
-                       },
-    'downbytes'     => { 'name' => 'Download limit for this package',
-                         'default' => '',
-                         'check' => sub { shift =~ /^\d*$/ },
-                         'format' => \&FS::UI::bytecount::display_bytecount,
-                         'parse' => \&FS::UI::bytecount::parse_bytecount,
-                       },
-    'totalbytes'    => { 'name' => 'Transfer limit for this package',
-                         'default' => '',
-                         'check' => sub { shift =~ /^\d*$/ },
-                         'format' => \&FS::UI::bytecount::display_bytecount,
-                         'parse' => \&FS::UI::bytecount::parse_bytecount,
-                       },
-);
-
-%usage_recharge_fields = (
-
-    'recharge_amount'       => { 'name' => 'Cost of recharge for this package',
-                         'default' => '',
-                         'check' => sub { shift =~ /^\d*(\.\d{2})?$/ },
-                       },
-    'recharge_seconds'      => { 'name' => 'Recharge time for this package',
-                         'default' => '',
-                         'check' => sub { shift =~ /^\d*$/ },
-                       },
-    'recharge_upbytes'      => { 'name' => 'Recharge upload for this package',
-                         'default' => '',
-                         'check' => sub { shift =~ /^\d*$/ },
-                         'format' => \&FS::UI::bytecount::display_bytecount,
-                         'parse' => \&FS::UI::bytecount::parse_bytecount,
-                       },
-    'recharge_downbytes'    => { 'name' => 'Recharge download for this package',
-                         'default' => '',
-                         'check' => sub { shift =~ /^\d*$/ },
-                         'format' => \&FS::UI::bytecount::display_bytecount,
-                         'parse' => \&FS::UI::bytecount::parse_bytecount,
-                       },
-    'recharge_totalbytes'   => { 'name' => 'Recharge transfer for this package',
-                         'default' => '',
-                         'check' => sub { shift =~ /^\d*$/ },
-                         'format' => \&FS::UI::bytecount::display_bytecount,
-                         'parse' => \&FS::UI::bytecount::parse_bytecount,
-                       },
-    'usage_rollover' => { 'name' => 'Allow usage from previous period to roll '.
-                                    ' over into current period',
-                          'type' => 'checkbox',
-                        },
-    'recharge_reset' => { 'name' => 'Reset usage to these values on manual '.
-                                    'package recharge',
-                          'type' => 'checkbox',
-                        },
-);
-
-@usage_fieldorder = qw( seconds upbytes downbytes totalbytes );
-@usage_recharge_fieldorder = qw(
-  recharge_amount recharge_seconds recharge_upbytes
-  recharge_downbytes recharge_totalbytes
-  usage_rollover recharge_reset
-);
-
 %info = (
   'name' => 'Flat rate (anniversary billing)',
   'shortname' => 'Anniversary',
+  'inherit_fields' => [ 'usage_Mixin', 'global_Mixin' ],
   'fields' => {
-    'setup_fee'     => { 'name' => 'Setup fee for this package',
-                         'default' => 0,
-                       },
-    'recur_fee'     => { 'name' => 'Recurring fee for this package',
-                         'default' => 0,
-                       },
-
     #false laziness w/voip_cdr.pm
     'recur_temporality' => { 'name' => 'Charge recurring fee for period',
                              'type' => 'select',
                              'select_options' => \%temporalities,
                            },
-    'unused_credit' => { 'name' => 'Credit the customer for the unused portion'.
-                                   ' of service at cancellation',
-                         'type' => 'checkbox',
-                       },
 
     #used in cust_pkg.pm so could add to any price plan
     'expire_months' => { 'name' => 'Auto-add an expiration date this number of months out',
@@ -145,22 +63,16 @@ tie my %contract_years, 'Tie::IxHash', (
                           'type' => 'checkbox',
                         },
 
-    %usage_fields,
-    %usage_recharge_fields,
-
     'externalid' => { 'name'   => 'Optional External ID',
                       'default' => '',
                     },
   },
-  'fieldorder' => [ qw( setup_fee recur_fee
-                        recur_temporality unused_credit
+  'fieldorder' => [ qw( recur_temporality 
                         expire_months adjourn_months
                         contract_end_months
                         start_1st sync_bill_date
                         suspend_bill unsuspend_adjust_bill
-                      ),
-                    @usage_fieldorder, @usage_recharge_fieldorder,
-                    qw( externalid ),
+                        externalid ),
                   ],
   'weight' => 10,
 );
@@ -239,12 +151,7 @@ sub calc_remain {
 
   my $next_bill = $cust_pkg->getfield('bill') || 0;
 
-  #my $last_bill = $cust_pkg->last_bill || 0;
-  my $last_bill = $cust_pkg->get('last_bill') || 0; #->last_bill falls back to setup
-
   return 0 if    ! $self->base_recur($cust_pkg)
-              || ! $self->option('unused_credit', 1)
-              || ! $last_bill
               || ! $next_bill
               || $next_bill < $time;
 
index c05e455..ec8c8eb 100644 (file)
@@ -10,17 +10,8 @@ use FS::part_pkg::flat;
 %info = (
   'name' => 'Flat rate with recurring commission per (any) active package',
   'shortname' => 'Commission per (any) active package',
+  'inherit_fields' => [ 'global_Mixin' ],
   'fields' => {
-    'setup_fee'     => { 'name' => 'Setup fee for this package',
-                         'default' => 0,
-                       },
-    'recur_fee'     => { 'name' => 'Recurring fee for this package',
-                         'default' => 0,
-                       },
-    'unused_credit' => { 'name' => 'Credit the customer for the unused portion'.
-                                   ' of service at cancellation',
-                         'type' => 'checkbox',
-                       },
     'comission_amount' => { 'name' => 'Commission amount per month (per active package)',
                             'default' => 0,
                           },
@@ -35,7 +26,7 @@ use FS::part_pkg::flat;
                             'select_label' => 'type',
                           },
   },
-  'fieldorder' => [ 'setup_fee', 'recur_fee', 'unused_credit', 'comission_depth', 'comission_amount', 'reason_type' ],
+  'fieldorder' => [ 'comission_depth', 'comission_amount', 'reason_type' ],
   #'setup' => 'what.setup_fee.value',
   #'recur' => '\'my $error = $cust_pkg->cust_main->credit( \' + what.comission_amount.value + \' * scalar($cust_pkg->cust_main->referral_cust_pkg(\' + what.comission_depth.value+ \')), "commission" ); die $error if $error; \' + what.recur_fee.value + \';\'',
   'weight' => 62,
index 5db4658..5acf73d 100644 (file)
@@ -10,32 +10,9 @@ use FS::part_pkg::flat;
 %info = (
   'name' => 'Flat rate with recurring commission per active customer',
   'shortname' => 'Commission per active customer',
-  'fields' => {
-    'setup_fee' => { 'name' => 'Setup fee for this package',
-                     'default' => 0,
-                   },
-    'recur_fee' => { 'name' => 'Recurring fee for this package',
-                     'default' => 0,
-                   },
-    'unused_credit' => { 'name' => 'Credit the customer for the unused portion'.
-                                   ' of service at cancellation',
-                         'type' => 'checkbox',
-                       },
-    'comission_amount' => { 'name' => 'Commission amount per month (per active customer)',
-                            'default' => 0,
-                          },
-    'comission_depth'  => { 'name' => 'Number of layers',
-                            'default' => 1,
-                          },
-    'reason_type'      => { 'name' => 'Reason type for commission credits',
-                            'type' => 'select_table',
-                            'select_table' => 'reason_type',
-                            'select_hash'  => { 'class' => 'R' },
-                            'select_key'   => 'typenum',
-                            'select_label' => 'type',
-                          },
-  },
-  'fieldorder' => [ 'setup_fee', 'recur_fee', 'unused_credit', 'comission_depth', 'comission_amount', 'reason_type' ],
+  'inherit_fields' => [ 'flat_comission', 'global_Mixin' ],
+  'fields' => { },
+  'fieldorder' => [ ],
   #'setup' => 'what.setup_fee.value',
   #'recur' => '\'my $error = $cust_pkg->cust_main->credit( \' + what.comission_amount.value + \' * scalar($cust_pkg->cust_main->referral_cust_main_ncancelled(\' + what.comission_depth.value+ \')), "commission" ); die $error if $error; \' + what.recur_fee.value + \';\'',
   'weight' => '60',
index 6f5ee69..26dd4d2 100644 (file)
@@ -10,23 +10,8 @@ use FS::part_pkg::flat;
 %info = (
   'name' => 'Flat rate with recurring commission per (selected) active package',
   'shortname' => 'Commission per (selected) active package',
+  'inherit_fields' => [ 'flat_comission', 'global_Mixin' ],
   'fields' => {
-    'setup_fee' => { 'name' => 'Setup fee for this package',
-                     'default' => 0,
-                   },
-    'recur_fee' => { 'name' => 'Recurring fee for this package',
-                     'default' => 0,
-                   },
-    'unused_credit' => { 'name' => 'Credit the customer for the unused portion'.
-                                   ' of service at cancellation',
-                         'type' => 'checkbox',
-                       },
-    'comission_amount' => { 'name' => 'Commission amount per month (per uncancelled package)',
-                            'default' => 0,
-                          },
-    'comission_depth'  => { 'name' => 'Number of layers',
-                            'default' => 1,
-                          },
     'comission_pkgpart' => { 'name' => 'Applicable packages<BR><FONT SIZE="-1">(hold <b>ctrl</b> to select multiple packages)</FONT>',
                              'type' => 'select_multiple',
                              'select_table' => 'part_pkg',
@@ -34,15 +19,8 @@ use FS::part_pkg::flat;
                              'select_key'   => 'pkgpart',
                              'select_label' => 'pkg',
                            },
-    'reason_type'       => { 'name' => 'Reason type for commission credits',
-                             'type' => 'select',
-                             'select_table' => 'reason_type',
-                             'select_hash'  => { 'class' => 'R' } ,
-                             'select_key'   => 'typenum',
-                             'select_label' => 'type',
-                           },
   },
-  'fieldorder' => [ 'setup_fee', 'recur_fee', 'unused_credit', 'comission_depth', 'comission_amount', 'comission_pkgpart', 'reason_type' ],
+  'fieldorder' => [ 'comission_depth', 'comission_amount', 'comission_pkgpart', 'reason_type' ],
   #'setup' => 'what.setup_fee.value',
   #'recur' => '""; var pkgparts = ""; for ( var c=0; c < document.flat_comission_pkg.comission_pkgpart.options.length; c++ ) { if (document.flat_comission_pkg.comission_pkgpart.options[c].selected) { pkgparts = pkgparts + document.flat_comission_pkg.comission_pkgpart.options[c].value + \', \'; } } what.recur.value = \'my $error = $cust_pkg->cust_main->credit( \' + what.comission_amount.value + \' * scalar( grep { my $pkgpart = $_->pkgpart; grep { $_ == $pkgpart } ( \' + pkgparts + \'  ) } $cust_pkg->cust_main->referral_cust_pkg(\' + what.comission_depth.value+ \')), "commission" ); die $error if $error; \' + what.recur_fee.value + \';\'',
   #'disabled' => 1,
index 33f9dd8..b4be72b 100644 (file)
@@ -11,28 +11,18 @@ use FS::part_pkg::flat;
   'name' => 'Free (or setup fee) for X days, then flat rate'.
             ' (anniversary billing)',
   'shortname' => 'Anniversary, with intro period',
+  'inherit_fields' => [ 'global_Mixin' ],
   'fields' =>  {
-    'setup_fee' => { 'name' => 'Setup fee for this package',
-                     'default' => 0,
-                   },
     'free_days' => { 'name' => 'Initial free days',
                      'default' => 0,
                    },
-    'recur_fee' => { 'name' => 'Recurring fee for this package',
-                     'default' => 0,
-                    },
     'recur_notify' => { 'name' => 'Number of days before recurring billing'.
                                   ' commences to notify customer. (0 means'.
                                   ' no warning)',
                      'default' => 0,
                     },
-    'unused_credit' => { 'name' => 'Credit the customer for the unused portion'.
-                                   ' of service at cancellation',
-                         'type' => 'checkbox',
-                       },
-  },
-  'fieldorder' => [ 'free_days', 'setup_fee', 'recur_fee', 'recur_notify',
-                    'unused_credit'
+      },
+  'fieldorder' => [ 'free_days', 'recur_notify',
                   ],
   #'setup' => '\'my $d = $cust_pkg->bill || $time; $d += 86400 * \' + what.free_days.value + \'; $cust_pkg->bill($d); $cust_pkg_mod_flag=1; \' + what.setup_fee.value',
   #'recur' => 'what.recur_fee.value',
@@ -58,11 +48,6 @@ sub calc_remain {
   return 0 if    $last_bill + (86400 * $free_days) == $next_bill
               && $last_bill == $cust_pkg->setup;
 
-  return 0 if    ! $self->base_recur($cust_pkg)
-              || ! $self->option('unused_credit', 1)
-              || ! $last_bill
-              || ! $next_bill;
-
   return $self->SUPER::calc_remain($cust_pkg, %options);
 }
 
index 2d551f1..1447730 100644 (file)
@@ -2,7 +2,6 @@ package FS::part_pkg::flat_introrate;
 
 use strict;
 use vars qw(@ISA %info $DEBUG $me);
-#use FS::Record qw(qsearch qsearchs);
 use FS::part_pkg::flat;
 
 use Date::Manip qw(DateCalc UnixDate ParseDate);
@@ -11,22 +10,23 @@ use Date::Manip qw(DateCalc UnixDate ParseDate);
 $me = '[' . __PACKAGE__ . ']';
 $DEBUG = 0;
 
-(%info) = (%FS::part_pkg::flat::info);
-$info{name} = 'Introductory price for X months, then flat rate,'.
-              'relative to setup date (anniversary billing)';
-$info{shortname} = 'Anniversary, with intro price';
-$info{fields} = { %{$info{fields}} };
-$info{fields}{intro_fee} =
-         { 'name' => 'Introductory recurring fee for this package',
+%info = (
+  'name' => 'Introductory price for X months, then flat rate,'.
+            'relative to setup date (anniversary billing)',
+  'shortname' => 'Anniversary, with intro price',
+  'inherit_fields' => [ 'flat', 'usage_Mixin', 'global_Mixin' ],
+  'fields' => {
+    'intro_fee' => { 'name' => 'Introductory recurring fee for this package',
                      'default' => 0,
-         };
-$info{fields}{intro_duration} =
+                   },
+    'intro_duration' =>
          { 'name' => 'Duration of the introductory period, in number of months',
            'default' => 0,
-         };
-$info{fieldorder} = [ @{ $info{fieldorder} } ];
-splice @{$info{fieldorder}}, 1, 0, qw( intro_duration intro_fee );
-$info{weight} = 14;
+         },
+  },
+  'fieldorder' => [ qw(intro_duration intro_fee) ],
+  'weight' => 14,
+);
 
 sub base_recur {
   my($self, $cust_pkg, $time ) = @_;
diff --git a/FS/FS/part_pkg/global_Mixin.pm b/FS/FS/part_pkg/global_Mixin.pm
new file mode 100644 (file)
index 0000000..56f1602
--- /dev/null
@@ -0,0 +1,38 @@
+package FS::part_pkg::global_Mixin;
+
+use strict;
+use vars qw(@ISA %info);
+use FS::part_pkg;
+@ISA = qw(FS::part_pkg);
+
+%info = (
+  'disabled' => 1,
+  'fields' => {
+    'setup_fee' => { 
+      'name' => 'Setup fee for this package',
+      'default' => 0,
+    },
+    'recur_fee' => { 
+      'name' => 'Recurring fee for this package',
+      'default' => 0,
+    },
+    'unused_credit_cancel' => {
+      'name' => 'Credit the customer for the unused portion of service at '.
+                 'cancellation',
+      'type' => 'checkbox',
+    },
+    'unused_credit_change' => {
+      'name' => 'Credit the customer for the unused portion of service when '.
+                'changing packages',
+      'type' => 'checkbox',
+    },
+  },
+  'fieldorder' => [ qw(
+    setup_fee
+    recur_fee
+    unused_credit_cancel
+    unused_credit_change
+  )],
+);
+
+1;
index cff165a..407343b 100644 (file)
@@ -21,28 +21,25 @@ tie my %overlimit_action, 'Tie::IxHash',
   'name' => 'Prepaid, flat rate',
   #'name' => 'Prepaid (no automatic recurring)', #maybe use it here too
   'shortname' => 'Prepaid, no automatic cycle',
+  'inherit_fields' => [ 'usage_Mixin', 'global_Mixin' ],
   'fields' => {
-    'setup_fee'   =>  { 'name' => 'One-time setup fee for this package',
-                        'default' => 0,
-                      },
-    'recur_fee'   =>  { 'name' => 'Initial and recharge fee for this package',
-                        'default' => 0,
-                      },
     'recur_action' => { 'name' => 'Action to take upon reaching end of prepaid preiod',
                         'type' => 'select',
                        'select_options' => \%recur_action,
                      },
-    %FS::part_pkg::flat::usage_fields,
     'overlimit_action' => { 'name' => 'Action to take upon reaching a usage limit.',
                             'type' => 'select',
                             'select_options' => \%overlimit_action,
                      },
     #XXX if you set overlimit_action to 'cancel', should also have the ability
     # to select a reason
+    
+    # do we need to disable these?
+    map { $_ => { 'disabled' => 1 } } (
+      qw(recharge_amount recharge_seconds recharge_upbytes recharge_downbytes
+      recharge_totalbytes usage_rollover recharge_reset) ),
   },
-  'fieldorder' => [ qw( setup_fee recur_fee recur_action ),
-                    @FS::part_pkg::flat::usage_fieldorder, 'overlimit_action',
-                  ],
+  'fieldorder' => [ qw( recur_action overlimit_action ) ],
   'weight' => 25,
 );
 
index 4abdb8d..367f152 100644 (file)
@@ -11,74 +11,14 @@ use FS::part_pkg::flat;
 %info = (
   'name' => 'First partial month pro-rated, then flat-rate (selectable billing day)',
   'shortname' => 'Prorate (Nth of month billing)',
+  'inherit_fields' => [ 'flat', 'usage_Mixin', 'global_Mixin' ],
   'fields' => {
-    'setup_fee' => { 'name' => 'Setup fee for this package',
-                     'default' => 0,
-                   },
-    'recur_fee' => { 'name' => 'Recurring fee for this package',
-                     'default' => 0,
-                    },
-    'unused_credit' => { 'name' => 'Credit the customer for the unused portion'.
-                                   ' of service at cancellation',
-                         'type' => 'checkbox',
-                       },
+    'recur_temporality' => {'disabled' => 1},
+    'sync_bill_date' => {'disabled' => 1},
     'cutoff_day' => { 'name' => 'Billing Day (1 - 28)',
                       'default' => 1,
                     },
-    'seconds'       => { 'name' => 'Time limit for this package',
-                         'default' => '',
-                         'check' => sub { shift =~ /^\d*$/ },
-                       },
-    'upbytes'       => { 'name' => 'Upload limit for this package',
-                         'default' => '',
-                         'check' => sub { shift =~ /^\d*$/ },
-                        'format' => \&FS::UI::bytecount::display_bytecount,
-                        'parse' => \&FS::UI::bytecount::parse_bytecount,
-                       },
-    'downbytes'     => { 'name' => 'Download limit for this package',
-                         'default' => '',
-                         'check' => sub { shift =~ /^\d*$/ },
-                        'format' => \&FS::UI::bytecount::display_bytecount,
-                        'parse' => \&FS::UI::bytecount::parse_bytecount,
-                       },
-    'totalbytes'    => { 'name' => 'Transfer limit for this package',
-                         'default' => '',
-                         'check' => sub { shift =~ /^\d*$/ },
-                        'format' => \&FS::UI::bytecount::display_bytecount,
-                        'parse' => \&FS::UI::bytecount::parse_bytecount,
-                       },
-    'recharge_amount'       => { 'name' => 'Cost of recharge for this package',
-                         'default' => '',
-                         'check' => sub { shift =~ /^\d*(\.\d{2})?$/ },
-                       },
-    'recharge_seconds'      => { 'name' => 'Recharge time for this package',
-                         'default' => '',
-                         'check' => sub { shift =~ /^\d*$/ },
-                       },
-    'recharge_upbytes'      => { 'name' => 'Recharge upload for this package',
-                         'default' => '',
-                         'check' => sub { shift =~ /^\d*$/ },
-                        'format' => \&FS::UI::bytecount::display_bytecount,
-                        'parse' => \&FS::UI::bytecount::parse_bytecount,
-                       },
-    'recharge_downbytes'    => { 'name' => 'Recharge download for this package',                         'default' => '',
-                         'check' => sub { shift =~ /^\d*$/ },
-                        'format' => \&FS::UI::bytecount::display_bytecount,
-                        'parse' => \&FS::UI::bytecount::parse_bytecount,
-                       },
-    'recharge_totalbytes'   => { 'name' => 'Recharge transfer for this package',                         'default' => '',
-                         'check' => sub { shift =~ /^\d*$/ },
-                        'format' => \&FS::UI::bytecount::display_bytecount,
-                        'parse' => \&FS::UI::bytecount::parse_bytecount,
-                       },
-    'usage_rollover' => { 'name' => 'Allow usage from previous period to roll '.
-                                   'over into current period',
-                         'type' => 'checkbox',
-                        },
-    'recharge_reset' => { 'name' => 'Reset usage to these values on manual '.
-                                    'package recharge',
-                          'type' => 'checkbox',
-                        },
+
     'add_full_period'=> { 'name' => 'When prorating first month, also bill '.
                                     'for one full period after that',
                           'type' => 'checkbox',
@@ -88,18 +28,8 @@ use FS::part_pkg::flat;
                                     'the nearest full day',
                           'type' => 'checkbox',
                         },
-
-    #it would be better if this had to be turned on, its confusing
-    'externalid' => { 'name'   => 'Optional External ID',
-                      'default' => '',
-                    },
   },
-  'fieldorder' => [ 'setup_fee', 'recur_fee', 'unused_credit', 'cutoff_day',
-                    'seconds', 'upbytes', 'downbytes', 'totalbytes',
-                    'recharge_amount', 'recharge_seconds', 'recharge_upbytes',
-                    'recharge_downbytes', 'recharge_totalbytes',
-                    'usage_rollover', 'recharge_reset', 'add_full_period',
-                    'prorate_round_day', 'externalid', ],
+  'fieldorder' => [ 'cutoff_day', 'add_full_period', 'prorate_round_day' ],
   'freq' => 'm',
   'weight' => 20,
 );
index 0073493..dd1b816 100644 (file)
@@ -11,27 +11,18 @@ use FS::part_pkg;
   'name' => 'Free (or setup fee) for X days, then prorate, then flat-rate ' .
          '(1st of month billing)',
   'shortname' => 'Prorate (Nth of month billing), with intro period', #??
+  'inherit_fields' => [ 'global_Mixin' ],
   'fields' =>  {
-    'setup_fee' => { 'name' => 'Setup fee for this package',
-                     'default' => 0,
-                   },
     'free_days' => { 'name' => 'Initial free days',
-                     'default' => 0,
-                   },
-    'recur_fee' => { 'name' => 'Recurring fee for this package',
-                     'default' => 0,
+                  'default' => 0,
                     },
     'recur_notify' => { 'name' => 'Number of days before recurring billing'.
                                   ' commences to notify customer. (0 means'.
                                   ' no warning)',
                      'default' => 0,
                     },
-    'unused_credit' => { 'name' => 'Credit the customer for the unused portion'.
-                                   ' of service at cancellation',
-                         'type' => 'checkbox',
-                       },
   },
-  'fieldorder' => [ 'free_days', 'setup_fee', 'recur_fee', 'unused_credit' ],
+  'fieldorder' => [ 'free_days', 'recur_notify' ],
   #'setup' => '\'my $d = $cust_pkg->bill || $time; $d += 86400 * \' + what.free_days.value + \'; $cust_pkg->bill($d); $cust_pkg_mod_flag=1; \' + what.setup_fee.value',
   #'recur' => 'what.recur_fee.value',
   'weight' => 22,
@@ -49,18 +40,13 @@ sub calc_setup {
 
 sub calc_remain {
   my ($self, $cust_pkg, %options) = @_;
-  my $next_bill = $cust_pkg->getfield('bill') || 0;
   my $last_bill = $cust_pkg->last_bill || 0;
+  my $next_bill = $cust_pkg->getfield('bill') || 0;
   my $free_days = $self->option('free_days');
 
   return 0 if    $last_bill + (86400 * $free_days) == $next_bill
               && $last_bill == $cust_pkg->setup;
 
-  return 0 if    ! $self->base_recur($cust_pkg)
-              || ! $self->option('unused_credit', 1)
-              || ! $last_bill
-              || ! $next_bill;
-
   return $self->SUPER::calc_remain($cust_pkg, %options);
 }
 
index 9452d44..03ed1cd 100644 (file)
@@ -14,11 +14,14 @@ our %info = (
   'name'      =>  'Bill from Time Worked on tickets in RT',
   'shortname' =>  'Project Billing (RT)',
   'weight'    => 55,
+  'inherit_fields' => [ 'global_Mixin' ],
   'fields'    =>  {
     'base_rate' =>  {   'name'    =>  'Rate (per minute)',
                         'default' => 0,
                     },
-  }
+    'recur_fee' => {'disabled' => 1},
+  },
+  'fieldorder' => [ 'base_rate' ],
 );
 
 sub calc_setup {
index e608d55..97274d0 100644 (file)
@@ -10,17 +10,8 @@ use FS::part_pkg::flat;
 %info = (
   'name' => 'Base charge plus charge per-hour from the session monitor',
   'shortname' => 'Session monitor (per-hour)',
+  'inherit_fields' => [ 'global_Mixin' ],
   'fields' => {
-    'setup_fee' => { 'name' => 'Setup fee for this package',
-                     'default' => 0,
-                   },
-    'recur_fee' => { 'name' => 'Base recurring fee for this package',
-                     'default' => 0,
-                   },
-    'unused_credit' => { 'name' => 'Credit the customer for the unused portion'.
-                                   ' of service at cancellation',
-                         'type' => 'checkbox',
-                       },
     'recur_included_hours' => { 'name' => 'Hours included',
                                 'default' => 0,
                               },
@@ -28,7 +19,7 @@ use FS::part_pkg::flat;
                                'default' => 0,
                              },
   },
-  'fieldorder' => [ 'setup_fee', 'recur_fee', 'unused_credit', 'recur_included_hours', 'recur_hourly_charge' ],
+  'fieldorder' => [ 'recur_included_hours', 'recur_hourly_charge' ],
   #'setup' => 'what.setup_fee.value',
   #'recur' => '\'my $hours = $cust_pkg->seconds_since($cust_pkg->bill || 0) / 3600 - \' + what.recur_included_hours.value + \'; $hours = 0 if $hours < 0; \' + what.recur_fee.value + \' + \' + what.recur_hourly_charge.value + \' * $hours;\'',
   'weight' => 80,
index 654fdf5..9c8dfd1 100644 (file)
@@ -10,17 +10,8 @@ use FS::part_pkg::flat;
 %info = (
   'name' => 'Base charge plus charge per-minute from the session monitor',
   'shortname' => 'Session monitor (per-minute)',
+  'inherit_fields' => [ 'global_Mixin' ],
   'fields' => {
-    'setup_fee' => { 'name' => 'Setup fee for this package',
-                     'default' => 0,
-                   },
-    'recur_fee' => { 'name' => 'Base recurring fee for this package',
-                     'default' => 0,
-                   },
-    'unused_credit' => { 'name' => 'Credit the customer for the unused portion'.
-                                   ' of service at cancellation',
-                         'type' => 'checkbox',
-                       },
     'recur_included_min' => { 'name' => 'Minutes included',
                               'default' => 0,
                               },
@@ -28,7 +19,7 @@ use FS::part_pkg::flat;
                               'default' => 0,
                             },
   },
-  'fieldorder' => [ 'setup_fee', 'recur_fee', 'unused_credit', 'recur_included_min', 'recur_minly_charge' ],
+  'fieldorder' => [ 'recur_included_min', 'recur_minly_charge' ],
   #'setup' => 'what.setup_fee.value',
   #'recur' => '\'my $min = $cust_pkg->seconds_since($cust_pkg->bill || 0) / 60 - \' + what.recur_included_min.value + \'; $min = 0 if $min < 0; \' + what.recur_fee.value + \' + \' + what.recur_minly_charge.value + \' * $min;\'',
   'weight' => 80,
index 8e803f9..8d43086 100644 (file)
@@ -9,17 +9,8 @@ use DBI;
 %info = (
   'name' => 'Base charge plus additional fees for external services from a configurable SQL query',
   'shortname' => 'External SQL query',
+  'inherit_fields' => [ 'global_Mixin' ],
   'fields' => {
-    'setup_fee' => { 'name' => 'Setup fee for this package',
-                     'default' => 0,
-                   },
-    'recur_fee' => { 'name' => 'Base recurring fee for this package',
-                     'default' => 0,
-                   },
-    'unused_credit' => { 'name' => 'Credit the customer for the unused portion'.
-                                   ' of service at cancellation',
-                         'type' => 'checkbox',
-                       },
     'cutoff_day'    => { 'name' => 'Billing Day (1 - 28) for prorating or '.
                                    'subscription',
                          'default' => '1',
@@ -48,7 +39,7 @@ use DBI;
                  'default' => '',
                },
   },
-  'fieldorder' => [qw( setup_fee recur_fee unused_credit recur_method cutoff_day
+  'fieldorder' => [qw( recur_method cutoff_day
                       add_full_period datasrc db_username db_password query 
                   )],
   'weight' => '58',
index eb80044..cf38257 100644 (file)
@@ -11,17 +11,8 @@ use FS::part_pkg::flat;
 %info = (
   'name' => 'Base charge plus a per-domain metered rate from a configurable SQL query',
   'shortname' => 'Bulk (per-domain from SQL query)',
+  'inherit_fields' => [ 'global_Mixin' ],
   'fields' => {
-    'setup_fee' => { 'name' => 'Setup fee for this package',
-                     'default' => 0,
-                   },
-    'recur_fee' => { 'name' => 'Base recurring fee for this package',
-                     'default' => 0,
-                   },
-    'unused_credit' => { 'name' => 'Credit the customer for the unused portion'.
-                                   ' of service at cancellation',
-                         'type' => 'checkbox',
-                       },
     'recur_included' => { 'name' => 'Units included',
                           'default' => 0,
                         },
@@ -41,7 +32,7 @@ use FS::part_pkg::flat;
                  'default' => '',
                },
   },
-  'fieldorder' => [qw( setup_fee recur_fee unused_credit recur_included recur_unit_charge datasrc db_username db_password query )],
+  'fieldorder' => [qw( recur_included recur_unit_charge datasrc db_username db_password query )],
  # 'setup' => 'what.setup_fee.value',
  # 'recur' => '\'my $dbh = DBI->connect(\"\' + what.datasrc.value + \'\", \"\' + what.db_username.value + \'\") or die $DBI::errstr; \'',
  #'recur' => '\'my $dbh = DBI->connect(\"\' + what.datasrc.value + \'\", \"\' + what.db_username.value + \'\", \"\' + what.db_password.value + \'\" ) or die $DBI::errstr; my $sth = $dbh->prepare(\"\' + what.query.value + \'\") or die $dbh->errstr; my $units = 0; foreach my $cust_svc ( grep { $_->part_svc->svcdb eq \"svc_domain\" } $cust_pkg->cust_svc ) { my $domain = $cust_svc->svc_x->domain; $sth->execute($domain) or die $sth->errstr; $units += $sth->fetchrow_arrayref->[0]; } $units -= \' + what.recur_included.value + \'; $units = 0 if $units < 0; \' + what.recur_fee.value + \' + $units * \' + what.recur_unit_charge.value + \';\'',
index 15f678f..3cc46ac 100644 (file)
@@ -10,18 +10,8 @@ use FS::part_pkg::flat;
 %info = (
   'name' => 'Base charge plus per-hour (and for data) from an SQL RADIUS radacct table',
   'shortname' => 'Usage charges from RADIUS',
+  'inherit_fields' => [ 'global_Mixin' ],
   'fields' => {
-    'setup_fee' => { 'name' => 'Setup fee for this package',
-                     'default' => 0,
-                   },
-    'recur_fee' => { 'name' => 'Base recurring fee for this package',
-                     'default' => 0,
-                   },
-    'unused_credit' => { 'name' => 'Credit the customer for the unused portion'.
-                                   ' of service at cancellation',
-                         'type' => 'checkbox',
-                       },
-
     'recur_included_hours' => { 'name' => 'Hours included',
                                 'default' => 0,
                               },
@@ -77,7 +67,7 @@ use FS::part_pkg::flat;
                             },
 
   },
-  'fieldorder' => [qw( setup_fee recur_fee unused_credit recur_included_hours recur_hourly_charge recur_hourly_cap recur_included_input recur_input_charge recur_input_cap recur_included_output recur_output_charge recur_output_cap recur_included_total recur_total_charge recur_total_cap global_cap )],
+  'fieldorder' => [qw( recur_included_hours recur_hourly_charge recur_hourly_cap recur_included_input recur_input_charge recur_input_cap recur_included_output recur_output_charge recur_output_cap recur_included_total recur_total_charge recur_total_cap global_cap )],
   #'setup' => 'what.setup_fee.value',
   #'recur' => '\'my $last_bill = $cust_pkg->last_bill; my $hours = $cust_pkg->seconds_since_sqlradacct($last_bill, $sdate ) / 3600 - \' + what.recur_included_hours.value + \'; $hours = 0 if $hours < 0; my $input = $cust_pkg->attribute_since_sqlradacct($last_bill, $sdate, \"AcctInputOctets\" ) / 1048576; my $output = $cust_pkg->attribute_since_sqlradacct($last_bill, $sdate, \"AcctOutputOctets\" ) / 1048576; my $total = $input + $output - \' + what.recur_included_total.value + \'; $total = 0 if $total < 0; my $input = $input - \' + what.recur_included_input.value + \'; $input = 0 if $input < 0; my $output = $output - \' + what.recur_included_output.value + \'; $output = 0 if $output < 0; my $totalcharge = sprintf(\"%.2f\", \' + what.recur_total_charge.value + \' * $total); my $inputcharge = sprintf(\"%.2f\", \' + what.recur_input_charge.value + \' * $input); my $outputcharge = sprintf(\"%.2f\", \' + what.recur_output_charge.value + \' * $output); my $hourscharge = sprintf(\"%.2f\", \' + what.recur_hourly_charge.value + \' * $hours); if ( \' + what.recur_total_charge.value + \' > 0 ) { push @details, \"Last month\\\'s data \". sprintf(\"%.1f\", $total). \" megs: \\\$$totalcharge\" } if ( \' + what.recur_input_charge.value + \' > 0 ) { push @details, \"Last month\\\'s download \". sprintf(\"%.1f\", $input). \" megs: \\\$$inputcharge\" } if ( \' + what.recur_output_charge.value + \' > 0 ) { push @details, \"Last month\\\'s upload \". sprintf(\"%.1f\", $output). \" megs: \\\$$outputcharge\" } if ( \' + what.recur_hourly_charge.value + \' > 0 ) { push @details, \"Last month\\\'s time \". sprintf(\"%.1f\", $hours). \" hours: \\\$$hourscharge\"; } \' + what.recur_fee.value + \' + $hourscharge + $inputcharge + $outputcharge + $totalcharge ;\'',
   'weight' => 40,
index 5495e3a..3c5f96b 100644 (file)
@@ -11,13 +11,8 @@ use FS::part_pkg::flat;
 %info = (
   'name' => 'First partial month full charge, then flat-rate (selectable billing day)',
   'shortname' => 'Subscription (Nth of month, full charge for first)',
+  'inherit_fields' => [ 'usage_Mixin', 'global_Mixin' ],
   'fields' => {
-    'setup_fee' => { 'name' => 'Setup fee for this package',
-                     'default' => 0,
-                   },
-    'recur_fee' => { 'name' => 'Recurring fee for this package',
-                     'default' => 0,
-                          },
     'cutoff_day' => { 'name' => 'Billing day',
                       'default' => 1,
                     },
@@ -81,7 +76,7 @@ use FS::part_pkg::flat;
                       'default' => '',
                     },
   },
-  'fieldorder' => [ 'setup_fee', 'recur_fee', 'cutoff_day', 'seconds',
+  'fieldorder' => [ 'cutoff_day', 'seconds',
                     'upbytes', 'downbytes', 'totalbytes',
                     'recharge_amount', 'recharge_seconds', 'recharge_upbytes',
                     'recharge_downbytes', 'recharge_totalbytes',
diff --git a/FS/FS/part_pkg/usage_Mixin.pm b/FS/FS/part_pkg/usage_Mixin.pm
new file mode 100644 (file)
index 0000000..028fce7
--- /dev/null
@@ -0,0 +1,77 @@
+package FS::part_pkg::usage_Mixin;
+
+use strict;
+use vars qw( @ISA %info );
+use FS::part_pkg;
+use FS::UI::bytecount;
+@ISA = qw(FS::part_pkg);
+
+# Field definitions for time and data usage, other than CDRs.
+
+%info = (
+  'disabled' => 1,
+  'fields' => {
+    'seconds'       => { 'name' => 'Time limit for this package',
+                         'default' => '',
+                         'check' => sub { shift =~ /^\d*$/ },
+                       },
+    'upbytes'       => { 'name' => 'Upload limit for this package',
+                         'default' => '',
+                         'check' => sub { shift =~ /^\d*$/ },
+                         'format' => \&FS::UI::bytecount::display_bytecount,
+                         'parse' => \&FS::UI::bytecount::parse_bytecount,
+                       },
+    'downbytes'     => { 'name' => 'Download limit for this package',
+                         'default' => '',
+                         'check' => sub { shift =~ /^\d*$/ },
+                         'format' => \&FS::UI::bytecount::display_bytecount,
+                         'parse' => \&FS::UI::bytecount::parse_bytecount,
+                       },
+    'totalbytes'    => { 'name' => 'Transfer limit for this package',
+                         'default' => '',
+                         'check' => sub { shift =~ /^\d*$/ },
+                         'format' => \&FS::UI::bytecount::display_bytecount,
+                         'parse' => \&FS::UI::bytecount::parse_bytecount,
+                       },
+    'recharge_amount'       => { 'name' => 'Cost of recharge for this package',
+                         'default' => '',
+                         'check' => sub { shift =~ /^\d*(\.\d{2})?$/ },
+                       },
+    'recharge_seconds'      => { 'name' => 'Recharge time for this package',
+                         'default' => '',
+                         'check' => sub { shift =~ /^\d*$/ },
+                       },
+    'recharge_upbytes'      => { 'name' => 'Recharge upload for this package',
+                         'default' => '',
+                         'check' => sub { shift =~ /^\d*$/ },
+                         'format' => \&FS::UI::bytecount::display_bytecount,
+                         'parse' => \&FS::UI::bytecount::parse_bytecount,
+                       },
+    'recharge_downbytes'    => { 'name' => 'Recharge download for this package',
+                         'default' => '',
+                         'check' => sub { shift =~ /^\d*$/ },
+                         'format' => \&FS::UI::bytecount::display_bytecount,
+                         'parse' => \&FS::UI::bytecount::parse_bytecount,
+                       },
+    'recharge_totalbytes'   => { 'name' => 'Recharge transfer for this package',
+                         'default' => '',
+                         'check' => sub { shift =~ /^\d*$/ },
+                         'format' => \&FS::UI::bytecount::display_bytecount,
+                         'parse' => \&FS::UI::bytecount::parse_bytecount,
+                       },
+    'usage_rollover' => { 'name' => 'Allow usage from previous period to roll '.
+                                    ' over into current period',
+                          'type' => 'checkbox',
+                        },
+    'recharge_reset' => { 'name' => 'Reset usage to these values on manual '.
+                                    'package recharge',
+                          'type' => 'checkbox',
+                        },
+  },
+  'fieldorder' => [ qw( seconds upbytes downbytes totalbytes
+                        recharge_amount recharge_seconds recharge_upbytes
+                        recharge_downbytes recharge_totalbytes 
+                        usage_rollover recharge_reset ) ],
+);
+
+1;
index 768f894..5dbd115 100644 (file)
@@ -48,25 +48,14 @@ tie my %granularity, 'Tie::IxHash', FS::rate_detail::granularities();
 %info = (
   'name' => 'VoIP rating by plan of CDR records in an internal (or external) SQL table',
   'shortname' => 'VoIP/telco CDR rating (standard)',
+  'inherit_fields' => [ 'global_Mixin' ],
   'fields' => {
-    'setup_fee'     => { 'name' => 'Setup fee for this package',
-                         'default' => 0,
-                       },
-    'recur_fee'     => { 'name' => 'Base recurring fee for this package',
-                         'default' => 0,
-                       },
-
     #false laziness w/flat.pm
     'recur_temporality' => { 'name' => 'Charge recurring fee for period',
                              'type' => 'select',
                              'select_options' => \%temporalities,
                            },
 
-    'unused_credit' => { 'name' => 'Credit the customer for the unused portion'.
-                                   ' of service at cancellation',
-                         'type' => 'checkbox',
-                       },
-
     'cutoff_day'    => { 'name' => 'Billing Day (1 - 28) for prorating or '.
                                    'subscription',
                          'default' => '1',
@@ -259,7 +248,7 @@ tie my %granularity, 'Tie::IxHash', FS::rate_detail::granularities();
 
   },
   'fieldorder' => [qw(
-                       setup_fee recur_fee recur_temporality unused_credit
+                       recur_temporality
                        recur_method cutoff_day
                        add_full_period
                        cdr_svc_method
index 8b1844a..1b91575 100644 (file)
@@ -24,25 +24,13 @@ tie my %granularity, 'Tie::IxHash', FS::rate_detail::granularities();
 %info = (
   'name' => 'VoIP flat rate pricing of CDRs for inbound calls',
   'shortname' => 'VoIP/telco CDR rating (inbound)',
+  'inherit_fields' => [ 'global_Mixin' ],
   'fields' => {
-    'setup_fee'     => { 'name' => 'Setup fee for this package',
-                         'default' => 0,
-                       },
-    'recur_fee'     => { 'name' => 'Base recurring fee for this package',
-                         'default' => 0,
-                       },
-
     #false laziness w/flat.pm
     'recur_temporality' => { 'name' => 'Charge recurring fee for period',
                              'type' => 'select',
                              'select_options' => \%temporalities,
                            },
-
-    'unused_credit' => { 'name' => 'Credit the customer for the unused portion'.
-                                   ' of service at cancellation',
-                         'type' => 'checkbox',
-                       },
-
     'cutoff_day'    => { 'name' => 'Billing Day (1 - 28) for prorating or '.
                                    'subscription',
                          'default' => '1',
@@ -155,7 +143,7 @@ tie my %granularity, 'Tie::IxHash', FS::rate_detail::granularities();
 
   },
   'fieldorder' => [qw(
-                       setup_fee recur_fee recur_temporality unused_credit
+                       recur_temporality
                        recur_method cutoff_day add_full_period
                        min_charge sec_granularity
                        default_prefix
index 441df58..5388767 100644 (file)
@@ -16,17 +16,8 @@ $DEBUG = 1;
   'disabled' => 1, #they're sucked into our CDR table now instead
   'name' => 'VoIP rating by plan of CDR records in an SQL RADIUS radacct table',
   'shortname' => 'VoIP/telco CDR rating (external RADIUS)',
+  'inherit_fields' => [ 'global_Mixin' ],
   'fields' => {
-    'setup_fee'     => { 'name' => 'Setup fee for this package',
-                         'default' => 0,
-                       },
-    'recur_fee'     => { 'name' => 'Base recurring fee for this package',
-                         'default' => 0,
-                       },
-    'unused_credit' => { 'name' => 'Credit the customer for the unused portion'.
-                                   ' of service at cancellation',
-                         'type' => 'checkbox',
-                       },
     'ratenum'   => { 'name' => 'Rate plan',
                      'type' => 'select',
                      'select_table' => 'rate',
@@ -34,7 +25,7 @@ $DEBUG = 1;
                      'select_label' => 'ratename',
                    },
   },
-  'fieldorder' => [qw( setup_fee recur_fee unused_credit ratenum ignore_unrateable )],
+  'fieldorder' => [qw( ratenum ignore_unrateable )],
   'weight' => 40,
 );