РК_ЗагрузкаОстатков 1.3.1.66: дерево групп и отбор по Отметка/Рекурсивно (#7).

Вложенность из parent_guid; фильтры nomenclature_groups(_recursive) при загрузке.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
mihailkudravcev
2026-08-14 14:26:20 +03:00
parent 546713ecce
commit 96f39f27b1
7 changed files with 263 additions and 39 deletions
+9
View File
@@ -4,6 +4,15 @@
---
## 1.3.1.66 (2026-08-14)
### РК_ЗагрузкаОстатков — дерево групп и отбор (#7)
- Таблица групп номенклатуры — `Representation=Tree` с вложенностью из `parent_guid`.
- Колонки **Отметка** и **Рекурсивно** (булево, по умолчанию Ложь).
- При загрузке остатков отмеченные группы уходят в `nomenclature_groups` /
`nomenclature_groups_recursive` (нужен **ws-rhana ≥ 0.0.0.42**).
## 1.3.1.65 (2026-08-14)
### РК_ЗагрузкаОстатков — исправление XML формы
+1 -1
View File
@@ -1 +1 @@
1.3.1.65
1.3.1.66
+1
View File
@@ -88,6 +88,7 @@
<Metadata name="DataProcessor.РК_ЗагрузкаОстатков.TabularSection.ВходящиеКомиссионныеТовары.Attribute.ТипЗапасов" id="47c8a3c1-d23c-4d8f-9f7e-7cab805b5be4"/>
<Metadata name="DataProcessor.РК_ЗагрузкаОстатков.TabularSection.ВходящиеКомиссионныеТовары.Attribute.ВидЗапасов" id="4917f342-9c11-4844-8f2e-159f2abe8cb4"/>
<Metadata name="DataProcessor.РК_ЗагрузкаОстатков.TabularSection.ОтборГруппНоменклатур.Attribute.Рекурсивно" id="4a8245d7-4a23-4416-b352-390932bec18e"/>
<Metadata name="DataProcessor.РК_ЗагрузкаОстатков.TabularSection.ОтборГруппНоменклатур.Attribute.РодительИдентификатор" id="a1b2c3d4-e5f6-4789-a012-3456789abcde"/>
<Metadata name="DataProcessor.РК_ЗагрузкаОстатков.TabularSection.ВходящиеКомиссионныеТовары.Attribute.ПартнерНаименование" id="4d2b3f2c-99f0-409d-926b-f999231e2e84"/>
<Metadata name="DataProcessor.РК_ЗагрузкаОстатков.TabularSection.ВходящиеКомиссионныеТовары.Attribute.ДоговорНаименование" id="4ece6fa6-3302-41bd-9a6a-2ef27f24d7c3"/>
<Metadata name="DataProcessor.РК_ЗагрузкаОстатков.TabularSection.ВходящиеСобственныеТовары.Attribute.ОрганизацияИдентификатор" id="4eef5276-30ac-40dd-bc7d-19e708da43e8"/>
+1 -1
View File
@@ -62,7 +62,7 @@
<xr:Item xsi:type="xr:MDObjectRef">Role.РК_ОсновнаяРоль</xr:Item>
</DefaultRoles>
<Vendor/>
<Version>1.3.1.65</Version>
<Version>1.3.1.66</Version>
<DefaultStyle/>
<DefaultLanguage>Language.Русский</DefaultLanguage>
<BriefInformation/>
@@ -4885,7 +4885,7 @@
<Type>
<v8:Type>xs:string</v8:Type>
<v8:StringQualifiers>
<v8:Length>10</v8:Length>
<v8:Length>0</v8:Length>
<v8:AllowedLength>Variable</v8:AllowedLength>
</v8:StringQualifiers>
</Type>
@@ -4936,7 +4936,7 @@
<MinValue xsi:nil="true"/>
<MaxValue xsi:nil="true"/>
<FillFromFillingValue>false</FillFromFillingValue>
<FillValue xsi:nil="true"/>
<FillValue xsi:type="xs:boolean">false</FillValue>
<FillChecking>DontCheck</FillChecking>
<ChoiceFoldersAndItems>Items</ChoiceFoldersAndItems>
<ChoiceParameterLinks/>
@@ -4957,13 +4957,9 @@
<v8:content>Рекурсивно</v8:content>
</v8:item>
</Synonym>
<Comment/>
<Comment>Включать вложенные группы исходной базы при отборе остатков</Comment>
<Type>
<v8:Type>xs:string</v8:Type>
<v8:StringQualifiers>
<v8:Length>10</v8:Length>
<v8:AllowedLength>Variable</v8:AllowedLength>
</v8:StringQualifiers>
<v8:Type>xs:boolean</v8:Type>
</Type>
<PasswordMode>false</PasswordMode>
<Format/>
@@ -4976,7 +4972,43 @@
<MinValue xsi:nil="true"/>
<MaxValue xsi:nil="true"/>
<FillFromFillingValue>false</FillFromFillingValue>
<FillValue xsi:type="xs:string"/>
<FillValue xsi:type="xs:boolean">false</FillValue>
<FillChecking>DontCheck</FillChecking>
<ChoiceFoldersAndItems>Items</ChoiceFoldersAndItems>
<ChoiceParameterLinks/>
<ChoiceParameters/>
<QuickChoice>Auto</QuickChoice>
<CreateOnInput>Auto</CreateOnInput>
<ChoiceForm/>
<LinkByType/>
<ChoiceHistoryOnInput>Auto</ChoiceHistoryOnInput>
</Properties>
</Attribute>
<Attribute uuid="a1b2c3d4-e5f6-4789-a012-3456789abcde">
<Properties>
<Name>РодительИдентификатор</Name>
<Synonym>
<v8:item>
<v8:lang>ru</v8:lang>
<v8:content>Родитель</v8:content>
</v8:item>
</Synonym>
<Comment>GUID родительской группы в исходной ИБ</Comment>
<Type>
<v8:Type>v8:UUID</v8:Type>
</Type>
<PasswordMode>false</PasswordMode>
<Format/>
<EditFormat/>
<ToolTip/>
<MarkNegatives>false</MarkNegatives>
<Mask/>
<MultiLine>false</MultiLine>
<ExtendedEdit>false</ExtendedEdit>
<MinValue xsi:nil="true"/>
<MaxValue xsi:nil="true"/>
<FillFromFillingValue>false</FillFromFillingValue>
<FillValue xsi:nil="true"/>
<FillChecking>DontCheck</FillChecking>
<ChoiceFoldersAndItems>Items</ChoiceFoldersAndItems>
<ChoiceParameterLinks/>
@@ -159,10 +159,14 @@
<ExtendedTooltip name="ГруппаОтбораЛевыйСтолбецРасширеннаяПодсказка" id="42"/>
<ChildItems>
<Table name="ОтборГруппНоменклатур" id="1518">
<AutoInsertNewRow>true</AutoInsertNewRow>
<EnableStartDrag>true</EnableStartDrag>
<EnableDrag>true</EnableDrag>
<DataPath>Объект.ОтборГруппНоменклатур</DataPath>
<Representation>Tree</Representation>
<ChangeRowSet>false</ChangeRowSet>
<ChangeRowOrder>false</ChangeRowOrder>
<AutoInsertNewRow>false</AutoInsertNewRow>
<InitialTreeView>ExpandAllLevels</InitialTreeView>
<EnableStartDrag>false</EnableStartDrag>
<EnableDrag>false</EnableDrag>
<DataPath>ОтборГруппНоменклатурДерево</DataPath>
<RowFilter xsi:nil="true"/>
<ContextMenu name="ОтборГруппНоменклатурКонтекстноеМеню" id="1519"/>
<AutoCommandBar name="ОтборГруппНоменклатурКоманднаяПанель" id="1520">
@@ -200,33 +204,27 @@
<ExtendedTooltip name="ОтборГруппНоменклатурУправлениеПоискомРасширеннаяПодсказка" id="1530"/>
</SearchControlAddition>
<ChildItems>
<LabelField name="ОтборГруппНоменклатурНомерСтроки" id="1531">
<DataPath>Объект.ОтборГруппНоменклатур.LineNumber</DataPath>
<EditMode>EnterOnInput</EditMode>
<ContextMenu name="ОтборГруппНоменклатурНомерСтрокиКонтекстноеМеню" id="1532"/>
<ExtendedTooltip name="ОтборГруппНоменклатурНомерСтрокиРасширеннаяПодсказка" id="1533"/>
</LabelField>
<InputField name="ОтборГруппНоменклатурНаименование" id="1534">
<DataPath>Объект.ОтборГруппНоменклатур.Наименование</DataPath>
<EditMode>EnterOnInput</EditMode>
<ExtendedEditMultipleValues>true</ExtendedEditMultipleValues>
<ContextMenu name="ОтборГруппНоменклатурНаименованиеКонтекстноеМеню" id="1535"/>
<ExtendedTooltip name="ОтборГруппНоменклатурНаименованиеРасширеннаяПодсказка" id="1536"/>
</InputField>
<CheckBoxField name="ОтборГруппНоменклатурОтметка" id="1537">
<DataPath>Объект.ОтборГруппНоменклатур.Отметка</DataPath>
<DataPath>ОтборГруппНоменклатурДерево.Отметка</DataPath>
<EditMode>EnterOnInput</EditMode>
<CheckBoxType>Auto</CheckBoxType>
<ContextMenu name="ОтборГруппНоменклатурОтметкаКонтекстноеМеню" id="1538"/>
<ExtendedTooltip name="ОтборГруппНоменклатурОтметкаРасширеннаяПодсказка" id="1539"/>
</CheckBoxField>
<InputField name="ОтборГруппНоменклатурРекурсивно" id="1540">
<DataPath>Объект.ОтборГруппНоменклатур.Рекурсивно</DataPath>
<InputField name="ОтборГруппНоменклатурНаименование" id="1534">
<DataPath>ОтборГруппНоменклатурДерево.Наименование</DataPath>
<ReadOnly>true</ReadOnly>
<EditMode>EnterOnInput</EditMode>
<ExtendedEditMultipleValues>true</ExtendedEditMultipleValues>
<ContextMenu name="ОтборГруппНоменклатурНаименованиеКонтекстноеМеню" id="1535"/>
<ExtendedTooltip name="ОтборГруппНоменклатурНаименованиеРасширеннаяПодсказка" id="1536"/>
</InputField>
<CheckBoxField name="ОтборГруппНоменклатурРекурсивно" id="1540">
<DataPath>ОтборГруппНоменклатурДерево.Рекурсивно</DataPath>
<EditMode>EnterOnInput</EditMode>
<CheckBoxType>Auto</CheckBoxType>
<ContextMenu name="ОтборГруппНоменклатурРекурсивноКонтекстноеМеню" id="1541"/>
<ExtendedTooltip name="ОтборГруппНоменклатурРекурсивноРасширеннаяПодсказка" id="1542"/>
</InputField>
</CheckBoxField>
</ChildItems>
</Table>
<Table name="ОтборСкладовВнешнейБазы" id="43">
@@ -1258,6 +1256,67 @@
<AdditionalColumns table="Объект.ВходящиеСобственныеТовары"/>
</Columns>
</Attribute>
<Attribute name="ОтборГруппНоменклатурДерево" id="5">
<Title>
<v8:item>
<v8:lang>ru</v8:lang>
<v8:content>Группы номенклатуры</v8:content>
</v8:item>
</Title>
<Type>
<v8:Type>v8:ValueTree</v8:Type>
</Type>
<Columns>
<Column name="Отметка" id="1">
<Title>
<v8:item>
<v8:lang>ru</v8:lang>
<v8:content>Отметка</v8:content>
</v8:item>
</Title>
<Type>
<v8:Type>xs:boolean</v8:Type>
</Type>
</Column>
<Column name="Наименование" id="2">
<Title>
<v8:item>
<v8:lang>ru</v8:lang>
<v8:content>Наименование</v8:content>
</v8:item>
</Title>
<Type>
<v8:Type>xs:string</v8:Type>
<v8:StringQualifiers>
<v8:Length>0</v8:Length>
<v8:AllowedLength>Variable</v8:AllowedLength>
</v8:StringQualifiers>
</Type>
</Column>
<Column name="Рекурсивно" id="3">
<Title>
<v8:item>
<v8:lang>ru</v8:lang>
<v8:content>Рекурсивно</v8:content>
</v8:item>
</Title>
<Type>
<v8:Type>xs:boolean</v8:Type>
</Type>
</Column>
<Column name="Идентификатор" id="4">
<Title>
<v8:item>
<v8:lang>ru</v8:lang>
<v8:content>Идентификатор</v8:content>
</v8:item>
</Title>
<Type>
<v8:Type>v8:UUID</v8:Type>
</Type>
</Column>
</Columns>
</Attribute>
<Attribute name="ПодключениеКСтороннейБазеПредыдущее" id="4">
<Title>
<v8:item>
@@ -21,6 +21,8 @@
Объект.ДатаДокументовВвода = Объект.ДатаОстатков;
КонецЕсли;
ПостроитьДеревоГруппИзТабличнойЧасти();
КонецПроцедуры
#КонецОбласти
@@ -251,6 +253,8 @@
Объект.ОтборСкладовВнешнейБазы.Очистить();
Объект.ОтборОрганизацийВнешнейБазы.Очистить();
Объект.ОтборГруппНоменклатур.Очистить();
ОтборГруппНоменклатурДерево.ПолучитьЭлементы().Очистить();
Объект.ВходящиеСобственныеТовары.Очистить();
Объект.ВходящиеКомиссионныеТовары.Очистить();
Объект.СозданныеДокументы.Очистить();
@@ -311,6 +315,8 @@
&НаСервере
Функция ЗагрузитьОстаткиНаСервере()
СинхронизироватьТабличнуюЧастьГруппИзДерева();
СкладыGUID = Новый Массив;
Для Каждого Стр Из Объект.ОтборСкладовВнешнейБазы Цикл
Если Стр.Отметка Тогда
@@ -337,12 +343,14 @@
ФильтрыСобственные.Вставить("organizations", ОрганизацииGUID);
КонецЕсли;
ФильтрыСобственные.Вставить("only_nonzero", Истина);
ДобавитьФильтрГруппНоменклатуры(ФильтрыСобственные);
ФильтрыКомиссия = Новый Структура;
Если ОрганизацииGUID.Количество() > 0 Тогда
ФильтрыКомиссия.Вставить("organizations", ОрганизацииGUID);
КонецЕсли;
ФильтрыКомиссия.Вставить("only_nonzero", Истина);
ДобавитьФильтрГруппНоменклатуры(ФильтрыКомиссия);
ПолныйОбходКомиссии = (ОрганизацииGUID.Количество() = 0);
СтрокиСобственные = ЗагрузитьСтраницыОстатков("combined", ФильтрыСобственные, Ложь);
@@ -518,6 +526,7 @@
Ответ = РК_ОбменСВнешнейБазой.СписокГруппНоменклатурыВнешнейБазы(Объект.ПодключениеКСтороннейБазе);
ЗаполнитьТаблицуГруппНоменклатурИзОтветаAPI(Объект.ОтборГруппНоменклатур, Ответ);
ПостроитьДеревоГруппИзТабличнойЧасти();
КонецПроцедуры
@@ -546,20 +555,134 @@
Продолжить;
КонецЕсли;
НовСтр = ТаблицаОтбора.Добавить();
ИмяОтображение = СокрЛП(Строка(ЗначениеСвойстваОтвета(СтрокаAPI, "name_display")));
Если ПустаяСтрока(ИмяОтображение) Тогда
ИмяОтображение = СокрЛП(Строка(ЗначениеСвойстваОтвета(СтрокаAPI, "name")));
КонецЕсли;
НовСтр.Наименование = ИмяОтображение;
НовСтр.Наименование = СокрЛП(Строка(ЗначениеСвойстваОтвета(СтрокаAPI, "name")));
Попытка
НовСтр.Идентификатор = Новый УникальныйИдентификатор(ГуидТекст);
Исключение
Продолжить;
КонецПопытки;
РодительТекст = СокрЛП(Строка(ЗначениеСвойстваОтвета(СтрокаAPI, "parent_guid")));
Если Не ПустаяСтрока(РодительТекст) Тогда
Попытка
НовСтр.РодительИдентификатор = Новый УникальныйИдентификатор(РодительТекст);
Исключение
КонецПопытки;
КонецЕсли;
СтараяОтметка = БылиОтметки.Получить(Строка(НовСтр.Идентификатор));
НовСтр.Отметка = ?(СтараяОтметка = Неопределено, Ложь, СтараяОтметка = Истина);
СтароеРекурсивно = БылоРекурсивно.Получить(Строка(НовСтр.Идентификатор));
НовСтр.Рекурсивно = ?(СтароеРекурсивно = Неопределено, Истина, СтароеРекурсивно = Истина);
НовСтр.Рекурсивно = ?(СтароеРекурсивно = Неопределено, Ложь, СтароеРекурсивно = Истина);
КонецЦикла;
КонецПроцедуры
&НаСервере
Процедура ПостроитьДеревоГруппИзТабличнойЧасти()
ОтборГруппНоменклатурДерево.ПолучитьЭлементы().Очистить();
Если Объект.ОтборГруппНоменклатур.Количество() = 0 Тогда
Возврат;
КонецЕсли;
УзлыПоGUID = Новый Соответствие;
Корни = Новый Массив;
Для Каждого СтрТЧ Из Объект.ОтборГруппНоменклатур Цикл
ДанныеУзла = Новый Структура;
ДанныеУзла.Вставить("СтрокаТЧ", СтрТЧ);
ДанныеУзла.Вставить("Дети", Новый Массив);
УзлыПоGUID.Вставить(Строка(СтрТЧ.Идентификатор), ДанныеУзла);
КонецЦикла;
Для Каждого СтрТЧ Из Объект.ОтборГруппНоменклатур Цикл
ДанныеУзла = УзлыПоGUID.Получить(Строка(СтрТЧ.Идентификатор));
КлючРодителя = Строка(СтрТЧ.РодительИдентификатор);
РодительУзел = Неопределено;
Если Не ПустаяСтрока(КлючРодителя) И КлючРодителя <> "00000000-0000-0000-0000-000000000000" Тогда
РодительУзел = УзлыПоGUID.Получить(КлючРодителя);
КонецЕсли;
Если РодительУзел = Неопределено Тогда
Корни.Добавить(ДанныеУзла);
Иначе
РодительУзел.Дети.Добавить(ДанныеУзла);
КонецЕсли;
КонецЦикла;
ДобавитьУзлыДереваГрупп(ОтборГруппНоменклатурДерево.ПолучитьЭлементы(), Корни);
КонецПроцедуры
&НаСервере
Процедура ДобавитьУзлыДереваГрупп(КоллекцияСтрок, Узлы)
Для Каждого ДанныеУзла Из Узлы Цикл
СтрТЧ = ДанныеУзла.СтрокаТЧ;
СтрокаДерева = КоллекцияСтрок.Добавить();
СтрокаДерева.Отметка = СтрТЧ.Отметка;
СтрокаДерева.Наименование = СтрТЧ.Наименование;
СтрокаДерева.Рекурсивно = СтрТЧ.Рекурсивно;
СтрокаДерева.Идентификатор = СтрТЧ.Идентификатор;
Если ДанныеУзла.Дети.Количество() > 0 Тогда
ДобавитьУзлыДереваГрупп(СтрокаДерева.ПолучитьЭлементы(), ДанныеУзла.Дети);
КонецЕсли;
КонецЦикла;
КонецПроцедуры
&НаСервере
Процедура СинхронизироватьТабличнуюЧастьГруппИзДерева()
Объект.ОтборГруппНоменклатур.Очистить();
ЗаписатьСтрокиДереваГруппВТЧ(ОтборГруппНоменклатурДерево.ПолучитьЭлементы(),
Новый УникальныйИдентификатор("00000000-0000-0000-0000-000000000000"));
КонецПроцедуры
&НаСервере
Процедура ЗаписатьСтрокиДереваГруппВТЧ(КоллекцияСтрок, РодительИдентификатор)
Для Каждого СтрокаДерева Из КоллекцияСтрок Цикл
НовСтр = Объект.ОтборГруппНоменклатур.Добавить();
НовСтр.Отметка = СтрокаДерева.Отметка;
НовСтр.Наименование = СтрокаДерева.Наименование;
НовСтр.Рекурсивно = СтрокаДерева.Рекурсивно;
НовСтр.Идентификатор = СтрокаДерева.Идентификатор;
НовСтр.РодительИдентификатор = РодительИдентификатор;
ЗаписатьСтрокиДереваГруппВТЧ(СтрокаДерева.ПолучитьЭлементы(), СтрокаДерева.Идентификатор);
КонецЦикла;
КонецПроцедуры
&НаСервере
Процедура ДобавитьФильтрГруппНоменклатуры(Фильтры)
ГруппыПрямые = Новый Массив;
ГруппыРекурсивно = Новый Массив;
СобратьОтмеченныеГруппыИзДерева(ОтборГруппНоменклатурДерево.ПолучитьЭлементы(),
ГруппыПрямые, ГруппыРекурсивно);
Если ГруппыПрямые.Количество() > 0 Тогда
Фильтры.Вставить("nomenclature_groups", ГруппыПрямые);
КонецЕсли;
Если ГруппыРекурсивно.Количество() > 0 Тогда
Фильтры.Вставить("nomenclature_groups_recursive", ГруппыРекурсивно);
КонецЕсли;
КонецПроцедуры
&НаСервере
Процедура СобратьОтмеченныеГруппыИзДерева(КоллекцияСтрок, ГруппыПрямые, ГруппыРекурсивно)
Для Каждого СтрокаДерева Из КоллекцияСтрок Цикл
Если СтрокаДерева.Отметка Тогда
ГуидТекст = Строка(СтрокаДерева.Идентификатор);
Если СтрокаДерева.Рекурсивно Тогда
ГруппыРекурсивно.Добавить(ГуидТекст);
Иначе
ГруппыПрямые.Добавить(ГуидТекст);
КонецЕсли;
КонецЕсли;
СобратьОтмеченныеГруппыИзДерева(СтрокаДерева.ПолучитьЭлементы(),
ГруппыПрямые, ГруппыРекурсивно);
КонецЦикла;
КонецПроцедуры