# Voip web functions

use Voip;
use Voip_Sessions;
use Nas;
use Log;
use Fees;
use Tariffs;

my $Voip     = Voip->new($db, $admin, \%conf);
my $sessions = Voip_Sessions->new($db, \%conf);
my $fees     = Fees->new($db, $admin, \%conf);
my $tariffs  = Tariffs->new($db, \%conf, $admin);

my $Nas = Nas->new($db, \%conf);
$Log = Log->new($db, \%conf);

my $MODULE = ($module{$index}) ? $module{$index} : 'Voip';
my $debug  = 0;

my @service_status_colors = ("$_COLORS[9]", "$_COLORS[6]", '#808080', '#0000FF', '#FF8000', '#009999');
my @service_status = ("$_ENABLE", "$_DISABLE", "$_ALLOW_ANSWER", "$_DISABLE: $_NON_PAYMENT");

$conf{VOIP_ASTERISK_USERS} = '' if (!$conf{VOIP_ASTERISK_USERS});


=comments
h323-disconnect-cause for CISCO of Radius Server
In case of CISCO router, from the Radius server h323-disconnect-cause with code is returned. Like h323-disconnect-cause=4 or h323-disconnect-cause=7. In the following mini dictionary disconnect cause along description corresponding code is shown which will help instantly to identify disconnect issue if we find any code.

          
           Local-Clear                    0
           Local-No-Accept                1
           Local-Decline                  2
           Remote-Clear                   3
           Remote-Refuse                  4
           Remote-No-Answer               5
           Remote-Caller-Abort            6
           Transport-Error                7
           Transport-Connect-Fail         8
           Gatekeeper-Clear               9
           Fail-No-User                   10
           Fail-No-Bandwidth              11
           No-Common-Capabilities         12
           FACILITY-Forward               13
           Fail-Security-Check            14
           Local-Busy                     15
           Local-Congestion               16
           Remote-Busy                    17
           Remote-Congestion              18
           Remote-Unreachable             19
           Remote-No-Endpoint             20
           Remote-Off-Line                21
           Remote-Temporary-Error         22
=cut

#*******************************************************************
# Delete user from module
# voip_user_del()
#*******************************************************************
sub voip_user_del {
  my ($uid, $attr) = @_;

  $Voip->{UID} = $uid;
  $Voip->user_del({ UID => $uid });

  return 0;
}

#*******************************************************************
# Change user variant form
# form_chg_vid()
#*******************************************************************
sub voip_chg_tp {
  my ($attr) = @_;

  my $user;

  if (defined($attr->{USER_INFO})) {
    $user = $attr->{USER_INFO};
    $user = $Voip->user_info($user->{UID});
    if ($user->{TOTAL} < 1) {
      $html->message('info', $_INFO, $_NOT_ACTIVE);
      return 0;
    }
  }
  else {
    $html->message('err', $_ERROR, "$_USER_NOT_EXIST");
    return 0;
  }

  my $period = $FORM{period} || 0;
  use Shedule;
  $shedule = Shedule->new($db, $admin);

  if ($FORM{set}) {
    if ($period > 0) {

      my ($year, $month, $day);
      if ($period == 1) {
        ($year, $month, $day) = split(/-/, $Voip->{ABON_DATE}, 3);
      }
      else {
        ($year, $month, $day) = split(/-/, $FORM{DATE}, 3);
      }

      $shedule->add(
        {
          UID      => $user->{UID},
          TYPE     => 'tp',
          ACTION   => $FORM{TP_ID},
          D        => $day,
          M        => $month,
          Y        => $year,
          DESCRIBE => "$message<br>
                   $_FROM: '$year-$month-$day'",
          MODULE => 'Voip'
        }
      );

      if ($shedule->{errno}) {
        $html->message('err', $_ERROR, "[$shedule->{errno}] $err_strs{$shedule->{errno}}");
      }
      else {
        $html->message('info', $_CHANGED, "$_CHANGED");
        $user->user_info($user->{UID});
      }
    }
    else {
      $user->user_change({%FORM});

      if ($users->{errno}) {
        $html->message('err', $_ERROR, "[$users->{errno}] $err_strs{$users->{errno}}");
      }
      else {
        $html->message('info', $_CHANGED, "$_CHANGED");
        $user->user_info($user->{UID});
      }

    }
  }
  elsif ($FORM{del}) {
    $shedule->del(
      {
        UID => $user->{UID},
        ID  => $FORM{SHEDULE_ID}
      }
    );

    $html->message('info', $_DELETED, "$_DELETED [$FORM{SHEDULE_ID}]");
  }

  my $tariffs;
  $shedule->info(
    {
      UID    => $user->{UID},
      TYPE   => 'tp',
      MODULE => 'Voip'
    }
  );

  if ($shedule->{TOTAL} > 0) {
    $table = $html->table(
      {
        width      => '100%',
        caption    => "$_SHEDULE",
        cols_align => [ 'left', 'left' ],
        rows       => [ [ "$_TARIF_PLAN:", "$shedule->{ACTION}" ], [ "$_DATE:", "$shedule->{D}-$shedule->{M}-$shedule->{Y}" ], [ "$_ADMIN:", "$shedule->{ADMIN_NAME}" ], [ "$_ADDED:", "$shedule->{DATE}" ], [ "ID:", "$shedule->{SHEDULE_ID}" ] ]
      }
    );
    $tariffs->{TARIF_PLAN_SEL} = $table->show() . $html->form_input('SHEDULE_ID', "$shedule->{SHEDULE_ID}", { TYPE => 'HIDDEN' });
    $tariffs->{ACTION}         = 'del';
    $tariffs->{LNG_ACTION}     = $_DEL;
  }
  else {
    $tariffs->{TARIF_PLAN_SEL} = $html->form_select(
      'TP_ID',
      {
        SELECTED          => $user->{TP_ID},
        SEL_MULTI_ARRAY   => $Voip->tp_list(),
        MULTI_ARRAY_KEY   => 8,
        MULTI_ARRAY_VALUE => '0,1',
        NO_ID             => 1,
        MAIN_MENU         => get_function_index('voip_tp'),
        MAIN_MENU_AGRV    => "TP_ID=$Voip->{TP_ID}"
      }
    );

    $tariffs->{PARAMS}    .= form_period($period);
    $tariffs->{ACTION}     = 'set';
    $tariffs->{LNG_ACTION} = $_CHANGE;
  }

  my $tp_index = get_function_index('voip_tp');

  $tariffs->{UID}     = $attr->{USER_INFO}->{UID};
  $tariffs->{TP_ID}   = $user->{TP_NUM};
  $tariffs->{TP_NAME} = "$user->{TP_NUM}:$user->{TP_NAME} ";

  print $html->tpl_show(templates('form_chg_tp'), $tariffs);
}

#**********************************************************
# user_voip
#**********************************************************
sub voip_users_list {

  if ($FORM{TP_ID}) {
    $LIST_PARAMS{TP_ID} = $FORM{TP_ID};
    $pages_qs .= "&TP_ID=$FORM{TP_ID}";
  }

  $Voip->{STATUS_SEL} = $html->form_select(
    'DISABLE',
    {
      SELECTED => $FORM{DISABLE} || '',
      SEL_HASH => {
        '' => $_ALL,
        0  => $service_status[0],
        1  => $service_status[1],
        2  => $service_status[2],
        3  => $service_status[3],
      },
      NO_ID => 1,
      STYLE => \@service_status_colors,
    }
  );

  $Voip->{GROUP_SEL} = sel_groups();
  $Voip->{TP_SEL}    = $html->form_select(
    'TP_ID',
    {
      SELECTED          => $FORM{TP_ID},
      SEL_MULTI_ARRAY   => [ [ '', '' ], @{ $Voip->tp_list() } ],
      MULTI_ARRAY_KEY   => 8,
      MULTI_ARRAY_VALUE => '0,1',
      NO_ID             => 1,
      MAIN_MENU         => get_function_index('voip_tp'),
    }
  );

  form_search({ SEARCH_FORM => $html->tpl_show(_include('voip_users_search', 'Voip'), { %$Voip, %FORM }, { OUTPUT2RETURN => 1 }) });

  print $html->letters_list({ pages_qs => $pages_qs });

  if ($FORM{letter}) {
    $LIST_PARAMS{FIRST_LETTER} = $FORM{letter};
    $pages_qs .= "&letter=$FORM{letter}";
  }

  my $list = $Voip->user_list({%LIST_PARAMS});
  my @TITLE = ($_LOGIN, $_FIO, $_DEPOSIT, $_CREDIT, $_TARIF_PLANS, $_STATUS, $_NUMBER, '-');
  for (my $i = 0 ; $i < $Voip->{SEARCH_FIELDS_COUNT} ; $i++) {
    push @TITLE, '-';
    $TITLE[ 7 + $i ] = "$_SEARCH";
  }

  if ($Voip->{errno}) {
    $html->message('err', $_ERROR, "[$Voip->{errno}] $err_strs{$Voip->{errno}}");
    return 0;
  }
  elsif ($Voip->{TOTAL} == 1) {
    my $ui = user_info($list->[0]->[7]);
    print $ui->{TABLE_SHOW};

    form_users({ USER_INFO => user_info($list->[0]->[7]) });
    return 0;
  }

  my $table = $html->table(
    {
      width      => '100%',
      caption    => "Voip $_USERS",
      border     => 1,
      title      => \@TITLE,
      cols_align => [ 'left', 'left', 'right', 'right', 'left', 'center', 'left', 'center', 'center', 'center' ],
      qs         => $pages_qs,
      pages      => $Voip->{TOTAL},
      ID         => 'VOIP_USERS_LIST'
    }
  );

  foreach my $line (@$list) {
    my $payments = ($permissions{1}) ? $html->button($_PAYMENTS, "index=2&UID=" . ($line->[ 7 + $Voip->{SEARCH_FIELDS_COUNT} ]), { CLASS => 'payments' }) : '';
    my @fields_array = ();
    for (my $i = 0 ; $i < $Voip->{SEARCH_FIELDS_COUNT} ; $i++) {
      push @fields_array, $line->[ 7 + $i ];
    }

    $table->addrow($html->button($line->[0], "index=15&UID=" . ($line->[ 7 + $Voip->{SEARCH_FIELDS_COUNT} ]) . "&MODULE=Voip"), "$line->[1]", "$line->[2]", "$line->[3]", "$line->[4]", $status[ $line->[5] ], "$line->[6]", @fields_array, $payments);
  }
  print $table->show();

  $table = $html->table(
    {
      width      => '100%',
      cols_align => [ 'right', 'right' ],
      rows       => [ [ "$_TOTAL:", $html->b($Voip->{TOTAL}) ] ]
    }
  );
  print $table->show();

  return 0;
}

#**********************************************************
# user_dv
#**********************************************************
sub voip_user {
  $Voip->{UID} = $FORM{UID};

  voip_provision();

  if ($FORM{add}) {
    if ($FORM{NUMBER} < 1) {
      $html->message('err', $_ERROR, "$ERR_WRONG_DATA $_NUMBER");
    }
    else {
      $Voip->user_add({%FORM});
      if (!$Voip->{errno}) {
        $html->message('info', $_INFO, "$_ADDED");
      }

      if ($conf{VOIP_ASTERISK_USERS}) {
        voip_mk_users_conf();
      }
    }
  }
  elsif ($FORM{set}) {
    $Voip->user_change({%FORM});
    if (!$Voip->{errno}) {
      $html->message('info', $_INFO, "$_CHANGED");
    }

    if ($conf{VOIP_ASTERISK_USERS}) {
      voip_mk_users_conf();
    }
  }
  elsif ($FORM{del} && $FORM{is_js_confirmed}) {
    $Voip->user_del();
    if (!$Voip->{errno}) {
      $html->message('info', $_INFO, "$_DELETED");
    }
  }

  if ($Voip->{errno}) {
    $html->message('err', $_ERROR, "[$Voip->{errno}] $err_strs{$Voip->{errno}}");
  }

  my $user = $Voip->user_info($FORM{UID});

  if ($user->{TOTAL} < 1) {
    $html->message('info', $_INFO, $_NOT_ACTIVE);
    $user               = $Voip->defaults();
    $user->{ACTION}     = 'add';
    $user->{LNG_ACTION} = $_ACTIVATE;
    $user->{TP_NAME}    = $html->form_select(
      'TP_ID',
      {
        SELECTED          => $FORM{TP_ID},
        SEL_MULTI_ARRAY   => $Voip->tp_list(),
        MULTI_ARRAY_KEY   => 8,
        MULTI_ARRAY_VALUE => '0,1',
        NO_ID             => 1,
        MENU              => get_function_index('voip_tp')
      }
    );

  }
  else {
    $user->{CHANGE_TP_BUTTON} = $html->button($_CHANGE, 'UID=' . $user->{UID} . '&index=' . get_function_index('voip_chg_tp'), { CLASS => 'change rightAlignText' });
    $user->{DEL_BUTTON} = "$_CONFIRM:" . $html->form_input('is_js_confirmed', "1", { TYPE => 'checkbox' }) . $html->form_input('del', "$_DEL", { TYPE => 'submit' });
    $user->{ACTION}     = 'set';
    $user->{LNG_ACTION} = $_CHANGE;
  }

  $user->{ALLOW_ANSWER} = ' checked' if ($user->{ALLOW_ANSWER} == 1);
  $user->{ALLOW_CALLS}  = ' checked' if ($user->{ALLOW_CALLS} == 1);

  $user->{STATUS_SEL} = $html->form_select(
    'DISABLE',
    {
      SELECTED => $user->{DISABLE} || 0,
      SEL_HASH => {
        0 => $service_status[0],
        1 => $service_status[1],
        2 => $service_status[2],
        3 => $service_status[3],
      },
      NO_ID => 1,
      STYLE => \@service_status_colors,
    }
  );

  if ($user->{DISABLE} > 0) {
    $user->{STATUS_COLOR} = $service_status_colors[ $user->{DISABLE} ];
  }

  $user->{NAS_SEL} = $html->form_select(
    'PROVISION_NAS_ID',
    {
      SELECTED => $user->{PROVISION_NAS_ID} || $FORM{PROVISION_NAS_ID},
      SEL_MULTI_ARRAY   => $Nas->list({ TYPE => 'ls_pap2t;ls_spa8000' }),
      MULTI_ARRAY_KEY   => 0,
      MULTI_ARRAY_VALUE => 1,
      MAIN_MENU         => get_function_index('form_nas'),
      MAIN_MENU_AGRV    => "chg=$user->{NAS_ID}"
    }
  );

  $user->{PROVISION} = $html->tpl_show(_include('voip_provision_user', 'Voip'), $user, { OUTPUT2RETURN => 1 });

  $html->tpl_show(_include('voip_user', 'Voip'), $user);
}

