Compare commits
32 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| cba9fe1e7b | |||
| baa49e77eb | |||
| b015462e50 | |||
| c9f1fc1bea | |||
| 1177886271 | |||
| 0e1c56dd18 | |||
| eefe237dff | |||
| 8d4e004177 | |||
| 1c63e2b856 | |||
| 3040cbf49a | |||
| 1a124a2571 | |||
| 26c8c3f3b9 | |||
| 50d814ebf6 | |||
| 7fc20876dd | |||
| 183108400e | |||
| 3055d34979 | |||
| 747f5f5f42 | |||
| 4db9409b94 | |||
| 8693bb29ca | |||
| 524d8ca41d | |||
| 3c77eca689 | |||
| 307f74b1d9 | |||
| 0c29393f3b | |||
| af3726cb91 | |||
| 0d40fd92f0 | |||
| 0f55d84355 | |||
| eafa889827 | |||
| 60cd880c2e | |||
| ea8de69863 | |||
| 11ef26e878 | |||
| 2770ebf958 | |||
| 536ca56c24 |
+1
-1
@@ -1,7 +1,7 @@
|
||||
APP_NAME=Investbrain
|
||||
APP_ENV=production
|
||||
APP_KEY=
|
||||
APP_DEBUG=false
|
||||
APP_DEBUG=true
|
||||
APP_TIMEZONE=UTC
|
||||
APP_PORT=8000
|
||||
APP_URL="http://localhost:${APP_PORT}"
|
||||
|
||||
@@ -6,6 +6,18 @@ Investbrain is a smart open-source investment tracker that helps you manage, tra
|
||||
|
||||
<p align="center"><a href="https://investbra.in" target="_blank"><img src="https://raw.githubusercontent.com/investbrainapp/investbrain/main/screenshot.png" width="100%" alt="Investbrain Screenshot"></a></p>
|
||||
|
||||
## Table of contents
|
||||
- [Under the hood](#under-the-hood)
|
||||
- [Install (self hosting)](#self-hosting)
|
||||
- [Chat with your holdings](#chat-with-your-holdings)
|
||||
- [Market data providers](#market-data-providers)
|
||||
- [Import / Export](#import--export)
|
||||
- [Configuration](#configuration)
|
||||
- [Updating](#updating)
|
||||
- [Command line utilities](#command-line-utilities)
|
||||
- [Troubleshooting](#troubleshooting)
|
||||
- [Testing](#testing)
|
||||
|
||||
## Under the hood
|
||||
|
||||
Investbrain is a Laravel PHP web application that leverages Livewire and Tailwind for its frontend. Most databases should work, including MySQL and SQLite. Out of the box, we feature three market data providers: [Yahoo Finance](https://finance.yahoo.com/), [Finnhub](https://finnhub.io/pricing-stock-api-market-data), and [Alpha Vantage](https://www.alphavantage.co/support/). But we also offer an extensible market data provider interface for intrepid developers to create their own! We also offer an integration with OpenAI's LLMs for our ["chat with your holdings"](#chat-with-your-holdings) capability. Finally, of course we have robust support for i18n, a11y, and dark mode.
|
||||
@@ -44,7 +56,7 @@ Congrats! You've just installed Investbrain!
|
||||
|
||||
Investbrain offers an AI powered chat assistant that is grounded on *your* investments. This enables you to use AI as a thought partner when making investment decisions.
|
||||
|
||||
When self-hosting, you can enable the chat assstant by configuring your OpenAI Secret Key and Organization ID in your [.env](https://github.com/investbrainapp/investbrain/blob/main/.env.example) file. Navigate to OpenAI to [create your keys](https://platform.openai.com/api-keys).
|
||||
When self-hosting, you can enable the chat assistant by configuring your OpenAI Secret Key and Organization ID in your [.env](https://github.com/investbrainapp/investbrain/blob/main/.env.example) file. Navigate to OpenAI to [create your keys](https://platform.openai.com/api-keys).
|
||||
|
||||
Always keep in mind the limitations of large language models. When in doubt, consult a licensed investment advisor.
|
||||
|
||||
@@ -93,6 +105,18 @@ MARKET_DATA_PROVIDER=yahoo,alphavantage,custom_provider
|
||||
|
||||
Feel free to submit a PR with any custom providers you create.
|
||||
|
||||
## Import / Export
|
||||
|
||||
Investbrain includes a convenient feature which allows you to import and export portfolios and transaction data.
|
||||
|
||||
### Import
|
||||
|
||||
Imports are "upserted" to the database. If the record does not already exist in the database, the record will be created. However, when a portfolio or transaction exists (the record's ID matches an existing record), the record will be updated. This way, you can simultaneously create new records, but also bulk update records.
|
||||
|
||||
### Export
|
||||
|
||||
Exporting your portfolios and transactions is a convenient way to back-up your Investbrain data. It is also a convenient way to maintain portability of *your* data.
|
||||
|
||||
## Configuration
|
||||
|
||||
There are several optional configurations available when installing using the recommended [Docker method](#self-hosting). These options are configurable using an environment file. Changes can be made in your [.env](https://github.com/investbrainapp/investbrain/blob/main/.env.example) file before installation.
|
||||
@@ -159,6 +183,31 @@ Just to be safe, we recommend backing up your portfolios before using these comm
|
||||
| sync:daily-change | Re-calculates daily snapshots of your portfolio's daily performance. Useful to fill in gaps in your portfolio charts. (Note: this is an extremely resource intensive query.) |
|
||||
| sync:holdings | Re-calculates performance of holdings with related transactions (i.e. dividends, realized gains, etc). |
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
If you are facing issues with Investbrain, it can be handy to monitor the application's logs:
|
||||
|
||||
```bash
|
||||
docker exec -it investbrain-app cat storage/logs/laravel.log
|
||||
```
|
||||
or you can live monitor logs using `tail`:
|
||||
|
||||
```bash
|
||||
docker exec -it investbrain-app tail -f storage/logs/laravel.log
|
||||
```
|
||||
|
||||
### Common issues
|
||||
|
||||
<details>
|
||||
|
||||
**<summary>Market data not refreshing on fresh install</summary>**
|
||||
|
||||
If you're unable to refresh market data out of the box (i.e. your market data provider is set to Yahoo), there is a chance Yahoo is being blocked by a firewall or adblocker. Pihole is known to block `fc.yahoo.com` which is the domain used to query Yahoo.
|
||||
|
||||
Once you whitelist `fc.yahoo.com` in pihole, your market data should begin populating!
|
||||
|
||||
</details>
|
||||
|
||||
## Testing
|
||||
|
||||
Investbrain has a robus PHPUnit test suite that creates an in-memory SQLite database and runs any queued jobs synchronously using Laravel's array driver. You can run the entire Investbrain test suite from within the Docker container by running:
|
||||
@@ -185,7 +234,7 @@ We ask that you be kind and polite when interacting with the Investbrain communi
|
||||
|
||||
## Security Vulnerabilities
|
||||
|
||||
If you discover a security vulnerability within Investbrain, please create an issue in the [Github repository](https://github.com/investbrainapp/investbrain). All security vulnerabilities will be promptly addressed.
|
||||
If you discover a security vulnerability within Investbrain, please submit your report via [Github](https://github.com/investbrainapp/investbrain/security/advisories/new). All security vulnerabilities will be promptly addressed. We ask that you keep any suspected vulnerabilities private and confidential until they have been appropriately addressed.
|
||||
|
||||
## License
|
||||
|
||||
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
# Security Policy
|
||||
|
||||
## Supported Versions
|
||||
|
||||
| Version | Supported |
|
||||
| ------- | ------------------ |
|
||||
| 1.0.x | :white_check_mark: |
|
||||
| < 1.0.0 | :x: |
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
If you discover a security vulnerability within Investbrain, please submit your report via [Github](https://github.com/investbrainapp/investbrain/security/advisories/new). All security vulnerabilities will be promptly addressed. We ask that you keep any suspected vulnerabilities private and confidential until they have been appropriately addressed.
|
||||
+11
-9
@@ -27,7 +27,7 @@ class Dividend extends Model
|
||||
|
||||
protected $casts = [
|
||||
'date' => 'datetime',
|
||||
'last_date' => 'datetime',
|
||||
'last_dividend_update' => 'datetime',
|
||||
];
|
||||
|
||||
public function marketData() {
|
||||
@@ -50,25 +50,29 @@ class Dividend extends Model
|
||||
/**
|
||||
* Grab new dividend data
|
||||
*
|
||||
* @param string $symbol
|
||||
* @return void
|
||||
*/
|
||||
public static function refreshDividendData(string $symbol)
|
||||
public static function refreshDividendData(string $symbol): void
|
||||
{
|
||||
$dividends_meta = self::where(['symbol' => $symbol])
|
||||
->selectRaw('COUNT(symbol) as total_dividends')
|
||||
->selectRaw('MAX(date) as last_date')
|
||||
->selectRaw('MAX(created_at) as last_dividend_update')
|
||||
->get()
|
||||
->first();
|
||||
|
||||
// assume we need to populate ALL dividend data
|
||||
$start_date = new \DateTime('@0');
|
||||
$start_date = new Carbon('@0');
|
||||
$end_date = now();
|
||||
|
||||
// nope, refresh forward looking only
|
||||
if ( $dividends_meta->total_dividends ) {
|
||||
|
||||
$start_date = $dividends_meta->last_dividend_update->addHours(24);
|
||||
}
|
||||
|
||||
// skip refresh if there's already recent data
|
||||
if ($start_date->greaterThan($end_date)) {
|
||||
|
||||
$start_date = $dividends_meta->last_date->addHours(48);
|
||||
return;
|
||||
}
|
||||
|
||||
// get some data
|
||||
@@ -99,8 +103,6 @@ class Dividend extends Model
|
||||
$market_data->last_dividend_amount = $dividend_data->sortByDesc('date')->first()['dividend_amount'];
|
||||
$market_data->save();
|
||||
}
|
||||
|
||||
return $dividend_data;
|
||||
}
|
||||
|
||||
public static function syncHoldings(string $symbol): void
|
||||
|
||||
@@ -125,7 +125,7 @@ class Transaction extends Model
|
||||
|
||||
public function scopeBeforeDate($query, $date)
|
||||
{
|
||||
return $query->whereDate('date', '<', $date);
|
||||
return $query->whereDate('date', '<=', $date);
|
||||
}
|
||||
|
||||
public function scopeMyTransactions()
|
||||
|
||||
@@ -2,7 +2,10 @@
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use Illuminate\Support\Arr;
|
||||
use Laravel\Jetstream\Features;
|
||||
use App\Actions\Jetstream\DeleteUser;
|
||||
use Illuminate\Support\Facades\Config;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use Laravel\Jetstream\Jetstream;
|
||||
|
||||
@@ -26,6 +29,13 @@ class JetstreamServiceProvider extends ServiceProvider
|
||||
|
||||
Jetstream::deleteUsersUsing(DeleteUser::class);
|
||||
|
||||
if ( config('investbrain.self_hosted', false) ) {
|
||||
|
||||
Config::set(
|
||||
'jetstream.features',
|
||||
array_keys(Arr::except(array_values(config('jetstream.features')), Features::termsAndPrivacyPolicy()))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -50,7 +50,7 @@ class QuantityValidationRule implements ValidationRule
|
||||
|
||||
$maxQuantity = $purchase_qty - $sales_qty;
|
||||
|
||||
if ($value > $maxQuantity) {
|
||||
if (round($value, 3) > round($maxQuantity, 3)) {
|
||||
$fail(__('The quantity must not be greater than the available quantity.'));
|
||||
}
|
||||
}
|
||||
|
||||
Generated
+100
-99
@@ -62,16 +62,16 @@
|
||||
},
|
||||
{
|
||||
"name": "aws/aws-sdk-php",
|
||||
"version": "3.325.3",
|
||||
"version": "3.325.7",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/aws/aws-sdk-php.git",
|
||||
"reference": "de0b289c7260fb19301ffa2eb724de2076daad74"
|
||||
"reference": "55852104253172e66c3358bf4c35281bbd8622b2"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/de0b289c7260fb19301ffa2eb724de2076daad74",
|
||||
"reference": "de0b289c7260fb19301ffa2eb724de2076daad74",
|
||||
"url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/55852104253172e66c3358bf4c35281bbd8622b2",
|
||||
"reference": "55852104253172e66c3358bf4c35281bbd8622b2",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -154,9 +154,9 @@
|
||||
"support": {
|
||||
"forum": "https://forums.aws.amazon.com/forum.jspa?forumID=80",
|
||||
"issues": "https://github.com/aws/aws-sdk-php/issues",
|
||||
"source": "https://github.com/aws/aws-sdk-php/tree/3.325.3"
|
||||
"source": "https://github.com/aws/aws-sdk-php/tree/3.325.7"
|
||||
},
|
||||
"time": "2024-11-06T19:05:22+00:00"
|
||||
"time": "2024-11-12T19:27:31+00:00"
|
||||
},
|
||||
{
|
||||
"name": "bacon/bacon-qr-code",
|
||||
@@ -1966,16 +1966,16 @@
|
||||
},
|
||||
{
|
||||
"name": "laravel/fortify",
|
||||
"version": "v1.24.4",
|
||||
"version": "v1.24.5",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/laravel/fortify.git",
|
||||
"reference": "5bd3bdd535acf4054865c64eec6d8bb8c60cc127"
|
||||
"reference": "bba8c2ecc3fcc78e8632e0d719ae10bef6343eef"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/laravel/fortify/zipball/5bd3bdd535acf4054865c64eec6d8bb8c60cc127",
|
||||
"reference": "5bd3bdd535acf4054865c64eec6d8bb8c60cc127",
|
||||
"url": "https://api.github.com/repos/laravel/fortify/zipball/bba8c2ecc3fcc78e8632e0d719ae10bef6343eef",
|
||||
"reference": "bba8c2ecc3fcc78e8632e0d719ae10bef6343eef",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -2027,20 +2027,20 @@
|
||||
"issues": "https://github.com/laravel/fortify/issues",
|
||||
"source": "https://github.com/laravel/fortify"
|
||||
},
|
||||
"time": "2024-10-29T13:59:23+00:00"
|
||||
"time": "2024-11-12T14:51:12+00:00"
|
||||
},
|
||||
{
|
||||
"name": "laravel/framework",
|
||||
"version": "v11.30.0",
|
||||
"version": "v11.31.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/laravel/framework.git",
|
||||
"reference": "dff716442d9c229d716be82ccc9a7de52eb97193"
|
||||
"reference": "365090ed2c68244e3141cdb5e247cdf3dfba2c40"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/laravel/framework/zipball/dff716442d9c229d716be82ccc9a7de52eb97193",
|
||||
"reference": "dff716442d9c229d716be82ccc9a7de52eb97193",
|
||||
"url": "https://api.github.com/repos/laravel/framework/zipball/365090ed2c68244e3141cdb5e247cdf3dfba2c40",
|
||||
"reference": "365090ed2c68244e3141cdb5e247cdf3dfba2c40",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -2236,20 +2236,20 @@
|
||||
"issues": "https://github.com/laravel/framework/issues",
|
||||
"source": "https://github.com/laravel/framework"
|
||||
},
|
||||
"time": "2024-10-30T15:00:34+00:00"
|
||||
"time": "2024-11-12T15:36:15+00:00"
|
||||
},
|
||||
{
|
||||
"name": "laravel/jetstream",
|
||||
"version": "v5.3.1",
|
||||
"version": "v5.3.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/laravel/jetstream.git",
|
||||
"reference": "d51ec6942f34e76ba4736452d5f4d6f54a186a6e"
|
||||
"reference": "e5b9ef610bf13fb3b6053893f711227213833f35"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/laravel/jetstream/zipball/d51ec6942f34e76ba4736452d5f4d6f54a186a6e",
|
||||
"reference": "d51ec6942f34e76ba4736452d5f4d6f54a186a6e",
|
||||
"url": "https://api.github.com/repos/laravel/jetstream/zipball/e5b9ef610bf13fb3b6053893f711227213833f35",
|
||||
"reference": "e5b9ef610bf13fb3b6053893f711227213833f35",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -2303,20 +2303,20 @@
|
||||
"issues": "https://github.com/laravel/jetstream/issues",
|
||||
"source": "https://github.com/laravel/jetstream"
|
||||
},
|
||||
"time": "2024-10-30T13:32:43+00:00"
|
||||
"time": "2024-11-11T20:18:18+00:00"
|
||||
},
|
||||
{
|
||||
"name": "laravel/prompts",
|
||||
"version": "v0.3.1",
|
||||
"version": "v0.3.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/laravel/prompts.git",
|
||||
"reference": "0f3848a445562dac376b27968f753c65e7e1036e"
|
||||
"reference": "0e0535747c6b8d6d10adca8b68293cf4517abb0f"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/laravel/prompts/zipball/0f3848a445562dac376b27968f753c65e7e1036e",
|
||||
"reference": "0f3848a445562dac376b27968f753c65e7e1036e",
|
||||
"url": "https://api.github.com/repos/laravel/prompts/zipball/0e0535747c6b8d6d10adca8b68293cf4517abb0f",
|
||||
"reference": "0e0535747c6b8d6d10adca8b68293cf4517abb0f",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -2332,7 +2332,7 @@
|
||||
"require-dev": {
|
||||
"illuminate/collections": "^10.0|^11.0",
|
||||
"mockery/mockery": "^1.5",
|
||||
"pestphp/pest": "^2.3",
|
||||
"pestphp/pest": "^2.3|^3.4",
|
||||
"phpstan/phpstan": "^1.11",
|
||||
"phpstan/phpstan-mockery": "^1.1"
|
||||
},
|
||||
@@ -2360,9 +2360,9 @@
|
||||
"description": "Add beautiful and user-friendly forms to your command-line applications.",
|
||||
"support": {
|
||||
"issues": "https://github.com/laravel/prompts/issues",
|
||||
"source": "https://github.com/laravel/prompts/tree/v0.3.1"
|
||||
"source": "https://github.com/laravel/prompts/tree/v0.3.2"
|
||||
},
|
||||
"time": "2024-10-09T19:42:26+00:00"
|
||||
"time": "2024-11-12T14:59:47+00:00"
|
||||
},
|
||||
{
|
||||
"name": "laravel/sanctum",
|
||||
@@ -2430,16 +2430,16 @@
|
||||
},
|
||||
{
|
||||
"name": "laravel/serializable-closure",
|
||||
"version": "v1.3.5",
|
||||
"version": "v1.3.6",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/laravel/serializable-closure.git",
|
||||
"reference": "1dc4a3dbfa2b7628a3114e43e32120cce7cdda9c"
|
||||
"reference": "f865a58ea3a0107c336b7045104c75243fa59d96"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/laravel/serializable-closure/zipball/1dc4a3dbfa2b7628a3114e43e32120cce7cdda9c",
|
||||
"reference": "1dc4a3dbfa2b7628a3114e43e32120cce7cdda9c",
|
||||
"url": "https://api.github.com/repos/laravel/serializable-closure/zipball/f865a58ea3a0107c336b7045104c75243fa59d96",
|
||||
"reference": "f865a58ea3a0107c336b7045104c75243fa59d96",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -2487,7 +2487,7 @@
|
||||
"issues": "https://github.com/laravel/serializable-closure/issues",
|
||||
"source": "https://github.com/laravel/serializable-closure"
|
||||
},
|
||||
"time": "2024-09-23T13:33:08+00:00"
|
||||
"time": "2024-11-11T17:06:04+00:00"
|
||||
},
|
||||
{
|
||||
"name": "laravel/socialite",
|
||||
@@ -3212,16 +3212,16 @@
|
||||
},
|
||||
{
|
||||
"name": "livewire/volt",
|
||||
"version": "v1.6.5",
|
||||
"version": "v1.6.6",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/livewire/volt.git",
|
||||
"reference": "d09fdb4cb52c6ce821d255683195bb6d446fe141"
|
||||
"reference": "9efa7bd50a71ad166ac44ed9322d2c004e0ece5f"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/livewire/volt/zipball/d09fdb4cb52c6ce821d255683195bb6d446fe141",
|
||||
"reference": "d09fdb4cb52c6ce821d255683195bb6d446fe141",
|
||||
"url": "https://api.github.com/repos/livewire/volt/zipball/9efa7bd50a71ad166ac44ed9322d2c004e0ece5f",
|
||||
"reference": "9efa7bd50a71ad166ac44ed9322d2c004e0ece5f",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -3280,20 +3280,20 @@
|
||||
"issues": "https://github.com/livewire/volt/issues",
|
||||
"source": "https://github.com/livewire/volt"
|
||||
},
|
||||
"time": "2024-05-31T19:07:20+00:00"
|
||||
"time": "2024-11-12T14:51:01+00:00"
|
||||
},
|
||||
{
|
||||
"name": "maatwebsite/excel",
|
||||
"version": "3.1.58",
|
||||
"version": "3.1.60",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/SpartnerNL/Laravel-Excel.git",
|
||||
"reference": "18495a71b112f43af8ffab35111a58b4e4ba4a4d"
|
||||
"reference": "4906dc57fbe6a41c405a77e1f7cac9078982c9c7"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/SpartnerNL/Laravel-Excel/zipball/18495a71b112f43af8ffab35111a58b4e4ba4a4d",
|
||||
"reference": "18495a71b112f43af8ffab35111a58b4e4ba4a4d",
|
||||
"url": "https://api.github.com/repos/SpartnerNL/Laravel-Excel/zipball/4906dc57fbe6a41c405a77e1f7cac9078982c9c7",
|
||||
"reference": "4906dc57fbe6a41c405a77e1f7cac9078982c9c7",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -3301,7 +3301,7 @@
|
||||
"ext-json": "*",
|
||||
"illuminate/support": "5.8.*||^6.0||^7.0||^8.0||^9.0||^10.0||^11.0",
|
||||
"php": "^7.0||^8.0",
|
||||
"phpoffice/phpspreadsheet": "^1.29.1",
|
||||
"phpoffice/phpspreadsheet": "^1.29.4",
|
||||
"psr/simple-cache": "^1.0||^2.0||^3.0"
|
||||
},
|
||||
"require-dev": {
|
||||
@@ -3349,7 +3349,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/SpartnerNL/Laravel-Excel/issues",
|
||||
"source": "https://github.com/SpartnerNL/Laravel-Excel/tree/3.1.58"
|
||||
"source": "https://github.com/SpartnerNL/Laravel-Excel/tree/3.1.60"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -3361,7 +3361,7 @@
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2024-09-07T13:53:36+00:00"
|
||||
"time": "2024-11-11T12:27:45+00:00"
|
||||
},
|
||||
{
|
||||
"name": "maennchen/zipstream-php",
|
||||
@@ -3613,16 +3613,16 @@
|
||||
},
|
||||
{
|
||||
"name": "monolog/monolog",
|
||||
"version": "3.7.0",
|
||||
"version": "3.8.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Seldaek/monolog.git",
|
||||
"reference": "f4393b648b78a5408747de94fca38beb5f7e9ef8"
|
||||
"reference": "32e515fdc02cdafbe4593e30a9350d486b125b67"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/Seldaek/monolog/zipball/f4393b648b78a5408747de94fca38beb5f7e9ef8",
|
||||
"reference": "f4393b648b78a5408747de94fca38beb5f7e9ef8",
|
||||
"url": "https://api.github.com/repos/Seldaek/monolog/zipball/32e515fdc02cdafbe4593e30a9350d486b125b67",
|
||||
"reference": "32e515fdc02cdafbe4593e30a9350d486b125b67",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -3642,12 +3642,14 @@
|
||||
"guzzlehttp/psr7": "^2.2",
|
||||
"mongodb/mongodb": "^1.8",
|
||||
"php-amqplib/php-amqplib": "~2.4 || ^3",
|
||||
"phpstan/phpstan": "^1.9",
|
||||
"phpstan/phpstan-deprecation-rules": "^1.0",
|
||||
"phpstan/phpstan-strict-rules": "^1.4",
|
||||
"phpunit/phpunit": "^10.5.17",
|
||||
"php-console/php-console": "^3.1.8",
|
||||
"phpstan/phpstan": "^2",
|
||||
"phpstan/phpstan-deprecation-rules": "^2",
|
||||
"phpstan/phpstan-strict-rules": "^2",
|
||||
"phpunit/phpunit": "^10.5.17 || ^11.0.7",
|
||||
"predis/predis": "^1.1 || ^2",
|
||||
"ruflin/elastica": "^7",
|
||||
"rollbar/rollbar": "^4.0",
|
||||
"ruflin/elastica": "^7 || ^8",
|
||||
"symfony/mailer": "^5.4 || ^6",
|
||||
"symfony/mime": "^5.4 || ^6"
|
||||
},
|
||||
@@ -3698,7 +3700,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/Seldaek/monolog/issues",
|
||||
"source": "https://github.com/Seldaek/monolog/tree/3.7.0"
|
||||
"source": "https://github.com/Seldaek/monolog/tree/3.8.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -3710,7 +3712,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-06-28T09:40:51+00:00"
|
||||
"time": "2024-11-12T13:57:08+00:00"
|
||||
},
|
||||
{
|
||||
"name": "mtdowling/jmespath.php",
|
||||
@@ -3780,16 +3782,16 @@
|
||||
},
|
||||
{
|
||||
"name": "nesbot/carbon",
|
||||
"version": "3.8.1",
|
||||
"version": "3.8.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/briannesbitt/Carbon.git",
|
||||
"reference": "10ac0aa86b8062219ce21e8189123d611ca3ecd9"
|
||||
"reference": "e1268cdbc486d97ce23fef2c666dc3c6b6de9947"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/10ac0aa86b8062219ce21e8189123d611ca3ecd9",
|
||||
"reference": "10ac0aa86b8062219ce21e8189123d611ca3ecd9",
|
||||
"url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/e1268cdbc486d97ce23fef2c666dc3c6b6de9947",
|
||||
"reference": "e1268cdbc486d97ce23fef2c666dc3c6b6de9947",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -3882,7 +3884,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-11-03T16:02:24+00:00"
|
||||
"time": "2024-11-07T17:46:48+00:00"
|
||||
},
|
||||
{
|
||||
"name": "nette/schema",
|
||||
@@ -4179,16 +4181,16 @@
|
||||
},
|
||||
{
|
||||
"name": "openai-php/client",
|
||||
"version": "v0.10.2",
|
||||
"version": "v0.10.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/openai-php/client.git",
|
||||
"reference": "efa92628ba9fb56f7877c0d616f5221c4a447856"
|
||||
"reference": "4a565d145e0fb3ea1baba8fffe39d86c56b6dc2c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/openai-php/client/zipball/efa92628ba9fb56f7877c0d616f5221c4a447856",
|
||||
"reference": "efa92628ba9fb56f7877c0d616f5221c4a447856",
|
||||
"url": "https://api.github.com/repos/openai-php/client/zipball/4a565d145e0fb3ea1baba8fffe39d86c56b6dc2c",
|
||||
"reference": "4a565d145e0fb3ea1baba8fffe39d86c56b6dc2c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -4206,11 +4208,10 @@
|
||||
"laravel/pint": "^1.18.1",
|
||||
"mockery/mockery": "^1.6.12",
|
||||
"nunomaduro/collision": "^7.11.0|^8.5.0",
|
||||
"pestphp/pest": "^2.36.0|^3.4.1",
|
||||
"pestphp/pest": "^2.36.0|^3.5.0",
|
||||
"pestphp/pest-plugin-arch": "^2.7|^3.0",
|
||||
"pestphp/pest-plugin-type-coverage": "^2.8.7|^3.1.0",
|
||||
"phpstan/phpstan": "^1.12.6",
|
||||
"rector/rector": "^1.2.7",
|
||||
"phpstan/phpstan": "^1.12.7",
|
||||
"symfony/var-dumper": "^6.4.11|^7.1.5"
|
||||
},
|
||||
"type": "library",
|
||||
@@ -4251,7 +4252,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/openai-php/client/issues",
|
||||
"source": "https://github.com/openai-php/client/tree/v0.10.2"
|
||||
"source": "https://github.com/openai-php/client/tree/v0.10.3"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -4267,7 +4268,7 @@
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2024-10-17T20:28:25+00:00"
|
||||
"time": "2024-11-12T20:51:16+00:00"
|
||||
},
|
||||
{
|
||||
"name": "openai-php/laravel",
|
||||
@@ -4612,16 +4613,16 @@
|
||||
},
|
||||
{
|
||||
"name": "phpoffice/phpspreadsheet",
|
||||
"version": "1.29.2",
|
||||
"version": "1.29.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/PHPOffice/PhpSpreadsheet.git",
|
||||
"reference": "3a5a818d7d3e4b5bd2e56fb9de44dbded6eae07f"
|
||||
"reference": "7ca7e325dca3adb6a598385aab81f527b8d6c75d"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/PHPOffice/PhpSpreadsheet/zipball/3a5a818d7d3e4b5bd2e56fb9de44dbded6eae07f",
|
||||
"reference": "3a5a818d7d3e4b5bd2e56fb9de44dbded6eae07f",
|
||||
"url": "https://api.github.com/repos/PHPOffice/PhpSpreadsheet/zipball/7ca7e325dca3adb6a598385aab81f527b8d6c75d",
|
||||
"reference": "7ca7e325dca3adb6a598385aab81f527b8d6c75d",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -4711,9 +4712,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/PHPOffice/PhpSpreadsheet/issues",
|
||||
"source": "https://github.com/PHPOffice/PhpSpreadsheet/tree/1.29.2"
|
||||
"source": "https://github.com/PHPOffice/PhpSpreadsheet/tree/1.29.4"
|
||||
},
|
||||
"time": "2024-09-29T07:04:47+00:00"
|
||||
"time": "2024-11-10T16:26:22+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpoption/phpoption",
|
||||
@@ -5731,16 +5732,16 @@
|
||||
},
|
||||
{
|
||||
"name": "robsontenorio/mary",
|
||||
"version": "1.41.2",
|
||||
"version": "1.41.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/robsontenorio/mary.git",
|
||||
"reference": "ec5661a7cb4911ffb48dbf64c4455bdb52d0f196"
|
||||
"reference": "d88af3a6e52c39e84455927111449035f1ede92d"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/robsontenorio/mary/zipball/ec5661a7cb4911ffb48dbf64c4455bdb52d0f196",
|
||||
"reference": "ec5661a7cb4911ffb48dbf64c4455bdb52d0f196",
|
||||
"url": "https://api.github.com/repos/robsontenorio/mary/zipball/d88af3a6e52c39e84455927111449035f1ede92d",
|
||||
"reference": "d88af3a6e52c39e84455927111449035f1ede92d",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -5806,7 +5807,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/robsontenorio/mary/issues",
|
||||
"source": "https://github.com/robsontenorio/mary/tree/1.41.2"
|
||||
"source": "https://github.com/robsontenorio/mary/tree/1.41.4"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -5814,7 +5815,7 @@
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2024-10-30T18:25:35+00:00"
|
||||
"time": "2024-11-12T14:30:56+00:00"
|
||||
},
|
||||
{
|
||||
"name": "scheb/yahoo-finance-api",
|
||||
@@ -8617,16 +8618,16 @@
|
||||
"packages-dev": [
|
||||
{
|
||||
"name": "fakerphp/faker",
|
||||
"version": "v1.23.1",
|
||||
"version": "v1.24.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/FakerPHP/Faker.git",
|
||||
"reference": "bfb4fe148adbf78eff521199619b93a52ae3554b"
|
||||
"reference": "a136842a532bac9ecd8a1c723852b09915d7db50"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/FakerPHP/Faker/zipball/bfb4fe148adbf78eff521199619b93a52ae3554b",
|
||||
"reference": "bfb4fe148adbf78eff521199619b93a52ae3554b",
|
||||
"url": "https://api.github.com/repos/FakerPHP/Faker/zipball/a136842a532bac9ecd8a1c723852b09915d7db50",
|
||||
"reference": "a136842a532bac9ecd8a1c723852b09915d7db50",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -8674,9 +8675,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/FakerPHP/Faker/issues",
|
||||
"source": "https://github.com/FakerPHP/Faker/tree/v1.23.1"
|
||||
"source": "https://github.com/FakerPHP/Faker/tree/v1.24.0"
|
||||
},
|
||||
"time": "2024-01-02T13:46:09+00:00"
|
||||
"time": "2024-11-07T15:11:20+00:00"
|
||||
},
|
||||
{
|
||||
"name": "filp/whoops",
|
||||
@@ -8868,16 +8869,16 @@
|
||||
},
|
||||
{
|
||||
"name": "laravel/sail",
|
||||
"version": "v1.37.1",
|
||||
"version": "v1.38.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/laravel/sail.git",
|
||||
"reference": "7efa151ea0d16f48233d6a6cd69f81270acc6e93"
|
||||
"reference": "d17abae06661dd6c46d13627b1683a2924259145"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/laravel/sail/zipball/7efa151ea0d16f48233d6a6cd69f81270acc6e93",
|
||||
"reference": "7efa151ea0d16f48233d6a6cd69f81270acc6e93",
|
||||
"url": "https://api.github.com/repos/laravel/sail/zipball/d17abae06661dd6c46d13627b1683a2924259145",
|
||||
"reference": "d17abae06661dd6c46d13627b1683a2924259145",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -8927,7 +8928,7 @@
|
||||
"issues": "https://github.com/laravel/sail/issues",
|
||||
"source": "https://github.com/laravel/sail"
|
||||
},
|
||||
"time": "2024-10-29T20:18:14+00:00"
|
||||
"time": "2024-11-11T20:16:51+00:00"
|
||||
},
|
||||
{
|
||||
"name": "mockery/mockery",
|
||||
@@ -9014,16 +9015,16 @@
|
||||
},
|
||||
{
|
||||
"name": "myclabs/deep-copy",
|
||||
"version": "1.12.0",
|
||||
"version": "1.12.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/myclabs/DeepCopy.git",
|
||||
"reference": "3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c"
|
||||
"reference": "123267b2c49fbf30d78a7b2d333f6be754b94845"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c",
|
||||
"reference": "3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c",
|
||||
"url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/123267b2c49fbf30d78a7b2d333f6be754b94845",
|
||||
"reference": "123267b2c49fbf30d78a7b2d333f6be754b94845",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -9062,7 +9063,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/myclabs/DeepCopy/issues",
|
||||
"source": "https://github.com/myclabs/DeepCopy/tree/1.12.0"
|
||||
"source": "https://github.com/myclabs/DeepCopy/tree/1.12.1"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -9070,7 +9071,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-06-12T14:39:25+00:00"
|
||||
"time": "2024-11-08T17:47:46+00:00"
|
||||
},
|
||||
{
|
||||
"name": "nunomaduro/collision",
|
||||
|
||||
+1
-1
@@ -143,7 +143,7 @@ return [
|
||||
|
|
||||
*/
|
||||
|
||||
'inject_morph_markers' => true,
|
||||
'inject_morph_markers' => false,
|
||||
|
||||
/*
|
||||
|---------------------------------------------------------------------------
|
||||
|
||||
Generated
+25
-21
@@ -11,12 +11,12 @@
|
||||
"@tailwindcss/forms": "^0.5.7",
|
||||
"@tailwindcss/typography": "^0.5.10",
|
||||
"autoprefixer": "^10.4.19",
|
||||
"axios": "^1.6.4",
|
||||
"axios": "^1.7.4",
|
||||
"daisyui": "^4.12.10",
|
||||
"laravel-vite-plugin": "^1.0",
|
||||
"postcss": "^8.4.40",
|
||||
"tailwindcss": "^3.4.7",
|
||||
"vite": "^5.0"
|
||||
"vite": "^5.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@alloc/quick-lru": {
|
||||
@@ -862,9 +862,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/axios": {
|
||||
"version": "1.7.3",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.7.3.tgz",
|
||||
"integrity": "sha512-Ar7ND9pU99eJ9GpoGQKhKf58GpUOgnzuaB7ueNQ5BMi0p+LZ5oaEnfF999fAArcTIBwXTCHAmGcHOZJaWPq9Nw==",
|
||||
"version": "1.7.4",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.7.4.tgz",
|
||||
"integrity": "sha512-DukmaFRnY6AzAALSH4J2M3k6PkaC+MfaAGdEERRWcC9q3/TWQwLpHR8ZRLKTdQ3aBDL64EdluRDjJqKw+BPZEw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"follow-redirects": "^1.15.6",
|
||||
@@ -1721,9 +1721,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/picocolors": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz",
|
||||
"integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==",
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
|
||||
"integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/picomatch": {
|
||||
@@ -1757,9 +1757,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/postcss": {
|
||||
"version": "8.4.40",
|
||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.40.tgz",
|
||||
"integrity": "sha512-YF2kKIUzAofPMpfH6hOi2cGnv/HrUlfucspc7pDyvv7kGdqXrfj8SCl/t8owkEgKEuu8ZcRjSOxFxVLqwChZ2Q==",
|
||||
"version": "8.4.47",
|
||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.47.tgz",
|
||||
"integrity": "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
@@ -1777,8 +1777,8 @@
|
||||
],
|
||||
"dependencies": {
|
||||
"nanoid": "^3.3.7",
|
||||
"picocolors": "^1.0.1",
|
||||
"source-map-js": "^1.2.0"
|
||||
"picocolors": "^1.1.0",
|
||||
"source-map-js": "^1.2.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^10 || ^12 || >=14"
|
||||
@@ -2090,9 +2090,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/source-map-js": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz",
|
||||
"integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==",
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
|
||||
"integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
@@ -2437,14 +2437,14 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/vite": {
|
||||
"version": "5.3.5",
|
||||
"resolved": "https://registry.npmjs.org/vite/-/vite-5.3.5.tgz",
|
||||
"integrity": "sha512-MdjglKR6AQXQb9JGiS7Rc2wC6uMjcm7Go/NHNO63EwiJXfuk9PgqiP/n5IDJCziMkfw9n4Ubp7lttNwz+8ZVKA==",
|
||||
"version": "5.4.10",
|
||||
"resolved": "https://registry.npmjs.org/vite/-/vite-5.4.10.tgz",
|
||||
"integrity": "sha512-1hvaPshuPUtxeQ0hsVH3Mud0ZanOLwVTneA1EgbAM5LhaZEqyPWGRQ7BtaMvUrTDeEaC8pxtj6a6jku3x4z6SQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"esbuild": "^0.21.3",
|
||||
"postcss": "^8.4.39",
|
||||
"rollup": "^4.13.0"
|
||||
"postcss": "^8.4.43",
|
||||
"rollup": "^4.20.0"
|
||||
},
|
||||
"bin": {
|
||||
"vite": "bin/vite.js"
|
||||
@@ -2463,6 +2463,7 @@
|
||||
"less": "*",
|
||||
"lightningcss": "^1.21.0",
|
||||
"sass": "*",
|
||||
"sass-embedded": "*",
|
||||
"stylus": "*",
|
||||
"sugarss": "*",
|
||||
"terser": "^5.4.0"
|
||||
@@ -2480,6 +2481,9 @@
|
||||
"sass": {
|
||||
"optional": true
|
||||
},
|
||||
"sass-embedded": {
|
||||
"optional": true
|
||||
},
|
||||
"stylus": {
|
||||
"optional": true
|
||||
},
|
||||
|
||||
+2
-2
@@ -9,12 +9,12 @@
|
||||
"@tailwindcss/forms": "^0.5.7",
|
||||
"@tailwindcss/typography": "^0.5.10",
|
||||
"autoprefixer": "^10.4.19",
|
||||
"axios": "^1.6.4",
|
||||
"axios": "^1.7.4",
|
||||
"daisyui": "^4.12.10",
|
||||
"laravel-vite-plugin": "^1.0",
|
||||
"postcss": "^8.4.40",
|
||||
"tailwindcss": "^3.4.7",
|
||||
"vite": "^5.0"
|
||||
"vite": "^5.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"apexcharts": "^3.51.0"
|
||||
|
||||
@@ -63,7 +63,9 @@
|
||||
<x-ib-card title="{{ __('Recent activity') }}" class="md:col-span-3">
|
||||
|
||||
@livewire('transactions-list', [
|
||||
'transactions' => $user->transactions
|
||||
'transactions' => $user->transactions,
|
||||
'showPortfolio' => true,
|
||||
'paginate' => false
|
||||
])
|
||||
|
||||
</x-ib-card>
|
||||
|
||||
@@ -207,7 +207,7 @@
|
||||
* 52 week high: {$holding->market_data->fifty_two_week_high}
|
||||
* Dividend yield: {$holding->market_data->dividend_yield}
|
||||
|
||||
Based on this current market data, quantity owned, and average cost basis, you should determine if the {$holding->symbol} holding is making or losing money.
|
||||
This data is current as of today's date: " . now()->format('Y-m-d') . ". Based on this current market data, quantity owned, and average cost basis, you should determine if the {$holding->symbol} holding is making or losing money.
|
||||
|
||||
Below is the question from the investor. Considering these facts, provide a concise response to the following question (give a direct response). Limit your response to no more than 75 words and consider using a common decision framework. Use github style markdown for any formatting:"
|
||||
])
|
||||
|
||||
@@ -36,7 +36,7 @@ new class extends Component {
|
||||
'symbol' => ['required', 'string', new SymbolValidationRule],
|
||||
'transaction_type' => 'required|string|in:BUY,SELL',
|
||||
'portfolio_id' => 'required|exists:portfolios,id',
|
||||
'date' => 'required|date_format:Y-m-d',
|
||||
'date' => ['required', 'date_format:Y-m-d', 'before_or_equal:' . now()->format('Y-m-d')],
|
||||
'quantity' => [
|
||||
'required',
|
||||
'numeric',
|
||||
@@ -83,14 +83,14 @@ new class extends Component {
|
||||
|
||||
public function save()
|
||||
{
|
||||
$this->authorize('fullAccess', $this->portfolio);
|
||||
|
||||
$validated = $this->validate();
|
||||
|
||||
if (!isset($this->portfolio)) {
|
||||
$this->portfolio = Portfolio::find($this->portfolio_id);
|
||||
}
|
||||
|
||||
$this->authorize('fullAccess', $this->portfolio);
|
||||
|
||||
$validated = $this->validate();
|
||||
|
||||
$transaction = $this->portfolio->transactions()->create($validated);
|
||||
$transaction->save();
|
||||
|
||||
|
||||
@@ -15,6 +15,10 @@ new class extends Component {
|
||||
public ?Portfolio $portfolio;
|
||||
public ?Transaction $editingTransaction;
|
||||
public Bool $shouldGoToHolding = true;
|
||||
public Bool $showPortfolio = false;
|
||||
public Bool $paginate = true;
|
||||
public Int $perPage = 5;
|
||||
public Int $offset = 0;
|
||||
|
||||
protected $listeners = [
|
||||
'transaction-updated' => '$refresh',
|
||||
@@ -38,17 +42,23 @@ new class extends Component {
|
||||
return $this->redirect(route('holding.show', ['portfolio' => $holding['portfolio_id'], 'symbol' => $holding['symbol']]));
|
||||
}
|
||||
|
||||
public function updateOffset($amount = 0)
|
||||
{
|
||||
$this->offset = $this->offset + $amount;
|
||||
}
|
||||
|
||||
}; ?>
|
||||
|
||||
<div class="">
|
||||
|
||||
@foreach($transactions->sortByDesc('date')->take(10) as $transaction)
|
||||
@foreach($transactions->sortByDesc('date')->slice($offset)->take($perPage) as $transaction)
|
||||
|
||||
<x-list-item
|
||||
no-separator
|
||||
:item="$transaction"
|
||||
class="cursor-pointer"
|
||||
x-data="{ loading: false, timeout: null }"
|
||||
:key="$transaction->id"
|
||||
@click="
|
||||
if ($wire.shouldGoToHolding) {
|
||||
|
||||
@@ -83,12 +93,44 @@ new class extends Component {
|
||||
<x-loading x-show="loading" x-cloak class="text-gray-400 ml-2" />
|
||||
</x-slot:value>
|
||||
<x-slot:sub-value>
|
||||
@if($showPortfolio)
|
||||
<span title="{{ __('Portfolio') }}">{{ $transaction->portfolio->title }} </span>
|
||||
·
|
||||
@endif
|
||||
<span title="{{ __('Transaction Date') }}">{{ $transaction->date->format('F j, Y') }} </span>
|
||||
</x-slot:sub-value>
|
||||
</x-list-item>
|
||||
|
||||
@endforeach
|
||||
|
||||
@if ($paginate && count($transactions) > $perPage)
|
||||
<div class="flex justify-between">
|
||||
|
||||
<span>
|
||||
@if($offset > 0)
|
||||
<x-button
|
||||
class="btn btn-sm btn-ghost text-secondary"
|
||||
wire:click="updateOffset(-{{ $perPage }})"
|
||||
>
|
||||
{!! __('pagination.previous') !!}
|
||||
</x-button>
|
||||
@endif
|
||||
</span>
|
||||
|
||||
<span>
|
||||
@if(count($transactions) - $offset > $offset)
|
||||
<x-button
|
||||
class="btn btn-sm btn-ghost text-secondary"
|
||||
wire:click="updateOffset({{ $perPage }})"
|
||||
>
|
||||
{!! __('pagination.next') !!}
|
||||
</x-button>
|
||||
@endif
|
||||
</span>
|
||||
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<x-ib-alpine-modal
|
||||
key="manage-transaction"
|
||||
title="{{ __('Manage Transaction') }}"
|
||||
@@ -96,7 +138,7 @@ new class extends Component {
|
||||
@livewire('manage-transaction-form', [
|
||||
'portfolio' => $portfolio,
|
||||
'transaction' => $editingTransaction,
|
||||
], key($editingTransaction->id ?? 'new'))
|
||||
], key($editingTransaction?->id.rand()))
|
||||
|
||||
</x-ib-alpine-modal>
|
||||
</div>
|
||||
@@ -173,7 +173,7 @@
|
||||
|
||||
{$formattedHoldings}
|
||||
|
||||
Based on the current market data, quantity owned, and average cost basis, you can determine the performance of any holding.
|
||||
This data is current as of today's date: " . now()->format('Y-m-d') . ". Based on the current market data, quantity owned, and average cost basis, you can determine the performance of any holding.
|
||||
|
||||
Below is the question from the investor. Considering these facts, provide a concise response to the following question (give a direct response). Limit your response to no more than 75 words and consider using a common decision framework. Use github style markdown for any formatting:"
|
||||
])
|
||||
|
||||
+2
-2
@@ -8,7 +8,7 @@ use App\Console\Commands\{RefreshMarketData, CaptureDailyChange, RefreshDividend
|
||||
* This scheduled job refreshes market data from your selected data provider
|
||||
* Update the cadence with the MARKET_DATA_REFRESH key in your env file
|
||||
*/
|
||||
Schedule::command(RefreshMarketData::class)->everyMinute()->weekdays();
|
||||
Schedule::command(RefreshMarketData::class)->weekdays()->everyMinute();
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -20,7 +20,7 @@ Schedule::command(CaptureDailyChange::class)->dailyAt(config('investbrain.daily_
|
||||
*
|
||||
* Refreshes dividend data for your holdings (and syncs new dividends to holdings)
|
||||
*/
|
||||
Schedule::command(RefreshDividendData::class)->days([1, 3, 5])->weekdays();
|
||||
Schedule::command(RefreshDividendData::class)->daily()->days([1, 3, 5]);
|
||||
|
||||
/**
|
||||
*
|
||||
|
||||
@@ -61,4 +61,26 @@ class DividendsTest extends TestCase
|
||||
$this->assertCount(3, $transactions);
|
||||
$this->assertEqualsWithDelta(4.95, $dividendsReinvested * $market_data->market_value, 0.01);
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
public function test_do_not_duplicate_recent_dividends(): void
|
||||
{
|
||||
$this->actingAs($user = User::factory()->create());
|
||||
|
||||
$portfolio = Portfolio::factory()->create();
|
||||
Transaction::factory()->buy()->yearsAgo()->portfolio($portfolio->id)->symbol('ACME')->create();
|
||||
|
||||
$holding = Holding::query()->portfolio($portfolio->id)->symbol('ACME')->first();
|
||||
|
||||
Dividend::create([
|
||||
'symbol' => 'ACME',
|
||||
'date' => now()->subDay(2),
|
||||
'dividend_amount' => .01
|
||||
]);
|
||||
|
||||
Dividend::refreshDividendData('ACME');
|
||||
|
||||
$this->assertCount(1, $holding->dividends);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user