MT#5879 Invoice generation fixes.

Use correct name for zone fees cost.
Fix condition for char column in script.
Add root element to xml before XPath parsing to avoid errors about
the same elements on root level.
Set timezone to local. Maybe it shouldn't be, but then should be changed
in both used methods.

Todo:
Country name for generation from web.
Clarify and implement if neccessary generation of existing invoice from web.
Now invoice for the same period created.
mr3.3.1
Irina Peshinskaya 11 years ago
parent 9965197657
commit a72adaea52

@ -170,7 +170,19 @@ sub create :Chained('inv_list') :PathPart('create') :Args() :Does(ACL) :ACLDetac
out => 1,
group_by_detail => 1,
);
my $calllist_rs = NGCP::Panel::Utils::Contract::get_contract_calls_rs(
c => $c,
customer_contract_id => $contract_id,
stime => $stime,
etime => $etime,
);
my $calllist = [ map {
my $call = {$_->get_inflated_columns};
$call->{start_time} = $call->{start_time}->epoch;
$call->{source_customer_cost} += 0.0; # make sure it's a number
$call;
} $calllist_rs->all ];
my $billing_mapping = $customer->billing_mappings->find($customer->get_column('bmid'));
my $billing_profile = $billing_mapping->billing_profile;
@ -194,13 +206,10 @@ sub create :Chained('inv_list') :PathPart('create') :Args() :Does(ACL) :ACLDetac
$form->params->{period_start} = $stime->epoch;
$form->params->{period_end} = $etime->epoch;
my $vat = $customer->vat_rate // 0;
$form->params->{amount_net} =
($balance->cash_balance_interval ? $balance->cash_balance_interval / 100 : 0) +
($billing_profile->interval_charge // 0); # TODO: if not a full month, calculate fraction?
$form->params->{amount_vat} = $customer->add_vat ?
$form->params->{amount_net} * ($vat/100) : 0;
$form->params->{amount_total} = $form->params->{amount_net} + $form->params->{amount_vat};
@ -239,36 +248,7 @@ sub create :Chained('inv_list') :PathPart('create') :Args() :Does(ACL) :ACLDetac
my $vars = {};
my $calllist_rs = $c->model('DB')->resultset('cdr')->search({
source_account_id => $customer->id,
call_status => 'ok',
start_time => { '>=' => $stime->epoch },
start_time => { '<=' => $etime->epoch },
},{
select => [qw/
source_user source_domain source_cli
destination_user_in
start_time duration call_type
source_customer_cost
source_customer_billing_zones_history.zone
source_customer_billing_zones_history.detail
/],
as => [qw/
source_user source_domain source_cli
destination_user_in
start_time duration call_type
source_customer_cost
zone
zone_detail
/],
join => 'source_customer_billing_zones_history',
});
my $calllist = [ map {
my $call = {$_->get_inflated_columns};
$call->{start_time} = $call->{start_time}->epoch;
$call->{source_customer_cost} += 0.0; # make sure it's a number
$call;
} $calllist_rs->all ];
# TODO: index 170 seems the upper limit here, then the calllist breaks

@ -392,6 +392,46 @@ sub get_contract_zonesfees {
return \%allzones;
}
sub get_contract_calls_rs{
my %params = @_;
(my($c,$customer_contract_id,$stime,$etime)) = @params{qw/c customer_contract_id stime etime/};
$stime ||= NGCP::Panel::Utils::DateTime::current_local()->truncate( to => 'month' );
$etime ||= $stime->clone->add( months => 1 );
my $calls_rs = $c->model('DB')->resultset('cdr')->search( {
# source_user_id => { 'in' => [ map {$_->uuid} @{$contract->{subscriber}} ] },
'call_status' => 'ok',
'source_user_id' => { '!=' => '0' },
'start_time' =>
[ -and =>
{ '>=' => $stime->epoch},
{ '<=' => $etime->epoch},
],
'source_account_id' => $customer_contract_id,
},{
select => [qw/
source_user source_domain source_cli
destination_user_in
start_time duration call_type
source_customer_cost
source_customer_billing_zones_history.zone
source_customer_billing_zones_history.detail
/],
as => [qw/
source_user source_domain source_cli
destination_user_in
start_time duration call_type
source_customer_cost
zone
zone_detail
/],
'join' => 'source_customer_billing_zones_history',
'order_by' => 'start_time',
} );
return $calls_rs;
}
1;
__END__

@ -27,6 +27,7 @@ sub from_string {
# convert it to xxxx-xx-xxTxx:xx:xx
$s =~ s/^(\d{4}\-\d{2}\-\d{2})\s+(\d.+)$/$1T$2/;
my $ts = DateTime::Format::ISO8601->parse_datetime($s);
$ts->set_time_zone( DateTime::TimeZone->new(name => 'local') );
return $ts;
}

@ -56,6 +56,8 @@ sub svg_pdf {
my $cmd = 'rsvg-convert';
my $cmd_full = $cmd.' '.join(' ', @cmd_args);
$c and $c->log->debug( $cmd_full );
print $cmd_full.";\n";
$$pdf_ref = capturex([0], $cmd, @cmd_args);
return 1;
}
@ -64,7 +66,8 @@ sub preprocess_svg {
my($svg_ref) = @_;
$$svg_ref=~s/(?:{\s*)?<!--{|}-->(?:\s*})?//gs;
$$svg_ref = '<root>'.$$svg_ref.'</root>';
my $xp = XML::XPath->new($$svg_ref);
my $g = $xp->find('//g[@class="page"]');
@ -75,9 +78,10 @@ sub preprocess_svg {
}
$$svg_ref = ($xp->findnodes('/'))[0]->toString();
$$svg_ref =~s/^<root>|<\/root>$//;
$$svg_ref=~s/<(g .*?)(?:display\s*=\s*["']*none["'[:blank:]]+)(.*?id *=["' ]+page[^"' ]*["' ]+)([^>]*)>/<$1$2$3>/gs;
$$svg_ref=~s/<(g .*?)(id *=["' ]+page[^"' ]*["' ]+.*?)(?:display\s*=\s*["']*none["'[:blank:]]+)([^>]*)>/<$1$2$3>/gs;
#$$svg_ref=~s/<(g .*?)(?:display\s*=\s*["']*none["'[:blank:]]+)(.*?id *=["' ]+page[^"' ]*["' ]+)([^>]*)>/<$1$2$3>/gs;
#$$svg_ref=~s/<(g .*?)(id *=["' ]+page[^"' ]*["' ]+.*?)(?:display\s*=\s*["']*none["'[:blank:]]+)([^>]*)>/<$1$2$3>/gs;
}
sub sanitize_svg {

@ -99,7 +99,7 @@
<text text-anchor="end" x="190mm" y="171mm" font-family="Verdana" font-size="8pt" font-weight="bold">Total Price in [% cur %]</text>
<line x1="22mm" y1="173mm" x2="190mm" y2="173mm" style="stroke:#000000;stroke-width:0.2mm;" />
<!--{ [% zonelist(fontfamily='Verdana', fontsize=8, startx=22, starty=179, offsety=5, miny=40, maxy=250, zones=zones.data, fields=[{name='zone',dx=0},{name='number',dx=78,anchor='end'},{name='duration',dx=35,timestamp2time=1,anchor='end'},{name='cost',dx=55,money_cents=1,comma='.',anchor='end'}]) -%] }-->
<!--{ [% zonelist(fontfamily='Verdana', fontsize=8, startx=22, starty=179, offsety=5, miny=40, maxy=250, zones=zones.data, fields=[{name='zone',dx=0},{name='number',dx=78,anchor='end'},{name='duration',dx=35,timestamp2time=1,anchor='end'},{name='customercost',dx=55,money_cents=1,comma='.',anchor='end'}]) -%] }-->
<!-- firsty-180 means the first y in the group is at 180mm; mandatory to automatically place the footer after the list -->
<g class="list-footer firsty-180 lasty-[% aux.lasty %]">

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

@ -162,12 +162,11 @@ sub get_billing_profile{
}
sub get_invoice_data_raw{
my($client_contract, $stime, $etime) = @_;
my $invoice_details_calls = $dbh->selectall_arrayref('select cdr.*,from_unixtime(cdr.start_time) as start_time,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
LEFT JOIN billing.billing_zones_history bzh ON bzh.bz_id = cdr.source_customer_billing_zone_id
where
cdr.source_user_id != 0
cdr.source_user_id != "0"
and cdr.call_status="ok"
and cdr.source_account_id=?
and cdr.start_time >= ?
@ -177,11 +176,11 @@ sub get_invoice_data_raw{
, { 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
my $invoice_details_zones = $dbh->selectall_arrayref('select SUM(cdr.source_customer_cost) AS customercost, 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
LEFT JOIN billing.billing_zones_history bzh ON bzh.bz_id = cdr.source_customer_billing_zone_id
where
cdr.source_user_id != 0
cdr.source_user_id != "0"
and cdr.call_status="ok"
and cdr.source_account_id=?
and cdr.start_time >= ?

Loading…
Cancel
Save