feat: add Purchase Orders & Corporate Invoicing (Phase 20)#59
Merged
JacobCoffee merged 7 commits intomainfrom Mar 19, 2026
Merged
feat: add Purchase Orders & Corporate Invoicing (Phase 20)#59JacobCoffee merged 7 commits intomainfrom
JacobCoffee merged 7 commits intomainfrom
Conversation
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…-only settlement - Add select_for_update() locking in record_payment/issue_credit_note - Reject mutations on cancelled POs (ValueError) - Fix credit-only PO settlement (was stuck in draft/sent) - Add send_purchase_order() service + Send PO view/URL/button - Make admin payment/credit inlines read-only - Add 5 new tests for lifecycle guards and send flow Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…PO metrics - Invoice PDF generation via reportlab with conference-prefixed filenames - Stripe Invoicing integration (create/send/sync invoices via Stripe API) - QuickBooks Online integration via httpx (create/send/sync invoices) - PO metrics on financial dashboard (status breakdown, revenue, balance, payments by method) - Conference model: QBO OAuth fields (realm_id, tokens, client credentials) - PurchaseOrder model: stripe_invoice_id/url and qbo_invoice_id/url fields Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
Pull request overview
Adds a corporate/offline purchase order system to the registration domain, with organizer-facing management UI plus optional integrations for Stripe Invoicing and QuickBooks Online.
Changes:
- Introduces Purchase Order data model + service layer for lifecycle, payments, credits, and PDF invoice generation.
- Adds organizer dashboard views/URLs/templates and admin registration for managing purchase orders (plus financial dashboard rollups).
- Adds new external integration modules for Stripe Invoice creation/sync and QBO invoice creation/sync (and adds
httpxdependency + QBO credential fields onConference).
Reviewed changes
Copilot reviewed 25 out of 26 changed files in this pull request and generated 15 comments.
Show a summary per file
| File | Description |
|---|---|
| uv.lock | Adds httpx to the locked dependency set. |
| pyproject.toml | Adds httpx>=0.28.1 dependency. |
| tests/test_registration/test_purchase_orders.py | Adds unit/integration tests for PO models + PO service layer. |
| src/django_program/registration/services/stripe_invoicing.py | Implements Stripe Invoice creation + sync + webhook handler for POs. |
| src/django_program/registration/services/qbo_invoicing.py | Implements QBO invoice creation + sync + webhook handler for POs (via httpx). |
| src/django_program/registration/services/purchase_orders.py | Adds PO service layer: create, pay, credit, status updates, cancel, PDF generation. |
| src/django_program/registration/purchase_order.py | Adds PO-related Django models (PO, line items, payments, credit notes). |
| src/django_program/registration/models.py | Re-exports PO models via registration.models and __all__. |
| src/django_program/registration/migrations/0020_purchaseorder_purchaseordercreditnote_and_more.py | Creates the new PO models. |
| src/django_program/registration/migrations/0021_add_qbo_invoice_fields.py | Adds Stripe/QBO invoice ID+URL fields to PurchaseOrder. |
| src/django_program/registration/admin.py | Registers PurchaseOrder admin with inlines for line items/payments/credits. |
| src/django_program/manage/views_purchase_orders.py | Adds organizer dashboard views for listing/creating/managing POs + invoice actions. |
| src/django_program/manage/urls_purchase_orders.py | Adds manage URL routing for PO dashboard endpoints. |
| src/django_program/manage/urls.py | Mounts purchase order URL routes under the manage area. |
| src/django_program/manage/views_financial.py | Adds purchase order rollups to financial dashboard context. |
| src/django_program/manage/templates/django_program/manage/purchase_order_list.html | Adds PO list page template (filtering + table). |
| src/django_program/manage/templates/django_program/manage/purchase_order_form.html | Adds PO creation form template + JS for line items. |
| src/django_program/manage/templates/django_program/manage/purchase_order_detail.html | Adds PO detail page template (line items, payments, credits, actions). |
| src/django_program/manage/templates/django_program/manage/financial_dashboard.html | Displays new PO rollups/sections on financial dashboard. |
| src/django_program/manage/templates/django_program/manage/base.html | Adds collapsible sidebar UI behavior + Purchase Orders nav link. |
| src/django_program/manage/views.py | Extends conference edit to include KPI targets form handling. |
| src/django_program/manage/forms.py | Adds KPITargetsForm. |
| src/django_program/manage/templates/django_program/manage/conference_edit.html | Adds KPI Targets section to conference edit page. |
| src/django_program/conference/models.py | Adds QBO credential/token fields to Conference. |
| src/django_program/conference/migrations/0010_add_qbo_fields.py | Migrates the new QBO fields onto Conference. |
| examples/seed.py | Seeds KPI targets + purchase orders into example dataset. |
Comments suppressed due to low confidence (1)
src/django_program/manage/views.py:873
ConferenceEditView.post()routes successful submissions through_forms_valid(), which callssuper().form_valid(form)and bypasses this class’sform_valid()override (so the success flash message won’t be set). Consider callingself.form_valid(form)(or moving the messaging logic into_forms_valid) so behavior stays consistent.
def _forms_valid(self, form: ConferenceForm, kpi_form: KPITargetsForm) -> HttpResponse:
"""Save both the conference and KPI targets forms."""
response = super().form_valid(form)
kpi = kpi_form.save(commit=False)
kpi.conference = self.conference
kpi.save()
return response
def form_valid(self, form: ConferenceForm) -> HttpResponse:
"""Save the form and add a success message.
Args:
form: The validated conference form.
Returns:
A redirect response to the success URL.
"""
messages.success(self.request, "Conference updated successfully.")
return super().form_valid(form)
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Validate amount > 0 and method in record_payment/issue_credit_note - Use conference currency_symbol in invoice PDF instead of hardcoded $ - Wrap handle_invoice_paid_webhook in transaction.atomic() - Cap QBO webhook sync to 50 POs to prevent timeouts - Fix PO balance_outstanding to subtract credits and exclude cancelled POs - Add today to detail view context for payment date default - Fix double-minus display bug in list template for negative balances - Annotate total_paid/total_credited in list view and admin to avoid N+1 - PurchaseOrder properties use annotations when available - Add sidebar accessibility (role=button, tabindex, aria-expanded, keydown) - Add 81 new tests: view tests, Stripe invoicing tests, QBO invoicing tests Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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.
Summary
select_for_update()locking and cancelled-PO guardsinvoice.paideventsTest plan
make devto seed database, visit/manage/<slug>/purchase-orders/to test CRUD/manage/<slug>/financial/for PO metrics section/admin/shows POs with readonly payment/credit inlinesmake cipasses (only pre-existing flaky badge test fails)🤖 Generated with Claude Code