Горячая смена тарифного плана в середине месяца

Технические вопросы по UTM 5.0
Denis Samsonov
Сообщения: 68
Зарегистрирован: Сб май 13, 2006 10:11

Сообщение Denis Samsonov »

еще один вариант смены ТП :)

Код: Выделить всё

#если пользователь выбрал тариф
if(isset($_POST['n_tariff_id'])) {
$n_tariff_id=$_POST['n_tariff_id']; //ID нового тарифа
$cur_date = strtotime(date("Y-m-d")); //текущая дата
$td_check = $cur_date-259200; //-30 дней от текущей даты
узнаем стоимость нового тарифа для проверки хватит ли абонентской платы

Код: Выделить всё

$ntsum_query = mysql_query("SELECT cost FROM tariffs_services_link, tariffs, periodic_services_data WHERE tariffs.id=tariffs_services_link.tariff_id AND periodic_services_data.id=tariffs_services_link.service_id AND tariffs.id='$n_tariff_id'") or die ("Не удалось узнать стоимость нового тарифа");
$ntsum_row = mysql_fetch_array($ntsum_query);
if &#40;$balance<$ntsum_row&#91;0&#93;&#41; die &#40;"<br><br><center>На вашем счету недостаточно средств для смены тарифа</center>"&#41;;
проверяем когда последний раз меняли тариф

Код: Выделить всё

$ltc_query = mysql_query&#40;"SELECT id, change_date FROM wk_tariffs_change WHERE account_id='$account_id' AND change_date BETWEEN $td_check AND $cur_date"&#41; or die&#40;"Не удается получить дату последней смены тарифа"&#41;;
if &#40;mysql_num_rows&#40;$ltc_query&#41;!=NULL&#41; die&#40;"<center><br><br>Вы меняли тариф менее чем 30 дней назад. Смена тарифа невозможна</center>"&#41;;

Узнаем стоимостт старого тарифа. для компенсации

Код: Выделить всё

$tsum_query = mysql_query&#40;"SELECT cost FROM tariffs_services_link, tariffs, periodic_services_data WHERE tariffs.id=tariffs_services_link.tariff_id AND periodic_services_data.id=tariffs_services_link.service_id AND tariffs.id='$tariff_id'"&#41; or die &#40;"Не удалось узнать стоимость текущего тарифа"&#41;;
$tsum_numresults = mysql_num_rows&#40;$tsum_query&#41;;
for &#40;$i=0; $i <$tsum_numresults; $i++&#41;&#123;
$tsum_row = mysql_fetch_array&#40;$tsum_query&#41;;
$tsum=$tsum+$tsum_row&#91;0&#93;;
&#125;
узнаем рассчетный период на который подключать пользователя

Код: Выделить всё

$start_date = date&#40;"Y-m-d"&#41;; //текущая дата    
$dperiod_query = mysql_query&#40;"SELECT id FROM discount_periods WHERE start_date=UNIX_TIMESTAMP&#40;'$start_date 06&#58;00&#58;00'&#41; AND periodic_type=3 AND is_expired=0 LIMIT 1"&#41; or die &#40;"Не удалось выполнить запрос на получение рассчетного периода"&#41;;
$dperiod_numrows = mysql_num_rows&#40;$dperiod_query&#41;;
if&#40;$dperiod_numrows==NULL&#41; die&#40;"Отсутствует подходящий рассчетный период. Смена тарифа невозможна"&#41;;
$dperiod_row=mysql_fetch_array&#40;$dperiod_query&#41;;
$dperiod=$dperiod_row&#91;0&#93;; //ID рассчетного периода для нового тарифа
узнаем IP адрес пользователя

Код: Выделить всё

$ipaddr_query = mysql_query&#40;"SELECT sl.user_id, u.login, INET_NTOA&#40;ip & 4294967295&#41; as ip, i.mask FROM ip_groups i, iptraffic_service_links isl, service_links sl, users u WHERE i.is_deleted='0' AND isl.is_deleted='0' AND sl.is_deleted='0' AND i.ip_group_id=isl.ip_group_id AND isl.id=sl.id AND sl.user_id=u.id AND ip_type=1 AND login='$login'"&#41;;
$ipaddr_numresults = mysql_num_rows &#40;$ipaddr_query&#41;;
$ipaddr_row = mysql_fetch_array&#40;$ipaddr_query&#41;;
$user_ip=$ipaddr_row&#91;2&#93;; //IP адрес пользователя

выключаем пользователю интернет

Код: Выделить всё

exec&#40;"$utils_path/utm5_urfaclient -h $utm5corehost -l $utm5coreuser -P $utm5corepass -x $utils_path/xml/ -a edit_account -account_id $account_id -int_status 0"&#41;;

удаляем старый тарифный план

Код: Выделить всё

exec&#40;"$utils_path/utm5_urfaclient -h $utm5corehost -l $utm5coreuser -P $utm5corepass -x $utils_path/xml/ -a unlink_tariff -user_id $id -account_id $account_id -tariff_link_id $tariff_link_id"&#41;;
#таймаут 10 секунд. на всякий случай
sleep&#40;5&#41;;
#присваиваем новый тарифный план
exec&#40;"$utils_path/utm5_urfaclient -h $utm5corehost -l $utm5coreuser -P $utm5corepass -x $utils_path/xml/ -a link_tariff_with_services -user_id $id -account_id $account_id -tariff_current $n_tariff_id -discount_period_id $dperiod -ip_address $user_ip -ip_not_vpn 1"&#41;;

делаем компенсацию

Код: Выделить всё

$days_to_dperiod = $dperiod_end_date_unixtime-$cur_date;
$days_to_dperiod = $days_to_dperiod/86400; //считаем сколько осталось дней до конца расчетного периода
$days_to_dperiod = round&#40;$days_to_dperiod,0&#41;; //округляем количество дней
$compday=$tsum/30; //стоимость 1-го дня старого тарифа    
$compensation=$compday*$days_to_dperiod;
$compensation=round&#40;$compensation,0&#41;;
exec&#40;"$utils_path/utm5_urfaclient -h $utm5corehost -l $utm5coreuser -P $utm5corepass -x $utils_path/xml/ -a add_payment -account_id $account_id -payment $compensation -payment_method 104 -comment \"Tariff change compensation\""&#41;;

включаем пользователю интернет

Код: Выделить всё

exec&#40;"$utils_path/utm5_urfaclient -h $utm5corehost -l $utm5coreuser -P $utm5corepass -x $utils_path/xml/ -a edit_account -account_id $account_id -int_status 1"&#41;;

вставляем запись о смене тарифа

Код: Выделить всё

mysql_query&#40;"INSERT INTO wk_tariffs_change &#40;account_id, change_date, tariff_id&#41; VALUES &#40;'$account_id', '$cur_date', '$n_tariff_id'&#41;"&#41; or die &#40;"Не удается сделать запись о смене тарифа"&#41;;
print&#40;"<br><br><center>Тариф успешно сменен</center>"&#41;;

?>
Последний раз редактировалось Denis Samsonov Пт ноя 06, 2009 10:25, всего редактировалось 2 раза.

Denis Samsonov
Сообщения: 68
Зарегистрирован: Сб май 13, 2006 10:11

Сообщение Denis Samsonov »

Кто посоветует что покрутить, что улучшить и как лучше сделать?

Аватара пользователя
Magnum72
Сообщения: 1947
Зарегистрирован: Чт сен 22, 2005 06:54
Контактная информация:

Сообщение Magnum72 »

Denis Samsonov писал(а):Кто посоветует что покрутить, что улучшить и как лучше сделать?
Для начала оформи код как

Код: Выделить всё

, ну нифига же не понятно

Pulse
Сообщения: 945
Зарегистрирован: Вт окт 03, 2006 12:58

Сообщение Pulse »

в дебаге видно что вызывается add_service_to_user один раз только

Аватара пользователя
Magnum72
Сообщения: 1947
Зарегистрирован: Чт сен 22, 2005 06:54
Контактная информация:

Сообщение Magnum72 »

Pulse писал(а):в дебаге видно что вызывается add_service_to_user один раз только
стукнись в аську подумаем, я честно не понимаю в чем глюк, тут или родители разные, или галочки подкючеть по умолчанию услугу не стоит. других вариантов просто нет как мне кажется

Denis Samsonov
Сообщения: 68
Зарегистрирован: Сб май 13, 2006 10:11

Сообщение Denis Samsonov »

Magnum72 писал(а):
Denis Samsonov писал(а):Кто посоветует что покрутить, что улучшить и как лучше сделать?
Для начала оформи код как

Код: Выделить всё

, ну нифига же не понятно[/quote]

Оформил

Аватара пользователя
Magnum72
Сообщения: 1947
Зарегистрирован: Чт сен 22, 2005 06:54
Контактная информация:

Сообщение Magnum72 »

Denis Samsonov писал(а):
Magnum72 писал(а):
Denis Samsonov писал(а):Кто посоветует что покрутить, что улучшить и как лучше сделать?
Для начала оформи код как

Код: Выделить всё

, ну нифига же не понятно[/quote]

Оформил[/quote]

1) Компенсация начиная с 007 уже не нужна, там недосписываются остатки абонентки.
2) проверку на наличие средств можно внести в урфу.
3) Расчетный период лучше узнавать в урфе в момент получения данных по старому ТП.

Воообще парадокс, урфа вроде куплена как я вижу, но используете вы ее на 1%, в принципе всю тяжелую артилерют можно выполнить внутри урфа скрипта, снаружи останется только предварительная проверка на дату последней смены ТП и запись о смене тарифа, хотя тоже не обязательно, оно в биллинге и так логигируется.

Denis Samsonov
Сообщения: 68
Зарегистрирован: Сб май 13, 2006 10:11

Сообщение Denis Samsonov »

Magnum72 писал(а):
Denis Samsonov писал(а):
Magnum72 писал(а):
Denis Samsonov писал(а):Кто посоветует что покрутить, что улучшить 1) Компенсация начиная с 007 уже не нужна, там недосписываются остатки абонентки.
Компенсация имхо все равно нужна будет, мы абонентку списываем полностью в начале рассчетного периода. Хотя..... может в 007 и поправили это.

А с урфой да, недавно совсем общаюсь, еще не врубился в ее логику. Где бы толковые доки по ней почитать и примеры поглядеть... (то что в доке нетапа всей картины имхо не дает)

Denis Samsonov
Сообщения: 68
Зарегистрирован: Сб май 13, 2006 10:11

Сообщение Denis Samsonov »

Magnum72 писал(а):]Кто посоветует что покрутить, что улучшить 1) Компенсация начиная с 007 уже не нужна, там недосписываются остатки абонентки.
Компенсация имхо все равно нужна будет, мы абонентку списываем полностью в начале рассчетного периода. Хотя..... может в 007 и поправили это.

