Дебиторка fifo по долгам контрагентов (УТ 10.3).




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

38 Comments

  1. Поручик

    Давненько на эту тему ничего не писали. Боюсь, в понедельник набежит бомонд, и закидают автора веществами. Я даже знаю кто.

    Reply
  2. mxm2

    Отчетец не без «тонких» ))) мест, но зато универсальный и работает. проверено. а так конечно правильнее применять подход с договорами по расчетным документам. Но не могу я народ заставить ))) в свое время «расслабила» их семерка. и еще в принципе отчет легко модифицировать, убрав детализацию по договорам (используя функцию Максимум или Минимум по Допустимым дням задолженности и Допустимой сумме задолженности)… Ну и вобщем готов к здоровой критике, ибо «чем больше я познаЮ, тем больше я не знАю» (с) Сократ

    Reply
  3. anig99

    Собственно кидаться какулями не буду.

    Просто есть несколько моментов:

    — ссылка на описание методики нерабочая (возможно ещё неотмодерировали)

    — оптимизация запроса за счет ограничения выборки по времени по дате последнего перехода в минус — это лучше, чем тупое ограничение выборки по общей дате, но всё же далека от цели… В реальности постоянные контрагенты НИКОГДА не оплачивают долг полностью, а только просроченный. Таким образом, оптимизация работать не будет.

    — жаль, что привязка только к договорам.

    — ознакомьтесь с материалами по теме. Есть мои статьи и отчеты (правда запросы там путаные), есть и другие (лень сейчас искать)

    Reply
  4. mxm2

    (3) anig99,

    — ссылка на описание методики нерабочая (возможно ещё неотмодерировали)

    в публикации методика не описана — мне её «на пальцах» объяснил наш экономист…

    В реальности постоянные контрагенты НИКОГДА не оплачивают долг полностью, а только просроченный. Таким образом, оптимизация работать не будет.

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

    По поводу статей — на этом сайте?

    Reply
  5. sevipa

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

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

    Reply
  6. IDija

    При попытке открыть, ругается на компоновку данных:

    {(20, 20)}: Таблица не найдена «РегистрСведений.АгентыПоДоговорам.СрезПоследних»

    ЛЕВОЕ СОЕДИНЕНИЕ <<?>>РегистрСведений.АгентыПоДоговорам.СрезПоследних(&ГраницаКонца, ) КАК АгентыПоДоговорамСрезПоследних

    Точно для ред. 10.3? Может с какого то определенного релиза?

    Reply
  7. Поручик

    (6) Нет в УТ 10.3 никакого релиза такого регистра.

    Reply
  8. mxm2

    (6) IDija,

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

    Reply
  9. mxm2
    IDija пишет:

    При попытке открыть, ругается на компоновку данных:

    {(20, 20)}: Таблица не найдена «РегистрСведений.АгентыПоДоговорам.СрезПоследних»

    ЛЕВОЕ СОЕДИНЕНИЕ <<?>>РегистрСведений.АгентыПоДоговорам.СрезПоследних(&ГраницаКонца, ) КАК АгентыПоДоговорамСрезПоследних

    Точно для ред. 10.3? Может с какого то определенного релиза?

    Перезалил файл.

    Reply
  10. mxm2
    anig99 пишет:

    Собственно кидаться какулями не буду.

    Просто есть несколько моментов:

    — ссылка на описание методики нерабочая (возможно ещё неотмодерировали)

    — оптимизация запроса за счет ограничения выборки по времени по дате последнего перехода в минус — это лучше, чем тупое ограничение выборки по общей дате, но всё же далека от цели… В реальности постоянные контрагенты НИКОГДА не оплачивают долг полностью, а только просроченный. Таким образом, оптимизация работать не будет.

    — жаль, что привязка только к договорам.

    — ознакомьтесь с материалами по теме. Есть мои статьи и отчеты (правда запросы там путаные), есть и другие (лень сейчас искать)

    Посмотрел Ваши публикации по поводу оптимизации, «буду курить»,

    У меня клиенты достаточно часто оплачивают долг до нуля, иногда даже авансируют… + договора действуют максимум 1 год.

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

    Reply
  11. IDija

    >> Кстати в статье текст запроса — верный, можно просто перенести, ну и внастройках отчета убрать упоминание «агента».

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

    Reply
  12. IDija

    (7) тогда не понятен ваш плюс…

    Reply
  13. mxm2

    (11) IDija, файл уже правильный, его достаточно скачать.

    «после двух ошибок исправлять далее не захотелось» — кроме отборов там нет упоминаний об агенте.)

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

    Reply
  14. urbanist

    Пару лет назад ваял на эту тему:

    http://infostart.ru/public/22091/

    Сейчас вспомнил и добавил с с просрочкой по интервалам:

    http://infostart.ru/public/100137/

    Reply
  15. mxm2

    (14) urbanist, всетаки инфо о доп днях и сумме правильнее брать из договора. а вот решение показывать — по интервалам — красиво. я в свое время исходил из того что отчет должен нормально печататься на а4 и раздаваться менеджерам-селянам (т.е. быть прозрачным и понятным)

    Reply
  16. urbanist

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

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

    Reply
  17. mxm2

    (16) urbanist, про правку — это да…, но по опыту торговлю чаще всего приходится «затачивать»… вот бухию — обычно оставляю в первозданном виде.

    Reply
  18. orehova123

    ммм, спасибо! интересно и достаточно подробно, добавлю в закладки

    Reply
  19. mxm2

    Для УТ11 аналогичный отчет: http://infostart.ru/public/128507/ (основная группировка по АналитикеУчетаПоПартнерам)

    Reply
  20. Stas-ch

    Спасибо за отчет.

    Клиент попросил нечто подобное, только в разрезе клиентов (без учета договора, ибо менеджеры, разносящие банк, часто и договор неправильно указывают). Ну и еще прикрутил к нему интервалы задолженности. Получилось то, что надо!

    Правда не понял, что есть поля

    НО и КО — если не сложно, опишите.

    Reply
  21. mxm2

    (20) Stas-ch, НО = Начальный остаток, КО = Конечный остаток, по логике отчета вроде это видно. Если модифицировали — смело выкладывайте, возможно кому-то нужен именно Ваш отчет.

    Reply
  22. kotuke

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

    Reply
  23. mxm2

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

    Reply
  24. LexSeIch

    Мир этому дому!

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

    Reply
  25. serge_focus

    Обсуждение похоже затихло…

    Однозначно плюс за расписанную процедуру.

    Но хочу заметить строить отчет погашая по фифо — очень нерационально. Берем ТЕКУЩИЙ ДОЛГ (+ или — ) и разворотом от сейчас назад по документам-регистратором задолженности. Набераем требуемую сумму — будет в 10 раз быстрее… Тем более если есть задача сохранить «девственность» кода 1С и не использовать для накопления регистры, то зачастую на средней фирме уже через год внешний пересчет всех долгов по ФИФО занимает прилично времени, и блокирует работу…

    А пересчет разворотом от сейчас успешно используется со времен 7.7 (здесь примеров полно).

    И второе. Количество дней просрочки часто используют для СТОПа отгрузок.

    А в случае с задачей оперативного изменения этого параметра, (для — например- предоставления акционных условий в рамках одного договора, на определенный период) использовать параметры отсрочки из «договора» очень неудобно.

    Да и при сохранении «девственности» кода 1С лучше использовать свойства объекта(справочник «Контрагенты»).

    Reply
  26. mxm2

    (25) serge_focus,

    Согласен с Вами. А есть соображения как можно сделать эффективнее с использованием регистров?

    Общая идея: записи в регистрах (самопальных) фомируются фоновым заданием (скажем ночью), со сдвигом соответствующей последовательности. А в процессе работы производится «склейка» результатов по регистру и остатка по fifo, непосредственно из документов.

    Reply
  27. ildarovich

    Предлагаю другое, гораздо более быстрое решение той же задачи: http://infostart.ru/public/262300/. Не требующее, к тому же, изменений в конфигурации.

    Reply
  28. Pawlick

    Все это здорово, но вот незадача:

    этот отчет и http://infostart.ru/public/262300/ от ildarovichа разные результаты показывают…

    или это только у меня одного?

    И кстати результаты отчета от ildarovichа более похожи на правду…

    Reply
  29. mxm2

    (28) Pawlick, у Вас нет документов введенных одной датой и одним времением по одному контрагенту? Всмотритесь в алгоритм: оптимизированный отчет имеет некоторые особенности.

    Reply
  30. 20tanush

    Ошибок в запрос как минимум 2:

    1. И (ВЫБОР

    КОГДА ДоговорРеализации.ДатаОплаты = ДАТАВРЕМЯ(1, 1, 1, 0, 0, 0)

    ТОГДА ВЫБОР

    КОГДА ДоговорРеализации.ДатаДокумента = ДоговорРеализацияКО.ДатаДокумента

    ТОГДА ДоговорРеализации.Регистратор ИНАЧЕ ДоговорРеализации.ДатаДокумента КОНЕЦ

    ИНАЧЕ ВЫБОР

    КОГДА ДоговорРеализации.ДатаОплаты = ДоговорРеализацияКО.ДатаОплаты

    ТОГДА ДоговорРеализации.Регистратор ИНАЧЕ ДоговорРеализации.ДатаОплаты КОНЕЦ

    КОНЕЦ)

    2. ГДЕ

    ВзаиморасчетыСКонтрагентамиОстаткиИОбороты.СуммаУпрНачальныйОстаток И ВзаиморасчетыСКонтрагентамиОстаткиИОбороты.СуммаУпрКонечныйОстаток > 0

    Reply
  31. mxm2

    (31) 20tanush, Как-то не очевидно, что в приведенных фрагментах есть ошибки. Логику запроса — вижу, а вот ошибок — нет. Ткните, как говорится, носом.

    Reply
  32. 20tanush

    Да, на вид все вроде очевидно. Но конструктор запроса спотыкается на этих местах.

    В 1. конструкция И (Выбор…) Неверные параметры «И»

    И (<<?>> Выбор…) 

    Во втором: получаю вот такую ошибку: «Операция не разрешена в предложении ГДЕ

    <<?>>ВзаиморасчетыСКонтрагентамиОстаткиИОбороты.СуммаУпрНачальныйОстаток И ВзаиморасчетыСКонтрагентамиОстаткиИОбороты.СуммаУпрКонечныйОстаток > 0″
    Reply
  33. 20tanush

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

    Reply
  34. mxm2

    (33) 20tanush, во втором случае следует читать ВзаиморасчетыСКонтрагентамиОстаткиИОбороты.СуммаУпрНачальныйОстаток <=0 И ВзаиморасчетыСКонтрагентамиОстаткиИОбороты.СуммаУпрКонечныйОстаток > 0,

    Видимо «<=» — «съел» редактор, в самом тексте обработки все в порядке. В основном тексте — это уже исправлено. Спасибо.

    Reply
  35. nucha

    Актуальный и доходчивый алгоритм. Хотя http://infostart.ru/public/262300/ быстрее в 3 раза.

    Reply
  36. Vit_Kherson

    Вопрос к автору или тем кто скачал. (Конфигурация УТ 10.3)

    1.Тут как-то возвраты учитываются?

    2.Если да, то если в документе ВозвратОтПокупателя в табличной части указан документ РеализацияТоваровиУслуг по которому был Возврат, то будет ли это учитываться как уменьшение долга по указанной Реализации? Или все возвраты учитываются как погашение самого старого долга?

    Reply
  37. mxm2

    (37) Возвраты учитываются как уменьшение суммы долга контрагента по конкретному договору (не по реализации, которая указана в ТЧ возврата)

    Reply
  38. 028

    здесь учитывается ввод начальных остатков: Расчеты с покупателями и заказчиками (счета 1210, 3510)?

    Reply

Leave a Comment

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