MT#5879 Script to generate invoices from templates.

ipeshinskaya/InvoiceTemplate5
Irina Peshinskaya 12 years ago committed by Victor Seva
parent 891a4c52fa
commit 0d39395842

@ -489,6 +489,9 @@ sub template_view :Chained('template_base') :PathPart('view') :Args {
my $tokens_re = qr/\[%(.*?)%\]/;
my $token_shape_re = qr/\s+/;
my %tokens_valid = map{$_=~s/$token_shape_re//sg; $_ => 1;} ($tt_string_default=~/$tokens_re/sg);
#use irka;
#use Data::Dumper;
#irka::loglong(Dumper(\%tokens_valid));
foreach( $tt_string_sanitized=~/$tokens_re/sg ){
my $token_shape=$_;
$token_shape=~s/$token_shape_re//sg;
@ -558,8 +561,7 @@ sub template_view :Chained('template_base') :PathPart('view') :Args {
#even better - to template filters
#also to model
$out->{tt_string_prepared}=$out->{tt_string_stored}=$out->{tt_string};
$out->{tt_string_prepared}=~s/(?:{\s*)?<!--{|}-->(?:\s*})?//gs;
$out->{tt_string_prepared}=~s/(<g .*?(id *=["' ]+(?:title|bg|mid)page["' ]+)?.*?)(?:display="none")(?(2)(?:.*?>)($2.*?>))/$1$3/gs;
NGCP::Panel::Utils::InvoiceTemplate::preprocessInvoiceTemplateSvg($in,\$out->{tt_string_prepared});
}
if( ($in->{tt_output_type} eq 'svg') || ( $in->{tt_output_type} eq 'html') ){
@ -591,59 +593,7 @@ sub template_view :Chained('template_base') :PathPart('view') :Args {
#method
$c->response->content_type('application/pdf');
my $svg = $c->view('SVG')->getTemplateProcessed($c,\$out->{tt_string_prepared}, $c->stash );
my(@pages) = $svg=~/(<svg.*?(?:\/svg>))/sig;
#$c->log->debug($svg);
my ($tempdirbase,$tempdir );
use File::Temp qw/tempfile tempdir/;
#my($fh, $tempfilename) = tempfile();
$tempdirbase = join('/',File::Spec->tmpdir,@$in{qw/provider_id tt_type tt_sourcestate/}, $out->{tt_id});
use File::Path qw( mkpath );
! -e $tempdirbase and mkpath( $tempdirbase, 0, 0777 );
$tempdir = tempdir( DIR => $tempdirbase , CLEANUP => 1 );
$c->log->debug("tempdirbase=$tempdirbase; tempdir=$tempdir;");
#try{
#} catch($e){
# NGCP::Panel::Utils::Message->error(
# c => $c,
# error => "Can't create temporary directory at: $tempdirbase;" ,
# desc => $c->loc("Can't create temporary directory."),
# );
#}
my $pagenum = 1;
my @pagefiles;
foreach my $page (@pages){
my $fh;
my $pagefile = "$tempdir/$pagenum.svg";
push @pagefiles, $pagefile;
open($fh,">",$pagefile);
#try{
#} catch($e){
# NGCP::Panel::Utils::Message->error(
# c => $c,
# error => "Can't create temporary page file at: $tempdirbase/$page.svg;" ,
# desc => $c->loc("Can't create temporary file."),
# );
#}
print $fh $page;
close $fh;
$pagenum++;
}
my $cmd = "rsvg-convert -f pdf ".join(" ", @pagefiles);
$c->log->debug($cmd);
#`chmod ugo+rwx $filename`;
#binmode(STDOUT);
#binmode(STDIN);
#$out->{tt_string} = `$cmd`;
{
#$cmd = "fc-list";
open B, "$cmd |";
binmode B;
local $/ = undef;
$out->{tt_string_pdf} = <B>;
close B;
}
NGCP::Panel::Utils::InvoiceTemplate::convertSvg2Pdf($c,\$svg,$in,$out);
$c->response->body($out->{tt_string_pdf});
return;
#$out->{tt_string} = `cat $filename `;

@ -231,81 +231,98 @@ sub getInvoiceClientContactInfo{
sub getInvoiceProviderClients{
my $self = shift;
my (%params) = @_;
my ($provider_id) = @params{qw/provider_id/};
#$schema->resultset('contracts')
# my $mapping_rs = $schema->resultset('billing_mappings');
# my $rs = $schema->resultset('contracts')
# ->search({
# 'me.status' => { '!=' => 'terminated' },
# 'billing_mappings.id' => {
# '=' => $mapping_rs->search({
# contract_id => { -ident => 'me.id' },
# start_date => [ -or =>
# { '<=' => NGCP::Panel::Utils::DateTime::current_local },
# { -is => undef },
# ],
# end_date => [ -or =>
# { '>=' => NGCP::Panel::Utils::DateTime::current_local },
# { -is => undef },
# ],
# },{
# alias => 'bilmap',
# rows => 1,
# order_by => {-desc => ['bilmap.start_date', 'bilmap.id']},
# })->get_column('id')->as_query,
# },
# },{
# 'join' => 'billing_mappings',
# '+select' => [
# 'billing_mappings.id',
# 'billing_mappings.start_date',
# 'billing_mappings.product_id',
# ],
# '+as' => [
# 'billing_mapping_id',
# 'billing_mapping_start_date',
# 'product_id',
# ],
# alias => 'me',
# });
#
# return $rs;
#very optimistic programming style
return NGCP::Panel::Utils::Contract::get_contract_rs(
schema => $self->schema,
)->search_rs({
'contact.reseller_id' => $provider_id,
},{
join => 'contact',
my ($provider_contact_id,$stime,$etime) = @params{qw/provider_contact_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_contact_id, #$client_contract_id - contract of the client
'id' => { '!=' => $provider_contact_id },
],
'-exists' => $self->schema->resultset('billing_mappings')->search({
'contract.contact_id' => \' = contacts.id',
'product.class' => [ "sipaccount", "pbxaccount" ],
'-and' => [
'start_date' => [ -or =>
{ '<=' => $etime->epoch },
{ -is => undef },
],
'end_date' => [ -or =>
{ '>=' => $stime->epoch },
{ -is => undef },
],
]
},{
alias => 'billing_mappings_top',
join => ['product','contract'],
})->as_query
});
}
sub get_contract_calls_rs{
my $self = shift;
my %params = @_;
(my($c,$provider_id,$client_id,$stime,$etime)) = @params{qw/c provider_id client_id stime etime/};
(my($c,$provider_contact_id,$client_contact_id,$stime,$etime)) = @params{qw/c provider_id client_id stime etime/};#I think it may be a record (very long var name)
my $source_account_id_condition;
if(!$client_id){
$source_account_id_condition = { 'in' => $self->getInvoiceProviderClients(%params)->search_rs({},{
'select' => 'me.id',
})->as_query()
#$self->schema('contracts')->search_rs({},{
# 'select' => 'me.id',
# 'join' => 'contact',
#})->as_query()
};
$stime ||= NGCP::Panel::Utils::DateTime::current_local()->truncate( to => 'month' );
$etime ||= $stime->clone->add( months => 1 );
if(!$client_contract_id){
#$source_account_id_condition = {
# 'in' => $self->getInvoiceProviderClients(%params)->search_rs({},{
# 'select' => 'me.id',
# })->as_query()
#};
$source_account_id_condition = { 'in' => $self->getInvoiceProviderClients(
provider_contact_id => $provider_contact_id,
stime => $stime,
etime => $etime,
)->search_rs(undef,{
'select' => 'me.id',
})->as_query };
}else{
$source_account_id_condition = $client_id;
$source_account_id_condition = $client_contract_id;
}
$sql = '
select cdr.* from accounting.cdr
#I find that sql is more compact and clear
$sql_of_all_provider_contract_id_clients_contact_ids_sip_pbx = ['
select contacts.*
from contacts
where
contacts.reseller_id=?
and exists (select *
from billing_mappings
inner join contracts on contracts.id=billing_mappings.contract_id
inner join products on billing_mappings.product_id=products.id and products.class in("sipaccount","pbxaccount")
where contracts.contact_id=contacts.id
and (start_date <= ? OR start_date IS NULL)
and (end_date >= ? OR end_date IS NULL)
)',$provider_contract_id, $etime->epoch, $stime->epoch];
$sql_of_all_client_contract_id_calls = '
select cdr.*
from accounting.cdr
inner join contracts on cdr.source_account_id=contracts.id
and contracts.status != "terminated"
inner join contacts on contracts.contact_id=contacts.id
and contacts.reseller_id=1 and contacts.reseller_id!=contacts.id
where
cdr.source_user_id != 0
and cdr.call_status="ok"
and exists (select *
from billing_mappings
inner join products on billing_mappings.product_id=products.id and products.class in("sipaccount","pbxaccount")
where contracts.id=billing_mappings.contract_id
and (billing_mappings.start_date >= now() OR start_date IS NULL)
and (billing_mappings.end_date <= now() OR end_date IS NULL)
)
and contracts.contact_id=22
order by cdr.start_time
';
$sql_of_all_provider_contact_id_clients_calls = '
select cdr.*
from contacts
inner join contracts on contracts.contact_id=contacts.id
and contacts.reseller_id=2 and contacts.reseller_id!=contacts.id
inner join accounting.cdr on cdr.source_account_id=contracts.id
and contracts.status != "terminated"
where
cdr.source_user_id != 0
and cdr.call_status="ok"
@ -317,20 +334,28 @@ sub get_contract_calls_rs{
and (billing_mappings.end_date <= now() OR end_date IS NULL)
)
order by cdr.start_time
';
';
my $calls_rs = $self->schema->resultset('cdr')->search( {
# source_user_id => { 'in' => [ map {$_->uuid} @{$contract->{subscriber}} ] },
'call_status' => 'ok',
'source_user_id' => { '!=' => '0' },
'contact.id' => { '!=' => $provider_id },
'contact.id' => { '!=' => $provider_contact_id },
'-and' => [
#'contact.reseller_id' => $provider_id,
#'contact.reseller_id' => $provider_id, #$client_contract_id - contract of the client
'contact.reseller_id' => { '!=' => undef },
],
'source_account.status' => { '!=' => 'terminated'},
'-exists' => $self->schema->resultset('billing_mappings')->search({
'contract_id' => \'= source_account.id',
'contract_id' => \'= source_account.id',
'product.class' => [ "sipaccount", "pbxaccount" ],
'start_date' => [ -or =>
{ '<=' => 'cdr.start_time' },
{ -is => undef },
],
'end_date' => [ -or =>
{ '>=' => 'cdr.start_time' },
{ -is => undef },
],
},{
alias => 'billing_mappings_top',
join => 'product',
@ -400,7 +425,7 @@ sub get_contract_zonesfees_rs {
#alias =>
join => 'source_customer_billing_zones_history',
group_by => 'source_customer_billing_zones_history.zone',
#order_by => 'source_customer_billing_zones_history.zone',
order_by => 'source_customer_billing_zones_history.zone',
} );
return $zonecalls_rs;

@ -13,8 +13,6 @@ sub create_contract_balance {
my $contract = $params{contract};
my $profile = $params{profile};
my ($cash_balance, $cash_balance_interval,
$free_time_balance, $free_time_balance_interval) = (0,0,0,0);
# first, calculate start and end time of current billing profile
# (we assume billing interval of 1 month)
@ -22,20 +20,13 @@ sub create_contract_balance {
my $etime = $stime->clone->add(months => 1)->subtract(seconds => 1);
# calculate free_time/cash ratio
my $free_time = $profile->interval_free_time || 0;
my $free_cash = $profile->interval_free_cash || 0;
if($free_time or $free_cash) {
$etime->add(seconds => 1);
my $ctime = NGCP::Panel::Utils::DateTime::current_local->truncate(to => 'day');
my $ratio = ($etime->epoch - $ctime->epoch) / ($etime->epoch - $stime->epoch);
$cash_balance = sprintf("%.4f", $free_cash * $ratio);
$cash_balance_interval = 0;
$free_time_balance = sprintf("%.0f", $free_time * $ratio);
$free_time_balance_interval = 0;
$etime->subtract(seconds => 1);
}
my ($cash_balance, $cash_balance_interval,
$free_time_balance, $free_time_balance_interval) = get_contract_balance_values(
interval_free_time => ( $profile->interval_free_time || 0 ),
interval_free_cash => ( $profile->interval_free_cash || 0 ),
stime => $stime,
etime => $etime,
);
try {
my $schema = $c->model('DB');
@ -60,7 +51,27 @@ sub create_contract_balance {
};
return;
}
sub get_contract_balance_values{
my %params = @_;
my($free_time,$free_cash,$stime,$etime) = @params{qw/interval_free_time interval_free_cash stime etime/};
my ($cash_balance, $cash_balance_interval,
$free_time_balance, $free_time_balance_interval) = (0,0,0,0);
if($free_time or $free_cash) {
$etime->add(seconds => 1);
my $ctime = NGCP::Panel::Utils::DateTime::current_local->truncate(to => 'day');
if( ( $ctime->epoch >= $stime->epoch ) && ( $ctime->epoch <= $stime->epoch ) ){
my $ratio = ($etime->epoch - $ctime->epoch) / ($etime->epoch - $stime->epoch);
$cash_balance = sprintf("%.4f", $free_cash * $ratio);
$cash_balance_interval = 0;
$free_time_balance = sprintf("%.0f", $free_time * $ratio);
$free_time_balance_interval = 0;
}
$etime->subtract(seconds => 1);
}
return ($cash_balance,$cash_balance_interval,$free_time_balance,$free_time_balance_interval);
}
sub recursively_lock_contract {
my %params = @_;

@ -5,6 +5,8 @@ use strict;
use warnings;
#use Moose;
use Sipwise::Base;
use File::Temp qw/tempfile tempdir/;
use File::Path qw/mkpath/;
sub getDefaultInvoiceTemplate{
my (%in) = @_;
@ -18,5 +20,71 @@ sub getDefaultInvoiceTemplate{
}
return \$result;
}
sub convertSvg2Pdf{
my($c,$svg_ref,$in,$out) = @_;
my $svg = $$svg_ref;
my(@pages) = $svg=~/(<svg.*?(?:\/svg>))/sig;
#$c->log->debug($svg);
my ($tempdirbase,$tempdir );
#my($fh, $tempfilename) = tempfile();
$tempdirbase = join('/',File::Spec->tmpdir,@$in{qw/provider_id tt_type tt_sourcestate/}, $out->{tt_id});
! -e $tempdirbase and mkpath( $tempdirbase, 0, 0777 );
$tempdir = tempdir( DIR => $tempdirbase , CLEANUP => 1 );
$c and $c->log->debug("tempdirbase=$tempdirbase; tempdir=$tempdir;");
#try{
#} catch($e){
# NGCP::Panel::Utils::Message->error(
# c => $c,
# error => "Can't create temporary directory at: $tempdirbase;" ,
# desc => $c->loc("Can't create temporary directory."),
# );
#}
my $pagenum = 1;
my @pagefiles;
foreach my $page (@pages){
my $fh;
my $pagefile = "$tempdir/$pagenum.svg";
push @pagefiles, $pagefile;
open($fh,">",$pagefile);
#try{
#} catch($e){
# NGCP::Panel::Utils::Message->error(
# c => $c,
# error => "Can't create temporary page file at: $tempdirbase/$page.svg;" ,
# desc => $c->loc("Can't create temporary file."),
# );
#}
print $fh $page;
close $fh;
$pagenum++;
}
my $cmd = "rsvg-convert -f pdf ".join(" ", @pagefiles);
$c and $c->log->debug($cmd);
#`chmod ugo+rwx $filename`;
#binmode(STDOUT);
#binmode(STDIN);
#$out->{tt_string} = `$cmd`;
{
#$cmd = "fc-list";
open B, "$cmd |";
binmode B;
local $/ = undef;
$out->{tt_string_pdf} = <B>;
close B;
}
}
sub preprocessInvoiceTemplateSvg{
my($in,$svg_ref) = @_;
no warnings 'uninitialized';
#print "1.\n\n\n\n\nsvg=".$out->{tt_string_prepared}.";";
$$svg_ref=~s/(?:{\s*)?<!--{|}-->(?:\s*})?//gs;
$$svg_ref=~s/(<g .*?(id *=["' ]+(?:title|bg|mid)page["' ]+)?.*?)(?:display="none")(?(2)(?:.*?>)($2.*?>))/$1$3/gs;
if($in->{no_fake_data}){
$$svg_ref=~s/\[%[^\[\%]+lorem.*?%\]//gs;
}
#print "\n\n2.\n\n\n\nsvg=".$out->{tt_string_prepared}.";";
}
1;

@ -23,8 +23,7 @@ sub translate_form {
NGCP::Panel::Utils::I18N->translate_form(@_);
}
sub process
{
sub process{
my ( $self, $c ) = @_;
#$c->res->content_type("image/svg+xml");
$self->{template}->context->define_vmethod(
@ -54,10 +53,10 @@ sub process
sub getTemplate{
my ( $self, $c, $template ) = @_;
if(defined $template){
$c->log->debug("getTemplate: template=$template;");
$c and $c->log->debug("getTemplate: template=$template;");
}
$template ||= ( $c->stash->{template} || $c->action . $self->config->{TEMPLATE_EXTENSION} );
$c->log->debug("getTemplate: template=$template;");
$c and $template ||= ( $c->stash->{template} || $c->action . $self->config->{TEMPLATE_EXTENSION} );
$c and $c->log->debug("getTemplate: template=$template;");
return $template;
}
#method is necessary to apply APP specific template configurations, e.g. path, tt file extensions etc
@ -69,6 +68,14 @@ sub getTemplateContent{
}
sub getTemplateProcessed{
my ( $self, $c, $template, $stash ) = @_;
$self->{template}->context->define_vmethod(
hash => get_column => sub {
my($item,$col) = @_;
if('HASH' eq ref $item){
return $item->{$col};
}
}
);
#$c->log->debug("getTemplateProcessed: template=$template;");
#my $result = $self->{template}->context->process($template, $stash);
#$c->log->debug("getTemplateProcessed: result=$result;");

@ -123,7 +123,7 @@
[% matches = page.match( page_interval_re ) -%]
[%interval = matches.0 || matches.1 %]
[%interval = Math.int(rows)%]
[%interval = Math.int(interval)%]
[%interval%]
[%END -%]
@ -137,7 +137,7 @@
[% midzonerows = get_page_rows_number('zonepage','svg') %]
[% titlezoneinterval = get_page_interval('titlepage','svg','zone') %]
[% midzoneinterval = get_page_interval('zonepage','svg') %]
[% midzonerows = get_page_rows_number('zonepage','svg') %]
[% midzonerows = Math.int(get_page_rows_number('zonepage','svg')) %]
[% midzonerows = ( midzonerows < 1 ) ? 30 : midzonerows %]
[% allmidzonepages = ( (allzonerowsnumber - titlezonerows) / midzonerows )|format('%d') %]
@ -148,7 +148,7 @@
[% allcallrowsnumber = invoice_details_calls.size() %]
[% titlecallrows = get_page_rows_number('titlepage','svg','call') %]
[% midcallrows = get_page_rows_number('callpage','svg') %]
[% midcallrows = Math.int(get_page_rows_number('callpage','svg')) %]
[% midcallrows = ( midcallrows < 1 ) ? 30 : midcallrows %]
[% titlecallinterval = get_page_interval('titlepage','svg', 'call') %]
[% midcallinterval = get_page_interval('callpage','svg') %]
@ -174,7 +174,7 @@
[% bgpage(pagenum) -%]
[% document_footer()%]
[%END-%]
[%IF ( pagetype == 'zone' || pagetype=='all' ) && allmidzonerows %]
[%IF ( pagetype == 'zone' || pagetype=='all' ) && allzonerowsnumber %]
[% pages = pagenum_in ? [ pagenum_in ] : [ 1 .. allmidzonepages ] %]
[%FOREACH pagenum IN pages %]
[% pagerowsstart = titlezonerows + midzonerows * ( pagenum - 1 )%]

@ -21,6 +21,7 @@ DEFAULT invoice.serviceallowance='69';
DEFAULT invoice.voice_termination_fees='10';
END;
IF !provider;
DEFAULT provider.bic='ABCDEFG1234';
DEFAULT provider.city='Provider City';
DEFAULT provider.company='Provider Gmbh.';
@ -35,6 +36,11 @@ DEFAULT provider.postcode='65104';
DEFAULT provider.street='Provider Street';
DEFAULT provider.url='http://www.provider.com/';
DEFAULT provider.vat='UATAA1234AA1234';
ELSE;
FOREACH i in ['bic','city','company','country','email','fax','fn','iban','mobile','phone','postcode','street','url','vat'];
provider.${i} = provider.get_column($i);
END;
END;
IF !client.id;
DEFAULT client.bic='ABCDEFG1234';

@ -166,7 +166,7 @@ g, text, tspan {
<text y="10" text-anchor="end" id="callpage_calls[%loop.count-%]" class="widedatarow">
<tspan x="0" id="callpage_calls_num[%loop.count-%]" text-anchor="start" class="widedatarow"><!--{[% call.0 %]}--><!--{[%#}-->1<!--{%]}--></tspan>
<!--{[%IF call.1; call = call.1; END%]}-->
<tspan x="10" id="callpage_calls_start_time%loop.count-%]" text-anchor="start" class="widedatarow"><!--{[% date.format(Math.int(call.get_column('start_time')),'%Y-%m-%d %H:%M:%S') %]}--><!--{[%#}-->0001-01-31 23:59:59<!--{%]}--></tspan>
<tspan x="10" id="callpage_calls_start_time[%loop.count-%]" text-anchor="start" class="widedatarow"><!--{[% date.format(Math.int(call.get_column('start_time')),'%Y-%m-%d %H:%M:%S') %]}--><!--{[%#}-->0001-01-31 23:59:59<!--{%]}--></tspan>
<tspan x="60" id="callpage_calls_duration[%loop.count-%]" class="widedatarow"><!--{[% call.get_column('duration')|format('%.3f') %]}--><!--{[%#}-->0.000<!--{%]}--></tspan>
<tspan x="90" id="callpage_calls_destination[%loop.count-%]" class="widedatarow"><!--{[% call.get_column('destination_user_in').replace('(.*?)\d{4}$','$1****') %]}--><!--{[%#}-->+00000000****<!--{%]}--></tspan>
<tspan x="105" id="callpage_calls_type[%loop.count-%]" class="widedatarow"><!--{[% call.get_column('call_type') %]}--><!--{[%#}-->call<!--{%]}--></tspan>

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 22 KiB

@ -0,0 +1,200 @@
#!/usr/bin/perl -w
use lib '/media/sf_/usr/share/VMHost/ngcp-panel/lib';
use strict;
use DBI;
use Data::Dumper;
use NGCP::Panel::Utils::DateTime;
use DateTime::TimeZone;
use Net::Domain qw(hostfqdn);
use LWP::UserAgent;
use NGCP::Panel::Utils::Contract;
use NGCP::Panel::Utils::InvoiceTemplate;
use NGCP::Panel;
use NGCP::Panel::View::SVG;
use Test::MockObject;
use Sipwise::Base;
my $debug = 1;
my ($dbuser, $dbpass);
my $mfile = '/etc/mysql/sipwise.cnf';
if(-f $mfile) {
open my $fh, "<", $mfile
or die "failed to open '$mfile': $!\n";
$_ = <$fh>; chomp;
s/^SIPWISE_DB_PASSWORD='(.+)'$/$1/;
$dbuser = 'sipwise'; $dbpass = $_;
} else {
$dbuser = 'root';
$dbpass = '';
}
print "using user '$dbuser' with pass '$dbpass'\n"
if($debug);
#my ($ua, $req, $res);
#use LWP::UserAgent;
#use HTTP::Request;
#$ua = LWP::UserAgent->new;
#$req = HTTP::Request->new('OPTIONS', 'https://192.168.56.7:1444/invoice/3/template');
##$res = $ua->request($req);
#my $controller = NGCP::Panel->controller('Invoice');
#my $c = NGCP::Panel->prepare($ua);
##$c->request->param->{tt_id} = 126;
##$c->request->method( 'POST' );
##$c->request->uri( 'https://192.168.56.7:1444/invoice/3/template');
#die();
my $dbh = DBI->connect('dbi:mysql:billing;host=localhost', $dbuser, $dbpass)
or die "failed to connect to billing DB\n";
#$dbh->trace(SQL);
#copypasted from tests
#my $uri = $ENV{CATALYST_SERVER} || ('https://'.hostfqdn.':4443');
#my $valid_ssl_client_cert = $ENV{API_SSL_CLIENT_CERT} ||
# "/etc/ssl/ngcp/api/NGCP-API-client-certificate.pem";
#my $valid_ssl_client_key = $ENV{API_SSL_CLIENT_KEY} ||
# $valid_ssl_client_cert;
#my $ssl_ca_cert = $ENV{API_SSL_CA_CERT} || "/etc/ssl/ngcp/api/ca-cert.pem";
#$ua->ssl_opts(
# SSL_cert_file => $valid_ssl_client_cert,
# SSL_key_file => $valid_ssl_client_key,
# SSL_ca_file => $ssl_ca_cert,
#);
my $stime = NGCP::Panel::Utils::DateTime::current_local()->truncate( to => 'month' );
my $etime_plus = $stime->clone->add( months => 1 );
my $etime = $etime_plus->clone->subtract( seconds => 1 );
my $c_mock = Test::MockObject->new();
$c_mock->set_false(qw/debug/);
my $view = NGCP::Panel::View::SVG->new($c_mock,{});
my $svg_default = $view->getTemplateContent(undef,'invoice/invoice_template_svg.tt');
NGCP::Panel::Utils::InvoiceTemplate::preprocessInvoiceTemplateSvg({no_fake_data => 1},\$svg_default);
#print $etime->ymd;
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"', { Slice => {} } ) } ){
my $provider_contact = $dbh->selectrow_hashref('select * from contacts where id=?', undef, $provider_contract->{contact_id} );
foreach my $client_contact (@{ $dbh->selectall_arrayref('select contacts.* from contacts where reseller_id = ?', { Slice => {} }, $provider_contract->{reseller_core_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.*
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
inner join products on billing_mappings.product_id=products.id and products.class in("sipaccount","pbxaccount")
where
contracts.status != "terminated"
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
) ) ){
my $invoice;
if(!(my $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))){
@$contract_balance{qw/cash_balance cash_balance_interval free_time_balance free_time_balance_interval/} = NGCP::Panel::Utils::Contract::get_contract_balance_values(
%$billing_profile,
stime => $stime,
etime => $etime->datetime,
);
$dbh->do('insert into contract_balances(contract_id,cash_balance,cash_balance_interval,free_time_balance,free_time_balance_interval,start,end,invoice_id)values(?,?,?,?,?,?,?,?)',undef,$client_contract->{id},@$contract_balance{qw/cash_balance cash_balance_interval free_time_balance free_time_balance_interval/},$stime->datetime, $etime->datetime,undef );
$invoice = create_invoice($client_contract->{id},$stime, $etime);
$contract_balance = $dbh->selectrow_hashref('select * from contract_balances where id=?',undef,$dbh->last_insert_id(undef,'billing','contract_balances','id'));
}else{
$invoice = $dbh->selectrow_hashref('select * from invoices where id=?',undef,$contract_balance->{invoice_id} );
$invoice = create_invoice($client_contract->{id},$stime, $etime);
}
my $invoice_details_calls = $dbh->selectall_arrayref('select cdr.*,bzh.zone, bzh.detail as zone_detail
from accounting.cdr
LEFT JOIN billing.billing_zones_history bzh ON bzh.id = cdr.source_customer_billing_zone_id
where
cdr.source_user_id != 0
and cdr.call_status="ok"
-- and cdr.source_account_id=?
-- and cdr.start_time >= ?
-- and cdr.start_time <= ?
order by cdr.start_time
limit 5'
, { Slice => {} }
#, $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
LEFT JOIN billing.billing_zones_history bzh ON bzh.id = cdr.source_customer_billing_zone_id
where
cdr.source_user_id != 0
and cdr.call_status="ok"
-- 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
);
my $i = 1;
$invoice_details_calls = [map{[$i++,$_]} (@$invoice_details_calls) x 1];
$i = 1;
$invoice_details_zones = [map{[$i++,$_]} (@$invoice_details_zones) x 1];
#my $controller = NGCP::Panel->controller('Invoice');
#my $c = NGCP::Panel->prepare();
# Monkey with $c to set up a fake context (set req->uri, or params)
my ($in, $out);
#tt_id used only as part in temporary directory
$in = {
no_fake_data => 1,
provider_id => $provider_contract->{reseller_core_id},
tt_type => 'svg',
tt_sourcestate => 'saved',
tt_id => 1,
};
$out = {
tt_id => 1,
};
my $stash = {
provider => $provider_contact,
client => $client_contact,
invoice => $invoice,
invoice_details_zones => $invoice_details_zones,
invoice_details_calls => $invoice_details_calls,
};
my $svg = $dbh->selectrow_array('select base64_saved from invoice_templates where is_active = 1 and type = "svg" and reseller_id=?',undef,$provider_contract->{reseller_core_id});
if(!$svg){
$svg = $svg_default;
#print "svg=$svg;";
}else{
NGCP::Panel::Utils::InvoiceTemplate::preprocessInvoiceTemplateSvg($in,\$svg);
}
$svg = $view->getTemplateProcessed($c_mock,\$svg, $stash );
print $svg;
die();
NGCP::Panel::Utils::InvoiceTemplate::convertSvg2Pdf(undef,\$svg,$in,$out);
#print $out->{tt_string_pdf};
die;
#my $result = $c->forward($controller, 'invoice_templaet', [] );
#$req = HTTP::Request->new('OPTIONS', $uri.'/invoice/'..'/');
#$res = $ua->request($req);
}
}
}
sub create_invoice{
my($contract_id, $stime, $etime) = @_;
#my $invoice_serial = $dbh->selectrow_array('select max(invoices.serial) from invoices inner join contract_balances on invoices.id=contract_balances.invoice_id where contract_balances.contract_id=?',undef,$contract_id );
my $invoice_serial = $dbh->selectrow_array('select max(invoices.serial) from invoices');
$invoice_serial += 1;
$dbh->do('insert into invoices(year,month,serial)values(?,?,?)', undef, $stime->year, $stime->month,$invoice_serial );
my $invoice_id = $dbh->last_insert_id(undef,'billing','invoices','id');
$dbh->do('update contract_balances set invoice_id = ? where contract_id=? and start=? and end=?', undef, $invoice_id,$contract_id, $stime->datetime, $etime->datetime );
return $dbh->selectrow_hashref('select * from invoices where id=?',undef, $invoice_id);
}
# OPTIONS tests
Loading…
Cancel
Save