MT#5879 Send invoices via email.

Text of the message should be conformed with sales. Also it would be nice to apply templates to email body.
Only smarthost is working, spent 3 hours with exim debug and while left with smarthost. Attachments and so one looks good.
Removed fake data.
Fix data parameter. Tested data and client contracts.
ipeshinskaya/InvoiceTemplate5
Irina Peshinskaya 11 years ago committed by Victor Seva
parent bde7cc02e6
commit 1fd67eb308

@ -47,6 +47,8 @@ my $builder = Local::Module::Build->new(
'DateTime::Format::ISO8601' => 0,
'DateTime::Format::RFC3339' => 0,
'DBIx::Class::ResultSet::RecursiveUpdate' => '0.30',
'Email::Sender::Simple' => 0,
'Email::Sender::Transport::SMTP' => 0,
'Email::Valid' => 0,
'File::ShareDir' => 0,
'File::Type' => 0,

6
debian/control vendored

@ -25,8 +25,7 @@ Build-Depends: debhelper (>= 8),
libdatetime-format-rfc3339-perl,
libdbix-class-resultset-recursiveupdate-perl (>= 0.30~),
libdevel-cover-perl,
libemail-mime-perl,
libemail-send-perl,
libemail-sender-perl,
libfile-spec-perl (>= 3.4000~),
libfile-type-perl,
libgd-gd2-perl,
@ -100,8 +99,7 @@ Depends: gettext,
libdatetime-perl,
libdbix-class-resultset-recursiveupdate-perl (>= 0.30~),
libdigest-sha3-perl,
libemail-mime-perl,
libemail-send-perl,
libemail-sender-perl,
libemail-valid-perl,
libfcgi-procmanager-perl,
libfile-spec-perl (>= 3.4000~),

@ -157,10 +157,15 @@ sub invoice_list :Chained('invoice_details_calls') :PathPart('list') :Args(0) {
my $backend = NGCP::Panel::Model::DB::InvoiceTemplate->new( schema => $c->model('DB') );
$c->forward( 'template_list_data' );
my $provider_id = $c->stash->{provider}->id;
my $invoice_list = $backend->getProviderInvoiceList(
provider_id => $provider_id,
);
$c->stash(
client_contacts_list => $backend->getInvoiceProviderClients( provider_id => $provider_id ),
invoice_list => [$invoice_list->all],
template => 'invoice/list.tt',
);
#$c->detach( $c->view() );
}
sub template_base :Chained('base') :PathPart('template') :CaptureArgs(0) {

@ -227,7 +227,22 @@ sub getInvoiceClientContactInfo{
reseller_id => $client_id,
});
}
sub getProviderInvoiceList{
my $self = shift;
my (%params) = @_;
my ($provider_reseller_id,$stime,$etime) = @params{qw/provider_id stime etime/};
$stime ||= NGCP::Panel::Utils::DateTime::current_local()->truncate( to => 'month' );
$etime ||= $stime->clone->add( months => 1);
$self->schema->resultset('contacts')->search_rs({
'-and' =>
[
'reseller_id' => $provider_reseller_id, #$client_contract_id - contract of the client
],
},{
'+select' => ['contract_balances.invoice_id','contract_balances.start','contract_balances.end'],
'join' => [{ 'contracts' => {'contract_balances' => 'invoice' }}]
});
}
sub getInvoiceProviderClients{
my $self = shift;
my (%params) = @_;

@ -14,7 +14,7 @@
<a class="btn btn-primary btn-large" href="[% c.uri_for('/back') %]"><i class="icon-arrow-left"></i> [% c.loc('Back') %]</a>
</span>
<span>
<a class="btn btn-primary btn-large" href="[% c.uri_for_action('invoice/template', [reseller.first.id]) %]">[% c.loc('Invoice Template')%] <i class="icon-edit"></i></a>
<a class="btn btn-primary btn-large" href="[% c.uri_for_action('invoice/template', [provider.id]) %]">[% c.loc('Invoice Template')%] <i class="icon-edit"></i></a>
</span>
</div>
@ -30,8 +30,20 @@
[% back_created = 1 -%]
<div class="accordion" id="invoice">
<div class="accordion-group">
<div class="accordion-heading">
<a class="accordion-toggle" data-toggle="collapse" data-parent="#invoice" href="#collapse_invoice_list">[% c.loc('Invoices') %]</a>
</div>
<div class="accordion-body collapse" id="collapse_invoice_list">
<div class="accordion-inner" style="overflow:auto; height: 300px;">
</div>
</div>
</div>
<!--div class="accordion-group">
<div class="accordion-heading">
<a class="accordion-toggle" data-toggle="collapse" data-parent="#customer_invoice" href="#collapse_invoice_details_zones">[% c.loc('Invoice Connection Fees') %]</a>
</div>
@ -107,7 +119,7 @@ oTable.fnClose();
</div>
</div>
</div>
</div-->
</div>

@ -7,6 +7,19 @@ use DBI;
use Data::Dumper;
use DateTime::TimeZone;
use Test::MockObject;
use Email::MIME;
use Email::Sender::Simple qw(sendmail);
use Email::Sender::Transport::SMTP;
#use IO::All;
#apt-get install libemail-send-perl
#apt-get install libemail-sender-perl
#apt-get install libtest-mockobject-perl
#apt-get install libnet-smtp-ssl-perl
#apt-get install libio-all-perl
use Sipwise::Base;
@ -39,6 +52,22 @@ print "using user '$dbuser' with pass '$dbpass'\n"
my $dbh = DBI->connect('dbi:mysql:billing;host=localhost', $dbuser, $dbpass)
or die "failed to connect to billing DB\n";
my $email_transport = Email::Sender::Transport::SMTP->new({
sasl_username => 'ipeshinskaya',
#host => 'mail.sipwise.com',
#port => 587,
#sasl_password => 'KfC4pXuV',
#ssl => 0,
host => 'smtp.googlemail.com',
port => 465,
ssl => 1,
sasl_password => '',
});
my $c_mock = Test::MockObject->new();
$c_mock->set_false(qw/debug/);
my $view = NGCP::Panel::View::SVG->new($c_mock,{});
@ -57,10 +86,11 @@ NGCP::Panel::Utils::InvoiceTemplate::preprocessInvoiceTemplateSvg( {no_fake_data
foreach my $provider_contract( @{$dbh->selectall_arrayref('select contracts.*,resellers.id as reseller_core_id from resellers inner join contracts on resellers.contract_id=contracts.id where resellers.status != "terminated"'.ify('and resellers.id', @{$opt->{reseller_id}}), { Slice => {} }, @{$opt->{reseller_id}} ) } ){
my $provider_contact = $dbh->selectrow_hashref('select * from contacts where id=?', undef, $provider_contract->{contact_id} );
#according to /reseller/ajax_reseller_filter
foreach my $client_contact (@{ $dbh->selectall_arrayref('select contacts.* from contacts where reseller_id = ?'.ify(' and contacts.id', @{$opt->{client_contact_id}}), { Slice => {} }, $provider_contract->{reseller_core_id}, @{$opt->{client_contact_id}} ) } ){
my $client_contract = $dbh->selectrow_hashref('select contracts.* from contracts where contracts.contact_id=? ', undef, $client_contact->{id} );
if( my $billing_profile = $dbh->selectrow_hashref('select billing_profiles.*
if( my $billing_profile = $dbh->selectrow_hashref('select distinct billing_profiles.*
from billing_mappings
inner join billing_profiles on billing_mappings.billing_profile_id=billing_profiles.id
inner join contracts on contracts.id=billing_mappings.contract_id
@ -70,7 +100,7 @@ foreach my $provider_contract( @{$dbh->selectall_arrayref('select contracts.*,re
and contracts.contact_id=?
and (billing_mappings.start_date <= ? OR billing_mappings.start_date IS NULL)
and (billing_mappings.end_date >= ? OR billing_mappings.end_date IS NULL)'
, undef, $client_contract->{id}, $etime->epoch, $stime->epoch
, undef, $client_contact->{id}, $etime->epoch, $stime->epoch
) ){
my ($contract_balance,$invoice)=({},{});
($contract_balance,$invoice) = get_contract_balance($client_contract,$billing_profile,$contract_balance,$invoice,$stime,$etime);
@ -81,13 +111,13 @@ foreach my $provider_contract( @{$dbh->selectall_arrayref('select contracts.*,re
where
cdr.source_user_id != 0
and cdr.call_status="ok"
-- and cdr.source_account_id=?
-- and cdr.start_time >= ?
-- and cdr.start_time <= ?
and cdr.source_account_id=?
and cdr.start_time >= ?
and cdr.start_time <= ?
order by cdr.start_time
limit 25'
-- limit 25'
, { Slice => {} }
#, $client_contract->{id},$stime->epoch,$etime->epoch
, $client_contract->{id},$stime->epoch,$etime->epoch
);
my $invoice_details_zones = $dbh->selectall_arrayref('select SUM(cdr.source_customer_cost) AS cost, COUNT(*) AS number, SUM(cdr.duration) AS duration,sum(cdr.source_customer_free_time) as free_time, bzh.zone
from accounting.cdr
@ -95,13 +125,13 @@ foreach my $provider_contract( @{$dbh->selectall_arrayref('select contracts.*,re
where
cdr.source_user_id != 0
and cdr.call_status="ok"
-- and cdr.source_account_id=?
-- and cdr.start_time >= ?
-- and cdr.start_time <= ?
and cdr.source_account_id=?
and cdr.start_time >= ?
and cdr.start_time <= ?
group by bzh.zone
order by bzh.zone'
, {Slice => {} }
#, $client_contract->{id},$stime->epoch,$etime->epoch
, $client_contract->{id},$stime->epoch,$etime->epoch
);
my $i = 1;
$invoice_details_calls = [map{[$i++,$_]} (@$invoice_details_calls) x 1];
@ -141,6 +171,7 @@ foreach my $provider_contract( @{$dbh->selectall_arrayref('select contracts.*,re
#print $out->{tt_string_pdf};
#die;
$dbh->do('update invoices set data=? where id=?',undef,$out->{tt_string_pdf},$invoice->{id});
email($provider_contact,$client_contact,$invoice,\$out->{tt_string_pdf});
}
}
}
@ -178,8 +209,43 @@ sub ify{
return ( $#_ == 0 ) ? ' '.$key.' = ? ': ( ( $#_ > 0 ) ? ( ' '.$key. 'in('.('?'x($#_+1)).') ') : '' );
}
# OPTIONS tests
sub email{
#todo: repeat my old function based on templates and store into utils
my($provider_contact,$client_contact,$invoice,$pdf_ref)=@_;
$client_contact->{email} //= '';
if(1 or $client_contact->{email}){
my $email = Email::MIME->create(
header => [
From => $provider_contact->{email},
#To => $client_contact->{email},
To => 'ipeshinskaya@gmail.com',
#To => 'ipeshinskaya@sipwise.com',
Subject => 'Invoice #'.$invoice->{serial},
],
parts => [
Email::MIME->create(
attributes => {
filename => "invoice_$invoice->{serial}.pdf",
content_type => "application/pdf",
encoding => "base64",
#encoding => "quoted-printable",
disposition => "attachment",
},
#body => io( $pdf_ref )->all,
body => $pdf_ref,
),
Email::MIME->create(
attributes => {
encoding => "quoted-printable",
content_type => "text/plain",
charset => "US-ASCII",
},
body_str => "Dear Customer!\n\nEmail:$client_contact->{email}\n\nSome text from sales here. Using loc somehow?\n Best regards,",
),
]
);
sendmail($email, { transport => $email_transport });
#sendmail($email);
print "Error sending email: $@" if $@;
}
}

Loading…
Cancel
Save