@@ -292,7 +298,7 @@
created () {
@foreach($attribute->options as $option)
this.optionRowCount++;
- var row = {'id': '{{ $option->id }}', 'sort_order': '{{ $option->sort_order }}'};
+ var row = {'id': '{{ $option->id }}', 'admin_name': '{{ $option->admin_name }}', 'sort_order': '{{ $option->sort_order }}'};
@foreach(Webkul\Core\Models\Locale::all() as $locale)
row['{{ $locale->code }}'] = "{{ $option->translate($locale->code)['label'] }}";
@@ -324,6 +330,10 @@
Vue.delete(this.optionRows, index);
},
+ adminName (row) {
+ return 'options[' + row.id + '][admin_name]';
+ },
+
localeInputName (row, locale) {
return 'options[' + row.id + '][' + locale + '][label]';
},
diff --git a/packages/Webkul/Admin/src/Resources/views/catalog/products/attribute-types/text.blade.php b/packages/Webkul/Admin/src/Resources/views/catalog/products/attribute-types/text.blade.php
deleted file mode 100644
index ffd5e9498..000000000
--- a/packages/Webkul/Admin/src/Resources/views/catalog/products/attribute-types/text.blade.php
+++ /dev/null
@@ -1,4 +0,0 @@
-
- {{ $attribute->admin_name }}
-
-
\ No newline at end of file
diff --git a/packages/Webkul/Admin/src/Resources/views/catalog/products/create.blade.php b/packages/Webkul/Admin/src/Resources/views/catalog/products/create.blade.php
index d1f94dbb1..0250c4797 100644
--- a/packages/Webkul/Admin/src/Resources/views/catalog/products/create.blade.php
+++ b/packages/Webkul/Admin/src/Resources/views/catalog/products/create.blade.php
@@ -100,7 +100,7 @@
@foreach($attribute->options as $option)
-
+
{{ $option->label }}
diff --git a/packages/Webkul/Admin/src/Resources/views/catalog/products/edit.blade.php b/packages/Webkul/Admin/src/Resources/views/catalog/products/edit.blade.php
index d1d5b82b1..5451985f2 100644
--- a/packages/Webkul/Admin/src/Resources/views/catalog/products/edit.blade.php
+++ b/packages/Webkul/Admin/src/Resources/views/catalog/products/edit.blade.php
@@ -26,9 +26,24 @@
@foreach($attributeGroup->attributes as $attribute)
- @if(view()->exists($typeView = 'admin::catalog.products.attribute-types.' . $attribute->type))
+ @if(!$product->super_attributes->contains($attribute))
+
+ is_required) {
+ array_push($validations, 'required');
+ }
- @include ($typeView)
+ array_push($validations, $attribute->validation);
+
+ $validations = implode('|', array_filter($validations));
+ ?>
+
+ @if(view()->exists($typeView = 'admin::catalog.products.field-types.' . $attribute->type))
+
+ @include ($typeView)
+
+ @endif
@endif
diff --git a/packages/Webkul/Admin/src/Resources/views/catalog/products/field-types/boolean.blade.php b/packages/Webkul/Admin/src/Resources/views/catalog/products/field-types/boolean.blade.php
new file mode 100644
index 000000000..b89bd5e1a
--- /dev/null
+++ b/packages/Webkul/Admin/src/Resources/views/catalog/products/field-types/boolean.blade.php
@@ -0,0 +1,16 @@
+
+ is_required ? 'class=required' : '' }}>
+ {{ $attribute->admin_name }}
+
+
+
+ code] ? 'selected' : ''}}>
+ {{ __('admin::app.catalog.products.no') }}
+
+ code] ? 'selected' : ''}}>
+ {{ __('admin::app.catalog.products.yes') }}
+
+
+
+ @{{ errors.first('{!! $attribute->code !!}') }}
+
\ No newline at end of file
diff --git a/packages/Webkul/Admin/src/Resources/views/catalog/products/field-types/date.blade.php b/packages/Webkul/Admin/src/Resources/views/catalog/products/field-types/date.blade.php
new file mode 100644
index 000000000..dd7a12c3f
--- /dev/null
+++ b/packages/Webkul/Admin/src/Resources/views/catalog/products/field-types/date.blade.php
@@ -0,0 +1,9 @@
+
+ is_required ? 'class=required' : '' }}>
+ {{ $attribute->admin_name }}
+
+
+
+
+ @{{ errors.first('{!! $attribute->code !!}') }}
+
\ No newline at end of file
diff --git a/packages/Webkul/Admin/src/Resources/views/catalog/products/field-types/datetime.blade.php b/packages/Webkul/Admin/src/Resources/views/catalog/products/field-types/datetime.blade.php
new file mode 100644
index 000000000..f3b6e44ac
--- /dev/null
+++ b/packages/Webkul/Admin/src/Resources/views/catalog/products/field-types/datetime.blade.php
@@ -0,0 +1,11 @@
+
+ is_required ? 'class=required' : '' }}>
+ {{ $attribute->admin_name }}
+
+
+
+
+
+
+ @{{ errors.first('{!! $attribute->code !!}') }}
+
\ No newline at end of file
diff --git a/packages/Webkul/Admin/src/Resources/views/catalog/products/field-types/multiselect.blade.php b/packages/Webkul/Admin/src/Resources/views/catalog/products/field-types/multiselect.blade.php
new file mode 100644
index 000000000..b78d78986
--- /dev/null
+++ b/packages/Webkul/Admin/src/Resources/views/catalog/products/field-types/multiselect.blade.php
@@ -0,0 +1,17 @@
+
+ is_required ? 'class=required' : '' }}>
+ {{ $attribute->admin_name }}
+
+
+
+
+ @foreach($attribute->options as $option)
+ id, explode(',', $attribute[$attribute->code])) ? 'selected' : ''}}>
+ {{ $option->admin_name }}
+
+ @endforeach
+
+
+
+ @{{ errors.first('{!! $attribute->code !!}') }}
+
\ No newline at end of file
diff --git a/packages/Webkul/Admin/src/Resources/views/catalog/products/field-types/price.blade.php b/packages/Webkul/Admin/src/Resources/views/catalog/products/field-types/price.blade.php
new file mode 100644
index 000000000..dd7a12c3f
--- /dev/null
+++ b/packages/Webkul/Admin/src/Resources/views/catalog/products/field-types/price.blade.php
@@ -0,0 +1,9 @@
+
+ is_required ? 'class=required' : '' }}>
+ {{ $attribute->admin_name }}
+
+
+
+
+ @{{ errors.first('{!! $attribute->code !!}') }}
+
\ No newline at end of file
diff --git a/packages/Webkul/Admin/src/Resources/views/catalog/products/field-types/select.blade.php b/packages/Webkul/Admin/src/Resources/views/catalog/products/field-types/select.blade.php
new file mode 100644
index 000000000..46857447e
--- /dev/null
+++ b/packages/Webkul/Admin/src/Resources/views/catalog/products/field-types/select.blade.php
@@ -0,0 +1,17 @@
+
+ is_required ? 'class=required' : '' }}>
+ {{ $attribute->admin_name }}
+
+
+
+
+ @foreach($attribute->options as $option)
+ id == $attribute[$attribute->code] ? 'selected' : ''}}>
+ {{ $option->admin_name }}
+
+ @endforeach
+
+
+
+ @{{ errors.first('{!! $attribute->code !!}') }}
+
\ No newline at end of file
diff --git a/packages/Webkul/Admin/src/Resources/views/catalog/products/field-types/text.blade.php b/packages/Webkul/Admin/src/Resources/views/catalog/products/field-types/text.blade.php
new file mode 100644
index 000000000..dd7a12c3f
--- /dev/null
+++ b/packages/Webkul/Admin/src/Resources/views/catalog/products/field-types/text.blade.php
@@ -0,0 +1,9 @@
+
+ is_required ? 'class=required' : '' }}>
+ {{ $attribute->admin_name }}
+
+
+
+
+ @{{ errors.first('{!! $attribute->code !!}') }}
+
\ No newline at end of file
diff --git a/packages/Webkul/Admin/src/Resources/views/catalog/products/field-types/textarea.blade.php b/packages/Webkul/Admin/src/Resources/views/catalog/products/field-types/textarea.blade.php
new file mode 100644
index 000000000..644fbd73e
--- /dev/null
+++ b/packages/Webkul/Admin/src/Resources/views/catalog/products/field-types/textarea.blade.php
@@ -0,0 +1,11 @@
+
+ is_required ? 'class=required' : '' }}>
+ {{ $attribute->admin_name }}
+
+
+
+
+ @{{ errors.first('{!! $attribute->code !!}') }}
+
\ No newline at end of file
diff --git a/packages/Webkul/Attribute/src/Database/Migrations/2018_07_05_140832_create_attribute_options_table.php b/packages/Webkul/Attribute/src/Database/Migrations/2018_07_05_140832_create_attribute_options_table.php
index 66883cd91..dddb4971d 100644
--- a/packages/Webkul/Attribute/src/Database/Migrations/2018_07_05_140832_create_attribute_options_table.php
+++ b/packages/Webkul/Attribute/src/Database/Migrations/2018_07_05_140832_create_attribute_options_table.php
@@ -15,6 +15,7 @@ class CreateAttributeOptionsTable extends Migration
{
Schema::create('attribute_options', function (Blueprint $table) {
$table->increments('id');
+ $table->string('admin_name')->nullable();
$table->integer('sort_order')->nullable();
$table->integer('attribute_id')->unsigned();
$table->foreign('attribute_id')->references('id')->on('attributes')->onDelete('cascade');
diff --git a/packages/Webkul/Attribute/src/Models/Attribute.php b/packages/Webkul/Attribute/src/Models/Attribute.php
index 9cab5be95..bc94bdc98 100644
--- a/packages/Webkul/Attribute/src/Models/Attribute.php
+++ b/packages/Webkul/Attribute/src/Models/Attribute.php
@@ -12,6 +12,8 @@ class Attribute extends TranslatableModel
protected $fillable = ['code', 'admin_name', 'type', 'position', 'is_required', 'is_unique', 'value_per_locale', 'value_per_channel', 'is_filterable', 'is_configurable'];
+ protected $with = ['options'];
+
/**
* Get the options.
*/
diff --git a/packages/Webkul/Core/src/Http/helpers.php b/packages/Webkul/Core/src/Http/helpers.php
index 1f8f52fb4..0312b5ce8 100644
--- a/packages/Webkul/Core/src/Http/helpers.php
+++ b/packages/Webkul/Core/src/Http/helpers.php
@@ -7,4 +7,42 @@
return new Core;
}
}
+
+ if (! function_exists('array_permutation')) {
+ function array_permutation($input)
+ {
+ $results = [];
+
+ while (list($key, $values) = each($input)) {
+ if (empty($values)) {
+ continue;
+ }
+
+ if (empty($results)) {
+ foreach($values as $value) {
+ $results[] = [$key => $value];
+ }
+ } else {
+ $append = [];
+
+ foreach($results as &$result) {
+ $result[$key] = array_shift($values);
+
+ $copy = $result;
+
+ foreach($values as $item) {
+ $copy[$key] = $item;
+ $append[] = $copy;
+ }
+
+ array_unshift($values, $result[$key]);
+ }
+
+ $results = array_merge($results, $append);
+ }
+ }
+
+ return $results;
+ }
+ }
?>
\ No newline at end of file
diff --git a/packages/Webkul/Product/src/Database/Migrations/2018_07_27_070011_create_product_attribute_value_table.php b/packages/Webkul/Product/src/Database/Migrations/2018_07_27_070011_create_product_attribute_values_table.php
similarity index 84%
rename from packages/Webkul/Product/src/Database/Migrations/2018_07_27_070011_create_product_attribute_value_table.php
rename to packages/Webkul/Product/src/Database/Migrations/2018_07_27_070011_create_product_attribute_values_table.php
index b567db652..9eca6f5b3 100644
--- a/packages/Webkul/Product/src/Database/Migrations/2018_07_27_070011_create_product_attribute_value_table.php
+++ b/packages/Webkul/Product/src/Database/Migrations/2018_07_27_070011_create_product_attribute_values_table.php
@@ -4,7 +4,7 @@ use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
-class CreateProductAttributeValueTable extends Migration
+class CreateProductAttributeValuesTable extends Migration
{
/**
* Run the migrations.
@@ -13,7 +13,7 @@ class CreateProductAttributeValueTable extends Migration
*/
public function up()
{
- Schema::create('product_attribute_value', function (Blueprint $table) {
+ Schema::create('product_attribute_values', function (Blueprint $table) {
$table->increments('id');
$table->string('locale')->nullable();
$table->text('text_value')->nullable();
@@ -25,7 +25,7 @@ class CreateProductAttributeValueTable extends Migration
$table->json('json_value')->nullable();
$table->integer('product_id')->unsigned();
$table->integer('attribute_id')->unsigned();
- $table->integer('channel_id')->unsigned();
+ $table->integer('channel_id')->nullable()->unsigned();
$table->foreign('product_id')->references('id')->on('products')->onDelete('cascade');
$table->foreign('attribute_id')->references('id')->on('attributes')->onDelete('cascade');
$table->foreign('channel_id')->references('id')->on('channels')->onDelete('cascade');
@@ -40,6 +40,6 @@ class CreateProductAttributeValueTable extends Migration
*/
public function down()
{
- Schema::dropIfExists('product_attribute_value');
+ Schema::dropIfExists('product_attribute_values');
}
}
diff --git a/packages/Webkul/Product/src/Http/Controllers/ProductController.php b/packages/Webkul/Product/src/Http/Controllers/ProductController.php
index 914b1f043..fccc401c1 100644
--- a/packages/Webkul/Product/src/Http/Controllers/ProductController.php
+++ b/packages/Webkul/Product/src/Http/Controllers/ProductController.php
@@ -118,8 +118,6 @@ class ProductController extends Controller
{
$product = $this->product->findOrFail($id);
- dd($product);
-
return view($this->_config['view'], compact('product'));
}
diff --git a/packages/Webkul/Product/src/Models/Product.php b/packages/Webkul/Product/src/Models/Product.php
index 906305959..5ac96bd54 100644
--- a/packages/Webkul/Product/src/Models/Product.php
+++ b/packages/Webkul/Product/src/Models/Product.php
@@ -3,16 +3,31 @@
namespace Webkul\Product\Models;
use Illuminate\Database\Eloquent\Model;
-use Webkul\Attribute\Models\Attribute;
-use Webkul\Category\Models\Category;
-use Webkul\Inventory\Models\InventorySource;
use Webkul\Attribute\Models\AttributeFamily;
+use Webkul\Category\Models\Category;
+use Webkul\Attribute\Models\Attribute;
+use Webkul\Product\Models\ProductAttributeValue;
+use Webkul\Inventory\Models\InventorySource;
class Product extends Model
{
- protected $fillable = ['type', 'attribute_family_id', 'sku'];
+ protected $fillable = ['type', 'attribute_family_id', 'sku', 'parent_id'];
- protected $with = ['super_attributes'];
+ protected $with = ['attribute_values', 'varients'];
+
+ /**
+ * @var array
+ */
+ protected $attributeTypeFields = [
+ 'text' => 'text_value',
+ 'textarea' => 'text_value',
+ 'price' => 'float_value',
+ 'boolean' => 'boolean_value',
+ 'select' => 'integer_value',
+ 'multiselect' => 'text_value',
+ 'datetime' => 'datetime_time',
+ 'date' => 'date_value',
+ ];
/**
* Get the product attribute family that owns the product.
@@ -22,6 +37,22 @@ class Product extends Model
return $this->belongsTo(AttributeFamily::class);
}
+ /**
+ * Get the product attribute values that owns the product.
+ */
+ public function attribute_values()
+ {
+ return $this->hasMany(ProductAttributeValue::class);
+ }
+
+ /**
+ * Get the product varients that owns the product.
+ */
+ public function varients()
+ {
+ return $this->hasMany(self::class, 'parent_id');
+ }
+
/**
* The categories that belong to the product.
*/
@@ -70,11 +101,28 @@ class Product extends Model
return $this->belongsToMany(self::class, 'product_cross_sells');
}
- public function __get($name) {
- // if(array_key_exists($name, $this->data)) {
- // return $this->data[$name];
- // }
+ /**
+ * @return array
+ */
+ public function attributesToArray()
+ {
+ $attributes = parent::attributesToArray();
- return null;
+ $hiddenAttributes = $this->getHidden();
+
+ foreach ($this->attribute_values as $attributeValue) {
+
+ $attribute = $attributeValue->attribute;
+
+ if (in_array($attribute->code, $hiddenAttributes)) {
+ continue;
+ }
+
+ if ($value = $attributeValue[$this->attributeTypeFields[$attribute->type]]) {
+ $attributes[$attribute->code] = $value;
+ }
+ }
+
+ return $attributes;
}
}
\ No newline at end of file
diff --git a/packages/Webkul/Product/src/Models/ProductAttributeValue.php b/packages/Webkul/Product/src/Models/ProductAttributeValue.php
index 2e045652f..30946de86 100644
--- a/packages/Webkul/Product/src/Models/ProductAttributeValue.php
+++ b/packages/Webkul/Product/src/Models/ProductAttributeValue.php
@@ -5,15 +5,34 @@ namespace Webkul\Product\Models;
use Illuminate\Database\Eloquent\Model;
use Webkul\Attribute\Models\Attribute;
use Webkul\Product\Models\Product;
+use Webkul\Channel\Models\Channel;
class ProductAttributeValue extends Model
{
+ public $timestamps = false;
+
+ protected $with = ['attribute'];
+
+ protected $fillable = [
+ 'product_id',
+ 'attribute_id',
+ 'channel_id',
+ 'locale',
+ 'text_value',
+ 'boolean_value',
+ 'integer_value',
+ 'float_value',
+ 'datetime_value',
+ 'date_value',
+ 'json_value'
+ ];
+
/**
- * Get the attribue that owns the attribute value.
+ * Get the attribute that owns the attribute value.
*/
- public function attribue()
+ public function attribute()
{
- return $this->belongsTo(Attribue::class);
+ return $this->belongsTo(Attribute::class);
}
/**
@@ -23,4 +42,12 @@ class ProductAttributeValue extends Model
{
return $this->belongsTo(Product::class);
}
+
+ /**
+ * Get the channel that owns the attribute value.
+ */
+ public function channel()
+ {
+ return $this->belongsTo(Channel::class);
+ }
}
\ No newline at end of file
diff --git a/packages/Webkul/Product/src/Repositories/ProductAttributeValueRepository.php b/packages/Webkul/Product/src/Repositories/ProductAttributeValueRepository.php
index 751fcbbbc..e769263b8 100644
--- a/packages/Webkul/Product/src/Repositories/ProductAttributeValueRepository.php
+++ b/packages/Webkul/Product/src/Repositories/ProductAttributeValueRepository.php
@@ -2,6 +2,8 @@
namespace Webkul\Product\Repositories;
+use Illuminate\Container\Container as App;
+use Webkul\Attribute\Repositories\AttributeRepository;
use Webkul\Core\Eloquent\Repository;
/**
@@ -11,7 +13,41 @@ use Webkul\Core\Eloquent\Repository;
* @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com)
*/
class ProductAttributeValueRepository extends Repository
-{
+{
+ /**
+ * AttributeRepository object
+ *
+ * @var array
+ */
+ protected $attribute;
+
+ /**
+ * @var array
+ */
+ protected $attributeTypeFields = [
+ 'text' => 'text_value',
+ 'textarea' => 'text_value',
+ 'price' => 'float_value',
+ 'boolean' => 'boolean_value',
+ 'select' => 'integer_value',
+ 'multiselect' => 'text_value',
+ 'datetime' => 'datetime_time',
+ 'date' => 'date_value',
+ ];
+
+ /**
+ * Create a new controller instance.
+ *
+ * @param Webkul\Attribute\Repositories\AttributeRepository $attribute
+ * @return void
+ */
+ public function __construct(AttributeRepository $attribute, App $app)
+ {
+ $this->attribute = $attribute;
+
+ parent::__construct($app);
+ }
+
/**
* Specify Model class name
*
@@ -28,12 +64,10 @@ class ProductAttributeValueRepository extends Repository
*/
public function create(array $data)
{
- $product = $this->model->create($data);
+ $attribute = $this->attribute->find($data['attribute_id']);
- foreach ($data['super_attributes'] as $attributeId => $attribute) {
- $product->super_attributes()->attach($attributeId);
- }
+ $data[$this->attributeTypeFields[$attribute->type]] = $data['value'];
- return $product;
+ return $this->model->create($data);
}
}
\ No newline at end of file
diff --git a/packages/Webkul/Product/src/Repositories/ProductRepository.php b/packages/Webkul/Product/src/Repositories/ProductRepository.php
index 30f1eabb9..0c8b81633 100644
--- a/packages/Webkul/Product/src/Repositories/ProductRepository.php
+++ b/packages/Webkul/Product/src/Repositories/ProductRepository.php
@@ -2,7 +2,10 @@
namespace Webkul\Product\Repositories;
+use Illuminate\Container\Container as App;
use Webkul\Core\Eloquent\Repository;
+use Webkul\Attribute\Repositories\AttributeRepository;
+use Webkul\Product\Repositories\ProductAttributeValueRepository;
/**
* Product Reposotory
@@ -12,6 +15,39 @@ use Webkul\Core\Eloquent\Repository;
*/
class ProductRepository extends Repository
{
+ /**
+ * AttributeRepository object
+ *
+ * @var array
+ */
+ protected $attribute;
+
+ /**
+ * ProductAttributeValueRepository object
+ *
+ * @var array
+ */
+ protected $attributeValue;
+
+ /**
+ * Create a new controller instance.
+ *
+ * @param Webkul\Attribute\Repositories\AttributeRepository $attribute
+ * @param Webkul\Attribute\Repositories\ProductAttributeValueRepository $attributeValue
+ * @return void
+ */
+ public function __construct(
+ AttributeRepository $attribute,
+ ProductAttributeValueRepository $attributeValue,
+ App $app)
+ {
+ $this->attribute = $attribute;
+
+ $this->attributeValue = $attributeValue;
+
+ parent::__construct($app);
+ }
+
/**
* Specify Model class name
*
@@ -31,11 +67,46 @@ class ProductRepository extends Repository
$product = $this->model->create($data);
if(isset($data['super_attributes'])) {
- foreach ($data['super_attributes'] as $attributeId => $attribute) {
- $product->super_attributes()->attach($attributeId);
+
+ $super_attributes = [];
+
+ foreach ($data['super_attributes'] as $attributeCode => $attributeOptions) {
+ $attribute = $this->attribute->findBy('code', $attributeCode);
+
+ $super_attributes[$attribute->id] = $attributeOptions;
+
+ $product->super_attributes()->attach($attribute->id);
+ }
+
+ foreach (array_permutation($super_attributes) as $permutation) {
+ $this->createVarient($product, $permutation);
}
}
return $product;
}
+
+ /**
+ * @param array $data
+ * @return mixed
+ */
+ public function createVarient($product, $permutation)
+ {
+ $varient = $this->model->create([
+ 'parent_id' => $product->id,
+ 'type' => 'simple',
+ 'attribute_family_id' => $product->attribute_family_id,
+ 'sku' => $product->sku . '-varient-' . implode('-', $permutation),
+ ]);
+
+ foreach($permutation as $attributeId => $optionId) {
+ $this->attributeValue->create([
+ 'product_id' => $varient->id,
+ 'attribute_id' => $attributeId,
+ 'value' => $optionId
+ ]);
+ }
+
+ return $varient;
+ }
}
\ No newline at end of file