А с урфой да, недавно совсем общаюсь, еще не врубился в ее логику. Где бы толковые доки по ней почитать и примеры поглядеть... (то что в доке нетапа всей картины имхо не дает)[/quote]

plaguekriz
Сообщения: 64
Зарегистрирован: Пн июн 15, 2009 15:28

Сообщение plaguekriz »

на основе скрипта Denis Samsonov сделал свой. Немного переделал для более удобного использования из консоли. Но есть такая проблема:
запрос

Код: Выделить всё

exec&#40;"$utils_path/bin/utm5_urfaclient -h $utm5corehost -l $utm5coreuser -P $utm5corepass -x $utils_path/xml/ -a unlink_tariff -user_id $user_id -account_id $account_id -tariff_link_id $tariff_link_id"&#41;;
не срабатывает. Данные получаю из запроса:

Код: Выделить всё

$user_data_query=mysql_query&#40;"SELECT sl.user_id, sl.account_id, sl.service_id, sl.tariff_link_id FROM service_links sl, users u WHERE u.id=sl.user_id AND u.login='$login' limit 1"&#41;;
$user_data_result=mysql_fetch_array&#40;$user_data_query&#41;;
$user_id=$user_data_result&#91;0&#93;;
$account_id=$user_data_result&#91;1&#93;;
$service_id=$user_data_result&#91;2&#93;;
$tariff_link_id=$user_data_result&#91;3&#93;;
Делаю этот запрос но тариф так и остается на месте. Почему такое может быть? В дебаге ничего предосудительного не заметил

