scripts:sample

Примеры скриптов

Скопировать значение одного поля в другое

Копируем значение из поля 'Поле-источник' в поле 'Текстовое поле'.

form.onChange(['Поле-источник'], true)
  .setValue('Текстовое поле', state => {
    const [value] = state.changes;
    return value.text;
  });

Вычислить сумму (разницу, процент) нескольких полей

В этом примере скрипт прибавляет премию сотрудника к его окладу и рассчитывает НДФЛ от полученной суммы. Затем вычитает НДФЛ из этой суммы и выводит итоговую выплату за месяц.

form.onChange(['Оклад', 'Премия'])
  .setValues(['НДФЛ (13%)', 'Итого к выплате за месяц'], state => {
    const [salary, bonus] = state.changes;
    const ndflTax = (salary.value + bonus.value) * 0.13;
    const result = (salary.value + bonus.value) - ndflTax;
    return [ndflTax, result];
  });

Сделать поле невидимым

В этом примере поле 'Оптовая скидка' скрыто, если значение в поле 'Количество' не превышает 99.

form.onChange(['Количество'], true)
  .setVisibility(['Оптовая скидка'], state => {
    const num = state.changes[0].value;
    return num > 99;
  });

Сделать поле невидимым, начиная с определённого этапа

В этом примере поле 'Клиент' будет скрыто, начиная со второго этапа.

form.onChange([''], true)
  .setVisibility (['Клиент'], state => {
    return state.currentStep < 2;
 });

Вывести значение колонки справочника

Здесь 'Справочник' — название поля с вашим справочником, 'Колонка' — название колонки справочника, а 'Текст' - поле типа Текст, в котором будет сохранено значение.

form.onChange(['Справочник'])
  .setValue('Текст', state => {
    const [item] = state.changes;
    return item.columns['Колонка'];
  });

Выбор значения из справочника по полю с типом Контакт

Иногда требуется подставлять в заявку ФИО сотрудника в родительном падеже. Простой пример — заявление на отпуск. Чтобы Pyrus делал это автоматически, создаём справочник со списком сотрудников и колонкой с их ФИО в родительном падеже. И подключаем к форме такой скрипт:

form.onChange(['Отпускник'])
  .setValue('От (ФИО):', state => {
    const [contactField] = state.changes;
    
    if (!catalogItems || !contactField || !contactField.person_id)
      return null;
    
    const filteredRow = catalogItems
       .find(item => item.columns['Сотрудник'] == contactField.person_id);
    
    return filteredRow ? filteredRow.columns['ФИО Род'] : null;
  });

В этом примере:

  • 'Отпускник' — название поля типа Контакт;
  • 'Сотрудник' и 'ФИО Род' — название колонок справочника, в котором мы ищем значение по выбранному полю;
  • 'От (ФИО):' - поле типа Текст, в котором сохраняем найденное значение из справочника.

Валидация: дата окончания не раньше даты начала

form.onChange(['Дата начала', 'Дата окончания'])
  .validate('Дата окончания', state => {
    const [start, end] = state.changes;

    if (start.date && end.date && start.date >= end.date)
      return {
        errorMessage: 'Не может быть раньше даты начала'
      };

    return null;
  });

Валидация: заполнено хотя бы одно поле

form.onChange(['Эл. почта', 'Телефон'], true)
  .validate('Эл. почта', state => {
    const [email, phone] = state.changes;

    if (!email.text && !phone.text) 
      return {
        errorMessage: 'Заполните электронную почту или телефон'
      };

    return null;
  });

Перенос крайнего срока в зависимости от приоритета

C возможностью установки произвольного срока.

form.onChange(['Высокий приоритет', 'Перенос даты'])
  .setValue('Срок', state => {
    const [checkmark, customDue] = state.changes;

    if (customDue.date)
      return {date: customDue.date};

    if (checkmark.checked)
      return {days_from_create: 1};

    return {days_from_create: 3};
  });

Установка срока за N дней до указанной даты

В этом примере в зависимости от указанной при заполнении даты срок будет автоматически устанавливаться за семь дней до этой даты.

form.onChange(['Дата'])
  .setValues(['Срок'], state => {
    const [watchingField] = state.changes;
    const newValueForCalculatedField = new Date(watchingField.date + 'T10:00:00Z');
    const daysBeforeDate = 7;
    
    newValueForCalculatedField
      .setDate(newValueForCalculatedField.getDate() - daysBeforeDate);
    
    return [{date: newValueForCalculatedField.toDateString()}];
  });

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

Скрипт подойдёт тем, кто в рамках задачи работает с партнёрами. В нашем примере статус задачи будет меняться на «В работе», если партнёр назначил ответственного в поле «Ответственный за решение».

    
const orgId = 
111111Индивидуальный номер организации, которая редактирует форму. Чтобы узнать ID, напишите на support@pyrus.com.
; form.onChange([], true) .setVisibility(['Открыта / Завершена'], state => false ); form.onChange([], true) .setStatus(state => { if (state.commenter.organization_id !== orgId) return {choice_name: 'В работе'}; }); form.onChange(['Ответственный за решение']) .setStatus(state => { const [currVal] = state.changes; const [prevVal] = state.prev; if (!prevVal && currVal) return {choice_name: 'В работе'}; });

Автоматическое заполнение срока SLA

Укажите в скрипте своё время решения и названия полей. Вместо числовых констант вы можете использовать переменные или формулы для расчёта времени решения. При изменении в заявке полей «Приоритет» и «Клиент» скрипт будет выполняться и устанавливать один из указанных в нём сроков.


form.onChange(['
ПриоритетНазвание поля типа «Справочник» в форме обращения
', '
КлиентНазвание поля типа «Справочник» в форме обращения
']) .setValue('
СрокНазвание поля типа «Срок» в форме обращения
', state => { const [priority, client] = state.changes; if (!priority || !client) return undefined; const tariff = client.columns['
ТарифКолонка справочника «Клиенты» с тарифами обслуживания
']; const priorityValue = priority.columns['
ПриоритетКолонка справочника «Приоритет»
']; const hours = getSlaHoursByTariffAndPriority(tariff, priorityValue); if (hours === undefined) return undefined; return {hours_from_create: hours}; }); function getSlaHoursByTariffAndPriority(tariff, priority) { switch (tariff) { case '
БазовыйНазвание тарифа (значение колонки справочника «Клиенты»)
': switch (priority) { case '
НизкийПриоритет (значение колонки справочника «Приоритет»)
' : return
64Срок в часах
; case '
СреднийПриоритет (значение колонки справочника «Приоритет»)
': return
32Срок в часах
; case '
ВысокийПриоритет (значение колонки справочника «Приоритет»)
': return
16Срок в часах
; } case '
СтандартНазвание тарифа (значение колонки справочника «Клиенты»)
': switch (priority) { case '
НизкийПриоритет (значение колонки справочника «Приоритет»)
' : return
32Срок в часах
; case '
СреднийПриоритет (значение колонки справочника «Приоритет»)
': return
16Срок в часах
; case '
ВысокийПриоритет (значение колонки справочника «Приоритет»)
': return
8Срок в часах
; } case '
ПремиумНазвание тарифа (значение колонки справочника «Клиенты»)
': switch (priority) { case '
НизкийПриоритет (значение колонки справочника «Приоритет»)
' : return
16Срок в часах
; case '
СреднийПриоритет (значение колонки справочника «Приоритет»)
': return
8Срок в часах
; case '
ВысокийПриоритет (значение колонки справочника «Приоритет»)
': return
4Срок в часах
; } default: return undefined; } }

Скрываем поле, если письмо пришло не от заданного адреса

Распознаём емейл из темы письма. Если письмо пришло не от mail@example.com — скрываем поле «Тип заявки».

const emailPattern = /([a-zа-яё0-9-._]+)\@([a-zа-яё0-9-._]+)\.([a-zа-яё]{2,3})/ig;   

form.onChange(['Тема письма'], true)
  .setValue('Тип заявки', state => {
    const [currVal] = state.changes;
    const emails = (currVal.text || '').match(emailPattern);
    const first = emails ? emails[0] : '';
    return first;
  });

form.onChange(['Email'], true)
  .setVisibility(['Тип заявки'], state => {
    const [choice] = state.changes;
    return choice && choice.text === "mail@example.com";
  });

Фильтрация справочника

Этот скрипт позволяет фильтровать список городов по выбранному региону. Другой пример — при выборе отдела показывать только статьи расходов, относящиеся к этому отделу.

let catalogItems = null;

form.getCatalog("
Города по регионамНазвание справочника, который связывает значения двух других справочников
").then(items => { catalogItems = items; }); form.onChange(["
РегионПоле, при изменении которого меняется список выбираемых значений в другом поле
"]).setFilter("
ГородПоле, значения в котором фильтруются в зависимости от выбора в первом поле
", state => { const [region] = state.changes; if (!catalogItems || !region || !region.columns) return null; const regionCol = region.columns["
РегионНазвание колонки, по значениям которой осуществляется фильтрация
"]; const filtered = catalogItems .filter(item => item.columns["
РегионНазвание колонки, по значениям которой осуществляется фильтрация
"] === regionCol) .map(item => item.columns["
ГородНазвание колонки, из которой берутся отфильтрованные значения
"]); return filtered.length > 0 ? { values: filtered } : null });

Установка даты в рабочих днях

Этот скрипт позволяет задавать дату с учётом выходных дней. Даты выходных и рабочих дней берутся из справочника.

var catalogHolidayItems = null;
var catalogWorkingItems = null;

// Получаем массив дат из справочника "Даты перенос" со столбцами "Даты перенос", "Тип"
form.getCatalog("Даты перенос").then(items => {
  catalogHolidayItems = items.filter(item => item.columns["Тип"] === 'Выходной')
    .map(item => item.columns["Даты перенос"]);
  catalogWorkingItems = items.filter(item => item.columns["Тип"] === 'Рабочий')
    .map(item => item.columns["Даты перенос"]);  
});

// Поиск даты в массиве
function dateInArray(mydate, array) {
  for (let i = 0; i < array.length; i++) {
    if (mydate.getTime() === array[i].getTime()) {
      return true;
    }
  }
  return false;
}

// Количество и список выходных и праздничных дней
form.onChange(['Дата','Дата окончания']).setValues(['Список выходных дней', 'Число выходных между датами'], 
  state => {
    const [startDateField, endDateField] = state.changes;
    if (!startDateField || !endDateField)
      return null;
    const startDate = new Date(startDateField.date);
    const endDate = new Date(endDateField.date);
       
    let weekends = 0;
    const holidays_array = [];
    const working_array = [];

    for (let j=0; j < catalogHolidayItems.length; j++) {
      holidays_array.push(new Date(catalogHolidayItems[j] +  'T00:00:00Z'));
    }
    for (let j=0; j < catalogWorkingItems.length; j++) {
      working_array.push(new Date(catalogWorkingItems[j] +  'T00:00:00Z'));
    }

    const text_array = [];
    let text = '';

    const month_names = 'января,февраля,марта,апреля,мая,июня,июля,августа,сентября,октября,ноября,декабря'.split(',');
    while(startDate <= endDate) {
      if ( ((startDate.getDay() == 0 || startDate.getDay() == 6) && !dateInArray(startDate, working_array) )  
      || dateInArray(startDate, holidays_array) )  {
        weekends += 1;
        const dateText = [startDate.getDate().toString(), month_names[startDate.getMonth()], startDate.getFullYear().toString(), 'г.'].join(' ');
        text_array.push(dateText);
      }
      
      startDate.setDate(startDate.getDate() + 1);
    }

    if (text_array.length === 1) {
      text = text_array[0];
    }
    else if (text_array.length > 1){
      text = text_array.slice(0, text_array.length - 1).join(', ') + ' и ' + text_array[text_array.length - 1];
    }

    return [text, weekends];
 });

// Установка даты в рабочих днях    
form.onChange(['Дата','Кол-во дней']).setValues(['Дата + Кол-во рабочих дней'], 
  state => {
    const [startDateField, daysNum] = state.changes;
    if (!startDateField || !daysNum) 
      return null;
       
    const startDate = new Date(startDateField.date);
    const endDate = new Date(startDateField.date);
    endDate.setDate(endDate.getDate() + daysNum.value);
       
    const holidays_array = [];
    const working_array = [];

    for (let j=0; j < catalogHolidayItems.length; j++) {
      holidays_array.push(new Date(catalogHolidayItems[j] +  'T00:00:00Z'))
    }
    for (let j=0; j < catalogWorkingItems.length; j++) {
      working_array.push(new Date(catalogWorkingItems[j] +  'T00:00:00Z'))
    }
    
    do 
      {
        if ( ((startDate.getDay() == 0 || startDate.getDay() == 6) && !dateInArray(startDate, working_array) )  
        || dateInArray(startDate, holidays_array) )  {
          endDate.setDate(endDate.getDate()+1);
        }
        startDate.setDate(startDate.getDate()+1);
    }
    while(startDate <= endDate)
       
    return [{date: endDate.toDateString()}]; 
   });

Была ли эта статья полезной?

Да, спасибо! Нет, остался вопрос