mirror of
				https://github.com/invoiceninja/invoiceninja.git
				synced 2025-11-03 19:47:34 -05:00 
			
		
		
		
	
						commit
						b2e535b6cb
					
				@ -1 +1 @@
 | 
				
			|||||||
5.6.15
 | 
					5.6.16
 | 
				
			||||||
@ -79,6 +79,7 @@ class OpenApiYaml extends Command
 | 
				
			|||||||
        Storage::disk('base')->append('/openapi/api-docs.yaml', file_get_contents($path.'/components.yaml'));
 | 
					        Storage::disk('base')->append('/openapi/api-docs.yaml', file_get_contents($path.'/components.yaml'));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Storage::disk('base')->append('/openapi/api-docs.yaml', file_get_contents($path.'/components/responses.yaml'));
 | 
					        Storage::disk('base')->append('/openapi/api-docs.yaml', file_get_contents($path.'/components/responses.yaml'));
 | 
				
			||||||
 | 
					        Storage::disk('base')->append('/openapi/api-docs.yaml', file_get_contents($path.'/components/examples.yaml'));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $directory = new DirectoryIterator($path . '/components/responses/');
 | 
					        $directory = new DirectoryIterator($path . '/components/responses/');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -51,6 +51,7 @@ class TranslationsExport extends Command
 | 
				
			|||||||
        'fi',
 | 
					        'fi',
 | 
				
			||||||
        'fr',
 | 
					        'fr',
 | 
				
			||||||
        'fr_CA',
 | 
					        'fr_CA',
 | 
				
			||||||
 | 
					        'fr_CH',
 | 
				
			||||||
        'he',
 | 
					        'he',
 | 
				
			||||||
        'hr',
 | 
					        'hr',
 | 
				
			||||||
        'hu',
 | 
					        'hu',
 | 
				
			||||||
 | 
				
			|||||||
