diff --git a/lib/NGCP/Panel/Controller/Invoice.pm b/lib/NGCP/Panel/Controller/Invoice.pm index 82b377c768..b9f0b5c9de 100644 --- a/lib/NGCP/Panel/Controller/Invoice.pm +++ b/lib/NGCP/Panel/Controller/Invoice.pm @@ -91,15 +91,19 @@ sub base :Chained('invoice') :PathPart('') :CaptureArgs(1) { sub invoice_details_zones :Chained('base') :PathPart('') :CaptureArgs(0) { my ($self, $c) = @_; $c->log->debug('invoice_details_zones'); + my($validator,$backend,$in,$out); + $backend = NGCP::Panel::Model::DB::InvoiceTemplate->new( schema => $c->model('DB') ); my $provider_id = $c->stash->{provider}->id; + my $client_id = $c->stash->{client} ? $c->stash->{client}->id : undef; my $stime = NGCP::Panel::Utils::DateTime::current_local()->truncate(to => 'month'); my $etime = $stime->clone->add(months => 1); #look, NGCP::Panel::Utils::Contract - it is kind of backend separation here #my $form = NGCP::Panel::Form::InvoiceTemplate::Basic->new( ); - my $invoice_details_zones = NGCP::Panel::Utils::Contract::get_contract_zonesfees_rs( + my $invoice_details_zones = $backend->get_contract_zonesfees_rs( c => $c, provider_id => $provider_id, + client_id => $client_id, stime => $stime, etime => $etime, ); @@ -115,15 +119,18 @@ sub invoice_details_zones :Chained('base') :PathPart('') :CaptureArgs(0) { sub invoice_details_calls :Chained('invoice_details_zones') :PathPart('') :CaptureArgs(0) { my ($self, $c) = @_; $c->log->debug('invoice_details_calls'); + my $backend = NGCP::Panel::Model::DB::InvoiceTemplate->new( schema => $c->model('DB') ); my $provider_id = $c->stash->{provider}->id; + my $client_id = $c->stash->{client} ? $c->stash->{client}->id : undef; my $stime = NGCP::Panel::Utils::DateTime::current_local()->truncate(to => 'month'); my $etime = $stime->clone->add(months => 1); #look, NGCP::Panel::Utils::Contract - it is kind of backend separation here #my $form = NGCP::Panel::Form::InvoiceTemplate::Basic->new( ); - my $invoice_details_calls = NGCP::Panel::Utils::Contract::get_contract_calls_rs( + my $invoice_details_calls = $backend->get_contract_calls_rs( c => $c, provider_id => $provider_id, + client_id => $client_id, stime => $stime, etime => $etime, ); @@ -147,7 +154,12 @@ sub invoice_details_calls :Chained('invoice_details_zones') :PathPart('') :Captu sub invoice_list :Chained('invoice_details_calls') :PathPart('list') :Args(0) { my ($self, $c) = @_; - $c->stash( template => 'invoice/list.tt' ); + my $backend = NGCP::Panel::Model::DB::InvoiceTemplate->new( schema => $c->model('DB') ); + $c->forward( 'template_list_data' ); + $c->stash( + client_contacts_list => $backend->getInvoiceProviderClients( provider_id => $provider_id ), + template => 'invoice/list.tt', + ); } sub template_base :Chained('base') :PathPart('template') :CaptureArgs(0) { @@ -156,13 +168,13 @@ sub template_base :Chained('base') :PathPart('template') :CaptureArgs(0) { $backend = NGCP::Panel::Model::DB::InvoiceTemplate->new( schema => $c->model('DB') ); $c->log->debug('template_base'); $c->forward( 'template_list_data' ); - my $client_id = $c->stash->{client} ? $c->stash->{client}->id : undef ; - my $client; - if($client_id){ - $client = $backend->getClient($client_id); - }else{ - #$c->stash->{provider}->id; - } + #my $client_id = $c->stash->{client} ? $c->stash->{client}->id : undef ; + #my $client; + #if($client_id){ + # $client = $backend->getClient($client_id); + #}else{ + # #$c->stash->{provider}->id; + #} #$c->stash( provider => $c->stash->{reseller}->first ); } @@ -180,11 +192,9 @@ sub template_info :Chained('template_base') :PathPart('info') :Args(0) { if($in->{tt_id}){ #always was sure that i'm calm and even friendly person, but I would kill with pleasure author of dbix. my $db_object; - ($out->{tt_id},undef,$db_object) = $backend->getCustomerInvoiceTemplate( %$in ); + ($out->{tt_id},undef,$db_object) = $backend->getInvoiceTemplate( %$in ); $out->{tt_data}->{tt_id} = $db_object->get_column('id'); - if(!$c->stash->{provider}){ - - } + $out->{tt_data}->{provider_id} = $db_object->get_column('reseller_id'); foreach(qw/name is_active/){$out->{tt_data}->{$_} = $db_object->get_column($_);} } if(!$out->{tt_data}){ @@ -295,9 +305,9 @@ sub template_activate :Chained('template_base') :PathPart('activate') :Args(2) { $in = $in_validated; #think about it more if( ! $in->{is_active} ){ - $backend->activateCustomerInvoiceTemplate(%$in); + $backend->activateInvoiceTemplate(%$in); }else{ - $backend->deactivateCustomerInvoiceTemplate(%$in); + $backend->deactivateInvoiceTemplate(%$in); } $c->flash(messages => [{type => 'success', text => $c->loc( $in->{is_active} @@ -354,7 +364,7 @@ sub template_delete :Chained('template_base') :PathPart('delete') :Args(1) { $in = $in_validated; #think about it more - $backend->deleteCustomerInvoiceTemplate(%$in); + $backend->deleteInvoiceTemplate(%$in); $c->flash(messages => [{type => 'success', text => $c->loc( 'Invoice template deleted' ) }]); @@ -367,7 +377,7 @@ sub template_list_data :Chained('base') :PathPart('') :CaptureArgs(0) { my($validator,$backend,$in,$out); $in->{provider_id} = $c->stash->{provider}->id; $backend = NGCP::Panel::Model::DB::InvoiceTemplate->new( schema => $c->model('DB') ); - my $records = $backend->getCustomerInvoiceTemplateList( %$in ); + my $records = [$backend->getInvoiceTemplateList( %$in )->all]; $c->stash( template_list => $records ); } sub template_list :Chained('template_base') :PathPart('list') :Args(0) { @@ -437,7 +447,7 @@ sub template_view :Chained('template_base') :PathPart('view') :Args { if(!$in->{tt_string} && !$tt_string_force_default){ #here we also may be better should contact model, not DB directly. Will return to this separation later #at the end - we can figure out rather basic controller behaviour - ($out->{tt_id},undef,$out->{tt_data}) = $backend->getCustomerInvoiceTemplate( %$in, result => \$tt_string_customer ); + ($out->{tt_id},undef,$out->{tt_data}) = $backend->getInvoiceTemplate( %$in, result => \$tt_string_customer ); if($out->{tt_data}){ $out->{json} = { @@ -481,7 +491,7 @@ sub template_view :Chained('template_base') :PathPart('view') :Args { } #/sanitize - to sub, later - my($tt_stored) = $backend->storeCustomerInvoiceTemplate( + my($tt_stored) = $backend->storeInvoiceTemplateContent( %$in, tt_string_sanitized => \$tt_string_sanitized, ); diff --git a/lib/NGCP/Panel/Model/DB/InvoiceTemplate.pm b/lib/NGCP/Panel/Model/DB/InvoiceTemplate.pm index a9e3f6dcc1..79e74625c6 100644 --- a/lib/NGCP/Panel/Model/DB/InvoiceTemplate.pm +++ b/lib/NGCP/Panel/Model/DB/InvoiceTemplate.pm @@ -22,12 +22,12 @@ sub getDefaultConditions{ } return $conditions; } -sub getCustomerInvoiceTemplate{ +sub getInvoiceTemplate{ my $self = shift; my (%params) = @_; my ($provider_id,$tt_sourcestate,$tt_type,$tt_id) = @params{qw/provider_id tt_sourcestate tt_type tt_id/}; - #irka::loglong("getCustomerInvoiceTemplate: tt_id=$tt_id;\n"); + #irka::loglong("getInvoiceTemplate: tt_id=$tt_id;\n"); #irka::loglong(Dumper(\%params)); my $result = ''; @@ -61,7 +61,7 @@ sub getCustomerInvoiceTemplate{ return ( $tt_id, \$result, $tt_record );#tt_record - sgorila hata, gori i saray } -sub storeCustomerInvoiceTemplate{ +sub storeInvoiceTemplateContent{ my $self = shift; my (%params) = @_; my ($provider_id, $tt_sourcestate, $tt_type,$tt_string,$tt_id,$is_active,$name) = @params{qw/provider_id tt_sourcestate tt_type tt_string_sanitized tt_id is_active name/}; @@ -145,7 +145,7 @@ sub storeInvoiceTemplateInfo{ }); return { tt_id => $tt_id }; } -sub getCustomerInvoiceTemplateList{ +sub getInvoiceTemplateList{ my $self = shift; my (%params) = @_; my ($provider_id,$tt_sourcestate,$tt_type, $tt_string, $tt_id) = @params{qw/provider_id tt_sourcestate tt_type tt_string_sanitized tt_id/}; @@ -154,11 +154,11 @@ sub getCustomerInvoiceTemplateList{ #$self->schema->resultset('invoice_template_fake')->find(\'select * from invoice_templates')->all #$self->schema->resultset('invoice_templates')->name(\'(select * from invoice_templates)')->all #]; - return [ $self->schema->resultset('invoice_templates')->search({ + return $self->schema->resultset('invoice_templates')->search({ reseller_id => $provider_id, - })->all ]; + }); } -sub deleteCustomerInvoiceTemplate{ +sub deleteInvoiceTemplate{ my $self = shift; my (%params) = @_; my ($provider_id, $tt_id) = @params{qw/provider_id tt_id/}; @@ -167,7 +167,7 @@ sub deleteCustomerInvoiceTemplate{ id => $tt_id, })->delete_all; } -sub activateCustomerInvoiceTemplate{ +sub activateInvoiceTemplate{ my $self = shift; my (%params) = @_; my ($provider_id, $tt_id) = @params{qw/provider_id tt_id/}; @@ -181,7 +181,7 @@ sub activateCustomerInvoiceTemplate{ $self->deactivateOtherTemplates($provider_id,$tt_id); }); } -sub deactivateCustomerInvoiceTemplate{ +sub deactivateInvoiceTemplate{ my $self = shift; my (%params) = @_; my ($provider_id, $tt_id) = @params{qw/provider_id tt_id/}; @@ -205,7 +205,7 @@ sub deactivateOtherTemplates{ is_active => 0, }); } -sub checkCustomerInvoiceTemplateContract{ +sub checkInvoiceTemplateProvider{ my $self = shift; my (%params) = @_; my ($provider_id,$tt_id) = @params{qw/provider_id tt_id/}; @@ -219,7 +219,7 @@ sub checkCustomerInvoiceTemplateContract{ return 0; } -sub getInvoiceClient{ +sub getInvoiceClientContactInfo{ my $self = shift; my (%params) = @_; my ($client_id) = @params{qw/client_id/}; @@ -227,18 +227,154 @@ sub getInvoiceClient{ reseller_id => $client_id, }); } + 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', - }); + + #return NGCP::Panel::Utils::Contract::get_contract_rs( + # schema => $self->schema, + # )->search_rs({ + # 'contact.reseller_id' => $provider_id, + # },{ + # join => 'contact', + #}); + return $self->schema->resultset('contacts')->search_rs({},{}); +} + +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 $source_account_id_condition; + if(!$client_id){ + $source_account_id_condition = { 'in' => $self->getInvoiceProviderClients(%params)->search_rs({},{ + 'select' => 'me.id', + })->as_query() }; + }else{ + $source_account_id_condition = $client_id; + } + my $zonecalls_rs = $self->schema->resultset('cdr')->search( { +# source_user_id => { 'in' => [ map {$_->uuid} @{$contract->{subscriber}} ] }, + call_status => 'ok', + source_user_id => { '!=' => '0' }, + + #source_account_id => $source_account_id_condition, + #-or => [ + # source_user_id => voip_subscribers.uuid, + # destination_user_id => voip_subscribers.uuid, + #], + #start_time => + # [ -and => + # { '>=' => $stime->epoch}, + # { '<=' => $etime->epoch}, + # ], + },{ + '+select' => [ + 'source_customer_billing_zones_history.zone', + 'source_customer_billing_zones_history.detail', + 'destination_user_in', + ], + '+as' => [qw/zone zone_detail destination/], + 'join' => ['source_customer_billing_zones_history','contracts'], + 'rows' => 37, + } ); + + return $zonecalls_rs; +} +sub get_contract_zonesfees_rs { + my $self = shift; + my %params = @_; + (my ($c,$provider_id,$client_id,$stime,$etime)) = @params{qw/c provider_id client_id stime etime/}; + my $source_account_id_condition; + if(!$client_id){ + $source_account_id_condition = { 'in' => $self->getInvoiceProviderClients(%params)->search_rs({},{ + 'select' => 'me.id', + })->as_query() }; + }else{ + $source_account_id_condition = $client_id; + } + + # SELECT 'out' as direction, SUM(c.source_customer_cost) AS cost, b.zone, + # COUNT(*) AS number, SUM(c.duration) AS duration + # FROM accounting.cdr c + # LEFT JOIN billing.voip_subscribers v ON c.source_user_id = v.uuid + # LEFT JOIN billing.billing_zones_history b ON b.id = c.source_customer_billing_zone_id + # WHERE v.contract_id = ? + # AND c.call_status = 'ok' + # $start_time $end_time + # GROUP BY b.zone + + my $zonecalls_rs = $self->schema->resultset('cdr')->search( { +# source_user_id => { 'in' => [ map {$_->uuid} @{$contract->{subscriber}} ] }, + call_status => 'ok', + source_user_id => { '!=' => '0' }, + source_account_id => $source_account_id_condition, + # start_time => + # [ -and => + # { '>=' => $stime->epoch}, + # { '<=' => $etime->epoch}, + # ], + + },{ + '+select' => [ + { sum => 'me.source_customer_cost', -as => 'cost', }, + { sum => 'me.source_customer_free_time', -as => 'free_time', } , + { sum => 'me.duration', -as => 'duration', } , + { count => '*', -as => 'number', } , + 'source_customer_billing_zones_history.zone', + 'source_customer_billing_zones_history.detail', + ], + '+as' => [qw/cost free_time duration number zone zone_detail/], + #alias => + join => 'source_customer_billing_zones_history', + group_by => 'source_customer_billing_zones_history.zone', + #order_by => 'source_customer_billing_zones_history.zone', + } ); + + return $zonecalls_rs; } + 1; \ No newline at end of file diff --git a/lib/NGCP/Panel/Utils/Contract.pm b/lib/NGCP/Panel/Utils/Contract.pm index 2212e45a72..16c88c1ab9 100644 --- a/lib/NGCP/Panel/Utils/Contract.pm +++ b/lib/NGCP/Panel/Utils/Contract.pm @@ -324,7 +324,6 @@ sub get_contract_zonesfees_rs { { '<=' => $etime->epoch}, ], source_account_id => $contract_id, - },{ 'select' => [ { sum => 'me.source_customer_cost', -as => 'customercost' }, { sum => 'me.source_carrier_cost', -as => 'carriercost' }, @@ -366,7 +365,6 @@ sub get_contract_zonesfees_rs { } ); return ($zonecalls_rs_in, $zonecalls_rs_out); -} sub get_contract_zonesfees { diff --git a/share/templates/invoice/list.tt b/share/templates/invoice/list.tt index 18f9bbf74d..752b133188 100644 --- a/share/templates/invoice/list.tt +++ b/share/templates/invoice/list.tt @@ -13,6 +13,9 @@ [% c.loc('Back') %] + + [% c.loc('Invoice Template')%] + [% IF reseller.first.status != "active" -%] diff --git a/share/templates/invoice/template.tt b/share/templates/invoice/template.tt index 882fc81179..30017f3ce3 100644 --- a/share/templates/invoice/template.tt +++ b/share/templates/invoice/template.tt @@ -68,7 +68,7 @@ var uriForAction = function( data, type ){ [% c.loc('Create invoices template')%] - [% c.loc('Create invoices template')%] + [% c.loc('Invoices')%] @@ -83,106 +83,16 @@ var uriForAction = function( data, type ){
[% back_created = 1 -%] -
- -
- - -
-
- - -[% - clearHelper(); - helper.name = c.loc('Invoice Connection Fees'); - helper.dt_columns = [ - { name => 'source_customer_billing_zones_history.zone', title => c.loc('Zone'), search=> 1 }, - { name => 'number', title => c.loc('Calls') }, - { name => 'duration', title => c.loc('Usage') }, - { name => 'free_time', title => c.loc('Free time') }, - { name => 'cost', title => c.loc('Amount EUR') }, - ]; - helper.name_single = c.loc('Invoice Connections Records'); - helper.identifier = 'invoice_details_zones_ajax'; - helper.ajax_uri = c.uri_for_action( '/invoice/ajax_datatables_data', [ provider.id, 'invoice_details_zones' ] ) ; - initHelperAuto(); - PROCESS 'helpers/datatables.tt'; --%] - [%PROCESS 'invoice/invoice_details_zones_list.tt' %] - -
-
+
+[%PROCESS 'invoice/template_list.tt' %]
-
- - -
-
- - -[% - clearHelper(); - helper.name = c.loc('Invoice Calls'); - helper.dt_columns = [ - { name => 'start_time', title => c.loc('Start time'), search_from_epoch => 1, search_to_epoch=>1 }, - { name => 'duration', title => c.loc('Duration') }, - { name => 'destination_user', title => c.loc('Destination'), search => 1 }, - { name => 'call_type', title => c.loc('Type'), search => 1 }, - { name => 'source_customer_billing_zones_history.zone', title => c.loc('Zone'), search=> 1 }, - { name => 'source_customer_cost', title => c.loc('Amount EUR') }, - ]; - helper.name_single = c.loc('Invoice calls'); - helper.identifier = 'invoice_details_calls_ajax'; - helper.ajax_uri = c.uri_for_action( '/invoice/ajax_datatables_data', [ provider.id, 'invoice_details_calls' ] ) ; - initHelperAuto(); - PROCESS 'helpers/datatables.tt'; --%] - [%PROCESS 'invoice/invoice_details_calls_list.tt' %] - -
-
-
- - - -
- -
-
- [%PROCESS 'invoice/template_list.tt' %] -
-
-
-
-
-
diff --git a/share/templates/reseller/details.tt b/share/templates/reseller/details.tt index fe219576c9..080485d5bd 100644 --- a/share/templates/reseller/details.tt +++ b/share/templates/reseller/details.tt @@ -4,9 +4,12 @@ [% c.loc('Back') %] - - [% c.loc('Invoice Template')%] - + + [% c.loc('Invoice Template')%] + + + [% c.loc('Invoices')%] +
[% back_created = 1 -%]