diff --git a/lib/NGCP/BulkProcessor/Calendar.pm b/lib/NGCP/BulkProcessor/Calendar.pm index aa953bc0..8ee54f20 100755 --- a/lib/NGCP/BulkProcessor/Calendar.pm +++ b/lib/NGCP/BulkProcessor/Calendar.pm @@ -34,6 +34,7 @@ our @EXPORT_OK = qw( datetime_from_string set_timezone current_local + from_epoch ); my $is_fake_time = 0; @@ -79,6 +80,12 @@ sub _current_local { } } +sub from_epoch { + my ($time,$tz) = @_; + $tz //= $LOCAL; + return DateTime->from_epoch(epoch => $time, time_zone => $tz); +} + sub current_local { return DateTime->now(time_zone => $LOCAL); } diff --git a/lib/NGCP/BulkProcessor/Dao/Trunk/accounting/cdr.pm b/lib/NGCP/BulkProcessor/Dao/Trunk/accounting/cdr.pm index 27ec2dce..9a2f803c 100755 --- a/lib/NGCP/BulkProcessor/Dao/Trunk/accounting/cdr.pm +++ b/lib/NGCP/BulkProcessor/Dao/Trunk/accounting/cdr.pm @@ -43,6 +43,8 @@ our @EXPORT_OK = qw( get_callidprefix + $OK_CALL_STATUS + ); #process_records #delete_ids @@ -140,11 +142,13 @@ my $expected_fieldnames = [ ]; my @callid_suffixes = (); -our $PBXSUFFIX = '_pbx-1'; +my $PBXSUFFIX = '_pbx-1'; push(@callid_suffixes,$PBXSUFFIX); -our $XFERSUFFIX = '_xfer-1'; +my $XFERSUFFIX = '_xfer-1'; push(@callid_suffixes,$XFERSUFFIX); +our $OK_CALL_STATUS = 'ok'; + my $indexes = {}; my $insert_unique_fields = []; diff --git a/lib/NGCP/BulkProcessor/Dao/Trunk/accounting/cdr_export_status_data.pm b/lib/NGCP/BulkProcessor/Dao/Trunk/accounting/cdr_export_status_data.pm index cf8bbb33..e7c669fb 100644 --- a/lib/NGCP/BulkProcessor/Dao/Trunk/accounting/cdr_export_status_data.pm +++ b/lib/NGCP/BulkProcessor/Dao/Trunk/accounting/cdr_export_status_data.pm @@ -181,11 +181,11 @@ sub update_export_status { ' WHERE ' . $db->columnidentifier('status_id') . ' = ? AND ' . $db->columnidentifier('export_status') . ' != ?'; my @params = ($export_status,$status_id,$export_status); if (defined $start_time_from) { - $stmt .= ' AND ' . $db->columnidentifier('start_time') . ' >= UNIX_TIMESTAMP(?)'; + $stmt .= ' AND ' . $db->columnidentifier('cdr_start_time') . ' >= UNIX_TIMESTAMP(?)'; push(@params,$start_time_from); } if (defined $start_time_to) { - $stmt .= ' AND ' . $db->columnidentifier('start_time') . ' < UNIX_TIMESTAMP(?)'; + $stmt .= ' AND ' . $db->columnidentifier('cdr_start_time') . ' < UNIX_TIMESTAMP(?)'; push(@params,$start_time_to); } diff --git a/lib/NGCP/BulkProcessor/Dao/Trunk/provisioning/voip_dbaliases.pm b/lib/NGCP/BulkProcessor/Dao/Trunk/provisioning/voip_dbaliases.pm index cc6b7d12..fa70783e 100755 --- a/lib/NGCP/BulkProcessor/Dao/Trunk/provisioning/voip_dbaliases.pm +++ b/lib/NGCP/BulkProcessor/Dao/Trunk/provisioning/voip_dbaliases.pm @@ -118,7 +118,7 @@ sub findby_subscriberidisprimary { my @params = ($subscriber_id,$is_primary); my $rows = $db->db_get_all_arrayref($stmt,@params); - return buildrecords_fromrows($rows,$load_recursive)->[0]; + return buildrecords_fromrows($rows,$load_recursive); } diff --git a/lib/NGCP/BulkProcessor/Projects/Disaster/Balances/Contracts.pm b/lib/NGCP/BulkProcessor/Projects/Disaster/Balances/Contracts.pm index 1ad613d9..7a65074d 100755 --- a/lib/NGCP/BulkProcessor/Projects/Disaster/Balances/Contracts.pm +++ b/lib/NGCP/BulkProcessor/Projects/Disaster/Balances/Contracts.pm @@ -76,7 +76,7 @@ our @EXPORT_OK = qw( fix_free_cash ); -my $create_sample_cdr = 0; +my $create_sample_cdr = 0; sub fix_contract_balance_gaps { @@ -539,7 +539,7 @@ sub _generate_cdr_init_context { $source_subscriber->{contract} = NGCP::BulkProcessor::Dao::Trunk::billing::contracts::findby_id($source_subscriber->{contract_id}); $source_subscriber->{contract}->{contact} = NGCP::BulkProcessor::Dao::Trunk::billing::contacts::findby_id($source_subscriber->{contract}->{contact_id}); $source_subscriber->{contract}->{prov_subscriber} = NGCP::BulkProcessor::Dao::Trunk::provisioning::voip_subscribers::findby_uuid(undef,$source_subscriber->{uuid}); - $source_subscriber->{primary_alias} = NGCP::BulkProcessor::Dao::Trunk::provisioning::voip_dbaliases::findby_subscriberidisprimary($source_subscriber->{contract}->{prov_subscriber}->{id},1); + $source_subscriber->{primary_alias} = NGCP::BulkProcessor::Dao::Trunk::provisioning::voip_dbaliases::findby_subscriberidisprimary($source_subscriber->{contract}->{prov_subscriber}->{id},1)->[0]; $source_subscriber->{domain} = $context->{domain_map}->{$source_subscriber->{domain_id}}->{domain}; $source_reseller = $context->{reseller_map}->{$source_subscriber->{contract}->{contact}->{reseller_id}}; } else { @@ -552,7 +552,7 @@ sub _generate_cdr_init_context { $dest_subscriber->{contract} = NGCP::BulkProcessor::Dao::Trunk::billing::contracts::findby_id($dest_subscriber->{contract_id}); $dest_subscriber->{contract}->{contact} = NGCP::BulkProcessor::Dao::Trunk::billing::contacts::findby_id($dest_subscriber->{contract}->{contact_id}); $dest_subscriber->{contract}->{prov_subscriber} = NGCP::BulkProcessor::Dao::Trunk::provisioning::voip_subscribers::findby_uuid(undef,$dest_subscriber->{uuid}); - $dest_subscriber->{primary_alias} = NGCP::BulkProcessor::Dao::Trunk::provisioning::voip_dbaliases::findby_subscriberidisprimary($dest_subscriber->{contract}->{prov_subscriber}->{id},1); + $dest_subscriber->{primary_alias} = NGCP::BulkProcessor::Dao::Trunk::provisioning::voip_dbaliases::findby_subscriberidisprimary($dest_subscriber->{contract}->{prov_subscriber}->{id},1)->[0]; $dest_subscriber->{domain} = $context->{domain_map}->{$dest_subscriber->{domain_id}}->{domain}; $dest_reseller = $context->{reseller_map}->{$dest_subscriber->{contract}->{contact}->{reseller_id}}; } else { diff --git a/lib/NGCP/BulkProcessor/Projects/Export/Ama/Ccs/CDR.pm b/lib/NGCP/BulkProcessor/Projects/Export/Ama/Ccs/CDR.pm index 88c27538..7c26538d 100644 --- a/lib/NGCP/BulkProcessor/Projects/Export/Ama/Ccs/CDR.pm +++ b/lib/NGCP/BulkProcessor/Projects/Export/Ama/Ccs/CDR.pm @@ -17,6 +17,13 @@ use NGCP::BulkProcessor::Projects::Export::Ama::Ccs::Settings qw( $export_cdr_limit $export_cdr_stream $export_cdr_rollover_fsn + + $ama_sensor_id + $ama_recording_office_id + $ama_incoming_trunk_group_number + $ama_outgoing_trunk_group_number + $ama_originating_digits_cdr_field + $ama_terminating_digits_cdr_field ); use NGCP::BulkProcessor::Logging qw ( @@ -35,6 +42,9 @@ use NGCP::BulkProcessor::Dao::Trunk::accounting::cdr_export_status qw(); use NGCP::BulkProcessor::Dao::Trunk::accounting::cdr_export_status_data qw(); use NGCP::BulkProcessor::Dao::Trunk::accounting::mark qw(); +use NGCP::BulkProcessor::Dao::Trunk::provisioning::voip_subscribers qw(); +use NGCP::BulkProcessor::Dao::Trunk::provisioning::voip_dbaliases qw(); + use NGCP::BulkProcessor::Projects::Export::Ama::Format::File qw(); use NGCP::BulkProcessor::Projects::Export::Ama::Format::Record qw(); use NGCP::BulkProcessor::Projects::Export::Ama::Format::Structures::Structure0510 qw(); @@ -66,7 +76,7 @@ use NGCP::BulkProcessor::ConnectorPool qw( use NGCP::BulkProcessor::Utils qw(threadid kbytes2gigs); # stringtobool check_ipnet trim); -use NGCP::BulkProcessor::Calendar qw(current_local); +use NGCP::BulkProcessor::Calendar qw(from_epoch); require Exporter; our @ISA = qw(Exporter); @@ -76,6 +86,8 @@ our @EXPORT_OK = qw( reset_export_status ); +my $DIRECT_FORWARDER_SCENARIO = 1; + my $file_sequence_number : shared = 0; my $rowcount : shared = 0; @@ -274,6 +286,8 @@ sub _export_cdrs_init_context { my $result = 0; $context->{cdrs} = []; $context->{call_id} = $call_id; + my $scenario = { code => 0, }; + $context->{scenario} = $scenario; if (not exists $context->{file_cdr_id_map}->{$cdr_id}) { my $call_id_prefix = NGCP::BulkProcessor::Dao::Trunk::accounting::cdr::get_callidprefix($call_id); @@ -285,10 +299,13 @@ sub _export_cdrs_init_context { if ((scalar @{$context->{cdrs}}) == 2 and not $context->{cdrs}->[0]->is_xfer() and $context->{cdrs}->[1]->is_xfer() + and ($scenario->{ccs_subscriber} = NGCP::BulkProcessor::Dao::Trunk::provisioning::voip_subscribers::findby_uuid(undef,$context->{cdrs}->[0]->{destination_user_id})) + and ($scenario->{ccs_subscriber}->{primary_alias} = NGCP::BulkProcessor::Dao::Trunk::provisioning::voip_dbaliases::findby_subscriberidisprimary($scenario->{ccs_subscriber}->{id},1)->[0]) ) { + $scenario->{code} = $DIRECT_FORWARDER_SCENARIO; $result = 1; - } else { - print "blah"; + #} else { + # print "blah"; } foreach my $cdr (@{$context->{cdrs}}) { if ($result) { @@ -304,12 +321,19 @@ sub _export_cdrs_init_context { } } - # todo: prepare the fields from the call's CDRs: - - $context->{dt} = current_local(); - $context->{source} = "43011001"; - $context->{destination} = "43011002"; - $context->{duration} = 123.456; + if ($scenario->{code} == $DIRECT_FORWARDER_SCENARIO) { + $scenario->{start_time} = $context->{cdrs}->[0]->{start_time}; + $scenario->{duration} = $context->{cdrs}->[0]->{duration}; + $scenario->{originating} = $context->{cdrs}->[0]->{$ama_originating_digits_cdr_field}; + $scenario->{terminating} = $context->{cdrs}->[1]->{$ama_terminating_digits_cdr_field}; + $scenario->{unanswered} = ($context->{cdrs}->[1]->{call_status} != $NGCP::BulkProcessor::Dao::Trunk::accounting::cdr::OK_CALL_STATUS ? 1 : 0); + $scenario->{correlation_id} = substr($context->{cdrs}->[0]->{id},-7); + $scenario->{nod} = { + originating_digits => $scenario->{originating}, + switch_number_digits => $scenario->{ccs_subscriber}->{primary_alias}->{username}, + mode => '0001', + }; + } return $result; @@ -385,16 +409,13 @@ sub _get_transfer_in { NGCP::BulkProcessor::Projects::Export::Ama::Format::Structures::Structure9013->new( rewritten => 0, - sensor_id => '438716', # Graz + sensor_id => $ama_sensor_id, padding => 0, - recording_office_id => '438716', - - date => NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::Date::get_ama_date($context->{dt}), - - connect_time => NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::ConnectTime::get_connect_time($context->{dt}), # adjacent + recording_office_id => $ama_recording_office_id, - dt => $context->{dt}, + #date => NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::Date::get_ama_date($context->{dt_transfer_in}), + #connect_time => NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::ConnectTime::get_connect_time($context->{dt_transfer_in}), # adjacent? file_sequence_number => $context->{file_sequence_number}, ) @@ -410,65 +431,72 @@ sub _get_record { ) = @params{qw/ context /}; - return NGCP::BulkProcessor::Projects::Export::Ama::Format::Record->new( - NGCP::BulkProcessor::Projects::Export::Ama::Format::Structures::Structure0510->new( - call_type => $NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::CallType::STATION_PAID, - - rewritten => 0, - sensor_id => '438716', # Graz - padding => 0, - recording_office_id => '438716', #008708 - - call_type => '970', - #call code 970c - #timing ind 000 - #seervice observed 0c - - #called party off-hook setzen - #unanswered => - - date => NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::Date::get_ama_date($context->{dt}), - - service_feature => $NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::ServiceFeature::OTHER, -#mit 43 - originating_significant_digits => NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::SignificantDigitsNextField::get_number_length($context->{source}), - originating_open_digits_1 => NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::SignificantDigitsNextField::get_number_digits_1($context->{source}), - originating_open_digits_2 => NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::SignificantDigitsNextField::get_number_digits_2($context->{source}), - - domestic_international => $NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::DomesticInternational::INTERNATIONAL, #get_number_domestic_international($context->{destination}), - -#2c -#destination number mit 43 -#dialed_in , 0er wegstreichen - terminating_significant_digits => NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::SignificantDigitsNextField::get_number_length($context->{destination}), - terminating_open_digits_1 => NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::SignificantDigitsNextField::get_number_digits_1($context->{destination}), - terminating_open_digits_2 => NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::SignificantDigitsNextField::get_number_digits_2($context->{destination}), - - connect_time => NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::ConnectTime::get_connect_time($context->{dt}), - elapsed_time => NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::ElapsedTime::get_elapsed_time($context->{duration}), - ), - NGCP::BulkProcessor::Projects::Export::Ama::Format::Modules::Module611->new( - generic_context_identifier => $NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::GenericContextIdentifier::IN_CORRELATION_ID, - parsing_rules => '7', - additional_digits_dialed => ((scalar @{$context->{cdrs}}) > 0 ? substr($context->{cdrs}->[0]->{id},-7) : undef), - ), - NGCP::BulkProcessor::Projects::Export::Ama::Format::Modules::Module199->new( - network_operator_data => NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::NetworkOperatorData::get_network_operator_data($context->{source},'123456'), - ), - NGCP::BulkProcessor::Projects::Export::Ama::Format::Modules::Module104->new( - direction => $NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::TrunkIdentification::INCOMING, - trunk_group_number => '2999', - trunk_member_number => '0000', - ), - NGCP::BulkProcessor::Projects::Export::Ama::Format::Modules::Module104->new( - direction => $NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::TrunkIdentification::OUTGOING, - trunk_group_number => '2014', - trunk_member_number => '0000', - ), - NGCP::BulkProcessor::Projects::Export::Ama::Format::Modules::Module000->new( - ), - ); + if ($context->{scenario}->{code} == $DIRECT_FORWARDER_SCENARIO) { + $context->{file}->update_start_end_time($context->{scenario}->{start_time},$context->{scenario}->{start_time} + $context->{scenario}->{duration}); + my $record = NGCP::BulkProcessor::Projects::Export::Ama::Format::Record->new( + NGCP::BulkProcessor::Projects::Export::Ama::Format::Structures::Structure0510->new( + call_type => $NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::CallType::STATION_PAID, + + rewritten => 0, + sensor_id => $ama_sensor_id, + + padding => 0, + recording_office_id => $ama_recording_office_id, + + call_type => '970', + #timing ind 000 + #seervice observed 0c + + unanswered => $context->{scenario}->{unanswered}, #called party off-hook setzen + + date => NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::Date::get_ama_date(from_epoch($context->{scenario}->{start_time})), + + service_feature => $NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::ServiceFeature::OTHER, + + originating_significant_digits => NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::SignificantDigitsNextField::get_number_length($context->{scenario}->{originating}), + originating_open_digits_1 => NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::SignificantDigitsNextField::get_number_digits_1($context->{scenario}->{originating}), + originating_open_digits_2 => NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::SignificantDigitsNextField::get_number_digits_2($context->{scenario}->{originating}), + + domestic_international => $NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::DomesticInternational::INTERNATIONAL, #get_number_domestic_international($context->{destination}), + + terminating_significant_digits => NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::SignificantDigitsNextField::get_number_length($context->{scenario}->{terminating}), + terminating_open_digits_1 => NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::SignificantDigitsNextField::get_number_digits_1($context->{scenario}->{terminating}), + terminating_open_digits_2 => NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::SignificantDigitsNextField::get_number_digits_2($context->{scenario}->{terminating}), + + connect_time => NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::ConnectTime::get_connect_time(from_epoch($context->{scenario}->{start_time})), + elapsed_time => NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::ElapsedTime::get_elapsed_time($context->{scenario}->{duration}), + ), + NGCP::BulkProcessor::Projects::Export::Ama::Format::Modules::Module611->new( + generic_context_identifier => $NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::GenericContextIdentifier::IN_CORRELATION_ID, + parsing_rules => $NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::GenericContextIdentifier::IN_CORRELATION_ID_PARSING_RULES, + additional_digits_dialed => $context->{scenario}->{correlation_id}, + ), + NGCP::BulkProcessor::Projects::Export::Ama::Format::Modules::Module199->new( + network_operator_data => NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::NetworkOperatorData::get_network_operator_data( + $context->{scenario}->{nod}->{originating_digits}, + $context->{scenario}->{nod}->{switch_number_digits}, + $context->{scenario}->{nod}->{mode}, + ), + ), + NGCP::BulkProcessor::Projects::Export::Ama::Format::Modules::Module104->new( + direction => $NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::TrunkIdentification::INCOMING, + trunk_group_number => $ama_incoming_trunk_group_number, + trunk_member_number => '0000', + ), + NGCP::BulkProcessor::Projects::Export::Ama::Format::Modules::Module104->new( + direction => $NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::TrunkIdentification::OUTGOING, + trunk_group_number => $ama_outgoing_trunk_group_number, + trunk_member_number => '0000', + ), + NGCP::BulkProcessor::Projects::Export::Ama::Format::Modules::Module000->new( + ), + ); + _info($context,"ama record from cdr ids " . join(', ',map { $_->{id}; } @{$context->{cdrs}}) . ':' . $record->to_string(),1); + return $record; + } else { + _error($context,"unknown scenario $context->{scenario}->{code} for cdr ids " . join(', ',map { $_->{id}; } @{$context->{cdrs}}) ); + } } @@ -480,26 +508,21 @@ sub _get_transfer_out { ) = @params{qw/ context /}; + return NGCP::BulkProcessor::Projects::Export::Ama::Format::Record->new( NGCP::BulkProcessor::Projects::Export::Ama::Format::Structures::Structure9014->new( @_, rewritten => 0, - sensor_id => '008708', # Graz + sensor_id => $ama_sensor_id, padding => 0, - recording_office_id => '008708', - - date => NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::Date::get_ama_date($context->{dt}), + recording_office_id => $ama_recording_office_id, - connect_time => NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::ConnectTime::get_connect_time($context->{dt}), + #date => NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::Date::get_ama_date($context->{dt_transfer_out}), + #connect_time => NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::ConnectTime::get_connect_time($context->{dt_transfer_out}), file_sequence_number => $context->{file_sequence_number}, - dt => $context->{dt}, - - #=> (scalar @records), - - ) ); diff --git a/lib/NGCP/BulkProcessor/Projects/Export/Ama/Ccs/Settings.pm b/lib/NGCP/BulkProcessor/Projects/Export/Ama/Ccs/Settings.pm index f331f410..2e58983f 100644 --- a/lib/NGCP/BulkProcessor/Projects/Export/Ama/Ccs/Settings.pm +++ b/lib/NGCP/BulkProcessor/Projects/Export/Ama/Ccs/Settings.pm @@ -29,6 +29,7 @@ use NGCP::BulkProcessor::LoadConfig qw( ); use NGCP::BulkProcessor::Utils qw(prompt timestampdigits); #stringtobool #format_number check_ipnet +use NGCP::BulkProcessor::Array qw(contains); require Exporter; our @ISA = qw(Exporter); @@ -53,6 +54,13 @@ our @EXPORT_OK = qw( $export_cdr_stream $export_cdr_rollover_fsn + $ama_sensor_id + $ama_recording_office_id + $ama_incoming_trunk_group_number + $ama_outgoing_trunk_group_number + $ama_originating_digits_cdr_field + $ama_terminating_digits_cdr_field + ); our $defaultconfig = 'config.cfg'; @@ -73,6 +81,13 @@ our $export_cdr_limit = undef; our $export_cdr_stream = undef; our $export_cdr_rollover_fsn = 0; +our $ama_sensor_id; +our $ama_recording_office_id; +our $ama_incoming_trunk_group_number; +our $ama_outgoing_trunk_group_number; +our $ama_originating_digits_cdr_field; +our $ama_terminating_digits_cdr_field; + sub update_settings { my ($data,$configfile) = @_; @@ -99,6 +114,20 @@ sub update_settings { $export_cdr_stream = $data->{export_cdr_stream} if exists $data->{export_cdr_stream}; $export_cdr_rollover_fsn = $data->{export_cdr_rollover_fsn} if exists $data->{export_cdr_rollover_fsn}; + $ama_sensor_id = $data->{ama_sensor_id} if exists $data->{ama_sensor_id}; + $ama_recording_office_id = $data->{ama_recording_office_id} if exists $data->{ama_recording_office_id}; + $ama_incoming_trunk_group_number = $data->{ama_incoming_trunk_group_number} if exists $data->{ama_incoming_trunk_group_number}; + $ama_outgoing_trunk_group_number = $data->{ama_outgoing_trunk_group_number} if exists $data->{ama_outgoing_trunk_group_number}; + + $ama_originating_digits_cdr_field = $data->{ama_originating_digits_cdr_field} if exists $data->{ama_originating_digits_cdr_field}; + unless (contains($ama_originating_digits_cdr_field,[qw(source_user source_user_out source_cli)])) { + configurationerror($configfile,'unknown ama_originating_digits_cdr_field',getlogger(__PACKAGE__)); + } + $ama_terminating_digits_cdr_field = $data->{ama_terminating_digits_cdr_field} if exists $data->{ama_terminating_digits_cdr_field}; + unless (contains($ama_terminating_digits_cdr_field,[qw(destination_user destination_user_out destination_user_dialed destination_user_in)])) { + configurationerror($configfile,'unknown ama_terminating_digits_cdr_field',getlogger(__PACKAGE__)); + } + return $result; } @@ -123,7 +152,7 @@ sub _parse_export_joins { my ($token,$file) = @_; my @joins = (); if (defined $token and length($token) > 0) { - foreach my $f (split_tuple($token)) { + foreach my $f (_split(\$token)) { next unless($f); $f =~ s/^\s*\{?\s*//; $f =~ s/\}\s*\}\s*$/}/; @@ -146,7 +175,7 @@ sub _parse_export_conditions { my ($token,$file) = @_; my @conditions = (); if (defined $token and length($token) > 0) { - foreach my $f (split_tuple($token)) { + foreach my $f (_split(\$token)) { next unless($f); $f =~ s/^\s*\{?\s*//; $f =~ s/\}\s*\}\s*$/}/; @@ -173,4 +202,33 @@ sub _get_numofthreads { return $_numofthreads; } +sub _split { + + my $buffer_ref = shift; + my $pos = 0; + my @tokens = (); + my $is_literal = 0; + my $token = ''; + while ($pos < length($$buffer_ref)) { + if ("'" eq substr($$buffer_ref,$pos,length("'"))) { + $is_literal = not $is_literal; + $token .= "'"; + $pos += length("'"); + } elsif ("," eq substr($$buffer_ref,$pos,length(","))) { + if ($is_literal) { + $token .= ","; + } else { + push(@tokens,$token); + $token = ''; + } + $pos += length(","); + } else { + $token .= substr($$buffer_ref,$pos,1); + $pos += 1; + } + } + push(@tokens,$token); + return @tokens; +} + 1; diff --git a/lib/NGCP/BulkProcessor/Projects/Export/Ama/Ccs/config.cfg b/lib/NGCP/BulkProcessor/Projects/Export/Ama/Ccs/config.cfg index dbf40bd7..74e277fe 100755 --- a/lib/NGCP/BulkProcessor/Projects/Export/Ama/Ccs/config.cfg +++ b/lib/NGCP/BulkProcessor/Projects/Export/Ama/Ccs/config.cfg @@ -57,7 +57,7 @@ completionemailrecipient = rkrenn@sipwise.com doneemailrecipient = ##logging: -fileloglevel = INFO +fileloglevel = DEBUG #DEBUG screenloglevel = INFO #INFO diff --git a/lib/NGCP/BulkProcessor/Projects/Export/Ama/Ccs/config.debug.cfg b/lib/NGCP/BulkProcessor/Projects/Export/Ama/Ccs/config.debug.cfg index a69f988c..9419038c 100755 --- a/lib/NGCP/BulkProcessor/Projects/Export/Ama/Ccs/config.debug.cfg +++ b/lib/NGCP/BulkProcessor/Projects/Export/Ama/Ccs/config.debug.cfg @@ -57,7 +57,7 @@ completionemailrecipient = rkrenn@sipwise.com doneemailrecipient = ##logging: -fileloglevel = INFO +fileloglevel = DEBUG #DEBUG screenloglevel = INFO #INFO diff --git a/lib/NGCP/BulkProcessor/Projects/Export/Ama/Ccs/settings.cfg b/lib/NGCP/BulkProcessor/Projects/Export/Ama/Ccs/settings.cfg index 04771ef1..82c0ea33 100755 --- a/lib/NGCP/BulkProcessor/Projects/Export/Ama/Ccs/settings.cfg +++ b/lib/NGCP/BulkProcessor/Projects/Export/Ama/Ccs/settings.cfg @@ -3,12 +3,24 @@ export_cdr_multithreading = 1 export_cdr_numofthreads = 2 export_cdr_blocksize = 1000 -export_cdr_joins = { 'billing.voip_subscribers source_voip_subscribers' => { 'source_voip_subscribers.uuid' => 'accounting.cdr.source_user_id' } }, { 'billing.voip_subscribers destination_voip_subscribers' => { 'destination_voip_subscribers.uuid' => 'accounting.cdr.destination_user_id' } }, { 'billing.billing_zones_history source_carrier_bbz' => { 'source_carrier_bbz.id' => 'accounting.cdr.source_carrier_billing_zone_id' } }, { 'billing.billing_zones_history source_reseller_bbz' => { 'source_reseller_bbz.id' => 'accounting.cdr.source_reseller_billing_zone_id' } }, { 'billing.billing_zones_history source_customer_bbz' => { 'source_customer_bbz.id' => 'accounting.cdr.source_customer_billing_zone_id' } }, { 'billing.billing_zones_history destination_carrier_bbz' => { 'destination_carrier_bbz.id' => 'accounting.cdr.destination_carrier_billing_zone_id' } }, { 'billing.billing_zones_history destination_reseller_bbz' => { 'destination_reseller_bbz.id' => 'accounting.cdr.destination_reseller_billing_zone_id' } }, { 'billing.billing_zones_history destination_customer_bbz' => { 'destination_customer_bbz.id' => 'accounting.cdr.destination_customer_billing_zone_id' } } -export_cdr_conditions = -#{ 'accounting.cdr.export_status' => { '=' => '"unexported"' } }, { 'accounting.cdr.call_status' => { '=' => '"ok"' } }, { 'accounting.cdr.rating_status' => { '=' => '"ok"' } } export_cdr_limit = 10000 export_cdr_stream = ama_ccs export_cdr_rollover_fsn = 1 -use_tempfiles = 1 +export_cdr_conditions = { 'accounting.cdr.destination_domain' => { 'IN' => '("80.110.2.164","ccs.upc.at")' } } +#export_cdr_conditions = { 'accounting.cdr.destination_domain' => { '=' => '"ccs.upc.at"' } } +#{ 'accounting.cdr.export_status' => { '=' => '"unexported"' } }, { 'accounting.cdr.call_status' => { '=' => '"ok"' } }, { 'accounting.cdr.rating_status' => { '=' => '"ok"' } } +#export_cdr_joins = { 'billing.voip_subscribers source_voip_subscribers' => { 'source_voip_subscribers.uuid' => 'accounting.cdr.source_user_id' } }, { 'billing.voip_subscribers destination_voip_subscribers' => { 'destination_voip_subscribers.uuid' => 'accounting.cdr.destination_user_id' } }, { 'billing.billing_zones_history source_carrier_bbz' => { 'source_carrier_bbz.id' => 'accounting.cdr.source_carrier_billing_zone_id' } }, { 'billing.billing_zones_history source_reseller_bbz' => { 'source_reseller_bbz.id' => 'accounting.cdr.source_reseller_billing_zone_id' } }, { 'billing.billing_zones_history source_customer_bbz' => { 'source_customer_bbz.id' => 'accounting.cdr.source_customer_billing_zone_id' } }, { 'billing.billing_zones_history destination_carrier_bbz' => { 'destination_carrier_bbz.id' => 'accounting.cdr.destination_carrier_billing_zone_id' } }, { 'billing.billing_zones_history destination_reseller_bbz' => { 'destination_reseller_bbz.id' => 'accounting.cdr.destination_reseller_billing_zone_id' } }, { 'billing.billing_zones_history destination_customer_bbz' => { 'destination_customer_bbz.id' => 'accounting.cdr.destination_customer_billing_zone_id' } } + +use_tempfiles = 1 +make_dir = 1 ama_filename_format = %1$sP%3$02d%4$02d%5$02d%6$02d%7$02d%9$02dAMA%10$s + +ama_max_blocks = 1000 + +ama_sensor_id = 438716 +ama_recording_office_id = 438716 +ama_incoming_trunk_group_number = 2999 +ama_outgoing_trunk_group_number = 2014 +ama_originating_digits_cdr_field = source_user +ama_terminating_digits_cdr_field = destination_user diff --git a/lib/NGCP/BulkProcessor/Projects/Export/Ama/Ccs/settings.debug.cfg b/lib/NGCP/BulkProcessor/Projects/Export/Ama/Ccs/settings.debug.cfg index c528b21f..2a5b7d2e 100755 --- a/lib/NGCP/BulkProcessor/Projects/Export/Ama/Ccs/settings.debug.cfg +++ b/lib/NGCP/BulkProcessor/Projects/Export/Ama/Ccs/settings.debug.cfg @@ -3,15 +3,25 @@ export_cdr_multithreading = 1 export_cdr_numofthreads = 2 export_cdr_blocksize = 1000 -#export_cdr_joins = { 'accounting.cdr_export_status_data esd' => { 'esd.cdr_id' => 'accounting.cdr.id' } }, { 'accounting.cdr_export_status es' => { 'es.id' => 'esd.status_id' } } -#export_cdr_conditions = { 'es.type' => { '=' => '"default"' } }, { 'esd.export_status' => { '=' => '"unexported"' } }, { 'accounting.cdr.call_status' => { '=' => '"ok"' } } -#, { 'accounting.cdr.rating_status' => { '=' => '"ok"' } } -export_cdr_conditions = -#{ 'accounting.cdr.call_status' => { '=' => '"ok"' } } export_cdr_stream = ama_ccs -#default export_cdr_limit = 10000 export_cdr_rollover_fsn = 1 + +export_cdr_conditions = { 'accounting.cdr.destination_domain' => { 'IN' => '("80.110.2.164","ccs.upc.at")' } } +#export_cdr_conditions = { 'accounting.cdr.destination_domain' => { '=' => '"ccs.upc.at"' } } +#, { 'accounting.cdr.rating_status' => { '=' => '"ok"' } } +#{ 'accounting.cdr.call_status' => { '=' => '"ok"' } } +#export_cdr_joins = { 'accounting.cdr_export_status_data esd' => { 'esd.cdr_id' => 'accounting.cdr.id' } }, { 'accounting.cdr_export_status es' => { 'es.id' => 'esd.status_id' } } + use_tempfiles = 1 +make_dir = 1 +ama_filename_format = %1$sdebug/P%3$02d%4$02d%5$02d%6$02d%7$02d%9$02dAMA.debug%10$s + +ama_max_blocks = 1000 -ama_filename_format = %1$sP%3$02d%4$02d%5$02d%6$02d%7$02d%9$02dAMA.debug%10$s +ama_sensor_id = 438716 +ama_recording_office_id = 438716 +ama_incoming_trunk_group_number = 2999 +ama_outgoing_trunk_group_number = 2014 +ama_originating_digits_cdr_field = source_user +ama_terminating_digits_cdr_field = destination_user \ No newline at end of file diff --git a/lib/NGCP/BulkProcessor/Projects/Export/Ama/Format/FieldSet.pm b/lib/NGCP/BulkProcessor/Projects/Export/Ama/Format/FieldSet.pm index e95cc9c4..cee34e36 100644 --- a/lib/NGCP/BulkProcessor/Projects/Export/Ama/Format/FieldSet.pm +++ b/lib/NGCP/BulkProcessor/Projects/Export/Ama/Format/FieldSet.pm @@ -10,11 +10,12 @@ use NGCP::BulkProcessor::LogError qw( require Exporter; our @ISA = qw(Exporter); our @EXPORT_OK = qw( - + $line_terminator ); my $field_separator = ": "; -my $line_terminator = "\n"; +our $line_terminator = "\n"; +my $indentation = " "; my $padding = ' '; sub new { @@ -78,7 +79,7 @@ sub to_string { } } foreach my $field (@{$self->{fields}}) { - push(@lines,uc($field->get_name()) . $field_separator . ($maxlen > 0 ? ($padding x ($maxlen - length($field->get_name()))) : '') . uc($field->get_hex(@_))); + push(@lines,$indentation . uc($field->get_name()) . $field_separator . ($maxlen > 0 ? ($padding x ($maxlen - length($field->get_name()))) : '') . uc($field->get_hex(@_))); } return join($line_terminator,@lines); diff --git a/lib/NGCP/BulkProcessor/Projects/Export/Ama/Format/Fields/ConnectTime.pm b/lib/NGCP/BulkProcessor/Projects/Export/Ama/Format/Fields/ConnectTime.pm index 9dda3abb..6b1af82c 100644 --- a/lib/NGCP/BulkProcessor/Projects/Export/Ama/Format/Fields/ConnectTime.pm +++ b/lib/NGCP/BulkProcessor/Projects/Export/Ama/Format/Fields/ConnectTime.pm @@ -16,7 +16,7 @@ our @EXPORT_OK = qw( my $field_name = "connect time"; my $length = 8; -my @param_names = qw/connect_time dt/; +my @param_names = qw/connect_time/; sub new { @@ -43,7 +43,7 @@ sub _get_param_names { sub get_hex { my $self = shift; - my ($connect_time,$dt) = $self->_get_params(@_); + my ($connect_time) = $self->_get_params(@_); die("invalid connect time '$connect_time'") unless length($connect_time) == 7; return $connect_time . $TERMINATOR; diff --git a/lib/NGCP/BulkProcessor/Projects/Export/Ama/Format/Fields/Date.pm b/lib/NGCP/BulkProcessor/Projects/Export/Ama/Format/Fields/Date.pm index 102a7d2d..e2947847 100644 --- a/lib/NGCP/BulkProcessor/Projects/Export/Ama/Format/Fields/Date.pm +++ b/lib/NGCP/BulkProcessor/Projects/Export/Ama/Format/Fields/Date.pm @@ -16,7 +16,7 @@ our @EXPORT_OK = qw( my $field_name = "date"; my $length = 6; -my @param_names = qw/date dt/; +my @param_names = qw/date/; sub new { @@ -43,7 +43,7 @@ sub _get_param_names { sub get_hex { my $self = shift; - my ($date,$dt) = $self->_get_params(@_); + my ($date) = $self->_get_params(@_); die("invalid date '$date'") unless length($date) == 5; return $date . $TERMINATOR; diff --git a/lib/NGCP/BulkProcessor/Projects/Export/Ama/Format/Fields/GenericContextIdentifier.pm b/lib/NGCP/BulkProcessor/Projects/Export/Ama/Format/Fields/GenericContextIdentifier.pm index 3f172ece..af46dbce 100644 --- a/lib/NGCP/BulkProcessor/Projects/Export/Ama/Format/Fields/GenericContextIdentifier.pm +++ b/lib/NGCP/BulkProcessor/Projects/Export/Ama/Format/Fields/GenericContextIdentifier.pm @@ -23,6 +23,8 @@ our @EXPORT_OK = qw( $NUMBER_PORTABILITY $NPI $CPS + + $IN_CORRELATION_ID_PARSING_RULES ); my $field_name = "generic context identifier"; @@ -57,6 +59,8 @@ push(@generic_context_ids,$NPI); our $CPS = '80080'; push(@generic_context_ids,$CPS); +our $IN_CORRELATION_ID_PARSING_RULES = 7; + sub new { my $class = shift; diff --git a/lib/NGCP/BulkProcessor/Projects/Export/Ama/Format/Fields/NetworkOperatorData.pm b/lib/NGCP/BulkProcessor/Projects/Export/Ama/Format/Fields/NetworkOperatorData.pm index 5c19bfdb..8a8f9c84 100644 --- a/lib/NGCP/BulkProcessor/Projects/Export/Ama/Format/Fields/NetworkOperatorData.pm +++ b/lib/NGCP/BulkProcessor/Projects/Export/Ama/Format/Fields/NetworkOperatorData.pm @@ -14,7 +14,7 @@ our @EXPORT_OK = qw( ); my $field_name = "network operator data"; -my $length = 49; +my $length = 40; my @param_names = qw/network_operator_data/; sub new { @@ -41,20 +41,28 @@ sub get_hex { my $self = shift; my ($network_operator_data) = $self->_get_params(@_); - die("invalid network operator data '$network_operator_data'") if length($network_operator_data) != 39; - return $network_operator_data . '1'; #$TERMINATOR; + die("invalid network operator data '$network_operator_data'") if length($network_operator_data) != 40; + return $network_operator_data; # . '1'; #$TERMINATOR; } sub get_network_operator_data { - my ($originating_digits,$switch_number_digits) = @_; + my ($originating_digits,$switch_number_digits,$mode) = @_; my $result = $originating_digits; my $padlength = 16 - length($originating_digits); - $result .= 'f' x $padlength; + if ($padlength >= 0) { + $result .= 'f' x $padlength; + } else { + die("invalid network operator data/originating_digits '$originating_digits'"); + } $result .= $switch_number_digits; $padlength = 20 - length($switch_number_digits); - $result .= 'f' x $padlength; - $result .= '800'; + if ($padlength >= 0) { + $result .= 'f' x $padlength; + } else { + die("invalid network operator data/switch_number_digits '$switch_number_digits'"); + } + $result .= $mode; return $result; } diff --git a/lib/NGCP/BulkProcessor/Projects/Export/Ama/Format/File.pm b/lib/NGCP/BulkProcessor/Projects/Export/Ama/Format/File.pm index d2306373..b1da455f 100644 --- a/lib/NGCP/BulkProcessor/Projects/Export/Ama/Format/File.pm +++ b/lib/NGCP/BulkProcessor/Projects/Export/Ama/Format/File.pm @@ -3,16 +3,23 @@ use strict; ## no critic +use File::Basename qw(fileparse); + use NGCP::BulkProcessor::Projects::Export::Ama::Format::Settings qw( $output_path $ama_filename_format $use_tempfiles $tempfile_path + $make_dir + $ama_max_blocks ); use NGCP::BulkProcessor::Projects::Export::Ama::Format::Block qw(); use NGCP::BulkProcessor::Projects::Export::Ama::Format::Structures::Structure9014 qw(); +use NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::Date qw(); +use NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::ConnectTime qw(); + use NGCP::BulkProcessor::Logging qw( getlogger ); @@ -21,7 +28,8 @@ use NGCP::BulkProcessor::LogError qw( fileerror ); -use NGCP::BulkProcessor::Utils qw(tempfilename); +use NGCP::BulkProcessor::Utils qw(tempfilename makepath); +use NGCP::BulkProcessor::Calendar qw(current_local from_epoch); require Exporter; our @ISA = qw(Exporter); @@ -29,7 +37,6 @@ our @EXPORT_OK = qw( ); -my $max_blocks = 99; my $ama_file_extension = '.ama'; sub new { @@ -50,9 +57,20 @@ sub reset { $self->_save_transfer_in(undef); $self->_save_transfer_out(undef); $self->{tempfilename} = tempfilename('XXXX',$tempfile_path,$ama_file_extension) if $use_tempfiles; + $self->{now} = current_local(); + $self->{min_start_time} = undef; + $self->{max_end_time} = undef; return; } +sub update_start_end_time { + my $self = shift; + my ($start_time,$end_time) = @_; + #my $end_time = $start_time + $duration; + $self->{min_start_time} = $start_time if (not defined $self->{min_start_time} or $self->{min_start_time} > $start_time); + $self->{max_end_time} = $end_time if (not defined $self->{max_end_time} or $self->{max_end_time} < $end_time); +} + sub get_record_count { my $self = shift; return $self->{record_count}; @@ -67,12 +85,12 @@ sub add_record { my $self = shift; my ($record,$pad) = @_; my $result; - if (not $pad and (scalar @{$self->{blocks}}) >= $max_blocks and not $self->{current_block}->records_fit($record, + if (not $pad and (scalar @{$self->{blocks}}) >= $ama_max_blocks and not $self->{current_block}->records_fit($record, $NGCP::BulkProcessor::Projects::Export::Ama::Format::Structures::Structure9014::length)) { $result = 0; } else { if (not $self->{current_block}->add_record($record)) { - if ((scalar @{$self->{blocks}}) >= $max_blocks) { + if ((scalar @{$self->{blocks}}) >= $ama_max_blocks) { $result = 0; } else { $self->{current_block}->set_padded(1); @@ -97,13 +115,13 @@ sub get_filename { return $self->{tempfilename} if ($use_tempfiles and $show_tempfilename); return sprintf($ama_filename_format, $output_path, - $self->{transfer_in}->get_structure()->get_date_field()->{dt}->year, - substr($self->{transfer_in}->get_structure()->get_date_field()->{dt}->year,-2), - $self->{transfer_in}->get_structure()->get_date_field()->{dt}->month, - $self->{transfer_in}->get_structure()->get_date_field()->{dt}->day, - $self->{transfer_in}->get_structure()->get_connect_time_field()->{dt}->hour, - $self->{transfer_in}->get_structure()->get_connect_time_field()->{dt}->minute, - $self->{transfer_in}->get_structure()->get_connect_time_field()->{dt}->second, + $self->{now}->year, + substr($self->{now}->year,-2), + $self->{now}->month, + $self->{now}->day, + $self->{now}->hour, + $self->{now}->minute, + $self->{now}->second, $self->{transfer_in}->get_structure()->get_file_sequence_number_field()->{file_sequence_number}, $ama_file_extension, ); @@ -120,6 +138,15 @@ sub _rename { return rename($self->{tempfilename},$filename); } +sub _makedir { + + my ($filename) = @_; + my ($name,$path,$suffix) = fileparse($filename,$ama_file_extension); + makepath($path,\&fileerror,getlogger(__PACKAGE__)) if ($make_dir and length($path) > 0 and not -d $path); + return $filename; + +} + sub flush { my $self = shift; my %params = @_; @@ -134,14 +161,14 @@ sub flush { fileerror($filename . ' already exists',getlogger(__PACKAGE__)); return 0; } else { - if (open(my $fh,">:raw",($use_tempfiles ? $self->{tempfilename} : $filename))) { + if (open(my $fh,">:raw",($use_tempfiles ? $self->{tempfilename} : _makedir($filename)))) { foreach my $block (@{$self->{blocks}}) { print $fh pack('H*',$block->get_hex()); } close $fh; if (defined $commit_cb) { if (&$commit_cb(@_)) { - if (not $use_tempfiles or $self->_rename($filename)) { + if (not $use_tempfiles or $self->_rename(_makedir($filename))) { return 1; } else { my $err = $!; @@ -193,9 +220,29 @@ sub close { )), 1, ); - # update count fields: + + # update transfer_in date/time: + my $min_start_dt; + $min_start_dt = from_epoch($self->{min_start_time}) if defined $self->{min_start_time}; + $self->{transfer_in}->get_structure()->get_date_field()->_set_params( + date => NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::Date::get_ama_date($min_start_dt // $self->{now}), + ); + $self->{transfer_in}->get_structure()->get_connect_time_field()->_set_params( + connect_time => NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::ConnectTime::get_connect_time($min_start_dt // $self->{now}), + ); + # update transfer_out date/time: + my $max_end_dt; + $max_end_dt = from_epoch($self->{max_end_time}) if defined $self->{max_end_time}; + $self->{transfer_out}->get_structure()->get_date_field()->_set_params( + date => NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::Date::get_ama_date($max_end_dt // $self->{now}), + ); + $self->{transfer_out}->get_structure()->get_connect_time_field()->_set_params( + connect_time => NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::ConnectTime::get_connect_time($max_end_dt // $self->{now}), + ); + # update transfer_out count fields: $self->{transfer_out}->get_structure()->get_block_count_field()->_set_params(block_count => $self->get_block_count()); $self->{transfer_out}->get_structure()->get_record_count_field()->_set_params(record_count => $self->get_record_count()); + $result |= $self->flush( commit_cb => $commit_cb, @_ @@ -232,7 +279,6 @@ sub write_record { my $result = 0; my $record = &$get_record(@_); if (not $self->add_record($record)) { - #my $blah="y"; $result |= $self->close( get_transfer_out => $get_transfer_out, commit_cb => $commit_cb, diff --git a/lib/NGCP/BulkProcessor/Projects/Export/Ama/Format/Record.pm b/lib/NGCP/BulkProcessor/Projects/Export/Ama/Format/Record.pm index 392e160f..f62ee3c1 100644 --- a/lib/NGCP/BulkProcessor/Projects/Export/Ama/Format/Record.pm +++ b/lib/NGCP/BulkProcessor/Projects/Export/Ama/Format/Record.pm @@ -3,6 +3,8 @@ use strict; ## no critic +use NGCP::BulkProcessor::Projects::Export::Ama::Format::FieldSet qw($line_terminator); + require Exporter; our @ISA = qw(Exporter); our @EXPORT_OK = qw( @@ -40,6 +42,20 @@ sub get_hex { return $result; } +sub to_string { + + my $self = shift; + + my $result = $line_terminator . $line_terminator . "record data:$line_terminator" . $self->{structure}->to_string(@_); + foreach my $module (@{$self->{modules}}) { + next unless $module->get_enabled(@_); + $result .= $line_terminator . $line_terminator . "module data:$line_terminator" . $module->to_string(@_); + } + $result .= $line_terminator; + return $result; + +} + sub get_length { my $self = shift; my $length = $record_descriptor_word_length; diff --git a/lib/NGCP/BulkProcessor/Projects/Export/Ama/Format/Settings.pm b/lib/NGCP/BulkProcessor/Projects/Export/Ama/Format/Settings.pm index a2793aa6..411e143e 100644 --- a/lib/NGCP/BulkProcessor/Projects/Export/Ama/Format/Settings.pm +++ b/lib/NGCP/BulkProcessor/Projects/Export/Ama/Format/Settings.pm @@ -41,8 +41,11 @@ our @EXPORT_OK = qw( $domestic_destination_pattern $international_destination_pattern + $make_dir $ama_filename_format $use_tempfiles + + $ama_max_blocks ); our $output_path = $working_path . 'output/'; @@ -53,6 +56,9 @@ our $use_tempfiles = 0; our $domestic_destination_pattern = undef; our $international_destination_pattern = undef; +our $ama_max_blocks = 1000; + +our $make_dir = 0; our $ama_filename_format = '%1$sP%3$02d%4$02d%5$02d%6$02d%7$02d%9$02dAMA%10$s'; sub update_settings { @@ -68,6 +74,7 @@ sub update_settings { $result &= _prepare_working_paths(1); $use_tempfiles = $data->{use_tempfiles} if exists $data->{use_tempfiles}; + $make_dir = $data->{make_dir} if exists $data->{make_dir}; my $regexp_result; $domestic_destination_pattern = $data->{domestic_destination_pattern} if exists $data->{domestic_destination_pattern}; @@ -79,6 +86,8 @@ sub update_settings { $ama_filename_format = $data->{ama_filename_format} if exists $data->{ama_filename_format}; + $ama_max_blocks = $data->{ama_max_blocks} if exists $data->{ama_max_blocks}; + return $result; } diff --git a/lib/NGCP/BulkProcessor/Projects/Export/Ama/Format/Structures/Structure9014.pm b/lib/NGCP/BulkProcessor/Projects/Export/Ama/Format/Structures/Structure9014.pm index a7a8157c..9907a10e 100644 --- a/lib/NGCP/BulkProcessor/Projects/Export/Ama/Format/Structures/Structure9014.pm +++ b/lib/NGCP/BulkProcessor/Projects/Export/Ama/Format/Structures/Structure9014.pm @@ -60,12 +60,14 @@ sub new { $self->_add_field(NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::RecordingOfficeId->new( @_, )); - $self->_add_field(NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::Date->new( + $self->{date} = NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::Date->new( @_, - )); - $self->_add_field(NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::ConnectTime->new( + ); + $self->_add_field($self->{date}); + $self->{connect_time} = NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::ConnectTime->new( @_, - )); + ); + $self->_add_field($self->{connect_time}); $self->_add_field(NGCP::BulkProcessor::Projects::Export::Ama::Format::Fields::GenericIssue->new( @_, )); @@ -112,6 +114,16 @@ sub get_block_count_field { return $self->{block_count}; } +sub get_date_field { + my $self = shift; + return $self->{date}; +} + +sub get_connect_time_field { + my $self = shift; + return $self->{connect_time}; +} + #sub get_instance { # return #} diff --git a/lib/NGCP/BulkProcessor/Projects/Massive/Generator/CDR.pm b/lib/NGCP/BulkProcessor/Projects/Massive/Generator/CDR.pm index c213661e..c0e8fa5b 100755 --- a/lib/NGCP/BulkProcessor/Projects/Massive/Generator/CDR.pm +++ b/lib/NGCP/BulkProcessor/Projects/Massive/Generator/CDR.pm @@ -333,7 +333,7 @@ sub _generate_cdr_init_context { $source_subscriber->{contract} = NGCP::BulkProcessor::Dao::Trunk::billing::contracts::findby_id($source_subscriber->{contract_id}); $source_subscriber->{contract}->{contact} = NGCP::BulkProcessor::Dao::Trunk::billing::contacts::findby_id($source_subscriber->{contract}->{contact_id}); $source_subscriber->{contract}->{prov_subscriber} = NGCP::BulkProcessor::Dao::Trunk::provisioning::voip_subscribers::findby_uuid(undef,$source_subscriber->{uuid}); - $source_subscriber->{primary_alias} = NGCP::BulkProcessor::Dao::Trunk::provisioning::voip_dbaliases::findby_subscriberidisprimary($source_subscriber->{contract}->{prov_subscriber}->{id},1); + $source_subscriber->{primary_alias} = NGCP::BulkProcessor::Dao::Trunk::provisioning::voip_dbaliases::findby_subscriberidisprimary($source_subscriber->{contract}->{prov_subscriber}->{id},1)->[0]; $source_subscriber->{domain} = $context->{domain_map}->{$source_subscriber->{domain_id}}->{domain}; $source_reseller = $context->{reseller_map}->{$source_subscriber->{contract}->{contact}->{reseller_id}}; } else { @@ -346,7 +346,7 @@ sub _generate_cdr_init_context { $dest_subscriber->{contract} = NGCP::BulkProcessor::Dao::Trunk::billing::contracts::findby_id($dest_subscriber->{contract_id}); $dest_subscriber->{contract}->{contact} = NGCP::BulkProcessor::Dao::Trunk::billing::contacts::findby_id($dest_subscriber->{contract}->{contact_id}); $dest_subscriber->{contract}->{prov_subscriber} = NGCP::BulkProcessor::Dao::Trunk::provisioning::voip_subscribers::findby_uuid(undef,$dest_subscriber->{uuid}); - $dest_subscriber->{primary_alias} = NGCP::BulkProcessor::Dao::Trunk::provisioning::voip_dbaliases::findby_subscriberidisprimary($dest_subscriber->{contract}->{prov_subscriber}->{id},1); + $dest_subscriber->{primary_alias} = NGCP::BulkProcessor::Dao::Trunk::provisioning::voip_dbaliases::findby_subscriberidisprimary($dest_subscriber->{contract}->{prov_subscriber}->{id},1)->[0]; $dest_subscriber->{domain} = $context->{domain_map}->{$dest_subscriber->{domain_id}}->{domain}; $dest_reseller = $context->{reseller_map}->{$dest_subscriber->{contract}->{contact}->{reseller_id}}; } else {