diff --git a/app/Domains/Product/Models/Brand.php b/app/Domains/Product/Models/Brand.php index d33032b..4b951ce 100644 --- a/app/Domains/Product/Models/Brand.php +++ b/app/Domains/Product/Models/Brand.php @@ -2,10 +2,12 @@ namespace App\Domains\Product\Models; +use App\Domains\Prop\Concerns\Propable; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; class Brand extends Model { use HasFactory; + use Propable; } diff --git a/app/Domains/Product/Models/Category.php b/app/Domains/Product/Models/Category.php index e8b407d..4cdd2eb 100644 --- a/app/Domains/Product/Models/Category.php +++ b/app/Domains/Product/Models/Category.php @@ -2,10 +2,12 @@ namespace App\Domains\Product\Models; +use App\Domains\Prop\Concerns\Propable; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; class Category extends Model { use HasFactory; + use Propable; } diff --git a/app/Domains/Product/Models/Product.php b/app/Domains/Product/Models/Product.php index bbaadef..86666c2 100644 --- a/app/Domains/Product/Models/Product.php +++ b/app/Domains/Product/Models/Product.php @@ -2,6 +2,7 @@ namespace App\Domains\Product\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; @@ -19,6 +20,7 @@ use Illuminate\Database\Eloquent\Relations\BelongsTo; class Product extends Model { use HasFactory; + use Propable; protected $table = 'productos'; diff --git a/app/Domains/Prop/Concerns/Propable.php b/app/Domains/Prop/Concerns/Propable.php new file mode 100644 index 0000000..59a1da4 --- /dev/null +++ b/app/Domains/Prop/Concerns/Propable.php @@ -0,0 +1,94 @@ + $attributes + */ + public static function createProp(array $attributes): Prop + { + return Prop::query()->create([ + ...$attributes, + 'propable_type' => static::class, + ]); + } + + /** + * @return Builder + */ + public function props(): Builder + { + return Prop::query()->forModel(static::class); + } + + /** + * @return HasMany + */ + public function propValues(): HasMany + { + return $this->hasMany(ModelPropValue::class, 'valuable_id') + ->whereHas('prop', fn (Builder $query) => $query->forModel(static::class)); + } + + public function getPropValue(Prop|string $prop): ?ModelPropValue + { + $resolvedProp = $this->resolveProp($prop); + + return $this->propValues() + ->where('prop_id', $resolvedProp->getKey()) + ->first(); + } + + public function setPropValue(Prop|string $prop, mixed $value): ModelPropValue + { + $this->ensurePropValuesCanBeManaged(); + + $resolvedProp = $this->resolveProp($prop); + + return $this->propValues()->updateOrCreate( + ['prop_id' => $resolvedProp->getKey()], + ['value' => $value], + ); + } + + public function deletePropValue(Prop|string $prop): bool + { + $resolvedProp = $this->resolveProp($prop); + + return $this->propValues() + ->where('prop_id', $resolvedProp->getKey()) + ->delete() > 0; + } + + protected function ensurePropValuesCanBeManaged(): void + { + if (! $this->exists) { + throw new LogicException('Cannot manage prop values for an unsaved model.'); + } + } + + protected function resolveProp(Prop|string $prop): Prop + { + if ($prop instanceof Prop) { + if ($prop->propable_type !== static::class) { + throw new LogicException('The given prop does not belong to this model type.'); + } + + return $prop; + } + + return Prop::query() + ->forModel(static::class) + ->where('codigo', $prop) + ->firstOrFail(); + } +} diff --git a/app/Domains/Tenant/Models/Tenant.php b/app/Domains/Tenant/Models/Tenant.php index 2437289..e31b743 100644 --- a/app/Domains/Tenant/Models/Tenant.php +++ b/app/Domains/Tenant/Models/Tenant.php @@ -2,14 +2,11 @@ namespace App\Domains\Tenant\Models; -use App\Domains\Prop\Models\ModelPropValue; -use App\Domains\Prop\Models\Prop; +use App\Domains\Prop\Concerns\Propable; use App\Domains\Product\Models\Product; use Illuminate\Database\Eloquent\Attributes\Fillable; -use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; -use Illuminate\Database\Eloquent\Relations\BelongsToMany; use Illuminate\Database\Eloquent\Relations\HasMany; #[Fillable([ @@ -20,6 +17,7 @@ use Illuminate\Database\Eloquent\Relations\HasMany; class Tenant extends Model { use HasFactory; + use Propable; /** * @return HasMany @@ -28,31 +26,4 @@ class Tenant extends Model { return $this->hasMany(Product::class, 'tenant_codigo', 'codigo'); } - - /** - * @return BelongsToMany - */ - public function tenantProps(): BelongsToMany - { - return $this->belongsToMany(TenantProp::class, 'tenant_prop_definitions', 'tenant_codigo', 'prop_codigo', 'codigo', 'codigo') - ->withPivot('valor') - ->withTimestamps(); - } - - /** - * @return Builder - */ - public function props(): Builder - { - return Prop::query()->forModel(static::class); - } - - /** - * @return HasMany - */ - public function propValues(): HasMany - { - return $this->hasMany(ModelPropValue::class, 'valuable_id') - ->whereHas('prop', fn (Builder $query) => $query->forModel(static::class)); - } }