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




Принцип обмена данными из 1С с сайтом (на MySQL) и выдачи (публикации) этих данных по запросу.
PHP-Скрипт автоматической загрузки данных из файла данных в формате CSV в базу данных сайта работающего на WordPress.

В продолжение моей темы: 1С:Альфа-Авто Автосалон Автосервис: обмен с сайтом.
С помощью данного скрипта можно загружать в автоматическом режиме, по расписанию, данные сервисных книжек (ремонтов авто) из 1С:Альфа-Авто Автосалон Автосервис.
Также можно загружать данные в ручном режиме: для этого делается скрытая страница, где размещается специальная кнопка.
Комментарии размещенные внутри скрипта разъяснят логику и порядок действия.
Комментарии с "/////    echo" использовались для отладки.
Дополнительно создана таблица для журналирования результатов загрузки данных.
Скрипт включает в себя защиту от SQL инъекций (думаю безопасность соблюдена в полной мере).
В кратце:
1. Пишется скрипт, который запускает этот.
2. Создается регламентное задание в WordPress, по которому запускается скрипт из п.1. 
3. Этот скрипт осуществляет проверку на существование файла обмена в папке.
4. Если данные не новые, загрузка не производится.
5. Если данные новые, очищается таблица сервисных книжек.
6. Загружаются новые данные.

Собственно сам скрипт:

<?php // Полная загрузка сервисных книжек, создан 2026-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 не будет опубликован. Обязательные поля помечены *