Код: Выделить всё

Processing action&#58; unlink_tariff
<call> tag&#58; rpcf_unlink_user_tariff
Processing call rpcf_unlink_user_tariff
URFA Call&#58; 0x3019
  account_id=>'44'; 
  tariff_link_id=>'51'; 
  user_id=>'44'; 
process_input start
INDEXES &#40;0&#41; &#58; 0 

get_var_value&#58; curr index 0 var.list.size 0 var.size 1
Passing int <user_id> value <44>
INDEXES &#40;0&#41; &#58; 0 

get_var_value&#58; curr index 0 var.list.size 0 var.size 1
Passing int <account_id> value <44>
INDEXES &#40;0&#41; &#58; 0 

get_var_value&#58; curr index 0 var.list.size 0 var.size 1
Passing int <tariff_link_id> value <51>
process_input end
<br><br><center>Тариф успешно сменен</center>


Avdoshkin
Сообщения: 156
Зарегистрирован: Вт май 10, 2005 19:28
Откуда: Ачинск
Контактная информация:

Сообщение Avdoshkin »

Из этой темы воспользовался XML-схемой по смене тарифа и немного подправил под себя. В результате все тариф меняется, привязывается все услуги к этому тарифу вообщем все ок, но в конце выдает ошибку гуру поясните как можно исправить...

Код: Выделить всё

