BiTel

Форум BiTel
bgbilling.ru     docs.bitel.ru     wiki.bitel.ru     dbinfo.bitel.ru     bgcrm.ru     billing.bitel.ru     bitel.ru    
Текущее время: 01 ноя 2024, 06:09

Часовой пояс: UTC + 5 часов [ Летнее время ]




Начать новую тему Ответить на тему  [ Сообщений: 81 ]  На страницу 1, 2, 3  След.
Автор Сообщение
 Заголовок сообщения: Свой action в личном кабинете
СообщениеДобавлено: 24 ноя 2009, 12:53 
Биллинг вер. 4.6

Появилась необходимость добавить свой action в личный кабинет пользователя(Web интерфейс).
На форуме нигде полного решения я не нашел. Хотелось бы собрать все воедино.

Редактируем файл /BGBillingServer/webroot/xsl/main.xsl

Добавляем:
...
<xsl:when test="data/@action = 'MemoTable' or data/@action = 'Memo'">ПРИМЕЧАНИЯ</xsl:when>
<xsl:when test="data/@action = 'test'">TEST</xsl:when>
<xsl:otherwise>НОВОСТИ</xsl:otherwise>
...
...
<xsl:when test="@action = 'MemoTable' or @action = 'Memo'">
<xsl:call-template name="Memo"/>
</xsl:when>
<xsl:when test="@action = 'test'">
<xsl:call-template name="Test"/>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="news"/>
</xsl:otherwise>
...
...
<xsl:otherwise>
<div class="toList"><a href="{$WEBEXECUTER}?action=MemoTable&amp;mid=contract">К списку ...</a></div>
<div class="MemoDate"><!-- <span>Дата:</span> --><xsl:value-of select="/data/memo/@date"/></div>
<div class="MemoTitle"><span>Заголовок:</span> <xsl:value-of select="/data/memo/@title"/></div>
<pre class="MemoText"><xsl:value-of select="/data/memo/@comment"/></pre>
</xsl:otherwise>
</xsl:choose>
</xsl:template>

<xsl:template name="Test">
<select name="test">
<option value="-1">---</option>
<xsl:for-each select="/data/test/table/row">
<option value="{@id}"><xsl:value-of select="@title"/></option>
</xsl:for-each>
</select>
</xsl:template>

<xsl:template name="news">
<xsl:if test="/data/news/item">
<div id="idDivNews">
<xsl:for-each select="/data/news/item">
<span class="date"><xsl:value-of select="@date"/></span><strong class="newsTitle"><xsl:value-of select="@title"/></strong><br/>^M
<xsl:choose>^M
<xsl:when test="data"><xsl:for-each select="data"><xsl:copy-of select="*|text()"/></xsl:for-each></xsl:when>^M
<xsl:otherwise><xsl:for-each select="div"><xsl:value-of select="."/><br/></xsl:for-each></xsl:otherwise>^M
</xsl:choose>
<br/>
</xsl:for-each>
</div>
</xsl:if>
</xsl:template>
...



Пишем пакет (файл WebAction_test.java):
Код:
package bitel.billing.server.contract;

import java.sql.SQLException;
import java.util.List;

import org.w3c.dom.Element;

import bitel.billing.server.contract.action.ActionBase;

public class WebAction_test   extends ActionBase
{
    @Override
    public void doAction()
            throws SQLException
    {
        Element test = createElement( rootNode, "test" );
        Element table = createElement( test, "table" );

        Element element = createElement( table, "row" );
        element.setAttribute( "id", String.valueOf( 1 ) );
        element.setAttribute( "title", "title1" );

        element = createElement( table, "row" );
        element.setAttribute( "id", String.valueOf( 2 ) );
        element.setAttribute( "title", "title2" );
    };
};


Компилим его:
BGBillingServer# /usr/lib/jdk/bin/javac -cp ./:lib/* lda/WebAction_test.java
Получаем файл: WebAction_test.class

