├── .editorconfig ├── .github └── workflows │ ├── analyse.yml │ ├── changelog.yml │ └── style.yml ├── .gitignore ├── CHANGELOG.md ├── LICENSE ├── README.md ├── UPGRADE.md ├── composer.json ├── phpstan.neon └── src ├── Nova ├── Actions │ ├── ProcessProductsWithMissingPrices.php │ ├── ResetFailures.php │ ├── RetrieveAllPrices.php │ ├── RetrievePrice.php │ └── UpdatePrice.php ├── Filters │ ├── Failed.php │ ├── Product.php │ ├── Status.php │ └── Sync.php ├── Metrics │ ├── PriceErrorsPerDay.php │ ├── PriceRetrievalsPerDay.php │ ├── PriceUpdatesPerDay.php │ ├── PricesSyncPartition.php │ ├── PricesToRetrieve.php │ └── PricesToUpdate.php └── PriceResource.php └── ServiceProvider.php /.editorconfig: -------------------------------------------------------------------------------- 1 | [*] 2 | charset = utf-8 3 | end_of_line = lf 4 | insert_final_newline = true 5 | indent_style = space 6 | indent_size = 4 7 | trim_trailing_whitespace = true 8 | -------------------------------------------------------------------------------- /.github/workflows/analyse.yml: -------------------------------------------------------------------------------- 1 | name: analyse 2 | 3 | on: ['push', 'pull_request'] 4 | 5 | jobs: 6 | test: 7 | runs-on: ${{ matrix.os }} 8 | strategy: 9 | fail-fast: true 10 | matrix: 11 | os: [ubuntu-latest] 12 | php: [8.3, 8.4] 13 | laravel: [11.*] 14 | stability: [prefer-stable] 15 | include: 16 | - laravel: 11.* 17 | testbench: 9.* 18 | 19 | name: P${{ matrix.php }} - L${{ matrix.laravel }} - ${{ matrix.stability }} - ${{ matrix.os }} 20 | 21 | steps: 22 | - name: Checkout code 23 | uses: actions/checkout@v4 24 | 25 | - name: Setup PHP 26 | uses: shivammathur/setup-php@v2 27 | with: 28 | php-version: ${{ matrix.php }} 29 | extensions: dom, curl, libxml, mbstring, zip, pdo, sqlite, pdo_sqlite, bcmath, soap, intl, gd, exif, iconv, imagick, fileinfo 30 | coverage: none 31 | 32 | - name: Install dependencies 33 | env: 34 | COMPOSER_AUTH: '{"http-basic":{"nova.laravel.com":{"username":"${{secrets.NOVA_USERNAME}}","password":"${{secrets.NOVA_PASSWORD}}"}}}' 35 | run: | 36 | composer require "laravel/framework:${{ matrix.laravel }}" "orchestra/testbench:${{ matrix.testbench }}" --no-interaction --no-update 37 | composer update --${{ matrix.stability }} --prefer-dist --no-interaction 38 | - name: Analyse 39 | run: composer analyse 40 | -------------------------------------------------------------------------------- /.github/workflows/changelog.yml: -------------------------------------------------------------------------------- 1 | name: "Update Changelog" 2 | 3 | on: 4 | release: 5 | types: [ published, edited, deleted ] 6 | 7 | jobs: 8 | generate: 9 | runs-on: ubuntu-latest 10 | 11 | steps: 12 | - name: Checkout code 13 | uses: actions/checkout@v3 14 | with: 15 | ref: ${{ github.event.release.target_commitish }} 16 | 17 | - name: Generate changelog 18 | uses: justbetter/generate-changelogs-action@main 19 | env: 20 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 21 | with: 22 | repository: ${{ github.repository }} 23 | 24 | - name: Commit CHANGELOG 25 | uses: stefanzweifel/git-auto-commit-action@v4 26 | with: 27 | branch: ${{ github.event.release.target_commitish }} 28 | commit_message: Update CHANGELOG 29 | file_pattern: CHANGELOG.md -------------------------------------------------------------------------------- /.github/workflows/style.yml: -------------------------------------------------------------------------------- 1 | name: style 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | jobs: 8 | style: 9 | name: Style 10 | runs-on: ubuntu-latest 11 | 12 | steps: 13 | - name: Checkout code 14 | uses: actions/checkout@v4 15 | 16 | - name: Setup PHP 17 | uses: shivammathur/setup-php@v2 18 | with: 19 | php-version: 8.4 20 | extensions: dom, curl, libxml, mbstring, zip, pdo, sqlite, pdo_sqlite, bcmath, soap, intl, gd, exif, iconv, imagick, fileinfo 21 | coverage: none 22 | 23 | - name: Install dependencies 24 | env: 25 | COMPOSER_AUTH: '{"http-basic":{"nova.laravel.com":{"username":"${{secrets.NOVA_USERNAME}}","password":"${{secrets.NOVA_PASSWORD}}"}}}' 26 | run: composer install 27 | 28 | - name: Style 29 | run: composer fix-style 30 | 31 | - name: Commit Changes 32 | uses: stefanzweifel/git-auto-commit-action@v4 33 | with: 34 | commit_message: Fix styling changes 35 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | vendor 2 | composer.lock 3 | .phpunit.result.cache 4 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | [Unreleased changes](https://github.com/justbetter/laravel-magento-prices-nova/compare/4.4.0...main) 4 | ## [4.4.0](https://github.com/justbetter/laravel-magento-prices-nova/releases/tag/4.4.0) - 2025-02-17 5 | 6 | ### What's Changed 7 | * Laravel 12 / Nova 5 support by @VincentBean in https://github.com/justbetter/laravel-magento-prices-nova/pull/11 8 | 9 | 10 | **Full Changelog**: https://github.com/justbetter/laravel-magento-prices-nova/compare/4.3.2...4.4.0 11 | 12 | ## [4.3.2](https://github.com/justbetter/laravel-magento-prices-nova/releases/tag/4.3.2) - 2024-09-18 13 | 14 | ### What's Changed 15 | * Add bulk operations to Nova resource by @VincentBean in https://github.com/justbetter/laravel-magento-prices-nova/pull/10 16 | 17 | 18 | **Full Changelog**: https://github.com/justbetter/laravel-magento-prices-nova/compare/4.3.1...4.3.2 19 | 20 | ## [4.3.1](https://github.com/justbetter/laravel-magento-prices-nova/releases/tag/4.3.1) - 2024-08-06 21 | 22 | ### What's Changed 23 | * Added uriKey by @ramonrietdijk in https://github.com/justbetter/laravel-magento-prices-nova/pull/9 24 | 25 | ### New Contributors 26 | * @ramonrietdijk made their first contribution in https://github.com/justbetter/laravel-magento-prices-nova/pull/9 27 | 28 | **Full Changelog**: https://github.com/justbetter/laravel-magento-prices-nova/compare/4.3.0...4.3.1 29 | 30 | ## [4.3.0](https://github.com/justbetter/laravel-magento-prices-nova/releases/tag/4.3.0) - 2024-08-05 31 | 32 | ### What's Changed 33 | * Update README.md composer require command by @FinnPaes in https://github.com/justbetter/laravel-magento-prices-nova/pull/7 34 | * Refactor by @VincentBean in https://github.com/justbetter/laravel-magento-prices-nova/pull/8 35 | 36 | ### New Contributors 37 | * @FinnPaes made their first contribution in https://github.com/justbetter/laravel-magento-prices-nova/pull/7 38 | 39 | **Full Changelog**: https://github.com/justbetter/laravel-magento-prices-nova/compare/4.2.0...4.3.0 40 | 41 | ## [4.2.0](https://github.com/justbetter/laravel-magento-prices-nova/releases/tag/4.2.0) - 2023-06-26 42 | 43 | **Full Changelog**: https://github.com/justbetter/laravel-magento-prices-nova/compare/4.1.3...4.2.0 44 | 45 | ## [4.1.3](https://github.com/justbetter/laravel-magento-prices-nova/releases/tag/4.1.3) - 2023-06-15 46 | 47 | ### What's Changed 48 | * Add license by @VincentBean in https://github.com/justbetter/laravel-magento-prices-nova/pull/6 49 | * Use Nova's ActionResponse 50 | 51 | **Full Changelog**: https://github.com/justbetter/laravel-magento-prices-nova/compare/4.1.2...4.1.3 52 | 53 | ## [4.1.2](https://github.com/justbetter/laravel-magento-prices-nova/releases/tag/4.1.2) - 2023-04-05 54 | 55 | ### What's Changed 56 | * Update metric labels by @VincentBean in https://github.com/justbetter/laravel-magento-prices-nova/pull/5 57 | 58 | 59 | **Full Changelog**: https://github.com/justbetter/laravel-magento-prices-nova/compare/4.1.1...4.1.2 60 | 61 | ## [4.1.1](https://github.com/justbetter/laravel-magento-prices-nova/releases/tag/4.1.1) - 2023-04-05 62 | 63 | ### What's Changed 64 | * Fix count metrics by @VincentBean in https://github.com/justbetter/laravel-magento-prices-nova/pull/4 65 | 66 | 67 | **Full Changelog**: https://github.com/justbetter/laravel-magento-prices-nova/compare/4.1.0...4.1.1 68 | 69 | ## [4.1.0](https://github.com/justbetter/laravel-magento-prices-nova/releases/tag/4.1.0) - 2023-03-10 70 | 71 | ### What's Changed 72 | * Support Laravel 10 by @VincentBean in https://github.com/justbetter/laravel-magento-prices-nova/pull/3 73 | 74 | 75 | **Full Changelog**: https://github.com/justbetter/laravel-magento-prices-nova/compare/4.0.9...4.1.0 76 | 77 | ## [4.0.9](https://github.com/justbetter/laravel-magento-prices-nova/releases/tag/4.0.9) - 2023-01-12 78 | 79 | Changelogs 80 | 81 | **Full Changelog**: https://github.com/justbetter/laravel-magento-prices-nova/compare/4.0.8...4.0.9 82 | 83 | ## [4.0.8](https://github.com/justbetter/laravel-magento-prices-nova/releases/tag/4.0.8) - 2023-01-12 84 | 85 | **Full Changelog**: https://github.com/justbetter/laravel-magento-prices-nova/compare/4.0.7...4.0.8 86 | 87 | ## [4.0.7](https://github.com/justbetter/laravel-magento-prices-nova/releases/tag/4.0.7) - 2023-01-12 88 | 89 | ### What's Changed 90 | * Add changelogs by @VincentBean in https://github.com/justbetter/laravel-magento-prices-nova/pull/2 91 | 92 | 93 | **Full Changelog**: https://github.com/justbetter/laravel-magento-prices-nova/compare/4.0.6...4.0.7 94 | 95 | ## [4.0.3](https://github.com/justbetter/laravel-magento-prices-nova/releases/tag/4.0.3) - 2022-10-19 96 | 97 | 98 | **Full Changelog**: https://github.com/justbetter/laravel-magento-prices-nova/compare/4.0.1...4.0.3 99 | 100 | ## [4.0.2](https://github.com/justbetter/laravel-magento-prices-nova/releases/tag/4.0.2) - 2022-10-11 101 | 102 | ### What's Changed 103 | * Magento existence by @VincentBean in https://github.com/justbetter/laravel-magento-prices-nova/pull/1 104 | 105 | ### New Contributors 106 | * @VincentBean made their first contribution in https://github.com/justbetter/laravel-magento-prices-nova/pull/1 107 | 108 | **Full Changelog**: https://github.com/justbetter/laravel-magento-prices-nova/compare/4.0.1...4.0.2 109 | 110 | ## [4.0.0](https://github.com/justbetter/laravel-magento-prices-nova/releases/tag/4.0.0) - 2022-09-20 111 | 112 | **Full Changelog**: https://github.com/justbetter/laravel-magento-prices-nova/commits/4.0.0 113 | 114 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) JustBetter 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 6 | documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 7 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit 8 | persons to whom the Software is furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the 11 | Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 14 | WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 15 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 16 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 17 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Laravel Magento Prices Nova 2 | 3 | This package is the Laravel Nova integration for `justbetter/laravel-magento-prices`. 4 | 5 | ## Installation 6 | 7 | Install the package. 8 | 9 | ```shell 10 | composer require justbetter/laravel-magento-prices-nova 11 | ``` 12 | 13 | ## Versioning 14 | 15 | Our major version corresponds to the major Nova version. 16 | 17 | | Package version | Nova version | 18 | |-----------------|--------------| 19 | | `^4.0` | `^4.0` | 20 | 21 | 22 | ## Contributing 23 | 24 | Please see [CONTRIBUTING](.github/CONTRIBUTING.md) for details. 25 | 26 | ## Security Vulnerabilities 27 | 28 | Please review [our security policy](../../security/policy) on how to report security vulnerabilities. 29 | 30 | ## Credits 31 | 32 | - [Vincent Boon](https://github.com/VincentBean) 33 | - [All Contributors](../../contributors) 34 | 35 | ## License 36 | 37 | The MIT License (MIT). Please see [License File](LICENSE) for more information. 38 | -------------------------------------------------------------------------------- /UPGRADE.md: -------------------------------------------------------------------------------- 1 | # Upgrade guide 2 | 3 | ## 4.2.x to 4.3.x 4 | 5 | The 4.3.x release adds support for `justbetter/laravel-magento-prices` version `^2.0`. 6 | 7 | ### Refactor 8 | 9 | A few classes like the resource have been renamed. The resource `Prices` is now `PriceResource`. Make sure to update all references if you make use of it manually. 10 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "justbetter/laravel-magento-prices-nova", 3 | "description": "Nova integration for justbetter/laravel-magento-prices", 4 | "type": "package", 5 | "license": "MIT", 6 | "authors": [ 7 | { 8 | "name": "Vincent Boon", 9 | "email": "vincent@justbetter.nl", 10 | "role": "Developer" 11 | }, 12 | { 13 | "name": "Ramon Rietdijk", 14 | "email": "ramon@justbetter.nl", 15 | "role": "Developer" 16 | } 17 | ], 18 | "require": { 19 | "php": "^8.3", 20 | "bolechen/nova-activitylog": "^0.5.0", 21 | "justbetter/laravel-magento-async-nova": "^4.0", 22 | "justbetter/laravel-magento-prices": "^2.0", 23 | "laravel/framework": "^11.0|^12.0", 24 | "laravel/nova": "^5.0" 25 | }, 26 | "require-dev": { 27 | "larastan/larastan": "^3.0", 28 | "laravel/pint": "^1.20", 29 | "orchestra/testbench": "^9.0", 30 | "pestphp/pest": "^3.7", 31 | "phpstan/phpstan-mockery": "^2.0", 32 | "phpunit/phpunit": "^11.5" 33 | }, 34 | "autoload": { 35 | "psr-4": { 36 | "JustBetter\\MagentoPricesNova\\": "src" 37 | } 38 | }, 39 | "scripts": { 40 | "analyse": "phpstan --memory-limit=256M", 41 | "style": "pint --test", 42 | "quality": [ 43 | "@style", 44 | "@analyse" 45 | ] 46 | }, 47 | "extra": { 48 | "laravel": { 49 | "providers": [ 50 | "JustBetter\\MagentoPricesNova\\ServiceProvider" 51 | ] 52 | } 53 | }, 54 | "config": { 55 | "sort-packages": true, 56 | "allow-plugins": { 57 | "pestphp/pest-plugin": true 58 | } 59 | }, 60 | "minimum-stability": "stable", 61 | "prefer-stable": true, 62 | "repositories": [ 63 | { 64 | "type": "composer", 65 | "url": "https://nova.laravel.com" 66 | } 67 | ] 68 | } 69 | -------------------------------------------------------------------------------- /phpstan.neon: -------------------------------------------------------------------------------- 1 | includes: 2 | - ./vendor/larastan/larastan/extension.neon 3 | - ./vendor/phpstan/phpstan-mockery/extension.neon 4 | 5 | parameters: 6 | paths: 7 | - src 8 | level: 8 9 | ignoreErrors: 10 | - identifier: missingType.iterableValue 11 | - identifier: missingType.generics 12 | -------------------------------------------------------------------------------- /src/Nova/Actions/ProcessProductsWithMissingPrices.php: -------------------------------------------------------------------------------- 1 | withName(__('Search missing prices in Magento')) 17 | ->standalone(); 18 | } 19 | 20 | public function handle(ActionFields $fields, Collection $models): ActionResponse 21 | { 22 | ProcessProductsWithMissingPricesJob::dispatch(); 23 | 24 | return ActionResponse::message(__('Searching...')); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Nova/Actions/ResetFailures.php: -------------------------------------------------------------------------------- 1 | withName(__('Reset failures')); 18 | } 19 | 20 | public function handle(ActionFields $fields, Collection $models): ActionResponse 21 | { 22 | /** @var bool $retrieve */ 23 | $retrieve = $fields->get('retrieve'); 24 | 25 | /** @var bool $update */ 26 | $update = $fields->get('update'); 27 | 28 | $models->each(fn (Price $price): bool => $price->update([ 29 | 'sync' => true, 30 | 'failed_at' => null, 31 | 'fail_count' => 0, 32 | 'retrieve' => $retrieve, 33 | 'update' => $update, 34 | ])); 35 | 36 | return ActionResponse::message(__('Failures reset!')); 37 | } 38 | 39 | public function fields(NovaRequest $request): array 40 | { 41 | return [ 42 | Boolean::make(__('Retrieve'), 'retrieve') 43 | ->help(__('Set the retrieve flag')), 44 | 45 | Boolean::make(__('Update'), 'update') 46 | ->help(__('Set the update flag')), 47 | ]; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/Nova/Actions/RetrieveAllPrices.php: -------------------------------------------------------------------------------- 1 | withName(__('Retrieve all prices')) 20 | ->standalone(); 21 | } 22 | 23 | public function handle(ActionFields $fields, Collection $models): ActionResponse 24 | { 25 | /** @var ?string $from */ 26 | $from = $fields->get('from'); 27 | 28 | if ($from !== null) { 29 | $carbon = Carbon::parse($from); 30 | } 31 | 32 | RetrieveAllPricesJob::dispatch($carbon ?? null); 33 | 34 | return ActionResponse::message(__('Retrieving...')); 35 | } 36 | 37 | public function fields(NovaRequest $request): array 38 | { 39 | return [ 40 | DateTime::make(__('From'), 'from') 41 | ->help(__('Optional, retrieve updated prices from this date')), 42 | ]; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/Nova/Actions/RetrievePrice.php: -------------------------------------------------------------------------------- 1 | withName(__('Retrieve selected price')); 19 | } 20 | 21 | public function handle(ActionFields $fields, Collection $models): ActionResponse 22 | { 23 | /** @var bool $force */ 24 | $force = $fields->get('force'); 25 | 26 | $models->each(fn (Price $model) => RetrievePriceJob::dispatch($model->sku, $force)); 27 | 28 | return ActionResponse::message(__('Retrieving...')); 29 | } 30 | 31 | public function fields(NovaRequest $request): array 32 | { 33 | return [ 34 | Boolean::make(__('Force Update'), 'force') 35 | ->help(__('Update the price to Magento, even if it has not changed')), 36 | ]; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/Nova/Actions/UpdatePrice.php: -------------------------------------------------------------------------------- 1 | withName(__('Update to Magento')); 18 | } 19 | 20 | public function handle(ActionFields $fields, Collection $models): ActionResponse 21 | { 22 | $models->each(fn (Price $price): PendingDispatch => UpdatePriceJob::dispatch($price)); 23 | 24 | return ActionResponse::message(__('Updating...')); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Nova/Filters/Failed.php: -------------------------------------------------------------------------------- 1 | name = __('Failed prices'); 15 | } 16 | 17 | /** @param Builder $query */ 18 | public function apply(NovaRequest $request, EloquentBuilder $query, mixed $value): Builder|EloquentBuilder 19 | { 20 | return match ($value) { 21 | 'day' => $query->whereDate('last_failed', '>=', now()->startOfDay()), 22 | 'week' => $query->whereDate('last_failed', '>=', now()->subWeek()->startOfDay()), 23 | default => $query->whereNotNull('last_failed'), 24 | }; 25 | } 26 | 27 | public function options(NovaRequest $request): array 28 | { 29 | return [ 30 | (string) __('Past day') => 'day', 31 | (string) __('Past week') => 'week', 32 | (string) __('All') => 'all', 33 | ]; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/Nova/Filters/Product.php: -------------------------------------------------------------------------------- 1 | name = __('Product exists in Magento'); 15 | } 16 | 17 | /** @param Builder $query */ 18 | public function apply(NovaRequest $request, EloquentBuilder $query, mixed $value): Builder|EloquentBuilder 19 | { 20 | return $query->whereHas('product', function (Builder $query) use ($value): void { 21 | $query->where('exists_in_magento', '=', $value); 22 | }); 23 | } 24 | 25 | public function options(NovaRequest $request): array 26 | { 27 | return [ 28 | (string) __('Exists in Magento') => 1, 29 | (string) __('Not in Magento') => 0, 30 | ]; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/Nova/Filters/Status.php: -------------------------------------------------------------------------------- 1 | name = __('Price status'); 15 | } 16 | 17 | /** @param Builder $query */ 18 | public function apply(NovaRequest $request, EloquentBuilder $query, mixed $value): Builder|EloquentBuilder 19 | { 20 | return $query->where($value, true); 21 | } 22 | 23 | public function options(NovaRequest $request): array 24 | { 25 | return [ 26 | (string) __('To retrieve') => 'retrieve', 27 | (string) __('To update') => 'update', 28 | ]; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Nova/Filters/Sync.php: -------------------------------------------------------------------------------- 1 | name = __('Price sync'); 15 | } 16 | 17 | /** @param Builder $query */ 18 | public function apply(NovaRequest $request, EloquentBuilder $query, mixed $value): Builder|EloquentBuilder 19 | { 20 | return $query->where('sync', '=', $value); 21 | } 22 | 23 | public function options(NovaRequest $request): array 24 | { 25 | return [ 26 | (string) __('In sync') => 1, 27 | (string) __('Not in sync') => 0, 28 | ]; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Nova/Metrics/PriceErrorsPerDay.php: -------------------------------------------------------------------------------- 1 | countByDays($request, Price::class, 'last_failed'); 15 | } 16 | 17 | public function ranges(): array 18 | { 19 | return [ 20 | 30 => __(':days days', ['days' => 30]), 21 | 60 => __(':days days', ['days' => 60]), 22 | 90 => __(':days days', ['days' => 90]), 23 | ]; 24 | } 25 | 26 | public function uriKey(): string 27 | { 28 | return 'price-errors-per-day'; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Nova/Metrics/PriceRetrievalsPerDay.php: -------------------------------------------------------------------------------- 1 | countByDays($request, Price::class, 'last_retrieved'); 15 | } 16 | 17 | public function ranges(): array 18 | { 19 | return [ 20 | 30 => __(':days days', ['days' => 30]), 21 | 60 => __(':days days', ['days' => 60]), 22 | 90 => __(':days days', ['days' => 90]), 23 | ]; 24 | } 25 | 26 | public function uriKey(): string 27 | { 28 | return 'price-retrievals-per-day'; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Nova/Metrics/PriceUpdatesPerDay.php: -------------------------------------------------------------------------------- 1 | countByDays($request, Price::class, 'last_updated'); 15 | } 16 | 17 | public function ranges(): array 18 | { 19 | return [ 20 | 30 => __(':days days', ['days' => 30]), 21 | 60 => __(':days days', ['days' => 60]), 22 | 90 => __(':days days', ['days' => 90]), 23 | ]; 24 | } 25 | 26 | public function uriKey(): string 27 | { 28 | return 'price-updates-per-day'; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Nova/Metrics/PricesSyncPartition.php: -------------------------------------------------------------------------------- 1 | name = __('Keep in sync'); 15 | } 16 | 17 | public function calculate(NovaRequest $request): PartitionResult 18 | { 19 | return $this 20 | ->count($request, Price::class, 'sync') 21 | ->label(fn (mixed $sync): string => $sync ? __('Yes') : __('No')); 22 | } 23 | 24 | public function uriKey(): string 25 | { 26 | return 'prices-sync-partition'; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/Nova/Metrics/PricesToRetrieve.php: -------------------------------------------------------------------------------- 1 | where('sync', '=', true) 17 | ->where('retrieve', '=', true) 18 | ->count() 19 | ); 20 | } 21 | 22 | public function uriKey(): string 23 | { 24 | return 'prices-to-retrieve'; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Nova/Metrics/PricesToUpdate.php: -------------------------------------------------------------------------------- 1 | where('sync', '=', true) 18 | ->where('update', '=', true) 19 | ->whereHas('product', function (Builder $query): void { 20 | $query->where('exists_in_magento', '=', true); 21 | }) 22 | ->count() 23 | ); 24 | } 25 | 26 | public function uriKey(): string 27 | { 28 | return 'prices-to-update'; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Nova/PriceResource.php: -------------------------------------------------------------------------------- 1 | help(__('Disable if this product stock should not be synced')) 46 | ->sortable(), 47 | 48 | Boolean::make(__('Exists in Magento'), function (Price $price): bool { 49 | $product = MagentoProduct::findBySku($price->sku); 50 | 51 | return $product === null ? false : $product->exists_in_magento; 52 | }) 53 | ->showOnIndex(false), 54 | 55 | Text::make(__('SKU'), 'sku') 56 | ->readonly() 57 | ->sortable(), 58 | 59 | Code::make(__('Base prices'), 'base_prices') 60 | ->json() 61 | ->readonly(), 62 | 63 | Code::make(__('Tier prices'), 'tier_prices') 64 | ->json() 65 | ->readonly(), 66 | 67 | Code::make(__('Special prices'), 'special_prices') 68 | ->json() 69 | ->readonly(), 70 | 71 | Boolean::make(__('Retrieve'), 'retrieve') 72 | ->help(__('Automatically set to true if this product should be retrieved')) 73 | ->sortable(), 74 | 75 | Boolean::make(__('Update'), 'update') 76 | ->help(__('Automatically set to true if this product should be updated in Magento')) 77 | ->sortable(), 78 | 79 | DateTime::make(__('Last retrieved'), 'last_retrieved') 80 | ->readonly() 81 | ->sortable(), 82 | 83 | DateTime::make(__('Last updated'), 'last_updated') 84 | ->readonly() 85 | ->sortable(), 86 | 87 | DateTime::make(__('Last failed'), 'last_failed') 88 | ->readonly() 89 | ->sortable(), 90 | 91 | Number::make(__('Fail count'), 'fail_count') 92 | ->readonly() 93 | ->onlyOnDetail(), 94 | 95 | MorphMany::make(__('Activity'), 'activities', Activitylog::class), 96 | 97 | MorphMany::make(__('Operations'), 'bulkOperations', BulkOperationResource::class), 98 | ]; 99 | } 100 | 101 | public function actions(NovaRequest $request): array 102 | { 103 | return [ 104 | Actions\RetrievePrice::make(), 105 | Actions\RetrieveAllPrices::make(), 106 | Actions\UpdatePrice::make(), 107 | Actions\ResetFailures::make(), 108 | Actions\ProcessProductsWithMissingPrices::make(), 109 | ]; 110 | } 111 | 112 | public function cards(NovaRequest $request): array 113 | { 114 | return [ 115 | Metrics\PricesToRetrieve::make(), 116 | Metrics\PricesToUpdate::make(), 117 | Metrics\PricesSyncPartition::make(), 118 | Metrics\PriceRetrievalsPerDay::make(), 119 | Metrics\PriceUpdatesPerDay::make(), 120 | Metrics\PriceErrorsPerDay::make(), 121 | ]; 122 | } 123 | 124 | public function filters(NovaRequest $request): array 125 | { 126 | return [ 127 | Filters\Status::make(), 128 | Filters\Failed::make(), 129 | Filters\Sync::make(), 130 | Filters\Product::make(), 131 | ]; 132 | } 133 | 134 | public static function authorizedToCreate(Request $request): bool 135 | { 136 | return false; 137 | } 138 | 139 | public function authorizedToReplicate(Request $request): bool 140 | { 141 | return false; 142 | } 143 | } 144 | -------------------------------------------------------------------------------- /src/ServiceProvider.php: -------------------------------------------------------------------------------- 1 |