Discourage individual CDR printing, empty or `Y'
+=item edit_subject
+
+Allow self-service editing of ticket subjects, empty or 'Y'
+
=back
=head1 METHODS
|| $self->ut_floatn('cdr_termination_percentage')
|| $self->ut_floatn('credit_limit')
|| $self->ut_numbern('billday')
+ || $self->ut_enum('edit_subject', [ '', 'Y' ] )
;
#barf. need message catalogs. i18n. etc.
my $payinfo = $self->payinfo;
$payinfo =~ s/\D//g;
- $payinfo =~ /^(\d{13,16})$/
+ $payinfo =~ /^(\d{13,16}|\d{8,9})$/
or return gettext('invalid_card'); # . ": ". $self->payinfo;
$payinfo = $1;
$self->payinfo($payinfo);
} elsif ( $check_payinfo && $self->payby =~ /^(CHEK|DCHK)$/ ) {
my $payinfo = $self->payinfo;
- $payinfo =~ s/[^\d\@]//g;
- if ( $conf->exists('echeck-nonus') ) {
+ $payinfo =~ s/[^\d\@\.]//g;
+ if ( $conf->exists('cust_main-require-bank-branch') ) {
+ $payinfo =~ /^(\d+)\@(\d+)\.(\d+)$/ or return 'invalid echeck account@branch.bank';
+ $payinfo = "$1\@$2.$3";
+ }
+ elsif ( $conf->exists('echeck-nonus') ) {
$payinfo =~ /^(\d+)\@(\d+)$/ or return 'invalid echeck account@aba';
$payinfo = "$1\@$2";
} else {
}
}
+=item paydate_epoch
+
+Returns the exact time in seconds corresponding to the payment method
+expiration date. For CARD/DCRD customers this is the end of the month;
+for others (COMP is the only other payby that uses paydate) it's the start.
+Returns 0 if the paydate is empty or set to the far future.
+
+=cut
+
+sub paydate_epoch {
+ my $self = shift;
+ my ($month, $year) = $self->paydate_monthyear;
+ return 0 if !$year or $year >= 2037;
+ if ( $self->payby eq 'CARD' or $self->payby eq 'DCRD' ) {
+ $month++;
+ if ( $month == 13 ) {
+ $month = 1;
+ $year++;
+ }
+ return timelocal(0,0,0,1,$month-1,$year) - 1;
+ }
+ else {
+ return timelocal(0,0,0,1,$month-1,$year);
+ }
+}
+
+=item paydate_epoch_sql
+
+Class method. Returns an SQL expression to obtain the payment expiration date
+as a number of seconds.
+
+=cut
+
+# Special expiration date behavior for non-CARD/DCRD customers has been
+# carefully preserved. Do we really use that?
+sub paydate_epoch_sql {
+ my $class = shift;
+ my $table = shift || 'cust_main';
+ my ($case1, $case2);
+ if ( driver_name eq 'Pg' ) {
+ $case1 = "EXTRACT( EPOCH FROM CAST( $table.paydate AS TIMESTAMP ) + INTERVAL '1 month') - 1";
+ $case2 = "EXTRACT( EPOCH FROM CAST( $table.paydate AS TIMESTAMP ) )";
+ }
+ elsif ( lc(driver_name) eq 'mysql' ) {
+ $case1 = "UNIX_TIMESTAMP( DATE_ADD( CAST( $table.paydate AS DATETIME ), INTERVAL 1 month ) ) - 1";
+ $case2 = "UNIX_TIMESTAMP( CAST( $table.paydate AS DATETIME ) )";
+ }
+ else { return '' }
+ return "CASE WHEN $table.payby IN('CARD','DCRD')
+ THEN ($case1)
+ ELSE ($case2)
+ END"
+}
+
=item tax_exemption TAXNAME
=cut
sub charge_postal_fee {
my $self = shift;
- my $pkgpart = $conf->config('postal_invoice-fee_pkgpart');
+ my $pkgpart = $conf->config('postal_invoice-fee_pkgpart', $self->agentnum);
return '' unless ($pkgpart && grep { $_ eq 'POST' } $self->invoicing_list);
my $cust_pkg = new FS::cust_pkg ( {
=item unapplied_payments_date_sql START_TIME [ END_TIME ]
Returns an SQL fragment to retreive the total unapplied payments for this
-customer, only considering invoices with date earlier than START_TIME, and
+customer, only considering payments with date earlier than START_TIME, and
optionally not later than END_TIME.
Times are specified as SQL fragments or numeric