Merge remote-tracking branch 'bagisto-hb/master' into 18472-bugfix/add-category-url-path
This commit is contained in:
commit
a50905781a
File diff suppressed because one or more lines are too long
|
|
@ -545,6 +545,7 @@ return [
|
|||
'file' => 'File',
|
||||
'checkbox' => 'Checkbox',
|
||||
'use_in_flat' => "Create in Product Flat Table",
|
||||
'default_null_option' => 'Create default empty option',
|
||||
],
|
||||
'families' => [
|
||||
'title' => 'Families',
|
||||
|
|
|
|||
|
|
@ -252,6 +252,15 @@
|
|||
</select>
|
||||
</div>
|
||||
|
||||
<div class="control-group">
|
||||
<span class="checkbox">
|
||||
<input type="checkbox" class="control" id="default-null-option" name="default-null-option" v-model="isNullOptionChecked" >
|
||||
|
||||
<label class="checkbox-view" for="default-null-option"></label>
|
||||
{{ __('admin::app.catalog.attributes.default_null_option') }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="table">
|
||||
<table>
|
||||
<thead>
|
||||
|
|
@ -292,7 +301,7 @@
|
|||
@foreach (app('Webkul\Core\Repositories\LocaleRepository')->all() as $locale)
|
||||
<td>
|
||||
<div class="control-group" :class="[errors.has(localeInputName(row, '{{ $locale->code }}')) ? 'has-error' : '']">
|
||||
<input type="text" v-validate="'{{ app()->getLocale() }}' == '{{ $locale->code }}' ? 'required': ''" v-model="row['{{ $locale->code }}']" :name="localeInputName(row, '{{ $locale->code }}')" class="control" data-vv-as=""{{ $locale->name . ' (' . $locale->code . ')' }}""/>
|
||||
<input type="text" v-validate="getOptionValidation(row, '{{ $locale->code }}')" v-model="row['{{ $locale->code }}']" :name="localeInputName(row, '{{ $locale->code }}')" class="control" data-vv-as=""{{ $locale->name . ' (' . $locale->code . ')' }}""/>
|
||||
<span class="control-error" v-if="errors.has(localeInputName(row, '{{ $locale->code }}'))">@{{ errors.first(localeInputName(row, '{!! $locale->code !!}')) }}</span>
|
||||
</div>
|
||||
</td>
|
||||
|
|
@ -313,7 +322,7 @@
|
|||
</table>
|
||||
</div>
|
||||
|
||||
<button type="button" class="btn btn-lg btn-primary mt-20" id="add-option-btn" @click="addOptionRow()">
|
||||
<button type="button" class="btn btn-lg btn-primary mt-20" id="add-option-btn" @click="addOptionRow(false)">
|
||||
{{ __('admin::app.catalog.attributes.add-option-btn-title') }}
|
||||
</button>
|
||||
</div>
|
||||
|
|
@ -339,10 +348,12 @@
|
|||
|
||||
data: function() {
|
||||
return {
|
||||
optionRowCount: 0,
|
||||
optionRowCount: 1,
|
||||
optionRows: [],
|
||||
show_swatch: false,
|
||||
swatch_type: ''
|
||||
swatch_type: '',
|
||||
isNullOptionChecked: false,
|
||||
idNullOption: null
|
||||
}
|
||||
},
|
||||
|
||||
|
|
@ -361,19 +372,32 @@
|
|||
},
|
||||
|
||||
methods: {
|
||||
addOptionRow: function () {
|
||||
var rowCount = this.optionRowCount++;
|
||||
var row = {'id': 'option_' + rowCount};
|
||||
addOptionRow: function (isNullOptionRow) {
|
||||
const rowCount = this.optionRowCount++;
|
||||
const id = 'option_' + rowCount;
|
||||
let row = {'id': id};
|
||||
|
||||
@foreach (app('Webkul\Core\Repositories\LocaleRepository')->all() as $locale)
|
||||
row['{{ $locale->code }}'] = '';
|
||||
@endforeach
|
||||
|
||||
row['notRequired'] = '';
|
||||
|
||||
if (isNullOptionRow) {
|
||||
this.idNullOption = id;
|
||||
row['notRequired'] = true;
|
||||
}
|
||||
|
||||
this.optionRows.push(row);
|
||||
},
|
||||
|
||||
removeRow: function (row) {
|
||||
var index = this.optionRows.indexOf(row)
|
||||
if (row.id === this.idNullOption) {
|
||||
this.idNullOption = null;
|
||||
this.isNullOptionChecked = false;
|
||||
}
|
||||
|
||||
const index = this.optionRows.indexOf(row);
|
||||
Vue.delete(this.optionRows, index);
|
||||
},
|
||||
|
||||
|
|
@ -387,6 +411,28 @@
|
|||
|
||||
sortOrderName: function (row) {
|
||||
return 'options[' + row.id + '][sort_order]';
|
||||
},
|
||||
|
||||
getOptionValidation: (row, localeCode) => {
|
||||
if (row.notRequired === true) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return ('{{ app()->getLocale() }}' === localeCode) ? 'required' : '';
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
watch: {
|
||||
isNullOptionChecked: function (val) {
|
||||
if (val) {
|
||||
if (! this.idNullOption) {
|
||||
this.addOptionRow(true);
|
||||
}
|
||||
} else if(this.idNullOption !== null && typeof this.idNullOption !== 'undefined') {
|
||||
const row = this.optionRows.find(optionRow => optionRow.id === this.idNullOption);
|
||||
this.removeRow(row);
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@
|
|||
<option value="file" {{ $selectedOption == 'file' ? 'selected' : '' }}>
|
||||
{{ __('admin::app.catalog.attributes.file') }}
|
||||
</option>
|
||||
<option value="file" {{ $selectedOption == 'checkbox' ? 'selected' : '' }}>
|
||||
<option value="checkbox" {{ $selectedOption == 'checkbox' ? 'selected' : '' }}>
|
||||
{{ __('admin::app.catalog.attributes.checkbox') }}
|
||||
</option>
|
||||
</select>
|
||||
|
|
@ -316,6 +316,15 @@
|
|||
</select>
|
||||
</div>
|
||||
|
||||
<div class="control-group">
|
||||
<span class="checkbox">
|
||||
<input type="checkbox" class="control" id="default-null-option" name="default-null-option" v-model="isNullOptionChecked">
|
||||
|
||||
<label class="checkbox-view" for="default-null-option"></label>
|
||||
{{ __('admin::app.catalog.attributes.default_null_option') }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="table">
|
||||
<table>
|
||||
<thead>
|
||||
|
|
@ -337,6 +346,7 @@
|
|||
</thead>
|
||||
|
||||
<tbody>
|
||||
|
||||
<tr v-for="(row, index) in optionRows">
|
||||
<td v-if="show_swatch && swatch_type == 'color'">
|
||||
<swatch-picker :input-name="'options[' + row.id + '][swatch_value]'" :color="row.swatch_value" colors="text-advanced" show-fallback />
|
||||
|
|
@ -357,7 +367,7 @@
|
|||
@foreach (app('Webkul\Core\Repositories\LocaleRepository')->all() as $locale)
|
||||
<td>
|
||||
<div class="control-group" :class="[errors.has(localeInputName(row, '{{ $locale->code }}')) ? 'has-error' : '']">
|
||||
<input type="text" v-validate="'{{ app()->getLocale() }}' == '{{ $locale->code }}' ? 'required': ''" v-model="row['{{ $locale->code }}']" :name="localeInputName(row, '{{ $locale->code }}')" class="control" data-vv-as=""{{ $locale->name . ' (' . $locale->code . ')' }}""/>
|
||||
<input type="text" v-validate="getOptionValidation(row, '{{ $locale->code }}')" v-model="row['{{ $locale->code }}']" :name="localeInputName(row, '{{ $locale->code }}')" class="control" data-vv-as=""{{ $locale->name . ' (' . $locale->code . ')' }}""/>
|
||||
<span class="control-error" v-if="errors.has(localeInputName(row, '{{ $locale->code }}'))">@{{ errors.first(localeInputName(row, '{!! $locale->code !!}')) }}</span>
|
||||
</div>
|
||||
</td>
|
||||
|
|
@ -396,22 +406,31 @@
|
|||
optionRowCount: 0,
|
||||
optionRows: [],
|
||||
show_swatch: "{{ $attribute->type == 'select' ? true : false }}",
|
||||
swatch_type: "{{ $attribute->swatch_type }}"
|
||||
swatch_type: "{{ $attribute->swatch_type }}",
|
||||
isNullOptionChecked: false,
|
||||
idNullOption: null
|
||||
}
|
||||
},
|
||||
|
||||
created: function () {
|
||||
@foreach ($attribute->options as $option)
|
||||
this.optionRowCount++;
|
||||
|
||||
var row = {
|
||||
'id': '{{ $option->id }}',
|
||||
'admin_name': '{{ $option->admin_name }}',
|
||||
'sort_order': '{{ $option->sort_order }}',
|
||||
'sort_order': '{{ $option->sort_order }}',
|
||||
'swatch_value': '{{ $option->swatch_value }}',
|
||||
'swatch_value_url': '{{ $option->swatch_value_url }}'
|
||||
'swatch_value_url': '{{ $option->swatch_value_url }}',
|
||||
'notRequired': ''
|
||||
};
|
||||
|
||||
@if (empty($option->label))
|
||||
this.isNullOptionChecked = true;
|
||||
this.idNullOption = '{{ $option->id }}';
|
||||
row['notRequired'] = true;
|
||||
@endif
|
||||
|
||||
@foreach (app('Webkul\Core\Repositories\LocaleRepository')->all() as $locale)
|
||||
row['{{ $locale->code }}'] = "{{ $option->translate($locale->code)['label'] }}";
|
||||
@endforeach
|
||||
|
|
@ -431,19 +450,32 @@
|
|||
},
|
||||
|
||||
methods: {
|
||||
addOptionRow: function () {
|
||||
var rowCount = this.optionRowCount++;
|
||||
var row = {'id': 'option_' + rowCount};
|
||||
addOptionRow: function (isNullOptionRow) {
|
||||
const rowCount = this.optionRowCount++;
|
||||
const id = 'option_' + rowCount;
|
||||
let row = {'id': id};
|
||||
|
||||
@foreach (app('Webkul\Core\Repositories\LocaleRepository')->all() as $locale)
|
||||
row['{{ $locale->code }}'] = '';
|
||||
@endforeach
|
||||
|
||||
row['notRequired'] = '';
|
||||
|
||||
if (isNullOptionRow) {
|
||||
this.idNullOption = id;
|
||||
row['notRequired'] = true;
|
||||
}
|
||||
|
||||
this.optionRows.push(row);
|
||||
},
|
||||
|
||||
removeRow: function (row) {
|
||||
var index = this.optionRows.indexOf(row)
|
||||
if (row.id === this.idNullOption) {
|
||||
this.idNullOption = null;
|
||||
this.isNullOptionChecked = false;
|
||||
}
|
||||
|
||||
const index = this.optionRows.indexOf(row)
|
||||
Vue.delete(this.optionRows, index);
|
||||
},
|
||||
|
||||
|
|
@ -457,8 +489,29 @@
|
|||
|
||||
sortOrderName: function (row) {
|
||||
return 'options[' + row.id + '][sort_order]';
|
||||
},
|
||||
|
||||
getOptionValidation: (row, localeCode) => {
|
||||
if (row.notRequired === true) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return ('{{ app()->getLocale() }}' === localeCode) ? 'required' : '';
|
||||
}
|
||||
},
|
||||
|
||||
watch: {
|
||||
isNullOptionChecked: function (val) {
|
||||
if (val) {
|
||||
if (! this.idNullOption) {
|
||||
this.addOptionRow(true);
|
||||
}
|
||||
} else if(this.idNullOption !== null && typeof this.idNullOption !== 'undefined') {
|
||||
const row = this.optionRows.find(optionRow => optionRow.id === this.idNullOption);
|
||||
this.removeRow(row);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
@endpush
|
||||
@endpush
|
||||
|
|
|
|||
|
|
@ -274,7 +274,7 @@
|
|||
{{ __('admin::app.dashboard.order-count', ['count' => $item->total_orders]) }}
|
||||
.
|
||||
{{ __('admin::app.dashboard.revenue', [
|
||||
'total' => core()->formatBasePrice($item->total_base_grand_total_invoiced)
|
||||
'total' => core()->formatBasePrice($item->total_base_grand_total)
|
||||
])
|
||||
}}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@
|
|||
<div class="control-group {!! $errors->has('image.*') ? 'has-error' : '' !!}">
|
||||
<label class="required">{{ __('admin::app.catalog.categories.image') }}</label>
|
||||
|
||||
<image-wrapper :button-label="'{{ __('admin::app.settings.sliders.image') }}'" input-name="image" :multiple="false" :images='"{{ url('storage/'.$slider->path) }}"' ></image-wrapper>
|
||||
<image-wrapper :button-label="'{{ __('admin::app.settings.sliders.image') }}'" input-name="image" :multiple="false" :images='"{{ Storage::url($slider->path) }}"'></image-wrapper>
|
||||
|
||||
<span class="control-error" v-if="{!! $errors->has('image.*') !!}">
|
||||
@foreach ($errors->get('image.*') as $key => $message)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,84 @@
|
|||
<?php
|
||||
|
||||
/** @var \Illuminate\Database\Eloquent\Factory $factory */
|
||||
|
||||
use Faker\Generator as Faker;
|
||||
use Webkul\Attribute\Models\Attribute;
|
||||
use Webkul\Core\Models\Locale;
|
||||
|
||||
$factory->define(Attribute::class, function (Faker $faker, array $attributes) {
|
||||
$types = [
|
||||
'text',
|
||||
'textarea',
|
||||
'price',
|
||||
'boolean',
|
||||
'select',
|
||||
'multiselect',
|
||||
'datetime',
|
||||
'date',
|
||||
'image',
|
||||
'file',
|
||||
'checkbox',
|
||||
];
|
||||
|
||||
$locales = Locale::pluck('code')->all();
|
||||
|
||||
// array $attributes does not contain any locale code
|
||||
if (count(array_diff_key(array_flip($locales), $attributes) ) === count($locales)) {
|
||||
$localeCode = $locales[0];
|
||||
|
||||
$attributes[$localeCode] = [
|
||||
'name' => $faker->word,
|
||||
];
|
||||
}
|
||||
|
||||
return [
|
||||
'admin_name' => $faker->word,
|
||||
'code' => $faker->word,
|
||||
'type' => array_rand($types),
|
||||
'validation' => '',
|
||||
'position' => $faker->randomDigit,
|
||||
'is_required' => false,
|
||||
'is_unique' => false,
|
||||
'value_per_locale' => false,
|
||||
'value_per_channel' => false,
|
||||
'is_filterable' => false,
|
||||
'is_configurable' => false,
|
||||
'is_user_defined' => true,
|
||||
'is_visible_on_front' => true,
|
||||
'swatch_type' => null,
|
||||
'use_in_flat' => true,
|
||||
];
|
||||
});
|
||||
|
||||
$factory->state(Attribute::class, 'validation_numeric', [
|
||||
'validation' => 'numeric',
|
||||
]);
|
||||
|
||||
$factory->state(Attribute::class, 'validation_email', [
|
||||
'validation' => 'email',
|
||||
]);
|
||||
|
||||
$factory->state(Attribute::class, 'validation_decimal', [
|
||||
'validation' => 'decimal',
|
||||
]);
|
||||
|
||||
$factory->state(Attribute::class, 'validation_url', [
|
||||
'validation' => 'url',
|
||||
]);
|
||||
|
||||
$factory->state(Attribute::class, 'required', [
|
||||
'is_required' => true,
|
||||
]);
|
||||
|
||||
$factory->state(Attribute::class, 'unique', [
|
||||
'is_unique' => true,
|
||||
]);
|
||||
|
||||
$factory->state(Attribute::class, 'filterable', [
|
||||
'is_filterable' => true,
|
||||
]);
|
||||
|
||||
$factory->state(Attribute::class, 'configurable', [
|
||||
'is_configurable' => true,
|
||||
]);
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
<?php
|
||||
|
||||
/** @var \Illuminate\Database\Eloquent\Factory $factory */
|
||||
|
||||
use Faker\Generator as Faker;
|
||||
use Webkul\Attribute\Models\Attribute;
|
||||
use Webkul\Attribute\Models\AttributeOption;
|
||||
use Webkul\Core\Models\Locale;
|
||||
|
||||
$factory->define(AttributeOption::class, function (Faker $faker, array $attributes) {
|
||||
|
||||
$locales = Locale::pluck('code')->all();
|
||||
|
||||
// array $attributes does not contain any locale code
|
||||
if (count(array_diff_key(array_flip($locales), $attributes) ) === count($locales)) {
|
||||
$localeCode = $locales[0];
|
||||
|
||||
$attributes[$localeCode] = [
|
||||
'label' => $faker->word,
|
||||
];
|
||||
}
|
||||
|
||||
return [
|
||||
'admin_name' => $faker->word,
|
||||
'sort_order' => $faker->randomDigit,
|
||||
'attribute_id' => function () {
|
||||
return factory(Attribute::class)->create()->id;
|
||||
},
|
||||
'swatch_value' => null,
|
||||
];
|
||||
});
|
||||
|
||||
$factory->defineAs(AttributeOption::class, 'swatch_color', function (Faker $faker, array $attributes) {
|
||||
return [
|
||||
'admin_name' => $faker->word,
|
||||
'sort_order' => $faker->randomDigit,
|
||||
'attribute_id' => function () {
|
||||
return factory(Attribute::class)
|
||||
->create(['swatch_type' => 'color'])
|
||||
->id;
|
||||
},
|
||||
'swatch_value' => $faker->hexColor,
|
||||
];
|
||||
});
|
||||
|
||||
$factory->defineAs(AttributeOption::class, 'swatch_image', function (Faker $faker, array $attributes) {
|
||||
return [
|
||||
'admin_name' => $faker->word,
|
||||
'sort_order' => $faker->randomDigit,
|
||||
'attribute_id' => function () {
|
||||
return factory(Attribute::class)
|
||||
->create(['swatch_type' => 'image'])
|
||||
->id;
|
||||
},
|
||||
'swatch_value' => '/tests/_data/ProductImageExampleForUpload.jpg',
|
||||
];
|
||||
});
|
||||
|
||||
$factory->defineAs(AttributeOption::class, 'swatch_dropdown', function (Faker $faker, array $attributes) {
|
||||
return [
|
||||
'admin_name' => $faker->word,
|
||||
'sort_order' => $faker->randomDigit,
|
||||
'attribute_id' => function () {
|
||||
return factory(Attribute::class)
|
||||
->create(['swatch_type' => 'dropdown'])
|
||||
->id;
|
||||
},
|
||||
'swatch_value' => null,
|
||||
];
|
||||
});
|
||||
|
||||
$factory->defineAs(AttributeOption::class, 'swatch_text', function (Faker $faker, array $attributes) {
|
||||
return [
|
||||
'admin_name' => $faker->word,
|
||||
'sort_order' => $faker->randomDigit,
|
||||
'attribute_id' => function () {
|
||||
return factory(Attribute::class)
|
||||
->create(['swatch_type' => 'text'])
|
||||
->id;
|
||||
},
|
||||
'swatch_value' => null,
|
||||
];
|
||||
});
|
||||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace Webkul\Attribute\Providers;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factory as EloquentFactory;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
|
||||
class AttributeServiceProvider extends ServiceProvider
|
||||
|
|
@ -14,6 +15,8 @@ class AttributeServiceProvider extends ServiceProvider
|
|||
public function boot()
|
||||
{
|
||||
$this->loadMigrationsFrom(__DIR__ . '/../Database/Migrations');
|
||||
|
||||
$this->app->make(EloquentFactory::class)->load(__DIR__ . '/../Database/Factories');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -93,8 +93,9 @@ class CustomerController extends Controller
|
|||
'gender' => 'required',
|
||||
'date_of_birth' => 'date|before:today',
|
||||
'email' => 'email|unique:customers,email,'.$id,
|
||||
'password' => 'confirmed|min:6|required_with:oldpassword',
|
||||
'oldpassword' => 'required_with:password',
|
||||
'password' => 'confirmed|min:6'
|
||||
'password_confirmation' => 'required_with:password',
|
||||
]);
|
||||
|
||||
$data = collect(request()->input())->except('_token')->toArray();
|
||||
|
|
@ -139,27 +140,26 @@ class CustomerController extends Controller
|
|||
|
||||
$customerRepository = $this->customerRepository->findorFail($id);
|
||||
|
||||
$orders = $customerRepository->all_orders->whereIn('status', ['pending', 'processing'])->first();
|
||||
|
||||
if ( $orders ) {
|
||||
session()->flash('error', trans('admin::app.response.order-pending'));
|
||||
|
||||
return redirect()->route($this->_config['redirect']);
|
||||
}
|
||||
|
||||
try {
|
||||
if ( Hash::check($data['password'], $customerRepository->password) ) {
|
||||
if (Hash::check($data['password'], $customerRepository->password)) {
|
||||
$orders = $customerRepository->all_orders->whereIn('status', ['pending', 'processing'])->first();
|
||||
|
||||
$this->customerRepository->delete($id);
|
||||
if ($orders) {
|
||||
session()->flash('error', trans('admin::app.response.order-pending'));
|
||||
|
||||
session()->flash('success', trans('admin::app.response.delete-success', ['name' => 'Customer']));
|
||||
return redirect()->route($this->_config['redirect']);
|
||||
} else {
|
||||
$this->customerRepository->delete($id);
|
||||
|
||||
return redirect()->route('customer.session.index');
|
||||
session()->flash('success', trans('admin::app.response.delete-success', ['name' => 'Customer']));
|
||||
|
||||
return redirect()->route('customer.session.index');
|
||||
}
|
||||
} else {
|
||||
session()->flash('error', trans('shop::app.customer.account.address.delete.wrong-password'));
|
||||
}
|
||||
|
||||
return redirect()->route('customer.session.index');
|
||||
return redirect()->back();
|
||||
}
|
||||
} catch(\Exception $e) {
|
||||
session()->flash('error', trans('admin::app.response.delete-failed', ['name' => 'Customer']));
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ class View extends AbstractProduct
|
|||
/**
|
||||
* Returns the visible custom attributes
|
||||
*
|
||||
* @param Product $product
|
||||
* @param Webkul\Product\Models\Product $product
|
||||
* @return integer
|
||||
*/
|
||||
public function getAdditionalData($product)
|
||||
|
|
@ -36,15 +36,23 @@ class View extends AbstractProduct
|
|||
} else if($value) {
|
||||
if ($attribute->type == 'select') {
|
||||
$attributeOption = $attributeOptionReposotory->find($value);
|
||||
if ($attributeOption)
|
||||
$value = $attributeOption->label ?? $attributeOption->admin_name;
|
||||
|
||||
if ($attributeOption) {
|
||||
$value = $attributeOption->label ?? null;
|
||||
|
||||
if (! $value) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
} else if ($attribute->type == 'multiselect' || $attribute->type == 'checkbox') {
|
||||
$lables = [];
|
||||
|
||||
$attributeOptions = $attributeOptionReposotory->findWhereIn('id', explode(",", $value));
|
||||
|
||||
foreach ($attributeOptions as $attributeOption) {
|
||||
$lables[] = $attributeOption->label ?? $attributeOption->admin_name;
|
||||
if ($label = $attributeOption->label) {
|
||||
$lables[] = $label;
|
||||
}
|
||||
}
|
||||
|
||||
$value = implode(", ", $lables);
|
||||
|
|
|
|||
|
|
@ -112,7 +112,7 @@ class ProductRepository extends Repository
|
|||
{
|
||||
$params = request()->input();
|
||||
|
||||
$results = app('Webkul\Product\Repositories\ProductFlatRepository')->scopeQuery(function($query) use($params, $categoryId) {
|
||||
$results = app(ProductFlatRepository::class)->scopeQuery(function($query) use($params, $categoryId) {
|
||||
$channel = request()->get('channel') ?: (core()->getCurrentChannelCode() ?: core()->getDefaultChannelCode());
|
||||
|
||||
$locale = request()->get('locale') ?: app()->getLocale();
|
||||
|
|
@ -212,7 +212,7 @@ class ProductRepository extends Repository
|
|||
*/
|
||||
public function findBySlugOrFail($slug, $columns = null)
|
||||
{
|
||||
$product = app('Webkul\Product\Repositories\ProductFlatRepository')->findOneWhere([
|
||||
$product = app(ProductFlatRepository::class)->findOneWhere([
|
||||
'url_key' => $slug,
|
||||
'locale' => app()->getLocale(),
|
||||
'channel' => core()->getCurrentChannelCode(),
|
||||
|
|
@ -236,7 +236,7 @@ class ProductRepository extends Repository
|
|||
*/
|
||||
public function findBySlug($slug)
|
||||
{
|
||||
return app('Webkul\Product\Repositories\ProductFlatRepository')->findOneWhere([
|
||||
return app(ProductFlatRepository::class)->findOneWhere([
|
||||
'url_key' => $slug,
|
||||
'locale' => app()->getLocale(),
|
||||
'channel' => core()->getCurrentChannelCode(),
|
||||
|
|
@ -250,7 +250,7 @@ class ProductRepository extends Repository
|
|||
*/
|
||||
public function getNewProducts()
|
||||
{
|
||||
$results = app('Webkul\Product\Repositories\ProductFlatRepository')->scopeQuery(function($query) {
|
||||
$results = app(ProductFlatRepository::class)->scopeQuery(function($query) {
|
||||
$channel = request()->get('channel') ?: (core()->getCurrentChannelCode() ?: core()->getDefaultChannelCode());
|
||||
|
||||
$locale = request()->get('locale') ?: app()->getLocale();
|
||||
|
|
@ -275,7 +275,7 @@ class ProductRepository extends Repository
|
|||
*/
|
||||
public function getFeaturedProducts()
|
||||
{
|
||||
$results = app('Webkul\Product\Repositories\ProductFlatRepository')->scopeQuery(function($query) {
|
||||
$results = app(ProductFlatRepository::class)->scopeQuery(function($query) {
|
||||
$channel = request()->get('channel') ?: (core()->getCurrentChannelCode() ?: core()->getDefaultChannelCode());
|
||||
|
||||
$locale = request()->get('locale') ?: app()->getLocale();
|
||||
|
|
@ -300,7 +300,7 @@ class ProductRepository extends Repository
|
|||
*/
|
||||
public function searchProductByAttribute($term)
|
||||
{
|
||||
$results = app('Webkul\Product\Repositories\ProductFlatRepository')->scopeQuery(function($query) use($term) {
|
||||
$results = app(ProductFlatRepository::class)->scopeQuery(function($query) use($term) {
|
||||
$channel = request()->get('channel') ?: (core()->getCurrentChannelCode() ?: core()->getDefaultChannelCode());
|
||||
|
||||
$locale = request()->get('locale') ?: app()->getLocale();
|
||||
|
|
|
|||
|
|
@ -167,7 +167,9 @@ abstract class AbstractType
|
|||
$product->update($data);
|
||||
|
||||
foreach ($product->attribute_family->custom_attributes as $attribute) {
|
||||
if ($attribute->type == 'boolean') {
|
||||
$route = request()->route() ? request()->route()->getName() : "";
|
||||
|
||||
if ($attribute->type == 'boolean' && $route != 'admin.catalog.products.massupdate') {
|
||||
$data[$attribute->code] = isset($data[$attribute->code]) && $data[$attribute->code] ? 1 : 0;
|
||||
}
|
||||
|
||||
|
|
@ -175,7 +177,7 @@ abstract class AbstractType
|
|||
continue;
|
||||
}
|
||||
|
||||
if ($attribute->type == 'date' && $data[$attribute->code] == '') {
|
||||
if ($attribute->type == 'date' && $data[$attribute->code] == '' && $route != 'admin.catalog.products.massupdate') {
|
||||
$data[$attribute->code] = null;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ class DownloadableProductController extends Controller
|
|||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @return \Illuminate\View\View
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function index() {
|
||||
return view($this->_config['view']);
|
||||
|
|
@ -77,7 +77,7 @@ class DownloadableProductController extends Controller
|
|||
}
|
||||
|
||||
$remainingDownloads = $downloadableLinkPurchased->download_bought - ($downloadableLinkPurchased->download_used + 1);
|
||||
|
||||
|
||||
if ($downloadableLinkPurchased->download_bought) {
|
||||
$this->downloadableLinkPurchasedRepository->update([
|
||||
'download_used' => $downloadableLinkPurchased->download_used + 1,
|
||||
|
|
|
|||
|
|
@ -44,8 +44,7 @@ class ReviewController extends Controller
|
|||
public function __construct(
|
||||
ProductRepository $productRepository,
|
||||
ProductReviewRepository $productReviewRepository
|
||||
)
|
||||
{
|
||||
) {
|
||||
$this->productRepository = $productRepository;
|
||||
|
||||
$this->productReviewRepository = $productReviewRepository;
|
||||
|
|
@ -57,15 +56,17 @@ class ReviewController extends Controller
|
|||
* Show the form for creating a new resource.
|
||||
*
|
||||
* @param string $slug
|
||||
* @return \Illuminate\View\View
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function create($slug)
|
||||
{
|
||||
$product = $this->productRepository->findBySlugOrFail($slug);
|
||||
if (auth()->guard('customer')->check() || core()->getConfigData('catalog.products.review.guest_review')) {
|
||||
$product = $this->productRepository->findBySlugOrFail($slug);
|
||||
|
||||
$guest_review = core()->getConfigData('catalog.products.review.guest_review');
|
||||
return view($this->_config['view'], compact('product', 'guest_review'));
|
||||
}
|
||||
|
||||
return view($this->_config['view'], compact('product', 'guest_review'));
|
||||
abort(404);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -103,7 +104,7 @@ class ReviewController extends Controller
|
|||
* Display reviews of particular product.
|
||||
*
|
||||
* @param string $slug
|
||||
* @return \Illuminate\View\View
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function show($slug)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -3,26 +3,26 @@ export const messages = {
|
|||
required : (field) => 'حقل' + field + ' مطلوب',
|
||||
alpha : (field) => field + ' يجب ان يحتوي على حروف فقط',
|
||||
alpha_num : (field) => field + ' قد يحتوي فقط على حروف وارقام',
|
||||
min : (field) => 'الحقل ' + field + ' يجب ان يحتوي على {length} حروف على الأقل',
|
||||
min : (field, length) => 'الحقل ' + field + ' يجب ان يحتوي على ' + length + ' حروف على الأقل',
|
||||
numeric : (field) => field + ' يمكن ان يحتوي فقط على ارقام',
|
||||
oneOf : (field) => 'الحقل ' + field + 'يجب ان يكون قيمة صحيحة',
|
||||
regex : (field) => 'الحقل' + field+ ' غير صحيح',
|
||||
required_if : (field) => 'حقل' + field + ' مطلوب',
|
||||
size : (field) => field + ' يجب ان يكون اقل من {size} كيلوبايت',
|
||||
min_value : (field) => 'قيمة الحقل' + field + ' يجب ان تكون اكبر من {min} او تساويها',
|
||||
size : (field, size) => field + ' يجب ان يكون اقل من ' + size + ' كيلوبايت',
|
||||
min_value : (field, min) => 'قيمة الحقل' + field + ' يجب ان تكون اكبر من ' + min + ' او تساويها',
|
||||
alpha_spaces : (field) => field + ' قد يحتوي فقط على حروف ومسافات',
|
||||
between : (field) => 'قيمة ' +field+ ' يجب ان تكون ما بين {min} و {max}',
|
||||
between : (field, min, max) => 'قيمة ' +field+ ' يجب ان تكون ما بين ' + min + ' و ' + max,
|
||||
confirmed : (field) => field + ' لا يماثل التأكيد',
|
||||
digits : (field) => field + ' يجب ان تحتوي فقط على ارقام والا يزيد عددها عن {length} رقم',
|
||||
dimensions : (field) => field + ' يجب ان تكون بمقاس {width} بكسل في {height} بكسل',
|
||||
digits : (field, length) => field + ' يجب ان تحتوي فقط على ارقام والا يزيد عددها عن ' + length + ' رقم',
|
||||
dimensions : (field, width, height) => field + ' يجب ان تكون بمقاس ' + width + ' بكسل في ' + height + ' بكسل',
|
||||
email : (field) => field + ' يجب ان يكون بريدا اليكتروني صحيح',
|
||||
excluded : (field) => 'الحقل' + field +'غير صحيح',
|
||||
ext : (field) =>'نوع مل'+ field + 'غير صحيح',
|
||||
image : (field) => field + ' يجب ان تكون صورة',
|
||||
integer : (field) => 'الحقل ' +field + ' يجب ان يكون عدداً صحيحاً',
|
||||
length : (field) => 'حقل'+ field + ' يجب الا يزيد عن {length}',
|
||||
max_value : (field) => 'قيمة الحقل '+ field + ' يجب ان تكون اصغر من {min} او تساويها',
|
||||
max : (field) => 'الحقل' + field + 'يجب ان يحتوي على {length} حروف على الأكثر',
|
||||
length : (field, length) => 'حقل'+ field + ' يجب الا يزيد عن ' + length,
|
||||
max_value : (field, min) => 'قيمة الحقل '+ field + ' يجب ان تكون اصغر من ' + min + ' او تساويها',
|
||||
max : (field, length) => 'الحقل' + field + 'يجب ان يحتوي على ' + length + ' حروف على الأكثر',
|
||||
mimes : (field) => 'نوع ملف' + field + 'غير صحيح'
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -300,6 +300,7 @@
|
|||
this_this.current_step = this_this.step_numbers[response.data.jump_to_section];
|
||||
|
||||
shippingMethods = response.data.shippingMethods;
|
||||
paymentMethods = response.data.paymentMethods;
|
||||
|
||||
this_this.getOrderSummary();
|
||||
})
|
||||
|
|
|
|||
|
|
@ -30,6 +30,9 @@
|
|||
<div class="account-table-content" style="width: 50%;">
|
||||
<table style="color: #5E5E5E;">
|
||||
<tbody>
|
||||
{!! view_render_event(
|
||||
'bagisto.shop.customers.account.profile.view.table.before', ['customer' => $customer])
|
||||
!!}
|
||||
<tr>
|
||||
<td>{{ __('shop::app.customer.account.profile.fname') }}</td>
|
||||
<td>{{ $customer->first_name }}</td>
|
||||
|
|
@ -54,6 +57,9 @@
|
|||
<td>{{ __('shop::app.customer.account.profile.email') }}</td>
|
||||
<td>{{ $customer->email }}</td>
|
||||
</tr>
|
||||
{!! view_render_event(
|
||||
'bagisto.shop.customers.account.profile.view.table.after', ['customer' => $customer])
|
||||
!!}
|
||||
|
||||
{{-- @if ($customer->subscribed_to_news_letter == 1)
|
||||
<tr>
|
||||
|
|
|
|||
|
|
@ -19,21 +19,21 @@
|
|||
@else
|
||||
<td>{{ $attribute['admin_name'] }}</td>
|
||||
@endif
|
||||
@if ($attribute['type'] == 'file' && $attribute['value'])
|
||||
<td>
|
||||
<a href="{{ route('shop.product.file.download', [$product->product_id, $attribute['id']])}}">
|
||||
<i class="icon sort-down-icon download"></i>
|
||||
</a>
|
||||
</td>
|
||||
@elseif ($attribute['type'] == 'image' && $attribute['value'])
|
||||
<td>
|
||||
<a href="{{ route('shop.product.file.download', [$product->product_id, $attribute['id']])}}">
|
||||
<img src="{{ Storage::url($attribute['value']) }}" style="height: 20px; width: 20px;"/>
|
||||
</a>
|
||||
</td>
|
||||
@else
|
||||
<td>{{ $attribute['value'] }}</td>
|
||||
@endif
|
||||
@if ($attribute['type'] == 'file' && $attribute['value'])
|
||||
<td>
|
||||
<a href="{{ route('shop.product.file.download', [$product->product_id, $attribute['id']])}}">
|
||||
<i class="icon sort-down-icon download"></i>
|
||||
</a>
|
||||
</td>
|
||||
@elseif ($attribute['type'] == 'image' && $attribute['value'])
|
||||
<td>
|
||||
<a href="{{ route('shop.product.file.download', [$product->product_id, $attribute['id']])}}">
|
||||
<img src="{{ Storage::url($attribute['value']) }}" style="height: 20px; width: 20px;"/>
|
||||
</a>
|
||||
</td>
|
||||
@else
|
||||
<td>{{ $attribute['value'] }}</td>
|
||||
@endif
|
||||
</tr>
|
||||
@endforeach
|
||||
|
||||
|
|
|
|||
|
|
@ -59,6 +59,10 @@
|
|||
data-method="{{ $action['method'] }}"
|
||||
data-action="{{ route($action['route'], $record->{$index}) }}"
|
||||
data-token="{{ csrf_token() }}"
|
||||
|
||||
@if (isset($action['target']))
|
||||
target="{{ $action['target'] }}"
|
||||
@endif
|
||||
|
||||
@if (isset($action['title']))
|
||||
title="{{ $action['title'] }}"
|
||||
|
|
|
|||
|
|
@ -20,10 +20,8 @@
|
|||
|
||||
<script>
|
||||
function finish() {
|
||||
lastIndex = window.location.href.lastIndexOf("/");
|
||||
secondlast = window.location.href.slice(0, lastIndex).lastIndexOf("/");
|
||||
next = window.location.href.slice(0, secondlast);
|
||||
next = window.location.href.split("/installer")[0];
|
||||
next = next.concat('/admin/login');
|
||||
window.location.href = next;
|
||||
}
|
||||
</script>
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,113 @@
|
|||
<?php
|
||||
|
||||
|
||||
namespace Tests\Functional\Product;
|
||||
|
||||
use FunctionalTester;
|
||||
use Faker\Factory;
|
||||
use Webkul\Attribute\Models\Attribute;
|
||||
use Webkul\Attribute\Models\AttributeFamily;
|
||||
use Webkul\Attribute\Models\AttributeOption;
|
||||
use Webkul\Core\Models\Locale;
|
||||
use Webkul\Product\Models\Product;
|
||||
use Webkul\Product\Models\ProductAttributeValue;
|
||||
|
||||
class ProductCest
|
||||
{
|
||||
/** @var Factory $faker */
|
||||
private $faker;
|
||||
|
||||
/** @var Attribute $attributeBrand */
|
||||
private $attributeBrand;
|
||||
/** @var AttributeOption $attributeBrandDefaultOption */
|
||||
private $attributeBrandDefaultOption;
|
||||
/** @var AttributeOption $attributeBrandOption */
|
||||
private $attributeBrandOption;
|
||||
|
||||
public function _before(FunctionalTester $I)
|
||||
{
|
||||
$this->faker = Factory::create();
|
||||
|
||||
$this->attributeBrand = $I->grabRecord(Attribute::class, [
|
||||
'code' => 'brand',
|
||||
'admin_name' => 'Brand',
|
||||
]);
|
||||
|
||||
$locales = Locale::pluck('code')->all();
|
||||
|
||||
$defaultAttributeOptionAttributes = [
|
||||
'attribute_id' => $this->attributeBrand->id,
|
||||
'admin_name' => 'no-brand',
|
||||
'sort_order' => 0,
|
||||
];
|
||||
|
||||
foreach ($locales as $locale) {
|
||||
$defaultAttributeOptionAttributes[$locale] = [
|
||||
'label' => '',
|
||||
];
|
||||
}
|
||||
|
||||
$this->attributeBrandDefaultOption = $I->have(AttributeOption::class,
|
||||
$defaultAttributeOptionAttributes);
|
||||
$this->attributeBrandOption = $I->have(AttributeOption::class, [
|
||||
'attribute_id' => $this->attributeBrand->id,
|
||||
]);
|
||||
|
||||
}
|
||||
|
||||
public function selectEmptyAttributeOptionOnProductCreation(FunctionalTester $I)
|
||||
{
|
||||
$I->loginAsAdmin();
|
||||
|
||||
$I->amOnAdminRoute('admin.catalog.products.create');
|
||||
$I->see(__('admin::app.catalog.products.add-title'), 'h1');
|
||||
|
||||
$I->selectOption('select#type', 'simple');
|
||||
|
||||
$attributeFamily = $I->grabRecord(AttributeFamily::class, [
|
||||
'code' => 'default',
|
||||
]);
|
||||
|
||||
$I->selectOption('select#attribute_family_id', $attributeFamily->id);
|
||||
|
||||
$sku = $this->faker->randomNumber(3);
|
||||
|
||||
$I->fillField('sku', $sku);
|
||||
$I->click(__('admin::app.catalog.products.save-btn-title'));
|
||||
|
||||
$I->seeInSource('Product created successfully.');
|
||||
|
||||
$I->seeCurrentRouteIs('admin.catalog.products.edit');
|
||||
|
||||
$productTitle = $this->faker->word;
|
||||
$productUrlKey = $this->faker->slug;
|
||||
|
||||
$I->fillField('name', $productTitle);
|
||||
$I->fillField('url_key', $productUrlKey);
|
||||
$I->selectOption($this->attributeBrand->code,
|
||||
$this->attributeBrandDefaultOption->id);
|
||||
$I->fillField('price', $this->faker->randomFloat(2));
|
||||
$I->fillField('weight', $this->faker->randomDigit);
|
||||
|
||||
$I->fillField('#short_description', $this->faker->paragraph(1, true));
|
||||
$I->fillField('#description', $this->faker->paragraph(5, true));
|
||||
|
||||
$I->click(__('admin::app.catalog.products.save-btn-title'));
|
||||
|
||||
$I->seeInSource('Product updated successfully.');
|
||||
$I->seeCurrentRouteIs('admin.catalog.products.index');
|
||||
|
||||
$product = $I->grabRecord(Product::class, [
|
||||
'sku' => $sku,
|
||||
'type' => 'simple',
|
||||
'attribute_family_id' => $attributeFamily->id,
|
||||
]);
|
||||
|
||||
$I->seeRecord(ProductAttributeValue::class, [
|
||||
'product_id' => $product->id,
|
||||
'attribute_id' => $this->attributeBrand->id,
|
||||
'integer_value' => $this->attributeBrandDefaultOption->id,
|
||||
'text_value' => null,
|
||||
]);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue