Skip to content

[Settings]: Company panel — assign Invoice Groups #240

Closed

Description

@nielsdrost7

SMART Plan — As an Admin, in the company Panel I want to be able to assign Invoice Groups to that single company

Specific

Within the Company panel (/{tenant}) Settings page (or a dedicated page), add a Select field that allows the customer_admin to choose the default Numbering (Invoice Group) for new invoices generated by their company. The selected Numbering ID is stored on the company record (e.g. companies.default_numbering_id) or via a dedicated settings key.

Measurable

  • The Settings page renders a select field populated with Numbering records available to this company.
  • Saving the form updates companies.default_numbering_id (or equivalent settings key).
  • The saved value is reflected on subsequent page loads (persisted correctly).
  • Only customer_admin and elevated roles can modify this setting.

Achievable

  1. Add default_numbering_id nullable FK column to companies table — Modules/Core/Database/Migrations/
  2. Add defaultNumbering() BelongsTo on Company model — Modules/Core/Models/Company.php
  3. Add a Select for default_numbering_id on the company Settings schema — Modules/Core/Filament/Company/Pages/Settings.php
  4. Scope select options to Numbering records associated with or owned by this company.
  5. Protect with role check.

Relevant

Each company may have different invoice numbering sequences (annual reset, project codes, etc.). The default Invoice Group drives the auto-increment counter for new invoices and quotes, so getting this right upfront saves manual correction of document numbers later.

Time-bound

Sprint 6.


Arrange · Act · Assert

// Modules/Core/Tests/Feature/Company/CompanyDefaultNumberingTest.php

#[Test]
public function it_saves_default_numbering_for_company(): void
{
    /* Arrange */
    $numbering = Numbering::factory()->for($this->company)->create();

    /* Act */
    $response = $this->testLivewire(CompanySettings::class)
        ->fillForm(['default_numbering_id' => $numbering->id])
        ->call('save');

    /* Assert */
    $response->assertHasNoErrors();
    $this->assertDatabaseHas('companies', [
        'id'                  => $this->company->id,
        'default_numbering_id' => $numbering->id,
    ]);
}

