Source code for metrics.notion

"""Notion related functions and classes"""

import logging
import os
import sys
from typing import Optional

import pandas as pd
import plotly.express as px
import plotly.graph_objects as go
import requests

from metrics.tempo_config import EUR2SEK


[docs]class Notion: """ I'M A DOCSTRING SHORT AND STOUT """ token: str database_id: str def __init__(self, token: Optional[str] = None, database_id: str = "") -> None: token = token or os.environ.get("NOTION_KEY") if token is None: sys.exit("Notion token not provided or NOTION_KEY not set") self.token = token self.database_id = database_id
[docs] def fetch_data(self, database_id) -> requests.Response: url = f"https://api.notion.com/v1/databases/{database_id}/query" response = requests.post( url, headers={"Authorization": f"Bearer {self.token}", "Notion-Version": "2022-06-28"}, timeout=30 ) return response
[docs]class WorkingHours(Notion): "The class for working hour handling" data: pd.DataFrame
[docs] def get_workinghours(self) -> None: result_dict = self.fetch_data(self.database_id).json() data = pd.DataFrame(columns=["User", "Daily", "Delta", "Start", "Stop"]) for item in result_dict["results"]: user = item["properties"]["User"]["title"][0]["plain_text"] daily = item["properties"]["Daily"]["number"] delta = item["properties"]["Delta"]["number"] start = item["properties"]["Start"]["rich_text"][0]["plain_text"] stop = item["properties"]["Stop"]["rich_text"][0]["plain_text"] data.loc[-1] = [user, daily, delta, start, stop] data.index = data.index + 1 self.data = data.sort_values(by=["User"])
[docs]class Allocations(Notion): "The class for allocations" data: pd.DataFrame
[docs] def get_allocations(self) -> None: result_dict = self.fetch_data(self.database_id).json() data = pd.DataFrame(columns=["User", "Allocation", "Start", "Stop", "Unconfirmed", "JiraID"]) for item in result_dict["results"]: user = item["properties"]["Assign"]["people"][0]["name"] allocation = item["properties"]["Allocation"]["number"] start = item["properties"]["Date"]["date"]["start"] stop = item["properties"]["Date"]["date"]["end"] unconfirmed = item["properties"]["Unconfirmed"]["checkbox"] jiratext = item["properties"]["Task ID"]["rich_text"] if jiratext == []: jiraid = "?" else: jiraid = jiratext[0]["plain_text"] data.loc[-1] = [user, allocation, start, stop, unconfirmed, jiraid] data.index = data.index + 1 self.data = data.sort_values(by=["User"])
[docs]class Crew(Notion): "The class for crew data" data: pd.DataFrame
[docs] def get_crew(self) -> None: result_dict = self.fetch_data(self.database_id).json() data = pd.DataFrame(columns=["User", "Role", "Hours", "Total cost", "UserId"]) for item in result_dict["results"]: user = item["properties"]["Person"]["people"][0]["name"] jira_id = item["properties"]["JIRA ID"]["rich_text"][0]["plain_text"] role = item["properties"]["Role"]["select"]["name"] currency = item["properties"]["Currency"]["select"]["name"] cost = item["properties"]["Total Cost"]["number"] / (EUR2SEK if currency == "SEK" else 1) hours = item["properties"]["Consulting Hours"]["number"] data.loc[-1] = [user, role, hours, cost, jira_id] data.index = data.index + 1 self.data = data.sort_values(by=["User"])
[docs]class Financials(Notion): "The class for finance data" data: pd.DataFrame
[docs] def get_financials(self) -> None: result_dict = self.fetch_data(self.database_id).json() data = pd.DataFrame(columns=["Month", "External_cost", "Real_income", "Starting_amount"]) for item in result_dict["results"]: month = item["properties"]["Month"]["title"][0]["plain_text"] extcost = item["properties"]["external-cost"]["formula"]["number"] income = item["properties"]["real-income"]["formula"]["number"] sekstart = item["properties"]["SEK Start"]["number"] eurstart = item["properties"]["EUR Start"]["number"] start = 0 if sekstart is not None: start += sekstart / EUR2SEK if eurstart is not None: start += eurstart abcost = item["properties"]["AB-Cost"]["number"] oycost = item["properties"]["OY-Cost"]["number"] if oycost is not None and abcost is not None: data.loc[-1] = [month, extcost, income, start] data.index = data.index + 1 self.data = data.sort_values(by=["Month"]) current_finances = 0 for i in range(len(self.data) - 1, 0, -1): start = self.data["Starting_amount"][i] current_finances += self.data["Real_income"][i] - self.data["External_cost"][i] + start if start != 0: break # Add 5 projected cost entries based on recent average extaverage = ( sum(self.data["External_cost"][-3:]) + sum(self.data["External_cost"][-2:]) + sum(self.data["External_cost"][-1:]) ) / 6 y, m = list(map(int, self.data.tail(1)["Month"][self.data.index.max()].split("-"))) for i in range(5): extcost = extaverage m = (m % 12) + 1 y = y + 1 if m == 1 else y # if dec -> jan then increase year m_ = f"0{m}" if m < 10 else str(m) month = f"{y}-{m_}" self.data.loc[-1] = [month, extcost, 0, current_finances] self.data.index = self.data.index + 1 current_finances = 0 logging.debug("Financial data\n%s", self.data)