X-Git-Url: http://git.freeside.biz/gitweb/?p=freeside.git;a=blobdiff_plain;f=httemplate%2Fedit%2Fpart_pkg.cgi;h=0a0b01e1148d63ea132cb1c22fb239fd93b5dda3;hp=778a0265e023e872b9a7440e5ff3f97810437703;hb=50cc2b95894b151599b458462dcd83edb68980ce;hpb=315ffb86414145b95f2541db8f9d89c1f7e71e3f diff --git a/httemplate/edit/part_pkg.cgi b/httemplate/edit/part_pkg.cgi index 778a0265e..0a0b01e11 100755 --- a/httemplate/edit/part_pkg.cgi +++ b/httemplate/edit/part_pkg.cgi @@ -9,8 +9,10 @@ #'viewall_dir' => 'browse', 'viewall_url' => $p.'browse/part_pkg.cgi', 'html_init' => include('/elements/init_overlib.html'). + include('/elements/init_calendar.html'). $javascript, 'html_bottom' => $html_bottom, + 'extra_fields_validate' => $validate_priceplan_fields, 'body_etc' => 'onLoad="agent_changed(document.edit_topform.agentnum); aux_planchanged(document.edit_topform.plan); @@ -28,7 +30,7 @@ 'onsubmit' => 'confirm_submit', - 'labels' => { + 'labels' => { 'pkgpart' => 'Package Definition', 'pkg' => 'Package', %locale_field_labels, @@ -40,7 +42,6 @@ 'setuptax' => 'Setup fee tax exempt', 'recurtax' => 'Recurring fee tax exempt', 'taxclass' => 'Tax class', - 'taxproduct_select'=> 'Tax products', 'plan' => 'Price plan', 'disabled' => 'Disable new orders', 'disable_line_item_date_ranges' => 'Disable line item date ranges', @@ -68,9 +69,12 @@ '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 ', + 'units_taxproductnum' => 'Per-line tax product', }, 'fields' => [ @@ -90,7 +94,7 @@ { type => 'columnstart' }, { field => 'pkg', - type => 'text', + type => 'input-locale-text', size => 40, #32 maxlength => 50, }, @@ -166,14 +170,44 @@ 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 part_pkg.pkgpart != $pkgpart" + : '' + }, + empty_label => 'no package', + }, + #price plan #setup fee #recurring frequency #recurring fee (auto-disable) - { type => 'columnnext' }, + { type => 'columnnext', value=>'Taxation', }, - {type=>'justtitle', value=>'Taxation' }, {field=>'setuptax', type=>'checkbox', value=>'Y'}, {field=>'recurtax', type=>'checkbox', value=>'Y'}, {field=>'taxclass', type=>'select-taxclass' }, @@ -181,23 +215,15 @@ 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 => 'taxproductnum', + type => 'part_pkg-taxproducts', + include_opt_callback => + sub { pkgpart => $_[0]->pkgpart }, + }, + { field => 'units_taxproductnum', + type => ($tax_data_vendor ? + 'select-taxproduct' : 'hidden'), }, - { type => 'tablebreak-tr-title', value => 'Promotions', #better name? }, @@ -216,19 +242,7 @@ ) ), - ( $conf->exists('part_pkg-delay_start') - ? ( { type => 'tablebreak-tr-title', - value => 'Delayed start', - }, - { field => 'delay_start', - type => 'text', size => 6 }, - ) - : () - ), - - { type => 'columnnext' }, - - {type=>'justtitle', value=>'Agent (reseller) types' }, + { type => 'columnnext', value=>'Agent (reseller) types' }, { field => 'agent_type', type => 'select-agent_type', @@ -269,7 +283,7 @@ { field=>'agent_pkgpartid', type=>'text', size=>21 }, { type => 'tablebreak-tr-title', - value => 'Line-item revenue recogition', #better name? + value => 'Line-item revenue recognition', #better name? }, { field=>'pay_weight', type=>'text', size=>6 }, { field=>'credit_weight', type=>'text', size=>6 }, @@ -298,6 +312,7 @@ 'name_col' => 'name', 'hashref' => { 'disabled' => '' }, 'multiple' => 1, + 'curr_value_callback' => $report_option_value_callback, }, { 'type' => 'tablebreak-tr-title', @@ -323,7 +338,7 @@ { 'field' => 'bill_dst_pkgpart', 'type' => 'select-part_pkg', 'extra_sql' => sub { $pkgpart - ? "AND pkgpart != $pkgpart" + ? "AND part_pkg.pkgpart != $pkgpart" : '' }, 'label_callback' => sub { shift->pkg_comment_only }, @@ -350,7 +365,7 @@ 'label' => 'Also include services from package: ', 'type' => 'select-part_pkg', 'extra_sql' => sub { $pkgpart - ? "AND pkgpart != $pkgpart" + ? "AND part_pkg.pkgpart != $pkgpart" : '' }, 'label_callback' => sub { shift->pkg_comment_only }, @@ -416,7 +431,7 @@ my $agent_clone_extra_sql = ' ) '; my $conf = new FS::Conf; -my $taxproducts = $conf->exists('enable_taxproducts'); +my $tax_data_vendor = $conf->config('tax_data_vendor'); my $fcc_opts = $conf->exists('part_pkg-show_fcc_options'); @@ -467,42 +482,6 @@ my $recur_show_zero_disabled = 1; my $pkgpart = ''; -my $splice_locale_fields = sub { - my( $fields, $pkey_value_callback, $pkg_value_callback ) = @_; - - my $n = 0; - my @locale_fields = ( - map { - my $pkey_value= $pkey_value_callback ? &$pkey_value_callback($_) : ''; - my $pkg_value = $pkg_value_callback - ? $pkg_value_callback eq 'cgiparam' - ? $cgi->param('pkgpartmsgnum'. $n. '_pkg') - : &$pkg_value_callback($_) - : ''; - ( - { field => 'pkgpartmsgnum'. $n, - type => 'hidden', - value => $pkey_value, - }, - { field => 'pkgpartmsgnum'. $n. '_locale', - type => 'hidden', - value => $_, - }, - { field => 'pkgpartmsgnum'. $n++. '_pkg', - type => 'text', - size => 40, - #maxlength => 50, - value => $pkg_value, - }, - ); - - } - @locales - ); - splice(@$fields, 7, 0, @locale_fields); #XXX 7 is arbitrary above - -}; - my $error_callback = sub { my($cgi, $object, $fields, $opt ) = @_; @@ -551,15 +530,10 @@ my $error_callback = sub { $pkgpart = $object->pkgpart; - &$splice_locale_fields( - $fields, - sub { - my $locale = shift; - my $part_pkg_msgcat = $object->part_pkg_msgcat($locale); - $part_pkg_msgcat ? $part_pkg_msgcat->pkgpartmsgnum : ''; - }, - 'cgiparam' - ); + if ( $cgi->param('error') =~ / is suggested with / ) { + #yeah, detection is a shitty kludge, but we don't have exception objects + $opt->{form_init} = ' Override suggestion