#**********************************************************
# Time intervals
# form_intervals()
#**********************************************************
sub voip_nas {
  $FORM{subf} = 18;
  voip_tp();
}

#**********************************************************
# Time intervals
# form_intervals()
#**********************************************************
sub voip_tp_routes {
  my ($attr) = @_;

  my $Voip_tp;
  my @caption = ($_PREFIX, $_ROUTES, "$_STATUS", "$_EXTRA_TARIFICATION", 'TRUNK');
  my @aligns = ('left', 'left', 'center');
  my @interval_ids  = ();
  my $intervals     = 0;
  my $exchange_rate = 1;

  $users->config_info({ PARAM => 'VOIP_ER' });
  if ($users->{TOTAL} > 0) {
    $exchange_rate = $users->{VALUE};
  }

  if (defined($attr->{TP})) {
    $Voip_tp = $attr->{TP};

    #Get time intervals
    @DAY_NAMES = ("$_ALL", 'Sun', 'Mon', 'Tue', 'Wen', 'The', 'Fri', 'Sat', "$_HOLIDAYS");
    my $list = $Voip_tp->ti_list({%LIST_PARAMS});
    foreach my $line (@$list) {

      push @caption,      "$_SUM (Min): " . $DAY_NAMES[ $line->[1] ] . "/ $line->[2]-$line->[3]";
      push @aligns,       'center';
      push @interval_ids, $line->[0];
    }
    $intervals = $Voip_tp->{TOTAL};

    if ($FORM{change}) {
      $Voip->rp_add({ %FORM, EXCHANGE_RATE => $exchange_rate });
      if (!$Voip->{errno}) {
        $html->message('info', $_INFO, "$_ADDED");
      }
    }
    elsif ($FORM{import}) {
      my $list = $Voip->routes_list({ %LIST_PARAMS, PAGE_ROWS => 100000 });
      my %prefix_id = ();
      foreach my $line (@$list) {
        $prefix_id{ $line->[0] } = $line->[4];
      }

      my $content  = $FORM{ROUTE_FILE}{Contents};
      my @rows_arr = split(/\n/, $content);
      my %FORM2    = ();

      foreach my $line (@rows_arr) {
        chop($line);
        my ($prefix, $trunk, $et, @prices) = split(/\t/, $line);
        for (my $i = 0 ; $i <= $#prices ; $i++) {
          $FORM2{ 't_' . $prefix_id{$prefix} . '_' . $interval_ids[$i] }  = $trunk;
          $FORM2{ 'et_' . $prefix_id{$prefix} . '_' . $interval_ids[$i] } = $et;
          if ($conf{VOIP_UNIT_TARIFICATION}) {
            $FORM2{ 'up_' . $prefix_id{$prefix} . '_' . $interval_ids[$i] } = $prices[$i];
            $FORM2{ 'p_' . $prefix_id{$prefix} . '_' . $interval_ids[$i] }  = $prices[$i] * $exchange_rate;
          }
          else {
            $FORM2{ 'p_' . $prefix_id{$prefix} . '_' . $interval_ids[$i] } = $prices[$i];
          }
        }
      }

      $Voip->rp_add({ %FORM2, EXCHANGE_RATE => $exchange_rate });
      if (!$Voip->{errno}) {
        $html->message('info', $_INFO, "$_IMPORT $_FILE: $FORM{ROUTE_FILE}{filename}\n $_ROWS: $#rows_arr\n $_CHANGED: $Voip->{TOTAL}");
      }
    }
    elsif ($FORM{export_rp}) {
      print "Content-Type: text/plain\n\n";
      $LIST_PARAMS{PAGE_ROWS} = 100000;
    }
    elsif ($FORM{clear}) {

    }
  }
  else {
    voip_tp({ f => 'voip_tp_routes' });
    return 0;
  }

  if ($Voip->{errno}) {
    $html->message('err', $_ERROR, "[$Voip->{errno}] $err_strs{$Voip->{errno}}");
  }

  $pages_qs = '';

  if (!$FORM{export_rp}) {
    form_search(
      {
        SIMPLE => {
          $_PREFIX   => "ROUTE_PREFIX",
          $_NAME     => "ROUTE_NAME",
          $_DISABLE  => "DISABLE",
          $_DESCRIBE => "DESCRIBE",
          $_GATEWAY  => "GATEWAY_SEL",
          $_SUM      => "PRICE"
        },

        HIDDEN_FIELDS => {
          TP_ID  => $FORM{TP_ID},
          routes => $FORM{routes}
        }
      }
    );
  }

  $list = $Voip->rp_list({%LIST_PARAMS});
  my %prices      = ();
  my %trunks      = ();
  my %et          = ();
  my %unit_prices = ();
  foreach my $line (@$list) {
    $prices{"$line->[0]"}{"$line->[1]"}      = $line->[3];
    $trunks{"$line->[0]"}{"$line->[1]"}      = $line->[4];
    $et{"$line->[0]"}{"$line->[1]"}          = $line->[5];
    $unit_prices{"$line->[0]"}{"$line->[1]"} = $line->[6];
  }

  my ($delete, $change);
  my $price       = 0;
  my $trunk       = 0;
  my $unit_price  = 0;
  my @export_arr  = ();
  my $TRUNKS_MARR = $Voip->trunk_list();

  my $extra_tarification_list = $Voip->extra_tarification_list();

  $pages_qs .= "&routes=$FORM{routes}";
  $list = $Voip->routes_list({%LIST_PARAMS});

  my $table = $html->table(
    {
      width      => '100%',
      caption    => $_ROUTES,
      border     => 1,
      title      => \@caption,
      cols_align => \@aligns,
      qs         => $pages_qs . "&TP_ID=$FORM{TP_ID}",
      pages      => $Voip->{TOTAL},
      ID         => 'VOIP_ROUTES_PRICES',
      header     => $html->button($_EXPORT, "export_rp=1&qindex=$index&TP_ID=$FORM{TP_ID}&routes=$FORM{routes}", { ex_params => 'TARGET=_new', BUTTON => 1 })
    }
  );

  foreach my $line (@$list) {
    my @l = ();
    for (my $i = 0 ; $i < $intervals ; $i++) {

      if (defined($prices{"$interval_ids[$i]"}{"$line->[4]"})) {
        $price      = $prices{ $interval_ids[$i] }{ $line->[4] };
        $unit_price = $unit_prices{ $interval_ids[$i] }{ $line->[4] };
        $trunk      = $trunks{ $interval_ids[$i] }{ $line->[4] } || $trunks{ $interval_ids[0] }{ $line->[4] };
      }
      else {
        $price      = '0.00';
        $unit_price = '0.00';
        $price .= " $interval_ids[$i] $line->[4] -0" if ($debug > 0);
      }

      if ($FORM{export_rp}) {
        push @l, $price;
      }
      else {
        push @l,
        (($conf{VOIP_UNIT_TARIFICATION}) ? $html->form_input("p_$line->[4]" . '_' . "$interval_ids[$i]", "$unit_price", { SIZE => 10 }) . $html->br() . $price : $html->form_input("p_$line->[4]" . '_' . "$interval_ids[$i]", "$price", { SIZE => 10 }))
        . (($i > 0) ? $html->form_input("t_$line->[4]" . '_' . "$interval_ids[$i]", "$trunk", { TYPE => 'hidden' }) : '');
      }
    }

    if ($FORM{export_rp}) {
      push @export_arr, [ $line->[0], $line->[1], $status[ $line->[2] ], $line->[3], @l ];
    }
    else {
      my $trunk_sel = $html->form_select(
        "t_$line->[4]" . '_' . "$interval_ids[$i]",
        {
          SELECTED          => $trunks{"$interval_ids[$i]"}{"$line->[4]"},
          SEL_MULTI_ARRAY   => [ [ 0, '-' ], @{$TRUNKS_MARR} ],
          MULTI_ARRAY_KEY   => 0,
          MULTI_ARRAY_VALUE => 1,
          NO_ID             => 1
        }
      );

      my $ext_tp_sel = $html->form_select(
        "et_$line->[4]" . '_' . "$interval_ids[$i]",
        {
          SELECTED => $et{"$interval_ids[$i]"}{"$line->[4]"} || 0,
          SEL_MULTI_ARRAY => [ [ 0, '-' ], @{$extra_tarification_list} ],
          MULTI_ARRAY_KEY => 0,
          MULTI_ARRAY_VALUE => 1,
          NO_ID             => 1
        }
      );

      $table->addrow("$line->[0]", "$line->[1]", $status[ $line->[2] ], $ext_tp_sel, $trunk_sel, @l);
    }
  }

  if ($FORM{export_rp}) {
    foreach my $rows (@export_arr) {
      foreach my $row (@$rows) {
        print "$row\t";
      }
      print "\n";
    }

    return 0;
  }

  my $table2 = $html->table(
    {
      width      => '100%',
      cols_align => [ 'right', 'right' ],
      rows       => [ [ $html->form_input('change', $_CHANGE, { TYPE => 'submit' }), "$_FILE: " . $html->form_input('ROUTE_FILE', "ROUTE_FILE", { TYPE => 'FILE' }) . $html->form_input('import', $_IMPORT, { TYPE => 'submit' }) ] ]
    }
  );

  print $html->form_main(
    {
      CONTENT => $table->show() . $table2->show(),
      ENCTYPE => 'multipart/form-data',
      NAME    => 'TP_ROUTES',
      ID      => 'TP_ROUTES',
      HIDDEN  => {
        TP_ID  => "$FORM{TP_ID}",
        index  => "$index",
        routes => "$FORM{routes}"
      },
    }
  );

  $table = $html->table(
    {
      width      => '100%',
      cols_align => [ 'right', 'right' ],
      rows       => [ [ "$_TOTAL:", $html->b($Voip->{TOTAL}) ] ]
    }
  );
  print $table->show();

}

#**********************************************************
# Time intervals
# form_intervals()
#**********************************************************
sub voip_intervals {
  my ($attr) = @_;

  @DAY_NAMES = ("$_ALL", 'Sun', 'Mon', 'Tue', 'Wen', 'The', 'Fri', 'Sat', "$_HOLIDAYS");
  my %visual_view = ();
  my $tarif_plan;

  if (defined($attr->{TP})) {
    $tarif_plan               = $attr->{TP};
    $tarif_plan->{ACTION}     = 'add';
    $tarif_plan->{LNG_ACTION} = $_ADD;

    if ($FORM{routes}) {
      voip_tp_routes({ TP => $attr->{TP} });
    }
    elsif ($FORM{add}) {
      $tarif_plan->ti_add({%FORM});
      if (!$tarif_plan->{errno}) {
        $html->message('info', $_INFO, "$_INTERVALS $_ADDED");
      }
    }
    elsif ($FORM{change}) {
      $tarif_plan->ti_change($FORM{TI_ID}, {%FORM});

      if (!$tarif_plan->{errno}) {
        $html->message('info', $_INFO, "$_INTERVALS $_CHANGED [$tarif_plan->{TI_ID}]");
      }
    }
    elsif (defined($FORM{chg})) {
      $tarif_plan->ti_info($FORM{chg});
      if (!$tarif_plan->{errno}) {
        $html->message('info', $_INFO, "$_INTERVALS $_CHANGE [$FORM{chg}]");
      }

      $tarif_plan->{ACTION}     = 'change';
      $tarif_plan->{LNG_ACTION} = $_CHANGE;
    }
    elsif ($FORM{del} && $FORM{is_js_confirmed}) {
      $tarif_plan->ti_del($FORM{del});
      if (!$tarif_plan->{errno}) {
        $html->message('info', $_DELETED, "$_DELETED $FORM{del}");
      }
    }
    else {
      $tarif_plan->ti_defaults();
    }

    my $list  = $tarif_plan->ti_list({%LIST_PARAMS});
    my $table = $html->table(
      {
        width      => '100%',
        caption    => $_INTERVALS,
        border     => 1,
        title      => [ '#', $_DAYS, $_BEGIN, $_END, $_HOUR_TARIF, '-', '-', '-', '-' ],
        cols_align => [ 'left', 'left', 'right', 'right', 'right', 'right', 'center', 'center', 'center', 'center' ],
        qs         => $pages_qs,
        ID         => 'VOIP_INTERVALS',
      }
    );

    my $color = "AAA000";
    foreach my $line (@$list) {

      my $delete = $html->button($_DEL, "index=$index$pages_qs&del=$line->[0]", { MESSAGE => "$_DEL [$line->[0]] ?", CLASS => 'del' });
      $color = sprintf("%06x", hex('0x' . $color) + 7000);

      #day, $hour|$end = color
      my ($h_b, $m_b, $s_b) = split(/:/, $line->[2], 3);
      my ($h_e, $m_e, $s_e) = split(/:/, $line->[3], 3);

      push(@{ $visual_view{ $line->[1] } }, "$h_b|$h_e|$color|$line->[0]");

      if (($FORM{tt} eq $line->[0]) || ($FORM{chg} eq $line->[0])) {
        $table->{rowcolor} = $_COLORS[0];
      }
      else {
        undef($table->{rowcolor});
      }

      $table->addtd(
        $table->td($line->[0], { rowspan => ($line->[5] > 0) ? 2 : 1 }),
        $table->td($html->b($DAY_NAMES[ $line->[1] ])),
        $table->td($line->[2]),
        $table->td($line->[3]),
        $table->td($line->[4]),
        $table->td($html->button("$_ROUTES", "index=$index$pages_qs&routes=$line->[0]", { CLASS => 'routes' })),
        $table->td($html->button("$_CHANGE", "index=$index$pages_qs&chg=$line->[0]",    { CLASS => 'change' })),
        $table->td($delete), $table->td("&nbsp;", { bgcolor => '#' . $color, rowspan => ($line->[5] > 0) ? 2 : 1 })
      );

    }
    print $table->show();

  }
  elsif (defined($FORM{TP_ID})) {
    $FORM{subf} = $index;
    voip_tp();
    return 0;
  }

  if ($tarif_plan->{errno}) {
    $html->message('err', $_ERROR, "[$tarif_plan->{errno}] $err_strs{$tarif_plan->{errno}} $tarif_plan->{errstr}");
  }

  $table = $html->table(
    {
      width       => '100%',
      title_plain => [ $_DAYS, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23 ],
      caption     => "$_INTERVALS",
      rowcolor    => $_COLORS[1]
    }
  );

  for (my $i = 0 ; $i < 9 ; $i++) {
    my @hours = ();

    my ($h_b, $h_e, $color, $p);
    my $link = "&nbsp;";
    for (my $h = 0 ; $h < 24 ; $h++) {

      if (defined($visual_view{$i})) {
        $day_periods = $visual_view{$i};

        foreach my $line (@$day_periods) {

          #print "$i -- $line    <br>\n";
          ($h_b, $h_e, $color, $p) = split(/\|/, $line, 4);
          if (($h >= $h_b) && ($h < $h_e)) {

            #     	   	 print "$i // $h => $h_b && $h <= $h_e // $color <br> \n";
            $tdcolor = '#' . $color;
            $link = $html->button('#', "index=$index&TP_ID=$FORM{TP_ID}&subf=$FORM{subf}&chg=$p");
            last;
          }
          else {
            $link    = "&nbsp;";
            $tdcolor = $_COLORS[1];
          }
        }
      }
      else {
        $link    = "&nbsp;";
        $tdcolor = $_COLORS[1];
      }

      push(@hours, $table->td("$link", { align => 'center', bgcolor => $tdcolor }));
    }

    $table->addtd($table->td($DAY_NAMES[$i]), @hours);
  }

  print $table->show();

  $tarif_plan->{SEL_DAYS} = $html->form_select(
    'TI_DAY',
    {
      SELECTED     => $day_id,
      SEL_ARRAY    => \@DAY_NAMES,
      ARRAY_NUM_ID => 1
    }
  );

  $html->tpl_show(templates('form_ti'), $tarif_plan);
}

