Skip to content

feat: add percentage discount helper for demo review#3

Merged
Galzi1 merged 1 commit into
mainfrom
demo/percentage-discount-helper
Apr 10, 2026
Merged

feat: add percentage discount helper for demo review#3
Galzi1 merged 1 commit into
mainfrom
demo/percentage-discount-helper

Conversation

@Galzi1

@Galzi1 Galzi1 commented Apr 10, 2026

Copy link
Copy Markdown
Owner

Demo goal

Create a fresh, small PR that is easy to review and likely to produce high-signal review comments for the github-pr-kb Phase 8 demo.

What changed

  • added calculate_total_with_percentage_discount
  • kept the implementation intentionally small so the review can focus on behavior and pricing rules

Review prompts

  1. Should discount_rate be validated or clamped so values outside the expected range cannot create surprising totals?
  2. Should percentage discounts reuse more of the existing discount validation/calculation path instead of introducing a separate flow?
  3. Should the code or docstring make the business rule explicit about whether the percentage discount applies before tax and whether it is meant to stack with the absolute-discount helper?

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@qodo-code-review

Copy link
Copy Markdown

Review Summary by Qodo

Add percentage discount helper function

✨ Enhancement

Grey Divider

Walkthroughs

Description
• Add percentage discount helper function for pricing calculations
• Applies discount before tax calculation using multiplier approach
• Intentionally minimal implementation to facilitate review discussion
Diagram
flowchart LR
  subtotal["subtotal"] -- "multiply by 1 - discount_rate" --> discounted["discounted_subtotal"]
  discounted -- "apply sales_tax_rate" --> total["final total"]
Loading

Grey Divider

File Changes

1. demo_app.py ✨ Enhancement +11/-0

Add percentage discount calculation helper

• Added new function calculate_total_with_percentage_discount that applies percentage-based
 discounts
• Function accepts subtotal, sales_tax_rate, and discount_rate parameters
• Calculates discounted subtotal by multiplying by (1 - discount_rate) factor
• Delegates final total calculation to existing calculate_total function

demo_app.py


Grey Divider

Qodo Logo

@qodo-code-review

qodo-code-review Bot commented Apr 10, 2026

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (1)   📘 Rule violations (0)   📎 Requirement gaps (0)   🎨 UX Issues (0)
🐞\ ≡ Correctness (1)

Grey Divider


Action required

1. Unbounded percentage discount math 🐞
Description
calculate_total_with_percentage_discount computes subtotal * (1 - discount_rate) without validating
discount_rate, so discount_rate > 1 yields a negative total and discount_rate < 0 increases the
subtotal despite the function claiming to apply a discount.
Code

demo_app.py[R38-41]

+    """Apply a percentage discount before tax."""
+
+    discounted_subtotal = subtotal * (1 - discount_rate)
+    return calculate_total(discounted_subtotal, sales_tax_rate=sales_tax_rate)
Evidence
The new helper directly applies (1 - discount_rate) and passes the result into calculate_total,
which does not clamp negative subtotals; this differs from calculate_total_with_discount, which
validates the discount and clamps the discounted subtotal to >= 0.0.

demo_app.py[33-41]
demo_app.py[8-20]
demo_app.py[23-30]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`calculate_total_with_percentage_discount()` can return negative totals or unintended surcharges because it does not validate `discount_rate` before applying `subtotal * (1 - discount_rate)`.

### Issue Context
The existing absolute discount helper rejects negative discounts and clamps the discounted subtotal to `>= 0.0`, but the new percentage helper lacks equivalent protections.

### Fix Focus Areas
- demo_app.py[33-41]
- demo_app.py[23-30]

### Suggested fix
- Enforce a clear contract for `discount_rate` (e.g., raise `ValueError` unless `0.0 <= discount_rate <= 1.0`, or clamp into that range).
- Prevent negative subtotals similarly to the absolute discount helper (e.g., `discounted_subtotal = max(subtotal * (1 - discount_rate), 0.0)`), if the business rule is “never return a negative total.”
- Consider adding a brief docstring note describing allowed range and behavior when out of range (raise vs clamp).

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

ⓘ The new review experience is currently in Beta. Learn more

Grey Divider

Qodo Logo

Comment thread demo_app.py
Comment on lines +38 to +41
"""Apply a percentage discount before tax."""

discounted_subtotal = subtotal * (1 - discount_rate)
return calculate_total(discounted_subtotal, sales_tax_rate=sales_tax_rate)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Action required

1. Unbounded percentage discount math 🐞 Bug ≡ Correctness

calculate_total_with_percentage_discount computes subtotal * (1 - discount_rate) without validating
discount_rate, so discount_rate > 1 yields a negative total and discount_rate < 0 increases the
subtotal despite the function claiming to apply a discount.
Agent Prompt
### Issue description
`calculate_total_with_percentage_discount()` can return negative totals or unintended surcharges because it does not validate `discount_rate` before applying `subtotal * (1 - discount_rate)`.

### Issue Context
The existing absolute discount helper rejects negative discounts and clamps the discounted subtotal to `>= 0.0`, but the new percentage helper lacks equivalent protections.

### Fix Focus Areas
- demo_app.py[33-41]
- demo_app.py[23-30]

### Suggested fix
- Enforce a clear contract for `discount_rate` (e.g., raise `ValueError` unless `0.0 <= discount_rate <= 1.0`, or clamp into that range).
- Prevent negative subtotals similarly to the absolute discount helper (e.g., `discounted_subtotal = max(subtotal * (1 - discount_rate), 0.0)`), if the business rule is “never return a negative total.”
- Consider adding a brief docstring note describing allowed range and behavior when out of range (raise vs clamp).

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment thread demo_app.py
) -> float:
"""Apply a percentage discount before tax."""

discounted_subtotal = subtotal * (1 - discount_rate)

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

We should validate or clamp discount_rate here. Values outside the expected range can turn this helper into a surcharge path or produce a negative total, and that kind of pricing bug is easy to miss because the formula still looks mathematically valid.

Comment thread demo_app.py
"""Apply a percentage discount before tax."""

discounted_subtotal = subtotal * (1 - discount_rate)
return calculate_total(discounted_subtotal, sales_tax_rate=sales_tax_rate)

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

I would rather route percentage discounts through the same normalization path as the absolute-discount helper instead of creating a second calculation flow. Keeping one shared path for validation, tax, and rounding makes future pricing changes less likely to drift.

Comment thread demo_app.py
sales_tax_rate: float,
discount_rate: float,
) -> float:
"""Apply a percentage discount before tax."""

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Please make the business rule explicit in the docstring: is discount_rate expected to be 0..1, and does this percentage discount apply before tax the same way as the absolute-discount helper? Those semantics affect invoice behavior, so I would not leave them implied by the implementation.

@Galzi1 Galzi1 merged commit 9fcaffb into main Apr 10, 2026
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