merge remote-tracking branch 'bagisto/master' into small-bugfix-and-tiny-refactoring

This commit is contained in:
Steffen Mahler 2020-01-28 15:51:50 +01:00
commit 0d696c6b1a
121 changed files with 2006 additions and 398 deletions

View File

@ -13,6 +13,7 @@ DB_PORT=3306
DB_DATABASE=bagisto_testing
DB_USERNAME=bagisto
DB_PASSWORD=secret
DB_PREFIX=
BROADCAST_DRIVER=log
CACHE_DRIVER=file

1
.gitignore vendored
View File

@ -7,6 +7,7 @@
/public/js
/public/vendor
/public/themes
/public/fonts
/vendor
/.idea
/.vscode

View File

@ -61,6 +61,7 @@ class GenerateProducts extends Command
try {
$result = $this->generateProduct->create();
} catch (\Exception $e) {
report($e);
continue;
}

1
bin/codecept Symbolic link
View File

@ -0,0 +1 @@
../vendor/bin/codecept

49
bin/test.sh Executable file
View File

@ -0,0 +1,49 @@
#!/bin/bash
printf "### start preparation ###\n"
WORKPATH=$(dirname ${0})
printf ">> workpath is %s\n" ${WORKPATH}
LOG_DIR="${WORKPATH}/../storage/logs/tests"
printf ">> log-dir is %s\n" ${LOG_DIR}
printf ">> create and truncate log dir\n"
mkdir -p ${LOG_DIR}
rm -rf ${LOG_DIR}/*
printf ">> truncate and migrate database\n"
php artisan migrate:fresh --env=testing --quiet
printf "### finish preparation ###\n"
printf "### start tests ###\n"
SUCCESS=1
execSuite() {
${WORKPATH}/../vendor/bin/codecept run ${1} \
--xml report_${1}.xml ${CODECEPT_OPTIONS} | tee ${LOG_DIR}/tests_${1}.log
if [[ ${PIPESTATUS[0]} -ne 0 ]]
then
SUCCESS=0
fi
}
execSuite unit
execSuite functional
if [[ ${?} -ne 0 ]]
then
SUCCESS=0
fi
printf "### finish tests ###\n"
if [[ ${SUCCESS} -eq 1 ]]
then
printf ">> all tests are \e[01;32mgreen\e[0m\n"
exit 0
else
printf ">> at least one test is \e[01;31mred\e[0m\n"
exit 1
fi

View File

@ -21,7 +21,7 @@
"resolve-url-loader": "^3.1.0",
"sass": "^1.24.5",
"sass-loader": "^8.0.2",
"vue": "^2.5.7",
"vue": "^2.6.11",
"vue-template-compiler": "^2.6.11"
},
"dependencies": {

View File

@ -52,7 +52,7 @@ class AddressDataGrid extends DataGrid
$queryBuilder = DB::table('customer_addresses as ca')
->leftJoin('countries', 'ca.country', '=', 'countries.code')
->leftJoin('customers as c', 'ca.customer_id', '=', 'c.id')
->addSelect('ca.id as address_id', 'ca.address1', 'ca.country', DB::raw('' . DB::getTablePrefix() . 'countries.name as country_name'), 'ca.state', 'ca.city', 'ca.postcode', 'ca.phone', 'ca.default_address')
->addSelect('ca.id as address_id', 'ca.company_name', 'ca.vat_id', 'ca.address1', 'ca.country', DB::raw('' . DB::getTablePrefix() . 'countries.name as country_name'), 'ca.state', 'ca.city', 'ca.postcode', 'ca.phone', 'ca.default_address')
->where('c.id', $customer->id);
$queryBuilder = $queryBuilder->leftJoin('country_states', function($qb) {
@ -65,6 +65,8 @@ class AddressDataGrid extends DataGrid
->addSelect(DB::raw(DB::getTablePrefix() . 'country_states.default_name as state_name'));
$this->addFilter('address_id', 'ca.id');
$this->addFilter('company_name', 'ca.company_name');
$this->addFilter('vat_id', 'ca.vat_id');
$this->addFilter('address1', 'ca.address1');
$this->addFilter('city', 'ca.city');
$this->addFilter('state_name', DB::raw(DB::getTablePrefix() . 'country_states.default_name'));
@ -77,6 +79,7 @@ class AddressDataGrid extends DataGrid
public function addColumns()
{
$this->addColumn([
'index' => 'address_id',
'label' => trans('admin::app.customers.addresses.address-id'),
@ -131,6 +134,15 @@ class AddressDataGrid extends DataGrid
'filterable' => true
]);
$this->addColumn([
'index' => 'vat_id',
'label' => trans('admin::app.customers.addresses.vat_id'),
'type' => 'string',
'searchable' => true,
'sortable' => true,
'filterable' => true
]);
$this->addColumn([
'index' => 'default_address',
'label' => trans('admin::app.customers.addresses.default-address'),

View File

@ -135,7 +135,8 @@ class CustomerDataGrid extends DataGrid
'type' => 'Edit',
'method' => 'GET', //use post only for redirects only
'route' => 'admin.customer.addresses.index',
'icon' => 'icon list-icon'
'icon' => 'icon list-icon',
'title' => trans('admin::app.customers.customers.addresses')
]);
$this->addAction([

View File

@ -2,6 +2,7 @@
namespace Webkul\Admin\Http\Controllers\Customer;
use Webkul\Customer\Rules\VatIdRule;
use Webkul\Admin\Http\Controllers\Controller;
use Webkul\Customer\Repositories\CustomerRepository as Customer;
use Webkul\Customer\Repositories\CustomerAddressRepository as CustomerAddress;
@ -20,25 +21,26 @@ class AddressController extends Controller
* @var array
*/
protected $_config;
/**
* Customer Repository object
*
* @var object
*/
*/
protected $customer;
/**
* CustomerAddress Repository object
*
* @var object
*/
*/
protected $customerAddress;
/**
* Create a new controller instance.
*
* @param Webkul\Customer\Repositories\CustomerAddressRepository $customerAddress
* @param Webkul\Customer\Repositories\CustomerAddressRepository $customerAddress
*
* @return void
*/
public function __construct(
@ -59,7 +61,7 @@ class AddressController extends Controller
* @return Mixed
*/
public function index($id)
{
{
$customer = $this->customer->find($id);
return view($this->_config['view'], compact('customer'));
@ -84,20 +86,24 @@ class AddressController extends Controller
*/
public function store()
{
request()->merge(['address1' => implode(PHP_EOL, array_filter(request()->input('address1')))]);
request()->merge([
'address1' => implode(PHP_EOL, array_filter(request()->input('address1'))),
]);
$data = collect(request()->input())->except('_token')->toArray();
$this->validate(request(), [
'address1' => 'string|required',
'country' => 'string|required',
'state' => 'string|required',
'city' => 'string|required',
'postcode' => 'required',
'phone' => 'required'
'company_name' => 'string',
'address1' => 'string|required',
'country' => 'string|required',
'state' => 'string|required',
'city' => 'string|required',
'postcode' => 'required',
'phone' => 'required',
'vat_id' => new VatIdRule(),
]);
if ( $this->customerAddress->create($data) ) {
if ($this->customerAddress->create($data)) {
session()->flash('success', trans('admin::app.customers.addresses.success-create'));
return redirect()->route('admin.customer.addresses.index', ['id' => $data['customer_id']]);
@ -131,19 +137,21 @@ class AddressController extends Controller
request()->merge(['address1' => implode(PHP_EOL, array_filter(request()->input('address1')))]);
$this->validate(request(), [
'address1' => 'string|required',
'country' => 'string|required',
'state' => 'string|required',
'city' => 'string|required',
'postcode' => 'required',
'phone' => 'required'
'company_name' => 'string',
'address1' => 'string|required',
'country' => 'string|required',
'state' => 'string|required',
'city' => 'string|required',
'postcode' => 'required',
'phone' => 'required',
'vat_id' => new VatIdRule(),
]);
$data = collect(request()->input())->except('_token')->toArray();
$address = $this->customerAddress->find($id);
if ( $address ) {
if ($address) {
$this->customerAddress->update($data, $id);
@ -157,7 +165,8 @@ class AddressController extends Controller
/**
* Remove the specified resource from storage.
*
* @param int $id
* @param int $id
*
* @return \Illuminate\Http\Response
*/
public function destroy($id)

View File

@ -31,14 +31,14 @@ class CustomerController extends Controller
*/
protected $customerRepository;
/**
/**
* CustomerGroupRepository object
*
* @var array
*/
protected $customerGroupRepository;
/**
/**
* ChannelRepository object
*
* @var array
@ -74,13 +74,13 @@ class CustomerController extends Controller
* Display a listing of the resource.
*
* @return \Illuminate\View\View
*/
*/
public function index()
{
return view($this->_config['view']);
}
/**
/**
* Show the form for creating a new resource.
*
* @return \Illuminate\View\View
@ -91,10 +91,10 @@ class CustomerController extends Controller
$channelName = $this->channelRepository->all();
return view($this->_config['view'], compact('customerGroup','channelName'));
return view($this->_config['view'], compact('customerGroup', 'channelName'));
}
/**
/**
* Store a newly created resource in storage.
*
* @return \Illuminate\Http\Response
@ -102,16 +102,16 @@ class CustomerController extends Controller
public function store()
{
$this->validate(request(), [
'first_name' => 'string|required',
'last_name' => 'string|required',
'gender' => 'required',
'email' => 'required|unique:customers,email',
'date_of_birth' => 'date|before:today'
'first_name' => 'string|required',
'last_name' => 'string|required',
'gender' => 'required',
'email' => 'required|unique:customers,email',
'date_of_birth' => 'date|before:today',
]);
$data = request()->all();
$password = rand(100000,10000000);
$password = rand(100000, 10000000);
$data['password'] = bcrypt($password);
@ -122,7 +122,7 @@ class CustomerController extends Controller
try {
Mail::queue(new NewCustomerNotification($customer, $password));
} catch (\Exception $e) {
report($e);
}
session()->flash('success', trans('admin::app.response.create-success', ['name' => 'Customer']));
@ -133,7 +133,8 @@ class CustomerController extends Controller
/**
* Show the form for editing the specified resource.
*
* @param int $id
* @param int $id
*
* @return \Illuminate\View\View
*/
public function edit($id)
@ -147,20 +148,21 @@ class CustomerController extends Controller
return view($this->_config['view'], compact('customer', 'customerGroup', 'channelName'));
}
/**
/**
* Update the specified resource in storage.
*
* @param int $id
* @param int $id
*
* @return \Illuminate\Http\Response
*/
public function update($id)
{
$this->validate(request(), [
'first_name' => 'string|required',
'last_name' => 'string|required',
'gender' => 'required',
'email' => 'required|unique:customers,email,'. $id,
'date_of_birth' => 'date|before:today'
'first_name' => 'string|required',
'last_name' => 'string|required',
'gender' => 'required',
'email' => 'required|unique:customers,email,' . $id,
'date_of_birth' => 'date|before:today',
]);
$this->customerRepository->update(request()->all(), $id);
@ -173,7 +175,8 @@ class CustomerController extends Controller
/**
* Remove the specified resource from storage.
*
* @param int $id
* @param int $id
*
* @return \Illuminate\Http\Response
*/
public function destroy($id)
@ -186,7 +189,7 @@ class CustomerController extends Controller
session()->flash('success', trans('admin::app.response.delete-success', ['name' => 'Customer']));
return response()->json(['message' => true], 200);
} catch(\Exception $e) {
} catch (\Exception $e) {
session()->flash('error', trans('admin::app.response.delete-failed', ['name' => 'Customer']));
}
@ -213,13 +216,13 @@ class CustomerController extends Controller
public function storeNote()
{
$this->validate(request(), [
'notes' => 'string|nullable'
'notes' => 'string|nullable',
]);
$customer = $this->customerRepository->find(request()->input('_customer'));
$noteTaken = $customer->update([
'notes' => request()->input('notes')
'notes' => request()->input('notes'),
]);
if ($noteTaken) {
@ -245,7 +248,7 @@ class CustomerController extends Controller
$customer = $this->customerRepository->find($customerId);
$customer->update([
'status' => $updateOption
'status' => $updateOption,
]);
}
@ -265,7 +268,7 @@ class CustomerController extends Controller
foreach ($customerIds as $customerId) {
$this->customerRepository->deleteWhere([
'id' => $customerId
'id' => $customerId,
]);
}

View File

@ -10,13 +10,15 @@ use Webkul\Admin\Mail\NewShipmentNotification;
use Webkul\Admin\Mail\NewInventorySourceNotification;
use Webkul\Admin\Mail\CancelOrderNotification;
use Webkul\Admin\Mail\NewRefundNotification;
/**
* Order event handler
*
* @author Jitendra Singh <jitendra@webkul.com>
* @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com)
*/
class Order {
class Order
{
/**
* @param mixed $order
@ -30,7 +32,7 @@ class Order {
Mail::queue(new NewAdminNotification($order));
} catch (\Exception $e) {
report($e);
}
}
@ -42,12 +44,13 @@ class Order {
public function sendNewInvoiceMail($invoice)
{
try {
if ($invoice->email_sent)
if ($invoice->email_sent) {
return;
}
Mail::queue(new NewInvoiceNotification($invoice));
} catch (\Exception $e) {
report($e);
}
}
@ -61,7 +64,7 @@ class Order {
try {
Mail::queue(new NewRefundNotification($refund));
} catch (\Exception $e) {
report($e);
}
}
@ -73,25 +76,28 @@ class Order {
public function sendNewShipmentMail($shipment)
{
try {
if ($shipment->email_sent)
if ($shipment->email_sent) {
return;
}
Mail::queue(new NewShipmentNotification($shipment));
Mail::queue(new NewInventorySourceNotification($shipment));
} catch (\Exception $e) {
report($e);
}
}
/*
/**
* @param mixed $order
* */
public function sendCancelOrderMail($order){
try{
*
*/
public function sendCancelOrderMail($order)
{
try {
Mail::queue(new CancelOrderNotification($order));
}catch (\Exception $e){
\Log::error('Error occured when sending email '.$e->getMessage());
} catch (\Exception $e) {
report($e);
}
}
}

View File

@ -760,10 +760,19 @@ return [
'state' => 'State',
'select-state' => 'اختر منطقة أو ولاية أو مقاطعة.',
'country' => 'Country',
'other' => 'Other',
'male' => 'Male',
'female' => 'Female',
'phone' => 'Phone',
'group-default' => 'لا يستطيع حذف افتراضي المجموعة.',
'edit-help-title' => 'Edit Customer',
'delete-help-title' => 'Delete Customer',
'addresses' => 'Addresses',
'mass-destroy-success' => 'Customers deleted successfully',
'mass-update-success' => 'Customers updated successfully',
'status' => 'Status',
'active' => 'Active',
'in-active' => 'Inactive'
],
'reviews' => [
'title' => 'باء-الاستعراضات',

View File

@ -334,7 +334,7 @@ return [
'item-status' => 'Item Status',
'item-ordered' => 'Ordered (:qty_ordered)',
'item-invoice' => 'Invoiced (:qty_invoiced)',
'item-shipped' => 'shipped (:qty_shipped)',
'item-shipped' => 'Shipped (:qty_shipped)',
'item-canceled' => 'Canceled (:qty_canceled)',
'item-refunded' => 'Refunded (:qty_refunded)',
'price' => 'Price',
@ -867,6 +867,7 @@ return [
'addresses' => [
'title' => ':customer_name\'s Addresses List',
'vat_id' => 'Vat id',
'create-title' => 'Create Customer\'s Address',
'edit-title' => 'Update Customer\'s Address',
'title-orders' => ':customer_name\'s Orders List',
@ -917,12 +918,14 @@ return [
'state' => 'State',
'select-state' => 'Select a region, state or province.',
'country' => 'Country',
'other' => 'Other',
'male' => 'Male',
'female' => 'Female',
'phone' => 'Phone',
'group-default' => 'Cannot delete the default group.',
'edit-help-title' => 'Edit Customer',
'delete-help-title' => 'Delete Customer',
'addresses' => 'Addresses',
'mass-destroy-success' => 'Customers deleted successfully',
'mass-update-success' => 'Customers updated successfully',
'status' => 'Status',

View File

@ -802,11 +802,13 @@ return [
'state' => 'استان',
'select-state' => 'یک منطقه ، ایالت یا استان را انتخاب کنید.',
'country' => 'کشور',
'other' => 'Other',
'male' => 'مرد',
'female' => 'زن',
'group-default' => 'نمی توان گروه پیش فرض را حذف کرد.',
'edit-help-title' => 'ویرایش مشتری',
'delete-help-title' => 'حذف مشتری',
'addresses' => 'Addresses',
'mass-destroy-success' => 'مشتریان با موفقیت حذف شدند',
'mass-update-success' => 'مشتریان با موفقیت به روز شدند',
'status' => 'وضعیت',

View File

@ -791,12 +791,14 @@ return [
'state' => 'Estado',
'select-state' => 'Selecione uma região, estado ou província.',
'country' => 'País',
'other' => 'Other',
'male' => 'Masculino',
'female' => 'Feminino',
'phone' => 'Telefone',
'group-default' => 'Não possível excluir o grupo de cliente.',
'edit-help-title' => 'Editar cliente',
'delete-help-title' => 'Excluir cliente',
'addresses' => 'Addresses',
'mass-destroy-success' => 'Clientes excluídos com sucesso',
'mass-update-success' => 'Clientes atualizados com sucesso',
'status' => 'Status',

View File

@ -39,7 +39,7 @@
<div class="control-group" :class="[errors.has('name') ? 'has-error' : '']">
<label for="name" class="required">{{ __('admin::app.catalog.categories.name') }}</label>
<input type="text" v-validate="'required'" class="control" id="name" name="name" value="{{ old('name') }}" data-vv-as="&quot;{{ __('admin::app.catalog.categories.name') }}&quot;"/>
<input type="text" v-validate="'required'" class="control" id="name" name="name" value="{{ old('name') }}" data-vv-as="&quot;{{ __('admin::app.catalog.categories.name') }}&quot;" v-slugify-target="'slug'"/>
<span class="control-error" v-if="errors.has('name')">@{{ errors.first('name') }}</span>
</div>
@ -96,7 +96,7 @@
<description></description>
<div class="control-group {!! $errors->has('image.*') ? 'has-error' : '' !!}">
<label>{{ __('admin::app.catalog.categories.image') }}
<label>{{ __('admin::app.catalog.categories.image') }}</label>
<image-wrapper :button-label="'{{ __('admin::app.catalog.products.add-image-btn-title') }}'" input-name="image" :multiple="false"></image-wrapper>

View File

@ -52,7 +52,7 @@
<div class="control-group" :class="[errors.has('{{$locale}}[name]') ? 'has-error' : '']">
<label for="name" class="required">{{ __('admin::app.catalog.categories.name') }}</label>
<input type="text" v-validate="'required'" class="control" id="name" name="{{$locale}}[name]" value="{{ old($locale)['name'] ?? $category->translate($locale)['name'] }}" data-vv-as="&quot;{{ __('admin::app.catalog.categories.name') }}&quot;"/>
<input type="text" v-validate="'required'" class="control" id="name" name="{{$locale}}[name]" value="{{ old($locale)['name'] ?? $category->translate($locale)['name'] }}" data-vv-as="&quot;{{ __('admin::app.catalog.categories.name') }}&quot;" v-slugify-target="'slug'"/>
<span class="control-error" v-if="errors.has('{{$locale}}[name]')">@{{ errors.first('{!!$locale!!}[name]') }}</span>
</div>
@ -109,7 +109,7 @@
<description></description>
<div class="control-group {!! $errors->has('image.*') ? 'has-error' : '' !!}">
<label>{{ __('admin::app.catalog.categories.image') }}
<label>{{ __('admin::app.catalog.categories.image') }}</label>
<image-wrapper :button-label="'{{ __('admin::app.catalog.products.add-image-btn-title') }}'" input-name="image" :multiple="false" :images='"{{ $category->image_url }}"'></image-wrapper>

View File

@ -304,6 +304,7 @@
this.bundle_option_products.push({
product: item,
qty: 0,
is_default: 0,
sort_order: 0
});
}
@ -348,9 +349,9 @@
this.bundle_option_products.forEach(function(product) {
if (this_this.bundleOption.type == 'radio' || this_this.bundleOption.type == 'select') {
product.is_default = product.id == productId ? 1 : 0;
product.is_default = product.product.id == productId ? 1 : 0;
} else {
if (product.id == productId)
if (product.product.id == productId)
product.is_default = product.is_default ? 0 : 1;
}
});
@ -381,7 +382,7 @@
},
checkProduct: function($event) {
this.$emit('onCheckProduct', this.product.id)
this.$emit('onCheckProduct', this.product.product.id)
}
}
});

View File

@ -1 +1,4 @@
<input type="text" v-validate="'{{$validations}}'" class="control" id="{{ $attribute->code }}" name="{{ $attribute->code }}" value="{{ old($attribute->code) ?: $product[$attribute->code] }}" data-vv-as="&quot;{{ $attribute->admin_name }}&quot;" {{ in_array($attribute->code, ['sku', 'url_key']) ? 'v-slugify' : '' }}/>
<input type="text" v-validate="'{{$validations}}'" class="control" id="{{ $attribute->code }}" name="{{ $attribute->code }}" value="{{ old($attribute->code) ?: $product[$attribute->code] }}" {{ in_array($attribute->code, ['sku', 'url_key']) ? 'v-slugify' : '' }} data-vv-as="&quot;{{ $attribute->admin_name }}&quot;" {{ $attribute->code == 'name' ? 'v-slugify-target=\'url_key\'' : '' }} />

View File

@ -301,6 +301,8 @@
@push('scripts')
<?php if ($field['type'] == 'country'): ?>
<script type="text/x-template" id="country-template">
<div>
@ -404,6 +406,8 @@
});
</script>
<?php endif; ?>
<script type="text/x-template" id="depends-template">
<div class="control-group" :class="[errors.has(name) ? 'has-error' : '']" v-if="this.isVisible">

View File

@ -36,6 +36,18 @@
<accordian :title="'{{ __('admin::app.customers.addresses.general') }}'" :active="true">
<div slot="body">
<div class="control-group" :class="[errors.has('company_name') ? 'has-error' : '']">
<label for="company_name">{{ __('shop::app.customer.account.address.create.company_name') }}</label>
<input type="text" class="control" name="company_name" value="{{ old('company_name') }}" data-vv-as="&quot;{{ __('shop::app.customer.account.address.create.company_name') }}&quot;">
<span class="control-error" v-if="errors.has('company_name')">@{{ errors.first('company_name') }}</span>
</div>
<div class="control-group" :class="[errors.has('vat_id') ? 'has-error' : '']">
<label for="vat_id">{{ __('shop::app.customer.account.address.create.vat_id') }}</label>
<input type="text" class="control" name="vat_id" value="{{ old('vat_id') }}" data-vv-as="&quot;{{ __('shop::app.customer.account.address.create.vat_id') }}&quot;">
<span class="control-error" v-if="errors.has('vat_id')">@{{ errors.first('vat_id') }}</span>
</div>
<div class="control-group" :class="[errors.has('address1[]') ? 'has-error' : '']">
<label for="address_0" class="required">{{ __('shop::app.customer.account.address.edit.street-address') }}</label>
<input type="text" class="control" name="address1[]" id="address_0" v-validate="'required'" value="{{ old('address1') }}" data-vv-as="&quot;{{ __('shop::app.customer.account.address.create.street-address') }}&quot;">

View File

@ -15,17 +15,17 @@
<div class="page-title">
<h1>{{ __('admin::app.customers.addresses.edit-title') }}</h1>
</div>
<div class="page-action">
<button type="submit" class="btn btn-primary btn-lg">
{{ __('admin::app.customers.addresses.save-btn-title') }}
</button>
</div>
</div>
<div class="page-content">
@csrf()
<input type="hidden" name="_method" value="PUT">
<input type="hidden" name="customer_id" value="{{ $address->customer_id }}">
@ -35,6 +35,18 @@
<?php $addresses = explode(PHP_EOL, $address->address1); ?>
<div class="control-group" :class="[errors.has('company_name') ? 'has-error' : '']">
<label for="company_name">{{ __('shop::app.customer.account.address.create.company_name') }}</label>
<input type="text" class="control" name="company_name" value="{{ $address->company_name }}" data-vv-as="&quot;{{ __('shop::app.customer.account.address.create.company_name') }}&quot;">
<span class="control-error" v-if="errors.has('company_name')">@{{ errors.first('company_name') }}</span>
</div>
<div class="control-group" :class="[errors.has('vat_id') ? 'has-error' : '']">
<label for="vat_id">{{ __('shop::app.customer.account.address.create.vat_id') }}</label>
<input type="text" class="control" name="vat_id" value="{{ $address->vat_id }}" data-vv-as="&quot;{{ __('shop::app.customer.account.address.create.vat_id') }}&quot;">
<span class="control-error" v-if="errors.has('vat_id')">@{{ errors.first('vat_id') }}</span>
</div>
<div class="control-group" :class="[errors.has('address1[]') ? 'has-error' : '']">
<label for="address_0" class="required">{{ __('shop::app.customer.account.address.edit.street-address') }}</label>
<input type="text" class="control" name="address1[]" id="address_0" v-validate="'required'" value="{{ isset($addresses[0]) ? $addresses[0] : '' }}" data-vv-as="&quot;{{ __('shop::app.customer.account.address.create.street-address') }}&quot;">
@ -51,11 +63,11 @@
<div class="control-group" :class="[errors.has('city') ? 'has-error' : '']">
<label for="city" class="required">{{ __('shop::app.customer.account.address.create.city') }}</label>
<input type="text" class="control" name="city" v-validate="'required|alpha_spaces'" value="{{ $address->city }}" data-vv-as="&quot;{{ __('shop::app.customer.account.address.create.city') }}&quot;">
<input type="text" class="control" name="city" v-validate="'required'" value="{{ $address->city }}" data-vv-as="&quot;{{ __('shop::app.customer.account.address.create.city') }}&quot;">
<span class="control-error" v-if="errors.has('city')">@{{ errors.first('city') }}</span>
</div>
@include ('shop::customers.account.address.country-state', ['countryCode' => old('country') ?? $address->country, 'stateCode' => old('state') ?? $address->state])
@include ('admin::customers.country-state', ['countryCode' => old('country') ?? $address->country, 'stateCode' => old('state') ?? $address->state])
<div class="control-group" :class="[errors.has('postcode') ? 'has-error' : '']">
<label for="postcode" class="required">{{ __('shop::app.customer.account.address.create.postcode') }}</label>

View File

@ -52,6 +52,7 @@
<div class="control-group" :class="[errors.has('gender') ? 'has-error' : '']">
<label for="gender" class="required">{{ __('admin::app.customers.customers.gender') }}</label>
<select name="gender" class="control" v-validate="'required'" data-vv-as="&quot;{{ __('shop::app.customers.customers.gender') }}&quot;">
<option value="Other">{{ __('admin::app.customers.customers.other') }}</option>
<option value="Male">{{ __('admin::app.customers.customers.male') }}</option>
<option value="Female">{{ __('admin::app.customers.customers.female') }}</option>
</select>

View File

@ -58,6 +58,7 @@
<div class="control-group">
<label for="gender" class="required">{{ __('admin::app.customers.customers.gender') }}</label>
<select name="gender" class="control" value="{{ $customer->gender }}" v-validate="'required'" data-vv-as="&quot;{{ __('shop::app.customers.customers.gender') }}&quot;">
<option value="Other" {{ $customer->gender == "Other" ? 'selected' : '' }}>{{ __('admin::app.customers.customers.other') }}</option>
<option value="Male" {{ $customer->gender == "Male" ? 'selected' : '' }}>{{ __('admin::app.customers.customers.male') }}</option>
<option value="Female" {{ $customer->gender == "Female" ? 'selected' : '' }}>{{ __('admin::app.customers.customers.female') }}</option>
</select>

View File

@ -160,13 +160,13 @@
</div>
<div class="control-group">
<label>{{ __('admin::app.settings.channels.logo') }}
<label>{{ __('admin::app.settings.channels.logo') }}</label>
<image-wrapper :button-label="'{{ __('admin::app.catalog.products.add-image-btn-title') }}'" input-name="logo" :multiple="false"></image-wrapper>
</div>
<div class="control-group">
<label>{{ __('admin::app.settings.channels.favicon') }}
<label>{{ __('admin::app.settings.channels.favicon') }}</label>
<image-wrapper :button-label="'{{ __('admin::app.catalog.products.add-image-btn-title') }}'" input-name="logo" :multiple="false"></image-wrapper>
</div>

View File

@ -171,13 +171,13 @@
</div>
<div class="control-group">
<label>{{ __('admin::app.settings.channels.logo') }}
<label>{{ __('admin::app.settings.channels.logo') }}</label>
<image-wrapper :button-label="'{{ __('admin::app.catalog.products.add-image-btn-title') }}'" input-name="logo" :multiple="false" :images='"{{ $channel->logo_url }}"'></image-wrapper>
</div>
<div class="control-group">
<label>{{ __('admin::app.settings.channels.favicon') }}
<label>{{ __('admin::app.settings.channels.favicon') }}</label>
<image-wrapper :button-label="'{{ __('admin::app.catalog.products.add-image-btn-title') }}'" input-name="favicon" :multiple="false" :images='"{{ $channel->favicon_url }}"'></image-wrapper>
</div>

View File

@ -47,8 +47,8 @@
<div class="control-group" :class="[errors.has('direction') ? 'has-error' : '']">
<label for="direction" class="required">{{ __('admin::app.settings.locales.direction') }}</label>
<select v-validate="'required'" class="control" id="direction" name="direction" data-vv-as="&quot;{{ __('admin::app.settings.locales.direction') }}&quot;">
<option value="ltr" selected title="Text direction left to right">ltr</option>
<option value="rtl" title="Text direction right to left">rtl</option>
<option value="ltr" selected title="Text direction left to right">LTR</option>
<option value="rtl" title="Text direction right to left">RTL</option>
</select>
<span class="control-error" v-if="errors.has('direction')">@{{ errors.first('direction') }}</span>
</div>

View File

@ -51,8 +51,8 @@
<div class="control-group" :class="[errors.has('direction') ? 'has-error' : '']">
<label for="direction" class="required">{{ __('admin::app.settings.locales.direction') }}</label>
<select v-validate="'required'" class="control" id="direction" name="direction" data-vv-as="&quot;{{ __('admin::app.settings.locales.direction') }}&quot;">
<option value="ltr" {{ old('direction') == 'ltr' ? 'selected' : '' }} title="Text direction left to right">ltr</option>
<option value="rtl" {{ old('direction') == 'rtl' ? 'selected' : '' }} title="Text direction right to left">rtl</option>
<option value="ltr" {{ (old('direction') ?: $locale->direction) == 'ltr' ? 'selected' : '' }}>LTR</option>
<option value="rtl" {{ (old('direction') ?: $locale->direction) == 'rtl' ? 'selected' : '' }}>RTL</option>
</select>
<span class="control-error" v-if="errors.has('direction')">@{{ errors.first('direction') }}</span>
</div>

View File

@ -0,0 +1,15 @@
<?php
/** @var \Illuminate\Database\Eloquent\Factory $factory */
use Faker\Generator as Faker;
use Webkul\Attribute\Models\AttributeFamily;
$factory->define(AttributeFamily::class, function (Faker $faker) {
return [
'name' => $faker->word(),
'code' => $faker->word(),
'is_user_defined' => rand(0, 1),
'status' => 0,
];
});

View File

@ -167,6 +167,7 @@ class AttributeController extends Controller
$this->attributeRepository->delete($value);
}
} catch (\Exception $e) {
report($e);
$suppressFlash = true;
continue;

View File

@ -154,7 +154,8 @@ class AttributeFamilyController extends Controller
return response()->json(['message' => true], 200);
} catch (\Exception $e) {
session()->flash('error', trans( 'admin::app.response.delete-failed', ['name' => 'Family']));
report($e);
session()->flash('error', trans('admin::app.response.delete-failed', ['name' => 'Family']));
}
}
@ -177,16 +178,18 @@ class AttributeFamilyController extends Controller
try {
$this->attributeFamilyRepository->delete($value);
} catch (\Exception $e) {
report($e);
$suppressFlash = true;
continue;
}
}
if (! $suppressFlash)
if (!$suppressFlash) {
session()->flash('success', ('admin::app.datagrid.mass-ops.delete-success'));
else
} else {
session()->flash('info', trans('admin::app.datagrid.mass-ops.partial-action', ['resource' => 'Attribute Family']));
}
return redirect()->back();
} else {

View File

@ -144,7 +144,7 @@ class AttributeRepository extends Repository
$data['value_per_channel'] = $data['value_per_locale'] = 0;
}
if (! in_array($data['type'], ['select', 'multiselect', 'price'])) {
if (! in_array($data['type'], ['select', 'multiselect', 'price', 'checkbox'])) {
$data['is_filterable'] = 0;
}

View File

@ -65,7 +65,7 @@ class CatalogRuleIndex
$this->catalogRuleProductPriceHelper->indexRuleProductPrice(1000);
} catch (\Exception $e) {
report($e);
}
}
@ -80,7 +80,7 @@ class CatalogRuleIndex
try {
if (! $product->getTypeInstance()->priceRuleCanBeApplied())
return;
$productIds = $product->getTypeInstance()->isComposite()
? $product->getTypeInstance()->getChildrenIds()
: [$product->id];
@ -93,7 +93,7 @@ class CatalogRuleIndex
$this->catalogRuleProductPriceHelper->indexRuleProductPrice(1000, $product);
} catch (\Exception $e) {
report($e);
}
}

View File

@ -0,0 +1,14 @@
<?php
/** @var \Illuminate\Database\Eloquent\Factory $factory */
use Faker\Generator as Faker;
use Webkul\Core\Models\SubscribersList;
$factory->define(SubscribersList::class, function (Faker $faker) {
return [
'email' => $faker->safeEmail,
'is_subscribed' => $faker->boolean,
'channel_id' => 1,
];
});

View File

@ -0,0 +1,52 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class AddApiTokenColumns extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
// @see https://laravel.com/docs/6.x/api-authentication#database-preparation
Schema::table('customers', function ($table) {
$table
->string('api_token', 80)
->after('password')
->unique()
->nullable()
->default(null);
});
Schema::table('admins', function ($table) {
$table
->string('api_token', 80)
->after('password')
->unique()
->nullable()
->default(null);
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('customers', function (Blueprint $table) {
$table->dropColumn('api_token');
});
Schema::table('admins', function (Blueprint $table) {
$table->dropColumn('api_token');
});
}
}

View File

@ -144,6 +144,7 @@ class CurrencyController extends Controller
return response()->json(['message' => true], 200);
} catch (\Exception $e) {
report($e);
session()->flash('error', trans('admin::app.response.delete-failed', ['name' => 'Currency']));
}
}

View File

@ -200,6 +200,7 @@ class ExchangeRateController extends Controller
return response()->json(['message' => true], 200);
} catch (\Exception $e) {
report($e);
session()->flash('error', trans('admin::app.response.delete-error', ['name' => 'Exchange rate']));
}
}

