Универсальные подбор и обработка объектов с установкой реквизитов табличных частей. Версия 1.9.25 (управляемое и обычное приложение) 8.2/8.3




Принцип обмена данными из 1С с сайтом (на MySQL) и выдачи (публикации) этих данных по запросу.
PHP-Скрипт автоматической загрузки данных из файла данных в формате CSV в базу данных сайта работающего на WordPress.

В продолжение моей темы: 1С:Альфа-Авто Автосалон Автосервис: обмен с сайтом.
С помощью данного скрипта можно загружать в автоматическом режиме, по расписанию, данные сервисных книжек (ремонтов авто) из 1С:Альфа-Авто Автосалон Автосервис.
Также можно загружать данные в ручном режиме: для этого делается скрытая страница, где размещается специальная кнопка.
Комментарии размещенные внутри скрипта разъяснят логику и порядок действия.
Комментарии с "/////    echo" использовались для отладки.
Дополнительно создана таблица для журналирования результатов загрузки данных.
Скрипт включает в себя защиту от SQL инъекций (думаю безопасность соблюдена в полной мере).
В кратце:
1. Пишется скрипт, который запускает этот.
2. Создается регламентное задание в WordPress, по которому запускается скрипт из п.1. 
3. Этот скрипт осуществляет проверку на существование файла обмена в папке.
4. Если данные не новые, загрузка не производится.
5. Если данные новые, очищается таблица сервисных книжек.
6. Загружаются новые данные.

Собственно сам скрипт:

<?php // Полная загрузка сервисных книжек, создан 2024-01-05 12:44:55

global $wpdb2;
global $failure;
global $file_hist;

/////  echo '<H2><b>Старт загрузки</b></H2><br>';

$failure=FALSE;
//подключаемся к базе
$wpdb2 = include_once 'connection.php'; ; // подключаемся к MySQL
// если не удалось подключиться, и нужно оборвать PHP с сообщением об этой ошибке
if (!empty($wpdb2->error))
{
/////   echo '<H2><b>Ошибка подключения к БД, завершение.</b></H2><br>';
$failure=TRUE;
wp_die( $wpdb2->error );
}

$m_size_file=0;
$m_mtime_file=0;
$m_comment='';
/////проверка существования файлов выгрузки из 1С
////файл выгрузки сервисных книжек
$file_hist = ABSPATH.'/_1c_alfa_exchange/AA_hist.csv';
if (!file_exists($file_hist))
{
/////   echo '<H2><b>Файл обмена с сервисными книжками не существует.</b></H2><br>';
$m_comment='Файл обмена с сервисными книжками не существует';
$failure=TRUE;
}

/////инициируем таблицу лога
/////если не существует файла то возврат и ничего не делаем
if ($failure){
///включает защиту от SQL инъекций и данные можно передавать как есть, например: $_GET['foo']
/////   echo '<H2><b>Попытка вставить запись в лог таблицу</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>$m_mtime_file,'last_size_upload'=>$m_size_file,'comment'=>$m_comment));
wp_die();
/////    echo '<H2><b>Возврат в начало.</b></H2><br>';
return $failure;
}
/////проверка лога загрузки, что бы не загружать тоже самое
$masiv_data_file=stat($file_hist);   ////передаем в массив свойство файла
$m_size_file=$masiv_data_file[7];    ////получаем размер файла
$m_mtime_file=$masiv_data_file[9];   ////получаем дату модификации файла
////создаем запрос на получение последней удачной загрузки
////выбираем по штампу времени создания (редактирования) файла загрузки AA_hist.csv, $m_mtime_file

/////   echo '<H2><b>Размер файла: '.$m_size_file.'</b></H2><br>';
/////   echo '<H2><b>Штамп времени файла: '.$m_mtime_file.'</b></H2><br>';
/////   echo '<H2><b>Формирование запроса на выборку из лога</b></H2><br>';
////препарируем запрос
$text_zaprosa=$wpdb2->prepare("SELECT * FROM `vin_logs` WHERE `last_mtime_upload` = %s", $m_mtime_file);
$results=$wpdb2->get_results($text_zaprosa);

