Untitled

mail@pastecode.io avatar
unknown
plain_text
7 months ago
12 kB
2
Indexable
Never
from jupytercloud.library import get_secret
import requests
import json
import pandas as pd
import numpy as np
from openpyxl import load_workbook
from io import BytesIO
import ast


# Получение токена из секрета
TrackerOauthToken = get_secret('sec-01hbdac4pph2h48dwacme1x15h')
TOKEN = TrackerOauthToken.get('TOKEN')

# Параметры запроса
HEADERS = {
    'Authorization': f'OAuth {TOKEN}',
    'Content-Type': 'application/json'}
URL = 'https://st-api.yandex-team.ru/v2/issues/'

# Фильтрация тикетов через query
start_date = "01.09.2023"
end_date = "30.09.2023"
query = f'Queue: Заявки ("Новая Зарплата": notEmpty() OR Теги:Массовое_повышение OR "Новая тарифная ставка":notEmpty()) (Статус: ! "Отмена заявки" Статус: !"В работе" Статус: !Проверка Статус: !"Ждем подтверждения" Статус: !"Согласование в HR") Резолюция: !Некорректный Резолюция: ! "Не будет исправлено" Резолюция: ! Duplicate Резолюция: ! "Дубликат (подзадача)" "Дата повышения": >= {start_date} "Дата повышения": < {end_date}'
filter = {
  'filter': {
  },
  'query': f'{query}'
}

# Список для всех тикетов, полученных из запроса
data = []

# Первый запрос
response_scroll = requests.post(f'{URL}_search?scrollType=unsorted&perScroll=1000', headers=HEADERS, data=json.dumps(filter))

# Cледующие запросы
if response_scroll.status_code == 200:
    
    try:
        
        while True:
            
            response_data = response_scroll.json()
            data.extend(response_data)

            # Если прокрутка еще не закончена, возвращаются заголовки X-Scroll-Id и X-Scroll-Token,
            # значения которых можно передать в параметрах scrollId и scrollToken соответственно для получения следующей страницы результатов.
            X_Scroll_Id = response_scroll.headers.get('X-Scroll-Id')
            X_Scroll_Token = response_scroll.headers.get('X-Scroll-Token')

            if not X_Scroll_Id or not X_Scroll_Token:
                break
                
            # Последующие запросы, состаленные используюя scrollId и scrollToken из заголовков предыдущих запросов
            response_scroll = requests.post(f'{URL}_search?scrollId={X_Scroll_Id}&scrollToken={X_Scroll_Token}', headers=HEADERS, data=json.dumps(filter))

    
    except json.JSONDecodeError as e:
        print(f'Failed to decode JSON: {e}')
        
    except:
        print(f'Request error: {response_scroll.status_code}')

# Данные по полям тикетов SALARY
keys = []
employees = []
logins = []
summaries = []
statuses = []
assignees = []
dates = []
bp_numbers = []
current_tariff_rates = []
new_tariff_rates = []
current_salaries = []
new_salaries = []
organizations = []
entities = []
transactions = []
systems = []
currencies = []
components = []

# Данные по тикетам с массовым повышением SALARY
mass = []

for ticket in data:
        tag = [tag for tag in ticket.get('tags', {})]
        
        if "Массовое_повышение" not in tag:

            keys.append(ticket.get('key', {}))
            employees.append(ticket.get('employee', {}).get('display', {}))
            logins.append(ticket.get('employee', {}).get('id', {}))
            summaries.append(ticket.get('summary', {}))
            statuses.append(ticket.get('status', {}).get('display', {}))
            assignees.append(ticket.get('assignee', {}).get('display', {}))
            dates.append(ticket.get('raiseDate', {}))
            bp_numbers.append(ticket.get('bpNumber', {}))
            current_tariff_rates.append(ticket.get('urrentTariffRate', {}))
            new_tariff_rates.append(ticket.get('rateTariff', {}))
            current_salaries.append(ticket.get('currentSalary', {}))
            new_salaries.append(ticket.get('newSalary', {}))
            organizations.append(ticket.get('organization', {}))
            entities.append(ticket.get('legalEntity2', {}).get('display', {}))
            transactions.append(ticket.get('5fedc3773bcd8c3a56eb7ef5--priznakSdelka', {}))
            systems.append(ticket.get('salarySystem', {}))
            currencies.append(ticket.get('currency', {}))
            components.append([component['display'] for component in ticket.get('components', {})])
            
        else:
            
            key_mass = ticket.get('key', {})
            summary_mass = ticket.get('summary', {})
            status_mass = ticket.get('status', {}).get('display', {})
            assignee_mass = ticket.get('assignee', {}).get('display', {})
            date_mass = ticket.get('raiseDate', {})
            component_mass = [component['display'] for component in ticket.get('components', {})]
                    
            # Создаём словарь с данными по тикетам с массовым повышением
            dict_mass = {'key': key_mass, 'summary': summary_mass, 'status': status_mass, 'assignee': assignee_mass, 'date': date_mass, 'component': component_mass}
            mass.append(dict_mass)

