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
7 changes: 7 additions & 0 deletions RELEASE.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
Release Notes
=============

Version 0.131.6
---------------

- B2B: Update Keycloak org membership when a user redeems an enrollment code (#2989)
- Change v2 req_tree to not return root node, improve OpenAPI spec (#3010)
- Add ability to manage the link between programs and contracts (#3006)

Version 0.131.4 (Released October 16, 2025)
---------------

Expand Down
56 changes: 56 additions & 0 deletions b2b/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
DiscountContractAttachmentRedemption,
OrganizationPage,
)
from courses.models import CourseRun


class ReadOnlyModelAdmin(admin.ModelAdmin):
Expand Down Expand Up @@ -42,6 +43,59 @@ class DiscountContractAttachmentRedemptionAdmin(ReadOnlyModelAdmin):
readonly_fields = ["user", "contract", "discount", "created_on"]


class ContractPageProgramInline(admin.TabularInline):
"""Inline to display programs for contract pages."""

model = ContractPage.programs.through
extra = 0
verbose_name = "Contract Program"
verbose_name_plural = "Contract Programs"

def has_add_permission(self, request, obj): # noqa: ARG002
"""Turn off add permission. These admins are supposed to be read-only."""

return False

def has_delete_permission(self, request, obj): # noqa: ARG002
"""Turn off delete permission. These admins are supposed to be read-only."""

return False

def has_change_permission(self, request, obj): # noqa: ARG002
"""Turn off change permission. These admins are supposed to be read-only."""

return False


class ContractPageCourseRunInline(admin.TabularInline):
"""Inline to display course runs for contract pages."""

model = CourseRun
fk_name = "b2b_contract"
extra = 0
fields = [
"courseware_id",
"title",
]
verbose_name = "Contract Course Run"
verbose_name_plural = "Contract Course Runs"

def has_add_permission(self, request, obj): # noqa: ARG002
"""Turn off add permission. These admins are supposed to be read-only."""

return False

def has_delete_permission(self, request, obj): # noqa: ARG002
"""Turn off delete permission. These admins are supposed to be read-only."""

return False

def has_change_permission(self, request, obj): # noqa: ARG002
"""Turn off change permission. These admins are supposed to be read-only."""

return False


@admin.register(ContractPage)
class ContractPageAdmin(ReadOnlyModelAdmin):
"""Admin for contract pages."""
Expand All @@ -65,11 +119,13 @@ class ContractPageAdmin(ReadOnlyModelAdmin):
"title",
"description",
"integration_type",
"membership_type",
"contract_start",
"contract_end",
"max_learners",
"enrollment_fixed_price",
]
inlines = [ContractPageCourseRunInline, ContractPageProgramInline]


@admin.register(OrganizationPage)
Expand Down
Loading