#**********************************************************
# Tarif plans
# form_tp
#**********************************************************
sub voip_tp {
  my ($attr) = @_;
  my @Payment_Types = ($_PREPAID, $_POSTPAID);

  $Voip_tp               = $Voip->tp_defaults();
  $Voip_tp->{LNG_ACTION} = $_ADD;
  $Voip_tp->{ACTION}     = 'ADD_TP';

  if ($FORM{ADD_TP}) {
    $Voip->tp_add({%FORM});
    if (!$Voip->{errno}) {
      $html->message('info', $_ADDED, "$_ADDED $Voip->{TP_ID}");
    }
  }
  elsif ($FORM{TP_ID}) {
    $Voip_tp = $Voip->tp_info($FORM{TP_ID});

    if ($Voip_tp->{errno}) {
      $html->message('err', $_ERROR, "[$Voip_tp->{errno}] $err_strs{$Voip->{errno}}");
      return 0;
    }

    if ($FORM{qindex}) {
      voip_tp_routes({ TP => $Voip_tp });
      return 0;
    }

    $pages_qs .= "&TP_ID=$FORM{TP_ID}&subf=$FORM{subf}";
    $LIST_PARAMS{TP} = $FORM{TP_ID};
    %F_ARGS = (TP => $Voip_tp);

    $Voip_tp->{NAME_SEL} = $html->form_main(
      {
        CONTENT => $html->form_select(
          'TP_ID',
          {
            SELECTED          => $FORM{TP_ID},
            SEL_MULTI_ARRAY   => $Voip->tp_list({%LIST_PARAMS}),
            MULTI_ARRAY_KEY   => 8,
            MULTI_ARRAY_VALUE => '0,1',
            NO_ID             => 1
          }
        ),
        HIDDEN => { index => "$index" },
        SUBMIT => { show  => "$_SHOW" }
      }
    );

    func_menu(
      {
        'ID'   => $Voip_tp->{ID},
        $_NAME => $Voip_tp->{NAME_SEL}
      },
      {
        $_INFO => ":TP_ID=$Voip_tp->{TP_ID}",

        #     $_USERS         => "11:TP_ID=$Voip_tp->{TP_ID}",
        #     $_INTERVALS     => "73:TP_ID=$Voip_tp->{TP_ID}",
        #     $_NAS           => "18:TP_ID=$Voip_tp->{TP_ID}"
      },
      { f_args => {%F_ARGS} }
    );

    if ($FORM{subf}) {
      return 0;
    }
    elsif ($FORM{change}) {
      $Voip->tp_change($FORM{TP_ID}, {%FORM});
      if (!$Voip->{errno}) {
        $html->message('info', $_CHANGED, "$_CHANGED $Voip->{TP_ID}");
      }
    }

    $Voip_tp->{LNG_ACTION} = $_CHANGE;
    $Voip_tp->{ACTION}     = 'change';

  }
  elsif ($FORM{del} && $FORM{is_js_confirmed}) {
    $Voip->tp_del($FORM{del});

    if (!$Voip->{errno}) {
      $html->message('info', $_DELETE, "$_DELETED $FORM{del}");
    }
  }

  if ($Voip->{errno}) {
    $html->message('err', $_ERROR, "[$Voip->{errno}] $err_strs{$Voip->{errno}}");
  }

  $Voip_tp->{PAYMENT_TYPE_SEL} = $html->form_select(
    'PAYMENT_TYPE',
    {
      SELECTED     => $Voip_tp->{PAYMENT_TYPE},
      SEL_ARRAY    => \@Payment_Types,
      ARRAY_NUM_ID => 1
    }
  );

  $html->tpl_show(_include('voip_tp', 'Voip'), $Voip_tp);

  my $list = $Voip->tp_list({ %LIST_PARAMS, COLS_NAME => 1 });

  # Time tariff Name Begin END Day fee Month fee Simultaneously - - -
  my $table = $html->table(
    {
      width      => '100%',
      caption    => "$_TARIF_PLANS",
      title      => [ '#', $_NAME, $_HOUR_TARIF, $_PAYMENT_TYPE, $_DAY_FEE, $_MONTH_FEE, $_SIMULTANEOUSLY, $_AGE, '-', '-', '-' ],
      cols_align => [ 'right', 'left', 'center', 'center', 'right', 'right', 'right', 'right', 'right', 'right', 'center', 'center', 'center' ],
      ID         => 'VOIP_TP'
    }
  );

  my ($delete, $change);
  foreach my $line (@$list) {
    if ($permissions{4}{1}) {
      $delete = $html->button($_DEL, "index=$index&del=$line->{tp_id}", { MESSAGE => "$_DEL ?", CLASS => 'del' });
      $change = $html->button($_INFO, "index=$index&TP_ID=$line->{tp_id}", { CLASS => 'change' });
    }

    if ($FORM{TP_ID} eq $line->{tp_id}) {
      $table->{rowcolor} = $_COLORS[0];
    }
    else {
      undef($table->{rowcolor});
    }

    $table->addrow(
      $html->b($line->{id}),
      $html->button("$line->{name}", "index=$index&TP_ID=$line->{tp_id}"),
      $bool_vals[ $line->{time_tarifs} ],
      $Payment_Types[ $line->{payment_type} ],
      $line->{day_fee}, 
      $line->{month_fee}, 
      $line->{logins}, 
      $line->{age}, 
      $html->button($_INTERVALS, "index=" . get_function_index('voip_intervals') . "&subf=73&TP_ID=$line->{tp_id}", { CLASS => 'interval' }),
      $change, $delete
    );
  }
  print $table->show();

  $table = $html->table(
    {
      width      => '100%',
      cols_align => [ 'right', 'right' ],
      rows       => [ [ "$_TOTAL:", $html->b($Voip->{TOTAL}) ] ]
    }
  );
  print $table->show();

}

#**********************************************************
#
# voip_trunks
#**********************************************************
sub voip_trunks {
  $Voip->{ACTION}     = 'add';
  $Voip->{LNG_ACTION} = $_ADD;

  if ($FORM{add}) {
    $Voip->trunk_add({%FORM});
    if (!$Voip->{errno}) {
      $html->message('info', $_ADDED, "$_ADDED $Voip->{TRUNK_ID}");
    }
  }
  elsif ($FORM{change}) {
    $Voip->trunk_change({%FORM});
    if (!$Voip->{errno}) {
      $html->message('info', $_INFO, "$_CHANGED");
    }
  }
  elsif ($FORM{chg}) {
    $Voip->trunk_info($FORM{chg});
    if (!$Voip->{errno}) {
      $html->message('info', $_INFO, "$_CHANGING");
    }

    $Voip->{ACTION}     = 'change';
    $Voip->{LNG_ACTION} = $_CHANGE;
  }
  elsif ($FORM{del} && $FORM{is_js_confirmed}) {
    $Voip->trunk_del($FORM{del});
    if (!$Voip->{errno}) {
      $html->message('info', $_DELETE, "$_DELETED $FORM{del}");
    }
  }

  if ($Voip->{errno}) {
    $html->message('err', $_ERROR, "[$Voip->{errno}] $err_strs{$Voip->{errno}}");
    return 0;
  }

  $Voip->{DISABLE} = ' checked' if ($Voip->{DISABLE} == 1);
  $Voip->{FAILOVER_TRUNK_SEL} = $html->form_select(
    'FAILOVER_TRUNK',
    {
      SELECTED          => $Voip->{FAILOVER_TRUNK},
      SEL_MULTI_ARRAY   => [ [ 0, '-' ], @{ $Voip->trunk_list() } ],
      MULTI_ARRAY_KEY   => 0,
      MULTI_ARRAY_VALUE => 1,
      NO_ID             => 1
    }
  );

  $Voip->{PROTOCOL_SEL} = $html->form_select(
    'PROTOCOL',
    {
      SELECTED  => $Voip->{PROTOCOL},
      SEL_ARRAY => [ 'SIP', 'IAX2', 'ZAP', 'H323' ],
    }
  );

  $html->tpl_show(_include('voip_trunk', 'Voip'), $Voip);

##
  my %new_hash     = ();
  my %phone_prefix = ();

  my $list = $Voip->trunk_list({%LIST_PARAMS});

  my $table = $html->table(
    {
      width      => '100%',
      caption    => "Trunks",
      border     => 1,
      title      => [ 'ID', $_NAME, $_PROTOCOL, "VOIP $_PROVIDER", "$_FAILOVER_TRUNK", '-', '-' ],
      cols_align => [ 'left', 'left', 'left', 'left', 'left', 'center', 'center' ],
      qs         => $pages_qs,
      pages      => $Voip->{TOTAL},
      ID         => 'VOIP_TRUNKS',
    }
  );

  my ($delete, $change);
  foreach my $line (@$list) {
    if ($permissions{4}{1}) {
      $delete = $html->button($_DEL, "index=$index&del=$line->[0]", { MESSAGE => "$_DEL $line->[0]?", CLASS => 'del' });
      $change = $html->button($_CHANGE, "index=$index&chg=$line->[0]", { CLASS => 'change' });
    }

    $table->addrow($line->[0], $line->[1], $line->[2], $line->[3], $line->[4], $change, $delete);

  }
  print $table->show();

  $table = $html->table(
    {
      width      => '100%',
      cols_align => [ 'right', 'right' ],
      rows       => [ [ "$_TOTAL:", $html->b($Voip->{TOTAL}) ] ]
    }
  );

  print $table->show();

}

