Деноминация




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

17 Comments

  1. &rew

    5sm это цена до деноминации или после? А если серьезно, непонятно одно (эс). 1с не создало никаких «типичных» механизмов кастрации?

    Reply
  2. Gladkov_Anton

    (1) &rew, Беглый осмотр интернета показал, что типовая обработка была только для 7.7

    Reply
  3. gubanoff

    Не раскрыта тема, что эта обработка — не панацея и решение всех проблем деноминации. Если у вас в конфигурации нет копеек в суммах (для начала), то и обработка не поможет. Это я про РБ на всякий случай, если тут вдруг какая-то другая деноминация имеется ввиду.

    Вот тут тема раскрывается чуть глубже

    Reply
  4. Gladkov_Anton

    (3) gubanoff, Да, конечно, это не таблетка от всего на свете, а просто инструмент, который можно использовать при решении проблемы 2016 года

    Reply
  5. Xershi

    А какой смысл в обработке, если проще курс поставить 1 июля в 1, а до первого в 0,0001 или кратность изменить на 10000.

    Reply
  6. Gladkov_Anton

    (5) Xershi, Изменение курса в регистре сведений «Курсы валют» никак не отразится на остатках регистров накопления и ресурсах других регистров сведений.

    Reply
  7. Xershi

    (6) все верно. Они и не должны меняться. У нас же курс меняется!

    Reply
  8. Gladkov_Anton

    (7) Xershi, Нет, меняется не только курс, но все финансовые показатели выраженные в национальной валюте.

    В том числе цены, остатки на счетах, учетные цены товаров и т.д.

    Reply
  9. Xershi

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

    Reply
  10. kiba

    Отличное решение для небольших баз. Нужно правда понимать что после данной обработки из-за округление слегка «поедут» остатки регистров бухгалтерии и накопления и нужно будет эту проблему решать. А вот для больших баз применение данной обработки под вопросом. Например на нашей базе УПП за 8 лет обработка всех нужных регистров будет исчисляться сутками (проверено).

    Reply
  11. Gladkov_Anton

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

    Производительность можно наращивать запустив данную обработку в нескольких сеансах одновременно.

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

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

    Reply
  12. gubanoff

    (11) в процессе деления на 10000 теряется точность. Списывали, например, какой-то материал 100 раз по 90 рублей. Списали за год 100 * 90 = 9000 рублей. Делим все на 10000, получаем что списывали весь год по 0 руб 0 коп, следовательно остается остаток 90 коп., которого не должно было быть по идее. Да, этот остаток можно списать корректировочно проводкой, но ведь это неправильно. Корректировочная проводка нужна только для списания разниц, возникших при делении сальдо (а не всех операций) на 10000.

    Reply
  13. Gladkov_Anton

    (12) gubanoff, Данная обработка работает с остатками, а не с оборотами.

    Решение о необходимости делать обработку, которая умеет деноминировать обороты пока не принято

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

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

    Если кто то облает нормативкой, или ссылками на нее — прошу делиться. Будем думать — будем делать.

    Reply
  14. gubanoff

    (13) Gladkov_Anton, нормативки пока нет

    Reply
  15. pt_olga

    до сих пор есть только Поставновление Минфина от 22.04.16

    http://www.minfin.gov.by/upload/accounting/acts/postmf_220416_27.pdf

    Reply
  16. Slypower

    Как данную обработку запустить на 1С:Предприятие 8.2 (8.2.17.157) редакция 1.6.49.5?

    Пишет:

    {Обработка.Деноминация.Форма.Форма.Форма(2,2)}: Ожидается оператор препроцессора
    #<<?>>Область ОсновнойФункционал
    {Обработка.Деноминация.Форма.Форма.Форма(199,2)}: Ожидается оператор препроцессора
    #<<?>>КонецОбласти
    {Обработка.Деноминация.Форма.Форма.Форма(201,2)}: Ожидается оператор препроцессора
    #<<?>>Область Интерфейс
    {Обработка.Деноминация.Форма.Форма.Форма(376,2)}: Ожидается оператор препроцессора
    #<<?>>КонецОбласти

    Reply
  17. Slypower

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

    Reply

Leave a Comment

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