if ($results)
{   foreach ( $results as $r)
{
////если штамп времени и размер файла совпадают, возврат
if (($r->last_mtime_upload==$m_mtime_file) && ($r->last_size_upload==$m_size_file))
{////echo '<H2><b>Возврат в начало, т.к. найдена запись в логе.</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>$m_mtime_file,'last_size_upload'=>$m_size_file,'comment'=>'Загрузка отменена, новых данных нет, т.к. найдена запись в логе.'));
wp_die();
return $failure;
}
}
}
////если данные новые, пишем в лог запись о начале загрузки
/////echo '<H2><b>Попытка вставить запись о начале загрузки в лог таблицу</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>0, 'last_size_upload'=>$m_size_file, 'comment'=>'Начало загрузки'));

////очищаем таблицу
$clear_tbl_zap=$wpdb2->prepare("TRUNCATE TABLE %s", 'vin_history');
$clear_tbl_zap_repl=str_replace("'","`",$clear_tbl_zap);
$results=$wpdb2->query($clear_tbl_zap_repl);
/////   echo '<H2><b>Очистка таблицы сервисных книжек</b></H2><br>';
if (empty($results))
{
/////   echo '<H2><b>Ошибка очистки таблицы книжек, завершение.</b></H2><br>';
//// если очистка не удалась, возврат
$failure=TRUE;
wp_die();
return $failure;
}

////загружаем данные
$table='vin_history';         // Имя таблицы для импорта
//$file_hist Имя CSV файла, откуда берется информация     // (путь от корня web-сервера)
$delim=';';          // Разделитель полей в CSV файле
$enclosed='"';      // Кавычки для содержимого полей
$escaped='\

