Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update Deployment Branch #10

Merged
merged 29 commits into from
Oct 23, 2024
Merged
Changes from 1 commit
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
e92ca50
Add top clients, sponsors, and workers components.
ElemarJR Oct 21, 2024
1b8840a
Merge branch 'eximiaco-labs:main' into account_manager_home
ElemarJR Oct 21, 2024
850ef91
Add responsiveness and expand/collapse to lists on home page
ElemarJR Oct 21, 2024
f8ce9e2
Rename TitledSummary to CaseSummary and add case details.
ElemarJR Oct 21, 2024
0227d6c
Add CasesByContractEnd component to display case details
ElemarJR Oct 21, 2024
b37279f
Update client name access in CasesByContractEnd component
ElemarJR Oct 21, 2024
993c9c3
Add filtering by selectedStat in CasesByContractEnd
ElemarJR Oct 21, 2024
d58d114
Add CasesUpdates component to frontend and enhance backend details
ElemarJR Oct 21, 2024
4157cf6
Add redirect from root to /home page
ElemarJR Oct 21, 2024
1c9a41b
Add 'isRecognized' field to Account Managers query
ElemarJR Oct 21, 2024
bdc4883
Add execution time tracking to GraphQL requests
ElemarJR Oct 22, 2024
923eebb
Enhance timesheet summarization efficiency and flexibility.
ElemarJR Oct 22, 2024
8071821
Merge pull request #6 from ElemarJR/account_manager_home
ElemarJR Oct 22, 2024
c5a876f
Update project inconsistency names and adjust link in page.tsx
ElemarJR Oct 22, 2024
b0f6032
Add home link and improve sidebar navigation
ElemarJR Oct 22, 2024
ab20c42
Refactor filter component and update filter logic
ElemarJR Oct 22, 2024
1a0ca98
Merge pull request #7 from ElemarJR/filters_on_cases
ElemarJR Oct 22, 2024
e7df824
Moving UI components from home directory
ElemarJR Oct 22, 2024
f62351f
Add new ConsultantOrEngineerHome component
ElemarJR Oct 22, 2024
9ca997c
Merge branch 'eximiaco-labs:main' into consultants_home
ElemarJR Oct 22, 2024
505d458
Add Google OAuth2 authentication
ElemarJR Oct 22, 2024
cd9edb0
Merge branch 'consultants_home' of https://github.com/ElemarJR/omnisc…
ElemarJR Oct 22, 2024
ce4e3f1
Merge pull request #8 from ElemarJR/consultants_home
ElemarJR Oct 22, 2024
9cb1c25
Remove deprecated backend components
ElemarJR Oct 23, 2024
6efb14a
Refactor project structure and add SalesFunnelB2B model
ElemarJR Oct 23, 2024
37bf1ec
Refactor SalesFunnelB2B: move file to 'src' directory
ElemarJR Oct 23, 2024
363150f
Add unit tests for helper functions
ElemarJR Oct 23, 2024
b5805b0
Format GraphQL query and fix nullable data reference
ElemarJR Oct 23, 2024
77b0248
Merge pull request #9 from ElemarJR/main
ElemarJR Oct 23, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Remove deprecated backend components
Deleted obsolete dashboard decorators and helper files, including component.py, key.py, kpi.py, and x9.py. Streamlined timesheet_dataset.py, semanticmodel.py, and tasksmanager.py by removing unnecessary methods and imports. Updated frontend/package.json to simplify the dev script.
ElemarJR committed Oct 23, 2024
commit 9cb1c25b58515f46108c77b5fcfdfa44fba03038
7 changes: 0 additions & 7 deletions backend/models/base/key.py

This file was deleted.

3 changes: 1 addition & 2 deletions backend/models/base/powerdataframe.py
Original file line number Diff line number Diff line change
@@ -185,5 +185,4 @@ def get_weekly_summary(self, by, alias=None, operation="sum", on='TimeInHs',
if alias is not None:
result.rename(columns={by: alias}, inplace=True)

return result

return result
7 changes: 1 addition & 6 deletions backend/models/base/semanticmodel.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,4 @@
from abc import ABC, abstractmethod


class SemanticModel(ABC):

@property
def common_queries(self):
return None

pass
Empty file.
17 changes: 0 additions & 17 deletions backend/models/dashboard/component.py

This file was deleted.

72 changes: 0 additions & 72 deletions backend/models/dashboard/kpi.py

This file was deleted.

75 changes: 0 additions & 75 deletions backend/models/dashboard/x9.py

This file was deleted.

187 changes: 1 addition & 186 deletions backend/models/datasets/timesheet_dataset.py
Original file line number Diff line number Diff line change
@@ -138,189 +138,4 @@ def get_last_four_weeks_ltes(self) -> SummarizablePowerDataFrame:
.filter_by(by='CreatedAtWeek', not_equals_to=previous6)
)

