<?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='\
Идея хорошая. В нашей организации давно витала в воздухе идея учёта этого показателя. Только я, с Вашего позволения, немножко переделаю. Расчёт буду производить по формуле: отношение объёма продаж к средневзвешенному (а не к среднему) размеру дебиторской задолженности. Сложнее, зато точнее. Ведь начальная сумма деб. задолженности может быть погашена на следующий день, а конечная может возникнуть за день до окончания периода.
И ещё параллельно можно рассчитывать среднее число дней для сбора долгов. Оно равно числу дней в периоде делённому на оборачиваемость деб. задолженности в этом периоде. Обычно рассчитывается за год.
В общем наговорил много, а самого главного не сказал: плюс однозначно.
big60, если будете считать по отношению к средневзвешенной, это будет уже не период оборачиваемости, а какой-то Ваш личный параметр, причем весьма отдаленный от того, чем оперирует экономическая теория.
Спасибо, полезная штучка…
+
(2) Использование таких простых формул средних показателей в экономике — наследие времен ручных расчетов. Современные технологии позволяют делать намного более точные расчеты, так как времени для этого на компьютере затрачивается капля. В данном случае можно было не писать отчет….А сделать всё в екселе…
Нужно думать, а не повторять, тем более формулы, которые даже в СТАРЫХ учебниках по эк.теории, эконометрики и статистики указаны как простейшие и очень грубые.
(4) Грубость не в формулах, а в используемых приближениях. Так в теории среднее для расчета коэффициентов оборачиваемости надо считать так:
X1 / 2 + X2 + … + Xn / 2
——————————
n — 1
где n — количество отрезков, на которые делится анализируемый период, чем больше — тем точнее. А в наиболее часто применяемом приближении n берут равным 2 независимо от периода. Т.е. проблема не в формуле.
Период оборачиваемости имеет следующий экономический смысл — за какой период продается количество товара равное среднему остатку. А вот если вместо среднего взять средневзвешенное это будет число с туманным экономическим смыслом.
(5) так и получается, что наибольшая точность будет достигнута при максимальном уменьшении временного отрезка…Тут уж надо исходить из рациональности…Если товарооборот чрезвычайно интенсивен («продажа с колес»), тогда лучше использовать минутный интервал, иначе суточный….И естественно, оптимизированная формула будет выглядеть иначе… ведь несмотря на выбранный интервал от складского документа до другого складского остаток неизменен, поэтому можно сократить число вычислений…
Средневзвешенные показатели хороши для сравнения. В моей статье по дебиторке это расписано. У среднего показателя экономический смысл может и есть… Но с практической точки зрения — нет. Один этот показатель нам ничего не даёт. Он даст какую-то информацию только в сравнении с другими периодами или точками/складами. А в этом случае средневзвешенные показатели всё-таки лучше.
Полезность показателя должна быть не в простоте объяснения, чем он по сути является, а в применимости его для контроля за текущей ситуацией (скорее всего в комплексе с другими показателями)
Ещё один пример непростого для понимания, но широко используемого в практике показателя — тонно километр…
(5) причем среднехронологические остатки можно взять по нескольким формулам. Ведь если рассчитывать оборачиваемость, например, за год и если взять даже очень маленький момент времени (день), то даже день является не точкой, а периодом. и какой брать остаток: начальный или конечный?
Пусть у нас n периодов. Тогда можно взять
с 1-го периода по n конечные остатки,
с 1 по n остатки начальные,
1 – начальные, а со 2 по n конечные,
с 1 по n-1 начальные, n – конечные,
с 0 по n конечные,
с 1 по n+1 начальные.
Какую из формул считать правильной?
(7) Брать конечные или начальные абсолютно без разницы, т.к. конечный одного периода, это начальный следующего, а начальный и конечный остатки всего периода анализа в любом случае брать надо.
Т.е., к примеру, если анализируем 3 дня и бьем на куски по одному дню: Надо взять
X1 — начальный остаток 1-го дня
X2 — конечный остаток 1-го дня или начальный 2-го (пофиг, ибо равны)
X3 — конечный остаток 2-го дня или начальный 3-го (пофиг, ибо равны)
X4 — конечный последнего дня
n = 4, т.е. среднее = (X1/2 + X2 +X3 + X4/2) / 3
Можете еще и в середине дня значение брать, главное что-бы интервалы между измерениями равные были, но как правило брать периоды короче одного дня нет смысла, если утром что-то было, а вечером его уже нет, то период оборачиваемости получится пол дня, что довольно точно отражает действительность.
Единственное дополнение к формуле которое я использую, это не суммирую нулевые значения, — но это для оборачиваемости товаров. Для расчета оборачиваемости дебиторки или кредиторки возможно этого делать не стоит.
И, кстати, говоря о средневзвешенных значениях, не указывать по какому параметру надо взвешивать — это беспредметно.
у меня почему-то не работает выбор покупателя. вместо этого выбор только по группе «ценные бумаги». зашла в конфигуратор, поменяла в модуле счет 62 (векселя) на 36 (покупатели).
выбор работает но отчет не формирует — все пусто.
помогите.
спасибо
(9) Посмотрите в плане счетов у сч.36 есть субконто? Оно (одно из них) называется Контрагенты?
Откройте конфигуратор, выберите пункт меню Конфигурация — Открыть конфигурацию. В дереве метаданных откройте ветвь «Планы счетов», два раза щелкните на пункте Основной. Посмотрите, какой(ие) вид субконто значится у счета 36? Запомните его название. В дереве метаданных откройте ветвь «Виды субконто», найдите субконто, приписанное к сч.36, щелкните на него два раза, в форме Свойства посмотрите тип значения этого субконто. Если справочник называется не «Контрагенты», то вам надо будет в модуле отчета заменить и это слово на название вашего справочника.
Или сделайте проще: в строке ТЗ.НоваяКолонка(«Наим»,»Справочник.Контрагенты»); удалите .Контрагенты.
Спасибо, убрала в строке ТЗ.НоваяКолонка («Наим»,»Справочник.Контрагенты»); значение .Контрагенты.
заработало.
спасибо огромное.
еще вопрос: в сформированной таблице колонки «продажи» не заполняются.
и если выбирать несколько контагентов, то в колонке «оборачиваемость, дней» — показивает только общия показатель в строке «ИТОГО»
Сформируйте оборотно-сальдовую ведомость по сч.36 за тот период, за который формируете отчет по оборачиваемости. Посмотрите, есть ли дебитовый оборот у тех нескольких контрагентов, которых вы выбираете в отчете? Колонка «Продажи» заполняется по данным дебета сч.36. Если у контрагента нет продаж, то и оборачиваемость у него нулевая.
Правда если у всех попавших в отчет продаж не было, то и итоговая цифра по оборачиваемости должна быть равна нулю.
Интересно.
А для 1С8 такой отчёт есть у кого нибудь?