You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
723 lines
30 KiB
723 lines
30 KiB
package NGCP::BulkProcessor::Projects::Migration::IPGallery::Provisioning;
|
|
use strict;
|
|
|
|
## no critic
|
|
|
|
use threads::shared qw();
|
|
use String::MkPasswd qw();
|
|
#use List::Util qw();
|
|
|
|
use NGCP::BulkProcessor::Projects::Migration::IPGallery::Settings qw(
|
|
$dry
|
|
$skip_errors
|
|
$batch
|
|
|
|
$reseller_id
|
|
$domain_name
|
|
$subsciber_username_prefix
|
|
$billing_profile_id
|
|
$contact_email_format
|
|
$webpassword_length
|
|
$generate_webpassword
|
|
|
|
$provision_subscriber_multithreading
|
|
$provision_subscriber_numofthreads
|
|
);
|
|
|
|
use NGCP::BulkProcessor::Logging qw (
|
|
getlogger
|
|
processing_info
|
|
processing_debug
|
|
);
|
|
use NGCP::BulkProcessor::LogError qw(
|
|
rowprocessingerror
|
|
rowprocessingwarn
|
|
);
|
|
|
|
use NGCP::BulkProcessor::Projects::Migration::IPGallery::Dao::import::Subscriber qw();
|
|
use NGCP::BulkProcessor::Projects::Migration::IPGallery::Dao::import::UsernamePassword qw();
|
|
use NGCP::BulkProcessor::Projects::Migration::IPGallery::Dao::import::FeatureOptionSetItem qw();
|
|
use NGCP::BulkProcessor::Projects::Migration::IPGallery::Dao::import::Batch qw();
|
|
|
|
use NGCP::BulkProcessor::Dao::Trunk::billing::billing_profiles qw();
|
|
use NGCP::BulkProcessor::Dao::Trunk::billing::products qw();
|
|
use NGCP::BulkProcessor::Dao::Trunk::billing::contacts qw();
|
|
use NGCP::BulkProcessor::Dao::Trunk::billing::contracts qw();
|
|
use NGCP::BulkProcessor::Dao::Trunk::billing::billing_mappings qw();
|
|
use NGCP::BulkProcessor::Dao::Trunk::billing::contract_balances qw();
|
|
use NGCP::BulkProcessor::Dao::Trunk::billing::domains qw();
|
|
use NGCP::BulkProcessor::Dao::Trunk::billing::voip_subscribers qw();
|
|
use NGCP::BulkProcessor::Dao::Trunk::billing::voip_numbers qw();
|
|
use NGCP::BulkProcessor::Dao::Trunk::billing::domain_resellers qw();
|
|
|
|
use NGCP::BulkProcessor::Dao::Trunk::provisioning::voip_domains qw();
|
|
use NGCP::BulkProcessor::Dao::Trunk::provisioning::voip_dbaliases qw();
|
|
use NGCP::BulkProcessor::Dao::Trunk::provisioning::voip_subscribers qw();
|
|
use NGCP::BulkProcessor::Dao::Trunk::provisioning::voip_preferences qw();
|
|
use NGCP::BulkProcessor::Dao::Trunk::provisioning::voip_usr_preferences qw();
|
|
|
|
use NGCP::BulkProcessor::Dao::Trunk::kamailio::voicemail_users qw();
|
|
|
|
use NGCP::BulkProcessor::RestRequests::Trunk::Subscribers qw();
|
|
use NGCP::BulkProcessor::RestRequests::Trunk::Customers qw();
|
|
|
|
use NGCP::BulkProcessor::Projects::Migration::IPGallery::Preferences qw(
|
|
set_preference
|
|
clear_preferences
|
|
);
|
|
|
|
use NGCP::BulkProcessor::ConnectorPool qw(
|
|
get_xa_db
|
|
);
|
|
|
|
use NGCP::BulkProcessor::Projects::Migration::IPGallery::ProjectConnectorPool qw(
|
|
destroy_all_dbs
|
|
);
|
|
|
|
use NGCP::BulkProcessor::Utils qw(create_uuid threadid);
|
|
|
|
require Exporter;
|
|
our @ISA = qw(Exporter);
|
|
our @EXPORT_OK = qw(
|
|
provision_subscribers
|
|
provision_subscribers_batch
|
|
);
|
|
|
|
sub provision_subscribers {
|
|
|
|
my $static_context = {};
|
|
my $result = _provision_subscribers_checks($static_context);
|
|
|
|
destroy_all_dbs();
|
|
my $warning_count :shared = 0;
|
|
return ($result && NGCP::BulkProcessor::Projects::Migration::IPGallery::Dao::import::Subscriber::process_records(
|
|
static_context => $static_context,
|
|
process_code => sub {
|
|
my ($context,$records,$row_offset) = @_;
|
|
my $rownum = $row_offset;
|
|
foreach my $imported_subscriber (@$records) {
|
|
$rownum++;
|
|
next unless _provision_susbcriber($context,$imported_subscriber,$rownum);
|
|
}
|
|
|
|
#return 0;
|
|
return 1;
|
|
},
|
|
init_process_context_code => sub {
|
|
my ($context)= @_;
|
|
$context->{db} = &get_xa_db();
|
|
$context->{error_count} = 0;
|
|
$context->{warning_count} = 0;
|
|
# below is not mandatory..
|
|
_check_insert_tables();
|
|
},
|
|
uninit_process_context_code => sub {
|
|
my ($context)= @_;
|
|
undef $context->{db};
|
|
destroy_all_dbs();
|
|
{
|
|
lock $warning_count;
|
|
$warning_count += $context->{warning_count};
|
|
}
|
|
},
|
|
load_recursive => 0,
|
|
multithreading => $provision_subscriber_multithreading,
|
|
numofthreads => $provision_subscriber_numofthreads,
|
|
),$warning_count);
|
|
}
|
|
|
|
sub provision_subscribers_batch {
|
|
|
|
my $static_context = {};
|
|
my $result = _provision_subscribers_checks($static_context);
|
|
|
|
destroy_all_dbs();
|
|
my $warning_count :shared = 0;
|
|
return ($result && NGCP::BulkProcessor::Projects::Migration::IPGallery::Dao::import::Batch::process_records(
|
|
static_context => $static_context,
|
|
process_code => sub {
|
|
my ($context,$records,$row_offset) = @_;
|
|
my $rownum = $row_offset;
|
|
foreach my $record (@$records) {
|
|
$rownum++;
|
|
my $imported_subscriber = NGCP::BulkProcessor::Projects::Migration::IPGallery::Dao::import::Subscriber::findby_subscribernumber($record->{number});
|
|
if (defined $imported_subscriber) {
|
|
next unless _provision_susbcriber($context,$imported_subscriber,$rownum);
|
|
} else {
|
|
if ($skip_errors) {
|
|
_warn($context,'record ' . $rownum . ' - no subscriber record for batch number found: ' . $record->{number});
|
|
next;
|
|
} else {
|
|
_error($context,'record ' . $rownum . ' - no subscriber record for batch number found: ' . $record->{number});
|
|
}
|
|
}
|
|
}
|
|
|
|
#return 0;
|
|
return 1;
|
|
},
|
|
init_process_context_code => sub {
|
|
my ($context)= @_;
|
|
$context->{db} = &get_xa_db();
|
|
$context->{error_count} = 0;
|
|
$context->{warning_count} = 0;
|
|
# below is not mandatory..
|
|
_check_insert_tables();
|
|
},
|
|
uninit_process_context_code => sub {
|
|
my ($context)= @_;
|
|
undef $context->{db};
|
|
destroy_all_dbs();
|
|
{
|
|
lock $warning_count;
|
|
$warning_count += $context->{warning_count};
|
|
}
|
|
},
|
|
load_recursive => 0,
|
|
multithreading => $provision_subscriber_multithreading,
|
|
numofthreads => $provision_subscriber_numofthreads,
|
|
),$warning_count);
|
|
}
|
|
|
|
|
|
sub _check_insert_tables {
|
|
|
|
NGCP::BulkProcessor::Dao::Trunk::billing::contacts::check_table();
|
|
NGCP::BulkProcessor::Dao::Trunk::billing::contracts::check_table();
|
|
NGCP::BulkProcessor::Dao::Trunk::billing::billing_mappings::check_table();
|
|
NGCP::BulkProcessor::Dao::Trunk::billing::contract_balances::check_table();
|
|
NGCP::BulkProcessor::Dao::Trunk::billing::voip_subscribers::check_table();
|
|
NGCP::BulkProcessor::Dao::Trunk::provisioning::voip_subscribers::check_table();
|
|
NGCP::BulkProcessor::Dao::Trunk::provisioning::voip_usr_preferences::check_table();
|
|
NGCP::BulkProcessor::Dao::Trunk::provisioning::voip_dbaliases::check_table();
|
|
NGCP::BulkProcessor::Dao::Trunk::kamailio::voicemail_users::check_table();
|
|
|
|
}
|
|
|
|
sub _provision_susbcriber {
|
|
my ($context,$imported_subscriber,$rownum) = @_;
|
|
|
|
return 0 unless _reset_context($context,$imported_subscriber,$rownum);
|
|
|
|
eval {
|
|
$context->{db}->db_begin();
|
|
#_warn($context,'AutoCommit is on') if $context->{db}->{drh}->{AutoCommit};
|
|
|
|
my $existing_billing_voip_subscribers = NGCP::BulkProcessor::Dao::Trunk::billing::voip_subscribers::findby_domainid_username_states($context->{db},
|
|
$context->{billing_domain}->{id},$context->{username},{ 'NOT IN' => $NGCP::BulkProcessor::Dao::Trunk::billing::voip_subscribers::TERMINATED_STATE});
|
|
if ((scalar @$existing_billing_voip_subscribers) == 0) {
|
|
|
|
if ($imported_subscriber->{delta} eq
|
|
$NGCP::BulkProcessor::Projects::Migration::IPGallery::Dao::import::Subscriber::deleted_delta) {
|
|
_info($context,"($context->{rownum}) " . 'subscriber ' . $context->{cli} . ' is deleted, and no active subscriber found');
|
|
} else {
|
|
|
|
my $existing_provisioning_voip_dbalias = NGCP::BulkProcessor::Dao::Trunk::provisioning::voip_dbaliases::findby_domainid_username($context->{db},
|
|
$context->{provisioning_voip_domain}->{id},$context->{cli});
|
|
|
|
if (not defined $existing_provisioning_voip_dbalias) {
|
|
_create_contact($context);
|
|
_create_contract($context);
|
|
_create_subscriber($context);
|
|
_info($context,"($context->{rownum}) " . 'subscriber ' . $context->{cli} . ' successfully provisioned',1);
|
|
|
|
|
|
} else {
|
|
_warn($context,"($context->{rownum}) " . 'existing provisioning voip_dbalias with username ' . $context->{cli} . ' found, skipping');
|
|
}
|
|
}
|
|
} elsif ((scalar @$existing_billing_voip_subscribers) == 1) {
|
|
my $existing_billing_voip_subscriber = $existing_billing_voip_subscribers->[0];
|
|
if ($imported_subscriber->{delta} eq
|
|
$NGCP::BulkProcessor::Projects::Migration::IPGallery::Dao::import::Subscriber::deleted_delta) {
|
|
|
|
_info($context,"($context->{rownum}) " . 'subscriber ' . $context->{cli} . ' is deleted, but active subscriber found');
|
|
|
|
if (_terminate_subscriber($context,$existing_billing_voip_subscriber->{id})) {
|
|
_terminate_contract($context,$existing_billing_voip_subscriber->{contract_id});
|
|
}
|
|
|
|
} else {
|
|
if ($context->{userpassworddelta} eq
|
|
$NGCP::BulkProcessor::Projects::Migration::IPGallery::Dao::import::UsernamePassword::updated_delta) {
|
|
|
|
_info($context,"($context->{rownum}) " . 'existing billing subscriber with username ' . $context->{username} . ' and updated password found (re-provisioned)');
|
|
|
|
if (_terminate_subscriber($context,$existing_billing_voip_subscriber->{id})) {
|
|
if (_terminate_contract($context,$existing_billing_voip_subscriber->{contract_id})) {
|
|
if ($dry) {
|
|
_create_contact($context);
|
|
_create_contract($context);
|
|
eval {
|
|
_create_subscriber($context);
|
|
};
|
|
if ($@) {
|
|
_info($context,"($context->{rownum}) " . 'expected error ' . $@ . ' while re-provisioning subscriber ' . $context->{cli} . ' in dry-mode',1);
|
|
} else {
|
|
if ($skip_errors) {
|
|
_warn($context,"($context->{rownum}) " . 'expected error while re-provisioning subscriber ' . $context->{cli} . ' in dry-mode missing');
|
|
} else {
|
|
_error($context,"($context->{rownum}) " . 'expected error while re-provisioning subscriber ' . $context->{cli} . ' in dry-mode missing');
|
|
}
|
|
}
|
|
} else {
|
|
_create_contact($context);
|
|
_create_contract($context);
|
|
_create_subscriber($context);
|
|
_info($context,"($context->{rownum}) " . 'subscriber ' . $context->{cli} . ' successfully re-provisioned');
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
_info($context,"($context->{rownum}) " . 'existing billing subscriber with username ' . $context->{username} . ' and unchanged password found, skipping',1);
|
|
}
|
|
}
|
|
} else {
|
|
_warn($context,"($context->{rownum}) " . 'multiple (' . (scalar @$existing_billing_voip_subscribers) . ') existing billing subscribers with username ' . $context->{username} . ' found, skipping');
|
|
}
|
|
|
|
if ($dry) {
|
|
$context->{db}->db_rollback(0);
|
|
} else {
|
|
$context->{db}->db_commit();
|
|
}
|
|
|
|
};
|
|
my $err = $@;
|
|
if ($err) {
|
|
eval {
|
|
$context->{db}->db_rollback(1);
|
|
};
|
|
die($err) if !$skip_errors;
|
|
}
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
sub _provision_subscribers_checks {
|
|
my ($context) = @_;
|
|
|
|
my $result = 1;
|
|
my $optioncount = 0;
|
|
eval {
|
|
$optioncount = NGCP::BulkProcessor::Projects::Migration::IPGallery::Dao::import::FeatureOption::countby_subscribernumber_option();
|
|
};
|
|
if ($@ or $optioncount == 0) {
|
|
rowprocessingerror(threadid(),'please import subscriber features first',getlogger(__PACKAGE__));
|
|
$result = 0; #even in skip-error mode..
|
|
}
|
|
my $userpasswordcount = 0;
|
|
eval {
|
|
$userpasswordcount = NGCP::BulkProcessor::Projects::Migration::IPGallery::Dao::import::UsernamePassword::countby_fqdn();
|
|
};
|
|
if ($@ or $userpasswordcount == 0) {
|
|
rowprocessingerror(threadid(),'please import user passwords first',getlogger(__PACKAGE__));
|
|
$result = 0; #even in skip-error mode..
|
|
}
|
|
my $subscribercount = 0;
|
|
eval {
|
|
$subscribercount = NGCP::BulkProcessor::Projects::Migration::IPGallery::Dao::import::Subscriber::countby_subscribernumber();
|
|
};
|
|
if ($@ or $subscribercount == 0) {
|
|
rowprocessingerror(threadid(),'please import subscribers first',getlogger(__PACKAGE__));
|
|
$result = 0; #even in skip-error mode..
|
|
}
|
|
|
|
if ($batch) {
|
|
my $batch_size = 0;
|
|
eval {
|
|
$batch_size = NGCP::BulkProcessor::Projects::Migration::IPGallery::Dao::import::Batch::countby_delta({ 'NOT IN' =>
|
|
$NGCP::BulkProcessor::Projects::Migration::IPGallery::Dao::import::Batch::deleted_delta});
|
|
};
|
|
if ($@ or $batch_size == 0) {
|
|
rowprocessingerror(threadid(),'please import a batch first',getlogger(__PACKAGE__));
|
|
$result = 0; #even in skip-error mode..
|
|
}
|
|
}
|
|
|
|
eval {
|
|
$context->{sip_account_product} = NGCP::BulkProcessor::Dao::Trunk::billing::products::findby_resellerid_handle(undef,
|
|
$NGCP::BulkProcessor::Dao::Trunk::billing::products::SIP_ACCOUNT_HANDLE)->[0];
|
|
};
|
|
if ($@ or not defined $context->{sip_account_product}) {
|
|
rowprocessingerror(threadid(),'cannot find sip account product',getlogger(__PACKAGE__));
|
|
$result = 0; #even in skip-error mode..
|
|
}
|
|
|
|
eval {
|
|
$context->{billing_domain} = NGCP::BulkProcessor::Dao::Trunk::billing::domains::findby_domain($domain_name);
|
|
if (defined $context->{billing_domain}
|
|
and NGCP::BulkProcessor::Dao::Trunk::billing::domain_resellers::countby_domainid_resellerid($context->{billing_domain}->{id},$reseller_id) == 0) {
|
|
undef $context->{billing_domain};
|
|
}
|
|
};
|
|
if ($@ or not defined $context->{billing_domain}) {
|
|
rowprocessingerror(threadid(),'cannot find billing domain',getlogger(__PACKAGE__));
|
|
$result = 0; #even in skip-error mode..
|
|
}
|
|
|
|
eval {
|
|
$context->{provisioning_voip_domain} = NGCP::BulkProcessor::Dao::Trunk::provisioning::voip_domains::findby_domain($domain_name);
|
|
};
|
|
if ($@ or not defined $context->{provisioning_voip_domain}) {
|
|
rowprocessingerror(threadid(),'cannot find provisioning domain',getlogger(__PACKAGE__));
|
|
$result = 0; #even in skip-error mode..
|
|
}
|
|
|
|
my $billing_profile = undef;
|
|
eval {
|
|
$billing_profile = NGCP::BulkProcessor::Dao::Trunk::billing::billing_profiles::findby_id($billing_profile_id);
|
|
if (defined $billing_profile and $billing_profile->{reseller_id} != $reseller_id) {
|
|
undef $billing_profile;
|
|
}
|
|
};
|
|
if ($@ or not defined $billing_profile) {
|
|
rowprocessingerror(threadid(),'cannot find billing profile',getlogger(__PACKAGE__));
|
|
$result = 0; #even in skip-error mode..
|
|
}
|
|
|
|
eval {
|
|
$context->{allowed_clis_attribute} = NGCP::BulkProcessor::Dao::Trunk::provisioning::voip_preferences::findby_attribute(
|
|
$NGCP::BulkProcessor::Dao::Trunk::provisioning::voip_preferences::ALLOWED_CLIS_ATTRIBUTE);
|
|
};
|
|
if ($@ or not defined $context->{allowed_clis_attribute}) {
|
|
rowprocessingerror(threadid(),'cannot find allowed_clis attribute',getlogger(__PACKAGE__));
|
|
$result = 0; #even in skip-error mode..
|
|
}
|
|
|
|
eval {
|
|
$context->{cli_attribute} = NGCP::BulkProcessor::Dao::Trunk::provisioning::voip_preferences::findby_attribute(
|
|
$NGCP::BulkProcessor::Dao::Trunk::provisioning::voip_preferences::CLI_ATTRIBUTE);
|
|
};
|
|
if ($@ or not defined $context->{cli_attribute}) {
|
|
rowprocessingerror(threadid(),'cannot find cli attribute',getlogger(__PACKAGE__));
|
|
$result = 0; #even in skip-error mode..
|
|
}
|
|
|
|
eval {
|
|
$context->{ac_attribute} = NGCP::BulkProcessor::Dao::Trunk::provisioning::voip_preferences::findby_attribute(
|
|
$NGCP::BulkProcessor::Dao::Trunk::provisioning::voip_preferences::AC_ATTRIBUTE);
|
|
};
|
|
if ($@ or not defined $context->{ac_attribute}) {
|
|
rowprocessingerror(threadid(),'cannot find ac attribute',getlogger(__PACKAGE__));
|
|
$result = 0; #even in skip-error mode..
|
|
}
|
|
|
|
eval {
|
|
$context->{cc_attribute} = NGCP::BulkProcessor::Dao::Trunk::provisioning::voip_preferences::findby_attribute(
|
|
$NGCP::BulkProcessor::Dao::Trunk::provisioning::voip_preferences::CC_ATTRIBUTE);
|
|
};
|
|
if ($@ or not defined $context->{cc_attribute}) {
|
|
rowprocessingerror(threadid(),'cannot find cc attribute',getlogger(__PACKAGE__));
|
|
$result = 0; #even in skip-error mode..
|
|
}
|
|
|
|
eval {
|
|
$context->{account_id_attribute} = NGCP::BulkProcessor::Dao::Trunk::provisioning::voip_preferences::findby_attribute(
|
|
$NGCP::BulkProcessor::Dao::Trunk::provisioning::voip_preferences::ACCOUNT_ID_ATTRIBUTE);
|
|
};
|
|
if ($@ or not defined $context->{account_id_attribute}) {
|
|
rowprocessingerror(threadid(),'cannot find account_id attribute',getlogger(__PACKAGE__));
|
|
$result = 0; #even in skip-error mode..
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
|
|
sub _create_contact {
|
|
|
|
my ($context) = @_;
|
|
|
|
$context->{contact_id} = NGCP::BulkProcessor::Dao::Trunk::billing::contacts::insert_row($context->{db},
|
|
reseller_id => $reseller_id,
|
|
email => sprintf($contact_email_format,$context->{username}), #$context->{cli}
|
|
);
|
|
#my $contact_id = NGCP::BulkProcessor::Dao::Trunk::billing::contacts::insert_row($db,{
|
|
# reseller_id => $reseller_id,
|
|
# email => sprintf($contact_email_format,$cli),
|
|
#});
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
sub _create_contract {
|
|
|
|
my ($context) = @_;
|
|
|
|
$context->{contract_id} = NGCP::BulkProcessor::Dao::Trunk::billing::contracts::insert_row($context->{db},
|
|
contact_id => $context->{contact_id},
|
|
);
|
|
|
|
$context->{billing_mapping_id} = NGCP::BulkProcessor::Dao::Trunk::billing::billing_mappings::insert_row($context->{db},
|
|
billing_profile_id => $billing_profile_id,
|
|
contract_id => $context->{contract_id},
|
|
product_id => $context->{sip_account_product}->{id},
|
|
);
|
|
|
|
$context->{contract_balance_id} = NGCP::BulkProcessor::Dao::Trunk::billing::contract_balances::insert_row($context->{db},
|
|
contract_id => $context->{contract_id},
|
|
);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
sub _create_subscriber {
|
|
|
|
my ($context) = @_;
|
|
|
|
my $result = 1;
|
|
|
|
$context->{billing_subscriber_id} = NGCP::BulkProcessor::Dao::Trunk::billing::voip_subscribers::insert_row($context->{db},
|
|
contract_id => $context->{contract_id},
|
|
domain_id => $context->{billing_domain}->{id},
|
|
username => $context->{username},
|
|
uuid => $context->{subscriber_uuid},
|
|
);
|
|
|
|
$context->{provisioning_subscriber_id} = NGCP::BulkProcessor::Dao::Trunk::provisioning::voip_subscribers::insert_row($context->{db},
|
|
account_id => $context->{contract_id},
|
|
domain_id => $context->{provisioning_voip_domain}->{id},
|
|
password => $context->{password},
|
|
username => $context->{username},
|
|
uuid => $context->{subscriber_uuid},
|
|
webpassword => $context->{webpassword},
|
|
webusername => $context->{webusername},
|
|
);
|
|
|
|
my $voip_number = NGCP::BulkProcessor::Dao::Trunk::billing::voip_numbers::forupdate_cc_ac_sn_subscriberid($context->{db},
|
|
$context->{e164}->{cc},$context->{e164}->{ac},$context->{e164}->{sn},$context->{billing_subscriber_id});
|
|
|
|
if (defined $voip_number) {
|
|
$context->{voip_number_id} = $voip_number->{id};
|
|
$result &= NGCP::BulkProcessor::Dao::Trunk::billing::voip_numbers::update_row($context->{db},{
|
|
id => $context->{voip_number_id},
|
|
reseller_id => $reseller_id,
|
|
subscriber_id => $context->{billing_subscriber_id},
|
|
});
|
|
} else {
|
|
$context->{voip_number_id} = NGCP::BulkProcessor::Dao::Trunk::billing::voip_numbers::insert_row($context->{db},
|
|
cc => $context->{e164}->{cc},
|
|
ac => $context->{e164}->{ac},
|
|
sn => $context->{e164}->{sn},
|
|
reseller_id => $reseller_id,
|
|
subscriber_id => $context->{billing_subscriber_id},
|
|
);
|
|
}
|
|
|
|
$context->{cli_preference_id} = set_preference($context,$context->{provisioning_subscriber_id},$context->{cli_attribute},$context->{cli});
|
|
|
|
$result &= NGCP::BulkProcessor::Dao::Trunk::billing::voip_subscribers::update_row($context->{db},{
|
|
id => $context->{billing_subscriber_id},
|
|
primary_number_id => $context->{voip_number_id},
|
|
});
|
|
|
|
$context->{voip_dbalias_id} = NGCP::BulkProcessor::Dao::Trunk::provisioning::voip_dbaliases::insert_row($context->{db},
|
|
domain_id => $context->{provisioning_voip_domain}->{id},
|
|
subscriber_id => $context->{provisioning_subscriber_id},
|
|
username => $context->{cli},
|
|
);
|
|
|
|
$context->{allowed_clis_preference_id} = set_preference($context,$context->{provisioning_subscriber_id},$context->{allowed_clis_attribute},$context->{cli});
|
|
|
|
$result &= NGCP::BulkProcessor::Dao::Trunk::billing::voip_numbers::release_subscriber_numbers($context->{db},
|
|
$context->{billing_subscriber_id},{ 'NOT IN' => $context->{voip_number_id} });
|
|
|
|
$result &= NGCP::BulkProcessor::Dao::Trunk::provisioning::voip_dbaliases::delete_dbaliases($context->{db},
|
|
$context->{provisioning_voip_domain}->{id},{ 'NOT IN' => $context->{cli} });
|
|
|
|
clear_preferences($context,$context->{provisioning_subscriber_id},$context->{allowed_clis_attribute},$context->{cli});
|
|
|
|
#voicemail
|
|
$context->{voicemail_user_id} = NGCP::BulkProcessor::Dao::Trunk::kamailio::voicemail_users::insert_row($context->{db},
|
|
customer_id => $context->{subscriber_uuid},
|
|
mailbox => $context->{cli},
|
|
password => $context->{mailbox_pin},
|
|
);
|
|
|
|
$context->{account_id_preference_id} = set_preference($context,$context->{provisioning_subscriber_id},$context->{account_id_attribute},$context->{contract_id});
|
|
if (defined $context->{e164}->{ac} and length($context->{e164}->{ac}) > 0) {
|
|
$context->{ac_preference_id} = set_preference($context,$context->{provisioning_subscriber_id},$context->{ac_attribute},$context->{e164}->{ac});
|
|
}
|
|
if (defined $context->{e164}->{cc} and length($context->{e164}->{cc}) > 0) {
|
|
$context->{cc_preference_id} = set_preference($context,$context->{provisioning_subscriber_id},$context->{cc_attribute},$context->{e164}->{cc});
|
|
}
|
|
|
|
return $result;
|
|
|
|
}
|
|
|
|
|
|
sub _reset_context {
|
|
|
|
my ($context,$imported_subscriber,$rownum) = @_;
|
|
|
|
my $result = 1;
|
|
|
|
$context->{rownum} = $rownum;
|
|
|
|
$context->{cli} = $imported_subscriber->subscribernumber();
|
|
$context->{e164} = {};
|
|
$context->{e164}->{cc} = substr($context->{cli},0,3);
|
|
$context->{e164}->{ac} = '';
|
|
$context->{e164}->{sn} = substr($context->{cli},3);
|
|
|
|
my $userpassword = NGCP::BulkProcessor::Projects::Migration::IPGallery::Dao::import::UsernamePassword::findby_fqdn($context->{cli});
|
|
if (defined $userpassword) {
|
|
$context->{username} = (defined $subsciber_username_prefix ? $subsciber_username_prefix : '') . $userpassword->{username};
|
|
$context->{password} = $userpassword->{password};
|
|
$context->{userpassworddelta} = $userpassword->{delta};
|
|
} else {
|
|
# once full username+passwords is available:
|
|
delete $context->{username};
|
|
delete $context->{password};
|
|
delete $context->{userpassworddelta};
|
|
if ($imported_subscriber->{delta} eq
|
|
$NGCP::BulkProcessor::Projects::Migration::IPGallery::Dao::import::Subscriber::deleted_delta) {
|
|
|
|
} else {
|
|
$result &= 0;
|
|
|
|
# for now, as username+passwords are incomplete:
|
|
#$context->{username} = $context->{e164}->{sn};
|
|
#$context->{password} = $context->{username};
|
|
#$context->{userpassworddelta} = $NGCP::BulkProcessor::Projects::Migration::IPGallery::Dao::import::UsernamePassword::updated_delta;
|
|
|
|
if ($skip_errors) {
|
|
# for now, as username+passwords are incomplete:
|
|
_warn($context,"($context->{rownum}) " . 'no username/password for subscriber found: ' . $context->{cli});
|
|
} else {
|
|
_error($context,"($context->{rownum}) " . 'no username/password for subscriber found: ' . $context->{cli});
|
|
}
|
|
}
|
|
}
|
|
|
|
$context->{webusername} = $context->{username};
|
|
if ($generate_webpassword) {
|
|
$context->{webpassword} = _generate_webpassword();
|
|
} else {
|
|
my $webpassword = NGCP::BulkProcessor::Projects::Migration::IPGallery::Dao::import::FeatureOptionSetItem::findby_subscribernumber_option_optionsetitem($context->{cli},
|
|
$NGCP::BulkProcessor::Projects::Migration::IPGallery::Dao::import::FeatureOptionSetItem::WEB_PASSWORD_OPTION_SET)->[0];
|
|
if (defined $webpassword) {
|
|
$context->{webpassword} = $webpassword->{optionsetitem};
|
|
} else {
|
|
$context->{webpassword} = undef;
|
|
}
|
|
}
|
|
|
|
$context->{subscriber_uuid} = create_uuid();
|
|
$context->{mailbox_pin} = sprintf("%04d", int(rand 10000));
|
|
|
|
delete $context->{contact_id};
|
|
delete $context->{contract_id};
|
|
delete $context->{billing_mapping_id};
|
|
delete $context->{contract_balance_id};
|
|
|
|
delete $context->{billing_subscriber_id};
|
|
delete $context->{provisioning_subscriber_id};
|
|
delete $context->{voip_number_id};
|
|
delete $context->{cli_preference_id};
|
|
delete $context->{voip_dbalias_id};
|
|
delete $context->{allowed_clis_preference_id};
|
|
delete $context->{account_id_preference_id};
|
|
delete $context->{ac_preference_id};
|
|
delete $context->{cc_preference_id};
|
|
delete $context->{voicemail_user_id};
|
|
|
|
return $result;
|
|
|
|
}
|
|
|
|
sub _generate_webpassword {
|
|
return String::MkPasswd::mkpasswd(
|
|
-length => $webpassword_length,
|
|
-minnum => 1, -minlower => 1, -minupper => 1, -minspecial => 1,
|
|
-distribute => 1, -fatal => 1,
|
|
);
|
|
}
|
|
|
|
sub _terminate_subscriber {
|
|
my ($context,$billing_subscriber_id) = @_;
|
|
|
|
my $result = 0;
|
|
my $subscriber_path = NGCP::BulkProcessor::RestRequests::Trunk::Subscribers::get_item_path($billing_subscriber_id);
|
|
eval {
|
|
if ($dry) {
|
|
my $subscriber = NGCP::BulkProcessor::RestRequests::Trunk::Subscribers::get_item($billing_subscriber_id);
|
|
$result = (defined $subscriber ? 1 : 0);
|
|
} else {
|
|
$result = NGCP::BulkProcessor::RestRequests::Trunk::Subscribers::delete_item($billing_subscriber_id);
|
|
}
|
|
};
|
|
if ($@ or not $result) {
|
|
if ($skip_errors) {
|
|
_warn($context,"($context->{rownum}) " . 'subscriber ' . $context->{cli} . ': could not ' . ($dry ? 'fetch' : 'terminate') . ' old subscriber ' . $subscriber_path);
|
|
} else {
|
|
_error($context,"($context->{rownum}) " . 'subscriber ' . $context->{cli} . ': could not ' . ($dry ? 'fetch' : 'terminate') . ' old subscriber ' . $subscriber_path);
|
|
}
|
|
} else {
|
|
_info($context,"($context->{rownum}) " . 'subscriber ' . $context->{cli} . ': old subscriber ' . $subscriber_path . ($dry ? ' fetched' : ' terminated'));
|
|
}
|
|
return $result;
|
|
|
|
}
|
|
|
|
sub _terminate_contract {
|
|
my ($context,$contract_id) = @_;
|
|
|
|
my $result = 0;
|
|
my $contract_path = NGCP::BulkProcessor::RestRequests::Trunk::Customers::get_item_path($contract_id);
|
|
eval {
|
|
my $customer;
|
|
if ($dry) {
|
|
$customer = NGCP::BulkProcessor::RestRequests::Trunk::Customers::get_item($contract_id);
|
|
} else {
|
|
$customer = NGCP::BulkProcessor::RestRequests::Trunk::Customers::update_item($contract_id,{
|
|
status => $NGCP::BulkProcessor::RestRequests::Trunk::Customers::TERMINATED_STATE,
|
|
});
|
|
}
|
|
$result = (defined $customer ? 1 : 0);
|
|
};
|
|
if ($@ or not $result) {
|
|
if ($skip_errors) {
|
|
_warn($context,"($context->{rownum}) " . 'subscriber ' . $context->{cli} . ': could not ' . ($dry ? 'fetch' : 'terminate') . ' old contract ' . $contract_path);
|
|
} else {
|
|
_error($context,"($context->{rownum}) " . 'subscriber ' . $context->{cli} . ': could not ' . ($dry ? 'fetch' : 'terminate') . ' old contract ' . $contract_path);
|
|
}
|
|
} else {
|
|
_info($context,"($context->{rownum}) " . 'subscriber ' . $context->{cli} . ': old contract ' . $contract_path . ($dry ? ' fetched' : ' terminated'));
|
|
}
|
|
return $result;
|
|
|
|
}
|
|
|
|
sub _error {
|
|
|
|
my ($context,$message) = @_;
|
|
$context->{error_count} = $context->{error_count} + 1;
|
|
rowprocessingerror($context->{tid},$message,getlogger(__PACKAGE__));
|
|
|
|
}
|
|
|
|
sub _warn {
|
|
|
|
my ($context,$message) = @_;
|
|
$context->{warning_count} = $context->{warning_count} + 1;
|
|
rowprocessingwarn($context->{tid},$message,getlogger(__PACKAGE__));
|
|
|
|
}
|
|
|
|
sub _info {
|
|
|
|
my ($context,$message,$debug) = @_;
|
|
if ($debug) {
|
|
processing_debug($context->{tid},$message,getlogger(__PACKAGE__));
|
|
} else {
|
|
processing_info($context->{tid},$message,getlogger(__PACKAGE__));
|
|
}
|
|
}
|
|
|
|
1;
|