Отчет по дебиторской задолженности




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

39 Comments

  1. nikk

    Ну как там?

    Девочки, Финансовые директора и Главные бухгалтеры!

    Хвалите меня уже. 🙂

    Reply
  2. Ёпрст

    Наши долги клиентосам ну никак не могут быть просроченными.

    Reply
  3. nikk

    Согласен.

    Я эту галочку (Учитывать авансы) потом влепил.

    Изначально это не предполагалось.

    Исправлю, если надо.

    Reply
  4. nikk

    Исправил количество просроченных дней.

    Теперь если задолженность наша, то будет «0» дней просрочки и

    отсрочка будет «-«.

    Reply
  5. VV

    Интересно, вечером поиграюсь. Почему-то показывает просрочку по ПКО.

    Reply
  6. nikk

    (5)

    В отчете есть расшифровка, выводит на Ведомость по контрагентам.

    Смотрите на ошибки в базе:

    1. Оплата может быть раньше чем выставлен счет (Заявка) клиенту,

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

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

    не тот, который стоит в Реализации.

    Reply
  7. VV

    Однозначно плюс 🙂 Даже с ведомостью по контрагентам сошлось в копейку. Не очень нравится «Рабочая задолженность», проще — Текущая.

    Если в этот же отчет впендюрить и Кредиторскую — будет очень востребованный отчет.

    <<В отчете есть расшифровка, выводит на Ведомость по контрагентам.>> — это где?

    Reply
  8. VV

    Да, и непонятка: Менеджер — Справочник.ЗначенияСвойств. Свойства и их значения подчинены Контрагентам. При выборе, ессно, пустая форма — не выбран владелец.

    ???

    Reply
  9. nikk

    (7)

    На счет Кредиторской задолженности……. я тоже подумываю 🙂

    Расшифровка работает на последних колонках с суммами (кроме колонки Штраф) и кроме строки с документом. То есть по Менеджеру, Контрагенту и Договору.

    А что касается — Справочник.ЗначенияСвойств, это я писал под определенную базу, в которой всё заполнено и такие ошибки не выскакивают. Но я думаю, можно Справочник.ЗначенияСвойств заменить на Справочник.ВидыСвойств, просто тогда двойная работа получиться, т.е. чтобы выбрать менеджера нужно будет сначала выбрать Вид свойства «По менеджерам».

    Reply
  10. nikk

    Еще раз прошу, не ругайте меня пожалуйста, я токарь (4 разряда)

    и мне трудновато с этим делом. 😳

    Reply
  11. CheBurator

    Обращаю ваше внимание, что штатная рассчетная формула даты оплаты (процедура глБанковскаяДата()) — можно использовать только для приблизительной оценки сроков оплаты — и уж тем более нельзя считать по этой формуле что долг является просроченным, потому как в штатной ТиС считаются тупо дни недели с 1 по 5 (сбт и вск — не считаются) — что никоим образом не соотносится с производственным календарем рабочего времени, утверждаемого на каждый год.

    Reply
  12. VV

    (9) так и у меня все заполнено: и виды и значения. Но справочник подчиненный, он без выбранного контрагента не работает. Просто в описании нужно добавить расшифровку реквизита Менеджер, раз база не типовая. В типовой, получается, этот реквизит не работает вообще.

    (10) никто и не ругает, просто мне отчет понравился, вот и разбираюсь — что к чему.

    (11) Сергей, так в ТиС и нет производственного календаря, нужно свой заводить. У меня в данной базе так и сделано, поэтому если считать по дате оплаты — все будет нормально.

    Reply
  13. nikk

    (12) Ааааааааааааа, извиняюсь, я совсем забыл, что в моей базе сделана константа для этого дела, ВидСвойстваКонтрагентов. Я под нее и написал в

    процедуре ПриНачалеВыбораЗначения:

    спр=СоздатьОбъект(«Справочник.ЗначенияСвойств»);

    спр.ИспользоватьВладельца(Константа.ВидСвойстваКонтрагентов);

    По этому у меня всё ровно.

    Так чего, сделать выбор Вида свойств вместо Значения свойств???

    Reply
  14. CheBurator

    (12) а если считать по глубине кредита из спр.договоров — то ненормально… так?

    Reply
  15. VV

    (13) вооооотттт… 🙂 докопались 🙂 Лучше использовать типовые механизмы, тогда и вопросов не будет. В Константе задан ВидСвойств = Менеджер?

    (14) да я не пробовал, меня устраивает и Дата Оплаты — просто и надежно. А дата у меня проставляется с учетом всего.

    Reply
  16. VV

    +15

    блин…. это типовая константа, получается. Во, я ее никуда ни разу не задействовал. Все, работает, вопрос снят.

    Но насчет Кредиторки — подумай 🙂

    Reply
  17. VV

    И еще: Если Контр не выбран — выводятся ВСЕ, а если Менагер не выбран, то — «не выбран».

    ??? Или я не допонял?

    Reply
  18. VV

    +17) И вдогонку: Есть Контр, у него есть Сво-во Менеджер, Есть значение свойства — Иванов И. И. Если фильтр по Иванову, Контру — таблица пустая. Если Менеджер = «», то таблица заполнена, но менеджер — «Не выбран»

    Reply
  19. nikk

    (17) Не, с этим всё правильно, если Контр не выбран — выводятся ВСЕ,

    а если уже в таблице пишет «Менеджер не выбран» — значит в карточке контрагента не заполнено поле «по менеджеру» на закладке прочее.

    А про то, что вдогонку, или я не понял чего то или так не может быть.

    Получается у контрагента Иванова менеджер он сам? Так что ли?

    Ну, даже если так, какая разница? Все равно должно работать. 😮

    Reply
  20. VV

    Нет, неверно:

    Есть Контр1. У него есть вид свойств = Менеджер. Значение = Иванов.

    Выбираем

    Менеджер = Иванов

    Контрагент = Контр1

    Таблица пустая

    Менеджер = «»

    Контрагент = Контр1

    Таблица заполнена, Менеджер = не выбран.

    Т.е. фильтр по менагеру не работает.

    Reply
  21. VV

    Да, могу все в картинках предстваить.

    Reply
  22. nikk

    (21) В картинках было бы хорошо. Можете на мыло скинуть zzazza@list.ru

    Я проверял, у меня всё работает, как не выбирай. Может у Вас двойник среди контрагентов и просто выбрали не того? 😮

    Reply
  23. VV

    (22) уже не надо в картинках. У меня почему-то очищало при записи в Контрагенте Основное свойство. Поигрался — записало и отчет заработал на 100%. Извиняюсь за ложную тревогу.

    Reply
  24. nikk

    (22) 🙂

    Reply
  25. koppp

    А как сделать выбор Менеджера из справочника Физ.лиц? Конфа не типовая

    Reply
  26. nikk

    (25) Так не могу сказать, если файл MD скинете на мыло, тогда посмотрю.

    Можно сюда: zzazza@list.ru

    Reply
  27. termit@mail.ru

    А эта обработка работает на основе движений регистров или по документам? А то у нас возвраты бывает задним числом вводятся и у стандартного отчёта крыша едет — просрочку показывает большую, которой нет. Или напрмер общий долг — 0, просрочено — 50т.р.

    Reply
  28. nikk

    (27) На основе движений регистров. Если косяки в программе, то и в отчете конечно же тоже.

    Reply
  29. кольщик

    Эх мне бы для ПУБа такой отчетик..

    Reply
  30. кольщик

    Автор ты тут бываешь?

    Reply
  31. nikk

    Бываю. Только помочь не могу 🙁

    На данный момент 1С малость забросил, занят семейными проблемами.

    Reply
  32. кольщик

    А ну тогда успехов в семейных делах. Отчет классный, мне как раз такой нужен.

    Reply
  33. кольщик

    Странно, поменял регистр на тот что в ПУБе, теперь реализация уменьшает долг, а поступление денег, его увеличивает))

    Reply
  34. кольщик

    Блин ну вот почему так может быть?

    В цикле перебираем все документы по контрагенту СумДок=Запрос.КонОст;

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

    Reply
  35. nikk

    Извини, не могу помочь, правда очень занят. 🙁

    Reply
  36. кольщик

    Кое-как настроил под ПУБ. Но получается один косяк. Если документ проводят задним числом, то последним показывается не тот документ что надо. Была отгрузка 13.04. Потом 27.04. Потом числа 28. оплатили за 13-е. Провели 13-ым. В итоге показывается накладная от 13-го, а от 27-го нет..

    Reply
  37. кольщик

    Началась какая то хренотень с отчетом. В отчет вместо реализации попадают поступления денежных средств. В итоге просрочка показывается неправильно((

    Reply
  38. кольщик

    VV, бываете здесь? В (5) писали что: Интересно, вечером поиграюсь. Почему-то показывает просрочку по ПКО.

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

    Случайно не нашли в чем была ошибка?

    Reply
  39. кольщик
    1. Оплата может быть раньше чем выставлен счет (Заявка) клиенту,

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

    Как сделать чтобы документ не болтался к непонято что и за что?

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

    Reply

Leave a Comment

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