Теперь вопрос куда его запихать?
В голову пришло три варианта:
1. Создать ремапинг action.remap_<module>_<action>=mypackage.MyAction
2. Создать отдельную библиотеку(что то вроде test.jar) и положить его в папку lib биллинга
3. Закинуть его в server.jar(/bitel/billing/server/contract)

Я выбрал 3-й вариант, как самый простой, но неверное не самый правильный :)

Я получил то что хотел. В личном кабинете появился пункт меню "TEST". При выборе этого пункта открывается заполненный комбобокс.

У меня вопрос к разработчикам.
Подскажите как правильно добавлять action? Т.е. как правильно подключить WebAction_test.class?


Вернуться к началу
  
 
 Заголовок сообщения: Re: Свой action в личном кабинете
СообщениеДобавлено: 24 ноя 2009, 14:09 
Не в сети
Разработчик
Аватара пользователя

Зарегистрирован: 19 дек 2006, 21:04
Сообщения: 5970
Карма: 256
Создать отдельную my.jar, потому что иначе при апдейте перетрётся.
Класс в том же пакете что и стандартные веб-экшны.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Свой action в личном кабинете
СообщениеДобавлено: 24 ноя 2009, 14:24 
Ок. Спасибо.
Извините за глупый вопрос. А как с линуксе создать my.jar? :)
Точнее с какими параметрами запускать /usr/lib/jdk/bin/jar?


Вернуться к началу
  
 
 Заголовок сообщения: Re: Свой action в личном кабинете
СообщениеДобавлено: 24 ноя 2009, 14:39 
Не в сети
Разработчик
Аватара пользователя

Зарегистрирован: 19 дек 2006, 21:04
Сообщения: 5970
Карма: 256
jar cf my.jar lda/


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Свой action в личном кабинете
СообщениеДобавлено: 24 ноя 2009, 15:03 
Спасибо. Все получилось.


Вернуться к началу
  
 
 Заголовок сообщения: Re: Свой action в личном кабинете
СообщениеДобавлено: 21 дек 2009, 13:55 
Не в сети

Зарегистрирован: 09 июл 2009, 11:31
Сообщения: 82
Откуда: Россия
Карма: 20
А каким образом можно данные из личного кабинета передать в action?
Например, я хочу, чтобы пользователь имел возможность сменить контактный email (аналогично смене пароля).


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Свой action в личном кабинете
СообщениеДобавлено: 21 дек 2009, 16:18 
Не в сети
Разработчик

Зарегистрирован: 08 ноя 2007, 01:05
Сообщения: 8343
Откуда: Уфа
Карма: 238
DDPaul писал(а):
А каким образом можно данные из личного кабинета передать в action?
Например, я хочу, чтобы пользователь имел возможность сменить контактный email (аналогично смене пароля).

данные передаются как стандартные параметры запроса ,а actiop достает их запроса ( объект request ) по имени


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Свой action в личном кабинете
СообщениеДобавлено: 21 дек 2009, 17:41 
Не в сети

Зарегистрирован: 09 июл 2009, 11:31
Сообщения: 82
Откуда: Россия
Карма: 20
А какой класс нужно использовать для работы с объектом request? Я пока не слишком силен в Java :)


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Свой action в личном кабинете
СообщениеДобавлено: 21 дек 2009, 19:11 
Не в сети
Разработчик

Зарегистрирован: 08 ноя 2007, 01:05
Сообщения: 8343
Откуда: Уфа
Карма: 238
DDPaul писал(а):
А какой класс нужно использовать для работы с объектом request? Я пока не слишком силен в Java :)

если вы пишете свой Action, знаит он наследуется от bitel.billing.server.ActionBase и там есть уже поле request - оно доступно


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Свой action в личном кабинете
СообщениеДобавлено: 21 дек 2009, 20:31 
Не в сети

Зарегистрирован: 09 июл 2009, 11:31
Сообщения: 82
Откуда: Россия
Карма: 20
Понял, спасибо, работает.

Еще пара вопросов.