@ -223,9 +223,12 @@ class Rule extends BaseRule implements RuleInterface
 | 
				
			|||||||
    public function calculateRates(): self
 | 
					    public function calculateRates(): self
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        if ($this->client->is_tax_exempt) {
 | 
					        if ($this->client->is_tax_exempt) {
 | 
				
			||||||
            // nlog("tax exempt");
 | 
					         
 | 
				
			||||||
            $this->tax_rate = 0;
 | 
					            $this->tax_rate = 0;
 | 
				
			||||||
            $this->reduced_tax_rate = 0;
 | 
					            $this->reduced_tax_rate = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return $this;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        // } elseif($this->client_subregion != $this->client->company->tax_data->seller_subregion && in_array($this->client_subregion, $this->eu_country_codes) && $this->client->has_valid_vat_number && $this->eu_business_tax_exempt) {
 | 
					        // } elseif($this->client_subregion != $this->client->company->tax_data->seller_subregion && in_array($this->client_subregion, $this->eu_country_codes) && $this->client->has_valid_vat_number && $this->eu_business_tax_exempt) {
 | 
				
			||||||
        //     nlog("euro zone and tax exempt");
 | 
					        //     nlog("euro zone and tax exempt");
 | 
				
			||||||
        //     $this->tax_rate = 0;
 | 
					        //     $this->tax_rate = 0;
 | 
				
			||||||
@ -246,10 +249,9 @@ class Rule extends BaseRule implements RuleInterface
 | 
				
			|||||||
        //         $this->tax_rate = $this->client->company->tax_data->regions->EU->subregions->{$this->client->company->country()->iso_3166_2}->tax_rate;
 | 
					        //         $this->tax_rate = $this->client->company->tax_data->regions->EU->subregions->{$this->client->company->country()->iso_3166_2}->tax_rate;
 | 
				
			||||||
        //         $this->reduced_tax_rate = $this->client->company->tax_data->regions->EU->subregions->{$this->client->company->country()->iso_3166_2}->reduced_tax_rate;
 | 
					        //         $this->reduced_tax_rate = $this->client->company->tax_data->regions->EU->subregions->{$this->client->company->country()->iso_3166_2}->reduced_tax_rate;
 | 
				
			||||||
        //     }
 | 
					        //     }
 | 
				
			||||||
        } else {
 | 
					
 | 
				
			||||||
        $this->tax_rate = $this->client->company->tax_data->regions->AU->subregions->{$this->client->company->country()->iso_3166_2}->tax_rate;
 | 
					        $this->tax_rate = $this->client->company->tax_data->regions->AU->subregions->{$this->client->company->country()->iso_3166_2}->tax_rate;
 | 
				
			||||||
        $this->reduced_tax_rate = $this->client->company->tax_data->regions->AU->subregions->{$this->client->company->country()->iso_3166_2}->reduced_tax_rate;
 | 
					        $this->reduced_tax_rate = $this->client->company->tax_data->regions->AU->subregions->{$this->client->company->country()->iso_3166_2}->reduced_tax_rate;
 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return $this;
 | 
					        return $this;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -37,9 +37,9 @@ class TokenFilters extends QueryFilters
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function is_system(bool $value = false): Builder
 | 
					    public function is_system(string $value = 'false'): Builder
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        return $this->builder->where('is_system', $value);
 | 
					        return $this->builder->where('is_system', $value == 'false' ? false : true);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
 | 
				
			|||||||
@ -25,6 +25,8 @@ class PdfSlot extends Component
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    public $pdf;
 | 
					    public $pdf;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public $url;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
    public function mount()
 | 
					    public function mount()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        MultiDB::setDb($this->db);
 | 
					        MultiDB::setDb($this->db);
 | 
				
			||||||
 | 
				
			|||||||
@ -42,6 +42,8 @@ trait MakesInvoiceHtml
 | 
				
			|||||||
    {
 | 
					    {
 | 
				
			||||||
        $data['__env'] = app(Factory::class);
 | 
					        $data['__env'] = app(Factory::class);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return Blade::render($string, $data); //potential fix for removing eval()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $php = Blade::compileString($string);
 | 
					        $php = Blade::compileString($string);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $obLevel = ob_get_level();
 | 
					        $obLevel = ob_get_level();
 | 
				
			||||||
 | 
				
			|||||||
@ -106,7 +106,6 @@
 | 
				
			|||||||
        "filp/whoops": "^2.7",
 | 
					        "filp/whoops": "^2.7",
 | 
				
			||||||
        "friendsofphp/php-cs-fixer": "^3.14",
 | 
					        "friendsofphp/php-cs-fixer": "^3.14",
 | 
				
			||||||
        "laracasts/cypress": "^3.0",
 | 
					        "laracasts/cypress": "^3.0",
 | 
				
			||||||
        "laravel/dusk": "^6.15",
 | 
					 | 
				
			||||||
        "mockery/mockery": "^1.4.4",
 | 
					        "mockery/mockery": "^1.4.4",
 | 
				
			||||||
        "nunomaduro/collision": "^6.1",
 | 
					        "nunomaduro/collision": "^6.1",
 | 
				
			||||||
        "nunomaduro/larastan": "^2.0",
 | 
					        "nunomaduro/larastan": "^2.0",
 | 
				
			||||||
 | 
				
			|||||||
@ -15,8 +15,8 @@ return [
 | 
				
			|||||||
    'require_https' => env('REQUIRE_HTTPS', true),
 | 
					    'require_https' => env('REQUIRE_HTTPS', true),
 | 
				
			||||||
    'app_url' => rtrim(env('APP_URL', ''), '/'),
 | 
					    'app_url' => rtrim(env('APP_URL', ''), '/'),
 | 
				
			||||||
    'app_domain' => env('APP_DOMAIN', 'invoicing.co'),
 | 
					    'app_domain' => env('APP_DOMAIN', 'invoicing.co'),
 | 
				
			||||||
    'app_version' => '5.6.15',
 | 
					    'app_version' => env('APP_VERSION','5.6.16'),
 | 
				
			||||||
    'app_tag' => '5.6.15',
 | 
					    'app_tag' => env('APP_TAG','5.6.16'),
 | 
				
			||||||
    'minimum_client_version' => '5.0.16',
 | 
					    'minimum_client_version' => '5.0.16',
 | 
				
			||||||
    'terms_version' => '1.0.1',
 | 
					    'terms_version' => '1.0.1',
 | 
				
			||||||
    'api_secret' => env('API_SECRET', ''),
 | 
					    'api_secret' => env('API_SECRET', ''),
 | 
				
			||||||
 | 
				
			|||||||
@ -0,0 +1,37 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use App\Models\Language;
 | 
				
			||||||
 | 
					use Illuminate\Support\Facades\Schema;
 | 
				
			||||||
 | 
					use Illuminate\Database\Schema\Blueprint;
 | 
				
			||||||
 | 
					use Illuminate\Database\Migrations\Migration;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					return new class extends Migration
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Run the migrations.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return void
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function up()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					            Language::unguard();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $language = Language::find(40);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (! $language) {
 | 
				
			||||||
 | 
					                Language::create(['id' => 40, 'name' => 'French - Swiss', 'locale' => 'fr_CH']);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Reverse the migrations.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return void
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function down()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        //
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
@ -64,6 +64,7 @@ class LanguageSeeder extends Seeder
 | 
				
			|||||||
            ['id' => 37, 'name' => 'Hebrew', 'locale' => 'he'],
 | 
					            ['id' => 37, 'name' => 'Hebrew', 'locale' => 'he'],
 | 
				
			||||||
            ['id' => 38, 'name' => 'Khmer', 'locale' => 'km_KH'],
 | 
					            ['id' => 38, 'name' => 'Khmer', 'locale' => 'km_KH'],
 | 
				
			||||||
            ['id' => 39, 'name' => 'Hungarian', 'locale' => 'hu'],
 | 
					            ['id' => 39, 'name' => 'Hungarian', 'locale' => 'hu'],
 | 
				
			||||||
 | 
					            ['id' => 40, 'name' => 'French - Swiss', 'locale' => 'fr_CH'],
 | 
				
			||||||
        ];
 | 
					        ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        foreach ($languages as $language) {
 | 
					        foreach ($languages as $language) {
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										64
									
								
								dusk.sh
									
									
									
									
									
								
							
							
						
						
									
										64
									
								
								dusk.sh
									
									
									
									
									
								
							@ -1,64 +0,0 @@
 | 
				
			|||||||
#!/bin/bash
 | 
					 | 
				
			||||||
n=1
 | 
					 | 
				
			||||||
TYPE=${!n}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
if [ -z "$TYPE" ]; then
 | 
					 | 
				
			||||||
    TYPE="all"
 | 
					 | 
				
			||||||
fi
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
echo "$ RUNNING: '$TYPE'"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
echo "$ php artisan optimize"
 | 
					 | 
				
			||||||
php artisan optimize
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
echo "=========================================="
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
GENERIC_TESTS=`find tests/Browser/ClientPortal/ -maxdepth 1  -type f -name '*.php'`
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
if [ $TYPE == 'gateways' ]; then
 | 
					 | 
				
			||||||
    GENERIC_TESTS=""
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    echo "$ Skippping generic tests."
 | 
					 | 
				
			||||||
    echo "=========================================="
 | 
					 | 
				
			||||||
fi
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
for TEST_CLASS in $GENERIC_TESTS; do
 | 
					 | 
				
			||||||
    echo "Test class: $TEST_CLASS"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    echo "$ php artisan migrate:fresh --seed"
 | 
					 | 
				
			||||||
    php artisan migrate:fresh --seed &> /dev/null
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    echo "$ php artisan ninja:create-single-account"
 | 
					 | 
				
			||||||
    php artisan ninja:create-single-account &> /dev/null
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    echo "$ php artisan dusk $TEST_CLASS"
 | 
					 | 
				
			||||||
    php -d memory_limit=1G artisan dusk ${@:2} --stop-on-error --stop-on-failure $TEST_CLASS || exit 1
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    echo "=========================================="
 | 
					 | 
				
			||||||
done || exit 1
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
GATEWAY_TESTS=`find tests/Browser/ClientPortal/Gateways/ -type f -name '*.php'`
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
if [ $TYPE == 'generic' ]; then
 | 
					 | 
				
			||||||
    GATEWAY_TESTS=""
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    echo "$ Skippping gateway tests."
 | 
					 | 
				
			||||||
    echo "=========================================="
 | 
					 | 
				
			||||||
fi
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
for TEST_CLASS in $GATEWAY_TESTS; do
 | 
					 | 
				
			||||||
    echo "Test class: $TEST_CLASS"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    echo "$ php artisan migrate:fresh --seed"
 | 
					 | 
				
			||||||
    php artisan migrate:fresh --seed &> /dev/null
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    echo "$ php artisan ninja:create-single-account"
 | 
					 | 
				
			||||||
    php artisan ninja:create-single-account &> /dev/null
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    echo "$ php artisan dusk $TEST_CLASS"
 | 
					 | 
				
			||||||
    php -d memory_limit=1G artisan dusk ${@:2} --stop-on-error --stop-on-failure $TEST_CLASS || exit 1
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    echo "=========================================="
 | 
					 | 
				
			||||||
done || exit 1
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
echo 'All tests completed successfully.'
 | 
					 | 
				
			||||||
@ -767,7 +767,7 @@ $LANG = array(
 | 
				
			|||||||
    'activity_19' => ':user aktualisierte Angebot :quote',
 | 
					    'activity_19' => ':user aktualisierte Angebot :quote',
 | 
				
			||||||
    'activity_20' => ':user mailte Angebot :quote für :client an :contact',
 | 
					    'activity_20' => ':user mailte Angebot :quote für :client an :contact',
 | 
				
			||||||
    'activity_21' => ':contact schaute Angebot :quote an',
 | 
					    'activity_21' => ':contact schaute Angebot :quote an',
 | 
				
			||||||
    'activity_22' => ':user archivierte Angebot :quote',
 | 
					    'activity_22' => ':user archiviertes Angebot :quote',
 | 
				
			||||||
    'activity_23' => ':user löschte Angebot :quote',
 | 
					    'activity_23' => ':user löschte Angebot :quote',
 | 
				
			||||||
    'activity_24' => ':user stellte Angebot :quote wieder her',
 | 
					    'activity_24' => ':user stellte Angebot :quote wieder her',
 | 
				
			||||||
    'activity_25' => ':user stellte Rechnung :invoice wieder her',
 | 
					    'activity_25' => ':user stellte Rechnung :invoice wieder her',
 | 
				
			||||||
@ -904,7 +904,7 @@ $LANG = array(
 | 
				
			|||||||
    'payment_terms_net' => 'Netto',
 | 
					    'payment_terms_net' => 'Netto',
 | 
				
			||||||
    'vendor' => 'Lieferant',
 | 
					    'vendor' => 'Lieferant',
 | 
				
			||||||
    'edit_vendor' => 'Lieferant Bearbeiten',
 | 
					    'edit_vendor' => 'Lieferant Bearbeiten',
 | 
				
			||||||
    'archive_vendor' => 'Lieferant Archivieren',
 | 
					    'archive_vendor' => 'Lieferant archivieren',
 | 
				
			||||||
    'delete_vendor' => 'Lieferant Löschen',
 | 
					    'delete_vendor' => 'Lieferant Löschen',
 | 
				
			||||||
    'view_vendor' => 'Lieferant Ansehen',
 | 
					    'view_vendor' => 'Lieferant Ansehen',
 | 
				
			||||||
    'deleted_expense' => 'Ausgabe erfolgreich gelöscht',
 | 
					    'deleted_expense' => 'Ausgabe erfolgreich gelöscht',
 | 
				
			||||||
@ -923,7 +923,7 @@ $LANG = array(
 | 
				
			|||||||
    'should_be_invoiced' => 'Sollte in Rechnung gestellt werden',
 | 
					    'should_be_invoiced' => 'Sollte in Rechnung gestellt werden',
 | 
				
			||||||
    'view_expense' => 'Ausgabe # :expense ansehen',
 | 
					    'view_expense' => 'Ausgabe # :expense ansehen',
 | 
				
			||||||
    'edit_expense' => 'Ausgabe Bearbeiten',
 | 
					    'edit_expense' => 'Ausgabe Bearbeiten',
 | 
				
			||||||
    'archive_expense' => 'Ausgabe Archivieren',
 | 
					    'archive_expense' => 'Ausgabe archivieren',
 | 
				
			||||||
    'delete_expense' => 'Ausgabe Löschen',
 | 
					    'delete_expense' => 'Ausgabe Löschen',
 | 
				
			||||||
    'view_expense_num' => 'Ausgabe # :expense',
 | 
					    'view_expense_num' => 'Ausgabe # :expense',
 | 
				
			||||||
    'updated_expense' => 'Ausgabe erfolgreich aktualisiert',
 | 
					    'updated_expense' => 'Ausgabe erfolgreich aktualisiert',
 | 
				
			||||||
@ -4534,12 +4534,12 @@ https://invoiceninja.github.io/docs/migration/#troubleshooting',
 | 
				
			|||||||
    'auto_archive_invoice_cancelled_help' => 'Automatisch Rechnungen archivieren, wenn diese storniert wurden',
 | 
					    'auto_archive_invoice_cancelled_help' => 'Automatisch Rechnungen archivieren, wenn diese storniert wurden',
 | 
				
			||||||
    'no_invoices_found' => 'Keine Rechnungen gefunden',
 | 
					    'no_invoices_found' => 'Keine Rechnungen gefunden',
 | 
				
			||||||
    'created_record' => 'Eintrag erfolgreich erstellt.',
 | 
					    'created_record' => 'Eintrag erfolgreich erstellt.',
 | 
				
			||||||
    'auto_archive_paid_invoices' => 'Bezahltes Automatisch Archivieren',
 | 
					    'auto_archive_paid_invoices' => 'Bezahltes automatisch archivieren',
 | 
				
			||||||
    'auto_archive_paid_invoices_help' => 'Automatische Archivierung von Rechnungen, wenn diese als bezahlt markiert werden.',
 | 
					    'auto_archive_paid_invoices_help' => 'Automatische Archivierung von Rechnungen, wenn diese als bezahlt markiert werden.',
 | 
				
			||||||
    'auto_archive_cancelled_invoices' => 'Auto-Archivierung abgebrochen',
 | 
					    'auto_archive_cancelled_invoices' => 'Auto-Archivierung abgebrochen',
 | 
				
			||||||
    'auto_archive_cancelled_invoices_help' => 'Automatisch Rechnungen archivieren, wenn diese storniert wurden.',
 | 
					    'auto_archive_cancelled_invoices_help' => 'Automatisch Rechnungen archivieren, wenn diese storniert wurden.',
 | 
				
			||||||
    'alternate_pdf_viewer' => 'Alternativer PDF Viewer',
 | 
					    'alternate_pdf_viewer' => 'Alternativer PDF Viewer',
 | 
				
			||||||
    'alternate_pdf_viewer_help' => 'Verbessere das Scrolling über die PDF Vorschau [BETA]',
 | 
					    'alternate_pdf_viewer_help' => 'Verbessere das Scrolling über die PDF-Vorschau [BETA]',
 | 
				
			||||||
    'currency_cayman_island_dollar' => 'Cayman Island Dollar',
 | 
					    'currency_cayman_island_dollar' => 'Cayman Island Dollar',
 | 
				
			||||||
    'download_report_description' => 'Bitte das angehängte Dokument öffnen, um den Report anzusehen.',
 | 
					    'download_report_description' => 'Bitte das angehängte Dokument öffnen, um den Report anzusehen.',
 | 
				
			||||||
    'left' => 'Links',
 | 
					    'left' => 'Links',
 | 
				
			||||||
@ -4604,7 +4604,7 @@ https://invoiceninja.github.io/docs/migration/#troubleshooting',
 | 
				
			|||||||
    'yes_its_great' => 'Ja, es ist super!',
 | 
					    'yes_its_great' => 'Ja, es ist super!',
 | 
				
			||||||
    'not_so_much' => 'Nein, eher weniger',
 | 
					    'not_so_much' => 'Nein, eher weniger',
 | 
				
			||||||
    'would_you_rate_it' => 'Danke für das Feedback, mächten Sie die App bewerten?',
 | 
					    'would_you_rate_it' => 'Danke für das Feedback, mächten Sie die App bewerten?',
 | 
				
			||||||
    'would_you_tell_us_more' => 'Das tut uns leid, dass zu hören. Was gefällt Ihnen nicht?',
 | 
					    'would_you_tell_us_more' => 'Es tut uns leid, das zu hören. Was gefällt Ihnen nicht?',
 | 
				
			||||||
    'sure_happy_to' => 'Gerne',
 | 
					    'sure_happy_to' => 'Gerne',
 | 
				
			||||||
    'no_not_now' => 'Nein, nicht jetzt.',
 | 
					    'no_not_now' => 'Nein, nicht jetzt.',
 | 
				
			||||||
    'add' => 'Hinzufügen',
 | 
					    'add' => 'Hinzufügen',
 | 
				
			||||||
@ -5116,6 +5116,12 @@ https://invoiceninja.github.io/docs/migration/#troubleshooting',
 | 
				
			|||||||
    'item_tax_rate2' => 'Item Tax Rate 2',
 | 
					    'item_tax_rate2' => 'Item Tax Rate 2',
 | 
				
			||||||
    'item_tax_rate3' => 'Item Tax Rate 3',
 | 
					    'item_tax_rate3' => 'Item Tax Rate 3',
 | 
				
			||||||
    'buy_price' => 'Buy Price',
 | 
					    'buy_price' => 'Buy Price',
 | 
				
			||||||
 | 
					    'country_Macedonia' => 'Macedonia',
 | 
				
			||||||
 | 
					    'admin_initiated_payments' => 'Admin Initiated Payments',
 | 
				
			||||||
 | 
					    'admin_initiated_payments_help' => 'Support entering a payment in the admin portal without an invoice',
 | 
				
			||||||
 | 
					    'paid_date' => 'Paid Date',
 | 
				
			||||||
 | 
					    'downloaded_entities' => 'An email will be sent with the PDFs',
 | 
				
			||||||
 | 
					
 | 
				
			||||||
);
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -5119,6 +5119,9 @@ $LANG = array(
 | 
				
			|||||||
    'admin_initiated_payments_help' => 'Support entering a payment in the admin portal without an invoice',
 | 
					    'admin_initiated_payments_help' => 'Support entering a payment in the admin portal without an invoice',
 | 
				
			||||||
    'paid_date' => 'Paid Date',
 | 
					    'paid_date' => 'Paid Date',
 | 
				
			||||||
    'downloaded_entities' => 'An email will be sent with the PDFs',
 | 
					    'downloaded_entities' => 'An email will be sent with the PDFs',
 | 
				
			||||||
 | 
					    'lang_French - Swiss' => 'French - Swiss',
 | 
				
			||||||
 | 
					    'currency_swazi_lilangeni' => 'Swazi Lilangeni',
 | 
				
			||||||
 | 
					    'income' => 'Income',
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
);
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -5110,6 +5110,8 @@ Lorsque les montant apparaîtront sur votre relevé, veuillez revenir sur cette
 | 
				
			|||||||
    'admin_initiated_payments' => 'Paiements initiés par l\'administration',
 | 
					    'admin_initiated_payments' => 'Paiements initiés par l\'administration',
 | 
				
			||||||
    'admin_initiated_payments_help' => 'Permet la saisie d\'un paiement dans le portal d\'administration sans facture',
 | 
					    'admin_initiated_payments_help' => 'Permet la saisie d\'un paiement dans le portal d\'administration sans facture',
 | 
				
			||||||
    'paid_date' => 'Date de paiement',
 | 
					    'paid_date' => 'Date de paiement',
 | 
				
			||||||
 | 
					    'downloaded_entities' => 'Un courriel sera envoyé avec le ou les PDF',
 | 
				
			||||||
 | 
					
 | 
				
			||||||
);
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -748,7 +748,7 @@ $LANG = array(
 | 
				
			|||||||
    'activity_7' => ':contact a visualisé la facture :invoice pour :client',
 | 
					    'activity_7' => ':contact a visualisé la facture :invoice pour :client',
 | 
				
			||||||
    'activity_8' => ':user a archivé la facture :invoice',
 | 
					    'activity_8' => ':user a archivé la facture :invoice',
 | 
				
			||||||
    'activity_9' => ':user a supprimé la facture :invoice',
 | 
					    'activity_9' => ':user a supprimé la facture :invoice',
 | 
				
			||||||
    'activity_10' => ':user entered payment :payment for :payment_amount on invoice :invoice for :client',
 | 
					    'activity_10' => ':user a saisi le paiement :payment pour :payment_montant sur la facture :invoice pour :client',
 | 
				
			||||||
    'activity_11' => ':user a mis à jour le paiement :payment',
 | 
					    'activity_11' => ':user a mis à jour le paiement :payment',
 | 
				
			||||||
    'activity_12' => ':user a archivé le paiement :payment',
 | 
					    'activity_12' => ':user a archivé le paiement :payment',
 | 
				
			||||||
    'activity_13' => ':user a supprimé le paiement :payment',
 | 
					    'activity_13' => ':user a supprimé le paiement :payment',
 | 
				
			||||||
@ -1991,7 +1991,7 @@ Lorsque les montant apparaîtront sur votre relevé, veuillez revenir sur cette
 | 
				
			|||||||
    'current_quarter' => 'Trimestre en cours',
 | 
					    'current_quarter' => 'Trimestre en cours',
 | 
				
			||||||
    'last_quarter' => 'Dernier trimestre',
 | 
					    'last_quarter' => 'Dernier trimestre',
 | 
				
			||||||
    'last_year' => 'Dernière année',
 | 
					    'last_year' => 'Dernière année',
 | 
				
			||||||
    'all_time' => 'All Time',
 | 
					    'all_time' => 'Tout le temps',
 | 
				
			||||||
    'custom_range' => 'Personnalisé',
 | 
					    'custom_range' => 'Personnalisé',
 | 
				
			||||||
    'url' => 'URL',
 | 
					    'url' => 'URL',
 | 
				
			||||||
    'debug' => 'Débogage',
 | 
					    'debug' => 'Débogage',
 | 
				
			||||||
@ -2252,7 +2252,7 @@ Lorsque les montant apparaîtront sur votre relevé, veuillez revenir sur cette
 | 
				
			|||||||
    'restore_recurring_expense' => 'Restaurer la dépense récurrente',
 | 
					    'restore_recurring_expense' => 'Restaurer la dépense récurrente',
 | 
				
			||||||
    'restored_recurring_expense' => 'La dépense récurrente a été restaurée avec succès',
 | 
					    'restored_recurring_expense' => 'La dépense récurrente a été restaurée avec succès',
 | 
				
			||||||
    'delete_recurring_expense' => 'Supprimer la dépense récurrente',
 | 
					    'delete_recurring_expense' => 'Supprimer la dépense récurrente',
 | 
				
			||||||
    'deleted_recurring_expense' => 'Successfully deleted recurring expense',
 | 
					    'deleted_recurring_expense' => 'Dépense récurrente supprimée avec succès',
 | 
				
			||||||
    'view_recurring_expense' => 'Visualiser la dépense récurrente',
 | 
					    'view_recurring_expense' => 'Visualiser la dépense récurrente',
 | 
				
			||||||
    'taxes_and_fees' => 'Taxes et frais',
 | 
					    'taxes_and_fees' => 'Taxes et frais',
 | 
				
			||||||
    'import_failed' => 'L\'importation a échoué',
 | 
					    'import_failed' => 'L\'importation a échoué',
 | 
				
			||||||
@ -2507,8 +2507,8 @@ Lorsque les montant apparaîtront sur votre relevé, veuillez revenir sur cette
 | 
				
			|||||||
    'partial_due_date' => 'Date d\'échéance du paiement partiel',
 | 
					    'partial_due_date' => 'Date d\'échéance du paiement partiel',
 | 
				
			||||||
    'task_fields' => 'Champs d\'intervention',
 | 
					    'task_fields' => 'Champs d\'intervention',
 | 
				
			||||||
    'product_fields_help' => 'Glisser et déposer les champs pour changer l\'ordre',
 | 
					    'product_fields_help' => 'Glisser et déposer les champs pour changer l\'ordre',
 | 
				
			||||||
    'custom_value1' => 'Custom Value 1',
 | 
					    'custom_value1' => 'Valeur personnalisée 1',
 | 
				
			||||||
    'custom_value2' => 'Custom Value 2',
 | 
					    'custom_value2' => 'Valeur personnalisée 2',
 | 
				
			||||||
    'enable_two_factor' => 'Authentification à deux facteurs',
 | 
					    'enable_two_factor' => 'Authentification à deux facteurs',
 | 
				
			||||||
    'enable_two_factor_help' => 'Utilisez votre téléphone pour confirmer votre identité lors de la connexion',
 | 
					    'enable_two_factor_help' => 'Utilisez votre téléphone pour confirmer votre identité lors de la connexion',
 | 
				
			||||||
    'two_factor_setup' => 'Configuration de l\'authentification à deux facteurs',
 | 
					    'two_factor_setup' => 'Configuration de l\'authentification à deux facteurs',
 | 
				
			||||||
@ -3855,7 +3855,7 @@ Lorsque les montant apparaîtront sur votre relevé, veuillez revenir sur cette
 | 
				
			|||||||
     'notification_credit_viewed' => 'Un crédit de :amount a été vu par le client :client.',
 | 
					     'notification_credit_viewed' => 'Un crédit de :amount a été vu par le client :client.',
 | 
				
			||||||
     'reset_password_text' => 'Saisissez votre adresse courriel pour réinitialiser votre mot de passe.',
 | 
					     'reset_password_text' => 'Saisissez votre adresse courriel pour réinitialiser votre mot de passe.',
 | 
				
			||||||
     'password_reset' => 'Réinitialisation du mot de passe',
 | 
					     'password_reset' => 'Réinitialisation du mot de passe',
 | 
				
			||||||
     'account_login_text' => 'Welcome! Glad to see you.',
 | 
					     'account_login_text' => 'Accueillir! Content de te voir.',
 | 
				
			||||||
     'request_cancellation' => 'Annuler la demande',
 | 
					     'request_cancellation' => 'Annuler la demande',
 | 
				
			||||||
     'delete_payment_method' => 'Supprimer le mode de paiement',
 | 
					     'delete_payment_method' => 'Supprimer le mode de paiement',
 | 
				
			||||||
     'about_to_delete_payment_method' => 'Le mode de paiement sera supprimé',
 | 
					     'about_to_delete_payment_method' => 'Le mode de paiement sera supprimé',
 | 
				
			||||||
@ -3969,7 +3969,7 @@ Lorsque les montant apparaîtront sur votre relevé, veuillez revenir sur cette
 | 
				
			|||||||
     'add_payment_method_first' => 'ajouter un mode de paiement',
 | 
					     'add_payment_method_first' => 'ajouter un mode de paiement',
 | 
				
			||||||
     'no_items_selected' => 'Aucun article sélectionné',
 | 
					     'no_items_selected' => 'Aucun article sélectionné',
 | 
				
			||||||
     'payment_due' => 'Paiement dû',
 | 
					     'payment_due' => 'Paiement dû',
 | 
				
			||||||
     'account_balance' => 'Account Balance',
 | 
					     'account_balance' => 'Solde du compte',
 | 
				
			||||||
     'thanks' => 'Merci',
 | 
					     'thanks' => 'Merci',
 | 
				
			||||||
     'minimum_required_payment' => 'Le paiement minimum requis est :amount',
 | 
					     'minimum_required_payment' => 'Le paiement minimum requis est :amount',
 | 
				
			||||||
     'under_payments_disabled' => 'La société ne tolère pas le sous-paiement.',
 | 
					     'under_payments_disabled' => 'La société ne tolère pas le sous-paiement.',
 | 
				
			||||||
@ -3994,7 +3994,7 @@ Lorsque les montant apparaîtront sur votre relevé, veuillez revenir sur cette
 | 
				
			|||||||
     'notification_invoice_reminder1_sent_subject' => 'Le rappel 1 pour la facture :invoice a été envoyé à :client',
 | 
					     'notification_invoice_reminder1_sent_subject' => 'Le rappel 1 pour la facture :invoice a été envoyé à :client',
 | 
				
			||||||
     'notification_invoice_reminder2_sent_subject' => 'Le rappel 2 pour la facture :invoice a été envoyé à :client',
 | 
					     'notification_invoice_reminder2_sent_subject' => 'Le rappel 2 pour la facture :invoice a été envoyé à :client',
 | 
				
			||||||
     'notification_invoice_reminder3_sent_subject' => 'Le rappel 3 pour la facture :invoice a été envoyé à :client',
 | 
					     'notification_invoice_reminder3_sent_subject' => 'Le rappel 3 pour la facture :invoice a été envoyé à :client',
 | 
				
			||||||
     'notification_invoice_custom_sent_subject' => 'Custom reminder for Invoice :invoice was sent to :client',
 | 
					     'notification_invoice_custom_sent_subject' => 'Un rappel personnalisé pour la facture :invoice a été envoyé à :client',
 | 
				
			||||||
     'notification_invoice_reminder_endless_sent_subject' => 'Un rappel perpétuel pour la facture :invoice a été envoyé à :client',
 | 
					     'notification_invoice_reminder_endless_sent_subject' => 'Un rappel perpétuel pour la facture :invoice a été envoyé à :client',
 | 
				
			||||||
     'assigned_user' => 'Utilisateur affecté',
 | 
					     'assigned_user' => 'Utilisateur affecté',
 | 
				
			||||||
     'setup_steps_notice' => 'Pour accéder à la prochaine étape, vous devez tester chaque section.',
 | 
					     'setup_steps_notice' => 'Pour accéder à la prochaine étape, vous devez tester chaque section.',
 | 
				
			||||||
@ -4372,7 +4372,7 @@ Lorsque les montant apparaîtront sur votre relevé, veuillez revenir sur cette
 | 
				
			|||||||
    'imported_customers' => 'Successfully started importing customers',
 | 
					    'imported_customers' => 'Successfully started importing customers',
 | 
				
			||||||
    'login_success' => 'Successful Login',
 | 
					    'login_success' => 'Successful Login',
 | 
				
			||||||
    'login_failure' => 'Failed Login',
 | 
					    'login_failure' => 'Failed Login',
 | 
				
			||||||
    'exported_data' => 'Once the file is ready you\'ll receive an email with a download link',
 | 
					    'exported_data' => 'Une fois le fichier prêt, vous recevrez un e-mail avec un lien de téléchargement',
 | 
				
			||||||
    'include_deleted_clients' => 'Include Deleted Clients',
 | 
					    'include_deleted_clients' => 'Include Deleted Clients',
 | 
				
			||||||
    'include_deleted_clients_help' => 'Load records belonging to deleted clients',
 | 
					    'include_deleted_clients_help' => 'Load records belonging to deleted clients',
 | 
				
			||||||
    'step_1_sign_in' => 'Step 1: Sign In',
 | 
					    'step_1_sign_in' => 'Step 1: Sign In',
 | 
				
			||||||
@ -4461,7 +4461,7 @@ Lorsque les montant apparaîtront sur votre relevé, veuillez revenir sur cette
 | 
				
			|||||||
    'activity_123' => ':user deleted recurring expense :recurring_expense',
 | 
					    'activity_123' => ':user deleted recurring expense :recurring_expense',
 | 
				
			||||||
    'activity_124' => ':user restored recurring expense :recurring_expense',
 | 
					    'activity_124' => ':user restored recurring expense :recurring_expense',
 | 
				
			||||||
    'fpx' => "FPX",
 | 
					    'fpx' => "FPX",
 | 
				
			||||||
    'to_view_entity_set_password' => 'To view the :entity you need to set a password.',
 | 
					    'to_view_entity_set_password' => 'Pour afficher le :entity, vous devez définir un mot de passe.',
 | 
				
			||||||
    'unsubscribe' => 'Unsubscribe',
 | 
					    'unsubscribe' => 'Unsubscribe',
 | 
				
			||||||
    'unsubscribed' => 'Unsubscribed',
 | 
					    'unsubscribed' => 'Unsubscribed',
 | 
				
			||||||
    'unsubscribed_text' => 'You have been removed from notifications for this document',
 | 
					    'unsubscribed_text' => 'You have been removed from notifications for this document',
 | 
				
			||||||
@ -4559,7 +4559,7 @@ Lorsque les montant apparaîtront sur votre relevé, veuillez revenir sur cette
 | 
				
			|||||||
    'purchase_order_number' => 'Numéro de bon de commande',
 | 
					    'purchase_order_number' => 'Numéro de bon de commande',
 | 
				
			||||||
    'purchase_order_number_short' => 'Bon de commande #',
 | 
					    'purchase_order_number_short' => 'Bon de commande #',
 | 
				
			||||||
    'inventory_notification_subject' => 'Inventory threshold notification for product: :product',
 | 
					    'inventory_notification_subject' => 'Inventory threshold notification for product: :product',
 | 
				
			||||||
    'inventory_notification_body' => 'Threshold of :amount has been reached for product: :product',
 | 
					    'inventory_notification_body' => 'Le seuil de :amount a été atteint pour le produit : :product',
 | 
				
			||||||
    'activity_130' => ':user a créé le bon de commande :purchase_order',
 | 
					    'activity_130' => ':user a créé le bon de commande :purchase_order',
 | 
				
			||||||
    'activity_131' => ':user a mis à jour le bon de commande :purchase_order',
 | 
					    'activity_131' => ':user a mis à jour le bon de commande :purchase_order',
 | 
				
			||||||
    'activity_132' => ':user a archivé le bon de commande :purchase_order',
 | 
					    'activity_132' => ':user a archivé le bon de commande :purchase_order',
 | 
				
			||||||
@ -4591,7 +4591,7 @@ Lorsque les montant apparaîtront sur votre relevé, veuillez revenir sur cette
 | 
				
			|||||||
    'vendor_document_upload' => 'Vendor Document Upload',
 | 
					    'vendor_document_upload' => 'Vendor Document Upload',
 | 
				
			||||||
    'vendor_document_upload_help' => 'Enable vendors to upload documents',
 | 
					    'vendor_document_upload_help' => 'Enable vendors to upload documents',
 | 
				
			||||||
    'are_you_enjoying_the_app' => 'Are you enjoying the app?',
 | 
					    'are_you_enjoying_the_app' => 'Are you enjoying the app?',
 | 
				
			||||||
    'yes_its_great' => 'Yes, it\'s great!',
 | 
					    'yes_its_great' => 'Oui c'est super!',
 | 
				
			||||||
    'not_so_much' => 'Not so much',
 | 
					    'not_so_much' => 'Not so much',
 | 
				
			||||||
    'would_you_rate_it' => 'Great to hear! Would you like to rate it?',
 | 
					    'would_you_rate_it' => 'Great to hear! Would you like to rate it?',
 | 
				
			||||||
    'would_you_tell_us_more' => 'Sorry to hear it! Would you like to tell us more?',
 | 
					    'would_you_tell_us_more' => 'Sorry to hear it! Would you like to tell us more?',
 | 
				
			||||||
@ -4900,7 +4900,7 @@ Lorsque les montant apparaîtront sur votre relevé, veuillez revenir sur cette
 | 
				
			|||||||
    'all_clients' => 'All Clients',
 | 
					    'all_clients' => 'All Clients',
 | 
				
			||||||
    'show_aging_table' => 'Show Aging Table',
 | 
					    'show_aging_table' => 'Show Aging Table',
 | 
				
			||||||
    'show_payments_table' => 'Afficher le tableau de paiement',
 | 
					    'show_payments_table' => 'Afficher le tableau de paiement',
 | 
				
			||||||
    'only_clients_with_invoices' => 'Only Clients with Invoices',
 | 
					    'only_clients_with_invoices' => 'Seuls les clients avec factures',
 | 
				
			||||||
    'email_statement' => 'Email Statement',
 | 
					    'email_statement' => 'Email Statement',
 | 
				
			||||||
    'once' => 'Once',
 | 
					    'once' => 'Once',
 | 
				
			||||||
    'schedules' => 'Schedules',
 | 
					    'schedules' => 'Schedules',
 | 
				
			||||||
@ -4962,9 +4962,9 @@ Lorsque les montant apparaîtront sur votre relevé, veuillez revenir sur cette
 | 
				
			|||||||
    'white_label_body' => 'Thank you for purchasing a white label license. <br><br> Your license key is: <br><br> :license_key',
 | 
					    'white_label_body' => 'Thank you for purchasing a white label license. <br><br> Your license key is: <br><br> :license_key',
 | 
				
			||||||
    'payment_type_Klarna' => 'Klarna',
 | 
					    'payment_type_Klarna' => 'Klarna',
 | 
				
			||||||
    'payment_type_Interac E Transfer' => 'Interac E Transfer',
 | 
					    'payment_type_Interac E Transfer' => 'Interac E Transfer',
 | 
				
			||||||
    'xinvoice_payable' => 'Payable within :payeddue days net until :paydate',
 | 
					    'xinvoice_payable' => 'Payable sous :payeddue jours net jusqu'à :paydate',
 | 
				
			||||||
    'xinvoice_no_buyers_reference' => "No buyer's reference given",
 | 
					    'xinvoice_no_buyers_reference' => "Aucune référence d'acheteur donnée",
 | 
				
			||||||
    'xinvoice_online_payment' => 'The invoice needs to be paid online via the provided link',
 | 
					    'xinvoice_online_payment' => 'La facture doit être payée en ligne via le lien fourni',
 | 
				
			||||||
    'pre_payment' => 'Prépaiement',
 | 
					    'pre_payment' => 'Prépaiement',
 | 
				
			||||||
    'number_of_payments' => 'Nombre de paiements',
 | 
					    'number_of_payments' => 'Nombre de paiements',
 | 
				
			||||||
    'number_of_payments_helper' => 'Le nombre de fois que ce paiement sera exécuté',
 | 
					    'number_of_payments_helper' => 'Le nombre de fois que ce paiement sera exécuté',
 | 
				
			||||||
@ -5013,99 +5013,105 @@ Lorsque les montant apparaîtront sur votre relevé, veuillez revenir sur cette
 | 
				
			|||||||
    'quote_product_columns' => 'Quote Product Columns',
 | 
					    'quote_product_columns' => 'Quote Product Columns',
 | 
				
			||||||
    'vendors' => 'Vendors',
 | 
					    'vendors' => 'Vendors',
 | 
				
			||||||
    'product_sales' => 'Product Sales',
 | 
					    'product_sales' => 'Product Sales',
 | 
				
			||||||
    'user_sales_report_header' => 'User sales report for client/s :client from :start_date to :end_date',
 | 
					    'user_sales_report_header' => 'Rapport sur les ventes des utilisateurs pour le ou les clients :client de :start_date à :end_date',
 | 
				
			||||||
    'client_balance_report' => 'Customer balance report',
 | 
					    'client_balance_report' => 'Rapport sur le solde du client',
 | 
				
			||||||
    'client_sales_report' => 'Customer sales report',
 | 
					    'client_sales_report' => 'Rapport de ventes client',
 | 
				
			||||||
    'user_sales_report' => 'User sales report',
 | 
					    'user_sales_report' => 'Rapport de ventes utilisateur',
 | 
				
			||||||
    'aged_receivable_detailed_report' => 'Aged Receivable Detailed Report',
 | 
					    'aged_receivable_detailed_report' => 'Rapport détaillé sur les créances chronologiques',
 | 
				
			||||||
    'aged_receivable_summary_report' => 'Aged Receivable Summary Report',
 | 
					    'aged_receivable_summary_report' => 'Rapport récapitulatif des créances chronologiques',
 | 
				
			||||||
    'taxable_amount' => 'Taxable Amount',
 | 
					    'taxable_amount' => 'Montant imposable',
 | 
				
			||||||
    'tax_summary' => 'Tax Summary',
 | 
					    'tax_summary' => 'Récapitulatif fiscal',
 | 
				
			||||||
    'oauth_mail' => 'OAuth / Mail',
 | 
					    'oauth_mail' => 'OAuth / Courrier',
 | 
				
			||||||
    'preferences' => 'Preferences',
 | 
					    'preferences' => 'Préférences',
 | 
				
			||||||
    'analytics' => 'Analytics',
 | 
					    'analytics' => 'Analytique',
 | 
				
			||||||
    'reduced_rate' => 'Reduced Rate',
 | 
					    'reduced_rate' => 'Tarif réduit',
 | 
				
			||||||
    'tax_all' => 'Tax All',
 | 
					    'tax_all' => 'Taxe Tout',
 | 
				
			||||||
    'tax_selected' => 'Tax Selected',
 | 
					    'tax_selected' => 'Taxe sélectionnée',
 | 
				
			||||||
    'version' => 'version',
 | 
					    'version' => 'version',
 | 
				
			||||||
    'seller_subregion' => 'Seller Subregion',
 | 
					    'seller_subregion' => 'Sous-région du vendeur',
 | 
				
			||||||
    'calculate_taxes' => 'Calculate Taxes',
 | 
					    'calculate_taxes' => 'Calculer les taxes',
 | 
				
			||||||
    'calculate_taxes_help' => 'Automatically calculate taxes when saving invoices',
 | 
					    'calculate_taxes_help' => 'Calculer automatiquement les taxes lors de l'enregistrement des factures',
 | 
				
			||||||
    'link_expenses' => 'Link Expenses',
 | 
					    'link_expenses' => 'Dépenses de lien',
 | 
				
			||||||
    'converted_client_balance' => 'Converted Client Balance',
 | 
					    'converted_client_balance' => 'Solde client converti',
 | 
				
			||||||
    'converted_payment_balance' => 'Converted Payment Balance',
 | 
					    'converted_payment_balance' => 'Solde de paiement converti',
 | 
				
			||||||
    'total_hours' => 'Total Hours',
 | 
					    'total_hours' => 'Heures totales',
 | 
				
			||||||
    'date_picker_hint' => 'Use +days to set the date in the future',
 | 
					    'date_picker_hint' => 'Utilisez + jours pour définir la date dans le futur',
 | 
				
			||||||
    'app_help_link' => 'More information ',
 | 
					    'app_help_link' => 'Plus d'information',
 | 
				
			||||||
    'here' => 'here',
 | 
					    'here' => 'ici',
 | 
				
			||||||
    'industry_Restaurant & Catering' => 'Restaurant & Catering',
 | 
					    'industry_Restaurant & Catering' => 'Restauration & Traiteur',
 | 
				
			||||||
    'show_credits_table' => 'Show Credits Table',
 | 
					    'show_credits_table' => 'Afficher le tableau des crédits',
 | 
				
			||||||
    'manual_payment' => 'Payment Manual',
 | 
					    'manual_payment' => 'Manuel de paiement',
 | 
				
			||||||
    'tax_summary_report' => 'Tax Summary Report',
 | 
					    'tax_summary_report' => 'Rapport récapitulatif des taxes',
 | 
				
			||||||
    'tax_category' => 'Tax Category',
 | 
					    'tax_category' => 'Catégorie de taxe',
 | 
				
			||||||
    'physical_goods' => 'Physical Goods',
 | 
					    'physical_goods' => 'Biens physiques',
 | 
				
			||||||
    'digital_products' => 'Digital Products',
 | 
					    'digital_products' => 'Produits numériques',
 | 
				
			||||||
    'services' => 'Services',
 | 
					    'services' => 'Prestations de service',
 | 
				
			||||||
    'shipping' => 'Shipping',
 | 
					    'shipping' => 'Expédition',
 | 
				
			||||||
    'tax_exempt' => 'Tax Exempt',
 | 
					    'tax_exempt' => 'Exonéré d'impôt',
 | 
				
			||||||
    'late_fee_added_locked_invoice' => 'Late fee for invoice :invoice added on :date',
 | 
					    'late_fee_added_locked_invoice' => 'Frais de retard pour facture :invoice ajouté sur :date',
 | 
				
			||||||
    'lang_Khmer' => 'Khmer',
 | 
					    'lang_Khmer' => 'Khmer',
 | 
				
			||||||
    'routing_id' => 'Routing ID',
 | 
					    'routing_id' => 'ID de routage',
 | 
				
			||||||
    'enable_e_invoice' => 'Enable E-Invoice',
 | 
					    'enable_e_invoice' => 'Activer la facture électronique',
 | 
				
			||||||
    'e_invoice_type' => 'E-Invoice Type',
 | 
					    'e_invoice_type' => 'Type de facture électronique',
 | 
				
			||||||
    'reduced_tax' => 'Reduced Tax',
 | 
					    'reduced_tax' => 'Taxe réduite',
 | 
				
			||||||
    'override_tax' => 'Override Tax',
 | 
					    'override_tax' => 'Remplacer la taxe',
 | 
				
			||||||
    'zero_rated' => 'Zero Rated',
 | 
					    'zero_rated' => 'Évalué zéro',
 | 
				
			||||||
    'reverse_tax' => 'Reverse Tax',
 | 
					    'reverse_tax' => 'Taxe inversée',
 | 
				
			||||||
    'updated_tax_category' => 'Successfully updated the tax category',
 | 
					    'updated_tax_category' => 'Mise à jour réussie de la catégorie de taxe',
 | 
				
			||||||
    'updated_tax_categories' => 'Successfully updated the tax categories',
 | 
					    'updated_tax_categories' => 'Mise à jour réussie des catégories de taxes',
 | 
				
			||||||
    'set_tax_category' => 'Set Tax Category',
 | 
					    'set_tax_category' => 'Définir la catégorie de taxe',
 | 
				
			||||||
    'payment_manual' => 'Payment Manual',
 | 
					    'payment_manual' => 'Manuel de paiement',
 | 
				
			||||||
    'expense_payment_type' => 'Expense Payment Type',
 | 
					    'expense_payment_type' => 'Type de paiement des dépenses',
 | 
				
			||||||
    'payment_type_Cash App' => 'Cash App',
 | 
					    'payment_type_Cash App' => 'Application de trésorerie',
 | 
				
			||||||
    'rename' => 'Rename',
 | 
					    'rename' => 'Renommer',
 | 
				
			||||||
    'renamed_document' => 'Successfully renamed document',
 | 
					    'renamed_document' => 'Document renommé avec succès',
 | 
				
			||||||
    'e_invoice' => 'E-Invoice',
 | 
					    'e_invoice' => 'Facture électronique',
 | 
				
			||||||
    'light_dark_mode' => 'Light/Dark Mode',
 | 
					    'light_dark_mode' => 'Mode clair/foncé',
 | 
				
			||||||
    'activities' => 'Activities',
 | 
					    'activities' => 'Activités',
 | 
				
			||||||
    'recent_transactions' => "Here are your company's most recent transactions:",
 | 
					    'recent_transactions' => "Voici les transactions les plus récentes de votre entreprise :",
 | 
				
			||||||
    'country_Palestine' => "Palestine",
 | 
					    'country_Palestine' => "Palestine",
 | 
				
			||||||
    'country_Taiwan' => 'Taiwan',
 | 
					    'country_Taiwan' => 'Taïwan',
 | 
				
			||||||
    'duties' => 'Duties',
 | 
					    'duties' => 'Devoirs',
 | 
				
			||||||
    'order_number' => 'Order Number',
 | 
					    'order_number' => 'Numéro de commande',
 | 
				
			||||||
    'order_id' => 'Order',
 | 
					    'order_id' => 'Commande',
 | 
				
			||||||
    'total_invoices_outstanding' => 'Total Invoices Outstanding',
 | 
					    'total_invoices_outstanding' => 'Total des factures impayées',
 | 
				
			||||||
    'recent_activity' => 'Recent Activity',
 | 
					    'recent_activity' => 'Activité récente',
 | 
				
			||||||
    'enable_auto_bill' => 'Enable auto billing',
 | 
					    'enable_auto_bill' => 'Activer la facturation automatique',
 | 
				
			||||||
    'email_count_invoices' => 'Email :count invoices',
 | 
					    'email_count_invoices' => 'E-mail :count factures',
 | 
				
			||||||
    'invoice_task_item_description' => 'Invoice Task Item Description',
 | 
					    'invoice_task_item_description' => 'Description de l'élément de tâche de la facture',
 | 
				
			||||||
    'invoice_task_item_description_help' => 'Add the item description to the invoice line items',
 | 
					    'invoice_task_item_description_help' => 'Ajouter la description de l'article aux éléments de ligne de la facture',
 | 
				
			||||||
    'next_send_time' => 'Next Send Time',
 | 
					    'next_send_time' => 'Prochaine heure d'envoi',
 | 
				
			||||||
    'uploaded_certificate' => 'Successfully uploaded certificate',
 | 
					    'uploaded_certificate' => 'Certificat téléchargé avec succès',
 | 
				
			||||||
    'certificate_set' => 'Certificate set',
 | 
					    'certificate_set' => 'Ensemble de certificats',
 | 
				
			||||||
    'certificate_not_set' => 'Certificate not set',
 | 
					    'certificate_not_set' => 'Certificat non défini',
 | 
				
			||||||
    'passphrase_set' => 'Passphrase set',
 | 
					    'passphrase_set' => 'Jeu de mots de passe',
 | 
				
			||||||
    'passphrase_not_set' => 'Passphrase not set',
 | 
					    'passphrase_not_set' => 'Mot de passe non défini',
 | 
				
			||||||
    'upload_certificate' => 'Upload Certificate',
 | 
					    'upload_certificate' => 'Télécharger le certificat',
 | 
				
			||||||
    'certificate_passphrase' => 'Certificate Passphrase',
 | 
					    'certificate_passphrase' => 'Phrase de passe du certificat',
 | 
				
			||||||
    'valid_vat_number' => 'Valid VAT Number',
 | 
					    'valid_vat_number' => 'Numéro de TVA valide',
 | 
				
			||||||
    'react_notification_link' => 'React Notification Links',
 | 
					    'react_notification_link' => 'Liens de notification de réaction',
 | 
				
			||||||
    'react_notification_link_help' => 'Admin emails will contain links to the react application',  
 | 
					    'react_notification_link_help' => 'Les e-mails d'administration contiendront des liens vers l'application de réaction',  
 | 
				
			||||||
    'show_task_billable' => 'Show Task Billable',
 | 
					    'show_task_billable' => 'Afficher la tâche facturable',
 | 
				
			||||||
    'credit_item' => 'Credit Item',
 | 
					    'credit_item' => 'Article de crédit',
 | 
				
			||||||
    'drop_file_here' => 'Drop file here',
 | 
					    'drop_file_here' => 'Déposez le fichier ici',
 | 
				
			||||||
    'files' => 'Files',
 | 
					    'files' => 'Des dossiers',
 | 
				
			||||||
    'camera' => 'Camera',
 | 
					    'camera' => 'Caméra',
 | 
				
			||||||
    'gallery' => 'Gallery',
 | 
					    'gallery' => 'Galerie',
 | 
				
			||||||
    'project_location' => 'Project Location',
 | 
					    'project_location' => 'Emplacement du projet',
 | 
				
			||||||
    'add_gateway_help_message' => 'Add a payment gateway (ie. Stripe, WePay or PayPal) to accept online payments', 
 | 
					    'add_gateway_help_message' => 'Ajoutez une passerelle de paiement (c.-à-d. Stripe, WePay ou PayPal) pour accepter les paiements en ligne', 
 | 
				
			||||||
    'lang_Hungarian' => 'Hungarian',
 | 
					    'lang_Hungarian' => 'hongrois',
 | 
				
			||||||
    'use_mobile_to_manage_plan' => 'Use your phone subscription settings to manage your plan',
 | 
					    'use_mobile_to_manage_plan' => 'Utilisez les paramètres de votre abonnement téléphonique pour gérer votre forfait',
 | 
				
			||||||
    'item_tax3' => 'Item Tax3',
 | 
					    'item_tax3' => 'Taxe sur les articles3',
 | 
				
			||||||
    'item_tax_rate1' => 'Item Tax Rate 1',
 | 
					    'item_tax_rate1' => 'Taux de taxe sur l'article 1',
 | 
				
			||||||
    'item_tax_rate2' => 'Item Tax Rate 2',
 | 
					    'item_tax_rate2' => 'Taux de taxe sur l'article 2',
 | 
				
			||||||
    'item_tax_rate3' => 'Item Tax Rate 3',
 | 
					    'item_tax_rate3' => 'Taux de taxe sur l'article 3',
 | 
				
			||||||
    'buy_price' => 'Buy Price',
 | 
					    'buy_price' => 'Prix d'achat',
 | 
				
			||||||
 | 
					    'country_Macedonia' => 'Macédoine',
 | 
				
			||||||
 | 
					    'admin_initiated_payments' => 'Paiements initiés par l'administrateur',
 | 
				
			||||||
 | 
					    'admin_initiated_payments_help' => 'Prise en charge de la saisie d'un paiement dans le portail d'administration sans facture',
 | 
				
			||||||
 | 
					    'paid_date' => 'La date de paiement',
 | 
				
			||||||
 | 
					    'downloaded_entities' => 'Un email sera envoyé avec les PDF',
 | 
				
			||||||
 | 
					
 | 
				
			||||||
);
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -39,7 +39,7 @@ paths:
 | 
				
			|||||||
        - $ref: "#/components/parameters/page_meta"
 | 
					        - $ref: "#/components/parameters/page_meta"
 | 
				
			||||||
      responses:
 | 
					      responses:
 | 
				
			||||||
        200:
 | 
					        200:
 | 
				
			||||||
          description: "Returns the client object"
 | 
					          description: "Returns the list of activities"
 | 
				
			||||||
          headers:
 | 
					          headers:
 | 
				
			||||||
            X-MINIMUM-CLIENT-VERSION:
 | 
					            X-MINIMUM-CLIENT-VERSION:
 | 
				
			||||||
              $ref: "#/components/headers/X-MINIMUM-CLIENT-VERSION"
 | 
					              $ref: "#/components/headers/X-MINIMUM-CLIENT-VERSION"
 | 
				
			||||||
@ -50,7 +50,15 @@ paths:
 | 
				
			|||||||
          content:
 | 
					          content:
 | 
				
			||||||
            application/json:
 | 
					            application/json:
 | 
				
			||||||
              schema:  
 | 
					              schema:  
 | 
				
			||||||
                $ref: "#/components/schemas/Client"
 | 
					                type: object
 | 
				
			||||||
 | 
					                properties:
 | 
				
			||||||
 | 
					                  data: 
 | 
				
			||||||
 | 
					                    type: array
 | 
				
			||||||
 | 
					                    items:
 | 
				
			||||||
 | 
					                      $ref: '#/components/schemas/Activity'
 | 
				
			||||||
 | 
					                  meta:
 | 
				
			||||||
 | 
					                    type: object
 | 
				
			||||||
 | 
					                    $ref: '#/components/schemas/Meta'
 | 
				
			||||||
        401:
 | 
					        401:
 | 
				
			||||||
          $ref: "#/components/responses/401"
 | 
					          $ref: "#/components/responses/401"
 | 
				
			||||||
        403:
 | 
					        403:
 | 
				
			||||||
@ -267,7 +275,15 @@ paths:
 | 
				
			|||||||
          content:
 | 
					          content:
 | 
				
			||||||
            application/json:
 | 
					            application/json:
 | 
				
			||||||
              schema:  
 | 
					              schema:  
 | 
				
			||||||
                $ref: "#/components/schemas/BankIntegration"
 | 
					                type: object
 | 
				
			||||||
 | 
					                properties:
 | 
				
			||||||
 | 
					                  data: 
 | 
				
			||||||
 | 
					                    type: array
 | 
				
			||||||
 | 
					                    items:
 | 
				
			||||||
 | 
					                      $ref: '#/components/schemas/BankIntegration'
 | 
				
			||||||
 | 
					                  meta:
 | 
				
			||||||
 | 
					                    type: object
 | 
				
			||||||
 | 
					                    $ref: '#/components/schemas/Meta'
 | 
				
			||||||
        401:
 | 
					        401:
 | 
				
			||||||
          $ref: "#/components/responses/401"
 | 
					          $ref: "#/components/responses/401"
 | 
				
			||||||
        403:
 | 
					        403:
 | 
				
			||||||
@ -671,7 +687,15 @@ paths:
 | 
				
			|||||||
          content:
 | 
					          content:
 | 
				
			||||||
            application/json:
 | 
					            application/json:
 | 
				
			||||||
              schema:  
 | 
					              schema:  
 | 
				
			||||||
                $ref: "#/components/schemas/BankTransaction"
 | 
					                type: object
 | 
				
			||||||
 | 
					                properties:
 | 
				
			||||||
 | 
					                  data: 
 | 
				
			||||||
 | 
					                    type: array
 | 
				
			||||||
 | 
					                    items:
 | 
				
			||||||
 | 
					                      $ref: '#/components/schemas/BankTransaction'
 | 
				
			||||||
 | 
					                  meta:
 | 
				
			||||||
 | 
					                    type: object
 | 
				
			||||||
 | 
					                    $ref: '#/components/schemas/Meta'
 | 
				
			||||||
        401:
 | 
					        401:
 | 
				
			||||||
          $ref: "#/components/responses/401"
 | 
					          $ref: "#/components/responses/401"
 | 
				
			||||||
        403:
 | 
					        403:
 | 
				
			||||||
@ -1016,7 +1040,15 @@ paths:
 | 
				
			|||||||
          content:
 | 
					          content:
 | 
				
			||||||
            application/json:
 | 
					            application/json:
 | 
				
			||||||
              schema:  
 | 
					              schema:  
 | 
				
			||||||
                $ref: "#/components/schemas/BankTransactionRule"
 | 
					                type: object
 | 
				
			||||||
 | 
					                properties:
 | 
				
			||||||
 | 
					                  data: 
 | 
				
			||||||
 | 
					                    type: array
 | 
				
			||||||
 | 
					                    items:
 | 
				
			||||||
 | 
					                      $ref: '#/components/schemas/BankTransactionRule'
 | 
				
			||||||
 | 
					                  meta:
 | 
				
			||||||
 | 
					                    type: object
 | 
				
			||||||
 | 
					                    $ref: '#/components/schemas/Meta'
 | 
				
			||||||
        401:
 | 
					        401:
 | 
				
			||||||
          $ref: "#/components/responses/401"
 | 
					          $ref: "#/components/responses/401"
 | 
				
			||||||
        403:
 | 
					        403:
 | 
				
			||||||
@ -1348,7 +1380,15 @@ paths:
 | 
				
			|||||||
          content:
 | 
					          content:
 | 
				
			||||||
            application/json:
 | 
					            application/json:
 | 
				
			||||||
              schema:  
 | 
					              schema:  
 | 
				
			||||||
                $ref: "#/components/schemas/ClientGatewayToken"
 | 
					                type: object
 | 
				
			||||||
 | 
					                properties:
 | 
				
			||||||
 | 
					                  data: 
 | 
				
			||||||
 | 
					                    type: array
 | 
				
			||||||
 | 
					                    items:
 | 
				
			||||||
 | 
					                      $ref: '#/components/schemas/ClientGatewayToken'
 | 
				
			||||||
 | 
					                  meta:
 | 
				
			||||||
 | 
					                    type: object
 | 
				
			||||||
 | 
					                    $ref: '#/components/schemas/Meta'
 | 
				
			||||||
        401:
 | 
					        401:
 | 
				
			||||||
          $ref: "#/components/responses/401"
 | 
					          $ref: "#/components/responses/401"
 | 
				
			||||||
        403:
 | 
					        403:
 | 
				
			||||||
@ -1605,7 +1645,15 @@ paths:
 | 
				
			|||||||
          content:
 | 
					          content:
 | 
				
			||||||
            application/json:
 | 
					            application/json:
 | 
				
			||||||
              schema:  
 | 
					              schema:  
 | 
				
			||||||
                $ref: "#/components/schemas/Company"
 | 
					                type: object
 | 
				
			||||||
 | 
					                properties:
 | 
				
			||||||
 | 
					                  data: 
 | 
				
			||||||
 | 
					                    type: array
 | 
				
			||||||
 | 
					                    items:
 | 
				
			||||||
 | 
					                      $ref: '#/components/schemas/Company'
 | 
				
			||||||
 | 
					                  meta:
 | 
				
			||||||
 | 
					                    type: object
 | 
				
			||||||
 | 
					                    $ref: '#/components/schemas/Meta'
 | 
				
			||||||
        401:
 | 
					        401:
 | 
				
			||||||
          $ref: "#/components/responses/401"
 | 
					          $ref: "#/components/responses/401"
 | 
				
			||||||
        403:
 | 
					        403:
 | 
				
			||||||
@ -1948,7 +1996,15 @@ paths:
 | 
				
			|||||||
          content:
 | 
					          content:
 | 
				
			||||||
            application/json:
 | 
					            application/json:
 | 
				
			||||||
              schema:  
 | 
					              schema:  
 | 
				
			||||||
                $ref: "#/components/schemas/CompanyGateway"
 | 
					                type: object
 | 
				
			||||||
 | 
					                properties:
 | 
				
			||||||
 | 
					                  data: 
 | 
				
			||||||
 | 
					                    type: array
 | 
				
			||||||
 | 
					                    items:
 | 
				
			||||||
 | 
					                      $ref: '#/components/schemas/CompanyGateway'
 | 
				
			||||||
 | 
					                  meta:
 | 
				
			||||||
 | 
					                    type: object
 | 
				
			||||||
 | 
					                    $ref: '#/components/schemas/Meta'
 | 
				
			||||||
        401:
 | 
					        401:
 | 
				
			||||||
          $ref: "#/components/responses/401"
 | 
					          $ref: "#/components/responses/401"
 | 
				
			||||||
        403:
 | 
					        403:
 | 
				
			||||||
@ -2255,7 +2311,15 @@ paths:
 | 
				
			|||||||
          content:
 | 
					          content:
 | 
				
			||||||
            application/json:
 | 
					            application/json:
 | 
				
			||||||
              schema:  
 | 
					              schema:  
 | 
				
			||||||
                $ref: "#/components/schemas/CompanyLedger"
 | 
					                type: object
 | 
				
			||||||
 | 
					                properties:
 | 
				
			||||||
 | 
					                  data: 
 | 
				
			||||||
 | 
					                    type: array
 | 
				
			||||||
 | 
					                    items:
 | 
				
			||||||
 | 
					                      $ref: '#/components/schemas/CompanyLedger'
 | 
				
			||||||
 | 
					                  meta:
 | 
				
			||||||
 | 
					                    type: object
 | 
				
			||||||
 | 
					                    $ref: '#/components/schemas/Meta'
 | 
				
			||||||
        401:
 | 
					        401:
 | 
				
			||||||
          $ref: "#/components/responses/401"
 | 
					          $ref: "#/components/responses/401"
 | 
				
			||||||
        403:
 | 
					        403:
 | 
				
			||||||
@ -2359,7 +2423,15 @@ paths:
 | 
				
			|||||||
          content:
 | 
					          content:
 | 
				
			||||||
            application/json:
 | 
					            application/json:
 | 
				
			||||||
              schema:  
 | 
					              schema:  
 | 
				
			||||||
                $ref: "#/components/schemas/Design"
 | 
					                type: object
 | 
				
			||||||
 | 
					                properties:
 | 
				
			||||||
 | 
					                  data: 
 | 
				
			||||||
 | 
					                    type: array
 | 
				
			||||||
 | 
					                    items:
 | 
				
			||||||
 | 
					                      $ref: '#/components/schemas/Design'
 | 
				
			||||||
 | 
					                  meta:
 | 
				
			||||||
 | 
					                    type: object
 | 
				
			||||||
 | 
					                    $ref: '#/components/schemas/Meta'
 | 
				
			||||||
        401:
 | 
					        401:
 | 
				
			||||||
          $ref: "#/components/responses/401"
 | 
					          $ref: "#/components/responses/401"
 | 
				
			||||||
        403:
 | 
					        403:
 | 
				
			||||||
@ -2667,7 +2739,15 @@ paths:
 | 
				
			|||||||
          content:
 | 
					          content:
 | 
				
			||||||
            application/json:
 | 
					            application/json:
 | 
				
			||||||
              schema:  
 | 
					              schema:  
 | 
				
			||||||
                $ref: "#/components/schemas/Document"
 | 
					                type: object
 | 
				
			||||||
 | 
					                properties:
 | 
				
			||||||
 | 
					                  data: 
 | 
				
			||||||
 | 
					                    type: array
 | 
				
			||||||
 | 
					                    items:
 | 
				
			||||||
 | 
					                      $ref: '#/components/schemas/Document'
 | 
				
			||||||
 | 
					                  meta:
 | 
				
			||||||
 | 
					                    type: object
 | 
				
			||||||
 | 
					                    $ref: '#/components/schemas/Meta'
 | 
				
			||||||
        401:
 | 
					        401:
 | 
				
			||||||
          $ref: "#/components/responses/401"
 | 
					          $ref: "#/components/responses/401"
 | 
				
			||||||
        403:
 | 
					        403:
 | 
				
			||||||
@ -2752,7 +2832,15 @@ paths:
 | 
				
			|||||||
          content:
 | 
					          content:
 | 
				
			||||||
            application/json:
 | 
					            application/json:
 | 
				
			||||||
              schema:  
 | 
					              schema:  
 | 
				
			||||||
                $ref: "#/components/schemas/ExpenseCategory"
 | 
					                type: object
 | 
				
			||||||
 | 
					                properties:
 | 
				
			||||||
 | 
					                  data: 
 | 
				
			||||||
 | 
					                    type: array
 | 
				
			||||||
 | 
					                    items:
 | 
				
			||||||
 | 
					                      $ref: '#/components/schemas/ExpenseCategory'
 | 
				
			||||||
 | 
					                  meta:
 | 
				
			||||||
 | 
					                    type: object
 | 
				
			||||||
 | 
					                    $ref: '#/components/schemas/Meta'
 | 
				
			||||||
        401:
 | 
					        401:
 | 
				
			||||||
          $ref: "#/components/responses/401"
 | 
					          $ref: "#/components/responses/401"
 | 
				
			||||||
        403:
 | 
					        403:
 | 
				
			||||||
@ -3048,7 +3136,15 @@ paths:
 | 
				
			|||||||
          content:
 | 
					          content:
 | 
				
			||||||
            application/json:
 | 
					            application/json:
 | 
				
			||||||
              schema:  
 | 
					              schema:  
 | 
				
			||||||
                $ref: "#/components/schemas/Expense"
 | 
					                type: object
 | 
				
			||||||
 | 
					                properties:
 | 
				
			||||||
 | 
					                  data: 
 | 
				
			||||||
 | 
					                    type: array
 | 
				
			||||||
 | 
					                    items:
 | 
				
			||||||
 | 
					                      $ref: '#/components/schemas/Expense'
 | 
				
			||||||
 | 
					                  meta:
 | 
				
			||||||
 | 
					                    type: object
 | 
				
			||||||
 | 
					                    $ref: '#/components/schemas/Meta'
 | 
				
			||||||
        401:
 | 
					        401:
 | 
				
			||||||
          $ref: "#/components/responses/401"
 | 
					          $ref: "#/components/responses/401"
 | 
				
			||||||
        403:
 | 
					        403:
 | 
				
			||||||
@ -3416,7 +3512,15 @@ paths:
 | 
				
			|||||||
          content:
 | 
					          content:
 | 
				
			||||||
            application/json:
 | 
					            application/json:
 | 
				
			||||||
              schema:  
 | 
					              schema:  
 | 
				
			||||||
                $ref: "#/components/schemas/GroupSetting"
 | 
					                type: object
 | 
				
			||||||
 | 
					                properties:
 | 
				
			||||||
 | 
					                  data: 
 | 
				
			||||||
 | 
					                    type: array
 | 
				
			||||||
 | 
					                    items:
 | 
				
			||||||
 | 
					                      $ref: '#/components/schemas/GroupSetting'
 | 
				
			||||||
 | 
					                  meta:
 | 
				
			||||||
 | 
					                    type: object
 | 
				
			||||||
 | 
					                    $ref: '#/components/schemas/Meta'
 | 
				
			||||||
        401:
 | 
					        401:
 | 
				
			||||||
          $ref: "#/components/responses/401"
 | 
					          $ref: "#/components/responses/401"
 | 
				
			||||||
        403:
 | 
					        403:
 | 
				
			||||||
@ -3899,8 +4003,8 @@ paths:
 | 
				
			|||||||
    post:
 | 
					    post:
 | 
				
			||||||
      tags:
 | 
					      tags:
 | 
				
			||||||
        - logout
 | 
					        - logout
 | 
				
			||||||
      summary: "Gets a list of logout"
 | 
					      summary: "Logs the user out of their current session"
 | 
				
			||||||
      description: "Lists all logout"
 | 
					      description: "Logs the user out of their current session"
 | 
				
			||||||
      operationId: getLogout
 | 
					      operationId: getLogout
 | 
				
			||||||
      parameters:
 | 
					      parameters:
 | 
				
			||||||
        - $ref: "#/components/parameters/X-API-TOKEN"
 | 
					        - $ref: "#/components/parameters/X-API-TOKEN"
 | 
				
			||||||
@ -4087,7 +4191,15 @@ paths:
 | 
				
			|||||||
          content:
 | 
					          content:
 | 
				
			||||||
            application/json:
 | 
					            application/json:
 | 
				
			||||||
              schema:  
 | 
					              schema:  
 | 
				
			||||||
                $ref: "#/components/schemas/PaymentTerm"
 | 
					                type: object
 | 
				
			||||||
 | 
					                properties:
 | 
				
			||||||
 | 
					                  data: 
 | 
				
			||||||
 | 
					                    type: array
 | 
				
			||||||
 | 
					                    items:
 | 
				
			||||||
 | 
					                      $ref: '#/components/schemas/PaymentTerm'
 | 
				
			||||||
 | 
					                  meta:
 | 
				
			||||||
 | 
					                    type: object
 | 
				
			||||||
 | 
					                    $ref: '#/components/schemas/Meta'
 | 
				
			||||||
        401:
 | 
					        401:
 | 
				
			||||||
          $ref: "#/components/responses/401"
 | 
					          $ref: "#/components/responses/401"
 | 
				
			||||||
        403:
 | 
					        403:
 | 
				
			||||||
@ -4521,7 +4633,15 @@ paths:
 | 
				
			|||||||
          content:
 | 
					          content:
 | 
				
			||||||
            application/json:
 | 
					            application/json:
 | 
				
			||||||
              schema:  
 | 
					              schema:  
 | 
				
			||||||
                $ref: "#/components/schemas/RecurringExpense"
 | 
					                type: object
 | 
				
			||||||
 | 
					                properties:
 | 
				
			||||||
 | 
					                  data: 
 | 
				
			||||||
 | 
					                    type: array
 | 
				
			||||||
 | 
					                    items:
 | 
				
			||||||
 | 
					                      $ref: '#/components/schemas/RecurringExpense'
 | 
				
			||||||
 | 
					                  meta:
 | 
				
			||||||
 | 
					                    type: object
 | 
				
			||||||
 | 
					                    $ref: '#/components/schemas/Meta'
 | 
				
			||||||
        401:
 | 
					        401:
 | 
				
			||||||
          $ref: "#/components/responses/401"
 | 
					          $ref: "#/components/responses/401"
 | 
				
			||||||
        403:
 | 
					        403:
 | 
				
			||||||
@ -4863,7 +4983,15 @@ paths:
 | 
				
			|||||||
          content:
 | 
					          content:
 | 
				
			||||||
            application/json:
 | 
					            application/json:
 | 
				
			||||||
              schema:  
 | 
					              schema:  
 | 
				
			||||||
                $ref: "#/components/schemas/RecurringQuote"
 | 
					                type: object
 | 
				
			||||||
 | 
					                properties:
 | 
				
			||||||
 | 
					                  data: 
 | 
				
			||||||
 | 
					                    type: array
 | 
				
			||||||
 | 
					                    items:
 | 
				
			||||||
 | 
					                      $ref: '#/components/schemas/RecurringQuote'
 | 
				
			||||||
 | 
					                  meta:
 | 
				
			||||||
 | 
					                    type: object
 | 
				
			||||||
 | 
					                    $ref: '#/components/schemas/Meta'
 | 
				
			||||||
        401:
 | 
					        401:
 | 
				
			||||||
          $ref: "#/components/responses/401"
 | 
					          $ref: "#/components/responses/401"
 | 
				
			||||||
        403:
 | 
					        403:
 | 
				
			||||||
@ -5759,7 +5887,15 @@ paths:
 | 
				
			|||||||
          content:
 | 
					          content:
 | 
				
			||||||
            application/json:
 | 
					            application/json:
 | 
				
			||||||
              schema:  
 | 
					              schema:  
 | 
				
			||||||
                $ref: "#/components/schemas/Subscription"
 | 
					                type: object
 | 
				
			||||||
 | 
					                properties:
 | 
				
			||||||
 | 
					                  data: 
 | 
				
			||||||
 | 
					                    type: array
 | 
				
			||||||
 | 
					                    items:
 | 
				
			||||||
 | 
					                      $ref: '#/components/schemas/Subscription'
 | 
				
			||||||
 | 
					                  meta:
 | 
				
			||||||
 | 
					                    type: object
 | 
				
			||||||
 | 
					                    $ref: '#/components/schemas/Meta'
 | 
				
			||||||
        401:
 | 
					        401:
 | 
				
			||||||
          $ref: "#/components/responses/401"
 | 
					          $ref: "#/components/responses/401"
 | 
				
			||||||
        403:
 | 
					        403:
 | 
				
			||||||
@ -6100,7 +6236,15 @@ paths:
 | 
				
			|||||||
          content:
 | 
					          content:
 | 
				
			||||||
            application/json:
 | 
					            application/json:
 | 
				
			||||||
              schema:  
 | 
					              schema:  
 | 
				
			||||||
                $ref: "#/components/schemas/SystemLog"
 | 
					                type: object
 | 
				
			||||||
 | 
					                properties:
 | 
				
			||||||
 | 
					                  data: 
 | 
				
			||||||
 | 
					                    type: array
 | 
				
			||||||
 | 
					                    items:
 | 
				
			||||||
 | 
					                      $ref: '#/components/schemas/SystemLog'
 | 
				
			||||||
 | 
					                  meta:
 | 
				
			||||||
 | 
					                    type: object
 | 
				
			||||||
 | 
					                    $ref: '#/components/schemas/Meta'
 | 
				
			||||||
        401:
 | 
					        401:
 | 
				
			||||||
          $ref: "#/components/responses/401"
 | 
					          $ref: "#/components/responses/401"
 | 
				
			||||||
        403:
 | 
					        403:
 | 
				
			||||||
@ -6405,7 +6549,15 @@ paths:
 | 
				
			|||||||
          content:
 | 
					          content:
 | 
				
			||||||
            application/json:
 | 
					            application/json:
 | 
				
			||||||
              schema:  
 | 
					              schema:  
 | 
				
			||||||
                $ref: "#/components/schemas/TaskStatus"
 | 
					                type: object
 | 
				
			||||||
 | 
					                properties:
 | 
				
			||||||
 | 
					                  data: 
 | 
				
			||||||
 | 
					                    type: array
 | 
				
			||||||
 | 
					                    items:
 | 
				
			||||||
 | 
					                      $ref: '#/components/schemas/TaskStatus'
 | 
				
			||||||
 | 
					                  meta:
 | 
				
			||||||
 | 
					                    type: object
 | 
				
			||||||
 | 
					                    $ref: '#/components/schemas/Meta'
 | 
				
			||||||
        401:
 | 
					        401:
 | 
				
			||||||
          $ref: "#/components/responses/401"
 | 
					          $ref: "#/components/responses/401"
 | 
				
			||||||
        403:
 | 
					        403:
 | 
				
			||||||
@ -6710,7 +6862,15 @@ paths:
 | 
				
			|||||||
          content:
 | 
					          content:
 | 
				
			||||||
            application/json:
 | 
					            application/json:
 | 
				
			||||||
              schema:  
 | 
					              schema:  
 | 
				
			||||||
                $ref: "#/components/schemas/TaxRate"
 | 
					                type: object
 | 
				
			||||||
 | 
					                properties:
 | 
				
			||||||
 | 
					                  data: 
 | 
				
			||||||
 | 
					                    type: array
 | 
				
			||||||
 | 
					                    items:
 | 
				
			||||||
 | 
					                      $ref: '#/components/schemas/TaxRate'
 | 
				
			||||||
 | 
					                  meta:
 | 
				
			||||||
 | 
					                    type: object
 | 
				
			||||||
 | 
					                    $ref: '#/components/schemas/Meta'
 | 
				
			||||||
        401:
 | 
					        401:
 | 
				
			||||||
          $ref: "#/components/responses/401"
 | 
					          $ref: "#/components/responses/401"
 | 
				
			||||||
        403:
 | 
					        403:
 | 
				
			||||||
@ -7019,7 +7179,15 @@ paths:
 | 
				
			|||||||
          content:
 | 
					          content:
 | 
				
			||||||
            application/json:
 | 
					            application/json:
 | 
				
			||||||
              schema:  
 | 
					              schema:  
 | 
				
			||||||
                $ref: "#/components/schemas/CompanyToken"
 | 
					                type: object
 | 
				
			||||||
 | 
					                properties:
 | 
				
			||||||
 | 
					                  data: 
 | 
				
			||||||
 | 
					                    type: array
 | 
				
			||||||
 | 
					                    items:
 | 
				
			||||||
 | 
					                      $ref: '#/components/schemas/CompanyToken'
 | 
				
			||||||
 | 
					                  meta:
 | 
				
			||||||
 | 
					                    type: object
 | 
				
			||||||
 | 
					                    $ref: '#/components/schemas/Meta'
 | 
				
			||||||
        401:
 | 
					        401:
 | 
				
			||||||
          $ref: "#/components/responses/401"
 | 
					          $ref: "#/components/responses/401"
 | 
				
			||||||
        403:
 | 
					        403:
 | 
				
			||||||
@ -7319,7 +7487,15 @@ paths:
 | 
				
			|||||||
          content:
 | 
					          content:
 | 
				
			||||||
            application/json:
 | 
					            application/json:
 | 
				
			||||||
              schema:  
 | 
					              schema:  
 | 
				
			||||||
                $ref: "#/components/schemas/User"
 | 
					                type: object
 | 
				
			||||||
 | 
					                properties:
 | 
				
			||||||
 | 
					                  data: 
 | 
				
			||||||
 | 
					                    type: array
 | 
				
			||||||
 | 
					                    items:
 | 
				
			||||||
 | 
					                      $ref: '#/components/schemas/User'
 | 
				
			||||||
 | 
					                  meta:
 | 
				
			||||||
 | 
					                    type: object
 | 
				
			||||||
 | 
					                    $ref: '#/components/schemas/Meta'
 | 
				
			||||||
        401:
 | 
					        401:
 | 
				
			||||||
          $ref: "#/components/responses/401"
 | 
					          $ref: "#/components/responses/401"
 | 
				
			||||||
        403:
 | 
					        403:
 | 
				
			||||||
@ -7767,7 +7943,15 @@ paths:
 | 
				
			|||||||
          content:
 | 
					          content:
 | 
				
			||||||
            application/json:
 | 
					            application/json:
 | 
				
			||||||
              schema:  
 | 
					              schema:  
 | 
				
			||||||
                $ref: "#/components/schemas/Webhook"
 | 
					                type: object
 | 
				
			||||||
 | 
					                properties:
 | 
				
			||||||
 | 
					                  data: 
 | 
				
			||||||
 | 
					                    type: array
 | 
				
			||||||
 | 
					                    items:
 | 
				
			||||||
 | 
					                      $ref: '#/components/schemas/Webhook'
 | 
				
			||||||
 | 
					                  meta:
 | 
				
			||||||
 | 
					                    type: object
 | 
				
			||||||
 | 
					                    $ref: '#/components/schemas/Meta'
 | 
				
			||||||
        401:
 | 
					        401:
 | 
				
			||||||
          $ref: "#/components/responses/401"
 | 
					          $ref: "#/components/responses/401"
 | 
				
			||||||
        403:
 | 
					        403:
 | 
				
			||||||
@ -8099,7 +8283,15 @@ paths:
 | 
				
			|||||||
          content:
 | 
					          content:
 | 
				
			||||||
            application/json:
 | 
					            application/json:
 | 
				
			||||||
              schema:  
 | 
					              schema:  
 | 
				
			||||||
                $ref: "#/components/schemas/Product"
 | 
					                type: object
 | 
				
			||||||
 | 
					                properties:
 | 
				
			||||||
 | 
					                  data: 
 | 
				
			||||||
 | 
					                    type: array
 | 
				
			||||||
 | 
					                    items:
 | 
				
			||||||
 | 
					                      $ref: '#/components/schemas/Product'
 | 
				
			||||||
 | 
					                  meta:
 | 
				
			||||||
 | 
					                    type: object
 | 
				
			||||||
 | 
					                    $ref: '#/components/schemas/Meta'
 | 
				
			||||||
        401:
 | 
					        401:
 | 
				
			||||||
          $ref: '#/components/responses/401'
 | 
					          $ref: '#/components/responses/401'
 | 
				
			||||||
        403:
 | 
					        403:
 | 
				
			||||||
@ -8504,7 +8696,15 @@ paths:
 | 
				
			|||||||
          content:
 | 
					          content:
 | 
				
			||||||
            application/json:
 | 
					            application/json:
 | 
				
			||||||
              schema:  
 | 
					              schema:  
 | 
				
			||||||
                $ref: "#/components/schemas/Task"
 | 
					                type: object
 | 
				
			||||||
 | 
					                properties:
 | 
				
			||||||
 | 
					                  data: 
 | 
				
			||||||
 | 
					                    type: array
 | 
				
			||||||
 | 
					                    items:
 | 
				
			||||||
 | 
					                      $ref: '#/components/schemas/Task'
 | 
				
			||||||
 | 
					                  meta:
 | 
				
			||||||
 | 
					                    type: object
 | 
				
			||||||
 | 
					                    $ref: '#/components/schemas/Meta'
 | 
				
			||||||
        401:
 | 
					        401:
 | 
				
			||||||
          $ref: "#/components/responses/401"
 | 
					          $ref: "#/components/responses/401"
 | 
				
			||||||
        403:
 | 
					        403:
 | 
				
			||||||
@ -8915,7 +9115,15 @@ paths:
 | 
				
			|||||||
          content:
 | 
					          content:
 | 
				
			||||||
            application/json:
 | 
					            application/json:
 | 
				
			||||||
              schema:  
 | 
					              schema:  
 | 
				
			||||||
                $ref: "#/components/schemas/Project"
 | 
					                type: object
 | 
				
			||||||
 | 
					                properties:
 | 
				
			||||||
 | 
					                  data: 
 | 
				
			||||||
 | 
					                    type: array
 | 
				
			||||||
 | 
					                    items:
 | 
				
			||||||
 | 
					                      $ref: '#/components/schemas/Project'
 | 
				
			||||||
 | 
					                  meta:
 | 
				
			||||||
 | 
					                    type: object
 | 
				
			||||||
 | 
					                    $ref: '#/components/schemas/Meta'
 | 
				
			||||||
        401:
 | 
					        401:
 | 
				
			||||||
          $ref: "#/components/responses/401"
 | 
					          $ref: "#/components/responses/401"
 | 
				
			||||||
        403:
 | 
					        403:
 | 
				
			||||||
@ -9388,7 +9596,19 @@ paths:
 | 
				
			|||||||
          content:
 | 
					          content:
 | 
				
			||||||
            application/json:
 | 
					            application/json:
 | 
				
			||||||
              schema:  
 | 
					              schema:  
 | 
				
			||||||
 | 
					                type: object
 | 
				
			||||||
 | 
					                properties:
 | 
				
			||||||
 | 
					                  data: 
 | 
				
			||||||
 | 
					                    type: array
 | 
				
			||||||
 | 
					                    items:
 | 
				
			||||||
                      $ref: '#/components/schemas/Client'
 | 
					                      $ref: '#/components/schemas/Client'
 | 
				
			||||||
 | 
					                    example:
 | 
				
			||||||
 | 
					                      $ref: '#/components/examples/Client'
 | 
				
			||||||
 | 
					                  meta:
 | 
				
			||||||
 | 
					                    type: object
 | 
				
			||||||
 | 
					                    $ref: '#/components/schemas/Meta'
 | 
				
			||||||
 | 
					                    example:
 | 
				
			||||||
 | 
					                      $ref: '#/components/examples/Meta'
 | 
				
			||||||
        401:
 | 
					        401:
 | 
				
			||||||
          $ref: '#/components/responses/401'
 | 
					          $ref: '#/components/responses/401'
 | 
				
			||||||
        403:
 | 
					        403:
 | 
				
			||||||
@ -9937,7 +10157,15 @@ paths:
 | 
				
			|||||||
          content:
 | 
					          content:
 | 
				
			||||||
            application/json:
 | 
					            application/json:
 | 
				
			||||||
              schema:  
 | 
					              schema:  
 | 
				
			||||||
                $ref: "#/components/schemas/Credit"
 | 
					                type: object
 | 
				
			||||||
 | 
					                properties:
 | 
				
			||||||
 | 
					                  data: 
 | 
				
			||||||
 | 
					                    type: array
 | 
				
			||||||
 | 
					                    items:
 | 
				
			||||||
 | 
					                      $ref: '#/components/schemas/Credit'
 | 
				
			||||||
 | 
					                  meta:
 | 
				
			||||||
 | 
					                    type: object
 | 
				
			||||||
 | 
					                    $ref: '#/components/schemas/Meta'
 | 
				
			||||||
        401:
 | 
					        401:
 | 
				
			||||||
          $ref: "#/components/responses/401"
 | 
					          $ref: "#/components/responses/401"
 | 
				
			||||||
        403:
 | 
					        403:
 | 
				
			||||||
@ -10396,7 +10624,15 @@ paths:
 | 
				
			|||||||
          content:
 | 
					          content:
 | 
				
			||||||
            application/json:
 | 
					            application/json:
 | 
				
			||||||
              schema:  
 | 
					              schema:  
 | 
				
			||||||
                $ref: "#/components/schemas/Payment"
 | 
					                type: object
 | 
				
			||||||
 | 
					                properties:
 | 
				
			||||||
 | 
					                  data: 
 | 
				
			||||||
 | 
					                    type: array
 | 
				
			||||||
 | 
					                    items:
 | 
				
			||||||
 | 
					                      $ref: '#/components/schemas/Payment'
 | 
				
			||||||
 | 
					                  meta:
 | 
				
			||||||
 | 
					                    type: object
 | 
				
			||||||
 | 
					                    $ref: '#/components/schemas/Meta'
 | 
				
			||||||
        401:
 | 
					        401:
 | 
				
			||||||
          $ref: "#/components/responses/401"
 | 
					          $ref: "#/components/responses/401"
 | 
				
			||||||
        403:
 | 
					        403:
 | 
				
			||||||
@ -10965,7 +11201,15 @@ paths:
 | 
				
			|||||||
          content:
 | 
					          content:
 | 
				
			||||||
            application/json:
 | 
					            application/json:
 | 
				
			||||||
              schema:  
 | 
					              schema:  
 | 
				
			||||||
                $ref: "#/components/schemas/Invoice"
 | 
					                type: object
 | 
				
			||||||
 | 
					                properties:
 | 
				
			||||||
 | 
					                  data: 
 | 
				
			||||||
 | 
					                    type: array
 | 
				
			||||||
 | 
					                    items:
 | 
				
			||||||
 | 
					                      $ref: '#/components/schemas/Invoice'
 | 
				
			||||||
 | 
					                  meta:
 | 
				
			||||||
 | 
					                    type: object
 | 
				
			||||||
 | 
					                    $ref: '#/components/schemas/Meta'
 | 
				
			||||||
        401:
 | 
					        401:
 | 
				
			||||||
          $ref: "#/components/responses/401"
 | 
					          $ref: "#/components/responses/401"
 | 
				
			||||||
        403:
 | 
					        403:
 | 
				
			||||||
@ -11594,7 +11838,15 @@ paths:
 | 
				
			|||||||
          content:
 | 
					          content:
 | 
				
			||||||
            application/json:
 | 
					            application/json:
 | 
				
			||||||
              schema:  
 | 
					              schema:  
 | 
				
			||||||
                $ref: "#/components/schemas/RecurringInvoice"
 | 
					                type: object
 | 
				
			||||||
 | 
					                properties:
 | 
				
			||||||
 | 
					                  data: 
 | 
				
			||||||
 | 
					                    type: array
 | 
				
			||||||
 | 
					                    items:
 | 
				
			||||||
 | 
					                      $ref: '#/components/schemas/RecurringInvoice'
 | 
				
			||||||
 | 
					                  meta:
 | 
				
			||||||
 | 
					                    type: object
 | 
				
			||||||
 | 
					                    $ref: '#/components/schemas/Meta'
 | 
				
			||||||
        401:
 | 
					        401:
 | 
				
			||||||
          $ref: "#/components/responses/401"
 | 
					          $ref: "#/components/responses/401"
 | 
				
			||||||
        403:
 | 
					        403:
 | 
				
			||||||
@ -12141,7 +12393,15 @@ paths:
 | 
				
			|||||||
          content:
 | 
					          content:
 | 
				
			||||||
            application/json:
 | 
					            application/json:
 | 
				
			||||||
              schema:  
 | 
					              schema:  
 | 
				
			||||||
                $ref: "#/components/schemas/Quote"
 | 
					                type: object
 | 
				
			||||||
 | 
					                properties:
 | 
				
			||||||
 | 
					                  data: 
 | 
				
			||||||
 | 
					                    type: array
 | 
				
			||||||
 | 
					                    items:
 | 
				
			||||||
 | 
					                      $ref: '#/components/schemas/Quote'
 | 
				
			||||||
 | 
					                  meta:
 | 
				
			||||||
 | 
					                    type: object
 | 
				
			||||||
 | 
					                    $ref: '#/components/schemas/Meta'
 | 
				
			||||||
        401:
 | 
					        401:
 | 
				
			||||||
          $ref: "#/components/responses/401"
 | 
					          $ref: "#/components/responses/401"
 | 
				
			||||||
        403:
 | 
					        403:
 | 
				
			||||||
@ -12613,7 +12873,15 @@ paths:
 | 
				
			|||||||
          content:
 | 
					          content:
 | 
				
			||||||
            application/json:
 | 
					            application/json:
 | 
				
			||||||
              schema:  
 | 
					              schema:  
 | 
				
			||||||
                $ref: "#/components/schemas/Credit"
 | 
					                type: object
 | 
				
			||||||
 | 
					                properties:
 | 
				
			||||||
 | 
					                  data: 
 | 
				
			||||||
 | 
					                    type: array
 | 
				
			||||||
 | 
					                    items:
 | 
				
			||||||
 | 
					                      $ref: '#/components/schemas/PurchaseOrder'
 | 
				
			||||||
 | 
					                  meta:
 | 
				
			||||||
 | 
					                    type: object
 | 
				
			||||||
 | 
					                    $ref: '#/components/schemas/Meta'
 | 
				
			||||||
        401:
 | 
					        401:
 | 
				
			||||||
          $ref: "#/components/responses/401"
 | 
					          $ref: "#/components/responses/401"
 | 
				
			||||||
        403:
 | 
					        403:
 | 
				
			||||||
@ -12649,7 +12917,7 @@ paths:
 | 
				
			|||||||
          content:
 | 
					          content:
 | 
				
			||||||
            application/json:
 | 
					            application/json:
 | 
				
			||||||
              schema:
 | 
					              schema:
 | 
				
			||||||
                $ref: "#/components/schemas/Credit"
 | 
					                $ref: "#/components/schemas/PurchaseOrder"
 | 
				
			||||||
        401:
 | 
					        401:
 | 
				
			||||||
          $ref: "#/components/responses/401"
 | 
					          $ref: "#/components/responses/401"
 | 
				
			||||||
        403:
 | 
					        403:
 | 
				
			||||||
@ -12695,7 +12963,7 @@ paths:
 | 
				
			|||||||
          content:
 | 
					          content:
 | 
				
			||||||
            application/json:
 | 
					            application/json:
 | 
				
			||||||
              schema:
 | 
					              schema:
 | 
				
			||||||
                $ref: "#/components/schemas/Credit"
 | 
					                $ref: "#/components/schemas/PurchaseOrder"
 | 
				
			||||||
        401:
 | 
					        401:
 | 
				
			||||||
          $ref: "#/components/responses/401"
 | 
					          $ref: "#/components/responses/401"
 | 
				
			||||||
        403:
 | 
					        403:
 | 
				
			||||||
@ -12740,7 +13008,7 @@ paths:
 | 
				
			|||||||
          content:
 | 
					          content:
 | 
				
			||||||
            application/json:
 | 
					            application/json:
 | 
				
			||||||
              schema:
 | 
					              schema:
 | 
				
			||||||
                $ref: "#/components/schemas/Credit"
 | 
					                $ref: "#/components/schemas/PurchaseOrder"
 | 
				
			||||||
        401:
 | 
					        401:
 | 
				
			||||||
          $ref: "#/components/responses/401"
 | 
					          $ref: "#/components/responses/401"
 | 
				
			||||||
        403:
 | 
					        403:
 | 
				
			||||||
@ -12825,7 +13093,7 @@ paths:
 | 
				
			|||||||
          content:
 | 
					          content:
 | 
				
			||||||
            application/json:
 | 
					            application/json:
 | 
				
			||||||
              schema:
 | 
					              schema:
 | 
				
			||||||
                $ref: "#/components/schemas/Invoice"
 | 
					                $ref: "#/components/schemas/PurchaseOrder"
 | 
				
			||||||
        401:
 | 
					        401:
 | 
				
			||||||
          $ref: "#/components/responses/401"
 | 
					          $ref: "#/components/responses/401"
 | 
				
			||||||
        403:
 | 
					        403:
 | 
				
			||||||
@ -12863,7 +13131,7 @@ paths:
 | 
				
			|||||||
          content:
 | 
					          content:
 | 
				
			||||||
            application/json:
 | 
					            application/json:
 | 
				
			||||||
              schema:
 | 
					              schema:
 | 
				
			||||||
                $ref: "#/components/schemas/Credit"
 | 
					                $ref: "#/components/schemas/PurchaseOrder"
 | 
				
			||||||
        401:
 | 
					        401:
 | 
				
			||||||
          $ref: "#/components/responses/401"
 | 
					          $ref: "#/components/responses/401"
 | 
				
			||||||
        403:
 | 
					        403:
 | 
				
			||||||
@ -12950,7 +13218,7 @@ paths:
 | 
				
			|||||||
          example: clone_to_quote
 | 
					          example: clone_to_quote
 | 
				
			||||||
      responses:
 | 
					      responses:
 | 
				
			||||||
        200:
 | 
					        200:
 | 
				
			||||||
          description: "Returns the invoice object"
 | 
					          description: "Returns the purchase order object"
 | 
				
			||||||
          headers:
 | 
					          headers:
 | 
				
			||||||
            X-MINIMUM-CLIENT-VERSION:
 | 
					            X-MINIMUM-CLIENT-VERSION:
 | 
				
			||||||
              $ref: "#/components/headers/X-MINIMUM-CLIENT-VERSION"
 | 
					              $ref: "#/components/headers/X-MINIMUM-CLIENT-VERSION"
 | 
				
			||||||
@ -12961,7 +13229,7 @@ paths:
 | 
				
			|||||||
          content:
 | 
					          content:
 | 
				
			||||||
            application/json:
 | 
					            application/json:
 | 
				
			||||||
              schema:
 | 
					              schema:
 | 
				
			||||||
                $ref: "#/components/schemas/Invoice"
 | 
					                $ref: "#/components/schemas/PurchaseOrder"
 | 
				
			||||||
        401:
 | 
					        401:
 | 
				
			||||||
          $ref: "#/components/responses/401"
 | 
					          $ref: "#/components/responses/401"
 | 
				
			||||||
        403:
 | 
					        403:
 | 
				
			||||||
@ -13006,7 +13274,7 @@ paths:
 | 
				
			|||||||
          content:
 | 
					          content:
 | 
				
			||||||
            application/json:
 | 
					            application/json:
 | 
				
			||||||
              schema:
 | 
					              schema:
 | 
				
			||||||
                $ref: "#/components/schemas/Vendor"
 | 
					                $ref: "#/components/schemas/PurchaseOrder"
 | 
				
			||||||
        401:
 | 
					        401:
 | 
				
			||||||
          $ref: "#/components/responses/401"
 | 
					          $ref: "#/components/responses/401"
 | 
				
			||||||
        403:
 | 
					        403:
 | 
				
			||||||
@ -13085,7 +13353,15 @@ paths:
 | 
				
			|||||||
          content:
 | 
					          content:
 | 
				
			||||||
            application/json:
 | 
					            application/json:
 | 
				
			||||||
              schema:  
 | 
					              schema:  
 | 
				
			||||||
                $ref: "#/components/schemas/Vendor"
 | 
					                type: object
 | 
				
			||||||
 | 
					                properties:
 | 
				
			||||||
 | 
					                  data: 
 | 
				
			||||||
 | 
					                    type: array
 | 
				
			||||||
 | 
					                    items:
 | 
				
			||||||
 | 
					                      $ref: '#/components/schemas/Vendor'
 | 
				
			||||||
 | 
					                  meta:
 | 
				
			||||||
 | 
					                    type: object
 | 
				
			||||||
 | 
					                    $ref: '#/components/schemas/Meta'
 | 
				
			||||||
        401:
 | 
					        401:
 | 
				
			||||||
          $ref: "#/components/responses/401"
 | 
					          $ref: "#/components/responses/401"
 | 
				
			||||||
        403:
 | 
					        403:
 | 
				
			||||||
@ -13459,6 +13735,78 @@ components:
 | 
				
			|||||||
      in: header       
 | 
					      in: header       
 | 
				
			||||||
      name: X-API-TOKEN 
 | 
					      name: X-API-TOKEN 
 | 
				
			||||||
  responses:
 | 
					  responses:
 | 
				
			||||||
 | 
					  examples:
 | 
				
			||||||
 | 
					    Client:
 | 
				
			||||||
 | 
					      - id: Opnel5aKBz
 | 
				
			||||||
 | 
					        user_id: Ua6Rw4pVbS
 | 
				
			||||||
 | 
					        assigned_user_id: Ua6Rw4pVbS
 | 
				
			||||||
 | 
					        company_id: Co7Vn3yLmW
 | 
				
			||||||
 | 
					        name: "Jim's Housekeeping"
 | 
				
			||||||
 | 
					        website: https://www.jims-housekeeping.com
 | 
				
			||||||
 | 
					        private_notes: Client prefers email communication over phone calls
 | 
				
			||||||
 | 
					        client_hash: asdfkjhk342hjhbfdvmnfb1
 | 
				
			||||||
 | 
					        industry_id: 5
 | 
				
			||||||
 | 
					        size_id: 2
 | 
				
			||||||
 | 
					        address1: 123 Main St
 | 
				
			||||||
 | 
					        address2: Apt 4B
 | 
				
			||||||
 | 
					        city: Beverly Hills
 | 
				
			||||||
 | 
					        state: California
 | 
				
			||||||
 | 
					        postal_code: 90210
 | 
				
			||||||
 | 
					        phone: 555-3434-3434
 | 
				
			||||||
 | 
					        country_id: 1
 | 
				
			||||||
 | 
					        custom_value1: Email
 | 
				
			||||||
 | 
					        custom_value2: John Doe
 | 
				
			||||||
 | 
					        custom_value3: Yes
 | 
				
			||||||
 | 
					        custom_value4: $50,000
 | 
				
			||||||
 | 
					        vat_number: VAT123456
 | 
				
			||||||
 | 
					        id_number: ID123456
 | 
				
			||||||
 | 
					        number: CL-0001
 | 
				
			||||||
 | 
					        shipping_address1: 5 Wallaby Way
 | 
				
			||||||
 | 
					        shipping_address2: Suite 5
 | 
				
			||||||
 | 
					        shipping_city: Perth
 | 
				
			||||||
 | 
					        shipping_state: Western Australia
 | 
				
			||||||
 | 
					        shipping_postal_code: 6110
 | 
				
			||||||
 | 
					        shipping_country_id: 4
 | 
				
			||||||
 | 
					        is_deleted: false
 | 
				
			||||||
 | 
					        balance: 500.00
 | 
				
			||||||
 | 
					        paid_to_date: 2000.00
 | 
				
			||||||
 | 
					        credit_balance: 100.00
 | 
				
			||||||
 | 
					        last_login: 1628686031
 | 
				
			||||||
 | 
					        created_at: 1617629031
 | 
				
			||||||
 | 
					        updated_at: 1628445631
 | 
				
			||||||
 | 
					        group_settings_id: Opnel5aKBz
 | 
				
			||||||
 | 
					        routing_id: Opnel5aKBz3489-dfkiu-2239-sdsd
 | 
				
			||||||
 | 
					        is_tax_exempt: false
 | 
				
			||||||
 | 
					        has_valid_vat_number: false
 | 
				
			||||||
 | 
					        payment_balance: 100
 | 
				
			||||||
 | 
					        contacts:
 | 
				
			||||||
 | 
					          - id: Opnel5aKBz
 | 
				
			||||||
 | 
					            first_name: John
 | 
				
			||||||
 | 
					            last_name: Doe
 | 
				
			||||||
 | 
					            email: jim@gmail.com
 | 
				
			||||||
 | 
					            phone: 555-3434-3434
 | 
				
			||||||
 | 
					            send_invoice: true
 | 
				
			||||||
 | 
					            custom_value1: Email
 | 
				
			||||||
 | 
					            custom_value2: John Doe
 | 
				
			||||||
 | 
					            custom_value3: Yes
 | 
				
			||||||
 | 
					            custom_value4: $50,000
 | 
				
			||||||
 | 
					            is_primary: true
 | 
				
			||||||
 | 
					            created_at: 1617629031
 | 
				
			||||||
 | 
					            updated_at: 1628445631
 | 
				
			||||||
 | 
					            deleted_at: 1628445631
 | 
				
			||||||
 | 
					    Meta:
 | 
				
			||||||
 | 
					      value:
 | 
				
			||||||
 | 
					        pagination:
 | 
				
			||||||
 | 
					          total: 1
 | 
				
			||||||
 | 
					          count: 1
 | 
				
			||||||
 | 
					          per_page: 20
 | 
				
			||||||
 | 
					          current_page: 1
 | 
				
			||||||
 | 
					          total_pages: 1
 | 
				
			||||||
 | 
					          links:
 | 
				
			||||||
 | 
					            - first: https://invoicing.co/api/v1/invoices?page=1
 | 
				
			||||||
 | 
					            - last: https://invoicing.co/api/v1/invoices?page=1
 | 
				
			||||||
 | 
					            - prev: null
 | 
				
			||||||
 | 
					            - next: null
 | 
				
			||||||
    429:
 | 
					    429:
 | 
				
			||||||
      description: 'Rate Limit Exceeded'
 | 
					      description: 'Rate Limit Exceeded'
 | 
				
			||||||
      content:
 | 
					      content:
 | 
				
			||||||
@ -16613,6 +16961,42 @@ components:
 | 
				
			|||||||
          type: integer
 | 
					          type: integer
 | 
				
			||||||
          example: '1'
 | 
					          example: '1'
 | 
				
			||||||
      type: object
 | 
					      type: object
 | 
				
			||||||
 | 
					    Meta:
 | 
				
			||||||
 | 
					      properties:
 | 
				
			||||||
 | 
					        pagination:
 | 
				
			||||||
 | 
					          $ref: '#/components/schemas/Pagination'
 | 
				
			||||||
 | 
					    Pagination:
 | 
				
			||||||
 | 
					      type: object
 | 
				
			||||||
 | 
					      properties:
 | 
				
			||||||
 | 
					        total:
 | 
				
			||||||
 | 
					          type: integer
 | 
				
			||||||
 | 
					          description: 'The total number of items'
 | 
				
			||||||
 | 
					          example: 1
 | 
				
			||||||
 | 
					          readOnly: true
 | 
				
			||||||
 | 
					        count:
 | 
				
			||||||
 | 
					          type: integer
 | 
				
			||||||
 | 
					          description: 'The number of items per page'
 | 
				
			||||||
 | 
					          example: 1
 | 
				
			||||||
 | 
					          readOnly: true
 | 
				
			||||||
 | 
					        per_page:
 | 
				
			||||||
 | 
					          type: integer
 | 
				
			||||||
 | 
					          description: 'The number of items per page'
 | 
				
			||||||
 | 
					          example: 1
 | 
				
			||||||
 | 
					          readOnly: true
 | 
				
			||||||
 | 
					        current_page:
 | 
				
			||||||
 | 
					          type: integer
 | 
				
			||||||
 | 
					          description: 'The current page number'
 | 
				
			||||||
 | 
					          example: 1
 | 
				
			||||||
 | 
					          readOnly: true
 | 
				
			||||||
 | 
					        total_pages:
 | 
				
			||||||
 | 
					          type: integer
 | 
				
			||||||
 | 
					          description: 'The total number of pages'
 | 
				
			||||||
 | 
					          example: 1
 | 
				
			||||||
 | 
					          readOnly: true
 | 
				
			||||||
 | 
					        links:
 | 
				
			||||||
 | 
					          type: array
 | 
				
			||||||
 | 
					          description: 'The pagination links'
 | 
				
			||||||
 | 
					          readOnly: true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    FeesAndLimits:
 | 
					    FeesAndLimits:
 | 
				
			||||||
      properties:
 | 
					      properties:
 | 
				
			||||||
@ -18597,8 +18981,6 @@ components:
 | 
				
			|||||||
          type: string
 | 
					          type: string
 | 
				
			||||||
          format: date
 | 
					          format: date
 | 
				
			||||||
          example: '1994-07-30'
 | 
					          example: '1994-07-30'
 | 
				
			||||||
        settings:
 | 
					 | 
				
			||||||
          $ref: '#/components/schemas/CompanySettings'
 | 
					 | 
				
			||||||
        last_viewed:
 | 
					        last_viewed:
 | 
				
			||||||
          description: Timestamp
 | 
					          description: Timestamp
 | 
				
			||||||
          type: number
 | 
					          type: number
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										72
									
								
								openapi/components/examples.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								openapi/components/examples.yaml
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,72 @@
 | 
				
			|||||||
 | 
					  examples:
 | 
				
			||||||
 | 
					    Client:
 | 
				
			||||||
 | 
					      - id: Opnel5aKBz
 | 
				
			||||||
 | 
					        user_id: Ua6Rw4pVbS
 | 
				
			||||||
 | 
					        assigned_user_id: Ua6Rw4pVbS
 | 
				
			||||||
 | 
					        company_id: Co7Vn3yLmW
 | 
				
			||||||
 | 
					        name: "Jim's Housekeeping"
 | 
				
			||||||
 | 
					        website: https://www.jims-housekeeping.com
 | 
				
			||||||
 | 
					        private_notes: Client prefers email communication over phone calls
 | 
				
			||||||
 | 
					        client_hash: asdfkjhk342hjhbfdvmnfb1
 | 
				
			||||||
 | 
					        industry_id: 5
 | 
				
			||||||
 | 
					        size_id: 2
 | 
				
			||||||
 | 
					        address1: 123 Main St
 | 
				
			||||||
 | 
					        address2: Apt 4B
 | 
				
			||||||
 | 
					        city: Beverly Hills
 | 
				
			||||||
 | 
					        state: California
 | 
				
			||||||
 | 
					        postal_code: 90210
 | 
				
			||||||
 | 
					        phone: 555-3434-3434
 | 
				
			||||||
 | 
					        country_id: 1
 | 
				
			||||||
 | 
					        custom_value1: Email
 | 
				
			||||||
 | 
					        custom_value2: John Doe
 | 
				
			||||||
 | 
					        custom_value3: Yes
 | 
				
			||||||
 | 
					        custom_value4: $50,000
 | 
				
			||||||
 | 
					        vat_number: VAT123456
 | 
				
			||||||
 | 
					        id_number: ID123456
 | 
				
			||||||
 | 
					        number: CL-0001
 | 
				
			||||||
 | 
					        shipping_address1: 5 Wallaby Way
 | 
				
			||||||
 | 
					        shipping_address2: Suite 5
 | 
				
			||||||
 | 
					        shipping_city: Perth
 | 
				
			||||||
 | 
					        shipping_state: Western Australia
 | 
				
			||||||
 | 
					        shipping_postal_code: 6110
 | 
				
			||||||
 | 
					        shipping_country_id: 4
 | 
				
			||||||
 | 
					        is_deleted: false
 | 
				
			||||||
 | 
					        balance: 500.00
 | 
				
			||||||
 | 
					        paid_to_date: 2000.00
 | 
				
			||||||
 | 
					        credit_balance: 100.00
 | 
				
			||||||
 | 
					        last_login: 1628686031
 | 
				
			||||||
 | 
					        created_at: 1617629031
 | 
				
			||||||
 | 
					        updated_at: 1628445631
 | 
				
			||||||
 | 
					        group_settings_id: Opnel5aKBz
 | 
				
			||||||
 | 
					        routing_id: Opnel5aKBz3489-dfkiu-2239-sdsd
 | 
				
			||||||
 | 
					        is_tax_exempt: false
 | 
				
			||||||
 | 
					        has_valid_vat_number: false
 | 
				
			||||||
 | 
					        payment_balance: 100
 | 
				
			||||||
 | 
					        contacts:
 | 
				
			||||||
 | 
					          - id: Opnel5aKBz
 | 
				
			||||||
 | 
					            first_name: John
 | 
				
			||||||
 | 
					            last_name: Doe
 | 
				
			||||||
 | 
					            email: jim@gmail.com
 | 
				
			||||||
 | 
					            phone: 555-3434-3434
 | 
				
			||||||
 | 
					            send_invoice: true
 | 
				
			||||||
 | 
					            custom_value1: Email
 | 
				
			||||||
 | 
					            custom_value2: John Doe
 | 
				
			||||||
 | 
					            custom_value3: Yes
 | 
				
			||||||
 | 
					            custom_value4: $50,000
 | 
				
			||||||
 | 
					            is_primary: true
 | 
				
			||||||
 | 
					            created_at: 1617629031
 | 
				
			||||||
 | 
					            updated_at: 1628445631
 | 
				
			||||||
 | 
					            deleted_at: 1628445631
 | 
				
			||||||
 | 
					    Meta:
 | 
				
			||||||
 | 
					      value:
 | 
				
			||||||
 | 
					        pagination:
 | 
				
			||||||
 | 
					          total: 1
 | 
				
			||||||
 | 
					          count: 1
 | 
				
			||||||
 | 
					          per_page: 20
 | 
				
			||||||
 | 
					          current_page: 1
 | 
				
			||||||
 | 
					          total_pages: 1
 | 
				
			||||||
 | 
					          links:
 | 
				
			||||||
 | 
					            - first: https://invoicing.co/api/v1/invoices?page=1
 | 
				
			||||||
 | 
					            - last: https://invoicing.co/api/v1/invoices?page=1
 | 
				
			||||||
 | 
					            - prev: null
 | 
				
			||||||
 | 
					            - next: null
 | 
				
			||||||
@ -168,8 +168,6 @@
 | 
				
			|||||||
          type: string
 | 
					          type: string
 | 
				
			||||||
          format: date
 | 
					          format: date
 | 
				
			||||||
          example: '1994-07-30'
 | 
					          example: '1994-07-30'
 | 
				
			||||||
        settings:
 | 
					 | 
				
			||||||
          $ref: '#/components/schemas/CompanySettings'
 | 
					 | 
				
			||||||
        last_viewed:
 | 
					        last_viewed:
 | 
				
			||||||
          description: Timestamp
 | 
					          description: Timestamp
 | 
				
			||||||
          type: number
 | 
					          type: number
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										36
									
								
								openapi/components/schemas/meta.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								openapi/components/schemas/meta.yaml
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,36 @@
 | 
				
			|||||||
 | 
					    Meta:
 | 
				
			||||||
 | 
					      properties:
 | 
				
			||||||
 | 
					        pagination:
 | 
				
			||||||
 | 
					          $ref: '#/components/schemas/Pagination'
 | 
				
			||||||
 | 
					    Pagination:
 | 
				
			||||||
 | 
					      type: object
 | 
				
			||||||
 | 
					      properties:
 | 
				
			||||||
 | 
					        total:
 | 
				
			||||||
 | 
					          type: integer
 | 
				
			||||||
 | 
					          description: 'The total number of items'
 | 
				
			||||||
 | 
					          example: 1
 | 
				
			||||||
 | 
					          readOnly: true
 | 
				
			||||||
 | 
					        count:
 | 
				
			||||||
 | 
					          type: integer
 | 
				
			||||||
 | 
					          description: 'The number of items per page'
 | 
				
			||||||
 | 
					          example: 1
 | 
				
			||||||
 | 
					          readOnly: true
 | 
				
			||||||
 | 
					        per_page:
 | 
				
			||||||
 | 
					          type: integer
 | 
				
			||||||
 | 
					          description: 'The number of items per page'
 | 
				
			||||||
 | 
					          example: 1
 | 
				
			||||||
 | 
					          readOnly: true
 | 
				
			||||||
 | 
					        current_page:
 | 
				
			||||||
 | 
					          type: integer
 | 
				
			||||||
 | 
					          description: 'The current page number'
 | 
				
			||||||
 | 
					          example: 1
 | 
				
			||||||
 | 
					          readOnly: true
 | 
				
			||||||
 | 
					        total_pages:
 | 
				
			||||||
 | 
					          type: integer
 | 
				
			||||||
 | 
					          description: 'The total number of pages'
 | 
				
			||||||
 | 
					          example: 1
 | 
				
			||||||
 | 
					          readOnly: true
 | 
				
			||||||
 | 
					        links:
 | 
				
			||||||
 | 
					          type: array
 | 
				
			||||||
 | 
					          description: 'The pagination links'
 | 
				
			||||||
 | 
					          readOnly: true
 | 
				
			||||||
@ -15,7 +15,7 @@ paths:
 | 
				
			|||||||
        - $ref: "#/components/parameters/page_meta"
 | 
					        - $ref: "#/components/parameters/page_meta"
 | 
				
			||||||
      responses:
 | 
					      responses:
 | 
				
			||||||
        200:
 | 
					        200:
 | 
				
			||||||
          description: "Returns the client object"
 | 
					          description: "Returns the list of activities"
 | 
				
			||||||
          headers:
 | 
					          headers:
 | 
				
			||||||
            X-MINIMUM-CLIENT-VERSION:
 | 
					            X-MINIMUM-CLIENT-VERSION:
 | 
				
			||||||
              $ref: "#/components/headers/X-MINIMUM-CLIENT-VERSION"
 | 
					              $ref: "#/components/headers/X-MINIMUM-CLIENT-VERSION"
 | 
				
			||||||
@ -26,7 +26,15 @@ paths:
 | 
				
			|||||||
          content:
 | 
					          content:
 | 
				
			||||||
            application/json:
 | 
					            application/json:
 | 
				
			||||||
              schema:  
 | 
					              schema:  
 | 
				
			||||||
                $ref: "#/components/schemas/Client"
 | 
					                type: object
 | 
				
			||||||
 | 
					                properties:
 | 
				
			||||||
 | 
					                  data: 
 | 
				
			||||||
 | 
					                    type: array
 | 
				
			||||||
 | 
					                    items:
 | 
				
			||||||
 | 
					                      $ref: '#/components/schemas/Activity'
 | 
				
			||||||
 | 
					                  meta:
 | 
				
			||||||
 | 
					                    type: object
 | 
				
			||||||
 | 
					                    $ref: '#/components/schemas/Meta'
 | 
				
			||||||
        401:
 | 
					        401:
 | 
				
			||||||
          $ref: "#/components/responses/401"
 | 
					          $ref: "#/components/responses/401"
 | 
				
			||||||
        403:
 | 
					        403:
 | 
				
			||||||
@ -243,7 +251,15 @@ paths:
 | 
				
			|||||||
          content:
 | 
					          content:
 | 
				
			||||||
            application/json:
 | 
					            application/json:
 | 
				
			||||||
              schema:  
 | 
					              schema:  
 | 
				
			||||||
                $ref: "#/components/schemas/BankIntegration"
 | 
					                type: object
 | 
				
			||||||
 | 
					                properties:
 | 
				
			||||||
 | 
					                  data: 
 | 
				
			||||||
 | 
					                    type: array
 | 
				
			||||||
 | 
					                    items:
 | 
				
			||||||
 | 
					                      $ref: '#/components/schemas/BankIntegration'
 | 
				
			||||||
 | 
					                  meta:
 | 
				
			||||||
 | 
					                    type: object
 | 
				
			||||||
 | 
					                    $ref: '#/components/schemas/Meta'
 | 
				
			||||||
        401:
 | 
					        401:
 | 
				
			||||||
          $ref: "#/components/responses/401"
 | 
					          $ref: "#/components/responses/401"
 | 
				
			||||||
        403:
 | 
					        403:
 | 
				
			||||||
@ -647,7 +663,15 @@ paths:
 | 
				
			|||||||
          content:
 | 
					          content:
 | 
				
			||||||
            application/json:
 | 
					            application/json:
 | 
				
			||||||
              schema:  
 | 
					              schema:  
 | 
				
			||||||
                $ref: "#/components/schemas/BankTransaction"
 | 
					                type: object
 | 
				
			||||||
 | 
					                properties:
 | 
				
			||||||
 | 
					                  data: 
 | 
				
			||||||
 | 
					                    type: array
 | 
				
			||||||
 | 
					                    items:
 | 
				
			||||||
 | 
					                      $ref: '#/components/schemas/BankTransaction'
 | 
				
			||||||
 | 
					                  meta:
 | 
				
			||||||
 | 
					                    type: object
 | 
				
			||||||
 | 
					                    $ref: '#/components/schemas/Meta'
 | 
				
			||||||
        401:
 | 
					        401:
 | 
				
			||||||
          $ref: "#/components/responses/401"
 | 
					          $ref: "#/components/responses/401"
 | 
				
			||||||
        403:
 | 
					        403:
 | 
				
			||||||
@ -992,7 +1016,15 @@ paths:
 | 
				
			|||||||
          content:
 | 
					          content:
 | 
				
			||||||
            application/json:
 | 
					            application/json:
 | 
				
			||||||
              schema:  
 | 
					              schema:  
 | 
				
			||||||
                $ref: "#/components/schemas/BankTransactionRule"
 | 
					                type: object
 | 
				
			||||||
 | 
					                properties:
 | 
				
			||||||
 | 
					                  data: 
 | 
				
			||||||
 | 
					                    type: array
 | 
				
			||||||
 | 
					                    items:
 | 
				
			||||||
 | 
					                      $ref: '#/components/schemas/BankTransactionRule'
 | 
				
			||||||
 | 
					                  meta:
 | 
				
			||||||
 | 
					                    type: object
 | 
				
			||||||
 | 
					                    $ref: '#/components/schemas/Meta'
 | 
				
			||||||
        401:
 | 
					        401:
 | 
				
			||||||
          $ref: "#/components/responses/401"
 | 
					          $ref: "#/components/responses/401"
 | 
				
			||||||
        403:
 | 
					        403:
 | 
				
			||||||
@ -1324,7 +1356,15 @@ paths:
 | 
				
			|||||||
          content:
 | 
					          content:
 | 
				
			||||||
            application/json:
 | 
					            application/json:
 | 
				
			||||||
              schema:  
 | 
					              schema:  
 | 
				
			||||||
                $ref: "#/components/schemas/ClientGatewayToken"
 | 
					                type: object
 | 
				
			||||||
 | 
					                properties:
 | 
				
			||||||
 | 
					                  data: 
 | 
				
			||||||
 | 
					                    type: array
 | 
				
			||||||
 | 
					                    items:
 | 
				
			||||||
 | 
					                      $ref: '#/components/schemas/ClientGatewayToken'
 | 
				
			||||||
 | 
					                  meta:
 | 
				
			||||||
 | 
					                    type: object
 | 
				
			||||||
 | 
					                    $ref: '#/components/schemas/Meta'
 | 
				
			||||||
        401:
 | 
					        401:
 | 
				
			||||||
          $ref: "#/components/responses/401"
 | 
					          $ref: "#/components/responses/401"
 | 
				
			||||||
        403:
 | 
					        403:
 | 
				
			||||||
@ -1581,7 +1621,15 @@ paths:
 | 
				
			|||||||
          content:
 | 
					          content:
 | 
				
			||||||
            application/json:
 | 
					            application/json:
 | 
				
			||||||
              schema:  
 | 
					              schema:  
 | 
				
			||||||
                $ref: "#/components/schemas/Company"
 | 
					                type: object
 | 
				
			||||||
 | 
					                properties:
 | 
				
			||||||
 | 
					                  data: 
 | 
				
			||||||
 | 
					                    type: array
 | 
				
			||||||
 | 
					                    items:
 | 
				
			||||||
 | 
					                      $ref: '#/components/schemas/Company'
 | 
				
			||||||
 | 
					                  meta:
 | 
				
			||||||
 | 
					                    type: object
 | 
				
			||||||
 | 
					                    $ref: '#/components/schemas/Meta'
 | 
				
			||||||
        401:
 | 
					        401:
 | 
				
			||||||
          $ref: "#/components/responses/401"
 | 
					          $ref: "#/components/responses/401"
 | 
				
			||||||
        403:
 | 
					        403:
 | 
				
			||||||
@ -1924,7 +1972,15 @@ paths:
 | 
				
			|||||||
          content:
 | 
					          content:
 | 
				
			||||||
            application/json:
 | 
					            application/json:
 | 
				
			||||||
              schema:  
 | 
					              schema:  
 | 
				
			||||||
                $ref: "#/components/schemas/CompanyGateway"
 | 
					                type: object
 | 
				
			||||||
 | 
					                properties:
 | 
				
			||||||
 | 
					                  data: 
 | 
				
			||||||
 | 
					                    type: array
 | 
				
			||||||
 | 
					                    items:
 | 
				
			||||||
 | 
					                      $ref: '#/components/schemas/CompanyGateway'
 | 
				
			||||||
 | 
					                  meta:
 | 
				
			||||||
 | 
					                    type: object
 | 
				
			||||||
 | 
					                    $ref: '#/components/schemas/Meta'
 | 
				
			||||||
        401:
 | 
					        401:
 | 
				
			||||||
          $ref: "#/components/responses/401"
 | 
					          $ref: "#/components/responses/401"
 | 
				
			||||||
        403:
 | 
					        403:
 | 
				
			||||||
@ -2231,7 +2287,15 @@ paths:
 | 
				
			|||||||
          content:
 | 
					          content:
 | 
				
			||||||
            application/json:
 | 
					            application/json:
 | 
				
			||||||
              schema:  
 | 
					              schema:  
 | 
				
			||||||
                $ref: "#/components/schemas/CompanyLedger"
 | 
					                type: object
 | 
				
			||||||
 | 
					                properties:
 | 
				
			||||||
 | 
					                  data: 
 | 
				
			||||||
 | 
					                    type: array
 | 
				
			||||||
 | 
					                    items:
 | 
				
			||||||
 | 
					                      $ref: '#/components/schemas/CompanyLedger'
 | 
				
			||||||
 | 
					                  meta:
 | 
				
			||||||
 | 
					                    type: object
 | 
				
			||||||
 | 
					                    $ref: '#/components/schemas/Meta'
 | 
				
			||||||
        401:
 | 
					        401:
 | 
				
			||||||
          $ref: "#/components/responses/401"
 | 
					          $ref: "#/components/responses/401"
 | 
				
			||||||
        403:
 | 
					        403:
 | 
				
			||||||
@ -2335,7 +2399,15 @@ paths:
 | 
				
			|||||||
          content:
 | 
					          content:
 | 
				
			||||||
            application/json:
 | 
					            application/json:
 | 
				
			||||||
              schema:  
 | 
					              schema:  
 | 
				
			||||||
                $ref: "#/components/schemas/Design"
 | 
					                type: object
 | 
				
			||||||
 | 
					                properties:
 | 
				
			||||||
 | 
					                  data: 
 | 
				
			||||||
 | 
					                    type: array
 | 
				
			||||||
 | 
					                    items:
 | 
				
			||||||
 | 
					                      $ref: '#/components/schemas/Design'
 | 
				
			||||||
 | 
					                  meta:
 | 
				
			||||||
 | 
					                    type: object
 | 
				
			||||||
 | 
					                    $ref: '#/components/schemas/Meta'
 | 
				
			||||||
        401:
 | 
					        401:
 | 
				
			||||||
          $ref: "#/components/responses/401"
 | 
					          $ref: "#/components/responses/401"
 | 
				
			||||||
        403:
 | 
					        403:
 | 
				
			||||||
@ -2643,7 +2715,15 @@ paths:
 | 
				
			|||||||
          content:
 | 
					          content:
 | 
				
			||||||
            application/json:
 | 
					            application/json:
 | 
				
			||||||
              schema:  
 | 
					              schema:  
 | 
				
			||||||
                $ref: "#/components/schemas/Document"
 | 
					                type: object
 | 
				
			||||||
 | 
					                properties:
 | 
				
			||||||
 | 
					                  data: 
 | 
				
			||||||
 | 
					                    type: array
 | 
				
			||||||
 | 
					                    items:
 | 
				
			||||||
 | 
					                      $ref: '#/components/schemas/Document'
 | 
				
			||||||
 | 
					                  meta:
 | 
				
			||||||
 | 
					                    type: object
 | 
				
			||||||
 | 
					                    $ref: '#/components/schemas/Meta'
 | 
				
			||||||
        401:
 | 
					        401:
 | 
				
			||||||
          $ref: "#/components/responses/401"
 | 
					          $ref: "#/components/responses/401"
 | 
				
			||||||
        403:
 | 
					        403:
 | 
				
			||||||
@ -2728,7 +2808,15 @@ paths:
 | 
				
			|||||||
          content:
 | 
					          content:
 | 
				
			||||||
            application/json:
 | 
					            application/json:
 | 
				
			||||||
              schema:  
 | 
					              schema:  
 | 
				
			||||||
                $ref: "#/components/schemas/ExpenseCategory"
 | 
					                type: object
 | 
				
			||||||
 | 
					                properties:
 | 
				
			||||||
 | 
					                  data: 
 | 
				
			||||||
 | 
					                    type: array
 | 
				
			||||||
 | 
					                    items:
 | 
				
			||||||
 | 
					                      $ref: '#/components/schemas/ExpenseCategory'
 | 
				
			||||||
 | 
					                  meta:
 | 
				
			||||||
 | 
					                    type: object
 | 
				
			||||||
 | 
					                    $ref: '#/components/schemas/Meta'
 | 
				
			||||||
        401:
 | 
					        401:
 | 
				
			||||||
          $ref: "#/components/responses/401"
 | 
					          $ref: "#/components/responses/401"
 | 
				
			||||||
        403:
 | 
					        403:
 | 
				
			||||||
@ -3024,7 +3112,15 @@ paths:
 | 
				
			|||||||
          content:
 | 
					          content:
 | 
				
			||||||
            application/json:
 | 
					            application/json:
 | 
				
			||||||
              schema:  
 | 
					              schema:  
 | 
				
			||||||
                $ref: "#/components/schemas/Expense"
 | 
					                type: object
 | 
				
			||||||
 | 
					                properties:
 | 
				
			||||||
 | 
					                  data: 
 | 
				
			||||||
 | 
					                    type: array
 | 
				
			||||||
 | 
					                    items:
 | 
				
			||||||
 | 
					                      $ref: '#/components/schemas/Expense'
 | 
				
			||||||
 | 
					                  meta:
 | 
				
			||||||
 | 
					                    type: object
 | 
				
			||||||
 | 
					                    $ref: '#/components/schemas/Meta'
 | 
				
			||||||
        401:
 | 
					        401:
 | 
				
			||||||
          $ref: "#/components/responses/401"
 | 
					          $ref: "#/components/responses/401"
 | 
				
			||||||
        403:
 | 
					        403:
 | 
				
			||||||
@ -3392,7 +3488,15 @@ paths:
 | 
				
			|||||||
          content:
 | 
					          content:
 | 
				
			||||||
            application/json:
 | 
					            application/json:
 | 
				
			||||||
              schema:  
 | 
					              schema:  
 | 
				
			||||||
                $ref: "#/components/schemas/GroupSetting"
 | 
					                type: object
 | 
				
			||||||
 | 
					                properties:
 | 
				
			||||||
 | 
					                  data: 
 | 
				
			||||||
 | 
					                    type: array
 | 
				
			||||||
 | 
					                    items:
 | 
				
			||||||
 | 
					                      $ref: '#/components/schemas/GroupSetting'
 | 
				
			||||||
 | 
					                  meta:
 | 
				
			||||||
 | 
					                    type: object
 | 
				
			||||||
 | 
					                    $ref: '#/components/schemas/Meta'
 | 
				
			||||||
        401:
 | 
					        401:
 | 
				
			||||||
          $ref: "#/components/responses/401"
 | 
					          $ref: "#/components/responses/401"
 | 
				
			||||||
        403:
 | 
					        403:
 | 
				
			||||||
@ -3875,8 +3979,8 @@ paths:
 | 
				
			|||||||
    post:
 | 
					    post:
 | 
				
			||||||
      tags:
 | 
					      tags:
 | 
				
			||||||
        - logout
 | 
					        - logout
 | 
				
			||||||
      summary: "Gets a list of logout"
 | 
					      summary: "Logs the user out of their current session"
 | 
				
			||||||
      description: "Lists all logout"
 | 
					      description: "Logs the user out of their current session"
 | 
				
			||||||
      operationId: getLogout
 | 
					      operationId: getLogout
 | 
				
			||||||
      parameters:
 | 
					      parameters:
 | 
				
			||||||
        - $ref: "#/components/parameters/X-API-TOKEN"
 | 
					        - $ref: "#/components/parameters/X-API-TOKEN"
 | 
				
			||||||
@ -4063,7 +4167,15 @@ paths:
 | 
				
			|||||||
          content:
 | 
					          content:
 | 
				
			||||||
            application/json:
 | 
					            application/json:
 | 
				
			||||||
              schema:  
 | 
					              schema:  
 | 
				
			||||||
                $ref: "#/components/schemas/PaymentTerm"
 | 
					                type: object
 | 
				
			||||||
 | 
					                properties:
 | 
				
			||||||
 | 
					                  data: 
 | 
				
			||||||
 | 
					                    type: array
 | 
				
			||||||
 | 
					                    items:
 | 
				
			||||||
 | 
					                      $ref: '#/components/schemas/PaymentTerm'
 | 
				
			||||||
 | 
					                  meta:
 | 
				
			||||||
 | 
					                    type: object
 | 
				
			||||||
 | 
					                    $ref: '#/components/schemas/Meta'
 | 
				
			||||||
        401:
 | 
					        401:
 | 
				
			||||||
          $ref: "#/components/responses/401"
 | 
					          $ref: "#/components/responses/401"
 | 
				
			||||||
        403:
 | 
					        403:
 | 
				
			||||||
@ -4497,7 +4609,15 @@ paths:
 | 
				
			|||||||
          content:
 | 
					          content:
 | 
				
			||||||
            application/json:
 | 
					            application/json:
 | 
				
			||||||
              schema:  
 | 
					              schema:  
 | 
				
			||||||
                $ref: "#/components/schemas/RecurringExpense"
 | 
					                type: object
 | 
				
			||||||
 | 
					                properties:
 | 
				
			||||||
 | 
					                  data: 
 | 
				
			||||||
 | 
					                    type: array
 | 
				
			||||||
 | 
					                    items:
 | 
				
			||||||
 | 
					                      $ref: '#/components/schemas/RecurringExpense'
 | 
				
			||||||
 | 
					                  meta:
 | 
				
			||||||
 | 
					                    type: object
 | 
				
			||||||
 | 
					                    $ref: '#/components/schemas/Meta'
 | 
				
			||||||
        401:
 | 
					        401:
 | 
				
			||||||
          $ref: "#/components/responses/401"
 | 
					          $ref: "#/components/responses/401"
 | 
				
			||||||
        403:
 | 
					        403:
 | 
				
			||||||
@ -4839,7 +4959,15 @@ paths:
 | 
				
			|||||||
          content:
 | 
					          content:
 | 
				
			||||||
            application/json:
 | 
					            application/json:
 | 
				
			||||||
              schema:  
 | 
					              schema:  
 | 
				
			||||||
                $ref: "#/components/schemas/RecurringQuote"
 | 
					                type: object
 | 
				
			||||||
 | 
					                properties:
 | 
				
			||||||
 | 
					                  data: 
 | 
				
			||||||
 | 
					                    type: array
 | 
				
			||||||
 | 
					                    items:
 | 
				
			||||||
 | 
					                      $ref: '#/components/schemas/RecurringQuote'
 | 
				
			||||||
 | 
					                  meta:
 | 
				
			||||||
 | 
					                    type: object
 | 
				
			||||||
 | 
					                    $ref: '#/components/schemas/Meta'
 | 
				
			||||||
        401:
 | 
					        401:
 | 
				
			||||||
          $ref: "#/components/responses/401"
 | 
					          $ref: "#/components/responses/401"
 | 
				
			||||||
        403:
 | 
					        403:
 | 
				
			||||||
@ -5735,7 +5863,15 @@ paths:
 | 
				
			|||||||
          content:
 | 
					          content:
 | 
				
			||||||
            application/json:
 | 
					            application/json:
 | 
				
			||||||
              schema:  
 | 
					              schema:  
 | 
				
			||||||
                $ref: "#/components/schemas/Subscription"
 | 
					                type: object
 | 
				
			||||||
 | 
					                properties:
 | 
				
			||||||
 | 
					                  data: 
 | 
				
			||||||
 | 
					                    type: array
 | 
				
			||||||
 | 
					                    items:
 | 
				
			||||||
 | 
					                      $ref: '#/components/schemas/Subscription'
 | 
				
			||||||
 | 
					                  meta:
 | 
				
			||||||
 | 
					                    type: object
 | 
				
			||||||
 | 
					                    $ref: '#/components/schemas/Meta'
 | 
				
			||||||
        401:
 | 
					        401:
 | 
				
			||||||
          $ref: "#/components/responses/401"
 | 
					          $ref: "#/components/responses/401"
 | 
				
			||||||
        403:
 | 
					        403:
 | 
				
			||||||
@ -6076,7 +6212,15 @@ paths:
 | 
				
			|||||||
          content:
 | 
					          content:
 | 
				
			||||||
            application/json:
 | 
					            application/json:
 | 
				
			||||||
              schema:  
 | 
					              schema:  
 | 
				
			||||||
                $ref: "#/components/schemas/SystemLog"
 | 
					                type: object
 | 
				
			||||||
 | 
					                properties:
 | 
				
			||||||
 | 
					                  data: 
 | 
				
			||||||
 | 
					                    type: array
 | 
				
			||||||
 | 
					                    items:
 | 
				
			||||||
 | 
					                      $ref: '#/components/schemas/SystemLog'
 | 
				
			||||||
 | 
					                  meta:
 | 
				
			||||||
 | 
					                    type: object
 | 
				
			||||||
 | 
					                    $ref: '#/components/schemas/Meta'
 | 
				
			||||||
        401:
 | 
					        401:
 | 
				
			||||||
          $ref: "#/components/responses/401"
 | 
					          $ref: "#/components/responses/401"
 | 
				
			||||||
        403:
 | 
					        403:
 | 
				
			||||||
@ -6381,7 +6525,15 @@ paths:
 | 
				
			|||||||
          content:
 | 
					          content:
 | 
				
			||||||
            application/json:
 | 
					            application/json:
 | 
				
			||||||
              schema:  
 | 
					              schema:  
 | 
				
			||||||
                $ref: "#/components/schemas/TaskStatus"
 | 
					                type: object
 | 
				
			||||||
 | 
					                properties:
 | 
				
			||||||
 | 
					                  data: 
 | 
				
			||||||
 | 
					                    type: array
 | 
				
			||||||
 | 
					                    items:
 | 
				
			||||||
 | 
					                      $ref: '#/components/schemas/TaskStatus'
 | 
				
			||||||
 | 
					                  meta:
 | 
				
			||||||
 | 
					                    type: object
 | 
				
			||||||
 | 
					                    $ref: '#/components/schemas/Meta'
 | 
				
			||||||
        401:
 | 
					        401:
 | 
				
			||||||
          $ref: "#/components/responses/401"
 | 
					          $ref: "#/components/responses/401"
 | 
				
			||||||
        403:
 | 
					        403:
 | 
				
			||||||
@ -6686,7 +6838,15 @@ paths:
 | 
				
			|||||||
          content:
 | 
					          content:
 | 
				
			||||||
            application/json:
 | 
					            application/json:
 | 
				
			||||||
              schema:  
 | 
					              schema:  
 | 
				
			||||||
                $ref: "#/components/schemas/TaxRate"
 | 
					                type: object
 | 
				
			||||||
 | 
					                properties:
 | 
				
			||||||
 | 
					                  data: 
 | 
				
			||||||
 | 
					                    type: array
 | 
				
			||||||
 | 
					                    items:
 | 
				
			||||||
 | 
					                      $ref: '#/components/schemas/TaxRate'
 | 
				
			||||||
 | 
					                  meta:
 | 
				
			||||||
 | 
					                    type: object
 | 
				
			||||||
 | 
					                    $ref: '#/components/schemas/Meta'
 | 
				
			||||||
        401:
 | 
					        401:
 | 
				
			||||||
          $ref: "#/components/responses/401"
 | 
					          $ref: "#/components/responses/401"
 | 
				
			||||||
        403:
 | 
					        403:
 | 
				
			||||||
@ -6995,7 +7155,15 @@ paths:
 | 
				
			|||||||
          content:
 | 
					          content:
 | 
				
			||||||
            application/json:
 | 
					            application/json:
 | 
				
			||||||
              schema:  
 | 
					              schema:  
 | 
				
			||||||
                $ref: "#/components/schemas/CompanyToken"
 | 
					                type: object
 | 
				
			||||||
 | 
					                properties:
 | 
				
			||||||
 | 
					                  data: 
 | 
				
			||||||
 | 
					                    type: array
 | 
				
			||||||
 | 
					                    items:
 | 
				
			||||||
 | 
					                      $ref: '#/components/schemas/CompanyToken'
 | 
				
			||||||
 | 
					                  meta:
 | 
				
			||||||
 | 
					                    type: object
 | 
				
			||||||
 | 
					                    $ref: '#/components/schemas/Meta'
 | 
				
			||||||
        401:
 | 
					        401:
 | 
				
			||||||
          $ref: "#/components/responses/401"
 | 
					          $ref: "#/components/responses/401"
 | 
				
			||||||
        403:
 | 
					        403:
 | 
				
			||||||
@ -7295,7 +7463,15 @@ paths:
 | 
				
			|||||||
          content:
 | 
					          content:
 | 
				
			||||||
            application/json:
 | 
					            application/json:
 | 
				
			||||||
              schema:  
 | 
					              schema:  
 | 
				
			||||||
                $ref: "#/components/schemas/User"
 | 
					                type: object
 | 
				
			||||||
 | 
					                properties:
 | 
				
			||||||
 | 
					                  data: 
 | 
				
			||||||
 | 
					                    type: array
 | 
				
			||||||
 | 
					                    items:
 | 
				
			||||||
 | 
					                      $ref: '#/components/schemas/User'
 | 
				
			||||||
 | 
					                  meta:
 | 
				
			||||||
 | 
					                    type: object
 | 
				
			||||||
 | 
					                    $ref: '#/components/schemas/Meta'
 | 
				
			||||||
        401:
 | 
					        401:
 | 
				
			||||||
          $ref: "#/components/responses/401"
 | 
					          $ref: "#/components/responses/401"
 | 
				
			||||||
        403:
 | 
					        403:
 | 
				
			||||||
@ -7743,7 +7919,15 @@ paths:
 | 
				
			|||||||
          content:
 | 
					          content:
 | 
				
			||||||
            application/json:
 | 
					            application/json:
 | 
				
			||||||
              schema:  
 | 
					              schema:  
 | 
				
			||||||
                $ref: "#/components/schemas/Webhook"
 | 
					                type: object
 | 
				
			||||||
 | 
					                properties:
 | 
				
			||||||
 | 
					                  data: 
 | 
				
			||||||
 | 
					                    type: array
 | 
				
			||||||
 | 
					                    items:
 | 
				
			||||||
 | 
					                      $ref: '#/components/schemas/Webhook'
 | 
				
			||||||
 | 
					                  meta:
 | 
				
			||||||
 | 
					                    type: object
 | 
				
			||||||
 | 
					                    $ref: '#/components/schemas/Meta'
 | 
				
			||||||
        401:
 | 
					        401:
 | 
				
			||||||
          $ref: "#/components/responses/401"
 | 
					          $ref: "#/components/responses/401"
 | 
				
			||||||
        403:
 | 
					        403:
 | 
				
			||||||
 | 
				
			|||||||
@ -118,7 +118,19 @@
 | 
				
			|||||||
          content:
 | 
					          content:
 | 
				
			||||||
            application/json:
 | 
					            application/json:
 | 
				
			||||||
              schema:  
 | 
					              schema:  
 | 
				
			||||||
 | 
					                type: object
 | 
				
			||||||
 | 
					                properties:
 | 
				
			||||||
 | 
					                  data: 
 | 
				
			||||||
 | 
					                    type: array
 | 
				
			||||||
 | 
					                    items:
 | 
				
			||||||
                      $ref: '#/components/schemas/Client'
 | 
					                      $ref: '#/components/schemas/Client'
 | 
				
			||||||
 | 
					                    example:
 | 
				
			||||||
 | 
					                      $ref: '#/components/examples/Client'
 | 
				
			||||||
 | 
					                  meta:
 | 
				
			||||||
 | 
					                    type: object
 | 
				
			||||||
 | 
					                    $ref: '#/components/schemas/Meta'
 | 
				
			||||||
 | 
					                    example:
 | 
				
			||||||
 | 
					                      $ref: '#/components/examples/Meta'
 | 
				
			||||||
        401:
 | 
					        401:
 | 
				
			||||||
          $ref: '#/components/responses/401'
 | 
					          $ref: '#/components/responses/401'
 | 
				
			||||||
        403:
 | 
					        403:
 | 
				
			||||||
 | 
				
			|||||||
@ -22,7 +22,15 @@
 | 
				
			|||||||
          content:
 | 
					          content:
 | 
				
			||||||
            application/json:
 | 
					            application/json:
 | 
				
			||||||
              schema:  
 | 
					              schema:  
 | 
				
			||||||
                $ref: "#/components/schemas/Credit"
 | 
					                type: object
 | 
				
			||||||
 | 
					                properties:
 | 
				
			||||||
 | 
					                  data: 
 | 
				
			||||||
 | 
					                    type: array
 | 
				
			||||||
 | 
					                    items:
 | 
				
			||||||
 | 
					                      $ref: '#/components/schemas/Credit'
 | 
				
			||||||
 | 
					                  meta:
 | 
				
			||||||
 | 
					                    type: object
 | 
				
			||||||
 | 
					                    $ref: '#/components/schemas/Meta'
 | 
				
			||||||
        401:
 | 
					        401:
 | 
				
			||||||
          $ref: "#/components/responses/401"
 | 
					          $ref: "#/components/responses/401"
 | 
				
			||||||
        403:
 | 
					        403:
 | 
				
			||||||
 | 
				
			|||||||
@ -107,7 +107,15 @@
 | 
				
			|||||||
          content:
 | 
					          content:
 | 
				
			||||||
            application/json:
 | 
					            application/json:
 | 
				
			||||||
              schema:  
 | 
					              schema:  
 | 
				
			||||||
                $ref: "#/components/schemas/Invoice"
 | 
					                type: object
 | 
				
			||||||
 | 
					                properties:
 | 
				
			||||||
 | 
					                  data: 
 | 
				
			||||||
 | 
					                    type: array
 | 
				
			||||||
 | 
					                    items:
 | 
				
			||||||
 | 
					                      $ref: '#/components/schemas/Invoice'
 | 
				
			||||||
 | 
					                  meta:
 | 
				
			||||||
 | 
					                    type: object
 | 
				
			||||||
 | 
					                    $ref: '#/components/schemas/Meta'
 | 
				
			||||||
        401:
 | 
					        401:
 | 
				
			||||||
          $ref: "#/components/responses/401"
 | 
					          $ref: "#/components/responses/401"
 | 
				
			||||||
        403:
 | 
					        403:
 | 
				
			||||||
 | 
				
			|||||||
@ -58,7 +58,15 @@
 | 
				
			|||||||
          content:
 | 
					          content:
 | 
				
			||||||
            application/json:
 | 
					            application/json:
 | 
				
			||||||
              schema:  
 | 
					              schema:  
 | 
				
			||||||
                $ref: "#/components/schemas/Payment"
 | 
					                type: object
 | 
				
			||||||
 | 
					                properties:
 | 
				
			||||||
 | 
					                  data: 
 | 
				
			||||||
 | 
					                    type: array
 | 
				
			||||||
 | 
					                    items:
 | 
				
			||||||
 | 
					                      $ref: '#/components/schemas/Payment'
 | 
				
			||||||
 | 
					                  meta:
 | 
				
			||||||
 | 
					                    type: object
 | 
				
			||||||
 | 
					                    $ref: '#/components/schemas/Meta'
 | 
				
			||||||
        401:
 | 
					        401:
 | 
				
			||||||
          $ref: "#/components/responses/401"
 | 
					          $ref: "#/components/responses/401"
 | 
				
			||||||
        403:
 | 
					        403:
 | 
				
			||||||
 | 
				
			|||||||
@ -53,7 +53,15 @@
 | 
				
			|||||||
          content:
 | 
					          content:
 | 
				
			||||||
            application/json:
 | 
					            application/json:
 | 
				
			||||||
              schema:  
 | 
					              schema:  
 | 
				
			||||||
                $ref: "#/components/schemas/Product"
 | 
					                type: object
 | 
				
			||||||
 | 
					                properties:
 | 
				
			||||||
 | 
					                  data: 
 | 
				
			||||||
 | 
					                    type: array
 | 
				
			||||||
 | 
					                    items:
 | 
				
			||||||
 | 
					                      $ref: '#/components/schemas/Product'
 | 
				
			||||||
 | 
					                  meta:
 | 
				
			||||||
 | 
					                    type: object
 | 
				
			||||||
 | 
					                    $ref: '#/components/schemas/Meta'
 | 
				
			||||||
        401:
 | 
					        401:
 | 
				
			||||||
          $ref: '#/components/responses/401'
 | 
					          $ref: '#/components/responses/401'
 | 
				
			||||||
        403:
 | 
					        403:
 | 
				
			||||||
 | 
				
			|||||||
@ -23,7 +23,15 @@
 | 
				
			|||||||
          content:
 | 
					          content:
 | 
				
			||||||
            application/json:
 | 
					            application/json:
 | 
				
			||||||
              schema:  
 | 
					              schema:  
 | 
				
			||||||
                $ref: "#/components/schemas/Project"
 | 
					                type: object
 | 
				
			||||||
 | 
					                properties:
 | 
				
			||||||
 | 
					                  data: 
 | 
				
			||||||
 | 
					                    type: array
 | 
				
			||||||
 | 
					                    items:
 | 
				
			||||||
 | 
					                      $ref: '#/components/schemas/Project'
 | 
				
			||||||
 | 
					                  meta:
 | 
				
			||||||
 | 
					                    type: object
 | 
				
			||||||
 | 
					                    $ref: '#/components/schemas/Meta'
 | 
				
			||||||
        401:
 | 
					        401:
 | 
				
			||||||
          $ref: "#/components/responses/401"
 | 
					          $ref: "#/components/responses/401"
 | 
				
			||||||
        403:
 | 
					        403:
 | 
				
			||||||
 | 
				
			|||||||
@ -22,7 +22,15 @@
 | 
				
			|||||||
          content:
 | 
					          content:
 | 
				
			||||||
            application/json:
 | 
					            application/json:
 | 
				
			||||||
              schema:  
 | 
					              schema:  
 | 
				
			||||||
                $ref: "#/components/schemas/Credit"
 | 
					                type: object
 | 
				
			||||||
 | 
					                properties:
 | 
				
			||||||
 | 
					                  data: 
 | 
				
			||||||
 | 
					                    type: array
 | 
				
			||||||
 | 
					                    items:
 | 
				
			||||||
 | 
					                      $ref: '#/components/schemas/PurchaseOrder'
 | 
				
			||||||
 | 
					                  meta:
 | 
				
			||||||
 | 
					                    type: object
 | 
				
			||||||
 | 
					                    $ref: '#/components/schemas/Meta'
 | 
				
			||||||
        401:
 | 
					        401:
 | 
				
			||||||
          $ref: "#/components/responses/401"
 | 
					          $ref: "#/components/responses/401"
 | 
				
			||||||
        403:
 | 
					        403:
 | 
				
			||||||
@ -58,7 +66,7 @@
 | 
				
			|||||||
          content:
 | 
					          content:
 | 
				
			||||||
            application/json:
 | 
					            application/json:
 | 
				
			||||||
              schema:
 | 
					              schema:
 | 
				
			||||||
                $ref: "#/components/schemas/Credit"
 | 
					                $ref: "#/components/schemas/PurchaseOrder"
 | 
				
			||||||
        401:
 | 
					        401:
 | 
				
			||||||
          $ref: "#/components/responses/401"
 | 
					          $ref: "#/components/responses/401"
 | 
				
			||||||
        403:
 | 
					        403:
 | 
				
			||||||
@ -104,7 +112,7 @@
 | 
				
			|||||||
          content:
 | 
					          content:
 | 
				
			||||||
            application/json:
 | 
					            application/json:
 | 
				
			||||||
              schema:
 | 
					              schema:
 | 
				
			||||||
                $ref: "#/components/schemas/Credit"
 | 
					                $ref: "#/components/schemas/PurchaseOrder"
 | 
				
			||||||
        401:
 | 
					        401:
 | 
				
			||||||
          $ref: "#/components/responses/401"
 | 
					          $ref: "#/components/responses/401"
 | 
				
			||||||
        403:
 | 
					        403:
 | 
				
			||||||
@ -149,7 +157,7 @@
 | 
				
			|||||||
          content:
 | 
					          content:
 | 
				
			||||||
            application/json:
 | 
					            application/json:
 | 
				
			||||||
              schema:
 | 
					              schema:
 | 
				
			||||||
                $ref: "#/components/schemas/Credit"
 | 
					                $ref: "#/components/schemas/PurchaseOrder"
 | 
				
			||||||
        401:
 | 
					        401:
 | 
				
			||||||
          $ref: "#/components/responses/401"
 | 
					          $ref: "#/components/responses/401"
 | 
				
			||||||
        403:
 | 
					        403:
 | 
				
			||||||
@ -234,7 +242,7 @@
 | 
				
			|||||||
          content:
 | 
					          content:
 | 
				
			||||||
            application/json:
 | 
					            application/json:
 | 
				
			||||||
              schema:
 | 
					              schema:
 | 
				
			||||||
                $ref: "#/components/schemas/Invoice"
 | 
					                $ref: "#/components/schemas/PurchaseOrder"
 | 
				
			||||||
        401:
 | 
					        401:
 | 
				
			||||||
          $ref: "#/components/responses/401"
 | 
					          $ref: "#/components/responses/401"
 | 
				
			||||||
        403:
 | 
					        403:
 | 
				
			||||||
@ -272,7 +280,7 @@
 | 
				
			|||||||
          content:
 | 
					          content:
 | 
				
			||||||
            application/json:
 | 
					            application/json:
 | 
				
			||||||
              schema:
 | 
					              schema:
 | 
				
			||||||
                $ref: "#/components/schemas/Credit"
 | 
					                $ref: "#/components/schemas/PurchaseOrder"
 | 
				
			||||||
        401:
 | 
					        401:
 | 
				
			||||||
          $ref: "#/components/responses/401"
 | 
					          $ref: "#/components/responses/401"
 | 
				
			||||||
        403:
 | 
					        403:
 | 
				
			||||||
@ -359,7 +367,7 @@
 | 
				
			|||||||
          example: clone_to_quote
 | 
					          example: clone_to_quote
 | 
				
			||||||
      responses:
 | 
					      responses:
 | 
				
			||||||
        200:
 | 
					        200:
 | 
				
			||||||
          description: "Returns the invoice object"
 | 
					          description: "Returns the purchase order object"
 | 
				
			||||||
          headers:
 | 
					          headers:
 | 
				
			||||||
            X-MINIMUM-CLIENT-VERSION:
 | 
					            X-MINIMUM-CLIENT-VERSION:
 | 
				
			||||||
              $ref: "#/components/headers/X-MINIMUM-CLIENT-VERSION"
 | 
					              $ref: "#/components/headers/X-MINIMUM-CLIENT-VERSION"
 | 
				
			||||||
@ -370,7 +378,7 @@
 | 
				
			|||||||
          content:
 | 
					          content:
 | 
				
			||||||
            application/json:
 | 
					            application/json:
 | 
				
			||||||
              schema:
 | 
					              schema:
 | 
				
			||||||
                $ref: "#/components/schemas/Invoice"
 | 
					                $ref: "#/components/schemas/PurchaseOrder"
 | 
				
			||||||
        401:
 | 
					        401:
 | 
				
			||||||
          $ref: "#/components/responses/401"
 | 
					          $ref: "#/components/responses/401"
 | 
				
			||||||
        403:
 | 
					        403:
 | 
				
			||||||
@ -415,7 +423,7 @@
 | 
				
			|||||||
          content:
 | 
					          content:
 | 
				
			||||||
            application/json:
 | 
					            application/json:
 | 
				
			||||||
              schema:
 | 
					              schema:
 | 
				
			||||||
                $ref: "#/components/schemas/Vendor"
 | 
					                $ref: "#/components/schemas/PurchaseOrder"
 | 
				
			||||||
        401:
 | 
					        401:
 | 
				
			||||||
          $ref: "#/components/responses/401"
 | 
					          $ref: "#/components/responses/401"
 | 
				
			||||||
        403:
 | 
					        403:
 | 
				
			||||||
 | 
				
			|||||||
@ -71,7 +71,15 @@
 | 
				
			|||||||
          content:
 | 
					          content:
 | 
				
			||||||
            application/json:
 | 
					            application/json:
 | 
				
			||||||
              schema:  
 | 
					              schema:  
 | 
				
			||||||
                $ref: "#/components/schemas/Quote"
 | 
					                type: object
 | 
				
			||||||
 | 
					                properties:
 | 
				
			||||||
 | 
					                  data: 
 | 
				
			||||||
 | 
					                    type: array
 | 
				
			||||||
 | 
					                    items:
 | 
				
			||||||
 | 
					                      $ref: '#/components/schemas/Quote'
 | 
				
			||||||
 | 
					                  meta:
 | 
				
			||||||
 | 
					                    type: object
 | 
				
			||||||
 | 
					                    $ref: '#/components/schemas/Meta'
 | 
				
			||||||
        401:
 | 
					        401:
 | 
				
			||||||
          $ref: "#/components/responses/401"
 | 
					          $ref: "#/components/responses/401"
 | 
				
			||||||
        403:
 | 
					        403:
 | 
				
			||||||
 | 
				
			|||||||
@ -61,7 +61,15 @@
 | 
				
			|||||||
          content:
 | 
					          content:
 | 
				
			||||||
            application/json:
 | 
					            application/json:
 | 
				
			||||||
              schema:  
 | 
					              schema:  
 | 
				
			||||||
                $ref: "#/components/schemas/RecurringInvoice"
 | 
					                type: object
 | 
				
			||||||
 | 
					                properties:
 | 
				
			||||||
 | 
					                  data: 
 | 
				
			||||||
 | 
					                    type: array
 | 
				
			||||||
 | 
					                    items:
 | 
				
			||||||
 | 
					                      $ref: '#/components/schemas/RecurringInvoice'
 | 
				
			||||||
 | 
					                  meta:
 | 
				
			||||||
 | 
					                    type: object
 | 
				
			||||||
 | 
					                    $ref: '#/components/schemas/Meta'
 | 
				
			||||||
        401:
 | 
					        401:
 | 
				
			||||||
          $ref: "#/components/responses/401"
 | 
					          $ref: "#/components/responses/401"
 | 
				
			||||||
        403:
 | 
					        403:
 | 
				
			||||||
 | 
				
			|||||||
@ -23,7 +23,15 @@
 | 
				
			|||||||
          content:
 | 
					          content:
 | 
				
			||||||
            application/json:
 | 
					            application/json:
 | 
				
			||||||
              schema:  
 | 
					              schema:  
 | 
				
			||||||
                $ref: "#/components/schemas/Task"
 | 
					                type: object
 | 
				
			||||||
 | 
					                properties:
 | 
				
			||||||
 | 
					                  data: 
 | 
				
			||||||
 | 
					                    type: array
 | 
				
			||||||
 | 
					                    items:
 | 
				
			||||||
 | 
					                      $ref: '#/components/schemas/Task'
 | 
				
			||||||
 | 
					                  meta:
 | 
				
			||||||
 | 
					                    type: object
 | 
				
			||||||
 | 
					                    $ref: '#/components/schemas/Meta'
 | 
				
			||||||
        401:
 | 
					        401:
 | 
				
			||||||
          $ref: "#/components/responses/401"
 | 
					          $ref: "#/components/responses/401"
 | 
				
			||||||
        403:
 | 
					        403:
 | 
				
			||||||
 | 
				
			|||||||
@ -23,7 +23,15 @@
 | 
				
			|||||||
          content:
 | 
					          content:
 | 
				
			||||||
            application/json:
 | 
					            application/json:
 | 
				
			||||||
              schema:  
 | 
					              schema:  
 | 
				
			||||||
                $ref: "#/components/schemas/Vendor"
 | 
					                type: object
 | 
				
			||||||
 | 
					                properties:
 | 
				
			||||||
 | 
					                  data: 
 | 
				
			||||||
 | 
					                    type: array
 | 
				
			||||||
 | 
					                    items:
 | 
				
			||||||
 | 
					                      $ref: '#/components/schemas/Vendor'
 | 
				
			||||||
 | 
					                  meta:
 | 
				
			||||||
 | 
					                    type: object
 | 
				
			||||||
 | 
					                    $ref: '#/components/schemas/Meta'
 | 
				
			||||||
        401:
 | 
					        401:
 | 
				
			||||||
          $ref: "#/components/responses/401"
 | 
					          $ref: "#/components/responses/401"
 | 
				
			||||||
        403:
 | 
					        403:
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										6
									
								
								public/flutter_service_worker.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								public/flutter_service_worker.js
									
									
									
									
										vendored
									
									
								
							@ -3,11 +3,11 @@ const MANIFEST = 'flutter-app-manifest';
 | 
				
			|||||||
const TEMP = 'flutter-temp-cache';
 | 
					const TEMP = 'flutter-temp-cache';
 | 
				
			||||||
const CACHE_NAME = 'flutter-app-cache';
 | 
					const CACHE_NAME = 'flutter-app-cache';
 | 
				
			||||||
const RESOURCES = {
 | 
					const RESOURCES = {
 | 
				
			||||||
"/": "26db67421962886d10771e134288cbed",
 | 
					"/": "faecf4eb3989415f8ac174b178967581",
 | 
				
			||||||
"flutter.js": "a85fcf6324d3c4d3ae3be1ae4931e9c5",
 | 
					"flutter.js": "a85fcf6324d3c4d3ae3be1ae4931e9c5",
 | 
				
			||||||
"favicon.png": "dca91c54388f52eded692718d5a98b8b",
 | 
					"favicon.png": "dca91c54388f52eded692718d5a98b8b",
 | 
				
			||||||
"main.dart.js": "b3dc261859fddeebc78cc668c7259ea5",
 | 
					"main.dart.js": "b0022e7084e6d7ec1e1a04e5d9f20501",
 | 
				
			||||||
"version.json": "6f194d02bb20caf51f9b3d380aa58f7d",
 | 
					"version.json": "bf49df736fed3f74ade0dbaebf08de11",
 | 
				
			||||||
"canvaskit/profiling/canvaskit.js": "c21852696bc1cc82e8894d851c01921a",
 | 
					"canvaskit/profiling/canvaskit.js": "c21852696bc1cc82e8894d851c01921a",
 | 
				
			||||||
"canvaskit/profiling/canvaskit.wasm": "371bc4e204443b0d5e774d64a046eb99",
 | 
					"canvaskit/profiling/canvaskit.wasm": "371bc4e204443b0d5e774d64a046eb99",
 | 
				
			||||||
"canvaskit/canvaskit.js": "97937cb4c2c2073c968525a3e08c86a3",
 | 
					"canvaskit/canvaskit.js": "97937cb4c2c2073c968525a3e08c86a3",
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										1702
									
								
								public/main.dart.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1702
									
								
								public/main.dart.js
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										1628
									
								
								public/main.foss.dart.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1628
									
								
								public/main.foss.dart.js
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										14
									
								
								public/main.profile.dart.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										14
									
								
								public/main.profile.dart.js
									
									
									
									
										vendored
									
									
								
							@ -66070,7 +66070,7 @@
 | 
				
			|||||||
      if (B.JSString_methods.startsWith$1(url, "https://invoicing.co"))
 | 
					      if (B.JSString_methods.startsWith$1(url, "https://invoicing.co"))
 | 
				
			||||||
        secret = "";
 | 
					        secret = "";
 | 
				
			||||||
      t1 = type$.legacy_String;
 | 
					      t1 = type$.legacy_String;
 | 
				
			||||||
      headers = A.LinkedHashMap_LinkedHashMap$_literal(["X-CLIENT", A.getPlatformName(), "X-CLIENT-VERSION", "5.0.122", "X-API-SECRET", secret, "X-Requested-With", "XMLHttpRequest", "Content-Type", "application/json; charset=utf-8"], t1, t1);
 | 
					      headers = A.LinkedHashMap_LinkedHashMap$_literal(["X-CLIENT-PLATFORM", A.getPlatformName(), "X-CLIENT-VERSION", "5.0.123", "X-API-SECRET", secret, "X-Requested-With", "XMLHttpRequest", "Content-Type", "application/json; charset=utf-8"], t1, t1);
 | 
				
			||||||
      if (token.length !== 0)
 | 
					      if (token.length !== 0)
 | 
				
			||||||
        headers.$indexSet(0, "X-API-Token", token);
 | 
					        headers.$indexSet(0, "X-API-Token", token);
 | 
				
			||||||
      if ((idToken == null ? "" : idToken).length !== 0)
 | 
					      if ((idToken == null ? "" : idToken).length !== 0)
 | 
				
			||||||
@ -66094,9 +66094,9 @@
 | 
				
			|||||||
        t2 = response.get$body(response).length > 200 ? B.JSString_methods.substring$2(response.get$body(response), 0, 200) : response.get$body(response);
 | 
					        t2 = response.get$body(response).length > 200 ? B.JSString_methods.substring$2(response.get$body(response), 0, 200) : response.get$body(response);
 | 
				
			||||||
        throw A.wrapException("Error: please check that Invoice Ninja v5 is installed on the server\n\nURL: " + url + "\n\nResponse: " + t2 + "\n\nHeaders: " + t1.toString$0(0) + "}");
 | 
					        throw A.wrapException("Error: please check that Invoice Ninja v5 is installed on the server\n\nURL: " + url + "\n\nResponse: " + t2 + "\n\nHeaders: " + t1.toString$0(0) + "}");
 | 
				
			||||||
      } else {
 | 
					      } else {
 | 
				
			||||||
        t1 = A.Version__compare(A.Version_parse("5.0.122"), A.Version_parse(minClientVersion));
 | 
					        t1 = A.Version__compare(A.Version_parse("5.0.123"), A.Version_parse(minClientVersion));
 | 
				
			||||||
        if (t1 < 0)
 | 
					        if (t1 < 0)
 | 
				
			||||||
          throw A.wrapException("Error: client not supported, please update to the latest version [Current v5.0.122 < Minimum v" + A.S(minClientVersion) + "]");
 | 
					          throw A.wrapException("Error: client not supported, please update to the latest version [Current v5.0.123 < Minimum v" + A.S(minClientVersion) + "]");
 | 
				
			||||||
        else {
 | 
					        else {
 | 
				
			||||||
          t1 = A.Version__compare(A.Version_parse(serverVersion), A.Version_parse("5.0.4"));
 | 
					          t1 = A.Version__compare(A.Version_parse(serverVersion), A.Version_parse("5.0.4"));
 | 
				
			||||||
          if (t1 < 0)
 | 
					          if (t1 < 0)
 | 
				
			||||||
@ -392504,7 +392504,7 @@
 | 
				
			|||||||
      version = "v" + (t1 == null ? "" : t1);
 | 
					      version = "v" + (t1 == null ? "" : t1);
 | 
				
			||||||
      if (version.length !== 0)
 | 
					      if (version.length !== 0)
 | 
				
			||||||
        version += "-";
 | 
					        version += "-";
 | 
				
			||||||
      return B.JSString_methods.$add(version + A.getPlatformLetter(), B.JSArray_methods.get$last("5.0.122".split(".")));
 | 
					      return B.JSString_methods.$add(version + A.getPlatformLetter(), B.JSArray_methods.get$last("5.0.123".split(".")));
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    get$historyList() {
 | 
					    get$historyList() {
 | 
				
			||||||
      var _this = this,
 | 
					      var _this = this,
 | 
				
			||||||
@ -455903,10 +455903,10 @@
 | 
				
			|||||||
  };
 | 
					  };
 | 
				
			||||||
  A.DocumentTile_build_closure.prototype = {
 | 
					  A.DocumentTile_build_closure.prototype = {
 | 
				
			||||||
    call$1(context) {
 | 
					    call$1(context) {
 | 
				
			||||||
      var t3, _null = null,
 | 
					      var t2, t3, _null = null,
 | 
				
			||||||
        t1 = A._setArrayType([], type$.JSArray_legacy_PopupMenuEntry_legacy_String),
 | 
					        t1 = A._setArrayType([], type$.JSArray_legacy_PopupMenuEntry_legacy_String),
 | 
				
			||||||
        t2 = this.$this.document.name;
 | 
					        fileName = this.$this.document.name.toLowerCase();
 | 
				
			||||||
      if (B.JSString_methods.endsWith$1(t2, ".png") || B.JSString_methods.endsWith$1(t2, ".jpg") || B.JSString_methods.endsWith$1(t2, ".jpeg")) {
 | 
					      if (B.JSString_methods.endsWith$1(fileName, ".png") || B.JSString_methods.endsWith$1(fileName, ".jpg") || B.JSString_methods.endsWith$1(fileName, ".jpeg") || B.JSString_methods.endsWith$1(fileName, ".bmp") || B.JSString_methods.endsWith$1(fileName, ".webp")) {
 | 
				
			||||||
        t2 = this.localization;
 | 
					        t2 = this.localization;
 | 
				
			||||||
        t1.push(A.PopupMenuItem$(new A.IconText(t2.get$view(t2), B.IconData_58458_MaterialIcons_null_false, _null, _null, false, _null), t2.get$view(t2), type$.legacy_String));
 | 
					        t1.push(A.PopupMenuItem$(new A.IconText(t2.get$view(t2), B.IconData_58458_MaterialIcons_null_false, _null, _null, false, _null), t2.get$view(t2), type$.legacy_String));
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
				
			|||||||
@ -1 +1 @@
 | 
				
			|||||||
{"app_name":"invoiceninja_flutter","version":"5.0.122","build_number":"122","package_name":"invoiceninja_flutter"}
 | 
					{"app_name":"invoiceninja_flutter","version":"5.0.123","build_number":"123","package_name":"invoiceninja_flutter"}
 | 
				
			||||||
@ -0,0 +1,98 @@
 | 
				
			|||||||
 | 
					@php
 | 
				
			||||||
 | 
					    //$mobile = stripos(request()->server('HTTP_USER_AGENT'), 'Android') || stripos(request()->server('HTTP_USER_AGENT'), 'iPhone') || stripos(request()->server('HTTP_USER_AGENT'), 'iPod') || stripos(request()->server('HTTP_USER_AGENT'), 'iPad');
 | 
				
			||||||
 | 
					    $mobile = false;
 | 
				
			||||||
 | 
					@endphp
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@push('head')
 | 
				
			||||||
 | 
					    <meta name="pdf-url" content="{{ $url ?? $entity->pdf_file_path($invitation, 'url', true) }}?cache_buster={{time()}}">
 | 
				
			||||||
 | 
					    <script src="{{ asset('js/vendor/pdf.js/pdf.min.js') }}"></script>
 | 
				
			||||||
 | 
					@endpush
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<div class="flex items-center justify-between mt-4">
 | 
				
			||||||
 | 
					    <section class="flex items-center">
 | 
				
			||||||
 | 
					        <div class="items-center" style="{{ $mobile ? '' : 'display: none' }}" id="pagination-button-container">
 | 
				
			||||||
 | 
					            <button class="input-label focus:outline-none hover:text-blue-600 transition ease-in-out duration-300"
 | 
				
			||||||
 | 
					                id="previous-page-button" title="Previous page">
 | 
				
			||||||
 | 
					                <svg class="w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
 | 
				
			||||||
 | 
					                    <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7" />
 | 
				
			||||||
 | 
					                </svg>
 | 
				
			||||||
 | 
					            </button>
 | 
				
			||||||
 | 
					            <button class="input-label focus:outline-none hover:text-blue-600 transition ease-in-out duration-300"
 | 
				
			||||||
 | 
					                id="next-page-button" title="Next page">
 | 
				
			||||||
 | 
					                <svg class="w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
 | 
				
			||||||
 | 
					                    <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" />
 | 
				
			||||||
 | 
					                </svg>
 | 
				
			||||||
 | 
					            </button>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					        <span class="text-sm text-gray-700 ml-2 {{ $mobile ? 'block' : 'hidden' }}">{{ ctrans('texts.page') }}:
 | 
				
			||||||
 | 
					            <span id="current-page-container"></span>
 | 
				
			||||||
 | 
					            <span>{{ strtolower(ctrans('texts.of')) }}</span>
 | 
				
			||||||
 | 
					            <span id="total-page-container"></span>
 | 
				
			||||||
 | 
					        </span>
 | 
				
			||||||
 | 
					    </section>
 | 
				
			||||||
 | 
					    <section class="flex items-center space-x-1">
 | 
				
			||||||
 | 
					        <div class="flex items-center mr-4 space-x-1 {{ $mobile ? 'block' : 'hidden' }}">
 | 
				
			||||||
 | 
					            <span class="text-gray-600 mr-2" id="zoom-level">100%</span>
 | 
				
			||||||
 | 
					            <a href="#" id="zoom-in">
 | 
				
			||||||
 | 
					                <svg class="text-gray-400 hover:text-gray-600 focus:outline-none focus:text-gray-600 cursor-pointer"
 | 
				
			||||||
 | 
					                    xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"
 | 
				
			||||||
 | 
					                    stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
 | 
				
			||||||
 | 
					                    <circle cx="11" cy="11" r="8"></circle>
 | 
				
			||||||
 | 
					                    <line x1="21" y1="21" x2="16.65" y2="16.65"></line>
 | 
				
			||||||
 | 
					                    <line x1="11" y1="8" x2="11" y2="14"></line>
 | 
				
			||||||
 | 
					                    <line x1="8" y1="11" x2="14" y2="11"></line>
 | 
				
			||||||
 | 
					                </svg>
 | 
				
			||||||
 | 
					            </a>
 | 
				
			||||||
 | 
					            <a href="#" id="zoom-out">
 | 
				
			||||||
 | 
					                <svg class="text-gray-400 hover:text-gray-600 focus:outline-none focus:text-gray-600 cursor-pointer"
 | 
				
			||||||
 | 
					                    xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"
 | 
				
			||||||
 | 
					                    stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
 | 
				
			||||||
 | 
					                    <circle cx="11" cy="11" r="8"></circle>
 | 
				
			||||||
 | 
					                    <line x1="21" y1="21" x2="16.65" y2="16.65"></line>
 | 
				
			||||||
 | 
					                    <line x1="8" y1="11" x2="14" y2="11"></line>
 | 
				
			||||||
 | 
					                </svg>
 | 
				
			||||||
 | 
					            </a>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					        <div x-data="{ open: false }" @keydown.escape="open = false" @click.away="open = false"
 | 
				
			||||||
 | 
					            class="relative inline-block text-left">
 | 
				
			||||||
 | 
					            <div>
 | 
				
			||||||
 | 
					                <button @click="open = !open"
 | 
				
			||||||
 | 
					                    class="flex items-center text-gray-400 hover:text-gray-600 focus:outline-none focus:text-gray-600">
 | 
				
			||||||
 | 
					                    <svg class="h-5 w-5" fill="currentColor" viewBox="0 0 20 20">
 | 
				
			||||||
 | 
					                        <path
 | 
				
			||||||
 | 
					                            d="M10 6a2 2 0 110-4 2 2 0 010 4zM10 12a2 2 0 110-4 2 2 0 010 4zM10 18a2 2 0 110-4 2 2 0 010 4z" />
 | 
				
			||||||
 | 
					                    </svg>
 | 
				
			||||||
 | 
					                </button>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					            <div x-show="open" x-transition:enter="transition ease-out duration-100"
 | 
				
			||||||
 | 
					                x-transition:enter-start="transform opacity-0 scale-95"
 | 
				
			||||||
 | 
					                x-transition:enter-end="transform opacity-100 scale-100"
 | 
				
			||||||
 | 
					                x-transition:leave="transition ease-in duration-75"
 | 
				
			||||||
 | 
					                x-transition:leave-start="transform opacity-100 scale-100"
 | 
				
			||||||
 | 
					                x-transition:leave-end="transform opacity-0 scale-95"
 | 
				
			||||||
 | 
					                class="origin-top-right absolute right-0 mt-2 w-56 rounded-md shadow-lg">
 | 
				
			||||||
 | 
					                <div class="rounded-md bg-white ring-1 ring-black ring-opacity-5">
 | 
				
			||||||
 | 
					                    <div class="py-1">
 | 
				
			||||||
 | 
					                        <a target="_blank" href="{{ $fullscreen_url ?? '?mode=fullscreen' }}"
 | 
				
			||||||
 | 
					                            class="block px-4 py-2 text-sm leading-5 text-gray-700 hover:bg-gray-100 hover:text-gray-900 focus:outline-none focus:bg-gray-100 focus:text-gray-900">{{ ctrans('texts.open_in_new_tab') }}</a>
 | 
				
			||||||
 | 
					                    </div>
 | 
				
			||||||
 | 
					                </div>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					    </section>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@if($mobile)
 | 
				
			||||||
 | 
					    <div class="w-full h-full overflow-auto mt-4">
 | 
				
			||||||
 | 
					        <canvas id="pdf-placeholder" class="shadow rounded-lg bg-white"></canvas>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					@else
 | 
				
			||||||
 | 
					    <iframe id="pdf-iframe" src="{{ $url ?? $entity->pdf_file_path($invitation, 'url', true) }}?cache_buster={{time()}}" class="h-screen w-full border-0 mt-4"></iframe>
 | 
				
			||||||
 | 
					@endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@if($mobile)
 | 
				
			||||||
 | 
					    @push('footer')
 | 
				
			||||||
 | 
					        <script src="{{ asset('js/clients/shared/pdf.js') }}" defer></script>
 | 
				
			||||||
 | 
					    @endpush
 | 
				
			||||||
 | 
					@endif
 | 
				
			||||||
@ -44,7 +44,7 @@
 | 
				
			|||||||
        <button onclick="setTimeout(() => this.disabled = true, 0); setTimeout(() => this.disabled = false, 5000); return true;" id="pdf-download" class="button button-primary bg-primary mt-4 md:mt-0">{{ ctrans('texts.download') }}</button>
 | 
					        <button onclick="setTimeout(() => this.disabled = true, 0); setTimeout(() => this.disabled = false, 5000); return true;" id="pdf-download" class="button button-primary bg-primary mt-4 md:mt-0">{{ ctrans('texts.download') }}</button>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @include('portal.ninja2020.components.pdf-viewer', ['url' => route('client.statement.raw')])
 | 
					    @include('portal.ninja2020.components.statement-pdf-viewer', ['url' => route('client.statement.raw')])
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
@endsection
 | 
					@endsection
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -1,45 +0,0 @@
 | 
				
			|||||||
<?php
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Invoice Ninja (https://invoiceninja.com).
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @license https://www.elastic.co/licensing/elastic-license
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace Tests\Browser\ClientPortal;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use Laravel\Dusk\Browser;
 | 
					 | 
				
			||||||
use Tests\Browser\Pages\ClientPortal\Login;
 | 
					 | 
				
			||||||
use Tests\DuskTestCase;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class CreditsTest extends DuskTestCase
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    protected function setUp(): void
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        parent::setUp();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        foreach (static::$browsers as $browser) {
 | 
					 | 
				
			||||||
            $browser->driver->manage()->deleteAllCookies();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visit(new Login())
 | 
					 | 
				
			||||||
                ->auth();
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testPageLoads()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.credits.index')
 | 
					 | 
				
			||||||
                ->assertSeeIn('span[data-ref="meta-title"]', 'Credits')
 | 
					 | 
				
			||||||
                ->visitRoute('client.logout');
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,45 +0,0 @@
 | 
				
			|||||||
<?php
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Invoice Ninja (https://invoiceninja.com).
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @license https://www.elastic.co/licensing/elastic-license
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace Tests\Browser\ClientPortal;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use Laravel\Dusk\Browser;
 | 
					 | 
				
			||||||
use Tests\Browser\Pages\ClientPortal\Login;
 | 
					 | 
				
			||||||
use Tests\DuskTestCase;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class DocumentsTest extends DuskTestCase
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    protected function setUp(): void
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        parent::setUp();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        foreach (static::$browsers as $browser) {
 | 
					 | 
				
			||||||
            $browser->driver->manage()->deleteAllCookies();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visit(new Login())
 | 
					 | 
				
			||||||
                ->auth();
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testPageLoads()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.documents.index')
 | 
					 | 
				
			||||||
                ->assertSee('Documents')
 | 
					 | 
				
			||||||
                ->visitRoute('client.logout');
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,127 +0,0 @@
 | 
				
			|||||||
<?php
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Invoice Ninja (https://invoiceninja.com).
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @license https://www.elastic.co/licensing/elastic-license
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace Tests\Browser\ClientPortal\Gateways\AuthorizeNet;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use App\Models\CompanyGateway;
 | 
					 | 
				
			||||||
use Laravel\Dusk\Browser;
 | 
					 | 
				
			||||||
use Tests\Browser\Pages\ClientPortal\Login;
 | 
					 | 
				
			||||||
use Tests\DuskTestCase;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class CreditCardTest extends DuskTestCase
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    protected function setUp(): void
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        parent::setUp();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if (getenv('GITHUB_ACTIONS')) {
 | 
					 | 
				
			||||||
            $this->markTestSkipped('Skipping Authorize.net (GitHub Actions)');
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        foreach (static::$browsers as $browser) {
 | 
					 | 
				
			||||||
            $browser->driver->manage()->deleteAllCookies();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visit(new Login())
 | 
					 | 
				
			||||||
                ->auth();
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->disableCompanyGateways();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        CompanyGateway::where('gateway_key', '3b6621f970ab18887c4f6dca78d3f8bb')->restore();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testPayWithNewCard()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.invoices.index')
 | 
					 | 
				
			||||||
                ->click('@pay-now')
 | 
					 | 
				
			||||||
                ->press('Pay Now')
 | 
					 | 
				
			||||||
                ->clickLink('Credit Card')
 | 
					 | 
				
			||||||
                ->type('card-number', '4007000000027')
 | 
					 | 
				
			||||||
                ->type('card-holders-name', 'John Doe')
 | 
					 | 
				
			||||||
                ->type('.expiry', '12/28')
 | 
					 | 
				
			||||||
                ->type('cvc', '100')
 | 
					 | 
				
			||||||
                ->press('Pay Now')
 | 
					 | 
				
			||||||
                ->waitForText('Details of the payment', 60);
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testPayWithNewCardAndSaveForFutureUse()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.invoices.index')
 | 
					 | 
				
			||||||
                ->click('@pay-now')
 | 
					 | 
				
			||||||
                ->press('Pay Now')
 | 
					 | 
				
			||||||
                ->clickLink('Credit Card')
 | 
					 | 
				
			||||||
                ->radio('#proxy_is_default', true)
 | 
					 | 
				
			||||||
                ->type('card-number', '4007000000027')
 | 
					 | 
				
			||||||
                ->type('card-holders-name', 'John Doe')
 | 
					 | 
				
			||||||
                ->type('.expiry', '12/28')
 | 
					 | 
				
			||||||
                ->type('cvc', '100')
 | 
					 | 
				
			||||||
                ->press('Pay Now')
 | 
					 | 
				
			||||||
                ->waitForText('Details of the payment', 60)
 | 
					 | 
				
			||||||
                ->visitRoute('client.payment_methods.index')
 | 
					 | 
				
			||||||
                ->clickLink('View')
 | 
					 | 
				
			||||||
                ->assertSee('0027');
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testPayWithSavedCard()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.invoices.index')
 | 
					 | 
				
			||||||
                ->click('@pay-now')
 | 
					 | 
				
			||||||
                ->press('Pay Now')
 | 
					 | 
				
			||||||
                ->clickLink('Credit Card')
 | 
					 | 
				
			||||||
                ->click('.toggle-payment-with-token')
 | 
					 | 
				
			||||||
                ->press('Pay Now')
 | 
					 | 
				
			||||||
                ->waitForText('Details of the payment', 60);
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testRemoveCard()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.payment_methods.index')
 | 
					 | 
				
			||||||
                ->clickLink('View')
 | 
					 | 
				
			||||||
                ->press('Remove Payment Method')
 | 
					 | 
				
			||||||
                ->waitForText('Confirmation')
 | 
					 | 
				
			||||||
                ->click('@confirm-payment-removal')
 | 
					 | 
				
			||||||
                ->assertSee('Payment method has been successfully removed.');
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testAddingCreditCardStandalone()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->markTestIncomplete("E00117 OTS Service Error 'Field validation error.'");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.payment_methods.index')
 | 
					 | 
				
			||||||
                ->press('Add Payment Method')
 | 
					 | 
				
			||||||
                ->clickLink('Credit Card')
 | 
					 | 
				
			||||||
                ->type('card-number', '4012888818888')
 | 
					 | 
				
			||||||
                ->type('card-holders-name', 'John Doe')
 | 
					 | 
				
			||||||
                ->type('.expiry', '12/28')
 | 
					 | 
				
			||||||
                ->type('cvc', '900')
 | 
					 | 
				
			||||||
                ->press('Add Payment Method')
 | 
					 | 
				
			||||||
                ->waitForText('0027', 60);
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,91 +0,0 @@
 | 
				
			|||||||
<?php
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace Tests\Browser\ClientPortal\Gateways\Braintree;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use App\DataMapper\FeesAndLimits;
 | 
					 | 
				
			||||||
use App\Models\Company;
 | 
					 | 
				
			||||||
use App\Models\CompanyGateway;
 | 
					 | 
				
			||||||
use App\Models\GatewayType;
 | 
					 | 
				
			||||||
use Laravel\Dusk\Browser;
 | 
					 | 
				
			||||||
use Tests\Browser\Pages\ClientPortal\Login;
 | 
					 | 
				
			||||||
use Tests\DuskTestCase;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class ACHTest extends DuskTestCase
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    protected function setUp(): void
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        parent::setUp();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        foreach (static::$browsers as $browser) {
 | 
					 | 
				
			||||||
            $browser->driver->manage()->deleteAllCookies();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visit(new Login())
 | 
					 | 
				
			||||||
                ->auth();
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->disableCompanyGateways();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        CompanyGateway::where('gateway_key', 'f7ec488676d310683fb51802d076d713')->restore();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $cg = CompanyGateway::where('gateway_key', 'f7ec488676d310683fb51802d076d713')->firstOrFail();
 | 
					 | 
				
			||||||
        $fees_and_limits = $cg->fees_and_limits;
 | 
					 | 
				
			||||||
        $fees_and_limits->{GatewayType::BANK_TRANSFER} = new FeesAndLimits();
 | 
					 | 
				
			||||||
        $cg->fees_and_limits = $fees_and_limits;
 | 
					 | 
				
			||||||
        $cg->save();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $company = Company::first();
 | 
					 | 
				
			||||||
        $settings = $company->settings;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $settings->client_portal_allow_under_payment = true;
 | 
					 | 
				
			||||||
        $settings->client_portal_allow_over_payment = true;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $company->settings = $settings;
 | 
					 | 
				
			||||||
        $company->save();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testAddingBankAccount()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.payment_methods.index')
 | 
					 | 
				
			||||||
                ->press('Add Payment Method')
 | 
					 | 
				
			||||||
                ->clickLink('Bank Account')
 | 
					 | 
				
			||||||
                ->type('#account-holder-name', 'John Doe')
 | 
					 | 
				
			||||||
                ->type('#account-number', '1000000000')
 | 
					 | 
				
			||||||
                ->type('#routing-number', '011000015')
 | 
					 | 
				
			||||||
                ->type('#billing-postal-code', '12345')
 | 
					 | 
				
			||||||
                ->press('Add Payment Method')
 | 
					 | 
				
			||||||
                ->waitForText('Added payment method.');
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testPayingWithExistingACH()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.invoices.index')
 | 
					 | 
				
			||||||
                ->click('@pay-now')
 | 
					 | 
				
			||||||
                ->press('Pay Now')
 | 
					 | 
				
			||||||
                ->clickLink('Bank Transfer')
 | 
					 | 
				
			||||||
                ->click('.toggle-payment-with-token')
 | 
					 | 
				
			||||||
                ->press('Pay Now')
 | 
					 | 
				
			||||||
                ->waitForText('Details of the payment', 60);
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testRemoveACHAccount()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.payment_methods.index')
 | 
					 | 
				
			||||||
                ->clickLink('View')
 | 
					 | 
				
			||||||
                ->press('Remove Payment Method')
 | 
					 | 
				
			||||||
                ->waitForText('Confirmation')
 | 
					 | 
				
			||||||
                ->click('@confirm-payment-removal')
 | 
					 | 
				
			||||||
                ->assertSee('Payment method has been successfully removed.');
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,145 +0,0 @@
 | 
				
			|||||||
<?php
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Invoice Ninja (https://invoiceninja.com).
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @license https://www.elastic.co/licensing/elastic-license
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace Tests\Browser\ClientPortal\Gateways\Braintree;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use App\DataMapper\FeesAndLimits;
 | 
					 | 
				
			||||||
use App\Models\Company;
 | 
					 | 
				
			||||||
use App\Models\CompanyGateway;
 | 
					 | 
				
			||||||
use App\Models\GatewayType;
 | 
					 | 
				
			||||||
use Laravel\Dusk\Browser;
 | 
					 | 
				
			||||||
use Tests\Browser\Pages\ClientPortal\Login;
 | 
					 | 
				
			||||||
use Tests\DuskTestCase;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class CreditCardTest extends DuskTestCase
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    protected function setUp(): void
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        parent::setUp();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        foreach (static::$browsers as $browser) {
 | 
					 | 
				
			||||||
            $browser->driver->manage()->deleteAllCookies();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visit(new Login())
 | 
					 | 
				
			||||||
                ->auth();
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->disableCompanyGateways();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        CompanyGateway::where('gateway_key', 'f7ec488676d310683fb51802d076d713')->restore();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $cg = CompanyGateway::where('gateway_key', 'f7ec488676d310683fb51802d076d713')->firstOrFail();
 | 
					 | 
				
			||||||
        $fees_and_limits = $cg->fees_and_limits;
 | 
					 | 
				
			||||||
        $fees_and_limits->{GatewayType::CREDIT_CARD} = new FeesAndLimits();
 | 
					 | 
				
			||||||
        $cg->fees_and_limits = $fees_and_limits;
 | 
					 | 
				
			||||||
        $cg->save();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $company = Company::first();
 | 
					 | 
				
			||||||
        $settings = $company->settings;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $settings->client_portal_allow_under_payment = true;
 | 
					 | 
				
			||||||
        $settings->client_portal_allow_over_payment = true;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $company->settings = $settings;
 | 
					 | 
				
			||||||
        $company->save();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testPayWithNewCard()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.invoices.index')
 | 
					 | 
				
			||||||
                ->click('@pay-now')
 | 
					 | 
				
			||||||
                ->type('@underpayment-input', '100')
 | 
					 | 
				
			||||||
                ->press('Pay Now')
 | 
					 | 
				
			||||||
                ->clickLink('Credit Card')
 | 
					 | 
				
			||||||
                ->waitFor('#braintree-hosted-field-number', 60)
 | 
					 | 
				
			||||||
                ->withinFrame('#braintree-hosted-field-number', function (Browser $browser) {
 | 
					 | 
				
			||||||
                    $browser->type('credit-card-number', '4111111111111111');
 | 
					 | 
				
			||||||
                })
 | 
					 | 
				
			||||||
                ->withinFrame('#braintree-hosted-field-expirationDate', function (Browser $browser) {
 | 
					 | 
				
			||||||
                    $browser->type('expiration', '04/25');
 | 
					 | 
				
			||||||
                })
 | 
					 | 
				
			||||||
                ->press('Pay Now')
 | 
					 | 
				
			||||||
                ->waitForText('Details of the payment', 60);
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testPayWithNewCardAndSaveForFuture()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.invoices.index')
 | 
					 | 
				
			||||||
                ->click('@pay-now')
 | 
					 | 
				
			||||||
                ->type('@underpayment-input', '100')
 | 
					 | 
				
			||||||
                ->press('Pay Now')
 | 
					 | 
				
			||||||
                ->clickLink('Credit Card')
 | 
					 | 
				
			||||||
                ->waitFor('#braintree-hosted-field-number', 60)
 | 
					 | 
				
			||||||
                ->withinFrame('#braintree-hosted-field-number', function (Browser $browser) {
 | 
					 | 
				
			||||||
                    $browser->typeSlowly('credit-card-number', '4005519200000004');
 | 
					 | 
				
			||||||
                })
 | 
					 | 
				
			||||||
                ->withinFrame('#braintree-hosted-field-expirationDate', function (Browser $browser) {
 | 
					 | 
				
			||||||
                    $browser->typeSlowly('expiration', '04/25');
 | 
					 | 
				
			||||||
                })
 | 
					 | 
				
			||||||
                ->radio('#proxy_is_default', true)
 | 
					 | 
				
			||||||
                ->press('Pay Now')
 | 
					 | 
				
			||||||
                ->waitForText('Details of the payment', 60)
 | 
					 | 
				
			||||||
                ->visitRoute('client.payment_methods.index')
 | 
					 | 
				
			||||||
                ->clickLink('View')
 | 
					 | 
				
			||||||
                ->assertSee('0004');
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testPayWithSavedCard()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->markTestSkipped('Works in "real" browser, otherwise giving error code 0.');
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.invoices.index')
 | 
					 | 
				
			||||||
                ->click('@pay-now')
 | 
					 | 
				
			||||||
                ->type('@underpayment-input', '100')
 | 
					 | 
				
			||||||
                ->press('Pay Now')
 | 
					 | 
				
			||||||
                ->clickLink('Credit Card')
 | 
					 | 
				
			||||||
                ->click('.toggle-payment-with-token')
 | 
					 | 
				
			||||||
                ->click('#pay-now-with-token')
 | 
					 | 
				
			||||||
                ->waitForText('Details of the payment', 60);
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testRemoveCreditCard()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.payment_methods.index')
 | 
					 | 
				
			||||||
                ->clickLink('View')
 | 
					 | 
				
			||||||
                ->press('Remove Payment Method')
 | 
					 | 
				
			||||||
                ->waitForText('Confirmation')
 | 
					 | 
				
			||||||
                ->click('@confirm-payment-removal')
 | 
					 | 
				
			||||||
                ->assertSee('Payment method has been successfully removed.');
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testAddingPaymentMethodShouldntBePossible()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.payment_methods.index')
 | 
					 | 
				
			||||||
                ->press('Add Payment Method')
 | 
					 | 
				
			||||||
                ->clickLink('Credit Card')
 | 
					 | 
				
			||||||
                ->assertSee('This payment method can be can saved for future use, once you complete your first transaction. Don\'t forget to check "Store credit card details" during payment process.');
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,45 +0,0 @@
 | 
				
			|||||||
<?php
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Invoice Ninja (https://invoiceninja.com).
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @license https://www.elastic.co/licensing/elastic-license
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace Tests\Browser\ClientPortal\Gateways\Braintree;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use App\Models\CompanyGateway;
 | 
					 | 
				
			||||||
use Laravel\Dusk\Browser;
 | 
					 | 
				
			||||||
use Tests\Browser\Pages\ClientPortal\Login;
 | 
					 | 
				
			||||||
use Tests\DuskTestCase;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class PayPalTest extends DuskTestCase
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    protected function setUp(): void
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        parent::setUp();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        foreach (static::$browsers as $browser) {
 | 
					 | 
				
			||||||
            $browser->driver->manage()->deleteAllCookies();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visit(new Login())
 | 
					 | 
				
			||||||
                ->auth();
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->disableCompanyGateways();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        CompanyGateway::where('gateway_key', 'f7ec488676d310683fb51802d076d713')->restore();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testOffsitePayment()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->markTestSkipped('Sometimes after redirect PayPal shows the register-like page with credit card, sometimes is login page.');
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,127 +0,0 @@
 | 
				
			|||||||
<?php
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Invoice Ninja (https://invoiceninja.com).
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @license https://www.elastic.co/licensing/elastic-license
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace Tests\Browser\ClientPortal\Gateways\CheckoutCom;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use App\Models\CompanyGateway;
 | 
					 | 
				
			||||||
use Laravel\Dusk\Browser;
 | 
					 | 
				
			||||||
use Tests\Browser\Pages\ClientPortal\Login;
 | 
					 | 
				
			||||||
use Tests\DuskTestCase;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class CreditCardTest extends DuskTestCase
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    protected function setUp(): void
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        parent::setUp();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        foreach (static::$browsers as $browser) {
 | 
					 | 
				
			||||||
            $browser->driver->manage()->deleteAllCookies();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->disableCompanyGateways();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        CompanyGateway::where('gateway_key', '3758e7f7c6f4cecf0f4f348b9a00f456')->restore();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visit(new Login())
 | 
					 | 
				
			||||||
                ->auth();
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testPayWithNewCard()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.invoices.index')
 | 
					 | 
				
			||||||
                ->click('@pay-now')
 | 
					 | 
				
			||||||
                ->press('Pay Now')
 | 
					 | 
				
			||||||
                ->clickLink('Credit Card')
 | 
					 | 
				
			||||||
                ->withinFrame('iframe', function (Browser $browser) {
 | 
					 | 
				
			||||||
                    $browser
 | 
					 | 
				
			||||||
                        ->type('cardnumber', '4242424242424242')
 | 
					 | 
				
			||||||
                        ->type('exp-date', '04/22')
 | 
					 | 
				
			||||||
                        ->type('cvc', '100');
 | 
					 | 
				
			||||||
                })
 | 
					 | 
				
			||||||
                ->press('#pay-button')
 | 
					 | 
				
			||||||
                ->waitForText('Details of the payment', 60);
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testPayWithNewCardAndSaveForFutureUse()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.invoices.index')
 | 
					 | 
				
			||||||
                ->click('@pay-now')
 | 
					 | 
				
			||||||
                ->press('Pay Now')
 | 
					 | 
				
			||||||
                ->clickLink('Credit Card')
 | 
					 | 
				
			||||||
                ->withinFrame('iframe', function (Browser $browser) {
 | 
					 | 
				
			||||||
                    $browser
 | 
					 | 
				
			||||||
                        ->type('cardnumber', '4242424242424242')
 | 
					 | 
				
			||||||
                        ->type('exp-date', '04/22')
 | 
					 | 
				
			||||||
                        ->type('cvc', '100');
 | 
					 | 
				
			||||||
                })
 | 
					 | 
				
			||||||
                ->radio('#proxy_is_default', true)
 | 
					 | 
				
			||||||
                ->press('#pay-button')
 | 
					 | 
				
			||||||
                ->waitForText('Details of the payment', 60)
 | 
					 | 
				
			||||||
                ->visitRoute('client.payment_methods.index')
 | 
					 | 
				
			||||||
                ->clickLink('View')
 | 
					 | 
				
			||||||
                ->assertSee('4242');
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testPayWithSavedCreditCard()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.invoices.index')
 | 
					 | 
				
			||||||
                ->click('@pay-now')
 | 
					 | 
				
			||||||
                ->press('Pay Now')
 | 
					 | 
				
			||||||
                ->clickLink('Credit Card')
 | 
					 | 
				
			||||||
                ->click('.toggle-payment-with-token')
 | 
					 | 
				
			||||||
                ->click('#pay-now-with-token')
 | 
					 | 
				
			||||||
                ->waitForText('Details of the payment', 60);
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testRemoveCreditCard()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.payment_methods.index')
 | 
					 | 
				
			||||||
                ->clickLink('View')
 | 
					 | 
				
			||||||
                ->press('Remove Payment Method')
 | 
					 | 
				
			||||||
                ->waitForText('Confirmation')
 | 
					 | 
				
			||||||
                ->click('@confirm-payment-removal')
 | 
					 | 
				
			||||||
                ->assertSee('Payment method has been successfully removed.');
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testAddingCreditCardStandalone()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.payment_methods.index')
 | 
					 | 
				
			||||||
                ->press('Add Payment Method')
 | 
					 | 
				
			||||||
                ->clickLink('Credit Card')
 | 
					 | 
				
			||||||
                ->withinFrame('iframe', function (Browser $browser) {
 | 
					 | 
				
			||||||
                    $browser
 | 
					 | 
				
			||||||
                        ->type('cardnumber', '4242424242424242')
 | 
					 | 
				
			||||||
                        ->type('exp-date', '04/22')
 | 
					 | 
				
			||||||
                        ->type('cvc', '100');
 | 
					 | 
				
			||||||
                })
 | 
					 | 
				
			||||||
                ->press('#pay-button')
 | 
					 | 
				
			||||||
                ->waitForText('Details of payment method', 60);
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,125 +0,0 @@
 | 
				
			|||||||
<?php
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Invoice Ninja (https://invoiceninja.com).
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @license https://www.elastic.co/licensing/elastic-license
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace Tests\Browser\ClientPortal\Gateways\Eway;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use Laravel\Dusk\Browser;
 | 
					 | 
				
			||||||
use Tests\Browser\Pages\ClientPortal\Login;
 | 
					 | 
				
			||||||
use Tests\DuskTestCase;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class CreditCardTest extends DuskTestCase
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    protected function setUp(): void
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        parent::setUp();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        foreach (static::$browsers as $browser) {
 | 
					 | 
				
			||||||
            $browser->driver->manage()->deleteAllCookies();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visit(new Login())
 | 
					 | 
				
			||||||
                ->auth();
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testPaymentWithNewCard()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.invoices.index')
 | 
					 | 
				
			||||||
                ->click('@pay-now')
 | 
					 | 
				
			||||||
                ->click('@pay-now-dropdown')
 | 
					 | 
				
			||||||
                ->clickLink('Credit Card')
 | 
					 | 
				
			||||||
                ->withinFrame('iframe', function (Browser $browser) {
 | 
					 | 
				
			||||||
                    $browser
 | 
					 | 
				
			||||||
                        ->type('EWAY_CARDNAME', 'Invoice Ninja')
 | 
					 | 
				
			||||||
                        ->type('EWAY_CARDNUMBER', '4111 1111 1111 1111')
 | 
					 | 
				
			||||||
                        ->type('EWAY_CARDEXPIRY', '04/22')
 | 
					 | 
				
			||||||
                        ->type('EWAY_CARDCVN', '100');
 | 
					 | 
				
			||||||
                })
 | 
					 | 
				
			||||||
                ->click('#pay-now')
 | 
					 | 
				
			||||||
                ->waitForText('Details of the payment', 60);
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testPayWithNewCardAndSaveForFutureUse()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.invoices.index')
 | 
					 | 
				
			||||||
                ->click('@pay-now')
 | 
					 | 
				
			||||||
                ->click('@pay-now-dropdown')
 | 
					 | 
				
			||||||
                ->clickLink('Credit Card')
 | 
					 | 
				
			||||||
                ->withinFrame('iframe', function (Browser $browser) {
 | 
					 | 
				
			||||||
                    $browser
 | 
					 | 
				
			||||||
                        ->type('EWAY_CARDNAME', 'Invoice Ninja')
 | 
					 | 
				
			||||||
                        ->type('EWAY_CARDNUMBER', '4111 1111 1111 1111')
 | 
					 | 
				
			||||||
                        ->type('EWAY_CARDEXPIRY', '04/22')
 | 
					 | 
				
			||||||
                        ->type('EWAY_CARDCVN', '100');
 | 
					 | 
				
			||||||
                })
 | 
					 | 
				
			||||||
                ->radio('#proxy_is_default', true)
 | 
					 | 
				
			||||||
                ->click('#pay-now')
 | 
					 | 
				
			||||||
                ->waitForText('Details of the payment', 60)
 | 
					 | 
				
			||||||
                ->visitRoute('client.payment_methods.index')
 | 
					 | 
				
			||||||
                ->clickLink('View')
 | 
					 | 
				
			||||||
                ->assertSee('1111');
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testPayWithSavedCreditCard()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.invoices.index')
 | 
					 | 
				
			||||||
                ->click('@pay-now')
 | 
					 | 
				
			||||||
                ->click('@pay-now-dropdown')
 | 
					 | 
				
			||||||
                ->clickLink('Credit Card')
 | 
					 | 
				
			||||||
                ->click('.toggle-payment-with-token')
 | 
					 | 
				
			||||||
                ->click('#pay-now')
 | 
					 | 
				
			||||||
                ->waitForText('Details of the payment', 60);
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testRemoveCreditCard()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.payment_methods.index')
 | 
					 | 
				
			||||||
                ->clickLink('View')
 | 
					 | 
				
			||||||
                ->press('Remove Payment Method')
 | 
					 | 
				
			||||||
                ->waitForText('Confirmation')
 | 
					 | 
				
			||||||
                ->click('@confirm-payment-removal')
 | 
					 | 
				
			||||||
                ->assertSee('Payment method has been successfully removed.');
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testAddingCreditCardStandalone()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.payment_methods.index')
 | 
					 | 
				
			||||||
                ->press('Add Payment Method')
 | 
					 | 
				
			||||||
                ->clickLink('Credit Card')
 | 
					 | 
				
			||||||
                ->withinFrame('iframe', function (Browser $browser) {
 | 
					 | 
				
			||||||
                    $browser
 | 
					 | 
				
			||||||
                        ->type('EWAY_CARDNAME', 'Invoice Ninja')
 | 
					 | 
				
			||||||
                        ->type('EWAY_CARDNUMBER', '4111 1111 1111 1111')
 | 
					 | 
				
			||||||
                        ->type('EWAY_CARDEXPIRY', '04/22')
 | 
					 | 
				
			||||||
                        ->type('EWAY_CARDCVN', '100');
 | 
					 | 
				
			||||||
                })
 | 
					 | 
				
			||||||
                ->press('Add Payment Method')
 | 
					 | 
				
			||||||
                ->waitForText('**** 1111');
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,42 +0,0 @@
 | 
				
			|||||||
<?php
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace Tests\Browser\ClientPortal\Gateways\GoCardless;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use App\Models\CompanyGateway;
 | 
					 | 
				
			||||||
use Laravel\Dusk\Browser;
 | 
					 | 
				
			||||||
use Tests\Browser\Pages\ClientPortal\Login;
 | 
					 | 
				
			||||||
use Tests\DuskTestCase;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class ACHTest extends DuskTestCase
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    protected function setUp(): void
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        parent::setUp();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        foreach (static::$browsers as $browser) {
 | 
					 | 
				
			||||||
            $browser->driver->manage()->deleteAllCookies();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->disableCompanyGateways();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        CompanyGateway::where('gateway_key', 'b9886f9257f0c6ee7c302f1c74475f6c')->restore();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visit(new Login())
 | 
					 | 
				
			||||||
                ->auth();
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testPayingWithNoPreauthorizedIsntPossible()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.invoices.index')
 | 
					 | 
				
			||||||
                ->click('@pay-now')
 | 
					 | 
				
			||||||
                ->press('Pay Now')
 | 
					 | 
				
			||||||
                ->clickLink('Bank Transfer')
 | 
					 | 
				
			||||||
                ->assertSee('To pay with a bank account, first you have to add it as payment method.');
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,42 +0,0 @@
 | 
				
			|||||||
<?php
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace Tests\Browser\ClientPortal\Gateways\GoCardless;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use App\Models\CompanyGateway;
 | 
					 | 
				
			||||||
use Laravel\Dusk\Browser;
 | 
					 | 
				
			||||||
use Tests\Browser\Pages\ClientPortal\Login;
 | 
					 | 
				
			||||||
use Tests\DuskTestCase;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class DirectDebitTest extends DuskTestCase
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    protected function setUp(): void
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        parent::setUp();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        foreach (static::$browsers as $browser) {
 | 
					 | 
				
			||||||
            $browser->driver->manage()->deleteAllCookies();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->disableCompanyGateways();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        CompanyGateway::where('gateway_key', 'b9886f9257f0c6ee7c302f1c74475f6c')->restore();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visit(new Login())
 | 
					 | 
				
			||||||
                ->auth();
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testPayingWithNoPreauthorizedIsntPossible()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.invoices.index')
 | 
					 | 
				
			||||||
                ->click('@pay-now')
 | 
					 | 
				
			||||||
                ->press('Pay Now')
 | 
					 | 
				
			||||||
                ->clickLink('Direct Debit')
 | 
					 | 
				
			||||||
                ->assertSee('To pay with a bank account, first you have to add it as payment method.');
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,42 +0,0 @@
 | 
				
			|||||||
<?php
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace Tests\Browser\ClientPortal\Gateways\GoCardless;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use App\Models\CompanyGateway;
 | 
					 | 
				
			||||||
use Laravel\Dusk\Browser;
 | 
					 | 
				
			||||||
use Tests\Browser\Pages\ClientPortal\Login;
 | 
					 | 
				
			||||||
use Tests\DuskTestCase;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class SEPATest extends DuskTestCase
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    protected function setUp(): void
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        parent::setUp();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        foreach (static::$browsers as $browser) {
 | 
					 | 
				
			||||||
            $browser->driver->manage()->deleteAllCookies();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->disableCompanyGateways();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        CompanyGateway::where('gateway_key', 'b9886f9257f0c6ee7c302f1c74475f6c')->restore();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visit(new Login())
 | 
					 | 
				
			||||||
                ->auth();
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testPayingWithNoPreauthorizedIsntPossible()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.invoices.index')
 | 
					 | 
				
			||||||
                ->click('@pay-now')
 | 
					 | 
				
			||||||
                ->press('Pay Now')
 | 
					 | 
				
			||||||
                ->clickLink('SEPA Direct Debit')
 | 
					 | 
				
			||||||
                ->assertSee('To pay with a bank account, first you have to add it as payment method.');
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,102 +0,0 @@
 | 
				
			|||||||
<?php
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Invoice Ninja (https://invoiceninja.com).
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @license https://www.elastic.co/licensing/elastic-license
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace Tests\Browser\ClientPortal\Gateways\Mollie;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use App\Models\CompanyGateway;
 | 
					 | 
				
			||||||
use Laravel\Dusk\Browser;
 | 
					 | 
				
			||||||
use Tests\Browser\Pages\ClientPortal\Login;
 | 
					 | 
				
			||||||
use Tests\DuskTestCase;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class BancontactTest extends DuskTestCase
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    protected function setUp(): void
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        parent::setUp();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        foreach (static::$browsers as $browser) {
 | 
					 | 
				
			||||||
            $browser->driver->manage()->deleteAllCookies();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->disableCompanyGateways();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        CompanyGateway::where('gateway_key', '1bd651fb213ca0c9d66ae3c336dc77e8')->restore();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visit(new Login())
 | 
					 | 
				
			||||||
                ->auth();
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testSuccessfulPayment(): void
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.invoices.index')
 | 
					 | 
				
			||||||
                ->click('@pay-now')
 | 
					 | 
				
			||||||
                ->press('Pay Now')
 | 
					 | 
				
			||||||
                ->clickLink('Bancontact')
 | 
					 | 
				
			||||||
                ->waitForText('Test profile')
 | 
					 | 
				
			||||||
                ->radio('final_state', 'paid')
 | 
					 | 
				
			||||||
                ->press('Continue')
 | 
					 | 
				
			||||||
                ->waitForText('Details of the payment')
 | 
					 | 
				
			||||||
                ->assertSee('Completed');
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testOpenPayments(): void
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.invoices.index')
 | 
					 | 
				
			||||||
                ->click('@pay-now')
 | 
					 | 
				
			||||||
                ->press('Pay Now')
 | 
					 | 
				
			||||||
                ->clickLink('Bancontact')
 | 
					 | 
				
			||||||
                ->waitForText('Test profile')
 | 
					 | 
				
			||||||
                ->radio('final_state', 'open')
 | 
					 | 
				
			||||||
                ->press('Continue')
 | 
					 | 
				
			||||||
                ->waitForText('Details of the payment')
 | 
					 | 
				
			||||||
                ->assertSee('Pending');
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testFailedPayment(): void
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.invoices.index')
 | 
					 | 
				
			||||||
                ->click('@pay-now')
 | 
					 | 
				
			||||||
                ->press('Pay Now')
 | 
					 | 
				
			||||||
                ->clickLink('Bancontact')
 | 
					 | 
				
			||||||
                ->waitForText('Test profile')
 | 
					 | 
				
			||||||
                ->radio('final_state', 'failed')
 | 
					 | 
				
			||||||
                ->press('Continue')
 | 
					 | 
				
			||||||
                ->waitForText('Failed.');
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testCancelledTest(): void
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.invoices.index')
 | 
					 | 
				
			||||||
                ->click('@pay-now')
 | 
					 | 
				
			||||||
                ->press('Pay Now')
 | 
					 | 
				
			||||||
                ->clickLink('Bancontact')
 | 
					 | 
				
			||||||
                ->waitForText('Test profile')
 | 
					 | 
				
			||||||
                ->radio('final_state', 'canceled')
 | 
					 | 
				
			||||||
                ->press('Continue')
 | 
					 | 
				
			||||||
                ->waitForText('Cancelled.');
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,72 +0,0 @@
 | 
				
			|||||||
<?php
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Invoice Ninja (https://invoiceninja.com).
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @license https://www.elastic.co/licensing/elastic-license
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace Tests\Browser\ClientPortal\Gateways\Mollie;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use App\Models\CompanyGateway;
 | 
					 | 
				
			||||||
use Laravel\Dusk\Browser;
 | 
					 | 
				
			||||||
use Tests\Browser\Pages\ClientPortal\Login;
 | 
					 | 
				
			||||||
use Tests\DuskTestCase;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class BankTransferTest extends DuskTestCase
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    protected function setUp(): void
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        parent::setUp();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        foreach (static::$browsers as $browser) {
 | 
					 | 
				
			||||||
            $browser->driver->manage()->deleteAllCookies();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->disableCompanyGateways();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        CompanyGateway::where('gateway_key', '1bd651fb213ca0c9d66ae3c336dc77e8')->restore();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visit(new Login())
 | 
					 | 
				
			||||||
                ->auth();
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testSuccessfulPayment(): void
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.invoices.index')
 | 
					 | 
				
			||||||
                ->click('@pay-now')
 | 
					 | 
				
			||||||
                ->press('Pay Now')
 | 
					 | 
				
			||||||
                ->clickLink('Bank Transfer')
 | 
					 | 
				
			||||||
                ->waitForText('Test profile')
 | 
					 | 
				
			||||||
                ->radio('final_state', 'paid')
 | 
					 | 
				
			||||||
                ->press('Continue')
 | 
					 | 
				
			||||||
                ->waitForText('Details of the payment')
 | 
					 | 
				
			||||||
                ->assertSee('Completed');
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testPendingPayment(): void
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.invoices.index')
 | 
					 | 
				
			||||||
                ->click('@pay-now')
 | 
					 | 
				
			||||||
                ->press('Pay Now')
 | 
					 | 
				
			||||||
                ->clickLink('Bank Transfer')
 | 
					 | 
				
			||||||
                ->waitForText('Test profile')
 | 
					 | 
				
			||||||
                ->radio('final_state', 'open')
 | 
					 | 
				
			||||||
                ->press('Continue')
 | 
					 | 
				
			||||||
                ->waitForText('Details of the payment')
 | 
					 | 
				
			||||||
                ->assertSee('Pending');
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,134 +0,0 @@
 | 
				
			|||||||
<?php
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Invoice Ninja (https://invoiceninja.com).
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @license https://www.elastic.co/licensing/elastic-license
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace Tests\Browser\ClientPortal\Gateways\Mollie;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use App\Models\CompanyGateway;
 | 
					 | 
				
			||||||
use Laravel\Dusk\Browser;
 | 
					 | 
				
			||||||
use Tests\Browser\Pages\ClientPortal\Login;
 | 
					 | 
				
			||||||
use Tests\DuskTestCase;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class CreditCardTest extends DuskTestCase
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    protected function setUp(): void
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        parent::setUp();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        foreach (static::$browsers as $browser) {
 | 
					 | 
				
			||||||
            $browser->driver->manage()->deleteAllCookies();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->disableCompanyGateways();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        CompanyGateway::where('gateway_key', '1bd651fb213ca0c9d66ae3c336dc77e8')->restore();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visit(new Login())
 | 
					 | 
				
			||||||
                ->auth();
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testPayWithNewCreditCard()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.invoices.index')
 | 
					 | 
				
			||||||
                ->click('@pay-now')
 | 
					 | 
				
			||||||
                ->press('Pay Now')
 | 
					 | 
				
			||||||
                ->clickLink('Credit Card')
 | 
					 | 
				
			||||||
                ->pause(5000)
 | 
					 | 
				
			||||||
                ->withinFrame('iframe[name=cardNumber-input]', function (Browser $browser) {
 | 
					 | 
				
			||||||
                    $browser->type('#cardNumber', '4242424242424242');
 | 
					 | 
				
			||||||
                })
 | 
					 | 
				
			||||||
                ->withinFrame('iframe[name=cardHolder-input]', function (Browser $browser) {
 | 
					 | 
				
			||||||
                    $browser->type('#cardHolder', 'Invoice Ninja Test Suite');
 | 
					 | 
				
			||||||
                })
 | 
					 | 
				
			||||||
                ->withinFrame('iframe[name=expiryDate-input]', function (Browser $browser) {
 | 
					 | 
				
			||||||
                    $browser->type('#expiryDate', '12/29');
 | 
					 | 
				
			||||||
                })
 | 
					 | 
				
			||||||
                ->withinFrame('iframe[name=verificationCode-input]', function (Browser $browser) {
 | 
					 | 
				
			||||||
                    $browser->type('#verificationCode', '100');
 | 
					 | 
				
			||||||
                })
 | 
					 | 
				
			||||||
                ->press('Pay Now')
 | 
					 | 
				
			||||||
                ->waitForText('Details of the payment', 60);
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testPayWithNewCreditCardAndSaveForFutureUse()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.invoices.index')
 | 
					 | 
				
			||||||
                ->click('@pay-now')
 | 
					 | 
				
			||||||
                ->press('Pay Now')
 | 
					 | 
				
			||||||
                ->clickLink('Credit Card')
 | 
					 | 
				
			||||||
                ->pause(5000)
 | 
					 | 
				
			||||||
                ->withinFrame('iframe[name=cardNumber-input]', function (Browser $browser) {
 | 
					 | 
				
			||||||
                    $browser->type('#cardNumber', '4242424242424242');
 | 
					 | 
				
			||||||
                })
 | 
					 | 
				
			||||||
                ->withinFrame('iframe[name=cardHolder-input]', function (Browser $browser) {
 | 
					 | 
				
			||||||
                    $browser->type('#cardHolder', 'Invoice Ninja Test Suite');
 | 
					 | 
				
			||||||
                })
 | 
					 | 
				
			||||||
                ->withinFrame('iframe[name=expiryDate-input]', function (Browser $browser) {
 | 
					 | 
				
			||||||
                    $browser->type('#expiryDate', '12/29');
 | 
					 | 
				
			||||||
                })
 | 
					 | 
				
			||||||
                ->withinFrame('iframe[name=verificationCode-input]', function (Browser $browser) {
 | 
					 | 
				
			||||||
                    $browser->type('#verificationCode', '100');
 | 
					 | 
				
			||||||
                })
 | 
					 | 
				
			||||||
                ->radio('#proxy_is_default', true)
 | 
					 | 
				
			||||||
                ->press('Pay Now')
 | 
					 | 
				
			||||||
                ->waitForText('Details of the payment', 60)
 | 
					 | 
				
			||||||
                ->visitRoute('client.payment_methods.index')
 | 
					 | 
				
			||||||
                ->clickLink('View')
 | 
					 | 
				
			||||||
                ->assertSee('4242');
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testPayWithSavedCreditCard()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.invoices.index')
 | 
					 | 
				
			||||||
                ->click('@pay-now')
 | 
					 | 
				
			||||||
                ->press('Pay Now')
 | 
					 | 
				
			||||||
                ->clickLink('Credit Card')
 | 
					 | 
				
			||||||
                ->click('.toggle-payment-with-token')
 | 
					 | 
				
			||||||
                ->press('Pay Now')
 | 
					 | 
				
			||||||
                ->waitForText('Details of the payment', 60);
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testAddingPaymentMethodShouldntBePossible()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.payment_methods.index')
 | 
					 | 
				
			||||||
                ->press('Add Payment Method')
 | 
					 | 
				
			||||||
                ->clickLink('Credit Card')
 | 
					 | 
				
			||||||
                ->assertSee('This payment method can be can saved for future use, once you complete your first transaction. Don\'t forget to check "Store credit card details" during payment process.');
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testRemoveCreditCard()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.payment_methods.index')
 | 
					 | 
				
			||||||
                ->clickLink('View')
 | 
					 | 
				
			||||||
                ->press('Remove Payment Method')
 | 
					 | 
				
			||||||
                ->waitForText('Confirmation')
 | 
					 | 
				
			||||||
                ->click('@confirm-payment-removal')
 | 
					 | 
				
			||||||
                ->assertSee('Payment method has been successfully removed.');
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,106 +0,0 @@
 | 
				
			|||||||
<?php
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Invoice Ninja (https://invoiceninja.com).
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @license https://www.elastic.co/licensing/elastic-license
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace Tests\Browser\ClientPortal\Gateways\Mollie;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use App\Models\CompanyGateway;
 | 
					 | 
				
			||||||
use Laravel\Dusk\Browser;
 | 
					 | 
				
			||||||
use Tests\Browser\Pages\ClientPortal\Login;
 | 
					 | 
				
			||||||
use Tests\DuskTestCase;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class IDEALTest extends DuskTestCase
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    protected function setUp(): void
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        parent::setUp();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        foreach (static::$browsers as $browser) {
 | 
					 | 
				
			||||||
            $browser->driver->manage()->deleteAllCookies();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->disableCompanyGateways();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        CompanyGateway::where('gateway_key', '1bd651fb213ca0c9d66ae3c336dc77e8')->restore();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visit(new Login())
 | 
					 | 
				
			||||||
                ->auth();
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testSuccessfulPayment(): void
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.invoices.index')
 | 
					 | 
				
			||||||
                ->click('@pay-now')
 | 
					 | 
				
			||||||
                ->press('Pay Now')
 | 
					 | 
				
			||||||
                ->clickLink('iDEAL')
 | 
					 | 
				
			||||||
                ->waitForText('Test profile')
 | 
					 | 
				
			||||||
                ->press('ABN AMRO')
 | 
					 | 
				
			||||||
                ->radio('final_state', 'paid')
 | 
					 | 
				
			||||||
                ->press('Continue')
 | 
					 | 
				
			||||||
                ->waitForText('Details of the payment')
 | 
					 | 
				
			||||||
                ->assertSee('Completed');
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testOpenPayment(): void
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.invoices.index')
 | 
					 | 
				
			||||||
                ->click('@pay-now')
 | 
					 | 
				
			||||||
                ->press('Pay Now')
 | 
					 | 
				
			||||||
                ->clickLink('iDEAL')
 | 
					 | 
				
			||||||
                ->waitForText('Test profile')
 | 
					 | 
				
			||||||
                ->press('ABN AMRO')
 | 
					 | 
				
			||||||
                ->radio('final_state', 'open')
 | 
					 | 
				
			||||||
                ->press('Continue')
 | 
					 | 
				
			||||||
                ->waitForText('Details of the payment')
 | 
					 | 
				
			||||||
                ->assertSee('Pending');
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testFailedPayment(): void
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.invoices.index')
 | 
					 | 
				
			||||||
                ->click('@pay-now')
 | 
					 | 
				
			||||||
                ->press('Pay Now')
 | 
					 | 
				
			||||||
                ->clickLink('iDEAL')
 | 
					 | 
				
			||||||
                ->waitForText('Test profile')
 | 
					 | 
				
			||||||
                ->press('ABN AMRO')
 | 
					 | 
				
			||||||
                ->radio('final_state', 'failed')
 | 
					 | 
				
			||||||
                ->press('Continue')
 | 
					 | 
				
			||||||
                ->waitForText('Failed.');
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testCancelledPayment(): void
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.invoices.index')
 | 
					 | 
				
			||||||
                ->click('@pay-now')
 | 
					 | 
				
			||||||
                ->press('Pay Now')
 | 
					 | 
				
			||||||
                ->clickLink('iDEAL')
 | 
					 | 
				
			||||||
                ->waitForText('Test profile')
 | 
					 | 
				
			||||||
                ->press('ABN AMRO')
 | 
					 | 
				
			||||||
                ->radio('final_state', 'canceled')
 | 
					 | 
				
			||||||
                ->press('Continue')
 | 
					 | 
				
			||||||
                ->waitForText('Cancelled.');
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,89 +0,0 @@
 | 
				
			|||||||
<?php
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Invoice Ninja (https://invoiceninja.com).
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @license https://www.elastic.co/licensing/elastic-license
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace Tests\Browser\ClientPortal\Gateways\Mollie;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use App\Models\CompanyGateway;
 | 
					 | 
				
			||||||
use Laravel\Dusk\Browser;
 | 
					 | 
				
			||||||
use Tests\Browser\Pages\ClientPortal\Login;
 | 
					 | 
				
			||||||
use Tests\DuskTestCase;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class KBCTest extends DuskTestCase
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    protected function setUp(): void
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        parent::setUp();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        foreach (static::$browsers as $browser) {
 | 
					 | 
				
			||||||
            $browser->driver->manage()->deleteAllCookies();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->disableCompanyGateways();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        CompanyGateway::where('gateway_key', '1bd651fb213ca0c9d66ae3c336dc77e8')->restore();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visit(new Login())
 | 
					 | 
				
			||||||
                ->auth();
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testSuccessfulPayment(): void
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.invoices.index')
 | 
					 | 
				
			||||||
                ->click('@pay-now')
 | 
					 | 
				
			||||||
                ->press('Pay Now')
 | 
					 | 
				
			||||||
                ->clickLink('Undefined.')
 | 
					 | 
				
			||||||
                ->waitForText('Test profile')
 | 
					 | 
				
			||||||
                ->press('CBC')
 | 
					 | 
				
			||||||
                ->radio('final_state', 'paid')
 | 
					 | 
				
			||||||
                ->press('Continue')
 | 
					 | 
				
			||||||
                ->waitForText('Details of the payment')
 | 
					 | 
				
			||||||
                ->assertSee('Completed');
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testFailedPayment(): void
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.invoices.index')
 | 
					 | 
				
			||||||
                ->click('@pay-now')
 | 
					 | 
				
			||||||
                ->press('Pay Now')
 | 
					 | 
				
			||||||
                ->clickLink('Undefined.')
 | 
					 | 
				
			||||||
                ->waitForText('Test profile')
 | 
					 | 
				
			||||||
                ->press('CBC')
 | 
					 | 
				
			||||||
                ->radio('final_state', 'failed')
 | 
					 | 
				
			||||||
                ->press('Continue')
 | 
					 | 
				
			||||||
                ->waitForText('Failed.');
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testCancelledTest(): void
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.invoices.index')
 | 
					 | 
				
			||||||
                ->click('@pay-now')
 | 
					 | 
				
			||||||
                ->press('Pay Now')
 | 
					 | 
				
			||||||
                ->clickLink('Undefined.')
 | 
					 | 
				
			||||||
                ->waitForText('Test profile')
 | 
					 | 
				
			||||||
                ->press('CBC')
 | 
					 | 
				
			||||||
                ->radio('final_state', 'canceled')
 | 
					 | 
				
			||||||
                ->press('Continue')
 | 
					 | 
				
			||||||
                ->waitForText('Cancelled.');
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,40 +0,0 @@
 | 
				
			|||||||
<?php
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Invoice Ninja (https://invoiceninja.com).
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @license https://www.elastic.co/licensing/elastic-license
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace Tests\Browser\ClientPortal\Gateways\PayPal;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use Laravel\Dusk\Browser;
 | 
					 | 
				
			||||||
use Tests\Browser\Pages\ClientPortal\Login;
 | 
					 | 
				
			||||||
use Tests\DuskTestCase;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class PayPalTest extends DuskTestCase
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    protected function setUp(): void
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        parent::setUp();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        foreach (static::$browsers as $browser) {
 | 
					 | 
				
			||||||
            $browser->driver->manage()->deleteAllCookies();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visit(new Login())
 | 
					 | 
				
			||||||
                ->auth();
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testOffsitePayment()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->markTestSkipped('Sometimes after redirect PayPal shows the register-like page with credit card, sometimes is login page.');
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,62 +0,0 @@
 | 
				
			|||||||
<?php
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Invoice Ninja (https://invoiceninja.com).
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @license https://www.elastic.co/licensing/elastic-license
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace Tests\Browser\ClientPortal\Gateways\PayTrace;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use App\Models\CompanyGateway;
 | 
					 | 
				
			||||||
use Laravel\Dusk\Browser;
 | 
					 | 
				
			||||||
use Tests\Browser\Pages\ClientPortal\Login;
 | 
					 | 
				
			||||||
use Tests\DuskTestCase;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class CreditCardTest extends DuskTestCase
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    protected function setUp(): void
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        parent::setUp();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        foreach (static::$browsers as $browser) {
 | 
					 | 
				
			||||||
            $browser->driver->manage()->deleteAllCookies();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->disableCompanyGateways();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        CompanyGateway::where('gateway_key', 'bbd736b3254b0aabed6ad7fda1298c88')->restore();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visit(new Login())
 | 
					 | 
				
			||||||
                ->auth();
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testPayingWithNewCreditCard()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->markTestSkipped('Credit card not supported.');
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.invoices.index')
 | 
					 | 
				
			||||||
                ->click('@pay-now')
 | 
					 | 
				
			||||||
                ->press('Pay Now')
 | 
					 | 
				
			||||||
                ->clickLink('Credit Card')
 | 
					 | 
				
			||||||
                ->withinFrame('iframe', function (Browser $browser) {
 | 
					 | 
				
			||||||
                    $browser
 | 
					 | 
				
			||||||
                        ->type('CC', '4012000098765439')
 | 
					 | 
				
			||||||
                        ->select('EXP_MM', '12')
 | 
					 | 
				
			||||||
                        ->select('EXP_YY', '30')
 | 
					 | 
				
			||||||
                        ->type('SEC', '999');
 | 
					 | 
				
			||||||
                })
 | 
					 | 
				
			||||||
                ->press('Pay Now')
 | 
					 | 
				
			||||||
                ->waitForText('Details of the payment', 60);
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,128 +0,0 @@
 | 
				
			|||||||
<?php
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Invoice Ninja (https://invoiceninja.com).
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @license https://www.elastic.co/licensing/elastic-license
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace Tests\Browser\ClientPortal\Gateways\Square;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use Laravel\Dusk\Browser;
 | 
					 | 
				
			||||||
use Tests\Browser\Pages\ClientPortal\Login;
 | 
					 | 
				
			||||||
use Tests\DuskTestCase;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class CreditCardTest extends DuskTestCase
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    protected function setUp(): void
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        parent::setUp();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        foreach (static::$browsers as $browser) {
 | 
					 | 
				
			||||||
            $browser->driver->manage()->deleteAllCookies();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visit(new Login())
 | 
					 | 
				
			||||||
                ->auth();
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testPaymentWithNewCard()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.invoices.index')
 | 
					 | 
				
			||||||
                ->click('@pay-now')
 | 
					 | 
				
			||||||
                ->click('@pay-now-dropdown')
 | 
					 | 
				
			||||||
                ->clickLink('Credit Card')
 | 
					 | 
				
			||||||
                ->type('#cardholder-name', 'John Doe')
 | 
					 | 
				
			||||||
                ->withinFrame('iframe', function (Browser $browser) {
 | 
					 | 
				
			||||||
                    $browser
 | 
					 | 
				
			||||||
                        ->type('#cardNumber', '4111 1111 1111 1111')
 | 
					 | 
				
			||||||
                        ->type('#expirationDate', '04/22')
 | 
					 | 
				
			||||||
                        ->type('#cvv', '1111')
 | 
					 | 
				
			||||||
                        ->type('#postalCode', '12345');
 | 
					 | 
				
			||||||
                })
 | 
					 | 
				
			||||||
                ->click('#pay-now')
 | 
					 | 
				
			||||||
                ->waitForText('Details of the payment', 60);
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testPayWithNewCardAndSaveForFutureUse()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.invoices.index')
 | 
					 | 
				
			||||||
                ->click('@pay-now')
 | 
					 | 
				
			||||||
                ->click('@pay-now-dropdown')
 | 
					 | 
				
			||||||
                ->clickLink('Credit Card')
 | 
					 | 
				
			||||||
                ->type('#cardholder-name', 'John Doe')
 | 
					 | 
				
			||||||
                ->withinFrame('iframe', function (Browser $browser) {
 | 
					 | 
				
			||||||
                    $browser
 | 
					 | 
				
			||||||
                        ->type('#cardNumber', '4111 1111 1111 1111')
 | 
					 | 
				
			||||||
                        ->type('#expirationDate', '04/22')
 | 
					 | 
				
			||||||
                        ->type('#cvv', '1111')
 | 
					 | 
				
			||||||
                        ->type('#postalCode', '12345');
 | 
					 | 
				
			||||||
                })
 | 
					 | 
				
			||||||
                ->radio('#proxy_is_default', true)
 | 
					 | 
				
			||||||
                ->click('#pay-now')
 | 
					 | 
				
			||||||
                ->waitForText('Details of the payment', 60)
 | 
					 | 
				
			||||||
                ->visitRoute('client.payment_methods.index')
 | 
					 | 
				
			||||||
                ->clickLink('View')
 | 
					 | 
				
			||||||
                ->assertSee('4242');
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testPayWithSavedCreditCard()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.invoices.index')
 | 
					 | 
				
			||||||
                ->click('@pay-now')
 | 
					 | 
				
			||||||
                ->click('@pay-now-dropdown')
 | 
					 | 
				
			||||||
                ->clickLink('Credit Card')
 | 
					 | 
				
			||||||
                ->click('.toggle-payment-with-token')
 | 
					 | 
				
			||||||
                ->click('#pay-now')
 | 
					 | 
				
			||||||
                ->waitForText('Details of the payment', 60);
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testRemoveCreditCard()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.payment_methods.index')
 | 
					 | 
				
			||||||
                ->clickLink('View')
 | 
					 | 
				
			||||||
                ->press('Remove Payment Method')
 | 
					 | 
				
			||||||
                ->waitForText('Confirmation')
 | 
					 | 
				
			||||||
                ->click('@confirm-payment-removal')
 | 
					 | 
				
			||||||
                ->assertSee('Payment method has been successfully removed.');
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testAddingCreditCardStandalone()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.payment_methods.index')
 | 
					 | 
				
			||||||
                ->press('Add Payment Method')
 | 
					 | 
				
			||||||
                ->clickLink('Credit Card')
 | 
					 | 
				
			||||||
                ->type('#cardholder-name', 'John Doe')
 | 
					 | 
				
			||||||
                ->withinFrame('iframe', function (Browser $browser) {
 | 
					 | 
				
			||||||
                    $browser
 | 
					 | 
				
			||||||
                        ->type('#cardNumber', '4111 1111 1111 1111')
 | 
					 | 
				
			||||||
                        ->type('#expirationDate', '04/22')
 | 
					 | 
				
			||||||
                        ->type('#cvv', '1111')
 | 
					 | 
				
			||||||
                        ->type('#postalCode', '12345');
 | 
					 | 
				
			||||||
                })
 | 
					 | 
				
			||||||
                ->press('Add Payment Method')
 | 
					 | 
				
			||||||
                ->waitForText('**** 1111');
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,133 +0,0 @@
 | 
				
			|||||||
<?php
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Invoice Ninja (https://invoiceninja.com).
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @license https://www.elastic.co/licensing/elastic-license
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace Tests\Browser\ClientPortal\Gateways\Stripe;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use App\DataMapper\FeesAndLimits;
 | 
					 | 
				
			||||||
use App\Models\Client;
 | 
					 | 
				
			||||||
use App\Models\CompanyGateway;
 | 
					 | 
				
			||||||
use App\Models\GatewayType;
 | 
					 | 
				
			||||||
use Laravel\Dusk\Browser;
 | 
					 | 
				
			||||||
use Tests\Browser\Pages\ClientPortal\Login;
 | 
					 | 
				
			||||||
use Tests\DuskTestCase;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class ACHTest extends DuskTestCase
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    protected function setUp(): void
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        parent::setUp();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        foreach (static::$browsers as $browser) {
 | 
					 | 
				
			||||||
            $browser->driver->manage()->deleteAllCookies();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visit(new Login())
 | 
					 | 
				
			||||||
                ->auth();
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->disableCompanyGateways();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Enable Stripe.
 | 
					 | 
				
			||||||
        CompanyGateway::where('gateway_key', 'd14dd26a37cecc30fdd65700bfb55b23')->restore();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Enable ACH.
 | 
					 | 
				
			||||||
        $cg = CompanyGateway::where('gateway_key', 'd14dd26a37cecc30fdd65700bfb55b23')->firstOrFail();
 | 
					 | 
				
			||||||
        $fees_and_limits = $cg->fees_and_limits;
 | 
					 | 
				
			||||||
        $fees_and_limits->{GatewayType::BANK_TRANSFER} = new FeesAndLimits();
 | 
					 | 
				
			||||||
        $cg->fees_and_limits = $fees_and_limits;
 | 
					 | 
				
			||||||
        $cg->save();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // ACH required US to be billing country.
 | 
					 | 
				
			||||||
        $client = Client::first();
 | 
					 | 
				
			||||||
        $client->country_id = 840;
 | 
					 | 
				
			||||||
        $client->save();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testAddingACHAccountAndVerifyingIt()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.payment_methods.index')
 | 
					 | 
				
			||||||
                ->press('Add Payment Method')
 | 
					 | 
				
			||||||
                ->clickLink('Bank Account')
 | 
					 | 
				
			||||||
                ->type('#account-holder-name', 'John Doe')
 | 
					 | 
				
			||||||
                ->select('#country', 'US')
 | 
					 | 
				
			||||||
                ->select('#currency', 'USD')
 | 
					 | 
				
			||||||
                ->type('#routing-number', '110000000')
 | 
					 | 
				
			||||||
                ->type('#account-number', '000123456789')
 | 
					 | 
				
			||||||
                ->check('#accept-terms')
 | 
					 | 
				
			||||||
                ->press('Add Payment Method')
 | 
					 | 
				
			||||||
                ->waitForText('ACH (Verification)', 60)
 | 
					 | 
				
			||||||
                ->type('@verification-1st', '32')
 | 
					 | 
				
			||||||
                ->type('@verification-2nd', '45')
 | 
					 | 
				
			||||||
                ->press('Complete Verification')
 | 
					 | 
				
			||||||
                ->assertSee('Verification completed successfully')
 | 
					 | 
				
			||||||
                ->assertSee('Bank Transfer');
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testPayingWithExistingACH()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.invoices.index')
 | 
					 | 
				
			||||||
                ->click('@pay-now')
 | 
					 | 
				
			||||||
                ->press('Pay Now')
 | 
					 | 
				
			||||||
                ->clickLink('Bank Transfer')
 | 
					 | 
				
			||||||
                ->click('.toggle-payment-with-token')
 | 
					 | 
				
			||||||
                ->press('Pay Now')
 | 
					 | 
				
			||||||
                ->waitForText('Details of the payment', 60);
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testRemoveACHAccount()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.payment_methods.index')
 | 
					 | 
				
			||||||
                ->clickLink('View')
 | 
					 | 
				
			||||||
                ->press('Remove Payment Method')
 | 
					 | 
				
			||||||
                ->waitForText('Confirmation')
 | 
					 | 
				
			||||||
                ->click('@confirm-payment-removal')
 | 
					 | 
				
			||||||
                ->assertSee('Payment method has been successfully removed.');
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testIntegerAndMinimumValueOnVerification()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.payment_methods.index')
 | 
					 | 
				
			||||||
                ->press('Add Payment Method')
 | 
					 | 
				
			||||||
                ->clickLink('Bank Account')
 | 
					 | 
				
			||||||
                ->type('#account-holder-name', 'John Doe')
 | 
					 | 
				
			||||||
                ->select('#country', 'US')
 | 
					 | 
				
			||||||
                ->select('#currency', 'USD')
 | 
					 | 
				
			||||||
                ->type('#routing-number', '110000000')
 | 
					 | 
				
			||||||
                ->type('#account-number', '000123456789')
 | 
					 | 
				
			||||||
                ->check('#accept-terms')
 | 
					 | 
				
			||||||
                ->press('Add Payment Method')
 | 
					 | 
				
			||||||
                ->waitForText('ACH (Verification)', 60)
 | 
					 | 
				
			||||||
                ->type('@verification-1st', '0.1')
 | 
					 | 
				
			||||||
                ->type('@verification-2nd', '0')
 | 
					 | 
				
			||||||
                ->press('Complete Verification')
 | 
					 | 
				
			||||||
                ->assertSee('The transactions.0 must be an integer')
 | 
					 | 
				
			||||||
                ->assertSee('The transactions.1 must be at least 1')
 | 
					 | 
				
			||||||
                ->type('@verification-1st', '32')
 | 
					 | 
				
			||||||
                ->type('@verification-2nd', '45')
 | 
					 | 
				
			||||||
                ->press('Complete Verification')
 | 
					 | 
				
			||||||
                ->assertSee('Bank Transfer');
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,75 +0,0 @@
 | 
				
			|||||||
<?php
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Invoice Ninja (https://invoiceninja.com).
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @license https://www.elastic.co/licensing/elastic-license
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace Tests\Browser\ClientPortal\Gateways\Stripe;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use App\DataMapper\FeesAndLimits;
 | 
					 | 
				
			||||||
use App\Models\Client;
 | 
					 | 
				
			||||||
use App\Models\CompanyGateway;
 | 
					 | 
				
			||||||
use App\Models\GatewayType;
 | 
					 | 
				
			||||||
use Laravel\Dusk\Browser;
 | 
					 | 
				
			||||||
use Tests\Browser\Pages\ClientPortal\Login;
 | 
					 | 
				
			||||||
use Tests\DuskTestCase;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class ACSSTest extends DuskTestCase
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    protected function setUp(): void
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        parent::setUp();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        foreach (static::$browsers as $browser) {
 | 
					 | 
				
			||||||
            $browser->driver->manage()->deleteAllCookies();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visit(new Login())
 | 
					 | 
				
			||||||
                ->auth();
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->disableCompanyGateways();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Enable Stripe.
 | 
					 | 
				
			||||||
        CompanyGateway::where('gateway_key', 'd14dd26a37cecc30fdd65700bfb55b23')->restore();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Enable SOFORT.
 | 
					 | 
				
			||||||
        $cg = CompanyGateway::where('gateway_key', 'd14dd26a37cecc30fdd65700bfb55b23')->firstOrFail();
 | 
					 | 
				
			||||||
        $fees_and_limits = $cg->fees_and_limits;
 | 
					 | 
				
			||||||
        $fees_and_limits->{GatewayType::ACSS} = new FeesAndLimits();
 | 
					 | 
				
			||||||
        $cg->fees_and_limits = $fees_and_limits;
 | 
					 | 
				
			||||||
        $cg->save();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $client = Client::first();
 | 
					 | 
				
			||||||
        $client->country_id = 276; // Change to US or Canada
 | 
					 | 
				
			||||||
        $client->save();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testPayingWithACSS()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.invoices.index')
 | 
					 | 
				
			||||||
                ->click('@pay-now')
 | 
					 | 
				
			||||||
                ->press('Pay Now')
 | 
					 | 
				
			||||||
                ->clickLink('ACSS')
 | 
					 | 
				
			||||||
                ->type('#acss-name', 'John Doe')
 | 
					 | 
				
			||||||
                ->type('#acss-name', 'John@Doe.com')
 | 
					 | 
				
			||||||
                ->withinFrame('iframe', function (Browser $browser) {
 | 
					 | 
				
			||||||
                    $browser->type('acss', '12345');
 | 
					 | 
				
			||||||
                })
 | 
					 | 
				
			||||||
                ->click('#pay-now')
 | 
					 | 
				
			||||||
                ->waitForText('ACSS test payment page', 120)
 | 
					 | 
				
			||||||
                ->press('.common-Button.common-Button--default')
 | 
					 | 
				
			||||||
                ->waitForText('Details of the payment', 60);
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,71 +0,0 @@
 | 
				
			|||||||
<?php
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Invoice Ninja (https://invoiceninja.com).
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @license https://www.elastic.co/licensing/elastic-license
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace Tests\Browser\ClientPortal\Gateways\Stripe;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use App\DataMapper\FeesAndLimits;
 | 
					 | 
				
			||||||
use App\Models\Client;
 | 
					 | 
				
			||||||
use App\Models\CompanyGateway;
 | 
					 | 
				
			||||||
use App\Models\GatewayType;
 | 
					 | 
				
			||||||
use Laravel\Dusk\Browser;
 | 
					 | 
				
			||||||
use Tests\Browser\Pages\ClientPortal\Login;
 | 
					 | 
				
			||||||
use Tests\DuskTestCase;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class AlipayTest extends DuskTestCase
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    protected function setUp(): void
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        parent::setUp();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        foreach (static::$browsers as $browser) {
 | 
					 | 
				
			||||||
            $browser->driver->manage()->deleteAllCookies();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visit(new Login())
 | 
					 | 
				
			||||||
                ->auth();
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->disableCompanyGateways();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Enable Stripe.
 | 
					 | 
				
			||||||
        CompanyGateway::where('gateway_key', 'd14dd26a37cecc30fdd65700bfb55b23')->restore();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Enable Alipay.
 | 
					 | 
				
			||||||
        $cg = CompanyGateway::where('gateway_key', 'd14dd26a37cecc30fdd65700bfb55b23')->firstOrFail();
 | 
					 | 
				
			||||||
        $fees_and_limits = $cg->fees_and_limits;
 | 
					 | 
				
			||||||
        $fees_and_limits->{GatewayType::ALIPAY} = new FeesAndLimits();
 | 
					 | 
				
			||||||
        $cg->fees_and_limits = $fees_and_limits;
 | 
					 | 
				
			||||||
        $cg->save();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Setting country  to DEU (276).
 | 
					 | 
				
			||||||
        $client = Client::first();
 | 
					 | 
				
			||||||
        $client->country_id = 276;
 | 
					 | 
				
			||||||
        $client->save();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testPayingWithAlipay()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.invoices.index')
 | 
					 | 
				
			||||||
                ->click('@pay-now')
 | 
					 | 
				
			||||||
                ->press('Pay Now')
 | 
					 | 
				
			||||||
                ->clickLink('Alipay')
 | 
					 | 
				
			||||||
                ->press('Pay Now')
 | 
					 | 
				
			||||||
                ->waitForText('Alipay test payment page', 120)
 | 
					 | 
				
			||||||
                ->press('.common-Button.common-Button--default')
 | 
					 | 
				
			||||||
                ->waitForText('Details of the payment', 60);
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,75 +0,0 @@
 | 
				
			|||||||
<?php
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Invoice Ninja (https://invoiceninja.com).
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @license https://www.elastic.co/licensing/elastic-license
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace Tests\Browser\ClientPortal\Gateways\Stripe;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use App\DataMapper\FeesAndLimits;
 | 
					 | 
				
			||||||
use App\Models\Client;
 | 
					 | 
				
			||||||
use App\Models\CompanyGateway;
 | 
					 | 
				
			||||||
use App\Models\GatewayType;
 | 
					 | 
				
			||||||
use Laravel\Dusk\Browser;
 | 
					 | 
				
			||||||
use Tests\Browser\Pages\ClientPortal\Login;
 | 
					 | 
				
			||||||
use Tests\DuskTestCase;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class BECSTest extends DuskTestCase
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    protected function setUp(): void
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        parent::setUp();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        foreach (static::$browsers as $browser) {
 | 
					 | 
				
			||||||
            $browser->driver->manage()->deleteAllCookies();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visit(new Login())
 | 
					 | 
				
			||||||
                ->auth();
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->disableCompanyGateways();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Enable Stripe.
 | 
					 | 
				
			||||||
        CompanyGateway::where('gateway_key', 'd14dd26a37cecc30fdd65700bfb55b23')->restore();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Enable SOFORT.
 | 
					 | 
				
			||||||
        $cg = CompanyGateway::where('gateway_key', 'd14dd26a37cecc30fdd65700bfb55b23')->firstOrFail();
 | 
					 | 
				
			||||||
        $fees_and_limits = $cg->fees_and_limits;
 | 
					 | 
				
			||||||
        $fees_and_limits->{GatewayType::BECS} = new FeesAndLimits();
 | 
					 | 
				
			||||||
        $cg->fees_and_limits = $fees_and_limits;
 | 
					 | 
				
			||||||
        $cg->save();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $client = Client::first();
 | 
					 | 
				
			||||||
        $client->country_id = 276; // Change to austria
 | 
					 | 
				
			||||||
        $client->save();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testPayingWithBECS()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.invoices.index')
 | 
					 | 
				
			||||||
                ->click('@pay-now')
 | 
					 | 
				
			||||||
                ->press('Pay Now')
 | 
					 | 
				
			||||||
                ->clickLink('BECS')
 | 
					 | 
				
			||||||
                ->type('#becs-name', 'John Doe')
 | 
					 | 
				
			||||||
                ->type('#becs-email', 'john@doe.com')
 | 
					 | 
				
			||||||
                ->withinFrame('iframe', function (Browser $browser) {
 | 
					 | 
				
			||||||
                    $browser->type('becs-iban', '000123456');
 | 
					 | 
				
			||||||
                })
 | 
					 | 
				
			||||||
                ->click('#pay-now')
 | 
					 | 
				
			||||||
                ->waitForText('BECS test payment page', 120)
 | 
					 | 
				
			||||||
                ->press('.common-Button.common-Button--default')
 | 
					 | 
				
			||||||
                ->waitForText('Details of the payment', 60);
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,71 +0,0 @@
 | 
				
			|||||||
<?php
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Invoice Ninja (https://invoiceninja.com).
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @license https://www.elastic.co/licensing/elastic-license
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace Tests\Browser\ClientPortal\Gateways\Stripe;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use App\DataMapper\FeesAndLimits;
 | 
					 | 
				
			||||||
use App\Models\Client;
 | 
					 | 
				
			||||||
use App\Models\CompanyGateway;
 | 
					 | 
				
			||||||
use App\Models\GatewayType;
 | 
					 | 
				
			||||||
use Laravel\Dusk\Browser;
 | 
					 | 
				
			||||||
use Tests\Browser\Pages\ClientPortal\Login;
 | 
					 | 
				
			||||||
use Tests\DuskTestCase;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class BancontactTest extends DuskTestCase
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    protected function setUp(): void
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        parent::setUp();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        foreach (static::$browsers as $browser) {
 | 
					 | 
				
			||||||
            $browser->driver->manage()->deleteAllCookies();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visit(new Login())
 | 
					 | 
				
			||||||
                ->auth();
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->disableCompanyGateways();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Enable Stripe.
 | 
					 | 
				
			||||||
        CompanyGateway::where('gateway_key', 'd14dd26a37cecc30fdd65700bfb55b23')->restore();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Enable SOFORT.
 | 
					 | 
				
			||||||
        $cg = CompanyGateway::where('gateway_key', 'd14dd26a37cecc30fdd65700bfb55b23')->firstOrFail();
 | 
					 | 
				
			||||||
        $fees_and_limits = $cg->fees_and_limits;
 | 
					 | 
				
			||||||
        $fees_and_limits->{GatewayType::BANCONTACT} = new FeesAndLimits();
 | 
					 | 
				
			||||||
        $cg->fees_and_limits = $fees_and_limits;
 | 
					 | 
				
			||||||
        $cg->save();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $client = Client::first();
 | 
					 | 
				
			||||||
        $client->country_id = 276;
 | 
					 | 
				
			||||||
        $client->save();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testPayingWithBancontact()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.invoices.index')
 | 
					 | 
				
			||||||
                ->click('@pay-now')
 | 
					 | 
				
			||||||
                ->press('Pay Now')
 | 
					 | 
				
			||||||
                ->clickLink('EPS')
 | 
					 | 
				
			||||||
                ->type('#bancontact-name', 'John Doe')
 | 
					 | 
				
			||||||
                ->click('#pay-now')
 | 
					 | 
				
			||||||
                ->waitForText('Bancontact test payment page', 120)
 | 
					 | 
				
			||||||
                ->press('.common-Button.common-Button--default')
 | 
					 | 
				
			||||||
                ->waitForText('Details of the payment', 60);
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,139 +0,0 @@
 | 
				
			|||||||
<?php
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Invoice Ninja (https://invoiceninja.com).
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @license https://www.elastic.co/licensing/elastic-license
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace Tests\Browser\ClientPortal\Gateways\Stripe;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use App\DataMapper\FeesAndLimits;
 | 
					 | 
				
			||||||
use App\Models\CompanyGateway;
 | 
					 | 
				
			||||||
use App\Models\GatewayType;
 | 
					 | 
				
			||||||
use Laravel\Dusk\Browser;
 | 
					 | 
				
			||||||
use Tests\Browser\Pages\ClientPortal\Login;
 | 
					 | 
				
			||||||
use Tests\DuskTestCase;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class CreditCardTest extends DuskTestCase
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    protected function setUp(): void
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        parent::setUp();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        foreach (static::$browsers as $browser) {
 | 
					 | 
				
			||||||
            $browser->driver->manage()->deleteAllCookies();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visit(new Login())
 | 
					 | 
				
			||||||
                ->auth();
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->disableCompanyGateways();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Enable Stripe.
 | 
					 | 
				
			||||||
        CompanyGateway::where('gateway_key', 'd14dd26a37cecc30fdd65700bfb55b23')->restore();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $cg = CompanyGateway::where('gateway_key', 'd14dd26a37cecc30fdd65700bfb55b23')->firstOrFail();
 | 
					 | 
				
			||||||
        $fees_and_limits = $cg->fees_and_limits;
 | 
					 | 
				
			||||||
        $fees_and_limits->{GatewayType::CREDIT_CARD} = new FeesAndLimits();
 | 
					 | 
				
			||||||
        $cg->fees_and_limits = $fees_and_limits;
 | 
					 | 
				
			||||||
        $cg->save();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testPaymentWithNewCard()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.invoices.index')
 | 
					 | 
				
			||||||
                ->click('@pay-now')
 | 
					 | 
				
			||||||
                ->click('@pay-now-dropdown')
 | 
					 | 
				
			||||||
                ->clickLink('Credit Card')
 | 
					 | 
				
			||||||
                ->type('#cardholder-name', 'John Doe')
 | 
					 | 
				
			||||||
                ->withinFrame('iframe', function (Browser $browser) {
 | 
					 | 
				
			||||||
                    $browser
 | 
					 | 
				
			||||||
                        ->type('cardnumber', '4242 4242 4242 4242')
 | 
					 | 
				
			||||||
                        ->type('exp-date', '04/22')
 | 
					 | 
				
			||||||
                        ->type('cvc', '242');
 | 
					 | 
				
			||||||
                })
 | 
					 | 
				
			||||||
                ->click('#pay-now')
 | 
					 | 
				
			||||||
                ->waitForText('Details of the payment', 60);
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testPayWithNewCardAndSaveForFutureUse()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.invoices.index')
 | 
					 | 
				
			||||||
                ->click('@pay-now')
 | 
					 | 
				
			||||||
                ->click('@pay-now-dropdown')
 | 
					 | 
				
			||||||
                ->clickLink('Credit Card')
 | 
					 | 
				
			||||||
                ->type('#cardholder-name', 'John Doe')
 | 
					 | 
				
			||||||
                ->withinFrame('iframe', function (Browser $browser) {
 | 
					 | 
				
			||||||
                    $browser
 | 
					 | 
				
			||||||
                        ->type('cardnumber', '4242 4242 4242 4242')
 | 
					 | 
				
			||||||
                        ->type('exp-date', '04/22')
 | 
					 | 
				
			||||||
                        ->type('cvc', '242');
 | 
					 | 
				
			||||||
                })
 | 
					 | 
				
			||||||
                ->radio('#proxy_is_default', true)
 | 
					 | 
				
			||||||
                ->click('#pay-now')
 | 
					 | 
				
			||||||
                ->waitForText('Details of the payment', 60)
 | 
					 | 
				
			||||||
                ->visitRoute('client.payment_methods.index')
 | 
					 | 
				
			||||||
                ->clickLink('View')
 | 
					 | 
				
			||||||
                ->assertSee('4242');
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testPayWithSavedCreditCard()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.invoices.index')
 | 
					 | 
				
			||||||
                ->click('@pay-now')
 | 
					 | 
				
			||||||
                ->click('@pay-now-dropdown')
 | 
					 | 
				
			||||||
                ->clickLink('Credit Card')
 | 
					 | 
				
			||||||
                ->click('.toggle-payment-with-token')
 | 
					 | 
				
			||||||
                ->click('#pay-now')
 | 
					 | 
				
			||||||
                ->waitForText('Details of the payment', 60);
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testRemoveCreditCard()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.payment_methods.index')
 | 
					 | 
				
			||||||
                ->clickLink('View')
 | 
					 | 
				
			||||||
                ->press('Remove Payment Method')
 | 
					 | 
				
			||||||
                ->waitForText('Confirmation')
 | 
					 | 
				
			||||||
                ->click('@confirm-payment-removal')
 | 
					 | 
				
			||||||
                ->assertSee('Payment method has been successfully removed.');
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testAddingCreditCardStandalone()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.payment_methods.index')
 | 
					 | 
				
			||||||
                ->press('Add Payment Method')
 | 
					 | 
				
			||||||
                ->clickLink('Credit Card')
 | 
					 | 
				
			||||||
                ->type('#cardholder-name', 'John Doe')
 | 
					 | 
				
			||||||
                ->withinFrame('iframe', function (Browser $browser) {
 | 
					 | 
				
			||||||
                    $browser
 | 
					 | 
				
			||||||
                        ->type('cardnumber', '4242 4242 4242 4242')
 | 
					 | 
				
			||||||
                        ->type('exp-date', '04/22')
 | 
					 | 
				
			||||||
                        ->type('cvc', '242');
 | 
					 | 
				
			||||||
                })
 | 
					 | 
				
			||||||
                ->press('Add Payment Method')
 | 
					 | 
				
			||||||
                ->waitForText('**** 4242');
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,74 +0,0 @@
 | 
				
			|||||||
<?php
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Invoice Ninja (https://invoiceninja.com).
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @license https://www.elastic.co/licensing/elastic-license
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace Tests\Browser\ClientPortal\Gateways\Stripe;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use App\DataMapper\FeesAndLimits;
 | 
					 | 
				
			||||||
use App\Models\Client;
 | 
					 | 
				
			||||||
use App\Models\CompanyGateway;
 | 
					 | 
				
			||||||
use App\Models\GatewayType;
 | 
					 | 
				
			||||||
use Laravel\Dusk\Browser;
 | 
					 | 
				
			||||||
use Tests\Browser\Pages\ClientPortal\Login;
 | 
					 | 
				
			||||||
use Tests\DuskTestCase;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class EPSTest extends DuskTestCase
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    protected function setUp(): void
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        parent::setUp();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        foreach (static::$browsers as $browser) {
 | 
					 | 
				
			||||||
            $browser->driver->manage()->deleteAllCookies();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visit(new Login())
 | 
					 | 
				
			||||||
                ->auth();
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->disableCompanyGateways();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Enable Stripe.
 | 
					 | 
				
			||||||
        CompanyGateway::where('gateway_key', 'd14dd26a37cecc30fdd65700bfb55b23')->restore();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Enable SOFORT.
 | 
					 | 
				
			||||||
        $cg = CompanyGateway::where('gateway_key', 'd14dd26a37cecc30fdd65700bfb55b23')->firstOrFail();
 | 
					 | 
				
			||||||
        $fees_and_limits = $cg->fees_and_limits;
 | 
					 | 
				
			||||||
        $fees_and_limits->{GatewayType::EPS} = new FeesAndLimits();
 | 
					 | 
				
			||||||
        $cg->fees_and_limits = $fees_and_limits;
 | 
					 | 
				
			||||||
        $cg->save();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $client = Client::first();
 | 
					 | 
				
			||||||
        $client->country_id = 276;
 | 
					 | 
				
			||||||
        $client->save();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testPayingWithEPS()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.invoices.index')
 | 
					 | 
				
			||||||
                ->click('@pay-now')
 | 
					 | 
				
			||||||
                ->press('Pay Now')
 | 
					 | 
				
			||||||
                ->clickLink('EPS')
 | 
					 | 
				
			||||||
                ->type('#eps-name', 'John Doe')
 | 
					 | 
				
			||||||
                ->withinFrame('iframe', function (Browser $browser) {
 | 
					 | 
				
			||||||
                    $browser->type('eps', '12345');
 | 
					 | 
				
			||||||
                })
 | 
					 | 
				
			||||||
                ->click('#pay-now')
 | 
					 | 
				
			||||||
                ->waitForText('EPS test payment page', 120)
 | 
					 | 
				
			||||||
                ->press('.common-Button.common-Button--default')
 | 
					 | 
				
			||||||
                ->waitForText('Details of the payment', 60);
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,71 +0,0 @@
 | 
				
			|||||||
<?php
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Invoice Ninja (https://invoiceninja.com).
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @license https://www.elastic.co/licensing/elastic-license
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace Tests\Browser\ClientPortal\Gateways\Stripe;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use App\DataMapper\FeesAndLimits;
 | 
					 | 
				
			||||||
use App\Models\Client;
 | 
					 | 
				
			||||||
use App\Models\CompanyGateway;
 | 
					 | 
				
			||||||
use App\Models\GatewayType;
 | 
					 | 
				
			||||||
use Laravel\Dusk\Browser;
 | 
					 | 
				
			||||||
use Tests\Browser\Pages\ClientPortal\Login;
 | 
					 | 
				
			||||||
use Tests\DuskTestCase;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class GiropayTest extends DuskTestCase
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    protected function setUp(): void
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        parent::setUp();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        foreach (static::$browsers as $browser) {
 | 
					 | 
				
			||||||
            $browser->driver->manage()->deleteAllCookies();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visit(new Login())
 | 
					 | 
				
			||||||
                ->auth();
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->disableCompanyGateways();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Enable Stripe.
 | 
					 | 
				
			||||||
        CompanyGateway::where('gateway_key', 'd14dd26a37cecc30fdd65700bfb55b23')->restore();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Enable SOFORT.
 | 
					 | 
				
			||||||
        $cg = CompanyGateway::where('gateway_key', 'd14dd26a37cecc30fdd65700bfb55b23')->firstOrFail();
 | 
					 | 
				
			||||||
        $fees_and_limits = $cg->fees_and_limits;
 | 
					 | 
				
			||||||
        $fees_and_limits->{GatewayType::GIROPAY} = new FeesAndLimits();
 | 
					 | 
				
			||||||
        $cg->fees_and_limits = $fees_and_limits;
 | 
					 | 
				
			||||||
        $cg->save();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $client = Client::first();
 | 
					 | 
				
			||||||
        $client->country_id = 276;
 | 
					 | 
				
			||||||
        $client->save();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testPayingWithGiropay()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.invoices.index')
 | 
					 | 
				
			||||||
                ->click('@pay-now')
 | 
					 | 
				
			||||||
                ->press('Pay Now')
 | 
					 | 
				
			||||||
                ->clickLink('Giropay')
 | 
					 | 
				
			||||||
                ->type('#giropay-name', 'John Doe')
 | 
					 | 
				
			||||||
                ->click('#pay-now')
 | 
					 | 
				
			||||||
                ->waitForText('Giropay test payment page', 120)
 | 
					 | 
				
			||||||
                ->press('.common-Button.common-Button--default')
 | 
					 | 
				
			||||||
                ->waitForText('Details of the payment', 60);
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,76 +0,0 @@
 | 
				
			|||||||
<?php
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Invoice Ninja (https://invoiceninja.com).
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @license https://www.elastic.co/licensing/elastic-license
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace Tests\Browser\ClientPortal\Gateways\Stripe;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use App\DataMapper\FeesAndLimits;
 | 
					 | 
				
			||||||
use App\Models\Client;
 | 
					 | 
				
			||||||
use App\Models\CompanyGateway;
 | 
					 | 
				
			||||||
use App\Models\GatewayType;
 | 
					 | 
				
			||||||
use Laravel\Dusk\Browser;
 | 
					 | 
				
			||||||
use Tests\Browser\Pages\ClientPortal\Login;
 | 
					 | 
				
			||||||
use Tests\DuskTestCase;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class Prezelewy24Test extends DuskTestCase
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    protected function setUp(): void
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        parent::setUp();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        foreach (static::$browsers as $browser) {
 | 
					 | 
				
			||||||
            $browser->driver->manage()->deleteAllCookies();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visit(new Login())
 | 
					 | 
				
			||||||
                ->auth();
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->disableCompanyGateways();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Enable Stripe.
 | 
					 | 
				
			||||||
        CompanyGateway::where('gateway_key', 'd14dd26a37cecc30fdd65700bfb55b23')->restore();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Enable SOFORT.
 | 
					 | 
				
			||||||
        $cg = CompanyGateway::where('gateway_key', 'd14dd26a37cecc30fdd65700bfb55b23')->firstOrFail();
 | 
					 | 
				
			||||||
        $fees_and_limits = $cg->fees_and_limits;
 | 
					 | 
				
			||||||
        $fees_and_limits->{GatewayType::PRZELEWY24} = new FeesAndLimits();
 | 
					 | 
				
			||||||
        $cg->fees_and_limits = $fees_and_limits;
 | 
					 | 
				
			||||||
        $cg->save();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $client = Client::first();
 | 
					 | 
				
			||||||
        $client->country_id = 276;
 | 
					 | 
				
			||||||
        $client->save();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testPayingWithPrezelewy24()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.invoices.index')
 | 
					 | 
				
			||||||
                ->click('@pay-now')
 | 
					 | 
				
			||||||
                ->press('Pay Now')
 | 
					 | 
				
			||||||
                ->clickLink('EPS')
 | 
					 | 
				
			||||||
                ->type('#eps-name', 'John Doe')
 | 
					 | 
				
			||||||
                ->type('#eps-email', 'john@doe.com')
 | 
					 | 
				
			||||||
                ->check('#p24-mandate-acceptance', 'John Doe')
 | 
					 | 
				
			||||||
                ->withinFrame('iframe', function (Browser $browser) {
 | 
					 | 
				
			||||||
                    $browser->type('p24', '12345');
 | 
					 | 
				
			||||||
                })
 | 
					 | 
				
			||||||
                ->click('#pay-now')
 | 
					 | 
				
			||||||
                ->waitForText('P24 test payment page', 120)
 | 
					 | 
				
			||||||
                ->press('.common-Button.common-Button--default')
 | 
					 | 
				
			||||||
                ->waitForText('Details of the payment', 60);
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,127 +0,0 @@
 | 
				
			|||||||
<?php
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Invoice Ninja (https://invoiceninja.com).
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @license https://www.elastic.co/licensing/elastic-license
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace Tests\Browser\ClientPortal\Gateways\Stripe;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use App\DataMapper\FeesAndLimits;
 | 
					 | 
				
			||||||
use App\Models\Client;
 | 
					 | 
				
			||||||
use App\Models\CompanyGateway;
 | 
					 | 
				
			||||||
use App\Models\GatewayType;
 | 
					 | 
				
			||||||
use Laravel\Dusk\Browser;
 | 
					 | 
				
			||||||
use Tests\Browser\Pages\ClientPortal\Login;
 | 
					 | 
				
			||||||
use Tests\DuskTestCase;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class SEPATest extends DuskTestCase
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    protected function setUp(): void
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        parent::setUp();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        foreach (static::$browsers as $browser) {
 | 
					 | 
				
			||||||
            $browser->driver->manage()->deleteAllCookies();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visit(new Login())
 | 
					 | 
				
			||||||
                ->auth();
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->disableCompanyGateways();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Enable Stripe.
 | 
					 | 
				
			||||||
        CompanyGateway::where('gateway_key', 'd14dd26a37cecc30fdd65700bfb55b23')->restore();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Enable SEPA.
 | 
					 | 
				
			||||||
        $cg = CompanyGateway::where('gateway_key', 'd14dd26a37cecc30fdd65700bfb55b23')->firstOrFail();
 | 
					 | 
				
			||||||
        $fees_and_limits = $cg->fees_and_limits;
 | 
					 | 
				
			||||||
        $fees_and_limits->{GatewayType::SEPA} = new FeesAndLimits();
 | 
					 | 
				
			||||||
        $cg->fees_and_limits = $fees_and_limits;
 | 
					 | 
				
			||||||
        $cg->save();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // SEPA required DE to be billing country.
 | 
					 | 
				
			||||||
        $client = Client::first();
 | 
					 | 
				
			||||||
        $client->country_id = 276;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $settings = $client->settings;
 | 
					 | 
				
			||||||
        $settings->currency_id = '3';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $client->settings = $settings;
 | 
					 | 
				
			||||||
        $client->save();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testPayingWithNewSEPABankAccount(): void
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.invoices.index')
 | 
					 | 
				
			||||||
                ->click('@pay-now')
 | 
					 | 
				
			||||||
                ->click('@pay-now-dropdown')
 | 
					 | 
				
			||||||
                ->clickLink('SEPA Direct Debit')
 | 
					 | 
				
			||||||
                ->type('#sepa-name', 'John Doe')
 | 
					 | 
				
			||||||
                ->type('#sepa-email-address', 'test@invoiceninja.com')
 | 
					 | 
				
			||||||
                ->withinFrame('iframe', function (Browser $browser) {
 | 
					 | 
				
			||||||
                    $browser->type('iban', 'DE89370400440532013000');
 | 
					 | 
				
			||||||
                })
 | 
					 | 
				
			||||||
                ->check('#sepa-mandate-acceptance', true)
 | 
					 | 
				
			||||||
                ->click('#pay-now')
 | 
					 | 
				
			||||||
                ->waitForText('Details of the payment', 60);
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testPayingWithNewSEPABankAccountAndSaveForFuture(): void
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.invoices.index')
 | 
					 | 
				
			||||||
                ->click('@pay-now')
 | 
					 | 
				
			||||||
                ->click('@pay-now-dropdown')
 | 
					 | 
				
			||||||
                ->clickLink('SEPA Direct Debit')
 | 
					 | 
				
			||||||
                ->type('#sepa-name', 'John Doe')
 | 
					 | 
				
			||||||
                ->type('#sepa-email-address', 'test@invoiceninja.com')
 | 
					 | 
				
			||||||
                ->withinFrame('iframe', function (Browser $browser) {
 | 
					 | 
				
			||||||
                    $browser->type('iban', 'DE89370400440532013000');
 | 
					 | 
				
			||||||
                })
 | 
					 | 
				
			||||||
                ->check('#sepa-mandate-acceptance', true)
 | 
					 | 
				
			||||||
                ->radio('#proxy_is_default', true)
 | 
					 | 
				
			||||||
                ->click('#pay-now')
 | 
					 | 
				
			||||||
                ->waitForText('Details of the payment', 60);
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testPayWithSavedBankAccount()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.invoices.index')
 | 
					 | 
				
			||||||
                ->click('@pay-now')
 | 
					 | 
				
			||||||
                ->click('@pay-now-dropdown')
 | 
					 | 
				
			||||||
                ->clickLink('SEPA Direct Debit')
 | 
					 | 
				
			||||||
                ->click('.toggle-payment-with-token')
 | 
					 | 
				
			||||||
                ->click('#pay-now')
 | 
					 | 
				
			||||||
                ->waitForText('Details of the payment', 60);
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testRemoveBankAccount()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.payment_methods.index')
 | 
					 | 
				
			||||||
                ->clickLink('View')
 | 
					 | 
				
			||||||
                ->press('Remove Payment Method')
 | 
					 | 
				
			||||||
                ->waitForText('Confirmation')
 | 
					 | 
				
			||||||
                ->click('@confirm-payment-removal')
 | 
					 | 
				
			||||||
                ->assertSee('Payment method has been successfully removed.');
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,72 +0,0 @@
 | 
				
			|||||||
<?php
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Invoice Ninja (https://invoiceninja.com).
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @license https://www.elastic.co/licensing/elastic-license
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace Tests\Browser\ClientPortal\Gateways\Stripe;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use App\DataMapper\FeesAndLimits;
 | 
					 | 
				
			||||||
use App\Models\Client;
 | 
					 | 
				
			||||||
use App\Models\CompanyGateway;
 | 
					 | 
				
			||||||
use App\Models\GatewayType;
 | 
					 | 
				
			||||||
use Laravel\Dusk\Browser;
 | 
					 | 
				
			||||||
use Tests\Browser\Pages\ClientPortal\Login;
 | 
					 | 
				
			||||||
use Tests\DuskTestCase;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class SofortTest extends DuskTestCase
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    protected function setUp(): void
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        parent::setUp();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        foreach (static::$browsers as $browser) {
 | 
					 | 
				
			||||||
            $browser->driver->manage()->deleteAllCookies();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visit(new Login())
 | 
					 | 
				
			||||||
                ->auth();
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->disableCompanyGateways();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Enable Stripe.
 | 
					 | 
				
			||||||
        CompanyGateway::where('gateway_key', 'd14dd26a37cecc30fdd65700bfb55b23')->restore();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Enable SOFORT.
 | 
					 | 
				
			||||||
        $cg = CompanyGateway::where('gateway_key', 'd14dd26a37cecc30fdd65700bfb55b23')->firstOrFail();
 | 
					 | 
				
			||||||
        $fees_and_limits = $cg->fees_and_limits;
 | 
					 | 
				
			||||||
        $fees_and_limits->{GatewayType::SOFORT} = new FeesAndLimits();
 | 
					 | 
				
			||||||
        $cg->fees_and_limits = $fees_and_limits;
 | 
					 | 
				
			||||||
        $cg->save();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // SOFORT required ['AUT', 'BEL', 'DEU', 'ITA', 'NLD', 'ESP'] to be billing country.
 | 
					 | 
				
			||||||
        // Setting country  to DEU (276).
 | 
					 | 
				
			||||||
        $client = Client::first();
 | 
					 | 
				
			||||||
        $client->country_id = 276;
 | 
					 | 
				
			||||||
        $client->save();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testPayingWithSofort()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.invoices.index')
 | 
					 | 
				
			||||||
                ->click('@pay-now')
 | 
					 | 
				
			||||||
                ->press('Pay Now')
 | 
					 | 
				
			||||||
                ->clickLink('Sofort')
 | 
					 | 
				
			||||||
                ->press('Pay Now')
 | 
					 | 
				
			||||||
                ->waitForText('Sofort test payment page', 120)
 | 
					 | 
				
			||||||
                ->press('.common-Button.common-Button--default')
 | 
					 | 
				
			||||||
                ->waitForText('Details of the payment', 60);
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,74 +0,0 @@
 | 
				
			|||||||
<?php
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Invoice Ninja (https://invoiceninja.com).
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @license https://www.elastic.co/licensing/elastic-license
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace Tests\Browser\ClientPortal\Gateways\Stripe;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use App\DataMapper\FeesAndLimits;
 | 
					 | 
				
			||||||
use App\Models\Client;
 | 
					 | 
				
			||||||
use App\Models\CompanyGateway;
 | 
					 | 
				
			||||||
use App\Models\GatewayType;
 | 
					 | 
				
			||||||
use Laravel\Dusk\Browser;
 | 
					 | 
				
			||||||
use Tests\Browser\Pages\ClientPortal\Login;
 | 
					 | 
				
			||||||
use Tests\DuskTestCase;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class iDEAL extends DuskTestCase
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    protected function setUp(): void
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        parent::setUp();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        foreach (static::$browsers as $browser) {
 | 
					 | 
				
			||||||
            $browser->driver->manage()->deleteAllCookies();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visit(new Login())
 | 
					 | 
				
			||||||
                ->auth();
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->disableCompanyGateways();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Enable Stripe.
 | 
					 | 
				
			||||||
        CompanyGateway::where('gateway_key', 'd14dd26a37cecc30fdd65700bfb55b23')->restore();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Enable SOFORT.
 | 
					 | 
				
			||||||
        $cg = CompanyGateway::where('gateway_key', 'd14dd26a37cecc30fdd65700bfb55b23')->firstOrFail();
 | 
					 | 
				
			||||||
        $fees_and_limits = $cg->fees_and_limits;
 | 
					 | 
				
			||||||
        $fees_and_limits->{GatewayType::IDEAL} = new FeesAndLimits();
 | 
					 | 
				
			||||||
        $cg->fees_and_limits = $fees_and_limits;
 | 
					 | 
				
			||||||
        $cg->save();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $client = Client::first();
 | 
					 | 
				
			||||||
        $client->country_id = 276;
 | 
					 | 
				
			||||||
        $client->save();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testPayingWithiDeal()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.invoices.index')
 | 
					 | 
				
			||||||
                ->click('@pay-now')
 | 
					 | 
				
			||||||
                ->press('Pay Now')
 | 
					 | 
				
			||||||
                ->clickLink('iDeal')
 | 
					 | 
				
			||||||
                ->type('#ideal-name', 'John Doe')
 | 
					 | 
				
			||||||
                ->withinFrame('iframe', function (Browser $browser) {
 | 
					 | 
				
			||||||
                    $browser->type('ideal', '12345');
 | 
					 | 
				
			||||||
                })
 | 
					 | 
				
			||||||
                ->click('#pay-now')
 | 
					 | 
				
			||||||
                ->waitForText('iDeal test payment page', 120)
 | 
					 | 
				
			||||||
                ->press('.common-Button.common-Button--default')
 | 
					 | 
				
			||||||
                ->waitForText('Details of the payment', 60);
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,62 +0,0 @@
 | 
				
			|||||||
<?php
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Invoice Ninja (https://invoiceninja.com).
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @license https://www.elastic.co/licensing/elastic-license
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace Tests\Browser\ClientPortal\Gateways\WePay;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use App\DataMapper\FeesAndLimits;
 | 
					 | 
				
			||||||
use App\Models\CompanyGateway;
 | 
					 | 
				
			||||||
use App\Models\GatewayType;
 | 
					 | 
				
			||||||
use Laravel\Dusk\Browser;
 | 
					 | 
				
			||||||
use Tests\Browser\Pages\ClientPortal\Login;
 | 
					 | 
				
			||||||
use Tests\DuskTestCase;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class ACHTest extends DuskTestCase
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    protected function setUp(): void
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        parent::setUp();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        foreach (static::$browsers as $browser) {
 | 
					 | 
				
			||||||
            $browser->driver->manage()->deleteAllCookies();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->disableCompanyGateways();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        CompanyGateway::where('gateway_key', '8fdeed552015b3c7b44ed6c8ebd9e992')->restore();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Enable ACH.
 | 
					 | 
				
			||||||
        $cg = CompanyGateway::where('gateway_key', '8fdeed552015b3c7b44ed6c8ebd9e992')->firstOrFail();
 | 
					 | 
				
			||||||
        $fees_and_limits = $cg->fees_and_limits;
 | 
					 | 
				
			||||||
        $fees_and_limits->{GatewayType::BANK_TRANSFER} = new FeesAndLimits();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $cg->fees_and_limits = $fees_and_limits;
 | 
					 | 
				
			||||||
        $cg->save();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visit(new Login())
 | 
					 | 
				
			||||||
                ->auth();
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testPayingWithNoPreauthorizedIsntPossible()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.invoices.index')
 | 
					 | 
				
			||||||
                ->click('@pay-now')
 | 
					 | 
				
			||||||
                ->press('Pay Now')
 | 
					 | 
				
			||||||
                ->clickLink('Bank Transfer')
 | 
					 | 
				
			||||||
                ->assertSee('To pay with a bank account, first you have to add it as payment method.');
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,126 +0,0 @@
 | 
				
			|||||||
<?php
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Invoice Ninja (https://invoiceninja.com).
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @license https://www.elastic.co/licensing/elastic-license
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace Tests\Browser\ClientPortal\Gateways\WePay;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use App\Models\Client;
 | 
					 | 
				
			||||||
use App\Models\CompanyGateway;
 | 
					 | 
				
			||||||
use Laravel\Dusk\Browser;
 | 
					 | 
				
			||||||
use Tests\Browser\Pages\ClientPortal\Login;
 | 
					 | 
				
			||||||
use Tests\DuskTestCase;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class CreditCardTest extends DuskTestCase
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    protected function setUp(): void
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        parent::setUp();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        foreach (static::$browsers as $browser) {
 | 
					 | 
				
			||||||
            $browser->driver->manage()->deleteAllCookies();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->disableCompanyGateways();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        CompanyGateway::where('gateway_key', '8fdeed552015b3c7b44ed6c8ebd9e992')->restore();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visit(new Login())
 | 
					 | 
				
			||||||
                ->auth();
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        Client::first()->update(['postal_code' => 99501]);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testPayWithNewCard()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.invoices.index')
 | 
					 | 
				
			||||||
                ->click('@pay-now')
 | 
					 | 
				
			||||||
                ->press('Pay Now')
 | 
					 | 
				
			||||||
                ->clickLink('Credit Card')
 | 
					 | 
				
			||||||
                ->type('card-number', '4003830171874018')
 | 
					 | 
				
			||||||
                ->type('card-holders-name', 'John Doe')
 | 
					 | 
				
			||||||
                ->type('.expiry', '12/28')
 | 
					 | 
				
			||||||
                ->type('cvc', '100')
 | 
					 | 
				
			||||||
                ->press('Pay Now')
 | 
					 | 
				
			||||||
                ->waitForText('Details of the payment', 60);
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testPayWithNewCardAndSaveForFutureUse()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.invoices.index')
 | 
					 | 
				
			||||||
                ->click('@pay-now')
 | 
					 | 
				
			||||||
                ->press('Pay Now')
 | 
					 | 
				
			||||||
                ->clickLink('Credit Card')
 | 
					 | 
				
			||||||
                ->type('card-number', '4003830171874018')
 | 
					 | 
				
			||||||
                ->type('card-holders-name', 'John Doe')
 | 
					 | 
				
			||||||
                ->type('.expiry', '12/28')
 | 
					 | 
				
			||||||
                ->type('cvc', '100')
 | 
					 | 
				
			||||||
                ->radio('#proxy_is_default', true)
 | 
					 | 
				
			||||||
                ->press('Pay Now')
 | 
					 | 
				
			||||||
                ->waitForText('Details of the payment', 60)
 | 
					 | 
				
			||||||
                ->visitRoute('client.payment_methods.index')
 | 
					 | 
				
			||||||
                ->clickLink('View')
 | 
					 | 
				
			||||||
                ->assertSee('4018');
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testPayWithSavedCreditCard()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.invoices.index')
 | 
					 | 
				
			||||||
                ->click('@pay-now')
 | 
					 | 
				
			||||||
                ->press('Pay Now')
 | 
					 | 
				
			||||||
                ->clickLink('Credit Card')
 | 
					 | 
				
			||||||
                ->click('.toggle-payment-with-token')
 | 
					 | 
				
			||||||
                ->press('Pay Now')
 | 
					 | 
				
			||||||
                ->waitForText('Details of the payment', 60);
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testRemoveCreditCard()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.payment_methods.index')
 | 
					 | 
				
			||||||
                ->clickLink('View')
 | 
					 | 
				
			||||||
                ->press('Remove Payment Method')
 | 
					 | 
				
			||||||
                ->waitForText('Confirmation')
 | 
					 | 
				
			||||||
                ->click('@confirm-payment-removal')
 | 
					 | 
				
			||||||
                ->assertSee('Payment method has been successfully removed.');
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testAddingCreditCardStandalone()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.payment_methods.index')
 | 
					 | 
				
			||||||
                ->press('Add Payment Method')
 | 
					 | 
				
			||||||
                ->clickLink('Credit Card')
 | 
					 | 
				
			||||||
                ->waitForText('Credit Card')
 | 
					 | 
				
			||||||
                ->type('#cardholder_name', 'John Doe')
 | 
					 | 
				
			||||||
                ->type('card-number', '4003830171874018')
 | 
					 | 
				
			||||||
                ->type('card-holders-name', 'John Doe')
 | 
					 | 
				
			||||||
                ->type('.expiry', '12/28')
 | 
					 | 
				
			||||||
                ->type('cvc', '100')
 | 
					 | 
				
			||||||
                ->press('Add Payment Method')
 | 
					 | 
				
			||||||
                ->waitForText(4018, 60);
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,101 +0,0 @@
 | 
				
			|||||||
<?php
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Invoice Ninja (https://invoiceninja.com).
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @license https://www.elastic.co/licensing/elastic-license
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace Tests\Browser\ClientPortal;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use App\Models\CompanyGateway;
 | 
					 | 
				
			||||||
use Laravel\Dusk\Browser;
 | 
					 | 
				
			||||||
use Tests\Browser\Pages\ClientPortal\Login;
 | 
					 | 
				
			||||||
use Tests\DuskTestCase;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class InvoicesTest extends DuskTestCase
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    protected function setUp(): void
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        parent::setUp();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        foreach (static::$browsers as $browser) {
 | 
					 | 
				
			||||||
            $browser->driver->manage()->deleteAllCookies();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visit(new Login())
 | 
					 | 
				
			||||||
                ->auth();
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testPageLoads()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.invoices.index')
 | 
					 | 
				
			||||||
                ->assertSeeIn('span[data-ref="meta-title"]', 'Invoices')
 | 
					 | 
				
			||||||
                ->visitRoute('client.logout');
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testClickingPayNowWithoutInvoices()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.invoices.index')
 | 
					 | 
				
			||||||
                ->press('Pay Now')
 | 
					 | 
				
			||||||
                ->assertSee('No payable invoices selected. Make sure you are not trying to pay draft invoice or invoice with zero balance due.')
 | 
					 | 
				
			||||||
                ->visitRoute('client.logout');
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testClickingDownloadWithoutInvoices()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.invoices.index')
 | 
					 | 
				
			||||||
                ->press('Download')
 | 
					 | 
				
			||||||
                ->assertSee('No items selected.')
 | 
					 | 
				
			||||||
                ->visitRoute('client.logout');
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testCheckingInvoiceAndClickingPayNow()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.invoices.index')
 | 
					 | 
				
			||||||
                ->check('.form-check.form-check-child')
 | 
					 | 
				
			||||||
                ->press('Pay Now')
 | 
					 | 
				
			||||||
                ->assertPathIs('/client/invoices/payment')
 | 
					 | 
				
			||||||
                ->visitRoute('client.logout');
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testPayNowButtonIsntShowingWhenNoGatewaysConfigured()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->disableCompanyGateways();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.invoices.index')
 | 
					 | 
				
			||||||
                ->assertDontSee('Pay Now');
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Enable Stripe.
 | 
					 | 
				
			||||||
        CompanyGateway::where('gateway_key', 'd14dd26a37cecc30fdd65700bfb55b23')->restore();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.invoices.index')
 | 
					 | 
				
			||||||
                ->assertSee('Pay Now')
 | 
					 | 
				
			||||||
                ->visitRoute('client.logout');
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,64 +0,0 @@
 | 
				
			|||||||
<?php
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Invoice Ninja (https://invoiceninja.com).
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @license https://www.elastic.co/licensing/elastic-license
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace Tests\Browser\ClientPortal;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use Laravel\Dusk\Browser;
 | 
					 | 
				
			||||||
use Tests\DuskTestCase;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class LoginTest extends DuskTestCase
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    protected function setUp(): void
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        parent::setUp();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        foreach (static::$browsers as $browser) {
 | 
					 | 
				
			||||||
            $browser->driver->manage()->deleteAllCookies();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testLoginPage()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visit(route('client.login'))
 | 
					 | 
				
			||||||
                ->assertSee('Client Portal')
 | 
					 | 
				
			||||||
                ->type('email', 'user@example.com')
 | 
					 | 
				
			||||||
                ->type('password', 'password')
 | 
					 | 
				
			||||||
                ->press('Login');
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            $browser->assertPathIs('/client/invoices');
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testLoginFormValidation()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visit(route('client.login'))
 | 
					 | 
				
			||||||
                ->press('Login')
 | 
					 | 
				
			||||||
                ->assertSee('The email field is required.')
 | 
					 | 
				
			||||||
                ->assertSee('The password field is required.');
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testForgotPasswordLink()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visit(route('client.login'))
 | 
					 | 
				
			||||||
                ->assertSeeLink('Forgot your password?')
 | 
					 | 
				
			||||||
                ->clickLink('Forgot your password?')
 | 
					 | 
				
			||||||
                ->assertPathIs('/client/password/reset');
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,45 +0,0 @@
 | 
				
			|||||||
<?php
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Invoice Ninja (https://invoiceninja.com).
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @license https://www.elastic.co/licensing/elastic-license
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace Tests\Browser\ClientPortal;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use Laravel\Dusk\Browser;
 | 
					 | 
				
			||||||
use Tests\Browser\Pages\ClientPortal\Login;
 | 
					 | 
				
			||||||
use Tests\DuskTestCase;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class PaymentMethodsTest extends DuskTestCase
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    protected function setUp(): void
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        parent::setUp();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        foreach (static::$browsers as $browser) {
 | 
					 | 
				
			||||||
            $browser->driver->manage()->deleteAllCookies();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visit(new Login())
 | 
					 | 
				
			||||||
                ->auth();
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testPageLoads()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.payment_methods.index')
 | 
					 | 
				
			||||||
                ->assertSeeIn('span[data-ref="meta-title"]', 'Payment Methods')
 | 
					 | 
				
			||||||
                ->visitRoute('client.logout');
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,80 +0,0 @@
 | 
				
			|||||||
<?php
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Invoice Ninja (https://invoiceninja.com).
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @license https://www.elastic.co/licensing/elastic-license
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace Tests\Browser\ClientPortal;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use App\Models\Client;
 | 
					 | 
				
			||||||
use App\Models\CompanyGateway;
 | 
					 | 
				
			||||||
use Laravel\Dusk\Browser;
 | 
					 | 
				
			||||||
use Tests\Browser\Pages\ClientPortal\Login;
 | 
					 | 
				
			||||||
use Tests\DuskTestCase;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class PaymentsTest extends DuskTestCase
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    protected function setUp(): void
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        parent::setUp();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        foreach (static::$browsers as $browser) {
 | 
					 | 
				
			||||||
            $browser->driver->manage()->deleteAllCookies();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visit(new Login())
 | 
					 | 
				
			||||||
                ->auth();
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testPageLoads()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.payments.index')
 | 
					 | 
				
			||||||
                ->assertSeeIn('span[data-ref="meta-title"]', 'Payments')
 | 
					 | 
				
			||||||
                ->visitRoute('client.logout');
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testRequiredFieldsCheck()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->disableCompanyGateways();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Enable Stripe.
 | 
					 | 
				
			||||||
        CompanyGateway::where('gateway_key', 'd14dd26a37cecc30fdd65700bfb55b23')->restore();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Stripe requires post code.
 | 
					 | 
				
			||||||
        Client::first()->update(['postal_code' => null]);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.invoices.index')
 | 
					 | 
				
			||||||
                ->click('@pay-now')
 | 
					 | 
				
			||||||
                ->press('Pay Now')
 | 
					 | 
				
			||||||
                ->clickLink('Credit Card')
 | 
					 | 
				
			||||||
                ->assertSee('Postal Code')
 | 
					 | 
				
			||||||
                ->type('client_postal_code', 10000)
 | 
					 | 
				
			||||||
                ->press('Continue')
 | 
					 | 
				
			||||||
                ->pause(2000)
 | 
					 | 
				
			||||||
                ->type('#cardholder-name', 'John Doe')
 | 
					 | 
				
			||||||
                ->withinFrame('iframe', function (Browser $browser) {
 | 
					 | 
				
			||||||
                    $browser
 | 
					 | 
				
			||||||
                        ->type('cardnumber', '4242 4242 4242 4242')
 | 
					 | 
				
			||||||
                        ->type('exp-date', '04/22')
 | 
					 | 
				
			||||||
                        ->type('cvc', '242');
 | 
					 | 
				
			||||||
                })
 | 
					 | 
				
			||||||
                ->click('#pay-now')
 | 
					 | 
				
			||||||
                ->waitForText('Details of the payment', 60)
 | 
					 | 
				
			||||||
                ->visitRoute('client.logout');
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,210 +0,0 @@
 | 
				
			|||||||
<?php
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace Tests\Browser\ClientPortal;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use Faker\Factory;
 | 
					 | 
				
			||||||
use Faker\Generator;
 | 
					 | 
				
			||||||
use Laravel\Dusk\Browser;
 | 
					 | 
				
			||||||
use Tests\Browser\Pages\ClientPortal\Login;
 | 
					 | 
				
			||||||
use Tests\DuskTestCase;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class ProfileSettingsTest extends DuskTestCase
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    /** @var Generator */
 | 
					 | 
				
			||||||
    public $faker;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    protected function setUp(): void
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        parent::setUp();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->faker = Factory::create();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        foreach (static::$browsers as $browser) {
 | 
					 | 
				
			||||||
            $browser->driver->manage()->deleteAllCookies();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visit(new Login())
 | 
					 | 
				
			||||||
                ->auth();
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testPageLoads()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.invoices.index')
 | 
					 | 
				
			||||||
                ->click('button[data-ref="client-profile-dropdown"]')
 | 
					 | 
				
			||||||
                ->click('a[data-ref="client-profile-dropdown-settings"]')
 | 
					 | 
				
			||||||
                ->waitForText('Client Information')
 | 
					 | 
				
			||||||
                ->assertSeeIn('span[data-ref="meta-title"]', 'Client Information')
 | 
					 | 
				
			||||||
                ->visitRoute('client.logout');
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testClientDetailsUpdate()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $original = [
 | 
					 | 
				
			||||||
            'name' => $this->faker->name(),
 | 
					 | 
				
			||||||
            'vat_number' => (string) $this->faker->randomNumber(6),
 | 
					 | 
				
			||||||
            'phone' => $this->faker->phoneNumber(),
 | 
					 | 
				
			||||||
            'website' => $this->faker->url(),
 | 
					 | 
				
			||||||
        ];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) use ($original) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.invoices.index')
 | 
					 | 
				
			||||||
                ->click('button[data-ref="client-profile-dropdown"]')
 | 
					 | 
				
			||||||
                ->click('a[data-ref="client-profile-dropdown-settings"]')
 | 
					 | 
				
			||||||
                ->waitForText('Client Information');
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->with('#update_contact', function (Browser $form) use ($original) {
 | 
					 | 
				
			||||||
                    $form
 | 
					 | 
				
			||||||
                        ->type('#client_name', $original['name'])
 | 
					 | 
				
			||||||
                        ->type('#client_vat_number', $original['vat_number'])
 | 
					 | 
				
			||||||
                        ->type('#client_phone', $original['phone'])
 | 
					 | 
				
			||||||
                        ->type('#client_website', $original['website'])
 | 
					 | 
				
			||||||
                        ->press('Save');
 | 
					 | 
				
			||||||
                })
 | 
					 | 
				
			||||||
                ->pause(2000)
 | 
					 | 
				
			||||||
                ->refresh();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            $updated = [
 | 
					 | 
				
			||||||
                'name' => $browser->value('#client_name'),
 | 
					 | 
				
			||||||
                'vat_number' => $browser->value('#client_vat_number'),
 | 
					 | 
				
			||||||
                'phone' => $browser->value('#client_phone'),
 | 
					 | 
				
			||||||
                'website' => $browser->value('#client_website'),
 | 
					 | 
				
			||||||
            ];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            $this->assertSame($original, $updated);
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testContactDetailsUpdate()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $original = [
 | 
					 | 
				
			||||||
            'first_name' => $this->faker->firstName(),
 | 
					 | 
				
			||||||
            'last_name' => $this->faker->lastName(),
 | 
					 | 
				
			||||||
            'email_address' => 'user@example.com',
 | 
					 | 
				
			||||||
            'phone' => $this->faker->phoneNumber(),
 | 
					 | 
				
			||||||
        ];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) use ($original) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.invoices.index')
 | 
					 | 
				
			||||||
                ->click('button[data-ref="client-profile-dropdown"]')
 | 
					 | 
				
			||||||
                ->click('a[data-ref="client-profile-dropdown-settings"]')
 | 
					 | 
				
			||||||
                ->waitForText('Client Information');
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->with('#update_client', function (Browser $form) use ($original) {
 | 
					 | 
				
			||||||
                    $form
 | 
					 | 
				
			||||||
                        ->type('#contact_first_name', $original['first_name'])
 | 
					 | 
				
			||||||
                        ->type('#contact_last_name', $original['last_name'])
 | 
					 | 
				
			||||||
                        ->scrollIntoView('#contact_email_address')
 | 
					 | 
				
			||||||
                        ->type('#contact_email_address', $original['email_address'])
 | 
					 | 
				
			||||||
                        ->type('#contact_phone', $original['phone'])
 | 
					 | 
				
			||||||
                        ->click('button[data-ref="update-contact-details"]');
 | 
					 | 
				
			||||||
                })
 | 
					 | 
				
			||||||
                ->pause(2000)
 | 
					 | 
				
			||||||
                ->refresh();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            $updated = [
 | 
					 | 
				
			||||||
                'first_name' => $browser->value('#contact_first_name'),
 | 
					 | 
				
			||||||
                'last_name' => $browser->value('#contact_last_name'),
 | 
					 | 
				
			||||||
                'email_address' => $browser->value('#contact_email_address'),
 | 
					 | 
				
			||||||
                'phone' => $browser->value('#contact_phone'),
 | 
					 | 
				
			||||||
            ];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            $this->assertSame($original, $updated);
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testBillingAddressUpdate()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $original = [
 | 
					 | 
				
			||||||
            'street' => $this->faker->streetName(),
 | 
					 | 
				
			||||||
            'apt' => $this->faker->streetAddress(),
 | 
					 | 
				
			||||||
            'city' => $this->faker->city(),
 | 
					 | 
				
			||||||
            'state' => $this->faker->state(),
 | 
					 | 
				
			||||||
            'postal_code' => $this->faker->postcode(),
 | 
					 | 
				
			||||||
        ];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) use ($original) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.invoices.index')
 | 
					 | 
				
			||||||
                ->click('button[data-ref="client-profile-dropdown"]')
 | 
					 | 
				
			||||||
                ->click('a[data-ref="client-profile-dropdown-settings"]')
 | 
					 | 
				
			||||||
                ->waitForText('Client Information');
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->with('#update_billing_address', function (Browser $form) use ($original) {
 | 
					 | 
				
			||||||
                    $form
 | 
					 | 
				
			||||||
                        ->type('#address1', $original['street'])
 | 
					 | 
				
			||||||
                        ->type('#address2', $original['apt'])
 | 
					 | 
				
			||||||
                        ->type('#city', $original['city'])
 | 
					 | 
				
			||||||
                        ->type('#state', $original['state'])
 | 
					 | 
				
			||||||
                        ->type('#postal_code', $original['postal_code'])
 | 
					 | 
				
			||||||
                        ->select('#country')
 | 
					 | 
				
			||||||
                        ->press('Save');
 | 
					 | 
				
			||||||
                })
 | 
					 | 
				
			||||||
                ->pause(1000)
 | 
					 | 
				
			||||||
                ->refresh();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            $updated = [
 | 
					 | 
				
			||||||
                'street' => $browser->value('#address1'),
 | 
					 | 
				
			||||||
                'apt' => $browser->value('#address2'),
 | 
					 | 
				
			||||||
                'city' => $browser->value('#city'),
 | 
					 | 
				
			||||||
                'state' => $browser->value('#state'),
 | 
					 | 
				
			||||||
                'postal_code' => $browser->value('#postal_code'),
 | 
					 | 
				
			||||||
            ];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            $this->assertSame($original, $updated);
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testShippingAddressUpdate()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $original = [
 | 
					 | 
				
			||||||
            'street' => $this->faker->streetName(),
 | 
					 | 
				
			||||||
            'apt' => $this->faker->streetAddress(),
 | 
					 | 
				
			||||||
            'city' => $this->faker->city(),
 | 
					 | 
				
			||||||
            'state' => $this->faker->state(),
 | 
					 | 
				
			||||||
            'postal_code' => $this->faker->postcode(),
 | 
					 | 
				
			||||||
        ];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) use ($original) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.invoices.index')
 | 
					 | 
				
			||||||
                ->click('button[data-ref="client-profile-dropdown"]')
 | 
					 | 
				
			||||||
                ->click('a[data-ref="client-profile-dropdown-settings"]')
 | 
					 | 
				
			||||||
                ->waitForText('Client Information');
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->with('#update_shipping_address', function (Browser $form) use ($original) {
 | 
					 | 
				
			||||||
                    $form
 | 
					 | 
				
			||||||
                        ->type('#shipping_address1', $original['street'])
 | 
					 | 
				
			||||||
                        ->type('#shipping_address2', $original['apt'])
 | 
					 | 
				
			||||||
                        ->type('#shipping_city', $original['city'])
 | 
					 | 
				
			||||||
                        ->type('#shipping_state', $original['state'])
 | 
					 | 
				
			||||||
                        ->type('#shipping_postal_code', $original['postal_code'])
 | 
					 | 
				
			||||||
                        ->select('#shipping_country')
 | 
					 | 
				
			||||||
                        ->press('Save');
 | 
					 | 
				
			||||||
                })
 | 
					 | 
				
			||||||
                ->pause(1000)
 | 
					 | 
				
			||||||
                ->refresh();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            $updated = [
 | 
					 | 
				
			||||||
                'street' => $browser->value('#shipping_address1'),
 | 
					 | 
				
			||||||
                'apt' => $browser->value('#shipping_address2'),
 | 
					 | 
				
			||||||
                'city' => $browser->value('#shipping_city'),
 | 
					 | 
				
			||||||
                'state' => $browser->value('#shipping_state'),
 | 
					 | 
				
			||||||
                'postal_code' => $browser->value('#shipping_postal_code'),
 | 
					 | 
				
			||||||
            ];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            $this->assertSame($original, $updated);
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,105 +0,0 @@
 | 
				
			|||||||
<?php
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Invoice Ninja (https://invoiceninja.com).
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @license https://www.elastic.co/licensing/elastic-license
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace Tests\Browser\ClientPortal;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use Laravel\Dusk\Browser;
 | 
					 | 
				
			||||||
use Tests\Browser\Pages\ClientPortal\Login;
 | 
					 | 
				
			||||||
use Tests\DuskTestCase;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class QuotesTest extends DuskTestCase
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    protected function setUp(): void
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        parent::setUp();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        foreach (static::$browsers as $browser) {
 | 
					 | 
				
			||||||
            $browser->driver->manage()->deleteAllCookies();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visit(new Login())
 | 
					 | 
				
			||||||
                ->auth();
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testPageLoads()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.quotes.index')
 | 
					 | 
				
			||||||
                ->assertSeeIn('span[data-ref="meta-title"]', 'Quotes')
 | 
					 | 
				
			||||||
                ->visitRoute('client.logout');
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testClickingApproveWithoutQuotesDoesntWork()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.quotes.index')
 | 
					 | 
				
			||||||
                ->press('Approve')
 | 
					 | 
				
			||||||
                ->assertPathIs('/client/quotes');
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testApprovingQuotes()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.quotes.index')
 | 
					 | 
				
			||||||
                ->check('.form-check.form-check-child')
 | 
					 | 
				
			||||||
                ->press('Approve')
 | 
					 | 
				
			||||||
                ->assertPathIs('/client/quotes/approve')
 | 
					 | 
				
			||||||
                ->press('Approve')
 | 
					 | 
				
			||||||
                ->assertPathIs('/client/quotes')
 | 
					 | 
				
			||||||
                ->assertSee('Quote(s) approved successfully.')
 | 
					 | 
				
			||||||
                ->visitRoute('client.logout');
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testQuotesWithSentStatusCanOnlyBeApproved()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.quotes.index')
 | 
					 | 
				
			||||||
                ->clickLink('View')
 | 
					 | 
				
			||||||
                ->assertSee('Only quotes with "Sent" status can be approved.')
 | 
					 | 
				
			||||||
                ->visitRoute('client.logout');
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testMessageForNonApprovableQuotesIsVisible()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.quotes.index')
 | 
					 | 
				
			||||||
                ->check('.form-check.form-check-child')
 | 
					 | 
				
			||||||
                ->press('Approve')
 | 
					 | 
				
			||||||
                ->assertPathIs('/client/quotes')
 | 
					 | 
				
			||||||
                ->assertDontSee('Quote(s) approved successfully.')
 | 
					 | 
				
			||||||
                ->assertSee('Only quotes with "Sent" status can be approved.')
 | 
					 | 
				
			||||||
                ->visitRoute('client.logout');
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testNoQuotesAvailableForDownloadMessage()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.quotes.index')
 | 
					 | 
				
			||||||
                ->press('Download')
 | 
					 | 
				
			||||||
                ->assertSee('No quotes available for download.');
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,65 +0,0 @@
 | 
				
			|||||||
<?php
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Invoice Ninja (https://invoiceninja.com).
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @license https://www.elastic.co/licensing/elastic-license
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace Tests\Browser\ClientPortal;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use App\Models\RecurringInvoice;
 | 
					 | 
				
			||||||
use Laravel\Dusk\Browser;
 | 
					 | 
				
			||||||
use Tests\Browser\Pages\ClientPortal\Login;
 | 
					 | 
				
			||||||
use Tests\DuskTestCase;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class RecurringInvoicesTest extends DuskTestCase
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    protected function setUp(): void
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        parent::setUp();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        foreach (static::$browsers as $browser) {
 | 
					 | 
				
			||||||
            $browser->driver->manage()->deleteAllCookies();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visit(new Login())
 | 
					 | 
				
			||||||
                ->auth();
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testPageLoads()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.recurring_invoices.index')
 | 
					 | 
				
			||||||
                ->assertSeeIn('span[data-ref="meta-title"]', 'Recurring Invoices')
 | 
					 | 
				
			||||||
                ->visitRoute('client.logout');
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testRequestingCancellation()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.recurring_invoices.index')
 | 
					 | 
				
			||||||
                ->clickLink('View')
 | 
					 | 
				
			||||||
                ->assertSee('Cancellation')
 | 
					 | 
				
			||||||
                ->press('Request Cancellation')
 | 
					 | 
				
			||||||
                ->pause(1000)
 | 
					 | 
				
			||||||
                ->waitForText('Request cancellation')
 | 
					 | 
				
			||||||
                ->press('Confirm')
 | 
					 | 
				
			||||||
                ->pause(5000)
 | 
					 | 
				
			||||||
                ->assertPathIs(
 | 
					 | 
				
			||||||
                    route('client.recurring_invoices.request_cancellation', RecurringInvoice::first()->hashed_id, false)
 | 
					 | 
				
			||||||
                )
 | 
					 | 
				
			||||||
                ->visitRoute('client.logout');
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,45 +0,0 @@
 | 
				
			|||||||
<?php
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Invoice Ninja (https://invoiceninja.com).
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @license https://www.elastic.co/licensing/elastic-license
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace Tests\Browser\ClientPortal;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use Laravel\Dusk\Browser;
 | 
					 | 
				
			||||||
use Tests\Browser\Pages\ClientPortal\Login;
 | 
					 | 
				
			||||||
use Tests\DuskTestCase;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class SubscriptionsTest extends DuskTestCase
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    protected function setUp(): void
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        parent::setUp();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        foreach (static::$browsers as $browser) {
 | 
					 | 
				
			||||||
            $browser->driver->manage()->deleteAllCookies();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visit(new Login())
 | 
					 | 
				
			||||||
                ->auth();
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testPageLoads()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->browse(function (Browser $browser) {
 | 
					 | 
				
			||||||
            $browser
 | 
					 | 
				
			||||||
                ->visitRoute('client.subscriptions.index')
 | 
					 | 
				
			||||||
                ->assertSeeIn('span[data-ref="meta-title"]', 'Subscriptions')
 | 
					 | 
				
			||||||
                ->visitRoute('client.logout');
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,51 +0,0 @@
 | 
				
			|||||||
<?php
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace Tests\Browser\Pages\ClientPortal;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use Laravel\Dusk\Browser;
 | 
					 | 
				
			||||||
use Laravel\Dusk\Page;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class Login extends Page
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * Get the URL for the page.
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * @return string
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    public function url(): string
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        return '/client/login';
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * Assert that the browser is on the page.
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * @param  Browser  $browser
 | 
					 | 
				
			||||||
     * @return void
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    public function assert(Browser $browser)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $browser->assertPathIs($this->url());
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * Get the element shortcuts for the page.
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * @return array
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    public function elements()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        return [
 | 
					 | 
				
			||||||
            '@element' => '#selector',
 | 
					 | 
				
			||||||
        ];
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function auth(Browser $browser)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $browser
 | 
					 | 
				
			||||||
            ->visitRoute('client.login')
 | 
					 | 
				
			||||||
            ->type('email', 'user@example.com')
 | 
					 | 
				
			||||||
            ->type('password', 'password')
 | 
					 | 
				
			||||||
            ->press('Login');
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										2
									
								
								tests/Browser/console/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								tests/Browser/console/.gitignore
									
									
									
									
										vendored
									
									
								
							@ -1,2 +0,0 @@
 | 
				
			|||||||
*
 | 
					 | 
				
			||||||
!.gitignore
 | 
					 | 
				
			||||||
							
								
								
									
										2
									
								
								tests/Browser/screenshots/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								tests/Browser/screenshots/.gitignore
									
									
									
									
										vendored
									
									
								
							@ -1,2 +0,0 @@
 | 
				
			|||||||
*
 | 
					 | 
				
			||||||
!.gitignore
 | 
					 | 
				
			||||||
@ -1,73 +0,0 @@
 | 
				
			|||||||
<?php
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace Tests;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use App\Models\CompanyGateway;
 | 
					 | 
				
			||||||
use Facebook\WebDriver\Chrome\ChromeOptions;
 | 
					 | 
				
			||||||
use Facebook\WebDriver\Remote\DesiredCapabilities;
 | 
					 | 
				
			||||||
use Facebook\WebDriver\Remote\RemoteWebDriver;
 | 
					 | 
				
			||||||
use Laravel\Dusk\TestCase as BaseTestCase;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
abstract class DuskTestCase extends BaseTestCase
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    use CreatesApplication;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * Prepare for Dusk test execution.
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * @beforeClass
 | 
					 | 
				
			||||||
     * @return void
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    public static function prepare()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        if (! static::runningInSail()) {
 | 
					 | 
				
			||||||
            static::startChromeDriver();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * Create the RemoteWebDriver instance.
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * @return RemoteWebDriver
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    protected function driver()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $options = (new ChromeOptions)->addArguments(collect([
 | 
					 | 
				
			||||||
            '--window-size=1920,1080',
 | 
					 | 
				
			||||||
        ])->unless($this->hasHeadlessDisabled(), function ($items) {
 | 
					 | 
				
			||||||
            return $items->merge([
 | 
					 | 
				
			||||||
                '--disable-gpu',
 | 
					 | 
				
			||||||
                '--headless',
 | 
					 | 
				
			||||||
            ]);
 | 
					 | 
				
			||||||
        })->all());
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return RemoteWebDriver::create(
 | 
					 | 
				
			||||||
            $_ENV['DUSK_DRIVER_URL'] ?? 'http://localhost:9515',
 | 
					 | 
				
			||||||
            DesiredCapabilities::chrome()->setCapability(
 | 
					 | 
				
			||||||
                ChromeOptions::CAPABILITY,
 | 
					 | 
				
			||||||
                $options
 | 
					 | 
				
			||||||
            )
 | 
					 | 
				
			||||||
        );
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * Determine whether the Dusk command has disabled headless mode.
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * @return bool
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    protected function hasHeadlessDisabled()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        return isset($_SERVER['DUSK_HEADLESS_DISABLED']) ||
 | 
					 | 
				
			||||||
            isset($_ENV['DUSK_HEADLESS_DISABLED']);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * Disable all company gateways, test classes should enable them per need.
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * @return void
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    public function disableCompanyGateways()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        CompanyGateway::where('company_id', 1)->delete();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user