Задав вопросы на форумах и не получив ни одного ответа, опросил бухгалтеров, и была поставлена следующая задача.
1. При проведении отображать информационное сообщение о том, что не заполнен номер ГТД, хотя должен.
2. При проведении отображать информационное сообщение о том, что не хватает остатка по текущему номеру ГТД.
Разумеется, можно использовать //infostart.ru/public/140232/ , но это спасёт, если не менять документы задним числом.
При перепроведении документов хотелось бы видеть такие ошибки.
Я открыл код БП 2.0, и вот что получилось.
1. Для БП 3.0 создаём общий модуль (на сервере).
Листинг:
Процедура ПроведениеДокументаСписанияПоСчетуГТД(Документ, ТаблицаПоТоварам, СодержаниеПроводки = "Списаны МПЗ") Экспорт
ТоварыПоНомерамГТД = Новый ТаблицаЗначений;
ТоварыПоНомерамГТД.Колонки.Добавить("Номенклатура");
ТоварыПоНомерамГТД.Колонки.Добавить("НомерГТД");
ТоварыПоНомерамГТД.Колонки.Добавить("СтранаПроисхождения");
ТоварыПоНомерамГТД.Колонки.Добавить("Количество");
ДатаДок = Документ.Дата;
Организация = Документ.Организация;
Проводки = Документ.Движения.Хозрасчетный;
// Формирование параметров отбора для запроса.
СписокНоменклатуры = Новый Массив;
СписокНомеровГТД = Новый Массив;
СписокСтранПроисхождения = Новый Массив;
Для каждого СтрокаТЧ из ТаблицаПоТоварам Цикл
Если НеУказанНомерГТД(СтрокаТЧ.НомерГТД,СтрокаТЧ.СтранаПроисхождения) Тогда
ОбщегоНазначенияКлиентСервер.СообщитьПользователю("Неверно заполнены данные по ГТД в строке "+СтрокаТЧ.НомерСтроки+"");
КонецЕсли;
Если ЭтоИмпортныйТовар(СтрокаТЧ.СчетУчета, СтрокаТЧ.НомерГТД, СтрокаТЧ.СтранаПроисхождения) Тогда
СписокНоменклатуры.Добавить(СтрокаТЧ.Номенклатура);
СписокНомеровГТД.Добавить(СтрокаТЧ.НомерГТД);
СписокСтранПроисхождения.Добавить(СтрокаТЧ.СтранаПроисхождения);
ТоварПоНомеруГТД = ТоварыПоНомерамГТД.Добавить();
ТоварПоНомеруГТД.Номенклатура = СтрокаТЧ.Номенклатура;
ТоварПоНомеруГТД.НомерГТД = СтрокаТЧ.НомерГТД;
ТоварПоНомеруГТД.СтранаПроисхождения = СтрокаТЧ.СтранаПроисхождения;
ТоварПоНомеруГТД.Количество = СтрокаТЧ.Количество;
КонецЕсли;
КонецЦикла;
Если СписокНоменклатуры.Количество() = 0 Тогда
Возврат;
КонецЕсли;
Запрос = Новый Запрос(
"ВЫБРАТЬ
| ХозрасчетныйОстатки.Субконто1 КАК Номенклатура,
| ХозрасчетныйОстатки.Субконто2 КАК НомерГТД,
| ХозрасчетныйОстатки.Субконто3 КАК СтранаПроисхождения,
| ХозрасчетныйОстатки.КоличествоОстатокДт КАК Количество
|ИЗ
| РегистрБухгалтерии.Хозрасчетный.Остатки(
| &Период,
| Счет = &СчетУчетаНомеровГТД,
| &Видысубконто,
| Субконто1 В (&СписокНоменклатуры)
| И Субконто2 В (&СписокНомеровГТД)
| И Субконто3 В (&СписокСтранПроисхождения)
| И Организация = &Организация) КАК ХозрасчетныйОстатки");
Запрос.УстановитьПараметр("Период", Документ.МоментВремени());
Запрос.УстановитьПараметр("Организация", Организация);
Запрос.УстановитьПараметр("СчетУчетаНомеровГТД", ПланыСчетов.Хозрасчетный.ГТД);
Запрос.УстановитьПараметр("СписокНоменклатуры", СписокНоменклатуры);
Запрос.УстановитьПараметр("СписокНомеровГТД", СписокНомеровГТД);
//ОбщегоНазначения.УдалитьПовторяющиесяЭлементы(СписокСтранПроисхождения);
ОбщегоНазначенияБПВызовСервера.УдалитьПовторяющиесяЭлементыМассива(СписокСтранПроисхождения);
Запрос.УстановитьПараметр("СписокСтранПроисхождения", СписокСтранПроисхождения);
ВидыСубконто = ПланыСчетов.Хозрасчетный.ГТД.ВидыСубконто.ВыгрузитьКолонку("ВидСубконто");
Запрос.УстановитьПараметр("ВидыСубконто", ВидыСубконто);
Остатки = Запрос.Выполнить();
ВыборкаОстатков = Остатки.Выбрать();
ТоварыПоНомерамГТД.Свернуть("Номенклатура,НомерГТД,СтранаПроисхождения", "Количество");
СтруктураПоиска = Новый Структура("Номенклатура,НомерГТД,СтранаПроисхождения");
ОтключитьКонтрольОстатков = Константы.ОтключитьКонтрольОтрицательныхОстатков.Получить();
Для каждого ТоварПоНомеруГТД из ТоварыПоНомерамГТД Цикл
СтруктураПоиска.Номенклатура = ТоварПоНомеруГТД.Номенклатура;
СтруктураПоиска.НомерГТД = ТоварПоНомеруГТД.НомерГТД;
СтруктураПоиска.СтранаПроисхождения = ТоварПоНомеруГТД.СтранаПроисхождения;
УчетноеКоличество = 0;
ВыборкаОстатков.Сбросить();
Пока ВыборкаОстатков.НайтиСледующий(СтруктураПоиска) Цикл
УчетноеКоличество = УчетноеКоличество + ВыборкаОстатков.Количество;
КонецЦикла;
КоличествоВПроводке = Мин(УчетноеКоличество, ТоварПоНомеруГТД.Количество);
Если КоличествоВПроводке < ТоварПоНомеруГТД.Количество Тогда
СтрокаНачалаСообщенияОбОшибке = "Для номенклатуры """+ СокрЛП(ТоварПоНомеруГТД.Номенклатура) + """ в табличной части ""Товары"" ";
СтрокаСообщения = "по счету ГТД определен остаток "+УчетноеКоличество+" ед. "+ТоварПоНомеруГТД.Номенклатура+" из необходимых "+ТоварПоНомеруГТД.Количество+" ед.";
ОбщегоНазначенияКлиентСервер.СообщитьПользователю(СтрокаНачалаСообщенияОбОшибке + СтрокаСообщения);
КонецЕсли;
КоличествоСписать = ?(ОтключитьКонтрольОстатков, ТоварПоНомеруГТД.Количество, КоличествоВПроводке);
КонецЦикла;
КонецПроцедуры // ПолучитьОстаткиПоНомерамГТД()
Функция ЭтоИмпортныйТовар(СчетУчета, НомерГТД, СтранаПроисхождения) Экспорт
Если НЕ ЗначениеЗаполнено(СтранаПроисхождения) или
СтранаПроисхождения = Справочники.СтраныМира.РОССИЯ или
НЕ ЗначениеЗаполнено(НомерГТД) Тогда
Результат = Ложь;
ИначеЕсли СчетУчета.ПринадлежитЭлементу(ПланыСчетов.Хозрасчетный.ТоварыНаСкладах) или
СчетУчета = ПланыСчетов.Хозрасчетный.ТоварыНаСкладах или
СчетУчета.ПринадлежитЭлементу(ПланыСчетов.Хозрасчетный.ТоварыВРозничнойТорговле) или
СчетУчета = ПланыСчетов.Хозрасчетный.ТоварыВРозничнойТорговле или
СчетУчета.ПринадлежитЭлементу(ПланыСчетов.Хозрасчетный.ТоварыПринятыеНаКомиссию) или
СчетУчета = ПланыСчетов.Хозрасчетный.ТоварыПринятыеНаКомиссию или
СчетУчета.ПринадлежитЭлементу(ПланыСчетов.Хозрасчетный.ТоварыВРозничнойТорговлеВПродажныхЦенахАТТ) или
СчетУчета = ПланыСчетов.Хозрасчетный.ТоварыВРозничнойТорговлеВПродажныхЦенахАТТ или
СчетУчета.ПринадлежитЭлементу(ПланыСчетов.Хозрасчетный.ПокупныеИзделия) или
СчетУчета = ПланыСчетов.Хозрасчетный.ПокупныеИзделия Тогда
Результат = Истина;
Иначе
Результат = Ложь;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция НеУказанНомерГТД(НомерГТД, СтранаПроисхождения) Экспорт
Если НЕ ЗначениеЗаполнено(СтранаПроисхождения) или
СтранаПроисхождения = Справочники.СтраныМира.РОССИЯ Тогда
Результат = Ложь;
ИначеЕсли НЕ ЗначениеЗаполнено(НомерГТД) Тогда
Результат = Истина;
Иначе
Результат = Ложь;
КонецЕсли;
Возврат Результат;
КонецФункции
2. В конец обработки проведения добавляем вызов:
ОбщийМодуль.ПроведениеДокументаСписанияПоСчетуГТД(ЭтотОбъект,ЭтотОбъект.Товары, "Реализация услуг");
Разберем на примере:
В первой строке я умышленно указал ГТД с остатком 5 вместо 10
Во второй строке не указывал совсем.
После проведения результат отображается на рисунке.
Вот таким образом мы решили проблему списания остатков по счёту ГТД.
Спасибо за внимание. Моя первая публикация, прошу прощения, если отнял ваше время :)