return data


def get_six_weeks_allocation_analysis(
df: pd.DataFrame,
date_of_interest: datetime,
column_of_interest: str = 'WorkerName'
):
week_day = (date_of_interest.weekday() + 1) % 7
week = Weeks.get_week_string(date_of_interest)
output_column_name = beauty.convert_to_label(column_of_interest)

df = df[df['NDayOfWeek'] <= week_day]
df_left = df[df['Week'] != week]
df_right = df[df['Week'] == week]

summary_left = df_left.groupby([column_of_interest, 'Week'])['TimeInHs'].sum().reset_index()
summary_left = summary_left.groupby(column_of_interest)['TimeInHs'].mean().reset_index()
summary_left.rename(columns={'TimeInHs': 'Mean'}, inplace=True)

summary_right = df_right.groupby(column_of_interest)['TimeInHs'].sum().reset_index()
summary_right.rename(columns={'TimeInHs': 'Current'}, inplace=True)
merged_summary = pd.merge(summary_left, summary_right, on=column_of_interest, how='outer').fillna(0)
merged_summary.rename(columns={column_of_interest: output_column_name}, inplace=True)

merged_summary['Total'] = merged_summary['Current'] + merged_summary['Mean']
merged_summary = merged_summary.sort_values(by='Total', ascending=False).reset_index(drop=True)
merged_summary.drop(columns=['Total'], inplace=True)

conditions = [
merged_summary['Current'] > merged_summary['Mean'],
merged_summary['Current'] < merged_summary['Mean'],
merged_summary['Current'] == merged_summary['Mean']
]
choices = [1, -1, 0]

merged_summary['Status'] = np.select(conditions, choices, default=0)

cols = ['Status', output_column_name, 'Mean', 'Current']
return merged_summary[cols]


class TimesheetDateAnalysis:
def __init__(self, df, date_of_interest: datetime, number_of_weeks: int = 6):
day_of_week = date_of_interest.strftime('%A')

kind_order = ['Squad', 'Consulting', 'Internal',]

kinds_present = [kind for kind in kind_order if kind in df['Kind'].unique()]

dates_of_interest = [(date_of_interest - timedelta(weeks=i)).date() for i in range(number_of_weeks)]
dates_of_interest = [d for d in dates_of_interest if d.strftime('%A') == day_of_week]

ds = df[df['DayOfWeek'] == day_of_week]
self.daily_summary = ds.groupby(['Date', 'Kind'])['TimeInHs'].sum().unstack().fillna(0)

all_dates_df = pd.DataFrame(0, index=dates_of_interest, columns=kinds_present)
all_dates_df.index.name = 'Date'

self.daily_summary = pd.concat([self.daily_summary, all_dates_df]).groupby('Date').sum().fillna(0)
self.daily_summary = self.daily_summary.sort_index()

current_day_data = df[df['Date'] == date_of_interest.date()]
self.total_hours = current_day_data['TimeInHs'].sum()

past_data = ds[ds['Date'] < date_of_interest.date()]
ds_grouped = past_data.groupby('Date')['TimeInHs'].sum()

past_dates_of_interest = [d for d in dates_of_interest if d < date_of_interest.date()]
past_dates_reference = pd.DataFrame(
past_dates_of_interest, columns=['Date']
).set_index('Date')

ds_grouped = past_dates_reference.join(ds_grouped, how='left').fillna(0)['TimeInHs']

self.best_day = ds_grouped.idxmax()
self.best_day_hours = ds_grouped.max()

self.worst_day = ds_grouped.idxmin()
self.worst_day_hours = ds_grouped.min()

self.average_hours = ds_grouped.mean()


class TimelinessSummary:
def __init__(self, df):
self.df = df

# Cálculos gerais
self.total_rows = len(df)
self.total_time_in_hours = df['TimeInHs'].sum()

# Filtros para os diferentes status
self.early_filter = df['Correctness'].str.startswith('WTF -')
self.ok_filter = df['Correctness'] == 'OK'
self.acceptable_filter = df['Correctness'] == 'Acceptable (1)'
self.other_filter = ~(self.early_filter | self.ok_filter | self.acceptable_filter)

# Contagem e soma das horas para cada status
self.early_rows = df[self.early_filter].shape[0]
self.early_time_in_hours = df.loc[self.early_filter, 'TimeInHs'].sum()

self.ok_rows = df[self.ok_filter].shape[0]
self.ok_time_in_hours = df.loc[self.ok_filter, 'TimeInHs'].sum()

self.acceptable_rows = df[self.acceptable_filter].shape[0]
self.acceptable_time_in_hours = df.loc[self.acceptable_filter, 'TimeInHs'].sum()

self.late_rows = df[self.other_filter].shape[0]
self.late_time_in_hours = df.loc[self.other_filter, 'TimeInHs'].sum()

