From 83db5c1b930932e01fa97f184e7cc65363d21ae9 Mon Sep 17 00:00:00 2001 From: Irina Peshinskaya Date: Thu, 8 May 2014 08:37:23 +0300 Subject: [PATCH] MT#5879 Multiple attachments and further web generation. --- lib/NGCP/Panel/Controller/Invoice.pm | 65 ++-------------------- lib/NGCP/Panel/Model/DB/InvoiceTemplate.pm | 12 ++-- share/templates/helpers/datatables.tt | 2 +- share/templates/invoice/list.tt | 4 +- share/tools/generate_invoices.pl | 60 +++++++++++++------- 5 files changed, 56 insertions(+), 87 deletions(-) diff --git a/lib/NGCP/Panel/Controller/Invoice.pm b/lib/NGCP/Panel/Controller/Invoice.pm index b3d644df69..7d817bb58e 100644 --- a/lib/NGCP/Panel/Controller/Invoice.pm +++ b/lib/NGCP/Panel/Controller/Invoice.pm @@ -264,70 +264,22 @@ sub invoice_generate :Chained('base') :PathPart('generate') :Args(0) { my $in_validated = $validator->fif; if($posted){ if($validator->validated) { - #copy/pasted from NGCP\Panel\Role\API\Customers.pm - my $customer = $backend->getInvoiceClientContactInfo($in); + my $client_contract = $backend->getInvoiceClientContractInfo($in); + my $client_contact = $backend->getInvoiceClientContactInfo($in); my $contract_balance = $backend->getContractBalance($in); + #$c->log->debug("customer->id="..";"); if(!$contract_balance){ my $billing_profile = $backend->getBillingProfile($in); NGCP::Panel::Utils::Contract::create_contract_balance( c => $c, profile => $billing_profile, - contract => $customer, + contract => $client_contract, ); $contract_balance = $backend->getContractBalance($in); } - #my $billing_mapping = $customer->billing_mappings->find($customer->get_column('bmid')); - #my $billing_profile_id = $billing_mapping->billing_profile->id; - #my $stime = NGCP::Panel::Utils::DateTime::current_local()->truncate(to => 'month'); - #my $etime = $stime->clone->add(months => 1); - #my $contract_balance = $customer->contract_balances - # ->find({ - # start => { '>=' => $stime }, - # end => { '<' => $etime }, - # }); - #unless($contract_balance) { - # try { - # NGCP::Panel::Utils::Contract::create_contract_balance( - # c => $c, - # profile => $billing_mapping->billing_profile, - # contract => $customer, - # ); - # } catch($e) { - # $self->log->error("Failed to create current contract balance for customer contract id '".$customer->id."': $e"); - # $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Internal Server Error."); - # return; - # }; - # $contract_balance = $customer->contract_balances->find({ - # start => { '>=' => $stime }, - # end => { '<' => $etime }, - # }); - #} - - - - - - - - - - - - - - - - - - - - - - - - - + + try { #$backend->storeInvoiceTemplateInfo(%$in_validated); $c->flash(messages => [{type => 'success', text => $c->loc( @@ -607,11 +559,6 @@ sub template_view :Chained('template_base') :PathPart('view') :Args { my($validator,$backend,$in,$out); -#fake data - $c->forward('invoice_details_calls'); - $c->forward('invoice_details_zones'); - #invoice number and data - #client info #input (undef,undef,@$in{qw/tt_type tt_viewmode tt_sourcestate tt_output_type tt_id/}) = @_ ; diff --git a/lib/NGCP/Panel/Model/DB/InvoiceTemplate.pm b/lib/NGCP/Panel/Model/DB/InvoiceTemplate.pm index 1d352f8f72..c86168b91f 100644 --- a/lib/NGCP/Panel/Model/DB/InvoiceTemplate.pm +++ b/lib/NGCP/Panel/Model/DB/InvoiceTemplate.pm @@ -219,18 +219,18 @@ sub checkInvoiceTemplateProvider{ return 0; } -sub getInvoiceClientContactInfo{ +sub getInvoiceClientContractInfo{ my $self = shift; my (%params) = @_; - my ($client_contact_id) = @params{qw/client_contact_id/}; - return $self->schema->resultset('contacts')->search({ - id => $client_contact_id, + my ($client_contract_id) = @params{qw/client_contract_id/}; + return $self->schema->resultset('contracts')->search({ + id => $client_contract_id, }); } sub getBillingProfile{ my $self = shift; my (%params) = @_; - my ($client_contact_id, $stime, $etime) = @params{qw/client_contact_id start end/}; + my ($client_contract_id, $stime, $etime) = @params{qw/client_contract_id start end/}; #select distinct billing_profiles.* #from billing_mappings #inner join billing_profiles on billing_mappings.billing_profile_id=billing_profiles.id @@ -242,7 +242,7 @@ sub getBillingProfile{ # and (billing_mappings.start_date <= ? OR billing_mappings.start_date IS NULL) # and (billing_mappings.end_date >= ? OR billing_mappings.end_date IS NULL) return $self->schema->resultset('billing_profiles')->search({ - 'contract.contact_id' => $client_contact_id, + 'contract.id' => $client_contract_id, #'contract.status' => { '!=' => 'terminated' }, 'product.class' => { '-in' => [qw/sipaccount pbxaccount/] }, 'billing_mappings.start_date' => [ diff --git a/share/templates/helpers/datatables.tt b/share/templates/helpers/datatables.tt index 0648df3203..9d6b2aca42 100644 --- a/share/templates/helpers/datatables.tt +++ b/share/templates/helpers/datatables.tt @@ -100,11 +100,11 @@ $(document).ready(function() { { "mRender": function ( data, type, full ) { var html = '' + '
'; + [% backuri = backuri | uri%] [% FOR button IN helper.dt_buttons -%] [% confirm_delete = button.name == "Delete" ? 'data-confirm="Delete"' : '' -%] [% confirm_delete = button.name == "Terminate" ? 'data-confirm="Terminate"' : confirm_delete -%] [%IF !( button.uri.search('[\?\&]back=|^javascript:') ); %] - [% backuri = backuri | uri%] [% button.uri = button.uri _ '?back=' _ backuri %] [%END%] [% IF button.condition -%] diff --git a/share/templates/invoice/list.tt b/share/templates/invoice/list.tt index 18da27199d..aa7f748009 100644 --- a/share/templates/invoice/list.tt +++ b/share/templates/invoice/list.tt @@ -81,10 +81,11 @@ function applyClientFilter(table,tr,contact_id){ { name => 'contracts.external_id', title => c.loc('External #'), search => 1 }, { name => 'email', title => c.loc('Contact Email'), search => 1 }, { name => 'contracts.billing_mappings.billing_profile.name', title => c.loc('Billing Profile'), search => 1 }, + { name => 'contracts.billing_mappings.product.name', title => c.loc('Product'), search => 1 }, { name => 'contracts.status', title => c.loc('Status'), search => 1 }, ]; helper.dt_buttons = [ - { name => c.loc('Generate invoice'), uri => 'javascript:void(0);', onclick => "fetch_into(\\'invoice_generate_form\\', \\'" _ c.uri_for_action('/invoice/invoice_generate', [ provider.id]) _ "\\',\\'item=invoice_generate&client_contact_id='+full.id+'\\',function(){modalFormScript();});void(0);", class => 'btn-small btn-primary', icon => 'icon-star' }, + { name => c.loc('Generate invoice'), uri => 'javascript:void(0);', onclick => "fetch_into(\\'invoice_generate_form\\', \\'" _ c.uri_for_action('/invoice/invoice_generate', [ provider.id]) _ "\\',\\'item=invoice_generate&client_contract_id='+full.contract_id+'\\',function(){modalFormScript();});void(0);", class => 'btn-small btn-primary', icon => 'icon-star' }, { name => c.loc('Filter invoices'), uri=>'javascript:void(0);', onclick => "applyClientFilter(\\'\\',\$(this).closest(\\'tr\\'),'+full.id+');", class => 'btn-small btn-primary', icon => 'icon-glass', tooltip => 'Click twice to clear client filter.' }, ]; helper.identifier = 'provider_client_list_ajax'; @@ -119,6 +120,7 @@ function applyClientFilter(table,tr,contact_id){ { name => 'contract_balances.contract.contact.reseller_id'}, { name => 'contract_balances.contract.contact.reseller.name'}, { name => 'contract_balances.contract.contact.id', title => c.loc('Client'), search => 1}, + { name => 'contract_balances.contract.id', title => c.loc('Contract'), search => 1}, { name => 'contract_balances.invoice_id', title => c.loc('Invoice #'), search => 1}, { name => 'contract_balances.start', title => c.loc('Period Start'), search_from_epoch => 1, search_to_epoch => 1, search_use_datetime => 1 }, { name => 'contract_balances.end', title => c.loc('Period End')}, diff --git a/share/tools/generate_invoices.pl b/share/tools/generate_invoices.pl index 83b1fa3adc..fe60364388 100644 --- a/share/tools/generate_invoices.pl +++ b/share/tools/generate_invoices.pl @@ -83,12 +83,21 @@ my $etime = $opt->{etime} my $svg_default = $view->getTemplateContent(undef,'invoice/invoice_template_svg.tt'); NGCP::Panel::Utils::InvoiceTemplate::preprocessInvoiceTemplateSvg( {no_fake_data => 1}, \$svg_default); + +my $invoices = {}; + 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}} ) } ){ + print "reseller_id=".$provider_contract->{reseller_core_id}.";\n"; 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}} ) } ){ + print "reseller_id=".$provider_contract->{reseller_core_id}.";contact_id=".$client_contact->{id}.";\n"; + + $invoices->{$client_contact->{id}} ||= []; + foreach my $client_contract (@{ $dbh->selectall_arrayref('select contracts.* from contracts where contracts.contact_id=? ', { Slice => {} }, $client_contact->{id} ) }){ + print "reseller_id=".$provider_contract->{reseller_core_id}.";conatct_id=".$client_contact->{id}.";contract_id=".$client_contract->{id}.";\n"; if( my $billing_profile = $dbh->selectrow_hashref('select distinct billing_profiles.* from billing_mappings @@ -170,12 +179,16 @@ foreach my $provider_contract( @{$dbh->selectall_arrayref('select contracts.*,re #binmode(STDOUT); #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}); + $invoice->{data} = $out->{tt_string_pdf}; + push @{$invoices->{$client_contact->{id}}}, $invoice; + $dbh->do('update invoices set data=? where id=?',undef,$out->{tt_string_pdf},$invoice->{id}); + }else{#if billing profile + print "No billing profile;\n" } - } - } -} + }#foreach contract + email($provider_contact,$client_contact,$invoices->{$client_contact->{id}} ); + }#foreach client contact +}#foreach reseller sub get_contract_balance{ my($client_contract,$billing_profile,$contract_balance,$invoice,$stime,$etime) = @_; if(!($contract_balance = $dbh->selectrow_hashref('select * from contract_balances where contract_id=? and date(start)=? and date(end)=?',undef,$client_contract->{id},$stime->ymd,$etime->ymd))){ @@ -212,29 +225,36 @@ sub ify{ sub email{ #todo: repeat my old function based on templates and store into utils - my($provider_contact,$client_contact,$invoice,$pdf_ref)=@_; + my($provider_contact,$client_contact,$client_invoices)=@_; + if(@$client_invoices < 1 ){ + return; + } $client_contact->{email} //= ''; if(1 or $client_contact->{email}){ + my @attachments = map { + my $invoice = $_; + 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 => $invoice->{data}, + ); + } @$client_invoices; 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}, + #To => 'ipeshinskaya@gmail.com', + To => 'ipeshinskaya@sipwise.com', + Subject => 'Invoices', #todo: ask sales about subject ], 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, - ), + @attachments, Email::MIME->create( attributes => { encoding => "quoted-printable",