Skip to content

Add Balance Due and Available Credit columns to Customers report#14390

Open
NiftyGaloot wants to merge 6 commits into
openfoodfoundation:masterfrom
NiftyGaloot:wishlist-562-balance-credit-columns
Open

Add Balance Due and Available Credit columns to Customers report#14390
NiftyGaloot wants to merge 6 commits into
openfoodfoundation:masterfrom
NiftyGaloot:wishlist-562-balance-credit-columns

Conversation

@NiftyGaloot

@NiftyGaloot NiftyGaloot commented Jun 10, 2026

Copy link
Copy Markdown

What's changed?

Adds two new columns to the Customers report:

  • Balance Due ($) — the outstanding amount the customer still owes across all their orders at the hub. Uses outstanding_balance (which deducts incomplete customer-credit payments) so applied-but-not-yet-captured credits are accounted for. Floored at zero.
  • Available Credit ($) — credit held in the customer's account via CustomerAccountTransaction records, available to apply to future orders. This is a separate ledger from order balances.

Closes openfoodfoundation/wishlist#562

How to test

  1. Generate a Customers report in the admin (/admin/reports/customers)
  2. Confirm the two new columns appear in the table and CSV export

No need to run these, they are run as part of Continuous Integration (CI), ie we run the full test suite when a PR is created:
4. Run unit specs: bundle exec rspec spec/lib/reports/customers_report_spec.rb
5. Run system spec: bundle exec rspec spec/system/admin/reports/customers_report_spec.rb

Files changed

  • lib/reporting/reports/customers/base.rb — added balance_due and credit_due columns + columns_format
  • config/locales/en.yml — added report_header_balance_due and report_header_credit_due i18n keys
  • spec/lib/reports/customers_report_spec.rb — updated all row expectations + added credit balance context
  • spec/system/admin/reports/customers_report_spec.rb — added new headers to expectation

🤖 Generated with Claude Code

Screenshots

image

NiftyGaloot and others added 4 commits June 1, 2026 12:36
- balance_due: use outstanding_balance (OrderBalance object) instead of new_outstanding_balance
- credit_due: use customer.credit_balance instead of deriving from order balances
- balance_due: sums outstanding_balance across a customer's orders at a hub,
  accounting for incomplete customer credit payments (floored at zero)
- credit_due: reads customer.credit_balance from CustomerAccountTransaction
  records — the separate credit ledger, not derived from order balances
- columns_format declares both as :currency for the report renderer
- Rename column header from "Credit Due" to "Available Credit" to match
  the customers tab in the dashboard
- Document known divergence in OutstandingBalanceQuery: unlike
  Balance#new_outstanding_balance, the SQL query does not deduct incomplete
  customer credit payments, causing the dashboard to overstate what a
  customer owes when credit has been applied but not yet captured

Closes openfoodfoundation/wishlist#562

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Restore 2-space indentation in Base#filter (regressed to 1-space)
- Add spec asserting credit_due reflects a non-zero CustomerAccountTransaction
  balance; previously all examples asserted "$0.00", so a regression in
  Customer#credit_balance would have gone undetected

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Update column name from "Credit Due ($)" to "Available Credit ($)"
  to match the renamed i18n key
- Remove hasBalanceDue/hasCreditDue assertions that required specific
  seed data to be present; format and non-negative value checks are
  sufficient here — non-zero value coverage is provided by
  customer-report-journey.spec.ts which sets up its own test data

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@github-project-automation github-project-automation Bot moved this to All the things 💤 in OFN Delivery board Jun 10, 2026
@sigmundpetersen sigmundpetersen moved this from All the things 💤 to In Progress ⚙ in OFN Delivery board Jun 10, 2026
@NiftyGaloot

Copy link
Copy Markdown
Author

This is my first attempt at an addition to the OFN code. I used both OpenCode and Claude AI to evaluate and test this wishlist item. The initial work was done using OpenCode with changes to the math suggested after asking for posting a proposed solution and asking for feedback. Additonal review and testing was done with Claude. Playwright allowed an inspection of test transactions in the localhost. The results appear to be working correctly.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@NiftyGaloot NiftyGaloot marked this pull request as ready for review June 10, 2026 16:19
The columns method is a data definition hash with multiple procs;
the complexity is inherent to its structure, not reducible without
obscuring the intent.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@NiftyGaloot NiftyGaloot marked this pull request as draft June 10, 2026 21:35
@NiftyGaloot NiftyGaloot marked this pull request as ready for review June 10, 2026 21:42
@sigmundpetersen sigmundpetersen moved this from In Progress ⚙ to Code review 🔎 in OFN Delivery board Jun 11, 2026

@rioug rioug left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@NiftyGaloot thanks for your help 🙏 . The changes look good 👍
For next time, we have Pull Request template, could you use it when creating a PR ? And also, it would have been better to remove the playwright related commits.

Comment on lines +14 to +19
#
# KNOWN DIVERGENCE: Balance#new_outstanding_balance deducts incomplete customer credit payments
# (payments.incomplete.customer_credit.sum(:amount)) from the balance, but this SQL query has no
# join to the payments table and cannot do the same. As a result, orders where customer credit has
# been applied but not yet captured are counted as fully unpaid here, causing the dashboard
# customers tab to overstate what the customer owes compared to the Customers report.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for documenting the divergence. It's out of scope for this PR, but it would be good to get others point on vue on this. OutstandingBalanceQuery takes into account any existing order, ie it includes non placed orders. This doesn't really make sense to me, if the order is not placed then the balance is not technically outstanding ? If we fix the query to only includes placed order, then the divergence will go away. @mkllnk @dacook what do you think ?

end

# rubocop:disable Metrics/AbcSize
# rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Claude is correct in its assessment but the intent of the comment is to say we are not going to fix it. Surprisingly, rubocop is not complaining after removal, so happy to keep as it is.

@rioug

rioug commented Jun 12, 2026

Copy link
Copy Markdown
Collaborator

@RachL this PR closes a wishlist item, I am not sure what's the usual process, but I though we should have an issue in the OFN repo to link to this PR ?

@rioug rioug added the user facing changes Thes pull requests affect the user experience label Jun 12, 2026
@RachL

RachL commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

@rioug we leave in wishlist anything that is not prepared / not ready to dev. I don't think it's mandatory to create an issue in the OFN repo. It is however mandatory to align on what is needed before submitting a PR. I don't follow the ai community of practice, therefore I can't comment if this is being done or not.

@NiftyGaloot

Copy link
Copy Markdown
Author

@rioug @RachL I did look for a way to move the wishlist item into a pr but didn't find how to do it. That was before learning how to use AI to find such things. I asked it this question now:

Is there information on how a wishlist item moves to a pr in the OFN documentation?

And got this response:

OFN's own docs cover parts of the path but don't have a single "wishlist → PR" page. The full pipeline is scattered:

  1. Wishlist — ideas collected at github.com/openfoodfoundation/wishlist (a separate repo for feature requests)
  2. Forum discussion — community.openfoodnetwork.org (Product Development category) — where wishlist items are discussed and prioritized per CONTRIBUTING.md
  3. GitHub issue — filed in the main repo with the appropriate template (story/bug/feature/tech-debt)
  4. PR → merge → deploy — documented in the wiki: review, test, merge & deploy (https://github.com/openfoodfoundation/openfoodnetwork/wiki/The-process-of-review,-test,-merge-and-deploy) and making a great PR (https://github.com/openfoodfoundation/openfoodnetwork/wiki/Making-a-great-pull-request)
    The step from wishlist → forum → GitHub issue is the least documented. The GOAT external doc (contributing-workflow.md) describes it as forum → issue → PR → merge, but that file is maintained outside OFN's own docs.
    The OFN Contributor Guide (https://ofn-user-guide.gitbook.io/ofn-contributor-guide/) and the wiki's Pipeline development process (https://github.com/openfoodfoundation/openfoodnetwork/wiki/Pipeline-development-process) have more context on how occasional contributors vs core devs pick up issues.

Should something be added to the documents spelling out what's needed to move a wishlist item up the chain to a pr?
Would you like me to create the steps I missed?

@RachL

RachL commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

@NiftyGaloot just to be sure we are speaking of the same thing :

  • a PR (pull request) is a request to merge a code contribution in one of the software branch (usually the main/master branch). technically it can be created any time. Often in open source (not just OFN) maintainers ask PR to be linked to issues.
  • an issue on the other end, holds no lines of code. It's a description of what needs to be done. In OFN's processes, currently wishlist are github issues.

So you can never transform an issue into a PR. Both will always stay but a PR can close an issue when it's merged.

If the question was how do wishlist get priorities in OFN, then in that case the current workflow is that there is a dedicated budget (mostly funded feature currently) and then it moves up.
A couple of years ago when OFN had more budget we put processes in place to find the low hang fruit in the wishlist to move them up to delivery regularly. There is unfortunately no budget to support these kind of processes currently.

@rioug

rioug commented Jun 15, 2026

Copy link
Copy Markdown
Collaborator

Thanks @RachL .

I just wanted some clarity on who has to say we are happy to proceed with a wishlist item, I am assuming it's Products. I'll raise topic in delivery circle this week. I am just trying to make sure we don't get random PR on something people want to add to OFN without prior consultation with the team/community.

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

Labels

user facing changes Thes pull requests affect the user experience

Projects

Status: Code review 🔎

Development

Successfully merging this pull request may close these issues.

Add Balance Due and Credit Due Columns to Customer report.

4 participants