<?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='\
Ликвидность я так понял это оборачиваемость в месяц, но очень грубая. В идеале для расчета оборачиваемости должен вычисляться среднемесячный остаток, а не просто браться конечный остаток.
У Вас инструмент для думающего менеджера.
Чаще применяется более топорный способ: есть на остатке на конец периода, был на начало периода, нет продаж в периоде, первое поступление было раньше начала периода — вот он неликвид. Такой способ лучше подходит для людей которые не хотят, не умеют или не имеют времени думать. А таких большинство. Во всяком случае по моим наблюдениям:(
С таким методом
тоже думать и смотреть надо. Видел не раз делали колонку в отчетах под названием «лежаки», те позиции номенклатуры по которым не было движений. Дальше уже фантазия автора по раскрашиванию в зависимости от срока «неликвидности» или еще что-нибудь. Удобнее же когда сразу в глаза бросается. Идеи принимаются и обсуждаются.
(1) windows98a,
Таким способом неликвид не скоро найдется. При такой аналитике об оперативной работе с неликвидом речи не может быть.
(2) kostyaomsk,
По моему опыту подстраивание системы под 1-2% номенклатуры неэффективно, пусть даже и неликвидной. А если у вас 30-40% неликвида, то проблема точно не в отсутствии раскрасок!
Всплыла у меня логическая ошибка: не берутся позиции с нулевым остатком — явные кандидаты на дефицит. Ближайшее время поправлю. Еще хочу добавить серии и в детализации добавить количество дней отсутствия товара на складе помесячно.
Все-таки нужна ли колонка, показывающая сколько дней лежит товар?
неликвид, потому что экономика неплановая, перепроизводство ненужных товаров, а кому-то может они нужны — информации не хватает. Вон в кап.странах апельсины уничтожают, чтобы не продавать по дешевой цене — это уже не нормально. Отдай их нуждающимся — зачем уничтожать? Что-то с такой экономикой не то..
(4) kostyaomsk,
Честно говоря, я ценностью и объективностью этого показателя не проникся, в отличии отПервойСистемы . Для меня это попытка круглое засовывать в квадратное. Считаю, что эту информацию нужно смотреть не в колонке, а в разрезе документов приходов. Возможно, со временем переосмыслю и добавлю.
(6) интересные решения.
обновил версию, подробности в описании
Как-то забыли в отчете про розницу… Операции в НТТ, например, не формируют движений по регистру ТоварыНаСкладах. ИМХО, логичней было бы строить запрос по остаткам на основе данных регистра накопления ПартииТоваровНаСкладах. В этом регистре хранятся остатки по всем складам в том числе розничным и НТТ.
Периодичность расчета ликвидности жестко задана в месяцах. А если регулярность поставок измеряется неделями, например? Как выявить неликвид в интервале, меньшем месяца?
Отборы, скорее всего надо было сделать универсальными, хотя бы отбор по номенклатуре. Зачастую в большой номенклатурной группе требуется анализ лишь по нескольким проблемным подгруппам. Делать отдельные отчеты для каждой подгруппы?
И в заключении хотел бы отметить, что анализ не|ликвидности, корректнее было бы производить на основе показателей оборачиваемости товаров, которых в отчете и в помине нет.
(9) premier,
Спасибо за конструктивную критику, давайте обсудим:
В НТТ товары откуда попадают? Поставщик товары возит напрямую в НТТ? Не представляю себе НТТ, для которой строится такая аналитика по неликвидам — имхо разрыв шаблона 🙂 У нас на серьезных предприятиях неликвид через одно место вычисляют, а вы хотите его в НТТ видеть — круто! Лично в моих серых буднях в НТТ такой аналитики никогда не ведется. В общем случае она ведется по некоторому центральному складу, с которого мы делаем расход на НТТ. И на этот центральный склад обычно возит поставщик товары. И аналитику корректнее делать по общему складу, имхо. Как я понял ситуацию, если мы формируем точку заказа по центральному складу у нас все цифры должны быть корректны.
И еще, я очень часто вижу проблемы с партиями на предприятиях — поэтому я пока против брать их в качестве основы.
Согласен, можно подумать. Отталкивался от месяца, т.к. неликвид у большинства смело вываливается за 6 месяцев, и детализация неделя-день — это пока суета на фоне имеющихся проблем.
Согласен, было бы удобно иметь, например «В списке из групп». Хочу сделать отбор по свойствам. Вы же не будете проблемную номенклатуру все время по папкам двигать — удобнее менять свойство, или категорию.
Поясните, что вы имеете ввиду под оборачиваемостью, которой в помине нет? А среднемесячный расход, а ликвидность — это не показатели?
Обновил, оттестил, наслаждайтесь 🙂
ХМ, а где хоть одно слово что это демо?
(12) lutikoff, приношу извинения, не обновил. код открыт, вы можете отключить «заглушку».
новую версию сегодня залью
Неплохо было бы в отборах сделать варианты «по группе из списка» «по списку» «не в группе из списка» и тд.
это касается как отбора номенклатуры, так и отбора складов
сейчас можно либо по одной папке в номенклатуре либо по всей
так же и по складам
несколько неудобно
И еще возможность исключить движения закупок и продаж товаров по выбранным контрагентам
Чтобы не учитывать продажи между собственными организациями
(14) Fenom, спасибо, учту в следующих разработках
Тут НТТ обсудили, вроде как анализ остатка идет через склад. А как быть если есть розничные магазина — АТТ. Очень важно выявить в каждом залежавшийся товар и в случае чего переместить в более активные магазины, либо просто на склад. В этой обработке никак нельзя добавить анализ розницы?
(17) sknarid,
У вас какая программа стоит на рознице: также УТ, Розница, Frontol… ? Есть центральная программа, хэд-офис, в которой собирается информация по движению товаров по розничным магазинам? Хорошо бы знать архитектуру информационной системы.
Если УТ или ККМ (Frontol, Штрих, …), которая выгружает отчеты по продажам в центральный офис, где стоит УТ10.3, тогда обработку можно использовать в текущем виде. Если что то другое — пишите, обмозгуем 🙂
Добрый день. Подойдет ли эта обработка для Комплексной автоматизации 1.1.44?
(19) Gallakr, проверка совместимости не проводилась. Если есть потребность, можем проверить.
что то я так и не понял как вывести отчет, чтобы хоть что то заполнил!
демо отключил
не понял — что значит используете демоверсию с ограничением?
скачал Работа с неликвидом и дефицитом 1.6.3