Преглед изворни кода

feat: Plaid import transaction updates

3.x
wallo пре 1 година
родитељ
комит
5a6f0a5503

+ 41
- 0
app/Console/Commands/FirePlaidWebhook.php Прегледај датотеку

1
+<?php
2
+
3
+namespace App\Console\Commands;
4
+
5
+use App\Models\Banking\ConnectedBankAccount;
6
+use App\Services\PlaidService;
7
+use Illuminate\Console\Command;
8
+
9
+class FirePlaidWebhook extends Command
10
+{
11
+    /**
12
+     * The name and signature of the console command.
13
+     *
14
+     * @var string
15
+     */
16
+    protected $signature = 'plaid:fire-webhook';
17
+
18
+    /**
19
+     * The console command description.
20
+     *
21
+     * @var string
22
+     */
23
+    protected $description = 'Command description';
24
+
25
+    /**
26
+     * Execute the console command.
27
+     */
28
+    public function handle(PlaidService $plaidService): void
29
+    {
30
+        $accessToken = ConnectedBankAccount::first()->access_token;
31
+        $webhookCode = 'DEFAULT_UPDATE';
32
+        $webhookType = 'TRANSACTIONS';
33
+
34
+        try {
35
+            $response = $plaidService->fireSandboxWebhook($accessToken, $webhookCode, $webhookType);
36
+            $this->info('Webhook Fired Successfully' . PHP_EOL . json_encode($response, JSON_PRETTY_PRINT));
37
+        } catch (\Exception $e) {
38
+            $this->error('Failed to Fire Webhook' . PHP_EOL . $e->getMessage());
39
+        }
40
+    }
41
+}

+ 6
- 1
app/Filament/Company/Resources/Banking/AccountResource.php Прегледај датотеку

251
             ])
251
             ])
252
             ->bulkActions([
252
             ->bulkActions([
253
                 Tables\Actions\BulkActionGroup::make([
253
                 Tables\Actions\BulkActionGroup::make([
254
-                    Tables\Actions\DeleteBulkAction::make(),
254
+                    Tables\Actions\DeleteBulkAction::make()
255
+                        ->requiresConfirmation()
256
+                        ->modalDescription('Are you sure you want to delete the selected accounts? All transactions associated with the accounts will be deleted as well.'),
255
                 ]),
257
                 ]),
256
             ])
258
             ])
259
+            ->checkIfRecordIsSelectableUsing(static function (BankAccount $record) {
260
+                return $record->isDisabled();
261
+            })
257
             ->emptyStateActions([
262
             ->emptyStateActions([
258
                 Tables\Actions\CreateAction::make(),
263
                 Tables\Actions\CreateAction::make(),
259
             ]);
264
             ]);

+ 1
- 2
app/Filament/Company/Resources/Banking/AccountResource/Pages/EditAccount.php Прегледај датотеку

4
 
4
 
5
 use App\Concerns\HandlesResourceRecordUpdate;
5
 use App\Concerns\HandlesResourceRecordUpdate;
6
 use App\Filament\Company\Resources\Banking\AccountResource;
6
 use App\Filament\Company\Resources\Banking\AccountResource;
7
-use Filament\Actions;
8
 use Filament\Resources\Pages\EditRecord;
7
 use Filament\Resources\Pages\EditRecord;
9
 
8
 
10
 class EditAccount extends EditRecord
9
 class EditAccount extends EditRecord
16
     protected function getHeaderActions(): array
15
     protected function getHeaderActions(): array
17
     {
16
     {
18
         return [
17
         return [
19
-            Actions\DeleteAction::make(),
18
+            //
20
         ];
19
         ];
21
     }
20
     }
22
 
21
 

+ 42
- 0
app/Http/Controllers/PlaidWebhookController.php Прегледај датотеку

1
+<?php
2
+
3
+namespace App\Http\Controllers;
4
+
5
+use App\Jobs\ProcessTransactionUpdate;
6
+use App\Models\Company;
7
+use Illuminate\Http\Request;
8
+
9
+class PlaidWebhookController extends Controller
10
+{
11
+    public function handleWebhook(Request $request)
12
+    {
13
+        $payload = $request->all();
14
+
15
+        if ($payload['webhook_type'] === 'TRANSACTIONS') {
16
+            $this->handleTransactionsWebhook($payload);
17
+        }
18
+
19
+        return response()->json(['message' => 'Plaid Transaction Webhook Received']);
20
+    }
21
+
22
+    private function handleTransactionsWebhook(array $payload): void
23
+    {
24
+        if ($payload['webhook_code'] === 'DEFAULT_UPDATE') {
25
+            $this->handleDefaultUpdate($payload);
26
+        }
27
+    }
28
+
29
+    private function handleDefaultUpdate(array $payload): void
30
+    {
31
+        $newTransactions = $payload['new_transactions'];
32
+        $itemID = $payload['item_id'];
33
+
34
+        $company = Company::whereHas('connectedBankAccounts', static function ($query) use ($itemID) {
35
+            $query->where('item_id', $itemID);
36
+        })->first();
37
+
38
+        if ($company && $newTransactions > 0) {
39
+            ProcessTransactionUpdate::dispatch($company, $itemID);
40
+        }
41
+    }
42
+}

+ 4
- 0
app/Jobs/ProcessTransactionImport.php Прегледај датотеку

78
 
78
 
79
             $transactionService->createStartingBalanceIfNeeded($this->company, $this->account, $this->bankAccount, $postedTransactions, $currentBalance, $startDate);
79
             $transactionService->createStartingBalanceIfNeeded($this->company, $this->account, $this->bankAccount, $postedTransactions, $currentBalance, $startDate);
80
             $transactionService->storeTransactions($this->company, $this->bankAccount, $postedTransactions);
80
             $transactionService->storeTransactions($this->company, $this->bankAccount, $postedTransactions);
81
+
82
+            $this->connectedBankAccount->update([
83
+                'last_imported_at' => Carbon::now(),
84
+            ]);
81
         }
85
         }
82
     }
86
     }
83
 }
87
 }

+ 88
- 0
app/Jobs/ProcessTransactionUpdate.php Прегледај датотеку

