mirror of
				https://github.com/invoiceninja/invoiceninja.git
				synced 2025-10-31 14:07:32 -04:00 
			
		
		
		
	Merge branch 'v5-develop' into v5-stable
This commit is contained in:
		
						commit
						1621dd91e7
					
				| @ -1 +1 @@ | |||||||
| 5.5.32 | 5.5.33 | ||||||
| @ -17,6 +17,7 @@ use App\Jobs\Cron\RecurringInvoicesCron; | |||||||
| use App\Jobs\Cron\SubscriptionCron; | use App\Jobs\Cron\SubscriptionCron; | ||||||
| use App\Jobs\Ledger\LedgerBalanceUpdate; | use App\Jobs\Ledger\LedgerBalanceUpdate; | ||||||
| use App\Jobs\Ninja\AdjustEmailQuota; | use App\Jobs\Ninja\AdjustEmailQuota; | ||||||
|  | use App\Jobs\Ninja\BankTransactionSync; | ||||||
| use App\Jobs\Ninja\CompanySizeCheck; | use App\Jobs\Ninja\CompanySizeCheck; | ||||||
| use App\Jobs\Ninja\QueueSize; | use App\Jobs\Ninja\QueueSize; | ||||||
| use App\Jobs\Ninja\SystemMaintenance; | use App\Jobs\Ninja\SystemMaintenance; | ||||||
| @ -42,40 +43,59 @@ class Kernel extends ConsoleKernel | |||||||
|      */ |      */ | ||||||
|     protected function schedule(Schedule $schedule) |     protected function schedule(Schedule $schedule) | ||||||
|     { |     { | ||||||
|  |         /* Check for the latest version of Invoice Ninja */ | ||||||
|         $schedule->job(new VersionCheck)->daily(); |         $schedule->job(new VersionCheck)->daily(); | ||||||
| 
 | 
 | ||||||
|  |         /* Checks and cleans redundant files */ | ||||||
|         $schedule->job(new DiskCleanup)->daily()->withoutOverlapping(); |         $schedule->job(new DiskCleanup)->daily()->withoutOverlapping(); | ||||||
| 
 | 
 | ||||||
|  |         /* Send reminders */ | ||||||
|         $schedule->job(new ReminderJob)->hourly()->withoutOverlapping(); |         $schedule->job(new ReminderJob)->hourly()->withoutOverlapping(); | ||||||
| 
 | 
 | ||||||
|  |         /* Returns the number of jobs in the queue */ | ||||||
|         $schedule->job(new QueueSize)->everyFiveMinutes()->withoutOverlapping(); |         $schedule->job(new QueueSize)->everyFiveMinutes()->withoutOverlapping(); | ||||||
| 
 | 
 | ||||||
|  |         /* Checks for large companies and marked them as is_large */ | ||||||
|         $schedule->job(new CompanySizeCheck)->daily()->withoutOverlapping(); |         $schedule->job(new CompanySizeCheck)->daily()->withoutOverlapping(); | ||||||
| 
 | 
 | ||||||
|  |         /* Pulls in the latest exchange rates */ | ||||||
|         $schedule->job(new UpdateExchangeRates)->daily()->withoutOverlapping(); |         $schedule->job(new UpdateExchangeRates)->daily()->withoutOverlapping(); | ||||||
| 
 | 
 | ||||||
|  |         /* Runs cleanup code for subscriptions */ | ||||||
|         $schedule->job(new SubscriptionCron)->daily()->withoutOverlapping(); |         $schedule->job(new SubscriptionCron)->daily()->withoutOverlapping(); | ||||||
| 
 | 
 | ||||||
|  |         /* Sends recurring invoices*/ | ||||||
|         $schedule->job(new RecurringInvoicesCron)->hourly()->withoutOverlapping(); |         $schedule->job(new RecurringInvoicesCron)->hourly()->withoutOverlapping(); | ||||||
| 
 | 
 | ||||||
|  |         /* Sends recurring invoices*/ | ||||||
|         $schedule->job(new RecurringExpensesCron)->dailyAt('00:10')->withoutOverlapping(); |         $schedule->job(new RecurringExpensesCron)->dailyAt('00:10')->withoutOverlapping(); | ||||||
| 
 | 
 | ||||||
|  |         /* Performs auto billing */ | ||||||
|         $schedule->job(new AutoBillCron)->dailyAt('06:00')->withoutOverlapping(); |         $schedule->job(new AutoBillCron)->dailyAt('06:00')->withoutOverlapping(); | ||||||
| 
 | 
 | ||||||
|  |         /* Checks the status of the scheduler */ | ||||||
|         $schedule->job(new SchedulerCheck)->daily()->withoutOverlapping(); |         $schedule->job(new SchedulerCheck)->daily()->withoutOverlapping(); | ||||||
| 
 | 
 | ||||||
|  |         /* Checks for scheduled tasks */ | ||||||
|         $schedule->job(new TaskScheduler())->daily()->withoutOverlapping(); |         $schedule->job(new TaskScheduler())->daily()->withoutOverlapping(); | ||||||
| 
 | 
 | ||||||
|  |         /* Performs system maintenance such as pruning the backup table */ | ||||||
|         $schedule->job(new SystemMaintenance)->weekly()->withoutOverlapping(); |         $schedule->job(new SystemMaintenance)->weekly()->withoutOverlapping(); | ||||||
| 
 | 
 | ||||||
|  |         /* Pulls in bank transactions from third party services */ | ||||||
|  |         $schedule->job(new BankTransactionSync)->dailyAt('04:00')->withoutOverlapping(); | ||||||
|  | 
 | ||||||
|         if (Ninja::isSelfHost()) { |         if (Ninja::isSelfHost()) { | ||||||
|  | 
 | ||||||
|             $schedule->call(function () { |             $schedule->call(function () { | ||||||
|                 Account::whereNotNull('id')->update(['is_scheduler_running' => true]); |                 Account::whereNotNull('id')->update(['is_scheduler_running' => true]); | ||||||
|             })->everyFiveMinutes(); |             })->everyFiveMinutes(); | ||||||
|  | 
 | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         /* Run hosted specific jobs */ |         /* Run hosted specific jobs */ | ||||||
|         if (Ninja::isHosted()) { |         if (Ninja::isHosted()) { | ||||||
|  | 
 | ||||||
|             $schedule->job(new AdjustEmailQuota)->dailyAt('23:30')->withoutOverlapping(); |             $schedule->job(new AdjustEmailQuota)->dailyAt('23:30')->withoutOverlapping(); | ||||||
| 
 | 
 | ||||||
|             $schedule->job(new SendFailedEmails)->daily()->withoutOverlapping(); |             $schedule->job(new SendFailedEmails)->daily()->withoutOverlapping(); | ||||||
| @ -85,12 +105,15 @@ class Kernel extends ConsoleKernel | |||||||
|             $schedule->command('ninja:check-data --database=db-ninja-02')->dailyAt('02:05')->withoutOverlapping(); |             $schedule->command('ninja:check-data --database=db-ninja-02')->dailyAt('02:05')->withoutOverlapping(); | ||||||
| 
 | 
 | ||||||
|             $schedule->command('ninja:s3-cleanup')->dailyAt('23:15')->withoutOverlapping(); |             $schedule->command('ninja:s3-cleanup')->dailyAt('23:15')->withoutOverlapping(); | ||||||
|  | 
 | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         if (config('queue.default') == 'database' && Ninja::isSelfHost() && config('ninja.internal_queue_enabled') && ! config('ninja.is_docker')) { |         if (config('queue.default') == 'database' && Ninja::isSelfHost() && config('ninja.internal_queue_enabled') && ! config('ninja.is_docker')) { | ||||||
|  | 
 | ||||||
|             $schedule->command('queue:work database --stop-when-empty --memory=256')->everyMinute()->withoutOverlapping(); |             $schedule->command('queue:work database --stop-when-empty --memory=256')->everyMinute()->withoutOverlapping(); | ||||||
| 
 | 
 | ||||||
|             $schedule->command('queue:restart')->everyFiveMinutes()->withoutOverlapping(); |             $schedule->command('queue:restart')->everyFiveMinutes()->withoutOverlapping(); | ||||||
|  |              | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -21,6 +21,7 @@ use Illuminate\Auth\Access\AuthorizationException; | |||||||
| use Illuminate\Auth\AuthenticationException; | use Illuminate\Auth\AuthenticationException; | ||||||
| use Illuminate\Database\Eloquent\ModelNotFoundException as ModelNotFoundException; | use Illuminate\Database\Eloquent\ModelNotFoundException as ModelNotFoundException; | ||||||
| use Illuminate\Database\Eloquent\RelationNotFoundException; | use Illuminate\Database\Eloquent\RelationNotFoundException; | ||||||
|  | use Illuminate\Database\QueryException; | ||||||
| use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler; | use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler; | ||||||
| use Illuminate\Http\Exceptions\ThrottleRequestsException; | use Illuminate\Http\Exceptions\ThrottleRequestsException; | ||||||
| use Illuminate\Http\Request; | use Illuminate\Http\Request; | ||||||
| @ -204,7 +205,11 @@ class Handler extends ExceptionHandler | |||||||
|             return response()->json(['message' => $exception->getMessage()], 400); |             return response()->json(['message' => $exception->getMessage()], 400); | ||||||
|         } elseif ($exception instanceof StripeConnectFailure) { |         } elseif ($exception instanceof StripeConnectFailure) { | ||||||
|             return response()->json(['message' => $exception->getMessage()], 400); |             return response()->json(['message' => $exception->getMessage()], 400); | ||||||
|         } |         } elseif ($exception instanceof QueryException) { | ||||||
|  |             return response()->json(['message' => 'We had a problem executing this query. Please retry.'], 500); | ||||||
|  |         }  | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
|         return parent::render($request, $exception); |         return parent::render($request, $exception); | ||||||
|     } |     } | ||||||
|  | |||||||
							
								
								
									
										41
									
								
								app/Exceptions/YodleeApiException.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								app/Exceptions/YodleeApiException.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,41 @@ | |||||||
|  | <?php | ||||||
|  | 
 | ||||||
|  | namespace App\Exceptions; | ||||||
|  | 
 | ||||||
|  | use Exception; | ||||||
|  | use Illuminate\Http\Request; | ||||||
|  | use Illuminate\Http\Response; | ||||||
|  | 
 | ||||||
|  | class YodleeApiException extends Exception | ||||||
|  | { | ||||||
|  |     /** | ||||||
|  |      * Report the exception. | ||||||
|  |      * | ||||||
|  |      * @return void | ||||||
|  |      */ | ||||||
|  |     public function report() | ||||||
|  |     { | ||||||
|  |         //
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Render the exception into an HTTP response. | ||||||
|  |      * | ||||||
|  |      * @param  Request  $request | ||||||
|  |      * @return Response | ||||||
|  |      */ | ||||||
|  |     public function render($request) | ||||||
|  |     { | ||||||
|  | 
 | ||||||
|  |         // $msg = 'Unable to refund the transaction';
 | ||||||
|  |         $msg = ctrans('texts.error'); | ||||||
|  | 
 | ||||||
|  |         if ($this->getMessage() && strlen($this->getMessage()) >= 1) { | ||||||
|  |             $msg = $this->getMessage(); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         return response()->json([ | ||||||
|  |             'message' => $msg, | ||||||
|  |         ], 400); | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										37
									
								
								app/Factory/BankIntegrationFactory.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								app/Factory/BankIntegrationFactory.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,37 @@ | |||||||
|  | <?php | ||||||
|  | /** | ||||||
|  |  * Invoice Ninja (https://invoiceninja.com). | ||||||
|  |  * | ||||||
|  |  * @link https://github.com/invoiceninja/invoiceninja source repository | ||||||
|  |  * | ||||||
|  |  * @copyright Copyright (c) 2022. Invoice Ninja LLC (https://invoiceninja.com) | ||||||
|  |  * | ||||||
|  |  * @license https://www.elastic.co/licensing/elastic-license | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | namespace App\Factory; | ||||||
|  | 
 | ||||||
|  | use App\Models\BankIntegration; | ||||||
|  | use Illuminate\Support\Str; | ||||||
|  | 
 | ||||||
|  | class BankIntegrationFactory | ||||||
|  | { | ||||||
|  |     public static function create(int $company_id, int $user_id, int $account_id) :BankIntegration | ||||||
|  |     { | ||||||
|  |         $bank_integration = new BankIntegration; | ||||||
|  |         $bank_integration->account_id = $account_id; | ||||||
|  |         $bank_integration->user_id = $user_id; | ||||||
|  |         $bank_integration->company_id = $company_id; | ||||||
|  | 
 | ||||||
|  |         $bank_integration->provider_name = ''; | ||||||
|  |         $bank_integration->bank_account_id = ''; | ||||||
|  |         $bank_integration->bank_account_name = ''; | ||||||
|  |         $bank_integration->bank_account_number = ''; | ||||||
|  |         $bank_integration->bank_account_status = ''; | ||||||
|  |         $bank_integration->bank_account_type = ''; | ||||||
|  |         $bank_integration->balance = 0; | ||||||
|  |         $bank_integration->currency = ''; | ||||||
|  |          | ||||||
|  |         return $bank_integration; | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										35
									
								
								app/Factory/BankTransactionFactory.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								app/Factory/BankTransactionFactory.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,35 @@ | |||||||
|  | <?php | ||||||
|  | /** | ||||||
|  |  * Invoice Ninja (https://invoiceninja.com). | ||||||
|  |  * | ||||||
|  |  * @link https://github.com/invoiceninja/invoiceninja source repository | ||||||
|  |  * | ||||||
|  |  * @copyright Copyright (c) 2022. Invoice Ninja LLC (https://invoiceninja.com) | ||||||
|  |  * | ||||||
|  |  * @license https://www.elastic.co/licensing/elastic-license | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | namespace App\Factory; | ||||||
|  | 
 | ||||||
|  | use App\Models\BankTransaction; | ||||||
|  | use Illuminate\Support\Str; | ||||||
|  | 
 | ||||||
|  | class BankTransactionFactory | ||||||
|  | { | ||||||
|  |     public static function create(int $company_id, int $user_id) :BankTransaction | ||||||
|  |     { | ||||||
|  |         $bank_transaction = new BankTransaction; | ||||||
|  |         $bank_transaction->user_id = $user_id; | ||||||
|  |         $bank_transaction->company_id = $company_id; | ||||||
|  | 
 | ||||||
|  |         $bank_transaction->amount = 0; | ||||||
|  |         $bank_transaction->currency_id = 1; | ||||||
|  |         $bank_transaction->account_type = ''; | ||||||
|  |         $bank_transaction->category_type = ''; | ||||||
|  |         $bank_transaction->date = now()->format('Y-m-d'); | ||||||
|  |         $bank_transaction->description = ''; | ||||||
|  |         $bank_transaction->status_id = 1; | ||||||
|  |          | ||||||
|  |         return $bank_transaction; | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										17
									
								
								app/Helpers/Bank/AccountTransformerInterface.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								app/Helpers/Bank/AccountTransformerInterface.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,17 @@ | |||||||
|  | <?php | ||||||
|  | /** | ||||||
|  |  * Invoice Ninja (https://invoiceninja.com). | ||||||
|  |  * | ||||||
|  |  * @link https://github.com/invoiceninja/invoiceninja source repository | ||||||
|  |  * | ||||||
|  |  * @copyright Copyright (c) 2022. Invoice Ninja LLC (https://invoiceninja.com) | ||||||
|  |  * | ||||||
|  |  * @license https://www.elastic.co/licensing/elastic-license | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | namespace App\Helpers\Bank; | ||||||
|  | 
 | ||||||
|  | interface AccountTransformerInterface | ||||||
|  | { | ||||||
|  |     public function transform($accounts);  | ||||||
|  | } | ||||||
							
								
								
									
										17
									
								
								app/Helpers/Bank/BankExpenseInterface.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								app/Helpers/Bank/BankExpenseInterface.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,17 @@ | |||||||
|  | <?php | ||||||
|  | /** | ||||||
|  |  * Invoice Ninja (https://invoiceninja.com). | ||||||
|  |  * | ||||||
|  |  * @link https://github.com/invoiceninja/invoiceninja source repository | ||||||
|  |  * | ||||||
|  |  * @copyright Copyright (c) 2022. Invoice Ninja LLC (https://invoiceninja.com) | ||||||
|  |  * | ||||||
|  |  * @license https://www.elastic.co/licensing/elastic-license | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | namespace App\Helpers\Bank; | ||||||
|  | 
 | ||||||
|  | interface BankExpenseInterface | ||||||
|  | { | ||||||
|  | 
 | ||||||
|  | } | ||||||
							
								
								
									
										17
									
								
								app/Helpers/Bank/BankRevenueInterface.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								app/Helpers/Bank/BankRevenueInterface.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,17 @@ | |||||||
|  | <?php | ||||||
|  | /** | ||||||
|  |  * Invoice Ninja (https://invoiceninja.com). | ||||||
|  |  * | ||||||
|  |  * @link https://github.com/invoiceninja/invoiceninja source repository | ||||||
|  |  * | ||||||
|  |  * @copyright Copyright (c) 2022. Invoice Ninja LLC (https://invoiceninja.com) | ||||||
|  |  * | ||||||
|  |  * @license https://www.elastic.co/licensing/elastic-license | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | namespace App\Helpers\Bank; | ||||||
|  | 
 | ||||||
|  | interface BankRevenueInterface | ||||||
|  | { | ||||||
|  |     public function transform($transaction); | ||||||
|  | } | ||||||
							
								
								
									
										103
									
								
								app/Helpers/Bank/Yodlee/Transformer/AccountTransformer.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										103
									
								
								app/Helpers/Bank/Yodlee/Transformer/AccountTransformer.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,103 @@ | |||||||
|  | <?php | ||||||
|  | /** | ||||||
|  |  * Invoice Ninja (https://invoiceninja.com). | ||||||
|  |  * | ||||||
|  |  * @link https://github.com/invoiceninja/invoiceninja source repository | ||||||
|  |  * | ||||||
|  |  * @copyright Copyright (c) 2022. Invoice Ninja LLC (https://invoiceninja.com) | ||||||
|  |  * | ||||||
|  |  * @license https://www.elastic.co/licensing/elastic-license | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | namespace App\Helpers\Bank\Yodlee\Transformer; | ||||||
|  | 
 | ||||||
|  | use App\Helpers\Bank\AccountTransformerInterface; | ||||||
|  |   | ||||||
|  | /** | ||||||
|  | [0] => stdClass Object | ||||||
|  | ( | ||||||
|  |     [CONTAINER] => bank | ||||||
|  |     [providerAccountId] => 11308693 | ||||||
|  |     [accountName] => My CD - 8878 | ||||||
|  |     [accountStatus] => ACTIVE | ||||||
|  |     [accountNumber] => xxxx8878 | ||||||
|  |     [aggregationSource] => USER | ||||||
|  |     [isAsset] => 1 | ||||||
|  |     [balance] => stdClass Object | ||||||
|  |         ( | ||||||
|  |             [currency] => USD | ||||||
|  |             [amount] => 49778.07 | ||||||
|  |         ) | ||||||
|  | 
 | ||||||
|  |     [id] => 12331861 | ||||||
|  |     [includeInNetWorth] => 1 | ||||||
|  |     [providerId] => 18769 | ||||||
|  |     [providerName] => Dag Site Captcha | ||||||
|  |     [isManual] =>  | ||||||
|  |     [currentBalance] => stdClass Object | ||||||
|  |         ( | ||||||
|  |             [currency] => USD | ||||||
|  |             [amount] => 49778.07 | ||||||
|  |         ) | ||||||
|  | 
 | ||||||
|  |     [accountType] => CD | ||||||
|  |     [displayedName] => LORETTA | ||||||
|  |     [createdDate] => 2022-07-28T06:55:33Z | ||||||
|  |     [lastUpdated] => 2022-07-28T06:56:09Z | ||||||
|  |     [dataset] => Array | ||||||
|  |         ( | ||||||
|  |             [0] => stdClass Object | ||||||
|  |                 ( | ||||||
|  |                     [name] => BASIC_AGG_DATA | ||||||
|  |                     [additionalStatus] => AVAILABLE_DATA_RETRIEVED | ||||||
|  |                     [updateEligibility] => ALLOW_UPDATE | ||||||
|  |                     [lastUpdated] => 2022-07-28T06:55:50Z | ||||||
|  |                     [lastUpdateAttempt] => 2022-07-28T06:55:50Z | ||||||
|  |                 ) | ||||||
|  | 
 | ||||||
|  |         ) | ||||||
|  | 
 | ||||||
|  | ) | ||||||
|  |     ) | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class AccountTransformer implements AccountTransformerInterface | ||||||
|  | { | ||||||
|  | 
 | ||||||
|  |     public function transform($yodlee_account) | ||||||
|  |     { | ||||||
|  | 
 | ||||||
|  |         $data = []; | ||||||
|  | 
 | ||||||
|  |         if(!property_exists($yodlee_account, 'account')) | ||||||
|  |             return $data; | ||||||
|  | 
 | ||||||
|  |         foreach($yodlee_account->account as $account) | ||||||
|  |         { | ||||||
|  |             $data[] = $this->transformAccount($account); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         return $data; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public function transformAccount($account) | ||||||
|  |     { | ||||||
|  |      | ||||||
|  |         return [ | ||||||
|  |             'id' => $account->id, | ||||||
|  |             'account_type' => $account->CONTAINER, | ||||||
|  |             'account_name' => $account->accountName, | ||||||
|  |             'account_status' => $account->accountStatus, | ||||||
|  |             'account_number' => $account->accountNumber, | ||||||
|  |             'provider_account_id' => $account->providerAccountId, | ||||||
|  |             'provider_id' => $account->providerId, | ||||||
|  |             'provider_name' => $account->providerName, | ||||||
|  |             'nickname' => property_exists($account, 'nickname') ? $account->nickname : '', | ||||||
|  |             'current_balance' => property_exists($account, 'currentBalance') ? $account->currentBalance->amount : 0, | ||||||
|  |             'account_currency' => property_exists($account, 'currency') ? $account->currentBalance->currency : '', | ||||||
|  |         ]; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
							
								
								
									
										80
									
								
								app/Helpers/Bank/Yodlee/Transformer/ExpenseTransformer.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										80
									
								
								app/Helpers/Bank/Yodlee/Transformer/ExpenseTransformer.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,80 @@ | |||||||
|  | <?php | ||||||
|  | /** | ||||||
|  |  * Invoice Ninja (https://invoiceninja.com). | ||||||
|  |  * | ||||||
|  |  * @link https://github.com/invoiceninja/invoiceninja source repository | ||||||
|  |  * | ||||||
|  |  * @copyright Copyright (c) 2022. Invoice Ninja LLC (https://invoiceninja.com) | ||||||
|  |  * | ||||||
|  |  * @license https://www.elastic.co/licensing/elastic-license | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | namespace App\Helpers\Bank\Yodlee\Transformer; | ||||||
|  |   | ||||||
|  | /** | ||||||
|  | "date": "string", | ||||||
|  | "sourceId": "string", | ||||||
|  | "symbol": "string", | ||||||
|  | "cusipNumber": "string", | ||||||
|  | "highLevelCategoryId": 0, | ||||||
|  | "detailCategoryId": 0, | ||||||
|  | "description": {}, | ||||||
|  | "memo": "string", | ||||||
|  | "settleDate": "string", | ||||||
|  | "type": "string", | ||||||
|  | "intermediary": [], | ||||||
|  | "baseType": "CREDIT", | ||||||
|  | "categorySource": "SYSTEM", | ||||||
|  | "principal": {}, | ||||||
|  | "lastUpdated": "string", | ||||||
|  | "interest": {}, | ||||||
|  | "price": {}, | ||||||
|  | "commission": {}, | ||||||
|  | "id": 0, | ||||||
|  | "merchantType": "string", | ||||||
|  | "amount": { | ||||||
|  | "amount": 0, | ||||||
|  | "convertedAmount": 0, | ||||||
|  | "currency": "USD", | ||||||
|  | "convertedCurrency": "USD" | ||||||
|  | }, | ||||||
|  | "checkNumber": "string", | ||||||
|  | "isPhysical": true, | ||||||
|  | "quantity": 0, | ||||||
|  | "valoren": "string", | ||||||
|  | "isManual": true, | ||||||
|  | "merchant": { | ||||||
|  | "website": "string", | ||||||
|  | "address": {}, | ||||||
|  | "contact": {}, | ||||||
|  | "categoryLabel": [], | ||||||
|  | "coordinates": {}, | ||||||
|  | "name": "string", | ||||||
|  | "id": "string", | ||||||
|  | "source": "YODLEE", | ||||||
|  | "logoURL": "string" | ||||||
|  | }, | ||||||
|  | "sedol": "string", | ||||||
|  | "transactionDate": "string", | ||||||
|  | "categoryType": "TRANSFER", | ||||||
|  | "accountId": 0, | ||||||
|  | "createdDate": "string", | ||||||
|  | "sourceType": "AGGREGATED", | ||||||
|  | "CONTAINER": "bank", | ||||||
|  | "postDate": "string", | ||||||
|  | "parentCategoryId": 0, | ||||||
|  | "subType": "OVERDRAFT_CHARGE", | ||||||
|  | "category": "string", | ||||||
|  | "runningBalance": {}, | ||||||
|  | "categoryId": 0, | ||||||
|  | "holdingDescription": "string", | ||||||
|  | "isin": "string", | ||||||
|  | "status": "POSTED" | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | class ExpenseTransformer | ||||||
|  | { | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
							
								
								
									
										187
									
								
								app/Helpers/Bank/Yodlee/Transformer/IncomeTransformer.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										187
									
								
								app/Helpers/Bank/Yodlee/Transformer/IncomeTransformer.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,187 @@ | |||||||
|  | <?php | ||||||
|  | /** | ||||||
|  |  * Invoice Ninja (https://invoiceninja.com). | ||||||
|  |  * | ||||||
|  |  * @link https://github.com/invoiceninja/invoiceninja source repository | ||||||
|  |  * | ||||||
|  |  * @copyright Copyright (c) 2022. Invoice Ninja LLC (https://invoiceninja.com) | ||||||
|  |  * | ||||||
|  |  * @license https://www.elastic.co/licensing/elastic-license | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | namespace App\Helpers\Bank\Yodlee\Transformer; | ||||||
|  | 
 | ||||||
|  | use App\Helpers\Bank\BankRevenueInterface; | ||||||
|  | use App\Utils\Traits\AppSetup; | ||||||
|  | use Illuminate\Support\Facades\Cache; | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  | "date": "string", | ||||||
|  | "sourceId": "string", | ||||||
|  | "symbol": "string", | ||||||
|  | "cusipNumber": "string", | ||||||
|  | "highLevelCategoryId": 0, | ||||||
|  | "detailCategoryId": 0, | ||||||
|  | "description": {}, | ||||||
|  | "memo": "string", | ||||||
|  | "settleDate": "string", | ||||||
|  | "type": "string", | ||||||
|  | "intermediary": [], | ||||||
|  | "baseType": "CREDIT", | ||||||
|  | "categorySource": "SYSTEM", | ||||||
|  | "principal": {}, | ||||||
|  | "lastUpdated": "string", | ||||||
|  | "interest": {}, | ||||||
|  | "price": {}, | ||||||
|  | "commission": {}, | ||||||
|  | "id": 0, | ||||||
|  | "merchantType": "string", | ||||||
|  | "amount": { | ||||||
|  | "amount": 0, | ||||||
|  | "convertedAmount": 0, | ||||||
|  | "currency": "USD", | ||||||
|  | "convertedCurrency": "USD" | ||||||
|  | }, | ||||||
|  | "checkNumber": "string", | ||||||
|  | "isPhysical": true, | ||||||
|  | "quantity": 0, | ||||||
|  | "valoren": "string", | ||||||
|  | "isManual": true, | ||||||
|  | "merchant": { | ||||||
|  | "website": "string", | ||||||
|  | "address": {}, | ||||||
|  | "contact": {}, | ||||||
|  | "categoryLabel": [], | ||||||
|  | "coordinates": {}, | ||||||
|  | "name": "string", | ||||||
|  | "id": "string", | ||||||
|  | "source": "YODLEE", | ||||||
|  | "logoURL": "string" | ||||||
|  | }, | ||||||
|  | "sedol": "string", | ||||||
|  | "transactionDate": "string", | ||||||
|  | "categoryType": "TRANSFER", | ||||||
|  | "accountId": 0, | ||||||
|  | "createdDate": "string", | ||||||
|  | "sourceType": "AGGREGATED", | ||||||
|  | "CONTAINER": "bank", | ||||||
|  | "postDate": "string", | ||||||
|  | "parentCategoryId": 0, | ||||||
|  | "subType": "OVERDRAFT_CHARGE", | ||||||
|  | "category": "string", | ||||||
|  | "runningBalance": {}, | ||||||
|  | "categoryId": 0, | ||||||
|  | "holdingDescription": "string", | ||||||
|  | "isin": "string", | ||||||
|  | "status": "POSTED" | ||||||
|  |   | ||||||
|  | ( | ||||||
|  | [CONTAINER] => bank | ||||||
|  | [id] => 103953585 | ||||||
|  | [amount] => stdClass Object | ||||||
|  |     ( | ||||||
|  |         [amount] => 480.66 | ||||||
|  |         [currency] => USD | ||||||
|  |     ) | ||||||
|  | 
 | ||||||
|  | [categoryType] => UNCATEGORIZE | ||||||
|  | [categoryId] => 1 | ||||||
|  | [category] => Uncategorized | ||||||
|  | [categorySource] => SYSTEM | ||||||
|  | [highLevelCategoryId] => 10000017 | ||||||
|  | [createdDate] => 2022-08-04T21:50:17Z | ||||||
|  | [lastUpdated] => 2022-08-04T21:50:17Z | ||||||
|  | [description] => stdClass Object | ||||||
|  |     ( | ||||||
|  |         [original] => CHEROKEE NATION TAX TA TAHLEQUAH OK | ||||||
|  |     ) | ||||||
|  | 
 | ||||||
|  | [isManual] =>  | ||||||
|  | [sourceType] => AGGREGATED | ||||||
|  | [date] => 2022-08-03 | ||||||
|  | [transactionDate] => 2022-08-03 | ||||||
|  | [postDate] => 2022-08-03 | ||||||
|  | [status] => POSTED | ||||||
|  | [accountId] => 12331794 | ||||||
|  | [runningBalance] => stdClass Object | ||||||
|  |     ( | ||||||
|  |         [amount] => 480.66 | ||||||
|  |         [currency] => USD | ||||||
|  |     ) | ||||||
|  | 
 | ||||||
|  | [checkNumber] => 998 | ||||||
|  | ) | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | class IncomeTransformer implements BankRevenueInterface | ||||||
|  | { | ||||||
|  |     use AppSetup; | ||||||
|  | 
 | ||||||
|  |     public function transform($transaction) | ||||||
|  |     { | ||||||
|  | 
 | ||||||
|  |         $data = []; | ||||||
|  | 
 | ||||||
|  |         if(!property_exists($transaction, 'transaction')) | ||||||
|  |             return $data; | ||||||
|  | 
 | ||||||
|  |         foreach($transaction->transaction as $transaction) | ||||||
|  |         { | ||||||
|  |             $data[] = $this->transformTransaction($transaction); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         return $data; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public function transformTransaction($transaction) | ||||||
|  |     { | ||||||
|  | 
 | ||||||
|  |         return [ | ||||||
|  |             'transaction_id' => $transaction->id, | ||||||
|  |             'amount' => $transaction->amount->amount, | ||||||
|  |             'currency_id' => $this->convertCurrency($transaction->amount->currency), | ||||||
|  |             'account_type' => $transaction->CONTAINER, | ||||||
|  |             'category_id' => $transaction->highLevelCategoryId, | ||||||
|  |             'category_type' => $transaction->categoryType, | ||||||
|  |             'date' => $transaction->date, | ||||||
|  |             'bank_account_id' => $transaction->accountId, | ||||||
|  |             'description' => $transaction->description->original, | ||||||
|  |             'base_type' => property_exists($transaction, 'baseType') ? $transaction->baseType : $this->calculateBaseType($transaction), | ||||||
|  |         ]; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private function calculateBaseType($transaction) | ||||||
|  |     { | ||||||
|  |         //CREDIT / DEBIT
 | ||||||
|  | 
 | ||||||
|  |         if(property_exists($transaction, 'highLevelCategoryId') && $transaction->highLevelCategoryId == 10000012) | ||||||
|  |             return 'CREDIT'; | ||||||
|  | 
 | ||||||
|  |         return 'DEBIT'; | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private function convertCurrency(string $code) | ||||||
|  |     { | ||||||
|  | 
 | ||||||
|  |         $currencies = Cache::get('currencies'); | ||||||
|  | 
 | ||||||
|  |         if (! $currencies) { | ||||||
|  |             $this->buildCache(true); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         $currency = $currencies->filter(function ($item) use($code){ | ||||||
|  |             return $item->code == $code; | ||||||
|  |         })->first(); | ||||||
|  | 
 | ||||||
|  |         if($currency) | ||||||
|  |             return $currency->id; | ||||||
|  | 
 | ||||||
|  |         return 1; | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
							
								
								
									
										284
									
								
								app/Helpers/Bank/Yodlee/Yodlee.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										284
									
								
								app/Helpers/Bank/Yodlee/Yodlee.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,284 @@ | |||||||
|  | <?php | ||||||
|  | /** | ||||||
|  |  * Invoice Ninja (https://invoiceninja.com). | ||||||
|  |  * | ||||||
|  |  * @link https://github.com/invoiceninja/invoiceninja source repository | ||||||
|  |  * | ||||||
|  |  * @copyright Copyright (c) 2022. Invoice Ninja LLC (https://invoiceninja.com) | ||||||
|  |  * | ||||||
|  |  * @license https://www.elastic.co/licensing/elastic-license | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | namespace App\Helpers\Bank\Yodlee; | ||||||
|  | 
 | ||||||
|  | use App\Exceptions\YodleeApiException; | ||||||
|  | use App\Helpers\Bank\Yodlee\Transformer\AccountTransformer; | ||||||
|  | use App\Helpers\Bank\Yodlee\Transformer\IncomeTransformer; | ||||||
|  | use Illuminate\Support\Facades\Http; | ||||||
|  | use Illuminate\Support\Str; | ||||||
|  |   | ||||||
|  | class Yodlee | ||||||
|  | { | ||||||
|  | 
 | ||||||
|  |     public bool $test_mode = false; | ||||||
|  | 
 | ||||||
|  |     private string $api_endpoint = 'https://production.api.yodlee.com/ysl'; | ||||||
|  | 
 | ||||||
|  |     private string $dev_api_endpoint = 'https://sandbox.api.yodlee.com/ysl'; | ||||||
|  |      | ||||||
|  |     private string $test_api_endpoint = 'https://development.api.yodlee.com/ysl'; | ||||||
|  | 
 | ||||||
|  |     public string $dev_fast_track_url = 'https://fl4.sandbox.yodlee.com/authenticate/restserver/fastlink'; | ||||||
|  | 
 | ||||||
|  |     public string $test_fast_track_url = 'https://fl4.preprod.yodlee.com/authenticate/USDevexPreProd3-449/fastlink?channelAppName=usdevexpreprod3'; | ||||||
|  | 
 | ||||||
|  |     public string $production_track_url = 'https://fl4.prod.yodlee.com/authenticate/USDevexProd3-331/fastlink?channelAppName=usdevexprod3'; | ||||||
|  | 
 | ||||||
|  |     protected string $client_id; | ||||||
|  | 
 | ||||||
|  |     protected string $client_secret; | ||||||
|  | 
 | ||||||
|  |     protected string $admin_name; | ||||||
|  | 
 | ||||||
|  |     protected ?string $bank_account_id; | ||||||
|  | 
 | ||||||
|  |     public function __construct(?string $bank_account_id = null) | ||||||
|  |     { | ||||||
|  | 
 | ||||||
|  |         $this->bank_account_id = $bank_account_id; | ||||||
|  | 
 | ||||||
|  |         $this->client_id = config('ninja.yodlee.client_id'); | ||||||
|  | 
 | ||||||
|  |         $this->client_secret = config('ninja.yodlee.client_secret'); | ||||||
|  | 
 | ||||||
|  |         $this->admin_name = config('ninja.yodlee.admin_name'); | ||||||
|  | 
 | ||||||
|  |         $this->test_mode = config('ninja.yodlee.test_mode'); | ||||||
|  | 
 | ||||||
|  |         config('ninja.yodlee.dev_mode') ? $this->setDevUrl() : null; | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public function getFastTrackUrl() | ||||||
|  |     { | ||||||
|  |         if(config('ninja.yodlee.dev_mode')) | ||||||
|  |             return $this->dev_fast_track_url; | ||||||
|  |          | ||||||
|  |         return $this->test_mode ? $this->test_fast_track_url : $this->production_track_url; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public function setTestMode() | ||||||
|  |     { | ||||||
|  |         $this->test_mode = true; | ||||||
|  | 
 | ||||||
|  |         return $this; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public function setDevUrl() | ||||||
|  |     { | ||||||
|  |         $this->test_api_endpoint = $this->dev_api_endpoint; | ||||||
|  | 
 | ||||||
|  |         $this->api_endpoint = $this->dev_api_endpoint; | ||||||
|  | 
 | ||||||
|  |         return $this; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public function getEndpoint() | ||||||
|  |     { | ||||||
|  |         return $this->test_mode ? $this->test_api_endpoint : $this->api_endpoint; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * If we do not pass in a user | ||||||
|  |      * we pass in the admin username instead | ||||||
|  |      */ | ||||||
|  |     public function getAccessToken($is_admin = false) | ||||||
|  |     { | ||||||
|  |         if($is_admin) | ||||||
|  |             $user = $this->admin_name; | ||||||
|  |         else | ||||||
|  |             $user = $this->bank_account_id ?: $this->admin_name; | ||||||
|  | 
 | ||||||
|  |         $response = $this->bankFormRequest('/auth/token', 'post', [],  ['loginName' => $user]); | ||||||
|  | 
 | ||||||
|  |         return $response->token->accessToken; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     public function createUser($company) | ||||||
|  |     { | ||||||
|  | 
 | ||||||
|  |         $token = $this->getAccessToken(true); | ||||||
|  | 
 | ||||||
|  |         $user['user'] = [ | ||||||
|  |             'loginName' => Str::uuid(), | ||||||
|  |         ]; | ||||||
|  | 
 | ||||||
|  | /* | ||||||
|  | { | ||||||
|  |   "user": { | ||||||
|  |     "preferences": { | ||||||
|  |       "dateFormat": "string", | ||||||
|  |       "timeZone": "string", | ||||||
|  |       "currency": "USD", | ||||||
|  |       "locale": "en_US" | ||||||
|  |     }, | ||||||
|  |     "address": { | ||||||
|  |       "zip": "string", | ||||||
|  |       "country": "string", | ||||||
|  |       "address3": "string", | ||||||
|  |       "address2": "string", | ||||||
|  |       "city": "string", | ||||||
|  |       "address1": "string", | ||||||
|  |       "state": "string" | ||||||
|  |     }, | ||||||
|  |     "loginName": "string", | ||||||
|  |     "name": { | ||||||
|  |       "middle": "string", | ||||||
|  |       "last": "string", | ||||||
|  |       "fullName": "string", | ||||||
|  |       "first": "string" | ||||||
|  |     }, | ||||||
|  |     "email": "string", | ||||||
|  |     "segmentName": "string" | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  |         $response = Http::withHeaders($this->getHeaders(["Authorization" => "Bearer {$token}"]))->post($this->getEndpoint(). "/user/register", $user); | ||||||
|  | 
 | ||||||
|  |         if($response->successful()) | ||||||
|  |             return $response->object(); | ||||||
|  | 
 | ||||||
|  |         if($response->failed()) | ||||||
|  |             throw new YodleeApiException($response->body()); | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public function getAccounts($params = []) | ||||||
|  |     { | ||||||
|  | 
 | ||||||
|  |         $token = $this->getAccessToken(); | ||||||
|  | 
 | ||||||
|  |         $response = Http::withHeaders($this->getHeaders(["Authorization" => "Bearer {$token}"]))->get($this->getEndpoint(). "/accounts", $params); | ||||||
|  | 
 | ||||||
|  |         if($response->successful()){ | ||||||
|  | 
 | ||||||
|  |             $at = new AccountTransformer(); | ||||||
|  |             return $at->transform($response->object()); | ||||||
|  | 
 | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         if($response->failed()) | ||||||
|  |             throw new YodleeApiException($response->body()); | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public function deleteAccount($account_id) | ||||||
|  |     { | ||||||
|  | 
 | ||||||
|  |         $token = $this->getAccessToken(); | ||||||
|  | 
 | ||||||
|  |         $response = Http::withHeaders($this->getHeaders(["Authorization" => "Bearer {$token}"]))->delete($this->getEndpoint(). "/accounts/{$account_id}", []); | ||||||
|  | 
 | ||||||
|  |         if($response->successful()){ | ||||||
|  | 
 | ||||||
|  |             return true; | ||||||
|  | 
 | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         if($response->failed()) | ||||||
|  |             throw new YodleeApiException($response->body()); | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     public function getTransactions($params = []) | ||||||
|  |     { | ||||||
|  |         $token = $this->getAccessToken(); | ||||||
|  |   | ||||||
|  |         $response = Http::withHeaders($this->getHeaders(["Authorization" => "Bearer {$token}"]))->get($this->getEndpoint(). "/transactions", $params); | ||||||
|  | 
 | ||||||
|  |         if($response->successful()){ | ||||||
|  |             // return $response->object();
 | ||||||
|  |             $it = new IncomeTransformer(); | ||||||
|  |             return $it->transform($response->object()); | ||||||
|  | 
 | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         if($response->failed()) | ||||||
|  |             throw new YodleeApiException($response->body()); | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public function getTransactionCount($params = []) | ||||||
|  |     { | ||||||
|  |         $token = $this->getAccessToken(); | ||||||
|  |   | ||||||
|  |         $response = Http::withHeaders($this->getHeaders(["Authorization" => "Bearer {$token}"]))->get($this->getEndpoint(). "/transactions/count", $params); | ||||||
|  | 
 | ||||||
|  |         if($response->successful()){ | ||||||
|  | 
 | ||||||
|  |             return $response->object(); | ||||||
|  | 
 | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         if($response->failed()) | ||||||
|  |             throw new YodleeApiException($response->body()); | ||||||
|  | 
 | ||||||
|  |     }     | ||||||
|  | 
 | ||||||
|  |     public function getTransactionCategories($params = []) | ||||||
|  |     { | ||||||
|  |         $token = $this->getAccessToken(); | ||||||
|  | 
 | ||||||
|  |         $response = Http::withHeaders($this->getHeaders(["Authorization" => "Bearer {$token}"]))->get($this->getEndpoint(). "/transactions/categories", $params); | ||||||
|  | 
 | ||||||
|  |         if($response->successful()) | ||||||
|  |             return $response->object(); | ||||||
|  | 
 | ||||||
|  |         if($response->failed()) | ||||||
|  |             throw new YodleeApiException($response->body()); | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private function bankFormRequest(string $uri, string $verb, array $data, array $headers) | ||||||
|  |     { | ||||||
|  | 
 | ||||||
|  |         $response = Http::withHeaders($this->getFormHeaders($headers))->asForm()->{$verb}($this->getEndpoint() . $uri, $this->buildBody()); | ||||||
|  | 
 | ||||||
|  |         if($response->successful()) | ||||||
|  |             return $response->object(); | ||||||
|  | 
 | ||||||
|  |         if($response->failed()) | ||||||
|  |             throw new YodleeApiException($response->body()); | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private function getHeaders($data = []) | ||||||
|  |     { | ||||||
|  |         return array_merge($data, [ | ||||||
|  |             'Api-Version' => '1.1', | ||||||
|  |             'ContentType' => 'application/json' | ||||||
|  |         ]); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     private function getFormHeaders($data = []) | ||||||
|  |     { | ||||||
|  |         return array_merge($data, [ | ||||||
|  |             'Api-Version' => '1.1', | ||||||
|  |         ]); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private function buildBody() | ||||||
|  |     { | ||||||
|  | 
 | ||||||
|  |         return [ | ||||||
|  |             'clientId' => $this->client_id, | ||||||
|  |             'secret' => $this->client_secret, | ||||||
|  |         ]; | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } | ||||||
							
								
								
									
										118
									
								
								app/Http/Controllers/Bank/YodleeController.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										118
									
								
								app/Http/Controllers/Bank/YodleeController.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,118 @@ | |||||||
|  | <?php | ||||||
|  | /** | ||||||
|  |  * Invoice Ninja (https://invoiceninja.com). | ||||||
|  |  * | ||||||
|  |  * @link https://github.com/invoiceninja/invoiceninja source repository | ||||||
|  |  * | ||||||
|  |  * @copyright Copyright (c) 2022. Invoice Ninja LLC (https://invoiceninja.com) | ||||||
|  |  * | ||||||
|  |  * @license https://www.elastic.co/licensing/elastic-license | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | namespace App\Http\Controllers\Bank; | ||||||
|  | 
 | ||||||
|  | use App\Helpers\Bank\Yodlee\Yodlee; | ||||||
|  | use App\Http\Controllers\BaseController; | ||||||
|  | use App\Http\Requests\Yodlee\YodleeAuthRequest; | ||||||
|  | use App\Jobs\Bank\ProcessBankTransactions; | ||||||
|  | use App\Models\BankIntegration; | ||||||
|  | use Illuminate\Http\Request; | ||||||
|  | 
 | ||||||
|  | class YodleeController extends BaseController | ||||||
|  | { | ||||||
|  | 
 | ||||||
|  |     public function auth(YodleeAuthRequest $request) | ||||||
|  |     { | ||||||
|  | 
 | ||||||
|  |         // create a user at this point 
 | ||||||
|  |         // use the one time token here to pull in the actual user
 | ||||||
|  |         // store the user_account_id on the accounts table
 | ||||||
|  | 
 | ||||||
|  |         $yodlee = new Yodlee(); | ||||||
|  | 
 | ||||||
|  |         $company = $request->getCompany(); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |         if($company->account->bank_integration_account_id){ | ||||||
|  | 
 | ||||||
|  |             $flow = 'edit'; | ||||||
|  | 
 | ||||||
|  |             $token = $company->account->bank_integration_account_id; | ||||||
|  | 
 | ||||||
|  |         } | ||||||
|  |         else{ | ||||||
|  | 
 | ||||||
|  |             $flow = 'add'; | ||||||
|  | 
 | ||||||
|  |             $response = $yodlee->createUser($company); | ||||||
|  | 
 | ||||||
|  |             $token = $response->user->loginName; | ||||||
|  | 
 | ||||||
|  |             $company->account->bank_integration_account_id = $token; | ||||||
|  | 
 | ||||||
|  |             $company->push(); | ||||||
|  |              | ||||||
|  |         } | ||||||
|  |          | ||||||
|  |         $yodlee = new Yodlee($token); | ||||||
|  | 
 | ||||||
|  |         if($request->has('window_closed') && $request->input("window_closed") == "true") | ||||||
|  |             $this->getAccounts($company, $token); | ||||||
|  | 
 | ||||||
|  |         $data = [ | ||||||
|  |             'access_token' => $yodlee->getAccessToken(), | ||||||
|  |             'fasttrack_url' => $yodlee->getFastTrackUrl(), | ||||||
|  |             'config_name' => config('ninja.yodlee.config_name'), | ||||||
|  |             'flow' => $flow, | ||||||
|  |             'company' => $company, | ||||||
|  |             'account' => $company->account, | ||||||
|  |             'completed' => $request->has('window_closed') ? true : false, | ||||||
|  |         ]; | ||||||
|  | 
 | ||||||
|  |         return view('bank.yodlee.auth', $data); | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private function getAccounts($company, $token) | ||||||
|  |     { | ||||||
|  |         $yodlee = new Yodlee($token); | ||||||
|  | 
 | ||||||
|  |         $accounts = $yodlee->getAccounts();  | ||||||
|  | 
 | ||||||
|  |         foreach($accounts as $account) | ||||||
|  |         { | ||||||
|  | 
 | ||||||
|  |             if(!BankIntegration::where('bank_account_id', $account['id'])->where('company_id', $company->id)->exists()) | ||||||
|  |             { | ||||||
|  |                 $bank_integration = new BankIntegration(); | ||||||
|  |                 $bank_integration->company_id = $company->id; | ||||||
|  |                 $bank_integration->account_id = $company->account_id; | ||||||
|  |                 $bank_integration->user_id = $company->owner()->id; | ||||||
|  |                 $bank_integration->bank_account_id = $account['id']; | ||||||
|  |                 $bank_integration->bank_account_type = $account['account_type']; | ||||||
|  |                 $bank_integration->bank_account_name = $account['account_name']; | ||||||
|  |                 $bank_integration->bank_account_status = $account['account_status']; | ||||||
|  |                 $bank_integration->bank_account_number = $account['account_number']; | ||||||
|  |                 $bank_integration->provider_id = $account['provider_id']; | ||||||
|  |                 $bank_integration->provider_name = $account['provider_name']; | ||||||
|  |                 $bank_integration->nickname = $account['nickname']; | ||||||
|  |                 $bank_integration->balance = $account['current_balance']; | ||||||
|  |                 $bank_integration->currency = $account['account_currency']; | ||||||
|  |                 $bank_integration->from_date = now()->subYear(); | ||||||
|  |                  | ||||||
|  |                 $bank_integration->save(); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |         $company->account->bank_integrations->each(function ($bank_integration) use ($company){ | ||||||
|  |              | ||||||
|  |             ProcessBankTransactions::dispatch($company->account->bank_integration_account_id, $bank_integration); | ||||||
|  | 
 | ||||||
|  |         }); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } | ||||||
							
								
								
									
										683
									
								
								app/Http/Controllers/BankIntegrationController.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										683
									
								
								app/Http/Controllers/BankIntegrationController.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,683 @@ | |||||||
|  | <?php | ||||||
|  | /** | ||||||
|  |  * Invoice Ninja (https://invoiceninja.com). | ||||||
|  |  * | ||||||
|  |  * @link https://github.com/invoiceninja/invoiceninja source repository | ||||||
|  |  * | ||||||
|  |  * @copyright Copyright (c) 2022. Invoice Ninja LLC (https://invoiceninja.com) | ||||||
|  |  * | ||||||
|  |  * @license https://www.elastic.co/licensing/elastic-license | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | namespace App\Http\Controllers; | ||||||
|  | 
 | ||||||
|  | use App\Factory\BankIntegrationFactory; | ||||||
|  | use App\Helpers\Bank\Yodlee\Yodlee; | ||||||
|  | use App\Http\Requests\BankIntegration\AdminBankIntegrationRequest; | ||||||
|  | use App\Http\Requests\BankIntegration\CreateBankIntegrationRequest; | ||||||
|  | use App\Http\Requests\BankIntegration\DestroyBankIntegrationRequest; | ||||||
|  | use App\Http\Requests\BankIntegration\EditBankIntegrationRequest; | ||||||
|  | use App\Http\Requests\BankIntegration\ShowBankIntegrationRequest; | ||||||
|  | use App\Http\Requests\BankIntegration\StoreBankIntegrationRequest; | ||||||
|  | use App\Http\Requests\BankIntegration\UpdateBankIntegrationRequest; | ||||||
|  | use App\Jobs\Bank\ProcessBankTransactions; | ||||||
|  | use App\Models\BankIntegration; | ||||||
|  | use App\Repositories\BankIntegrationRepository; | ||||||
|  | use App\Services\Bank\BankService; | ||||||
|  | use App\Transformers\BankIntegrationTransformer; | ||||||
|  | use App\Utils\Traits\MakesHash; | ||||||
|  | use Illuminate\Http\Request; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class BankIntegrationController extends BaseController | ||||||
|  | { | ||||||
|  |     use MakesHash; | ||||||
|  | 
 | ||||||
|  |     protected $entity_type = BankIntegration::class; | ||||||
|  | 
 | ||||||
|  |     protected $entity_transformer = BankIntegrationTransformer::class; | ||||||
|  | 
 | ||||||
|  |     protected $bank_integration_repo; | ||||||
|  | 
 | ||||||
|  |     public function __construct(BankIntegrationRepository $bank_integration_repo) | ||||||
|  |     { | ||||||
|  |         parent::__construct(); | ||||||
|  | 
 | ||||||
|  |         $this->bank_integration_repo = $bank_integration_repo; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * @OA\Get( | ||||||
|  |      *      path="/api/v1/bank_integrations", | ||||||
|  |      *      operationId="getBankIntegrations", | ||||||
|  |      *      tags={"bank_integrations"}, | ||||||
|  |      *      summary="Gets a list of bank_integrations", | ||||||
|  |      *      description="Lists all bank integrations", | ||||||
|  |      *      @OA\Parameter(ref="#/components/parameters/X-Api-Secret"), | ||||||
|  |      *      @OA\Parameter(ref="#/components/parameters/X-Api-Token"), | ||||||
|  |      *      @OA\Parameter(ref="#/components/parameters/X-Requested-With"), | ||||||
|  |      *      @OA\Parameter(ref="#/components/parameters/include"), | ||||||
|  |      *      @OA\Parameter(ref="#/components/parameters/index"), | ||||||
|  |      *      @OA\Parameter( | ||||||
|  |      *          name="rows", | ||||||
|  |      *          in="query", | ||||||
|  |      *          description="The number of bank integrations to return", | ||||||
|  |      *          example="50", | ||||||
|  |      *          required=false, | ||||||
|  |      *          @OA\Schema( | ||||||
|  |      *              type="number", | ||||||
|  |      *              format="integer", | ||||||
|  |      *          ), | ||||||
|  |      *      ), | ||||||
|  |      *      @OA\Response( | ||||||
|  |      *          response=200, | ||||||
|  |      *          description="A list of bank integrations", | ||||||
|  |      *          @OA\Header(header="X-MINIMUM-CLIENT-VERSION", ref="#/components/headers/X-MINIMUM-CLIENT-VERSION"), | ||||||
|  |      *          @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"), | ||||||
|  |      *          @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"), | ||||||
|  |      *          @OA\JsonContent(ref="#/components/schemas/BankIntegration"), | ||||||
|  |      *       ), | ||||||
|  |      *       @OA\Response( | ||||||
|  |      *          response=422, | ||||||
|  |      *          description="Validation error", | ||||||
|  |      *          @OA\JsonContent(ref="#/components/schemas/ValidationError"), | ||||||
|  |      *       ), | ||||||
|  |      *       @OA\Response( | ||||||
|  |      *           response="default", | ||||||
|  |      *           description="Unexpected Error", | ||||||
|  |      *           @OA\JsonContent(ref="#/components/schemas/Error"), | ||||||
|  |      *       ), | ||||||
|  |      *     ) | ||||||
|  |      * @param Request $request | ||||||
|  |      * @return Response|mixed | ||||||
|  |      */ | ||||||
|  |     public function index(Request $request) | ||||||
|  |     { | ||||||
|  | 
 | ||||||
|  |         $bank_integrations = BankIntegration::query()->company(); | ||||||
|  | 
 | ||||||
|  |         return $this->listResponse($bank_integrations); | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Display the specified resource. | ||||||
|  |      * | ||||||
|  |      * @param ShowBankIntegrationRequest $request | ||||||
|  |      * @param BankIntegration $bank_integration | ||||||
|  |      * @return Response | ||||||
|  |      * | ||||||
|  |      * | ||||||
|  |      * @OA\Get( | ||||||
|  |      *      path="/api/v1/bank_integrations/{id}", | ||||||
|  |      *      operationId="showBankIntegration", | ||||||
|  |      *      tags={"bank_integrations"}, | ||||||
|  |      *      summary="Shows a bank_integration", | ||||||
|  |      *      description="Displays a bank_integration by id", | ||||||
|  |      *      @OA\Parameter(ref="#/components/parameters/X-Api-Secret"), | ||||||
|  |      *      @OA\Parameter(ref="#/components/parameters/X-Api-Token"), | ||||||
|  |      *      @OA\Parameter(ref="#/components/parameters/X-Requested-With"), | ||||||
|  |      *      @OA\Parameter(ref="#/components/parameters/include"), | ||||||
|  |      *      @OA\Parameter( | ||||||
|  |      *          name="id", | ||||||
|  |      *          in="path", | ||||||
|  |      *          description="The BankIntegration Hashed ID", | ||||||
|  |      *          example="D2J234DFA", | ||||||
|  |      *          required=true, | ||||||
|  |      *          @OA\Schema( | ||||||
|  |      *              type="string", | ||||||
|  |      *              format="string", | ||||||
|  |      *          ), | ||||||
|  |      *      ), | ||||||
|  |      *      @OA\Response( | ||||||
|  |      *          response=200, | ||||||
|  |      *          description="Returns the bank_integration object", | ||||||
|  |      *          @OA\Header(header="X-MINIMUM-CLIENT-VERSION", ref="#/components/headers/X-MINIMUM-CLIENT-VERSION"), | ||||||
|  |      *          @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"), | ||||||
|  |      *          @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"), | ||||||
|  |      *          @OA\JsonContent(ref="#/components/schemas/BankIntegration"), | ||||||
|  |      *       ), | ||||||
|  |      *       @OA\Response( | ||||||
|  |      *          response=422, | ||||||
|  |      *          description="Validation error", | ||||||
|  |      *          @OA\JsonContent(ref="#/components/schemas/ValidationError"), | ||||||
|  |      * | ||||||
|  |      *       ), | ||||||
|  |      *       @OA\Response( | ||||||
|  |      *           response="default", | ||||||
|  |      *           description="Unexpected Error", | ||||||
|  |      *           @OA\JsonContent(ref="#/components/schemas/Error"), | ||||||
|  |      *       ), | ||||||
|  |      *     ) | ||||||
|  |      */ | ||||||
|  |     public function show(ShowBankIntegrationRequest $request, BankIntegration $bank_integration) | ||||||
|  |     { | ||||||
|  |         return $this->itemResponse($bank_integration); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Show the form for editing the specified resource. | ||||||
|  |      * | ||||||
|  |      * @param EditBankIntegrationRequest $request | ||||||
|  |      * @param BankIntegration $bank_integration | ||||||
|  |      * @return Response | ||||||
|  |      * | ||||||
|  |      * | ||||||
|  |      * @OA\Get( | ||||||
|  |      *      path="/api/v1/bank_integrations/{id}/edit", | ||||||
|  |      *      operationId="editBankIntegration", | ||||||
|  |      *      tags={"bank_integrations"}, | ||||||
|  |      *      summary="Shows a bank_integration for editing", | ||||||
|  |      *      description="Displays a bank_integration by id", | ||||||
|  |      *      @OA\Parameter(ref="#/components/parameters/X-Api-Secret"), | ||||||
|  |      *      @OA\Parameter(ref="#/components/parameters/X-Api-Token"), | ||||||
|  |      *      @OA\Parameter(ref="#/components/parameters/X-Requested-With"), | ||||||
|  |      *      @OA\Parameter(ref="#/components/parameters/include"), | ||||||
|  |      *      @OA\Parameter( | ||||||
|  |      *          name="id", | ||||||
|  |      *          in="path", | ||||||
|  |      *          description="The BankIntegration Hashed ID", | ||||||
|  |      *          example="D2J234DFA", | ||||||
|  |      *          required=true, | ||||||
|  |      *          @OA\Schema( | ||||||
|  |      *              type="string", | ||||||
|  |      *              format="string", | ||||||
|  |      *          ), | ||||||
|  |      *      ), | ||||||
|  |      *      @OA\Response( | ||||||
|  |      *          response=200, | ||||||
|  |      *          description="Returns the bank_integration object", | ||||||
|  |      *          @OA\Header(header="X-MINIMUM-CLIENT-VERSION", ref="#/components/headers/X-MINIMUM-CLIENT-VERSION"), | ||||||
|  |      *          @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"), | ||||||
|  |      *          @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"), | ||||||
|  |      *          @OA\JsonContent(ref="#/components/schemas/BankIntegration"), | ||||||
|  |      *       ), | ||||||
|  |      *       @OA\Response( | ||||||
|  |      *          response=422, | ||||||
|  |      *          description="Validation error", | ||||||
|  |      *          @OA\JsonContent(ref="#/components/schemas/ValidationError"), | ||||||
|  |      * | ||||||
|  |      *       ), | ||||||
|  |      *       @OA\Response( | ||||||
|  |      *           response="default", | ||||||
|  |      *           description="Unexpected Error", | ||||||
|  |      *           @OA\JsonContent(ref="#/components/schemas/Error"), | ||||||
|  |      *       ), | ||||||
|  |      *     ) | ||||||
|  |      */ | ||||||
|  |     public function edit(EditBankIntegrationRequest $request, BankIntegration $bank_integration) | ||||||
|  |     { | ||||||
|  |         return $this->itemResponse($bank_integration); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Update the specified resource in storage. | ||||||
|  |      * | ||||||
|  |      * @param UpdateBankIntegrationRequest $request | ||||||
|  |      * @param BankIntegration $bank_integration | ||||||
|  |      * @return Response | ||||||
|  |      * | ||||||
|  |      * | ||||||
|  |      * | ||||||
|  |      * @OA\Put( | ||||||
|  |      *      path="/api/v1/bank_integrations/{id}", | ||||||
|  |      *      operationId="updateBankIntegration", | ||||||
|  |      *      tags={"bank_integrations"}, | ||||||
|  |      *      summary="Updates a bank_integration", | ||||||
|  |      *      description="Handles the updating of a bank_integration by id", | ||||||
|  |      *      @OA\Parameter(ref="#/components/parameters/X-Api-Secret"), | ||||||
|  |      *      @OA\Parameter(ref="#/components/parameters/X-Api-Token"), | ||||||
|  |      *      @OA\Parameter(ref="#/components/parameters/X-Requested-With"), | ||||||
|  |      *      @OA\Parameter(ref="#/components/parameters/include"), | ||||||
|  |      *      @OA\Parameter( | ||||||
|  |      *          name="id", | ||||||
|  |      *          in="path", | ||||||
|  |      *          description="The BankIntegration Hashed ID", | ||||||
|  |      *          example="D2J234DFA", | ||||||
|  |      *          required=true, | ||||||
|  |      *          @OA\Schema( | ||||||
|  |      *              type="string", | ||||||
|  |      *              format="string", | ||||||
|  |      *          ), | ||||||
|  |      *      ), | ||||||
|  |      *      @OA\Response( | ||||||
|  |      *          response=200, | ||||||
|  |      *          description="Returns the bank_integration object", | ||||||
|  |      *          @OA\Header(header="X-MINIMUM-CLIENT-VERSION", ref="#/components/headers/X-MINIMUM-CLIENT-VERSION"), | ||||||
|  |      *          @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"), | ||||||
|  |      *          @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"), | ||||||
|  |      *          @OA\JsonContent(ref="#/components/schemas/BankIntegration"), | ||||||
|  |      *       ), | ||||||
|  |      *       @OA\Response( | ||||||
|  |      *          response=422, | ||||||
|  |      *          description="Validation error", | ||||||
|  |      *          @OA\JsonContent(ref="#/components/schemas/ValidationError"), | ||||||
|  |      * | ||||||
|  |      *       ), | ||||||
|  |      *       @OA\Response( | ||||||
|  |      *           response="default", | ||||||
|  |      *           description="Unexpected Error", | ||||||
|  |      *           @OA\JsonContent(ref="#/components/schemas/Error"), | ||||||
|  |      *       ), | ||||||
|  |      *     ) | ||||||
|  |      */ | ||||||
|  |     public function update(UpdateBankIntegrationRequest $request, BankIntegration $bank_integration) | ||||||
|  |     { | ||||||
|  | 
 | ||||||
|  |         //stubs for updating the model
 | ||||||
|  |         $bank_integration = $this->bank_integration_repo->save($request->all(), $bank_integration); | ||||||
|  | 
 | ||||||
|  |         return $this->itemResponse($bank_integration->fresh()); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Show the form for creating a new resource. | ||||||
|  |      * | ||||||
|  |      * @param CreateBankIntegrationRequest $request | ||||||
|  |      * @return Response | ||||||
|  |      * | ||||||
|  |      * | ||||||
|  |      * | ||||||
|  |      * @OA\Get( | ||||||
|  |      *      path="/api/v1/bank_integrations/create", | ||||||
|  |      *      operationId="getBankIntegrationsCreate", | ||||||
|  |      *      tags={"bank_integrations"}, | ||||||
|  |      *      summary="Gets a new blank bank_integration object", | ||||||
|  |      *      description="Returns a blank object with default values", | ||||||
|  |      *      @OA\Parameter(ref="#/components/parameters/X-Api-Secret"), | ||||||
|  |      *      @OA\Parameter(ref="#/components/parameters/X-Api-Token"), | ||||||
|  |      *      @OA\Parameter(ref="#/components/parameters/X-Requested-With"), | ||||||
|  |      *      @OA\Parameter(ref="#/components/parameters/include"), | ||||||
|  |      *      @OA\Response( | ||||||
|  |      *          response=200, | ||||||
|  |      *          description="A blank bank_integration object", | ||||||
|  |      *          @OA\Header(header="X-MINIMUM-CLIENT-VERSION", ref="#/components/headers/X-MINIMUM-CLIENT-VERSION"), | ||||||
|  |      *          @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"), | ||||||
|  |      *          @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"), | ||||||
|  |      *          @OA\JsonContent(ref="#/components/schemas/BankIntegration"), | ||||||
|  |      *       ), | ||||||
|  |      *       @OA\Response( | ||||||
|  |      *          response=422, | ||||||
|  |      *          description="Validation error", | ||||||
|  |      *          @OA\JsonContent(ref="#/components/schemas/ValidationError"), | ||||||
|  |      * | ||||||
|  |      *       ), | ||||||
|  |      *       @OA\Response( | ||||||
|  |      *           response="default", | ||||||
|  |      *           description="Unexpected Error", | ||||||
|  |      *           @OA\JsonContent(ref="#/components/schemas/Error"), | ||||||
|  |      *       ), | ||||||
|  |      *     ) | ||||||
|  |      */ | ||||||
|  |     public function create(CreateBankIntegrationRequest $request) | ||||||
|  |     { | ||||||
|  |         $bank_integration = BankIntegrationFactory::create(auth()->user()->company()->id, auth()->user()->id, auth()->user()->account_id); | ||||||
|  | 
 | ||||||
|  |         return $this->itemResponse($bank_integration); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Store a newly created resource in storage. | ||||||
|  |      * | ||||||
|  |      * @param StoreBankIntegrationRequest $request | ||||||
|  |      * @return Response | ||||||
|  |      * | ||||||
|  |      * | ||||||
|  |      * | ||||||
|  |      * @OA\Post( | ||||||
|  |      *      path="/api/v1/bank_integrations", | ||||||
|  |      *      operationId="storeBankIntegration", | ||||||
|  |      *      tags={"bank_integrations"}, | ||||||
|  |      *      summary="Adds a bank_integration", | ||||||
|  |      *      description="Adds an bank_integration to a company", | ||||||
|  |      *      @OA\Parameter(ref="#/components/parameters/X-Api-Secret"), | ||||||
|  |      *      @OA\Parameter(ref="#/components/parameters/X-Api-Token"), | ||||||
|  |      *      @OA\Parameter(ref="#/components/parameters/X-Requested-With"), | ||||||
|  |      *      @OA\Parameter(ref="#/components/parameters/include"), | ||||||
|  |      *      @OA\Response( | ||||||
|  |      *          response=200, | ||||||
|  |      *          description="Returns the saved bank_integration object", | ||||||
|  |      *          @OA\Header(header="X-MINIMUM-CLIENT-VERSION", ref="#/components/headers/X-MINIMUM-CLIENT-VERSION"), | ||||||
|  |      *          @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"), | ||||||
|  |      *          @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"), | ||||||
|  |      *          @OA\JsonContent(ref="#/components/schemas/BankIntegration"), | ||||||
|  |      *       ), | ||||||
|  |      *       @OA\Response( | ||||||
|  |      *          response=422, | ||||||
|  |      *          description="Validation error", | ||||||
|  |      *          @OA\JsonContent(ref="#/components/schemas/ValidationError"), | ||||||
|  |      * | ||||||
|  |      *       ), | ||||||
|  |      *       @OA\Response( | ||||||
|  |      *           response="default", | ||||||
|  |      *           description="Unexpected Error", | ||||||
|  |      *           @OA\JsonContent(ref="#/components/schemas/Error"), | ||||||
|  |      *       ), | ||||||
|  |      *     ) | ||||||
|  |      */ | ||||||
|  |     public function store(StoreBankIntegrationRequest $request) | ||||||
|  |     { | ||||||
|  |         //stub to store the model
 | ||||||
|  |         $bank_integration = $this->bank_integration_repo->save($request->all(), BankIntegrationFactory::create(auth()->user()->company()->id, auth()->user()->id, auth()->user()->account_id)); | ||||||
|  | 
 | ||||||
|  |         return $this->itemResponse($bank_integration); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Remove the specified resource from storage. | ||||||
|  |      * | ||||||
|  |      * @param DestroyBankIntegrationRequest $request | ||||||
|  |      * @param BankIntegration $bank_integration | ||||||
|  |      * @return Response | ||||||
|  |      * | ||||||
|  |      * | ||||||
|  |      * @throws \Exception | ||||||
|  |      * @OA\Delete( | ||||||
|  |      *      path="/api/v1/bank_integrations/{id}", | ||||||
|  |      *      operationId="deleteBankIntegration", | ||||||
|  |      *      tags={"bank_integrations"}, | ||||||
|  |      *      summary="Deletes a bank_integration", | ||||||
|  |      *      description="Handles the deletion of a bank_integration by id", | ||||||
|  |      *      @OA\Parameter(ref="#/components/parameters/X-Api-Secret"), | ||||||
|  |      *      @OA\Parameter(ref="#/components/parameters/X-Api-Token"), | ||||||
|  |      *      @OA\Parameter(ref="#/components/parameters/X-Requested-With"), | ||||||
|  |      *      @OA\Parameter(ref="#/components/parameters/include"), | ||||||
|  |      *      @OA\Parameter( | ||||||
|  |      *          name="id", | ||||||
|  |      *          in="path", | ||||||
|  |      *          description="The BankIntegration Hashed ID", | ||||||
|  |      *          example="D2J234DFA", | ||||||
|  |      *          required=true, | ||||||
|  |      *          @OA\Schema( | ||||||
|  |      *              type="string", | ||||||
|  |      *              format="string", | ||||||
|  |      *          ), | ||||||
|  |      *      ), | ||||||
|  |      *      @OA\Response( | ||||||
|  |      *          response=200, | ||||||
|  |      *          description="Returns a HTTP status", | ||||||
|  |      *          @OA\Header(header="X-MINIMUM-CLIENT-VERSION", ref="#/components/headers/X-MINIMUM-CLIENT-VERSION"), | ||||||
|  |      *          @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"), | ||||||
|  |      *          @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"), | ||||||
|  |      *       ), | ||||||
|  |      *       @OA\Response( | ||||||
|  |      *          response=422, | ||||||
|  |      *          description="Validation error", | ||||||
|  |      *          @OA\JsonContent(ref="#/components/schemas/ValidationError"), | ||||||
|  |      * | ||||||
|  |      *       ), | ||||||
|  |      *       @OA\Response( | ||||||
|  |      *           response="default", | ||||||
|  |      *           description="Unexpected Error", | ||||||
|  |      *           @OA\JsonContent(ref="#/components/schemas/Error"), | ||||||
|  |      *       ), | ||||||
|  |      *     ) | ||||||
|  |      */ | ||||||
|  |     public function destroy(DestroyBankIntegrationRequest $request, BankIntegration $bank_integration) | ||||||
|  |     { | ||||||
|  |         $this->bank_integration_repo->delete($bank_integration); | ||||||
|  | 
 | ||||||
|  |         return $this->itemResponse($bank_integration->fresh()); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Perform bulk actions on the list view. | ||||||
|  |      * | ||||||
|  |      * @return Collection | ||||||
|  |      * | ||||||
|  |      * @OA\Post( | ||||||
|  |      *      path="/api/v1/bank_integrations/bulk", | ||||||
|  |      *      operationId="bulkBankIntegrations", | ||||||
|  |      *      tags={"bank_integrations"}, | ||||||
|  |      *      summary="Performs bulk actions on an array of bank_integrations", | ||||||
|  |      *      description="", | ||||||
|  |      *      @OA\Parameter(ref="#/components/parameters/X-Api-Secret"), | ||||||
|  |      *      @OA\Parameter(ref="#/components/parameters/X-Api-Token"), | ||||||
|  |      *      @OA\Parameter(ref="#/components/parameters/X-Requested-With"), | ||||||
|  |      *      @OA\Parameter(ref="#/components/parameters/index"), | ||||||
|  |      *      @OA\RequestBody( | ||||||
|  |      *         description="Action paramters", | ||||||
|  |      *         required=true, | ||||||
|  |      *         @OA\MediaType( | ||||||
|  |      *             mediaType="application/json", | ||||||
|  |      *             @OA\Schema( | ||||||
|  |      *                 type="array", | ||||||
|  |      *                 @OA\Items( | ||||||
|  |      *                     type="integer", | ||||||
|  |      *                     description="Array of hashed IDs to be bulk 'actioned", | ||||||
|  |      *                     example="[0,1,2,3]", | ||||||
|  |      *                 ), | ||||||
|  |      *             ) | ||||||
|  |      *         ) | ||||||
|  |      *     ), | ||||||
|  |      *      @OA\Response( | ||||||
|  |      *          response=200, | ||||||
|  |      *          description="The Bulk Action response", | ||||||
|  |      *          @OA\Header(header="X-MINIMUM-CLIENT-VERSION", ref="#/components/headers/X-MINIMUM-CLIENT-VERSION"), | ||||||
|  |      *          @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"), | ||||||
|  |      *          @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"), | ||||||
|  |      *       ), | ||||||
|  |      *       @OA\Response( | ||||||
|  |      *          response=422, | ||||||
|  |      *          description="Validation error", | ||||||
|  |      *          @OA\JsonContent(ref="#/components/schemas/ValidationError"), | ||||||
|  | 
 | ||||||
|  |      *       ), | ||||||
|  |      *       @OA\Response( | ||||||
|  |      *           response="default", | ||||||
|  |      *           description="Unexpected Error", | ||||||
|  |      *           @OA\JsonContent(ref="#/components/schemas/Error"), | ||||||
|  |      *       ), | ||||||
|  |      *     ) | ||||||
|  |      */ | ||||||
|  |     public function bulk() | ||||||
|  |     { | ||||||
|  |         $action = request()->input('action'); | ||||||
|  | 
 | ||||||
|  |         if(!in_array($action, ['archive', 'restore', 'delete'])) | ||||||
|  |             return response()->json(['message' => 'Unsupported action.'], 400); | ||||||
|  | 
 | ||||||
|  |         $ids = request()->input('ids'); | ||||||
|  |              | ||||||
|  |         $bank_integrations = BankIntegration::withTrashed()->whereIn('id', $this->transformKeys($ids))->company()->get(); | ||||||
|  | 
 | ||||||
|  |         $bank_integrations->each(function ($bank_integration, $key) use ($action) { | ||||||
|  |             if (auth()->user()->can('edit', $bank_integration)) { | ||||||
|  |                 $this->bank_integration_repo->{$action}($bank_integration); | ||||||
|  |             } | ||||||
|  |         }); | ||||||
|  | 
 | ||||||
|  |         /* Need to understand which permission are required for the given bulk action ie. view / edit */ | ||||||
|  | 
 | ||||||
|  |         return $this->listResponse(BankIntegration::withTrashed()->whereIn('id', $this->transformKeys($ids))->company()); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Return the remote list of accounts stored on the third party provider. | ||||||
|  |      * | ||||||
|  |      * @return Response | ||||||
|  |      * | ||||||
|  |      * @OA\Post( | ||||||
|  |      *      path="/api/v1/bank_integrations/refresh_accounts", | ||||||
|  |      *      operationId="getRefreshAccounts", | ||||||
|  |      *      tags={"bank_integrations"}, | ||||||
|  |      *      summary="Gets the list of accounts from the remote server", | ||||||
|  |      *      description="Adds an bank_integration to a company", | ||||||
|  |      *      @OA\Parameter(ref="#/components/parameters/X-Api-Secret"), | ||||||
|  |      *      @OA\Parameter(ref="#/components/parameters/X-Api-Token"), | ||||||
|  |      *      @OA\Parameter(ref="#/components/parameters/X-Requested-With"), | ||||||
|  |      *      @OA\Parameter(ref="#/components/parameters/include"), | ||||||
|  |      *      @OA\Response( | ||||||
|  |      *          response=200, | ||||||
|  |      *          description="Returns the saved bank_integration object", | ||||||
|  |      *          @OA\Header(header="X-MINIMUM-CLIENT-VERSION", ref="#/components/headers/X-MINIMUM-CLIENT-VERSION"), | ||||||
|  |      *          @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"), | ||||||
|  |      *          @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"), | ||||||
|  |      *          @OA\JsonContent(ref="#/components/schemas/BankIntegration"), | ||||||
|  |      *       ), | ||||||
|  |      *       @OA\Response( | ||||||
|  |      *          response=422, | ||||||
|  |      *          description="Validation error", | ||||||
|  |      *          @OA\JsonContent(ref="#/components/schemas/ValidationError"), | ||||||
|  |      * | ||||||
|  |      *       ), | ||||||
|  |      *       @OA\Response( | ||||||
|  |      *           response="default", | ||||||
|  |      *           description="Unexpected Error", | ||||||
|  |      *           @OA\JsonContent(ref="#/components/schemas/Error"), | ||||||
|  |      *       ), | ||||||
|  |      *     ) | ||||||
|  |      */ | ||||||
|  |     public function refreshAccounts(AdminBankIntegrationRequest $request) | ||||||
|  |     { | ||||||
|  |         // As yodlee is the first integration we don't need to perform switches yet, however
 | ||||||
|  |         // if we add additional providers we can reuse this class
 | ||||||
|  | 
 | ||||||
|  |         $bank_account_id = auth()->user()->account->bank_integration_account_id; | ||||||
|  | 
 | ||||||
|  |         if(!$bank_account_id) | ||||||
|  |             return response()->json(['message' => 'Not yet authenticated with Bank Integration service'], 400); | ||||||
|  | 
 | ||||||
|  |         $yodlee = new Yodlee($bank_account_id); | ||||||
|  | 
 | ||||||
|  |         $accounts = $yodlee->getAccounts();  | ||||||
|  | 
 | ||||||
|  |         foreach($accounts as $account) | ||||||
|  |         { | ||||||
|  | 
 | ||||||
|  |             if(!BankIntegration::where('bank_account_id', $account['id'])->where('company_id', auth()->user()->company()->id)->exists()) | ||||||
|  |             { | ||||||
|  |                 $bank_integration = new BankIntegration(); | ||||||
|  |                 $bank_integration->company_id = auth()->user()->company()->id; | ||||||
|  |                 $bank_integration->account_id = auth()->user()->account_id; | ||||||
|  |                 $bank_integration->user_id = auth()->user()->id; | ||||||
|  |                 $bank_integration->bank_account_id = $account['id']; | ||||||
|  |                 $bank_integration->bank_account_type = $account['account_type']; | ||||||
|  |                 $bank_integration->bank_account_name = $account['account_name']; | ||||||
|  |                 $bank_integration->bank_account_status = $account['account_status']; | ||||||
|  |                 $bank_integration->bank_account_number = $account['account_number']; | ||||||
|  |                 $bank_integration->provider_id = $account['provider_id']; | ||||||
|  |                 $bank_integration->provider_name = $account['provider_name']; | ||||||
|  |                 $bank_integration->nickname = $account['nickname']; | ||||||
|  |                 $bank_integration->balance = $account['current_balance']; | ||||||
|  |                 $bank_integration->currency = $account['account_currency']; | ||||||
|  |                  | ||||||
|  |                 $bank_integration->save(); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |         return response()->json(BankIntegration::query()->company(), 200); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Return the remote list of accounts stored on the third party provider | ||||||
|  |      * and update our local cache. | ||||||
|  |      * | ||||||
|  |      * @return Response | ||||||
|  |      * | ||||||
|  |      * @OA\Post( | ||||||
|  |      *      path="/api/v1/bank_integrations/remove_account/account_id", | ||||||
|  |      *      operationId="getRemoveAccount", | ||||||
|  |      *      tags={"bank_integrations"}, | ||||||
|  |      *      summary="Removes an account from the integration", | ||||||
|  |      *      description="Removes an account from the integration", | ||||||
|  |      *      @OA\Parameter(ref="#/components/parameters/X-Api-Secret"), | ||||||
|  |      *      @OA\Parameter(ref="#/components/parameters/X-Api-Token"), | ||||||
|  |      *      @OA\Parameter(ref="#/components/parameters/X-Requested-With"), | ||||||
|  |      *      @OA\Parameter(ref="#/components/parameters/include"), | ||||||
|  |      *      @OA\Response( | ||||||
|  |      *          response=200, | ||||||
|  |      *          description="Returns the bank_integration object", | ||||||
|  |      *          @OA\Header(header="X-MINIMUM-CLIENT-VERSION", ref="#/components/headers/X-MINIMUM-CLIENT-VERSION"), | ||||||
|  |      *          @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"), | ||||||
|  |      *          @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"), | ||||||
|  |      *          @OA\JsonContent(ref="#/components/schemas/BankIntegration"), | ||||||
|  |      *       ), | ||||||
|  |      *       @OA\Response( | ||||||
|  |      *          response=422, | ||||||
|  |      *          description="Validation error", | ||||||
|  |      *          @OA\JsonContent(ref="#/components/schemas/ValidationError"), | ||||||
|  |      * | ||||||
|  |      *       ), | ||||||
|  |      *       @OA\Response( | ||||||
|  |      *           response="default", | ||||||
|  |      *           description="Unexpected Error", | ||||||
|  |      *           @OA\JsonContent(ref="#/components/schemas/Error"), | ||||||
|  |      *       ), | ||||||
|  |      *     ) | ||||||
|  |      */ | ||||||
|  | 
 | ||||||
|  |     public function removeAccount(AdminBankIntegrationRequest $request, $acc_id) | ||||||
|  |     { | ||||||
|  | 
 | ||||||
|  |         $bank_account_id = auth()->user()->account->bank_integration_account_id; | ||||||
|  | 
 | ||||||
|  |         if(!$bank_account_id) | ||||||
|  |             return response()->json(['message' => 'Not yet authenticated with Bank Integration service'], 400); | ||||||
|  | 
 | ||||||
|  |         $bi = BankIntegration::withTrashed()->where('bank_account_id', $acc_id)->where('company_id', auth()->user()->company()->id)->firstOrFail(); | ||||||
|  | 
 | ||||||
|  |         $yodlee = new Yodlee($bank_account_id); | ||||||
|  |         $res = $yodlee->deleteAccount($acc_id); | ||||||
|  | 
 | ||||||
|  |         $this->bank_integration_repo->delete($bi); | ||||||
|  | 
 | ||||||
|  |         return $this->itemResponse($bi->fresh()); | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Return the remote list of accounts stored on the third party provider | ||||||
|  |      * and update our local cache. | ||||||
|  |      * | ||||||
|  |      * @return Response | ||||||
|  |      * | ||||||
|  |      * @OA\Post( | ||||||
|  |      *      path="/api/v1/bank_integrations/get_transactions/account_id", | ||||||
|  |      *      operationId="getAccountTransactions", | ||||||
|  |      *      tags={"bank_integrations"}, | ||||||
|  |      *      summary="Retrieve transactions for a account", | ||||||
|  |      *      description="Retrieve transactions for a account", | ||||||
|  |      *      @OA\Parameter(ref="#/components/parameters/X-Api-Secret"), | ||||||
|  |      *      @OA\Parameter(ref="#/components/parameters/X-Api-Token"), | ||||||
|  |      *      @OA\Parameter(ref="#/components/parameters/X-Requested-With"), | ||||||
|  |      *      @OA\Parameter(ref="#/components/parameters/include"), | ||||||
|  |      *      @OA\Response( | ||||||
|  |      *          response=200, | ||||||
|  |      *          description="Retrieve transactions for a account", | ||||||
|  |      *          @OA\Header(header="X-MINIMUM-CLIENT-VERSION", ref="#/components/headers/X-MINIMUM-CLIENT-VERSION"), | ||||||
|  |      *          @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"), | ||||||
|  |      *          @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"), | ||||||
|  |      *          @OA\JsonContent(ref="#/components/schemas/BankIntegration"), | ||||||
|  |      *       ), | ||||||
|  |      *       @OA\Response( | ||||||
|  |      *          response=422, | ||||||
|  |      *          description="Validation error", | ||||||
|  |      *          @OA\JsonContent(ref="#/components/schemas/ValidationError"), | ||||||
|  |      * | ||||||
|  |      *       ), | ||||||
|  |      *       @OA\Response( | ||||||
|  |      *           response="default", | ||||||
|  |      *           description="Unexpected Error", | ||||||
|  |      *           @OA\JsonContent(ref="#/components/schemas/Error"), | ||||||
|  |      *       ), | ||||||
|  |      *     ) | ||||||
|  |      */ | ||||||
|  |     public function getTransactions(AdminBankIntegrationRequest $request) | ||||||
|  |     { | ||||||
|  | 
 | ||||||
|  |         auth()->user()->account->bank_integrations->each(function ($bank_integration) { | ||||||
|  |              | ||||||
|  |             ProcessBankTransactions::dispatchSync(auth()->user()->account->bank_integration_account_id, $bank_integration); | ||||||
|  | 
 | ||||||
|  |         }); | ||||||
|  | 
 | ||||||
|  |         return response()->json(['message' => 'Fetching transactions....'], 200); | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										563
									
								
								app/Http/Controllers/BankTransactionController.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										563
									
								
								app/Http/Controllers/BankTransactionController.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,563 @@ | |||||||
|  | <?php | ||||||
|  | /** | ||||||
|  |  * Invoice Ninja (https://invoiceninja.com). | ||||||
|  |  * | ||||||
|  |  * @link https://github.com/invoiceninja/invoiceninja source repository | ||||||
|  |  * | ||||||
|  |  * @copyright Copyright (c) 2022. Invoice Ninja LLC (https://invoiceninja.com) | ||||||
|  |  * | ||||||
|  |  * @license https://www.elastic.co/licensing/elastic-license | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | namespace App\Http\Controllers; | ||||||
|  | 
 | ||||||
|  | use App\Factory\BankTransactionFactory; | ||||||
|  | use App\Helpers\Bank\Yodlee\Yodlee; | ||||||
|  | use App\Http\Requests\BankTransaction\AdminBankTransactionRequest; | ||||||
|  | use App\Http\Requests\BankTransaction\CreateBankTransactionRequest; | ||||||
|  | use App\Http\Requests\BankTransaction\DestroyBankTransactionRequest; | ||||||
|  | use App\Http\Requests\BankTransaction\EditBankTransactionRequest; | ||||||
|  | use App\Http\Requests\BankTransaction\ImportBankTransactionsRequest; | ||||||
|  | use App\Http\Requests\BankTransaction\MatchBankTransactionRequest; | ||||||
|  | use App\Http\Requests\BankTransaction\ShowBankTransactionRequest; | ||||||
|  | use App\Http\Requests\BankTransaction\StoreBankTransactionRequest; | ||||||
|  | use App\Http\Requests\BankTransaction\UpdateBankTransactionRequest; | ||||||
|  | use App\Http\Requests\Import\PreImportRequest; | ||||||
|  | use App\Jobs\Bank\MatchBankTransactions; | ||||||
|  | use App\Models\BankTransaction; | ||||||
|  | use App\Repositories\BankTransactionRepository; | ||||||
|  | use App\Services\Bank\BankService; | ||||||
|  | use App\Transformers\BankTransactionTransformer; | ||||||
|  | use App\Utils\Traits\MakesHash; | ||||||
|  | use Illuminate\Http\Request; | ||||||
|  | use Illuminate\Support\Facades\Cache; | ||||||
|  | use Illuminate\Support\Str; | ||||||
|  | 
 | ||||||
|  | class BankTransactionController extends BaseController | ||||||
|  | { | ||||||
|  |     use MakesHash; | ||||||
|  |      | ||||||
|  |     protected $entity_type = BankTransaction::class; | ||||||
|  | 
 | ||||||
|  |     protected $entity_transformer = BankTransactionTransformer::class; | ||||||
|  | 
 | ||||||
|  |     protected $bank_transaction_repo; | ||||||
|  | 
 | ||||||
|  |     public function __construct(BankTransactionRepository $bank_transaction_repo) | ||||||
|  |     { | ||||||
|  |         parent::__construct(); | ||||||
|  | 
 | ||||||
|  |         $this->bank_transaction_repo = $bank_transaction_repo; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * @OA\Get( | ||||||
|  |      *      path="/api/v1/bank_transactions", | ||||||
|  |      *      operationId="getBankTransactions", | ||||||
|  |      *      tags={"bank_transactions"}, | ||||||
|  |      *      summary="Gets a list of bank_transactions", | ||||||
|  |      *      description="Lists all bank integrations", | ||||||
|  |      *      @OA\Parameter(ref="#/components/parameters/X-Api-Secret"), | ||||||
|  |      *      @OA\Parameter(ref="#/components/parameters/X-Api-Token"), | ||||||
|  |      *      @OA\Parameter(ref="#/components/parameters/X-Requested-With"), | ||||||
|  |      *      @OA\Parameter(ref="#/components/parameters/include"), | ||||||
|  |      *      @OA\Parameter(ref="#/components/parameters/index"), | ||||||
|  |      *      @OA\Parameter( | ||||||
|  |      *          name="rows", | ||||||
|  |      *          in="query", | ||||||
|  |      *          description="The number of bank integrations to return", | ||||||
|  |      *          example="50", | ||||||
|  |      *          required=false, | ||||||
|  |      *          @OA\Schema( | ||||||
|  |      *              type="number", | ||||||
|  |      *              format="integer", | ||||||
|  |      *          ), | ||||||
|  |      *      ), | ||||||
|  |      *      @OA\Response( | ||||||
|  |      *          response=200, | ||||||
|  |      *          description="A list of bank integrations", | ||||||
|  |      *          @OA\Header(header="X-MINIMUM-CLIENT-VERSION", ref="#/components/headers/X-MINIMUM-CLIENT-VERSION"), | ||||||
|  |      *          @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"), | ||||||
|  |      *          @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"), | ||||||
|  |      *          @OA\JsonContent(ref="#/components/schemas/BankTransaction"), | ||||||
|  |      *       ), | ||||||
|  |      *       @OA\Response( | ||||||
|  |      *          response=422, | ||||||
|  |      *          description="Validation error", | ||||||
|  |      *          @OA\JsonContent(ref="#/components/schemas/ValidationError"), | ||||||
|  |      *       ), | ||||||
|  |      *       @OA\Response( | ||||||
|  |      *           response="default", | ||||||
|  |      *           description="Unexpected Error", | ||||||
|  |      *           @OA\JsonContent(ref="#/components/schemas/Error"), | ||||||
|  |      *       ), | ||||||
|  |      *     ) | ||||||
|  |      * @param Request $request | ||||||
|  |      * @return Response|mixed | ||||||
|  |      */ | ||||||
|  |     public function index(Request $request) | ||||||
|  |     { | ||||||
|  | 
 | ||||||
|  |         $bank_transactions = BankTransaction::query()->company(); | ||||||
|  | 
 | ||||||
|  |         return $this->listResponse($bank_transactions); | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Display the specified resource. | ||||||
|  |      * | ||||||
|  |      * @param ShowBankTransactionRequest $request | ||||||
|  |      * @param BankTransaction $bank_transaction | ||||||
|  |      * @return Response | ||||||
|  |      * | ||||||
|  |      * | ||||||
|  |      * @OA\Get( | ||||||
|  |      *      path="/api/v1/bank_transactions/{id}", | ||||||
|  |      *      operationId="showBankTransaction", | ||||||
|  |      *      tags={"bank_transactions"}, | ||||||
|  |      *      summary="Shows a bank_transaction", | ||||||
|  |      *      description="Displays a bank_transaction by id", | ||||||
|  |      *      @OA\Parameter(ref="#/components/parameters/X-Api-Secret"), | ||||||
|  |      *      @OA\Parameter(ref="#/components/parameters/X-Api-Token"), | ||||||
|  |      *      @OA\Parameter(ref="#/components/parameters/X-Requested-With"), | ||||||
|  |      *      @OA\Parameter(ref="#/components/parameters/include"), | ||||||
|  |      *      @OA\Parameter( | ||||||
|  |      *          name="id", | ||||||
|  |      *          in="path", | ||||||
|  |      *          description="The BankTransaction Hashed ID", | ||||||
|  |      *          example="D2J234DFA", | ||||||
|  |      *          required=true, | ||||||
|  |      *          @OA\Schema( | ||||||
|  |      *              type="string", | ||||||
|  |      *              format="string", | ||||||
|  |      *          ), | ||||||
|  |      *      ), | ||||||
|  |      *      @OA\Response( | ||||||
|  |      *          response=200, | ||||||
|  |      *          description="Returns the bank_transaction object", | ||||||
|  |      *          @OA\Header(header="X-MINIMUM-CLIENT-VERSION", ref="#/components/headers/X-MINIMUM-CLIENT-VERSION"), | ||||||
|  |      *          @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"), | ||||||
|  |      *          @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"), | ||||||
|  |      *          @OA\JsonContent(ref="#/components/schemas/BankTransaction"), | ||||||
|  |      *       ), | ||||||
|  |      *       @OA\Response( | ||||||
|  |      *          response=422, | ||||||
|  |      *          description="Validation error", | ||||||
|  |      *          @OA\JsonContent(ref="#/components/schemas/ValidationError"), | ||||||
|  |      * | ||||||
|  |      *       ), | ||||||
|  |      *       @OA\Response( | ||||||
|  |      *           response="default", | ||||||
|  |      *           description="Unexpected Error", | ||||||
|  |      *           @OA\JsonContent(ref="#/components/schemas/Error"), | ||||||
|  |      *       ), | ||||||
|  |      *     ) | ||||||
|  |      */ | ||||||
|  |     public function show(ShowBankTransactionRequest $request, BankTransaction $bank_transaction) | ||||||
|  |     { | ||||||
|  |         return $this->itemResponse($bank_transaction); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Show the form for editing the specified resource. | ||||||
|  |      * | ||||||
|  |      * @param EditBankTransactionRequest $request | ||||||
|  |      * @param BankTransaction $bank_transaction | ||||||
|  |      * @return Response | ||||||
|  |      * | ||||||
|  |      * | ||||||
|  |      * @OA\Get( | ||||||
|  |      *      path="/api/v1/bank_transactions/{id}/edit", | ||||||
|  |      *      operationId="editBankTransaction", | ||||||
|  |      *      tags={"bank_transactions"}, | ||||||
|  |      *      summary="Shows a bank_transaction for editing", | ||||||
|  |      *      description="Displays a bank_transaction by id", | ||||||
|  |      *      @OA\Parameter(ref="#/components/parameters/X-Api-Secret"), | ||||||
|  |      *      @OA\Parameter(ref="#/components/parameters/X-Api-Token"), | ||||||
|  |      *      @OA\Parameter(ref="#/components/parameters/X-Requested-With"), | ||||||
|  |      *      @OA\Parameter(ref="#/components/parameters/include"), | ||||||
|  |      *      @OA\Parameter( | ||||||
|  |      *          name="id", | ||||||
|  |      *          in="path", | ||||||
|  |      *          description="The BankTransaction Hashed ID", | ||||||
|  |      *          example="D2J234DFA", | ||||||
|  |      *          required=true, | ||||||
|  |      *          @OA\Schema( | ||||||
|  |      *              type="string", | ||||||
|  |      *              format="string", | ||||||
|  |      *          ), | ||||||
|  |      *      ), | ||||||
|  |      *      @OA\Response( | ||||||
|  |      *          response=200, | ||||||
|  |      *          description="Returns the bank_transaction object", | ||||||
|  |      *          @OA\Header(header="X-MINIMUM-CLIENT-VERSION", ref="#/components/headers/X-MINIMUM-CLIENT-VERSION"), | ||||||
|  |      *          @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"), | ||||||
|  |      *          @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"), | ||||||
|  |      *          @OA\JsonContent(ref="#/components/schemas/BankTransaction"), | ||||||
|  |      *       ), | ||||||
|  |      *       @OA\Response( | ||||||
|  |      *          response=422, | ||||||
|  |      *          description="Validation error", | ||||||
|  |      *          @OA\JsonContent(ref="#/components/schemas/ValidationError"), | ||||||
|  |      * | ||||||
|  |      *       ), | ||||||
|  |      *       @OA\Response( | ||||||
|  |      *           response="default", | ||||||
|  |      *           description="Unexpected Error", | ||||||
|  |      *           @OA\JsonContent(ref="#/components/schemas/Error"), | ||||||
|  |      *       ), | ||||||
|  |      *     ) | ||||||
|  |      */ | ||||||
|  |     public function edit(EditBankTransactionRequest $request, BankTransaction $bank_transaction) | ||||||
|  |     { | ||||||
|  |         return $this->itemResponse($bank_transaction); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Update the specified resource in storage. | ||||||
|  |      * | ||||||
|  |      * @param UpdateBankTransactionRequest $request | ||||||
|  |      * @param BankTransaction $bank_transaction | ||||||
|  |      * @return Response | ||||||
|  |      * | ||||||
|  |      * | ||||||
|  |      * | ||||||
|  |      * @OA\Put( | ||||||
|  |      *      path="/api/v1/bank_transactions/{id}", | ||||||
|  |      *      operationId="updateBankTransaction", | ||||||
|  |      *      tags={"bank_transactions"}, | ||||||
|  |      *      summary="Updates a bank_transaction", | ||||||
|  |      *      description="Handles the updating of a bank_transaction by id", | ||||||
|  |      *      @OA\Parameter(ref="#/components/parameters/X-Api-Secret"), | ||||||
|  |      *      @OA\Parameter(ref="#/components/parameters/X-Api-Token"), | ||||||
|  |      *      @OA\Parameter(ref="#/components/parameters/X-Requested-With"), | ||||||
|  |      *      @OA\Parameter(ref="#/components/parameters/include"), | ||||||
|  |      *      @OA\Parameter( | ||||||
|  |      *          name="id", | ||||||
|  |      *          in="path", | ||||||
|  |      *          description="The BankTransaction Hashed ID", | ||||||
|  |      *          example="D2J234DFA", | ||||||
|  |      *          required=true, | ||||||
|  |      *          @OA\Schema( | ||||||
|  |      *              type="string", | ||||||
|  |      *              format="string", | ||||||
|  |      *          ), | ||||||
|  |      *      ), | ||||||
|  |      *      @OA\Response( | ||||||
|  |      *          response=200, | ||||||
|  |      *          description="Returns the bank_transaction object", | ||||||
|  |      *          @OA\Header(header="X-MINIMUM-CLIENT-VERSION", ref="#/components/headers/X-MINIMUM-CLIENT-VERSION"), | ||||||
|  |      *          @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"), | ||||||
|  |      *          @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"), | ||||||
|  |      *          @OA\JsonContent(ref="#/components/schemas/BankTransaction"), | ||||||
|  |      *       ), | ||||||
|  |      *       @OA\Response( | ||||||
|  |      *          response=422, | ||||||
|  |      *          description="Validation error", | ||||||
|  |      *          @OA\JsonContent(ref="#/components/schemas/ValidationError"), | ||||||
|  |      * | ||||||
|  |      *       ), | ||||||
|  |      *       @OA\Response( | ||||||
|  |      *           response="default", | ||||||
|  |      *           description="Unexpected Error", | ||||||
|  |      *           @OA\JsonContent(ref="#/components/schemas/Error"), | ||||||
|  |      *       ), | ||||||
|  |      *     ) | ||||||
|  |      */ | ||||||
|  |     public function update(UpdateBankTransactionRequest $request, BankTransaction $bank_transaction) | ||||||
|  |     { | ||||||
|  | 
 | ||||||
|  |         //stubs for updating the model
 | ||||||
|  |         $bank_transaction = $this->bank_transaction_repo->save($request->all(), $bank_transaction); | ||||||
|  | 
 | ||||||
|  |         return $this->itemResponse($bank_transaction->fresh()); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Show the form for creating a new resource. | ||||||
|  |      * | ||||||
|  |      * @param CreateBankTransactionRequest $request | ||||||
|  |      * @return Response | ||||||
|  |      * | ||||||
|  |      * | ||||||
|  |      * | ||||||
|  |      * @OA\Get( | ||||||
|  |      *      path="/api/v1/bank_transactions/create", | ||||||
|  |      *      operationId="getBankTransactionsCreate", | ||||||
|  |      *      tags={"bank_transactions"}, | ||||||
|  |      *      summary="Gets a new blank bank_transaction object", | ||||||
|  |      *      description="Returns a blank object with default values", | ||||||
|  |      *      @OA\Parameter(ref="#/components/parameters/X-Api-Secret"), | ||||||
|  |      *      @OA\Parameter(ref="#/components/parameters/X-Api-Token"), | ||||||
|  |      *      @OA\Parameter(ref="#/components/parameters/X-Requested-With"), | ||||||
|  |      *      @OA\Parameter(ref="#/components/parameters/include"), | ||||||
|  |      *      @OA\Response( | ||||||
|  |      *          response=200, | ||||||
|  |      *          description="A blank bank_transaction object", | ||||||
|  |      *          @OA\Header(header="X-MINIMUM-CLIENT-VERSION", ref="#/components/headers/X-MINIMUM-CLIENT-VERSION"), | ||||||
|  |      *          @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"), | ||||||
|  |      *          @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"), | ||||||
|  |      *          @OA\JsonContent(ref="#/components/schemas/BankTransaction"), | ||||||
|  |      *       ), | ||||||
|  |      *       @OA\Response( | ||||||
|  |      *          response=422, | ||||||
|  |      *          description="Validation error", | ||||||
|  |      *          @OA\JsonContent(ref="#/components/schemas/ValidationError"), | ||||||
|  |      * | ||||||
|  |      *       ), | ||||||
|  |      *       @OA\Response( | ||||||
|  |      *           response="default", | ||||||
|  |      *           description="Unexpected Error", | ||||||
|  |      *           @OA\JsonContent(ref="#/components/schemas/Error"), | ||||||
|  |      *       ), | ||||||
|  |      *     ) | ||||||
|  |      */ | ||||||
|  |     public function create(CreateBankTransactionRequest $request) | ||||||
|  |     { | ||||||
|  |         $bank_transaction = BankTransactionFactory::create(auth()->user()->company()->id, auth()->user()->id, auth()->user()->account_id); | ||||||
|  | 
 | ||||||
|  |         return $this->itemResponse($bank_transaction); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Store a newly created resource in storage. | ||||||
|  |      * | ||||||
|  |      * @param StoreBankTransactionRequest $request | ||||||
|  |      * @return Response | ||||||
|  |      * | ||||||
|  |      * | ||||||
|  |      * | ||||||
|  |      * @OA\Post( | ||||||
|  |      *      path="/api/v1/bank_transactions", | ||||||
|  |      *      operationId="storeBankTransaction", | ||||||
|  |      *      tags={"bank_transactions"}, | ||||||
|  |      *      summary="Adds a bank_transaction", | ||||||
|  |      *      description="Adds an bank_transaction to a company", | ||||||
|  |      *      @OA\Parameter(ref="#/components/parameters/X-Api-Secret"), | ||||||
|  |      *      @OA\Parameter(ref="#/components/parameters/X-Api-Token"), | ||||||
|  |      *      @OA\Parameter(ref="#/components/parameters/X-Requested-With"), | ||||||
|  |      *      @OA\Parameter(ref="#/components/parameters/include"), | ||||||
|  |      *      @OA\Response( | ||||||
|  |      *          response=200, | ||||||
|  |      *          description="Returns the saved bank_transaction object", | ||||||
|  |      *          @OA\Header(header="X-MINIMUM-CLIENT-VERSION", ref="#/components/headers/X-MINIMUM-CLIENT-VERSION"), | ||||||
|  |      *          @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"), | ||||||
|  |      *          @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"), | ||||||
|  |      *          @OA\JsonContent(ref="#/components/schemas/BankTransaction"), | ||||||
|  |      *       ), | ||||||
|  |      *       @OA\Response( | ||||||
|  |      *          response=422, | ||||||
|  |      *          description="Validation error", | ||||||
|  |      *          @OA\JsonContent(ref="#/components/schemas/ValidationError"), | ||||||
|  |      * | ||||||
|  |      *       ), | ||||||
|  |      *       @OA\Response( | ||||||
|  |      *           response="default", | ||||||
|  |      *           description="Unexpected Error", | ||||||
|  |      *           @OA\JsonContent(ref="#/components/schemas/Error"), | ||||||
|  |      *       ), | ||||||
|  |      *     ) | ||||||
|  |      */ | ||||||
|  |     public function store(StoreBankTransactionRequest $request) | ||||||
|  |     { | ||||||
|  |         //stub to store the model
 | ||||||
|  |         $bank_transaction = $this->bank_transaction_repo->save($request->all(), BankTransactionFactory::create(auth()->user()->company()->id, auth()->user()->id, auth()->user()->account_id)); | ||||||
|  | 
 | ||||||
|  |         return $this->itemResponse($bank_transaction); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Remove the specified resource from storage. | ||||||
|  |      * | ||||||
|  |      * @param DestroyBankTransactionRequest $request | ||||||
|  |      * @param BankTransaction $bank_transaction | ||||||
|  |      * @return Response | ||||||
|  |      * | ||||||
|  |      * | ||||||
|  |      * @throws \Exception | ||||||
|  |      * @OA\Delete( | ||||||
|  |      *      path="/api/v1/bank_transactions/{id}", | ||||||
|  |      *      operationId="deleteBankTransaction", | ||||||
|  |      *      tags={"bank_transactions"}, | ||||||
|  |      *      summary="Deletes a bank_transaction", | ||||||
|  |      *      description="Handles the deletion of a bank_transaction by id", | ||||||
|  |      *      @OA\Parameter(ref="#/components/parameters/X-Api-Secret"), | ||||||
|  |      *      @OA\Parameter(ref="#/components/parameters/X-Api-Token"), | ||||||
|  |      *      @OA\Parameter(ref="#/components/parameters/X-Requested-With"), | ||||||
|  |      *      @OA\Parameter(ref="#/components/parameters/include"), | ||||||
|  |      *      @OA\Parameter( | ||||||
|  |      *          name="id", | ||||||
|  |      *          in="path", | ||||||
|  |      *          description="The BankTransaction Hashed ID", | ||||||
|  |      *          example="D2J234DFA", | ||||||
|  |      *          required=true, | ||||||
|  |      *          @OA\Schema( | ||||||
|  |      *              type="string", | ||||||
|  |      *              format="string", | ||||||
|  |      *          ), | ||||||
|  |      *      ), | ||||||
|  |      *      @OA\Response( | ||||||
|  |      *          response=200, | ||||||
|  |      *          description="Returns a HTTP status", | ||||||
|  |      *          @OA\Header(header="X-MINIMUM-CLIENT-VERSION", ref="#/components/headers/X-MINIMUM-CLIENT-VERSION"), | ||||||
|  |      *          @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"), | ||||||
|  |      *          @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"), | ||||||
|  |      *       ), | ||||||
|  |      *       @OA\Response( | ||||||
|  |      *          response=422, | ||||||
|  |      *          description="Validation error", | ||||||
|  |      *          @OA\JsonContent(ref="#/components/schemas/ValidationError"), | ||||||
|  |      * | ||||||
|  |      *       ), | ||||||
|  |      *       @OA\Response( | ||||||
|  |      *           response="default", | ||||||
|  |      *           description="Unexpected Error", | ||||||
|  |      *           @OA\JsonContent(ref="#/components/schemas/Error"), | ||||||
|  |      *       ), | ||||||
|  |      *     ) | ||||||
|  |      */ | ||||||
|  |     public function destroy(DestroyBankTransactionRequest $request, BankTransaction $bank_transaction) | ||||||
|  |     { | ||||||
|  |         $this->bank_transaction_repo->delete($bank_transaction); | ||||||
|  | 
 | ||||||
|  |         return $this->itemResponse($bank_transaction->fresh()); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Perform bulk actions on the list view. | ||||||
|  |      * | ||||||
|  |      * @return Collection | ||||||
|  |      * | ||||||
|  |      * @OA\Post( | ||||||
|  |      *      path="/api/v1/bank_transations/bulk", | ||||||
|  |      *      operationId="bulkBankTransactions", | ||||||
|  |      *      tags={"bank_transactions"}, | ||||||
|  |      *      summary="Performs bulk actions on an array of bank_transations", | ||||||
|  |      *      description="", | ||||||
|  |      *      @OA\Parameter(ref="#/components/parameters/X-Api-Secret"), | ||||||
|  |      *      @OA\Parameter(ref="#/components/parameters/X-Api-Token"), | ||||||
|  |      *      @OA\Parameter(ref="#/components/parameters/X-Requested-With"), | ||||||
|  |      *      @OA\Parameter(ref="#/components/parameters/index"), | ||||||
|  |      *      @OA\RequestBody( | ||||||
|  |      *         description="Action paramters", | ||||||
|  |      *         required=true, | ||||||
|  |      *         @OA\MediaType( | ||||||
|  |      *             mediaType="application/json", | ||||||
|  |      *             @OA\Schema( | ||||||
|  |      *                 type="array", | ||||||
|  |      *                 @OA\Items( | ||||||
|  |      *                     type="integer", | ||||||
|  |      *                     description="Array of hashed IDs to be bulk 'actioned", | ||||||
|  |      *                     example="[0,1,2,3]", | ||||||
|  |      *                 ), | ||||||
|  |      *             ) | ||||||
|  |      *         ) | ||||||
|  |      *     ), | ||||||
|  |      *      @OA\Response( | ||||||
|  |      *          response=200, | ||||||
|  |      *          description="The Bulk Action response", | ||||||
|  |      *          @OA\Header(header="X-MINIMUM-CLIENT-VERSION", ref="#/components/headers/X-MINIMUM-CLIENT-VERSION"), | ||||||
|  |      *          @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"), | ||||||
|  |      *          @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"), | ||||||
|  |      *       ), | ||||||
|  |      *       @OA\Response( | ||||||
|  |      *          response=422, | ||||||
|  |      *          description="Validation error", | ||||||
|  |      *          @OA\JsonContent(ref="#/components/schemas/ValidationError"), | ||||||
|  | 
 | ||||||
|  |      *       ), | ||||||
|  |      *       @OA\Response( | ||||||
|  |      *           response="default", | ||||||
|  |      *           description="Unexpected Error", | ||||||
|  |      *           @OA\JsonContent(ref="#/components/schemas/Error"), | ||||||
|  |      *       ), | ||||||
|  |      *     ) | ||||||
|  |      */ | ||||||
|  |     public function bulk() | ||||||
|  |     { | ||||||
|  |         $action = request()->input('action'); | ||||||
|  | 
 | ||||||
|  |         if(!in_array($action, ['archive', 'restore', 'delete'])) | ||||||
|  |             return response()->json(['message' => 'Unsupported action.'], 400); | ||||||
|  | 
 | ||||||
|  |         $ids = request()->input('ids'); | ||||||
|  |              | ||||||
|  |         $bank_transactions = BankTransaction::withTrashed()->whereIn('id', $this->transformKeys($ids))->company()->get(); | ||||||
|  | 
 | ||||||
|  |         $bank_transactions->each(function ($bank_transaction, $key) use ($action) { | ||||||
|  |             if (auth()->user()->can('edit', $bank_transaction)) { | ||||||
|  |                 $this->bank_transaction_repo->{$action}($bank_transaction); | ||||||
|  |             } | ||||||
|  |         }); | ||||||
|  | 
 | ||||||
|  |         /* Need to understand which permission are required for the given bulk action ie. view / edit */ | ||||||
|  | 
 | ||||||
|  |         return $this->listResponse(BankTransaction::withTrashed()->whereIn('id', $this->transformKeys($ids))->company()); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Perform bulk actions on the list view. | ||||||
|  |      * | ||||||
|  |      * @return Collection | ||||||
|  |      * | ||||||
|  |      * @OA\Post( | ||||||
|  |      *      path="/api/v1/bank_transations/match", | ||||||
|  |      *      operationId="matchBankTransactions", | ||||||
|  |      *      tags={"bank_transactions"}, | ||||||
|  |      *      summary="Performs match actions on an array of bank_transactions", | ||||||
|  |      *      description="", | ||||||
|  |      *      @OA\Parameter(ref="#/components/parameters/X-Api-Secret"), | ||||||
|  |      *      @OA\Parameter(ref="#/components/parameters/X-Api-Token"), | ||||||
|  |      *      @OA\Parameter(ref="#/components/parameters/X-Requested-With"), | ||||||
|  |      *      @OA\Parameter(ref="#/components/parameters/index"), | ||||||
|  |      *      @OA\RequestBody( | ||||||
|  |      *         description="Action paramters", | ||||||
|  |      *         required=true, | ||||||
|  |      *         @OA\MediaType( | ||||||
|  |      *             mediaType="application/json", | ||||||
|  |      *             @OA\Schema( | ||||||
|  |      *                 type="array", | ||||||
|  |      *                 @OA\Items( | ||||||
|  |      *                     type="integer", | ||||||
|  |      *                     description="Array of hashed IDs to be bulk 'actioned", | ||||||
|  |      *                     example="[0,1,2,3]", | ||||||
|  |      *                 ), | ||||||
|  |      *             ) | ||||||
|  |      *         ) | ||||||
|  |      *     ), | ||||||
|  |      *      @OA\Response( | ||||||
|  |      *          response=200, | ||||||
|  |      *          description="The Bulk Action response", | ||||||
|  |      *          @OA\Header(header="X-MINIMUM-CLIENT-VERSION", ref="#/components/headers/X-MINIMUM-CLIENT-VERSION"), | ||||||
|  |      *          @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"), | ||||||
|  |      *          @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"), | ||||||
|  |      *       ), | ||||||
|  |      *       @OA\Response( | ||||||
|  |      *          response=422, | ||||||
|  |      *          description="Validation error", | ||||||
|  |      *          @OA\JsonContent(ref="#/components/schemas/ValidationError"), | ||||||
|  | 
 | ||||||
|  |      *       ), | ||||||
|  |      *       @OA\Response( | ||||||
|  |      *           response="default", | ||||||
|  |      *           description="Unexpected Error", | ||||||
|  |      *           @OA\JsonContent(ref="#/components/schemas/Error"), | ||||||
|  |      *       ), | ||||||
|  |      *     ) | ||||||
|  |      */ | ||||||
|  |     public function match(MatchBankTransactionRequest $request) | ||||||
|  |     { | ||||||
|  | 
 | ||||||
|  |         // MatchBankTransactions::dispatch(auth()->user()->company()->id, auth()->user()->company()->db, $request->all());
 | ||||||
|  |          | ||||||
|  |         $bts = (new MatchBankTransactions(auth()->user()->company()->id, auth()->user()->company()->db, $request->all()))->handle(); | ||||||
|  | 
 | ||||||
|  |         return $this->listResponse($bts); | ||||||
|  |   | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | } | ||||||
| @ -105,6 +105,8 @@ class BaseController extends Controller | |||||||
|           'company.vendors.documents', |           'company.vendors.documents', | ||||||
|           'company.webhooks', |           'company.webhooks', | ||||||
|           'company.system_logs', |           'company.system_logs', | ||||||
|  |           'company.bank_integrations', | ||||||
|  |           'company.bank_transactions', | ||||||
|         ]; |         ]; | ||||||
| 
 | 
 | ||||||
|     private $mini_load = [ |     private $mini_load = [ | ||||||
| @ -122,6 +124,7 @@ class BaseController extends Controller | |||||||
|         'company.designs.company', |         'company.designs.company', | ||||||
|         'company.expense_categories', |         'company.expense_categories', | ||||||
|         'company.subscriptions', |         'company.subscriptions', | ||||||
|  |         'company.bank_integrations', | ||||||
|     ]; |     ]; | ||||||
| 
 | 
 | ||||||
|     public function __construct() |     public function __construct() | ||||||
| @ -438,6 +441,20 @@ class BaseController extends Controller | |||||||
|                         $query->where('subscriptions.user_id', $user->id); |                         $query->where('subscriptions.user_id', $user->id); | ||||||
|                     } |                     } | ||||||
|                 }, |                 }, | ||||||
|  |                 'company.bank_integrations'=> function ($query) use ($updated_at, $user) { | ||||||
|  |                     $query->whereNotNull('updated_at'); | ||||||
|  | 
 | ||||||
|  |                     if (! $user->isAdmin()) { | ||||||
|  |                         $query->where('bank_integrations.user_id', $user->id); | ||||||
|  |                     } | ||||||
|  |                 }, | ||||||
|  |                 'company.bank_transactions'=> function ($query) use ($updated_at, $user) { | ||||||
|  |                     $query->where('updated_at', '>=', $updated_at); | ||||||
|  | 
 | ||||||
|  |                     if (! $user->isAdmin()) { | ||||||
|  |                         $query->where('bank_transactions.user_id', $user->id); | ||||||
|  |                     } | ||||||
|  |                 }, | ||||||
|             ] |             ] | ||||||
|         ); |         ); | ||||||
| 
 | 
 | ||||||
| @ -497,6 +514,12 @@ class BaseController extends Controller | |||||||
|                         $query->where('activities.user_id', $user->id); |                         $query->where('activities.user_id', $user->id); | ||||||
|                     } |                     } | ||||||
|                 }, |                 }, | ||||||
|  |                 'company.bank_integrations'=> function ($query) use ($created_at, $user) { | ||||||
|  | 
 | ||||||
|  |                     if (! $user->isAdmin()) { | ||||||
|  |                         $query->where('bank_integrations.user_id', $user->id); | ||||||
|  |                     } | ||||||
|  |                 }, | ||||||
|             ] |             ] | ||||||
|         ); |         ); | ||||||
| 
 | 
 | ||||||
| @ -741,6 +764,20 @@ class BaseController extends Controller | |||||||
| 
 | 
 | ||||||
|                     } |                     } | ||||||
|                 }, |                 }, | ||||||
|  |                 'company.bank_integrations'=> function ($query) use ($created_at, $user) { | ||||||
|  |                     $query->where('created_at', '>=', $created_at); | ||||||
|  | 
 | ||||||
|  |                     if (! $user->isAdmin()) { | ||||||
|  |                         $query->where('bank_integrations.user_id', $user->id); | ||||||
|  |                     } | ||||||
|  |                 }, | ||||||
|  |                 'company.bank_transactions'=> function ($query) use ($created_at, $user) { | ||||||
|  |                     $query->where('created_at', '>=', $created_at); | ||||||
|  | 
 | ||||||
|  |                     if (! $user->isAdmin()) { | ||||||
|  |                         $query->where('bank_transactions.user_id', $user->id); | ||||||
|  |                     } | ||||||
|  |                 }, | ||||||
|             ] |             ] | ||||||
|         ); |         ); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -669,7 +669,7 @@ class ClientController extends BaseController | |||||||
|      * |      * | ||||||
|      * |      * | ||||||
|      * @OA\Post( |      * @OA\Post( | ||||||
|      *      path="/api/v1/clients/{id}/{mergaeble_client_hashed_id}/merge", |      *      path="/api/v1/clients/{id}/{mergeable_client_hashed_id}/merge", | ||||||
|      *      operationId="mergeClient", |      *      operationId="mergeClient", | ||||||
|      *      tags={"clients"}, |      *      tags={"clients"}, | ||||||
|      *      summary="Merges two clients", |      *      summary="Merges two clients", | ||||||
| @ -690,7 +690,7 @@ class ClientController extends BaseController | |||||||
|      *          ), |      *          ), | ||||||
|      *      ), |      *      ), | ||||||
|      *      @OA\Parameter( |      *      @OA\Parameter( | ||||||
|      *          name="mergeable_client_hashedid", |      *          name="mergeable_client_hashed_id", | ||||||
|      *          in="path", |      *          in="path", | ||||||
|      *          description="The Mergeable Client Hashed ID", |      *          description="The Mergeable Client Hashed ID", | ||||||
|      *          example="D2J234DFA", |      *          example="D2J234DFA", | ||||||
|  | |||||||
| @ -3,20 +3,21 @@ | |||||||
|  * @OA\Schema( |  * @OA\Schema( | ||||||
|  *   schema="Activity", |  *   schema="Activity", | ||||||
|  *   type="object", |  *   type="object", | ||||||
|  *       @OA\Property(property="id", type="string", example="Opnel5aKBz", description="______"), |  *       @OA\Property(property="id", type="string", example="Opnel5aKBz", description="The id field of the activity"), | ||||||
|  *       @OA\Property(property="activity_type_id", type="string", example="2", description="______"), |  *       @OA\Property(property="activity_type_id", type="string", example="Opnel5aKBz", description="The activity type id"), | ||||||
|  *       @OA\Property(property="client_id", type="string", example="2", description="______"), |  *       @OA\Property(property="client_id", type="string", example="Opnel5aKBz", description="The client hashed id"), | ||||||
|  *       @OA\Property(property="company_id", type="string", example="2", description="______"), |  *       @OA\Property(property="company_id", type="string", example="Opnel5aKBz", description="The company hashed id"), | ||||||
|  *       @OA\Property(property="user_id", type="string", example="2", description="______"), |  *       @OA\Property(property="user_id", type="string", example="Opnel5aKBz", description="The user hashed id"), | ||||||
|  *       @OA\Property(property="invoice_id", type="string", example="2", description="______"), |  *       @OA\Property(property="invoice_id", type="string", example="Opnel5aKBz", description="The invoice hashed id"), | ||||||
|  *       @OA\Property(property="payment_id", type="string", example="2", description="______"), |  *       @OA\Property(property="payment_id", type="string", example="Opnel5aKBz", description="The payment hashed id"), | ||||||
|  *       @OA\Property(property="credit_id", type="string", example="2", description="______"), |  *       @OA\Property(property="credit_id", type="string", example="Opnel5aKBz", description="The credit hashed id"), | ||||||
|  *       @OA\Property(property="updated_at", type="string", example="2", description="______"), |  *       @OA\Property(property="updated_at", type="integer", example="343421434", description="Unixtimestamp the last time the record was updated"), | ||||||
|  *       @OA\Property(property="expense_id", type="string", example="2", description="______"), |  *       @OA\Property(property="expense_id", type="string", example="Opnel5aKBz", description="The expense hashed id"), | ||||||
|  *       @OA\Property(property="is_system", type="boolean", example=true, description="______"), |  *       @OA\Property(property="is_system", type="boolean", example=true, description="Defines is the activity was performed by the system"), | ||||||
|  *       @OA\Property(property="contact_id", type="string", example="2", description="______"), |  *       @OA\Property(property="contact_id", type="string", example="Opnel5aKBz", description="The contact hashed id"), | ||||||
|  *       @OA\Property(property="task_id", type="string", example="2", description="______"), |  *       @OA\Property(property="task_id", type="string", example="Opnel5aKBz", description="The task hashed id"), | ||||||
|  *       @OA\Property(property="notes", type="string", example="2", description="______"), |  *       @OA\Property(property="notes", type="string", example="Opnel5aKBz", description="Activity Notes"), | ||||||
|  *       @OA\Property(property="ip", type="string", example="2", description="______"), |  *       @OA\Property(property="token_id", type="string", example="Opnel5aKBz", description="The hashed ID of the token who performed the action"), | ||||||
|  |  *       @OA\Property(property="ip", type="string", example="192.168.1.252", description="The IP Address of the user who performed the action"), | ||||||
|  * ) |  * ) | ||||||
|  */ |  */ | ||||||
|  | |||||||
							
								
								
									
										18
									
								
								app/Http/Controllers/OpenAPI/BankIntegration.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								app/Http/Controllers/OpenAPI/BankIntegration.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,18 @@ | |||||||
|  | <?php | ||||||
|  | /** | ||||||
|  |  * @OA\Schema( | ||||||
|  |  *   schema="BankIntegration", | ||||||
|  |  *   type="object", | ||||||
|  |  *       @OA\Property(property="id", type="string", example="AS3df3A", description="The bank integration hashed id"), | ||||||
|  |  *       @OA\Property(property="company_id", type="string", example="AS3df3A", description="The company hashed id"), | ||||||
|  |  *       @OA\Property(property="user_id", type="string", example="AS3df3A", description="The user hashed id"), | ||||||
|  |  *       @OA\Property(property="provider_bank_name", type="string", example="Chase Bank", description="The providers bank name"), | ||||||
|  |  *       @OA\Property(property="bank_account_id", type="integer", example="1233434", description="The bank account id"), | ||||||
|  |  *       @OA\Property(property="bank_account_name", type="string", example="My Checking Acc", description="The name of the account"), | ||||||
|  |  *       @OA\Property(property="bank_account_number", type="string", example="111 234 2332", description="The account number"), | ||||||
|  |  *       @OA\Property(property="bank_account_status", type="string", example="ACTIVE", description="The status of the bank account"), | ||||||
|  |  *       @OA\Property(property="bank_account_type", type="string", example="CREDITCARD", description="The type of account"), | ||||||
|  |  *       @OA\Property(property="balance", type="number", example="1000000", description="The current bank balance if available"), | ||||||
|  |  *       @OA\Property(property="currency", type="string", example="USD", description="iso_3166_3 code"), | ||||||
|  |  * ) | ||||||
|  |  */ | ||||||
							
								
								
									
										20
									
								
								app/Http/Controllers/OpenAPI/BankTransaction.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								app/Http/Controllers/OpenAPI/BankTransaction.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,20 @@ | |||||||
|  | <?php | ||||||
|  | /** | ||||||
|  |  * @OA\Schema( | ||||||
|  |  *   schema="BankTransaction", | ||||||
|  |  *   type="object", | ||||||
|  |  *       @OA\Property(property="id", type="string", example="AS3df3A", description="The bank integration hashed id"), | ||||||
|  |  *       @OA\Property(property="company_id", type="string", example="AS3df3A", description="The company hashed id"), | ||||||
|  |  *       @OA\Property(property="user_id", type="string", example="AS3df3A", description="The user hashed id"), | ||||||
|  |  *       @OA\Property(property="transaction_id", type="integer", example=343434, description="The id of the transaction"), | ||||||
|  |  *       @OA\Property(property="amount", type="number", example=10.00, description="The transaction amount"), | ||||||
|  |  *       @OA\Property(property="currency_id", type="string", example="1", description="The currency ID of the currency"), | ||||||
|  |  *       @OA\Property(property="account_type", type="string", example="creditCard", description="The account type"), | ||||||
|  |  *       @OA\Property(property="description", type="string", example="Potato purchases for kevin", description="The description of the transaction"), | ||||||
|  |  *       @OA\Property(property="category_id", type="integer", example=1, description="The category id"), | ||||||
|  |  *       @OA\Property(property="category_type", type="string", example="Expenses", description="The category description"), | ||||||
|  |  *       @OA\Property(property="base_type", type="string", example="CREDIT", description="Either CREDIT or DEBIT"), | ||||||
|  |  *       @OA\Property(property="date", type="string", example="2022-09-01", description="The date of the transaction"), | ||||||
|  |  *       @OA\Property(property="bank_account_id", type="integer", example="1", description="The ID number of the bank account"), | ||||||
|  |  * ) | ||||||
|  |  */ | ||||||
| @ -3,29 +3,28 @@ | |||||||
|  * @OA\Schema( |  * @OA\Schema( | ||||||
|  *   schema="ClientContact", |  *   schema="ClientContact", | ||||||
|  *   type="object", |  *   type="object", | ||||||
|  *       @OA\Property(property="id", type="string", example="Opnel5aKBz", description="_________"), |  *       @OA\Property(property="id", type="string", example="Opnel5aKBz", description="The hashed if of the contact"), | ||||||
|  *       @OA\Property(property="user_id", type="string", example="", description="__________"), |  *       @OA\Property(property="user_id", type="string", example="Opnel5aKBz", description="The hashed id of the user who created the contact"), | ||||||
|  *       @OA\Property(property="company_id", type="string", example="", description="________"), |  *       @OA\Property(property="company_id", type="string", example="Opnel5aKBz", description="The hashed id of the company"), | ||||||
|  *       @OA\Property(property="client_id", type="string", example="", description="________"), |  *       @OA\Property(property="client_id", type="string", example="Opnel5aKBz", description="The hashed id of the client"), | ||||||
|  *       @OA\Property(property="first_name", type="string", example="", description="________"), |  *       @OA\Property(property="first_name", type="string", example="John", description="The first name of the contact"), | ||||||
|  *       @OA\Property(property="last_name", type="string", example="", description="________"), |  *       @OA\Property(property="last_name", type="string", example="Doe", description="The last name of the contact"), | ||||||
|  *       @OA\Property(property="phone", type="string", example="", description="________"), |  *       @OA\Property(property="phone", type="string", example="555-152-4524", description="The phone number of the contact"), | ||||||
|  *       @OA\Property(property="custom_value1", type="string", example="", description="________"), |  *       @OA\Property(property="custom_value1", type="string", example="", description="A Custom field value"), | ||||||
|  *       @OA\Property(property="custom_value2", type="string", example="", description="________"), |  *       @OA\Property(property="custom_value2", type="string", example="", description="A Custom field value"), | ||||||
|  *       @OA\Property(property="custom_value3", type="string", example="", description="________"), |  *       @OA\Property(property="custom_value3", type="string", example="", description="A Custom field value"), | ||||||
|  *       @OA\Property(property="custom_value4", type="string", example="", description="________"), |  *       @OA\Property(property="custom_value4", type="string", example="", description="A Custom field value"), | ||||||
|  *       @OA\Property(property="email", type="string", example="", description="________"), |  *       @OA\Property(property="email", type="string", example="", description="The email of the contact"), | ||||||
|  *       @OA\Property(property="accepted_terms_version", type="string", example="", description="________"), |  *       @OA\Property(property="accepted_terms_version", type="string", example="A long set of ToS", description="The terms of service which the contact has accpeted"), | ||||||
|  *       @OA\Property(property="password", type="string", example="", description="________"), |  *       @OA\Property(property="password", type="string", example="*****", description="The hashed password of the contact"), | ||||||
|  *       @OA\Property(property="confirmation-code", type="string", example="", description="________"), |  *       @OA\Property(property="confirmation-code", type="string", example="333-sdjkh34gbasd", description="The confirmation code used to authenticate the contacts email address"), | ||||||
|  *       @OA\Property(property="token", type="string", example="", description="________"), |  *       @OA\Property(property="token", type="string", example="333-sdjkh34gbasd", description="A uuid based token."), | ||||||
|  *       @OA\Property(property="is_primary", type="boolean", example=true, description="________"), |  *       @OA\Property(property="is_primary", type="boolean", example=true, description="Defines is this contact is the primary contact for the client"), | ||||||
|  *       @OA\Property(property="confirmed", type="boolean", example=true, description="________"), |  *       @OA\Property(property="confirmed", type="boolean", example=true, description="Boolean value confirms the user has confirmed their account."), | ||||||
|  *       @OA\Property(property="is_locked", type="boolean", example=true, description="________"), |  *       @OA\Property(property="is_locked", type="boolean", example=true, description="Boolean value defines if the contact has been locked out."), | ||||||
|  *       @OA\Property(property="send_email", type="boolean", example=true, description="________"), |  *       @OA\Property(property="send_email", type="boolean", example=true, description="Boolean value determines is this contact should receive emails"), | ||||||
|  *       @OA\Property(property="failed_logins", type="number", format="integer", example="3", description="________"), |  *       @OA\Property(property="failed_logins", type="number", format="integer", example="3", description="The number of failed logins the contact has had"), | ||||||
|  *       @OA\Property(property="email_verified_at", type="number", format="integer", example="134341234234", description="________"), |  *       @OA\Property(property="email_verified_at", type="number", format="integer", example="134341234234", description="The date which the contact confirmed their email"), | ||||||
|  *       @OA\Property(property="paid_to_date", type="number", format="float", example="10.00", description="________"), |  | ||||||
|  *       @OA\Property(property="last_login", type="number", format="integer", example="134341234234", description="Timestamp"), |  *       @OA\Property(property="last_login", type="number", format="integer", example="134341234234", description="Timestamp"), | ||||||
|  *       @OA\Property(property="created_at", type="number", format="integer", example="134341234234", description="Timestamp"), |  *       @OA\Property(property="created_at", type="number", format="integer", example="134341234234", description="Timestamp"), | ||||||
|  *       @OA\Property(property="updated_at", type="number", format="integer", example="134341234234", description="Timestamp"), |  *       @OA\Property(property="updated_at", type="number", format="integer", example="134341234234", description="Timestamp"), | ||||||
|  | |||||||
| @ -3,13 +3,13 @@ | |||||||
|  * @OA\Schema( |  * @OA\Schema( | ||||||
|  *   schema="ClientGatewayToken", |  *   schema="ClientGatewayToken", | ||||||
|  *   type="object", |  *   type="object", | ||||||
|  *       @OA\Property(property="id", type="string", example="Opnel5aKBz", description="______"), |  *       @OA\Property(property="id", type="string", example="Opnel5aKBz", description="The hashed id of the client gateway token"), | ||||||
|  *       @OA\Property(property="company_id", type="string", example="2", description="______"), |  *       @OA\Property(property="company_id", type="string", example="2", description="The hashed id of the company"), | ||||||
|  *       @OA\Property(property="client_id", type="string", example="2", description="______"), |  *       @OA\Property(property="client_id", type="string", example="2", description="The hashed_id of the client"), | ||||||
|  *       @OA\Property(property="token", type="string", example="2", description="______"), |  *       @OA\Property(property="token", type="string", example="2", description="The payment token"), | ||||||
|  *       @OA\Property(property="routing_number", type="string", example="2", description="______"), |  *       @OA\Property(property="routing_number", type="string", example="2", description="THe bank account routing number"), | ||||||
|  *       @OA\Property(property="company_gateway_id", type="string", example="2", description="______"), |  *       @OA\Property(property="company_gateway_id", type="string", example="2", description="The hashed id of the company gateway"), | ||||||
|  *       @OA\Property(property="is_default", type="boolean", example="true", description="______"), |  *       @OA\Property(property="is_default", type="boolean", example="true", description="Flag determining if the token is the default payment method"), | ||||||
|  * |  * | ||||||
|  * ) |  * ) | ||||||
|  */ |  */ | ||||||
|  | |||||||
| @ -3,9 +3,9 @@ | |||||||
|  * @OA\Schema( |  * @OA\Schema( | ||||||
|  *   schema="Client", |  *   schema="Client", | ||||||
|  *   type="object", |  *   type="object", | ||||||
|  *       @OA\Property(property="id", type="string", example="Opnel5aKBz", description="_________"), |  *       @OA\Property(property="id", type="string", example="Opnel5aKBz", description="The hashed id of the client"), | ||||||
|  *       @OA\Property(property="user_id", type="string", example="", description="__________"), |  *       @OA\Property(property="user_id", type="string", example="", description="The hashed id of the user"), | ||||||
|  *       @OA\Property(property="company_id", type="string", example="", description="________"), |  *       @OA\Property(property="company_id", type="string", example="", description="The hashed id of the company"), | ||||||
|  *       @OA\Property( |  *       @OA\Property( | ||||||
|  *       	property="contacts", |  *       	property="contacts", | ||||||
|  *        	type="array", |  *        	type="array", | ||||||
| @ -13,35 +13,35 @@ | |||||||
|  *           	ref="#/components/schemas/ClientContact", |  *           	ref="#/components/schemas/ClientContact", | ||||||
|  *          ), |  *          ), | ||||||
|  *       ), |  *       ), | ||||||
|  *       @OA\Property(property="name", type="string", example="", description="________"), |  *       @OA\Property(property="name", type="string", example="Jims housekeeping", description="The client name"), | ||||||
|  *       @OA\Property(property="website", type="string", example="", description="________"), |  *       @OA\Property(property="website", type="string", example="www.jims.com", description="The client website"), | ||||||
|  *       @OA\Property(property="private_notes", type="string", example="", description="________"), |  *       @OA\Property(property="private_notes", type="string", example="These are very private notes", description="Private notes on the client"), | ||||||
|  *       @OA\Property(property="client_hash", type="string", example="", description="________"), |  *       @OA\Property(property="client_hash", type="string", example="asdfkjhk342hjhbfdvmnfb1", description="The client hash"), | ||||||
|  *       @OA\Property(property="industry_id", type="string", example="", description="________"), |  *       @OA\Property(property="industry_id", type="number", example="5", description="The industry id of the client"), | ||||||
|  *       @OA\Property(property="size_id", type="string", example="", description="________"), |  *       @OA\Property(property="size_id", type="number", example="2", description="The size id of the client"), | ||||||
|  *       @OA\Property(property="address1", type="string", example="", description="________"), |  *       @OA\Property(property="address1", type="string", example="", description="Address line 1"), | ||||||
|  *       @OA\Property(property="address2", type="string", example="", description="________"), |  *       @OA\Property(property="address2", type="string", example="", description="Address line 2"), | ||||||
|  *       @OA\Property(property="city", type="string", example="", description="________"), |  *       @OA\Property(property="city", type="string", example="Beverley Hills", description="City"), | ||||||
|  *       @OA\Property(property="state", type="string", example="", description="________"), |  *       @OA\Property(property="state", type="string", example="Californnia", description="State/Locality"), | ||||||
|  *       @OA\Property(property="postal_code", type="string", example="", description="________"), |  *       @OA\Property(property="postal_code", type="string", example="90210", description="Zip / Postal code"), | ||||||
|  *       @OA\Property(property="phone", type="string", example="555-3434-3434", description="The client phone number"), |  *       @OA\Property(property="phone", type="string", example="555-3434-3434", description="The client phone number"), | ||||||
|  *       @OA\Property(property="country_id", type="number", format="integer", example="1", description="________"), |  *       @OA\Property(property="country_id", type="number", format="integer", example="1", description="The client country id"), | ||||||
|  *       @OA\Property(property="custom_value1", type="string", example="", description="________"), |  *       @OA\Property(property="custom_value1", type="string", example="Something custom", description="A custom value"), | ||||||
|  *       @OA\Property(property="custom_value2", type="string", example="", description="________"), |  *       @OA\Property(property="custom_value2", type="string", example="2002-01-01", description="A custom value"), | ||||||
|  *       @OA\Property(property="custom_value3", type="string", example="", description="________"), |  *       @OA\Property(property="custom_value3", type="string", example="Something custom", description="A custom value"), | ||||||
|  *       @OA\Property(property="custom_value4", type="string", example="", description="________"), |  *       @OA\Property(property="custom_value4", type="string", example="Something custom", description="A custom value"), | ||||||
|  *       @OA\Property(property="vat_number", type="string", example="", description="________"), |  *       @OA\Property(property="vat_number", type="string", example="VAT123", description="The client VAT number"), | ||||||
|  *       @OA\Property(property="id_number", type="string", example="", description="________"), |  *       @OA\Property(property="id_number", type="string", example="CLIENT_ID_NUMBER", description=" The client id number"), | ||||||
|  *       @OA\Property(property="number", type="string", example="", description="________"), |  *       @OA\Property(property="number", type="string", example="", description="The client number - assigned by the system typically"), | ||||||
|  *       @OA\Property(property="shipping_address1", type="string", example="", description="________"), |  *       @OA\Property(property="shipping_address1", type="string", example="5 Wallaby Way", description="The shipping address line 1"), | ||||||
|  *       @OA\Property(property="shipping_address2", type="string", example="", description="________"), |  *       @OA\Property(property="shipping_address2", type="string", example="Suite 5", description="The shipping address line 2"), | ||||||
|  *       @OA\Property(property="shipping_city", type="string", example="", description="________"), |  *       @OA\Property(property="shipping_city", type="string", example="Perth", description="The shipping city"), | ||||||
|  *       @OA\Property(property="shipping_state", type="string", example="", description="________"), |  *       @OA\Property(property="shipping_state", type="string", example="Western Australia", description="The shipping state"), | ||||||
|  *       @OA\Property(property="shipping_postal_code", type="string", example="", description="________"), |  *       @OA\Property(property="shipping_postal_code", type="string", example="6110", description="The shipping postal code"), | ||||||
|  *       @OA\Property(property="shipping_country_id", type="number", format="integer", example="", description="________"), |  *       @OA\Property(property="shipping_country_id", type="number", format="integer", example="4", description="The shipping country id"), | ||||||
|  *       @OA\Property(property="is_deleted", type="boolean", example=true, description="________"), |  *       @OA\Property(property="is_deleted", type="boolean", example=true, description="Boolean flagged determining if the client has been deleted"), | ||||||
|  *       @OA\Property(property="balance", type="number", format="float", example="10.00", description="________"), |  *       @OA\Property(property="balance", type="number", format="float", example="10.00", description="The client balance"), | ||||||
|  *       @OA\Property(property="paid_to_date", type="number", format="float", example="10.00", description="________"), |  *       @OA\Property(property="paid_to_date", type="number", format="float", example="10.00", description="The amount the client has paid to date."), | ||||||
|  *       @OA\Property(property="credit_balance", type="number", format="float", example="10.00", description="An amount which is available to the client for future use."), |  *       @OA\Property(property="credit_balance", type="number", format="float", example="10.00", description="An amount which is available to the client for future use."), | ||||||
|  *       @OA\Property(property="last_login", type="number", format="integer", example="134341234234", description="Timestamp"), |  *       @OA\Property(property="last_login", type="number", format="integer", example="134341234234", description="Timestamp"), | ||||||
|  *       @OA\Property(property="created_at", type="number", format="integer", example="134341234234", description="Timestamp"), |  *       @OA\Property(property="created_at", type="number", format="integer", example="134341234234", description="Timestamp"), | ||||||
|  | |||||||
| @ -3,14 +3,14 @@ | |||||||
|  * @OA\Schema( |  * @OA\Schema( | ||||||
|  *   schema="CompanyGateway", |  *   schema="CompanyGateway", | ||||||
|  *   type="object", |  *   type="object", | ||||||
|  *       @OA\Property(property="id", type="string", example="Opnel5aKBz", description="______"), |  *       @OA\Property(property="id", type="string", example="Opnel5aKBz", description="The hashed id of the company gateway"), | ||||||
|  *       @OA\Property(property="company_id", type="string", example="2", description="______"), |  *       @OA\Property(property="company_id", type="string", example="2", description="The company hashed id"), | ||||||
|  *       @OA\Property(property="gateway_key", type="string", example="2", description="______"), |  *       @OA\Property(property="gateway_key", type="string", example="2", description="The gateway key (hash)"), | ||||||
|  *       @OA\Property(property="accepted_credit_cards", type="integer", example="32", description="Bitmask representation of cards"), |  *       @OA\Property(property="accepted_credit_cards", type="integer", example="32", description="Bitmask representation of cards"), | ||||||
|  *       @OA\Property(property="require_billing_address", type="boolean", example=true, description="______"), |  *       @OA\Property(property="require_billing_address", type="boolean", example=true, description="Determines if the the billing address is required prior to payment."), | ||||||
|  *       @OA\Property(property="require_shipping_address", type="boolean", example=true, description="______"), |  *       @OA\Property(property="require_shipping_address", type="boolean", example=true, description="Determines if the the billing address is required prior to payment."), | ||||||
|  *       @OA\Property(property="config", type="string", example="dfadsfdsafsafd", description="The configuration map for the gateway"), |  *       @OA\Property(property="config", type="string", example="dfadsfdsafsafd", description="The configuration map for the gateway"), | ||||||
|  *       @OA\Property(property="update_details", type="boolean", example=true, description="______"), |  *       @OA\Property(property="update_details", type="boolean", example=true, description="Determines if the client details should be updated."), | ||||||
|  *       @OA\Property( |  *       @OA\Property( | ||||||
|  *       	property="fees_and_limits", |  *       	property="fees_and_limits", | ||||||
|  *        	type="array", |  *        	type="array", | ||||||
|  | |||||||
| @ -17,9 +17,9 @@ | |||||||
|  *       @OA\Property(property="update_products", type="boolean", example=true, description="Toggles updating a product description which description changes"), |  *       @OA\Property(property="update_products", type="boolean", example=true, description="Toggles updating a product description which description changes"), | ||||||
|  *       @OA\Property(property="show_product_details", type="boolean", example=true, description="Toggles showing a product description which description changes"), |  *       @OA\Property(property="show_product_details", type="boolean", example=true, description="Toggles showing a product description which description changes"), | ||||||
|  *       @OA\Property(property="custom_fields", type="object", description="Custom fields map"), |  *       @OA\Property(property="custom_fields", type="object", description="Custom fields map"), | ||||||
|  *       @OA\Property(property="enable_product_cost", type="boolean", example=true, description="______________"), |  *       @OA\Property(property="enable_product_cost", type="boolean", example=true, description="Show/Hide the product cost field in the UI"), | ||||||
|  *       @OA\Property(property="enable_product_quantity", type="boolean", example=true, description="______________"), |  *       @OA\Property(property="enable_product_quantity", type="boolean", example=true, description="Show/hide the product quantity field (used in the UI to show the default quantity)"), | ||||||
|  *       @OA\Property(property="default_quantity", type="boolean", example=true, description="______________"), |  *       @OA\Property(property="default_quantity", type="boolean", example=true, description="Enable/Disable whether to use a default quantity"), | ||||||
|  *       @OA\Property(property="custom_surcharge_taxes1", type="boolean", example=true, description="Toggles charging taxes on custom surcharge amounts"), |  *       @OA\Property(property="custom_surcharge_taxes1", type="boolean", example=true, description="Toggles charging taxes on custom surcharge amounts"), | ||||||
|  *       @OA\Property(property="custom_surcharge_taxes2", type="boolean", example=true, description="Toggles charging taxes on custom surcharge amounts"), |  *       @OA\Property(property="custom_surcharge_taxes2", type="boolean", example=true, description="Toggles charging taxes on custom surcharge amounts"), | ||||||
|  *       @OA\Property(property="custom_surcharge_taxes3", type="boolean", example=true, description="Toggles charging taxes on custom surcharge amounts"), |  *       @OA\Property(property="custom_surcharge_taxes3", type="boolean", example=true, description="Toggles charging taxes on custom surcharge amounts"), | ||||||
|  | |||||||
| @ -4,20 +4,20 @@ | |||||||
|  *   schema="CompanySettings", |  *   schema="CompanySettings", | ||||||
|  *   type="object", |  *   type="object", | ||||||
|  *       @OA\Property(property="timezone_id", type="string", example="15", description="The timezone id"), |  *       @OA\Property(property="timezone_id", type="string", example="15", description="The timezone id"), | ||||||
|  *       @OA\Property(property="date_format_id", type="string", example="15", description="____________"), |  *       @OA\Property(property="date_format_id", type="string", example="15", description="The date format id"), | ||||||
|  *       @OA\Property(property="military_time", type="boolean", example=true, description="____________"), |  *       @OA\Property(property="military_time", type="boolean", example=true, description="Toggles 12/24 hour time"), | ||||||
|  *       @OA\Property(property="language_id", type="string", example="1", description="____________"), |  *       @OA\Property(property="language_id", type="string", example="1", description="The language id"), | ||||||
|  *       @OA\Property(property="show_currency_code", type="boolean", example=true, description="____________"), |  *       @OA\Property(property="show_currency_code", type="boolean", example=true, description="Toggles whether the currency symbol or code is shown"), | ||||||
|  *       @OA\Property(property="currency_id", type="string", example=true, description="The default currency id"), |  *       @OA\Property(property="currency_id", type="string", example=true, description="The default currency id"), | ||||||
|  *       @OA\Property(property="payment_terms", type="integer", example="1", description="-1 sets no payment term, 0 sets payment due immediately, positive integers indicates payment terms in days"), |  *       @OA\Property(property="payment_terms", type="integer", example="1", description="-1 sets no payment term, 0 sets payment due immediately, positive integers indicates payment terms in days"), | ||||||
|  *       @OA\Property(property="company_gateway_ids", type="string", example="1,2,3,4", description="A commad separate list of available gateways"), |  *       @OA\Property(property="company_gateway_ids", type="string", example="1,2,3,4", description="A commad separate list of available gateways"), | ||||||
|  *       @OA\Property(property="custom_value1", type="string", example="Custom Label", description="____________"), |  *       @OA\Property(property="custom_value1", type="string", example="Custom Label", description="A Custom Label"), | ||||||
|  *       @OA\Property(property="custom_value2", type="string", example="Custom Label", description="____________"), |  *       @OA\Property(property="custom_value2", type="string", example="Custom Label", description="A Custom Label"), | ||||||
|  *       @OA\Property(property="custom_value3", type="string", example="Custom Label", description="____________"), |  *       @OA\Property(property="custom_value3", type="string", example="Custom Label", description="A Custom Label"), | ||||||
|  *       @OA\Property(property="custom_value4", type="string", example="Custom Label", description="____________"), |  *       @OA\Property(property="custom_value4", type="string", example="Custom Label", description="A Custom Label"), | ||||||
|  *       @OA\Property(property="default_task_rate", type="number", format="float", example="10.00", description="____________"), |  *       @OA\Property(property="default_task_rate", type="number", format="float", example="10.00", description="The default task rate"), | ||||||
|  *       @OA\Property(property="send_reminders", type="boolean", example=true, description="____________"), |  *       @OA\Property(property="send_reminders", type="boolean", example=true, description="Toggles whether reminders are sent"), | ||||||
|  *       @OA\Property(property="enable_client_portal_tasks", type="boolean", example=true, description="____________"), |  *       @OA\Property(property="enable_client_portal_tasks", type="boolean", example=true, description="Show/hide the tasks panel in the client portal"), | ||||||
|  *       @OA\Property(property="email_style", type="string", example="light", description="options include plain,light,dark,custom"), |  *       @OA\Property(property="email_style", type="string", example="light", description="options include plain,light,dark,custom"), | ||||||
|  *       @OA\Property(property="reply_to_email", type="string", example="email@gmail.com", description="The reply to email address"), |  *       @OA\Property(property="reply_to_email", type="string", example="email@gmail.com", description="The reply to email address"), | ||||||
|  *       @OA\Property(property="bcc_email", type="string", example="email@gmail.com, contact@gmail.com", description="A comma separate list of BCC emails"), |  *       @OA\Property(property="bcc_email", type="string", example="email@gmail.com, contact@gmail.com", description="A comma separate list of BCC emails"), | ||||||
| @ -26,35 +26,35 @@ | |||||||
|  *       @OA\Property(property="email_style_custom", type="string", example="<HTML></HTML>", description="The custom template"), |  *       @OA\Property(property="email_style_custom", type="string", example="<HTML></HTML>", description="The custom template"), | ||||||
|  *       @OA\Property(property="counter_number_applied", type="string", example="when_sent", description="enum when the invoice number counter is set, ie when_saved, when_sent, when_paid"), |  *       @OA\Property(property="counter_number_applied", type="string", example="when_sent", description="enum when the invoice number counter is set, ie when_saved, when_sent, when_paid"), | ||||||
|  *       @OA\Property(property="quote_number_applied", type="string", example="when_sent", description="enum when the quote number counter is set, ie when_saved, when_sent"), |  *       @OA\Property(property="quote_number_applied", type="string", example="when_sent", description="enum when the quote number counter is set, ie when_saved, when_sent"), | ||||||
|  *       @OA\Property(property="custom_message_dashboard", type="string", example="Please pay invoices immediately", description="____________"), |  *       @OA\Property(property="custom_message_dashboard", type="string", example="Please pay invoices immediately", description="A custom message which is displayed on the dashboard"), | ||||||
|  *       @OA\Property(property="custom_message_unpaid_invoice", type="string", example="Please pay invoices immediately", description="____________"), |  *       @OA\Property(property="custom_message_unpaid_invoice", type="string", example="Please pay invoices immediately", description="A custom message which is displayed in the client portal when a client is viewing a unpaid invoice."), | ||||||
|  *       @OA\Property(property="custom_message_paid_invoice", type="string", example="Thanks for paying this invoice!", description="____________"), |  *       @OA\Property(property="custom_message_paid_invoice", type="string", example="Thanks for paying this invoice!", description="A custom message which is displayed in the client portal when a client is viewing a paid invoice."), | ||||||
|  *       @OA\Property(property="custom_message_unapproved_quote", type="string", example="Please approve quote", description="____________"), |  *       @OA\Property(property="custom_message_unapproved_quote", type="string", example="Please approve quote", description="A custom message which is displayed in the client portal when a client is viewing a unapproved quote."), | ||||||
|  *       @OA\Property(property="lock_invoices", type="boolean", example=true, description="____________"), |  *       @OA\Property(property="lock_invoices", type="boolean", example=true, description="Toggles whether invoices are locked once sent and cannot be modified further"), | ||||||
|  *       @OA\Property(property="auto_archive_invoice", type="boolean", example=true, description="____________"), |  *       @OA\Property(property="auto_archive_invoice", type="boolean", example=true, description="Toggles whether a invoice is archived immediately following payment"), | ||||||
|  *       @OA\Property(property="auto_archive_quote", type="boolean", example=true, description="____________"), |  *       @OA\Property(property="auto_archive_quote", type="boolean", example=true, description="Toggles whether a quote is archived after being converted to a invoice"), | ||||||
|  *       @OA\Property(property="auto_convert_quote", type="boolean", example=true, description="____________"), |  *       @OA\Property(property="auto_convert_quote", type="boolean", example=true, description="Toggles whether a quote is converted to a invoice when approved"), | ||||||
|  *       @OA\Property(property="inclusive_taxes", type="boolean", example=true, description="____________"), |  *       @OA\Property(property="inclusive_taxes", type="boolean", example=true, description="Boolean flag determining whether inclusive or exclusive taxes are used"), | ||||||
|  *       @OA\Property(property="translations", type="object", example="", description="JSON payload of customized translations"), |  *       @OA\Property(property="translations", type="object", example="", description="JSON payload of customized translations"), | ||||||
|  *       @OA\Property(property="task_number_pattern", type="string", example="{$year}-{$counter}", description="Allows customisation of the task number pattern"), |  *       @OA\Property(property="task_number_pattern", type="string", example="{$year}-{$counter}", description="Allows customisation of the task number pattern"), | ||||||
|  *       @OA\Property(property="task_number_counter", type="integer", example="1", description="____________"), |  *       @OA\Property(property="task_number_counter", type="integer", example="1", description="The incrementing counter for tasks"), | ||||||
|  *       @OA\Property(property="reminder_send_time", type="integer", example="32400", description="Time from UTC +0 when the email will be sent to the client"), |  *       @OA\Property(property="reminder_send_time", type="integer", example="32400", description="Time from UTC +0 when the email will be sent to the client"), | ||||||
|  *       @OA\Property(property="expense_number_pattern", type="string", example="{$year}-{$counter}", description="Allows customisation of the expense number pattern"), |  *       @OA\Property(property="expense_number_pattern", type="string", example="{$year}-{$counter}", description="Allows customisation of the expense number pattern"), | ||||||
|  *       @OA\Property(property="expense_number_counter", type="integer", example="1", description="____________"), |  *       @OA\Property(property="expense_number_counter", type="integer", example="1", description="The incrementing counter for expenses"), | ||||||
|  *       @OA\Property(property="vendor_number_pattern", type="string", example="{$year}-{$counter}", description="Allows customisation of the vendor number pattern"), |  *       @OA\Property(property="vendor_number_pattern", type="string", example="{$year}-{$counter}", description="Allows customisation of the vendor number pattern"), | ||||||
|  *       @OA\Property(property="vendor_number_counter", type="integer", example="1", description="____________"), |  *       @OA\Property(property="vendor_number_counter", type="integer", example="1", description="The incrementing counter for vendors"), | ||||||
|  *       @OA\Property(property="ticket_number_pattern", type="string", example="{$year}-{$counter}", description="Allows customisation of the ticket number pattern"), |  *       @OA\Property(property="ticket_number_pattern", type="string", example="{$year}-{$counter}", description="Allows customisation of the ticket number pattern"), | ||||||
|  *       @OA\Property(property="ticket_number_counter", type="integer", example="1", description="____________"), |  *       @OA\Property(property="ticket_number_counter", type="integer", example="1", description="The incrementing counter for tickets"), | ||||||
|  *       @OA\Property(property="payment_number_pattern", type="string", example="{$year}-{$counter}", description="Allows customisation of the payment number pattern"), |  *       @OA\Property(property="payment_number_pattern", type="string", example="{$year}-{$counter}", description="Allows customisation of the payment number pattern"), | ||||||
|  *       @OA\Property(property="payment_number_counter", type="integer", example="1", description="____________"), |  *       @OA\Property(property="payment_number_counter", type="integer", example="1", description="The incrementing counter for payments"), | ||||||
|  *       @OA\Property(property="invoice_number_pattern", type="string", example="{$year}-{$counter}", description="Allows customisation of the invoice number pattern"), |  *       @OA\Property(property="invoice_number_pattern", type="string", example="{$year}-{$counter}", description="Allows customisation of the invoice number pattern"), | ||||||
|  *       @OA\Property(property="invoice_number_counter", type="integer", example="1", description="____________"), |  *       @OA\Property(property="invoice_number_counter", type="integer", example="1", description="The incrementing counter for invoices"), | ||||||
|  *       @OA\Property(property="quote_number_pattern", type="string", example="{$year}-{$counter}", description="Allows customisation of the quote number pattern"), |  *       @OA\Property(property="quote_number_pattern", type="string", example="{$year}-{$counter}", description="Allows customisation of the quote number pattern"), | ||||||
|  *       @OA\Property(property="quote_number_counter", type="integer", example="1", description="____________"), |  *       @OA\Property(property="quote_number_counter", type="integer", example="1", description="The incrementing counter for quotes"), | ||||||
|  *       @OA\Property(property="client_number_pattern", type="string", example="{$year}-{$counter}", description="Allows customisation of the client number pattern"), |  *       @OA\Property(property="client_number_pattern", type="string", example="{$year}-{$counter}", description="Allows customisation of the client number pattern"), | ||||||
|  *       @OA\Property(property="client_number_counter", type="integer", example="1", description="____________"), |  *       @OA\Property(property="client_number_counter", type="integer", example="1", description="The incrementing counter for clients"), | ||||||
|  *       @OA\Property(property="credit_number_pattern", type="string", example="{$year}-{$counter}", description="Allows customisation of the credit number pattern"), |  *       @OA\Property(property="credit_number_pattern", type="string", example="{$year}-{$counter}", description="Allows customisation of the credit number pattern"), | ||||||
|  *       @OA\Property(property="credit_number_counter", type="integer", example="1", description="____________"), |  *       @OA\Property(property="credit_number_counter", type="integer", example="1", description="The incrementing counter for credits"), | ||||||
|  *       @OA\Property(property="recurring_invoice_number_prefix", type="string", example="R", description="This string is prepended to the recurring invoice number"), |  *       @OA\Property(property="recurring_invoice_number_prefix", type="string", example="R", description="This string is prepended to the recurring invoice number"), | ||||||
|  *       @OA\Property(property="reset_counter_frequency_id", type="integer", example="1", description="CONSTANT which is used to apply the frequency which the counters are reset"), |  *       @OA\Property(property="reset_counter_frequency_id", type="integer", example="1", description="CONSTANT which is used to apply the frequency which the counters are reset"), | ||||||
|  *       @OA\Property(property="reset_counter_date", type="string", example="2019-01-01", description="The explicit date which is used to reset counters"), |  *       @OA\Property(property="reset_counter_date", type="string", example="2019-01-01", description="The explicit date which is used to reset counters"), | ||||||
| @ -103,52 +103,52 @@ | |||||||
|  *       @OA\Property(property="name", type="string", example="Acme Co", description="The company name"), |  *       @OA\Property(property="name", type="string", example="Acme Co", description="The company name"), | ||||||
|  *       @OA\Property(property="company_logo", type="object", example="logo.png", description="The company logo file"), |  *       @OA\Property(property="company_logo", type="object", example="logo.png", description="The company logo file"), | ||||||
|  *       @OA\Property(property="website", type="string", example="www.acme.com", description="The company website URL"), |  *       @OA\Property(property="website", type="string", example="www.acme.com", description="The company website URL"), | ||||||
|  *       @OA\Property(property="address1", type="string", example="Suite 888", description="____________"), |  *       @OA\Property(property="address1", type="string", example="Suite 888", description="The company address line 1"), | ||||||
|  *       @OA\Property(property="address2", type="string", example="5 Jimbo Way", description="____________"), |  *       @OA\Property(property="address2", type="string", example="5 Jimbo Way", description="The company address line 2"), | ||||||
|  *       @OA\Property(property="city", type="string", example="Sydney", description="____________"), |  *       @OA\Property(property="city", type="string", example="Sydney", description="The company city"), | ||||||
|  *       @OA\Property(property="state", type="string", example="Florisa", description="____________"), |  *       @OA\Property(property="state", type="string", example="Florisa", description="The company state"), | ||||||
|  *       @OA\Property(property="postal_code", type="string", example="90210", description="____________"), |  *       @OA\Property(property="postal_code", type="string", example="90210", description="The company zip/postal code"), | ||||||
|  *       @OA\Property(property="phone", type="string", example="555-213-3948", description="____________"), |  *       @OA\Property(property="phone", type="string", example="555-213-3948", description="The company phone"), | ||||||
|  *       @OA\Property(property="email", type="string", example="joe@acme.co", description="____________"), |  *       @OA\Property(property="email", type="string", example="joe@acme.co", description="The company email"), | ||||||
|  *       @OA\Property(property="country_id", type="string", example="1", description="The country ID"), |  *       @OA\Property(property="country_id", type="string", example="1", description="The country ID"), | ||||||
|  *       @OA\Property(property="vat_number", type="string", example="32 120 377 720", description="____________"), |  *       @OA\Property(property="vat_number", type="string", example="32 120 377 720", description="The company VAT/TAX ID number"), | ||||||
|  *       @OA\Property(property="page_size", type="string", example="A4", description="The default page size"), |  *       @OA\Property(property="page_size", type="string", example="A4", description="The default page size"), | ||||||
|  *       @OA\Property(property="font_size", type="number", example="9", description="The font size"), |  *       @OA\Property(property="font_size", type="number", example="9", description="The font size"), | ||||||
|  *       @OA\Property(property="primary_font", type="string", example="roboto", description="The primary font"), |  *       @OA\Property(property="primary_font", type="string", example="roboto", description="The primary font"), | ||||||
|  *       @OA\Property(property="secondary_font", type="string", example="roboto", description="The secondary font"), |  *       @OA\Property(property="secondary_font", type="string", example="roboto", description="The secondary font"), | ||||||
|  *       @OA\Property(property="hide_paid_to_date", type="boolean", example=false, description="____________"), |  *       @OA\Property(property="hide_paid_to_date", type="boolean", example=false, description="Flags whether to hide the paid to date field"), | ||||||
|  *       @OA\Property(property="embed_documents", type="boolean", example=false, description="____________"), |  *       @OA\Property(property="embed_documents", type="boolean", example=false, description="Toggled whether to embed documents in the PDF"), | ||||||
|  *       @OA\Property(property="all_pages_header", type="boolean", example=false, description="____________"), |  *       @OA\Property(property="all_pages_header", type="boolean", example=false, description="The header for the PDF"), | ||||||
|  *       @OA\Property(property="all_pages_footer", type="boolean", example=false, description="____________"), |  *       @OA\Property(property="all_pages_footer", type="boolean", example=false, description="The footer for the PDF"), | ||||||
|  *       @OA\Property(property="document_email_attachment", type="boolean", example=false, description="____________"), |  *       @OA\Property(property="document_email_attachment", type="boolean", example=false, description="Toggles whether to attach documents in the email"), | ||||||
|  *       @OA\Property(property="enable_client_portal_password", type="boolean", example=false, description="____________"), |  *       @OA\Property(property="enable_client_portal_password", type="boolean", example=false, description="Toggles password protection of the client portal"), | ||||||
|  *       @OA\Property(property="enable_email_markup", type="boolean", example=false, description="____________"), |  *       @OA\Property(property="enable_email_markup", type="boolean", example=false, description="Toggles the use of markdown in emails"), | ||||||
|  *       @OA\Property(property="enable_client_portal_dashboard", type="boolean", example=false, description="____________"), |  *       @OA\Property(property="enable_client_portal_dashboard", type="boolean", example=false, description="Toggles whether the client dashboard is shown in the client portal"), | ||||||
|  *       @OA\Property(property="enable_client_portal", type="boolean", example=false, description="____________"), |  *       @OA\Property(property="enable_client_portal", type="boolean", example=false, description="Toggles whether the entire client portal is displayed to the client, or only the context"), | ||||||
|  *       @OA\Property(property="email_template_statement", type="string", example="template matter", description="____________"), |  *       @OA\Property(property="email_template_statement", type="string", example="template matter", description="The body of the email for statements"), | ||||||
|  *       @OA\Property(property="email_subject_statement", type="string", example="subject matter", description="____________"), |  *       @OA\Property(property="email_subject_statement", type="string", example="subject matter", description="The subject of the email for statements"), | ||||||
|  *       @OA\Property(property="signature_on_pdf", type="boolean", example=false, description="____________"), |  *       @OA\Property(property="signature_on_pdf", type="boolean", example=false, description="Toggles whether the signature (if available) is displayed on the PDF"), | ||||||
|  *       @OA\Property(property="quote_footer", type="string", example="the quote footer", description="____________"), |  *       @OA\Property(property="quote_footer", type="string", example="the quote footer", description="The default quote footer"), | ||||||
|  *       @OA\Property(property="email_subject_custom1", type="string", example="Custom Subject 1", description="____________"), |  *       @OA\Property(property="email_subject_custom1", type="string", example="Custom Subject 1", description="Custom reminder template subject"), | ||||||
|  *       @OA\Property(property="email_subject_custom2", type="string", example="Custom Subject 2", description="____________"), |  *       @OA\Property(property="email_subject_custom2", type="string", example="Custom Subject 2", description="Custom reminder template subject"), | ||||||
|  *       @OA\Property(property="email_subject_custom3", type="string", example="Custom Subject 3", description="____________"), |  *       @OA\Property(property="email_subject_custom3", type="string", example="Custom Subject 3", description="Custom reminder template subject"), | ||||||
|  *       @OA\Property(property="email_template_custom1", type="string", example="<HTML>", description="____________"), |  *       @OA\Property(property="email_template_custom1", type="string", example="<HTML>", description="Custom reminder template body"), | ||||||
|  *       @OA\Property(property="email_template_custom2", type="string", example="<HTML>", description="____________"), |  *       @OA\Property(property="email_template_custom2", type="string", example="<HTML>", description="Custom reminder template body"), | ||||||
|  *       @OA\Property(property="email_template_custom3", type="string", example="<HTML>", description="____________"), |  *       @OA\Property(property="email_template_custom3", type="string", example="<HTML>", description="Custom reminder template body"), | ||||||
|  *       @OA\Property(property="enable_reminder1", type="boolean", example=false, description="____________"), |  *       @OA\Property(property="enable_reminder1", type="boolean", example=false, description="Toggles whether this reminder is enabled"), | ||||||
|  *       @OA\Property(property="enable_reminder2", type="boolean", example=false, description="____________"), |  *       @OA\Property(property="enable_reminder2", type="boolean", example=false, description="Toggles whether this reminder is enabled"), | ||||||
|  *       @OA\Property(property="enable_reminder3", type="boolean", example=false, description="____________"), |  *       @OA\Property(property="enable_reminder3", type="boolean", example=false, description="Toggles whether this reminder is enabled"), | ||||||
|  *       @OA\Property(property="num_days_reminder1", type="number", example="9", description="The Reminder interval"), |  *       @OA\Property(property="num_days_reminder1", type="number", example="9", description="The Reminder interval"), | ||||||
|  *       @OA\Property(property="num_days_reminder2", type="number", example="9", description="The Reminder interval"), |  *       @OA\Property(property="num_days_reminder2", type="number", example="9", description="The Reminder interval"), | ||||||
|  *       @OA\Property(property="num_days_reminder3", type="number", example="9", description="The Reminder interval"), |  *       @OA\Property(property="num_days_reminder3", type="number", example="9", description="The Reminder interval"), | ||||||
|  *       @OA\Property(property="schedule_reminder1", type="string", example="after_invoice_date", description="(enum: after_invoice_date, before_due_date, after_due_date)"), |  *       @OA\Property(property="schedule_reminder1", type="string", example="after_invoice_date", description="(enum: after_invoice_date, before_due_date, after_due_date)"), | ||||||
|  *       @OA\Property(property="schedule_reminder2", type="string", example="after_invoice_date", description="(enum: after_invoice_date, before_due_date, after_due_date)"), |  *       @OA\Property(property="schedule_reminder2", type="string", example="after_invoice_date", description="(enum: after_invoice_date, before_due_date, after_due_date)"), | ||||||
|  *       @OA\Property(property="schedule_reminder3", type="string", example="after_invoice_date", description="(enum: after_invoice_date, before_due_date, after_due_date)"), |  *       @OA\Property(property="schedule_reminder3", type="string", example="after_invoice_date", description="(enum: after_invoice_date, before_due_date, after_due_date)"), | ||||||
|  *       @OA\Property(property="late_fee_amount1", type="number", example=10.00, description="____________"), |  *       @OA\Property(property="late_fee_amount1", type="number", example=10.00, description="The late fee amount for reminder 1"), | ||||||
|  *       @OA\Property(property="late_fee_amount2", type="number", example=20.00, description="____________"), |  *       @OA\Property(property="late_fee_amount2", type="number", example=20.00, description="The late fee amount for reminder 2"), | ||||||
|  *       @OA\Property(property="late_fee_amount3", type="number", example=100.00, description="____________"), |  *       @OA\Property(property="late_fee_amount3", type="number", example=100.00, description="The late fee amount for reminder 2"), | ||||||
|  *       @OA\Property(property="endless_reminder_frequency_id", type="string", example="1", description="____________"), |  *       @OA\Property(property="endless_reminder_frequency_id", type="string", example="1", description="The frequency id of the endless reminder"), | ||||||
|  *       @OA\Property(property="client_online_payment_notification", type="boolean", example=false, description="____________"), |  *       @OA\Property(property="client_online_payment_notification", type="boolean", example=false, description="Determines if a client should receive the notification for a online payment"), | ||||||
|  *       @OA\Property(property="client_manual_payment_notification", type="boolean", example=false, description="____________"), |  *       @OA\Property(property="client_manual_payment_notification", type="boolean", example=false, description="Determines if a client should receive the notification for a manually entered payment"), | ||||||
|  * ) |  * ) | ||||||
|  */ |  */ | ||||||
|  | |||||||
| @ -3,8 +3,8 @@ | |||||||
|  * @OA\Schema( |  * @OA\Schema( | ||||||
|  *   schema="CreditPaymentable", |  *   schema="CreditPaymentable", | ||||||
|  *   type="object", |  *   type="object", | ||||||
|  *       @OA\Property(property="credit_id", type="string", example="Opnel5aKBz", description="______"), |  *       @OA\Property(property="credit_id", type="string", example="Opnel5aKBz", description="The credit hashed id"), | ||||||
|  *       @OA\Property(property="amount", type="string", example="2", description="______"), |  *       @OA\Property(property="amount", type="string", example="2", description="The credit amount"), | ||||||
|  * |  * | ||||||
|  * ) |  * ) | ||||||
|  */ |  */ | ||||||
|  | |||||||
| @ -3,33 +3,33 @@ | |||||||
|  * @OA\Schema( |  * @OA\Schema( | ||||||
|  *   schema="Credit", |  *   schema="Credit", | ||||||
|  *   type="object", |  *   type="object", | ||||||
|  *       @OA\Property(property="id", type="string", example="Opnel5aKBz", description="_________"), |  *       @OA\Property(property="id", type="string", example="Opnel5aKBz", description="The credit hashed id"), | ||||||
|  *       @OA\Property(property="user_id", type="string", example="", description="__________"), |  *       @OA\Property(property="user_id", type="string", example="", description="The user hashed id"), | ||||||
|  *       @OA\Property(property="assigned_user_id", type="string", example="", description="__________"), |  *       @OA\Property(property="assigned_user_id", type="string", example="", description="The assigned user hashed id"), | ||||||
|  *       @OA\Property(property="company_id", type="string", example="", description="________"), |  *       @OA\Property(property="company_id", type="string", example="", description="The company hashed id"), | ||||||
|  *       @OA\Property(property="client_id", type="string", example="", description="________"), |  *       @OA\Property(property="client_id", type="string", example="", description="The client hashed id"), | ||||||
|  *       @OA\Property(property="status_id", type="string", example="", description="________"), |  *       @OA\Property(property="status_id", type="string", example="", description="The status field id infors of the current status of the credit"), | ||||||
|  *       @OA\Property(property="invoice_id", type="string", example="", description="The linked invoice this credit is applied to"), |  *       @OA\Property(property="invoice_id", type="string", example="", description="The linked invoice this credit is applied to"), | ||||||
|  *       @OA\Property(property="number", type="string", example="QUOTE_101", description="The credit number - is a unique alpha numeric number per credit per company"), |  *       @OA\Property(property="number", type="string", example="QUOTE_101", description="The credit number - is a unique alpha numeric number per credit per company"), | ||||||
|  *       @OA\Property(property="po_number", type="string", example="", description="________"), |  *       @OA\Property(property="po_number", type="string", example="", description="The purchase order number this credit refers to"), | ||||||
|  *       @OA\Property(property="terms", type="string", example="", description="________"), |  *       @OA\Property(property="terms", type="string", example="", description="The credit terms field"), | ||||||
|  *       @OA\Property(property="public_notes", type="string", example="", description="________"), |  *       @OA\Property(property="public_notes", type="string", example="", description="The public notes field of the credit"), | ||||||
|  *       @OA\Property(property="private_notes", type="string", example="", description="________"), |  *       @OA\Property(property="private_notes", type="string", example="", description="The private notes field of the credit"), | ||||||
|  *       @OA\Property(property="footer", type="string", example="", description="________"), |  *       @OA\Property(property="footer", type="string", example="", description="The credit footer text"), | ||||||
|  *       @OA\Property(property="custom_value1", type="string", example="", description="________"), |  *       @OA\Property(property="custom_value1", type="string", example="", description="A Custom value"), | ||||||
|  *       @OA\Property(property="custom_value2", type="string", example="", description="________"), |  *       @OA\Property(property="custom_value2", type="string", example="", description="A Custom value"), | ||||||
|  *       @OA\Property(property="custom_value3", type="string", example="", description="________"), |  *       @OA\Property(property="custom_value3", type="string", example="", description="A Custom value"), | ||||||
|  *       @OA\Property(property="custom_value4", type="string", example="", description="________"), |  *       @OA\Property(property="custom_value4", type="string", example="", description="A Custom value"), | ||||||
|  *       @OA\Property(property="tax_name1", type="string", example="", description="________"), |  *       @OA\Property(property="tax_name1", type="string", example="", description="The tax name"), | ||||||
|  *       @OA\Property(property="tax_name2", type="string", example="", description="________"), |  *       @OA\Property(property="tax_name2", type="string", example="", description="The tax rate"), | ||||||
|  *       @OA\Property(property="tax_rate1", type="number", format="float", example="10.00", description="_________"), |  *       @OA\Property(property="tax_rate1", type="number", format="float", example="10.00", description="The tax name"), | ||||||
|  *       @OA\Property(property="tax_rate2", type="number", format="float", example="10.00", description="_________"), |  *       @OA\Property(property="tax_rate2", type="number", format="float", example="10.00", description="The tax rate"), | ||||||
|  *       @OA\Property(property="tax_name3", type="string", example="", description="________"), |  *       @OA\Property(property="tax_name3", type="string", example="", description="The tax name"), | ||||||
|  *       @OA\Property(property="tax_rate3", type="number", format="float", example="10.00", description="_________"), |  *       @OA\Property(property="tax_rate3", type="number", format="float", example="10.00", description="The tax rate"), | ||||||
|  *       @OA\Property(property="total_taxes", type="number", format="float", example="10.00", description="The total taxes for the credit"), |  *       @OA\Property(property="total_taxes", type="number", format="float", example="10.00", description="The total taxes for the credit"), | ||||||
|  *       @OA\Property(property="line_items", type="object", example="", description="_________"), |  *       @OA\Property(property="line_items", type="object", example="", description="The line items array containing the line items of the credit"), | ||||||
|  *       @OA\Property(property="amount", type="number", format="float", example="10.00", description="_________"), |  *       @OA\Property(property="amount", type="number", format="float", example="10.00", description="The total credit amount"), | ||||||
|  *       @OA\Property(property="balance", type="number", format="float", example="10.00", description="_________"), |  *       @OA\Property(property="balance", type="number", format="float", example="10.00", description="The credit balance"), | ||||||
|  *       @OA\Property(property="paid_to_date", type="number", format="float", example="10.00", description="_________"), |  *       @OA\Property(property="paid_to_date", type="number", format="float", example="10.00", description="_________"), | ||||||
|  *       @OA\Property(property="discount", type="number", format="float", example="10.00", description="_________"), |  *       @OA\Property(property="discount", type="number", format="float", example="10.00", description="_________"), | ||||||
|  *       @OA\Property(property="partial", type="number", format="float", example="10.00", description="_________"), |  *       @OA\Property(property="partial", type="number", format="float", example="10.00", description="_________"), | ||||||
|  | |||||||
| @ -3,18 +3,18 @@ | |||||||
|  * @OA\Schema( |  * @OA\Schema( | ||||||
|  *   schema="Document", |  *   schema="Document", | ||||||
|  *   type="object", |  *   type="object", | ||||||
|  *       @OA\Property(property="id", type="string", example="AS3df3A", description="The design hashed id"), |  *       @OA\Property(property="id", type="string", example="AS3df3A", description="The document hashed id"), | ||||||
|  *       @OA\Property(property="user_id", type="string", example="", description="__________"), |  *       @OA\Property(property="user_id", type="string", example="", description="The user hashed id"), | ||||||
|  *       @OA\Property(property="assigned_user_id", type="string", example="", description="__________"), |  *       @OA\Property(property="assigned_user_id", type="string", example="", description="The assigned user hashed id"), | ||||||
|  *       @OA\Property(property="project_id", type="string", example="", description="__________"), |  *       @OA\Property(property="project_id", type="string", example="", description="The project associated with this document"), | ||||||
|  *       @OA\Property(property="vendor_id", type="string", example="", description="__________"), |  *       @OA\Property(property="vendor_id", type="string", example="", description="The vendor associated with this documents"), | ||||||
|  *       @OA\Property(property="name", type="string", example="Beauty", description="The design name"), |  *       @OA\Property(property="name", type="string", example="Beauty", description="The document name"), | ||||||
|  *       @OA\Property(property="url", type="string", example="Beauty", description="The design name"), |  *       @OA\Property(property="url", type="string", example="Beauty", description="The document url"), | ||||||
|  *       @OA\Property(property="preview", type="string", example="Beauty", description="The design name"), |  *       @OA\Property(property="preview", type="string", example="Beauty", description="The document preview url"), | ||||||
|  *       @OA\Property(property="type", type="string", example="Beauty", description="The design name"), |  *       @OA\Property(property="type", type="string", example="Beauty", description="The document type"), | ||||||
|  *       @OA\Property(property="disk", type="string", example="Beauty", description="The design name"), |  *       @OA\Property(property="disk", type="string", example="Beauty", description="The document disk"), | ||||||
|  *       @OA\Property(property="hash", type="string", example="Beauty", description="The design name"), |  *       @OA\Property(property="hash", type="string", example="Beauty", description="The document hashed"), | ||||||
|  *       @OA\Property(property="is_deleted", type="boolean", example=true, description="Flag to determine if the design is deleted"), |  *       @OA\Property(property="is_deleted", type="boolean", example=true, description="Flag to determine if the document is deleted"), | ||||||
|  *       @OA\Property(property="is_default", type="boolean", example=true, description="Flag to determine if the document is a default doc"), |  *       @OA\Property(property="is_default", type="boolean", example=true, description="Flag to determine if the document is a default doc"), | ||||||
|  *       @OA\Property(property="created_at", type="number", format="integer", example="134341234234", description="Timestamp"), |  *       @OA\Property(property="created_at", type="number", format="integer", example="134341234234", description="Timestamp"), | ||||||
|  *       @OA\Property(property="updated_at", type="number", format="integer", example="134341234234", description="Timestamp"), |  *       @OA\Property(property="updated_at", type="number", format="integer", example="134341234234", description="Timestamp"), | ||||||
|  | |||||||
| @ -3,11 +3,11 @@ | |||||||
|  * @OA\Schema( |  * @OA\Schema( | ||||||
|  *   schema="ExpenseCategory", |  *   schema="ExpenseCategory", | ||||||
|  *   type="object", |  *   type="object", | ||||||
|  *       @OA\Property(property="id", type="string", example="Opnel5aKBz", description="______"), |  *       @OA\Property(property="id", type="string", example="Opnel5aKBz", description="The expense hashed id"), | ||||||
|  *       @OA\Property(property="name", type="string", example="Accounting", description="______"), |  *       @OA\Property(property="name", type="string", example="Accounting", description="The expense category name"), | ||||||
|  *       @OA\Property(property="user_id", type="string", example="XS987sD", description="______"), |  *       @OA\Property(property="user_id", type="string", example="XS987sD", description="The user hashed id"), | ||||||
|  *       @OA\Property(property="is_deleted", type="boolean", example=true, description="______"), |  *       @OA\Property(property="is_deleted", type="boolean", example=true, description="Flag determining whether the expense category has been deleted"), | ||||||
|  *       @OA\Property(property="updated_at", type="string", example="2", description="______"), |  *       @OA\Property(property="updated_at", type="integer", example="2", description="The updated at timestamp"), | ||||||
|  *       @OA\Property(property="created_at", type="string", example="2", description="______"), |  *       @OA\Property(property="created_at", type="integer", example="2", description="The created at timestamp"), | ||||||
|  * ) |  * ) | ||||||
|  */ |  */ | ||||||
|  | |||||||
| @ -3,40 +3,40 @@ | |||||||
|  * @OA\Schema( |  * @OA\Schema( | ||||||
|  *   schema="Expense", |  *   schema="Expense", | ||||||
|  *   type="object", |  *   type="object", | ||||||
|  *       @OA\Property(property="id", type="string", example="Opnel5aKBz", description="_________"), |  *       @OA\Property(property="id", type="string", example="Opnel5aKBz", description="The expense hashed id"), | ||||||
|  *       @OA\Property(property="user_id", type="string", example="", description="__________"), |  *       @OA\Property(property="user_id", type="string", example="", description="The user hashed id"), | ||||||
|  *       @OA\Property(property="assigned_user_id", type="string", example="", description="__________"), |  *       @OA\Property(property="assigned_user_id", type="string", example="", description="The assigned user hashed id"), | ||||||
|  *       @OA\Property(property="company_id", type="string", example="", description="________"), |  *       @OA\Property(property="company_id", type="string", example="", description="The company hashed id"), | ||||||
|  *       @OA\Property(property="client_id", type="string", example="", description="________"), |  *       @OA\Property(property="client_id", type="string", example="", description="The client hashed id"), | ||||||
|  *       @OA\Property(property="invoice_id", type="string", example="", description="________"), |  *       @OA\Property(property="invoice_id", type="string", example="", description="The related invoice hashed id"), | ||||||
|  *       @OA\Property(property="bank_id", type="string", example="", description="________"), |  *       @OA\Property(property="bank_id", type="string", example="", description="The bank id related to this expense"), | ||||||
|  *       @OA\Property(property="invoice_currency_id", type="string", example="", description="________"), |  *       @OA\Property(property="invoice_currency_id", type="string", example="", description="The currency id of the related invoice"), | ||||||
|  *       @OA\Property(property="expense_currency_id", type="string", example="", description="________"), |  *       @OA\Property(property="expense_currency_id", type="string", example="", description="The currency id of the expense"), | ||||||
|  *       @OA\Property(property="invoice_category_id", type="string", example="", description="________"), |  *       @OA\Property(property="invoice_category_id", type="string", example="", description="The invoice category id"), | ||||||
|  *       @OA\Property(property="payment_type_id", type="string", example="", description="________"), |  *       @OA\Property(property="payment_type_id", type="string", example="", description="The payment type id"), | ||||||
|  *       @OA\Property(property="recurring_expense_id", type="string", example="", description="________"), |  *       @OA\Property(property="recurring_expense_id", type="string", example="", description="The related recurring expense this expense was created from"), | ||||||
|  *       @OA\Property(property="private_notes", type="string", example="", description="________"), |  *       @OA\Property(property="private_notes", type="string", example="", description="The private notes of the expense"), | ||||||
|  *       @OA\Property(property="public_notes", type="string", example="", description="________"), |  *       @OA\Property(property="public_notes", type="string", example="", description="The public notes of the expense"), | ||||||
|  *       @OA\Property(property="transaction_reference", type="string", example="", description="________"), |  *       @OA\Property(property="transaction_reference", type="string", example="", description="The transaction references of the expense"), | ||||||
|  *       @OA\Property(property="transcation_id", type="string", example="", description="________"), |  *       @OA\Property(property="transcation_id", type="string", example="", description="The transaction id of the expense"), | ||||||
|  *       @OA\Property(property="custom_value1", type="string", example="", description="________"), |  *       @OA\Property(property="custom_value1", type="string", example="", description="A custom value"), | ||||||
|  *       @OA\Property(property="custom_value2", type="string", example="", description="________"), |  *       @OA\Property(property="custom_value2", type="string", example="", description="A custom value"), | ||||||
|  *       @OA\Property(property="custom_value3", type="string", example="", description="________"), |  *       @OA\Property(property="custom_value3", type="string", example="", description="A custom value"), | ||||||
|  *       @OA\Property(property="custom_value4", type="string", example="", description="________"), |  *       @OA\Property(property="custom_value4", type="string", example="", description="A custom value"), | ||||||
|  *       @OA\Property(property="tax_name1", type="string", example="", description="________"), |  *       @OA\Property(property="tax_name1", type="string", example="", description="Tax name"), | ||||||
|  *       @OA\Property(property="tax_name2", type="string", example="", description="________"), |  *       @OA\Property(property="tax_name2", type="string", example="", description="Tax name"), | ||||||
|  *       @OA\Property(property="tax_rate1", type="number", format="float", example="10.00", description="_________"), |  *       @OA\Property(property="tax_rate1", type="number", format="float", example="10.00", description="Tax rate"), | ||||||
|  *       @OA\Property(property="tax_rate2", type="number", format="float", example="10.00", description="_________"), |  *       @OA\Property(property="tax_rate2", type="number", format="float", example="10.00", description="Tax rate"), | ||||||
|  *       @OA\Property(property="tax_name3", type="string", example="", description="________"), |  *       @OA\Property(property="tax_name3", type="string", example="", description="Tax name"), | ||||||
|  *       @OA\Property(property="tax_rate3", type="number", format="float", example="10.00", description="_________"), |  *       @OA\Property(property="tax_rate3", type="number", format="float", example="10.00", description="Tax rate"), | ||||||
|  *       @OA\Property(property="amount", type="number", format="float", example="10.00", description="_________"), |  *       @OA\Property(property="amount", type="number", format="float", example="10.00", description="The total expense amont"), | ||||||
|  *       @OA\Property(property="foreign_amount", type="number", format="float", example="10.00", description="_________"), |  *       @OA\Property(property="foreign_amount", type="number", format="float", example="10.00", description="The total foreign amount of the expense"), | ||||||
|  *       @OA\Property(property="exchange_rate", type="number", format="float", example="0.80", description="_________"), |  *       @OA\Property(property="exchange_rate", type="number", format="float", example="0.80", description="The exchange rate at the time of the expense"), | ||||||
|  *       @OA\Property(property="date", type="string", example="", description="________"), |  *       @OA\Property(property="date", type="string", example="2022-12-01", description="The expense date formate Y-m-d"), | ||||||
|  *       @OA\Property(property="payment_date", type="string", example="", description="________"), |  *       @OA\Property(property="payment_date", type="string", example="", description="The date of payment for the expense, format Y-m-d"), | ||||||
|  *       @OA\Property(property="should_be_invoiced", type="boolean", example=true, description="_________"), |  *       @OA\Property(property="should_be_invoiced", type="boolean", example=true, description="Flag whether the expense should be invoiced"), | ||||||
|  *       @OA\Property(property="is_deleted", type="boolean", example=true, description="_________"), |  *       @OA\Property(property="is_deleted", type="boolean", example=true, description="Boolean determining whether the expense has been deleted"), | ||||||
|  *       @OA\Property(property="invoice_documents", type="boolean", example=true, description=""), |  *       @OA\Property(property="invoice_documents", type="boolean", example=true, description="Passing the expense documents over to the invoice"), | ||||||
|  *       @OA\Property(property="updated_at", type="number", format="integer", example="1434342123", description="Timestamp"), |  *       @OA\Property(property="updated_at", type="number", format="integer", example="1434342123", description="Timestamp"), | ||||||
|  *       @OA\Property(property="archived_at", type="number", format="integer", example="1434342123", description="Timestamp"), |  *       @OA\Property(property="archived_at", type="number", format="integer", example="1434342123", description="Timestamp"), | ||||||
|  * ) |  * ) | ||||||
|  | |||||||
| @ -3,17 +3,17 @@ | |||||||
|  * @OA\Schema( |  * @OA\Schema( | ||||||
|  *   schema="FeesAndLimits", |  *   schema="FeesAndLimits", | ||||||
|  *   type="object", |  *   type="object", | ||||||
|  *       @OA\Property(property="min_limit", type="string", example="2", description="______"), |  *       @OA\Property(property="min_limit", type="string", example="2", description="The minimum amount accepted for this gateway"), | ||||||
|  *       @OA\Property(property="max_limit", type="string", example="2", description="______"), |  *       @OA\Property(property="max_limit", type="string", example="2", description="The maximum amount accepted for this gateway"), | ||||||
|  *       @OA\Property(property="fee_amount", type="number", format="float", example="2.0", description="______"), |  *       @OA\Property(property="fee_amount", type="number", format="float", example="2.0", description="The gateway fee amount"), | ||||||
|  *       @OA\Property(property="fee_percent", type="number", format="float", example="2.0", description="______"), |  *       @OA\Property(property="fee_percent", type="number", format="float", example="2.0", description="The gateway fee percentage"), | ||||||
|  *       @OA\Property(property="fee_tax_name1", type="string", example="2", description="______"), |  *       @OA\Property(property="fee_tax_name1", type="string", example="GST", description="Fee tax name"), | ||||||
|  *       @OA\Property(property="fee_tax_name2", type="string", example="2", description="______"), |  *       @OA\Property(property="fee_tax_name2", type="string", example="VAT", description="Fee tax name"), | ||||||
|  *       @OA\Property(property="fee_tax_name3", type="string", example="2", description="______"), |  *       @OA\Property(property="fee_tax_name3", type="string", example="CA Sales Tax", description="Fee tax name"), | ||||||
|  *       @OA\Property(property="fee_tax_rate1", type="number", format="float", example="2.0", description="______"), |  *       @OA\Property(property="fee_tax_rate1", type="number", format="float", example="10.0", description="The tax rate"), | ||||||
|  *       @OA\Property(property="fee_tax_rate2", type="number", format="float", example="2.0", description="______"), |  *       @OA\Property(property="fee_tax_rate2", type="number", format="float", example="17.5", description="The tax rate"), | ||||||
|  *       @OA\Property(property="fee_tax_rate3", type="number", format="float", example="2.0", description="______"), |  *       @OA\Property(property="fee_tax_rate3", type="number", format="float", example="25.0", description="The tax rate"), | ||||||
|  *       @OA\Property(property="fee_cap", type="number", format="float", example="2.0", description="______"), |  *       @OA\Property(property="fee_cap", type="number", format="float", example="2.0", description="If set the fee amount will be no higher than this amount"), | ||||||
|  *       @OA\Property(property="adjust_fee_percent", type="boolean", example=true, description="______"), |  *       @OA\Property(property="adjust_fee_percent", type="boolean", example=true, description="Adjusts the fee to match the exact gateway fee."), | ||||||
|  * ) |  * ) | ||||||
|  */ |  */ | ||||||
|  | |||||||
| @ -3,10 +3,10 @@ | |||||||
|  * @OA\Schema( |  * @OA\Schema( | ||||||
|  *   schema="GroupSetting", |  *   schema="GroupSetting", | ||||||
|  *   type="object", |  *   type="object", | ||||||
|  *       @OA\Property(property="id", type="string", example="Opnel5aKBz", description="_________"), |  *       @OA\Property(property="id", type="string", example="Opnel5aKBz", description="The group setting hashed id"), | ||||||
|  *       @OA\Property(property="user_id", type="string", example="", description="__________"), |  *       @OA\Property(property="user_id", type="string", example="Opnel5aKBz", description="The user hashed id"), | ||||||
|  *       @OA\Property(property="company_id", type="string", example="", description="________"), |  *       @OA\Property(property="company_id", type="string", example="Opnel5aKBz", description="The company hashed id"), | ||||||
|  *       @OA\Property(property="name", type="string", example="", description="________"), |  *       @OA\Property(property="name", type="string", example="A groupies group", description="The name of the group"), | ||||||
|  *       @OA\Property(property="settings", type="object", example="", description="________"), |  *       @OA\Property(property="settings", type="object", example="", description="The settings object"), | ||||||
|  * ) |  * ) | ||||||
|  */ |  */ | ||||||
|  | |||||||
| @ -3,43 +3,43 @@ | |||||||
|  * @OA\Schema( |  * @OA\Schema( | ||||||
|  *   schema="Invoice", |  *   schema="Invoice", | ||||||
|  *   type="object", |  *   type="object", | ||||||
|  *       @OA\Property(property="id", type="string", example="Opnel5aKBz", description="_________"), |  *       @OA\Property(property="id", type="string", example="Opnel5aKBz", description="The invoice hashed id"), | ||||||
|  *       @OA\Property(property="user_id", type="string", example="", description="__________"), |  *       @OA\Property(property="user_id", type="string", example="Opnel5aKBz", description="The user hashed id"), | ||||||
|  *       @OA\Property(property="assigned_user_id", type="string", example="", description="__________"), |  *       @OA\Property(property="assigned_user_id", type="string", example="Opnel5aKBz", description="The assigned user hashed id"), | ||||||
|  *       @OA\Property(property="company_id", type="string", example="", description="________"), |  *       @OA\Property(property="company_id", type="string", example="Opnel5aKBz", description="The company hashed id"), | ||||||
|  *       @OA\Property(property="client_id", type="string", example="", description="________"), |  *       @OA\Property(property="client_id", type="string", example="Opnel5aKBz", description="The client hashed id"), | ||||||
|  *       @OA\Property(property="status_id", type="string", example="", description="________"), |  *       @OA\Property(property="status_id", type="string", example="4", description="The invoice status variable"), | ||||||
|  *       @OA\Property(property="number", type="string", example="INV_101", description="The invoice number - is a unique alpha numeric number per invoice per company"), |  *       @OA\Property(property="number", type="string", example="INV_101", description="The invoice number - is a unique alpha numeric number per invoice per company"), | ||||||
|  *       @OA\Property(property="po_number", type="string", example="", description="________"), |  *       @OA\Property(property="po_number", type="string", example="PO-1234", description="The purchase order associated with this invoice"), | ||||||
|  *       @OA\Property(property="terms", type="string", example="", description="________"), |  *       @OA\Property(property="terms", type="string", example="These are invoice terms", description="The invoice terms"), | ||||||
|  *       @OA\Property(property="public_notes", type="string", example="", description="________"), |  *       @OA\Property(property="public_notes", type="string", example="These are some public notes", description="The public notes of the invoice"), | ||||||
|  *       @OA\Property(property="private_notes", type="string", example="", description="________"), |  *       @OA\Property(property="private_notes", type="string", example="These are some private notes", description="The private notes of the invoice"), | ||||||
|  *       @OA\Property(property="footer", type="string", example="", description="________"), |  *       @OA\Property(property="footer", type="string", example="", description="The invoice footer notes"), | ||||||
|  *       @OA\Property(property="custom_value1", type="string", example="", description="________"), |  *       @OA\Property(property="custom_value1", type="string", example="2022-10-01", description="A custom field value"), | ||||||
|  *       @OA\Property(property="custom_value2", type="string", example="", description="________"), |  *       @OA\Property(property="custom_value2", type="string", example="Something custom", description="A custom field value"), | ||||||
|  *       @OA\Property(property="custom_value3", type="string", example="", description="________"), |  *       @OA\Property(property="custom_value3", type="string", example="", description="A custom field value"), | ||||||
|  *       @OA\Property(property="custom_value4", type="string", example="", description="________"), |  *       @OA\Property(property="custom_value4", type="string", example="", description="A custom field value"), | ||||||
|  *       @OA\Property(property="tax_name1", type="string", example="", description="________"), |  *       @OA\Property(property="tax_name1", type="string", example="", description="The tax name"), | ||||||
|  *       @OA\Property(property="tax_name2", type="string", example="", description="________"), |  *       @OA\Property(property="tax_name2", type="string", example="", description="The tax name"), | ||||||
|  *       @OA\Property(property="tax_rate1", type="number", format="float", example="10.00", description="_________"), |  *       @OA\Property(property="tax_rate1", type="number", format="float", example="10.00", description="The tax rate"), | ||||||
|  *       @OA\Property(property="tax_rate2", type="number", format="float", example="10.00", description="_________"), |  *       @OA\Property(property="tax_rate2", type="number", format="float", example="10.00", description="The tax rate"), | ||||||
|  *       @OA\Property(property="tax_name3", type="string", example="", description="________"), |  *       @OA\Property(property="tax_name3", type="string", example="", description="The tax name"), | ||||||
|  *       @OA\Property(property="tax_rate3", type="number", format="float", example="10.00", description="_________"), |  *       @OA\Property(property="tax_rate3", type="number", format="float", example="10.00", description="The tax rate"), | ||||||
|  *       @OA\Property(property="total_taxes", type="number", format="float", example="10.00", description="The total taxes for the invoice"), |  *       @OA\Property(property="total_taxes", type="number", format="float", example="10.00", description="The total taxes for the invoice"), | ||||||
|  *       @OA\Property(property="line_items", type="object", example="", description="_________"), |  *       @OA\Property(property="line_items", type="object", example="", description="An array of objects which define the line items of the invoice"), | ||||||
|  *       @OA\Property(property="amount", type="number", format="float", example="10.00", description="_________"), |  *       @OA\Property(property="amount", type="number", format="float", example="10.00", description="The invoice amount"), | ||||||
|  *       @OA\Property(property="balance", type="number", format="float", example="10.00", description="_________"), |  *       @OA\Property(property="balance", type="number", format="float", example="10.00", description="The invoice balance"), | ||||||
|  *       @OA\Property(property="paid_to_date", type="number", format="float", example="10.00", description="_________"), |  *       @OA\Property(property="paid_to_date", type="number", format="float", example="10.00", description="The amount paid on the invoice to date"), | ||||||
|  *       @OA\Property(property="discount", type="number", format="float", example="10.00", description="_________"), |  *       @OA\Property(property="discount", type="number", format="float", example="10.00", description="The invoice discount, can be an amount or a percentage"), | ||||||
|  *       @OA\Property(property="partial", type="number", format="float", example="10.00", description="_________"), |  *       @OA\Property(property="partial", type="number", format="float", example="10.00", description="The deposit/partial amount"), | ||||||
|  *       @OA\Property(property="is_amount_discount", type="boolean", example=true, description="_________"), |  *       @OA\Property(property="is_amount_discount", type="boolean", example=true, description="Flag determining if the discount is an amount or a percentage"), | ||||||
|  *       @OA\Property(property="is_deleted", type="boolean", example=true, description="_________"), |  *       @OA\Property(property="is_deleted", type="boolean", example=true, description="Defines if the invoice has been deleted"), | ||||||
|  *       @OA\Property(property="uses_inclusive_taxes", type="boolean", example=true, description="Defines the type of taxes used as either inclusive or exclusive"), |  *       @OA\Property(property="uses_inclusive_taxes", type="boolean", example=true, description="Defines the type of taxes used as either inclusive or exclusive"), | ||||||
|  *       @OA\Property(property="date", type="string", format="date", example="1994-07-30", description="The Invoice Date"), |  *       @OA\Property(property="date", type="string", format="date", example="1994-07-30", description="The Invoice Date"), | ||||||
|  *       @OA\Property(property="last_sent_date", type="string", format="date", example="1994-07-30", description="The last date the invoice was sent out"), |  *       @OA\Property(property="last_sent_date", type="string", format="date", example="1994-07-30", description="The last date the invoice was sent out"), | ||||||
|  *       @OA\Property(property="next_send_date", type="string", format="date", example="1994-07-30", description="The Next date for a reminder to be sent"), |  *       @OA\Property(property="next_send_date", type="string", format="date", example="1994-07-30", description="The Next date for a reminder to be sent"), | ||||||
|  *       @OA\Property(property="partial_due_date", type="string", format="date", example="1994-07-30", description="_________"), |  *       @OA\Property(property="partial_due_date", type="string", format="date", example="1994-07-30", description="The due date for the deposit/partial amount"), | ||||||
|  *       @OA\Property(property="due_date", type="string", format="date", example="1994-07-30", description="_________"), |  *       @OA\Property(property="due_date", type="string", format="date", example="1994-07-30", description="The due date of the invoice"), | ||||||
|  *       @OA\Property(property="settings",ref="#/components/schemas/CompanySettings"), |  *       @OA\Property(property="settings",ref="#/components/schemas/CompanySettings"), | ||||||
|  *       @OA\Property(property="last_viewed", type="number", format="integer", example="1434342123", description="Timestamp"), |  *       @OA\Property(property="last_viewed", type="number", format="integer", example="1434342123", description="Timestamp"), | ||||||
|  *       @OA\Property(property="updated_at", type="number", format="integer", example="1434342123", description="Timestamp"), |  *       @OA\Property(property="updated_at", type="number", format="integer", example="1434342123", description="Timestamp"), | ||||||
|  | |||||||
| @ -3,18 +3,18 @@ | |||||||
|  * @OA\Schema( |  * @OA\Schema( | ||||||
|  *   schema="Payment", |  *   schema="Payment", | ||||||
|  *   type="object", |  *   type="object", | ||||||
|  *       @OA\Property(property="id", type="string", example="Opnel5aKBz", description="______"), |  *       @OA\Property(property="id", type="string", example="Opnel5aKBz", description="The payment hashed id"), | ||||||
|  *       @OA\Property(property="client_id", type="string", example="Opnel5aKBz", description="______"), |  *       @OA\Property(property="client_id", type="string", example="Opnel5aKBz", description="The client hashed id"), | ||||||
|  *       @OA\Property(property="invitation_id", type="string", example="Opnel5aKBz", description="______"), |  *       @OA\Property(property="invitation_id", type="string", example="Opnel5aKBz", description="The invitation hashed id"), | ||||||
|  *       @OA\Property(property="client_contact_id", type="string", example="Opnel5aKBz", description="______"), |  *       @OA\Property(property="client_contact_id", type="string", example="Opnel5aKBz", description="The client contact hashed id"), | ||||||
|  *       @OA\Property(property="user_id", type="string", example="Opnel5aKBz", description="______"), |  *       @OA\Property(property="user_id", type="string", example="Opnel5aKBz", description="The user hashed id"), | ||||||
|  *       @OA\Property(property="type_id", type="string", example="1", description="The Payment Type ID"), |  *       @OA\Property(property="type_id", type="string", example="1", description="The Payment Type ID"), | ||||||
|  *       @OA\Property(property="date", type="string", example="1-1-2014", description="The Payment date"), |  *       @OA\Property(property="date", type="string", example="1-1-2014", description="The Payment date"), | ||||||
|  *       @OA\Property(property="transaction_reference", type="string", example="xcsSxcs124asd", description="The transaction reference as defined by the payment gateway"), |  *       @OA\Property(property="transaction_reference", type="string", example="xcsSxcs124asd", description="The transaction reference as defined by the payment gateway"), | ||||||
|  *       @OA\Property(property="assigned_user_id", type="string", example="Opnel5aKBz", description="______"), |  *       @OA\Property(property="assigned_user_id", type="string", example="Opnel5aKBz", description="The assigned user hashed id"), | ||||||
|  *       @OA\Property(property="private_notes", type="string", example="The payment was refunded due to error", description="______"), |  *       @OA\Property(property="private_notes", type="string", example="The payment was refunded due to error", description="The private notes of the payment"), | ||||||
|  *       @OA\Property(property="is_manual", type="boolean", example=true, description="______"), |  *       @OA\Property(property="is_manual", type="boolean", example=true, description="Flags whether the payment was made manually or processed via a gateway"), | ||||||
|  *       @OA\Property(property="is_deleted", type="boolean", example=true, description="______"), |  *       @OA\Property(property="is_deleted", type="boolean", example=true, description="Defines if the payment has been deleted"), | ||||||
|  *       @OA\Property(property="amount", type="number", example=10.00, description="The amount of this payment"), |  *       @OA\Property(property="amount", type="number", example=10.00, description="The amount of this payment"), | ||||||
|  *       @OA\Property(property="refunded", type="number", example=10.00, description="The refunded amount of this payment"), |  *       @OA\Property(property="refunded", type="number", example=10.00, description="The refunded amount of this payment"), | ||||||
|  *       @OA\Property(property="updated_at", type="number", format="integer", example="1434342123", description="Timestamp"), |  *       @OA\Property(property="updated_at", type="number", format="integer", example="1434342123", description="Timestamp"), | ||||||
|  | |||||||
| @ -6,8 +6,8 @@ | |||||||
|  *       @OA\Property(property="id", type="string", example="AS3df3A", description="The paymentable hashed id"), |  *       @OA\Property(property="id", type="string", example="AS3df3A", description="The paymentable hashed id"), | ||||||
|  *       @OA\Property(property="invoice_id", type="string", example="AS3df3A", description="The invoice hashed id"), |  *       @OA\Property(property="invoice_id", type="string", example="AS3df3A", description="The invoice hashed id"), | ||||||
|  *       @OA\Property(property="credit_id", type="string", example="AS3df3A", description="The credit hashed id"), |  *       @OA\Property(property="credit_id", type="string", example="AS3df3A", description="The credit hashed id"), | ||||||
|  *       @OA\Property(property="refunded", type="number", format="float", example="10.00", description="______"), |  *       @OA\Property(property="refunded", type="number", format="float", example="10.00", description="The amount that has been refunded for this payment"), | ||||||
|  *       @OA\Property(property="amount", type="number", format="float", example="10.00", description="______"), |  *       @OA\Property(property="amount", type="number", format="float", example="10.00", description="The amount that has been applied to the payment"), | ||||||
|  *       @OA\Property(property="updated_at", type="number", format="integer", example="1434342123", description="Timestamp"), |  *       @OA\Property(property="updated_at", type="number", format="integer", example="1434342123", description="Timestamp"), | ||||||
|  *       @OA\Property(property="created_at", type="number", format="integer", example="1434342123", description="Timestamp"),* |  *       @OA\Property(property="created_at", type="number", format="integer", example="1434342123", description="Timestamp"),* | ||||||
|  * ) |  * ) | ||||||
|  | |||||||
| @ -3,6 +3,6 @@ | |||||||
|  * @OA\Schema( |  * @OA\Schema( | ||||||
|  *   schema="Product", |  *   schema="Product", | ||||||
|  *   type="object", |  *   type="object", | ||||||
|  *       @OA\Property(property="id", type="string", example="Opnel5aKBz", description="______"), |  *       @OA\Property(property="id", type="string", example="Opnel5aKBz", description="The product hashed id"), | ||||||
|  * ) |  * ) | ||||||
|  */ |  */ | ||||||
|  | |||||||
| @ -3,7 +3,7 @@ | |||||||
|  * @OA\Schema( |  * @OA\Schema( | ||||||
|  *   schema="Project", |  *   schema="Project", | ||||||
|  *   type="object", |  *   type="object", | ||||||
|  *       @OA\Property(property="id", type="string", example="Opnel5aKBz", description="______"), |  *       @OA\Property(property="id", type="string", example="Opnel5aKBz", description="The project hashed id"), | ||||||
|  *       @OA\Property(property="name", type="string", example="New Project", description="______"), |  *       @OA\Property(property="name", type="string", example="New Project", description="The project name"), | ||||||
|  * ) |  * ) | ||||||
|  */ |  */ | ||||||
|  | |||||||
| @ -3,43 +3,43 @@ | |||||||
|  * @OA\Schema( |  * @OA\Schema( | ||||||
|  *   schema="Quote", |  *   schema="Quote", | ||||||
|  *   type="object", |  *   type="object", | ||||||
|  *       @OA\Property(property="id", type="string", example="Opnel5aKBz", description="_________"), |  *       @OA\Property(property="id", type="string", example="Opnel5aKBz", description="The quote hashed id"), | ||||||
|  *       @OA\Property(property="user_id", type="string", example="", description="__________"), |  *       @OA\Property(property="user_id", type="string", example="", description="The user hashed id"), | ||||||
|  *       @OA\Property(property="assigned_user_id", type="string", example="", description="__________"), |  *       @OA\Property(property="assigned_user_id", type="string", example="", description="The assigned user hashed id"), | ||||||
|  *       @OA\Property(property="company_id", type="string", example="", description="________"), |  *       @OA\Property(property="company_id", type="string", example="", description="The company hashed id"), | ||||||
|  *       @OA\Property(property="client_id", type="string", example="", description="________"), |  *       @OA\Property(property="client_id", type="string", example="", description="The client hashed id"), | ||||||
|  *       @OA\Property(property="status_id", type="string", example="", description="________"), |  *       @OA\Property(property="status_id", type="string", example="", description="The status of the quote"), | ||||||
|  *       @OA\Property(property="number", type="string", example="QUOTE_101", description="The quote number - is a unique alpha numeric number per quote per company"), |  *       @OA\Property(property="number", type="string", example="QUOTE_101", description="The quote number - is a unique alpha numeric number per quote per company"), | ||||||
|  *       @OA\Property(property="po_number", type="string", example="", description="________"), |  *       @OA\Property(property="po_number", type="string", example="PO-1234", description="The purchase order number associated with this quote"), | ||||||
|  *       @OA\Property(property="terms", type="string", example="", description="________"), |  *       @OA\Property(property="terms", type="string", example="These are some quote terms. Valid for 14 days.", description="The quote terms"), | ||||||
|  *       @OA\Property(property="public_notes", type="string", example="", description="________"), |  *       @OA\Property(property="public_notes", type="string", example="These are public notes which the client may see", description="Public notes for the quote"), | ||||||
|  *       @OA\Property(property="private_notes", type="string", example="", description="________"), |  *       @OA\Property(property="private_notes", type="string", example="These are private notes, not to be disclosed to the client", description="Private notes for the quote"), | ||||||
|  *       @OA\Property(property="footer", type="string", example="", description="________"), |  *       @OA\Property(property="footer", type="string", example="The text goes in the footer of the quote", description="Footer text of quote"), | ||||||
|  *       @OA\Property(property="custom_value1", type="string", example="", description="________"), |  *       @OA\Property(property="custom_value1", type="string", example="A custom value", description="Custom value field"), | ||||||
|  *       @OA\Property(property="custom_value2", type="string", example="", description="________"), |  *       @OA\Property(property="custom_value2", type="string", example="A custom value", description="Custom value field"), | ||||||
|  *       @OA\Property(property="custom_value3", type="string", example="", description="________"), |  *       @OA\Property(property="custom_value3", type="string", example="A custom value", description="Custom value field"), | ||||||
|  *       @OA\Property(property="custom_value4", type="string", example="", description="________"), |  *       @OA\Property(property="custom_value4", type="string", example="A custom value", description="Custom value field"), | ||||||
|  *       @OA\Property(property="tax_name1", type="string", example="", description="________"), |  *       @OA\Property(property="tax_name1", type="string", example="GST", description="The tax name"), | ||||||
|  *       @OA\Property(property="tax_name2", type="string", example="", description="________"), |  *       @OA\Property(property="tax_name2", type="string", example="VAT", description="The tax name"), | ||||||
|  *       @OA\Property(property="tax_rate1", type="number", format="float", example="10.00", description="_________"), |  *       @OA\Property(property="tax_rate1", type="number", format="float", example="10.00", description="The tax rate"), | ||||||
|  *       @OA\Property(property="tax_rate2", type="number", format="float", example="10.00", description="_________"), |  *       @OA\Property(property="tax_rate2", type="number", format="float", example="10.00", description="The tax rate"), | ||||||
|  *       @OA\Property(property="tax_name3", type="string", example="", description="________"), |  *       @OA\Property(property="tax_name3", type="string", example="", description="The tax name"), | ||||||
|  *       @OA\Property(property="tax_rate3", type="number", format="float", example="10.00", description="_________"), |  *       @OA\Property(property="tax_rate3", type="number", format="float", example="10.00", description="The tax rate"), | ||||||
|  *       @OA\Property(property="total_taxes", type="number", format="float", example="10.00", description="The total taxes for the quote"), |  *       @OA\Property(property="total_taxes", type="number", format="float", example="10.00", description="The total taxes for the quote"), | ||||||
|  *       @OA\Property(property="line_items", type="object", example="", description="_________"), |  *       @OA\Property(property="line_items", type="object", example="[{"product_key":"test", "unit_cost":10},{"product_key":"test", "unit_cost":10}]", description="An array of line items of the quote"), | ||||||
|  *       @OA\Property(property="amount", type="number", format="float", example="10.00", description="_________"), |  *       @OA\Property(property="amount", type="number", format="float", example="10.00", description="The total amount of the quote"), | ||||||
|  *       @OA\Property(property="balance", type="number", format="float", example="10.00", description="_________"), |  *       @OA\Property(property="balance", type="number", format="float", example="10.00", description="The balance due of the quote"), | ||||||
|  *       @OA\Property(property="paid_to_date", type="number", format="float", example="10.00", description="_________"), |  *       @OA\Property(property="paid_to_date", type="number", format="float", example="10.00", description="The amount that has been paid to date on the quote"), | ||||||
|  *       @OA\Property(property="discount", type="number", format="float", example="10.00", description="_________"), |  *       @OA\Property(property="discount", type="number", format="float", example="10.00", description="The quote discount"), | ||||||
|  *       @OA\Property(property="partial", type="number", format="float", example="10.00", description="_________"), |  *       @OA\Property(property="partial", type="number", format="float", example="10.00", description="The partial/deposit amount"), | ||||||
|  *       @OA\Property(property="is_amount_discount", type="boolean", example=true, description="_________"), |  *       @OA\Property(property="is_amount_discount", type="boolean", example=true, description="Boolean flag determining if the quote is an amount or percentage"), | ||||||
|  *       @OA\Property(property="is_deleted", type="boolean", example=true, description="_________"), |  *       @OA\Property(property="is_deleted", type="boolean", example=true, description="Boolean flag determining if the quote has been deleted"), | ||||||
|  *       @OA\Property(property="uses_inclusive_taxes", type="boolean", example=true, description="Defines the type of taxes used as either inclusive or exclusive"), |  *       @OA\Property(property="uses_inclusive_taxes", type="boolean", example=true, description="Defines the type of taxes used as either inclusive or exclusive"), | ||||||
|  *       @OA\Property(property="date", type="string", format="date", example="1994-07-30", description="The Quote Date"), |  *       @OA\Property(property="date", type="string", format="date", example="1994-07-30", description="The Quote Date"), | ||||||
|  *       @OA\Property(property="last_sent_date", type="string", format="date", example="1994-07-30", description="The last date the quote was sent out"), |  *       @OA\Property(property="last_sent_date", type="string", format="date", example="1994-07-30", description="The last date the quote was sent out"), | ||||||
|  *       @OA\Property(property="next_send_date", type="string", format="date", example="1994-07-30", description="The Next date for a reminder to be sent"), |  *       @OA\Property(property="next_send_date", type="string", format="date", example="1994-07-30", description="The Next date for a reminder to be sent"), | ||||||
|  *       @OA\Property(property="partial_due_date", type="string", format="date", example="1994-07-30", description="_________"), |  *       @OA\Property(property="partial_due_date", type="string", format="date", example="1994-07-30", description="The date when the partial/deposit is due"), | ||||||
|  *       @OA\Property(property="due_date", type="string", format="date", example="1994-07-30", description="_________"), |  *       @OA\Property(property="due_date", type="string", format="date", example="1994-07-30", description="The date the quote is valid until"), | ||||||
|  *       @OA\Property(property="settings",ref="#/components/schemas/CompanySettings"), |  *       @OA\Property(property="settings",ref="#/components/schemas/CompanySettings"), | ||||||
|  *       @OA\Property(property="last_viewed", type="number", format="integer", example="1434342123", description="Timestamp"), |  *       @OA\Property(property="last_viewed", type="number", format="integer", example="1434342123", description="Timestamp"), | ||||||
|  *       @OA\Property(property="updated_at", type="number", format="integer", example="1434342123", description="Timestamp"), |  *       @OA\Property(property="updated_at", type="number", format="integer", example="1434342123", description="Timestamp"), | ||||||
|  | |||||||
| @ -3,44 +3,43 @@ | |||||||
|  * @OA\Schema( |  * @OA\Schema( | ||||||
|  *   schema="RecurringExpense", |  *   schema="RecurringExpense", | ||||||
|  *   type="object", |  *   type="object", | ||||||
|  *       @OA\Property(property="id", type="string", example="Opnel5aKBz", description="_________"), |  *       @OA\Property(property="id", type="string", example="Opnel5aKBz", description="The hashed id of the recurring expense"), | ||||||
|  *       @OA\Property(property="user_id", type="string", example="", description="__________"), |  *       @OA\Property(property="user_id", type="string", example="Opnel5aKBz", description="The hashed id of the user who created the recurring expense"), | ||||||
|  *       @OA\Property(property="assigned_user_id", type="string", example="", description="__________"), |  *       @OA\Property(property="assigned_user_id", type="string", example="Opnel5aKBz", description="The hashed id of the user assigned to this recurring expense"), | ||||||
|  *       @OA\Property(property="company_id", type="string", example="", description="________"), |  *       @OA\Property(property="company_id", type="string", example="Opnel5aKBz", description="The hashed id of the company"), | ||||||
|  *       @OA\Property(property="client_id", type="string", example="", description="________"), |  *       @OA\Property(property="client_id", type="string", example="Opnel5aKBz", description="The hashed id of the client"), | ||||||
|  *       @OA\Property(property="invoice_id", type="string", example="", description="________"), |  *       @OA\Property(property="invoice_id", type="string", example="Opnel5aKBz", description="The hashed id of the invoice"), | ||||||
|  *       @OA\Property(property="bank_id", type="string", example="", description="________"), |  *       @OA\Property(property="bank_id", type="string", example="22", description="The id of the bank associated with this recurring expense"), | ||||||
|  *       @OA\Property(property="invoice_currency_id", type="string", example="", description="________"), |  *       @OA\Property(property="invoice_currency_id", type="string", example="1", description="The currency id of the invoice associated with this recurring expense"), | ||||||
|  *       @OA\Property(property="expense_currency_id", type="string", example="", description="________"), |  *       @OA\Property(property="expense_currency_id", type="string", example="1", description="The currency id of the expense associated with this recurring expense"), | ||||||
|  *       @OA\Property(property="invoice_category_id", type="string", example="", description="________"), |  *       @OA\Property(property="invoice_category_id", type="string", example="1", description="The category id of the invoice"), | ||||||
|  *       @OA\Property(property="payment_type_id", type="string", example="", description="________"), |  *       @OA\Property(property="payment_type_id", type="string", example="1", description="The payment type id"), | ||||||
|  *       @OA\Property(property="recurring_expense_id", type="string", example="", description="________"), |  *       @OA\Property(property="private_notes", type="string", example="Private and confidential", description="The recurring expense private notes"), | ||||||
|  *       @OA\Property(property="private_notes", type="string", example="", description="________"), |  *       @OA\Property(property="public_notes", type="string", example="This is the best client in the world", description="The recurring expense public notes"), | ||||||
|  *       @OA\Property(property="public_notes", type="string", example="", description="________"), |  *       @OA\Property(property="transaction_reference", type="string", example="EXP-1223-2333", description="The recurring expense transaction reference"), | ||||||
|  *       @OA\Property(property="transaction_reference", type="string", example="", description="________"), |  *       @OA\Property(property="transcation_id", type="string", example="1233312312", description="The transaction id of the recurring expense"), | ||||||
|  *       @OA\Property(property="transcation_id", type="string", example="", description="________"), |  *       @OA\Property(property="custom_value1", type="string", example="$1000", description="Custom value field"), | ||||||
|  *       @OA\Property(property="custom_value1", type="string", example="", description="________"), |  *       @OA\Property(property="custom_value2", type="string", example="2022-10-10", description="Custom value field"), | ||||||
|  *       @OA\Property(property="custom_value2", type="string", example="", description="________"), |  *       @OA\Property(property="custom_value3", type="string", example="short text", description="Custom value field"), | ||||||
|  *       @OA\Property(property="custom_value3", type="string", example="", description="________"), |  *       @OA\Property(property="custom_value4", type="string", example="very long text", description="Custom value field"), | ||||||
|  *       @OA\Property(property="custom_value4", type="string", example="", description="________"), |  *       @OA\Property(property="tax_name1", type="string", example="GST", description="The tax name"), | ||||||
|  *       @OA\Property(property="tax_name1", type="string", example="", description="________"), |  *       @OA\Property(property="tax_name2", type="string", example="VAT", description="The tax name"), | ||||||
|  *       @OA\Property(property="tax_name2", type="string", example="", description="________"), |  *       @OA\Property(property="tax_rate1", type="number", format="float", example="10.00", description="The tax rate"), | ||||||
|  *       @OA\Property(property="tax_rate1", type="number", format="float", example="10.00", description="_________"), |  *       @OA\Property(property="tax_rate2", type="number", format="float", example="10.00", description="The tax rate"), | ||||||
|  *       @OA\Property(property="tax_rate2", type="number", format="float", example="10.00", description="_________"), |  *       @OA\Property(property="tax_name3", type="string", example="", description="The tax name"), | ||||||
|  *       @OA\Property(property="tax_name3", type="string", example="", description="________"), |  *       @OA\Property(property="tax_rate3", type="number", format="float", example="10.00", description="The tax rate"), | ||||||
|  *       @OA\Property(property="tax_rate3", type="number", format="float", example="10.00", description="_________"), |  *       @OA\Property(property="amount", type="number", format="float", example="10.00", description="The total amount of the recurring expense"), | ||||||
|  *       @OA\Property(property="amount", type="number", format="float", example="10.00", description="_________"), |  *       @OA\Property(property="frequency_id", type="number", format="int", example="1", description="The frequency this recurring expense fires"), | ||||||
|  *       @OA\Property(property="frequency_id", type="number", format="int", example="1", description="_________"), |  *       @OA\Property(property="remaining_cycles", type="number", format="int", example="1", description="The number of remaining cycles for this recurring expense"), | ||||||
|  *       @OA\Property(property="remaining_cycles", type="number", format="int", example="1", description="_________"), |  *       @OA\Property(property="foreign_amount", type="number", format="float", example="10.00", description="The foreign currency amount of the recurring expense"), | ||||||
|  *       @OA\Property(property="foreign_amount", type="number", format="float", example="10.00", description="_________"), |  *       @OA\Property(property="exchange_rate", type="number", format="float", example="0.80", description="The exchange rate for the expernse"), | ||||||
|  *       @OA\Property(property="exchange_rate", type="number", format="float", example="0.80", description="_________"), |  *       @OA\Property(property="date", type="string", example="", description="The date of the expense"), | ||||||
|  *       @OA\Property(property="date", type="string", example="", description="________"), |  *       @OA\Property(property="payment_date", type="string", example="", description="The date the expense was paid"), | ||||||
|  *       @OA\Property(property="payment_date", type="string", example="", description="________"), |  *       @OA\Property(property="should_be_invoiced", type="boolean", example=true, description="Boolean flag determining if the expense should be invoiced"), | ||||||
|  *       @OA\Property(property="should_be_invoiced", type="boolean", example=true, description="_________"), |  *       @OA\Property(property="is_deleted", type="boolean", example=true, description="Boolean flag determining if the recurring expense is deleted"), | ||||||
|  *       @OA\Property(property="is_deleted", type="boolean", example=true, description="_________"), |  | ||||||
|  *       @OA\Property(property="last_sent_date", type="string", format="date", example="1994-07-30", description="The Date it was sent last"), |  *       @OA\Property(property="last_sent_date", type="string", format="date", example="1994-07-30", description="The Date it was sent last"), | ||||||
|  *       @OA\Property(property="next_send_date", type="string", format="date", example="1994-07-30", description="The next send date"), |  *       @OA\Property(property="next_send_date", type="string", format="date", example="1994-07-30", description="The next send date"), | ||||||
|  *       @OA\Property(property="invoice_documents", type="boolean", example=true, description=""), |  *       @OA\Property(property="invoice_documents", type="boolean", example=true, description="Boolean flag determining if the documents associated with this expense should be passed onto the invoice if it is converted to an invoice"), | ||||||
|  *       @OA\Property(property="updated_at", type="number", format="integer", example="1434342123", description="Timestamp"), |  *       @OA\Property(property="updated_at", type="number", format="integer", example="1434342123", description="Timestamp"), | ||||||
|  *       @OA\Property(property="archived_at", type="number", format="integer", example="1434342123", description="Timestamp"), |  *       @OA\Property(property="archived_at", type="number", format="integer", example="1434342123", description="Timestamp"), | ||||||
|  * ) |  * ) | ||||||
|  | |||||||
| @ -3,6 +3,56 @@ | |||||||
|  * @OA\Schema( |  * @OA\Schema( | ||||||
|  *   schema="RecurringInvoice", |  *   schema="RecurringInvoice", | ||||||
|  *   type="object", |  *   type="object", | ||||||
|  *       @OA\Property(property="id", type="string", example="Opnel5aKBz", description="______"), |  *       @OA\Property(property="id", type="string", example="Opnel5aKBz", description="The hashed id of the recurring invoice"), | ||||||
|  |  *       @OA\Property(property="user_id", type="string", example="Opnel5aKBz", description="The user hashed id"), | ||||||
|  |  *       @OA\Property(property="assigned_user_id", type="string", example="Opnel5aKBz", description="The assigned user hashed id"), | ||||||
|  |  *       @OA\Property(property="company_id", type="string", example="Opnel5aKBz", description="The company hashed id"), | ||||||
|  |  *       @OA\Property(property="client_id", type="string", example="Opnel5aKBz", description="The client hashed id"), | ||||||
|  |  *       @OA\Property(property="status_id", type="string", example="4", description="The invoice status variable"), | ||||||
|  |  *       @OA\Property(property="frequency_id", type="number", example="4", description="The recurring invoice frequency"), | ||||||
|  |  *       @OA\Property(property="remaining_cycles", type="number", example="4", description="The number of invoices left to be generated"), | ||||||
|  |  *       @OA\Property(property="number", type="string", example="INV_101", description="The recurringinvoice number - is a unique alpha numeric number per invoice per company"), | ||||||
|  |  *       @OA\Property(property="po_number", type="string", example="PO-1234", description="The purchase order associated with this recurring invoice"), | ||||||
|  |  *       @OA\Property(property="terms", type="string", example="These are invoice terms", description="The invoice terms"), | ||||||
|  |  *       @OA\Property(property="public_notes", type="string", example="These are some public notes", description="The public notes of the invoice"), | ||||||
|  |  *       @OA\Property(property="private_notes", type="string", example="These are some private notes", description="The private notes of the invoice"), | ||||||
|  |  *       @OA\Property(property="footer", type="string", example="", description="The invoice footer notes"), | ||||||
|  |  *       @OA\Property(property="custom_value1", type="string", example="2022-10-01", description="A custom field value"), | ||||||
|  |  *       @OA\Property(property="custom_value2", type="string", example="Something custom", description="A custom field value"), | ||||||
|  |  *       @OA\Property(property="custom_value3", type="string", example="", description="A custom field value"), | ||||||
|  |  *       @OA\Property(property="custom_value4", type="string", example="", description="A custom field value"), | ||||||
|  |  *       @OA\Property(property="tax_name1", type="string", example="", description="The tax name"), | ||||||
|  |  *       @OA\Property(property="tax_name2", type="string", example="", description="The tax name"), | ||||||
|  |  *       @OA\Property(property="tax_rate1", type="number", format="float", example="10.00", description="The tax rate"), | ||||||
|  |  *       @OA\Property(property="tax_rate2", type="number", format="float", example="10.00", description="The tax rate"), | ||||||
|  |  *       @OA\Property(property="tax_name3", type="string", example="", description="The tax name"), | ||||||
|  |  *       @OA\Property(property="tax_rate3", type="number", format="float", example="10.00", description="The tax rate"), | ||||||
|  |  *       @OA\Property(property="total_taxes", type="number", format="float", example="10.00", description="The total taxes for the invoice"), | ||||||
|  |  *       @OA\Property(property="line_items", type="object", example="", description="An array of objects which define the line items of the invoice"), | ||||||
|  |  *       @OA\Property(property="amount", type="number", format="float", example="10.00", description="The invoice amount"), | ||||||
|  |  *       @OA\Property(property="balance", type="number", format="float", example="10.00", description="The invoice balance"), | ||||||
|  |  *       @OA\Property(property="paid_to_date", type="number", format="float", example="10.00", description="The amount paid on the invoice to date"), | ||||||
|  |  *       @OA\Property(property="discount", type="number", format="float", example="10.00", description="The invoice discount, can be an amount or a percentage"), | ||||||
|  |  *       @OA\Property(property="partial", type="number", format="float", example="10.00", description="The deposit/partial amount"), | ||||||
|  |  *       @OA\Property(property="is_amount_discount", type="boolean", example=true, description="Flag determining if the discount is an amount or a percentage"), | ||||||
|  |  *       @OA\Property(property="is_deleted", type="boolean", example=true, description="Defines if the invoice has been deleted"), | ||||||
|  |  *       @OA\Property(property="uses_inclusive_taxes", type="boolean", example=true, description="Defines the type of taxes used as either inclusive or exclusive"), | ||||||
|  |  *       @OA\Property(property="date", type="string", format="date", example="1994-07-30", description="The Invoice Date"), | ||||||
|  |  *       @OA\Property(property="last_sent_date", type="string", format="date", example="1994-07-30", description="The last date the invoice was sent out"), | ||||||
|  |  *       @OA\Property(property="next_send_date", type="string", format="date", example="1994-07-30", description="The Next date for a reminder to be sent"), | ||||||
|  |  *       @OA\Property(property="partial_due_date", type="string", format="date", example="1994-07-30", description="The due date for the deposit/partial amount"), | ||||||
|  |  *       @OA\Property(property="due_date", type="string", format="date", example="1994-07-30", description="The due date of the invoice"), | ||||||
|  |  *       @OA\Property(property="settings",ref="#/components/schemas/CompanySettings"), | ||||||
|  |  *       @OA\Property(property="last_viewed", type="number", format="integer", example="1434342123", description="Timestamp"), | ||||||
|  |  *       @OA\Property(property="updated_at", type="number", format="integer", example="1434342123", description="Timestamp"), | ||||||
|  |  *       @OA\Property(property="archived_at", type="number", format="integer", example="1434342123", description="Timestamp"), | ||||||
|  |  *       @OA\Property(property="custom_surcharge1", type="number", format="float", example="10.00", description="First Custom Surcharge"), | ||||||
|  |  *       @OA\Property(property="custom_surcharge2", type="number", format="float", example="10.00", description="Second Custom Surcharge"), | ||||||
|  |  *       @OA\Property(property="custom_surcharge3", type="number", format="float", example="10.00", description="Third Custom Surcharge"), | ||||||
|  |  *       @OA\Property(property="custom_surcharge4", type="number", format="float", example="10.00", description="Fourth Custom Surcharge"), | ||||||
|  |  *       @OA\Property(property="custom_surcharge_tax1", type="boolean", example=true, description="Toggles charging taxes on custom surcharge amounts"), | ||||||
|  |  *       @OA\Property(property="custom_surcharge_tax2", type="boolean", example=true, description="Toggles charging taxes on custom surcharge amounts"), | ||||||
|  |  *       @OA\Property(property="custom_surcharge_tax3", type="boolean", example=true, description="Toggles charging taxes on custom surcharge amounts"), | ||||||
|  |  *       @OA\Property(property="custom_surcharge_tax4", type="boolean", example=true, description="Toggles charging taxes on custom surcharge amounts"), | ||||||
|  * ) |  * ) | ||||||
|  */ |  */ | ||||||
|  | |||||||
| @ -3,6 +3,56 @@ | |||||||
|  * @OA\Schema( |  * @OA\Schema( | ||||||
|  *   schema="RecurringQuote", |  *   schema="RecurringQuote", | ||||||
|  *   type="object", |  *   type="object", | ||||||
|  *       @OA\Property(property="id", type="string", example="Opnel5aKBz", description="______"), |  *       @OA\Property(property="id", type="string", example="Opnel5aKBz", description="The hashed id of the recurring quote"), | ||||||
|  |  *       @OA\Property(property="user_id", type="string", example="Opnel5aKBz", description="The user hashed id"), | ||||||
|  |  *       @OA\Property(property="assigned_user_id", type="string", example="Opnel5aKBz", description="The assigned user hashed id"), | ||||||
|  |  *       @OA\Property(property="company_id", type="string", example="Opnel5aKBz", description="The company hashed id"), | ||||||
|  |  *       @OA\Property(property="client_id", type="string", example="Opnel5aKBz", description="The client hashed id"), | ||||||
|  |  *       @OA\Property(property="status_id", type="string", example="4", description="The quote status variable"), | ||||||
|  |  *       @OA\Property(property="frequency_id", type="number", example="4", description="The recurring quote frequency"), | ||||||
|  |  *       @OA\Property(property="remaining_cycles", type="number", example="4", description="The number of quotes left to be generated"), | ||||||
|  |  *       @OA\Property(property="number", type="string", example="INV_101", description="The recurringquote number - is a unique alpha numeric number per quote per company"), | ||||||
|  |  *       @OA\Property(property="po_number", type="string", example="PO-1234", description="The purchase order associated with this recurring quote"), | ||||||
|  |  *       @OA\Property(property="terms", type="string", example="These are quote terms", description="The quote terms"), | ||||||
|  |  *       @OA\Property(property="public_notes", type="string", example="These are some public notes", description="The public notes of the quote"), | ||||||
|  |  *       @OA\Property(property="private_notes", type="string", example="These are some private notes", description="The private notes of the quote"), | ||||||
|  |  *       @OA\Property(property="footer", type="string", example="", description="The quote footer notes"), | ||||||
|  |  *       @OA\Property(property="custom_value1", type="string", example="2022-10-01", description="A custom field value"), | ||||||
|  |  *       @OA\Property(property="custom_value2", type="string", example="Something custom", description="A custom field value"), | ||||||
|  |  *       @OA\Property(property="custom_value3", type="string", example="", description="A custom field value"), | ||||||
|  |  *       @OA\Property(property="custom_value4", type="string", example="", description="A custom field value"), | ||||||
|  |  *       @OA\Property(property="tax_name1", type="string", example="", description="The tax name"), | ||||||
|  |  *       @OA\Property(property="tax_name2", type="string", example="", description="The tax name"), | ||||||
|  |  *       @OA\Property(property="tax_rate1", type="number", format="float", example="10.00", description="The tax rate"), | ||||||
|  |  *       @OA\Property(property="tax_rate2", type="number", format="float", example="10.00", description="The tax rate"), | ||||||
|  |  *       @OA\Property(property="tax_name3", type="string", example="", description="The tax name"), | ||||||
|  |  *       @OA\Property(property="tax_rate3", type="number", format="float", example="10.00", description="The tax rate"), | ||||||
|  |  *       @OA\Property(property="total_taxes", type="number", format="float", example="10.00", description="The total taxes for the quote"), | ||||||
|  |  *       @OA\Property(property="line_items", type="object", example="", description="An array of objects which define the line items of the quote"), | ||||||
|  |  *       @OA\Property(property="amount", type="number", format="float", example="10.00", description="The quote amount"), | ||||||
|  |  *       @OA\Property(property="balance", type="number", format="float", example="10.00", description="The quote balance"), | ||||||
|  |  *       @OA\Property(property="paid_to_date", type="number", format="float", example="10.00", description="The amount paid on the quote to date"), | ||||||
|  |  *       @OA\Property(property="discount", type="number", format="float", example="10.00", description="The quote discount, can be an amount or a percentage"), | ||||||
|  |  *       @OA\Property(property="partial", type="number", format="float", example="10.00", description="The deposit/partial amount"), | ||||||
|  |  *       @OA\Property(property="is_amount_discount", type="boolean", example=true, description="Flag determining if the discount is an amount or a percentage"), | ||||||
|  |  *       @OA\Property(property="is_deleted", type="boolean", example=true, description="Defines if the quote has been deleted"), | ||||||
|  |  *       @OA\Property(property="uses_inclusive_taxes", type="boolean", example=true, description="Defines the type of taxes used as either inclusive or exclusive"), | ||||||
|  |  *       @OA\Property(property="date", type="string", format="date", example="1994-07-30", description="The quote Date"), | ||||||
|  |  *       @OA\Property(property="last_sent_date", type="string", format="date", example="1994-07-30", description="The last date the quote was sent out"), | ||||||
|  |  *       @OA\Property(property="next_send_date", type="string", format="date", example="1994-07-30", description="The Next date for a reminder to be sent"), | ||||||
|  |  *       @OA\Property(property="partial_due_date", type="string", format="date", example="1994-07-30", description="The due date for the deposit/partial amount"), | ||||||
|  |  *       @OA\Property(property="due_date", type="string", format="date", example="1994-07-30", description="The due date of the quote"), | ||||||
|  |  *       @OA\Property(property="settings",ref="#/components/schemas/CompanySettings"), | ||||||
|  |  *       @OA\Property(property="last_viewed", type="number", format="integer", example="1434342123", description="Timestamp"), | ||||||
|  |  *       @OA\Property(property="updated_at", type="number", format="integer", example="1434342123", description="Timestamp"), | ||||||
|  |  *       @OA\Property(property="archived_at", type="number", format="integer", example="1434342123", description="Timestamp"), | ||||||
|  |  *       @OA\Property(property="custom_surcharge1", type="number", format="float", example="10.00", description="First Custom Surcharge"), | ||||||
|  |  *       @OA\Property(property="custom_surcharge2", type="number", format="float", example="10.00", description="Second Custom Surcharge"), | ||||||
|  |  *       @OA\Property(property="custom_surcharge3", type="number", format="float", example="10.00", description="Third Custom Surcharge"), | ||||||
|  |  *       @OA\Property(property="custom_surcharge4", type="number", format="float", example="10.00", description="Fourth Custom Surcharge"), | ||||||
|  |  *       @OA\Property(property="custom_surcharge_tax1", type="boolean", example=true, description="Toggles charging taxes on custom surcharge amounts"), | ||||||
|  |  *       @OA\Property(property="custom_surcharge_tax2", type="boolean", example=true, description="Toggles charging taxes on custom surcharge amounts"), | ||||||
|  |  *       @OA\Property(property="custom_surcharge_tax3", type="boolean", example=true, description="Toggles charging taxes on custom surcharge amounts"), | ||||||
|  |  *       @OA\Property(property="custom_surcharge_tax4", type="boolean", example=true, description="Toggles charging taxes on custom surcharge amounts"), | ||||||
|  * ) |  * ) | ||||||
|  */ |  */ | ||||||
|  | |||||||
| @ -11,7 +11,7 @@ | |||||||
|  *       @OA\Property(property="category_id", type="integer", example=1, description="The Category Type ID"), |  *       @OA\Property(property="category_id", type="integer", example=1, description="The Category Type ID"), | ||||||
|  *       @OA\Property(property="type_id", type="integer", example=1, description="The Type Type ID"), |  *       @OA\Property(property="type_id", type="integer", example=1, description="The Type Type ID"), | ||||||
|  *       @OA\Property(property="log", type="object", example="{'key':'value'}", description="The json object of the error"), |  *       @OA\Property(property="log", type="object", example="{'key':'value'}", description="The json object of the error"), | ||||||
|  *       @OA\Property(property="updated_at", type="string", example="2", description="______"), |  *       @OA\Property(property="updated_at", type="string", example="2", description="Timestamp"), | ||||||
|  *       @OA\Property(property="created_at", type="string", example="2", description="______"), |  *       @OA\Property(property="created_at", type="string", example="2", description="Timestamp"), | ||||||
|  * ) |  * ) | ||||||
|  */ |  */ | ||||||
|  | |||||||
| @ -3,25 +3,25 @@ | |||||||
|  * @OA\Schema( |  * @OA\Schema( | ||||||
|  *   schema="Task", |  *   schema="Task", | ||||||
|  *   type="object", |  *   type="object", | ||||||
|  *       @OA\Property(property="id", type="string", example="Opnel5aKBz", description="_________"), |  *       @OA\Property(property="id", type="string", example="Opnel5aKBz", description="The hashed id of the task"), | ||||||
|  *       @OA\Property(property="user_id", type="string", example="", description="__________"), |  *       @OA\Property(property="user_id", type="string", example="Opnel5aKBz", description="The hashed id of the user who created the task"), | ||||||
|  *       @OA\Property(property="assigned_user_id", type="string", example="", description="__________"), |  *       @OA\Property(property="assigned_user_id", type="string", example="Opnel5aKBz", description="The assigned user of the task"), | ||||||
|  *       @OA\Property(property="company_id", type="string", example="", description="________"), |  *       @OA\Property(property="company_id", type="string", example="Opnel5aKBz", description="The hashed id of the company"), | ||||||
|  *       @OA\Property(property="client_id", type="string", example="", description="________"), |  *       @OA\Property(property="client_id", type="string", example="Opnel5aKBz", description="The hashed if of the client"), | ||||||
|  *       @OA\Property(property="invoice_id", type="string", example="", description="________"), |  *       @OA\Property(property="invoice_id", type="string", example="Opnel5aKBz", description="The hashed id of the invoice associated with the task"), | ||||||
|  *       @OA\Property(property="project_id", type="string", example="", description="________"), |  *       @OA\Property(property="project_id", type="string", example="Opnel5aKBz", description="The hashed id of the project associated with the task"), | ||||||
|  *       @OA\Property(property="number", type="string", example="", description="________"), |  *       @OA\Property(property="number", type="string", example="TASK-123", description="The number of the task"), | ||||||
|  *       @OA\Property(property="time_log", type="string", example="", description="________"), |  *       @OA\Property(property="time_log", type="string", example="[[1,2],[3,4]]", description="An array of unix time stamps defining the start and end times of the task"), | ||||||
|  *       @OA\Property(property="is_running", type="boolean", example=true, description="________"), |  *       @OA\Property(property="is_running", type="boolean", example=true, description="Determines if the task is still running"), | ||||||
|  *       @OA\Property(property="is_deleted", type="boolean", example=true, description="________"), |  *       @OA\Property(property="is_deleted", type="boolean", example=true, description="Boolean flag determining if the task has been deleted"), | ||||||
|  *       @OA\Property(property="task_status_id", type="string", example="", description="________"), |  *       @OA\Property(property="task_status_id", type="string", example="Opnel5aKBz", description="The hashed id of the task status"), | ||||||
|  *       @OA\Property(property="description", type="string", example="", description="________"), |  *       @OA\Property(property="description", type="string", example="A wonder task to work on", description="The task description"), | ||||||
|  *       @OA\Property(property="duration", type="integer", example="", description="________"), |  *       @OA\Property(property="duration", type="integer", example="", description="The task duration"), | ||||||
|  *       @OA\Property(property="task_status_order", type="integer", example="", description="________"), |  *       @OA\Property(property="task_status_order", type="integer", example="4", description="The order of the task"), | ||||||
|  *       @OA\Property(property="custom_value1", type="string", example="", description="________"), |  *       @OA\Property(property="custom_value1", type="string", example="2022-10-10", description="A custom value"), | ||||||
|  *       @OA\Property(property="custom_value2", type="string", example="", description="________"), |  *       @OA\Property(property="custom_value2", type="string", example="$1100", description="A custom value"), | ||||||
|  *       @OA\Property(property="custom_value3", type="string", example="", description="________"), |  *       @OA\Property(property="custom_value3", type="string", example="I need help", description="A custom value"), | ||||||
|  *       @OA\Property(property="custom_value4", type="string", example="", description="________"), |  *       @OA\Property(property="custom_value4", type="string", example="INV-3343", description="A custom value"), | ||||||
|  *       @OA\Property(property="created_at", type="number", format="integer", example="1434342123", description="Timestamp"), |  *       @OA\Property(property="created_at", type="number", format="integer", example="1434342123", description="Timestamp"), | ||||||
|  *       @OA\Property(property="updated_at", type="number", format="integer", example="1434342123", description="Timestamp"), |  *       @OA\Property(property="updated_at", type="number", format="integer", example="1434342123", description="Timestamp"), | ||||||
|  *       @OA\Property(property="archived_at", type="number", format="integer", example="1434342123", description="Timestamp"), |  *       @OA\Property(property="archived_at", type="number", format="integer", example="1434342123", description="Timestamp"), | ||||||
|  | |||||||
| @ -5,7 +5,7 @@ | |||||||
|  *   type="object", |  *   type="object", | ||||||
|  *       @OA\Property(property="name", type="string", example="Backlog", description="The task status name"), |  *       @OA\Property(property="name", type="string", example="Backlog", description="The task status name"), | ||||||
|  *       @OA\Property(property="created_at", type="number", format="integer", example="134341234234", description="Timestamp"), |  *       @OA\Property(property="created_at", type="number", format="integer", example="134341234234", description="Timestamp"), | ||||||
|  *       @OA\Property(property="is_deleted", type="boolean", example=true, description="______"), |  *       @OA\Property(property="is_deleted", type="boolean", example=true, description="A boolean flag determining if the task status has been deleted"), | ||||||
|  *       @OA\Property(property="updated_at", type="number", format="integer", example="134341234234", description="Timestamp"), |  *       @OA\Property(property="updated_at", type="number", format="integer", example="134341234234", description="Timestamp"), | ||||||
|  *       @OA\Property(property="archived_at", type="number", format="integer", example="134341234234", description="Timestamp"), |  *       @OA\Property(property="archived_at", type="number", format="integer", example="134341234234", description="Timestamp"), | ||||||
|  * ) |  * ) | ||||||
|  | |||||||
| @ -3,9 +3,9 @@ | |||||||
|  * @OA\Schema( |  * @OA\Schema( | ||||||
|  *   schema="TaxRate", |  *   schema="TaxRate", | ||||||
|  *   type="object", |  *   type="object", | ||||||
|  *       @OA\Property(property="id", type="string", example="Opnel5aKBz", description="______"), |  *       @OA\Property(property="id", type="string", example="Opnel5aKBz", description="Thie hashed id of the tax"), | ||||||
|  *       @OA\Property(property="name", type="string", example="GST", description="______"), |  *       @OA\Property(property="name", type="string", example="GST", description="The tax name"), | ||||||
|  *       @OA\Property(property="rate", type="number", example="10", description="______"), |  *       @OA\Property(property="rate", type="number", example="10", description="The tax rate"), | ||||||
|  *       @OA\Property(property="is_deleted", type="boolean", example=true, description="______"), |  *       @OA\Property(property="is_deleted", type="boolean", example=true, description="Boolean flag determining if the tax has been deleted"), | ||||||
|  * ) |  * ) | ||||||
|  */ |  */ | ||||||
|  | |||||||
| @ -3,15 +3,15 @@ | |||||||
|  * @OA\Schema( |  * @OA\Schema( | ||||||
|  *   schema="User", |  *   schema="User", | ||||||
|  *   type="object", |  *   type="object", | ||||||
|  *       @OA\Property(property="id", type="string", example="Opnel5aKBz", description="__________"), |  *       @OA\Property(property="id", type="string", example="Opnel5aKBz", description="The hashed id of the user"), | ||||||
|  *       @OA\Property(property="first_name", type="string", example="The users first name", description="________"), |  *       @OA\Property(property="first_name", type="string", example="Brad", description="The first name of the user"), | ||||||
|  *       @OA\Property(property="last_name", type="string", example="The users last name", description="_________"), |  *       @OA\Property(property="last_name", type="string", example="Pitt", description="The last name of the user"), | ||||||
|  *       @OA\Property(property="email", type="string", example="", description="_________"), |  *       @OA\Property(property="email", type="string", example="brad@pitt.com", description="The users email address"), | ||||||
|  *       @OA\Property(property="phone", type="string", example="555-1233-23232", description="_________"), |  *       @OA\Property(property="phone", type="string", example="555-1233-23232", description="The users phone number"), | ||||||
|  *       @OA\Property(property="signature", type="string", example="A users text signature", description="_________"), |  *       @OA\Property(property="signature", type="string", example="Have a nice day!", description="The users sign off signature"), | ||||||
|  *       @OA\Property(property="avatar", type="string", example="https://url.to.your/avatar.png", description="_________"), |  *       @OA\Property(property="avatar", type="string", example="https://url.to.your/avatar.png", description="The users avatar"), | ||||||
|  *       @OA\Property(property="accepted_terms_version", type="string", example="1.0.1", description="_________"), |  *       @OA\Property(property="accepted_terms_version", type="string", example="1.0.1", description="The version of the invoice ninja terms that has been accepted by the user"), | ||||||
|  *       @OA\Property(property="oauth_user_id", type="string", example="jkhasdf789as6f675sdf768sdfs", description="_________"), |  *       @OA\Property(property="oauth_user_id", type="string", example="jkhasdf789as6f675sdf768sdfs", description="The provider id of the oauth entity"), | ||||||
|  *       @OA\Property(property="oauth_provider_id", type="string", example="google", description="_________"), |  *       @OA\Property(property="oauth_provider_id", type="string", example="google", description="The oauth entity id"), | ||||||
|  * ) |  * ) | ||||||
|  */ |  */ | ||||||
|  | |||||||
| @ -3,19 +3,19 @@ | |||||||
|  * @OA\Schema( |  * @OA\Schema( | ||||||
|  *   schema="VendorContact", |  *   schema="VendorContact", | ||||||
|  *   type="object", |  *   type="object", | ||||||
|  *       @OA\Property(property="id", type="string", example="Opnel5aKBz", description="_________"), |  *       @OA\Property(property="id", type="string", example="Opnel5aKBz", description="The hashed id of the vendor contact"), | ||||||
|  *       @OA\Property(property="user_id", type="string", example="", description="__________"), |  *       @OA\Property(property="user_id", type="string", example="Opnel5aKBz", description="The hashed id of the user id"), | ||||||
|  *       @OA\Property(property="company_id", type="string", example="", description="________"), |  *       @OA\Property(property="company_id", type="string", example="Opnel5aKBz", description="The hashed id of the company"), | ||||||
|  *       @OA\Property(property="vendor_id", type="string", example="", description="________"), |  *       @OA\Property(property="vendor_id", type="string", example="Opnel5aKBz", description="The hashed id of the vendor"), | ||||||
|  *       @OA\Property(property="first_name", type="string", example="", description="________"), |  *       @OA\Property(property="first_name", type="string", example="Harry", description="The first name of the contact"), | ||||||
|  *       @OA\Property(property="last_name", type="string", example="", description="________"), |  *       @OA\Property(property="last_name", type="string", example="Windsor", description="The last name of the contact"), | ||||||
|  *       @OA\Property(property="phone", type="string", example="", description="________"), |  *       @OA\Property(property="phone", type="string", example="555-123-1234", description="The contacts phone number"), | ||||||
|  *       @OA\Property(property="custom_value1", type="string", example="", description="________"), |  *       @OA\Property(property="custom_value1", type="string", example="2022-10-10", description="A custom value"), | ||||||
|  *       @OA\Property(property="custom_value2", type="string", example="", description="________"), |  *       @OA\Property(property="custom_value2", type="string", example="$1000", description="A custom value"), | ||||||
|  *       @OA\Property(property="custom_value3", type="string", example="", description="________"), |  *       @OA\Property(property="custom_value3", type="string", example="", description="A custom value"), | ||||||
|  *       @OA\Property(property="custom_value4", type="string", example="", description="________"), |  *       @OA\Property(property="custom_value4", type="string", example="", description="A custom value"), | ||||||
|  *       @OA\Property(property="email", type="string", example="", description="________"), |  *       @OA\Property(property="email", type="string", example="harry@windsor.com", description="The contact email address"), | ||||||
|  *       @OA\Property(property="is_primary", type="boolean", example=true, description="________"), |  *       @OA\Property(property="is_primary", type="boolean", example=true, description="Boolean flag determining if the contact is the primary contact for the vendor"), | ||||||
|  *       @OA\Property(property="created_at", type="number", format="integer", example="134341234234", description="Timestamp"), |  *       @OA\Property(property="created_at", type="number", format="integer", example="134341234234", description="Timestamp"), | ||||||
|  *       @OA\Property(property="updated_at", type="number", format="integer", example="134341234234", description="Timestamp"), |  *       @OA\Property(property="updated_at", type="number", format="integer", example="134341234234", description="Timestamp"), | ||||||
|  *       @OA\Property(property="deleted_at", type="number", format="integer", example="134341234234", description="Timestamp"), |  *       @OA\Property(property="deleted_at", type="number", format="integer", example="134341234234", description="Timestamp"), | ||||||
|  | |||||||
| @ -3,11 +3,11 @@ | |||||||
|  * @OA\Schema( |  * @OA\Schema( | ||||||
|  *   schema="Vendor", |  *   schema="Vendor", | ||||||
|  *   type="object", |  *   type="object", | ||||||
|  *       @OA\Property(property="id", type="string", example="Opnel5aKBz", description="_________"), |  *       @OA\Property(property="id", type="string", example="Opnel5aKBz", description="The hashed id of the vendor"), | ||||||
|  *       @OA\Property(property="user_id", type="string", example="", description="__________"), |  *       @OA\Property(property="user_id", type="string", example="Opnel5aKBz", description="The hashed id of the user who created the vendor"), | ||||||
|  *       @OA\Property(property="assigned_user_id", type="string", example="", description="__________"), |  *       @OA\Property(property="assigned_user_id", type="string", example="Opnel5aKBz", description="The hashed id of the assigned user to this vendor"), | ||||||
|  *       @OA\Property(property="company_id", type="string", example="", description="________"), |  *       @OA\Property(property="company_id", type="string", example="Opnel5aKBz", description="The hashed id of the company"), | ||||||
|  *       @OA\Property(property="client_id", type="string", example="", description="________"), |  *       @OA\Property(property="client_id", type="string", example="Opnel5aKBz", description="The hashed id of the client"), | ||||||
|  *       @OA\Property( |  *       @OA\Property( | ||||||
|  *       	property="contacts", |  *       	property="contacts", | ||||||
|  *        	type="array", |  *        	type="array", | ||||||
| @ -16,10 +16,10 @@ | |||||||
|  *           	ref="#/components/schemas/VendorContact", |  *           	ref="#/components/schemas/VendorContact", | ||||||
|  *          ), |  *          ), | ||||||
|  *       ), |  *       ), | ||||||
|  *       @OA\Property(property="name", type="string", example="", description="________"), |  *       @OA\Property(property="name", type="string", example="Harry's cafe de wheels", description="The vendor name"), | ||||||
|  *       @OA\Property(property="website", type="string", example="", description="________"), |  *       @OA\Property(property="website", type="string", example="www.harry.com", description="The website of the vendor"), | ||||||
|  *       @OA\Property(property="private_notes", type="string", example="", description="________"), |  *       @OA\Property(property="private_notes", type="string", example="Shhh, don't tell the vendor", description="The private notes of the vendor"), | ||||||
|  *       @OA\Property(property="industry_id", type="string", example="", description="________"), |  *       @OA\Property(property="industry_id", type="string", example="1", description="The industry id of the vendor"), | ||||||
|  *       @OA\Property(property="size_id", type="string", example="", description="________"), |  *       @OA\Property(property="size_id", type="string", example="", description="________"), | ||||||
|  *       @OA\Property(property="address1", type="string", example="", description="________"), |  *       @OA\Property(property="address1", type="string", example="", description="________"), | ||||||
|  *       @OA\Property(property="address2", type="string", example="", description="________"), |  *       @OA\Property(property="address2", type="string", example="", description="________"), | ||||||
|  | |||||||
| @ -52,6 +52,7 @@ class QueryLogging | |||||||
| 
 | 
 | ||||||
|             // nlog("Query count = {$count}");
 |             // nlog("Query count = {$count}");
 | ||||||
|             // nlog($queries);
 |             // nlog($queries);
 | ||||||
|  |             // nlog($request->url());
 | ||||||
|              |              | ||||||
|             if ($count > 175) { |             if ($count > 175) { | ||||||
|                 nlog("Query count = {$count}"); |                 nlog("Query count = {$count}"); | ||||||
|  | |||||||
| @ -65,7 +65,7 @@ class VendorContactKeyLogin | |||||||
|                 return redirect($this->setRedirectPath()); |                 return redirect($this->setRedirectPath()); | ||||||
|             } |             } | ||||||
|         } elseif ($request->segment(3) && config('ninja.db.multi_db_enabled')) { |         } elseif ($request->segment(3) && config('ninja.db.multi_db_enabled')) { | ||||||
|             if (MultiDB::findAndSetDbByContactKey($request->segment(3))) { |             if (MultiDB::findAndSetDbByVendorContactKey($request->segment(3))) { | ||||||
|                 if ($vendor_contact = VendorContact::where('contact_key', $request->segment(3))->first()) { |                 if ($vendor_contact = VendorContact::where('contact_key', $request->segment(3))->first()) { | ||||||
|                     if (empty($vendor_contact->email)) { |                     if (empty($vendor_contact->email)) { | ||||||
|                         $vendor_contact->email = Str::random(6).'@example.com'; |                         $vendor_contact->email = Str::random(6).'@example.com'; | ||||||
|  | |||||||
| @ -0,0 +1,28 @@ | |||||||
|  | <?php | ||||||
|  | /** | ||||||
|  |  * Invoice Ninja (https://invoiceninja.com). | ||||||
|  |  * | ||||||
|  |  * @link https://github.com/invoiceninja/invoiceninja source repository | ||||||
|  |  * | ||||||
|  |  * @copyright Copyright (c) 2022. Invoice Ninja LLC (https://invoiceninja.com) | ||||||
|  |  * | ||||||
|  |  * @license https://www.elastic.co/licensing/elastic-license | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | namespace App\Http\Requests\BankIntegration; | ||||||
|  | 
 | ||||||
|  | use App\Http\Requests\Request; | ||||||
|  | use App\Models\BankIntegration; | ||||||
|  | 
 | ||||||
|  | class AdminBankIntegrationRequest extends Request | ||||||
|  | { | ||||||
|  |     /** | ||||||
|  |      * Determine if the user is authorized to make this request. | ||||||
|  |      * | ||||||
|  |      * @return bool | ||||||
|  |      */ | ||||||
|  |     public function authorize() : bool | ||||||
|  |     { | ||||||
|  |         return auth()->user()->isAdmin(); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,28 @@ | |||||||
|  | <?php | ||||||
|  | /** | ||||||
|  |  * Invoice Ninja (https://invoiceninja.com). | ||||||
|  |  * | ||||||
|  |  * @link https://github.com/invoiceninja/invoiceninja source repository | ||||||
|  |  * | ||||||
|  |  * @copyright Copyright (c) 2022. Invoice Ninja LLC (https://invoiceninja.com) | ||||||
|  |  * | ||||||
|  |  * @license https://www.elastic.co/licensing/elastic-license | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | namespace App\Http\Requests\BankIntegration; | ||||||
|  | 
 | ||||||
|  | use App\Http\Requests\Request; | ||||||
|  | use App\Models\BankIntegration; | ||||||
|  | 
 | ||||||
|  | class CreateBankIntegrationRequest extends Request | ||||||
|  | { | ||||||
|  |     /** | ||||||
|  |      * Determine if the user is authorized to make this request. | ||||||
|  |      * | ||||||
|  |      * @return bool | ||||||
|  |      */ | ||||||
|  |     public function authorize() : bool | ||||||
|  |     { | ||||||
|  |         return auth()->user()->can('create', BankIntegration::class); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,27 @@ | |||||||
|  | <?php | ||||||
|  | /** | ||||||
|  |  * Invoice Ninja (https://invoiceninja.com). | ||||||
|  |  * | ||||||
|  |  * @link https://github.com/invoiceninja/invoiceninja source repository | ||||||
|  |  * | ||||||
|  |  * @copyright Copyright (c) 2022. Invoice Ninja LLC (https://invoiceninja.com) | ||||||
|  |  * | ||||||
|  |  * @license https://www.elastic.co/licensing/elastic-license | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | namespace App\Http\Requests\BankIntegration; | ||||||
|  | 
 | ||||||
|  | use App\Http\Requests\Request; | ||||||
|  | 
 | ||||||
|  | class DestroyBankIntegrationRequest extends Request | ||||||
|  | { | ||||||
|  |     /** | ||||||
|  |      * Determine if the user is authorized to make this request. | ||||||
|  |      * | ||||||
|  |      * @return bool | ||||||
|  |      */ | ||||||
|  |     public function authorize() : bool | ||||||
|  |     { | ||||||
|  |         return auth()->user()->can('edit', $this->bank_integration); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,27 @@ | |||||||
|  | <?php | ||||||
|  | /** | ||||||
|  |  * Invoice Ninja (https://invoiceninja.com). | ||||||
|  |  * | ||||||
|  |  * @link https://github.com/invoiceninja/invoiceninja source repository | ||||||
|  |  * | ||||||
|  |  * @copyright Copyright (c) 2022. Invoice Ninja LLC (https://invoiceninja.com) | ||||||
|  |  * | ||||||
|  |  * @license https://www.elastic.co/licensing/elastic-license | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | namespace App\Http\Requests\BankIntegration; | ||||||
|  | 
 | ||||||
|  | use App\Http\Requests\Request; | ||||||
|  | 
 | ||||||
|  | class EditBankIntegrationRequest extends Request | ||||||
|  | { | ||||||
|  |     /** | ||||||
|  |      * Determine if the user is authorized to make this request. | ||||||
|  |      * | ||||||
|  |      * @return bool | ||||||
|  |      */ | ||||||
|  |     public function authorize() : bool | ||||||
|  |     { | ||||||
|  |         return auth()->user()->can('edit', $this->bank_integration); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,27 @@ | |||||||
|  | <?php | ||||||
|  | /** | ||||||
|  |  * Invoice Ninja (https://invoiceninja.com). | ||||||
|  |  * | ||||||
|  |  * @link https://github.com/invoiceninja/invoiceninja source repository | ||||||
|  |  * | ||||||
|  |  * @copyright Copyright (c) 2022. Invoice Ninja LLC (https://invoiceninja.com) | ||||||
|  |  * | ||||||
|  |  * @license https://www.elastic.co/licensing/elastic-license | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | namespace App\Http\Requests\BankIntegration; | ||||||
|  | 
 | ||||||
|  | use App\Http\Requests\Request; | ||||||
|  | 
 | ||||||
|  | class ShowBankIntegrationRequest extends Request | ||||||
|  | { | ||||||
|  |     /** | ||||||
|  |      * Determine if the user is authorized to make this request. | ||||||
|  |      * | ||||||
|  |      * @return bool | ||||||
|  |      */ | ||||||
|  |     public function authorize() : bool | ||||||
|  |     { | ||||||
|  |         return auth()->user()->can('view', $this->bank_integration); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,57 @@ | |||||||
|  | <?php | ||||||
|  | /** | ||||||
|  |  * Invoice Ninja (https://invoiceninja.com). | ||||||
|  |  * | ||||||
|  |  * @link https://github.com/invoiceninja/invoiceninja source repository | ||||||
|  |  * | ||||||
|  |  * @copyright Copyright (c) 2022. Invoice Ninja LLC (https://invoiceninja.com) | ||||||
|  |  * | ||||||
|  |  * @license https://www.elastic.co/licensing/elastic-license | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | namespace App\Http\Requests\BankIntegration; | ||||||
|  | 
 | ||||||
|  | use App\Http\Requests\Request; | ||||||
|  | use App\Models\BankIntegration; | ||||||
|  | use App\Utils\Traits\MakesHash; | ||||||
|  | 
 | ||||||
|  | class StoreBankIntegrationRequest extends Request | ||||||
|  | { | ||||||
|  |     use MakesHash; | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Determine if the user is authorized to make this request. | ||||||
|  |      * | ||||||
|  |      * @return bool | ||||||
|  |      */ | ||||||
|  |     public function authorize() : bool | ||||||
|  |     { | ||||||
|  |         return auth()->user()->can('create', BankIntegration::class); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public function rules() | ||||||
|  |     { | ||||||
|  |          | ||||||
|  |         $rules = [ | ||||||
|  |             'bank_account_name' => 'required|min:3' | ||||||
|  |         ]; | ||||||
|  | 
 | ||||||
|  |         return $rules; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public function prepareForValidation() | ||||||
|  |     { | ||||||
|  |         $input = $this->all(); | ||||||
|  | 
 | ||||||
|  |         if(!array_key_exists('provider_name', $input) || strlen($input['provider_name']) == 0) | ||||||
|  |             $input['provider_name'] = $input['bank_account_name']; | ||||||
|  | 
 | ||||||
|  |         $this->replace($input); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public function messages() | ||||||
|  |     { | ||||||
|  |         return []; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } | ||||||
| @ -0,0 +1,51 @@ | |||||||
|  | <?php | ||||||
|  | /** | ||||||
|  |  * Invoice Ninja (https://invoiceninja.com). | ||||||
|  |  * | ||||||
|  |  * @link https://github.com/invoiceninja/invoiceninja source repository | ||||||
|  |  * | ||||||
|  |  * @copyright Copyright (c) 2022. Invoice Ninja LLC (https://invoiceninja.com) | ||||||
|  |  * | ||||||
|  |  * @license https://www.elastic.co/licensing/elastic-license | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | namespace App\Http\Requests\BankIntegration; | ||||||
|  | 
 | ||||||
|  | use App\Http\Requests\Request; | ||||||
|  | use App\Utils\Traits\MakesHash; | ||||||
|  | 
 | ||||||
|  | class UpdateBankIntegrationRequest extends Request | ||||||
|  | { | ||||||
|  |     use MakesHash; | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Determine if the user is authorized to make this request. | ||||||
|  |      * | ||||||
|  |      * @return bool | ||||||
|  |      */ | ||||||
|  |     public function authorize() : bool | ||||||
|  |     { | ||||||
|  |         return auth()->user()->can('edit', $this->bank_integration); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public function rules() | ||||||
|  |     { | ||||||
|  |         /* Ensure we have a client name, and that all emails are unique*/ | ||||||
|  |         $rules = []; | ||||||
|  | 
 | ||||||
|  |         return $rules; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public function messages() | ||||||
|  |     { | ||||||
|  |         return [ ]; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public function prepareForValidation() | ||||||
|  |     { | ||||||
|  |         $input = $this->all(); | ||||||
|  | 
 | ||||||
|  |         $this->replace($input); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } | ||||||
| @ -0,0 +1,38 @@ | |||||||
|  | <?php | ||||||
|  | /** | ||||||
|  |  * Invoice Ninja (https://invoiceninja.com). | ||||||
|  |  * | ||||||
|  |  * @link https://github.com/invoiceninja/invoiceninja source repository | ||||||
|  |  * | ||||||
|  |  * @copyright Copyright (c) 2022. Invoice Ninja LLC (https://invoiceninja.com) | ||||||
|  |  * | ||||||
|  |  * @license https://www.elastic.co/licensing/elastic-license | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | namespace App\Http\Requests\BankIntegration; | ||||||
|  | 
 | ||||||
|  | use App\Http\Requests\Request; | ||||||
|  | 
 | ||||||
|  | class UploadBankIntegrationRequest extends Request | ||||||
|  | { | ||||||
|  |     /** | ||||||
|  |      * Determine if the user is authorized to make this request. | ||||||
|  |      * | ||||||
|  |      * @return bool | ||||||
|  |      */ | ||||||
|  |     public function authorize() : bool | ||||||
|  |     { | ||||||
|  |         return auth()->user()->can('edit', $this->bank_integration); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public function rules() | ||||||
|  |     { | ||||||
|  |         $rules = []; | ||||||
|  | 
 | ||||||
|  |         if ($this->input('documents')) { | ||||||
|  |             $rules['documents'] = 'file|mimes:csv,png,ai,jpeg,tiff,pdf,gif,psd,txt,doc,xls,ppt,xlsx,docx,pptx|max:2000000'; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         return $rules; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,28 @@ | |||||||
|  | <?php | ||||||
|  | /** | ||||||
|  |  * Invoice Ninja (https://invoiceninja.com). | ||||||
|  |  * | ||||||
|  |  * @link https://github.com/invoiceninja/invoiceninja source repository | ||||||
|  |  * | ||||||
|  |  * @copyright Copyright (c) 2022. Invoice Ninja LLC (https://invoiceninja.com) | ||||||
|  |  * | ||||||
|  |  * @license https://www.elastic.co/licensing/elastic-license | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | namespace App\Http\Requests\BankTransaction; | ||||||
|  | 
 | ||||||
|  | use App\Http\Requests\Request; | ||||||
|  | use App\Models\BankTransaction; | ||||||
|  | 
 | ||||||
|  | class AdminBankTransactionRequest extends Request | ||||||
|  | { | ||||||
|  |     /** | ||||||
|  |      * Determine if the user is authorized to make this request. | ||||||
|  |      * | ||||||
|  |      * @return bool | ||||||
|  |      */ | ||||||
|  |     public function authorize() : bool | ||||||
|  |     { | ||||||
|  |         return auth()->user()->isAdmin(); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,28 @@ | |||||||
|  | <?php | ||||||
|  | /** | ||||||
|  |  * Invoice Ninja (https://invoiceninja.com). | ||||||
|  |  * | ||||||
|  |  * @link https://github.com/invoiceninja/invoiceninja source repository | ||||||
|  |  * | ||||||
|  |  * @copyright Copyright (c) 2022. Invoice Ninja LLC (https://invoiceninja.com) | ||||||
|  |  * | ||||||
|  |  * @license https://www.elastic.co/licensing/elastic-license | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | namespace App\Http\Requests\BankTransaction; | ||||||
|  | 
 | ||||||
|  | use App\Http\Requests\Request; | ||||||
|  | use App\Models\BankTransaction; | ||||||
|  | 
 | ||||||
|  | class CreateBankTransactionRequest extends Request | ||||||
|  | { | ||||||
|  |     /** | ||||||
|  |      * Determine if the user is authorized to make this request. | ||||||
|  |      * | ||||||
|  |      * @return bool | ||||||
|  |      */ | ||||||
|  |     public function authorize() : bool | ||||||
|  |     { | ||||||
|  |         return auth()->user()->can('create', BankTransaction::class); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,27 @@ | |||||||
|  | <?php | ||||||
|  | /** | ||||||
|  |  * Invoice Ninja (https://invoiceninja.com). | ||||||
|  |  * | ||||||
|  |  * @link https://github.com/invoiceninja/invoiceninja source repository | ||||||
|  |  * | ||||||
|  |  * @copyright Copyright (c) 2022. Invoice Ninja LLC (https://invoiceninja.com) | ||||||
|  |  * | ||||||
|  |  * @license https://www.elastic.co/licensing/elastic-license | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | namespace App\Http\Requests\BankTransaction; | ||||||
|  | 
 | ||||||
|  | use App\Http\Requests\Request; | ||||||
|  | 
 | ||||||
|  | class DestroyBankTransactionRequest extends Request | ||||||
|  | { | ||||||
|  |     /** | ||||||
|  |      * Determine if the user is authorized to make this request. | ||||||
|  |      * | ||||||
|  |      * @return bool | ||||||
|  |      */ | ||||||
|  |     public function authorize() : bool | ||||||
|  |     { | ||||||
|  |         return auth()->user()->can('edit', $this->bank_transaction); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,27 @@ | |||||||
|  | <?php | ||||||
|  | /** | ||||||
|  |  * Invoice Ninja (https://invoiceninja.com). | ||||||
|  |  * | ||||||
|  |  * @link https://github.com/invoiceninja/invoiceninja source repository | ||||||
|  |  * | ||||||
|  |  * @copyright Copyright (c) 2022. Invoice Ninja LLC (https://invoiceninja.com) | ||||||
|  |  * | ||||||
|  |  * @license https://www.elastic.co/licensing/elastic-license | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | namespace App\Http\Requests\BankTransaction; | ||||||
|  | 
 | ||||||
|  | use App\Http\Requests\Request; | ||||||
|  | 
 | ||||||
|  | class EditBankTransactionRequest extends Request | ||||||
|  | { | ||||||
|  |     /** | ||||||
|  |      * Determine if the user is authorized to make this request. | ||||||
|  |      * | ||||||
|  |      * @return bool | ||||||
|  |      */ | ||||||
|  |     public function authorize() : bool | ||||||
|  |     { | ||||||
|  |         return auth()->user()->can('edit', $this->bank_transaction); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,67 @@ | |||||||
|  | <?php | ||||||
|  | /** | ||||||
|  |  * Invoice Ninja (https://invoiceninja.com). | ||||||
|  |  * | ||||||
|  |  * @link https://github.com/invoiceninja/invoiceninja source repository | ||||||
|  |  * | ||||||
|  |  * @copyright Copyright (c) 2022. Invoice Ninja LLC (https://invoiceninja.com) | ||||||
|  |  * | ||||||
|  |  * @license https://www.elastic.co/licensing/elastic-license | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | namespace App\Http\Requests\BankTransaction; | ||||||
|  | 
 | ||||||
|  | use App\Http\Requests\Request; | ||||||
|  | use App\Models\BankTransaction; | ||||||
|  | 
 | ||||||
|  | class ImportBankTransactionsRequest extends Request | ||||||
|  | { | ||||||
|  |     /** | ||||||
|  |      * Determine if the user is authorized to make this request. | ||||||
|  |      * | ||||||
|  |      * @return bool | ||||||
|  |      */ | ||||||
|  |     public function authorize() : bool | ||||||
|  |     { | ||||||
|  |         return auth()->user()->isAdmin(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public function rules() | ||||||
|  |     { | ||||||
|  | 
 | ||||||
|  |         $rules = [ | ||||||
|  |             'transactions' => 'bail|array', | ||||||
|  |             'transactions.*.id' => 'bail|required', | ||||||
|  |             'transactions.*.invoice_ids' => 'nullable|string|sometimes', | ||||||
|  |             'transactions.*.ninja_category_id' => 'nullable|string|sometimes' | ||||||
|  |         ]; | ||||||
|  | 
 | ||||||
|  |         $rules['transactions.*.vendor_id'] = 'bail|sometimes|exists:vendors,id,company_id,'.auth()->user()->company()->id.',is_deleted,0'; | ||||||
|  | 
 | ||||||
|  |         return $rules; | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public function prepareForValidation() | ||||||
|  |     { | ||||||
|  |         $inputs = $this->all(); | ||||||
|  |          | ||||||
|  |         foreach($inputs['transactions'] as $key => $input) | ||||||
|  |         { | ||||||
|  |          | ||||||
|  |             if(array_key_exists('id', $inputs['transactions'][$key])) | ||||||
|  |                 $inputs['transactions'][$key]['id'] = $this->decodePrimaryKey($input['id']); | ||||||
|  | 
 | ||||||
|  |             if(array_key_exists('ninja_category_id', $inputs['transactions'][$key]) && strlen($inputs['transactions'][$key]['ninja_category_id']) >= 1) | ||||||
|  |                 $inputs['transactions'][$key]['ninja_category_id'] = $this->decodePrimaryKey($inputs['transactions'][$key]['ninja_category_id']); | ||||||
|  | 
 | ||||||
|  |             if(array_key_exists('vendor_id', $inputs['transactions'][$key]) && strlen($inputs['transactions'][$key]['vendor_id']) >= 1) | ||||||
|  |                 $inputs['transactions'][$key]['vendor_id'] = $this->decodePrimaryKey($inputs['transactions'][$key]['vendor_id']); | ||||||
|  | 
 | ||||||
|  |             // $input = $this->decodePrimaryKeys($input);
 | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         $this->replace($inputs); | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,67 @@ | |||||||
|  | <?php | ||||||
|  | /** | ||||||
|  |  * Invoice Ninja (https://invoiceninja.com). | ||||||
|  |  * | ||||||
|  |  * @link https://github.com/invoiceninja/invoiceninja source repository | ||||||
|  |  * | ||||||
|  |  * @copyright Copyright (c) 2022. Invoice Ninja LLC (https://invoiceninja.com) | ||||||
|  |  * | ||||||
|  |  * @license https://www.elastic.co/licensing/elastic-license | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | namespace App\Http\Requests\BankTransaction; | ||||||
|  | 
 | ||||||
|  | use App\Http\Requests\Request; | ||||||
|  | use App\Models\BankTransaction; | ||||||
|  | 
 | ||||||
|  | class MatchBankTransactionRequest extends Request | ||||||
|  | { | ||||||
|  |     /** | ||||||
|  |      * Determine if the user is authorized to make this request. | ||||||
|  |      * | ||||||
|  |      * @return bool | ||||||
|  |      */ | ||||||
|  |     public function authorize() : bool | ||||||
|  |     { | ||||||
|  |         return auth()->user()->isAdmin(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public function rules() | ||||||
|  |     { | ||||||
|  | 
 | ||||||
|  |         $rules = [ | ||||||
|  |             'transactions' => 'bail|array', | ||||||
|  |             'transactions.*.id' => 'bail|required', | ||||||
|  |             'transactions.*.invoice_ids' => 'nullable|string|sometimes', | ||||||
|  |             'transactions.*.ninja_category_id' => 'nullable|string|sometimes' | ||||||
|  |         ]; | ||||||
|  | 
 | ||||||
|  |         $rules['transactions.*.vendor_id'] = 'bail|sometimes|exists:vendors,id,company_id,'.auth()->user()->company()->id.',is_deleted,0'; | ||||||
|  | 
 | ||||||
|  |         return $rules; | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public function prepareForValidation() | ||||||
|  |     { | ||||||
|  |         $inputs = $this->all(); | ||||||
|  |          | ||||||
|  |         foreach($inputs['transactions'] as $key => $input) | ||||||
|  |         { | ||||||
|  |          | ||||||
|  |             if(array_key_exists('id', $inputs['transactions'][$key])) | ||||||
|  |                 $inputs['transactions'][$key]['id'] = $this->decodePrimaryKey($input['id']); | ||||||
|  | 
 | ||||||
|  |             if(array_key_exists('ninja_category_id', $inputs['transactions'][$key]) && strlen($inputs['transactions'][$key]['ninja_category_id']) >= 1) | ||||||
|  |                 $inputs['transactions'][$key]['ninja_category_id'] = $this->decodePrimaryKey($inputs['transactions'][$key]['ninja_category_id']); | ||||||
|  | 
 | ||||||
|  |             if(array_key_exists('vendor_id', $inputs['transactions'][$key]) && strlen($inputs['transactions'][$key]['vendor_id']) >= 1) | ||||||
|  |                 $inputs['transactions'][$key]['vendor_id'] = $this->decodePrimaryKey($inputs['transactions'][$key]['vendor_id']); | ||||||
|  | 
 | ||||||
|  |             // $input = $this->decodePrimaryKeys($input);
 | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         $this->replace($inputs); | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,27 @@ | |||||||
|  | <?php | ||||||
|  | /** | ||||||
|  |  * Invoice Ninja (https://invoiceninja.com). | ||||||
|  |  * | ||||||
|  |  * @link https://github.com/invoiceninja/invoiceninja source repository | ||||||
|  |  * | ||||||
|  |  * @copyright Copyright (c) 2022. Invoice Ninja LLC (https://invoiceninja.com) | ||||||
|  |  * | ||||||
|  |  * @license https://www.elastic.co/licensing/elastic-license | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | namespace App\Http\Requests\BankTransaction; | ||||||
|  | 
 | ||||||
|  | use App\Http\Requests\Request; | ||||||
|  | 
 | ||||||
|  | class ShowBankTransactionRequest extends Request | ||||||
|  | { | ||||||
|  |     /** | ||||||
|  |      * Determine if the user is authorized to make this request. | ||||||
|  |      * | ||||||
|  |      * @return bool | ||||||
|  |      */ | ||||||
|  |     public function authorize() : bool | ||||||
|  |     { | ||||||
|  |         return auth()->user()->can('view', $this->bank_transaction); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,51 @@ | |||||||
|  | <?php | ||||||
|  | /** | ||||||
|  |  * Invoice Ninja (https://invoiceninja.com). | ||||||
|  |  * | ||||||
|  |  * @link https://github.com/invoiceninja/invoiceninja source repository | ||||||
|  |  * | ||||||
|  |  * @copyright Copyright (c) 2022. Invoice Ninja LLC (https://invoiceninja.com) | ||||||
|  |  * | ||||||
|  |  * @license https://www.elastic.co/licensing/elastic-license | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | namespace App\Http\Requests\BankTransaction; | ||||||
|  | 
 | ||||||
|  | use App\Http\Requests\Request; | ||||||
|  | use App\Models\BankTransaction; | ||||||
|  | use App\Utils\Traits\MakesHash; | ||||||
|  | 
 | ||||||
|  | class StoreBankTransactionRequest extends Request | ||||||
|  | { | ||||||
|  |     use MakesHash; | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Determine if the user is authorized to make this request. | ||||||
|  |      * | ||||||
|  |      * @return bool | ||||||
|  |      */ | ||||||
|  |     public function authorize() : bool | ||||||
|  |     { | ||||||
|  |         return auth()->user()->can('create', BankTransaction::class); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public function rules() | ||||||
|  |     { | ||||||
|  |          | ||||||
|  |         $rules = []; | ||||||
|  | 
 | ||||||
|  |         return $rules; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public function prepareForValidation() | ||||||
|  |     { | ||||||
|  |         $input = $this->all(); | ||||||
|  | 
 | ||||||
|  |             if(array_key_exists('bank_integration_id', $input) && strlen($input['bank_integration_id']) > 1) | ||||||
|  |                 $input['bank_integration_id'] = $this->decodePrimaryKey($input['bank_integration_id']); | ||||||
|  | 
 | ||||||
|  |         $this->replace($input); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | } | ||||||
| @ -0,0 +1,76 @@ | |||||||
|  | <?php | ||||||
|  | /** | ||||||
|  |  * Invoice Ninja (https://invoiceninja.com). | ||||||
|  |  * | ||||||
|  |  * @link https://github.com/invoiceninja/invoiceninja source repository | ||||||
|  |  * | ||||||
|  |  * @copyright Copyright (c) 2022. Invoice Ninja LLC (https://invoiceninja.com) | ||||||
|  |  * | ||||||
|  |  * @license https://www.elastic.co/licensing/elastic-license | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | namespace App\Http\Requests\BankTransaction; | ||||||
|  | 
 | ||||||
|  | use App\Http\Requests\Request; | ||||||
|  | use App\Utils\Traits\MakesHash; | ||||||
|  | 
 | ||||||
|  | class UpdateBankTransactionRequest extends Request | ||||||
|  | { | ||||||
|  |     use MakesHash; | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Determine if the user is authorized to make this request. | ||||||
|  |      * | ||||||
|  |      * @return bool | ||||||
|  |      */ | ||||||
|  |     public function authorize() : bool | ||||||
|  |     { | ||||||
|  |         return auth()->user()->can('edit', $this->bank_transaction); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public function rules() | ||||||
|  |     { | ||||||
|  |         /* Ensure we have a client name, and that all emails are unique*/ | ||||||
|  |         $rules = [ | ||||||
|  |             'date' => 'bail|required|date', | ||||||
|  |             'description' => 'bail|sometimes|string', | ||||||
|  |             'amount' => 'numeric|required', | ||||||
|  |         ]; | ||||||
|  | 
 | ||||||
|  |         if (isset($this->currency_id))  | ||||||
|  |             $rules['currency_id'] = 'sometimes|exists:currencies,id'; | ||||||
|  |          | ||||||
|  |         if(isset($this->vendor_id)) | ||||||
|  |             $rules['vendor_id'] = 'bail|required|exists:vendors,id,company_id,'.auth()->user()->company()->id.',is_deleted,0'; | ||||||
|  | 
 | ||||||
|  |         if(isset($this->expense_id)) | ||||||
|  |             $rules['expense_id'] = 'bail|required|exists:expenses,id,company_id,'.auth()->user()->company()->id.',is_deleted,0'; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |         return $rules; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public function prepareForValidation() | ||||||
|  |     { | ||||||
|  |         $input = $this->all(); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |             if(array_key_exists('baseType', $input) && strlen($input['baseType']) > 1) | ||||||
|  |                 $input['base_type'] = $input['baseType']; //== 'deposit' ? 'CREDIT' : 'DEBIT';
 | ||||||
|  | 
 | ||||||
|  |             if(array_key_exists('vendor_id', $input) && strlen($input['vendor_id']) > 1) | ||||||
|  |                 $input['vendor_id'] = $this->decodePrimaryKey($input['vendor_id']); | ||||||
|  | 
 | ||||||
|  |             if(array_key_exists('expense_id', $input) && strlen($input['expense_id']) > 1) | ||||||
|  |                 $input['expense_id'] = $this->decodePrimaryKey($input['expense_id']); | ||||||
|  | 
 | ||||||
|  |             if(array_key_exists('ninja_category_id', $input) && strlen($input['ninja_category_id']) > 1) | ||||||
|  |                 $input['ninja_category_id'] = $this->decodePrimaryKey($input['ninja_category_id']); | ||||||
|  | 
 | ||||||
|  |             if(array_key_exists('bank_integration_id', $input) && strlen($input['bank_integration_id']) > 1) | ||||||
|  |                 $input['bank_integration_id'] = $this->decodePrimaryKey($input['bank_integration_id']); | ||||||
|  | 
 | ||||||
|  |         $this->replace($input); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } | ||||||
| @ -0,0 +1,38 @@ | |||||||
|  | <?php | ||||||
|  | /** | ||||||
|  |  * Invoice Ninja (https://invoiceninja.com). | ||||||
|  |  * | ||||||
|  |  * @link https://github.com/invoiceninja/invoiceninja source repository | ||||||
|  |  * | ||||||
|  |  * @copyright Copyright (c) 2022. Invoice Ninja LLC (https://invoiceninja.com) | ||||||
|  |  * | ||||||
|  |  * @license https://www.elastic.co/licensing/elastic-license | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | namespace App\Http\Requests\BankTransaction; | ||||||
|  | 
 | ||||||
|  | use App\Http\Requests\Request; | ||||||
|  | 
 | ||||||
|  | class UploadBankTransactionRequest extends Request | ||||||
|  | { | ||||||
|  |     /** | ||||||
|  |      * Determine if the user is authorized to make this request. | ||||||
|  |      * | ||||||
|  |      * @return bool | ||||||
|  |      */ | ||||||
|  |     public function authorize() : bool | ||||||
|  |     { | ||||||
|  |         return auth()->user()->can('edit', $this->bank_transaction); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public function rules() | ||||||
|  |     { | ||||||
|  |         $rules = []; | ||||||
|  | 
 | ||||||
|  |         if ($this->input('documents')) { | ||||||
|  |             $rules['documents'] = 'file|mimes:csv,png,ai,jpeg,tiff,pdf,gif,psd,txt,doc,xls,ppt,xlsx,docx,pptx|max:2000000'; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         return $rules; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -31,7 +31,7 @@ class ProfitLossRequest extends Request | |||||||
|             'start_date' => 'string|date', |             'start_date' => 'string|date', | ||||||
|             'end_date' => 'string|date', |             'end_date' => 'string|date', | ||||||
|             'is_income_billed' => 'required|bail|bool', |             'is_income_billed' => 'required|bail|bool', | ||||||
|             'is_expense_billed' => 'required|bail|bool', |             'is_expense_billed' => 'bool', | ||||||
|             'include_tax' => 'required|bail|bool', |             'include_tax' => 'required|bail|bool', | ||||||
|             'date_range' => 'sometimes|string', |             'date_range' => 'sometimes|string', | ||||||
|             'send_email' => 'bool', |             'send_email' => 'bool', | ||||||
|  | |||||||
| @ -109,6 +109,10 @@ class Request extends FormRequest | |||||||
|             $input['invoice_id'] = $this->decodePrimaryKey($input['invoice_id']); |             $input['invoice_id'] = $this->decodePrimaryKey($input['invoice_id']); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |         if (array_key_exists('expense_id', $input) && is_string($input['expense_id'])) { | ||||||
|  |             $input['expense_id'] = $this->decodePrimaryKey($input['expense_id']); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|         if (array_key_exists('design_id', $input) && is_string($input['design_id'])) { |         if (array_key_exists('design_id', $input) && is_string($input['design_id'])) { | ||||||
|             $input['design_id'] = $this->decodePrimaryKey($input['design_id']); |             $input['design_id'] = $this->decodePrimaryKey($input['design_id']); | ||||||
|         } |         } | ||||||
|  | |||||||
							
								
								
									
										39
									
								
								app/Http/Requests/Yodlee/YodleeAdminRequest.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								app/Http/Requests/Yodlee/YodleeAdminRequest.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,39 @@ | |||||||
|  | <?php | ||||||
|  | /** | ||||||
|  |  * Invoice Ninja (https://invoiceninja.com). | ||||||
|  |  * | ||||||
|  |  * @link https://github.com/invoiceninja/invoiceninja source repository | ||||||
|  |  * | ||||||
|  |  * @copyright Copyright (c) 2022. Invoice Ninja LLC (https://invoiceninja.com) | ||||||
|  |  * | ||||||
|  |  * @license https://www.elastic.co/licensing/elastic-license | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | namespace App\Http\Requests\Yodlee; | ||||||
|  | 
 | ||||||
|  | use App\Http\Requests\Request; | ||||||
|  | 
 | ||||||
|  | class YodleeAdminRequest extends Request | ||||||
|  | { | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Determine if the user is authorized to make this request. | ||||||
|  |      * | ||||||
|  |      * @return bool | ||||||
|  |      */ | ||||||
|  |     public function authorize() | ||||||
|  |     { | ||||||
|  |         return auth()->user()->isAdmin(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Get the validation rules that apply to the request. | ||||||
|  |      * | ||||||
|  |      * @return array | ||||||
|  |      */ | ||||||
|  |     public function rules() | ||||||
|  |     { | ||||||
|  |         return []; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } | ||||||
							
								
								
									
										70
									
								
								app/Http/Requests/Yodlee/YodleeAuthRequest.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								app/Http/Requests/Yodlee/YodleeAuthRequest.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,70 @@ | |||||||
|  | <?php | ||||||
|  | /** | ||||||
|  |  * Invoice Ninja (https://invoiceninja.com). | ||||||
|  |  * | ||||||
|  |  * @link https://github.com/invoiceninja/invoiceninja source repository | ||||||
|  |  * | ||||||
|  |  * @copyright Copyright (c) 2022. Invoice Ninja LLC (https://invoiceninja.com) | ||||||
|  |  * | ||||||
|  |  * @license https://www.elastic.co/licensing/elastic-license | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | namespace App\Http\Requests\Yodlee; | ||||||
|  | 
 | ||||||
|  | use App\Http\Requests\Request; | ||||||
|  | use App\Libraries\MultiDB; | ||||||
|  | use App\Models\Company; | ||||||
|  | use App\Models\User; | ||||||
|  | use Illuminate\Support\Facades\Cache; | ||||||
|  | 
 | ||||||
|  | class YodleeAuthRequest extends Request | ||||||
|  | { | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Determine if the user is authorized to make this request. | ||||||
|  |      * | ||||||
|  |      * @return bool | ||||||
|  |      */ | ||||||
|  |     public function authorize() | ||||||
|  |     { | ||||||
|  |         return true; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Get the validation rules that apply to the request. | ||||||
|  |      * | ||||||
|  |      * @return array | ||||||
|  |      */ | ||||||
|  |     public function rules() | ||||||
|  |     { | ||||||
|  |         return []; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public function getTokenContent() | ||||||
|  |     { | ||||||
|  |         if ($this->state) { | ||||||
|  |             $this->token = $this->state; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         $data = Cache::get($this->token); | ||||||
|  | 
 | ||||||
|  |         return $data; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public function getContact() | ||||||
|  |     { | ||||||
|  |         MultiDB::findAndSetDbByCompanyKey($this->getTokenContent()['company_key']); | ||||||
|  | 
 | ||||||
|  |         return User::findOrFail($this->getTokenContent()['user_id']); | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public function getCompany() | ||||||
|  |     { | ||||||
|  |          | ||||||
|  |         MultiDB::findAndSetDbByCompanyKey($this->getTokenContent()['company_key']); | ||||||
|  | 
 | ||||||
|  |         return Company::where('company_key', $this->getTokenContent()['company_key'])->firstOrFail(); | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										47
									
								
								app/Import/Definitions/BankTransactionMap.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								app/Import/Definitions/BankTransactionMap.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,47 @@ | |||||||
|  | <?php | ||||||
|  | /** | ||||||
|  |  * client Ninja (https://clientninja.com). | ||||||
|  |  * | ||||||
|  |  * @link https://github.com/clientninja/clientninja source repository | ||||||
|  |  * | ||||||
|  |  * @copyright Copyright (c) 2022. client Ninja LLC (https://clientninja.com) | ||||||
|  |  * | ||||||
|  |  * @license https://www.elastic.co/licensing/elastic-license | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | namespace App\Import\Definitions; | ||||||
|  | 
 | ||||||
|  | class BankTransactionMap | ||||||
|  | { | ||||||
|  |     public static function importable() | ||||||
|  |     { | ||||||
|  |         return [ | ||||||
|  |             0 => 'bank.transaction_id', | ||||||
|  |             1 => 'bank.amount', | ||||||
|  |             2 => 'bank.currency', | ||||||
|  |             3 => 'bank.account_type', | ||||||
|  |             4 => 'bank.category_id', | ||||||
|  |             5 => 'bank.category_type', | ||||||
|  |             6 => 'bank.date', | ||||||
|  |             7 => 'bank.bank_account_id', | ||||||
|  |             8 => 'bank.description', | ||||||
|  |             9 => 'bank.base_type', | ||||||
|  |         ]; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static function import_keys() | ||||||
|  |     { | ||||||
|  |         return [ | ||||||
|  |             0 => 'texts.transaction_id', | ||||||
|  |             1 => 'texts.amount', | ||||||
|  |             2 => 'texts.currency', | ||||||
|  |             3 => 'texts.account_type', | ||||||
|  |             4 => 'texts.category_id', | ||||||
|  |             5 => 'texts.category_type', | ||||||
|  |             6 => 'texts.date', | ||||||
|  |             7 => 'texts.bank_account_id', | ||||||
|  |             8 => 'texts.description', | ||||||
|  |             9 => 'texts.type', | ||||||
|  |         ]; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -36,6 +36,10 @@ class ExpenseMap | |||||||
|             17 => 'expense.tax_rate3', |             17 => 'expense.tax_rate3', | ||||||
|             18 => 'expense.uses_inclusive_taxes', |             18 => 'expense.uses_inclusive_taxes', | ||||||
|             19 => 'expense.payment_date', |             19 => 'expense.payment_date', | ||||||
|  |             20 => 'expense.custom_value1', | ||||||
|  |             21 => 'expense.custom_value2', | ||||||
|  |             22 => 'expense.custom_value3', | ||||||
|  |             23 => 'expense.custom_value4', | ||||||
| 
 | 
 | ||||||
|         ]; |         ]; | ||||||
|     } |     } | ||||||
| @ -63,6 +67,10 @@ class ExpenseMap | |||||||
|             17 => 'texts.tax_rate3', |             17 => 'texts.tax_rate3', | ||||||
|             18 => 'texts.uses_inclusive_taxes', |             18 => 'texts.uses_inclusive_taxes', | ||||||
|             19 => 'texts.payment_date', |             19 => 'texts.payment_date', | ||||||
|  |             20 => 'texts.custom_value1', | ||||||
|  |             21 => 'texts.custom_value2', | ||||||
|  |             22 => 'texts.custom_value3', | ||||||
|  |             23 => 'texts.custom_value4', | ||||||
| 
 | 
 | ||||||
|         ]; |         ]; | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -187,7 +187,6 @@ class BaseImport | |||||||
| 
 | 
 | ||||||
|             try { |             try { | ||||||
|                 $entity = $this->transformer->transform($record); |                 $entity = $this->transformer->transform($record); | ||||||
|                 // $validator = $this->request_name::runFormRequest($entity);
 |  | ||||||
|                 $validator = $this->runValidation($entity); |                 $validator = $this->runValidation($entity); | ||||||
| 
 | 
 | ||||||
|                 if ($validator->fails()) { |                 if ($validator->fails()) { | ||||||
|  | |||||||
| @ -11,6 +11,7 @@ | |||||||
| 
 | 
 | ||||||
| namespace App\Import\Providers; | namespace App\Import\Providers; | ||||||
| 
 | 
 | ||||||
|  | use App\Factory\BankTransactionFactory; | ||||||
| use App\Factory\ClientFactory; | use App\Factory\ClientFactory; | ||||||
| use App\Factory\ExpenseFactory; | use App\Factory\ExpenseFactory; | ||||||
| use App\Factory\InvoiceFactory; | use App\Factory\InvoiceFactory; | ||||||
| @ -18,6 +19,7 @@ use App\Factory\PaymentFactory; | |||||||
| use App\Factory\ProductFactory; | use App\Factory\ProductFactory; | ||||||
| use App\Factory\QuoteFactory; | use App\Factory\QuoteFactory; | ||||||
| use App\Factory\VendorFactory; | use App\Factory\VendorFactory; | ||||||
|  | use App\Http\Requests\BankTransaction\StoreBankTransactionRequest; | ||||||
| use App\Http\Requests\Client\StoreClientRequest; | use App\Http\Requests\Client\StoreClientRequest; | ||||||
| use App\Http\Requests\Expense\StoreExpenseRequest; | use App\Http\Requests\Expense\StoreExpenseRequest; | ||||||
| use App\Http\Requests\Invoice\StoreInvoiceRequest; | use App\Http\Requests\Invoice\StoreInvoiceRequest; | ||||||
| @ -35,6 +37,8 @@ use App\Import\Transformer\Csv\PaymentTransformer; | |||||||
| use App\Import\Transformer\Csv\ProductTransformer; | use App\Import\Transformer\Csv\ProductTransformer; | ||||||
| use App\Import\Transformer\Csv\QuoteTransformer; | use App\Import\Transformer\Csv\QuoteTransformer; | ||||||
| use App\Import\Transformer\Csv\VendorTransformer; | use App\Import\Transformer\Csv\VendorTransformer; | ||||||
|  | use App\Import\Transformers\Bank\BankTransformer; | ||||||
|  | use App\Repositories\BankTransactionRepository; | ||||||
| use App\Repositories\ClientRepository; | use App\Repositories\ClientRepository; | ||||||
| use App\Repositories\ExpenseRepository; | use App\Repositories\ExpenseRepository; | ||||||
| use App\Repositories\InvoiceRepository; | use App\Repositories\InvoiceRepository; | ||||||
| @ -60,12 +64,50 @@ class Csv extends BaseImport implements ImportInterface | |||||||
|                 'vendor', |                 'vendor', | ||||||
|                 'expense', |                 'expense', | ||||||
|                 'quote', |                 'quote', | ||||||
|  |                 'bank_transaction', | ||||||
|             ]) |             ]) | ||||||
|         ) { |         ) { | ||||||
|             $this->{$entity}(); |             $this->{$entity}(); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     public function bank_transaction() | ||||||
|  |     { | ||||||
|  |         $entity_type = 'bank_transaction'; | ||||||
|  | 
 | ||||||
|  |         $data = $this->getCsvData($entity_type); | ||||||
|  | 
 | ||||||
|  |         if (is_array($data)) { | ||||||
|  |             $data = $this->preTransformCsv($data, $entity_type); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |             if(array_key_exists('bank_integration_id', $this->request)){ | ||||||
|  | 
 | ||||||
|  |                 foreach($data as $key => $value) | ||||||
|  |                 { | ||||||
|  |                     $data['bank_integration_id'][$key] = $this->request['bank_integration_id']; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         if (empty($data)) { | ||||||
|  |             $this->entity_count['bank_transactions'] = 0; | ||||||
|  | 
 | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         $this->request_name = StoreBankTransactionRequest::class; | ||||||
|  |         $this->repository_name = BankTransactionRepository::class; | ||||||
|  |         $this->factory_name = BankTransactionFactory::class; | ||||||
|  | 
 | ||||||
|  |         $this->transformer = new BankTransformer($this->company); | ||||||
|  |         $bank_transaction_count = $this->ingest($data, $entity_type); | ||||||
|  |         $this->entity_count['bank_transactions'] = $bank_transaction_count; | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     public function client() |     public function client() | ||||||
|     { |     { | ||||||
|         $entity_type = 'client'; |         $entity_type = 'client'; | ||||||
|  | |||||||
							
								
								
									
										81
									
								
								app/Import/Transformers/Bank/BankTransformer.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										81
									
								
								app/Import/Transformers/Bank/BankTransformer.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,81 @@ | |||||||
|  | <?php | ||||||
|  | /** | ||||||
|  |  * client Ninja (https://clientninja.com). | ||||||
|  |  * | ||||||
|  |  * @link https://github.com/clientninja/clientninja source repository | ||||||
|  |  * | ||||||
|  |  * @copyright Copyright (c) 2022. client Ninja LLC (https://clientninja.com) | ||||||
|  |  * | ||||||
|  |  * @license https://www.elastic.co/licensing/elastic-license | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | namespace App\Import\Transformers\Bank; | ||||||
|  | 
 | ||||||
|  | use App\Import\ImportException; | ||||||
|  | use App\Import\Transformers\BaseTransformer; | ||||||
|  | use App\Models\BankTransaction; | ||||||
|  | use App\Utils\Number; | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Class BankTransformer. | ||||||
|  |  */ | ||||||
|  | class BankTransformer extends BaseTransformer | ||||||
|  | { | ||||||
|  |     /** | ||||||
|  |      * @param $line_items_data | ||||||
|  |      * | ||||||
|  |      * @return bool|array | ||||||
|  |      */ | ||||||
|  |     public function transform($transaction) | ||||||
|  |     { | ||||||
|  |     	$now = now(); | ||||||
|  | 
 | ||||||
|  |     	$transformed = [ | ||||||
|  |             // 'bank_integration_id' => $this->bank_integration->id,
 | ||||||
|  |             'transaction_id' => $this->getNumber($transaction,'bank.transaction_id'), | ||||||
|  |             'amount' => abs($this->getFloat($transaction, 'bank.amount')), | ||||||
|  |             'currency_id' => $this->getCurrencyByCode($transaction, 'bank.currency'), | ||||||
|  |             'account_type' => strlen($this->getString($transaction, 'bank.account_type')) > 1 ? $this->getString($transaction, 'bank.account_type') : 'bank', | ||||||
|  |             'category_id' => $this->getNumber($transaction, 'bank.category_id') > 0 ? $this->getNumber($transaction, 'bank.category_id') : null, | ||||||
|  |             'category_type' => $this->getString($transaction, 'category_type'), | ||||||
|  |             'date' => array_key_exists('date', $transaction) ? date('Y-m-d', strtotime(str_replace("/","-",$transaction['date']))) | ||||||
|  |                 : now()->format('Y-m-d'), | ||||||
|  |             'bank_account_id' => array_key_exists('bank_account_id', $transaction) ? $transaction['bank_account_id'] : 0, | ||||||
|  |             'description' => array_key_exists('description', $transaction)? $transaction['description'] : '', | ||||||
|  |             'base_type' => $this->calculateType($transaction), | ||||||
|  |             'created_at' => $now, | ||||||
|  |             'updated_at' => $now, | ||||||
|  |             'company_id' => $this->company->id, | ||||||
|  |             'user_id' => $this->company->owner()->id, | ||||||
|  |         ]; | ||||||
|  | 
 | ||||||
|  |         return $transformed; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     private function calculateType($transaction) | ||||||
|  |     { | ||||||
|  | 
 | ||||||
|  |     	if(array_key_exists('base_type', $transaction) && $transaction['base_type'] == 'CREDIT') | ||||||
|  |     		return 'CREDIT'; | ||||||
|  | 
 | ||||||
|  |     	if(array_key_exists('base_type', $transaction) && $transaction['base_type'] == 'DEBIT') | ||||||
|  |     		return 'DEBIT'; | ||||||
|  | 
 | ||||||
|  |     	if(array_key_exists('category_id',$transaction)) | ||||||
|  |     		return 'DEBIT'; | ||||||
|  | 
 | ||||||
|  |     	if(array_key_exists('category_type', $transaction) && $transaction['category_type'] == 'Income') | ||||||
|  |     		return 'CREDIT'; | ||||||
|  | 
 | ||||||
|  |     	if(array_key_exists('category_type', $transaction)) | ||||||
|  |     		return 'DEBIT'; | ||||||
|  | 
 | ||||||
|  |     	if(array_key_exists('amount', $transaction) && is_numeric($transaction['amount']) && $transaction['amount'] > 0) | ||||||
|  |     		return 'CREDIT'; | ||||||
|  | 
 | ||||||
|  |     	return 'DEBIT'; | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } | ||||||
| @ -86,7 +86,7 @@ class CreateAccount | |||||||
|             $sp794f3f->hosted_company_count = config('ninja.quotas.free.max_companies'); |             $sp794f3f->hosted_company_count = config('ninja.quotas.free.max_companies'); | ||||||
|             $sp794f3f->account_sms_verified = true; |             $sp794f3f->account_sms_verified = true; | ||||||
| 
 | 
 | ||||||
|             if(in_array($this->getDomain($this->request['email']), ['gmail.com', 'hotmail.com', 'outlook.com', 'yahoo.com', 'aol.com', 'mail.ru'])){ |             if(in_array($this->getDomain($this->request['email']), ['givmail.com','yopmail.com','gmail.com', 'hotmail.com', 'outlook.com', 'yahoo.com', 'aol.com', 'mail.ru'])){ | ||||||
|                 $sp794f3f->account_sms_verified = false; |                 $sp794f3f->account_sms_verified = false; | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|  | |||||||
							
								
								
									
										365
									
								
								app/Jobs/Bank/MatchBankTransactions.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										365
									
								
								app/Jobs/Bank/MatchBankTransactions.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,365 @@ | |||||||
|  | <?php | ||||||
|  | /** | ||||||
|  |  * Credit Ninja (https://invoiceninja.com). | ||||||
|  |  * | ||||||
|  |  * @link https://github.com/invoiceninja/invoiceninja source repository | ||||||
|  |  * | ||||||
|  |  * @copyright Copyright (c) 2022. Credit Ninja LLC (https://invoiceninja.com) | ||||||
|  |  * | ||||||
|  |  * @license https://www.elastic.co/licensing/elastic-license | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | namespace App\Jobs\Bank; | ||||||
|  | 
 | ||||||
|  | use App\Events\Invoice\InvoiceWasPaid; | ||||||
|  | use App\Events\Payment\PaymentWasCreated; | ||||||
|  | use App\Factory\ExpenseCategoryFactory; | ||||||
|  | use App\Factory\ExpenseFactory; | ||||||
|  | use App\Factory\PaymentFactory; | ||||||
|  | use App\Helpers\Bank\Yodlee\Yodlee; | ||||||
|  | use App\Libraries\Currency\Conversion\CurrencyApi; | ||||||
|  | use App\Libraries\MultiDB; | ||||||
|  | use App\Models\BankIntegration; | ||||||
|  | use App\Models\BankTransaction; | ||||||
|  | use App\Models\Company; | ||||||
|  | use App\Models\Currency; | ||||||
|  | use App\Models\ExpenseCategory; | ||||||
|  | use App\Models\Invoice; | ||||||
|  | use App\Models\Payment; | ||||||
|  | use App\Services\Bank\BankService; | ||||||
|  | use App\Utils\Ninja; | ||||||
|  | use App\Utils\Traits\GeneratesCounter; | ||||||
|  | use App\Utils\Traits\MakesHash; | ||||||
|  | use Illuminate\Bus\Queueable; | ||||||
|  | use Illuminate\Contracts\Queue\ShouldQueue; | ||||||
|  | use Illuminate\Foundation\Bus\Dispatchable; | ||||||
|  | use Illuminate\Queue\InteractsWithQueue; | ||||||
|  | use Illuminate\Queue\Middleware\WithoutOverlapping; | ||||||
|  | use Illuminate\Queue\SerializesModels; | ||||||
|  | use Illuminate\Support\Carbon; | ||||||
|  | use Illuminate\Support\Facades\Cache; | ||||||
|  | 
 | ||||||
|  | class MatchBankTransactions implements ShouldQueue | ||||||
|  | { | ||||||
|  |     use Dispatchable, InteractsWithQueue, Queueable, SerializesModels, GeneratesCounter, MakesHash; | ||||||
|  | 
 | ||||||
|  |     private int $company_id; | ||||||
|  | 
 | ||||||
|  |     private string $db; | ||||||
|  | 
 | ||||||
|  |     private array $input; | ||||||
|  | 
 | ||||||
|  |     protected Company $company; | ||||||
|  | 
 | ||||||
|  |     public Invoice $invoice; | ||||||
|  | 
 | ||||||
|  |     private BankTransaction $bt; | ||||||
|  | 
 | ||||||
|  |     private $categories; | ||||||
|  | 
 | ||||||
|  |     private float $available_balance = 0; | ||||||
|  |      | ||||||
|  |     private array $attachable_invoices = []; | ||||||
|  | 
 | ||||||
|  |     public $bts; | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Create a new job instance. | ||||||
|  |      */ | ||||||
|  |     public function __construct(int $company_id, string $db, array $input) | ||||||
|  |     { | ||||||
|  | 
 | ||||||
|  |         $this->company_id = $company_id; | ||||||
|  |         $this->db = $db; | ||||||
|  |         $this->input = $input['transactions']; | ||||||
|  |         $this->categories = collect(); | ||||||
|  |         $this->bts = collect(); | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Execute the job. | ||||||
|  |      * | ||||||
|  |      * | ||||||
|  |      * @return void | ||||||
|  |      */ | ||||||
|  |     public function handle() | ||||||
|  |     { | ||||||
|  | 
 | ||||||
|  |         MultiDB::setDb($this->db); | ||||||
|  | 
 | ||||||
|  |         $this->company = Company::find($this->company_id); | ||||||
|  | 
 | ||||||
|  |         $yodlee = new Yodlee($this->company->account->bank_integration_account_id); | ||||||
|  | 
 | ||||||
|  |         $bank_categories = Cache::get('bank_categories'); | ||||||
|  |          | ||||||
|  |         if(!$bank_categories){ | ||||||
|  |             $_categories = $yodlee->getTransactionCategories(); | ||||||
|  |             $this->categories = collect($_categories->transactionCategory); | ||||||
|  |             Cache::forever('bank_categories', $this->categories); | ||||||
|  |         } | ||||||
|  |         else { | ||||||
|  |             $this->categories = collect($bank_categories); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         foreach($this->input as $input) | ||||||
|  |         { | ||||||
|  |             if(array_key_exists('invoice_ids', $input) && strlen($input['invoice_ids']) > 1) | ||||||
|  |                 $this->matchInvoicePayment($input); | ||||||
|  |             else | ||||||
|  |                 $this->matchExpense($input); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         return BankTransaction::whereIn('id', $this->bts); | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private function getInvoices(string $invoice_hashed_ids) | ||||||
|  |     { | ||||||
|  |         $collection = collect(); | ||||||
|  | 
 | ||||||
|  |         $invoices = explode(",", $invoice_hashed_ids); | ||||||
|  | 
 | ||||||
|  |         if(count($invoices) >= 1)  | ||||||
|  |         { | ||||||
|  | 
 | ||||||
|  |             foreach($invoices as $invoice){ | ||||||
|  | 
 | ||||||
|  |                 if(is_string($invoice) && strlen($invoice) > 1) | ||||||
|  |                     $collection->push($this->decodePrimaryKey($invoice)); | ||||||
|  |             } | ||||||
|  |          | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         return $collection; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private function checkPayable($invoices) :bool | ||||||
|  |     { | ||||||
|  | 
 | ||||||
|  |         foreach($invoices as $invoice){ | ||||||
|  | 
 | ||||||
|  |             $invoice->service()->markSent(); | ||||||
|  |              | ||||||
|  |             if(!$invoice->isPayable()) | ||||||
|  |                 return false; | ||||||
|  | 
 | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         return true; | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private function matchInvoicePayment($input) :self | ||||||
|  |     {  | ||||||
|  |         $this->bt = BankTransaction::find($input['id']); | ||||||
|  | 
 | ||||||
|  |         $_invoices = Invoice::withTrashed()->find($this->getInvoices($input['invoice_ids'])); | ||||||
|  |          | ||||||
|  |             $amount = $this->bt->amount; | ||||||
|  | 
 | ||||||
|  |         if($_invoices && $this->checkPayable($_invoices)){ | ||||||
|  | 
 | ||||||
|  |             $this->createPayment($_invoices, $amount); | ||||||
|  | 
 | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         $this->bts->push($this->bt->id); | ||||||
|  | 
 | ||||||
|  |         return $this; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private function matchExpense($input) :self | ||||||
|  |     {  | ||||||
|  |         //if there is a category id, pull it from Yodlee and insert - or just reuse!!
 | ||||||
|  |         $this->bt = BankTransaction::find($input['id']); | ||||||
|  | 
 | ||||||
|  |         $expense = ExpenseFactory::create($this->bt->company_id, $this->bt->user_id); | ||||||
|  |         $expense->category_id = $this->resolveCategory($input); | ||||||
|  |         $expense->amount = $this->bt->amount; | ||||||
|  |         $expense->number = $this->getNextExpenseNumber($expense); | ||||||
|  |         $expense->currency_id = $this->bt->currency_id; | ||||||
|  |         $expense->date = Carbon::parse($this->bt->date); | ||||||
|  |         $expense->payment_date = Carbon::parse($this->bt->date); | ||||||
|  |         $expense->transaction_reference = $this->bt->description; | ||||||
|  |         $expense->transaction_id = $this->bt->id; | ||||||
|  |         $expense->vendor_id = array_key_exists('vendor_id', $input) ? $input['vendor_id'] : null; | ||||||
|  |         $expense->save(); | ||||||
|  | 
 | ||||||
|  |         $this->bt->expense_id = $expense->id; | ||||||
|  |         $this->bt->vendor_id = array_key_exists('vendor_id', $input) ? $input['vendor_id'] : null; | ||||||
|  |         $this->bt->status_id = BankTransaction::STATUS_CONVERTED; | ||||||
|  |         $this->bt->save(); | ||||||
|  | 
 | ||||||
|  |         $this->bts->push($this->bt->id); | ||||||
|  | 
 | ||||||
|  |         return $this; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private function createPayment($invoices, float $amount) :void | ||||||
|  |     { | ||||||
|  |         $this->available_balance = $amount; | ||||||
|  | 
 | ||||||
|  |         \DB::connection(config('database.default'))->transaction(function () use($invoices) { | ||||||
|  | 
 | ||||||
|  |             $invoices->each(function ($invoice) use ($invoices){ | ||||||
|  |              | ||||||
|  |                 $this->invoice = Invoice::withTrashed()->where('id', $invoice->id)->lockForUpdate()->first(); | ||||||
|  | 
 | ||||||
|  |                 if($invoices->count() == 1){ | ||||||
|  |                     $_amount = $this->available_balance; | ||||||
|  |                 } | ||||||
|  |                 elseif($invoices->count() > 1 && floatval($this->invoice->balance) < floatval($this->available_balance) && $this->available_balance > 0) | ||||||
|  |                 { | ||||||
|  |                     $_amount = $this->invoice->balance; | ||||||
|  |                     $this->available_balance = $this->available_balance - $this->invoice->balance; | ||||||
|  |                 } | ||||||
|  |                 elseif($invoices->count() > 1 && floatval($this->invoice->balance) > floatval($this->available_balance) && $this->available_balance > 0) | ||||||
|  |                 { | ||||||
|  |                     $_amount = $this->available_balance; | ||||||
|  |                     $this->available_balance = 0; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 $this->attachable_invoices[] = ['id' => $this->invoice->id, 'amount' => $_amount]; | ||||||
|  | 
 | ||||||
|  |                 $this->invoice | ||||||
|  |                     ->service() | ||||||
|  |                     ->setExchangeRate() | ||||||
|  |                     ->updateBalance($_amount * -1) | ||||||
|  |                     ->updatePaidToDate($_amount) | ||||||
|  |                     ->setCalculatedStatus() | ||||||
|  |                     ->save(); | ||||||
|  | 
 | ||||||
|  |                 }); | ||||||
|  | 
 | ||||||
|  |         }, 1); | ||||||
|  | 
 | ||||||
|  |         /* Create Payment */ | ||||||
|  |         $payment = PaymentFactory::create($this->invoice->company_id, $this->invoice->user_id); | ||||||
|  | 
 | ||||||
|  |         $payment->amount = $amount; | ||||||
|  |         $payment->applied = $amount; | ||||||
|  |         $payment->status_id = Payment::STATUS_COMPLETED; | ||||||
|  |         $payment->client_id = $this->invoice->client_id; | ||||||
|  |         $payment->transaction_reference = $this->bt->description; | ||||||
|  |         $payment->transaction_id = $this->bt->id; | ||||||
|  |         $payment->currency_id = $this->bt->currency_id; | ||||||
|  |         $payment->is_manual = false; | ||||||
|  |         $payment->date = $this->bt->date ? Carbon::parse($this->bt->date) : now(); | ||||||
|  |          | ||||||
|  | 
 | ||||||
|  |         /* Bank Transfer! */ | ||||||
|  |         $payment_type_id = 1; | ||||||
|  | 
 | ||||||
|  |         $payment->saveQuietly(); | ||||||
|  | 
 | ||||||
|  |         $payment->service()->applyNumber()->save(); | ||||||
|  |          | ||||||
|  |         if($payment->client->getSetting('send_email_on_mark_paid')) | ||||||
|  |             $payment->service()->sendEmail(); | ||||||
|  | 
 | ||||||
|  |         $this->setExchangeRate($payment); | ||||||
|  | 
 | ||||||
|  |         /* Create a payment relationship to the invoice entity */ | ||||||
|  |         foreach($this->attachable_invoices as $attachable_invoice) | ||||||
|  |         { | ||||||
|  | 
 | ||||||
|  |             $payment->invoices()->attach($attachable_invoice['id'], [ | ||||||
|  |                 'amount' => $attachable_invoice['amount'], | ||||||
|  |             ]); | ||||||
|  | 
 | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         event('eloquent.created: App\Models\Payment', $payment); | ||||||
|  | 
 | ||||||
|  |         $this->invoice->next_send_date = null; | ||||||
|  | 
 | ||||||
|  |         $this->invoice | ||||||
|  |                 ->service() | ||||||
|  |                 ->applyNumber() | ||||||
|  |                 ->touchPdf() | ||||||
|  |                 ->save(); | ||||||
|  | 
 | ||||||
|  |         $payment->ledger() | ||||||
|  |                 ->updatePaymentBalance($amount * -1); | ||||||
|  | 
 | ||||||
|  |         $this->invoice | ||||||
|  |              ->client | ||||||
|  |              ->service() | ||||||
|  |              ->updateBalanceAndPaidToDate($amount*-1, $amount) | ||||||
|  |              ->save(); | ||||||
|  | 
 | ||||||
|  |         $this->invoice = $this->invoice | ||||||
|  |                              ->service() | ||||||
|  |                              ->workFlow() | ||||||
|  |                              ->save(); | ||||||
|  | 
 | ||||||
|  |         /* Update Invoice balance */ | ||||||
|  |         event(new PaymentWasCreated($payment, $payment->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null))); | ||||||
|  |         event(new InvoiceWasPaid($this->invoice, $payment, $payment->company, Ninja::eventVars(auth()->user() ? auth()->user()->id : null))); | ||||||
|  | 
 | ||||||
|  |         $this->bt->invoice_ids = collect($invoices)->pluck('hashed_id')->implode(','); | ||||||
|  |         $this->bt->status_id = BankTransaction::STATUS_CONVERTED; | ||||||
|  |         $this->bt->save(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private function resolveCategory($input) :?int | ||||||
|  |     { | ||||||
|  |         if(array_key_exists('ninja_category_id', $input) && (int)$input['ninja_category_id'] > 1){ | ||||||
|  |             $this->bt->ninja_category_id = $input['ninja_category_id']; | ||||||
|  |             $this->bt->save(); | ||||||
|  | 
 | ||||||
|  |             return (int)$input['ninja_category_id']; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         $category = $this->categories->firstWhere('highLevelCategoryId', $this->bt->category_id); | ||||||
|  | 
 | ||||||
|  |         $ec = ExpenseCategory::where('company_id', $this->bt->company_id)->where('bank_category_id', $this->bt->category_id)->first(); | ||||||
|  | 
 | ||||||
|  |         if($ec) | ||||||
|  |             return $ec->id; | ||||||
|  | 
 | ||||||
|  |         if($category) | ||||||
|  |         { | ||||||
|  |             $ec = ExpenseCategoryFactory::create($this->bt->company_id, $this->bt->user_id); | ||||||
|  |             $ec->bank_category_id = $this->bt->category_id; | ||||||
|  |             $ec->name = $category->highLevelCategoryName; | ||||||
|  |             $ec->save(); | ||||||
|  | 
 | ||||||
|  |             return $ec->id; | ||||||
|  |         } | ||||||
|  |          | ||||||
|  | 
 | ||||||
|  |         return null; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private function setExchangeRate(Payment $payment) | ||||||
|  |     { | ||||||
|  |         if ($payment->exchange_rate != 1) { | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         $client_currency = $payment->client->getSetting('currency_id'); | ||||||
|  |         $company_currency = $payment->client->company->settings->currency_id; | ||||||
|  | 
 | ||||||
|  |         if ($company_currency != $client_currency) { | ||||||
|  |             $exchange_rate = new CurrencyApi(); | ||||||
|  | 
 | ||||||
|  |             $payment->exchange_rate = $exchange_rate->exchangeRate($client_currency, $company_currency, Carbon::parse($payment->date)); | ||||||
|  |             $payment->exchange_currency_id = $company_currency; | ||||||
|  | 
 | ||||||
|  |             $payment->saveQuietly(); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public function middleware() | ||||||
|  |     { | ||||||
|  |         return [new WithoutOverlapping($this->company_id)]; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | } | ||||||
							
								
								
									
										155
									
								
								app/Jobs/Bank/ProcessBankTransactions.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										155
									
								
								app/Jobs/Bank/ProcessBankTransactions.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,155 @@ | |||||||
|  | <?php | ||||||
|  | /** | ||||||
|  |  * Credit Ninja (https://invoiceninja.com). | ||||||
|  |  * | ||||||
|  |  * @link https://github.com/invoiceninja/invoiceninja source repository | ||||||
|  |  * | ||||||
|  |  * @copyright Copyright (c) 2022. Credit Ninja LLC (https://invoiceninja.com) | ||||||
|  |  * | ||||||
|  |  * @license https://www.elastic.co/licensing/elastic-license | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | namespace App\Jobs\Bank; | ||||||
|  | 
 | ||||||
|  | use App\Helpers\Bank\Yodlee\Yodlee; | ||||||
|  | use App\Libraries\MultiDB; | ||||||
|  | use App\Models\BankIntegration; | ||||||
|  | use App\Models\BankTransaction; | ||||||
|  | use App\Models\Company; | ||||||
|  | use App\Services\Bank\BankService; | ||||||
|  | use Illuminate\Bus\Queueable; | ||||||
|  | use Illuminate\Contracts\Queue\ShouldQueue; | ||||||
|  | use Illuminate\Foundation\Bus\Dispatchable; | ||||||
|  | use Illuminate\Queue\InteractsWithQueue; | ||||||
|  | use Illuminate\Queue\SerializesModels; | ||||||
|  | use Illuminate\Support\Carbon; | ||||||
|  | 
 | ||||||
|  | class ProcessBankTransactions implements ShouldQueue | ||||||
|  | { | ||||||
|  |     use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; | ||||||
|  | 
 | ||||||
|  |     private string $bank_integration_account_id; | ||||||
|  | 
 | ||||||
|  |     private BankIntegration $bank_integration; | ||||||
|  | 
 | ||||||
|  |     private ?string $from_date; | ||||||
|  | 
 | ||||||
|  |     private bool $stop_loop = true; | ||||||
|  | 
 | ||||||
|  |     private int $skip = 0; | ||||||
|  | 
 | ||||||
|  |     public Company $company; | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Create a new job instance. | ||||||
|  |      */ | ||||||
|  |     public function __construct(string $bank_integration_account_id, BankIntegration $bank_integration) | ||||||
|  |     { | ||||||
|  |         $this->bank_integration_account_id = $bank_integration_account_id; | ||||||
|  |         $this->bank_integration = $bank_integration; | ||||||
|  |         $this->from_date = $bank_integration->from_date; | ||||||
|  |         $this->company = $this->bank_integration->company; | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Execute the job. | ||||||
|  |      * | ||||||
|  |      * | ||||||
|  |      * @return void | ||||||
|  |      */ | ||||||
|  |     public function handle() | ||||||
|  |     { | ||||||
|  | 
 | ||||||
|  |         set_time_limit(0); | ||||||
|  | 
 | ||||||
|  |         //Loop through everything until we are up to date
 | ||||||
|  |         $this->from_date = $this->from_date ?: '2021-01-01'; | ||||||
|  | 
 | ||||||
|  |         do{ | ||||||
|  | 
 | ||||||
|  |             $this->processTransactions(); | ||||||
|  | 
 | ||||||
|  |         } | ||||||
|  |         while($this->stop_loop); | ||||||
|  | 
 | ||||||
|  |         BankService::dispatch($this->company->id, $this->company->db); | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     private function processTransactions() | ||||||
|  |     { | ||||||
|  | 
 | ||||||
|  |         $yodlee = new Yodlee($this->bank_integration_account_id); | ||||||
|  | 
 | ||||||
|  |         $data = [ | ||||||
|  |             'top' => 500, | ||||||
|  |             'fromDate' => $this->from_date, | ||||||
|  |             'accountId' => $this->bank_integration->bank_account_id, | ||||||
|  |             'skip' => $this->skip, | ||||||
|  |         ]; | ||||||
|  | 
 | ||||||
|  |         //Get transaction count object
 | ||||||
|  |         $transaction_count = $yodlee->getTransactionCount($data); | ||||||
|  | 
 | ||||||
|  |         //Get int count
 | ||||||
|  |         $count = $transaction_count->transaction->TOTAL->count; | ||||||
|  | 
 | ||||||
|  |         //get transactions array
 | ||||||
|  |         $transactions = $yodlee->getTransactions($data);  | ||||||
|  | 
 | ||||||
|  |         //if no transactions, update the from_date and move on
 | ||||||
|  |         if(count($transactions) == 0){ | ||||||
|  | 
 | ||||||
|  |             $this->bank_integration->from_date = now(); | ||||||
|  |             $this->bank_integration->save(); | ||||||
|  |             $this->stop_loop = false; | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         //Harvest the company
 | ||||||
|  | 
 | ||||||
|  |         MultiDB::setDb($this->company->db); | ||||||
|  | 
 | ||||||
|  |         /*Get the user */ | ||||||
|  |         $user_id = $this->company->owner()->id; | ||||||
|  |          | ||||||
|  |         /* Unguard the model to perform batch inserts */ | ||||||
|  |         BankTransaction::unguard(); | ||||||
|  | 
 | ||||||
|  |         $now = now(); | ||||||
|  |          | ||||||
|  |         foreach($transactions as $transaction) | ||||||
|  |         { | ||||||
|  | 
 | ||||||
|  |             if(BankTransaction::where('transaction_id', $transaction['transaction_id'])->where('company_id', $this->company->id)->withTrashed()->exists()) | ||||||
|  |                 continue; | ||||||
|  | 
 | ||||||
|  |             //this should be much faster to insert than using ::create()
 | ||||||
|  |             $bt = \DB::table('bank_transactions')->insert( | ||||||
|  |                 array_merge($transaction,[ | ||||||
|  |                     'company_id' => $this->company->id, | ||||||
|  |                     'user_id' => $user_id, | ||||||
|  |                     'bank_integration_id' => $this->bank_integration->id, | ||||||
|  |                     'created_at' => $now, | ||||||
|  |                     'updated_at' => $now, | ||||||
|  |                 ]) | ||||||
|  |             ); | ||||||
|  | 
 | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |         $this->skip = $this->skip + 500; | ||||||
|  | 
 | ||||||
|  |         if($count < 500){ | ||||||
|  |             $this->stop_loop = false; | ||||||
|  | 
 | ||||||
|  |             $this->bank_integration->from_date = now(); | ||||||
|  |             $this->bank_integration->save(); | ||||||
|  | 
 | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } | ||||||
| @ -77,6 +77,7 @@ class CompanyExport implements ShouldQueue | |||||||
|         set_time_limit(0); |         set_time_limit(0); | ||||||
| 
 | 
 | ||||||
|         $this->export_data['app_version'] = config('ninja.app_version'); |         $this->export_data['app_version'] = config('ninja.app_version'); | ||||||
|  |         $this->export_data['storage_url'] = Storage::url(''); | ||||||
| 
 | 
 | ||||||
|         $this->export_data['activities'] = $this->company->all_activities->map(function ($activity){ |         $this->export_data['activities'] = $this->company->all_activities->map(function ($activity){ | ||||||
| 
 | 
 | ||||||
| @ -167,7 +168,8 @@ class CompanyExport implements ShouldQueue | |||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|         $this->export_data['company'] = $this->company->toArray(); |         $this->export_data['company'] = $this->company->toArray(); | ||||||
| 
 |         $this->export_data['company']['company_key'] = $this->createHash(); | ||||||
|  |          | ||||||
|         $this->export_data['company_gateways'] = $this->company->company_gateways()->withTrashed()->cursor()->map(function ($company_gateway){ |         $this->export_data['company_gateways'] = $this->company->company_gateways()->withTrashed()->cursor()->map(function ($company_gateway){ | ||||||
| 
 | 
 | ||||||
|             $company_gateway = $this->transformArrayOfKeys($company_gateway, ['company_id', 'user_id']); |             $company_gateway = $this->transformArrayOfKeys($company_gateway, ['company_id', 'user_id']); | ||||||
| @ -515,8 +517,8 @@ class CompanyExport implements ShouldQueue | |||||||
| 
 | 
 | ||||||
|         $path = 'backups'; |         $path = 'backups'; | ||||||
|          |          | ||||||
|         if(!Storage::disk(config('filesystems.default'))->exists($path)) |         // if(!Storage::disk(config('filesystems.default'))->exists($path))
 | ||||||
|             Storage::disk(config('filesystems.default'))->makeDirectory($path, 0775); |         //     Storage::disk(config('filesystems.default'))->makeDirectory($path, 0775);
 | ||||||
| 
 | 
 | ||||||
|         $zip_path = public_path('storage/backups/'.$file_name); |         $zip_path = public_path('storage/backups/'.$file_name); | ||||||
|         $zip = new \ZipArchive(); |         $zip = new \ZipArchive(); | ||||||
|  | |||||||
| @ -1075,7 +1075,6 @@ class CompanyImport implements ShouldQueue | |||||||
|     private function import_documents() |     private function import_documents() | ||||||
|     { |     { | ||||||
| 
 | 
 | ||||||
|         // foreach($this->backup_file->documents as $document)
 |  | ||||||
|         foreach((object)$this->getObject("documents") as $document) |         foreach((object)$this->getObject("documents") as $document) | ||||||
|         { |         { | ||||||
| 
 | 
 | ||||||
| @ -1105,6 +1104,29 @@ class CompanyImport implements ShouldQueue | |||||||
| 
 | 
 | ||||||
|             $new_document->save(['timestamps' => false]); |             $new_document->save(['timestamps' => false]); | ||||||
|          |          | ||||||
|  | 
 | ||||||
|  |             $storage_url = (object)$this->getObject('storage_url', true); | ||||||
|  | 
 | ||||||
|  |             if(!Storage::exists($new_document->url)){ | ||||||
|  | 
 | ||||||
|  |                 $url = $storage_url . $new_document->url; | ||||||
|  | 
 | ||||||
|  |                 $file = @file_get_contents($url); | ||||||
|  | 
 | ||||||
|  |                 if($file) | ||||||
|  |                 { | ||||||
|  |                     try{ | ||||||
|  |                         Storage::disk(config('filesystems.default'))->put($new_document->url, $file); | ||||||
|  |                     } | ||||||
|  |                     catch(\Exception $e) | ||||||
|  |                     { | ||||||
|  |                         nlog($e->getMessage()); | ||||||
|  |                         nlog("I could not upload {$new_document->url}"); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         return $this; |         return $this; | ||||||
|  | |||||||
| @ -126,6 +126,12 @@ class ZipDocuments implements ShouldQueue | |||||||
|             $number = '_'.$document->documentable->number; |             $number = '_'.$document->documentable->number; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         return "{$date}_{$document->documentable->translate_entity()}{$number}_{$filename}"; |         $entity = ctrans('texts.document'); | ||||||
|  | 
 | ||||||
|  |         if(isset($document->documentable)){ | ||||||
|  |             $entity = $document->documentable->translate_entity(); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         return "{$date}_{$entity}{$number}_{$filename}"; | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -213,11 +213,7 @@ class CreateEntityPdf implements ShouldQueue | |||||||
| 
 | 
 | ||||||
|         if ($pdf) { |         if ($pdf) { | ||||||
|             try { |             try { | ||||||
|                 if (! Storage::disk($this->disk)->exists($path)) { |                 Storage::disk($this->disk)->put($file_path, $pdf); | ||||||
|                     Storage::disk($this->disk)->makeDirectory($path, 0775); |  | ||||||
|                 } |  | ||||||
| 
 |  | ||||||
|                 Storage::disk($this->disk)->put($file_path, $pdf, 'public'); |  | ||||||
|             } catch (\Exception $e) { |             } catch (\Exception $e) { | ||||||
|                 throw new FilePermissionsFailure($e->getMessage()); |                 throw new FilePermissionsFailure($e->getMessage()); | ||||||
|             } |             } | ||||||
|  | |||||||
| @ -74,7 +74,7 @@ class CSVIngest implements ShouldQueue | |||||||
| 
 | 
 | ||||||
|         $engine = $this->bootEngine(); |         $engine = $this->bootEngine(); | ||||||
| 
 | 
 | ||||||
|         foreach (['client', 'product', 'invoice', 'payment', 'vendor', 'expense', 'quote'] as $entity) { |         foreach (['client', 'product', 'invoice', 'payment', 'vendor', 'expense', 'quote', 'bank_transaction'] as $entity) { | ||||||
|             $engine->import($entity); |             $engine->import($entity); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -42,10 +42,7 @@ class NinjaMailer extends Mailable | |||||||
| 
 | 
 | ||||||
|         $ninja_mailable = $this->from(config('mail.from.address'), $from_name) |         $ninja_mailable = $this->from(config('mail.from.address'), $from_name) | ||||||
|                     ->subject($this->mail_obj->subject) |                     ->subject($this->mail_obj->subject) | ||||||
|                     ->view($this->mail_obj->markdown, $this->mail_obj->data) |                     ->view($this->mail_obj->markdown, $this->mail_obj->data); | ||||||
|                     ->withSymfonyMessage(function ($message) { |  | ||||||
|                         $message->getHeaders()->addTextHeader('Tag', $this->mail_obj->tag); |  | ||||||
|                     }); |  | ||||||
| 
 | 
 | ||||||
|         if (property_exists($this->mail_obj, 'text_view')) { |         if (property_exists($this->mail_obj, 'text_view')) { | ||||||
|             $ninja_mailable->text($this->mail_obj->text_view, $this->mail_obj->data); |             $ninja_mailable->text($this->mail_obj->text_view, $this->mail_obj->data); | ||||||
|  | |||||||
| @ -128,12 +128,19 @@ class NinjaMailerJob implements ShouldQueue | |||||||
|             /* Count the amount of emails sent across all the users accounts */ |             /* Count the amount of emails sent across all the users accounts */ | ||||||
|             Cache::increment($this->company->account->key); |             Cache::increment($this->company->account->key); | ||||||
| 
 | 
 | ||||||
|         } catch (\Exception | \RuntimeException $e) { |         } catch (\Exception | \RuntimeException | \Google\Service\Exception $e) { | ||||||
|              |              | ||||||
|             nlog("error failed with {$e->getMessage()}"); |             nlog("error failed with {$e->getMessage()}"); | ||||||
| 
 | 
 | ||||||
|             $message = $e->getMessage(); |             $message = $e->getMessage(); | ||||||
| 
 | 
 | ||||||
|  |             if($e instanceof \Google\Service\Exception){ | ||||||
|  | 
 | ||||||
|  |                 if(($e->getCode() == 429) && ($this->nmo->to_user instanceof ClientContact)) | ||||||
|  |                     $this->logMailError("Google rate limiter hit, we will retry in 30 seconds.", $this->nmo->to_user->client); | ||||||
|  | 
 | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|             /** |             /** | ||||||
|              * Post mark buries the proper message in a a guzzle response |              * Post mark buries the proper message in a a guzzle response | ||||||
|              * this merges a text string with a json object |              * this merges a text string with a json object | ||||||
|  | |||||||
							
								
								
									
										81
									
								
								app/Jobs/Ninja/BankTransactionSync.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										81
									
								
								app/Jobs/Ninja/BankTransactionSync.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,81 @@ | |||||||
|  | <?php | ||||||
|  | /** | ||||||
|  |  * Invoice Ninja (https://invoiceninja.com). | ||||||
|  |  * | ||||||
|  |  * @link https://github.com/invoiceninja/invoiceninja source repository | ||||||
|  |  * | ||||||
|  |  * @copyright Copyright (c) 2022. Invoice Ninja LLC (https://invoiceninja.com) | ||||||
|  |  * | ||||||
|  |  * @license https://www.elastic.co/licensing/elastic-license | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | namespace App\Jobs\Ninja; | ||||||
|  | 
 | ||||||
|  | use App\Jobs\Bank\ProcessBankTransactions; | ||||||
|  | use App\Libraries\MultiDB; | ||||||
|  | use App\Models\Account; | ||||||
|  | use App\Utils\Ninja; | ||||||
|  | use Illuminate\Bus\Queueable; | ||||||
|  | use Illuminate\Contracts\Queue\ShouldQueue; | ||||||
|  | use Illuminate\Foundation\Bus\Dispatchable; | ||||||
|  | use Illuminate\Queue\InteractsWithQueue; | ||||||
|  | use Illuminate\Queue\SerializesModels; | ||||||
|  | use Illuminate\Support\Facades\Cache; | ||||||
|  | 
 | ||||||
|  | class BankTransactionSync implements ShouldQueue | ||||||
|  | { | ||||||
|  |     use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Create a new job instance. | ||||||
|  |      * | ||||||
|  |      * @return void | ||||||
|  |      */ | ||||||
|  | 
 | ||||||
|  |     public function __construct() | ||||||
|  |     { | ||||||
|  |         //
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Execute the job. | ||||||
|  |      * | ||||||
|  |      * @return void | ||||||
|  |      */ | ||||||
|  |     public function handle() | ||||||
|  |     { | ||||||
|  |         // if (! Ninja::isHosted()) {
 | ||||||
|  |         //     return;
 | ||||||
|  |         // }
 | ||||||
|  | 
 | ||||||
|  |         //multiDB environment, need to
 | ||||||
|  |         foreach (MultiDB::$dbs as $db) { | ||||||
|  |             MultiDB::setDB($db); | ||||||
|  | 
 | ||||||
|  |             nlog("syncing transactions"); | ||||||
|  | 
 | ||||||
|  |             $this->syncTransactions(); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public function syncTransactions() | ||||||
|  |     { | ||||||
|  |         $a = Account::with('bank_integrations')->whereNotNull('bank_integration_account_id')->cursor()->each(function ($account){ | ||||||
|  | 
 | ||||||
|  |             // $queue = Ninja::isHosted() ? 'bank' : 'default';
 | ||||||
|  | 
 | ||||||
|  |             // if($account->isPaid())
 | ||||||
|  |             // {
 | ||||||
|  | 
 | ||||||
|  |                 $account->bank_integrations->each(function ($bank_integration) use ($account){ | ||||||
|  |                      | ||||||
|  |                     ProcessBankTransactions::dispatchSync($account->bank_integration_account_id, $bank_integration); | ||||||
|  | 
 | ||||||
|  |                 }); | ||||||
|  | 
 | ||||||
|  |             // }
 | ||||||
|  | 
 | ||||||
|  |         }); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } | ||||||
| @ -83,9 +83,23 @@ class UpdateOrCreateProduct implements ShouldQueue | |||||||
| 
 | 
 | ||||||
|             $product = Product::withTrashed()->firstOrNew(['product_key' => $item->product_key, 'company_id' => $this->invoice->company->id]); |             $product = Product::withTrashed()->firstOrNew(['product_key' => $item->product_key, 'company_id' => $this->invoice->company->id]); | ||||||
| 
 | 
 | ||||||
|  |                 /* If a user is using placeholders in their descriptions, do not update the products */ | ||||||
|  |                 $string_hit = false; | ||||||
|  | 
 | ||||||
|  |                 foreach ( [':MONTH',':YEAR',':QUARTER',':WEEK'] as $string )  | ||||||
|  |                 { | ||||||
|  |                  | ||||||
|  |                     if(stripos($product->notes, $string) !== FALSE) { | ||||||
|  |                         $string_hit = true;  | ||||||
|  |                     } | ||||||
|  |                      | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 if($string_hit) | ||||||
|  |                     continue; | ||||||
|  | 
 | ||||||
|             $product->product_key = $item->product_key; |             $product->product_key = $item->product_key; | ||||||
|             $product->notes = isset($item->notes) ? $item->notes : ''; |             $product->notes = isset($item->notes) ? $item->notes : ''; | ||||||
|             //$product->cost = isset($item->cost) ? $item->cost : 0; //this value shouldn't be updated.
 |  | ||||||
|             $product->price = isset($item->cost) ? $item->cost : 0; |             $product->price = isset($item->cost) ? $item->cost : 0; | ||||||
| 
 | 
 | ||||||
|             if (! $product->id) { |             if (! $product->id) { | ||||||
|  | |||||||
| @ -17,11 +17,13 @@ use App\Libraries\MultiDB; | |||||||
| use App\Mail\User\UserNotificationMailer; | use App\Mail\User\UserNotificationMailer; | ||||||
| use App\Models\Company; | use App\Models\Company; | ||||||
| use App\Models\User; | use App\Models\User; | ||||||
|  | use App\Utils\Ninja; | ||||||
| use Illuminate\Bus\Queueable; | use Illuminate\Bus\Queueable; | ||||||
| use Illuminate\Contracts\Queue\ShouldQueue; | use Illuminate\Contracts\Queue\ShouldQueue; | ||||||
| use Illuminate\Foundation\Bus\Dispatchable; | use Illuminate\Foundation\Bus\Dispatchable; | ||||||
| use Illuminate\Queue\InteractsWithQueue; | use Illuminate\Queue\InteractsWithQueue; | ||||||
| use Illuminate\Queue\SerializesModels; | use Illuminate\Queue\SerializesModels; | ||||||
|  | use Illuminate\Support\Facades\App; | ||||||
| use Illuminate\Support\Facades\Mail; | use Illuminate\Support\Facades\Mail; | ||||||
| use stdClass; | use stdClass; | ||||||
| 
 | 
 | ||||||
| @ -54,11 +56,14 @@ class UserEmailChanged implements ShouldQueue | |||||||
| 
 | 
 | ||||||
|     public function handle() |     public function handle() | ||||||
|     { |     { | ||||||
|         nlog('notifying user of email change'); |  | ||||||
| 
 |  | ||||||
|         //Set DB
 |         //Set DB
 | ||||||
|         MultiDB::setDb($this->company->db); |         MultiDB::setDb($this->company->db); | ||||||
| 
 | 
 | ||||||
|  |         App::forgetInstance('translator'); | ||||||
|  |         $t = app('translator'); | ||||||
|  |         $t->replace(Ninja::transformTranslations($this->company->settings)); | ||||||
|  |         App::setLocale($this->company->getLocale()); | ||||||
|  | 
 | ||||||
|         /*Build the object*/ |         /*Build the object*/ | ||||||
|         $mail_obj = new stdClass; |         $mail_obj = new stdClass; | ||||||
|         $mail_obj->subject = ctrans('texts.email_address_changed'); |         $mail_obj->subject = ctrans('texts.email_address_changed'); | ||||||
|  | |||||||
| @ -100,7 +100,7 @@ class ReminderJob implements ShouldQueue | |||||||
|                              |                              | ||||||
|                              $invoice->invitations->each(function ($invitation) use ($invoice, $reminder_template) { |                              $invoice->invitations->each(function ($invitation) use ($invoice, $reminder_template) { | ||||||
|                                  EmailEntity::dispatch($invitation, $invitation->company, $reminder_template); |                                  EmailEntity::dispatch($invitation, $invitation->company, $reminder_template); | ||||||
|                                  nlog("Firing reminder email for invoice {$invoice->number}"); |                                  nlog("Firing reminder email for invoice {$invoice->number} - {$reminder_template}"); | ||||||
|                              }); |                              }); | ||||||
| 
 | 
 | ||||||
|                              if ($invoice->invitations->count() > 0) { |                              if ($invoice->invitations->count() > 0) { | ||||||
|  | |||||||
| @ -167,7 +167,7 @@ class UploadFile implements ShouldQueue | |||||||
|                     $previewHeight = $height * Document::DOCUMENT_PREVIEW_SIZE / $width; |                     $previewHeight = $height * Document::DOCUMENT_PREVIEW_SIZE / $width; | ||||||
|                 } else { |                 } else { | ||||||
|                     $previewHeight = Document::DOCUMENT_PREVIEW_SIZE; |                     $previewHeight = Document::DOCUMENT_PREVIEW_SIZE; | ||||||
|                     $previewWidth = $width * DOCUMENT_PREVIEW_SIZE / $height; |                     $previewWidth = $width * Document::DOCUMENT_PREVIEW_SIZE / $height; | ||||||
|                 } |                 } | ||||||
| 
 | 
 | ||||||
|                 $img->resize($previewWidth, $previewHeight); |                 $img->resize($previewWidth, $previewHeight); | ||||||
|  | |||||||
							
								
								
									
										10
									
								
								app/Jobs/Vendor/CreatePurchaseOrderPdf.php
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										10
									
								
								app/Jobs/Vendor/CreatePurchaseOrderPdf.php
									
									
									
									
										vendored
									
									
								
							| @ -99,18 +99,11 @@ class CreatePurchaseOrderPdf implements ShouldQueue | |||||||
|         if ($pdf) { |         if ($pdf) { | ||||||
| 
 | 
 | ||||||
|             try{ |             try{ | ||||||
|                  |                 Storage::disk($this->disk)->put($this->file_path, $pdf); | ||||||
|                 if(!Storage::disk($this->disk)->exists($this->path))  |  | ||||||
|                     Storage::disk($this->disk)->makeDirectory($this->path, 0775); |  | ||||||
| 
 |  | ||||||
|                 Storage::disk($this->disk)->put($this->file_path, $pdf, 'public'); |  | ||||||
| 
 |  | ||||||
|             } |             } | ||||||
|             catch(\Exception $e) |             catch(\Exception $e) | ||||||
|             { |             { | ||||||
| 
 |  | ||||||
|                 throw new FilePermissionsFailure($e->getMessage()); |                 throw new FilePermissionsFailure($e->getMessage()); | ||||||
| 
 |  | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|          |          | ||||||
| @ -209,7 +202,6 @@ class CreatePurchaseOrderPdf implements ShouldQueue | |||||||
| 
 | 
 | ||||||
|                 if($numbered_pdf) |                 if($numbered_pdf) | ||||||
|                     $pdf = $numbered_pdf; |                     $pdf = $numbered_pdf; | ||||||
|                  |  | ||||||
| 
 | 
 | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -18,6 +18,7 @@ use App\Models\Company; | |||||||
| use App\Models\CompanyToken; | use App\Models\CompanyToken; | ||||||
| use App\Models\Document; | use App\Models\Document; | ||||||
| use App\Models\User; | use App\Models\User; | ||||||
|  | use App\Models\VendorContact; | ||||||
| use Illuminate\Support\Facades\DB; | use Illuminate\Support\Facades\DB; | ||||||
| use Illuminate\Support\Str; | use Illuminate\Support\Str; | ||||||
| 
 | 
 | ||||||
| @ -364,6 +365,23 @@ class MultiDB | |||||||
|         return false; |         return false; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     public static function findAndSetDbByVendorContactKey($contact_key) :bool | ||||||
|  |     { | ||||||
|  |         $current_db = config('database.default'); | ||||||
|  | 
 | ||||||
|  |         foreach (self::$dbs as $db) { | ||||||
|  |             if (VendorContact::on($db)->where('contact_key', $contact_key)->exists()) { | ||||||
|  |                 self::setDb($db); | ||||||
|  | 
 | ||||||
|  |                 return true; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         self::setDB($current_db); | ||||||
|  | 
 | ||||||
|  |         return false; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     public static function findAndSetDbByClientHash($client_hash) :bool |     public static function findAndSetDbByClientHash($client_hash) :bool | ||||||
|     { |     { | ||||||
|         $current_db = config('database.default'); |         $current_db = config('database.default'); | ||||||
|  | |||||||
| @ -100,7 +100,6 @@ class InvoiceEmailEngine extends BaseEmailEngine | |||||||
|             $subject_template = $this->client->getSetting('email_subject_'.$this->reminder_template); |             $subject_template = $this->client->getSetting('email_subject_'.$this->reminder_template); | ||||||
|         } else { |         } else { | ||||||
|             $subject_template = EmailTemplateDefaults::getDefaultTemplate('email_subject_'.$this->reminder_template, $this->client->locale()); |             $subject_template = EmailTemplateDefaults::getDefaultTemplate('email_subject_'.$this->reminder_template, $this->client->locale()); | ||||||
|             // $subject_template = $this->client->getSetting('email_subject_'.$this->reminder_template);
 |  | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         if (iconv_strlen($subject_template) == 0) { |         if (iconv_strlen($subject_template) == 0) { | ||||||
|  | |||||||
| @ -146,10 +146,17 @@ class TemplateEmail extends Mailable | |||||||
| 
 | 
 | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |         //22-10-2022 - Performance - To improve the performance/reliability of sending emails, attaching as Data is much better, stubs in place
 | ||||||
|         foreach ($this->build_email->getAttachments() as $file) { |         foreach ($this->build_email->getAttachments() as $file) { | ||||||
|             if (is_string($file)) { |             if (is_string($file)) { | ||||||
|  |                 // nlog($file);
 | ||||||
|  |                 // $file_data = file_get_contents($file);
 | ||||||
|  |                 // $this->attachData($file_data, basename($file));
 | ||||||
|                 $this->attach($file); |                 $this->attach($file); | ||||||
|             } elseif (is_array($file)) { |             } elseif (is_array($file)) { | ||||||
|  |                 // nlog($file['path']);
 | ||||||
|  |                 // $file_data = file_get_contents($file['path']);
 | ||||||
|  |                 // $this->attachData($file_data, $file['name']);
 | ||||||
|                 $this->attach($file['path'], ['as' => $file['name'], 'mime' => null]); |                 $this->attach($file['path'], ['as' => $file['name'], 'mime' => null]); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  | |||||||
| @ -140,6 +140,11 @@ class Account extends BaseModel | |||||||
|         return $this->hasMany(Company::class); |         return $this->hasMany(Company::class); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     public function bank_integrations() | ||||||
|  |     { | ||||||
|  |         return $this->hasMany(BankIntegration::class); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     public function company_users() |     public function company_users() | ||||||
|     { |     { | ||||||
|         return $this->hasMany(CompanyUser::class); |         return $this->hasMany(CompanyUser::class); | ||||||
| @ -359,9 +364,9 @@ class Account extends BaseModel | |||||||
|                 'plan_price' => $price, |                 'plan_price' => $price, | ||||||
|                 'trial' => false, |                 'trial' => false, | ||||||
|                 'plan' => $plan, |                 'plan' => $plan, | ||||||
|                 'started' => DateTime::createFromFormat('Y-m-d', $this->plan_started), |                 'started' => $this->plan_started ? DateTime::createFromFormat('Y-m-d', $this->plan_started) : false, | ||||||
|                 'expires' => $plan_expires, |                 'expires' => $plan_expires, | ||||||
|                 'paid' => DateTime::createFromFormat('Y-m-d', $this->plan_paid), |                 'paid' => $this->plan_paid ? DateTime::createFromFormat('Y-m-d', $this->plan_paid) : false, | ||||||
|                 'term' => $this->plan_term, |                 'term' => $this->plan_term, | ||||||
|                 'active' => $plan_active, |                 'active' => $plan_active, | ||||||
|             ]; |             ]; | ||||||
|  | |||||||
| @ -36,15 +36,15 @@ class Backup extends BaseModel | |||||||
|         $filename = now()->format('Y_m_d').'_'.md5(time()).'.html'; |         $filename = now()->format('Y_m_d').'_'.md5(time()).'.html'; | ||||||
|         $file_path = $path.$filename; |         $file_path = $path.$filename; | ||||||
| 
 | 
 | ||||||
|         Storage::disk(config('filesystems.default'))->makeDirectory($path, 0775); |         // Storage::disk(config('filesystems.default'))->makeDirectory($path, 0775);
 | ||||||
| 
 | 
 | ||||||
|         Storage::disk(config('filesystems.default'))->put($file_path, $html); |         Storage::disk(config('filesystems.default'))->put($file_path, $html); | ||||||
| 
 | 
 | ||||||
|         if (Storage::disk(config('filesystems.default'))->exists($file_path)) { |         // if (Storage::disk(config('filesystems.default'))->exists($file_path)) {
 | ||||||
|             $this->html_backup = ''; |             $this->html_backup = ''; | ||||||
|             $this->filename = $file_path; |             $this->filename = $file_path; | ||||||
|             $this->save(); |             $this->save(); | ||||||
|         } |         // }
 | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public function deleteFile() |     public function deleteFile() | ||||||
|  | |||||||
Some files were not shown because too many files have changed in this diff Show More
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user