Как установить цену у сборки товаров в 1С: Розница




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

4 Comments

  1. leks88

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

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

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

    Reply
  2. oldcopy

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

    Скажем, кальмар на развес подорожал, но при этом старый приход практически весь распродан, а фасованные еще остались и есть желание их быстрее распродать. По предложенной схеме их цена вырастет, что не всегда хорошо, особенно в продуктовом сегменте.

    Мы сделали иначе, доработали документ Сборка товаров чтобы он при проведении формировал документ Установка цен в котором как раз формируется цена на полученный товар, также к Номенклатуре добавили связанный справочник — Спецификации, теперь при выборе товара в документ сборки табличная часть с комплектующими заполняется автоматически, также сразу учитывается необходимый уровень наценки за работу по комплектации.

    Reply
  3. altmf

    (2)Замечание интересное, но:

    1. Разве описанный вами кейс не имеет место в любом случае, если не используется партионный учет? Кроме того, можно ведь до момента продажи всех уже расфасованных колец не проводить установку новых цен расфасованных колец.

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

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

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

    Reply
  4. oldcopy

    (3) 1. Имеет. Партионный учет и продуктовая розница — вещи вообще трудносочетаемые. Я к тому, что привязывать цену одного товара к цене другого товара таким не совсем явным образом не есть хорошо. Поэтому мы и перешли на установку цен в момент сборки. В этом случае труднее сделать что-то не так.

    2. Вариант со спецификациями хорош тем, что позволяет автоматически производить комплектацию с минимумом действий со стороны персонала, если подобного товара много, то выигрыш становится ощутимым. Хотя пример с кальмаром тут плох, весовой товар вообще не надо фасовать через сборку. Достаточно купить весы с печатью этикеток и просто расфасовать с их помощью. И продавать далее как весовой.

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

    Reply

Leave a Comment

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