#**********************************************************
# Tarif plans
# voip_routes
#**********************************************************
sub voip_routes {

  $Voip->{ACTION}     = 'add';
  $Voip->{LNG_ACTION} = $_ADD;
  $Voip->{PARENT_ID}  = 0;

  if ($FORM{add}) {
    $Voip->route_add({%FORM});
    if (!$Voip->{errno}) {
      $html->message('info', $_ADDED, "$_ADDED $Voip->{ROUTE_ID}");
    }
  }
  elsif ($FORM{import}) {
    my $content = $FORM{ROUTE_FILE}{Contents};
    my @rows_arr = split(/\n/, $content);

    my $count = 0;

    foreach my $line (@rows_arr) {
      chop($line);
      my ($prefix, $name, $status) = split(/\t/, $line);
      $Voip->route_add(
        {
          ROUTE_PREFIX => $prefix,
          ROUTE_NAME   => $name,
          DISABLE      => $status,
          REPLACE      => 1
        }
      );
      $count++;
    }

    if (!$Voip->{errno}) {
      $html->message('info', $_INFO, "$_IMPORT $_FILE: $FORM{ROUTE_FILE}{filename} ADDED: $count");
    }
  }
  elsif ($FORM{export}) {
    print "Content-Type: text/plain\n\n";
    my $list = $Voip->routes_list({ PAGE_ROWS => 100000 });
    printf("%-12s| %-40s| %-8s| %-10s|\n" . "---------------------------------------------------------------------\n", $_PREFIX, $_NAME, $_STATUS, $_CHANGED);

    foreach my $line (@$list) {
      printf("%-12s| %-40s| %-8s| %-10s|\n", $line->[0], $line->[1], $status[ $line->[2] ], $line->[3]);
    }
    return 0;
  }
  elsif ($FORM{change}) {
    $Voip->route_change({%FORM});
    if (!$Voip->{errno}) {
      $html->message('info', $_INFO, "$_CHANGED");
    }
  }
  elsif ($FORM{change}) {
    $Voip->route_del($FORM{del});
    if (!$Voip->{errno}) {
      $html->message('info', $_INFO, "$_DELETED");
    }
  }

  if ($FORM{add_route}) {
    my $list = $Voip->routes_list({ PAGE_ROWS => 100000 });

    my %route_items = ();
    foreach my $line (@$list) {
      $route_items{ $line->[0] }{ $line->[5] } = $line->[1];
    }

    my $root_index = $FORM{add_route};
    my $h          = $route_items{$root_index};
    $Voip->{PARENT_ID} = $root_index;

    while (my ($par_key, $name) = each(%$h)) {
      $menu_navigator = $html->button("$name", "index=$index&ROUTE_ID=$root_index") . $menu_navigator;
      $tree{$root_index} = 1;
      if ($par_key > 0) {
        $root_index = $par_key;
        $h          = $route_items{$par_key};
      }
    }

    $Voip->{PARENT} = $menu_navigator;

  }
  elsif ($FORM{ROUTE_ID}) {
    $Voip->route_info($FORM{ROUTE_ID}, {%FORM});
    if (!$Voip->{errno}) {
      $html->message('info', $_INFO, "$_CHANGING");
    }

    $Voip->{ACTION}     = 'change';
    $Voip->{LNG_ACTION} = $_CHANGE;
  }
  elsif (defined($FORM{del}) && $FORM{is_js_confirmed}) {
    $Voip->route_del($FORM{del});
    if (!$Voip->{errno}) {
      $html->message('info', $_DELETE, "$_DELETED $FORM{del}");
    }
  }

  if ($Voip->{errno}) {
    if ($Voip->{errno} == 7) {
      $html->message('err', $_ERROR, "$_PREFIX $_EXIST");
    }
    else {
      $html->message('err', $_ERROR, "[$Voip->{errno}] $err_strs{$Voip->{errno}}");
      return 0;
    }
  }

  $Voip->{DISABLE} = ' checked' if ($Voip->{DISABLE} == 1);
  $html->tpl_show(_include('voip_route', 'Voip'), $Voip);

  my %SEARCH_FIELDS = (
    $_PREFIX   => "ROUTE_PREFIX",
    $_NAME     => "ROUTE_NAME",
    $_DISABLE  => "DISABLE",
    $_DESCRIBE => "DESCRIBE"
  );

  $output .= form_search({ SIMPLE => \%SEARCH_FIELDS, });

##
  my %new_hash     = ();
  my %phone_prefix = ();

  my $list = $Voip->routes_list({%LIST_PARAMS, COLS_NAME => 1 });

  my $table = $html->table(
    {
      width      => '100%',
      caption    => "$_ROUTES",
      border     => 1,
      title      => [ $_PREFIX, $_NAME, $_STATUS, $_DATE, '-', '-' ],
      cols_align => [ 'left', 'left', 'center', 'right', 'center', 'center' ],
      qs         => $pages_qs,
      pages      => $Voip->{TOTAL},
      ID         => 'VOIP_ROUTES',
      header     => $html->button($_EXPORT, "qindex=$index&export=1", { BUTTON => 1 })
    }
  );

  my ($delete, $change);
  foreach my $line (@$list) {
    if ($permissions{4}{1}) {
      $delete = $html->button($_DEL, "index=$index&del=$line->{id}", { MESSAGE => "$_DEL '$line->{prefix}' ?", CLASS => 'del' });
      $change = $html->button($_CHANGE, "index=$index&ROUTE_ID=$line->{id}", { CLASS => 'change' });
    }

    $table->addrow($line->{prefix}, 
      $line->{name}, 
      $status[ $line->{disable} ], 
      $line->{date}, 
      $change, 
      $delete);

  }

  my $table2 = $html->table(
    {
      width      => '100%',
      cols_align => [ 'right', 'right' ],
      rows       => [ [ "$_IMPORT $_FILE: " . $html->form_input('ROUTE_FILE', "ROUTE_FILE", { TYPE => 'FILE' }) . $html->form_input('import', $_IMPORT, { TYPE => 'submit' }) ] ]
    }
  );

  print $html->form_main(
    {
      CONTENT => $table->show() . $table2->show(),
      ENCTYPE => 'multipart/form-data',
      NAME    => 'TP_ROUTES',
      ID      => 'TP_ROUTES',
      HIDDEN  => { index => "$index", },
    }
  );

  $table = $html->table(
    {
      width      => '100%',
      cols_align => [ 'right', 'right' ],
      rows       => [ [ "$_TOTAL:", $html->b($Voip->{TOTAL}) ] ]
    }
  );

  print $table->show();

  #--------------------------------------------------------------------
  # Tree View

  #
  #foreach my $line (@$list) {
  #  $new_hash{$line->[5]}{$line->[0]}="$line->[2]";
  #  $route_info{$line->[0]}="$line->[1]:$line->[3]";
  #}
  #
  #my $h = $new_hash{0};
  #my @last_array = ();
  #
  #my @menu_sorted = sort {
  #   $h->{$b} <=> $h->{$a}
  #     ||
  #   length($a) <=> length($b)
  #     ||
  #   $a cmp $b
  #} keys %$h;
  #
  #foreach my $parent (@menu_sorted) {
  #
  #  if ($permissions{4}{1}) {
  #    $delete = $html->button($_DEL, "index=$index&del=$parent", "$_DEL ?");
  #    $change = "<a href='$SELF_URL?index=$index&ROUTE_ID=$parent'>$_CHANGE</a>";
  #    $add    = "<a href='$SELF_URL?index=$index&add_route=$parent&ROUTE_ID=$parent'>$_ADD</a>";
  #   }
  #
  #
  #
  #  my $val = $h->{$parent};
  #  my $level = 0;
  #  my $prefix = '';
  #  my ($phone_prefix, $enable) = split(/:/, $route_info{$parent}, 2);
  #
  #  $table->addrow("$phone_prefix",  "$val",
  #     $status[$enable],
  #     $add,
  #     $change,
  #     $delete
  #    );
  #
  #  if (defined($new_hash{$parent})) {
  #    $level++;
  #    $prefix .= "&nbsp;&nbsp;&nbsp;";
  #    label:
  #      my $mi = $new_hash{$parent};
  #
  #      while(my($k, $val)=each %$mi) {
  #
  #        if ($permissions{4}{1}) {
  #          $delete = $html->button($_DEL, "index=$index&del=$k", "$_DEL ?");
  #          $change = "<a href='$SELF_URL?index=$index&ROUTE_ID=$k'>$_CHANGE</a>";
  #          $add    = "<a href='$SELF_URL?index=$index&add_route=$k'>$_ADD</a>";
  #        }
  #
  #        my ($phone_prefix, $enable) = split(/:/, $route_info{$k}, 2);
  #        $table->addrow("$prefix $phone_prefix", "$prefix $val",
  #            $status[$enable],
  #            $add,
  #            $change,
  #            $delete );
  #
  #        if (defined($new_hash{$k})) {
  #      	   $mi = $new_hash{$k};
  #      	   $level++;
  #           $prefix .= "&nbsp;&nbsp;&nbsp;";
  #           push @last_array, $parent;
  #           $parent = $k;
  #         }
  #        delete($new_hash{$parent}{$k});
  #      }
  #
  #    if ($#last_array > -1) {
  #      $parent = pop @last_array;
##      print "POP/$#last_array/$parent/<br>\n";
  #      $level--;
  #

  #

  #

  #
  #         }
  #        delete($new_hash{$parent}{$k});
  #      }
  #
  #    if ($#last_array > -1) {
  #      $parent = pop @last_array;
##      print "POP/$#last_array/$parent/<br>\n";
  #      $level--;
  #

}

#*******************************************************************
# online users
#*******************************************************************
sub voip_online {

  my $message;

  if ($FORM{ping}) {
    if ($FORM{ping} =~ /^(\d){1,3}\.(\d){1,3}\.(\d){1,3}\.(\d){1,3}$/) {
      my $res = `$PING -c 5 $FORM{ping}`;
      $html->message('info', $_INFO, "Ping  $FORM{ping}<br>Result:<br><pre>$res</pre>");
    }
    else {
      $html->message('err', $_ERROR, "$ERR_WRONG_DATA");
    }
  }
  elsif ($FORM{hangup}) {
    my ($nas_id, $acct_session_id, $user_name) = split(/ /, $FORM{hangup}, 4);
    $Nas->info({ NAS_ID => $nas_id, SECRETKEY => $conf{secretkey} });

    if ($Nas->{errno}) {
      $html->message('err', $_NAS, "$Nas->{errstr}");
      return 0;
    }

    $nas_port_id = 0;
    require "Abills/nas.pl";
    my $ret = hangup($nas, "$nas_port_id", "", "$acct_session_id");

    if ($ret == 0) {
      $message = "$_NAS ID: $nas_id 
                 $_NAS IP: $Nas->{NAS_IP}
                 $_PORT: $nas_port_id
                 $_SESSION_ID: $acct_session_id
                 $ret ";
      sleep 3;
    }
    elsif ($ret == 1) {
      $message = 'NAS NOT supported yet';
    }

    $html->message('info', $_INFO, "$message");
  }
  elsif ($FORM{zapall}) {
    $sessions->zap(0, 0, 0, { ALL => 1, %FORM });
    $html->message('info', $_INFO, "Zapped all sessions");
  }
  elsif ($FORM{zap}) {
    my ($nas_id, $acct_session_id) = split(/[ +]+/, $FORM{zap}, 3);
    $sessions->zap($nas_id, $acct_session_id);

    if ($sessions->{errno}) {
      $html->message('err', $_ERROR, "[$sessions->{errno}] $err_strs{$sessions->{errno}}");
      return 0;
    }

    $Nas->info({ NAS_ID => $nas_id, SECRETKEY => $conf{secretkey} });
    $message = "$_NAS: $Nas->{NAS_IP} / $Nas->{NAS_INDENTIFIER}\n" . "$_PORT: $nas_port_id\n" . "SESSION_ID: $acct_session_id\n";

    $sessions->list(
      {
        ACCT_SESSION_ID => $acct_session_id,
        NAS_ID          => $Nas->{NAS_ID}
      }
    );

    if ($sessions->{TOTAL} < 1) {
      $message .= $html->button('add to log', "index=$index&tolog=$acct_session_id&nas_id=$nas_id", { BUTTON => 1 }) . ' ' . $html->button("$_DEL", "index=$index&del=$acct_session_id&nas_id=$nas_id&nas_port_id=$nas_port_id", { BUTTON => 1 });
    }
    else {
      $message = "$_EXIST";
      $sessions->{delete} = 1;
      $sessions->online_del(
        {
          NAS_ID          => $nas_id,
          ACCT_SESSION_ID => $acct_session_id
        }
      );

    }

    $html->message('info', $_CLOSED, $message);
  }
  elsif ($FORM{tolog}) {
    my $ACCT_INFO = $sessions->online_info(
      {
        NAS_ID          => $FORM{nas_id},
        ACCT_SESSION_ID => $FORM{tolog}
      }
    );

    if ($ACCT_INFO->{TOTAL} < 1) {
      $html->message('err', $_ERROR, "$_NOT_EXIST $_SESSION_ID [$FORM{tolog}]");
      return 0;
    }

    require Voip_aaa;
    $ACCT_INFO->{ACCT_STATUS_TYPE} = 'Stop';

    $Nas->info(
      {
        NAS_ID    => $ACCT_INFO->{NAS_ID},
        SECRETKEY => $conf{secretkey}
      }
    );

    Voip_aaa->import();
    my $Acct = Voip_aaa->new($db, \%conf);
    my $r = $Acct->accounting($ACCT_INFO, $Nas, \%conf);

    if ($Acct->{errno}) {
      $html->message('err', $_ERROR, "[$Acct->{errno}] $Acct->{errstr}");
    }
    else {
      my $table = $html->table({ width => '100%' });
      while (my ($k, $v) = each %$ACCT_INFO) {
        $table->addrow("$k", $v);
      }

      #while(my($k, $v)=each %$Acct) {
      #    $table->addrow($k, $v);
      #  }
      $html->message('info', $_ADDED, $table->show());
    }

    $sessions->online_del(
      {
        NAS_ID          => $ACCT_INFO->{NAS_ID},
        ACCT_SESSION_ID => $ACCT_INFO->{ACCT_SESSION_ID}
      }
    );
  }
  elsif ($FORM{del} || $FORM{dellist}) {
    if ($FORM{dellist}) {
      my @sessions_list = split(/, /, $FORM{dellist});
      $sessions->online_del({ SESSIONS_LIST => \@sessions_list });
      $FORM{del} = $FORM{dellist};
    }
    else {
      $sessions->online_del(
        {
          NAS_ID          => $FORM{nas_id},
          ACCT_SESSION_ID => $FORM{del}
        }
      );
    }

    if (!$sessions->{errno}) {
      $html->message('info', $_DELETED, "NAS_ID: $FORM{nas_id}\nACCT_SESSION_ID: $FORM{del}");
    }

  }

  $form_link = '';
  my $cure = '';

  if ($FORM{ZAPED}) {
    $LIST_PARAMS{ZAPED} = 1;
    $form_link = $html->button('On line', "index=$index", { BUTTON => 1, IMG => ':button_activate.png' });
    $cure = 'Zap';
  }
  else {
    $sessions->online({ ZAPED => 1 });
    $form_link = $html->button($_ZAPED, "index=$index&ZAPED=1", { BUTTON => 1, IMG => ':button_del.png' }) . " ($sessions->{TOTAL})";
    $cure = 'Online';
  }

  $sessions->online({%LIST_PARAMS});
  my $dub_ports  = $sessions->{dub_ports};
  my $dub_logins = $sessions->{dub_logins};

  my $table = $html->table(
    {
      caption    => "$cure",
      width      => '100%',
      title      => [ "$_USER", "$_FIO", "CALLED_STATION_ID", "CALLING_STATION_ID", "$_DURATION", "$_TYPE", "CLIENT_IP_ADDRESS", "-", "-", "-" ],
      cols_align => [ 'left', 'left', 'right', 'right', 'right', 'right', 'right', 'right', 'right', 'center' ],
      qs         => $pages_qs,
    }
  );

  my $online     = $sessions->{nas_sorted};
  my $nas_list   = $Nas->list();
  my @call_types = ("$_ANSWER", "$_ORIGIN");
  foreach my $nas_row (@$nas_list) {
    next if (!defined($online->{ $nas_row->[0] }));

    $table->{rowcolor} = $_COLORS[0];
    $table->{extra}    = "colspan='9' class='small'";
    $table->addrow("$nas_row->[0]:" . $html->button($html->b($nas_row->[1]), "index=" . get_function_index('form_nas') . "&NAS_ID=$nas_row->[0]") . ":$nas_row->[4]");

    my $l = $online->{ $nas_row->[0] };
    foreach my $line (@$l) {
      undef($table->{rowcolor});
      undef($table->{extra});
      if (defined($dub_logins->{ $line->[0] })) { $bg = '#FFFF00'; }

      #    elsif (defined($dub_ports->{$nas_row->[4]}{$line->[2]})) { $bg='#00FF40';    }
      elsif ($line->[9] == 3) { $bg = '#FF0000'; }

      my $zap = $html->button('Z', "index=$index&zap=$nas_row->[0]+$line->[10]", { TITLE => 'Zap', CLASS => 'del' });
      my $hangup = ($FORM{ZAPED}) ? $html->form_input('dellist', "$line->[10]", { TYPE => 'checkbox' }) : $html->button('H', "index=$index&hangup=$nas_row->[0]+$line->[2]+$line->[9]+$line->[0]", { TITLE => 'Hangup', CLASS => 'off' });

      my $user_info = '';

      $call_type = ($line->[5] == 0) ? $html->color_mark($call_types[ $line->[5] ], "$_COLORS[7]") : $call_types[ $line->[5] ];
      $table->addrow($html->button($line->[0], "index=11&UID=$line->[9]", { TITLE => "$user_info" }), $line->[1], $line->[2], $line->[3], $line->[4], $call_type, $line->[6], $html->button('P', "index=$index&ping=$line->[6]", { TITLE => 'Ping', BUTTON => 1 }), "$zap", "$hangup");
    }
  }

  my $table2 = $html->table(
    {
      width      => '100%',
      cols_align => [ 'right', 'right', 'right' ],
      rows       => [ [ "$_TOTAL:", $html->b($sessions->{TOTAL}), "$form_link" ] ]
    }
  );

  my $total  = $table2->show();
  my $output = $total . $table->show();

  $table = $html->table(
    {
      width       => '100%',
      title_plain => [ "$_REFRESH (sec): " . $html->form_input('REFRESH', int(($FORM{REFRESH}) ? $FORM{REFRESH} : 0), { SIZE => 4 }), $html->form_input('SHOW', $_SHOW, { TYPE => 'SUBMIT' }) ],
      cols_align => [ 'center:noprint', 'center:noprint' ],
    }
  );

  if ($FORM{ZAPED}) {
    $output = $html->form_main(
      {
        CONTENT => $output,
        HIDDEN  => {
          index => "$index",
          ZAPED => 1
        },
        SUBMIT => { go => "$_DEL" },
        METHOD => 'GET'
      }
    );
  }
  else {
    $output .= $html->form_main(
      {
        CONTENT => $table->show(),
        HIDDEN  => { index => "$index" },
        METHOD  => 'GET'
      }
    );

    $output .= $html->button('Zap All', "index=$index&zapall=1", { IMG => ':tech_work.png', MESSAGE => "Do you realy want ZAP all sessions ?" });
  }

  print $output;

}