View File

@ -104,6 +104,7 @@ class SubscriptionController extends Controller
return response()->json(['message' => true], 200);
} catch (\Exception $e) {
report($e);
session()->flash('error', trans('admin::app.response.delete-failed', ['name' => 'Subscriber']));
}

View File

@ -24,6 +24,8 @@ class CoreServiceProvider extends ServiceProvider
$this->loadMigrationsFrom(__DIR__ . '/../Database/Migrations');
$this->registerEloquentFactoriesFrom(__DIR__ . '/../Database/Factories');
$this->loadTranslationsFrom(__DIR__ . '/../Resources/lang', 'core');
Validator::extend('slug', 'Webkul\Core\Contracts\Validations\Slug@passes');
@ -37,8 +39,6 @@ class CoreServiceProvider extends ServiceProvider
]);
SliderProxy::observe(SliderObserver::class);
$this->registerEloquentFactoriesFrom(__DIR__ . '/../Database/Factories');
}
/**
@ -50,6 +50,7 @@ class CoreServiceProvider extends ServiceProvider
{
$this->registerFacades();
}
/**
* Register Bouncer as a singleton.
*
@ -68,11 +69,12 @@ class CoreServiceProvider extends ServiceProvider
/**
* Register factories.
*
* @param string $path
* @param string $path
*
* @return void
*/
protected function registerEloquentFactoriesFrom($path): void
{
$this->app->make(EloquentFactory::class)->load($path);
}
}
}

View File

@ -0,0 +1,36 @@
<?php
/** @var \Illuminate\Database\Eloquent\Factory $factory */
use Faker\Generator as Faker;
use Webkul\Customer\Models\Customer;
use Webkul\Customer\Models\CustomerAddress;
$factory->define(CustomerAddress::class, function (Faker $faker) {
$now = date("Y-m-d H:i:s");
// use an locale from a country in europe so the vat id can be generated
$fakerIt = \Faker\Factory::create('it_IT');
return [
'customer_id' => function () {
return factory(Customer::class)->create()->id;
},
'company_name' => $faker->company,
'vat_id' => $fakerIt->vatId(),
'first_name' => $faker->firstName,
'last_name' => $faker->lastName,
'address1' => $faker->streetAddress,
'country' => $faker->countryCode,
'state' => $faker->state,
'city' => $faker->city,
'postcode' => $faker->postcode,
'phone' => $faker->e164PhoneNumber,
'default_address' => array_random([0, 1]),
'created_at' => $now,
'updated_at' => $now,
];
});

View File

@ -0,0 +1,34 @@
<?php
/** @var \Illuminate\Database\Eloquent\Factory $factory */
use Faker\Generator as Faker;
use Illuminate\Support\Facades\Hash;
use Webkul\Customer\Models\Customer;
$factory->define(Customer::class, function (Faker $faker) {
$now = date("Y-m-d H:i:s");
$gender = array_rand(['male', 'female', 'other']);
$password = $faker->password;
return [
'first_name' => $faker->firstName($gender),
'last_name' => $faker->lastName,
'gender' => ucfirst($gender),
'email' => $faker->email,
'status' => 1,
'password' => Hash::make($password),
'customer_group_id' => 2,
'is_verified' => 1,
'created_at' => $now,
'updated_at' => $now,
'notes' => json_encode(array('plain_password' => $password)),
];
});
$factory->state(Customer::class, 'male', [
'gender' => 'Male',
]);
$factory->state(Customer::class, 'female', [
'gender' => 'Female',
]);

View File

@ -0,0 +1,15 @@
<?php
/** @var \Illuminate\Database\Eloquent\Factory $factory */
use Faker\Generator as Faker;
use Webkul\Customer\Models\CustomerGroup;
$factory->define(CustomerGroup::class, function (Faker $faker) {
$name = ucfirst($faker->word);
return [
'name' => $name,
'is_user_defined' => $faker->boolean,
'code' => lcfirst($name),
];
});

View File

@ -0,0 +1,44 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CustomerAddressImprovements extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('customer_addresses', function (Blueprint $table) {
$table->string('company_name')->nullable()->after('customer_id');
$table->string('vat_id')->nullable()->after('company_name');
});
Schema::table('orders', function (Blueprint $table) {
$table->string('customer_company_name')->nullable()->after('customer_last_name');
$table->string('customer_vat_id')->nullable()->after('customer_company_name');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('customer_addresses', function (Blueprint $table) {
$table->dropColumn('company_name');
$table->dropColumn('vat_id');
});
Schema::table('orders', function (Blueprint $table) {
$table->dropColumn('customer_company_name');
$table->dropColumn('customer_vat_id');
});
}
}

View File

@ -0,0 +1,36 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AddNewColumnAndRenameNameColumnInCustomerAddressesTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('customer_addresses', function (Blueprint $table) {
$table->renameColumn('name', 'first_name')->nullable();
});
Schema::table('customer_addresses', function (Blueprint $table) {
$table->string('last_name')->after('first_name')->nullable();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('customer_addresses', function (Blueprint $table) {
//
});
}
}

View File

@ -5,6 +5,7 @@ namespace Webkul\Customer\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Webkul\Customer\Repositories\CustomerAddressRepository;
use Webkul\Customer\Rules\VatIdRule;
use Auth;
/**
@ -77,15 +78,19 @@ class AddressController extends Controller
$data = collect(request()->input())->except('_token')->toArray();
$this->validate(request(), [
'address1' => 'string|required',
'country' => 'string|required',
'state' => 'string|required',
'city' => 'string|required',
'postcode' => 'required',
'phone' => 'required',
'company_name' => 'string',
'address1' => 'string|required',
'country' => 'string|required',
'state' => 'string|required',
'city' => 'string|required',
'postcode' => 'required',
'phone' => 'required',
'vat_id' => new VatIdRule(),
]);
$cust_id['customer_id'] = $this->customer->id;
$cust_id['first_name'] = $this->customer->first_name;
$cust_id['last_name'] = $this->customer->last_name;
$data = array_merge($cust_id, $data);
if ($this->customer->addresses->count() == 0) {
@ -136,12 +141,14 @@ class AddressController extends Controller
request()->merge(['address1' => implode(PHP_EOL, array_filter(request()->input('address1')))]);
$this->validate(request(), [
'address1' => 'string|required',
'country' => 'string|required',
'state' => 'string|required',
'city' => 'string|required',
'postcode' => 'required',
'phone' => 'required',
'company_name' => 'string',
'address1' => 'string|required',
'country' => 'string|required',
'state' => 'string|required',
'city' => 'string|required',
'postcode' => 'required',
'phone' => 'required',
'vat_id' => new VatIdRule(),
]);
$data = collect(request()->input())->except('_token')->toArray();

View File

@ -10,7 +10,7 @@ use Webkul\Product\Repositories\ProductReviewRepository;
* Customer controlller for the customer basically for the tasks of customers which will be
* done after customer authentication.
*
* @author Prashant Singh <prashant.singh852@webkul.com>
* @author Prashant Singh <prashant.singh852@webkul.com>
* @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com)
*/
class CustomerController extends Controller
@ -26,23 +26,24 @@ class CustomerController extends Controller
* CustomerRepository object
*
* @var Object
*/
*/
protected $customerRepository;
/**
* ProductReviewRepository object
*
* @var array
*/
*/
protected $productReviewRepository;
/**
* Create a new controller instance.
*
* @param \Webkul\Customer\Repositories\CustomerRepository $customer
* @param \Webkul\Product\Repositories\ProductReviewRepository $productReview
* @param \Webkul\Customer\Repositories\CustomerRepository $customer
* @param \Webkul\Product\Repositories\ProductReviewRepository $productReview
*
* @return void
*/
*/
public function __construct(CustomerRepository $customerRepository, ProductReviewRepository $productReviewRepository)
{
$this->middleware('customer');
@ -88,31 +89,34 @@ class CustomerController extends Controller
$id = auth()->guard('customer')->user()->id;
$this->validate(request(), [
'first_name' => 'string',
'last_name' => 'string',
'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',
'first_name' => 'string',
'last_name' => 'string',
'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_confirmation' => 'required_with:password',
]);
$data = collect(request()->input())->except('_token')->toArray();
if ($data['date_of_birth'] == "")
if (isset ($data['date_of_birth']) && $data['date_of_birth'] == "") {
unset($data['date_of_birth']);
}
if ($data['oldpassword'] != "" || $data['oldpassword'] != null) {
if(Hash::check($data['oldpassword'], auth()->guard('customer')->user()->password)) {
$data['password'] = bcrypt($data['password']);
if (isset ($data['oldpassword'])) {
if ($data['oldpassword'] != "" || $data['oldpassword'] != null) {
if (Hash::check($data['oldpassword'], auth()->guard('customer')->user()->password)) {
$data['password'] = bcrypt($data['password']);
} else {
session()->flash('warning', trans('shop::app.customer.account.profile.unmatch'));
return redirect()->back();
}
} else {
session()->flash('warning', trans('shop::app.customer.account.profile.unmatch'));
return redirect()->back();
unset($data['password']);
}
} else {
unset($data['password']);
}
if ($this->customerRepository->update($data, $id)) {
@ -129,7 +133,8 @@ class CustomerController extends Controller
/**
* Remove the specified resource from storage.
*
* @param int $id
* @param int $id
*
* @return \Illuminate\Http\Response
*/
public function destroy($id)
@ -160,7 +165,7 @@ class CustomerController extends Controller
return redirect()->back();
}
} catch(\Exception $e) {
} catch (\Exception $e) {
session()->flash('error', trans('admin::app.response.delete-failed', ['name' => 'Customer']));
return redirect()->route($this->_config['redirect']);

View File

@ -71,6 +71,7 @@ class ForgotPasswordController extends Controller
['email' => trans($response)]
);
} catch (\Exception $e) {
report($e);
session()->flash('error', trans($e->getMessage()));
return redirect()->back();

View File

@ -2,6 +2,8 @@
namespace Webkul\Customer\Http\Controllers;
use Illuminate\Support\Str;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Event;
use Illuminate\Support\Facades\Mail;
use Webkul\Customer\Mail\RegistrationEmail;
@ -85,6 +87,7 @@ class RegistrationController extends Controller
$data = request()->input();
$data['password'] = bcrypt($data['password']);
$data['api_token'] = Str::random(80);
if (core()->getConfigData('customer.settings.email.verification')) {
$data['is_verified'] = 0;
@ -111,18 +114,19 @@ class RegistrationController extends Controller
session()->flash('success', trans('shop::app.customer.signup-form.success-verify'));
} catch (\Exception $e) {
report($e);
session()->flash('info', trans('shop::app.customer.signup-form.success-verify-email-unsent'));
}
} else {
try {
try {
Mail::queue(new RegistrationEmail(request()->all()));
session()->flash('success', trans('shop::app.customer.signup-form.success-verify')); //customer registered successfully
} catch (\Exception $e) {
report($e);
session()->flash('info', trans('shop::app.customer.signup-form.success-verify-email-unsent'));
}
session()->flash('success', trans('shop::app.customer.signup-form.success'));
}
@ -174,6 +178,7 @@ class RegistrationController extends Controller
\Cookie::queue(\Cookie::forget('email-for-resend'));
}
} catch (\Exception $e) {
report($e);
session()->flash('error', trans('shop::app.customer.signup-form.verification-not-sent'));
return redirect()->back();

View File

@ -172,6 +172,7 @@ class WishlistController extends Controller
return redirect()->back();
} catch (\Exception $e) {
report($e);
session()->flash('warning', $e->getMessage());
return redirect()->route('shop.productOrCategory.index', $wishlistItem->product->url_key);

View File

@ -17,9 +17,9 @@ class Customer extends Authenticatable implements CustomerContract, JWTSubject
protected $table = 'customers';
protected $fillable = ['first_name', 'last_name', 'gender', 'date_of_birth', 'email', 'phone', 'password', 'customer_group_id', 'subscribed_to_news_letter', 'is_verified', 'token', 'notes', 'status'];
protected $fillable = ['first_name', 'last_name', 'gender', 'date_of_birth', 'email', 'phone', 'password', 'api_token', 'customer_group_id', 'subscribed_to_news_letter', 'is_verified', 'token', 'notes', 'status'];
protected $hidden = ['password', 'remember_token'];
protected $hidden = ['password', 'api_token', 'remember_token'];
/**
* Get the customer full name.

View File

@ -1,4 +1,5 @@
<?php
namespace Webkul\Customer\Models;
use Illuminate\Database\Eloquent\Model;
@ -8,5 +9,27 @@ class CustomerAddress extends Model implements CustomerAddressContract
{
protected $table = 'customer_addresses';
protected $fillable = ['customer_id' ,'address1', 'country', 'state', 'city', 'postcode', 'phone', 'default_address'];
protected $fillable = [
'customer_id',
'company_name',
'vat_id',
'address1',
'address2',
'country',
'state',
'city',
'postcode',
'phone',
'default_address',
'first_name',
'last_name',
];
/**
* Get the customer address full name.
*/
public function getNameAttribute()
{
return $this->first_name . ' ' . $this->last_name;
}
}

View File

@ -2,6 +2,7 @@
namespace Webkul\Customer\Providers;
use Illuminate\Database\Eloquent\Factory as EloquentFactory;
use Illuminate\Support\ServiceProvider;
use Illuminate\Routing\Router;
use Webkul\Customer\Http\Middleware\RedirectIfNotCustomer;
@ -16,4 +17,28 @@ class CustomerServiceProvider extends ServiceProvider
$this->loadMigrationsFrom(__DIR__ . '/../Database/Migrations');
}
/**
* Register services.
*
* @return void
* @throws \Illuminate\Contracts\Container\BindingResolutionException
*/
public function register()
{
$this->registerEloquentFactoriesFrom(__DIR__ . '/../Database/Factories');
}
/**
* Register factories.
*
* @param string $path
*
* @return void
* @throws \Illuminate\Contracts\Container\BindingResolutionException
*/
protected function registerEloquentFactoriesFrom($path): void
{
$this->app->make(EloquentFactory::class)->load($path);
}
}

View File

