Skip to content
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
1 change: 0 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,6 @@ USER mitodl

RUN --mount=type=cache,target=/opt/uv-cache,uid=1000,gid=1000 \
uv sync --frozen --no-install-project
RUN uv pip install watchfiles

FROM code AS jupyter-notebook

Expand Down
8 changes: 8 additions & 0 deletions RELEASE.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
Release Notes
=============

Version 1.159.2
---------------

- Filter active cert issue_date in db query (#3748)
- Add some viz into misconfigured contracts (#3744)
- fix: update the beat task timing for retry_failed_edx_enrollments (#3723)
- Enable live reload for the django app (#3738)

Version 1.159.1 (Released July 09, 2026)
---------------

Expand Down
6 changes: 6 additions & 0 deletions b2b/views/v0/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,12 @@ def _create_discount_codes_for_contract(
# For contract attachment JIT code generation, any product associated w/ the contract should
# work for creating the discount code, so we just grab the first one.
product = contract.get_products().first()
if not product:
log.exception(
"Contract %s has no product, cannot provision JIT discount codes", contract
)
return new_discounts

for _ in range(count_to_provision):
discount = _create_discount_with_product(
product, Decimal(0), REDEMPTION_TYPE_ONE_TIME
Expand Down
45 changes: 45 additions & 0 deletions b2b/views/v0/manager_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -1428,6 +1428,51 @@ def test_bulk_assign_provisions_codes_for_uncapped_contract(
)


def test_bulk_assign_no_product_for_uncapped_contract(
org_setup, manager_drf_client, mocker, caplog
):
"""bulk_assign doesnt attempt JIT code provisioning for a misconfigured contract without a product."""
mocker.patch("b2b.views.v0.manager.queue_send_enrollment_code_assignment_email")
_, _, (contract_1, *_), *_ = org_setup

uncapped_contract = ContractPageFactory.create(
membership_type=CONTRACT_MEMBERSHIP_CODE,
max_learners=None,
organization=contract_1.organization,
)

records = [
{"email": "learner1@example.com", "name": "Learner One"},
{"email": "learner2@example.com", "name": "Learner Two"},
]

bulk_assign_url = reverse(
"b2b:b2b-manager-org-contract-bulk-assign",
kwargs={
"parent_lookup_organization": uncapped_contract.organization.id,
"pk": uncapped_contract.id,
},
)

resp = manager_drf_client.post(bulk_assign_url, data=records, format="json")

assert resp.status_code == status.HTTP_200_OK

resp_data = resp.json()
assert len(resp_data["assigned"]) == 0
assert len(resp_data["errors"]) == 2
assert all("No available code." in err["detail"] for err in resp_data["errors"])

assert uncapped_contract.get_discounts().count() == 0
assert (
DiscountContractAttachmentRedemption.objects.filter(
contract=uncapped_contract
).count()
== 0
)
assert "has no product" in caplog.text


def test_bulk_assign_skips_already_assigned_or_redeemed(
org_setup, manager_drf_client, mocker
):
Expand Down
7 changes: 2 additions & 5 deletions courses/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
from django.db import models
from django.db.models import Exists, OuterRef, Prefetch, Q
from django.db.models.constraints import CheckConstraint, UniqueConstraint
from django.db.models.functions import Now
from django.urls import reverse
from django.utils import timezone
from django.utils.functional import cached_property
Expand Down Expand Up @@ -1715,11 +1716,7 @@ def get_queryset(self):
Returns:
QuerySet: queryset for un-revoked certificates
"""
return (
super()
.get_queryset()
.filter(is_revoked=False, issue_date__lte=now_in_utc())
)
return super().get_queryset().filter(is_revoked=False, issue_date__lte=Now())


class BaseCertificate(models.Model):
Expand Down
4 changes: 2 additions & 2 deletions main/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
from main.sentry import init_sentry
from openapi.settings_spectacular import open_spectacular_settings

VERSION = "1.159.1"
VERSION = "1.159.2"

log = logging.getLogger()

Expand Down Expand Up @@ -967,7 +967,7 @@
"sync-courseruns-data": {
"task": "courses.tasks.sync_courseruns_data",
"schedule": crontab(
minute=0,
minute=10,
hour=CRON_COURSERUN_SYNC_HOURS,
day_of_week=CRON_COURSERUN_SYNC_DAYS,
day_of_month="*",
Expand Down
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ dev = [
"pytest-xdist[psutil]>=3.6.1,<4",
"mitol-drf-lint>=2025.3.27",
"pytest-urllib3>=0.2.0",
"granian[reload]>=2.5.4,<3",
]

[tool.uv]
Expand Down
2 changes: 1 addition & 1 deletion scripts/run-django-dev.sh
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,4 @@ for url in "${health_urls[@]}"; do
fi
done

exec granian --interface wsgi --host 0.0.0.0 --port "${PORT:-8013}" --workers 2 main.wsgi:application
exec granian --interface wsgi --host 0.0.0.0 --port "${PORT:-8013}" --workers 2 --reload main.wsgi:application
49 changes: 49 additions & 0 deletions uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.