1
+<?php
2
+
3
+namespace App\Jobs;
4
+
5
+use App\Models\Banking\ConnectedBankAccount;
6
+use App\Models\Company;
7
+use App\Services\PlaidService;
8
+use App\Services\TransactionService;
9
+use Illuminate\Bus\Queueable;
10
+use Illuminate\Contracts\Queue\ShouldQueue;
11
+use Illuminate\Foundation\Bus\Dispatchable;
12
+use Illuminate\Queue\InteractsWithQueue;
13
+use Illuminate\Queue\SerializesModels;
14
+use Illuminate\Support\Carbon;
15
+
16
+class ProcessTransactionUpdate implements ShouldQueue
17
+{
18
+    use Dispatchable;
19
+    use InteractsWithQueue;
20
+    use Queueable;
21
+    use SerializesModels;
22
+
23
+    protected Company $company;
24
+
25
+    protected string $item_id;
26
+
27
+    /**
28
+     * Create a new job instance.
29
+     */
30
+    public function __construct(Company $company, string $item_id)
31
+    {
32
+        $this->company = $company;
33
+        $this->item_id = $item_id;
34
+    }
35
+
36
+    /**
37
+     * Execute the job.
38
+     */
39
+    public function handle(PlaidService $plaidService, TransactionService $transactionService): void
40
+    {
41
+        $connectedBankAccounts = $this->company->connectedBankAccounts()
42
+            ->where('item_id', $this->item_id)
43
+            ->where('import_transactions', true);
44
+
45
+        foreach ($connectedBankAccounts as $connectedBankAccount) {
46
+            /** @var ConnectedBankAccount $connectedBankAccount */
47
+            $accessToken = $connectedBankAccount->access_token;
48
+            $bankAccount = $connectedBankAccount->bankAccount;
49
+            $allTransactions = [];
50
+            $offset = 0;
51
+
52
+            $bufferDays = 15;
53
+            $lastImportedAtDate = Carbon::parse($connectedBankAccount->last_imported_at);
54
+            $startDate = $lastImportedAtDate->subDays($bufferDays)->toDateString();
55
+            $endDate = Carbon::now()->toDateString();
56
+
57
+            $transactionsResponse = $plaidService->getTransactions($accessToken, $startDate, $endDate, [
58
+                'account_ids' => [$connectedBankAccount->external_account_id],
59
+            ]);
60
+
61
+            $allTransactions = [...$allTransactions, ...$transactionsResponse->transactions];
62
+            $totalTransactions = $transactionsResponse->total_transactions;
63
+
64
+            while (count($allTransactions) < $totalTransactions) {
65
+                $offset += count($transactionsResponse->transactions);
66
+                $transactionsResponse = $plaidService->getTransactions($accessToken, $startDate, $endDate, [
67
+                    'account_ids' => [$connectedBankAccount->external_account_id],
68
+                    'offset' => $offset,
69
+                ]);
70
+
71
+                $allTransactions = [...$allTransactions, ...$transactionsResponse->transactions];
72
+            }
73
+
74
+            $existingTransactionIds = $bankAccount->transactions()->pluck('transaction_id')->toArray();
75
+            $newTransactions = array_filter($allTransactions, static function ($transaction) use ($existingTransactionIds) {
76
+                return ! in_array($transaction->transaction_id, $existingTransactionIds) && $transaction->pending === false;
77
+            });
78
+
79
+            if (count($newTransactions) > 0) {
80
+                $transactionService->storeTransactions($this->company, $bankAccount, $newTransactions);
81
+
82
+                $connectedBankAccount->update([
83
+                    'last_imported_at' => Carbon::now(),
84
+                ]);
85
+            }
86
+        }
87
+    }
88
+}

+ 1
- 0
app/Models/Accounting/Transaction.php Прегледај датотеку

28
         'company_id',
28
         'company_id',
29
         'account_id', // Account from Chart of Accounts (Income/Expense accounts)
29
         'account_id', // Account from Chart of Accounts (Income/Expense accounts)
30
         'bank_account_id', // Cash/Bank Account
30
         'bank_account_id', // Cash/Bank Account
31
+        'plaid_transaction_id',
31
         'contact_id',
32
         'contact_id',
32
         'type', // 'deposit', 'withdrawal', 'journal'
33
         'type', // 'deposit', 'withdrawal', 'journal'
33
         'payment_channel',
34
         'payment_channel',

+ 2
- 0
app/Models/Banking/ConnectedBankAccount.php Прегледај датотеку

33
         'type',
33
         'type',
34
         'subtype',
34
         'subtype',
35
         'import_transactions',
35
         'import_transactions',
36
+        'last_imported_at',
36
         'created_by',
37
         'created_by',
37
         'updated_by',
38
         'updated_by',
38
     ];
39
     ];
41
         'import_transactions' => 'boolean',
42
         'import_transactions' => 'boolean',
42
         'type' => BankAccountType::class,
43
         'type' => BankAccountType::class,
43
         'access_token' => 'encrypted',
44
         'access_token' => 'encrypted',
45
+        'last_imported_at' => 'datetime',
44
     ];
46
     ];
45
 
47
 
46
     protected $appends = [
48
     protected $appends = [

+ 13
- 0
app/Models/Banking/Institution.php Прегледај датотеку

57
         return null;
57
         return null;
58
     }
58
     }
59
 
59
 
60
+    public function getLastImportDate(): ?string
61
+    {
62
+        $latestDate = $this->connectedBankAccounts->map(function ($connectedBankAccount) {
63
+            return $connectedBankAccount->last_imported_at;
64
+        })->filter()->max();
65
+
66
+        if ($latestDate) {
67
+            return Carbon::parse($latestDate)->diffForHumans();
68
+        }
69
+
70
+        return null;
71
+    }
72
+
60
     protected function logoUrl(): Attribute
73
     protected function logoUrl(): Attribute
61
     {
74
     {
62
         return Attribute::get(static function (mixed $value, array $attributes): ?string {
75
         return Attribute::get(static function (mixed $value, array $attributes): ?string {

+ 22
- 1
app/Observers/BankAccountObserver.php Прегледај датотеку

3
 namespace App\Observers;
3
 namespace App\Observers;
4
 
4
 
5
 use App\Enums\Accounting\AccountType;
5
 use App\Enums\Accounting\AccountType;
6
-use App\Models\Accounting\Account;
7
 use App\Models\Accounting\AccountSubtype;
6
 use App\Models\Accounting\AccountSubtype;
7
+use App\Models\Accounting\Transaction;
8
 use App\Models\Banking\BankAccount;
8
 use App\Models\Banking\BankAccount;
9
+use Illuminate\Support\Facades\DB;
9
 
10
 
10
 class BankAccountObserver
11
 class BankAccountObserver
11
 {
12
 {
52
         //
53
         //
53
     }
54
     }
54
 
55
 
56
+    /**
57
+     * Handle the BankAccount "deleting" event.
58
+     */
59
+    public function deleting(BankAccount $bankAccount): void
60
+    {
61
+        DB::transaction(function () use ($bankAccount) {
62
+            $account = $bankAccount->account;
63
+            $connectedBankAccount = $bankAccount->connectedBankAccount;
64
+
65
+            if ($account) {
66
+                $bankAccount->transactions()->each(fn (Transaction $transaction) => $transaction->delete());
67
+                $account->delete();
68
+            }
69
+
70
+            if ($connectedBankAccount) {
71
+                $connectedBankAccount->delete();
72
+            }
73
+        });
74
+    }
75
+
55
     /**
76
     /**
56
      * Handle the BankAccount "deleted" event.
77
      * Handle the BankAccount "deleted" event.
57
      */
78
      */

+ 14
- 0
app/Services/PlaidService.php Прегледај датотеку

21
 
21
 
22
     protected ?string $environment;
22
     protected ?string $environment;
23
 
23
 
24
+    protected ?string $webhook_url;
25
+
24
     protected ?string $base_url;
26
     protected ?string $base_url;
25
 
27
 
26
     protected HttpClient $client;
28
     protected HttpClient $client;
51
         $this->client_id = $this->config->get('plaid.client_id');
53
         $this->client_id = $this->config->get('plaid.client_id');
52
         $this->client_secret = $this->config->get('plaid.client_secret');
54
         $this->client_secret = $this->config->get('plaid.client_secret');
53
         $this->environment = $this->config->get('plaid.environment', 'sandbox');
55
         $this->environment = $this->config->get('plaid.environment', 'sandbox');
56
+        $this->webhook_url = $this->config->get('plaid.webhook_url');
54
 
57
 
55
         $this->setBaseUrl($this->environment);
58
         $this->setBaseUrl($this->environment);
56
     }
59
     }
191
             $data['products'] = $products;
194
             $data['products'] = $products;
192
         }
195
         }
193
 
196
 
197
+        if (! empty($this->webhook_url)) {
198
+            $data['webhook'] = $this->webhook_url;
199
+        }
200
+
194
         return $this->sendRequest('link/token/create', $data);
201
         return $this->sendRequest('link/token/create', $data);
195
     }
202
     }