1. Как в action'е добавить новый атрибут к xml-узлу data?
Например, атрибут status="ok", так чтобы в шаблонах можно было использовать стандартную конструкцию:
Код:
<xsl:if test="@status = 'ok'"><div class="infoMessage">Email изменен />!</div></xsl:if>

2. Доступна ли API документация по ActionBase?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Свой action в личном кабинете
СообщениеДобавлено: 21 дек 2009, 20:50 
Не в сети
Аватара пользователя

Зарегистрирован: 30 май 2008, 15:51
Сообщения: 6055
Карма: 244
статус OK сам должен добавиться. статус error устанавливается после setErrorStatus("текст ошибки")

_________________
I'm clever. I've got a computer.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Свой action в личном кабинете
СообщениеДобавлено: 21 дек 2009, 20:51 
Не в сети
Аватара пользователя

Зарегистрирован: 30 май 2008, 15:51
Сообщения: 6055
Карма: 244
добавить новый атрибут к узлу data:
Код:
rootNode.setAttribute("attr","value");

_________________
I'm clever. I've got a computer.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Свой action в личном кабинете
СообщениеДобавлено: 23 дек 2009, 13:53 
Не в сети

Зарегистрирован: 09 июл 2009, 11:31
Сообщения: 82
Откуда: Россия
Карма: 20
Спасибо, с этим разобрался.

Теперь вопрос, как, собственно, изменить параметр договора типа email в action'е. Насколько я понимаю, есть 2 способа: через SQL либо через API.

Решил сначала попробовать через API:

Код:
...
String email = request.getParameter( "email" );
   
// Получаем идентификатор клиента в cid, как описано в wiki
// ID параметра типа email - pid

ContractEmailParamValue emailParam = new ContractEmailParamValue();
emailParam.setEmail( email );
    
ContractParameterManager cpm = new ContractParameterManager( con );
cpm.setEmailParam( cid, pid, emailParam, true, 1 );
...


В server.log после запуска action'а видим:
Код:
LoggingPrintStream - com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry '12-19' for key 2

cid=12, pid=19 в данном случае.

setEmailParam, насколько я понял, используется для создания нового параметра типа email. А как изменить уже существующий? Удалить и создать или есть специальная функция?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Свой action в личном кабинете
СообщениеДобавлено: 25 дек 2009, 21:31 
Не в сети

Зарегистрирован: 09 июл 2009, 11:31
Сообщения: 82
Откуда: Россия
Карма: 20
Вроде разобрался, действительно, сначала нужно удалить конкретное значение параметра из договора, потом задать новое, примерно вот так:

Код:
cpm.deleteParamForContract( "contract_parameter_type_3", cid );
cpm.setEmailParam( cid, pid, emailParam, false, 1 );


Пока не понял, как сделать так, чтобы отображаемое в личном кабинете значение изменялось соответственно - видимо генерируемый XML с параметрами договора как-то кэшируется, и измененное значение параметра появляется в ЛК только после перезапуска биллинга. Есть ли тут какое-нибудь решение?

И еще один вопрос - можно ли в action'е вызывать функции из библиотеки скриптов?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Свой action в личном кабинете
СообщениеДобавлено: 25 дек 2009, 23:19 
Не в сети
Разработчик

Зарегистрирован: 07 апр 2007, 23:51
Сообщения: 4493
Откуда: Уфа, Россия
Карма: 187
DDPaul писал(а):
Вроде разобрался, действительно, сначала нужно удалить конкретное значение параметра из договора, потом задать новое, примерно вот так:
Код:
cpm.deleteParamForContract( "contract_parameter_type_3", cid );
cpm.setEmailParam( cid, pid, emailParam, false, 1 );



Для обновления email достаточно вызвать:
Код:
cpm.setEmailParam( cid, pid, emailParam, false, 1 );


Если у вас в договоре более одного параметра типа email, код
Код:
cpm.deleteParamForContract( "contract_parameter_type_3", cid );

