Анализ затрат и доходов




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

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

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

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

    К сожалению в ближайшее время скриншотов не будет, так как почему то «сервер не найден», а я в отпуск ухожу

    Reply
  2. bogdan_king

    В отчете у тебя есть ТабДокумент.ПроверитьВывод(ОблСтрока); так вот если никакого принтера нет, она вызывает исключение, поэтому ее нужно как обвязать Попыткой, или еще как.

    Reply
  3. zzerro

    Не встречал такого раньше… Вообще то какая разница по идее есть принтер или нет. Но в принципе тогда нужно весь цикл включать в попытку

    Reply
  4. popkovsf65

    А чё про 23, 25 счета забыл?

    Reply
  5. zzerro

    Про 23 и 25 счета не просили. Если нада будет, то и их сделаю

    Reply
  6. valkovaolga

    +5

    Reply
  7. witch

    Добавьте если можно в разрезе подразделений))

    Reply
  8. zzerro

    (7) Я подумаю над вашим предложением…

    Reply
  9. witch

    Подумайте пожалуйста,это бы очень очень облегчило мне жизнь))

    Reply
  10. zzerro

    Обновил отчет. Появилась новая закладка по затратам на 20 и 26 счетах. Для других счетов группировки по подразделениям сделать не получается, так как у них нет такого субконто в плане счетов.

    Reply
  11. gutentag

    (4) Отчет очень понравился, но есть пара замечания/пожелания. Большая просьба: добавьте группировки

    1. «группировать по счетам» или выделить отдельно расходы собираемые на счете 91.02

    2. добавьте, пожалуйста, затраты по 25-счету и 23-счету. но т.к. эти счета могут закрываться в 20, то в этом случае надо исключать проводки типа д.20-к.25(23)

    —-

    Ошибка в отчете: Если счет 26(25 и др.) закрывается в счет 20, то отчет показывает эти проводки/суммы = возникает ошибка.

    Reply
  12. zzerro

    (11) Я так понимаю, что нужно исключить проводки Дт20 — Кт26,25,23, которые выходят при выводе данных по 20му счету?

    Reply
  13. witch

    очень хорошо сделано, еще раз спасибо огромное)))

    Reply
  14. zzerro

    (11) Выкладываю версию отчета 1.1 где учтены ваши пожелания

    Reply
  15. gutentag

    (12) Тут нужна отдельная кнопка, типа «Печать только «полные затраты» по 20-счету», или выводить на экран/печать отдельный отчет показывающий все собранные затраты по счету 20.

    —-

    На мой взгляд, вопрос не однозначный(извините, если ввел в заблуждение):

    1. Если анализируем расходы, как это задумывалось изначально, тогда, я лично считаю, что расходы относимые Дт20 — Кт26,25,23 надо исключить.

    2. Если надо смотреть счет 20 для анализа [тут следовало бы поставить фразу «полная производственная себестоимость»но это не совсем корректное выражение]себестоимости продукции/услуг/работ, тогда надо делать два отчета а) по 20-счету с проводками Дт20 — Кт26,25,23

    б) отчет по распределению затрат (что и куда списывается с Кт.26,25,23, где для каждого счета свои «таблички распределения»)

    ——

    ЗЫ. На всякий случай, могу прислать свой файл(без каких то дальнейших обязательств) — пример ведомости по распределению затрат по со счета 25, тогда пишите свой адрес мне в личку.

    Reply
  16. gutentag

    …А группировка по счета, лично для меня, — очень ценная вещь! Спасибо!

    Reply
  17. zzerro

    В ближайшее время не будет времени дорабатывать проект, но с вопросами включения и исключения проводок Дт20 — Кт26,25,23 думаю можно что нибудь придумать… например с возмозможностью включения и исключения

    Reply
  18. zzerro

    Добавил флаг «Исключить проводки Дт 20 — Кт 23, 25, 26» — при установленном флаге обороты соответствующих проводок будут исключены из отчета.

    Reply
  19. edin

    А нельзя ли сделать чтобы периодичсность выводилась в колонку а не в строку?.

    Reply
  20. witch

    А можно адаптировать это для 1с 8.2?

    Reply
  21. mkhatemul

    Для Бухни 2.0 взлетел без переделок. Отлично !

    Reply
  22. kauksi

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

    Reply
  23. zhleonid8

    без скринов не солидно

    Reply
  24. elena_77

    Большое спасибо. Плюс+

    Reply
  25. extremehelp

    А будет ли версия для бух 2.0 на 8.2

    Reply
  26. zzerro

    (25) Вот в (21) сказали что работает на БП 2.0, и у меня тоже работает. Нужно просто открыть обработку в конфигураторе 8.2 и согласиться на конвертирование. После этого должно работать.

    Reply
  27. Alexbis2010

    У меня вылетает ошибка

    {Форма.Форма(944)}: Ошибка при вызове метода контекста (Выполнить): {(28, 4)}: Таблица не найдена «Справочник.ПрочиеДоходыИРасходы»

    <<?>>Справочник.ПрочиеДоходыИРасходы КАК ПрочийДоходРасход

    СтатьиЗатрат.Загрузить(Запрос.Выполнить().Выгрузить());

    по причине:

    {(28, 4)}: Таблица не найдена «Справочник.ПрочиеДоходыИРасходы»

    <<?>>Справочник.ПрочиеДоходыИРасходы КАК ПрочийДоходРасход

    Как от неё избавиться?

    Reply
  28. eryomenko

    Хороший отчет, спасибо. Без проблем сконвертировал для 8.2. Да, и хотелось бы видеть скрины до того как скачиваешь данный отчет.

    Reply
  29. zzerro

    (27) А что у вас за конфигурация? Видимо отсутствует справочник Прочие доходы и расходы.

    Reply
  30. zzerro

    (28) До них руки как-то не дошли, если не забуду, то сделаю

    Reply

Leave a Comment

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