#**********************************************************
# Whow sessions from log
# voip_sessions()
#**********************************************************
sub voip_sessions {
  my ($list) = @_;

  #Session List

  if (!$list) {
    if (!defined($FORM{sort})) {
      $LIST_PARAMS{SORT} = 2;
      $LIST_PARAMS{DESC} = 'DESC';
    }
    $list = $sessions->list({%LIST_PARAMS});
  }

  if ($FORM{del} && $FORM{is_js_confirmed}) {
    if (!defined($permissions{3}{1})) {
      $html->message('err', $_ERROR, 'ACCESS DENY');
      return 0;
    }

    my ($UID, $session_id, $nas_id, $session_start_date, $session_start_time, $sum, $login) = split(/ /, $FORM{del}, 7);

    $sessions->del($UID, $session_id, $nas_id, "$session_start_date $session_start_time");
    if (!$sessions->{errno}) {
      $html->message('info', $_DELETED, "$_LOGIN: $login<br> SESSION_ID: $session_id<br> NAS_ID: $nas_id<br> SESSION_START: $session_start_date $session_start_time<br> $_SUM: $sum");
      form_back_money('log', $sum, { UID => $UID });    #
      return 0;
    }
  }

  if ($sessions->{errno}) {
    $html->message('err', $_ERROR, "[$sessions->{errno}] $err_strs{$sessions->{errno}}");
  }

  return 0 if ($sessions->{TOTAL} < 1);
  my $table = $html->table(
    {
      width        => '100%',
      caption      => $_SESSIONS,
      border       => 1,
      title        => [ "$_USER", "$_START", "$_DURATION", "$_TARIF_PLAN", "CALLING_STATION_ID", "CALLED_STATION_ID", "NAS", "IP", "$_SUM", "-", "-" ],
      cols_align   => [ 'left', 'right', 'right', 'RIGHT', 'right', 'right', 'right', 'right', 'right', 'right', 'center' ],
      qs           => $pages_qs,
      pages        => $sessions->{TOTAL},
      recs_on_page => $LIST_PARAMS{PAGE_ROWS},
      ID           => 'VOIP_SESSIONS'
    }
  );

  my $delete = '';

  use Billing;
  my $Billing = Billing->new($db, \%conf);

  foreach my $line (@$list) {
    if ($permissions{3}{1}) {

      #$UID, $session_id, $nas_id, $session_start_date, $session_start_time, $sum, $login
      $delete = $html->button($_DEL, "index=$index$pages_qs&del=$line->[11]+$line->[9]+$line->[6]+$line->[1]+$line->[8]+$line->[0]", { MESSAGE => "$_DEL Session SESSION_ID $line->[9]?", CLASS => 'del', NO_LINK_FORMER => 1 });
    }

    $table->addrow(
      $html->button($line->[0], "index=11&UID=$line->[11]"),
      $line->[1], $line->[2], $line->[3], $line->[4], $line->[5], $line->[6], $line->[7],
      "$line->[8] $test",
      $html->button('D', "index=$index&UID=$line->[11]&SESSION_ID=$line->[9]", { TITLE => 'Session Detail', CLASS => 'stats' }), $delete
    );
  }

  print $table->show();
}

#**********************************************************
# voip_use_all_monthes();
#**********************************************************
sub voip_use_allmonthes {

  $FORM{allmonthes} = 'y';
  voip_use();
}

#**********************************************************
# dv_use();
#**********************************************************
sub voip_use {
  reports(
    {
      DATE      => $FORM{DATE},
      REPORT    => '',
      EX_PARAMS => {
        DATE   => "$_DATE",
        USERS  => "$_USERS",
        ADMINS => "$_ADMINS",

      },
      PERIOD_FORM => 1,
    }
  );
  my ($tables_sessions, $table_fees);

  #Day reposrt
  if (defined($FORM{DATE})) {

    #Used Fraffic
    $table_sessions = $html->table(
      {
        width      => '100%',
        caption    => "$_SESSIONS",
        title      => [ "$_DATE", "$_USERS", "$_SESSIONS", $_DURATION, $_SUM ],
        cols_align => [ 'right', 'left', 'right', 'right', 'right' ],
        qs         => $pages_qs
      }
    );

    my $list = $sessions->reports({%LIST_PARAMS});
    foreach my $line (@$list) {
      $table_sessions->addrow($html->b($line->[0]), $html->button("$line->[1]", "index=11&subf=22&UID=$line->[5]&DATE=$line->[0]"), $line->[2], $line->[3], $html->b($line->[4]));
    }

  }
  else {

    #Used Traffic
    $table_sessions = $html->table(
      {
        width      => '100%',
        caption    => "$_SESSIONS",
        title      => [ "$_DATE", "$_USERS", "$_SESSIONS", $_DURATION, $_SUM ],
        cols_align => [ 'right', 'right', 'right', 'right', 'right' ],
        qs         => $pages_qs
      }
    );

    my $list = $sessions->reports({%LIST_PARAMS});
    foreach my $line (@$list) {
      $table_sessions->addrow($html->button($line->[0], "index=$index&$type=$line->[0]$pages_qs"), $line->[1], $line->[2], $line->[3], $html->b($line->[4]));
    }

  }

  $table = $html->table(
    {
      width      => '100%',
      caption    => $_SESSIONS,
      cols_align => [ 'right', 'right', 'right', 'right', 'right', 'right' ],
      rows => [ [ "$_USERS: " . $html->b($sessions->{USERS}), "$_SESSIONS: " . $html->b($sessions->{SESSIONS}), "$_DURATION: " . $html->b($sessions->{DURATION}), "$_SUM: " . $html->b($sessions->{SUM}) ] ],
      rowcolor => $_COLORS[2]
    }
  );

  print $table_sessions->show() . $table->show();

}

#**********************************************************
# dv_error
#**********************************************************
sub voip_error {
  my ($attr)    = @_;
  my $PAGE_ROWS = 25;
  my $login     = '';

  my %log_levels_rev = reverse %log_levels;
  my @ACTIONS = ('', 'AUTH', 'ACCT', 'HANGUP', 'CALCULATION', 'CMD');

  if ($attr->{USER_INFO}) {
    my $user = $attr->{USER_INFO};
    $Voip->user_info($attr->{USER_INFO}->{UID});

    $login = $Voip->{NUMBER};
    $LIST_PARAMS{LOGIN_EXPR} = $Voip->{NUMBER};
  }
  elsif ($FORM{LOGIN_EXPR}) {
    $login = $FORM{LOGIN_EXPR};
    $LIST_PARAMS{LOGIN_EXPR} = $FORM{LOGIN_EXPR};
    $pages_qs .= "&LOGIN_EXPR=$FORM{LOGIN_EXPR}";
  }
  elsif ($FORM{UID}) {
    voip_user();
    return 0;
  }

  #Sql Part
  if ($conf{ERROR2DB}) {
    my %nas_ids = (
      '' => '',
      0  => 'UNKNOWN',
    );

    my $list = $Nas->list({ TYPE => 'asterisk,gnugk,cisco_voip' });
    foreach my $line (@$list) {
      $nas_ids{ $line->[0] } = $line->[1];
    }

    $Voip->{LOG_TYPE_SEL} = $html->form_select(
      'LOG_TYPE',
      {
        SELECTED => $FORM{LOG_TYPE},
        SEL_HASH => { '' => '', %log_levels_rev },
        NO_ID    => 1
      }
    );

    $Voip->{NAS_ID_SEL} = $html->form_select(
      'NAS_ID',
      {
        SELECTED => $FORM{NAS_ID},
        SEL_HASH => \%nas_ids,
        NO_ID    => 1
      }
    );

    $Voip->{ACTIONS_SEL} = $html->form_select(
      'ACTION',
      {
        SELECTED  => $FORM{ACTION},
        SEL_ARRAY => \@ACTIONS,
      }
    );

    form_search({ SEARCH_FORM => $html->tpl_show(_include('voip_errors_search', 'Voip'), { %FORM, %$Voip }, { OUTPUT2RETURN => 1 }) });

    if (!$FORM{sort}) {
      $LIST_PARAMS{SORT} = 1;
      $LIST_PARAMS{DESC} = DESC;
    }

    if ($FORM{search}) {
      $LIST_PARAMS{INTERVAL} = "$FORM{FROM_DATE}/$FORM{TO_DATE}";
    }

    $LIST_PARAMS{NAS_ID} = join(';', keys %nas_ids);

    $list = $Log->log_list({%LIST_PARAMS});
    my $table = $html->table(
      {
        caption    => $_TOTAL,
        width      => '100%',
        cols_align => [ 'right', 'right' ],
      }
    );

    my $total = 0;
    foreach my $line (@{ $Log->{list} }) {
      $table->addrow($log_levels_rev{ $line->[0] }, $line->[1]);
      $total += $line->[1];
    }

    $table->addrow($_TOTAL, $total);

    print $table->show();

    $table = $html->table(
      {
        caption => "$_ERROR",
        width   => '100%',
        title   => [ $_DATE, "$_TYPE", "$_ACTION", "$_USER", "$_TEXT", "NAS" ],
        pages   => $total,
        qs      => $pages_qs,
        ID      => 'DV_ERRORS'
      }
    );

    foreach my $line (@$list) {
      $table->addrow($line->[0], $log_levels_rev{ $line->[1] }, $line->[2], $html->button($line->[3], "index=11&LOGIN=$line->[3]"), ($line->[1] < 5) ? $html->color_mark($line->[4], "#FF0000") : $line->[4], $nas_ids{ $line->[5] });
    }

    print $table->show();
  }

  return 0 if (in_array('Dv', \@MODULES));

  #File part
  if (!-f $conf{LOGFILE}) {
    $html->message('info', $_INFO, "'$conf{LOGFILE}' $_NOT_EXIST");
    return 0;
  }

  if (defined($FORM{LOG_TYPE})) {
    $pages_qs .= "&LOG_TYPE=$FORM{LOG_TYPE}";
  }

  my ($list, $types, $totals) = show_log(
    "$login",
    "$conf{LOGFILE}",
    {
      DATE      => $FORM{DATE},
      LOG_TYPE  => $log_levels_rev{ $FORM{LOG_TYPE} },
      PG        => $PG,
      PAGE_ROWS => 25                                    #$PAGE_ROWS
    }
  );

  my $table = $html->table(
    {
      caption => "System $_ERROR",
      width   => '100%',
      pages   => $totals,
      qs      => $pages_qs,
      ID      => 'DV_ERRORS'
    }
  );

  foreach my $line (@$list) {
    if ($line =~ m/LOG_WARNING/i) {
      $line = $html->color_mark($line, '#FF0000');
    }

    $table->addrow($line);
  }
  print $table->show();

  $table = $html->table(
    {
      width      => '100%',
      cols_align => [ 'right', 'right' ]
    }
  );

  $table->addrow($html->button("$_TOTAL", "index=$index&$pages_qs"), $totals);
  while (my ($k, $v) = each %$types) {
    $table->addrow($html->button($k, "index=$index&LOG_TYPE=$k$pages_qs"), $v);
  }

  $table->addrow($_SIZE, int2byte((-s $conf{LOGFILE}))) if ($login eq '');

  print $table->show();
}