удалит все параметры


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Свой action в личном кабинете
СообщениеДобавлено: 28 дек 2009, 13:03 
Не в сети

Зарегистрирован: 09 июл 2009, 11:31
Сообщения: 82
Откуда: Россия
Карма: 20
При вызове cpm.setEmailParam( cid, pid, emailParam, false, 1 ) MySQL-сервер получает вот такую команду:

Код:
INSERT INTO contract_parameter_type_3 SET cid=12, pid=19, email='test@mail.ru;'


Наверное должен быть UPDATE вместо INSERT?

Версия сервера биллинга 4.6.641.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Свой action в личном кабинете
СообщениеДобавлено: 28 дек 2009, 18:54 
Не в сети
Разработчик

Зарегистрирован: 07 апр 2007, 23:51
Сообщения: 4493
Откуда: Уфа, Россия
Карма: 187
там несколько кривой код для того что бы UPDATE вызвался добавьте

Код:
emailParam.setEmailId( 1 );


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Свой action в личном кабинете
СообщениеДобавлено: 28 дек 2009, 19:23 
Не в сети

Зарегистрирован: 09 июл 2009, 11:31
Сообщения: 82
Откуда: Россия
Карма: 20
Да, так работает, спасибо.

Теперь нужно сделать так, чтобы введенное значение тут же отобразилось в личном кабинете. Чувствую, что копать надо в сторону обработки событий, но пока не получается.

Пытаюсь сделать так:
Код:
...
ContractParamChangedEvent cpce = new ContractParamChangedEvent( cid, pid, emailParam );


Потом вроде бы нужно запустить EventProcessor и воспользоваться его методом addEvent(), но вот с какими параметрами вызвать конструктор EventProcessor()?

Выдержка из API:
Код:
EventProcessor(DefaultServerSetup setup, boolean processMode, ExtraEventProcessor extraProccessor)


Конкретно ставит в тупик ExtraEventProcessor. Это, насколько я понял, интерфейс, который реализуется классом EventProcessor. Моих знаний в Java и API BGBilling не хватает, чтобы разрешить эту проблему курицы и яйца.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Свой action в личном кабинете
СообщениеДобавлено: 30 дек 2009, 13:00 
Не в сети
Аватара пользователя

Зарегистрирован: 30 май 2008, 15:51
Сообщения: 6055
Карма: 244
Вам это и не нужно разрешать, это просто дополнительный эвентпроцессор, да и не туда смотрите, не нужно на объявление его глядеть)

Код:
EventProcessor.getProcessor().addEvent( cpce );

_________________
I'm clever. I've got a computer.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Свой action в личном кабинете
СообщениеДобавлено: 30 дек 2009, 15:33 
Не в сети
Разработчик

Зарегистрирован: 07 апр 2007, 23:51
Сообщения: 4493
Откуда: Уфа, Россия
Карма: 187
я немного не понял где и что не меняется после изменения мыла. можно скриншотик?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Свой action в личном кабинете
СообщениеДобавлено: 30 дек 2009, 20:00 
Не в сети

Зарегистрирован: 09 июл 2009, 11:31
Сообщения: 82
Откуда: Россия
Карма: 20
Я сделал формочку для action'а как на скриншоте web1.png. Значение для поля Email подставляется следующим образом:

Код:
...
<xsl:variable name="email" select="/data/contract_data/parameters/parameter[@pid='19']/@value"/>
...
<tr>
   <th>Email:</th>
   <td><input type="text" name="email" value="{$email}" size="30" maxlength="30"/></td>
</tr>
...


В конфигурации биллинга, естественно, установлена опция web.add.contract=1.

В клиенте биллинга, соответственно, отображается то же значение.

Скриншот после изменения email'а - web2.png. Видно, что значение в переменной $email осталось то же самое.

Кусок кода action'а:

Код:
...
String email = request.getParameter( "email" );
if( email != null )
{
   pid = 19;
   
   // Get old value
   ContractEmailParamValue emailParam = cpm.getEmailParam( cid, pid );
   String oldEmail = emailParam.getEmail();

   if( !email.equals( oldEmail ))
   {
      // Set new value and throw event
      emailParam.setEmail( email );
      emailParam.setEmailId( 1 );
      cpm.setEmailParam( cid, pid, emailParam, false, 1 );
      event = new ContractParamChangedEvent( cid, pid, emailParam );
      EventProcessor.getProcessor().addEvent( event );
   }
}
...


В server.log event появляется:
Код:
12-30/16:28:57  INFO [http-8080-1] EventProcessor - Add event to queue Event bitel.billing.server.script.bean.event.ContractParamChangedEvent cid: 43; module: 0; type: 9


В клиенте биллинга отображается новое значение параметра (bg2.png).

Однако генерируемый биллингом XML для личного кабинета не меняется:
Код:
<parameters>
    ...
    <parameter pid="19" pt="3" sort="25" title="E-mail" value="test@mail.ru; "/>
    ...
</parameters>


Иногда, он может измениться, как нужно, но, как правило, остается неизменным, какие значения бы я ни вбивал. После перезапуска сервера биллинга в XML, попадает новое значение.

Кроме того, если несколько раз менять параметр через клиент биллинга, то возникает такая же проблема - в личном кабинете, в конце концов, "устаканивается" какое-нибудь значение и не меняется вплоть до перезапуска.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Свой action в личном кабинете
СообщениеДобавлено: 30 дек 2009, 20:24 
отличная затея. после отладки ждем подробное описание.


Вернуться к началу
  
 
 Заголовок сообщения: Re: Свой action в личном кабинете
СообщениеДобавлено: 30 дек 2009, 21:00 
Не в сети
Разработчик

Зарегистрирован: 07 апр 2007, 23:51
Сообщения: 4493
Откуда: Уфа, Россия
Карма: 187
добавьте в код акшена

Код:
request.getSession().removeAttribute( "contract_data" );


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Свой action в личном кабинете
СообщениеДобавлено: 13 янв 2010, 20:15 
Не в сети

Зарегистрирован: 09 июл 2009, 11:31
Сообщения: 82
Откуда: Россия
Карма: 20
Добрый день, с прошедшими праздниками :) Спасибо за советы, обновление параметра работает.

Теперь хочется прикрутить еще и валидацию параметра с помощью обработи события "Перед изменением параметра договора", как в Wiki.

Для тестирования повесил на обработку вот такой скрипт поведения:
Код:
import bitel.billing.server.contract.bean.*;

pid = event.getParamId();
value = event.getValue();
 
// Проверка значения параметра типа Email
if( value instanceof ContractEmailParamValue )
{
    value = value.getEmail();
    print( "pid=" + pid + "; value=" + value );
   
    if( value.length() > 10 )
    {
        event.setError( "Длина параметра больше 10" );
        return;
    }
}

Скрипт работает, при попытке ввести email длиннее 10 символов, клиент биллинга выдает предупреждение об ошибке.

Из action'а это событие вызываю с помощью класса ContractParamBeforeChangeEvent. Вот кусок кода:
Код:
// Set email parameter
ContractEmailParamValue emailParam = cpm.getEmailParam( cid, pid );
String paramValue = request.getParameter( "email" );
emailParam.setEmail( paramValue );
emailParam.setEmailId( 1 );
cpm.setEmailParam( cid, pid, emailParam, false, 1 );

// Throw "before change" event for validation
ContractParamBeforeChangeEvent eventBefore = new ContractParamBeforeChangeEvent( cid, pid, emailParam );
if( eventBefore != null )
{
    EventProcessor.getProcessor().addEvent( eventBefore );
    errorBefore = eventBefore.getError();

    // If validation passes then throw "parameter changed" event
    if( errorBefore == null )
    {
   event = new ContractParamChangedEvent( cid, pid, emailParam );
   EventProcessor.getProcessor().addEvent( event )
    }
}


