You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[Invoices]: Generate invoice number for draft recurring invoices #368
Generate the invoice number for draft invoices for recurring invoices does not respect the setting on invoice settings
Expected Behavior
When I choose "Generate the invoice number for draft invoices" with "No" it should be used for generating the recurring invoices too when the draft invoices are generated from recurring invoices
Current Behavior
When you run the recurring invoices with "Automatically Email recurring invoices" to "No" a invoice number is generated for the draft invoices no matter if the setting "Generate the invoice number for draft invoices" is set to "No"
Steps to Reproduce
Go to Settings
Set "Generate the invoice number for draft invoices" to "No"
Set "Automatically Email recurring invoices" to "No" because
Generate the draft invoices with the "index.php/invoices/cron/recur/...."
Can you take a screenshot of the current situation and then add with your editor in a new image what you wanted to see (expected behavior)?
Generating the draft invoices in the process of recurring invoices must follow the same rules like the manual copy of a invoice or generating a new invoice. What you see in a screenshot depends additionally on what you setup un the invoice group form so it make no sense to put here a screenshot
Bug story: As a company admin, I want the "Generate invoice number for draft invoices" setting to be respected when the recurring invoice cron generates draft invoices, so that draft invoices created from recurring schedules do not get a permanent invoice number until they are finalised.
v2 context: v2 uses RecurringInvoiceService (no cron URL — uses Laravel's artisan scheduler). The setting is stored in company settings as generate_invoice_number_for_draft. When the scheduler fires and generates a draft invoice from a RecurringInvoice, it must check this setting before assigning a number.
Acceptance Criteria:
When generate_invoice_number_for_draft = false and the recurring invoice scheduler runs with auto_send = false, the generated draft invoice has invoice_number = null.
When generate_invoice_number_for_draft = true, the draft invoice is assigned a number immediately on creation.
Setting changes take effect on the next scheduler run (not retroactively).
The fix applies via php artisan invoiceplane:process-recurring (or equivalent artisan command).
Implementation:
In RecurringInvoiceService::generateInvoice(), after creating the draft invoice, check $company->settings->generate_invoice_number_for_draft.
If false, skip calling NumberingService::assignInvoiceNumber($invoice).
If true, call NumberingService::assignInvoiceNumber($invoice) as normal.
Test Scenarios (PHPUnit):
// Draft from recurring has no number when setting is false/* Arrange */$this->company->settings()->update(['generate_invoice_number_for_draft' => false]);
$ri = RecurringInvoice::factory()->for($this->company)
->create(['auto_send' => false, 'next_invoice_date' => today()]);
/* Act */app(RecurringInvoiceService::class)->processRecurring();
/* Assert */$this->assertDatabaseHas('invoices',
['recurring_invoice_id' => $ri->id, 'invoice_number' => null]);
// Draft from recurring gets number when setting is true/* Arrange */$this->company->settings()->update(['generate_invoice_number_for_draft' => true]);
$ri = RecurringInvoice::factory()->for($this->company)
->create(['auto_send' => false, 'next_invoice_date' => today()]);
/* Act */app(RecurringInvoiceService::class)->processRecurring();
/* Assert */$invoice = Invoice::where('recurring_invoice_id', $ri->id)->first();
$this->assertNotNull($invoice->invoice_number);
changed the title [-]Generate the invoice number for draft invoices for recurring invoices[/-][+][Invoices]: Generate invoice number for draft recurring invoices[/+]on Jun 13, 2026
Added to support future implementation of this request. The issue body is unchanged.
There is no "Generate the invoice number for draft invoices" setting anywhere in this codebase today (ip2 has no generate_invoice_number/invoice_number_for_draft-style key at all) — this v1 setting was never ported to v2. More fundamentally, Modules\Invoices\Services\RecurringInvoiceService is an empty stub class: there is currently no code in v2 that generates draft invoices from a recurring profile at all, so the index.php/invoices/cron/recur/... flow this bug describes doesn't exist yet either — this report is really about a not-yet-built feature (tracked as #52 in this epic). The scaffolding around recurring invoices is also inconsistent independent of this bug: RecurringInvoice (model and factory) still import a Modules\Core\Models\DocumentGroup class that no longer exists in the codebase (it was renamed to Numbering), and RecurringInvoiceForm binds a document_group_id field that isn't a real column on recurring_invoices (the actual FK is numbering_id).
Edge cases worth covering: a company that flips the setting between two generation runs (only new invoices should respect the new value; already-generated drafts shouldn't be retroactively renumbered), and a recurring profile whose numbering_id scheme was deleted after being referenced.
Original report (preserved): With "Generate the invoice number for draft invoices" = No and "Automatically Email recurring invoices" = No, running the recurring cron still assigns invoice numbers to the generated draft invoices, ignoring the setting.
v1 spec: application/modules/invoices/models/Mdl_invoices.php:414-422 — on create, a DRAFT invoice gets a real number only when generate_invoice_number_for_draft = 1, otherwise invoice_number = ''; the number is assigned later on first status change away from draft (Mdl_invoices.php:677-686). The v1 recurring cron bypassed this by passing a pre-computed number (application/modules/invoices/controllers/Cron.php:83) — that bypass is the bug being reported.
v2 status: the Toggle exists (Modules/Core/Filament/Admin/Pages/Settings.php:330-331) and manual invoice creation honors it (Modules/Invoices/Tests/Feature/InvoiceNumberGenerationOnCreateTest.php), but the recurring generation engine (Epic #52) does not exist yet. This issue pins the requirement so the engine does not re-introduce the v1 bug.
Specific
The recurring generation engine must route generated invoices through the same numbering path as manual creation: when generate_invoice_number_for_draft is off, engine-generated drafts get no number (assigned on transition out of DRAFT, drawing from the schedule's numbering_id group); when on, the number is reserved at generation time from recurring_invoices.numbering_id (fallback: source invoice's numbering group).
Measurable
Toggle off → generated draft has null/empty number; sending it later assigns the next number in the schedule's numbering group with no gaps.
Toggle on → generated draft carries the next number immediately.
Two schedules sharing one numbering group never collide (sequential numbers, no duplicates) — v2 already guards duplicates (InvoiceDuplicateNumberPreventionTest.php).
Achievable
No new code path: the engine calls the existing invoice-creation service which already implements the toggle; this issue is the regression test contract.
Relevant
Sequential-numbering compliance (many jurisdictions forbid gaps); drafts that may be discarded must not burn numbers.
Time-Bound
Ships inside the generation-engine sprint (Epic #52) as its numbering acceptance tests.
Arrange
Numbering group at next value N; generate_invoice_number_for_draft = false; automatic_email_on_recur = false; one due monthly schedule with numbering_id set.
Act
Run the engine; then move the generated invoice from DRAFT to SENT.
Assert
After generation: invoice exists in DRAFT with empty/null invoice_number; numbering group still at N.
After status change: invoice number equals N's formatted value; group advanced to N+1.
Re-run with toggle = true: generated draft is numbered immediately from the schedule's group.
Schedule without numbering_id falls back to the source invoice's numbering group.
Activity
nielsdrost7 commentedon Apr 6, 2025
Can you take a screenshot of the current situation and then add with your editor in a new image what you wanted to see (expected behavior)?
gklimm commentedon Apr 6, 2025
Generating the draft invoices in the process of recurring invoices must follow the same rules like the manual copy of a invoice or generating a new invoice. What you see in a screenshot depends additionally on what you setup un the invoice group form so it make no sense to put here a screenshot
nielsdrost7 commentedon Jun 13, 2026
Planning Note — v2 Implementation
Bug story: As a company admin, I want the "Generate invoice number for draft invoices" setting to be respected when the recurring invoice cron generates draft invoices, so that draft invoices created from recurring schedules do not get a permanent invoice number until they are finalised.
v2 context: v2 uses
RecurringInvoiceService(no cron URL — uses Laravel's artisan scheduler). The setting is stored in company settings asgenerate_invoice_number_for_draft. When the scheduler fires and generates a draft invoice from aRecurringInvoice, it must check this setting before assigning a number.Acceptance Criteria:
generate_invoice_number_for_draft = falseand the recurring invoice scheduler runs withauto_send = false, the generated draft invoice hasinvoice_number = null.generate_invoice_number_for_draft = true, the draft invoice is assigned a number immediately on creation.php artisan invoiceplane:process-recurring(or equivalent artisan command).Implementation:
RecurringInvoiceService::generateInvoice(), after creating the draft invoice, check$company->settings->generate_invoice_number_for_draft.false, skip callingNumberingService::assignInvoiceNumber($invoice).true, callNumberingService::assignInvoiceNumber($invoice)as normal.Test Scenarios (PHPUnit):
Generated by Claude Code
[-]Generate the invoice number for draft invoices for recurring invoices[/-][+][Invoices]: Generate invoice number for draft recurring invoices[/+]nielsdrost7 commentedon Jul 16, 2026
Test Suggestions
Added to support future implementation of this request. The issue body is unchanged.
There is no "Generate the invoice number for draft invoices" setting anywhere in this codebase today (
ip2has nogenerate_invoice_number/invoice_number_for_draft-style key at all) — this v1 setting was never ported to v2. More fundamentally,Modules\Invoices\Services\RecurringInvoiceServiceis an empty stub class: there is currently no code in v2 that generates draft invoices from a recurring profile at all, so theindex.php/invoices/cron/recur/...flow this bug describes doesn't exist yet either — this report is really about a not-yet-built feature (tracked as #52 in this epic). The scaffolding around recurring invoices is also inconsistent independent of this bug:RecurringInvoice(model and factory) still import aModules\Core\Models\DocumentGroupclass that no longer exists in the codebase (it was renamed toNumbering), andRecurringInvoiceFormbinds adocument_group_idfield that isn't a real column onrecurring_invoices(the actual FK isnumbering_id).it_leaves_the_generated_invoice_number_null_when_auto_numbering_is_disabled()it_assigns_an_invoice_number_immediately_when_auto_numbering_is_enabled()it_respects_the_setting_independently_of_the_auto_email_recurring_toggle()Edge cases worth covering: a company that flips the setting between two generation runs (only new invoices should respect the new value; already-generated drafts shouldn't be retroactively renumbered), and a recurring profile whose
numbering_idscheme was deleted after being referenced.nielsdrost7 commentedon Jul 18, 2026
v1 spec:
application/modules/invoices/models/Mdl_invoices.php:414-422— on create, a DRAFT invoice gets a real number only whengenerate_invoice_number_for_draft = 1, otherwiseinvoice_number = ''; the number is assigned later on first status change away from draft (Mdl_invoices.php:677-686). The v1 recurring cron bypassed this by passing a pre-computed number (application/modules/invoices/controllers/Cron.php:83) — that bypass is the bug being reported.v2 status: the Toggle exists (
Modules/Core/Filament/Admin/Pages/Settings.php:330-331) and manual invoice creation honors it (Modules/Invoices/Tests/Feature/InvoiceNumberGenerationOnCreateTest.php), but the recurring generation engine (Epic #52) does not exist yet. This issue pins the requirement so the engine does not re-introduce the v1 bug.Specific
The recurring generation engine must route generated invoices through the same numbering path as manual creation: when
generate_invoice_number_for_draftis off, engine-generated drafts get no number (assigned on transition out of DRAFT, drawing from the schedule'snumbering_idgroup); when on, the number is reserved at generation time fromrecurring_invoices.numbering_id(fallback: source invoice's numbering group).Measurable
InvoiceDuplicateNumberPreventionTest.php).Achievable
No new code path: the engine calls the existing invoice-creation service which already implements the toggle; this issue is the regression test contract.
Relevant
Sequential-numbering compliance (many jurisdictions forbid gaps); drafts that may be discarded must not burn numbers.
Time-Bound
Ships inside the generation-engine sprint (Epic #52) as its numbering acceptance tests.
Arrange
generate_invoice_number_for_draft = false;automatic_email_on_recur = false; one due monthly schedule withnumbering_idset.Act
Assert
invoice_number; numbering group still at N.numbering_idfalls back to the source invoice's numbering group.