Merge branch 'master' of git.freeside.biz:/home/git/freeside
[freeside.git] / httemplate / edit / part_pkg.cgi
index 65eca6c..9f5510d 100755 (executable)
@@ -28,7 +28,7 @@
 
      'onsubmit'              => 'confirm_submit',
 
-     'labels' => { 
+     'labels' => {
                    'pkgpart'          => 'Package Definition',
                    'pkg'              => 'Package',
                    %locale_field_labels,
                    'plan'             => 'Price plan',
                    'disabled'         => 'Disable new orders',
                    'disable_line_item_date_ranges' => 'Disable line item date ranges',
+                   'start_on_hold'    => 'Start on hold',
                    'setup_cost'       => 'Setup cost',
                    'recur_cost'       => 'Recur cost',
                    'pay_weight'       => 'Payment weight',
                    'credit_weight'    => 'Credit weight',
                    'agent_pkgpartid'  => 'External ID',
                    'agentnum'         => 'Agent',
+                   'agent_type'       => ' ', #just its title headingn is fine
                    'setup_fee'        => 'Setup fee',
                    'setup_show_zero'  => 'Show zero setup',
                    'recur_fee'        => 'Recurring fee',
                    'svc_dst_pkgpart'  => 'Include services of package',
                    'supp_dst_pkgpart' => 'When ordering package, also order',
                    'report_option'    => 'Report classes',
-                   'fcc_ds0s'         => 'Voice-grade equivalents',
-                   'fcc_voip_class'   => 'Category',
                    'delay_start'      => 'Default delay (days)',
+                   'adjourn_months'   => 'Suspend the package after ',
+                   'contract_end_months' => 'Contract ends after ',
+                   'expire_months'    => 'Cancel the package after ',
+                   'change_to_pkgpart'=> 'and replace it with ',
                  },
 
      'fields' => [
                      ),
                      {field=>'disabled', type=>$disabled_type, value=>'Y'},
                      {field=>'disable_line_item_date_ranges', type=>$disabled_type, value=>'Y'},
+                     { field => 'start_on_hold',
+                       type => 'checkbox',
+                       value => 'Y'
+                     },
 
                      { type     => 'tablebreak-tr-title',
                        value    => 'Pricing', #better name?
                          sort $conf->config('currencies')
                      ),
 
+                     ( $conf->exists('part_pkg-delay_start')
+                       ? ( { type  => 'tablebreak-tr-title',
+                             value => 'Delayed start',
+                           },
+                           { field => 'delay_start',
+                             type => 'text', size => 6 },
+                         )
+                       : ()
+                     ),
+
+                     { type   => 'tablebreak-tr-title',
+                       value  => 'Limited duration',
+                     },
+                     { field  => 'adjourn_months',
+                       type   => 'select-months',
+                     },
+                     { field  => 'contract_end_months',
+                       type   => 'select-months',
+                     },
+                     { field  => 'expire_months',
+                       type   => 'select-expire_months',
+                     },
+                     { field  => 'change_to_pkgpart',
+                       type   => 'select-part_pkg',
+                       extra_sql  => sub { $pkgpart
+                        ? "AND pkgpart != $pkgpart"
+                        : ''
+                       },
+                       empty_label => 'no package',
+                     },
+
                      #price plan
                      #setup fee
                      #recurring frequency
                        type  => 'hidden',
                        value => join(',', @taxproductnums),
                      },
-                     { field => 'taxproduct_select',
-                       type  => 'selectlayers',
-                       options => [ '(default)', @taxproductnums ],
-                       curr_value => '(default)',
-                       labels  => { ( '(default)' => '(default)' ),
-                                    map {($_=>$usage_class{$_})}
-                                    @taxproductnums
-                                  },
-                       layer_fields => \%taxproduct_fields,
-                       layer_values_callback => $taxproduct_values,
-                       layers_only  =>   !$taxproducts,
-                       cell_style   => ( !$taxproducts
-                                         ? 'display:none'
-                                         : ''
-                                       ),
+                     #{ field => 'taxproduct_select',
+                     #  type  => 'selectlayers',
+                     #  options => [ '(default)', @taxproductnums ],
+                     #  curr_value => '(default)',
+                     #  labels  => { ( '(default)' => '(default)' ),
+                     #               map {($_=>$usage_class{$_})}
+                     #               @taxproductnums
+                     #             },
+                     #  layer_fields => \%taxproduct_fields,
+                     #  layer_values_callback => $taxproduct_values,
+                     #  layers_only  =>   !$taxproducts,
+                     #  cell_style   => ( !$taxproducts
+                     #                    ? 'display:none'
+                     #                    : ''
+                     #                  ),
+                     #},
+                     { field => 'taxproductnum',
+                       type  => 'part_pkg-taxproducts',
+                       include_opt_callback =>
+                         sub { pkgpart => $_[0]->pkgpart },
                      },
 
                      { type  => 'tablebreak-tr-title',
                          )
                      ),
 
-                     ( $conf->exists('part_pkg-delay_start')
-                       ? ( { type  => 'tablebreak-tr-title',
-                             value => 'Delayed start',
-                           },
-                           { field => 'delay_start',
-                             type => 'text', size => 6 },
-                         )
-                       : ()
-                     ),
-
                    { type => 'columnnext' },
 
