Compare commits
No commits in common. "4f0f06a7da427c9753b2dce35ee73ce421ebc904" and "972e7511576a4f78c80742fde7e679b887910add" have entirely different histories.
4f0f06a7da
...
972e751157
@ -1,18 +0,0 @@
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
indent_size = 4
|
||||
indent_style = space
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[*.md]
|
||||
trim_trailing_whitespace = false
|
||||
|
||||
[*.{yml,yaml}]
|
||||
indent_size = 2
|
||||
|
||||
[compose.yaml]
|
||||
indent_size = 4
|
||||
@ -1,23 +0,0 @@
|
||||
APP_NAME="Szállítói webrendelő (Testing)"
|
||||
APP_ENV=testing
|
||||
APP_STAGE=local
|
||||
APP_KEY=base64:Ftjcs9gvv7IgMLvSzaCQIaqIPBFO2fezCFUb+owUSCE=
|
||||
APP_DEBUG=true
|
||||
APP_URL=https://t2t.emegrendeles.hu.test
|
||||
SERVER_PORT=9000
|
||||
FORCE_HTTPS=true
|
||||
|
||||
DB_CONNECTION=mysql
|
||||
DB_HOST=127.0.0.1
|
||||
DB_PORT=3306
|
||||
DB_DATABASE=d2d
|
||||
DB_USERNAME=root
|
||||
DB_PASSWORD=
|
||||
|
||||
BROADCAST_DRIVER=log
|
||||
CACHE_DRIVER=file
|
||||
QUEUE_CONNECTION=sync
|
||||
SESSION_DRIVER=file
|
||||
SESSION_LIFETIME=120
|
||||
|
||||
MAIL_MAILER=log
|
||||
65
.env.example
65
.env.example
@ -1,65 +0,0 @@
|
||||
APP_NAME=Laravel
|
||||
APP_ENV=local
|
||||
APP_KEY=
|
||||
APP_DEBUG=true
|
||||
APP_URL=http://localhost
|
||||
|
||||
APP_LOCALE=en
|
||||
APP_FALLBACK_LOCALE=en
|
||||
APP_FAKER_LOCALE=en_US
|
||||
|
||||
APP_MAINTENANCE_DRIVER=file
|
||||
# APP_MAINTENANCE_STORE=database
|
||||
|
||||
# PHP_CLI_SERVER_WORKERS=4
|
||||
|
||||
BCRYPT_ROUNDS=12
|
||||
|
||||
LOG_CHANNEL=stack
|
||||
LOG_STACK=single
|
||||
LOG_DEPRECATIONS_CHANNEL=null
|
||||
LOG_LEVEL=debug
|
||||
|
||||
DB_CONNECTION=sqlite
|
||||
# DB_HOST=127.0.0.1
|
||||
# DB_PORT=3306
|
||||
# DB_DATABASE=laravel
|
||||
# DB_USERNAME=root
|
||||
# DB_PASSWORD=
|
||||
|
||||
SESSION_DRIVER=database
|
||||
SESSION_LIFETIME=120
|
||||
SESSION_ENCRYPT=false
|
||||
SESSION_PATH=/
|
||||
SESSION_DOMAIN=null
|
||||
|
||||
BROADCAST_CONNECTION=log
|
||||
FILESYSTEM_DISK=local
|
||||
QUEUE_CONNECTION=database
|
||||
|
||||
CACHE_STORE=database
|
||||
# CACHE_PREFIX=
|
||||
|
||||
MEMCACHED_HOST=127.0.0.1
|
||||
|
||||
REDIS_CLIENT=phpredis
|
||||
REDIS_HOST=127.0.0.1
|
||||
REDIS_PASSWORD=null
|
||||
REDIS_PORT=6379
|
||||
|
||||
MAIL_MAILER=log
|
||||
MAIL_SCHEME=null
|
||||
MAIL_HOST=127.0.0.1
|
||||
MAIL_PORT=2525
|
||||
MAIL_USERNAME=null
|
||||
MAIL_PASSWORD=null
|
||||
MAIL_FROM_ADDRESS="hello@example.com"
|
||||
MAIL_FROM_NAME="${APP_NAME}"
|
||||
|
||||
AWS_ACCESS_KEY_ID=
|
||||
AWS_SECRET_ACCESS_KEY=
|
||||
AWS_DEFAULT_REGION=us-east-1
|
||||
AWS_BUCKET=
|
||||
AWS_USE_PATH_STYLE_ENDPOINT=false
|
||||
|
||||
VITE_APP_NAME="${APP_NAME}"
|
||||
14
.env.testing
14
.env.testing
@ -1,14 +0,0 @@
|
||||
APP_ENV=testing
|
||||
APP_KEY=base64:Ftjcs9gvv7IgMLvSzaCQIaqIPBFO2fezCFUb+owUSCE=
|
||||
DB_CONNECTION=mysql
|
||||
DB_DATABASE=d2dTest
|
||||
|
||||
SZUNETNAPOK_API_KEY=test_api_key
|
||||
SZUNETNAPOK_API_URL=https://szunetnapok.hu/api/
|
||||
DB_HOST=127.0.0.1
|
||||
DB_PORT=3306
|
||||
DB_USERNAME=root
|
||||
DB_PASSWORD=
|
||||
CACHE_DRIVER=array
|
||||
SESSION_DRIVER=array
|
||||
QUEUE_CONNECTION=sync
|
||||
11
.gitattributes
vendored
11
.gitattributes
vendored
@ -1,11 +0,0 @@
|
||||
* text=auto eol=lf
|
||||
|
||||
*.blade.php diff=html
|
||||
*.css diff=css
|
||||
*.html diff=html
|
||||
*.md diff=markdown
|
||||
*.php diff=php
|
||||
|
||||
/.github export-ignore
|
||||
CHANGELOG.md export-ignore
|
||||
.styleci.yml export-ignore
|
||||
92
.gitignore
vendored
92
.gitignore
vendored
@ -1,75 +1,25 @@
|
||||
# =============================================================================
|
||||
# 1. LARAVEL ALAPOK & KÖRNYEZETI FÁJLOK (BIZTONSÁG)
|
||||
# =============================================================================
|
||||
# ---> Laravel
|
||||
/vendor/
|
||||
node_modules/
|
||||
npm-debug.log
|
||||
yarn-error.log
|
||||
|
||||
# Laravel 4 specific
|
||||
bootstrap/compiled.php
|
||||
app/storage/
|
||||
|
||||
# Laravel 5 & Lumen specific
|
||||
public/storage
|
||||
public/hot
|
||||
|
||||
# Laravel 5 & Lumen specific with changed public path
|
||||
public_html/storage
|
||||
public_html/hot
|
||||
|
||||
storage/*.key
|
||||
.env
|
||||
.env.backup
|
||||
.env.production
|
||||
.env.*
|
||||
auth.json
|
||||
/storage/*.key
|
||||
|
||||
# =============================================================================
|
||||
# 2. WINDOWS & IDE / FEJLESZTŐI ESZKÖZÖK (DOCKERBE NEM KELL)
|
||||
# =============================================================================
|
||||
Thumbs.db
|
||||
desktop.ini
|
||||
.DS_Store
|
||||
|
||||
/.fleet
|
||||
/.idea
|
||||
/.nova
|
||||
/.vscode
|
||||
/.zed
|
||||
Homestead.json
|
||||
Homestead.yaml
|
||||
|
||||
.phpactor.json
|
||||
Homestead.json
|
||||
/.vagrant
|
||||
.phpunit.result.cache
|
||||
/.phpunit.cache
|
||||
/.junie
|
||||
|
||||
# =============================================================================
|
||||
# 3. LOKÁLIS FÁJLRENDSZER, LOGOK ÉS CACHE (SOHASEM COMMITOLJUK)
|
||||
# =============================================================================
|
||||
*.log
|
||||
/storage/logs/*
|
||||
!/storage/logs/.gitignore
|
||||
|
||||
/storage/framework/*
|
||||
!/storage/framework/.gitignore
|
||||
|
||||
/storage/debugbar/*
|
||||
/storage/pail
|
||||
/storage/tmp/
|
||||
|
||||
/bootstrap/cache/*
|
||||
!/bootstrap/cache/.gitignore
|
||||
|
||||
# =============================================================================
|
||||
# 4. DEPENDENCY-K ÉS GENERÁLT ASSETEK (DOCKER / PIPELINE ÉPÍTI)
|
||||
# =============================================================================
|
||||
/vendor
|
||||
/node_modules
|
||||
|
||||
/public/build
|
||||
/public/hot
|
||||
/public/storage
|
||||
|
||||
# Filament & Scribe auto-generált assetek
|
||||
/public/css/filament
|
||||
/public/js/filament
|
||||
/public/fonts/filament
|
||||
/public/vendor/scribe
|
||||
|
||||
# =============================================================================
|
||||
# 5. TESZTELÉS (DUSK MARADVÁNYOK)
|
||||
# =============================================================================
|
||||
/tests/Browser/screenshots/*
|
||||
/tests/Browser/source/*
|
||||
|
||||
# =============================================================================
|
||||
# 6. EVOLÚCIÓS MARADVÁNYOK & FELHASZNÁLÓI ADATOK (GDPR / TISZTASÁG)
|
||||
# =============================================================================
|
||||
/public/images/supplierLogo/*
|
||||
/public/attachments/*
|
||||
/database/csv/*
|
||||
|
||||
184
AGENTS.md
184
AGENTS.md
@ -1,184 +0,0 @@
|
||||
<laravel-boost-guidelines>
|
||||
=== foundation rules ===
|
||||
|
||||
# Laravel Boost Guidelines
|
||||
|
||||
The Laravel Boost guidelines are specifically curated by Laravel maintainers for this application. These guidelines should be followed closely to ensure the best experience when building Laravel applications.
|
||||
|
||||
## Foundational Context
|
||||
|
||||
This application is a Laravel application and its main Laravel ecosystems package & versions are below. You are an expert with them all. Ensure you abide by these specific packages & versions.
|
||||
|
||||
- php - 8.4
|
||||
- filament/filament (FILAMENT) - v4
|
||||
- laravel/framework (LARAVEL) - v12
|
||||
- laravel/prompts (PROMPTS) - v0
|
||||
- laravel/sanctum (SANCTUM) - v4
|
||||
- livewire/livewire (LIVEWIRE) - v3
|
||||
- laravel/boost (BOOST) - v2
|
||||
- laravel/mcp (MCP) - v0
|
||||
- laravel/pail (PAIL) - v1
|
||||
- laravel/sail (SAIL) - v1
|
||||
- pestphp/pest (PEST) - v3
|
||||
- phpunit/phpunit (PHPUNIT) - v11
|
||||
- tailwindcss (TAILWINDCSS) - v4
|
||||
|
||||
## Skills Activation
|
||||
|
||||
This project has domain-specific skills available. You MUST activate the relevant skill whenever you work in that domain—don't wait until you're stuck.
|
||||
|
||||
- `laravel-best-practices` — Apply this skill whenever writing, reviewing, or refactoring Laravel PHP code. This includes creating or modifying controllers, models, migrations, form requests, policies, jobs, scheduled commands, service classes, and Eloquent queries. Triggers for N+1 and query performance issues, caching strategies, authorization and security patterns, validation, error handling, queue and job configuration, route definitions, and architectural decisions. Also use for Laravel code reviews and refactoring existing Laravel code to follow best practices. Covers any task involving Laravel backend PHP code patterns.
|
||||
- `livewire-development` — Use for any task or question involving Livewire. Activate if user mentions Livewire, wire: directives, or Livewire-specific concepts like wire:model, wire:click, invoke this skill. Covers building new components, debugging reactivity issues, real-time form validation, loading states, migrating from Livewire 2 to 3, converting component formats (SFC/MFC/class-based), and performance optimization. Do not use for non-Livewire reactive UI (React, Vue, Alpine-only, Inertia.js) or standard Laravel forms without Livewire.
|
||||
- `pest-testing` — Use this skill for Pest PHP testing in Laravel projects only. Trigger whenever any test is being written, edited, fixed, or refactored — including fixing tests that broke after a code change, adding assertions, converting PHPUnit to Pest, adding datasets, and TDD workflows. Always activate when the user asks how to write something in Pest, mentions test files or directories (tests/Feature, tests/Unit) or architecture tests. Covers: it()/expect() syntax, datasets, mocking, browser testing, arch(), Livewire component tests, RefreshDatabase, and all Pest 4 features. Do not use for editing factories, seeders, migrations, controllers, models, or non-test PHP code.
|
||||
- `tailwindcss-development` — Always invoke when the user's message includes 'tailwind' in any form. Also invoke for: building responsive grid layouts (multi-column card grids, product grids), flex/grid page structures (dashboards with sidebars, fixed topbars, mobile-toggle navs), styling UI components (cards, tables, navbars, pricing sections, forms, inputs, badges), adding dark mode variants, fixing spacing or typography, and Tailwind v3/v4 work. The core use case: writing or fixing Tailwind utility classes in HTML templates (Blade, JSX, Vue). Skip for backend PHP logic, database queries, API routes, JavaScript with no HTML/CSS component, CSS file audits, build tool configuration, and vanilla CSS.
|
||||
|
||||
## Conventions
|
||||
|
||||
- You must follow all existing code conventions used in this application. When creating or editing a file, check sibling files for the correct structure, approach, and naming.
|
||||
- Use descriptive names for variables and methods. For example, `isRegisteredForDiscounts`, not `discount()`.
|
||||
- Check for existing components to reuse before writing a new one.
|
||||
|
||||
## Verification Scripts
|
||||
|
||||
- Do not create verification scripts or tinker when tests cover that functionality and prove they work. Unit and feature tests are more important.
|
||||
|
||||
## Application Structure & Architecture
|
||||
|
||||
- Stick to existing directory structure; don't create new base folders without approval.
|
||||
- Do not change the application's dependencies without approval.
|
||||
|
||||
## Frontend Bundling
|
||||
|
||||
- If the user doesn't see a frontend change reflected in the UI, it could mean they need to run `npm run build`, `npm run dev`, or `composer run dev`. Ask them.
|
||||
|
||||
## Documentation Files
|
||||
|
||||
- You must only create documentation files if explicitly requested by the user.
|
||||
|
||||
## Replies
|
||||
|
||||
- Be concise in your explanations - focus on what's important rather than explaining obvious details.
|
||||
|
||||
=== boost rules ===
|
||||
|
||||
# Laravel Boost
|
||||
|
||||
## Tools
|
||||
|
||||
- Laravel Boost is an MCP server with tools designed specifically for this application. Prefer Boost tools over manual alternatives like shell commands or file reads.
|
||||
- Use `database-query` to run read-only queries against the database instead of writing raw SQL in tinker.
|
||||
- Use `database-schema` to inspect table structure before writing migrations or models.
|
||||
- Use `get-absolute-url` to resolve the correct scheme, domain, and port for project URLs. Always use this before sharing a URL with the user.
|
||||
- Use `browser-logs` to read browser logs, errors, and exceptions. Only recent logs are useful, ignore old entries.
|
||||
|
||||
## Searching Documentation (IMPORTANT)
|
||||
|
||||
- Always use `search-docs` before making code changes. Do not skip this step. It returns version-specific docs based on installed packages automatically.
|
||||
- Pass a `packages` array to scope results when you know which packages are relevant.
|
||||
- Use multiple broad, topic-based queries: `['rate limiting', 'routing rate limiting', 'routing']`. Expect the most relevant results first.
|
||||
- Do not add package names to queries because package info is already shared. Use `test resource table`, not `filament 4 test resource table`.
|
||||
|
||||
### Search Syntax
|
||||
|
||||
1. Use words for auto-stemmed AND logic: `rate limit` matches both "rate" AND "limit".
|
||||
2. Use `"quoted phrases"` for exact position matching: `"infinite scroll"` requires adjacent words in order.
|
||||
3. Combine words and phrases for mixed queries: `middleware "rate limit"`.
|
||||
4. Use multiple queries for OR logic: `queries=["authentication", "middleware"]`.
|
||||
|
||||
## Artisan
|
||||
|
||||
- Run Artisan commands directly via the command line (e.g., `php artisan route:list`). Use `php artisan list` to discover available commands and `php artisan [command] --help` to check parameters.
|
||||
- Inspect routes with `php artisan route:list`. Filter with: `--method=GET`, `--name=users`, `--path=api`, `--except-vendor`, `--only-vendor`.
|
||||
- Read configuration values using dot notation: `php artisan config:show app.name`, `php artisan config:show database.default`. Or read config files directly from the `config/` directory.
|
||||
- To check environment variables, read the `.env` file directly.
|
||||
|
||||
## Tinker
|
||||
|
||||
- Execute PHP in app context for debugging and testing code. Do not create models without user approval, prefer tests with factories instead. Prefer existing Artisan commands over custom tinker code.
|
||||
- Always use single quotes to prevent shell expansion: `php artisan tinker --execute 'Your::code();'`
|
||||
- Double quotes for PHP strings inside: `php artisan tinker --execute 'User::where("active", true)->count();'`
|
||||
|
||||
=== php rules ===
|
||||
|
||||
# PHP
|
||||
|
||||
- Always use curly braces for control structures, even for single-line bodies.
|
||||
- Use PHP 8 constructor property promotion: `public function __construct(public GitHub $github) { }`. Do not leave empty zero-parameter `__construct()` methods unless the constructor is private.
|
||||
- Use explicit return type declarations and type hints for all method parameters: `function isAccessible(User $user, ?string $path = null): bool`
|
||||
- Use TitleCase for Enum keys: `FavoritePerson`, `BestLake`, `Monthly`.
|
||||
- Prefer PHPDoc blocks over inline comments. Only add inline comments for exceptionally complex logic.
|
||||
- Use array shape type definitions in PHPDoc blocks.
|
||||
|
||||
=== laravel/core rules ===
|
||||
|
||||
# Do Things the Laravel Way
|
||||
|
||||
- Use `php artisan make:` commands to create new files (i.e. migrations, controllers, models, etc.). You can list available Artisan commands using `php artisan list` and check their parameters with `php artisan [command] --help`.
|
||||
- If you're creating a generic PHP class, use `php artisan make:class`.
|
||||
- Pass `--no-interaction` to all Artisan commands to ensure they work without user input. You should also pass the correct `--options` to ensure correct behavior.
|
||||
|
||||
### Model Creation
|
||||
|
||||
- When creating new models, create useful factories and seeders for them too. Ask the user if they need any other things, using `php artisan make:model --help` to check the available options.
|
||||
|
||||
## APIs & Eloquent Resources
|
||||
|
||||
- For APIs, default to using Eloquent API Resources and API versioning unless existing API routes do not, then you should follow existing application convention.
|
||||
|
||||
## URL Generation
|
||||
|
||||
- When generating links to other pages, prefer named routes and the `route()` function.
|
||||
|
||||
## Testing
|
||||
|
||||
- When creating models for tests, use the factories for the models. Check if the factory has custom states that can be used before manually setting up the model.
|
||||
- Faker: Use methods such as `$this->faker->word()` or `fake()->randomDigit()`. Follow existing conventions whether to use `$this->faker` or `fake()`.
|
||||
- When creating tests, make use of `php artisan make:test [options] {name}` to create a feature test, and pass `--unit` to create a unit test. Most tests should be feature tests.
|
||||
|
||||
## Vite Error
|
||||
|
||||
- If you receive an "Illuminate\Foundation\ViteException: Unable to locate file in Vite manifest" error, you can run `npm run build` or ask the user to run `npm run dev` or `composer run dev`.
|
||||
|
||||
=== laravel/v12 rules ===
|
||||
|
||||
# Laravel 12
|
||||
|
||||
- CRITICAL: ALWAYS use `search-docs` tool for version-specific Laravel documentation and updated code examples.
|
||||
- This project upgraded from Laravel 10 without migrating to the new streamlined Laravel file structure.
|
||||
- This is perfectly fine and recommended by Laravel. Follow the existing structure from Laravel 10. We do not need to migrate to the new Laravel structure unless the user explicitly requests it.
|
||||
|
||||
## Laravel 10 Structure
|
||||
|
||||
- Middleware typically lives in `app\Http/Middleware/` and service providers in `app\Providers/`.
|
||||
- There is no `bootstrap/app.php` application configuration in a Laravel 10 structure:
|
||||
- Middleware registration happens in `app\Http/Kernel.php`
|
||||
- Exception handling is in `app\Exceptions/Handler.php`
|
||||
- Console commands and schedule register in `app\Console/Kernel.php`
|
||||
- Rate limits likely exist in `RouteServiceProvider` or `app\Http/Kernel.php`
|
||||
|
||||
## Database
|
||||
|
||||
- When modifying a column, the migration must include all of the attributes that were previously defined on the column. Otherwise, they will be dropped and lost.
|
||||
- Laravel 12 allows limiting eagerly loaded records natively, without external packages: `$query->latest()->limit(10);`.
|
||||
|
||||
### Models
|
||||
|
||||
- Casts can and likely should be set in a `casts()` method on a model rather than the `$casts` property. Follow existing conventions from other models.
|
||||
|
||||
=== livewire/core rules ===
|
||||
|
||||
# Livewire
|
||||
|
||||
- Livewire allow to build dynamic, reactive interfaces in PHP without writing JavaScript.
|
||||
- You can use Alpine.js for client-side interactions instead of JavaScript frameworks.
|
||||
- Keep state server-side so the UI reflects it. Validate and authorize in actions as you would in HTTP requests.
|
||||
|
||||
=== pest/core rules ===
|
||||
|
||||
## Pest
|
||||
|
||||
- This project uses Pest for testing. Create tests: `php artisan make:test --pest {name}`.
|
||||
- Run tests: `php artisan test --compact` or filter: `php artisan test --compact --filter=testName`.
|
||||
- Do NOT delete tests without approval.
|
||||
|
||||
</laravel-boost-guidelines>
|
||||
59
README.md
59
README.md
@ -1,59 +1,2 @@
|
||||
<p align="center"><a href="https://laravel.com" target="_blank"><img src="https://raw.githubusercontent.com/laravel/art/master/logo-lockup/5%20SVG/2%20CMYK/1%20Full%20Color/laravel-logolockup-cmyk-red.svg" width="400" alt="Laravel Logo"></a></p>
|
||||
# Munyi
|
||||
|
||||
<p align="center">
|
||||
<a href="https://github.com/laravel/framework/actions"><img src="https://github.com/laravel/framework/workflows/tests/badge.svg" alt="Build Status"></a>
|
||||
<a href="https://packagist.org/packages/laravel/framework"><img src="https://img.shields.io/packagist/dt/laravel/framework" alt="Total Downloads"></a>
|
||||
<a href="https://packagist.org/packages/laravel/framework"><img src="https://img.shields.io/packagist/v/laravel/framework" alt="Latest Stable Version"></a>
|
||||
<a href="https://packagist.org/packages/laravel/framework"><img src="https://img.shields.io/packagist/l/laravel/framework" alt="License"></a>
|
||||
</p>
|
||||
|
||||
## About Laravel
|
||||
|
||||
Laravel is a web application framework with expressive, elegant syntax. We believe development must be an enjoyable and creative experience to be truly fulfilling. Laravel takes the pain out of development by easing common tasks used in many web projects, such as:
|
||||
|
||||
- [Simple, fast routing engine](https://laravel.com/docs/routing).
|
||||
- [Powerful dependency injection container](https://laravel.com/docs/container).
|
||||
- Multiple back-ends for [session](https://laravel.com/docs/session) and [cache](https://laravel.com/docs/cache) storage.
|
||||
- Expressive, intuitive [database ORM](https://laravel.com/docs/eloquent).
|
||||
- Database agnostic [schema migrations](https://laravel.com/docs/migrations).
|
||||
- [Robust background job processing](https://laravel.com/docs/queues).
|
||||
- [Real-time event broadcasting](https://laravel.com/docs/broadcasting).
|
||||
|
||||
Laravel is accessible, powerful, and provides tools required for large, robust applications.
|
||||
|
||||
## Learning Laravel
|
||||
|
||||
Laravel has the most extensive and thorough [documentation](https://laravel.com/docs) and video tutorial library of all modern web application frameworks, making it a breeze to get started with the framework. You can also check out [Laravel Learn](https://laravel.com/learn), where you will be guided through building a modern Laravel application.
|
||||
|
||||
If you don't feel like reading, [Laracasts](https://laracasts.com) can help. Laracasts contains thousands of video tutorials on a range of topics including Laravel, modern PHP, unit testing, and JavaScript. Boost your skills by digging into our comprehensive video library.
|
||||
|
||||
## Laravel Sponsors
|
||||
|
||||
We would like to extend our thanks to the following sponsors for funding Laravel development. If you are interested in becoming a sponsor, please visit the [Laravel Partners program](https://partners.laravel.com).
|
||||
|
||||
### Premium Partners
|
||||
|
||||
- **[Vehikl](https://vehikl.com)**
|
||||
- **[Tighten Co.](https://tighten.co)**
|
||||
- **[Kirschbaum Development Group](https://kirschbaumdevelopment.com)**
|
||||
- **[64 Robots](https://64robots.com)**
|
||||
- **[Curotec](https://www.curotec.com/services/technologies/laravel)**
|
||||
- **[DevSquad](https://devsquad.com/hire-laravel-developers)**
|
||||
- **[Redberry](https://redberry.international/laravel-development)**
|
||||
- **[Active Logic](https://activelogic.com)**
|
||||
|
||||
## Contributing
|
||||
|
||||
Thank you for considering contributing to the Laravel framework! The contribution guide can be found in the [Laravel documentation](https://laravel.com/docs/contributions).
|
||||
|
||||
## Code of Conduct
|
||||
|
||||
In order to ensure that the Laravel community is welcoming to all, please review and abide by the [Code of Conduct](https://laravel.com/docs/contributions#code-of-conduct).
|
||||
|
||||
## Security Vulnerabilities
|
||||
|
||||
If you discover a security vulnerability within Laravel, please send an e-mail to Taylor Otwell via [taylor@laravel.com](mailto:taylor@laravel.com). All security vulnerabilities will be promptly addressed.
|
||||
|
||||
## License
|
||||
|
||||
The Laravel framework is open-sourced software licensed under the [MIT license](https://opensource.org/licenses/MIT).
|
||||
|
||||
@ -1,58 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class CheckTestDb extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'app:check-test-db';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Ellenőrzi a pillanatnyi adatbázis kapcsolatot és az aktív environmentet.';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$this->newLine();
|
||||
$this->info('--- Adatbázis Kapcsolat Ellenőrzése ---');
|
||||
$this->info('APP_ENV: ' . app()->environment());
|
||||
$this->info('DB_CONNECTION: ' . config('database.default'));
|
||||
$this->info('DB_DATABASE (config): ' . config('database.connections.mysql.database'));
|
||||
$this->info('DB_DATABASE (env): ' . env('DB_DATABASE'));
|
||||
|
||||
try {
|
||||
$dbName = DB::select('SELECT DATABASE() as db')[0]->db;
|
||||
$this->info('TÉNYLEGES ADATBÁZIS (MySQL select): ' . $dbName);
|
||||
|
||||
if (app()->environment() === 'testing' && strtolower($dbName) !== strtolower('d2dTest')) {
|
||||
$this->error('VIGYÁZAT: Teszt környezetben nem a d2dTest adatbázist használod! (Kapcsolódva: ' . $dbName . ')');
|
||||
} elseif (app()->environment() === 'testing' && strtolower($dbName) === strtolower('d2dTest')) {
|
||||
$this->success('Minden rendben: Teszt környezetben a d2dTest adatbázist használod.');
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
$this->error('Hiba az adatbázishoz való csatlakozáskor: ' . $e->getMessage());
|
||||
}
|
||||
$this->newLine();
|
||||
}
|
||||
|
||||
/**
|
||||
* Success message override
|
||||
*/
|
||||
protected function success(string $message)
|
||||
{
|
||||
$this->line("<info>{$message}</info>");
|
||||
}
|
||||
}
|
||||
@ -1,168 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Models\Attachment;
|
||||
use App\Models\Order;
|
||||
use App\Models\OrderArchive;
|
||||
use App\Models\OrderArchivesItem;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
class EmegrendelesCleanup extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'emegrendeles:cleanup {date : A dátum, ami előtti megrendeléseket törölni kell (YYYY-MM-DD)} {--dry-run : Csak szimuláció, nem töröl semmit}';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Megrendelések törlése egy adott dátum előtt az orders és order_archives táblákból.';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*/
|
||||
public function handle(): int
|
||||
{
|
||||
$date = $this->argument('date');
|
||||
|
||||
if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $date)) {
|
||||
$this->error('Érvénytelen dátum formátum. Használd az YYYY-MM-DD formátumot.');
|
||||
return 1;
|
||||
}
|
||||
|
||||
$dryRun = $this->option('dry-run');
|
||||
|
||||
// Számlálás
|
||||
$ordersCount = Order::where('deliveryDate', '<', $date)->count();
|
||||
|
||||
$archiveQuery = OrderArchive::where('deliveryDate', '<', $date);
|
||||
$archivesCount = $archiveQuery->count();
|
||||
|
||||
$itemsCount = OrderArchivesItem::whereIn('order_archive_id', function ($query) use ($date) {
|
||||
$query->select('id')->from('order_archives')->where('deliveryDate', '<', $date);
|
||||
})->count();
|
||||
|
||||
$attachmentsCount = Attachment::whereIn('attachable_id', function ($query) use ($date) {
|
||||
$query->select('id')->from('order_archives')->where('deliveryDate', '<', $date);
|
||||
})->where('attachable_type', OrderArchive::class)->count();
|
||||
|
||||
$this->info("Törlendő elemek száma ($date előtt):");
|
||||
$this->table(
|
||||
['Típus', 'Darabszám'],
|
||||
[
|
||||
['Megrendelések (orders)', $ordersCount],
|
||||
['Archivált megrendelések (order_archives)', $archivesCount],
|
||||
['Archivált tételek (order_archives_items)', $itemsCount],
|
||||
['Csatolt fájlok (attachments)', $attachmentsCount],
|
||||
]
|
||||
);
|
||||
|
||||
// Első megmaradó megrendelés keresése
|
||||
$firstRemainingOrder = Order::where('deliveryDate', '>=', $date)
|
||||
->orderBy('deliveryDate', 'asc')
|
||||
->orderBy('humanId', 'asc')
|
||||
->first();
|
||||
|
||||
$firstRemainingArchive = OrderArchive::where('deliveryDate', '>=', $date)
|
||||
->orderBy('deliveryDate', 'asc')
|
||||
->orderBy('humanId', 'asc')
|
||||
->first();
|
||||
|
||||
$firstRemaining = null;
|
||||
if ($firstRemainingOrder && $firstRemainingArchive) {
|
||||
if ($firstRemainingOrder->deliveryDate < $firstRemainingArchive->deliveryDate) {
|
||||
$firstRemaining = $firstRemainingOrder;
|
||||
} elseif ($firstRemainingOrder->deliveryDate > $firstRemainingArchive->deliveryDate) {
|
||||
$firstRemaining = $firstRemainingArchive;
|
||||
} else {
|
||||
$firstRemaining = ($firstRemainingOrder->humanId <= $firstRemainingArchive->humanId)
|
||||
? $firstRemainingOrder
|
||||
: $firstRemainingArchive;
|
||||
}
|
||||
} else {
|
||||
$firstRemaining = $firstRemainingOrder ?: $firstRemainingArchive;
|
||||
}
|
||||
|
||||
if ($firstRemaining) {
|
||||
$this->info("Az első megmaradó megrendelés:");
|
||||
$this->line("- Human ID: " . ($firstRemaining->humanId ?: 'N/A'));
|
||||
$this->line("- Dátum: " . $firstRemaining->deliveryDate);
|
||||
} else {
|
||||
$this->warn("Nincs megmaradó megrendelés a megadott dátumtól kezdődően.");
|
||||
}
|
||||
|
||||
if ($dryRun) {
|
||||
$this->info('Dry-run mód: nem történt törlés.');
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ($ordersCount === 0 && $archivesCount === 0) {
|
||||
$this->info('Nincs törlendő elem.');
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!$this->confirm('Biztosan törölni szeretnéd a megadott elemeket?')) {
|
||||
$this->info('Művelet megszakítva.');
|
||||
return 0;
|
||||
}
|
||||
|
||||
$this->info('Törlés megkezdése...');
|
||||
|
||||
\Illuminate\Support\Facades\Schema::disableForeignKeyConstraints();
|
||||
|
||||
try {
|
||||
// Orders törlése
|
||||
Order::where('deliveryDate', '<', $date)->delete();
|
||||
$this->info('Megrendelések törölve.');
|
||||
|
||||
// Archivált adatok törlése optimalizáltan
|
||||
$this->info('Archivált adatok törlése...');
|
||||
$bar = $this->output->createProgressBar($archivesCount);
|
||||
$bar->start();
|
||||
|
||||
OrderArchive::where('deliveryDate', '<', $date)->chunkById(1000, function ($archives) use ($bar) {
|
||||
$archiveIds = $archives->pluck('id')->toArray();
|
||||
|
||||
// Kapcsolódó tételek törlése tömegesen
|
||||
OrderArchivesItem::whereIn('order_archive_id', $archiveIds)->delete();
|
||||
|
||||
// Csatolmányok és fizikai fájlok kezelése
|
||||
$attachments = Attachment::whereIn('attachable_id', $archiveIds)
|
||||
->where('attachable_type', OrderArchive::class)
|
||||
->get();
|
||||
|
||||
if ($attachments->isNotEmpty()) {
|
||||
$filePaths = $attachments->map(function ($attachment) {
|
||||
return $attachment->path . DIRECTORY_SEPARATOR . $attachment->filename;
|
||||
})->toArray();
|
||||
|
||||
// Fizikai fájlok törlése a tárhelyről kötegelve
|
||||
Storage::disk('attachments')->delete($filePaths);
|
||||
|
||||
// Attachment rekordok törlése az adatbázisból
|
||||
Attachment::whereIn('id', $attachments->pluck('id'))->delete();
|
||||
}
|
||||
|
||||
// Maguk az archívum rekordok törlése tömegesen
|
||||
OrderArchive::whereIn('id', $archiveIds)->delete();
|
||||
|
||||
$bar->advance($archives->count());
|
||||
});
|
||||
|
||||
$bar->finish();
|
||||
$this->info("");
|
||||
$this->info('Archivált megrendelések és kapcsolódó elemek törölve.');
|
||||
} finally {
|
||||
\Illuminate\Support\Facades\Schema::enableForeignKeyConstraints();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -1,100 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Enums\DbStatusFieldEnum;
|
||||
use App\Enums\ProductTypeEnum;
|
||||
use App\Models\ProductGroup;
|
||||
use Illuminate\Console\Command;
|
||||
use Rap2hpoutre\FastExcel\FastExcel;
|
||||
|
||||
class EmegrendelesImportProductGroup extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'emegrendeles:importProductGroup {--file= : default database/import/productGroup.xlsx}';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Product group importer';
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
private function parseNodes($parentNode, $collection)
|
||||
{
|
||||
$parentNodeName = $parentNode->name;
|
||||
$rootNode = false;
|
||||
if (! isset($parentNode->parent_id) || is_null($parentNode->parent_id)) {
|
||||
// o maga a root Node
|
||||
$rootNode = true;
|
||||
}
|
||||
|
||||
foreach ($collection as $row) {
|
||||
if (isset($row[$parentNodeName])
|
||||
&& strlen($row[$parentNodeName]) > 0
|
||||
&& $row[$parentNodeName] !== 'n/a'
|
||||
) {
|
||||
|
||||
$node = [
|
||||
'name' => $row[$parentNodeName],
|
||||
'status' => DbStatusFieldEnum::active,
|
||||
|
||||
];
|
||||
if ($rootNode) {
|
||||
if (ProductTypeEnum::hasValue($node['name'])) {
|
||||
$node['type'] = ProductTypeEnum::getKey($node['name']);
|
||||
} else {
|
||||
$node['type'] = ProductTypeEnum::X();
|
||||
}
|
||||
} else {
|
||||
$node['type'] = $parentNode->type;
|
||||
|
||||
}
|
||||
$treeNode = $parentNode->children()->create($node);
|
||||
$this->parseNodes($treeNode, $collection);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*/
|
||||
public function handle(): int
|
||||
{
|
||||
// $name = $this->argument('name');
|
||||
$collection = (new FastExcel)->sheet(1)->import(
|
||||
database_path().'/import/productGroup.xlsx'
|
||||
);
|
||||
|
||||
$rootName = array_keys($collection->first())[0];
|
||||
$tree = [
|
||||
'name' => $rootName,
|
||||
'status' => DbStatusFieldEnum::active,
|
||||
];
|
||||
\Schema::disableForeignKeyConstraints();
|
||||
ProductGroup::truncate();
|
||||
|
||||
$rootNode = ProductGroup::create($tree);
|
||||
$this->parseNodes($rootNode, $collection);
|
||||
|
||||
\Schema::enableForeignKeyConstraints();
|
||||
$this->info('Import End');
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -1,191 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Models\Order;
|
||||
use App\Models\OrderNumber;
|
||||
use App\Models\ProductGroup;
|
||||
use Box\Spout\Common\Exception\IOException;
|
||||
use Box\Spout\Common\Exception\UnsupportedTypeException;
|
||||
use Box\Spout\Reader\Exception\ReaderNotOpenedException;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
class EmegrendelesOrderNumberChange extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'emegrendeles:orderNumberChange {workerNumber=1}';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Change and convert order numbers ';
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
private function getMaxSupplierOrderNumber(): int
|
||||
{
|
||||
// SELECT max(supplierOrderNumber) FROM `order_archives` WHERE deliveryDate>'2025-01-01';
|
||||
|
||||
return \DB::table('order_archives')
|
||||
->where('deliveryDate', '>', '2025-01-01')
|
||||
->max('supplierOrderNumber');
|
||||
}
|
||||
|
||||
private function setDefaultOrderNumberForSuppliers(): void
|
||||
{
|
||||
$this->info('Start setDefaultOrderNumberForSuppliers');
|
||||
$supplierIds = \DB::table('order_archives')
|
||||
->selectRaw('DISTINCT(supplier_id)')
|
||||
->orderBy('supplier_id')
|
||||
->get();
|
||||
foreach ($supplierIds as $supplierId) {
|
||||
|
||||
$o = OrderNumber::create([
|
||||
'id' => $this->startOrderNumber,
|
||||
'year' => 25,
|
||||
'supplier_id' => $supplierId->supplier_id,
|
||||
'order_id' => 1000 + $supplierId->supplier_id,
|
||||
]);
|
||||
|
||||
}
|
||||
$this->info('End setDefaultOrderNumberForSuppliers');
|
||||
}
|
||||
|
||||
private function changeTable()
|
||||
{
|
||||
$this->info('Start changeTable');
|
||||
$this->info('change id field, and add supplier_order_number field');
|
||||
\Schema::table('order_numbers', function (\Illuminate\Database\Schema\Blueprint $table) {
|
||||
|
||||
$table->integer('id')->change()->unsigned();
|
||||
$table->dropIndex('PRIMARY');
|
||||
$table->integer('supplier_order_number')->unsigned()->after('id');
|
||||
// $table->string('new_column');
|
||||
// $table->dropColumn('old_column');
|
||||
// $table->integer('existing_column')->nullable();
|
||||
});
|
||||
$this->info('set supplier_order_number = id');
|
||||
\DB::table('order_numbers')->update(['supplier_order_number' => \DB::raw('id')]);
|
||||
$startId = 10000;
|
||||
$this->info('recreate id field value');
|
||||
foreach (\DB::table('order_numbers')->get() as $orderNumber) {
|
||||
\DB::table('order_numbers')
|
||||
->where('id', $orderNumber->id)
|
||||
->where('order_id', $orderNumber->order_id)
|
||||
->update(['id' => $startId]);
|
||||
$startId++;
|
||||
}
|
||||
\Schema::table('order_numbers', function (\Illuminate\Database\Schema\Blueprint $table) {
|
||||
/*
|
||||
ALTER TABLE `order_numbers` CHANGE `id` `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, add PRIMARY KEY (`id`);
|
||||
*/
|
||||
// $table->integer('id')->change()->autoIncrement()->primary();
|
||||
$this->info(' set id field auto increment and primary key');
|
||||
\DB::statement('ALTER TABLE `order_numbers` CHANGE `id` `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, ADD PRIMARY KEY (`id`)');
|
||||
$this->info(' set unique key on supplier_order_number, year, supplier_id');
|
||||
$table->unique(['supplier_order_number', 'year', 'supplier_id'], 'unique_supplier_order_number_year_supplier_id');
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private function createSupplierOrderNumber(int $orderId): ?array
|
||||
{
|
||||
$ret = [];
|
||||
if ($Order = Order::find($orderId)) {
|
||||
// dd($Order->toArray());
|
||||
if ($o = OrderNumber::where('order_id', $orderId)->get()->first()) {
|
||||
} else {
|
||||
$orderYear = Carbon::createFromDate($Order->deliveryDate)->format('y');
|
||||
$maxSupplierOrderNumber = OrderNumber::where('supplier_id', $Order->supplier_id)
|
||||
->where('year', $orderYear)
|
||||
->max('supplier_order_number');
|
||||
$nextSupplierOrderNumber = $maxSupplierOrderNumber ? ($maxSupplierOrderNumber + 1) : 1;
|
||||
$this->info($maxSupplierOrderNumber.' '.$nextSupplierOrderNumber);
|
||||
$maxRetry = 5;
|
||||
while ($maxRetry > 0) {
|
||||
try {
|
||||
$o = OrderNumber::create([
|
||||
'supplier_order_number' => $nextSupplierOrderNumber,
|
||||
'year' => $orderYear,
|
||||
'supplier_id' => $Order->supplier_id,
|
||||
|
||||
]);
|
||||
$o->order_id = $orderId;
|
||||
$o->save();
|
||||
break;
|
||||
} catch (\Exception $e) {
|
||||
$this->error('Error creating OrderNumber for supplier:'.$Order->supplier_id.' - '.$e->getMessage());
|
||||
$maxRetry--;
|
||||
$nextSupplierOrderNumber++;
|
||||
usleep(rand(400, 600));
|
||||
}
|
||||
}
|
||||
if (! $o) {
|
||||
$this->error('Error creating OrderNumber for supplier:'.$Order->supplier_id.' - maxRetry');
|
||||
throw new \Exception('Error creating OrderNumber for supplier:'.$Order->supplier_id);
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
$ret = $o->toArray();
|
||||
} else {
|
||||
$ret = null;
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
*
|
||||
* @throws IOException
|
||||
* @throws UnsupportedTypeException
|
||||
* @throws ReaderNotOpenedException
|
||||
*/
|
||||
public function handle(): int
|
||||
{
|
||||
var_dump(config('app.env', 'env'.now()));
|
||||
var_dump(config('app.stage', 'fuck'.now()));
|
||||
|
||||
$this->changeTable();
|
||||
/*
|
||||
$supplierOrderNumber=$this->createSupplierOrderNumber(16605);
|
||||
dd($supplierOrderNumber);
|
||||
$this->info("created supplier order number $supplierOrderNumber");
|
||||
*/
|
||||
|
||||
// $this->generateRandomSupplierNumber();
|
||||
return 0;
|
||||
/*
|
||||
|
||||
ALTER TABLE `order_numbers` CHANGE `id` `id` INT(10) UNSIGNED NOT NULL;
|
||||
ALTER TABLE `order_numbers` DROP PRIMARY KEY;
|
||||
ALTER TABLE `order_numbers` ADD `supplier_order_number` INT UNSIGNED NOT NULL AFTER `id`;
|
||||
|
||||
|
||||
//$name = $this->argument('name');
|
||||
\Schema::disableForeignKeyConstraints();
|
||||
ProductGroup::truncate();
|
||||
\Schema::enableForeignKeyConstraints();
|
||||
$this->info('Import End');
|
||||
return 0;
|
||||
*/
|
||||
}
|
||||
}
|
||||
@ -1,135 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Models\OrderNumber;
|
||||
use App\Models\ProductGroup;
|
||||
use Box\Spout\Common\Exception\IOException;
|
||||
use Box\Spout\Common\Exception\UnsupportedTypeException;
|
||||
use Box\Spout\Reader\Exception\ReaderNotOpenedException;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
class EmegrendelesOrderNumberTest extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'emegrendeles:orderNumberTest {workerNumber=1}';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Recovery and test order numbers from emegrendeles';
|
||||
|
||||
protected $startOrderNumber = 4999;
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
private function getMaxSupplierOrderNumber(): int
|
||||
{
|
||||
// SELECT max(supplierOrderNumber) FROM `order_archives` WHERE deliveryDate>'2025-01-01';
|
||||
|
||||
return \DB::table('order_archives')
|
||||
->where('deliveryDate', '>', '2025-01-01')
|
||||
->max('supplierOrderNumber');
|
||||
}
|
||||
|
||||
private function setDefaultOrderNumberForSuppliers(): void
|
||||
{
|
||||
$this->info('Start setDefaultOrderNumberForSuppliers');
|
||||
$supplierIds = \DB::table('order_archives')
|
||||
->selectRaw('DISTINCT(supplier_id)')
|
||||
->orderBy('supplier_id')
|
||||
->get();
|
||||
foreach ($supplierIds as $supplierId) {
|
||||
|
||||
$o = OrderNumber::create([
|
||||
'id' => $this->startOrderNumber,
|
||||
'year' => 25,
|
||||
'supplier_id' => $supplierId->supplier_id,
|
||||
'order_id' => 1000 + $supplierId->supplier_id,
|
||||
]);
|
||||
|
||||
}
|
||||
$this->info('End setDefaultOrderNumberForSuppliers');
|
||||
}
|
||||
|
||||
private function generateRandomSupplierNumber($count = 10000)
|
||||
{
|
||||
$this->info('Start generateRandomSupplierNumber');
|
||||
$supplierIds = \DB::table('order_archives')
|
||||
->selectRaw('DISTINCT(supplier_id)')
|
||||
->orderBy('supplier_id')
|
||||
->get();
|
||||
$supplierIds = $supplierIds->pluck('supplier_id')->toArray();
|
||||
$startOrderID = $this->getMaxSupplierOrderNumber();
|
||||
$startOrderID += $this->argument('workerNumber') * $count;
|
||||
$this->info('Start generateRandomSupplierNumber from orderID:'.$startOrderID);
|
||||
for ($i = 0; $i < $count; $i++) {
|
||||
$randomSupplierId = $supplierIds[array_rand($supplierIds)];
|
||||
try {
|
||||
$o = OrderNumber::create([
|
||||
'year' => 25,
|
||||
'supplier_id' => $randomSupplierId,
|
||||
'order_id' => $startOrderID + $i,
|
||||
]);
|
||||
$this->info('Created OrderNumber: '.$o->id.' for supplier:'.$o->supplier_id);
|
||||
} catch (\Exception $e) {
|
||||
$this->error('Error creating Order for supplier:'.$randomSupplierId.' - '.$e->getMessage());
|
||||
}
|
||||
usleep(rand(150, 600));
|
||||
}
|
||||
$this->info('End generateRandomSupplierNumber');
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
*
|
||||
* @throws IOException
|
||||
* @throws UnsupportedTypeException
|
||||
* @throws ReaderNotOpenedException
|
||||
*/
|
||||
public function handle(): int
|
||||
{
|
||||
var_dump(config('app.env', 'env'.now()));
|
||||
var_dump(config('app.stage', 'fuck'.now()));
|
||||
|
||||
$DBMaxSupplierOrderNumber = $this->getMaxSupplierOrderNumber();
|
||||
if ($this->startOrderNumber < $DBMaxSupplierOrderNumber) {
|
||||
$this->error('Max startOrderNumber wrong. Set:'.
|
||||
$this->startOrderNumber.
|
||||
' inDB:'.$DBMaxSupplierOrderNumber
|
||||
|
||||
);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
\DB::table('order_numbers')->truncate();
|
||||
$this->setDefaultOrderNumberForSuppliers();
|
||||
|
||||
// $this->generateRandomSupplierNumber();
|
||||
return 0;
|
||||
/*
|
||||
//$name = $this->argument('name');
|
||||
\Schema::disableForeignKeyConstraints();
|
||||
ProductGroup::truncate();
|
||||
\Schema::enableForeignKeyConstraints();
|
||||
$this->info('Import End');
|
||||
return 0;
|
||||
*/
|
||||
}
|
||||
}
|
||||
@ -1,325 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Enums\DbStatusFieldEnum;
|
||||
use App\Models\Contact;
|
||||
use App\Models\ProfitCenter;
|
||||
use App\Models\Role;
|
||||
use App\Models\User;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
class EmegrendelesimportProfitCenterWithUsers extends Command
|
||||
{
|
||||
private string $defaultFile = 'profitCenterWithUser.php';
|
||||
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'emegrendeles:importProfitCenterWithUsers {--file= : default database/import/*defaultFile*}
|
||||
{--doc : print documentation }';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'ProfitCenter import with user';
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->signature = str_replace('*defaultFile*', $this->defaultFile, $this->signature);
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
public function printDoc()
|
||||
{
|
||||
$this->info("
|
||||
1: source malvac.e98.hu localhost - fs.emegrendeles.hu - felhasznalo
|
||||
2: sql Select:
|
||||
SELECT
|
||||
f.kod id,
|
||||
f.nev userName,
|
||||
f.jelszo userPassword,
|
||||
k_email userEmail,
|
||||
f.statusz,
|
||||
fa.nev name,
|
||||
fa.irsz postCode,
|
||||
fa.varos city,
|
||||
fa.cim street,
|
||||
fa.megjegy note,
|
||||
k_email email,
|
||||
k_tel phone,
|
||||
k_mob mobil,
|
||||
k_nev contactName,
|
||||
k_email contactEmail,
|
||||
k_tel contactPhone,
|
||||
k_mob contactMobil
|
||||
FROM `felhasznalo` as f
|
||||
left join felhasznalo_adat fa on fa.kod=f.kod
|
||||
WHERE f.`statusz`='F'
|
||||
order by name
|
||||
3: export json
|
||||
");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* From https://stackoverflow.com/a/19136663/319266
|
||||
*/
|
||||
public function stripComments(string $str = '')
|
||||
{
|
||||
$str = preg_replace('!/\*.*?\*/!s', '', $str);
|
||||
$str = preg_replace('/\n\s*\n/', "\n", $str);
|
||||
|
||||
return $str;
|
||||
}
|
||||
|
||||
private function stripPrefixedItemFromArray($data, $prefix)
|
||||
{
|
||||
if (is_array($prefix)) {
|
||||
foreach ($prefix as $pre) {
|
||||
$data = $this->stripPrefixedItemFromArray($data, $pre);
|
||||
}
|
||||
} else {
|
||||
foreach ($data as $k => $v) {
|
||||
if (strpos($k, $prefix) !== false) {
|
||||
unset($data[$k]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
private function getPrefixKeyedDataFromArray($data, $prefix)
|
||||
{
|
||||
$retArray = [];
|
||||
foreach ($data as $k => $v) {
|
||||
if (strpos($k, $prefix) !== false) {
|
||||
$key = str_replace($prefix, '', $k);
|
||||
$key = lcfirst($key);
|
||||
$retArray[$key] = $v;
|
||||
}
|
||||
}
|
||||
|
||||
return $retArray;
|
||||
}
|
||||
|
||||
private function getUserDataFromArray($data)
|
||||
{
|
||||
$userData = $this->getPrefixKeyedDataFromArray($data, 'user');
|
||||
$userData['password'] = \Hash::make($userData['password']);
|
||||
|
||||
return $userData;
|
||||
}
|
||||
|
||||
private function getContactDataFromArray($data)
|
||||
{
|
||||
return $this->getPrefixKeyedDataFromArray($data, 'contact');
|
||||
}
|
||||
|
||||
private function getAcceptedProfitCenterData($data)
|
||||
{
|
||||
$acceptedKey = [
|
||||
'name',
|
||||
'hooreycaId',
|
||||
'nameId',
|
||||
'email',
|
||||
'postCode',
|
||||
'city',
|
||||
'street',
|
||||
'phone',
|
||||
'mobil',
|
||||
'note',
|
||||
];
|
||||
$retData = [];
|
||||
foreach ($data as $k => $v) {
|
||||
if (in_array($k, $acceptedKey)) {
|
||||
$retData[$k] = $v;
|
||||
}
|
||||
}
|
||||
|
||||
return $retData;
|
||||
}
|
||||
|
||||
private function fillNeedProfitCenterData($data,
|
||||
$num = null,
|
||||
?bool $convertNull = true)
|
||||
{
|
||||
if (! $num) {
|
||||
$num = random_int(1000, 9999);
|
||||
}
|
||||
$data = $this->getAcceptedProfitCenterData($data);
|
||||
if (! isset($data['hooreycaId'])) {
|
||||
$data['hooreycaId'] = 'H'.$num;
|
||||
}
|
||||
if ($convertNull) {
|
||||
foreach ($data as $k => $v) {
|
||||
if ($v === '') {
|
||||
$data[$k] = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
$data['status'] = DbStatusFieldEnum::active;
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
private function getAcceptedContactData($data)
|
||||
{
|
||||
$acceptedKey = [
|
||||
'name',
|
||||
'email',
|
||||
'phone',
|
||||
'note',
|
||||
];
|
||||
if (isset($data['mobil']) && ! is_null($data['mobil']) && $data['mobil'] !== '') {
|
||||
$data['phone'] = $data['mobil'];
|
||||
}
|
||||
$retData = [];
|
||||
foreach ($data as $k => $v) {
|
||||
if (in_array($k, $acceptedKey)) {
|
||||
$retData[$k] = $v;
|
||||
}
|
||||
}
|
||||
|
||||
return $retData;
|
||||
}
|
||||
|
||||
private function fillNeedContactData($data,
|
||||
$num = null,
|
||||
?bool $convertNull = true)
|
||||
{
|
||||
$data = $this->getAcceptedContactData($data);
|
||||
if ($convertNull) {
|
||||
foreach ($data as $k => $v) {
|
||||
if ($v === '') {
|
||||
$data[$k] = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
$data['status'] = DbStatusFieldEnum::active;
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
private function createUser($userData)
|
||||
{
|
||||
if ($user = User::where('email', $userData['email'])->first()) {
|
||||
$emailPieces = explode('@', $userData['email']);
|
||||
$userData['email'] = $emailPieces[0].time().'@'.$emailPieces[1];
|
||||
$this->error('Presents user:'.$userData['name'].' rename email:'.$userData['email']);
|
||||
/* print var_export($userData,true);
|
||||
print var_export($user->toArray(),true);
|
||||
die();*/
|
||||
} else {
|
||||
}
|
||||
$user = User::Create($userData);
|
||||
$this->info('User created:'.$user->name);
|
||||
|
||||
return $user;
|
||||
}
|
||||
|
||||
private ?Role $RoleProfitCenter = null;
|
||||
|
||||
private function initProfitCenterRole()
|
||||
{
|
||||
$this->RoleProfitCenter = Role::where('name', 'profit-center')->first();
|
||||
}
|
||||
|
||||
public function importFile($file, $format = 'JSON')
|
||||
{
|
||||
$this->initProfitCenterRole();
|
||||
$this->info('inport fileName:'.$file.' format'.$format);
|
||||
$file = base_path().DIRECTORY_SEPARATOR.'database'.DIRECTORY_SEPARATOR.'import'.DIRECTORY_SEPARATOR.$file;
|
||||
$this->info('file:'.$file);
|
||||
|
||||
switch ($format) {
|
||||
case 'JSON':
|
||||
try {
|
||||
// json_decode("{", false, 512, JSON_THROW_ON_ERROR);
|
||||
$jsonStr = $this->stripComments(file_get_contents($file));
|
||||
$jsonStr = ltrim($jsonStr);
|
||||
$itemsArray = json_decode($jsonStr, true, 512, JSON_THROW_ON_ERROR);
|
||||
} catch (\JsonException $exception) {
|
||||
echo $exception->getMessage(); // displays "Syntax error"
|
||||
exit();
|
||||
}
|
||||
break;
|
||||
case 'PHP':
|
||||
require_once $file;
|
||||
$itemsArray = $f;
|
||||
break;
|
||||
}
|
||||
auth()->loginUsingId(1);
|
||||
|
||||
foreach ($itemsArray as $k => $item) {
|
||||
|
||||
/*
|
||||
array (
|
||||
'id' => 182,
|
||||
'userName' => 'atrium',
|
||||
'userPass' => 'atriumetterem',
|
||||
'statusz' => 'F',
|
||||
'name' => 'Átrium',
|
||||
'postCode' => 1138,
|
||||
'city' => 'Budapest',
|
||||
'street' => 'Váci út 45.',
|
||||
'note' => '',
|
||||
'contactName' => 'Szőnyi Iván',
|
||||
'contactEmail' => 'atrium@eurest.hu',
|
||||
'contactPhone' => '',
|
||||
'contactMobil' => '06-30/207-0148',
|
||||
)
|
||||
*/
|
||||
$userData = $this->getUserDataFromArray($item);
|
||||
$contactData = $this->getContactDataFromArray($item);
|
||||
/*
|
||||
print var_export($item,true);
|
||||
*/
|
||||
|
||||
$profitCenterData = $this->stripPrefixedItemFromArray($item, ['user', 'contact']);
|
||||
$profitCenterData = $this->fillNeedProfitCenterData($profitCenterData, $k + 1);
|
||||
$ProfitCenter = ProfitCenter::create($profitCenterData);
|
||||
$contactData = $this->fillNeedContactData($contactData);
|
||||
$Contact = Contact::create($contactData);
|
||||
$this->info('Contact created:'.$Contact->name);
|
||||
$User = $this->createUser($userData);
|
||||
$User->syncRolesWithoutDetaching([$this->RoleProfitCenter]);
|
||||
$ProfitCenter->users()->syncWithoutDetaching($User);
|
||||
$ProfitCenter->syncContactRelations([$Contact->id]);
|
||||
$this->info('ProfitCenter created:'.$ProfitCenter->name);
|
||||
|
||||
}
|
||||
// $this->info(var_export($Json,true));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*/
|
||||
public function handle(): int
|
||||
{
|
||||
// $name = $this->argument('name');
|
||||
if ($this->option('doc')) {
|
||||
return $this->printDoc();
|
||||
}
|
||||
$file = $this->defaultFile;
|
||||
if ($this->option('file')) {
|
||||
$file = $this->option('file');
|
||||
}
|
||||
$this->importFile($file, 'PHP');
|
||||
$this->info('Import End');
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -1,181 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Models\Attachment;
|
||||
use App\Models\PriceList;
|
||||
use App\Models\PricelistFile;
|
||||
use App\Models\PricelistFileLine;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
class PricelistCleanup extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'pricelist:cleanup {date : A dátum, ami előtti árlistákat törölni kell (YYYY-MM-DD)} {--dry-run : Csak szimuláció, nem töröl semmit}';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Árlisták és kapcsolódó adatok törlése egy adott dátum előtt.';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*/
|
||||
public function handle(): int
|
||||
{
|
||||
$date = $this->argument('date');
|
||||
|
||||
if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $date)) {
|
||||
$this->error('Érvénytelen dátum formátum. Használd az YYYY-MM-DD formátumot.');
|
||||
return 1;
|
||||
}
|
||||
|
||||
$dryRun = $this->option('dry-run');
|
||||
|
||||
// Számlálás
|
||||
$priceListsCount = PriceList::where('available', '<', $date)->count();
|
||||
|
||||
$priceListPricesCount = DB::table('price_list_prices')
|
||||
->whereIn('price_list_id', function ($query) use ($date) {
|
||||
$query->select('id')->from('price_lists')->where('available', '<', $date);
|
||||
})->count();
|
||||
|
||||
$pricelistFilesCount = PricelistFile::where('available_date', '<', $date)->count();
|
||||
|
||||
$pricelistFileLinesCount = PricelistFileLine::whereIn('pricelist_file_id', function ($query) use ($date) {
|
||||
$query->select('id')->from('pricelist_files')->where('available_date', '<', $date);
|
||||
})->count();
|
||||
|
||||
$attachmentsCount = Attachment::whereIn('attachable_id', function ($query) use ($date) {
|
||||
$query->select('id')->from('price_lists')->where('available', '<', $date);
|
||||
})->where('attachable_type', PriceList::class)
|
||||
->orWhere(function($query) use ($date) {
|
||||
$query->whereIn('attachable_id', function ($subQuery) use ($date) {
|
||||
$subQuery->select('id')->from('pricelist_files')->where('available_date', '<', $date);
|
||||
})->where('attachable_type', PricelistFile::class);
|
||||
})->count();
|
||||
|
||||
$this->info("Törlendő elemek száma ($date előtt):");
|
||||
$this->table(
|
||||
['Típus', 'Darabszám'],
|
||||
[
|
||||
['Árlisták (price_lists)', $priceListsCount],
|
||||
['Árlista árak (price_list_prices)', $priceListPricesCount],
|
||||
['Árlista fájlok (pricelist_files)', $pricelistFilesCount],
|
||||
['Árlista fájl sorok (pricelist_file_lines)', $pricelistFileLinesCount],
|
||||
['Csatolt fájlok (attachments)', $attachmentsCount],
|
||||
]
|
||||
);
|
||||
|
||||
if ($dryRun) {
|
||||
$this->info('Dry-run mód: nem történt törlés.');
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ($priceListsCount === 0 && $pricelistFilesCount === 0) {
|
||||
$this->info('Nincs törlendő elem.');
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!$this->confirm('Biztosan törölni szeretnéd a megadott elemeket?')) {
|
||||
$this->info('Művelet megszakítva.');
|
||||
return 0;
|
||||
}
|
||||
|
||||
$this->info('Törlés megkezdése...');
|
||||
\Illuminate\Support\Facades\Schema::disableForeignKeyConstraints();
|
||||
// PriceLists törlése optimalizáltan
|
||||
if ($priceListsCount > 0) {
|
||||
$this->info('Árlisták és kapcsolódó árak törlése...');
|
||||
$bar = $this->output->createProgressBar($priceListsCount);
|
||||
$bar->start();
|
||||
|
||||
PriceList::where('available', '<', $date)->chunkById(1000, function ($priceLists) use ($bar) {
|
||||
$ids = $priceLists->pluck('id')->toArray();
|
||||
|
||||
// Kapcsolódó árak törlése
|
||||
DB::table('price_list_prices')->whereIn('price_list_id', $ids)->delete();
|
||||
|
||||
// Csatolmányok kezelése
|
||||
$attachments = Attachment::whereIn('attachable_id', $ids)
|
||||
->where('attachable_type', PriceList::class)
|
||||
->get();
|
||||
|
||||
$this->deleteAttachments($attachments);
|
||||
|
||||
// Maguk a rekordok törlése
|
||||
PriceList::whereIn('id', $ids)->delete();
|
||||
|
||||
$bar->advance($priceLists->count());
|
||||
});
|
||||
|
||||
$bar->finish();
|
||||
$this->info("");
|
||||
}
|
||||
|
||||
// PricelistFiles törlése optimalizáltan
|
||||
if ($pricelistFilesCount > 0) {
|
||||
$this->info('Árlista fájlok és kapcsolódó sorok törlése...');
|
||||
$bar = $this->output->createProgressBar($pricelistFilesCount);
|
||||
$bar->start();
|
||||
|
||||
PricelistFile::where('available_date', '<', $date)->chunkById(1000, function ($files) use ($bar) {
|
||||
$ids = $files->pluck('id')->toArray();
|
||||
|
||||
// Kapcsolódó sorok törlése
|
||||
PricelistFileLine::whereIn('pricelist_file_id', $ids)->delete();
|
||||
|
||||
// Csatolmányok kezelése
|
||||
$attachments = Attachment::whereIn('attachable_id', $ids)
|
||||
->where('attachable_type', PricelistFile::class)
|
||||
->get();
|
||||
|
||||
$this->deleteAttachments($attachments);
|
||||
|
||||
// Maguk a rekordok törlése
|
||||
PricelistFile::whereIn('id', $ids)->delete();
|
||||
|
||||
$bar->advance($files->count());
|
||||
});
|
||||
|
||||
$bar->finish();
|
||||
$this->info("");
|
||||
}
|
||||
|
||||
$this->info('A tisztítás sikeresen befejeződött.');
|
||||
\Illuminate\Support\Facades\Schema::enableForeignKeyConstraints();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Csatolmányok és fizikai fájlok törlése
|
||||
*/
|
||||
protected function deleteAttachments($attachments): void
|
||||
{
|
||||
if ($attachments->isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$filePaths = $attachments->map(function ($attachment) {
|
||||
return $attachment->path . DIRECTORY_SEPARATOR . $attachment->filename;
|
||||
})->toArray();
|
||||
|
||||
// Fizikai fájlok törlése (feltételezve az 'attachments' disket, mint az EmegrendelesCleanup-nál)
|
||||
try {
|
||||
Storage::disk('attachments')->delete($filePaths);
|
||||
} catch (\Exception $e) {
|
||||
$this->warn('Hiba a fizikai fájlok törlésekor: ' . $e->getMessage());
|
||||
}
|
||||
|
||||
// Attachment rekordok törlése
|
||||
Attachment::whereIn('id', $attachments->pluck('id'))->delete();
|
||||
}
|
||||
}
|
||||
@ -1,51 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Models\PricelistFile;
|
||||
use App\Services\PricelistFileProcessService;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
class PricelistProcessCommand extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'pricelist:process {id}';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Elindítja a megadott azonosítójú árlista fájl kezdeti feldolgozási láncát (Pre-process -> Validation)';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*/
|
||||
public function handle(PricelistFileProcessService $service): int
|
||||
{
|
||||
$id = $this->argument('id');
|
||||
$pricelistFile = PricelistFile::find($id);
|
||||
|
||||
if (!$pricelistFile) {
|
||||
$this->error("A(z) {$id} ID-vel rendelkező árlista fájl nem található.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
$this->info("Folyamat elindítása: {$pricelistFile->filename} (ID: {$id})");
|
||||
$this->info("Workflow állapotok alaphelyzetbe állítása...");
|
||||
|
||||
try {
|
||||
$service->resetWorkflow($pricelistFile);
|
||||
$service->dispatchInitialChain($pricelistFile);
|
||||
$this->info("Az árlista feldolgozási lánc (Pre-process -> Validation) sikeresen ütemezve.");
|
||||
return 0;
|
||||
} catch (\Exception $e) {
|
||||
$this->error("Hiba történt a folyamat indításakor: " . $e->getMessage());
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,89 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class QueueListCommand extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'queue:list {--queue= : Szűrés a queue nevére} {--failed : A hibás jobok kilistázása}';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Kilistázza a várólistán lévő (vagy hibás) jobokat táblázatos formában';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*/
|
||||
public function handle(): int
|
||||
{
|
||||
$queueFilter = $this->option('queue');
|
||||
$showFailed = $this->option('failed');
|
||||
|
||||
$tableName = $showFailed ? 'failed_jobs' : 'jobs';
|
||||
|
||||
if (!Schema::hasTable($tableName)) {
|
||||
$this->error("A(z) {$tableName} tábla nem létezik.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
$query = DB::table($tableName);
|
||||
|
||||
if ($queueFilter) {
|
||||
$query->where('queue', $queueFilter);
|
||||
}
|
||||
|
||||
$jobs = $query->orderBy($showFailed ? 'failed_at' : 'created_at', 'desc')->get();
|
||||
|
||||
if ($jobs->isEmpty()) {
|
||||
$this->info("Nincsenek " . ($showFailed ? "hibás " : "") . "jobok a várólistán.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
$tableData = $jobs->map(function ($job) use ($showFailed) {
|
||||
$payload = json_decode($job->payload, true);
|
||||
$displayName = $payload['displayName'] ?? 'Ismeretlen';
|
||||
|
||||
if ($showFailed) {
|
||||
return [
|
||||
'ID' => $job->id,
|
||||
'Queue' => $job->queue,
|
||||
'Job Class' => $displayName,
|
||||
'Failed At' => $job->failed_at,
|
||||
'Exception' => substr($job->exception, 0, 70) . '...',
|
||||
];
|
||||
}
|
||||
|
||||
return [
|
||||
'ID' => $job->id,
|
||||
'Queue' => $job->queue,
|
||||
'Job Class' => $displayName,
|
||||
'Attempts' => $job->attempts,
|
||||
'Reserved At' => $job->reserved_at ? Carbon::createFromTimestamp($job->reserved_at)->format('Y.m.d H:i:s') : 'Nincs lefoglalva',
|
||||
'Available At' => Carbon::createFromTimestamp($job->available_at)->format('Y.m.d H:i:s'),
|
||||
'Created At' => Carbon::createFromTimestamp($job->created_at)->format('Y.m.d H:i:s'),
|
||||
];
|
||||
});
|
||||
|
||||
if ($showFailed) {
|
||||
$headers = ['ID', 'Queue', 'Job Class', 'Failed At', 'Exception'];
|
||||
} else {
|
||||
$headers = ['ID', 'Queue', 'Job Class', 'Próbálkozások', 'Lefoglalva', 'Elérhető', 'Létrehozva'];
|
||||
}
|
||||
|
||||
$this->table($headers, $tableData);
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -1,44 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
class SyncWorkCalendar extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'app:sync-work-calendar {year? : A szinkronizálandó év (alapértelmezett: aktuális)}';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Munkaszüneti napok szinkronizálása külső API-ból';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*/
|
||||
public function handle(\App\Services\WorkCalendarService $service): int
|
||||
{
|
||||
$year = $this->argument('year') ? (int) $this->argument('year') : now()->year;
|
||||
|
||||
$this->info("Szinkronizálás indítása {$year} évre...");
|
||||
|
||||
if ($service->syncFromApi($year)) {
|
||||
$this->info('A szinkronizálás sikeresen befejeződött.');
|
||||
return self::SUCCESS;
|
||||
}
|
||||
|
||||
$this->error('A szinkronizálás során hiba történt:');
|
||||
foreach ($service->getError() as $error) {
|
||||
$this->error("- " . implode(', ', (array) $error));
|
||||
}
|
||||
|
||||
return self::FAILURE;
|
||||
}
|
||||
}
|
||||
@ -1,20 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
class appGetDbConfigCommand extends Command
|
||||
{
|
||||
protected $signature = 'app:get-dbconfig';
|
||||
|
||||
protected $description = 'Command description';
|
||||
|
||||
public function handle(): void
|
||||
{
|
||||
$User = new \App\Models\User;
|
||||
$DriverName = $User->getConnection()->getDriverName();
|
||||
$config = config('database.connections.'.$DriverName, 'Can not get database connection config');
|
||||
$this->info(var_export($config, true));
|
||||
}
|
||||
}
|
||||
@ -1,142 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Models\OrderArchive;
|
||||
use App\Models\OrderArchivesItem;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Support\Env;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Mail;
|
||||
|
||||
class hooreycaIdNotifier extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
|
||||
protected $signature = 'emegrendeles:hooreycaIdNotifier {--doc : print documentation }';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Send scheduled hooreyca id missing in order notification to Delirest';
|
||||
private Carbon $nowTime;
|
||||
private Carbon $fromTime;
|
||||
protected bool $sendEmail=true;
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->nowTime=Carbon::now();
|
||||
|
||||
$this->fromTime=Carbon::yesterday();
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function handle(): int
|
||||
{
|
||||
$tmp=explode('\\', __CLASS__);
|
||||
$className=end($tmp);
|
||||
$this->info($className." started");
|
||||
$this->sendEmail= config('app.send_hooreyca_id_notification',false);
|
||||
//$this->info("Need debug!!!");
|
||||
$this->info("Send email:".var_export($this->sendEmail,true));
|
||||
$this->checkMissingHooreycaId();
|
||||
$this->info($className." end");
|
||||
return 0;
|
||||
}
|
||||
|
||||
public function info($string, $verbosity = null)
|
||||
{
|
||||
if($verbosity){
|
||||
Log::channel('hooreycaIdNotifier')->info($string, $verbosity);
|
||||
parent::info($string.' data: '.var_export($verbosity,true));
|
||||
}else{
|
||||
Log::channel('hooreycaIdNotifier')->info($string);
|
||||
parent::info($string);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private function checkMissingHooreycaId()
|
||||
{
|
||||
//$this->fromTime=Carbon::parse('2023-09-18');
|
||||
$this->info($this->fromTime->toDateString());
|
||||
$Orders=OrderArchive::select(['id','supplier_name','profit_center_name'])->where('sentTime','>',$this->fromTime->toDateString())->get();
|
||||
|
||||
if(count($Orders)<1){
|
||||
$this->info('No active Order Notification this moment');
|
||||
return;
|
||||
}else{
|
||||
$this->info('Active Order Notification this moment:'.count($Orders).'');
|
||||
}
|
||||
//dd($Orders->get()->where('id',12182)->toArray());
|
||||
|
||||
$orderItems=OrderArchivesItem::
|
||||
select(['name','hooreycaId','order_archive_id','id'])
|
||||
->whereIn('order_archive_id',$Orders->pluck('id'))
|
||||
->where(function ($query) {
|
||||
$query->where('hooreycaId','=','')
|
||||
->orWhereNull('hooreycaId');
|
||||
})
|
||||
|
||||
->orderBy('name')
|
||||
//->distinct()
|
||||
->limit(10)
|
||||
//->toSql();
|
||||
->get() ;
|
||||
//dd($orderItems);
|
||||
if(count($orderItems)<1){
|
||||
$this->info('No missing Hooreyca ID this moment');
|
||||
return;
|
||||
}else{
|
||||
$this->info('Missing Hooreyca ID this moment:'.count($orderItems));
|
||||
}
|
||||
//debug
|
||||
//return;
|
||||
//dd($orderItems->toArray());
|
||||
$viewData=['fromTime'=>$this->fromTime->format('Y.m.d.'),'items'=>[]];
|
||||
foreach ($orderItems->toArray() as $item){
|
||||
//dd($Orders->where('id',$item['order_archive_id'])->toArray()[0]);
|
||||
//dd($item, $Orders->where('id',$item['order_archive_id']));
|
||||
$OrderData=$Orders->where('id',$item['order_archive_id'])->first()->toArray();
|
||||
$item=array_merge($item,$OrderData);
|
||||
$viewData['items'][]=$item;
|
||||
//parent::info('item',['asdasd']);
|
||||
$this->info('item',$item);
|
||||
//Log::channel('hooreycaIdNotifier')->info('item', $item);
|
||||
//var_dump($item);
|
||||
}
|
||||
|
||||
if($this->sendEmail){
|
||||
$MailResult=Mail::send('email.hooreycaIdNotifier',$viewData,function($m){
|
||||
|
||||
//$subject='Delirest - '.$orderData['profit_center']['name'].' - '.$orderData['humanId'];
|
||||
$subject='Hooreyca id missing';
|
||||
$m->subject($subject);
|
||||
$m->to( explode(',',config('app.mail_to_hooreyca_id_notification','city99@e98.hu')));
|
||||
$m->bcc('city99@e98.hu');
|
||||
});
|
||||
$this->info('Email sent to:'.var_export(explode(',',config('app.mail_to_hooreyca_id_notification','city99@e98.hu'))));
|
||||
$this->info('Email result'.
|
||||
var_export($MailResult,true));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@ -1,357 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Enums\OrderFlag;
|
||||
use App\Http\Controllers\OrderController;
|
||||
use App\Models\OrderArchive;
|
||||
use App\Models\SupplierNotifier as SupplierNotifierModel;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class supplierNotifier extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'emegrendeles:supplierNotifier {--doc : print documentation }';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Send scheduled unprocessed order notification to supplier';
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected bool $sendEmail = false;
|
||||
|
||||
protected int $minHour = 0;
|
||||
|
||||
protected array $notifierHour = [3, 8, 24];
|
||||
|
||||
protected array $workHour = [
|
||||
1 => [4, 18],
|
||||
2 => [4, 18],
|
||||
3 => [4, 18],
|
||||
4 => [4, 18],
|
||||
5 => [4, 16],
|
||||
6 => [23, -1],
|
||||
0 => [23, -1],
|
||||
|
||||
];
|
||||
|
||||
protected array $nextDay = [
|
||||
1 => 2,
|
||||
2 => 3,
|
||||
3 => 4,
|
||||
4 => 5,
|
||||
5 => 1,
|
||||
6 => 1,
|
||||
0 => 1,
|
||||
];
|
||||
|
||||
private Carbon $nowTime;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->minHour = $this->notifierHour[0];
|
||||
$this->nowTime = Carbon::now();
|
||||
$this->sendEmail = env('SEND_SUPPLIER_NOTIFICATION', false);
|
||||
}
|
||||
|
||||
public function info($string, $verbosity = null)
|
||||
{
|
||||
if ($verbosity) {
|
||||
Log::channel('supplierNotifier')->info($string, $verbosity);
|
||||
} else {
|
||||
Log::channel('supplierNotifier')->info($string);
|
||||
}
|
||||
parent::info($string, $verbosity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*/
|
||||
public function handle(): int
|
||||
{
|
||||
$this->info('Supplier Notifier Started');
|
||||
// Log::channel('supplierNotifier')->info('Supplier Notifier Started',['requestData'=>var_export($request->server(),true)]);
|
||||
// $name = $this->ask('What is your name?');
|
||||
// $this->info('hello '.$name);
|
||||
// $this->error('error','sdsd');
|
||||
// $this->warn('warn','pppp');
|
||||
// $this->exampleProgressBar();
|
||||
// $this->testTimes();
|
||||
// $this->testSupplierNotifierModel();
|
||||
|
||||
/* $s=new SupplierNotifierModel();
|
||||
$s->makeNotificationsForOrderArchive(12179);*/
|
||||
$this->info(get_current_user());
|
||||
$this->checkUnprocessedOrderNotification();
|
||||
|
||||
$this->info('Supplier Notifier end');
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
private function testSupplierNotifierModel($timeStr = null)
|
||||
{
|
||||
|
||||
$timeStr = '2023-09-08 15:12:12'; // péntek in work
|
||||
$timeStr = '2023-09-08 6:12:12'; // péntek +3+8
|
||||
$timeStr = '2023-09-08 17:12:12'; // péntek out of work
|
||||
$timeStr = '2023-09-08 11:12:12'; // péntek +3
|
||||
$timeStr = '2023-09-04 07:12:12'; // hetfő +3+8
|
||||
$timeStr = '2023-09-04 03:12:12'; // hetfő before work
|
||||
$timeStr = '2023-09-04 18:12:12'; // hetfő out of work
|
||||
$timeStr = '2023-09-04 07:12:12'; // hetfő +3+8
|
||||
$timeStr = '2023-09-18 07:13:56';
|
||||
$SupplierNotifier = new SupplierNotifierModel;
|
||||
// $SupplierNotifier->makeTime($timeStr);
|
||||
$SupplierNotifier->makeNotificationsForOrderArchive(12180);
|
||||
}
|
||||
|
||||
public function exampleProgressBar($max = null)
|
||||
{
|
||||
if (! $max) {
|
||||
$max = 100;
|
||||
}
|
||||
|
||||
$bar = $this->output->createProgressBar($max);
|
||||
$bar->start();
|
||||
for ($i = 0; $i < $max; $i++) {
|
||||
usleep(300);
|
||||
$bar->advance();
|
||||
}
|
||||
$bar->finish();
|
||||
}
|
||||
|
||||
private function sendNotification(int $orderArchiveId)
|
||||
{
|
||||
// $orderData=app(OrderController::class)->getOrderData($orderArchiveId);
|
||||
$orderData = app(OrderController::class)->getOrderData(null, getOrderFromOrderArchive($orderArchiveId));
|
||||
$orderData['feedBackIdLinkParam'] = base64_encode($orderData['feedBackId']);
|
||||
$orderData['sentTime'] = Carbon::now()->toDateTimeString();
|
||||
$orderData['noPrintButton'] = true;
|
||||
$HTMLInvoice = view('modules.order.invoice')->with($orderData
|
||||
)->render();
|
||||
$HTMLOrder = view('email.order')->with(['orderHTMLInvoice' => $HTMLInvoice,
|
||||
'orderData' => $orderData,
|
||||
]
|
||||
)->render();
|
||||
|
||||
$subject = 'EMLÉKEZTETŐ A Szállítói webrendelőn érkezett megrendelés visszaigazolására ';
|
||||
$fileType = $orderData['supplier']['emailAttachmentType'];
|
||||
$attachments = app(OrderController::class)->getEmailAttachment($orderData, $fileType);
|
||||
$to = [];
|
||||
if ($orderData['customNotificationEmail'] && $orderData['customNotificationEmail'] != 'NULL') {
|
||||
$to[] = $orderData['customNotificationEmail'];
|
||||
}
|
||||
|
||||
if (env('APP_STAGE', 'DEV') == 'PROD') {
|
||||
$to[] = $orderData['supplier']['orderEmail'];
|
||||
if ($orderData['supplier']['orderEmail2']) {
|
||||
$to[] = $orderData['supplier']['orderEmail2'];
|
||||
}
|
||||
} else {
|
||||
$to[] = env('MAIL_TO_ORDER_ADDRESS');
|
||||
}
|
||||
$bcc = [];
|
||||
if (env('MAIL_TO_ORDER_ADDRESS') != 'city@e98.hu') {
|
||||
$bcc[] = ('city@e98.hu');
|
||||
}
|
||||
|
||||
$this->info('Notification sent: '.$orderArchiveId.' address:'.implode(',', array_merge($to, $bcc)));
|
||||
|
||||
if ($this->sendEmail) {
|
||||
\Mail::send('email.supplierNotifier', [
|
||||
'originalEmailHTML' => $HTMLOrder,
|
||||
], function ($m) use ($fileType, $attachments, $to, $bcc) {
|
||||
|
||||
// $subject='Delirest - '.$orderData['profit_center']['name'].' - '.$orderData['humanId'];
|
||||
$subject = 'EMLÉKEZTETŐ A Szállítói webrendelőn érkezett megrendelés visszaigazolására';
|
||||
/* if($orderData['orderFlag']==OrderFlag::modifier){
|
||||
$subject.=' MÓDOSÍTÁS';
|
||||
}*/
|
||||
$m->subject($subject);
|
||||
|
||||
foreach ($to as $address) {
|
||||
$m->to($address);
|
||||
}
|
||||
foreach ($bcc as $address) {
|
||||
$m->bcc($address);
|
||||
}
|
||||
|
||||
// $m->attach($attach,['as'=>$fileNameWithExt]);
|
||||
if ($fileType !== 'none') {
|
||||
if (is_array($attachments) && count($attachments) > 0) {
|
||||
foreach ($attachments as $attachData) {
|
||||
$m->attachData($attachData['attach'], $attachData['fileNameWithExt']);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function checkUnprocessedOrderNotification()
|
||||
{
|
||||
|
||||
$Orders = OrderArchive::select('id')->where('sentTime', '>', Carbon::now()->subWeek()->toDateTimeString())->whereNull('confirmed')->get();
|
||||
// OrderArchive::groupBy()
|
||||
// dd($Orders->toArray());
|
||||
|
||||
$NeedNotification = SupplierNotifierModel::whereIn('order_archive_id', $Orders->pluck('id'))
|
||||
->whereNull('sent')
|
||||
// ->where('id','<',1)
|
||||
->where('need_send', '<', DB::raw("'".Carbon::now()->toDateTimeString()."'"))
|
||||
->orderBy('need_send');
|
||||
// dd($NeedNotification->toSql(),$NeedNotification->getBindings());
|
||||
|
||||
$orderFinished = [];
|
||||
if ($NeedNotification->get()->count() < 1) {
|
||||
$this->info('No active Supplier Order Notification this moment');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($NeedNotification->get() as $notification) {
|
||||
// var_dump($notification->order_archive_id);
|
||||
// dd($notification->order_archive_id);
|
||||
if (! in_array($notification->order_archive_id, $orderFinished)) {
|
||||
$this->sendNotification($notification->order_archive_id);
|
||||
$orderFinished[] = $notification->order_archive_id;
|
||||
// var_dump('add'.$notification->order_archive_id);
|
||||
// var_dump($notification->toArray());
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* kodnál az összes olyat ami régebbi mint mostani dátum hogy ne küldjön újat.
|
||||
*/
|
||||
$Notifies = SupplierNotifierModel::whereIn('order_archive_id', $orderFinished)->whereNull('sent')->where('need_send', '<', Carbon::now());
|
||||
if ($Notifies->get()->count() > 0) {
|
||||
$Nid = $Notifies->pluck('id')->toArray();
|
||||
$Notifies->update(['sent' => Carbon::now()]);
|
||||
$this->info('SupplierNotifier update:'.implode(',', $Nid));
|
||||
}
|
||||
}
|
||||
|
||||
public function testTimes()
|
||||
{
|
||||
|
||||
/*
|
||||
* Pl: hétfőn 7 órakkor leadott megrendelés emlékeztető hetfő 10,15 óra.
|
||||
*/
|
||||
/* $searchDay = 'Monday';
|
||||
$searchDate = new Carbon(); //or whatever Carbon instance you're using
|
||||
$lastDay = Carbon::createFromTimeStamp(strtotime("last $searchDay", $searchDate->timestamp));
|
||||
$lastDay->setTime(7,rand(0,58));
|
||||
$checkTime=$lastDay->toDateTimeString();
|
||||
//$this->nowTime=$lastDay->setTime(7+rand(0,13),rand(0,58));
|
||||
$this->nowTime=$lastDay->setTime(10,rand(0,58));
|
||||
$this->nowTime=$lastDay->setTime(15,rand(0,58));
|
||||
$this->info('nowTime>'.$this->nowTime->toDateTimeString());
|
||||
$this->diffTime($checkTime);*/
|
||||
$checkTime = Carbon::parse('2023-09-04');
|
||||
$checkTime->setTime(7, rand(0, 58));
|
||||
$nowTime = Carbon::parse('2023-09-04');
|
||||
$nowTime->setTime(10, 59);
|
||||
$nowTime->setTime(15, 59);
|
||||
$this->nowTime = $nowTime;
|
||||
// $this->info('nowTime>'.$this->nowTime->toDateTimeString());
|
||||
// $this->diffTime($checkTime);
|
||||
|
||||
/*
|
||||
* hétfőn 21 órakkor leadott megrendelés emlékeztető kedd 7,12 óra.
|
||||
*/
|
||||
$checkTime = Carbon::parse('2023-09-04');
|
||||
$checkTime->setTime(21, rand(0, 58));
|
||||
$nowTime = Carbon::parse('2023-09-05');
|
||||
/*
|
||||
$nowTime->setTime(5,59);
|
||||
$nowTime->setTime(7,59);
|
||||
$nowTime->setTime(10,59);
|
||||
$nowTime->setTime(12,59);
|
||||
|
||||
*/
|
||||
$nowTime->setTime(12, 59);
|
||||
$this->nowTime = $nowTime;
|
||||
// $this->info('nowTime>'.$this->nowTime->toDateTimeString());
|
||||
// $this->diffTime($checkTime);
|
||||
|
||||
/*
|
||||
* Kedden 18 órakkor leadott megrendelés emlékeztető Szerda 7,12 óra.
|
||||
*/
|
||||
$checkTime = Carbon::parse('2023-09-05');
|
||||
$checkTime->setTime(18, rand(0, 58));
|
||||
$nowTime = Carbon::parse('2023-09-06');
|
||||
/*
|
||||
$nowTime->setTime(5,59);
|
||||
$nowTime->setTime(7,59);
|
||||
$nowTime->setTime(10,59);
|
||||
$nowTime->setTime(12,59);
|
||||
|
||||
*/
|
||||
$nowTime->setTime(12, 59);
|
||||
$this->nowTime = $nowTime;
|
||||
// $this->info('nowTime>'.$this->nowTime->toDateTimeString().' '.$this->nowTime->format('l'));
|
||||
// $this->diffTime($checkTime);
|
||||
|
||||
/*
|
||||
* Péntek 13 órakkor leadott megrendelés emlékeztető hétfő 7,12 óra.
|
||||
*/
|
||||
$checkTime = Carbon::parse('2023-09-08');
|
||||
$checkTime->setTime(13, rand(0, 58));
|
||||
$nowTime = Carbon::parse('2023-09-11');
|
||||
/*
|
||||
$nowTime->setTime(5,59);
|
||||
$nowTime->setTime(7,59);
|
||||
$nowTime->setTime(10,59);
|
||||
$nowTime->setTime(12,59);
|
||||
|
||||
*/
|
||||
$nowTime->setTime(16, 50);
|
||||
$this->nowTime = $nowTime;
|
||||
|
||||
/*
|
||||
$this->info('nowTime>'.$this->nowTime->toDateTimeString().' '.$this->nowTime->format('l'));
|
||||
$this->makeTime($checkTime);
|
||||
*/
|
||||
|
||||
/*
|
||||
* Péntek 13 órakkor leadott megrendelés emlékeztető hétfő 7,12 óra.
|
||||
*/
|
||||
$checkTime = Carbon::parse('2023-09-08');
|
||||
$checkTime->setTime(19, rand(0, 58));
|
||||
|
||||
$nowTime = Carbon::parse('2023-09-11');
|
||||
/*
|
||||
$nowTime->setTime(5,59);
|
||||
$nowTime->setTime(7,59);
|
||||
$nowTime->setTime(10,59);
|
||||
$nowTime->setTime(12,59);
|
||||
|
||||
*/
|
||||
$nowTime->setTime(16, 50);
|
||||
$this->nowTime = $nowTime;
|
||||
$this->makeTime($checkTime);
|
||||
|
||||
/*
|
||||
$this->info('nowTime>'.$this->nowTime->toDateTimeString().' '.$this->nowTime->format('l'));
|
||||
$this->diffTime($checkTime);
|
||||
*/
|
||||
|
||||
}
|
||||
}
|
||||
@ -1,28 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console;
|
||||
|
||||
use Illuminate\Console\Scheduling\Schedule;
|
||||
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
|
||||
|
||||
class Kernel extends ConsoleKernel
|
||||
{
|
||||
/**
|
||||
* Define the application's command schedule.
|
||||
*/
|
||||
protected function schedule(Schedule $schedule): void
|
||||
{
|
||||
// $schedule->command('inspire')->hourly();
|
||||
// $schedule->command('app:sync-work-calendar')->quarterly();
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the commands for the application.
|
||||
*/
|
||||
protected function commands(): void
|
||||
{
|
||||
$this->load(__DIR__.'/Commands');
|
||||
|
||||
require base_path('routes/console.php');
|
||||
}
|
||||
}
|
||||
@ -1,15 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Database;
|
||||
|
||||
use Illuminate\Database\Schema\Blueprint as BaseBlueprint;
|
||||
|
||||
class Blueprint extends BaseBlueprint
|
||||
{
|
||||
public function userIdFields()
|
||||
{
|
||||
$this->unsignedInteger('created_by')->nullable();
|
||||
$this->unsignedInteger('updated_by')->nullable();
|
||||
$this->unsignedInteger('deleted_by')->nullable();
|
||||
}
|
||||
}
|
||||
@ -1,19 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums;
|
||||
|
||||
use BenSampo\Enum\Enum;
|
||||
|
||||
/**
|
||||
* @method static static kg()
|
||||
* @method static static l()
|
||||
* @method static static db()
|
||||
*/
|
||||
class BasicUnitEnum extends Enum
|
||||
{
|
||||
const kg = 'kg';
|
||||
|
||||
const l = 'l';
|
||||
|
||||
const db = 'db';
|
||||
}
|
||||
@ -1,19 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums;
|
||||
|
||||
use BenSampo\Enum\Enum;
|
||||
|
||||
/**
|
||||
* @method static static orderMail()
|
||||
* @method static static contactMember()
|
||||
* @method static static customerService()
|
||||
*/
|
||||
final class ContactTypeEnum extends Enum
|
||||
{
|
||||
const orderMail = 'Megrendelés e-mailcím';
|
||||
|
||||
const contactMember = 'Kapcsolattartó';
|
||||
|
||||
const customerService = 'Vevőszolgálat';
|
||||
}
|
||||
@ -1,17 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums;
|
||||
|
||||
enum DataSource: string
|
||||
{
|
||||
case Api = 'api';
|
||||
case Manual = 'manual';
|
||||
|
||||
public function label(): string
|
||||
{
|
||||
return match($this) {
|
||||
self::Api => 'API',
|
||||
self::Manual => 'Kézi rögzítés',
|
||||
};
|
||||
}
|
||||
}
|
||||
@ -1,22 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums;
|
||||
|
||||
use BenSampo\Enum\Enum;
|
||||
|
||||
/**
|
||||
* @method static static draft()
|
||||
* @method static static active()
|
||||
* @method static static archive()
|
||||
* @method static static deleted()
|
||||
*/
|
||||
final class DbStatusFieldEnum extends Enum
|
||||
{
|
||||
const draft = 'draft';
|
||||
|
||||
const active = 'active';
|
||||
|
||||
const archive = 'archive';
|
||||
|
||||
const deleted = 'deleted';
|
||||
}
|
||||
@ -1,19 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums;
|
||||
|
||||
use BenSampo\Enum\Enum;
|
||||
|
||||
/**
|
||||
* @method static static pdf()
|
||||
* @method static static excel()
|
||||
* @method static static none()
|
||||
*/
|
||||
final class EmailAttachmentTypeEnum extends Enum
|
||||
{
|
||||
const pdf = 'pdf';
|
||||
|
||||
const excel = 'excel';
|
||||
|
||||
const nincs = 'nincs';
|
||||
}
|
||||
@ -1,29 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums;
|
||||
|
||||
use BenSampo\Enum\Enum;
|
||||
|
||||
/**
|
||||
* @method static static modifier()
|
||||
* @method static static modified()
|
||||
* @method static static storno()
|
||||
*/
|
||||
final class OrderFlag extends Enum
|
||||
{
|
||||
const modifier = 'modifier';
|
||||
|
||||
const modified = 'modified';
|
||||
|
||||
const storno = 'storno';
|
||||
|
||||
public static function getDescription($value): string
|
||||
{
|
||||
return match ($value) {
|
||||
self::modifier => 'módosító',
|
||||
self::modified => 'módosított',
|
||||
self::storno => 'stornó',
|
||||
default => 'eredeti',
|
||||
};
|
||||
}
|
||||
}
|
||||
@ -1,36 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums;
|
||||
|
||||
use BenSampo\Enum\Enum;
|
||||
|
||||
/**
|
||||
* @method static static supplierSelect()
|
||||
* @method static static parameter()
|
||||
* @method static static productSelect()
|
||||
* @method static static invoice()
|
||||
* @method static static send()
|
||||
* @method static static sent()
|
||||
* @method static static confirmed()
|
||||
*/
|
||||
final class OrderStatusEnum extends Enum
|
||||
{
|
||||
const supplierSelect = 'supplierSelect';
|
||||
|
||||
const parameter = 'parameter';
|
||||
|
||||
const productSelect = 'productSelect';
|
||||
|
||||
const invoice = 'invoice';
|
||||
|
||||
const send = 'send';
|
||||
|
||||
const sent = 'sent';
|
||||
|
||||
const confirmed = 'confirmed';
|
||||
|
||||
const archived = 'archived';
|
||||
/*
|
||||
const = '';
|
||||
*/
|
||||
}
|
||||
@ -1,16 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums;
|
||||
|
||||
use BenSampo\Enum\Enum;
|
||||
|
||||
/**
|
||||
* @method static static daily()
|
||||
* @method static static weekly()
|
||||
*/
|
||||
final class OrderType extends Enum
|
||||
{
|
||||
const daily = 'daily';
|
||||
|
||||
const weekly = 'weekly';
|
||||
}
|
||||
@ -1,28 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums;
|
||||
|
||||
enum OverrideScope: string
|
||||
{
|
||||
case General = 'general'; // Általános – adott beszállítóra, minden régióra és profitcenterre
|
||||
case Region = 'region'; // Régió-specifikus – adott régióra vonatkozó felülbírálás
|
||||
case ProfitCenter = 'profit_center'; // Profitcenter-specifikus – csak 1 konkrét profitcenterre
|
||||
|
||||
public function label(): string
|
||||
{
|
||||
return match($this) {
|
||||
self::General => 'Általános (minden telephely)',
|
||||
self::Region => 'Régió-specifikus',
|
||||
self::ProfitCenter => 'Profitcenter-specifikus',
|
||||
};
|
||||
}
|
||||
|
||||
public function color(): string
|
||||
{
|
||||
return match($this) {
|
||||
self::General => 'gray',
|
||||
self::Region => 'warning',
|
||||
self::ProfitCenter => 'info',
|
||||
};
|
||||
}
|
||||
}
|
||||
@ -1,53 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums;
|
||||
|
||||
enum PreProcessErrorCode: string
|
||||
{
|
||||
case FILE_NOT_FOUND = 'FILE_NOT_FOUND';
|
||||
case FILE_CORRUPTED = 'FILE_CORRUPTED';
|
||||
case FILE_TOO_LARGE = 'FILE_TOO_LARGE';
|
||||
case FILE_EMPTY = 'FILE_EMPTY';
|
||||
case INVALID_EXTENSION = 'INVALID_EXTENSION';
|
||||
case NO_WORKSHEET = 'NO_WORKSHEET';
|
||||
case COLUMN_COUNT_MISMATCH = 'COLUMN_COUNT_MISMATCH';
|
||||
case COLUMN_MISSING = 'COLUMN_MISSING';
|
||||
case COLUMN_EXTRA = 'COLUMN_EXTRA';
|
||||
case HEADER_MISMATCH = 'HEADER_MISMATCH';
|
||||
case NO_DATA_ROWS = 'NO_DATA_ROWS';
|
||||
|
||||
public function label(): string
|
||||
{
|
||||
return match ($this) {
|
||||
self::FILE_NOT_FOUND => 'A fájl nem található a szerveren.',
|
||||
self::FILE_CORRUPTED => 'A fájl sérült vagy nem nyitható meg.',
|
||||
self::FILE_TOO_LARGE => 'A fájl mérete meghaladja a megengedett határt.',
|
||||
self::FILE_EMPTY => 'A fájl üres.',
|
||||
self::INVALID_EXTENSION => 'A fájl kiterjesztése nem megfelelő.',
|
||||
self::NO_WORKSHEET => 'Az Excel fájl nem tartalmaz munkalapot.',
|
||||
self::COLUMN_COUNT_MISMATCH => 'Az oszlopok száma nem egyezik az elvárt struktúrával.',
|
||||
self::COLUMN_MISSING => 'Hiányzó oszlop(ok) az elvárt struktúrából.',
|
||||
self::COLUMN_EXTRA => 'Többlet oszlop(ok) az elvárt struktúrához képest.',
|
||||
self::HEADER_MISMATCH => 'Egy vagy több oszlopfejléc nem egyezik az elvárttal.',
|
||||
self::NO_DATA_ROWS => 'A fájl nem tartalmaz feldolgozható adatsort.',
|
||||
};
|
||||
}
|
||||
|
||||
public function severity(): string
|
||||
{
|
||||
return match ($this) {
|
||||
self::FILE_NOT_FOUND,
|
||||
self::FILE_CORRUPTED,
|
||||
self::FILE_EMPTY,
|
||||
self::INVALID_EXTENSION,
|
||||
self::NO_WORKSHEET,
|
||||
self::COLUMN_COUNT_MISMATCH,
|
||||
self::HEADER_MISMATCH,
|
||||
self::NO_DATA_ROWS => 'blocker',
|
||||
|
||||
self::COLUMN_MISSING => 'error',
|
||||
self::COLUMN_EXTRA,
|
||||
self::FILE_TOO_LARGE => 'warning',
|
||||
};
|
||||
}
|
||||
}
|
||||
@ -1,45 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums;
|
||||
|
||||
enum PricelistFileLineStatusEnum: string
|
||||
{
|
||||
case ok = 'ok';
|
||||
case warning = 'warning';
|
||||
case error = 'error';
|
||||
case new_product = 'new_product';
|
||||
case updated = 'updated';
|
||||
|
||||
public function label(): string
|
||||
{
|
||||
return match ($this) {
|
||||
self::ok => 'rendben',
|
||||
self::warning => 'figyelmeztetés',
|
||||
self::error => 'hiba',
|
||||
self::new_product => 'új termék',
|
||||
self::updated => 'módosítás',
|
||||
};
|
||||
}
|
||||
|
||||
public function color(): string
|
||||
{
|
||||
return match ($this) {
|
||||
self::ok => 'success',
|
||||
self::warning => 'warning',
|
||||
self::error => 'danger',
|
||||
self::new_product => 'info',
|
||||
self::updated => 'primary',
|
||||
};
|
||||
}
|
||||
|
||||
public function icon(): string
|
||||
{
|
||||
return match ($this) {
|
||||
self::ok => 'heroicon-o-check-circle',
|
||||
self::warning => 'heroicon-o-exclamation-triangle',
|
||||
self::error => 'heroicon-o-x-circle',
|
||||
self::new_product => 'heroicon-o-sparkles',
|
||||
self::updated => 'heroicon-o-pencil-square',
|
||||
};
|
||||
}
|
||||
}
|
||||
@ -1,25 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums;
|
||||
|
||||
enum PricelistFileStatusEnum: string
|
||||
{
|
||||
case todo = 'todo';
|
||||
case inprogress = 'inprogress';
|
||||
case fail = 'fail';
|
||||
case done = 'done';
|
||||
case waiting_for_approval = 'waiting_for_approval';
|
||||
case closed = 'closed';
|
||||
|
||||
public function label(): string
|
||||
{
|
||||
return match ($this) {
|
||||
self::todo => 'elvégzendő',
|
||||
self::inprogress => 'folyamatban',
|
||||
self::fail => 'hiba',
|
||||
self::done => 'elkészült',
|
||||
self::waiting_for_approval => 'jóváhagyásra vár',
|
||||
self::closed => 'lezárva',
|
||||
};
|
||||
}
|
||||
}
|
||||
@ -1,28 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums;
|
||||
|
||||
enum PricelistSellerUnitEnum: string
|
||||
{
|
||||
case csom = 'csom';
|
||||
case kart = 'kart';
|
||||
case rúd = 'rúd';
|
||||
case db = 'db';
|
||||
case dob = 'dob';
|
||||
case zsák = 'zsák';
|
||||
case tálca = 'tálca';
|
||||
case kg = 'kg';
|
||||
case liter = 'liter';
|
||||
case pár = 'pár';
|
||||
case tekercs = 'tekercs';
|
||||
|
||||
/**
|
||||
* Visszaadja az összes értéket tömbként
|
||||
*
|
||||
* @return array<string>
|
||||
*/
|
||||
public static function values(): array
|
||||
{
|
||||
return array_column(self::cases(), 'value');
|
||||
}
|
||||
}
|
||||
@ -1,20 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums;
|
||||
|
||||
enum PricelistUnitEnum: string
|
||||
{
|
||||
case l = 'l';
|
||||
case kg = 'kg';
|
||||
case db = 'db';
|
||||
|
||||
/**
|
||||
* Visszaadja az összes értéket tömbként
|
||||
*
|
||||
* @return array<string>
|
||||
*/
|
||||
public static function values(): array
|
||||
{
|
||||
return array_column(self::cases(), 'value');
|
||||
}
|
||||
}
|
||||
@ -1,30 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums;
|
||||
|
||||
enum PricelistVatEnum: int
|
||||
{
|
||||
case Percent5 = 5;
|
||||
case Percent18 = 18;
|
||||
case Percent27 = 27;
|
||||
|
||||
/**
|
||||
* Visszaadja az összes értéket tömbként (5, 18, 27)
|
||||
*
|
||||
* @return array<int>
|
||||
*/
|
||||
public static function values(): array
|
||||
{
|
||||
return array_column(self::cases(), 'value');
|
||||
}
|
||||
|
||||
/**
|
||||
* Visszaadja a megjelenítendő címkéket (pl. '5%')
|
||||
*
|
||||
* @return array<string>
|
||||
*/
|
||||
public static function labels(): array
|
||||
{
|
||||
return array_map(fn($case) => $case->value . '%', self::cases());
|
||||
}
|
||||
}
|
||||
@ -1,76 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums;
|
||||
|
||||
use App\Jobs\PricelistPreProcessJob;
|
||||
use App\Jobs\PricelistValidationJob;
|
||||
use App\Jobs\PricelistExecutionJob;
|
||||
|
||||
enum PricelistWorkflowStep: string
|
||||
{
|
||||
case Preprocessing = 'preprocess';
|
||||
case Validation = 'validation';
|
||||
case Approval = 'approval';
|
||||
case Execution = 'execution';
|
||||
|
||||
/**
|
||||
* Magyar megnevezés (UI megjelenítéshez)
|
||||
*/
|
||||
public function label(): string
|
||||
{
|
||||
return match($this) {
|
||||
self::Preprocessing => 'Előfeldolgozás',
|
||||
self::Validation => 'Validálás',
|
||||
self::Approval => 'Jóváhagyás',
|
||||
self::Execution => 'Végrehajtás',
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* A lépéshez tartozó Job osztály neve
|
||||
*/
|
||||
public function jobClass(): ?string
|
||||
{
|
||||
return match($this) {
|
||||
self::Preprocessing => PricelistPreProcessJob::class,
|
||||
self::Validation => PricelistValidationJob::class,
|
||||
self::Execution => PricelistExecutionJob::class,
|
||||
self::Approval => null, // Manuális lépésnél nincs automatikus job
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* A lépéshez tartozó Job példány visszaadása
|
||||
*/
|
||||
public function getJob(\App\Models\PricelistFile $file): ?object
|
||||
{
|
||||
$jobClass = $this->jobClass();
|
||||
return $jobClass ? new $jobClass($file) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Státusz színek (UI megjelenítéshez)
|
||||
*/
|
||||
public function color(string $status): string
|
||||
{
|
||||
return match ($status) {
|
||||
'pending' => 'gray',
|
||||
'inprogress' => 'primary',
|
||||
'completed' => 'success',
|
||||
'failed' => 'danger',
|
||||
default => 'gray',
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Segédfüggvény az alapértelmezett workflow struktúra legenerálásához
|
||||
*/
|
||||
public static function defaultSteps(): array
|
||||
{
|
||||
return array_map(fn($step) => [
|
||||
'name' => $step->value,
|
||||
'label' => $step->label(),
|
||||
'status' => 'pending',
|
||||
], self::cases());
|
||||
}
|
||||
}
|
||||
@ -1,19 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums;
|
||||
|
||||
use BenSampo\Enum\Enum;
|
||||
|
||||
/**
|
||||
* @method static static F()
|
||||
* @method static static N()
|
||||
* @method static static X()
|
||||
*/
|
||||
final class ProductTypeEnum extends Enum
|
||||
{
|
||||
const F = 'Food';
|
||||
|
||||
const N = 'NonFood';
|
||||
|
||||
const X = 'Other';
|
||||
}
|
||||
@ -1,27 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums;
|
||||
|
||||
/**
|
||||
* @method static static g()
|
||||
*/
|
||||
class ProductUnitEnum extends BasicUnitEnum
|
||||
{
|
||||
const g = 'g';
|
||||
|
||||
const ml = 'ml';
|
||||
|
||||
const tálca = 'tálca';
|
||||
|
||||
const csom = 'csom';
|
||||
|
||||
const dob = 'dob';
|
||||
|
||||
const kart = 'kart';
|
||||
|
||||
const rúd = 'rúd';
|
||||
|
||||
const pár = 'pár';
|
||||
|
||||
const zsák = 'zsák';
|
||||
}
|
||||
@ -1,25 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums;
|
||||
|
||||
enum StockStatusEnum: string
|
||||
{
|
||||
case InStock = 'in_stock';
|
||||
case OutOfStock = 'out_of_stock';
|
||||
|
||||
public function label(): string
|
||||
{
|
||||
return match ($this) {
|
||||
self::InStock => 'Raktáron',
|
||||
self::OutOfStock => 'Nincs raktáron',
|
||||
};
|
||||
}
|
||||
|
||||
public function color(): string
|
||||
{
|
||||
return match ($this) {
|
||||
self::InStock => 'success',
|
||||
self::OutOfStock => 'danger',
|
||||
};
|
||||
}
|
||||
}
|
||||
@ -1,25 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums;
|
||||
|
||||
enum WorkDayType: string
|
||||
{
|
||||
case Holiday = 'holiday'; // Munkaszüneti nap
|
||||
case WorkingDay = 'working_day'; // Plusz munkanap (pl. szombat)
|
||||
|
||||
public function label(): string
|
||||
{
|
||||
return match($this) {
|
||||
self::Holiday => 'Munkaszüneti nap',
|
||||
self::WorkingDay => 'Áthelyezett munkanap',
|
||||
};
|
||||
}
|
||||
|
||||
public function color(): string
|
||||
{
|
||||
return match($this) {
|
||||
self::Holiday => 'danger',
|
||||
self::WorkingDay => 'success',
|
||||
};
|
||||
}
|
||||
}
|
||||
@ -1,92 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Exceptions;
|
||||
|
||||
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Support\Str;
|
||||
use Throwable;
|
||||
|
||||
class Handler extends ExceptionHandler
|
||||
{
|
||||
/**
|
||||
* A list of exception types with their corresponding custom log levels.
|
||||
*
|
||||
* @var array<class-string<\Throwable>, \Psr\Log\LogLevel::*>
|
||||
*/
|
||||
protected $levels = [
|
||||
//
|
||||
];
|
||||
|
||||
/**
|
||||
* A list of the exception types that are not reported.
|
||||
*
|
||||
* @var array<int, class-string<\Throwable>>
|
||||
*/
|
||||
protected $dontReport = [
|
||||
//
|
||||
];
|
||||
|
||||
/**
|
||||
* A list of the inputs that are never flashed to the session on validation exceptions.
|
||||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $dontFlash = [
|
||||
'current_password',
|
||||
'password',
|
||||
'password_confirmation',
|
||||
];
|
||||
|
||||
/**
|
||||
* Register the exception handling callbacks for the application.
|
||||
*/
|
||||
public function register(): void
|
||||
{
|
||||
$this->reportable(function (Throwable $e) {
|
||||
//
|
||||
});
|
||||
|
||||
// AJAX kérések esetén mindig JSON választ adunk, egyedi referencia kóddal
|
||||
$this->renderable(function (Throwable $e, $request) {
|
||||
if ($request->ajax() || $request->wantsJson()) {
|
||||
return $this->handleAjaxException($e, $request);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private function handleAjaxException(Throwable $e, $request): JsonResponse
|
||||
{
|
||||
// Validációs hibákat nem piszkáljuk – azokat a Laravel alapból kezeli
|
||||
if ($e instanceof \Illuminate\Validation\ValidationException) {
|
||||
return parent::render($request, $e);
|
||||
}
|
||||
|
||||
// Egyedi referencia kód generálása
|
||||
$errorRef = 'ERR-' . now()->format('ymdHis') . '-' . strtoupper(Str::random(6));
|
||||
|
||||
// Teljes technikai részlet a logba
|
||||
\Log::error("[$errorRef] Unhandled exception", [
|
||||
'error_ref' => $errorRef,
|
||||
'message' => $e->getMessage(),
|
||||
'exception' => get_class($e),
|
||||
'file' => $e->getFile(),
|
||||
'line' => $e->getLine(),
|
||||
'url' => $request->fullUrl(),
|
||||
'method' => $request->method(),
|
||||
'user_id' => auth()->id(),
|
||||
'input' => $request->except($this->dontFlash),
|
||||
'trace' => $e->getTraceAsString(),
|
||||
]);
|
||||
|
||||
$statusCode = method_exists($e, 'getStatusCode')
|
||||
? $e->getStatusCode()
|
||||
: 500;
|
||||
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'error_ref' => $errorRef,
|
||||
'message' => "Váratlan hiba történt. Hivatkozási kód: $errorRef",
|
||||
], $statusCode);
|
||||
}
|
||||
}
|
||||
@ -1,28 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace app\Exceptions;
|
||||
|
||||
use Flugg\Responder\Exceptions\Http\HttpException;
|
||||
|
||||
/**
|
||||
* An exception thrown whan a relation is not found.
|
||||
*
|
||||
* @author Alexander Tømmerås <flugged@gmail.com>
|
||||
* @license The MIT License
|
||||
*/
|
||||
class MethodNotAllowedHttpAPIException extends HttpException
|
||||
{
|
||||
/**
|
||||
* An HTTP status code.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $status = 405;
|
||||
|
||||
/**
|
||||
* An error code.
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
protected $errorCode = 'MethodNotAllowedHttpException';
|
||||
}
|
||||
@ -1,264 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Exports;
|
||||
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Support\Collection;
|
||||
use Maatwebsite\Excel\Concerns\FromView;
|
||||
use Maatwebsite\Excel\Concerns\ShouldAutoSize;
|
||||
use Maatwebsite\Excel\Concerns\WithColumnFormatting;
|
||||
use Maatwebsite\Excel\Concerns\WithCustomValueBinder;
|
||||
use Maatwebsite\Excel\Concerns\WithMapping;
|
||||
use Maatwebsite\Excel\Concerns\WithStyles;
|
||||
use PhpOffice\PhpSpreadsheet\Cell\Cell;
|
||||
use PhpOffice\PhpSpreadsheet\Cell\DataType;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
|
||||
|
||||
class ExportOrderInvoiceExcel implements FromView, ShouldAutoSize, WithColumnFormatting, WithCustomValueBinder, WithMapping, WithStyles
|
||||
{
|
||||
public function __construct($data)
|
||||
{
|
||||
$this->data = $data;
|
||||
}
|
||||
|
||||
public function collection(): Collection
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
public function view(): View
|
||||
{
|
||||
return view('modules.order.excelExport')->with($this->data);
|
||||
|
||||
return view('test.invoice')->with($this->data);
|
||||
}
|
||||
|
||||
private function searchByValue($sheet, $needValue, $partial = true): array
|
||||
{
|
||||
foreach ($sheet->getRowIterator() as $row) {
|
||||
$ret = [
|
||||
'col' => null,
|
||||
'row' => null,
|
||||
];
|
||||
$cellIterator = $row->getCellIterator();
|
||||
$cellIterator->setIterateOnlyExistingCells(true);
|
||||
foreach ($cellIterator as $cell) {
|
||||
if ($partial) {
|
||||
if (strpos($cell->getValue(), $needValue) !== false) {
|
||||
$ret['col'] = $cell->getColumn();
|
||||
$ret['row'] = $cell->getRow();
|
||||
$retArray[] = $ret;
|
||||
}
|
||||
} else {
|
||||
if ($cell->getValue() == $needValue) {
|
||||
$ret['col'] = $cell->getColumn();
|
||||
$ret['row'] = $cell->getRow();
|
||||
$retArray[] = $ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// dd($retArray);
|
||||
return $retArray;
|
||||
}
|
||||
|
||||
private function formatHead(Worksheet $sheet)
|
||||
{
|
||||
$lastCell = $sheet->getHighestColumn();
|
||||
$sheet->getRowDimension(1)->setRowHeight(170);
|
||||
$dataRange = 'A1:'.$lastCell.'1';
|
||||
$sheet->getStyle($dataRange)->applyFromArray([
|
||||
'borders' => [
|
||||
'outline' => [
|
||||
'borderStyle' => \PhpOffice\PhpSpreadsheet\Style\Border::BORDER_MEDIUM,
|
||||
],
|
||||
],
|
||||
'font' => [
|
||||
'bold' => true,
|
||||
],
|
||||
]);
|
||||
|
||||
}
|
||||
|
||||
private function formatTitleRow(Worksheet $sheet)
|
||||
{
|
||||
$headValueInRow = $this->searchByValue($sheet, 'Cikkszám', true)[0]['row'];
|
||||
$lastCell = $sheet->getHighestColumn();
|
||||
$dataRange = 'A'.$headValueInRow.':'.$lastCell.$headValueInRow;
|
||||
$sheet->getStyle($dataRange)->applyFromArray([
|
||||
'borders' => [
|
||||
'outline' => [
|
||||
'borderStyle' => \PhpOffice\PhpSpreadsheet\Style\Border::BORDER_MEDIUM,
|
||||
],
|
||||
'inside' => [
|
||||
'borderStyle' => \PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THIN,
|
||||
],
|
||||
|
||||
],
|
||||
'font' => [
|
||||
'bold' => true,
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
private function formatDayRows(Worksheet $sheet)
|
||||
{
|
||||
$pointerText = 'Szállítási dátum:';
|
||||
$dateValueInRow = $this->searchByValue($sheet, $pointerText, true);
|
||||
$lastCell = $sheet->getHighestColumn();
|
||||
// fejlécet skipelni kell
|
||||
foreach ($dateValueInRow as $item) {
|
||||
$row = $item['row'];
|
||||
if ($row > 1) {
|
||||
$dataRange = 'A'.($row).':'.$lastCell.($row);
|
||||
$sheet->getStyle($dataRange)->applyFromArray([
|
||||
'borders' => [
|
||||
'outline' => [
|
||||
'borderStyle' => \PhpOffice\PhpSpreadsheet\Style\Border::BORDER_MEDIUM,
|
||||
],
|
||||
],
|
||||
'font' => [
|
||||
'size' => 14,
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private function formatSumRows(Worksheet $sheet)
|
||||
{
|
||||
$pointerText = 'Végösszeg';
|
||||
$sumValueInRow = $this->searchByValue($sheet, $pointerText, true);
|
||||
$lastCell = $sheet->getHighestColumn();
|
||||
// fejlécet skipelni kell
|
||||
foreach ($sumValueInRow as $item) {
|
||||
$row = $item['row'];
|
||||
if ($row > 1) {
|
||||
$dataRange = 'A'.$row.':'.$lastCell.$row;
|
||||
$sheet->getStyle($dataRange)->applyFromArray([
|
||||
'borders' => [
|
||||
'outline' => [
|
||||
'borderStyle' => \PhpOffice\PhpSpreadsheet\Style\Border::BORDER_MEDIUM,
|
||||
],
|
||||
],
|
||||
'font' => [
|
||||
'bold' => true,
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private function setItemRowFormat(Worksheet $sheet, $dataRange)
|
||||
{
|
||||
$sheet->getStyle($dataRange)->applyFromArray([
|
||||
'borders' => [
|
||||
'outline' => [
|
||||
'borderStyle' => \PhpOffice\PhpSpreadsheet\Style\Border::BORDER_MEDIUM,
|
||||
],
|
||||
'inside' => [
|
||||
'borderStyle' => \PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THIN,
|
||||
],
|
||||
],
|
||||
]);
|
||||
|
||||
}
|
||||
|
||||
private function formatItemsRows(Worksheet $sheet)
|
||||
{
|
||||
|
||||
$pointerText = 'Végösszeg';
|
||||
$sumValueInRow = $this->searchByValue($sheet, $pointerText, true);
|
||||
$lastCell = $sheet->getHighestColumn();
|
||||
|
||||
if ($this->data['orderType'] == 'weekly') {
|
||||
$pointerText = 'Szállítási dátum:';
|
||||
$dateValueInRow = $this->searchByValue($sheet, $pointerText, true);
|
||||
for ($i = 0; $i < count($sumValueInRow); $i++) {
|
||||
$dataRange = 'A'.($dateValueInRow[$i]['row'] + 1).':'.$lastCell.($sumValueInRow[$i]['row'] - 1);
|
||||
$this->setItemRowFormat($sheet, $dataRange);
|
||||
}
|
||||
} else {
|
||||
$headValueInRow = $this->searchByValue($sheet, 'Cikkszám', true)[0]['row'];
|
||||
$dataRange = 'A'.($headValueInRow + 1).':'.$lastCell.($sumValueInRow[0]['row'] - 1);
|
||||
$this->setItemRowFormat($sheet, $dataRange);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function styles(Worksheet $sheet)
|
||||
{
|
||||
$this->formatHead($sheet);
|
||||
$this->formatTitleRow($sheet);
|
||||
$this->formatDayRows($sheet);
|
||||
$this->formatItemsRows($sheet);
|
||||
$this->formatSumRows($sheet);
|
||||
|
||||
return;
|
||||
|
||||
return [
|
||||
|
||||
/*$sumValueInRow=>[
|
||||
'borders' => [
|
||||
'outline' => [
|
||||
'borderStyle' => \PhpOffice\PhpSpreadsheet\Style\Border::BORDER_MEDIUM,
|
||||
],
|
||||
'inside' => [
|
||||
'borderStyle' => \PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THIN,
|
||||
],
|
||||
|
||||
],
|
||||
'font' => [
|
||||
'bold' => true,
|
||||
],
|
||||
],*/
|
||||
|
||||
];
|
||||
/* return [
|
||||
// Style the first row as bold text.
|
||||
1 => ['font' => ['bold' => true]],
|
||||
|
||||
// Styling a specific cell by coordinate.
|
||||
'B2' => ['font' => ['italic' => true]],
|
||||
|
||||
// Styling an entire column.
|
||||
'C' => ['font' => ['size' => 16]],
|
||||
];*/
|
||||
}
|
||||
|
||||
public function map($row): array
|
||||
{
|
||||
// TODO: Implement map() method.
|
||||
dd('asd');
|
||||
}
|
||||
|
||||
public function columnFormats(): array
|
||||
{
|
||||
// TODO: Implement columnFormats() method.
|
||||
return [];
|
||||
}
|
||||
|
||||
public function bindValue(Cell $cell, $value)
|
||||
{
|
||||
// TODO: Implement bindValue() method.
|
||||
// dd([$cell,$value]);
|
||||
// dd($cell->getColumn());
|
||||
// dd($cell->getDataType());
|
||||
// $cell->setDataType(DataType::TYPE_STRING);
|
||||
$noConvertToNumeric = ['A'];
|
||||
$cell->setValueExplicit($value, DataType::TYPE_STRING);
|
||||
if (is_numeric($value)) {
|
||||
if (! in_array($cell->getColumn(), $noConvertToNumeric)) {
|
||||
$cell->setValueExplicit($value, DataType::TYPE_NUMERIC);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
return $cell->getColumn();
|
||||
}
|
||||
}
|
||||
@ -1,78 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Exports;
|
||||
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Maatwebsite\Excel\Concerns\FromView;
|
||||
use Maatwebsite\Excel\Concerns\ShouldAutoSize;
|
||||
use PhpOffice\PhpSpreadsheet\Cell\Cell;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
|
||||
|
||||
class ExportSuppliersProfitCentersExcel implements FromView, ShouldAutoSize
|
||||
{
|
||||
public function __construct($data)
|
||||
{
|
||||
$this->data = $data;
|
||||
}
|
||||
|
||||
public function view(): View
|
||||
{
|
||||
return view('admin.export.SupplierProfitCenterExcel')->with($this->data);
|
||||
|
||||
}
|
||||
|
||||
private function setItemRowFormat(Worksheet $sheet, $dataRange)
|
||||
{
|
||||
$sheet->getStyle($dataRange)->applyFromArray([
|
||||
'borders' => [
|
||||
'outline' => [
|
||||
'borderStyle' => \PhpOffice\PhpSpreadsheet\Style\Border::BORDER_MEDIUM,
|
||||
],
|
||||
'inside' => [
|
||||
'borderStyle' => \PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THIN,
|
||||
],
|
||||
],
|
||||
]);
|
||||
|
||||
}
|
||||
|
||||
private function formatItemsRows(Worksheet $sheet)
|
||||
{
|
||||
|
||||
$pointerText = 'Végösszeg';
|
||||
$sumValueInRow = $this->searchByValue($sheet, $pointerText, true);
|
||||
$lastCell = $sheet->getHighestColumn();
|
||||
|
||||
if ($this->data['orderType'] == 'weekly') {
|
||||
$pointerText = 'Szállítási dátum:';
|
||||
$dateValueInRow = $this->searchByValue($sheet, $pointerText, true);
|
||||
for ($i = 0; $i < count($sumValueInRow); $i++) {
|
||||
$dataRange = 'A'.($dateValueInRow[$i]['row'] + 1).':'.$lastCell.($sumValueInRow[$i]['row'] - 1);
|
||||
$this->setItemRowFormat($sheet, $dataRange);
|
||||
}
|
||||
} else {
|
||||
$headValueInRow = $this->searchByValue($sheet, 'Cikkszám', true)[0]['row'];
|
||||
$dataRange = 'A'.($headValueInRow + 1).':'.$lastCell.($sumValueInRow[0]['row'] - 1);
|
||||
$this->setItemRowFormat($sheet, $dataRange);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function styles(Worksheet $sheet) {}
|
||||
|
||||
public function map($row): array
|
||||
{
|
||||
// TODO: Implement map() method.
|
||||
}
|
||||
|
||||
public function columnFormats(): array
|
||||
{
|
||||
// TODO: Implement columnFormats() method.
|
||||
return [];
|
||||
}
|
||||
|
||||
public function bindValue(Cell $cell, $value)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -1,175 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Exports;
|
||||
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Support\Collection;
|
||||
use Maatwebsite\Excel\Concerns\FromView;
|
||||
use Maatwebsite\Excel\Concerns\ShouldAutoSize;
|
||||
use Maatwebsite\Excel\Concerns\WithColumnFormatting;
|
||||
use Maatwebsite\Excel\Concerns\WithCustomValueBinder;
|
||||
use Maatwebsite\Excel\Concerns\WithMapping;
|
||||
use Maatwebsite\Excel\Concerns\WithStyles;
|
||||
use PhpOffice\PhpSpreadsheet\Cell\Cell;
|
||||
use PhpOffice\PhpSpreadsheet\Cell\DataType;
|
||||
use PhpOffice\PhpSpreadsheet\Style\Border;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
|
||||
|
||||
class ExportTest implements FromView, ShouldAutoSize, WithColumnFormatting, WithCustomValueBinder, WithMapping, WithStyles
|
||||
{
|
||||
public function __construct($data)
|
||||
{
|
||||
$this->data = $data;
|
||||
}
|
||||
|
||||
public function collection(): Collection
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
public function view(): View
|
||||
{
|
||||
// TODO: Implement view() method.
|
||||
return view('test.excelExport')->with($this->data);
|
||||
|
||||
return view('test.invoice')->with($this->data);
|
||||
}
|
||||
|
||||
private function searchByValue($sheet, $needValue, $partial = true): array
|
||||
{
|
||||
$ret = [
|
||||
'col' => null,
|
||||
'row' => null,
|
||||
];
|
||||
foreach ($sheet->getRowIterator() as $row) {
|
||||
$cellIterator = $row->getCellIterator();
|
||||
$cellIterator->setIterateOnlyExistingCells(true);
|
||||
foreach ($cellIterator as $cell) {
|
||||
if ($partial) {
|
||||
if (strpos($cell->getValue(), $needValue) !== false) {
|
||||
$ret['col'] = $cell->getColumn();
|
||||
$ret['row'] = $cell->getRow();
|
||||
}
|
||||
} else {
|
||||
if ($cell->getValue() == $needValue) {
|
||||
$ret['col'] = $cell->getColumn();
|
||||
$ret['row'] = $cell->getRow();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public function styles(Worksheet $sheet)
|
||||
{
|
||||
|
||||
$sumValueInRow = $this->searchByValue($sheet, 'Végösszeg', true)['row'];
|
||||
$headValueInRow = $this->searchByValue($sheet, 'Cikkszám', true)['row'];
|
||||
$lastCell = $sheet->getHighestColumn();
|
||||
$lastRow = $sheet->getHighestRow();
|
||||
|
||||
// orderProfitcenter data style in return
|
||||
|
||||
// rowsHead style in return
|
||||
|
||||
// data range border Style
|
||||
$dataRange = 'A'.($headValueInRow + 1).':'.$lastCell.$sumValueInRow;
|
||||
$sheet->getStyle($dataRange)->applyFromArray([
|
||||
'borders' => [
|
||||
'outline' => [
|
||||
'borderStyle' => \PhpOffice\PhpSpreadsheet\Style\Border::BORDER_MEDIUM,
|
||||
],
|
||||
'inside' => [
|
||||
'borderStyle' => \PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THIN,
|
||||
],
|
||||
],
|
||||
]);
|
||||
// footer style in return
|
||||
|
||||
return [
|
||||
'1' => [
|
||||
'borders' => [
|
||||
'outline' => [
|
||||
'borderStyle' => \PhpOffice\PhpSpreadsheet\Style\Border::BORDER_MEDIUM,
|
||||
],
|
||||
],
|
||||
'font' => [
|
||||
'bold' => true,
|
||||
],
|
||||
],
|
||||
$headValueInRow => [
|
||||
'borders' => [
|
||||
'outline' => [
|
||||
'borderStyle' => \PhpOffice\PhpSpreadsheet\Style\Border::BORDER_MEDIUM,
|
||||
],
|
||||
'inside' => [
|
||||
'borderStyle' => \PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THIN,
|
||||
],
|
||||
|
||||
],
|
||||
'font' => [
|
||||
'bold' => true,
|
||||
],
|
||||
],
|
||||
$sumValueInRow => [
|
||||
'borders' => [
|
||||
'outline' => [
|
||||
'borderStyle' => \PhpOffice\PhpSpreadsheet\Style\Border::BORDER_MEDIUM,
|
||||
],
|
||||
'inside' => [
|
||||
'borderStyle' => \PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THIN,
|
||||
],
|
||||
|
||||
],
|
||||
'font' => [
|
||||
'bold' => true,
|
||||
],
|
||||
],
|
||||
|
||||
];
|
||||
/* return [
|
||||
// Style the first row as bold text.
|
||||
1 => ['font' => ['bold' => true]],
|
||||
|
||||
// Styling a specific cell by coordinate.
|
||||
'B2' => ['font' => ['italic' => true]],
|
||||
|
||||
// Styling an entire column.
|
||||
'C' => ['font' => ['size' => 16]],
|
||||
];*/
|
||||
}
|
||||
|
||||
public function map($row): array
|
||||
{
|
||||
// TODO: Implement map() method.
|
||||
dd('asd');
|
||||
}
|
||||
|
||||
public function columnFormats(): array
|
||||
{
|
||||
// TODO: Implement columnFormats() method.
|
||||
return [];
|
||||
}
|
||||
|
||||
public function bindValue(Cell $cell, $value)
|
||||
{
|
||||
// TODO: Implement bindValue() method.
|
||||
// dd([$cell,$value]);
|
||||
// dd($cell->getColumn());
|
||||
// dd($cell->getDataType());
|
||||
// $cell->setDataType(DataType::TYPE_STRING);
|
||||
$noConvertToNumeric = ['A'];
|
||||
$cell->setValueExplicit($value, DataType::TYPE_STRING);
|
||||
if (is_numeric($value)) {
|
||||
if (! in_array($cell->getColumn(), $noConvertToNumeric)) {
|
||||
$cell->setValueExplicit($value, DataType::TYPE_NUMERIC);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
return $cell->getColumn();
|
||||
}
|
||||
}
|
||||
@ -1,38 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Facades;
|
||||
|
||||
use App\Database\Blueprint;
|
||||
use Illuminate\Database\Schema\Builder;
|
||||
use Illuminate\Support\Facades\Schema as BaseSchema;
|
||||
|
||||
class Schema extends BaseSchema
|
||||
{
|
||||
/**
|
||||
* Get a schema builder instance for a connection.
|
||||
*/
|
||||
public static function connection($name)
|
||||
{
|
||||
/** @var Builder $builder */
|
||||
$builder = static::$app['db']->connection($name)->getSchemaBuilder();
|
||||
$builder->blueprintResolver(static function ($table, $callback) {
|
||||
return new Blueprint($table, $callback);
|
||||
});
|
||||
|
||||
return $builder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a schema builder instance for the default connection.
|
||||
*/
|
||||
protected static function getFacadeAccessor(): Builder
|
||||
{
|
||||
/** @var Builder $builder */
|
||||
$builder = static::$app['db']->connection()->getSchemaBuilder();
|
||||
$builder->blueprintResolver(static function ($table, $callback) {
|
||||
return new Blueprint($table, $callback);
|
||||
});
|
||||
|
||||
return $builder;
|
||||
}
|
||||
}
|
||||
@ -1,37 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Auth;
|
||||
|
||||
use Filament\Schemas\Components\Component;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Auth\Pages\Login as BaseLogin;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
use SensitiveParameter;
|
||||
|
||||
class Login extends BaseLogin
|
||||
{
|
||||
protected function getEmailFormComponent(): Component
|
||||
{
|
||||
return TextInput::make('name')
|
||||
->label('Felhasználónév')
|
||||
->required()
|
||||
->autocomplete()
|
||||
->autofocus()
|
||||
->extraInputAttributes(['tabindex' => 1]);
|
||||
}
|
||||
|
||||
protected function getCredentialsFromFormData(#[SensitiveParameter] array $data): array
|
||||
{
|
||||
return [
|
||||
'name' => $data['name'],
|
||||
'password' => $data['password'],
|
||||
];
|
||||
}
|
||||
|
||||
protected function throwFailureValidationException(): never
|
||||
{
|
||||
throw ValidationException::withMessages([
|
||||
'data.name' => __('filament-panels::auth/pages/login.messages.failed'),
|
||||
]);
|
||||
}
|
||||
}
|
||||
@ -1,138 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Pages;
|
||||
|
||||
use App\Models\ProfitCenter;
|
||||
use App\Models\ProfitCenterSupplierSchedule;
|
||||
use App\Models\Supplier;
|
||||
use App\Services\NextDeliveryDateCalculatorService;
|
||||
use Filament\Pages\Page;
|
||||
|
||||
class CalendarTest extends Page
|
||||
{
|
||||
protected static string | \BackedEnum | null $navigationIcon = 'heroicon-o-calendar';
|
||||
|
||||
protected string $view = 'filament.pages.calendar-test';
|
||||
|
||||
protected static ?string $title = 'Naptár Teszt';
|
||||
|
||||
protected static bool $shouldRegisterNavigation = false;
|
||||
|
||||
public ?int $supplierId = null;
|
||||
|
||||
public ?int $profitCenterId = null;
|
||||
|
||||
public string $selectedDate = '';
|
||||
|
||||
public string $selectedTime = '';
|
||||
|
||||
public function mount(): void
|
||||
{
|
||||
$now = now();
|
||||
$this->selectedDate = $now->format('Y-m-d');
|
||||
$this->selectedTime = $now->format('H:i');
|
||||
|
||||
$first = ProfitCenterSupplierSchedule::first();
|
||||
|
||||
if ($first) {
|
||||
$this->supplierId = $first->supplier_id;
|
||||
$this->profitCenterId = $first->profit_center_id;
|
||||
}
|
||||
}
|
||||
|
||||
public function getSupplier(): ?Supplier
|
||||
{
|
||||
if (!$this->supplierId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return Supplier::find($this->supplierId);
|
||||
}
|
||||
|
||||
public function getNextDeliveryDate(): ?string
|
||||
{
|
||||
if (! $this->supplierId || ! $this->profitCenterId || ! $this->selectedDate || ! $this->selectedTime) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$dt = \Illuminate\Support\Carbon::parse("{$this->selectedDate} {$this->selectedTime}");
|
||||
|
||||
$result = app(NextDeliveryDateCalculatorService::class)->calculate(
|
||||
supplierId: $this->supplierId,
|
||||
profitCenterId: $this->profitCenterId,
|
||||
orderDateTime: $dt,
|
||||
);
|
||||
|
||||
return $result?->translatedFormat('Y. F j., l');
|
||||
}
|
||||
|
||||
public function getNextDeliveryDateRaw(): ?string
|
||||
{
|
||||
if (! $this->supplierId || ! $this->profitCenterId || ! $this->selectedDate || ! $this->selectedTime) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$dt = \Illuminate\Support\Carbon::parse("{$this->selectedDate} {$this->selectedTime}");
|
||||
|
||||
$result = app(NextDeliveryDateCalculatorService::class)->calculate(
|
||||
supplierId: $this->supplierId,
|
||||
profitCenterId: $this->profitCenterId,
|
||||
orderDateTime: $dt,
|
||||
);
|
||||
|
||||
return $result?->format('Y-m-d');
|
||||
}
|
||||
|
||||
public function getSuppliers(): array
|
||||
{
|
||||
return Supplier::orderBy('name')->pluck('name', 'id')->toArray();
|
||||
}
|
||||
|
||||
public function getProfitCenters(): array
|
||||
{
|
||||
if (!$this->supplierId) {
|
||||
return ProfitCenter::orderBy('name')->pluck('name', 'id')->toArray();
|
||||
}
|
||||
|
||||
$pcIds = ProfitCenterSupplierSchedule::where('supplier_id', $this->supplierId)
|
||||
->pluck('profit_center_id');
|
||||
|
||||
return ProfitCenter::whereIn('id', $pcIds)->orderBy('name')->pluck('name', 'id')->toArray();
|
||||
}
|
||||
|
||||
public function updatedSupplierId(): void
|
||||
{
|
||||
$this->profitCenterId = null;
|
||||
|
||||
$first = ProfitCenterSupplierSchedule::where('supplier_id', $this->supplierId)->first();
|
||||
|
||||
if ($first) {
|
||||
$this->profitCenterId = $first->profit_center_id;
|
||||
}
|
||||
|
||||
$this->dispatch('calendar-filter-changed', supplierId: $this->supplierId, profitCenterId: $this->profitCenterId);
|
||||
$this->dispatchNextDeliveryDateChanged();
|
||||
}
|
||||
|
||||
public function updatedProfitCenterId(): void
|
||||
{
|
||||
$this->dispatch('calendar-filter-changed', supplierId: $this->supplierId, profitCenterId: $this->profitCenterId);
|
||||
$this->dispatchNextDeliveryDateChanged();
|
||||
}
|
||||
|
||||
public function updatedSelectedDate(): void
|
||||
{
|
||||
$this->dispatchNextDeliveryDateChanged();
|
||||
}
|
||||
|
||||
public function updatedSelectedTime(): void
|
||||
{
|
||||
$this->dispatchNextDeliveryDateChanged();
|
||||
}
|
||||
|
||||
protected function dispatchNextDeliveryDateChanged(): void
|
||||
{
|
||||
$this->dispatch('next-delivery-date-changed', date: $this->getNextDeliveryDateRaw());
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,17 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Pages;
|
||||
|
||||
use Filament\Pages\Dashboard as BaseDashboard;
|
||||
|
||||
class Dashboard extends BaseDashboard
|
||||
{
|
||||
protected static string|\BackedEnum|null $navigationIcon = 'heroicon-o-home';
|
||||
|
||||
protected static ?string $title = 'Műszerfal';
|
||||
|
||||
public function getWidgets(): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
}
|
||||
@ -1,104 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Pages;
|
||||
|
||||
use Filament\Pages\Page;
|
||||
use Filament\Forms\Components\Select;
|
||||
use Filament\Forms\Components\DatePicker;
|
||||
use Filament\Forms\Components\Textarea;
|
||||
use Filament\Forms\Components\FileUpload;
|
||||
use Filament\Schemas\Schema;
|
||||
use Filament\Forms\Contracts\HasForms;
|
||||
use Filament\Forms\Concerns\InteractsWithForms;
|
||||
use App\Models\Supplier;
|
||||
use App\Models\PricelistFile;
|
||||
use App\Filament\Resources\PricelistFiles\PricelistFileResource;
|
||||
use App\Jobs\PricelistPreProcessJob;
|
||||
use Filament\Notifications\Notification;
|
||||
use Filament\Actions\Action;
|
||||
|
||||
use Illuminate\Contracts\Support\Htmlable;
|
||||
|
||||
class PriceListProcessor extends Page implements HasForms
|
||||
{
|
||||
use InteractsWithForms;
|
||||
|
||||
protected static string | \BackedEnum | null $navigationIcon = 'heroicon-o-document-text';
|
||||
|
||||
protected string $view = 'filament.pages.price-list-processor';
|
||||
|
||||
protected static ?string $title = 'Árlista feldolgozó';
|
||||
|
||||
protected static ?string $navigationLabel = 'Árlista feldolgozó';
|
||||
|
||||
protected static bool $shouldRegisterNavigation = false;
|
||||
|
||||
public ?array $data = [];
|
||||
|
||||
public function mount(): void
|
||||
{
|
||||
$this->form->fill();
|
||||
}
|
||||
|
||||
public function form(Schema $form): Schema
|
||||
{
|
||||
return $form
|
||||
->schema([
|
||||
Select::make('supplier_id')
|
||||
->label('Beszállító')
|
||||
->options(Supplier::query()->pluck('name', 'id'))
|
||||
->required()
|
||||
->searchable(),
|
||||
DatePicker::make('available_date')
|
||||
->label('Életbelépés dátuma')
|
||||
->required()
|
||||
->native(false)
|
||||
->displayFormat('Y.m.d'),
|
||||
Textarea::make('note')
|
||||
->label('Megjegyzés')
|
||||
->rows(3),
|
||||
FileUpload::make('filename')
|
||||
->label('Fájl kiválasztása')
|
||||
->required()
|
||||
->acceptedFileTypes(['application/vnd.ms-excel', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'text/csv'])
|
||||
->disk('public')
|
||||
->directory('pricelist-uploads')
|
||||
->preserveFilenames(),
|
||||
])
|
||||
->statePath('data');
|
||||
}
|
||||
|
||||
protected function getFormActions(): array
|
||||
{
|
||||
return [
|
||||
Action::make('save')
|
||||
->label('Feltöltés és feldolgozás indítása')
|
||||
->submit('save')
|
||||
->color('primary'),
|
||||
];
|
||||
}
|
||||
|
||||
public function save()
|
||||
{
|
||||
$data = $this->form->getState();
|
||||
|
||||
$pricelistFile = PricelistFile::create([
|
||||
'filename' => $data['filename'],
|
||||
'supplier_id' => $data['supplier_id'],
|
||||
'available_date' => $data['available_date'],
|
||||
'note' => $data['note'],
|
||||
]);
|
||||
|
||||
app(\App\Services\PricelistFileProcessService::class)->dispatchInitialChain($pricelistFile);
|
||||
|
||||
Notification::make()
|
||||
->title('Sikeres feltöltés')
|
||||
->body('Az árlista fájl rögzítve lett és a feldolgozás elindult.')
|
||||
->success()
|
||||
->send();
|
||||
|
||||
$this->form->fill();
|
||||
|
||||
return redirect()->to(PricelistFileResource::getUrl('view', ['record' => $pricelistFile]));
|
||||
}
|
||||
}
|
||||
@ -1,68 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\DeliveryCalendarOverrides;
|
||||
|
||||
use App\Filament\Resources\DeliveryCalendarOverrides\Pages\CreateDeliveryCalendarOverride;
|
||||
use App\Filament\Resources\DeliveryCalendarOverrides\Pages\EditDeliveryCalendarOverride;
|
||||
use App\Filament\Resources\DeliveryCalendarOverrides\Pages\ListDeliveryCalendarOverrides;
|
||||
use App\Filament\Resources\DeliveryCalendarOverrides\Schemas\DeliveryCalendarOverrideForm;
|
||||
use App\Filament\Resources\DeliveryCalendarOverrides\Tables\DeliveryCalendarOverridesTable;
|
||||
use App\Models\DeliveryCalendarOverride;
|
||||
use BackedEnum;
|
||||
use Filament\Resources\Resource;
|
||||
use Filament\Schemas\Schema;
|
||||
use Filament\Support\Icons\Heroicon;
|
||||
use Filament\Tables\Table;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\SoftDeletingScope;
|
||||
|
||||
class DeliveryCalendarOverrideResource extends Resource
|
||||
{
|
||||
protected static ?string $model = DeliveryCalendarOverride::class;
|
||||
|
||||
protected static string|BackedEnum|null $navigationIcon = 'heroicon-o-exclamation-triangle';
|
||||
|
||||
protected static string|\UnitEnum|null $navigationGroup = 'Szállítás';
|
||||
|
||||
protected static ?string $navigationLabel = 'Beszállítói felülbírálások';
|
||||
|
||||
protected static ?string $modelLabel = 'Beszállítói felülbírálás';
|
||||
|
||||
protected static ?string $pluralLabel = 'Beszállítói felülbírálások';
|
||||
|
||||
protected static ?string $breadcrumb = 'Beszállítói felülbírálások';
|
||||
|
||||
public static function form(Schema $schema): Schema
|
||||
{
|
||||
return DeliveryCalendarOverrideForm::configure($schema);
|
||||
}
|
||||
|
||||
public static function table(Table $table): Table
|
||||
{
|
||||
return DeliveryCalendarOverridesTable::configure($table);
|
||||
}
|
||||
|
||||
public static function getRelations(): array
|
||||
{
|
||||
return [
|
||||
//
|
||||
];
|
||||
}
|
||||
|
||||
public static function getPages(): array
|
||||
{
|
||||
return [
|
||||
'index' => ListDeliveryCalendarOverrides::route('/'),
|
||||
'create' => CreateDeliveryCalendarOverride::route('/create'),
|
||||
'edit' => EditDeliveryCalendarOverride::route('/{record}/edit'),
|
||||
];
|
||||
}
|
||||
|
||||
public static function getRecordRouteBindingEloquentQuery(): Builder
|
||||
{
|
||||
return parent::getRecordRouteBindingEloquentQuery()
|
||||
->withoutGlobalScopes([
|
||||
SoftDeletingScope::class,
|
||||
]);
|
||||
}
|
||||
}
|
||||
@ -1,11 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\DeliveryCalendarOverrides\Pages;
|
||||
|
||||
use App\Filament\Resources\DeliveryCalendarOverrides\DeliveryCalendarOverrideResource;
|
||||
use Filament\Resources\Pages\CreateRecord;
|
||||
|
||||
class CreateDeliveryCalendarOverride extends CreateRecord
|
||||
{
|
||||
protected static string $resource = DeliveryCalendarOverrideResource::class;
|
||||
}
|
||||
@ -1,23 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\DeliveryCalendarOverrides\Pages;
|
||||
|
||||
use App\Filament\Resources\DeliveryCalendarOverrides\DeliveryCalendarOverrideResource;
|
||||
use Filament\Actions\DeleteAction;
|
||||
use Filament\Actions\ForceDeleteAction;
|
||||
use Filament\Actions\RestoreAction;
|
||||
use Filament\Resources\Pages\EditRecord;
|
||||
|
||||
class EditDeliveryCalendarOverride extends EditRecord
|
||||
{
|
||||
protected static string $resource = DeliveryCalendarOverrideResource::class;
|
||||
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
DeleteAction::make(),
|
||||
ForceDeleteAction::make(),
|
||||
RestoreAction::make(),
|
||||
];
|
||||
}
|
||||
}
|
||||
@ -1,19 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\DeliveryCalendarOverrides\Pages;
|
||||
|
||||
use App\Filament\Resources\DeliveryCalendarOverrides\DeliveryCalendarOverrideResource;
|
||||
use Filament\Actions\CreateAction;
|
||||
use Filament\Resources\Pages\ListRecords;
|
||||
|
||||
class ListDeliveryCalendarOverrides extends ListRecords
|
||||
{
|
||||
protected static string $resource = DeliveryCalendarOverrideResource::class;
|
||||
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
CreateAction::make(),
|
||||
];
|
||||
}
|
||||
}
|
||||
@ -1,61 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\DeliveryCalendarOverrides\Schemas;
|
||||
|
||||
use App\Enums\OverrideScope;
|
||||
use Filament\Forms\Components\DatePicker;
|
||||
use Filament\Forms\Components\Select;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Forms\Components\Toggle;
|
||||
use Filament\Schemas\Components\Utilities\Get;
|
||||
use Filament\Schemas\Schema;
|
||||
|
||||
class DeliveryCalendarOverrideForm
|
||||
{
|
||||
public static function configure(Schema $schema): Schema
|
||||
{
|
||||
return $schema
|
||||
->components([
|
||||
Select::make('supplier_id')
|
||||
->label('Beszállító')
|
||||
->relationship('supplier', 'name', fn($query) => $query->where('hasDeliveryConstraint', true))
|
||||
->searchable()
|
||||
->required()
|
||||
->live(),
|
||||
Select::make('override_scope')
|
||||
->label('Felülbírálás szintje')
|
||||
->options(collect(OverrideScope::cases())->mapWithKeys(
|
||||
fn(OverrideScope $scope) => [$scope->value => $scope->label()]
|
||||
))
|
||||
->default(OverrideScope::General->value)
|
||||
->required()
|
||||
->live(),
|
||||
Select::make('delivery_schedule_id')
|
||||
->label('Szállítási sablon')
|
||||
->relationship('deliverySchedule', 'name')
|
||||
->searchable()
|
||||
->visible(fn(Get $get) => $get('override_scope') === OverrideScope::Region->value)
|
||||
->required(fn(Get $get) => $get('override_scope') === OverrideScope::Region->value),
|
||||
Select::make('profit_center_id')
|
||||
->label('Profitcenter')
|
||||
->relationship('profitCenter', 'name', fn($query, Get $get) => $query->when(
|
||||
$get('supplier_id'),
|
||||
fn($q, $supplierId) => $q->whereHas('suppliers', fn($s) => $s->where('suppliers.id', $supplierId))
|
||||
))
|
||||
->searchable()
|
||||
->visible(fn(Get $get) => $get('override_scope') === OverrideScope::ProfitCenter->value)
|
||||
->required(fn(Get $get) => $get('override_scope') === OverrideScope::ProfitCenter->value),
|
||||
DatePicker::make('date')
|
||||
->label('Dátum')
|
||||
->required()
|
||||
->native(false)
|
||||
->displayFormat('Y-m-d'),
|
||||
Toggle::make('is_delivery_day')
|
||||
->label('Szállítási nap?')
|
||||
->default(true),
|
||||
TextInput::make('description')
|
||||
->label('Indoklás / Megjegyzés')
|
||||
->maxLength(255),
|
||||
]);
|
||||
}
|
||||
}
|
||||
@ -1,72 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\DeliveryCalendarOverrides\Tables;
|
||||
|
||||
use App\Enums\OverrideScope;
|
||||
use Filament\Actions\BulkActionGroup;
|
||||
use Filament\Actions\DeleteBulkAction;
|
||||
use Filament\Actions\EditAction;
|
||||
use Filament\Actions\ForceDeleteBulkAction;
|
||||
use Filament\Actions\RestoreBulkAction;
|
||||
use Filament\Tables\Columns\IconColumn;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
use Filament\Tables\Filters\SelectFilter;
|
||||
use Filament\Tables\Filters\TrashedFilter;
|
||||
use Filament\Tables\Table;
|
||||
|
||||
class DeliveryCalendarOverridesTable
|
||||
{
|
||||
public static function configure(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->columns([
|
||||
TextColumn::make('supplier.name')
|
||||
->label('Beszállító')
|
||||
->searchable()
|
||||
->sortable(),
|
||||
TextColumn::make('override_scope')
|
||||
->label('Szint')
|
||||
->badge()
|
||||
->formatStateUsing(fn(OverrideScope $state) => $state->label())
|
||||
->color(fn(OverrideScope $state) => $state->color())
|
||||
->sortable(),
|
||||
TextColumn::make('deliverySchedule.name')
|
||||
->label('Szállítási sablon')
|
||||
->placeholder('—')
|
||||
->toggleable(),
|
||||
TextColumn::make('profitCenter.name')
|
||||
->label('Profitcenter')
|
||||
->placeholder('—')
|
||||
->toggleable(),
|
||||
TextColumn::make('date')
|
||||
->label('Dátum')
|
||||
->date('Y-m-d')
|
||||
->sortable(),
|
||||
IconColumn::make('is_delivery_day')
|
||||
->boolean()
|
||||
->label('Szállítási nap'),
|
||||
TextColumn::make('description')
|
||||
->label('Megjegyzés')
|
||||
->limit(30)
|
||||
->toggleable(isToggledHiddenByDefault: true),
|
||||
])
|
||||
->filters([
|
||||
SelectFilter::make('override_scope')
|
||||
->label('Felülbírálás szintje')
|
||||
->options(collect(OverrideScope::cases())->mapWithKeys(
|
||||
fn(OverrideScope $scope) => [$scope->value => $scope->label()]
|
||||
)),
|
||||
TrashedFilter::make(),
|
||||
])
|
||||
->recordActions([
|
||||
EditAction::make(),
|
||||
])
|
||||
->toolbarActions([
|
||||
BulkActionGroup::make([
|
||||
DeleteBulkAction::make(),
|
||||
ForceDeleteBulkAction::make(),
|
||||
RestoreBulkAction::make(),
|
||||
]),
|
||||
]);
|
||||
}
|
||||
}
|
||||
@ -1,68 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\DeliverySchedules;
|
||||
|
||||
use App\Filament\Resources\DeliverySchedules\Pages\CreateDeliverySchedule;
|
||||
use App\Filament\Resources\DeliverySchedules\Pages\EditDeliverySchedule;
|
||||
use App\Filament\Resources\DeliverySchedules\Pages\ListDeliverySchedules;
|
||||
use App\Filament\Resources\DeliverySchedules\Schemas\DeliveryScheduleForm;
|
||||
use App\Filament\Resources\DeliverySchedules\Tables\DeliverySchedulesTable;
|
||||
use App\Models\DeliverySchedule;
|
||||
use BackedEnum;
|
||||
use Filament\Resources\Resource;
|
||||
use Filament\Schemas\Schema;
|
||||
use Filament\Support\Icons\Heroicon;
|
||||
use Filament\Tables\Table;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\SoftDeletingScope;
|
||||
|
||||
class DeliveryScheduleResource extends Resource
|
||||
{
|
||||
protected static ?string $model = DeliverySchedule::class;
|
||||
|
||||
protected static string|BackedEnum|null $navigationIcon = 'heroicon-o-calendar-days';
|
||||
|
||||
protected static string|\UnitEnum|null $navigationGroup = 'Szállítás';
|
||||
|
||||
protected static ?string $navigationLabel = 'Szállítási sablonok';
|
||||
|
||||
protected static ?string $modelLabel = 'Szállítási sablon';
|
||||
|
||||
protected static ?string $pluralLabel = 'Szállítási sablonok';
|
||||
|
||||
protected static ?string $breadcrumb = 'Szállítási sablonok';
|
||||
|
||||
public static function form(Schema $schema): Schema
|
||||
{
|
||||
return DeliveryScheduleForm::configure($schema);
|
||||
}
|
||||
|
||||
public static function table(Table $table): Table
|
||||
{
|
||||
return DeliverySchedulesTable::configure($table);
|
||||
}
|
||||
|
||||
public static function getRelations(): array
|
||||
{
|
||||
return [
|
||||
//
|
||||
];
|
||||
}
|
||||
|
||||
public static function getPages(): array
|
||||
{
|
||||
return [
|
||||
'index' => ListDeliverySchedules::route('/'),
|
||||
'create' => CreateDeliverySchedule::route('/create'),
|
||||
'edit' => EditDeliverySchedule::route('/{record}/edit'),
|
||||
];
|
||||
}
|
||||
|
||||
public static function getRecordRouteBindingEloquentQuery(): Builder
|
||||
{
|
||||
return parent::getRecordRouteBindingEloquentQuery()
|
||||
->withoutGlobalScopes([
|
||||
SoftDeletingScope::class,
|
||||
]);
|
||||
}
|
||||
}
|
||||
@ -1,11 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\DeliverySchedules\Pages;
|
||||
|
||||
use App\Filament\Resources\DeliverySchedules\DeliveryScheduleResource;
|
||||
use Filament\Resources\Pages\CreateRecord;
|
||||
|
||||
class CreateDeliverySchedule extends CreateRecord
|
||||
{
|
||||
protected static string $resource = DeliveryScheduleResource::class;
|
||||
}
|
||||
@ -1,23 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\DeliverySchedules\Pages;
|
||||
|
||||
use App\Filament\Resources\DeliverySchedules\DeliveryScheduleResource;
|
||||
use Filament\Actions\DeleteAction;
|
||||
use Filament\Actions\ForceDeleteAction;
|
||||
use Filament\Actions\RestoreAction;
|
||||
use Filament\Resources\Pages\EditRecord;
|
||||
|
||||
class EditDeliverySchedule extends EditRecord
|
||||
{
|
||||
protected static string $resource = DeliveryScheduleResource::class;
|
||||
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
DeleteAction::make(),
|
||||
ForceDeleteAction::make(),
|
||||
RestoreAction::make(),
|
||||
];
|
||||
}
|
||||
}
|
||||
@ -1,19 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\DeliverySchedules\Pages;
|
||||
|
||||
use App\Filament\Resources\DeliverySchedules\DeliveryScheduleResource;
|
||||
use Filament\Actions\CreateAction;
|
||||
use Filament\Resources\Pages\ListRecords;
|
||||
|
||||
class ListDeliverySchedules extends ListRecords
|
||||
{
|
||||
protected static string $resource = DeliveryScheduleResource::class;
|
||||
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
CreateAction::make(),
|
||||
];
|
||||
}
|
||||
}
|
||||
@ -1,44 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\DeliverySchedules\Schemas;
|
||||
|
||||
use Filament\Schemas\Components\Grid;
|
||||
use Filament\Schemas\Components\Section;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Forms\Components\Toggle;
|
||||
use Filament\Schemas\Schema;
|
||||
|
||||
class DeliveryScheduleForm
|
||||
{
|
||||
public static function configure(Schema $schema): Schema
|
||||
{
|
||||
return $schema
|
||||
->components([
|
||||
Section::make('Sablon adatai')
|
||||
->columnSpanFull()
|
||||
->schema([
|
||||
Grid::make(2)
|
||||
->schema([
|
||||
TextInput::make('name')
|
||||
->label('Sablon neve')
|
||||
->required()
|
||||
->maxLength(255),
|
||||
Toggle::make('is_active')
|
||||
->label('Aktív')
|
||||
->default(true),
|
||||
]),
|
||||
Section::make('Szállítási napok')
|
||||
->columns(7)
|
||||
->schema([
|
||||
Toggle::make('monday')->label('Hétfő')->default(false),
|
||||
Toggle::make('tuesday')->label('Kedd')->default(false),
|
||||
Toggle::make('wednesday')->label('Szerda')->default(false),
|
||||
Toggle::make('thursday')->label('Csütörtök')->default(false),
|
||||
Toggle::make('friday')->label('Péntek')->default(false),
|
||||
Toggle::make('saturday')->label('Szombat')->default(false),
|
||||
Toggle::make('sunday')->label('Vasárnap')->default(false),
|
||||
]),
|
||||
]),
|
||||
]);
|
||||
}
|
||||
}
|
||||
@ -1,49 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\DeliverySchedules\Tables;
|
||||
|
||||
use Filament\Actions\BulkActionGroup;
|
||||
use Filament\Actions\DeleteBulkAction;
|
||||
use Filament\Actions\EditAction;
|
||||
use Filament\Actions\ForceDeleteBulkAction;
|
||||
use Filament\Actions\RestoreBulkAction;
|
||||
use Filament\Tables\Filters\TrashedFilter;
|
||||
use Filament\Tables\Table;
|
||||
|
||||
class DeliverySchedulesTable
|
||||
{
|
||||
public static function configure(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->columns([
|
||||
\Filament\Tables\Columns\TextColumn::make('name')
|
||||
->label('Név')
|
||||
->searchable()
|
||||
->sortable(),
|
||||
\Filament\Tables\Columns\IconColumn::make('monday')->boolean()->label('H'),
|
||||
\Filament\Tables\Columns\IconColumn::make('tuesday')->boolean()->label('K'),
|
||||
\Filament\Tables\Columns\IconColumn::make('wednesday')->boolean()->label('Sze'),
|
||||
\Filament\Tables\Columns\IconColumn::make('thursday')->boolean()->label('Cs'),
|
||||
\Filament\Tables\Columns\IconColumn::make('friday')->boolean()->label('P'),
|
||||
\Filament\Tables\Columns\IconColumn::make('saturday')->boolean()->label('Szo'),
|
||||
\Filament\Tables\Columns\IconColumn::make('sunday')->boolean()->label('V'),
|
||||
\Filament\Tables\Columns\IconColumn::make('is_active')
|
||||
->boolean()
|
||||
->label('Aktív')
|
||||
->sortable(),
|
||||
])
|
||||
->filters([
|
||||
TrashedFilter::make(),
|
||||
])
|
||||
->recordActions([
|
||||
EditAction::make(),
|
||||
])
|
||||
->toolbarActions([
|
||||
BulkActionGroup::make([
|
||||
DeleteBulkAction::make(),
|
||||
ForceDeleteBulkAction::make(),
|
||||
RestoreBulkAction::make(),
|
||||
]),
|
||||
]);
|
||||
}
|
||||
}
|
||||
@ -1,16 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\PricelistFiles\Pages;
|
||||
|
||||
use App\Filament\Resources\PricelistFiles\PricelistFileResource;
|
||||
use Filament\Resources\Pages\CreateRecord;
|
||||
|
||||
class CreatePricelistFile extends CreateRecord
|
||||
{
|
||||
protected static string $resource = PricelistFileResource::class;
|
||||
|
||||
protected function afterCreate(): void
|
||||
{
|
||||
app(\App\Services\PricelistFileProcessService::class)->dispatchInitialChain($this->record);
|
||||
}
|
||||
}
|
||||
@ -1,34 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\PricelistFiles\Pages;
|
||||
|
||||
use App\Enums\PricelistFileStatusEnum;
|
||||
use App\Filament\Resources\PricelistFiles\PricelistFileResource;
|
||||
use App\Services\PricelistFileProcessService;
|
||||
use Filament\Actions\DeleteAction;
|
||||
use Filament\Actions\ForceDeleteAction;
|
||||
use Filament\Actions\RestoreAction;
|
||||
use Filament\Actions\ViewAction;
|
||||
use Filament\Resources\Pages\EditRecord;
|
||||
|
||||
class EditPricelistFile extends EditRecord
|
||||
{
|
||||
protected static string $resource = PricelistFileResource::class;
|
||||
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
ViewAction::make(),
|
||||
DeleteAction::make(),
|
||||
ForceDeleteAction::make(),
|
||||
RestoreAction::make(),
|
||||
];
|
||||
}
|
||||
|
||||
protected function afterSave(): void
|
||||
{
|
||||
if ($this->record->status === PricelistFileStatusEnum::fail) {
|
||||
app(PricelistFileProcessService::class)->dispatchInitialChain($this->record);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,24 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\PricelistFiles\Pages;
|
||||
|
||||
use App\Filament\Resources\PricelistFiles\PricelistFileResource;
|
||||
use Filament\Actions\Action;
|
||||
use App\Filament\Pages\PriceListProcessor;
|
||||
use Filament\Resources\Pages\ListRecords;
|
||||
|
||||
class ListPricelistFiles extends ListRecords
|
||||
{
|
||||
protected static string $resource = PricelistFileResource::class;
|
||||
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
Action::make('create_pricelist')
|
||||
->label('Új árlista felvitele')
|
||||
->url(fn (): string => PriceListProcessor::getUrl())
|
||||
->button()
|
||||
->color('primary'),
|
||||
];
|
||||
}
|
||||
}
|
||||
@ -1,28 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\PricelistFiles\Pages;
|
||||
|
||||
use App\Filament\Resources\PricelistFiles\PricelistFileResource;
|
||||
use Filament\Actions\EditAction;
|
||||
use Filament\Resources\Pages\ViewRecord;
|
||||
use App\Enums\PricelistFileStatusEnum;
|
||||
|
||||
class ViewPricelistFile extends ViewRecord
|
||||
{
|
||||
protected static string $resource = PricelistFileResource::class;
|
||||
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
EditAction::make()
|
||||
->visible(fn ($record) => $record->status === PricelistFileStatusEnum::fail),
|
||||
];
|
||||
}
|
||||
|
||||
protected function getHeaderWidgets(): array
|
||||
{
|
||||
return [
|
||||
// Később ide jöhetnek widgetek, pl. statisztika a feldolgozásról
|
||||
];
|
||||
}
|
||||
}
|
||||
@ -1,80 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\PricelistFiles;
|
||||
|
||||
use App\Filament\Resources\PricelistFiles\Pages\CreatePricelistFile;
|
||||
use App\Filament\Resources\PricelistFiles\Pages\EditPricelistFile;
|
||||
use App\Filament\Resources\PricelistFiles\Pages\ListPricelistFiles;
|
||||
use App\Filament\Resources\PricelistFiles\Pages\ViewPricelistFile;
|
||||
use App\Filament\Resources\PricelistFiles\Schemas\PricelistFileForm;
|
||||
use App\Filament\Resources\PricelistFiles\Schemas\PricelistFileInfolist;
|
||||
use App\Filament\Resources\PricelistFiles\Tables\PricelistFilesTable;
|
||||
use App\Models\PricelistFile;
|
||||
use BackedEnum;
|
||||
use Filament\Resources\Resource;
|
||||
use Filament\Schemas\Schema;
|
||||
use Filament\Support\Icons\Heroicon;
|
||||
use Filament\Tables\Table;
|
||||
use Filament\Support\Enums\Width;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\SoftDeletingScope;
|
||||
|
||||
class PricelistFileResource extends Resource
|
||||
{
|
||||
protected static ?string $model = PricelistFile::class;
|
||||
|
||||
protected static string|BackedEnum|null $navigationIcon = 'heroicon-o-document-text';
|
||||
|
||||
protected static ?string $navigationLabel = 'Árlista feldolgozó';
|
||||
|
||||
protected static ?string $breadcrumb = 'Árlista feldolgozó';
|
||||
|
||||
protected static ?string $pluralLabel = 'Árlista feldolgozó';
|
||||
|
||||
protected static ?string $modelLabel = 'Árlista fájl';
|
||||
|
||||
public static function getMaxWidth(): Width|string|null
|
||||
{
|
||||
return Width::Full;
|
||||
}
|
||||
|
||||
public static function form(Schema $schema): Schema
|
||||
{
|
||||
return PricelistFileForm::configure($schema);
|
||||
}
|
||||
|
||||
public static function infolist(Schema $schema): Schema
|
||||
{
|
||||
return PricelistFileInfolist::configure($schema);
|
||||
}
|
||||
|
||||
public static function table(Table $table): Table
|
||||
{
|
||||
return PricelistFilesTable::configure($table);
|
||||
}
|
||||
|
||||
public static function getRelations(): array
|
||||
{
|
||||
return [
|
||||
RelationManagers\LinesRelationManager::class,
|
||||
];
|
||||
}
|
||||
|
||||
public static function getPages(): array
|
||||
{
|
||||
return [
|
||||
'index' => ListPricelistFiles::route('/'),
|
||||
'create' => CreatePricelistFile::route('/create'),
|
||||
'view' => ViewPricelistFile::route('/{record}'),
|
||||
'edit' => EditPricelistFile::route('/{record}/edit'),
|
||||
];
|
||||
}
|
||||
|
||||
public static function getRecordRouteBindingEloquentQuery(): Builder
|
||||
{
|
||||
return parent::getRecordRouteBindingEloquentQuery()
|
||||
->withoutGlobalScopes([
|
||||
SoftDeletingScope::class,
|
||||
]);
|
||||
}
|
||||
}
|
||||
@ -1,283 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\PricelistFiles\RelationManagers;
|
||||
|
||||
use App\Enums\PricelistFileLineStatusEnum;
|
||||
use App\Enums\PricelistFileStatusEnum;
|
||||
use App\Services\PriceListService;
|
||||
use Filament\Actions\ViewAction;
|
||||
use Filament\Infolists\Components\TextEntry;
|
||||
use Filament\Resources\RelationManagers\RelationManager;
|
||||
use Filament\Schemas\Components\EmbeddedTable;
|
||||
use Filament\Schemas\Components\Grid;
|
||||
use Filament\Schemas\Components\RenderHook;
|
||||
use Filament\Schemas\Components\Section;
|
||||
use Filament\Schemas\Components\Text;
|
||||
use Filament\Schemas\Schema;
|
||||
use Filament\Support\Facades\FilamentView;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
use Filament\Tables\Table;
|
||||
use Filament\Tables\View\TablesRenderHook;
|
||||
use Filament\View\PanelsRenderHook;
|
||||
use Filament\Support\Enums\Width;
|
||||
use Illuminate\Support\HtmlString;
|
||||
use Filament\Schemas\Components\Tabs\Tab;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
class LinesRelationManager extends RelationManager
|
||||
{
|
||||
protected static string $relationship = 'lines';
|
||||
|
||||
protected static ?string $title = 'Feldolgozott sorok';
|
||||
|
||||
public function booted()
|
||||
{
|
||||
FilamentView::registerRenderHook(
|
||||
TablesRenderHook::TOOLBAR_START,
|
||||
fn () => $this->getTabsContentComponent()->container($this->makeSchema())->toHtml(),
|
||||
scopes: static::class,
|
||||
);
|
||||
}
|
||||
|
||||
public function content(Schema $schema): Schema
|
||||
{
|
||||
return $schema
|
||||
->components([
|
||||
RenderHook::make(PanelsRenderHook::RESOURCE_RELATION_MANAGER_BEFORE),
|
||||
EmbeddedTable::make(),
|
||||
RenderHook::make(PanelsRenderHook::RESOURCE_RELATION_MANAGER_AFTER),
|
||||
]);
|
||||
}
|
||||
|
||||
public function getTabs(): array
|
||||
{
|
||||
$ownerRecord = $this->getOwnerRecord();
|
||||
$counts = $ownerRecord->lines()
|
||||
->selectRaw('status, count(*) as count')
|
||||
->groupBy('status')
|
||||
->pluck('count', 'status');
|
||||
|
||||
return [
|
||||
'all' => Tab::make('Mind')
|
||||
->badge($counts->sum()),
|
||||
'hibas' => Tab::make('Hibás')
|
||||
->icon(PricelistFileLineStatusEnum::error->icon())
|
||||
->badgeColor(PricelistFileLineStatusEnum::error->color())
|
||||
->badge($counts->get(PricelistFileLineStatusEnum::error->value, 0))
|
||||
->modifyQueryUsing(fn (Builder $query) => $query->where('status', PricelistFileLineStatusEnum::error)),
|
||||
'warning' => Tab::make('Figyelmeztetések')
|
||||
->icon(PricelistFileLineStatusEnum::warning->icon())
|
||||
->badgeColor(PricelistFileLineStatusEnum::warning->color())
|
||||
->badge($counts->get(PricelistFileLineStatusEnum::warning->value, 0))
|
||||
->modifyQueryUsing(fn (Builder $query) => $query->where('status', PricelistFileLineStatusEnum::warning)),
|
||||
'uj' => Tab::make('Új')
|
||||
->icon(PricelistFileLineStatusEnum::new_product->icon())
|
||||
->badgeColor(PricelistFileLineStatusEnum::new_product->color())
|
||||
->badge($counts->get(PricelistFileLineStatusEnum::new_product->value, 0))
|
||||
->modifyQueryUsing(fn (Builder $query) => $query->where('status', PricelistFileLineStatusEnum::new_product)),
|
||||
'modosult' => Tab::make('Módosult')
|
||||
->icon(PricelistFileLineStatusEnum::updated->icon())
|
||||
->badgeColor(PricelistFileLineStatusEnum::updated->color())
|
||||
->badge($counts->get(PricelistFileLineStatusEnum::updated->value, 0))
|
||||
->modifyQueryUsing(fn (Builder $query) => $query->where('status', PricelistFileLineStatusEnum::updated)),
|
||||
];
|
||||
}
|
||||
|
||||
public function form(Schema $schema): Schema
|
||||
{
|
||||
return $schema
|
||||
->components([
|
||||
Grid::make(1)
|
||||
->schema([
|
||||
Section::make('Módosulások')
|
||||
->schema([
|
||||
Text::make(fn ($record) => new HtmlString(
|
||||
'<div class="grid grid-cols-1 gap-4">' .
|
||||
collect($record->diff ?? [])->map(function ($d, $field) {
|
||||
$old = $d['old_label'] ?? $d['old'] ?? 'N/A';
|
||||
$new = $d['new_label'] ?? $d['new'] ?? 'N/A';
|
||||
$label = $d['label'] ?? $field;
|
||||
|
||||
if ($old === '' || $old === null) $old = '<i>(üres)</i>';
|
||||
if ($new === '' || $new === null) $new = '<i>(üres)</i>';
|
||||
|
||||
// Ár formázása ha árról van szó
|
||||
if ($field === 'price') {
|
||||
$old = number_format((float)($d['old'] ?? 0), 2, ',', ' ') . ' Ft';
|
||||
$new = number_format((float)($d['new'] ?? 0), 2, ',', ' ') . ' Ft';
|
||||
}
|
||||
|
||||
return "<div class='text-sm border-l-4 border-info-500 pl-3 py-1 bg-info-50/50 dark:bg-info-950/20'>
|
||||
<div class='font-bold text-gray-700 dark:text-gray-300'>$label</div>
|
||||
<div class='flex items-center gap-2 mt-1'>
|
||||
<span class='text-gray-500 line-through'>$old</span>
|
||||
<span class='text-gray-400'>→</span>
|
||||
<span class='text-info-600 font-bold'>$new</span>
|
||||
</div>
|
||||
</div>";
|
||||
})->join('') .
|
||||
'</div>'
|
||||
)),
|
||||
])
|
||||
->visible(fn ($record) => !empty($record->diff)),
|
||||
|
||||
Section::make('Validációs üzenetek')
|
||||
->schema([
|
||||
Text::make(fn ($record) => new HtmlString(
|
||||
'<ul class="list-disc ml-5">' .
|
||||
collect($record->validation_messages ?? [])->map(fn ($msg) => "<li>$msg</li>")->join('') .
|
||||
'</ul>'
|
||||
)),
|
||||
])
|
||||
->visible(fn ($record) => !empty($record->validation_messages)),
|
||||
])
|
||||
->columnSpan(1)
|
||||
->visible(fn ($record) => !empty($record->diff) || !empty($record->validation_messages)),
|
||||
|
||||
Section::make('Adatok')
|
||||
->schema([
|
||||
Text::make(fn ($record) => new HtmlString(
|
||||
'
|
||||
<table class="min-w-full divide-y divide-gray-200 dark:divide-white/10">
|
||||
<thead class="bg-gray-50 dark:bg-white/5">
|
||||
<tr>
|
||||
<th class="px-3 py-2 text-left text-xs font-medium text-gray-500 uppercase tracking-wider w-1/3">Oszlop</th>
|
||||
<th class="px-3 py-2 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Érték</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="bg-white dark:bg-transparent divide-y divide-gray-200 dark:divide-white/10">
|
||||
' . collect($record->payload ?? [])->map(function ($value, $key) {
|
||||
$valStr = is_array($value) ? json_encode($value) : (string)$value;
|
||||
return '<tr>
|
||||
<td class="px-3 py-2 text-sm text-gray-500 dark:text-gray-400 font-medium bg-gray-50/50 dark:bg-white/5">' . e($key) . '</td>
|
||||
<td class="px-3 py-2 text-sm text-gray-900 dark:text-gray-200 whitespace-normal break-words">' . e($valStr) . '</td>
|
||||
</tr>';
|
||||
})->join('') . '
|
||||
</tbody>
|
||||
</table>
|
||||
'
|
||||
)),
|
||||
])
|
||||
->columnSpan(fn ($record) => (empty($record->diff) && empty($record->validation_messages)) ? 2 : 1),
|
||||
]);
|
||||
}
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->recordTitleAttribute('id')
|
||||
->columns([
|
||||
TextColumn::make('row_number')
|
||||
->label('#')
|
||||
->sortable()
|
||||
->width('50px'),
|
||||
|
||||
TextColumn::make('status')
|
||||
->label('Státusz')
|
||||
->badge()
|
||||
->color(fn (PricelistFileLineStatusEnum $state) => $state->color())
|
||||
->formatStateUsing(fn (PricelistFileLineStatusEnum $state) => $state->label())
|
||||
->icon(fn (PricelistFileLineStatusEnum $state) => $state->icon())
|
||||
->sortable(),
|
||||
|
||||
TextColumn::make('product_info')
|
||||
->label('Termék')
|
||||
->description(fn ($record) => $record->payload[PriceListService::EXPECTED_HEADERS[4]] ?? '')
|
||||
->getStateUsing(fn ($record) => $record->payload[PriceListService::EXPECTED_HEADERS[0]] ?? 'N/A')
|
||||
->color(fn ($record) => !empty($record->diff) ? 'info' : null)
|
||||
->wrap()
|
||||
->searchable(query: function ($query, string $search) {
|
||||
$sku = PriceListService::EXPECTED_HEADERS[0];
|
||||
$name = PriceListService::EXPECTED_HEADERS[4];
|
||||
$query->where("payload->$sku", 'like', "%{$search}%")
|
||||
->orWhere("payload->$name", 'like', "%{$search}%");
|
||||
}),
|
||||
|
||||
|
||||
TextColumn::make('price_diff')
|
||||
->label('Árváltozás')
|
||||
->html()
|
||||
->getStateUsing(function ($record) {
|
||||
// Biztonságos elérés data_get-tel, mert a diff lehet null
|
||||
$oldPrice = data_get($record->diff, 'price.old');
|
||||
|
||||
// Az új árat a diff-ből vesszük (már float), vagy a payload-ból (string lehet)
|
||||
$newPriceRaw = data_get($record->diff, 'price.new') ?? data_get($record->payload, PriceListService::EXPECTED_HEADERS[14]);
|
||||
|
||||
// Normalizálás: szóközök eltávolítása és tizedesvessző cseréje
|
||||
$newPrice = is_string($newPriceRaw)
|
||||
? (float) str_replace([' ', ','], ['', '.'], $newPriceRaw)
|
||||
: (float) $newPriceRaw;
|
||||
|
||||
// Ha nincs régi ár, vagy az nulla, akkor nincs százalékos számítás
|
||||
if (empty($oldPrice) || (float)$oldPrice === 0.0) {
|
||||
return number_format($newPrice, 2, ',', ' ') . ' Ft';
|
||||
}
|
||||
|
||||
$oldPrice = (float) $oldPrice;
|
||||
$diffPercent = (($newPrice / $oldPrice) - 1) * 100;
|
||||
|
||||
$colorClass = $diffPercent > 0 ? 'text-danger-600' : ($diffPercent < 0 ? 'text-success-600' : 'text-gray-600');
|
||||
$icon = $diffPercent > 0 ? '↑' : ($diffPercent < 0 ? '↓' : '');
|
||||
|
||||
return sprintf(
|
||||
'<div class="flex flex-col">
|
||||
<span class="text-xs text-gray-500 line-through">%s Ft</span>
|
||||
<span class="font-bold">%s Ft <span class="%s">%s %s%%</span></span>
|
||||
</div>',
|
||||
number_format($oldPrice, 2, ',', ' '),
|
||||
number_format($newPrice, 2, ',', ' '),
|
||||
$colorClass,
|
||||
$icon,
|
||||
number_format(abs($diffPercent), 1, ',', ' ')
|
||||
);
|
||||
})
|
||||
->visible(fn ($livewire) => $livewire->getOwnerRecord()->status !== PricelistFileStatusEnum::todo),
|
||||
|
||||
TextColumn::make('validation_messages')
|
||||
->label('Megjegyzés')
|
||||
->listWithLineBreaks()
|
||||
->bulleted()
|
||||
->wrap()
|
||||
->color(fn ($state) => collect($state)->contains(fn ($msg) => str_contains($msg, 'Hiányzó') || str_contains($msg, 'Ismeretlen') || str_contains($msg, 'Érvénytelen')) ? 'danger' : 'info')
|
||||
->getStateUsing(function ($record) {
|
||||
$messages = collect($record->validation_messages ?? [])->values();
|
||||
|
||||
$diffMessages = collect($record->diff ?? [])->map(function ($d, $field) {
|
||||
$label = $d['label'] ?? $field;
|
||||
$old = $d['old_label'] ?? $d['old'] ?? 'N/A';
|
||||
$new = $d['new_label'] ?? $d['new'] ?? 'N/A';
|
||||
|
||||
if ($field === 'price') {
|
||||
$old = number_format((float)($d['old'] ?? 0), 0, ',', ' ') . ' Ft';
|
||||
$new = number_format((float)($d['new'] ?? 0), 0, ',', ' ') . ' Ft';
|
||||
}
|
||||
|
||||
return "Módosult $label: $old -> $new";
|
||||
})->values();
|
||||
|
||||
return $messages->merge($diffMessages)->toArray();
|
||||
}),
|
||||
])
|
||||
->filters([
|
||||
//
|
||||
])
|
||||
->headerActions([
|
||||
//
|
||||
])
|
||||
->actions([
|
||||
ViewAction::make()
|
||||
->slideOver()
|
||||
->modalWidth(Width::FourExtraLarge)
|
||||
->iconButton()
|
||||
->modalHeading(fn ($record) => "Sor száma: #{$record->row_number}")
|
||||
->modalDescription(fn ($record) => "Státusz: " . $record->status->label()),
|
||||
])
|
||||
->bulkActions([
|
||||
//
|
||||
])
|
||||
->defaultSort('row_number', 'asc')
|
||||
->striped()
|
||||
->poll('5s');
|
||||
}
|
||||
}
|
||||
@ -1,48 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\PricelistFiles\Schemas;
|
||||
|
||||
use App\Models\Supplier;
|
||||
use Filament\Forms\Components\DatePicker;
|
||||
use Filament\Forms\Components\FileUpload;
|
||||
use Filament\Forms\Components\Select;
|
||||
use Filament\Forms\Components\Textarea;
|
||||
use Filament\Schemas\Components\Grid;
|
||||
use Filament\Schemas\Components\Section;
|
||||
use Filament\Schemas\Schema;
|
||||
|
||||
class PricelistFileForm
|
||||
{
|
||||
public static function configure(Schema $schema): Schema
|
||||
{
|
||||
return $schema
|
||||
->components([
|
||||
Section::make('Árlista fájl adatai')
|
||||
->schema([
|
||||
Grid::make(2)
|
||||
->schema([
|
||||
Select::make('supplier_id')
|
||||
->label('Beszállító')
|
||||
->options(Supplier::query()->pluck('name', 'id'))
|
||||
->required()
|
||||
->searchable(),
|
||||
DatePicker::make('available_date')
|
||||
->label('Életbelépés dátuma')
|
||||
->required()
|
||||
->native(false)
|
||||
->displayFormat('Y.m.d'),
|
||||
]),
|
||||
Textarea::make('note')
|
||||
->label('Megjegyzés')
|
||||
->rows(3),
|
||||
FileUpload::make('filename')
|
||||
->label('Fájl kiválasztása')
|
||||
->required()
|
||||
->acceptedFileTypes(['application/vnd.ms-excel', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'text/csv'])
|
||||
->disk('public')
|
||||
->directory('pricelist-uploads')
|
||||
->preserveFilenames(),
|
||||
])
|
||||
]);
|
||||
}
|
||||
}
|
||||
@ -1,203 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\PricelistFiles\Schemas;
|
||||
|
||||
use App\Enums\PricelistFileStatusEnum;
|
||||
use Filament\Schemas\Components\Grid;
|
||||
use Filament\Schemas\Components\Section;
|
||||
use Filament\Schemas\Components\Text;
|
||||
use Filament\Infolists\Components\RepeatableEntry;
|
||||
use Filament\Infolists\Components\TextEntry;
|
||||
use Filament\Schemas\Schema;
|
||||
use Filament\Support\Enums\FontWeight;
|
||||
use Filament\Support\Enums\IconPosition;
|
||||
use Filament\Support\Enums\Width;
|
||||
|
||||
class PricelistFileInfolist
|
||||
{
|
||||
public static function configure(Schema $schema): Schema
|
||||
{
|
||||
return $schema
|
||||
->components([
|
||||
Section::make(null)
|
||||
->poll('5s')
|
||||
->columnSpanFull()
|
||||
->maxWidth(Width::Full)
|
||||
->schema([
|
||||
Grid::make(2)
|
||||
->columnSpanFull()
|
||||
->maxWidth(Width::Full)
|
||||
->schema([
|
||||
// BAL OSZLOP
|
||||
Grid::make(1)
|
||||
->columnSpan(1)
|
||||
->schema([
|
||||
Section::make('Fájl információk')
|
||||
->schema([
|
||||
Grid::make(3)
|
||||
->schema([
|
||||
TextEntry::make('filename')
|
||||
->label('Fájlnév')
|
||||
->icon('heroicon-o-document-text')
|
||||
->color('primary'),
|
||||
TextEntry::make('supplier.name')
|
||||
->label('Beszállító')
|
||||
->icon('heroicon-o-user'),
|
||||
TextEntry::make('status')
|
||||
->label('Státusz')
|
||||
->badge()
|
||||
->formatStateUsing(fn (PricelistFileStatusEnum $state): string => $state->label())
|
||||
->color(fn (PricelistFileStatusEnum $state): string => match ($state) {
|
||||
PricelistFileStatusEnum::todo => 'gray',
|
||||
PricelistFileStatusEnum::inprogress => 'info',
|
||||
PricelistFileStatusEnum::done => 'success',
|
||||
PricelistFileStatusEnum::fail => 'danger',
|
||||
PricelistFileStatusEnum::waiting_for_approval => 'primary',
|
||||
PricelistFileStatusEnum::closed => 'warning',
|
||||
}),
|
||||
]),
|
||||
Grid::make(3)
|
||||
->schema([
|
||||
TextEntry::make('available_date')
|
||||
->label('Életbelépés')
|
||||
->date('Y.m.d'),
|
||||
TextEntry::make('created_at')
|
||||
->label('Feltöltés')
|
||||
->dateTime('Y.m.d H:i'),
|
||||
]),
|
||||
// SÁRGA NÉGYZET JAVÍTÁSA: Teljes szélességben alul, csak hiba esetén
|
||||
TextEntry::make('processing_current_step')
|
||||
->label('Validációs hiba')
|
||||
->weight('bold')
|
||||
->color('danger')
|
||||
->columnSpanFull()
|
||||
->visible(fn ($record) => $record->status === PricelistFileStatusEnum::fail)
|
||||
->formatStateUsing(fn ($state, $record) => str_contains((string)$state, 'hibás') ? $state : "Hiba történt a folyamat során: $state"),
|
||||
|
||||
// Folyamatban lévő állapot kijelzése (nem hiba, de hasznos)
|
||||
TextEntry::make('processing_current_step_inprogress')
|
||||
->label('Aktuális folyamat')
|
||||
->getStateUsing(fn ($record) => $record->processing_current_step)
|
||||
->weight('bold')
|
||||
->color('info')
|
||||
->columnSpanFull()
|
||||
->visible(fn ($record) => $record->status === PricelistFileStatusEnum::inprogress)
|
||||
->formatStateUsing(fn ($state, $record) => "$state ({$record->processing_current_step_percentage}%)"),
|
||||
|
||||
TextEntry::make('note')
|
||||
->label('Megjegyzés')
|
||||
->placeholder('Nincs megjegyzés')
|
||||
->columnSpanFull(),
|
||||
]),
|
||||
]),
|
||||
|
||||
// JOBB OSZLOP
|
||||
Grid::make(1)
|
||||
->columnSpan(1)
|
||||
->schema([
|
||||
Section::make('Fájl statisztika') // KÉK NÉGYZETEK JAVÍTÁSA: Összevont szekció
|
||||
->schema([
|
||||
Grid::make(5)->schema([
|
||||
TextEntry::make('lines_count')
|
||||
->label('Sorok')
|
||||
->icon('heroicon-o-list-bullet')
|
||||
->getStateUsing(fn ($record) => $record->lines()->count()),
|
||||
TextEntry::make('error_lines_count')
|
||||
->label('Hibás')
|
||||
->icon('heroicon-o-x-circle')
|
||||
->color('danger')
|
||||
->getStateUsing(fn ($record) => $record->lines()->where('status', 'error')->count()),
|
||||
TextEntry::make('warning_lines_count')
|
||||
->label('Figyelm.')
|
||||
->icon('heroicon-o-exclamation-triangle')
|
||||
->color('warning')
|
||||
->getStateUsing(fn ($record) => $record->lines()->where('status', 'warning')->count()),
|
||||
TextEntry::make('new_lines_count')
|
||||
->label('Új')
|
||||
->icon('heroicon-o-sparkles')
|
||||
->color('info')
|
||||
->getStateUsing(fn ($record) => $record->lines()->where('status', 'new_product')->count()),
|
||||
TextEntry::make('updated_lines_count')
|
||||
->label('Módosult')
|
||||
->icon('heroicon-o-pencil-square')
|
||||
->color('primary')
|
||||
->getStateUsing(fn ($record) => $record->lines()->where('status', 'updated')->count()),
|
||||
]),
|
||||
Grid::make(4)->schema([
|
||||
TextEntry::make('file_meta.preprocess.statistics.data_rows')
|
||||
->label('Adatsorok')
|
||||
->icon('heroicon-o-table-cells'),
|
||||
TextEntry::make('file_meta.preprocess.statistics.column_count')
|
||||
->label('Oszlopok'),
|
||||
TextEntry::make('file_meta.preprocess.file_info.file_size_human')
|
||||
->label('Fájlméret'),
|
||||
TextEntry::make('file_meta.preprocess.duration_seconds')
|
||||
->label('Idő')
|
||||
->suffix(' mp'),
|
||||
])
|
||||
->extraAttributes(['class' => 'mt-4 border-t pt-4']),
|
||||
])
|
||||
->visible(fn ($record) => $record->lines()->exists() || !empty($record->file_meta['preprocess'] ?? [])),
|
||||
|
||||
Section::make('Feldolgozási folyamat (Workflow)')
|
||||
->collapsible()
|
||||
->collapsed(fn ($record) => $record->status !== PricelistFileStatusEnum::inprogress)
|
||||
->schema([
|
||||
RepeatableEntry::make('workflow_steps')
|
||||
->label(false)
|
||||
->schema([
|
||||
TextEntry::make('label')
|
||||
->label('Lépés')
|
||||
->weight('bold')
|
||||
->inlineLabel(),
|
||||
TextEntry::make('status')
|
||||
->label('Állapot')
|
||||
->badge()
|
||||
->inlineLabel()
|
||||
->formatStateUsing(fn (string $state): string => match ($state) {
|
||||
'pending' => 'várakozik',
|
||||
'inprogress' => 'folyamatban',
|
||||
'completed' => 'kész',
|
||||
'failed' => 'hiba',
|
||||
default => $state,
|
||||
})
|
||||
->color(fn (string $state): string => match ($state) {
|
||||
'pending' => 'gray',
|
||||
'inprogress' => 'info',
|
||||
'completed' => 'success',
|
||||
'failed' => 'danger',
|
||||
default => 'gray',
|
||||
})
|
||||
->icon(fn (string $state): string => match ($state) {
|
||||
'pending' => 'heroicon-o-clock',
|
||||
'inprogress' => 'heroicon-o-arrow-path',
|
||||
'completed' => 'heroicon-o-check-circle',
|
||||
'failed' => 'heroicon-o-x-circle',
|
||||
default => 'heroicon-o-question-mark-circle',
|
||||
}),
|
||||
])
|
||||
->columns(2)
|
||||
->columnSpanFull(),
|
||||
]),
|
||||
|
||||
RepeatableEntry::make('file_meta.preprocess.warnings')
|
||||
->label('Előfeldolgozási figyelmeztetések')
|
||||
->schema([
|
||||
TextEntry::make('message')->label('Leírás')->color('warning'),
|
||||
TextEntry::make('severity')->label('Súlyosság')->badge()->color('warning'),
|
||||
])
|
||||
->visible(fn ($record) => !empty($record->file_meta['preprocess']['warnings'] ?? [])),
|
||||
|
||||
RepeatableEntry::make('file_meta.preprocess.errors')
|
||||
->label('Előfeldolgozási hibák')
|
||||
->schema([
|
||||
TextEntry::make('message')->label('Leírás')->color('danger'),
|
||||
TextEntry::make('severity')->label('Súlyosság')->badge()->color('danger'),
|
||||
])
|
||||
->visible(fn ($record) => !empty($record->file_meta['preprocess']['errors'] ?? [])),
|
||||
]),
|
||||
]),
|
||||
]),
|
||||
]);
|
||||
}
|
||||
}
|
||||
@ -1,72 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\PricelistFiles\Tables;
|
||||
|
||||
use Filament\Actions\BulkActionGroup;
|
||||
use Filament\Actions\DeleteBulkAction;
|
||||
use Filament\Actions\EditAction;
|
||||
use Filament\Actions\ForceDeleteBulkAction;
|
||||
use Filament\Actions\RestoreBulkAction;
|
||||
use Filament\Actions\ViewAction;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
use Filament\Tables\Filters\TrashedFilter;
|
||||
use Filament\Tables\Table;
|
||||
use App\Enums\PricelistFileStatusEnum;
|
||||
|
||||
class PricelistFilesTable
|
||||
{
|
||||
public static function configure(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->poll('5s')
|
||||
->columns([
|
||||
TextColumn::make('filename')
|
||||
->label('Fájlnév')
|
||||
->searchable()
|
||||
->sortable(),
|
||||
TextColumn::make('supplier.name')
|
||||
->label('Beszállító')
|
||||
->searchable()
|
||||
->sortable(),
|
||||
TextColumn::make('status')
|
||||
->label('Státusz')
|
||||
->badge()
|
||||
->formatStateUsing(fn (PricelistFileStatusEnum $state): string => $state->label())
|
||||
->color(fn (PricelistFileStatusEnum $state): string => match ($state) {
|
||||
PricelistFileStatusEnum::todo => 'gray',
|
||||
PricelistFileStatusEnum::inprogress => 'info',
|
||||
PricelistFileStatusEnum::done => 'success',
|
||||
PricelistFileStatusEnum::fail => 'danger',
|
||||
PricelistFileStatusEnum::waiting_for_approval => 'primary',
|
||||
PricelistFileStatusEnum::closed => 'warning',
|
||||
})
|
||||
->sortable(),
|
||||
TextColumn::make('processing_current_step')
|
||||
->label('Aktuális lépés')
|
||||
->placeholder('Nincs adat'),
|
||||
TextColumn::make('processing_current_step_percentage')
|
||||
->label('Készültség')
|
||||
->suffix('%')
|
||||
->alignCenter(),
|
||||
TextColumn::make('created_at')
|
||||
->label('Feltöltve')
|
||||
->dateTime('Y.m.d H:i')
|
||||
->sortable(),
|
||||
])
|
||||
->filters([
|
||||
TrashedFilter::make(),
|
||||
])
|
||||
->recordActions([
|
||||
ViewAction::make(),
|
||||
EditAction::make()
|
||||
->visible(fn ($record) => $record->status === PricelistFileStatusEnum::fail),
|
||||
])
|
||||
->toolbarActions([
|
||||
BulkActionGroup::make([
|
||||
DeleteBulkAction::make(),
|
||||
ForceDeleteBulkAction::make(),
|
||||
RestoreBulkAction::make(),
|
||||
]),
|
||||
]);
|
||||
}
|
||||
}
|
||||
@ -1,11 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\ProfitCenterSupplierSchedules\Pages;
|
||||
|
||||
use App\Filament\Resources\ProfitCenterSupplierSchedules\ProfitCenterSupplierScheduleResource;
|
||||
use Filament\Resources\Pages\CreateRecord;
|
||||
|
||||
class CreateProfitCenterSupplierSchedule extends CreateRecord
|
||||
{
|
||||
protected static string $resource = ProfitCenterSupplierScheduleResource::class;
|
||||
}
|
||||
@ -1,30 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\ProfitCenterSupplierSchedules\Pages;
|
||||
|
||||
use App\Filament\Resources\ProfitCenterSupplierSchedules\ProfitCenterSupplierScheduleResource;
|
||||
use Filament\Actions\DeleteAction;
|
||||
use Filament\Actions\ForceDeleteAction;
|
||||
use Filament\Actions\RestoreAction;
|
||||
use Filament\Resources\Pages\EditRecord;
|
||||
|
||||
class EditProfitCenterSupplierSchedule extends EditRecord
|
||||
{
|
||||
protected static string $resource = ProfitCenterSupplierScheduleResource::class;
|
||||
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
DeleteAction::make(),
|
||||
ForceDeleteAction::make(),
|
||||
RestoreAction::make(),
|
||||
];
|
||||
}
|
||||
|
||||
protected function getFooterWidgets(): array
|
||||
{
|
||||
return [
|
||||
\App\Filament\Widgets\DeliveryCalendarWidget::class,
|
||||
];
|
||||
}
|
||||
}
|
||||
@ -1,19 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\ProfitCenterSupplierSchedules\Pages;
|
||||
|
||||
use App\Filament\Resources\ProfitCenterSupplierSchedules\ProfitCenterSupplierScheduleResource;
|
||||
use Filament\Actions\CreateAction;
|
||||
use Filament\Resources\Pages\ListRecords;
|
||||
|
||||
class ListProfitCenterSupplierSchedules extends ListRecords
|
||||
{
|
||||
protected static string $resource = ProfitCenterSupplierScheduleResource::class;
|
||||
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
CreateAction::make(),
|
||||
];
|
||||
}
|
||||
}
|
||||
@ -1,75 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\ProfitCenterSupplierSchedules;
|
||||
|
||||
use App\Filament\Resources\ProfitCenterSupplierSchedules\Pages\CreateProfitCenterSupplierSchedule;
|
||||
use App\Filament\Resources\ProfitCenterSupplierSchedules\Pages\EditProfitCenterSupplierSchedule;
|
||||
use App\Filament\Resources\ProfitCenterSupplierSchedules\Pages\ListProfitCenterSupplierSchedules;
|
||||
use App\Filament\Resources\ProfitCenterSupplierSchedules\Schemas\ProfitCenterSupplierScheduleForm;
|
||||
use App\Filament\Resources\ProfitCenterSupplierSchedules\Tables\ProfitCenterSupplierSchedulesTable;
|
||||
use App\Models\ProfitCenterSupplierSchedule;
|
||||
use BackedEnum;
|
||||
use Filament\Resources\Resource;
|
||||
use Filament\Schemas\Schema;
|
||||
use Filament\Support\Icons\Heroicon;
|
||||
use Filament\Tables\Table;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\SoftDeletingScope;
|
||||
|
||||
class ProfitCenterSupplierScheduleResource extends Resource
|
||||
{
|
||||
protected static ?string $model = ProfitCenterSupplierSchedule::class;
|
||||
|
||||
protected static string|BackedEnum|null $navigationIcon = 'heroicon-o-link';
|
||||
|
||||
protected static string|\UnitEnum|null $navigationGroup = 'Szállítás';
|
||||
|
||||
protected static ?string $navigationLabel = 'Profitcenter ütemezés';
|
||||
|
||||
protected static ?string $modelLabel = 'Profitcenter ütemezés';
|
||||
|
||||
protected static ?string $pluralLabel = 'Profitcenter ütemezések';
|
||||
|
||||
protected static ?string $breadcrumb = 'Profitcenter ütemezés';
|
||||
|
||||
public static function form(Schema $schema): Schema
|
||||
{
|
||||
return ProfitCenterSupplierScheduleForm::configure($schema);
|
||||
}
|
||||
|
||||
public static function table(Table $table): Table
|
||||
{
|
||||
return ProfitCenterSupplierSchedulesTable::configure($table);
|
||||
}
|
||||
|
||||
public static function getRelations(): array
|
||||
{
|
||||
return [
|
||||
//
|
||||
];
|
||||
}
|
||||
|
||||
public static function getPages(): array
|
||||
{
|
||||
return [
|
||||
'index' => ListProfitCenterSupplierSchedules::route('/'),
|
||||
'create' => CreateProfitCenterSupplierSchedule::route('/create'),
|
||||
'edit' => EditProfitCenterSupplierSchedule::route('/{record}/edit'),
|
||||
];
|
||||
}
|
||||
|
||||
public static function getWidgets(): array
|
||||
{
|
||||
return [
|
||||
\App\Filament\Widgets\DeliveryCalendarWidget::class,
|
||||
];
|
||||
}
|
||||
|
||||
public static function getRecordRouteBindingEloquentQuery(): Builder
|
||||
{
|
||||
return parent::getRecordRouteBindingEloquentQuery()
|
||||
->withoutGlobalScopes([
|
||||
SoftDeletingScope::class,
|
||||
]);
|
||||
}
|
||||
}
|
||||
@ -1,31 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\ProfitCenterSupplierSchedules\Schemas;
|
||||
|
||||
use Filament\Forms\Components\Select;
|
||||
use Filament\Schemas\Schema;
|
||||
|
||||
class ProfitCenterSupplierScheduleForm
|
||||
{
|
||||
public static function configure(Schema $schema): Schema
|
||||
{
|
||||
return $schema
|
||||
->components([
|
||||
Select::make('profit_center_id')
|
||||
->label('Profit Center')
|
||||
->relationship('profitCenter', 'name')
|
||||
->searchable()
|
||||
->required(),
|
||||
Select::make('supplier_id')
|
||||
->label('Beszállító')
|
||||
->relationship('supplier', 'name')
|
||||
->searchable()
|
||||
->required(),
|
||||
Select::make('delivery_schedule_id')
|
||||
->label('Szállítási sablon')
|
||||
->relationship('deliverySchedule', 'name')
|
||||
->searchable()
|
||||
->required(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
@ -1,46 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\ProfitCenterSupplierSchedules\Tables;
|
||||
|
||||
use Filament\Actions\BulkActionGroup;
|
||||
use Filament\Actions\DeleteBulkAction;
|
||||
use Filament\Actions\EditAction;
|
||||
use Filament\Actions\ForceDeleteBulkAction;
|
||||
use Filament\Actions\RestoreBulkAction;
|
||||
use Filament\Tables\Filters\TrashedFilter;
|
||||
use Filament\Tables\Table;
|
||||
|
||||
class ProfitCenterSupplierSchedulesTable
|
||||
{
|
||||
public static function configure(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->columns([
|
||||
\Filament\Tables\Columns\TextColumn::make('profitCenter.name')
|
||||
->label('Profit Center')
|
||||
->searchable()
|
||||
->sortable(),
|
||||
\Filament\Tables\Columns\TextColumn::make('supplier.name')
|
||||
->label('Beszállító')
|
||||
->searchable()
|
||||
->sortable(),
|
||||
\Filament\Tables\Columns\TextColumn::make('deliverySchedule.name')
|
||||
->label('Szállítási sablon')
|
||||
->searchable()
|
||||
->sortable(),
|
||||
])
|
||||
->filters([
|
||||
TrashedFilter::make(),
|
||||
])
|
||||
->recordActions([
|
||||
EditAction::make(),
|
||||
])
|
||||
->toolbarActions([
|
||||
BulkActionGroup::make([
|
||||
DeleteBulkAction::make(),
|
||||
ForceDeleteBulkAction::make(),
|
||||
RestoreBulkAction::make(),
|
||||
]),
|
||||
]);
|
||||
}
|
||||
}
|
||||
@ -1,11 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\WorkCalendars\Pages;
|
||||
|
||||
use App\Filament\Resources\WorkCalendars\WorkCalendarResource;
|
||||
use Filament\Resources\Pages\CreateRecord;
|
||||
|
||||
class CreateWorkCalendar extends CreateRecord
|
||||
{
|
||||
protected static string $resource = WorkCalendarResource::class;
|
||||
}
|
||||
@ -1,23 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\WorkCalendars\Pages;
|
||||
|
||||
use App\Filament\Resources\WorkCalendars\WorkCalendarResource;
|
||||
use Filament\Actions\DeleteAction;
|
||||
use Filament\Actions\ForceDeleteAction;
|
||||
use Filament\Actions\RestoreAction;
|
||||
use Filament\Resources\Pages\EditRecord;
|
||||
|
||||
class EditWorkCalendar extends EditRecord
|
||||
{
|
||||
protected static string $resource = WorkCalendarResource::class;
|
||||
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
DeleteAction::make(),
|
||||
ForceDeleteAction::make(),
|
||||
RestoreAction::make(),
|
||||
];
|
||||
}
|
||||
}
|
||||
@ -1,19 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\WorkCalendars\Pages;
|
||||
|
||||
use App\Filament\Resources\WorkCalendars\WorkCalendarResource;
|
||||
use Filament\Actions\CreateAction;
|
||||
use Filament\Resources\Pages\ListRecords;
|
||||
|
||||
class ListWorkCalendars extends ListRecords
|
||||
{
|
||||
protected static string $resource = WorkCalendarResource::class;
|
||||
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
CreateAction::make(),
|
||||
];
|
||||
}
|
||||
}
|
||||
@ -1,31 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\WorkCalendars\Schemas;
|
||||
|
||||
use App\Enums\WorkDayType;
|
||||
use Filament\Forms\Components\DatePicker;
|
||||
use Filament\Forms\Components\Select;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Schemas\Schema;
|
||||
|
||||
class WorkCalendarForm
|
||||
{
|
||||
public static function configure(Schema $schema): Schema
|
||||
{
|
||||
return $schema
|
||||
->components([
|
||||
DatePicker::make('date')
|
||||
->label('Dátum')
|
||||
->required()
|
||||
->native(false)
|
||||
->displayFormat('Y-m-d'),
|
||||
Select::make('type')
|
||||
->label('Típus')
|
||||
->options(WorkDayType::class)
|
||||
->required(),
|
||||
TextInput::make('description')
|
||||
->label('Leírás')
|
||||
->maxLength(255),
|
||||
]);
|
||||
}
|
||||
}
|
||||
@ -1,47 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\WorkCalendars\Tables;
|
||||
|
||||
use Filament\Actions\BulkActionGroup;
|
||||
use Filament\Actions\DeleteBulkAction;
|
||||
use Filament\Actions\EditAction;
|
||||
use Filament\Actions\ForceDeleteBulkAction;
|
||||
use Filament\Actions\RestoreBulkAction;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
use Filament\Tables\Filters\TrashedFilter;
|
||||
use Filament\Tables\Table;
|
||||
|
||||
class WorkCalendarsTable
|
||||
{
|
||||
public static function configure(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->columns([
|
||||
TextColumn::make('date')
|
||||
->label('Dátum')
|
||||
->date()
|
||||
->sortable(),
|
||||
TextColumn::make('type')
|
||||
->label('Típus')
|
||||
->badge()
|
||||
->formatStateUsing(fn ($state) => $state?->label())
|
||||
->color(fn ($state) => $state?->color()),
|
||||
TextColumn::make('description')
|
||||
->label('Leírás')
|
||||
->searchable(),
|
||||
])
|
||||
->filters([
|
||||
TrashedFilter::make(),
|
||||
])
|
||||
->recordActions([
|
||||
EditAction::make(),
|
||||
])
|
||||
->toolbarActions([
|
||||
BulkActionGroup::make([
|
||||
DeleteBulkAction::make(),
|
||||
ForceDeleteBulkAction::make(),
|
||||
RestoreBulkAction::make(),
|
||||
]),
|
||||
]);
|
||||
}
|
||||
}
|
||||
@ -1,62 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Resources\WorkCalendars;
|
||||
|
||||
use App\Filament\Resources\WorkCalendars\Pages\CreateWorkCalendar;
|
||||
use App\Filament\Resources\WorkCalendars\Pages\EditWorkCalendar;
|
||||
use App\Filament\Resources\WorkCalendars\Pages\ListWorkCalendars;
|
||||
use App\Filament\Resources\WorkCalendars\Schemas\WorkCalendarForm;
|
||||
use App\Filament\Resources\WorkCalendars\Tables\WorkCalendarsTable;
|
||||
use App\Models\WorkCalendar;
|
||||
use BackedEnum;
|
||||
use Filament\Resources\Resource;
|
||||
use Filament\Schemas\Schema;
|
||||
use Filament\Support\Icons\Heroicon;
|
||||
use Filament\Tables\Table;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\SoftDeletingScope;
|
||||
|
||||
class WorkCalendarResource extends Resource
|
||||
{
|
||||
protected static ?string $model = WorkCalendar::class;
|
||||
|
||||
protected static string|BackedEnum|null $navigationIcon = 'heroicon-o-calendar';
|
||||
|
||||
protected static string|\UnitEnum|null $navigationGroup = 'Szállítás';
|
||||
|
||||
protected static ?string $navigationLabel = 'Munkanaptárak';
|
||||
|
||||
public static function form(Schema $schema): Schema
|
||||
{
|
||||
return WorkCalendarForm::configure($schema);
|
||||
}
|
||||
|
||||
public static function table(Table $table): Table
|
||||
{
|
||||
return WorkCalendarsTable::configure($table);
|
||||
}
|
||||
|
||||
public static function getRelations(): array
|
||||
{
|
||||
return [
|
||||
//
|
||||
];
|
||||
}
|
||||
|
||||
public static function getPages(): array
|
||||
{
|
||||
return [
|
||||
'index' => ListWorkCalendars::route('/'),
|
||||
'create' => CreateWorkCalendar::route('/create'),
|
||||
'edit' => EditWorkCalendar::route('/{record}/edit'),
|
||||
];
|
||||
}
|
||||
|
||||
public static function getRecordRouteBindingEloquentQuery(): Builder
|
||||
{
|
||||
return parent::getRecordRouteBindingEloquentQuery()
|
||||
->withoutGlobalScopes([
|
||||
SoftDeletingScope::class,
|
||||
]);
|
||||
}
|
||||
}
|
||||
@ -1,27 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Supplier\Resources\ProductStocks\Pages;
|
||||
|
||||
use App\Filament\Supplier\Resources\ProductStocks\ProductStockResource;
|
||||
use Filament\Actions\Action;
|
||||
use Filament\Resources\Pages\EditRecord;
|
||||
|
||||
class EditProductStock extends EditRecord
|
||||
{
|
||||
protected static string $resource = ProductStockResource::class;
|
||||
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
Action::make('back')
|
||||
->label('Vissza a listához')
|
||||
->url(fn () => ProductStockResource::getUrl('index'))
|
||||
->color('gray'),
|
||||
];
|
||||
}
|
||||
|
||||
protected function getRedirectUrl(): string
|
||||
{
|
||||
return ProductStockResource::getUrl('index');
|
||||
}
|
||||
}
|
||||
@ -1,11 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Supplier\Resources\ProductStocks\Pages;
|
||||
|
||||
use App\Filament\Supplier\Resources\ProductStocks\ProductStockResource;
|
||||
use Filament\Resources\Pages\ListRecords;
|
||||
|
||||
class ListProductStocks extends ListRecords
|
||||
{
|
||||
protected static string $resource = ProductStockResource::class;
|
||||
}
|
||||
@ -1,57 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Supplier\Resources\ProductStocks;
|
||||
|
||||
use App\Filament\Supplier\Resources\ProductStocks\Pages\EditProductStock;
|
||||
use App\Filament\Supplier\Resources\ProductStocks\Pages\ListProductStocks;
|
||||
use App\Filament\Supplier\Resources\ProductStocks\Schemas\ProductStockForm;
|
||||
use App\Filament\Supplier\Resources\ProductStocks\Tables\ProductStocksTable;
|
||||
use App\Models\Product;
|
||||
use BackedEnum;
|
||||
use Filament\Resources\Resource;
|
||||
use Filament\Schemas\Schema;
|
||||
use Filament\Support\Icons\Heroicon;
|
||||
use Filament\Tables\Table;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
class ProductStockResource extends Resource
|
||||
{
|
||||
protected static ?string $model = Product::class;
|
||||
|
||||
protected static string|BackedEnum|null $navigationIcon = Heroicon::OutlinedCube;
|
||||
|
||||
protected static ?string $navigationLabel = 'Termékeim';
|
||||
|
||||
protected static ?string $breadcrumb = 'Termékeim';
|
||||
|
||||
protected static ?string $modelLabel = 'Termék';
|
||||
|
||||
protected static ?string $pluralLabel = 'Termékeim';
|
||||
|
||||
/**
|
||||
* Csak a bejelentkezett supplier saját termékei jelennek meg.
|
||||
*/
|
||||
public static function getEloquentQuery(): Builder
|
||||
{
|
||||
return parent::getEloquentQuery()
|
||||
->where('supplier_id', auth()->user()->supplier_id);
|
||||
}
|
||||
|
||||
public static function form(Schema $schema): Schema
|
||||
{
|
||||
return ProductStockForm::configure($schema);
|
||||
}
|
||||
|
||||
public static function table(Table $table): Table
|
||||
{
|
||||
return ProductStocksTable::configure($table);
|
||||
}
|
||||
|
||||
public static function getPages(): array
|
||||
{
|
||||
return [
|
||||
'index' => ListProductStocks::route('/'),
|
||||
'edit' => EditProductStock::route('/{record}/edit'),
|
||||
];
|
||||
}
|
||||
}
|
||||
@ -1,23 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Supplier\Resources\ProductStocks\Schemas;
|
||||
|
||||
use App\Enums\StockStatusEnum;
|
||||
use Filament\Forms\Components\Select;
|
||||
use Filament\Schemas\Schema;
|
||||
|
||||
class ProductStockForm
|
||||
{
|
||||
public static function configure(Schema $schema): Schema
|
||||
{
|
||||
return $schema->components([
|
||||
Select::make('stock_status')
|
||||
->label('Készlet státusz')
|
||||
->options(
|
||||
collect(StockStatusEnum::cases())
|
||||
->mapWithKeys(fn (StockStatusEnum $case) => [$case->value => $case->label()])
|
||||
)
|
||||
->required(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
@ -1,36 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Supplier\Resources\ProductStocks\Tables;
|
||||
|
||||
use App\Enums\StockStatusEnum;
|
||||
use Filament\Actions\EditAction;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
use Filament\Tables\Table;
|
||||
|
||||
class ProductStocksTable
|
||||
{
|
||||
public static function configure(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->columns([
|
||||
TextColumn::make('name')
|
||||
->label('Termék neve')
|
||||
->searchable()
|
||||
->sortable(),
|
||||
|
||||
TextColumn::make('sku')
|
||||
->label('Cikkszám')
|
||||
->searchable(),
|
||||
|
||||
TextColumn::make('stock_status')
|
||||
->label('Készlet státusz')
|
||||
->badge()
|
||||
->formatStateUsing(fn (StockStatusEnum $state) => $state->label())
|
||||
->color(fn (StockStatusEnum $state) => $state->color()),
|
||||
])
|
||||
->recordAction('edit')
|
||||
->actions([
|
||||
EditAction::make()->label('Státusz módosítása'),
|
||||
]);
|
||||
}
|
||||
}
|
||||
@ -1,27 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\SupplierPortal\Resources\ProductStocks\Pages;
|
||||
|
||||
use App\Filament\SupplierPortal\Resources\ProductStocks\ProductStockResource;
|
||||
use Filament\Actions\Action;
|
||||
use Filament\Resources\Pages\EditRecord;
|
||||
|
||||
class EditProductStock extends EditRecord
|
||||
{
|
||||
protected static string $resource = ProductStockResource::class;
|
||||
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
Action::make('back')
|
||||
->label('Vissza a listához')
|
||||
->url(fn () => ProductStockResource::getUrl('index'))
|
||||
->color('gray'),
|
||||
];
|
||||
}
|
||||
|
||||
protected function getRedirectUrl(): string
|
||||
{
|
||||
return ProductStockResource::getUrl('index');
|
||||
}
|
||||
}
|
||||
@ -1,67 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\SupplierPortal\Resources\ProductStocks\Pages;
|
||||
|
||||
use App\Filament\SupplierPortal\Resources\ProductStocks\ProductStockResource;
|
||||
use App\Livewire\SupplierPortal\ProductGroupTree;
|
||||
use Filament\Resources\Pages\ListRecords;
|
||||
use Filament\Schemas\Components\EmbeddedTable;
|
||||
use Filament\Schemas\Components\Flex;
|
||||
use Filament\Schemas\Components\Group;
|
||||
use Filament\Schemas\Components\Livewire;
|
||||
use Filament\Schemas\Schema;
|
||||
use Filament\Support\Enums\Width;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Livewire\Attributes\On;
|
||||
|
||||
class ListProductStocks extends ListRecords
|
||||
{
|
||||
protected static string $resource = ProductStockResource::class;
|
||||
|
||||
public ?int $productGroupId = null;
|
||||
|
||||
#[On('product-group-selected')]
|
||||
public function onProductGroupSelected(?int $groupId): void
|
||||
{
|
||||
$this->productGroupId = $groupId;
|
||||
$this->resetTable();
|
||||
}
|
||||
|
||||
public function getMaxContentWidth(): Width | string | null
|
||||
{
|
||||
return Width::Screen;
|
||||
}
|
||||
|
||||
public function content(Schema $schema): Schema
|
||||
{
|
||||
return $schema
|
||||
->components([
|
||||
Flex::make([
|
||||
Livewire::make(ProductGroupTree::class)
|
||||
->id('product-group-tree')
|
||||
->grow(false)
|
||||
->extraAttributes(['style' => 'width: 300px; flex-shrink: 0; position: sticky; top: 1rem;']),
|
||||
|
||||
Group::make([
|
||||
EmbeddedTable::make(),
|
||||
])
|
||||
->grow()
|
||||
->extraAttributes(['style' => 'min-width: 0;']),
|
||||
])
|
||||
->verticallyAlignStart()
|
||||
->from('md')
|
||||
->extraAttributes(['style' => 'width: 100%; gap: 1rem;']),
|
||||
]);
|
||||
}
|
||||
|
||||
protected function applyFiltersToTableQuery(Builder $query): Builder
|
||||
{
|
||||
$query = parent::applyFiltersToTableQuery($query);
|
||||
|
||||
if ($this->productGroupId !== null) {
|
||||
$query->where('product_group_id', $this->productGroupId);
|
||||
}
|
||||
|
||||
return $query;
|
||||
}
|
||||
}
|
||||
@ -1,57 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\SupplierPortal\Resources\ProductStocks;
|
||||
|
||||
use App\Filament\SupplierPortal\Resources\ProductStocks\Pages\EditProductStock;
|
||||
use App\Filament\SupplierPortal\Resources\ProductStocks\Pages\ListProductStocks;
|
||||
use App\Filament\SupplierPortal\Resources\ProductStocks\Schemas\ProductStockForm;
|
||||
use App\Filament\SupplierPortal\Resources\ProductStocks\Tables\ProductStocksTable;
|
||||
use App\Models\Product;
|
||||
use BackedEnum;
|
||||
use Filament\Resources\Resource;
|
||||
use Filament\Schemas\Schema;
|
||||
use Filament\Support\Icons\Heroicon;
|
||||
use Filament\Tables\Table;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
class ProductStockResource extends Resource
|
||||
{
|
||||
protected static ?string $model = Product::class;
|
||||
|
||||
protected static string|BackedEnum|null $navigationIcon = Heroicon::OutlinedCube;
|
||||
|
||||
protected static ?string $navigationLabel = 'Termékeim';
|
||||
|
||||
protected static ?string $breadcrumb = 'Termékeim';
|
||||
|
||||
protected static ?string $modelLabel = 'Termék';
|
||||
|
||||
protected static ?string $pluralLabel = 'Termékeim';
|
||||
|
||||
/**
|
||||
* Csak a bejelentkezett supplier saját termékei jelennek meg.
|
||||
*/
|
||||
public static function getEloquentQuery(): Builder
|
||||
{
|
||||
return parent::getEloquentQuery()
|
||||
->where('supplier_id', auth()->user()->supplier_id);
|
||||
}
|
||||
|
||||
public static function form(Schema $schema): Schema
|
||||
{
|
||||
return ProductStockForm::configure($schema);
|
||||
}
|
||||
|
||||
public static function table(Table $table): Table
|
||||
{
|
||||
return ProductStocksTable::configure($table);
|
||||
}
|
||||
|
||||
public static function getPages(): array
|
||||
{
|
||||
return [
|
||||
'index' => ListProductStocks::route('/'),
|
||||
'edit' => EditProductStock::route('/{record}/edit'),
|
||||
];
|
||||
}
|
||||
}
|
||||
@ -1,23 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\SupplierPortal\Resources\ProductStocks\Schemas;
|
||||
|
||||
use App\Enums\StockStatusEnum;
|
||||
use Filament\Forms\Components\Select;
|
||||
use Filament\Schemas\Schema;
|
||||
|
||||
class ProductStockForm
|
||||
{
|
||||
public static function configure(Schema $schema): Schema
|
||||
{
|
||||
return $schema->components([
|
||||
Select::make('stock_status')
|
||||
->label('Készlet státusz')
|
||||
->options(
|
||||
collect(StockStatusEnum::cases())
|
||||
->mapWithKeys(fn (StockStatusEnum $case) => [$case->value => $case->label()])
|
||||
)
|
||||
->required(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
@ -1,47 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\SupplierPortal\Resources\ProductStocks\Tables;
|
||||
|
||||
use App\Enums\StockStatusEnum;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
use Filament\Tables\Columns\ToggleColumn;
|
||||
use Filament\Tables\Filters\SelectFilter;
|
||||
use Filament\Tables\Table;
|
||||
|
||||
class ProductStocksTable
|
||||
{
|
||||
public static function configure(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->columns([
|
||||
TextColumn::make('name')
|
||||
->label('Termék neve')
|
||||
->searchable()
|
||||
->sortable(),
|
||||
|
||||
TextColumn::make('supplierProductNumber')
|
||||
->label('Cikkszám')
|
||||
->searchable(),
|
||||
|
||||
ToggleColumn::make('stock_status')
|
||||
->label('Raktáron')
|
||||
->onColor('success')
|
||||
->offColor('danger')
|
||||
->getStateUsing(fn ($record) => $record->stock_status === StockStatusEnum::InStock)
|
||||
->updateStateUsing(function ($record, bool $state) {
|
||||
$record->stock_status = $state
|
||||
? StockStatusEnum::InStock
|
||||
: StockStatusEnum::OutOfStock;
|
||||
$record->save();
|
||||
}),
|
||||
])
|
||||
->filters([
|
||||
SelectFilter::make('stock_status')
|
||||
->label('Raktáron')
|
||||
->options([
|
||||
StockStatusEnum::InStock->value => 'Igen',
|
||||
StockStatusEnum::OutOfStock->value => 'Nem',
|
||||
]),
|
||||
]);
|
||||
}
|
||||
}
|
||||
@ -1,414 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Widgets;
|
||||
|
||||
use App\Enums\OverrideScope;
|
||||
use App\Models\ProfitCenterSupplierSchedule;
|
||||
use App\Models\DeliveryCalendarOverride;
|
||||
use App\Models\WorkCalendar;
|
||||
use App\Enums\WorkDayType;
|
||||
use App\Services\DeliveryCalendarService;
|
||||
use App\Services\WorkCalendarService;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Saade\FilamentFullCalendar\Widgets\FullCalendarWidget;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Filament\Actions\Action;
|
||||
use Filament\Forms\Components\Hidden;
|
||||
use Filament\Forms\Components\Placeholder;
|
||||
use Filament\Forms\Components\Toggle;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Livewire\Attributes\On;
|
||||
|
||||
class DeliveryCalendarWidget extends FullCalendarWidget
|
||||
{
|
||||
/**
|
||||
* @var ProfitCenterSupplierSchedule|null
|
||||
*/
|
||||
public Model | int | string | null $record = null;
|
||||
|
||||
public ?int $supplierId = null;
|
||||
|
||||
public ?int $profitCenterId = null;
|
||||
|
||||
/** Következő szállítási nap dátuma (YYYY-MM-DD formátum), kék kiemeléshez. */
|
||||
public ?string $nextDeliveryDate = null;
|
||||
|
||||
/**
|
||||
* Inaktív (nem választható) napok listája.
|
||||
*
|
||||
* @var array<string>
|
||||
*/
|
||||
protected array $inactiveDates = [];
|
||||
|
||||
public function mount(): void
|
||||
{
|
||||
$this->loadRecordFromFilter();
|
||||
}
|
||||
|
||||
public function updatedSupplierId(): void
|
||||
{
|
||||
$this->loadRecordFromFilter();
|
||||
$this->refreshRecords();
|
||||
}
|
||||
|
||||
public function updatedProfitCenterId(): void
|
||||
{
|
||||
$this->loadRecordFromFilter();
|
||||
$this->refreshRecords();
|
||||
}
|
||||
|
||||
#[On('calendar-filter-changed')]
|
||||
public function onFilterChanged(?int $supplierId, ?int $profitCenterId): void
|
||||
{
|
||||
$this->supplierId = $supplierId;
|
||||
$this->profitCenterId = $profitCenterId;
|
||||
$this->record = null;
|
||||
$this->loadRecordFromFilter();
|
||||
$this->refreshRecords();
|
||||
}
|
||||
|
||||
#[On('next-delivery-date-changed')]
|
||||
public function onNextDeliveryDateChanged(?string $date): void
|
||||
{
|
||||
$this->nextDeliveryDate = $date;
|
||||
$this->refreshRecords();
|
||||
}
|
||||
|
||||
protected function loadRecordFromFilter(): void
|
||||
{
|
||||
if ($this->record instanceof ProfitCenterSupplierSchedule) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($this->supplierId && $this->profitCenterId) {
|
||||
$this->record = ProfitCenterSupplierSchedule::where('supplier_id', $this->supplierId)
|
||||
->where('profit_center_id', $this->profitCenterId)
|
||||
->first();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!$this->record) {
|
||||
$this->record = ProfitCenterSupplierSchedule::first();
|
||||
}
|
||||
}
|
||||
|
||||
public function fetchEvents(array $info): array
|
||||
{
|
||||
if (!($this->record instanceof ProfitCenterSupplierSchedule)) {
|
||||
$this->loadRecordFromFilter();
|
||||
}
|
||||
|
||||
if (!$this->record) {
|
||||
$this->dispatch('calendar-events-done');
|
||||
return $this->getDemoEvents($info);
|
||||
}
|
||||
|
||||
/** @var DeliveryCalendarService $service */
|
||||
$service = app(DeliveryCalendarService::class);
|
||||
/** @var WorkCalendarService $workService */
|
||||
$workService = app(WorkCalendarService::class);
|
||||
|
||||
$start = Carbon::parse($info['start']);
|
||||
$end = Carbon::parse($info['end']);
|
||||
|
||||
$events = [];
|
||||
|
||||
// 1. Szállítási napok – zöld háttér
|
||||
$deliveryDates = $service->getAvailableDeliveryDates(
|
||||
$this->record->profitCenter,
|
||||
$this->record->supplier,
|
||||
$start,
|
||||
$end
|
||||
);
|
||||
|
||||
foreach ($deliveryDates as $date) {
|
||||
$events[] = [
|
||||
'id' => 'delivery-' . $date->format('Y-m-d'),
|
||||
'title' => '',
|
||||
'start' => $date->format('Y-m-d'),
|
||||
'end' => $date->addDay()->format('Y-m-d'),
|
||||
'allDay' => true,
|
||||
'display' => 'background',
|
||||
'backgroundColor' => '#4CAF50',
|
||||
'extendedProps' => ['type' => 'delivery'],
|
||||
];
|
||||
}
|
||||
|
||||
// 2. Munkaszüneti napok – piros háttér
|
||||
$workCalendarEntries = $workService->getCalendarEntries($start, $end);
|
||||
foreach ($workCalendarEntries as $entry) {
|
||||
if ($entry->type === WorkDayType::Holiday) {
|
||||
$events[] = [
|
||||
'id' => 'holiday-' . $entry->date->format('Y-m-d'),
|
||||
'title' => '',
|
||||
'start' => $entry->date->format('Y-m-d'),
|
||||
'end' => $entry->date->copy()->addDay()->format('Y-m-d'),
|
||||
'allDay' => true,
|
||||
'display' => 'background',
|
||||
'backgroundColor' => '#EF4444',
|
||||
'extendedProps' => ['type' => 'holiday'],
|
||||
];
|
||||
} elseif ($entry->type === WorkDayType::WorkingDay) {
|
||||
// 3. Áthelyezett munkanapok – narancssárga háttér
|
||||
$events[] = [
|
||||
'id' => 'transferred-' . $entry->date->format('Y-m-d'),
|
||||
'title' => '',
|
||||
'start' => $entry->date->format('Y-m-d'),
|
||||
'end' => $entry->date->copy()->addDay()->format('Y-m-d'),
|
||||
'allDay' => true,
|
||||
'display' => 'background',
|
||||
'backgroundColor' => '#F59E0B',
|
||||
'extendedProps' => ['type' => 'transferred'],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
// 4. Hétvégék – szürke háttér (inaktív napok)
|
||||
$current = $start->copy();
|
||||
while ($current->lte($end)) {
|
||||
if ($current->isWeekend()) {
|
||||
$events[] = [
|
||||
'id' => 'weekend-' . $current->format('Y-m-d'),
|
||||
'title' => '',
|
||||
'start' => $current->format('Y-m-d'),
|
||||
'end' => $current->copy()->addDay()->format('Y-m-d'),
|
||||
'allDay' => true,
|
||||
'display' => 'background',
|
||||
'backgroundColor' => '#E5E7EB',
|
||||
'extendedProps' => ['type' => 'inactive'],
|
||||
];
|
||||
}
|
||||
$current->addDay();
|
||||
}
|
||||
|
||||
// 5. Következő szállítási nap – kék háttér
|
||||
if ($this->nextDeliveryDate) {
|
||||
$nextDate = Carbon::parse($this->nextDeliveryDate);
|
||||
if ($nextDate->between($start, $end)) {
|
||||
$events[] = [
|
||||
'id' => 'next-delivery-' . $nextDate->format('Y-m-d'),
|
||||
'title' => '',
|
||||
'start' => $nextDate->format('Y-m-d'),
|
||||
'end' => $nextDate->copy()->addDay()->format('Y-m-d'),
|
||||
'allDay' => true,
|
||||
'display' => 'background',
|
||||
'backgroundColor' => '#3B82F6',
|
||||
'extendedProps' => ['type' => 'next-delivery'],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
$this->dispatch('calendar-events-done');
|
||||
return $events;
|
||||
}
|
||||
|
||||
/**
|
||||
* Demo események generálása, ha nincs valós adat.
|
||||
*
|
||||
* @param array{start: string, end: string} $info
|
||||
* @return array<int, array<string, mixed>>
|
||||
*/
|
||||
protected function getDemoEvents(array $info): array
|
||||
{
|
||||
$start = Carbon::parse($info['start']);
|
||||
$end = Carbon::parse($info['end']);
|
||||
$events = [];
|
||||
|
||||
$current = $start->copy();
|
||||
while ($current->lte($end)) {
|
||||
$dayOfWeek = $current->dayOfWeek;
|
||||
$dayOfMonth = $current->day;
|
||||
$dateStr = $current->format('Y-m-d');
|
||||
$nextDateStr = $current->copy()->addDay()->format('Y-m-d');
|
||||
|
||||
if ($current->isWeekend()) {
|
||||
// Hétvégék – szürke háttér (inaktív)
|
||||
$events[] = [
|
||||
'id' => 'weekend-' . $dateStr,
|
||||
'title' => '',
|
||||
'start' => $dateStr,
|
||||
'end' => $nextDateStr,
|
||||
'allDay' => true,
|
||||
'display' => 'background',
|
||||
'backgroundColor' => '#E5E7EB',
|
||||
'extendedProps' => ['type' => 'inactive'],
|
||||
];
|
||||
} elseif ($dayOfWeek === Carbon::MONDAY || $dayOfWeek === Carbon::WEDNESDAY || $dayOfWeek === Carbon::FRIDAY) {
|
||||
// Hétfő, szerda, péntek – zöld háttér (szállítási napok)
|
||||
$events[] = [
|
||||
'id' => 'delivery-' . $dateStr,
|
||||
'title' => '',
|
||||
'start' => $dateStr,
|
||||
'end' => $nextDateStr,
|
||||
'allDay' => true,
|
||||
'display' => 'background',
|
||||
'backgroundColor' => '#4CAF50',
|
||||
'extendedProps' => ['type' => 'delivery'],
|
||||
];
|
||||
}
|
||||
|
||||
// Néhány speciális nap bemutatóként
|
||||
if ($dayOfMonth === 15) {
|
||||
// Minden hónap 15-e – narancssárga (áthelyezett munkanap)
|
||||
$events[] = [
|
||||
'id' => 'special-orange-' . $dateStr,
|
||||
'title' => '',
|
||||
'start' => $dateStr,
|
||||
'end' => $nextDateStr,
|
||||
'allDay' => true,
|
||||
'display' => 'background',
|
||||
'backgroundColor' => '#F59E0B',
|
||||
'extendedProps' => ['type' => 'transferred'],
|
||||
];
|
||||
}
|
||||
|
||||
if ($dayOfMonth === 1) {
|
||||
// Minden hónap 1-je – piros (ünnepnap)
|
||||
$events[] = [
|
||||
'id' => 'special-red-' . $dateStr,
|
||||
'title' => '',
|
||||
'start' => $dateStr,
|
||||
'end' => $nextDateStr,
|
||||
'allDay' => true,
|
||||
'display' => 'background',
|
||||
'backgroundColor' => '#EF4444',
|
||||
'extendedProps' => ['type' => 'holiday'],
|
||||
];
|
||||
}
|
||||
|
||||
if ($dayOfMonth === 10 || $dayOfMonth === 20) {
|
||||
// 10-e és 20-a – kék (megrendelési határidő)
|
||||
$events[] = [
|
||||
'id' => 'special-blue-' . $dateStr,
|
||||
'title' => '',
|
||||
'start' => $dateStr,
|
||||
'end' => $nextDateStr,
|
||||
'allDay' => true,
|
||||
'display' => 'background',
|
||||
'backgroundColor' => '#3B82F6',
|
||||
'extendedProps' => ['type' => 'deadline'],
|
||||
];
|
||||
}
|
||||
|
||||
$current->addDay();
|
||||
}
|
||||
|
||||
return $events;
|
||||
}
|
||||
|
||||
public function onDateSelect(string $start, ?string $end, bool $allDay, ?array $view, ?array $resource): void
|
||||
{
|
||||
$this->mountAction('manageOverride', [
|
||||
'date' => Carbon::parse($start)->format('Y-m-d'),
|
||||
]);
|
||||
}
|
||||
|
||||
public function onEventClick(array $event): void
|
||||
{
|
||||
$date = data_get($event, 'start');
|
||||
|
||||
if (!$date) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->mountAction('manageOverride', [
|
||||
'date' => Carbon::parse($date)->format('Y-m-d'),
|
||||
]);
|
||||
}
|
||||
|
||||
protected function headerActions(): array
|
||||
{
|
||||
return [
|
||||
Action::make('manageOverride')
|
||||
->label('Felülbírálás kezelése')
|
||||
->modalHeading(fn (array $arguments) => "Szállítás felülbírálása" . (isset($arguments['date']) ? ": " . $arguments['date'] : ""))
|
||||
->form(fn (array $arguments) => [
|
||||
Placeholder::make('info')
|
||||
->hiddenLabel()
|
||||
->content('A háttérben látható naptárban egyszerre több hónapot is áttekinthet. Itt egy konkrét nap módosítását végezheti el.'),
|
||||
\Filament\Forms\Components\DatePicker::make('date')
|
||||
->label('Dátum')
|
||||
->required()
|
||||
->default($arguments['date'] ?? null)
|
||||
->disabled(fn () => isset($arguments['date']))
|
||||
->dehydrated(),
|
||||
Toggle::make('is_delivery_day')
|
||||
->label('Szállítási nap?')
|
||||
->default(function () use ($arguments) {
|
||||
$date = $arguments['date'] ?? null;
|
||||
if (!$date) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$override = DeliveryCalendarOverride::where('supplier_id', $this->record->supplier_id)
|
||||
->whereDate('date', $date)
|
||||
->where('override_scope', OverrideScope::ProfitCenter->value)
|
||||
->where('profit_center_id', $this->record->profit_center_id)
|
||||
->first();
|
||||
|
||||
if ($override) {
|
||||
return $override->is_delivery_day;
|
||||
}
|
||||
|
||||
return app(DeliveryCalendarService::class)->isDeliveryDay(
|
||||
$this->record->profitCenter,
|
||||
$this->record->supplier,
|
||||
Carbon::parse($date)
|
||||
);
|
||||
}),
|
||||
TextInput::make('description')
|
||||
->label('Indoklás / Megjegyzés')
|
||||
->default(fn () => isset($arguments['date'])
|
||||
? DeliveryCalendarOverride::where('supplier_id', $this->record->supplier_id)
|
||||
->whereDate('date', $arguments['date'])
|
||||
->where('override_scope', OverrideScope::ProfitCenter->value)
|
||||
->where('profit_center_id', $this->record->profit_center_id)
|
||||
->first()?->description
|
||||
: null
|
||||
),
|
||||
])
|
||||
->action(function (array $data) {
|
||||
DeliveryCalendarOverride::updateOrCreate(
|
||||
[
|
||||
'supplier_id' => $this->record->supplier_id,
|
||||
'override_scope' => OverrideScope::ProfitCenter->value,
|
||||
'profit_center_id' => $this->record->profit_center_id,
|
||||
'date' => $data['date'],
|
||||
],
|
||||
[
|
||||
'is_delivery_day' => (bool) $data['is_delivery_day'],
|
||||
'description' => $data['description'],
|
||||
]
|
||||
);
|
||||
|
||||
$this->refreshRecords();
|
||||
}),
|
||||
];
|
||||
}
|
||||
|
||||
public function config(): array
|
||||
{
|
||||
return [
|
||||
'initialView' => 'multiMonthYear',
|
||||
'views' => [
|
||||
'multiMonthYear' => [
|
||||
'duration' => ['months' => 6],
|
||||
],
|
||||
],
|
||||
'multiMonthMaxColumns' => 6,
|
||||
'headerToolbar' => [
|
||||
'left' => 'prev,next today',
|
||||
'center' => 'title',
|
||||
'right' => 'multiMonthYear',
|
||||
],
|
||||
'locale' => 'hu',
|
||||
'firstDay' => 1,
|
||||
'height' => 'auto',
|
||||
'contentHeight' => 'auto',
|
||||
'selectable' => true,
|
||||
'editable' => false,
|
||||
'dayMaxEvents' => false,
|
||||
'fixedWeekCount' => false,
|
||||
];
|
||||
}
|
||||
}
|
||||
@ -1,124 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Admin;
|
||||
|
||||
use App\Enums\DbStatusFieldEnum;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Address;
|
||||
use App\Services\AddressService;
|
||||
use App\Traits\JsonApiCustomFunctionTraits;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Response;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
use Validator;
|
||||
|
||||
class AddressController extends Controller
|
||||
{
|
||||
use JsonApiCustomFunctionTraits;
|
||||
|
||||
protected AddressService $service;
|
||||
|
||||
public function __construct(AddressService $service)
|
||||
{
|
||||
$this->service = $service;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*/
|
||||
public function index(): Response|JsonResponse
|
||||
{
|
||||
return response()->noContent();
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*/
|
||||
public function create(): Response|JsonResponse
|
||||
{
|
||||
return response('create');
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
*
|
||||
* @throws ValidationException
|
||||
*/
|
||||
public function store(Request $request): Response|JsonResponse
|
||||
{
|
||||
$validated = Validator::make($request->all(), [
|
||||
'street' => 'required',
|
||||
'name' => 'string|nullable|max:250',
|
||||
'postCode' => 'string|nullable|max:250',
|
||||
'city' => 'string|nullable|max:250',
|
||||
'note' => 'string|nullable|max:65000',
|
||||
]);
|
||||
|
||||
if ($validated->fails()) {
|
||||
return response()->json($this->convertMessageBagToJSONAPIError($validated->getMessageBag()));
|
||||
}
|
||||
|
||||
$newItem = new Address;
|
||||
$newItem->fill($validated->validated());
|
||||
$newItem->status = DbStatusFieldEnum::active;
|
||||
$newItem->save();
|
||||
|
||||
return response()->json($newItem->toArray());
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*/
|
||||
public function show(int $ContactId): Response|JsonResponse
|
||||
{
|
||||
|
||||
return response()->json(Address::findOrFail($ContactId));
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*/
|
||||
public function edit(int $ContactId): Response|JsonResponse
|
||||
{
|
||||
return response()->noContent();
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*/
|
||||
public function update(Request $request, int $ItemId): Response|JsonResponse
|
||||
{
|
||||
$validated = Validator::make($request->all(), [
|
||||
'street' => 'required',
|
||||
'name' => 'string|nullable|max:250',
|
||||
'postCode' => 'string|nullable|max:250',
|
||||
'city' => 'string|nullable|max:250',
|
||||
'note' => 'string|nullable|max:65000',
|
||||
]);
|
||||
|
||||
if ($validated->fails()) {
|
||||
return response()->json($this->convertMessageBagToJSONAPIError($validated->getMessageBag()));
|
||||
}
|
||||
|
||||
$newItem = Address::findOrFail($ItemId);
|
||||
$newItem->fill($validated->validated());
|
||||
|
||||
$newItem->save();
|
||||
|
||||
return response()->json($newItem->toArray());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*/
|
||||
public function destroy(int $ContactId): Response|JsonResponse
|
||||
{
|
||||
$item = Address::findOrFail($ContactId);
|
||||
$item->delete();
|
||||
|
||||
return response()->json(['success' => true]);
|
||||
}
|
||||
}
|
||||
@ -1,243 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Admin;
|
||||
|
||||
use App\Enums\ContactTypeEnum;
|
||||
use App\Enums\DbStatusFieldEnum;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Contact;
|
||||
use App\Rules\PhoneRule;
|
||||
use App\Services\ContactService;
|
||||
use App\Traits\JsonApiCustomFunctionTraits;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Response;
|
||||
use Illuminate\Validation\Rule;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
use LaravelJsonApi\Core\Document\Error;
|
||||
use LaravelJsonApi\Core\Document\ErrorList;
|
||||
use LaravelJsonApi\Core\Document\ErrorSource;
|
||||
use LaravelJsonApi\Core\Document\JsonApi;
|
||||
use Log;
|
||||
use Validator;
|
||||
|
||||
class ContactController extends Controller
|
||||
{
|
||||
use JsonApiCustomFunctionTraits;
|
||||
|
||||
protected ContactService $service;
|
||||
|
||||
public function __construct(ContactService $service)
|
||||
{
|
||||
$this->service = $service;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*/
|
||||
public function index(): Response|JsonResponse|ErrorList|JsonApi
|
||||
{
|
||||
|
||||
Log::channel('chromePHP')->critical('BrowserConsole', ['basename' => basename(__FILE__), 'line' => __LINE__]);
|
||||
|
||||
/*
|
||||
return csrf_token();
|
||||
*/
|
||||
/*
|
||||
$error=Error::make();
|
||||
$error->setStatus('201');
|
||||
$error->setId(12);
|
||||
$error->setSource( ['pointer'=>'pointer','parameter'=>'parameter2']);
|
||||
return $error;
|
||||
return JsonApi::make();
|
||||
*/
|
||||
|
||||
$error = Error::fromArray([
|
||||
'status' => 201,
|
||||
'id' => 99,
|
||||
// 'soucre'=>$errorSource
|
||||
'source' => ['pointer' => 'pointer', 'parameter' => 'parameter4'],
|
||||
]);
|
||||
$error2 = Error::fromArray([
|
||||
// 'soucre'=>$errorSource
|
||||
'source' => ['pointer' => 'pointer', 'parameter' => 'parameter2'],
|
||||
]);
|
||||
// dd(Error::make()->setSource($errorSource));
|
||||
// return $error;
|
||||
|
||||
$errorList = ErrorList::fromArray([
|
||||
$error, $error2,
|
||||
]);
|
||||
|
||||
return $errorList;
|
||||
|
||||
$error = Error::make()->setStatus(202);
|
||||
/*
|
||||
['code'=>202,
|
||||
'detail'=>'ez a hiba leirasa',
|
||||
'status'=>202,
|
||||
'title'=>'van baj'
|
||||
]
|
||||
|
||||
$error=Error::fromArray(['code'=>999,
|
||||
'detail'=>'ez a hiba leirasa',
|
||||
'status'=>202,
|
||||
'title'=>'van baj2',
|
||||
'code'=>'400',
|
||||
'soucre'=>'xax'
|
||||
//'soucre'=>['pointer'=>'pointer','parameter'=>'parameter']
|
||||
]);
|
||||
|
||||
*/
|
||||
$errorSource = ErrorSource::fromArray(
|
||||
['pointer' => 'pointer', 'parameter' => 'parameter']
|
||||
);
|
||||
$error = Error::make();
|
||||
$error->setStatus('201');
|
||||
$error->setId(12);
|
||||
$error->setSource(['pointer' => 'pointer', 'parameter' => 'parameter2']);
|
||||
|
||||
$error = Error::fromArray([
|
||||
'status' => 201,
|
||||
'id' => 99,
|
||||
// 'soucre'=>$errorSource
|
||||
'source' => ['pointer' => 'pointer', 'parameter' => 'parameter4'],
|
||||
]);
|
||||
$error2 = Error::fromArray([
|
||||
'status' => 202,
|
||||
'id' => 92,
|
||||
// 'soucre'=>$errorSource
|
||||
'source' => ['pointer' => 'pointer', 'parameter' => 'parameter2'],
|
||||
]);
|
||||
// dd(Error::make()->setSource($errorSource));
|
||||
// return $error;
|
||||
|
||||
$errorList = ErrorList::fromArray([
|
||||
$error, $error2,
|
||||
]);
|
||||
|
||||
$errorList = JsonApi::make('1');
|
||||
$errorList->data = ['id' => 12];
|
||||
$errorList->setMeta(['total' => 200]);
|
||||
|
||||
return $errorList;
|
||||
// return JsonApi::make();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*/
|
||||
public function create(): Response|JsonResponse
|
||||
{
|
||||
return response('create');
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
*
|
||||
* @throws ValidationException
|
||||
*/
|
||||
public function store(Request $request): Response|JsonResponse|ErrorList
|
||||
{
|
||||
$validated = Validator::make($request->all(), [
|
||||
'name' => 'required',
|
||||
'email' => 'email|nullable',
|
||||
// 'phone'=>'regex:"^[\/+][0-9]{1,2}[(][0-9]{1,2}[)][0-9]{3}[ ][0-9]{3,4}$"|nullable',
|
||||
'phone' => ['nullable', new PhoneRule],
|
||||
'note' => 'string|nullable|max:65000',
|
||||
// 'type'=>'string|nullable|enum:'.ContactTypeEnum::class
|
||||
'type.*' => ['nullable', Rule::in(ContactTypeEnum::getKeys())],
|
||||
]);
|
||||
|
||||
if ($validated->fails()) {
|
||||
return $this->convertMessageBagToJSONAPIError($validated->getMessageBag());
|
||||
}
|
||||
$fillData = $validated->validated();
|
||||
|
||||
if (isset($fillData['type']) && is_array($fillData['type'])) {
|
||||
$fillData['type'] = implode(',', $fillData['type']);
|
||||
} else {
|
||||
$fillData['type'] = null;
|
||||
}
|
||||
$contact = new Contact;
|
||||
|
||||
$contact->fill($fillData);
|
||||
$contact->status = DbStatusFieldEnum::active;
|
||||
$contact->save();
|
||||
|
||||
return response()->json($contact->toArray());
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*/
|
||||
public function show(int $ContactId): Response|JsonResponse
|
||||
{
|
||||
|
||||
return response()->json(Contact::findOrFail($ContactId));
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*/
|
||||
public function edit(int $ContactId): Response|JsonResponse
|
||||
{
|
||||
return response()->noContent();
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*/
|
||||
public function update(Request $request, int $ContactId): Response|JsonResponse|ErrorList
|
||||
{
|
||||
/*dd(var_export(ContactTypeEnum::getKeys(),true),[
|
||||
'name'=>'required',
|
||||
'email'=>'email',
|
||||
//'phone'=>'regex:"^[\/+][0-9]{1,2}[(][0-9]{1,2}[)][0-9]{3}[ ][0-9]{3,4}$"|nullable',
|
||||
'phone'=>['nullable',new PhoneRule()],
|
||||
'note'=>'string|nullable|max:65000',
|
||||
'type'=>'nullable|enum:'
|
||||
]);*/
|
||||
|
||||
$validated = Validator::make($request->all(), [
|
||||
'name' => 'required',
|
||||
'email' => 'email|nullable',
|
||||
// 'phone'=>'regex:"^[\/+][0-9]{1,2}[(][0-9]{1,2}[)][0-9]{3}[ ][0-9]{3,4}$"|nullable',
|
||||
'phone' => ['nullable', new PhoneRule],
|
||||
'note' => 'string|nullable|max:65000',
|
||||
'type.*' => ['nullable', Rule::in(ContactTypeEnum::getKeys())],
|
||||
]);
|
||||
|
||||
if ($validated->fails()) {
|
||||
return $this->convertMessageBagToJSONAPIError($validated->getMessageBag());
|
||||
}
|
||||
// dd($validated->validated());
|
||||
$fillData = $validated->validated();
|
||||
|
||||
if (isset($fillData['type']) && is_array($fillData['type'])) {
|
||||
$fillData['type'] = implode(',', $fillData['type']);
|
||||
} else {
|
||||
$fillData['type'] = null;
|
||||
}
|
||||
$contact = Contact::findOrFail($ContactId);
|
||||
$contact->fill($fillData);
|
||||
|
||||
$contact->save();
|
||||
|
||||
return response()->json($contact->toArray());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*/
|
||||
public function destroy(int $ContactId): Response|JsonResponse
|
||||
{
|
||||
$contact = Contact::findOrFail($ContactId);
|
||||
$contact->delete();
|
||||
|
||||
return response()->json(['success' => true]);
|
||||
}
|
||||
}
|
||||
@ -1,99 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Admin;
|
||||
|
||||
use App\Exports\ExportSuppliersProfitCentersExcel;
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\View\View;
|
||||
use Maatwebsite\Excel\Facades\Excel;
|
||||
|
||||
class ExportController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*/
|
||||
public function index(): View
|
||||
{
|
||||
return view('admin.export.index');
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function store(Request $request)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function show(int $id)
|
||||
{
|
||||
if (\request()->get('fileName')) {
|
||||
$fileNameWithPath = \Storage::disk()->path('Export'.DIRECTORY_SEPARATOR.\request()->get('fileName'));
|
||||
|
||||
return response()->file($fileNameWithPath, ['Content-Disposition' => 'attachment;filename='.\request()->get('fileName')]);
|
||||
}
|
||||
|
||||
$Suppliers = \App\Models\Supplier::with(['profitCenter' => function ($query) {
|
||||
$query->orderBy('name');
|
||||
}])->orderBy('name')->get();
|
||||
|
||||
$fileName = 'SuppliersProfitCenters_'.date('Ymd_His').'.xlsx';
|
||||
Excel::store(new ExportSuppliersProfitCentersExcel(['Suppliers' => $Suppliers]), 'Export/'.$fileName);
|
||||
|
||||
return view('admin.export.SupplierProfitCenterExcelSuccess', ['fileName' => $fileName]);
|
||||
|
||||
return response()->json(['success' => true]);
|
||||
|
||||
return Excel::download(new ExportSuppliersProfitCentersExcel(['Suppliers' => $Suppliers]), 'SuppliersProfitCenters'.date('Ymd_His').'.xlsx');
|
||||
|
||||
return view('admin.export.SupplierProfitCenterExcel')->with(['Suppliers' => $Suppliers]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function edit(int $id)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function update(Request $request, int $id)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function destroy(int $id)
|
||||
{
|
||||
//
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user