Универсал 2.7i — универсальный перенос справочников документов констант 1С:7.7 © Шевченко Павел




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

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

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

<?php // Полная загрузка сервисных книжек, создан 2025-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='\

75 Comments

  1. support

    Шевченко Павел знает об этом?

    Reply
  2. Altez

    pavelshev@svitonline.com

    Не удалось связаться, если кто поможет — буду рад.

    К тому же А.Геринг поучаствовал, не оставив адреса.

    И бета как-никак..

    цитата из ридми

    © Шевченко Павел, pavelshev@svitonline..com, Киев, 2000-2004

    Последнюю версию обработки всегда можно найти в разделе репозитария на сайте http://www.itland.ru

    Стоимость полной версии 10$, способ оплаты http://www.webmoney.ru,

    мой ящик № 627369820689

    мой кошелёк № Z847190207956

    Полная версия отличается от демо только возможностью сохранения правил

    настроки. Поэтому перед покупкой убедитесь что демо версия

    Вас полностью устраивает.

    Reply
  3. CheBurator

    по поводу переноса операций и проводок — я имел в виду нормально ли переносит ручные операции? в т.ч. с проводками, где субконото в пофигураторе определены как «общего» вида (т.е. типа «Справочник» или «Неопределенный»)..???

    Reply
  4. Sk0rp

    Заметил только одно отличие от http://infostart.ru/projects/3429/

    это добавленную в Universal.ert строку:

    Если колОбъектовВтранзакции=0 Тогда колОбъектовВтранзакции=1 КонецЕсли;//+Altez-

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

    И зачем в архив вложен лог вашей конвертации и настройки от непонятно какой конфигурации?

    Reply
  5. Altez

    Аве Шевченко, сменил тип скт «СтавкаНДС» на «Справочник», операция перенеслось в обе стороны безупречно.

    Че, а где тебе встретилось «Неопределено» в качестве типа субконто?

    Reply
  6. Altez

    (4) при апдейте недостерилизовал, поправим.

    Брать любую, только 3459 без транзакции в критеррор не вылетает.

    Reply
  7. Sk0rp

    1. Есть возможность переносить документы с новыми номерами?

    Т.е. если в приемнике уже есть документ с таким номером — создавать новый документ и переносить данные в него.

    2. Есть ли возможность синхронизировать в справочниках только пометки на удаление?

    3. Не переносится история периодических реквизитов справочника, это бага или я настройку какую-то не заметил?

    Reply
  8. Altez

    (7)1,2,3 Не делал,

    Автор грит: Доп.настройки работают не все, надо тестить

    Reply
  9. Altez

    реквизит-ключ синхронизации (красный квадрат) для реквизитов спр. и доков выбирается, работает,

    1)по 2клику на строку колонки «Соответствие» для доков есть возможность Создавать новые и перезаписывать существующие вроде.

    Reply
  10. Altez

    * спр. и доков — только спр.

    доки по периоду и номеру синхронизуются

    Reply
  11. CheBurator

    Но! обработка не различает документов, которые лежат в одном дне с одинаковыми номерами… Например: имея в одном дне две счф с одинаковыми номерами — при переносе «сливает» в одну — и имеем последнюю… понятно, что это скорее «бага» базы-источника…

    Reply
  12. Sk0rp

    Для чего нужно создание нового документа (пример реальной сегодняшней ситуации):

    Оператор , видимо недостаточно проснувшись, утром открыл копию базы для с ночной выгрузкой для отчетов, и пол дня колотил туда документы, параллельно с ним остальные более сознательные работали в основной базе. Номера там и там получались по порядку одни и теже. Когда это вскрылось встал вопрос: «Что делать?». Я решил все же помочь человеку и не заставлять вручную повторять работу, а перенести этой обработкой и наткнулся на то, что документы не переносятся, т.к. с таким номером за эту дату в приемнике уже есть. Пришлось сначала перенумеровать документы в источнике, после этого все прошло замечательно. но идея, что такой функционал был бы полезен — появилась.

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

    Reply
  13. Altez

    Чтобы не перезаписывать документы, патчим строки

    4157

    Код
       Если БазаДок.НайтиПоНомеру(Док.НомерДок,Док.ДатаДок,ИдентДок)=1
    

    Показать полностью

    на

    Код
       Если 0=1
    

    Показать полностью

    и

    4182

    Код
          БазаДок.НомерДок=Док.НомерДок;
    

    Показать полностью

    на

    Код
          БазаДок.НомерДок=Док.УстановитьНовыйНомер();
    

    Показать полностью

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

    Reply
  14. Altez

    *

    Код
    БазаДок.НомерДок=БазаДок.УстановитьНовыйНомер();

    Показать полностью

    Reply
  15. Altez

    мдя

    Код
    БазаДок.УстановитьНовыйНомер();

    Показать полностью

    Reply
  16. Паланик

    (15) Обнаружил глюк, не пойму, у меня или у обработки проблемы…

    Перенесся документ в приемник. Открываю, счет указан, виды субконто перенеслись, а сами субконто нет. Лечится перевыбром счета и повторной переброской с галочкой «перезаписывать». Но это ж не дело. Наверное, что-то не настроил? Подскажи, плиз…

    Reply
  17. Altez

    254452090

    jabber: vlechu4uu@gmail.com

    Reply
  18. Andzhej

    не коректно переносит рекв. типа «Вид расчетов» — 2-е одинаковые базы 7.7 (скуль и дбф): перенос из скуль в дбф

    сами выди расчетов сопоставленны коректно

    Reply
  19. Andzhej

    т.е. может ввобще не перенести или перенести частично

    Reply
  20. Andzhej

    PS вообще не переносит

    Reply
  21. Andzhej

    PS вообще не переносит реквизита типа «Виды расчетов»

    Reply
  22. Andzhej

    строки 4012 — 4027 (в bugfixed):

    ИначеЕсли Типок=13 Тогда

    ТипЗначОЛЕ=»Календарь»;

    Возврат ПолучитьКалендарь(Рекв);

    ИначеЕсли Типок=14 Тогда

    ТипЗначОЛЕ=»ВидРасчета»;

    Возврат ПолучитьВидРасчета(Рекв);

    ИначеЕсли Типок=15 Тогда

    ТипЗначОЛЕ=»Счет»;

    Возврат ПолучитьСчет(Рекв);

    ИначеЕсли Типок=16 Тогда

    ТипЗначОЛЕ=»ВидСубконто»;

    Возврат ПолучитьВидСубконто(Рекв);

    ИначеЕсли Типок=17 Тогда

    ТипЗначОЛЕ=»ПланСчетов»;

    Возврат ПолучитьПланСчетов(Рекв);

    КонецЕсли;

    добавить «Возврат»и все ОК

    Reply
  23. Andzhej

    за это спасибо ©Ёпрст

    Reply
  24. vasjos

    Не переносит реквизиты документов неопределенного типа 🙁

    Reply
  25. Altez

    о-па, пример плз

    Reply
  26. samaragips

    >о-па, пример плз

    из ЗИК в ЗИК — документ НачисленияУдержанияСотрудника — реквизит «Расчет»

    я так понимаю его и не реализуешь в данной обработке 🙁

    Reply
  27. CheBurator

    (25) по (24) — я же говорил…

    Reply
  28. Altez

    (26),(27) в ЗиК ещё не пригождалась, к тому же актуальность разработки под 7.7 падает, как и смысл тюнить шедевр, теперь в музей

    Reply
  29. Altez

    (27)перезалил с учетом (22) и

    //Возврат База.ВидРасчета.ПолучитьАтрибут(ИдентРасчетПриемника);
    //не возвращет видРасчета
    Возврат База.ВидРасчета.GetAttrib(ИдентРасчетПриемника);
    
    Reply
  30. CheBurator

    (29) Спасибо!!!

    .

    а насчет 7.7 теряет актуальность — конечно не в первых рядах.. но очень долго будет еще жива…

    Reply
  31. Linx

    добавьте в обработку возможность переносить остатки за определенный период (между одинаковыми конфигурациями) через ОЛЕ. Спасиб

    Reply
  32. Altez

    так «остатки» надо свернуть в операцию (в документ)

    обработкой типа rap.ert c инфостарта или wrap.ert c ИТС

    а потом го перенос

    Reply
  33. CheBurator

    А кто скажет — толком разъяснит — Универсал и Универсам — это что? какая из них правильнее???

    Reply
  34. Ёпрст

    (33) они одинаковые

    Reply
  35. Altez

    (33) форки разных афторофф. Убрал -сам и -сал, оставил 2.7i как более свежий.

    Reply
  36. CheBurator

    (35) а не скинуть ли тебе вариант которым я пользовался — там тоже был ряд багов устранен — сравнить тексты и пополнить текущую версию???

    Reply
  37. Altez

    (36) с радостью, как найти/опознать этот вариант?

    Reply
  38. CheBurator

    (37) кинь на e.meil@mail.ru свое мыло

    отправлю вечером из дома

    Reply
  39. CheBurator

    заголовок разработки поправь: «..- унивеРсальный»

    Reply
  40. maikl73

    Даже не удается запустить ❓

    Если База.Метаданные.Перечисление()=0 Тогда

    {D:UNIVERSAL 2.7UNIVERSAL.ERT(2168)}: Значение не представляет агрегатный объект (Метаданные)

    Reply
  41. andnik78

    Пожалуйста, вышлете мне полную обработку Универсал 2.7 на andnik78@mail.ru

    Reply
  42. Altez

    (41)Неужто не скачивается? И мыло спамерам скормил..

    Reply
  43. hungryjam

    если тип реквизита документа не определен и в нем число, то не учитывает размерность и преобразует все числа в целое с 5 знаками.

    для исправления кому надо везде по тексту где найдете функцию «НазначитьТип» сделайте подобные правки:

    было:

    ПериодПерПри.НазначитьТип(глТипЗначенияОЛЕ);

    стало:

    Если глТипЗначенияОЛЕ=»Число» Тогда

    ПериодПерПри.НазначитьТип(глТипЗначенияОЛЕ,15,5);

    Иначе

    ПериодПерПри.НазначитьТип(глТипЗначенияОЛЕ);

    КонецЕсли;

    Reply
  44. alfia

    Спасибо

    Reply
  45. 2011b11

    Спасибо вам за обработку

    Reply
  46. baza1978

    спасибо автору, автор пищи еще.

    Reply
  47. Nikola178

    Автору большое спасибо, обработка лучшая из всех, которыми доводилось пользоваться при переносе.(конечно не без недостатков, как было писано выше)

    Reply
  48. ВладАн

    Что-то, как-то тюнинг застоялся. Пора-бы уже и доп. настройки доделать:)

    Reply
  49. Altez

    (48)8ка не пускает. а что за настройки?

    Reply
  50. ВладАн

    по синхронизации…

    ПС или это Павел планировал?

    ПСПС А вопрос снимается сам нашел цитату

    Altez пишет:

    (7)1,2,3 Не делал,

    Автор грит: Доп.настройки работают не все, надо тестить

    Reply
  51. post279

    Все работает!

    Reply
  52. T-AleXandr

    Использовал несколько раз на разных базах. Где-то прокатывало, где-то нет. Так что есть и плюсы и минусы.

    Reply
  53. dicwork

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

    А как указать базу откуда копировать?

    Reply
  54. dicwork

    А есть ли где нибудь документация по пользованию этой обработкой. По ReadMe понять как работать довольно сложно. Потратил кучу времени пока выяснил, что база источник это база откуда запускается обработка. Есть ли где-то в природе описание работы с этим мощным инструментом или как всегда нужно осваивать «методом тыка»?

    Reply
  55. Arico

    Как я могу купить данную обработку, чтобы она сохраняла настройки? По е-майл, указанному в обработке, связаться с Шевченко Павлом не удается

    Reply
  56. Altez

    (55) Arico, у меня сохраняла, что из настроек не сохранилось?

    Reply
  57. Altez

    (54) вникал нажимая кнопки слева направо сверху вниз, в тяжелых случаях открывал отладчик,

    мы ж не в ЦУПе, а какой случай по-вашему нужно задокументировать или экранизировать?

    Reply
  58. vas5780

    Попробую перенести справочники из Бух Бух, как получится постараюсь отписаться.

    Reply
  59. nkorkin

    Как перенести документы из ТиС в ТиС, справочник единицы не синхронизируется т.к. код и наименование нулевой длины? Ошибка: Для справочника Единицы не установлен ключ синхронизации!

    Reply
  60. Altez

    (59) nkorkin, изв. уже не помню как синхронилось, буду рад, если кто недавно переносил решение обубликует

    Reply
  61. Biss81

    Спасибо за обработку, очень выручила при переходе с самописной базы данных

    Reply
  62. corsar4ik

    Это то, что надо! Отличная вещь, давно искал, спасибо! Спасибо автору!

    Reply
  63. Muller2306

    (16) Паланик,

    Вместо

    Если ТабДокТЛок.ТипСоот=»Неопределенный» Тогда

    БазаДок.НазначитьТип(ТабДокТЛок.РеквСоот,глТипЗначенияОЛЕ);

    КонецЕсли;

    попробуйте

    Попытка

    БазаДок.НазначитьТип(ТабДокТЛок.РеквСоот,глТипЗначенияОЛЕ);

    Исключение

    КонецПопытки;

    и вместо

    Если (ТабДокШоЛок.ТипСоот=»Неопределенный») Тогда

    БазаДок.НазначитьТип(ТабДокШоЛок.РеквСоот,глТипЗначенияОЛЕ);

    КонецЕсли;

    вот это

    Попытка

    БазаДок.НазначитьТип(ТабДокШоЛок.РеквСоот,глТипЗначенияОЛЕ);

    Исключение

    КонецПопытки;

    Reply
  64. dicwork

    Кто нибудь может подсказать как с помощью этой обработки переписать только календари? При нажатии на «Ок» высвечиваются только справочники, документы и константы.

    Reply
  65. trioka

    (59) nkorkin,

    ты решил проблему? у меня даже если поставить синхронизацию по ОКЕИ то все равно фигня какаято получается, типа невозможно сохранить…. бла бла бла…

    Ругается — переносит. в с базовых единицах пусто.

    как перенести справочник только номенклатуры? ну со всеми единицами и штрих-кодами конечно.

    если даже не с этой обработкой, то какие есть еще варианты?

    Reply
  66. corsar4ik

    вопрос есть: при переносе документа его реквизит-справочник, существующий в базе приемнике и источнике с одним кодом, но разным содержимым перезаписывается или пропускается?

    Reply
  67. skilster

    Подскажите, как с помощью Universal синхронизировать справочники номенклатуры в Бухгалтерии и ТиС? Если наименование товара совпадает — перезаписать с заменой кода, если нет — создать новый в подходящей для этого группы (группы заведомо названы одинаково). Минут 40 уже бьюсь — номенклатура тупо дублируется вне зависимости от настроек.

    Reply
  68. isaev 100

    (59) То же никак… Правда база приемник очень сильно переписана, но и между двумя «стандартными» ТиС с ошибками. : (

    Reply
  69. MasterCifra

    (59) nkorkin, Добрый день. Подскажите — вы решили проблему или нет? у меня сейчас такая же ошибка не дает перенести еденицу измерения в номенклатуре, а справочник насчитывает порядка 16000 едениц

    Reply
  70. Altez

    (69)к сож. обработка давно не поддерживается (хотя возможность перенести вышеупомянутые справочники в ней есть, ибо переносил), конвертация данных в помощь

    Reply
  71. MasterCifra

    А еще как бороться с такой ошибкой:

    Метод ОсновнойЖурналРасчетов не может быть доступен так как компонента Расчет не загружена!

    Конфигурация ТиС 9.2 (7.70.963)

    Reply
  72. Altez

    (70)нужно просто закомментировать строчку кода, вызывающую исключение

    Reply
  73. nkorkin

    (69) Нет не решил. Юзал Рокет.

    Reply
  74. try2016

    По поводу единиц…не вдавался подробно…нет времени на это. Но если модифицировать код вот так. То по быстрому получится синхронизировать справочники, если не создаются в приемнике элементы и они там уже есть.

    Искать по //Синхронизация

    // Синхронизация //\r
    Если (глТабСприСоот.НайтиЗначение(Строка(СпСправочников.Спр)+»_»+СпСправочников.Ключ,нстр2,»СпрРекв»)=0) И (Строка(СпСправочников.Спр) <> «Единицы») Тогда
    Сообщить(«Для справочника «+Спр.Вид()+» не установлен ключ синхронизации!»);
    Возврат 0;
    КонецЕсли;
    
    Если Строка(СпСправочников.Спр) <> «Единицы» Тогда
    КлючПриемник=глТабСприСоот.ПолучитьЗначение(нстр2,»РеквСоот»);
    КлючИсточник=СпСправочников.Ключ;
    КоличествоУровнейСоот=СпСправочников.КоличествоУровнейСоот;
    ДлинаКодаСоот=СпСправочников.ДлинаКодаСоот;
    СерииКодовСоот=СпСправочников.СерииКодовСоот;
    ДлинаКодаСоот=СпСправочников.ДлинаКодаСоот;
    ДлинаНаименованияСоот=СпСправочников.ДлинаНаименованияСоот;
    Иначе
    КлючПриемник=»ОКЕИ»;
    КлючИсточник=»ОКЕИ»;
    КоличествоУровнейСоот=1;
    ДлинаКодаСоот=3;
    СерииКодовСоот=»ВесьСправочник»;
    ДлинаНаименованияСоот=25;
    КонецЕсли; 

    Показать

    Reply
  75. wap25

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

    Для ХХ=1 По ВсегоХХ Цикл
    глТабСпрРеквОЛЕ.НоваяСтрока();
    глТабСпрРеквОЛЕ.Спр_Рекв=глТабСпрОЛЕ.Идентификатор+»_»+База.Метаданные.Справочник(Инд).Реквизит(ХХ).Идентификатор;
    глТабСпрРеквОЛЕ.Спр=глТабСпрОЛЕ.Идентификатор;
    глТабСпрРеквОЛЕ.Идентификатор=База.Метаданные.Справочник(Инд).Реквизит(ХХ).Идентификатор;
    глТабСпрРеквОЛЕ.Представление=База.Метаданные.Справочник(Инд).Реквизит(ХХ).Представление();
    глТабСпрРеквОЛЕ.Периодический=База.Метаданные.Справочник(Инд).Реквизит(ХХ).Периодический;
    глТабСпрРеквОЛЕ.Использование=База.Метаданные.Справочник(Инд).Реквизит(ХХ).Использование;
    // (Строка 2277) Добавим заполнение типа реквизита
    глТабСпрРеквОЛЕ.Тип = База.Метаданные.Справочник(Инд).Реквизит(ХХ).Тип;
    КонецЦикла;
    

    Показать

    Reply

Leave a Comment

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