'; + } }; @@ -576,29 +550,42 @@ my $new_object_callback = sub { }; +my $report_option_value_callback = sub { + my ($cgi, $object) = @_; + my @report_option; + if ( defined $cgi->param('report_option') ) { + @report_option = $cgi->param('report_option'); + } else { + foreach ($object->options) { + /^report_option_(\d+)$/ && (push @report_option, $1); + } + } + join(',', @report_option); +}; + sub set_report_option { my($cgi, $object, $fields ) = @_; #, $opt my @report_option = (); foreach ($object->options) { /^usage_taxproductnum_(\d+)$/ && ($taxproductnums{$1} = 1); - /^report_option_(\d+)$/ && (push @report_option, $1); +# /^report_option_(\d+)$/ && (push @report_option, $1); } foreach ($object->part_pkg_taxoverride) { $taxproductnums{$_->usage_class} = 1 if $_->usage_class; } - $cgi->param('report_option', join(',', @report_option)); - foreach my $field ( @$fields ) { - next unless ( - ref($field) eq 'HASH' && - $field->{field} && - $field->{field} eq 'report_option' - ); - #$field->{curr_value} = join(',', @report_option); - $field->{value} = join(',', @report_option); - } +# $cgi->param('report_option', join(',', @report_option)); +# foreach my $field ( @$fields ) { +# next unless ( +# ref($field) eq 'HASH' && +# $field->{field} && +# $field->{field} eq 'report_option' +# ); +# #$field->{curr_value} = join(',', @report_option); +# $field->{value} = join(',', @report_option); +# } } @@ -632,20 +619,6 @@ my $edit_callback = sub { $pkgpart = $object->pkgpart; - &$splice_locale_fields( - $fields, - sub { - my $locale = shift; - my $part_pkg_msgcat = $object->part_pkg_msgcat($locale); - $part_pkg_msgcat ? $part_pkg_msgcat->pkgpartmsgnum : ''; - }, - sub { - my $locale = shift; - my $part_pkg_msgcat = $object->part_pkg_msgcat($locale); - $part_pkg_msgcat ? $part_pkg_msgcat->pkg : ''; - } - ); - }; my $new_callback = sub { @@ -659,8 +632,6 @@ my $new_callback = sub { $options{'suspend_bill'}=1 if $conf->exists('part_pkg-default_suspend_bill'); - &$splice_locale_fields($fields, '', ''); - }; my $clone_callback = sub { @@ -668,7 +639,7 @@ my $clone_callback = sub { if ( $cgi->param('pkgnum') ) { - my $cust_pkg = qsearchs('cust_pkg', { 'pkgnum' => $cgi->param('pkgnum') } ); + my $cust_pkg = qsearchs('cust_pkg', { 'pkgnum' => scalar($cgi->param('pkgnum')) } ); $object->agentnum( $cust_pkg->cust_main->agentnum ); $opt->{action} = 'Custom'; @@ -693,23 +664,18 @@ my $clone_callback = sub { $object->set($_ => $options{$_}) foreach (qw( setup_fee recur_fee disable_line_item_date_ranges )); + $recur_disabled = $object->freq ? 0 : 1; + $recur_show_zero_disabled = + $object->freq + ? $object->option('recur_fee') > 0 ? 1 : 0 + : 1; + foreach my $currency ( $conf->config('currencies') ) { my %part_pkg_currency = $object->part_pkg_currency_options($currency); $object->set( $_.'_'.$currency, $part_pkg_currency{$_} ) foreach keys %part_pkg_currency; } - $recur_disabled = $object->freq ? 0 : 1; - - &$splice_locale_fields( - $fields, - '', - sub { - my $locale = shift; - my $part_pkg_msgcat = $object->part_pkg_msgcat($locale); - $part_pkg_msgcat ? $part_pkg_msgcat->pkg : ''; - } - ); }; my $discount_error_callback = sub { @@ -736,7 +702,7 @@ my $usageprice_error_callback = sub { && $cgi->param("usagepricepart$1_price") ) { new FS::part_pkg_usageprice { - 'usagepricepart' => $cgi->param("usagepricepart$1"), + 'usagepricepart' => scalar($cgi->param("usagepricepart$1")), 'pkgpart' => $object->pkgpart, 'price' => scalar($cgi->param("usagepricepart$1_price")), #'currency @@ -888,8 +854,9 @@ my $javascript = <<'END'; supp_pkg_rows[0].style.display = 'none'; var button = document.getElementById('show_supp_pkgs'); button.onclick = show_supp_pkgs_click; - button.style.backgroundColor = '#cccccc'; - button.style.border = '1px solid #7e0079'; + //button.style.backgroundColor = '#cccccc'; + //button.style.border = '1px solid #7e0079'; + button.style.border = 'thin solid #999999'; button.style.padding = '1px'; } } @@ -928,6 +895,15 @@ tie my %plan_labels, 'Tie::IxHash', map { $_ => ( $plans{$_}->{'shortname'} || $plans{$_}->{'name'} ) } keys %plans; +my $validate_priceplan_fields = {}; +foreach my $priceplan (keys %plans) { + my $plan_fields = $plans{$priceplan}->{fields}; + foreach my $price_plan_field (keys %$plan_fields) { + $validate_priceplan_fields->{$priceplan."__".$price_plan_field} = $plan_fields->{$price_plan_field}->{"js_validate"} + if exists $plan_fields->{$price_plan_field}->{"js_validate"}; + } +} + my $html_bottom = sub { my( $object ) = @_; @@ -936,7 +912,7 @@ my $html_bottom = sub { my $layer_callback = sub { my $layer = shift; - my $html = ntable("#cccccc",2); + my $html = ''; #$html .= ' # @@ -956,9 +932,13 @@ my $html_bottom = sub { #$html .= ''; my $href = $plans{$layer}->{'fields'}; - my @fields = exists($plans{$layer}->{'fieldorder'}) - ? @{$plans{$layer}->{'fieldorder'}} - : keys %{ $href }; + my @fields; + if ( $plans{$layer}->{'fieldorder'} ) { + @fields = @{ $plans{$layer}->{'fieldorder'} }; + } else { + warn "FS::part_pkg::$layer has no fieldorder.\n"; + @fields = keys %$href; + } # hash of dependencies for each of the Pricing Plan fields. # make sure NOT to use double-quotes inside the 'msg' value. @@ -967,13 +947,22 @@ my $html_bottom = sub { '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 @suspend_credit_type_conf = qsearch('conf', { 'name' => 'suspend_credit_type' } ); - return 1 if (exists($suspend_credit_type_conf[0]) && $suspend_credit_type_conf[0]->{Hash}{value}); + 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})) { @@ -987,7 +976,8 @@ my $html_bottom = sub { next if !$display; } - $html .= ''; } $html .= '
'. $href->{$field}{'name'}. ''; + $html .= '
'. $href->{$field}{'name'}. ' + '; my $format = sub { shift }; $format = $href->{$field}{'format'} if exists($href->{$field}{'format'}); @@ -1006,6 +996,14 @@ my $html_bottom = sub { : $href->{$field}{'default'} ). qq!">!; + } elsif ( $href->{$field}{'type'} eq 'textarea' ) { + + $html .= qq!!; + } elsif ( $href->{$field}{'type'} eq 'checkbox' ) { $html .= qq!'; + } elsif ( $href->{$field}{'type'} eq 'date' ) { + + $html .= include('/elements/input-date-field.html', { + 'name' => $layer.'__'.$field, + 'value' => $options{$field}, + }); + + } elsif ( $href->{$field}{'type'} =~ /^select-rt-/ ) { + + $html .= include('/elements/'.$href->{$field}{'type'}.'.html', + 'name' => $layer.'__'.$field, + 'curr_value' => $options{$field}, + map { $_ => $href->{$field}{$_} } + grep { $_ !~ /^(name|type|parse)$/ } + keys %{ $href->{$field} } + ); + } elsif ( $href->{$field}{'type'} eq 'select-rate' ) { $html .= include('/elements/select-rate.html', @@ -1086,9 +1101,11 @@ my $html_bottom = sub { $html .= '
'; - - $html .= qq('; + + $html .= include('/elements/hidden.html', + field => $layer.'__OPTIONS', + value => join(',', @fields) + ); $html; @@ -1106,13 +1123,8 @@ my $html_bottom = sub { my $return = include('/elements/selectlayers.html', %selectlayers, 'layers_only'=>1 ). ''; + include('/elements/selectlayers.html', %selectlayers, 'js_only'=>1 ) . + ''; $return; @@ -1193,14 +1205,11 @@ my $field_callback = sub { my $field = $fieldref->{field}; if ($field eq 'taxproductnums') { $fieldref->{value} = join(',', @taxproductnums); - } elsif ($field eq 'taxproduct_select') { - $fieldref->{options} = [ '(default)', @taxproductnums ]; - $fieldref->{labels} = { ( '(default)' => '(default)' ), - map {( $_ => ($usage_class{$_} || $_) )} - @taxproductnums - }; - $fieldref->{layer_fields} = \%taxproduct_fields; - $fieldref->{layer_values_callback} = $taxproduct_values; + } elsif ($field eq 'taxproductnum') { # part_pkg-taxproduct, new style + if ( !$tax_data_vendor ) { + # then make the widget go away + $fieldref->{type} = 'hidden'; + } } };