Skip to content

Add send-to-Google-Sheets support for B2B enrollment codes#3363

Draft
jkachel wants to merge 1 commit intomainfrom
jkachel/7931-add-b2b-gsheets-output
Draft

Add send-to-Google-Sheets support for B2B enrollment codes#3363
jkachel wants to merge 1 commit intomainfrom
jkachel/7931-add-b2b-gsheets-output

Conversation

@jkachel
Copy link
Contributor

@jkachel jkachel commented Mar 8, 2026

What are the relevant tickets?

Closes mitodl/hq#7931

Description (What does it do?)

Adds the ability to send a contract's enrollment codes to a Google Sheet.

This PR adds a couple of new fields to the ContractPage model. These fields allow the user to specify the URL to a Google Sheet that we can throw codes into, and what worksheet (tab) within the document to use for this purpose. When set, the system will write enrollment codes to the sheet, and update the status of the individual codes as they're used.

Each ContractPage can have its own individual Google Sheet to work in. Or, it can share a Sheet with other contracts and use a specified tab within the sheet. For now, only one mapping is supported per contract. To make things easier for folks managing the contract, the integration takes a URL to the sheet rather than a bare sheet ID. The sheet must be writable by MITx Online's configured service account.

How can this be tested?

You'll need the Google Sheets integration set up. Should be some docs for this alongside the deferrals/refunds code. The enrollment codes code uses the same underlying setup.

Create a new Google Sheet with nothing in it. Make sure it's created in a way that it should be visible and writable by the user you're using for MITx Online. Then, create a contract that involves codes, and paste in the sheet's URL where it says. (Test specifying the individual tab as well.)

  • Add some courses to the contract and check the sheet. It should be populated with the contract's codes.
  • Use one of the codes for attachment and check the sheet again; it should note that the code was used. (This may take a bit of time.)
  • Delete one or more of the codes using the b2b_codes command. This should mark the code as invalid in the sheet but leave the code there.
  • Change the header. You should be able to tack on new columns to the end without issue but changing the pre-set columns should trigger the system to overwrite your changes to the best of its abilities.

Additional Context

The integration uses the same base stuff that the deferrals and refunds processing code uses, but works a good bit differently. The refund/deferral code expects to only ever read a single sheet and this expects to work on any number of sheets. So, it's using the ol-django google_sheets code but really only to bootstrap pygsheets.

The code will check for and write a header row to whatever worksheet is configured so it's best to give it a blank sheet to work from. The header row will be written the first N columns don't match the columns set in the code.

A field was also added to the Discount model to keep track of where the code lands in the sheet, so it doesn't have to trawl through the entire sheet to update a code. (There can be potentially thousands of codes.) It will check to make sure the code is actually there; if it isn't, then it'll default to iterating through the sheet to find it.

There's options in here to set the start row but we're not using the at the moment.

@github-actions
Copy link

github-actions bot commented Mar 8, 2026

OpenAPI Changes

Show/hide ## Changes for v0.yaml:
## Changes for v0.yaml:


## Changes for v1.yaml:


## Changes for v2.yaml:


Unexpected changes? Ensure your branch is up-to-date with main (consider rebasing).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant