Conflicts resolved

This commit is contained in:
jitendra 2020-11-09 17:02:00 +05:30
commit 67fc98db83
146 changed files with 3089 additions and 3216 deletions

View File

@ -40,7 +40,6 @@ jobs:
- name: Composer install
run: |
set -e
composer global require hirak/prestissimo
composer install --no-interaction --ansi --no-progress --no-suggest --optimize-autoloader
- name: Migrate database

View File

@ -5,9 +5,9 @@
"framework",
"laravel"
],
"license": "MIT",
"type": "project",
"require": {
"php": "^7.2.5",
"ext-curl": "*",
@ -25,6 +25,7 @@
"doctrine/dbal": "2.9.2",
"fideloper/proxy": "^4.2",
"flynsarmy/db-blade-compiler": "^5.5",
"fzaninotto/faker": "^1.4",
"guzzlehttp/guzzle": "~6.3",
"intervention/image": "^2.4",
"intervention/imagecache": "^2.3",
@ -48,7 +49,6 @@
"codeception/module-laravel5": "^1.0",
"codeception/module-webdriver": "^1.0",
"filp/whoops": "^2.0",
"fzaninotto/faker": "^1.4",
"mockery/mockery": "^1.3.1",
"nunomaduro/collision": "^4.1",
"phpunit/phpunit": "^8.5"
@ -123,7 +123,6 @@
"extra": {
"laravel": {
"dont-discover": [
"barryvdh/laravel-debugbar",
"laravel/dusk"
]
}
@ -143,6 +142,7 @@
"Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
"@php artisan package:discover"
],
"test": [
"set -e",
"@php artisan migrate:fresh --env=testing",

2743
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -246,8 +246,6 @@ return [
//Laravel Maatwebsite
Maatwebsite\Excel\ExcelServiceProvider::class,
Barryvdh\Debugbar\ServiceProvider::class,
//Repository
Prettus\Repository\Providers\RepositoryServiceProvider::class,
Konekt\Concord\ConcordServiceProvider::class,

View File

@ -66,6 +66,6 @@ return array(
|
*/
'lifetime' => 43200,
'lifetime' => 525600,
);

View File

@ -0,0 +1,106 @@
<?php
namespace Webkul\API\Http\Controllers\Shop;
class InvoiceController extends Controller
{
/**
* Contains current guard.
*
* @var array
*/
protected $guard;
/**
* Contains route related configuration.
*
* @var array
*/
protected $_config;
/**
* Repository object.
*
* @var \Webkul\Core\Eloquent\Repository
*/
protected $repository;
/**
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
$this->guard = request()->has('token') ? 'api' : 'customer';
$this->_config = request('_config');
if (isset($this->_config['authorization_required']) && $this->_config['authorization_required']) {
auth()->setDefaultDriver($this->guard);
$this->middleware('auth:' . $this->guard);
}
if ($this->_config) {
$this->repository = app($this->_config['repository']);
}
}
/**
* Returns a listing of the invoices.
*
* @return \Illuminate\Http\Response
*/
public function index()
{
$query = $this->repository->scopeQuery(function($query) {
$query = $query->leftJoin('orders', 'invoices.order_id', '=', 'orders.id')->select('invoices.*', 'orders.customer_id');
if (isset($this->_config['authorization_required']) && $this->_config['authorization_required']) {
$query = $query->where('customer_id', auth()->user()->id);
}
foreach (request()->except(['page', 'limit', 'pagination', 'sort', 'order', 'token']) as $input => $value) {
$query = $query->whereIn($input, array_map('trim', explode(',', $value)));
}
if ($sort = request()->input('sort')) {
$query = $query->orderBy($sort, request()->input('order') ?? 'desc');
} else {
$query = $query->orderBy('id', 'desc');
}
return $query;
});
if (is_null(request()->input('pagination')) || request()->input('pagination')) {
$results = $query->paginate(request()->input('limit') ?? 10);
} else {
$results = $query->get();
}
return $this->_config['resource']::collection($results);
}
/**
* Returns an individual invoice.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function get($id)
{
if (isset($this->_config['authorization_required']) && $this->_config['authorization_required']) {
$query = $this->repository->leftJoin('orders', 'invoices.order_id', '=', 'orders.id')
->select('invoices.*', 'orders.customer_id')
->where('customer_id', auth()->user()->id)
->findOrFail($id);
} else {
$query = $this->repository->findOrFail($id);
}
return new $this->_config['resource']($query);
}
}

View File

@ -12,7 +12,7 @@ class ResourceController extends Controller
* @var array
*/
protected $guard;
/**
* Contains route related configuration
*
@ -45,7 +45,9 @@ class ResourceController extends Controller
$this->middleware('auth:' . $this->guard);
}
$this->repository = app($this->_config['repository']);
if ($this->_config) {
$this->repository = app($this->_config['repository']);
}
}
/**
@ -58,8 +60,8 @@ class ResourceController extends Controller
$query = $this->repository->scopeQuery(function($query) {
if (isset($this->_config['authorization_required']) && $this->_config['authorization_required']) {
$query = $query->where('customer_id', auth()->user()->id );
}
}
foreach (request()->except(['page', 'limit', 'pagination', 'sort', 'order', 'token']) as $input => $value) {
$query = $query->whereIn($input, array_map('trim', explode(',', $value)));
}
@ -89,11 +91,11 @@ class ResourceController extends Controller
* @return \Illuminate\Http\Response
*/
public function get($id)
{
$query = isset($this->_config['authorization_required']) && $this->_config['authorization_required'] ?
$this->repository->where('customer_id', auth()->user()->id)->findOrFail($id) :
{
$query = isset($this->_config['authorization_required']) && $this->_config['authorization_required'] ?
$this->repository->where('customer_id', auth()->user()->id)->findOrFail($id) :
$this->repository->findOrFail($id);
return new $this->_config['resource']($query);
}
@ -108,7 +110,7 @@ class ResourceController extends Controller
$wishlistProduct = $this->repository->findOrFail($id);
$this->repository->delete($id);
return response()->json([
'message' => 'Item removed successfully.',
]);

View File

@ -31,6 +31,8 @@ class Product extends JsonResource
{
$product = $this->product ? $this->product : $this;
$prices = $product->getTypeInstance()->getProductPrices();
return [
'id' => $product->id,
'type' => $product->type,
@ -49,13 +51,21 @@ class Product extends JsonResource
'super_attributes' => Attribute::collection($product->super_attributes),
]),
'special_price' => $this->when(
$product->getTypeInstance()->haveSpecialPrice(),
$product->getTypeInstance()->getSpecialPrice()
),
$product->getTypeInstance()->haveSpecialPrice(),
$product->getTypeInstance()->getSpecialPrice()
),
'formated_special_price' => $this->when(
$product->getTypeInstance()->haveSpecialPrice(),
core()->currency($product->getTypeInstance()->getSpecialPrice())
),
$product->getTypeInstance()->haveSpecialPrice(),
core()->currency($product->getTypeInstance()->getSpecialPrice())
),
'regular_price' => $this->when(
$product->getTypeInstance()->haveSpecialPrice(),
data_get($prices, 'regular_price.price')
),
'formated_regular_price' => $this->when(
$product->getTypeInstance()->haveSpecialPrice(),
data_get($prices, 'regular_price.formated_price')
),
'reviews' => [
'total' => $total = $this->productReviewHelper->getTotalReviews($product),
'total_rating' => $total ? $this->productReviewHelper->getTotalRating($product) : 0,
@ -67,4 +77,4 @@ class Product extends JsonResource
'updated_at' => $this->updated_at,
];
}
}
}

View File

@ -202,13 +202,13 @@ Route::group(['prefix' => 'api'], function ($router) {
//Invoice routes
Route::get('invoices', 'ResourceController@index')->defaults('_config', [
Route::get('invoices', 'InvoiceController@index')->defaults('_config', [
'repository' => 'Webkul\Sales\Repositories\InvoiceRepository',
'resource' => 'Webkul\API\Http\Resources\Sales\Invoice',
'authorization_required' => true
]);
Route::get('invoices/{id}', 'ResourceController@get')->defaults('_config', [
Route::get('invoices/{id}', 'InvoiceController@get')->defaults('_config', [
'repository' => 'Webkul\Sales\Repositories\InvoiceRepository',
'resource' => 'Webkul\API\Http\Resources\Sales\Invoice',
'authorization_required' => true

File diff suppressed because one or more lines are too long

View File

@ -1,4 +1,4 @@
{
"/js/admin.js": "/js/admin.js?id=b022291aa1cad7dfcc84",
"/css/admin.css": "/css/admin.css?id=8f4fcca5914f5370ddda"
"/css/admin.css": "/css/admin.css?id=f2b20e4283a639808ef6"
}

View File

@ -121,13 +121,13 @@ return [
'title' => 'admin::app.admin.system.logo-image',
'type' => 'image',
'channel_based' => true,
'validation' => 'mimes:jpeg,bmp,png,jpg',
'validation' => 'mimes:bmp,jpeg,jpg,png,webp',
], [
'name' => 'favicon',
'title' => 'admin::app.admin.system.favicon',
'type' => 'image',
'channel_based' => true,
'validation' => 'mimes:jpeg,bmp,png,jpg',
'validation' => 'mimes:bmp,jpeg,jpg,png,webp',
],
],
], [

View File

@ -12,11 +12,15 @@ class CartRuleCouponDataGrid extends DataGrid
protected $sortOrder = 'desc';
public function prepareQueryBuilder()
{
$queryBuilder = DB::table('cart_rule_coupons')
->addSelect('id', 'code', 'created_at', 'expired_at', 'times_used')
->where('cart_rule_coupons.cart_rule_id', collect(request()->segments())->last());
{
$route = request()->route() ? request()->route()->getName() : "" ;
$cartRuleId = $route == 'admin.cart-rules.edit' ? collect(request()->segments())->last() : last(explode("/", url()->previous()));
$queryBuilder = DB::table('cart_rule_coupons')
->addSelect('id', 'code', 'created_at', 'expired_at', 'times_used')
->where('cart_rule_coupons.cart_rule_id', $cartRuleId);
$this->setQueryBuilder($queryBuilder);
}

View File

@ -99,6 +99,14 @@ class CategoryDataGrid extends DataGrid
'route' => 'admin.catalog.categories.delete',
'confirm_text' => trans('ui::app.datagrid.massaction.delete', ['resource' => 'product']),
'icon' => 'icon trash-icon',
'function' => 'deleteFunction($event, "delete")'
]);
$this->addMassAction([
'type' => 'delete',
'label' => trans('admin::app.datagrid.delete'),
'action' => route('admin.catalog.categories.massdelete'),
'method' => 'DELETE',
]);
}
}

View File

@ -7,17 +7,6 @@ use Excel;
class ExportController extends Controller
{
protected $exportableGrids = [
'OrderDataGrid',
'OrderInvoicesDataGrid',
'OrderShipmentsDataGrid',
'OrderRefundDataGrid',
'CustomerDataGrid',
'TaxRateDataGrid',
'ProductDataGrid',
'CMSPageDataGrid',
];
/**
* Create a new controller instance.
*
@ -43,18 +32,6 @@ class ExportController extends Controller
$path = '\Webkul\Admin\DataGrids'.'\\'.last($gridName);
$proceed = false;
foreach ($this->exportableGrids as $exportableGrid) {
if (last($gridName) == $exportableGrid) {
$proceed = true;
}
}
if (! $proceed) {
return redirect()->back();
}
$gridInstance = new $path;
$records = $gridInstance->export();

View File

@ -58,7 +58,7 @@ class ConfigurationForm extends FormRequest
&& ! request()->input('general.design.admin_logo.logo_image.delete')
) {
$this->rules = array_merge($this->rules, [
'general.design.admin_logo.logo_image' => 'required|mimes:jpeg,bmp,png,jpg|max:5000',
'general.design.admin_logo.logo_image' => 'required|mimes:bmp,jpeg,jpg,png,webp|max:5000',
]);
}
@ -66,7 +66,7 @@ class ConfigurationForm extends FormRequest
&& ! request()->input('general.design.admin_logo.favicon.delete')
) {
$this->rules = array_merge($this->rules, [
'general.design.admin_logo.favicon' => 'required|mimes:jpeg,bmp,png,jpg|max:5000',
'general.design.admin_logo.favicon' => 'required|mimes:bmp,jpeg,jpg,png,webp|max:5000',
]);
}
@ -74,7 +74,7 @@ class ConfigurationForm extends FormRequest
&& ! request()->input('sales.orderSettings.invoice_slip_design.logo.delete')
) {
$this->rules = array_merge($this->rules, [
'sales.orderSettings.invoice_slip_design.logo' => 'required|mimes:jpeg,bmp,png,jpg|max:5000',
'sales.orderSettings.invoice_slip_design.logo' => 'required|mimes:bmp,jpeg,jpg,png,webp|max:5000',
]);
}
@ -89,7 +89,7 @@ class ConfigurationForm extends FormRequest
public function messages()
{
return [
'general.design.admin_logo.logo_image.mimes' => 'Invalid file format. Use only jpeg, bmp, png, jpg.',
'general.design.admin_logo.logo_image.mimes' => 'Invalid file format. Use only bmp, jpeg, jpg, png and webp.',
'catalog.products.storefront.products_per_page.comma_seperated_integer' => 'The "Product Per Page" field must be numeric and may contain comma.'
];
}

View File

@ -335,6 +335,13 @@ Route::group(['middleware' => ['web']], function () {
Route::post('/categories/delete/{id}', 'Webkul\Category\Http\Controllers\CategoryController@destroy')->name('admin.catalog.categories.delete');
//category massdelete
Route::post('categories/massdelete', 'Webkul\Category\Http\Controllers\CategoryController@massDestroy')->defaults('_config', [
'redirect' => 'admin.catalog.categories.index',
])->name('admin.catalog.categories.massdelete');
Route::post('/categories/product/count', 'Webkul\Category\Http\Controllers\CategoryController@categoryProductCount')->name('admin.catalog.categories.product.count');
// Catalog Attribute Routes
Route::get('/attributes', 'Webkul\Attribute\Http\Controllers\AttributeController@index')->defaults('_config', [

View File

@ -174,6 +174,10 @@
float: left;
}
.multiselect {
text-align: unset;
}
.pagination .page-item .icon {
transform: rotate(180deg);
}

View File

@ -2,7 +2,7 @@
return [
'save' => 'حفظ',
'create' => 'خلق',
'create' => 'إنشاء',
'update' => 'تحديث',
'delete' => 'حذف',
'copy-of' => 'نسخة من ',
@ -47,20 +47,20 @@ return [
'my-account' => 'حسابي',
'logout' => 'خروج',
'visit-shop' => 'قم بزيارة المتجر',
'dashboard' => 'لوحة العدادات',
'dashboard' => 'لوحة التحكم',
'sales' => 'المبيعات',
'orders' => 'الأوامر',
'orders' => 'الطلبات',
'shipments' => 'الشحنات',
'invoices' => 'الفواتير',
'catalog' => 'فهرس',
'products' => 'المنتجات',
'categories' => 'الفئات',
'attributes' => 'الصفات',
'attributes' => 'الخصائص',
'attribute-families' => 'وصف الأسر',
'customers' => 'زبائن',
'groups' => 'المجموعات',
'reviews' => 'باء-الاستعراضات',
'newsletter-subscriptions' => 'الاشتراك في الرسالة الإخبارية',
'reviews' => 'التقييمات',
'newsletter-subscriptions' => 'الاشتراك في النشرة البريدية',
'configure' => 'اضبط',
'settings' => 'إعدادات',
'locales' => 'لغات',
@ -81,9 +81,9 @@ return [
],
'acl' => [
'dashboard' => 'لوحة العدادات',
'dashboard' => 'لوحة التحكم',
'sales' => 'المبيعات',
'orders' => 'الأوامر',
'orders' => 'الطلبات',
'shipments' => 'الشحنات',
'invoices' => 'الفواتير',
'catalog' => 'فهرس',
@ -117,7 +117,7 @@ return [
],
'dashboard' => [
'title' => 'لوحة العدادات',
'title' => 'لوحة التحكم',
'from' => 'من',
'to' => 'إلى',
'total-customers' => 'مجموع الزبائن',
@ -140,10 +140,10 @@ return [
'datagrid' => [
'mass-ops' => [
'method-error' => 'خطأ! تم اكتشاف طريقة خاطئة ، الرجاء التحقق من تشكيل حركة الكتلة',
'delete-success' => "تم حذف المورد بنجاح :Selected",
'method-error' => 'خطأ! تم اكتشاف طريقة خاطئة، الرجاء التحقق من تشكيل حركة الكتلة',
'delete-success' => "تم الحذف بنجاح :Selected",
'partial-action' => 'ولم تنفذ بعض الإجراءات بسبب القيود المفروضة على النظام :resource',
'update-success' => "تم تحديث المورد بنجاح :Selected",
'update-success' => "تم التحديث بنجاح :Selected",
'no-resource' => 'المورد المقدم غير كاف للعمل',
],
@ -154,7 +154,7 @@ return [
'copy' => 'نسخ',
'name' => 'اسم',
'direction' => 'اتجاه',
'fullname' => 'الاسم الكامل',
'fullname' => 'الاسم بالكامل',
'type' => 'النوع',
'required' => 'مطلوب',
'unique' => 'فريد',
@ -171,10 +171,10 @@ return [
'layout' => 'نسق',
'url-key' => 'مفتاح URL',
'comment' => 'تعليق',
'product-name' => 'المنتج',
'product-name' => 'إسم المنتج',
'currency-name' => 'اسم العملة',
'exch-rate' => 'باء-سعر الصرف',
'priority' => 'Priority',
'priority' => 'الأولوية',
'subscribed' => 'مشترك',
'base-total' => 'المجموع الأساسي',
'grand-total' => 'المجموع الكلي',
@ -232,10 +232,10 @@ return [
'account' => [
'title' => 'حسابي',
'save-btn-title' => 'احفظ',
'general' => 'ألف-لمحة عامة',
'general' => 'عام',
'name' => 'اسم',
'email' => 'البريد الإلكتروني',
'password' => 'كلمه السر',
'password' => 'كلمه المرور',
'confirm-password' => 'تأكيد كلمة المرور',
'change-password' => 'غير كلمة سر الحساب',
'current-password' => 'كلمة المرور الحالية'
@ -243,22 +243,22 @@ return [
'users' => [
'forget-password' => [
'title' => 'انس كلمة السر',
'header-title' => 'استرجع كلمة السر',
'title' => 'نسيت كلمة المرور',
'header-title' => 'استرجع كلمة المرور',
'email' => 'البريد الإلكتروني المسجل',
'password' => 'كلمه السر',
'password' => 'كلمه المرور',
'confirm-password' => 'تأكيد كلمة المرور',
'back-link-title' => 'العودة للتوقيع',
'submit-btn-title' => 'بريد إلكتروني كلمة مرور إعادة تعيين وصلة'
],
'reset-password' => [
'title' => 'أعد ضبط كلمة السر',
'title' => 'أعد ضبط كلمة المرور',
'email' => 'البريد الإلكتروني المسجل',
'password' => 'كلمه السر',
'password' => 'كلمه المرور',
'confirm-password' => 'تأكيد كلمة المرور',
'back-link-title' => 'العودة للتوقيع',
'submit-btn-title' => 'أعد ضبط كلمة السر'
'submit-btn-title' => 'أعد ضبط كلمة المرور'
],
'roles' => [
@ -266,10 +266,10 @@ return [
'add-role-title' => 'أضف الدور',
'edit-role-title' => 'حرر الدور',
'save-btn-title' => 'احفظ الدور',
'general' => 'ألف-لمحة عامة',
'general' => 'عام',
'name' => 'اسم',
'description' => 'الوصف',
'access-control' => 'مراقبة الدخول',
'access-control' => 'صلاحيات الوصول',
'permissions' => 'الأذون',
'custom' => 'مخصص',
'all' => 'الكل'
@ -280,33 +280,33 @@ return [
'add-user-title' => 'إضافة مستخدم',
'edit-user-title' => 'حرر المستخدم',
'save-btn-title' => 'احفظ المستخدم',
'general' => 'ألف-لمحة عامة',
'general' => 'عام',
'email' => 'البريد الإلكتروني',
'name' => 'اسم',
'password' => 'كلمه الس',
'password' => 'كلمه المرور',
'confirm-password' => 'تأكيد كلمة المرور',
'status-and-role' => 'المركز والدور',
'role' => 'الدور',
'status' => 'الحالة',
'account-is-active' => 'الحساب نشط',
'current-password' => 'أدخل كلمة السر الحالية',
'current-password' => 'أدخل كلمة المرور الحالية',
'confirm-delete' => 'تأكيد حذف هذا الحساب',
'confirm-delete-title' => 'تأكيد كلمة السر قبل حذف',
'confirm-delete-title' => 'تأكيد كلمة المرور قبل حذف',
'delete-last' => 'على الأقل مدير واحد مطلوب.',
'delete-success' => 'نجاح! حذف المستخدم',
'incorrect-password' => 'كلمة السر التي أدخلتها غير صحيحة',
'password-match' => 'كلمة السر الحالية لا تطابق.',
'incorrect-password' => 'كلمة المرور التي أدخلتها غير صحيحة',
'password-match' => 'كلمة المرور الحالية لا تطابق.',
'account-save' => 'الحساب التغييرات و الموفرة بنجاح.',
'login-error' => 'الرجاء التحقق من أوراق اعتمادك ومحاولة مرة أخرى.',
'activate-warning' => 'حسابك لم يتم تفعيله بعد ، الرجاء الاتصال بالمدير.'
'activate-warning' => 'حسابك لم يتم تفعيله بعد، الرجاء الاتصال بالمدير.'
],
'sessions' => [
'title' => 'وقع هنا',
'email' => 'البريد الإلكتروني',
'password' => 'كلمه السر',
'forget-password-link-title' => 'نسيت كلمة السر ؟',
'remember-me' => 'تذكريني',
'password' => 'كلمه المرور',
'forget-password-link-title' => 'نسيت كلمة المرور؟',
'remember-me' => 'تذكرني',
'submit-btn-title' => 'وقع هنا'
]
],
@ -1235,7 +1235,7 @@ return [
'admin' => [
'emails' => [
'email' => 'Email',
'email' => 'البريد الإلكتروني',
'notification_label' => 'إشعارات',
'notifications' => [
'verification' => 'ارسل ايميل التفعيل',
@ -1301,6 +1301,11 @@ return [
'weight-unit' => 'وحدة الوزن',
'admin-page-limit' => 'العناصر الافتراضية لكل صفحة (المشرف)',
'design' => 'التصميم',
'email-settings' => 'إعدادات البريد الإلكتروني',
'email-sender-name' => 'اسم مرسل البريد الإلكتروني',
'shop-email-from' => 'متجر عنوان البريد الإلكتروني [لإرسال رسائل البريد الإلكتروني]',
'admin-name' => 'اسم المسؤول',
'admin-email' => 'البريد الإلكتروني للمسؤول',
'admin-logo' => 'شعار المسؤول',
'logo-image' => 'صورة الشعار',
'credit-max' => 'الحد الأقصى لائتمان العميل',
@ -1316,48 +1321,55 @@ return [
'sandbox' => 'صندوق الرمل',
'all-channels' => 'الكل',
'all-locales' => 'الكل',
'invoice-slip-design' => 'Invoice Slip Design',
'logo' => 'Logo',
'storefront' => 'Storefront',
'default-list-mode' => 'Default List Mode',
'grid' => 'Grid',
'list' => 'List',
'products-per-page' => 'Products Per Page',
'sort-by' => 'Sort By',
'invoice-slip-design' => 'تصميم قسيمة الفاتورة',
'logo' => 'شعار',
'storefront' => 'واجهة المحل',
'default-list-mode' => 'وضع القائمة الافتراضي',
'grid' => 'جريد',
'list' => 'قائمة',
'products-per-page' => 'المنتجات في الصفحة',
'sort-by' => 'صنف حسب',
'from-z-a' => 'From Z-A',
'from-a-z' => 'From A-Z',
'newest-first' => 'Newest First',
'oldest-first' => 'Oldest First',
'cheapest-first' => 'Cheapest First',
'expensive-first' => 'Expensive First',
'comma-seperated' => 'Comma Seperated',
'favicon' => 'Favicon',
'comma-seperated' => 'مفصولة بفواصل',
'favicon' => 'فافيكون',
'seo' => 'SEO',
'rich-snippets' => 'Rich Snippets',
'products' => 'Products',
'enable' => 'Enable',
'show-weight' => 'Show Weight',
'show-categories' => 'Show Categories',
'show-images' => 'Show Images',
'show-reviews' => 'Show Reviews',
'show-ratings' => 'Show Ratings',
'show-offers' => 'Show Offers',
'show-sku' => 'Show SKU',
'categories' => 'Categories',
'show-sku' => 'Show SKU',
'show-search-input-field' => 'Show Search Input Field',
'rich-snippets' => 'قصاصات غنية',
'products' => 'منتجات',
'enable' => 'ممكن',
'show-weight' => 'عرض الوزن',
'show-categories' => 'إظهار الفئات',
'show-images' => 'عرض الصور',
'show-reviews' => 'عرض التعليقات',
'show-ratings' => 'إظهار التقييمات',
'show-offers' => 'عرض العروض',
'show-sku' => 'عرض SKU',
'categories' => 'التصنيفات',
'show-sku' => 'عرض SKU',
'show-search-input-field' => 'إظهار حقل إدخال البحث',
'store-name' => 'اسم المتجر',
'vat-number' => 'ظريبه الشراء',
'contact-number' => 'رقم الاتصال',
'bank-details' => 'التفاصيل المصرفية',
'mailing-address' => 'Send Check to',
'instructions' => 'Instructions',
'custom-scripts' => 'Custom Scripts',
'custom-css' => 'Custom CSS',
'custom-javascript' => 'Custom Javascript',
'paypal-smart-button' => 'PayPal',
'client-id' => 'Client Id',
'client-id-info' => 'Use "sb" for testing.'
'client-id-info' => 'Use "sb" for testing.',
'mailing-address' => 'أرسل الشيك إلى',
'instructions' => 'تعليمات',
'custom-scripts' => 'البرامج النصية المخصصة',
'custom-css' => 'لغة تنسيق ويب حسب الطلب',
'custom-javascript' => 'جافا سكريبت مخصص',
'paypal-smart-button' => 'زر PayPal الذكي',
'client-id' => 'معرف العميل',
'client-id-info' => 'استخدم "sb" للاختبار.'
]
]
];

View File

@ -26,4 +26,58 @@
{!! view_render_event('bagisto.admin.catalog.categories.list.after') !!}
</div>
@stop
@stop
@push('scripts')
<script>
$(document).ready(function(){
$("input[type='checkbox']").change(deleteFunction);
});
var deleteFunction = function(e,type) {
if (type == 'delete') {
var indexes = $(e.target).parent().attr('id');
} else {
$("input[type='checkbox']").attr('disabled', true);
var formData = {};
$.each($('form').serializeArray(), function(i, field) {
formData[field.name] = field.value;
});
var indexes = formData.indexes;
}
if (indexes) {
$.ajax({
type : 'POST',
url : '{{route("admin.catalog.categories.product.count")}}',
data : {
_token: '{{csrf_token()}}',
indexes: indexes
},
success:function(data) {
$("input[type='checkbox']").attr('disabled', false);
if (data.product_count > 0) {
var message = "{{trans('ui::app.datagrid.massaction.delete-category-product')}}";
if (type == 'delete') {
doAction(e, message);
} else {
$('form').attr('onsubmit', 'return confirm("'+message+'")');
}
} else {
var message = "{{ __('ui::app.datagrid.click_on_action') }}";
if (type == 'delete') {
doAction(e, message);
} else {
$('form').attr('onsubmit', 'return confirm("'+message+'")');
}
}
}
});
} else {
$("input[type='checkbox']").attr('disabled', false);
}
}
</script>
@endpush

View File

@ -85,7 +85,7 @@
<div class="control-group">
<div class="control-group" :class="[errors.has(inputName + '[value]') ? 'has-error' : '']">
<input type="number" v-validate="'required|min_value:0'" :name="[inputName + '[value]']" v-model="customerGroupPrice.value" class="control" data-vv-as="&quot;{{ __('admin::app.datagrid.price') }}&quot;"/>
<input type="number" v-validate="{required: true, min_value: 0, ...(customerGroupPrice.value_type === 'discount' ? {max_value: 100} : {})}" :name="[inputName + '[value]']" v-model="customerGroupPrice.value" class="control" data-vv-as="&quot;{{ __('admin::app.datagrid.price') }}&quot;"/>
<span class="control-error" v-if="errors.has(inputName + '[value]')">@{{ errors.first(inputName + '[value]') }}</span>
</div>
</div>
@ -159,4 +159,4 @@
}
});
</script>
@endpush
@endpush

View File

@ -96,9 +96,9 @@
array_push($validations, 'size:' . $retVal);
}
if ($attribute->type == 'image') {
if ($attribute->type == 'image') {
$retVal = (core()->getConfigData('catalog.products.attribute.image_attribute_upload_size')) ? core()->getConfigData('catalog.products.attribute.image_attribute_upload_size') : '2048' ;
array_push($validations, 'size:' . $retVal . '|mimes:jpeg, bmp, png, jpg');
array_push($validations, 'size:' . $retVal . '|mimes:bmp,jpeg,jpg,png,webp');
}
array_push($validations, $attribute->validation);

View File

@ -99,7 +99,7 @@
@elseif ($field['type'] == 'password')
<input type="password" v-validate="'{{ $validations }}'" class="control" id="{{ $firstField }}[{{ $secondField }}][{{ $thirdField }}][{{ $field['name'] }}]" name="{{ $firstField }}[{{ $secondField }}][{{ $thirdField }}][{{ $field['name'] }}]" value="{{ old($name) ?: core()->getConfigData($name) }}" data-vv-as="&quot;{{ trans($field['title']) }}&quot;">
@elseif ($field['type'] == 'number')
<input type="number" min="0" v-validate="'{{ $validations }}'" class="control" id="{{ $firstField }}[{{ $secondField }}][{{ $thirdField }}][{{ $field['name'] }}]" name="{{ $firstField }}[{{ $secondField }}][{{ $thirdField }}][{{ $field['name'] }}]" value="{{ old($name) ?: core()->getConfigData($name) }}" data-vv-as="&quot;{{ trans($field['title']) }}&quot;">
@ -111,7 +111,7 @@
@elseif ($field['type'] == 'textarea')
<textarea v-validate="'{{ $validations }}'" class="control" id="{{ $firstField }}[{{ $secondField }}][{{ $thirdField }}][{{ $field['name'] }}]" name="{{ $firstField }}[{{ $secondField }}][{{ $thirdField }}][{{ $field['name'] }}]" data-vv-as="&quot;{{ trans($field['title']) }}&quot;">{{ old($name) ?: core()->getConfigData($name) }}</textarea>
<textarea v-validate="'{{ $validations }}'" class="control" id="{{ $firstField }}[{{ $secondField }}][{{ $thirdField }}][{{ $field['name'] }}]" name="{{ $firstField }}[{{ $secondField }}][{{ $thirdField }}][{{ $field['name'] }}]" data-vv-as="&quot;{{ trans($field['title']) }}&quot;">{{ old($name) ? core()->getConfigData($name) : (isset($field['default_value']) ? $field['default_value'] : '') }}</textarea>
@elseif ($field['type'] == 'select')
@ -215,7 +215,7 @@
@elseif ($field['type'] == 'boolean')
<?php $selectedOption = core()->getConfigData($name) ?? ''; ?>
<?php $selectedOption = core()->getConfigData($name) ?? (isset($field['default_value']) ? $field['default_value'] : ''); ?>
<label class="switch">
<input type="hidden" name="{{ $firstField }}[{{ $secondField }}][{{ $thirdField }}][{{ $field['name'] }}]" value="0" />

View File

@ -12,7 +12,7 @@
@else
<link rel="icon" sizes="16x16" href="{{ asset('vendor/webkul/ui/assets/images/favicon.ico') }}" />
@endif
<link rel="stylesheet" href="{{ asset('vendor/webkul/admin/assets/css/admin.css') }}">
<link rel="stylesheet" href="{{ asset('vendor/webkul/ui/assets/css/ui.css') }}">
@ -71,7 +71,7 @@
{!! view_render_event('bagisto.admin.layout.head') !!}
</head>
<body @if (core()->getCurrentLocale()->direction == 'rtl') class="rtl" @endif style="scroll-behavior: smooth;">
<body @if (core()->getCurrentLocale() && core()->getCurrentLocale()->direction == 'rtl') class="rtl" @endif style="scroll-behavior: smooth;">
<div id="app" class="container">
<flash-wrapper ref='flashes'></flash-wrapper>
@ -81,8 +81,8 @@
<div class="adjacent-center">
<div class="brand-logo">
@if (core()->getConfigData('general.design.admin_logo.logo_image'))
<img src="{{ \Illuminate\Support\Facades\Storage::url(core()->getConfigData('general.design.admin_logo.logo_image')) }}" alt="{{ config('app.name') }}" style="height: 40px; width: 110px;"/>
@if (core()->getConfigData('general.design.admin_logo.logo_image', core()->getCurrentChannelCode()))
<img src="{{ \Illuminate\Support\Facades\Storage::url(core()->getConfigData('general.design.admin_logo.logo_image', core()->getCurrentChannelCode())) }}" alt="{{ config('app.name') }}" style="height: 40px; width: 110px;"/>
@else
<img src="{{ asset('vendor/webkul/ui/assets/images/logo.png') }}" alt="{{ config('app.name') }}"/>
@endif

View File

@ -7,7 +7,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="csrf-token" content="{{ csrf_token() }}">
@if ($favicon = core()->getConfigData('general.design.admin_logo.favicon'))
@if ($favicon = core()->getConfigData('general.design.admin_logo.favicon', core()->getCurrentChannelCode()))
<link rel="icon" sizes="16x16" href="{{ \Illuminate\Support\Facades\Storage::url($favicon) }}" />
@else
<link rel="icon" sizes="16x16" href="{{ asset('vendor/webkul/ui/assets/images/favicon.ico') }}" />

View File

@ -2,8 +2,8 @@
<div class="navbar-top-left">
<div class="brand-logo">
<a href="{{ route('admin.dashboard.index') }}">
@if (core()->getConfigData('general.design.admin_logo.logo_image'))
<img src="{{ \Illuminate\Support\Facades\Storage::url(core()->getConfigData('general.design.admin_logo.logo_image')) }}" alt="{{ config('app.name') }}" style="height: 40px; width: 110px;"/>
@if (core()->getConfigData('general.design.admin_logo.logo_image', core()->getCurrentChannelCode()))
<img src="{{ \Illuminate\Support\Facades\Storage::url(core()->getConfigData('general.design.admin_logo.logo_image', core()->getCurrentChannelCode())) }}" alt="{{ config('app.name') }}" style="height: 40px; width: 110px;"/>
@else
<img src="{{ asset('vendor/webkul/ui/assets/images/logo.png') }}" alt="{{ config('app.name') }}"/>
@endif
@ -32,7 +32,7 @@
<div class="dropdown-list bottom-right">
<span class="app-version">{{ __('admin::app.layouts.app-version', ['version' => 'v' . config('app.version')]) }}</span>
<div class="dropdown-container">
<label>Account</label>
<ul>

View File

@ -457,12 +457,38 @@
</form>
<div class="content">
<div class="page-header">
<div class="page-action">
<div class="export-import" @click="showModal('downloadDataGrid')">
<i class="export-icon"></i>
<span >
{{ __('admin::app.export.export') }}
</span>
</div>
</div>
</div>
</div>
<modal id="downloadDataGrid" :is-open="this.$root.modalIds.downloadDataGrid">
<h3 slot="header">{{ __('admin::app.export.download') }}</h3>
<div slot="body">
<export-form></export-form>
</div>
</modal>
@inject('cartRuleCouponGrid','Webkul\Admin\DataGrids\CartRuleCouponDataGrid')
{!! $cartRuleCouponGrid->render() !!}
</div>
</script>
@push('scripts')
@include('admin::export.export', ['gridName' => $cartRuleCouponGrid])
@endpush
<script>
Vue.component('cart-rule', {
@ -754,7 +780,11 @@
})
}
});
}
},
showModal(id) {
this.$root.$set(this.$root.modalIds, id, true);
},
}
});
</script>

View File

@ -454,8 +454,14 @@
<tr class="bold">
<td>{{ __('admin::app.sales.orders.total-due') }}</td>
<td>-</td>
<td>{{ core()->formatBasePrice($order->base_total_due) }}</td>
@if($order->status !== 'canceled')
<td>{{ core()->formatBasePrice($order->base_total_due) }}</td>
@else
<td id="due-amount-on-cancelled">{{ core()->formatBasePrice(0.00) }}</td>
@endif
</tr>
</table>
</div>

View File

@ -55,16 +55,20 @@
</span>
</div>
<div class="control-group">
<div class="control-group" :class="[errors.has(controlName + '[special_price]') ? 'has-error' : '']">
<label class="ticket-label">{{ __('bookingproduct::app.admin.catalog.products.special-price') }}</label>
<input type="text" :name="controlName + '[special_price]'" v-model="ticketItem.special_price" class="control">
<input type="text" v-validate="{decimal: true, min_value:0, ...(ticketItem.price ? {max_value: ticketItem.price} : {})}" :name="controlName + '[special_price]'" v-model="ticketItem.special_price" class="control" data-vv-as="&quot;{{ __('bookingproduct::app.admin.catalog.products.price') }}&quot;">
<span class="control-error" v-if="errors.has(controlName + '[special_price]')">
@{{ errors.first(controlName + '[special_price]') }}
</span>
</div>
</td>
<td>
<div class="control-group" :class="[errors.has(controlName + '[price]') ? 'has-error' : '']">
<label class="ticket-label">{{ __('bookingproduct::app.admin.catalog.products.price') }}</label>
<input type="text" v-validate="'required'" :name="controlName + '[price]'" v-model="ticketItem.price" class="control" data-vv-as="&quot;{{ __('bookingproduct::app.admin.catalog.products.price') }}&quot;">
<input type="text" v-validate="'required|decimal|min_value:0'" :name="controlName + '[price]'" v-model="ticketItem.price" class="control" data-vv-as="&quot;{{ __('bookingproduct::app.admin.catalog.products.price') }}&quot;">
<span class="control-error" v-if="errors.has(controlName + '[price]')">
@{{ errors.first(controlName + '[price]') }}

View File

@ -8,7 +8,7 @@
<div class="control-group-container">
<div class="form-group date" :class="[errors.has('booking[date]') ? 'has-error' : '']">
<date @onChange="dateSelected($event)">
<date @onChange="dateSelected($event)" :minDate="'{{$bookingProduct->available_from}}'" :maxDate="'{{$bookingProduct->available_to}}'">
<input type="text" v-validate="'required'" name="booking[date]" class="form-style" data-vv-as="&quot;{{ __('bookingproduct::app.shop.products.date') }}&quot;"/>
</date>
@ -24,7 +24,7 @@
</div>
</div>
</div>
</script>
<script>
@ -54,6 +54,6 @@
}
}
});
</script>
@endpush
@endpush

View File

@ -238,6 +238,7 @@ class Booking extends Virtual
}
if (isset($options1['booking'], $options2['booking'])
&& isset($options1['booking']['ticket_id'], $options2['booking']['ticket_id'])
&& $options1['booking']['ticket_id'] === $options2['booking']['ticket_id']) {
return true;
}

View File

@ -119,7 +119,7 @@ class CartRuleController extends Controller
'customer_groups' => 'required|array|min:1',
'coupon_type' => 'required',
'use_auto_generation' => 'required_if:coupon_type,==,1',
'coupon_code' => 'required_if:use_auto_generation,==,0',
'coupon_code' => 'required_if:use_auto_generation,==,0|unique:cart_rule_coupons,code',
'starts_from' => 'nullable|date',
'ends_till' => 'nullable|date|after_or_equal:starts_from',
'action_type' => 'required',
@ -169,7 +169,7 @@ class CartRuleController extends Controller
'customer_groups' => 'required|array|min:1',
'coupon_type' => 'required',
'use_auto_generation' => 'required_if:coupon_type,==,1',
'coupon_code' => 'required_if:use_auto_generation,==,0',
'coupon_code' => 'required_if:use_auto_generation,==,0|unique:cart_rule_coupons,code,' . $id,
'starts_from' => 'nullable|date',
'ends_till' => 'nullable|date|after_or_equal:starts_from',
'action_type' => 'required',

View File

@ -82,7 +82,7 @@ class CategoryController extends Controller
$this->validate(request(), [
'slug' => ['required', 'unique:category_translations,slug', new \Webkul\Core\Contracts\Validations\Slug],
'name' => 'required',
'image.*' => 'mimes:jpeg,jpg,bmp,png',
'image.*' => 'mimes:bmp,jpeg,jpg,png,webp',
'description' => 'required_if:display_mode,==,description_only,products_and_description',
]);
@ -127,7 +127,7 @@ class CategoryController extends Controller
}
}],
$locale . '.name' => 'required',
'image.*' => 'mimes:jpeg,jpg,bmp,png',
'image.*' => 'mimes:bmp,jpeg,jpg,png,webp',
]);
$this->categoryRepository->update(request()->all(), $id);
@ -153,7 +153,10 @@ class CategoryController extends Controller
try {
Event::dispatch('catalog.category.delete.before', $id);
$this->categoryRepository->delete($id);
if($category->products->count() > 0) {
$category->products()->delete();
}
$category->delete();
Event::dispatch('catalog.category.delete.after', $id);
@ -175,36 +178,52 @@ class CategoryController extends Controller
*/
public function massDestroy()
{
$suppressFlash = false;
$suppressFlash = true;
$categoryIds = explode(',', request()->input('indexes'));
if (request()->isMethod('delete') || request()->isMethod('post')) {
$indexes = explode(',', request()->input('indexes'));
foreach ($categoryIds as $categoryId) {
$category = $this->categoryRepository->find($categoryId);
foreach ($indexes as $key => $value) {
try {
Event::dispatch('catalog.category.delete.before', $value);
if (isset($category)) {
if(strtolower($category->name) == "root") {
$suppressFlash = false;
session()->flash('warning', trans('admin::app.response.delete-category-root', ['name' => 'Category']));
} else {
try {
$suppressFlash = true;
Event::dispatch('catalog.category.delete.before', $categoryId);
$this->categoryRepository->delete($value);
if($category->products->count() > 0) {
$category->products()->delete();
}
$category->delete();
Event::dispatch('catalog.category.delete.after', $value);
} catch(\Exception $e) {
$suppressFlash = true;
continue;
Event::dispatch('catalog.category.delete.after', $categoryId);
} catch(\Exception $e) {
session()->flash('error', trans('admin::app.response.delete-failed', ['name' => 'Category']));
}
}
}
if (! $suppressFlash) {
session()->flash('success', trans('admin::app.datagrid.mass-ops.delete-success'));
} else {
session()->flash('info', trans('admin::app.datagrid.mass-ops.partial-action', ['resource' => 'Attribute Family']));
}
return redirect()->back();
} else {
session()->flash('error', trans('admin::app.datagrid.mass-ops.method-error'));
return redirect()->back();
}
if (count($categoryIds) != 1 || $suppressFlash == true) {
session()->flash('success', trans('admin::app.datagrid.mass-ops.delete-success', ['resource' => 'Category']));
}
return redirect()->route($this->_config['redirect']);
}
public function categoryProductCount() {
$indexes = explode(",", request()->input('indexes'));
$product_count = 0;
foreach($indexes as $index) {
$category = $this->categoryRepository->find($index);
$product_count += $category->products->count();
}
return response()->json(['product_count' => $product_count], 200);
}
}

View File

@ -9,6 +9,7 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Webkul\Category\Contracts\Category as CategoryContract;
use Webkul\Attribute\Models\AttributeProxy;
use Webkul\Category\Repositories\CategoryRepository;
use Webkul\Product\Models\ProductProxy;
/**
* Class Category
@ -129,4 +130,12 @@ class Category extends TranslatableModel implements CategoryContract
return $this->findInTree($category->children);
}
/**
* The products that belong to the category.
*/
public function products()
{
return $this->belongsToMany(ProductProxy::modelClass(), 'product_categories');
}
}

View File

@ -38,7 +38,16 @@ class Install extends Command
public function handle()
{
$this->checkForEnvFile();
// cached new changes
$this->warn('Step: Caching new changes...');
$cached = $this->call('config:cache');
$this->info($cached);
// waiting for 2 seconds
$this->warn('Please wait...');
sleep(2);
// running `php artisan migrate`
$this->warn('Step: Migrating all tables into database...');
$migrate = $this->call('migrate:fresh');
@ -64,15 +73,10 @@ class Install extends Command
$result = shell_exec('composer dump-autoload');
$this->info($result);
// cached new changes
$this->warn('Step: Caching new changes...');
$cached = $this->call('config:cache');
$this->info($cached);
$this->info('-----------------------------');
$this->info('Congratulations!');
$this->info('The installation has been finished and you can now use Bagisto.');
$this->info('Go to https://your-site/admin and authenticate with:');
$this->info('Go to '. url(config('app.admin_url')) .' and authenticate with:');
$this->info('Email: admin@example.com');
$this->info('Password: admin123');
$this->info('Cheers!');
@ -107,6 +111,10 @@ class Install extends Command
$input_app_url = $this->ask('Please Enter the APP URL : ');
$this->envUpdate('APP_URL=', $input_app_url ? $input_app_url : $default_app_url );
$default_admin_url = 'admin';
$input_admin_url = $this->ask('Please Enter the Admin URL : ');
$this->envUpdate('APP_ADMIN_URL=', $input_admin_url ?: $default_admin_url);
$locale = $this->choice('Please select the default locale or press enter to continue', ['ar', 'en', 'fa', 'nl', 'pt_BR'], 1);
$this->envUpdate('APP_LOCALE=', $locale);

View File

@ -16,11 +16,12 @@ class ChannelTableSeeder extends Seeder
'code' => 'default',
'name' => 'Default',
'theme' => 'velocity',
'hostname' => config('app.url'),
'root_category_id' => 1,
'home_page_content' => '<p>@include("shop::home.slider") @include("shop::home.featured-products") @include("shop::home.new-products")</p>
<div class="banner-container">
<div class="left-banner"><img data-src="themes/default/assets/images/1.webp" class="lazyload" alt="test" width="720" height="720" /></div>
<div class="right-banner"><img data-src="themes/default/assets/images/2.webp" class="lazyload" alt="test" width="460" height="330" /> <img data-src="themes/default/assets/images/3.webp" class="lazyload" alt="test" width="460" height="330" /></div>
<div class="left-banner"><img src='.asset("/themes/default/assets/images/1.webp").' data-src='.asset("/themes/default/assets/images/1.webp").' class="lazyload" alt="test" width="720" height="720" /></div>
<div class="right-banner"><img src='. asset("/themes/default/assets/images/2.webp").' data-src='. asset("/themes/default/assets/images/2.webp").' class="lazyload" alt="test" width="460" height="330" /> <img src='.asset("/themes/default/assets/images/3.webp").' data-src='.asset("/themes/default/assets/images/3.webp").' class="lazyload" alt="test" width="460" height="330" /></div>
</div>',
'footer_content' => '<div class="list-container"><span class="list-heading">Quick Links</span><ul class="list-group"><li><a href="@php echo route(\'shop.cms.page\', \'about-us\') @endphp">About Us</a></li><li><a href="@php echo route(\'shop.cms.page\', \'return-policy\') @endphp">Return Policy</a></li><li><a href="@php echo route(\'shop.cms.page\', \'refund-policy\') @endphp">Refund Policy</a></li><li><a href="@php echo route(\'shop.cms.page\', \'terms-conditions\') @endphp">Terms and conditions</a></li><li><a href="@php echo route(\'shop.cms.page\', \'terms-of-use\') @endphp">Terms of Use</a></li><li><a href="@php echo route(\'shop.cms.page\', \'contact-us\') @endphp">Contact Us</a></li></ul></div><div class="list-container"><span class="list-heading">Connect With Us</span><ul class="list-group"><li><a href="#"><span class="icon icon-facebook"></span>Facebook </a></li><li><a href="#"><span class="icon icon-twitter"></span> Twitter </a></li><li><a href="#"><span class="icon icon-instagram"></span> Instagram </a></li><li><a href="#"> <span class="icon icon-google-plus"></span>Google+ </a></li><li><a href="#"> <span class="icon icon-linkedin"></span>LinkedIn </a></li></ul></div>',
'name' => 'Default',
@ -44,4 +45,4 @@ class ChannelTableSeeder extends Seeder
'inventory_source_id' => 1,
]);
}
}
}

View File

@ -69,8 +69,8 @@ class ChannelController extends Controller
'currencies' => 'required|array|min:1',
'base_currency_id' => 'required|in_array:currencies.*',
'root_category_id' => 'required',
'logo.*' => 'mimes:jpeg,jpg,bmp,png',
'favicon.*' => 'mimes:jpeg,jpg,bmp,png',
'logo.*' => 'mimes:bmp,jpeg,jpg,png,webp',
'favicon.*' => 'mimes:bmp,jpeg,jpg,png,webp',
'seo_title' => 'required|string',
'seo_description' => 'required|string',
'seo_keywords' => 'required|string',
@ -132,8 +132,8 @@ class ChannelController extends Controller
'currencies' => 'required|array|min:1',
'base_currency_id' => 'required|in_array:currencies.*',
'root_category_id' => 'required',
'logo.*' => 'mimes:jpeg,jpg,bmp,png',
'favicon.*' => 'mimes:jpeg,jpg,bmp,png',
'logo.*' => 'mimes:bmp,jpeg,jpg,png,webp',
'favicon.*' => 'mimes:bmp,jpeg,jpg,png,webp',
'hostname' => 'unique:channels,hostname,' . $id,
]);

View File

@ -58,7 +58,7 @@ class SliderController extends Controller
$channels = core()->getAllChannels();
$locale = request()->get('locale') ?: core()->getCurrentLocale();
return view($this->_config['view'])->with("locale", $locale);
}
@ -72,7 +72,7 @@ class SliderController extends Controller
$this->validate(request(), [
'title' => 'string|required',
'channel_id' => 'required',
'image.*' => 'required|mimes:jpeg,bmp,png,jpg',
'image.*' => 'required|mimes:bmp,jpeg,jpg,png,webp',
]);
$result = $this->sliderRepository->save(request()->all());
@ -109,12 +109,12 @@ class SliderController extends Controller
$this->validate(request(), [
'title' => 'string|required',
'channel_id' => 'required',
'image.*' => 'sometimes|mimes:jpeg,bmp,png,jpg',
'image.*' => 'sometimes|mimes:bmp,jpeg,jpg,png,webp',
]);
if ( is_null(request()->image)) {
session()->flash('error', trans('admin::app.settings.sliders.update-fail'));
return redirect()->back();
}

View File

@ -29,7 +29,6 @@
}
.main-container-wrapper .product-card .product-image img {
height: auto;
max-width: 100%;
}
</style>
@ -102,7 +101,7 @@
}
$('.path-hint-tooltip').css('left', left - minus)
$('.path-hint-tooltip').css('top', currentElement.offset().top + 20)
})

View File

@ -131,7 +131,13 @@ class Toolbar extends AbstractProduct
{
$params = request()->input();
if (isset($params['mode']) && $key == $params['mode']) {
$defaultMode = core()->getConfigData('catalog.products.storefront.mode')
? core()->getConfigData('catalog.products.storefront.mode')
: 'grid';
if (request()->input() == null && $key == $defaultMode) {
return true;
} else if (isset($params['mode']) && $key == $params['mode']) {
return true;
}

View File

@ -64,10 +64,10 @@ class ProductForm extends FormRequest
public function rules()
{
$product = $this->productRepository->find($this->id);
$this->rules = array_merge($product->getTypeInstance()->getTypeValidationRules(), [
'sku' => ['required', 'unique:products,sku,' . $this->id, new \Webkul\Core\Contracts\Validations\Slug],
'images.*' => 'nullable|mimes:jpeg,jpg,bmp,png',
'images.*' => 'nullable|mimes:bmp,jpeg,jpg,png,webp',
'special_price_from' => 'nullable|date',
'special_price_to' => 'nullable|date|after_or_equal:special_price_from',
'special_price' => ['nullable', new \Webkul\Core\Contracts\Validations\Decimal, 'lt:price'],
@ -87,7 +87,7 @@ class ProductForm extends FormRequest
}
if ($attribute->type == 'text' && $attribute->validation) {
array_push($validations,
array_push($validations,
$attribute->validation == 'decimal'
? new \Webkul\Core\Contracts\Validations\Decimal
: $attribute->validation

View File

@ -659,16 +659,22 @@ abstract class AbstractType
continue;
}
if ($price->value < $lastPrice) {
if ($price->value_type == 'discount') {
if ($price->value_type == 'discount') {
if ($price->value >= 0 && $price->value <= 100) {
$lastPrice = $product->price - ($product->price * $price->value) / 100;
} else {
$lastPrice = $price->value;
$lastQty = $price->qty;
$lastCustomerGroupId = $price->customer_group_id;
}
} else {
if ($price->value >= 0 && $price->value < $lastPrice) {
$lastPrice = $price->value;
$lastQty = $price->qty;
$lastQty = $price->qty;
$lastCustomerGroupId = $price->customer_group_id;
$lastCustomerGroupId = $price->customer_group_id;
}
}
}

View File

@ -419,8 +419,8 @@ class Bundle extends AbstractType
$priceHtml .= '<div class="price-from">';
if ($prices['from']['regular_price']['price'] != $prices['from']['final_price']['price']) {
$priceHtml .= '<span class="regular-price">' . $prices['from']['regular_price']['formated_price'] . '</span>'
. '<span class="special-price">' . $prices['from']['final_price']['formated_price'] . '</span>';
$priceHtml .= '<span class="bundle-regular-price">' . $prices['from']['regular_price']['formated_price'] . '</span>'
. '<span class="bundle-special-price">' . $prices['from']['final_price']['formated_price'] . '</span>';
} else {
$priceHtml .= '<span>' . $prices['from']['regular_price']['formated_price'] . '</span>';
}
@ -429,11 +429,11 @@ class Bundle extends AbstractType
if ($prices['from']['regular_price']['price'] != $prices['to']['regular_price']['price']
|| $prices['from']['final_price']['price'] != $prices['to']['final_price']['price']
) {
$priceHtml .= '<span style="font-weight: 500;margin-top: 1px;margin-bottom: 1px;display: block;">To</span>';
$priceHtml .= '<span class="bundle-to">To</span>';
if ($prices['to']['regular_price']['price'] != $prices['to']['final_price']['price']) {
$priceHtml .= '<span class="regular-price">' . $prices['to']['regular_price']['formated_price'] . '</span>'
. '<span class="special-price">' . $prices['to']['final_price']['formated_price'] . '</span>';
$priceHtml .= '<span class="bundle-regular-price">' . $prices['to']['regular_price']['formated_price'] . '</span>'
. '<span class="bundle-special-price">' . $prices['to']['final_price']['formated_price'] . '</span>';
} else {
$priceHtml .= '<span>' . $prices['to']['regular_price']['formated_price'] . '</span>';
}

View File

@ -52,7 +52,7 @@ return [
'name' => 'logo',
'title' => 'admin::app.admin.system.logo',
'type' => 'image',
'validation' => 'mimes:jpeg,bmp,png,jpg',
'validation' => 'mimes:bmp,jpeg,jpg,png,webp',
'channel_based' => true,
],
]

File diff suppressed because one or more lines are too long

View File

@ -1,10 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="18px" height="18px" viewBox="0 0 18 18" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 50.2 (55047) - http://www.bohemiancoding.com/sketch -->
<title>arrow-down</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="arrow-down" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<polygon id="Rectangle-2" fill="#A5A5A5" transform="translate(9.000000, 8.000000) rotate(-45.000000) translate(-9.000000, -8.000000) " points="6 5 12 11 6 11"></polygon>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 633 B

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 7.1 KiB

File diff suppressed because one or more lines are too long

View File

@ -1,4 +1,4 @@
{
"/js/shop.js": "/js/shop.js?id=73723ffa31b9e1876375",
"/css/shop.css": "/css/shop.css?id=4d6a80790b697b2dc931"
"/js/shop.js": "/js/shop.js?id=c4dfdb6d0482241432f9",
"/css/shop.css": "/css/shop.css?id=45a1e46876af32f30871"
}

View File

@ -12,8 +12,13 @@ return [
'type' => 'boolean',
'locale_based' => true,
'channel_based' => true,
],
[
], [
'name' => 'wishlist_option',
'title' => 'shop::app.products.wishlist-options',
'type' => 'boolean',
'locale_based' => true,
'channel_based' => true,
], [
'name' => 'image_search',
'title' => 'shop::app.search.image-search-option',
'type' => 'boolean',

View File

@ -1,10 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="18px" height="18px" viewBox="0 0 18 18" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 50.2 (55047) - http://www.bohemiancoding.com/sketch -->
<title>arrow-down</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="arrow-down" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<polygon id="Rectangle-2" fill="#A5A5A5" transform="translate(9.000000, 8.000000) rotate(-45.000000) translate(-9.000000, -8.000000) " points="6 5 12 11 6 11"></polygon>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 633 B

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 7.1 KiB

View File

@ -117,6 +117,22 @@ input {
}
}
/* Product Page Description */
.details {
.description {
overflow: auto;
}
.accordian {
.accordian-content {
div {
overflow: auto;
}
}
}
}
/* Show the indicator (dot/circle) when checked */
.radio-container input:checked ~ .checkmark:after {
display: block;
@ -188,10 +204,16 @@ input {
}
}
/* if not very important use bootstrap 4 float-left and float-right class */
.pull-right {
float:right;
float: right !important;
}
.pull-left {
float: left !important;
}
/* if not very important use bootstrap 4 float-left and float-right class */
//wishlist icon hover properties
.add-to-wishlist {
.wishlist-icon {
@ -229,6 +251,28 @@ input {
.special-price {
color: $disc-price;
}
/*
To Do: Start adjusting if equal height needed in default theme as well.
*/
.price-from {
.bundle-regular-price {
color: $font-light;
text-decoration: line-through;
margin-right: 10px;
}
.bundle-special-price {
color: $disc-price;
}
.bundle-to {
display: block;
font-weight: 500;
margin-top: 1px;
margin-bottom: 1px;
}
}
}
//horizontal rule
@ -4642,7 +4686,6 @@ td {
.icon.remove-product {
top: 5px;
float: right;
cursor: pointer;
position: relative;
background-color: black;

View File

@ -72,8 +72,8 @@ return [
'page-title' => 'بحث',
'found-results' => 'تم العثور على نتائج البحث',
'found-result' => 'تم العثور على نتيجة البحث',
'analysed-keywords' => 'Analysed Keywords',
'image-search-option' => 'Image Search Option'
'analysed-keywords' => 'الكلمات الأساسية التي تم تحليلها',
'image-search-option' => 'خيار البحث عن الصور'
],
'reviews' => [
@ -440,7 +440,8 @@ return [
'none' => 'لا شيء',
'available-for-order' => 'متوفر لطلب الشراء',
'settings' => 'Settings',
'compare_options' => 'Compare Options',
'compare_options' => 'قارن الخيارات',
'wishlist-options' => 'Wishlist Options'
],
// 'reviews' => [

View File

@ -438,6 +438,7 @@ return [
'available' => 'Verfügbar',
'settings' => 'Settings',
'compare_options' => 'Compare Options',
'wishlist-options' => 'Wishlist Options'
],
// 'reviews' => [

View File

@ -441,6 +441,7 @@ return [
'available-for-order' => 'Available for Order',
'settings' => 'Settings',
'compare_options' => 'Compare Options',
'wishlist-options' => 'Wishlist Options'
],
// 'reviews' => [

View File

@ -411,6 +411,7 @@ return [
'available-for-order' => 'Disponible para ordenar',
'settings' => 'Settings',
'compare_options' => 'Compare Options',
'wishlist-options' => 'Wishlist Options'
],
// 'reviews' => [

View File

@ -440,6 +440,7 @@ return [
'available-for-order' => 'Available for Order',
'settings' => 'Settings',
'compare_options' => 'Compare Options',
'wishlist-options' => 'Wishlist Options'
],
// 'reviews' => [

View File

@ -438,6 +438,7 @@ return [
'available-for-order' => 'Disponibile per lordine',
'settings' => 'Settings',
'compare_options' => 'Compare Options',
'wishlist-options' => 'Wishlist Options'
],
// 'reviews' => [

View File

@ -407,6 +407,7 @@ return [
'available-for-order' => '注文可能',
'settings' => 'Settings',
'compare_options' => 'Compare Options',
'wishlist-options' => 'Wishlist Options'
],
'buynow' => [

View File

@ -445,6 +445,7 @@ return [
'available-for-order' => 'Beschikbaar voor bestelling',
'settings' => 'Settings',
'compare_options' => 'Compare Options',
'wishlist-options' => 'Wishlist Options'
],
// 'reviews' => [

View File

@ -438,6 +438,7 @@ return [
'available-for-order' => 'Dostępne na zamówienie',
'settings' => 'Settings',
'compare_options' => 'Compare Options',
'wishlist-options' => 'Wishlist Options'
],
// 'reviews' => [

View File

@ -428,6 +428,7 @@ return [
'available-for-order' => 'Disponível para encomenda',
'settings' => 'Settings',
'compare_options' => 'Compare Options',
'wishlist-options' => 'Wishlist Options'
],
// 'reviews' => [

View File

@ -438,6 +438,7 @@ return [
'available-for-order' => 'Sipariş İçin Uygun',
'settings' => 'Settings',
'compare_options' => 'Compare Options',
'wishlist-options' => 'Wishlist Options'
],
// 'reviews' => [

View File

@ -87,13 +87,19 @@
<a href="{{ route('shop.checkout.cart.remove', $item->id) }}" onclick="removeLink('{{ __('shop::app.checkout.cart.cart-remove-action') }}')">{{ __('shop::app.checkout.cart.remove-link') }}</a></span>
@auth('customer')
<span class="towishlist">
@if ($item->parent_id != 'null' ||$item->parent_id != null)
<a href="{{ route('shop.movetowishlist', $item->id) }}" onclick="removeLink('{{ __('shop::app.checkout.cart.cart-remove-action') }}')">{{ __('shop::app.checkout.cart.move-to-wishlist') }}</a>
@else
<a href="{{ route('shop.movetowishlist', $item->child->id) }}" onclick="removeLink('{{ __('shop::app.checkout.cart.cart-remove-action') }}')">{{ __('shop::app.checkout.cart.move-to-wishlist') }}</a>
@php
$showWishlist = core()->getConfigData('general.content.shop.wishlist_option') == "1" ? true : false;
@endphp
@if ($showWishlist)
<span class="towishlist">
@if ($item->parent_id != 'null' ||$item->parent_id != null)
<a href="{{ route('shop.movetowishlist', $item->id) }}" onclick="removeLink('{{ __('shop::app.checkout.cart.cart-remove-action') }}')">{{ __('shop::app.checkout.cart.move-to-wishlist') }}</a>
@else
<a href="{{ route('shop.movetowishlist', $item->child->id) }}" onclick="removeLink('{{ __('shop::app.checkout.cart.cart-remove-action') }}')">{{ __('shop::app.checkout.cart.move-to-wishlist') }}</a>
@endif
</span>
@endif
</span>
@endauth
</div>

View File

@ -194,8 +194,14 @@
<tr class="bold">
<td>{{ __('shop::app.customer.account.order.view.total-due') }}</td>
<td>-</td>
<td>{{ core()->formatPrice($order->total_due, $order->order_currency_code) }}</td>
@if($order->status !== 'canceled')
<td>{{ core()->formatPrice($order->total_due, $order->order_currency_code) }}</td>
@else
<td>{{ core()->formatPrice(0.00, $order->order_currency_code) }}</td>
@endif
</tr>
<tbody>
</table>

View File

@ -11,6 +11,8 @@
<ul class="menubar">
@php
$showCompare = core()->getConfigData('general.content.shop.compare_option') == "1" ? true : false;
$showWishlist = core()->getConfigData('general.content.shop.wishlist_option') == "1" ? true : false;
@endphp
@if (! $showCompare)
@ -19,6 +21,12 @@
@endphp
@endif
@if (! $showWishlist)
@php
unset($menuItem['children']['wishlist']);
@endphp
@endif
@foreach ($menuItem['children'] as $subMenuItem)
<li class="menu-item {{ $menu->getActive($subMenuItem) }}">
<a href="{{ $subMenuItem['url'] }}">

View File

@ -3,7 +3,7 @@
$comparableAttributes = $attributeRepository->getComparableAttributesBelongsToFamily();
$locale = request()->get('locale') ?: app()->getLocale();
$attributeOptionTranslations = DB::table('attribute_option_translations')->where('locale', $locale)->get()->toJson();
@endphp
@ -16,7 +16,7 @@
<button
v-if="products.length > 0"
class="btn btn-primary btn-md pull-right"
class="btn btn-primary btn-md {{ core()->getCurrentLocale()->direction == 'rtl' ? 'pull-left' : 'pull-right' }}"
@click="removeProductCompare('all')">
{{ __('shop::app.customer.account.wishlist.deleteall') }}
</button>
@ -122,7 +122,7 @@
@break
@endswitch
@endswitch
</td>
</tr>
@endforeach
@ -326,7 +326,7 @@
'type': `alert-error`,
'message': "{{ __('shop::app.common.error') }}"
}];
this.$root.addFlashMessages();
});
} else {

View File

@ -150,6 +150,10 @@
@endguest
@auth('customer')
@php
$showWishlist = core()->getConfigData('general.content.shop.wishlist_option') == "1" ? true : false;
@endphp
<ul class="dropdown-list account customer">
<li>
<div>
@ -163,9 +167,11 @@
<a href="{{ route('customer.profile.index') }}">{{ __('shop::app.header.profile') }}</a>
</li>
<li>
<a href="{{ route('customer.wishlist.index') }}">{{ __('shop::app.header.wishlist') }}</a>
</li>
@if ($showWishlist)
<li>
<a href="{{ route('customer.wishlist.index') }}">{{ __('shop::app.header.wishlist') }}</a>
</li>
@endif
<li>
<a href="{{ route('shop.checkout.cart.index') }}">{{ __('shop::app.header.cart') }}</a>
@ -230,7 +236,7 @@
<input type="file" :id="'image-search-container-' + _uid" ref="image_search_input" v-on:change="uploadImage()"/>
<img :id="'uploaded-image-url-' + + _uid" :src="uploaded_image_url" alt=""/>
<img :id="'uploaded-image-url-' + + _uid" :src="uploaded_image_url" alt="" width="20" height="20" />
</label>
</div>
</script>
@ -391,4 +397,4 @@
}
});
</script>
@endpush
@endpush

View File

@ -39,7 +39,7 @@
</head>
<body @if (core()->getCurrentLocale()->direction == 'rtl') class="rtl" @endif style="scroll-behavior: smooth;">
<body @if (core()->getCurrentLocale() && core()->getCurrentLocale()->direction == 'rtl') class="rtl" @endif style="scroll-behavior: smooth;">
{!! view_render_event('bagisto.shop.layout.body.before') !!}
@ -103,7 +103,7 @@
@endif
window.serverErrors = [];
@if (isset($errors))
@if (count($errors))
window.serverErrors = @json($errors->getMessages());

View File

@ -1,5 +1,7 @@
@php
$showCompare = core()->getConfigData('general.content.shop.compare_option') == "1" ? true : false
$showCompare = core()->getConfigData('general.content.shop.compare_option') == "1" ? true : false;
$showWishlist = core()->getConfigData('general.content.shop.wishlist_option') == "1" ? true : false;
@endphp
<div class="cart-wish-wrap">
@ -10,8 +12,10 @@
<button class="btn btn-lg btn-primary addtocart" {{ $product->isSaleable() ? '' : 'disabled' }}>{{ ($product->type == 'booking') ? __('shop::app.products.book-now') : __('shop::app.products.add-to-cart') }}</button>
</form>
@include('shop::products.wishlist')
@if ($showWishlist)
@include('shop::products.wishlist')
@endif
@if ($showCompare)
@include('shop::products.compare', [
'productId' => $product->id

View File

@ -4,7 +4,7 @@
<script type="text/x-template" id="compare-component-template">
<a
class="unset compare-icon text-right"
class="unset text-right"
title="{{ __('shop::app.customer.compare.add-tooltip') }}"
@click="addProductToCompare"
style="cursor: pointer">
@ -18,7 +18,7 @@
template: '#compare-component-template',
data: function () {
data: function () {
return {
'baseUrl': "{{ url()->to('/') }}",
'customer': '{{ auth()->guard('customer')->user() ? "true" : "false" }}' == "true",
@ -37,7 +37,7 @@
'type': `alert-${response.data.status}`,
'message': response.data.message
}];
this.$root.addFlashMessages()
}).catch(error => {
window.flashMessages = [{
@ -113,7 +113,7 @@
'type': `alert-error`,
'message': "{{ __('shop::app.common.error') }}"
}];
this.$root.addFlashMessages();
});
} else {

View File

@ -21,7 +21,7 @@
<meta name="twitter:title" content="{{ $product->name }}" />
<meta name="twitter:description" content="{!! $product->description !!}" />
<meta name="twitter:description" content="{!! htmlspecialchars(trim(strip_tags($product->description))) !!}" />
<meta name="twitter:image:alt" content="" />
@ -33,7 +33,7 @@
<meta property="og:image" content="{{ $productBaseImage['medium_image_url'] }}" />
<meta property="og:description" content="{!! $product->description !!}" />
<meta property="og:description" content="{!! htmlspecialchars(trim(strip_tags($product->description))) !!}" />
<meta property="og:url" content="{{ route('shop.productOrCategory.index', $product->url_key) }}" />
@stop

View File

@ -39,12 +39,20 @@
</li>
</ul>
<div class="product-hero-image" id="product-hero-image">
<img :src="currentLargeImageUrl" id="pro-img" :data-image="currentOriginalImageUrl" alt=""/>
@auth('customer')
<a @if ($wishListHelper->getWishlistProduct($product)) class="add-to-wishlist already" @else class="add-to-wishlist" @endif href="{{ route('customer.wishlist.add', $product->product_id) }}">
</a>
@php
$showWishlist = core()->getConfigData('general.content.shop.wishlist_option') == "1" ? true : false;
@endphp
@if ($showWishlist)
<a @if ($wishListHelper->getWishlistProduct($product)) class="add-to-wishlist already" @else class="add-to-wishlist" @endif href="{{ route('customer.wishlist.add', $product->product_id) }}">
</a>
@endif
@endauth
</div>
@ -163,7 +171,7 @@
var wishlist = " <?php echo $wishListHelper->getWishlistProduct($product); ?> ";
$(document).mousemove(function(event) {
if ($('.add-to-wishlist').length || wishlist != 1) {
if ($('.add-to-wishlist').length || wishlist != 0) {
if (event.pageX > $('.add-to-wishlist').offset().left && event.pageX < $('.add-to-wishlist').offset().left+32 && event.pageY > $('.add-to-wishlist').offset().top && event.pageY < $('.add-to-wishlist').offset().top+32) {
$(".zoomContainer").addClass("show-wishlist");

File diff suppressed because one or more lines are too long

View File

@ -1,18 +1,18 @@
/* flatpickr v4.6.3, @license MIT */
/* flatpickr v4.6.6, @license MIT */
/*! *****************************************************************************
Copyright (c) Microsoft Corporation. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
this file except in compliance with the License. You may obtain a copy of the
License at http://www.apache.org/licenses/LICENSE-2.0
Copyright (c) Microsoft Corporation.
THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
MERCHANTABLITY OR NON-INFRINGEMENT.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.
See the Apache Version 2.0 License for specific language governing permissions
and limitations under the License.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
***************************************************************************** */
/**

View File

@ -1,4 +1,4 @@
{
"/js/ui.js": "/js/ui.js?id=706b63016a08ec91d32b",
"/js/ui.js": "/js/ui.js?id=2cf17b86ea451828fd09",
"/css/ui.css": "/css/ui.css?id=5673703005b2ac3d0889"
}

View File

@ -195,8 +195,10 @@ abstract class DataGrid
$unparsed = url()->previous();
}
if (count(explode('?', $unparsed)) > 1) {
$to_be_parsed = explode('?', $unparsed)[1];
$getParametersArr = explode('?', $unparsed);
if (count($getParametersArr) > 1) {
$to_be_parsed = $getParametersArr[1];
$to_be_parsed = urldecode($to_be_parsed);
parse_str($to_be_parsed, $parsedUrl);
unset($parsedUrl['page']);
@ -205,7 +207,7 @@ abstract class DataGrid
if (isset($parsedUrl['grand_total'])) {
foreach ($parsedUrl['grand_total'] as $key => $value) {
$parsedUrl['grand_total'][$key] = str_replace(',', '.', $parsedUrl['grand_total'][$key]);
}
}
}
$this->itemsPerPage = isset($parsedUrl['perPage']) ? $parsedUrl['perPage']['eq'] : $this->itemsPerPage;
@ -477,6 +479,146 @@ abstract class DataGrid
$filter_value
);
}
} elseif ($columnType === 'boolean') {
if ($this->enableFilterMap && isset($this->filterMap[$columnName])) {
if ($this->operators[$condition] == '=') {
if ($filter_value == 1) {
$collection->Where(function($query) use($columnName, $condition, $filter_value) {
$query->where(
$this->filterMap[$columnName],
$this->operators[$condition],
$filter_value
)->orWhereNotNull($this->filterMap[$columnName]);
});
} else {
$collection->Where(function($query) use($columnName, $condition, $filter_value) {
$query->where(
$this->filterMap[$columnName],
$this->operators[$condition],
$filter_value
)->orWhereNull($this->filterMap[$columnName]);
});
}
} elseif ($this->operators[$condition] == '<>') {
if ($filter_value == 1) {
$collection->Where(function($query) use($columnName, $condition, $filter_value) {
$query->where(
$this->filterMap[$columnName],
$this->operators[$condition],
$filter_value
)->orWhereNull($this->filterMap[$columnName]);
});
} else {
$collection->Where(function($query) use($columnName, $condition, $filter_value) {
$query->where(
$this->filterMap[$columnName],
$this->operators[$condition],
$filter_value
)->orWhereNotNull($this->filterMap[$columnName]);
});
}
} else {
$collection->Where(function($query) use($columnName, $condition, $filter_value) {
$query->where(
$this->filterMap[$columnName],
$this->operators[$condition],
$filter_value
);
});
}
} elseif ($this->enableFilterMap && ! isset($this->filterMap[$columnName])) {
if ($this->operators[$condition] == '=') {
if ($filter_value == 1) {
$collection->Where(function($query) use($columnName, $condition, $filter_value) {
$query->where(
$columnName,
$this->operators[$condition],
$filter_value
)->orWhereNotNull($this->filterMap[$columnName]);
});
} else {
$collection->Where(function($query) use($columnName, $condition, $filter_value) {
$query->where(
$columnName,
$this->operators[$condition],
$filter_value
)->orWhereNull($this->filterMap[$columnName]);
});
}
} elseif ($this->operators[$condition] == '<>') {
if ($filter_value == 1) {
$collection->Where(function($query) use($columnName, $condition, $filter_value) {
$query->where(
$columnName,
$this->operators[$condition],
$filter_value
)->orWhereNull($this->filterMap[$columnName]);
});
} else {
$collection->Where(function($query) use($columnName, $condition, $filter_value) {
$query->where(
$columnName,
$this->operators[$condition],
$filter_value
)->orWhereNotNull($this->filterMap[$columnName]);
});
}
} else {
$collection->Where(function($query) use($columnName, $condition, $filter_value) {
$query->where(
$columnName,
$this->operators[$condition],
$filter_value
);
});
}
} else {
if ($this->operators[$condition] == '=') {
if ($filter_value == 1) {
$collection->Where(function($query) use($columnName, $condition, $filter_value) {
$query->where(
$columnName,
$this->operators[$condition],
$filter_value
)->orWhereNotNull($this->filterMap[$columnName]);
});
} else {
$collection->Where(function($query) use($columnName, $condition, $filter_value) {
$query->where(
$columnName,
$this->operators[$condition],
$filter_value
)->orWhereNull($this->filterMap[$columnName]);
});
}
} elseif ($this->operators[$condition] == '<>') {
if ($filter_value == 1) {
$collection->Where(function($query) use($columnName, $condition, $filter_value) {
$query->where(
$columnName,
$this->operators[$condition],
$filter_value
)->orWhereNull($this->filterMap[$columnName]);
});
} else {
$collection->Where(function($query) use($columnName, $condition, $filter_value) {
$query->where(
$columnName,
$this->operators[$condition],
$filter_value
)->orWhereNotNull($this->filterMap[$columnName]);
});
}
} else {
$collection->Where(function($query) use($columnName, $condition, $filter_value) {
$query->where(
$columnName,
$this->operators[$condition],
$filter_value
);
});
}
}
} else {
if ($this->enableFilterMap && isset($this->filterMap[$columnName])) {
$collection->where(

View File

@ -1,54 +1,73 @@
<template>
<span>
<slot>
<input type="text" :name="name" class="control" :value="value" data-input>
</slot>
<span
class="icon cross-icon"
v-if="! hideRemoveButton"
@click.prevent="clear">
</span>
</span>
<span>
<slot>
<input
type="text"
:name="name"
class="control"
:value="value"
data-input
/>
</slot>
<span
class="icon cross-icon"
v-if="!hideRemoveButton"
@click.prevent="clear"
>
</span>
</span>
</template>
<script>
import Flatpickr from 'flatpickr';
import Flatpickr from "flatpickr";
export default {
props: {
name: String,
props: {
name: String,
value: String,
value: String,
hideRemoveButton: [Number, String]
},
minDate: String,
data () {
return {
datepicker: null
}
},
maxDate: String,
mounted () {
var this_this = this;
hideRemoveButton: [Number, String],
},
var element = this.$el.getElementsByTagName('input')[0];
this.datepicker = new Flatpickr(
element, {
allowInput: true,
altFormat: 'Y-m-d',
dateFormat: 'Y-m-d',
weekNumbers: true,
onChange: function(selectedDates, dateStr, instance) {
this_this.$emit('onChange', dateStr)
},
});
},
methods: {
clear() {
this.datepicker.clear();
}
data() {
return {
datepicker: null,
};
},
mounted() {
var this_this = this;
var options = {
allowInput: true,
altFormat: "Y-m-d",
dateFormat: "Y-m-d",
weekNumbers: true,
onChange: function(selectedDates, dateStr, instance) {
this_this.$emit("onChange", dateStr);
},
};
if (this.minDate) {
options.minDate = this.minDate;
}
};
</script>
if (this.maxDate) {
options.maxDate = this.maxDate;
}
var element = this.$el.getElementsByTagName("input")[0];
this.datepicker = new Flatpickr(element, options);
},
methods: {
clear() {
this.datepicker.clear();
},
},
};
</script>

View File

@ -9,6 +9,7 @@ return [
'mass-update-status' => 'هل تريد حقا تحديث الحالة من منتقى :resource?',
'delete' => 'هل تريد حقا حذف هذا :resource?',
'edit' => 'هل تريد حقا تحرير هذا :resource?',
'delete-category-product' => 'The selected categories contains products. Performing this action will remove the related products. Do you really want to perform this action?'
],
'zero-index' => 'يمكن أن تحتوي أعمدة الفهرس على قيم أكبر من الصفر فقط',

View File

@ -9,6 +9,7 @@ return [
'mass-update-status' => 'Möchten Sie den Status der ausgewählten :resource wirklich aktualisieren?',
'delete' => 'Möchten Sie diese Aktion wirklich ausführen?',
'edit' => 'Möchten Sie :resource wirklich bearbeiten?',
'delete-category-product' => 'The selected categories contains products. Performing this action will remove the related products. Do you really want to perform this action?'
],
'zero-index' => 'Indexspalten können nur Werte größer als Null haben',

View File

@ -9,6 +9,7 @@ return [
'mass-update-status' => 'Do you really want to update status of these selected :resource?',
'delete' => 'Do you really want to perform this action?',
'edit' => 'Do you really want to edit this :resource?',
'delete-category-product' => 'The selected categories contains products. Performing this action will remove the related products. Do you really want to perform this action?'
],
'zero-index' => 'Index columns can have values greater than zero only',

View File

@ -9,6 +9,7 @@ return [
'mass-update-status' => 'آیا واقعاً می خواهید وضعیت انتخاب شده را به روز کنید :resource?',
'delete' => 'آیا واقعاً می خواهید این عمل را انجام دهید؟',
'edit' => 'آیا واقعاً می خواهید این را ویرایش کنید :resource?',
'delete-category-product' => 'The selected categories contains products. Performing this action will remove the related products. Do you really want to perform this action?'
],
'zero-index' => 'ستون های فهرست می توانند مقادیری بیشتر از صفر داشته باشند',

View File

@ -9,6 +9,7 @@ return [
'mass-update-status' => 'Vuoi aggiornare davvero lo stato dei :resource selezionati?',
'delete' => 'Vuoi davvero effettuare questa azione?',
'edit' => 'Vuoi davvero modificare questo :resource?',
'delete-category-product' => 'The selected categories contains products. Performing this action will remove the related products. Do you really want to perform this action?'
],
'zero-index' => 'Le colonnne indice possono avere solo valori maggiori di zero',

View File

@ -9,6 +9,7 @@ return [
'mass-update-status' => 'Do you really want to update status of these selected :resource?',
'delete' => 'Wilt u deze actie echt uitvoeren?',
'edit' => 'Wil je dit echt bewerken :resource?',
'delete-category-product' => 'The selected categories contains products. Performing this action will remove the related products. Do you really want to perform this action?'
],
'zero-index' => 'Index columns can have values greater than zero only',

View File

@ -9,6 +9,7 @@ return [
'mass-update-status' => 'Czy naprawdę chcesz zaktualizować status tych wybranych :resource?',
'delete' => 'Czy naprawdę chcesz wykonać tę akcję?',
'edit' => 'Czy naprawdę chcesz edytować :resource?',
'delete-category-product' => 'The selected categories contains products. Performing this action will remove the related products. Do you really want to perform this action?'
],
'zero-index' => 'Kolumny indeksu mogą mieć wartości większe niż tylko zero',

View File

@ -9,6 +9,7 @@ return [
'mass-update-status' => 'Você realmente deseja atualizar o status desses itens selecionados :resource?',
'delete' => 'Você realmente deseja excluir este :resource?',
'edit' => 'Você realmente quer editar este :resource?',
'delete-category-product' => 'The selected categories contains products. Performing this action will remove the related products. Do you really want to perform this action?'
],
'zero-index' => 'Colunas do índice podem ter valores maiores que zero apenas',

View File

@ -9,6 +9,7 @@ return [
'mass-update-status' => 'Seçili :resource kayıtlarının durumunu güncellemek istediğinizden emin misiniz?',
'delete' => 'Bu işlemi gerçekleştirmek istediğinizden emin misiniz?',
'edit' => ':resource kaydını düzenlemek istediğinizden emin misiniz?',
'delete-category-product' => 'The selected categories contains products. Performing this action will remove the related products. Do you really want to perform this action?'
],
'zero-index' => 'Index sütunları sadece sıfırdan büyük değere sahip olmalı',

View File

@ -48,25 +48,32 @@
@if ($toDisplay)
<a
@if ($action['method'] == 'GET')
href="{{ route($action['route'], $record->{$action['index'] ?? $index}) }}"
@endif
id="{{ $record->{$action['index'] ?? $index} }}"
@if ($action['method'] != 'GET')
v-on:click="doAction($event)"
@endif
@if ($action['method'] == 'GET')
href="{{ route($action['route'], $record->{$action['index'] ?? $index}) }}"
@endif
data-method="{{ $action['method'] }}"
data-action="{{ route($action['route'], $record->{$index}) }}"
data-token="{{ csrf_token() }}"
@if ($action['method'] != 'GET')
@if (isset($action['function']))
v-on:click="{{$action['function']}}"
@else
v-on:click="doAction($event)"
@endif
@endif
@if (isset($action['target']))
target="{{ $action['target'] }}"
@endif
data-method="{{ $action['method'] }}"
data-action="{{ route($action['route'], $record->{$index}) }}"
data-token="{{ csrf_token() }}"
@if (isset($action['title']))
title="{{ $action['title'] }}"
@endif>
@if (isset($action['target']))
target="{{ $action['target'] }}"
@endif
@if (isset($action['title']))
title="{{ $action['title'] }}"
@endif
>
<span class="{{ $action['icon'] }}"></span>
</a>
@endif

View File

@ -8,7 +8,7 @@
<span class="icon checkbox-dash-icon"></span>
</span>
<form method="POST" id="mass-action-form" style="display: inline-flex;" action="" onsubmit="return confirm('{{ __('ui::app.datagrid.click_on_action') }}')">
<form method="POST" id="mass-action-form" style="display: inline-flex;" action="" :onsubmit="`return confirm('${massActionConfirmText}')`">
@csrf()
<input type="hidden" id="indexes" name="indexes" v-model="dataIds">

View File

@ -272,6 +272,7 @@
massActions: @json($results['massactions']),
massActionsToggle: false,
massActionTarget: null,
massActionConfirmText: '{{ __('ui::app.datagrid.click_on_action') }}',
massActionType: null,
massActionValues: [],
massActionTargets: [],
@ -457,7 +458,8 @@
for (let id in this.massActions) {
targetObj = {
'type': this.massActions[id].type,
'action': this.massActions[id].action
'action': this.massActions[id].action,
'confirm_text': this.massActions[id].confirm_text
};
this.massActionTargets.push(targetObj);
@ -483,6 +485,7 @@
for (let i in this.massActionTargets) {
if (this.massActionTargets[i].type === 'delete') {
this.massActionTarget = this.massActionTargets[i].action;
this.massActionConfirmText = this.massActionTargets[i].confirm_text ? this.massActionTargets[i].confirm_text : this.massActionConfirmText;
break;
}
@ -493,6 +496,7 @@
for (let i in this.massActionTargets) {
if (this.massActionTargets[i].type === 'update') {
this.massActionTarget = this.massActionTargets[i].action;
this.massActionConfirmText = this.massActionTargets[i].confirm_text ? this.massActionTargets[i].confirm_text : this.massActionConfirmText;
break;
}
@ -816,31 +820,6 @@
}
},
doAction: function (e) {
var element = e.currentTarget;
if (confirm('{{__('ui::app.datagrid.massaction.delete') }}')) {
axios.post(element.getAttribute('data-action'), {
_token: element.getAttribute('data-token'),
_method: element.getAttribute('data-method')
}).then(function (response) {
this.result = response;
if (response.data.redirect) {
window.location.href = response.data.redirect;
} else {
location.reload();
}
}).catch(function (error) {
location.reload();
});
e.preventDefault();
} else {
e.preventDefault();
}
},
captureColumn: function (id) {
element = document.getElementById(id);
@ -869,6 +848,37 @@
}
}
});
function doAction(e, message, type) {
var element = e.currentTarget;
if (message) {
element = e.target.parentElement;
}
message = message || '{{__('ui::app.datagrid.massaction.delete') }}';
if (confirm(message)) {
axios.post(element.getAttribute('data-action'), {
_token: element.getAttribute('data-token'),
_method: element.getAttribute('data-method')
}).then(function (response) {
this.result = response;
if (response.data.redirect) {
window.location.href = response.data.redirect;
} else {
location.reload();
}
}).catch(function (error) {
location.reload();
});
e.preventDefault();
} else {
e.preventDefault();
}
}
</script>
@endpush
</div>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,5 +1,5 @@
{
"/js/velocity.js": "/js/velocity.js?id=8aa00114ba3523e8303b",
"/js/velocity.js": "/js/velocity.js?id=3881062524b183f96b0c",
"/css/velocity-admin.css": "/css/velocity-admin.css?id=4322502d80a0e4a0affd",
"/css/velocity.css": "/css/velocity.css?id=8cf54786f83b29684543"
"/css/velocity.css": "/css/velocity.css?id=2405c8967f518a3ce499"
}

View File

@ -132,6 +132,104 @@ class VelocityMetaDataSeeder extends Seeder
'updated_at' => $now,
],
//Wishlist show config data
[
'code' => 'general.content.shop.wishlist_option',
'value' => '1',
'channel_code' => 'default',
'locale_code' => 'en',
'created_at' => $now,
'updated_at' => $now,
],
[
'code' => 'general.content.shop.wishlist_option',
'value' => '1',
'channel_code' => 'default',
'locale_code' => 'fr',
'created_at' => $now,
'updated_at' => $now,
],
[
'code' => 'general.content.shop.wishlist_option',
'value' => '1',
'channel_code' => 'default',
'locale_code' => 'ar',
'created_at' => $now,
'updated_at' => $now,
],
[
'code' => 'general.content.shop.wishlist_option',
'value' => '1',
'channel_code' => 'default',
'locale_code' => 'de',
'created_at' => $now,
'updated_at' => $now,
],
[
'code' => 'general.content.shop.wishlist_option',
'value' => '1',
'channel_code' => 'default',
'locale_code' => 'es',
'created_at' => $now,
'updated_at' => $now,
],
[
'code' => 'general.content.shop.wishlist_option',
'value' => '1',
'channel_code' => 'default',
'locale_code' => 'fa',
'created_at' => $now,
'updated_at' => $now,
],
[
'code' => 'general.content.shop.wishlist_option',
'value' => '1',
'channel_code' => 'default',
'locale_code' => 'it',
'created_at' => $now,
'updated_at' => $now,
],
[
'code' => 'general.content.shop.wishlist_option',
'value' => '1',
'channel_code' => 'default',
'locale_code' => 'ja',
'created_at' => $now,
'updated_at' => $now,
],
[
'code' => 'general.content.shop.wishlist_option',
'value' => '1',
'channel_code' => 'default',
'locale_code' => 'nl',
'created_at' => $now,
'updated_at' => $now,
],
[
'code' => 'general.content.shop.wishlist_option',
'value' => '1',
'channel_code' => 'default',
'locale_code' => 'pl',
'created_at' => $now,
'updated_at' => $now,
],
[
'code' => 'general.content.shop.wishlist_option',
'value' => '1',
'channel_code' => 'default',
'locale_code' => 'pt_BR',
'created_at' => $now,
'updated_at' => $now,
],
[
'code' => 'general.content.shop.wishlist_option',
'value' => '1',
'channel_code' => 'default',
'locale_code' => 'tr',
'created_at' => $now,
'updated_at' => $now,
],
/* Image search core config data starts here */
[
'code' => 'general.content.shop.image_search',
@ -232,4 +330,4 @@ class VelocityMetaDataSeeder extends Seeder
/* Image search core config data ends here */
]);
}
}
}

View File

@ -253,6 +253,7 @@ class ConfigurationController extends Controller
\DB::table('velocity_meta_data')->insert([
'locale' => $locale,
'channel' => $channel,
'header_content_count' => '5',
'home_page_content' => "<p>@include('shop::home.advertisements.advertisement-four')@include('shop::home.featured-products') @include('shop::home.product-policy') @include('shop::home.advertisements.advertisement-three') @include('shop::home.new-products') @include('shop::home.advertisements.advertisement-two')</p>",
'footer_left_content' => __('velocity::app.admin.meta-data.footer-left-raw-content'),

View File

@ -168,6 +168,7 @@ class ShopController extends Controller
'name' => $category->name,
'children' => $formattedChildCategory,
'category_icon_path' => $category->category_icon_path,
'image' => $category->image
];
}

View File

@ -48,12 +48,6 @@ Route::group(['middleware' => ['web', 'locale', 'theme', 'currency']], function
Route::delete('/comparison', 'ComparisonController@deleteComparisonProduct')
->name('customer.product.delete.compare');
Route::get('/guest-wishlist', 'ShopController@getWishlistList')
->name('velocity.product.guest-wishlist')
->defaults('_config', [
'view' => 'shop::guest.wishlist.index'
]);
Route::get('/items-count', 'ShopController@getItemsCount')
->name('velocity.product.item-count');

View File

@ -1,5 +1,6 @@
<template>
<form method="POST" @submit.prevent="addToCart">
<!-- for move to cart from wishlist -->
<a
:href="wishlistMoveRoute"
@ -25,6 +26,7 @@
<span class="fs14 fw6 text-uppercase text-up-4" v-text="btnText"></span>
</button>
</form>
</template>
@ -67,15 +69,6 @@
if (response.data.status == 'success') {
this.$root.miniCartKey++;
if (this.moveToCart == "true") {
let existingItems = this.getStorageValue('wishlist_product');
let updatedItems = existingItems.filter(item => item != this.productFlatId);
this.$root.headerItemsCount++;
this.setStorageValue('wishlist_product', updatedItems);
}
window.showAlert(`alert-success`, this.__('shop.general.alert.success'), response.data.message);
if (this.reloadPage == "1") {

View File

@ -0,0 +1,98 @@
<template>
<div class="container-fluid remove-padding-margin">
<shimmer-component v-if="isLoading && !isMobileView"></shimmer-component>
<template v-else-if="categoryProducts.length > 0">
<card-list-header
:heading="categoryDetails.name"
:view-all="`${this.baseUrl}/${categoryDetails.slug}`">
</card-list-header>
<div class="carousel-products vc-full-screen ltr" v-if="!isMobileView">
<carousel-component
slides-per-page="6"
navigation-enabled="hide"
pagination-enabled="hide"
:slides-count="categoryProducts.length"
locale-direction="localeDirection"
:id="`${categoryDetails.name}-carousel`">
<slide
:key="index"
:slot="`slide-${index}`"
v-for="(product, index) in categoryProducts">
<product-card
:list="list"
:product="product">
</product-card>
</slide>
</carousel-component>
</div>
<div class="carousel-products vc-small-screen" v-else>
<carousel-component
slides-per-page="2"
navigation-enabled="hide"
pagination-enabled="hide"
:slides-count="categoryProducts.length"
locale-direction="localeDirection"
:id="`${categoryDetails.name}-carousel`">
<slide
:key="index"
:slot="`slide-${index}`"
v-for="(product, index) in categoryProducts">
<product-card
:list="list"
:product="product">
</product-card>
</slide>
</carousel-component>
</div>
</template>
</div>
</template>
<script>
export default {
props: [
'categorySlug',
'localeDirection'
],
data: function () {
return {
isLoading: true,
isCategory: false,
heading: 'customer',
categoryProducts: [],
isMobileView: this.$root.isMobile(),
}
},
mounted: function () {
this.getCategoryDetails();
},
methods: {
'getCategoryDetails': function () {
this.$http.get(`${this.baseUrl}/category-details?category-slug=${this.categorySlug}`)
.then(response => {
if (response.data.status) {
this.list = response.data.list;
this.categoryDetails = response.data.categoryDetails;
this.categoryProducts = response.data.categoryProducts;
this.isCategory = true;
}
this.isLoading = false;
})
.catch(error => {
this.isLoading = false;
console.log(this.__('error.something_went_wrong'));
});
}
}
}
</script>

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