#**********************************************************
# stats
#**********************************************************
sub voip_stats {
  my ($attr) = @_;

  if (defined($attr->{USER_INFO})) {
    my $user = $attr->{USER_INFO};

    $UID = $user->{UID};
    $LIST_PARAMS{UID} = $UID;
    if (!defined($FORM{sort})) {
      $LIST_PARAMS{SORT} = 2;
      $LIST_PARAMS{DESC} = DESC;
    }

    if (defined($FORM{OP_SID}) and $FORM{OP_SID} eq $COOKIES{OP_SID}) {
      $html->message('err', $_ERROR, "$_EXIST $FORM{OP_SID} eq $COOKIES{OP_SID}");
    }
    elsif ($FORM{bm}) {
      use Bills;
      my $Bill = Bills->new($db);
      $Bill->action('add', "$FORM{BILL_ID}", $FORM{sum});
      if ($bill->{errno}) {
        $html->message('err', $_ERROR, "[$bill->{errno}] $err_strs{$bill->{errno}}");
      }
      else {
        $html->message('info', $_INFO, "$_ADDED: SUM $FORM{sum}, BILL_ID: $FORM{BILL_ID}");
      }
    }
    elsif ($FORM{SESSION_ID}) {
      $pages_qs .= "&SESSION_ID=$FORM{SESSION_ID}";
      voip_session_detail({ USER_INFO => $attr->{USER_INFO} });

      return 0;
    }

  }

  #elsif($FORM{UID}) {
  #	form_users();
  #	return 0;
  #}

  if ($sessions->{errno}) {
    $html->message('err', $_ERROR, "[$sessions->{errno}] $err_strs{$sessions->{errno}}");
  }

  if ($FORM{rows}) {
    $LIST_PARAMS{PAGE_ROWS} = $FORM{rows};
    $conf{list_max_recs}    = $FORM{rows};
    $pages_qs .= "&rows=$conf{list_max_recs}";
  }

  #PEriods totals
  my $list = $sessions->periods_totals({%LIST_PARAMS});

  if (!defined($sessions->{sum_4})) {
    $html->message('info', $_INFO, "$_NO_RECORD");
    return 0;
  }

  my $table = $html->table(
    {
      width       => '100%',
      title_plain => [ "$_PERIOD", "$_DURATION", "$_SUM" ],
      cols_align  => [ 'left', 'right', 'right' ],
      rowcolor    => $_COLORS[1]
    }
  );

  for (my $i = 0 ; $i < 5 ; $i++) {
    $table->addrow($html->button("$PERIODS[$i]", "index=$index&period=$i$pages_qs"), "$sessions->{'duration_'. $i}", $sessions->{ 'sum_' . $i });
  }
  print $table->show();

  $table = $html->table(
    {
      width       => '100%',
      rowcolor    => $_COLORS[0],
      title_plain => [ "$_FROM: ", $html->date_fld('from', { MONTHES => \@MONTHES }), "$_TO: ", $html->date_fld('to', { MONTHES => \@MONTHES }), "$_ROWS: ", $html->form_input('rows', int($conf{list_max_recs}), { SIZE => 4 }), $html->form_input('show', $_SHOW, { TYPE => 'submit' }) ],
    }
  );

  print $html->form_main(
    {
      CONTENT => $table->show({ OUTPUT2RETURN => 1 }),
      HIDDEN  => {
        sid   => "$sid",
        index => "$index",
        UID   => "$UID"
      }
    }
  );

  voip_stats_calculation($sessions);

  if (defined($FORM{show})) {
    $pages_qs .= "&show=y&fromD=$FORM{fromD}&fromm=$FORM{fromM}&fromy=$FORM{fromY}&tod=$FORM{toD}&tom=$FORM{toM}&toy=$FORM{toY}";
    $FORM{fromM}++;
    $FORM{toM}++;
    $FORM{fromM} = sprintf("%.2d", $FORM{fromM}++);
    $FORM{toM}   = sprintf("%.2d", $FORM{toM}++);
    $LIST_PARAMS{INTERVAL} = "$FORM{fromY}-$FORM{fromM}-$FORM{fromD}/$FORM{toY}-$FORM{toM}-$FORM{toD}";
  }
  elsif (defined($FORM{period})) {
    $LIST_PARAMS{PERIOD} = int($FORM{period});
    $pages_qs .= "&period=$FORM{period}";
  }
  elsif ($FORM{DATE}) {
    $LIST_PARAMS{DATE} = $FORM{DATE};
    $pages_qs .= "&DATE=$FORM{DATE}";
  }

  if (!defined($FORM{sort})) {
    $LIST_PARAMS{SORT} = 2;
    $LIST_PARAMS{DESC} = DESC;
  }

  #Session List
  $list  = $sessions->list({%LIST_PARAMS});
  $table = $html->table(
    {
      width       => '640',
      rowcolor    => $_COLORS[1],
      caption     => $_TOTAL,
      title_plain => [ "$_SESSIONS", "$_DURATION", "$_SUM" ],
      cols_align  => [ 'right', 'right', 'right' ],
      rows        => [ [ $sessions->{TOTAL}, $sessions->{DURATION}, $sessions->{SUM} ] ],
    }
  );
  print $table->show();
  voip_sessions($list, $sessions) if ($sessions->{TOTAL} > 0);
}

#*******************************************************************
# Session Detail
# voip_session_detail();
#*******************************************************************
sub voip_session_detail {
  my ($attr) = @_;
  my $user;

  if (defined($attr->{USER_INFO})) {
    $user = $attr->{USER_INFO};
    $LIST_PARAMS{LOGIN} = $user->{LOGIN};

    #	if ($FORM{RECALC}) {
    #		$sessions->session_detail({ %FORM });
    #
    #    use Billing;
    #    my $Billing = Billing->new($db, $CONF);
    #
    #    my($UID,
    #     $SUM,
    #     $BILL_ID,
    #     $TARIF_PLAN,
    #     $TIME_TARIF,
    #     $TRAF_TARIF) = $Billing->session_sum($sessions->{LOGIN},
    #                                          $sessions->{START_UNIXTIME},
    #                                          $sessions->{DURATION},
    #                                            {  OUTBYTE  =>  $sessions->{SENT},
    #                                               INBYTE   =>  $sessions->{RECV},
    #                                               OUTBYTE2 =>  $sessions->{SENT2},
    #                                               INBYTE2  =>  $sessions->{RECV2}
    #                                             },
    #                                          {
    #                                          	disable_rt_billing => 1,
    #                                          	TP_NUM             => $sessions->{TP_ID}
    #                                           }
    #                                          );
    #
    #    my $change = '';
    #
    #    if ($sessions->{SUM} != $SUM) {
    #      $change = "$_CHANGE  ". $html->button($_YES, "index=$index&RECALC=1&SESSION_ID=$FORM{SESSION_ID}&UID=$FORM{UID}&change=1", { BUTTON => 1 }). ' ?';
    #
    #      if ($FORM{change}) {
    #        use Bills;
    #        my $Bill = Bills->new($db);
    #        $Bill->action('add', "$sessions->{BILL_ID}", $sessions->{SUM}) if ($sessions->{SUM});
    #        $Bill->action('take', "$sessions->{BILL_ID}", $SUM) if ($SUM > 0);
    #
    #        $sessions->query($db, "UPDATE dv_log SET sum='$SUM' WHERE acct_session_id='$sessions->{SESSION_ID}';", 'do');
    #
    #        if($bill->{errno}) {
    #          $html->message('err', $_ERROR, "[$bill->{errno}] $err_strs{$bill->{errno}}");
    #         }
    #        else {
    #          $html->message('info', $_INFO, "$_ADDED: SUM $FORM{sum}, BILL_ID: $FORM{BILL_ID}");
    #         }
    #      	$change = "$_CHANGED";
    #       }
    #     }
    #
    #		$html->message('info', "$_RECALCULATE", "$_TARIF_PLAN: $TARIF_PLAN, $_SUM: $sessions->{SUM} -> $SUM  $change");
    #	 }

  }
  elsif (defined($LIST_PARAMS{LOGIN})) {

  }
  elsif ($FORM{UID}) {
    voip_user();
    return 0;
  }

  my %ACCT_TERMINATE_CAUSES = (
    'Unknown'                      => 0,
    'User-Request'                 => 1,
    'Lost-Carrier'                 => 2,
    'Lost-Service'                 => 3,
    'Idle-Timeout'                 => 4,
    'Session-Timeout'              => 5,
    'Admin-Reset'                  => 6,
    'Admin-Reboot'                 => 7,
    'Port-Error'                   => 8,
    'NAS-Error'                    => 9,
    'NAS-Request'                  => 10,
    'NAS-Reboot'                   => 11,
    'Port-Unneeded'                => 12,
    'Port-Preempted'               => 13,
    'Port-Suspended'               => 14,
    'Service-Unavailable'          => 15,
    'Callback'                     => 16,
    'User-Error'                   => 17,
    'Host-Request'                 => 18,
    'Supplicant-Restart'           => 19,
    'Reauthentication-Failure'     => 20,
    'Port-Reinit'                  => 21,
    'Port-Disabled'                => 22,
    'Lost-Alive/Billd Calculation' => 23
  );

  my %ACCT_TERMINATE_CAUSES_VALUE = reverse %ACCT_TERMINATE_CAUSES;

  $sessions->session_detail({%FORM});
  $sessions->{ACCT_TERMINATE_CAUSE} = "$sessions->{ACCT_TERMINATE_CAUSE} : " . $ACCT_TERMINATE_CAUSES_VALUE{ $sessions->{ACCT_TERMINATE_CAUSE} };
  $sessions->{RECALC} = $html->button($_RECALCULATE, "index=$index&RECALC=1&SESSION_ID=$FORM{SESSION_ID}&UID=$FORM{UID}", { BUTTON => 1 });

  $sessions->{ROUTE_ID} = $html->button($sessions->{ROUTE_ID}, "&ROUTE_ID=$sessions->{ROUTE_ID}&index=" . get_function_index('voip_routes'));

  $html->tpl_show(_include('voip_session_detail', 'Voip'), { %$sessions, });

}

#*******************************************************************
# WHERE period
# base_state($where, $period);
#*******************************************************************
sub voip_stats_calculation {
  my ($sessions) = @_;

  $sessions->calculation({%LIST_PARAMS});

  my $table = $html->table(
    {
      width       => '640',
      rowcolor    => $_COLORS[1],
      title_plain => [ "-", "$_MIN", "$_MAX", "$_AVG" ],
      cols_align  => [ 'left', 'right', 'right', 'right' ],
      rows        => [ [ $_DURATION, $sessions->{min_dur}, $sessions->{max_dur}, $sessions->{avg_dur} ], [ $_SUM, $sessions->{min_sum}, $sessions->{max_sum}, $sessions->{avg_sum} ] ]
    }
  );
  print $table->show();
}

#**********************************************************
# form_stats
#**********************************************************
sub voip_user_stats {

  #my ($user) = @_;
  #$UID = $user->{UID};
  #$LIST_PARAMS{UID} = $user->{UID};

  if (!defined($FORM{sort})) {
    $LIST_PARAMS{SORT} = 2;
    $LIST_PARAMS{DESC} = DESC;
  }

  if ($sessions->{errno}) {
    $html->message('err', $_ERROR, "[$sessions->{errno}] $err_strs{$sessions->{errno}}");
  }

  if ($FORM{rows}) {

    $LIST_PARAMS{PAGE_ROWS} = $FORM{rows};
    $conf{list_max_recs}    = $FORM{rows};
    $pages_qs .= "&rows=$conf{list_max_recs}";
  }

  #PEriods totals
  my $list  = $sessions->periods_totals({%LIST_PARAMS});
  my $table = $html->table(
    {
      width       => '100%',
      caption     => $_PERIOD,
      title_plain => [ "$_PERIOD", "$_DURATION", "$_SUM" ],
      cols_align  => [ 'left', 'right', 'right' ],
      rowcolor    => $_COLORS[1],
      ID          => 'PERIODS'
    }
  );

  if (!defined($sessions->{sum_4})) {
    $html->message('info', $_INFO, $_NO_RECORD);
    return 0;
  }

  for (my $i = 0 ; $i < 5 ; $i++) {
    $table->addrow($html->button("$PERIODS[$i]", "index=$index&period=$i$pages_qs"), "$sessions->{'duration_'. $i}", $sessions->{ 'sum_' . $i });
  }
  print $table->show();

  $table = $html->table(
    {
      width    => '100%',
      rowcolor => $_COLORS[0],
      rows     => [
        [
          "$_FROM: ", $html->date_fld('from', { MONTHES => \@MONTHES }),
          "$_TO: ", $html->date_fld('to', { MONTHES => \@MONTHES }),
          "$_ROWS: ",
          $html->form_input('rows', int($conf{list_max_recs}), { SIZE => 4,        OUTPUT2RETURN => 1 }),
          $html->form_input('show', $_SHOW,                    { TYPE => 'submit', OUTPUT2RETURN => 1 })
        ]
      ],
    }
  );

  print $html->form_main(
    {
      CONTENT => $table->show({ OUTPUT2RETURN => 1 }),
      HIDDEN  => {
        sid   => "$sid",
        index => "$index",
        UID   => "$UID"
      }
    }
  );

  voip_stats_calculation($sessions);

  if (defined($FORM{show})) {
    $pages_qs .= "&show=y&fromD=$FORM{fromD}&fromm=$FORM{fromM}&fromy=$FORM{fromY}&tod=$FORM{toD}&tom=$FORM{toM}&toy=$FORM{toY}";
    $FORM{fromM}++;
    $FORM{toM}++;
    $FORM{fromM} = sprintf("%.2d", $FORM{fromM}++);
    $FORM{toM}   = sprintf("%.2d", $FORM{toM}++);
    $LIST_PARAMS{INTERVAL} = "$FORM{fromY}-$FORM{fromM}-$FORM{fromD}/$FORM{toY}-$FORM{toM}-$FORM{toD}";
  }
  elsif (defined($FORM{period})) {
    $LIST_PARAMS{PERIOD} = int($FORM{period});
    $pages_qs .= "&period=$FORM{period}";
  }

  #Session List
  $list = $sessions->list({%LIST_PARAMS});

  $table = $html->table(
    {
      width       => '640',
      caption     => $_TOTAL,
      rowcolor    => $_COLORS[1],
      title_plain => [ "$_SESSIONS", "$_DURATION", "$_SUM" ],
      cols_align  => [ 'right', 'right', 'right' ],
      rows        => [ [ $sessions->{TOTAL}, $sessions->{DURATION}, $sessions->{SUM} ] ],
      ID          => 'VOIP_TOTALS'
    }
  );
  print $table->show();

  voip_sessions($list, $sessions) if ($sessions->{TOTAL} > 0);
}

