# easy-invoice/2.4.1/includes/Forms/Invoice/InvoiceFieldRegistration.php

Easy Invoice – Invoice Generator, PDF Quotes &amp; Payments, version 2.4.1. 760 lines.

- Page: https://pluginprobe.com/plugins/easy-invoice/2.4.1/code/includes/Forms/Invoice/InvoiceFieldRegistration.php
- Raw: https://pluginprobe.com/plugins/easy-invoice/2.4.1/raw/includes/Forms/Invoice/InvoiceFieldRegistration.php
- Modified: 2026-09-15T12:31:20+00:00

Line numbers below start at 1. Link to a line or a range by appending a fragment to the
page URL, for example `https://pluginprobe.com/plugins/easy-invoice/2.4.1/code/includes/Forms/Invoice/InvoiceFieldRegistration.php#L10-L20`.

```php
<?php
/**
 * Invoice Field Registration Class
 *
 * @package     EasyInvoice
 * @author      Your Name
 * @copyright   Copyright (c) 2023, Your Company
 * @license     http://opensource.org/licenses/gpl-2.0.php GNU Public License
 * @since       1.0.0
 */

namespace EasyInvoice\Forms\Invoice;

use EasyInvoice\Forms\BaseFieldRegistration;

/**
 * Invoice Field Registration
 *
 * Handles registration of invoice-specific form fields, tabs, and templates.
 *
 * @since 1.0.0
 */
class InvoiceFieldRegistration extends BaseFieldRegistration {
    
    /**
     * Register default tabs
     *
     * @since 1.0.0
     * @return void
     */
    public function registerDefaultTabs(): void {
        // Define all tabs in a single array for easy modification by pro plugins
        $all_tabs = $this->getDefaultTabsArray();
        
        // Apply filter to allow pro plugins to modify tabs
        $all_tabs = apply_filters('easy_invoice_invoice_form_tabs', $all_tabs);
        
        // Register all tabs from the array
        foreach ($all_tabs as $tab_id => $tab_config) {
            $this->registerTab($tab_id, $tab_config);
        }
    }

    /**
     * Get default tabs array
     *
     * @since 1.0.0
     * @return array
     */
    private function getDefaultTabsArray(): array {
        return [
            'invoice-tab' => [
                'label' => __('Invoice Details', 'easy-invoice'),
                'icon' => 'fas fa-file-invoice',
                'active' => true,
                'order' => 1
            ],
            'items-tab' => [
                'label' => __('Items', 'easy-invoice'),
                'icon' => 'fas fa-list',
                'active' => false,
                'order' => 2
            ],
            'client-tab' => [
                'label' => __('Client', 'easy-invoice'),
                'icon' => 'fas fa-user',
                'active' => false,
                'order' => 3
            ],
            'discounts-taxes-tab' => [
                'label' => __('Discounts & Taxes', 'easy-invoice'),
                'icon' => 'fas fa-percentage',
                'active' => false,
                'order' => 4
            ],
            'payments-tab' => [
                'label' => __('Payment', 'easy-invoice'),
                'icon' => 'fas fa-credit-card',
                'active' => false,
                'order' => 5
            ]
        ];
    }

    /**
     * Register default fields
     *
     * @since 1.0.0
     * @return void
     */
    public function registerDefaultFields(): void {
        // Define all fields in a single array for easy modification by pro plugins
        $all_fields = $this->getDefaultFieldsArray();

        // Gate the basic tax fields on the global Settings → Tax →
        // Enable Tax setting. When tax is globally off, the entire
        // tax block (override checkbox, tax rate, prices include tax)
        // is hidden from the invoice builder — the merchant has to
        // turn tax on globally before any tax controls surface here.
        // discount_calculation_method stays (it lives in the discount
        // section, controls discount timing, not tax).
        if (get_option('easy_invoice_tax_enabled', 'no') !== 'yes') {
            $tax_field_names = ['tax_enabled', 'tax_rate', 'prices_include_tax'];
            $all_fields = array_values(array_filter(
                $all_fields,
                static fn($f) => !in_array($f['name'] ?? '', $tax_field_names, true)
            ));
        }

        // Apply filter to allow pro plugins to modify fields
        $all_fields = apply_filters('easy_invoice_invoice_fields', $all_fields);

        // Register all fields from the array
        foreach ($all_fields as $field_config) {
            $this->registerField($field_config['tab_id'], $field_config);
        }
    }

    /**
     * Get default fields array
     *
     * @since 1.0.0
     * @return array
     */
    private function getDefaultFieldsArray(): array {
        return [
            // Invoice Tab Fields
            [
                'tab_id' => 'invoice-tab',
                'name' => 'invoice_template',
                'type' => 'hidden',
                'label' => __('Invoice Template', 'easy-invoice'),
                'required' => false,
                'grid_cols' => 'sm:col-span-6',
                'order' => 0,
                'default_value' => 'standard',
                'sanitize_callback' => 'sanitize_text_field',
                'validate_callback' => function($value) {
                    return !empty(trim($value)) ? true : __('Invoice template is required.', 'easy-invoice');
                }
            ],
            [
                'tab_id' => 'invoice-tab',
                'name' => 'title',
                'type' => 'text',
                'label' => __('Invoice Title', 'easy-invoice'),
                'placeholder' => __('Enter invoice title', 'easy-invoice'),
                'required' => true,
                'grid_cols' => 'sm:col-span-6',
                'order' => 1,
                'sanitize_callback' => 'sanitize_text_field',
                'validate_callback' => function($value) {
                    return !empty(trim($value)) ? true : __('Invoice title is required.', 'easy-invoice');
                }
            ],
            [
                'tab_id' => 'invoice-tab',
                'name' => 'description',
                'type' => 'textarea',
                'label' => __('Invoice Description', 'easy-invoice'),
                'placeholder' => __('Enter invoice description or additional details', 'easy-invoice'),
                'required' => false,
                'grid_cols' => 'sm:col-span-6',
                'rows' => 3,
                'order' => 2,
                'description' => __('Optional description or additional details about this invoice.', 'easy-invoice'),
                'sanitize_callback' => 'sanitize_textarea_field',
            ],
            [
                'tab_id' => 'invoice-tab',
                'name' => 'number',
                'type' => 'text',
                'label' => __('Invoice Number', 'easy-invoice'),
                'placeholder' => __('INV-001', 'easy-invoice'),
                'required' => true,
                'readonly' => true,
                'description' => __('This is the unique number for your invoice. It cannot be changed.', 'easy-invoice'),
                'grid_cols' => 'sm:col-span-3',
                'order' => 3,
                'default_value' => function() {
                    // For new invoices, show the next number without incrementing
                    // For existing invoices, this will be overridden by the invoice object's getNumber() method
                    if (class_exists('\\EasyInvoice\\Services\\InvoiceNumberService')) {
                        $service = new \EasyInvoice\Services\InvoiceNumberService();
                        return $service->getNextNumber();
                    }
                    return 'INV-' . str_pad(time(), 6, '0', STR_PAD_LEFT);
                },
                'sanitize_callback' => 'sanitize_text_field',
                'validate_callback' => function($value) {
                    return !empty(trim($value)) ? true : __('Invoice number is required.', 'easy-invoice');
                }
            ],
            [
                'tab_id' => 'invoice-tab',
                'name' => 'issue_date',
                'type' => 'date',
                'label' => __('Issue Date', 'easy-invoice'),
                'required' => true,
                'grid_cols' => 'sm:col-span-3',
                'order' => 4,
                // Both date fields are `required` but shipped with no default, so a
                // brand-new invoice always failed its first save with "Issue Date is
                // required / Due Date is required" — while the live preview beside the
                // form was already showing dates, which made the error look wrong.
                // The quote form has always defaulted its date this way.
                //
                // current_time() rather than gmdate(): gmdate() uses the server timezone,
                // so a site ahead of or behind UTC could get yesterday's or tomorrow's
                // date on a new invoice.
                'default_value' => current_time('Y-m-d'),
                'sanitize_callback' => 'sanitize_text_field',
                'validate_callback' => function($value) {
                    return !empty($value) && strtotime($value) ? true : __('Please enter a valid issue date.', 'easy-invoice');
                }
            ],
            [
                'tab_id' => 'invoice-tab',
                'name' => 'due_date',
                'type' => 'date',
                'label' => __('Due Date', 'easy-invoice'),
                'required' => true,
                'grid_cols' => 'sm:col-span-3',
                'order' => 5,
                // Defaults to issue date + the configured payment term
                // (Settings → Invoice → "Due days", default 30) rather than a
                // hardcoded value, so the prefilled date matches the terms the site
                // actually bills on. See the note on issue_date above.
                'default_value' => gmdate('Y-m-d', strtotime(
                    '+' . max(0, (int) get_option('easy_invoice_invoice_due_days', 30)) . ' days',
                    strtotime(current_time('Y-m-d'))
                )),
                'sanitize_callback' => 'sanitize_text_field',
                'validate_callback' => function($value) {
                    return !empty($value) && strtotime($value) ? true : __('Please enter a valid due date.', 'easy-invoice');
                }
            ],
            [
                'tab_id' => 'invoice-tab',
                'name' => 'status',
                'type' => 'select',
                'label' => __('Status', 'easy-invoice'),
                'required' => true,
                'grid_cols' => 'sm:col-span-3',
                'options' => [
                    'available' => __('Available', 'easy-invoice'),
                    'draft' => __('Draft', 'easy-invoice'),
                    'overdue' => __('Overdue', 'easy-invoice'),
                    'paid' => __('Paid', 'easy-invoice'),
                    'unpaid' => __('Unpaid', 'easy-invoice'),
                    'cancelled' => __('Cancelled', 'easy-invoice')
                ],
                'order' => 6
            ],
            // Customer tax identity. FormProcessor stores a field as
            // '_easy_invoice_' . $name, so these land on the meta keys
            // Services\TaxTreatment reads when deciding whether an invoice is a
            // cross-border reverse charge or an export.
            [
                'tab_id' => 'invoice-tab',
                'name' => 'customer_vat_number',
                'type' => 'text',
                'label' => __('Customer VAT number', 'easy-invoice'),
                'placeholder' => __('e.g. FR12345678901', 'easy-invoice'),
                'grid_cols' => 'sm:col-span-3',
                'section' => 'notes',
                'order' => 4,
                'description' => __('Needed to invoice a VAT-registered business in another country without charging VAT.', 'easy-invoice'),
            ],
            [
                'tab_id' => 'invoice-tab',
                'name' => 'customer_country',
                'type' => 'text',
                'label' => __('Customer country', 'easy-invoice'),
                'placeholder' => __('e.g. FR', 'easy-invoice'),
                'grid_cols' => 'sm:col-span-3',
                'section' => 'notes',
                'order' => 5,
                'description' => __('Two-letter country code.', 'easy-invoice'),
            ],
            [
                'tab_id' => 'invoice-tab',
                'name' => 'notes',
                'type' => 'textarea',
                'label' => __('Notes', 'easy-invoice'),
                'placeholder' => __('Additional notes for the client', 'easy-invoice'),
                'grid_cols' => 'sm:col-span-6',
                'rows' => 3,
                'section' => 'notes',
                'order' => 6,
                'description' => __('These notes will be visible to your client on the invoice.', 'easy-invoice'),
            ],
            [
                'tab_id' => 'invoice-tab',
                'name' => 'internal_notes',
                'type' => 'textarea',
                'label' => __('Internal Notes', 'easy-invoice'),
                'placeholder' => __('Internal notes (not visible to client)', 'easy-invoice'),
                'grid_cols' => 'sm:col-span-6',
                'rows' => 3,
                'section' => 'notes',
                'order' => 7,
                'description' => __('Only you and your team can see these notes. Clients will not see them.', 'easy-invoice'),
            ],
            [
                'tab_id' => 'invoice-tab',
                'name' => 'terms',
                'type' => 'textarea',
                'label' => __('Payment Terms', 'easy-invoice'),
                'placeholder' => __('Payment terms and conditions', 'easy-invoice'),
                'grid_cols' => 'sm:col-span-6',
                'rows' => 3,
                'section' => 'notes',
                'order' => 8,
                'default_value' => function() {
                    return \EasyInvoice\Controllers\SettingsController::getInvoiceTermsConditions();
                },
                'description' => __('Specify the payment terms and conditions for this invoice.', 'easy-invoice'),
            ],


            // Client Tab Fields
            [
                'tab_id' => 'client-tab',
                'name' => 'client_id',
                'type' => 'select',
                'label' => __('Select Client', 'easy-invoice'),
                'required' => false,
                'grid_cols' => 'sm:col-span-6',
                'options' => $this->getClientOptions(),
                'order' => 1,
                'description' => __('Choose an existing client or add a new one.', 'easy-invoice'),
            ],

            // Discounts & Taxes Tab Fields
            [
                'tab_id' => 'discounts-taxes-tab',
                'name' => 'discount_type',
                'type' => 'select',
                'label' => __('Discount Type', 'easy-invoice'),
                'grid_cols' => 'sm:col-span-2',
                'section' => 'discount',
                'options' => [
                    'none' => __('No Discount', 'easy-invoice'),
                    'percentage' => __('Percentage', 'easy-invoice'),
                    'fixed' => __('Fixed Amount', 'easy-invoice')
                ],
                'order' => 1,
                'description' => __('Choose how the discount should be applied to this invoice.', 'easy-invoice'),
            ],
            [
                'tab_id' => 'discounts-taxes-tab',
                'name' => 'discount_value',
                'type' => 'number',
                'label' => __('Discount Value', 'easy-invoice'),
                'placeholder' => '0.00',
                'grid_cols' => 'sm:col-span-2',
                'section' => 'discount',
                'min' => '0',
                'step' => '0.01',
                'order' => 2,
                'sanitize_callback' => 'floatval',
                'validate_callback' => function($value) {
                    return is_numeric($value) && $value >= 0 ? true : __('Discount value must be a non-negative number.', 'easy-invoice');
                },
                'description' => __('Enter the discount amount or percentage for this invoice.', 'easy-invoice'),
            ],
            [
                // Per-invoice "Enable Tax" override.
                //
                // Defaults to the global Settings → Tax → Enable Tax
                // checkbox value. The user can flip it for a specific
                // invoice — handy for tax-exempt customers (override
                // "on" globally → "off" here) or one-off taxable
                // invoices when tax is globally off.
                //
                // calculateTotals() in the Invoice model treats the
                // tax_rate as 0 when this is unchecked, regardless of
                // what value sits in the tax_rate field — so the rest
                // of this section can stay visible without applying
                // tax until the user opts in.
                'tab_id' => 'discounts-taxes-tab',
                'name' => 'tax_enabled',
                'type' => 'checkbox',
                'label' => __('Apply Tax to This Invoice', 'easy-invoice'),
                'grid_cols' => 'sm:col-span-6',
                'section' => 'tax',
                'order' => 2.5,
                'default_value' => function() {
                    // Default to global setting. Saved values override.
                    return get_option('easy_invoice_tax_enabled', 'no') === 'yes' ? 'yes' : 'no';
                },
                'sanitize_callback' => function($value) {
                    // Coerce any truthy input ('yes', '1', 1, true, 'on')
                    // to 'yes'; anything else to 'no'. Stored as a
                    // string so the field-save loop persists '' as 'no'
                    // (PHP checkbox unchecked = field absent from POST).
                    if ($value === 'yes' || $value === '1' || $value === 1 || $value === true || $value === 'on') return 'yes';
                    return 'no';
                },
                'description' => __('Override the global tax setting for this invoice. Defaults to whatever is configured in Settings → Tax.', 'easy-invoice'),
            ],
            // Discount calculation timing — belongs in the discount
            // section (it controls when the discount applies relative
            // to tax, not how tax is calculated). Pinned next to the
            // Discount Type / Value fields above so the grouping is
            // intuitive.
            [
                'tab_id' => 'discounts-taxes-tab',
                'name' => 'discount_calculation_method',
                'type' => 'select',
                'label' => __('Discount Timing', 'easy-invoice'),
                'grid_cols' => 'sm:col-span-2',
                'section' => 'discount',
                'options' => [
                    'before_tax' => __('Before Tax', 'easy-invoice'),
                    'after_tax' => __('After Tax', 'easy-invoice')
                ],
                'order' => 3,
                'description' => __('Apply discount before tax (reduces taxable amount) or after tax (tax on full amount)', 'easy-invoice'),
            ],

            // Tax sub-fields below sit on one row (2 + 2 + 2 = 6 cols)
            // so the user sees Tax Rate and Price Includes Tax
            // side-by-side under the Apply Tax checkbox.
            [
                'tab_id' => 'discounts-taxes-tab',
                'name' => 'tax_rate',
                'type' => 'number',
                'label' => __('Tax Rate (%)', 'easy-invoice'),
                'placeholder' => '0.00',
                'grid_cols' => 'sm:col-span-3',
                'section' => 'tax',
                'min' => '0',
                'max' => '100',
                'step' => '0.01',
                'order' => 4,
                'default_value' => function() {
                    return easy_invoice_get_tax_rate();
                },
                'sanitize_callback' => 'floatval',
                'validate_callback' => function($value) {
                    return is_numeric($value) && $value >= 0 && $value <= 100 ? true : __('Tax rate must be between 0 and 100.', 'easy-invoice');
                },
                'description' => __('The tax rate that will be applied to taxable items in this invoice.', 'easy-invoice'),
            ],

            [
                'tab_id' => 'discounts-taxes-tab',
                'name' => 'prices_include_tax',
                'type' => 'select',
                'label' => __('Price Includes Tax', 'easy-invoice'),
                'grid_cols' => 'sm:col-span-3',
                'section' => 'tax',
                'options' => [
                    'no' => __('No', 'easy-invoice'),
                    'yes' => __('Yes', 'easy-invoice')
                ],
                'order' => 5,
                'description' => __('Choose whether the prices in this invoice include tax or not.', 'easy-invoice'),
            ],

            // Payments Tab Fields
            [
                'tab_id' => 'payments-tab',
                'name' => 'payment_gateways',
                'type' => 'payment_gateways',
                'label' => __('Payment Gateways', 'easy-invoice'),
                'grid_cols' => 'sm:col-span-12',
                'section' => 'payment',
                'order' => 1
            ],
            [
                'tab_id' => 'payments-tab',
                'name' => 'payment_gateways_toggle_state',
                'type' => 'hidden',
                'label' => __('Payment Gateways Toggle State', 'easy-invoice'),
                'default_value' => '0',
                'section' => 'payment',
                'order' => 2
            ],

            // Currency Section in Payment Tab
            [
                'tab_id' => 'payments-tab',
                'name' => 'currency_code',
                'type' => 'select',
                'label' => __('Currency', 'easy-invoice'),
                'grid_cols' => 'sm:col-span-3',
                'section' => 'currency',
                'options' => array_merge(
                    ['global' => __('Use from Global Settings', 'easy-invoice')],
                    \EasyInvoice\Helpers\CurrencyHelper::getCurrencyOptions()
                ),
                'default_value' => 'global',
                'order' => 2,
                'description' => __('Select the currency for this invoice or use global settings.', 'easy-invoice'),
            ],
            [
                'tab_id' => 'payments-tab',
                'name' => 'currency_position',
                'type' => 'select',
                'label' => __('Currency Symbol Position', 'easy-invoice'),
                'grid_cols' => 'sm:col-span-3',
                'section' => 'currency',
                'options' => [
                    'global' => __('Use from Global Settings', 'easy-invoice'),
                    'before' => __('Before Amount', 'easy-invoice'),
                    'after' => __('After Amount', 'easy-invoice'),
                ],
                'default_value' => 'global',
                'order' => 3,
                'description' => __('Choose where to display the currency symbol or use global setting.', 'easy-invoice'),
            ],
        ];
    }

    /**
     * Register default templates
     *
     * @since 1.0.0
     * @return void
     */
    public function registerDefaultTemplates(): void {
        // Define all templates in a single array for easy modification by pro plugins
        $all_templates = $this->getDefaultTemplatesArray();
        
        // Apply filter to allow pro plugins to modify templates
        $all_templates = apply_filters('easy_invoice_invoice_templates', $all_templates);
        
        // Register all templates from the array
        foreach ($all_templates as $template_id => $template_config) {
            $this->registerTemplate($template_id, $template_config);
        }
    }

    /**
     * Get default templates array
     *
     * @since 1.0.0
     * @return array
     */
    private function getDefaultTemplatesArray(): array {
        // Check if this is the free version (no pro plugin active)
        $is_free_version = !easy_invoice_has_pro();
        
        return [
            'standard' => [
                'name' => __('Standard', 'easy-invoice'),
                'icon' => 'fas fa-file-invoice',
                'description' => __('Clean and professional standard template', 'easy-invoice'),
                'order' => 1,
                'is_free' => true
            ],
            'legacy' => [
                'name' => __('Legacy', 'easy-invoice'),
                'icon' => 'fas fa-file-alt',
                'description' => __('Clean, minimalist design with traditional business layout', 'easy-invoice'),
                'order' => 2,
                'is_free' => true
            ],
            'professional' => [
                'name' => __('Professional', 'easy-invoice'),
                'icon' => 'fas fa-briefcase',
                'description' => __('Professional business template with modern design', 'easy-invoice'),
                'order' => 3,
                'is_free' => !$is_free_version
            ],
            'modern' => [
                'name' => __('Modern', 'easy-invoice'),
                'icon' => 'fas fa-rocket',
                'description' => __('Modern and sleek design template', 'easy-invoice'),
                'order' => 4,
                'is_free' => !$is_free_version
            ]
        ];
    }

    /**
     * Register default item fields
     *
     * @since 1.0.0
     * @return void
     */
    public function registerDefaultItemFields(): void {
        // Define all item fields in a single array for easy modification by pro plugins
        $all_item_fields = $this->getDefaultItemFieldsArray();
        
        // Apply filter to allow pro plugins to modify item fields
        $all_item_fields = apply_filters('easy_invoice_invoice_item_fields', $all_item_fields);
        
        // Register all item fields from the array
        foreach ($all_item_fields as $field_config) {
            $this->registerItemField($field_config);
        }
    }

    /**
     * Get default item fields array
     *
     * @since 1.0.0
     * @return array
     */
    private function getDefaultItemFieldsArray(): array {
        $fields = [
            [
                'name' => 'title',
                'type' => 'text',
                'label' => __('Item Title', 'easy-invoice'),
                'placeholder' => __('Enter item title', 'easy-invoice'),
                'required' => true,
                'container_class' => 'sm:col-span-6',
                'order' => 1,
                'description' => __('A short name for this item (e.g. Service Fee, Product Name).', 'easy-invoice'),
            ],
            [
                'name' => 'description',
                'type' => 'textarea',
                'label' => __('Description', 'easy-invoice'),
                'placeholder' => __('Enter item description', 'easy-invoice'),
                'container_class' => 'sm:col-span-6',
                'rows' => 3,
                'order' => 2,
                'description' => __('Details about this item for your client.', 'easy-invoice'),
            ],
            [
                'name' => 'quantity',
                'type' => 'number',
                'label' => __('Quantity', 'easy-invoice'),
                'placeholder' => '0',
                'required' => true,
                'container_class' => 'sm:col-span-1',
                'min' => '0',
                'step' => '0.01',
                'default_value' => '0',
                'order' => 3,
                'description' => __('How many units of this item are being billed?', 'easy-invoice'),
            ],
            [
                'name' => 'price',
                'type' => 'number',
                'label' => __('Price', 'easy-invoice'),
                'placeholder' => '0.00',
                'required' => true,
                'container_class' => 'sm:col-span-1',
                'min' => '0',
                'step' => '0.01',
                'default_value' => '0.00',
                'order' => 4,
                'description' => __('Unit price for this item.', 'easy-invoice'),
            ]
        ];

        // Add adjust field only if setting allows it
        if (\EasyInvoice\Controllers\SettingsController::shouldShowInvoiceAdjustField()) {
            $fields[] = [
                'name' => 'adjust_percentage',
                'type' => 'number',
                'label' => __('Adjust (%)', 'easy-invoice'),
                'placeholder' => '0.00',
                'container_class' => 'sm:col-span-1',
                'min' => '-100',
                'max' => '1000',
                'step' => '0.01',
                'default_value' => '0.00',
                'order' => 5,
                'description' => __('Percentage adjustment to apply to this item (positive for markup, negative for discount).', 'easy-invoice'),
            ];
        }

        // Add total field
        $fields[] = [
            'name' => 'total',
            'type' => 'number',
            'label' => __('Total', 'easy-invoice'),
            'placeholder' => '0.00',
            'container_class' => 'sm:col-span-1',
            'min' => '0',
            'step' => '0.01',
            'default_value' => '0.00',
            'readonly' => true,
            'order' => \EasyInvoice\Controllers\SettingsController::shouldShowInvoiceAdjustField() ? 6 : 5,
            'description' => __('Total amount for this item (Quantity x Price) with adjustment applied.', 'easy-invoice'),
        ];

        // Add taxable field
        $fields[] = [
            'name' => 'taxable',
            'type' => 'checkbox',
            'label' => __('Taxable', 'easy-invoice'),
            'container_class' => 'sm:col-span-6',
            'default_value' => '1',
            'order' => \EasyInvoice\Controllers\SettingsController::shouldShowInvoiceAdjustField() ? 7 : 6,
            'description' => __('Check if this item is subject to tax.', 'easy-invoice'),
        ];

        return $fields;
    }

    /**
     * Get client options for select field
     *
     * @since 1.0.0
     * @return array
     */
    private function getClientOptions(): array {
        $options = ['' => __('Select a client', 'easy-invoice')];
        
        // Get clients from repository
        $client_repository = new \EasyInvoice\Repositories\ClientRepository();
        $clients = $client_repository->all();
        
        foreach ($clients as $client) {
            $client_name = $client->getBusinessClientName() ?: ($client->getFirstName() . ' ' . $client->getLastName());
            $options[$client->getId()] = $client_name;
        }
        
        return $options;
    }

    /**
     * Get the filter name for tabs
     *
     * @since 1.0.0
     * @return string
     */
    protected function getTabFilterName(): string {
        return 'easy_invoice_invoice_register_tab';
    }

    /**
     * Get the filter name for fields
     *
     * @since 1.0.0
     * @return string
     */
    protected function getFieldFilterName(): string {
        return 'easy_invoice_invoice_register_field';
    }

    /**
     * Get the filter name for templates
     *
     * @since 1.0.0
     * @return string
     */
    protected function getTemplateFilterName(): string {
        return 'easy_invoice_invoice_register_template';
    }

    /**
     * Get the filter name for item fields
     *
     * @since 1.0.0
     * @return string
     */
    protected function getItemFieldFilterName(): string {
        return 'easy_invoice_invoice_register_item_field';
    }
} 
```
