...

Реализация своего метода API для получения файлов в формате base64 из сторонней системы

Тема в разделе "Скрипты и разработка", создана пользователем grebina, 7 июн 2023.

  1. grebina

    grebina Техническая поддержка

    Задача: реализовать метод API для создания элемента приложения "Входящее письмо" в ELMA365 (например, из 1С) с заполнением контекстных переменных типа Приложение и переменной типа "Файлы"-Несколько.

    Вводные данные:
    Контекст приложения "Входящие письма":
    [​IMG]
    1. Отправитель (sender) тип Приложение - "Контрагенты" - Один. Контрагенты - приложение в этом же разделе.
    2. Подписал (signatory) тип Приложение - "Контактные лица" - Один. Контактные лица - приложение в этом же разделе.
    3. Проект (project) тип Приложение - "Проекты" - Один. Проекты - приложение в этом же разделе.
    4. Ответственный (assignee) тип Пользователи-Один.
    5. Файлы (files) тип Файлы-Несколько.
    Условия:
    1. Из сторонней системы передаётся массив файлов с двумя параметрами:
      - название файла,
      - содержимое файла в формате base64
      Если массив не пустой, письмо создаётся с файлами.
    2. Для заполнения проекта в body передаётся строка "projectCode". По этому значению выполняется поиск Проекта по совпадению с переменной "kod1C" типа Строка. Если Проект не найден, письмо создаётся без проекта.
      [​IMG]
    3. Для заполнения Ответственного в body передаётся строка "assigneeFIO". По этому значению выполняется поиск Пользователя по совпадению с "__name". Если пользователь не найден, письмо создаётся без ответственного.
    4. Для заполнения Контрагента в body передаются строки name, fullname, inn, kod1C. По значению "inn" выполняется поиск контрагента. Если Контрагент не найден, создаётся новый Контрагент.
      [​IMG]
    5. Для заполнения Контактного лица в body передаются строки fio, position . По значению "fio" выполняется поиск Контактного лица по совпадению с "__name". Если Контактное лицо не найдено, создаётся новое.
      [​IMG]
    Реализация:

    Создаём свой модуль в разделе Администрирование-Модули.

    В настройки модуля добавляем все приложения, которые нам понадобятся для создания Входящего письма:
    [​IMG]
    Создаём метод API "incoming_letter_create" тип POST:
    [​IMG]
    В методах API на вкладке Сценарии появится наш метод async function incoming_letter_create(req: FetchRequest): Promise<HttpResponse | void> {}

    Перед его реализацией добавим метод конвертации строки base64 в тип ArrayBuffer:
    Код:
    
    //функция конвертации строки base64 в тип ArrayBuffer
    function base64ab(base64: string): ArrayBuffer {
      const 
    binary_string = atob(base64);
      const 
    len = binary_string.length;
      const 
    bytes = new Uint8Array(len);
      for (var 
    i = 0; i < len; i++) { bytes[i] = binary_string.charCodeAt(i); }
      return 
    bytes.buffer;
    }
    Затем реализуем наш метод API incoming_letter_create . Весь код сценариев API модуля:
    Код:
    
    //функция конвертации строки base64 в тип ArrayBuffer
    function base64ab(base64: string): ArrayBuffer {
      const 
    binary_string = atob(base64);
      const 
    len = binary_string.length;
      const 
    bytes = new Uint8Array(len);
      for (var 
    i = 0; i < len; i++) { bytes[i] = binary_string.charCodeAt(i); }
      return 
    bytes.buffer;
    }

    async function incoming_letter_create(req: FetchRequest): Promise<HttpResponse | void> {
      const 
    response = new HttpResponse()
      const 
    request = JSON.parse(req.body! as string)//получаем body

      
    const letterName = request['name']
      const 
    assigneeFIO = request['assigneeFIO']
      const 
    projectCode = request['projectCode']
      const 
    contractorName = request['contractor']['name']
      const 
    contractorFullname = request['contractor']['fullname']
      const 
    contractorINN = request['contractor']['inn']
      const 
    contractorKod1C = request['contractor']['kod1C']
      const 
    cotactFIO = request['contact']['fio']
      const 
    cotactPosition = request['contact']['position']
      const 
    description = request['description']
      const 
    filesData = request['files']


      
    let project = await Namespace.params.fields.project1c.app.search().where((f, g) => g.and(f.kod1C.eq(projectCode), f.__deletedAt.eq(null))).first()//ищем проект по полю kod1C

      
    let assignee = await System.users.search().where((f, g) => g.and(f.__name.like(assigneeFIO), f.__deletedAt.eq(null))).first()//ищем Пользователя по ФИО

      
    let contractor = await Namespace.params.fields.contractors.app.search().where((f, g) => g.and(f.inn.eq(contractorINN), f.__deletedAt.eq(null))).first()//ищем контрагента по ИНН

      
    if (!contractor) {//если не нашли, создаём контрагента
        
    contractor = Namespace.params.fields.contractors.app.create()
        
    contractor.data.__name = contractorName
        contractor
    .data.fullname = contractorFullname
        contractor
    .data.inn = contractorINN
        contractor
    .data.kod1c = contractorKod1C
        await contractor
    .save()
      }

      
    let contact = await Namespace.params.fields.contacts.app.search().where((f, g) => g.and(f.__name.like(cotactFIO), f.__deletedAt.eq(null))).first()//ищем Контактное лицо по ФИО
      
    if (!contact) {//если не нашли, создаём контакт
        
    contact = Namespace.params.fields.contacts.app.create()
        
    contact.data.__name = cotactFIO
        contact
    .data.position = cotactPosition
        contact
    .data.contractors = contractor
        await contact
    .save()
      }

      
    let newIncomingletter = Namespace.params.fields.incoming_letter.app.create() //создаём входящее письмо
      
    newIncomingletter.data.__name = letterName;//Тема
      
    newIncomingletter.data.description = description;//описание
      
    newIncomingletter.data.sender = contractor;//Отправитель
      
    newIncomingletter.data.signatory = contact;//Подписал
      
    if (project) {
        
    newIncomingletter.data.project = project//проект
      
    }
      if (
    assignee) {
        
    newIncomingletter.data.assignee = assignee//Ответственный
      
    }
      if (
    filesData)//если указан массив файлов
      
    {
        const 
    filesArray: FileItem[] = []
        for (
    let i in filesData) {//массив данных файлов
          
    if (i) {
            
    let fileName = filesData[i].fileName as string; //получаем название файла
            
    let content = filesData[i].base64 as string;//получаем контент в base64
            
    if (content) {
              
    let abContent = base64ab(content)//вызываем метод конвертации base64 в ArrayBuffer
              
    if (fileName && abContent) {
                
    let file = await Namespace.params.fields.file.create(fileName, abContent)//создаём файл
                
    filesArray.push(file)
              }

            }
          }


        }
        
    newIncomingletter.data.files = filesArray;//заполняем переменную Файлы
      
    }
      
    await newIncomingletter.save()//сохраняем письмо

      
    try {
        const 
    letterId = newIncomingletter.data.__id//получаем id созданного письма и возвращаем его в ответе сервера
        
    response
          
    .status(200)
          .
    json({
            
    msg: 'success',
            
    letterId: letterId,
          })
          .
    set('Content-Type', 'application/json')
      }
      catch (
    e) {
        
    response
          
    .status(500)
          .
    json({
            
    msg: 'error: ' + e.message,
          })
          .
    set('Content-Type', 'application/json')
      }
      return 
    response
    }
    Для использования метода нужно корректно заполнить body. Пример body можно посмотреть во вложениях к статье.

    Вложения:

    Последнее редактирование: 7 июн 2023