#**********************************************************
# voip_user_routes
#**********************************************************
sub voip_user_info {
  my $user = $Voip->user_info($LIST_PARAMS{UID});

  if ($user->{TOTAL} < 1) {
    $html->message('info', $_INFO, "$_NOT_ACTIVE");
    return 0;
  }

  $html->tpl_show(_include('voip_user_info', 'Voip'), $Voip);
}

#**********************************************************
# voip_user_routes
#**********************************************************
sub voip_user_routes {

  my $user = $Voip->user_info($LIST_PARAMS{UID});

  require Tariffs;
  Tariffs->import();
  my $Voip_tp = Tariffs->new($db, \%conf);
  $WEEKDAYS[0] = $_ALL;
  my $list = $Voip_tp->ti_list({ TP_ID => $user->{TP_ID} });
  my @caption = ($_PREFIX, $_ROUTES, "$_STATUS");
  my @aligns       = ('left', 'left', 'center');
  my @interval_ids = ();
  my $intervals    = 0;
  foreach my $line (@$list) {

    #push @caption, "$_SUM (Min): ". $WEEKDAYS[$line->[1]] .$html->br().  sec2time($line->[2], {str => 1}). '-' . sec2time($line->[3], {str => 1});
    push @caption, $html->b($WEEKDAYS[ $line->[1] ]) . $html->br() . sec2time($line->[2], { format => 1 }) . '-' . sec2time($line->[3], { format => 1 });
    push @aligns, 'center';
    push @interval_ids, $line->[0];
  }
  $intervals = $Voip_tp->{TOTAL};

  $list = $Voip->rp_list({%LIST_PARAMS});
  my %prices = ();
  foreach my $line (@$list) {

    #print "-- $line->[0] / $line->[1] / $line->[2] / $line->[3] <br>\n";
    $prices{"$line->[0]"}{"$line->[1]"} = $line->[3];
  }

  $pages_qs .= "&routes=$FORM{routes}";
  $list = $Voip->routes_list({%LIST_PARAMS});

  my $table = $html->table(
    {
      width      => '100%',
      caption    => $_ROUTES,
      border     => 1,
      title      => \@caption,
      cols_align => \@aligns,
      qs         => $pages_qs,
      pages      => $Voip->{TOTAL},
      ID         => 'VOIP_ROUTES_PRICES',
    }
  );

  my ($delete, $change);
  my $price = 0;
  foreach my $line (@$list) {
    my @l = ();
    for (my $i = 0 ; $i < $intervals ; $i++) {
      if (defined($prices{"$interval_ids[$i]"}{"$line->[4]"})) {
        $price = $prices{ $interval_ids[$i] }{ $line->[4] };
      }
      else {
        $price = "0.00";
        $price .= " $interval_ids[$i] $line->[4] -0" if ($debug > 0);
      }
      push @l, $price;
    }
    $table->addrow("$line->[0]", "$line->[1]", $status[ $line->[2] ], @l);
  }

  print $table->show();

}

#**********************************************************
# daily_fees
#**********************************************************
sub voip_daily_fees {
  my ($attr) = @_;

  my $debug = $attr->{DEBUG} || 0;
  my $debug_output = '';
  $debug_output .= "Voip: Daily periodic\n" if ($debug > 1);

  $LIST_PARAMS{TP_ID} = $attr->{TP_ID} if ($attr->{TP_ID});
  my %VOIP_LIST_PARAMS = ();
  $VOIP_LIST_PARAMS{LOGIN} = $attr->{LOGIN} if ($attr->{LOGIN});
  $VOIP_LIST_PARAMS{EXT_BILL} = 1 if ($conf{BONUS_EXT_FUNCTIONS});

  $ADMIN_REPORT{DATE} = $DATE if (!$ADMIN_REPORT{DATE});
  my ($y, $m, $d) = split(/-/, $ADMIN_REPORT{DATE}, 3);

  my $tp_list = $tariffs->list(
    {
      %LIST_PARAMS,
      MODULE    => 'Voip',
      COLS_NAME => 1
    }
  );

  foreach my $tp (@$tp_list) {
    my %TP_INFO   = ();
    my $TP_ID     = $tp->{id};
    my $postpaid  = $tp->{payment_type};
    my $daily_fee = $tp->{day_fee};

    $TP_INFO{POSTPAID_MONTHLY} = $tp->{postpaid_monthly_fee};
    $TP_INFO{REDUCTION}        = $tp->{reduction_fee};
    $TP_INFO{TP_NUM}           = $tp->{tp_id};

    $debug_output .= "TP ID: $tp->{id} DF: $daily_fee POSTPAID: $postpaid\n" if ($debug > 1);
    if ($daily_fee > 0) {
      my $ulist = $Voip->user_list(
        {
          ACTIVATE     => "<=$DATE",
          EXPIRE       => "0000-00-00,>$DATE",
          STATUS       => '0',
          LOGIN_STATUS => 0,
          TP_ID        => $TP_INFO{TP_NUM},
          COLS_NAME    => 1
        }
      );

      foreach my $u (@$ulist) {
        my %user = (
          LOGIN     => $u->{id},
          UID       => $u->{uid},
          BILL_ID   => $u->{bill_id},
          ACTIVATE  => $u->{activate},
          REDUCTION => $u->{reduction},
          DEPOSIT   => $u->{deposit},
          CREDIT    => $u->{credit},
          STATUS    => $u->{voip_status},
        );

        $debug_output .= " Login: $user{LOGIN} ($user{UID}) REDUCTION: $user{REDUCTION} DEPOSIT: $u->{deposit} CREDIT $user{CREDIT} ACTIVE: $user{ACTIVATE}\n" if ($debug > 3);

        if ($postpaid || $user{DEPOSIT} + $user{CREDIT} > 0) {
          my %FEES_PARAMS = (
            DESCRIBE => "Voip: $_DAY_FEE ($TP_ID)",
            DATE     => "$ADMIN_REPORT{DATE} $TIME",
            METHOD   => 1
          );

          $fees->take(\%user, $daily_fee, \%FEES_PARAMS);
        }
      }
    }
  }

  $DEBUG .= $debug_output;
  return $debug_output;
}

#**********************************************************
# monthly_fees
#**********************************************************
sub voip_monthly_fees {
  my ($attr) = @_;

  my $debug = $attr->{DEBUG} || 0;
  my $debug_output = '';
  $debug_output .= "Voip: Monthly periodic payments\n" if ($debug > 1);

  use Users;
  my $users = Users->new($db, $admin, \%conf);

  $LIST_PARAMS{TP_ID} = $attr->{TP_ID} if ($attr->{TP_ID});
  my %VOIP_LIST_PARAMS = ();
  $VOIP_LIST_PARAMS{LOGIN} = $attr->{LOGIN} if ($attr->{LOGIN});
  $VOIP_LIST_PARAMS{EXT_BILL} = 1 if ($conf{BONUS_EXT_FUNCTIONS});

  $ADMIN_REPORT{DATE} = $DATE if (!$ADMIN_REPORT{DATE});
  my ($y, $m, $d) = split(/-/, $ADMIN_REPORT{DATE}, 3);

  my $list = $tariffs->list({ %LIST_PARAMS, MODULE => 'Voip' });
  my $date_unixtime = mktime(0, 0, 0, $d, ($m - 1), $y - 1900, 0, 0, 0);

  foreach my $line (@$list) {
    my %TP_INFO   = ();
    my $TP_ID     = $line->[0];
    my $postpaid  = $line->[4];
    my $month_fee = $line->[6];

    $TP_INFO{POSTPAID_MONTHLY} = $line->[13];
    $TP_INFO{REDUCTION}        = $line->[11];
    $TP_INFO{TP_NUM}           = $line->[18];

    $debug_output .= "TP ID: $line->[0] MF: $month_fee POSTPAID: $postpaid\n" if ($debug > 1);

    if ($month_fee > 0) {
      my $ulist = $Voip->user_list(
        {
          ACTIVATE     => "<=$DATE",
          EXPIRE       => "0000-00-00,>$DATE",
          STATUS       => '0;2',
          LOGIN_STATUS => 0,
          TP_ID        => $TP_INFO{TP_NUM},
          PAGE_ROWS    => 10000000,
          COLS_NAME    => 1,
          %VOIP_LIST_PARAMS
        }
      );

      foreach my $u (@$ulist) {
        my %user = (
          LOGIN     => $u->{id},
          UID       => $u->{uid},
          BILL_ID   => $u->{bill_id},
          ACTIVATE  => $u->{activate},
          REDUCTION => 0,
          DEPOSIT   => $u->{deposit},
          CREDIT    => $u->{credit},
          STATUS    => $u->{voip_status},
        );

        $debug_output .= " Login: $user{LOGIN} ($user{UID}) REDUCTION: $user{REDUCTION} DEPOSIT: $u->{deposit} CREDIT $user{CREDIT} ACTIVE: $user{ACTIVATE}\n" if ($debug > 3);
        my %FEES_PARAMS = (
          DESCRIBE => "Voip: $_MONTH_FEE ($TP_ID)",
          DATE     => $ADMIN_REPORT{DATE},
          METHOD   => 1
        );

        if ($user{ACTIVATE} eq '0000-00-00' and $d == 1) {
          if ($postpaid > 0 || $user{DEPOSIT} + $user{CREDIT} > 0) {
            $fees->take(\%user, $month_fee, \%FEES_PARAMS);
          }
          elsif ($conf{VOIP_ONEMONTH_INCOMMING_ALLOW}) {
            my $change_status = ($user{STATUS} == 0) ? 2 : 1;
            $Voip->user_change({ UID => $user{UID}, DISABLE => $change_status });
            $debug_output .= " CHANGE STATUS: $user{STATUS} -> $change_status\n" if ($debug > 3);
          }
        }
        elsif ($user{ACTIVATE} ne '0000-00-00') {
          if ($postpaid > 0 || $user{DEPOSIT} + $user{CREDIT} > 0) {
            my ($activate_y, $activate_m, $activate_d) = split(/-/, $user{ACTIVATE}, 3);
            my $active_unixtime = mktime(0, 0, 0, $activate_d, ($activate_m - 1), $activate_y - 1900, 0, 0, 0);

            if ($date_unixtime - $active_unixtime > 30 * 86400) {
              $fees->take(\%user, $month_fee, \%FEES_PARAMS);
              $users->change($user{UID}, { ACTIVATE => $DATE, UID => $user{UID} });
            }
          }
          elsif ($conf{VOIP_ONEMONTH_INCOMMING_ALLOW}) {
            my $change_status = ($user{STATUS} == 0) ? 2 : 1;
            $Voip->user_change({ UID => $user{UID}, DISABLE => $change_status });
            $debug_output .= " CHANGE STATUS: $user{STATUS} -> $change_status\n" if ($debug > 3);
          }
        }
      }
    }
  }

  $DEBUG .= $debug_output;
  return $debug_output;
}

#**********************************************************
# user_warnings
#
#**********************************************************
sub voip_users_warning_messages {

  my %LIST_PARAMS = (USERS_WARNINGS => 'y');
  my $list = $Voip->list({%LIST_PARAMS});

  $ADMIN_REPORT{USERS_WARNINGS} = sprintf("%-14s| %4s|%-20s| %9s| %8s|\n", $_LOGIN, 'TP', $_TARIF_PLAN, $_DEPOSIT, $_CREDIT) . "---------------------------------------------------------------\n";
  return 0 if ($Dv->{TOTAL} < 1);
  my %USER_INFO = ();

  foreach my $line (@$list) {

    #u.id, u.email, u.tp_id, u.credit, u.deposit, tp.name, tp.uplimit

    $USER_INFO{LOGIN}   = $line->[0];
    $USER_INFO{TP_NAME} = $line->[5];
    $USER_INFO{TP_ID}   = $line->[2];
    $USER_INFO{DEPOSIT} = $line->[4];
    $USER_INFO{CREDIT}  = $line->[3];

    my $email = ((!defined($line->[1])) || $line->[1] eq '') ? (($conf{USERS_MAIL_DOMAIN}) ? "$line->[0]\@$conf{USERS_MAIL_DOMAIN}" : '') : "$line->[1]";

    if ($email eq '') {
      next;
    }

    $ADMIN_REPORT{USERS_WARNINGS} .= sprintf("%-14s| %4d|%-20s| %9.4f| %8.2f|\n", $USER_INFO{LOGIN}, $USER_INFO{TP_ID}, $USER_INFO{TP_NAME}, $USER_INFO{DEPOSIT}, $USER_INFO{CREDIT});

    my $message = $html->tpl_show(_include('dv_users_warning_messages', 'Dv'), \%USER_INFO, { notprint => 'yes' });

    sendmail("$conf{ADMIN_MAIL}", "$email", "  .", "$message", "$conf{MAIL_CHARSET}", "2 (High)");
  }

  $ADMIN_REPORT{USERS_WARNINGS} .= "---------------------------------------------------------------
$_TOTAL: $Dv->{TOTAL}\n";

}

