mirror of
				https://github.com/invoiceninja/invoiceninja.git
				synced 2025-11-04 04:07:32 -05:00 
			
		
		
		
	
						commit
						a0f0607f71
					
				
							
								
								
									
										1
									
								
								.env.ci
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								.env.ci
									
									
									
									
									
								
							@ -24,3 +24,4 @@ PHANTOMJS_PDF_GENERATION=false
 | 
				
			|||||||
CACHE_DRIVER=redis
 | 
					CACHE_DRIVER=redis
 | 
				
			||||||
QUEUE_CONNECTION=redis
 | 
					QUEUE_CONNECTION=redis
 | 
				
			||||||
SESSION_DRIVER=redis
 | 
					SESSION_DRIVER=redis
 | 
				
			||||||
 | 
					PDF_GENERATOR=hosted_ninja
 | 
				
			||||||
@ -1 +1 @@
 | 
				
			|||||||
5.9.6
 | 
					5.9.7
 | 
				
			||||||
@ -176,6 +176,7 @@ class BackupUpdate extends Command
 | 
				
			|||||||
                    try {
 | 
					                    try {
 | 
				
			||||||
                        $doc_bin = $document->getFile();
 | 
					                        $doc_bin = $document->getFile();
 | 
				
			||||||
                    } catch(\Exception $e) {
 | 
					                    } catch(\Exception $e) {
 | 
				
			||||||
 | 
					                        nlog("Exception:: BackupUpdate::" . $e->getMessage());
 | 
				
			||||||
                        nlog($e->getMessage());
 | 
					                        nlog($e->getMessage());
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -184,8 +185,6 @@ class BackupUpdate extends Command
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                        $document->disk = $this->option('disk');
 | 
					                        $document->disk = $this->option('disk');
 | 
				
			||||||
                        $document->saveQuietly();
 | 
					                        $document->saveQuietly();
 | 
				
			||||||
 | 
					 | 
				
			||||||
                        nlog("Documents - Moving {$document->url} to {$this->option('disk')}");
 | 
					 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                });
 | 
					                });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -199,8 +198,6 @@ class BackupUpdate extends Command
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                    if ($backup_bin) {
 | 
					                    if ($backup_bin) {
 | 
				
			||||||
                        Storage::disk($this->option('disk'))->put($backup->filename, $backup_bin);
 | 
					                        Storage::disk($this->option('disk'))->put($backup->filename, $backup_bin);
 | 
				
			||||||
 | 
					 | 
				
			||||||
                        nlog("Backups - Moving {$backup->filename} to {$this->option('disk')}");
 | 
					 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                });
 | 
					                });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