@ -6,12 +6,11 @@ use Webkul\Core\Eloquent\Repository;
use Illuminate\Support\Facades\Event;
/**
* Customer Reposotory
* Customer Repository
*
* @author Prashant Singh <prashant.singh852@webkul.com>
* @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com)
*/
class CustomerAddressRepository extends Repository
{
/**
@ -27,21 +26,20 @@ class CustomerAddressRepository extends Repository
/**
* @param array $data
*
* @return mixed
*/
public function create(array $data)
{
Event::dispatch('customer.addresses.create.before');
if ( isset($data['default_address']) ) {
$data['default_address'] = 1;
} else {
$data['default_address'] = 0;
}
$data['default_address'] = isset($data['default_address']) ? 1 : 0;
$default_address = $this->findWhere(['customer_id' => $data['customer_id'], 'default_address' => 1])->first();
$default_address = $this
->findWhere(['customer_id' => $data['customer_id'], 'default_address' => 1])
->first();
if ( isset($default_address->id) && $data['default_address'] ) {
if (isset($default_address->id) && $data['default_address']) {
$default_address->update(['default_address' => 0]);
}
@ -54,7 +52,8 @@ class CustomerAddressRepository extends Repository
/**
* @param array $data
* @param $id
* @param $id
*
* @return mixed
*/
public function update(array $data, $id)
@ -63,16 +62,14 @@ class CustomerAddressRepository extends Repository
Event::dispatch('customer.addresses.update.before', $id);
if (isset($data['default_address']) ) {
$data['default_address'] = 1;
} else {
$data['default_address'] = 0;
}
$data['default_address'] = isset($data['default_address']) ? 1 : 0;
$default_address = $this->findWhere(['customer_id' => $address->customer_id, 'default_address' => 1])->first();
$default_address = $this
->findWhere(['customer_id' => $address->customer_id, 'default_address' => 1])
->first();
if ( isset($default_address->id) && $data['default_address'] ) {
if ( $default_address->id != $address->id ) {
if (isset($default_address->id) && $data['default_address']) {
if ($default_address->id != $address->id) {
$default_address->update(['default_address' => 0]);
}
$address->update($data);

View File

@ -0,0 +1,42 @@
<?php
namespace Webkul\Customer\Rules;
use Illuminate\Contracts\Validation\Rule;
use Webkul\Customer\Rules\VatValidator;
/**
* Class VatIdRule
*
* @see https://laravel.com/docs/5.8/validation#using-rule-objects
* @package App\Rules
*/
class VatIdRule implements Rule
{
/**
* Determine if the validation rule passes.
*
* The rules are borrowed from:
* @see https://raw.githubusercontent.com/danielebarbaro/laravel-vat-eu-validator/master/src/VatValidator.php
*
* @param string $attribute
* @param mixed $value
* @return bool
*/
public function passes($attribute, $value)
{
$validator = new VatValidator();
return $validator->validate($value);
}
/**
* Get the validation error message.
*
* @return string
*/
public function message()
{
return trans('shop::app.invalid_vat_format');
}
}

View File

@ -0,0 +1,95 @@
<?php
namespace Webkul\Customer\Rules;
/**
* Class VatValidator
*
* This class is borrowed from:
*
* @see https://raw.githubusercontent.com/danielebarbaro/laravel-vat-eu-validator
*
* @package Danielebarbaro\LaravelVatEuValidator
*/
class VatValidator
{
/**
* Regular expression patterns per country code
*
* @var array
* @link http://ec.europa.eu/taxation_customs/vies/faq.html?locale=en#item_11
*/
protected static $pattern_expression = array(
'AT' => 'U[A-Z\d]{8}',
'BE' => '(0\d{9}|\d{10})',
'BG' => '\d{9,10}',
'CY' => '\d{8}[A-Z]',
'CZ' => '\d{8,10}',
'DE' => '\d{9}',
'DK' => '(\d{2} ?){3}\d{2}',
'EE' => '\d{9}',
'EL' => '\d{9}',
'ES' => '[A-Z]\d{7}[A-Z]|\d{8}[A-Z]|[A-Z]\d{8}',
'FI' => '\d{8}',
'FR' => '([A-Z]{2}|\d{2})\d{9}',
'GB' => '\d{9}|\d{12}|(GD|HA)\d{3}',
'HR' => '\d{11}',
'HU' => '\d{8}',
'IE' => '[A-Z\d]{8}|[A-Z\d]{9}',
'IT' => '\d{11}',
'LT' => '(\d{9}|\d{12})',
'LU' => '\d{8}',
'LV' => '\d{11}',
'MT' => '\d{8}',
'NL' => '\d{9}B\d{2}',
'PL' => '\d{10}',
'PT' => '\d{9}',
'RO' => '\d{2,10}',
'SE' => '\d{12}',
'SI' => '\d{8}',
'SK' => '\d{10}',
);
/**
* Validate a VAT number format.
*
* @param string $vatNumber
*
* @return boolean
*/
public function validate(string $vatNumber): bool
{
$vatNumber = $this->vatCleaner($vatNumber);
list($country, $number) = $this->splitVat($vatNumber);
if (! isset(self::$pattern_expression[$country])) {
return false;
}
return preg_match('/^' . self::$pattern_expression[$country] . '$/', $number) > 0;
}
/**
* @param string $vatNumber
*
* @return string
*/
private function vatCleaner(string $vatNumber): string
{
$vatNumber_no_spaces = trim($vatNumber);
return strtoupper($vatNumber_no_spaces);
}
/**
* @param string $vatNumber
*
* @return array
*/
private function splitVat(string $vatNumber): array
{
return [
substr($vatNumber, 0, 2),
substr($vatNumber, 2),
];
}
}

View File

@ -168,6 +168,7 @@ class InventorySourceController extends Controller
return response()->json(['message' => true], 200);
} catch (\Exception $e) {
report($e);
session()->flash('error', trans('admin::app.response.delete-failed', ['name' => 'Inventory source']));
}
}

View File

@ -3,7 +3,7 @@ return [
'cashondelivery' => [
'code' => 'cashondelivery',
'title' => 'Cash On Delivery',
'description' => 'shop::app.checkout.onepage.cash-desc',
'description' => 'Cash On Delivery',
'class' => 'Webkul\Payment\Payment\CashOnDelivery',
'active' => true,
'sort' => 1
@ -12,7 +12,7 @@ return [
'moneytransfer' => [
'code' => 'moneytransfer',
'title' => 'Money Transfer',
'description' => 'shop::app.checkout.onepage.money-desc',
'description' => 'Money Transfer',
'class' => 'Webkul\Payment\Payment\MoneyTransfer',
'active' => true,
'sort' => 2
@ -21,7 +21,7 @@ return [
'paypal_standard' => [
'code' => 'paypal_standard',
'title' => 'Paypal Standard',
'description' => 'shop::app.checkout.onepage.paypal-desc',
'description' => 'Paypal Standard',
'class' => 'Webkul\Paypal\Payment\Standard',
'sandbox' => true,
'active' => true,

View File

@ -0,0 +1,20 @@
<?php
/** @var \Illuminate\Database\Eloquent\Factory $factory */
use Faker\Generator as Faker;
use Webkul\Product\Models\ProductReview;
$factory->define(ProductReview::class, function (Faker $faker, array $attributes) {
if (!array_key_exists('product_id', $attributes)) {
throw new InvalidArgumentException('product_id must be provided. You may use $I->haveProduct() to generate a product');
}
return [
'title' => $faker->words(5, true),
'rating' => $faker->numberBetween(0, 10),
'status' => 1,
'comment' => $faker->sentence(20),
'product_id' => $attributes['product_id'],
];
});

View File

@ -45,6 +45,14 @@ class BundleOption extends AbstractProduct
$options[$option->id] = $this->getOptionItemData($option);
}
usort ($options, function($a, $b) {
if ($a['sort_order'] == $b['sort_order']) {
return 0;
}
return ($a['sort_order'] < $b['sort_order']) ? -1 : 1;
});
return $options;
}
@ -68,7 +76,7 @@ class BundleOption extends AbstractProduct
/**
* Get formed data from bundle option product
*
*
* @param ProductBundleOption $option
* @return array
*/
@ -83,10 +91,19 @@ class BundleOption extends AbstractProduct
'price' => $bundleOptionProduct->product->getTypeInstance()->getProductPrices(),
'name' => $bundleOptionProduct->product->name,
'product_id' => $bundleOptionProduct->product_id,
'is_default' => $bundleOptionProduct->is_default
'is_default' => $bundleOptionProduct->is_default,
'sort_order' => $bundleOptionProduct->sort_order
];
}
usort ($products, function($a, $b) {
if ($a['sort_order'] == $b['sort_order']) {
return 0;
}
return ($a['sort_order'] < $b['sort_order']) ? -1 : 1;
});
return $products;
}
}

View File

@ -245,6 +245,7 @@ class ProductController extends Controller
return response()->json(['message' => true], 200);
} catch (\Exception $e) {
report($e);
session()->flash('error', trans('admin::app.response.delete-failed', ['name' => 'Product']));
}

View File

@ -105,6 +105,7 @@ class ReviewController extends Controller
return response()->json(['message' => true], 200);
} catch (\Exception $e) {
report($e);
session()->flash('success', trans('admin::app.response.delete-failed', ['name' => 'Review']));
}

View File

@ -74,7 +74,8 @@ class ProductForm extends FormRequest
'sku' => ['required', 'unique:products,sku,' . $this->id, new \Webkul\Core\Contracts\Validations\Slug],
'images.*' => 'mimes:jpeg,jpg,bmp,png',
'special_price_from' => 'nullable|date',
'special_price_to' => 'nullable|date|after_or_equal:special_price_from'
'special_price_to' => 'nullable|date|after_or_equal:special_price_from',
'special_price' => ['nullable', new \Webkul\Core\Contracts\Validations\Decimal, 'lt:price']
]);
foreach ($product->getEditableAttributes() as $attribute) {

View File

@ -68,7 +68,7 @@ class ProductBundleOptionProductRepository extends Repository
}
}
if (! $haveIsDefaulFlag)
if (! $haveIsDefaulFlag && $data['is_required'])
$data['products'][key($data['products'])]['is_default'] = 1;
}
}

View File

@ -213,7 +213,7 @@ class Bundle extends AbstractType
}
}
if (! $haveRequiredOptions)
if (! $haveRequiredOptions && count($minPrices))
$minPrice = min($minPrices);
return $minPrice;
@ -523,6 +523,8 @@ class Bundle extends AbstractType
*/
public function getAdditionalOptions($data)
{
$bundleOptionQuantities = $data['bundle_option_qty'] ?? [];
foreach ($data['bundle_options'] as $optionId => $optionProductIds) {
$option = $this->productBundleOptionRepository->find($optionId);
@ -537,7 +539,7 @@ class Bundle extends AbstractType
$qty = $data['bundle_option_qty'][$optionId] ?? $optionProduct->qty;
if (! isset($data['bundle_option_qty'][$optionId]))
$data['bundle_option_qty'][$optionId] = $qty;
$bundleOptionQuantities[$optionId] = $qty;
$labels[] = $qty . ' x ' . $optionProduct->product->name . ' ' . core()->currency($optionProduct->product->getTypeInstance()->getMinimalPrice());
}
@ -551,6 +553,8 @@ class Bundle extends AbstractType
}
}
$data['bundle_option_qty'] = $bundleOptionQuantities;
return $data;
}

View File

@ -0,0 +1,25 @@
<?php
/** @var \Illuminate\Database\Eloquent\Factory $factory */
use Faker\Generator as Faker;
use Webkul\Inventory\Models\InventorySource;
$factory->define(InventorySource::class, function (Faker $faker) {
$code = $faker->unique()->word;
return [
'code' => $faker->unique()->word,
'name' => $code,
'description' => $faker->sentence,
'contact_name' => $faker->name,
'contact_email' => $faker->safeEmail,
'contact_number' => $faker->phoneNumber,
'country' => $faker->countryCode,
'state' => $faker->state,
'city' => $faker->city,
'street' => $faker->streetAddress,
'postcode' => $faker->postcode,
'priority' => 0,
'status' => 1,
];
});

View File

@ -0,0 +1,61 @@
<?php
/** @var \Illuminate\Database\Eloquent\Factory $factory */
use Faker\Generator as Faker;
use Webkul\Sales\Models\Invoice;
use Webkul\Sales\Models\Order;
use Webkul\Sales\Models\OrderAddress;
$factory->define(Invoice::class, function (Faker $faker, array $attributes) {
$subTotal = $faker->randomFloat(2);
$shippingAmount = $faker->randomFloat(2);
$taxAmount = $faker->randomFloat(2);
if (!$attributes['order_id']) {
$attributes['order_id'] = function () {
return factory(Order::class)->create()->id;
};
}
if (!$attributes['order_address_id']) {
$attributes['order_address_id'] = function () use ($attributes) {
return factory(OrderAddress::class)
->create(['order_id' => $attributes['order_id']])
->id;
};
}
return [
'email_sent' => 0,
'total_qty' => $faker->randomNumber(),
'base_currency_code' => 'EUR',
'channel_currency_code' => 'EUR',
'order_currency_code' => 'EUR',
'sub_total' => $subTotal,
'base_sub_total' => $subTotal,
'grand_total' => $subTotal,
'base_grand_total' => $subTotal,
'shipping_amount' => $shippingAmount,
'base_shipping_amount' => $shippingAmount,
'tax_amount' => $taxAmount,
'base_tax_amount' => $taxAmount,
'discount_amount' => 0,
'base_discount_amount' => 0,
'order_id' => $attributes['order_id'],
'order_address_id' => $attributes['order_address_id'],
];
});
$factory->state(Invoice::class, 'pending', [
'status' => 'pending',
]);
$factory->state(Invoice::class, 'paid', [
'status' => 'paid',
]);
$factory->state(Invoice::class, 'refunded', [
'status' => 'refunded',
]);