#**********************************************************
# voip_gk_console
#**********************************************************
sub voip_gk_console {

  use Nas;
  my $nas = Nas->new($db, \%conf);

  my $list = $Nas->list({ TYPE => 'gnugk' });
  my $table = $html->table(
    {
      caption    => "$_NAS",
      width      => '100%',
      border     => 1,
      title      => [ "#", "$_NAME", 'NAS-Identifier', 'IP' ],
      cols_align => [ 'right', 'left', 'left', 'right' ],
      qs         => $pages_qs
    }
  );

  my ($host, $user, $password);
  foreach my $line (@$list) {
    if ($line->[0] eq $FORM{NAS_ID}) {
      $table->{rowcolor} = $_COLORS[4];
    }
    else {
      undef($table->{rowcolor});
    }

    $table->addrow($html->button("$line->[0]", "index=$index&NAS_ID=$line->[0]"), $line->[1], $line->[2], $line->[3]);
  }
  print $table->show();

  if ($FORM{NAS_ID}) {

    my %gk_commands = (
      help                         => 'help',
      unregisteralias              => 'unregisteralias',
      PrintAllRegistrations        => 'PrintAllRegistrations, r, ? - Show all registered endpoints',
      PrintAllRegistrationsVerbose => 'PrintAllRegistrationsVerbose, rv, ?? - Show details of all registered endpoints',
      PrintCurrentCalls            => "PrintCurrentCalls, c, ! - Show all current calls using the same ACF syntax as in call establishment. ",
      PrintCurrentCallsVerbose     => "PrintCurrentCallsVerbose, cv, !!  - Show details of all current calls.",
      Find                         => "Find, f - Find a registered endpoint by an alias or a prefix. ",
      FindVerbose                  => "FindVerbose, fv - Find details of a registered endpoint by an alias or a prefix. ",
      UnregisterIP                 => "Forcedly unregister an endpoint by IP and call signalling port. ",
      UnregisterAllEndpoints       => "Forcedly unregister all registered endpoints",

      who                => 'who',
      statistics         => 'statistics',
      shutdown           => 'shutdown',
      debug              => 'debug',
      disconnectalias    => 'disconnectalias',
      disconnectcall     => 'disconnectcall',
      disconnectendpoint => 'disconnectendpoint',
      disconnectip       => 'disconnectip',
      disconnectsession  => 'disconnectsession',
      version            => 'version',
      reload             => 'reload',

    );

    if (length($FORM{command}) > 0) {
      $Nas->info({ NAS_ID => $FORM{NAS_ID} });
      my @commands = ();

      require 'Abills/nas.pl';
      push @commands, "login:\t$Nas->{NAS_MNG_USER}";
      push @commands, "assword:\t$Nas->{NAS_MNG_PASSWORD}";
      push @commands, ";\t$FORM{command}";
      push @commands, ";\tquit";

      my $result    = telnet_cmd("$Nas->{NAS_MNG_IP_PORT}", \@commands, { debug => 1 });
      my $total     = 0;
      my @rows      = split(/\n/, $result);
      my @registred = ();

      if ($FORM{command} =~ /\!|CurrentCalls/) {
        my $table = $html->table(
          {
            width  => '100%',
            border => 1,
            title  => [ 'NUMBER', 'ACF', 'Caller_IP:Port', 'Caller_EPID', 'CRV', 'DestinationInfo', 'SrcInfo', 'IsAnswered', '-' ],
            cols_align => [ 'right', 'center', 'right', 'left', 'left', 'center' ],
            qs         => $pages_qs,
            caption    => 'Associated'
          }
        );

        my @rows = split(/\n/, $result);

        foreach my $line (@rows) {

          if ($line =~ /Dial/) {

            #print "#      Caller_Aliases|Callee_Aliases|Bandwidth|Connected_Time <r>";
            my @registred = split(/\|/, $line);
            $table->addrow(@registred);
            $total++;
          }
          elsif ($line =~ /ACF/) {
            my @registred = split(/\|/, $line);

            #ACF|Caller_IP:Port|Caller_EPID|CRV|DestinationInfo|SrcInfo|IsAnswered;
            #ACF|Callee_IP:Port|Callee_EPID|CRV|DestinationInfo|SrcInfo|IsAnswered;
            $table->addrow('&nbsp;', @registred, $html->button("H", "index=$index&NAS_ID=$FORM{NAS_ID}&command=disconnectcall+$registred[4]", { TITLE => 'Hangup', BUTTON => 1 }));
          }
        }
        print $table->show();

        $table = $html->table(
          {
            caption    => 'Commands',
            width      => '100%',
            cols_align => [ 'right', 'right' ],
            rows       => [ [ "$_TOTAL:", $html->b($total) ] ]
          }
        );

        print $table->show();

        #CurrentCalls
        #Call No. 1 | CallID 06 20 60 00 00 60 40 10 00 00 00 0a f4 53 db fd | 5 | 175
        #Dial 600:dialedDigits
        #ACF|192.168.101.23:2832|9868_ag1|8354|600:dialedDigits|101:dialedDigits|false;
        #ACF|192.168.101.18:1720|9870_ag1|41122|600:dialedDigits|101:dialedDigits|true;
        #Number of Calls: 1 Active: 0 From Neighbor: 0 From Parent: 0

      }
      elsif ($FORM{command} =~ /\?|PrintAllRegistrations$/) {
        my $table = $html->table(
          {
            width      => '100%',
            border     => 1,
            title      => [ "#", "IP", 'NUMBER', "$_TYPE", "ID", '' ],
            cols_align => [ 'right', 'right', 'left', 'center', 'left', 'center' ],
            qs         => $pages_qs,
            caption    => 'Associated'
          }
        );

        foreach my $line (@rows) {
          if ($line =~ /RCF/) {
            @registred = split(/\|/, $line);
            push @registred, $html->button('H', "index=$index&NAS_ID=$FORM{NAS_ID}&command=UnregisterIP+$registred[1]", { TITLE => 'Hangup', BUTTON => 1 });
            $table->addrow(@registred);
          }
        }
        print $table->show();

        $table = $html->table(
          {
            width      => '100%',
            cols_align => [ 'right', 'right' ],
            rows       => [ [ "$_TOTAL:", "<b>$total</b>" ] ]
          }
        );
        print $table->show();
      }
      else {
        $result =~ s/\n/<br>/g;
        $html->message('info', $_INFO, "$result");
      }
    }

    print $html->form_main(
      {
        CONTENT => $html->form_input('command', "$FORM{command}"),
        HIDDEN  => {
          index  => "$index",
          NAS_ID => "$FORM{NAS_ID}"
        },
        SUBMIT => { go => "$_SHOW" }
      }
    );

    $table = $html->table(
      {
        caption    => 'Commands',
        width      => '100%',
        border     => 1,
        title      => [ "_COMMAND", "_HELP" ],
        cols_align => [ 'left', 'left' ]
      }
    );

    foreach my $k (sort keys %gk_commands) {
      $table->addrow($html->button("$k", "index=$index&NAS_ID=$FORM{NAS_ID}&command=$k"), $gk_commands{$k});
    }
    print $table->show();

  }

}

#***********************************************************
# voip_sheduler
#***********************************************************
sub voip_sheduler {
  my ($type, $action, $uid) = @_;

  my $user = $Voip->user_info($uid);
  if ($type eq 'tp') {
    $Voip->user_change(
      {
        UID   => $uid,
        TP_ID => $action
      }
    );
  }

}

#***********************************************************
# Add asterisk user
#***********************************************************
sub voip_mk_users_conf {
  my ($attr) = @_;

  my $content = '';

  my $list = $Voip->user_list(
    {
      PAGE_ROWS => 100000,
      CID       => '*',
      PASSWORD  => 1,
      IP        => '>=0',
      COLS_NAME => 1
    }
  );

  foreach my $line (@$list) {
    my %info = (
      LOGIN     => $line->{id},
      FIO       => $line->{fio},
      NUMBER    => $line->{number},
      CALLER_ID => $line->{cid},
      PASSWORD  => $line->{password},
      HOST      => ($line->{ip} eq '0.0.0.0') ? 'dynamic' : $line->{ip},
      DATE      => $DATE,
      TIME      => $TIME
    );

    $content .= $html->tpl_show(_include('voip_users_conf', 'Voip'), \%info, { OUTPUT2RETURN => 1 });
  }

  if (open(FILE, ">$conf{VOIP_ASTERISK_USERS}")) {
    print FILE "$content\n";
    close(FILE);
  }
  else {

    #$html->message('err', "Voip:$_ERROR", "Can't open file config file '$conf{VOIP_ASTERISK_USERS}' $!") if (! $attr->{QUITE});
  }

  if ($conf{VOIP_ASTERISK_RESTART}) {
    system($conf{VOIP_ASTERISK_RESTART});
  }

}

#***********************************************************
# voip_report
#***********************************************************
sub voip_report {
  my ($type, $attr) = @_;
  my $REPORT = "Module: Voip\n";

  %LIST_PARAMS = %{ $attr->{LIST_PARAMS} } if (defined($attr->{LIST_PARAMS}));

  return $REPORT;
}

#***********************************************************
# voip_report
#***********************************************************
sub voip_extra_tarification {
  my ($type, $attr) = @_;

  %LIST_PARAMS = %{ $attr->{LIST_PARAMS} } if (defined($attr->{LIST_PARAMS}));
  $Voip->{ACTION}     = 'add';
  $Voip->{LNG_ACTION} = $_ADD;

  if ($FORM{add}) {
    $Voip->extra_tarification_add({%FORM});
    if (!$Voip->{errno}) {
      $html->message('info', $_INFO, "$_ADDED");
    }
  }
  elsif ($FORM{change}) {
    $Voip->extra_tarification_change({%FORM});
    if (!$Voip->{errno}) {
      $html->message('info', $_INFO, "$_CHANGED");
    }
  }
  elsif ($FORM{chg}) {
    $Voip->extra_tarification_info({ %FORM, ID => $FORM{chg} });
    if (!$Voip->{errno}) {
      $html->message('info', $_INFO, "$_CHANGING");
    }
    $Voip->{ACTION}     = 'change';
    $Voip->{LNG_ACTION} = $_CHANGE;
  }
  elsif ($FORM{del} && $FORM{is_js_confirmed}) {
    $Voip->extra_tarification_del({ ID => $FORM{del} });
    if (!$Voip->{errno}) {
      $html->message('info', $_INFO, "$_DELETED");
    }
  }

  if ($Voip->{errno}) {
    $html->message('err', $_ERROR, "[$Voip->{errno}] $err_strs{$Voip->{errno}}");
  }

  $html->tpl_show(_include('voip_extra_tarification', 'Voip'), $Voip);

  my $list = $Voip->extra_tarification_list({%LIST_PARAMS});

  if ($Voip->{errno}) {
    $html->message('err', $_ERROR, "[$Voip->{errno}] $err_strs{$Voip->{errno}}");
    return 0;
  }

  my $table = $html->table(
    {
      width      => '100%',
      border     => 1,
      title      => [ 'id', "$_NAME", "$_PREPAID $_TIME", '-', '-' ],
      cols_align => [ 'left', 'left', 'right', 'right', 'left', 'center', 'left', 'center', 'center', 'center' ],
      qs         => $pages_qs,
      pages      => $Voip->{TOTAL}
    }
  );

  foreach my $line (@$list) {
    my $delete = $html->button($_DEL, "index=$index&del=$line->[0]", { MESSAGE => "$_DEL [$line->[0]] ?", CLASS => 'del' });
    my $change = $html->button($_DEL, "index=$index&chg=$line->[0]", { CLASS => 'change' });

    $table->{rowcolor} = ($FORM{chg} && $FORM{chg} == $line->[0]) ? $_COLORS[0] : undef;

    $table->addrow(
      $line->[0],
      "$line->[1]",
      "$line->[2]",
      $change,
      $delete,

    );
  }
  print $table->show();

  $table = $html->table(
    {
      width      => '100%',
      cols_align => [ 'right', 'right' ],
      rows       => [ [ "$_TOTAL:", $html->b($Voip->{TOTAL}) ] ]
    }
  );
  print $table->show();
}

#**********************************************************
# exchange_rate
#**********************************************************
sub voip_exchange_rate {
  my %info = (
    ACTION     => 'add',
    LNG_ACTION => $_ADD
  );

  if ($FORM{add}) {
    $FORM{VOIP_ER_CHANGED} = "$DATE $TIME";
    while (my ($k, $v) = each %FORM) {
      next if ($k !~ /^VOIP_/);
      $users->config_add(
        {
          PARAM => $k,
          VALUE => "$v"
        }
      );
    }

    if (!$users->{errno}) {
      $html->message('info', $_INFO, "$_CHANGED");
      $admin->{MODULE} = 'Voip';
      $admin->system_action_add("$FORM{VOIP_ER}", { TYPE => 41 });
      $Voip->rp_change_exhange_rate({ EXCHANGE_RATE => $FORM{VOIP_ER} });
    }
  }
  elsif ($FORM{change}) {
    $FORM{VOIP_ER_CHANGED} = "$DATE $TIME";
    while (my ($k, $v) = each %FORM) {
      next if ($k !~ /^VOIP_/);
      $users->config_change(
        $k,
        {
          PARAM => $k,
          NAME  => "$v"
        }
      );
    }

    if (!$users->{errno}) {
      $html->message('info', $_INFO, "$_CHANGED");
      $admin->{MODULE} = 'Voip';
      $admin->system_action_add("$FORM{VOIP_ER}", { TYPE => 41 });
      $Voip->rp_change_exhange_rate({ EXCHANGE_RATE => $FORM{VOIP_ER} });
    }

  }

  my $list = $users->config_list({ PARAM => 'VOIP_*', SORT => 2 });

  foreach my $line (@$list) {
    $info{ $line->[0] } = $line->[1];
  }
  if ($info{VOIP_ER}) {
    $info{ACTION}     = 'change';
    $info{LNG_ACTION} = $_CHANGE;
  }

  $html->tpl_show(_include('voip_er', 'Voip'), \%info);
}

#**********************************************************
#
#**********************************************************
sub voip_payments_maked {
  my ($attr) = @_;

  voip_mk_users_conf();
}

#**********************************************************
# Provision
#**********************************************************
sub voip_provision {
  my ($attr) = @_;

  my $list = $Nas->list({ TYPE => 'ls_pap2t;ls_spa8000' });

  my $hosts = '';
  foreach my $line (@$list) {
    $hosts .= $html->tpl_show(
      _include('voip_provision_dhcp_host', 'Voip'),
      {
        NAS_ID   => $line->[0],
        HOSTNAME => $line->[1],
        MAC      => $line->[15],
        IP       => $line->[3],
        ROUTERS  => '',
      },
      { OUTPUT2RETURN => 1 }
    );
  }

  my $conf = $html->tpl_show(_include('voip_provision_dhcp_conf', 'Voip'), { HOSTS => $hosts }, { OUTPUT2RETURN => 1 });

  if (open(FILE, ">/usr/local/abills/Abills/templates/provision_dhcp.conf")) {
    print FILE "$conf\n";
    close(FILE);
  }
  else {

  }

}

1

