diff options
author | Ivan Kohler <ivan@freeside.biz> | 2012-04-02 10:37:52 -0700 |
---|---|---|
committer | Ivan Kohler <ivan@freeside.biz> | 2012-04-02 10:37:52 -0700 |
commit | f84937b2a6cc6ba63cdab177866b1417c32b1028 (patch) | |
tree | 945b3e0bb69355c264f43d5a83e2fde70fef9d98 | |
parent | 59db9d8aa66fe128a26e512c5172982e041c59ae (diff) | |
parent | c2ee6c5c4f274bbf86729cacd2fe011ea71f725d (diff) |
Merge branch 'master' of git.freeside.biz:/home/git/freeside
-rw-r--r-- | FS/FS/Conf.pm | 18 | ||||
-rw-r--r-- | FS/FS/Report/Table.pm | 21 | ||||
-rw-r--r-- | FS/FS/Schema.pm | 9 | ||||
-rw-r--r-- | FS/FS/cust_bill.pm | 34 | ||||
-rw-r--r-- | FS/FS/cust_pay.pm | 27 | ||||
-rw-r--r-- | FS/FS/part_event/Condition.pm | 2 | ||||
-rw-r--r-- | FS/FS/part_event/Condition/has_cust_tag.pm | 49 | ||||
-rw-r--r-- | FS/FS/part_pkg.pm | 135 | ||||
-rwxr-xr-x | httemplate/browse/part_pkg.cgi | 21 | ||||
-rwxr-xr-x | httemplate/edit/cust_pay.cgi | 26 | ||||
-rwxr-xr-x | httemplate/edit/part_pkg.cgi | 28 | ||||
-rwxr-xr-x | httemplate/edit/process/cust_pay.cgi | 5 | ||||
-rw-r--r-- | httemplate/elements/city.html | 6 | ||||
-rw-r--r-- | httemplate/elements/tr-select-cust_tag.html | 2 | ||||
-rw-r--r-- | httemplate/graph/cust_signup.html | 29 | ||||
-rw-r--r-- | httemplate/graph/report_cust_signup.html | 6 | ||||
-rw-r--r-- | httemplate/view/cust_main/payment_history.html | 2 | ||||
-rw-r--r-- | httemplate/view/cust_pay.html | 22 |
18 files changed, 412 insertions, 30 deletions
diff --git a/FS/FS/Conf.pm b/FS/FS/Conf.pm index 2bc1f1960..1b01aa64a 100644 --- a/FS/FS/Conf.pm +++ b/FS/FS/Conf.pm @@ -694,6 +694,13 @@ sub reason_type_options { }, { + 'key' => 'part_pkg-lineage', + 'section' => '', + 'description' => 'When editing a package definition, if setup or recur fees are changed, create a new package rather than changing the existing package.', + 'type' => 'checkbox', + }, + + { 'key' => 'apacheip', #not actually deprecated yet #'section' => 'deprecated', @@ -2284,6 +2291,13 @@ and customer address. Include units.', }, { + 'key' => 'require_cash_deposit_info', + 'section' => 'billing', + 'description' => 'When recording cash payments, display bank deposit information fields.', + 'type' => 'checkbox', + }, + + { 'key' => 'paymentforcedtobatch', 'section' => 'deprecated', 'description' => 'See batch-enable_payby and realtime-disable_payby. Used to (for CHEK): Cause per customer payment entry to be forced to a batch processor rather than performed realtime.', @@ -2926,7 +2940,7 @@ and customer address. Include units.', 'section' => 'invoicing', 'description' => 'Enable FTP of raw invoice data - format.', 'type' => 'select', - 'select_enum' => [ '', 'default', 'billco', ], + 'select_enum' => [ '', 'default', 'oneline', 'billco', ], }, { @@ -2962,7 +2976,7 @@ and customer address. Include units.', 'section' => 'invoicing', 'description' => 'Enable spooling of raw invoice data - format.', 'type' => 'select', - 'select_enum' => [ '', 'default', 'billco', ], + 'select_enum' => [ '', 'default', 'oneline', 'billco', ], }, { diff --git a/FS/FS/Report/Table.pm b/FS/FS/Report/Table.pm index 3942543b5..b0e911f84 100644 --- a/FS/FS/Report/Table.pm +++ b/FS/FS/Report/Table.pm @@ -32,21 +32,32 @@ options in %opt. =over 4 -=item signups: The number of customers signed up. +=item signups: The number of customers signed up. Options are "refnum" +(limit by advertising source) and "indirect" (boolean, tells us to limit +to customers that have a referral_custnum that matches the advertising source). =cut sub signups { my( $self, $speriod, $eperiod, $agentnum, %opt ) = @_; - my @where = ( - $self->in_time_period_and_agent($speriod, $eperiod, $agentnum, 'signupdate') + my @where = ( $self->in_time_period_and_agent($speriod, $eperiod, $agentnum, + 'cust_main.signupdate') ); - if ( $opt{'refnum'} ) { + my $join = ''; + if ( $opt{'indirect'} ) { + $join = " JOIN cust_main AS referring_cust_main". + " ON (cust_main.referral_custnum = referring_cust_main.custnum)"; + + if ( $opt{'refnum'} ) { + push @where, "referring_cust_main.refnum = ".$opt{'refnum'}; + } + } + elsif ( $opt{'refnum'} ) { push @where, "refnum = ".$opt{'refnum'}; } $self->scalar_sql( - "SELECT COUNT(*) FROM cust_main WHERE ".join(' AND ', @where) + "SELECT COUNT(*) FROM cust_main $join WHERE ".join(' AND ', @where) ); } diff --git a/FS/FS/Schema.pm b/FS/FS/Schema.pm index ab853e6ce..5147432a1 100644 --- a/FS/FS/Schema.pm +++ b/FS/FS/Schema.pm @@ -1343,12 +1343,17 @@ sub tables_hashref { # index into payby table # eventually 'payinfo', 'varchar', 'NULL', 512, '', '', #see cust_main above - 'paymask', 'varchar', 'NULL', $char_d, '', '', + 'paymask', 'varchar', 'NULL', $char_d, '', '', 'paydate', 'varchar', 'NULL', 10, '', '', 'paybatch', 'varchar', 'NULL', $char_d, '', '', #for auditing purposes. 'payunique', 'varchar', 'NULL', $char_d, '', '', #separate paybatch "unique" functions from current usage 'closed', 'char', 'NULL', 1, '', '', 'pkgnum', 'int', 'NULL', '', '', '', #desired pkgnum for pkg-balances + # cash/check deposit info fields + 'bank', 'varchar', 'NULL', $char_d, '', '', + 'depositor', 'varchar', 'NULL', $char_d, '', '', + 'account', 'varchar', 'NULL', 20, '', '', + 'teller', 'varchar', 'NULL', 20, '', '', ], 'primary_key' => 'paynum', #i guess not now, with cust_pay_pending, if we actually make it here, we _do_ want to record it# 'unique' => [ [ 'payunique' ] ], @@ -1690,6 +1695,8 @@ sub tables_hashref { 'no_auto', 'char', 'NULL', 1, '', '', 'recur_show_zero', 'char', 'NULL', 1, '', '', 'setup_show_zero', 'char', 'NULL', 1, '', '', + 'successor', 'int', 'NULL', '', '', '', + 'family_pkgpart','int', 'NULL', '', '', '', ], 'primary_key' => 'pkgpart', 'unique' => [], diff --git a/FS/FS/cust_bill.pm b/FS/FS/cust_bill.pm index 3aa75eca5..945771e0d 100644 --- a/FS/FS/cust_bill.pm +++ b/FS/FS/cust_bill.pm @@ -2005,6 +2005,36 @@ sub print_csv { '0', # 29 | Other Taxes & Fees*** NUM* 9 ); + } elsif ( lc($opt{'format'}) eq 'oneline' ) { #name? + + my ($previous_balance) = $self->previous; + my $totaldue = sprintf('%.2f', $self->owed + $previous_balance); + my @items = map { + ($_->{pkgnum} || ''), + $_->{description}, + $_->{amount} + } $self->_items_pkg; + + $csv->combine( + $cust_main->agentnum, + $self->custnum, + $cust_main->first, + $cust_main->last, + $cust_main->address1, + $cust_main->address2, + $cust_main->city, + $cust_main->state, + $cust_main->zip, + + # invoice fields + time2str("%x", $self->_date), + $self->invnum, + $self->charged, + $totaldue, + + @items, + ); + } else { $csv->combine( @@ -2044,6 +2074,10 @@ sub print_csv { } + } elsif ( lc($opt{'format'}) eq 'oneline' ) { + + #do nothing + } else { foreach my $cust_bill_pkg ( $self->cust_bill_pkg ) { diff --git a/FS/FS/cust_pay.pm b/FS/FS/cust_pay.pm index d98d11ecb..ef30809b0 100644 --- a/FS/FS/cust_pay.pm +++ b/FS/FS/cust_pay.pm @@ -113,6 +113,22 @@ books closed flag, empty or `Y' Desired pkgnum when using experimental package balances. +=item bank + +The bank where the payment was deposited. + +=item depositor + +The name of the depositor. + +=item account + +The deposit account number. + +=item teller + +The teller number. + =back =head1 METHODS @@ -493,8 +509,11 @@ sub check { || $self->ut_textn('payunique') || $self->ut_enum('closed', [ '', 'Y' ]) || $self->ut_foreign_keyn('pkgnum', 'cust_pkg', 'pkgnum') + || $self->ut_textn('bank') + || $self->ut_alphan('depositor') + || $self->ut_numbern('account') + || $self->ut_numbern('teller') || $self->payinfo_check() - || $self->ut_numbern('discount_term') ; return $error if $error; @@ -509,6 +528,12 @@ sub check { return "invalid discount_term" if ($self->discount_term && $self->discount_term < 2); + if ( $self->payby eq 'CASH' and $conf->exists('require_cash_deposit_info') ) { + foreach (qw(bank depositor account teller)) { + return "$_ required" if $self->get($_) eq ''; + } + } + #i guess not now, with cust_pay_pending, if we actually make it here, we _do_ want to record it # # UNIQUE index should catch this too, without race conditions, but this # # should give a better error message the other 99.9% of the time... diff --git a/FS/FS/part_event/Condition.pm b/FS/FS/part_event/Condition.pm index 32751974c..b3948153e 100644 --- a/FS/FS/part_event/Condition.pm +++ b/FS/FS/part_event/Condition.pm @@ -360,7 +360,7 @@ sub condition_sql_option_option { } -#used for part_event/Condition/cust_bill_has_service.pm +#used for part_event/Condition/cust_bill_has_service.pm and has_cust_tag.pm #a little false laziness w/above and condition_sql_option_integer sub condition_sql_option_option_integer { my( $class, $option, $driver_name ) = @_; diff --git a/FS/FS/part_event/Condition/has_cust_tag.pm b/FS/FS/part_event/Condition/has_cust_tag.pm new file mode 100644 index 000000000..cde933881 --- /dev/null +++ b/FS/FS/part_event/Condition/has_cust_tag.pm @@ -0,0 +1,49 @@ +package FS::part_event::Condition::has_cust_tag; + +use strict; + +use base qw( FS::part_event::Condition ); +use FS::Record qw( qsearch ); + +sub description { + 'Customer has tag', +} + +sub eventtable_hashref { + { 'cust_main' => 1, + 'cust_bill' => 1, + 'cust_pkg' => 1, + }; +} + +#something like this +sub option_fields { + ( + 'tagnum' => { 'label' => 'Customer tag', + 'type' => 'select-cust_tag', + 'multiple' => 1, + }, + ); +} + +sub condition { + my( $self, $object ) = @_; + + my $cust_main = $self->cust_main($object); + + my $hashref = $self->option('tagnum') || {}; + grep $hashref->{ $_->tagnum }, $cust_main->cust_tag; +} + +sub condition_sql { + my( $self, $table ) = @_; + + my $matching_tags = + "SELECT tagnum FROM cust_tag WHERE cust_tag.custnum = $table.custnum". + " AND cust_tag.tagnum IN ". + $self->condition_sql_option_option_integer('tagnum'); + + "EXISTS($matching_tags)"; +} + +1; diff --git a/FS/FS/part_pkg.pm b/FS/FS/part_pkg.pm index 373982b84..061001bdc 100644 --- a/FS/FS/part_pkg.pm +++ b/FS/FS/part_pkg.pm @@ -103,6 +103,13 @@ inherits from FS::Record. The following fields are currently supported: =item fcc_ds0s - Optional DS0 equivalency number for FCC form 477 +=item successor - Foreign key for the part_pkg that replaced this record. +If this record is not obsolete, will be null. + +=item family_pkgpart - Foreign key for the part_pkg that was the earliest +ancestor of this record. If this record is not a successor to another +part_pkg, will be equal to pkgpart. + =back =head1 METHODS @@ -192,6 +199,16 @@ sub insert { return $error; } + # set family_pkgpart + if ( $self->get('family_pkgpart') eq '' ) { + $self->set('family_pkgpart' => $self->pkgpart); + $error = $self->SUPER::replace; + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return $error; + } + } + my $conf = new FS::Conf; if ( $conf->exists('agent_defaultpkg') ) { warn " agent_defaultpkg set; allowing all agents to purchase package" @@ -294,7 +311,7 @@ sub insert { } } - warn " commiting transaction" if $DEBUG; + warn " committing transaction" if $DEBUG and $oldAutoCommit; $dbh->commit or die $dbh->errstr if $oldAutoCommit; ''; @@ -360,6 +377,28 @@ sub replace { my $oldAutoCommit = $FS::UID::AutoCommit; local $FS::UID::AutoCommit = 0; my $dbh = dbh; + + my $conf = new FS::Conf; + if ( $conf->exists('part_pkg-lineage') ) { + if ( grep { $options->{options}->{$_} ne $old->option($_, 1) } + qw(setup_fee recur_fee) #others? config? + ) { + + warn " superseding package" if $DEBUG; + + my $error = $new->supersede($old, %$options); + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return $error; + } + else { + warn " committing transaction" if $DEBUG and $oldAutoCommit; + $dbh->commit if $oldAutoCommit; + return $error; + } + } + #else nothing + } #plandata shit stays in replace for upgrades until after 2.0 (or edit #_upgrade_data) @@ -501,8 +540,18 @@ sub replace { } } } + + # propagate changes to certain core fields + if ( $conf->exists('part_pkg-lineage') ) { + warn " propagating changes to family" if $DEBUG; + my $error = $new->propagate($old); + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return $error; + } + } - warn " commiting transaction" if $DEBUG; + warn " committing transaction" if $DEBUG and $oldAutoCommit; $dbh->commit or die $dbh->errstr if $oldAutoCommit; ''; } @@ -573,6 +622,8 @@ sub check { : $self->ut_agentnum_acl('agentnum', \@null_agentnum_right) ) || $self->ut_numbern('fcc_ds0s') + || $self->ut_foreign_keyn('successor', 'part_pkg', 'pkgpart') + || $self->ut_foreign_keyn('family_pkgpart', 'part_pkg', 'pkgpart') || $self->SUPER::check ; return $error if $error; @@ -587,6 +638,76 @@ sub check { ''; } +=item supersede OLD [, OPTION => VALUE ... ] + +Inserts this package as a successor to the package OLD. All options are as +for C<insert>. After inserting, disables OLD and sets the new package as its +successor. + +=cut + +sub supersede { + my ($new, $old, %options) = @_; + my $error; + + $new->set('pkgpart' => ''); + $new->set('family_pkgpart' => $old->family_pkgpart); + warn " inserting successor package\n" if $DEBUG; + $error = $new->insert(%options); + return $error if $error; + + warn " disabling superseded package\n" if $DEBUG; + $old->set('successor' => $new->pkgpart); + $old->set('disabled' => 'Y'); + $error = $old->SUPER::replace; # don't change its options/pkg_svc records + return $error if $error; + + warn " propagating changes to family" if $DEBUG; + $new->propagate($old); +} + +=item propagate OLD + +If any of certain fields have changed from OLD to this package, then, +for all packages in the same lineage as this one, sets those fields +to their values in this package. + +=cut + +my @propagate_fields = ( + qw( pkg classnum setup_cost recur_cost taxclass + setuptax recurtax pay_weight credit_weight + ) +); + +sub propagate { + my $new = shift; + my $old = shift; + my %fields = ( + map { $_ => $new->get($_) } + grep { $new->get($_) ne $old->get($_) } + @propagate_fields + ); + + my @part_pkg = qsearch('part_pkg', { + 'family_pkgpart' => $new->family_pkgpart + }); + my @error; + foreach my $part_pkg ( @part_pkg ) { + my $pkgpart = $part_pkg->pkgpart; + next if $pkgpart == $new->pkgpart; # don't modify $new + warn " propagating to pkgpart $pkgpart\n" if $DEBUG; + foreach ( keys %fields ) { + $part_pkg->set($_, $fields{$_}); + } + # SUPER::replace to avoid changing non-core fields + my $error = $part_pkg->SUPER::replace; + push @error, "pkgpart $pkgpart: $error" + if $error; + } + join("\n", @error); +} + =item pkg_comment [ OPTION => VALUE... ] Returns an (internal) string representing this package. Currently, @@ -1277,7 +1398,7 @@ sub _rebless { } return $self if ref($self) =~ /::$plan$/; #already blessed into plan subclass my $class = ref($self). "::$plan"; - warn "reblessing $self into $class" if $DEBUG; + warn "reblessing $self into $class" if $DEBUG > 1; eval "use $class;"; die $@ if $@; bless($self, $class) unless $@; @@ -1410,6 +1531,14 @@ sub _upgrade_data { # class method die $error if $error; } + # set family_pkgpart on any packages that don't have it + @part_pkg = qsearch('part_pkg', { 'family_pkgpart' => '' }); + foreach my $part_pkg (@part_pkg) { + $part_pkg->set('family_pkgpart' => $part_pkg->pkgpart); + my $error = $part_pkg->SUPER::replace; + die $error if $error; + } + my @part_pkg_option = qsearch('part_pkg_option', { 'optionname' => 'unused_credit', 'optionvalue' => 1, diff --git a/httemplate/browse/part_pkg.cgi b/httemplate/browse/part_pkg.cgi index 766806044..4ca78d718 100755 --- a/httemplate/browse/part_pkg.cgi +++ b/httemplate/browse/part_pkg.cgi @@ -45,6 +45,7 @@ my $select = '*'; my $orderby = 'pkgpart'; my %hash = (); my $extra_count = ''; +my $family_pkgpart; if ( $cgi->param('active') ) { $orderby = 'num_active DESC'; @@ -77,6 +78,16 @@ if ( $cgi->param('missing_recur_fee') ) { )"; } +if ( $cgi->param('family') =~ /^(\d+)$/ ) { + $family_pkgpart = $1; + push @where, "family_pkgpart = $1"; + # Hiding disabled or one-time charges and limiting by classnum aren't + # very useful in this mode, so all links should still refer back to the + # non-family-limited display. + $cgi->param('showdisabled', 1); + $cgi->delete('family'); +} + push @where, FS::part_pkg->curuser_pkgs_sql unless $acl_edit_global; @@ -209,6 +220,16 @@ push @fields, sub { $part_pkg->part_pkg_discount; [ + ( !$family_pkgpart && + $part_pkg->pkgpart == $part_pkg->family_pkgpart ? () : [ + { + 'align'=> 'center', + 'colspan' => 2, + 'size' => '-1', + 'data' => '<b>Show all versions</b>', + 'link' => $p.'browse/part_pkg.cgi?family='.$part_pkg->family_pkgpart, + } + ] ), [ { data =>$plan, align=>'center', diff --git a/httemplate/edit/cust_pay.cgi b/httemplate/edit/cust_pay.cgi index 3fd9c79eb..7a1bb00fa 100755 --- a/httemplate/edit/cust_pay.cgi +++ b/httemplate/edit/cust_pay.cgi @@ -18,7 +18,7 @@ <INPUT TYPE="hidden" NAME="payby" VALUE="<% $payby %>"> <INPUT TYPE="hidden" NAME="paybatch" VALUE="<% $paybatch %>"> -<BR><BR> +<BR> <% mt('Payment') |h %> <% ntable("#cccccc", 2) %> @@ -56,7 +56,29 @@ <TD ALIGN="right"><% mt('Check #') |h %></TD> <TD COLSPAN=2><INPUT TYPE="text" NAME="payinfo" VALUE="<% $payinfo %>" SIZE=10></TD> </TR> -% } +% } +% elsif ( $payby eq 'CASH' and $conf->exists('require_cash_deposit_info') ) { + <TR> + <TD ALIGN="right"><% mt('Bank') |h %></TD> + <TD COLSPAN=3><INPUT TYPE="text" NAME="bank" VALUE="<% $cgi->param('bank') %>"></TD> + </TR> + <TR> + <TD ALIGN="right"><% mt('Check #') |h %></TD> + <TD COLSPAN=2><INPUT TYPE="text" NAME="payinfo" VALUE="<% $payinfo %>" SIZE=10></TD> + </TR> + <TR> + <TD ALIGN="right"><% mt('Teller #') |h %></TD> + <TD COLSPAN=2><INPUT TYPE="text" NAME="teller" VALUE="<% $cgi->param('teller') %>" SIZE=10></TD> + </TR> + <TR> + <TD ALIGN="right"><% mt('Depositor') |h %></TD> + <TD COLSPAN=3><INPUT TYPE="text" NAME="depositor" VALUE="<% $cgi->param('depositor') %>"></TD> + </TR> + <TR> + <TD ALIGN="right"><% mt('Account #') |h %></TD> + <TD COLSPAN=2><INPUT TYPE="text" NAME="account" VALUE="<% $cgi->param('account') %>" SIZE=18></TD> + </TR> +% } <TR> % if ( $link eq 'custnum' || $link eq 'popup' ) { diff --git a/httemplate/edit/part_pkg.cgi b/httemplate/edit/part_pkg.cgi index e5edcdedc..cd0731370 100755 --- a/httemplate/edit/part_pkg.cgi +++ b/httemplate/edit/part_pkg.cgi @@ -24,6 +24,8 @@ 'error_callback' => $error_callback, 'field_callback' => $field_callback, + 'onsubmit' => 'confirm_submit', + 'labels' => { 'pkgpart' => 'Package Definition', 'pkg' => 'Package (customer-visible)', @@ -66,6 +68,8 @@ }, { field=>'custom', type=>'hidden' }, + { field=>'family_pkgpart', type=>'hidden' }, + { field=>'successor', type=>'hidden' }, { type => 'columnstart' }, @@ -593,7 +597,7 @@ my $javascript = <<'END'; } - function aux_planchanged(what) { + function aux_planchanged(what) { //? alert('called!'); var plan = what.options[what.selectedIndex].value; @@ -609,9 +613,29 @@ my $javascript = <<'END'; } - </SCRIPT> END +my $warning = + 'Changing the setup or recurring fee will create a new package definition. '. + 'Continue?'; + +if ( $conf->exists('part_pkg-lineage') ) { + $javascript .= " + function confirm_submit(f) { + + 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'); + } + } + return true; + } +"; +} + +$javascript .= '</SCRIPT>'; + tie my %plans, 'Tie::IxHash', %{ FS::part_pkg::plan_info() }; tie my %plan_labels, 'Tie::IxHash', diff --git a/httemplate/edit/process/cust_pay.cgi b/httemplate/edit/process/cust_pay.cgi index e74f9022f..06f5e64d5 100755 --- a/httemplate/edit/process/cust_pay.cgi +++ b/httemplate/edit/process/cust_pay.cgi @@ -28,6 +28,8 @@ %} <%init> +my $conf = FS::Conf->new; + $cgi->param('linknum') =~ /^(\d+)$/ or die "Illegal linknum: ". $cgi->param('linknum'); my $linknum = $1; @@ -46,6 +48,7 @@ my $new = new FS::cust_pay ( { $_, scalar($cgi->param($_)); } qw( paid payby payinfo paybatch pkgnum discount_term + bank depositor account teller ) #} fields('cust_pay') } ); @@ -57,6 +60,6 @@ push @rights, 'Post cash payment' if $new->payby eq 'CASH'; die "access denied" unless $FS::CurrentUser::CurrentUser->access_right(\@rights); -my $error = $new->insert( 'manual' => 1 ); +my $error ||= $new->insert( 'manual' => 1 ); </%init> diff --git a/httemplate/elements/city.html b/httemplate/elements/city.html index f6d2b4bad..6a2142f29 100644 --- a/httemplate/elements/city.html +++ b/httemplate/elements/city.html @@ -107,7 +107,11 @@ function <% $pre %>county_changed(what, callback) {} <% $text_style %> > -% if ( !$disable_select ) { +% if ( $disable_select ) { +%# avoid JS errors +<INPUT TYPE="hidden" ID="city_select"> +% } +% else { <SELECT NAME = "<%$pre%>city_select" ID = "<%$pre%>city_select" diff --git a/httemplate/elements/tr-select-cust_tag.html b/httemplate/elements/tr-select-cust_tag.html index b2b6d967e..5312644ef 100644 --- a/httemplate/elements/tr-select-cust_tag.html +++ b/httemplate/elements/tr-select-cust_tag.html @@ -28,7 +28,7 @@ my $cgi = $opt{'cgi'}; my $is_report = $opt{'is_report'}; my @curr_tagnum = (); -if ( $cgi->param('error') ) { +if ( $cgi && $cgi->param('error') ) { @curr_tagnum = $cgi->param('tagnum'); } elsif ( $opt{'custnum'} ) { @curr_tagnum = map $_->tagnum, diff --git a/httemplate/graph/cust_signup.html b/httemplate/graph/cust_signup.html index dd9100f1e..a3eb702f2 100644 --- a/httemplate/graph/cust_signup.html +++ b/httemplate/graph/cust_signup.html @@ -9,7 +9,7 @@ 'agentnum' => $agentnum, 'sprintf' => '%u', 'disable_money' => 1, - 'bottom_total' => (scalar @items > 1 ? 1 : 0), + 'bottom_total' => (scalar @items > 1 && !$indirect ? 1 : 0), 'bottom_link' => $bottom_link, 'link_fromparam' => 'signupdate_begin', 'link_toparam' => 'signupdate_end', @@ -59,25 +59,34 @@ elsif ( $cgi->param('refnum') =~ /^(\d*)$/ ) { } } +my $indirect = ($cgi->param('indirect') eq 'Y' ? 1 : 0); + my (@items, @labels, @colors, @params, @links); my $hue = 0; -my $hue_increment = 125; +my $hue_increment = 75; my @signup_colors; foreach my $referral (@referral) { + my %params = ('refnum' => $referral->refnum) unless $all_referral; + push @items, 'signups'; push @labels, ( $all_referral ? 'Signups' : $referral->referral ); - push @params, ( $all_referral ? [] : [ 'refnum' => $referral->refnum ] ); + push @params, [ %params ]; push @links, $link . ($all_referral ? '' : "refnum=".$referral->refnum.';'); - if ( !@signup_colors ) { - @signup_colors = Color::Scheme->new - ->from_hue($hue) - ->scheme('analogic') - ->colors; - $hue += $hue_increment; + # rotate hue for each referral type + @signup_colors = Color::Scheme->new->from_hue($hue)->colors; + $hue += $hue_increment; + push @colors, $signup_colors[0]; + if ( $indirect ) { + push @items, 'signups'; + push @labels, $all_referral ? + 'Referrals' : + $referral->referral . ' referrals'; + push @params, [ %params, 'indirect' => 1 ]; + push @links, ''; + push @colors, $signup_colors[1]; } - push @colors, shift @signup_colors; } </%init> diff --git a/httemplate/graph/report_cust_signup.html b/httemplate/graph/report_cust_signup.html index 9d3f5006b..12dec8e6a 100644 --- a/httemplate/graph/report_cust_signup.html +++ b/httemplate/graph/report_cust_signup.html @@ -22,6 +22,12 @@ ) %> +<& /elements/tr-td-label.html, label => 'Show customer referrals' &> +<TD> + <INPUT TYPE="checkbox" NAME="indirect" VALUE="Y"> +</TD> +</TR> + </TABLE> <BR><INPUT TYPE="submit" VALUE="Display"> diff --git a/httemplate/view/cust_main/payment_history.html b/httemplate/view/cust_main/payment_history.html index b5b716199..c453ffadc 100644 --- a/httemplate/view/cust_main/payment_history.html +++ b/httemplate/view/cust_main/payment_history.html @@ -13,6 +13,7 @@ 'cust_main' => $cust_main, 'actionlabel' => emt('Enter check payment'), 'width' => 392, + 'height' => 392, &> % } @@ -24,6 +25,7 @@ 'cust_main' => $cust_main, 'actionlabel' => emt('Enter cash payment'), 'width' => 392, + 'height' => 392, &> % } diff --git a/httemplate/view/cust_pay.html b/httemplate/view/cust_pay.html index d02f1543d..f9c8bc19c 100644 --- a/httemplate/view/cust_pay.html +++ b/httemplate/view/cust_pay.html @@ -98,6 +98,28 @@ % } +% if ( $cust_pay->payby eq 'CASH' && $cust_pay->payinfo ) { + <TR> + <TD ALIGN="right"><% mt('Bank') |h %></TD> + <TD BGCOLOR="#FFFFFF"><B><% $cust_pay->bank %></B></TD> + </TR> + + <TR> + <TD ALIGN="right"><% mt('Teller #') |h %></TD> + <TD BGCOLOR="#FFFFFF"><B><% $cust_pay->teller %></B></TD> + </TR> + + <TR> + <TD ALIGN="right"><% mt('Depositor') |h %></TD> + <TD BGCOLOR="#FFFFFF"><B><% $cust_pay->depositor %></B></TD> + </TR> + + <TR> + <TD ALIGN="right"><% mt('Account #') |h %></TD> + <TD BGCOLOR="#FFFFFF"><B><% $cust_pay->account %></B></TD> + </TR> +% } + % if ( $conf->exists('pkg-balances') && $cust_pay->pkgnum ) { % my $cust_pkg = qsearchs('cust_pkg', { 'pkgnum' => $cust_pay->pkgnum } ); <TR> |