# Cálculo das porcentagens
total_hours = self.total_time_in_hours
if total_hours == 0:
self.early_percentage = 0
self.ok_percentage = 100
self.acceptable_percentage = 0
self.late_percentage = 0
else:
self.early_percentage = (self.early_time_in_hours / total_hours) * 100
self.ok_percentage = (self.ok_time_in_hours / total_hours) * 100
self.acceptable_percentage = (self.acceptable_time_in_hours / total_hours) * 100
self.late_percentage = (self.late_time_in_hours / total_hours) * 100

# Pré-calculando os resumos de trabalhadores por status
self.early_workers = self._create_worker_summary(self.early_filter)
self.ok_workers = self._create_worker_summary(self.ok_filter)
self.acceptable_workers = self._create_worker_summary(self.acceptable_filter)
self.late_workers = self._create_worker_summary(self.other_filter)

def _create_worker_summary(self, filter_condition):
# Agrupa por WorkerName e calcula o número de entradas e o total de horas
worker_group = self.df[filter_condition].groupby('WorkerName').agg(
entries=('WorkerName', 'size'),
time_in_hours=('TimeInHs', 'sum')
).reset_index()

# Cria a lista de dicionários para cada trabalhador
worker_list = [
{
'worker': row['WorkerName'],
'entries': row['entries'],
'time_in_hours': row['time_in_hours']
}
for _, row in worker_group.iterrows()
]

return worker_list


class TimeSheetFieldSummary:
def __init__(self, df: pd.DataFrame, field: str):
self.no_data = len(df) == 0
if self.no_data:
return

self.total_hours = df['TimeInHs'].sum()

self.grouped_total_hours = df.groupby([field, 'Kind'])['TimeInHs'].sum().unstack().fillna(0)
self.grouped_total_hours['Total'] = self.grouped_total_hours.sum(axis=1)
self.grouped_total_hours = self.grouped_total_hours.sort_values('Total', ascending=False)

self.unique = df[field].nunique()
self.avg_hours = self.total_hours / self.unique
self.std_hours = df.groupby([field])['TimeInHs'].sum().std()

cumulative_hours = self.grouped_total_hours['Total'].cumsum()
cumulative_hours_80 = cumulative_hours[cumulative_hours <= cumulative_hours.iloc[-1] * 0.80]
if len(cumulative_hours_80) == 0:
self.allocation_80 = 0
else:
self.allocation_80 = \
cumulative_hours[cumulative_hours <= cumulative_hours.iloc[-1] * 0.80].index[-1]


class TimesheetCommonQueries:
def __init__(self, df: pd.DataFrame):
self.df = df

def list_products_or_services(self) -> List[str]:
separated_products_or_services = set()

for items in self.df['ProductsOrServices'].unique():
separated_products_or_services.update(items.split(';'))

return list(separated_products_or_services)
return data
37 changes: 1 addition & 36 deletions backend/models/semantic/tasksmanager.py
Original file line number Diff line number Diff line change
@@ -7,8 +7,6 @@

import models.syntactic.todoist as t

from models.dashboard.x9 import x9

from typing import List, Optional
from pydantic import BaseModel
from settings import api_settings
@@ -139,22 +137,12 @@ def get_tasks(self, project_id: str) -> List[Task]:
if task.project_id == project_id and not task.is_deleted
]

# todoist_completed_tasks = self.todoist.fetch_completed_tasks(project_id)
# completed_tasks = [
# Task.from_todoist_task(task)
# for task in todoist_completed_tasks
# ]

return tasks

@property
def users(self):
return self.todoist.fetch_collaborators()

@property
def common_queries(self):
return CommonQueries(self)


class ProjectsDataFrame(PowerDataFrame):
def __init__(self, data):
@@ -164,27 +152,4 @@ def to_ui(self):
columns = ['Name']
df = self.data[columns].copy()
df.columns = ['Project']
return df


class CommonQueries:
def __init__(self, tm: TasksManager):
self.tm = tm or TasksManager()

@x9(family='todoist')
def find_projects_without_tasks(self):
return (self.tm.projects
.filter_by(by='HasTasks', equals_to=False)
)

@x9(family='todoist')
def find_projects_with_late_tasks(self):
return (self.tm.projects
.filter_by(by='HasLateTasks', equals_to=False)
)

@x9(family='todoist')
def find_projects_without_due(self):
return (self.tm.projects
.filter_by(by='AllTasksHaveDue', equals_to=False)
)
return df
2 changes: 1 addition & 1 deletion frontend/package.json
Original file line number Diff line number Diff line change
@@ -3,7 +3,7 @@
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "NODE_OPTIONS='--inspect' next dev -p 80",
"dev": "NODE_OPTIONS='--inspect' next dev",
"build": "next build",
"start": "next start",
"lint": "next lint"