99 Comments

  1. tormozit

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

    Reply
  2. Поручик

    (1) Да? Что не так? Эта фича не главная, потребовалась обработка дополнительных объектов, не предусмотренных в исходных программах, остальное от нефиг делать.

    Reply
  3. Поручик

    Немного пофиксил формирование отбора для поиска объектов и добавил использование настроек в доступные обработки.

    Reply
  4. Поручик

    Добавлен поиск и отбор объектов по количеству строк в табличных частях.

    Reply
  5. alexandr1972_1

    Отличное развитие обработки. Память о Душелове останется надолго.

    Reply
  6. wowkai

    спасибо за обработку!

    Reply
  7. Поручик

    Кто скачал, возьмите пофиксенную обрабтку. В обработке для обычного приложения обнаружена ошибка, вернее там был черновой вариант.

    Reply
  8. Поручик

    (12) Скорее всего перенумерация сделана так, как это было нужно автору оригинала. В этом деле на всех не угодишь и цели такой нет.

    Reply
  9. Поручик

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

    Reply
  10. Поручик

    Добавлена обработка планов обмена. Обработку теперь можно назвать по-настоящему универсальной.

    Reply
  11. Поручик

    Несколько небольших фиксов в управляемой и обычной форме.

    Reply
  12. Поручик

    Небольшой рефокторинг кода в управляемой форме.

    Reply
  13. Boroda

    Так, моё мнение: с (14) по (17) лучше было бы не в комментариях написать, а в описание обработки добавить (и нагляднее было бы, и изучать все комментарии для ознакомления с модификациями не требовалось бы, хотя, и это бывает подчас полезно).

    «Форма выбора объекта метаданных импортирована из конфигурации Управление торговлей 11 с небольшими исправлениями для этой обработки.» — это для большего удобства, что ли? На работе, скажем, в ЗУП, это никак не скажется? Всё сработает ОК?

    Reply
  14. Поручик

    (18) В ЗуП откроется вариант для обычного приложения или почти типовая обработка.

    Reply
  15. Поручик

    Исправлена ошибка в перетаскивании доступных обработок.

    Reply
  16. Поручик

    и ошибка в сохранении списка обработок

    Reply
  17. vprus

    Спасибо за обработку. Отличная. Очень удобная, в отличие от стандартной «Групповой обработки справочников и документов». Только при добавлении обработки в базу 1С в «Дополнительные внешние обработки» — НЕ СРАБАТЫВАЕТ ПРИ ЗАПУСКЕ, хотя старые обработки запускаются нормально. Замечено на УТ 10.3.

    Reply
  18. Поручик

    (22) Она создана в основном для управляемого приложения. Вариант для обычного или толстого клиента добавлен для универсальности.

    Reply
  19. vprus

    Еще один недостаток: обработка не сохраняет настройки изменения реквизитов табличной части документов. При открытии сохраненной настройки поле с табличными частями пустое. Проверено на УТ 10.3. Проверить в управляемом приложении нет возможности (может в тонком клиенте и работает).

    Reply
  20. Поручик

    (24) Предыдущий пост внимательно читайте. Вариант для обычного приложения меня не интересует.

    Reply
  21. Поручик

    Добавлено автоматическое добавление реквизитов объекта для отбора при открытии настройки отбора.

    Reply
  22. DoctorRoza

    Хорошая вещь, нужно по-тестить!

    Reply
  23. KroVladS

    Свойства и категории есть возможность менять?

    Reply
  24. LivingStar

    скачал обработку, при открытии она выдала вот такие ошибки:

    |

    {Форма.ПодборИОбработка.Форма(313,29)}: Процедура или функция с указанным именем не определена (ПолучитьПолноеИмяФормы)

    Обработка = ПолучитьФорму(<<?>>ПолучитьПолноеИмяФормы(ИмяФормыОбработки), СтруктураПараметров, ЭтаФорма);

    {Форма.ПодборИОбработка.Форма(427,30)}: Процедура или функция с указанным именем не определена (ПолучитьПолноеИмяФормы)

    ФормаОтбора = ПолучитьФорму(<<?>>ПолучитьПолноеИмяФормы(«ФормаОтбора»), СтруктураПараметров, ЭтаФорма);

    {Форма.ПодборИОбработка.Форма(491,29)}: Процедура или функция с указанным именем не определена (ПолучитьПолноеИмяФормы)

    Обработка = ПолучитьФорму(<<?>>ПолучитьПолноеИмяФормы(ТекущаяСтрока.ИмяФормы), СтруктураПараметров, ЭтаФорма);

    {Форма.ПодборИОбработка.Форма(502,29)}: Процедура или функция с указанным именем не определена (ПолучитьПолноеИмяФормы)

    Обработка = ПолучитьФорму(<<?>>ПолучитьПолноеИмяФормы(Родитель.ИмяФормы), СтруктураПараметров, ЭтаФорма);

    {Форма.ПодборИОбработка.Форма(539,29)}: Процедура или функция с указанным именем не определена (ПолучитьПолноеИмяФормы)

    Отказ = НЕ ПолучитьФорму(<<?>>ПолучитьПолноеИмяФормы(Элемент.ТекущиеДанные.ИмяФормы)).мИспользоватьНастройки;

    {Форма.ПодборИОбработка.Форма(554,23)}: Процедура или функция с указанным именем не определена (ПолучитьПолноеИмяФормы)

    Если ПолучитьФорму(<<?>>ПолучитьПолноеИмяФормы(Элемент.ТекущиеДанные.ПолучитьРодителя().ИмяФормы)).мИспользоватьНастройки Тогда

    {Форма.ПодборИОбработка.Форма(702,46)}: Процедура или функция с указанным именем не определена (ПолучитьПолноеИмяФормы)

    ТипыОбрабатываемыхОбъектов = ПолучитьФорму(<<?>>ПолучитьПолноеИмяФормы(ИмяОбработки)).мТипыОбрабатываемыхОбъектов;

    {Форма.ПодборИОбработка.Форма(504,2)}: Процедура или функция с указанным именем не определена (ИзменитьПризнакОтключенияКонтроляНастроек)

    <<?>>ИзменитьПризнакОтключенияКонтроляНастроек(объект.РежимКорректировки);

    {Форма.ПодборИОбработка.Форма(506,2)}: Процедура или функция с указанным именем не определена (ИзменитьПризнакОтключенияКонтроляНастроек)

    <<?>>ИзменитьПризнакОтключенияКонтроляНастроек(ложь);

    {Форма.ПодборИОбработка.Форма(746,2)}: Процедура или функция с указанным именем не определена (ИзменитьПризнакОтключенияКонтроляНастроек)

    <<?>>ИзменитьПризнакОтключенияКонтроляНастроек(ложь);

    {Форма.ПодборИОбработка.Форма(679,2)}: Процедура или функция с указанным именем не определена (ВыбратьОбработки)

    <<?>>ВыбратьОбработки(Истина);

    {Форма.ПодборИОбработка.Форма(684,2)}: Процедура или функция с указанным именем не определена (ВыбратьОбработки)

    <<?>>ВыбратьОбработки(Ложь);

    |

    1с SQL Server 2008 1С:Предприятие 8.2 (8.2.15.301)

    Reply
  25. Поручик

    (29) Понятия не имею, как у вас умудрилось глюкануть. Это особенно удивило

    ИзменитьПризнакОтключенияКонтроляНастроек(объект.РежимКорректировки);

    Такой строки в моём вариант близко нет.

    Reply
  26. Поручик

    (28) Меняйте, кто запрещает. Этот механизм конфигурационно-зависимый, в разных конфах реализован по разному.

    Reply
  27. Sairys

    сейчас скачаешь попробуем, а то уже надоело обрабатывать всё в неуправляемом приложении

    Reply
  28. Sairys

    Не ищет документы по номеру

    Reply
  29. Поручик

    (33) Не свисти, ищет.

    Reply
  30. Sairys

    всё вроде в норме

    Reply
  31. dem_mad

    спасибо за обработку! очень удобная

    Reply
  32. powerpc

    Отличная обработка! Если добавить галку с возможностью записи «ОбменДанными.Загрузка» (где-то была на Инфостарте), то вообще будет песня. И печати не хватает всегда. Можно отсюда тоже плюшки перетаскать: http://infostart.ru/public/18576/

    Reply
  33. Поручик

    (37) Лень посмотреть, что находится в «Настройках»? Печать появится, когда мне самому потребуется.

    Reply
  34. o956op

    Отличная обработка. Спасибо!

    Reply
  35. SamJack

    Очень пригодилась. Полезная вещь, плюсую

    Reply
  36. powerpc

    (38) Глаза разул. А про такие же настройки в обычной форме и печать забудь, уже сделал.

    Reply
  37. Поручик

    Обновление

    Добавлено сохранение настроек реквизитов табличной части в форме Установка реквизитов, пофиксены некоторые мелкие глюки.

    Reply
  38. cerg110

    Спасибо за хорошую обработку.

    Reply
  39. Поручик

    (47) Правда, что-ль? А ты файл скачал?

    Reply
  40. Поручик

    Обновление

    Добавлена выборка и сортировка объектов с помощью схемы компоновки данных, позволяющая производить отбор по дополнительным характеристикам объектов.

    Reply
  41. Поручик

    Немного подумал и решил добавить функционала.

    [+] Выбор отображаемых полей при поиске объектов.

    [+] Открытие формы списка текущего объекта поиска.

    [+] Сохранение/восстановление настроек обработок.

    Reply
  42. Kaniman

    (54) спасибо огромное! полезные добавления. Вопрос такое есть, извините, мало опыта с обработкой табличных частей:

    Нужно разбить операцию (бухгалтерская- ручные проводки) по признакам КФО=1 или 2 (это у бюджетников).

    Т.е. скопировать операцию дважды и в одной остваить по 1, а в другой по 2. Можно так обработать?

    Reply
  43. Поручик

    (55) Произвольный алгоритм вам поможет. Пишите код так, как будто работаете в конфигураторе.

    Reply
  44. Поручик

    Добавлено сохранение настроек изменения реквизитов табличной части и открытия формы списка объекта поиска в варианте для обычного приложения.

    Reply
  45. electronik

    Интересно интересно как появятся деньги обязательно скачаю как раз то что я ищу.Автору огромное спасибо

    Reply
  46. Поручик
  47. Поручик

    Пофиксено.

    Не выбирался тип значения для реквизитов, содержащих несколько типов данных.

    Reply
  48. Поручик

    Добавлено

    Поиск и отбор объектов возможен по значениям агрегатных функций для числовых реквизитов табличных частей: сумма, максимум, минимум, среднее.

    Reply
  49. Mirage78

    Reply
  50. Поручик

    (62) Не свисти, работает.

    >>> СМ улетают за скачивание «обновлённой» — это у дятлов недостаточно сообразительных юзеров. Умный воспользовался бы гуглем и нашёл бы по названию эту и другие мои программы на моём сайте.

    Reply
  51. Поручик

    Просто небольшой рефакторинг кода.

    Reply
  52. Поручик

    Обновление

    Для варианта управляемого приложения добавлено сохранение и восстановление истории выбора объектов и настроек отбора.

    Для варианта обычного приложения добавлена возможность отбора по значениям агрегатных функций для числовых реквизитов табличных частей: сумма, максимум, минимум, среднее.

    Reply
  53. 1977

    При Выборе справочника номенклатуры выкидывает ошибку {Форма.ПодборИОбработка.Форма(776)}: Значение не является значением объектного типа (ПолноеИмя)

    Если ПолноеИмяОбъекта = ОбъектПоиска.ПолноеИмя Тогда

    Reply
  54. Поручик

    (70) Косяк, наверное. Приеду с отпуска на югах, исправлю.

    Reply
  55. Поручик

    (70) Исправил. Заодно пофиксил другую, незамеченную никем ошибку, связанную с иерархическими справочниками.

    Reply
  56. 1977

    Как наберу рейтинг, скачаю по тестирую!!!

    Reply
  57. Поручик

    (73) Мани, что-ли? Могу продать. 4 рубля штука.

    Reply
  58. 1977

    Могу купить, но лучшее на Мыло сбросить.

    Reply
  59. Поручик

    (75) На мыло сбросить будет стоить 200 рублей, если ума не хватает найти в гугле.

    Reply
  60. 1977

    Будем искать.

    Reply
  61. Поручик

    Добавлено сохранение истории выбора строки поиска.

    Reply
  62. Поручик

    (79) В описалово вкурись. Если бы была, то написал. Воспользуйся другой обработкой, которая входит в состав многих конфигураций. Так и называется: Групповая обработка справочников и документов.

    (80) сообщения автору публикации приходят автоматом. Повторять не требуется.

    Reply
  63. Поручик

    Обработка обновлена

    Добавлена возможность группового снятия пометки на удаление объектов.

    Reply
  64. knowikDen

    Спасибо большущее за обработку

    Reply
  65. Поручик

    Небольшой фикс, не влияющий на функциональность.

    Reply
  66. Поручик

    (85) Включи в настройках обрабатывать в транзакции и будет счастье и обработка на сервере. Индикатор останется, это Душелов ещё делал.

    Reply
  67. Fuego

    Спасибо авторам! Сэкономил массу времени!

    Reply
  68. DoctorRoza

    (86) Решил воспользоваться Вашей обработкой, УТ 11.0.7.21, управляемое приложение. Хочу отобрать документы РТУ по дате документа за период. В Настройке отбора, Вид сравнения не нашел метода «Между» или «Интервал», в поле Значение есть только «начало след./пред.» и т.п. Произвольный запрос — это решение, но нужно юзерам что по — проще. Может что не так делаю или как отобрать доки за период?

    Reply
  69. DoctorRoza

    (86) и еще .. получаю документы в списке, как они упорядочиваются? У меня список начинается доками с 15.08, вроде идет упорядочивание по дате, но в конце появляются доки с 1.08 и опять все по дате. Спасибо!

    Reply
  70. Поручик

    (88)(89) А я что поделаю, это СКД. Пользуйся настройкой порядка и прочими мощностями инструмента.

    Reply
  71. DoctorRoza

    (90) и вот еще, Вы можете доработать установку/снятие флажка объектов для обработки, при групповом выделении строк списке? Мыслю, это даст больше места для маневра! 🙂

    Reply
  72. Поручик

    (91) Если устроит установка/снятие флажков в выделенных строках при нажатии кнопки, то не вопрос. Кидаете деньги мне на телефон или яндекс кошелёк и сегодня сделаю.

    Reply
  73. Поручик

    (91) За деньги уже не надо, так нормально?

    Reply
  74. Поручик

    (91) Ну так надо доработать или нет?

    Reply
  75. Поручик

    Добавлен функционал.

    Для табличной части предусмотрены режимы обработки:

    Замена значений — заменяются значения отмеченных реквизитов в существующих строках.

    Добавление строки — поиск строк по значениям отмеченных реквизитов и добавление новой строки в случае отсутствия строк по заданному отбору.

    Удаление строк по выбранным полям — поиск и удаление строк по заданному отбору.

    Reply
  76. makas

    Спасибо!

    Reply
  77. Поручик

    (96) Плюс лень было поставить?

    Reply
  78. makas

    Всегда пожалуйста!

    Reply
  79. makas

    (97)

    завтра зайду еще разок. В гости:)

    Reply
  80. eugen91

    Будет ли работать на Ут 11 для Беларуси?

    Reply
  81. Поручик

    (100) У вас глаза косые или читать не умеем? Описание перечитайте, только вдумчиво.

    Reply
  82. lordguard

    Скачал, выбрал кадровое перемещение, при замене реквизита выдало. Поле объекта не обнаружено. В файле есть рисунок скрина. Очень нужна эта обработка. Если быстро разберетесь с проблемой , заплачу.

    Reply
  83. Поручик

    (102) Ставьте плюс, сейчас залью

    Reply
  84. Поручик

    Добавлена возможность указать количество объектов при обработке в транзакции .

    Выяснилось, что обработка большого количества объектов (over 2000) валит процесс наповал.

    Reply
  85. Поручик

    Немного подумал и решил добавить возможность выбора режима записи документа при установке реквизитов или в произвольном алгоритме.

    Reply
  86. Поручик

    Давно хотел добавить вызов доступных обработок в контекстное меню таблицы найденных объектов. Сегодня эту мечту осуществил. Так что жрите, бесплатно пользуйтесь на здоровье.

    Reply
  87. knowikDen

    Спасибо что не оставляете обработку 🙂 Оченно полезная вещь

    Reply
  88. eugen91

    Не очень получилось пользоваться этой обрабоктой. Как-то тяжковата она

    Reply
  89. Поручик

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

    Reply
  90. AlexO

    (109)

    аа.. зачем? вроде уже от 1С есть?

    Reply
  91. Поручик

    (110) Вообще я на твои вопросы не отвечаю, но на этот раз, так уж и быть, окажу честь. Обработка от 1С имеет урезанный функционал, сравни матчасть.

    Reply
  92. AlexO

    (111)

    спасибо, что оказал честь 🙂

    Reply
  93. adhocprog

    (111) Сергей, почему Вы внесли меня в черный список? Как мне кажется, я повода не давал.

    Reply
  94. alekseies

    {Форма.УстановкаРеквизитов.Форма(53)}: Поле объекта не обнаружено (Материалы)

    СтрокаТаблицы[ЭлементыФормы.СписокТабличнаяЧасть.Значение] = Реквизит.Значение;

    попробовал «Установка реквизита» — табличная часть — такая ошибка ………….

    Reply
  95. Поручик

    (201) Бухгалтерия предприятия 2.0? Угадал.

    Исправил.

    Reply
  96. lefthander

    Хм… отличная обработка, но вот почему то не хочет делать то что нужно мне.

    Сделал запрос, нашел объекты, на странице Обработки открываю Установка (замена) реквизитов, устанавливаю реквизит который надо поменять и получаю ошибку Значение не является значением объектного типа.

    {ВнешняяОбработка.УниверсальныеПодборИОбработкаОбъектовУФ.Форма.УстановкаРеквизитов.Форма(90)}: Значение не является значением объектного типа (ПолучитьОбъект)

    Объект = Ссылка.ПолучитьОбъект();

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

    Подскажите куда покопать?

    ЗЫ обработку сегодня скачал

    И в списке отобранных объектов пустая колонка Объект.

    Reply
  97. lefthander

    о, и этот улетел

    Reply
  98. Поручик

    (607) Если отобрали запросом, в запросе должна быть колонка с именем Объект и тип ссылка на ваш объект.

    Reply
  99. lefthander

    (609)Понял, меня терзали смутные сомнения на этот счет…. 😉 Спасибо. Завтра попробую..

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *