Заполнение встречного выпуска для УПП (обработка)




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

12 Comments

  1. kapustinag

    Уточните, пожалуйста — она что, по каждой ошибке типа «Не выполнено распределение по переделам для затрат» пишет в этот регистр сведений? Так ведь некоторые такие ошибки могут быть из-за недонастроенного регистра сведений «Встречный выпуск продукции…», а некоторые — из-за действительно неверно оформленных первичных документов.

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

    Reply
  2. kapustinag

    Или все-таки обработка дает пользователю выбрать, по каким ошибкам делать записи в регистр, а по каким — не делать?

    Не хватает подробностей в описании публикации, и/или скриншотов.

    Reply
  3. jefjef

    (2) kapustinag,

    Да, обработка просто фиксирует встречные выпуски с нулевым переделом. Те, по которым возникают ошибки. И позволяет затем рассчитать себестоимость, распределить затраты. Обработка не предназначена для гуру в настройках встречного выпуска, если есть желание отслеживать и настраивать встречные выпуски руцями — для этого в 1С вся отчетность уже имеется. Но если встречных выпусков за период зафиксированы десятки/сотни, а выковыривать их вручную и разбираться с каждым в отдельности нет вожделения — то можно воспользоваться этой обработкой. Я искал что либо подобное по всем интернетам, ничего путнего не нашел, и поэтому написал сам. Никаких настроек в обработке нет, просто указывается проведенный не рассчитавшийся документ «расчет себестоимости выпуска», она лохматит его движения и фиксирует встречные выпуски. Все просто, как грабли.

    Reply
  4. jefjef

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

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

    Reply
  5. гаврюша

    Подскажите, пожалуйста: чтобы встречный выпуск за предыдущие периоды не тянулся в текущий расчет себестоимости необходимо просто очистить полностью этот регистр или как?

    Reply
  6. Instructor

    Всё работает — код простой и со вкусом. Благодарю.

    Reply
  7. jefjef

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

    Моя обработка спасает не всегда!

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

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

    Например электроцех выпустил электроэнергию. Она пошла распределяться как ОПЗ по подразделениям и благодаря кривым настройкам способов распределения часть упала на электроцех. Получилось электроэнергия сделана из электроэнергии. Программный встречный выпуск. С таким обработка борется.

    Умышленные встречные выпуски — это когда бухгалтер провел требование накладную и отчет производства на одно и то же. Например колбасный цех получил мясо от бойни, весь месяц выпускал колбасу, а потом часть мяса отдал в магазин на реализацию. Бухгалтер проводит отчет производства на мясо по колбасному цеху и все. Такой встречный выпуск моя обработка не вылечит, тут только искать отчет производства, который сделал мясо из мяса и ругаться с бухгалтерией. В таких случаях только анализ распределения производственных затрат поможет.

    Reply
  8. mrWatson

    (7) jefjef, и как он тогда оценит электроэнергию? да он ругаться не будет, но какой суммой оценит?

    Reply
  9. mrWatson

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

    Reply
  10. jefjef

    (8)

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

    Насчет вопроса «и как он тогда оценит электроэнергию? да он ругаться не будет, но какой суммой оценит?» Поскольку все оценки производятся модулем «ПроцедурыРасчетаСебестоимостиВыпуска» то оценит по тем затратам, какие туда упадут и по той базе распределения, которая для них задана.

    Обработка сия тупо фиксирует все нераспределенные расчетом затраты в регистре «Встречный выпуск» во всех возможных вариациях и уже при следующем расчете к ним применяются особые алгоритмы распределения — а ля итерационный расчет затрат встречного выпуска и т.п.

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

    Однако!

    Надо в расчет себестоимости добавлять выполняемые действия «Распределение косвенных затрат по переделам». То есть не один раз это делать, а два-три, может и больше. Тогда рассчитает, может быть какие-то копейки в НЗП и останутся, но в целом рассчитает.

    Что плохо: добавление в расчет действия «Распределение косвенных затрат по переделам» увеличивает время расчета практически вдвое. И сколько таких действий будет добавлено, во втолько раз и увеличится время расчета. На больших базах это неприемлемо. Когда у меня расчет стал колбасить по три часа пришлось искать новые пути решения.

    Reply
  11. jefjef

    По новым путям решения.

    Для себя я встречные выпуски поборол раз и навсегда. Дешево и сердито, скромно и со вкусом. Потому сюда давно и не заглядывал. Наверное склепаю отдельный пост по этому вопросу, поскольку тема непростая и в свое время вразумительного ответа для себя нигде не нашел, пришлось набивать свои шишки.

    Reply
  12. jefjef

    Вот тут запилил новую публикацию на эту тему http://infostart.ru/public/566357/

    (пока на модерации)

    Reply

Leave a Comment

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