Activity

  1. added this to the v2.0.0-alpha milestone on Dec 28, 2025
  2. coderabbitai commented on Jan 2, 2026

    @coderabbitai
    Contributor

    Coding Plan

    Approach

    Enable administrators to manage Invoice Groups (Numberings of type INVOICE) for companies directly from the Company resource in the Admin panel, allowing them to view, create, edit, and delete invoice groups associated with a specific company.

    Observations

    The project is a Laravel-based application using Filament for admin panels with a modular structure. Invoice Groups are implemented through the Numbering model (located in Modules/Core) which already has a company_id foreign key establishing a one-to-many relationship. The Company model resides in Modules/Core/Models/Company.php and has a Filament admin resource at Modules/Core/Filament/Admin/Resources/Companies/CompanyResource.php. The codebase follows a pattern of using RelationManagers to manage hasMany relationships in Filament resources, as evidenced by multiple examples in Projects, Quotes, and Invoices modules. The Company resource currently has no relation managers registered.

    Assumptions
    Assumption 1: UI Approach for Relationship Management

    Options Considered:

    • RelationManager pattern - dedicated tab showing numberings table with actions
    • Inline form component - CheckboxList or Select with relationship() method

    Chosen Option: 1

    Rationale: The codebase exclusively uses RelationManagers for managing hasMany relationships (see TasksRelationManager, QuoteItemsRelationManager). No examples exist of inline CheckboxList/Select for hasMany management. This approach aligns with established patterns and provides better UX for managing potentially many records.

    💡 User Tips

    Regenerate the plan with different choices with @coderabbitai <feedback>.

    Implementation Steps

    Phase 1: Create Numberings Relation Manager

    Add a RelationManager to the Company admin resource that allows administrators to view and manage invoice groups (Numberings of type INVOICE) for each company.

    Task 1: Create NumberingsRelationManager Class

    Create a new RelationManager specifically for managing invoice groups from the Company resource perspective.

    • Create Modules/Core/Filament/Admin/Resources/Companies/RelationManagers/NumberingsRelationManager.php extending Filament's RelationManager
    • Set protected static $relationship property to 'numberings' (referencing the hasMany relationship on Company model)
    • Configure the table to display relevant numbering fields (name, type, format, prefix, next_id)
    • Apply default query modifier to filter only Numberings where type = NumberingType::INVOICE so only invoice groups are shown
    • Add header action for creating new invoice groups using existing NumberingForm schema patterns
    • Add table actions for editing and deleting individual numbering records
    • Configure appropriate authorization checks for create/edit/delete actions
    Task 2: Register Relation Manager in CompanyResource

    Integrate the new RelationManager into the Company resource so it appears as a tab when viewing/editing companies.

    • Update Modules/Core/Filament/Admin/Resources/Companies/CompanyResource.php
    • Modify the getRelations() method to return an array containing NumberingsRelationManager::class
    • Ensure the relation manager tab label is translated appropriately (e.g., "Invoice Groups")
    Task 3: Add Company Relationship to Numbering Model (If Missing)

    Verify and potentially add the inverse relationship from Numbering to Company for proper ORM traversal.

    • Review Modules/Core/Models/Numbering.php to confirm existence of company() belongsTo relationship
    • If not present, add public function company(): BelongsTo method returning belongsTo(Company::class)
    • Ensure the BelongsToCompany trait is applied (already confirmed in exploration)
    🤖 Prompt for AI agents
    Create a NumberingsRelationManager for the Company resource to manage invoice
    groups. This phase sets up the relation manager with filtering for INVOICE type
    numberings.
    
    Create NumberingsRelationManager class:
    - Extend Filament's RelationManager
    - Set relationship property to 'numberings'
    - Configure table columns for name, type, format, prefix, next_id
    - Add query modifier to filter where type = NumberingType::INVOICE
    - Add header action for creating new invoice groups using existing NumberingForm
    patterns
    - Add edit and delete table actions
    - Include authorization checks
    
    Register in CompanyResource:
    - Update getRelations() method to include NumberingsRelationManager::class
    - Set appropriate tab label with translation
    
    Verify Numbering model:
    - Check for company() belongsTo relationship
    - Add if missing: public function company(): BelongsTo returning
    belongsTo(Company::class)
    - Verify BelongsToCompany trait is applied
    

    Phase 2: Implement Comprehensive Tests with AAA Pattern

    Create feature tests following the strict AAA (Arrange-Act-Assert) pattern to verify the relation manager functionality and handle edge cases. All tests must use explicit section separators (/* arrange */, /* act */, /* assert */ comments or region markers) to clearly demarcate each phase, following the established codebase pattern observed in Modules/Quotes/Tests/Feature/QuotesTest.php.

    Task 1: Create NumberingRelationManager Feature Tests with AAA Structure

    Implement comprehensive tests for the relation manager functionality covering standard CRUD operations, with each test explicitly structured using AAA pattern.

    • Create Modules/Core/Tests/Feature/CompanyNumberingRelationManagerTest.php extending AbstractAdminPanelTestCase
    • Each test must include explicit /* arrange */, /* act */, and /* assert */ section comments
    • Test: Admin can view numberings relation manager on company edit page
      • Arrange: Create authenticated admin user, create company with 2-3 invoice groups using factories
      • Act: Navigate to company edit page and render the numberings relation manager tab
      • Assert: Verify table renders with correct data, correct number of rows displayed
    • Test: Admin can see only INVOICE type numberings in the relation manager
      • Arrange: Create company, create 2 INVOICE type numberings, 1 QUOTE type, 1 EXPENSE type using Numbering::factory()
      • Act: Load relation manager table component
      • Assert: Verify only 2 INVOICE type numberings appear, non-INVOICE types are filtered out
    • Test: Admin can create new invoice group for company through relation manager
      • Arrange: Create authenticated admin, create company, prepare form data for new invoice group
      • Act: Call CreateAction on relation manager with form data
      • Assert: Assert database has new numbering record with correct company_id and type=INVOICE
    • Test: Admin can edit existing invoice group through relation manager
      • Arrange: Create company with existing invoice group, prepare updated form data (change name/format)
      • Act: Call EditAction on relation manager with updated data
      • Assert: Assert database record updated with new values, company_id remains unchanged
    • Test: Admin can delete invoice group through relation manager
      • Arrange: Create company with invoice group, verify it exists in database
      • Act: Call DeleteAction on relation manager for the invoice group
      • Assert: Assert database no longer contains the numbering record (or soft deleted if applicable)
    • Test: Newly created invoice group automatically has correct company_id
      • Arrange: Create two different companies, authenticate as admin, prepare invoice group data
      • Act: Create invoice group through relation manager for company A
      • Assert: Verify created numbering has company_id matching company A, not company B
    Task 2: Create Edge Case Tests with Explicit AAA Structure

    Implement tests for boundary conditions and error scenarios to ensure robustness, with clear AAA separation in each test.

    • Continue in Modules/Core/Tests/Feature/CompanyNumberingRelationManagerTest.php file
    • Each edge case test must follow strict AAA pattern with section comments
    • Test: Relation manager displays empty state when company has no invoice groups
      • Arrange: Create company with zero numberings (no factory calls for numberings)
      • Act: Load relation manager component
      • Assert: Verify empty state message displayed, no table rows present
    • Test: Relation manager correctly handles company with many invoice groups (pagination)
      • Arrange: Create company with 25+ invoice groups to exceed typical page size
      • Act: Load relation manager table, navigate to page 2
      • Assert: Verify pagination controls present, correct subset of records on each page
    • Test: Creating invoice group with duplicate name for same company shows validation error
      • Arrange: Create company with existing invoice group named "Default Invoice Group"
      • Act: Attempt to create another invoice group with same name through CreateAction
      • Assert: Assert validation error message displayed, database count unchanged
    • Test: Deleting invoice group that is referenced by invoices handles appropriately
      • Arrange: Create company, create invoice group, create invoice using that numbering_id
      • Act: Attempt to delete the invoice group through DeleteAction
      • Assert: Verify appropriate behavior (cascade delete invoices OR restrict deletion with error message based on FK constraint)
    • Test: Non-admin users cannot access relation manager (authorization)
      • Arrange: Create regular user without admin permissions, create company
      • Act: Attempt to access relation manager as non-admin user
      • Assert: Assert authorization exception thrown or access denied
    • Test: Filtering excludes non-INVOICE numbering types completely
      • Arrange: Create company with numberings of all types (INVOICE, QUOTE, EXPENSE, PAYMENT, PROJECT, TASK, CUSTOMER)
      • Act: Load relation manager and retrieve all visible records
      • Assert: Assert only INVOICE type numberings present, count matches expected, verify each record's type field
    • Test: Editing invoice group type to non-INVOICE removes it from relation manager view
      • Arrange: Create company with invoice group, load relation manager showing the record
      • Act: Edit the numbering to change type from INVOICE to QUOTE
      • Assert: Reload relation manager, assert record no longer visible in table
    • Test: Creating invoice group with missing required fields shows validation errors
      • Arrange: Create company, prepare incomplete form data (missing name or format)
      • Act: Attempt to submit CreateAction with incomplete data
      • Assert: Assert validation error messages for required fields, database count unchanged
    Task 3: Create Authorization and Permission Tests with AAA Structure

    Verify proper access control for the relation manager operations, with explicit AAA pattern in each test.

    • Create tests in the same test file checking authorization boundaries
    • Each authorization test must use clear AAA section separators
    • Test: Super admin can perform all operations (create/edit/delete)
      • Arrange: Create super admin user using factory, create company with invoice groups
      • Act: Perform create, edit, and delete operations through relation manager
      • Assert: All operations succeed, database reflects changes, no authorization errors
    • Test: Regular admin user permissions (if role-based access control exists)
      • Arrange: Create regular admin user with limited permissions, create company
      • Act: Attempt various operations (create/edit/delete) on invoice groups
      • Assert: Verify operations succeed or fail based on configured permissions
    • Test: Company panel users cannot access admin relation manager (separation of concerns)
      • Arrange: Create company panel user (non-admin), authenticate as that user
      • Act: Attempt to access CompanyResource relation manager from admin panel
      • Assert: Assert access denied or authorization exception, user cannot view/modify
    • Test: Unauthorized user attempting to create invoice group for another user's company
      • Arrange: Create two companies (A and B), create user with access only to company A
      • Act: Attempt to create invoice group for company B through relation manager
      • Assert: Assert authorization failure, database unchanged for company B
    🤖 Prompt for AI agents
    Create comprehensive feature tests for the NumberingsRelationManager following
    strict AAA pattern with explicit section separators. This phase ensures the
    relation manager works correctly with proper access control.
    
    Create CompanyNumberingRelationManagerTest extending AbstractAdminPanelTestCase:
    - Use explicit /* arrange */, /* act */, /* assert */ section comments in every
    test
    - Follow the pattern from Modules/Quotes/Tests/Feature/QuotesTest.php
    
    CRUD operation tests with AAA structure:
    - Test viewing relation manager: Arrange (create admin + company with 2-3
    invoice groups), Act (navigate to company edit page and render tab), Assert
    (verify table renders with correct data)
    - Test INVOICE type filtering: Arrange (create company with 2 INVOICE, 1 QUOTE,
    1 EXPENSE numberings), Act (load relation manager), Assert (only 2 INVOICE types
    visible)
    - Test creating invoice group: Arrange (create admin + company + form data), Act
    (call CreateAction), Assert (database has new record with correct company_id and
    type=INVOICE)
    - Test editing invoice group: Arrange (create company with invoice group +
    updated data), Act (call EditAction), Assert (database updated, company_id
    unchanged)
    - Test deleting invoice group: Arrange (create company with invoice group), Act
    (call DeleteAction), Assert (record no longer in database)
    - Test automatic company_id assignment: Arrange (create two companies + admin),
    Act (create invoice group for company A), Assert (numbering has company_id of
    company A)
    
    Edge case tests with AAA structure:
    - Test empty state: Arrange (company with no numberings), Act (load relation
    manager), Assert (empty state displayed)
    - Test pagination: Arrange (company with 25+ invoice groups), Act (load and
    navigate pages), Assert (pagination controls present, correct records per page)
    - Test duplicate name validation: Arrange (company with existing "Default
    Invoice Group"), Act (attempt to create duplicate), Assert (validation error,
    database unchanged)
    - Test deletion of referenced numbering: Arrange (company + invoice group +
    invoice using it), Act (attempt delete), Assert (cascade or restrict based on FK
    constraint)
    - Test non-admin access: Arrange (regular user without admin permissions), Act
    (attempt access), Assert (authorization exception)
    - Test complete filtering: Arrange (company with all numbering types), Act (load
    relation manager), Assert (only INVOICE types present)
    - Test type change removes from view: Arrange (company with invoice group
    visible), Act (edit type from INVOICE to QUOTE), Assert (record no longer
    visible after reload)
    - Test missing required fields: Arrange (company + incomplete form data), Act
    (attempt CreateAction), Assert (validation errors, database unchanged)
    
    Authorization tests with AAA structure:
    - Test super admin operations: Arrange (super admin + company with invoice
    groups), Act (perform create/edit/delete), Assert (all succeed, database
    reflects changes)
    - Test regular admin permissions: Arrange (regular admin + company), Act
    (attempt operations), Assert (succeed or fail based on permissions)
    - Test company panel user access: Arrange (company panel user), Act (attempt
    access to admin relation manager), Assert (access denied)
    - Test unauthorized company access: Arrange (two companies + user with access to
    only company A), Act (attempt to create for company B), Assert (authorization
    failure, database unchanged)
    

    🚀 Next Steps

    🤖 All AI agent prompts combined
    Task: 1
    
    Create a NumberingsRelationManager for the Company resource to manage invoice
    groups. This phase sets up the relation manager with filtering for INVOICE type
    numberings.
    
    Create NumberingsRelationManager class:
    - Extend Filament's RelationManager
    - Set relationship property to 'numberings'
    - Configure table columns for name, type, format, prefix, next_id
    - Add query modifier to filter where type = NumberingType::INVOICE
    - Add header action for creating new invoice groups using existing NumberingForm
    patterns
    - Add edit and delete table actions
    - Include authorization checks
    
    Register in CompanyResource:
    - Update getRelations() method to include NumberingsRelationManager::class
    - Set appropriate tab label with translation
    
    Verify Numbering model:
    - Check for company() belongsTo relationship
    - Add if missing: public function company(): BelongsTo returning
    belongsTo(Company::class)
    - Verify BelongsToCompany trait is applied
    ===============================================================================
    
    Task: 2
    
    Create comprehensive feature tests for the NumberingsRelationManager following
    strict AAA pattern with explicit section separators. This phase ensures the
    relation manager works correctly with proper access control.
    
    Create CompanyNumberingRelationManagerTest extending AbstractAdminPanelTestCase:
    - Use explicit /* arrange */, /* act */, /* assert */ section comments in every
    test
    - Follow the pattern from Modules/Quotes/Tests/Feature/QuotesTest.php
    
    CRUD operation tests with AAA structure:
    - Test viewing relation manager: Arrange (create admin + company with 2-3
    invoice groups), Act (navigate to company edit page and render tab), Assert
    (verify table renders with correct data)
    - Test INVOICE type filtering: Arrange (create company with 2 INVOICE, 1 QUOTE,
    1 EXPENSE numberings), Act (load relation manager), Assert (only 2 INVOICE types
    visible)
    - Test creating invoice group: Arrange (create admin + company + form data), Act
    (call CreateAction), Assert (database has new record with correct company_id and
    type=INVOICE)
    - Test editing invoice group: Arrange (create company with invoice group +
    updated data), Act (call EditAction), Assert (database updated, company_id
    unchanged)
    - Test deleting invoice group: Arrange (create company with invoice group), Act
    (call DeleteAction), Assert (record no longer in database)
    - Test automatic company_id assignment: Arrange (create two companies + admin),
    Act (create invoice group for company A), Assert (numbering has company_id of
    company A)
    
    Edge case tests with AAA structure:
    - Test empty state: Arrange (company with no numberings), Act (load relation
    manager), Assert (empty state displayed)
    - Test pagination: Arrange (company with 25+ invoice groups), Act (load and
    navigate pages), Assert (pagination controls present, correct records per page)
    - Test duplicate name validation: Arrange (company with existing "Default
    Invoice Group"), Act (attempt to create duplicate), Assert (validation error,
    database unchanged)
    - Test deletion of referenced numbering: Arrange (company + invoice group +
    invoice using it), Act (attempt delete), Assert (cascade or restrict based on FK
    constraint)
    - Test non-admin access: Arrange (regular user without admin permissions), Act
    (attempt access), Assert (authorization exception)
    - Test complete filtering: Arrange (company with all numbering types), Act (load
    relation manager), Assert (only INVOICE types present)
    - Test type change removes from view: Arrange (company with invoice group
    visible), Act (edit type from INVOICE to QUOTE), Assert (record no longer
    visible after reload)
    - Test missing required fields: Arrange (company + incomplete form data), Act
    (attempt CreateAction), Assert (validation errors, database unchanged)
    
    Authorization tests with AAA structure:
    - Test super admin operations: Arrange (super admin + company with invoice
    groups), Act (perform create/edit/delete), Assert (all succeed, database
    reflects changes)
    - Test regular admin permissions: Arrange (regular admin + company), Act
    (attempt operations), Assert (succeed or fail based on permissions)
    - Test company panel user access: Arrange (company panel user), Act (attempt
    access to admin relation manager), Assert (access denied)
    - Test unauthorized company access: Arrange (two companies + user with access to
    only company A), Act (attempt to create for company B), Assert (authorization
    failure, database unchanged)
    
    💡 Iterate on the plan with: @coderabbitai <feedback>
    Example Feedback
    - @coderabbitai You can skip phase 3. Add a simple unit test case for phase 2.
    - @coderabbitai For assumption 1 go ahead with option 3 and replan.
    

    💬 Have feedback or questions? Drop into our discord!

  3. coderabbitai commented on Jan 2, 2026

    @coderabbitai
    Contributor

    I've updated the plan above based on your feedback. Ready to proceed when you are!

  4. coderabbitai commented on Jan 3, 2026

    @coderabbitai
    Contributor
    🧩 Analysis chain

    @nielsdrost7, I'll create a PR with the PHPUnit tests following the AAA pattern. Let me first examine the existing test structure in your codebase to ensure consistency, then generate the test code.


    🏁 Script executed:

    #!/bin/bash
    # Find and examine the existing test pattern mentioned in the plan
    fd -e php QuotesTest.php --exec cat {}
    

    Length of output: 32057


    🏁 Script executed:

    #!/bin/bash
    # Find AbstractAdminPanelTestCase to understand the base test class
    fd -e php AbstractAdminPanelTestCase --exec cat {}
    

    Length of output: 1002


    🏁 Script executed:

    #!/bin/bash
    # Check the Numbering model and factory for proper test data creation
    fd -e php "Numbering.php" Modules/Core/Models --exec cat {}
    

    Length of output: 6621


    🏁 Script executed:

    #!/bin/bash
    # Look for existing test factories
    fd -e php NumberingFactory --exec cat {}
    

    Length of output: 1033


    🏁 Script executed:

    #!/bin/bash
    # Check Company model for the numberings relationship
    fd -e php "Company.php" Modules/Core/Models --exec cat {}
    

    Length of output: 9089


    Perfect! I've examined your existing test patterns. Now I'll create a pull request with the PHPUnit tests following your AAA structure and coding standards.

    Task: Create PHPUnit tests for NumberingsRelationManager with AAA pattern

    • Generate comprehensive test file following the exact patterns from QuotesTest.php
    • Include explicit /* arrange */, /* act */, /* assert */ section comments in every test
    • Cover CRUD operations, edge cases, and authorization scenarios
    • Use #[Test] and #[Group()] attributes consistently

    🧠 Learnings used
    Learnt from: CR
    Repo: InvoicePlane/InvoicePlane-v2 PR: 0
    File: .github/copilot-instructions.md:0-0
    Timestamp: 2025-12-30T10:55:34.915Z
    Learning: Applies to **/Tests/**/*.php : Tests must be meaningful - validate actual behavior and data, not simple "ok" checks
    

    Learnt from: CR
    Repo: InvoicePlane/InvoicePlane-v2 PR: 0
    File: .github/copilot-instructions.md:0-0
    Timestamp: 2025-12-30T10:55:34.915Z
    Learning: Applies to **/Tests/**/*.php : Prefer Fakes and Fixtures over Mocks in unit tests
    

    Learnt from: CR
    Repo: InvoicePlane/InvoicePlane-v2 PR: 0
    File: .github/copilot-instructions.md:0-0
    Timestamp: 2025-12-30T10:55:34.915Z
    Learning: Applies to **/Tests/**/*.php : Use data providers for testing multiple scenarios with the same logic
    

    Learnt from: CR
    Repo: InvoicePlane/InvoicePlane-v2 PR: 0
    File: .github/copilot-instructions.md:0-0
    Timestamp: 2025-12-30T10:55:34.915Z
    Learning: Applies to **/Tests/**/*.php : Place happy paths last in test cases
    

    Learnt from: CR
    Repo: InvoicePlane/InvoicePlane-v2 PR: 0
    File: .github/copilot-instructions.md:0-0
    Timestamp: 2025-12-30T10:55:34.915Z
    Learning: Applies to **/Tests/**/*.php : Tests must include inline comment blocks for sections (/* Arrange */, /* Act */, /* Assert */)
    

    Learnt from: CR
    Repo: InvoicePlane/InvoicePlane-v2 PR: 0
    File: .github/copilot-instructions.md:0-0
    Timestamp: 2025-12-30T10:55:34.915Z
    Learning: Applies to **/Tests/**/*.php : Test functions must be prefixed with `it_` and make grammatical sense (e.g., `it_creates_payment`, `it_validates_invoice_has_customer`)
    

    Learnt from: CR
    Repo: InvoicePlane/InvoicePlane-v2 PR: 0
    File: .github/copilot-instructions.md:0-0
    Timestamp: 2025-12-30T10:55:34.915Z
    Learning: Applies to **/Tests/**/*.php : Reusable test logic (fixtures, setup) must live in abstract test cases, not inline
    

    Learnt from: CR
    Repo: InvoicePlane/InvoicePlane-v2 PR: 0
    File: .github/copilot-instructions.md:0-0
    Timestamp: 2025-12-30T10:55:34.915Z
    Learning: Applies to **/Tests/**/*.php : Use `#[Test]` attribute instead of `test` annotations in unit tests
    

    ⏳ Preparing changes...

  5. nielsdrost7 commented on Jan 3, 2026

    @nielsdrost7
    CollaboratorAuthor

    @coderabbitai show me the PR

  6. coderabbitai commented on Jan 3, 2026

    @coderabbitai
    Contributor

    @nielsdrost7, I'll create the pull request now with both the NumberingsRelationManager and the comprehensive PHPUnit tests following the AAA pattern.

    Task: Create NumberingsRelationManager with comprehensive AAA tests

    • Implement the relation manager for managing invoice groups from the Company resource
    • Create comprehensive test file with explicit AAA section comments
    • Follow all established coding patterns and test standards

    🧠 Learnings used
    Learnt from: CR
    Repo: InvoicePlane/InvoicePlane-v2 PR: 0
    File: .github/copilot-instructions.md:0-0
    Timestamp: 2025-12-30T10:55:34.915Z
    Learning: Applies to **/Tests/**/*.php : Tests must include inline comment blocks for sections (/* Arrange */, /* Act */, /* Assert */)
    

    Learnt from: CR
    Repo: InvoicePlane/InvoicePlane-v2 PR: 0
    File: .github/copilot-instructions.md:0-0
    Timestamp: 2025-12-30T10:55:34.915Z
    Learning: Applies to **/Tests/**/*.php : Tests must be meaningful - validate actual behavior and data, not simple "ok" checks
    

    Learnt from: CR
    Repo: InvoicePlane/InvoicePlane-v2 PR: 0
    File: .github/copilot-instructions.md:0-0
    Timestamp: 2025-12-30T10:55:34.915Z
    Learning: Applies to **/Tests/**/*.php : Test functions must be prefixed with `it_` and make grammatical sense (e.g., `it_creates_payment`, `it_validates_invoice_has_customer`)
    

    ⏳ Preparing changes...

  7. nielsdrost7 commented on Jan 3, 2026

    @nielsdrost7
    CollaboratorAuthor

    @coderabbitai show me the PR

  8. coderabbitai commented on Jan 3, 2026

    @coderabbitai
    Contributor

    @nielsdrost7, I'll create the pull request for you now. Another agent will implement the changes based on the requirements below.

    Implementation Plan: NumberingsRelationManager with AAA Tests

    Summary: Create a RelationManager for managing invoice groups from the Company admin resource, along with comprehensive PHPUnit tests following strict AAA pattern.

    Files to create/modify:

    • Create: Modules/Core/Filament/Admin/Resources/Companies/RelationManagers/NumberingsRelationManager.php
    • Modify: Modules/Core/Filament/Admin/Resources/Companies/CompanyResource.php
    • Create: Modules/Core/Tests/Feature/CompanyNumberingRelationManagerTest.php

    The agent will now create a pull request with these changes. The PR will include the RelationManager implementation and all 17 comprehensive tests following your AAA pattern requirements.


    ⏳ Preparing changes...

  9. nielsdrost7 commented on Jan 4, 2026

    @nielsdrost7
    CollaboratorAuthor

    @coderabbitai

    The agent will now create a pull request with these changes. The PR will include the RelationManager implementation and all 17 comprehensive tests following your AAA pattern requirements.

    The pull-request didn't get created yet. Please make it happen

  10. coderabbitai commented on Jan 4, 2026

    @coderabbitai
    Contributor

    I've updated the plan above based on your feedback. Ready to proceed when you are!

  11. changed the title [-]As an Admin, in the company Panel I want to be able to assign Invoice Groups to that single company[/-] [+][Settings]: Company panel — assign Invoice Groups[/+] on Jun 13, 2026
  12. nielsdrost7 commented on Jul 24, 2026

    @nielsdrost7
    CollaboratorAuthor

    SMART Plan — Company panel — assign Invoice Groups (Numbering)

    Specific

    Within the Company panel Settings page, add a Select field to choose the default Invoice Group (Numbering series) for the company. This selects from the company's assigned Numbering records, or all Numbering records if not yet scoped per-company.

    Measurable

    • Numbering/Invoice Groups appear in a dropdown.
    • Selection stored on companies.default_numbering_id or a settings row.
    • When creating invoices, the default numbering is pre-selected.
    • Success message confirms the default assignment.

    Achievable

    1. Add default_numbering_id column to companies table, or store the value in settings table scoped to the company.
    2. Create a Select field in CompanySettings pointing to Modules\Core\Models\Numbering.
    3. Update InvoiceService/InvoiceObserver to use $company->default_numbering_id when creating.

    Relevant

    Multi-invoice-series companies need different numbering prefixes per division. A per-company default eliminates manual selection on every new invoice.

    Time-bound

    Sprint 6.

  13. nielsdrost7 commented on Jul 24, 2026

    @nielsdrost7
    CollaboratorAuthor

    Already satisfied — CompanySettings.php's Invoices tab has Select::make(Setting::KEY_INVOICE_NUMBERING_ID) with options scoped to Numbering::query()->where('company_id', $this->getCompanyId()), persisted via Setting::saveForCompany(). Added a targeted test proving both the scoping (a company never sees another company's numbering) and persistence: CompanySettingsTest::it_offers_and_persists_the_default_invoice_numbering_scoped_to_the_company on feature/235-243-company-settings-cluster.

  14. added a commit that references this issue on Aug 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    refinedRefined with SMART plan / test suggestions

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions