Skip to content

Show negative enterprise fees in shopfront price breakdown#14396

Open
David-OFN-CA wants to merge 2 commits into
openfoodfoundation:masterfrom
David-OFN-CA:14017-negative-fees-pie-chart
Open

Show negative enterprise fees in shopfront price breakdown#14396
David-OFN-CA wants to merge 2 commits into
openfoodfoundation:masterfrom
David-OFN-CA:14017-negative-fees-pie-chart

Conversation

@David-OFN-CA

@David-OFN-CA David-OFN-CA commented Jun 11, 2026

Copy link
Copy Markdown
Collaborator

What? Why?

Negative enterprise fees (used as discounts by some enterprises) calculated correctly on orders and appeared correctly in reports, but were silently excluded from the shopfront price-breakdown pie chart.

Root cause: EnterpriseFeeCalculator#indexed_fees_by_type_for and #fees_by_type_for both filtered results with .select { |_fee_type, amount| amount > 0 }, dropping any fee type whose net amount was negative before the data reached the variant serializer and the Angular pie-chart template.

Fix: change both guards to .reject { |_fee_type, amount| amount.zero? } — this preserves negative values while still excluding true-zero entries.

(Note: PR opened by an AI agent on behalf of @David-OFN-CA)

What should we test?

  1. Create an enterprise fee with a negative amount (e.g. -20% flat rate) and add it to an order cycle.
  2. Visit the shop, click the pie chart icon on a variant that has the fee applied.
  3. Before this fix: the negative fee is absent from the breakdown.
  4. After this fix: the negative fee appears in the breakdown (e.g. as "Admin: -$2.00").
  5. Confirm that fees with a 0 value are still excluded from the pie chart.
  6. Confirm orders with only positive fees are unaffected.

Release notes

Changelog Category (reviewers may add a label for the release notes):

  • User facing changes
  • API changes (V0, V1, DFC or Webhook)
  • Technical changes only
  • Feature toggled

Screenshot

pr-14396-negative-fee-screenshot

Negative enterprise fees (used as discounts) were silently filtered out
by `amount > 0` guards in `EnterpriseFeeCalculator`, so they never
reached the variant serializer or the shopfront pie chart — even though
they calculated correctly on orders and appeared in reports.

Change both `select { amount > 0 }` calls to `reject { amount.zero? }`
so non-zero fees (positive and negative) are all included.

Closes openfoodfoundation#14017

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 11, 2026
@David-OFN-CA David-OFN-CA marked this pull request as draft June 11, 2026 17:47
@David-OFN-CA David-OFN-CA marked this pull request as ready for review June 11, 2026 19:18
@sigmundpetersen sigmundpetersen moved this from All the things 💤 to Code review 🔎 in OFN Delivery board Jun 12, 2026
@rioug rioug added the user facing changes Thes pull requests affect the user experience label Jun 15, 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.

I think we can improve the test, currently we are not testing the whole logic, see comments. But otherwise it looks good 👍

Comment thread lib/open_food_network/enterprise_fee_calculator.rb
Comment thread lib/open_food_network/enterprise_fee_calculator.rb
@github-project-automation github-project-automation Bot moved this from Code review 🔎 to In Progress ⚙ in OFN Delivery board Jun 15, 2026
@rioug asked to confirm zero-amount fees aren't taken into account.
Zero exclusion and negative inclusion were already covered separately,
but this adds a combined example per computation (regular + indexed)
that sets one fee to 0 (dropped) and one to negative (kept) in the same
breakdown, exercising the full reject { amount.zero? } logic in one
assertion.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@David-OFN-CA

Copy link
Copy Markdown
Collaborator Author

Thanks @rioug — added in 2df620e. Since zero-exclusion and negative-inclusion were already covered in separate examples, I added a combined test to each computation block (regular + indexed) that sets one fee to 0 and another to -1.23 in the same breakdown, then asserts the zero is dropped while the negative is kept. That exercises the full reject { amount.zero? } discrimination in a single assertion, so the whole logic is covered explicitly. All 30 examples pass locally, rubocop clean.

@sigmundpetersen sigmundpetersen added the ai AI generated or assisted PR/Issue label Jun 25, 2026
@David-OFN-CA

Copy link
Copy Markdown
Collaborator Author

Hi @rioug — this is ready for another look when you have a moment. 🙏

I've addressed your request to cover the zero-fee logic in both computation blocks. Each block (regular and indexed) now has:

  • "filters out zero fees" — sets a fee to 0 and asserts it's excluded (the direct check you asked for).
  • "drops zero fees while keeping negative ones in the same breakdown" (2df620e535) — sets one fee to -1.23 and another to 0 in the same breakdown, then asserts the negative is kept while the zero is dropped.

That second test is the meaningful regression guard here: it's the one case that would still fail under the old select { amount > 0 } (which dropped negatives too) and only passes under reject(&:zero?). So it pins exactly the behaviour change this PR introduces.

CI is green. Could you re-review when you get a chance? Thanks!

@David-OFN-CA David-OFN-CA requested a review from rioug June 25, 2026 14:41
@sigmundpetersen sigmundpetersen moved this from In Progress ⚙ to Code review 🔎 in OFN Delivery board Jun 25, 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.

Thanks @David-OFN-CA ! It looks good.

@dacook dacook left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Great, thanks for fixing.

Comment on lines +170 to +172
it "drops zero fees while keeping negative ones in the same breakdown" do
ef_admin.calculator.update_attribute :preferred_amount, -1.23
ef_sales.calculator.update_attribute :preferred_amount, 0

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I would suggest for next time, to set these fee amounts using let(), rather than updating here. Generally we try to set up all conditions for a test outside the it block. This helps clarify what the context is, and is also more efficient (this test will create an admin fee of 1.23, then update it to -1.23, which results in an unnecessary extra database interaction).
I'm not sure if I explained that well, so this is what I mean:

  context "with both zero and negative fees" do
    let!(:ef_admin) { create(:enterprise_fee, fee_type: 'admin', amount: -1.23, name: "Admin") }
    let!(:ef_sales) { create(:enterprise_fee, fee_type: 'sales', amount: 0, name: "Sales") }

    it "drops zero fees while keeping negative ones in the same breakdown"

(this replaces the ef_admin and ef_sales that were defined above)

@David-OFN-CA I'm wondering are you able to feed this feedback back to your AI agent to learn from?

@dacook dacook moved this from Code review 🔎 to Test Ready 🧪 in OFN Delivery board Jul 7, 2026
@AMEA-LYON AMEA-LYON self-assigned this Jul 8, 2026
@AMEA-LYON AMEA-LYON added the pr-staged-uk staging.openfoodnetwork.org.uk label Jul 8, 2026
@AMEA-LYON

Copy link
Copy Markdown

All tests successfull !! Congratulations !

fees_null fees_positive fees_negative

@AMEA-LYON AMEA-LYON removed the pr-staged-uk staging.openfoodnetwork.org.uk label Jul 8, 2026
@AMEA-LYON AMEA-LYON moved this from Test Ready 🧪 to Ready to go 🚀 in OFN Delivery board Jul 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ai AI generated or assisted PR/Issue user facing changes Thes pull requests affect the user experience

Projects

Status: Ready to go 🚀

Development

Successfully merging this pull request may close these issues.

Negative enterprise fees are not listed in the shop pie chart

5 participants