Version 5.1 by admin on 2026/06/07 18:49

Show last authors
1 Часто бывает полезно выявить неактивные пропуска, то есть пропуска, по которым давно не было никаких событий доступа. Для решения этой задачи в Платформе НЕЙРОСС реализован скрипт автоматизации, позволяет автоматически обнаружить неактивные пропуска и поместить их в отдельную группу, а также, при необходимости, — выполнить бессрочную приостановку пропуска.
2
3 Контролируются не все пропуска, а только пропуска выбранных владельцев.
4
5 Посредством настройки свойств скрипта автоматизации вы можете:
6
7 * задать имя группы для помещения пропусков;
8 * определить, требуется ли автоматически выполнять изъятие пропусков, либо решение будет принимать оператор бюро пропусков;
9 * задать период неактивности — временной интервал в днях, по истечении которого при отсутствии событий доступа пропуск считается неактивным;
10 * указать, требуется ли учитывать факт изменения пропуска совместно с событием доступа — пропуск будет считаться неактивным, если за заданный период не было ни события доступа, ни факта изменения пропуска оператором бюро пропусков;
11 * пометить, что пропуск приостановлен скриптом автоматизации.
12
13 {{info}}
14 Задание автоматизации может запускаться оператором вручную, по расписанию (например, раз в неделю по воскресеньям), либо по какому-либо событию/системному действию.
15 {{/info}}
16
17 **Пример: Найти пропуска, по которым не было событий доступа в течение 60 дней и поместить их в группу «Устаревшие пропуска»**
18
19 Задание автоматизации запускается автоматически ежедневно в 23:00, производится поиск за интервал в 60 дне. Найденные неактивные пропуска не приостанавливаются, остаются действительными и принадлежащими «своим» группам, но дополнительно помещаются в группу «Устаревшие пропуска». Анализируются только события доступа, факт изменения пропуска оператором АРМ Доступ не анализируется.
20
21 [[image:attach:card_inactivity_scrypt.png]]
22
23 \\
24
25 === {{id name="Контрольактивностипропуска-НастройкиСКУД"/}}Настройки СКУД ===
26
27 Вам потребуется:
28
29 1. Создать пользовательское свойство владельца пропуска для указания перечня лиц, для которых требуется проводить контроль активности пропуска.
30 1. Добавить свойство на форму владельца пропуска и задать в значение true для владельцев, чьи пропуска требуется анализировать.
31 1. Создать пользовательское свойство пропуска для пометок о том, что пропуск приостановлен скриптом.
32 1. Добавить свойство на форму пропуска.
33
34 Порядок действий:
35
36 |=(((
37 Задача
38 )))|=(((
39 Комментарий
40 )))
41 |(((
42 Создание пользовательского свойства
43 )))|(((
44 (((
45 В разделе **Настройки СКУД** АРМ НЕЙРОСС Доступ:
46
47 1. На вкладке **Свойства владельца пропуска** добавьте новое свойство, задайте название и ключ свойства, укажите тип «Переключатель».
48 [[image:attach:card_inactivity_appprp.png||height="250"]]
49 1. На вкладке **Свойства пропуска** добавьте новое свойство, задайте название и ключ свойства, укажите тип «Переключатель».
50 [[image:attach:PausedByScrypt_addprp.png||height="250"]]
51
52 [[doc:neyross.Настройка Платформы НЕЙРОСС.Настройка функций контроля доступа.Добавление пользовательских свойств.WebHome]]
53 )))
54 )))
55 |(((
56 Изменение формы владельца пропуска
57 )))|(((
58 (((
59 В разделе **Персонал** АРМ НЕЙРОСС Доступ выберите группу пропусков, для которой нужно настроить контроль активности, перейдите к вкладке **Настройки группы**:
60
61 1. На вкладке (%%)**Форма ввода: Владелец пропуска** добавьте поле **Контроль активности** (название может быть любым) на форму владельца пропуска.
62 1. На вкладке **Форма ввода: Пропуск добавьте** поле **Приостановлен скриптом** (название может быть любым) на форму пропуска.
63
64 {{info}}
65 Рекомендуем использовать Конструктор форм. При использовании нестандартных форм, обратитесь к специалистам компании ИТРИУМ за услугой по доработке формы.
66 {{/info}}
67
68 [[doc:neyross.Настройка Платформы НЕЙРОСС.Настройка функций контроля доступа.Настройка форм ввода данных.WebHome]]
69
70 При необходимости вывода информации в таблице пропусков, на вкладке **Настройка таблицы** добавьте вывод данных свойств.
71
72 [[doc:neyross.Настройка Платформы НЕЙРОСС.Настройка функций контроля доступа.Настройка таблицы пропусков.WebHome]]
73 )))
74 )))
75 |(((
76 Включение необходимости контроля активности пропуска
77 )))|(((
78 (((
79 Выберите владельцев, для которых требуется проводить контроль активности пропуска, и в режиме редактирования пропуска / группы пропусков в поле **Контроль активности** установите переключатель в положение [[image:attach:ui.Параметры узла.WebHome@fa-on.png||thumbnail="true" height="18"]]**Включено**. Сохраните данные владельца.
80
81 [[image:attach:card_inactivity_person_form.png||width="500"]]
82
83 [[doc:neyross.АРМ НЕЙРОСС Доступ.Управление пропусками.WebHome]]
84 )))
85 )))
86 |(((
87 Просмотр результатов работы скрипта
88 )))|(((
89 Дождитесь выполнения условия запуска задания (в нашем примере это 23:00 текущего дня).
90 )))
91
92 == {{id name="Контрольактивностипропуска-Настройкиавтоматизации"/}}Настройки автоматизации ==
93
94 Скопируйте приведённый ниже код скрипта (% class="auto-cursor-target" style="color: rgb(23, 43, 77); color: rgb(23, 43, 77)" %)и создайте файл с произвольным именем и расширением **JSON**, например: (%%)//задание_автоматизации_Контроль_устаревших пропусков.json//(% class="auto-cursor-target" style="color: rgb(23, 43, 77); color: rgb(23, 43, 77)" %). Для этого удобно использовать простые текстовые редакторы типа Блокнот или Notepad++. Вы также можете обратиться к специалистам компании ИТРИУМ, мы вышлем подготовленный файл.
95
96 {{code language="java"}}
97
98 import play.api.libs.json.Format
99 import beans.pacs.{PacsFolderBean, PassBean}
100 import extensions.automation.scripts.AutomationActionScript
101 import extensions.automation.signals.AutomationSignal
102 import models.common.UserIdentity
103 import models.neyross.{Pass, PassComponent}
104 import models.pacs.{PacsFolder, PacsFolderComponent}
105 import dto.pacs.PacsFolderMovementDto
106 import services.logging.web.{LoggerWithWeb => Logger}
107 import play.api.libs.json.{JsObject, Json}
108 import proto.neyross.PassProto
109 import services.common.{SystemLogService, SystemLogTag}
110 import services.neyross.NeyrossEmbedApiService
111 import slick.dbio.DBIOAction
112 import utils.TableExtension
113 import utils.bootstrap.CustomPostgresProfile
114 import utils.common.ScalaUtils
115
116 import java.time.OffsetDateTime
117 import java.util.UUID
118 import scala.concurrent.Future
119
120 class ObsoletePassControlAutomationScript extends AutomationActionScript {
121
122 val logger = Logger("ObsoletePassControlAutomationScript")
123
124 private val postgresProfile = ctx.dbConfig.profile.asInstanceOf[CustomPostgresProfile]
125
126 import postgresProfile.api._
127
128 implicit val ec = ctx.executionContext
129 private val neyrossEmbedApi = ctx.injector.instanceOf[NeyrossEmbedApiService]
130 private val pacsFolderBean = ctx.injector.instanceOf[PacsFolderBean]
131 private val systemLogService = ctx.injector.instanceOf[SystemLogService]
132 private val passBean = ctx.injector.instanceOf[PassBean]
133
134 private val folders = new PacsFolderComponent()(ctx.dbConfig)
135 private val passes = new PassComponent()(ctx.dbConfig, neyrossEmbedApi, ec)
136
137 // @parameter { "type": "string", "title": "Название группы для устаревших пропусков", "key": "workingFolder" }
138 val workingFolder = "Устаревшие пропуска"
139
140 // @parameter { "type": "string", "title": "Идентификатор свойства-признака контроля", "key": "shouldControlOutdateProperty", "description": "Контролироваться будут пропуска только тех владельцев, которые имеют данное свойство" }
141 val shouldControlOutdateProperty = "inactivity"
142
143 // @parameter { "type": "string", "title": "Значение свойства-признака контроля", "key": "shouldControlOutdatePropertyValue", "description": "Контролироваться будут пропуска только тех владельцев, которые имеют указанное значение данного свойства (true означает Да)" }
144 val shouldControlOutdatePropertyValue = "true"
145
146 // @parameter { "type": "select", "title": "Режим работы", "key": "mode", "options": [ { "value": "default", "label": "Помещение устаревших пропусков группу" }, { "value": "withStopping", "label": "Приостановка и помещение устаревших пропусков в группу" } ] }
147 val mode = "withStopping"
148
149 // @parameter { "type": "number", "title": "Максимальный период неактивности, дней", "key": "inactivityPeriod" }
150 val inactivityPeriod = 1
151
152 // @parameter { "type": "boolean", "title": "Анализировать время изменения пропуска", "key": "isUpdateTimeAnalysisEnabled", "description": "Если флаг установлен, при расчёте активности пропуска будут учитываться также события изменения пропуска оператором бюро пропусков. В противном случае будет анализироваться только время последнего прохода по данному пропуску" }
153 val isUpdateTimeAnalysisEnabled = false
154
155 // @parameter { "type": "string", "title": "Идентификатор свойства-маркера контроля", "key": "scriptMarkPropertyKey", "description": "При автоматической приостановке пропуска к нему будет добавлено свойство с данным идентификатором и значением true (Да). Вы можете вынести данное свойство на форму пропуска или в таблицу пропусков, при необходимости" }
156 val scriptMarkPropertyKey = "PausedByScrypt"
157
158 val modeLocalization: Map[String, String] =
159 Map(
160 "default" -> "Помещение устаревших пропусков в группу",
161 "withStopping" -> "Приостановка и помещение устаревших пропусков в группу"
162 )
163
164 logger.debug(s"mode: ${modeLocalization.getOrElse(mode, "")}")
165 logger.debug(s"modification time analysing: $isUpdateTimeAnalysisEnabled")
166 logger.debug(s"inactivity period: $inactivityPeriod")
167
168 override def onSignal(signal: AutomationSignal): Future[Unit] = {
169 workingFolder.trim match {
170 case "" =>
171 logger.warn("working folder name is empty. do nothing")
172 Future.unit
173 case nonEmptyFolderName =>
174 runWithNonEmptyFolderName(nonEmptyFolderName)
175 }
176 }
177
178 private def createFolderWithNameAndParent(name: String, parent: Option[String]) = {
179 val uuid = UUID.randomUUID().toString
180 val folder = PacsFolder(
181 id = None,
182 uuid = Some(uuid),
183 name = Some(name),
184 parent = parent,
185 isDefault = false,
186 templates = None,
187 defaultValues = None,
188 settings = None,
189 created = OffsetDateTime.now(),
190 deleted = false
191 )
192 folders.insert(folder).map(_ => Some(uuid))
193 }
194
195 private def getFolderUuidByName(folderName: String) = {
196 folders.folders
197 .filter(f => f.name === folderName && !f.deleted)
198 .result
199 .headOption
200 .flatMap({
201 case Some(folder) =>
202 DBIOAction.successful(folder.uuid)
203 case _ =>
204 folders
205 .findDefault()
206 .flatMap({
207 case Some(defaultFolder) if defaultFolder.uuid.nonEmpty =>
208 createFolderWithNameAndParent(folderName, defaultFolder.uuid)
209 case _ =>
210 logger.warn("there is no valid default folder. wtf?")
211 DBIOAction.successful(None)
212 })
213 })
214 }
215
216 private def isOutdated(timestamp: OffsetDateTime): Boolean = {
217 val threshold = OffsetDateTime.now().minusDays(inactivityPeriod)
218 logger.trace(s"checking if chosen timestamp $timestamp is older than threshold $threshold")
219 threshold.isAfter(timestamp)
220 }
221
222 private def isStoppedOrInOutdatedFolder(
223 pass: Pass,
224 outdatedFolderUuid: String,
225 passFolders: List[String]
226 ): Boolean = {
227 pass.getState.contains(PassProto.Pass.State.sSTOPPED) || passFolders.contains(outdatedFolderUuid)
228 }
229
230 private def isOutdatedPassRecord(record: PassRecord): Boolean = {
231 // from all pass times, choose latest one and check if it outdated
232 val lastAccessGrantedAtOption = record._2
233 val created = record._3
234 val lastUpdatedAtOption = record._4
235 logger.trace(s"last access granted: $lastAccessGrantedAtOption, created: $created, last updated: $lastUpdatedAtOption")
236 // in any cases, pass has "created" time
237 var latestTimeToCheck: OffsetDateTime = created
238 if (
239 lastAccessGrantedAtOption.isDefined &&
240 lastAccessGrantedAtOption.get.isAfter(latestTimeToCheck)
241 ) {
242 // last access event was later than created time - using it
243 latestTimeToCheck = lastAccessGrantedAtOption.get
244 }
245 if (isUpdateTimeAnalysisEnabled) {
246 if (
247 lastUpdatedAtOption.isDefined &&
248 lastUpdatedAtOption.get.isAfter(latestTimeToCheck)
249 ) {
250 // last update event was later than created time and last access time - using it
251 latestTimeToCheck = lastUpdatedAtOption.get
252 }
253 }
254 isOutdated(latestTimeToCheck)
255 }
256
257 private def getPassesToMove(records: Seq[PassRecord], outdatedFolderUuid: String): Seq[Pass] = {
258 records
259 .filter(record => {
260 logger.trace(s"pass ${record._5.uuid} handling")
261 !isStoppedOrInOutdatedFolder(record._5, outdatedFolderUuid, record._1.getOrElse(Nil)) &&
262 isOutdatedPassRecord(record)
263 })
264 .map(_._5)
265 }
266
267 type PassFolders = Option[List[String]]
268 type LastAccessGrantedAt = Option[OffsetDateTime]
269 type Created = OffsetDateTime
270 type LastUpdatedAt = Option[OffsetDateTime]
271 type PassRecord = (PassFolders, LastAccessGrantedAt, Created, LastUpdatedAt, Pass)
272
273 type PersonUUID = String
274 type PersonFolders = Option[Seq[String]]
275 type PersonRecord = (PersonUUID, PersonFolders)
276
277 private def personToControlHandler(
278 outdatedFolderUuid: String,
279 personRecord: PersonRecord
280 ): Future[Seq[String]] = {
281 val dbAction =
282 passes
283 .extendedPasses4(
284 TableExtension.folders(ctx.dbConfig),
285 TableExtension.lastAccessGrantedAt(ctx.dbConfig),
286 TableExtension.created(ctx.dbConfig),
287 TableExtension.lastUpdatedAt(ctx.dbConfig)
288 )
289 .filter(r => r.person === personRecord._1 && !r.deleted)
290 .result
291
292 ctx
293 .dbRun(dbAction)
294 .flatMap(result => {
295 logger.trace(s"found passes of person ${personRecord._1}: ${result.map(_._5.uuid)}")
296 val passesToMove = getPassesToMove(result, outdatedFolderUuid)
297 logger.trace(s"found outdated passes of person ${personRecord._1}: ${passesToMove.map(_.uuid)}")
298 if (passesToMove.nonEmpty) {
299 val isPersonInOutdatedFolder = personRecord._2.exists(_.contains(outdatedFolderUuid))
300 val personsToMove = Option.when(!isPersonInOutdatedFolder)(personRecord._1).toList
301 val dto = PacsFolderMovementDto(personsToMove, passesToMove.map(_.uuid))
302 pacsFolderBean.copyToFolder(outdatedFolderUuid, dto)(ui = null, None).map(_ => passesToMove.map(_.uuid))
303 } else {
304 Future.successful(Nil)
305 }
306 })
307 }
308
309 private def getPersonsToControl: Future[Vector[PersonRecord]] = {
310 val personsToControl =
311 sql"""
312 SELECT DISTINCT uuid, folders
313 FROM
314 neyross_person,
315 jsonb_to_recordset((person_json->>'properties'):: jsonb) AS props(key text, value text)
316 WHERE
317 key = '#${shouldControlOutdateProperty}' AND
318 value = '#${shouldControlOutdatePropertyValue}' AND
319 neyross_person.deleted = false
320 """.as[PersonRecord]
321
322 ctx.dbRun(personsToControl)
323 }
324
325 case class Property(key: String, value: String, index: Option[Long] = None)
326
327 object Property {
328 implicit val jsonFormat: Format[Property] = Json.format[Property]
329 }
330
331 private def stopPassesWithUuid(uuids: Seq[String]): Future[Unit] = {
332 ctx
333 .dbRun(passes.findByUuids(uuids))
334 .flatMap(updatedPasses => {
335 ScalaUtils
336 .sequentialTraverse(updatedPasses)(updatedPass => {
337 logger.trace(s"stopping pass ${updatedPass.uuid}; setting property $scriptMarkPropertyKey and disabled_from fields")
338 val passJson = updatedPass.toFullJson.asOpt[JsObject].get
339 val passProperties = (passJson \ "properties").asOpt[List[Property]].getOrElse(Nil)
340
341 val newPassProperties = passProperties.filter(p => {
342 p.key != scriptMarkPropertyKey
343 }) :+ Property(
344 scriptMarkPropertyKey,
345 "true"
346 )
347 val newPassJson = passJson ++ Json.obj(
348 "disabled_from" -> OffsetDateTime.now().toInstant.getEpochSecond.toInt,
349 "properties" -> Json.toJson(newPassProperties)
350 )
351 logger.trace(s"new pass json is: $newPassJson")
352 passBean
353 .updateV2(updatedPass.uuid, newPassJson)(UserIdentity.getFakeUserIdentityFor("Автоматизация"), None)
354 })
355 .map(_ => ())
356 })
357 }
358
359 private def runWithNonEmptyFolderName(folderName: String): Future[Unit] = {
360 systemLogService
361 .log(
362 SystemLogTag.NORMAL,
363 SystemLogTag.AUTOMATION
364 )(s"Запущен процесс контроля устаревших пропусков")
365 .map(_ => ())
366 ctx
367 .dbRun(getFolderUuidByName(folderName))
368 .flatMap({
369 case Some(folderUUID) =>
370 logger.debug(s"working folder is $folderName ($folderUUID)")
371 getPersonsToControl
372 .flatMap(persons => {
373 logger.debug(s"found persons to control: $persons")
374 ScalaUtils.sequentialTraverse(persons)(personToControlHandler(folderUUID, _))
375 })
376 .flatMap(uuids => {
377 val flatUuidsList = uuids.flatten.distinct
378 if (flatUuidsList.nonEmpty) {
379 val stopping = if (mode == "withStopping") {
380 stopPassesWithUuid(flatUuidsList)
381 } else {
382 Future.unit
383 }
384 stopping.flatMap(_ => {
385 val yesOrNo = Option
386 .when(isUpdateTimeAnalysisEnabled)("да")
387 .getOrElse("нет")
388 logger.debug(s"were moved ${flatUuidsList.size} passes")
389 val message =
390 s"""В группу '$folderName' было помещено ${flatUuidsList.size} пропусков.
391 |Режим работы: ${modeLocalization.getOrElse(mode, "")}.
392 |Анализировать время изменения пропуска: $yesOrNo
393 |Максимальный период неактивности: $inactivityPeriod дней""".stripMargin
394 systemLogService
395 .log(
396 SystemLogTag.NORMAL,
397 SystemLogTag.AUTOMATION
398 )(
399 message = message,
400 data = Some(Json.toJson(flatUuidsList))
401 )
402 .map(_ => ())
403 })
404 } else {
405 logger.debug("not found persons with obsolete persons or passes")
406 systemLogService
407 .log(
408 SystemLogTag.NORMAL,
409 SystemLogTag.AUTOMATION
410 )(s"Не найдено владельцев для контроля устаревших пропусков, либо все пропуска таких владельцев не являются устаревшими")
411 .map(_ => ())
412 }
413 })
414 case _ =>
415 Future.unit
416 })
417 Future.unit
418 }
419 }
420
421 new ObsoletePassControlAutomationScript
422 {{/code}}
423
424 (% class="auto-cursor-target" style="color: rgb(23, 43, 77); color: rgb(23, 43, 77)" %)Добавьте задание автоматизации
425
426 1. (% class="auto-cursor-target" style="color: rgb(23, 43, 77); color: rgb(23, 43, 77)" %)В разделе **Автоматизация** нажмите на кнопку  **Добавить новое задание [[image:attach:ui.Параметры узла.WebHome@btn_add_new.png||thumbnail="true" height="18"]]**, нажмите на кнопку **Импорт** и укажите путь к подготовленному на предыдущем этапе файлу ~[[[Автоматизация>>doc:ui.Параметры узла.Автоматизация.WebHome||style="" shape="rect"]]].
427 1. В блоке **Параметры сигнала** выберите **По расписанию**, настройте расписание (например, 0 23 * * * для ежедневного запуска, или 0 23 * * 1 для запуска раз в неделю по воскресеньям).
428 1. (((
429 В блоке **Параметры действия** настройте параметры задания автоматизации согласно таблице ниже.
430
431 |=(((
432 Параметр
433 )))|=(((
434 Комментарий
435 )))
436 |(((
437 Название группы устаревших пропусков
438 )))|(((
439 Название группы. При запуске скрипта проверяется наличие группы с указанным именем в группе **Все**. При отсутствии, — она будет создана. В эту группу помещаться все найденные пропуска и их владельцы. Если название пустое, задание не выполняется.
440 )))
441 |(((
442 Идентификатор свойства — признака контроля
443 )))|(((
444 Уникальный идентификатор пользовательского свойства владельца пропуска, созданный на этапе [[#Настройки СКУД>>doc:||anchor="Контрольактивностипропуска-НастройкиСКУД"]]. В нашем примере: inactivity
445 )))
446 |(((
447 Значение свойства — признака контроля
448 )))|(((
449 (((
450 * true — если требуется проверять пропуска, для владельцев которого в поле **Контроль пропусков** переключатель установлен в положение [[image:attach:ui.Параметры узла.WebHome@fa-on.png||thumbnail="true" height="18"]] **Включено**.
451 * false — если требуется проверять пропуска, для владельцев которого в поле **Контроль пропусков** переключатель установлен в положение [[image:attach:ui.Параметры узла.WebHome@fa-off.png||thumbnail="true" height="18"]] **Выключено**.
452
453 В нашем примере: true
454 )))
455 )))
456 |(((
457 Режим работы
458 )))|(((
459 Выберите из раскрывающегося списка требуемые действия с пропусками:  требуется ли просто помещать пропуска в дополнительную группу для принятия решения оператором о дальнейших действиях с пропуском, либо необходимо приостанавливать действие найденных пропусков и помещать в группу.
460
461 * Помещение устаревших пропусков в группу — просто помещать пропуска в дополнительную группу для принятия решения оператором о дальнейших действиях с пропуском. Пропуск остаётся действительным. Доступ по нему возможен.
462 * Приостановка и помещение устаревших пропусков в группу — приостанавливать пропуск и помещать в дополнительную группу. Пропуск не удаляется из контроллеров доступа, но доступ блокируется.
463 )))
464 |(((
465 Максимальный период неактивности, дней
466 )))|(((
467 Укажите временной интервал в днях (количество дней), по истечению которого пропуск без событий доступа считается устаревшим.
468 )))
469 |(((
470 Анализировать время изменения пропуска
471 )))|(((
472 Установите флаг в поле, если, помимо событий доступа при расчёте активности пропуска требуется учитывать не только события доступа, но и события изменения пропуска оператором бюро пропусков.
473 )))
474 |(((
475 Идентификатор свойства-маркера контроля
476 )))|(((
477 Уникальный идентификатор пользовательского свойства пропуска, значение которого будет устанавливаться в true для пропусков, которые приостановлены данным скриптом. В нашем примере: PausedByScrypt
478 )))
479
480 === {{id name="Контрольактивностипропуска-Алгоритмработы"/}}Алгоритм работы ===
481
482 (% class="wiki-list0" %)
483 1. Поиск владельцев, для которых в поле с указанным идентификатором задано указанное значение.
484 1. Поиск активных пропусков для найденных владельцев (если пропуск уже приостановлен или находится в группе устаревших пропусков операции с ним не выполняются).
485 1. Поиск времени «активизации пропуска»:
486 (% class="wiki-list0" %)
487 11. Если флаг в поле **Анализировать время изменения пропуска** установлен, то выбирается наиболее позднее из времени последнего редактирования и времени последнего прохода по пропуску
488 11. Если флаг не установлен, выбирается время последнего прохода по пропуску.
489 1. Если «время активизации» раньше чем (% class="inline-code" %)##текущее время минус **Максимальный период неактивности**,##(%%) пропуск дополнительно помещается в группу устаревших пропусков.
490 1. Если указан режим работы «Приостановка и перемещение устаревших пропусков в группу», все найденные пропуска бессрочно приостанавливаются. В поле** Приостановлен с** задаётся текущее время.
491 )))
492 1. Нажмите на кнопку **Сохранить задание**.
493
494 {{error}}
495 **ВАЖНО**
496
497 В НЕЙРОСС пропуск не «привязывается» жёстко к одной группе. Принадлежность пропуска группе пропусков является просто свойством пропуска. Пропуск может принадлежать нескольким группам одновременно. При помещении пропуска в группу **Устаревшие пропуска**, пропуск остаётся также и в групе, в которой он располагался до запуска скрипта. Изъятие пропуска из группы осуществляется оператором АРМ Доступ с помощью команды (% style="text-align: left;" %)**Другие действия** (% style="text-align: left;" %)**> Действие с группами > Изъять из текущей группы.**
498 {{/error}}
499
500 === {{id name="Контрольактивностипропуска-Запускзадания"/}}Запуск задания ===
501
502 Дождитесь выполнения условия запуска задания или запустите задание вручную. Для ручного запуска в поле **Тип сигнала** выберите значение **По HTTP-запросу**, сохраните задание и нажмите отправить запрос(%%).
503
504 [[image:attach:task_run_manually.png||height="205"]]
505
506 Вы можете отслеживать процедуру инициализации и выполнения задания в Журнале аудита ~[[[doc:ui.Журнал аудита.WebHome]]].
507
508 [[image:attach:card_inactivity_scrypt_log.png||width="900"]]
509
510 Запуск и выполненные скриптом действия фиксируются в системном журнале ~[[[doc:ui.Системный журнал.WebHome]]].
511
512 [[image:attach:card_inactivity_journal.png]]
513
514 Если в поле** Режим работы** задана необходимость приостановки пропуска. В системном журнале отражается факт блокировки действия на контроллерах и задания срока приостановки с текущего времени:
515
516 [[image:attach:card_inactivity_journal1.png]]
517
518 Пропуска приостанавливаются с текущего времени, свойство **Приостановлен скриптом** у приостановленных пропусков устанавливается в значение **Да** (true).
519
520 [[image:attach:card_inactivity_card_form.png||height="250"]]

Платформа НЕЙРОСС