Дубли контрагентов. Жесткий запрет на запись дублей [Расширение]




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

55 Comments

  1. Craig

    «+» за оперативное освоение новых технологий (возможность 8.3.6.)

    Reply
  2. insurgut

    Спасибо за пример!

    Reply
  3. logdog

    Для БП 3.0.40.24 ошибка при старте.

    Ошибка подключения расширения: ЖесткийЗапретНаЗаписьДублейКонтрагентов (1.0) — Ошибка свойства РежимСовместимостиИнтерфейса у объекта

    Режим совместимости — Не использовать

    Reply
  4. gorevg

    Интересно, а как расширения сказываются на скорости работы в программе. Ведь, как я понимаю, платформа применяет расширение «на лету». Был у кого-нибудь опыт?

    Reply
  5. mrXoxot

    (3) logdog,

    Да, необходимо снять совместимость с 8.3.5 — это можно сделать в конфигураторе или дождаться когда разработчики БП3 снимут это в типовой конфигурации.

    Reply
  6. logdog

    (5) Я написал, что снято. Прикладываю картинку. http://joxi.ru/zANp9ypS0ZRpm9

    Может есть какое-то отличие в коде для БП КОРП и БП?

    Reply
  7. Поручик

    Ух ты, супер. Расширения — это то, что я так долго ждал.

    Reply
  8. mrXoxot

    (6) logdog,

    Проверил на ПРОФ 3.0.40.24 . Работает, подключается.

    Проверял на платформе 8.3.6.1977. Какая у Вас?

    Reply
  9. logdog

    (8) и на 8.3.6.1977 и на 8.3.6.1999 выдает ошибку =( http://joxi.ru/12M79B7TQ1M8rJ

    Reply
  10. mrXoxot

    Проблема в режиме совместимости интерфейса. Должно стоять — Такси. Разрешить 8.2, как в типовой. У Вас стоит просто Такси.(9) logdog,

    Reply
  11. logdog

    (10) Да, проблема была в этом. Спасибо.

    Reply
  12. planar74

    И как они с РИБ работают? Надо каждому узлу отправлять или достаточно в ЦБ загрузить?

    Reply
  13. qwinter

    Пока в расширениях нельзя будет добавлять свои справочники, документы, регистры надобности в них нет. Разве что поудобнее будет внешние отчеты цеплять.

    Reply
  14. planar74

    (13) qwinter,

    «Дополнительных отчетов и обработок» больше не будет?

    Reply
  15. Alex_E

    (14) planar74, Почему? Одно другому никак не мешает. Вот возможность в расширении изменить поведение формы хоть того же документа — это проще в расширении сделать. Можно добавить раздел в командный интерфейс и включить туда какой то свой набор данных (из имеющихся в типовой, если её не менять), плюс отчеты и пр., в общем много чего уже можно, но хотелось бы больше :-).

    Reply
  16. planar74

    (15) Alex_E,

    Раздел в командный интерфейс добавить в конфигурации или расширении? Насколько я понял, в расширение нельзя добавлять новые объекты конфигурации. В ряде случаев, конечно, может помочь, но не сильно. Я крайне редко сталкивался с ситуацией, когда форму или обработку проведения приходилось менять без (например) добавления реквизита в конфигурацию.

    Reply
  17. Alex_E

    (16) planar74, Подсистему в расширение ввести можно, сейчас пишу настройку, добавил — работает… Вообще проверить, что можно что нельзя достаточно просто — в дереве расширения правой кнопкой на то, что хочется добавить, если активно — то можно.

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

    Reply
  18. qwinter

    (15) Alex_E, одно другое заменяет. На текущий момент именно так. Только внешние печатные формы остаются. Все остальное гораздо удобнее и правильнее делать в расширениях.

    Reply
  19. Alex_E

    (18) qwinter,

    одно другое заменяет. На текущий момент именно так.

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

    С другой стороны, что в 8.3.6.* понравилось — это режим объединения, то, что можно текст модулей поменять как захочешь в момент объединения — уже много значит, для настроенных…

    Reply
  20. planar74

    (17) Alex_E,

    И как вы эти дополнительные реквизиты в запросах используете? Через левое соединение с проверкой по коду вида характеристики?

    Reply
  21. Alex_E

    (20) planar74, По разному, в зависимости от ситуации, иногда через http://infostart.ru/public/288722/, иногда в запросе, «по коду» никогда не использую — доп.реквизиты или сведения создаю программно в любом случае. В запросе через левое соединение, нужный доп.реквизит определяется, чаще всего, по заголовку свойства плана видов характеристик, т.е. пользователю «полета для творчества» оставляю минимум. Пока проблем с этим не было …

    Reply
  22. qwinter

    (19) Alex_E, не думаю что типовые будут долго еще на 8.3.5

    Reply
  23. Alex_E

    (22) qwinter, надеюсь 🙂

    Reply
  24. ZOMI

    Дополнительный вопрос это «жесткий запрет» ?

    Reply
  25. Yashazz

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

    Reply
  26. mrXoxot

    (24) ZOMI,

    Вопрос был в типовом решении.

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

    Но если очень хочется, то можно записать через «Еще»

    Reply
  27. mrXoxot

    (22) qwinter,

    В опубликованных планах сказано, что 3.0.41 будет без режима совместимости с 8.3.5

    То есть, да здравствует 8.3.6.

    Reply
  28. mrXoxot

    (12) planar74,

    Не проверял как работает в РИБ. Но вот, что удалось найти в документации:

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

    Более подробно здесь.

    То есть, кажется, что нужно будет подключать для каждого узла своё расширение.

    Reply
  29. mrXoxot

    (4) gorevg,

    Расширение применяется один раз вначале.

    Подключение расширения к сеансу пользователя выполняется перед вызовом обработчика события УстановкаПараметровСеанса и остается подключенным до завершения сеанса

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

    Reply
  30. 1cmax

    (13) qwinter, абсолютно поддерживаю, это как в мобильной платформе запросов не было сначала, ждемс

    Reply
  31. hobi
    Пока в расширениях нельзя будет добавлять свои справочники, документы, регистры надобности в них нет. Разве что поудобнее будет внешние отчеты цеплять.

    (18) qwinter, мне кажется, самое существенное в расширениях сейчас —

    возможность переопределить типы реквизитов объектов метаданных.

    Можно добавить новый тип в составной в критериях отбора, в определяемых типах, в реквизит «Основание», в план видов характеристик.

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

    Reply
  32. mrXoxot

    (31) hobi,

    Как говорится : «В руках специалиста и табуретка является оружием массового уничтожения».

    Reply
  33. qwinter

    (32) а толку? Не будете же вы добавлять реквизиты отдельно, а форму и типы переделывать в расширении? И как это впоследствии поддерживать?

    Reply
  34. planar74

    (28) по ходу, не только каждому узлу, но и каждому пользователю на узле. Весело, ничего не скажешь.

    Reply
  35. PavelZnaikin

    Народ скажите правильно я понял, что с помощью расширений можно добавлять будет свои Документы, Справочники. Так и изменять форму существующих документов и справочников?

    Reply
  36. Alex_E

    (35) PavelZnaikin,

    добавлять будет свои Документы, Справочники.

    — нет

    изменять форму существующих документов и справочников?

    — да

    Reply
  37. Bassgood

    (34) planar74, не каждому пользователю, а для каждого разделителя, если база использует механизм разделения данных, т.е. совсем жестко будет сочетание РИБ + разделение данных.

    Reply
  38. chmv

    ++++++++++ за новое

    Reply
  39. &rew

    Вот тоже осваиваю данный механизм в плане выноса «дописок» для облегчения обновления. Наткнулся на ПВХ. В расширении дает менять составной тип ПВХ, а в режиме предприятия шлет напрочь. Т.е. вопрос — предполагается такая возможность в будущем или просто вследствие сырости не запретили еще менять тип ПВХ в расширении? (вопрос риторический. Время покажет)

    Reply
  40. ekaruk

    (39) &rew, По логике не должно быть такой возможности.

    Изменение типа ПВХ физически это изменение структуры БД (добавление новых физических колонок на SQL сервере)

    А такой возможности у расширений сейчас нет.

    Reply
  41. &rew

    (40) ekaruk, Это все понятно, про таблицы, типы и прочие ограничения, но речь идет о ПВХ. Это некий «хамелеон» от 1С, который как бы сам по себе уникальный вид, но может «притворяться» кем угодно. Понятно что в рамках определенных типов, но всё же. Почему тогда не создать Универсальное ПВХ, и назначить ему в типы все типы (как бы масломаслянно это не звучало), и тащить через все конфы а то и вообще в БСП включить. Это, конечно, я утрирую, но только дабы четче донести свою мыслЮ.

    Reply
  42. shatt

    Доброго дня! Как обстоит дело с отладкой при создании расширений?

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

    Reply
  43. &rew

    (42) shatt, Эээ. Да всё нормально вроде как с отладкой. На 8.3.6.1999 (да и выше пробовал) работает стандартно. Работаю на win 7 и server 2008, 2012.

    Reply
  44. &rew

    (42) shatt, С ИТСа

    В связи с тем, что список расширений является единым и для доступа из конфигуратора и для доступа из «1С:Предприятия», система не позволяет выполнять взаимоисключающие действия. Другими словами, если в Конфигураторе открыто окно с расширением, то его невозможно удалить из списка расширений в режиме «1С:Предприятия». Расширение, во время записи в информационную базу в режиме «1С:Предприятия», в конфигураторе является недоступным для любых операций с ним.

    Reply
  45. AlexeyPapanov

    //правка

    я писал пост ниже, а позже сам разобрался.

    поясните для танкистов. вот скачал расширение, пытаюсь понять как это работает.

    у вас в модуле формы объекта «спр.Контрагенты» две процедуры:

    — Процедура ДублиКонтрагентовПередЗаписью()

    — Процедура ДублиКонтрагентовЗаписатьДубль()

    я только не пойму где они вызываются.

    вот допустим стоит задача проверить определенный реквизит и в зависимости от этого разрешить запись элемента или запретить, т.е. поставить Отказ=Истина.

    но процедуры ПередЗаписью или ПриЗаписи находятся же в модуле объекта, а не формы.

    а в расширение попадает только форма.

    поясните, как быть?

    я нашел, что, если мы добавляем форму в расширение, то для формы можно также писать обработчики событий формы, среди которых есть ПередЗаписью.

    вот простой пример

    &НаКлиенте
    Процедура Р_ПередЗаписью(Отказ, ПараметрыЗаписи)
    Если НЕ ЗначениеЗаполнено(Объект.НоменклатурнаяГруппа) И НЕ Объект.ЭтоГруппа Тогда
    Отказ = Истина;
    Сообщить(«Не заполнен реквизит «»НоменклатурнаяГруппа»»!»);
    КонецЕсли;
    КонецПроцедуры
    
    Reply
  46. mrXoxot

    (45) El_Loco,

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

    Reply
  47. SkyHunter

    Господа, а подскажите, чем может быть чревато отключение режима совместимости в Бух 3.0?

    Reply
  48. mrXoxot

    (47) SkyHunter,

    На текущий момент ничего отключать не нужно.

    На актуальном релизе данное расширение работает корректно.

    Совместимость с 8.3.5 была снята в 3.0.41

    Reply
  49. mrXoxot

    Обновил расширения для Бухгалтерия 3.0.44

    Reply
  50. user849791

    А есть такое же, но для документооборота?

    Reply
  51. mrXoxot

    (50) У меня, к сожалению, нет.

    Reply
  52. demaxxx

    В БП 3.0 (3.0.65.72) при подключении расширения

    Ошибки:

    ———————————————————————————

    15.01.2019 12:16:41

    ЖесткийЗапретНаЗаписьДублейКонтрагентов (1.1): Критичная: Не найден объект ФункциональнаяОпция.Новости_РазрешенаРаботаСНовостями

    Reply
  53. mrXoxot

    (52) Можете просто удалить этот реквизит из расширения.

    Обновил расширение в публикации.

    Reply
  54. demaxxx

    (53) Удалить не могу, похоже что возможность редактирования отключена, или я что то не так делаю..

    Reply
  55. demaxxx

    В файловой работает, в SQL при добавлении расширения получаем http://prntscr.com/mbx5wy

    Reply

Leave a Comment

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