Функция поиска email owned by в таблице Service

Функция поиска email owned by в таблице Service

(function runNotificationScript(
    /* SimpleRecord */ current,
    /* SimpleTemplatePrinter */ template,
    /* SimpleEmailOutbound */ email,
    /* SimpleRecord */ event
    ) {
function ifLastRecord(){
let lastRecord = null;
const forRecord = new SimpleRecord('sys_cmdb_ci_service');
forRecord.addEncodedQuery('^ORDERBYDESCsys_created_at');
forRecord.setLimit(1);
forRecord.query();

if (forRecord.next()) {
    lastRecord = forRecord.owned_by.email;
}
//print("Last created record in sys_cmdb_ci_service: " + lastRecord);
return lastRecord
}
function GetBusinessServiceOwnerEmail(service){
  let emails = '';
  const current_service = new SimpleRecord('sys_cmdb_ci_service');
  current_service.addQuery('sys_id', service);
  current_service.selectAttributes(['service_type','owned_by']);
  current_service.query();
  current_service.next();
  while(current_service.owned_by.email==null || current_service.service_type != 'Business'){
    current_service.addQuery('sys_id',service);
    current_service.selectAttributes(['sys_id','service_type','master_service','owned_by']);
    current_service.query();
    current_service.next();
    emails = current_service.owned_by.email;
    service = current_service.master_service.sys_id;
  };
return emails;
}
if (current.service.owned_by.email != null) {
  return current.service.owned_by.email
}
if (GetBusinessServiceOwnerEmail(current.service.sys_id) == ifLastRecord()) {//Если последняя запись в таблице, значит не нашли не owner не master_owner
   return  ss.getProperty('itsm_request.tempServiceOwnerEmail');
}
else if (current.service.owned_by.email == null) {
  let business_owner = GetBusinessServiceOwnerEmail(current.service.sys_id)
  return business_owner
}

})(current, template, email, event);

​Notification Rule:

Name: Service dissatisfaction notification to owner ​Table: itsm_task

Inherited: true ​Condition: Service Swatisfaction is Below Expectation

Active: true

When to Send: Record is Updated ​Who will receive: Other recipients: ${script:getOwnerEmail} ​
​В письме просто сообщение о том, что клиент недоволен сервисом ​

​Цель поста не столько поделиться решением, сколько получить совет как данный код можно написать логичнее, и сделать оптимизацию ​
Необходима функция бесконечного поиска owned_by.email по сервису или если его нет то по мастер_сервису
В комментариях буду рад критике и советам ​

2 лайка

Привет, Илья! Я бы оптимизировал вот так. НЕ ТЕСТИРОВАЛ. Чего в моем скрипте не хватает - защиты в рекурсии от infinite loop. Будет меньше обращений к базе данных через SimpleRecord.query() и, похоже, функция ifLastRecord() не нужна.

Из общей практики:

  1. Проверка на [null, 0, пустую строку]: if (!myVar) { /Что-то пусто тут/ }
  2. Используем setLimit(1) везде, где ожидаем одну запись (наш случай - фильтр по sys_id)
  3. Сравнения всегда делаем строгие с помощью === или !==. Это позволит на ранних этапах разработки определить тонкие моменты с преобразованием типов данных.

Я не уверен насчет ifа с " currentService.service_type !== ‘Business’", чего Вы хотели этим добиться?

(function runNotificationScript(
    /*SimpleRecord */ current,
    //eslint-disable-next-line no-unused-vars
    /*SimpleTemplatePrinter */ template,
    //eslint-disable-next-line no-unused-vars
    /*SimpleEmailOutbound */ email,
    //eslint-disable-next-line no-unused-vars
    /*SimpleRecord */ event,
) {
    function GetBusinessServiceOwnerEmail(service) {
        if (!service) {
            return null; //Проверка, что нам дали параметр для вызова функции
        }
        const currentService = new SimpleRecord('sys_cmdb_ci_service');
        currentService.addQuery('sys_id', service);
        currentService.selectAttributes(['sys_id', 'service_type', 'owned_by', 'master_service']);
        currentService.setLimit(1); //Ищем по sys_id, значит ожидаем одну запись
        currentService.query();
        if (!currentService.next()) {
            //Не нашли сервис по sys_id
            return null;
        }
        if ((!currentService.owned_by.email || currentService.service_type !== 'Business') && currentService.master_service) {
            return GetBusinessServiceOwnerEmail(currentService.getValue('master_service')); //Рекурсивный вызов GetBusinessServiceOwnerEmail для непустого master_service
        }
        if (!currentService.owned_by) {
            return null; //У сервиса нет владельца
        }
        return currentService.owned_by.email;
    }

    if (current.service.owned_by.email) {
        return current.service.owned_by.email;
    }
    const serviceOwnerEmail = GetBusinessServiceOwnerEmail(current.getValue('service'));

    if (!serviceOwnerEmail) {
        //Нет почты service owner
        return ss.getProperty('itsm_request.tempServiceOwnerEmail');
    }
    return serviceOwnerEmail;
//eslint-disable-next-line no-undef
})(current, template, email, event);

С уважением, Никита

1 лайк

Я так понимаю, что в service хранится ID записи.
В таком случае лучше использовать имя serviceID.

Если мы ищем по sys_id, то почему бы не использовать метод SimpleRecord.get(id)?
Тогда не нужно устанавливать лимит и писать какие-либо ещё запросы.
Не понадобиться вызов currentService.query().
А вместо проверки if (!currentService.next()) можно будет использовать проверку if (!currentService.sys_id)

1 лайк

Да, это вариант.
SimpleRecord.get(id)

Но обязательно проверка if (!currentService.sys_id) {/* Не нашли, не процессим */}