From d540445a9a35750e1127e3854ecba420d588a022 Mon Sep 17 00:00:00 2001 From: khoff Date: Thu, 24 Apr 2003 01:00:42 +0000 Subject: Apparently deleting elements from svc_Common->hashref is bad. --- FS/FS/part_export/sqlmail.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FS/FS/part_export/sqlmail.pm b/FS/FS/part_export/sqlmail.pm index 0c0cb367b..f97674c27 100644 --- a/FS/FS/part_export/sqlmail.pm +++ b/FS/FS/part_export/sqlmail.pm @@ -142,7 +142,7 @@ sub update_values { # Update records to conform to a particular server_type. my ($self, $svc, $svcdb) = (shift,shift,shift); - my $svchash = $svc->hashref or return ''; + my $svchash = { %{$svc->hashref} } or return ''; # We need a copy. if ($svcdb eq 'svc_acct') { if ($self->option('server_type') eq 'courier_crypt') { -- cgit v1.2.1 From 2c0751312ced1bcbcfa0907393895fb19d25c280 Mon Sep 17 00:00:00 2001 From: khoff Date: Thu, 24 Apr 2003 01:43:10 +0000 Subject: Support for exporting to an ISC BIND9 name server --- FS/FS/part_export.pm | 30 +++++++++++++++++++++--------- bin/bind.export | 15 +++++++++++++-- 2 files changed, 34 insertions(+), 11 deletions(-) diff --git a/FS/FS/part_export.pm b/FS/FS/part_export.pm index a6a67d2db..d898d2616 100644 --- a/FS/FS/part_export.pm +++ b/FS/FS/part_export.pm @@ -718,18 +718,30 @@ tie my %vpopmail_options, 'Tie::IxHash', ; tie my %bind_options, 'Tie::IxHash', - #'machine' => { label=>'named machine' }, - 'named_conf' => { label => 'named.conf location', - default=> '/etc/bind/named.conf' }, - 'zonepath' => { label => 'path to zone files', - default=> '/etc/bind/', }, + #'machine' => { label=>'named machine' }, + 'named_conf' => { label => 'named.conf location', + default=> '/etc/bind/named.conf' }, + 'zonepath' => { label => 'path to zone files', + default=> '/etc/bind/', }, + 'bind_release' => { label => 'ISC BIND Release', + type => 'select', + options => [qw(BIND8 BIND9)], + default => 'BIND8' }, + 'bind9_minttl' => { label => 'The minttl required by bind9 and RFC1035.', + default => '1D' }, ; tie my %bind_slave_options, 'Tie::IxHash', - #'machine' => { label=> 'Slave machine' }, - 'master' => { label=> 'Master IP address(s) (semicolon-separated)' }, - 'named_conf' => { label => 'named.conf location', - default => '/etc/bind/named.conf' }, + #'machine' => { label=> 'Slave machine' }, + 'master' => { label=> 'Master IP address(s) (semicolon-separated)' }, + 'named_conf' => { label => 'named.conf location', + default => '/etc/bind/named.conf' }, + 'bind_release' => { label => 'ISC BIND Release', + type => 'select', + options => [qw(BIND8 BIND9)], + default => 'BIND8' }, + 'bind9_minttl' => { label => 'The minttl required by bind9 and RFC1035.', + default => '1D' }, ; tie my %http_options, 'Tie::IxHash', diff --git a/bin/bind.export b/bin/bind.export index 055782a20..64d44065d 100755 --- a/bin/bind.export +++ b/bin/bind.export @@ -30,6 +30,10 @@ foreach my $export ( @exports ) { my $machine = $export->machine; my $prefix = "$spooldir/$machine"; + my $bind_rel = $export->option('bind_release'); + my $ndc_cmd = ($bind_rel eq 'BIND9') ? 'rndc' : 'ndc'; + my $minttl = $export->option('bind9_minttl'); + #prevent old domain files from piling up #rmtree "$prefix" or die "can't rmtree $prefix.db: $!"; @@ -79,6 +83,10 @@ END open (DB_MASTER,">$prefix/db.$domain") or die "can't open $prefix/db.$domain: $!"; + if ($bind_rel eq 'BIND9') { + print DB_MASTER "\$TTL $minttl\n\$ORIGIN $domain.\n"; + } + my @domain_records = qsearch('domain_record', { 'svcnum' => $svc_domain->svcnum } ); foreach my $domain_record ( @@ -114,7 +122,7 @@ END } ) or die "rsync to $machine failed: ". join(" / ", $rsync->err); # warn $rsync->out; - ssh("root\@$machine", 'ndc reload'); + ssh("root\@$machine", "$ndc_cmd reload"); } @@ -125,6 +133,9 @@ foreach my $sexport ( @sexports ) { #false laziness with above my $machine = $sexport->machine; my $prefix = "$spooldir/$machine"; + my $bind_rel = $sexport->option('bind_release'); + my $ndc_cmd = ($bind_rel eq 'BIND9') ? 'rndc' : 'ndc'; + #prevent old domain files from piling up #rmtree "$prefix" or die "can't rmtree $prefix.db: $!"; @@ -166,7 +177,7 @@ END } ) or die "rsync to $machine failed: ". join(" / ", $rsync->err); # warn $rsync->out; - ssh("root\@$machine", 'ndc reload'); + ssh("root\@$machine", "$ndc_cmd reload"); } close NAMED_CONF; -- cgit v1.2.1 From 21bc19b84183312dbb4087a33ad1ce5877088f82 Mon Sep 17 00:00:00 2001 From: ivan Date: Thu, 24 Apr 2003 02:46:41 +0000 Subject: better shellcommands documentation of all sorts --- FS/FS/part_export.pm | 10 ++++---- FS/FS/part_export/domain_shellcommands.pm | 38 ++++++++++++++----------------- 2 files changed, 22 insertions(+), 26 deletions(-) diff --git a/FS/FS/part_export.pm b/FS/FS/part_export.pm index d898d2616..8370b3f9e 100644 --- a/FS/FS/part_export.pm +++ b/FS/FS/part_export.pm @@ -872,13 +872,13 @@ tie my %forward_shellcommands_options, 'Tie::IxHash', 'desc' => 'Real-time export via remote SSH (i.e. useradd, userdel, etc.)', 'options' => \%shellcommands_options, 'nodomain' => 'Y', - 'notes' => 'Run remote commands via SSH. Usernames are considered unique (also see shellcommands_withdomain). You probably want this if the commands you are running will not accept a domain as a parameter. You will need to setup SSH for unattended operation.

Use these buttons for some useful presets:
', + 'notes' => 'Run remote commands via SSH. Usernames are considered unique (also see shellcommands_withdomain). You probably want this if the commands you are running will not accept a domain as a parameter. You will need to setup SSH for unattended operation.

Use these buttons for some useful presets:
The following variables are available for interpolation (prefixed with new_ or old_ for replace operations):
  • $username
  • $_password
  • $quoted_password - unencrypted password quoted for the shell
  • $crypt_password - encrypted password
  • $uid
  • $gid
  • $finger - GECOS, already quoted for the shell (do not add additional quotes)
  • $dir - home directory
  • $shell
  • $quota
  • All other fields in svc_acct are also available.
', }, 'shellcommands_withdomain' => { 'desc' => 'Real-time export via remote SSH.', 'options' => \%shellcommands_withdomain_options, - 'notes' => 'Run remote commands via SSH. username@domain (rather than just usernames) are considered unique (also see shellcommands). You probably want this if the commands you are running will accept a domain as a parameter, and will allow the same username with different domains. You will need to setup SSH for unattended operation.', + 'notes' => 'Run remote commands via SSH. username@domain (rather than just usernames) are considered unique (also see shellcommands). You probably want this if the commands you are running will accept a domain as a parameter, and will allow the same username with different domains. You will need to setup SSH for unattended operation.

The following variables are available for interpolation (prefixed with new_ or old_ for replace operations):
  • $username
  • $domain
  • $_password
  • $quoted_password - unencrypted password quoted for the shell
  • $crypt_password - encrypted password
  • $uid
  • $gid
  • $finger - GECOS, already quoted for the shell (do not add additional quotes)
  • $dir - home directory
  • $shell
  • $quota
  • All other fields in svc_acct are also available.
', }, 'ldap' => { @@ -959,7 +959,7 @@ tie my %forward_shellcommands_options, 'Tie::IxHash', 'domain_shellcommands' => { 'desc' => 'Run remote commands via SSH, for domains.', 'options' => \%domain_shellcommands_options, - 'notes' => 'Run remote commands via SSH, for domains. You will need to setup SSH for unattended operation.

Use these buttons for some useful presets:
', + 'notes' => 'Run remote commands via SSH, for domains. You will need to setup SSH for unattended operation.

Use these buttons for some useful presets:
The following variables are available for interpolation (prefixed with new_ or old_ for replace operations):
  • $domain
  • $qdomain - domain with periods replaced by colons
  • $uid - of catchall account
  • $gid - of catchall account
  • $dir - home directory of catchall account
  • All other fields in svc_domain are also available.
', }, @@ -976,7 +976,7 @@ tie my %forward_shellcommands_options, 'Tie::IxHash', 'forward_shellcommands' => { 'desc' => 'Run remote commands via SSH, for forwards', 'options' => \%forward_shellcommands_options, - 'notes' => 'Run remote commands via SSH, for forwards. You will need to setup SSH for unattended operation.

Use these buttons for some useful presets:
  • /home/vpopmail/domains/$domain/$username/.qmail; chown vpopmail:vchkpw /home/vpopmail/domains/$domain/$username/.qmail; }"; this.form.userdel.value = "rm /home/vpopmail/domains/$domain/$username/.qmail"; this.form.usermod.value = "mv /home/vpopmail/domains/$old_domain/$old_username/.qmail /home/vpopmail/domains/$new_domain/$new_username; [ \"$old_destination\" != \"$new_destination\" ] && { echo \"$new_destination\" > /home/vpopmail/domains/$new_domain/$new_username/.qmail; chown vpopmail:vchkpw /home/vpopmail/domains/$new_domain/$new_username/.qmail; }";\'>
', + 'notes' => 'Run remote commands via SSH, for forwards. You will need to setup SSH for unattended operation.

Use these buttons for some useful presets:
  • /home/vpopmail/domains/$domain/$username/.qmail; chown vpopmail:vchkpw /home/vpopmail/domains/$domain/$username/.qmail; }"; this.form.userdel.value = "rm /home/vpopmail/domains/$domain/$username/.qmail"; this.form.usermod.value = "mv /home/vpopmail/domains/$old_domain/$old_username/.qmail /home/vpopmail/domains/$new_domain/$new_username; [ \"$old_destination\" != \"$new_destination\" ] && { echo \"$new_destination\" > /home/vpopmail/domains/$new_domain/$new_username/.qmail; chown vpopmail:vchkpw /home/vpopmail/domains/$new_domain/$new_username/.qmail; }";\'>
The following variables are available for interpolation (prefixed with new_ or old_ for replace operations):
  • $username
  • $domain
  • $destination - forward destination
  • All other fields in svc_forward are also available.
', }, }, @@ -984,7 +984,7 @@ tie my %forward_shellcommands_options, 'Tie::IxHash', 'www_shellcommands' => { 'desc' => 'Run remote commands via SSH, for virtual web sites.', 'options' => \%www_shellcommands_options, - 'notes' => 'Run remote commands via SSH, for virtual web sites. You will need to setup SSH for unattended operation.', + 'notes' => 'Run remote commands via SSH, for virtual web sites. You will need to setup SSH for unattended operation.

The following variables are available for interpolation (prefixed with new_ or old_ for replace operations):
  • $zone
  • $username
  • $homedir
  • All other fields in svc_www are also available.
', }, 'apache' => { diff --git a/FS/FS/part_export/domain_shellcommands.pm b/FS/FS/part_export/domain_shellcommands.pm index 5b100e8c6..0edbab0dd 100644 --- a/FS/FS/part_export/domain_shellcommands.pm +++ b/FS/FS/part_export/domain_shellcommands.pm @@ -58,27 +58,23 @@ sub _export_replace { ${"old_$_"} = $old->getfield($_) foreach $old->fields; ${"new_$_"} = $new->getfield($_) foreach $new->fields; } -# my $old_domain_record = $old->domain_record; # or die ? -# my $old_zone = $old_domain_record->reczone; # or die ? -# unless ( $old_zone =~ /\.$/ ) { -# my $old_svc_domain = $old_domain_record->svc_domain; # or die ? -# $old_zone .= '.'. $old_svc_domain->domain; -# } -# -# my $old_svc_acct = $old->svc_acct; # or die ? -# my $old_username = $old_svc_acct->username; -# my $old_homedir = $old_svc_acct->dir; # or die ? -# -# my $new_domain_record = $new->domain_record; # or die ? -# my $new_zone = $new_domain_record->reczone; # or die ? -# unless ( $new_zone =~ /\.$/ ) { -# my $new_svc_domain = $new_domain_record->svc_domain; # or die ? -# $new_zone .= '.'. $new_svc_domain->domain; -# } - -# my $new_svc_acct = $new->svc_acct; # or die ? -# my $new_username = $new_svc_acct->username; -# my $new_homedir = $new_svc_acct->dir; # or die ? + ( $old_qdomain = $old_domain ) =~ s/\./:/g; #see dot-qmail(5): EXTENSION ADDRESSES + ( $new_qdomain = $new_domain ) =~ s/\./:/g; #see dot-qmail(5): EXTENSION ADDRESSES + + if ( $old->catchall ) { + no strict 'refs'; + my $svc_acct = $old->catchall_svc_acct; + ${"old_$_"} = $svc_acct->getfield($_) foreach qw(uid gid dir); + } else { + ${"old_$_"} = '' foreach qw(uid gid dir); + } + if ( $new->catchall ) { + no strict 'refs'; + my $svc_acct = $new->catchall_svc_acct; + ${"new_$_"} = $svc_acct->getfield($_) foreach qw(uid gid dir); + } else { + ${"new_$_"} = '' foreach qw(uid gid dir); + } #done setting variables for the command -- cgit v1.2.1 From fdf62da26a4a9127fd43f359163f231a89bc692d Mon Sep 17 00:00:00 2001 From: khoff Date: Thu, 24 Apr 2003 18:45:03 +0000 Subject: Support for nWnDnHnMnS time format --- FS/FS/domain_record.pm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/FS/FS/domain_record.pm b/FS/FS/domain_record.pm index 2f7e270dc..d3682c351 100644 --- a/FS/FS/domain_record.pm +++ b/FS/FS/domain_record.pm @@ -241,7 +241,7 @@ sub check { if ( $self->rectype eq 'SOA' ) { my $recdata = $self->recdata; $recdata =~ s/\s+/ /g; - $recdata =~ /^([a-z0-9\.\-]+ [\w\-\+]+\.[a-z0-9\.\-]+ \( (\d+ ){5}\))$/i + $recdata =~ /^([a-z0-9\.\-]+ [\w\-\+]+\.[a-z0-9\.\-]+ \( ([\dwdhmsWDHMS]+ ){5}\))$/i or return "Illegal data for SOA record: $recdata"; $self->recdata($1); } elsif ( $self->rectype eq 'NS' ) { @@ -332,7 +332,7 @@ sub zone { =head1 VERSION -$Id: domain_record.pm,v 1.13 2003-03-29 04:53:44 ivan Exp $ +$Id: domain_record.pm,v 1.14 2003-04-24 18:45:03 khoff Exp $ =head1 BUGS -- cgit v1.2.1 From cc6317796afe74fd6dcbc4712abfcb09ff199598 Mon Sep 17 00:00:00 2001 From: khoff Date: Thu, 24 Apr 2003 18:46:36 +0000 Subject: MySQL returns zero on an update when no values change. We would insert on an rv of zero, so now we select count(*)... instead of relying on the rv of the update. --- FS/FS/part_export/sqlmail.pm | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/FS/FS/part_export/sqlmail.pm b/FS/FS/part_export/sqlmail.pm index f97674c27..64f72df07 100644 --- a/FS/FS/part_export/sqlmail.pm +++ b/FS/FS/part_export/sqlmail.pm @@ -115,17 +115,19 @@ sub sqlmail_replace { my %attrs = @_; map { $attrs{$_} = $attrs{$_} ? qq!'$attrs{$_}'! : 'NULL'; } keys(%attrs); - my $query = sprintf('UPDATE %s SET %s WHERE svcnum = %s', - $table, join(', ', map {"$_ = $attrs{$_}"} keys(%attrs)), - $oldsvcnum); - - my $rv = $dbh->do($query) or die $dbh->errstr; - - if ($rv == 0) { + my $query = "SELECT COUNT(*) FROM $table WHERE svcnum = $oldsvcnum"; + my $result = $dbh->selectrow_arrayref($query) or die $dbh->errstr; + + if (@$result[0] == 0) { $query = sprintf("INSERT INTO %s (%s) values (%s)", $table, join(",", keys(%attrs)), join(',', values(%attrs))); $dbh->do($query) or die $dbh->errstr; + } else { + $query = sprintf('UPDATE %s SET %s WHERE svcnum = %s', + $table, join(', ', map {"$_ = $attrs{$_}"} keys(%attrs)), + $oldsvcnum); + $dbh->do($query) or die $dbh->errstr; } $dbh->disconnect; -- cgit v1.2.1 From 7d0dbc7da5c736da8989b9aeb2e8911fa16462a9 Mon Sep 17 00:00:00 2001 From: ivan Date: Thu, 24 Apr 2003 23:02:16 +0000 Subject: fix for bug triggered by nonexistant referring customer numbers --- httemplate/edit/cust_main.cgi | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/httemplate/edit/cust_main.cgi b/httemplate/edit/cust_main.cgi index d8edbcd8e..2b7d8d0dc 100755 --- a/httemplate/edit/cust_main.cgi +++ b/httemplate/edit/cust_main.cgi @@ -124,9 +124,11 @@ if ( $custnum && ! $conf->exists('editreferrals') ) { #referring customer #print qq!

Referring Customer: !; -if ( $cust_main->referral_custnum ) { - my $referring_cust_main = - qsearchs('cust_main', { custnum => $cust_main->referral_custnum } ); +my $referring_cust_main = ''; +if ( $cust_main->referral_custnum + and $referring_cust_main = + qsearchs('cust_main', { custnum => $cust_main->referral_custnum } ) +) { print '

Referring Customer: '. $cust_main->referral_custnum. ': '. -- cgit v1.2.1 From d5aab81fa7c59695bc4bad8820bbd7d9e1d77309 Mon Sep 17 00:00:00 2001 From: khoff Date: Sat, 26 Apr 2003 00:28:47 +0000 Subject: Tyop --- FS/FS/cust_bill.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FS/FS/cust_bill.pm b/FS/FS/cust_bill.pm index aa82eb6f8..76c0752ab 100644 --- a/FS/FS/cust_bill.pm +++ b/FS/FS/cust_bill.pm @@ -812,7 +812,7 @@ sub realtime_bop { 'invnum' => $self->invnum, 'paid' => $amount, '_date' => '', - 'payby' => method2payby{$method}, + 'payby' => $method2payby{$method}, 'payinfo' => $cust_main->payinfo, 'paybatch' => "$processor:". $transaction->authorization, } ); -- cgit v1.2.1 From 6b49613d47236c0fc01ad37021c460d0c8809c9a Mon Sep 17 00:00:00 2001 From: khoff Date: Sat, 26 Apr 2003 02:01:09 +0000 Subject: I don't like FS::Record warnings --- FS/FS/cust_svc.pm | 1 + 1 file changed, 1 insertion(+) diff --git a/FS/FS/cust_svc.pm b/FS/FS/cust_svc.pm index 26e6274a1..8ac806519 100644 --- a/FS/FS/cust_svc.pm +++ b/FS/FS/cust_svc.pm @@ -11,6 +11,7 @@ use FS::pkg_svc; use FS::svc_acct; use FS::svc_domain; use FS::svc_forward; +use FS::svc_broadband; use FS::domain_record; use FS::part_export; -- cgit v1.2.1 From c4a7388a676878b64a3d3b2b2e0a4004e4daf669 Mon Sep 17 00:00:00 2001 From: khoff Date: Tue, 29 Apr 2003 16:59:10 +0000 Subject: It helps if you can edit the ip_addr field. --- httemplate/edit/svc_broadband.cgi | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/httemplate/edit/svc_broadband.cgi b/httemplate/edit/svc_broadband.cgi index f017d7a6e..ee7f8becf 100644 --- a/httemplate/edit/svc_broadband.cgi +++ b/httemplate/edit/svc_broadband.cgi @@ -96,10 +96,18 @@ Service #<%=$svcnum ? $svcnum : "(NEW)"%>

- <%=&ntable("#cccccc",2)%> - + + IP Address + +<% if ( $part_svc->part_svc_column('ip_addr')->columnflag eq 'F' ) { %> + <%=$ip_addr%> +<% } else { %> + +<% } %> + + Download speed -- cgit v1.2.1 From e77371fc4d3443c7b97a387bd25897b52200d64a Mon Sep 17 00:00:00 2001 From: khoff Date: Tue, 29 Apr 2003 18:28:50 +0000 Subject: Better SOA checking --- FS/FS/domain_record.pm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/FS/FS/domain_record.pm b/FS/FS/domain_record.pm index d3682c351..77b955088 100644 --- a/FS/FS/domain_record.pm +++ b/FS/FS/domain_record.pm @@ -241,7 +241,7 @@ sub check { if ( $self->rectype eq 'SOA' ) { my $recdata = $self->recdata; $recdata =~ s/\s+/ /g; - $recdata =~ /^([a-z0-9\.\-]+ [\w\-\+]+\.[a-z0-9\.\-]+ \( ([\dwdhmsWDHMS]+ ){5}\))$/i + $recdata =~ /^([a-z0-9\.\-]+ [\w\-\+]+\.[a-z0-9\.\-]+ \( ((\d+|((\d+[WDHMS])+)) ){5}\))$/i or return "Illegal data for SOA record: $recdata"; $self->recdata($1); } elsif ( $self->rectype eq 'NS' ) { @@ -332,7 +332,7 @@ sub zone { =head1 VERSION -$Id: domain_record.pm,v 1.14 2003-04-24 18:45:03 khoff Exp $ +$Id: domain_record.pm,v 1.15 2003-04-29 18:28:50 khoff Exp $ =head1 BUGS -- cgit v1.2.1 From aee635ea9986d031a996381f71e67d1446c10331 Mon Sep 17 00:00:00 2001 From: khoff Date: Tue, 29 Apr 2003 19:49:37 +0000 Subject: 0 has a hash key looks like svcnum = 0. Suprisingly, '' works. --- httemplate/misc/catchall.cgi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/httemplate/misc/catchall.cgi b/httemplate/misc/catchall.cgi index 9aa84be18..3402b61e6 100755 --- a/httemplate/misc/catchall.cgi +++ b/httemplate/misc/catchall.cgi @@ -77,7 +77,7 @@ if ($pkgnum) { } # add an absence of a catchall -$email{0} = "(none)"; +$email{''} = "(none)"; my $p1 = popurl(1); print header("Domain Catchall Edit", ''); -- cgit v1.2.1 From f558d1e0e0ae2c956f7dd77d35ae647e45776087 Mon Sep 17 00:00:00 2001 From: khoff Date: Fri, 2 May 2003 23:51:06 +0000 Subject: CARD && DCRD? --- httemplate/view/cust_main.cgi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/httemplate/view/cust_main.cgi b/httemplate/view/cust_main.cgi index 2dc53e674..cea8d6321 100755 --- a/httemplate/view/cust_main.cgi +++ b/httemplate/view/cust_main.cgi @@ -223,7 +223,7 @@ if ( $conf->config('payby-default') ne 'HIDE' ) { 'Billing type', ; - if ( $cust_main->payby eq 'CARD' && $cust_main->payby eq 'DCRD' ) { + if ( $cust_main->payby eq 'CARD' || $cust_main->payby eq 'DCRD' ) { my $payinfo = $cust_main->payinfo; $payinfo = 'x'x(length($payinfo)-4). substr($payinfo,(length($payinfo)-4)); print 'Credit card ', @@ -236,7 +236,7 @@ if ( $conf->config('payby-default') ne 'HIDE' ) { 'Name on card', $cust_main->payname, '' ; - } elsif ( $cust_main->payby eq 'CHEK' && $cust_main->payby eq 'DCHK') { + } elsif ( $cust_main->payby eq 'CHEK' || $cust_main->payby eq 'DCHK') { my( $account, $aba ) = split('@', $cust_main->payinfo ); print 'Electronic check', ( $cust_main->payby eq 'CHEK' ? '(automatic)' : '(on-demand)' ), -- cgit v1.2.1 From 5b16f111a4c03075e27bfc1f2299a9ed2c71a605 Mon Sep 17 00:00:00 2001 From: ivan Date: Sat, 3 May 2003 01:30:35 +0000 Subject: clean up CVS cruft --- FS/FS/part_export.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FS/FS/part_export.pm b/FS/FS/part_export.pm index 8370b3f9e..9a1b9d864 100644 --- a/FS/FS/part_export.pm +++ b/FS/FS/part_export.pm @@ -307,7 +307,7 @@ sub part_svc { =item svc_x -Returns a list of associate FS::svc_* records. +Returns a list of associated FS::svc_* records. =cut -- cgit v1.2.1 From 4cde7ff66b9d008668a430615264c38eb723de2b Mon Sep 17 00:00:00 2001 From: ivan Date: Sat, 3 May 2003 02:03:48 +0000 Subject: typo in usage instructions --- bin/apache.export | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/apache.export b/bin/apache.export index 399fb0377..908313606 100755 --- a/bin/apache.export +++ b/bin/apache.export @@ -60,6 +60,6 @@ close HTTPD_CONF; # ----- sub usage { - die "Usage:\n export.export user\n"; + die "Usage:\n apache.export user\n"; } -- cgit v1.2.1 From 61a2cea1f9f09fcb0482af442f45ef620277a8dc Mon Sep 17 00:00:00 2001 From: ivan Date: Sat, 3 May 2003 02:06:56 +0000 Subject: enable quota maintenance in infostreet export --- FS/FS/part_export/infostreet.pm | 37 +++++++++++++++++++++++++++++++++++++ httemplate/edit/svc_acct.cgi | 11 ++++++++++- 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/FS/FS/part_export/infostreet.pm b/FS/FS/part_export/infostreet.pm index f2d519932..caca7c5e1 100644 --- a/FS/FS/part_export/infostreet.pm +++ b/FS/FS/part_export/infostreet.pm @@ -55,6 +55,12 @@ sub _export_insert { $err_or_queue = $self->infostreet_queueContact( $svc_acct->svcnum, $svc_acct->username, %contact_info ); return $err_or_queue unless ref($err_or_queue); + + # If a quota has been specified set the quota because it is not the default + $err_or_queue = $self->infostreet_queueSetQuota( $svc_acct->svcnum, + $svc_acct->username, $svc_acct->quota ) if $svc_acct->quota; + return $err_or_queue unless ref($err_or_queue); + my $error = $err_or_queue->depend_insert( $jobnum ); return $error if $error; @@ -68,6 +74,13 @@ sub _export_replace { my( $self, $new, $old ) = (shift, shift, shift); return "can't change username with InfoStreet" if $old->username ne $new->username; + + # If the quota has changed then do the export to setQuota + my $err_or_queue = $self->infostreet_queueSetQuota( $new->svcnum, $new->username, $new->quota ) + if ( $old->quota != $new->quota ); + return $err_or_queue unless ref($err_or_queue); + + return '' unless $old->_password ne $new->_password; $self->infostreet_queue( $new->svcnum, 'passwd', $new->username, $new->_password ); @@ -150,6 +163,30 @@ sub infostreet_setContact { } +sub infostreet_queueSetQuota { + + my( $self, $svcnum) = (shift, shift); + my $queue = new FS::queue { + 'svcnum' => $svcnum, + 'job' => 'FS::part_export::infostreet::infostreet_setQuota', + }; + + $queue->insert( + $self->option('url'), + $self->option('login'), + $self->option('password'), + $self->option('groupID'), + @_, + ) or $queue; + +} + +sub infostreet_setQuota { + my($url, $is_username, $is_password, $groupID, $username, $quota) = @_; + infostreet_command($url, $is_username, $is_password, $groupID, 'setQuota', $username, [ 'int'=> $quota ] ); +} + + sub infostreet_command { #subroutine, not method my($url, $username, $password, $groupID, $method, @args) = @_; diff --git a/httemplate/edit/svc_acct.cgi b/httemplate/edit/svc_acct.cgi index d4c9a738d..4420bb609 100755 --- a/httemplate/edit/svc_acct.cgi +++ b/httemplate/edit/svc_acct.cgi @@ -244,7 +244,16 @@ my($quota,$slipip)=( $svc_acct->slipip, ); -print qq!!; +if ( $part_svc->part_svc_column('quota')->columnflag eq "F" ) +{ + print qq!!; +} else { + print <Quota: + + +END +} if ( $part_svc->part_svc_column('slipip')->columnflag eq "F" ) { print qq!!; -- cgit v1.2.1 From 903fb4a4509866ffaba09bf09fe535ba3ae02400 Mon Sep 17 00:00:00 2001 From: khoff Date: Sun, 4 May 2003 20:58:01 +0000 Subject: proposed cust_main.cgi --- httemplate/view/cust_main_alt.cgi | 819 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 819 insertions(+) create mode 100644 httemplate/view/cust_main_alt.cgi diff --git a/httemplate/view/cust_main_alt.cgi b/httemplate/view/cust_main_alt.cgi new file mode 100644 index 000000000..80fa49e04 --- /dev/null +++ b/httemplate/view/cust_main_alt.cgi @@ -0,0 +1,819 @@ + +<% + +my $conf = new FS::Conf; + +#false laziness with view/cust_pkg.cgi, but i'm trying to make that go away so +my %uiview = (); +my %uiadd = (); +foreach my $part_svc ( qsearch('part_svc',{}) ) { + $uiview{$part_svc->svcpart} = popurl(2). "view/". $part_svc->svcdb . ".cgi"; + $uiadd{$part_svc->svcpart}= popurl(2). "edit/". $part_svc->svcdb . ".cgi"; +} + +print header("Customer View", menubar( + 'Main Menu' => popurl(2) +)); + +print < +.package TH { font-size: medium } +.package TR { font-size: smaller } +.package .datehdr TH { font-size: smaller } +.package .pkgnum { font-size: medium } +.package .provision { font-size: larger; color: red; font-weight: bold } + +END + +die "No customer specified (bad URL)!" unless $cgi->keywords; +my($query) = $cgi->keywords; # needs parens with my, ->keywords returns array +$query =~ /^(\d+)$/; +my $custnum = $1; +my $cust_main = qsearchs('cust_main',{'custnum'=>$custnum}); +die "Customer not found!" unless $cust_main; + +print qq!
Edit this customer!; + +print < +function cancel_areyousure(href) { + if (confirm("Perminantly delete all services and cancel this customer?") == true) + window.location.href = href; +} + +END + +print qq! | !. + 'Cancel this customer' + if $cust_main->ncancelled_pkgs; + +print qq! | !. + 'Delete this customer' + if $conf->exists('deletecustomers'); + +unless ( $conf->exists('disable_customer_referrals') ) { + print qq! | !, + qq!Refer a new customer!; + + print qq! | !, + qq!View this customer's referrals!; +} + +print '

'; + +my $signupurl = $conf->config('signupurl'); +if ( $signupurl ) { +print "This customer's signup URL: ". + "$signupurl?ref=$custnum

"; +} + +print ''; + +print &itable(), ''; + +print ''; + + print "Billing address", &ntable("#cccccc"), "", + &ntable("#cccccc",2), + 'Contact name', + '', + $cust_main->last, ', ', $cust_main->first, + ''; +print 'SS#', + $cust_main->ss || ' ', '' + if $conf->exists('show_ss'); + +print '', + 'Company', + $cust_main->company, + '', + 'Address', + $cust_main->address1, + '', + ; + print ' ', + $cust_main->address2, '' + if $cust_main->address2; + print 'City', + $cust_main->city, + 'State', + $cust_main->state, + 'Zip', + $cust_main->zip, '', + 'Country', + $cust_main->country, + '', + ; + my $daytime_label = FS::Msgcat::_gettext('daytime') || 'Day Phone'; + my $night_label = FS::Msgcat::_gettext('night') || 'Night Phone'; + print ''. $daytime_label. + '', + $cust_main->daytime || ' ', '', + ''. $night_label. + '', + $cust_main->night || ' ', '', + 'Fax', + $cust_main->fax || ' ', '', + '', "" + ; + + if ( defined $cust_main->dbdef_table->column('ship_last') ) { + + my $pre = $cust_main->ship_last ? 'ship_' : ''; + + print "
Service address", &ntable("#cccccc"), "", + &ntable("#cccccc",2), + 'Contact name', + '', + $cust_main->get("${pre}last"), ', ', $cust_main->get("${pre}first"), + '', + 'Company', + $cust_main->get("${pre}company"), + '', + 'Address', + $cust_main->get("${pre}address1"), + '', + ; + print ' ', + $cust_main->get("${pre}address2"), '' + if $cust_main->get("${pre}address2"); + print 'City', + $cust_main->get("${pre}city"), + 'State', + $cust_main->get("${pre}state"), + 'Zip', + $cust_main->get("${pre}zip"), '', + 'Country', + $cust_main->get("${pre}country"), + '', + ; + print ''. $daytime_label. '', + '', + $cust_main->get("${pre}daytime") || ' ', '', + ''. $night_label. ''. + '', + $cust_main->get("${pre}night") || ' ', '', + 'Fax', + $cust_main->get("${pre}fax") || ' ', '', + '', "" + ; + + } + +print ''; + +print ''; + + print &ntable("#cccccc"), "", &ntable("#cccccc",2), + 'Customer number', + $custnum, '', + ; + + my @agents = qsearch( 'agent', {} ); + my $agent; + unless ( scalar(@agents) == 1 ) { + $agent = qsearchs('agent',{ 'agentnum' => $cust_main->agentnum } ); + print 'Agent', + $agent->agentnum, ": ", $agent->agent, ''; + } else { + $agent = $agents[0]; + } + my @referrals = qsearch( 'part_referral', {} ); + unless ( scalar(@referrals) == 1 ) { + my $referral = qsearchs('part_referral', { + 'refnum' => $cust_main->refnum + } ); + print 'Advertising source', + $referral->refnum, ": ", $referral->referral, ''; + } + print 'Order taker', + $cust_main->otaker, ''; + + print 'Referring Customer'; + my $referring_cust_main = ''; + if ( $cust_main->referral_custnum + && ( $referring_cust_main = + qsearchs('cust_main', { custnum => $cust_main->referral_custnum } ) + ) + ) { + print ''. + $cust_main->referral_custnum. ': '. + ( $referring_cust_main->company + ? $referring_cust_main->company. ' ('. + $referring_cust_main->last. ', '. $referring_cust_main->first. + ')' + : $referring_cust_main->last. ', '. $referring_cust_main->first + ). + ''; + } + print ''; + + print ''; + +print '
'; + +if ( $conf->config('payby-default') ne 'HIDE' ) { + + my @invoicing_list = $cust_main->invoicing_list; + print "Billing information (", + qq!!, "Bill now)", + &ntable("#cccccc"), "", &ntable("#cccccc",2), + 'Tax exempt', + $cust_main->tax ? 'yes' : 'no', + '', + 'Postal invoices', + ( grep { $_ eq 'POST' } @invoicing_list ) ? 'yes' : 'no', + '', + 'Email invoices', + join(', ', grep { $_ ne 'POST' } @invoicing_list ) || 'no', + '', + 'Billing type', + ; + + if ( $cust_main->payby eq 'CARD' || $cust_main->payby eq 'DCRD' ) { + my $payinfo = $cust_main->payinfo; + $payinfo = 'x'x(length($payinfo)-4). substr($payinfo,(length($payinfo)-4)); + print 'Credit card ', + ( $cust_main->payby eq 'CARD' ? '(automatic)' : '(on-demand)' ), + '', + 'Card number', + $payinfo, '', + 'Expiration', + $cust_main->paydate, '', + 'Name on card', + $cust_main->payname, '' + ; + } elsif ( $cust_main->payby eq 'CHEK' || $cust_main->payby eq 'DCHK') { + my( $account, $aba ) = split('@', $cust_main->payinfo ); + print 'Electronic check', + ( $cust_main->payby eq 'CHEK' ? '(automatic)' : '(on-demand)' ), + '', + 'Account number', + $account, '', + 'ABA/Routing code', + $aba, '', + 'Bank name', + $cust_main->payname, '' + ; + } elsif ( $cust_main->payby eq 'LECB' ) { + $cust_main->payinfo =~ /^(\d{3})(\d{3})(\d{4})$/; + my $payinfo = "$1-$2-$3"; + print 'Phone bill billing', + 'Phone number', + $payinfo, '', + ; + } elsif ( $cust_main->payby eq 'BILL' ) { + print 'Billing'; + print 'P.O. ', + $cust_main->payinfo, '', + if $cust_main->payinfo; + print 'Expiration', + $cust_main->paydate, '', + 'Attention', + $cust_main->payname, '', + ; + } elsif ( $cust_main->payby eq 'COMP' ) { + print 'Complimentary', + 'Authorized by', + $cust_main->payinfo, '', + 'Expiration', + $cust_main->paydate, '', + ; + } + + print ""; + +} + +print ''; + +if ( defined $cust_main->dbdef_table->column('comments') + && $cust_main->comments ) +{ + print "
Comments". &ntable("#cccccc"). "". + &ntable("#cccccc",2). + '
'.
+        encode_entities($cust_main->comments).
+        '
'; +} + +print ''; + +print '
'. + '
'. + qq!!. + '

'; + +if ( $conf->config('payby-default') ne 'HIDE' ) { + + print '
'. + qq!
!. + qq!!. + qq!Description:!. + qq! Amount:!. + qq! !; + + #false laziness w/ edit/part_pkg.cgi + if ( $conf->exists('enable_taxclasses') ) { + print ''; + } else { + print ''; + } + + print qq!

!; + +} + +print < +function cust_pkg_areyousure(href) { + if (confirm("Permanently delete included services and cancel this package?") == true) + window.location.href = href; +} +function svc_areyousure(href) { + if (confirm("Permanently unprovision and delete this service?") == true) + window.location.href = href; +} + +END + +print qq!
Packages !, +# qq!
Click on package number to view/edit package.!, + qq!( Order and cancel packages (preserves services) )!, +; + +#begin display packages + +#get package info + +my $packages = get_packages(); + +if ( @$packages ) { +%> + + + + + + + + + + + + + + +<% +foreach my $pkg (sort pkgsort_pkgnum_cancel @$packages) { + my $rowspan = 0; + + if ($pkg->{cancel}) { + $rowspan = 0; + } else { + foreach my $svcpart (@{$pkg->{svcparts}}) { + $rowspan += $svcpart->{count}; + $rowspan++ if ($svcpart->{count} < $svcpart->{quantity}); + } + } + +%> + + + + +<% + foreach (qw(setup last_bill next_bill susp expire cancel)) { + print qq! \n!; + } + + if ($rowspan == 0) { print qq!\n!; next; } + + my $cnt = 0; + foreach my $svcpart (sort {$a->{svcpart} <=> $b->{svcpart}} @{$pkg->{svcparts}}) { + foreach my $service (@{$svcpart->{services}}) { + print '' if ($cnt > 0); +%> + + + +<% + $cnt++; + } + if ($svcpart->{count} < $svcpart->{quantity}) { + print qq!\n! if ($cnt > 0); + print qq! \n\n!; + } + } +} +print '
PackageDatesServices
SetupLast billNext billSusp.ExpireCancel
CLASS="pkgnum"><%=$pkg->{pkgnum}%>> + <%=$pkg->{pkg}%> - <%=$pkg->{comment}%> ( <%=pkg_details_link($pkg)%> )
+<% unless ($pkg->{cancel}) { %> + ( <%=pkg_change_link($pkg)%> ) + ( <%=($pkg->{susp}) ? pkg_unsuspend_link($pkg) : pkg_suspend_link($pkg)%> | <%=pkg_cancel_link($pkg)%> ) + ( <%=pkg_dates_link($pkg)%> | <%=pkg_customize_link($pkg)%> ) +<% } %> +
! . pkg_datestr($pkg,$_) . qq!
<%=svc_link($svcpart,$service)%><%=svc_label_link($svcpart,$service)%>
( <%=svc_unprovision_link($service)%> )
!.svc_provision_link($pkg,$svcpart).qq!
' +} + +#end display packages + + +print < +function cust_pay_areyousure(href) { + if (confirm("Are you sure you want to delete this payment?") + == true) + window.location.href = href; +} +function cust_pay_unapply_areyousure(href) { + if (confirm("Are you sure you want to unapply this payment?") + == true) + window.location.href = href; +} + +END + +if ( $conf->config('payby-default') ne 'HIDE' ) { + + #formatting + print qq!

Payment History!. + qq! ( !. + qq!!. + qq!Post payment | !. + qq!!. + qq!Post credit )!; + + #get payment history + # + # major problem: this whole thing is way too sloppy. + # minor problem: the description lines need better formatting. + + my @history = (); #needed for mod_perl :) + + my %target = (); + + my @bills = qsearch('cust_bill',{'custnum'=>$custnum}); + foreach my $bill (@bills) { + my($bref)=$bill->hashref; + my $bpre = ( $bill->owed > 0 ) + ? ' Open ' + : ''; + my $bpost = ( $bill->owed > 0 ) ? '' : ''; + push @history, + $bref->{_date} . qq!\t${bpre}Invoice #! . $bref->{invnum} . + qq! (Balance \$! . $bill->owed . qq!)$bpost\t! . + $bref->{charged} . qq!\t\t\t!; + + my(@cust_bill_pay)=qsearch('cust_bill_pay',{'invnum'=> $bref->{invnum} } ); + # my(@payments)=qsearch('cust_pay',{'invnum'=> $bref->{invnum} } ); + # my($payment); + foreach my $cust_bill_pay (@cust_bill_pay) { + my $payment = $cust_bill_pay->cust_pay; + my($date,$invnum,$payby,$payinfo,$paid)=($payment->_date, + $cust_bill_pay->invnum, + $payment->payby, + $payment->payinfo, + $cust_bill_pay->amount, + ); + $payinfo = 'x'x(length($payinfo)-4). substr($payinfo,(length($payinfo)-4)) + if $payby eq 'CARD'; + my $target = "$payby$payinfo"; + $payby =~ s/^BILL$/Check #/ if $payinfo; + $payby =~ s/^(CARD|COMP)$/$1 /; + my $delete = $payment->closed !~ /^Y/i && $conf->exists('deletepayments') + ? qq! (delete)! + : ''; + my $unapply = + $payment->closed !~ /^Y/i && $conf->exists('unapplypayments') + ? qq! (unapply)! + : ''; + push @history, + "$date\tPayment, Invoice #$invnum ($payby$payinfo)$delete$unapply\t\t$paid\t\t\t$target"; + } + + my(@cust_credit_bill)= + qsearch('cust_credit_bill', { 'invnum'=> $bref->{invnum} } ); + foreach my $cust_credit_bill (@cust_credit_bill) { + my $cust_credit = $cust_credit_bill->cust_credit; + my($date, $invnum, $crednum, $amount, $reason, $app_date ) = ( + $cust_credit->_date, + $cust_credit_bill->invnum, + $cust_credit_bill->crednum, + $cust_credit_bill->amount, + $cust_credit->reason, + time2str("%D", $cust_credit_bill->_date), + ); + push @history, + "$date\tCredit #$crednum: $reason
". + "(applied to invoice #$invnum on $app_date)\t\t\t$amount\t"; + } + } + + my @credits = grep { scalar(my @array = $_->cust_credit_refund) } + qsearch('cust_credit',{'custnum'=>$custnum}); + foreach my $credit (@credits) { + my($cref)=$credit->hashref; + my(@cust_credit_refund)= + qsearch('cust_credit_refund', { 'crednum'=> $cref->{crednum} } ); + foreach my $cust_credit_refund (@cust_credit_refund) { + my $cust_refund = $cust_credit_refund->cust_credit; + my($date, $crednum, $amount, $reason, $app_date ) = ( + $credit->_date, + $credit->crednum, + $cust_credit_refund->amount, + $credit->reason, + time2str("%D", $cust_credit_refund->_date), + ); + push @history, + "$date\tCredit #$crednum: $reason
". + "(applied to refund on $app_date)\t\t\t$amount\t"; + } + } + + @credits = grep { $_->credited > 0 } + qsearch('cust_credit',{'custnum'=>$custnum}); + foreach my $credit (@credits) { + my($cref)=$credit->hashref; + push @history, + $cref->{_date} . "\t" . + qq!!. + 'Unapplied credit #' . + $cref->{crednum} . ": ". + $cref->{reason} . "\t\t\t" . $credit->credited . "\t"; + } + + my(@refunds)=qsearch('cust_refund',{'custnum'=> $custnum } ); + foreach my $refund (@refunds) { + my($rref)=$refund->hashref; + my($refundnum) = ( + $refund->refundnum, + ); + + push @history, + $rref->{_date} . "\tRefund #$refundnum, (" . + $rref->{payby} . " " . $rref->{payinfo} . ") by " . + $rref->{otaker} . " - ". $rref->{reason} . "\t\t\t\t" . + $rref->{refund}; + } + + my @unapplied_payments = + grep { $_->unapplied > 0 } qsearch('cust_pay', { 'custnum' => $custnum } ); + foreach my $payment (@unapplied_payments) { + my $payby = $payment->payby; + my $payinfo = $payment->payinfo; + #false laziness w/above + $payinfo = 'x'x(length($payinfo)-4). substr($payinfo,(length($payinfo)-4)) + if $payby eq 'CARD'; + my $target = "$payby$payinfo"; + $payby =~ s/^BILL$/Check #/ if $payinfo; + $payby =~ s/^(CARD|COMP)$/$1 /; + my $delete = $payment->closed !~ /^Y/i && $conf->exists('deletepayments') + ? qq! (delete)! + : ''; + push @history, + $payment->_date. "\t". + 'Unapplied payment #' . + $payment->paynum . " ($payby$payinfo) ". + '('. + "apply)$delete". + "\t\t" . $payment->unapplied . "\t\t\t$target"; + } + + #formatting + print &table(), < + Date + Description + Charge + Payment + In-house
Credit
+ Refund + Balance + +END + + #display payment history + + my $balance = 0; + foreach my $item (sort keyfield_numerically @history) { + my($date,$desc,$charge,$payment,$credit,$refund,$target)=split(/\t/,$item); + $charge ||= 0; + $payment ||= 0; + $credit ||= 0; + $refund ||= 0; + $balance += $charge - $payment; + $balance -= $credit - $refund; + $balance = sprintf("%.2f", $balance); + $balance =~ s/^\-0\.00$/0.00/; #yay ieee fp + $target = '' unless defined $target; + + print ""; + print qq!! unless $target && $target{$target}++; + print time2str("%D",$date); + print '' if $target && $target{$target} == 1; + print "", + "$desc", + "", + ( $charge ? "\$".sprintf("%.2f",$charge) : '' ), + "", + "", + ( $payment ? "- \$".sprintf("%.2f",$payment) : '' ), + "", + "", + ( $credit ? "- \$".sprintf("%.2f",$credit) : '' ), + "", + "", + ( $refund ? "\$".sprintf("%.2f",$refund) : '' ), + "", + "\$" . $balance, + "", + "\n"; + } + + print ""; + +} + +print ''; + +#subroutiens +sub keyfield_numerically { (split(/\t/,$a))[0] <=> (split(/\t/,$b))[0]; } + +%> + +<% + + +sub get_packages { + +my @packages = (); + +foreach my $cust_pkg (($conf->exists('hidecancelledpackages') ? ($cust_main->ncancelled_pkgs) + : ($cust_main->all_pkgs))) { + + my $part_pkg = $cust_pkg->part_pkg; + + my %pkg = (); + $pkg{pkgnum} = $cust_pkg->pkgnum; + $pkg{pkg} = $part_pkg->pkg; + $pkg{pkgpart} = $part_pkg->pkgpart; + $pkg{comment} = $part_pkg->getfield('comment'); + $pkg{setup} = $cust_pkg->getfield('setup'); + $pkg{last_bill} = $cust_pkg->getfield('last_bill'); + $pkg{next_bill} = $cust_pkg->getfield('bill'); + $pkg{susp} = $cust_pkg->getfield('susp'); + $pkg{expire} = $cust_pkg->getfield('expire'); + $pkg{cancel} = $cust_pkg->getfield('cancel'); + + $pkg{svcparts} = []; + + foreach my $pkg_svc (qsearch('pkg_svc', { 'pkgpart' => $part_pkg->pkgpart })) { + + next if ($pkg_svc->quantity == 0); + + my $part_svc = qsearchs('part_svc', { 'svcpart' => $pkg_svc->svcpart }); + + my $svcpart = {}; + $svcpart->{svcpart} = $part_svc->svcpart; + $svcpart->{svc} = $part_svc->svc; + $svcpart->{svcdb} = $part_svc->svcdb; + $svcpart->{quantity} = $pkg_svc->quantity; + $svcpart->{count} = 0; + + $svcpart->{services} = []; + + foreach my $cust_svc (qsearch('cust_svc', { 'pkgnum' => $cust_pkg->pkgnum, + 'svcpart' => $part_svc->svcpart } )) { + + my $svc = {}; + $svc->{svcnum} = $cust_svc->svcnum; + $svc->{label} = ($cust_svc->label)[1]; + + push @{$svcpart->{services}}, $svc; + + $svcpart->{count}++; + + } + + push @{$pkg{svcparts}}, $svcpart; + + } + + push @packages, \%pkg; + +} + +return \@packages; + +} + +sub svc_link { + + my ($svcpart, $svc) = (shift,shift) or return ''; + return qq!$svcpart->{svc}!; + +} + +sub svc_label_link { + + my ($svcpart, $svc) = (shift,shift) or return ''; + return qq!$svc->{label}!; + +} + +sub svc_provision_link { + my ($pkg, $svcpart) = (shift,shift) or return ''; + return qq!! . + qq!Provision $svcpart->{svc} (! . ($svcpart->{quantity} - $svcpart->{count}) . qq!)!; +} + +sub svc_unprovision_link { + my $svc = shift or return ''; + return qq!Unprovision!; +} + +# This should be generalized to use config options to determine order. +sub pkgsort_pkgnum_cancel { + if ($a->{cancel} and $b->{cancel}) { + return ($a->{pkgnum} <=> $b->{pkgnum}); + } elsif ($a->{cancel} or $b->{cancel}) { + return (-1) if ($b->{cancel}); + return (1) if ($a->{cancel}); + return (0); + } else { + return($a->{pkgnum} <=> $b->{pkgnum}); + } +} + +sub pkg_datestr { + my ($pkg,$field) = (shift,shift) or return ''; + return $pkg->{$field} ? time2str('%D
%l:%M:%S%P %z', + $pkg->{$field}) + : ' '; +} + +sub pkg_details_link { + my $pkg = shift or return ''; + return qq!Details!; +} + +sub pkg_change_link { + my $pkg = shift or return ''; + return qq!Change package!; +} + +sub pkg_suspend_link { + my $pkg = shift or return ''; + return qq!Suspend!; +} + +sub pkg_unsuspend_link { + my $pkg = shift or return ''; + return qq!Unsuspend!; +} + +sub pkg_cancel_link { + my $pkg = shift or return ''; + return qq!Cancel!; +} + +sub pkg_dates_link { + my $pkg = shift or return ''; + return qq!Edit dates!; +} + +sub pkg_customize_link { + my $pkg = shift or return ''; + return qq!Customize!; +} + +%> + -- cgit v1.2.1 From bc2e387fcf4cf847ef7b51e4137e276fedea5c1e Mon Sep 17 00:00:00 2001 From: khoff Date: Tue, 6 May 2003 20:33:03 +0000 Subject: Can't pull out of thin air. --- httemplate/view/cust_main_alt.cgi | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/httemplate/view/cust_main_alt.cgi b/httemplate/view/cust_main_alt.cgi index 80fa49e04..01e46b59a 100644 --- a/httemplate/view/cust_main_alt.cgi +++ b/httemplate/view/cust_main_alt.cgi @@ -371,7 +371,7 @@ print qq!
Packages !, #get package info -my $packages = get_packages(); +my $packages = get_packages($cust_main); if ( @$packages ) { %> @@ -673,6 +673,8 @@ sub keyfield_numerically { (split(/\t/,$a))[0] <=> (split(/\t/,$b))[0]; } sub get_packages { +my $cust_main = shift or return undef; + my @packages = (); foreach my $cust_pkg (($conf->exists('hidecancelledpackages') ? ($cust_main->ncancelled_pkgs) -- cgit v1.2.1 From 5839c5c7d8fe0b2cfe13e2bbd3a1c25128b4cecf Mon Sep 17 00:00:00 2001 From: ivan Date: Tue, 6 May 2003 21:15:55 +0000 Subject: don't create new files in lieu of branches --- httemplate/view/cust_main_alt.cgi | 821 -------------------------------------- 1 file changed, 821 deletions(-) delete mode 100644 httemplate/view/cust_main_alt.cgi diff --git a/httemplate/view/cust_main_alt.cgi b/httemplate/view/cust_main_alt.cgi deleted file mode 100644 index 01e46b59a..000000000 --- a/httemplate/view/cust_main_alt.cgi +++ /dev/null @@ -1,821 +0,0 @@ - -<% - -my $conf = new FS::Conf; - -#false laziness with view/cust_pkg.cgi, but i'm trying to make that go away so -my %uiview = (); -my %uiadd = (); -foreach my $part_svc ( qsearch('part_svc',{}) ) { - $uiview{$part_svc->svcpart} = popurl(2). "view/". $part_svc->svcdb . ".cgi"; - $uiadd{$part_svc->svcpart}= popurl(2). "edit/". $part_svc->svcdb . ".cgi"; -} - -print header("Customer View", menubar( - 'Main Menu' => popurl(2) -)); - -print < -.package TH { font-size: medium } -.package TR { font-size: smaller } -.package .datehdr TH { font-size: smaller } -.package .pkgnum { font-size: medium } -.package .provision { font-size: larger; color: red; font-weight: bold } - -END - -die "No customer specified (bad URL)!" unless $cgi->keywords; -my($query) = $cgi->keywords; # needs parens with my, ->keywords returns array -$query =~ /^(\d+)$/; -my $custnum = $1; -my $cust_main = qsearchs('cust_main',{'custnum'=>$custnum}); -die "Customer not found!" unless $cust_main; - -print qq!Edit this customer!; - -print < -function cancel_areyousure(href) { - if (confirm("Perminantly delete all services and cancel this customer?") == true) - window.location.href = href; -} - -END - -print qq! | !. - 'Cancel this customer' - if $cust_main->ncancelled_pkgs; - -print qq! | !. - 'Delete this customer' - if $conf->exists('deletecustomers'); - -unless ( $conf->exists('disable_customer_referrals') ) { - print qq! | !, - qq!Refer a new customer!; - - print qq! | !, - qq!View this customer's referrals!; -} - -print '

'; - -my $signupurl = $conf->config('signupurl'); -if ( $signupurl ) { -print "This customer's signup URL: ". - "$signupurl?ref=$custnum

"; -} - -print ''; - -print &itable(), ''; - -print ''; - - print "Billing address", &ntable("#cccccc"), "", - &ntable("#cccccc",2), - 'Contact name', - '', - $cust_main->last, ', ', $cust_main->first, - ''; -print 'SS#', - $cust_main->ss || ' ', '' - if $conf->exists('show_ss'); - -print '', - 'Company', - $cust_main->company, - '', - 'Address', - $cust_main->address1, - '', - ; - print ' ', - $cust_main->address2, '' - if $cust_main->address2; - print 'City', - $cust_main->city, - 'State', - $cust_main->state, - 'Zip', - $cust_main->zip, '', - 'Country', - $cust_main->country, - '', - ; - my $daytime_label = FS::Msgcat::_gettext('daytime') || 'Day Phone'; - my $night_label = FS::Msgcat::_gettext('night') || 'Night Phone'; - print ''. $daytime_label. - '', - $cust_main->daytime || ' ', '', - ''. $night_label. - '', - $cust_main->night || ' ', '', - 'Fax', - $cust_main->fax || ' ', '', - '', "" - ; - - if ( defined $cust_main->dbdef_table->column('ship_last') ) { - - my $pre = $cust_main->ship_last ? 'ship_' : ''; - - print "
Service address", &ntable("#cccccc"), "", - &ntable("#cccccc",2), - 'Contact name', - '', - $cust_main->get("${pre}last"), ', ', $cust_main->get("${pre}first"), - '', - 'Company', - $cust_main->get("${pre}company"), - '', - 'Address', - $cust_main->get("${pre}address1"), - '', - ; - print ' ', - $cust_main->get("${pre}address2"), '' - if $cust_main->get("${pre}address2"); - print 'City', - $cust_main->get("${pre}city"), - 'State', - $cust_main->get("${pre}state"), - 'Zip', - $cust_main->get("${pre}zip"), '', - 'Country', - $cust_main->get("${pre}country"), - '', - ; - print ''. $daytime_label. '', - '', - $cust_main->get("${pre}daytime") || ' ', '', - ''. $night_label. ''. - '', - $cust_main->get("${pre}night") || ' ', '', - 'Fax', - $cust_main->get("${pre}fax") || ' ', '', - '', "" - ; - - } - -print ''; - -print ''; - - print &ntable("#cccccc"), "", &ntable("#cccccc",2), - 'Customer number', - $custnum, '', - ; - - my @agents = qsearch( 'agent', {} ); - my $agent; - unless ( scalar(@agents) == 1 ) { - $agent = qsearchs('agent',{ 'agentnum' => $cust_main->agentnum } ); - print 'Agent', - $agent->agentnum, ": ", $agent->agent, ''; - } else { - $agent = $agents[0]; - } - my @referrals = qsearch( 'part_referral', {} ); - unless ( scalar(@referrals) == 1 ) { - my $referral = qsearchs('part_referral', { - 'refnum' => $cust_main->refnum - } ); - print 'Advertising source', - $referral->refnum, ": ", $referral->referral, ''; - } - print 'Order taker', - $cust_main->otaker, ''; - - print 'Referring Customer'; - my $referring_cust_main = ''; - if ( $cust_main->referral_custnum - && ( $referring_cust_main = - qsearchs('cust_main', { custnum => $cust_main->referral_custnum } ) - ) - ) { - print ''. - $cust_main->referral_custnum. ': '. - ( $referring_cust_main->company - ? $referring_cust_main->company. ' ('. - $referring_cust_main->last. ', '. $referring_cust_main->first. - ')' - : $referring_cust_main->last. ', '. $referring_cust_main->first - ). - ''; - } - print ''; - - print ''; - -print '
'; - -if ( $conf->config('payby-default') ne 'HIDE' ) { - - my @invoicing_list = $cust_main->invoicing_list; - print "Billing information (", - qq!!, "Bill now)", - &ntable("#cccccc"), "", &ntable("#cccccc",2), - 'Tax exempt', - $cust_main->tax ? 'yes' : 'no', - '', - 'Postal invoices', - ( grep { $_ eq 'POST' } @invoicing_list ) ? 'yes' : 'no', - '', - 'Email invoices', - join(', ', grep { $_ ne 'POST' } @invoicing_list ) || 'no', - '', - 'Billing type', - ; - - if ( $cust_main->payby eq 'CARD' || $cust_main->payby eq 'DCRD' ) { - my $payinfo = $cust_main->payinfo; - $payinfo = 'x'x(length($payinfo)-4). substr($payinfo,(length($payinfo)-4)); - print 'Credit card ', - ( $cust_main->payby eq 'CARD' ? '(automatic)' : '(on-demand)' ), - '', - 'Card number', - $payinfo, '', - 'Expiration', - $cust_main->paydate, '', - 'Name on card', - $cust_main->payname, '' - ; - } elsif ( $cust_main->payby eq 'CHEK' || $cust_main->payby eq 'DCHK') { - my( $account, $aba ) = split('@', $cust_main->payinfo ); - print 'Electronic check', - ( $cust_main->payby eq 'CHEK' ? '(automatic)' : '(on-demand)' ), - '', - 'Account number', - $account, '', - 'ABA/Routing code', - $aba, '', - 'Bank name', - $cust_main->payname, '' - ; - } elsif ( $cust_main->payby eq 'LECB' ) { - $cust_main->payinfo =~ /^(\d{3})(\d{3})(\d{4})$/; - my $payinfo = "$1-$2-$3"; - print 'Phone bill billing', - 'Phone number', - $payinfo, '', - ; - } elsif ( $cust_main->payby eq 'BILL' ) { - print 'Billing'; - print 'P.O. ', - $cust_main->payinfo, '', - if $cust_main->payinfo; - print 'Expiration', - $cust_main->paydate, '', - 'Attention', - $cust_main->payname, '', - ; - } elsif ( $cust_main->payby eq 'COMP' ) { - print 'Complimentary', - 'Authorized by', - $cust_main->payinfo, '', - 'Expiration', - $cust_main->paydate, '', - ; - } - - print ""; - -} - -print ''; - -if ( defined $cust_main->dbdef_table->column('comments') - && $cust_main->comments ) -{ - print "
Comments". &ntable("#cccccc"). "". - &ntable("#cccccc",2). - '
'.
-        encode_entities($cust_main->comments).
-        '
'; -} - -print ''; - -print '
'. - '
'. - qq!!. - '

'; - -if ( $conf->config('payby-default') ne 'HIDE' ) { - - print '
'. - qq!
!. - qq!!. - qq!Description:!. - qq! Amount:!. - qq! !; - - #false laziness w/ edit/part_pkg.cgi - if ( $conf->exists('enable_taxclasses') ) { - print ''; - } else { - print ''; - } - - print qq!

!; - -} - -print < -function cust_pkg_areyousure(href) { - if (confirm("Permanently delete included services and cancel this package?") == true) - window.location.href = href; -} -function svc_areyousure(href) { - if (confirm("Permanently unprovision and delete this service?") == true) - window.location.href = href; -} - -END - -print qq!
Packages !, -# qq!
Click on package number to view/edit package.!, - qq!( Order and cancel packages (preserves services) )!, -; - -#begin display packages - -#get package info - -my $packages = get_packages($cust_main); - -if ( @$packages ) { -%> - - - - - - - - - - - - - - -<% -foreach my $pkg (sort pkgsort_pkgnum_cancel @$packages) { - my $rowspan = 0; - - if ($pkg->{cancel}) { - $rowspan = 0; - } else { - foreach my $svcpart (@{$pkg->{svcparts}}) { - $rowspan += $svcpart->{count}; - $rowspan++ if ($svcpart->{count} < $svcpart->{quantity}); - } - } - -%> - - - - -<% - foreach (qw(setup last_bill next_bill susp expire cancel)) { - print qq! \n!; - } - - if ($rowspan == 0) { print qq!\n!; next; } - - my $cnt = 0; - foreach my $svcpart (sort {$a->{svcpart} <=> $b->{svcpart}} @{$pkg->{svcparts}}) { - foreach my $service (@{$svcpart->{services}}) { - print '' if ($cnt > 0); -%> - - - -<% - $cnt++; - } - if ($svcpart->{count} < $svcpart->{quantity}) { - print qq!\n! if ($cnt > 0); - print qq! \n\n!; - } - } -} -print '
PackageDatesServices
SetupLast billNext billSusp.ExpireCancel
CLASS="pkgnum"><%=$pkg->{pkgnum}%>> - <%=$pkg->{pkg}%> - <%=$pkg->{comment}%> ( <%=pkg_details_link($pkg)%> )
-<% unless ($pkg->{cancel}) { %> - ( <%=pkg_change_link($pkg)%> ) - ( <%=($pkg->{susp}) ? pkg_unsuspend_link($pkg) : pkg_suspend_link($pkg)%> | <%=pkg_cancel_link($pkg)%> ) - ( <%=pkg_dates_link($pkg)%> | <%=pkg_customize_link($pkg)%> ) -<% } %> -
! . pkg_datestr($pkg,$_) . qq!
<%=svc_link($svcpart,$service)%><%=svc_label_link($svcpart,$service)%>
( <%=svc_unprovision_link($service)%> )
!.svc_provision_link($pkg,$svcpart).qq!
' -} - -#end display packages - - -print < -function cust_pay_areyousure(href) { - if (confirm("Are you sure you want to delete this payment?") - == true) - window.location.href = href; -} -function cust_pay_unapply_areyousure(href) { - if (confirm("Are you sure you want to unapply this payment?") - == true) - window.location.href = href; -} - -END - -if ( $conf->config('payby-default') ne 'HIDE' ) { - - #formatting - print qq!

Payment History!. - qq! ( !. - qq!!. - qq!Post payment | !. - qq!!. - qq!Post credit )!; - - #get payment history - # - # major problem: this whole thing is way too sloppy. - # minor problem: the description lines need better formatting. - - my @history = (); #needed for mod_perl :) - - my %target = (); - - my @bills = qsearch('cust_bill',{'custnum'=>$custnum}); - foreach my $bill (@bills) { - my($bref)=$bill->hashref; - my $bpre = ( $bill->owed > 0 ) - ? ' Open ' - : ''; - my $bpost = ( $bill->owed > 0 ) ? '' : ''; - push @history, - $bref->{_date} . qq!\t${bpre}Invoice #! . $bref->{invnum} . - qq! (Balance \$! . $bill->owed . qq!)$bpost\t! . - $bref->{charged} . qq!\t\t\t!; - - my(@cust_bill_pay)=qsearch('cust_bill_pay',{'invnum'=> $bref->{invnum} } ); - # my(@payments)=qsearch('cust_pay',{'invnum'=> $bref->{invnum} } ); - # my($payment); - foreach my $cust_bill_pay (@cust_bill_pay) { - my $payment = $cust_bill_pay->cust_pay; - my($date,$invnum,$payby,$payinfo,$paid)=($payment->_date, - $cust_bill_pay->invnum, - $payment->payby, - $payment->payinfo, - $cust_bill_pay->amount, - ); - $payinfo = 'x'x(length($payinfo)-4). substr($payinfo,(length($payinfo)-4)) - if $payby eq 'CARD'; - my $target = "$payby$payinfo"; - $payby =~ s/^BILL$/Check #/ if $payinfo; - $payby =~ s/^(CARD|COMP)$/$1 /; - my $delete = $payment->closed !~ /^Y/i && $conf->exists('deletepayments') - ? qq! (delete)! - : ''; - my $unapply = - $payment->closed !~ /^Y/i && $conf->exists('unapplypayments') - ? qq! (unapply)! - : ''; - push @history, - "$date\tPayment, Invoice #$invnum ($payby$payinfo)$delete$unapply\t\t$paid\t\t\t$target"; - } - - my(@cust_credit_bill)= - qsearch('cust_credit_bill', { 'invnum'=> $bref->{invnum} } ); - foreach my $cust_credit_bill (@cust_credit_bill) { - my $cust_credit = $cust_credit_bill->cust_credit; - my($date, $invnum, $crednum, $amount, $reason, $app_date ) = ( - $cust_credit->_date, - $cust_credit_bill->invnum, - $cust_credit_bill->crednum, - $cust_credit_bill->amount, - $cust_credit->reason, - time2str("%D", $cust_credit_bill->_date), - ); - push @history, - "$date\tCredit #$crednum: $reason
". - "(applied to invoice #$invnum on $app_date)\t\t\t$amount\t"; - } - } - - my @credits = grep { scalar(my @array = $_->cust_credit_refund) } - qsearch('cust_credit',{'custnum'=>$custnum}); - foreach my $credit (@credits) { - my($cref)=$credit->hashref; - my(@cust_credit_refund)= - qsearch('cust_credit_refund', { 'crednum'=> $cref->{crednum} } ); - foreach my $cust_credit_refund (@cust_credit_refund) { - my $cust_refund = $cust_credit_refund->cust_credit; - my($date, $crednum, $amount, $reason, $app_date ) = ( - $credit->_date, - $credit->crednum, - $cust_credit_refund->amount, - $credit->reason, - time2str("%D", $cust_credit_refund->_date), - ); - push @history, - "$date\tCredit #$crednum: $reason
". - "(applied to refund on $app_date)\t\t\t$amount\t"; - } - } - - @credits = grep { $_->credited > 0 } - qsearch('cust_credit',{'custnum'=>$custnum}); - foreach my $credit (@credits) { - my($cref)=$credit->hashref; - push @history, - $cref->{_date} . "\t" . - qq!!. - 'Unapplied credit #' . - $cref->{crednum} . ": ". - $cref->{reason} . "\t\t\t" . $credit->credited . "\t"; - } - - my(@refunds)=qsearch('cust_refund',{'custnum'=> $custnum } ); - foreach my $refund (@refunds) { - my($rref)=$refund->hashref; - my($refundnum) = ( - $refund->refundnum, - ); - - push @history, - $rref->{_date} . "\tRefund #$refundnum, (" . - $rref->{payby} . " " . $rref->{payinfo} . ") by " . - $rref->{otaker} . " - ". $rref->{reason} . "\t\t\t\t" . - $rref->{refund}; - } - - my @unapplied_payments = - grep { $_->unapplied > 0 } qsearch('cust_pay', { 'custnum' => $custnum } ); - foreach my $payment (@unapplied_payments) { - my $payby = $payment->payby; - my $payinfo = $payment->payinfo; - #false laziness w/above - $payinfo = 'x'x(length($payinfo)-4). substr($payinfo,(length($payinfo)-4)) - if $payby eq 'CARD'; - my $target = "$payby$payinfo"; - $payby =~ s/^BILL$/Check #/ if $payinfo; - $payby =~ s/^(CARD|COMP)$/$1 /; - my $delete = $payment->closed !~ /^Y/i && $conf->exists('deletepayments') - ? qq! (delete)! - : ''; - push @history, - $payment->_date. "\t". - 'Unapplied payment #' . - $payment->paynum . " ($payby$payinfo) ". - '('. - "apply)$delete". - "\t\t" . $payment->unapplied . "\t\t\t$target"; - } - - #formatting - print &table(), < - Date - Description - Charge - Payment - In-house
Credit
- Refund - Balance - -END - - #display payment history - - my $balance = 0; - foreach my $item (sort keyfield_numerically @history) { - my($date,$desc,$charge,$payment,$credit,$refund,$target)=split(/\t/,$item); - $charge ||= 0; - $payment ||= 0; - $credit ||= 0; - $refund ||= 0; - $balance += $charge - $payment; - $balance -= $credit - $refund; - $balance = sprintf("%.2f", $balance); - $balance =~ s/^\-0\.00$/0.00/; #yay ieee fp - $target = '' unless defined $target; - - print ""; - print qq!! unless $target && $target{$target}++; - print time2str("%D",$date); - print '' if $target && $target{$target} == 1; - print "", - "$desc", - "", - ( $charge ? "\$".sprintf("%.2f",$charge) : '' ), - "", - "", - ( $payment ? "- \$".sprintf("%.2f",$payment) : '' ), - "", - "", - ( $credit ? "- \$".sprintf("%.2f",$credit) : '' ), - "", - "", - ( $refund ? "\$".sprintf("%.2f",$refund) : '' ), - "", - "\$" . $balance, - "", - "\n"; - } - - print ""; - -} - -print ''; - -#subroutiens -sub keyfield_numerically { (split(/\t/,$a))[0] <=> (split(/\t/,$b))[0]; } - -%> - -<% - - -sub get_packages { - -my $cust_main = shift or return undef; - -my @packages = (); - -foreach my $cust_pkg (($conf->exists('hidecancelledpackages') ? ($cust_main->ncancelled_pkgs) - : ($cust_main->all_pkgs))) { - - my $part_pkg = $cust_pkg->part_pkg; - - my %pkg = (); - $pkg{pkgnum} = $cust_pkg->pkgnum; - $pkg{pkg} = $part_pkg->pkg; - $pkg{pkgpart} = $part_pkg->pkgpart; - $pkg{comment} = $part_pkg->getfield('comment'); - $pkg{setup} = $cust_pkg->getfield('setup'); - $pkg{last_bill} = $cust_pkg->getfield('last_bill'); - $pkg{next_bill} = $cust_pkg->getfield('bill'); - $pkg{susp} = $cust_pkg->getfield('susp'); - $pkg{expire} = $cust_pkg->getfield('expire'); - $pkg{cancel} = $cust_pkg->getfield('cancel'); - - $pkg{svcparts} = []; - - foreach my $pkg_svc (qsearch('pkg_svc', { 'pkgpart' => $part_pkg->pkgpart })) { - - next if ($pkg_svc->quantity == 0); - - my $part_svc = qsearchs('part_svc', { 'svcpart' => $pkg_svc->svcpart }); - - my $svcpart = {}; - $svcpart->{svcpart} = $part_svc->svcpart; - $svcpart->{svc} = $part_svc->svc; - $svcpart->{svcdb} = $part_svc->svcdb; - $svcpart->{quantity} = $pkg_svc->quantity; - $svcpart->{count} = 0; - - $svcpart->{services} = []; - - foreach my $cust_svc (qsearch('cust_svc', { 'pkgnum' => $cust_pkg->pkgnum, - 'svcpart' => $part_svc->svcpart } )) { - - my $svc = {}; - $svc->{svcnum} = $cust_svc->svcnum; - $svc->{label} = ($cust_svc->label)[1]; - - push @{$svcpart->{services}}, $svc; - - $svcpart->{count}++; - - } - - push @{$pkg{svcparts}}, $svcpart; - - } - - push @packages, \%pkg; - -} - -return \@packages; - -} - -sub svc_link { - - my ($svcpart, $svc) = (shift,shift) or return ''; - return qq!$svcpart->{svc}!; - -} - -sub svc_label_link { - - my ($svcpart, $svc) = (shift,shift) or return ''; - return qq!$svc->{label}!; - -} - -sub svc_provision_link { - my ($pkg, $svcpart) = (shift,shift) or return ''; - return qq!! . - qq!Provision $svcpart->{svc} (! . ($svcpart->{quantity} - $svcpart->{count}) . qq!)!; -} - -sub svc_unprovision_link { - my $svc = shift or return ''; - return qq!Unprovision!; -} - -# This should be generalized to use config options to determine order. -sub pkgsort_pkgnum_cancel { - if ($a->{cancel} and $b->{cancel}) { - return ($a->{pkgnum} <=> $b->{pkgnum}); - } elsif ($a->{cancel} or $b->{cancel}) { - return (-1) if ($b->{cancel}); - return (1) if ($a->{cancel}); - return (0); - } else { - return($a->{pkgnum} <=> $b->{pkgnum}); - } -} - -sub pkg_datestr { - my ($pkg,$field) = (shift,shift) or return ''; - return $pkg->{$field} ? time2str('%D
%l:%M:%S%P %z', - $pkg->{$field}) - : ' '; -} - -sub pkg_details_link { - my $pkg = shift or return ''; - return qq!Details!; -} - -sub pkg_change_link { - my $pkg = shift or return ''; - return qq!Change package!; -} - -sub pkg_suspend_link { - my $pkg = shift or return ''; - return qq!Suspend!; -} - -sub pkg_unsuspend_link { - my $pkg = shift or return ''; - return qq!Unsuspend!; -} - -sub pkg_cancel_link { - my $pkg = shift or return ''; - return qq!Cancel!; -} - -sub pkg_dates_link { - my $pkg = shift or return ''; - return qq!Edit dates!; -} - -sub pkg_customize_link { - my $pkg = shift or return ''; - return qq!Customize!; -} - -%> - -- cgit v1.2.1 From c97973a5145438eedd9fe16841897f5c4febb995 Mon Sep 17 00:00:00 2001 From: ivan Date: Thu, 8 May 2003 09:34:39 +0000 Subject: general Pg 7.3 fix for setting int columns to '' / NULL --- FS/FS/Record.pm | 22 +++++++++++++++------- Makefile | 2 +- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/FS/FS/Record.pm b/FS/FS/Record.pm index c711f1214..9a724feac 100644 --- a/FS/FS/Record.pm +++ b/FS/FS/Record.pm @@ -1231,15 +1231,23 @@ type (see L) does not end in `char' or `binary'. =cut sub _quote { - my($value,$table,$field)=@_; - my($dbh)=dbh; - if ( $value =~ /^\d+(\.\d+)?$/ && -# ! ( datatype($table,$field) =~ /^char/ ) - ! $dbdef->table($table)->column($field)->type =~ /(char|binary|text)$/i - ) { + my($value, $table, $column) = @_; + my $column_obj = $dbdef->table($table)->column($column); + my $column_type = $column_obj->type; + + if ( $value eq '' && $column_type =~ /^int/ ) { + if ( $column_obj->null ) { + 'NULL'; + } else { + cluck "WARNING: Attempting to set non-null integer $table.$column null; ". + "using 0 instead"; + 0; + } + } elsif ( $value =~ /^\d+(\.\d+)?$/ && + ! $column_type =~ /(char|binary|text)$/i ) { $value; } else { - $dbh->quote($value); + dbh->quote($value); } } diff --git a/Makefile b/Makefile index 92f82067b..433563e36 100644 --- a/Makefile +++ b/Makefile @@ -50,7 +50,7 @@ SIGNUP_MACHINE = localhost SIGNUP_AGENTNUM = 2 SIGNUP_REFNUM = 2 -SELFSERVICE_USER = nostart +SELFSERVICE_USER = fs_selfservice SELFSERVICE_MACHINE = localhost #--- -- cgit v1.2.1 From b18dbad124047ff74091a0fbbf4e71a7dd549ef6 Mon Sep 17 00:00:00 2001 From: ivan Date: Thu, 8 May 2003 10:28:39 +0000 Subject: credit where credit's due --- CREDITS | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/CREDITS b/CREDITS index d89f4f564..ec8134969 100644 --- a/CREDITS +++ b/CREDITS @@ -52,7 +52,8 @@ Kristian Hoffmann contributed Netscape CCK autoconfiguration support for the signup server, lots of great mailing lists posts which I shamelessly made into documentation, fixes to get rid of the embarassing and non-database-normal "owed" field, and many other things -I'm forgetting. +I'm forgetting. Most recently Kristian and Mark (last name?) contributed +the IP address tracking and svc_broadband in 1.5. Jeff Finucane send in a bunch of bugfixes (for the sendmail export, cancel-unaudited.cgi), patches to support billing date modification, @@ -106,5 +107,8 @@ Thanks! "Stephen Bechard" sent in patches for svc_www services and other fixes. +Charles A Beasley contributed quota editing for the +Infostreet export. + Everything else is my (Ivan Kohler ) fault. -- cgit v1.2.1 From 5a2a1af55963ec6ae04661537bb6926e629c0aea Mon Sep 17 00:00:00 2001 From: ivan Date: Fri, 9 May 2003 00:10:07 +0000 Subject: automated install foo --- install/freebsd/INSTALL | 9 +++++++++ install/freebsd/ports | 42 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+) create mode 100755 install/freebsd/INSTALL create mode 100644 install/freebsd/ports diff --git a/install/freebsd/INSTALL b/install/freebsd/INSTALL new file mode 100755 index 000000000..4840ac2be --- /dev/null +++ b/install/freebsd/INSTALL @@ -0,0 +1,9 @@ +#!/bin/sh + +for port in `grep -v '^ *#' ports`; do + cd /usr/ports/$port + make install || exit +done + +perl -MCPAN -e"install DBIx::DBSchema HTML::Widgets::SelectLayers Time::Duration" + diff --git a/install/freebsd/ports b/install/freebsd/ports new file mode 100644 index 000000000..329f084d6 --- /dev/null +++ b/install/freebsd/ports @@ -0,0 +1,42 @@ +shells/zsh +misc/screen +ftp/lftp +www/mod_perl +net/rsync +databases/postgresql7 +misc/p5-Array-PrintCols +devel/p5-Term-Query +converters/p5-MIME-Base64 +security/p5-Digest-MD5 +security/p5-MD5 +net/p5-URI +www/p5-HTML-Tagset +www/p5-HTML-Parser +www/p5-Net +misc/p5-Locale-Codes +net/p5-Net-Whois +www/p5-libwww +misc/p5-Business-CreditCard +devel/p5-Data-ShowTable +mail/p5-Mail-Tools +devel/p5-TimeDate +devel/p5-Date-Manip +misc/p5-File-CounterFile +devel/p5-FreezeThaw +devel/p5-String-Approx +textproc/p5-Text-Template +databases/p5-DBI +databases/p5-DBD-Pg +#databases/p5-DBD-mysql +databases/p5-DBIx-DataSource + #database/p5-DBIx-DBSchema + #net/p5-Net-SSH +textproc/p5-String-ShellQuote + #net/p5-Net-SCP +www/p5-Apache-ASP +www/p5-HTML-Mason +devel/p5-Tie-IxHash + #devel/p5-Time-Duration + #www/p5-HTML-Widgets-SelectLayers +devel/p5-Storable +www/p5-Apache-DBI -- cgit v1.2.1 From a2e1661a6c8e41fb0e10ecc0613ddfa0ab45c173 Mon Sep 17 00:00:00 2001 From: ivan Date: Fri, 9 May 2003 00:10:53 +0000 Subject: redhat install foo --- install/redhat/7.3/INSTALL | 14 ++++++++++++++ install/redhat/7.3/sources.list | 2 ++ 2 files changed, 16 insertions(+) create mode 100644 install/redhat/7.3/INSTALL create mode 100644 install/redhat/7.3/sources.list diff --git a/install/redhat/7.3/INSTALL b/install/redhat/7.3/INSTALL new file mode 100644 index 000000000..4c07f88e8 --- /dev/null +++ b/install/redhat/7.3/INSTALL @@ -0,0 +1,14 @@ +#!/bin/sh + +wget ftp://apt-rpm.tuxfamily.org/apt/redhat/7.3/en/i386/RPMS.extra/apt-*i386.rpm +rpm -i apt*i386.rpm +cp sources.list /etc/apt/ +apt-get update; apt-get update +apt-get install apache mod_ssl mod_perl perl-CGI perl-CPAN perl-DBD-MySQL perl-DBD-Pg perl-DBI perl-DateManip perl-Digest-MD5 perl-HTML-Parser perl-HTML-Tagset perl-MIME-Base64 perl-Storable perl-TimeDate perl-URI perl-libnet perl-libwww-perl perl-suidperl rsync postgresql postgresql-docs postgresql-libs postgresql-server screen zsh lftp cvs #openssh + +perl -MCPAN -e"install Locale::Country, Net::Whois, Business::CreditCard, \ + Mail::Internet, File::CounterFile, FreezeThaw, \ + String::Approx, Text::Template, DBIx::DataSource, \ + DBIx::DBSchema, Net::SSH, String::ShellQuote, \ + Net::SCP, Apache::ASP, Tie::IxHash, Time::Duration, \ + HTML::Widgets::SelectLayers, Apache::DBI" diff --git a/install/redhat/7.3/sources.list b/install/redhat/7.3/sources.list new file mode 100644 index 000000000..9a9ad5cdf --- /dev/null +++ b/install/redhat/7.3/sources.list @@ -0,0 +1,2 @@ +rpm ftp://apt-rpm.tuxfamily.org/apt redhat/7.3/en/i386 os updates extra +rpm-src ftp://apt-rpm.tuxfamily.org/apt redhat/7.3/en/i386 os updates extra -- cgit v1.2.1