TT#40509 Add "default" option to timezone select

Change-Id: Id9f12d57c8cc18e2b2de1eef63f003ff5f791863
changes/18/22718/11
Irina Peshinskaya 7 years ago
parent abbd681754
commit 10f57f11e8

@ -40,15 +40,17 @@ sub list_contact :Chained('/') :PathPart('contact') :CaptureArgs(0) :Does(ACL) :
]);
}
sub timezone_ajax :Chained('/') :PathPart('contact/timezone_ajax') :Args(0) {
my ($self, $c) = @_;
sub timezone_ajax :Chained('/') :PathPart('contact/timezone_ajax') :Args() {
my ($self, $c, $parent_owner_type, $parent_owner_id) = @_;
my $default_tz_data = NGCP::Panel::Utils::DateTime::get_default_timezone_name($c, $parent_owner_type, $parent_owner_id);
my $tz_rs = $c->model('DB')->resultset('timezones');
my $tz_rs = $c->model('DB')->resultset('timezones');
my $tz_cols = NGCP::Panel::Utils::Datatables::set_columns($c, [
{ name => "name", search => 1, title => $c->loc('Timezone') },
]);
NGCP::Panel::Utils::Datatables::process($c, $tz_rs, $tz_cols);
NGCP::Panel::Utils::Datatables::process($c, $tz_rs, $tz_cols, undef, { topData => $default_tz_data } );
$c->detach( $c->view("JSON") );
}

@ -2797,7 +2797,7 @@ sub edit_master :Chained('master') :PathPart('edit') :Args(0) :Does(ACL) :ACLDet
$schema->txn_do(sub {
my $email = delete $form->params->{email} || undef;
my $timezone = delete $form->params->{timezone}{name} || undef;
my $timezone = delete $form->values->{timezone}{name} || undef;
if ($subscriber->contact) {
$subscriber->contact->update({
email => $email,

@ -17,18 +17,17 @@ has 'custom_renderers' => ( isa => 'HashRef', is => 'rw' );
has 'no_ordering' => ( isa => 'Bool', is => 'rw' );
has 'language_file' => (isa => 'Str', is => 'rw', default => 'dataTables.default.js' );
#didn't want to incude some complex role related logic here,
#as these DataTable fields also are used in API
#To don't slow down API
#traits => ['Code']
has 'adjust_datatable_vars' => ( isa => 'CodeRef', is => 'rw' );
sub render_element {
my ($self) = @_;
my $output = '';
(my $tablename = $self->html_name) =~ s!\.!!g;
if($self->ajax_src !~/dt_columns/){
my $i = 0;
my $dt_columns = [ map {{name=>$_,title=>$self->table_titles->[$i++],}} @{$self->table_fields} ];
my $decoder = URI::Encode->new;
$self->ajax_src( $self->ajax_src.($self->ajax_src!~/\?/?'?':'&').'dt_columns='.$decoder->encode(to_json($dt_columns)) );
}
my $vars = {
label => $self->label,
field_name => $self->html_name,
@ -44,7 +43,8 @@ sub render_element {
language_file => $self->language_file,
wrapper_class => ref $self->wrapper_class eq 'ARRAY' ? join (' ', @{$self->wrapper_class}) : $self->wrapper_class,
};
ref $self->adjust_datatable_vars eq 'CODE' and $self->adjust_datatable_vars->($self, $vars);
my $t = new Template({
ABSOLUTE => 1,
INCLUDE_PATH => [

@ -1,4 +1,5 @@
package NGCP::Panel::Field::TimezoneSelect;
use HTML::FormHandler::Moose;
use NGCP::Panel::Utils::DateTime;
extends 'HTML::FormHandler::Field::Compound';
@ -13,10 +14,17 @@ has_field 'name' => (
ajax_src => '/contact/timezone_ajax',
table_titles => ['Name'],
table_fields => ['name'],
adjust_datatable_vars => \&adjust_datatable_vars,
inflate_default_method => \&inflate_timezone,#from db to form
deflate_value_method => \&deflate_timezone,#from form to db
);
sub validate {
my $self = shift;
my $form = $self->form;
my $c = $form->ctx;
return unless $c;
my $value = $self->value;
if (ref $value && exists $value->{name}) {
$value = $value->{name};
@ -25,14 +33,102 @@ sub validate {
sprintf 'Invalid validation of unparsed input: %s', $value);
return;
}
#is_valid_timezone_name($tz, $all, $c, $allow_empty)
#unless(grep { /^\Q$value\E$/ } DateTime::TimeZone->all_names) {
unless (NGCP::Panel::Utils::DateTime::is_valid_timezone_name($value)) {
unless (NGCP::Panel::Utils::DateTime::is_valid_timezone_name($value, 0, $c, 1)) {
$self->add_error(sprintf 'Invalid timezone name: %s', $value);
}
return;
}
sub adjust_datatable_vars {
my ($self, $vars) = @_;
my $form = $self->form;
my $ctx = $form->ctx;
return unless $ctx;
my ($tz_owner_parent_type, $tz_owner_parent_id) = get_parent_info($ctx);
$vars->{ajax_src} = (
$ctx->uri_for_action('/contact/timezone_ajax', $tz_owner_parent_type, $tz_owner_parent_id)->as_string
);
}
sub deflate_timezone { # deflate: default value: clean and return empty string
my ( $self, $value ) = @_;
my $c = $self->form->ctx;
$value = NGCP::Panel::Utils::DateTime::strip_empty_timezone_name($c, $value);
return $value;
}
sub inflate_timezone { # inflate: name empty timezone properly so it could be checked by form
my ($self, $value) = @_;
if (!$value) {
my $c = $self->form->ctx;
my ($parent_owner_type, $parent_owner_id) = get_parent_info($c);
my $default_tz_data = NGCP::Panel::Utils::DateTime::get_default_timezone_name($c, $parent_owner_type, $parent_owner_id);
$value = $default_tz_data->{name};
}
return $value;
}
sub get_parent_info {
my ($c) = @_;
my ($tz_owner_parent_type,$tz_owner_parent_id) = ('', '');
my $schema = $c->model('DB');
if ($c->stash->{subscriber}) {
$tz_owner_parent_type = 'contract';
#billing subscriber
$tz_owner_parent_id = $c->stash->{subscriber}->contract_id;
} elsif ($c->stash->{contract}) {
$tz_owner_parent_type = 'reseller';
$tz_owner_parent_id = $c->stash->{contract}->contact->reseller_id // '';
} elsif ($c->stash->{contact}) {
#edit - we can rely on contact owner info
my $contact_id = $c->stash->{contact}->id;
my %timezones_spec = (
'subscriber' => 'voip_subscriber_timezone',
'contract' => 'contract_timezone');
while (my($type,$result_set) = each %timezones_spec ) {
if (my $owner_tz = $schema->resultset($result_set)->search_rs({contact_id => $contact_id})->first) {
if ($type eq 'subscriber') {
$tz_owner_parent_type = 'contract';
#billing subscriber
$tz_owner_parent_id = $owner_tz->contract->id;
} elsif ($type eq 'contract') {
$tz_owner_parent_type = 'reseller';
#billing subscriber
$tz_owner_parent_id = $owner_tz->contract->contact->reseller_id // '';
}
last;
}
}
} elsif ($c->stash->{close_target}) {
my $close_target = $c->stash->{close_target};
if ($close_target =~m!/(contract|customer)(?:/[^0-9]+)?/([0-9]+)/!) {
if ($close_target =~m!/subscriber/create/!) {
$tz_owner_parent_type = 'contract';
$tz_owner_parent_id = $2;
} else {
$tz_owner_parent_type = 'reseller';
#it may be reseller contract
$tz_owner_parent_id = $schema->resultset('contracts')->search_rs({id => $2})->first->contact->reseller_id;
if (!$tz_owner_parent_id) {
#it is reseller contract
$tz_owner_parent_type = 'top';
}
}
} elsif ($close_target =~m!/(subscriber)(?:/[^0-9]+)?/([0-9]+)/!) {
$tz_owner_parent_type = 'contract';
#billing subscriber
$tz_owner_parent_id = $schema->resultset('voip_subscribers')->search_rs({id => $2})->first->contract_id;
} elsif ($close_target =~m!/reseller/!) {
$tz_owner_parent_type = 'top';
}
} else {
$tz_owner_parent_type = 'noparentinfo';
}
return $tz_owner_parent_type, $tz_owner_parent_id;
}
no Moose;
1;

@ -251,6 +251,24 @@ sub process {
}
}
# show any arbitrary data rows on top, just like a union would do
# hash is expected or array of hashes expected
my $topData = $params->{topData};
if (defined $topData) {
my $topDataArray;
if (ref $topData eq 'HASH') {
$topDataArray = [$topData];
} else {
$topDataArray = $topData;
}
foreach my $topDataRow (@$topDataArray) {
unshift @{ $aaData }, _prune_row($user_tz, $cols, %$topDataRow);
if (defined $row_func) {
$aaData->[0] = {%{$aaData->[0]}, $row_func->($topDataRow)};
}
}
}
if (keys %{ $aggregations }) {
$c->stash(dt_custom_footer => $aggregations);
}

@ -18,8 +18,17 @@ use Time::Warp qw();
my $is_fake_time = 0;
sub is_valid_timezone_name {
my ($tz,$all) = shift;
return 0 unless $tz;
my ($tz, $all, $c, $allow_empty) = @_;
if (!$tz && !$allow_empty) {
return 0;
}
if ($c) {
$tz = NGCP::Panel::Utils::DateTime::strip_empty_timezone_name($c, $tz);
#we allow empty value to switch to the parent default
if (!$tz) {
return $allow_empty ? 1 : 0;
}
}
if ($all) {
return DateTime::TimeZone->is_valid_name($tz);
} else {
@ -28,6 +37,54 @@ sub is_valid_timezone_name {
}
}
sub strip_empty_timezone_name {
my ($c, $value) = @_;
my $default_names = join ('|', map {'^'.$_} ($c->loc('customer default'),$c->loc('reseller default'),$c->loc('default')));
if ($value =~ /$default_names/i) {
return '';
}
return $value;
}
sub get_default_timezone_name {
my($c, $parent_owner_type, $parent_owner_id) = @_;
$parent_owner_type //= '';
my ($default_tz_data, $default_tz_data_rs);
my $parent_tz_rs;
my $noparentinfo = ($parent_owner_type eq 'noparentinfo');
if ($parent_owner_type && !$noparentinfo) {
if ($parent_owner_id) {
if ($parent_owner_type eq 'contract') {
$parent_tz_rs = $c->model('DB')->resultset('contract_timezone')->search_rs({
'contract_id' => $parent_owner_id
},{
'columns' => [ { name => \('concat("'.$c->loc('customer default').' (",name,")")')} ],
});
} elsif ($parent_owner_type eq 'reseller') {
$parent_tz_rs = $c->model('DB')->resultset('reseller_timezone')->search_rs({
'reseller_id' => $parent_owner_id
},{
'columns' => [ { name => \('concat("'.$c->loc('reseller default').' (",name,")")')} ],
});
}
} elsif ($parent_owner_type eq 'top') {
$default_tz_data = { name => $c->loc('default (localtime)') };
} else {
$default_tz_data = { name => $c->loc('default (parent/localtime)') };
}
} elsif ($noparentinfo) {
$default_tz_data = { name => $c->loc('default (parent/localtime)') };
}
if (!$default_tz_data) {
if ($parent_tz_rs) {
$default_tz_data = { $parent_tz_rs->first->get_inflated_columns };
} else {
$default_tz_data = { name => $c->loc('default (parent/localtime)') };
}
}
return $default_tz_data;
}
sub normalize_db_tz_name {
my $tz = shift;
if (defined $tz) {

Loading…
Cancel
Save