196
 
203
 
244
 
251
 
245
         return $this->sendRequest('transactions/get', $data);
252
         return $this->sendRequest('transactions/get', $data);
246
     }
253
     }
254
+
255
+    public function fireSandboxWebhook(string $access_token, string $webhook_code, string $webhook_type): object
256
+    {
257
+        $data = compact('access_token', 'webhook_code', 'webhook_type');
258
+
259
+        return $this->sendRequest('sandbox/item/fire_webhook', $data);
260
+    }
247
 }
261
 }

+ 1
- 0
app/Services/TransactionService.php Прегледај датотеку

70
             'company_id' => $company->id,
70
             'company_id' => $company->id,
71
             'account_id' => $chartAccount->id,
71
             'account_id' => $chartAccount->id,
72
             'bank_account_id' => $bankAccount->id,
72
             'bank_account_id' => $bankAccount->id,
73
+            'plaid_transaction_id' => $transaction->transaction_id,
73
             'type' => $transactionType,
74
             'type' => $transactionType,
74
             'amount' => abs($transaction->amount),
75
             'amount' => abs($transaction->amount),
75
             'payment_channel' => $paymentChannel,
76
             'payment_channel' => $paymentChannel,

+ 47
- 47
composer.lock Прегледај датотеку

497
         },
497
         },
498
         {
498
         {
499
             "name": "aws/aws-sdk-php",
499
             "name": "aws/aws-sdk-php",
500
-            "version": "3.304.3",
500
+            "version": "3.304.4",
501
             "source": {
501
             "source": {
502
                 "type": "git",
502
                 "type": "git",
503
                 "url": "https://github.com/aws/aws-sdk-php.git",
503
                 "url": "https://github.com/aws/aws-sdk-php.git",
504
-                "reference": "d1ecaba720dc5d935d4ff66255f990fce3aa9727"
504
+                "reference": "20be41a5f1eef4c8a53a6ae7c0fc8b7346c0c386"
505
             },
505
             },
506
             "dist": {
506
             "dist": {
507
                 "type": "zip",
507
                 "type": "zip",
508
-                "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/d1ecaba720dc5d935d4ff66255f990fce3aa9727",
509
-                "reference": "d1ecaba720dc5d935d4ff66255f990fce3aa9727",
508
+                "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/20be41a5f1eef4c8a53a6ae7c0fc8b7346c0c386",
509
+                "reference": "20be41a5f1eef4c8a53a6ae7c0fc8b7346c0c386",
510
                 "shasum": ""
510
                 "shasum": ""
511
             },
511
             },
512
             "require": {
512
             "require": {
586
             "support": {
586
             "support": {
587
                 "forum": "https://forums.aws.amazon.com/forum.jspa?forumID=80",
587
                 "forum": "https://forums.aws.amazon.com/forum.jspa?forumID=80",
588
                 "issues": "https://github.com/aws/aws-sdk-php/issues",
588
                 "issues": "https://github.com/aws/aws-sdk-php/issues",
589
-                "source": "https://github.com/aws/aws-sdk-php/tree/3.304.3"
589
+                "source": "https://github.com/aws/aws-sdk-php/tree/3.304.4"
590
             },
590
             },
591
-            "time": "2024-04-11T18:05:41+00:00"
591
+            "time": "2024-04-12T18:06:45+00:00"
592
         },
592
         },
593
         {
593
         {
594
             "name": "aws/aws-sdk-php-laravel",
594
             "name": "aws/aws-sdk-php-laravel",
1790
         },
1790
         },
1791
         {
1791
         {
1792
             "name": "dompdf/dompdf",
1792
             "name": "dompdf/dompdf",
1793
-            "version": "v2.0.4",
1793
+            "version": "v2.0.5",
1794
             "source": {
1794
             "source": {
1795
                 "type": "git",
1795
                 "type": "git",
1796
                 "url": "https://github.com/dompdf/dompdf.git",
1796
                 "url": "https://github.com/dompdf/dompdf.git",
1797
-                "reference": "093f2d9739cec57428e39ddadedfd4f3ae862c0f"
1797
+                "reference": "502e966a0da0446dd6712ee4f678dc4736181fcb"
1798
             },
1798
             },
1799
             "dist": {
1799
             "dist": {
1800
                 "type": "zip",
1800
                 "type": "zip",
1801
-                "url": "https://api.github.com/repos/dompdf/dompdf/zipball/093f2d9739cec57428e39ddadedfd4f3ae862c0f",
1802
-                "reference": "093f2d9739cec57428e39ddadedfd4f3ae862c0f",
1801
+                "url": "https://api.github.com/repos/dompdf/dompdf/zipball/502e966a0da0446dd6712ee4f678dc4736181fcb",
1802
+                "reference": "502e966a0da0446dd6712ee4f678dc4736181fcb",
1803
                 "shasum": ""
1803
                 "shasum": ""
1804
             },
1804
             },
1805
             "require": {
1805
             "require": {
1807
                 "ext-mbstring": "*",
1807
                 "ext-mbstring": "*",
1808
                 "masterminds/html5": "^2.0",
1808
                 "masterminds/html5": "^2.0",
1809
                 "phenx/php-font-lib": ">=0.5.4 <1.0.0",
1809
                 "phenx/php-font-lib": ">=0.5.4 <1.0.0",
1810
-                "phenx/php-svg-lib": ">=0.3.3 <1.0.0",
1810
+                "phenx/php-svg-lib": ">=0.5.2 <1.0.0",
1811
                 "php": "^7.1 || ^8.0"
1811
                 "php": "^7.1 || ^8.0"
1812
             },
1812
             },
1813
             "require-dev": {
1813
             "require-dev": {
1846
             "homepage": "https://github.com/dompdf/dompdf",
1846
             "homepage": "https://github.com/dompdf/dompdf",
1847
             "support": {
1847
             "support": {
1848
                 "issues": "https://github.com/dompdf/dompdf/issues",
1848
                 "issues": "https://github.com/dompdf/dompdf/issues",
1849
-                "source": "https://github.com/dompdf/dompdf/tree/v2.0.4"
1849
+                "source": "https://github.com/dompdf/dompdf/tree/v2.0.5"
1850
             },
1850
             },
1851
-            "time": "2023-12-12T20:19:39+00:00"
1851
+            "time": "2024-04-11T11:59:08+00:00"
1852
         },
1852
         },
1853
         {
1853
         {
1854
             "name": "dragonmantank/cron-expression",
1854
             "name": "dragonmantank/cron-expression",
1980
         },
1980
         },
1981
         {
1981
         {
1982
             "name": "filament/actions",
1982
             "name": "filament/actions",
1983
-            "version": "v3.2.65",
1983
+            "version": "v3.2.66",
1984
             "source": {
1984
             "source": {
1985
                 "type": "git",
1985
                 "type": "git",
1986
                 "url": "https://github.com/filamentphp/actions.git",
1986
                 "url": "https://github.com/filamentphp/actions.git",
2033
         },
2033
         },
2034
         {
2034
         {
2035
             "name": "filament/filament",
2035
             "name": "filament/filament",
2036
-            "version": "v3.2.65",
2036
+            "version": "v3.2.66",
2037
             "source": {
2037
             "source": {
2038
                 "type": "git",
2038
                 "type": "git",
2039
                 "url": "https://github.com/filamentphp/panels.git",
2039
                 "url": "https://github.com/filamentphp/panels.git",
2040
-                "reference": "669ce35aef3a577af7f5d27b8acc7e4622c45f33"
2040
+                "reference": "69c4c60fbc9c22708dde1aee017c4cc2ff99e0a1"
2041
             },
2041
             },
2042
             "dist": {
2042
             "dist": {
2043
                 "type": "zip",
2043
                 "type": "zip",
2044
-                "url": "https://api.github.com/repos/filamentphp/panels/zipball/669ce35aef3a577af7f5d27b8acc7e4622c45f33",
2045
-                "reference": "669ce35aef3a577af7f5d27b8acc7e4622c45f33",
2044
+                "url": "https://api.github.com/repos/filamentphp/panels/zipball/69c4c60fbc9c22708dde1aee017c4cc2ff99e0a1",
2045
+                "reference": "69c4c60fbc9c22708dde1aee017c4cc2ff99e0a1",
2046
                 "shasum": ""
2046
                 "shasum": ""
2047
             },
2047
             },
2048
             "require": {
2048
             "require": {
2094
                 "issues": "https://github.com/filamentphp/filament/issues",
2094
                 "issues": "https://github.com/filamentphp/filament/issues",
2095
                 "source": "https://github.com/filamentphp/filament"
2095
                 "source": "https://github.com/filamentphp/filament"
2096
             },
2096
             },
2097
-            "time": "2024-04-11T21:38:39+00:00"
2097
+            "time": "2024-04-12T14:57:11+00:00"
2098
         },
2098
         },
2099
         {
2099
         {
2100
             "name": "filament/forms",
2100
             "name": "filament/forms",
2101
-            "version": "v3.2.65",
2101
+            "version": "v3.2.66",
2102
             "source": {
2102
             "source": {
2103
                 "type": "git",
2103
                 "type": "git",
2104
                 "url": "https://github.com/filamentphp/forms.git",
2104
                 "url": "https://github.com/filamentphp/forms.git",
2154
         },
2154
         },
2155
         {
2155
         {
2156
             "name": "filament/infolists",
2156
             "name": "filament/infolists",
2157
-            "version": "v3.2.65",
2157
+            "version": "v3.2.66",
2158
             "source": {
2158
             "source": {
2159
                 "type": "git",
2159
                 "type": "git",
2160
                 "url": "https://github.com/filamentphp/infolists.git",
2160
                 "url": "https://github.com/filamentphp/infolists.git",
2205
         },
2205
         },
2206
         {
2206
         {
2207
             "name": "filament/notifications",
2207
             "name": "filament/notifications",
2208
-            "version": "v3.2.65",
2208
+            "version": "v3.2.66",
2209
             "source": {
2209
             "source": {
2210
                 "type": "git",
2210
                 "type": "git",
2211
                 "url": "https://github.com/filamentphp/notifications.git",
2211
                 "url": "https://github.com/filamentphp/notifications.git",
2257
         },
2257
         },
2258
         {
2258
         {
2259
             "name": "filament/support",
2259
             "name": "filament/support",
2260
-            "version": "v3.2.65",
2260
+            "version": "v3.2.66",
2261
             "source": {
2261
             "source": {
2262
                 "type": "git",
2262
                 "type": "git",
2263
                 "url": "https://github.com/filamentphp/support.git",
2263
                 "url": "https://github.com/filamentphp/support.git",
2315
         },
2315
         },
2316
         {
2316
         {
2317
             "name": "filament/tables",
2317
             "name": "filament/tables",
2318
-            "version": "v3.2.65",
2318
+            "version": "v3.2.66",
2319
             "source": {
2319
             "source": {
2320
                 "type": "git",
2320
                 "type": "git",
2321
                 "url": "https://github.com/filamentphp/tables.git",
2321
                 "url": "https://github.com/filamentphp/tables.git",
2322
-                "reference": "1cdf9ee9ba35cad6e8e41725896e26e397549440"
2322
+                "reference": "0f3d2b3525a7ffd6cf71f26fcc02d33c4d6c7793"
2323
             },
2323
             },
2324
             "dist": {
2324
             "dist": {
2325
                 "type": "zip",
2325
                 "type": "zip",
2326
-                "url": "https://api.github.com/repos/filamentphp/tables/zipball/1cdf9ee9ba35cad6e8e41725896e26e397549440",
2327
-                "reference": "1cdf9ee9ba35cad6e8e41725896e26e397549440",
2326
+                "url": "https://api.github.com/repos/filamentphp/tables/zipball/0f3d2b3525a7ffd6cf71f26fcc02d33c4d6c7793",
2327
+                "reference": "0f3d2b3525a7ffd6cf71f26fcc02d33c4d6c7793",
2328
                 "shasum": ""
2328
                 "shasum": ""
2329
             },
2329
             },
2330
             "require": {
2330
             "require": {
2364
                 "issues": "https://github.com/filamentphp/filament/issues",
2364
                 "issues": "https://github.com/filamentphp/filament/issues",
2365
                 "source": "https://github.com/filamentphp/filament"
2365
                 "source": "https://github.com/filamentphp/filament"
2366
             },
2366
             },
2367
-            "time": "2024-04-11T07:41:14+00:00"
2367
+            "time": "2024-04-12T14:57:32+00:00"
2368
         },
2368
         },
2369
         {
2369
         {
2370
             "name": "filament/widgets",
2370
             "name": "filament/widgets",
2371
-            "version": "v3.2.65",
2371
+            "version": "v3.2.66",
2372
             "source": {
2372
             "source": {
2373
                 "type": "git",
2373
                 "type": "git",
2374
                 "url": "https://github.com/filamentphp/widgets.git",
2374
                 "url": "https://github.com/filamentphp/widgets.git",
4490
         },
4490
         },
4491
         {
4491
         {
4492
             "name": "matomo/device-detector",
4492
             "name": "matomo/device-detector",
4493
-            "version": "6.3.0",
4493
+            "version": "6.3.1",
4494
             "source": {
4494
             "source": {
4495
                 "type": "git",
4495
                 "type": "git",
4496
                 "url": "https://github.com/matomo-org/device-detector.git",
4496
                 "url": "https://github.com/matomo-org/device-detector.git",
4497
-                "reference": "35efad75b31f2596701834d19f097497909572a4"
4497
+                "reference": "8096093346917ee2477d802ab3b00c4c091c5cee"
4498
             },
4498
             },
4499
             "dist": {
4499
             "dist": {
4500
                 "type": "zip",
4500
                 "type": "zip",
4501
-                "url": "https://api.github.com/repos/matomo-org/device-detector/zipball/35efad75b31f2596701834d19f097497909572a4",
4502
-                "reference": "35efad75b31f2596701834d19f097497909572a4",
4501
+                "url": "https://api.github.com/repos/matomo-org/device-detector/zipball/8096093346917ee2477d802ab3b00c4c091c5cee",
4502
+                "reference": "8096093346917ee2477d802ab3b00c4c091c5cee",
4503
                 "shasum": ""
4503
                 "shasum": ""
4504
             },
4504
             },
4505
             "require": {
4505
             "require": {
4555
                 "source": "https://github.com/matomo-org/matomo",
4555
                 "source": "https://github.com/matomo-org/matomo",
4556
                 "wiki": "https://dev.matomo.org/"
4556
                 "wiki": "https://dev.matomo.org/"
4557
             },
4557
             },
4558
-            "time": "2024-02-16T16:26:57+00:00"
4558
+            "time": "2024-04-12T12:16:21+00:00"
4559
         },
4559
         },
4560
         {
4560
         {
4561
             "name": "monolog/monolog",
4561
             "name": "monolog/monolog",
4562
-            "version": "3.5.0",
4562
+            "version": "3.6.0",
4563
             "source": {
4563
             "source": {
4564
                 "type": "git",
4564
                 "type": "git",
4565
                 "url": "https://github.com/Seldaek/monolog.git",
4565
                 "url": "https://github.com/Seldaek/monolog.git",
4566
-                "reference": "c915e2634718dbc8a4a15c61b0e62e7a44e14448"
4566
+                "reference": "4b18b21a5527a3d5ffdac2fd35d3ab25a9597654"
4567
             },
4567
             },
4568
             "dist": {
4568
             "dist": {
4569
                 "type": "zip",
4569
                 "type": "zip",
4570
-                "url": "https://api.github.com/repos/Seldaek/monolog/zipball/c915e2634718dbc8a4a15c61b0e62e7a44e14448",
4571
-                "reference": "c915e2634718dbc8a4a15c61b0e62e7a44e14448",
4570
+                "url": "https://api.github.com/repos/Seldaek/monolog/zipball/4b18b21a5527a3d5ffdac2fd35d3ab25a9597654",
4571
+                "reference": "4b18b21a5527a3d5ffdac2fd35d3ab25a9597654",
4572
                 "shasum": ""
4572
                 "shasum": ""
4573
             },
4573
             },
4574
             "require": {
4574
             "require": {
4591
                 "phpstan/phpstan": "^1.9",
4591
                 "phpstan/phpstan": "^1.9",
4592
                 "phpstan/phpstan-deprecation-rules": "^1.0",
4592
                 "phpstan/phpstan-deprecation-rules": "^1.0",
4593
                 "phpstan/phpstan-strict-rules": "^1.4",
4593
                 "phpstan/phpstan-strict-rules": "^1.4",
4594
-                "phpunit/phpunit": "^10.1",
4594
+                "phpunit/phpunit": "^10.5.17",
4595
                 "predis/predis": "^1.1 || ^2",
4595
                 "predis/predis": "^1.1 || ^2",
4596
                 "ruflin/elastica": "^7",
4596
                 "ruflin/elastica": "^7",
4597
                 "symfony/mailer": "^5.4 || ^6",
4597
                 "symfony/mailer": "^5.4 || ^6",
4644
             ],
4644
             ],
4645
             "support": {
4645
             "support": {
4646
                 "issues": "https://github.com/Seldaek/monolog/issues",
4646
                 "issues": "https://github.com/Seldaek/monolog/issues",
4647
-                "source": "https://github.com/Seldaek/monolog/tree/3.5.0"
4647
+                "source": "https://github.com/Seldaek/monolog/tree/3.6.0"
4648
             },
4648
             },
4649
             "funding": [
4649
             "funding": [
4650
                 {
4650
                 {
4656
                     "type": "tidelift"
4656
                     "type": "tidelift"
4657
                 }
4657
                 }
4658
             ],
4658
             ],
4659
-            "time": "2023-10-27T15:32:31+00:00"
4659
+            "time": "2024-04-12T21:02:21+00:00"
4660
         },
4660
         },
4661
         {
4661
         {
4662
             "name": "mtdowling/jmespath.php",
4662
             "name": "mtdowling/jmespath.php",
10344
         },
10344
         },
10345
         {
10345
         {
10346
             "name": "phpunit/phpunit",
10346
             "name": "phpunit/phpunit",
10347
-            "version": "10.5.17",
10347
+            "version": "10.5.18",
10348
             "source": {
10348
             "source": {
10349
                 "type": "git",
10349
                 "type": "git",
10350
                 "url": "https://github.com/sebastianbergmann/phpunit.git",
10350
                 "url": "https://github.com/sebastianbergmann/phpunit.git",
10351
-                "reference": "c1f736a473d21957ead7e94fcc029f571895abf5"
10351
+                "reference": "835df1709ac6c968ba34bf23f3c30e5d5a266de8"
10352
             },
10352
             },
10353
             "dist": {
10353
             "dist": {
10354
                 "type": "zip",
10354
                 "type": "zip",
10355
-                "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/c1f736a473d21957ead7e94fcc029f571895abf5",
10356
-                "reference": "c1f736a473d21957ead7e94fcc029f571895abf5",
10355
+                "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/835df1709ac6c968ba34bf23f3c30e5d5a266de8",
10356
+                "reference": "835df1709ac6c968ba34bf23f3c30e5d5a266de8",
10357
                 "shasum": ""
10357
                 "shasum": ""
10358
             },
10358
             },
10359
             "require": {
10359
             "require": {
10425
             "support": {
10425
             "support": {
10426
                 "issues": "https://github.com/sebastianbergmann/phpunit/issues",
10426
                 "issues": "https://github.com/sebastianbergmann/phpunit/issues",
10427
                 "security": "https://github.com/sebastianbergmann/phpunit/security/policy",
10427
                 "security": "https://github.com/sebastianbergmann/phpunit/security/policy",
10428
-                "source": "https://github.com/sebastianbergmann/phpunit/tree/10.5.17"
10428
+                "source": "https://github.com/sebastianbergmann/phpunit/tree/10.5.18"
10429
             },
10429
             },
10430
             "funding": [
10430
             "funding": [
10431
                 {
10431
                 {
10441
                     "type": "tidelift"
10441
                     "type": "tidelift"
10442
                 }
10442
                 }
10443
             ],
10443
             ],
10444
-            "time": "2024-04-05T04:39:01+00:00"
10444
+            "time": "2024-04-14T07:05:31+00:00"
10445
         },
10445
         },
10446
         {
10446
         {
10447
             "name": "sebastian/cli-parser",
10447
             "name": "sebastian/cli-parser",

+ 1
- 0
config/plaid.php Прегледај датотеку

4
     'client_id' => env('PLAID_CLIENT_ID'),
4
     'client_id' => env('PLAID_CLIENT_ID'),
5
     'client_secret' => env('PLAID_CLIENT_SECRET'),
5
     'client_secret' => env('PLAID_CLIENT_SECRET'),
6
     'environment' => env('PLAID_ENVIRONMENT', 'sandbox'),
6
     'environment' => env('PLAID_ENVIRONMENT', 'sandbox'),
7
+    'webhook_url' => env('PLAID_WEBHOOK_URL'), // Example: https://my-static-domain.ngrok-free.app/api/plaid/webhook
7
 ];
8
 ];

+ 1
- 0
database/migrations/2023_09_03_100000_create_accounting_tables.php Прегледај датотеку

86
             $table->string('type')->default(BankAccountType::DEFAULT);
86
             $table->string('type')->default(BankAccountType::DEFAULT);
87
             $table->string('subtype')->nullable();
87
             $table->string('subtype')->nullable();
88
             $table->boolean('import_transactions')->default(false);
88
             $table->boolean('import_transactions')->default(false);
89
+            $table->timestamp('last_imported_at')->nullable();
89
             $table->foreignId('created_by')->nullable()->constrained('users')->nullOnDelete();
90
             $table->foreignId('created_by')->nullable()->constrained('users')->nullOnDelete();
90
             $table->foreignId('updated_by')->nullable()->constrained('users')->nullOnDelete();
91
             $table->foreignId('updated_by')->nullable()->constrained('users')->nullOnDelete();
91
             $table->timestamps();
92
             $table->timestamps();

+ 1
- 0
database/migrations/2024_01_01_234943_create_transactions_table.php Прегледај датотеку

16
             $table->foreignId('company_id')->constrained()->cascadeOnDelete();
16
             $table->foreignId('company_id')->constrained()->cascadeOnDelete();
17
             $table->foreignId('account_id')->nullable()->constrained()->nullOnDelete();
17
             $table->foreignId('account_id')->nullable()->constrained()->nullOnDelete();
18
             $table->foreignId('bank_account_id')->nullable()->constrained()->nullOnDelete();
18
             $table->foreignId('bank_account_id')->nullable()->constrained()->nullOnDelete();
19
+            $table->string('plaid_transaction_id')->nullable();
19
             $table->foreignId('contact_id')->nullable()->constrained()->nullOnDelete();
20
             $table->foreignId('contact_id')->nullable()->constrained()->nullOnDelete();
20
             $table->string('type'); // deposit, withdrawal, journal
21
             $table->string('type'); // deposit, withdrawal, journal
21
             $table->string('payment_channel')->nullable(); // online, in store, other
22
             $table->string('payment_channel')->nullable(); // online, in store, other

+ 70
- 70
package-lock.json Прегледај датотеку

507
             }
507
             }
508
         },
508
         },
509
         "node_modules/@rollup/rollup-android-arm-eabi": {
509
         "node_modules/@rollup/rollup-android-arm-eabi": {
510
-            "version": "4.14.1",
511
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.14.1.tgz",
512
-            "integrity": "sha512-fH8/o8nSUek8ceQnT7K4EQbSiV7jgkHq81m9lWZFIXjJ7lJzpWXbQFpT/Zh6OZYnpFykvzC3fbEvEAFZu03dPA==",
510
+            "version": "4.14.2",
511
+            "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.14.2.tgz",
512
+            "integrity": "sha512-ahxSgCkAEk+P/AVO0vYr7DxOD3CwAQrT0Go9BJyGQ9Ef0QxVOfjDZMiF4Y2s3mLyPrjonchIMH/tbWHucJMykQ==",
513
             "cpu": [
513
             "cpu": [
514
                 "arm"
514
                 "arm"
515
             ],
515
             ],
520
             ]
520
             ]
521
         },
521
         },
522
         "node_modules/@rollup/rollup-android-arm64": {
522
         "node_modules/@rollup/rollup-android-arm64": {
523
-            "version": "4.14.1",
524
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.14.1.tgz",
525
-            "integrity": "sha512-Y/9OHLjzkunF+KGEoJr3heiD5X9OLa8sbT1lm0NYeKyaM3oMhhQFvPB0bNZYJwlq93j8Z6wSxh9+cyKQaxS7PQ==",
523
+            "version": "4.14.2",
524
+            "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.14.2.tgz",
525
+            "integrity": "sha512-lAarIdxZWbFSHFSDao9+I/F5jDaKyCqAPMq5HqnfpBw8dKDiCaaqM0lq5h1pQTLeIqueeay4PieGR5jGZMWprw==",
526
             "cpu": [
526
             "cpu": [
527
                 "arm64"
527
                 "arm64"
528
             ],
528
             ],
533
             ]
533
             ]
534
         },
534
         },
535
         "node_modules/@rollup/rollup-darwin-arm64": {
535
         "node_modules/@rollup/rollup-darwin-arm64": {
536
-            "version": "4.14.1",
537
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.14.1.tgz",
538
-            "integrity": "sha512-+kecg3FY84WadgcuSVm6llrABOdQAEbNdnpi5X3UwWiFVhZIZvKgGrF7kmLguvxHNQy+UuRV66cLVl3S+Rkt+Q==",
536
+            "version": "4.14.2",
537
+            "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.14.2.tgz",
538
+            "integrity": "sha512-SWsr8zEUk82KSqquIMgZEg2GE5mCSfr9sE/thDROkX6pb3QQWPp8Vw8zOq2GyxZ2t0XoSIUlvHDkrf5Gmf7x3Q==",
539
             "cpu": [
539
             "cpu": [
540
                 "arm64"
540
                 "arm64"
541
             ],
541
             ],
546
             ]
546
             ]
547
         },
547
         },
548
         "node_modules/@rollup/rollup-darwin-x64": {
548
         "node_modules/@rollup/rollup-darwin-x64": {
549
-            "version": "4.14.1",
550
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.14.1.tgz",
551
-            "integrity": "sha512-2pYRzEjVqq2TB/UNv47BV/8vQiXkFGVmPFwJb+1E0IFFZbIX8/jo1olxqqMbo6xCXf8kabANhp5bzCij2tFLUA==",
549
+            "version": "4.14.2",
550
+            "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.14.2.tgz",
551
+            "integrity": "sha512-o/HAIrQq0jIxJAhgtIvV5FWviYK4WB0WwV91SLUnsliw1lSAoLsmgEEgRWzDguAFeUEUUoIWXiJrPqU7vGiVkA==",
552
             "cpu": [
552
             "cpu": [
553
                 "x64"
553
                 "x64"
554
             ],
554
             ],
559
             ]
559
             ]
560
         },
560
         },
561
         "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
561
         "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
562
-            "version": "4.14.1",
563
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.14.1.tgz",
564
-            "integrity": "sha512-mS6wQ6Do6/wmrF9aTFVpIJ3/IDXhg1EZcQFYHZLHqw6AzMBjTHWnCG35HxSqUNphh0EHqSM6wRTT8HsL1C0x5g==",
562
+            "version": "4.14.2",
563
+            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.14.2.tgz",
564
+            "integrity": "sha512-nwlJ65UY9eGq91cBi6VyDfArUJSKOYt5dJQBq8xyLhvS23qO+4Nr/RreibFHjP6t+5ap2ohZrUJcHv5zk5ju/g==",
565
             "cpu": [
565
             "cpu": [
566
                 "arm"
566
                 "arm"
567
             ],
567
             ],
572
             ]
572
             ]
573
         },
573
         },
574
         "node_modules/@rollup/rollup-linux-arm64-gnu": {
574
         "node_modules/@rollup/rollup-linux-arm64-gnu": {
575
-            "version": "4.14.1",
576
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.14.1.tgz",
577
-            "integrity": "sha512-p9rGKYkHdFMzhckOTFubfxgyIO1vw//7IIjBBRVzyZebWlzRLeNhqxuSaZ7kCEKVkm/kuC9fVRW9HkC/zNRG2w==",
575
+            "version": "4.14.2",
576
+            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.14.2.tgz",
577
+            "integrity": "sha512-Pg5TxxO2IVlMj79+c/9G0LREC9SY3HM+pfAwX7zj5/cAuwrbfj2Wv9JbMHIdPCfQpYsI4g9mE+2Bw/3aeSs2rQ==",
578
             "cpu": [
578
             "cpu": [
579
                 "arm64"
579
                 "arm64"
580
             ],
580
             ],
585
             ]
585
             ]
586
         },
586
         },
587
         "node_modules/@rollup/rollup-linux-arm64-musl": {
587
         "node_modules/@rollup/rollup-linux-arm64-musl": {
588
-            "version": "4.14.1",
589
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.14.1.tgz",
590
-            "integrity": "sha512-nDY6Yz5xS/Y4M2i9JLQd3Rofh5OR8Bn8qe3Mv/qCVpHFlwtZSBYSPaU4mrGazWkXrdQ98GB//H0BirGR/SKFSw==",
588
+            "version": "4.14.2",
589
+            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.14.2.tgz",
590
+            "integrity": "sha512-cAOTjGNm84gc6tS02D1EXtG7tDRsVSDTBVXOLbj31DkwfZwgTPYZ6aafSU7rD/4R2a34JOwlF9fQayuTSkoclA==",
591
             "cpu": [
591
             "cpu": [
592
                 "arm64"
592
                 "arm64"
593
             ],
593
             ],
598
             ]
598
             ]
599
         },
599
         },
600
         "node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
600
         "node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
601
-            "version": "4.14.1",
602
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.14.1.tgz",
603
-            "integrity": "sha512-im7HE4VBL+aDswvcmfx88Mp1soqL9OBsdDBU8NqDEYtkri0qV0THhQsvZtZeNNlLeCUQ16PZyv7cqutjDF35qw==",
601
+            "version": "4.14.2",
602
+            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.14.2.tgz",
603
+            "integrity": "sha512-4RyT6v1kXb7C0fn6zV33rvaX05P0zHoNzaXI/5oFHklfKm602j+N4mn2YvoezQViRLPnxP8M1NaY4s/5kXO5cw==",
604
             "cpu": [
604
             "cpu": [
605
-                "ppc64le"
605
+                "ppc64"
606
             ],
606
             ],
607
             "dev": true,
607
             "dev": true,
608
             "optional": true,
608
             "optional": true,
611
             ]
611
             ]
612
         },
612
         },
613
         "node_modules/@rollup/rollup-linux-riscv64-gnu": {
613
         "node_modules/@rollup/rollup-linux-riscv64-gnu": {
614
-            "version": "4.14.1",
615
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.14.1.tgz",
616
-            "integrity": "sha512-RWdiHuAxWmzPJgaHJdpvUUlDz8sdQz4P2uv367T2JocdDa98iRw2UjIJ4QxSyt077mXZT2X6pKfT2iYtVEvOFw==",
614
+            "version": "4.14.2",
615
+            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.14.2.tgz",
616
+            "integrity": "sha512-KNUH6jC/vRGAKSorySTyc/yRYlCwN/5pnMjXylfBniwtJx5O7X17KG/0efj8XM3TZU7raYRXJFFReOzNmL1n1w==",
617
             "cpu": [
617
             "cpu": [
618
                 "riscv64"
618
                 "riscv64"
619
             ],
619
             ],
624
             ]
624
             ]
625
         },
625
         },
626
         "node_modules/@rollup/rollup-linux-s390x-gnu": {
626
         "node_modules/@rollup/rollup-linux-s390x-gnu": {
627
-            "version": "4.14.1",
628
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.14.1.tgz",
629
-            "integrity": "sha512-VMgaGQ5zRX6ZqV/fas65/sUGc9cPmsntq2FiGmayW9KMNfWVG/j0BAqImvU4KTeOOgYSf1F+k6at1UfNONuNjA==",
627
+            "version": "4.14.2",
628
+            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.14.2.tgz",
629
+            "integrity": "sha512-xPV4y73IBEXToNPa3h5lbgXOi/v0NcvKxU0xejiFw6DtIYQqOTMhZ2DN18/HrrP0PmiL3rGtRG9gz1QE8vFKXQ==",
630
             "cpu": [
630
             "cpu": [
631
                 "s390x"
631
                 "s390x"
632
             ],
632
             ],
637
             ]
637
             ]
638
         },
638
         },
639
         "node_modules/@rollup/rollup-linux-x64-gnu": {
639
         "node_modules/@rollup/rollup-linux-x64-gnu": {
640
-            "version": "4.14.1",
641
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.14.1.tgz",
642
-            "integrity": "sha512-9Q7DGjZN+hTdJomaQ3Iub4m6VPu1r94bmK2z3UeWP3dGUecRC54tmVu9vKHTm1bOt3ASoYtEz6JSRLFzrysKlA==",
640
+            "version": "4.14.2",
641
+            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.14.2.tgz",
642
+            "integrity": "sha512-QBhtr07iFGmF9egrPOWyO5wciwgtzKkYPNLVCFZTmr4TWmY0oY2Dm/bmhHjKRwZoGiaKdNcKhFtUMBKvlchH+Q==",
643
             "cpu": [
643
             "cpu": [
644
                 "x64"
644
                 "x64"
645
             ],
645
             ],
650
             ]
650
             ]
651
         },
651
         },
652
         "node_modules/@rollup/rollup-linux-x64-musl": {
652
         "node_modules/@rollup/rollup-linux-x64-musl": {
653
-            "version": "4.14.1",
654
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.14.1.tgz",
655
-            "integrity": "sha512-JNEG/Ti55413SsreTguSx0LOVKX902OfXIKVg+TCXO6Gjans/k9O6ww9q3oLGjNDaTLxM+IHFMeXy/0RXL5R/g==",
653
+            "version": "4.14.2",
654
+            "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.14.2.tgz",
655
+            "integrity": "sha512-8zfsQRQGH23O6qazZSFY5jP5gt4cFvRuKTpuBsC1ZnSWxV8ZKQpPqOZIUtdfMOugCcBvFGRa1pDC/tkf19EgBw==",
656
             "cpu": [
656
             "cpu": [
657
                 "x64"
657
                 "x64"
658
             ],
658
             ],
663
             ]
663
             ]
664
         },
664
         },
665
         "node_modules/@rollup/rollup-win32-arm64-msvc": {
665
         "node_modules/@rollup/rollup-win32-arm64-msvc": {
666
-            "version": "4.14.1",
667
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.14.1.tgz",
668
-            "integrity": "sha512-ryS22I9y0mumlLNwDFYZRDFLwWh3aKaC72CWjFcFvxK0U6v/mOkM5Up1bTbCRAhv3kEIwW2ajROegCIQViUCeA==",
666
+            "version": "4.14.2",
667
+            "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.14.2.tgz",
668
+            "integrity": "sha512-H4s8UjgkPnlChl6JF5empNvFHp77Jx+Wfy2EtmYPe9G22XV+PMuCinZVHurNe8ggtwoaohxARJZbaH/3xjB/FA==",
669
             "cpu": [
669
             "cpu": [
670
                 "arm64"
670
                 "arm64"
671
             ],
671
             ],
676
             ]
676
             ]
677
         },
677
         },
678
         "node_modules/@rollup/rollup-win32-ia32-msvc": {
678
         "node_modules/@rollup/rollup-win32-ia32-msvc": {
679
-            "version": "4.14.1",
680
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.14.1.tgz",
681
-            "integrity": "sha512-TdloItiGk+T0mTxKx7Hp279xy30LspMso+GzQvV2maYePMAWdmrzqSNZhUpPj3CGw12aGj57I026PgLCTu8CGg==",
679
+            "version": "4.14.2",
680
+            "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.14.2.tgz",
681
+            "integrity": "sha512-djqpAjm/i8erWYF0K6UY4kRO3X5+T4TypIqw60Q8MTqSBaQNpNXDhxdjpZ3ikgb+wn99svA7jxcXpiyg9MUsdw==",
682
             "cpu": [
682
             "cpu": [
683
                 "ia32"
683
                 "ia32"
684
             ],
684
             ],
689
             ]
689
             ]
690
         },
690
         },
691
         "node_modules/@rollup/rollup-win32-x64-msvc": {
691
         "node_modules/@rollup/rollup-win32-x64-msvc": {
692
-            "version": "4.14.1",
693
-            "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.14.1.tgz",
694
-            "integrity": "sha512-wQGI+LY/Py20zdUPq+XCem7JcPOyzIJBm3dli+56DJsQOHbnXZFEwgmnC6el1TPAfC8lBT3m+z69RmLykNUbew==",
692
+            "version": "4.14.2",
693
+            "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.14.2.tgz",
694
+            "integrity": "sha512-teAqzLT0yTYZa8ZP7zhFKEx4cotS8Tkk5XiqNMJhD4CpaWB1BHARE4Qy+RzwnXvSAYv+Q3jAqCVBS+PS+Yee8Q==",
695
             "cpu": [
695
             "cpu": [
696
                 "x64"
696
                 "x64"
697
             ],
697
             ],
918
             }
918
             }
