Skip to content

Commit

Permalink
Fix second bug with Program total price calculation ECOM-7023
Browse files Browse the repository at this point in the history
  • Loading branch information
schenedx committed Feb 27, 2017
1 parent 735a635 commit 7828932
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 16 deletions.
29 changes: 23 additions & 6 deletions course_discovery/apps/course_metadata/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -810,6 +810,28 @@ def seats(self):
def seat_types(self):
return set(seat.type for seat in self.seats)

def _select_for_total_price(self, selected_seat, candidate_seat):
"""
A helper function to determine which course_run seat is best suitable to be used to calculate
the program total price. A seat is most suitable if the related course_run is now enrollable,
has not ended, and the enrollment_start date is most recent
"""
end_valid = candidate_seat.course_run.end is None or \
candidate_seat.course_run.end >= datetime.datetime.now(pytz.UTC)

selected_enrollment_start = selected_seat.course_run.enrollment_start or \
pytz.utc.localize(datetime.datetime.min)

# Only select the candidate seat if the candidate seat has no enrollment start,
# or make sure the candidate course_run is enrollable and
# the candidate seat enrollment start is most recent
enrollment_start_valid = candidate_seat.course_run.enrollment_start is None or (
candidate_seat.course_run.enrollment_start > selected_enrollment_start and
candidate_seat.course_run.enrollment_start < datetime.datetime.now(pytz.UTC)
)

return end_valid and enrollment_start_valid

def _get_total_price_by_currency(self):
"""
This helper function returns the total program price indexed by the currency
Expand All @@ -832,12 +854,7 @@ def _get_total_price_by_currency(self):
# If the candidate seat has a different currency than the one in the array,
# always add to the array
add_seat = True
elif ((seat.course_run.end is None or
seat.course_run.end >= datetime.datetime.now(pytz.UTC)) and
(seat.course_run.enrollment_start is None or
seat.course_run.enrollment_start > (
selected_seat.course_run.enrollment_start or datetime.datetime.min) and
seat.course_run.enrollment_start < datetime.datetime.now(pytz.UTC))):
elif self._select_for_total_price(selected_seat, seat):
# If the seat has same currency, the course has not ended,
# and the course is enrollable, then choose the new seat associated with the course instead,
# and mark the original seat in the array to be removed
Expand Down
27 changes: 17 additions & 10 deletions course_discovery/apps/course_metadata/tests/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -513,20 +513,27 @@ def create_program_with_multiple_course_runs(self, set_all_dates=True):
currency = Currency.objects.get(code='USD')
single_course_course_runs = factories.CourseRunFactory.create_batch(3)
course = factories.CourseFactory()
course_runs_same_course = factories.CourseRunFactory.create_batch(2, course=course)
course_runs_same_course = factories.CourseRunFactory.create_batch(3, course=course)
for course_run in single_course_course_runs:
factories.SeatFactory(type='audit', currency=currency, course_run=course_run, price=0)
factories.SeatFactory(type='verified', currency=currency, course_run=course_run, price=10)

day_diff = 1
day_separation = 1
for course_run in course_runs_same_course:
if set_all_dates or day_diff > 1:
course_run.enrollment_start = datetime.datetime.now() - datetime.timedelta(days=day_diff)
course_run.end = datetime.datetime.now() + datetime.timedelta(weeks=day_diff)
course_run.save()
if set_all_dates or day_separation < 2:
course_run.enrollment_start = datetime.datetime.now() - datetime.timedelta(days=day_separation)
course_run.end = datetime.datetime.now() + datetime.timedelta(weeks=day_separation)
else:
course_run.enrollment_start = None
course_run.end = None
course_run.save()
factories.SeatFactory(type='audit', currency=currency, course_run=course_run, price=0)
factories.SeatFactory(type='verified', currency=currency, course_run=course_run, price=(day_diff * 100))
day_diff += 1
factories.SeatFactory(
type='verified',
currency=currency,
course_run=course_run,
price=(day_separation * 100))
day_separation += 1

applicable_seat_types = SeatType.objects.filter(slug__in=['verified'])
program_type = factories.ProgramTypeFactory(applicable_seat_types=applicable_seat_types)
Expand All @@ -543,7 +550,7 @@ def test_price_ranges_with_multiple_course_runs(self):
"""
program = self.create_program_with_multiple_course_runs()

expected_price_ranges = [{'currency': 'USD', 'min': Decimal(10), 'max': Decimal(200), 'total': Decimal(130)}]
expected_price_ranges = [{'currency': 'USD', 'min': Decimal(10), 'max': Decimal(300), 'total': Decimal(130)}]
self.assertEqual(program.price_ranges, expected_price_ranges)

def test_price_ranges_with_multiple_course_runs_and_none_dates(self):
Expand All @@ -553,7 +560,7 @@ def test_price_ranges_with_multiple_course_runs_and_none_dates(self):
"""
program = self.create_program_with_multiple_course_runs(set_all_dates=False)

expected_price_ranges = [{'currency': 'USD', 'min': Decimal(10), 'max': Decimal(200), 'total': Decimal(230)}]
expected_price_ranges = [{'currency': 'USD', 'min': Decimal(10), 'max': Decimal(300), 'total': Decimal(130)}]
self.assertEqual(program.price_ranges, expected_price_ranges)

def test_staff(self):
Expand Down

0 comments on commit 7828932

Please sign in to comment.