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




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

37 Comments

  1. ZLENKO

    «При реализации возникла проблема»

    А в чем проблема то ? В конфигурацию добавить 1 строчку кода и сделать доступным количество дней отсрочки.

    Reply
  2. macsol

    (1) А проблема в том, что у меня в базе 7 организаций, из них 3 — в разных городах России, а я один со всем этим хозяйством. 1-сники штампуют обновления каждый месяц. Если я буду по любому случаю в конфу «строчки добавлять», то просто не справлюсь один с очередным обновлением. Я придерживаюсь такого мнения, что менять конфу нужно только в случае крайней необходимости. Если можно обойти, нужно обходить.

    Reply
  3. ZLENKO

    А можно увидеть в отчете по каким документам просрочено и на сколько дней просрочено ?

    Reply
  4. wirg

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

    Reply
  5. molot

    «При реализации возникла проблема»

    Кстати, а чем «Максимальное число дней отсрочки» в договоре не устраивает? В 23-м релизе — доступно и для договоров с поставщиком. А до этого можно было и внешней обработкой заполнять…

    Reply
  6. macsol

    (5) Не успеваю угнаться за новыми релизами, 6 дней назад обновлялся только.

    «Максимальное число дней отсрочки» в типовой конфигурации доступно только при ведении взаиморасчетов по документам расчетов. У нас не все договора ведутся по документам расчетов. Внешней обработкой заполнить можно, только в типовой форме значений не будет видно, придется выводить в этой обработке. А самый главный минус — человеческий фактор. Придется обучать менеджеров пользоваться обработкой и отчетом.

    Reply
  7. macsol

    (3)В этом отчете нельзя. Я писал что у нас договора смешаны. Запрос строился по регистру «Взаиморасчеты с контрагентами». Если у вас все договора ведутся по документам расчетов то можно переделать запрос по регистру «Взаиморасчеты с контрагентами по документам расчетов» и дернуть нужные данные. У меня такой задачи не стояло.

    Reply
  8. ZLENKO

    (7) У нас документы расчетов вообще не используются, поэтому я написал отчет, который выдает данные в независимости от использования документов расчетов. По личному опыту если выдается сумма без расшифровки — возникает много вопросов типа «Почему тут такая сумма ?!».

    Reply
  9. macsol

    (8) Если документы расчетов не используются можно считать что платежи их закрывают по порядку. В моем случае все смешано, поэтому выбрать какой-то один способ (по порядку или по док.расчетов с контр) не правильно. Когда у манагеров возникают вопросы, они ищут на них ответы в типовых отчетах.

    Reply
  10. anig99

    Вот-вот. Точно как (8) Возьми мою обработку, глянь. А число дней отсрочки там вычисляется отдельно, можно исправить на твой вариант со свойствами. И расшифровки там есть. Скоро обновлю отчет — пару функций добавлю. Оценки не ставлю ибо особо плохого в этой обработке не вижу, но и новизны никакой.

    Reply
  11. ZLENKO

    (9) «ищут на них ответы в типовых отчетах»

    Ну вот, например, на вопрос «А за какие такие отгрузки у клиента просрочена оплата на вот эту сумму что показывает отчет ?» в каких типовых отчетах и как они ищут ответ ? Вручную отбирают последние отгрузки что ли ?

    Reply
  12. ZLENKO

    (10) «Оценки не ставлю ибо особо плохого в этой обработке не вижу, но и новизны никакой.»

    Аналогично.

    Reply
  13. macsol

    Да пофиг оценки, интересно послушать мнения. Если кто знает, пролейте свет.

    Какое выражение в запросе выполниться быстрее :

    a >= b

    Не a<b

    Reply
  14. macsol

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

    Reply
  15. ZLENKO

    (14) С другой стороны, если каждый начнет выкладывать сюда все свои запросы или процедуры — раздел «Программы» превратится в помойку. Для обсуждения приемов программирования есть раздел «Форум» и тематические форумы на других сайтах.

    Reply
  16. molot

    (13) второе.

    Только вряд ли ты этим че-то оптимизируешь 🙂

    Reply
  17. anig99

    Код закрыт — это минус. Производительность по сравнению с моей обработкой вроде бы хуже. Пока тестировал на 1 клиенте — где-то раз в 10 эта обработка медленнее. Сейчас буду пробывать на группе клиентов. Но для манагеров часто важен 1 клиент.

    Reply
  18. anig99

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

    Reply
  19. anig99

    Да… на множестве клиентов получилось быстрее. Но вот достоверность данных надо тоже проверить.

    Reply
  20. anig99

    А что за 2 скриншот? На интервалы не похоже.

    Reply
  21. macsol

    (20) вывод таблицей по строки — контрагенты

    колонки — отсрочка платежа.

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

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

    Reply
  22. macsol

    (18) Я реализовал предварительный отбор, который ускоряет работу запроса при установке отборов. При малых значениях выборки, ускорение впечатляет. Но эту версию не выкладываю.

    Reply
  23. ZLENKO

    (19) Проверил отчет на демо базе конфигурации «Управление торговлей».

    Отчет работает неправильно:

    — общая сумма задолженности всех контрагентов не соответствует отчету «Ведомость по взаиморасчетам с контрагентами», а должна быть одинаковая;

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

    Reply
  24. Nefertary

    «Создается свойство договора «Отсрочка платежа», в нем по порядку добавляются знаечения свойств 1,2,3, 4, 5, 6… Числа должны идти по порядку, и заканчиваться числом равным количеству дней максимальной отсрочки.»

    Можно создать свойство договора «Отсрочка платежа» и задать ему тип «Число».

    Reply
  25. macsol

    (23) спасибо за тестирование, замечание справедливо. Я перемудрил с запросом (некоторые данные задваивались). Во второй версии исправил.

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

    Reply
  26. macsol

    (24) Решая некоторые задачи, иногда кажется что простых решений нет, по-этому и спрятаны эти решения прямо перед носом тех кто их не замечает.

    В общем — огромное спасибо и респект. Во второй версии отчета использовал числовой тип.

    Reply
  27. Nefertary

    Дефолтовое название характеристики лучше другое поставить

    Reply
  28. macsol

    (27) аФтор начальник отдела продаж.

    Reply
  29. anig99

    чего-то последняя версия какая-то не такая стала. Во первых — странное поведение с датами отчета.

    » Если документы сформировавшие остаток на дату отчета не входят в этот интервал, отчет присваивает им дату ДАТА = (Дата начала интервала — 1 день) отнесение задолженности

    на текущую и просроченную будет расчитываться исходя из этой даты.» — честно абракадабра какая-то. Т.е. получается, что если долг не вошел в этот период, то я его не увижу? Фигня какая-то… должен сидеть и подбирать период… Имхо изначально отчет лучше был.

    Reply
  30. macsol

    (29) Извиняюсь за костоязычность. Попробую объяснить заново. Отчет выводит задолженность на конец последней даты интервала. Общую задолженность отчет покажет в любом случае. В интервал могут не попасть даты документов — образовавших эту задолженность. Отчет может не показать документ регистратор, и если он его не находит, то присваивает ему дату КонецПериода — 1.

    Это сделано для ускорения, кому нужна вся инфа, уменьшат начальную дату интервала.

    Reply
  31. anig99

    Просто получается, что если я не угадаю с периодом, то просроченный долг увижу неверно. Это очень плохо.

    Reply
  32. anig99

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

    Reply
  33. macsol

    (32)Уже посмотрел, впечатление хорошее. Есть недочеты, я тебе о них написал.

    Reply
  34. orsprog

    Да ладно!!! вполне сносный отчет…

    Reply
  35. AndrewAks

    Скачал v4, сконвертировал под 8.2, при запуске получил сообщение «Демонстрационный срок использования отчета вышел.». Отчёт платный? И если да, то почему об этом нигде не сказано?

    Reply
  36. trum86

    (33) при запуске пишет «Демонстрационный срок использования отчета вышел.», какой еще демонстрационный срок? Только скачал..

    Reply
  37. Dracarys

    То же самое: «Скачал v4, сконвертировал под 8.2, при запуске получил сообщение «Демонстрационный срок использования отчета вышел.»»

    {ВнешнийОтчет.ВедомостьПоВзаиморасчетамТекущимПросроченным.МодульОбъекта(737)}: Ошибка при вызове метода контекста (Вывести)

    по причине:

    Ошибка вывода результата

    по причине:

    Ошибка при выводе результата

    по причине:

    Ошибка получения данных

    по причине:

    Ошибка создания набора данных «НаборДанных1»

    по причине:

    Ошибка при исполнении запроса набора данных

    по причине:

    {(94, 21)}: Ошибка обработки представления «РегистрНакопления.ВзаиморасчетыСКонтрагентамиПоДокументамРасчетов.ОстаткиИОбороты:Неправильно задан период: начало периода должно быть меньше или равно окончанию»

    ЛЕВОЕ СОЕДИНЕНИЕ <<?>>РегистрНакопления.ВзаиморасчетыСКонтрагентамиПоДокументамРасчетов.ОстаткиИОбороты(&ДатаНачала, &ДатаОкончания, Регистратор, , ДоговорКонтрагента.ВестиПоДокументамРасчетовСКонтрагентом) КАК Обороты

    Reply

Leave a Comment

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