Т.е. если обработчик события ContractParamBeforeChangeEvent не выдал ошибку, то сгенерировать событие ContractParamChangedEvent.

В итоге, при изменении параметра через Web-интерфейс, скрипт поведения по событию "Перед изменением параметра договора" запускается (лог без ошибок, значения pid и value выводятся), но возвращаемое методом getError() значение всегда равно null, независимо от длины email'а.

Что можете посоветовать?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Свой action в личном кабинете
СообщениеДобавлено: 14 янв 2010, 14:27 
Не в сети
Разработчик
Аватара пользователя

Зарегистрирован: 19 дек 2006, 21:04
Сообщения: 5970
Карма: 256
Вызывайте не addEvent, а processEvent


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Свой action в личном кабинете
СообщениеДобавлено: 14 янв 2010, 15:57 
ждем подробного описания


Вернуться к началу
  
 
 Заголовок сообщения: Re: Свой action в личном кабинете
СообщениеДобавлено: 25 янв 2010, 16:22 
Не в сети

Зарегистрирован: 09 июл 2009, 11:31
Сообщения: 82
Откуда: Россия
Карма: 20
Скоро выложу :) Пока еще один вопрос возник - можно ли класс или хотя бы функцию, описанные в "Библиотеке скриптов" вызывать из action'а? Т.е. хочется что-то типа директивы includeBGBS для скриптов поведения.

Вроде понимаю, что включить "Библиотеку скриптов" можно таким образом
Код:
import ru.bitel.bgbilling.kernel.script.common.bean.ScriptLibrary.*;

А как оттуда вытащить функции?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Свой action в личном кабинете
СообщениеДобавлено: 28 янв 2010, 13:53 
Не в сети

Зарегистрирован: 09 июл 2009, 11:31
Сообщения: 82
Откуда: Россия
Карма: 20
Распишу свой вопрос чуть подробнее.

Для связки переменной из POST-запроса и кодом параметра в биллинге я использую HashMap и определяю дополнительный класс:

Код:
public class AdditionalParams {
    public static HashMap<String,Integer> pids()
    {
   HashMap<String,Integer> hash = new HashMap<String,Integer>();
   hash.put( "email",   19 );
   hash.put( "login",   33 );
   return hash;
    }
    ...
}


В action'е, соответственно:

Код:
import bitel.billing.server.contract.AdditionalParams;
HashMap<String,Integer> pids = AdditionalParams.pids()
String  paramKey = "email";
String  paramValue = request.getParameter( paramKey );
Integer paramID = pids.get( paramKey );


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

Так вот мне не очень нравится то, что при добавлении нового параметра (который можно изменять из личного кабинета) нужно изменять класс AdditionalParams, перекомпилировать его, и, как следствие, перезапускать биллинг.

Если же есть возможность этот класс определить в библиотеке скриптов, и вызывать его методы из action'а, то перезапуск не потребуется - схема получится более удобной и логичной.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Свой action в личном кабинете
СообщениеДобавлено: 03 фев 2010, 16:32 
Не в сети

Зарегистрирован: 09 июл 2009, 11:31
Сообщения: 82
Откуда: Россия
Карма: 20
Уважаемые разработчики, вопрос все еще актуален.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Свой action в личном кабинете
СообщениеДобавлено: 03 фев 2010, 18:00 
Не в сети
Разработчик
Аватара пользователя

Зарегистрирован: 19 дек 2006, 21:04
Сообщения: 5970
Карма: 256
Такие параметры мы обычно храним в конфиге сервера, а получаем
Код:
setup.get( key, def )
setup.getInt( key, def )

Главное чтобы имя вашего параметра не пересеклось вдруг с нашим.


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 81 ]  На страницу 1, 2, 3  След.

Часовой пояс: UTC + 5 часов [ Летнее время ]


Кто сейчас на конференции

Сейчас этот форум просматривают: Bing [Bot] и гости: 1


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  
cron
POWERED_BY
Русская поддержка phpBB
[ Time : 0.116s | 69 Queries | GZIP : On ]