From c1c1117600e5cc072458a059902a928b4ab1bfa5 Mon Sep 17 00:00:00 2001 From: Gerhard Jungwirth Date: Wed, 9 Jul 2014 15:59:05 +0200 Subject: [PATCH] MT#8035 Write start_ivr and end_ivr events when updating cf_mappings or cf_destination_sets one entry per cf_mapping --- lib/NGCP/Panel/Controller/Subscriber.pm | 68 +++++++++++++++++--- lib/NGCP/Panel/Role/API/CFDestinationSets.pm | 11 ++++ lib/NGCP/Panel/Role/API/CFMappings.pm | 25 +++++++ lib/NGCP/Panel/Role/API/CallForwards.pm | 11 ++++ lib/NGCP/Panel/Utils/Subscriber.pm | 52 +++++++++++++++ 5 files changed, 157 insertions(+), 10 deletions(-) diff --git a/lib/NGCP/Panel/Controller/Subscriber.pm b/lib/NGCP/Panel/Controller/Subscriber.pm index e8efd38426..7c5c2b0c48 100644 --- a/lib/NGCP/Panel/Controller/Subscriber.pm +++ b/lib/NGCP/Panel/Controller/Subscriber.pm @@ -982,19 +982,17 @@ sub preferences_callforward :Chained('base') :PathPart('preferences/callforward' $c->model('DB')->schema->txn_do( sub { my $map = $cf_mapping->first; my $dest_set; + my $old_autoattendant = 0; if($map && $map->destination_set) { $dest_set = $map->destination_set; + $old_autoattendant = NGCP::Panel::Utils::Subscriber::check_dset_autoattendant_status($dest_set); + $dest_set->voip_cf_destinations->delete_all; } unless($dest_set) { $dest_set = $c->model('DB')->resultset('voip_cf_destination_sets')->create({ name => 'quickset_'.$cf_type, subscriber_id => $prov_subscriber->id, }); - } else { - my @all = $dest_set->voip_cf_destinations->all; - foreach my $dest(@all) { - $dest->delete; - } } my $numberstr = ""; @@ -1009,6 +1007,12 @@ sub preferences_callforward :Chained('base') :PathPart('preferences/callforward' my $dest = $cf_form->field('destination'); my $d = $dest->field('destination')->value; my $t = 300; + NGCP::Panel::Utils::Subscriber::check_cf_ivr( + subscriber => $c->stash->{subscriber}, + schema => $c->model('DB'), + old_aa => $old_autoattendant, + new_aa => ($d eq 'autoattendant'), + ); if ($d eq "uri") { $t = $dest->field('uri')->field('timeout')->value; # TODO: check for valid timeout here @@ -1167,14 +1171,14 @@ sub preferences_callforward_advanced :Chained('base') :PathPart('preferences/cal if($posted && $cf_form->validated) { try { $c->model('DB')->schema->txn_do( sub { + my $autoattendant_count = 0; my @active = $cf_form->field('active_callforward')->fields; - if($cf_mapping->count) { + if($cf_mapping->first) { # there are mappings foreach my $map($cf_mapping->all) { + $autoattendant_count += NGCP::Panel::Utils::Subscriber::check_dset_autoattendant_status($map->destination_set); $map->delete; - foreach my $cf($cf_preference->all) { - $cf->delete; - } } + $cf_preference->delete_all; unless(@active) { $ringtimeout_preference->first->delete if($cf_type eq "cft" && $ringtimeout_preference->first); @@ -1194,6 +1198,26 @@ sub preferences_callforward_advanced :Chained('base') :PathPart('preferences/cal time_set_id => $map->field('time_set')->value, }); $cf_preference->create({ value => $m->id }); + $autoattendant_count -= NGCP::Panel::Utils::Subscriber::check_dset_autoattendant_status($m->destination_set); + } + if ($autoattendant_count > 0) { + while ($autoattendant_count != 0) { + $autoattendant_count--; + NGCP::Panel::Utils::Events::insert( + schema => $c->model('DB'), + subscriber => $c->stash->{subscriber}, + type => 'end_ivr', + ); + } + } elsif ($autoattendant_count < 0) { + while ($autoattendant_count != 0) { + $autoattendant_count++; + NGCP::Panel::Utils::Events::insert( + schema => $c->model('DB'), + subscriber => $c->stash->{subscriber}, + type => 'start_ivr', + ); + } } if($cf_type eq "cft") { if($ringtimeout_preference->first) { @@ -1438,12 +1462,18 @@ sub preferences_callforward_destinationset_edit :Chained('preferences_callforwar # delete whole set and mapping if empty my @fields = $form->field('destination')->fields; unless(@fields) { - foreach my $mapping($set->voip_cf_mappings) { + foreach my $mapping($set->voip_cf_mappings->all) { my $cf = $cf_preference->find({ value => $mapping->id }); $cf->delete if $cf; $ringtimeout_preference->first->delete if($cf_type eq "cft" && $ringtimeout_preference->first); $mapping->delete; + NGCP::Panel::Utils::Subscriber::check_cf_ivr( # one event per affected mapping + subscriber => $c->stash->{subscriber}, + schema => $schema, + old_aa => NGCP::Panel::Utils::Subscriber::check_dset_autoattendant_status($set), + new_aa => 0, + ); } $set->delete; NGCP::Panel::Utils::Navigation::back_or($c, $fallback, 1); @@ -1452,6 +1482,7 @@ sub preferences_callforward_destinationset_edit :Chained('preferences_callforwar if($form->field('name')->value ne $set->name) { $set->update({name => $form->field('name')->value}); } + my $old_autoattendant = NGCP::Panel::Utils::Subscriber::check_dset_autoattendant_status($set); $set->voip_cf_destinations->delete_all; my $number = $c->stash->{subscriber}->primary_number; @@ -1483,6 +1514,23 @@ sub preferences_callforward_destinationset_edit :Chained('preferences_callforwar priority => $dest->field('priority')->value, }); } + $set->discard_changes; # reload (destinations may be cached) + my $new_autoattendant = NGCP::Panel::Utils::Subscriber::check_dset_autoattendant_status($set); + my $event_type = ''; + if (!$old_autoattendant && $new_autoattendant) { + $event_type = 'start_ivr'; + } elsif ($old_autoattendant && !$new_autoattendant) { + $event_type = 'end_ivr'; + } + if ($event_type) { + foreach my $mapping ($set->voip_cf_mappings->all) { # one event per affected mapping + NGCP::Panel::Utils::Events::insert( + schema => $schema, + subscriber => $c->stash->{subscriber}, + type => $event_type, + ); + } + } }); } catch($e) { $c->log->error("failed to update destination set: $e"); diff --git a/lib/NGCP/Panel/Role/API/CFDestinationSets.pm b/lib/NGCP/Panel/Role/API/CFDestinationSets.pm index e3296e6a08..205c33df12 100644 --- a/lib/NGCP/Panel/Role/API/CFDestinationSets.pm +++ b/lib/NGCP/Panel/Role/API/CFDestinationSets.pm @@ -139,6 +139,7 @@ sub update_item { name => $resource->{name}, subscriber_id => $subscriber->id, })->discard_changes; + my $old_aa = NGCP::Panel::Utils::Subscriber::check_dset_autoattendant_status($item); $item->voip_cf_destinations->delete; for my $d ( @{$resource->{destinations}} ) { delete $d->{destination_set_id}; @@ -150,6 +151,16 @@ sub update_item { ); $item->create_related("voip_cf_destinations", $d); } + $item->discard_changes; + my $new_aa = NGCP::Panel::Utils::Subscriber::check_dset_autoattendant_status($item); + foreach ($item->voip_cf_mappings->all) { + NGCP::Panel::Utils::Subscriber::check_cf_ivr( # one event per affected mapping + schema => $schema, + subscriber => $item->subscriber->voip_subscriber, + old_aa => $old_aa, + new_aa => $new_aa, + ); + } } catch($e) { $c->log->error("failed to create cfdestinationset: $e"); $self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to create cfdestinationset."); diff --git a/lib/NGCP/Panel/Role/API/CFMappings.pm b/lib/NGCP/Panel/Role/API/CFMappings.pm index def9c7002b..9400b7cb25 100644 --- a/lib/NGCP/Panel/Role/API/CFMappings.pm +++ b/lib/NGCP/Panel/Role/API/CFMappings.pm @@ -157,6 +157,10 @@ sub update_item { } try { + my $autoattendant_count = 0; + foreach my $map($mappings_rs->all) { + $autoattendant_count += NGCP::Panel::Utils::Subscriber::check_dset_autoattendant_status($map->destination_set); + } $mappings_rs->delete; for my $type ( qw/cfu cfb cft cfna/) { $cf_preferences{$type}->delete; @@ -164,6 +168,27 @@ sub update_item { for my $mapping ( @new_mappings ) { $mapping->insert; $cf_preferences{$mapping->type}->create({ value => $mapping->id }); + $autoattendant_count -= NGCP::Panel::Utils::Subscriber::check_dset_autoattendant_status($mapping->destination_set); + } + + if ($autoattendant_count > 0) { + while ($autoattendant_count != 0) { + $autoattendant_count--; + NGCP::Panel::Utils::Events::insert( + schema => $c->model('DB'), + subscriber => $item, + type => 'end_ivr', + ); + } + } elsif ($autoattendant_count < 0) { + while ($autoattendant_count != 0) { + $autoattendant_count++; + NGCP::Panel::Utils::Events::insert( + schema => $c->model('DB'), + subscriber => $item, + type => 'start_ivr', + ); + } } if ($resource->{cft_ringtimeout} && $resource->{cft_ringtimeout} > 0) { diff --git a/lib/NGCP/Panel/Role/API/CallForwards.pm b/lib/NGCP/Panel/Role/API/CallForwards.pm index 123f1d7863..5ce61cc104 100644 --- a/lib/NGCP/Panel/Role/API/CallForwards.pm +++ b/lib/NGCP/Panel/Role/API/CallForwards.pm @@ -173,6 +173,7 @@ sub update_item { $number = '' } my $domain = $prov_subs->domain->domain // ''; + my $old_autoattendant = NGCP::Panel::Utils::Subscriber::check_dset_autoattendant_status($dset); if ($dset) { if ((defined $resource->{$type}{destinations}) && @{ $resource->{$type}{destinations}}) { $dset->voip_cf_destinations->delete; #empty dset @@ -211,6 +212,16 @@ sub update_item { delete $t->{time_set_id}; $tset->voip_cf_periods->update_or_create($t); } + + $dset->discard_changes if $dset; # update destinations + my $new_autoattendant = NGCP::Panel::Utils::Subscriber::check_dset_autoattendant_status($dset); + NGCP::Panel::Utils::Subscriber::check_cf_ivr( + subscriber => $item, + schema => $c->model('DB'), + old_aa => $old_autoattendant, + new_aa => $new_autoattendant, + ); + unless ( $dset && $dset->voip_cf_destinations->count ) { $mapping->delete; $cf_preference->delete; diff --git a/lib/NGCP/Panel/Utils/Subscriber.pm b/lib/NGCP/Panel/Utils/Subscriber.pm index 3b007f7b82..1e1bb026db 100644 --- a/lib/NGCP/Panel/Utils/Subscriber.pm +++ b/lib/NGCP/Panel/Utils/Subscriber.pm @@ -982,6 +982,41 @@ sub apply_rewrite { return $callee; } +sub check_cf_ivr { + my (%params) = @_; + + my $subscriber = $params{subscriber}; + my $schema = $params{schema}; + my $new_aa = $params{new_aa}; # boolean, false on delete + my $old_aa = $params{old_aa}; # boolean, false on create + if ($old_aa && !$new_aa) { + NGCP::Panel::Utils::Events::insert( + schema => $schema, subscriber => $subscriber, + type => 'end_ivr', + ); + } elsif (!$old_aa && $new_aa) { + NGCP::Panel::Utils::Events::insert( + schema => $schema, subscriber => $subscriber, + type => 'start_ivr', + ); + } + return; +} + +sub check_dset_autoattendant_status { + my ($dset) = @_; + + my $status = 0; + if ($dset) { + for my $dest ($dset->voip_cf_destinations->all) { + if ( (destination_to_field($dest->destination))[0] eq 'autoattendant' ) { + $status = 1; + } + } + } + return $status; +} + 1; =head1 NAME @@ -1002,6 +1037,23 @@ has no subscriber_id set. In that case we can just reuse that number. If the number does not exist at all, we just create it. For reference see _get_number_for_update() in ossbss. +=head2 check_cf_ivr + +old_aa and new_aa are boolean params that determine if a cf mapping had an autoattendant +set before and after update. it will then create the according start_ivr or +end_ivr entry. + + the logic: + change/delete dset: + check each mapping + change/create/delete mapping: + check old/new dset (may be false) + +=head2 check_dset_autoattendant_status + +Returns a boolean value, if the dset has an autoattendant destination. Can be used +for check_cf_ivr(). + =head1 AUTHOR Andreas Granig,