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




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

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

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

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

30 Comments

  1. zhyhallo

    Спасибо автору. Хорошая статья. Отлично подобраны ссылки по этой теме.

    Reply
  2. polos75

    Обновить, а потом смотреть, что поменялось — мягко говоря, рискованный метод.

    Сначала в копии базы сравниваю конфигурацию базы с конфигурацией поставщика.

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

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

    После этого обычно нет странных проводок и неоткрывающихся форм.

    Reply
  3. kraynev-navi

    (2) Обновление происходит на копии, риска нет. Надо бы добавить абзац, что только потом все изменения на рабочую перетекают после всех проверок. Сделаю чуть позже.

    Reply
  4. klinval

    (2) polos75, Статья не о том как обновлять нетиповую базу (какие галочки ставить при обновлении, как анализировать код до и после и т.д.), а о способе проверки, что после обновления ничего «не поехало». Причём «поехать» могло не только из-за своих доработок, но и из-за ошибок в типовой конфе.

    У нас был случай: обновляли переписанную БП 3.0. Тогда ещё не было этого автоматизированного средства проверки, поэтому перепроводили квартал в базе ДО и ПОСЛЕ и смотрели ОСВ. Оборотка «поехала». Стал выяснять и оказалось, что программист фирмы 1С в условии вида:

    Если <Какое-то условие> Тогда А = А*(-1)

    Сделал изменение вида:

    Если НЕ <Какое-то условие> Тогда А = А*(-1)

    Благодаря этому проводки получались обратные (относительно тех которые должны были получится).

    В техподдержке проблему признали. Как скоро они исправили я не помню, но мы ошибку фактически «засекли» ещё до внесения в рабочую базу.

    Получается как ни документируй свой код, какими тестами его не покрывай: от такого вида ошибок не застрахуешься… Фактически данным методом проверки мы находим не только ошибки связанные с нашими доработками, но и ошибки фирмы 1С в типовой конфигурации. После внесения исправлений (если обнаружены ошибки) в рабочую базу идёт уже код, который в движениях по регистрам даёт такой-же результат как и код до обновления.

    Reply
  5. artbear

    Спасибо за статью и за упоминание xUnitFor1C.

    Только секрет открытия проверки открытия/закрытия всех форм конфигурации так и остался не раскрытым 🙂

    Посмотрите небольшую статью про эту фичу xUnitFor1C (элемент т.н. «дымовых» тестов)

    Reply
  6. artbear

    (0) Да, подобную методику вполне успешно юзал в свое время, хотя довольно тяжеловато и долговато 🙁

    В свое время так и не автоматизировал подобный тест 🙁 часть операций делал руками.

    Reply
  7. klinval

    (6) artbear,

    Да, подобную методику вполне успешно юзал в свое время, хотя довольно тяжеловато и долговато 🙁

    То что это долго — согласен. Но благодаря автоматизации уже не «тяжеловато» — нажал кнопку и занимайся своими делами (или вообще на ночь оставь выгружаться/проводится).

    Тяжело уже потом дебажить, т.е. выяснять почему движения не идентичные. Но это всё-равно когда-нибудь пришлось бы искать/исправлять. И лучше это сделать до обновления, а не в самый завальный период (в закрытии квартала или года). Плюс особенно «весело», если ошибку обнаруживают когда год закрыт и отчеты все сданы…

    Reply
  8. kraynev-navi

    (5) Артур, статья-то не про дымовые тесты 🙂 Но сказать надо было.

    Очень жду в xUnitFor1C доработку ПослеЗапускаСценария, которую обсуждали в привате.

    Reply
  9. jerry_maguire

    Без ссылки на vanessa-behavior и в целом на продукты семейства vanessa-stack статья не полная.

    Reply
  10. lustin

    (9) jerry_maguire, автор я так понимаю сознательно не использует vanessa stack, используя функционал сценариев xUnit как видно в (8). Но отсутствие упоминания про скажем http://infostart.ru/public/534673/ действительно удручает.

    Reply
  11. kraynev-navi

    Накинулись-то.

    (9) Александр, я пока еще даже не «финалист» )) . Изначально обработка писалась без всяких TDD, BDD. Поэтому VB ПОКА не использовал.

    (10) То, что не используется vanessa stack, так это от недостатка информации по нему.

    Есть несколько видео, есть платный курс, который записал Александр. Статьи очень общие. Направленность их все-таки агитационная, не в практической плоскости.

    Описание наработок, которые скопились в библиотеках тоже нету. Можно сидеть-шерстить самостоятельно ибо опен-соурс. Но времени не так много.

    И да, жду продолжения по ссылке, которую прислали.

    На мой взгляд, в связи с вышеописанным, xUnitFor1C более открыт и прост для понимания и применения. ИМХО. Хотя курс бы тоже не помешал. И видео по змейке скрыли, увы.

    (10) Вопрос вам, как разработчикам vanessa, моих знаний не хватает. Как решить вышеописанную задачу средствами vanessa stack?

    Reply
  12. Pr-Mex

    (11) вебинар смотрели? http://infostart.ru/webinars/537546/

    Reply
  13. kraynev-navi

    (12) несколько раз

    Reply
  14. lustin

    (11) я отрефлексировал на указание топика от 2012 года в котором я же и участвовал. Что касается не упоминания Behavior — я понимаю, что вы сознательно используете xUnit и это нормально. Как говорит Женя — слава богу что хоть что-то начали. еще 2 года назад было вот так http://www.forum.mista.ru/topic.php?id=730184&page=1

    Reply
  15. kraynev-navi

    Вы как-то принимаете все на свой счет, как критику и т.д.. Не надо. Никого не хочу выделить или опустить. Я использую в меру своего понимания и знаний и VB и xUnit , если понимаю как это сделать и какие преимущества мне это сулит.

    Исторически сложилось, что изучение начал с xUnit. Коллега его, например, не очень понял.

    Очень хорошо, что есть и то и другое и что это все развивается. Вообще, спасибо всем разработчикам, что это в опенсоурс! (респектуха!)

    Про задачу, озвученную в статье. Я не вижу как ее решать ни средствами VB, не средствами xUnit. Решал по-старинке.

    (15) про рефлексию не понял, если честно.

    (9) про гиттер да, оперативно.

    p.s. Ссылку на статью размещу в разделе «Другие статьи про тестирование». Там будет справедливо, да.

    Reply
  16. jerry_maguire

    (16) конструктивный подход)

    Reply
  17. JohnyDeath

    (14) Саш, ты как-то в штыки все воспринимаешь. Зачем вот так сразу скатываться до взаимоупреков?

    Это ж не враждующие продукты, а взаимодополняющие.

    По поводу понимания VB vs xUnitFor1C. Согласен с автором, мне, как и ему, пока проще освоить xUnitFor1C, потому как с него начинал. Хотя зачем я их опять сравниваю? )

    Reply
  18. jerry_maguire

    (18) JohnyDeath, осознал) если спозиционировался как разработчик, то в комментарии и обсуждения не лезть, это менеджерское дело.

    Reply
  19. artbear

    ОФФ: (14) Опять какие-то странные наезды и сравнения/противопоставления вкупе с навязчивой рекламой 🙁

    вылечись уже наконец от этого.

    Reply
  20. Pr-Mex

    (20) artbear, пул реквесты и правда в xUnitFor1C висят по пол года и больше. С этим надо что-то делать.

    Reply
  21. Bellerofont

    Спасибо за статью! Очень познавательно!

    Reply
  22. sashocq

    (11)

    Есть несколько видео, есть платный курс, который записал Александр

    Что за курс? Где найти?

    Reply
  23. kraynev-navi

    (25) Не вижу сейчас ссылки на ИС. А вообще, можно спросить у ведущих https://plus.google.com/+SilverbulletersOrgSocial/posts/etMaB73uVwF , если они сами тут не ответят.

    Вот еще в свободном доступе кое-что:

    http://infostart.ru/webinars/521983/

    http://infostart.ru/webinars/537546/

    Reply
  24. drogs

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

    Reply
  25. enschede

    Интересно, а каковы «масштабы» обновления, чтобы был смысл в применении подобных методов проверки и инструментов описанных в статье? Можно ли как-то оценить границу, за которой проще все руками сделать? Применимо ли что-то из этого, если требуется выполнять обновление не огромной базы с большим количеством специфики предприятия, а слабо измененной конфигурации? Допустим обновление выполняется в течение дня? А если в течение недели?

    Reply
  26. kraynev-navi

    (28)

    Смотря какая ответственность лежит на главном бухгалтере ))

    У нас был случай, когда «приехало» обновление БП, ошибки которого мы уже исправляли ранее. И вот опять. Тут критерий длительности обновления по часам совсем не помог бы. Если не ошибаюсь, обновление было минорное тогда.

    Единственный минус дополнительных проверок, который я вижу — это их длительность (зависит от размера базы). Надо развернуть, провести. Сравнить уже быстро можно — обработка https://infostart.ru/public/544800/ ваще все сама делает (почти). На ночь поставил, утром сравнил.

    Рутины мало. По сравнению с обновлением.

    И даже работу этой обработки можно запрограммировать, чтобы еще меньше нажимать (при помощи записи действий пользователя в vanessе, например)

    Reply
  27. acanta

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

    Насколько это целесообразно?

    Reply
  28. kraynev-navi

    (30) Не понял. Можете развернуто пояснить про весь процесс и его цель?

    Reply
  29. enschede

    (29) Наверно, есть смысл разделить вопрос на две части: «учетную» и «техническую». Учетная — это то, что касается корректности учетных данных, а техническая — работоспособности доработок.

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

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

    Reply
  30. kraynev-navi

    (32) Критерий очень простой — если стало лениво каждый раз честно проверять работоспособность всех доработок, пора автоматизировать.

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

    Reply

Leave a Comment

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