Отрицательные остатки на счете 41 и создание прихода (Бухгалтерия 3.0)




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

41 Comments

  1. ben_art

    UPD 16.05.2014

    теперь обработка регистрируется справочник внешние обработки. Для удобства рекомендую размещение ставить раздел «покупкиПродажи»

    Reply
  2. Татьяна_69

    вопрос — «Позволяет также создать документ поступления» — создается документ Поступление товаров и услуг или Оприходование товаров???

    если Поступление — надо какого-то контрагента подставлять?

    Reply
  3. ben_art

    Поступление

    Reply
  4. ben_art

    (2) Татьяна_69, Поступление, если надо можно переделать под любой другой документ схожей структуры. Возможность выбора контрагента есть.

    Reply
  5. makas

    Обработка ГТД и Страну происхождения подбирает?

    Reply
  6. ben_art

    (5) makas, К сожалению нет. так как у меня нет базы с гтд. Да и товар с гтд в минус не должен уходить.

    Reply
  7. Vadim75

    Спасибо за полезные обработки. Скачал вашу первую обработку (со себестоимостью). Одна проблема — при добавлении данных в табличную часть Товары, ранее созданного документа поступления по данному поставщику вылетает ошибка (во вложенном файлике). Подскажите, пожалуйста. А так несомненно + за работу.

    Reply
  8. ben_art

    (7) Vadim75, Странно у меня такого не было. На днях попробую помочь

    Reply
  9. Vadim75

    (8) спасибо большое, будем ждать. Тестировали на релизе Бухгалтерия предприятия 3.0 (3.0.37.37)

    Reply
  10. ben_art

    (9) Vadim75, к сожалению у меня только 3.0.34.18

    ошибку воссоздать не удалось

    Reply
  11. pashamix

    А по НДС есть разбивка?

    Reply
  12. ben_art

    (11) pashamix, Обработка просто анализирует 41 счет находит документы движения и пытается закрыть эти минуса новым поступлением. Если в 41 счете у Вас товар разбивается то и обработка разобьёт

    Reply
  13. Vadim75

    (10) Проблема видимо нет в релизе БП 3.0, а в релизе 1С:Предприятие 8.3, у меня используется (8.3.5.1383).Может посмотрите и выложите здесь обновление, очень необходмимо. Спасибо за понимание.

    Reply
  14. ben_art

    (13) Vadim75, К сожалению у меня сейчас вообще нет базы в которой можно было проверить.

    Не могли бы Вы проверить что возвращает функция «Найти поступление()».

    скорей всего ничего.

    Reply
  15. Vadim75

    (14) функция «Найти поступление() ничего не возвращает. Что посоветуете?

    Reply
  16. ben_art

    попробуйте скопировать запрос в консоль запросов и проверить в ручную

    там в условиях отборы по дате , организации и складу ещё коментарий

    Запрос = Новый Запрос;
    Запрос.Текст =
    «ВЫБРАТЬ
    | ПоступлениеТоваровУслуг.Ссылка
    |ИЗ
    | Документ.ПоступлениеТоваровУслуг КАК ПоступлениеТоваровУслуг
    |ГДЕ
    | ПоступлениеТоваровУслуг.Дата = &Дат
    | И ПоступлениеТоваровУслуг.ПометкаУдаления = ЛОЖЬ
    | И ПоступлениеТоваровУслуг.Организация = &Орг
    | И ПоступлениеТоваровУслуг.Склад = &Скл
    | И ПоступлениеТоваровУслуг.Контрагент = &Пост
    | И Выразить(ПоступлениеТоваровУслуг.Комментарий как строка(24)) В (&Ком)»;
    Запрос.УстановитьПараметр(«Дат», НачалоМесяца(Дат));
    Запрос.УстановитьПараметр(«Орг», Орг);
    Запрос.УстановитьПараметр(«Пост», Пост);
    Запрос.УстановитьПараметр(«Скл», Скл);
    Запрос.УстановитьПараметр(«Ком», «#СозданоБэтменом»);
    Результат = Запрос.Выполнить();
    ВыборкаДетальныеЗаписи = Результат.Выбрать();

    Показать

    точно могу сказать что коментарий создаваемого и искомого документов не совпадает, замените И Выразить(ПоступлениеТоваровУслуг.Комментарий как строка(24)) В (&Ком)»;

    на И ПоступлениеТоваровУслуг.Комментарий подобно &Ком

    и в параметрах укажите тот коментарий который в документе.

    Ещё проверьте есть ли реализациях и посутплениях поле склад и организация.

    Reply
  17. Vadim75

    (16) все сделал как написали. Проблема, что функция Найти поступление() возвращает — ВыборкаИзРезультатаЗапроса (в 1 прикрепленном файлике). Потом пытался через разименование ссылки обращаться, тогда получаю значение документа поступления (в 2 прикрепленном файлике) Как посоветуете поступить?

    Reply
  18. Vadim75

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

    Reply
  19. ben_art

    думаю надо будет воспользоваться фун-цией ЭтоНовый()

    на выходных попробую найти бэкап и во всем разобраться

    Reply
  20. Vadim75

    (19) огромное спасибо, будем ждать от вас новой информации.

    Reply
  21. vch8282

    Скажите, цену продажи может брать из отчета о розничных продажах, можно доработать .чтобы брала цену товара от туда ?

    Reply
  22. ben_art

    (20) Vadim75,

    Я наконец разобрался, во всем виной моя невнимательность.

    Вам надо в функции найтипоступление() заменить все начиная с запрос усатновитьПараметр

    на

    Запрос.УстановитьПараметр(«Дат», Дат);

    Запрос.УстановитьПараметр(«Орг», Орг);

    Запрос.УстановитьПараметр(«Пост», Пост);

    Запрос.УстановитьПараметр(«Скл», Скл);

    Запрос.УстановитьПараметр(«Комментарий», «#Здесь бэл БЭТМЕН»);

    Результат = Запрос.Выполнить();

    ВыборкаДетальныеЗаписи = Результат.Выбрать();

    Пока ВыборкаДетальныеЗаписи.Следующий() Цикл

    ОбъектСсылка = ВыборкаДетальныеЗаписи.Ссылка;

    ПОбъект = ОбъектСсылка.ПолучитьОбъект();

    Сообщить(«Открыто: «+ОбъектСсылка);

    Возврат ПОбъект;

    КонецЦикла;

    Возврат Неопределено;

    Reply
  23. ben_art

    (21) vch8282, чуть позже доработаю, чтоб брала.

    Reply
  24. Vadim75

    (22) теперь появляется ошибка при добавлении товара в уже ранее созданный документ (скрин прикреплен)

    Reply
  25. ben_art

    (24) Vadim75, отправьте пожалуйста мне в почту ar-bam@mail.ru обработку что-то я не понимаю о чём вы(

    Reply
  26. Vadim75

    (25) отправил)).

    Reply
  27. Vadim75

    (25) По поводу описанной ошибки, там глюк, после добавления товара в уже созданный документ, при записи документа выполняется процедура ПриСозданииНаСервере() (ФормаДокументаОбщая

    ПоступленияТоваровУслуг)

    Ошибка выскакивает для релиза БП 3,039,56 — последний на данный момент.

    Изменений на форму не вносил, возможно у вас старый релиз. (обработку ранее вам высылал по почте)

    Reply
  28. ek.kuznetsova

    Второй вариант с ценой продажи работает отлично!!! СПАСИБО)))

    Бухгалтерия предприятия, редакция 3.0 (3.0.39.60)

    Reply
  29. nar-79

    Добрый день.

    Скачала второй вариант с продажной ценой.

    После заполнения пишет: цена не найдена «наименование номенклатуры»

    Подскажите из-за чего такое может быть и можно ли исправить?

    Reply
  30. ben_art

    (29) nar-79, Точно сказать не могу , но может документ с отрицательным остатком не тот. Делал только под реализацию

    Reply
  31. megaalex

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

    скачал обе, ошибка в итоге при создании прихода «Преобразовние к типу Число не может быть выполнено».

    похоже, что нужен фильтр по складу + наверное возможность заполнять по типу цен из справочника

    Reply
  32. IsiKosta

    есть по этой теме http://infostart.ru/public/276164/

    Reply
  33. 410225

    есть возможность брать гтд из отгрузки?

    Reply
  34. ben_art

    UPD 12.01.2016

    обЪединил в один файл , теперь есть выбор какую цену искать (себестоимость или цену продажи).

    Добавил возможность отбора по складу.

    после выполнения открывается форма списка документов для дальнейшего проведения документов в ручную.

    Reply
  35. ben_art

    (33) 410225, ГТД из отгрузки не берёт , так как это не правильно )

    Reply
  36. oazissk07@gmail.com

    Добрый день!выдает две ошибки. во вложении.Посмотрите, пожалуйста.

    Reply
  37. ben_art

    (36) oazissk07@gmail.com,

    1) эта ошибка возникает в случае если программа не смогла найти цену поступления или цену продажи

    либо у Вас нету поступления этого товара , либо в ТЧ этого документа нет цены продажи .

    Напишите какие документы у Вас в списке.

    2) Создайте контрагенту (поставщику) основной договор. Можно конечно вынести выбор договора на форму , но я решил не нагромождать её.

    Reply
  38. cj512

    Косяки….

    1. Если включен партионный учет, то субконто2 — партии, а не склады (запрос накладывает отбор на субконто2)

    2. Ошибка в открытии документа Поступления, зачем-то открывается форма списка

     Форма = ПолучитьФорму(«Документ.ПоступлениеТоваровУслуг.Форма.ФормаСписка»,П);
    Форма.Открыть();
    

    Reply
  39. ben_art

    (38) cj512, Да вы правы , если партионный учет то субконто разные. если Вам это необходимо могу поправить.

    Форма списка открывается так как, по задумке, должны создаваться несколько документов(на каждый склад)

    Правда в обычной бухгалтерии дело в настройке «учет по складам»

    Reply
  40. gvozditut

    Здравствуйте купил вашу обработку 2 проблемы

    1 После нажатия кнопки заполнить ничего не происходит

    2 Просит Основной договор контрагента хотя он проставлен

    Reply
  41. ben_art

    (40) gvozditut, Добавил на форму реквизит «основной договор»

    и процедуру при изменении поставщика подставляется основной договор

    Reply

Leave a Comment

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