Compare commits
17 Commits
v1.0.0
...
refactor/s
| Author | SHA1 | Date | |
|---|---|---|---|
| 6d123cd403 | |||
| 3164a00e6c | |||
| 36cbc8da29 | |||
| 58e027cad5 | |||
| 971c5f6cd9 | |||
| 2524f00dfd | |||
| 045fcfab72 | |||
| cfe29b41a9 | |||
| bd600649b6 | |||
| 7685089540 | |||
| 889e188deb | |||
| 4a166e3cbf | |||
| d8b3a354d9 | |||
| 44f75185a1 | |||
| 3adef9341e | |||
| 3b1698ffd1 | |||
| c436302d7a |
@@ -5,10 +5,6 @@ APP_DEBUG=false
|
|||||||
APP_URL=http://localhost
|
APP_URL=http://localhost
|
||||||
|
|
||||||
PURCHASE_CHECKOUT_EXPIRATION_MINUTES=30
|
PURCHASE_CHECKOUT_EXPIRATION_MINUTES=30
|
||||||
PURCHASE_QR_EXPIRATION_MINUTES=15
|
|
||||||
PURCHASE_TELEPAGOS_EXPIRATION_MINUTES=30
|
|
||||||
PURCHASE_TRANSFER_EXPIRATION_MINUTES=1440
|
|
||||||
PURCHASE_TRANSFER_CANDIDATE_AMOUNT_TOLERANCE_PERCENTAGE=5
|
|
||||||
STOCK_RESERVATION_EXPIRATION_MINUTES=30
|
STOCK_RESERVATION_EXPIRATION_MINUTES=30
|
||||||
FRONTEND_URLS=http://localhost:4200
|
FRONTEND_URLS=http://localhost:4200
|
||||||
|
|
||||||
@@ -45,7 +41,6 @@ COMMANDS_LOG_LEVEL=info
|
|||||||
COMMANDS_LOG_DAYS=30
|
COMMANDS_LOG_DAYS=30
|
||||||
EMAILS_LOG_LEVEL=info
|
EMAILS_LOG_LEVEL=info
|
||||||
EMAILS_LOG_DAYS=30
|
EMAILS_LOG_DAYS=30
|
||||||
EMAIL_DELIVERY_LEASE_SECONDS=300
|
|
||||||
|
|
||||||
DB_CONNECTION=mysql
|
DB_CONNECTION=mysql
|
||||||
DB_HOST=127.0.0.1
|
DB_HOST=127.0.0.1
|
||||||
|
|||||||
54
AGENTS.md
54
AGENTS.md
@@ -1,29 +1,19 @@
|
|||||||
# Project Conventions
|
# Project Conventions
|
||||||
|
|
||||||
## Test database safety
|
|
||||||
|
|
||||||
- Tests must use SQLite `:memory:` through `tests/bootstrap.php` and `Tests\TestCase`.
|
|
||||||
- Never run tests, `migrate:fresh`, `migrate:refresh`, or `db:wipe` against a persistent database, including the developer's `shopit` database.
|
|
||||||
- Never bypass the connection safety guard to resolve test failures. Use `php tests/verify-database-safety.php` to verify isolation without queries or migrations.
|
|
||||||
|
|
||||||
## Architecture
|
## Architecture
|
||||||
|
|
||||||
This project uses a domain-oriented structure grouped by business area under
|
This project uses a domain-oriented structure under `app/Domains`.
|
||||||
`app/Domains`. Cross-cutting modules live under `app/Shared`.
|
|
||||||
|
|
||||||
Business domains must live in:
|
Each domain must live in:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
app/Domains/<Area>/<DomainName>/
|
app/Domains/<DomainName>/
|
||||||
```
|
```
|
||||||
|
|
||||||
The current areas are `Core`, `Commerce`, and `Ticketing`. Cross-cutting
|
|
||||||
modules live in `app/Shared/<ModuleName>/`.
|
|
||||||
|
|
||||||
Supported folders inside each domain:
|
Supported folders inside each domain:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
app/Domains/<Area>/<DomainName>/
|
app/Domains/<DomainName>/
|
||||||
├── Models/
|
├── Models/
|
||||||
├── Controllers/
|
├── Controllers/
|
||||||
├── Requests/
|
├── Requests/
|
||||||
@@ -38,28 +28,22 @@ app/Domains/<Area>/<DomainName>/
|
|||||||
|
|
||||||
- Root API routes live in `routes/api.php`.
|
- Root API routes live in `routes/api.php`.
|
||||||
- `routes/api.php` should act as an aggregator only.
|
- `routes/api.php` should act as an aggregator only.
|
||||||
- Each business domain defines its own routes in
|
- Each domain defines its own routes in `app/Domains/<DomainName>/routes/api.php`.
|
||||||
`app/Domains/<Area>/<DomainName>/routes/api.php`.
|
|
||||||
- Shared modules that expose routes define them in
|
|
||||||
`app/Shared/<ModuleName>/routes/api.php`.
|
|
||||||
|
|
||||||
## Namespaces
|
## Namespaces
|
||||||
|
|
||||||
Use this namespace pattern:
|
Use this namespace pattern:
|
||||||
|
|
||||||
```php
|
```php
|
||||||
App\Domains\<Area>\<DomainName>\Models
|
App\Domains\<DomainName>\Models
|
||||||
App\Domains\<Area>\<DomainName>\Controllers
|
App\Domains\<DomainName>\Controllers
|
||||||
App\Domains\<Area>\<DomainName>\Requests
|
App\Domains\<DomainName>\Requests
|
||||||
App\Domains\<Area>\<DomainName>\Resources
|
App\Domains\<DomainName>\Resources
|
||||||
App\Domains\<Area>\<DomainName>\Services
|
App\Domains\<DomainName>\Services
|
||||||
App\Domains\<Area>\<DomainName>\Policies
|
App\Domains\<DomainName>\Policies
|
||||||
App\Domains\<Area>\<DomainName>\Exceptions
|
App\Domains\<DomainName>\Exceptions
|
||||||
```
|
```
|
||||||
|
|
||||||
For cross-cutting modules, use `App\Shared\<ModuleName>\...`. Reusable enums
|
|
||||||
and rules live directly under `App\Shared`.
|
|
||||||
|
|
||||||
## Responsibilities
|
## Responsibilities
|
||||||
|
|
||||||
- `Models/`: Eloquent models and model relationships.
|
- `Models/`: Eloquent models and model relationships.
|
||||||
@@ -90,19 +74,13 @@ and rules live directly under `App\Shared`.
|
|||||||
- Namespace, folder, and class names must stay aligned.
|
- Namespace, folder, and class names must stay aligned.
|
||||||
- Route files should be named `api.php`.
|
- Route files should be named `api.php`.
|
||||||
|
|
||||||
## Current Areas and Modules
|
## Current Domains
|
||||||
|
|
||||||
- `Core`: `Administrator`, `Auth`, `Authorization`, `Bootstrap`, `Client`,
|
- `Tenant`
|
||||||
`Menu`, `Staff`, `Tenant`.
|
- `Product`
|
||||||
- `Commerce`: `Cart`, `Catalog`, `Purchase`, `Sale`.
|
|
||||||
- `Ticketing`: `Desfile`, `Event`, `FiestaFutbolInfantil`, `Ticket`.
|
|
||||||
- `Shared`: `Attachable`, `Forms`, `Integration`, `Logging`, `MailTest`,
|
|
||||||
`Notification`, `StorageTest`, plus shared enums and rules.
|
|
||||||
|
|
||||||
## Notes For Future Changes
|
## Notes For Future Changes
|
||||||
|
|
||||||
- New features should be added inside the corresponding domain first.
|
- New features should be added inside the corresponding domain first.
|
||||||
- Add new business features to the appropriate area under `app/Domains`.
|
- If a concern does not belong to an existing domain, create a new domain under `app/Domains`.
|
||||||
- Keep generic reusable code in `app/Shared`; do not use it as a catch-all for
|
|
||||||
business features.
|
|
||||||
- Avoid placing new business code in `app/Http/Controllers` or `app/Models`.
|
- Avoid placing new business code in `app/Http/Controllers` or `app/Models`.
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Shared\Attachable\Enums;
|
namespace App\Domains\Attachable\Enums;
|
||||||
|
|
||||||
enum AttachmentType: string
|
enum AttachmentType: string
|
||||||
{
|
{
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Shared\Attachable\Exceptions;
|
namespace App\Domains\Attachable\Exceptions;
|
||||||
|
|
||||||
use RuntimeException;
|
use RuntimeException;
|
||||||
|
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Shared\Attachable\Models;
|
namespace App\Domains\Attachable\Models;
|
||||||
|
|
||||||
use App\Shared\Attachable\Enums\AttachmentType;
|
use App\Domains\Attachable\Enums\AttachmentType;
|
||||||
use Illuminate\Database\Eloquent\Attributes\Fillable;
|
use Illuminate\Database\Eloquent\Attributes\Fillable;
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Shared\Attachable\Models;
|
namespace App\Domains\Attachable\Models;
|
||||||
|
|
||||||
use Illuminate\Database\Eloquent\Attributes\Fillable;
|
use Illuminate\Database\Eloquent\Attributes\Fillable;
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Shared\Attachable\Services;
|
namespace App\Domains\Attachable\Services;
|
||||||
|
|
||||||
use App\Shared\Attachable\Enums\AttachmentType;
|
use App\Domains\Attachable\Enums\AttachmentType;
|
||||||
use App\Shared\Attachable\Exceptions\AttachmentStorageException;
|
use App\Domains\Attachable\Exceptions\AttachmentStorageException;
|
||||||
use App\Shared\Attachable\Models\Attachment;
|
use App\Domains\Attachable\Models\Attachment;
|
||||||
use App\Shared\Attachable\Models\AttachmentCrop;
|
use App\Domains\Attachable\Models\AttachmentCrop;
|
||||||
use Illuminate\Http\UploadedFile;
|
use Illuminate\Http\UploadedFile;
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
use Illuminate\Support\Facades\Storage;
|
use Illuminate\Support\Facades\Storage;
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Domains\Core\Auth\Controllers;
|
namespace App\Domains\Auth\Controllers;
|
||||||
|
|
||||||
use App\Domains\Core\Auth\Requests\AdminAppLoginRequest;
|
use App\Domains\Auth\Requests\AdminAppLoginRequest;
|
||||||
use App\Domains\Core\Auth\Resources\UserResource;
|
use App\Domains\Auth\Resources\UserResource;
|
||||||
use App\Domains\Core\Auth\Services\PasswordLoginService;
|
use App\Domains\Auth\Services\PasswordLoginService;
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
|
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Domains\Core\Auth\Controllers;
|
namespace App\Domains\Auth\Controllers;
|
||||||
|
|
||||||
use App\Domains\Core\Auth\Models\User;
|
use App\Domains\Auth\Models\User;
|
||||||
use App\Domains\Core\Auth\Resources\AdminAppMeResource;
|
use App\Domains\Auth\Resources\AdminAppMeResource;
|
||||||
use App\Domains\Core\Auth\Services\AdminAppContextService;
|
use App\Domains\Auth\Services\AdminAppContextService;
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Domains\Core\Auth\Controllers;
|
namespace App\Domains\Auth\Controllers;
|
||||||
|
|
||||||
use App\Domains\Core\Auth\Models\ResetPasswordAttempt;
|
use App\Domains\Auth\Models\ResetPasswordAttempt;
|
||||||
use App\Domains\Core\Auth\Requests\AdminAppCreateResetPasswordAttemptRequest;
|
use App\Domains\Auth\Requests\AdminAppCreateResetPasswordAttemptRequest;
|
||||||
use App\Domains\Core\Auth\Services\ResetPasswordAttemptService;
|
use App\Domains\Auth\Services\ResetPasswordAttemptService;
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
|
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Domains\Core\Auth\Controllers;
|
namespace App\Domains\Auth\Controllers;
|
||||||
|
|
||||||
use App\Domains\Core\Auth\Models\ResetPasswordAttempt;
|
use App\Domains\Auth\Models\ResetPasswordAttempt;
|
||||||
use App\Domains\Core\Auth\Requests\CreateResetPasswordAttemptRequest;
|
use App\Domains\Auth\Requests\CreateResetPasswordAttemptRequest;
|
||||||
use App\Domains\Core\Auth\Services\ResetPasswordAttemptService;
|
use App\Domains\Auth\Services\ResetPasswordAttemptService;
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
|
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Domains\Core\Auth\Controllers;
|
namespace App\Domains\Auth\Controllers;
|
||||||
|
|
||||||
use App\Domains\Core\Auth\Models\ResetPasswordAttempt;
|
use App\Domains\Auth\Models\ResetPasswordAttempt;
|
||||||
use App\Domains\Core\Auth\Requests\ScannerCreateResetPasswordAttemptRequest;
|
use App\Domains\Auth\Requests\ScannerCreateResetPasswordAttemptRequest;
|
||||||
use App\Domains\Core\Auth\Services\ResetPasswordAttemptService;
|
use App\Domains\Auth\Services\ResetPasswordAttemptService;
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
|
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Domains\Core\Auth\Controllers;
|
namespace App\Domains\Auth\Controllers;
|
||||||
|
|
||||||
use App\Domains\Core\Auth\Services\GoogleAuthService;
|
use App\Domains\Auth\Services\GoogleAuthService;
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use Illuminate\Http\RedirectResponse;
|
use Illuminate\Http\RedirectResponse;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Domains\Core\Auth\Controllers;
|
namespace App\Domains\Auth\Controllers;
|
||||||
|
|
||||||
use App\Domains\Core\Auth\Requests\GoogleTokenExchangeRequest;
|
use App\Domains\Auth\Requests\GoogleTokenExchangeRequest;
|
||||||
use App\Domains\Core\Auth\Resources\UserResource;
|
use App\Domains\Auth\Resources\UserResource;
|
||||||
use App\Domains\Core\Auth\Services\GoogleAuthService;
|
use App\Domains\Auth\Services\GoogleAuthService;
|
||||||
use App\Domains\Commerce\Cart\Services\GuestCartMergeService;
|
use App\Domains\Cart\Services\GuestCartMergeService;
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
use Illuminate\Support\Facades\Cookie;
|
use Illuminate\Support\Facades\Cookie;
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Domains\Core\Auth\Controllers;
|
namespace App\Domains\Auth\Controllers;
|
||||||
|
|
||||||
use App\Domains\Core\Auth\Requests\LoginUserRequest;
|
use App\Domains\Auth\Requests\LoginUserRequest;
|
||||||
use App\Domains\Core\Auth\Resources\UserResource;
|
use App\Domains\Auth\Resources\UserResource;
|
||||||
use App\Domains\Core\Auth\Services\PasswordLoginService;
|
use App\Domains\Auth\Services\PasswordLoginService;
|
||||||
use App\Domains\Commerce\Cart\Services\GuestCartMergeService;
|
use App\Domains\Cart\Services\GuestCartMergeService;
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
use Illuminate\Support\Facades\Cookie;
|
use Illuminate\Support\Facades\Cookie;
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Domains\Core\Auth\Controllers;
|
namespace App\Domains\Auth\Controllers;
|
||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Domains\Core\Auth\Controllers;
|
namespace App\Domains\Auth\Controllers;
|
||||||
|
|
||||||
use App\Domains\Core\Auth\Resources\UserResource;
|
use App\Domains\Auth\Resources\UserResource;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Domains\Core\Auth\Controllers;
|
namespace App\Domains\Auth\Controllers;
|
||||||
|
|
||||||
use App\Domains\Core\Auth\Requests\RegisterUserRequest;
|
use App\Domains\Auth\Requests\RegisterUserRequest;
|
||||||
use App\Domains\Core\Auth\Resources\UserResource;
|
use App\Domains\Auth\Resources\UserResource;
|
||||||
use App\Domains\Core\Auth\Services\RegisterUserService;
|
use App\Domains\Auth\Services\RegisterUserService;
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
|
|
||||||
@@ -1,11 +1,10 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Domains\Core\Auth\Controllers;
|
namespace App\Domains\Auth\Controllers;
|
||||||
|
|
||||||
use App\Domains\Core\Auth\Models\ResetPasswordAttempt;
|
use App\Domains\Auth\Models\ResetPasswordAttempt;
|
||||||
use App\Domains\Core\Auth\Requests\ResetPasswordRequest;
|
use App\Domains\Auth\Requests\ResetPasswordRequest;
|
||||||
use App\Domains\Core\Auth\Services\ResetPasswordAttemptService;
|
use App\Domains\Auth\Services\ResetPasswordAttemptService;
|
||||||
use App\Domains\Core\Authorization\Enums\RoleCode;
|
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
use Illuminate\Validation\ValidationException;
|
use Illuminate\Validation\ValidationException;
|
||||||
@@ -27,7 +26,6 @@ class ResetPasswordController extends Controller
|
|||||||
$data['email'],
|
$data['email'],
|
||||||
$data['codigo'],
|
$data['codigo'],
|
||||||
$data['password'],
|
$data['password'],
|
||||||
RoleCode::from($request->route('reset_role', RoleCode::User->value)),
|
|
||||||
)) {
|
)) {
|
||||||
throw ValidationException::withMessages([
|
throw ValidationException::withMessages([
|
||||||
'codigo' => __('api.auth.password_reset_invalid'),
|
'codigo' => __('api.auth.password_reset_invalid'),
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Domains\Core\Auth\Controllers;
|
namespace App\Domains\Auth\Controllers;
|
||||||
|
|
||||||
use App\Domains\Core\Auth\Requests\ScannerLoginRequest;
|
use App\Domains\Auth\Requests\ScannerLoginRequest;
|
||||||
use App\Domains\Core\Auth\Resources\UserResource;
|
use App\Domains\Auth\Resources\UserResource;
|
||||||
use App\Domains\Core\Auth\Services\PasswordLoginService;
|
use App\Domains\Auth\Services\PasswordLoginService;
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
|
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Domains\Core\Auth\Controllers;
|
namespace App\Domains\Auth\Controllers;
|
||||||
|
|
||||||
use App\Domains\Core\Auth\Models\User;
|
use App\Domains\Auth\Models\User;
|
||||||
use App\Domains\Core\Auth\Resources\ScannerMeResource;
|
use App\Domains\Auth\Resources\ScannerMeResource;
|
||||||
use App\Domains\Core\Auth\Services\ScannerContextService;
|
use App\Domains\Auth\Services\ScannerContextService;
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Domains\Core\Auth\Controllers;
|
namespace App\Domains\Auth\Controllers;
|
||||||
|
|
||||||
use App\Domains\Core\Auth\Requests\UpdateProfileRequest;
|
use App\Domains\Auth\Requests\UpdateProfileRequest;
|
||||||
use App\Domains\Core\Auth\Resources\UserResource;
|
use App\Domains\Auth\Resources\UserResource;
|
||||||
use App\Domains\Core\Auth\Services\ProfileService;
|
use App\Domains\Auth\Services\ProfileService;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
|
|
||||||
class UpdateProfileController
|
class UpdateProfileController
|
||||||
@@ -1,11 +1,10 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Domains\Core\Auth\Controllers;
|
namespace App\Domains\Auth\Controllers;
|
||||||
|
|
||||||
use App\Domains\Core\Auth\Models\ResetPasswordAttempt;
|
use App\Domains\Auth\Models\ResetPasswordAttempt;
|
||||||
use App\Domains\Core\Auth\Requests\ValidateResetPasswordAttemptRequest;
|
use App\Domains\Auth\Requests\ValidateResetPasswordAttemptRequest;
|
||||||
use App\Domains\Core\Auth\Services\ResetPasswordAttemptService;
|
use App\Domains\Auth\Services\ResetPasswordAttemptService;
|
||||||
use App\Domains\Core\Authorization\Enums\RoleCode;
|
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
use Illuminate\Validation\ValidationException;
|
use Illuminate\Validation\ValidationException;
|
||||||
@@ -26,7 +25,6 @@ class ValidateResetPasswordAttemptController extends Controller
|
|||||||
$result = $this->resetPasswordAttemptService->validateCode(
|
$result = $this->resetPasswordAttemptService->validateCode(
|
||||||
$data['email'],
|
$data['email'],
|
||||||
$data['codigo'],
|
$data['codigo'],
|
||||||
RoleCode::from($request->route('reset_role', RoleCode::User->value)),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
if ($result === ResetPasswordAttemptService::CODE_EXPIRED) {
|
if ($result === ResetPasswordAttemptService::CODE_EXPIRED) {
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Domains\Core\Auth\Exceptions;
|
namespace App\Domains\Auth\Exceptions;
|
||||||
|
|
||||||
use Carbon\CarbonImmutable;
|
use Carbon\CarbonImmutable;
|
||||||
use RuntimeException;
|
use RuntimeException;
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Domains\Core\Auth\Models;
|
namespace App\Domains\Auth\Models;
|
||||||
|
|
||||||
use Illuminate\Database\Eloquent\Attributes\Fillable;
|
use Illuminate\Database\Eloquent\Attributes\Fillable;
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Domains\Core\Auth\Models;
|
namespace App\Domains\Auth\Models;
|
||||||
|
|
||||||
use Illuminate\Database\Eloquent\Attributes\Fillable;
|
use Illuminate\Database\Eloquent\Attributes\Fillable;
|
||||||
use Illuminate\Database\Eloquent\Attributes\Hidden;
|
use Illuminate\Database\Eloquent\Attributes\Hidden;
|
||||||
@@ -17,8 +17,6 @@ class ResetPasswordAttempt extends Model
|
|||||||
|
|
||||||
public const REASON_STAFF_CREATED = 'staff_created';
|
public const REASON_STAFF_CREATED = 'staff_created';
|
||||||
|
|
||||||
public const REASON_ADMINISTRATOR_CREATED = 'administrator_created';
|
|
||||||
|
|
||||||
public const STATUS_PENDING = 'pending';
|
public const STATUS_PENDING = 'pending';
|
||||||
|
|
||||||
public const STATUS_VALIDATED = 'validated';
|
public const STATUS_VALIDATED = 'validated';
|
||||||
@@ -1,13 +1,11 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Domains\Core\Auth\Models;
|
namespace App\Domains\Auth\Models;
|
||||||
|
|
||||||
use App\Domains\Core\Authorization\Enums\RoleCode;
|
use App\Domains\Authorization\Enums\RoleCode;
|
||||||
use App\Domains\Core\Authorization\Models\Role;
|
use App\Domains\Authorization\Models\Role;
|
||||||
use App\Domains\Commerce\Catalog\Models\Category;
|
use App\Domains\Catalog\Models\Category;
|
||||||
use App\Domains\Ticketing\Event\Models\EventDateChangeView;
|
use App\Domains\Tenant\Models\Tenant;
|
||||||
use App\Domains\Core\Tenant\Models\Tenant;
|
|
||||||
use App\Domains\Ticketing\Ticket\Models\ScanAttempt;
|
|
||||||
use Database\Factories\UserFactory;
|
use Database\Factories\UserFactory;
|
||||||
use Illuminate\Database\Eloquent\Attributes\Fillable;
|
use Illuminate\Database\Eloquent\Attributes\Fillable;
|
||||||
use Illuminate\Database\Eloquent\Attributes\Hidden;
|
use Illuminate\Database\Eloquent\Attributes\Hidden;
|
||||||
@@ -15,17 +13,16 @@ use Illuminate\Database\Eloquent\Factories\HasFactory;
|
|||||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||||
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
|
||||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||||
use Illuminate\Notifications\Notifiable;
|
use Illuminate\Notifications\Notifiable;
|
||||||
use Laravel\Sanctum\HasApiTokens;
|
use Laravel\Sanctum\HasApiTokens;
|
||||||
|
|
||||||
#[Fillable(['nombre_apellido', 'email', 'password', 'dni', 'telefono', 'google_id', 'rol_codigo', 'tenant_codigo'])]
|
#[Fillable(['nombre_apellido', 'email', 'password', 'dni', 'telefono', 'google_id', 'rol_codigo', 'tenant_codigo'])]
|
||||||
#[Hidden(['password', 'remember_token', 'active_email', 'active_google_id'])]
|
#[Hidden(['password', 'remember_token'])]
|
||||||
class User extends Authenticatable
|
class User extends Authenticatable
|
||||||
{
|
{
|
||||||
/** @use HasFactory<UserFactory> */
|
/** @use HasFactory<UserFactory> */
|
||||||
use HasApiTokens, HasFactory, Notifiable, SoftDeletes;
|
use HasApiTokens, HasFactory, Notifiable;
|
||||||
|
|
||||||
protected $attributes = [
|
protected $attributes = [
|
||||||
'rol_codigo' => RoleCode::User->value,
|
'rol_codigo' => RoleCode::User->value,
|
||||||
@@ -48,18 +45,6 @@ class User extends Authenticatable
|
|||||||
return $this->hasMany(LoginAttempt::class);
|
return $this->hasMany(LoginAttempt::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @return HasMany<ScanAttempt, $this> */
|
|
||||||
public function scanAttempts(): HasMany
|
|
||||||
{
|
|
||||||
return $this->hasMany(ScanAttempt::class, 'scanner_user_id');
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @return HasMany<EventDateChangeView, $this> */
|
|
||||||
public function eventDateChangeViews(): HasMany
|
|
||||||
{
|
|
||||||
return $this->hasMany(EventDateChangeView::class);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return BelongsTo<Role, $this>
|
* @return BelongsTo<Role, $this>
|
||||||
*/
|
*/
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Domains\Core\Auth\Requests;
|
namespace App\Domains\Auth\Requests;
|
||||||
|
|
||||||
use Illuminate\Foundation\Http\FormRequest;
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Domains\Core\Auth\Requests;
|
namespace App\Domains\Auth\Requests;
|
||||||
|
|
||||||
use Illuminate\Foundation\Http\FormRequest;
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Domains\Core\Auth\Requests;
|
namespace App\Domains\Auth\Requests;
|
||||||
|
|
||||||
use Illuminate\Foundation\Http\FormRequest;
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Domains\Core\Auth\Requests;
|
namespace App\Domains\Auth\Requests;
|
||||||
|
|
||||||
use Illuminate\Foundation\Http\FormRequest;
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Domains\Core\Auth\Requests;
|
namespace App\Domains\Auth\Requests;
|
||||||
|
|
||||||
use Illuminate\Foundation\Http\FormRequest;
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
@@ -1,8 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Domains\Core\Auth\Requests;
|
namespace App\Domains\Auth\Requests;
|
||||||
|
|
||||||
use App\Domains\Core\Authorization\Enums\RoleCode;
|
|
||||||
use Illuminate\Foundation\Http\FormRequest;
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
use Illuminate\Validation\Rule;
|
use Illuminate\Validation\Rule;
|
||||||
use Illuminate\Validation\Rules\Password;
|
use Illuminate\Validation\Rules\Password;
|
||||||
@@ -14,26 +13,15 @@ class RegisterUserRequest extends FormRequest
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function prepareForValidation(): void
|
/**
|
||||||
{
|
* @return array<string, mixed>
|
||||||
if (is_string($this->input('email'))) {
|
*/
|
||||||
$this->merge(['email' => mb_strtolower(trim($this->input('email')))]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @return array<string, mixed> */
|
|
||||||
public function rules(): array
|
public function rules(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'tenant_codigo' => ['nullable', 'string', Rule::exists('tenants', 'codigo')],
|
'tenant_codigo' => ['nullable', 'string', Rule::exists('tenants', 'codigo')],
|
||||||
'nombre_apellido' => ['required', 'string', 'max:255'],
|
'nombre_apellido' => ['required', 'string', 'max:255'],
|
||||||
'email' => [
|
'email' => ['required', 'string', 'email', 'max:255', Rule::unique('users', 'email')],
|
||||||
'required',
|
|
||||||
'string',
|
|
||||||
'email',
|
|
||||||
'max:255',
|
|
||||||
Rule::unique('users', 'active_email')->where('rol_codigo', RoleCode::User->value)->whereNull('deleted_at'),
|
|
||||||
],
|
|
||||||
'password' => ['required', 'string', 'confirmed', Password::min(8)->mixedCase()->symbols()],
|
'password' => ['required', 'string', 'confirmed', Password::min(8)->mixedCase()->symbols()],
|
||||||
'dni' => ['nullable', 'string', 'max:255'],
|
'dni' => ['nullable', 'string', 'max:255'],
|
||||||
'telefono' => ['nullable', 'string', 'max:255'],
|
'telefono' => ['nullable', 'string', 'max:255'],
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Domains\Core\Auth\Requests;
|
namespace App\Domains\Auth\Requests;
|
||||||
|
|
||||||
use Illuminate\Foundation\Http\FormRequest;
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Domains\Core\Auth\Requests;
|
namespace App\Domains\Auth\Requests;
|
||||||
|
|
||||||
use Illuminate\Foundation\Http\FormRequest;
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Domains\Core\Auth\Requests;
|
namespace App\Domains\Auth\Requests;
|
||||||
|
|
||||||
class ScannerLoginRequest extends AdminAppLoginRequest {}
|
class ScannerLoginRequest extends AdminAppLoginRequest {}
|
||||||
@@ -1,10 +1,9 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Domains\Core\Auth\Requests;
|
namespace App\Domains\Auth\Requests;
|
||||||
|
|
||||||
use Illuminate\Foundation\Http\FormRequest;
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
use Illuminate\Validation\Rule;
|
use Illuminate\Validation\Rule;
|
||||||
use Illuminate\Validation\Rules\Password;
|
|
||||||
|
|
||||||
class UpdateProfileRequest extends FormRequest
|
class UpdateProfileRequest extends FormRequest
|
||||||
{
|
{
|
||||||
@@ -13,13 +12,6 @@ class UpdateProfileRequest extends FormRequest
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function prepareForValidation(): void
|
|
||||||
{
|
|
||||||
if (is_string($this->input('email'))) {
|
|
||||||
$this->merge(['email' => mb_strtolower(trim($this->input('email')))]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function rules(): array
|
public function rules(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
@@ -27,13 +19,11 @@ class UpdateProfileRequest extends FormRequest
|
|||||||
'email' => [
|
'email' => [
|
||||||
'required',
|
'required',
|
||||||
'email',
|
'email',
|
||||||
Rule::unique('users', 'active_email')->where('rol_codigo', $this->user()->rol_codigo)
|
Rule::unique('users', 'email')->ignore($this->user()->id),
|
||||||
->whereNull('deleted_at')
|
|
||||||
->ignore($this->user()->id),
|
|
||||||
],
|
],
|
||||||
'dni' => ['nullable', 'string', 'regex:/^[0-9]{7,8}$/'],
|
'dni' => ['nullable', 'string', 'regex:/^[0-9]{7,8}$/'],
|
||||||
'telefono' => ['nullable', 'string', 'regex:/^\+?[0-9\s\-]+$/'],
|
'telefono' => ['nullable', 'string', 'regex:/^\+?[0-9\s\-]+$/'],
|
||||||
'password' => ['nullable', 'string', Password::min(8)->mixedCase()->symbols()],
|
'password' => ['nullable', 'string', \Illuminate\Validation\Rules\Password::min(8)->mixedCase()->symbols()],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Domains\Core\Auth\Requests;
|
namespace App\Domains\Auth\Requests;
|
||||||
|
|
||||||
use Illuminate\Foundation\Http\FormRequest;
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Domains\Core\Auth\Resources;
|
namespace App\Domains\Auth\Resources;
|
||||||
|
|
||||||
use App\Domains\Core\Auth\Models\User;
|
use App\Domains\Auth\Models\User;
|
||||||
use App\Domains\Core\Tenant\Resources\TenantResource;
|
use App\Domains\Tenant\Resources\TenantResource;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Http\Resources\Json\JsonResource;
|
use Illuminate\Http\Resources\Json\JsonResource;
|
||||||
|
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Domains\Core\Auth\Resources;
|
namespace App\Domains\Auth\Resources;
|
||||||
|
|
||||||
use App\Domains\Core\Auth\Models\User;
|
use App\Domains\Auth\Models\User;
|
||||||
use App\Domains\Core\Tenant\Resources\TenantResource;
|
use App\Domains\Tenant\Resources\TenantResource;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Http\Resources\Json\JsonResource;
|
use Illuminate\Http\Resources\Json\JsonResource;
|
||||||
|
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Domains\Core\Auth\Resources;
|
namespace App\Domains\Auth\Resources;
|
||||||
|
|
||||||
use App\Domains\Core\Auth\Models\User;
|
use App\Domains\Auth\Models\User;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Http\Resources\Json\JsonResource;
|
use Illuminate\Http\Resources\Json\JsonResource;
|
||||||
|
|
||||||
@@ -24,11 +24,6 @@ class UserResource extends JsonResource
|
|||||||
'telefono' => $this->telefono,
|
'telefono' => $this->telefono,
|
||||||
'rol_codigo' => $this->rol_codigo,
|
'rol_codigo' => $this->rol_codigo,
|
||||||
'tenant_codigo' => $this->tenant_codigo,
|
'tenant_codigo' => $this->tenant_codigo,
|
||||||
'categories' => $this->whenLoaded('scanCategories', fn () => $this->scanCategories
|
|
||||||
->map(fn ($category) => [
|
|
||||||
'id' => $category->id,
|
|
||||||
'nombre' => $category->nombre,
|
|
||||||
])->values()),
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Domains\Core\Auth\Services;
|
namespace App\Domains\Auth\Services;
|
||||||
|
|
||||||
use App\Domains\Core\Auth\Models\User;
|
use App\Domains\Auth\Models\User;
|
||||||
use App\Domains\Core\Authorization\Enums\RoleCode;
|
use App\Domains\Authorization\Enums\RoleCode;
|
||||||
|
|
||||||
class AdminAppContextService
|
class AdminAppContextService
|
||||||
{
|
{
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Domains\Core\Auth\Services;
|
namespace App\Domains\Auth\Services;
|
||||||
|
|
||||||
use App\Domains\Core\Auth\Models\User;
|
use App\Domains\Auth\Models\User;
|
||||||
use App\Domains\Core\Authorization\Enums\RoleCode;
|
use App\Domains\Authorization\Enums\RoleCode;
|
||||||
use Illuminate\Support\Facades\Hash;
|
use Illuminate\Support\Facades\Hash;
|
||||||
|
|
||||||
class AdminCredentialVerifier
|
class AdminCredentialVerifier
|
||||||
@@ -11,7 +11,7 @@ class AdminCredentialVerifier
|
|||||||
public function verify(string $email, string $password): bool
|
public function verify(string $email, string $password): bool
|
||||||
{
|
{
|
||||||
$admin = User::query()
|
$admin = User::query()
|
||||||
->where('active_email', mb_strtolower(trim($email)))
|
->where('email', mb_strtolower(trim($email)))
|
||||||
->where('rol_codigo', RoleCode::Admin->value)
|
->where('rol_codigo', RoleCode::Admin->value)
|
||||||
->first();
|
->first();
|
||||||
|
|
||||||
@@ -1,12 +1,11 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Domains\Core\Auth\Services;
|
namespace App\Domains\Auth\Services;
|
||||||
|
|
||||||
use App\Domains\Core\Auth\Models\User;
|
use App\Domains\Auth\Models\User;
|
||||||
use App\Domains\Core\Authorization\Enums\RoleCode;
|
use App\Domains\Notification\Events\UserRegistered;
|
||||||
use App\Shared\Notification\Events\UserRegistered;
|
use App\Domains\Tenant\Models\Tenant;
|
||||||
use App\Domains\Core\Tenant\Models\Tenant;
|
use App\Domains\Tenant\Support\TenantDomainNormalizer;
|
||||||
use App\Domains\Core\Tenant\Support\TenantDomainNormalizer;
|
|
||||||
use Illuminate\Http\RedirectResponse;
|
use Illuminate\Http\RedirectResponse;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Facades\Cache;
|
use Illuminate\Support\Facades\Cache;
|
||||||
@@ -125,12 +124,12 @@ class GoogleAuthService
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
$user = User::query()->where('rol_codigo', RoleCode::User->value)->where('google_id', $googleId)->first();
|
$user = User::query()->where('google_id', $googleId)->first();
|
||||||
if ($user) {
|
if ($user) {
|
||||||
return $user;
|
return $user;
|
||||||
}
|
}
|
||||||
|
|
||||||
$user = User::query()->where('rol_codigo', RoleCode::User->value)->where('active_email', mb_strtolower(trim($email)))->first();
|
$user = User::query()->where('email', $email)->first();
|
||||||
if ($user) {
|
if ($user) {
|
||||||
$user->forceFill(['google_id' => $googleId])->save();
|
$user->forceFill(['google_id' => $googleId])->save();
|
||||||
|
|
||||||
@@ -1,14 +1,14 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Domains\Core\Auth\Services;
|
namespace App\Domains\Auth\Services;
|
||||||
|
|
||||||
use App\Domains\Core\Auth\Exceptions\AccountLockedException;
|
use App\Domains\Auth\Exceptions\AccountLockedException;
|
||||||
use App\Domains\Core\Auth\Models\LoginAttempt;
|
use App\Domains\Auth\Models\LoginAttempt;
|
||||||
use App\Domains\Core\Auth\Models\ResetPasswordAttempt;
|
use App\Domains\Auth\Models\ResetPasswordAttempt;
|
||||||
use App\Domains\Core\Auth\Models\User;
|
use App\Domains\Auth\Models\User;
|
||||||
use App\Domains\Core\Authorization\Enums\PermissionCode;
|
use App\Domains\Authorization\Enums\PermissionCode;
|
||||||
use App\Domains\Core\Authorization\Enums\RoleCode;
|
use App\Domains\Authorization\Enums\RoleCode;
|
||||||
use App\Shared\Notification\Events\PasswordResetRequested;
|
use App\Domains\Notification\Events\PasswordResetRequested;
|
||||||
use Carbon\CarbonImmutable;
|
use Carbon\CarbonImmutable;
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
use Illuminate\Support\Facades\Hash;
|
use Illuminate\Support\Facades\Hash;
|
||||||
@@ -85,7 +85,7 @@ class PasswordLoginService
|
|||||||
null,
|
null,
|
||||||
$ipAddress,
|
$ipAddress,
|
||||||
$userAgent,
|
$userAgent,
|
||||||
RoleCode::Scanner,
|
null,
|
||||||
true,
|
true,
|
||||||
PermissionCode::ScanTickets->value,
|
PermissionCode::ScanTickets->value,
|
||||||
PasswordResetRequested::CHANNEL_SCANNER,
|
PasswordResetRequested::CHANNEL_SCANNER,
|
||||||
@@ -120,7 +120,7 @@ class PasswordLoginService
|
|||||||
$passwordResetChannel,
|
$passwordResetChannel,
|
||||||
): array {
|
): array {
|
||||||
$user = User::query()
|
$user = User::query()
|
||||||
->where('active_email', $normalizedEmail)
|
->where('email', $normalizedEmail)
|
||||||
->when(
|
->when(
|
||||||
$requiredRole !== null,
|
$requiredRole !== null,
|
||||||
fn ($query) => $query->where('rol_codigo', $requiredRole->value),
|
fn ($query) => $query->where('rol_codigo', $requiredRole->value),
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Domains\Core\Auth\Services;
|
namespace App\Domains\Auth\Services;
|
||||||
|
|
||||||
use App\Domains\Core\Auth\Models\User;
|
use App\Domains\Auth\Models\User;
|
||||||
use Illuminate\Support\Facades\Hash;
|
use Illuminate\Support\Facades\Hash;
|
||||||
|
|
||||||
class ProfileService
|
class ProfileService
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Domains\Core\Auth\Services;
|
namespace App\Domains\Auth\Services;
|
||||||
|
|
||||||
use App\Domains\Core\Auth\Models\User;
|
use App\Domains\Auth\Models\User;
|
||||||
use App\Shared\Notification\Events\UserRegistered;
|
use App\Domains\Notification\Events\UserRegistered;
|
||||||
|
|
||||||
class RegisterUserService
|
class RegisterUserService
|
||||||
{
|
{
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Domains\Core\Auth\Services;
|
namespace App\Domains\Auth\Services;
|
||||||
|
|
||||||
use App\Domains\Core\Auth\Models\ResetPasswordAttempt;
|
use App\Domains\Auth\Models\ResetPasswordAttempt;
|
||||||
use App\Domains\Core\Auth\Models\User;
|
use App\Domains\Auth\Models\User;
|
||||||
use App\Domains\Core\Authorization\Enums\RoleCode;
|
use App\Domains\Authorization\Enums\RoleCode;
|
||||||
use App\Shared\Notification\Events\PasswordResetRequested;
|
use App\Domains\Notification\Events\PasswordResetRequested;
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
use Illuminate\Support\Facades\Log;
|
use Illuminate\Support\Facades\Log;
|
||||||
use Throwable;
|
use Throwable;
|
||||||
@@ -28,8 +28,7 @@ class ResetPasswordAttemptService
|
|||||||
try {
|
try {
|
||||||
$attemptId = DB::transaction(function () use ($email, $emailFingerprint, $reason): ?int {
|
$attemptId = DB::transaction(function () use ($email, $emailFingerprint, $reason): ?int {
|
||||||
$user = User::query()
|
$user = User::query()
|
||||||
->where('active_email', mb_strtolower(trim($email)))
|
->where('email', $email)
|
||||||
->where('rol_codigo', RoleCode::User->value)
|
|
||||||
->lockForUpdate()
|
->lockForUpdate()
|
||||||
->first();
|
->first();
|
||||||
|
|
||||||
@@ -66,7 +65,7 @@ class ResetPasswordAttemptService
|
|||||||
try {
|
try {
|
||||||
$result = DB::transaction(function () use ($email, $emailFingerprint, $reason): ?array {
|
$result = DB::transaction(function () use ($email, $emailFingerprint, $reason): ?array {
|
||||||
$user = User::query()
|
$user = User::query()
|
||||||
->where('active_email', mb_strtolower(trim($email)))
|
->where('email', $email)
|
||||||
->where('rol_codigo', RoleCode::AdminApp->value)
|
->where('rol_codigo', RoleCode::AdminApp->value)
|
||||||
->whereNotNull('tenant_codigo')
|
->whereNotNull('tenant_codigo')
|
||||||
->lockForUpdate()
|
->lockForUpdate()
|
||||||
@@ -114,7 +113,7 @@ class ResetPasswordAttemptService
|
|||||||
try {
|
try {
|
||||||
$result = DB::transaction(function () use ($email, $emailFingerprint, $reason): ?array {
|
$result = DB::transaction(function () use ($email, $emailFingerprint, $reason): ?array {
|
||||||
$user = User::query()
|
$user = User::query()
|
||||||
->where('active_email', mb_strtolower(trim($email)))
|
->where('email', $email)
|
||||||
->where('rol_codigo', RoleCode::Scanner->value)
|
->where('rol_codigo', RoleCode::Scanner->value)
|
||||||
->whereNotNull('tenant_codigo')
|
->whereNotNull('tenant_codigo')
|
||||||
->lockForUpdate()
|
->lockForUpdate()
|
||||||
@@ -153,15 +152,14 @@ class ResetPasswordAttemptService
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function validateCode(string $email, string $code, RoleCode $role = RoleCode::User): string
|
public function validateCode(string $email, string $code): string
|
||||||
{
|
{
|
||||||
$emailFingerprint = $this->emailFingerprint($email);
|
$emailFingerprint = $this->emailFingerprint($email);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return DB::transaction(function () use ($email, $code, $emailFingerprint, $role): string {
|
return DB::transaction(function () use ($email, $code, $emailFingerprint): string {
|
||||||
$user = User::query()
|
$user = User::query()
|
||||||
->where('active_email', mb_strtolower(trim($email)))
|
->where('email', $email)
|
||||||
->where('rol_codigo', $role->value)
|
|
||||||
->lockForUpdate()
|
->lockForUpdate()
|
||||||
->first();
|
->first();
|
||||||
|
|
||||||
@@ -209,15 +207,14 @@ class ResetPasswordAttemptService
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function resetPassword(string $email, string $code, string $password, RoleCode $role = RoleCode::User): bool
|
public function resetPassword(string $email, string $code, string $password): bool
|
||||||
{
|
{
|
||||||
$emailFingerprint = $this->emailFingerprint($email);
|
$emailFingerprint = $this->emailFingerprint($email);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return DB::transaction(function () use ($email, $code, $password, $emailFingerprint, $role): bool {
|
return DB::transaction(function () use ($email, $code, $password, $emailFingerprint): bool {
|
||||||
$user = User::query()
|
$user = User::query()
|
||||||
->where('active_email', mb_strtolower(trim($email)))
|
->where('email', $email)
|
||||||
->where('rol_codigo', $role->value)
|
|
||||||
->lockForUpdate()
|
->lockForUpdate()
|
||||||
->first();
|
->first();
|
||||||
|
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Domains\Core\Auth\Services;
|
namespace App\Domains\Auth\Services;
|
||||||
|
|
||||||
use App\Domains\Core\Auth\Models\User;
|
use App\Domains\Auth\Models\User;
|
||||||
|
|
||||||
class ScannerContextService
|
class ScannerContextService
|
||||||
{
|
{
|
||||||
@@ -19,16 +19,6 @@ class ScannerContextService
|
|||||||
|
|
||||||
$user->setRelation('tenant', $tenant);
|
$user->setRelation('tenant', $tenant);
|
||||||
|
|
||||||
if ($tenant->requiresScannerCategoryValidation()) {
|
|
||||||
$categories = $user->scanCategories()
|
|
||||||
->orderBy('nombre')
|
|
||||||
->get();
|
|
||||||
|
|
||||||
if ($categories->isNotEmpty()) {
|
|
||||||
$user->setRelation('scanCategories', $categories);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $user;
|
return $user;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
use App\Domains\Core\Auth\Controllers\AdminAppLoginController;
|
use App\Domains\Auth\Controllers\AdminAppLoginController;
|
||||||
use App\Domains\Core\Auth\Controllers\AdminAppMeController;
|
use App\Domains\Auth\Controllers\AdminAppMeController;
|
||||||
use App\Domains\Core\Auth\Controllers\CreateAdminAppResetPasswordAttemptController;
|
use App\Domains\Auth\Controllers\CreateAdminAppResetPasswordAttemptController;
|
||||||
use App\Domains\Core\Auth\Controllers\ResetPasswordController;
|
use App\Domains\Auth\Controllers\ResetPasswordController;
|
||||||
use App\Domains\Core\Auth\Controllers\ValidateResetPasswordAttemptController;
|
use App\Domains\Auth\Controllers\ValidateResetPasswordAttemptController;
|
||||||
use Illuminate\Support\Facades\Route;
|
use Illuminate\Support\Facades\Route;
|
||||||
|
|
||||||
Route::prefix('v1/adminapp')->group(function (): void {
|
Route::prefix('v1/adminapp')->group(function (): void {
|
||||||
@@ -12,10 +12,8 @@ Route::prefix('v1/adminapp')->group(function (): void {
|
|||||||
Route::post('password/reset-attempts', CreateAdminAppResetPasswordAttemptController::class)
|
Route::post('password/reset-attempts', CreateAdminAppResetPasswordAttemptController::class)
|
||||||
->middleware('throttle:5,1');
|
->middleware('throttle:5,1');
|
||||||
Route::post('password/reset-attempts/validate', ValidateResetPasswordAttemptController::class)
|
Route::post('password/reset-attempts/validate', ValidateResetPasswordAttemptController::class)
|
||||||
->defaults('reset_role', 'adminapp')
|
|
||||||
->middleware('throttle:10,1');
|
->middleware('throttle:10,1');
|
||||||
Route::post('password/reset', ResetPasswordController::class)
|
Route::post('password/reset', ResetPasswordController::class)
|
||||||
->defaults('reset_role', 'adminapp')
|
|
||||||
->middleware('throttle:5,1');
|
->middleware('throttle:5,1');
|
||||||
Route::middleware(['auth:sanctum', 'adminapp.tenant'])
|
Route::middleware(['auth:sanctum', 'adminapp.tenant'])
|
||||||
->get('me', AdminAppMeController::class);
|
->get('me', AdminAppMeController::class);
|
||||||
@@ -1,14 +1,14 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
use App\Domains\Core\Auth\Controllers\CreateResetPasswordAttemptController;
|
use App\Domains\Auth\Controllers\CreateResetPasswordAttemptController;
|
||||||
use App\Domains\Core\Auth\Controllers\GoogleTokenExchangeController;
|
use App\Domains\Auth\Controllers\GoogleTokenExchangeController;
|
||||||
use App\Domains\Core\Auth\Controllers\LoginController;
|
use App\Domains\Auth\Controllers\LoginController;
|
||||||
use App\Domains\Core\Auth\Controllers\LogoutController;
|
use App\Domains\Auth\Controllers\LogoutController;
|
||||||
use App\Domains\Core\Auth\Controllers\MeController;
|
use App\Domains\Auth\Controllers\MeController;
|
||||||
use App\Domains\Core\Auth\Controllers\RegisterController;
|
use App\Domains\Auth\Controllers\RegisterController;
|
||||||
use App\Domains\Core\Auth\Controllers\ResetPasswordController;
|
use App\Domains\Auth\Controllers\ResetPasswordController;
|
||||||
use App\Domains\Core\Auth\Controllers\UpdateProfileController;
|
use App\Domains\Auth\Controllers\UpdateProfileController;
|
||||||
use App\Domains\Core\Auth\Controllers\ValidateResetPasswordAttemptController;
|
use App\Domains\Auth\Controllers\ValidateResetPasswordAttemptController;
|
||||||
use Illuminate\Support\Facades\Route;
|
use Illuminate\Support\Facades\Route;
|
||||||
|
|
||||||
Route::post('/register', RegisterController::class);
|
Route::post('/register', RegisterController::class);
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
use App\Domains\Core\Auth\Controllers\CreateScannerResetPasswordAttemptController;
|
use App\Domains\Auth\Controllers\CreateScannerResetPasswordAttemptController;
|
||||||
use App\Domains\Core\Auth\Controllers\ResetPasswordController;
|
use App\Domains\Auth\Controllers\ResetPasswordController;
|
||||||
use App\Domains\Core\Auth\Controllers\ScannerLoginController;
|
use App\Domains\Auth\Controllers\ScannerLoginController;
|
||||||
use App\Domains\Core\Auth\Controllers\ScannerMeController;
|
use App\Domains\Auth\Controllers\ScannerMeController;
|
||||||
use App\Domains\Core\Auth\Controllers\ValidateResetPasswordAttemptController;
|
use App\Domains\Auth\Controllers\ValidateResetPasswordAttemptController;
|
||||||
use Illuminate\Support\Facades\Route;
|
use Illuminate\Support\Facades\Route;
|
||||||
|
|
||||||
Route::prefix('v1/scanner')->group(function (): void {
|
Route::prefix('v1/scanner')->group(function (): void {
|
||||||
@@ -12,10 +12,8 @@ Route::prefix('v1/scanner')->group(function (): void {
|
|||||||
Route::post('password/reset-attempts', CreateScannerResetPasswordAttemptController::class)
|
Route::post('password/reset-attempts', CreateScannerResetPasswordAttemptController::class)
|
||||||
->middleware('throttle:5,1');
|
->middleware('throttle:5,1');
|
||||||
Route::post('password/reset-attempts/validate', ValidateResetPasswordAttemptController::class)
|
Route::post('password/reset-attempts/validate', ValidateResetPasswordAttemptController::class)
|
||||||
->defaults('reset_role', 'scanner')
|
|
||||||
->middleware('throttle:10,1');
|
->middleware('throttle:10,1');
|
||||||
Route::post('password/reset', ResetPasswordController::class)
|
Route::post('password/reset', ResetPasswordController::class)
|
||||||
->defaults('reset_role', 'scanner')
|
|
||||||
->middleware('throttle:5,1');
|
->middleware('throttle:5,1');
|
||||||
Route::middleware(['auth:sanctum', 'scanner.tenant'])
|
Route::middleware(['auth:sanctum', 'scanner.tenant'])
|
||||||
->get('me', ScannerMeController::class);
|
->get('me', ScannerMeController::class);
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Domains\Core\Authorization\Enums;
|
namespace App\Domains\Authorization\Enums;
|
||||||
|
|
||||||
enum PermissionCode: string
|
enum PermissionCode: string
|
||||||
{
|
{
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Domains\Core\Authorization\Enums;
|
namespace App\Domains\Authorization\Enums;
|
||||||
|
|
||||||
enum RoleCode: string
|
enum RoleCode: string
|
||||||
{
|
{
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Domains\Core\Authorization\Models;
|
namespace App\Domains\Authorization\Models;
|
||||||
|
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Domains\Core\Authorization\Models;
|
namespace App\Domains\Authorization\Models;
|
||||||
|
|
||||||
use App\Domains\Core\Auth\Models\User;
|
use App\Domains\Auth\Models\User;
|
||||||
use App\Domains\Core\Menu\Models\Menu;
|
use App\Domains\Menu\Models\Menu;
|
||||||
use App\Domains\Core\Menu\Models\MenuRole;
|
use App\Domains\Menu\Models\MenuRole;
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Domains\Core\Authorization\Models;
|
namespace App\Domains\Authorization\Models;
|
||||||
|
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Domains\Core\Bootstrap\Controllers;
|
namespace App\Domains\Bootstrap\Controllers;
|
||||||
|
|
||||||
use App\Domains\Core\Bootstrap\Requests\AdminAppBootstrapRequest;
|
use App\Domains\Bootstrap\Requests\AdminAppBootstrapRequest;
|
||||||
use App\Domains\Core\Bootstrap\Resources\AdminAppBootstrapResource;
|
use App\Domains\Bootstrap\Resources\AdminAppBootstrapResource;
|
||||||
use App\Domains\Core\Bootstrap\Services\AdminAppBootstrapService;
|
use App\Domains\Bootstrap\Services\AdminAppBootstrapService;
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
|
|
||||||
class AdminAppBootstrapController extends Controller
|
class AdminAppBootstrapController extends Controller
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Domains\Core\Bootstrap\Controllers;
|
namespace App\Domains\Bootstrap\Controllers;
|
||||||
|
|
||||||
use App\Domains\Core\Bootstrap\Requests\ScannerBootstrapRequest;
|
use App\Domains\Bootstrap\Requests\ScannerBootstrapRequest;
|
||||||
use App\Domains\Core\Bootstrap\Resources\ScannerBootstrapResource;
|
use App\Domains\Bootstrap\Resources\ScannerBootstrapResource;
|
||||||
use App\Domains\Core\Bootstrap\Services\ScannerBootstrapService;
|
use App\Domains\Bootstrap\Services\ScannerBootstrapService;
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
|
|
||||||
class ScannerBootstrapController extends Controller
|
class ScannerBootstrapController extends Controller
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Domains\Core\Bootstrap\Controllers;
|
namespace App\Domains\Bootstrap\Controllers;
|
||||||
|
|
||||||
use App\Domains\Core\Bootstrap\Requests\TenantBootstrapRequest;
|
use App\Domains\Bootstrap\Requests\TenantBootstrapRequest;
|
||||||
use App\Domains\Core\Bootstrap\Services\TenantBootstrapService;
|
use App\Domains\Bootstrap\Services\TenantBootstrapService;
|
||||||
use App\Domains\Core\Tenant\Resources\TenantResource;
|
use App\Domains\Tenant\Resources\TenantResource;
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
|
|
||||||
class TenantBootstrapController extends Controller
|
class TenantBootstrapController extends Controller
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Domains\Core\Bootstrap\Requests;
|
namespace App\Domains\Bootstrap\Requests;
|
||||||
|
|
||||||
class AdminAppBootstrapRequest extends TenantBootstrapRequest {}
|
class AdminAppBootstrapRequest extends TenantBootstrapRequest {}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Domains\Core\Bootstrap\Requests;
|
namespace App\Domains\Bootstrap\Requests;
|
||||||
|
|
||||||
class ScannerBootstrapRequest extends TenantBootstrapRequest {}
|
class ScannerBootstrapRequest extends TenantBootstrapRequest {}
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Domains\Core\Bootstrap\Requests;
|
namespace App\Domains\Bootstrap\Requests;
|
||||||
|
|
||||||
use App\Domains\Core\Tenant\Support\TenantDomainNormalizer;
|
use App\Domains\Tenant\Support\TenantDomainNormalizer;
|
||||||
use Closure;
|
use Closure;
|
||||||
use Illuminate\Foundation\Http\FormRequest;
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
|
|
||||||
@@ -1,23 +1,22 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Domains\Core\Bootstrap\Resources;
|
namespace App\Domains\Bootstrap\Resources;
|
||||||
|
|
||||||
use App\Domains\Core\Tenant\Models\AdminWebsiteType;
|
use App\Domains\Tenant\Models\WebsiteType;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Http\Resources\Json\JsonResource;
|
use Illuminate\Http\Resources\Json\JsonResource;
|
||||||
|
|
||||||
/** @mixin array{website_type: AdminWebsiteType} */
|
/** @mixin array{website_type: WebsiteType} */
|
||||||
class AdminAppBootstrapResource extends JsonResource
|
class AdminAppBootstrapResource extends JsonResource
|
||||||
{
|
{
|
||||||
/** @return array<string, mixed> */
|
/** @return array<string, mixed> */
|
||||||
public function toArray(Request $request): array
|
public function toArray(Request $request): array
|
||||||
{
|
{
|
||||||
/** @var AdminWebsiteType $websiteType */
|
/** @var WebsiteType $websiteType */
|
||||||
$websiteType = $this->resource['website_type'];
|
$websiteType = $this->resource['website_type'];
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'admin_website_type_code' => $websiteType->codigo,
|
'website_type_code' => $websiteType->codigo,
|
||||||
'site_title' => $websiteType->site_title,
|
|
||||||
'primary_color' => $websiteType->primary_color,
|
'primary_color' => $websiteType->primary_color,
|
||||||
'secondary_color' => $websiteType->secondary_color,
|
'secondary_color' => $websiteType->secondary_color,
|
||||||
'danger_color' => $websiteType->danger_color,
|
'danger_color' => $websiteType->danger_color,
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Domains\Core\Bootstrap\Resources;
|
namespace App\Domains\Bootstrap\Resources;
|
||||||
|
|
||||||
class ScannerBootstrapResource extends AdminAppBootstrapResource {}
|
class ScannerBootstrapResource extends AdminAppBootstrapResource {}
|
||||||
@@ -1,16 +1,16 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Domains\Core\Bootstrap\Services;
|
namespace App\Domains\Bootstrap\Services;
|
||||||
|
|
||||||
use App\Domains\Core\Tenant\Models\AdminWebsiteType;
|
use App\Domains\Tenant\Models\WebsiteType;
|
||||||
|
|
||||||
class AdminAppBootstrapService
|
class AdminAppBootstrapService
|
||||||
{
|
{
|
||||||
/** @return array{website_type: AdminWebsiteType} */
|
/** @return array{website_type: WebsiteType} */
|
||||||
public function get(string $domain): array
|
public function get(string $domain): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'website_type' => AdminWebsiteType::query()
|
'website_type' => WebsiteType::query()
|
||||||
->with(['siteLogo', 'footerLogo', 'favicon'])
|
->with(['siteLogo', 'footerLogo', 'favicon'])
|
||||||
->where('dominio', $domain)
|
->where('dominio', $domain)
|
||||||
->firstOrFail(),
|
->firstOrFail(),
|
||||||
@@ -1,16 +1,16 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Domains\Core\Bootstrap\Services;
|
namespace App\Domains\Bootstrap\Services;
|
||||||
|
|
||||||
use App\Domains\Core\Tenant\Models\AdminWebsiteType;
|
use App\Domains\Tenant\Models\WebsiteType;
|
||||||
|
|
||||||
class ScannerBootstrapService
|
class ScannerBootstrapService
|
||||||
{
|
{
|
||||||
/** @return array{website_type: AdminWebsiteType} */
|
/** @return array{website_type: WebsiteType} */
|
||||||
public function get(string $domain): array
|
public function get(string $domain): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'website_type' => AdminWebsiteType::query()
|
'website_type' => WebsiteType::query()
|
||||||
->with(['siteLogo', 'footerLogo', 'favicon'])
|
->with(['siteLogo', 'footerLogo', 'favicon'])
|
||||||
->where('scanner_domain', $domain)
|
->where('scanner_domain', $domain)
|
||||||
->firstOrFail(),
|
->firstOrFail(),
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Domains\Core\Bootstrap\Services;
|
namespace App\Domains\Bootstrap\Services;
|
||||||
|
|
||||||
use App\Domains\Core\Authorization\Enums\RoleCode;
|
use App\Domains\Authorization\Enums\RoleCode;
|
||||||
use App\Domains\Core\Tenant\Models\Tenant;
|
use App\Domains\Tenant\Models\Tenant;
|
||||||
use App\Domains\Core\Tenant\Services\TenantInformationService;
|
use App\Domains\Tenant\Services\TenantInformationService;
|
||||||
use App\Domains\Core\Tenant\Support\TenantDomainNormalizer;
|
use App\Domains\Tenant\Support\TenantDomainNormalizer;
|
||||||
use Illuminate\Database\Eloquent\ModelNotFoundException;
|
use Illuminate\Database\Eloquent\ModelNotFoundException;
|
||||||
|
|
||||||
class TenantBootstrapService
|
class TenantBootstrapService
|
||||||
@@ -32,13 +32,11 @@ class TenantBootstrapService
|
|||||||
return $this->tenantInformationService->load(
|
return $this->tenantInformationService->load(
|
||||||
$tenant,
|
$tenant,
|
||||||
[
|
[
|
||||||
'eventDateChanges',
|
|
||||||
'menues' => fn ($query) => $query->whereHas(
|
'menues' => fn ($query) => $query->whereHas(
|
||||||
'roles',
|
'roles',
|
||||||
fn ($query) => $query->where('codigo', RoleCode::User->value)
|
fn ($query) => $query->where('codigo', RoleCode::User->value)
|
||||||
),
|
),
|
||||||
$tenant->storefront_website_type_code === 'onticket_multi_event'
|
'categories' => fn ($query) => $query->orderBy('nombre'),
|
||||||
? 'eventCategories' : 'categories' => fn ($query) => $query->orderBy('nombre'),
|
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
use App\Domains\Core\Bootstrap\Controllers\AdminAppBootstrapController;
|
use App\Domains\Bootstrap\Controllers\AdminAppBootstrapController;
|
||||||
use Illuminate\Support\Facades\Route;
|
use Illuminate\Support\Facades\Route;
|
||||||
|
|
||||||
Route::get(
|
Route::get(
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
use App\Domains\Core\Bootstrap\Controllers\TenantBootstrapController;
|
use App\Domains\Bootstrap\Controllers\TenantBootstrapController;
|
||||||
use Illuminate\Support\Facades\Route;
|
use Illuminate\Support\Facades\Route;
|
||||||
|
|
||||||
Route::get('tenants/bootstrap', TenantBootstrapController::class);
|
Route::get('tenants/bootstrap', TenantBootstrapController::class);
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
use App\Domains\Core\Bootstrap\Controllers\ScannerBootstrapController;
|
use App\Domains\Bootstrap\Controllers\ScannerBootstrapController;
|
||||||
use Illuminate\Support\Facades\Route;
|
use Illuminate\Support\Facades\Route;
|
||||||
|
|
||||||
Route::get(
|
Route::get(
|
||||||
@@ -1,13 +1,13 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Domains\Commerce\Cart\Controllers;
|
namespace App\Domains\Cart\Controllers;
|
||||||
|
|
||||||
use App\Domains\Commerce\Cart\Models\CartItem;
|
use App\Domains\Cart\Models\CartItem;
|
||||||
use App\Domains\Commerce\Cart\Requests\AddCartItemRequest;
|
use App\Domains\Cart\Requests\AddCartItemRequest;
|
||||||
use App\Domains\Commerce\Cart\Requests\UpdateCartItemQuantityRequest;
|
use App\Domains\Cart\Requests\UpdateCartItemQuantityRequest;
|
||||||
use App\Domains\Commerce\Cart\Resources\CartResource;
|
use App\Domains\Cart\Resources\CartResource;
|
||||||
use App\Domains\Commerce\Cart\Services\CartService;
|
use App\Domains\Cart\Services\CartService;
|
||||||
use App\Domains\Core\Tenant\Models\Tenant;
|
use App\Domains\Tenant\Models\Tenant;
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
@@ -1,17 +1,17 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Domains\Commerce\Cart\Models;
|
namespace App\Domains\Cart\Models;
|
||||||
|
|
||||||
use App\Domains\Core\Auth\Models\User;
|
use App\Domains\Auth\Models\User;
|
||||||
use App\Domains\Commerce\Catalog\Models\CatalogItem;
|
use App\Domains\Catalog\Models\CatalogItem;
|
||||||
use App\Domains\Commerce\Catalog\Models\Inventory;
|
use App\Domains\Catalog\Models\Inventory;
|
||||||
use App\Domains\Commerce\Catalog\Models\StockReservation;
|
use App\Domains\Catalog\Models\StockReservation;
|
||||||
use App\Domains\Commerce\Catalog\Models\Variant;
|
use App\Domains\Catalog\Models\Variant;
|
||||||
use App\Domains\Commerce\Catalog\Services\CatalogInventoryService;
|
use App\Domains\Catalog\Services\CatalogInventoryService;
|
||||||
use App\Domains\Commerce\Catalog\Services\StockReservationService;
|
use App\Domains\Catalog\Services\StockReservationService;
|
||||||
use App\Domains\Commerce\Purchase\Models\Purchase;
|
use App\Domains\Purchase\Models\Purchase;
|
||||||
use App\Domains\Commerce\Purchase\Services\UserPurchaseLimitService;
|
use App\Domains\Purchase\Services\UserPurchaseLimitService;
|
||||||
use App\Domains\Core\Tenant\Models\Tenant;
|
use App\Domains\Tenant\Models\Tenant;
|
||||||
use Illuminate\Database\Eloquent\Attributes\Fillable;
|
use Illuminate\Database\Eloquent\Attributes\Fillable;
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
@@ -375,7 +375,7 @@ class Cart extends Model
|
|||||||
): CatalogItem|Variant {
|
): CatalogItem|Variant {
|
||||||
$catalogItemQuery = CatalogItem::query()
|
$catalogItemQuery = CatalogItem::query()
|
||||||
->whereKey($catalogItemId)
|
->whereKey($catalogItemId)
|
||||||
->forTenantCatalog($this->tenant()->firstOrFail());
|
->where('tenant_code', $this->tenant_codigo);
|
||||||
|
|
||||||
if ($lockForUpdate) {
|
if ($lockForUpdate) {
|
||||||
$catalogItemQuery->lockForUpdate();
|
$catalogItemQuery->lockForUpdate();
|
||||||
@@ -400,17 +400,6 @@ class Cart extends Model
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($catalogItem->bundleComponents()
|
|
||||||
->whereNotNull('component_variant_id')
|
|
||||||
->whereHas('variant', fn ($query) => $query
|
|
||||||
->whereNotNull('sales_disabled_at')
|
|
||||||
->orWhereNotNull('replaced_by_variant_id'))
|
|
||||||
->exists()) {
|
|
||||||
throw ValidationException::withMessages([
|
|
||||||
'catalog_item_id' => [__('api.cart.bundle_component_unavailable')],
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $catalogItem;
|
return $catalogItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -441,12 +430,6 @@ class Cart extends Model
|
|||||||
throw new NotFoundHttpException('Variant not found for catalog item.');
|
throw new NotFoundHttpException('Variant not found for catalog item.');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! $variant->isSellable()) {
|
|
||||||
throw ValidationException::withMessages([
|
|
||||||
'variant_id' => [__('api.cart.variant_unavailable')],
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
$inventory = $this->resolveInventory($variant->inventory_id, $lockForUpdate);
|
$inventory = $this->resolveInventory($variant->inventory_id, $lockForUpdate);
|
||||||
$variant->setRelation('catalogItem', $catalogItem);
|
$variant->setRelation('catalogItem', $catalogItem);
|
||||||
$variant->setRelation('inventory', $inventory);
|
$variant->setRelation('inventory', $inventory);
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Domains\Commerce\Cart\Models;
|
namespace App\Domains\Cart\Models;
|
||||||
|
|
||||||
use App\Domains\Commerce\Catalog\Models\CatalogItem;
|
use App\Domains\Catalog\Models\CatalogItem;
|
||||||
use App\Domains\Commerce\Catalog\Models\Variant;
|
use App\Domains\Catalog\Models\Variant;
|
||||||
use Illuminate\Database\Eloquent\Attributes\Fillable;
|
use Illuminate\Database\Eloquent\Attributes\Fillable;
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Domains\Commerce\Cart\Requests;
|
namespace App\Domains\Cart\Requests;
|
||||||
|
|
||||||
use Illuminate\Foundation\Http\FormRequest;
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
use Illuminate\Validation\Rule;
|
use Illuminate\Validation\Rule;
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Domains\Commerce\Cart\Requests;
|
namespace App\Domains\Cart\Requests;
|
||||||
|
|
||||||
use Illuminate\Foundation\Http\FormRequest;
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
|
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Domains\Commerce\Cart\Resources;
|
namespace App\Domains\Cart\Resources;
|
||||||
|
|
||||||
use App\Domains\Commerce\Cart\Models\CartItem;
|
use App\Domains\Cart\Models\CartItem;
|
||||||
use App\Domains\Commerce\Catalog\Enums\InventoryPolicy;
|
use App\Domains\Catalog\Enums\InventoryPolicy;
|
||||||
use App\Domains\Commerce\Catalog\Models\Variant;
|
use App\Domains\Catalog\Models\Variant;
|
||||||
use App\Domains\Core\Tenant\Models\Tenant;
|
use App\Domains\Tenant\Models\Tenant;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Http\Resources\Json\JsonResource;
|
use Illuminate\Http\Resources\Json\JsonResource;
|
||||||
|
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Domains\Commerce\Cart\Resources;
|
namespace App\Domains\Cart\Resources;
|
||||||
|
|
||||||
use App\Domains\Commerce\Cart\Models\Cart;
|
use App\Domains\Cart\Models\Cart;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Http\Resources\Json\JsonResource;
|
use Illuminate\Http\Resources\Json\JsonResource;
|
||||||
|
|
||||||
@@ -1,12 +1,12 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Domains\Commerce\Cart\Services;
|
namespace App\Domains\Cart\Services;
|
||||||
|
|
||||||
use App\Domains\Core\Auth\Models\User;
|
use App\Domains\Auth\Models\User;
|
||||||
use App\Domains\Commerce\Cart\Models\Cart;
|
use App\Domains\Cart\Models\Cart;
|
||||||
use App\Domains\Commerce\Catalog\Exceptions\StockReservationExpiredException;
|
use App\Domains\Catalog\Exceptions\StockReservationExpiredException;
|
||||||
use App\Domains\Commerce\Catalog\Services\ExpireStockReservationsService;
|
use App\Domains\Catalog\Services\ExpireStockReservationsService;
|
||||||
use App\Domains\Core\Tenant\Models\Tenant;
|
use App\Domains\Tenant\Models\Tenant;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Domains\Commerce\Cart\Services;
|
namespace App\Domains\Cart\Services;
|
||||||
|
|
||||||
use App\Domains\Core\Auth\Models\User;
|
use App\Domains\Auth\Models\User;
|
||||||
use App\Domains\Commerce\Cart\Models\Cart;
|
use App\Domains\Cart\Models\Cart;
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
|
|
||||||
class GuestCartMergeService
|
class GuestCartMergeService
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
use App\Domains\Commerce\Cart\Controllers\CartController;
|
use App\Domains\Cart\Controllers\CartController;
|
||||||
use Illuminate\Support\Facades\Route;
|
use Illuminate\Support\Facades\Route;
|
||||||
|
|
||||||
Route::prefix('tenants/{tenant:codigo}')
|
Route::prefix('tenants/{tenant:codigo}')
|
||||||
@@ -1,25 +1,27 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Domains\Commerce\Catalog\Controllers;
|
namespace App\Domains\Catalog\Controllers;
|
||||||
|
|
||||||
use App\Domains\Commerce\Cart\Services\CartService;
|
use App\Domains\Cart\Services\CartService;
|
||||||
use App\Domains\Commerce\Catalog\Models\CatalogItem;
|
use App\Domains\Catalog\Models\CatalogItem;
|
||||||
use App\Domains\Commerce\Catalog\Models\Category;
|
use App\Domains\Catalog\Models\Category;
|
||||||
use App\Domains\Commerce\Catalog\Models\FeaturedGroup;
|
use App\Domains\Catalog\Models\FeaturedGroup;
|
||||||
use App\Domains\Commerce\Catalog\Requests\CatalogItemDetailRequest;
|
use App\Domains\Catalog\Requests\CatalogItemDetailRequest;
|
||||||
use App\Domains\Commerce\Catalog\Requests\CatalogVariantOptionsRequest;
|
use App\Domains\Catalog\Requests\CatalogVariantOptionsRequest;
|
||||||
use App\Domains\Commerce\Catalog\Requests\CategoryPageRequest;
|
use App\Domains\Catalog\Requests\CategoryPageRequest;
|
||||||
use App\Domains\Commerce\Catalog\Requests\FeaturedGroupPageRequest;
|
use App\Domains\Catalog\Requests\FeaturedGroupPageRequest;
|
||||||
use App\Domains\Commerce\Catalog\Requests\SearchCatalogItemsRequest;
|
use App\Domains\Catalog\Requests\SearchCatalogItemsRequest;
|
||||||
use App\Domains\Commerce\Catalog\Resources\CatalogFeaturedGroupResource;
|
use App\Domains\Catalog\Requests\StoreCatalogItemRequest;
|
||||||
use App\Domains\Commerce\Catalog\Resources\CatalogItemDetailResource;
|
use App\Domains\Catalog\Resources\CatalogFeaturedGroupResource;
|
||||||
use App\Domains\Commerce\Catalog\Resources\CatalogSearchItemResource;
|
use App\Domains\Catalog\Resources\CatalogItemDetailResource;
|
||||||
use App\Domains\Commerce\Catalog\Resources\CatalogVariantOptionsResource;
|
use App\Domains\Catalog\Resources\CatalogItemResource;
|
||||||
use App\Domains\Commerce\Catalog\Services\CatalogItemAllowanceService;
|
use App\Domains\Catalog\Resources\CatalogSearchItemResource;
|
||||||
use App\Domains\Commerce\Catalog\Services\CatalogService;
|
use App\Domains\Catalog\Resources\CatalogVariantOptionsResource;
|
||||||
use App\Domains\Commerce\Catalog\Services\FeaturedGroupService;
|
use App\Domains\Catalog\Services\CatalogItemAllowanceService;
|
||||||
use App\Domains\Commerce\Catalog\Services\VariantSelectionService;
|
use App\Domains\Catalog\Services\CatalogService;
|
||||||
use App\Domains\Core\Tenant\Models\Tenant;
|
use App\Domains\Catalog\Services\FeaturedGroupService;
|
||||||
|
use App\Domains\Catalog\Services\VariantSelectionService;
|
||||||
|
use App\Domains\Tenant\Models\Tenant;
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
@@ -38,7 +40,7 @@ class CatalogController extends Controller
|
|||||||
return response()->json($featuredGroups->map(
|
return response()->json($featuredGroups->map(
|
||||||
fn (FeaturedGroup $featuredGroup): array => (new CatalogFeaturedGroupResource(
|
fn (FeaturedGroup $featuredGroup): array => (new CatalogFeaturedGroupResource(
|
||||||
$featuredGroup,
|
$featuredGroup,
|
||||||
$featuredGroupService->itemsResponse($featuredGroup, $tenant, 1, $this->userId($request)),
|
$featuredGroupService->itemsResponse($featuredGroup, 1, $this->userId($request)),
|
||||||
))->resolve()
|
))->resolve()
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@@ -100,7 +102,6 @@ class CatalogController extends Controller
|
|||||||
|
|
||||||
return response()->json($featuredGroupService->itemsResponse(
|
return response()->json($featuredGroupService->itemsResponse(
|
||||||
$featuredGroup,
|
$featuredGroup,
|
||||||
$tenant,
|
|
||||||
$page,
|
$page,
|
||||||
$this->userId($request),
|
$this->userId($request),
|
||||||
));
|
));
|
||||||
@@ -113,8 +114,7 @@ class CatalogController extends Controller
|
|||||||
CatalogService $catalogService,
|
CatalogService $catalogService,
|
||||||
CatalogItemAllowanceService $allowances,
|
CatalogItemAllowanceService $allowances,
|
||||||
): CatalogItemDetailResource {
|
): CatalogItemDetailResource {
|
||||||
abort_unless($catalogItem->tenant_code === $tenant->codigo
|
abort_unless($catalogItem->tenant_code === $tenant->codigo, 404);
|
||||||
&& ($tenant->active_event_id === null || $catalogItem->event_id === $tenant->active_event_id), 404);
|
|
||||||
|
|
||||||
$variantId = $request->validated('variant_id');
|
$variantId = $request->validated('variant_id');
|
||||||
|
|
||||||
@@ -134,8 +134,7 @@ class CatalogController extends Controller
|
|||||||
VariantSelectionService $variantSelectionService,
|
VariantSelectionService $variantSelectionService,
|
||||||
CartService $cartService,
|
CartService $cartService,
|
||||||
): CatalogVariantOptionsResource {
|
): CatalogVariantOptionsResource {
|
||||||
abort_unless($catalogItem->tenant_code === $tenant->codigo
|
abort_unless($catalogItem->tenant_code === $tenant->codigo, 404);
|
||||||
&& ($tenant->active_event_id === null || $catalogItem->event_id === $tenant->active_event_id), 404);
|
|
||||||
|
|
||||||
$includedVariantId = null;
|
$includedVariantId = null;
|
||||||
$cartItemId = $request->validated('cart_item_id');
|
$cartItemId = $request->validated('cart_item_id');
|
||||||
@@ -164,6 +163,21 @@ class CatalogController extends Controller
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function store(
|
||||||
|
StoreCatalogItemRequest $request,
|
||||||
|
Tenant $tenant,
|
||||||
|
CatalogService $catalogService,
|
||||||
|
): JsonResponse {
|
||||||
|
$catalogItem = $catalogService->create([
|
||||||
|
...$request->validated(),
|
||||||
|
'tenant_code' => $tenant->codigo,
|
||||||
|
]);
|
||||||
|
|
||||||
|
return CatalogItemResource::make($catalogItem)
|
||||||
|
->response()
|
||||||
|
->setStatusCode(201);
|
||||||
|
}
|
||||||
|
|
||||||
private function userId(Request $request): ?int
|
private function userId(Request $request): ?int
|
||||||
{
|
{
|
||||||
$userId = $request->user()?->getAuthIdentifier() ?? Auth::guard('sanctum')->id();
|
$userId = $request->user()?->getAuthIdentifier() ?? Auth::guard('sanctum')->id();
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Domains\Commerce\Catalog\Enums;
|
namespace App\Domains\Catalog\Enums;
|
||||||
|
|
||||||
enum CatalogItemType: string
|
enum CatalogItemType: string
|
||||||
{
|
{
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Domains\Commerce\Catalog\Enums;
|
namespace App\Domains\Catalog\Enums;
|
||||||
|
|
||||||
enum FeaturedGroupSource: string
|
enum FeaturedGroupSource: string
|
||||||
{
|
{
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Domains\Commerce\Catalog\Enums;
|
namespace App\Domains\Catalog\Enums;
|
||||||
|
|
||||||
enum GroupLayout: string
|
enum GroupLayout: string
|
||||||
{
|
{
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Domains\Commerce\Catalog\Enums;
|
namespace App\Domains\Catalog\Enums;
|
||||||
|
|
||||||
enum InventoryPolicy: string
|
enum InventoryPolicy: string
|
||||||
{
|
{
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Domains\Commerce\Catalog\Enums;
|
namespace App\Domains\Catalog\Enums;
|
||||||
|
|
||||||
enum InventorySubject: string
|
enum InventorySubject: string
|
||||||
{
|
{
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Domains\Commerce\Catalog\Enums;
|
namespace App\Domains\Catalog\Enums;
|
||||||
|
|
||||||
enum ProductLayout: string
|
enum ProductLayout: string
|
||||||
{
|
{
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Domains\Commerce\Catalog\Exceptions;
|
namespace App\Domains\Catalog\Exceptions;
|
||||||
|
|
||||||
use RuntimeException;
|
use RuntimeException;
|
||||||
|
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Domains\Commerce\Catalog\Models;
|
namespace App\Domains\Catalog\Models;
|
||||||
|
|
||||||
use App\Domains\Ticketing\Event\Models\EventDate;
|
use App\Domains\Event\Models\EventDate;
|
||||||
use App\Shared\Enums\FieldType;
|
use App\Domains\Shared\Enums\FieldType;
|
||||||
use App\Domains\Core\Tenant\Models\Tenant;
|
use App\Domains\Tenant\Models\Tenant;
|
||||||
use Illuminate\Database\Eloquent\Attributes\Fillable;
|
use Illuminate\Database\Eloquent\Attributes\Fillable;
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
@@ -59,8 +59,6 @@ class Attribute extends Model
|
|||||||
public function eventDates(): HasMany
|
public function eventDates(): HasMany
|
||||||
{
|
{
|
||||||
return $this->hasMany(EventDate::class, 'tenant_code', 'tenant_codigo')
|
return $this->hasMany(EventDate::class, 'tenant_code', 'tenant_codigo')
|
||||||
->whereNull('rescheduled_to_event_date_id')
|
|
||||||
->whereNull('suspended_at')
|
|
||||||
->orderBy('date')
|
->orderBy('date')
|
||||||
->orderBy('time_start');
|
->orderBy('time_start');
|
||||||
}
|
}
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Domains\Commerce\Catalog\Models;
|
namespace App\Domains\Catalog\Models;
|
||||||
|
|
||||||
use App\Domains\Ticketing\Ticket\Models\ValidityTime;
|
use App\Domains\Ticket\Models\ValidityTime;
|
||||||
use Illuminate\Database\Eloquent\Attributes\Fillable;
|
use Illuminate\Database\Eloquent\Attributes\Fillable;
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Domains\Commerce\Catalog\Models;
|
namespace App\Domains\Catalog\Models;
|
||||||
|
|
||||||
use App\Domains\Core\Tenant\Models\Tenant;
|
use App\Domains\Tenant\Models\Tenant;
|
||||||
use Illuminate\Database\Eloquent\Attributes\Fillable;
|
use Illuminate\Database\Eloquent\Attributes\Fillable;
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Domains\Commerce\Catalog\Models;
|
namespace App\Domains\Catalog\Models;
|
||||||
|
|
||||||
use Illuminate\Database\Eloquent\Attributes\Fillable;
|
use Illuminate\Database\Eloquent\Attributes\Fillable;
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
@@ -1,15 +1,14 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Domains\Commerce\Catalog\Models;
|
namespace App\Domains\Catalog\Models;
|
||||||
|
|
||||||
use App\Shared\Attachable\Models\Attachment;
|
use App\Domains\Attachable\Models\Attachment;
|
||||||
use App\Domains\Commerce\Catalog\Enums\CatalogItemType;
|
use App\Domains\Catalog\Enums\CatalogItemType;
|
||||||
use App\Domains\Commerce\Catalog\Enums\InventoryPolicy;
|
use App\Domains\Catalog\Enums\InventoryPolicy;
|
||||||
use App\Domains\Commerce\Catalog\Enums\InventorySubject;
|
use App\Domains\Catalog\Enums\InventorySubject;
|
||||||
use App\Domains\Commerce\Catalog\Services\CatalogInventoryService;
|
use App\Domains\Catalog\Services\CatalogInventoryService;
|
||||||
use App\Domains\Core\Tenant\Models\Tenant;
|
use App\Domains\Tenant\Models\Tenant;
|
||||||
use App\Domains\Ticketing\Event\Models\Event;
|
use App\Domains\Ticket\Models\Ticket;
|
||||||
use App\Domains\Ticketing\Ticket\Models\Ticket;
|
|
||||||
use Illuminate\Database\Eloquent\Attributes\Fillable;
|
use Illuminate\Database\Eloquent\Attributes\Fillable;
|
||||||
use Illuminate\Database\Eloquent\Builder;
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
@@ -31,7 +30,6 @@ use Illuminate\Support\Collection;
|
|||||||
'group_order',
|
'group_order',
|
||||||
'descripcion',
|
'descripcion',
|
||||||
'precio',
|
'precio',
|
||||||
'sales_end_at',
|
|
||||||
'inventory_policy',
|
'inventory_policy',
|
||||||
'inventory_subject',
|
'inventory_subject',
|
||||||
'max_units_per_user',
|
'max_units_per_user',
|
||||||
@@ -53,30 +51,15 @@ class CatalogItem extends Model
|
|||||||
'group_order' => 0,
|
'group_order' => 0,
|
||||||
];
|
];
|
||||||
|
|
||||||
protected static function booted(): void
|
|
||||||
{
|
|
||||||
static::creating(function (CatalogItem $item): void {
|
|
||||||
if ($item->event_id !== null || $item->tenant_code === null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$item->event_id = Tenant::query()
|
|
||||||
->where('codigo', $item->tenant_code)
|
|
||||||
->value('active_event_id');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function casts(): array
|
protected function casts(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'event_id' => 'integer',
|
|
||||||
'category_id' => 'integer',
|
'category_id' => 'integer',
|
||||||
'brand_id' => 'integer',
|
'brand_id' => 'integer',
|
||||||
'inventory_id' => 'integer',
|
'inventory_id' => 'integer',
|
||||||
'type' => CatalogItemType::class,
|
'type' => CatalogItemType::class,
|
||||||
'group_order' => 'integer',
|
'group_order' => 'integer',
|
||||||
'precio' => 'decimal:2',
|
'precio' => 'decimal:2',
|
||||||
'sales_end_at' => 'datetime',
|
|
||||||
'inventory_policy' => InventoryPolicy::class,
|
'inventory_policy' => InventoryPolicy::class,
|
||||||
'inventory_subject' => InventorySubject::class,
|
'inventory_subject' => InventorySubject::class,
|
||||||
'max_units_per_user' => 'integer',
|
'max_units_per_user' => 'integer',
|
||||||
@@ -90,21 +73,6 @@ class CatalogItem extends Model
|
|||||||
return $this->belongsTo(Tenant::class, 'tenant_code', 'codigo');
|
return $this->belongsTo(Tenant::class, 'tenant_code', 'codigo');
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @return BelongsTo<Event, $this> */
|
|
||||||
public function event(): BelongsTo
|
|
||||||
{
|
|
||||||
return $this->belongsTo(Event::class);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @param Builder<CatalogItem> $query */
|
|
||||||
public function scopeForTenantCatalog(Builder $query, Tenant $tenant): Builder
|
|
||||||
{
|
|
||||||
return $query
|
|
||||||
->where('catalog_items.tenant_code', $tenant->codigo)
|
|
||||||
->when($tenant->active_event_id !== null, fn (Builder $query): Builder => $query
|
|
||||||
->where('catalog_items.event_id', $tenant->active_event_id));
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @return BelongsTo<Category, $this> */
|
/** @return BelongsTo<Category, $this> */
|
||||||
public function category(): BelongsTo
|
public function category(): BelongsTo
|
||||||
{
|
{
|
||||||
@@ -193,10 +161,6 @@ class CatalogItem extends Model
|
|||||||
|
|
||||||
public function isAvailable(): bool
|
public function isAvailable(): bool
|
||||||
{
|
{
|
||||||
if (! $this->isSaleOpen()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($this->type === CatalogItemType::Bundle) {
|
if ($this->type === CatalogItemType::Bundle) {
|
||||||
$availableStock = $this->availableStock();
|
$availableStock = $this->availableStock();
|
||||||
|
|
||||||
@@ -214,31 +178,12 @@ class CatalogItem extends Model
|
|||||||
public function scopeWhereAvailable(Builder $query): Builder
|
public function scopeWhereAvailable(Builder $query): Builder
|
||||||
{
|
{
|
||||||
return $query->where(function (Builder $query): void {
|
return $query->where(function (Builder $query): void {
|
||||||
$query->whereNull('catalog_items.sales_end_at')
|
|
||||||
->orWhere('catalog_items.sales_end_at', '>', now());
|
|
||||||
})->where(function (Builder $query): void {
|
|
||||||
$query
|
$query
|
||||||
->where(function (Builder $unlimitedQuery): void {
|
->where('catalog_items.inventory_policy', InventoryPolicy::Unlimited->value)
|
||||||
$unlimitedQuery
|
|
||||||
->where('catalog_items.inventory_policy', InventoryPolicy::Unlimited->value)
|
|
||||||
->where(function (Builder $selectionQuery): void {
|
|
||||||
$selectionQuery
|
|
||||||
->whereDoesntHave('variants')
|
|
||||||
->orWhereHas('variants', fn (Builder $variantQuery): Builder => $variantQuery
|
|
||||||
->whereNull('sales_disabled_at')
|
|
||||||
->whereNull('replaced_by_variant_id'));
|
|
||||||
});
|
|
||||||
})
|
|
||||||
->orWhereHas(
|
->orWhereHas(
|
||||||
'variants',
|
'variants.inventory',
|
||||||
fn (Builder $variantQuery): Builder => $variantQuery
|
fn (Builder $inventoryQuery): Builder => $inventoryQuery
|
||||||
->whereNull('sales_disabled_at')
|
->whereColumn('inventories.real_stock', '>', 'inventories.reserved_stock')
|
||||||
->whereNull('replaced_by_variant_id')
|
|
||||||
->whereHas(
|
|
||||||
'inventory',
|
|
||||||
fn (Builder $inventoryQuery): Builder => $inventoryQuery
|
|
||||||
->whereColumn('inventories.real_stock', '>', 'inventories.reserved_stock')
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
->orWhere(function (Builder $directItemQuery): void {
|
->orWhere(function (Builder $directItemQuery): void {
|
||||||
$directItemQuery
|
$directItemQuery
|
||||||
@@ -256,22 +201,13 @@ class CatalogItem extends Model
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public function isSaleOpen(): bool
|
|
||||||
{
|
|
||||||
return $this->sales_end_at === null || now()->lt($this->sales_end_at);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @return Collection<int, Variant> */
|
/** @return Collection<int, Variant> */
|
||||||
public function visibleVariants(?int $includedVariantId = null): Collection
|
public function visibleVariants(?int $includedVariantId = null): Collection
|
||||||
{
|
{
|
||||||
return $this->variants
|
return $this->variants
|
||||||
->each(fn (Variant $variant) => $variant->setRelation('catalogItem', $this))
|
->filter(fn (Variant $variant): bool => ($includedVariantId !== null && $variant->id === $includedVariantId)
|
||||||
->filter(fn (Variant $variant): bool => $variant->hasOnlyActiveEventDates()
|
|| $this->inventory_policy === InventoryPolicy::Unlimited
|
||||||
&& (($includedVariantId !== null && $variant->id === $includedVariantId)
|
|| ($variant->inventory?->availableStock() ?? 0) > 0)
|
||||||
|| ($variant->isSellable() && (
|
|
||||||
$this->inventory_policy === InventoryPolicy::Unlimited
|
|
||||||
|| ($variant->inventory?->availableStock() ?? 0) > 0
|
|
||||||
))))
|
|
||||||
->values();
|
->values();
|
||||||
}
|
}
|
||||||
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user