Skip to content

Commit

Permalink
Merge pull request #95 from ElemarJR/fix_forecast
Browse files Browse the repository at this point in the history
Fix forecast
  • Loading branch information
ElemarJR authored Jan 4, 2025
2 parents 9ebd9e2 + 00b1360 commit e28fd8a
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 15 deletions.
8 changes: 7 additions & 1 deletion backend/models/src/omni_models/analytics/revenue_tracking.py
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,12 @@ def process_project(date_of_interest: date, case: Case, project, timesheet_df: p
elif case.pre_contracted_value:
fee = project.billing.fee / 100

if project.created_at > date_of_interest:
fee = 0

if project.due_on and (project.due_on.date() if hasattr(project.due_on, 'date') else project.due_on) < (date_of_interest.date() if hasattr(date_of_interest, 'date') else date_of_interest):
fee = 0

should_do_pro_rata = (
case.start_of_contract
and case.start_of_contract.year == date_of_interest.year
Expand All @@ -351,7 +357,7 @@ def process_project(date_of_interest: date, case: Case, project, timesheet_df: p
result = {
"kind": project.kind,
"name": project.name,
"fee": project.billing.fee / 100,
"fee": fee,
"hours": project_df["TimeInHs"].sum() if len(project_df) > 0 else 0,
"fixed": True
}
Expand Down
15 changes: 15 additions & 0 deletions backend/models/src/omni_models/domain/cases.py
Original file line number Diff line number Diff line change
Expand Up @@ -296,4 +296,19 @@ def __build_data(self) -> Dict[str, Case]:
if deal and (deal not in case.deals):
case.deals.append(deal)

for case in cases_dict.values():
for tracker_project in case.tracker_info:
if tracker_project.status == 'archived' and tracker_project.kind != 'consulting':
if not tracker_project.due_on:
due_on = None
if tracker_project.name.endswith("- 2024"):
due_on = datetime(year=2024, month=12, day=31, hour=23, minute=59, second= 59)
elif case.end_of_contract:
due_on = case.end_of_contract
elif case.is_active:
due_on = self.tracker.find_project_due_on(tracker_project.id)

if due_on:
tracker_project.due_on = due_on

self.__data = cases_dict
22 changes: 21 additions & 1 deletion backend/models/src/omni_models/semantic/timetracker/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,4 +70,24 @@ def all_projects(self):
if project_id in result:
result[project_id].due_on = task.due_on

return result
return result

def enforce_due_on(self, project: Project):
if project.status != 'archived':
return

if project.due_on:
return

tasks = self.everhour.fetch_project_tasks(project.id)
for task in tasks:
if task.name == 'Encerramento' and task.due_on:
project.due_on = task.due_on
break

def find_project_due_on(self, project_id: str) -> datetime:
tasks = self.everhour.fetch_project_tasks(project_id)
for task in tasks:
if task.name == 'Encerramento' and task.due_on:
return task.due_on
return None
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ def kind(self):

@classmethod
def from_base_instance(cls, base_instance: e.Project, client: Client):
base_dict = base_instance.dict()
base_dict = base_instance.model_dump()
base_dict['is_squad'] = client.is_squad if client else False
base_dict['is_eximiaco'] = client.is_eximiaco if client else True
base_dict['is_handson'] = client.is_handson if client else False
Expand Down
17 changes: 11 additions & 6 deletions backend/models/src/omni_models/syntactic/everhour/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,17 +57,22 @@ def fetch_appointments(self, starting: datetime, ending: datetime) -> List[Appoi
)
for ap in json
]

@cache
def fetch_all_projects(self, status: Optional[str] = None) -> List[Project]:

def fetch_all_projects_json(self, status: Optional[str] = None) -> List[Dict[str, Any]]:
params = {
"limit": 10000,
"page": 1
}

if status:
params["status"] = status

json = self.fetch("projects", params=params)
return json

@cache
def fetch_all_projects(self, status: Optional[str] = None) -> List[Project]:
json = self.fetch_all_projects_json(status)
return [
Project(**p)
for p in json
Expand All @@ -76,7 +81,7 @@ def fetch_all_projects(self, status: Optional[str] = None) -> List[Project]:
@cache
def fetch_project_tasks(self, project_id: str) -> List[Task]:
params = {
"limit": 10000,
"limit": 250,
"page": 1
}
json = self.fetch(f"projects/{project_id}/tasks", params=params)
Expand All @@ -96,7 +101,7 @@ def search_tasks(self, query: str) -> List[Task]:
def _search_tasks_json(self, query: str) -> List[Dict[str, Any]]:
params = {
"query": query,
"searchInClosed": False
"searchInClosed": "true"
}
json = self.fetch("tasks/search", params=params)
return json
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,16 @@
from typing import Optional, List
from pydantic import BaseModel, field_validator
from pydantic import BaseModel, field_validator, Field
from datetime import datetime

class Task(BaseModel):
id: str
name: str
due_on: Optional[datetime] = None
due_on: Optional[datetime] = Field(alias='dueOn', default=None)
projects: List[str]

@field_validator('due_on', mode='before')
@classmethod
def validate_due_on(cls, value):
if isinstance(value, str):
return datetime.strptime(value, "%Y-%m-%d")
return value

class Config:
populate_by_name = True
return value

0 comments on commit e28fd8a

Please sign in to comment.