919
         },
919
         },
920
         "node_modules/caniuse-lite": {
920
         "node_modules/caniuse-lite": {
921
-            "version": "1.0.30001608",
922
-            "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001608.tgz",
923
-            "integrity": "sha512-cjUJTQkk9fQlJR2s4HMuPMvTiRggl0rAVMtthQuyOlDWuqHXqN8azLq+pi8B2TjwKJ32diHjUqRIKeFX4z1FoA==",
921
+            "version": "1.0.30001609",
922
+            "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001609.tgz",
923
+            "integrity": "sha512-JFPQs34lHKx1B5t1EpQpWH4c+29zIyn/haGsbpfq3suuV9v56enjFt23zqijxGTMwy1p/4H2tjnQMY+p1WoAyA==",
924
             "dev": true,
924
             "dev": true,
925
             "funding": [
925
             "funding": [
926
                 {
926
                 {
1066
             "dev": true
1066
             "dev": true
1067
         },
1067
         },
1068
         "node_modules/electron-to-chromium": {
1068
         "node_modules/electron-to-chromium": {
1069
-            "version": "1.4.733",
1070
-            "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.733.tgz",
1071
-            "integrity": "sha512-gUI9nhI2iBGF0OaYYLKOaOtliFMl+Bt1rY7VmEjwxOxqoYLub/D9xmduPEhbw2imE6gYkJKhIE5it+KE2ulVxQ==",
1069
+            "version": "1.4.736",
1070
+            "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.736.tgz",
1071
+            "integrity": "sha512-Rer6wc3ynLelKNM4lOCg7/zPQj8tPOCB2hzD32PX9wd3hgRRi9MxEbmkFCokzcEhRVMiOVLjnL9ig9cefJ+6+Q==",
1072
             "dev": true
1072
             "dev": true
1073
         },
1073
         },
1074
         "node_modules/emoji-regex": {
1074
         "node_modules/emoji-regex": {
1997
             }
1997
             }
1998
         },
1998
         },
1999
         "node_modules/rollup": {
1999
         "node_modules/rollup": {
2000
-            "version": "4.14.1",
2001
-            "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.14.1.tgz",
2002
-            "integrity": "sha512-4LnHSdd3QK2pa1J6dFbfm1HN0D7vSK/ZuZTsdyUAlA6Rr1yTouUTL13HaDOGJVgby461AhrNGBS7sCGXXtT+SA==",
2000
+            "version": "4.14.2",
2001
+            "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.14.2.tgz",
2002
+            "integrity": "sha512-WkeoTWvuBoFjFAhsEOHKRoZ3r9GfTyhh7Vff1zwebEFLEFjT1lG3784xEgKiTa7E+e70vsC81roVL2MP4tgEEQ==",
2003
             "dev": true,
2003
             "dev": true,
2004
             "dependencies": {
2004
             "dependencies": {
2005
                 "@types/estree": "1.0.5"
2005
                 "@types/estree": "1.0.5"
2012
                 "npm": ">=8.0.0"
2012
                 "npm": ">=8.0.0"
2013
             },
2013
             },
2014
             "optionalDependencies": {
2014
             "optionalDependencies": {
2015
-                "@rollup/rollup-android-arm-eabi": "4.14.1",
2016
-                "@rollup/rollup-android-arm64": "4.14.1",
2017
-                "@rollup/rollup-darwin-arm64": "4.14.1",
2018
-                "@rollup/rollup-darwin-x64": "4.14.1",
2019
-                "@rollup/rollup-linux-arm-gnueabihf": "4.14.1",
2020
-                "@rollup/rollup-linux-arm64-gnu": "4.14.1",
2021
-                "@rollup/rollup-linux-arm64-musl": "4.14.1",
2022
-                "@rollup/rollup-linux-powerpc64le-gnu": "4.14.1",
2023
-                "@rollup/rollup-linux-riscv64-gnu": "4.14.1",
2024
-                "@rollup/rollup-linux-s390x-gnu": "4.14.1",
2025
-                "@rollup/rollup-linux-x64-gnu": "4.14.1",
2026
-                "@rollup/rollup-linux-x64-musl": "4.14.1",
2027
-                "@rollup/rollup-win32-arm64-msvc": "4.14.1",
2028
-                "@rollup/rollup-win32-ia32-msvc": "4.14.1",
2029
-                "@rollup/rollup-win32-x64-msvc": "4.14.1",
2015
+                "@rollup/rollup-android-arm-eabi": "4.14.2",
2016
+                "@rollup/rollup-android-arm64": "4.14.2",
2017
+                "@rollup/rollup-darwin-arm64": "4.14.2",
2018
+                "@rollup/rollup-darwin-x64": "4.14.2",
2019
+                "@rollup/rollup-linux-arm-gnueabihf": "4.14.2",
2020
+                "@rollup/rollup-linux-arm64-gnu": "4.14.2",
2021
+                "@rollup/rollup-linux-arm64-musl": "4.14.2",
2022
+                "@rollup/rollup-linux-powerpc64le-gnu": "4.14.2",
2023
+                "@rollup/rollup-linux-riscv64-gnu": "4.14.2",
2024
+                "@rollup/rollup-linux-s390x-gnu": "4.14.2",
2025
+                "@rollup/rollup-linux-x64-gnu": "4.14.2",
2026
+                "@rollup/rollup-linux-x64-musl": "4.14.2",
2027
+                "@rollup/rollup-win32-arm64-msvc": "4.14.2",
2028
+                "@rollup/rollup-win32-ia32-msvc": "4.14.2",
2029
+                "@rollup/rollup-win32-x64-msvc": "4.14.2",
2030
                 "fsevents": "~2.3.2"
2030
                 "fsevents": "~2.3.2"
2031
             }
2031
             }
2032
         },
2032
         },

+ 2
- 2
resources/views/livewire/company/service/connected-account/list-institutions.blade.php Прегледај датотеку

19
                             {{ $institution->name }}
19
                             {{ $institution->name }}
20
                         </h3>
20
                         </h3>
21
 
21
 
22
-                        @if($institution->getLastTransactionDate())
22
+                        @if($institution->getLastImportDate())
23
                             <p class="connected-account-section-header-description text-sm leading-6 text-gray-500 dark:text-gray-400">
23
                             <p class="connected-account-section-header-description text-sm leading-6 text-gray-500 dark:text-gray-400">
24
-                                {{ __('Last updated') }} {{ $institution->getLastTransactionDate() }}
24
+                                {{ __('Last updated') }} {{ $institution->getLastImportDate() }}
25
                             </p>
25
                             </p>
26
                         @endif
26
                         @endif
27
                     </div>
27
                     </div>

+ 3
- 0
routes/api.php Прегледај датотеку

1
 <?php
1
 <?php
2
 
2
 
3
+use App\Http\Controllers\PlaidWebhookController;
3
 use Illuminate\Http\Request;
4
 use Illuminate\Http\Request;
4
 use Illuminate\Support\Facades\Route;
5
 use Illuminate\Support\Facades\Route;
5
 
6
 
6
 Route::get('/user', function (Request $request) {
7
 Route::get('/user', function (Request $request) {
7
     return $request->user();
8
     return $request->user();
8
 })->middleware('auth:sanctum');
9
 })->middleware('auth:sanctum');
10
+
11
+Route::post('/plaid/webhook', [PlaidWebhookController::class, 'handleWebhook']);

Loading…
Откажи
Сачувај