-                     { field    => 'agent_type',
-                       type     => 'select-agent_types',
-                       disabled => ! $acl_edit_global,
+                     {type=>'justtitle', value=>'Agent (reseller) types' },
+
+                     { field       => 'agent_type',
+                       type        => 'select-agent_type',
+                       disabled    => ! $acl_edit_global,
+                       element_etc => 'size="10"',
+                       multiple    =>  '1', #cause edit.html is dum
                        curr_value_callback => sub {
                          my($cgi, $object, $field) = @_;
                          #in the other callbacks..?  hmm.
@@ -406,7 +444,7 @@ my $agent_clone_extra_sql =
   ' ) ';
 
 my $conf = new FS::Conf;
-my $taxproducts = $conf->exists('enable_taxproducts');
+my $taxproducts = $conf->config('tax_data_vendor') ne '';
 
 my $fcc_opts = $conf->exists('part_pkg-show_fcc_options');
 
@@ -551,6 +589,11 @@ my $error_callback = sub {
     'cgiparam'
   );
 
+  if ( $cgi->param('error') =~ / is suggested with / ) {
+    #yeah, detection is a shitty kludge, but we don't have exception objects
+    $opt->{form_init} = '<INPUT TYPE="checkbox" NAME="part_pkg_restrict_soft_override" VALUE="Y"> Override suggestion<BR><BR>';
+  }
+
 };
 
 my $new_hashref_callback = sub { { 'plan' => 'flat' }; };
@@ -644,8 +687,7 @@ my $new_callback = sub {
   my $conf = new FS::Conf; 
 
   if ( $conf->exists('agent_defaultpkg') ) {
-    #my @all_agent_types = map {$_->typenum} qsearch('agent_type',{});
-    @agent_type = map {$_->typenum} qsearch('agent_type',{});
+    @agent_type = map {$_->typenum} qsearch('agent_type', { 'disabled'=>'' });
   }
 
   $options{'suspend_bill'}=1 if $conf->exists('part_pkg-default_suspend_bill');
@@ -885,6 +927,11 @@ my $javascript = <<'END';
       }
     }
 
+    function finish_edit_fcc(id) {
+      cClick();
+      show_fcc_options(id); // refresh the display
+    }
+
 END
 
 my $warning =
@@ -945,7 +992,30 @@ my $html_bottom = sub {
     my @fields = exists($plans{$layer}->{'fieldorder'})
                    ? @{$plans{$layer}->{'fieldorder'}}
                    : keys %{ $href };
-  
+    
+    # hash of dependencies for each of the Pricing Plan fields.
+    # make sure NOT to use double-quotes inside the 'msg' value.
+    my $dependencies = {
+        'unused_credit_suspend' => {
+            'msg'       => q|You must set the 'suspend_credit_type' option in Configuration->Settings to gain access to this option.|,
+            'are_met'   => sub{
+                my $conf = new FS::conf;
+                my @conf_info = qsearch('conf', { 'name' => 'suspend_credit_type' } );
+                return 1 if (exists($conf_info[0]) && $conf_info[0]->{Hash}{value});
+                return 0;
+            }
+        },
+        'unused_credit_cancel' => {
+            'msg'       => q|You must set the 'cancel_credit_type' option in Configuration->Settings to gain access to this option.|,
+            'are_met'   => sub{
+                my $conf = new FS::conf;
+                my @conf_info = qsearch('conf', { 'name' => 'cancel_credit_type' } );
+                return 1 if (exists($conf_info[0]) && $conf_info[0]->{Hash}{value});
+                return 0;
+            }
+        }
+    };
+    
     foreach my $field ( grep $_ !~ /^(setup|recur)_fee$/, @fields ) {
   
       if(!exists($href->{$field})) {
@@ -967,7 +1037,10 @@ my $html_bottom = sub {
       #XXX these should use elements/ fields... (or this whole thing should
       #just use layer_fields instead of layer_callback)
   
-      if ( ! exists($href->{$field}{'type'}) ) {
+      if (exists($dependencies->{$field}) && !$dependencies->{$field}{'are_met'}()) {
+          $html .= q!<span title="!.$dependencies->{$field}{'msg'}.q!">N/A</span>!;
+          
+      } elsif ( ! exists($href->{$field}{'type'}) ) {
   
         $html .= qq!<INPUT TYPE="text" NAME="${layer}__$field" VALUE="!.
                  ( exists($options{$field})
@@ -1077,9 +1150,9 @@ my $html_bottom = sub {
     '<SCRIPT TYPE="text/javascript">'.
       include('/elements/selectlayers.html', %selectlayers, 'js_only'=>1 );
 
-  $return .=
-    "taxproduct_selectchanged(document.getElementById('taxproduct_select'));\n"
-      if $taxproducts;
+#  $return .=
+#    "taxproduct_selectchanged(document.getElementById('taxproduct_select'));\n"
+#      if $taxproducts;
 
   $return .= '</SCRIPT>';
 
@@ -1170,6 +1243,11 @@ my $field_callback = sub {
                            };
     $fieldref->{layer_fields} = \%taxproduct_fields;
     $fieldref->{layer_values_callback} = $taxproduct_values;
+  } elsif ($field eq 'taxproductnum') { # part_pkg-taxproduct, new style
+    if ( !$taxproducts ) {
+      # then make the widget go away
+      $fieldref->{type} = 'hidden';
+    }
   }
 };