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

Try to fix weeks gaps #23

Merged
merged 2 commits into from
Jan 9, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
20 changes: 12 additions & 8 deletions ooui/graph/timerange.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from datetime import datetime, timedelta
from dateutil.relativedelta import relativedelta

from ooui.helpers.dates import datetime_from_string
from ooui.graph.fields import get_value_for_operator


Expand Down Expand Up @@ -101,8 +102,8 @@ def get_missing_consecutive_dates(dates, timerange, interval=1):
sorted_dates = sorted(dates)

for i in range(len(sorted_dates) - 1):
date1 = datetime.strptime(sorted_dates[i], format_str)
date2 = datetime.strptime(sorted_dates[i + 1], format_str)
date1 = datetime_from_string(sorted_dates[i], format_str)
date2 = datetime_from_string(sorted_dates[i + 1], format_str)

next_date = add_time_unit(date1, interval, units)

Expand Down Expand Up @@ -171,8 +172,8 @@ def convert_date_to_time_range_adjusted(date, timerange):
:rtype: str
:returns: The adjusted date in the specified time range format.
"""
format_str = get_date_format(date)
moment_date = datetime.strptime(date, format_str)
format_str = get_date_format(date, timerange)
moment_date = datetime_from_string(date, format_str)

if timerange == 'hour':
return moment_date.strftime('%Y-%m-%d %H:00')
Expand All @@ -188,7 +189,7 @@ def convert_date_to_time_range_adjusted(date, timerange):
raise ValueError("Unsupported timerange: {}".format(timerange))


def get_date_format(date_str):
def get_date_format(date_str, timerange=None):
"""
Determine the appropriate date format string based on whether the input
string contains a colon.
Expand All @@ -202,7 +203,10 @@ def get_date_format(date_str):
if ':' in date_str:
return '%Y-%m-%d %H:%M:%S'
elif date_str.count('-') == 1:
return '%Y-%m'
if timerange == 'month':
return '%Y-%m'
else:
return '%Y-%W'
else:
return '%Y-%m-%d'

Expand Down Expand Up @@ -280,8 +284,8 @@ def check_dates_consecutive(dates, unit):
format_str = get_format_for_units(unit)

for i in range(len(dates) - 1):
date1 = datetime.strptime(dates[i], format_str)
date2 = datetime.strptime(dates[i + 1], format_str)
date1 = datetime_from_string(dates[i], format_str)
date2 = datetime_from_string(dates[i + 1], format_str)

if unit == 'hours':
diff = (date2 - date1).total_seconds() / 3600
Expand Down
12 changes: 12 additions & 0 deletions ooui/helpers/dates.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
from datetime import datetime

def datetime_from_string(string, format_str):
if format_str == '%Y-%W':
# The "%W" format string doesn't work with strptime, so we need to
# manually parse the week number and year.
return datetime.strptime(string + '-0', '%Y-%W-%w')
elif format_str == "%Y-%m-%d":
return datetime.strptime(string[:10], format_str)
elif format_str == "%Y-%m-%d %H:%M":
return datetime.strptime(string[:16], format_str)
return datetime.strptime(string, format_str)
54 changes: 53 additions & 1 deletion spec/graph/timerange_spec.py
Original file line number Diff line number Diff line change
Expand Up @@ -240,11 +240,17 @@
result = get_missing_consecutive_dates(dates_data, 'month')
expect(result).to(equal(['2024-02', '2024-04']))

with context('when checking for missing weeks'):
with it('should return a list of missing weeks'):
dates_data = ['2024-01', '2024-03', '2024-05']
result = get_missing_consecutive_dates(dates_data, 'week')
expect(result).to(equal(['2024-02', '2024-04']))


with description('Testing fill_gaps_in_timerange_data') as self:

with context('when filling gaps in time range data'):
with it('should return the final values with gaps filled'):
with it('should return the final values with gaps filled by day'):
values_data = [
{'x': '2024-05-01', 'type': 'Revenue', 'stacked': 'A', 'value': 100},
{'x': '2024-05-05', 'type': 'Revenue', 'stacked': 'A', 'value': 200},
Expand All @@ -262,6 +268,22 @@
{'x': '2024-06-01', 'type': 'Profit', 'stacked': 'B', 'value': 300}
))

with it('should return the final values with gaps filled by week'):
values_data = [
{'x': '2024-01', 'type': 'Revenue', 'stacked': 'A', 'value': 100},
{'x': '2024-02', 'type': 'Revenue', 'stacked': 'A', 'value': 200},
{'x': '2024-04', 'type': 'Revenue', 'stacked': 'A', 'value': 300}
]

result = fill_gaps_in_timerange_data(values_data, 'week', 1)

expect(result).to(contain_only(
{'x': '2024-01', 'type': 'Revenue', 'stacked': 'A', 'value': 100},
{'x': '2024-02', 'type': 'Revenue', 'stacked': 'A', 'value': 200},
{'x': '2024-03', 'type': 'Revenue', 'stacked': 'A', 'value': 0},
{'x': '2024-04', 'type': 'Revenue', 'stacked': 'A', 'value': 300},
))


with description('Testing process_timerange_data') as self:

Expand Down Expand Up @@ -342,6 +364,36 @@
'type': 'Revenue', 'value': 300.0},
))

with it('should return the final combined and filled values by week'):
values_data = [
{'x': '2024-01', 'type': 'Revenue', 'stacked': 'A',
'value': 100, 'operator': '+'},
{'x': '2024-02', 'type': 'Revenue', 'stacked': 'A',
'value': 200, 'operator': '+'},
{'x': '2024-03', 'type': 'Revenue', 'stacked': 'A',
'value': 300, 'operator': '+'},
{'x': '2024-05', 'type': 'Revenue', 'stacked': 'A',
'value': 500, 'operator': '+'}
]

result = process_timerange_data(
values_data, 'week', 1,
)

expect(result).to(contain_only(
{'x': '2024-01', 'type': 'Revenue', 'stacked': 'A',
'value': 100, 'operator': '+'},
{'x': '2024-02', 'type': 'Revenue', 'stacked': 'A',
'value': 200, 'operator': '+'},
{'x': '2024-03', 'type': 'Revenue', 'stacked': 'A',
'value': 300, 'operator': '+'},
{'x': '2024-04', 'type': 'Revenue', 'stacked': 'A',
'value': 0},
{'x': '2024-05', 'type': 'Revenue', 'stacked': 'A',
'value': 500, 'operator': '+'}
))


with description('add_time_unit function'):
with context('when adding different time units'):
with it('adds days correctly'):
Expand Down
Loading