}
foreach my $table (qw( cust_main_invoice cust_main_exemption cust_tag )) {
- foreach my $record ( qsearch( 'table', { 'custnum' => $self->custnum } ) ) {
+ foreach my $record ( qsearch( $table, { 'custnum' => $self->custnum } ) ) {
my $error = $record->delete;
if ( $error ) {
$dbh->rollback if $oldAutoCommit;
my $msgnum = $conf->config('decline_msgnum', $self->agentnum);
my $error = '';
if ( $msgnum ) {
+ # include the raw error message in the transaction state
+ $cust_pay_pending->setfield('error', $transaction->error_message);
my $msg_template = qsearchs('msg_template', { msgnum => $msgnum });
- $error = $msg_template->send( 'cust_main' => $self );
+ $error = $msg_template->send( 'cust_main' => $self,
+ 'object' => $cust_pay_pending );
}
else { #!$msgnum
my $self = shift;
my $sql = 'SELECT SUM('. $self->balance_date_sql(@_).
') FROM cust_main WHERE custnum='. $self->custnum;
- sprintf( "%.2f", $self->scalar_sql($sql) );
+ sprintf( '%.2f', $self->scalar_sql($sql) );
}
=item balance_pkgnum PKGNUM
);
}
+=item cust_pay_pending_attempt
+
+Returns all payment attempts / declined payments for this customer, as pending
+payments objects (see L<FS::cust_pay_pending>), with status "done" but without
+a corresponding payment (see L<FS::cust_pay>).
+
+=cut
+
+sub cust_pay_pending_attempt {
+ my $self = shift;
+ return $self->num_cust_pay_pending_attempt unless wantarray;
+ sort { $a->_date <=> $b->_date }
+ qsearch( 'cust_pay_pending', {
+ 'custnum' => $self->custnum,
+ 'status' => 'done',
+ 'paynum' => '',
+ },
+ );
+}
+
=item num_cust_pay_pending
Returns the number of pending payments (see L<FS::cust_pay_pending>) for this
sub num_cust_pay_pending {
my $self = shift;
- my $sql = " SELECT COUNT(*) FROM cust_pay_pending ".
- " WHERE custnum = ? AND status != 'done' ";
- my $sth = dbh->prepare($sql) or die dbh->errstr;
- $sth->execute($self->custnum) or die $sth->errstr;
- $sth->fetchrow_arrayref->[0];
+ $self->scalar_sql(
+ " SELECT COUNT(*) FROM cust_pay_pending ".
+ " WHERE custnum = ? AND status != 'done' ",
+ $self->custnum
+ );
+}
+
+=item num_cust_pay_pending_attempt
+
+Returns the number of pending payments (see L<FS::cust_pay_pending>) for this
+customer, with status "done" but without a corresp. Also called automatically when the
+cust_pay_pending method is used in a scalar context.
+
+=cut
+
+sub num_cust_pay_pending_attempt {
+ my $self = shift;
+ $self->scalar_sql(
+ " SELECT COUNT(*) FROM cust_pay_pending ".
+ " WHERE custnum = ? AND status = 'done' AND paynum IS NULL",
+ $self->custnum
+ );
}
=item cust_refund
=cut
+# a lot like cust_bill::print_latex
sub generate_letter {
my ($self, $template, %options) = @_;
$letter_data{company_name} = $conf->config('company_name', $self->agentnum);
my $dir = $FS::UID::conf_dir."/cache.". $FS::UID::datasrc;
+
+ my $lh = new File::Temp( TEMPLATE => 'letter.'. $self->custnum. '.XXXXXXXX',
+ DIR => $dir,
+ SUFFIX => '.eps',
+ UNLINK => 0,
+ ) or die "can't open temp file: $!\n";
+ print $lh $conf->config_binary('logo.eps', $self->agentnum)
+ or die "can't write temp file: $!\n";
+ close $lh;
+ $letter_data{'logo_file'} = $lh->filename;
+
my $fh = new File::Temp( TEMPLATE => 'letter.'. $self->custnum. '.XXXXXXXX',
DIR => $dir,
SUFFIX => '.tex',
$letter_template->fill_in( OUTPUT => $fh, HASH => \%letter_data );
close $fh;
$fh->filename =~ /^(.*).tex$/ or die "unparsable filename: ". $fh->filename;
- return $1;
+ return ($1, $letter_data{'logo_file'});
+
}
=item print_ps TEMPLATE
sub print_ps {
my $self = shift;
- my $file = $self->generate_letter(@_);
- FS::Misc::generate_ps($file);
+ my($file, $lfile) = $self->generate_letter(@_);
+ my $ps = FS::Misc::generate_ps($file);
+ unlink($file.'.tex');
+ unlink($lfile);
+
+ $ps;
}
=item print TEMPLATE