feat(invoice): Show the billed period on each invoice item - #7227
feat(invoice): Show the billed period on each invoice item#7227Shariqk3 wants to merge 1 commit into
Conversation
Customers cannot see when a charge starts or stops. Extra storage or a resized server looks the same as a full month of use. Each item now keeps the first and the last date of the usage records it bills for. The period comes from the usage records, and not from a new log doctype, because the usage records already hold the date of each charge. Fixes frappe#4942 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Confidence Score: 4/5The PR appears safe to merge after removing the migration’s non-atomic per-invoice commit. Billing-period behavior is coherent, but a later migration failure can leave only the previously processed invoices updated. Files Needing Attention: press/press/doctype/invoice/patches/set_item_periods_on_draft_invoices.py Reviews (1): Last reviewed commit: "feat(invoice): Show the billed period on..." | Re-trigger Greptile |
| invoice.set_item_periods() | ||
| for item in invoice.items: | ||
| item.db_update() | ||
| frappe.db.commit() |
There was a problem hiding this comment.
Committing inside the invoice loop makes the patch non-atomic: an error processing a later invoice leaves earlier invoices updated while the migration remains incomplete. Let the patch runner commit only after the entire patch succeeds.
| frappe.db.commit() |
Context Used: Guidelines for reviewing Frappe Framework applicat... (source)
Knowledge Base Used: Billing
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## develop #7227 +/- ##
===========================================
+ Coverage 59.66% 59.71% +0.05%
===========================================
Files 1019 1019
Lines 93493 93609 +116
Branches 1212 1213 +1
===========================================
+ Hits 55780 55902 +122
+ Misses 37690 37684 -6
Partials 23 23
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
Tick the box to add this pull request to the merge queue (same as
|
|
@Shariqk3 this solution is overengineered. I have mentioned the simple approach in the comment of the issue. I think this is already fixed by Huzan by showing subscription lists which tracks the same thing. |
Fixes #4942
Problem
An invoice line tells the customer what was charged and how much. It does not tell the customer when. A partner sees
server-1 Storage Add-on for 12 daysand cannot tell which 12 days. The same is true after a server resize: the invoice shows two lines for the same server on two plans, but not the day the change happened.Solution
Each Invoice Item now keeps the first and the last date of the usage records it bills for.
period_startandperiod_endare new read-only Date fields on Invoice Item.add_usage_recordwidens the period of an item when it adds a usage record to it.remove_usage_recordreads the periods back from the usage records that stay, so a cancelled usage record cannot leave a wrong date.server-1 Storage Add-on for 12 days from 03-08-2026 to 14-08-2026. The description also goes into the invoice PDF.The period comes from the usage records, and not from a new log doctype, because the usage records already hold the date of each charge.
Notes
descriptionfield is now 240 characters, up from 140. The period text adds about 30 characters, and a long site name plus a plan name could pass the old limit.Tests
Three new tests in
test_invoice.py:test_invoice_item_period_covers_first_and_last_usage_recordtest_invoice_item_period_moves_when_the_first_usage_record_is_cancelledtest_invoice_item_description_names_the_billed_periodAll 32 tests in
press.press.doctype.invoice.test_invoicepass, together with the subscription tests.ruff check, Biome, and semgrep are clean, and the dashboard builds.🤖 Generated with Claude Code