From 5c81d6997a6bae5827a30b5f965c0549b652e401 Mon Sep 17 00:00:00 2001 From: ncoronel Date: Mon, 22 Jun 2026 12:07:46 -0300 Subject: [PATCH] Add Prop and ModelPropValue models with relationships; create migration files for props, prop options, prop data types, and model prop values --- app/Domains/Product/Models/Brand.php | 22 +++++++- app/Domains/Product/Models/Category.php | 22 +++++++- app/Domains/Product/Models/Product.php | 19 +++++++ app/Domains/Prop/Models/ModelPropValue.php | 38 +++++++++++++ app/Domains/Prop/Models/Prop.php | 56 +++++++++++++++++++ app/Domains/Prop/Models/PropDataType.php | 25 +++++++++ app/Domains/Prop/Models/PropOption.php | 27 +++++++++ app/Domains/Tenant/Models/Tenant.php | 19 +++++++ ...2_120000_create_props_data_types_table.php | 29 ++++++++++ .../2026_06_22_120100_create_props_table.php | 36 ++++++++++++ ...06_22_120200_create_prop_options_table.php | 33 +++++++++++ ..._120300_create_model_prop_values_table.php | 40 +++++++++++++ 12 files changed, 364 insertions(+), 2 deletions(-) create mode 100644 app/Domains/Prop/Models/ModelPropValue.php create mode 100644 app/Domains/Prop/Models/Prop.php create mode 100644 app/Domains/Prop/Models/PropDataType.php create mode 100644 app/Domains/Prop/Models/PropOption.php create mode 100644 database/migrations/2026_06_22_120000_create_props_data_types_table.php create mode 100644 database/migrations/2026_06_22_120100_create_props_table.php create mode 100644 database/migrations/2026_06_22_120200_create_prop_options_table.php create mode 100644 database/migrations/2026_06_22_120300_create_model_prop_values_table.php diff --git a/app/Domains/Product/Models/Brand.php b/app/Domains/Product/Models/Brand.php index d8fb316..ffaee1a 100644 --- a/app/Domains/Product/Models/Brand.php +++ b/app/Domains/Product/Models/Brand.php @@ -2,9 +2,29 @@ namespace App\Domains\Product\Models; +use App\Domains\Prop\Models\ModelPropValue; +use App\Domains\Prop\Models\Prop; +use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; +use Illuminate\Database\Eloquent\Relations\MorphMany; class Brand extends Model { - // Placeholder model for the product domain structure. + use HasFactory; + + /** + * @return MorphMany + */ + public function props(): MorphMany + { + return $this->morphMany(Prop::class, 'propable'); + } + + /** + * @return MorphMany + */ + public function propValues(): MorphMany + { + return $this->morphMany(ModelPropValue::class, 'valuable'); + } } diff --git a/app/Domains/Product/Models/Category.php b/app/Domains/Product/Models/Category.php index 8bbca0f..f8d128e 100644 --- a/app/Domains/Product/Models/Category.php +++ b/app/Domains/Product/Models/Category.php @@ -2,9 +2,29 @@ namespace App\Domains\Product\Models; +use App\Domains\Prop\Models\ModelPropValue; +use App\Domains\Prop\Models\Prop; +use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; +use Illuminate\Database\Eloquent\Relations\MorphMany; class Category extends Model { - // Placeholder model for the product domain structure. + use HasFactory; + + /** + * @return MorphMany + */ + public function props(): MorphMany + { + return $this->morphMany(Prop::class, 'propable'); + } + + /** + * @return MorphMany + */ + public function propValues(): MorphMany + { + return $this->morphMany(ModelPropValue::class, 'valuable'); + } } diff --git a/app/Domains/Product/Models/Product.php b/app/Domains/Product/Models/Product.php index bbaadef..ca92445 100644 --- a/app/Domains/Product/Models/Product.php +++ b/app/Domains/Product/Models/Product.php @@ -2,11 +2,14 @@ namespace App\Domains\Product\Models; +use App\Domains\Prop\Models\ModelPropValue; +use App\Domains\Prop\Models\Prop; 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\MorphMany; #[Fillable([ 'tenant_codigo', @@ -37,4 +40,20 @@ class Product extends Model { return $this->belongsTo(Tenant::class, 'tenant_codigo', 'codigo'); } + + /** + * @return MorphMany + */ + public function props(): MorphMany + { + return $this->morphMany(Prop::class, 'propable'); + } + + /** + * @return MorphMany + */ + public function propValues(): MorphMany + { + return $this->morphMany(ModelPropValue::class, 'valuable'); + } } diff --git a/app/Domains/Prop/Models/ModelPropValue.php b/app/Domains/Prop/Models/ModelPropValue.php new file mode 100644 index 0000000..fa44130 --- /dev/null +++ b/app/Domains/Prop/Models/ModelPropValue.php @@ -0,0 +1,38 @@ + + */ + public function valuable(): MorphTo + { + return $this->morphTo(); + } + + /** + * @return BelongsTo + */ + public function prop(): BelongsTo + { + return $this->belongsTo(Prop::class, 'prop_codigo', 'codigo'); + } +} diff --git a/app/Domains/Prop/Models/Prop.php b/app/Domains/Prop/Models/Prop.php new file mode 100644 index 0000000..f0b3a38 --- /dev/null +++ b/app/Domains/Prop/Models/Prop.php @@ -0,0 +1,56 @@ + + */ + public function propable(): MorphTo + { + return $this->morphTo(); + } + + /** + * @return BelongsTo + */ + public function dataType(): BelongsTo + { + return $this->belongsTo(PropDataType::class, 'data_type_id'); + } + + /** + * @return HasMany + */ + public function options(): HasMany + { + return $this->hasMany(PropOption::class); + } + + /** + * @return HasMany + */ + public function modelValues(): HasMany + { + return $this->hasMany(ModelPropValue::class, 'prop_codigo', 'codigo'); + } +} diff --git a/app/Domains/Prop/Models/PropDataType.php b/app/Domains/Prop/Models/PropDataType.php new file mode 100644 index 0000000..e93aad0 --- /dev/null +++ b/app/Domains/Prop/Models/PropDataType.php @@ -0,0 +1,25 @@ + + */ + public function props(): HasMany + { + return $this->hasMany(Prop::class, 'data_type_id'); + } +} diff --git a/app/Domains/Prop/Models/PropOption.php b/app/Domains/Prop/Models/PropOption.php new file mode 100644 index 0000000..32416de --- /dev/null +++ b/app/Domains/Prop/Models/PropOption.php @@ -0,0 +1,27 @@ + + */ + public function prop(): BelongsTo + { + return $this->belongsTo(Prop::class); + } +} diff --git a/app/Domains/Tenant/Models/Tenant.php b/app/Domains/Tenant/Models/Tenant.php index 19eb89f..dfcb92c 100644 --- a/app/Domains/Tenant/Models/Tenant.php +++ b/app/Domains/Tenant/Models/Tenant.php @@ -2,12 +2,15 @@ namespace App\Domains\Tenant\Models; +use App\Domains\Prop\Models\ModelPropValue; +use App\Domains\Prop\Models\Prop; use App\Domains\Product\Models\Product; use Illuminate\Database\Eloquent\Attributes\Fillable; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsToMany; use Illuminate\Database\Eloquent\Relations\HasMany; +use Illuminate\Database\Eloquent\Relations\MorphMany; #[Fillable([ 'codigo', @@ -35,4 +38,20 @@ class Tenant extends Model ->withPivot('valor') ->withTimestamps(); } + + /** + * @return MorphMany + */ + public function props(): MorphMany + { + return $this->morphMany(Prop::class, 'propable'); + } + + /** + * @return MorphMany + */ + public function propValues(): MorphMany + { + return $this->morphMany(ModelPropValue::class, 'valuable'); + } } diff --git a/database/migrations/2026_06_22_120000_create_props_data_types_table.php b/database/migrations/2026_06_22_120000_create_props_data_types_table.php new file mode 100644 index 0000000..ae7b41c --- /dev/null +++ b/database/migrations/2026_06_22_120000_create_props_data_types_table.php @@ -0,0 +1,29 @@ +id(); + $table->string('name'); + $table->string('code')->unique(); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('props_data_types'); + } +}; diff --git a/database/migrations/2026_06_22_120100_create_props_table.php b/database/migrations/2026_06_22_120100_create_props_table.php new file mode 100644 index 0000000..b6b472d --- /dev/null +++ b/database/migrations/2026_06_22_120100_create_props_table.php @@ -0,0 +1,36 @@ +id(); + $table->string('propable_type'); + $table->unsignedBigInteger('propable_id')->nullable(); + $table->enum('scope', ['global', 'particular']); + $table->string('codigo')->unique(); + $table->string('nombre'); + $table->boolean('is_required')->default(false); + $table->foreignId('data_type_id')->constrained('props_data_types')->cascadeOnUpdate()->restrictOnDelete(); + $table->timestamps(); + + $table->index(['propable_type', 'propable_id']); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('props'); + } +}; diff --git a/database/migrations/2026_06_22_120200_create_prop_options_table.php b/database/migrations/2026_06_22_120200_create_prop_options_table.php new file mode 100644 index 0000000..77c37d8 --- /dev/null +++ b/database/migrations/2026_06_22_120200_create_prop_options_table.php @@ -0,0 +1,33 @@ +id(); + $table->foreignId('prop_id')->constrained('props')->cascadeOnUpdate()->cascadeOnDelete(); + $table->string('value'); + $table->string('label'); + $table->unsignedInteger('sort_order')->default(0); + $table->timestamps(); + + $table->unique(['prop_id', 'value']); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('prop_options'); + } +}; diff --git a/database/migrations/2026_06_22_120300_create_model_prop_values_table.php b/database/migrations/2026_06_22_120300_create_model_prop_values_table.php new file mode 100644 index 0000000..2004284 --- /dev/null +++ b/database/migrations/2026_06_22_120300_create_model_prop_values_table.php @@ -0,0 +1,40 @@ +id(); + $table->string('valuable_type'); + $table->unsignedBigInteger('valuable_id'); + $table->string('prop_codigo'); + $table->text('value')->nullable(); + $table->timestamps(); + + $table->foreign('prop_codigo') + ->references('codigo') + ->on('props') + ->cascadeOnUpdate() + ->cascadeOnDelete(); + + $table->unique(['valuable_type', 'valuable_id', 'prop_codigo']); + $table->index(['valuable_type', 'valuable_id']); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('model_prop_values'); + } +};