+
+my $edit_callback = sub {
+ my( $cgi, $object, $fields, $opt ) = @_;
+
+ $setup_show_zero_disabled = ($object->option('setup_fee') > 0) ? 1 : 0;
+
+ $recur_disabled = $object->freq ? 0 : 1;
+
+ $recur_show_zero_disabled =
+ $object->freq
+ ? $object->option('recur_fee') > 0 ? 1 : 0
+ : 1;
+
+ (@agent_type) =
+ map {$_->typenum} qsearch('type_pkgs', { 'pkgpart' => $object->pkgpart } );
+
+ set_report_option( $cgi, $object, $fields);
+
+ %options = $object->options;
+
+ $object->set($_ => $object->option($_, 1))
+ foreach (qw( setup_fee recur_fee disable_line_item_date_ranges ));
+
+ 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;
+ }
+
+ $pkgpart = $object->pkgpart;
+
+};
+
+my $new_callback = sub {
+ my( $cgi, $object, $fields ) = @_;
+
+ my $conf = new FS::Conf;
+
+ if ( $conf->exists('agent_defaultpkg') ) {
+ @agent_type = map {$_->typenum} qsearch('agent_type', { 'disabled'=>'' });
+ }
+
+ $options{'suspend_bill'}=1 if $conf->exists('part_pkg-default_suspend_bill');
+
+};
+
+my $clone_callback = sub {
+ my( $cgi, $object, $fields, $opt ) = @_;
+
+ if ( $cgi->param('pkgnum') ) {
+
+ my $cust_pkg = qsearchs('cust_pkg', { 'pkgnum' => scalar($cgi->param('pkgnum')) } );
+ $object->agentnum( $cust_pkg->cust_main->agentnum );
+
+ $opt->{action} = 'Custom';
+
+ #my $part_pkg = $clone_part_pkg->clone;
+ #this is all clone does anyway
+ $object->custom('Y');
+
+ $object->disabled('Y');
+
+ } else { #when explicitly cloning, not customizing
+
+ (@agent_type) =
+ map {$_->typenum} qsearch('type_pkgs',{ 'pkgpart' => $object->pkgpart } );
+
+ }
+
+ set_report_option( $cgi, $object, $fields);
+
+ %options = $object->options;
+
+ $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;
+ }
+
+};
+
+my $discount_error_callback = sub {
+ my( $cgi, $object ) = @_;
+ map {
+ if ( /^discountnum(\d+)$/ &&
+ ( my $discountnum = $cgi->param("discountnum$1") ) )
+ {
+ new FS::part_pkg_discount {
+ 'pkgpart' => $object->pkgpart,
+ 'discountnum' => $discountnum,
+ };
+ } else {
+ ();
+ }
+ }
+ $cgi->param;
+};
+
+my $usageprice_error_callback = sub {
+ my( $cgi, $object ) = @_;
+ map {
+ if ( /^usagepricepart(\d+)_price$/
+ && $cgi->param("usagepricepart$1_price") )
+ {
+ new FS::part_pkg_usageprice {
+ 'usagepricepart' => scalar($cgi->param("usagepricepart$1")),
+ 'pkgpart' => $object->pkgpart,
+ 'price' => scalar($cgi->param("usagepricepart$1_price")),
+ #'currency
+ 'action' => scalar($cgi->param("usagepricepart$1_action")),
+ 'target' => scalar($cgi->param("usagepricepart$1_target")),
+ 'amount' => scalar($cgi->param("usagepricepart$1_amount")),
+ };
+ } else {
+ ();
+ }
+ }
+ $cgi->param;
+};
+
+my $m2_error_callback_maker = sub {
+ my $link_type = shift; #yay closures
+ return sub {
+ my( $cgi, $object ) = @_;
+ map {
+
+ if ( /^${link_type}_dst_pkgpart(\d+)$/ &&
+ ( my $dst = $cgi->param("${link_type}_dst_pkgpart$1") ) )
+ {
+
+ my $hidden = $cgi->param("${link_type}_dst_pkgpart__hidden$1")
+ || '';
+ new FS::part_pkg_link {
+ 'link_type' => $link_type,
+ 'src_pkgpart' => $object->pkgpart,
+ 'dst_pkgpart' => $dst,
+ 'hidden' => $hidden,
+ };
+ } else {
+ ();
+ }
+ }
+ $cgi->param;
+ };
+};
+
+my $javascript = <<'END';
+ <SCRIPT TYPE="text/javascript">
+
+ function freq_changed(what) {
+ var freq = what.options[what.selectedIndex].value;
+
+ if ( freq == '0' ) {
+ what.form.recur_fee.disabled = true;
+ what.form.recur_fee.style.backgroundColor = '#dddddd';
+ what.form.recur_show_zero.disabled = true;
+ //what.form.recur_show_zero.style.backgroundColor= '#dddddd';
+ } else {
+ what.form.recur_fee.disabled = false;
+ what.form.recur_fee.style.backgroundColor = '#ffffff';
+ recur_changed( what.form.recur_fee );
+ //what.form.recur_show_zero.style.backgroundColor= '#ffffff';
+ }
+
+ }
+
+ function setup_changed(what) {
+ var setup = what.value;
+ if ( parseFloat(setup) == 0 ) {
+ what.form.setup_show_zero.disabled = false;
+ } else {
+ what.form.setup_show_zero.disabled = true;
+ }
+ }
+
+ function recur_changed(what) {
+ var recur = what.value;
+ if ( parseFloat(recur) == 0 ) {
+ what.form.recur_show_zero.disabled = false;
+ } else {
+ what.form.recur_show_zero.disabled = true;
+ }
+ }
+
+ function agent_changed(what) {
+
+ var agentnum;
+ if ( what.type == 'select-one' ) {
+ agentnum = what.options[what.selectedIndex].value;
+ } else {
+ agentnum = what.value;
+ }
+
+ if ( agentnum == 0 ) {
+ what.form.agent_type.disabled = false;
+ //what.form.agent_type.style.backgroundColor = '#ffffff';
+ what.form.agent_type.style.visibility = '';
+ } else {
+ what.form.agent_type.disabled = true;
+ //what.form.agent_type.style.backgroundColor = '#dddddd';
+ what.form.agent_type.style.visibility = 'hidden';
+ }
+
+ }
+
+ function aux_planchanged(what) { //?
+
+ var plan = what.options[what.selectedIndex].value;
+
+ var term_table = document.getElementById('TableNumber8') // XXX NOT ROBUST
+ if ( plan == 'flat' || plan == 'prorate' || plan == 'subscription' ) {
+ //term_table.disabled = false;
+ //term_table.style.visibility = '';
+ term_table.style.display = '';
+ } else {
+ //term_table.disabled = true;
+ //term_table.style.visibility = 'hidden';
+ term_table.style.display = 'none';
+ }
+
+ var currency_regex = /^(setup|recur)_fee_[A-Z]{3}$/;
+
+ var form = what.form
+ for ( var i=0; i < form.length; i++ ) {
+ if ( currency_regex.test(form[i].name) ) {
+ if ( plan == 'currency_fixed' ) {
+ form[i].disabled = false;
+ } else {
+ form[i].disabled = true;
+ }
+ }
+ }
+
+ }
+
+ // some magic to make "supplemental packages" less obvious
+ var supp_pkg_rows = [];
+ function show_supp_pkgs_click() {
+ supp_pkg_rows[0].style.display = '';
+ this.onclick = '';
+ this.style.backgroundColor = '';
+ this.style.border = '';
+ this.style.padding = '';
+ }
+
+ function hide_supp_pkgs() {
+ var all_selects = document.getElementsByTagName('select');
+ for (var i=0; i < all_selects.length; i++) {
+ if ( all_selects[i].id.match(/^supp_dst_pkgpart/) ) {
+ supp_pkg_rows.push( all_selects[i].parentNode.parentNode );
+ }
+ }
+ if ( supp_pkg_rows.length == 1 ) {
+ // there are none configured, so hide the row to create a new one
+ 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.padding = '1px';
+ }
+ }
+
+ function finish_edit_fcc(id) {
+ cClick();
+ show_fcc_options(id); // refresh the display
+ }
+
+END
+
+my $warning =
+ 'Changing the setup or recurring fee will create a new package definition. '.
+ 'Continue?';
+
+$javascript .= "function confirm_submit(f) {";
+if ( $conf->exists('part_pkg-lineage') ) {
+ $javascript .= "
+
+ var fields = Array('setup_fee','recur_fee');
+ for(var i=0; i < fields.length; i++) {
+ if ( f[fields[i]].value != f[fields[i]].defaultValue ) {
+ return confirm('$warning');
+ }
+ }
+";