diff --git a/app/Domains/Catalog/Controllers/BrandController.php b/app/Domains/Catalog/Controllers/BrandController.php new file mode 100644 index 0000000..2fff76a --- /dev/null +++ b/app/Domains/Catalog/Controllers/BrandController.php @@ -0,0 +1,55 @@ +orderByDesc('id')->get())->response(); + } + + public function store(StoreBrandRequest $request): JsonResponse + { + $validated = $request->validated(); + $props = $validated['props'] ?? []; + unset($validated['props']); + + $brand = Brand::create($validated); + $brand->syncPropValues($props); + + return BrandResource::make($brand)->response()->setStatusCode(201); + } + + public function show(Brand $marca): BrandResource + { + return BrandResource::make($marca); + } + + public function update(UpdateBrandRequest $request, Brand $marca): BrandResource + { + $validated = $request->validated(); + $props = $validated['props'] ?? []; + unset($validated['props']); + + $marca->update($validated); + $marca->syncPropValues($props); + + return BrandResource::make($marca); + } + + public function destroy(Brand $marca): Response + { + $marca->delete(); + + return response()->noContent(); + } +} diff --git a/app/Domains/Catalog/Controllers/CategoryController.php b/app/Domains/Catalog/Controllers/CategoryController.php new file mode 100644 index 0000000..746fce7 --- /dev/null +++ b/app/Domains/Catalog/Controllers/CategoryController.php @@ -0,0 +1,59 @@ +with(['parent', 'subCategories','tenant'])->orderByDesc('id')->get() + )->response(); + } + + public function store(StoreCategoryRequest $request): JsonResponse + { + $validated = $request->validated(); + $props = $validated['props'] ?? []; + unset($validated['props']); + + $category = Category::create($validated); + $category->syncPropValues($props); + + return CategoryResource::make($category->load(['parent', 'subCategories', 'tenant'])) + ->response() + ->setStatusCode(201); + } + + public function show(Category $categoria): CategoryResource + { + return CategoryResource::make($categoria->load(['parent', 'subCategories', 'tenant'])); + } + + public function update(UpdateCategoryRequest $request, Category $categoria): CategoryResource + { + $validated = $request->validated(); + $props = $validated['props'] ?? []; + unset($validated['props']); + + $categoria->update($validated); + $categoria->syncPropValues($props); + + return CategoryResource::make($categoria->load(['parent', 'subCategories', 'tenant'])); + } + + public function destroy(Category $categoria): Response + { + $categoria->delete(); + + return response()->noContent(); + } +} diff --git a/app/Domains/Catalog/Models/Brand.php b/app/Domains/Catalog/Models/Brand.php index 0c9a3f1..ffb4688 100644 --- a/app/Domains/Catalog/Models/Brand.php +++ b/app/Domains/Catalog/Models/Brand.php @@ -3,11 +3,29 @@ namespace App\Domains\Catalog\Models; use App\Domains\Prop\Concerns\Propable; +use App\Domains\Tenant\Models\Tenant; +use Illuminate\Database\Eloquent\Attributes\Fillable; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; +use Illuminate\Database\Eloquent\Relations\BelongsTo; +#[Fillable([ + 'tenant_codigo', + 'nombre', + 'descripcion', +])] class Brand extends Model { use HasFactory; use Propable; + + protected $table = 'brands'; + + /** + * @return BelongsTo + */ + public function tenant(): BelongsTo + { + return $this->belongsTo(Tenant::class, 'tenant_codigo', 'codigo'); + } } diff --git a/app/Domains/Catalog/Models/Category.php b/app/Domains/Catalog/Models/Category.php index f7eb64c..1803f6c 100644 --- a/app/Domains/Catalog/Models/Category.php +++ b/app/Domains/Catalog/Models/Category.php @@ -3,11 +3,58 @@ namespace App\Domains\Catalog\Models; use App\Domains\Prop\Concerns\Propable; +use App\Domains\Tenant\Models\Tenant; +use Illuminate\Database\Eloquent\Attributes\Fillable; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; +use Illuminate\Database\Eloquent\Relations\BelongsTo; +use Illuminate\Database\Eloquent\Relations\HasMany; +#[Fillable([ + 'tenant_code', + 'categoria_id', + 'nombre', +])] class Category extends Model { use HasFactory; use Propable; + + protected $table = 'categorias'; + + protected function casts(): array + { + return [ + 'categoria_id' => 'integer', + ]; + } + + public function isGlobal(): bool + { + return $this->tenant_code === null; + } + + /** + * @return BelongsTo + */ + public function tenant(): BelongsTo + { + return $this->belongsTo(Tenant::class, 'tenant_code', 'codigo'); + } + + /** + * @return BelongsTo + */ + public function parent(): BelongsTo + { + return $this->belongsTo(self::class, 'categoria_id'); + } + + /** + * @return HasMany + */ + public function subCategories(): HasMany + { + return $this->hasMany(self::class, 'categoria_id'); + } } diff --git a/app/Domains/Catalog/Requests/StoreBrandRequest.php b/app/Domains/Catalog/Requests/StoreBrandRequest.php new file mode 100644 index 0000000..e3beb68 --- /dev/null +++ b/app/Domains/Catalog/Requests/StoreBrandRequest.php @@ -0,0 +1,27 @@ + + */ + public function rules(): array + { + return [ + 'tenant_codigo' => ['required', 'string', 'exists:tenants,codigo'], + 'nombre' => ['required', 'string', 'max:255'], + 'descripcion' => ['nullable', 'string'], + ...PropRules::sync(), + ]; + } +} diff --git a/app/Domains/Catalog/Requests/StoreCategoryRequest.php b/app/Domains/Catalog/Requests/StoreCategoryRequest.php new file mode 100644 index 0000000..5c6cd7e --- /dev/null +++ b/app/Domains/Catalog/Requests/StoreCategoryRequest.php @@ -0,0 +1,27 @@ + + */ + public function rules(): array + { + return [ + 'tenant_code' => ['required', 'string', 'exists:tenants,codigo'], + 'categoria_id' => ['nullable', 'integer', 'exists:categorias,id'], + 'nombre' => ['required', 'string', 'max:255'], + ...PropRules::sync(), + ]; + } +} diff --git a/app/Domains/Catalog/Requests/UpdateBrandRequest.php b/app/Domains/Catalog/Requests/UpdateBrandRequest.php new file mode 100644 index 0000000..eaa7b6d --- /dev/null +++ b/app/Domains/Catalog/Requests/UpdateBrandRequest.php @@ -0,0 +1,27 @@ + + */ + public function rules(): array + { + return [ + 'tenant_codigo' => ['required', 'string', 'exists:tenants,codigo'], + 'nombre' => ['required', 'string', 'max:255'], + 'descripcion' => ['nullable', 'string'], + ...PropRules::sync(), + ]; + } +} diff --git a/app/Domains/Catalog/Requests/UpdateCategoryRequest.php b/app/Domains/Catalog/Requests/UpdateCategoryRequest.php new file mode 100644 index 0000000..e485a3e --- /dev/null +++ b/app/Domains/Catalog/Requests/UpdateCategoryRequest.php @@ -0,0 +1,37 @@ + + */ + public function rules(): array + { + /** @var Category|null $category */ + $category = $this->route('categoria'); + + return [ + 'tenant_code' => ['required', 'string', 'exists:tenants,codigo'], + 'categoria_id' => [ + 'nullable', + 'integer', + 'exists:categorias,id', + Rule::notIn([$category?->id]), + ], + 'nombre' => ['required', 'string', 'max:255'], + ...PropRules::sync(), + ]; + } +} diff --git a/app/Domains/Catalog/Resources/BrandResource.php b/app/Domains/Catalog/Resources/BrandResource.php new file mode 100644 index 0000000..4bf0a04 --- /dev/null +++ b/app/Domains/Catalog/Resources/BrandResource.php @@ -0,0 +1,25 @@ + + */ + public function toArray(Request $request): array + { + return [ + 'id' => $this->id, + 'tenant_codigo' => $this->tenant_codigo, + 'nombre' => $this->nombre, + 'descripcion' => $this->descripcion, + ]; + } +} diff --git a/app/Domains/Catalog/Resources/CategoryResource.php b/app/Domains/Catalog/Resources/CategoryResource.php new file mode 100644 index 0000000..609b0b4 --- /dev/null +++ b/app/Domains/Catalog/Resources/CategoryResource.php @@ -0,0 +1,32 @@ + + */ + public function toArray(Request $request): array + { + return [ + 'id' => $this->id, + 'tenant_code' => $this->tenant_code, + 'is_global' => $this->resource->isGlobal(), + 'tenant' => $this->resource->isGlobal() + ? null + : TenantResource::make($this->whenLoaded('tenant')), + 'categoria_id' => $this->categoria_id, + 'nombre' => $this->nombre, + 'parent' => self::make($this->whenLoaded('parent')), + 'sub_categories' => self::collection($this->whenLoaded('subCategories')), + ]; + } +} diff --git a/app/Domains/Catalog/routes/api.php b/app/Domains/Catalog/routes/api.php index afa26c2..34a85e1 100644 --- a/app/Domains/Catalog/routes/api.php +++ b/app/Domains/Catalog/routes/api.php @@ -1,6 +1,10 @@ parameters(['marcas' => 'marca']); +Route::apiResource('categorias', CategoryController::class)->parameters(['categorias' => 'categoria']); Route::apiResource('productos', ProductController::class);