<?xml version="1.0"?>
<urfa>
  <parameter name="user_id"/>
  <parameter name="account_id"/>
  <parameter name="slink_id"/>
  <parameter name="discount_period_id"/>
  <parameter name="is_blocked"/>
  <parameter name="discount_date"/>
  <parameter name="tariff_link_id"/>
  <parameter name="tariff_current"/>
  <parameter name="tariff_next"/>
  <parameter name="start_date"/>
  <parameter name="expire_date"/>
  <parameter name="unabon"/>
  <parameter name="unprepay"/>
  <parameter name="is_blocked"/>
  <parameter name="ip_address"/>
  <parameter name="mask"/>
  <parameter name="mac"/>
  <parameter name="iptraffic_login"/>
  <parameter name="iptraffic_allowed_cid"/>
  <parameter name="iptraffic_password"/>
  <parameter name="ip_not_vpn"/>
  <parameter name="dont_use_fw"/>
  <parameter name="router_id"/>
  <parameter name="tclass_id"/>
  <parameter name="quota"/>
  <parameter name="callback_enabled"/>
  <parameter name="dialup_login"/>
  <parameter name="dialup_allowed_cid"/>
  <parameter name="dialup_allowed_csid"/>
  <parameter name="dialup_password"/>
  <parameter name="tariff_link_id_find"/>
  <parameter name="lock_per_srv" value="0"/>
  <parameter name="lock_ip_srv" value="0"/>

  <call function="rpcf_get_all_services_for_user"/>
  <for name="w" from="0" count="size&#40;slink_id_array&#41;">
    <set dst="service_type" src="service_type_array" src_index="w"/>
    <set dst="slink_id" src="slink_id_array" src_index="w" />

    <if variable="service_type" value="2" condition="eq">
      <if variable="lock_per_srv" value="1" condition="ne">
        <call function="rpcf_get_periodic_service_link"/>
        <if variable="tariff_link_id" value="tariff_link_id_find" condition="eq">
          <set dst="lock_per_srv" value="1"/>
          <call function="rpcf_delete_slink"/>
        </if>
      </if>
    </if>

    <if variable="service_type" value="3" condition="eq">
        <remove name="ip_address"/>
        <remove name="mask"/>
        <remove name="mac"/>
        <remove name="iptraffic_login"/>
        <remove name="iptraffic_password"/>
        <remove name="iptraffic_allowed_cid"/>
        <remove name="ip_not_vpn"/>
        <remove name="dont_use_fw"/>
        <remove name="router_id"/>
        <remove name="tclass_id"/>
        <remove name="tclass_name"/>
        <remove name="quota"/>
      <if variable="lock_ip_srv" value="1" condition="ne">
        <call function="rpcf_get_iptraffic_service_link"/>
        <if variable="tariff_link_id" value="tariff_link_id_find" condition="eq">
          <set dst="lock_ip_srv" value="1"/>
          <call function="rpcf_delete_slink"/>
        </if>
      </if>
    </if>
  </for>

  <call function="rpcf_get_user_by_account"/>

  <set dst="tariff_link_id" src="tariff_link_id_find"/>
  <call function="rpcf_unlink_user_tariff"/>

  <set dst="tariff_link_id" value="0"/>
  <call function="rpcf_link_user_tariff"/>

  <set dst="tariff_id" src="tariff_current"/>
  <call function="rpcf_get_tariff"/>
  <for name="j" from="0" count="size&#40;service_id_array&#41;">
    <set src="link_by_default_array" src_index="j" dst="link_by_default"/>
    <if variable="link_by_default" value="1" condition="eq">
      <set dst="slink_id" value="0"/>
      <set src="service_id_array" src_index="j" dst="service_id"/>
      <set src="service_type_array" src_index="j" dst="service_type"/>
      <set src="service_cost_array" src_index="j" dst="service_cost"/>
      <set dst="return_type" value=""/>
      <set dst="unabon" value="1"/>.
      <set dst="unprepay" value="1"/>.
      <set dst="start_date" value="now&#40;&#41;"/>.

      <if variable="service_type" value="2" condition="eq">
        <call function="rpcf_add_service_to_user"/>
      </if>

      <if variable="service_type" value="3" condition="eq">
        <call function="rpcf_add_service_to_user"/>
      </if>
    </if>
  </for>
</urfa>
Ошибка:

Код: Выделить всё

FAILED TO PARSE INDEXES&#58;
INDEXES &#40;j&#41; &#58; 2

get_var_value&#58; curr index 2 var.list.size 0 var.size 2
Array link_by_default_array index &#40;0&#41; ,2 out of range &#40;read&#41;
ERROR&#58; Array index out of range

Avdoshkin
Сообщения: 156
Зарегистрирован: Вт май 10, 2005 19:28
Откуда: Ачинск
Контактная информация:

Сообщение Avdoshkin »

Отвечаю на свой вопрос, может, кому пригодится.

FAILED TO PARSE INDEXES:
то это сообщение является не ошибкой, а предупреждением, связанным с типом принимаемых данных. Оно никак не влияет на работоспособность utm5_urfaclient, поэтому его можно смело игнорировать при отсутствии других ошибок.
Сообщение вида array index out of range свидетельствуют о проблеме с перезаписью данных: при использовании цикла необходимо обнулять данные в
используемых переменных с помощью команды <remove name="имя переменной"/>

Рабочий вариант смены тарифа и входящими в него услугами.

Код: Выделить всё

utm5_urfaclient -a test24 -account_id 438 -tariff_current 449 -tariff_link_id_find 12329
<?xml version="1.0"?>
<urfa>
  <parameter name="user_id"/>
  <parameter name="account_id"/>
  <parameter name="slink_id"/>
  <parameter name="discount_period_id"/>
  <parameter name="is_blocked"/>
  <parameter name="discount_date"/>
  <parameter name="tariff_link_id"/>
  <parameter name="tariff_current"/>
  <parameter name="tariff_next"/>
  <parameter name="start_date"/>
  <parameter name="expire_date"/>
  <parameter name="unabon"/>
  <parameter name="unprepay"/>
  <parameter name="is_blocked"/>
  <parameter name="ip_address"/>
  <parameter name="mask"/>
  <parameter name="mac"/>
  <parameter name="iptraffic_login"/>
  <parameter name="iptraffic_allowed_cid"/>
  <parameter name="iptraffic_password"/>
  <parameter name="ip_not_vpn"/>
  <parameter name="dont_use_fw"/>
  <parameter name="router_id"/>
  <parameter name="tclass_id"/>
  <parameter name="quota"/>
  <parameter name="callback_enabled"/>
  <parameter name="dialup_login"/>
  <parameter name="dialup_allowed_cid"/>
  <parameter name="dialup_allowed_csid"/>
  <parameter name="dialup_password"/>
  <parameter name="tariff_link_id_find"/>
  <parameter name="lock_per_srv" value="0"/>
  <parameter name="lock_ip_srv" value="0"/>

  <call function="rpcf_get_all_services_for_user"/>
  <for name="w" from="0" count="size&#40;slink_id_array&#41;">
    <set dst="service_type" src="service_type_array" src_index="w"/>
    <set dst="slink_id" src="slink_id_array" src_index="w" />

    <if variable="service_type" value="2" condition="eq">
      <if variable="lock_per_srv" value="1" condition="ne">
        <call function="rpcf_get_periodic_service_link"/>
        <if variable="tariff_link_id" value="tariff_link_id_find" condition="eq">
          <set dst="lock_per_srv" value="1"/>
          <call function="rpcf_delete_slink"/>
        </if>
      </if>
    </if>

    <if variable="service_type" value="3" condition="eq">
      <if variable="lock_ip_srv" value="1" condition="ne">
        <call function="rpcf_get_iptraffic_service_link"/>
        <if variable="tariff_link_id" value="tariff_link_id_find" condition="eq">
          <set dst="lock_ip_srv" value="1"/>
          <call function="rpcf_delete_slink"/>
        </if>
      </if>
    </if>
  </for>

  <call function="rpcf_get_user_by_account"/>

  <set dst="tariff_link_id" src="tariff_link_id_find"/>
  <call function="rpcf_unlink_user_tariff"/>

  <set dst="tariff_link_id" value="0"/>
  <call function="rpcf_link_user_tariff"/>

  <set dst="tariff_id" src="tariff_current"/>
  <call function="rpcf_get_tariff_new"/>
  <for name="j" from="0" count="size&#40;service_id_array&#41;">
  <set src="link_by_default_array" src_index="j" dst="link_by_default"/>
     <if variable="link_by_default" value="1" condition="eq">
      <set dst="slink_id" value="0"/>
      <set src="service_id_array" src_index="j" dst="service_id"/>
      <set src="service_type_array" src_index="j" dst="service_type"/>
      <set src="service_cost_array" src_index="j" dst="service_cost"/>
      <set dst="return_type" value=""/>
      <set dst="unabon" value="1"/>
      <set dst="unprepay" value="1"/>
      <set dst="start_date" value="now&#40;&#41;"/>

      <if variable="service_type" value="2" condition="eq">
        <call function="rpcf_add_service_to_user"/>
      </if>
      <if variable="service_type" value="3" condition="eq">
        <call function="rpcf_add_service_to_user"/>
     </if>
   </if>
  </for>
</urfa>


Ответить