Repository navigation
Disbursements flow - #4987
Draft
bickelj wants to merge 18 commits into
Draft
Disbursements flow#4987bickelj wants to merge 18 commits into
bickelj wants to merge 18 commits into
Conversation
frjo
reviewed
Sep 16, 2026
| "BRL", | ||
| "MXN", | ||
| "NGN", | ||
| ] |
Member
There was a problem hiding this comment.
I think this should be a setting. The values seem good as a default.
bickelj
force-pushed
the
disbursements-flow
branch
2 times, most recently
from
November 4, 2026 21:40
8ecc136 to
d7bc9a8
Compare
A broad range is allowed so as to support current and future monies. Several fiat currencies use 0 or 3 decimal places. Several digital currencies support 6-18 digits following the decimal place. Displaying the amounts in a sensible way will be a UI concern. Thanks to GLM-5.2 (LLM) for helpful hints.
Offer an hint at currency codes with a datalist with top ten codes. Actually load original when editing and save updates to the contract. There is wide decimal precision available on input, but exactly two decimal places are shown in the UI unless more are used. LLM assistance by unsloth/Qwen3.6-35B-A3B-GGUF:UD-Q4_K_XL Further LLM assistance by GLM-5.2
Introduce a Disbursement model (one transaction against a Contract) recorded by staff with no approval workflow. Negative amounts are allowed so repayments net out via Sum(). The canonical audit trail is written to Wagtail's ModelLogEntry via wagtail.log_actions.log on every save, mirroring ApplicationRevision.save; activity/messenger notices are a separate, best-effort concern for the views MR. This is model-only: CRUD views, the All Projects columns, and the audit report come on a follow-on branch. GLM-5.2
Stack create/update/delete views (staff/finance), a DisbursementForm, and URL routes on the Disbursement model. Entry is a modal on the project page; on save the user returns to the project page. Activity/messenger notices are emitted for create/update/delete with the amount included (not the note), wired through the activity adapters like invoices. GLM-5.2
bickelj
force-pushed
the
disbursements-flow
branch
2 times, most recently
from
November 5, 2026 19:55
40d5b66 to
db0136d
Compare
Render a "Contracts and Disbursements" section where upstream places invoices: it lists each contract (with its approved amount) and its disbursements, with Add/Edit/Delete disbursement buttons gated by the can_add_disbursement checker (staff/finance/contracting). Staff/finance can also add further contracts from here, reusing the countersigned contract form (no stage transition; the first contract still goes through the contracting flow, which transitions the project). Notes are staff/finance-only, so the Notes column is omitted for applicants. Amounts display with a minimum of two decimal places, keeping any extra precision, to match the contract amount rendering. GLM-5.2
The ARDC fork needs a per-contract disbursement ledger in place of upstream's invoicing flow, but unconditionally removing the invoicing UI would break other deployments sharing this fork base. Add PROJECTS_PAYMENTS_FLOW (an INVOICING/DISBURSEMENTS/DISABLED enum) so each deployment selects its payments flow. The project detail page renders each section through a helper tag (project_can_have_invoices_ section / project_can_have_disbursements_section) that folds the payments-flow check in with the existing visibility rules, keeping the template terse; the contracting documents section stays during Contracting and is hidden under DISBURSEMENTS once a contract exists (the C&D section takes over). The contract upload forms (UploadContractForm, UploadCountersignedContractForm, and the CreateContractForm that extends it) likewise hide their amount_requested, amount_approved and currency fields unless DISBURSEMENTS is selected, so the ledger fields only appear where the per-contract ledger exists. ARDC sets DISBURSEMENTS in ardc.py. GLM-5.2
Without this change, the currency code input widget was the same size in appearance as the amounts. With this change, its size and maximum length are proportioned more accurately.
For convenience, use the system setting's `CURRENCY_CODE` to prepopulate the currency field on a contract. It can still be left blank for several reasons: it may not be known yet and it is still important for old, existing data to allow `NULL`, also when not using the `PROJECTS_PAYMENTS_FLOW=DISBURSEMENTS` setting it will be `NULL`.
Without this change, it is hard to tell what currency is disbursed. With this change, it is easier because the contract's currency shows.
The disbursements table had no horizontal scroll wrapper. Its nowrap thead gives it a ~707px minimum width, so on narrower viewports the table and its Edit/Delete buttons rendered outside the card border. Now the table scrolls within the card, as the sibling invoice and report tables already do. Made with GLM-5.3-Flash.
Without this change, the Disbursement form's Amount label does not say which currency the entered amount is in. With this change, the related Contract's currency code shows next to the Amount label, matching the Disbursements table header. Assisted-by: GLM-5.3-Flash
In most currencies we use two decimal places and right-justify amounts so this change does the same for the Disbursements table that shows up in the Projects area.
Staff previously keyed each disbursement amount from scratch. The create form now starts from the awarded amount net of the contract's existing disbursements, and editing keeps the amount. GLM-5.3-Flash, an LLM supervised and prompted by @jbickel
The Notes column in the Contracts and Disbursements section was hidden from applicants and labelled "visible to staff and finance only", so grantees could not see the notes staff record against their disbursements. Now anyone who can view the project sees the Notes column and its contents; recording and editing disbursements stay staff/finance. GLM-5.3-Flash, an LLM supervised and prompted by @jbickel
Disbursements were only visible per project, with no way to see or extract money movement across all projects. Add an admin-only ledger at /apply/projects/disbursements/ (Staff Admin group or superuser): one row per disbursement with contract requested/approved amounts repeated, ISO 8601 disbursement-date and date-recorded columns, date-range, currency and project-status filters, a numeric total when a single currency is filtered, and filter-respecting CSV export. The nav entry and page only exist under the DISBURSEMENTS payments flow. GLM-5.3-Flash, an LLM supervised and prompted by @jbickel
The per-contract Disbursements section gave weak labels: the contract link read just "#65", the disbursement list had no heading, and the first column said "Date". The contract link now reads "Contract #65", the list carries an "N Disbursements:" count heading under each contract, and the first column is "Disbursement date", matching the All Disbursements table. GLM-5.3-Flash, an LLM supervised and prompted by @jbickel
Staff had to open each project to see its contract totals. The All Projects table now shows a contracts total per project with its currency code, and shows "Multiple currencies" instead of a cross-currency sum when the amounts span more than one currency. Projects with no approved amount entered show an em dash rather than 0.00, keeping absence distinct from a genuine zero. The column is gated on the DISBURSEMENTS payments flow, where contracts carry amounts at all. GLM-5.3-Flash, an LLM supervised and prompted by @jbickel
Staff tracking grant money had to open each project and read through its contracts and disbursements to learn how much had gone out. The All Projects list and its CSV export now show each project's disbursement total, summed across all of its contracts, with repayments netting out. Totals spanning more than one currency, including a coded amount beside an uncoded one, show as "Multiple currencies" instead of a blended amount; a single currency code is shown beside the total. Projects without disbursements show "—" rather than a misleading 0.00. GLM-5.3-Flash, an LLM supervised and prompted by @jbickel
bickelj
force-pushed
the
disbursements-flow
branch
from
November 6, 2026 16:13
db0136d to
619c8b2
Compare
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Note: this is a draft, not ready for merge by any stretch of the imagination (I don't expect lint or tests to even pass yet). I cherry-picked the relevant commits into a first-pass on main here while the commit order was top of mind. There will be more commits added as the feature evolves downstream.
Without this change, there is quite a complex process for invoicing, approvals, and tracking of payments. With this change, there is a relatively straightforward way to associate money amounts with contracts and then disbursements with those contracts. It breaks the 1-to-1 project-to-contract relationship when a system setting
PROJECTS_PAYMENTS_FLOWis set toDISBURSEMENTS. The standard flow isINVOICINGand another is offered:DISABLED. The sameContractmodel is re-used in either flow, but after that, the models/forms/views diverge.