View File

@ -0,0 +1,34 @@
<?php
/** @var \Illuminate\Database\Eloquent\Factory $factory */
use Faker\Generator as Faker;
use Webkul\Customer\Models\Customer;
use Webkul\Customer\Models\CustomerAddress;
use Webkul\Sales\Models\Order;
use Webkul\Sales\Models\OrderAddress;
$factory->define(OrderAddress::class, function (Faker $faker) {
$customer = factory(Customer::class)->create();
$customerAddress = factory(CustomerAddress::class)->create();
return [
'first_name' => $customer->first_name,
'last_name' => $customer->last_name,
'email' => $customer->email,
'address1' => $customerAddress->address1,
'country' => $customerAddress->country,
'state' => $customerAddress->state,
'city' => $customerAddress->city,
'postcode' => $customerAddress->postcode,
'phone' => $customerAddress->phone,
'address_type' => 'billing',
'order_id' => function () {
return factory(Order::class)->create()->id;
},
];
});
$factory->state(OrderAddress::class, 'shipping', [
'address_type' => 'shipping',
]);

View File

@ -0,0 +1,65 @@
<?php
/** @var \Illuminate\Database\Eloquent\Factory $factory */
use Faker\Generator as Faker;
use Illuminate\Support\Facades\DB;
use Webkul\Core\Models\Channel;
use Webkul\Customer\Models\Customer;
use Webkul\Sales\Models\Order;
$factory->define(Order::class, function (Faker $faker) {
$lastOrder = DB::table('orders')
->orderBy('id', 'desc')
->select('id')
->first()
->id ?? 0;
$customer = factory(Customer::class)->create();
return [
'increment_id' => $lastOrder + 1,
'status' => 'pending',
'channel_name' => 'Default',
'is_guest' => 0,
'customer_id' => $customer->id,
'customer_email' => $customer->email,
'customer_first_name' => $customer->first_name,
'customer_last_name' => $customer->last_name,
'is_gift' => 0,
'total_item_count' => 1,
'total_qty_ordered' => 1,
'base_currency_code' => 'EUR',
'channel_currency_code' => 'EUR',
'order_currency_code' => 'EUR',
'grand_total' => 0.0000,
'base_grand_total' => 0.0000,
'grand_total_invoiced' => 0.0000,
'base_grand_total_invoiced' => 0.0000,
'grand_total_refunded' => 0.0000,
'base_grand_total_refunded' => 0.0000,
'sub_total' => 0.0000,
'base_sub_total' => 0.0000,
'sub_total_invoiced' => 0.0000,
'base_sub_total_invoiced' => 0.0000,
'sub_total_refunded' => 0.0000,
'base_sub_total_refunded' => 0.0000,
'customer_type' => Customer::class,
'channel_id' => 1,
'channel_type' => Channel::class,
'cart_id' => 0,
];
});
$factory->state(Order::class, 'pending', [
'status' => 'pending',
]);
$factory->state(Order::class, 'completed', [
'status' => 'completed',
]);
$factory->state(Order::class, 'closed', [
'status' => 'closed',
]);

View File

@ -0,0 +1,16 @@
<?php
/** @var \Illuminate\Database\Eloquent\Factory $factory */
use Faker\Generator as Faker;
use Webkul\Sales\Models\Order;
use Webkul\Sales\Models\Refund;
$factory->define(Refund::class, function (Faker $faker, array $attributes) {
return [
'order_id' => function () {
return factory(Order::class)->create()->id;
},
];
});

View File

@ -0,0 +1,22 @@
<?php
/** @var \Illuminate\Database\Eloquent\Factory $factory */
use Faker\Generator as Faker;
use Webkul\Inventory\Models\InventorySource;
use Webkul\Sales\Models\OrderAddress;
use Webkul\Sales\Models\Shipment;
$factory->define(Shipment::class, function (Faker $faker) {
$address = factory(OrderAddress::class)->create();
return [
'total_qty' => $faker->numberBetween(1, 20),
'order_id' => $address->order_id,
'order_address_id' => $address->id,
'inventory_source_id' => function () {
return factory(InventorySource::class)->create()->id;
},
];
});

View File

@ -7,16 +7,26 @@ use Webkul\Sales\Contracts\Order as OrderContract;
class Order extends Model implements OrderContract
{
protected $guarded = ['id', 'items', 'shipping_address', 'billing_address', 'customer', 'channel', 'payment', 'created_at', 'updated_at'];
protected $guarded = [
'id',
'items',
'shipping_address',
'billing_address',
'customer',
'channel',
'payment',
'created_at',
'updated_at',
];
protected $statusLabel = [
'pending' => 'Pending',
'pending' => 'Pending',
'pending_payment' => 'Pending Payment',
'processing' => 'Processing',
'completed' => 'Completed',
'canceled' => 'Canceled',
'closed' => 'Closed',
'fraud' => 'Fraud'
'processing' => 'Processing',
'completed' => 'Completed',
'canceled' => 'Canceled',
'closed' => 'Closed',
'fraud' => 'Fraud',
];
/**
@ -90,7 +100,7 @@ class Order extends Model implements OrderContract
{
return $this->hasMany(RefundProxy::modelClass());
}
/**
* Get the customer record associated with the order.
*/
@ -193,12 +203,12 @@ class Order extends Model implements OrderContract
{
if ($this->status == 'fraud')
return false;
foreach ($this->items as $item) {
if ($item->canInvoice())
return true;
}
return false;
}
@ -209,7 +219,7 @@ class Order extends Model implements OrderContract
{
if ($this->status == 'fraud')
return false;
foreach ($this->items as $item) {
if ($item->canCancel())
return true;
@ -225,7 +235,7 @@ class Order extends Model implements OrderContract
{
if ($this->status == 'fraud')
return false;
foreach ($this->items as $item) {
if ($item->qty_to_refund > 0)
return true;

View File

@ -2,6 +2,7 @@
namespace Webkul\Sales\Providers;
use Illuminate\Database\Eloquent\Factory as EloquentFactory;
use Illuminate\Support\ServiceProvider;
class SalesServiceProvider extends ServiceProvider
@ -15,11 +16,27 @@ class SalesServiceProvider extends ServiceProvider
* Register services.
*
* @return void
* @throws \Illuminate\Contracts\Container\BindingResolutionException
*/
public function register()
{
$this->registerEloquentFactoriesFrom(__DIR__ . '/../Database/Factories');
$this->mergeConfigFrom(
dirname(__DIR__) . '/Config/system.php', 'core'
);
}
/**
* Register factories.
*
* @param string $path
*
* @return void
* @throws \Illuminate\Contracts\Container\BindingResolutionException
*/
protected function registerEloquentFactoriesFrom($path): void
{
$this->app->make(EloquentFactory::class)->load($path);
}
}

View File

@ -6,7 +6,6 @@ use Illuminate\Container\Container as App;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Event;
use Webkul\Core\Eloquent\Repository;
use Webkul\Core\Models\CoreConfig;
use Webkul\Sales\Contracts\Order;
use Webkul\Sales\Models\Order as OrderModel;
@ -196,22 +195,20 @@ class OrderRepository extends Repository
*/
public function generateIncrementId()
{
$config = new CoreConfig();
foreach ([ 'Prefix' => 'prefix',
'Length' => 'length',
'Suffix' => 'suffix', ] as
$varSuffix => $confKey)
{
$var = "invoiceNumber{$varSuffix}";
$$var = $config->where('code', '=', "sales.orderSettings.order_number.order_number_{$confKey}")->first() ?: false;
$$var = core()->getConfigData('sales.orderSettings.order_number.order_number_'.$confKey) ?: false;
}
$lastOrder = $this->model->orderBy('id', 'desc')->limit(1)->first();
$lastId = $lastOrder ? $lastOrder->id : 0;
if ($invoiceNumberLength && ($invoiceNumberPrefix || $invoiceNumberSuffix)) {
$invoiceNumber = ($invoiceNumberPrefix->value) . sprintf("%0{$invoiceNumberLength->value}d", 0) . ($lastId + 1) . ($invoiceNumberSuffix->value);
$invoiceNumber = ($invoiceNumberPrefix) . sprintf("%0{$invoiceNumberLength}d", 0) . ($lastId + 1) . ($invoiceNumberSuffix);
} else {
$invoiceNumber = $lastId + 1;
}

View File

@ -263,7 +263,7 @@ class RefundRepository extends Repository
$summary['tax']['price'] += ($orderItem->tax_amount / $orderItem->qty_ordered) * $qty;
}
$summary['shipping']['price'] += $order->base_shipping_invoiced - $order->base_shipping_refunded;
$summary['shipping']['price'] += $order->base_shipping_invoiced - $order->base_shipping_refunded - $order->base_shipping_discount_amount;
$summary['grand_total']['price'] += $summary['subtotal']['price'] + $summary['tax']['price'] + $summary['shipping']['price'] - $summary['discount']['price'];

View File

@ -25,6 +25,6 @@
"ez-plus": "^1.2.1",
"vee-validate": "^2.2.15",
"vue-flatpickr": "^2.3.0",
"vue-slider-component": "^3.0.44"
"vue-slider-component": "^2.7.5"
}
}

File diff suppressed because one or more lines are too long

View File

@ -39,9 +39,3 @@
* (c) 2014-2019 Evan You
* Released under the MIT License.
*/
/**
* vue-class-component v7.0.1
* (c) 2015-present Evan You
* @license MIT
*/

View File

@ -1,4 +1,4 @@
{
"/js/shop.js": "/js/shop.js?id=8fc3af6f1d9024329021",
"/js/shop.js": "/js/shop.js?id=d0a3f597b439d75f4a4e",
"/css/shop.css": "/css/shop.css?id=617c680f279cb4a73734"
}

View File

@ -12,6 +12,8 @@ class AddStoredFunctionToGetUrlPathOfCategory extends Migration
*/
public function up()
{
$dbPrefix = DB::getTablePrefix();
$functionSQL = <<< SQL
DROP FUNCTION IF EXISTS `get_url_path_of_category`;
CREATE FUNCTION get_url_path_of_category(
@ -21,7 +23,7 @@ class AddStoredFunctionToGetUrlPathOfCategory extends Migration
RETURNS VARCHAR(255)
DETERMINISTIC
BEGIN
DECLARE urlPath VARCHAR(255);
-- Category with id 1 is root by default
IF categoryId <> 1
@ -29,9 +31,9 @@ class AddStoredFunctionToGetUrlPathOfCategory extends Migration
SELECT
GROUP_CONCAT(parent_translations.slug SEPARATOR '/') INTO urlPath
FROM
categories AS node,
categories AS parent
JOIN category_translations AS parent_translations ON parent.id = parent_translations.category_id
${dbPrefix}categories AS node,
${dbPrefix}categories AS parent
JOIN ${dbPrefix}category_translations AS parent_translations ON parent.id = parent_translations.category_id
WHERE
node._lft >= parent._lft
AND node._rgt <= parent._rgt
@ -40,15 +42,15 @@ class AddStoredFunctionToGetUrlPathOfCategory extends Migration
AND parent_translations.locale = localeCode
GROUP BY
node.id;
IF urlPath IS NULL
THEN
SET urlPath = (SELECT slug FROM category_translations WHERE category_translations.category_id = categoryId);
SET urlPath = (SELECT slug FROM ${dbPrefix}category_translations WHERE ${dbPrefix}category_translations.category_id = categoryId);
END IF;
ELSE
SET urlPath = '';
END IF;
RETURN urlPath;
END;
SQL;

View File

@ -2,6 +2,7 @@
use Illuminate\Support\Facades\DB;
use Illuminate\Database\Migrations\Migration;
use Webkul\Category\Models\CategoryTranslation;
class AddTriggerToCategoryTranslations extends Migration
{
@ -15,11 +16,13 @@ class AddTriggerToCategoryTranslations extends Migration
*/
public function up()
{
$dbPrefix = DB::getTablePrefix();
$triggerBody = $this->getTriggerBody();
$insertTrigger = <<< SQL
CREATE TRIGGER %s
BEFORE INSERT ON category_translations
FOR EACH ROW
BEFORE INSERT ON ${dbPrefix}category_translations
FOR EACH ROW
BEGIN
$triggerBody
END;
@ -27,8 +30,8 @@ SQL;
$updateTrigger = <<< SQL
CREATE TRIGGER %s
BEFORE UPDATE ON category_translations
FOR EACH ROW
BEFORE UPDATE ON ${dbPrefix}category_translations
FOR EACH ROW
BEGIN
$triggerBody
END;
@ -59,20 +62,22 @@ SQL;
*/
private function getTriggerBody()
{
$dbPrefix = DB::getTablePrefix();
return <<<SQL
DECLARE parentUrlPath varchar(255);
DECLARE urlPath varchar(255);
-- Category with id 1 is root by default
IF NEW.category_id <> 1
THEN
SELECT
GROUP_CONCAT(parent_translations.slug SEPARATOR '/') INTO parentUrlPath
FROM
categories AS node,
categories AS parent
JOIN category_translations AS parent_translations ON parent.id = parent_translations.category_id
${dbPrefix}categories AS node,
${dbPrefix}categories AS parent
JOIN ${dbPrefix}category_translations AS parent_translations ON parent.id = parent_translations.category_id
WHERE
node._lft >= parent._lft
AND node._rgt <= parent._rgt
@ -81,16 +86,16 @@ SQL;
AND parent_translations.locale = NEW.locale
GROUP BY
node.id;
IF parentUrlPath IS NULL
IF parentUrlPath IS NULL
THEN
SET urlPath = NEW.slug;
ELSE
SET urlPath = concat(parentUrlPath, '/', NEW.slug);
END IF;
SET NEW.url_path = urlPath;
END IF;
SQL;

View File

@ -16,10 +16,11 @@ class AddTriggerToCategories extends Migration
public function up()
{
$triggerBody = $this->getTriggerBody();
$dbPrefix = DB::getTablePrefix();
$insertTrigger = <<< SQL
CREATE TRIGGER %s
AFTER INSERT ON categories
CREATE TRIGGER %s
AFTER INSERT ON ${dbPrefix}categories
FOR EACH ROW
BEGIN
$triggerBody
@ -27,8 +28,8 @@ class AddTriggerToCategories extends Migration
SQL;
$updateTrigger = <<< SQL
CREATE TRIGGER %s
AFTER UPDATE ON categories
CREATE TRIGGER %s
AFTER UPDATE ON ${dbPrefix}categories
FOR EACH ROW
BEGIN
$triggerBody
@ -60,39 +61,41 @@ SQL;
*/
private function getTriggerBody(): string
{
$dbPrefix = DB::getTablePrefix();
return <<< SQL
DECLARE urlPath VARCHAR(255);
DECLARE localeCode VARCHAR(255);
DECLARE done INT;
DECLARE curs CURSOR FOR (SELECT category_translations.locale
FROM category_translations
DECLARE curs CURSOR FOR (SELECT ${dbPrefix}category_translations.locale
FROM ${dbPrefix}category_translations
WHERE category_id = NEW.id);
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
IF EXISTS (
SELECT *
FROM category_translations
FROM ${dbPrefix}category_translations
WHERE category_id = NEW.id
)
THEN
OPEN curs;
SET done = 0;
REPEAT
REPEAT
FETCH curs INTO localeCode;
SELECT get_url_path_of_category(NEW.id, localeCode) INTO urlPath;
UPDATE category_translations
SET url_path = urlPath
WHERE category_translations.category_id = NEW.id;
UPDATE ${dbPrefix}category_translations
SET url_path = urlPath
WHERE ${dbPrefix}category_translations.category_id = NEW.id;
UNTIL done END REPEAT;
CLOSE curs;
END IF;
SQL;
}

View File

@ -16,10 +16,12 @@ class AlterTriggerCategoryTranslations extends Migration
public function up()
{
$triggerBody = $this->getTriggerBody();
$dbPrefix = DB::getTablePrefix();
$insertTrigger = <<< SQL
CREATE TRIGGER %s
BEFORE INSERT ON category_translations
FOR EACH ROW
BEFORE INSERT ON ${dbPrefix}category_translations
FOR EACH ROW
BEGIN
$triggerBody
END;
@ -27,8 +29,8 @@ SQL;
$updateTrigger = <<< SQL
CREATE TRIGGER %s
BEFORE UPDATE ON category_translations
FOR EACH ROW
BEFORE UPDATE ON ${dbPrefix}category_translations
FOR EACH ROW
BEGIN
$triggerBody
END;
@ -66,44 +68,46 @@ SQL;
*/
private function getTriggerBody()
{
$dbPrefix = DB::getTablePrefix();
return <<<SQL
DECLARE parentUrlPath varchar(255);
DECLARE urlPath varchar(255);
IF NOT EXISTS (
SELECT id
FROM categories
FROM ${dbPrefix}categories
WHERE
id = NEW.category_id
AND parent_id IS NULL
)
THEN
SELECT
GROUP_CONCAT(parent_translations.slug SEPARATOR '/') INTO parentUrlPath
FROM
categories AS node,
categories AS parent
JOIN category_translations AS parent_translations ON parent.id = parent_translations.category_id
${dbPrefix}categories AS node,
${dbPrefix}categories AS parent
JOIN ${dbPrefix}category_translations AS parent_translations ON parent.id = parent_translations.category_id
WHERE
node._lft >= parent._lft
AND node._rgt <= parent._rgt
AND node.id = (SELECT parent_id FROM categories WHERE id = NEW.category_id)
AND node.parent_id IS NOT NULL
AND node.id = (SELECT parent_id FROM ${dbPrefix}categories WHERE id = NEW.category_id)
AND node.parent_id IS NOT NULL
AND parent.parent_id IS NOT NULL
AND parent_translations.locale = NEW.locale
GROUP BY
node.id;
IF parentUrlPath IS NULL
IF parentUrlPath IS NULL
THEN
SET urlPath = NEW.slug;
ELSE
SET urlPath = concat(parentUrlPath, '/', NEW.slug);
END IF;
SET NEW.url_path = urlPath;
END IF;
SQL;

View File

@ -12,6 +12,8 @@ class AlterStoredFunctionUrlPathCategory extends Migration
*/
public function up()
{
$dbPrefix = DB::getTablePrefix();
$functionSQL = <<< SQL
DROP FUNCTION IF EXISTS `get_url_path_of_category`;
CREATE FUNCTION get_url_path_of_category(
@ -21,12 +23,12 @@ class AlterStoredFunctionUrlPathCategory extends Migration
RETURNS VARCHAR(255)
DETERMINISTIC
BEGIN
DECLARE urlPath VARCHAR(255);
IF NOT EXISTS (
SELECT id
FROM categories
SELECT id
FROM ${dbPrefix}categories
WHERE
id = categoryId
AND parent_id IS NULL
@ -35,9 +37,9 @@ class AlterStoredFunctionUrlPathCategory extends Migration
SELECT
GROUP_CONCAT(parent_translations.slug SEPARATOR '/') INTO urlPath
FROM
categories AS node,
categories AS parent
JOIN category_translations AS parent_translations ON parent.id = parent_translations.category_id
${dbPrefix}categories AS node,
${dbPrefix}categories AS parent
JOIN ${dbPrefix}category_translations AS parent_translations ON parent.id = parent_translations.category_id
WHERE
node._lft >= parent._lft
AND node._rgt <= parent._rgt
@ -47,15 +49,15 @@ class AlterStoredFunctionUrlPathCategory extends Migration
AND parent_translations.locale = localeCode
GROUP BY
node.id;
IF urlPath IS NULL
THEN
SET urlPath = (SELECT slug FROM category_translations WHERE category_translations.category_id = categoryId);
SET urlPath = (SELECT slug FROM ${dbPrefix}category_translations WHERE ${dbPrefix}category_translations.category_id = categoryId);
END IF;
ELSE
SET urlPath = '';
END IF;
RETURN urlPath;
END;
SQL;

View File

@ -18,10 +18,11 @@ class AlterTriggerOnCategories extends Migration
public function up()
{
$triggerBody = $this->getTriggerBody();
$dbPrefix = DB::getTablePrefix();
$insertTrigger = <<< SQL
CREATE TRIGGER %s
AFTER INSERT ON categories
CREATE TRIGGER %s
AFTER INSERT ON ${dbPrefix}categories
FOR EACH ROW
BEGIN
$triggerBody
@ -29,8 +30,8 @@ class AlterTriggerOnCategories extends Migration
SQL;
$updateTrigger = <<< SQL
CREATE TRIGGER %s
AFTER UPDATE ON categories
CREATE TRIGGER %s
AFTER UPDATE ON ${dbPrefix}categories
FOR EACH ROW
BEGIN
$triggerBody
@ -68,46 +69,48 @@ SQL;
*/
private function getTriggerBody(): string
{
$dbPrefix = DB::getTablePrefix();
return <<< SQL
DECLARE urlPath VARCHAR(255);
DECLARE localeCode VARCHAR(255);
DECLARE done INT;
DECLARE curs CURSOR FOR (SELECT category_translations.locale
FROM category_translations
DECLARE curs CURSOR FOR (SELECT ${dbPrefix}category_translations.locale
FROM ${dbPrefix}category_translations
WHERE category_id = NEW.id);
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
IF EXISTS (
SELECT *
FROM category_translations
FROM ${dbPrefix}category_translations
WHERE category_id = NEW.id
)
THEN
OPEN curs;
SET done = 0;
REPEAT
REPEAT
FETCH curs INTO localeCode;
SELECT get_url_path_of_category(NEW.id, localeCode) INTO urlPath;
IF NEW.parent_id IS NULL
IF NEW.parent_id IS NULL
THEN
SET urlPath = '';
END IF;
UPDATE category_translations
SET url_path = urlPath
WHERE
category_translations.category_id = NEW.id
AND category_translations.locale = localeCode;
UPDATE ${dbPrefix}category_translations
SET url_path = urlPath
WHERE
${dbPrefix}category_translations.category_id = NEW.id
AND ${dbPrefix}category_translations.locale = localeCode;
UNTIL done END REPEAT;
CLOSE curs;
END IF;
SQL;
}

View File

@ -185,6 +185,8 @@ class CartController extends Controller
'message' => trans('shop::app.checkout.total.invalid-coupon')
]);
} catch (\Exception $e) {
report($e);
return response()->json([
'success' => false,
'message' => trans('shop::app.checkout.total.coupon-apply-issue')

View File

@ -75,6 +75,7 @@ class SubscriptionController extends Controller
session()->flash('success', trans('shop::app.subscription.subscribed'));
} catch (\Exception $e) {
report($e);
session()->flash('error', trans('shop::app.subscription.not-subscribed'));
$mailSent = false;

View File

@ -1,6 +1,7 @@
<?php
return [
'invalid_vat_format' => 'The given vat id has a wrong format',
'security-warning' => 'Suspicious activity found!!!',
'nothing-to-delete' => 'Nothing to delete',
@ -219,6 +220,10 @@ return [
'create' => [
'page-title' => 'Add Address Form',
'company_name' => 'Company name',
'first_name' => 'First name',
'last_name' => 'Last name',
'vat_id' => 'Vat id',
'title' => 'Add Address',
'street-address' => 'Street Address',
'country' => 'Country',
@ -234,6 +239,10 @@ return [
'edit' => [
'page-title' => 'Edit Address',
'company_name' => 'Company name',
'first_name' => 'First name',
'last_name' => 'Last name',
'vat_id' => 'Vat id',
'title' => 'Edit Address',
'street-address' => 'Street Address',
'submit' => 'Save Address',

View File

@ -19,13 +19,32 @@
{!! view_render_event('bagisto.shop.customers.account.address.create.before') !!}
<form method="post" action="{{ route('customer.address.create') }}" @submit.prevent="onSubmit">
<form id="customer-address-form" method="post" action="{{ route('customer.address.create') }}" @submit.prevent="onSubmit">
<div class="account-table-content">
@csrf
{!! view_render_event('bagisto.shop.customers.account.address.create_form_controls.before') !!}
<div class="control-group" :class="[errors.has('company_name') ? 'has-error' : '']">
<label for="company_name">{{ __('shop::app.customer.account.address.create.company_name') }}</label>
<input value="<?= old('company_name'); ?>" type="text" class="control" name="company_name" data-vv-as="&quot;{{ __('shop::app.customer.account.address.create.company_name') }}&quot;">
<span class="control-error" v-if="errors.has('company_name')">@{{ errors.first('company_name') }}</span>
</div>
<div class="control-group {!! $errors->has('vat_id') ? 'has-error' : '' !!}">
<label for="vat_id">{{ __('shop::app.customer.account.address.create.vat_id') }}</label>
<input type="text" class="control" name="vat_id"
value="<?= old('vat_id'); ?>"
data-vv-as="&quot;{{ __('shop::app.customer.account.address.create.vat_id') }}&quot;">
<span class="control-error" v-if="{!! $errors->has('vat_id') !!}">
@foreach ($errors->get('vat_id') as $message)
{{ $message }}
@endforeach
</span>
</div>
<div class="control-group" :class="[errors.has('address1[]') ? 'has-error' : '']">
<label for="address_0" class="required">{{ __('shop::app.customer.account.address.create.street-address') }}</label>
<input type="text" class="control" name="address1[]" id="address_0" v-validate="'required'" data-vv-as="&quot;{{ __('shop::app.customer.account.address.create.street-address') }}&quot;">
@ -44,19 +63,19 @@
<div class="control-group" :class="[errors.has('city') ? 'has-error' : '']">
<label for="city" class="required">{{ __('shop::app.customer.account.address.create.city') }}</label>
<input type="text" class="control" name="city" v-validate="'required'" data-vv-as="&quot;{{ __('shop::app.customer.account.address.create.city') }}&quot;">
<input value="<?= old('city'); ?>" type="text" class="control" name="city" v-validate="'required'" data-vv-as="&quot;{{ __('shop::app.customer.account.address.create.city') }}&quot;">
<span class="control-error" v-if="errors.has('city')">@{{ errors.first('city') }}</span>
</div>
<div class="control-group" :class="[errors.has('postcode') ? 'has-error' : '']">
<label for="postcode" class="required">{{ __('shop::app.customer.account.address.create.postcode') }}</label>
<input type="text" class="control" name="postcode" v-validate="'required'" data-vv-as="&quot;{{ __('shop::app.customer.account.address.create.postcode') }}&quot;">
<input value="<?= old('postcode'); ?>" type="text" class="control" name="postcode" v-validate="'required'" data-vv-as="&quot;{{ __('shop::app.customer.account.address.create.postcode') }}&quot;">
<span class="control-error" v-if="errors.has('postcode')">@{{ errors.first('postcode') }}</span>
</div>
<div class="control-group" :class="[errors.has('phone') ? 'has-error' : '']">
<label for="phone" class="required">{{ __('shop::app.customer.account.address.create.phone') }}</label>
<input type="text" class="control" name="phone" v-validate="'required'" data-vv-as="&quot;{{ __('shop::app.customer.account.address.create.phone') }}&quot;">
<input value="<?= old('phone'); ?>" type="text" class="control" name="phone" v-validate="'required'" data-vv-as="&quot;{{ __('shop::app.customer.account.address.create.phone') }}&quot;">
<span class="control-error" v-if="errors.has('phone')">@{{ errors.first('phone') }}</span>
</div>

View File

@ -18,8 +18,8 @@
</div>
{!! view_render_event('bagisto.shop.customers.account.address.edit.before', ['address' => $address]) !!}
<form method="post" action="{{ route('customer.address.edit', $address->id) }}" @submit.prevent="onSubmit">
<form id="customer-address-form" method="post" action="{{ route('customer.address.edit', $address->id) }}" @submit.prevent="onSubmit">
<div class="account-table-content">
@method('PUT')
@ -27,6 +27,24 @@
{!! view_render_event('bagisto.shop.customers.account.address.edit_form_controls.before', ['address' => $address]) !!}
<div class="control-group" :class="[errors.has('company_name') ? 'has-error' : '']">
<label for="company_name">{{ __('shop::app.customer.account.address.edit.company_name') }}</label>
<input type="text" value="{{ $address->company_name }}" class="control" name="company_name" data-vv-as="&quot;{{ __('shop::app.customer.account.address.edit.company_name') }}&quot;">
<span class="control-error" v-if="errors.has('company_name')">@{{ errors.first('company_name') }}</span>
</div>
<div class="control-group {!! $errors->has('vat_id') ? 'has-error' : '' !!}">
<label for="vat_id">{{ __('shop::app.customer.account.address.create.vat_id') }}</label>
<input type="text" class="control" name="vat_id"
value="{{ $address->vat_id }}"
data-vv-as="&quot;{{ __('shop::app.customer.account.address.create.vat_id') }}&quot;">
<span class="control-error" v-if="{!! $errors->has('vat_id') !!}">
@foreach ($errors->get('vat_id') as $message)
{{ $message }}
@endforeach
</span>
</div>
<?php $addresses = explode(PHP_EOL, $address->address1); ?>

View File

@ -6,95 +6,108 @@
@section('content-wrapper')
<div class="account-content">
<div class="account-content">
@include('shop::customers.account.partials.sidemenu')
@include('shop::customers.account.partials.sidemenu')
<div class="account-layout">
<div class="account-layout">
<div class="account-head">
<span class="back-icon"><a href="{{ route('customer.account.index') }}"><i class="icon icon-menu-back"></i></a></span>
<span class="account-heading">{{ __('shop::app.customer.account.address.index.title') }}</span>
<div class="account-head">
<span class="back-icon"><a href="{{ route('customer.account.index') }}"><i
class="icon icon-menu-back"></i></a></span>
<span
class="account-heading">{{ __('shop::app.customer.account.address.index.title') }}</span>
@if (! $addresses->isEmpty())
<span class="account-action">
@if (! $addresses->isEmpty())
<span class="account-action">
<a href="{{ route('customer.address.create') }}">{{ __('shop::app.customer.account.address.index.add') }}</a>
</span>
@else
<span></span>
@endif
<div class="horizontal-rule"></div>
</div>
@else
<span></span>
@endif
<div class="horizontal-rule"></div>
</div>
{!! view_render_event('bagisto.shop.customers.account.address.list.before', ['addresses' => $addresses]) !!}
{!! view_render_event('bagisto.shop.customers.account.address.list.before', ['addresses' => $addresses]) !!}
<div class="account-table-content">
@if ($addresses->isEmpty())
<div>{{ __('shop::app.customer.account.address.index.empty') }}</div>
<br/>
<a href="{{ route('customer.address.create') }}">{{ __('shop::app.customer.account.address.index.add') }}</a>
@else
<div class="address-holder">
@foreach ($addresses as $address)
<div class="address-card">
<div class="details">
<span class="bold">{{ auth()->guard('customer')->user()->name }}</span>
<ul class="address-card-list">
<li class="mt-5">
{{ $address->name }}
</li>
<div class="account-table-content">
@if ($addresses->isEmpty())
<div>{{ __('shop::app.customer.account.address.index.empty') }}</div>
<br/>
<a href="{{ route('customer.address.create') }}">{{ __('shop::app.customer.account.address.index.add') }}</a>
@else
<div class="address-holder">
@foreach ($addresses as $address)
<div class="address-card">
<div class="details">
<span
class="bold">{{ auth()->guard('customer')->user()->name }}</span>
<ul class="address-card-list">
<li class="mt-5">
{{ $address->company_name }}
</li>
<li class="mt-5">
{{ $address->address1 }},
</li>
<li class="mt-5">
{{ $address->first_name }}
</li>
<li class="mt-5">
{{ $address->city }}
</li>
<li class="mt-5">
{{ $address->last_name }}
</li>
<li class="mt-5">
{{ $address->state }}
</li>
<li class="mt-5">
{{ $address->address1 }},
</li>
<li class="mt-5">
{{ core()->country_name($address->country) }} {{ $address->postcode }}
</li>
<li class="mt-5">
{{ $address->city }}
</li>
<li class="mt-10">
{{ __('shop::app.customer.account.address.index.contact') }} : {{ $address->phone }}
</li>
</ul>
<li class="mt-5">
{{ $address->state }}
</li>
<div class="control-links mt-20">
<li class="mt-5">
{{ core()->country_name($address->country) }} {{ $address->postcode }}
</li>
<li class="mt-10">
{{ __('shop::app.customer.account.address.index.contact') }}
: {{ $address->phone }}
</li>
</ul>
<div class="control-links mt-20">
<span>
<a href="{{ route('customer.address.edit', $address->id) }}">
{{ __('shop::app.customer.account.address.index.edit') }}
</a>
</span>
<span>
<a href="{{ route('address.delete', $address->id) }}" onclick="deleteAddress('{{ __('shop::app.customer.account.address.index.confirm-delete') }}')">
<span>
<a href="{{ route('address.delete', $address->id) }}"
onclick="deleteAddress('{{ __('shop::app.customer.account.address.index.confirm-delete') }}')">
{{ __('shop::app.customer.account.address.index.delete') }}
</a>
</span>
</div>
</div>
</div>
</div>
@endforeach
</div>
@endif
</div>
@endforeach
</div>
@endif
</div>
{!! view_render_event('bagisto.shop.customers.account.address.list.after', ['addresses' => $addresses]) !!}
{!! view_render_event('bagisto.shop.customers.account.address.list.after', ['addresses' => $addresses]) !!}
</div>
</div>
</div>
@endsection
@push('scripts')
<script>
function deleteAddress(message) {
if (!confirm(message))
event.preventDefault();
event.preventDefault();
}
</script>
@endpush

View File

@ -42,13 +42,10 @@
@endif
<?php
$query = parse_url(\Illuminate\Support\Facades\Request::path(), PHP_URL_QUERY);
$searchTerm = explode("&", $query);
$term = request()->input('term');
foreach($searchTerm as $term){
if (strpos($term, 'term') !== false) {
$serachQuery = $term;
}
if (! is_null($term)) {
$serachQuery = 'term='.request()->input('term');
}
?>

View File

@ -29,13 +29,10 @@
</div>
<?php
$query = parse_url(\Illuminate\Support\Facades\Request::path(), PHP_URL_QUERY);
$searchTerm = explode("&", $query);
$term = request()->input('term');
foreach($searchTerm as $term){
if (strpos($term, 'term') !== false) {
$serachQuery = $term;
}
if (! is_null($term)) {
$serachQuery = 'term='.request()->input('term');
}
?>

View File

@ -182,7 +182,7 @@
data: function() {
return {
selected_product: (this.option.type == 'checkbox' || this.option.type == 'multiselect') ? [] : null,
qty_validations: ''
}
},

View File

@ -282,6 +282,7 @@ class TaxRateController extends Controller
}
}
} catch (\Exception $e) {
report($e);
$failure = new Failure(1, 'rows', [0 => trans('admin::app.export.enough-row-error')]);
session()->flash('error', $failure->errors()[0]);

View File

@ -16,7 +16,10 @@
"jquery": "^3.4.1",
"laravel-mix": "^5.0.0",
"laravel-mix-merge-manifest": "^0.1.2",
"vue": "^2.6.10"
"sass": "^1.24.4",
"sass-loader": "^8.0.2",
"vue": "^2.6.10",
"vue-template-compiler": "^2.6.11"
},
"dependencies": {
"@babel/polyfill": "^7.7.0",

File diff suppressed because one or more lines are too long

View File

@ -1,4 +1,4 @@
{
"/js/ui.js": "/js/ui.js?id=ed9978ac7d054203f0bc",
"/js/ui.js": "/js/ui.js?id=d6802d7d61cdbdfc21e5",
"/css/ui.css": "/css/ui.css?id=0895b560bbc19259cee8"
}

View File

@ -14,6 +14,7 @@ import ImageUpload from './components/image/image-upload';
import ImageWrapper from './components/image/image-wrapper';
import ImageItem from './components/image/image-item';
import Slugify from './directives/slugify';
import SlugifyTarget from './directives/slugify-target';
import Code from './directives/code';
import Alert from './directives/alert';
import DatetimeComponent from './components/datetime';
@ -35,6 +36,7 @@ Vue.component('image-upload', ImageUpload);
Vue.component('image-wrapper', ImageWrapper);
Vue.component('image-item', ImageItem);
Vue.directive('slugify', Slugify);
Vue.directive('slugify-target', SlugifyTarget);
Vue.directive('code', Code);
Vue.directive('alert', Alert);
Vue.component('datetime', DatetimeComponent);

View File

@ -0,0 +1,24 @@
<script>
export default {
bind(el, binding, vnode) {
let handler = function (e) {
setTimeout(function () {
var target = document.getElementById(binding.value);
target.value = e.target.value.toString()
.toLowerCase()
.replace(/[^\w- ]+/g, '')
// replace whitespaces with dashes
.replace(/ +/g, '-')
// avoid having multiple dashes (---- translates into -)
.replace('![-\s]+!u', '-')
.trim();
}, 100);
};
el.addEventListener('input', handler);
}
}
</script>

View File

@ -2,6 +2,7 @@
namespace Webkul\User\Database\Seeders;
use Illuminate\Support\Str;
use Illuminate\Database\Seeder;
use DB;
@ -16,6 +17,9 @@ class AdminsTableSeeder extends Seeder
'name' => 'Example',
'email' => 'admin@example.com',
'password' => bcrypt('admin123'),
'api_token' => Str::random(80),
'created_at' => date('Y-m-d H:i:s'),
'updated_at' => date('Y-m-d H:i:s'),
'status' => 1,
'role_id' => 1,
]);

Some files were not shown because too many files have changed in this diff Show More