Implement simple way of adding Call-Forwards.

agranig/1_0_subfix
Andreas Granig 13 years ago
parent a87ee3a34e
commit 6937ac595f

@ -228,6 +228,27 @@ sub preferences :Chained('base') :PathPart('preferences') :Args(0) {
$self->load_preference_list($c);
$c->stash(template => 'subscriber/preferences.tt');
my $prov_subscriber = $c->stash->{subscriber}->provisioning_voip_subscriber;
my $cfs = {};
for my $type(qw/cfu cfna cft cfb/) {
$c->stash('cf_mappings_'.$type => $prov_subscriber->voip_cf_mappings
->find({ type => $type }));
if(defined $c->stash->{'cf_mappings_'.$type}) {
$cfs->{$type} = [ $c->stash->{'cf_mappings_'.$type}
->destination_set
->voip_cf_destinations->search({},
{ order_by => { -asc => 'priority' }}
)->all ];
}
}
$c->stash(cf_destinations => $cfs);
my $ringtimeout_preference = $c->model('DB')->resultset('voip_preferences')->search({
attribute => 'ringtimeout', 'usr_pref' => 1,
})->first->voip_usr_preferences->find({
subscriber_id => $prov_subscriber->id,
});
$c->stash(cf_ringtimeout => $ringtimeout_preference ? $ringtimeout_preference->value : undef);
}
sub preferences_base :Chained('base') :PathPart('preferences') :CaptureArgs(1) {
@ -290,6 +311,48 @@ sub preferences_callforward :Chained('base') :PathPart('preferences/callforward'
}
}
my $posted = ($c->request->method eq 'POST');
my $voip_preferences = $c->model('DB')->resultset('voip_preferences')->search({
'usr_pref' => 1,
});
my $cf_preference = $voip_preferences->find({ 'attribute' => $cf_type })
->voip_usr_preferences;
my $ringtimeout_preference = $voip_preferences->find({ 'attribute' => 'ringtimeout' })
->voip_usr_preferences;
my $billing_subscriber = $c->stash->{subscriber};
my $prov_subscriber = $billing_subscriber->provisioning_voip_subscriber;
my $cf_mapping = $prov_subscriber->voip_cf_mappings->find({ type => $cf_type });
my $destination;
if($cf_mapping &&
$cf_mapping->destination_set &&
$cf_mapping->destination_set->voip_cf_destinations->first) {
$destination = $cf_mapping->destination_set->voip_cf_destinations->first;
}
my $params = {};
if($destination) {
$params->{destination} = $destination->destination;
if($cf_type eq 'cft') {
my $rt = $ringtimeout_preference->find({ subscriber_id => $prov_subscriber->id });
if($rt) {
$params->{ringtimeout} = $rt->value;
} else {
$params->{ringtimeout} = 15;
}
}
}
if($posted) {
$params = $c->request->params;
if($params->{destination} !~ /\@/) {
$params->{destination} .= '@'.$billing_subscriber->domain->domain;
}
if($params->{destination} !~ /^sip:/) {
$params->{destination} = 'sip:' . $params->{destination};
}
}
my $cf_form;
if($cf_type eq "cft") {
$cf_form = NGCP::Panel::Form::SubscriberCFTSimple->new;
@ -297,6 +360,85 @@ sub preferences_callforward :Chained('base') :PathPart('preferences/callforward'
$cf_form = NGCP::Panel::Form::SubscriberCFSimple->new;
}
# TODO: if more than one entry in $cf_mapping->voip_cf_destination_set->voip_cf_destinations,
# show advanced mode and list them all; same for time sets
$cf_form->process(
params => $params,
action => $c->uri_for_action('/subscriber/preferences', [$c->req->captures->[0], $c->req->captures->[1]])
);
if($posted && $cf_form->validated) {
try {
$c->model('DB')->schema->txn_do( sub {
my $dest_set = $c->model('DB')->resultset('voip_cf_destination_sets')->find({
subscriber_id => $prov_subscriber->id,
name => 'quickset_'.$cf_type,
});
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 $dest = $dest_set->voip_cf_destinations->create({
priority => 1,
timeout => 300,
destination => $c->request->params->{destination},
});
unless(defined $cf_mapping) {
$cf_mapping = $prov_subscriber->voip_cf_mappings->create({
type => $cf_type,
# subscriber_id => $prov_subscriber->id,
destination_set_id => $dest_set->id,
time_set_id => undef, #$time_set_id,
});
}
my $cf_preference_row = $cf_preference->find({
subscriber_id => $prov_subscriber->id
});
if($cf_preference_row) {
$cf_preference_row->update({ value => $cf_mapping->id });
} else {
$cf_preference->create({
subscriber_id => $prov_subscriber->id,
value => $cf_mapping->id,
});
}
if($cf_type eq 'cft') {
my $ringtimeout_preference_row = $ringtimeout_preference->find({
subscriber_id => $prov_subscriber->id
});
if($ringtimeout_preference_row) {
$ringtimeout_preference_row->update({
value => $c->request->params->{ringtimeout}
});
} else {
$ringtimeout_preference->create({
subscriber_id => $prov_subscriber->id,
value => $c->request->params->{ringtimeout},
});
}
}
});
} catch($e) {
$c->log->error("failed to save call-forward: $e");
$c->flash(messages => [{type => 'error', text => 'Failed to save Call Forward'}]);
$c->response->redirect($c->uri_for_action('/subscriber/preferences', [$c->req->captures->[0]]));
return;
}
$c->flash(messages => [{type => 'success', text => 'Successfully saved Call Forward'}]);
$c->response->redirect($c->uri_for_action('/subscriber/preferences', [$c->req->captures->[0]]));
return;
}
$self->load_preference_list($c);
$c->stash(template => 'subscriber/preferences.tt');
$c->stash(
@ -305,6 +447,14 @@ sub preferences_callforward :Chained('base') :PathPart('preferences/callforward'
cf_form => $cf_form,
);
}

@ -24,4 +24,15 @@ sub build_form_element_class {
return [qw(form-horizontal)];
}
sub validate_destination {
my ($self, $field) = @_;
# TODO: proper SIP URI check!
if($field->value !~ /^sip:.+\@.+$/) {
my $err_msg = 'Destination must be a valid SIP URI in format "sip:user@domain"';
$field->add_error($err_msg);
}
}
1;
# vim: set tabstop=4 expandtab:

@ -15,4 +15,14 @@ has_block 'fields' => (
render_list => [qw(destination ringtimeout)],
);
sub validate_ringtimeout {
my ($self, $field) = @_;
if($field->value < 1) {
my $err_msg = 'Ring Timeout must be greater than 0';
$field->add_error($err_msg);
}
}
1;
# vim: set tabstop=4 expandtab:

@ -52,69 +52,27 @@
</tr>
</thead>
<tbody>
[% FOR cf IN [ { type = "cfu", desc = "Unconditional" },
{ type = "cfb", desc = "Busy" },
{ type = "cft", desc = "Timeout" },
{ type = "cfna", desc = "Unavailable" } ] -%]
<tr class="sw_action_row">
<td>Call Forward Unconditional</td>
<td></td>
<td>Call Forward [% cf.desc %]</td>
<td>[% cf_ringtimeout IF cf.type == "cft" && cf_destinations.${cf.type}.size %]</td>
<td>
4312345<br/>
foo@bar.com<br/>
voicebox
[% FOR d IN cf_destinations.${cf.type} -%]
[% d.destination %] <span class="pull-right">for [% d.timeout %]s</span><br/>
[% END -%]
</td>
<td>always</td>
<td>[% 'always' IF cf_destinations.${cf.type}.size %]</td>
<td class="ngcp-actions-column">
<div class="sw_actions pull-right">
<a class="btn btn-primary btn-small" href="[% c.uri_for_action("/subscriber/preferences_callforward", [c.req.captures.0, "cfu"]) %]"><i class="icon-edit"></i> Edit</a>
</div>
</td>
</tr>
<tr class="sw_action_row">
<td>Call Forward Busy</td>
<td></td>
<td>
4312345<br/>
foo@bar.com<br/>
voicebox
</td>
<td>always</td>
<td class="ngcp-actions-column">
<div class="sw_actions pull-right">
<a class="btn btn-primary btn-small" href="[% c.uri_for_action("/subscriber/preferences_callforward", [c.req.captures.0, "cfb"]) %]"><i class="icon-edit"></i> Edit</a>
</div>
</td>
</tr>
<tr class="sw_action_row">
<td>Call Forward Timeout</td>
<td>15s</td>
<td>
4312345<br/>
foo@bar.com<br/>
voicebox
</td>
<td>always</td>
<td class="ngcp-actions-column">
<div class="sw_actions pull-right">
<a class="btn btn-primary btn-small" href="[% c.uri_for_action("/subscriber/preferences_callforward", [c.req.captures.0, "cft"]) %]"><i class="icon-edit"></i> Edit</a>
</div>
</td>
</tr>
<tr class="sw_action_row">
<td>Call Forward Unavailable</td>
<td></td>
<td>
4312345<br/>
foo@bar.com<br/>
voicebox
</td>
<td>always</td>
<td class="ngcp-actions-column">
<div class="sw_actions pull-right">
<a class="btn btn-primary btn-small" href="[% c.uri_for_action("/subscriber/preferences_callforward", [c.req.captures.0, "cfna"]) %]"><i class="icon-edit"></i> Edit</a>
<a class="btn btn-primary btn-small" href="[% c.uri_for_action("/subscriber/preferences_callforward", [c.req.captures.0, cf.type]) %]"><i class="icon-edit"></i> Edit</a>
</div>
</td>
</tr>
[% END -%]
</tbody>
</table>

Loading…
Cancel
Save