diff --git a/CHANGELOG.md b/CHANGELOG.md index 174ac1a..0e681cb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,21 @@ --- +## 1.3.1.98 (2026-08-20) + +### РК_ПроверкаСерий — доработка объединения дублей (#15) + +- Исправлен ложный отказ «Отметьте группы для объединения»: перед проверкой завершается редактирование строки, колонка `Отметка` переведена в `EditMode=Directly`, уточнены сообщения (в т.ч. когда отмеченные группы уже объединены). +- При поиске дублей заполняется `ИдентификаторСерии` (UUID мастер-серии). +- Для таблицы `ГруппыДублей` добавлены сортировка по текущей колонке и открытие формы мастер-серии по событию `Выбор`. +- Команда **Выбрать другую мастер серию** (`Ctrl+C`) открывает `ФормаИзмененияМастерСерии` со списком серий группы; после выбора пересчитываются мастер, остатки и детали строки. + +## 1.3.1.97 (2026-08-20) + +### РК_ПроверкаСерий — заготовки UI объединения дублей (#15) + +- Добавлены `ГруппыДублейДеталиОстатков1`, реквизит `ИдентификаторСерии`, пустая форма `ФормаИзмененияМастерСерии` (доработаны в 1.3.1.98). + ## 1.3.1.96 (2026-08-20) ### РК_ПроверкаСерий — исправление события двойного клика (#17) diff --git a/VERSION b/VERSION index 13af310..c1651cf 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.3.1.97 +1.3.1.98 diff --git a/src/ConfigDumpInfo.xml b/src/ConfigDumpInfo.xml index a4098af..90da7f1 100644 --- a/src/ConfigDumpInfo.xml +++ b/src/ConfigDumpInfo.xml @@ -246,8 +246,8 @@ - - + + diff --git a/src/Configuration.xml b/src/Configuration.xml index ad9e6e7..bbf55c8 100644 --- a/src/Configuration.xml +++ b/src/Configuration.xml @@ -62,7 +62,7 @@ Role.РК_ОсновнаяРоль - 1.3.1.97 + 1.3.1.98 Language.Русский diff --git a/src/DataProcessors/РК_ПроверкаСерий/Forms/Форма/Ext/Form.xml b/src/DataProcessors/РК_ПроверкаСерий/Forms/Форма/Ext/Form.xml index a43437f..3bc9b8f 100644 --- a/src/DataProcessors/РК_ПроверкаСерий/Forms/Форма/Ext/Form.xml +++ b/src/DataProcessors/РК_ПроверкаСерий/Forms/Форма/Ext/Form.xml @@ -337,6 +337,11 @@ Form.Command.СнятьОтметкуГруппыДублей + @@ -362,6 +367,16 @@ Form.Command.СнятьОтметкуГруппыДублей + + @@ -389,10 +404,13 @@ + + ГруппыДублейВыбор + Объект.ГруппыДублей.Отметка - EnterOnInput + Directly Auto @@ -821,5 +839,44 @@ СнятьОтметкуГруппыДублей + + + <v8:item> + <v8:lang>ru</v8:lang> + <v8:content>Сортировать по колонке</v8:content> + </v8:item> + + + + ru + Сортировать таблицу групп дублей по текущей колонке + + + + StdPicture.SortListAsc + true + + СортироватьГруппыДублейПоКолонке + + + + <v8:item> + <v8:lang>ru</v8:lang> + <v8:content>Выбрать другую мастер серию</v8:content> + </v8:item> + + + + ru + Выбрать другую мастер-серию из серии группы дублей текущей строки + + + Ctrl+C + + StdPicture.ChooseValue + true + + ВыбратьДругуюМастерСерию + \ 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 ee2c348..7f5ca98 100644 --- a/src/DataProcessors/РК_ПроверкаСерий/Forms/Форма/Ext/Form/Module.bsl +++ b/src/DataProcessors/РК_ПроверкаСерий/Forms/Форма/Ext/Form/Module.bsl @@ -233,8 +233,19 @@ Возврат; КонецЕсли; - Если Не ЕстьОтмеченныеГруппыДублей() Тогда - ПоказатьПредупреждение(, "Отметьте группы для объединения"); + // Зафиксировать значение колонки «Отметка», если ячейка ещё в режиме редактирования. + Если Элементы.ГруппыДублей.ТекущиеДанные <> Неопределено Тогда + Элементы.ГруппыДублей.ЗакончитьРедактированиеСтроки(Ложь); + КонецЕсли; + + СостояниеОтметок = СостояниеОтметокГруппДублей(); + Если СостояниеОтметок.КОбъединению = 0 Тогда + Если СостояниеОтметок.ОтмеченоВсего > 0 Тогда + ПоказатьПредупреждение(, + "Отмеченные группы уже объединены. Снимите признак «Объединено» повторным поиском дублей или отметьте другие группы."); + Иначе + ПоказатьПредупреждение(, "Отметьте группы для объединения (колонка «Отметка»)"); + КонецЕсли; Возврат; КонецЕсли; @@ -293,6 +304,85 @@ УстановитьОтметкуВыделенныхСтрок("ГруппыДублей", Ложь); КонецПроцедуры +&НаКлиенте +Процедура СортироватьГруппыДублейПоКолонке(Команда) + + ТекущееПоле = Элементы.ГруппыДублей.ТекущийЭлемент; + Если ТекущееПоле = Неопределено Тогда + ПоказатьПредупреждение(, "Выберите колонку таблицы (щёлкните ячейку)"); + Возврат; + КонецЕсли; + + ИмяКолонки = ИмяКолонкиСортировкиГруппДублей(ТекущееПоле.Имя); + Если Не ЗначениеЗаполнено(ИмяКолонки) Тогда + ПоказатьПредупреждение(, "По этой колонке сортировка недоступна"); + Возврат; + КонецЕсли; + + СортироватьГруппыДублейНаСервере(ИмяКолонки + " Возр"); + +КонецПроцедуры + +&НаКлиенте +Процедура ГруппыДублейВыбор(Элемент, ВыбраннаяСтрока, Поле, СтандартнаяОбработка) + + ТекущаяСтрока = ТекущаяСтрокаГруппыДублей(); + Если ТекущаяСтрока = Неопределено Тогда + Возврат; + КонецЕсли; + + СтандартнаяОбработка = Ложь; + ОткрытьФормуСерии(ТекущаяСтрока.СерияМастер); + +КонецПроцедуры + +&НаКлиенте +Процедура ВыбратьДругуюМастерСерию(Команда) + + ТекущаяСтрока = ТекущаяСтрокаГруппыДублей(); + Если ТекущаяСтрока = Неопределено Тогда + ПоказатьПредупреждение(, "Выберите строку группы дублей"); + Возврат; + КонецЕсли; + + Если ТекущаяСтрока.Объединено Тогда + ПоказатьПредупреждение(, "Группа уже объединена"); + Возврат; + КонецЕсли; + + ПараметрыФормы = Новый Структура; + ПараметрыФормы.Вставить("СерияМастер", ТекущаяСтрока.СерияМастер); + ПараметрыФормы.Вставить("ВидНоменклатуры", ТекущаяСтрока.ВидНоменклатуры); + ПараметрыФормы.Вставить("Номер", ТекущаяСтрока.Номер); + ПараметрыФормы.Вставить("ГоденДо", ТекущаяСтрока.ГоденДо); + + Описание = Новый ОписаниеОповещения( + "ВыбратьДругуюМастерСериюЗавершение", + ЭтотОбъект, + ТекущаяСтрока.ПолучитьИдентификатор()); + ОткрытьФорму( + "DataProcessor.РК_ПроверкаСерий.Form.ФормаИзмененияМастерСерии", + ПараметрыФормы, + ЭтотОбъект, + , + , + , + Описание, + РежимОткрытияОкнаФормы.БлокироватьОкноВладельца); + +КонецПроцедуры + +&НаКлиенте +Процедура ВыбратьДругуюМастерСериюЗавершение(Результат, ИдентификаторСтроки) Экспорт + + Если Результат = Неопределено Или Не ЗначениеЗаполнено(Результат) Тогда + Возврат; + КонецЕсли; + + ПрименитьНовуюМастерСериюНаСервере(ИдентификаторСтроки, Результат); + +КонецПроцедуры + #КонецОбласти #Область СлужебныеПроцедурыИФункции @@ -422,12 +512,60 @@ &НаКлиенте Функция ЕстьОтмеченныеГруппыДублей() + Возврат СостояниеОтметокГруппДублей().КОбъединению > 0; + +КонецФункции + +&НаКлиенте +Функция СостояниеОтметокГруппДублей() + + Результат = Новый Структура("ОтмеченоВсего, КОбъединению", 0, 0); Для Каждого Стр Из Объект.ГруппыДублей Цикл - Если Стр.Отметка И Не Стр.Объединено Тогда - Возврат Истина; + Если Не Стр.Отметка Тогда + Продолжить; + КонецЕсли; + Результат.ОтмеченоВсего = Результат.ОтмеченоВсего + 1; + Если Не Стр.Объединено Тогда + Результат.КОбъединению = Результат.КОбъединению + 1; КонецЕсли; КонецЦикла; - Возврат Ложь; + Возврат Результат; + +КонецФункции + +&НаКлиенте +Функция ТекущаяСтрокаГруппыДублей() + + Если Элементы.ГруппыДублей.ТекущиеДанные = Неопределено Тогда + Возврат Неопределено; + КонецЕсли; + + Возврат Элементы.ГруппыДублей.ТекущиеДанные; + +КонецФункции + +&НаКлиенте +Функция ИмяКолонкиСортировкиГруппДублей(ИмяПоляФормы) + + СоответствиеИмен = Новый Соответствие; + СоответствиеИмен.Вставить("ГруппыДублейОтметка", "Отметка"); + СоответствиеИмен.Вставить("ГруппыДублейИдентификаторГруппы", "ИдентификаторГруппы"); + СоответствиеИмен.Вставить("ГруппыДублейСерияМастер", "СерияМастер"); + СоответствиеИмен.Вставить("ГруппыДублейПредупреждение", "Предупреждение"); + СоответствиеИмен.Вставить("ГруппыДублейВидНоменклатуры", "ВидНоменклатуры"); + СоответствиеИмен.Вставить("ГруппыДублейНомер", "Номер"); + СоответствиеИмен.Вставить("ГруппыДублейГоденДо", "ГоденДо"); + СоответствиеИмен.Вставить("ГруппыДублейДатаПроизводства", "ДатаПроизводства"); + СоответствиеИмен.Вставить("ГруппыДублейКоличествоСерий", "КоличествоСерий"); + СоответствиеИмен.Вставить("ГруппыДублейКоличествоЗамен", "КоличествоЗамен"); + СоответствиеИмен.Вставить("ГруппыДублейОстатокМастер", "ОстатокМастер"); + СоответствиеИмен.Вставить("ГруппыДублейОстатокДублей", "ОстатокДублей"); + СоответствиеИмен.Вставить("ГруппыДублейСерийСОстатком", "СерийСОстатком"); + СоответствиеИмен.Вставить("ГруппыДублейДеталиОстатков", "ДеталиОстатков"); + СоответствиеИмен.Вставить("ГруппыДублейОбъединено", "Объединено"); + СоответствиеИмен.Вставить("ГруппыДублейКомментарий", "Комментарий"); + СоответствиеИмен.Вставить("ГруппыДублейИдентификаторСерии", "ИдентификаторСерии"); + Возврат СоответствиеИмен.Получить(ИмяПоляФормы); КонецФункции @@ -1304,6 +1442,19 @@ &НаСервере Процедура ДобавитьСтрокуГруппыДублей(НомерГруппы, ДанныеГруппы, Мастер, СерииГруппы, Остатки) + НовСтр = Объект.ГруппыДублей.Добавить(); + НовСтр.ИдентификаторГруппы = НомерГруппы; + НовСтр.ВидНоменклатуры = ДанныеГруппы.ВидНоменклатуры; + НовСтр.Номер = ДанныеГруппы.Номер; + НовСтр.ГоденДо = ДанныеГруппы.ГоденДо; + НовСтр.Объединено = Ложь; + ЗаполнитьПоказателиГруппыДублей(НовСтр, Мастер, СерииГруппы, Остатки); + +КонецПроцедуры + +&НаСервере +Процедура ЗаполнитьПоказателиГруппыДублей(СтрГруппа, Мастер, СерииГруппы, Остатки) + ОстатокМастер = ОстатокСерииИзСоответствия(Остатки, Мастер); ОстатокДублей = 0; СерийСОстатком = 0; @@ -1331,21 +1482,57 @@ Предупреждение = "У дублей есть остатки → перенос на мастер"; КонецЕсли; - НовСтр = Объект.ГруппыДублей.Добавить(); - НовСтр.Отметка = ПустаяСтрока(Предупреждение); - НовСтр.ИдентификаторГруппы = НомерГруппы; - НовСтр.ВидНоменклатуры = ДанныеГруппы.ВидНоменклатуры; - НовСтр.Номер = ДанныеГруппы.Номер; - НовСтр.ГоденДо = ДанныеГруппы.ГоденДо; - НовСтр.ДатаПроизводства = Мастер.ДатаПроизводства; - НовСтр.СерияМастер = Мастер; - НовСтр.КоличествоСерий = СерииГруппы.Количество(); - НовСтр.КоличествоЗамен = КоличествоЗамен; - НовСтр.ОстатокМастер = ОстатокМастер; - НовСтр.ОстатокДублей = ОстатокДублей; - НовСтр.СерийСОстатком = СерийСОстатком; - НовСтр.Предупреждение = Предупреждение; - НовСтр.ДеталиОстатков = СтрСоединить(Детали, "; "); + СтрГруппа.ДатаПроизводства = Мастер.ДатаПроизводства; + СтрГруппа.СерияМастер = Мастер; + СтрГруппа.ИдентификаторСерии = Мастер.УникальныйИдентификатор(); + СтрГруппа.КоличествоСерий = СерииГруппы.Количество(); + СтрГруппа.КоличествоЗамен = КоличествоЗамен; + СтрГруппа.ОстатокМастер = ОстатокМастер; + СтрГруппа.ОстатокДублей = ОстатокДублей; + СтрГруппа.СерийСОстатком = СерийСОстатком; + СтрГруппа.Предупреждение = Предупреждение; + СтрГруппа.ДеталиОстатков = СтрСоединить(Детали, "; "); + Если Не СтрГруппа.Объединено Тогда + СтрГруппа.Отметка = ПустаяСтрока(Предупреждение); + КонецЕсли; + +КонецПроцедуры + +&НаСервере +Процедура ПрименитьНовуюМастерСериюНаСервере(ИдентификаторСтроки, НоваяМастерСерия) + + СтрГруппа = Объект.ГруппыДублей.НайтиПоИдентификатору(ИдентификаторСтроки); + Если СтрГруппа = Неопределено Тогда + Возврат; + КонецЕсли; + + Если СтрГруппа.Объединено Тогда + Возврат; + КонецЕсли; + + Если СтрГруппа.СерияМастер = НоваяМастерСерия Тогда + Возврат; + КонецЕсли; + + СерииГруппы = СерииГруппыДублей( + СтрГруппа.ВидНоменклатуры, + СтрГруппа.Номер, + СтрГруппа.ГоденДо); + Если СерииГруппы.Найти(НоваяМастерСерия) = Неопределено Тогда + СтрГруппа.Комментарий = "Выбранная серия не входит в группу дублей"; + Возврат; + КонецЕсли; + + Остатки = СведенияОстатковПоСериям(СерииГруппы).Остатки; + ЗаполнитьПоказателиГруппыДублей(СтрГруппа, НоваяМастерСерия, СерииГруппы, Остатки); + СтрГруппа.Комментарий = "Мастер-серия изменена вручную"; + +КонецПроцедуры + +&НаСервере +Процедура СортироватьГруппыДублейНаСервере(ВыражениеСортировки) + + Объект.ГруппыДублей.Сортировать(ВыражениеСортировки); КонецПроцедуры diff --git a/src/DataProcessors/РК_ПроверкаСерий/Forms/ФормаИзмененияМастерСерии/Ext/Form.xml b/src/DataProcessors/РК_ПроверкаСерий/Forms/ФормаИзмененияМастерСерии/Ext/Form.xml index 9007333..6943983 100644 --- a/src/DataProcessors/РК_ПроверкаСерий/Forms/ФормаИзмененияМастерСерии/Ext/Form.xml +++ b/src/DataProcessors/РК_ПроверкаСерий/Forms/ФормаИзмененияМастерСерии/Ext/Form.xml @@ -6,13 +6,200 @@ Выбор мастер серии - + LockOwnerWindow + + false + + + + + + + ПриСозданииНаСервере + + + + + <v8:item> + <v8:lang>ru</v8:lang> + <v8:content>Выберите серию группы, которая станет мастер-серией</v8:content> + </v8:item> + + + + + + List + false + false + true + СерииГруппы + + + + false + + + + + СерииГруппы + SearchStringRepresentation + + + + + + + СерииГруппы + ViewStatusRepresentation + + + + + + + СерииГруппы + SearchControl + + + + + + СерииГруппыВыбор + + + + СерииГруппы.ЭтоМастер + true + EnterOnInput + Auto + + + + + СерииГруппы.Серия + true + EnterOnInput + + + + + СерииГруппы.Остаток + true + EnterOnInput + 10 + + + + + СерииГруппы.ИдентификаторСерии + true + EnterOnInput + + + + +
+
- + + + <v8:item> + <v8:lang>ru</v8:lang> + <v8:content>Серии группы</v8:content> + </v8:item> + - cfg:DataProcessorObject.РК_ПроверкаСерий + v8:ValueTable + + + + + <v8:item> + <v8:lang>ru</v8:lang> + <v8:content>Серия</v8:content> + </v8:item> + + + cfg:CatalogRef.СерииНоменклатуры + + + + + <v8:item> + <v8:lang>ru</v8:lang> + <v8:content>Остаток</v8:content> + </v8:item> + + + xs:decimal + + 15 + 3 + Any + + + + + + <v8:item> + <v8:lang>ru</v8:lang> + <v8:content>Мастер</v8:content> + </v8:item> + + + xs:boolean + + + + + <v8:item> + <v8:lang>ru</v8:lang> + <v8:content>UUID</v8:content> + </v8:item> + + + v8:UUID + + + + + + + <v8:item> + <v8:lang>ru</v8:lang> + <v8:content>Серия мастер</v8:content> + </v8:item> + + + cfg:CatalogRef.СерииНоменклатуры - true - \ No newline at end of file + + + + <v8:item> + <v8:lang>ru</v8:lang> + <v8:content>Выбрать</v8:content> + </v8:item> + + + + ru + Назначить выбранную серию мастер-серией группы + + + Выбрать + + + diff --git a/src/DataProcessors/РК_ПроверкаСерий/Forms/ФормаИзмененияМастерСерии/Ext/Form/Module.bsl b/src/DataProcessors/РК_ПроверкаСерий/Forms/ФормаИзмененияМастерСерии/Ext/Form/Module.bsl new file mode 100644 index 0000000..6bc4bc9 --- /dev/null +++ b/src/DataProcessors/РК_ПроверкаСерий/Forms/ФормаИзмененияМастерСерии/Ext/Form/Module.bsl @@ -0,0 +1,130 @@ +#Область ОбработчикиСобытийФормы + +&НаСервере +Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка) + + СерияМастер = Параметры.СерияМастер; + ВидНоменклатуры = Параметры.ВидНоменклатуры; + Номер = Параметры.Номер; + ГоденДо = Параметры.ГоденДо; + + ЗаполнитьСерииГруппы(ВидНоменклатуры, Номер, ГоденДо); + +КонецПроцедуры + +#КонецОбласти + +#Область ОбработчикиКомандФормы + +&НаКлиенте +Процедура Выбрать(Команда) + + ВыбраннаяСерия = ТекущаяВыбраннаяСерия(); + Если Не ЗначениеЗаполнено(ВыбраннаяСерия) Тогда + ПоказатьПредупреждение(, "Выберите серию в таблице"); + Возврат; + КонецЕсли; + + Закрыть(ВыбраннаяСерия); + +КонецПроцедуры + +#КонецОбласти + +#Область ОбработчикиСобытийЭлементовТаблицыФормыСерииГруппы + +&НаКлиенте +Процедура СерииГруппыВыбор(Элемент, ВыбраннаяСтрока, Поле, СтандартнаяОбработка) + + СтандартнаяОбработка = Ложь; + ВыбраннаяСерия = ТекущаяВыбраннаяСерия(); + Если ЗначениеЗаполнено(ВыбраннаяСерия) Тогда + Закрыть(ВыбраннаяСерия); + КонецЕсли; + +КонецПроцедуры + +#КонецОбласти + +#Область СлужебныеПроцедурыИФункции + +&НаКлиенте +Функция ТекущаяВыбраннаяСерия() + + Если Элементы.СерииГруппы.ТекущиеДанные = Неопределено Тогда + Возврат Неопределено; + КонецЕсли; + + Возврат Элементы.СерииГруппы.ТекущиеДанные.Серия; + +КонецФункции + +&НаСервере +Процедура ЗаполнитьСерииГруппы(ВидНоменклатуры, Номер, ГоденДо) + + СерииГруппы.Очистить(); + + Запрос = Новый Запрос; + Запрос.Текст = + "ВЫБРАТЬ + | Сер.Ссылка КАК Серия + |ИЗ + | Справочник.СерииНоменклатуры КАК Сер + |ГДЕ + | Сер.ВидНоменклатуры = &Вид + | И Сер.Номер = &Номер + | И Сер.ГоденДо = &ГоденДо + | И НЕ Сер.ПометкаУдаления"; + Запрос.УстановитьПараметр("Вид", ВидНоменклатуры); + Запрос.УстановитьПараметр("Номер", Номер); + Запрос.УстановитьПараметр("ГоденДо", ГоденДо); + + Серии = Новый Массив; + Выборка = Запрос.Выполнить().Выбрать(); + Пока Выборка.Следующий() Цикл + Серии.Добавить(Выборка.Серия); + КонецЦикла; + + Остатки = ОстаткиСерий(Серии); + Для Каждого Серия Из Серии Цикл + НовСтр = СерииГруппы.Добавить(); + НовСтр.Серия = Серия; + НовСтр.ЭтоМастер = (Серия = СерияМастер); + НовСтр.ИдентификаторСерии = Серия.УникальныйИдентификатор(); + Остаток = Остатки.Получить(Серия); + НовСтр.Остаток = ?(Остаток = Неопределено, 0, Остаток); + КонецЦикла; + + СерииГруппы.Сортировать("ЭтоМастер Убыв, Остаток Убыв, Серия"); + +КонецПроцедуры + +&НаСервере +Функция ОстаткиСерий(Серии) + + Результат = Новый Соответствие; + Если Серии.Количество() = 0 Тогда + Возврат Результат; + КонецЕсли; + + Запрос = Новый Запрос; + Запрос.Текст = + "ВЫБРАТЬ + | Ост.Серия КАК Серия, + | СУММА(Ост.ВНаличииОстаток) КАК Количество + |ИЗ + | РегистрНакопления.ТоварыНаСкладах.Остатки(, Серия В (&Серии)) КАК Ост + |СГРУППИРОВАТЬ ПО + | Ост.Серия"; + Запрос.УстановитьПараметр("Серии", Серии); + + Выборка = Запрос.Выполнить().Выбрать(); + Пока Выборка.Следующий() Цикл + Результат.Вставить(Выборка.Серия, Выборка.Количество); + КонецЦикла; + + Возврат Результат; + +КонецФункции + +#КонецОбласти