@ -220,6 +220,7 @@ class BaseRule implements RuleInterface
 | 
				
			|||||||
                try {
 | 
					                try {
 | 
				
			||||||
                    $this->invoice->saveQuietly();
 | 
					                    $this->invoice->saveQuietly();
 | 
				
			||||||
                } catch(\Exception $e) {
 | 
					                } catch(\Exception $e) {
 | 
				
			||||||
 | 
					                    nlog("Exception:: BaseRule::" . $e->getMessage());
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										44
									
								
								app/Exceptions/DuplicatePaymentException.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								app/Exceptions/DuplicatePaymentException.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,44 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Invoice Ninja (https://invoiceninja.com).
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @copyright Copyright (c) 2024. Invoice Ninja LLC (https://invoiceninja.com)
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @license https://www.elastic.co/licensing/elastic-license
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace App\Exceptions;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use Exception;
 | 
				
			||||||
 | 
					use Illuminate\Http\JsonResponse;
 | 
				
			||||||
 | 
					use Illuminate\Http\Request;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class DuplicatePaymentException extends Exception
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Report the exception.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return void
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function report()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        //
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Render the exception into an HTTP response.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param  Request  $request
 | 
				
			||||||
 | 
					     * @return JsonResponse
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function render($request)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return response()->json([
 | 
				
			||||||
 | 
					            'message' => 'Duplicate request',
 | 
				
			||||||
 | 
					        ], 400);
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -1,111 +0,0 @@
 | 
				
			|||||||
<?php
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Invoice Ninja (https://invoiceninja.com).
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @link https://github.com/invoiceninja/invoiceninja source repository
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @copyright Copyright (c) 2024. Invoice Ninja LLC (https://invoiceninja.com)
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @license https://www.elastic.co/licensing/elastic-license
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace App\Helpers\Bank\Yodlee\DTO;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use Illuminate\Support\Collection;
 | 
					 | 
				
			||||||
use Spatie\LaravelData\Attributes\MapInputName;
 | 
					 | 
				
			||||||
use Spatie\LaravelData\Data;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * @deprecated
 | 
					 | 
				
			||||||
 * [
 | 
					 | 
				
			||||||
    "account": [
 | 
					 | 
				
			||||||
      [
 | 
					 | 
				
			||||||
        "CONTAINER": "bank",
 | 
					 | 
				
			||||||
        "providerAccountId": 1005,
 | 
					 | 
				
			||||||
        "accountName": "Business Acct",
 | 
					 | 
				
			||||||
        "accountStatus": "ACTIVE",
 | 
					 | 
				
			||||||
        "accountNumber": "1011",
 | 
					 | 
				
			||||||
        "aggregationSource": "USER",
 | 
					 | 
				
			||||||
        "isAsset": true,
 | 
					 | 
				
			||||||
        "balance": [
 | 
					 | 
				
			||||||
          "currency": "AUD",
 | 
					 | 
				
			||||||
          "amount": 304.98,
 | 
					 | 
				
			||||||
        ],
 | 
					 | 
				
			||||||
        "id": 10139315,
 | 
					 | 
				
			||||||
        "includeInNetWorth": true,
 | 
					 | 
				
			||||||
        "providerId": "3857",
 | 
					 | 
				
			||||||
        "providerName": "Bank",
 | 
					 | 
				
			||||||
        "isManual": false,
 | 
					 | 
				
			||||||
        "availableBalance": {#2966
 | 
					 | 
				
			||||||
          "currency": "AUD",
 | 
					 | 
				
			||||||
          "amount": 304.98,
 | 
					 | 
				
			||||||
        ],
 | 
					 | 
				
			||||||
        "currentBalance": [
 | 
					 | 
				
			||||||
          "currency": "AUD",
 | 
					 | 
				
			||||||
          "amount": 3044.98,
 | 
					 | 
				
			||||||
        ],
 | 
					 | 
				
			||||||
        "accountType": "CHECKING",
 | 
					 | 
				
			||||||
        "displayedName": "after David",
 | 
					 | 
				
			||||||
        "createdDate": "2023-01-10T08:29:07Z",
 | 
					 | 
				
			||||||
        "classification": "SMALL_BUSINESS",
 | 
					 | 
				
			||||||
        "lastUpdated": "2023-08-01T23:50:13Z",
 | 
					 | 
				
			||||||
        "nickname": "Business ",
 | 
					 | 
				
			||||||
        "bankTransferCode": [
 | 
					 | 
				
			||||||
          [
 | 
					 | 
				
			||||||
            "id": "062",
 | 
					 | 
				
			||||||
            "type": "BSB",
 | 
					 | 
				
			||||||
          ],
 | 
					 | 
				
			||||||
        ],
 | 
					 | 
				
			||||||
        "dataset": [
 | 
					 | 
				
			||||||
          [
 | 
					 | 
				
			||||||
            "name": "BASIC_AGG_DATA",
 | 
					 | 
				
			||||||
            "additionalStatus": "AVAILABLE_DATA_RETRIEVED",
 | 
					 | 
				
			||||||
            "updateEligibility": "ALLOW_UPDATE",
 | 
					 | 
				
			||||||
            "lastUpdated": "2023-08-01T23:49:53Z",
 | 
					 | 
				
			||||||
            "lastUpdateAttempt": "2023-08-01T23:49:53Z",
 | 
					 | 
				
			||||||
            "nextUpdateScheduled": "2023-08-03T14:45:14Z",
 | 
					 | 
				
			||||||
          ],
 | 
					 | 
				
			||||||
        ],
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
    ],
 | 
					 | 
				
			||||||
  ];
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
class AccountSummary extends Data
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    public ?int $id;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[MapInputName('CONTAINER')]
 | 
					 | 
				
			||||||
    public ?string $account_type = '';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[MapInputName('accountName')]
 | 
					 | 
				
			||||||
    public ?string $account_name = '';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[MapInputName('accountStatus')]
 | 
					 | 
				
			||||||
    public ?string $account_status = '';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[MapInputName('accountNumber')]
 | 
					 | 
				
			||||||
    public ?string $account_number = '';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[MapInputName('providerAccountId')]
 | 
					 | 
				
			||||||
    public int $provider_account_id;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[MapInputName('providerId')]
 | 
					 | 
				
			||||||
    public ?string $provider_id = '';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[MapInputName('providerName')]
 | 
					 | 
				
			||||||
    public ?string $provider_name = '';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public ?string $nickname = '';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public ?float $current_balance = 0;
 | 
					 | 
				
			||||||
    public ?string $account_currency = '';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public static function prepareForPipeline(Collection $properties): Collection
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $properties->put('current_balance', $properties['currentBalance']['amount'] ?? 0);
 | 
					 | 
				
			||||||
        $properties->put('account_currency', $properties['currentBalance']['currency'] ?? 0);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return $properties;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -11,7 +11,6 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace App\Http\Controllers\Bank;
 | 
					namespace App\Http\Controllers\Bank;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use App\Helpers\Bank\Yodlee\DTO\AccountSummary;
 | 
					 | 
				
			||||||
use App\Helpers\Bank\Yodlee\Yodlee;
 | 
					use App\Helpers\Bank\Yodlee\Yodlee;
 | 
				
			||||||
use App\Http\Controllers\BaseController;
 | 
					use App\Http\Controllers\BaseController;
 | 
				
			||||||
use App\Http\Requests\Yodlee\YodleeAdminRequest;
 | 
					use App\Http\Requests\Yodlee\YodleeAdminRequest;
 | 
				
			||||||
@ -301,8 +300,6 @@ class YodleeController extends BaseController
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        $summary = $yodlee->getAccountSummary($account_number);
 | 
					        $summary = $yodlee->getAccountSummary($account_number);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        //@todo remove laravel-data
 | 
					 | 
				
			||||||
        // $transformed_summary = AccountSummary::from($summary[0]);
 | 
					 | 
				
			||||||
        $transformed_summary = $this->transformSummary($summary[0]);
 | 
					        $transformed_summary = $this->transformSummary($summary[0]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return response()->json($transformed_summary, 200);
 | 
					        return response()->json($transformed_summary, 200);
 | 
				
			||||||
 | 
				
			|||||||
@ -495,7 +495,7 @@ class PurchaseOrderController extends BaseController
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        $purchase_orders = PurchaseOrder::withTrashed()->whereIn('id', $this->transformKeys($ids))->company()->get();
 | 
					        $purchase_orders = PurchaseOrder::withTrashed()->whereIn('id', $this->transformKeys($ids))->company()->get();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (! $purchase_orders) {
 | 
					        if ($purchase_orders->count() == 0) {
 | 
				
			||||||
            return response()->json(['message' => 'No Purchase Orders Found']);
 | 
					            return response()->json(['message' => 'No Purchase Orders Found']);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -141,6 +141,7 @@ class StripeConnectController extends BaseController
 | 
				
			|||||||
                $company_gateway->save();
 | 
					                $company_gateway->save();
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        } catch(\Exception $e) {
 | 
					        } catch(\Exception $e) {
 | 
				
			||||||
 | 
					            nlog("Exception:: StripeConnectController::" . $e->getMessage());
 | 
				
			||||||
            nlog("could not harvest stripe company name");
 | 
					            nlog("could not harvest stripe company name");
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -93,6 +93,7 @@ class PasswordProtection
 | 
				
			|||||||
                try {
 | 
					                try {
 | 
				
			||||||
                    $payload = json_decode(base64_decode(str_replace('_', '/', str_replace('-', '+', explode('.', request()->header('X-API-OAUTH-PASSWORD'))[1]))));
 | 
					                    $payload = json_decode(base64_decode(str_replace('_', '/', str_replace('-', '+', explode('.', request()->header('X-API-OAUTH-PASSWORD'))[1]))));
 | 
				
			||||||
                } catch(\Exception $e) {
 | 
					                } catch(\Exception $e) {
 | 
				
			||||||
 | 
					                    nlog("Exception:: PasswordProtection::" . $e->getMessage());
 | 
				
			||||||
                    nlog("could not decode microsoft response");
 | 
					                    nlog("could not decode microsoft response");
 | 
				
			||||||
                    return response()->json(['message' => 'Could not decode the response from Microsoft'], 412);
 | 
					                    return response()->json(['message' => 'Could not decode the response from Microsoft'], 412);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
				
			|||||||
@ -11,6 +11,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace App\Http\Requests\Payment;
 | 
					namespace App\Http\Requests\Payment;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use App\Exceptions\DuplicatePaymentException;
 | 
				
			||||||
use App\Http\Requests\Request;
 | 
					use App\Http\Requests\Request;
 | 
				
			||||||
use App\Http\ValidationRules\Credit\CreditsSumRule;
 | 
					use App\Http\ValidationRules\Credit\CreditsSumRule;
 | 
				
			||||||
use App\Http\ValidationRules\Credit\ValidCreditsRules;
 | 
					use App\Http\ValidationRules\Credit\ValidCreditsRules;
 | 
				
			||||||
@ -79,6 +80,11 @@ class StorePaymentRequest extends Request
 | 
				
			|||||||
        /** @var \App\Models\User $user */
 | 
					        /** @var \App\Models\User $user */
 | 
				
			||||||
        $user = auth()->user();
 | 
					        $user = auth()->user();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if(\Illuminate\Support\Facades\Cache::has($this->ip()."|".$this->input('amount', 0)."|".$this->input('client_id', '')."|".$user->company()->company_key))
 | 
				
			||||||
 | 
					            throw new DuplicatePaymentException('Duplicate request.', 429);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        \Illuminate\Support\Facades\Cache::put(($this->ip()."|".$this->input('amount', 0)."|".$this->input('client_id', '')."|".$user->company()->company_key), true, 1);
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
        $input = $this->all();
 | 
					        $input = $this->all();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $invoices_total = 0;
 | 
					        $invoices_total = 0;
 | 
				
			||||||
 | 
				
			|||||||
@ -126,15 +126,14 @@ class MatchBankTransactions implements ShouldQueue
 | 
				
			|||||||
    {
 | 
					    {
 | 
				
			||||||
        $collection = collect();
 | 
					        $collection = collect();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /** @array $invoices */
 | 
				
			||||||
        $invoices = explode(",", $invoice_hashed_ids);
 | 
					        $invoices = explode(",", $invoice_hashed_ids);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (count($invoices) >= 1) {
 | 
					 | 
				
			||||||
        foreach ($invoices as $invoice) {
 | 
					        foreach ($invoices as $invoice) {
 | 
				
			||||||
            if (is_string($invoice) && strlen($invoice) > 1) {
 | 
					            if (is_string($invoice) && strlen($invoice) > 1) {
 | 
				
			||||||
                $collection->push($this->decodePrimaryKey($invoice));
 | 
					                $collection->push($this->decodePrimaryKey($invoice));
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return $collection->toArray();
 | 
					        return $collection->toArray();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -189,7 +188,7 @@ class MatchBankTransactions implements ShouldQueue
 | 
				
			|||||||
    private function coalesceExpenses($expense): string
 | 
					    private function coalesceExpenses($expense): string
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (!$this->bt->expense_id || strlen($this->bt->expense_id) < 1) {
 | 
					        if (!$this->bt->expense_id || strlen($this->bt->expense_id ?? '') < 2) {
 | 
				
			||||||
            return $expense;
 | 
					            return $expense;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -233,11 +232,12 @@ class MatchBankTransactions implements ShouldQueue
 | 
				
			|||||||
        $_invoices = Invoice::query()
 | 
					        $_invoices = Invoice::query()
 | 
				
			||||||
            ->withTrashed()
 | 
					            ->withTrashed()
 | 
				
			||||||
            ->where('company_id', $this->bt->company_id)
 | 
					            ->where('company_id', $this->bt->company_id)
 | 
				
			||||||
            ->whereIn('id', $this->getInvoices($input['invoice_ids']));
 | 
					            ->whereIn('id', $this->getInvoices($input['invoice_ids']))
 | 
				
			||||||
 | 
					            ->get();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $amount = $this->bt->amount;
 | 
					        $amount = $this->bt->amount;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if ($_invoices && $this->checkPayable($_invoices)) {
 | 
					        if ($_invoices->count() >0 && $this->checkPayable($_invoices)) {
 | 
				
			||||||
            $this->createPayment($_invoices, $amount);
 | 
					            $this->createPayment($_invoices, $amount);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            $this->bts->push($this->bt->id);
 | 
					            $this->bts->push($this->bt->id);
 | 
				
			||||||
@ -323,6 +323,7 @@ class MatchBankTransactions implements ShouldQueue
 | 
				
			|||||||
            });
 | 
					            });
 | 
				
			||||||
        }, 2);
 | 
					        }, 2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // @phpstan-ignore-next-line
 | 
				
			||||||
        if (!$this->invoice) {
 | 
					        if (!$this->invoice) {
 | 
				
			||||||
            return;
 | 
					            return;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@ -355,7 +356,7 @@ class MatchBankTransactions implements ShouldQueue
 | 
				
			|||||||
        $this->setExchangeRate($payment);
 | 
					        $this->setExchangeRate($payment);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /* Create a payment relationship to the invoice entity */
 | 
					        /* Create a payment relationship to the invoice entity */
 | 
				
			||||||
        foreach ($this->attachable_invoices as $attachable_invoice) {
 | 
					        foreach ($this->attachable_invoices as $attachable_invoice) { // @phpstan-ignore-line
 | 
				
			||||||
            $payment->invoices()->attach($attachable_invoice['id'], [
 | 
					            $payment->invoices()->attach($attachable_invoice['id'], [
 | 
				
			||||||
                'amount' => $attachable_invoice['amount'],
 | 
					                'amount' => $attachable_invoice['amount'],
 | 
				
			||||||
            ]);
 | 
					            ]);
 | 
				
			||||||
 | 
				
			|||||||
@ -70,6 +70,7 @@ class UpdateTaxData implements ShouldQueue
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        } catch(\Exception $e) {            
 | 
					        } catch(\Exception $e) {            
 | 
				
			||||||
 | 
					            nlog("Exception:: UpdateTaxData::" . $e->getMessage());
 | 
				
			||||||
            nlog("problem getting tax data => ".$e->getMessage());
 | 
					            nlog("problem getting tax data => ".$e->getMessage());
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -61,6 +61,7 @@ class CompanyTaxRate implements ShouldQueue
 | 
				
			|||||||
                try {
 | 
					                try {
 | 
				
			||||||
                    $calculated_state = USStates::getState($this->company->settings->postal_code);
 | 
					                    $calculated_state = USStates::getState($this->company->settings->postal_code);
 | 
				
			||||||
                } catch(\Exception $e) {
 | 
					                } catch(\Exception $e) {
 | 
				
			||||||
 | 
					                    nlog("Exception:: CompanyTaxRate::" . $e->getMessage());
 | 
				
			||||||
                    nlog("could not calculate state from postal code => {$this->company->settings->postal_code} or from state {$this->company->settings->state}");
 | 
					                    nlog("could not calculate state from postal code => {$this->company->settings->postal_code} or from state {$this->company->settings->state}");
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -123,6 +123,7 @@ class CreateCompany
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        } catch(\Exception $e) {
 | 
					        } catch(\Exception $e) {
 | 
				
			||||||
 | 
					            nlog("Exception:: CreateCompany::" . $e->getMessage());
 | 
				
			||||||
            nlog("Could not resolve country => {$e->getMessage()}");
 | 
					            nlog("Could not resolve country => {$e->getMessage()}");
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -156,6 +157,7 @@ class CreateCompany
 | 
				
			|||||||
            return $company;
 | 
					            return $company;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        } catch(\Exception $e) {
 | 
					        } catch(\Exception $e) {
 | 
				
			||||||
 | 
					            nlog("Exception:: CreateCompany::" . $e->getMessage());
 | 
				
			||||||
            nlog("SETUP: could not complete setup for Spanish Locale");
 | 
					            nlog("SETUP: could not complete setup for Spanish Locale");
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -189,6 +191,7 @@ class CreateCompany
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        } catch(\Exception $e) {
 | 
					        } catch(\Exception $e) {
 | 
				
			||||||
            nlog($e->getMessage());
 | 
					            nlog($e->getMessage());
 | 
				
			||||||
 | 
					            nlog("Exception:: CreateCompany::" . $e->getMessage());
 | 
				
			||||||
            nlog("SETUP: could not complete setup for South African Locale");
 | 
					            nlog("SETUP: could not complete setup for South African Locale");
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -222,6 +225,7 @@ class CreateCompany
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        } catch(\Exception $e) {
 | 
					        } catch(\Exception $e) {
 | 
				
			||||||
            nlog($e->getMessage());
 | 
					            nlog($e->getMessage());
 | 
				
			||||||
 | 
					            nlog("Exception:: CreateCompany::" . $e->getMessage());
 | 
				
			||||||
            nlog("SETUP: could not complete setup for Australian Locale");
 | 
					            nlog("SETUP: could not complete setup for Australian Locale");
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -111,14 +111,17 @@ class CreateRawPdf
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
            $pdf = $ps->boot()->getPdf();
 | 
					            $pdf = $ps->boot()->getPdf();
 | 
				
			||||||
        } catch (\Exception) {
 | 
					        } catch (\Exception $e) {
 | 
				
			||||||
 | 
					            echo "EXCEPTION::".PHP_EOL;
 | 
				
			||||||
 | 
					            echo $e->getMessage().PHP_EOL;
 | 
				
			||||||
            throw new FilePermissionsFailure('Unable to generate the raw PDF');
 | 
					            throw new FilePermissionsFailure('Unable to generate the raw PDF');
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if ($this->entity_string == "invoice" && $this->entity->client->getSetting("merge_e_invoice_to_pdf")) {
 | 
					        if ($this->entity_string == "invoice" && $this->entity->client->getSetting("merge_e_invoice_to_pdf")) {
 | 
				
			||||||
            $pdf = (new MergeEDocument($this->entity, $pdf))->handle();
 | 
					            $pdf = (new MergeEDocument($this->entity, $pdf))->handle();
 | 
				
			||||||
        }        
 | 
					        }        
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $merge_docs = $this->entity->client ? $this->entity->client->getSetting('embed_documents') : $this->company->getSetting('embed_documents');
 | 
					        $merge_docs = isset($this->entity->client) ? $this->entity->client->getSetting('embed_documents') : $this->company->getSetting('embed_documents');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if($merge_docs && ($this->entity->documents()->where('is_public', true)->count() > 0 || $this->company->documents()->where('is_public', true)->count() > 0)) {
 | 
					        if($merge_docs && ($this->entity->documents()->where('is_public', true)->count() > 0 || $this->company->documents()->where('is_public', true)->count() > 0)) {
 | 
				
			||||||
            $pdf = $this->entity->documentMerge($pdf);
 | 
					            $pdf = $this->entity->documentMerge($pdf);
 | 
				
			||||||
 | 
				
			|||||||
@ -71,6 +71,7 @@ class AdjustEmailQuota implements ShouldQueue
 | 
				
			|||||||
                try {
 | 
					                try {
 | 
				
			||||||
                    LightLogs::create(new EmailCount($email_count, $account->key))->send(); // this runs syncronously
 | 
					                    LightLogs::create(new EmailCount($email_count, $account->key))->send(); // this runs syncronously
 | 
				
			||||||
                } catch(\Exception $e) {
 | 
					                } catch(\Exception $e) {
 | 
				
			||||||
 | 
					                    nlog("Exception:: AdjustEmailQuota::" . $e->getMessage());
 | 
				
			||||||
                    nlog($e->getMessage());
 | 
					                    nlog($e->getMessage());
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
				
			|||||||
@ -93,6 +93,7 @@ class BankTransactionSync implements ShouldQueue
 | 
				
			|||||||
                        try {
 | 
					                        try {
 | 
				
			||||||
                            (new ProcessBankTransactionsNordigen($bank_integration))->handle();
 | 
					                            (new ProcessBankTransactionsNordigen($bank_integration))->handle();
 | 
				
			||||||
                        } catch(\Exception $e) {
 | 
					                        } catch(\Exception $e) {
 | 
				
			||||||
 | 
					                            nlog("Exception:: BankTransactioSync::" . $e->getMessage());
 | 
				
			||||||
                            sleep(20);
 | 
					                            sleep(20);
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -89,6 +89,7 @@ class TaskScheduler implements ShouldQueue
 | 
				
			|||||||
                        /** @var \App\Models\Scheduler $scheduler */
 | 
					                        /** @var \App\Models\Scheduler $scheduler */
 | 
				
			||||||
                        $scheduler->service()->runTask();
 | 
					                        $scheduler->service()->runTask();
 | 
				
			||||||
                    } catch(\Exception $e) {
 | 
					                    } catch(\Exception $e) {
 | 
				
			||||||
 | 
					                        nlog("Exception:: TaskScheduler::" . $e->getMessage());
 | 
				
			||||||
                        nlog($e->getMessage());
 | 
					                        nlog($e->getMessage());
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -179,6 +179,7 @@ class Document extends BaseModel
 | 
				
			|||||||
        try {
 | 
					        try {
 | 
				
			||||||
            return route('api.documents.show', ['document' => $this->hashed_id]).'/download';
 | 
					            return route('api.documents.show', ['document' => $this->hashed_id]).'/download';
 | 
				
			||||||
        } catch(\Exception $e) {
 | 
					        } catch(\Exception $e) {
 | 
				
			||||||
 | 
					            nlog("Exception:: Document::" . $e->getMessage());
 | 
				
			||||||
            return '';
 | 
					            return '';
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -252,7 +253,7 @@ class Document extends BaseModel
 | 
				
			|||||||
            return $img->getImageBlob();
 | 
					            return $img->getImageBlob();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        } catch(\Exception $e) {
 | 
					        } catch(\Exception $e) {
 | 
				
			||||||
 | 
					            nlog("Exception:: Document::" . $e->getMessage());
 | 
				
			||||||
            nlog($e->getMessage());
 | 
					            nlog($e->getMessage());
 | 
				
			||||||
            return $catch_image;
 | 
					            return $catch_image;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
				
			|||||||
@ -66,7 +66,7 @@ class EmailQuotaNotification extends Notification
 | 
				
			|||||||
    {
 | 
					    {
 | 
				
			||||||
        $content = "Email quota exceeded by Account {$this->account->key} \n";
 | 
					        $content = "Email quota exceeded by Account {$this->account->key} \n";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $owner = $this->account->companies()->first()->owner();
 | 
					        $owner = $this->account->companies()->first()->owner() ?? $this->account->users()->orderBy('id','asc')->first();
 | 
				
			||||||
        $owner_name = $owner->present()->name() ?? 'No Owner Found';
 | 
					        $owner_name = $owner->present()->name() ?? 'No Owner Found';
 | 
				
			||||||
        $owner_email = $owner->email ?? 'No Owner Email Found';
 | 
					        $owner_email = $owner->email ?? 'No Owner Email Found';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -93,7 +93,6 @@ class RouteServiceProvider extends ServiceProvider
 | 
				
			|||||||
            return Limit::perMinute(15)->by($request->ip());
 | 
					            return Limit::perMinute(15)->by($request->ip());
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
 | 
				
			|||||||
@ -21,10 +21,6 @@ class PaymentMethod
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    use MakesHash;
 | 
					    use MakesHash;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private $client;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    private $amount;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /** @var \Illuminate\Support\Collection<CompanyGateway> $gateways **/
 | 
					    /** @var \Illuminate\Support\Collection<CompanyGateway> $gateways **/
 | 
				
			||||||
    private $gateways;
 | 
					    private $gateways;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -32,10 +28,8 @@ class PaymentMethod
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    private $payment_urls = [];
 | 
					    private $payment_urls = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function __construct(Client $client, float $amount)
 | 
					    public function __construct(private Client $client, private float $amount)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $this->client = $client;
 | 
					 | 
				
			||||||
        $this->amount = $amount;
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function run()
 | 
					    public function run()
 | 
				
			||||||
@ -105,7 +99,6 @@ class PaymentMethod
 | 
				
			|||||||
                $transformed_ids = [];
 | 
					                $transformed_ids = [];
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
            $this->gateways = $this->client
 | 
					            $this->gateways = $this->client
 | 
				
			||||||
                             ->company
 | 
					                             ->company
 | 
				
			||||||
                             ->company_gateways
 | 
					                             ->company_gateways
 | 
				
			||||||
@ -140,7 +133,7 @@ class PaymentMethod
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            foreach ($gateway->driver($this->client)->gatewayTypes() as $type) {
 | 
					            foreach ($gateway->driver($this->client)->gatewayTypes() as $type) {
 | 
				
			||||||
                if (isset($gateway->fees_and_limits) && is_object($gateway->fees_and_limits) && property_exists($gateway->fees_and_limits, $type)) {
 | 
					                if (isset($gateway->fees_and_limits) && is_object($gateway->fees_and_limits) && property_exists($gateway->fees_and_limits, $type)) {
 | 
				
			||||||
                    if ($this->validGatewayForAmount($gateway->fees_and_limits->{$type}, $this->amount) && $gateway->fees_and_limits->{$type}->is_enabled) {
 | 
					                    if ($this->validGatewayForAmount($gateway->fees_and_limits->{$type}) && $gateway->fees_and_limits->{$type}->is_enabled) {
 | 
				
			||||||
                        $this->payment_methods[] = [$gateway->id => $type];
 | 
					                        $this->payment_methods[] = [$gateway->id => $type];
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                } else {
 | 
					                } else {
 | 
				
			||||||
@ -211,6 +204,7 @@ class PaymentMethod
 | 
				
			|||||||
            ];
 | 
					            ];
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    //@deprecated as buildUrl() supercedes
 | 
					    //@deprecated as buildUrl() supercedes
 | 
				
			||||||
@ -256,7 +250,7 @@ class PaymentMethod
 | 
				
			|||||||
        return $this;
 | 
					        return $this;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private function validGatewayForAmount($fees_and_limits_for_payment_type, $amount): bool
 | 
					    private function validGatewayForAmount($fees_and_limits_for_payment_type): bool
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        if (isset($fees_and_limits_for_payment_type)) {
 | 
					        if (isset($fees_and_limits_for_payment_type)) {
 | 
				
			||||||
            $fees_and_limits = $fees_and_limits_for_payment_type;
 | 
					            $fees_and_limits = $fees_and_limits_for_payment_type;
 | 
				
			||||||
 | 
				
			|||||||
@ -68,6 +68,7 @@ class CompanyService
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        } catch(\Exception $e) {
 | 
					        } catch(\Exception $e) {
 | 
				
			||||||
 | 
					            nlog("Exception:: CompanyService::" . $e->getMessage());
 | 
				
			||||||
            nlog($e->getMessage());
 | 
					            nlog($e->getMessage());
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -36,7 +36,7 @@ class TriggeredActions extends AbstractService
 | 
				
			|||||||
            try {
 | 
					            try {
 | 
				
			||||||
                $this->invoice->service()->autoBill();
 | 
					                $this->invoice->service()->autoBill();
 | 
				
			||||||
            } catch(\Exception $e) {
 | 
					            } catch(\Exception $e) {
 | 
				
			||||||
 | 
					                nlog("Exception:: TriggeredActions::" . $e->getMessage());
 | 
				
			||||||
            } //update notification sends automatically for this.
 | 
					            } //update notification sends automatically for this.
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -100,6 +100,7 @@ class TaxProvider
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        } catch(\Exception $e) {
 | 
					        } catch(\Exception $e) {
 | 
				
			||||||
 | 
					            nlog("Exception:: TaxProvider::" . $e->getMessage());
 | 
				
			||||||
            nlog("Could not updated company tax data: " . $e->getMessage());
 | 
					            nlog("Could not updated company tax data: " . $e->getMessage());
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -91,7 +91,6 @@
 | 
				
			|||||||
        "setasign/fpdi": "^2.3",
 | 
					        "setasign/fpdi": "^2.3",
 | 
				
			||||||
        "socialiteproviders/apple": "dev-master",
 | 
					        "socialiteproviders/apple": "dev-master",
 | 
				
			||||||
        "socialiteproviders/microsoft": "^4.1",
 | 
					        "socialiteproviders/microsoft": "^4.1",
 | 
				
			||||||
        "spatie/laravel-data": "^3.6",
 | 
					 | 
				
			||||||
        "sprain/swiss-qr-bill": "^4.3",
 | 
					        "sprain/swiss-qr-bill": "^4.3",
 | 
				
			||||||
        "square/square": "30.0.0.*",
 | 
					        "square/square": "30.0.0.*",
 | 
				
			||||||
        "stripe/stripe-php": "^12",
 | 
					        "stripe/stripe-php": "^12",
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										1472
									
								
								composer.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										1472
									
								
								composer.lock
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@ -17,8 +17,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' => env('APP_VERSION', '5.9.6'),
 | 
					    'app_version' => env('APP_VERSION', '5.9.7'),
 | 
				
			||||||
    'app_tag' => env('APP_TAG', '5.9.6'),
 | 
					    'app_tag' => env('APP_TAG', '5.9.7'),
 | 
				
			||||||
    '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', false),
 | 
					    'api_secret' => env('API_SECRET', false),
 | 
				
			||||||
 | 
				
			|||||||
@ -77,6 +77,7 @@
 | 
				
			|||||||
@section('gateway_footer')
 | 
					@section('gateway_footer')
 | 
				
			||||||
@endsection
 | 
					@endsection
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@push('footer')
 | 
					@push('footer')
 | 
				
			||||||
<script type="application/json" fncls="fnparams-dede7cc5-15fd-4c75-a9f4-36c430ee3a99">
 | 
					<script type="application/json" fncls="fnparams-dede7cc5-15fd-4c75-a9f4-36c430ee3a99">
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
				
			|||||||
@ -38,11 +38,14 @@ class ClientModelTest extends TestCase
 | 
				
			|||||||
        if (! config('ninja.testvars.stripe')) {
 | 
					        if (! config('ninja.testvars.stripe')) {
 | 
				
			||||||
            $this->markTestSkipped('Skip test no company gateways installed');
 | 
					            $this->markTestSkipped('Skip test no company gateways installed');
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if(CompanyGateway::count() == 0)
 | 
				
			||||||
 | 
					            $this->markTestSkipped('Skip test no company gateways installed');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function testPaymentMethodsWithCreditsEnforced()
 | 
					    public function testPaymentMethodsWithCreditsEnforced()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $amount = 40;
 | 
					 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        $payment_methods = $this->client->service()->getPaymentMethods(40);
 | 
					        $payment_methods = $this->client->service()->getPaymentMethods(40);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -54,7 +54,9 @@ class CompanyGatewayResolutionTest extends TestCase
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        $this->withoutExceptionHandling();
 | 
					        $this->withoutExceptionHandling();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        CompanyGateway::whereNotNull('id')->delete();
 | 
					        CompanyGateway::query()->withTrashed()->cursor()->each(function ($cg){
 | 
				
			||||||
 | 
					            $cg->forceDelete();
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $data = [];
 | 
					        $data = [];
 | 
				
			||||||
        $data[1]['min_limit'] = -1;
 | 
					        $data[1]['min_limit'] = -1;
 | 
				
			||||||
@ -123,6 +125,9 @@ class CompanyGatewayResolutionTest extends TestCase
 | 
				
			|||||||
    {
 | 
					    {
 | 
				
			||||||
        $amount = 10;
 | 
					        $amount = 10;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->client->country_id = 840;
 | 
				
			||||||
 | 
					        $this->client->save();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->assertInstanceOf('\\stdClass', $this->cg->fees_and_limits);
 | 
					        $this->assertInstanceOf('\\stdClass', $this->cg->fees_and_limits);
 | 
				
			||||||
        // $this->assertObjectHasAttribute('min_limit', $this->cg->fees_and_limits->{1});
 | 
					        // $this->assertObjectHasAttribute('min_limit', $this->cg->fees_and_limits->{1});
 | 
				
			||||||
        $this->assertNotNull($this->cg->fees_and_limits->{1}->min_limit);
 | 
					        $this->assertNotNull($this->cg->fees_and_limits->{1}->min_limit);
 | 
				
			||||||
@ -135,7 +140,9 @@ class CompanyGatewayResolutionTest extends TestCase
 | 
				
			|||||||
    {
 | 
					    {
 | 
				
			||||||
        $amount = 10;
 | 
					        $amount = 10;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        CompanyGateway::whereNotNull('id')->delete();
 | 
					        CompanyGateway::query()->withTrashed()->cursor()->each(function ($cg) {
 | 
				
			||||||
 | 
					            $cg->forceDelete();
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $data = [];
 | 
					        $data = [];
 | 
				
			||||||
        $data[1]['min_limit'] = -1;
 | 
					        $data[1]['min_limit'] = -1;
 | 
				
			||||||
@ -181,9 +188,10 @@ class CompanyGatewayResolutionTest extends TestCase
 | 
				
			|||||||
        $this->cg->fees_and_limits = $data;
 | 
					        $this->cg->fees_and_limits = $data;
 | 
				
			||||||
        $this->cg->save();
 | 
					        $this->cg->save();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // nlog($this->client->service()->getPaymentMethods($amount));
 | 
					        $this->client->country_id = 840;
 | 
				
			||||||
 | 
					        $this->client->save();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->assertEquals(2, count($this->client->service()->getPaymentMethods($amount)));
 | 
					        $this->assertEquals(1, count($this->client->service()->getPaymentMethods($amount)));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function testEnableFeeAdjustment()
 | 
					    public function testEnableFeeAdjustment()
 | 
				
			||||||
 | 
				
			|||||||
@ -75,6 +75,7 @@ class PaymentTest extends TestCase
 | 
				
			|||||||
                ],
 | 
					                ],
 | 
				
			||||||
            ],
 | 
					            ],
 | 
				
			||||||
            'date' => '2020/12/11',
 | 
					            'date' => '2020/12/11',
 | 
				
			||||||
 | 
					            'idempotency_key' => 'xx',
 | 
				
			||||||
        ];
 | 
					        ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $response = $this->withHeaders([
 | 
					        $response = $this->withHeaders([
 | 
				
			||||||
@ -84,6 +85,8 @@ class PaymentTest extends TestCase
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        $response->assertStatus(200);
 | 
					        $response->assertStatus(200);
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
 | 
					        sleep(1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $response = $this->withHeaders([
 | 
					        $response = $this->withHeaders([
 | 
				
			||||||
            'X-API-SECRET' => config('ninja.api_secret'),
 | 
					            'X-API-SECRET' => config('ninja.api_secret'),
 | 
				
			||||||
            'X-API-TOKEN' => $this->token,
 | 
					            'X-API-TOKEN' => $this->token,
 | 
				
			||||||
@ -1869,6 +1872,7 @@ class PaymentTest extends TestCase
 | 
				
			|||||||
            'date' => '2020/12/12',
 | 
					            'date' => '2020/12/12',
 | 
				
			||||||
            'number' => 'duplicate',
 | 
					            'number' => 'duplicate',
 | 
				
			||||||
        ];
 | 
					        ];
 | 
				
			||||||
 | 
					sleep(1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $response = $this->withHeaders([
 | 
					        $response = $this->withHeaders([
 | 
				
			||||||
            'X-API-SECRET' => config('ninja.api_secret'),
 | 
					            'X-API-SECRET' => config('ninja.api_secret'),
 | 
				
			||||||
@ -1876,7 +1880,7 @@ class PaymentTest extends TestCase
 | 
				
			|||||||
        ])->postJson('/api/v1/payments', $data);
 | 
					        ])->postJson('/api/v1/payments', $data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $response->assertStatus(200);
 | 
					        $response->assertStatus(200);
 | 
				
			||||||
 | 
					sleep(1);
 | 
				
			||||||
        $response = $this->withHeaders([
 | 
					        $response = $this->withHeaders([
 | 
				
			||||||
            'X-API-SECRET' => config('ninja.api_secret'),
 | 
					            'X-API-SECRET' => config('ninja.api_secret'),
 | 
				
			||||||
            'X-API-TOKEN' => $this->token,
 | 
					            'X-API-TOKEN' => $this->token,
 | 
				
			||||||
 | 
				
			|||||||
@ -11,19 +11,20 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace Tests\Feature;
 | 
					namespace Tests\Feature;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use Tests\TestCase;
 | 
				
			||||||
 | 
					use App\Utils\Ninja;
 | 
				
			||||||
 | 
					use App\Models\Activity;
 | 
				
			||||||
 | 
					use Tests\MockAccountData;
 | 
				
			||||||
 | 
					use Illuminate\Support\Str;
 | 
				
			||||||
 | 
					use App\Models\PurchaseOrder;
 | 
				
			||||||
 | 
					use App\Utils\Traits\MakesHash;
 | 
				
			||||||
 | 
					use App\Models\PurchaseOrderInvitation;
 | 
				
			||||||
 | 
					use Illuminate\Database\Eloquent\Model;
 | 
				
			||||||
 | 
					use Illuminate\Support\Facades\Session;
 | 
				
			||||||
 | 
					use App\Repositories\ActivityRepository;
 | 
				
			||||||
use App\Events\PurchaseOrder\PurchaseOrderWasCreated;
 | 
					use App\Events\PurchaseOrder\PurchaseOrderWasCreated;
 | 
				
			||||||
use App\Events\PurchaseOrder\PurchaseOrderWasUpdated;
 | 
					use App\Events\PurchaseOrder\PurchaseOrderWasUpdated;
 | 
				
			||||||
use App\Models\Activity;
 | 
					 | 
				
			||||||
use App\Models\PurchaseOrder;
 | 
					 | 
				
			||||||
use App\Repositories\ActivityRepository;
 | 
					 | 
				
			||||||
use App\Utils\Ninja;
 | 
					 | 
				
			||||||
use App\Utils\Traits\MakesHash;
 | 
					 | 
				
			||||||
use Illuminate\Database\Eloquent\Model;
 | 
					 | 
				
			||||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
 | 
					use Illuminate\Foundation\Testing\DatabaseTransactions;
 | 
				
			||||||
use Illuminate\Support\Facades\Session;
 | 
					 | 
				
			||||||
use Illuminate\Support\Str;
 | 
					 | 
				
			||||||
use Tests\MockAccountData;
 | 
					 | 
				
			||||||
use Tests\TestCase;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
class PurchaseOrderTest extends TestCase
 | 
					class PurchaseOrderTest extends TestCase
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -37,12 +38,8 @@ class PurchaseOrderTest extends TestCase
 | 
				
			|||||||
    {
 | 
					    {
 | 
				
			||||||
        parent::setUp();
 | 
					        parent::setUp();
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        Session::start();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->faker = \Faker\Factory::create();
 | 
					        $this->faker = \Faker\Factory::create();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Model::reguard();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->makeTestData();
 | 
					        $this->makeTestData();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -97,10 +94,39 @@ class PurchaseOrderTest extends TestCase
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    public function testPurchaseOrderBulkActions()
 | 
					    public function testPurchaseOrderBulkActions()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $i = $this->purchase_order->invitations->first();
 | 
					
 | 
				
			||||||
 | 
					        $po = PurchaseOrder::factory()->create([
 | 
				
			||||||
 | 
					            'user_id' => $this->user->id,
 | 
				
			||||||
 | 
					            'company_id' => $this->company->id,
 | 
				
			||||||
 | 
					            'vendor_id' => $this->vendor->id,
 | 
				
			||||||
 | 
					        ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // PurchaseOrderInvitation::factory()->create([
 | 
				
			||||||
 | 
					        //     'user_id' => $this->user->id,
 | 
				
			||||||
 | 
					        //     'company_id' => $this->company->id,
 | 
				
			||||||
 | 
					        //     'vendor_contact_id' => $this->vendor->contacts()->first()->id,
 | 
				
			||||||
 | 
					        //     'purchase_order_id' => $po->id,
 | 
				
			||||||
 | 
					        // ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $po->service()->createInvitations()->save();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $i = $po->invitations->first();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $data = [
 | 
					        $data = [
 | 
				
			||||||
            'ids' =>[$this->purchase_order->hashed_id],
 | 
					            'ids' => [$po->hashed_id],
 | 
				
			||||||
 | 
					            'action' => 'download',
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $response = $this->withHeaders([
 | 
				
			||||||
 | 
					            'X-API-SECRET' => config('ninja.api_secret'),
 | 
				
			||||||
 | 
					            'X-API-TOKEN' => $this->token,
 | 
				
			||||||
 | 
					        ])->post("/api/v1/purchase_orders/bulk", $data)
 | 
				
			||||||
 | 
					        ->assertStatus(200);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $data = [
 | 
				
			||||||
 | 
					            'ids' =>[$po->hashed_id],
 | 
				
			||||||
            'action' => 'archive',
 | 
					            'action' => 'archive',
 | 
				
			||||||
        ];
 | 
					        ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -111,7 +137,7 @@ class PurchaseOrderTest extends TestCase
 | 
				
			|||||||
        ->assertStatus(200);
 | 
					        ->assertStatus(200);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $data = [
 | 
					        $data = [
 | 
				
			||||||
            'ids' =>[$this->purchase_order->hashed_id],
 | 
					            'ids' =>[$po->hashed_id],
 | 
				
			||||||
            'action' => 'restore',
 | 
					            'action' => 'restore',
 | 
				
			||||||
        ];
 | 
					        ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -122,7 +148,7 @@ class PurchaseOrderTest extends TestCase
 | 
				
			|||||||
        ->assertStatus(200);
 | 
					        ->assertStatus(200);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $data = [
 | 
					        $data = [
 | 
				
			||||||
            'ids' =>[$this->purchase_order->hashed_id],
 | 
					            'ids' =>[$po->hashed_id],
 | 
				
			||||||
            'action' => 'delete',
 | 
					            'action' => 'delete',
 | 
				
			||||||
        ];
 | 
					        ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -134,7 +160,7 @@ class PurchaseOrderTest extends TestCase
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $data = [
 | 
					        $data = [
 | 
				
			||||||
            'ids' =>[$this->purchase_order->hashed_id],
 | 
					            'ids' =>[$po->hashed_id],
 | 
				
			||||||
            'action' => 'restore',
 | 
					            'action' => 'restore',
 | 
				
			||||||
        ];
 | 
					        ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -144,16 +170,6 @@ class PurchaseOrderTest extends TestCase
 | 
				
			|||||||
        ])->post("/api/v1/purchase_orders/bulk", $data)
 | 
					        ])->post("/api/v1/purchase_orders/bulk", $data)
 | 
				
			||||||
        ->assertStatus(200);
 | 
					        ->assertStatus(200);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $data = [
 | 
					 | 
				
			||||||
            'ids' =>[$this->purchase_order->hashed_id],
 | 
					 | 
				
			||||||
            'action' => 'download',
 | 
					 | 
				
			||||||
        ];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $response = $this->withHeaders([
 | 
					 | 
				
			||||||
            'X-API-SECRET' => config('ninja.api_secret'),
 | 
					 | 
				
			||||||
            'X-API-TOKEN' => $this->token,
 | 
					 | 
				
			||||||
        ])->post("/api/v1/purchase_orders/bulk", $data)
 | 
					 | 
				
			||||||
        ->assertStatus(200);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $data = [
 | 
					        $data = [
 | 
				
			||||||
            'ids' =>[],
 | 
					            'ids' =>[],
 | 
				
			||||||
@ -167,7 +183,7 @@ class PurchaseOrderTest extends TestCase
 | 
				
			|||||||
        ->assertStatus(302);
 | 
					        ->assertStatus(302);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $data = [
 | 
					        $data = [
 | 
				
			||||||
            'ids' =>[$this->purchase_order->hashed_id],
 | 
					            'ids' =>[$po->hashed_id],
 | 
				
			||||||
            'action' => '',
 | 
					            'action' => '',
 | 
				
			||||||
        ];
 | 
					        ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -179,7 +195,7 @@ class PurchaseOrderTest extends TestCase
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $data = [
 | 
					        $data = [
 | 
				
			||||||
            'ids' =>[$this->purchase_order->hashed_id],
 | 
					            'ids' =>[$po->hashed_id],
 | 
				
			||||||
            'action' => 'molly',
 | 
					            'action' => 'molly',
 | 
				
			||||||
        ];
 | 
					        ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -128,18 +128,6 @@ class AccountSummaryTest extends TestCase
 | 
				
			|||||||
        parent::setUp();
 | 
					        parent::setUp();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function testWithBadDataTransformations()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $dtox = \App\Helpers\Bank\Yodlee\DTO\AccountSummary::from($this->bad_data[0]);
 | 
					 | 
				
			||||||
        $this->assertEquals(19315, $dtox->id);
 | 
					 | 
				
			||||||
        $this->assertEquals('', $dtox->account_status);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function testTransform()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $dto = \App\Helpers\Bank\Yodlee\DTO\AccountSummary::from($this->data[0]);
 | 
					 | 
				
			||||||
        $this->assertEquals($dto->id, 19315);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function testTransformRefactor()
 | 
					    public function testTransformRefactor()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
				
			|||||||
@ -203,32 +203,32 @@ trait MockAccountData
 | 
				
			|||||||
    {
 | 
					    {
 | 
				
			||||||
        config(['database.default' => config('ninja.db.default')]);
 | 
					        config(['database.default' => config('ninja.db.default')]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /* Warm up the cache !*/
 | 
					        // /* Warm up the cache !*/
 | 
				
			||||||
        $cached_tables = config('ninja.cached_tables');
 | 
					        // $cached_tables = config('ninja.cached_tables');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Artisan::call('db:seed', [
 | 
					        // Artisan::call('db:seed', [
 | 
				
			||||||
        '--force' => true
 | 
					        // '--force' => true
 | 
				
			||||||
        ]);
 | 
					        // ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        foreach ($cached_tables as $name => $class) {
 | 
					        // foreach ($cached_tables as $name => $class) {
 | 
				
			||||||
            // check that the table exists in case the migration is pending
 | 
					        //     // check that the table exists in case the migration is pending
 | 
				
			||||||
            if (! Schema::hasTable((new $class())->getTable())) {
 | 
					        //     if (! Schema::hasTable((new $class())->getTable())) {
 | 
				
			||||||
                continue;
 | 
					        //         continue;
 | 
				
			||||||
            }
 | 
					        //     }
 | 
				
			||||||
            if ($name == 'payment_terms') {
 | 
					        //     if ($name == 'payment_terms') {
 | 
				
			||||||
                $orderBy = 'num_days';
 | 
					        //         $orderBy = 'num_days';
 | 
				
			||||||
            } elseif ($name == 'fonts') {
 | 
					        //     } elseif ($name == 'fonts') {
 | 
				
			||||||
                $orderBy = 'sort_order';
 | 
					        //         $orderBy = 'sort_order';
 | 
				
			||||||
            } elseif (in_array($name, ['currencies', 'industries', 'languages', 'countries', 'banks'])) {
 | 
					        //     } elseif (in_array($name, ['currencies', 'industries', 'languages', 'countries', 'banks'])) {
 | 
				
			||||||
                $orderBy = 'name';
 | 
					        //         $orderBy = 'name';
 | 
				
			||||||
            } else {
 | 
					        //     } else {
 | 
				
			||||||
                $orderBy = 'id';
 | 
					        //         $orderBy = 'id';
 | 
				
			||||||
            }
 | 
					        //     }
 | 
				
			||||||
            $tableData = $class::orderBy($orderBy)->get();
 | 
					        //     $tableData = $class::orderBy($orderBy)->get();
 | 
				
			||||||
            if ($tableData->count()) {
 | 
					        //     if ($tableData->count()) {
 | 
				
			||||||
                Cache::forever($name, $tableData);
 | 
					        //         Cache::forever($name, $tableData);
 | 
				
			||||||
            }
 | 
					        //     }
 | 
				
			||||||
        }
 | 
					        // }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->faker = \Faker\Factory::create();
 | 
					        $this->faker = \Faker\Factory::create();
 | 
				
			||||||
        $fake_email = $this->faker->email();
 | 
					        $fake_email = $this->faker->email();
 | 
				
			||||||
@ -600,14 +600,9 @@ trait MockAccountData
 | 
				
			|||||||
            'purchase_order_id' => $this->purchase_order->id,
 | 
					            'purchase_order_id' => $this->purchase_order->id,
 | 
				
			||||||
        ]);
 | 
					        ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $purchase_order_invitations = PurchaseOrderInvitation::whereCompanyId($this->purchase_order->company_id)
 | 
					 | 
				
			||||||
            ->wherePurchaseOrderId($this->purchase_order->id);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->purchase_order->setRelation('invitations', $purchase_order_invitations);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->purchase_order->service()->markSent();
 | 
					        $this->purchase_order->service()->markSent();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->purchase_order->setRelation('client', $this->client);
 | 
					        $this->purchase_order->setRelation('vendor', $this->vendor);
 | 
				
			||||||
        $this->purchase_order->setRelation('company', $this->company);
 | 
					        $this->purchase_order->setRelation('company', $this->company);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->purchase_order->save();
 | 
					        $this->purchase_order->save();
 | 
				
			||||||
@ -813,7 +808,7 @@ trait MockAccountData
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        if (config('ninja.testvars.stripe')) {
 | 
					        if (config('ninja.testvars.stripe')) {
 | 
				
			||||||
            $data = [];
 | 
					            $data = [];
 | 
				
			||||||
            $data[1]['min_limit'] = 234;
 | 
					            $data[1]['min_limit'] = 22;
 | 
				
			||||||
            $data[1]['max_limit'] = 65317;
 | 
					            $data[1]['max_limit'] = 65317;
 | 
				
			||||||
            $data[1]['fee_amount'] = 0.00;
 | 
					            $data[1]['fee_amount'] = 0.00;
 | 
				
			||||||
            $data[1]['fee_percent'] = 0.000;
 | 
					            $data[1]['fee_percent'] = 0.000;
 | 
				
			||||||
 | 
				
			|||||||
@ -24,6 +24,11 @@ class PdfGenerationTest extends TestCase
 | 
				
			|||||||
    protected function setUp(): void
 | 
					    protected function setUp(): void
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        parent::setUp();
 | 
					        parent::setUp();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if (config('ninja.testvars.travis') !== false) {
 | 
				
			||||||
 | 
					    $this->markTestSkipped('Skip test for Travis');
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function testPdfGeneration()
 | 
					    public function testPdfGeneration()
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user