Автор Анна Евкова
Преподаватель который помогает студентам и школьникам в учёбе.

Разработка регламента выполнения процесса «Управление документооборотом» (1 Построение бизнес-процессов «как есть»)

Содержание:

Введение

Целью работы – разработка авторизированной системы документооборота, в конечном итоге позволяющей снизить издержки на данный процесс.

Задачи работы:

1 Описать предметную область

2 Разработать автоматизированную систему документооборота в виде диаграмм IDEF

Предметом работы является разработка системы автоматизации документоооборота в виде диаграмм IDEF.

Объектом работы является система, средствами которой осуществляется разработка системы автоматизации документоооборота.

При решении поставленных задач в процессе работы использовались методы:

  • аналитический метод;
  • статистический метод;
  • графические методы;
  • сравнительный метод;
  • методы сбора и обработки данных;

Практическая значимость проекта заключается в современности и актуальности используемых технологий, благодаря которым решались поставленные задачи, в оптимизации множества процессов и новизне приводимой информации. Основные положения данного проекта доведены до возможных рекомендаций администрациим пожелавшим вывести свой бизнес в интернет.

При доработке систем автоматизации документооборота на этапах кодирования и тестирования выявляется большое количество ошибок, исправление которых влечет за собой кардинальное изменение всей разрабатываемой системы. Учесть такие ошибки возможно только при моделировании и глубоком, детальном анализе создаваемых проектов. Моделирование позволяет «увидеть» проект в процессе разработки и создать предпосылки для анализа поведения системы в зависимости от начальных условий.

1 Построение бизнес-процессов «как есть»

1.1 Описание предметной области. Постановка задачи

Под документооборотом понимается движение документов на предприятии (в организации) с момента их создания или получения до завершающего исполнения или отправки.

Как правило, документы различаются по типам носителей информации (рисунок 1.2).

http://twidler.ru/Content/Images/buhgalterskiy-uchet-i-audit/16/27516/1.png

Рисунок 1.2 - Типы документов и их взаимодействие

Для любой организации можно выделить три основных потока документов (таблица 1.1):

1) Входящие. Входящий документ – документ, поступивший в учреждение. Большинство входящих документов должны порождать соответствующие исходящие, в установленные сроки. Сроки могут быть установлены нормативными актами, предписывающими то или иное время ответа на соответствующий входящий документ, или могут быть указаны непосредственно во входящем документе.

2) Исходящие. Исходящий документ – официальный документ, отправляемый из учреждения. Большинство исходящих документов являются ответом организации на входящие документы. Некоторая часть исходящих документов готовится на основе внутренних документов организации. Небольшое число исходящих документов может требовать поступления входящих документов (например, запросы в другие организации).

3) Внутренние. Внутренний документ – официальный документ, не выходящий за пределы подготовившей его организации. Данные документы используются для организации работы учреждения (организации), так как они обеспечивают целенаправленное решение управленческих задач в пределах одной организации.

Таблица 1.1

Традиционная работа с документами в организации без использования автоматизированной системы документооборота

Форма

документа

Документопоток

входящей информации

внутренних документов

исходящей информации

Электронные документы

Сообщения электронной почты, факсимильная информация

Сообщения в корпоративной сети, факсы

Ответы и письма по электронной почте,

факсимильная информация

Бумажные документы

Письма,

договоры и контракты,

законодательные акты,

нормативные документы,

периодические издания,

Книги, реклама

Приказы,

инструкции,

отчеты,

служебные записки,

командировочные документы,

бухгалтерские документы

Письма,

договоры и контракты,

пресс – релизы

От правильной постановки документооборота в организации зависит оперативность, экономичность, надежность функционирования аппарата управления, организация и культура труда персонала управления.

Документооборот в организациях имеет три основные системы:

1. централизованную;

2. децентрализованную;

3. смешанную.

Выбор системы документооборота зависит от характера деятельности, функций, организационной структуры организации.

При централизованной системе все операции, связанные с документационным обеспечением управления сосредотачиваются в одном месте, в единой для всей организации службе или у секретаря (прием документов, их регистрация, контроль исполнения, хранение дел и др.), что позволяет значительно повысить качество их обработки. При децентрализованной системе все виды работ с документами производятся непосредственно в структурных подразделениях организации, т.е. документооборот каждое функциональное подразделение ведет самостоятельно

При смешанной системе документооборота одни операции (прием, отправка корреспонденции) осуществляются в одной из служб ДОУ, а другие (регистрация, оформление и составление документов, формирование дел) производятся в других функциональных подразделениях.

Порядок движения документов в организации включает в себя организацию документооборота, включая технологию личной работы исполнителей, создание информационно–поисковых систем по документам организации, контроль их исполнения. Процесс движения документов от момента их создания (получения) до момента передачи в архив можно представить в виде схем, приведенных ниже (рисунок 1.3).

Поступление документов на предприятие

Сортирование документов

Регистрация документов

Передача документов руководителю администрации (руководителям структурных подразделений)

Принятие решений руководителем

Направление документов на исполнение

Исполнение документов

Текущее хранение документов

Передача документов в архив

Рисунок 1.3 - Жизненный цикл документа

Цели автоматизации документооборота организации

Безбумажный документооборот предусматривает применение компьютера в управленческой деятельности для хранения, поиска и отображения информации, позволяя свести к минимуму или исключить полностью применение бумажных носителей.

Необходимость автоматизации документооборота продиктована проблемами, возникающими в работе компаний всех организационно-правовых форм, которые по сути своей идентичны:

  • потеря документа, либо его долгий поиск (большой объем документации;
  • поиск документов в рамках организации затруднен из-за децентрализованной регистрации);
  • задержки прохождения и исполнения документов (сложные схемы согласования документов и человеческий фактор);
  • фактическая бесконтрольность исполнения (отсутствие информации об исполнении и исполнителе в реальном времени);
  • проблемы контроля исполнения документа (отсутствие или плохая организация упреждающего контроля;
  • неисполнение документов или задержка их исполнения); избыточность документооборота (в т.ч. дублирование документов);
  • большой штат сотрудников, работающих с документами (рутинные технологические операции) и др.

Цели автоматизации документооборота организации, вне зависимости от организационно-правовых форм, довольно схожи и заключаются в следующем:

  • повышение качества и оперативности управления, и как следствие этого обеспечение конкурентоспособности администрации на рынке;
  • объединение в единый документооборотенный цикл всех структурных подразделений организации, включая территориально-удаленные;
  • обеспечение оперативного, и в то же время разграниченного доступа к информационным (документационным) ресурсам организации;
  • снижение трудовых и временных затрат и накладных расходов, и как следствие, получение экономического эффекта;
  • заложение основы постепенного перехода к электронному документообороту на предприятии, работа на перспективу.

Достижение поставленных целей возможно посредством решения задач автоматизации документооборота организации, которые условно можно систематизировать по следующим областям:

Подготовка и оформление документов.

  • повышение качества и оперативности подготовки документов, создаваемых в организации;
  • унификация процесса работы с документами на всех этапах его существования;

Организация документооборота и исполнения документов.

  • исключение дублирования ввода информации о документе на различных этапах работы с ним (процесс регистрации)
  • исключение возможности потери документа (создание документальной базы организации);
  • упорядочение документооборота организации (упрощение схем прохождения документов – маршрутизация);
  • повышение оперативности и качества работы исполнителей с документами;
  • сокращение сроков исполнения и прохождения документов;
  • своевременное информирование сотрудников и руководства о поступивших и создаваемых документах (исключение дублирования работы над одним и тем же документом);

Организация контроля исполнения документов.

  • объединение документационных потоков всех подразделений организации (в том числе территориально-удаленных);
  • оперативное получение информации о состоянии исполнения и месте нахождения любого документа;
  • обеспечение отслеживания этапов прохождением документов в подразделениях организации с момента их получения (создания) до завершения работы с ними (исполнения).

Организация хранения документов, поисковая система.

  • обеспечение централизованного хранения текстов документов, подготовленных в электронном виде, их графических образов и материалов к ним;
  • обеспечение возможности оперативного поиска и организации логического связывания документов, относящихся к одному вопросу;
  • обеспечение оперативного поиска и подборки документов (материалов) по тематическому набору реквизитов;

Таким образом, суммируя все выше сказанное можно сделать вывод: автоматизация документационного обеспечения управления организации, вне зависимости от организационно-правовых форм, ввиду комплексного подхода к решению проблем документооборота, повышает оперативность управления, эффективность работы ее сотрудников, а, следовательно, приводит к повышению конкурентоспособности на рынке.

История развития информационных систем в управлении документами

Огромное увеличение объемов информации и большие изменения спроса информации стали предъявлять новые требования к организации информационно-документационного обслуживания в организации. Стали меняться требования к службам, занимающимся информационно-документационным обеспечением. За рубежом их стали называть службой управления (или менеджмента) информационно-документационными ресурсами, в нашей стране – службой документационного обеспечения управления (ДОУ).

1.2 Выбор средства для моделирования бизнес-процессов

Одним из первых и основных этапов проекта по описанию бизнес-процессов компании является выбор методов и инструментальных средств моделирования.

В настоящее время на рынке программного обеспечения есть большое количество продуктов, предназначенных для моделирования деятельности предприятия, в основу каждого из них заложена определенная методология.

В целом выделяют два подхода к моделированию.

Структурно-алгоритмический – основными строительными блоками модели при использовании данного подхода являются функции (процедуры). Модель представляет собой выстроенную последовательность функций, при этом имеется возможность их декомпозиции на составные части; на вход каждой функции поступают некоторые данные, на выходе имеются определенные результаты ее выполнения, показывается ресурсное окружение функции – люди, информационные системы, регламенты.

К этому блоку относится методология IDEF; инструментом, реализующим данную методологию, является BPWin.

Объектно-ориентированный подход предполагает использование объектов – сущностей, обладающих идентичностью, состоянием и поведением. Модель в данном случае представляет собой всестороннее описание объекта исследования – кроме описания собственно бизнес-процесса, в ней содержится описание: организационной структуры предприятия, структуры информационных систем, операционных и регламентирующих документов. При моделировании в соответствии с объектно-ориентированным подходом создается единая база данных объектов модели, благодаря этому появляется возможность отслеживания взаимосвязей между объектами и безызбыточности построенной модели.

Методологии, поддерживающие объектно-ориентированный принцип: методология Aris (группа продуктов IDS Sheer «Aris») и методология UML (продукт Rational Rose). Методология UML в основном ориентирована на разработку программного обеспечения, Aris используется для описания бизнес-процессов предприятия.

Aris в том числе предоставляет возможность оценки процессов по заданным параметрам, например с точки зрения времени и стоимости их выполнения.

При моделировании деятельности организации в случае обоснования необходимости возможна интеграция нескольких систем, в этом случае в их состав должны входить соответствующие механизмы экспорта/импорта.

В России для моделирования и анализа бизнес-процессов достаточно широко используются следующие средства моделирования: Rational Rose, Oracle Designer, AllFusion Process Modeler (BPWin) и AllFusion ERwin Data Modeler (ERWin), ARIS, Power Designer. За рубежом, помимо упомянутых, активно используются такие средства, как System Architect, Ithink Analyst, ReThink и др. В табл. 1.1 представлен перечень инструментальных средств, участвующих в рассмотрении. Приведенная информация включает:

- наименование инструментального средства;

- данные о поставщике и представителе в России;

- краткую характеристику инструментального средства.

Таблица 1.2

Средства моделирования

http://www.nnre.ru/kompyutery_i_internet/praktika_i_problematika_modelirovanija_biznes_processov/i_013.jpg
http://www.nnre.ru/kompyutery_i_internet/praktika_i_problematika_modelirovanija_biznes_processov/i_014.jpg
http://www.nnre.ru/kompyutery_i_internet/praktika_i_problematika_modelirovanija_biznes_processov/i_015.jpg
http://www.nnre.ru/kompyutery_i_internet/praktika_i_problematika_modelirovanija_biznes_processov/i_016.jpg

Выделим основные критерии, позволяющие из представленных средств моделирования выбрать те, применение которых в России могло бы с большей вероятностью себя оправдать. Такими критериями являются:

- устойчивое положение продукта на рынке (срок его существования, программа развития продукта, система отчетов о проблемах, совокупность применений и др.);

- распространенность продукта (количество проданных лицензий, наличие, размер и уровень деятельности пользовательской группы);

- доступность поддержки поставщика. Такие услуги могут включать телефонную «горячую линию», техническую и консультационную поддержку через представителя поставщика в России;

- доступность обучения. Обучение может проводиться на территории представителя поставщика в России, пользователя или где-либо в другом месте;

- доступность материалов по продукту. Они могут включать компьютерные учебные материалы, учебные пособия, книги, статьи, информацию в Интернете, демоверсии.

Из приведенного в таблице списка инструментальных средств для более подробного анализа выделим те программные продукты, которые удовлетворяют указанным критериям. В этом случае в рамки нашего дальнейшего рассмотрения попадают BPWIn/ERWin.

BPWin и ERWin компании СотрШвгAssociates. Computer Associates International, Inc. (CA) входит в пятерку ведущих производителей программного обеспечения, предлагая средства моделирования, резервного копирования, управления инфраструктурой предприятия (сетями, серверами и т. д.), информационной безопасности, business intelligence и т. д. Пакет BPWin основан на методологии IDEF и предназначен для функционального моделирования и анализа деятельности предприятия. Методология IDEF, являющаяся официальным федеральным стандартом США, представляет собой совокупность методов, правил и процедур, предназначенных для построения функциональной модели объекта какой-либо предметной области. Функциональная модель IDEF0 отображает функциональную структуру объекта, то есть производимые им действия и связи между этими действиями.

Возможности BPwin:

- поддерживает сразу три стандартные нотации – IDEF0 (функциональное моделирование), DFD (моделирование потоков данных) и IDEF3 (моделирование потоков работ). Эти три основных ракурса позволяют описывать предметную область наиболее комплексно;

- позволяет оптимизировать процедуры в компании;

- полностью поддерживает методы расчета себестоимости по объему хозяйственной деятельности (функционально-стоимостной анализ, ABC);

- позволяет облегчить сертификацию на соответствие стандартам качества ISO9000;

- интегрирован с ERwin (для моделирования БД), Paradigm Plus (для моделирования компонентов ПО) и др.;

- интегрирован со средством имитационного моделирования Arena;

- содержит собственный генератор отчетов;

- позволяет эффективно манипулировать моделями – сливать и расщеплять их;

- имеет широкий набор средств документирования моделей, проектов.

Пакет ERWin – это средство концептуального моделирования БД. Используется при моделировании и создании баз данных произвольной сложности на основе диаграмм «сущность – связь». В настоящее время ERWin является наиболее популярным пакетом моделирования данных благодаря поддержке широкого спектра СУБД самых различных классов. Возможности ERWin:

- поддерживает методологию структурного моделирования SADT и следующие нотации: стандартную нотацию IDEFlx для ER-диаграмм моделей данных, нотацию IE и специальную нотацию, предназначенную для проектирования хранилищ данных – Dimensional;

- поддерживается прямое (создание БД на основе модели) и обратное (генерация модели по имеющейся базе данных) проектирование для 20 типов СУБД: настольные, реляционные и специализированные СУБД, предназначенные для создания хранилищ данных;

- интегрирован линейкой продуктов Computer Associates для поддержки всех стадий разработки ИС, CASE-средствами Oracle Designer, Rational Rose, средствами разработки и др.;

- позволяет повторно использовать компоненты созданных ранее моделей, а также использовать наработки других разработчиков;

- возможна совместная работа группы проектировщиков с одними и теми же моделями (с помощью AllFusion Model Manager);

- позволяет переносить структуру БД (не сами данные!) из СУБД одного типа в СУБД другого;

- позволяет документировать структуру БД.

1.3 Моделирование бизнес-процессов «как есть»

Отразим действующие процессы документооборота в организации с использованием средств BPwin. Для отражениея этих процессов используем модель AS-IS.

ПРОЦЕСС: Регистрация документа.

ВХОД: Входящий документ.

ВЫХОД: Зарегистрированный входящий документ.

АЛГОРИТМ: Зарегистрировать поступивший входящий документ, присвоив ему уникальный номер, в соответствии с Инструкцией по делопроизводству и внутренним Порядком документооборота.

ПРОЦЕСС: Обработка документа.

ВХОД: Зарегистрированный входящий документ.

ВЫХОД: Исполненный входящий документ, исходящий ответный документ.

АЛГОРИТМ: Исполнить поступивший документ и, если требуется, подготовить и отправить ответный исходящий документ.

ПОДПРОЦЕССЫ:

Вынесение резолюций.

Постановка на контроль.

Исполнение документа.

Снятие с контроля.

ПРОЦЕСС: Списание в дело.

ВХОД: Исполненный входящий документ.

ВЫХОД: Списанный документ.

АЛГОРИТМ: Подшить обработанный документ в дело с соответствующей номенклатурой.

ПРОЦЕСС: Формирование отчетов.

ВХОД: Списанный документ, исходящий ответный документ.

ВЫХОД: Реестр зарегистрированных входящих/ исходящих документов, Реестр документов, переданных на исполнение, Сводка об исполнении документов.

АЛГОРИТМ: Ручное формирование необходимых отчетов.

ПОДПРОЦЕССЫ:

Поиск форм отчетов.

Ручное заполнение форм отчетов.

Печать отчетов.

Эта модель показывает, как функционирует документооборот в организации, когда процессы не автоматизированы.



Рисунок 1.4 – Модель AS-IS процесса «Документооборот в организации»


Рисунок 1.5 – Декомпозиция процесса «Документооборот в организации» в нотации IDЕF0 модели AS-IS


Рисунок 1.6 – Декомпозиция процесса «Обработка документа» модели AS-IS

Рисунок 1.7 - Декомпозиция процесса «Формирование отчетов» модели AS-IS




Рисунок 1.8 - Декомпозиция процесса «Исполнение документа» в нотации IDEF3 модели AS-IS

2 Построение бизнес-процессов «как должно быть»

2.1 Предлагаемые мероприятия по улучшению бизнес-процессов

После внедрения проектируемой информационной системы, организация документооборота будет представлена в виде модели TO-BE.

ПРОЦЕСС: Автоматизированное рабочее место «Делопроизводство».

ВХОД: Входящие документы.

ВЫХОД: Автоматизированные отчеты.

ПОДПРОЦЕССЫ:

АРМ «Делопроизводство: работа с документами».

АРМ «Делопроизводство: отчетность».

ПРОЦЕСС: АРМ «Делопроизводство: работа с документами».

ВХОД: Входящие документы.

ВЫХОД: Исполненные документы, исходящие ответные документы.

АЛГОРИТМ: Автоматизированный учет документов и контроль за их исполнением.

ПОДПРОЦЕССЫ:

Регистрация в АРМ «Делопроизводство».

Рассмотрение документа.

Исполнение документа.

ПРОЦЕСС: АРМ «Делопроизводство: отчетность».

ВХОД: Исполненные документы, исходящие ответные документы.

ВЫХОД: Автоматизированные отчеты.

АЛГОРИТМ: Автоматизирование формирование отчетов и вывод их на бумажные носители.

ПОДПРОЦЕССЫ:

Автоматическая загрузка данных в шаблоны отчетов.

Вывод отчетов.

2.2 Моделирование бизнес-процессов «как должно быть»




Рисунок 2.1 - Модель TO-BE процесса «АРМ “Делопроизводство”»




Рисунок 2.2 - Декомпозиция процесса «АРМ “Делопроизводство”» в нотации IDEF0 модели TO-BE


Рисунок 2.3 - Декомпозиция процесса «АРМ “Делопроизводство: работа с документами”» модели TO-BE




Рисунок 2.4 - Декомпозиция процесса «АРМ “Делопроизводство: отчетность”» модели TO-BE


Рисунок 2.5 – Контекстная диаграмма потоков данных

Заключение

Целью данной работы была разработка модели системы автоматизации документооборота риэлтерской организации. Данная цель была достигнута, и в ходе разработки были реализованы следующие диаграммы и модели:

  • Концептуальная модель системы
  • Диаграмма вариантов использования;
  • Диаграмма классов;
  • Диаграмма состояний.

Все эти диаграммы очень важны при разработке программного кода проекта, они несомненно упрощают задачу разработки программного продукта.

Список литературы

  1. ГОСТ Р ИСО/МЭК 12207/99. Государственный стандарт РФ. Информационная технология. Процессы жизненного цикла информационных систем. Издание официальное. - М., 1999
  2. Схемы алгоритмов, программ, данных и систем. Условные обозначения и правила выполнения. ГОСТ 19.701-90 (ИСО 5807-85) / Государственный комитет СССР по управлению качеством продукции и стандартам, 01.01.1992.
  3. Автоматизированные информационные системы, базы и банки данных. Вводный курс: Учебное пособие, М.: Гелиос АРВ, 2007. - 368 с., ил
  4. Астелс, Дэвид; Миллер Гранвилл; Новак, Мирослав, Практическое руководство по экстремальному программированию, Пер. с англ. - М.: Издательский дом "Вильямс", 2008. - 320 с.: ил. - Парал. тит. англ
  5. Вендров А.М., CASE-технологии. Современные методы и средства проектирования информационных систем - М.: Финансы и статистика, 2007 г, 456 стр.
  6. Вигерс Карл, Разработка требований к программному обеспечению, Пер, с англ. - М.:Издательско-торговый дом "Русская Редакция", 2008. -576с.: ил
  7. Гвоздева Т. В., Б. А. Баллод, Проектирование информационных систем, М, Издательство: Феникс, 2009 г., 512 стр.
  8. Голицына О. Л., И. И. Попов, Н. В. Максимов, Т. Л. Партыка, Информационные технологии, М, Издательство Инфра-М, 2009 г., 608 стр.
  9. Емельянова Н. З., Партыка Т. Л., И. И. Попов, Проектирование информационных систем, М, Издательство: Форум, 2009 г., 432 стр.
  10. Емельянова Н. З., Т. Л. Партыка, И. И. Попов, М, Издательство Форум, 2007 г., , 416 стр.
  11. Илюшечкин В. М. , Основы использования и проектирования баз данных, М, Издательство Юрайт, 2010 г., 224 стр.
  12. Котляров В. П., Т. В. Коликова, Основы тестирования программного обеспечения, Издательства: Интернет-университет информационных технологий, Бином. Лаборатория знаний, 2009 г., 288 стр.
  13. Кузин А. В., С. В. Левонисова, Базы данных, М, Издательство: Академия, 2008 г., 320 стр.
  14. Кузнецов С. Д., Основы баз данных, М, Издательства: Бином. Лаборатория знаний, Интернет-университет информационных технологий, 2007 г., 488 стр.
  15. Молчанов А. Ю., Системное программное обеспечение, М, Издательство: Питер, 2010 г., 400 стр.
  16. Незнанов А. А., Программирование и алгоритмизация, М, Издательство: Академия, 2010 г., 304 стр.
  17. Пирогов В. Ю., Информационные системы и базы данных. М, Организация и проектирование, Издательство: БХВ-Петербург, 2009 г.528 стр.
  18. Предметно-ориентированные экономические информационные системы, М, Издательство: Финансы и статистика, 2007 г., 224 стр.
  19. Реляционные базы данных: практические приемы оптимальных решений. – СПб.: БХВ-Петербург, 2009 – 400с.:ил;

Приложение А – Листинг программы электронного документооборота

///////////////////////////////////////////////////////////////////////////////////////////////

// МОДУЛЬ СОДЕРЖИТ ПРОЦЕДУРЫ И ФУНКЦИИ РАБОТЫ С ВНУТРЕННИМИ, ВХОДЯЩИМИ И ИСХОДЯЩИМИ ДОКУМЕНТАМИ

//

// Формирует наименование документа из заголовка

Функция НаименованиеДокумента(Документ) Экспорт

Заголовок = СокрЛП(Документ.Заголовок);

ДлинаНаименования = Документ.Метаданные().ДлинаНаименования;

Если ЗначениеЗаполнено(Документ.РегистрационныйНомер) Тогда

Постфикс = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(

НСТР("ru = ' (№ %1 от %2)'"),

СокрЛП(Документ.РегистрационныйНомер),

Формат(Документ.ДатаРегистрации, "ДЛФ=D"));

Иначе

Постфикс = "";

КонецЕсли;

Если СтрДлина(Заголовок + Постфикс) > ДлинаНаименования Тогда

Заголовок = Лев(Заголовок, ДлинаНаименования - СтрДлина(Постфикс));

ДлинаЗаголовка = СтрДлина(Заголовок);

ПозицияПробела = ДлинаЗаголовка;

Пока ПозицияПробела > 0 Цикл

Если Сред(Заголовок, ПозицияПробела, 1) = " " Тогда

Прервать;

КонецЕсли;

ПозицияПробела = ПозицияПробела - 1;

КонецЦикла;

Если ПозицияПробела > 1 Тогда

Заголовок = Лев(Заголовок, ПозицияПробела - 1);

КонецЕсли;

КонецЕсли;

Возврат Заголовок + Постфикс;

КонецФункции

// Формирует наименование номенклатуры дел

Функция НаименованиеНоменклатурыДел(НоменклатураДел) Экспорт

Заголовок = НоменклатураДел.ПолноеНаименование;

Заголовок = СтрЗаменить(Заголовок, Символы.ПС, " ");

Заголовок = СокрЛП(Заголовок);

ДлинаНаименования = НоменклатураДел.Метаданные().ДлинаНаименования;

Если СтрДлина(Заголовок) > ДлинаНаименования Тогда

Заголовок = Лев(Заголовок, ДлинаНаименования);

ДлинаЗаголовка = СтрДлина(Заголовок);

ПозицияПробела = ДлинаЗаголовка;

Пока ПозицияПробела > 0 Цикл

Если Сред(Заголовок, ПозицияПробела, 1) = " " Тогда

Прервать;

КонецЕсли;

ПозицияПробела = ПозицияПробела - 1;

КонецЦикла;

Если ПозицияПробела > 1 Тогда

Заголовок = Лев(Заголовок, ПозицияПробела - 1);

КонецЕсли;

КонецЕсли;

Возврат Заголовок;

КонецФункции

// Возвращает количество файлов по документу

Функция КоличествоФайлов(Документ) Экспорт

Если Не ЗначениеЗаполнено(Документ) Тогда

Возврат 0;

КонецЕсли;

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ РАЗРЕШЕННЫЕ

| КОЛИЧЕСТВО(*) КАК Количество

|ИЗ

| Справочник.Файлы КАК Файлы

|ГДЕ

| Файлы.ВладелецФайла = &Документ";

Запрос.УстановитьПараметр("Документ", Документ);

Результат = Запрос.Выполнить();

Если Результат.Пустой() Тогда

Возврат 0;

КонецЕсли;

Выборка = Результат.Выбрать();

Выборка.Следующий();

Возврат Выборка.Количество;

КонецФункции

// Возвращает количество задач по документу

Функция КоличествоЗадач(Документ, ТолькоНевыполненные = Ложь) Экспорт

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ РАЗРЕШЕННЫЕ

| КОЛИЧЕСТВО(*) КАК Количество

|ИЗ

| Задача.ЗадачаИсполнителя КАК ЗадачаИсполнителя

|ГДЕ

| ЗадачаИсполнителя.Предмет = &Документ

| И (НЕ ЗадачаИсполнителя.ПометкаУдаления)";

Если ТолькоНевыполненные Тогда

Запрос.Текст = Запрос.Текст + " И (НЕ ЗадачаИсполнителя.Выполнена)";

КонецЕсли;

Запрос.УстановитьПараметр("Документ", Документ);

Результат = Запрос.Выполнить();

Если Результат.Пустой() Тогда

Возврат 0;

КонецЕсли;

Выборка = Результат.Выбрать();

Выборка.Следующий();

Возврат Выборка.Количество;

КонецФункции

// Возвращает вид документа по умолчанию

Функция ПолучитьВидДокументаПоУмолчанию(Ссылка) Экспорт

ВидДокумента = Неопределено;

Если ТипЗнч(Ссылка) = Тип("СправочникСсылка.ВходящиеДокументы") Тогда

ВидДокумента = ХранилищеОбщихНастроек.Загрузить("НастройкиРаботыСДокументами", "ВидВходящегоДокумента");

ТипМетаданных = "ВидыВходящихДокументов";

ИначеЕсли ТипЗнч(Ссылка) = Тип("СправочникСсылка.ИсходящиеДокументы") Тогда

ВидДокумента = ХранилищеОбщихНастроек.Загрузить("НастройкиРаботыСДокументами", "ВидИсходящегоДокумента");

ТипМетаданных = "ВидыИсходящихДокументов";

ИначеЕсли ТипЗнч(Ссылка) = Тип("СправочникСсылка.ВнутренниеДокументы") Тогда

ВидДокумента = ХранилищеОбщихНастроек.Загрузить("НастройкиРаботыСДокументами", "ВидВнутреннегоДокумента");

ТипМетаданных = "ВидыВнутреннихДокументов";

КонецЕсли;

Если Не ЗначениеЗаполнено(ВидДокумента) Тогда

Запрос = Новый Запрос;

Запрос.Текст = СтрЗаменить(

"ВЫБРАТЬ РАЗРЕШЕННЫЕ ПЕРВЫЕ 1

| ТаблицаВидаДокументов.Ссылка КАК Ссылка

|ИЗ

| &ВидДокумента КАК ТаблицаВидаДокументов

|ГДЕ

| (НЕ ТаблицаВидаДокументов.ПометкаУдаления)

| И (НЕ ТаблицаВидаДокументов.ЭтоГруппа)

| И ЛОЖЬ В

| (ВЫБРАТЬ

| ЛОЖЬ КАК ЗначениеЛожь

| ИЗ

| (ВЫБРАТЬ ПЕРВЫЕ 2

| ИСТИНА КАК ЗначениеИстина

| ИЗ

| &ВидДокумента КАК ТаблицаВидаДокументов

| ГДЕ

| (НЕ ТаблицаВидаДокументов.ПометкаУдаления)

| И (НЕ ТаблицаВидаДокументов.ЭтоГруппа)

| ) КАК ВыбранныеОбъекты

| ИМЕЮЩИЕ

| КОЛИЧЕСТВО(ВыбранныеОбъекты.ЗначениеИстина) = 1)", "&ВидДокумента", "Справочник." + ТипМетаданных);

Результат = Запрос.Выполнить();

Если Не Результат.Пустой() Тогда

Выборка = Результат.Выбрать();

Выборка.Следующий();

ВидДокумента = Выборка.Ссылка;

КонецЕсли;

КонецЕсли;

Возврат ВидДокумента;

КонецФункции

// Возвращает способ доставки по умолчанию

Функция ПолучитьСпособДоставкиПоУмолчанию(Тип) Экспорт

СпособДоставки = Справочники.СпособыДоставки.ПустаяСсылка();

Если Тип = "СпособПолучения" Тогда

СпособДоставки = ХранилищеОбщихНастроек.Загрузить("НастройкиРаботыСДокументами", "СпособПолучения");

ИначеЕсли Тип = "СпособОтправки" Тогда

СпособДоставки = ХранилищеОбщихНастроек.Загрузить("НастройкиРаботыСДокументами", "СпособОтправки");

КонецЕсли;

Если Не ЗначениеЗаполнено(СпособДоставки) Тогда

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ РАЗРЕШЕННЫЕ ПЕРВЫЕ 1

| СпособыДоставки.Ссылка КАК Ссылка

|ИЗ

| Справочник.СпособыДоставки КАК СпособыДоставки

|ГДЕ

| (НЕ СпособыДоставки.ПометкаУдаления)

| И ЛОЖЬ В

| (ВЫБРАТЬ

| ЛОЖЬ КАК ЗначениеЛожь

| ИЗ

| (ВЫБРАТЬ ПЕРВЫЕ 2

| ИСТИНА КАК ЗначениеИстина

| ИЗ

| Справочник.СпособыДоставки КАК СпособыДоставки

| ГДЕ

| (НЕ СпособыДоставки.ПометкаУдаления)

| ) КАК ВыбранныеОбъекты

| ИМЕЮЩИЕ

| КОЛИЧЕСТВО(ВыбранныеОбъекты.ЗначениеИстина) = 1)";

Результат = Запрос.Выполнить();

Если Не Результат.Пустой() Тогда

Выборка = Результат.Выбрать();

Выборка.Следующий();

СпособДоставки = Выборка.Ссылка;

КонецЕсли;

КонецЕсли;

Возврат СпособДоставки;

КонецФункции

Функция ПолучитьВалютуПоУмолчанию() Экспорт

Валюта = ХранилищеОбщихНастроек.Загрузить("НастройкиРаботыСДокументами", "Валюта");

Если ЗначениеЗаполнено(Валюта) Тогда

Возврат Валюта;

КонецЕсли;

Валюта = Константы.ОсновнаяВалюта.Получить();

Возврат Валюта;

КонецФункции

// Получает актуальное состояние документа

Функция ПолучитьСостояниеДокумента(Документ) Экспорт

Если Не ПолучитьФункциональнуюОпцию("ИспользоватьСостоянияДокументов") Тогда

Возврат Перечисления.СостоянияДокументов.ПустаяСсылка();

КонецЕсли;

Если Не ЗначениеЗаполнено(Документ) Тогда

Возврат Перечисления.СостоянияДокументов.ПустаяСсылка();

КонецЕсли;

УстановитьПривилегированныйРежим(Истина);

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| СостоянияДокументовСрезПоследних.Состояние КАК Состояние

|ИЗ

| РегистрСведений.СостоянияДокументов.СрезПоследних(, Документ = &Документ) КАК СостоянияДокументовСрезПоследних";

Запрос.УстановитьПараметр("Документ", Документ);

Результат = Запрос.Выполнить();

Если Результат.Пустой() Тогда

Возврат Перечисления.СостоянияДокументов.ПустаяСсылка();

КонецЕсли;

Выборка = Результат.Выбрать();

Выборка.Следующий();

Возврат Выборка.Состояние;

КонецФункции

// Устанавливает состояние документа

Процедура ЗаписатьСостояниеДокумента(Документ, Период, Состояние, Установил) Экспорт

Если Не ПолучитьФункциональнуюОпцию("ИспользоватьСостоянияДокументов") Тогда

Возврат;

КонецЕсли;

ТекущееСостояние = ПолучитьСостояниеДокумента(Документ);

Если ТекущееСостояние = Состояние Тогда

Возврат;

КонецЕсли;

УстановитьПривилегированныйРежим(Истина);

МенеджерЗаписи = РегистрыСведений.СостоянияДокументов.СоздатьМенеджерЗаписи();

МенеджерЗаписи.Период = Период;

МенеджерЗаписи.Документ = Документ;

МенеджерЗаписи.Состояние = Состояние;

МенеджерЗаписи.Установил = Установил;

МенеджерЗаписи.Записать();

КонецПроцедуры

// Удаляет все состояния документа, установленные объектом Установил

//

Процедура УдалитьСостояниеДокумента(Документ, Установил) Экспорт

Если Не ПолучитьФункциональнуюОпцию("ИспользоватьСостоянияДокументов") Тогда

Возврат;

КонецЕсли;

УстановитьПривилегированныйРежим(Истина);

Набор = РегистрыСведений.СостоянияДокументов.СоздатьНаборЗаписей();

Набор.Отбор.Документ.Установить(Документ);

Набор.Прочитать();

ЗаписиКУдалению = Новый Массив;

Для каждого Запись Из Набор Цикл

Если Запись.Установил = Установил Тогда

ЗаписиКУдалению.Добавить(Запись);

КонецЕсли;

КонецЦикла;

Для каждого Запись Из ЗаписиКУдалению Цикл

Набор.Удалить(Запись);

КонецЦикла;

Набор.Записать(Истина);

КонецПроцедуры

// Возвращает ключ актуального состояния документа

Функция ПолучитьКлючСостоянияДокумента(Документ) Экспорт

Если Не ЗначениеЗаполнено(Документ) Тогда

Возврат Неопределено;

КонецЕсли;

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| СостоянияДокументовСрезПоследних.Период КАК Период

|ИЗ

| РегистрСведений.СостоянияДокументов.СрезПоследних(, Документ = &Документ) КАК СостоянияДокументовСрезПоследних";

Запрос.УстановитьПараметр("Документ", Документ);

Результат = Запрос.Выполнить();

Если Результат.Пустой() Тогда

Возврат Неопределено;

КонецЕсли;

Выборка = Результат.Выбрать();

Выборка.Следующий();

Возврат РегистрыСведений.СостоянияДокументов.СоздатьКлючЗаписи( Новый Структура("Период, Документ", Выборка.Период, Документ) );

КонецФункции

// Возвращает признак использования видов входящих документов

Функция ИспользоватьВидыВходящихДокументов() Экспорт

Возврат ПолучитьФункциональнуюОпцию("ИспользоватьВидыВходящихДокументов");

КонецФункции

// Возвращает признак использования видов исходящих документов

Функция ИспользоватьВидыИсходящихДокументов() Экспорт

Возврат ПолучитьФункциональнуюОпцию("ИспользоватьВидыИсходящихДокументов");

КонецФункции

// Возвращает признак использования видов внутренних документов

Функция ИспользоватьВидыВнутреннихДокументов() Экспорт

Возврат ПолучитьФункциональнуюОпцию("ИспользоватьВидыВнутреннихДокументов");

КонецФункции

// Возвращает признак использования видов документов по объекту

Функция ИспользоватьВидыДокументов(ВидДокумента) Экспорт

ИспользоватьВидыДокументов = Ложь;

Если ТипЗнч(ВидДокумента) = Тип("СправочникСсылка.ВидыВходящихДокументов") Тогда

ИспользоватьВидыДокументов = Делопроизводство.ИспользоватьВидыВходящихДокументов();

ИначеЕсли ТипЗнч(ВидДокумента) = Тип("СправочникСсылка.ВидыИсходящихДокументов") Тогда

ИспользоватьВидыДокументов = Делопроизводство.ИспользоватьВидыИсходящихДокументов();

ИначеЕсли ТипЗнч(ВидДокумента) = Тип("СправочникСсылка.ВидыВнутреннихДокументов") Тогда

ИспользоватьВидыДокументов = Делопроизводство.ИспользоватьВидыВнутреннихДокументов();

КонецЕсли;

Возврат ИспользоватьВидыДокументов;

КонецФункции

// Возвращает признак использования номенклатуры дел

Функция ИспользоватьНоменклатуруДел() Экспорт

Возврат ПолучитьФункциональнуюОпцию("ИспользоватьНоменклатуруДел");

КонецФункции

// Проверяет уникальность регистрационного номера

Функция РегистрационныйНомерУникален(Объект) Экспорт

УстановитьПривилегированныйРежим(Истина);

Нумератор = Нумерация.ПолучитьНумераторДокумента(Объект.ВидДокумента);

Если ЗначениеЗаполнено(Нумератор) Тогда // автонумерация

Периодичность = Нумератор.Периодичность;

Иначе // ручная нумерация

Периодичность = Перечисления.ПериодичностьНумераторов.Год;

КонецЕсли;

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| Ссылка

|ИЗ

| Справочник." + Объект.Ссылка.Метаданные().Имя + " КАК Справочник ";

Если Нумератор.НезависимаяНумерацияПоСвязанномуДокументу Тогда

Запрос.Текст = Запрос.Текст +

" ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.СвязиДокументов КАК СвязиДокументов

| ПО СвязиДокументов.Документ = Справочник.Ссылка И СвязиДокументов.ТипСвязи = &ТипСвязи ";

Запрос.УстановитьПараметр("ТипСвязи", Нумератор.ТипСвязи);

КонецЕсли;

Запрос.Текст = Запрос.Текст +

" ГДЕ

| РегистрационныйНомер = &РегистрационныйНомер

| И ДатаРегистрации МЕЖДУ &НачалоПериодаНумерации И &КонецПериодаНумерации

| И Ссылка <> &Ссылка ";

Если ПолучитьФункциональнуюОпцию("ИспользоватьУчетПоОрганизациям") И Нумератор.НезависимаяНумерацияПоОрганизациям Тогда

Запрос.Текст = Запрос.Текст + " И (Организация = &Организация) ";

Запрос.УстановитьПараметр("Организация", Объект.Организация);

КонецЕсли;

Если Нумератор.НезависимаяНумерацияПоСвязанномуДокументу Тогда

СвязанныйДокумент = СвязиДокументов.ПолучитьСвязанныйДокумент(Объект.Ссылка, Нумератор.ТипСвязи);

Если ЗначениеЗаполнено(СвязанныйДокумент) Тогда

Запрос.Текст = Запрос.Текст + " И (СвязанныйДокумент = &СвязанныйДокумент) ";

Запрос.УстановитьПараметр("СвязанныйДокумент", СвязанныйДокумент);

КонецЕсли;

КонецЕсли;

Если ИспользоватьВидыДокументов(Объект.ВидДокумента) Тогда

Если ЗначениеЗаполнено(Нумератор) Тогда // проверка уникальности в рамках нумератора

Запрос.Текст = Запрос.Текст + " И (ВидДокумента.Нумератор = &Нумератор) ";

Запрос.УстановитьПараметр("Нумератор", Нумератор);

Иначе

Запрос.Текст = Запрос.Текст + " И (ВидДокумента = &ВидДокумента) ";

Запрос.УстановитьПараметр("ВидДокумента", Объект.ВидДокумента);

КонецЕсли;

КонецЕсли;

Запрос.УстановитьПараметр("РегистрационныйНомер", Объект.РегистрационныйНомер);

Запрос.УстановитьПараметр("НачалоПериодаНумерации", Нумерация.НачалоПериодаНумерации(Периодичность, Объект.ДатаРегистрации));

Запрос.УстановитьПараметр("КонецПериодаНумерации", Нумерация.КонецПериодаНумерации(Периодичность, Объект.ДатаРегистрации));

Запрос.УстановитьПараметр("Ссылка", Объект.Ссылка);

Результат = Запрос.Выполнить();

Возврат Результат.Пустой();

КонецФункции

// Устанавливает доступность полей карточки документа в зависимости от состояния

Процедура УстановитьДоступностьПоСостоянию(Форма, Состояние, ДоступныеПоля = "") Экспорт

ДоступныеПоля = "";

НедоступныеПоля = "";

НеизменяемыеПоля = "";

Если Не ПолучитьФункциональнуюОпцию("ИспользоватьСостоянияДокументов") Тогда

Возврат;

КонецЕсли;

Если РольДоступна("ПолныеПрава") Тогда

Возврат;

КонецЕсли;

Если ТипЗнч(Форма.Объект.Ссылка) = Тип("СправочникСсылка.ВходящиеДокументы") Тогда

РольДелопроизводитель = РольДоступна("ДобавлениеИзменениеВходящихДокументов");

НеизменяемыеПоля = Новый Структура("

|ОтправленОтвет,

|ОтветПереадресовавшему,

|ПереадресованДокументом, КонтактноеЛицоПереадресата, Переадресат, Переадресовать,

|Категории,

|ИсторияСогласования, ВизыСогласованияПечатьЛистСогласования,

|ГруппаЭЦП, ФормаПодписать, ФайлыПодписатьФайл, ФайлыДобавитьЭЦПИзФайла, ФайлыСохранитьВместеСЭЦП,

|ФайлыКонтекстноеМенюПодписатьФайл, ФайлыКонтекстноеМенюДобавитьЭЦПИзФайла, ФайлыКонтекстноеМенюСохранитьВместеСЭЦП,

|Комментарий");

ИначеЕсли ТипЗнч(Форма.Объект.Ссылка) = Тип("СправочникСсылка.ИсходящиеДокументы") Тогда

РольДелопроизводитель = РольДоступна("РегистрацияИсходящихДокументов");

НеизменяемыеПоля = Новый Структура("

|ПолученОтвет,

|Категории,

|ИсторияСогласования, ВизыСогласованияПечатьЛистСогласования,

|ГруппаЭЦП, ФормаПодписать, ФайлыПодписатьФайл, ФайлыДобавитьЭЦПИзФайла, ФайлыСохранитьВместеСЭЦП,

|ФайлыКонтекстноеМенюПодписатьФайл, ФайлыКонтекстноеМенюДобавитьЭЦПИзФайла, ФайлыКонтекстноеМенюСохранитьВместеСЭЦП,

|Комментарий");

ИначеЕсли ТипЗнч(Форма.Объект.Ссылка) = Тип("СправочникСсылка.ВнутренниеДокументы") Тогда

РольДелопроизводитель = РольДоступна("РегистрацияВнутреннихДокументов");

НеизменяемыеПоля = Новый Структура("

|Категории,

|ИсторияСогласования, ВизыСогласованияПечатьЛистСогласования,

|ГруппаЭЦП, ФормаПодписать, ФайлыПодписатьФайл, ФайлыДобавитьЭЦПИзФайла, ФайлыСохранитьВместеСЭЦП,

|ФайлыКонтекстноеМенюПодписатьФайл, ФайлыКонтекстноеМенюДобавитьЭЦПИзФайла, ФайлыКонтекстноеМенюСохранитьВместеСЭЦП,

|Комментарий,

|НеДействуетВСоответствии");

КонецЕсли;

// Рабочие группы

Если ТипЗнч(НеизменяемыеПоля) = Тип("Структура") Тогда

НеизменяемыеПоля.Вставить("РабочаяГруппаТаблица");

НеизменяемыеПоля.Вставить("РабочаяГруппаТаблицаУчастник");

НеизменяемыеПоля.Вставить("ПодобратьУчастниковРабочейГруппы");

НеизменяемыеПоля.Вставить("РабочаяГруппаТаблицаДобавить");

НеизменяемыеПоля.Вставить("РабочаяГруппаТаблицаУдалить");

НеизменяемыеПоля.Вставить("РабочаяГруппаТаблицаРабочаяГруппаОбновить");

НеизменяемыеПоля.Вставить("РабочаяГруппаТаблицаВывестиСписок");

НеизменяемыеПоля.Вставить("ПерезаполнитьРабочуюГруппуДокумента");

НеизменяемыеПоля.Вставить("ЗапретитьАвтоматическоеДобавлениеУчастниковРабочейГруппы");

КонецЕсли;

Если Константы.ОграничиватьДоступностьПолейПоСостоянию.Получить() Тогда

Если Состояние = Перечисления.СостоянияДокументов.НаРегистрации Тогда

Если РольДелопроизводитель Тогда

ДоступныеПоля = "";

НедоступныеПоля = "";

Иначе

ДоступныеПоля = Новый Структура("

|Состояние,

|ОткрытьФайл, СохранитьКак, НастроитьСписок, ВывестиСписок, Изменить,

|КонтекстноеМенюФайлыОткрытьФайл, КонтекстноеМенюФайлыСохранитьКак");

КонецЕсли;

ИначеЕсли (Состояние = Перечисления.СостоянияДокументов.Зарегистрирован)

И (ТипЗнч(Форма.Объект.Ссылка) = Тип("СправочникСсылка.ВходящиеДокументы")) Тогда

Если РольДелопроизводитель Тогда

ДоступныеПоля = Новый Структура("

|Зарегистрировать, РегистрационныйНомер, ДатаРегистрации,

|Резолюции, РезолюцииДобавить, РезолюцииИзменить, РезолюцииУдалить,

|Состояние,

|СрокИсполнения, Дело,

|ОткрытьФайл, СохранитьКак, НастроитьСписок, ВывестиСписок, Изменить,

|КонтекстноеМенюФайлыОткрытьФайл, КонтекстноеМенюФайлыСохранитьКак");

Иначе

ДоступныеПоля = Новый Структура("

|ОткрытьФайл, СохранитьКак, НастроитьСписок, ВывестиСписок, Изменить,

|КонтекстноеМенюФайлыОткрытьФайл, КонтекстноеМенюФайлыСохранитьКак");

КонецЕсли;

ИначеЕсли (Состояние = Перечисления.СостоянияДокументов.Зарегистрирован)

И (ТипЗнч(Форма.Объект.Ссылка) = Тип("СправочникСсылка.ИсходящиеДокументы")) Тогда

Если РольДелопроизводитель Тогда

Если Форма.Объект.Получатели.НайтиСтроки(Новый Структура("Отправлен", Истина)).Количество() > 0 Тогда

ДоступныеПоля = Новый Структура("

|Зарегистрировать, РегистрационныйНомер, ДатаРегистрации,

|Состояние,

|СрокИсполнения, Дело,

|Отправлен, ДатаОтправки, СпособОтправки, ВходящийНомер, ВходящаяДата,

|Получатели, ПолучателиОтправлен, ПолучателиДатаОтправки, ПолучателиСпособОтправки, ПолучателиВходящийНомер, ПолучателиВходящаяДата,

|ОткрытьФайл, СохранитьКак, НастроитьСписок, ВывестиСписок, Изменить,

|КонтекстноеМенюФайлыОткрытьФайл, КонтекстноеМенюФайлыСохранитьКак");

Иначе

ДоступныеПоля = Новый Структура("

|Зарегистрировать, РегистрационныйНомер, ДатаРегистрации,

|Состояние,

|СрокИсполнения, Дело,

|ЗакончитьРедактирование, Занять, Освободить, Редактировать, СохранитьИзменения, ОбновитьИзФайлаНаДиске, ФайлыЗашифровать, ФайлыРасшифровать, ФайлыКонтекстноеМенюЗашифровать, ФайлыКонтекстноеМенюРасшифровать,

|КонтекстноеМенюФайлыЗакончитьРедактирование, КонтекстноеМенюФайлыЗанять, КонтекстноеМенюФайлыОсвободить, КонтекстноеМенюФайлыРедактировать, КонтекстноеМенюФайлыСохранитьИзменения, КонтекстноеМенюФайлыОбновитьИзФайлаНаДиске,

|Отправлен, ДатаОтправки, СпособОтправки, ВходящийНомер, ВходящаяДата,

|Получатели, ПолучателиОтправлен, ПолучателиДатаОтправки, ПолучателиСпособОтправки, ПолучателиВходящийНомер, ПолучателиВходящаяДата,

|Файлы, СоздатьФайл, ОткрытьФайл, СохранитьКак, НастроитьСписок, ВывестиСписок, Изменить,

|КонтекстноеМенюФайлыОткрытьФайл, КонтекстноеМенюФайлыСохранитьКак");

КонецЕсли;

Иначе

ДоступныеПоля = Новый Структура("

|ОткрытьФайл, СохранитьКак, НастроитьСписок, ВывестиСписок, Изменить,

|КонтекстноеМенюФайлыОткрытьФайл, КонтекстноеМенюФайлыСохранитьКак");

КонецЕсли;

ИначеЕсли (Состояние = Перечисления.СостоянияДокументов.Зарегистрирован)

И (ТипЗнч(Форма.Объект.Ссылка) = Тип("СправочникСсылка.ВнутренниеДокументы")) Тогда

Если РольДелопроизводитель Тогда

ДоступныеПоля = Новый Структура("

|НеДействует, ДатаОкончанияДействия, Бессрочный, ПорядокПродления,

|Зарегистрировать, РегистрационныйНомер, ДатаРегистрации,

|Состояние, Папка,

|СрокИсполнения, СрокДействияСтрока, Дело, Отменен, ОтмененДокументом,

|ЗакончитьРедактирование, Занять, Освободить, Редактировать, СохранитьИзменения, ОбновитьИзФайлаНаДиске, ФайлыЗашифровать, ФайлыРасшифровать, ФайлыКонтекстноеМенюЗашифровать, ФайлыКонтекстноеМенюРасшифровать,

|КонтекстноеМенюФайлыЗакончитьРедактирование, КонтекстноеМенюФайлыЗанять, КонтекстноеМенюФайлыОсвободить, КонтекстноеМенюФайлыРедактировать, КонтекстноеМенюФайлыСохранитьИзменения, КонтекстноеМенюФайлыОбновитьИзФайлаНаДиске,

|Файлы, СоздатьФайл, ОткрытьФайл, СохранитьКак, НастроитьСписок, ВывестиСписок, Изменить,

|КонтекстноеМенюФайлыОткрытьФайл, КонтекстноеМенюФайлыСохранитьКак");

Иначе

ДоступныеПоля = Новый Структура("

|СрокДействияСтрока,

|ОткрытьФайл, СохранитьКак, НастроитьСписок, ВывестиСписок, Изменить,

|КонтекстноеМенюФайлыОткрытьФайл, КонтекстноеМенюФайлыСохранитьКак");

КонецЕсли;

ИначеЕсли Состояние = Перечисления.СостоянияДокументов.НаРассмотрении Тогда

Если РольДелопроизводитель Тогда

ДоступныеПоля = Новый Структура("

|Зарегистрировать, РегистрационныйНомер, ДатаРегистрации,

|Состояние, Папка,

|СрокИсполнения,

|Резолюции, РезолюцииДобавить, РезолюцииИзменить, РезолюцииУдалить,

|ОткрытьФайл, СохранитьКак, НастроитьСписок, ВывестиСписок, Изменить,

|КонтекстноеМенюФайлыОткрытьФайл, КонтекстноеМенюФайлыСохранитьКак");

Иначе

ДоступныеПоля = Новый Структура("

|Резолюции, РезолюцииДобавить, РезолюцииИзменить, РезолюцииУдалить,

|ОткрытьФайл, СохранитьКак, НастроитьСписок, ВывестиСписок, Изменить,

|КонтекстноеМенюФайлыОткрытьФайл, КонтекстноеМенюФайлыСохранитьКак");

КонецЕсли;

ИначеЕсли Состояние = Перечисления.СостоянияДокументов.Рассмотрен Тогда

Если РольДелопроизводитель Тогда

ДоступныеПоля = Новый Структура("

|Зарегистрировать, РегистрационныйНомер, ДатаРегистрации,

|Состояние, Папка,

|СрокИсполнения,

|ОткрытьФайл, СохранитьКак, НастроитьСписок, ВывестиСписок, Изменить,

|КонтекстноеМенюФайлыОткрытьФайл, КонтекстноеМенюФайлыСохранитьКак");

Иначе

ДоступныеПоля = Новый Структура("

|ОткрытьФайл, СохранитьКак, НастроитьСписок, ВывестиСписок, Изменить,

|КонтекстноеМенюФайлыОткрытьФайл, КонтекстноеМенюФайлыСохранитьКак");

КонецЕсли;

ИначеЕсли Состояние = Перечисления.СостоянияДокументов.НаИсполнении Тогда

Если РольДелопроизводитель Тогда

ДоступныеПоля = Новый Структура("

|НеДействует, ДатаОкончанияДействия, Бессрочный, ПорядокПродления,

|Зарегистрировать, РегистрационныйНомер, ДатаРегистрации,

|Состояние, Папка,

|СрокИсполнения,

|Резолюции, РезолюцииДобавить, РезолюцииИзменить, РезолюцииУдалить,

|ОткрытьФайл, СохранитьКак, НастроитьСписок, ВывестиСписок, Изменить,

|КонтекстноеМенюФайлыОткрытьФайл, КонтекстноеМенюФайлыСохранитьКак");

Иначе

ДоступныеПоля = Новый Структура("

|Резолюции, РезолюцииДобавить, РезолюцииИзменить, РезолюцииУдалить,

|ОткрытьФайл, СохранитьКак, НастроитьСписок, ВывестиСписок, Изменить,

|КонтекстноеМенюФайлыОткрытьФайл, КонтекстноеМенюФайлыСохранитьКак");

КонецЕсли;

ИначеЕсли Состояние = Перечисления.СостоянияДокументов.Исполнен Тогда

Если РольДелопроизводитель Тогда

ДоступныеПоля = Новый Структура("

|Зарегистрировать, РегистрационныйНомер, ДатаРегистрации,

|Состояние, Папка,

|Дело,

|ОткрытьФайл, СохранитьКак, НастроитьСписок, ВывестиСписок, Изменить,

|КонтекстноеМенюФайлыОткрытьФайл, КонтекстноеМенюФайлыСохранитьКак");

Иначе

ДоступныеПоля = Новый Структура("

|ОткрытьФайл, СохранитьКак, НастроитьСписок, ВывестиСписок, Изменить,

|КонтекстноеМенюФайлыОткрытьФайл, КонтекстноеМенюФайлыСохранитьКак");

КонецЕсли;

ИначеЕсли Состояние = Перечисления.СостоянияДокументов.Проект

Или Состояние = Перечисления.СостоянияДокументов.НеСогласован

Или Состояние = Перечисления.СостоянияДокументов.НеУтвержден Тогда

ДоступныеПоля = "";

НедоступныеПоля = Новый Структура("Подписал, Утвердил, Дело");

ИначеЕсли Состояние = Перечисления.СостоянияДокументов.НаСогласовании Тогда

ДоступныеПоля = Новый Структура("

|Состояние, Папка,

|ВизыСогласования, ВизыСогласованияСоздать, ВизыСогласованияИзменить, ВизыСогласованияУдалить, ВизыСогласованияКонтекстноеМенюСоздать, ВизыСогласованияКонтекстноеМенюИзменить, ВизыСогласованияКонтекстноеМенюУдалить, ВизыСогласованияКонтекстноеМенюОбновить,

|ЗакончитьРедактирование, Занять, Освободить, Редактировать, СохранитьИзменения, ОбновитьИзФайлаНаДиске, ФайлыЗашифровать, ФайлыРасшифровать, ФайлыКонтекстноеМенюЗашифровать, ФайлыКонтекстноеМенюРасшифровать,

|КонтекстноеМенюФайлыЗакончитьРедактирование, КонтекстноеМенюФайлыЗанять, КонтекстноеМенюФайлыОсвободить, КонтекстноеМенюФайлыРедактировать, КонтекстноеМенюФайлыСохранитьИзменения, КонтекстноеМенюФайлыОбновитьИзФайлаНаДиске,

|Файлы, СоздатьФайл, ОткрытьФайл, СохранитьКак, НастроитьСписок, ВывестиСписок, Изменить,

|КонтекстноеМенюФайлыОткрытьФайл, КонтекстноеМенюФайлыСохранитьКак");

ИначеЕсли Состояние = Перечисления.СостоянияДокументов.НаУтверждении Тогда

ДоступныеПоля = Новый Структура("

|Состояние, Папка,

|Подписал, Утвердил,

|ЗакончитьРедактирование, Занять, Освободить, Редактировать, СохранитьИзменения, ОбновитьИзФайлаНаДиске, ФайлыЗашифровать, ФайлыРасшифровать, ФайлыКонтекстноеМенюЗашифровать, ФайлыКонтекстноеМенюРасшифровать,

|КонтекстноеМенюФайлыЗакончитьРедактирование, КонтекстноеМенюФайлыЗанять, КонтекстноеМенюФайлыОсвободить, КонтекстноеМенюФайлыРедактировать, КонтекстноеМенюФайлыСохранитьИзменения, КонтекстноеМенюФайлыОбновитьИзФайлаНаДиске,

|Файлы, СоздатьФайл, ОткрытьФайл, СохранитьКак, НастроитьСписок, ВывестиСписок, Изменить,

|КонтекстноеМенюФайлыОткрытьФайл, КонтекстноеМенюФайлыСохранитьКак");

ИначеЕсли Состояние = Перечисления.СостоянияДокументов.Согласован

Или Состояние = Перечисления.СостоянияДокументов.Утвержден Тогда

Если РольДелопроизводитель Тогда

ДоступныеПоля = Новый Структура("

|Состояние, Папка,

|Зарегистрировать, НоменклатураДел,

|ОткрытьФайл, СохранитьКак, НастроитьСписок, ВывестиСписок, Изменить,

|КонтекстноеМенюФайлыОткрытьФайл, КонтекстноеМенюФайлыСохранитьКак");

Иначе

ДоступныеПоля = Новый Структура("

|Состояние,

|ОткрытьФайл, СохранитьКак, НастроитьСписок, ВывестиСписок, Изменить,

|КонтекстноеМенюФайлыОткрытьФайл, КонтекстноеМенюФайлыСохранитьКак");

КонецЕсли;

КонецЕсли;

Для Каждого Элемент Из Форма.Элементы Цикл

Если ТипЗнч(Элемент) = Тип("ГруппаФормы") И Элемент.Имя <> "ГруппаСвойства" Тогда

Продолжить;

КонецЕсли;

Если ТипЗнч(Элемент) = Тип("ДекорацияФормы") Тогда

Продолжить;

КонецЕсли;

Если ТипЗнч(Элемент) = Тип("КнопкаФормы") И Элемент.Родитель.Имя = "ФормаКоманднаяПанель" Тогда

Продолжить;

КонецЕсли;

Если ТипЗнч(Элемент) = Тип("КнопкаФормы") И Элемент.Родитель.Имя = "КоманднаяПанельФормыСоздатьНаОсновании" Тогда

Продолжить;

КонецЕсли;

Если ТипЗнч(Элемент) = Тип("КнопкаФормы") И Элемент.Родитель.Имя = "ФормаСоздатьНаОсновании" Тогда

Продолжить;

КонецЕсли;

Если ТипЗнч(Элемент) = Тип("КнопкаФормы") И Элемент.Родитель.Имя = "КоманднаяПанельФормыПечать" Тогда

Продолжить;

КонецЕсли;

Если ТипЗнч(Элемент) = Тип("КнопкаФормы") И Элемент.Родитель.Имя = "ФормаПечать" Тогда

Продолжить;

КонецЕсли;

Если НеизменяемыеПоля.Свойство(Элемент.Имя) Тогда

Продолжить;

КонецЕсли;

РодительНеИзменяемоеПоле = Ложь;

ТекущийРодитель = Элемент.Родитель;

Пока ТипЗнч(ТекущийРодитель) <> Тип("УправляемаяФорма") Цикл

Если НеизменяемыеПоля.Свойство(ТекущийРодитель.Имя) Тогда

РодительНеИзменяемоеПоле = Истина;

Прервать;

КонецЕсли;

ТекущийРодитель = ТекущийРодитель.Родитель;

КонецЦикла;

Если РодительНеИзменяемоеПоле Тогда

Продолжить;

КонецЕсли;

Если ДоступныеПоля = "" Тогда

Если (НедоступныеПоля <> "") И НедоступныеПоля.Свойство(Элемент.Имя) Тогда

Доступность = Ложь;

Иначе

Доступность = Истина;

КонецЕсли;

ИначеЕсли ДоступныеПоля.Свойство(Элемент.Имя) Тогда

Доступность = Истина;

Иначе

Доступность = Ложь;

КонецЕсли;

Если ТипЗнч(Элемент) = Тип("КнопкаФормы") Тогда

Элемент.Доступность = Доступность;

Иначе

Элемент.ТолькоПросмотр = Не Доступность;

КонецЕсли;

КонецЦикла;

КонецЕсли;

// доступность поля состояние зависит от настройки

Если Не Константы.РазрешитьРучноеИзменениеСостоянияДокументов.Получить()

И Константы.ИспользоватьБизнесПроцессыИЗадачи.Получить() Тогда

Форма.Элементы.Состояние.ТолькоПросмотр = Истина;

КонецЕсли;

КонецПроцедуры

// Получает контактное лицо корреспондента

Функция КонтактноеЛицоКорреспондента(Корреспондент) Экспорт

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ РАЗРЕШЕННЫЕ ПЕРВЫЕ 1

| КонтактныеЛица.Ссылка КАК КонтактноеЛицо

|ИЗ

| Справочник.КонтактныеЛица КАК КонтактныеЛица

|ГДЕ

| КонтактныеЛица.Владелец = &Владелец

| И (НЕ КонтактныеЛица.ПометкаУдаления)

| И ЛОЖЬ В

| (ВЫБРАТЬ

| ЛОЖЬ КАК ЗначениеЛожь

| ИЗ

| (ВЫБРАТЬ ПЕРВЫЕ 2

| ИСТИНА КАК ЗначениеИстина

| ИЗ

| Справочник.КонтактныеЛица КАК КонтактныеЛица

| ГДЕ

| (НЕ КонтактныеЛица.ПометкаУдаления)

| И КонтактныеЛица.Владелец = &Владелец

| ) КАК ВыбранныеОбъекты

| ИМЕЮЩИЕ

| КОЛИЧЕСТВО(ВыбранныеОбъекты.ЗначениеИстина) = 1)";

Запрос.УстановитьПараметр("Владелец", Корреспондент);

Результат = Запрос.Выполнить();

Если Не Результат.Пустой() Тогда

Выборка = Результат.Выбрать();

Выборка.Следующий();

Возврат Выборка.КонтактноеЛицо;

КонецЕсли;

Возврат Неопределено;

КонецФункции

// Возвращает количество документов переданного вида

Функция КоличествоДокументовПоВидуДокумента(ВидДокумента) Экспорт

УстановитьПривилегированныйРежим(Истина);

Если ТипЗнч(ВидДокумента) = Тип("СправочникСсылка.ВидыВнутреннихДокументов") Тогда

Тип = "ВнутренниеДокументы";

ИначеЕсли ТипЗнч(ВидДокумента) = Тип("СправочникСсылка.ВидыВходящихДокументов") Тогда

Тип = "ВходящиеДокументы";

ИначеЕсли ТипЗнч(ВидДокумента) = Тип("СправочникСсылка.ВидыИсходящихДокументов") Тогда

Тип = "ИсходящиеДокументы";

КонецЕсли;

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| КОЛИЧЕСТВО(*) КАК Количество

|ИЗ

| Справочник." + Тип + "

|ГДЕ

| ВидДокумента = &ВидДокумента

| И РегистрационныйНомер <> """"";

Запрос.УстановитьПараметр("ВидДокумента", ВидДокумента);

Результат = Запрос.Выполнить();

Если Результат.Пустой() Тогда

Возврат 0;

КонецЕсли;

Выборка = Результат.Выбрать();

Выборка.Следующий();

Возврат Выборка.Количество;

КонецФункции

// Возвращает количество документов для переданного нумератора

Функция КоличествоДокументовПоНумератору(Нумератор) Экспорт

УстановитьПривилегированныйРежим(Истина);

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| КОЛИЧЕСТВО(*) КАК Количество

|ИЗ

| Справочник.ВходящиеДокументы КАК ВходящиеДокументы

|ГДЕ

| ВходящиеДокументы.ВидДокумента.Нумератор = &Нумератор

| И ВходящиеДокументы.РегистрационныйНомер <> """"

|

|ОБЪЕДИНИТЬ ВСЕ

|

|ВЫБРАТЬ

| КОЛИЧЕСТВО(*)

|ИЗ

| Справочник.ИсходящиеДокументы КАК ИсходящиеДокументы

|ГДЕ

| ИсходящиеДокументы.ВидДокумента.Нумератор = &Нумератор

| И ИсходящиеДокументы.РегистрационныйНомер <> """"

|

|ОБЪЕДИНИТЬ ВСЕ

|

|ВЫБРАТЬ

| КОЛИЧЕСТВО(*)

|ИЗ

| Справочник.ВнутренниеДокументы КАК ВнутренниеДокументы

|ГДЕ

| ВнутренниеДокументы.ВидДокумента.Нумератор = &Нумератор

| И ВнутренниеДокументы.РегистрационныйНомер <> """"";

Запрос.УстановитьПараметр("Нумератор", Нумератор);

Результат = Запрос.Выполнить();

Если Результат.Пустой() Тогда

Возврат 0;

КонецЕсли;

Возврат Результат.Выгрузить().Итог("Количество");

КонецФункции

// Возвращает количество документов с пустым видом

Функция КоличествоДокументовСПустымВидом(ТипДокумента) Экспорт

УстановитьПривилегированныйРежим(Истина);

Если ТипДокумента = "ВходящийДокумент" Тогда

ТекстЗапроса =

"ВЫБРАТЬ

| КОЛИЧЕСТВО(*) КАК Количество

|ИЗ

| Справочник.ВходящиеДокументы КАК ВходящиеДокументы

|ГДЕ

| ВходящиеДокументы.ВидДокумента = ЗНАЧЕНИЕ(Справочник.ВидыВходящихДокументов.ПустаяСсылка)";

ИначеЕсли ТипДокумента = "ИсходящийДокумент" Тогда

ТекстЗапроса =

"ВЫБРАТЬ

| КОЛИЧЕСТВО(*) КАК Количество

|ИЗ

| Справочник.ИсходящиеДокументы КАК ИсходящиеДокументы

|ГДЕ

| ИсходящиеДокументы.ВидДокумента = ЗНАЧЕНИЕ(Справочник.ВидыИсходящихДокументов.ПустаяСсылка)";

ИначеЕсли ТипДокумента = "ВнутреннийДокумент" Тогда

ТекстЗапроса =

"ВЫБРАТЬ

| КОЛИЧЕСТВО(*) КАК Количество

|ИЗ

| Справочник.ВнутренниеДокументы КАК ВнутренниеДокументы

|ГДЕ

| ВнутренниеДокументы.ВидДокумента = ЗНАЧЕНИЕ(Справочник.ВидыВнутреннихДокументов.ПустаяСсылка)";

КонецЕсли;

Запрос = Новый Запрос(ТекстЗапроса);

Результат = Запрос.Выполнить();

Если Результат.Пустой() Тогда

Возврат 0;

КонецЕсли;

Выборка = Результат.Выбрать();

Выборка.Следующий();

Возврат Выборка.Количество;

КонецФункции

// Инициализирует персональные настройки работы с документами - для использования на клиенте

Функция ПолучитьПерсональныеНастройкиРаботыСДокументамиСервер() Экспорт

Настройки = Новый Структура;

ПоказыватьПредупреждениеПриРегистрации = ХранилищеОбщихНастроек.Загрузить("НастройкиРаботыСДокументами", "ПоказыватьПредупреждениеПриРегистрации");

Если ПоказыватьПредупреждениеПриРегистрации = Неопределено Тогда

ПоказыватьПредупреждениеПриРегистрации = Истина;

ХранилищеОбщихНастроек.Сохранить("НастройкиРаботыСДокументами", "ПоказыватьПредупреждениеПриРегистрации", ПоказыватьПредупреждениеПриРегистрации);

КонецЕсли;

Настройки.Вставить("ПоказыватьПредупреждениеПриРегистрации", ПоказыватьПредупреждениеПриРегистрации И ПолучитьФункциональнуюОпцию("ИспользоватьСостоянияДокументов"));

СпособОтраженияПередачиКорреспонденту = ХранилищеОбщихНастроек.Загрузить("НастройкиРаботыСДокументами", "СпособОтраженияПередачиКорреспонденту");

Если СпособОтраженияПередачиКорреспонденту = Неопределено Тогда

СпособОтраженияПередачиКорреспонденту = Перечисления.СпособыОтраженияПередачиКорреспонденту.ЗадаватьВопрос;

ХранилищеОбщихНастроек.Сохранить("НастройкиРаботыСДокументами", "СпособОтраженияПередачиКорреспонденту", СпособОтраженияПередачиКорреспонденту);

КонецЕсли;

Настройки.Вставить("СпособОтраженияПередачиКорреспонденту", СпособОтраженияПередачиКорреспонденту);

УстановитьПривилегированныйРежим(Истина);

Настройки.Вставить("ИспользоватьФайлыУВходящихДокументов", Константы.ИспользоватьФайлыУВходящихДокументов.Получить());

Настройки.Вставить("ИспользоватьФайлыУИсходящихДокументов", Константы.ИспользоватьФайлыУИсходящихДокументов.Получить());

Возврат Настройки; // параметры доступны только для чтения

КонецФункции

// Возвращает ключ записи регистра сведений ЖурналПередачиДокументов

Функция ПолучитьКлючЖурналаПередачи(Период, Документ, ТипЭкземпляра, НомерЭкземпляра) Экспорт

Ключ = РегистрыСведений.ЖурналПередачиДокументов.СоздатьКлючЗаписи(

Новый Структура("Период, Документ, ТипЭкземпляра, НомерЭкземпляра",

Период,

Документ,

ТипЭкземпляра,

НомерЭкземпляра));

Возврат Ключ;

КонецФункции

// Возвращает количество держателей документа

Функция КоличествоКомуПереданДокумент(Документ) Экспорт

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| КОЛИЧЕСТВО(*) КАК Количество

|ИЗ

| РегистрСведений.ЖурналПередачиДокументов КАК ЖурналПередачиДокументов

|ГДЕ

| ЖурналПередачиДокументов.Документ = &Документ

| И ЖурналПередачиДокументов.Возвращен = ЛОЖЬ";

Запрос.УстановитьПараметр("Документ", Документ);

Результат = Запрос.Выполнить();

Если Результат.Пустой() Тогда

Возврат 0;

КонецЕсли;

Выборка = Результат.Выбрать();

Выборка.Следующий();

Возврат Выборка.Количество;

КонецФункции

// Формирует строку информации о держателях документа

Функция СтрокаКомуПереданДокумент(Документ) Экспорт

Если Не ЗначениеЗаполнено(Документ) Тогда

Возврат "";

КонецЕсли;

ОригиналПередан = "";

ОригиналПереданДата = '00010101';

ОригиналПереданМассив = Новый Массив;

ОригиналПереданКоличество = 0;

КопияПередана = "";

КопияПереданаДата = '00010101';

КопияПереданаМассив = Новый Массив;

КопияПереданаКоличество = 0;

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ РАЗРЕШЕННЫЕ

| ЖурналПередачиДокументов.ТипЭкземпляра КАК ТипЭкземпляра,

| ЖурналПередачиДокументов.Пользователь КАК Пользователь,

| ЖурналПередачиДокументов.Период КАК ДатаПередачи,

| ЖурналПередачиДокументов.НомерЭкземпляра КАК НомерЭкземпляра

|ИЗ

| РегистрСведений.ЖурналПередачиДокументов КАК ЖурналПередачиДокументов

|ГДЕ

| ЖурналПередачиДокументов.Документ = &Документ

| И ЖурналПередачиДокументов.Возвращен = ЛОЖЬ";

Запрос.УстановитьПараметр("Документ", Документ);

Выборка = Запрос.Выполнить().Выбрать();

Пока Выборка.Следующий() Цикл

Если Выборка.ТипЭкземпляра = Перечисления.ТипыЭкземпляров.Оригинал Тогда

Если ОригиналПереданМассив.Найти(Выборка.Пользователь) = Неопределено Тогда

ОригиналПередан = ОригиналПередан + Строка(Выборка.Пользователь) + ", ";

ОригиналПереданМассив.Добавить(Выборка.Пользователь);

КонецЕсли;

ОригиналПереданКоличество = ОригиналПереданКоличество + 1;

ОригиналПереданДата = Выборка.ДатаПередачи;

ИначеЕсли Выборка.ТипЭкземпляра = Перечисления.ТипыЭкземпляров.Копия Тогда

Если КопияПереданаМассив.Найти(Выборка.Пользователь) = Неопределено Тогда

КопияПередана = КопияПередана + Строка(Выборка.Пользователь) + ", ";

КопияПереданаМассив.Добавить(Выборка.Пользователь);

КонецЕсли;

КопияПереданаКоличество = КопияПереданаКоличество + 1;

КопияПереданаДата = Выборка.ДатаПередачи;

КонецЕсли;

КонецЦикла;

Если ОригиналПередан <> "" Тогда

ОригиналПередан = Лев(ОригиналПередан, СтрДлина(ОригиналПередан) - 2);

Если ОригиналПереданКоличество = 1 Тогда

ОригиналПередан = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(

НСтр("ru = 'Оригинал находится у пользователя %1 с %2'"),

ОригиналПередан,

Формат(ОригиналПереданДата, "ДФ=dd.MM.yyyy"));

ИначеЕсли ОригиналПереданКоличество > 1 Тогда

Если ОригиналПереданМассив.Количество() = 1 Тогда

ОригиналПередан = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(

НСтр("ru = 'Оригиналы находятся у пользователя %1'"),

ОригиналПередан);

Иначе

ОригиналПередан = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(

НСтр("ru = 'Оригиналы находятся у пользователей %1'"),

ОригиналПередан);

КонецЕсли;

КонецЕсли;

КонецЕсли;

Если КопияПередана <> "" Тогда

КопияПередана = Лев(КопияПередана, СтрДлина(КопияПередана) - 2);

Если КопияПереданаКоличество = 1 Тогда

КопияПередана = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(

НСтр("ru = 'Копия находится у пользователя %1 с %2'"),

КопияПередана,

Формат(КопияПереданаДата, "ДФ=dd.MM.yyyy"));

ИначеЕсли КопияПереданаКоличество > 1 Тогда

Если КопияПереданаМассив.Количество() = 1 Тогда

КопияПередана = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(

НСтр("ru = 'Копии находятся у пользователя %1'"),

КопияПередана);

Иначе

КопияПередана = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(

НСтр("ru = 'Копии находятся у пользователей %1'"),

КопияПередана);

КонецЕсли;

КонецЕсли;

КонецЕсли;

Если ОригиналПередан <> "" И КопияПередана <> "" Тогда

Возврат ОригиналПередан + Символы.ПС + КопияПередана;

Иначе

Возврат ОригиналПередан + КопияПередана;

КонецЕсли;

КонецФункции

// Получает актуальное состояние дела

Функция ПолучитьСостояниеДела(Дело) Экспорт

Если Не ЗначениеЗаполнено(Дело) Тогда

Возврат Перечисления.СостоянияДелХраненияДокументов.ПустаяСсылка();

КонецЕсли;

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| СостоянияДелХраненияДокументов.Состояние КАК Состояние

|ИЗ

| РегистрСведений.СостоянияДелХраненияДокументов.СрезПоследних(, ДелоХраненияДокументов = &Дело) КАК СостоянияДелХраненияДокументов";

Запрос.УстановитьПараметр("Дело", Дело);

Результат = Запрос.Выполнить();

Если Результат.Пустой() Тогда

Возврат Перечисления.СостоянияДелХраненияДокументов.ПустаяСсылка();

КонецЕсли;

Выборка = Результат.Выбрать();

Выборка.Следующий();

Возврат Выборка.Состояние;

КонецФункции

// Возвращает режим выбора вида документа

Функция ПолучитьРежимВыбораВидаДокумента(ТипДокумента) Экспорт

Если ТипДокумента = "ВходящийДокумент" Тогда

ВидДокумента = "ВидыВходящихДокументов";

ИначеЕсли ТипДокумента = "ИсходящийДокумент" Тогда

ВидДокумента = "ВидыИсходящихДокументов";

ИначеЕсли ТипДокумента = "ВнутреннийДокумент" Тогда

ВидДокумента = "ВидыВнутреннихДокументов";

КонецЕсли;

Запрос = Новый Запрос;

Запрос.Текст = СтрЗаменить(

"ВЫБРАТЬ РАЗРЕШЕННЫЕ

| ЛОЖЬ КАК ЗначениеЛожь

|ГДЕ

| ВЫБОР

| КОГДА ЛОЖЬ В

| (ВЫБРАТЬ ПЕРВЫЕ 1

| ЛОЖЬ

| ИЗ

| &ВидДокумента КАК ТаблицаВидаДокументов

| ГДЕ

| ТаблицаВидаДокументов.ЭтоГруппа)

| ТОГДА ИСТИНА

| ИНАЧЕ ЛОЖЬ В

| (ВЫБРАТЬ

| ЛОЖЬ КАК ЗначениеЛожь

| ИЗ

| (ВЫБРАТЬ ПЕРВЫЕ 16

| ИСТИНА КАК ЗначениеИстина

| ИЗ

| &ВидДокумента КАК ТаблицаВидаДокументов

| ) КАК ВыбранныеОбъекты

| ИМЕЮЩИЕ

| КОЛИЧЕСТВО(ВыбранныеОбъекты.ЗначениеИстина) > 15)

| КОНЕЦ", "&ВидДокумента", "Справочник." + ВидДокумента);

Результат = Запрос.Выполнить();

БыстрыйВыборВидаДокумента = Результат.Пустой();

Возврат БыстрыйВыборВидаДокумента;

КонецФункции

// Проверяет проверку возможности отнесения документа в дело

Функция ДелоМожетСодержатьДокумент(ТипПроверки, ЗначениеПроверки, Дело) Экспорт

УстановитьПривилегированныйРежим(Истина);

Если ТипПроверки = "ВидыДокументов" Тогда

Если ЗначениеЗаполнено(ЗначениеПроверки) И Дело.НоменклатураДел.ВидыДокументов.Количество() > 0 Тогда

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| ИСТИНА

|ГДЕ

| &ВидДокумента В ИЕРАРХИИ

| (ВЫБРАТЬ

| ВидыДокументов.ВидДокумента

| ИЗ

| Справочник.НоменклатураДел.ВидыДокументов КАК ВидыДокументов

| ГДЕ

| ВидыДокументов.Ссылка = &НоменклатураДел)";

Запрос.УстановитьПараметр("ВидДокумента", ЗначениеПроверки);

Запрос.УстановитьПараметр("НоменклатураДел", Дело.НоменклатураДел);

Результат = Запрос.Выполнить();

Если Результат.Пустой() Тогда

Возврат Ложь;

КонецЕсли;

КонецЕсли;

ИначеЕсли ТипПроверки = "Корреспонденты" Тогда

Если ЗначениеЗаполнено(ЗначениеПроверки) И Дело.НоменклатураДел.Корреспонденты.Количество() > 0 Тогда

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| ИСТИНА

|ГДЕ

| &Корреспондент В ИЕРАРХИИ

| (ВЫБРАТЬ

| Корреспонденты.Корреспондент

| ИЗ

| Справочник.НоменклатураДел.Корреспонденты КАК Корреспонденты

| ГДЕ

| Корреспонденты.Ссылка = &НоменклатураДел)";

Запрос.УстановитьПараметр("Корреспондент", ЗначениеПроверки);

Запрос.УстановитьПараметр("НоменклатураДел", Дело.НоменклатураДел);

Результат = Запрос.Выполнить();

Если Результат.Пустой() Тогда

Возврат Ложь;

КонецЕсли;

КонецЕсли;

ИначеЕсли ТипПроверки = "ВопросыДеятельности" Тогда

Если ЗначениеЗаполнено(ЗначениеПроверки) И Дело.НоменклатураДел.ВопросыДеятельности.Количество() > 0 Тогда

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| ИСТИНА

|ГДЕ

| &ВопросДеятельности В ИЕРАРХИИ

| (ВЫБРАТЬ

| ВопросыДеятельности.ВопросДеятельности

| ИЗ

| Справочник.НоменклатураДел.ВопросыДеятельности КАК ВопросыДеятельности

| ГДЕ

| ВопросыДеятельности.Ссылка = &НоменклатураДел)";

Запрос.УстановитьПараметр("ВопросДеятельности", ЗначениеПроверки);

Запрос.УстановитьПараметр("НоменклатураДел", Дело.НоменклатураДел);

Результат = Запрос.Выполнить();

Если Результат.Пустой() Тогда

Возврат Ложь;

КонецЕсли;

КонецЕсли;

КонецЕсли;

Возврат Истина;

КонецФункции

// Возвражает Истина, если корреспондент является юридическим лицом

Функция КорреспондентЮрЛицо(Корреспондент) Экспорт

Возврат ЗначениеЗаполнено(Корреспондент)

И ТипЗнч(Корреспондент) = Тип("СправочникСсылка.Корреспонденты")

И (Корреспондент.ЮрФизЛицо = Перечисления.ЮрФизЛицо.ЮрЛицо

Или Корреспондент.ЮрФизЛицо = Перечисления.ЮрФизЛицо.ИндивидуальныйПредприниматель

Или Корреспондент.ЮрФизЛицо = Перечисления.ЮрФизЛицо.ЮрЛицоНеРезидент);

КонецФункции

// Возвражает структуру данных корреспондента

Функция ПолучитьДанныеКорреспондента(Корреспондент) Экспорт

ДанныеКорреспондента = Новый Структура;

ДанныеКорреспондента.Вставить("КорреспондентЮрЛицо", КорреспондентЮрЛицо(Корреспондент));

ДанныеКорреспондента.Вставить("КонтактноеЛицо", КонтактноеЛицоКорреспондента(Корреспондент));

Возврат ДанныеКорреспондента;

КонецФункции

Процедура УдалитьВременныеСохраненныеПоиски(ТекущийПользователь) Экспорт

СписокСохраненныхПоисков = ХранилищеНастроекДанныхФорм.ПолучитьСписок("Обработка.ПоискПоРеквизитам.Форма.ПоискДокументовИФайлов");

Для Каждого СохраненныйПоиск Из СписокСохраненныхПоисков Цикл

КлючПоиска = СохраненныйПоиск.Значение;

Если Найти(КлючПоиска, "_временный_") > 0 Тогда

УстановитьПривилегированныйРежим(Истина);

ПользовательИБ = ПользователиИнформационнойБазы.НайтиПоУникальномуИдентификатору(ТекущийПользователь.ИдентификаторПользователяИБ);

Если ПользовательИБ <> Неопределено Тогда

ХранилищеНастроекДанныхФорм.Удалить("Обработка.ПоискПоРеквизитам.Форма.ПоискДокументовИФайлов", КлючПоиска, ПользовательИБ.Имя);

КонецЕсли;

КонецЕсли;

КонецЦикла;

КонецПроцедуры

Функция ПолучитьТекущуюДату() Экспорт

Возврат ТекущаяДатаСеанса();

КонецФункции

// Получает признак Отправлен

Функция ПолучитьПризнакОтправлен(ИсходящийДокумент, Получатель, Адресат) Экспорт

Отправлен = Ложь;

ПараметрыОтбора = Новый Структура("Получатель", Получатель);

НайденныеСтроки = ИсходящийДокумент.Получатели.НайтиСтроки(ПараметрыОтбора);

Если НайденныеСтроки.Количество() = 1 Тогда

Отправлен = НайденныеСтроки[0].Отправлен;

Иначе

ПараметрыОтбора = Новый Структура("Получатель, Адресат", Получатель, Адресат);

НайденныеСтроки = ИсходящийДокумент.Получатели.НайтиСтроки(ПараметрыОтбора);

Если НайденныеСтроки.Количество() = 1 Тогда

Отправлен = НайденныеСтроки[0].Отправлен;

КонецЕсли;

КонецЕсли;

Возврат Отправлен;

КонецФункции

// Заполнить подчиненные документы

Процедура ЗаполнитьПодчиненныеДокументы(СтрокаДерева, ПараметрыДокумент) Экспорт

Ссылка = СтрокаДерева.Ссылка;

Если ТипЗнч(Ссылка) = Тип("СправочникСсылка.ВходящиеДокументы") Тогда

ТекстЗапроса =

"ВЫБРАТЬ РАЗРЕШЕННЫЕ

| ИсходящиеДокументы.Ссылка КАК Ссылка,

| ИсходящиеДокументы.Заголовок КАК Заголовок,

| ИсходящиеДокументы.РегистрационныйНомер КАК РегистрационныйНомер,

| ИсходящиеДокументы.ДатаРегистрации КАК ДатаРегистрации,

| 1 КАК ИндексКартинки,

| ИсходящиеДокументы.ДатаСоздания КАК ДатаСоздания

|ИЗ

| Справочник.ИсходящиеДокументы КАК ИсходящиеДокументы

| ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.СвязиДокументов КАК СвязьПредметПереписки

| ПО ИсходящиеДокументы.Ссылка = СвязьПредметПереписки.Документ

| И (СвязьПредметПереписки.ТипСвязи = ЗНАЧЕНИЕ(Справочник.ТипыСвязей.ПредметПереписки))

| ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.СвязиДокументов КАК СвязьВОтветНа

| ПО ИсходящиеДокументы.Ссылка = СвязьВОтветНа.Документ

| И (СвязьВОтветНа.ТипСвязи = ЗНАЧЕНИЕ(Справочник.ТипыСвязей.ОтправленВОтветНа))

|ГДЕ

| СвязьВОтветНа.СвязанныйДокумент = &Ссылка

| И СвязьПредметПереписки.СвязанныйДокумент = &ПредметПереписки

| И (НЕ ИсходящиеДокументы.ПометкаУдаления)

|

|УПОРЯДОЧИТЬ ПО

| ДатаСоздания";

ИначеЕсли ТипЗнч(Ссылка) = Тип("СправочникСсылка.ИсходящиеДокументы") Тогда

ТекстЗапроса =

"ВЫБРАТЬ РАЗРЕШЕННЫЕ

| ВходящиеДокументы.Ссылка КАК Ссылка,

| ВходящиеДокументы.Заголовок КАК Заголовок,

| ВходящиеДокументы.РегистрационныйНомер КАК РегистрационныйНомер,

| ВходящиеДокументы.ДатаРегистрации КАК ДатаРегистрации,

| 0 КАК ИндексКартинки,

| ВходящиеДокументы.ДатаСоздания КАК ДатаСоздания

|ИЗ

| Справочник.ВходящиеДокументы КАК ВходящиеДокументы

| ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.СвязиДокументов КАК СвязьПредметПереписки

| ПО ВходящиеДокументы.Ссылка = СвязьПредметПереписки.Документ

| И (СвязьПредметПереписки.ТипСвязи = ЗНАЧЕНИЕ(Справочник.ТипыСвязей.ПредметПереписки))

| ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.СвязиДокументов КАК СвязьВОтветНа

| ПО ВходящиеДокументы.Ссылка = СвязьВОтветНа.Документ

| И (СвязьВОтветНа.ТипСвязи = ЗНАЧЕНИЕ(Справочник.ТипыСвязей.ПолученВОтветНа))

|ГДЕ

| СвязьВОтветНа.СвязанныйДокумент = &Ссылка

| И СвязьПредметПереписки.СвязанныйДокумент = &ПредметПереписки

| И (НЕ ВходящиеДокументы.ПометкаУдаления)

|

|УПОРЯДОЧИТЬ ПО

| ДатаСоздания";

КонецЕсли;

Запрос = Новый Запрос;

Запрос.Текст = ТекстЗапроса;

Запрос.УстановитьПараметр("Ссылка", Ссылка);

Запрос.УстановитьПараметр("ПредметПереписки", ПараметрыДокумент);

Выборка = Запрос.Выполнить().Выбрать();

Пока Выборка.Следующий() Цикл

НоваяСтрока = СтрокаДерева.Строки.Добавить();

ЗаполнитьЗначенияСвойств(НоваяСтрока, Выборка);

Если ТипЗнч(Ссылка) = Тип("СправочникСсылка.ВходящиеДокументы") Тогда

Отправлен = ПолучитьПризнакОтправлен(Выборка.Ссылка, Ссылка.Отправитель, Ссылка.Подписал);

НоваяСтрока.ИндексКартинки = ?(Отправлен, 1, 3);

КонецЕсли;

ЗаполнитьПодчиненныеДокументы(НоваяСтрока, ПараметрыДокумент);

КонецЦикла;

КонецПроцедуры

// Заполнить дерево переписки

Функция ЗаполнитьДерево(Дерево, ПараметрыДокумент) Экспорт

Дерево.Строки.Очистить();

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ РАЗРЕШЕННЫЕ

| ВходящийДокумент.Ссылка КАК Ссылка,

| ВходящийДокумент.ДатаРегистрации,

| ВходящийДокумент.РегистрационныйНомер,

| ВходящийДокумент.Заголовок,

| ВходящийДокумент.ДатаСоздания КАК ДатаСоздания

|ИЗ

| Справочник.ВходящиеДокументы КАК ВходящийДокумент

| ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.СвязиДокументов КАК СвязьПредметПереписки

| ПО ВходящийДокумент.Ссылка = СвязьПредметПереписки.Документ

| И (СвязьПредметПереписки.ТипСвязи = ЗНАЧЕНИЕ(Справочник.ТипыСвязей.ПредметПереписки))

| ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.СвязиДокументов КАК СвязьВОтветНа

| ПО ВходящийДокумент.Ссылка = СвязьВОтветНа.Документ

| И (СвязьВОтветНа.ТипСвязи = ЗНАЧЕНИЕ(Справочник.ТипыСвязей.ПолученВОтветНа))

| ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.СвязиДокументов КАК СвязьВОтветНаПредметПереписки

| ПО (СвязьВОтветНа.СвязанныйДокумент = СвязьВОтветНаПредметПереписки.Документ)

| И (СвязьВОтветНаПредметПереписки.ТипСвязи = ЗНАЧЕНИЕ(Справочник.ТипыСвязей.ПредметПереписки))

|ГДЕ

| СвязьПредметПереписки.СвязанныйДокумент = &ПредметПереписки

| И (СвязьВОтветНа.СвязанныйДокумент ЕСТЬ NULL

| ИЛИ ЕСТЬNULL(СвязьВОтветНаПредметПереписки.СвязанныйДокумент, """") <> &ПредметПереписки)

| И (НЕ ВходящийДокумент.ПометкаУдаления)

|

|ОБЪЕДИНИТЬ ВСЕ

|

|ВЫБРАТЬ

| ИсходящийДокумент.Ссылка,

| ИсходящийДокумент.ДатаРегистрации,

| ИсходящийДокумент.РегистрационныйНомер,

| ИсходящийДокумент.Заголовок,

| ИсходящийДокумент.ДатаСоздания

|ИЗ

| Справочник.ИсходящиеДокументы КАК ИсходящийДокумент

| ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.СвязиДокументов КАК СвязьПредметПереписки

| ПО ИсходящийДокумент.Ссылка = СвязьПредметПереписки.Документ

| И (СвязьПредметПереписки.ТипСвязи = ЗНАЧЕНИЕ(Справочник.ТипыСвязей.ПредметПереписки))

| ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.СвязиДокументов КАК СвязьВОтветНа

| ПО ИсходящийДокумент.Ссылка = СвязьВОтветНа.Документ

| И (СвязьВОтветНа.ТипСвязи = ЗНАЧЕНИЕ(Справочник.ТипыСвязей.ОтправленВОтветНа))

| ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.СвязиДокументов КАК СвязьВОтветНаПредметПереписки

| ПО (СвязьВОтветНа.СвязанныйДокумент = СвязьВОтветНаПредметПереписки.Документ)

| И (СвязьВОтветНаПредметПереписки.ТипСвязи = ЗНАЧЕНИЕ(Справочник.ТипыСвязей.ПредметПереписки))

|ГДЕ

| СвязьПредметПереписки.СвязанныйДокумент = &ПредметПереписки

| И (СвязьВОтветНа.СвязанныйДокумент ЕСТЬ NULL

| ИЛИ ЕСТЬNULL(СвязьВОтветНаПредметПереписки.СвязанныйДокумент, """") <> &ПредметПереписки)

| И (НЕ ИсходящийДокумент.ПометкаУдаления)

|

|УПОРЯДОЧИТЬ ПО

| ДатаСоздания";

Запрос.УстановитьПараметр("ПредметПереписки", ПараметрыДокумент);

ТаблДокументов = Запрос.Выполнить().Выгрузить();

ТаблДокументов.Сортировать("ДатаРегистрации");

Для Каждого Строка Из ТаблДокументов Цикл

НоваяСтрока = Дерево.Строки.Добавить();

ЗаполнитьЗначенияСвойств(НоваяСтрока, Строка);

Если ТипЗнч(НоваяСтрока.Ссылка) = Тип("СправочникСсылка.ВходящиеДокументы") Тогда

НоваяСтрока.ИндексКартинки = 0;

ИначеЕсли ТипЗнч(НоваяСтрока.Ссылка) = Тип("СправочникСсылка.ИсходящиеДокументы") Тогда

Если НоваяСтрока.Ссылка.Получатели.Найти(Истина, "Отправлен") <> Неопределено Тогда

НоваяСтрока.ИндексКартинки = 1;

Иначе

НоваяСтрока.ИндексКартинки = 3;

КонецЕсли;

КонецЕсли;

ЗаполнитьПодчиненныеДокументы(НоваяСтрока, ПараметрыДокумент);

КонецЦикла;

КонецФункции

// Выводит номенклатуру дел в дерево

Процедура ЗаполнитьДеревоНоменклатурыДел(Дерево, Год, Организация) Экспорт

// получение дерева разделов номенклатуры дел

Запрос = Новый Запрос;

ТекстЗапроса =

"ВЫБРАТЬ РАЗРЕШЕННЫЕ

| РазделыНоменклатурыДел.Индекс КАК Индекс,

| РазделыНоменклатурыДел.Наименование,

| РазделыНоменклатурыДел.ПометкаУдаления,

| РазделыНоменклатурыДел.Ссылка КАК Ссылка,

| РазделыНоменклатурыДел.Родитель

|ИЗ

| Справочник.РазделыНоменклатурыДел КАК РазделыНоменклатурыДел ";

Условие = "";

Если ПолучитьФункциональнуюОпцию("ИспользоватьУчетПоОрганизациям") И ЗначениеЗаполнено(Организация) Тогда

Условие = Условие + " (Организация = &Организация) И ";

Запрос.УстановитьПараметр("Организация", Организация);

КонецЕсли;

Если ЗначениеЗаполнено(Год) Тогда

Условие = Условие + " (Год = &Год) И ";

Запрос.УстановитьПараметр("Год", Год);

КонецЕсли;

Если Условие <> "" Тогда

ТекстЗапроса = ТекстЗапроса + " ГДЕ " + Лев(Условие, СтрДлина(Условие)-2);

КонецЕсли;

ТекстЗапроса = ТекстЗапроса +

" ИТОГИ ПО

| Ссылка ТОЛЬКО ИЕРАРХИЯ

|АВТОУПОРЯДОЧИВАНИЕ";

Запрос.Текст = ТекстЗапроса;

Выборка = Запрос.Выполнить().Выбрать();

Пока Выборка.Следующий() Цикл

Если Не ЗначениеЗаполнено(Выборка.Ссылка) Тогда

Продолжить;

КонецЕсли;

Родитель = Выборка.Родитель;

Если Родитель.Пустая() Тогда

СтрокаРодитель = Дерево;

Иначе

СтрокаРодитель = Дерево.Строки.Найти(Родитель, "Ссылка", Истина);

КонецЕсли;

НоваяСтрока = СтрокаРодитель.Строки.Добавить();

НоваяСтрока.Ссылка = Выборка.Ссылка;

НоваяСтрока.Наименование = Выборка.Индекс + " " + Выборка.Наименование;

НоваяСтрока.ИндексКартинки = ?(Выборка.ПометкаУдаления, 1, 0);

НоваяСтрока.ЭтоГруппа = Истина;

КонецЦикла;

// получение списка элементов номенклатуры дел

Запрос = Новый Запрос;

ТекстЗапроса =

"ВЫБРАТЬ РАЗРЕШЕННЫЕ

| НоменклатураДел.Индекс,

| НоменклатураДел.Наименование,

| НоменклатураДел.ПометкаУдаления,

| НоменклатураДел.Ссылка КАК Ссылка,

| НоменклатураДел.Раздел

|ИЗ

| Справочник.НоменклатураДел КАК НоменклатураДел ";

Условие = "";

Если ПолучитьФункциональнуюОпцию("ИспользоватьУчетПоОрганизациям") И ЗначениеЗаполнено(Организация) Тогда

Условие = Условие + " (Организация = &Организация) И ";

Запрос.УстановитьПараметр("Организация", Организация);

КонецЕсли;

Если ЗначениеЗаполнено(Год) Тогда

Условие = Условие + " (Год = &Год) И ";

Запрос.УстановитьПараметр("Год", Год);

КонецЕсли;

Если Условие <> "" Тогда

ТекстЗапроса = ТекстЗапроса + " ГДЕ " + Лев(Условие, СтрДлина(Условие)-2);

КонецЕсли;

ТекстЗапроса = ТекстЗапроса + " УПОРЯДОЧИТЬ ПО Индекс";

Запрос.Текст = ТекстЗапроса;

Выборка = Запрос.Выполнить().Выбрать();

Пока Выборка.Следующий() Цикл

Если Выборка.Раздел.Пустая() Тогда

СтрокаРодитель = Дерево;

Иначе

СтрокаРодитель = Дерево.Строки.Найти(Выборка.Раздел, "Ссылка", Истина);

КонецЕсли;

Если СтрокаРодитель <> Неопределено Тогда

НоваяСтрока = СтрокаРодитель.Строки.Добавить();

НоваяСтрока.Ссылка = Выборка.Ссылка;

НоваяСтрока.Наименование = Выборка.Индекс + " " + Выборка.Наименование;

НоваяСтрока.ИндексКартинки = ?(Выборка.ПометкаУдаления, 3, 2);

НоваяСтрока.ЭтоГруппа = Ложь;

КонецЕсли;

КонецЦикла;

Если Дерево.Строки.Количество() > 0 Тогда

НоваяСтрока = Дерево.Строки.Добавить();

НоваяСтрока.Ссылка = Справочники.НоменклатураДел.ПустаяСсылка();

НоваяСтрока.Наименование = НСтр("ru = '<Номенклатура дел не указана>'");

НоваяСтрока.ИндексКартинки = 2;

НоваяСтрока.ЭтоГруппа = Ложь;

КонецЕсли;

КонецПроцедуры

// Выводит дела (тома) в дерево

Процедура ЗаполнитьДеревоДелТомов(Дерево, Год, Организация) Экспорт

Запрос = Новый Запрос;

ТекстЗапроса =

"ВЫБРАТЬ РАЗРЕШЕННЫЕ

| ДелаХраненияДокументов.Ссылка,

| ДелаХраненияДокументов.Наименование,

| ДелаХраненияДокументов.ПометкаУдаления,

| ДелаХраненияДокументов.НоменклатураДел.Раздел КАК Раздел

|ИЗ

| Справочник.ДелаХраненияДокументов КАК ДелаХраненияДокументов";

Условие = "";

Если ПолучитьФункциональнуюОпцию("ИспользоватьУчетПоОрганизациям") И ЗначениеЗаполнено(Организация) Тогда

Условие = Условие + " (ДелаХраненияДокументов.Организация = &Организация) И ";

Запрос.УстановитьПараметр("Организация", Организация);

КонецЕсли;

Если ЗначениеЗаполнено(Год) Тогда

Условие = Условие + " (ДелаХраненияДокументов.НоменклатураДел.Год = &Год) И ";

Запрос.УстановитьПараметр("Год", Год);

КонецЕсли;

Если Условие <> "" Тогда

ТекстЗапроса = ТекстЗапроса + " ГДЕ " + Лев(Условие, СтрДлина(Условие)-2);

КонецЕсли;

ТекстЗапроса = ТекстЗапроса +

" УПОРЯДОЧИТЬ ПО

| ДелаХраненияДокументов.НоменклатураДел.Индекс,

| ДелаХраненияДокументов.НомерТома";

Запрос.Текст = ТекстЗапроса;

ТаблицаДела = Запрос.Выполнить().Выгрузить();

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ РАЗРЕШЕННЫЕ

| РазделыНоменклатурыДел.Индекс,

| РазделыНоменклатурыДел.Наименование,

| РазделыНоменклатурыДел.ПометкаУдаления,

| РазделыНоменклатурыДел.Ссылка КАК Ссылка,

| РазделыНоменклатурыДел.Родитель

|ИЗ

| Справочник.РазделыНоменклатурыДел КАК РазделыНоменклатурыДел

|ГДЕ

| РазделыНоменклатурыДел.Ссылка В(&Разделы)

|ИТОГИ ПО

| Ссылка ТОЛЬКО ИЕРАРХИЯ

|АВТОУПОРЯДОЧИВАНИЕ";

Запрос.УстановитьПараметр("Разделы", ТаблицаДела.ВыгрузитьКолонку("Раздел"));

Выборка = Запрос.Выполнить().Выбрать();

Пока Выборка.Следующий() Цикл

Если Не ЗначениеЗаполнено(Выборка.Ссылка) Тогда

Продолжить;

КонецЕсли;

Родитель = Выборка.Родитель;

Если Родитель.Пустая() Тогда

СтрокаРодитель = Дерево;

Иначе

СтрокаРодитель = Дерево.Строки.Найти(Родитель, "Ссылка", Истина);

КонецЕсли;

НоваяСтрока = СтрокаРодитель.Строки.Добавить();

НоваяСтрока.Ссылка = Выборка.Ссылка;

НоваяСтрока.Наименование = Выборка.Индекс + " " + Выборка.Наименование;

НоваяСтрока.ИндексКартинки = ?(Выборка.ПометкаУдаления, 1, 0);

НоваяСтрока.ЭтоГруппа = Истина;

КонецЦикла;

Для Каждого Строка Из ТаблицаДела Цикл

Если Строка.Раздел.Пустая() Тогда

СтрокаРодитель = Дерево;

Иначе

СтрокаРодитель = Дерево.Строки.Найти(Строка.Раздел, "Ссылка", Истина);

КонецЕсли;

Если СтрокаРодитель <> Неопределено Тогда

НоваяСтрока = СтрокаРодитель.Строки.Добавить();

НоваяСтрока.Ссылка = Строка.Ссылка;

НоваяСтрока.Наименование = Строка.Наименование;

НоваяСтрока.ИндексКартинки = ?(Строка.ПометкаУдаления, 3, 2);

НоваяСтрока.ЭтоГруппа = Ложь;

КонецЕсли;

КонецЦикла;

Если Дерево.Строки.Количество() > 0 Тогда

НоваяСтрока = Дерево.Строки.Добавить();

НоваяСтрока.Ссылка = Справочники.ДелаХраненияДокументов.ПустаяСсылка();

НоваяСтрока.Наименование = НСтр("ru = '<Дело (том) не указано>'");

НоваяСтрока.ИндексКартинки = 2;

НоваяСтрока.ЭтоГруппа = Ложь;

КонецЕсли;

КонецПроцедуры

// Возвращает признак необходимости указания связи для регистрации документа

Функция ДляРегистрацииНеобходимоУказатьСвязанныйДокумент(Форма) Экспорт

Если Не ПолучитьФункциональнуюОпцию("ИспользоватьСвязиДокументов") Тогда

Возврат Ложь;

КонецЕсли;

Если Не ЗначениеЗаполнено(Форма.Нумератор) Тогда

Возврат Ложь;

КонецЕсли;

ПараметрыНумератора = ОбщегоНазначения.ПолучитьЗначенияРеквизитов(Форма.Нумератор,

"НезависимаяНумерацияПоСвязанномуДокументу, ТипСвязи");

Если Не ПараметрыНумератора.НезависимаяНумерацияПоСвязанномуДокументу Тогда

Возврат Ложь;

КонецЕсли;

Если ЗначениеЗаполнено(Форма.Объект.Ссылка) Тогда

ДокументДляНумерации = СвязиДокументов.ПолучитьСвязанныйДокумент(Форма.Объект.Ссылка, ПараметрыНумератора.ТипСвязи);

Иначе

ДокументДляНумерации = Неопределено;

КонецЕсли;

ДокументНеНайден = Не ЗначениеЗаполнено(ДокументДляНумерации);

Если ДокументНеНайден И Форма.ТипСвязиНумератора <> ПараметрыНумератора.ТипСвязи Тогда

Форма.ТипСвязиНумератора = ПараметрыНумератора.ТипСвязи;

СтруктураОбъекта = Новый Структура;

СтруктураОбъекта.Вставить("ВидДокумента", Форма.Объект.ВидДокумента);

НастройкиСвязи = СвязиДокументов.ПолучитьНастройкиСвязи(СтруктураОбъекта);

СтрокиНастроекСвязи = НастройкиСвязи.НайтиСтроки(Новый Структура("ТипСвязи", Форма.ТипСвязиНумератора));

Форма.ТипыВидыСвязанныхДокументовДляНумерации.Очистить();

Для Каждого СтрокаНастроекСвязи из СтрокиНастроекСвязи Цикл

Строка = Форма.ТипыВидыСвязанныхДокументовДляНумерации.Добавить();

Строка.Тип = СтрокаНастроекСвязи.ТипСсылкаНа;

Строка.Вид = СтрокаНастроекСвязи.СсылкаНа;

КонецЦикла;

КонецЕсли;

Возврат ДокументНеНайден;

КонецФункции

// Проверяет возможность изменить вид документа, если у него имеются связанные документы

Процедура ПроверкаСвязейПриИзмененииВидаДокумента(Объект, Отказ) Экспорт

Если Делопроизводство.ИспользоватьВидыДокументов(Объект.ВидДокумента) И Не Объект.Ссылка.Пустая() Тогда

СтарыйВидДокумента = ОбщегоНазначения.ПолучитьЗначениеРеквизита(Объект.Ссылка, "ВидДокумента");

// если изменен вид документа

Если Объект.ВидДокумента <> СтарыйВидДокумента Тогда

УстановитьПривилегированныйРежим(Истина);

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| СвязиДокументов.СвязанныйДокумент,

| СвязиДокументов.ТипСвязи

|ИЗ

| РегистрСведений.СвязиДокументов КАК СвязиДокументов

|ГДЕ

| СвязиДокументов.Документ = &Документ";

Запрос.УстановитьПараметр("Документ", Объект.Ссылка);

Выборка = Запрос.Выполнить().Выбрать();

Пока Выборка.Следующий() Цикл

ДокументСтруктура = Новый Структура;

ДокументСтруктура.Вставить("Ссылка", Объект.Ссылка);

ДокументСтруктура.Вставить("ВидДокумента", Объект.ВидДокумента);

НастройкаСвязи = СвязиДокументов.ПолучитьНастройкуСвязи(ДокументСтруктура, Выборка.СвязанныйДокумент, Выборка.ТипСвязи);

Если НастройкаСвязи = Неопределено Тогда

ТекстСообщения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(

НСтр("ru = 'Для документа указана связь ""%1"", которую нельзя использовать для документов этого вида'"),

Строка(Выборка.ТипСвязи));

ОбщегоНазначенияКлиентСервер.СообщитьПользователю(ТекстСообщения,,"Объект.ВидДокумента",,Отказ);

КонецЕсли;

КонецЦикла;

КонецЕсли;

КонецЕсли;

КонецПроцедуры

// Открывает форму выбора дела

Процедура ВыбратьДело(ЭлементДело, Параметры) Экспорт

ПараметрыФормы = Параметры;

ПараметрыФормы.Вставить("РежимВыбора", "ИзКарточкиДокумента");

ОткрытьФорму("Справочник.ДелаХраненияДокументов.ФормаВыбора", ПараметрыФормы, ЭлементДело);

КонецПроцедуры

// Открывает форму выбора получателя

Процедура ВыбратьПолучателя(ЭлементПолучатель, РеквизитПолучатель) Экспорт

ПараметрыФормы = Новый Структура("Получатель", РеквизитПолучатель);

ОткрытьФорму("ОбщаяФорма.ВыборПолучателя", ПараметрыФормы, ЭлементПолучатель);

КонецПроцедуры

// Выполняет проверки перед закрытием документа

Процедура ПередЗакрытиемДокумента(Объект, Отказ) Экспорт

Если Не ЗначениеЗаполнено(Объект.Ссылка) Тогда

Возврат;

КонецЕсли;

ТекущийПользователь = ФайловыеФункцииКлиентПовтИсп.ПолучитьПерсональныеНастройкиРаботыСФайлами().ТекущийПользователь;

ПараметрыФормы = Новый Структура;

ПараметрыФормы.Вставить("СообщениеВопрос", НСтр("ru = 'Закрыть карточку?'"));

ПараметрыФормы.Вставить("СообщениеЗаголовок", НСтр("ru = 'Некоторые файлы заняты вами для редактирования:'"));

ПараметрыФормы.Вставить("Заголовок", Строка(Объект.Ссылка));

ПараметрыФормы.Вставить("ВладелецФайла", Объект.Ссылка);

ПараметрыФормы.Вставить("Редактирует", ТекущийПользователь);

РаботаСФайламиКлиент.ОткрытьДиалогСписокЗанятыхФайлов(Отказ, ПараметрыФормы);

КонецПроцедуры

// Открывает форму текущего состояния документа

Процедура ОткрытьТекущееСостояниеДокумента(Документ, Элемент) Экспорт

Если Не ЗначениеЗаполнено(Документ) Тогда

Предупреждение(НСтр("ru = 'Для доступа к состоянию элемент необходимо записать!'"));

Возврат;

КонецЕсли;

Ключ = Делопроизводство.ПолучитьКлючСостоянияДокумента(Документ);

Если Ключ = Неопределено Тогда

Возврат;

КонецЕсли;

ПараметрыФормы = Новый Структура("Ключ", Ключ);

ОткрытьФормуМодально("РегистрСведений.СостоянияДокументов.ФормаЗаписи", ПараметрыФормы, Элемент);

КонецПроцедуры

// Открывает форму предупреждения при регистрации документа

Функция ПредупредитьПриРегистрации() Экспорт

ПоказыватьПредупреждениеПриРегистрации = ДелопроизводствоКлиентПовтИсп.ПолучитьПерсональныеНастройкиРаботыСДокументами().ПоказыватьПредупреждениеПриРегистрации;

Если ПоказыватьПредупреждениеПриРегистрации = Истина Тогда

Результат = ОткрытьФормуМодально("ОбщаяФорма.ПредупреждениеПриРегистрации");

Если Результат <> КодВозвратаДиалога.Да Тогда

Возврат Ложь;

КонецЕсли;

КонецЕсли;

Возврат Истина;

КонецФункции

// Открывает форму предупреждения при перерегистрации документа

Функция ПредупредитьПриПеререгистрации() Экспорт

ТекстВопроса = НСтр("ru = 'Документ будет перерегистрирован. Продолжить?'");

Ответ = Вопрос(ТекстВопроса, РежимДиалогаВопрос.ДаНет);

Если Ответ <> КодВозвратаДиалога.Да Тогда

Возврат Ложь;

КонецЕсли;

Возврат Истина;

КонецФункции

// Открывает форму записи журнала передачи документа

Процедура ОткрытьКарточкуПередачиДокумента(Документ, ВладелецФормы) Экспорт

Количество = Делопроизводство.КоличествоКомуПереданДокумент(Документ);

Если Количество = 0 Тогда

Возврат;

ИначеЕсли Количество = 1 Тогда

ПараметрыФормы = Новый Структура("ПоказатьДержателяДокумента", Документ);

ОткрытьФорму("РегистрСведений.ЖурналПередачиДокументов.ФормаЗаписи", ПараметрыФормы, ВладелецФормы);

Иначе

ПараметрыФормы = Новый Структура("ПоказатьДержателейДокумента", Документ);

ОткрытьФорму("РегистрСведений.ЖурналПередачиДокументов.Форма.ФормаСпискаДокумента", ПараметрыФормы, ВладелецФормы);

КонецЕсли;

КонецПроцедуры

// Показывает форму вопроса с возможностью сохранения ответа в персональные настройки

// Параметры:

// ЭлементВладелец - элемент формы, который будет владельцем открываемой формы с вопросом

// Заголовок вопроса - заголовок для формы вопроса

// ТекстВопроса - формулировка вопроса

// КлючПерсональнойНастройкиПоказаВопроса - ключ персональной настройки, хранящей флаг необходимости показа формы

// ИмяПерсональнойНастройкипоказаВопроса - имя персональной настройки, хранящей флаг необходимости показа формы

// СписокДоступныхВариантов - список доступных вариантов ответов на вопрос

// ВариантОтветаПоУмолчанию - вариант ответа, который будет помечен как вариант ответа по умолчанию

// Возвращает:

// Значение типа КодВозвратаДиалога

Функция ПоказатьРасширеннуюФормуВопроса(

ЭлементВладелец,

ЗаголовокВопроса,

ТекстВопроса,

КлючПерсональнойНастройкиПоказаВопроса,

ИмяПерсональнойНастройкиПоказаВопроса,

СписокДоступныхВариантов,

ВариантОтветаПоУмолчанию = "Да") Экспорт

ПараметрыФормы = Новый Структура;

Параметрыформы.Вставить("Заголовок", ЗаголовокВопроса);

Параметрыформы.Вставить("ТекстВопроса", ТекстВопроса);

Параметрыформы.Вставить("СписокДоступныхВариантов", СписокДоступныхВариантов);

Параметрыформы.Вставить("КлючПерсональнойНастройки", КлючПерсональнойНастройкиПоказаВопроса);

Параметрыформы.Вставить("ИмяПерсональнойНастройки", ИмяПерсональнойНастройкиПоказаВопроса);

ПараметрыФормы.Вставить("ВариантОтветаПоУмолчанию", ВариантОтветаПоУмолчанию);

Ответ = ОткрытьФормуМодально("ОбщаяФорма.РасширенныйВопрос", ПараметрыФормы, ЭлементВладелец);

Если НЕ ЗначениеЗаполнено(Ответ) ИЛИ Ответ = Ложь Тогда

Возврат Ответ;

КонецЕсли;

ЗначениеДляВозврата = Неопределено;

Выполнить("ЗначениеДляВозврата = КодВозвратаДиалога." + Ответ);

Возврат ЗначениеДляВозврата;

КонецФункции

// Предлагает записать текущий документ

// Возвращает:

// Истина - Документ удачно записан,

// Ложь - отказ от записи или не удалось записать.

//

Функция ПредложитьЗаписатьДокумент(Форма, Текст) Экспорт

Режим = РежимДиалогаВопрос.ДаНет;

Ответ = Вопрос(Текст, РежимДиалогаВопрос.ДаНет, 0);

Если Ответ <> КодВозвратаДиалога.Да Тогда

Возврат Ложь;

КонецЕсли;

Результат = Форма.Записать();

Если Результат Тогда

ПоказатьОповещениеПользователя(

"Создание:",

ПолучитьНавигационнуюСсылку(Форма.Объект.Ссылка),

Строка(Форма.Объект.Ссылка),

БиблиотекаКартинок.Информация32);

КонецЕсли;

Возврат Результат;

КонецФункции

// Копирует файл из временного хранилища на клиента и открывает его для просмотра

//

Процедура ОткрытьФайлИзВременногоХранилища(АдресВоВременномХранилище, ИмяФайла) Экспорт

Если Не РасширениеРаботыСФайламиПодключено() Тогда

Предупреждение(НСтр("ru = 'Не удалось подключить расширение работы с файлами.'"));

Возврат;

КонецЕсли;

ДвоичныеДанные = ПолучитьИзВременногоХранилища(АдресВоВременномХранилище);

Если ДвоичныеДанные = Неопределено Тогда

Предупреждение(НСтр("ru = 'Не удалось получить файл. Возможно он был удален.'"));

Возврат;

КонецЕсли;

ПолноеИмяВременногоФайла = ПолучитьПолноеИмяВременногоФайла(ИмяФайла);

Если ПустаяСтрока(ПолноеИмяВременногоФайла) Тогда

Предупреждение(НСтр("ru = 'Не удалось создать временный файл.'"));

Возврат;

КонецЕсли;

Попытка

ДвоичныеДанные.Записать(ПолноеИмяВременногоФайла);

Исключение

СообщениеОбОшибке = ОписаниеОшибки();

Предупреждение(СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(

НСтр("ru = 'Не удалось записать временный файл.

|%1'"),

СообщениеОбОшибке));

Возврат;

КонецПопытки;

ОткрытьФайлНаДиске(ПолноеИмяВременногоФайла, ИмяФайла);

КонецПроцедуры

Процедура ОткрытьФайлНаДиске(ПолноеИмяФайла, ИмяФайла) Экспорт

Попытка

РаботаСФайламиКлиент.ЗапуститьПриложениеПоИмениФайла(ПолноеИмяФайла);

Исключение

Предупреждение(СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(

НСтр("ru = 'Не удалось открыть файл %1

|%2'"),

ИмяФайла,

ОписаниеОшибки()));

Возврат;

КонецПопытки;

КонецПроцедуры

Функция РасширениеРаботыСФайламиПодключено()

Если Не ПодключитьРасширениеРаботыСФайлами() Тогда

Предупреждение(НСтр("ru = 'Не подключено расширение работы с файлами!'"));

Возврат Ложь;

КонецЕсли;

Возврат Истина;;

КонецФункции

Функция ПолучитьПолноеИмяВременногоФайла(ИмяФайла) Экспорт

#Если ВебКлиент Тогда

Возврат "";

#Иначе

Возврат ПолучитьИмяВременногоКаталога() + "\" + ИмяФайла;

#КонецЕсли

КонецФункции

#Если Не ВебКлиент Тогда

Функция ПолучитьИмяВременногоКаталога()

ИмяВременногоКаталога = ПолучитьИмяВременногоФайла("");

СоздатьКаталог(ИмяВременногоКаталога);

Возврат ИмяВременногоКаталога;

КонецФункции

#КонецЕсли

// Открывает меню выбора папки и сохраняет файл из временного храналища в указанную папку

// Возвращает ссылку на файл или Неопределено в случае неуспеха

//

Функция СоздатьФайлИзВременногоХранилища(Форма, АдресВоВременномХранилище, ИмяФайла) Экспорт

Папка = Неопределено;

Если Не ВыбратьПапку(Папка) Тогда

Возврат Неопределено;

КонецЕсли;

ПолноеИмяФайла = ПолучитьПолноеИмяВременногоФайла(ИмяФайла);

Попытка

ДвоичныеДанные = ПолучитьИзВременногоХранилища(АдресВоВременномХранилище);

ДвоичныеДанные.Записать(ПолноеИмяФайла);

Файл = РаботаСФайламиКлиент.СоздатьДокументНаОсновеФайла(

ПолноеИмяФайла,

Папка,

Форма,

Ложь, //НеОткрыватьКарточкуПослеСозданияИзФайла

ИмяФайла);

Исключение

Текст = НСтр("ru = 'Не удалось сохранить файл.'") + Символы.ПС + ОписаниеОшибки();

Предупреждение(Текст);

Возврат Неопределено;

КонецПопытки;

Возврат Файл;

КонецФункции

// Открывает меню выбора папки и сохраняет файл из временного храналища в указанную папку

// Возвращает ссылку на файл или Неопределено в случае неуспеха

//

Функция СоздатьФайлИзВременногоФайлаНаДиске(Форма, ПолноеИмяФайла, ИмяФайла) Экспорт

Папка = Неопределено;

Если Не ВыбратьПапку(Папка) Тогда

Возврат Неопределено;

КонецЕсли;

Попытка

Файл = РаботаСФайламиКлиент.СоздатьДокументНаОсновеФайла(

ПолноеИмяФайла,

Папка,

Форма,

Ложь, //НеОткрыватьКарточкуПослеСозданияИзФайла

ИмяФайла);

Исключение

Текст = НСтр("ru = 'Не удалось сохранить файл.'") + Символы.ПС + ОписаниеОшибки();

Предупреждение(Текст);

Возврат Неопределено;

КонецПопытки;

Возврат Файл;

КонецФункции

Функция ВыбратьПапку(Папка)

Результат = ОткрытьФормуМодально("Справочник.ПапкиФайлов.ФормаВыбора");

Если Результат = Неопределено Или Результат.Пустая() Тогда

Возврат Ложь;

КонецЕсли;

Папка = Результат;

Возврат Истина;

КонецФункции

Процедура НайтиСтрокуДереваПоСсылке(Ссылка, Дерево, Идентификатор) Экспорт

Если Идентификатор <> Неопределено Тогда

Возврат;

КонецЕсли;

Для Каждого Строка Из Дерево.ПолучитьЭлементы() Цикл

Если Строка.Ссылка = Ссылка Тогда

Идентификатор = Строка.ПолучитьИдентификатор();

Прервать;

КонецЕсли;

НайтиСтрокуДереваПоСсылке(Ссылка, Строка, Идентификатор);

КонецЦикла;

КонецПроцедуры

Функция ВвестиСтрокуСЗаголовоком(Значение, Заголовок = "", Надпись = "", Длина = 0) Экспорт

ПараметрыФормы = Новый Структура;

ПараметрыФормы.Вставить("Значение", Значение);

ПараметрыФормы.Вставить("Заголовок", Заголовок);

ПараметрыФормы.Вставить("Надпись", Надпись);

ПараметрыФормы.Вставить("Длина", Длина);

Результат = ОткрытьФормуМодально("ОбщаяФорма.ВводСтрокиСЗаголовком", ПараметрыФормы);

Если ТипЗнч(Результат) = Тип("Строка") И ЗначениеЗаполнено(Результат) Тогда

Значение = СокрЛП(Результат);

Возврат Истина;

КонецЕсли;

Возврат Ложь;

КонецФункции

// Обработчик подписки на событие ЗаписатьОбщиеРеквизитыДокументов.

//

Процедура ЗаписатьОбщиеРеквизитыДокументов(Источник, Отказ) Экспорт

Если Источник.ОбменДанными.Загрузка Тогда

Возврат;

КонецЕсли;

УстановитьПривилегированныйРежим(Истина);

МенеджерЗаписи = РегистрыСведений.ОбщиеРеквизитыДокументов.СоздатьМенеджерЗаписи();

МенеджерЗаписи.Документ = Источник.Ссылка;

МенеджерЗаписи.Прочитать();

МенеджерЗаписи.Документ = Источник.Ссылка;

МенеджерЗаписи.РегистрационныйНомер = Источник.РегистрационныйНомер;

МенеджерЗаписи.ДатаРегистрации = Источник.ДатаРегистрации;

МенеджерЗаписи.Сумма = Источник.Сумма;

МенеджерЗаписи.Валюта = Источник.Валюта;

МенеджерЗаписи.СрокИсполнения = Источник.СрокИсполнения;

МенеджерЗаписи.Заголовок = Источник.Заголовок;

МенеджерЗаписи.Записать();

КонецПроцедуры

////////////////////////////////////////////////////////////////////////////////

// Программный интерфейс

// Возвращает структуру прав доступа к указанному объекту для указанного

// пользователя. Если пользователь не указан, то используется текуший

// пользователь.

Функция ПолучитьПраваПоОбъекту(ОбъектДоступа, Пользователь = Неопределено) Экспорт

// Проверка на использование ограничения прав доступа

Если Не ДокументооборотПраваДоступаПовтИсп.ВключеноИспользованиеПравДоступа() Тогда

// Если права доступа не включены, то все разрешено

Права = Новый Структура(

"Добавление, Изменение, Удаление, УправлениеПравами, Чтение",

Истина, Истина, Истина, Истина, Истина);

Возврат Права;

КонецЕсли;

// Если использование прав доступа включено, то выполняется получение прав доступа

УстановитьПривилегированныйРежим(Истина);

Если Не ЗначениеЗаполнено(Пользователь) Тогда

Пользователь = ОбщегоНазначения.ТекущийПользователь();

КонецЕсли;

Права = Новый Структура(

"Добавление, Изменение, Удаление, УправлениеПравами, Чтение",

Ложь, Ложь, Ложь, Ложь, Ложь);

// Роли Полные права все разрешено

Если ПользователиСерверПовтИсп.ЭтоПолноправныйПользовательИБ(Пользователь) Тогда

Права.Чтение = Истина;

Права.Добавление = Истина;

Права.Изменение = Истина;

Права.Удаление = Истина;

Права.УправлениеПравами = Истина;

Возврат Права;

КонецЕсли;

Запрос = Новый Запрос;

Если ТипЗнч(ОбъектДоступа) = Тип("СправочникСсылка.ВерсииФайлов")

Или ТипЗнч(ОбъектДоступа) = Тип("СправочникСсылка.Файлы") Тогда

ВладелецФайла = Неопределено;

Если ТипЗнч(ОбъектДоступа) = Тип("СправочникСсылка.Файлы") Тогда

ВладелецФайла = ОбщегоНазначения.ПолучитьЗначениеРеквизита(ОбъектДоступа, "ВладелецФайла");

КонецЕсли;

Если ТипЗнч(ОбъектДоступа) = Тип("СправочникСсылка.ВерсииФайлов") Тогда

Файл = ОбщегоНазначения.ПолучитьЗначениеРеквизита(ОбъектДоступа, "Владелец");

ВладелецФайла = ОбщегоНазначения.ПолучитьЗначениеРеквизита(Файл, "ВладелецФайла");

КонецЕсли;

Запрос.Текст =

"ВЫБРАТЬ

| ПраваПоДескрипторамДоступа.Добавление,

| ПраваПоДескрипторамДоступа.Изменение,

| ПраваПоДескрипторамДоступа.Удаление,

| ПраваПоДескрипторамДоступа.УправлениеПравами,

| ПраваПоДескрипторамДоступа.Чтение

|ИЗ

| РегистрСведений.ПраваПоДескрипторамДоступа КАК ПраваПоДескрипторамДоступа

| ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.ДескрипторыДоступаДляФайлов КАК ДескрипторыДоступаДляФайлов

| ПО ПраваПоДескрипторамДоступа.Дескриптор = ДескрипторыДоступаДляФайлов.Дескриптор

|ГДЕ

| ПраваПоДескрипторамДоступа.Пользователь = &Пользователь

| И ДескрипторыДоступаДляФайлов.ВладелецФайла = &ВладелецФайла";

Запрос.УстановитьПараметр("ВладелецФайла", ВладелецФайла);

Иначе

Запрос.Текст =

"ВЫБРАТЬ

| ПраваПоДескрипторамДоступа.Добавление,

| ПраваПоДескрипторамДоступа.Изменение,

| ПраваПоДескрипторамДоступа.Удаление,

| ПраваПоДескрипторамДоступа.УправлениеПравами,

| ПраваПоДескрипторамДоступа.Чтение

|ИЗ

| РегистрСведений.ПраваПоДескрипторамДоступа КАК ПраваПоДескрипторамДоступа

| ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.ДескрипторыДоступаДляОбъектов КАК ДескрипторыДоступаДляОбъектов

| ПО ПраваПоДескрипторамДоступа.Дескриптор = ДескрипторыДоступаДляОбъектов.Дескриптор

|ГДЕ

| ПраваПоДескрипторамДоступа.Пользователь = &Пользователь

| И ДескрипторыДоступаДляОбъектов.Объект = &ОбъектДоступа";

Запрос.УстановитьПараметр("ОбъектДоступа", ОбъектДоступа.Ссылка);

КонецЕсли;

Запрос.УстановитьПараметр("Пользователь", Пользователь);

Результат = Запрос.Выполнить();

ВыборкаДетальныеЗаписи = Результат.Выбрать();

Если ВыборкаДетальныеЗаписи.Следующий() Тогда

Права.Добавление = ВыборкаДетальныеЗаписи.Добавление;

Права.Изменение = ВыборкаДетальныеЗаписи.Изменение;

Права.Удаление = ВыборкаДетальныеЗаписи.Удаление;

Права.УправлениеПравами = ВыборкаДетальныеЗаписи.УправлениеПравами;

Права.Чтение = ВыборкаДетальныеЗаписи.Чтение;

КонецЕсли;

РасширитьДоступПравамиБезОграничения(Права, ОбъектДоступа, Пользователь);

Возврат Права;

КонецФункции

// Обновляет права доступа по указанному дескриптору

Процедура ОбновитьПраваДоступаПоДескриптору(Дескриптор, Немедленно = Неопределено) Экспорт

УстановитьПривилегированныйРежим(Истина);

Менеджер = ОбщегоНазначения.МенеджерОбъектаПоСсылке(Дескриптор);

Менеджер.ОбновитьПрава(

Дескриптор,

Неопределено, // Протокол

Немедленно);

КонецПроцедуры

// Расширяет переданное соответствие с правами доступа, добавляя к нему

// руководителей тех пользователей, которые уже перечислены в этом соответствии

//

// Если руководители были добавлены, то возвращает Истина

Функция РасширитьПраваПоРуководителям(ПраваДоступа) Экспорт

УстановитьПривилегированныйРежим(Истина);

РуководителиДобавлены = Ложь;

// Расширяем с учетом передачи прав руководителям

Если Константы.ДобавлятьРуководителямДоступПодчиненных.Получить() Тогда

ВсеРуководители = РегистрыСведений.ПодчиненностьСотрудников.ПолучитьВсехРуководителей();

Для каждого Запись Из ПраваДоступа Цикл

// Получение всех руководителей пользователя

Руководители = ВсеРуководители.Получить(Запись.Ключ);

Если Руководители <> Неопределено Тогда

Ст = Новый Структура("Чтение, Добавление, Изменение, Удаление, УправлениеПравами");

ЗаполнитьЗначенияСвойств(Ст, Запись.Значение);

// Обход и добавление каждого руководителя

Для каждого Эл Из Руководители Цикл

ДобавитьЗаписьВСоответствиеПрав(ПраваДоступа, Эл, Ст);

РуководителиДобавлены = Истина;

КонецЦикла;

КонецЕсли;

КонецЦикла;

КонецЕсли;

Возврат РуководителиДобавлены;

КонецФункции

// Расширяет переданное соответствие с правами доступа, добавляя к нему

// делегатов тех пользователей, которые уже перечислены в этом соответствии

//

// Если делегаты были добавлены, то возвращает Истина

Функция РасширитьПраваПоДелегатам(ПраваДоступа, ДескрипторДоступа) Экспорт

Возврат ДокументооборотПраваДоступаПереопределяемый.РасширитьПраваПоДелегатам(ПраваДоступа, ДескрипторДоступа);

КонецФункции

// Добавляет сведения о правах пользователя в соответствие, объединяя их с уже

// существующими сведениями для данного пользователя

Процедура ДобавитьЗаписьВСоответствиеПрав(ПраваДоступа, Пользователь, Знач Права) Экспорт

Эл = ПраваДоступа.Получить(Пользователь);

Если Эл <> Неопределено Тогда

Эл.Чтение = Эл.Чтение ИЛИ Права.Чтение;

Эл.Добавление = Эл.Добавление ИЛИ Права.Добавление;

Эл.Изменение = Эл.Изменение ИЛИ Права.Изменение;

Эл.Удаление = Эл.Удаление ИЛИ Права.Удаление;

Эл.УправлениеПравами = Эл.УправлениеПравами ИЛИ Права.УправлениеПравами;

Иначе

Эл = Новый Структура("Чтение, Добавление, Изменение, Удаление, УправлениеПравами");

ЗаполнитьЗначенияСвойств(Эл, Права);

КонецЕсли;

ПраваДоступа.Вставить(Пользователь, Эл);

КонецПроцедуры

// Добавляет указанные права указанного пользователя или роли к соответсвию прав,

// производит автоматическое разыменование роли до конкретных пользователей

Процедура ДобавитьПользователяВСоответствиеПрав(

ПраваДоступа,

Пользователь,

ОсновнойОбъектАдресации,

ДополнительныйОбъектАдресации,

Знач Права) Экспорт

// Если пользователь не указан, то запись не добавляется

Если Не ЗначениеЗаполнено(Пользователь) Тогда

Возврат;

КонецЕсли;

Если ТипЗнч(Пользователь) = Тип("СправочникСсылка.Пользователи") Тогда

РеквизитыПользователя = ОбщегоНазначения.ПолучитьЗначенияРеквизитов(Пользователь,

"ПометкаУдаления, Недействителен");

Если Не РеквизитыПользователя.ПометкаУдаления И Не РеквизитыПользователя.Недействителен Тогда

ДобавитьЗаписьВСоответствиеПрав(ПраваДоступа, Пользователь, Права);

КонецЕсли;

ИначеЕсли ТипЗнч(Пользователь) = Тип("СправочникСсылка.РолиИсполнителей") Тогда

ИсполнителиРоли = РегистрыСведений.ИсполнителиЗадач.ПолучитьИсполнителейРоли(

Пользователь,

ОсновнойОбъектАдресации,

ДополнительныйОбъектАдресации);

Для каждого Эл Из ИсполнителиРоли Цикл

ДобавитьЗаписьВСоответствиеПрав(ПраваДоступа, Эл.Исполнитель, Права);

КонецЦикла;

ИначеЕсли ТипЗнч(Пользователь) = Тип("СправочникСсылка.ГруппыПользователей") Тогда

ПользователиГруппы = ДокументооборотПраваДоступаПовтИсп.ПолучитьСоставГруппыПользователей(Пользователь);

Для каждого Эл Из ПользователиГруппы Цикл

ДобавитьЗаписьВСоответствиеПрав(ПраваДоступа, Эл.Пользователь, Права);

КонецЦикла;

Иначе

ВызватьИсключение(НСтр("ru = 'Неизвестный тип пользователя.'"));

КонецЕсли;

КонецПроцедуры

// Определяет дескриптор доступа для указанного объекта доступа

// Пр необходимости создает новый дескриптор, привязывает его к

// объекту и вычисляет права

Функция ОпределитьДескрипторДоступаОбъекта(ОбъектДоступа, Немедленно = Ложь) Экспорт

УстановитьПривилегированныйРежим(Истина);

// Получение ссылки на подходящий дескриптор

Дескриптор = ПолучитьДескрипторДоступа(ОбъектДоступа, Немедленно);

// Сохранение соответствия объекта доступа и его дескриптора

РегистрыСведений.ДескрипторыДоступаДляОбъектов.Сохранить(Дескриптор.Ссылка, ОбъектДоступа.Ссылка);

Возврат Дескриптор;

КонецФункции

// Определяет дескриптор доступа для указанного владельца файла

// При необходимости создает новый дескриптор, привязывает его к дескриптору

// владельца файла и вычисляет права

Функция ОпределитьДескрипторДоступаФайлаПоВладельцу(ВладелецФайла) Экспорт

УстановитьПривилегированныйРежим(Истина);

// Получение ссылки на подходящий дескриптор

Дескриптор = ПолучитьДескрипторДоступаФайла(ВладелецФайла);

Возврат Дескриптор;

КонецФункции

// Определяет дескриптор(ы) доступа для указанного набора записей

// При необходимости создает новый дескриптор и вычисляет права

Функция ОпределитьДескрипторДоступаНабораЗаписей(НаборЗаписей, Немедленно = Ложь) Экспорт

УстановитьПривилегированныйРежим(Истина);

МетаданныеНабораЗаписей = НаборЗаписей.Метаданные();

ИдентификаторОбъектаМетаданных = ОбщегоНазначения.ИдентификаторОбъектаМетаданных(МетаданныеНабораЗаписей);

Для каждого Запись Из НаборЗаписей Цикл

Дескриптор = ПолучитьДескрипторДоступаЗаписиНабораЗаписей(

ИдентификаторОбъектаМетаданных,

Запись,

Немедленно);

КонецЦикла;

Возврат Дескриптор;

КонецФункции

// Копирует права указанного объекта в указанные ПраваДоступа

Процедура СкопироватьПраваОбъекта(ОбъектДоступа, ПраваДоступа) Экспорт

УстановитьПривилегированныйРежим(Истина);

Для Каждого Эл из ПраваДоступа Цикл

ВызватьИсключение НСтр("ru = 'Для копирования прав объекта указан не пустой набор прав.'");

КонецЦикла;

ДескрипторДоступа = РегистрыСведений.ДескрипторыДоступаДляОбъектов.НайтиДескрипторДляОбъекта(ОбъектДоступа);

Если ЗначениеЗаполнено(ДескрипторДоступа) Тогда

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| ПраваПоДескрипторамДоступа.Добавление,

| ПраваПоДескрипторамДоступа.Изменение,

| ПраваПоДескрипторамДоступа.Удаление,

| ПраваПоДескрипторамДоступа.УправлениеПравами,

| ПраваПоДескрипторамДоступа.Чтение,

| ПраваПоДескрипторамДоступа.Пользователь

|ИЗ

| РегистрСведений.ПраваПоДескрипторамДоступа КАК ПраваПоДескрипторамДоступа

|ГДЕ

| ПраваПоДескрипторамДоступа.Дескриптор = &Дескриптор";

Запрос.УстановитьПараметр("Дескриптор", ДескрипторДоступа);

Результат = Запрос.Выполнить();

ВыборкаДетальныеЗаписи = Результат.Выбрать();

Пока ВыборкаДетальныеЗаписи.Следующий() Цикл

ПраваПользователя = Новый Структура("Чтение, Добавление, Изменение, Удаление, УправлениеПравами");

ПраваПользователя.Чтение = ВыборкаДетальныеЗаписи.Чтение;

ПраваПользователя.Добавление = ВыборкаДетальныеЗаписи.Изменение; // По умолчанию право добавления не отличается от права изменения

ПраваПользователя.Изменение = ВыборкаДетальныеЗаписи.Изменение;

ПраваПользователя.Удаление = ВыборкаДетальныеЗаписи.Изменение; // По умолчанию право удаления не отличается от права изменения

ПраваПользователя.УправлениеПравами = ВыборкаДетальныеЗаписи.УправлениеПравами;

ПраваДоступа.Вставить(ВыборкаДетальныеЗаписи.Пользователь, ПраваПользователя);

КонецЦикла;

КонецЕсли;

КонецПроцедуры

// Копирует права указанного дескриптора в указанные ПраваДоступа

Процедура СкопироватьПраваДескриптора(ДескрипторДоступа, ПраваДоступа) Экспорт

УстановитьПривилегированныйРежим(Истина);

Для Каждого Эл из ПраваДоступа Цикл

ВызватьИсключение НСтр("ru = 'Для копирования прав объекта указан не пустой набор прав.'");

КонецЦикла;

Если ЗначениеЗаполнено(ДескрипторДоступа) Тогда

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| ПраваПоДескрипторамДоступа.Добавление,

| ПраваПоДескрипторамДоступа.Изменение,

| ПраваПоДескрипторамДоступа.Удаление,

| ПраваПоДескрипторамДоступа.УправлениеПравами,

| ПраваПоДескрипторамДоступа.Чтение,

| ПраваПоДескрипторамДоступа.Пользователь

|ИЗ

| РегистрСведений.ПраваПоДескрипторамДоступа КАК ПраваПоДескрипторамДоступа

|ГДЕ

| ПраваПоДескрипторамДоступа.Дескриптор = &Дескриптор";

Запрос.УстановитьПараметр("Дескриптор", ДескрипторДоступа);

Результат = Запрос.Выполнить();

ВыборкаДетальныеЗаписи = Результат.Выбрать();

Пока ВыборкаДетальныеЗаписи.Следующий() Цикл

ПраваПользователя = Новый Структура("Чтение, Добавление, Изменение, Удаление, УправлениеПравами");

ПраваПользователя.Чтение = ВыборкаДетальныеЗаписи.Чтение;

ПраваПользователя.Добавление = ВыборкаДетальныеЗаписи.Изменение; // По умолчанию право добавления не отличается от права изменения

ПраваПользователя.Изменение = ВыборкаДетальныеЗаписи.Изменение;

ПраваПользователя.Удаление = ВыборкаДетальныеЗаписи.Изменение; // По умолчанию право удаления не отличается от права изменения

ПраваПользователя.УправлениеПравами = ВыборкаДетальныеЗаписи.УправлениеПравами;

ПраваДоступа.Вставить(ВыборкаДетальныеЗаписи.Пользователь, ПраваПользователя);

КонецЦикла;

КонецЕсли;

КонецПроцедуры

// Умножает структуру прав доступа для указанных объектов для всех пользователей

Функция УмножитьПраваОбъектов(ОбъектыДоступа) Экспорт

УстановитьПривилегированныйРежим(Истина);

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| ПраваПоДескрипторамДоступа.Добавление,

| ПраваПоДескрипторамДоступа.Изменение,

| ПраваПоДескрипторамДоступа.Удаление,

| ПраваПоДескрипторамДоступа.УправлениеПравами,

| ПраваПоДескрипторамДоступа.Чтение,

| ПраваПоДескрипторамДоступа.Пользователь

|ПОМЕСТИТЬ ПраваВременная

|ИЗ

| РегистрСведений.ПраваПоДескрипторамДоступа КАК ПраваПоДескрипторамДоступа

| ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.ДескрипторыДоступаДляОбъектов КАК ДескрипторыДоступаДляОбъектов

| ПО ПраваПоДескрипторамДоступа.Дескриптор = ДескрипторыДоступаДляОбъектов.Дескриптор

|ГДЕ

| ДескрипторыДоступаДляОбъектов.Объект В(&ОбъектыДоступа)

|

|ИНДЕКСИРОВАТЬ ПО

| ПраваПоДескрипторамДоступа.Пользователь

|;

|

|////////////////////////////////////////////////////////////////////////////////

|ВЫБРАТЬ

| ПраваВременная.Пользователь,

| КОЛИЧЕСТВО(ПраваВременная.Добавление) КАК ЧислоРазрешенных

|ПОМЕСТИТЬ ПраваДобавлениеВременная

|ИЗ

| ПраваВременная КАК ПраваВременная

|ГДЕ

| ПраваВременная.Добавление

|

|СГРУППИРОВАТЬ ПО

| ПраваВременная.Пользователь

|

|ИМЕЮЩИЕ

| КОЛИЧЕСТВО(ПраваВременная.Добавление) = &КоличествоЗаписей

|;

|

|////////////////////////////////////////////////////////////////////////////////

|ВЫБРАТЬ

| ПраваВременная.Пользователь,

| КОЛИЧЕСТВО(ПраваВременная.Изменение) КАК ЧислоРазрешенных

|ПОМЕСТИТЬ ПраваИзменениеВременная

|ИЗ

| ПраваВременная КАК ПраваВременная

|ГДЕ

| ПраваВременная.Изменение

|

|СГРУППИРОВАТЬ ПО

| ПраваВременная.Пользователь

|

|ИМЕЮЩИЕ

| КОЛИЧЕСТВО(ПраваВременная.Изменение) = &КоличествоЗаписей

|;

|

|////////////////////////////////////////////////////////////////////////////////

|ВЫБРАТЬ

| ПраваВременная.Пользователь,

| КОЛИЧЕСТВО(ПраваВременная.Удаление) КАК ЧислоРазрешенных

|ПОМЕСТИТЬ ПраваУдалениеВременная

|ИЗ

| ПраваВременная КАК ПраваВременная

|ГДЕ

| ПраваВременная.Удаление

|

|СГРУППИРОВАТЬ ПО

| ПраваВременная.Пользователь

|

|ИМЕЮЩИЕ

| КОЛИЧЕСТВО(ПраваВременная.Удаление) = &КоличествоЗаписей

|;

|

|////////////////////////////////////////////////////////////////////////////////

|ВЫБРАТЬ

| ПраваВременная.Пользователь,

| КОЛИЧЕСТВО(ПраваВременная.УправлениеПравами) КАК ЧислоРазрешенных

|ПОМЕСТИТЬ ПраваУправлениеПравамиВременная

|ИЗ

| ПраваВременная КАК ПраваВременная

|ГДЕ

| ПраваВременная.УправлениеПравами

|

|СГРУППИРОВАТЬ ПО

| ПраваВременная.Пользователь

|

|ИМЕЮЩИЕ

| КОЛИЧЕСТВО(ПраваВременная.УправлениеПравами) = &КоличествоЗаписей

|;

|

|////////////////////////////////////////////////////////////////////////////////

|ВЫБРАТЬ

| ПраваВременная.Пользователь,

| КОЛИЧЕСТВО(ПраваВременная.Чтение) КАК ЧислоРазрешенных

|ПОМЕСТИТЬ ПраваЧтениеВременная

|ИЗ

| ПраваВременная КАК ПраваВременная

|ГДЕ

| ПраваВременная.Чтение

|

|СГРУППИРОВАТЬ ПО

| ПраваВременная.Пользователь

|

|ИМЕЮЩИЕ

| КОЛИЧЕСТВО(ПраваВременная.Чтение) = &КоличествоЗаписей

|;

|

|////////////////////////////////////////////////////////////////////////////////

|ВЫБРАТЬ РАЗЛИЧНЫЕ

| ПраваВременная.Пользователь,

| ВЫБОР

| КОГДА ПраваДобавлениеВременная.Пользователь ЕСТЬ NULL

| ТОГДА ЛОЖЬ

| ИНАЧЕ ИСТИНА

| КОНЕЦ КАК Добавление,

| ВЫБОР

| КОГДА ПраваИзменениеВременная.Пользователь ЕСТЬ NULL

| ТОГДА ЛОЖЬ

| ИНАЧЕ ИСТИНА

| КОНЕЦ КАК Изменение,

| ВЫБОР

| КОГДА ПраваУправлениеПравамиВременная.Пользователь ЕСТЬ NULL

| ТОГДА ЛОЖЬ

| ИНАЧЕ ИСТИНА

| КОНЕЦ КАК Удаление,

| ВЫБОР

| КОГДА ПраваУдалениеВременная.Пользователь ЕСТЬ NULL

| ТОГДА ЛОЖЬ

| ИНАЧЕ ИСТИНА

| КОНЕЦ КАК УправлениеПравами,

| ВЫБОР

| КОГДА ПраваЧтениеВременная.Пользователь ЕСТЬ NULL

| ТОГДА ЛОЖЬ

| ИНАЧЕ ИСТИНА

| КОНЕЦ КАК Чтение

|ИЗ

| ПраваВременная КАК ПраваВременная

| ЛЕВОЕ СОЕДИНЕНИЕ ПраваДобавлениеВременная КАК ПраваДобавлениеВременная

| ПО (ПраваДобавлениеВременная.Пользователь = ПраваВременная.Пользователь)

| ЛЕВОЕ СОЕДИНЕНИЕ ПраваИзменениеВременная КАК ПраваИзменениеВременная

| ПО (ПраваИзменениеВременная.Пользователь = ПраваВременная.Пользователь)

| ЛЕВОЕ СОЕДИНЕНИЕ ПраваУдалениеВременная КАК ПраваУдалениеВременная

| ПО (ПраваУдалениеВременная.Пользователь = ПраваВременная.Пользователь)

| ЛЕВОЕ СОЕДИНЕНИЕ ПраваУправлениеПравамиВременная КАК ПраваУправлениеПравамиВременная

| ПО (ПраваУправлениеПравамиВременная.Пользователь = ПраваВременная.Пользователь)

| ЛЕВОЕ СОЕДИНЕНИЕ ПраваЧтениеВременная КАК ПраваЧтениеВременная

| ПО (ПраваЧтениеВременная.Пользователь = ПраваВременная.Пользователь)

|ГДЕ

| (НЕ ПраваДобавлениеВременная.Пользователь ЕСТЬ NULL

| ИЛИ НЕ ПраваИзменениеВременная.Пользователь ЕСТЬ NULL

| ИЛИ НЕ ПраваУправлениеПравамиВременная.Пользователь ЕСТЬ NULL

| ИЛИ НЕ ПраваУдалениеВременная.Пользователь ЕСТЬ NULL

| ИЛИ НЕ ПраваЧтениеВременная.Пользователь ЕСТЬ NULL )";

Запрос.УстановитьПараметр("ОбъектыДоступа", ОбъектыДоступа);

Запрос.УстановитьПараметр("КоличествоЗаписей", ОбъектыДоступа.Количество());

Результат = Запрос.Выполнить().Выгрузить();

Возврат Результат;

КонецФункции

// Удаляет все данные, связанные с правами доступа

// Используется для полного обновления прав доступа ко всем данным информационной базы

Процедура УдалитьВсеДанныеОПравахДоступа(ЭтоФоновоеЗадание = Ложь) Экспорт

УстановитьПривилегированныйРежим(Истина);

Если Не ЭтоФоновоеЗадание И Константы.ДокументооборотИспользоватьОтложенноеОбновлениеПравДоступа.Получить() Тогда

// Отключение регл. заданий

ЗаданиеОперативноеВключено = ОтключитьОбработкуОперативнойОчереди();

ЗаданиеДолгоеВключено = ОтключитьОбработкуДолгойОчереди();

// Удаление всех прав объектов

Набор = РегистрыСведений.ПраваПоДескрипторамДоступа.СоздатьНаборЗаписей();

Набор.Записать();

// Включение регл. заданий

Если ЗаданиеОперативноеВключено Тогда

ВключитьОбработкуОперативнойОчереди();

КонецЕсли;

Если ЗаданиеДолгоеВключено Тогда

ВключитьОбработкуДолгойОчереди();

КонецЕсли;

Возврат; // Остальные данные будут удалены фоновым заданием

КонецЕсли;

НачатьТранзакцию();

// Очистка очереди

РегистрыСведений.ОчередьОбновленияПравДоступа.Очистить();

// Удаление всех прав объектов

Набор = РегистрыСведений.ПраваПоДескрипторамДоступа.СоздатьНаборЗаписей();

Набор.Записать();

Набор = РегистрыСведений.ДескрипторыДоступаДляОбъектов.СоздатьНаборЗаписей();

Набор.Записать();

Выборка = Справочники.ДескрипторыДоступаОбъектов.Выбрать();

Пока Выборка.Следующий() Цикл

Объект = Выборка.ПолучитьОбъект();

Объект.Удалить();

КонецЦикла;

// Удаление всех прав файлов

НаборЗаписей = РегистрыСведений.ДескрипторыДоступаДляФайлов.СоздатьНаборЗаписей();

НаборЗаписей.Записать();

Выборка = Справочники.ДескрипторыДоступаФайлов.Выбрать();

Пока Выборка.Следующий() Цикл

Объект = Выборка.ПолучитьОбъект();

Объект.Удалить();

КонецЦикла;

// Удаление всех прав регистров

Выборка = Справочники.ДескрипторыДоступаРегистров.Выбрать();

Пока Выборка.Следующий() Цикл

Объект = Выборка.ПолучитьОбъект();

Объект.Удалить();

КонецЦикла;

ЗафиксироватьТранзакцию();

КонецПроцедуры

// Обновляет сведения о правах доступа всех данных информационной базы.

Процедура ОбновитьПраваВсехДанных() Экспорт

УстановитьПривилегированныйРежим(Истина);

ВремяНачала = ТекущаяДата();

// Пересчет прав всех объектов

ТипыВладельцев = Метаданные.ПодпискиНаСобытия.ДокументооборотПраваДоступаПриЗаписиОбъектаДоступа.Источник.Типы();

Для Каждого Тип Из ТипыВладельцев Цикл

ИмяСправочника = Метаданные.НайтиПоТипу(Тип).ПолноеИмя();

ОпределитьПраваПоИмениОбъекта(ИмяСправочника);

КонецЦикла;

// Пересчет прав всех файлов

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ РАЗЛИЧНЫЕ

| Файлы.ВладелецФайла

|ИЗ

| Справочник.Файлы КАК Файлы";

Выборка = Запрос.Выполнить().Выбрать();

Пока Выборка.Следующий() Цикл

ОпределитьДескрипторДоступаФайлаПоВладельцу(Выборка.ВладелецФайла);

КонецЦикла;

// Пересчет прав всех регистров

ТипыВладельцев = Метаданные.ПодпискиНаСобытия.ДокументооборотПраваДоступаПередЗаписьюНабораЗаписей.Источник.Типы();

Для Каждого Тип Из ТипыВладельцев Цикл

МетаданныеРегистра = Метаданные.НайтиПоТипу(Тип);

ПолноеИмя = МетаданныеРегистра.ПолноеИмя();

ОпределитьПраваПоИмениРегистра(ПолноеИмя)

КонецЦикла;

КонецПроцедуры

// Определяет права доступа для всех объектов указанной таблицы

// Если права для этого объекта уже определены, то ничего не делает

Процедура ОпределитьПраваПоИмениОбъекта(Таблица) Экспорт

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| Данные.Ссылка

|ИЗ

| [Таблица] КАК Данные";

Запрос.Текст = СтрЗаменить(Запрос.Текст, "[Таблица]", Таблица);

Выборка = Запрос.Выполнить().Выбрать();

Пока Выборка.Следующий() Цикл

ДокументооборотПраваДоступа.ОпределитьДескрипторДоступаОбъекта(Выборка.Ссылка);

КонецЦикла;

КонецПроцедуры

// Определяет права доступа для всех записей указанного регистра

// Если права для записей этого регситра уже определены, то ничего не делает

Процедура ОпределитьПраваПоИмениРегистра(ПолноеИмя) Экспорт

МенеджерРегистра = ОбщегоНазначения.МенеджерОбъектаПоПолномуИмени(ПолноеИмя);

МетаданныеРегистра = Метаданные.НайтиПоПолномуИмени(ПолноеИмя);

ПодчиненРегистратору = Ложь;

Если Метаданные.РегистрыНакопления.Содержит(МетаданныеРегистра) Тогда

ПодчиненРегистратору = Истина;

КонецЕсли;

Если Метаданные.РегистрыСведений.Содержит(МетаданныеРегистра) Тогда

Если МетаданныеРегистра.РежимЗаписи = Метаданные.СвойстваОбъектов.РежимЗаписиРегистра.ПодчинениеРегистратору Тогда

ПодчиненРегистратору = Истина;

КонецЕсли;

КонецЕсли;

Если ПодчиненРегистратору Тогда

// Пересчет прав всех записей по уникальным регистраторам

Запрос = Новый Запрос;

Запрос.Текст = "ВЫБРАТЬ РАЗЛИЧНЫЕ Регистр.Регистратор";

Запрос.Текст = Запрос.Текст +

"

|ИЗ

| %1 КАК Регистр";

Запрос.Текст = СтрЗаменить(Запрос.Текст, "%1", ПолноеИмя);

Выборка = Запрос.Выполнить().Выбрать();

// Обход результатов запроса

Пока Выборка.Следующий() Цикл

// Чтение набора записей с отбором по регистратору

НаборЗаписей = МенеджерРегистра.СоздатьНаборЗаписей();

НаборЗаписей.Отбор.Регистратор.Установить(Выборка.Регистратор);

НаборЗаписей.Прочитать();

// Определение дескриптора для набора записей

ДокументооборотПраваДоступа.ОпределитьДескрипторДоступаНабораЗаписей(НаборЗаписей);

КонецЦикла;

Иначе

СведенияОПолях = Новый Структура("ОбъектДоступа1, ОбъектДоступа2, ОбъектДоступа3");

МенеджерРегистра.ЗаполнитьСведенияОПоляхДоступа(СведенияОПолях);

// Пересчет прав всех уникальных записей всех регистров

Запрос = Новый Запрос;

Запрос.Текст = "ВЫБРАТЬ РАЗЛИЧНЫЕ ";

// Добавление к запросу правообразующих полей

Запрос.Текст = Запрос.Текст +

"Регистр." + СведенияОПолях.ОбъектДоступа1;

Если СведенияОПолях.ОбъектДоступа2 <> Неопределено Тогда

Запрос.Текст = Запрос.Текст + ", Регистр." + СведенияОПолях.ОбъектДоступа2;

КонецЕсли;

Если СведенияОПолях.ОбъектДоступа3 <> Неопределено Тогда

Запрос.Текст = Запрос.Текст + ", Регистр." + СведенияОПолях.ОбъектДоступа3;

КонецЕсли;

// Добавление к запросу всех измерений регистра

Для каждого Измерение Из МетаданныеРегистра.Измерения Цикл

Если Измерение.Имя <> СведенияОПолях.ОбъектДоступа1

И Измерение.Имя <> СведенияОПолях.ОбъектДоступа2

И Измерение.Имя <> СведенияОПолях.ОбъектДоступа2 Тогда

Запрос.Текст = Запрос.Текст + ", Регистр." + Измерение.Имя;

КонецЕсли;

КонецЦикла;

Запрос.Текст = Запрос.Текст +

"

|ИЗ

| %1 КАК Регистр";

Запрос.Текст = СтрЗаменить(Запрос.Текст, "%1", ПолноеИмя);

Выборка = Запрос.Выполнить().Выбрать();

// Обход результатов запроса

Пока Выборка.Следующий() Цикл

// Чтение набора записей

НаборЗаписей = МенеджерРегистра.СоздатьНаборЗаписей();

Для каждого Измерение Из МетаданныеРегистра.Измерения Цикл

НаборЗаписей.Отбор[Измерение.Имя].Установить(Выборка[Измерение.Имя]);

КонецЦикла;

НаборЗаписей.Прочитать();

// Определение дескриптора для набора записей

ДокументооборотПраваДоступа.ОпределитьДескрипторДоступаНабораЗаписей(НаборЗаписей);

КонецЦикла;

КонецЕсли;

КонецПроцедуры

// Возвращает Истина если у указанного пользователя есть указанная роль

// Если пользователь не указан, то используется текущий пользователь

Функция ЕстьРоль(Роль, Объект = Неопределено, Пользователь = Неопределено) Экспорт

Если УправлениеДоступом.ЭтоПолноправныйПользователь(Пользователь) Тогда

Возврат Истина;

КонецЕсли;

// Проверка, что роль назначается пользователю через группу доступа по профилю.

УстановитьПривилегированныйРежим(Истина);

Если Пользователь = Неопределено Тогда

Пользователь = ОбщегоНазначения.ТекущийПользователь();

КонецЕсли;

ОбъектМетаданныхРоль = Метаданные.Роли.Найти(Роль);

ИдентификаторРоли = ОбщегоНазначения.ИдентификаторОбъектаМетаданных(ОбъектМетаданныхРоль);

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| ДокументооборотПользователиГруппДоступа.ГруппаДоступа

|ИЗ

| РегистрСведений.ДокументооборотПользователиГруппДоступа КАК ДокументооборотПользователиГруппДоступа

| ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.ПрофилиГруппДоступа.Роли КАК ПрофилиГруппДоступаРоли

| ПО ДокументооборотПользователиГруппДоступа.ГруппаДоступа.Профиль = ПрофилиГруппДоступаРоли.Ссылка

|ГДЕ

| ДокументооборотПользователиГруппДоступа.Пользователь = &Пользователь

| И ПрофилиГруппДоступаРоли.Роль = &Роль";

Запрос.УстановитьПараметр("Пользователь", Пользователь);

Запрос.УстановитьПараметр("Роль", ИдентификаторРоли);

Результат = Запрос.Выполнить();

ЕстьРоль = Не Результат.Пустой();

// Проверка значений доступа

Если ЕстьРоль И Объект <> Неопределено Тогда

ЕстьРоль = Ложь;

ДескрипторОбъекта = ПолучитьДескрипторДоступа(Объект);

Выборка = Результат.Выбрать();

Пока Выборка.Следующий() Цикл

ЕстьРоль = Справочники.ДескрипторыДоступаОбъектов.ДоступПоЗначениямРазрешен(

ДескрипторОбъекта, Выборка.ГруппаДоступа);

Если ЕстьРоль Тогда

Прервать;

КонецЕсли;

КонецЦикла;

КонецЕсли;

Возврат ЕстьРоль;

КонецФункции

// Вызывается рекурсивно

Процедура ОбновитьПраваОбъектовЗависящихОтГруппыПользователей(ГруппаПользователей, Немедленно = Неопределено) Экспорт

УстановитьПривилегированныйРежим(Истина);

// Рекурсивный вызов обновления для родительской группы пользователей

Если ЗначениеЗаполнено(ГруппаПользователей.Родитель) Тогда

ОбновитьПраваОбъектовЗависящихОтГруппыПользователей(ГруппаПользователей.Родитель, Немедленно);

КонецЕсли;

// Проверка на отложенное обновление прав доступа

Если ДокументооборотПраваДоступаПовтИсп.ОтложенноеОбновлениеПравДоступа()

И Немедленно <> Истина Тогда

// Добавление в очередь

РегистрыСведений.ОчередьОбновленияПравДоступа.Добавить(ГруппаПользователей);

Возврат;

КонецЕсли;

// Группы доступа

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| ГруппыДоступаПользователи.Ссылка

|ИЗ

| Справочник.ГруппыДоступа.Пользователи КАК ГруппыДоступаПользователи

|ГДЕ

| ГруппыДоступаПользователи.Пользователь = &Пользователь";

Запрос.УстановитьПараметр("Пользователь", ГруппаПользователей.Ссылка);

Результат = Запрос.Выполнить();

ВыборкаДетальныеЗаписи = Результат.Выбрать();

Пока ВыборкаДетальныеЗаписи.Следующий() Цикл

ОбновитьПраваЗависящиеОтГруппыДоступа(ВыборкаДетальныеЗаписи.Ссылка);

КонецЦикла;

// РегистрСведений НастройкиПравОбъектов

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| НастройкиПравОбъектов.Объект

|ИЗ

| РегистрСведений.НастройкиПравОбъектов КАК НастройкиПравОбъектов

|ГДЕ

| НастройкиПравОбъектов.Пользователь = &Пользователь";

Запрос.УстановитьПараметр("Пользователь", ГруппаПользователей.Ссылка);

Результат = Запрос.Выполнить();

ВыборкаДетальныеЗаписи = Результат.Выбрать();

Пока ВыборкаДетальныеЗаписи.Следующий() Цикл

ОбновитьПраваПапки(ВыборкаДетальныеЗаписи.Объект);

КонецЦикла;

// Табличная часть "РабочаяГруппа" у дескриптора доступа объекта

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| ДескрипторыДоступаОбъектовРабочаяГруппа.Ссылка

|ИЗ

| Справочник.ДескрипторыДоступаОбъектов.РабочаяГруппа КАК ДескрипторыДоступаОбъектовРабочаяГруппа

|ГДЕ

| ДескрипторыДоступаОбъектовРабочаяГруппа.Участник = &ГруппаПользователей";

Запрос.УстановитьПараметр("ГруппаПользователей", ГруппаПользователей.Ссылка);

Результат = Запрос.Выполнить();

ВыборкаДетальныеЗаписи = Результат.Выбрать();

Пока ВыборкаДетальныеЗаписи.Следующий() Цикл

Справочники.ДескрипторыДоступаОбъектов.ОбновитьПрава(ВыборкаДетальныеЗаписи.Ссылка);

КонецЦикла;

// Табличная часть "Пользователи" у дескриптора доступа объекта

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| ДескрипторыДоступаОбъектовПользователи.Ссылка

|ИЗ

| Справочник.ДескрипторыДоступаОбъектов.Пользователи КАК ДескрипторыДоступаОбъектовПользователи

|ГДЕ

| ДескрипторыДоступаОбъектовПользователи.Пользователь = &ГруппаПользователей";

Запрос.УстановитьПараметр("ГруппаПользователей", ГруппаПользователей.Ссылка);

Результат = Запрос.Выполнить();

ВыборкаДетальныеЗаписи = Результат.Выбрать();

Пока ВыборкаДетальныеЗаписи.Следующий() Цикл

Справочники.ДескрипторыДоступаОбъектов.ОбновитьПрава(ВыборкаДетальныеЗаписи.Ссылка);

КонецЦикла;

// Если изменена группа ВсеПользователи, то выполняется обновление всех дескрипторов

// для элементов справочников, которые являются группами. Т.к. доступ к группам имеют

// все пользователи без ограничений

Если ГруппаПользователей = Справочники.ГруппыПользователей.ВсеПользователи Тогда

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| ДескрипторыДоступаОбъектов.Ссылка

|ИЗ

| Справочник.ДескрипторыДоступаОбъектов КАК ДескрипторыДоступаОбъектов

|ГДЕ

| ДескрипторыДоступаОбъектов.Группа = Истина";

Результат = Запрос.Выполнить();

ВыборкаДетальныеЗаписи = Результат.Выбрать();

Пока ВыборкаДетальныеЗаписи.Следующий() Цикл

Справочники.ДескрипторыДоступаОбъектов.ОбновитьПрава(ВыборкаДетальныеЗаписи.Ссылка);

КонецЦикла;

КонецЕсли;

КонецПроцедуры

// Обновляет права, зависящие от указанного подразделения

// - для руководителя подразделения

// - для входящих в подразделение пользователей

// - для родительских и подчиненных подразделений

Процедура ОбновитьПраваПоПодразделению(Подразделение, Немедленно = Неопределено) Экспорт

УстановитьПривилегированныйРежим(Истина);

// Если не установлена передача руководителям доступа подчиненных

// то тогда при изменении подразделений обновление прав выполнять

// не требуется

Если Константы.ДобавлятьРуководителямДоступПодчиненных.Получить() Тогда

Если ДокументооборотПраваДоступаПовтИсп.ОтложенноеОбновлениеПравДоступа()

И Немедленно <> Истина Тогда

РегистрыСведений.ОчередьОбновленияПравДоступа.Добавить(Подразделение);

Иначе

ОбновитьПраваПоПодчиненнымПодразделениям(Подразделение);

КонецЕсли;

КонецЕсли;

КонецПроцедуры

// Находит все объекты, которые используют указанный дескриптор

// и обновляет права всех других дескрипторов, которые зависят

// от этих объектов

Процедура ОбновитьПраваЗависимыхДескрипторовДоступа(Дескриптор) Экспорт

УстановитьПривилегированныйРежим(Истина);

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| ДескрипторыДоступаДляОбъектов.Объект

|ИЗ

| РегистрСведений.ДескрипторыДоступаДляОбъектов КАК ДескрипторыДоступаДляОбъектов

|ГДЕ

| ДескрипторыДоступаДляОбъектов.Дескриптор = &Дескриптор";

Запрос.УстановитьПараметр("Дескриптор", Дескриптор.Ссылка);

Результат = Запрос.Выполнить();

ВыборкаДетальныеЗаписи = Результат.Выбрать();

Пока ВыборкаДетальныеЗаписи.Следующий() Цикл

ОбновитьПраваСвязанныхДескрипторовПоОбъекту(ВыборкаДетальныеЗаписи.Объект);

КонецЦикла;

КонецПроцедуры

// Обновляет все дескрипторы прав доступа, в правах которых встречается

// указанный пользователь

Процедура ОбновитьПраваПоПользователю(Пользователь, Немедленно = Ложь) Экспорт

Если Не Немедленно Тогда

РегистрыСведений.ОчередьОбновленияПравДоступа.Добавить(Пользователь, Дата("00010101000000"));

Иначе

УстановитьПривилегированныйРежим(Истина);

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| ПраваПоДескрипторамДоступа.Дескриптор

|ИЗ

| РегистрСведений.ПраваПоДескрипторамДоступа КАК ПраваПоДескрипторамДоступа

|ГДЕ

| ПраваПоДескрипторамДоступа.Пользователь = &Пользователь";

Запрос.УстановитьПараметр("Пользователь", Пользователь);

Результат = Запрос.Выполнить();

ВыборкаДетальныеЗаписи = Результат.Выбрать();

Немедленно = Не ДокументооборотПраваДоступаПовтИсп.ОтложенноеОбновлениеПравДоступа();

Пока ВыборкаДетальныеЗаписи.Следующий() Цикл

ОбновитьПраваДоступаПоДескриптору(ВыборкаДетальныеЗаписи.Дескриптор, Немедленно);

КонецЦикла;

КонецЕсли;

КонецПроцедуры

// Восстанавливает все права пользователя, которые у него были до

// пометки на удаление или установки признака "Недействителен"

Процедура ВосстановитьПраваПользователя(Пользователь, Немедленно = Ложь) Экспорт

// По группе доступа

Запрос = Новый Запрос("ВЫБРАТЬ

| ГруппыДоступаПользователи.Ссылка КАК ГруппаДоступа

|ИЗ

| Справочник.ГруппыДоступа.Пользователи КАК ГруппыДоступаПользователи

|ГДЕ

| ГруппыДоступаПользователи.Пользователь = &Пользователь");

Запрос.УстановитьПараметр("Пользователь", Пользователь);

Выборка = Запрос.Выполнить().Выбрать();

Пока Выборка.Следующий() Цикл

ОбновитьПраваЗависящиеОтГруппыДоступа(Выборка.ГруппаДоступа);

КонецЦикла;

// По группе пользователей

Запрос = Новый Запрос("ВЫБРАТЬ

| ГруппыПользователейСостав.Ссылка КАК ГруппаПользователей

|ИЗ

| Справочник.ГруппыПользователей.Состав КАК ГруппыПользователейСостав

|ГДЕ

| ГруппыПользователейСостав.Пользователь = &Пользователь");

Запрос.УстановитьПараметр("Пользователь", Пользователь);

Выборка = Запрос.Выполнить().Выбрать();

Пока Выборка.Следующий() Цикл

ОбновитьПраваОбъектовЗависящихОтГруппыПользователей(Выборка.ГруппаПользователей);

КонецЦикла;

// По рабочей группе дескриптора

Запрос = Новый Запрос("ВЫБРАТЬ

| ДескрипторыДоступаОбъектовРабочаяГруппа.Ссылка КАК Дескриптор

|ИЗ

| Справочник.ДескрипторыДоступаОбъектов.РабочаяГруппа КАК ДескрипторыДоступаОбъектовРабочаяГруппа

|ГДЕ

| ДескрипторыДоступаОбъектовРабочаяГруппа.Участник = &Пользователь");

Запрос.УстановитьПараметр("Пользователь", Пользователь);

Выборка = Запрос.Выполнить().Выбрать();

Пока Выборка.Следующий() Цикл

ОбновитьПраваДоступаПоДескриптору(Выборка.Дескриптор, Немедленно);

КонецЦикла;

// По пользователям дескриптора

Запрос = Новый Запрос("ВЫБРАТЬ

| ДескрипторыДоступаОбъектовПользователи.Ссылка КАК Дескриптор

|ИЗ

| Справочник.ДескрипторыДоступаОбъектов.Пользователи КАК ДескрипторыДоступаОбъектовПользователи

|ГДЕ

| ДескрипторыДоступаОбъектовПользователи.Пользователь = &Пользователь");

Запрос.УстановитьПараметр("Пользователь", Пользователь);

Выборка = Запрос.Выполнить().Выбрать();

Пока Выборка.Следующий() Цикл

ОбновитьПраваДоступаПоДескриптору(Выборка.Дескриптор, Немедленно);

КонецЦикла;

// По роли исполнителя в дескрипторе

Запрос = Новый Запрос("ВЫБРАТЬ

| ДескрипторыДоступаОбъектовПользователи.Ссылка КАК Дескриптор

|ИЗ

| РегистрСведений.ИсполнителиЗадач КАК ИсполнителиЗадач

| ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.ДескрипторыДоступаОбъектов.Пользователи КАК ДескрипторыДоступаОбъектовПользователи

| ПО ИсполнителиЗадач.РольИсполнителя = ДескрипторыДоступаОбъектовПользователи.Пользователь

| И ИсполнителиЗадач.ОсновнойОбъектАдресации = ДескрипторыДоступаОбъектовПользователи.ОсновнойОбъектАдресации

| И ИсполнителиЗадач.ДополнительныйОбъектАдресации = ДескрипторыДоступаОбъектовПользователи.ДополнительныйОбъектАдресации

|ГДЕ

| ИсполнителиЗадач.Исполнитель = &Пользователь

|

|ОБЪЕДИНИТЬ ВСЕ

|

|ВЫБРАТЬ

| ДескрипторыДоступаОбъектовРабочаяГруппа.Ссылка

|ИЗ

| РегистрСведений.ИсполнителиЗадач КАК ИсполнителиЗадач

| ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.ДескрипторыДоступаОбъектов.РабочаяГруппа КАК ДескрипторыДоступаОбъектовРабочаяГруппа

| ПО ИсполнителиЗадач.ОсновнойОбъектАдресации = ДескрипторыДоступаОбъектовРабочаяГруппа.ОсновнойОбъектАдресации

| И ИсполнителиЗадач.ДополнительныйОбъектАдресации = ДескрипторыДоступаОбъектовРабочаяГруппа.ДополнительныйОбъектАдресации

|ГДЕ

| ИсполнителиЗадач.Исполнитель = &Пользователь");

Запрос.УстановитьПараметр("Пользователь", Пользователь);

Выборка = Запрос.Выполнить().Выбрать();

Пока Выборка.Следующий() Цикл

ОбновитьПраваДоступаПоДескриптору(Выборка.Дескриптор, Немедленно);

КонецЦикла;

// Права папок

Запрос = Новый Запрос("ВЫБРАТЬ РАЗЛИЧНЫЕ

| НастройкиПравОбъектов.Объект

|ИЗ

| РегистрСведений.НастройкиПравОбъектов КАК НастройкиПравОбъектов

|ГДЕ

| НастройкиПравОбъектов.Пользователь = &Пользователь");

Запрос.УстановитьПараметр("Пользователь", Пользователь);

Выборка = Запрос.Выполнить().Выбрать();

Пока Выборка.Следующий() Цикл

ОбновитьПраваПапки(Выборка.Объект);

КонецЦикла;

КонецПроцедуры

// Заполняет ТЧ дескриптора НастройкаПрав по настройкам папки

Процедура ЗаполнитьНастройкиДескриптора(ДескрипторДоступа, Папка) Экспорт

// Собственные права папки

Запрос = Новый Запрос("ВЫБРАТЬ

| НастройкиПравОбъектов.Пользователь КАК Пользователь,

| НастройкиПравОбъектов.Право КАК Право,

| НастройкиПравОбъектов.ПравоЗапрещено КАК ПравоЗапрещено,

| НаследованиеНастроекПравОбъектов.Наследовать

|ИЗ

| РегистрСведений.НаследованиеНастроекПравОбъектов КАК НаследованиеНастроекПравОбъектов

| ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.НастройкиПравОбъектов КАК НастройкиПравОбъектов

| ПО НастройкиПравОбъектов.Объект = НаследованиеНастроекПравОбъектов.Родитель

|ГДЕ

| НаследованиеНастроекПравОбъектов.Объект = &Объект

| И НаследованиеНастроекПравОбъектов.Родитель = &Объект");

Запрос.УстановитьПараметр("Объект", Папка.Ссылка);

Результат = Запрос.Выполнить();

Наследовать = Истина;

Если Не Результат.Пустой() Тогда

ТаблицаПрав = Результат.Выгрузить();

Наследовать = ТаблицаПрав[0].Наследовать;

Если ЗначениеЗаполнено(ТаблицаПрав[0].Право) Тогда

ДескрипторДоступа.НастройкаПрав.Загрузить(ТаблицаПрав);

КонецЕсли;

Иначе

ДескрипторДоступа.НастройкаПрав.Очистить();

КонецЕсли;

// Наследуемые права

Если Наследовать Тогда

Запрос.Текст = "ВЫБРАТЬ

| НастройкиПравОбъектов.Пользователь,

| НастройкиПравОбъектов.Право,

| НастройкиПравОбъектов.ПравоЗапрещено

|ИЗ

| РегистрСведений.НастройкиПравОбъектов КАК НастройкиПравОбъектов

| ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.НаследованиеНастроекПравОбъектов КАК НаследованиеНастроекПравОбъектов

| ПО НастройкиПравОбъектов.Объект = НаследованиеНастроекПравОбъектов.Родитель

|ГДЕ

| НаследованиеНастроекПравОбъектов.Объект = &Объект

| И НаследованиеНастроекПравОбъектов.Родитель <> &Объект

| И НастройкиПравОбъектов.НаследованиеРазрешено

|

|УПОРЯДОЧИТЬ ПО

| Пользователь,

| Право";

Выборка = Запрос.Выполнить().Выбрать();

Пока Выборка.Следующий() Цикл

ЗаполнитьЗначенияСвойств(ДескрипторДоступа.НастройкаПрав.Добавить(), Выборка);

КонецЦикла;

КонецЕсли;

КонецПроцедуры

// Включает регл. задание обработки оперативной очереди

Процедура ВключитьОбработкуОперативнойОчереди() Экспорт

Задание = РегламентныеЗадания.НайтиПредопределенное("ДокументооборотОбновлениеПравДоступаОперативное");

Задание.Использование = Истина;

Задание.Записать();

КонецПроцедуры

// Включает регл. задание обработки долгой очереди

Процедура ВключитьОбработкуДолгойОчереди() Экспорт

Задание = РегламентныеЗадания.НайтиПредопределенное("ДокументооборотОбновлениеПравДоступаДолгое");

Задание.Использование = Истина;

Задание.Записать();

КонецПроцедуры

// Останавливает регл. задание обработки оперативной очереди

// Возвращаемое значение:

// Истина, если регл. задание было активно

// Ложь, если регл. задание уже было отключено

Функция ОтключитьОбработкуОперативнойОчереди(ТолькоФоновоеЗадание = Ложь) Экспорт

// Отключение регл. задания

Задание = РегламентныеЗадания.НайтиПредопределенное("ДокументооборотОбновлениеПравДоступаОперативное");

ЗаданиеАктивно = Задание.Использование;

Если Не ТолькоФоновоеЗадание И ЗаданиеАктивно Тогда

Задание.Использование = Ложь;

Задание.Записать();

КонецЕсли;

// Остановка фонового задания

Попытка

ИДЗадания = Задание.УникальныйИдентификатор;

Свойства = РегламентныеЗаданияСервер.ПолучитьСвойстваПоследнегоФоновогоЗаданияВыполненияРегламентногоЗадания(Задание);

РегламентныеЗаданияСервер.ОтменитьФоновоеЗадание(Свойства.Идентификатор);

Исключение

КонецПопытки;

Возврат ЗаданиеАктивно;

КонецФункции

// Останавливает регл. задание обработки долгой очереди

// Возвращаемое значение:

// Истина, если регл. задание было активно

// Ложь, если регл. задание уже было отключено

Функция ОтключитьОбработкуДолгойОчереди(ТолькоФоновоеЗадание = Ложь) Экспорт

// Отключение регл. задания

Задание = РегламентныеЗадания.НайтиПредопределенное("ДокументооборотОбновлениеПравДоступаДолгое");

ЗаданиеАктивно = Задание.Использование;

Если ЗаданиеАктивно Тогда

Если Не ТолькоФоновоеЗадание Тогда

Задание.Использование = Ложь;

Задание.Записать();

КонецЕсли;

// Остановка фонового задания

Попытка

ИДЗадания = Задание.УникальныйИдентификатор;

Свойства = РегламентныеЗаданияСервер.ПолучитьСвойстваПоследнегоФоновогоЗаданияВыполненияРегламентногоЗадания(Задание);

РегламентныеЗаданияСервер.ОтменитьФоновоеЗадание(Свойства.Идентификатор);

Исключение

КонецПопытки;

КонецЕсли;

Возврат ЗаданиеАктивно;

КонецФункции

// Добавляет к переданной стуктуре прав права, не ограниченные на уровне записей

Процедура РасширитьДоступПравамиБезОграничения(Права, ОбъектДоступа, Пользователь = Неопределено) Экспорт

УстановитьПривилегированныйРежим(Истина);

Если Не ЗначениеЗаполнено(Пользователь) Тогда

Пользователь = ОбщегоНазначения.ТекущийПользователь();

КонецЕсли;

// Проверка прав, не ограниченных на уровне записей

Запрос = Новый Запрос;

Запрос.Текст = "ВЫБРАТЬ

| МАКСИМУМ(ПраваГруппДоступаНаТаблицы.ЧтениеБезОграничения) КАК Чтение,

| МАКСИМУМ(ПраваГруппДоступаНаТаблицы.ДобавлениеБезОграничения) КАК Добавление,

| МАКСИМУМ(ПраваГруппДоступаНаТаблицы.ИзменениеБезОграничения) КАК Изменение,

| МАКСИМУМ(ПраваГруппДоступаНаТаблицы.УдалениеБезОграничения) КАК Удаление,

| МАКСИМУМ(ПраваГруппДоступаНаТаблицы.ПраваБезОграничения) КАК УправлениеПравами

|ИЗ

| РегистрСведений.ПраваГруппДоступаНаТаблицы КАК ПраваГруппДоступаНаТаблицы

| ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.ГруппыДоступа.Пользователи КАК ГруппыДоступаПользователи

| ПО ПраваГруппДоступаНаТаблицы.ГруппаДоступа = ГруппыДоступаПользователи.Ссылка

|ГДЕ

| ПраваГруппДоступаНаТаблицы.Таблица.ЗначениеПустойСсылки = &ПустаяСсылка

| И ГруппыДоступаПользователи.Пользователь = &Пользователь

|

|ИМЕЮЩИЕ

| (МАКСИМУМ(ПраваГруппДоступаНаТаблицы.ЧтениеБезОграничения) = ИСТИНА

| ИЛИ МАКСИМУМ(ПраваГруппДоступаНаТаблицы.ДобавлениеБезОграничения) = ИСТИНА

| ИЛИ МАКСИМУМ(ПраваГруппДоступаНаТаблицы.ИзменениеБезОграничения) = ИСТИНА

| ИЛИ МАКСИМУМ(ПраваГруппДоступаНаТаблицы.УдалениеБезОграничения) = ИСТИНА

| ИЛИ МАКСИМУМ(ПраваГруппДоступаНаТаблицы.ПраваБезОграничения) = ИСТИНА)";

Запрос.УстановитьПараметр("ПустаяСсылка", Новый(ТипЗнч(ОбъектДоступа.Ссылка)));

Запрос.УстановитьПараметр("Пользователь", Пользователь);

Результат = Запрос.Выполнить();

Если Не Результат.Пустой() Тогда

ВыборкаПравБезОграничений = Результат.Выбрать();

ВыборкаПравБезОграничений.Следующий();

Права.Чтение = Права.Чтение или ВыборкаПравБезОграничений.Чтение;

Права.Изменение = Права.Изменение или ВыборкаПравБезОграничений.Изменение;

Права.Удаление = Права.Удаление или ВыборкаПравБезОграничений.Удаление;

Права.УправлениеПравами = Права.УправлениеПравами или ВыборкаПравБезОграничений.УправлениеПравами;

// Добавление без ограничений проверяется вместе с изменением, т.к. тут может

// не быть ограничений РЛС даже если они подразумеваются

Права.Добавление = Права.Добавление или

ВыборкаПравБезОграничений.Добавление и ВыборкаПравБезОграничений.Изменение;

КонецЕсли;

КонецПроцедуры

////////////////////////////////////////////////////////////////////////////////

// Обработчики подписок и регламентных заданий

// Обработчик подписки ДокументооборотПраваДоступаПередЗаписьюОбъектаДоступа

Процедура ДокументооборотПраваДоступаПередЗаписьюОбъектаДоступа(Источник, Отказ) Экспорт

Если Не ДокументооборотПраваДоступаПовтИсп.ВключеноИспользованиеПравДоступа() Тогда

Возврат;

КонецЕсли;

// Сохранение признака ЭтоНовый для использования в обработчике события ПриЗаписи

Источник.ДополнительныеСвойства.Вставить("ЭтоНовый", Источник.ЭтоНовый());

// Сохранение старого дескриптора доступа для обнаружения того, что дескриптор изменен

Если Не Источник.ЭтоНовый() Тогда

СтарыйДескриптор = РегистрыСведений.ДескрипторыДоступаДляОбъектов.НайтиДескрипторДляОбъекта(Источник.Ссылка);

Источник.ДополнительныеСвойства.Вставить("СтарыйДескриптор", СтарыйДескриптор);

КонецЕсли;

КонецПроцедуры

// Обработчик подписки ДокументооборотПраваДоступаПередЗаписьюДокумента

Процедура ДокументооборотПраваДоступаПередЗаписьюДокумента(Источник, Отказ, РежимЗаписи, РежимПроведения) Экспорт

Если Не ДокументооборотПраваДоступаПовтИсп.ВключеноИспользованиеПравДоступа() Тогда

Возврат;

КонецЕсли;

// Сохранение признака ЭтоНовый для использования в обработчике события ПриЗаписи

Источник.ДополнительныеСвойства.Вставить("ЭтоНовый", Источник.ЭтоНовый());

КонецПроцедуры

// Обработчик подписки ДокументооборотПраваДоступаПриЗаписиОбъектаДоступа

Процедура ДокументооборотПраваДоступаПриЗаписиОбъектаДоступа(Источник, Отказ) Экспорт

Если Не ДокументооборотПраваДоступаПовтИсп.ВключеноИспользованиеПравДоступа() Тогда

Возврат;

КонецЕсли;

НеобходимаПроверкаПравПоДескриптору = Не ПривилегированныйРежим() И Не РольДоступна("ПолныеПрава");

Дескриптор = ОпределитьДескрипторДоступаОбъекта(

Источник,

НеобходимаПроверкаПравПоДескриптору); // Немедленно

// Проверка права добавления

Если НеобходимаПроверкаПравПоДескриптору Тогда

Права = РегистрыСведений.ПраваПоДескрипторамДоступа.ПолучитьПраваПоДескриптору(Дескриптор);

РасширитьДоступПравамиБезОграничения(Права, Источник.Ссылка);

НетПрав = Ложь;

Если Источник.ДополнительныеСвойства.ЭтоНовый Тогда

// Для новых объектов проверяется право добавления

Если Не Права.Добавление Тогда

НетПрав = Истина;

КонецЕсли;

Иначе

// Для существующих объектов проверяется право изменения

Если Не Права.Изменение Тогда

НетПрав = Истина;

КонецЕсли;

КонецЕсли;

Если НетПрав Тогда

ВызватьИсключение НСтр("ru = 'Недостаточно прав для выполнения операции.

|Обратитесь к администратору.'");

КонецЕсли;

КонецЕсли;

// Проверка на изменение дескриптора

Если Источник.ДополнительныеСвойства.Свойство("СтарыйДескриптор") Тогда

// Если дескприптор поменялся, то обновляются права всех данных,

// которые зависят от этого объекта

Если Источник.ДополнительныеСвойства.СтарыйДескриптор <> Дескриптор Тогда

ОбновитьПраваЗависимыхДанных(Источник.Ссылка);

КонецЕсли;

КонецЕсли;

КонецПроцедуры

// Обработчик подписки ДокументооборотПраваДоступаПередЗаписьюФайла

Процедура ДокументооборотПраваДоступаПередЗаписьюФайла(Источник, Отказ) Экспорт

Если Не ДокументооборотПраваДоступаПовтИсп.ВключеноИспользованиеПравДоступа() Тогда

Возврат;

КонецЕсли;

Дескриптор = ПолучитьДескрипторДоступаФайла(

Источник.ВладелецФайла,

Истина);

// Проверка права добавления

Если Не ПривилегированныйРежим() И Не РольДоступна("ПолныеПрава") Тогда

Если Источник.ЭтоНовый() Тогда

Права = РегистрыСведений.ПраваПоДескрипторамДоступа.ПолучитьПраваПоДескриптору(Дескриптор);

РасширитьДоступПравамиБезОграничения(Права, Источник.Ссылка);

Если Не Права.Добавление Тогда

ВызватьИсключение НСтр("ru = 'Недостаточно прав для выполнения операции.

|Обратитесь к администратору.'");

КонецЕсли;

КонецЕсли;

КонецЕсли;

КонецПроцедуры

// Обработчик подписки ДокументооборотПраваДоступаПередЗаписьюНабораЗаписей

Процедура ДокументооборотПраваДоступаПередЗаписьюНабораЗаписей(Источник, Отказ, Замещение) Экспорт

Если Не ДокументооборотПраваДоступаПовтИсп.ВключеноИспользованиеПравДоступа() Тогда

Возврат;

КонецЕсли;

ОпределитьДескрипторДоступаНабораЗаписей(

Источник,

Истина); // Немедленно

КонецПроцедуры

// Обработчик подписки ДокументооборотПередЗаписьюПравообразующихОбъектов

Процедура ДокументооборотПередЗаписьюПравообразующихОбъектов(Источник, Отказ) Экспорт

УстановитьПривилегированныйРежим(Истина);

Если Не ДокументооборотПраваДоступаПовтИсп.ВключеноИспользованиеПравДоступа() Тогда

Возврат;

КонецЕсли;

Если ДокументооборотПраваДоступаПереопределяемый.ДокументооборотПередЗаписьюПравообразующихОбъектов(Источник, Отказ) Тогда

Возврат;

КонецЕсли;

// Проверка на то, что изменились правообразующие реквизиты

Если ТипЗнч(Источник) = Тип("СправочникОбъект.ГруппыПользователей") Тогда

СтарыйСостав = Источник.Ссылка.Состав;

Если Источник.ЭтоНовый() Тогда

Источник.ДополнительныеСвойства.Вставить("ЗначениеИзменено", Истина);

ИначеЕсли Источник.Родитель <> Источник.Ссылка.Родитель Тогда

Источник.ДополнительныеСвойства.Вставить("ЗначениеИзменено", Истина);

Источник.ДополнительныеСвойства.Вставить("СтарыйРодитель", Источник.Ссылка.Родитель);

ИначеЕсли Источник.Состав.Количество() <> СтарыйСостав.Количество() Тогда

Источник.ДополнительныеСвойства.Вставить("ЗначениеИзменено", Истина);

Иначе

// Поэлементное сравнение

ЗначениеИзменено = Ложь;

Для Сч = 0 По СтарыйСостав.Количество() - 1 Цикл

Если СтарыйСостав[Сч].Пользователь <> Источник.Состав[Сч].Пользователь Тогда

ЗначениеИзменено = Истина;

Прервать;

КонецЕсли;

КонецЦикла;

Если ЗначениеИзменено Тогда

Источник.ДополнительныеСвойства.Вставить("ЗначениеИзменено", Истина);

КонецЕсли;

КонецЕсли;

ИначеЕсли ТипЗнч(Источник) = Тип("СправочникОбъект.ГруппыДоступа") Тогда

Если Не Источник.ЭтоГруппа Тогда

Источник.ДополнительныеСвойства.Вставить("ЗначениеИзменено", Истина);

Если Не Источник.ЭтоНовый() Тогда

ЗначенияДоступа = ПолучитьЗначенияДоступаГруппыДоступа(Источник.Ссылка);

Источник.ДополнительныеСвойства.Вставить("СтарыеЗначенияДоступа", ЗначенияДоступа);

Источник.ДополнительныеСвойства.Вставить("СтарыйПрофиль", Источник.Ссылка.Профиль);

Источник.ДополнительныеСвойства.Вставить("СтарыйСостав", Источник.Ссылка.Пользователи);

КонецЕсли;

КонецЕсли;

ИначеЕсли ТипЗнч(Источник) = Тип("СправочникОбъект.Пользователи") Тогда

Источник.ДополнительныеСвойства.Вставить("ЭтоНовый", Источник.ЭтоНовый());

Источник.ДополнительныеСвойства.Вставить("ЗначениеИзменено", Истина);

Источник.ДополнительныеСвойства.Вставить("ИзмененаПометкаУдаления",

Источник.ПометкаУдаления <> Источник.Ссылка.ПометкаУдаления);

Источник.ДополнительныеСвойства.Вставить("ИзмененПризнакДействительности",

Источник.Недействителен <> Источник.Ссылка.Недействителен);

ИначеЕсли ТипЗнч(Источник) = Тип("СправочникОбъект.ПапкиФайлов")

ИЛИ ТипЗнч(Источник) = Тип("СправочникОбъект.ПапкиВнутреннихДокументов") Тогда

Если Источник.Родитель <> Источник.Ссылка.Родитель Тогда

Источник.ДополнительныеСвойства.Вставить("ЗначениеИзменено", Истина);

КонецЕсли;

ИначеЕсли ТипЗнч(Источник) = Тип("СправочникОбъект.СтруктураАдминистрации") Тогда

Если Источник.Родитель <> Источник.Ссылка.Родитель

ИЛИ Источник.Руководитель <> Источник.Ссылка.Руководитель Тогда

Источник.ДополнительныеСвойства.Вставить("ЗначениеИзменено", Истина);

КонецЕсли;

ИначеЕсли ТипЗнч(Источник) = Тип("СправочникОбъект.ПрофилиГруппДоступа") Тогда

СтарыеРоли = Источник.Ссылка.Роли;

СтарыеВидыДоступа = Источник.Ссылка.ВидыДоступа;

СтарыеЗначенияДоступа = Источник.Ссылка.ЗначенияДоступа;

Если Источник.Роли.Количество() <> СтарыеРоли.Количество()

Или Источник.ВидыДоступа.Количество() <> СтарыеВидыДоступа.Количество()

Или Источник.ЗначенияДоступа.Количество() <> СтарыеЗначенияДоступа.Количество() Тогда

Источник.ДополнительныеСвойства.Вставить("ЗначениеИзменено", Истина);

Иначе

// Поэлементное сравнение

ЗначениеИзменено = Ложь;

Для Сч = 0 По СтарыеРоли.Количество() - 1 Цикл

Если СтарыеРоли[Сч].Роль <> Источник.Роли[Сч].Роль Тогда

ЗначениеИзменено = Истина;

Прервать;

КонецЕсли;

КонецЦикла;

Если ЗначениеИзменено Тогда

Источник.ДополнительныеСвойства.Вставить("ЗначениеИзменено", Истина);

КонецЕсли;

Если Не ЗначениеИзменено Тогда

Для Сч = 0 По СтарыеВидыДоступа.Количество() - 1 Цикл

Если СтарыеВидыДоступа[Сч].ВидДоступа <> Источник.ВидыДоступа[Сч].ВидДоступа

Или СтарыеВидыДоступа[Сч].ДоступРазрешен <> Источник.ВидыДоступа[Сч].ДоступРазрешен Тогда

ЗначениеИзменено = Истина;

Прервать;

КонецЕсли;

КонецЦикла;

Если ЗначениеИзменено Тогда

Источник.ДополнительныеСвойства.Вставить("ЗначениеИзменено", Истина);

КонецЕсли;

КонецЕсли;

Если Не ЗначениеИзменено Тогда

Для Сч = 0 По СтарыеЗначенияДоступа.Количество() - 1 Цикл

Если СтарыеЗначенияДоступа[Сч].ВидДоступа <> Источник.ЗначенияДоступа[Сч].ВидДоступа

Или СтарыеЗначенияДоступа[Сч].ЗначениеДоступа <> Источник.ЗначенияДоступа[Сч].ЗначениеДоступа Тогда

ЗначениеИзменено = Истина;

Прервать;

КонецЕсли;

КонецЦикла;

Если ЗначениеИзменено Тогда

Источник.ДополнительныеСвойства.Вставить("ЗначениеИзменено", Истина);

КонецЕсли;

КонецЕсли;

КонецЕсли;

КонецЕсли;

КонецПроцедуры

// Обработчик подписки ДокументооборотПриЗаписиПравообразующихОбъектов

Процедура ДокументооборотПриЗаписиПравообразующихОбъектов(Источник, Отказ) Экспорт

УстановитьПривилегированныйРежим(Истина);

Если Не ДокументооборотПраваДоступаПовтИсп.ВключеноИспользованиеПравДоступа() Тогда

Возврат;

КонецЕсли;

// Проверка на то, что правообразующие свойства источника были изменены

Если НЕ Источник.ДополнительныеСвойства.Свойство("ЗначениеИзменено")

Или НЕ Источник.ДополнительныеСвойства.ЗначениеИзменено Тогда

Возврат;

КонецЕсли;

// Обработка источников разных типов

Если ДокументооборотПраваДоступаПереопределяемый.ДокументооборотПриЗаписиПравообразующихОбъектов(Источник, Отказ) Тогда

Возврат;

КонецЕсли;

ТипИсточника = ТипЗнч(Источник);

Если ТипИсточника = Тип("СправочникОбъект.ГруппыПользователей") Тогда

// Перезагрузка регл. заданий - для корректной работы функций повторного использования

ОтключитьОбработкуОперативнойОчереди(Истина);

ОтключитьОбработкуДолгойОчереди(Истина);

ТекущийПриоритетОчередиОбновленияПрав = ПараметрыСеанса.ПриоритетОчередиОбновленияПрав;

ПараметрыСеанса.ПриоритетОчередиОбновленияПрав = 2; // Долгая очередь

Попытка

Если Источник.ДополнительныеСвойства.Свойство("СтарыйРодитель") Тогда

ОбновитьПраваОбъектовЗависящихОтГруппыПользователей(Источник.ДополнительныеСвойства.СтарыйРодитель);

КонецЕсли;

ОбновитьПраваОбъектовЗависящихОтГруппыПользователей(Источник.Ссылка);

ПараметрыСеанса.ПриоритетОчередиОбновленияПрав = ТекущийПриоритетОчередиОбновленияПрав;

Исключение

ПараметрыСеанса.ПриоритетОчередиОбновленияПрав = ТекущийПриоритетОчередиОбновленияПрав;

ВызватьИсключение;

КонецПопытки;

ИначеЕсли ТипИсточника = Тип("СправочникОбъект.Пользователи") Тогда

Если Источник.ДополнительныеСвойства.ЭтоНовый Тогда

ТекущийПриоритетОчередиОбновленияПрав = ПараметрыСеанса.ПриоритетОчередиОбновленияПрав;

ПараметрыСеанса.ПриоритетОчередиОбновленияПрав = 2; // Долгая очередь

Попытка

// При добавлении нового пользователя неявно меняется состав

// предопределенной виртуальной группы "Все пользователи"

ОбновитьПраваОбъектовЗависящихОтГруппыПользователей(

Справочники.ГруппыПользователей.ВсеПользователи);

// Обновление пустых дескрипторов, которые дают разрешения всем пользователям

ОбновитьПраваПустыхДескрипторов();

ПараметрыСеанса.ПриоритетОчередиОбновленияПрав = ТекущийПриоритетОчередиОбновленияПрав;

Исключение

ПараметрыСеанса.ПриоритетОчередиОбновленияПрав = ТекущийПриоритетОчередиОбновленияПрав;

ВызватьИсключение;

КонецПопытки;

// Изменена пометка на удаление или признак "Недействителен"

ИначеЕсли Источник.ДополнительныеСвойства.ИзмененаПометкаУдаления

Или Источник.ДополнительныеСвойства.ИзмененПризнакДействительности Тогда

Немедленно = Не ДокументооборотПраваДоступаПовтИсп.ОтложенноеОбновлениеПравДоступа();

Если Источник.ПометкаУдаления Или Источник.Недействителен Тогда

ОбновитьПраваПоПользователю(Источник.Ссылка, Немедленно);

Иначе

ВосстановитьПраваПользователя(Источник.Ссылка, Немедленно);

КонецЕсли;

КонецЕсли;

ИначеЕсли ТипИсточника = Тип("СправочникОбъект.ГруппыДоступа") Тогда

Если Источник.ЭтоГруппа Тогда

Возврат;

КонецЕсли;

// Отключение регл. заданий для корректной работы функций повторного использования

ОтключитьОбработкуОперативнойОчереди(Истина);

ОтключитьОбработкуДолгойОчереди(Истина);

// Обновление сведений о составе групп доступа

РегистрыСведений.ДокументооборотПользователиГруппДоступа.ОбновитьПоГруппеДоступа(Источник.Ссылка);

Если Источник.ЭтоНовый() Тогда

Источник.ДополнительныеСвойства.Вставить("ЗначениеИзменено", Истина);

Иначе

СтарыеЗначенияДоступа = Новый Массив;

Если Источник.ДополнительныеСвойства.Свойство("СтарыеЗначенияДоступа") Тогда

СтарыеЗначенияДоступа = Источник.ДополнительныеСвойства.СтарыеЗначенияДоступа;

КонецЕсли;

СтарыйПрофиль = Неопределено;

Если Источник.ДополнительныеСвойства.Свойство("СтарыйПрофиль") Тогда

СтарыйПрофиль = Источник.ДополнительныеСвойства.СтарыйПрофиль;

КонецЕсли;

СтарыйСостав = Неопределено;

Если Источник.ДополнительныеСвойства.Свойство("СтарыйСостав") Тогда

СтарыйСостав = Источник.ДополнительныеСвойства.СтарыйСостав;

КонецЕсли;

ЗначенияДоступаДляОбработки = Новый Массив;

ПолныйПересчет = Ложь;

// Проверка изменения профиля группы доступа

Если СтарыйПрофиль <> Источник.Профиль Тогда

ПолныйПересчет = Истина;

КонецЕсли;

// Проверка изменения состава участников

Если СтарыйСостав = Неопределено

Или СтарыйСостав.Количество() <> Источник.Пользователи.Количество() Тогда

ПолныйПересчет = Истина;

Иначе

// Поэлементное сравнение старых и новых пользователей группы

Для Сч = 0 По СтарыйСостав.Количество() - 1 Цикл

Если СтарыйСостав[Сч].Пользователь <> Источник.Пользователи[Сч].Пользователь Тогда

ПолныйПересчет = Истина;

Прервать;

КонецЕсли;

КонецЦикла;

КонецЕсли;

НовыеЗначенияДоступа = ПолучитьЗначенияДоступаГруппыДоступа(Источник.Ссылка);

// Добавление новых значений доступа

Для каждого Эл Из НовыеЗначенияДоступа Цикл

ЗначенияДоступаДляОбработки.Добавить(Эл);

КонецЦикла;

Если ПолныйПересчет Тогда

// Добавление старых значений доступа

Для каждого Эл Из СтарыеЗначенияДоступа Цикл

ЗначенияДоступаДляОбработки.Добавить(Эл);

КонецЦикла;

КонецЕсли;

// Обновление отобранных значений доступа

ТекущийПриоритетОчередиОбновленияПрав = ПараметрыСеанса.ПриоритетОчередиОбновленияПрав;

ПараметрыСеанса.ПриоритетОчередиОбновленияПрав = 2; // Долгая очередь

Попытка

ОбновитьПраваПоЗначениямВидовДоступа(ЗначенияДоступаДляОбработки);

ПараметрыСеанса.ПриоритетОчередиОбновленияПрав = ТекущийПриоритетОчередиОбновленияПрав;

Исключение

ПараметрыСеанса.ПриоритетОчередиОбновленияПрав = ТекущийПриоритетОчередиОбновленияПрав;

ВызватьИсключение;

КонецПопытки;

КонецЕсли;

ИначеЕсли ТипИсточника = Тип("СправочникОбъект.ПапкиФайлов")

ИЛИ ТипИсточника = Тип("СправочникОбъект.ПапкиВнутреннихДокументов") Тогда

ОбновитьПраваДескрипторовЗависящихОтПапки(Источник.Ссылка);

ИначеЕсли ТипИсточника = Тип("СправочникОбъект.СтруктураАдминистрации") Тогда

ТекущийПриоритетОчередиОбновленияПрав = ПараметрыСеанса.ПриоритетОчередиОбновленияПрав;

ПараметрыСеанса.ПриоритетОчередиОбновленияПрав = 2; // Долгая очередь

Попытка

ОбновитьПраваПоПодразделению(Источник.Ссылка);

ПараметрыСеанса.ПриоритетОчередиОбновленияПрав = ТекущийПриоритетОчередиОбновленияПрав;

Исключение

ПараметрыСеанса.ПриоритетОчередиОбновленияПрав = ТекущийПриоритетОчередиОбновленияПрав;

ВызватьИсключение;

КонецПопытки;

ИначеЕсли ТипИсточника = Тип("СправочникОбъект.ПрофилиГруппДоступа") Тогда

Если Не Источник.ЭтоНовый() Тогда

ОбновитьПраваДескрипторовЗависящихОтПрофиля(Источник.Ссылка);

КонецЕсли;

КонецЕсли;

КонецПроцедуры

// Обработчик подписки ДокументооборотПередЗаписьюПравообразующихРегистров

Процедура ДокументооборотПередЗаписьюПравообразующихРегистров(Источник, Отказ, Замещение) Экспорт

УстановитьПривилегированныйРежим(Истина);

Если Не ДокументооборотПраваДоступаПовтИсп.ВключеноИспользованиеПравДоступа() Тогда

Возврат;

КонецЕсли;

Если ТипЗнч(Источник) = Тип("РегистрСведенийНаборЗаписей.СведенияОПользователях") Тогда

// Проверка изменения подразделения пользователя

Пользователь = Источник.Отбор.Пользователь.Значение;

СведенияОПользователе =

РегистрыСведений.СведенияОПользователях.ПолучитьСведенияОПользователе(Пользователь);

Если Источник.Количество() <> 0 Тогда

Для каждого Эл Из Источник Цикл

Если Не СведенияОПользователе.Свойство("Подразделение") Тогда

Источник.ДополнительныеСвойства.Вставить("СтароеПодразделение", Неопределено);

Иначе

Если Эл.Подразделение <> СведенияОПользователе.Подразделение Тогда

Источник.ДополнительныеСвойства.Вставить("СтароеПодразделение", СведенияОПользователе.Подразделение);

Прервать;

КонецЕсли;

КонецЕсли;

КонецЦикла;

Иначе

Если Не СведенияОПользователе.Свойство("Подразделение") Тогда

Источник.ДополнительныеСвойства.Вставить("СтароеПодразделение", Неопределено);

Иначе

Источник.ДополнительныеСвойства.Вставить("СтароеПодразделение", СведенияОПользователе.Подразделение);

КонецЕсли;

КонецЕсли;

КонецЕсли;

КонецПроцедуры

// Обработчик подписки ДокументооборотПриЗаписиПравообразующихРегистров

Процедура ДокументооборотПриЗаписиПравообразующихРегистров(Источник, Отказ, Замещение) Экспорт

УстановитьПривилегированныйРежим(Истина);

Если Не ДокументооборотПраваДоступаПовтИсп.ВключеноИспользованиеПравДоступа() Тогда

Возврат;

КонецЕсли;

Если ДокументооборотПраваДоступаПереопределяемый.ДокументооборотПриЗаписиПравообразующихРегистров(Источник, Отказ) Тогда

Возврат;

КонецЕсли;

Если ТипЗнч(Источник) = Тип("РегистрСведенийНаборЗаписей.ДескрипторыДоступаДляОбъектов") Тогда

// Обработка изменения владельца файла

Для каждого Эл Из Источник Цикл

ОбновитьПраваСвязанныхДескрипторовПоОбъекту(Эл.Объект);

КонецЦикла;

ИначеЕсли ТипЗнч(Источник) = Тип("РегистрСведенийНаборЗаписей.ИсполнителиЗадач") Тогда

ТекущийПриоритетОчередиОбновленияПрав = ПараметрыСеанса.ПриоритетОчередиОбновленияПрав;

ПараметрыСеанса.ПриоритетОчередиОбновленияПрав = 2; // Долгая очередь

Попытка

ПриЗаписиИсполнителейЗадач(Источник);

ПараметрыСеанса.ПриоритетОчередиОбновленияПрав = ТекущийПриоритетОчередиОбновленияПрав;

Исключение

ПараметрыСеанса.ПриоритетОчередиОбновленияПрав = ТекущийПриоритетОчередиОбновленияПрав;

ВызватьИсключение;

КонецПопытки;

ИначеЕсли ТипЗнч(Источник) = Тип("РегистрСведенийНаборЗаписей.НастройкиПравОбъектов") Тогда

Папка = Источник.Отбор.Объект.Значение;

ОбновитьПраваПапки(Папка);

ИначеЕсли ТипЗнч(Источник) = Тип("РегистрСведенийНаборЗаписей.НаследованиеНастроекПравОбъектов") Тогда

Папка = Источник.Отбор.Объект.Значение;

ОбновитьПраваПапки(Папка);

ИначеЕсли ТипЗнч(Источник) = Тип("РегистрСведенийНаборЗаписей.СведенияОПользователях") Тогда

ТекущийПриоритетОчередиОбновленияПрав = ПараметрыСеанса.ПриоритетОчередиОбновленияПрав;

ПараметрыСеанса.ПриоритетОчередиОбновленияПрав = 2; // Долгая очередь

Попытка

ПриЗаписиСведенийОПользователях(Источник);

ПараметрыСеанса.ПриоритетОчередиОбновленияПрав = ТекущийПриоритетОчередиОбновленияПрав;

Исключение

ПараметрыСеанса.ПриоритетОчередиОбновленияПрав = ТекущийПриоритетОчередиОбновленияПрав;

ВызватьИсключение;

КонецПопытки;

КонецЕсли;

КонецПроцедуры

// Обработчик подписки ДокументооборотПраваДоступаПередЗаписьюПравообразующихКонстант

Процедура ДокументооборотПраваДоступаПередЗаписьюПравообразующихКонстант(Источник, Отказ) Экспорт

Если Константы[Источник.Метаданные().Имя].Получить() <> Источник.Значение Тогда

Источник.ДополнительныеСвойства.Вставить("ЗначениеИзменено", Истина);

КонецЕсли;

КонецПроцедуры

// Обработчик подписки ДокументооборотПраваДоступаПриЗаписиПравообразующихКонстант

Процедура ДокументооборотПраваДоступаПриЗаписиПравообразующихКонстант(Источник, Отказ) Экспорт

УстановитьПривилегированныйРежим(Истина);

Если НЕ Источник.ДополнительныеСвойства.Свойство("ЗначениеИзменено")

Или НЕ Источник.ДополнительныеСвойства.ЗначениеИзменено Тогда

Возврат;

КонецЕсли;

// Вызов переопределяемого метода

Если ДокументооборотПраваДоступаПереопределяемый.ДокументооборотПраваДоступаПриЗаписиПравообразующихКонстант(Источник, Отказ) Тогда

Возврат;

КонецЕсли;

ТекущийПриоритетОчередиОбновленияПрав = ПараметрыСеанса.ПриоритетОчередиОбновленияПрав;

ПараметрыСеанса.ПриоритетОчередиОбновленияПрав = 2; // Долгая очередь

Попытка

ПриЗаписиКонстанты(Источник);

ПараметрыСеанса.ПриоритетОчередиОбновленияПрав = ТекущийПриоритетОчередиОбновленияПрав;

Исключение

ПараметрыСеанса.ПриоритетОчередиОбновленияПрав = ТекущийПриоритетОчередиОбновленияПрав;

ВызватьИсключение;

КонецПопытки;

КонецПроцедуры

// Обработчик подписки ДокументооборотПраваДоступаПередЗаписьюПапок

Процедура ДокументооборотПраваДоступаПередЗаписьюПапок(Источник, Отказ) Экспорт

УстановитьПривилегированныйРежим(Истина);

РегистрыСведений.НаследованиеНастроекПравОбъектов.Обновить(Источник);

УстановитьПривилегированныйРежим(Ложь);

КонецПроцедуры

// Обработчик регламентного задания ДокументооборотОбновлениеПравДоступаОперативное

Процедура ДокументооборотОбновлениеПравДоступаОперативное() Экспорт

ОбновитьПовторноИспользуемыеЗначения();

ОбработатьОчередьОбновленияПравДоступа(1);

КонецПроцедуры

// Обработчик регламентного задания ДокументооборотОбновлениеПравДоступаДолгое

Процедура ДокументооборотОбновлениеПравДоступаДолгое() Экспорт

УстановитьПривилегированныйРежим(Истина);

ОбновитьПовторноИспользуемыеЗначения();

ПараметрыСеанса.ПриоритетОчередиОбновленияПрав = 2;

// Проверка на необходимость полного обновления прав доступа

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ ПЕРВЫЕ 1

| ИСТИНА КАК ЕстьЗаписи

|ИЗ

| РегистрСведений.ПраваПоДескрипторамДоступа КАК ПраваПоДескрипторамДоступа";

Результат = Запрос.Выполнить();

Если Результат.Пустой() Тогда

// Полное обновление всех прав

ДокументооборотПраваДоступа.УдалитьВсеДанныеОПравахДоступа(Истина);

ДокументооборотПраваДоступа.ОбновитьПраваВсехДанных();

КонецЕсли;

ОбработатьОчередьОбновленияПравДоступа(2);

ПараметрыСеанса.ПриоритетОчередиОбновленияПрав = 1;

КонецПроцедуры

Процедура ОбработатьОчередьОбновленияПравДоступа(Приоритет) Экспорт

УстановитьПривилегированныйРежим(Истина);

ПараметрыСеанса.ПриоритетОчередиОбновленияПрав = Приоритет;

ЗаписьЖурналаРегистрации(

НСтр("ru = 'Права доступа'"),

УровеньЖурналаРегистрации.Информация,,

,

НСтр("ru = 'Начато обновление прав доступа'"));

Количество = РегистрыСведений.ОчередьОбновленияПравДоступа.ОбработатьПорцию();

Пока Количество <> 0 Цикл

Количество = РегистрыСведений.ОчередьОбновленияПравДоступа.ОбработатьПорцию();

КонецЦикла;

ЗаписьЖурналаРегистрации(

НСтр("ru = 'Права доступа'"),

УровеньЖурналаРегистрации.Информация,,

,

НСтр("ru = 'Закончено обновление прав доступа'"));

КонецПроцедуры

// Обработчик регламентного задания ДокументооборотУдалениеУстаревшихПравДоступа

Процедура ДокументооборотУдалениеУстаревшихПравДоступа() Экспорт

УстановитьПривилегированныйРежим(Истина);

ЗаписьЖурналаРегистрации(

НСтр("ru = 'Права доступа'"),

УровеньЖурналаРегистрации.Информация,,

,

НСтр("ru = 'Начато удаление устаревших прав доступа'"));

Справочники.ДескрипторыДоступаОбъектов.УдалитьНеиспользуемые();

Справочники.ДескрипторыДоступаФайлов.УдалитьНеиспользуемые();

Справочники.ДескрипторыДоступаРегистров.УдалитьНеиспользуемые();

ЗаписьЖурналаРегистрации(

НСтр("ru = 'Права доступа'"),

УровеньЖурналаРегистрации.Информация,,

,

НСтр("ru = 'Закончено удаление устаревших прав доступа'"));

КонецПроцедуры

// Обновляет права всех дескрипторов, которые зависят от указанного дескриптора

Процедура ОбновитьПраваСвязанныхДескрипторовПоДескриптору(Дескриптор) Экспорт

УстановитьПривилегированныйРежим(Истина);

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| ДескрипторыДоступаДляОбъектов.Объект

|ИЗ

| РегистрСведений.ДескрипторыДоступаДляОбъектов КАК ДескрипторыДоступаДляОбъектов

|ГДЕ

| ДескрипторыДоступаДляОбъектов.Дескриптор = &Дескриптор";

Запрос.УстановитьПараметр("Дескриптор", Дескриптор);

Результат = Запрос.Выполнить();

ВыборкаДетальныеЗаписи = Результат.Выбрать();

Пока ВыборкаДетальныеЗаписи.Следующий() Цикл

ОбновитьПраваСвязанныхДескрипторовПоОбъекту(ВыборкаДетальныеЗаписи.Объект);

КонецЦикла;

КонецПроцедуры

// Обновляет права всех дескрипторов, которые зависят от указанных

// групп доступа корреспондентов

Процедура ОбновитьПраваПоГруппамДоступаКорреспондентов(ГруппыДоступа) Экспорт

Если ГруппыДоступа.Количество() = 0 Тогда

Возврат;

КонецЕсли;

// ДескрипторыДоступаОбъектов

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ РАЗЛИЧНЫЕ

| ДескрипторыДоступаОбъектовКорреспонденты.Ссылка

|ИЗ

| Справочник.ДескрипторыДоступаОбъектов.Корреспонденты КАК ДескрипторыДоступаОбъектовКорреспонденты

|ГДЕ

| ДескрипторыДоступаОбъектовКорреспонденты.ГруппаДоступа В(&ГруппыДоступа)";

Запрос.УстановитьПараметр("ГруппыДоступа", ГруппыДоступа);

Результат = Запрос.Выполнить();

ВыборкаДетальныеЗаписи = Результат.Выбрать();

Пока ВыборкаДетальныеЗаписи.Следующий() Цикл

Справочники.ДескрипторыДоступаОбъектов.ОбновитьПрава(ВыборкаДетальныеЗаписи.Ссылка);

КонецЦикла;

// ДескрипторыДоступаРегистров

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| ДескрипторыДоступаРегистров.Ссылка

|ИЗ

| Справочник.ДескрипторыДоступаРегистров КАК ДескрипторыДоступаРегистров

|ГДЕ

| ДескрипторыДоступаРегистров.ОбъектДоступа1 В(&ГруппыДоступа)

|

|ОБЪЕДИНИТЬ ВСЕ

|

|ВЫБРАТЬ

| ДескрипторыДоступаРегистров.Ссылка

|ИЗ

| Справочник.ДескрипторыДоступаРегистров КАК ДескрипторыДоступаРегистров

|ГДЕ

| ДескрипторыДоступаРегистров.ОбъектДоступа2 В(&ГруппыДоступа)

|

|ОБЪЕДИНИТЬ ВСЕ

|

|ВЫБРАТЬ

| ДескрипторыДоступаРегистров.Ссылка

|ИЗ

| Справочник.ДескрипторыДоступаРегистров КАК ДескрипторыДоступаРегистров

|ГДЕ

| ДескрипторыДоступаРегистров.ОбъектДоступа3 В(&ГруппыДоступа)";

Запрос.УстановитьПараметр("ГруппыДоступа", ГруппыДоступа);

Результат = Запрос.Выполнить();

ВыборкаДетальныеЗаписи = Результат.Выбрать();

Пока ВыборкаДетальныеЗаписи.Следующий() Цикл

Справочники.ДескрипторыДоступаРегистров.ОбновитьПрава(ВыборкаДетальныеЗаписи.Ссылка);

КонецЦикла;

КонецПроцедуры

// Обновляет права всех дескрипторов, которые зависят от указанных

// групп доступа физлиц

Процедура ОбновитьПраваПоГруппамДоступаФизлиц(ГруппыДоступа) Экспорт

Если ГруппыДоступа.Количество() = 0 Тогда

Возврат;

КонецЕсли;

// ДескрипторыДоступаОбъектов

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ РАЗЛИЧНЫЕ

| ДескрипторыДоступаОбъектовФизическиеЛица.Ссылка

|ИЗ

| Справочник.ДескрипторыДоступаОбъектов.ФизическиеЛица КАК ДескрипторыДоступаОбъектовФизическиеЛица

|ГДЕ

| ДескрипторыДоступаОбъектовФизическиеЛица.ГруппаДоступа В(&ГруппыДоступа)";

Запрос.УстановитьПараметр("ГруппыДоступа", ГруппыДоступа);

Результат = Запрос.Выполнить();

ВыборкаДетальныеЗаписи = Результат.Выбрать();

Пока ВыборкаДетальныеЗаписи.Следующий() Цикл

Справочники.ДескрипторыДоступаОбъектов.ОбновитьПрава(ВыборкаДетальныеЗаписи.Ссылка);

КонецЦикла;

// ДескрипторыДоступаРегистров

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| ДескрипторыДоступаРегистров.Ссылка

|ИЗ

| Справочник.ДескрипторыДоступаРегистров КАК ДескрипторыДоступаРегистров

|ГДЕ

| ДескрипторыДоступаРегистров.ОбъектДоступа1 В(&ГруппыДоступа)

|

|ОБЪЕДИНИТЬ ВСЕ

|

|ВЫБРАТЬ

| ДескрипторыДоступаРегистров.Ссылка

|ИЗ

| Справочник.ДескрипторыДоступаРегистров КАК ДескрипторыДоступаРегистров

|ГДЕ

| ДескрипторыДоступаРегистров.ОбъектДоступа2 В(&ГруппыДоступа)

|

|ОБЪЕДИНИТЬ ВСЕ

|

|ВЫБРАТЬ

| ДескрипторыДоступаРегистров.Ссылка

|ИЗ

| Справочник.ДескрипторыДоступаРегистров КАК ДескрипторыДоступаРегистров

|ГДЕ

| ДескрипторыДоступаРегистров.ОбъектДоступа3 В(&ГруппыДоступа)";

Запрос.УстановитьПараметр("ГруппыДоступа", ГруппыДоступа);

Результат = Запрос.Выполнить();

ВыборкаДетальныеЗаписи = Результат.Выбрать();

Пока ВыборкаДетальныеЗаписи.Следующий() Цикл

Справочники.ДескрипторыДоступаРегистров.ОбновитьПрава(ВыборкаДетальныеЗаписи.Ссылка);

КонецЦикла;

КонецПроцедуры

// Обновляет права файлов, владельцем которых является указанный объект

Процедура ОбновитьПраваФайловОбъекта(Объект) Экспорт

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ ПЕРВЫЕ 1

| Файлы.Ссылка

|ИЗ

| Справочник.Файлы КАК Файлы

|ГДЕ

| Файлы.ВладелецФайла = &ВладелецФайла";

Запрос.УстановитьПараметр("ВладелецФайла", Объект.Ссылка);

Результат = Запрос.Выполнить();

ВыборкаДетальныеЗаписи = Результат.Выбрать();

Если ВыборкаДетальныеЗаписи.Следующий() Тогда

// Определение дескриптора

Дескриптор = ОпределитьДескрипторДоступаФайлаПоВладельцу(Объект.Ссылка);

// Вычисление права

Если Дескриптор <> Неопределено Тогда

Справочники.ДескрипторыДоступаФайлов.ОбновитьПрава(Дескриптор);

КонецЕсли;

КонецЕсли;

КонецПроцедуры

////////////////////////////////////////////////////////////////////////////////

// Служебные методы

Функция ВсеРуководителиПользователя(Пользователь)

МассивРуководителей = Новый Массив;

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| СведенияОПользователях.Подразделение КАК Подразделение

|ИЗ

| РегистрСведений.СведенияОПользователях КАК СведенияОПользователях

|ГДЕ

| СведенияОПользователях.Пользователь = &Пользователь";

Запрос.УстановитьПараметр("Пользователь", Пользователь);

Результат = Запрос.Выполнить();

Если Результат.Пустой() Тогда

Возврат МассивРуководителей;

КонецЕсли;

Выборка = Результат.Выбрать();

Выборка.Следующий();

Подразделение = Выборка.Подразделение;

Пока ЗначениеЗаполнено(Подразделение) Цикл

Руководитель = Подразделение.Руководитель;

Если ЗначениеЗаполнено(Руководитель) И Руководитель <> Пользователь Тогда

МассивРуководителей.Добавить(Руководитель);

КонецЕсли;

Подразделение = Подразделение.Родитель;

КонецЦикла;

Возврат МассивРуководителей;

КонецФункции

Функция ПолучитьДескрипторДоступа(ОбъектДоступа, Немедленно = Ложь)

УстановитьПривилегированныйРежим(Истина);

НовыйДескриптор = Справочники.ДескрипторыДоступаОбъектов.СоздатьНовыйДескриптор(ОбъектДоступа);

ГотовыйДескриптор = Справочники.ДескрипторыДоступаОбъектов.НайтиДескрипторПоОбразцу(НовыйДескриптор);

Если ЗначениеЗаполнено(ГотовыйДескриптор) Тогда

Возврат ГотовыйДескриптор;

КонецЕсли;

// Запись нового дескриптора

Если Немедленно Тогда

НовыйДескриптор.ДополнительныеСвойства.Вставить("НемедленноРассчитатьПрава", Истина);

КонецЕсли;

НовыйДескриптор.Записать();

Возврат НовыйДескриптор.Ссылка;

КонецФункции

Функция ПолучитьДескрипторДоступаФайла(ВладелецФайла, Немедленно = Ложь)

УстановитьПривилегированныйРежим(Истина);

// Поиск существующего дескриптора

ДескрипторВладельца = РегистрыСведений.ДескрипторыДоступаДляОбъектов.НайтиДескрипторДляОбъекта(ВладелецФайла);

// Владелец файла может не участвовать в механизме прав доступа

Если ДескрипторВладельца = Неопределено Тогда

Возврат Неопределено;

КонецЕсли;

ГотовыйДескриптор = НайтиДескрипторФайла(ДескрипторВладельца);

Если ЗначениеЗаполнено(ГотовыйДескриптор) Тогда

// Запись соответствия владельца файла и дескриптора доступа файла

РегистрыСведений.ДескрипторыДоступаДляФайлов.Сохранить(ГотовыйДескриптор.Ссылка, ВладелецФайла.Ссылка);

Возврат ГотовыйДескриптор;

КонецЕсли;

// Формирование нового дескриптора

НовыйДескриптор = Справочники.ДескрипторыДоступаФайлов.СоздатьЭлемент();

НовыйДескриптор.ДескрипторВладельца = ДескрипторВладельца;

// Проверяем, что тип владельца файла указан в допустимах типах

// реквизита ВладелецФайла

Если Не ЗначениеЗаполнено(НовыйДескриптор.ДескрипторВладельца) Тогда

ТекстОшибки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(

НСтр("ru = 'Не указан тип владельца файла (%1).'"),

ВладелецФайла.Метаданные().ПолноеИмя());

ВызватьИсключение ТекстОшибки;

КонецЕсли;

// Начало транзакции т.к. дескриптор и его привязка к владельцу файла должны

// записываться строго вместе

ВнешняяТранзакция = ТранзакцияАктивна();

Если Не ВнешняяТранзакция Тогда

НачатьТранзакцию();

КонецЕсли;

// Запись дескриптора

Если Немедленно Тогда

НовыйДескриптор.ДополнительныеСвойства.Вставить("НемедленноРассчитатьПрава", Истина);

КонецЕсли;

НовыйДескриптор.Записать();

// Запись соответствия владельца файла и дескриптора доступа файла

РегистрыСведений.ДескрипторыДоступаДляФайлов.Сохранить(НовыйДескриптор.Ссылка, ВладелецФайла.Ссылка);

// Завершение транзакции

Если Не ВнешняяТранзакция Тогда

ЗафиксироватьТранзакцию();

КонецЕсли;

Возврат НовыйДескриптор.Ссылка;

КонецФункции

Функция НайтиДескрипторФайла(ДескрипторВладельца)

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| ДескрипторыДоступаФайлов.Ссылка

|ИЗ

| Справочник.ДескрипторыДоступаФайлов КАК ДескрипторыДоступаФайлов

|ГДЕ

| ДескрипторыДоступаФайлов.ДескрипторВладельца = &ДескрипторВладельца";

Запрос.УстановитьПараметр("ДескрипторВладельца", ДескрипторВладельца);

Результат = Запрос.Выполнить();

ВыборкаДетальныеЗаписи = Результат.Выбрать();

Если ВыборкаДетальныеЗаписи.Следующий() Тогда

Возврат ВыборкаДетальныеЗаписи.Ссылка;

КонецЕсли;

Возврат Неопределено;

КонецФункции

Функция ПолучитьДескрипторДоступаЗаписиНабораЗаписей(ИдентификаторОбъектаМетаданных, Запись, Немедленно = Ложь)

УстановитьПривилегированныйРежим(Истина);

НовыйДескриптор = Справочники.ДескрипторыДоступаРегистров.СоздатьНовыйДескриптор(ИдентификаторОбъектаМетаданных, Запись);

ГотовыйДескриптор = Справочники.ДескрипторыДоступаРегистров.НайтиДескрипторПоОбразцу(НовыйДескриптор);

Если ЗначениеЗаполнено(ГотовыйДескриптор) Тогда

Возврат ГотовыйДескриптор;

КонецЕсли;

// Запись нового дескриптора

Если Немедленно Тогда

НовыйДескриптор.ДополнительныеСвойства.Вставить("НемедленноРассчитатьПрава", Истина);

КонецЕсли;

НовыйДескриптор.Записать();

Возврат НовыйДескриптор.Ссылка;

КонецФункции

Процедура ОбновитьПраваСвязанныхДескрипторовПоОбъекту(Объект)

УстановитьПривилегированныйРежим(Истина);

// Вызов переопределяемого метода

ДокументооборотПраваДоступаПереопределяемый.ОбновитьПраваСвязанныхДескрипторовПоОбъекту(Объект);

// Обновление прав на файлы

ОбновитьПраваФайловОбъекта(Объект);

// Обновление прав на регистры

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| ДескрипторыДоступаРегистров.Ссылка

|ИЗ

| Справочник.ДескрипторыДоступаРегистров КАК ДескрипторыДоступаРегистров

|ГДЕ

| ДескрипторыДоступаРегистров.ОбъектДоступа1 = &ОбъектДоступа1

|

|ОБЪЕДИНИТЬ ВСЕ

|

|ВЫБРАТЬ

| ДескрипторыДоступаРегистров.Ссылка

|ИЗ

| Справочник.ДескрипторыДоступаРегистров КАК ДескрипторыДоступаРегистров

|ГДЕ

| ДескрипторыДоступаРегистров.ОбъектДоступа2 = &ОбъектДоступа2

|

|ОБЪЕДИНИТЬ ВСЕ

|

|ВЫБРАТЬ

| ДескрипторыДоступаРегистров.Ссылка

|ИЗ

| Справочник.ДескрипторыДоступаРегистров КАК ДескрипторыДоступаРегистров

|ГДЕ

| ДескрипторыДоступаРегистров.ОбъектДоступа3 = &ОбъектДоступа3";

Запрос.УстановитьПараметр("ОбъектДоступа1", Объект.Ссылка);

Запрос.УстановитьПараметр("ОбъектДоступа2", Объект.Ссылка);

Запрос.УстановитьПараметр("ОбъектДоступа3", Объект.Ссылка);

Результат = Запрос.Выполнить();

ВыборкаДетальныеЗаписи = Результат.Выбрать();

Пока ВыборкаДетальныеЗаписи.Следующий() Цикл

Справочники.ДескрипторыДоступаРегистров.ОбновитьПрава(ВыборкаДетальныеЗаписи.Ссылка);

КонецЦикла;

// Обновление прав на задачи процессов

Если ЭтоБизнесПроцесс(Объект.Ссылка) Тогда

ПраваДоступаНаБизнесПроцессыВызовСервера.ОбновитьПраваНаЗадачиБизнесПроцесса(Объект.Ссылка);

ПраваДоступаНаБизнесПроцессыВызовСервера.ОбновитьПраваНаДочерниеБизнесПроцессы(Объект.Ссылка);

КонецЕсли;

КонецПроцедуры

// Обновляет права папки и всех ее подпапок

Процедура ОбновитьПраваПапки(Папка)

Если Не ЗначениеЗаполнено(Папка) Тогда

Возврат;

КонецЕсли;

УстановитьПривилегированныйРежим(Истина);

ИмяТаблицы = Папка.Метаданные().ПолноеИмя();

// Отбор всех папок в иерархии

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| ТаблицаПапок.Ссылка

|ИЗ

| #Таблица КАК ТаблицаПапок

|ГДЕ

| ТаблицаПапок.Ссылка В ИЕРАРХИИ (&Папка)";

Запрос.Текст = СтрЗаменить(Запрос.Текст, "#Таблица", ИмяТаблицы);

Запрос.УстановитьПараметр("Папка", Папка);

Результат = Запрос.Выполнить();

ВыборкаДетальныеЗаписи = Результат.Выбрать();

Пока ВыборкаДетальныеЗаписи.Следующий() Цикл

// Обновление прав для каждой папки

ОпределитьДескрипторДоступаОбъекта(ВыборкаДетальныеЗаписи.Ссылка);

ОбновитьПраваДоступаДляОбъекта(ВыборкаДетальныеЗаписи.Ссылка);

ОбновитьПраваДескрипторовЗависящихОтПапки(ВыборкаДетальныеЗаписи.Ссылка);

КонецЦикла;

КонецПроцедуры

Процедура ОбновитьПраваДескрипторовЗависящихОтПапки(Папка)

УстановитьПривилегированныйРежим(Истина);

// Обновление дескрипторов объектов

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| ДескрипторыДоступаОбъектов.Ссылка

|ИЗ

| Справочник.ДескрипторыДоступаОбъектов КАК ДескрипторыДоступаОбъектов

|ГДЕ

| ДескрипторыДоступаОбъектов.Папка = &Папка";

Запрос.УстановитьПараметр("Папка", Папка);

Результат = Запрос.Выполнить();

ВыборкаДетальныеЗаписи = Результат.Выбрать();

Пока ВыборкаДетальныеЗаписи.Следующий() Цикл

Справочники.ДескрипторыДоступаОбъектов.ОбновитьПрава(ВыборкаДетальныеЗаписи.Ссылка);

КонецЦикла;

// Обновление дескрипторов файлов

Справочники.ДескрипторыДоступаФайлов.ОбновитьПраваПоВладельцуФайла(Папка);

КонецПроцедуры

Процедура ОбновитьПраваДескрипторовЗависящихОтПрофиля(Профиль)

УстановитьПривилегированныйРежим(Истина);

ЗначенияДоступа = Новый Массив;

Для каждого Эл Из Профиль.ВидыДоступа Цикл

// Пропускаем неиспользуемые виды доступа

Если Эл.ВидДоступа = ПланыВидовХарактеристик.ВидыДоступа.ДополнительныеСведения

ИЛИ Эл.ВидДоступа = ПланыВидовХарактеристик.ВидыДоступа.Пользователи Тогда

Продолжить;

КонецЕсли;

ВсеЗначенияВида = ПолучитьВсеЗначенияВидаДоступа(Эл.ВидДоступа);

Для каждого ЗначениеВида Из ВсеЗначенияВида Цикл

ЗначенияДоступа.Добавить(ЗначениеВида.Ссылка);

КонецЦикла;

// Добавление пустой ссылки

ЗначенияДоступа.Добавить(ПолучитьПустуюСсылкуДляВидаДоступа(Эл.ВидДоступа));

КонецЦикла;

ОбновитьПраваПоЗначениямВидовДоступа(ЗначенияДоступа);

КонецПроцедуры

// Возвращает массив значений доступа, права по которым определяет указанная

// группа доступа

Функция ПолучитьЗначенияДоступаГруппыДоступа(ГруппаДоступа)

ЗначенияДоступа = Новый Массив;

Для каждого Эл Из ГруппаДоступа.Профиль.ВидыДоступа Цикл

// Пропускаем неиспользуемые виды доступа

Если Эл.ВидДоступа = ПланыВидовХарактеристик.ВидыДоступа.ДополнительныеСведения

ИЛИ Эл.ВидДоступа = ПланыВидовХарактеристик.ВидыДоступа.Пользователи Тогда

Продолжить;

КонецЕсли;

ВсеЗначенияВида = ПолучитьВсеЗначенияВидаДоступа(Эл.ВидДоступа);

Для каждого ЗначениеВида Из ВсеЗначенияВида Цикл

ЗначенияДоступа.Добавить(ЗначениеВида.Ссылка);

КонецЦикла;

// Добавление пустой ссылки

ЗначенияДоступа.Добавить(ПолучитьПустуюСсылкуДляВидаДоступа(Эл.ВидДоступа));

КонецЦикла;

Возврат ЗначенияДоступа;

КонецФункции

Процедура ЗаполнитьЗначенияГруппыДоступаПоВидуДоступа(ЗначенияДоступа, ГруппаДоступа, ВидДоступа)

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| ЗначенияГруппДоступа.ЗначениеДоступа КАК ЗначениеДоступа,

| ЗначенияГруппДоступа.ТолькоВидДоступа КАК Разрешено

|ИЗ

| РегистрСведений.ЗначенияГруппДоступа КАК ЗначенияГруппДоступа

|ГДЕ

| ЗначенияГруппДоступа.ГруппаДоступа = &ГруппаДоступа

| И ЗначенияГруппДоступа.ВидДоступа = &ВидДоступа";

Запрос.УстановитьПараметр("ГруппаДоступа", ГруппаДоступа.Ссылка);

Запрос.УстановитьПараметр("ВидДоступа", ВидДоступа);

ВыборкаДетальныеЗаписи = Запрос.Выполнить().Выбрать();

Если ВыборкаДетальныеЗаписи.Количество() <> 0 Тогда

Если ВыборкаДетальныеЗаписи.Количество() = 1 Тогда

Если ВыборкаДетальныеЗаписи.Следующий() Тогда

Если ЗначениеЗаполнено(ВыборкаДетальныеЗаписи.ЗначениеДоступа) Тогда

// Указано разрешение или запрещение

ЗначениеДоступа = Новый Структура;

ЗначениеДоступа.Вставить("Значение", ВыборкаДетальныеЗаписи.ЗначениеДоступа);

ЗначениеДоступа.Вставить("Разрешено", ВыборкаДетальныеЗаписи.Разрешено);

ЗначенияДоступа.Добавить(ЗначениеДоступа);

Иначе

// Все запрещены

ВсеЗначения = ПолучитьВсеЗначенияВидаДоступа(ВидДоступа);

Для каждого Эл Из ВсеЗначения Цикл

ЗначениеДоступа = Новый Структура;

ЗначениеДоступа.Вставить("Значение", Эл.Ссылка);

ЗначениеДоступа.Вставить("Разрешено", Ложь);

ЗначенияДоступа.Добавить(ЗначениеДоступа);

КонецЦикла;

КонецЕсли;

КонецЕсли;

Иначе

// Указан список разрешенных или запрещенных

Пока ВыборкаДетальныеЗаписи.Следующий() Цикл

Если ВыборкаДетальныеЗаписи.ЗначениеДоступа <> Неопределено Тогда

ЗначениеДоступа = Новый Структура;

ЗначениеДоступа.Вставить("Значение", ВыборкаДетальныеЗаписи.ЗначениеДоступа);

ЗначениеДоступа.Вставить("Разрешено", ВыборкаДетальныеЗаписи.Разрешено);

ЗначенияДоступа.Добавить(ЗначениеДоступа);

КонецЕсли;

КонецЦикла;

КонецЕсли;

Иначе

// Все разрешены, добавляем все значения, соответствующие этому виду доступа

ВсеЗначения = ПолучитьВсеЗначенияВидаДоступа(ВидДоступа);

Для каждого Эл Из ВсеЗначения Цикл

ЗначениеДоступа = Новый Структура;

ЗначениеДоступа.Вставить("Значение", Эл.Ссылка);

ЗначениеДоступа.Вставить("Разрешено", Истина);

ЗначенияДоступа.Добавить(ЗначениеДоступа);

КонецЦикла;

КонецЕсли;

КонецПроцедуры

Функция ПолучитьВсеЗначенияВидаДоступа(ВидДоступа)

Типы = ВидДоступа.ТипЗначения.Типы();

Если Типы.Количество() > 1 Тогда

ВызватьИсключение НСтр("ru = 'Число типов вида доступа больше 1.'");

КонецЕсли;

МетаданныеТипа = Метаданные.НайтиПоТипу(Типы[0]);

ИмяТаблицы = МетаданныеТипа.ПолноеИмя();

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| Таблица.Ссылка

|ИЗ

| #Таблица КАК Таблица";

Запрос.Текст = СтрЗаменить(Запрос.Текст, "#Таблица", ИмяТаблицы);

Возврат Запрос.Выполнить().Выгрузить();

КонецФункции

Функция ПолучитьПустуюСсылкуДляВидаДоступа(ВидДоступа)

ПустаяСсылка = Неопределено;

Типы = ВидДоступа.ТипЗначения.Типы();

Если Типы.Количество() > 1 Тогда

ВызватьИсключение НСтр("ru = 'Число типов вида доступа больше 1.'");

КонецЕсли;

МетаданныеТипа = Метаданные.НайтиПоТипу(Типы[0]);

Менеджер = ОбщегоНазначения.МенеджерОбъектаПоПолномуИмени(МетаданныеТипа.ПолноеИмя());

ПустаяСсылка = Менеджер.ПустаяСсылка();

Возврат ПустаяСсылка;

КонецФункции

Процедура ОбновитьПраваЗависящиеОтГруппыДоступа(ГруппаДоступа)

УстановитьПривилегированныйРежим(Истина);

ЗначенияДоступа = ПолучитьЗначенияДоступаГруппыДоступа(ГруппаДоступа);

ОбновитьПраваПоЗначениямВидовДоступа(ЗначенияДоступа);

КонецПроцедуры

// Обновляет права всех дескрипторов доступа в которых есть ссылки на

// указанные значения доступа

Процедура ОбновитьПраваПоЗначениямВидовДоступа(ЗначенияДоступа)

УстановитьПривилегированныйРежим(Истина);

// Поиск и обновление дексрипторов по реквизитам

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| ДескрипторыДоступаОбъектов.Ссылка

|ИЗ

| Справочник.ДескрипторыДоступаОбъектов КАК ДескрипторыДоступаОбъектов

|ГДЕ

| ДескрипторыДоступаОбъектов.ВидОбъекта В(&ЗначенияДоступа)

|

|ОБЪЕДИНИТЬ ВСЕ

|

|ВЫБРАТЬ

| ДескрипторыДоступаОбъектов.Ссылка

|ИЗ

| Справочник.ДескрипторыДоступаОбъектов КАК ДескрипторыДоступаОбъектов

|ГДЕ

| ДескрипторыДоступаОбъектов.ВопросДеятельности В(&ЗначенияДоступа)

|

|ОБЪЕДИНИТЬ ВСЕ

|

|ВЫБРАТЬ

| ДескрипторыДоступаОбъектов.Ссылка

|ИЗ

| Справочник.ДескрипторыДоступаОбъектов КАК ДескрипторыДоступаОбъектов

|ГДЕ

| ДескрипторыДоступаОбъектов.ГрифДоступа В(&ЗначенияДоступа)

|

|ОБЪЕДИНИТЬ ВСЕ

|

|ВЫБРАТЬ

| ДескрипторыДоступаОбъектов.Ссылка

|ИЗ

| Справочник.ДескрипторыДоступаОбъектов КАК ДескрипторыДоступаОбъектов

|ГДЕ

| ДескрипторыДоступаОбъектов.Организация В(&ЗначенияДоступа)";

Запрос.УстановитьПараметр("ЗначенияДоступа", ЗначенияДоступа);

Результат = Запрос.Выполнить();

ВыборкаДетальныеЗаписи = Результат.Выбрать();

Пока ВыборкаДетальныеЗаписи.Следующий() Цикл

Справочники.ДескрипторыДоступаОбъектов.ОбновитьПрава(ВыборкаДетальныеЗаписи.Ссылка);

КонецЦикла;

// Поиск и обновление дексрипторов по группам доступа корреспондентов

ГруппыДоступаКорреспондентов = Новый Массив();

Для каждого Эл Из ЗначенияДоступа Цикл

Если ТипЗнч(Эл) = Тип("СправочникСсылка.ГруппыДоступаКорреспондентов") Тогда

ГруппыДоступаКорреспондентов.Добавить(Эл);

КонецЕсли;

КонецЦикла;

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ РАЗЛИЧНЫЕ

| ДескрипторыДоступаОбъектовКорреспонденты.Ссылка

|ИЗ

| Справочник.ДескрипторыДоступаОбъектов.Корреспонденты КАК ДескрипторыДоступаОбъектовКорреспонденты

|ГДЕ

| ДескрипторыДоступаОбъектовКорреспонденты.ГруппаДоступа В(&ГруппыДоступаКорреспондентов)";

Запрос.УстановитьПараметр("ГруппыДоступаКорреспондентов", ГруппыДоступаКорреспондентов);

Результат = Запрос.Выполнить();

ВыборкаДетальныеЗаписи = Результат.Выбрать();

Пока ВыборкаДетальныеЗаписи.Следующий() Цикл

Справочники.ДескрипторыДоступаОбъектов.ОбновитьПрава(ВыборкаДетальныеЗаписи.Ссылка);

КонецЦикла;

// Поиск и обновление дексрипторов по группам доступа физических лиц

ГруппыДоступаФизЛиц = Новый Массив();

Для каждого Эл Из ЗначенияДоступа Цикл

Если ТипЗнч(Эл) = Тип("СправочникСсылка.ГруппыДоступаФизическихЛиц") Тогда

ГруппыДоступаФизЛиц.Добавить(Эл);

КонецЕсли;

КонецЦикла;

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ РАЗЛИЧНЫЕ

| ДескрипторыДоступаОбъектовФизическиеЛица.Ссылка

|ИЗ

| Справочник.ДескрипторыДоступаОбъектов.ФизическиеЛица КАК ДескрипторыДоступаОбъектовФизическиеЛица

|ГДЕ

| ДескрипторыДоступаОбъектовФизическиеЛица.ГруппаДоступа В(&ГруппыДоступаФизЛиц)";

Запрос.УстановитьПараметр("ГруппыДоступаФизЛиц", ГруппыДоступаФизЛиц);

Результат = Запрос.Выполнить();

ВыборкаДетальныеЗаписи = Результат.Выбрать();

Пока ВыборкаДетальныеЗаписи.Следующий() Цикл

Справочники.ДескрипторыДоступаОбъектов.ОбновитьПрава(ВыборкаДетальныеЗаписи.Ссылка);

КонецЦикла;

КонецПроцедуры

Процедура ОбновитьПраваПоПодчиненнымПодразделениям(Подразделение)

УстановитьПривилегированныйРежим(Истина);

// Выбор всех подразделений от указанного (включительно)

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| СтруктураАдминистрации.Ссылка

|ИЗ

| Справочник.СтруктураАдминистрации КАК СтруктураАдминистрации

|ГДЕ

| СтруктураАдминистрации.Ссылка В ИЕРАРХИИ(&Родитель)";

Запрос.УстановитьПараметр("Родитель", Подразделение);

Результат = Запрос.Выполнить();

ВыборкаДетальныеЗаписи = Результат.Выбрать();

Пока ВыборкаДетальныеЗаписи.Следующий() Цикл

ОбновитьПраваСотрудниковПодразделения(ВыборкаДетальныеЗаписи.Ссылка);

КонецЦикла;

КонецПроцедуры

Процедура ОбновитьПраваСотрудниковПодразделения(Подразделение)

УстановитьПривилегированныйРежим(Истина);

// Выбор всех дескрипторов, в правах которых встречаются сотрудники

// указанного подразделения

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| ПраваПоДескрипторамДоступа.Дескриптор

|ИЗ

| РегистрСведений.ПраваПоДескрипторамДоступа КАК ПраваПоДескрипторамДоступа

| ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.СведенияОПользователях КАК СведенияОПользователях

| ПО ПраваПоДескрипторамДоступа.Пользователь = СведенияОПользователях.Пользователь

|ГДЕ

| СведенияОПользователях.Подразделение = &Подразделение";

Запрос.УстановитьПараметр("Подразделение", Подразделение);

Результат = Запрос.Выполнить();

ВыборкаДетальныеЗаписи = Результат.Выбрать();

Пока ВыборкаДетальныеЗаписи.Следующий() Цикл

ОбновитьПраваДоступаПоДескриптору(ВыборкаДетальныеЗаписи.Дескриптор);

КонецЦикла;

КонецПроцедуры

// Находит дексриптор указанного объекта доступа и немедленно обновляет права

// найденного дескриптора. Если дескриптор не найден, то создает его.

Процедура ОбновитьПраваДоступаДляОбъекта(ОбъектДоступа)

УстановитьПривилегированныйРежим(Истина);

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| ДескрипторыДоступаДляОбъектов.Дескриптор

|ИЗ

| РегистрСведений.ДескрипторыДоступаДляОбъектов КАК ДескрипторыДоступаДляОбъектов

|ГДЕ

| ДескрипторыДоступаДляОбъектов.Объект = &ОбъектДоступа";

Запрос.УстановитьПараметр("ОбъектДоступа", ОбъектДоступа);

Результат = Запрос.Выполнить();

ВыборкаДетальныеЗаписи = Результат.Выбрать();

Если ВыборкаДетальныеЗаписи.Следующий() Тогда

Немедленно = Не ДокументооборотПраваДоступаПовтИсп.ОтложенноеОбновлениеПравДоступа();

ОбновитьПраваДоступаПоДескриптору(

ВыборкаДетальныеЗаписи.Дескриптор,

Немедленно);

Иначе

ОпределитьДескрипторДоступаОбъекта(ОбъектДоступа);

КонецЕсли;

КонецПроцедуры

Процедура ОбновлениеРолейПередЗаписьюОбъектовПередЗаписью(Источник, Отказ) Экспорт

Если ТипЗнч(Источник) = Тип("СправочникОбъект.Пользователи") Тогда

Источник.ДополнительныеСвойства.Вставить("ЭтоНовый", Источник.ЭтоНовый());

ИначеЕсли ТипЗнч(Источник) = Тип("СправочникОбъект.ГруппыПользователей") Тогда

СоставГруппы = Новый ТаблицаЗначений;

СоставГруппы.Колонки.Добавить("Пользователь");

Если Не Источник.ЭтоНовый() Тогда

СоставГруппы = ДокументооборотПраваДоступаПовтИсп.ПолучитьСоставГруппыПользователей(Источник.Ссылка);

КонецЕсли;

Источник.ДополнительныеСвойства.Вставить("СтарыйСоставГруппы", СоставГруппы);

Если Не Источник.ЭтоНовый() Тогда

СтарыйРодитель = ОбщегоНазначения.ПолучитьЗначениеРеквизита(Источник.Ссылка, "Родитель");

Источник.ДополнительныеСвойства.Вставить("СтарыйРодитель", СтарыйРодитель);

КонецЕсли;

ИначеЕсли ТипЗнч(Источник) = Тип("СправочникОбъект.ГруппыДоступа") Тогда

СоставГруппы = Новый ТаблицаЗначений;

СоставГруппы.Колонки.Добавить("Пользователь");

Если Не Источник.ЭтоНовый() Тогда

СоставГруппы = Источник.Ссылка.Пользователи;

КонецЕсли;

Источник.ДополнительныеСвойства.Вставить("СтарыйСоставГруппы", СоставГруппы);

КонецЕсли;

КонецПроцедуры

Процедура ОбновлениеРолейПриЗаписиОбъектовПриЗаписи(Источник, Отказ) Экспорт

Если ТипЗнч(Источник) = Тип("СправочникОбъект.Пользователи")

И (Источник.ДополнительныеСвойства.ЭтоНовый

Или (Источник.ДополнительныеСвойства.Свойство("ДобавленНовыйПользовательИБ")

И Источник.ДополнительныеСвойства.ДобавленНовыйПользовательИБ)) Тогда

МассивПользователей = Новый Массив;

МассивПользователей.Добавить(Источник.Ссылка);

УправлениеДоступом.ОбновитьРолиПользователей(МассивПользователей);

РегистрыСведений.ДокументооборотПользователиГруппДоступа.ОбновитьВсе();

КонецЕсли;

Если ТипЗнч(Источник) = Тип("СправочникОбъект.ГруппыПользователей") Тогда

МассивИзменений = Новый Массив;

ПолноеОбновление = Ложь;

Если Источник.ДополнительныеСвойства.Свойство("СтарыйРодитель") Тогда

СтарыйРодитель = Источник.ДополнительныеСвойства.СтарыйРодитель;

Если СтарыйРодитель <> Источник.Родитель Тогда

// Полное обновление

ПолноеОбновление = Истина;

СоставГруппы = ДокументооборотПраваДоступаПовтИсп.ПолучитьСоставГруппыПользователей(Источник.Ссылка);

Для Каждого Строка Из СоставГруппы Цикл

МассивИзменений.Добавить(Строка.Пользователь);

КонецЦикла;

КонецЕсли;

КонецЕсли;

Если Не ПолноеОбновление Тогда

// Поиск и обновление отличий в составе группы пользователей

НовыйСоставГруппы = ДокументооборотПраваДоступаПовтИсп.ПолучитьСоставГруппыПользователей(Источник.Ссылка);

СтарыйСоставГруппы = Источник.ДополнительныеСвойства.СтарыйСоставГруппы;

Для Каждого Строка Из НовыйСоставГруппы Цикл

Пользователь = Строка.Пользователь;

Если СтарыйСоставГруппы.Найти(Пользователь, "Пользователь") = Неопределено Тогда

Если МассивИзменений.Найти(Пользователь) = Неопределено Тогда

МассивИзменений.Добавить(Пользователь);

КонецЕсли;

КонецЕсли;

КонецЦикла;

Для Каждого Строка Из СтарыйСоставГруппы Цикл

Пользователь = Строка.Пользователь;

Если НовыйСоставГруппы.Найти(Пользователь, "Пользователь") = Неопределено Тогда

Если МассивИзменений.Найти(Пользователь) = Неопределено Тогда

МассивИзменений.Добавить(Пользователь);

КонецЕсли;

КонецЕсли;

КонецЦикла;

КонецЕсли;

УправлениеДоступом.ОбновитьРолиПользователей(МассивИзменений);

РегистрыСведений.ДокументооборотПользователиГруппДоступа.ОбновитьВсе();

КонецЕсли;

Если ТипЗнч(Источник) = Тип("СправочникОбъект.ГруппыДоступа") Тогда

НовыйСоставГруппы = Источник.Пользователи;

СтарыйСоставГруппы = Источник.ДополнительныеСвойства.СтарыйСоставГруппы;

МассивИзменений = Новый Массив;

Для Каждого Строка Из НовыйСоставГруппы Цикл

Пользователь = Строка.Пользователь;

Если СтарыйСоставГруппы.Найти(Пользователь, "Пользователь") = Неопределено Тогда

Если МассивИзменений.Найти(Пользователь) = Неопределено Тогда

МассивИзменений.Добавить(Пользователь);

КонецЕсли;

КонецЕсли;

КонецЦикла;

Для Каждого Строка Из СтарыйСоставГруппы Цикл

Пользователь = Строка.Пользователь;

Если НовыйСоставГруппы.Найти(Пользователь, "Пользователь") = Неопределено Тогда

Если МассивИзменений.Найти(Пользователь) = Неопределено Тогда

МассивИзменений.Добавить(Пользователь);

КонецЕсли;

КонецЕсли;

КонецЦикла;

ОбновитьМассивПользователейИГруппПользователей(МассивИзменений);

РегистрыСведений.ДокументооборотПользователиГруппДоступа.ОбновитьПоГруппеДоступа(Источник.Ссылка);

КонецЕсли;

Если ТипЗнч(Источник) = Тип("СправочникОбъект.ПрофилиГруппДоступа") Тогда

// Группы доступа

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| ГруппыДоступа.Ссылка КАК Ссылка

|ИЗ

| Справочник.ГруппыДоступа КАК ГруппыДоступа

|ГДЕ

| ГруппыДоступа.Профиль = &Профиль";

Запрос.УстановитьПараметр("Профиль", Источник.Ссылка);

Результат = Запрос.Выполнить().Выгрузить().ВыгрузитьКолонку("Ссылка");

Для Каждого ГруппаДоступа Из Результат Цикл

МассивИзменений = Новый Массив;

Для Каждого Строка Из ГруппаДоступа.Пользователи Цикл

МассивИзменений.Добавить(Строка.Пользователь);

КонецЦикла;

ОбновитьМассивПользователейИГруппПользователей(МассивИзменений);

РегистрыСведений.ДокументооборотПользователиГруппДоступа.ОбновитьПоГруппеДоступа(ГруппаДоступа);

КонецЦикла;

КонецЕсли;

КонецПроцедуры

Процедура ОбновитьМассивПользователейИГруппПользователей(МассивИзменений)

МассивИзмененийРазвернутый = Новый Массив;

Для Каждого ПользовательИлиГруппа Из МассивИзменений Цикл

Если ТипЗнч(ПользовательИлиГруппа) = Тип("СправочникСсылка.Пользователи") Тогда

Если МассивИзмененийРазвернутый.Найти(ПользовательИлиГруппа) = Неопределено Тогда

МассивИзмененийРазвернутый.Добавить(ПользовательИлиГруппа);

КонецЕсли;

ИначеЕсли ТипЗнч(ПользовательИлиГруппа) = Тип("СправочникСсылка.ГруппыПользователей") Тогда

СоставГруппы = ДокументооборотПраваДоступаПовтИсп.ПолучитьСоставГруппыПользователей(ПользовательИлиГруппа);

Для Каждого Строка Из СоставГруппы Цикл

Если МассивИзмененийРазвернутый.Найти(Строка.Пользователь) = Неопределено Тогда

МассивИзмененийРазвернутый.Добавить(Строка.Пользователь);

КонецЕсли;

КонецЦикла;

КонецЕсли;

КонецЦикла;

УправлениеДоступом.ОбновитьРолиПользователей(МассивИзмененийРазвернутый);

КонецПроцедуры

Процедура ОбновитьПраваЗависимыхДанных(ОбъектСсылка)

ДокументооборотПраваДоступаПереопределяемый.ОбновитьПраваЗависимыхДанных(ОбъектСсылка);

КонецПроцедуры

Процедура ОбновитьПраваПустыхДескрипторов()

УстановитьПривилегированныйРежим(Истина);

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ РАЗЛИЧНЫЕ

| ПраваПоДескрипторамДоступа.Дескриптор

|ИЗ

| РегистрСведений.ПраваПоДескрипторамДоступа КАК ПраваПоДескрипторамДоступа

| ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.ДескрипторыДоступаОбъектов КАК ДескрипторыДоступаОбъектов

| ПО ПраваПоДескрипторамДоступа.Дескриптор = ДескрипторыДоступаОбъектов.Ссылка

|ГДЕ

| ДескрипторыДоступаОбъектов.ЭтоПустойДескриптор";

Результат = Запрос.Выполнить();

ВыборкаДетальныеЗаписи = Результат.Выбрать();

Пока ВыборкаДетальныеЗаписи.Следующий() Цикл

Немедленно = Не ДокументооборотПраваДоступаПовтИсп.ОтложенноеОбновлениеПравДоступа();

ОбновитьПраваДоступаПоДескриптору(ВыборкаДетальныеЗаписи.Дескриптор, Немедленно);

КонецЦикла;

КонецПроцедуры

// Возвращает Истина если переданная ссылка является ссылкой на любой бизнес-процесс

Функция ЭтоБизнесПроцесс(Ссылка)

МетаданныеОбъекта = Ссылка.Метаданные();

Возврат Метаданные.БизнесПроцессы.Содержит(МетаданныеОбъекта);

КонецФункции

// Обрабатывает запись набора записей РС ИсполнителиЗадач

Процедура ПриЗаписиИсполнителейЗадач(Источник)

Если Источник.Количество() = 0 Тогда

// Обработка удаления набора записей

РольИсполнителя = Источник.Отбор.РольИсполнителя.Значение;

ОсновнойОбъектАдресации = Источник.Отбор.ОсновнойОбъектАдресации.Значение;

ДополнительныйОбъектАдресации = Источник.Отбор.ДополнительныйОбъектАдресации.Значение;

// Поиск дескрипторов по ТЧ Пользователи

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ РАЗЛИЧНЫЕ

| ДескрипторыДоступаОбъектовПользователи.Ссылка

|ИЗ

| Справочник.ДескрипторыДоступаОбъектов.Пользователи КАК ДескрипторыДоступаОбъектовПользователи

|ГДЕ

| ДескрипторыДоступаОбъектовПользователи.Пользователь = &Пользователь

| И ДескрипторыДоступаОбъектовПользователи.ОсновнойОбъектАдресации = &ОсновнойОбъектАдресации

| И ДескрипторыДоступаОбъектовПользователи.ДополнительныйОбъектАдресации = &ДополнительныйОбъектАдресации";

Запрос.УстановитьПараметр("ДополнительныйОбъектАдресации", ДополнительныйОбъектАдресации);

Запрос.УстановитьПараметр("ОсновнойОбъектАдресации", ОсновнойОбъектАдресации);

Запрос.УстановитьПараметр("Пользователь", РольИсполнителя);

Результат = Запрос.Выполнить();

ВыборкаДетальныеЗаписи = Результат.Выбрать();

Пока ВыборкаДетальныеЗаписи.Следующий() Цикл

Справочники.ДескрипторыДоступаОбъектов.ОбновитьПрава(ВыборкаДетальныеЗаписи.Ссылка);

КонецЦикла;

// Поиск дескрипторов по ТЧ РабочаяГруппа

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ РАЗЛИЧНЫЕ

| ДескрипторыДоступаОбъектовРабочаяГруппа.Ссылка

|ИЗ

| Справочник.ДескрипторыДоступаОбъектов.РабочаяГруппа КАК ДескрипторыДоступаОбъектовРабочаяГруппа

|ГДЕ

| ДескрипторыДоступаОбъектовРабочаяГруппа.Участник = &Участник

| И ДескрипторыДоступаОбъектовРабочаяГруппа.ОсновнойОбъектАдресации = &ОсновнойОбъектАдресации

| И ДескрипторыДоступаОбъектовРабочаяГруппа.ДополнительныйОбъектАдресации = &ДополнительныйОбъектАдресации";

Запрос.УстановитьПараметр("ДополнительныйОбъектАдресации", ДополнительныйОбъектАдресации);

Запрос.УстановитьПараметр("ОсновнойОбъектАдресации", ОсновнойОбъектАдресации);

Запрос.УстановитьПараметр("Участник", РольИсполнителя);

Результат = Запрос.Выполнить();

ВыборкаДетальныеЗаписи = Результат.Выбрать();

Пока ВыборкаДетальныеЗаписи.Следующий() Цикл

Справочники.ДескрипторыДоступаОбъектов.ОбновитьПрава(ВыборкаДетальныеЗаписи.Ссылка);

КонецЦикла;

Иначе

// Обработка записи нового набора записей

Для каждого Эл Из Источник Цикл

РольИсполнителя = Эл.РольИсполнителя;

ОсновнойОбъектАдресации = Эл.ОсновнойОбъектАдресации;

ДополнительныйОбъектАдресации = Эл.ДополнительныйОбъектАдресации;

// Поиск дескрипторов по ТЧ Пользователи

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ РАЗЛИЧНЫЕ

| ДескрипторыДоступаОбъектовПользователи.Ссылка

|ИЗ

| Справочник.ДескрипторыДоступаОбъектов.Пользователи КАК ДескрипторыДоступаОбъектовПользователи

|ГДЕ

| ДескрипторыДоступаОбъектовПользователи.Пользователь = &Пользователь

| И ДескрипторыДоступаОбъектовПользователи.ОсновнойОбъектАдресации = &ОсновнойОбъектАдресации

| И ДескрипторыДоступаОбъектовПользователи.ДополнительныйОбъектАдресации = &ДополнительныйОбъектАдресации";

Запрос.УстановитьПараметр("ДополнительныйОбъектАдресации", ДополнительныйОбъектАдресации);

Запрос.УстановитьПараметр("ОсновнойОбъектАдресации", ОсновнойОбъектАдресации);

Запрос.УстановитьПараметр("Пользователь", РольИсполнителя);

Результат = Запрос.Выполнить();

ВыборкаДетальныеЗаписи = Результат.Выбрать();

Пока ВыборкаДетальныеЗаписи.Следующий() Цикл

Справочники.ДескрипторыДоступаОбъектов.ОбновитьПрава(ВыборкаДетальныеЗаписи.Ссылка);

КонецЦикла;

// Поиск дескрипторов по ТЧ РабочаяГруппа

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ РАЗЛИЧНЫЕ

| ДескрипторыДоступаОбъектовРабочаяГруппа.Ссылка

|ИЗ

| Справочник.ДескрипторыДоступаОбъектов.РабочаяГруппа КАК ДескрипторыДоступаОбъектовРабочаяГруппа

|ГДЕ

| ДескрипторыДоступаОбъектовРабочаяГруппа.Участник = &Участник

| И ДескрипторыДоступаОбъектовРабочаяГруппа.ОсновнойОбъектАдресации = &ОсновнойОбъектАдресации

| И ДескрипторыДоступаОбъектовРабочаяГруппа.ДополнительныйОбъектАдресации = &ДополнительныйОбъектАдресации";

Запрос.УстановитьПараметр("ДополнительныйОбъектАдресации", ДополнительныйОбъектАдресации);

Запрос.УстановитьПараметр("ОсновнойОбъектАдресации", ОсновнойОбъектАдресации);

Запрос.УстановитьПараметр("Участник", РольИсполнителя);

Результат = Запрос.Выполнить();

ВыборкаДетальныеЗаписи = Результат.Выбрать();

Пока ВыборкаДетальныеЗаписи.Следующий() Цикл

Справочники.ДескрипторыДоступаОбъектов.ОбновитьПрава(ВыборкаДетальныеЗаписи.Ссылка);

КонецЦикла;

КонецЦикла;

КонецЕсли;

КонецПроцедуры

// Обрабатывает запись набора записей РС СведенияОПользователях

Процедура ПриЗаписиСведенийОПользователях(Источник)

Если Константы.ДобавлятьРуководителямДоступПодчиненных.Получить() Тогда

Если Источник.ДополнительныеСвойства.Свойство("СтароеПодразделение") Тогда

// Если подразделение пользователя было изменено, то

// выполняется обновление прав, зависящих от пользователя

Немедленно = Не ДокументооборотПраваДоступаПовтИсп.ОтложенноеОбновлениеПравДоступа();

ЗначениеОтбора = Источник.Отбор.Пользователь.Значение;

Если ЗначениеЗаполнено(ЗначениеОтбора) Тогда

ОбновитьПраваПоПользователю(ЗначениеОтбора, Немедленно);

Иначе

Для каждого Эл Из Источник Цикл

ОбновитьПраваПоПользователю(Эл.Пользователь, Немедленно);

КонецЦикла;

КонецЕсли;

КонецЕсли;

КонецЕсли;

КонецПроцедуры

// Обрабатывает запись правообразующих констант

Процедура ПриЗаписиКонстанты(Источник)

Если ТипЗнч(Источник) = Тип("КонстантаМенеджерЗначения.ИспользоватьУчетПоОрганизациям") Тогда

// Обработка всех дескрипторов, у которых установлен реквизит Организация

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| ДескрипторыДоступаОбъектов.Ссылка

|ИЗ

| Справочник.ДескрипторыДоступаОбъектов КАК ДескрипторыДоступаОбъектов

|ГДЕ

| ДескрипторыДоступаОбъектов.Организация <> &ПустаяОрганизация";

Запрос.УстановитьПараметр("ПустаяОрганизация", Справочники.Организации.ПустаяСсылка());

Результат = Запрос.Выполнить();

ВыборкаДетальныеЗаписи = Результат.Выбрать();

Пока ВыборкаДетальныеЗаписи.Следующий() Цикл

Дескриптор = ВыборкаДетальныеЗаписи.Ссылка;

Справочники.ДескрипторыДоступаОбъектов.ОбновитьПрава(Дескриптор);

ОбновитьПраваСвязанныхДескрипторовПоДескриптору(Дескриптор);

КонецЦикла;

ИначеЕсли ТипЗнч(Источник) = Тип("КонстантаМенеджерЗначения.ИспользоватьГрифыДоступа") Тогда

// Обработка всех дескрипторов, у которых установлен реквизит ГрифДоступа

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| ДескрипторыДоступаОбъектов.Ссылка

|ИЗ

| Справочник.ДескрипторыДоступаОбъектов КАК ДескрипторыДоступаОбъектов

|ГДЕ

| ДескрипторыДоступаОбъектов.ГрифДоступа <> &ГрифДоступа";

Запрос.УстановитьПараметр("ГрифДоступа", Справочники.ГрифыДоступа.ПустаяСсылка());

Результат = Запрос.Выполнить();

ВыборкаДетальныеЗаписи = Результат.Выбрать();

Пока ВыборкаДетальныеЗаписи.Следующий() Цикл

Дескриптор = ВыборкаДетальныеЗаписи.Ссылка;

Справочники.ДескрипторыДоступаОбъектов.ОбновитьПрава(Дескриптор);

ОбновитьПраваСвязанныхДескрипторовПоДескриптору(Дескриптор);

КонецЦикла;

ИначеЕсли ТипЗнч(Источник) = Тип("КонстантаМенеджерЗначения.ИспользоватьВопросыДеятельности") Тогда

// Обработка всех дескрипторов, у которых установлен реквизит ВопросДеятельности

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| ДескрипторыДоступаОбъектов.Ссылка

|ИЗ

| Справочник.ДескрипторыДоступаОбъектов КАК ДескрипторыДоступаОбъектов

|ГДЕ

| ДескрипторыДоступаОбъектов.ВопросДеятельности <> &ВопросДеятельности";

Запрос.УстановитьПараметр("ВопросДеятельности", Справочники.ВопросыДеятельности.ПустаяСсылка());

Результат = Запрос.Выполнить();

ВыборкаДетальныеЗаписи = Результат.Выбрать();

Пока ВыборкаДетальныеЗаписи.Следующий() Цикл

Дескриптор = ВыборкаДетальныеЗаписи.Ссылка;

Справочники.ДескрипторыДоступаОбъектов.ОбновитьПрава(Дескриптор);

ОбновитьПраваСвязанныхДескрипторовПоДескриптору(Дескриптор);

КонецЦикла;

ИначеЕсли ТипЗнч(Источник) = Тип("КонстантаМенеджерЗначения.ИспользоватьВидыИсходящихДокументов") Тогда

// Обработка всех дескрипторов, у которых установлен реквизит ВидОбъекта

// типа Справочник.ВидыИсходящихДокументов

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| ДескрипторыДоступаОбъектов.Ссылка

|ИЗ

| Справочник.ДескрипторыДоступаОбъектов КАК ДескрипторыДоступаОбъектов

|ГДЕ

| ДескрипторыДоступаОбъектов.ВидОбъекта <> &ВидОбъекта

| И ТИПЗНАЧЕНИЯ(ДескрипторыДоступаОбъектов.ВидОбъекта) = ТИП(Справочник.ВидыИсходящихДокументов)";

Запрос.УстановитьПараметр("ВидОбъекта", Справочники.ВидыИсходящихДокументов.ПустаяСсылка());

Результат = Запрос.Выполнить();

ВыборкаДетальныеЗаписи = Результат.Выбрать();

Пока ВыборкаДетальныеЗаписи.Следующий() Цикл

Дескриптор = ВыборкаДетальныеЗаписи.Ссылка;

Справочники.ДескрипторыДоступаОбъектов.ОбновитьПрава(Дескриптор);

ОбновитьПраваСвязанныхДескрипторовПоДескриптору(Дескриптор);

КонецЦикла;

ИначеЕсли ТипЗнч(Источник) = Тип("КонстантаМенеджерЗначения.ИспользоватьВидыВходящихДокументов") Тогда

// Обработка всех дескрипторов, у которых установлен реквизит ВидОбъекта

// типа Справочник.ВидыВходящихДокументов

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| ДескрипторыДоступаОбъектов.Ссылка

|ИЗ

| Справочник.ДескрипторыДоступаОбъектов КАК ДескрипторыДоступаОбъектов

|ГДЕ

| ДескрипторыДоступаОбъектов.ВидОбъекта <> &ВидОбъекта

| И ТИПЗНАЧЕНИЯ(ДескрипторыДоступаОбъектов.ВидОбъекта) = ТИП(Справочник.ВидыВходящихДокументов)";

Запрос.УстановитьПараметр("ВидОбъекта", Справочники.ВидыВходящихДокументов.ПустаяСсылка());

Результат = Запрос.Выполнить();

ВыборкаДетальныеЗаписи = Результат.Выбрать();

Пока ВыборкаДетальныеЗаписи.Следующий() Цикл

Дескриптор = ВыборкаДетальныеЗаписи.Ссылка;

Справочники.ДескрипторыДоступаОбъектов.ОбновитьПрава(Дескриптор);

ОбновитьПраваСвязанныхДескрипторовПоДескриптору(Дескриптор);

КонецЦикла;

ИначеЕсли ТипЗнч(Источник) = Тип("КонстантаМенеджерЗначения.ИспользоватьВидыВнутреннихДокументов") Тогда

// Обработка всех дескрипторов, у которых установлен реквизит ВидОбъекта

// типа Справочник.ВидыВнутреннихДокументов

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| ДескрипторыДоступаОбъектов.Ссылка

|ИЗ

| Справочник.ДескрипторыДоступаОбъектов КАК ДескрипторыДоступаОбъектов

|ГДЕ

| ДескрипторыДоступаОбъектов.ВидОбъекта <> &ВидОбъекта

| И ТИПЗНАЧЕНИЯ(ДескрипторыДоступаОбъектов.ВидОбъекта) = ТИП(Справочник.ВидыВнутреннихДокументов)";

Запрос.УстановитьПараметр("ВидОбъекта", Справочники.ВидыВнутреннихДокументов.ПустаяСсылка());

Результат = Запрос.Выполнить();

ВыборкаДетальныеЗаписи = Результат.Выбрать();

Пока ВыборкаДетальныеЗаписи.Следующий() Цикл

Дескриптор = ВыборкаДетальныеЗаписи.Ссылка;

Справочники.ДескрипторыДоступаОбъектов.ОбновитьПрава(Дескриптор);

ОбновитьПраваСвязанныхДескрипторовПоДескриптору(Дескриптор);

КонецЦикла;

ИначеЕсли ТипЗнч(Источник) = Тип("КонстантаМенеджерЗначения.ДобавлятьРуководителямДоступПодчиненных") Тогда

// Обновление всех дескрипторов

// ДескрипторыДоступаОбъектов

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| ДескрипторыДоступаОбъектов.Ссылка

|ИЗ

| Справочник.ДескрипторыДоступаОбъектов КАК ДескрипторыДоступаОбъектов";

Результат = Запрос.Выполнить();

ВыборкаДетальныеЗаписи = Результат.Выбрать();

Пока ВыборкаДетальныеЗаписи.Следующий() Цикл

Справочники.ДескрипторыДоступаОбъектов.ОбновитьПрава(ВыборкаДетальныеЗаписи.Ссылка);

КонецЦикла;

// ДескрипторыДоступаРегистров

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| ДескрипторыДоступаРегистров.Ссылка

|ИЗ

| Справочник.ДескрипторыДоступаРегистров КАК ДескрипторыДоступаРегистров";

Результат = Запрос.Выполнить();

ВыборкаДетальныеЗаписи = Результат.Выбрать();

Пока ВыборкаДетальныеЗаписи.Следующий() Цикл

Справочники.ДескрипторыДоступаРегистров.ОбновитьПрава(ВыборкаДетальныеЗаписи.Ссылка);

КонецЦикла;

// ДескрипторыДоступаФайлов

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| ДескрипторыДоступаФайлов.Ссылка

|ИЗ

| Справочник.ДескрипторыДоступаФайлов КАК ДескрипторыДоступаФайлов";

Результат = Запрос.Выполнить();

ВыборкаДетальныеЗаписи = Результат.Выбрать();

Пока ВыборкаДетальныеЗаписи.Следующий() Цикл

Справочники.ДескрипторыДоступаФайлов.ОбновитьПрава(ВыборкаДетальныеЗаписи.Ссылка);

КонецЦикла;

КонецЕсли;

КонецПроцедуры

// Извлечь текст из файла и поместить в ХранилищеЗначения

Функция ИзвлечьТекстВХранилищеЗначения(ПолноеИмяФайла) Экспорт

Текст = "";

ИзвлекатьТекстыФайловНаСервере = Константы.ИзвлекатьТекстыФайловНаСервере.Получить();

Если Не ИзвлекатьТекстыФайловНаСервере Тогда

ТипПлатформыСервера = ОбщегоНазначенияПовтИсп.ТипПлатформыСервера();

Если ТипПлатформыСервера = ТипПлатформы.Windows_x86 ИЛИ ТипПлатформыСервера = ТипПлатформы.Windows_x86_64 Тогда

Текст = ФайловыеФункцииКлиентСервер.ИзвлечьТекст(ПолноеИмяФайла);

КонецЕсли;

КонецЕсли;

Если ПустаяСтрока(Текст) Тогда

Возврат "";

КонецЕсли;

ХранилищеЗначения = Новый ХранилищеЗначения(Текст);

Возврат ХранилищеЗначения;

КонецФункции

// Разыменовать lnk файл

Функция РазыменоватьLnkФайл(ВыбранныйФайл) Экспорт

ТипПлатформыСервера = ОбщегоНазначенияПовтИсп.ТипПлатформыСервера();

Если ТипПлатформыСервера = ТипПлатформы.Windows_x86 ИЛИ ТипПлатформыСервера = ТипПлатформы.Windows_x86_64 Тогда

ShellApp = Новый COMОбъект("shell.application");

FolderObj = ShellApp.NameSpace(ВыбранныйФайл.Путь); // полный (только) путь на lnk-файл

FolderObjItem = FolderObj.items().item(ВыбранныйФайл.Имя); // только имя lnk-файла

Link = FolderObjItem.GetLink();

Возврат Новый Файл(Link.path);

КонецЕсли;

Возврат ВыбранныйФайл;

КонецФункции

// Рекурсивная функция импорта файлов с диска - принимает массив файлов (или каталогов)

// - если файл, просто добавляет его, если каталог - создает группу и рекурсивно вызывает саму себя

Процедура ИмпортФайлов(

Владелец,

Путь,

ФайлыАргумент,

Индикатор,

МассивИменФайловСОшибками,

МассивСтруктурВсехФайлов,

Комментарий,

ХранитьВерсии,

Рекурсивно,

КоличествоСуммарное,

Счетчик,

ИдентификаторФормы,

Знач ПсевдоФайловаяСистема,

ДобавленныеФайлы,

МассивВсехПапок,

РежимЗагрузки,

Пользователь,

ПараметрыРаспознавания) Экспорт

Перем ПерваяПапкаСТакимЖеИменем;

Перем ДокГруппаСсылка;

МаксРазмерФайла = ФайловыеФункции.ПолучитьМаксимальныйРазмерФайла();

ЗапретЗагрузкиФайловПоРасширению = ФайловыеФункции.ПолучитьЗапретЗагрузкиФайловПоРасширению();

СписокЗапрещенныхРасширений = ФайловыеФункции.ПолучитьСписокЗапрещенныхРасширений();

Для Каждого ВыбранныйФайл Из ФайлыАргумент Цикл

Попытка

Если ВыбранныйФайл.Существует() Тогда

Если ВыбранныйФайл.Расширение = ".lnk" Тогда

ВыбранныйФайл = РазыменоватьLnkФайл(ВыбранныйФайл);

КонецЕсли;

Если ВыбранныйФайл.ЭтоКаталог() Тогда

Если Рекурсивно = Истина Тогда

НовыйПуть = Строка(ВыбранныйФайл.Путь);

ОбщегоНазначенияКлиентСервер.ДобавитьСлешЕслиНужно(НовыйПуть, ОбщегоНазначенияПовтИсп.ТипПлатформыСервера());

НовыйПуть = НовыйПуть + Строка(ВыбранныйФайл.Имя);

МассивФайлов = ФайловыеФункцииКлиентСервер.НайтиФайлыПсевдо(ПсевдоФайловаяСистема, НовыйПуть);

// Создаем группу в справочнике - эквивалент папки на диске

Если МассивФайлов.Количество() <> 0 Тогда

ИмяФайла = ВыбранныйФайл.Имя;

Если РаботаСФайламиВызовСервера.ЕстьПапкаСТакимИменем(ИмяФайла, Владелец, ПерваяПапкаСТакимЖеИменем) Тогда

ДокГруппаСсылка = ПерваяПапкаСТакимЖеИменем;

Иначе

ДокГруппаСсылка = РаботаСФайламиВызовСервера.СправочникиПапкиСоздатьЭлемент(ИмяФайла, Владелец, Пользователь);

КонецЕсли;

ИмпортФайлов(

ДокГруппаСсылка,

НовыйПуть,

МассивФайлов,

Индикатор,

МассивИменФайловСОшибками,

МассивСтруктурВсехФайлов,

Комментарий,

ХранитьВерсии,

Рекурсивно,

КоличествоСуммарное,

Счетчик,

ИдентификаторФормы,

ПсевдоФайловаяСистема,

ДобавленныеФайлы,

МассивВсехПапок,

РежимЗагрузки,

Пользователь,

ПараметрыРаспознавания);

МассивВсехПапок.Добавить(НовыйПуть);

КонецЕсли;

КонецЕсли;

Продолжить;

КонецЕсли;

Если Не ФайловыеФункцииКлиентСервер.ФайлМожноЗагружать(ВыбранныйФайл, МаксРазмерФайла, ЗапретЗагрузкиФайловПоРасширению, СписокЗапрещенныхРасширений, МассивИменФайловСОшибками) Тогда

Продолжить;

КонецЕсли;

// Создаем Элемент справочника Файлы

ИмяБезРасширения = ВыбранныйФайл.ИмяБезРасширения;

Расширение = ВыбранныйФайл.Расширение;

Если РежимЗагрузки Тогда

Если РаботаСФайламиВызовСервера.ЕстьФайлСТакимИменем(ИмяБезРасширения, Владелец) Тогда

Запись = Новый Структура;

Запись.Вставить("ИмяФайла", ВыбранныйФайл.ПолноеИмя);

ТекстОшибки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(

НСтр("ru = 'Файл с таким именем уже есть в информационной базе в папке ""%1""'"),

Строка(Владелец));

Запись.Вставить("Ошибка", ТекстОшибки);

МассивИменФайловСОшибками.Добавить(Запись);

Продолжить;

КонецЕсли;

КонецЕсли;

АдресВременногоХранилищаФайла = ВыбранныйФайл.ПолноеИмя;

АдресВременногоХранилищаТекста = ИзвлечьТекстВХранилищеЗначения(

ВыбранныйФайл.ПолноеИмя);

// Создаем элемент справочника Файлы

РаботаСФайламиКлиентСервер.СоздатьЭлементСправочникаФайлы(ВыбранныйФайл, МассивСтруктурВсехФайлов,

Владелец, ИдентификаторФормы, Комментарий, ХранитьВерсии, ДобавленныеФайлы,

АдресВременногоХранилищаФайла, АдресВременногоХранилищаТекста, Пользователь,

ПараметрыРаспознавания);

Иначе

Запись = Новый Структура;

Запись.Вставить("ИмяФайла", ВыбранныйФайл.ПолноеИмя);

Запись.Вставить("Ошибка", НСтр("ru = 'Файл отсутствует на диске'"));

МассивИменФайловСОшибками.Добавить(Запись);

КонецЕсли;

Исключение

ОшибкаИнфо = ИнформацияОбОшибке();

СообщениеОбОшибке = "";

Если ОшибкаИнфо.Причина = Неопределено Тогда

СообщениеОбОшибке =ОшибкаИнфо.Описание;

Иначе

СообщениеОбОшибке = ОшибкаИнфо.Причина.Описание;

КонецЕсли;

Запись = Новый Структура;

Запись.Вставить("ИмяФайла", ВыбранныйФайл.ПолноеИмя);

Запись.Вставить("Ошибка", СообщениеОбОшибке);

МассивИменФайловСОшибками.Добавить(Запись);

КонецПопытки;

КонецЦикла;

КонецПроцедуры

// Импорт - с вспомогательными операциями типа проверки предельного размера и впоследствии удаления файлов и показа ошибок

// при импорте только одной папки - вернет на нее ссылку

Функция ИмпортФайловВыполнить(

ПапкаДляДобавления,

ВыбранныеФайлы,

Комментарий,

ХранитьВерсии,

УдалятьФайлыПослеДобавления,

Рекурсивно,

ИдентификаторФормы,

Знач ПсевдоФайловаяСистема,

ДобавленныеФайлы,

РежимЗагрузки,

Пользователь,

МассивИменФайловСОшибками,

СтратегияРаспознавания,

ЯзыкРаспознавания) Экспорт

Перем ПерваяПапкаСТакимЖеИменем;

Перем ПапкаДляДобавленияТекущая;

ВыбранКаталог = Ложь;

Путь = "";

КоличествоСуммарное = 0;

МассивФайлов = Новый Массив;

Счетчик = 0;

Индикатор = 0;

МассивСтруктурВсехФайлов = Новый Массив;

МассивВсехПапок = Новый Массив;

ПапкаДляДобавленияТекущая = Неопределено;

// параметры распознавания по умолчанию

РаспознатьПослеДобавления = Истина;

Если СтратегияРаспознавания = Перечисления.СтратегииРаспознаванияТекста.НеРаспознавать Тогда

РаспознатьПослеДобавления = Ложь;

КонецЕсли;

ИспользоватьРаспознавание = РаботаСФайламиВызовСервера.ПолучитьИспользоватьРаспознавание();

Если ИспользоватьРаспознавание = Ложь Тогда

РаспознатьПослеДобавления = Ложь;

КонецЕсли;

ПараметрыРаспознавания = Новый Структура("СтратегияРаспознавания, ЯзыкРаспознавания, РаспознатьПослеДобавления",

СтратегияРаспознавания, ЯзыкРаспознавания, РаспознатьПослеДобавления);

Для Каждого ИмяФайла Из ВыбранныеФайлы Цикл

Попытка

ВыбранныйФайл = Новый Файл(ИмяФайла.Значение);

ВыбранКаталог = Ложь;

Если ВыбранныйФайл.Существует() Тогда

ВыбранКаталог = ВыбранныйФайл.ЭтоКаталог();

КонецЕсли;

Если ВыбранКаталог Тогда

Путь = ИмяФайла.Значение;

МассивФайловЭтогоКаталога = ФайловыеФункцииКлиентСервер.НайтиФайлыПсевдо(ПсевдоФайловаяСистема, Путь);

ИмяПапки = ВыбранныйФайл.Имя;

Если РаботаСФайламиВызовСервера.ЕстьПапкаСТакимИменем(ИмяПапки, ПапкаДляДобавления, ПерваяПапкаСТакимЖеИменем) Тогда

ПапкаДляДобавленияТекущая = ПерваяПапкаСТакимЖеИменем;

Иначе

ПапкаДляДобавленияТекущая = РаботаСФайламиВызовСервера.СправочникиПапкиСоздатьЭлемент(ИмяПапки, ПапкаДляДобавления, Пользователь);

КонецЕсли;

// Собственно импорт

ИмпортФайлов(

ПапкаДляДобавленияТекущая,

Путь,

МассивФайловЭтогоКаталога,

Индикатор,

МассивИменФайловСОшибками,

МассивСтруктурВсехФайлов,

Комментарий,

ХранитьВерсии,

Рекурсивно,

КоличествоСуммарное,

Счетчик,

ИдентификаторФормы,

ПсевдоФайловаяСистема,

ДобавленныеФайлы,

МассивВсехПапок,

РежимЗагрузки,

Пользователь,

ПараметрыРаспознавания);

МассивВсехПапок.Добавить(Путь);

Иначе

МассивФайлов.Добавить(ВыбранныйФайл);

КонецЕсли;

Исключение

// запись в журнал регистрации

ОписаниеОшибки = КраткоеПредставлениеОшибки(ИнформацияОбОшибке());

ТекстСообщения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(

НСтр("ru = 'Ошибка автоматической загрузки файлов: ""%1""'"),

ОписаниеОшибки);

ЗаписьЖурналаРегистрации("Автоматическая загрузка файлов",

УровеньЖурналаРегистрации.Ошибка, , ,

ТекстСообщения);

КонецПопытки;

КонецЦикла;

Если МассивФайлов.Количество() <> 0 Тогда

// Собственно импорт

ИмпортФайлов(

ПапкаДляДобавления,

Путь,

МассивФайлов,

Индикатор,

МассивИменФайловСОшибками,

МассивСтруктурВсехФайлов,

Комментарий,

ХранитьВерсии,

Рекурсивно,

КоличествоСуммарное,

Счетчик,

ИдентификаторФормы,

ПсевдоФайловаяСистема,

ДобавленныеФайлы,

МассивВсехПапок,

РежимЗагрузки,

Пользователь,

ПараметрыРаспознавания);

КонецЕсли;

Если УдалятьФайлыПослеДобавления = Истина Тогда

ФайловыеФункцииКлиентСервер.УдалитьФайлыПослеДобавления(МассивСтруктурВсехФайлов, МассивВсехПапок, РежимЗагрузки);

КонецЕсли;

// Вывод сообщений об ошибках

Для Каждого Выборка Из МассивИменФайловСОшибками Цикл

ТекстСообщения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(

НСтр("ru = 'Ошибка автоматической загрузки файла ""%1"": ""%2""'"),

Выборка.ИмяФайла, Выборка.Ошибка);

ЗаписьЖурналаРегистрации("Автоматическая загрузка файлов",

УровеньЖурналаРегистрации.Ошибка, , ,

ТекстСообщения);

КонецЦикла;

Если ВыбранныеФайлы.Количество() <> 1 Тогда

ПапкаДляДобавленияТекущая = Неопределено;

КонецЕсли;

Возврат ПапкаДляДобавленияТекущая;

КонецФункции

Функция ЕстьПравоДоступа(Пользователь, Папка)

// если не включена функциональная опция "использовать права доступа" - то не делаем проверки.

Если Не УправлениеДоступом.ОграничиватьДоступНаУровнеЗаписей() Тогда

Возврат Истина;

КонецЕсли;

Возврат ДокументооборотПраваДоступа.ПолучитьПраваПоОбъекту(Папка, Пользователь).Добавление;

КонецФункции

Процедура ЗагрузкаФайлов(МассивНастроек) Экспорт

Если ТипЗнч(МассивНастроек) <> Тип("Массив") Тогда

Возврат;

КонецЕсли;

Для Каждого Настройка Из МассивНастроек Цикл

КаталогНаДиске = "";

ТипПлатформыСервера = ОбщегоНазначенияПовтИсп.ТипПлатформыСервера();

Если ТипПлатформыСервера = ТипПлатформы.Windows_x86 ИЛИ ТипПлатформыСервера = ТипПлатформы.Windows_x86_64 Тогда

КаталогНаДиске = Настройка.КаталогWindows;

Иначе

КаталогНаДиске = Настройка.КаталогLinux;

КонецЕсли;

Папка = Настройка.Папка;

Пользователь = Настройка.Пользователь;

СтратегияРаспознавания = Неопределено;

ЯзыкРаспознавания = Неопределено;

Если Настройка.Свойство("СтратегияРаспознавания") Тогда

СтратегияРаспознавания = Настройка.СтратегияРаспознавания;

Иначе

СтратегияРаспознавания = Перечисления.СтратегииРаспознаванияТекста.ПоместитьТолькоВТекстовыйОбраз;

КонецЕсли;

Если Настройка.Свойство("ЯзыкРаспознавания") Тогда

ЯзыкРаспознавания = Настройка.ЯзыкРаспознавания;

Иначе

ЯзыкРаспознавания = РаботаСФайламиВызовСервера.ПолучитьЯзыкРаспознавания();

КонецЕсли;

Если ПустаяСтрока(КаталогНаДиске) Тогда

ЗаписьЖурналаРегистрации("Автоматическая загрузка файлов",

УровеньЖурналаРегистрации.Ошибка, , ,

НСтр("ru = 'Не указан каталог на диске'"));

Продолжить;

КонецЕсли;

ФайлКаталога = Новый Файл(КаталогНаДиске);

Если Не ФайлКаталога.Существует() Тогда

ТекстОшибки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(

НСтр("ru = 'Неверный путь к каталогу на диске: ""%1""'"),

КаталогНаДиске);

ЗаписьЖурналаРегистрации("Автоматическая загрузка файлов",

УровеньЖурналаРегистрации.Ошибка, , ,

ТекстОшибки);

Продолжить;

КонецЕсли;

Если Папка.Пустая() Тогда

ЗаписьЖурналаРегистрации("Автоматическая загрузка файлов",

УровеньЖурналаРегистрации.Ошибка, , ,

НСтр("ru = 'Не указана папка'"));

Продолжить;

КонецЕсли;

Если Пользователь.Пустая() Тогда

ЗаписьЖурналаРегистрации("Автоматическая загрузка файлов",

УровеньЖурналаРегистрации.Ошибка, , ,

НСтр("ru = 'Не указан пользователь'"));

Продолжить;

КонецЕсли;

Если Не ЕстьПравоДоступа(Пользователь, Папка) Тогда

ТекстОшибки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(

НСтр("ru = 'У пользователя ""%1"" нет прав на добавление файлов в папку ""%2""'"),

Пользователь, Папка);

ЗаписьЖурналаРегистрации("Автоматическая загрузка файлов",

УровеньЖурналаРегистрации.Ошибка, , ,

ТекстОшибки);

Продолжить;

КонецЕсли;

Попытка

ВыбранныеФайлы = Новый СписокЗначений;

НайденныеФайлы = НайтиФайлы(КаталогНаДиске, "*.*");

Для Каждого ФайлВложенный Из НайденныеФайлы Цикл

ВыбранныеФайлы.Добавить(ФайлВложенный.ПолноеИмя);

КонецЦикла;

ПсевдоФайловаяСистема = Новый Соответствие; // соответствие путь к директории - файлы и папки в ней

ДобавленныеФайлы = Новый Массив;

МассивИменФайловСОшибками = Новый Массив;

Описание = "";

ХранитьВерсии = Истина;

УдалятьФайлыПослеДобавления = Истина;

ПапкаДляДобавленияТекущая = ИмпортФайловВыполнить(

Папка,

ВыбранныеФайлы,

Описание,

ХранитьВерсии,

УдалятьФайлыПослеДобавления,

Истина,

Неопределено, //УникальныйИдентификатор,

ПсевдоФайловаяСистема,

ДобавленныеФайлы,

Истина, // режим загрузки

Пользователь,

МассивИменФайловСОшибками,

СтратегияРаспознавания,

ЯзыкРаспознавания);

ТекстСообщения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(

НСтр("ru = 'Закончена автоматическая загрузка файлов из каталога ""%1"" в папку ""%2"". Загружено файлов: %3. Не удалось загрузить файлов: %4.'"),

КаталогНаДиске, Папка, ДобавленныеФайлы.Количество(), МассивИменФайловСОшибками.Количество());

ЗаписьЖурналаРегистрации("Автоматическая загрузка файлов",

УровеньЖурналаРегистрации.Информация, , ,

ТекстСообщения);

Исключение

// запись в журнал регистрации

ОписаниеОшибки = КраткоеПредставлениеОшибки(ИнформацияОбОшибке());

ТекстСообщения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(

НСтр("ru = 'Ошибка автоматической загрузки файлов: ""%1"" из каталога ""%2"" в папку ""%3""'"),

ОписаниеОшибки, КаталогНаДиске, Папка);

ЗаписьЖурналаРегистрации("Автоматическая загрузка файлов",

УровеньЖурналаРегистрации.Ошибка, , ,

ТекстСообщения);

КонецПопытки;

КонецЦикла;

КонецПроцедуры

Процедура ЗаписатьСобытие(Задача, Событие, Комментарий = "") Экспорт

УстановитьПривилегированныйРежим(Истина);

МенеджерЗаписи = РегистрыСведений.ИсторияСобытийЗадач.СоздатьМенеджерЗаписи();

МенеджерЗаписи.Задача = Задача;

МенеджерЗаписи.ДатаСобытия = ТекущаяДата();

МенеджерЗаписи.Пользователь = ПараметрыСеанса.ТекущийПользователь;

МенеджерЗаписи.Событие = Событие;

МенеджерЗаписи.Комментарий = Комментарий;

МенеджерЗаписи.Записать();

КонецПроцедуры

Процедура ЗаписатьСобытиеОткрытаКарточка(Задача) Экспорт

ЗаписатьСобытие(Задача, Перечисления.ВидыСобытийЗадач.ОткрытаКарточка);

КонецПроцедуры

// Выводит состояние документа (проведен, не проведен, записан)

Процедура ОбновитьСостояниеДокумента(Ссылка, СостояниеДокумента, КартинкаСостоянияДокумента) Экспорт

Проведен = Ссылка.Проведен;

ПометкаУдаления = Ссылка.ПометкаУдаления;

РазрешеноПроведение = (Ссылка.Метаданные().Проведение = Метаданные.СвойстваОбъектов.Проведение.Разрешить);

Если ПометкаУдаления Тогда

СостояниеДокумента = "Помечен на удаление";

КартинкаСостоянияДокумента = 2;

ИначеЕсли Проведен Тогда

СостояниеДокумента = "Проведен";

КартинкаСостоянияДокумента = 1;

ИначеЕсли РазрешеноПроведение Тогда

СостояниеДокумента = "Не проведен";

КартинкаСостоянияДокумента = 0;

Иначе

СостояниеДокумента = "Записан";

КартинкаСостоянияДокумента = 3;

КонецЕсли;

КонецПроцедуры

// Продляет срок действия документов из регламентного задания

Процедура АвтоматическоеПродлениеДоговоров() Экспорт

УстановитьПривилегированныйРежим(Истина);

ДокументыОтветственных = Новый ТаблицаЗначений;

ДокументыОтветственных.Колонки.Добавить("Документ");

ДокументыОтветственных.Колонки.Добавить("Ответственный");

ДокументыОтветственных.Колонки.Добавить("СтараяДатаОкончания");

ДокументыОтветственных.Колонки.Добавить("НоваяДатаОкончания");

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| ВнутренниеДокументы.Ссылка,

| ВнутренниеДокументы.ПорядокПродления,

| ВнутренниеДокументы.Ответственный

|ИЗ

| Справочник.ВнутренниеДокументы КАК ВнутренниеДокументы

|ГДЕ

| ВнутренниеДокументы.ВидДокумента.УчитыватьСрокДействия

| И (НЕ ВнутренниеДокументы.Бессрочный)

| И ВнутренниеДокументы.ПорядокПродления В(&ПорядокПродления)

| И КОНЕЦПЕРИОДА(ВнутренниеДокументы.ДатаОкончанияДействия, ДЕНЬ) < &ТекущаяДата";

ПорядокПродления = Новый Массив;

ПорядокПродления.Добавить(Перечисления.ПорядокПродления.АвтоматическиНаМесяц);

ПорядокПродления.Добавить(Перечисления.ПорядокПродления.АвтоматическиНаКвартал);

ПорядокПродления.Добавить(Перечисления.ПорядокПродления.АвтоматическиНаПолугодие);

ПорядокПродления.Добавить(Перечисления.ПорядокПродления.АвтоматическиНаГод);

ПорядокПродления.Добавить(Перечисления.ПорядокПродления.АвтоматическиНаНеопределенныйСрок);

Запрос.УстановитьПараметр("ПорядокПродления", ПорядокПродления);

Запрос.УстановитьПараметр("ТекущаяДата", ТекущаяДата());

Выборка = Запрос.Выполнить().Выбрать();

Пока Выборка.Следующий() Цикл

Если Выборка.ПорядокПродления = Перечисления.ПорядокПродления.АвтоматическиНаМесяц Тогда

НаСрок = 1;

ИначеЕсли Выборка.ПорядокПродления = Перечисления.ПорядокПродления.АвтоматическиНаКвартал Тогда

НаСрок = 3;

ИначеЕсли Выборка.ПорядокПродления = Перечисления.ПорядокПродления.АвтоматическиНаПолугодие Тогда

НаСрок = 6;

ИначеЕсли Выборка.ПорядокПродления = Перечисления.ПорядокПродления.АвтоматическиНаГод Тогда

НаСрок = 12;

КонецЕсли;

Объект = Выборка.Ссылка.ПолучитьОбъект();

СтараяДатаОкончания = Объект.ДатаОкончанияДействия;

Если Выборка.ПорядокПродления = Перечисления.ПорядокПродления.АвтоматическиНаНеопределенныйСрок Тогда

Объект.ДатаОкончанияДействия = '00010101';

Объект.Бессрочный = Истина;

НоваяДатаОкончания = "Бессрочный";

Иначе

Если КонецДня(Объект.ДатаОкончанияДействия) = КонецМесяца(Объект.ДатаОкончанияДействия) Тогда

Объект.ДатаОкончанияДействия = КонецМесяца(ДобавитьМесяц(Объект.ДатаОкончанияДействия, НаСрок));

Иначе

Объект.ДатаОкончанияДействия = ДобавитьМесяц(Объект.ДатаОкончанияДействия, НаСрок);

КонецЕсли;

НоваяДатаОкончания = Объект.ДатаОкончанияДействия;

КонецЕсли;

ТекстСообщения = "";

Попытка

ЗаблокироватьДанныеДляРедактирования(Объект.Ссылка);

Объект.Записать();

// Записываем информацию о продлении в историю срока действия документа.

ПараметрыЗаписи = Новый Структура;

ПараметрыЗаписи.Вставить("Документ", Объект.Ссылка);

ПараметрыЗаписи.Вставить("ДатаНачалаДействия", Объект.ДатаНачалаДействия);

ПараметрыЗаписи.Вставить("ДатаОкончанияДействия", Объект.ДатаОкончанияДействия);

ПараметрыЗаписи.Вставить("Бессрочный", Объект.Бессрочный);

ПараметрыЗаписи.Вставить("ПорядокПродления", Объект.ПорядокПродления);

ПараметрыЗаписи.Вставить("ДокументИсточникИзменения", Неопределено);

ПараметрыЗаписи.Вставить("Комментарий", НСтр("ru = 'Срок действия документа автоматически продлен.'"));

РегистрыСведений.ИсторияСроковДействияДокументов.ДобавитьЗапись(ПараметрыЗаписи);

Исключение

ТекстСообщения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(

НСтр("ru = 'Ошибка при автоматическом продлении срока действия документа: %1.'"),

ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));

УровеньВажностиСобытия = УровеньЖурналаРегистрации.Ошибка;

КонецПопытки;

Если ПустаяСтрока(ТекстСообщения) Тогда

ТекстСообщения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(

НСтр("ru = 'Автоматически продлен срок действия документа до %1.'"),

Формат(НоваяДатаОкончания, "ДФ=dd.MM.yyyy"));

УровеньВажностиСобытия = УровеньЖурналаРегистрации.Информация;

Если ЗначениеЗаполнено(Выборка.Ответственный) Тогда

НоваяСтрока = ДокументыОтветственных.Добавить();

НоваяСтрока.Документ = Выборка.Ссылка;

НоваяСтрока.Ответственный = Выборка.Ответственный;

НоваяСтрока.СтараяДатаОкончания = СтараяДатаОкончания;

НоваяСтрока.НоваяДатаОкончания = НоваяДатаОкончания;

КонецЕсли;

КонецЕсли;

ЗаписьЖурналаРегистрации(НСтр("ru = 'Автоматическое продление договоров.'"), УровеньВажностиСобытия, Выборка.Ссылка.Метаданные(), Выборка.Ссылка, ТекстСообщения);

КонецЦикла;

// отправка уведомлений по почте

Ответственные = ДокументыОтветственных.Скопировать();

Ответственные.Свернуть("Ответственный");

Для Каждого Строка Из Ответственные Цикл

Ответственный = Строка.Ответственный;

ПочтовыйАдрес = УправлениеКонтактнойИнформацией.ПолучитьКонтактнуюИнформацияОбъекта(Ответственный, Справочники.ВидыКонтактнойИнформации.EmailПользователя);

Если ПустаяСтрока(ПочтовыйАдрес) Тогда

ТекстСообщения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(

НСтр("ru = 'Уведомление не было отправлено, так как у пользователя %1 не задан адрес электронной почты.'"),

Строка(Ответственный));

ЗаписьЖурналаРегистрации(НСтр("ru = 'Уведомление об автоматическом продлении договоров'"), УровеньЖурналаРегистрации.Информация,,, ТекстСообщения);

Продолжить;

КонецЕсли;

ПараметрыПисьма = Новый Структура;

ПараметрыПисьма.Вставить("Кому", ПочтовыйАдрес);

ТелоПисьма =

НСтр("ru = 'У следующих документов был автоматически продлен срок действия:

|

|'");

НайденныеСтроки = ДокументыОтветственных.НайтиСтроки(Новый Структура("Ответственный", Ответственный));

Для Каждого НайденнаяСтрока Из НайденныеСтроки Цикл

ТелоПисьма = ТелоПисьма

+ НайденнаяСтрока.Документ.Заголовок

+ ?(ЗначениеЗаполнено(НайденнаяСтрока.Документ.РегистрационныйНомер), " № " + НайденнаяСтрока.Документ.РегистрационныйНомер, "")

+ ?(ЗначениеЗаполнено(НайденнаяСтрока.Документ.ДатаРегистрации), " от " + Формат(НайденнаяСтрока.Документ.ДатаРегистрации,"ДФ=dd.MM.yyyy"), "")

+ ?(ЗначениеЗаполнено(НайденнаяСтрока.Документ.Корреспондент), ", корреспондент " + Строка(НайденнаяСтрока.Документ.Корреспондент), "")

+ НСтр("ru = ' - срок действия продлен до '") + Формат(НайденнаяСтрока.НоваяДатаОкончания, "ДФ=dd.MM.yyyy") + Символы.ПС;

КонецЦикла;

ПараметрыПисьма.Вставить("Текст", ТелоПисьма);

ТемаПисьма = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(

НСтр("ru = 'Автоматически продлены сроки действия документов (%1)'"),

НайденныеСтроки.Количество());

ПараметрыПисьма.Вставить("Тема", ТемаПисьма);

ТекстСообщения = "";

Попытка

ЛегкаяПочтаСервер.ОтправитьИнтернетПочта(ПараметрыПисьма);

Исключение

ТекстСообщения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(

НСтр("ru = 'Ошибка при отправке уведомления об автоматическом продлении договоров: %1.'"),

ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));

УровеньВажностиСобытия = УровеньЖурналаРегистрации.Ошибка;

КонецПопытки;

Если ПустаяСтрока(ТекстСообщения) Тогда

ТекстСообщения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(

НСтр("ru = 'Уведомление об автоматическом продлении договоров успешно отправлено на адрес %1.'"),

ПочтовыйАдрес);

УровеньВажностиСобытия = УровеньЖурналаРегистрации.Информация;

КонецЕсли;

ЗаписьЖурналаРегистрации(НСтр("ru = 'Автоматическое продление договоров'"), УровеньВажностиСобытия,,, ТекстСообщения);

КонецЦикла;

КонецПроцедуры

/////////////////////////////////////////////////////////////////////////////////////////

// РАБОТА С ИМЕНЕМ ФАЙЛА

// Возвращает структуру

// Результат (Структура)

// - Имя (Строка)

// - Расширение (Строка)

//

// Параметры:

// - ИмяФайла (Строка)

//

Функция РазложитьИмяФайла(ИмяФайла) Экспорт

Расширение = ИмяФайла;

Поз = Найти(Расширение, ".");

Если Поз = 0 Тогда

Возврат Новый Структура("Имя, Расширение", СокрЛП(ИмяФайла), "");

КонецЕсли;

Пока Поз > 0 Цикл

Расширение = Сред(Расширение, Поз + 1);

Поз = Найти(Расширение, ".");

КонецЦикла;

Имя = Лев(ИмяФайла, СтрДлина(ИмяФайла) - СтрДлина(Расширение) - 1);

Возврат Новый Структура("Имя, Расширение", СокрЛП(Имя), СокрЛП(Расширение));

КонецФункции

// Возвращает структуру

// Результат (Структура)

// - Каталог (Строка) - без последнего слеша

// - ИмяФайла (Строка) - имя файла с расширением

// - Имя (Строка)

// - Расширение (Строка) - без точки

//

// Параметры:

// - ПолноеИмяФайла (Строка)

//

Функция РазложитьПолноеИмяФайла(ПолноеИмяФайла) Экспорт

ИмяФайла = ПолноеИмяФайла;

Каталог = "";

Пока Истина Цикл

Поз = Макс(Найти(ИмяФайла, "\"), Найти(ИмяФайла, "/"));

Если Поз = 0 Тогда

Прервать;

КонецЕсли;

Каталог = Каталог + Лев(ИмяФайла, Поз);

ИмяФайла = Сред(ИмяФайла, Поз+1);

КонецЦикла;

ПоследнийСимволКаталога = Прав(Каталог, 1);

Если (ПоследнийСимволКаталога = "\") Или (ПоследнийСимволКаталога = "/") Тогда

Каталог = Лев(Каталог, СтрДлина(Каталог) - 1);

КонецЕсли;

ИияФайлаИнфо = РазложитьИмяФайла(ИмяФайла);

ИияФайлаИнфо.Вставить("ИмяФайла", ИмяФайла);

ИияФайлаИнфо.Вставить("Каталог", Каталог);

Возврат ИияФайлаИнфо;

КонецФункции

/////////////////////////////////////////////////////////////////////////////////////////

// РАБОТА С АДРЕСАМИ ЭЛЕКТРОННОЙ ПОЧТЫ

// Принимает строку почтовых адресов в виде

// "name1 <addr1@dom1>, name2 <addr2@dom2>, ..., nameN <addrN@domN>"

// или

// "name1 <addr1@dom1>; name2 <addr2@dom2>; ...; nameN <addrN@domN>"

// Возвращает:

// Результат (Массив)

// - Элемент (Структура)

// - Адрес (Строка)

// - Представление (Строка)

//

Функция РазложитьСтрокуПочтовыхАдресов(Знач ПочтовыеАдресаСтр) Экспорт

Результат = Новый Массив;

ПочтовыеАдресаСтр= СтрЗаменить(ПочтовыеАдресаСтр, ";", Символы.ПС);

ПочтовыеАдресаСтр = СтрЗаменить(ПочтовыеАдресаСтр, ",", Символы.ПС);

Для Счетчик = 1 По СтрЧислоСтрок(ПочтовыеАдресаСтр) Цикл

АдресСтр = СокрЛП(СтрПолучитьСтроку(ПочтовыеАдресаСтр, Счетчик));

Если ПустаяСтрока(АдресСтр) Тогда

Продолжить;

КонецЕсли;

АдресЭлектроннойПочтыИнфо = РазложитьПредставлениеАдресаЭлектроннойПочты(АдресСтр);

Результат.Добавить(АдресЭлектроннойПочтыИнфо);

КонецЦикла;

Возврат Результат;

КонецФункции

// Принимает строку почтового адреса в виде

// "name <addr@dom>"

// Возвращает:

// Результат (Структура)

// - Адрес (Строка) - addr@dom

// - ОтображаемоеИмя (Строка) - name

// - Пользователь (Строка)- addr

// - Домен (Строка) - dom

//

Функция РазложитьПредставлениеАдресаЭлектроннойПочты(Знач АдресЭлектроннойПочтыСтр) Экспорт

Результат = Новый Структура("Адрес, ОтображаемоеИмя, Пользователь, Домен", "", "", "", "");

АдресЭлектроннойПочтыСтр = СокрЛП(АдресЭлектроннойПочтыСтр);

Поз = Найти(АдресЭлектроннойПочтыСтр, "<");

Результат.ОтображаемоеИмя = "";

Результат.Адрес = АдресЭлектроннойПочтыСтр;

Если Поз > 0 Тогда

Результат.ОтображаемоеИмя = СокрЛП(Лев(АдресЭлектроннойПочтыСтр, Поз - 1));

АдресЭлектроннойПочтыСтр = Сред(АдресЭлектроннойПочтыСтр, Поз + 1);

Поз = Найти(АдресЭлектроннойПочтыСтр, ">");

Если Поз > 0 Тогда

Результат.Адрес = СокрЛП(Лев(АдресЭлектроннойПочтыСтр, Поз - 1));

Иначе

Результат.Адрес = "";

КонецЕсли;

КонецЕсли;

Если Не ЭтоАдресЭлектроннойПочты(Результат.Адрес) Тогда

Результат.Адрес = "";

Иначе

Поз = Найти(Результат.Адрес, "@");

Результат.Пользователь = Лев(Результат.Адрес, Поз - 1);

Результат.Домен = Сред(Результат.Адрес, Поз + 1);

КонецЕсли;

Возврат Результат;

КонецФункции

// Проверяет строку на формат адреса электронной почты

// проверка не точная но основные элементы на месте

//

Функция ЭтоАдресЭлектроннойПочты(АдресЭлектроннойПочты) Экспорт

Поз = Найти(АдресЭлектроннойПочты, "@");

Если Поз = 0 Тогда

Возврат Ложь;

КонецЕсли;

Если СтрЧислоВхождений(АдресЭлектроннойПочты, "@") <> 1 Тогда

Возврат Ложь;

КонецЕсли;

Если Прав(АдресЭлектроннойПочты, 1) = "."

Или Лев(АдресЭлектроннойПочты, 1) = "." Тогда

Возврат Ложь;

КонецЕсли;

Если Найти(АдресЭлектроннойПочты, "..") > 0 Тогда

Возврат Ложь;

КонецЕсли;

ДопустимыеСимволы = "-.0123456789@ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz";

Для НомерСимвола = 1 По СтрДлина(АдресЭлектроннойПочты) Цикл

Если Найти(ДопустимыеСимволы, Сред(АдресЭлектроннойПочты, НомерСимвола, 1)) = 0 Тогда

Возврат Ложь;

КонецЕсли;

КонецЦикла;

Пользователь = Лев(АдресЭлектроннойПочты, Поз - 1);

Если СтрДлина(Пользователь) = 0 Тогда

Возврат Ложь;

КонецЕсли;

Сервер = Сред(АдресЭлектроннойПочты, Поз + 1);

Если СтрДлина(Сервер) = 0 Тогда

Возврат Ложь;

КонецЕсли;

Поз = Найти(Сервер, ".");

Если Поз = 0 Тогда

Возврат Ложь;

КонецЕсли;

Возврат Истина;

КонецФункции

//Формирует представление адресата электронной почты

//

//Параметры

// Имя - Строка - имя адресата

// Адрес - Строка - адрес электронной почты адресата

// Контакт - СправочникСсылка - контакт, которому принадлежит имя и адрес почты.

//

// Результат (Строка) - "Имя <Адрес>" или "Адрес"

//

Функция ПолучитьПредставлениеАдресаЭлектроннойПочты(Имя, Адрес) Экспорт

Если ПустаяСтрока(Имя) Или Имя = Адрес Тогда

Результат = Адрес;

ИначеЕсли ПустаяСтрока(Адрес) Тогда

Результат = Имя;

Иначе

Результат = Имя + " <" + Адрес + ">";

КонецЕсли;

Возврат Результат;

КонецФункции

/////////////////////////////////////////////////////////////////////////////////////////

// РАБОТА С ТЕКСТОМ

// Удаляет недопустимые символы в XML-строке

// Параметры:

// - Текст (Строка)

// - СимволЗамены (Строка)

//

// Результат (Строка)

//

Функция УдалитьНедопустимыеСимволыXML(Знач Текст) Экспорт

#Если Не ВебКлиент Тогда

ПозицияНачала = 1;

Пока Истина Цикл

Если ПозицияНачала > СтрДлина(Текст) Тогда

Прервать;

КонецЕсли;

Позиция = НайтиНедопустимыеСимволыXML(Текст, ПозицияНачала);

Если Позиция = 0 Тогда

Прервать;

КонецЕсли;

// Если возращается позиция, больше чем должна быть, то корректируем ее.

Если Позиция > 1 Тогда

НедопустимыйСимвол = Сред(Текст, Позиция - 1, 1);

Если НайтиНедопустимыеСимволыXML(НедопустимыйСимвол) > 0 Тогда

Текст = СтрЗаменить(Текст, НедопустимыйСимвол, "");

КонецЕсли;

КонецЕсли;

НедопустимыйСимвол = Сред(Текст, Позиция, 1);

Если НайтиНедопустимыеСимволыXML(НедопустимыйСимвол) > 0 Тогда

Текст = СтрЗаменить(Текст, НедопустимыйСимвол, "");

КонецЕсли;

ПозицияНачала = Макс(1, Позиция - 1);

КонецЦикла;

#КонецЕсли

Возврат Текст;

КонецФункции

// Удаляет пустые строки в тексте.

//

Процедура УдалитьПустыеСтроки(Текст) Экспорт

Результат = "";

Для Индекс = 1 По СтрЧислоСтрок(Текст) Цикл

Строка = СтрПолучитьСтроку(Текст, Индекс);

Если ЗначениеЗаполнено(Строка) Тогда

ДобавитьЗначениеКСтрокеЧерезРазделитель(

Результат,

Символы.ПС,

Строка);

КонецЕсли;

КонецЦикла;

Текст = Результат;

КонецПроцедуры

// Добавляет к каждой строке спереди символ квотирования.

//

Процедура ДобавитьКвотирование(Текст, Знач СимволКвотирования) Экспорт

Результат = "";

Для Индекс = 1 По СтрЧислоСтрок(Текст) Цикл

Строка = СтрПолучитьСтроку(Текст, Индекс);

ДобавитьЗначениеКСтрокеЧерезРазделитель(

Результат,

Символы.ПС,

СимволКвотирования + Строка);

КонецЦикла;

Текст = Результат;

КонецПроцедуры

// Заменяет в переданном тексте ошибочные последовательности переноса строк.

// Все последовательности [ВК]+ПС заменяются на ВК+ПС.

// Все одиночные символы ВК заменяются на ВК+ПС.

//

Процедура ИсправитьПереносыСтрок(Текст) Экспорт

Пока Найти(Текст, Символы.ВК + Символы.ПС) > 0 Цикл

Текст = СтрЗаменить(Текст, Символы.ВК + Символы.ПС, Символы.ПС);

КонецЦикла;

Если Найти(Текст, Символы.ВК) > 0 Тогда

Текст = СтрЗаменить(Текст, Символы.ВК, Символы.ПС);

КонецЕсли;

КонецПроцедуры

/////////////////////////////////////////////////////////////////////////////////////////

// РАБОТА С ПРЕДСТАВЛЕНИЕМ РАЗМЕРОВ

// Принимает размер в байтах.

// Возвращает строку, например: 7.2 Кбайт, 35 Кбайт, 5.5 Мбайт, 12 Мбайт

Функция ПолучитьРазмерСтрокой(Размер) Экспорт

Если Размер = 0 Тогда

Возврат "-";

ИначеЕсли Размер < 1024 * 10 Тогда // < 10 Кб

Возврат СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(

НСтр("ru = '%1 Кб'"),

Формат(Макс(1, Окр(Размер / 1024, 1, 1)), "ЧГ=0"));

ИначеЕсли Размер < 1024 * 1024 Тогда // < 1 Мб

Возврат СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(

НСтр("ru = '%1 Кб'"),

Формат(Цел(Размер / 1024), "ЧГ=0"));

ИначеЕсли Размер < 1024 * 1024 * 10 Тогда // < 10 Мб

Возврат СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(

НСтр("ru = '%1 Мб'"),

Формат(Окр(Размер / 1024 / 1024, 1, 1), "ЧГ=0"));

Иначе // >= 10 Мб

Возврат СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(

НСтр("ru = '%1 Мб'"),

Формат(Цел(Размер / 1024 / 1024), "ЧГ=0"));

КонецЕсли;

КонецФункции

/////////////////////////////////////////////////////////////////////////////////////////

// РАБОТА С КОДИРОВКАМИ

// Функция возвращает таблицу имен кодировок

// Возвращаемое значение:

// Результат (СписокЗначений)

// - Значение (Строка) - например "ibm852"

// - Представление (Строка) - например "ibm852 (Центральноевропейская DOS)"

//

Функция ПолучитьСписокКодировок() Экспорт

СписокКодировок = Новый СписокЗначений;

СписокКодировок.Добавить("ibm852", "IBM852 (Центральноевропейская DOS)");

СписокКодировок.Добавить("ibm866", "IBM866 (Кириллица DOS)");

СписокКодировок.Добавить("iso-8859-1", "ISO-8859-1 (Западноевропейская ISO)");

СписокКодировок.Добавить("iso-8859-2", "ISO-8859-2 (Центральноевропейская ISO)");

СписокКодировок.Добавить("iso-8859-3", "ISO-8859-3 (Латиница 3 ISO)");

СписокКодировок.Добавить("iso-8859-4", "ISO-8859-4 (Балтийская ISO)");

СписокКодировок.Добавить("iso-8859-5", "ISO-8859-5 (Кириллица ISO)");

СписокКодировок.Добавить("iso-8859-7", "ISO-8859-7 (Греческая ISO)");

СписокКодировок.Добавить("iso-8859-9", "ISO-8859-9 (Турецкая ISO)");

СписокКодировок.Добавить("iso-8859-15", "ISO-8859-15 (Латиница 9 ISO)");

СписокКодировок.Добавить("koi8-r", "KOI8-R (Кириллица KOI8-R)");

СписокКодировок.Добавить("koi8-u", "KOI8-U (Кириллица KOI8-U)");

СписокКодировок.Добавить("us-ascii", "US-ASCII США");

СписокКодировок.Добавить("utf-8", "UTF-8 (Юникод UTF-8)");

СписокКодировок.Добавить("windows-1250", "Windows-1250 (Центральноевропейская Windows)");

СписокКодировок.Добавить("windows-1251", "windows-1251 (Кириллица Windows)");

СписокКодировок.Добавить("windows-1252", "Windows-1252 (Западноевропейская Windows)");

СписокКодировок.Добавить("windows-1253", "Windows-1253 (Греческая Windows)");

СписокКодировок.Добавить("windows-1254", "Windows-1254 (Турецкая Windows)");

СписокКодировок.Добавить("windows-1257", "Windows-1257 (Балтийская Windows)");

Возврат СписокКодировок;

КонецФункции

/////////////////////////////////////////////////////////////////////////////////////////

// ПРОЧИЕ ФУНКЦИИ

// Выделяет продстроку в скобках.

// Напрмер: ВыделитьПодстрокуВСкобках("Name <name@company.ru>", "<", ">") = "name@company.ru"

//

Функция ВыделитьПодстрокуВСкобках(Знач Строка, Знач ЛеваяСкобка, Знач ПраваяСкобка) Экспорт

Поз = Найти(Строка, ЛеваяСкобка);

Если Поз <> 0 Тогда

Строка = Сред(Строка, Поз+1);

КонецЕсли;

Поз = Найти(Строка, ПраваяСкобка);

Если Поз <> 0 Тогда

Строка = Лев(Строка, Поз-1);

КонецЕсли;

Возврат Строка;

КонецФункции

// Ищет подстроку в строке, после указанной позиции

//

Функция НайтиПосле(Строка, Подстрока, НачальнаяПозиция = 0) Экспорт

Позиция = Найти(Сред(Строка, НачальнаяПозиция + 1), Подстрока);

Если Позиция = 0 Тогда

Возврат 0;

КонецЕсли;

Возврат НачальнаяПозиция + Позиция;

КонецФункции

Функция ПолучитьСвязанныйДокумент(Документ, Знач ТипСвязи) Экспорт

Если ТипЗнч(ТипСвязи) = Тип("Строка") Тогда

ТипСвязи = Справочники.ТипыСвязей[ТипСвязи];

КонецЕсли;

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ РАЗРЕШЕННЫЕ ПЕРВЫЕ 1

| СвязиДокументов.СвязанныйДокумент,

| СвязиДокументов.Комментарий,

| СвязиДокументов.Установил,

| СвязиДокументов.ДатаУстановки

|ИЗ

| РегистрСведений.СвязиДокументов КАК СвязиДокументов

|ГДЕ

| СвязиДокументов.Документ = &Документ

| И СвязиДокументов.ТипСвязи = &ТипСвязи";

Запрос.УстановитьПараметр("Документ", Документ);

Запрос.УстановитьПараметр("ТипСвязи", ТипСвязи);

Результат = Запрос.Выполнить();

Если Результат.Пустой() Тогда

Возврат Неопределено;

КонецЕсли;

Выборка = Результат.Выбрать();

Выборка.Следующий();

Возврат Выборка.СвязанныйДокумент;

КонецФункции

Функция ПолучитьСвязанныеДокументы(Документ, Знач ТипСвязи) Экспорт

Если ТипЗнч(ТипСвязи) = Тип("Строка") Тогда

ТипСвязи = Справочники.ТипыСвязей[ТипСвязи];

КонецЕсли;

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ РАЗРЕШЕННЫЕ

| СвязиДокументов.СвязанныйДокумент,

| СвязиДокументов.Комментарий,

| СвязиДокументов.Установил,

| СвязиДокументов.ДатаУстановки

|ИЗ

| РегистрСведений.СвязиДокументов КАК СвязиДокументов

|ГДЕ

| СвязиДокументов.Документ = &Документ

| И СвязиДокументов.ТипСвязи = &ТипСвязи";

Запрос.УстановитьПараметр("Документ", Документ);

Запрос.УстановитьПараметр("ТипСвязи", ТипСвязи);

Возврат Запрос.Выполнить().Выгрузить().ВыгрузитьКолонку("СвязанныйДокумент");

КонецФункции

Процедура СоздатьНастройкуСвязи(

ТипСвязи,

СсылкаИз,

СсылкаНа,

ХарактерСвязи,

ТипОбратнойСвязи = Неопределено,

ХарактерОбратнойСвязи = Неопределено,

Предопределенная = Ложь,

Комментарий = "") Экспорт

МенеджерЗаписи = РегистрыСведений.НастройкаСвязей.СоздатьМенеджерЗаписи();

МенеджерЗаписи.ТипСвязи = ТипСвязи;

МенеджерЗаписи.СсылкаИз = СсылкаИз;

МенеджерЗаписи.СсылкаНа = СсылкаНа;

МенеджерЗаписи.ХарактерСвязи = ХарактерСвязи;

МенеджерЗаписи.ТипОбратнойСвязи = ТипОбратнойСвязи;

МенеджерЗаписи.ХарактерОбратнойСвязи = ХарактерОбратнойСвязи;

МенеджерЗаписи.Предопределенная = Предопределенная;

МенеджерЗаписи.Комментарий = Комментарий;

МенеджерЗаписи.Записать();

Если ЗначениеЗаполнено(ТипОбратнойСвязи) Тогда

МенеджерЗаписи = РегистрыСведений.НастройкаСвязей.СоздатьМенеджерЗаписи();

МенеджерЗаписи.ТипСвязи = ТипОбратнойСвязи ;

МенеджерЗаписи.СсылкаИз = СсылкаНа;

МенеджерЗаписи.СсылкаНа = СсылкаИз;

МенеджерЗаписи.ХарактерСвязи = ХарактерОбратнойСвязи;

МенеджерЗаписи.ТипОбратнойСвязи = ТипСвязи;

МенеджерЗаписи.ХарактерОбратнойСвязи = ХарактерСвязи;

МенеджерЗаписи.Предопределенная = Предопределенная;

МенеджерЗаписи.Комментарий = Комментарий;

МенеджерЗаписи.Записать();

КонецЕсли;

КонецПроцедуры

Процедура СоздатьСвязь(

Документ,

СвязанныйДокумент,

ТипСвязи,

Установил = Неопределено,

ДатаУстановки = Неопределено,

Комментарий = "",

Порядок = 0) Экспорт

НачатьТранзакцию();

Попытка

МенеджерЗаписи = РегистрыСведений.СвязиДокументов.СоздатьМенеджерЗаписи();

МенеджерЗаписи.Документ = Документ;

МенеджерЗаписи.СвязанныйДокумент = СвязанныйДокумент;

МенеджерЗаписи.ТипСвязи = ТипСвязи;

МенеджерЗаписи.Комментарий = Комментарий;

МенеджерЗаписи.Порядок = Порядок;

Если Установил = Неопределено Тогда

МенеджерЗаписи.Установил = ОбщегоНазначения.ТекущийПользователь();

Иначе

МенеджерЗаписи.Установил = Установил;

КонецЕсли;

Если ДатаУстановки = Неопределено Тогда

МенеджерЗаписи.ДатаУстановки = ТекущаяДата();

Иначе

МенеджерЗаписи.ДатаУстановки = ДатаУстановки;

КонецЕсли;

МенеджерЗаписи.Записать();

НастройкаСвязи = ПолучитьНастройкуСвязи(Документ, СвязанныйДокумент, ТипСвязи);

Если НастройкаСвязи = Неопределено Тогда

ТекстСообщения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(

НСтр("ru = 'Тип связи %1 не настроен для %2'"), Строка(ТипСвязи), Строка(СвязанныйДокумент));

ВызватьИсключение ТекстСообщения;

КонецЕсли;

Если ЗначениеЗаполнено(НастройкаСвязи.ТипОбратнойСвязи) Тогда

МенеджерОбратнойЗаписи = РегистрыСведений.СвязиДокументов.СоздатьМенеджерЗаписи();

МенеджерОбратнойЗаписи.Документ = МенеджерЗаписи.СвязанныйДокумент;

МенеджерОбратнойЗаписи.СвязанныйДокумент = МенеджерЗаписи.Документ;

МенеджерОбратнойЗаписи.ТипСвязи = НастройкаСвязи.ТипОбратнойСвязи;

МенеджерОбратнойЗаписи.Установил = МенеджерЗаписи.Установил;

МенеджерОбратнойЗаписи.ДатаУстановки = МенеджерЗаписи.ДатаУстановки;

МенеджерОбратнойЗаписи.Комментарий = МенеджерЗаписи.Комментарий;

МенеджерОбратнойЗаписи.Порядок = МенеджерЗаписи.Порядок;

МенеджерОбратнойЗаписи.Записать();

КонецЕсли;

ЗафиксироватьТранзакцию();

Исключение

ОтменитьТранзакцию();

ВызватьИсключение;

КонецПопытки;

КонецПроцедуры

Процедура УдалитьСвязь(Документ, СвязанныйДокумент, ТипСвязи) Экспорт

МенеджерЗаписи = РегистрыСведений.СвязиДокументов.СоздатьМенеджерЗаписи();

МенеджерЗаписи.Документ = Документ;

МенеджерЗаписи.СвязанныйДокумент = СвязанныйДокумент;

МенеджерЗаписи.ТипСвязи = ТипСвязи;

МенеджерЗаписи.Удалить();

НастройкаСвязи = ПолучитьНастройкуСвязи(Документ, СвязанныйДокумент, ТипСвязи);

Если НастройкаСвязи = Неопределено Тогда

ТекстСообщения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(

НСтр("ru = 'Тип связи %1 не настроен для %2'"), Строка(ТипСвязи), Строка(СвязанныйДокумент));

ВызватьИсключение ТекстСообщения;

КонецЕсли;

Если ЗначениеЗаполнено(НастройкаСвязи.ТипОбратнойСвязи) Тогда

МенеджерЗаписи = РегистрыСведений.СвязиДокументов.СоздатьМенеджерЗаписи();

МенеджерЗаписи.Документ = СвязанныйДокумент;

МенеджерЗаписи.СвязанныйДокумент = Документ;

МенеджерЗаписи.ТипСвязи = НастройкаСвязи.ТипОбратнойСвязи;

МенеджерЗаписи.Удалить();

КонецЕсли;

КонецПроцедуры

Процедура УстановитьКомментарийТипаСвязи(ТипСвязи, Комментарий) Экспорт

ТипСвязиОбъект = ТипСвязи.ПолучитьОбъект();

ТипСвязиОбъект.Комментарий = Комментарий;

ТипСвязиОбъект.Записать();

КонецПроцедуры

Функция ПолучитьРодителей(Элемент) Экспорт

Родители = Новый Массив;

ТекущийРодитель = Элемент.Родитель;

Пока Не ТекущийРодитель.Пустая() Цикл

Родители.Добавить(ТекущийРодитель);

ТекущийРодитель = ТекущийРодитель.Родитель;

КонецЦикла;

Возврат Родители;

КонецФункции

Функция ПолучитьНастройкуСвязи(Документ, СвязанныйДокумент, ТипСвязи) Экспорт

СтруктураВозврата = Новый Структура("ТипСвязи, СсылкаИз, СсылкаНа, ТипОбратнойСвязи, ХарактерСвязи, ХарактерОбратнойСвязи");

НастройкиСвязи = Новый ТаблицаЗначений;

НастройкиСвязи.Колонки.Добавить("ТипСвязи");

НастройкиСвязи.Колонки.Добавить("СсылкаИз");

НастройкиСвязи.Колонки.Добавить("УровеньСсылкаИз");

НастройкиСвязи.Колонки.Добавить("СсылкаНа");

НастройкиСвязи.Колонки.Добавить("УровеньСсылкаНа");

НастройкиСвязи.Колонки.Добавить("Уровень");

НастройкиСвязи.Колонки.Добавить("ХарактерСвязи");

НастройкиСвязи.Колонки.Добавить("ТипОбратнойСвязи");

НастройкиСвязи.Колонки.Добавить("ХарактерОбратнойСвязи");

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| НастройкаСвязей.ТипСвязи,

| НастройкаСвязей.СсылкаИз,

| НастройкаСвязей.СсылкаНа,

| НастройкаСвязей.ХарактерСвязи,

| НастройкаСвязей.ТипОбратнойСвязи,

| НастройкаСвязей.ХарактерОбратнойСвязи,

| НастройкаСвязей.Комментарий

|ИЗ

| РегистрСведений.НастройкаСвязей КАК НастройкаСвязей

|ГДЕ

| НастройкаСвязей.ТипСвязи = &ТипСвязи";

Запрос.УстановитьПараметр("ТипСвязи", ТипСвязи);

Если ТипЗнч(Документ) = Тип("СправочникСсылка.Файлы") Тогда

Запрос.Текст = Запрос.Текст +

" И (ТИПЗНАЧЕНИЯ(НастройкаСвязей.СсылкаИз) = ТИПЗНАЧЕНИЯ(&Документ)) ";

Запрос.УстановитьПараметр("Документ", Документ);

Иначе

Запрос.Текст = Запрос.Текст +

" И (НастройкаСвязей.СсылкаИз = &ВидДокумента

| ИЛИ НастройкаСвязей.СсылкаИз В (&Родители)

| ИЛИ НастройкаСвязей.СсылкаИз = &ПустаяСсылка) ";

ВидДокументаСсылкаИз = Документ.ВидДокумента;

ПустаяСсылкаИз = Справочники[ВидДокументаСсылкаИз.Метаданные().Имя].ПустаяСсылка();

РодителиСсылкаИз = ПолучитьРодителей(ВидДокументаСсылкаИз);

Запрос.УстановитьПараметр("ВидДокумента", ВидДокументаСсылкаИз);

Запрос.УстановитьПараметр("Родители", РодителиСсылкаИз);

Запрос.УстановитьПараметр("ПустаяСсылка", ПустаяСсылкаИз);

КонецЕсли;

Если ТипЗнч(СвязанныйДокумент) = Тип("Строка")

Или ТипЗнч(СвязанныйДокумент) = Тип("СправочникСсылка.Файлы") Тогда

Запрос.Текст = Запрос.Текст +

" И (ТИПЗНАЧЕНИЯ(НастройкаСвязей.СсылкаНа) = ТИПЗНАЧЕНИЯ(&СвязанныйДокумент)) ";

Запрос.УстановитьПараметр("СвязанныйДокумент", СвязанныйДокумент);

Иначе

Запрос.Текст = Запрос.Текст +

" И (НастройкаСвязей.СсылкаНа = &ВидДокументаСсылкаНа

| ИЛИ НастройкаСвязей.СсылкаНа В (&РодителиСсылкаНа)

| ИЛИ НастройкаСвязей.СсылкаНа = &ПустаяСсылкаНа) ";

ВидДокументаСсылкаНа = СвязанныйДокумент.ВидДокумента;

РодителиСсылкаНа = ПолучитьРодителей(ВидДокументаСсылкаНа);

ПустаяСсылкаНа = Справочники[ВидДокументаСсылкаНа.Метаданные().Имя].ПустаяСсылка();

Запрос.УстановитьПараметр("ВидДокументаСсылкаНа", ВидДокументаСсылкаНа);

Запрос.УстановитьПараметр("РодителиСсылкаНа", РодителиСсылкаНа);

Запрос.УстановитьПараметр("ПустаяСсылкаНа", ПустаяСсылкаНа);

КонецЕсли;

Выборка = Запрос.Выполнить().Выбрать();

Пока Выборка.Следующий() Цикл

НоваяСтрока = НастройкиСвязи.Добавить();

НоваяСтрока.ТипСвязи = Выборка.ТипСвязи;

НоваяСтрока.СсылкаИз = Выборка.СсылкаИз;

НоваяСтрока.СсылкаНа = Выборка.СсылкаНа;

Если ТипЗнч(Выборка.СсылкаИз) = Тип("СправочникСсылка.Файлы") Тогда

НоваяСтрока.УровеньСсылкаИз = 0;

Иначе

Если Выборка.СсылкаИз = ВидДокументаСсылкаИз Тогда

НоваяСтрока.УровеньСсылкаИз = 0;

ИначеЕсли Выборка.СсылкаИз = ПустаяСсылкаИз Тогда

НоваяСтрока.УровеньСсылкаИз = 1000;

Иначе

НоваяСтрока.УровеньСсылкаИз = РодителиСсылкаИз.Найти(Выборка.СсылкаИз) + 1;

КонецЕсли;

КонецЕсли;

Если ТипЗнч(Выборка.СсылкаНа) = Тип("Строка")

Или ТипЗнч(Выборка.СсылкаНа) = Тип("СправочникСсылка.Файлы") Тогда

НоваяСтрока.УровеньСсылкаНа = 0;

Иначе

Если Выборка.СсылкаНа = ВидДокументаСсылкаНа Тогда

НоваяСтрока.УровеньСсылкаНа = 0;

ИначеЕсли Выборка.СсылкаНа = ПустаяСсылкаНа Тогда

НоваяСтрока.УровеньСсылкаНа = 1000;

Иначе

НоваяСтрока.УровеньСсылкаНа = РодителиСсылкаНа.Найти(Выборка.СсылкаНа) + 1;

КонецЕсли;

КонецЕсли;

НоваяСтрока.Уровень = НоваяСтрока.УровеньСсылкаИз + НоваяСтрока.УровеньСсылкаНа;

НоваяСтрока.ХарактерСвязи = Выборка.ХарактерСвязи;

НоваяСтрока.ТипОбратнойСвязи = Выборка.ТипОбратнойСвязи;

НоваяСтрока.ХарактерОбратнойСвязи = Выборка.ХарактерОбратнойСвязи;

КонецЦикла;

НастройкиСвязи.Сортировать("Уровень Возр");

Если НастройкиСвязи.Количество() > 0 Тогда

ЗаполнитьЗначенияСвойств(СтруктураВозврата, НастройкиСвязи[0]);

Возврат СтруктураВозврата;

КонецЕсли;

Возврат Неопределено;

КонецФункции

Функция ПолучитьНастройкиСвязи(Документ, СвязанныйДокумент = Неопределено) Экспорт

НастройкиСвязи = Новый ТаблицаЗначений;

НастройкиСвязи.Колонки.Добавить("ТипСвязи");

НастройкиСвязи.Колонки.Добавить("СсылкаИз");

НастройкиСвязи.Колонки.Добавить("ТипСсылкаИз");

НастройкиСвязи.Колонки.Добавить("ТипСсылкаИзПредставление");

НастройкиСвязи.Колонки.Добавить("СсылкаНа");

НастройкиСвязи.Колонки.Добавить("ТипСсылкаНа");

НастройкиСвязи.Колонки.Добавить("ТипСсылкаНаПредставление");

НастройкиСвязи.Колонки.Добавить("ХарактерСвязи");

НастройкиСвязи.Колонки.Добавить("ТипОбратнойСвязи");

НастройкиСвязи.Колонки.Добавить("ХарактерОбратнойСвязи");

Если Не ЗначениеЗаполнено(Документ) Тогда

Возврат НастройкиСвязи;

КонецЕсли;

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| НастройкаСвязей.ТипСвязи,

| НастройкаСвязей.СсылкаИз,

| НастройкаСвязей.СсылкаНа,

| НастройкаСвязей.ХарактерСвязи,

| НастройкаСвязей.ТипОбратнойСвязи,

| НастройкаСвязей.ХарактерОбратнойСвязи,

| НастройкаСвязей.Комментарий

|ИЗ

| РегистрСведений.НастройкаСвязей КАК НастройкаСвязей";

Если ТипЗнч(Документ) = Тип("СправочникСсылка.Файлы") Тогда

Запрос.Текст = Запрос.Текст +

" ГДЕ (ТИПЗНАЧЕНИЯ(НастройкаСвязей.СсылкаИз) = ТИПЗНАЧЕНИЯ(&Документ)) ";

Запрос.УстановитьПараметр("Документ", Документ);

Иначе

Запрос.Текст = Запрос.Текст +

" ГДЕ (НастройкаСвязей.СсылкаИз = &ВидДокумента

| ИЛИ НастройкаСвязей.СсылкаИз В (&Родители)

| ИЛИ НастройкаСвязей.СсылкаИз = &ПустаяСсылка) ";

ВидДокументаСсылкаИз = Документ.ВидДокумента;

ПустаяСсылкаИз = Справочники[ВидДокументаСсылкаИз.Метаданные().Имя].ПустаяСсылка();

РодителиИз = ПолучитьРодителей(ВидДокументаСсылкаИз);

Запрос.УстановитьПараметр("ВидДокумента", ВидДокументаСсылкаИз);

Запрос.УстановитьПараметр("Родители", РодителиИз);

Запрос.УстановитьПараметр("ПустаяСсылка", ПустаяСсылкаИз);

КонецЕсли;

Если СвязанныйДокумент <> Неопределено Тогда

Если ТипЗнч(СвязанныйДокумент) = Тип("Строка")

Или ТипЗнч(СвязанныйДокумент) = Тип("СправочникСсылка.Файлы") Тогда

Запрос.Текст = Запрос.Текст +

" И (ТИПЗНАЧЕНИЯ(НастройкаСвязей.СсылкаНа) = ТИПЗНАЧЕНИЯ(&СвязанныйДокумент)) ";

Запрос.УстановитьПараметр("СвязанныйДокумент", СвязанныйДокумент);

Иначе

Запрос.Текст = Запрос.Текст +

" И (НастройкаСвязей.СсылкаНа = &ВидДокументаСсылкаНа

| ИЛИ НастройкаСвязей.СсылкаНа В (&РодителиСсылкаНа)

| ИЛИ НастройкаСвязей.СсылкаНа = &ПустаяСсылкаНа) ";

ВидДокументаСсылкаНа = СвязанныйДокумент.ВидДокумента;

РодителиСсылкаНа = ПолучитьРодителей(ВидДокументаСсылкаНа);

ПустаяСсылкаНа = Справочники[ВидДокументаСсылкаНа.Метаданные().Имя].ПустаяСсылка();

Запрос.УстановитьПараметр("ВидДокументаСсылкаНа", ВидДокументаСсылкаНа);

Запрос.УстановитьПараметр("РодителиСсылкаНа", РодителиСсылкаНа);

Запрос.УстановитьПараметр("ПустаяСсылкаНа", ПустаяСсылкаНа);

КонецЕсли;

КонецЕсли;

Выборка = Запрос.Выполнить().Выбрать();

Пока Выборка.Следующий() Цикл

НоваяСтрока = НастройкиСвязи.Добавить();

НоваяСтрока.ТипСвязи = Выборка.ТипСвязи;

НоваяСтрока.СсылкаИз = Выборка.СсылкаИз;

НоваяСтрока.СсылкаНа = Выборка.СсылкаНа;

Если ТипЗнч(Выборка.СсылкаИз) = Тип("СправочникСсылка.ВидыВходящихДокументов") Тогда

НоваяСтрока.ТипСсылкаИз = "СправочникСсылка.ВходящиеДокументы";

НоваяСтрока.ТипСсылкаИзПредставление = "Входящий документ";

ИначеЕсли ТипЗнч(Выборка.СсылкаИз) = Тип("СправочникСсылка.ВидыИсходящихДокументов") Тогда

НоваяСтрока.ТипСсылкаИз = "СправочникСсылка.ИсходящиеДокументы";

НоваяСтрока.ТипСсылкаИзПредставление = "Исходящий документ";

ИначеЕсли ТипЗнч(Выборка.СсылкаИз) = Тип("СправочникСсылка.ВидыВнутреннихДокументов") Тогда

НоваяСтрока.ТипСсылкаИз = "СправочникСсылка.ВнутренниеДокументы";

НоваяСтрока.ТипСсылкаИзПредставление = "Внутренний документ";

ИначеЕсли ТипЗнч(Выборка.СсылкаИз) = Тип("СправочникСсылка.Файлы") Тогда

НоваяСтрока.ТипСсылкаИз = "СправочникСсылка.Файлы";

НоваяСтрока.ТипСсылкаИзПредставление = "Файл";

КонецЕсли;

Если ТипЗнч(Выборка.СсылкаНа) = Тип("СправочникСсылка.ВидыВходящихДокументов") Тогда

НоваяСтрока.ТипСсылкаНа = "СправочникСсылка.ВходящиеДокументы";

НоваяСтрока.ТипСсылкаНаПредставление = "Входящий документ";

ИначеЕсли ТипЗнч(Выборка.СсылкаНа) = Тип("СправочникСсылка.ВидыИсходящихДокументов") Тогда

НоваяСтрока.ТипСсылкаНа = "СправочникСсылка.ИсходящиеДокументы";

НоваяСтрока.ТипСсылкаНаПредставление = "Исходящий документ";

ИначеЕсли ТипЗнч(Выборка.СсылкаНа) = Тип("СправочникСсылка.ВидыВнутреннихДокументов") Тогда

НоваяСтрока.ТипСсылкаНа = "СправочникСсылка.ВнутренниеДокументы";

НоваяСтрока.ТипСсылкаНаПредставление = "Внутренний документ";

ИначеЕсли ТипЗнч(Выборка.СсылкаНа) = Тип("Строка") Тогда

НоваяСтрока.ТипСсылкаНа = "Строка";

НоваяСтрока.ТипСсылкаНаПредставление = "Внешний ресурс";

ИначеЕсли ТипЗнч(Выборка.СсылкаНа) = Тип("СправочникСсылка.Файлы") Тогда

НоваяСтрока.ТипСсылкаНа = "СправочникСсылка.Файлы";

НоваяСтрока.ТипСсылкаНаПредставление = "Файл";

КонецЕсли;

НоваяСтрока.ХарактерСвязи = Выборка.ХарактерСвязи;

НоваяСтрока.ТипОбратнойСвязи = Выборка.ТипОбратнойСвязи;

НоваяСтрока.ХарактерОбратнойСвязи = Выборка.ХарактерОбратнойСвязи;

КонецЦикла;

Возврат НастройкиСвязи;

КонецФункции

Процедура УстановитьСвязь(

Документ,

НачальныйСвязанныйДокумент,

СвязанныйДокумент,

ТипСвязи,

Установил = Неопределено,

ДатаУстановки = Неопределено,

Комментарий = "") Экспорт

Если НачальныйСвязанныйДокумент = СвязанныйДокумент Тогда

Возврат;

КонецЕсли;

Если ЗначениеЗаполнено(НачальныйСвязанныйДокумент) Тогда

Если ЗначениеЗаполнено(СвязанныйДокумент) Тогда

СвязиДокументов.УдалитьСвязь(Документ, НачальныйСвязанныйДокумент, ТипСвязи);

СвязиДокументов.СоздатьСвязь(Документ, СвязанныйДокумент, ТипСвязи, Установил, ДатаУстановки, Комментарий);

Иначе

СвязиДокументов.УдалитьСвязь(Документ, НачальныйСвязанныйДокумент, ТипСвязи);

КонецЕсли;

Иначе

Если ЗначениеЗаполнено(СвязанныйДокумент) Тогда

СвязиДокументов.СоздатьСвязь(Документ, СвязанныйДокумент, ТипСвязи, Установил, ДатаУстановки, Комментарий);

КонецЕсли;

КонецЕсли;

НачальныйСвязанныйДокумент = СвязанныйДокумент;

КонецПроцедуры

Процедура ОбновитьСвязиДокумента(СвязанныйДокумент) Экспорт

УстановитьПривилегированныйРежим(Истина);

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| СвязиДокументов.Документ,

| СвязиДокументов.ТипСвязи,

| СвязиДокументов.СвязанныйДокумент

|ИЗ

| РегистрСведений.СвязиДокументов КАК СвязиДокументов

|ГДЕ

| СвязиДокументов.СвязанныйДокумент = &СвязанныйДокумент";

Запрос.УстановитьПараметр("СвязанныйДокумент", СвязанныйДокумент);

Выборка = Запрос.Выполнить().Выбрать();

Пока Выборка.Следующий() Цикл

МенеджерЗаписи = РегистрыСведений.СвязиДокументов.СоздатьМенеджерЗаписи();

МенеджерЗаписи.Документ = Выборка.Документ;

МенеджерЗаписи.ТипСвязи = Выборка.ТипСвязи;

МенеджерЗаписи.СвязанныйДокумент = Выборка.СвязанныйДокумент;

МенеджерЗаписи.УдалитьСвязанныйДокумент = Неопределено;

МенеджерЗаписи.СвязаннаяСтрока = "";

МенеджерЗаписи.Прочитать();

Если ТипЗнч(СвязанныйДокумент) = Тип("СправочникСсылка.ИсходящиеДокументы") Тогда

Получатели = СвязанныйДокумент.Получатели;

Отправлен = Ложь;

Если Получатели.Количество() = 1 Тогда

Отправлен = Получатели[0].Отправлен;

ИначеЕсли Получатели.Найти(Ложь, "Отправлен") = Неопределено Тогда

Отправлен = Истина;

ИначеЕсли ТипЗнч(МенеджерЗаписи.Документ) = Тип("СправочникСсылка.ВходящиеДокументы") Тогда

ВходящийДокумент = МенеджерЗаписи.Документ;

ПараметрыОтбора = Новый Структура("Получатель", ВходящийДокумент.Отправитель);

НайденныеСтроки = Получатели.НайтиСтроки(ПараметрыОтбора);

Если НайденныеСтроки.Количество() = 1 Тогда

Отправлен = НайденныеСтроки[0].Отправлен;

Иначе

ПараметрыОтбора = Новый Структура("Получатель, Адресат", ВходящийДокумент.Отправитель, ВходящийДокумент.Подписал);

НайденныеСтроки = Получатели.НайтиСтроки(ПараметрыОтбора);

Если НайденныеСтроки.Количество() = 1 Тогда

Отправлен = НайденныеСтроки[0].Отправлен;

КонецЕсли;

КонецЕсли;

КонецЕсли;

Если Отправлен <> МенеджерЗаписи.СвязанныйДокументОтправлен Тогда

МенеджерЗаписи.Записать();

КонецЕсли;

КонецЕсли;

КонецЦикла;

КонецПроцедуры

Функция УстановитьРеквизитыПриДобавленииСвязи(ДокументСсылка, УникальныйИдентификаторДокумента, ТипСвязи) Экспорт

РеквизитыИзменены = Ложь;

Если ТипЗнч(ДокументСсылка) = Тип("СправочникСсылка.ВходящиеДокументы") Тогда

Если (ТипСвязи = Справочники.ТипыСвязей.ПервичноеОбращение) И (Не ДокументСсылка.Повторное) Тогда

ДокументОбъект = ДокументСсылка.ПолучитьОбъект();

ЗаблокироватьДанныеДляРедактирования(ДокументОбъект.Ссылка, , УникальныйИдентификаторДокумента);

ДокументОбъект.Повторное = Истина;

ДокументОбъект.Записать();

РазблокироватьДанныеДляРедактирования(ДокументОбъект.Ссылка, УникальныйИдентификаторДокумента);

РеквизитыИзменены = Истина;

КонецЕсли;

Если (ТипСвязи = Справочники.ТипыСвязей.ОсновноеОбращение) И (Не ДокументСсылка.Дубликат) Тогда

ДокументОбъект = ДокументСсылка.ПолучитьОбъект();

ЗаблокироватьДанныеДляРедактирования(ДокументОбъект.Ссылка,, УникальныйИдентификаторДокумента);

ДокументОбъект.Дубликат = Истина;

ДокументОбъект.Записать();

РазблокироватьДанныеДляРедактирования(ДокументОбъект.Ссылка, УникальныйИдентификаторДокумента);

РеквизитыИзменены = Истина;

КонецЕсли;

ИначеЕсли ТипЗнч(ДокументСсылка) = Тип("СправочникСсылка.ВнутренниеДокументы") Тогда

Если (ТипСвязи = Справочники.ТипыСвязей.НеДействуетВСоответствии) И (Не ДокументСсылка.НеДействует) Тогда

ДокументОбъект = ДокументСсылка.ПолучитьОбъект();

ЗаблокироватьДанныеДляРедактирования(ДокументОбъект.Ссылка,, УникальныйИдентификаторДокумента);

ДокументОбъект.НеДействует = Истина;

ДокументОбъект.Записать();

РазблокироватьДанныеДляРедактирования(ДокументОбъект.Ссылка, УникальныйИдентификаторДокумента);

РеквизитыИзменены = Истина;

КонецЕсли;

КонецЕсли;

Возврат РеквизитыИзменены;

КонецФункции

Функция УстановитьРеквизитыПриУдаленииСвязи(ДокументСсылка, УникальныйИдентификаторДокумента, ТипСвязи) Экспорт

РеквизитыИзменены = Ложь;

Если ТипЗнч(ДокументСсылка) = Тип("СправочникСсылка.ВходящиеДокументы") Тогда

Если (ТипСвязи = Справочники.ТипыСвязей.ПервичноеОбращение) И ДокументСсылка.Повторное Тогда

ДокументОбъект = ДокументСсылка.ПолучитьОбъект();

ЗаблокироватьДанныеДляРедактирования(ДокументОбъект.Ссылка,, УникальныйИдентификаторДокумента);

ДокументОбъект.Повторное = Ложь;

ДокументОбъект.Записать();

РазблокироватьДанныеДляРедактирования(ДокументОбъект.Ссылка, УникальныйИдентификаторДокумента);

РеквизитыИзменены = Истина;

КонецЕсли;

Если (ТипСвязи = Справочники.ТипыСвязей.ОсновноеОбращение) И ДокументСсылка.Дубликат Тогда

ДокументОбъект = ДокументСсылка.ПолучитьОбъект();

ЗаблокироватьДанныеДляРедактирования(ДокументОбъект.Ссылка,, УникальныйИдентификаторДокумента);

ДокументОбъект.Дубликат = Ложь;

ДокументОбъект.Записать();

РазблокироватьДанныеДляРедактирования(ДокументОбъект.Ссылка, УникальныйИдентификаторДокумента);

РеквизитыИзменены = Истина;

КонецЕсли;

ИначеЕсли ТипЗнч(ДокументСсылка) = Тип("СправочникСсылка.ВнутренниеДокументы") Тогда

Если (ТипСвязи = Справочники.ТипыСвязей.НеДействуетВСоответствии) И ДокументСсылка.НеДействует Тогда

ДокументОбъект = ДокументСсылка.ПолучитьОбъект();

ЗаблокироватьДанныеДляРедактирования(ДокументОбъект.Ссылка,, УникальныйИдентификаторДокумента);

ДокументОбъект.НеДействует = Ложь;

ДокументОбъект.Записать();

РазблокироватьДанныеДляРедактирования(ДокументОбъект.Ссылка, УникальныйИдентификаторДокумента);

РеквизитыИзменены = Истина;

КонецЕсли;

КонецЕсли;

Возврат РеквизитыИзменены;

КонецФункции

// Обработчик обновления информационной базы

//

Процедура ПерейтиНаВерсию_1_2_1_3() Экспорт

Набор = РегистрыСведений.СвязиДокументов.СоздатьНаборЗаписей();

Набор.Отбор.ТипСвязи.Установить(Справочники.ТипыСвязей.Содержит);

Набор.Прочитать();

Набор.Очистить();

Набор.Записать(Истина);

Набор = РегистрыСведений.СвязиДокументов.СоздатьНаборЗаписей();

Набор.Отбор.ТипСвязи.Установить(Справочники.ТипыСвязей.ВходитВКомплект);

Набор.Прочитать();

Набор.Очистить();

Набор.Записать(Истина);

УстановитьКомментарийТипаСвязи(Справочники.ТипыСвязей.ВходитВКомплект, НСтр("ru = 'Ссылка на комплект документов'"));

УстановитьКомментарийТипаСвязи(Справочники.ТипыСвязей.Содержит, НСтр("ru = 'Ссылка на элемент комплекта'"));

СоздатьНастройкуСвязи(Справочники.ТипыСвязей.Содержит,

Справочники.ВидыВнутреннихДокументов.ПустаяСсылка(),

Справочники.ВидыВнутреннихДокументов.ПустаяСсылка(),

Перечисления.ХарактерСвязей.Множественная,

Справочники.ТипыСвязей.ВходитВКомплект,

Перечисления.ХарактерСвязей.Множественная,

Истина);

СоздатьНастройкуСвязи(Справочники.ТипыСвязей.Содержит,

Справочники.ВидыВнутреннихДокументов.ПустаяСсылка(),

Справочники.ВидыВходящихДокументов.ПустаяСсылка(),

Перечисления.ХарактерСвязей.Множественная,

Справочники.ТипыСвязей.ВходитВКомплект,

Перечисления.ХарактерСвязей.Множественная,

Истина);

СоздатьНастройкуСвязи(Справочники.ТипыСвязей.Содержит,

Справочники.ВидыВнутреннихДокументов.ПустаяСсылка(),

Справочники.ВидыИсходящихДокументов.ПустаяСсылка(),

Перечисления.ХарактерСвязей.Множественная,

Справочники.ТипыСвязей.ВходитВКомплект,

Перечисления.ХарактерСвязей.Множественная,

Истина);

СоздатьНастройкуСвязи(Справочники.ТипыСвязей.Содержит,

Справочники.ВидыВнутреннихДокументов.ПустаяСсылка(),

Справочники.Файлы.ПустаяСсылка(),

Перечисления.ХарактерСвязей.Множественная,,,

Истина);

КонецПроцедуры

Процедура ОбновитьСвязиПриРазделенииИзмерения() Экспорт

// Разделение данных в регистре сведений СвязиДокументов на два измерения

Если Метаданные.РегистрыСведений.СвязиДокументов.Измерения.Найти("УдалитьСвязанныйДокумент") <> Неопределено Тогда

ВыборкаТипыСвязей = Справочники.ТипыСвязей.Выбрать();

Пока ВыборкаТипыСвязей.Следующий() Цикл

ТипСвязи = ВыборкаТипыСвязей.Ссылка;

НаборСвязиДокументов = РегистрыСведений.СвязиДокументов.СоздатьНаборЗаписей();

НаборСвязиДокументов.Отбор.ТипСвязи.Установить(ТипСвязи);

НаборСвязиДокументов.Прочитать();

ЗаписатьНабор = Ложь;

Для каждого Запись Из НаборСвязиДокументов Цикл

Если ЗначениеЗаполнено(Запись.СвязанныйДокумент)

Или ЗначениеЗаполнено(Запись.СвязаннаяСтрока)

Или Не ЗначениеЗаполнено(Запись.УдалитьСвязанныйДокумент) Тогда

Продолжить;

КонецЕсли;

Если ТипЗнч(Запись.УдалитьСвязанныйДокумент) = Тип("Строка") Тогда

Запись.СвязаннаяСтрока = Запись.УдалитьСвязанныйДокумент;

Иначе

Запись.СвязанныйДокумент = Запись.УдалитьСвязанныйДокумент;

КонецЕсли;

Запись.УдалитьСвязанныйДокумент = Неопределено;

ЗаписатьНабор = Истина;

КонецЦикла;

Если ЗаписатьНабор Тогда

НаборСвязиДокументов.ОбменДанными.Загрузка = Истина;

НаборСвязиДокументов.Записать();

КонецЕсли;

КонецЦикла;

КонецЕсли;

КонецПроцедуры

Размещено на Allbest.ru