Строим "фасады" в 1С




Принцип обмена данными из 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='\

40 Comments

  1. TODD22

    Пример начал с рассылки уведомлений и как то внезапно перескочил на логирование.

    Reply
  2. ktb

    (1) Есть такой момент, но про уведомления показалось интереснее, а логирование было быстрее и проще реализовать для примера. 😉

    Reply
  3. neikist

    Хм, может ошибаюсь, но это больше не на фасад похоже, а на шаблон «Самозванец (Imposter)», правда узнал я об этом шаблоне из книги «Разработка через тестирование» Кента Бека, и что то он довольно редко встречается, когда загуглил — только на некоторых сайтах было. А фасад на мой взгляд это скорее обертка над одним или несколькими объектами сделанная для упрощения взаимодействия (может уровень абстракции повыше нужен, может половина api не нужна, а часть нужно объединить, и т.д.). А так подход хороший, сам пользуюсь, правда в моем случае я часто в модулях менеджеров такое размещаю вместо общих. Плюс можно задействовать шаблон «Шаблонный метод», определить некую общую логику куда передавать свой модуль реализующий интерфейс как зависимость и дергать методы уже «интерфейса».

    Reply
  4. boln

    На партнерке был 10 лет назад разговор про «мегадокументы». Это тоже один из частных случаев паттерна Facade.

    https://partners.v8.1c.ru/forum/topic/586245

    Reply
  5. ktb

    (3) Согласен, что это не совсем «фасад», но уж больно название понравилось. 🙂

    Reply
  6. ktb

    (4) В принципе, это все про абстрактные классы. 🙂

    Reply
  7. kalyaka

    (5) вот описание паттерна Фасад: https://refactoring.guru/ru/design-patterns/facade

    У Вас же скорее Интерфейс или Адаптер:

    https://refactoring.guru/ru/design-patterns/adapter

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

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

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

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

    Reply
  8. o.nikolaev

    Насчет попытки протащить полноценный ООП в язык платформы как-то было замечено, что через некоторое время начнут возмущаться «почему так сложно все стало»? Ибо одолеть сложность с помощью ООП, увы, нет — через некоторое время потекут и «фасады» и «мегадокументы» и «фабрики» и любая, в общем-то, human-конструкция.

    На местах — кто во что горазд, в зависимости от того какие книжки по ООП (или компиляторам) были прочитаны: и обработки зашивают в макеты обработки — «менеджера пакетов» и встраивают свои языки в строковые реквизиты справочников-интерпретаторов и обработки — генераторы исполнения текстов для «Выполнить()». Полный набор годноты. Критерий истинности, как всегда — практика. Работает? Стабильно? Надежно? Позволяет доработку-эволюцию быстро исполнить? Ну и «молодцом».

    Reply
  9. boln

    (8)

    Насчет попытки протащить полноценный ООП в язык платформы как-то было замечено, что через некоторое время начнут возмущаться «почему так сложно все стало»?

    Да ладно, повозмущаемся да привыкнем 🙂

    Уж какой взрыв возмущения вызвала три года назад 1С-овская реализация «асинхронности», и то уже забыли и смирились.

    Reply
  10. Артано

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

    Не согласен с выводом в 7, что недостаточно абстрактная статья. Она ведь и называется строим XXX вместе. Это изложение какой-то теории в приложении к конкретной практической реализации.

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

    Автора, на мой взгляд, конечно можно критиковать, и не в последнюю очередь за попытку поймать «хайп», но кто без греха…

    В целом — заслуженный плюс. За исследование, обобщение опыта и публикацию

    Reply
  11. Gureev

    1Ска сама по себе фасад.

    Чего только стоит

    Движения.Записать();
    Reply
  12. ktb

    (7) Ну фасад, является частным случаем интерфейса, а адаптер все таки немного про преобразование интерфейса.

    Переопределяемые модули, на мой взгляд, несколько более «низкоуровневый» вариант решения. В своем варианте я немного сильнее ограничил «простор для творчества».

    В статье я привел только общее описание для пояснения подхода, все детали можно изучить в коде. 🙂

    Reply
  13. ktb

    (8) Согласен, главное вовремя остановиться, до того как работа с универсальным механизмом станет сложнее чем с конфигуратором. 🙂

    Reply
  14. ktb

    (10)

    …достаточно заменить библиотеку и вуаля, реализован новый функционал…

    Как бы в статье именно такой вариант и описан, только вместо DLL, обработка.

    Reply
  15. awk

    (10)

    берут … и пытаются это натянуть на 1С

    Неужели лучше брать и изобретать велосипед?

    Зачем в Си++ создается интерфейс?

    Интерфейс предписывает объекту, что тот должен содержать определенный набор функций, кроме того эти должны содержать параметры определенного типа.

    Как это можно реализовать в 1С? Никак.

    Да вы что? Пример (псевдокод):

    Интерфейс И {

    void** foo(void** pp);

    }

    Клас А : И {

    void** foo(void** pp) throw new FuException(«….»);

    }

    И что тут интерфейс предписал? Какого типа параметр?

    Объекты можно упаковать в динамические библиотеки (dll), т.е. достаточно заменить библиотеку и вуаля, реализован новый функционал, кроме того можно создать различные dll для различных конфигурации ОС и ПК.

    А что обработки отменили? Меняйте обработки, хоть статически, хоть динамически.

    Есть такой термин — декомпозиция. Декомпозиция применяется крайне широко, и далеко не только в программировании, но нет, мы буде упорно пытаться натянуть методы ООП, т.к. других не знаем.

    Допустим знаем, все равно нельзя брать лучшее от ООП?

    Reply
  16. Rustig

    (12) фасад на фасаде … 🙂

    Reply
  17. HAMMER_59

    (16)

    Да вы что? Пример (псевдокод):

    Интерфейс И {

    void** foo(void** pp);

    }

    Клас А : И {

    void** foo(void** pp) throw new FuException(«….»);

    }

    Дай дураку стеклянный… он и руки порежет.

    Естественно много чего можно написать на Си++, но мы же говорим про правильную разработку.

    Инкапсуляция, Наследование, Полиморфизм — будете спорить, что всего этого нет в 1С? Удачи.

    Reply
  18. awk

    (18)

    Дай дураку стеклянный… он и руки порежет.

    Согласен. Пример кстати компиляции правильной разработки на С++ и Джава.

    HRESULT QueryInterface(
    [in]  REFIID riid,
    [out] void   **ppvObject
    );

    Collection<String> c = new ArrayList<>();
    Collections.addAll(c, «a», «b», «c»);
    Collection<String> c2 = Collections.unmodifiableCollection©;
    c2.add(«d»); // Throw java.lang.UnsupportedOperationException
    

    В последнем примере <String> легко можно опустить.

    Инкапсуляция, Наследование, Полиморфизм — будете спорить, что всего этого нет в 1С? Удачи.

    Наследование? В 1С? Не в пакетах XDTO? Что-то не припомню, напомните?

    Reply
  19. Артано

    Читая про споры на тему «в 1с нет ООП» всё время вспоминаю однажды сказанную по этому поводу фразу:

    глядя на код некоторых из спорщиков, кричащих что в 1с нет ООП, можно сказать что в 1с нет даже структурного программирования
    Reply
  20. HAMMER_59

    (19) Какой же поток сознания из вас льётся…

    Попробую объяснить по простому, может тогда до вас дойдёт.

    То что вы написали, звучит примерно так: «А на коробке автомат, вот тоже можно переключать вручную скорости».

    Кто с этим спорит? Может для вас это новость, но остальные также понимают, что от этого АКПП, далеко не то же самое что КПП, но вам сложно это осознать.

    «Вот же смотрите похоже ведь».

    Мой брат (меня он перерос)

    Доводит всех до слез,

    Он мне сказал, что Дед-Мороз

    Совсем не Дед-Мороз!

    Он мне сказал:

    — В него не верь! —

    Но тут сама

    Открылась дверь,

    И вдруг я вижу —

    Входит дед.

    Он с бородой,

    В тулуп одет.

    Тулуп до самых пят!

    Он говорит:

    — А елка где?

    А дети разве спят?

    С большим серебряным

    Мешком

    Стоит

    Осыпанный снежком,

    В пушистой шапке

    Дед,

    А старший брат

    Твердит тайком:

    — Да это наш сосед!

    Как ты не видишь: нос похож!

    И руки, и спина! —

    Я отвечаю: — Ну и что ж!

    А ты на бабушку похож,

    Но ты же не она!

    Reply
  21. awk

    (21)

    звучит примерно так

    У вас в голове? Я доносил:

    1. Знания надо обобщать и повторно использовать.

    2. Думать надо головой.

    3. Техническое ограничение обойти можно.

    4. Ограничения накладываются не только технически.

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

    P.S.

    Как, вырванное из контекста:

    А на коробке автомат, вот тоже можно переключать вручную скорости

    соотносится с:

    АКПП, далеко не то же самое что КПП

    Я вообще не понимаю.

    Reply
  22. HAMMER_59

    (22)

    1. Знания надо обобщать и повторно использовать.

    2. Думать надо головой.

    3. Техническое ограничение обойти можно.

    4. Ограничения накладываются не только технически.

    1. Вчера сделали открытие, а теперь всем доносите?

    2. Еще чем-то умеете думать? Точно адекватны?

    3. Кто с этим спорит, что можно пытаться натянуть «сову на глобус», и возможно, даже получится.

    4. Можно и вовсе вести учет на бумаге без всяких программ и компьютеров. Глубокие сомнение, что у вас есть хоть какое-то представление зачем нужно проектирование, именно поэтому у вас такая каша в голове.

    Reply
  23. brr

    (20) гхм, а что же тогда есть?

    Reply
  24. awk

    (23) Риторику отбрасываем (вопросы 1-4).

    Раз вы постулируете знания: «Зачем нужно проектирование», соблаговолите их раскрыть. В противном случае, вы являетесь пустобрехом.

    Reply
  25. supp

    А на расширениях такое написать?

    Reply
  26. ktb

    (26) Должно превращаться в расширение копи-пастой.

    Reply
  27. HAMMER_59

    (25)

    Основная цель проектирования, в моём понимании — преодоление ограничений человеческого мышления. Одно из самых слабых мест — краткосрочная память, в которую умещается от 5 до 8 единиц знаний. Данное ограничение легко проверить, попробуйте быстро запомнить число, чем больше цифр будет в числе, тем больше будет ошибок.

    В краткосрочную память мы помещаем : код программы, переменные виды, виды переменных.

    Основным приёмом сокращения всего выше перечисленного является декомпозиция.

    Я считаю:

    1. Проектирование на уровне объектов в 1С ограничено определенными рамками — деревом метаданных, и никуда от этого не деться.

    2. Проектировать, естественно, можно не только в конфигураторе, например, для SAP есть стандартные нотации — ARIS.

    Для 1С, в частности, на инфостарте все пытаются притянуть методы проектирования от ООП, которые явно не подходят. Но они ведь проще, и информации по ним в разы больше.

    Reply
  28. awk

    (28) Вы про какое проектирование? На каком уровне? Как 1С коррелирует с SAP? Как эти фирмы коррелируют с методологиями описания бизнес-процессов? Будет ли ваше высказывание справедливо, если я проектирую класс на яве? Будет ли ваше высказывание справедливо, если я проектирую баг трекер?

    Reply
  29. HAMMER_59

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

    У вас же очередной поток сознания. Трудно признать что где-то у Вас капитальный провал в знаниях?

    Очень напоминаете человека, который чуток позанимался ООП, а скорее всего так и есть, только вы там чуток, сям чуток, еще там, этакая разносторонняя личность.

    — «О я умею классы создавать, и так, и этак, а еще так».

    — «А зачем классы создаешь?»

    — «Не ну это, ну я и на Си++, и на Си шарп, и Ява, и …» (опять не видите аналогий с вашими ответами?)

    Reply
  30. Артано

    (24) спагетти, в виде функций по 500-2000 строк и хорошо если без операторов GoTo

    Reply
  31. lazarenko

    ко всему прочему в примере еще паттерн Factory Method применен

    Reply
  32. awk

    (30) Мне крайне льстит, признание вами, наличия у меня сознания. Жаль, что за вами я не могу признать того же. Печально, что выше уровня детского сада вы так и не можете подняться, однако попробую не опускаясь на ваш уровень объяснить.

    Проектирование (в общем смысле) — это процесс создания проекта. Соответственно требуется оно для того что бы создать проект. Цель у него проект.

    Что такое проект можно посмотреть в Википедии https://ru.wikipedia.org/wiki/Проект_(в_управленческой_деятельности)

    Найдете там слова ООП, SAP, 1С, ARIS — кидайте ссылку буду рад ознакомиться.

    То о чем вы пишете — называется конструирование.

    Конструирование — деятельность по созданию материального образа разрабатываемого объекта, ему свойственна работа с натурными моделями и их графическими изображениями (чертежи, эскизы, компьютерные модели). Эти модели и изображения, а также некоторые виды изделий называют конструкциями. Например, конструирование форм одежды, конструирование интерьеров, разработка конструкции машины, конструктивные и объёмно-планировочные решения объекта капитального строительства, металлоконструкция, строительные конструкции.

    При это вы описываете конструирование крайне конкретное. Конструирование приложений на базе продуктов фирм 1С SAP AG.

    Так что про кашу могу согласиться, только уточнив в чьей голове она находиться. Она у вас в голове.

    Reply
  33. OerlandHue

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

    Спасибо за статью, я бы с удовольствием почитал больше статей про паттерны программирования в 1С.

    Reply
  34. ktb

    (34) Про «токсично ведете» не совсем понял.

    Что касается «почитать про паттерны программирования», планирую, как минимум, еще статью по реализации событийной модели в 1С.

    Reply
  35. ManyakRus

    1) сделано:

    1 новый справочник

    4 обработки

    3 общих модуля

    когда по-обычному намного легче «добавив дополнительную ветку кода для нового способа отправки».

    В итоге никакой пользы.

    2) насчёт «интерфейса» — трудно заставить самого себя писать код по-человечески ?

    делать стандартные имена функций и др…

    Reply
  36. Vortigaunt

    А разве не тот же подход используют в типовых конфигурациях?

    — Торговое оборудование

    — Механизм внешних печатных форм / обработок / обработок заполнения таб. частей.

    Все это работает практически так же, как описал автор. И цель та же. Расширение функционала без переписывания половины конфигурации.

    Или я невнимательно прочитал статью и отличия все таки есть?

    Reply
  37. Vortigaunt

    (34) Можете почитать вот эту статью:

    https://infostart.ru/public/624689/

    Я для себя этот подход с кэшированием адаптировал под написание своеобразных заменителей синглетов (singletone) на язые 1с: если нет — то создать, в любом случае вернуть. Преимущество в том, что объявление и инициализация объекта запакованы в одну функцию. Потом проще взять из загашника старую обработку и скопировать нужные функции, какие надо из одного, а не 3 мест кода.

    Reply
  38. ktb

    (37) Да, принцип реализации похож, различия в деталях.

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

    В БСП и конфигурациях 1С расширяемость доступна для ограниченных применений.

    Reply
  39. musatov1c.ru

    О! Это напоминает R-схемы. Это они?

    Reply
  40. ktb

    (40) Это вроде как принятое изображение interface. (Мышка, MS Paint) 😁

    Reply

Leave a Comment

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