with pd.ExcelWriter('Кадровая сверка.xlsx', engine='xlsxwriter') as writer:
    
    # Создаём датафрейс с данными по тикетам
    df_main = pd.DataFrame({
            'Ключ тикета': keys,
            'Сотрудник': employees,
            'Логин': logins,
            'Задача': summaries,
            'Статус': statuses,
            'Исполнитель': assignees,
            'Дата повышения': dates,
            'Номер БП': bp_numbers,
            'Текущая тарифная ставка': current_tariff_rates,
            'Новая тарифная ставка': new_tariff_rates,
            'Текущая зарплата': current_salaries,
            'Новая зарплата': new_salaries,
            'Оклад': None,
            'Валюта': None,
            'Ставка': None,
            'Организация': organizations,
            'Юридическое лицо 2.0': entities,
            'Признак сделка': transactions,
            'Система оплаты труда': systems,
            'Компоненты': components
        })

    # Разбиваем столбец 'Новая зарплата' на 'Оклад', 'Валюта', 'Ставка'
    # Орабатываем исключения в столбце 'Оклад'
    # 'Компоненты' представляем в виде строки
    df_main['Оклад'] = df_main['Новая зарплата'].str.extract(r'(\d[\d\s.,]*)')
    df_main['Оклад'] = df_main['Оклад'].str.replace(r'\s,', '', regex=True).str.replace(',', '.', regex=True)
    df_main['Валюта'] = df_main['Новая зарплата'].str.extract(r'([A-Z]+)').fillna('')
    df_main['Ставка'] = df_main['Новая зарплата'].str.extract(r'\(([^)]+)\)')
    df_main['Ставка'] = df_main['Ставка'].apply(lambda x: None if x == 'None' else x)
    df_main['Компоненты'] = df_main['Компоненты'].apply(lambda x: ', '.join(map(str, x)))
    
    df_main = df_main.replace([{}], value=np.NaN)
    df_main.fillna('', inplace=True)
    df_main.index = pd.RangeIndex(1, len(df_main)+1, name='№') 

    # Сохраняем датафрейм с данными по всем тикетам кроме массовых на первом листе эксель 'Выгрузка'
    df_main.to_excel(writer, sheet_name='Выгрузка', index=True, header=True)
    
    
    for mass_ticket in mass:
        
        key = mass_ticket.get('key')
        summary = mass_ticket.get('summary')
        status = mass_ticket.get('status')
        assignee = mass_ticket.get('assignee')
        date = mass_ticket.get('date')
        component = [component for component in mass_ticket.get('component')]
        
        # Запрос для получения списка вложений в массовых тикетах
        response_mass = requests.get(f'{URL}{key}/attachments', headers=HEADERS)
        
        attach_id = response_mass.json()[0].get('id')
        attach_name = response_mass.json()[0].get('name')

        # Запрос для получения ссылки на скачивание кокретного вложения
        response_attach = requests.get(f'{URL}{key}/attachments/{attach_id}/{attach_name}', headers=HEADERS)
        
            
        try:
            
            # Содержимое вложения представляем в виде датафрейма
            df_mass = pd.read_excel(BytesIO(response_attach.content), skiprows=[0], header=0)

            # Дополняем вложение данными из массового тикета
            df_mass['Ссылка на тикет'] = key
            df_mass.insert(1, 'Задача', summary)
            df_mass.insert(2, 'Исполнитель', assignee)
            df_mass.insert(3, 'Статус', status)
            df_mass.insert(4, 'Дата повышения', date)
            df_mass.insert(5, 'Компоненты', str(component))
            df_mass['Компоненты'] = df_mass['Компоненты'].apply(lambda x: ', '.join(map(str, ast.literal_eval(x))))

            df_mass.index = pd.RangeIndex(1, len(df_mass)+1, name='№')
            
            # Сохраняем датафрейм с данными по массовым тикетам на листах эксель
            df_mass.to_excel(writer, sheet_name=f'Mass_{key}', index=True)

        
        except Exception as e:
            print(f'Error reading attached file: {e}', mass_ticket)
        
        
        # Запрос для получения комментариев к массовому тикету
        response_comment = requests.get(f'{URL}{key}/comments', headers=HEADERS)

        
        try:

            comment_list = []
            comments = response_comment.json()

            for comment in comments:

                author = comment.get('createdBy', {}).get('display', {})
                date = comment.get('createdAt', {})
                text = comment.get('text', {})

                # Создаём словарь с данными по всем комментариям к тикету
                dict = {'Автор': author, 'Создан': date, 'Текст': text}
                comment_list.append(dict)

            # Создаём датафрейс с данными по комментариям к массовому тикету
            df_comm = pd.DataFrame(comment_list)
            
            df_comm.index = pd.RangeIndex(1, len(df_comm)+1, name='№')

            # Сохраняем датафрейм с комментариями к массовым тикетам на листах эксель
            df_comm.to_excel(writer, sheet_name=f'Comments_{key}', index=True)


        except Exception as e:
            print(f'Error reading comments: {e}', mass_ticket)