diff --git a/CHANGELOG.md b/CHANGELOG.md index f9ad581..3871e17 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,27 @@ --- +## 1.3.1.57 (2026-08-12) + +### РК_ЗагрузкаОстатков — понятная ошибка при Активно = Ложь + +- Текст исключения в `РК_ОбменСВнешнейБазой.НастройкиПодключения`: что включить «Активно» и что проверка health работает без флажка. +- Команды формы (подбор складов, загрузка, сопоставление, создание документов) показывают предупреждение вместо стека исключения. + +--- + +## 1.3.1.56 (2026-08-12) + +### РК_ЗагрузкаОстатков — создание документов ввода остатков + +- Реквизиты: `Организация`, `ПерезаписатьДокументы`. +- ТЧ: `ДокументВвода`, `ЗагруженоВДокумент`. +- Команда «Создать документы»: `ВводОстатковТоваров` (1 документ на склад, операция «собственные товары»), + только количество (без себестоимости — данных в API пока нет). +- Тег комментария: `РК_ПереносОстатков yyyyMMdd`; опционально удаление непроведённых документов волны. + +--- + ## 1.3.1.55 (2026-08-11) ### Добавлено diff --git a/VERSION b/VERSION index f228051..09b0584 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.3.1.55 +1.3.1.57 diff --git a/src/CommonModules/РК_ОбменСВнешнейБазой/Ext/Module.bsl b/src/CommonModules/РК_ОбменСВнешнейБазой/Ext/Module.bsl index b64749c..20c0dc2 100644 --- a/src/CommonModules/РК_ОбменСВнешнейБазой/Ext/Module.bsl +++ b/src/CommonModules/РК_ОбменСВнешнейБазой/Ext/Module.bsl @@ -2,6 +2,8 @@ #Область ПрограммныйИнтерфейс // Настройки подключения из элемента справочника РК_НастройкиПодключенияКВнешнейБазе. +// Для рабочих вызовов (остатки, склады) требуется «Активно = Истина». +// Проверка «Проверить» в карточке справочника намеренно не смотрит на этот флажок. // Функция НастройкиПодключения(Подключение) Экспорт @@ -12,8 +14,10 @@ Реквизиты = ОбщегоНазначения.ЗначенияРеквизитовОбъекта(Подключение, "АдресПодключения, Токен, Таймаут, Логин, Пароль, Активно, ИмяТекущейБазы"); - Если Реквизиты.Активно = Ложь Тогда - ВызватьИсключение "Подключение к сторонней базе отключено (Активно = Ложь)"; + Если Реквизиты.Активно <> Истина Тогда + ВызватьИсключение НСтр("ru = 'Подключение к сторонней базе отключено.'") + + Символы.ПС + НСтр("ru = 'Откройте карточку настройки, включите флажок «Активно» и запишите элемент.'") + + Символы.ПС + НСтр("ru = 'Проверка соединения («Проверить») работает и без этого флажка.'"); КонецЕсли; Адрес = СокрЛП(Строка(Реквизиты.АдресПодключения)); diff --git a/src/Configuration.xml b/src/Configuration.xml index b83e83c..718181c 100644 --- a/src/Configuration.xml +++ b/src/Configuration.xml @@ -62,7 +62,7 @@ Role.РК_ОсновнаяРоль - 1.3.1.55 + 1.3.1.57 Language.Русский diff --git a/src/DataProcessors/РК_ЗагрузкаОстатков.xml b/src/DataProcessors/РК_ЗагрузкаОстатков.xml index ed4ef0c..9af24a4 100644 --- a/src/DataProcessors/РК_ЗагрузкаОстатков.xml +++ b/src/DataProcessors/РК_ЗагрузкаОстатков.xml @@ -136,6 +136,74 @@ Auto + + + Организация + + + ru + Организация + + + + + cfg:CatalogRef.Организации + + false + + + + false + + false + false + + + ShowError + Items + + + Auto + Auto + + + Auto + + + + + ПерезаписатьДокументы + + + ru + Перезаписать документы + + + Удалить непроведённые документы волны перед созданием + + xs:boolean + + false + + + + false + + false + false + + + DontCheck + Items + + + Auto + Auto + + + Auto + + @@ -1307,6 +1375,78 @@ Auto + + + ДокументВвода + + + ru + Документ ввода + + + + + cfg:DocumentRef.ВводОстатковТоваров + + false + + + + false + + false + false + + + false + + DontCheck + Items + + + Auto + Auto + + + Auto + + + + + ЗагруженоВДокумент + + + ru + Загружено в документ + + + + + xs:boolean + + false + + + + false + + false + false + + + false + false + DontCheck + Items + + + Auto + Auto + + + Auto + +
Форма
diff --git a/src/DataProcessors/РК_ЗагрузкаОстатков/Ext/ObjectModule.bsl b/src/DataProcessors/РК_ЗагрузкаОстатков/Ext/ObjectModule.bsl index 376efa0..b24c5eb 100644 --- a/src/DataProcessors/РК_ЗагрузкаОстатков/Ext/ObjectModule.bsl +++ b/src/DataProcessors/РК_ЗагрузкаОстатков/Ext/ObjectModule.bsl @@ -113,10 +113,236 @@ КонецФункции +// Создание документов ВводОстатковТоваров по сопоставленным строкам (1 документ на склад). +// Себестоимость не заполняется (нет данных в API) — только оперативный учёт количества. +// +// Параметры: +// РежимТест - Булево - только подсчёт без записи +// +// Возвращаемое значение: +// Структура - СозданоДокументов, УдаленоДокументов, СтрокВДокументах, Пропущено, Ошибок, ТекстТега +// +Функция СоздатьДокументыВводаОстатков(РежимТест = Истина) Экспорт + + Результат = Новый Структура; + Результат.Вставить("СозданоДокументов", 0); + Результат.Вставить("УдаленоДокументов", 0); + Результат.Вставить("СтрокВДокументах", 0); + Результат.Вставить("Пропущено", 0); + Результат.Вставить("Ошибок", 0); + Результат.Вставить("ТекстТега", ""); + + Если Не ЗначениеЗаполнено(Организация) Тогда + ВызватьИсключение "Укажите организацию для документов ввода остатков"; + КонецЕсли; + Если Не ЗначениеЗаполнено(ДатаДокументовВвода) Тогда + ВызватьИсключение "Укажите дату документов ввода"; + КонецЕсли; + + ТекстТега = ТегКомментарияДокументов(); + Результат.ТекстТега = ТекстТега; + + СтрокиПоСкладу = СгруппироватьСопоставленныеСтрокиПоСкладу(); + Если СтрокиПоСкладу.Количество() = 0 Тогда + Возврат Результат; + КонецЕсли; + + Если ПерезаписатьДокументы И Не РежимТест Тогда + Результат.УдаленоДокументов = УдалитьПрежниеДокументыВолны(ТекстТега); + КонецЕсли; + + Для Каждого ЭлементСклада Из СтрокиПоСкладу Цикл + + СкладДок = ЭлементСклада.Ключ; + СтрокиСклада = ЭлементСклада.Значение; + Если СтрокиСклада.Количество() = 0 Тогда + Продолжить; + КонецЕсли; + + Попытка + Если РежимТест Тогда + Результат.СозданоДокументов = Результат.СозданоДокументов + 1; + Результат.СтрокВДокументах = Результат.СтрокВДокументах + СтрокиСклада.Количество(); + Продолжить; + КонецЕсли; + + Док = СоздатьДокументПоСкладу(СкладДок, СтрокиСклада, ТекстТега); + Если ЗначениеЗаполнено(Док) Тогда + Результат.СозданоДокументов = Результат.СозданоДокументов + 1; + Результат.СтрокВДокументах = Результат.СтрокВДокументах + Док.Товары.Количество(); + Для Каждого СтрТ Из СтрокиСклада Цикл + СтрТ.ДокументВвода = Док.Ссылка; + СтрТ.ЗагруженоВДокумент = Истина; + КонецЦикла; + КонецЕсли; + Исключение + Результат.Ошибок = Результат.Ошибок + 1; + КонецПопытки; + + КонецЦикла; + + Возврат Результат; + +КонецФункции + #КонецОбласти #Область СлужебныеПроцедурыИФункции +Функция ТегКомментарияДокументов() + + Суффикс = Формат(ДатаДокументовВвода, "ДФ=yyyyMMdd"); + Если ПустаяСтрока(Суффикс) Тогда + Суффикс = Формат(ДатаОстатков, "ДФ=yyyyMMdd"); + КонецЕсли; + Возврат "РК_ПереносОстатков " + Суффикс; + +КонецФункции + +Функция СгруппироватьСопоставленныеСтрокиПоСкладу() + + Группы = Новый Соответствие; + Для Каждого СтрТ Из ВходящиеДанные Цикл + Если Не СтрТ.Сопоставлено Тогда + Продолжить; + КонецЕсли; + Если Не ЗначениеЗаполнено(СтрТ.Склад) Или Не ЗначениеЗаполнено(СтрТ.Номенклатура) Тогда + Продолжить; + КонецЕсли; + Если СтрТ.Количество <= 0 Тогда + Продолжить; + КонецЕсли; + КлючСклада = Строка(СтрТ.Склад.УникальныйИдентификатор()); + СтрокиСклада = Группы.Получить(КлючСклада); + Если СтрокиСклада = Неопределено Тогда + СтрокиСклада = Новый Массив; + Группы.Вставить(КлючСклада, СтрокиСклада); + КонецЕсли; + СтрокиСклада.Добавить(СтрТ); + КонецЦикла; + + // Переключить ключи на ссылки складов для удобства обхода. + Результат = Новый Соответствие; + Для Каждого СтрТ Из ВходящиеДанные Цикл + Если Не СтрТ.Сопоставлено Или Не ЗначениеЗаполнено(СтрТ.Склад) Тогда + Продолжить; + КонецЕсли; + КлючСклада = Строка(СтрТ.Склад.УникальныйИдентификатор()); + СтрокиСклада = Группы.Получить(КлючСклада); + Если СтрокиСклада <> Неопределено И Результат.Получить(СтрТ.Склад) = Неопределено Тогда + Результат.Вставить(СтрТ.Склад, СтрокиСклада); + КонецЕсли; + КонецЦикла; + Возврат Результат; + +КонецФункции + +Функция УдалитьПрежниеДокументыВолны(ТекстТега) + + Удалено = 0; + Запрос = Новый Запрос; + Запрос.Текст = + "ВЫБРАТЬ + | Ввод.Ссылка КАК Ссылка + |ИЗ + | Документ.ВводОстатковТоваров КАК Ввод + |ГДЕ + | НЕ Ввод.ПометкаУдаления + | И НЕ Ввод.Проведен + | И Ввод.Организация = &Организация + | И Ввод.Комментарий ПОДОБНО &Тег + | И Ввод.ХозяйственнаяОперация = ЗНАЧЕНИЕ(Перечисление.ХозяйственныеОперации.ВводОстатковСобственныхТоваров)"; + Запрос.УстановитьПараметр("Организация", Организация); + Запрос.УстановитьПараметр("Тег", "%" + ТекстТега + "%"); + + Выборка = Запрос.Выполнить().Выбрать(); + Пока Выборка.Следующий() Цикл + Попытка + ДокОб = Выборка.Ссылка.ПолучитьОбъект(); + ДокОб.Удалить(); + Удалено = Удалено + 1; + Исключение + КонецПопытки; + КонецЦикла; + Возврат Удалено; + +КонецФункции + +Функция СоздатьДокументПоСкладу(СкладДок, СтрокиСклада, ТекстТега) + + Док = Документы.ВводОстатковТоваров.СоздатьДокумент(); + Док.Дата = ДатаДокументовВвода; + Док.Организация = Организация; + Док.Склад = СкладДок; + Док.ХозяйственнаяОперация = Перечисления.ХозяйственныеОперации.ВводОстатковСобственныхТоваров; + Док.Комментарий = ТекстТега + ", склад " + СокрЛП(Строка(СкладДок)); + Док.ОтражатьВОперативномУчете = Истина; + Док.ОтражатьСебестоимость = Ложь; + Док.ЦенаВключаетНДС = Ложь; + + Попытка + Док.Подразделение = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(СкладДок, "Подразделение"); + Исключение + КонецПопытки; + + Попытка + Док.Валюта = ЗначениеНастроекПовтИсп.ВалютаРегламентированногоУчетаОрганизации(Организация); + Исключение + Док.Валюта = Константы.ВалютаРегламентированногоУчета.Получить(); + КонецПопытки; + + Если Не ЗначениеЗаполнено(Док.НалогообложениеНДС) Тогда + Док.НалогообложениеНДС = Перечисления.ТипыНалогообложенияНДС.ПродажаОблагаетсяНДС; + КонецЕсли; + Попытка + ПараметрыНДС = Документы.ВводОстатковТоваров.ИнициализироватьПараметрыВидовДеятельностиНДС(Док); + УчетНДСУП.ЗаполнитьВидДеятельностиНДС(Док.ВидДеятельностиНДС, ПараметрыНДС); + Исключение + КонецПопытки; + + Для Каждого СтрТ Из СтрокиСклада Цикл + НовСтр = Док.Товары.Добавить(); + НовСтр.Номенклатура = СтрТ.Номенклатура; + НовСтр.Характеристика = СтрТ.Характеристика; + НовСтр.Серия = СтрТ.СерияСсылка; + НовСтр.Количество = СтрТ.Количество; + НовСтр.КоличествоУпаковок = СтрТ.Количество; + НовСтр.Цена = 0; + НовСтр.Сумма = 0; + Попытка + НовСтр.СтавкаНДС = СтрТ.Номенклатура.СтавкаНДС; + Исключение + КонецПопытки; + Если ЗначениеЗаполнено(СтрТ.НомерГТДСсылка) Тогда + НовСтр.НомерГТД = СтрТ.НомерГТДСсылка; + КонецЕсли; + Если ЗначениеЗаполнено(СтрТ.СерияСсылка) Тогда + СтрСер = Док.Серии.Добавить(); + СтрСер.Номенклатура = НовСтр.Номенклатура; + СтрСер.Характеристика = НовСтр.Характеристика; + СтрСер.Серия = СтрТ.СерияСсылка; + СтрСер.Количество = НовСтр.Количество; + СтрСер.КоличествоУпаковок = НовСтр.Количество; + КонецЕсли; + КонецЦикла; + + Если Док.Товары.Количество() = 0 Тогда + Возврат Документы.ВводОстатковТоваров.ПустаяСсылка(); + КонецЕсли; + + ОбщегоНазначенияУТ.ЗаполнитьИдентификаторыДокумента(Док, "Товары"); + Попытка + ПараметрыУказанияСерий = НоменклатураСервер.ПараметрыУказанияСерий(Док, Документы.ВводОстатковТоваров); + НоменклатураСервер.ЗаполнитьСтатусыУказанияСерий(Док, ПараметрыУказанияСерий); + Исключение + КонецПопытки; + + Док.ОбменДанными.Загрузка = Ложь; + Док.Записать(РежимЗаписиДокумента.Запись); + Возврат Док; + +КонецФункции + Процедура ЗаполнитьСтрокуВходящихДанныхИзAPI(НовСтр, СтрокаAPI) НовСтр.НоменклатураИдентификатор = UUIDИзСтроки(ЗначениеСвойства(СтрокаAPI, "nomenclature_guid", "")); diff --git a/src/DataProcessors/РК_ЗагрузкаОстатков/Forms/Форма/Ext/Form.xml b/src/DataProcessors/РК_ЗагрузкаОстатков/Forms/Форма/Ext/Form.xml index 63b5932..9103185 100644 --- a/src/DataProcessors/РК_ЗагрузкаОстатков/Forms/Форма/Ext/Form.xml +++ b/src/DataProcessors/РК_ЗагрузкаОстатков/Forms/Форма/Ext/Form.xml @@ -19,6 +19,11 @@ Form.Command.Сопоставить + @@ -43,6 +48,25 @@ + + Объект.Организация + true + + + + + Объект.ПерезаписатьДокументы + + + ru + Удалить непроведённые документы этой волны перед созданием + + + ShowRight + Auto + + + <v8:item> @@ -227,6 +251,19 @@ <ContextMenu name="ВходящиеДанныеКомментарийСопоставленияКонтекстноеМеню" id="111"/> <ExtendedTooltip name="ВходящиеДанныеКомментарийСопоставленияРасширеннаяПодсказка" id="112"/> </InputField> + <InputField name="ВходящиеДанныеДокументВвода" id="125"> + <DataPath>Объект.ВходящиеДанные.ДокументВвода</DataPath> + <EditMode>EnterOnInput</EditMode> + <ContextMenu name="ВходящиеДанныеДокументВводаКонтекстноеМеню" id="126"/> + <ExtendedTooltip name="ВходящиеДанныеДокументВводаРасширеннаяПодсказка" id="127"/> + </InputField> + <CheckBoxField name="ВходящиеДанныеЗагруженоВДокумент" id="128"> + <DataPath>Объект.ВходящиеДанные.ЗагруженоВДокумент</DataPath> + <EditMode>EnterOnInput</EditMode> + <CheckBoxType>Auto</CheckBoxType> + <ContextMenu name="ВходящиеДанныеЗагруженоВДокументКонтекстноеМеню" id="129"/> + <ExtendedTooltip name="ВходящиеДанныеЗагруженоВДокументРасширеннаяПодсказка" id="130"/> + </CheckBoxField> </ChildItems> </Table> </ChildItems> @@ -439,5 +476,20 @@ </ToolTip> <Action>Сопоставить</Action> </Command> + <Command name="СоздатьДокументы" id="4"> + <Title> + <v8:item> + <v8:lang>ru</v8:lang> + <v8:content>Создать документы</v8:content> + </v8:item> + + + + ru + Создать ВводОстатковТоваров по сопоставленным строкам + + + СоздатьДокументы + \ No newline at end of file diff --git a/src/DataProcessors/РК_ЗагрузкаОстатков/Forms/Форма/Ext/Form/Module.bsl b/src/DataProcessors/РК_ЗагрузкаОстатков/Forms/Форма/Ext/Form/Module.bsl index a59c694..2b73d87 100644 --- a/src/DataProcessors/РК_ЗагрузкаОстатков/Forms/Форма/Ext/Form/Module.bsl +++ b/src/DataProcessors/РК_ЗагрузкаОстатков/Forms/Форма/Ext/Form/Module.bsl @@ -32,7 +32,12 @@ Возврат; КонецЕсли; - ПодобратьСкладыНаСервере(); + Попытка + ПодобратьСкладыНаСервере(); + Исключение + ПоказатьПредупреждение(, КраткоеПредставлениеОшибки(ИнформацияОбОшибке())); + Возврат; + КонецПопытки; Элементы.ГруппаСтраницы.ТекущаяСтраница = Элементы.ГруппаОтбор; КонецПроцедуры @@ -49,7 +54,12 @@ Возврат; КонецЕсли; - Количество = ЗагрузитьОстаткиНаСервере(); + Попытка + Количество = ЗагрузитьОстаткиНаСервере(); + Исключение + ПоказатьПредупреждение(, КраткоеПредставлениеОшибки(ИнформацияОбОшибке())); + Возврат; + КонецПопытки; Элементы.ГруппаСтраницы.ТекущаяСтраница = Элементы.ГруппаВходящиеДанные; ПоказатьОповещениеПользователя("Загрузка остатков", , "Загружено строк: " + Формат(Количество, "ЧГ=0")); @@ -79,11 +89,53 @@ Возврат; КонецЕсли; РежимТест = (РезультатВопроса <> КодВозвратаДиалога.Да); - Текст = СопоставитьНаСервере(РежимТест); + Попытка + Текст = СопоставитьНаСервере(РежимТест); + Исключение + ПоказатьПредупреждение(, КраткоеПредставлениеОшибки(ИнформацияОбОшибке())); + Возврат; + КонецПопытки; ПоказатьОповещениеПользователя("Сопоставление", , Текст); КонецПроцедуры +&НаКлиенте +Процедура СоздатьДокументы(Команда) + + Если Не ЗначениеЗаполнено(Объект.Организация) Тогда + ПоказатьПредупреждение(, "Укажите организацию"); + Возврат; + КонецЕсли; + Если Не ЗначениеЗаполнено(Объект.ДатаДокументовВвода) Тогда + ПоказатьПредупреждение(, "Укажите дату документов ввода"); + Возврат; + КонецЕсли; + + Описание = Новый ОписаниеОповещения("СоздатьДокументыПослеВопроса", ЭтотОбъект); + ПоказатьВопрос(Описание, + "Создать документы ВводОстатковТоваров?" + Символы.ПС + + "Да — запись; Нет — только подсчёт (тест); Отмена — прервать.", + РежимДиалогаВопрос.ДаНетОтмена); + +КонецПроцедуры + +&НаКлиенте +Процедура СоздатьДокументыПослеВопроса(РезультатВопроса, ДопПараметры) Экспорт + + Если РезультатВопроса = КодВозвратаДиалога.Отмена Тогда + Возврат; + КонецЕсли; + РежимТест = (РезультатВопроса <> КодВозвратаДиалога.Да); + Попытка + Текст = СоздатьДокументыНаСервере(РежимТест); + Исключение + ПоказатьПредупреждение(, КраткоеПредставлениеОшибки(ИнформацияОбОшибке())); + Возврат; + КонецПопытки; + ПоказатьОповещениеПользователя("Документы ввода", , Текст); + +КонецПроцедуры + #КонецОбласти #Область СлужебныеПроцедурыИФункции @@ -210,6 +262,24 @@ КонецФункции +&НаСервере +Функция СоздатьДокументыНаСервере(РежимТест) + + ОбъектОбработки = РеквизитФормыВЗначение("Объект"); + Результат = ОбъектОбработки.СоздатьДокументыВводаОстатков(РежимТест); + ЗначениеВРеквизитФормы(ОбъектОбработки, "Объект"); + + Возврат СтрШаблон( + "Документов: %1; строк: %2; удалено прежних: %3; ошибок: %4; тег: %5%6", + Формат(Результат.СозданоДокументов, "ЧН=0; ЧГ=0"), + Формат(Результат.СтрокВДокументах, "ЧН=0; ЧГ=0"), + Формат(Результат.УдаленоДокументов, "ЧН=0; ЧГ=0"), + Формат(Результат.Ошибок, "ЧН=0; ЧГ=0"), + Результат.ТекстТега, + ?(РежимТест, " (тест)", "")); + +КонецФункции + &НаСервере Функция ЗначениеСвойстваОтвета(Источник, Имя)