diff --git a/.editorconfig b/.editorconfig
index 1492202b4..9cdbc2ed9 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -3,7 +3,7 @@ root = true
[*]
charset = utf-8
end_of_line = lf
-insert_final_newline = true
+insert_final_newline = false
indent_style = space
indent_size = 4
trim_trailing_whitespace = true
diff --git a/.env.example b/.env.example
index ec44a1259..9f59e6c4c 100644
--- a/.env.example
+++ b/.env.example
@@ -1,5 +1,6 @@
APP_NAME=Laravel
APP_ENV=local
+APP_VERSION=0.1.6
APP_KEY=
APP_DEBUG=true
APP_URL=http://localhost
@@ -16,7 +17,7 @@ DB_PASSWORD=secret
BROADCAST_DRIVER=log
CACHE_DRIVER=file
SESSION_DRIVER=file
-SESSION_LIFETIME=120
+SESSION_LIFETIME=10
QUEUE_DRIVER=sync
REDIS_HOST=127.0.0.1
@@ -30,6 +31,11 @@ MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
+SHOP_MAIL_FROM=shop@bagsaas.com
+ADMIN_MAIL_TO=admin@bagsaas.com
+
+fixer_api_key=
+
PUSHER_APP_ID=
PUSHER_APP_KEY=
PUSHER_APP_SECRET=
diff --git a/.gitignore b/.gitignore
index bc05ff310..42eced022 100644
--- a/.gitignore
+++ b/.gitignore
@@ -18,3 +18,4 @@ yarn-error.log
/ignorables/*
composer.lock
package-lock.json
+yarn.lock
diff --git a/CHANGELOG for v0.1.x.md b/CHANGELOG for v0.1.x.md
index 364437e01..bbd67d15a 100755
--- a/CHANGELOG for v0.1.x.md
+++ b/CHANGELOG for v0.1.x.md
@@ -2,6 +2,243 @@
#### This changelog consists the bug & security fixes and new features being included in the releases listed below.
+## **v0.1.6(28th of June, 2019)** - *Release*
+
+* [feature] - Cart rules for providing discount with coupons and without coupons.
+
+* [feature] - Take notes on customers.
+
+* [feature] - Added swatch type attribute for products.
+
+* [feature] - Added file type attribute for products.
+
+* [feature] - Added image type attribute for products.
+
+* [feature] - Admins can now export products.
+
+* [feature] - Activate/Deactivate customers from admin panel.
+
+* [feature] - Added backorders as global level configuration for Admin.
+
+* [feature] - REST APIs added as a separate package.
+
+* [enhancement] - Each channel can choose their respective root category.
+
+* [enhancement] - Added customer group 'Guest' for guest type user comparison (reference usage in cart rule create and edit).
+
+* [enhancement] - Global configuration to allow reviews from guests.
+
+* [enhancement] - Weight unit options added as global configuration.
+
+* [enhancement] - Dynamic footer bottom text input added as global level configuration.
+
+* [enhancement] - Admin can now change their logo added as global level configuration.
+
+* [enhancement] - Added global configuration for news letter subscription.
+
+* [enhancement] - Added configuration to enable email verification on customer registration.
+
+* [enhancement] - Dependent field added in system configuration.
+
+* [optimization] - Removed products dependency from products_datagrid table and that table had been phased out of the system successfully.
+
+* [optimization] - Massive performance improvements in page load from last stable release of v0.1.5.
+
+* #636 [fixed] - Getting exception in shipment grid.
+
+* #638 [fixed] - Colors are not available in swatch on selecting Swatch Type as "Color Swatch".
+
+* #639 [fixed] - Broken link of image, on edit page of attribute in case of Swatch Type "Image" when editing first time.
+
+* #642 [fixed] - Getting exception on search in Products, Categories, Shipments & Product Reviews datagrids.
+
+* #654 [fixed] - Getting Exception while adding product images by gui installer.
+
+* #646 [fixed] - Warning: array_combine() expects parameter 1 to be array, null given ( install.php on line 32 ).
+
+* #647 [fixed] - Special price not working.
+
+* #655 [fixed] - Not able to create category with images, category doesn't get save if image is used.
+
+* #656 [fixed] - Getting checkout page blank when product is added in cart first and then proceed for checkout.Getting this issue in case of logged-in customer.Getting same issue in case of Buy-now also.
+
+* #657 [fixed] - Not able to export order.Not getting any response after clicking on Export.Getting this issue for all export functionality
+
+* #666 [enhancement] - Create possibility of choose the qty os address line.
+
+* #671 [fixed] - Having these errors Undefined variable: key/value.
+
+* #730 [fixed] - Add a word limitation for Category name so that after that limit category name should display in different line.
+
+* #729 [fixed] - Price Slider overlap with category menu.
+
+* #728 [fixed] - If multiple products are added in cart and we update the quantity of product which is not available then in this case its not showing a message that request quantity is not available, it shows success message that products in cart is updated.
+
+* #727 [fixed] - Quantity of Product doesn't get updated at product page after generating shipment.
+
+* #720 [fixed] - Case issue HomeController.php.
+
+* #718 [fixed] - If user with custom role doesn't have access of Products and if he click on product link given in dashboard then getting exception.It should display unauthorised access message.
+
+* #717 [fixed] - Url is not working "Add to Cart" in drop shipping manager.
+
+* #713 [fixed] - Getting exception on deleting default channel.
+
+* #712 [fixed] - Correct the filter option in Invoice grid.
+
+* #710 [fixed] - Getting exception when applying filter on Product according to Status.
+
+* #709 [fixed] - Getting exception when applying filter according to Order Date of Order grid of Admin.
+
+* #707 [fixed] - If in display mode for categories "Only Product" is selected then description should not display on front-end and if Only "Description" is selected than product should not display for category.
+
+* #705 [fixed] - For 3 level menu option if access is given for only first menu and third menu , then getting unauthorized access.
+
+* #699 [fixed] - Active category class missing
+
+* #765 [fixed] - Getting issue in mass deletion for the configurable products if we have saved the products but variation and name of products has not saved.Getting this issue when App_Debug mode is false.
+
+* #764 [fixed] - Make "Sliders" and "Image" field as required.While creating slider if image is not uploaded then slider is not created and its not showing that this field is required validation message.
+
+* #763 [fixed] - Add a validation in tax rate that it should not be negative.
+
+* #762 [fixed] - In Order Section of Customer Account no column is available in filter dropdown.
+
+* #761 [fixed] - Issue in creating products if special characters are used in sku field.On add Product page if we use special character then it will be saved but when we click on Save Product button it gives validation error message that "The sku must be valid slug." admin.
+
+* #760 [fixed] - Not able to add product to Wishlist from product page.
+
+* #759 [fixed] - Text for Add to Cart button is not properly visible on product page for locale pt_BR.
+
+* #757 [fixed] - Product getting save if price and weight is negative in variants of configurable product.
+
+* #755 [fixed] - When trying to change display mode for product to list view when locale is "arabic" , it changes to default locale.
+
+* #753 [fixed] - While creating attribute of type swatch, admin name and name according to locale is showing as required but get saved if field is left as blank, and while creating product this attribute field is blank.
+
+* #752 [fixed] - On creating custom theme for shop it was also affecting admin panel's frontend.
+
+* #750 [fixed] - Cross site request forgery.
+
+* #749 [fixed] - Broken access control.
+
+* #742 [fixed] - Getting exception when we change locale from Search result page.
+
+* #741 [fixed] - Trying to get property 'permission_type' of non-object.
+
+* #825 [fixed] - unable to update ( is_filterable ) in attributes.
+
+* #818 [fixed] - Email should sent to the respective inventory from which shipment has been created.
+
+* #817 [fixed] - Admin should receive an email when an order is placed.
+
+* #815 [fixed] - Issue in Attribute while creating configurable product.
+
+* #814 [fixed] - Implement sort order feature for payment methods, so that payment method should display on front-end according to sort-order.
+
+* #783 [fixed] - Image display issue of product on front-end when installation is done through GUI Installer.
+
+* #771 [fixed] - Getting exception when login with custom role.
+
+* #767 [fixed] - After applying filter of status , the result display in boolean for Active/True and Inactive/False.
+
+* #879 [fixed] - Getting validation error message for locale while editing attribute.Attribute value is required for all locale.
+
+* #867 [fixed] - Getting exception if user create shipment for product which has been deleted from catalog.
+
+* #842 [fixed] - Not able to export. This functionality is not working everywhere, where export is used.
+
+* #841 [fixed] - Layout issue on 404 Page.
+
+* #835 [fixed] - Parent Products show instock when all children have quantity 0.
+
+* #939 [fixed] - Not able to save price in decimal for configurable products.
+
+* #932 [fixed] - Getting incorrect price of product in case of configurable product if custom attribute of select type is used.
+
+* #923 [fixed] - Required validation is not working for Lines in a Street Address, and add 1 as default line for address field.
+
+* #917 [fixed] - Attribute name should display with attribute value.
+
+* #916 [fixed] - SQLSTATE[42S22]: Column not found: 1054 Unknown column 'phone'.
+
+* #897 [fixed] - Product get saved without image, if used image is large in size.It should throw an error message.
+
+* #896 [fixed] - getVariantMinPrice does not look at special_price.
+
+* #894 [fixed] - Storage link command is missing when installing framework through installer.
+
+* #890 [fixed] - An error message should show if uploaded mage size is large, while saving the category.
+
+* #1003 [fixed] - Getting exception if on editing any cart rule we select " Use Coupon" as Yes.
+
+* #1001 [fixed] - Getting error while placing an order.
+
+* #997 [fixed] - Change the validation for description.
+
+* #995 [fixed] - [default] en field of labels section disappear after entering data in "Global Label" field.
+
+* #994 [fixed] - Getting exception while creating cart rules.
+
+* #993 [fixed] - Rule Name should be alphanumeric.
+
+* #957 [fixed] - Typo in event fire.
+
+* #949 [fixed] - Refresh order summary on every checkout step.
+
+* #1075 [fixed] - Validation error message is not showing for Customer Group.
+
+* #1069 [fixed] - Getting exception on editing the second customer.
+
+* #1068 [fixed] - Product Inventory is "Zero" but in product page showing In Stock.
+
+* #1065 [fixed] - On editing any cart rule if user need to add any new condition then he need to select value from Add Conditions again.
+
+* #1061 [fixed] - Cart rule not working For Shipping code.
+
+* #1060 [fixed] - If cart rule is not created for guest then also it is applicable for guest user.
+
+* #1059 [fixed] - Cart Rule not working for Shipping state. Created a non coupon cart rule for Condition Shipping state but it doesn't get applied.
+
+* #1053 [fixed] - Discount amount is not displaying in orders.
+
+* #1052 [fixed] - Coupon is not applicable in case of payment methods.
+
+* #1051 [fixed] - If cart rule is create for customer having group guest, then also general group customer is also able to use the same coupon.
+
+* #1050 [fixed] - Coupon code discount amount is not displaying on checkout page.
+
+* #1011 [fixed] - Channel, Add Condition and Global label field not showing validation error message if user save without entering any data in these fields.
+
+* #1007 [fixed] - Applying zero discount amount in case of percentage.
+
+* #1006 [fixed] - Not able to remove coupon if once applied.
+
+* #1005 [fixed] - Cart rule not working correctly with coupon code.Fixed discount of amount 10 is created but after applying amount need to pay by customer is 10.
+
+* #1131 [fixed] - If "does not contain" is used in case of Shipping city, then discount amount get implemented before selecting any address.
+
+* #1127 [fixed] - Getting wrong grandtotal if in cart rule shipping is selected as free.
+
+* #1113 [fixed] - Cart rule is not working for guest user.
+
+* #1114 [fixed] - Unable to search cart rule by name.
+
+* #1112 [fixed] - Provide an option to delete the note added for a customer.
+
+* #1103 [fixed] - If entered coupon is incorrect then after clicking on Apply coupon button once the button should get disabled until the coupon code changes.
+
+* #1102 [fixed] - If in condition percentage of product is selected , then also fixed amount discount is applied.
+
+* #1097 [fixed] - Coupon get applied if only one product is added in cart and from action it is saved as buy atleast 2.
+
+* #1096 [fixed] - If any discount is already applied on cart and customer uses his coupon to get discount then in this case coupon discount should be applied.
+
+* #1095 [fixed] - If maximum quantity allowed to discount is selected as 2 then on both product discount should be applied.
+
+* #1080 [fixed] - Customer should be logged out if admin blocked the user, and a message should display "Your account has been blocked by admin".
+
+
## **v0.1.5(15th of March, 2019)** - *Release*
* [feature] - Category display mode.
diff --git a/README.md b/README.md
index 5436abd62..d7f8566a2 100755
--- a/README.md
+++ b/README.md
@@ -10,14 +10,15 @@
-# Topics
-1. ### [Introduction](#1-introduction-)
-2. ### [Requirements](#2-requirements-)
-3. ### [Installation & Configuration](#3-installation--configuration-)
-4. ### [License](#4-license-)
-5. ### [Miscellaneous](#5-miscellaneous-)
+## Topics
+1. [Introduction](#introduction)
+2. [Documentation](#documentation)
+3. [Requirements](#requirements)
+4. [Installation & Configuration](#installation-and-configuration)
+5. [License](#license)
+6. [Miscellaneous](#miscellaneous)
-### 1. Introduction :
+### Introduction
[Bagisto](https://www.bagisto.com) is a hand tailored E-Commerce framework designed on some of the hottest opensource technologies
such as [Laravel](https://laravel.com) a [PHP](https://secure.php.net/) framework, [Vue.js](https://vuejs.org)
@@ -26,6 +27,8 @@ a progressive Javascript framework.
**Bagisto is viable attempt to cut down your time, cost and workforce for building online stores or migrating from physical stores
to the ever demanding online world. Your business whether small or huge it suits all and very simple to set it up.**
+**Read our documentation: [Bagisto Docs](https://devdocs.bagisto.com/)**
+
**We are also having a forum for any type of your concern, feature request discussions. Please visit: [Bagisto Forums](https://forums.bagisto.com/)**
# Visit our live [Demo](https://demo.bagisto.com)
@@ -44,16 +47,21 @@ It packs in lots of demanding features that allows your business to scale in no
* Orders Management System.
* Customer Cart, Wishlist, Product Reviews.
* Simple and Configurable Products.
+* Price rules (Discount) inbuilt.
* Check out [click here](https://bagisto.com/features/).
**For Developers**:
Dev guys can take advantage of two of the hottest frameworks used in this project Laravel and Vue.js, both of these frameworks have been used in Bagisto.
Bagisto is using power of both of these frameworks and making best out of it out of the box.
-### 2. Requirements :
+### Documentation
-* **OS**: Ubuntu 16.04 LTS or higher.
-* **SERVER**: Apache 2 or NGINX
+#### Bagisto Documentation [https://devdocs.bagisto.com](https://devdocs.bagisto.com)
+
+### Requirements
+
+* **OS**: Ubuntu 16.04 LTS or higher / Windows 7 or Higher (WAMP / XAMP).
+* **SERVER**: Apache 2 or NGINX.
* **RAM**: 3 GB or higher.
* **PHP**: 7.1.17 or higher.
* **Processor**: Clock Cycle 1 Ghz or higher.
@@ -62,13 +70,13 @@ Bagisto is using power of both of these frameworks and making best out of it out
* **Node**: 8.11.3 LTS or higher.
* **Composer**: 1.6.5 or higher.
-### 3. Installation & Configuration :
+### Installation and Configuration
**1. Try our new GUI installer to install Bagisto:**
##### a. Download zip from the link below:
-[Download](https://github.com/bagisto/bagisto/archive/v0.1.5.zip)
+[Download](https://github.com/bagisto/bagisto/archive/v0.1.6.zip)
##### b. Extract the contents of zip and execute the project in browser:
@@ -132,6 +140,11 @@ Although, mailer environment variables are also required to be set up as **Bagis
##### On server:
+Warning: Before going full on production mode we recommend you to install developer dependencies.
+In order to do that, run the command below:
+
+> composer install --no-dev
+
~~~
Open the specified entry point in your hosts file in browser or make entry in hosts file if not done.
~~~
@@ -159,36 +172,26 @@ password:admin123
> *http(s)://example.com/customer/register*
-### 5. License :
+### License
Bagisto is a truly opensource E-Commerce framework which will always be free under the [MIT License](https://github.com/bagisto/bagisto/blob/master/LICENSE).
-### 6. Miscellaneous :
+### Miscellaneous
#### Contributors
-This project exists thanks to all the people who contribute.
-
+This project is on [Open Collective](https://opencollective.com/bagisto) and it exists thanks to this people who contribute.
+
#### Backers
-Thank you to all our backers! 🙏 [[Become a backer](https://opencollective.com/bagisto#backer)]
-
-
+Thank you to all our backers! 🙏
+
#### Sponsors
-Support this project by becoming a sponsor. Your logo will show up here with a link to your website. [[Become a sponsor](https://opencollective.com/bagisto#sponsor)]
+Support this project by becoming a sponsor. Your logo will show up here with a link to your website.
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
+
diff --git a/app/Console/Commands/BagistoVersion.php b/app/Console/Commands/BagistoVersion.php
new file mode 100644
index 000000000..6e0b5c04f
--- /dev/null
+++ b/app/Console/Commands/BagistoVersion.php
@@ -0,0 +1,42 @@
+comment('v' . config('app.version'));
+ }
+}
diff --git a/app/Providers/RouteServiceProvider.php b/app/Providers/RouteServiceProvider.php
index 5ea48d39d..265d66d00 100755
--- a/app/Providers/RouteServiceProvider.php
+++ b/app/Providers/RouteServiceProvider.php
@@ -23,8 +23,6 @@ class RouteServiceProvider extends ServiceProvider
*/
public function boot()
{
- //
-
parent::boot();
}
diff --git a/composer.json b/composer.json
index af3ebc6da..b97e6c745 100755
--- a/composer.json
+++ b/composer.json
@@ -9,11 +9,19 @@
"type": "project",
"require": {
"php": "^7.1.3",
+ "ext-curl": "*",
+ "ext-intl": "*",
+ "ext-mbstring": "*",
+ "ext-openssl": "*",
+ "ext-pdo": "*",
+ "ext-pdo_mysql": "*",
+ "ext-tokenizer": "*",
"barryvdh/laravel-dompdf": "^0.8.0@dev",
"dimsav/laravel-translatable": "^9.0",
"doctrine/dbal": "^2.9@dev",
"fideloper/proxy": "^4.0",
"flynsarmy/db-blade-compiler": "*",
+ "guzzlehttp/guzzle": "~6.0",
"intervention/image": "^2.4",
"intervention/imagecache": "^2.3",
"kalnoy/nestedset": "^4.3",
@@ -23,12 +31,13 @@
"maatwebsite/excel": "3.1.x-dev",
"nwidart/laravel-modules": "^3.2",
"prettus/l5-repository": "^2.6",
- "propaganistas/laravel-intl": "^2.0"
+ "tymon/jwt-auth": "dev-develop"
},
"require-dev": {
"barryvdh/laravel-debugbar": "^3.1",
"filp/whoops": "^2.0",
"fzaninotto/faker": "^1.4",
+ "laravel/dusk": "^4.0",
"mockery/mockery": "^1.0",
"nunomaduro/collision": "^2.0",
"phpunit/phpunit": "^7.0"
@@ -49,7 +58,10 @@
"bagisto/laravel-shipping": "v0.1.0",
"bagisto/laravel-payment": "v0.1.0",
"bagisto/laravel-sales": "v0.1.0",
- "bagisto/laravel-tax": "v0.1.0"
+ "bagisto/laravel-tax": "v0.1.0",
+ "bagisto/laravel-api": "v0.1.0",
+ "bagisto/laravel-paypal": "v0.1.0",
+ "bagisto/laravel-discount": "v0.1.0"
},
"autoload": {
"classmap": [
@@ -76,7 +88,9 @@
"Webkul\\Paypal\\": "packages/Webkul/Paypal/src",
"Webkul\\Sales\\": "packages/Webkul/Sales/src",
"Webkul\\Tax\\": "packages/Webkul/Tax/src",
- "Webkul\\API\\": "packages/Webkul/API"
+ "Webkul\\API\\": "packages/Webkul/API",
+ "Webkul\\Discount\\": "packages/Webkul/Discount/src",
+ "Webkul\\CMS\\": "packages/Webkul/CMS/src"
}
},
"autoload-dev": {
@@ -86,7 +100,9 @@
},
"extra": {
"laravel": {
- "dont-discover": []
+ "dont-discover": [
+ "barryvdh/laravel-debugbar"
+ ]
}
},
"scripts": {
diff --git a/config/app.php b/config/app.php
index d151dd0cf..14eec2d67 100755
--- a/config/app.php
+++ b/config/app.php
@@ -130,22 +130,16 @@ return [
'cipher' => 'AES-256-CBC',
- /*
- |--------------------------------------------------------------------------
- | Autoloaded Service Providers
- |--------------------------------------------------------------------------
- |
- | The service providers listed here will be automatically loaded on the
- | request to your application. Feel free to add your own services to
- | this array to grant expanded functionality to your applications.
- |
- */
-
/*
Code Editor
*/
'editor' =>'vscode',
+ /*
+ Application Version
+ */
+ 'version' => env('APP_VERSION', '0.1.6'),
+
/**
* Blacklisting attributes while debugging
*/
@@ -165,6 +159,17 @@ return [
],
],
+ /*
+ |--------------------------------------------------------------------------
+ | Autoloaded Service Providers
+ |--------------------------------------------------------------------------
+ |
+ | The service providers listed here will be automatically loaded on the
+ | request to your application. Feel free to add your own services to
+ | this array to grant expanded functionality to your applications.
+ |
+ */
+
'providers' => [
/*
@@ -198,7 +203,6 @@ return [
*/
Dimsav\Translatable\TranslatableServiceProvider::class,
- Propaganistas\LaravelIntl\IntlServiceProvider::class,
/*
* Application Service Providers...
@@ -240,6 +244,8 @@ return [
Webkul\Sales\Providers\SalesServiceProvider::class,
Webkul\Tax\Providers\TaxServiceProvider::class,
Webkul\API\Providers\APIServiceProvider::class,
+ Webkul\Discount\Providers\DiscountServiceProvider::class,
+ Webkul\CMS\Providers\CMSServiceProvider::class
],
/*
@@ -296,5 +302,7 @@ return [
'DbView' => Flynsarmy\DbBladeCompiler\Facades\DbView::class,
'PDF' => Barryvdh\DomPDF\Facade::class,
'Excel' => Maatwebsite\Excel\Facades\Excel::class,
+ 'Concord' => Konekt\Concord\Facades\Concord::class,
+ 'Helper' => Konekt\Concord\Facades\Helper::class,
],
];
\ No newline at end of file
diff --git a/config/auth.php b/config/auth.php
index caa89e114..6b8c92e4b 100755
--- a/config/auth.php
+++ b/config/auth.php
@@ -13,7 +13,7 @@ return [
],
'api' => [
- 'driver' => 'token',
+ 'driver' => 'jwt',
'provider' => 'customers',
],
diff --git a/config/concord.php b/config/concord.php
index 8544115c0..0af8125b0 100755
--- a/config/concord.php
+++ b/config/concord.php
@@ -8,5 +8,16 @@ return [
* VendorB\ModuleY\Providers\ModuleServiceProvider::class
*
*/
+
+ \Webkul\Attribute\Providers\ModuleServiceProvider::class,
+ \Webkul\Category\Providers\ModuleServiceProvider::class,
+ \Webkul\Checkout\Providers\ModuleServiceProvider::class,
+ \Webkul\Core\Providers\ModuleServiceProvider::class,
+ \Webkul\Customer\Providers\ModuleServiceProvider::class,
+ \Webkul\Inventory\Providers\ModuleServiceProvider::class,
+ \Webkul\Product\Providers\ModuleServiceProvider::class,\Webkul\Sales\Providers\ModuleServiceProvider::class,
+ \Webkul\Tax\Providers\ModuleServiceProvider::class,
+ \Webkul\User\Providers\ModuleServiceProvider::class,\Webkul\Discount\Providers\ModuleServiceProvider::class,
+ \Webkul\CMS\Providers\ModuleServiceProvider::class
]
-];
+];
\ No newline at end of file
diff --git a/config/product_types.php b/config/discount-rules.php
similarity index 100%
rename from config/product_types.php
rename to config/discount-rules.php
diff --git a/config/imagecache.php b/config/imagecache.php
index da65ce2b5..9dd290040 100755
--- a/config/imagecache.php
+++ b/config/imagecache.php
@@ -9,13 +9,13 @@ return array(
|
| Enter the routes name to enable dynamic imagecache manipulation.
| This handle will define the first part of the URI:
- |
+ |
| {route}/{template}/{filename}
- |
+ |
| Examples: "images", "img/cache"
|
*/
-
+
'route' => 'cache',
/*
@@ -23,13 +23,13 @@ return array(
| Storage paths
|--------------------------------------------------------------------------
|
- | The following paths will be searched for the image filename, submited
- | by URI.
- |
+ | The following paths will be searched for the image filename, submited
+ | by URI.
+ |
| Define as many directories as you like.
|
*/
-
+
'paths' => array(
storage_path('app/public'),
public_path('storage')
@@ -41,7 +41,7 @@ return array(
|--------------------------------------------------------------------------
|
| Here you may specify your own manipulation filter templates.
- | The keys of this array will define which templates
+ | The keys of this array will define which templates
| are available in the URI:
|
| {route}/{template}/{filename}
@@ -50,7 +50,7 @@ return array(
| will be applied, by its fully qualified name.
|
*/
-
+
'templates' => array(
'small' => 'Webkul\Product\CacheFilters\Small',
'medium' => 'Webkul\Product\CacheFilters\Medium',
@@ -65,7 +65,7 @@ return array(
| Lifetime in minutes of the images handled by the imagecache route.
|
*/
-
+
'lifetime' => 43200,
-);
+);
\ No newline at end of file
diff --git a/config/jwt.php b/config/jwt.php
new file mode 100644
index 000000000..8b7843b6b
--- /dev/null
+++ b/config/jwt.php
@@ -0,0 +1,304 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+return [
+
+ /*
+ |--------------------------------------------------------------------------
+ | JWT Authentication Secret
+ |--------------------------------------------------------------------------
+ |
+ | Don't forget to set this in your .env file, as it will be used to sign
+ | your tokens. A helper command is provided for this:
+ | `php artisan jwt:secret`
+ |
+ | Note: This will be used for Symmetric algorithms only (HMAC),
+ | since RSA and ECDSA use a private/public key combo (See below).
+ |
+ */
+
+ 'secret' => env('JWT_SECRET'),
+
+ /*
+ |--------------------------------------------------------------------------
+ | JWT Authentication Keys
+ |--------------------------------------------------------------------------
+ |
+ | The algorithm you are using, will determine whether your tokens are
+ | signed with a random string (defined in `JWT_SECRET`) or using the
+ | following public & private keys.
+ |
+ | Symmetric Algorithms:
+ | HS256, HS384 & HS512 will use `JWT_SECRET`.
+ |
+ | Asymmetric Algorithms:
+ | RS256, RS384 & RS512 / ES256, ES384 & ES512 will use the keys below.
+ |
+ */
+
+ 'keys' => [
+
+ /*
+ |--------------------------------------------------------------------------
+ | Public Key
+ |--------------------------------------------------------------------------
+ |
+ | A path or resource to your public key.
+ |
+ | E.g. 'file://path/to/public/key'
+ |
+ */
+
+ 'public' => env('JWT_PUBLIC_KEY'),
+
+ /*
+ |--------------------------------------------------------------------------
+ | Private Key
+ |--------------------------------------------------------------------------
+ |
+ | A path or resource to your private key.
+ |
+ | E.g. 'file://path/to/private/key'
+ |
+ */
+
+ 'private' => env('JWT_PRIVATE_KEY'),
+
+ /*
+ |--------------------------------------------------------------------------
+ | Passphrase
+ |--------------------------------------------------------------------------
+ |
+ | The passphrase for your private key. Can be null if none set.
+ |
+ */
+
+ 'passphrase' => env('JWT_PASSPHRASE'),
+
+ ],
+
+ /*
+ |--------------------------------------------------------------------------
+ | JWT time to live
+ |--------------------------------------------------------------------------
+ |
+ | Specify the length of time (in minutes) that the token will be valid for.
+ | Defaults to 1 hour.
+ |
+ | You can also set this to null, to yield a never expiring token.
+ | Some people may want this behaviour for e.g. a mobile app.
+ | This is not particularly recommended, so make sure you have appropriate
+ | systems in place to revoke the token if necessary.
+ | Notice: If you set this to null you should remove 'exp' element from 'required_claims' list.
+ |
+ */
+
+ 'ttl' => env('JWT_TTL', 60),
+
+ /*
+ |--------------------------------------------------------------------------
+ | Refresh time to live
+ |--------------------------------------------------------------------------
+ |
+ | Specify the length of time (in minutes) that the token can be refreshed
+ | within. I.E. The user can refresh their token within a 2 week window of
+ | the original token being created until they must re-authenticate.
+ | Defaults to 2 weeks.
+ |
+ | You can also set this to null, to yield an infinite refresh time.
+ | Some may want this instead of never expiring tokens for e.g. a mobile app.
+ | This is not particularly recommended, so make sure you have appropriate
+ | systems in place to revoke the token if necessary.
+ |
+ */
+
+ 'refresh_ttl' => env('JWT_REFRESH_TTL', 20160),
+
+ /*
+ |--------------------------------------------------------------------------
+ | JWT hashing algorithm
+ |--------------------------------------------------------------------------
+ |
+ | Specify the hashing algorithm that will be used to sign the token.
+ |
+ | See here: https://github.com/namshi/jose/tree/master/src/Namshi/JOSE/Signer/OpenSSL
+ | for possible values.
+ |
+ */
+
+ 'algo' => env('JWT_ALGO', 'HS256'),
+
+ /*
+ |--------------------------------------------------------------------------
+ | Required Claims
+ |--------------------------------------------------------------------------
+ |
+ | Specify the required claims that must exist in any token.
+ | A TokenInvalidException will be thrown if any of these claims are not
+ | present in the payload.
+ |
+ */
+
+ 'required_claims' => [
+ 'iss',
+ 'iat',
+ 'exp',
+ 'nbf',
+ 'sub',
+ 'jti',
+ ],
+
+ /*
+ |--------------------------------------------------------------------------
+ | Persistent Claims
+ |--------------------------------------------------------------------------
+ |
+ | Specify the claim keys to be persisted when refreshing a token.
+ | `sub` and `iat` will automatically be persisted, in
+ | addition to the these claims.
+ |
+ | Note: If a claim does not exist then it will be ignored.
+ |
+ */
+
+ 'persistent_claims' => [
+ // 'foo',
+ // 'bar',
+ ],
+
+ /*
+ |--------------------------------------------------------------------------
+ | Lock Subject
+ |--------------------------------------------------------------------------
+ |
+ | This will determine whether a `prv` claim is automatically added to
+ | the token. The purpose of this is to ensure that if you have multiple
+ | authentication models e.g. `App\User` & `App\OtherPerson`, then we
+ | should prevent one authentication request from impersonating another,
+ | if 2 tokens happen to have the same id across the 2 different models.
+ |
+ | Under specific circumstances, you may want to disable this behaviour
+ | e.g. if you only have one authentication model, then you would save
+ | a little on token size.
+ |
+ */
+
+ 'lock_subject' => true,
+
+ /*
+ |--------------------------------------------------------------------------
+ | Leeway
+ |--------------------------------------------------------------------------
+ |
+ | This property gives the jwt timestamp claims some "leeway".
+ | Meaning that if you have any unavoidable slight clock skew on
+ | any of your servers then this will afford you some level of cushioning.
+ |
+ | This applies to the claims `iat`, `nbf` and `exp`.
+ |
+ | Specify in seconds - only if you know you need it.
+ |
+ */
+
+ 'leeway' => env('JWT_LEEWAY', 0),
+
+ /*
+ |--------------------------------------------------------------------------
+ | Blacklist Enabled
+ |--------------------------------------------------------------------------
+ |
+ | In order to invalidate tokens, you must have the blacklist enabled.
+ | If you do not want or need this functionality, then set this to false.
+ |
+ */
+
+ 'blacklist_enabled' => env('JWT_BLACKLIST_ENABLED', true),
+
+ /*
+ | -------------------------------------------------------------------------
+ | Blacklist Grace Period
+ | -------------------------------------------------------------------------
+ |
+ | When multiple concurrent requests are made with the same JWT,
+ | it is possible that some of them fail, due to token regeneration
+ | on every request.
+ |
+ | Set grace period in seconds to prevent parallel request failure.
+ |
+ */
+
+ 'blacklist_grace_period' => env('JWT_BLACKLIST_GRACE_PERIOD', 0),
+
+ /*
+ |--------------------------------------------------------------------------
+ | Cookies encryption
+ |--------------------------------------------------------------------------
+ |
+ | By default Laravel encrypt cookies for security reason.
+ | If you decide to not decrypt cookies, you will have to configure Laravel
+ | to not encrypt your cookie token by adding its name into the $except
+ | array available in the middleware "EncryptCookies" provided by Laravel.
+ | see https://laravel.com/docs/master/responses#cookies-and-encryption
+ | for details.
+ |
+ | Set it to true if you want to decrypt cookies.
+ |
+ */
+
+ 'decrypt_cookies' => false,
+
+ /*
+ |--------------------------------------------------------------------------
+ | Providers
+ |--------------------------------------------------------------------------
+ |
+ | Specify the various providers used throughout the package.
+ |
+ */
+
+ 'providers' => [
+
+ /*
+ |--------------------------------------------------------------------------
+ | JWT Provider
+ |--------------------------------------------------------------------------
+ |
+ | Specify the provider that is used to create and decode the tokens.
+ |
+ */
+
+ 'jwt' => Tymon\JWTAuth\Providers\JWT\Lcobucci::class,
+
+ /*
+ |--------------------------------------------------------------------------
+ | Authentication Provider
+ |--------------------------------------------------------------------------
+ |
+ | Specify the provider that is used to authenticate users.
+ |
+ */
+
+ 'auth' => Tymon\JWTAuth\Providers\Auth\Illuminate::class,
+
+ /*
+ |--------------------------------------------------------------------------
+ | Storage Provider
+ |--------------------------------------------------------------------------
+ |
+ | Specify the provider that is used to store tokens in the blacklist.
+ |
+ */
+
+ 'storage' => Tymon\JWTAuth\Providers\Storage\Illuminate::class,
+
+ ],
+
+];
diff --git a/config/mail.php b/config/mail.php
index bb92224c5..e458fefce 100755
--- a/config/mail.php
+++ b/config/mail.php
@@ -56,8 +56,8 @@ return [
*/
'from' => [
- 'address' => env('MAIL_FROM_ADDRESS', 'hello@example.com'),
- 'name' => env('MAIL_FROM_NAME', 'Example'),
+ 'address' => env('SHOP_MAIL_FROM'),
+ 'name' => env('MAIL_FROM_NAME')
],
/*
diff --git a/config/paymentmethods.php b/config/paymentmethods.php
index 2ac30fc74..6dd355233 100755
--- a/config/paymentmethods.php
+++ b/config/paymentmethods.php
@@ -1,6 +1,4 @@
\ No newline at end of file
+];
\ No newline at end of file
diff --git a/config/pricerules.php b/config/pricerules.php
new file mode 100644
index 000000000..25058db0c
--- /dev/null
+++ b/config/pricerules.php
@@ -0,0 +1,5 @@
+ env('SPARKPOST_SECRET'),
],
+ 'exchange-api' => [
+ 'default' => 'fixer',
+ 'fixer' => [
+ 'paid_account' => false,
+ 'key' => env('fixer_api_key'),
+ 'class' => 'Webkul\Core\Helpers\Exchange\FixerExchange'
+ ]
+ ],
+
'stripe' => [
'model' => App\User::class,
'key' => env('STRIPE_KEY'),
'secret' => env('STRIPE_SECRET'),
- ],
-
+ ]
];
diff --git a/config/session.php b/config/session.php
index 736fb3c79..f94a17900 100755
--- a/config/session.php
+++ b/config/session.php
@@ -29,9 +29,9 @@ return [
|
*/
- 'lifetime' => env('SESSION_LIFETIME', 120),
+ 'lifetime' => env('SESSION_LIFETIME', 30),
- 'expire_on_close' => false,
+ 'expire_on_close' => true,
/*
|--------------------------------------------------------------------------
diff --git a/config/translatable.php b/config/translatable.php
index 7c556e1ab..1ef910d3e 100755
--- a/config/translatable.php
+++ b/config/translatable.php
@@ -54,7 +54,7 @@ return [
| $useTranslationFallback when defined
|
*/
- 'use_fallback' => true,
+ 'use_fallback' => false,
/*
|--------------------------------------------------------------------------
diff --git a/database/factories/UserFactory.php b/database/factories/UserFactory.php
index facf2337b..467777c5f 100755
--- a/database/factories/UserFactory.php
+++ b/database/factories/UserFactory.php
@@ -20,4 +20,4 @@ $factory->define(App\User::class, function (Faker $faker) {
'password' => '$2y$10$TKh8H1.PfQx37YgCzwiKb.KjNyWgaHb9cbcoQgdIVFlYg7B77UdFm', // secret
'remember_token' => str_random(10),
];
-});
+});
\ No newline at end of file
diff --git a/packages/Webkul/API/Http/Controllers/Shop/AddressController.php b/packages/Webkul/API/Http/Controllers/Shop/AddressController.php
new file mode 100644
index 000000000..32dd0c0e8
--- /dev/null
+++ b/packages/Webkul/API/Http/Controllers/Shop/AddressController.php
@@ -0,0 +1,115 @@
+
+ * @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com)
+ */
+class AddressController extends Controller
+{
+ /**
+ * Contains current guard
+ *
+ * @var array
+ */
+ protected $guard;
+
+ /**
+ * Contains route related configuration
+ *
+ * @var array
+ */
+ protected $_config;
+
+ /**
+ * CustomerAddressRepository object
+ *
+ * @var Object
+ */
+ protected $customerAddressRepository;
+
+ /**
+ * Controller instance
+ *
+ * @param Webkul\Customer\Repositories\CustomerAddressRepository $customerAddressRepository
+ */
+ public function __construct(
+ CustomerAddressRepository $customerAddressRepository
+ )
+ {
+ $this->guard = request()->has('token') ? 'api' : 'customer';
+
+ auth()->setDefaultDriver($this->guard);
+
+ $this->middleware('auth:' . $this->guard);
+
+ $this->_config = request('_config');
+
+ $this->customerAddressRepository = $customerAddressRepository;
+ }
+
+ /**
+ * Store a newly created resource in storage.
+ *
+ * @return \Illuminate\Http\Response
+ */
+ public function store()
+ {
+ $customer = auth($this->guard)->user();
+
+ request()->merge([
+ 'address1' => implode(PHP_EOL, array_filter(request()->input('address1'))),
+ 'customer_id' => $customer->id
+ ]);
+
+ $this->validate(request(), [
+ 'address1' => 'string|required',
+ 'country' => 'string|required',
+ 'state' => 'string|required',
+ 'city' => 'string|required',
+ 'postcode' => 'required',
+ 'phone' => 'required'
+ ]);
+
+ $customerAddress = $this->customerAddressRepository->create(request()->all());
+
+ return response()->json([
+ 'message' => 'Your address has been created successfully.',
+ 'data' => new CustomerAddressResource($customerAddress)
+ ]);
+ }
+
+ /**
+ * Update the specified resource in storage.
+ *
+ * @return \Illuminate\Http\Response
+ */
+ public function update()
+ {
+ $customer = auth($this->guard)->user();
+
+ 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'
+ ]);
+
+ $this->customerAddressRepository->update(request()->all(), request()->input('id'));
+
+ return response()->json([
+ 'message' => 'Your address has been updated successfully.',
+ 'data' => new CustomerAddressResource($this->customerAddressRepository->find(request()->input('id')))
+ ]);
+ }
+}
\ No newline at end of file
diff --git a/packages/Webkul/API/Http/Controllers/Shop/CartController.php b/packages/Webkul/API/Http/Controllers/Shop/CartController.php
new file mode 100644
index 000000000..1846c7a9e
--- /dev/null
+++ b/packages/Webkul/API/Http/Controllers/Shop/CartController.php
@@ -0,0 +1,215 @@
+
+ * @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com)
+ */
+class CartController extends Controller
+{
+ /**
+ * Contains current guard
+ *
+ * @var array
+ */
+ protected $guard;
+
+ /**
+ * CartRepository object
+ *
+ * @var Object
+ */
+ protected $cartRepository;
+
+ /**
+ * CartItemRepository object
+ *
+ * @var Object
+ */
+ protected $cartItemRepository;
+
+ /**
+ * Controller instance
+ *
+ * @param Webkul\Checkout\Repositories\CartRepository $cartRepository
+ * @param Webkul\Checkout\Repositories\CartItemRepository $cartItemRepository
+ */
+ public function __construct(
+ CartRepository $cartRepository,
+ CartItemRepository $cartItemRepository
+ )
+ {
+ $this->guard = request()->has('token') ? 'api' : 'customer';
+
+ auth()->setDefaultDriver($this->guard);
+
+ // $this->middleware('auth:' . $this->guard);
+
+ $this->_config = request('_config');
+
+ $this->cartRepository = $cartRepository;
+
+ $this->cartItemRepository = $cartItemRepository;
+ }
+
+ /**
+ * Get customer cart
+ *
+ * @return \Illuminate\Http\Response
+ */
+ public function get()
+ {
+ $customer = auth($this->guard)->user();
+
+ $cart = Cart::getCart();
+
+ return response()->json([
+ 'data' => $cart ? new CartResource($cart) : null
+ ]);
+ }
+
+
+ /**
+ * Store a newly created resource in storage.
+ *
+ * @param int $id
+ * @return \Illuminate\Http\Response
+ */
+ public function store($id)
+ {
+ Event::fire('checkout.cart.item.add.before', $id);
+
+ $result = Cart::add($id, request()->except('_token'));
+
+ if (! $result) {
+ $message = session()->get('warning') ?? session()->get('error');
+ return response()->json([
+ 'error' => session()->get('warning')
+ ], 400);
+ }
+
+ Event::fire('checkout.cart.item.add.after', $result);
+
+ Cart::collectTotals();
+
+ $cart = Cart::getCart();
+
+ return response()->json([
+ 'message' => 'Product added to cart successfully.',
+ 'data' => $cart ? new CartResource($cart) : null
+ ]);
+ }
+
+ /**
+ * Update the specified resource in storage.
+ *
+ * @return \Illuminate\Http\Response
+ */
+ public function update()
+ {
+ foreach (request()->get('qty') as$qty) {
+ if ($qty <= 0) {
+ return response()->json([
+ 'message' => trans('shop::app.checkout.cart.quantity.illegal')
+ ], 401);
+ }
+ }
+
+ foreach (request()->get('qty') as $itemId => $qty) {
+ $item = $this->cartItemRepository->findOneByField('id', $itemId);
+
+ Event::fire('checkout.cart.item.update.before', $itemId);
+
+ Cart::updateItem($item->product_id, ['quantity' => $qty], $itemId);
+
+ Event::fire('checkout.cart.item.update.after', $item);
+ }
+
+ Cart::collectTotals();
+
+ $cart = Cart::getCart();
+
+ return response()->json([
+ 'message' => 'Cart updated successfully.',
+ 'data' => $cart ? new CartResource($cart) : null
+ ]);
+ }
+
+ /**
+ * Remove the specified resource from storage.
+ *
+ * @return \Illuminate\Http\Response
+ */
+ public function destroy()
+ {
+ Event::fire('checkout.cart.delete.before');
+
+ Cart::deActivateCart();
+
+ Event::fire('checkout.cart.delete.after');
+
+ $cart = Cart::getCart();
+
+ return response()->json([
+ 'message' => 'Cart removed successfully.',
+ 'data' => $cart ? new CartResource($cart) : null
+ ]);
+ }
+
+ /**
+ * Remove the specified resource from storage.
+ *
+ * @param int $id
+ * @return \Illuminate\Http\Response
+ */
+ public function destroyItem($id)
+ {
+ Event::fire('checkout.cart.item.delete.before', $id);
+
+ Cart::removeItem($id);
+
+ Event::fire('checkout.cart.item.delete.after', $id);
+
+ Cart::collectTotals();
+
+ $cart = Cart::getCart();
+
+ return response()->json([
+ 'message' => 'Cart removed successfully.',
+ 'data' => $cart ? new CartResource($cart) : null
+ ]);
+ }
+
+ /**
+ * Function to move a already added product to wishlist
+ * will run only on customer authentication.
+ *
+ * @param instance cartItem $id
+ */
+ public function moveToWishlist($id)
+ {
+ Event::fire('checkout.cart.item.move-to-wishlist.before', $id);
+
+ Cart::moveToWishlist($id);
+
+ Event::fire('checkout.cart.item.move-to-wishlist.after', $id);
+
+ Cart::collectTotals();
+
+ $cart = Cart::getCart();
+
+ return response()->json([
+ 'message' => 'Cart item moved to wishlist successfully.',
+ 'data' => $cart ? new CartResource($cart) : null
+ ]);
+ }
+}
\ No newline at end of file
diff --git a/packages/Webkul/API/Http/Controllers/Shop/CategoryController.php b/packages/Webkul/API/Http/Controllers/Shop/CategoryController.php
index 89b737dd5..19a5b2390 100755
--- a/packages/Webkul/API/Http/Controllers/Shop/CategoryController.php
+++ b/packages/Webkul/API/Http/Controllers/Shop/CategoryController.php
@@ -3,7 +3,6 @@
namespace Webkul\API\Http\Controllers\Shop;
use Illuminate\Http\Request;
-use Illuminate\Http\Response;
use Webkul\Category\Repositories\CategoryRepository;
use Webkul\API\Http\Resources\Catalog\Category as CategoryResource;
diff --git a/packages/Webkul/API/Http/Controllers/Shop/CheckoutController.php b/packages/Webkul/API/Http/Controllers/Shop/CheckoutController.php
new file mode 100644
index 000000000..c16adf18b
--- /dev/null
+++ b/packages/Webkul/API/Http/Controllers/Shop/CheckoutController.php
@@ -0,0 +1,220 @@
+
+ * @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com)
+ */
+class CheckoutController extends Controller
+{
+ /**
+ * Contains current guard
+ *
+ * @var array
+ */
+ protected $guard;
+
+ /**
+ * CartRepository object
+ *
+ * @var Object
+ */
+ protected $cartRepository;
+
+ /**
+ * CartItemRepository object
+ *
+ * @var Object
+ */
+ protected $cartItemRepository;
+
+ /**
+ * Controller instance
+ *
+ * @param Webkul\Checkout\Repositories\CartRepository $cartRepository
+ * @param Webkul\Checkout\Repositories\CartItemRepository $cartItemRepository
+ * @param Webkul\Sales\Repositories\OrderRepository $orderRepository
+ */
+ public function __construct(
+ CartRepository $cartRepository,
+ CartItemRepository $cartItemRepository,
+ OrderRepository $orderRepository
+ )
+ {
+ $this->guard = request()->has('token') ? 'api' : 'customer';
+
+ auth()->setDefaultDriver($this->guard);
+
+
+ // $this->middleware('auth:' . $this->guard);
+
+ $this->_config = request('_config');
+
+ $this->cartRepository = $cartRepository;
+
+ $this->cartItemRepository = $cartItemRepository;
+
+ $this->orderRepository = $orderRepository;
+ }
+
+ /**
+ * Saves customer address.
+ *
+ * @param \Webkul\Checkout\Http\Requests\CustomerAddressForm $request
+ * @return \Illuminate\Http\Response
+ */
+ public function saveAddress(CustomerAddressForm $request)
+ {
+ $data = request()->all();
+
+ $data['billing']['address1'] = implode(PHP_EOL, array_filter($data['billing']['address1']));
+ $data['shipping']['address1'] = implode(PHP_EOL, array_filter($data['shipping']['address1']));
+
+ if (isset($data['billing']['id']) && str_contains($data['billing']['id'], 'address_')) {
+ unset($data['billing']['id']);
+ unset($data['billing']['address_id']);
+ }
+
+ if (isset($data['shipping']['id']) && str_contains($data['shipping']['id'], 'address_')) {
+ unset($data['shipping']['id']);
+ unset($data['shipping']['address_id']);
+ }
+
+
+ if (Cart::hasError() || ! Cart::saveCustomerAddress($data) || ! Shipping::collectRates())
+ abort(400);
+
+ $rates = [];
+
+ foreach (Shipping::getGroupedAllShippingRates() as $code => $shippingMethod) {
+ $rates[] = [
+ 'carrier_title' => $shippingMethod['carrier_title'],
+ 'rates' => CartShippingRateResource::collection(collect($shippingMethod['rates']))
+ ];
+ }
+
+ Cart::collectTotals();
+
+ return response()->json([
+ 'data' => [
+ 'rates' => $rates,
+ 'cart' => new CartResource(Cart::getCart())
+ ]
+ ]);
+ }
+
+ /**
+ * Saves shipping method.
+ *
+ * @return \Illuminate\Http\Response
+ */
+ public function saveShipping()
+ {
+ $shippingMethod = request()->get('shipping_method');
+
+ if (Cart::hasError() || !$shippingMethod || ! Cart::saveShippingMethod($shippingMethod))
+ abort(400);
+
+ Cart::collectTotals();
+
+ return response()->json([
+ 'data' => [
+ 'methods' => Payment::getPaymentMethods(),
+ 'cart' => new CartResource(Cart::getCart())
+ ]
+ ]);
+ }
+
+ /**
+ * Saves payment method.
+ *
+ * @return \Illuminate\Http\Response
+ */
+ public function savePayment()
+ {
+ $payment = request()->get('payment');
+
+ if (Cart::hasError() || ! $payment || ! Cart::savePaymentMethod($payment))
+ abort(400);
+
+ return response()->json([
+ 'data' => [
+ 'cart' => new CartResource(Cart::getCart())
+ ]
+ ]);
+ }
+
+ /**
+ * Saves order.
+ *
+ * @return \Illuminate\Http\Response
+ */
+ public function saveOrder()
+ {
+ if (Cart::hasError())
+ abort(400);
+
+ Cart::collectTotals();
+
+ $this->validateOrder();
+
+ $cart = Cart::getCart();
+
+ if ($redirectUrl = Payment::getRedirectUrl($cart)) {
+ return response()->json([
+ 'success' => true,
+ 'redirect_url' => $redirectUrl
+ ]);
+ }
+
+ $order = $this->orderRepository->create(Cart::prepareDataForOrder());
+
+ Cart::deActivateCart();
+
+ return response()->json([
+ 'success' => true,
+ 'order' => new OrderResource($order),
+ ]);
+ }
+
+ /**
+ * Validate order before creation
+ *
+ * @return mixed
+ */
+ public function validateOrder()
+ {
+ $cart = Cart::getCart();
+
+ if (! $cart->shipping_address) {
+ throw new \Exception(trans('Please check shipping address.'));
+ }
+
+ if (! $cart->billing_address) {
+ throw new \Exception(trans('Please check billing address.'));
+ }
+
+ if (! $cart->selected_shipping_rate) {
+ throw new \Exception(trans('Please specify shipping method.'));
+ }
+
+ if (! $cart->payment) {
+ throw new \Exception(trans('Please specify payment method.'));
+ }
+ }
+}
\ No newline at end of file
diff --git a/packages/Webkul/API/Http/Controllers/Shop/CoreController.php b/packages/Webkul/API/Http/Controllers/Shop/CoreController.php
index 56c347466..27290bdcd 100755
--- a/packages/Webkul/API/Http/Controllers/Shop/CoreController.php
+++ b/packages/Webkul/API/Http/Controllers/Shop/CoreController.php
@@ -3,7 +3,6 @@
namespace Webkul\API\Http\Controllers\Shop;
use Illuminate\Http\Request;
-use Illuminate\Http\Response;
/**
* Core controller
@@ -13,6 +12,36 @@ use Illuminate\Http\Response;
*/
class CoreController extends Controller
{
+ /**
+ * Returns a listing of the resource.
+ *
+ * @return \Illuminate\Http\Response
+ */
+ public function getConfig()
+ {
+ $configValues = [];
+
+ foreach (explode(',', request()->input('_config')) as $config) {
+ $configValues[$config] = core()->getConfigData($config);
+ }
+
+ return response()->json([
+ 'data' => $configValues
+ ]);
+ }
+
+ /**
+ * Returns a listing of the resource.
+ *
+ * @return \Illuminate\Http\Response
+ */
+ public function getCountryStateGroup()
+ {
+ return response()->json([
+ 'data' => core()->groupedStatesByCountries()
+ ]);
+ }
+
/**
* Returns a listing of the resource.
*
diff --git a/packages/Webkul/API/Http/Controllers/Shop/CustomerController.php b/packages/Webkul/API/Http/Controllers/Shop/CustomerController.php
new file mode 100644
index 000000000..d5296b841
--- /dev/null
+++ b/packages/Webkul/API/Http/Controllers/Shop/CustomerController.php
@@ -0,0 +1,73 @@
+
+ * @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com)
+ */
+class CustomerController extends Controller
+{
+ /**
+ * Contains route related configuration
+ *
+ * @var array
+ */
+ protected $_config;
+
+ /**
+ * Repository object
+ *
+ * @var array
+ */
+ protected $customerRepository;
+
+ /**
+ * @param CustomerRepository object $customer
+ */
+ public function __construct(CustomerRepository $customerRepository)
+ {
+ $this->_config = request('_config');
+
+ $this->customerRepository = $customerRepository;
+ }
+
+ /**
+ * Method to store user's sign up form data to DB.
+ *
+ * @return Mixed
+ */
+ public function create()
+ {
+ request()->validate([
+ 'first_name' => 'required',
+ 'last_name' => 'required',
+ 'email' => 'email|required|unique:customers,email',
+ 'password' => 'confirmed|min:6|required'
+ ]);
+
+ $data = request()->input();
+
+ $data = array_merge($data, [
+ 'password' => bcrypt($data['password']),
+ 'channel_id' => core()->getCurrentChannel()->id,
+ 'is_verified' => 1,
+ 'customer_group_id' => 1
+ ]);
+
+ Event::fire('customer.registration.before');
+
+ $customer = $this->customerRepository->create($data);
+
+ Event::fire('customer.registration.after', $customer);
+
+ return response()->json([
+ 'message' => 'Your account has been created successfully.'
+ ]);
+ }
+}
\ No newline at end of file
diff --git a/packages/Webkul/API/Http/Controllers/Shop/ForgotPasswordController.php b/packages/Webkul/API/Http/Controllers/Shop/ForgotPasswordController.php
new file mode 100644
index 000000000..50529541e
--- /dev/null
+++ b/packages/Webkul/API/Http/Controllers/Shop/ForgotPasswordController.php
@@ -0,0 +1,51 @@
+
+ * @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com)
+ */
+class ForgotPasswordController extends Controller
+{
+ use SendsPasswordResetEmails;
+
+ /**
+ * Store a newly created resource in storage.
+ *
+ * @return \Illuminate\Http\Response
+ */
+ public function store()
+ {
+ $this->validate(request(), [
+ 'email' => 'required|email'
+ ]);
+
+ $response = $this->broker()->sendResetLink(request(['email']));
+
+ if ($response == Password::RESET_LINK_SENT) {
+ return response()->json([
+ 'message' => trans($response)
+ ]);
+ }
+
+ return response()->json([
+ 'error' => trans($response)
+ ]);
+ }
+
+ /**
+ * Get the broker to be used during password reset.
+ *
+ * @return \Illuminate\Contracts\Auth\PasswordBroker
+ */
+ public function broker()
+ {
+ return Password::broker('customers');
+ }
+}
\ No newline at end of file
diff --git a/packages/Webkul/API/Http/Controllers/Shop/ProductController.php b/packages/Webkul/API/Http/Controllers/Shop/ProductController.php
index 65d9b9ec1..3f7c4acce 100755
--- a/packages/Webkul/API/Http/Controllers/Shop/ProductController.php
+++ b/packages/Webkul/API/Http/Controllers/Shop/ProductController.php
@@ -30,8 +30,6 @@ class ProductController extends Controller
*/
public function __construct(ProductRepository $productRepository)
{
- // $this->middleware('auth:api');
-
$this->productRepository = $productRepository;
}
@@ -42,7 +40,7 @@ class ProductController extends Controller
*/
public function index()
{
- return ProductResource::collection($this->productRepository->getAll());
+ return ProductResource::collection($this->productRepository->getAll(request()->input('category_id')));
}
/**
@@ -56,4 +54,28 @@ class ProductController extends Controller
$this->productRepository->findOrFail($id)
);
}
+
+ /**
+ * Returns product's additional information.
+ *
+ * @return \Illuminate\Http\Response
+ */
+ public function additionalInformation($id)
+ {
+ return response()->json([
+ 'data' => app('Webkul\Product\Helpers\View')->getAdditionalData($this->productRepository->findOrFail($id))
+ ]);
+ }
+
+ /**
+ * Returns product's additional information.
+ *
+ * @return \Illuminate\Http\Response
+ */
+ public function configurableConfig($id)
+ {
+ return response()->json([
+ 'data' => app('Webkul\Product\Helpers\ConfigurableOption')->getConfigurationConfig($this->productRepository->findOrFail($id))
+ ]);
+ }
}
diff --git a/packages/Webkul/API/Http/Controllers/Shop/ResourceController.php b/packages/Webkul/API/Http/Controllers/Shop/ResourceController.php
index f88ee55a4..2fdd8b859 100644
--- a/packages/Webkul/API/Http/Controllers/Shop/ResourceController.php
+++ b/packages/Webkul/API/Http/Controllers/Shop/ResourceController.php
@@ -3,7 +3,6 @@
namespace Webkul\API\Http\Controllers\Shop;
use Illuminate\Http\Request;
-use Illuminate\Http\Response;
/**
* Resource Controller
@@ -13,6 +12,13 @@ use Illuminate\Http\Response;
*/
class ResourceController extends Controller
{
+ /**
+ * Contains current guard
+ *
+ * @var array
+ */
+ protected $guard;
+
/**
* Contains route related configuration
*
@@ -34,10 +40,17 @@ class ResourceController extends Controller
*/
public function __construct()
{
- // $this->middleware('auth:api');
+ $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);
+ }
+
$this->repository = app($this->_config['repository']);
}
@@ -49,12 +62,14 @@ class ResourceController extends Controller
public function index()
{
$query = $this->repository->scopeQuery(function($query) {
- foreach (request()->except(['page', 'limit', 'pagination', 'sort', 'order']) as $input => $value) {
- $query = $query->where($input, $value);
+ 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;
@@ -80,4 +95,20 @@ class ResourceController extends Controller
$this->repository->findOrFail($id)
);
}
+
+ /**
+ * Delete's a individual resource.
+ *
+ * @return \Illuminate\Http\Response
+ */
+ public function destroy($id)
+ {
+ $wishlistProduct = $this->repository->findOrFail($id);
+
+ $this->repository->delete($id);
+
+ return response()->json([
+ 'message' => 'Item removed successfully.'
+ ]);
+ }
}
diff --git a/packages/Webkul/API/Http/Controllers/Shop/ReviewController.php b/packages/Webkul/API/Http/Controllers/Shop/ReviewController.php
new file mode 100644
index 000000000..5121628be
--- /dev/null
+++ b/packages/Webkul/API/Http/Controllers/Shop/ReviewController.php
@@ -0,0 +1,75 @@
+
+ * @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com)
+ */
+class ReviewController extends Controller
+{
+ /**
+ * Contains current guard
+ *
+ * @var array
+ */
+ protected $guard;
+
+ /**
+ * ProductReviewRepository object
+ *
+ * @var array
+ */
+ protected $reviewRepository;
+
+ /**
+ * Controller instance
+ *
+ * @param Webkul\Product\Repositories\ProductReviewRepository $reviewRepository
+ */
+ public function __construct(ProductReviewRepository $reviewRepository)
+ {
+ $this->guard = request()->has('token') ? 'api' : 'customer';
+
+ auth()->setDefaultDriver($this->guard);
+
+ $this->reviewRepository = $reviewRepository;
+ }
+
+ /**
+ * Store a newly created resource in storage.
+ *
+ * @param \Illuminate\Http\Request $request
+ * @return \Illuminate\Http\Response
+ */
+ public function store(Request $request, $id)
+ {
+ $customer = auth($this->guard)->user();
+
+ $this->validate(request(), [
+ 'comment' => 'required',
+ 'rating' => 'required|numeric|min:1|max:5',
+ 'title' => 'required',
+ ]);
+
+ $data = array_merge(request()->all(), [
+ 'customer_id' => $customer ? $customer->id : null,
+ 'name' => $customer ? $customer->name : request()->input('name'),
+ 'status' => 'pending',
+ 'product_id' => $id
+ ]);
+
+ $productReview = $this->reviewRepository->create($data);
+
+ return response()->json([
+ 'message' => 'Your review submitted successfully.',
+ 'data' => new ProductReviewResource($this->reviewRepository->find($productReview->id))
+ ]);
+ }
+}
\ No newline at end of file
diff --git a/packages/Webkul/API/Http/Controllers/Shop/SessionController.php b/packages/Webkul/API/Http/Controllers/Shop/SessionController.php
new file mode 100644
index 000000000..0d6b83ce9
--- /dev/null
+++ b/packages/Webkul/API/Http/Controllers/Shop/SessionController.php
@@ -0,0 +1,145 @@
+
+ * @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com)
+ */
+class SessionController extends Controller
+{
+ /**
+ * Contains current guard
+ *
+ * @var array
+ */
+ protected $guard;
+
+ /**
+ * Contains route related configuration
+ *
+ * @var array
+ */
+ protected $_config;
+
+ /**
+ * Controller instance
+ *
+ * @param Webkul\Customer\Repositories\CustomerRepository $customerRepository
+ */
+ public function __construct(CustomerRepository $customerRepository)
+ {
+ $this->guard = request()->has('token') ? 'api' : 'customer';
+
+ auth()->setDefaultDriver($this->guard);
+
+ $this->middleware('auth:' . $this->guard, ['only' => ['get', 'update', 'destroy']]);
+
+ $this->_config = request('_config');
+
+ $this->customerRepository = $customerRepository;
+ }
+
+ /**
+ * Method to store user's sign up form data to DB.
+ *
+ * @return Mixed
+ */
+ public function create()
+ {
+ request()->validate([
+ 'email' => 'required|email',
+ 'password' => 'required'
+ ]);
+
+ $jwtToken = null;
+
+ if (! $jwtToken = auth()->guard($this->guard)->attempt(request()->only('email', 'password'))) {
+ return response()->json([
+ 'error' => 'Invalid Email or Password',
+ ], 401);
+ }
+
+ Event::fire('customer.after.login', request()->input('email'));
+
+ $customer = auth($this->guard)->user();
+
+ return response()->json([
+ 'token' => $jwtToken,
+ 'message' => 'Logged in successfully.',
+ 'data' => new CustomerResource($customer)
+ ]);
+ }
+
+ /**
+ * Get details for current logged in customer
+ *
+ * @return \Illuminate\Http\Response
+ */
+ public function get()
+ {
+ $customer = auth($this->guard)->user();
+
+ return response()->json([
+ 'data' => new CustomerResource($customer)
+ ]);
+ }
+
+ /**
+ * Update the specified resource in storage.
+ *
+ * @return \Illuminate\Http\Response
+ */
+ public function update()
+ {
+ $customer = auth($this->guard)->user();
+
+ $this->validate(request(), [
+ 'first_name' => 'required',
+ 'last_name' => 'required',
+ 'gender' => 'required',
+ 'date_of_birth' => 'nullable|date|before:today',
+ 'email' => 'email|unique:customers,email,' . $customer->id,
+ 'password' => 'confirmed|min:6'
+ ]);
+
+ $data = request()->all();
+
+ if (! $data['date_of_birth']) {
+ unset($data['date_of_birth']);
+ }
+
+ if (!isset($data['password']) || ! $data['password']) {
+ unset($data['password']);
+ } else {
+ $data['password'] = bcrypt($data['password']);
+ }
+
+ $this->customerRepository->update($data, $customer->id);
+
+ return response()->json([
+ 'message' => 'Your account has been created successfully.',
+ 'data' => new CustomerResource($this->customerRepository->find($customer->id))
+ ]);
+ }
+
+ /**
+ * Remove the specified resource from storage.
+ *
+ * @return \Illuminate\Http\Response
+ */
+ public function destroy()
+ {
+ auth()->guard($this->guard)->logout();
+
+ return response()->json([
+ 'message' => 'Logged out successfully.',
+ ]);
+ }
+}
\ No newline at end of file
diff --git a/packages/Webkul/API/Http/Controllers/Shop/WishlistController.php b/packages/Webkul/API/Http/Controllers/Shop/WishlistController.php
new file mode 100644
index 000000000..9086e3f6a
--- /dev/null
+++ b/packages/Webkul/API/Http/Controllers/Shop/WishlistController.php
@@ -0,0 +1,135 @@
+
+ * @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com)
+ */
+class WishlistController extends Controller
+{
+ /**
+ * WishlistRepository object
+ *
+ * @var object
+ */
+ protected $wishlistRepository;
+
+ /**
+ * ProductRepository object
+ *
+ * @var object
+ */
+ protected $productRepository;
+
+ /**
+ * @param Webkul\Customer\Repositories\WishlistRepository $wishlistRepository
+ * @param Webkul\Product\Repositories\ProductRepository $productRepository
+ */
+ public function __construct(
+ WishlistRepository $wishlistRepository,
+ ProductRepository $productRepository
+ )
+ {
+ $this->guard = request()->has('token') ? 'api' : 'customer';
+
+ auth()->setDefaultDriver($this->guard);
+
+ $this->middleware('auth:' . $this->guard);
+
+ $this->wishlistRepository = $wishlistRepository;
+
+ $this->productRepository = $productRepository;
+ }
+
+ /**
+ * Function to add item to the wishlist.
+ *
+ * @param integer $id
+ * @return \Illuminate\Http\Response
+ */
+ public function create($id)
+ {
+ $product = $this->productRepository->findOrFail($id);
+
+ $customer = auth()->guard($this->guard)->user();
+
+ $wishlistItem = $this->wishlistRepository->findOneWhere([
+ 'channel_id' => core()->getCurrentChannel()->id,
+ 'product_id' => $id,
+ 'customer_id' => $customer->id
+ ]);
+
+ if (! $wishlistItem) {
+ $wishlistItem = $this->wishlistRepository->create([
+ 'channel_id' => core()->getCurrentChannel()->id,
+ 'product_id' => $id,
+ 'customer_id' => $customer->id
+ ]);
+
+ return response()->json([
+ 'data' => new WishlistResource($wishlistItem),
+ 'message' => trans('customer::app.wishlist.success')
+ ]);
+ } else {
+ $this->wishlistRepository->delete($wishlistItem->id);
+
+ return response()->json([
+ 'data' => null,
+ 'message' => 'Item removed from wishlist successfully.'
+ ]);
+ }
+ }
+
+ /**
+ * Move product from wishlist to cart.
+ *
+ * @param integer $id
+ * @return \Illuminate\Http\Response
+ */
+ public function moveToCart($id)
+ {
+ $wishlistItem = $this->wishlistRepository->findOrFail($id);
+
+ if ($wishlistItem->customer_id != auth()->guard($this->guard)->user()->id)
+ return response()->json([
+ 'message' => trans('shop::app.security-warning')
+ ], 400);
+
+ $result = Cart::moveToCart($wishlistItem);
+
+ if ($result == 1) {
+ if ($wishlistItem->delete()) {
+ Cart::collectTotals();
+
+ return response()->json([
+ 'data' => 1,
+ 'message' => trans('shop::app.wishlist.moved')
+ ]);
+ } else {
+ return response()->json([
+ 'data' => 1,
+ 'error' => trans('shop::app.wishlist.move-error')
+ ], 400);
+ }
+ } else if ($result == 0) {
+ return response()->json([
+ 'data' => 0,
+ 'error' => trans('shop::app.wishlist.error')
+ ], 400);
+ } else if ($result == -1) {
+ return response()->json([
+ 'data' => -1,
+ 'error' => trans('shop::app.checkout.cart.add-config-warning')
+ ], 400);
+ }
+ }
+}
\ No newline at end of file
diff --git a/packages/Webkul/API/Http/Resources/Catalog/Attribute.php b/packages/Webkul/API/Http/Resources/Catalog/Attribute.php
index 53d7be651..098b93f12 100644
--- a/packages/Webkul/API/Http/Resources/Catalog/Attribute.php
+++ b/packages/Webkul/API/Http/Resources/Catalog/Attribute.php
@@ -17,6 +17,7 @@ class Attribute extends JsonResource
return [
'id' => $this->id,
'code' => $this->code,
+ 'type' => $this->type,
'name' => $this->name,
'swatch_type' => $this->swatch_type,
'options' => AttributeOption::collection($this->options),
diff --git a/packages/Webkul/API/Http/Resources/Catalog/Category.php b/packages/Webkul/API/Http/Resources/Catalog/Category.php
index cb1e69af8..2ecb649ac 100644
--- a/packages/Webkul/API/Http/Resources/Catalog/Category.php
+++ b/packages/Webkul/API/Http/Resources/Catalog/Category.php
@@ -19,6 +19,7 @@ class Category extends JsonResource
'code' => $this->code,
'name' => $this->name,
'slug' => $this->slug,
+ 'display_mode' => $this->display_mode,
'description' => $this->description,
'meta_title' => $this->meta_title,
'meta_description' => $this->meta_description,
diff --git a/packages/Webkul/API/Http/Resources/Catalog/Product.php b/packages/Webkul/API/Http/Resources/Catalog/Product.php
index daed34d40..b2617b4b9 100644
--- a/packages/Webkul/API/Http/Resources/Catalog/Product.php
+++ b/packages/Webkul/API/Http/Resources/Catalog/Product.php
@@ -17,6 +17,8 @@ class Product extends JsonResource
$this->productImageHelper = app('Webkul\Product\Helpers\ProductImage');
+ $this->productReviewHelper = app('Webkul\Product\Helpers\Review');
+
parent::__construct($resource);
}
@@ -34,14 +36,16 @@ class Product extends JsonResource
'id' => $product->id,
'type' => $product->type,
'name' => $this->name,
- 'price' => $this->price,
- 'formated_price' => core()->currency($this->price),
+ 'url_key' => $this->url_key,
+ 'price' => $product->type == 'configurable' ? $this->productPriceHelper->getVariantMinPrice($product) : $this->price,
+ 'formated_price' => $product->type == 'configurable' ? core()->currency($this->productPriceHelper->getVariantMinPrice($product)) : core()->currency($this->price),
+ 'short_description' => $this->short_description,
'description' => $this->description,
'sku' => $this->sku,
'images' => ProductImage::collection($product->images),
'base_image' => $this->productImageHelper->getProductBaseImage($product),
'variants' => Self::collection($this->variants),
- 'in_stock' => $product->haveSufficientQuantity(1),
+ 'in_stock' => $product->type == 'configurable' ? 1 : $product->haveSufficientQuantity(1),
$this->mergeWhen($product->type == 'configurable', [
'super_attributes' => Attribute::collection($product->super_attributes),
]),
@@ -53,6 +57,13 @@ class Product extends JsonResource
$this->productPriceHelper->haveSpecialPrice($product),
core()->currency($this->productPriceHelper->getSpecialPrice($product))
),
+ 'reviews' => [
+ 'total' => $total = $this->productReviewHelper->getTotalReviews($product),
+ 'total_rating' => $total ? $this->productReviewHelper->getTotalRating($product) : 0,
+ 'average_rating' => $total ? $this->productReviewHelper->getAverageRating($product) : 0,
+ 'percentage' => $total ? json_encode($this->productReviewHelper->getPercentageRating($product)) : [],
+ ],
+ 'is_saved' => false,
'created_at' => $this->created_at,
'updated_at' => $this->updated_at,
];
diff --git a/packages/Webkul/API/Http/Resources/Catalog/ProductImage.php b/packages/Webkul/API/Http/Resources/Catalog/ProductImage.php
index 6cbff228b..cd4e574bf 100644
--- a/packages/Webkul/API/Http/Resources/Catalog/ProductImage.php
+++ b/packages/Webkul/API/Http/Resources/Catalog/ProductImage.php
@@ -18,6 +18,7 @@ class ProductImage extends JsonResource
'id' => $this->id,
'path' => $this->path,
'url' => $this->url,
+ 'original_image_url' => $this->url,
'small_image_url' => url('cache/small/' . $this->path),
'medium_image_url' => url('cache/medium/' . $this->path),
'large_image_url' => url('cache/large/' . $this->path)
diff --git a/packages/Webkul/API/Http/Resources/Catalog/ProductReview.php b/packages/Webkul/API/Http/Resources/Catalog/ProductReview.php
index 4b6799283..a2902b598 100644
--- a/packages/Webkul/API/Http/Resources/Catalog/ProductReview.php
+++ b/packages/Webkul/API/Http/Resources/Catalog/ProductReview.php
@@ -18,7 +18,7 @@ class ProductReview extends JsonResource
return [
'id' => $this->id,
'title' => $this->title,
- 'rating' => $this->rating,
+ 'rating' => number_format($this->rating, 1, '.', ''),
'comment' => $this->comment,
'name' => $this->name,
'status' => $this->status,
diff --git a/packages/Webkul/API/Http/Resources/Checkout/Cart.php b/packages/Webkul/API/Http/Resources/Checkout/Cart.php
new file mode 100644
index 000000000..2a6401b9e
--- /dev/null
+++ b/packages/Webkul/API/Http/Resources/Checkout/Cart.php
@@ -0,0 +1,65 @@
+ $this->id,
+ 'customer_email' => $this->customer_email,
+ 'customer_first_name' => $this->customer_first_name,
+ 'customer_last_name' => $this->customer_last_name,
+ 'shipping_method' => $this->shipping_method,
+ 'coupon_code' => $this->coupon_code,
+ 'is_gift' => $this->is_gift,
+ 'items_count' => $this->items_count,
+ 'items_qty' => $this->items_qty,
+ 'exchange_rate' => $this->exchange_rate,
+ 'global_currency_code' => $this->global_currency_code,
+ 'base_currency_code' => $this->base_currency_code,
+ 'channel_currency_code' => $this->channel_currency_code,
+ 'cart_currency_code' => $this->cart_currency_code,
+ 'grand_total' => $this->grand_total,
+ 'formated_grand_total' => core()->formatPrice($this->grand_total, $this->cart_currency_code),
+ 'base_grand_total' => $this->base_grand_total,
+ 'formated_base_grand_total' => core()->formatBasePrice($this->base_grand_total),
+ 'sub_total' => $this->sub_total,
+ 'formated_sub_total' => core()->formatPrice($this->sub_total, $this->cart_currency_code),
+ 'base_sub_total' => $this->base_sub_total,
+ 'formated_base_sub_total' => core()->formatBasePrice($this->base_sub_total),
+ 'tax_total' => $this->tax_total,
+ 'formated_tax_total' => core()->formatPrice($this->tax_total, $this->cart_currency_code),
+ 'base_tax_total' => $this->base_tax_total,
+ 'formated_base_tax_total' => core()->formatBasePrice($this->base_tax_total),
+ 'discount' => $this->discount,
+ 'formated_discount' => core()->formatPrice($this->discount, $this->cart_currency_code),
+ 'base_discount' => $this->base_discount,
+ 'formated_base_discount' => core()->formatBasePrice($this->base_discount),
+ 'checkout_method' => $this->checkout_method,
+ 'is_guest' => $this->is_guest,
+ 'is_active' => $this->is_active,
+ 'conversion_time' => $this->conversion_time,
+ 'customer' => $this->when($this->customer_id, new CustomerResource($this->customer)),
+ 'channel' => $this->when($this->channel_id, new ChannelResource($this->channel)),
+ 'items' => CartItem::collection($this->items),
+ 'selected_shipping_rate' => new CartShippingRate($this->selected_shipping_rate),
+ 'payment' => new CartPayment($this->payment),
+ 'billing_address' => new CartAddress($this->billing_address),
+ 'shipping_address' => new CartAddress($this->shipping_address),
+ 'created_at' => $this->created_at,
+ 'updated_at' => $this->updated_at,
+ ];
+ }
+}
\ No newline at end of file
diff --git a/packages/Webkul/API/Http/Resources/Checkout/CartAddress.php b/packages/Webkul/API/Http/Resources/Checkout/CartAddress.php
new file mode 100644
index 000000000..1bed8697c
--- /dev/null
+++ b/packages/Webkul/API/Http/Resources/Checkout/CartAddress.php
@@ -0,0 +1,34 @@
+ $this->id,
+ 'first_name' => $this->first_name,
+ 'last_name' => $this->last_name,
+ 'name' => $this->name,
+ 'email' => $this->email,
+ 'address1' => explode(PHP_EOL, $this->address1),
+ 'country' => $this->country,
+ 'country_name' => core()->country_name($this->country),
+ 'state' => $this->state,
+ 'city' => $this->city,
+ 'postcode' => $this->postcode,
+ 'phone' => $this->phone,
+ 'created_at' => $this->created_at,
+ 'updated_at' => $this->updated_at,
+ ];
+ }
+}
\ No newline at end of file
diff --git a/packages/Webkul/API/Http/Resources/Checkout/CartItem.php b/packages/Webkul/API/Http/Resources/Checkout/CartItem.php
new file mode 100644
index 000000000..37c36684e
--- /dev/null
+++ b/packages/Webkul/API/Http/Resources/Checkout/CartItem.php
@@ -0,0 +1,57 @@
+ $this->id,
+ 'quantity' => $this->quantity,
+ 'sku' => $this->sku,
+ 'type' => $this->type,
+ 'name' => $this->name,
+ 'coupon_code' => $this->coupon_code,
+ 'weight' => $this->weight,
+ 'total_weight' => $this->total_weight,
+ 'base_total_weight' => $this->base_total_weight,
+ 'price' => $this->price,
+ 'formated_price' => core()->formatPrice($this->price, $this->cart->cart_currency_code),
+ 'base_price' => $this->base_price,
+ 'formated_base_price' => core()->formatBasePrice($this->base_price),
+ 'custom_price' => $this->custom_price,
+ 'formated_custom_price' => core()->formatPrice($this->custom_price, $this->cart->cart_currency_code),
+ 'total' => $this->total,
+ 'formated_total' => core()->formatPrice($this->total, $this->cart->cart_currency_code),
+ 'base_total' => $this->base_total,
+ 'formated_base_total' => core()->formatBasePrice($this->base_total),
+ 'tax_percent' => $this->tax_percent,
+ 'tax_amount' => $this->tax_amount,
+ 'formated_tax_amount' => core()->formatPrice($this->tax_amount, $this->cart->cart_currency_code),
+ 'base_tax_amount' => $this->base_tax_amount,
+ 'formated_base_tax_amount' => core()->formatBasePrice($this->base_tax_amount),
+ 'discount_percent' => $this->discount_percent,
+ 'discount_amount' => $this->discount_amount,
+ 'formated_discount_amount' => core()->formatPrice($this->discount_amount, $this->cart->cart_currency_code),
+ 'base_discount_amount' => $this->base_discount_amount,
+ 'formated_base_discount_amount' => core()->formatBasePrice($this->base_discount_amount),
+ 'additional' => is_array($this->resource->additional)
+ ? $this->resource->additional
+ : json_decode($this->resource->additional, true),
+ 'child' => new self($this->child),
+ 'product' => $this->when($this->product_id, new ProductResource($this->product)),
+ 'created_at' => $this->created_at,
+ 'updated_at' => $this->updated_at,
+ ];
+ }
+}
\ No newline at end of file
diff --git a/packages/Webkul/API/Http/Resources/Checkout/CartPayment.php b/packages/Webkul/API/Http/Resources/Checkout/CartPayment.php
new file mode 100644
index 000000000..8ab0c28ac
--- /dev/null
+++ b/packages/Webkul/API/Http/Resources/Checkout/CartPayment.php
@@ -0,0 +1,25 @@
+ $this->id,
+ 'method' => $this->method,
+ 'method_title' => core()->getConfigData('sales.paymentmethods.' . $this->method . '.title'),
+ 'created_at' => $this->created_at,
+ 'updated_at' => $this->updated_at
+ ];
+ }
+}
\ No newline at end of file
diff --git a/packages/Webkul/API/Http/Resources/Checkout/CartShippingRate.php b/packages/Webkul/API/Http/Resources/Checkout/CartShippingRate.php
new file mode 100644
index 000000000..370697be5
--- /dev/null
+++ b/packages/Webkul/API/Http/Resources/Checkout/CartShippingRate.php
@@ -0,0 +1,35 @@
+ $this->id,
+ 'carrier' => $this->carrier,
+ 'carrier_title' => $this->carrier_title,
+ 'method' => $this->method,
+ 'method_title' => $this->method_title,
+ 'method_description' => $this->method_description,
+ 'price' => $this->price,
+ 'formated_price' => core()->formatPrice($this->price, $cart->cart_currency_code),
+ 'base_price' => $this->base_price,
+ 'formated_base_price' => core()->formatBasePrice($this->base_price),
+ 'created_at' => $this->created_at,
+ 'updated_at' => $this->updated_at
+ ];
+ }
+}
\ No newline at end of file
diff --git a/packages/Webkul/API/Http/Resources/Core/Channel.php b/packages/Webkul/API/Http/Resources/Core/Channel.php
index e80393075..e85085ce0 100644
--- a/packages/Webkul/API/Http/Resources/Core/Channel.php
+++ b/packages/Webkul/API/Http/Resources/Core/Channel.php
@@ -33,6 +33,7 @@ class Channel extends JsonResource
'favicon_url' => $this->favicon_url,
'default_locale' => $this->when($this->default_locale_id, new LocaleResource($this->default_locale)),
'base_currency' => $this->when($this->default_currency_id, new CurrencyResource($this->default_currency)),
+ 'root_category_id' => $this->root_category_id,
'root_category' => $this->when($this->root_category_id, new CategoryResource($this->root_category)),
'created_at' => $this->created_at,
'updated_at' => $this->updated_at,
diff --git a/packages/Webkul/API/Http/Resources/Core/Country.php b/packages/Webkul/API/Http/Resources/Core/Country.php
new file mode 100644
index 000000000..46f13f0c1
--- /dev/null
+++ b/packages/Webkul/API/Http/Resources/Core/Country.php
@@ -0,0 +1,23 @@
+ $this->id,
+ 'code' => $this->code,
+ 'name' => $this->name
+ ];
+ }
+}
\ No newline at end of file
diff --git a/packages/Webkul/API/Http/Resources/Customer/CustomerAddress.php b/packages/Webkul/API/Http/Resources/Customer/CustomerAddress.php
index 40daa2301..3b792e195 100644
--- a/packages/Webkul/API/Http/Resources/Customer/CustomerAddress.php
+++ b/packages/Webkul/API/Http/Resources/Customer/CustomerAddress.php
@@ -16,9 +16,9 @@ class CustomerAddress extends JsonResource
{
return [
'id' => $this->id,
- 'address1' => $this->address1,
- 'address2' => $this->address2,
+ 'address1' => explode(PHP_EOL, $this->address1),
'country' => $this->country,
+ 'country_name' => core()->country_name($this->country),
'state' => $this->state,
'city' => $this->city,
'postcode' => $this->postcode,
diff --git a/packages/Webkul/API/Http/Resources/Sales/Invoice.php b/packages/Webkul/API/Http/Resources/Sales/Invoice.php
index 10cdad74c..239056f25 100644
--- a/packages/Webkul/API/Http/Resources/Sales/Invoice.php
+++ b/packages/Webkul/API/Http/Resources/Sales/Invoice.php
@@ -23,18 +23,29 @@ class Invoice extends JsonResource
'channel_currency_code' => $this->channel_currency_code,
'order_currency_code' => $this->order_currency_code,
'sub_total' => $this->sub_total,
+ 'formated_sub_total' => core()->formatPrice($this->sub_total, $this->order_currency_code),
'base_sub_total' => $this->base_sub_total,
+ 'formated_base_sub_total' => core()->formatBasePrice($this->base_sub_total),
'grand_total' => $this->grand_total,
+ 'formated_grand_total' => core()->formatPrice($this->grand_total, $this->order_currency_code),
'base_grand_total' => $this->base_grand_total,
+ 'formated_base_grand_total' => core()->formatBasePrice($this->base_grand_total),
'shipping_amount' => $this->shipping_amount,
+ 'formated_shipping_amount' => core()->formatPrice($this->shipping_amount, $this->order_currency_code),
'base_shipping_amount' => $this->base_shipping_amount,
+ 'formated_base_shipping_amount' => core()->formatBasePrice($this->base_shipping_amount),
'tax_amount' => $this->tax_amount,
+ 'formated_tax_amount' => core()->formatPrice($this->tax_amount, $this->order_currency_code),
'base_tax_amount' => $this->base_tax_amount,
+ 'formated_base_tax_amount' => core()->formatBasePrice($this->base_tax_amount),
'discount_amount' => $this->discount_amount,
+ 'formated_discount_amount' => core()->formatPrice($this->discount_amount, $this->order_currency_code),
'base_discount_amount' => $this->base_discount_amount,
+ 'formated_base_discount_amount' => core()->formatBasePrice($this->base_discount_amount),
'order_address' => new OrderAddress($this->address),
'transaction_id' => $this->transaction_id,
'items' => InvoiceItem::collection($this->items),
+ 'created_at' => $this->created_at
];
}
}
\ No newline at end of file
diff --git a/packages/Webkul/API/Http/Resources/Sales/InvoiceItem.php b/packages/Webkul/API/Http/Resources/Sales/InvoiceItem.php
index 5c134645a..611226cef 100644
--- a/packages/Webkul/API/Http/Resources/Sales/InvoiceItem.php
+++ b/packages/Webkul/API/Http/Resources/Sales/InvoiceItem.php
@@ -17,16 +17,27 @@ class InvoiceItem extends JsonResource
return [
'id' => $this->id,
'name' => $this->name,
+ // 'product' => $this->when($this->product, new ProductResource($this->product)),
'description' => $this->description,
'sku' => $this->sku,
'description' => $this->description,
'qty' => $this->qty,
'price' => $this->price,
+ 'formated_price' => core()->formatPrice($this->price, $this->invoice->order_currency_code),
'base_price' => $this->base_price,
+ 'formated_base_price' => core()->formatBasePrice($this->base_price),
'total' => $this->total,
+ 'formated_total' => core()->formatPrice($this->total, $this->invoice->order_currency_code),
'base_total' => $this->base_total,
+ 'formated_base_total' => core()->formatBasePrice($this->base_total),
'tax_amount' => $this->tax_amount,
+ 'formated_tax_amount' => core()->formatPrice($this->tax_amount, $this->invoice->order_currency_code),
'base_tax_amount' => $this->base_tax_amount,
+ 'formated_base_tax_amount' => core()->formatBasePrice($this->base_tax_amount),
+ 'grand_total' => $this->total + $this->tax_amount,
+ 'formated_grand_total' => core()->formatPrice($this->total + $this->tax_amount, $this->invoice->order_currency_code),
+ 'base_grand_total' => $this->base_total + $this->base_tax_amount,
+ 'formated_base_grand_total' => core()->formatBasePrice($this->base_total + $this->base_tax_amount),
'additional' => is_array($this->resource->additional)
? $this->resource->additional
: json_decode($this->resource->additional, true),
diff --git a/packages/Webkul/API/Http/Resources/Sales/Order.php b/packages/Webkul/API/Http/Resources/Sales/Order.php
index 59d7dff63..5f59e561c 100644
--- a/packages/Webkul/API/Http/Resources/Sales/Order.php
+++ b/packages/Webkul/API/Http/Resources/Sales/Order.php
@@ -19,6 +19,7 @@ class Order extends JsonResource
return [
'id' => $this->id,
'status' => $this->status,
+ 'status_label' => $this->status_label,
'channel_name' => $this->channel_name,
'is_guest' => $this->is_guest,
'customer_email' => $this->customer_email,
@@ -26,6 +27,7 @@ class Order extends JsonResource
'customer_last_name' => $this->customer_last_name,
'shipping_method' => $this->shipping_method,
'shipping_title' => $this->shipping_title,
+ 'payment_title' => core()->getConfigData('sales.paymentmethods.' . $this->payment->method . '.title'),
'shipping_description' => $this->shipping_description,
'coupon_code' => $this->coupon_code,
'is_gift' => $this->is_gift,
@@ -35,37 +37,68 @@ class Order extends JsonResource
'channel_currency_code' => $this->channel_currency_code,
'order_currency_code' => $this->order_currency_code,
'grand_total' => $this->grand_total,
+ 'formated_grand_total' => core()->formatPrice($this->grand_total, $this->order_currency_code),
'base_grand_total' => $this->base_grand_total,
+ 'formated_base_grand_total' => core()->formatBasePrice($this->base_grand_total),
'grand_total_invoiced' => $this->grand_total_invoiced,
+ 'formated_grand_total_invoiced' => core()->formatPrice($this->grand_total_invoiced, $this->order_currency_code),
'base_grand_total_invoiced' => $this->base_grand_total_invoiced,
+ 'formated_base_grand_total_invoiced' => core()->formatBasePrice($this->base_grand_total_invoiced),
'grand_total_refunded' => $this->grand_total_refunded,
+ 'formated_grand_total_refunded' => core()->formatPrice($this->grand_total_refunded, $this->order_currency_code),
'base_grand_total_refunded' => $this->base_grand_total_refunded,
+ 'formated_base_grand_total_refunded' => core()->formatBasePrice($this->base_grand_total_refunded),
'sub_total' => $this->sub_total,
+ 'formated_sub_total' => core()->formatPrice($this->sub_total, $this->order_currency_code),
'base_sub_total' => $this->base_sub_total,
+ 'formated_base_sub_total' => core()->formatBasePrice($this->base_sub_total),
'sub_total_invoiced' => $this->sub_total_invoiced,
+ 'formated_sub_total_invoiced' => core()->formatPrice($this->sub_total_invoiced, $this->order_currency_code),
'base_sub_total_invoiced' => $this->base_sub_total_invoiced,
+ 'formated_base_sub_total_invoiced' => core()->formatBasePrice($this->base_sub_total_invoiced),
'sub_total_refunded' => $this->sub_total_refunded,
+ 'formated_sub_total_refunded' => core()->formatPrice($this->sub_total_refunded, $this->order_currency_code),
'discount_percent' => $this->discount_percent,
'discount_amount' => $this->discount_amount,
+ 'formated_discount_amount' => core()->formatPrice($this->discount_amount, $this->order_currency_code),
'base_discount_amount' => $this->base_discount_amount,
+ 'formated_base_discount_amount' => core()->formatBasePrice($this->base_discount_amount),
'discount_invoiced' => $this->discount_invoiced,
+ 'formated_discount_invoiced' => core()->formatPrice($this->discount_invoiced, $this->order_currency_code),
'base_discount_invoiced' => $this->base_discount_invoiced,
+ 'formated_base_discount_invoiced' => core()->formatBasePrice($this->base_discount_invoiced),
'discount_refunded' => $this->discount_refunded,
+ 'formated_discount_refunded' => core()->formatPrice($this->discount_refunded, $this->order_currency_code),
'base_discount_refunded' => $this->base_discount_refunded,
+ 'formated_base_discount_refunded' => core()->formatBasePrice($this->base_discount_refunded),
'tax_amount' => $this->tax_amount,
+ 'formated_tax_amount' => core()->formatPrice($this->tax_amount, $this->order_currency_code),
'base_tax_amount' => $this->base_tax_amount,
+ 'formated_base_tax_amount' => core()->formatBasePrice($this->base_tax_amount),
'tax_amount_invoiced' => $this->tax_amount_invoiced,
+ 'formated_tax_amount_invoiced' => core()->formatPrice($this->tax_amount_invoiced, $this->order_currency_code),
'base_tax_amount_invoiced' => $this->base_tax_amount_invoiced,
+ 'formated_base_tax_amount_invoiced' => core()->formatBasePrice($this->base_tax_amount_invoiced),
'tax_amount_refunded' => $this->tax_amount_refunded,
+ 'formated_tax_amount_refunded' => core()->formatPrice($this->tax_amount_refunded, $this->order_currency_code),
'base_tax_amount_refunded' => $this->base_tax_amount_refunded,
+ 'formated_base_tax_amount_refunded' => core()->formatBasePrice($this->base_tax_amount_refunded),
'shipping_amount' => $this->shipping_amount,
+ 'formated_shipping_amount' => core()->formatPrice($this->shipping_amount, $this->order_currency_code),
'base_shipping_amount' => $this->base_shipping_amount,
+ 'formated_base_shipping_amount' => core()->formatBasePrice($this->base_shipping_amount),
'shipping_invoiced' => $this->shipping_invoiced,
+ 'formated_shipping_invoiced' => core()->formatPrice($this->shipping_invoiced, $this->order_currency_code),
'base_shipping_invoiced' => $this->base_shipping_invoiced,
+ 'formated_base_shipping_invoiced' => core()->formatBasePrice($this->base_shipping_invoiced),
'shipping_refunded' => $this->shipping_refunded,
+ 'formated_shipping_refunded' => core()->formatPrice($this->shipping_refunded, $this->order_currency_code),
'base_shipping_refunded' => $this->base_shipping_refunded,
+ 'formated_base_shipping_refunded' => core()->formatBasePrice($this->base_shipping_refunded),
'customer' => $this->when($this->customer_id, new CustomerResource($this->customer)),
'channel' => $this->when($this->channel_id, new ChannelResource($this->channel)),
+ 'shipping_address' => new OrderAddress($this->shipping_address),
+ 'billing_address' => new OrderAddress($this->billing_address),
'updated_at' => $this->updated_at,
'items' => OrderItem::collection($this->items),
'invoices' => Invoice::collection($this->invoices),
diff --git a/packages/Webkul/API/Http/Resources/Sales/OrderAddress.php b/packages/Webkul/API/Http/Resources/Sales/OrderAddress.php
index a10733aa6..bb18a5a6a 100644
--- a/packages/Webkul/API/Http/Resources/Sales/OrderAddress.php
+++ b/packages/Webkul/API/Http/Resources/Sales/OrderAddress.php
@@ -19,9 +19,9 @@ class OrderAddress extends JsonResource
'email' => $this->email,
'first_name' => $this->first_name,
'last_name' => $this->last_name,
- 'address1' => $this->address1,
- 'address2' => $this->address2,
+ 'address1' => explode(PHP_EOL, $this->address1),
'country' => $this->country,
+ 'country_name' => core()->country_name($this->country),
'state' => $this->state,
'city' => $this->city,
'postcode' => $this->postcode,
diff --git a/packages/Webkul/API/Http/Resources/Sales/OrderItem.php b/packages/Webkul/API/Http/Resources/Sales/OrderItem.php
index 9401ca817..cbfb19846 100644
--- a/packages/Webkul/API/Http/Resources/Sales/OrderItem.php
+++ b/packages/Webkul/API/Http/Resources/Sales/OrderItem.php
@@ -3,6 +3,7 @@
namespace Webkul\API\Http\Resources\Sales;
use Illuminate\Http\Resources\Json\JsonResource;
+use Webkul\API\Http\Resources\Catalog\Product as ProductResource;
class OrderItem extends JsonResource
{
@@ -19,35 +20,61 @@ class OrderItem extends JsonResource
'sku' => $this->sku,
'type' => $this->type,
'name' => $this->name,
+ 'product' => $this->when($this->product, new ProductResource($this->product)),
'coupon_code' => $this->coupon_code,
'weight' => $this->weight,
'total_weight' => $this->total_weight,
'qty_ordered' => $this->qty_ordered,
'qty_canceled' => $this->qty_canceled,
+ 'qty_invoiced' => $this->qty_invoiced,
'qty_shipped' => $this->qty_shipped,
'qty_refunded' => $this->qty_refunded,
'price' => $this->price,
+ 'formated_price' => core()->formatPrice($this->price, $this->order->order_currency_code),
'base_price' => $this->base_price,
+ 'formated_base_price' => core()->formatBasePrice($this->base_price),
'total' => $this->total,
+ 'formated_total' => core()->formatPrice($this->total, $this->order->order_currency_code),
'base_total' => $this->base_total,
+ 'formated_base_total' => core()->formatBasePrice($this->base_total),
'total_invoiced' => $this->total_invoiced,
+ 'formated_total_invoiced' => core()->formatPrice($this->total_invoiced, $this->order->order_currency_code),
'base_total_invoiced' => $this->base_total_invoiced,
+ 'formated_base_total_invoiced' => core()->formatBasePrice($this->base_total_invoiced),
'amount_refunded' => $this->amount_refunded,
+ 'formated_amount_refunded' => core()->formatPrice($this->amount_refunded, $this->order->order_currency_code),
'base_amount_refunded' => $this->base_amount_refunded,
+ 'formated_base_amount_refunded' => core()->formatBasePrice($this->base_amount_refunded),
'discount_percent' => $this->discount_percent,
'discount_amount' => $this->discount_amount,
+ 'formated_discount_amount' => core()->formatPrice($this->discount_amount, $this->order->order_currency_code),
'base_discount_amount' => $this->base_discount_amount,
+ 'formated_base_discount_amount' => core()->formatBasePrice($this->base_discount_amount),
'discount_invoiced' => $this->discount_invoiced,
+ 'formated_discount_invoiced' => core()->formatPrice($this->discount_invoiced, $this->order->order_currency_code),
'base_discount_invoiced' => $this->base_discount_invoiced,
+ 'formated_base_discount_invoiced' => core()->formatBasePrice($this->base_discount_invoiced),
'discount_refunded' => $this->discount_refunded,
+ 'formated_discount_refunded' => core()->formatPrice($this->discount_refunded, $this->order->order_currency_code),
'base_discount_refunded' => $this->base_discount_refunded,
+ 'formated_base_discount_refunded' => core()->formatBasePrice($this->base_discount_refunded),
'tax_percent' => $this->tax_percent,
'tax_amount' => $this->tax_amount,
+ 'formated_tax_amount' => core()->formatPrice($this->tax_amount, $this->order->order_currency_code),
'base_tax_amount' => $this->base_tax_amount,
+ 'formated_base_tax_amount' => core()->formatBasePrice($this->base_tax_amount),
'tax_amount_invoiced' => $this->tax_amount_invoiced,
+ 'formated_tax_amount_invoiced' => core()->formatPrice($this->tax_amount_invoiced, $this->order->order_currency_code),
'base_tax_amount_invoiced' => $this->base_tax_amount_invoiced,
+ 'formated_base_tax_amount_invoiced' => core()->formatBasePrice($this->base_tax_amount_invoiced),
'tax_amount_refunded' => $this->tax_amount_refunded,
+ 'formated_tax_amount_refunded' => core()->formatPrice($this->tax_amount_refunded, $this->order->order_currency_code),
'base_tax_amount_refunded' => $this->base_tax_amount_refunded,
+ 'formated_base_tax_amount_refunded' => core()->formatBasePrice($this->base_tax_amount_refunded),
+ 'grant_total' => $this->total + $this->tax_amount,
+ 'formated_grant_total' => core()->formatPrice($this->total + $this->tax_amount, $this->order->order_currency_code),
+ 'base_grant_total' => $this->base_total + $this->base_tax_amount,
+ 'formated_base_grant_total' => core()->formatPrice($this->base_total + $this->base_tax_amount, $this->order->order_currency_code),
'additional' => is_array($this->resource->additional)
? $this->resource->additional
: json_decode($this->resource->additional, true),
diff --git a/packages/Webkul/API/Http/Resources/Sales/ShipmentItem.php b/packages/Webkul/API/Http/Resources/Sales/ShipmentItem.php
index 7c4436867..678af6d6f 100644
--- a/packages/Webkul/API/Http/Resources/Sales/ShipmentItem.php
+++ b/packages/Webkul/API/Http/Resources/Sales/ShipmentItem.php
@@ -22,9 +22,13 @@ class ShipmentItem extends JsonResource
'qty' => $this->qty,
'weight' => $this->weight,
'price' => $this->price,
+ 'formated_price' => core()->formatPrice($this->price, $this->shipment->order->order_currency_code),
'base_price' => $this->base_price,
+ 'formated_base_price' => core()->formatBasePrice($this->base_price),
'total' => $this->total,
+ 'formated_total' => core()->formatPrice($this->total, $this->shipment->order->order_currency_code),
'base_total' => $this->base_total,
+ 'formated_base_total' => core()->formatBasePrice($this->base_total),
'additional' => is_array($this->resource->additional)
? $this->resource->additional
: json_decode($this->resource->additional, true)
diff --git a/packages/Webkul/API/Http/routes.php b/packages/Webkul/API/Http/routes.php
index bcb588c5b..a0ab07548 100755
--- a/packages/Webkul/API/Http/routes.php
+++ b/packages/Webkul/API/Http/routes.php
@@ -2,7 +2,7 @@
Route::group(['prefix' => 'api'], function ($router) {
- Route::group(['namespace' => 'Webkul\API\Http\Controllers\Shop', 'middleware' => ['locale', 'currency']], function ($router) {
+ Route::group(['namespace' => 'Webkul\API\Http\Controllers\Shop', 'middleware' => ['locale', 'theme', 'currency']], function ($router) {
//Currency and Locale switcher
Route::get('switch-currency', 'CoreController@switchCurrency');
@@ -15,7 +15,7 @@ Route::group(['prefix' => 'api'], function ($router) {
'resource' => 'Webkul\API\Http\Resources\Catalog\Category'
]);
- Route::get('descendants-categories', 'CategoryController@index');
+ Route::get('descendant-categories', 'CategoryController@index');
Route::get('categories/{id}', 'ResourceController@get')->defaults('_config', [
'repository' => 'Webkul\Category\Repositories\CategoryRepository',
@@ -52,6 +52,10 @@ Route::group(['prefix' => 'api'], function ($router) {
Route::get('products/{id}', 'ProductController@get');
+ Route::get('product-additional-information/{id}', 'ProductController@additionalInformation');
+
+ Route::get('product-configurable-config/{id}', 'ProductController@configurableConfig');
+
//Product Review routes
Route::get('reviews', 'ResourceController@index')->defaults('_config', [
@@ -64,6 +68,8 @@ Route::group(['prefix' => 'api'], function ($router) {
'resource' => 'Webkul\API\Http\Resources\Catalog\ProductReview'
]);
+ Route::post('reviews/{id}/create', 'ReviewController@store');
+
//Channel routes
Route::get('channels', 'ResourceController@index')->defaults('_config', [
@@ -89,6 +95,20 @@ Route::group(['prefix' => 'api'], function ($router) {
]);
+ //Country routes
+ Route::get('countries', 'ResourceController@index')->defaults('_config', [
+ 'repository' => 'Webkul\Core\Repositories\CountryRepository',
+ 'resource' => 'Webkul\API\Http\Resources\Core\Country'
+ ]);
+
+ Route::get('countries/{id}', 'ResourceController@get')->defaults('_config', [
+ 'repository' => 'Webkul\Core\Repositories\CountryRepository',
+ 'resource' => 'Webkul\API\Http\Resources\Core\Country'
+ ]);
+
+ Route::get('country-states', 'CoreController@getCountryStateGroup');
+
+
//Slider routes
Route::get('sliders', 'ResourceController@index')->defaults('_config', [
'repository' => 'Webkul\Core\Repositories\SliderRepository',
@@ -112,71 +132,138 @@ Route::group(['prefix' => 'api'], function ($router) {
'resource' => 'Webkul\API\Http\Resources\Core\Currency'
]);
+ Route::get('config', 'CoreController@getConfig');
+
//Customer routes
- Route::get('customers', 'ResourceController@index')->defaults('_config', [
- 'repository' => 'Webkul\Customer\Repositories\CustomerRepository',
- 'resource' => 'Webkul\API\Http\Resources\Customer\Customer'
- ]);
+ Route::post('customer/login', 'SessionController@create');
+
+ Route::post('customer/forgot-password', 'ForgotPasswordController@store');
+
+ Route::get('customer/logout', 'SessionController@destroy');
+
+ Route::get('customer/get', 'SessionController@get');
+
+ Route::put('customer/profile', 'SessionController@update');
+
+ Route::post('customer/register', 'CustomerController@create');
Route::get('customers/{id}', 'ResourceController@get')->defaults('_config', [
'repository' => 'Webkul\Customer\Repositories\CustomerRepository',
- 'resource' => 'Webkul\API\Http\Resources\Customer\Customer'
+ 'resource' => 'Webkul\API\Http\Resources\Customer\Customer',
+ 'authorization_required' => true
]);
//Customer Address routes
Route::get('addresses', 'ResourceController@index')->defaults('_config', [
'repository' => 'Webkul\Customer\Repositories\CustomerAddressRepository',
- 'resource' => 'Webkul\API\Http\Resources\Customer\CustomerAddress'
+ 'resource' => 'Webkul\API\Http\Resources\Customer\CustomerAddress',
+ 'authorization_required' => true
]);
Route::get('addresses/{id}', 'ResourceController@get')->defaults('_config', [
'repository' => 'Webkul\Customer\Repositories\CustomerAddressRepository',
- 'resource' => 'Webkul\API\Http\Resources\Customer\CustomerAddress'
+ 'resource' => 'Webkul\API\Http\Resources\Customer\CustomerAddress',
+ 'authorization_required' => true
+ ]);
+
+ Route::delete('addresses/{id}', 'ResourceController@destroy')->defaults('_config', [
+ 'repository' => 'Webkul\Customer\Repositories\CustomerAddressRepository',
+ 'resource' => 'Webkul\API\Http\Resources\Customer\CustomerAddress',
+ 'authorization_required' => true
+ ]);
+
+ Route::put('addresses/{id}', 'AddressController@update')->defaults('_config', [
+ 'authorization_required' => true
+ ]);
+
+ Route::post('addresses/create', 'AddressController@store')->defaults('_config', [
+ 'authorization_required' => true
]);
//Order routes
Route::get('orders', 'ResourceController@index')->defaults('_config', [
'repository' => 'Webkul\Sales\Repositories\OrderRepository',
- 'resource' => 'Webkul\API\Http\Resources\Sales\Order'
+ 'resource' => 'Webkul\API\Http\Resources\Sales\Order',
+ 'authorization_required' => true
]);
Route::get('orders/{id}', 'ResourceController@get')->defaults('_config', [
'repository' => 'Webkul\Sales\Repositories\OrderRepository',
- 'resource' => 'Webkul\API\Http\Resources\Sales\Order'
+ 'resource' => 'Webkul\API\Http\Resources\Sales\Order',
+ 'authorization_required' => true
]);
//Invoice routes
Route::get('invoices', 'ResourceController@index')->defaults('_config', [
'repository' => 'Webkul\Sales\Repositories\InvoiceRepository',
- 'resource' => 'Webkul\API\Http\Resources\Sales\Invoice'
+ 'resource' => 'Webkul\API\Http\Resources\Sales\Invoice',
+ 'authorization_required' => true
]);
Route::get('invoices/{id}', 'ResourceController@get')->defaults('_config', [
'repository' => 'Webkul\Sales\Repositories\InvoiceRepository',
- 'resource' => 'Webkul\API\Http\Resources\Sales\Invoice'
+ 'resource' => 'Webkul\API\Http\Resources\Sales\Invoice',
+ 'authorization_required' => true
]);
//Invoice routes
Route::get('shipments', 'ResourceController@index')->defaults('_config', [
'repository' => 'Webkul\Sales\Repositories\ShipmentRepository',
- 'resource' => 'Webkul\API\Http\Resources\Sales\Shipment'
+ 'resource' => 'Webkul\API\Http\Resources\Sales\Shipment',
+ 'authorization_required' => true
]);
Route::get('shipments/{id}', 'ResourceController@get')->defaults('_config', [
'repository' => 'Webkul\Sales\Repositories\ShipmentRepository',
- 'resource' => 'Webkul\API\Http\Resources\Sales\Shipment'
+ 'resource' => 'Webkul\API\Http\Resources\Sales\Shipment',
+ 'authorization_required' => true
]);
//Wishlist routes
Route::get('wishlist', 'ResourceController@index')->defaults('_config', [
'repository' => 'Webkul\Customer\Repositories\WishlistRepository',
- 'resource' => 'Webkul\API\Http\Resources\Customer\Wishlist'
+ 'resource' => 'Webkul\API\Http\Resources\Customer\Wishlist',
+ 'authorization_required' => true
]);
+
+ Route::delete('wishlist/{id}', 'ResourceController@destroy')->defaults('_config', [
+ 'repository' => 'Webkul\Customer\Repositories\WishlistRepository',
+ 'resource' => 'Webkul\API\Http\Resources\Customer\Wishlist',
+ 'authorization_required' => true
+ ]);
+
+ Route::get('move-to-cart/{id}', 'WishlistController@moveToCart');
+
+ Route::get('wishlist/add/{id}', 'WishlistController@create');
+
+
+ //Checkout routes
+ Route::group(['prefix' => 'checkout'], function ($router) {
+ Route::post('cart/add/{id}', 'CartController@store');
+
+ Route::get('cart', 'CartController@get');
+
+ Route::get('cart/empty', 'CartController@destroy');
+
+ Route::put('cart/update', 'CartController@update');
+
+ Route::get('cart/remove-item/{id}', 'CartController@destroyItem');
+
+ Route::get('cart/move-to-wishlist/{id}', 'CartController@moveToWishlist');
+
+ Route::post('save-address', 'CheckoutController@saveAddress');
+
+ Route::post('save-shipping', 'CheckoutController@saveShipping');
+
+ Route::post('save-payment', 'CheckoutController@savePayment');
+
+ Route::post('save-order', 'CheckoutController@saveOrder');
+ });
});
});
\ No newline at end of file
diff --git a/packages/Webkul/API/Providers/APIServiceProvider.php b/packages/Webkul/API/Providers/APIServiceProvider.php
index 1d166f21a..a4644fb37 100755
--- a/packages/Webkul/API/Providers/APIServiceProvider.php
+++ b/packages/Webkul/API/Providers/APIServiceProvider.php
@@ -3,6 +3,8 @@
namespace Webkul\API\Providers;
use Illuminate\Support\ServiceProvider;
+use Illuminate\Routing\Router;
+use Webkul\API\Http\Middleware\JwtMiddleware;
class APIServiceProvider extends ServiceProvider
{
@@ -11,7 +13,7 @@ class APIServiceProvider extends ServiceProvider
*
* @return void
*/
- public function boot()
+ public function boot(Router $router)
{
$this->loadRoutesFrom(__DIR__.'/../Http/routes.php');
}
diff --git a/packages/Webkul/Admin/composer.json b/packages/Webkul/Admin/composer.json
index 67a87fa43..dd550b7b6 100755
--- a/packages/Webkul/Admin/composer.json
+++ b/packages/Webkul/Admin/composer.json
@@ -26,4 +26,4 @@
}
},
"minimum-stability": "dev"
-}
+}
\ No newline at end of file
diff --git a/packages/Webkul/Admin/publishable/assets/css/admin.css b/packages/Webkul/Admin/publishable/assets/css/admin.css
index 613fb7a91..44882449d 100755
--- a/packages/Webkul/Admin/publishable/assets/css/admin.css
+++ b/packages/Webkul/Admin/publishable/assets/css/admin.css
@@ -1 +1 @@
-@import url(https://fonts.googleapis.com/css?family=Montserrat:400,500);body{margin:0;color:#3a3a3a;font-family:Montserrat,sans-serif;font-size:14px;font-weight:500;position:static;min-height:100%;width:100%}::-webkit-scrollbar{width:12px}::-webkit-scrollbar-track{-webkit-box-shadow:inset 0 0 6px hsla(0,0%,100%,.3);border-radius:10px}::-webkit-scrollbar-thumb{border-radius:10px;-webkit-box-shadow:inset 0 0 6px rgba(0,0,0,.5)}.navbar-top{height:60px;background:#fff;font-size:0;-webkit-box-shadow:0 3px 6px 0 rgba(0,0,0,.05);box-shadow:0 3px 6px 0 rgba(0,0,0,.05);border-bottom:1px solid hsla(0,0%,64%,.2);position:fixed;left:0;right:0;z-index:5}.navbar-top .navbar-top-left{width:50%;height:60px;display:inline-block;vertical-align:middle}.navbar-top .navbar-top-left .brand-logo{padding:10px}.navbar-top .navbar-top-right{width:50%;height:60px;text-align:right;display:inline-block;vertical-align:middle}.navbar-top .navbar-top-right .profile-info{display:inline-block;vertical-align:middle;text-align:left;min-width:50px;padding:12px 0;margin:0 25px 0 30px;font-size:15px;cursor:pointer;position:relative}.navbar-top .navbar-top-right .profile-info .dropdown-list{top:63px}.navbar-top .navbar-top-right .profile-info .name{color:#000311;display:block;text-align:left}.navbar-top .navbar-top-right .profile-info .role{font-size:14px;color:#8e8e8e;display:block;text-align:left}.navbar-top .navbar-top-right .profile-info i.icon{margin-left:10px}.navbar-left{position:fixed;left:0;top:60px;width:90px;padding-top:20px;border-right:1px solid hsla(0,0%,64%,.2);height:auto;bottom:0;z-index:2}.navbar-left ul.menubar li.menu-item{padding:10px 5px;font-size:11px;text-align:center;text-transform:uppercase}.navbar-left ul.menubar li.menu-item a{color:#a2a2a2}.navbar-left ul.menubar li.menu-item.active a{color:#0041ff}.content-container{padding-left:90px;position:absolute;margin-top:60px;top:0;right:0;left:0;bottom:0;height:calc(100% - 60px);width:100%}.content-container .inner-section{height:100%}.content-container .aside-nav{width:280px;position:fixed;top:60px;bottom:0;border-right:1px solid hsla(0,0%,64%,.2);background:#f8f9fa;padding-top:10px;padding-bottom:10px;z-index:4}.content-container .aside-nav ul{overflow-y:auto;height:90%}.content-container .aside-nav a{padding:15px;display:block;color:#000311}.content-container .aside-nav .active a{background:#fff;border-top:1px solid hsla(0,0%,64%,.2);border-bottom:1px solid hsla(0,0%,64%,.2)}.content-container .aside-nav .active i{float:right}.content-container .content-wrapper{padding:25px;margin-left:305px}.content-container .content{margin-top:25px}.content-container .content.full-page{padding:25px}.content-container .content .page-header{display:inline-block;margin-bottom:20px;width:100%}.content-container .content .page-header .page-title{float:left}.content-container .content .page-header .page-title .back-link{float:left;margin-right:10px;width:24px;height:24px;cursor:pointer;margin-top:5px}.content-container .content .page-header .page-title h1{margin-bottom:0;vertical-align:middle;display:inline-block}.content-container .content .page-header .page-action{float:right}.content-container .content .page-header .page-action *{display:inline-block}.content-container .content .page-header .page-action a{margin-left:25px}.content-container .content .page-header .control-group{width:180px;display:inline-block;margin-bottom:0;margin-left:20px}.content-container .content .page-header .control{width:100%;margin:0}.content-container .content .page-content{width:100%;display:inline-block}.control-group label{width:70%}.control-group label .locale{float:right;color:#8e8e8e}.control-group .mce-tinymce{margin-top:10px;margin-bottom:5px}.dashboard .page-header{margin-bottom:0!important;padding-bottom:15px;border-bottom:1px solid hsla(0,0%,64%,.2)}.dashboard .page-content{margin-top:15px}.dashboard .card{height:445px;background:#fff;border:1px solid #e7e7e7;-webkit-box-shadow:0 5px 10px 2px rgba(0,0,0,.08);box-shadow:0 5px 10px 2px rgba(0,0,0,.08);border-radius:2px;padding:20px 0 0 20px}.dashboard .card .card-title{font-size:14px;color:#a2a2a2;letter-spacing:-.26px;text-transform:uppercase}.dashboard .card .card-info{width:100%;height:100%;display:inline-block}.dashboard .card .card-info.center{text-align:center}.dashboard .card .card-info ul li{border-bottom:1px solid hsla(0,0%,64%,.2);width:100%;display:inline-block;padding:10px 0;position:relative}.dashboard .card .card-info ul li .image{height:60px;width:60px;float:left;margin-right:15px}.dashboard .card .card-info ul li .image.product{background:#f2f2f2}.dashboard .card .card-info ul li .image img{width:100%}.dashboard .card .card-info ul li .description{margin-top:10px}.dashboard .card .card-info ul li .description .name{color:#0041ff}.dashboard .card .card-info ul li .description .info{color:#3a3a3a;margin-top:5px}.dashboard .card .card-info ul li .icon.angle-right-icon{position:absolute;right:30px;top:50%;margin-top:-8px}.dashboard .card .card-info ul li:last-child{border-bottom:0}.dashboard .card .card-info .no-result-found{margin-top:146px}.dashboard .card .card-info .no-result-found p{margin:0;color:#a2a2a2}.dashboard .dashboard-stats{display:grid;grid-template-columns:repeat(auto-fill,minmax(320px,1fr));grid-auto-rows:auto;grid-column-gap:30px;grid-row-gap:15px}.dashboard .dashboard-stats .dashboard-card{height:100px;background:#fff;border:1px solid #e7e7e7;-webkit-box-shadow:0 5px 10px 2px rgba(0,0,0,.08);box-shadow:0 5px 10px 2px rgba(0,0,0,.08);border-radius:5px;position:relative;padding:15px}.dashboard .dashboard-stats .dashboard-card .title{font-size:14px;color:#a2a2a2;text-transform:uppercase}.dashboard .dashboard-stats .dashboard-card .data{padding-top:3px;font-size:32px;color:#0041ff}.dashboard .dashboard-stats .dashboard-card .data .progress{font-size:14px;color:#8e8e8e;float:right;margin-top:9px}.dashboard .dashboard-stats .dashboard-card .data .progress .icon{vertical-align:middle}.dashboard .graph-stats{margin-top:30px;width:100%;display:inline-block}.dashboard .graph-stats .left-card-container{float:left;width:75%;padding-right:9px}.dashboard .graph-stats .right-card-container{float:left;width:25%;padding-left:21px}.dashboard .sale-stock{width:100%;display:inline-block;display:grid;grid-template-columns:repeat(auto-fill,minmax(435px,1fr));grid-auto-rows:auto;grid-column-gap:30px;grid-row-gap:15px;margin-top:30px}.sale-container .sale-section{font-size:16px}.sale-container .sale-section .secton-title{font-size:18px;color:#8e8e8e;padding:15px 0;border-bottom:1px solid hsla(0,0%,64%,.2)}.sale-container .sale-section .section-content{display:block;padding:20px 0}.sale-container .sale-section .section-content .row{display:block;padding:7px 0}.sale-container .sale-section .section-content .row .title{width:200px;color:#3a3a3a;letter-spacing:-.26px;display:inline-block}.sale-container .sale-section .section-content .row .value{color:#3a3a3a;letter-spacing:-.26px;display:inline-block}.sale-container .table .qty-row{display:block;margin-bottom:5px}.sale-container .table .qty-row:last-child{margin-bottom:0}.sale-container .table .radio{margin:0}.sale-container .sale-summary{margin-top:2%;height:130px;float:right}.sale-container .sale-summary tr td{padding:5px 8px}.sale-container .sale-summary tr.bold{font-weight:600;font-size:15px}.sale-container .sale-summary tr.border td{border-bottom:1px solid hsla(0,0%,64%,.2)}.stars{margin-top:5px}.stars .icon{width:16px;height:16px}.export-import{cursor:pointer}.export-import .export-icon,.export-import .import-icon{position:relative;top:10px}.export-import span{margin-left:2px}.configuration-image{position:relative;height:33px;width:33px;top:15px;border-radius:3px;margin-right:5px}.download{position:relative;height:24px!important;width:24px!important;top:12px;margin-right:10px}.aside-nav-toggle{height:48px;width:100%;padding-top:15px;border-top:1px solid hsla(0,0%,64%,.2)}.aside-nav-toggle .close-icon,.aside-nav-toggle .open-icon{position:absolute;cursor:pointer;left:45%}.aside-nav-toggle.open{display:none}.linked-product-search-result{-webkit-box-shadow:0 2px 4px 0 rgba(0,0,0,.16),0 0 9px 0 rgba(0,0,0,.16);box-shadow:0 2px 4px 0 rgba(0,0,0,.16),0 0 9px 0 rgba(0,0,0,.16);z-index:10;text-align:left;border-radius:3px;background-color:#fff;width:70%;max-height:200px;overflow-y:auto}.linked-product-search-result li{padding:10px;border-bottom:1px solid #e8e8e8;cursor:pointer}.rtl{direction:rtl}.rtl .navbar-top .navbar-top-right{text-align:left}.rtl .navbar-top .navbar-top-right .profile-info{margin:0 30px 0 25px}.rtl .navbar-top .navbar-top-right .profile-info i.icon{margin-left:0;margin-right:10px}.rtl .navbar-left{border-left:1px solid hsla(0,0%,64%,.2);border-right:none;left:calc(100% - 90px)}.rtl .content-container{padding-right:90px;padding-left:0}.rtl .content-container .content .page-header .page-title{float:right}.rtl .content-container .content .page-header .page-action{float:left}.rtl .content-container .content .page-header .page-action a{margin-left:0}.rtl .content-container .content .page-header .control-group{margin-right:20px;margin-left:0}.rtl .content-container .content .page-header .control-group.date:after{margin-top:6px;position:absolute;margin-right:-35px}.rtl .content-container .content .page-header .control-group.date:last-child{margin-left:0}.rtl .content-container .content-wrapper{padding:25px 305px 25px 25px;margin-left:0}.rtl .content-container .aside-nav .active i{float:left;-webkit-transform:rotate(180deg);transform:rotate(180deg)}.rtl .dashboard .dashboard-stats .dashboard-card .data span{float:left}.rtl .dashboard .card{padding:20px 20px 0 0}.rtl .dashboard .card .card-info ul li .image{float:right;margin-right:0;margin-left:15px}.rtl .dashboard .card .card-info ul li .icon.angle-right-icon{left:30px;right:auto;-webkit-transform:rotate(180deg);transform:rotate(180deg)}.rtl .dashboard .graph-stats .left-card-container{float:right;padding-right:0}.rtl .dashboard .graph-stats .right-card-container{float:right;padding-left:0;padding-right:30px}.rtl .sale-container .sale-summary{float:left}.rtl .grid-container .filter-row-one .search-filter{border:2px solid #c7c7c7;border-radius:2px}.rtl .grid-container .filter-row-one .search-filter .control{border:none;padding-right:10px}.rtl .grid-container .filter-row-one .search-filter .icon-wrapper{border:none;padding-top:2px;padding-right:5px;border-right:2px solid #c7c7c7;border-radius:0}.rtl .grid-container .filter-row-two .filter-tag .icon.cross-icon,.rtl .grid-container .filter-row-two .filter-tag .wrapper{margin-right:10px;margin-left:0}.rtl .grid-container .filter-row-one .dropdown-filters{right:unset;left:25px}.rtl .grid-container .filter-wrapper .filter-row-one .dropdown-filters .more-filters .dropdown-toggle .dropdown-header span{padding-right:5px}.rtl .grid-container .table tbody td.action a:first-child{margin-left:10px;margin-right:0}.rtl .table table{text-align:right}.rtl .table table .massaction-remove{margin-right:5px!important;margin-left:10px}.rtl .table table .btn.btn-primary{margin-right:10px!important}.rtl .dropdown-list.bottom-right{left:0;right:auto}.rtl .dropdown-list .dropdown-container{text-align:right}.rtl .accordian .accordian-header .icon{float:left}.rtl .tree-container .tree-item{padding-right:30px}.rtl .tree-container .tree-item .expand-icon,.rtl .tree-container .tree-item .folder-icon{margin-left:10px;margin-right:0}.rtl .tree-container>.tree-item{padding-right:0}.rtl .radio .radio-view{margin-left:5px}.rtl .image-wrapper .image-item{margin-right:0;margin-left:20px}.rtl .image-wrapper .image-item .remove-image{margin-right:0}.rtl .control-group label.required:before{content:"*";color:#fc6868;font-weight:700}.rtl .control-group label.required:after{content:none}.rtl .control-group label .locale{float:left}.rtl .control-group.date:after{margin-top:15px;position:absolute;margin-right:-35px}.rtl .pagination .page-item .icon{-webkit-transform:rotate(180deg);transform:rotate(180deg)}.pagination{margin-top:30px}
\ No newline at end of file
+@import url(https://fonts.googleapis.com/css?family=Montserrat:400,500);body{margin:0;color:#3a3a3a;font-family:Montserrat,sans-serif;font-size:14px;font-weight:500;position:static;min-height:100%;width:100%}::-webkit-scrollbar{width:12px}::-webkit-scrollbar-track{-webkit-box-shadow:inset 0 0 6px hsla(0,0%,100%,.3);border-radius:10px}::-webkit-scrollbar-thumb{border-radius:10px;-webkit-box-shadow:inset 0 0 6px rgba(0,0,0,.5)}.navbar-top{height:60px;background:#fff;font-size:0;-webkit-box-shadow:0 3px 6px 0 rgba(0,0,0,.05);box-shadow:0 3px 6px 0 rgba(0,0,0,.05);border-bottom:1px solid hsla(0,0%,64%,.2);position:fixed;left:0;right:0;z-index:5}.navbar-top .navbar-top-left{width:50%;height:60px;display:inline-block;vertical-align:middle}.navbar-top .navbar-top-left .brand-logo{padding:10px}.navbar-top .navbar-top-right{width:50%;height:60px;text-align:right;display:inline-block;vertical-align:middle}.navbar-top .navbar-top-right .profile-info{display:inline-block;vertical-align:middle;text-align:left;min-width:50px;padding:12px 0;margin:0 25px 0 30px;font-size:15px;cursor:pointer;position:relative}.navbar-top .navbar-top-right .profile-info .dropdown-list{top:63px}.navbar-top .navbar-top-right .profile-info .name{color:#000311;display:block;text-align:left}.navbar-top .navbar-top-right .profile-info .role{font-size:14px;color:#8e8e8e;display:block;text-align:left}.navbar-top .navbar-top-right .profile-info i.icon{margin-left:10px}.navbar-left{position:fixed;left:0;top:60px;width:90px;padding-top:20px;border-right:1px solid hsla(0,0%,64%,.2);height:auto;bottom:0;z-index:2}.navbar-left ul.menubar li.menu-item{padding:10px 5px;font-size:11px;text-align:center;text-transform:uppercase}.navbar-left ul.menubar li.menu-item a{color:#a2a2a2}.navbar-left ul.menubar li.menu-item.active a{color:#0041ff}.navbar-left ul.menubar li.menu-item span{display:block;margin:auto}.content-container{padding-left:90px;position:absolute;margin-top:60px;top:0;right:0;left:0;bottom:0;height:calc(100% - 60px);width:100%}.content-container .inner-section{height:100%}.content-container .aside-nav{width:280px;position:fixed;top:60px;bottom:0;border-right:1px solid hsla(0,0%,64%,.2);background:#f8f9fa;padding-top:10px;padding-bottom:10px;z-index:4}.content-container .aside-nav ul{overflow-y:auto;height:90%}.content-container .aside-nav a{padding:15px;display:block;color:#000311}.content-container .aside-nav .active a{background:#fff;border-top:1px solid hsla(0,0%,64%,.2);border-bottom:1px solid hsla(0,0%,64%,.2)}.content-container .aside-nav .active i{float:right}.content-container .content-wrapper{padding:25px;margin-left:305px}.content-container .content{margin-top:25px}.content-container .content.full-page{padding:25px}.content-container .content .page-header{display:inline-block;margin-bottom:20px;width:100%}.content-container .content .page-header .page-title{float:left}.content-container .content .page-header .page-title .back-link{float:left;margin-right:10px;width:24px;height:24px;cursor:pointer;margin-top:5px}.content-container .content .page-header .page-title h1{margin-bottom:0;vertical-align:middle;display:inline-block;line-height:normal}.content-container .content .page-header .page-action{float:right}.content-container .content .page-header .page-action *{display:inline-block}.content-container .content .page-header .page-action a{margin-left:25px}.content-container .content .page-header .control-group{width:180px;display:inline-block;margin-bottom:0;margin-left:20px}.content-container .content .page-header .control{width:100%;margin:0}.content-container .content .page-content{width:100%;display:inline-block}.control-container{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;-webkit-box-align:start;-ms-flex-align:start;align-items:flex-start;width:750px}.control-container .control{background:#fff;border:2px solid #c7c7c7;border-radius:3px;width:150px;height:36px;display:inline-block;vertical-align:middle;-webkit-transition:.2s cubic-bezier(.4,0,.2,1);transition:.2s cubic-bezier(.4,0,.2,1);padding:0 10px;font-size:15px}.control-container .control:focus{border-color:#0041ff}.control-container .icon:hover{cursor:pointer}.control-container .control-group::last-child{margin-right:0}.boolean-control-container{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;-webkit-box-pack:start;-ms-flex-pack:start;justify-content:flex-start;width:750px}.boolean-control-container .control-group{width:200px}.control-group label{width:70%}.control-group label .locale{float:right;color:#8e8e8e}.control-group .mce-tinymce{margin-top:10px;margin-bottom:5px}.dashboard .page-header{margin-bottom:0!important;padding-bottom:15px;border-bottom:1px solid hsla(0,0%,64%,.2)}.dashboard .page-content{margin-top:15px}.dashboard .card{height:445px;background:#fff;border:1px solid #e7e7e7;-webkit-box-shadow:0 5px 10px 2px rgba(0,0,0,.08);box-shadow:0 5px 10px 2px rgba(0,0,0,.08);border-radius:2px;padding:20px 0 0 20px;overflow:auto}.dashboard .card .card-title{font-size:14px;color:#a2a2a2;letter-spacing:-.26px;text-transform:uppercase}.dashboard .card .card-info{width:100%;display:inline-block}.dashboard .card .card-info.center{text-align:center}.dashboard .card .card-info ul li{border-bottom:1px solid hsla(0,0%,64%,.2);width:100%;display:inline-block;padding:10px 0;position:relative}.dashboard .card .card-info ul li .image{height:60px;width:60px;float:left;margin-right:15px}.dashboard .card .card-info ul li .image.product{background:#f2f2f2}.dashboard .card .card-info ul li .image img{width:100%}.dashboard .card .card-info ul li .description{margin-top:10px}.dashboard .card .card-info ul li .description .name{color:#0041ff}.dashboard .card .card-info ul li .description .info{color:#3a3a3a;margin-top:5px}.dashboard .card .card-info ul li .icon.angle-right-icon{position:absolute;right:30px;top:50%;margin-top:-8px}.dashboard .card .card-info ul li:last-child{border-bottom:0}.dashboard .card .card-info .no-result-found{margin-top:146px}.dashboard .card .card-info .no-result-found p{margin:0;color:#a2a2a2}.dashboard .dashboard-stats{display:grid;grid-template-columns:repeat(auto-fill,minmax(320px,1fr));grid-auto-rows:auto;grid-column-gap:30px;grid-row-gap:15px}.dashboard .dashboard-stats .dashboard-card{height:100px;background:#fff;border:1px solid #e7e7e7;-webkit-box-shadow:0 5px 10px 2px rgba(0,0,0,.08);box-shadow:0 5px 10px 2px rgba(0,0,0,.08);border-radius:5px;position:relative;padding:15px}.dashboard .dashboard-stats .dashboard-card .title{font-size:14px;color:#a2a2a2;text-transform:uppercase}.dashboard .dashboard-stats .dashboard-card .data{padding-top:13px;font-size:32px;color:#0041ff}.dashboard .dashboard-stats .dashboard-card .data .progress{font-size:14px;color:#8e8e8e;float:right;margin-top:-2px}.dashboard .dashboard-stats .dashboard-card .data .progress .icon{vertical-align:middle}.dashboard .graph-stats{margin-top:30px;width:100%;display:inline-block}.dashboard .graph-stats .left-card-container{float:left;width:75%;padding-right:9px}.dashboard .graph-stats .right-card-container{float:left;width:25%;padding-left:21px}.dashboard .sale-stock{width:100%;display:inline-block;display:grid;grid-template-columns:repeat(auto-fill,minmax(435px,1fr));grid-auto-rows:auto;grid-column-gap:30px;grid-row-gap:15px;margin-top:30px}.sale-container .sale-section{font-size:16px}.sale-container .sale-section .secton-title{font-size:18px;color:#8e8e8e;padding:15px 0;border-bottom:1px solid hsla(0,0%,64%,.2)}.sale-container .sale-section .section-content{display:block;padding:20px 0}.sale-container .sale-section .section-content .row{display:block;padding:7px 0}.sale-container .sale-section .section-content .row .title{width:200px;color:#3a3a3a;letter-spacing:-.26px;display:inline-block}.sale-container .sale-section .section-content .row .value{color:#3a3a3a;letter-spacing:-.26px;display:inline-block}.sale-container .table .qty-row{display:block;margin-bottom:5px}.sale-container .table .qty-row:last-child{margin-bottom:0}.sale-container .table .radio{margin:0}.sale-container .sale-summary{margin-top:2%;height:130px;float:right}.sale-container .sale-summary tr td{padding:5px 8px}.sale-container .sale-summary tr.bold{font-weight:600;font-size:15px}.sale-container .sale-summary tr.border td{border-bottom:1px solid hsla(0,0%,64%,.2)}.stars{margin-top:5px}.stars .icon{width:16px;height:16px}.export-import{cursor:pointer}.export-import .export-icon,.export-import .import-icon{position:relative;top:10px}.export-import span{margin-left:2px}.configuration-image{position:relative;height:33px;width:33px;top:15px;border-radius:3px;margin-right:5px}.download{position:relative;height:24px!important;width:24px!important;top:12px;margin-right:10px}.aside-nav-toggle{height:48px;width:100%;padding-top:15px;border-top:1px solid hsla(0,0%,64%,.2)}.aside-nav-toggle .close-icon,.aside-nav-toggle .open-icon{position:absolute;cursor:pointer;left:45%}.aside-nav-toggle.open{display:none}.linked-product-search-result{-webkit-box-shadow:0 2px 4px 0 rgba(0,0,0,.16),0 0 9px 0 rgba(0,0,0,.16);box-shadow:0 2px 4px 0 rgba(0,0,0,.16),0 0 9px 0 rgba(0,0,0,.16);z-index:10;text-align:left;border-radius:3px;background-color:#fff;width:70%;max-height:200px;overflow-y:auto}.linked-product-search-result li{padding:10px;border-bottom:1px solid #e8e8e8;cursor:pointer}.rtl{direction:rtl}.rtl .navbar-top .navbar-top-right{text-align:left}.rtl .navbar-top .navbar-top-right .profile-info{margin:0 30px 0 25px}.rtl .navbar-top .navbar-top-right .profile-info i.icon{margin-left:0;margin-right:10px}.rtl .navbar-left{border-left:1px solid hsla(0,0%,64%,.2);border-right:none;left:calc(100% - 90px)}.rtl .content-container{padding-right:90px;padding-left:0}.rtl .content-container .content .page-header .page-title{float:right}.rtl .content-container .content .page-header .page-action{float:left}.rtl .content-container .content .page-header .page-action a{margin-left:0}.rtl .content-container .content .page-header .control-group{margin-right:20px;margin-left:0}.rtl .content-container .content .page-header .control-group.date:after{margin-top:6px;position:absolute;margin-right:-35px}.rtl .content-container .content .page-header .control-group.date:last-child{margin-left:0}.rtl .content-container .content-wrapper{padding:25px 305px 25px 25px;margin-left:0}.rtl .content-container .aside-nav .active i{float:left;-webkit-transform:rotate(180deg);transform:rotate(180deg)}.rtl .dashboard .dashboard-stats .dashboard-card .data span{float:left}.rtl .dashboard .card{padding:20px 20px 0 0}.rtl .dashboard .card .card-info ul li .image{float:right;margin-right:0;margin-left:15px}.rtl .dashboard .card .card-info ul li .icon.angle-right-icon{left:30px;right:auto;-webkit-transform:rotate(180deg);transform:rotate(180deg)}.rtl .dashboard .graph-stats .left-card-container{float:right;padding-right:0}.rtl .dashboard .graph-stats .right-card-container{float:right;padding-left:0;padding-right:30px}.rtl .sale-container .sale-summary{float:left}.rtl .grid-container .filter-row-one .search-filter{border:2px solid #c7c7c7;border-radius:2px}.rtl .grid-container .filter-row-one .search-filter .control{border:none;padding-right:10px}.rtl .grid-container .filter-row-one .search-filter .icon-wrapper{border:none;padding-top:2px;padding-right:5px;border-right:2px solid #c7c7c7;border-radius:0}.rtl .grid-container .filter-row-two .filter-tag .icon.cross-icon,.rtl .grid-container .filter-row-two .filter-tag .wrapper{margin-right:10px;margin-left:0}.rtl .grid-container .filter-row-one .dropdown-filters{right:unset;left:25px}.rtl .grid-container .filter-wrapper .filter-row-one .dropdown-filters .more-filters .dropdown-toggle .dropdown-header span{padding-right:5px}.rtl .grid-container .table tbody td.action a:first-child{margin-left:10px;margin-right:0}.rtl .table table{text-align:right}.rtl .table table .massaction-remove{margin-right:5px!important;margin-left:10px}.rtl .table table .btn.btn-primary{margin-right:10px!important}.rtl .dropdown-list.bottom-right{left:0;right:auto}.rtl .dropdown-list .dropdown-container{text-align:right}.rtl .accordian .accordian-header .icon{float:left}.rtl .tree-container .tree-item{padding-right:30px}.rtl .tree-container .tree-item .expand-icon,.rtl .tree-container .tree-item .folder-icon{margin-left:10px;margin-right:0}.rtl .tree-container>.tree-item{padding-right:0}.rtl .radio .radio-view{margin-left:5px}.rtl .image-wrapper .image-item{margin-right:0;margin-left:20px}.rtl .image-wrapper .image-item .remove-image{margin-right:0}.rtl .control-group label.required:before{content:"*";color:#fc6868;font-weight:700}.rtl .control-group label.required:after{content:none}.rtl .control-group label .locale{float:left}.rtl .control-group.date:after{margin-top:15px;position:absolute;margin-right:-35px}.rtl .pagination .page-item .icon{-webkit-transform:rotate(180deg);transform:rotate(180deg)}.fixed-action{position:fixed;top:108px;right:32px}.fixed-action-slight{position:fixed;top:94px;right:32px}.pagination{margin-top:30px}
\ No newline at end of file
diff --git a/packages/Webkul/Admin/publishable/assets/js/admin.js b/packages/Webkul/Admin/publishable/assets/js/admin.js
index 732e71883..313b51ff7 100755
--- a/packages/Webkul/Admin/publishable/assets/js/admin.js
+++ b/packages/Webkul/Admin/publishable/assets/js/admin.js
@@ -1 +1 @@
-!function(e){var t={};function n(r){if(t[r])return t[r].exports;var i=t[r]={i:r,l:!1,exports:{}};return e[r].call(i.exports,i,i.exports,n),i.l=!0,i.exports}n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{configurable:!1,enumerable:!0,get:r})},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="/",n(n.s=0)}({0:function(e,t,n){n("J66Q"),e.exports=n("MT9B")},"162o":function(e,t,n){(function(e){var r=void 0!==e&&e||"undefined"!=typeof self&&self||window,i=Function.prototype.apply;function o(e,t){this._id=e,this._clearFn=t}t.setTimeout=function(){return new o(i.call(setTimeout,r,arguments),clearTimeout)},t.setInterval=function(){return new o(i.call(setInterval,r,arguments),clearInterval)},t.clearTimeout=t.clearInterval=function(e){e&&e.close()},o.prototype.unref=o.prototype.ref=function(){},o.prototype.close=function(){this._clearFn.call(r,this._id)},t.enroll=function(e,t){clearTimeout(e._idleTimeoutId),e._idleTimeout=t},t.unenroll=function(e){clearTimeout(e._idleTimeoutId),e._idleTimeout=-1},t._unrefActive=t.active=function(e){clearTimeout(e._idleTimeoutId);var t=e._idleTimeout;t>=0&&(e._idleTimeoutId=setTimeout(function(){e._onTimeout&&e._onTimeout()},t))},n("mypn"),t.setImmediate="undefined"!=typeof self&&self.setImmediate||void 0!==e&&e.setImmediate||this&&this.setImmediate,t.clearImmediate="undefined"!=typeof self&&self.clearImmediate||void 0!==e&&e.clearImmediate||this&&this.clearImmediate}).call(t,n("DuR2"))},"21It":function(e,t,n){"use strict";var r=n("FtD3");e.exports=function(e,t,n){var i=n.config.validateStatus;n.status&&i&&!i(n.status)?t(r("Request failed with status code "+n.status,n.config,null,n.request,n)):e(n)}},"5VQ+":function(e,t,n){"use strict";var r=n("cGG2");e.exports=function(e,t){r.forEach(e,function(n,r){r!==t&&r.toUpperCase()===t.toUpperCase()&&(e[t]=n,delete e[r])})}},"7GwW":function(e,t,n){"use strict";var r=n("cGG2"),i=n("21It"),o=n("DQCr"),a=n("oJlt"),s=n("GHBc"),u=n("FtD3"),c="undefined"!=typeof window&&window.btoa&&window.btoa.bind(window)||n("thJu");e.exports=function(e){return new Promise(function(t,l){var f=e.data,d=e.headers;r.isFormData(f)&&delete d["Content-Type"];var p=new XMLHttpRequest,h="onreadystatechange",v=!1;if("undefined"==typeof window||!window.XDomainRequest||"withCredentials"in p||s(e.url)||(p=new window.XDomainRequest,h="onload",v=!0,p.onprogress=function(){},p.ontimeout=function(){}),e.auth){var m=e.auth.username||"",g=e.auth.password||"";d.Authorization="Basic "+c(m+":"+g)}if(p.open(e.method.toUpperCase(),o(e.url,e.params,e.paramsSerializer),!0),p.timeout=e.timeout,p[h]=function(){if(p&&(4===p.readyState||v)&&(0!==p.status||p.responseURL&&0===p.responseURL.indexOf("file:"))){var n="getAllResponseHeaders"in p?a(p.getAllResponseHeaders()):null,r={data:e.responseType&&"text"!==e.responseType?p.response:p.responseText,status:1223===p.status?204:p.status,statusText:1223===p.status?"No Content":p.statusText,headers:n,config:e,request:p};i(t,l,r),p=null}},p.onerror=function(){l(u("Network Error",e,null,p)),p=null},p.ontimeout=function(){l(u("timeout of "+e.timeout+"ms exceeded",e,"ECONNABORTED",p)),p=null},r.isStandardBrowserEnv()){var y=n("p1b6"),b=(e.withCredentials||s(e.url))&&e.xsrfCookieName?y.read(e.xsrfCookieName):void 0;b&&(d[e.xsrfHeaderName]=b)}if("setRequestHeader"in p&&r.forEach(d,function(e,t){void 0===f&&"content-type"===t.toLowerCase()?delete d[t]:p.setRequestHeader(t,e)}),e.withCredentials&&(p.withCredentials=!0),e.responseType)try{p.responseType=e.responseType}catch(t){if("json"!==e.responseType)throw t}"function"==typeof e.onDownloadProgress&&p.addEventListener("progress",e.onDownloadProgress),"function"==typeof e.onUploadProgress&&p.upload&&p.upload.addEventListener("progress",e.onUploadProgress),e.cancelToken&&e.cancelToken.promise.then(function(e){p&&(p.abort(),l(e),p=null)}),void 0===f&&(f=null),p.send(f)})}},"7t+N":function(e,t,n){var r;!function(t,n){"use strict";"object"==typeof e&&"object"==typeof e.exports?e.exports=t.document?n(t,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return n(e)}:n(t)}("undefined"!=typeof window?window:this,function(n,i){"use strict";var o=[],a=n.document,s=Object.getPrototypeOf,u=o.slice,c=o.concat,l=o.push,f=o.indexOf,d={},p=d.toString,h=d.hasOwnProperty,v=h.toString,m=v.call(Object),g={},y=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType},b=function(e){return null!=e&&e===e.window},x={type:!0,src:!0,noModule:!0};function w(e,t,n){var r,i=(t=t||a).createElement("script");if(i.text=e,n)for(r in x)n[r]&&(i[r]=n[r]);t.head.appendChild(i).parentNode.removeChild(i)}function _(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?d[p.call(e)]||"object":typeof e}var T=function(e,t){return new T.fn.init(e,t)},C=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;function $(e){var t=!!e&&"length"in e&&e.length,n=_(e);return!y(e)&&!b(e)&&("array"===n||0===t||"number"==typeof t&&t>0&&t-1 in e)}T.fn=T.prototype={jquery:"3.3.1",constructor:T,length:0,toArray:function(){return u.call(this)},get:function(e){return null==e?u.call(this):e<0?this[e+this.length]:this[e]},pushStack:function(e){var t=T.merge(this.constructor(),e);return t.prevObject=this,t},each:function(e){return T.each(this,e)},map:function(e){return this.pushStack(T.map(this,function(t,n){return e.call(t,n,t)}))},slice:function(){return this.pushStack(u.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(e){var t=this.length,n=+e+(e<0?t:0);return this.pushStack(n>=0&&n+~]|"+F+")"+F+"*"),W=new RegExp("="+F+"*([^\\]'\"]*?)"+F+"*\\]","g"),Y=new RegExp(R),z=new RegExp("^"+I+"$"),V={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+P),PSEUDO:new RegExp("^"+R),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+F+"*(even|odd|(([+-]|)(\\d*)n|)"+F+"*(?:([+-]|)"+F+"*(\\d+)|))"+F+"*\\)|)","i"),bool:new RegExp("^(?:"+L+")$","i"),needsContext:new RegExp("^"+F+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+F+"*((?:-\\d)?\\d*)"+F+"*\\)|)(?=[^-]|$)","i")},G=/^(?:input|select|textarea|button)$/i,Z=/^h\d$/i,X=/^[^{]+\{\s*\[native \w/,J=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,K=/[+~]/,Q=new RegExp("\\\\([\\da-f]{1,6}"+F+"?|("+F+")|.)","ig"),ee=function(e,t,n){var r="0x"+t-65536;return r!=r||n?t:r<0?String.fromCharCode(r+65536):String.fromCharCode(r>>10|55296,1023&r|56320)},te=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ne=function(e,t){return t?"\0"===e?"�":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},re=function(){d()},ie=ye(function(e){return!0===e.disabled&&("form"in e||"label"in e)},{dir:"parentNode",next:"legend"});try{N.apply(S=j.call(w.childNodes),w.childNodes),S[w.childNodes.length].nodeType}catch(e){N={apply:S.length?function(e,t){E.apply(e,j.call(t))}:function(e,t){for(var n=e.length,r=0;e[n++]=t[r++];);e.length=n-1}}}function oe(e,t,r,i){var o,s,c,l,f,h,g,y=t&&t.ownerDocument,_=t?t.nodeType:9;if(r=r||[],"string"!=typeof e||!e||1!==_&&9!==_&&11!==_)return r;if(!i&&((t?t.ownerDocument||t:w)!==p&&d(t),t=t||p,v)){if(11!==_&&(f=J.exec(e)))if(o=f[1]){if(9===_){if(!(c=t.getElementById(o)))return r;if(c.id===o)return r.push(c),r}else if(y&&(c=y.getElementById(o))&&b(t,c)&&c.id===o)return r.push(c),r}else{if(f[2])return N.apply(r,t.getElementsByTagName(e)),r;if((o=f[3])&&n.getElementsByClassName&&t.getElementsByClassName)return N.apply(r,t.getElementsByClassName(o)),r}if(n.qsa&&!A[e+" "]&&(!m||!m.test(e))){if(1!==_)y=t,g=e;else if("object"!==t.nodeName.toLowerCase()){for((l=t.getAttribute("id"))?l=l.replace(te,ne):t.setAttribute("id",l=x),s=(h=a(e)).length;s--;)h[s]="#"+l+" "+ge(h[s]);g=h.join(","),y=K.test(e)&&ve(t.parentNode)||t}if(g)try{return N.apply(r,y.querySelectorAll(g)),r}catch(e){}finally{l===x&&t.removeAttribute("id")}}}return u(e.replace(H,"$1"),t,r,i)}function ae(){var e=[];return function t(n,i){return e.push(n+" ")>r.cacheLength&&delete t[e.shift()],t[n+" "]=i}}function se(e){return e[x]=!0,e}function ue(e){var t=p.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function ce(e,t){for(var n=e.split("|"),i=n.length;i--;)r.attrHandle[n[i]]=t}function le(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)for(;n=n.nextSibling;)if(n===t)return-1;return e?1:-1}function fe(e){return function(t){return"input"===t.nodeName.toLowerCase()&&t.type===e}}function de(e){return function(t){var n=t.nodeName.toLowerCase();return("input"===n||"button"===n)&&t.type===e}}function pe(e){return function(t){return"form"in t?t.parentNode&&!1===t.disabled?"label"in t?"label"in t.parentNode?t.parentNode.disabled===e:t.disabled===e:t.isDisabled===e||t.isDisabled!==!e&&ie(t)===e:t.disabled===e:"label"in t&&t.disabled===e}}function he(e){return se(function(t){return t=+t,se(function(n,r){for(var i,o=e([],n.length,t),a=o.length;a--;)n[i=o[a]]&&(n[i]=!(r[i]=n[i]))})})}function ve(e){return e&&void 0!==e.getElementsByTagName&&e}for(t in n=oe.support={},o=oe.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return!!t&&"HTML"!==t.nodeName},d=oe.setDocument=function(e){var t,i,a=e?e.ownerDocument||e:w;return a!==p&&9===a.nodeType&&a.documentElement?(h=(p=a).documentElement,v=!o(p),w!==p&&(i=p.defaultView)&&i.top!==i&&(i.addEventListener?i.addEventListener("unload",re,!1):i.attachEvent&&i.attachEvent("onunload",re)),n.attributes=ue(function(e){return e.className="i",!e.getAttribute("className")}),n.getElementsByTagName=ue(function(e){return e.appendChild(p.createComment("")),!e.getElementsByTagName("*").length}),n.getElementsByClassName=X.test(p.getElementsByClassName),n.getById=ue(function(e){return h.appendChild(e).id=x,!p.getElementsByName||!p.getElementsByName(x).length}),n.getById?(r.filter.ID=function(e){var t=e.replace(Q,ee);return function(e){return e.getAttribute("id")===t}},r.find.ID=function(e,t){if(void 0!==t.getElementById&&v){var n=t.getElementById(e);return n?[n]:[]}}):(r.filter.ID=function(e){var t=e.replace(Q,ee);return function(e){var n=void 0!==e.getAttributeNode&&e.getAttributeNode("id");return n&&n.value===t}},r.find.ID=function(e,t){if(void 0!==t.getElementById&&v){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];for(i=t.getElementsByName(e),r=0;o=i[r++];)if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),r.find.TAG=n.getElementsByTagName?function(e,t){return void 0!==t.getElementsByTagName?t.getElementsByTagName(e):n.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){for(;n=o[i++];)1===n.nodeType&&r.push(n);return r}return o},r.find.CLASS=n.getElementsByClassName&&function(e,t){if(void 0!==t.getElementsByClassName&&v)return t.getElementsByClassName(e)},g=[],m=[],(n.qsa=X.test(p.querySelectorAll))&&(ue(function(e){h.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&m.push("[*^$]="+F+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||m.push("\\["+F+"*(?:value|"+L+")"),e.querySelectorAll("[id~="+x+"-]").length||m.push("~="),e.querySelectorAll(":checked").length||m.push(":checked"),e.querySelectorAll("a#"+x+"+*").length||m.push(".#.+[+~]")}),ue(function(e){e.innerHTML="";var t=p.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&m.push("name"+F+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&m.push(":enabled",":disabled"),h.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&m.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),m.push(",.*:")})),(n.matchesSelector=X.test(y=h.matches||h.webkitMatchesSelector||h.mozMatchesSelector||h.oMatchesSelector||h.msMatchesSelector))&&ue(function(e){n.disconnectedMatch=y.call(e,"*"),y.call(e,"[s!='']:x"),g.push("!=",R)}),m=m.length&&new RegExp(m.join("|")),g=g.length&&new RegExp(g.join("|")),t=X.test(h.compareDocumentPosition),b=t||X.test(h.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)for(;t=t.parentNode;)if(t===e)return!0;return!1},D=t?function(e,t){if(e===t)return f=!0,0;var r=!e.compareDocumentPosition-!t.compareDocumentPosition;return r||(1&(r=(e.ownerDocument||e)===(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!n.sortDetached&&t.compareDocumentPosition(e)===r?e===p||e.ownerDocument===w&&b(w,e)?-1:t===p||t.ownerDocument===w&&b(w,t)?1:l?M(l,e)-M(l,t):0:4&r?-1:1)}:function(e,t){if(e===t)return f=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e===p?-1:t===p?1:i?-1:o?1:l?M(l,e)-M(l,t):0;if(i===o)return le(e,t);for(n=e;n=n.parentNode;)a.unshift(n);for(n=t;n=n.parentNode;)s.unshift(n);for(;a[r]===s[r];)r++;return r?le(a[r],s[r]):a[r]===w?-1:s[r]===w?1:0},p):p},oe.matches=function(e,t){return oe(e,null,null,t)},oe.matchesSelector=function(e,t){if((e.ownerDocument||e)!==p&&d(e),t=t.replace(W,"='$1']"),n.matchesSelector&&v&&!A[t+" "]&&(!g||!g.test(t))&&(!m||!m.test(t)))try{var r=y.call(e,t);if(r||n.disconnectedMatch||e.document&&11!==e.document.nodeType)return r}catch(e){}return oe(t,p,null,[e]).length>0},oe.contains=function(e,t){return(e.ownerDocument||e)!==p&&d(e),b(e,t)},oe.attr=function(e,t){(e.ownerDocument||e)!==p&&d(e);var i=r.attrHandle[t.toLowerCase()],o=i&&k.call(r.attrHandle,t.toLowerCase())?i(e,t,!v):void 0;return void 0!==o?o:n.attributes||!v?e.getAttribute(t):(o=e.getAttributeNode(t))&&o.specified?o.value:null},oe.escape=function(e){return(e+"").replace(te,ne)},oe.error=function(e){throw new Error("Syntax error, unrecognized expression: "+e)},oe.uniqueSort=function(e){var t,r=[],i=0,o=0;if(f=!n.detectDuplicates,l=!n.sortStable&&e.slice(0),e.sort(D),f){for(;t=e[o++];)t===e[o]&&(i=r.push(o));for(;i--;)e.splice(r[i],1)}return l=null,e},i=oe.getText=function(e){var t,n="",r=0,o=e.nodeType;if(o){if(1===o||9===o||11===o){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=i(e)}else if(3===o||4===o)return e.nodeValue}else for(;t=e[r++];)n+=i(t);return n},(r=oe.selectors={cacheLength:50,createPseudo:se,match:V,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(Q,ee),e[3]=(e[3]||e[4]||e[5]||"").replace(Q,ee),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||oe.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&oe.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return V.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&Y.test(n)&&(t=a(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(Q,ee).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=C[e+" "];return t||(t=new RegExp("(^|"+F+")"+e+"("+F+"|$)"))&&C(e,function(e){return t.test("string"==typeof e.className&&e.className||void 0!==e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(e,t,n){return function(r){var i=oe.attr(r,e);return null==i?"!="===t:!t||(i+="","="===t?i===n:"!="===t?i!==n:"^="===t?n&&0===i.indexOf(n):"*="===t?n&&i.indexOf(n)>-1:"$="===t?n&&i.slice(-n.length)===n:"~="===t?(" "+i.replace(q," ")+" ").indexOf(n)>-1:"|="===t&&(i===n||i.slice(0,n.length+1)===n+"-"))}},CHILD:function(e,t,n,r,i){var o="nth"!==e.slice(0,3),a="last"!==e.slice(-4),s="of-type"===t;return 1===r&&0===i?function(e){return!!e.parentNode}:function(t,n,u){var c,l,f,d,p,h,v=o!==a?"nextSibling":"previousSibling",m=t.parentNode,g=s&&t.nodeName.toLowerCase(),y=!u&&!s,b=!1;if(m){if(o){for(;v;){for(d=t;d=d[v];)if(s?d.nodeName.toLowerCase()===g:1===d.nodeType)return!1;h=v="only"===e&&!h&&"nextSibling"}return!0}if(h=[a?m.firstChild:m.lastChild],a&&y){for(b=(p=(c=(l=(f=(d=m)[x]||(d[x]={}))[d.uniqueID]||(f[d.uniqueID]={}))[e]||[])[0]===_&&c[1])&&c[2],d=p&&m.childNodes[p];d=++p&&d&&d[v]||(b=p=0)||h.pop();)if(1===d.nodeType&&++b&&d===t){l[e]=[_,p,b];break}}else if(y&&(b=p=(c=(l=(f=(d=t)[x]||(d[x]={}))[d.uniqueID]||(f[d.uniqueID]={}))[e]||[])[0]===_&&c[1]),!1===b)for(;(d=++p&&d&&d[v]||(b=p=0)||h.pop())&&((s?d.nodeName.toLowerCase()!==g:1!==d.nodeType)||!++b||(y&&((l=(f=d[x]||(d[x]={}))[d.uniqueID]||(f[d.uniqueID]={}))[e]=[_,b]),d!==t)););return(b-=i)===r||b%r==0&&b/r>=0}}},PSEUDO:function(e,t){var n,i=r.pseudos[e]||r.setFilters[e.toLowerCase()]||oe.error("unsupported pseudo: "+e);return i[x]?i(t):i.length>1?(n=[e,e,"",t],r.setFilters.hasOwnProperty(e.toLowerCase())?se(function(e,n){for(var r,o=i(e,t),a=o.length;a--;)e[r=M(e,o[a])]=!(n[r]=o[a])}):function(e){return i(e,0,n)}):i}},pseudos:{not:se(function(e){var t=[],n=[],r=s(e.replace(H,"$1"));return r[x]?se(function(e,t,n,i){for(var o,a=r(e,null,i,[]),s=e.length;s--;)(o=a[s])&&(e[s]=!(t[s]=o))}):function(e,i,o){return t[0]=e,r(t,null,o,n),t[0]=null,!n.pop()}}),has:se(function(e){return function(t){return oe(e,t).length>0}}),contains:se(function(e){return e=e.replace(Q,ee),function(t){return(t.textContent||t.innerText||i(t)).indexOf(e)>-1}}),lang:se(function(e){return z.test(e||"")||oe.error("unsupported lang: "+e),e=e.replace(Q,ee).toLowerCase(),function(t){var n;do{if(n=v?t.lang:t.getAttribute("xml:lang")||t.getAttribute("lang"))return(n=n.toLowerCase())===e||0===n.indexOf(e+"-")}while((t=t.parentNode)&&1===t.nodeType);return!1}}),target:function(t){var n=e.location&&e.location.hash;return n&&n.slice(1)===t.id},root:function(e){return e===h},focus:function(e){return e===p.activeElement&&(!p.hasFocus||p.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:pe(!1),disabled:pe(!0),checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,!0===e.selected},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeType<6)return!1;return!0},parent:function(e){return!r.pseudos.empty(e)},header:function(e){return Z.test(e.nodeName)},input:function(e){return G.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},text:function(e){var t;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(t=e.getAttribute("type"))||"text"===t.toLowerCase())},first:he(function(){return[0]}),last:he(function(e,t){return[t-1]}),eq:he(function(e,t,n){return[n<0?n+t:n]}),even:he(function(e,t){for(var n=0;n=0;)e.push(r);return e}),gt:he(function(e,t,n){for(var r=n<0?n+t:n;++r1?function(t,n,r){for(var i=e.length;i--;)if(!e[i](t,n,r))return!1;return!0}:e[0]}function xe(e,t,n,r,i){for(var o,a=[],s=0,u=e.length,c=null!=t;s-1&&(o[c]=!(a[c]=f))}}else g=xe(g===a?g.splice(h,g.length):g),i?i(null,a,g,u):N.apply(a,g)})}function _e(e){for(var t,n,i,o=e.length,a=r.relative[e[0].type],s=a||r.relative[" "],u=a?1:0,l=ye(function(e){return e===t},s,!0),f=ye(function(e){return M(t,e)>-1},s,!0),d=[function(e,n,r){var i=!a&&(r||n!==c)||((t=n).nodeType?l(e,n,r):f(e,n,r));return t=null,i}];u1&&be(d),u>1&&ge(e.slice(0,u-1).concat({value:" "===e[u-2].type?"*":""})).replace(H,"$1"),n,u0,i=e.length>0,o=function(o,a,s,u,l){var f,h,m,g=0,y="0",b=o&&[],x=[],w=c,T=o||i&&r.find.TAG("*",l),C=_+=null==w?1:Math.random()||.1,$=T.length;for(l&&(c=a===p||a||l);y!==$&&null!=(f=T[y]);y++){if(i&&f){for(h=0,a||f.ownerDocument===p||(d(f),s=!v);m=e[h++];)if(m(f,a||p,s)){u.push(f);break}l&&(_=C)}n&&((f=!m&&f)&&g--,o&&b.push(f))}if(g+=y,n&&y!==g){for(h=0;m=t[h++];)m(b,x,a,s);if(o){if(g>0)for(;y--;)b[y]||x[y]||(x[y]=O.call(u));x=xe(x)}N.apply(u,x),l&&!o&&x.length>0&&g+t.length>1&&oe.uniqueSort(u)}return l&&(_=C,c=w),b};return n?se(o):o}(o,i))).selector=e}return s},u=oe.select=function(e,t,n,i){var o,u,c,l,f,d="function"==typeof e&&e,p=!i&&a(e=d.selector||e);if(n=n||[],1===p.length){if((u=p[0]=p[0].slice(0)).length>2&&"ID"===(c=u[0]).type&&9===t.nodeType&&v&&r.relative[u[1].type]){if(!(t=(r.find.ID(c.matches[0].replace(Q,ee),t)||[])[0]))return n;d&&(t=t.parentNode),e=e.slice(u.shift().value.length)}for(o=V.needsContext.test(e)?0:u.length;o--&&(c=u[o],!r.relative[l=c.type]);)if((f=r.find[l])&&(i=f(c.matches[0].replace(Q,ee),K.test(u[0].type)&&ve(t.parentNode)||t))){if(u.splice(o,1),!(e=i.length&&ge(u)))return N.apply(n,i),n;break}}return(d||s(e,p))(i,t,!v,n,!t||K.test(e)&&ve(t.parentNode)||t),n},n.sortStable=x.split("").sort(D).join("")===x,n.detectDuplicates=!!f,d(),n.sortDetached=ue(function(e){return 1&e.compareDocumentPosition(p.createElement("fieldset"))}),ue(function(e){return e.innerHTML="","#"===e.firstChild.getAttribute("href")})||ce("type|href|height|width",function(e,t,n){if(!n)return e.getAttribute(t,"type"===t.toLowerCase()?1:2)}),n.attributes&&ue(function(e){return e.innerHTML="",e.firstChild.setAttribute("value",""),""===e.firstChild.getAttribute("value")})||ce("value",function(e,t,n){if(!n&&"input"===e.nodeName.toLowerCase())return e.defaultValue}),ue(function(e){return null==e.getAttribute("disabled")})||ce(L,function(e,t,n){var r;if(!n)return!0===e[t]?t.toLowerCase():(r=e.getAttributeNode(t))&&r.specified?r.value:null}),oe}(n);T.find=A,T.expr=A.selectors,T.expr[":"]=T.expr.pseudos,T.uniqueSort=T.unique=A.uniqueSort,T.text=A.getText,T.isXMLDoc=A.isXML,T.contains=A.contains,T.escapeSelector=A.escape;var D=function(e,t,n){for(var r=[],i=void 0!==n;(e=e[t])&&9!==e.nodeType;)if(1===e.nodeType){if(i&&T(e).is(n))break;r.push(e)}return r},k=function(e,t){for(var n=[];e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n},S=T.expr.match.needsContext;function O(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()}var E=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function N(e,t,n){return y(t)?T.grep(e,function(e,r){return!!t.call(e,r,e)!==n}):t.nodeType?T.grep(e,function(e){return e===t!==n}):"string"!=typeof t?T.grep(e,function(e){return f.call(t,e)>-1!==n}):T.filter(t,e,n)}T.filter=function(e,t,n){var r=t[0];return n&&(e=":not("+e+")"),1===t.length&&1===r.nodeType?T.find.matchesSelector(r,e)?[r]:[]:T.find.matches(e,T.grep(t,function(e){return 1===e.nodeType}))},T.fn.extend({find:function(e){var t,n,r=this.length,i=this;if("string"!=typeof e)return this.pushStack(T(e).filter(function(){for(t=0;t1?T.uniqueSort(n):n},filter:function(e){return this.pushStack(N(this,e||[],!1))},not:function(e){return this.pushStack(N(this,e||[],!0))},is:function(e){return!!N(this,"string"==typeof e&&S.test(e)?T(e):e||[],!1).length}});var j,M=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/;(T.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||j,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&e.length>=3?[null,e,null]:M.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof T?t[0]:t,T.merge(this,T.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:a,!0)),E.test(r[1])&&T.isPlainObject(t))for(r in t)y(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=a.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):y(e)?void 0!==n.ready?n.ready(e):e(T):T.makeArray(e,this)}).prototype=T.fn,j=T(a);var L=/^(?:parents|prev(?:Until|All))/,F={children:!0,contents:!0,next:!0,prev:!0};function I(e,t){for(;(e=e[t])&&1!==e.nodeType;);return e}T.fn.extend({has:function(e){var t=T(e,this),n=t.length;return this.filter(function(){for(var e=0;e-1:1===n.nodeType&&T.find.matchesSelector(n,e))){o.push(n);break}return this.pushStack(o.length>1?T.uniqueSort(o):o)},index:function(e){return e?"string"==typeof e?f.call(T(e),this[0]):f.call(this,e.jquery?e[0]:e):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){return this.pushStack(T.uniqueSort(T.merge(this.get(),T(e,t))))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}}),T.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return D(e,"parentNode")},parentsUntil:function(e,t,n){return D(e,"parentNode",n)},next:function(e){return I(e,"nextSibling")},prev:function(e){return I(e,"previousSibling")},nextAll:function(e){return D(e,"nextSibling")},prevAll:function(e){return D(e,"previousSibling")},nextUntil:function(e,t,n){return D(e,"nextSibling",n)},prevUntil:function(e,t,n){return D(e,"previousSibling",n)},siblings:function(e){return k((e.parentNode||{}).firstChild,e)},children:function(e){return k(e.firstChild)},contents:function(e){return O(e,"iframe")?e.contentDocument:(O(e,"template")&&(e=e.content||e),T.merge([],e.childNodes))}},function(e,t){T.fn[e]=function(n,r){var i=T.map(this,t,n);return"Until"!==e.slice(-5)&&(r=n),r&&"string"==typeof r&&(i=T.filter(r,i)),this.length>1&&(F[e]||T.uniqueSort(i),L.test(e)&&i.reverse()),this.pushStack(i)}});var P=/[^\x20\t\r\n\f]+/g;function R(e){return e}function q(e){throw e}function H(e,t,n,r){var i;try{e&&y(i=e.promise)?i.call(e).done(t).fail(n):e&&y(i=e.then)?i.call(e,t,n):t.apply(void 0,[e].slice(r))}catch(e){n.apply(void 0,[e])}}T.Callbacks=function(e){e="string"==typeof e?function(e){var t={};return T.each(e.match(P)||[],function(e,n){t[n]=!0}),t}(e):T.extend({},e);var t,n,r,i,o=[],a=[],s=-1,u=function(){for(i=i||e.once,r=t=!0;a.length;s=-1)for(n=a.shift();++s-1;)o.splice(n,1),n<=s&&s--}),this},has:function(e){return e?T.inArray(e,o)>-1:o.length>0},empty:function(){return o&&(o=[]),this},disable:function(){return i=a=[],o=n="",this},disabled:function(){return!o},lock:function(){return i=a=[],n||t||(o=n=""),this},locked:function(){return!!i},fireWith:function(e,n){return i||(n=[e,(n=n||[]).slice?n.slice():n],a.push(n),t||u()),this},fire:function(){return c.fireWith(this,arguments),this},fired:function(){return!!r}};return c},T.extend({Deferred:function(e){var t=[["notify","progress",T.Callbacks("memory"),T.Callbacks("memory"),2],["resolve","done",T.Callbacks("once memory"),T.Callbacks("once memory"),0,"resolved"],["reject","fail",T.Callbacks("once memory"),T.Callbacks("once memory"),1,"rejected"]],r="pending",i={state:function(){return r},always:function(){return o.done(arguments).fail(arguments),this},catch:function(e){return i.then(null,e)},pipe:function(){var e=arguments;return T.Deferred(function(n){T.each(t,function(t,r){var i=y(e[r[4]])&&e[r[4]];o[r[1]](function(){var e=i&&i.apply(this,arguments);e&&y(e.promise)?e.promise().progress(n.notify).done(n.resolve).fail(n.reject):n[r[0]+"With"](this,i?[e]:arguments)})}),e=null}).promise()},then:function(e,r,i){var o=0;function a(e,t,r,i){return function(){var s=this,u=arguments,c=function(){var n,c;if(!(e=o&&(r!==q&&(s=void 0,u=[n]),t.rejectWith(s,u))}};e?l():(T.Deferred.getStackHook&&(l.stackTrace=T.Deferred.getStackHook()),n.setTimeout(l))}}return T.Deferred(function(n){t[0][3].add(a(0,n,y(i)?i:R,n.notifyWith)),t[1][3].add(a(0,n,y(e)?e:R)),t[2][3].add(a(0,n,y(r)?r:q))}).promise()},promise:function(e){return null!=e?T.extend(e,i):i}},o={};return T.each(t,function(e,n){var a=n[2],s=n[5];i[n[1]]=a.add,s&&a.add(function(){r=s},t[3-e][2].disable,t[3-e][3].disable,t[0][2].lock,t[0][3].lock),a.add(n[3].fire),o[n[0]]=function(){return o[n[0]+"With"](this===o?void 0:this,arguments),this},o[n[0]+"With"]=a.fireWith}),i.promise(o),e&&e.call(o,o),o},when:function(e){var t=arguments.length,n=t,r=Array(n),i=u.call(arguments),o=T.Deferred(),a=function(e){return function(n){r[e]=this,i[e]=arguments.length>1?u.call(arguments):n,--t||o.resolveWith(r,i)}};if(t<=1&&(H(e,o.done(a(n)).resolve,o.reject,!t),"pending"===o.state()||y(i[n]&&i[n].then)))return o.then();for(;n--;)H(i[n],a(n),o.reject);return o.promise()}});var U=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;T.Deferred.exceptionHook=function(e,t){n.console&&n.console.warn&&e&&U.test(e.name)&&n.console.warn("jQuery.Deferred exception: "+e.message,e.stack,t)},T.readyException=function(e){n.setTimeout(function(){throw e})};var B=T.Deferred();function W(){a.removeEventListener("DOMContentLoaded",W),n.removeEventListener("load",W),T.ready()}T.fn.ready=function(e){return B.then(e).catch(function(e){T.readyException(e)}),this},T.extend({isReady:!1,readyWait:1,ready:function(e){(!0===e?--T.readyWait:T.isReady)||(T.isReady=!0,!0!==e&&--T.readyWait>0||B.resolveWith(a,[T]))}}),T.ready.then=B.then,"complete"===a.readyState||"loading"!==a.readyState&&!a.documentElement.doScroll?n.setTimeout(T.ready):(a.addEventListener("DOMContentLoaded",W),n.addEventListener("load",W));var Y=function(e,t,n,r,i,o,a){var s=0,u=e.length,c=null==n;if("object"===_(n))for(s in i=!0,n)Y(e,t,s,n[s],!0,o,a);else if(void 0!==r&&(i=!0,y(r)||(a=!0),c&&(a?(t.call(e,r),t=null):(c=t,t=function(e,t,n){return c.call(T(e),n)})),t))for(;s1,null,!0)},removeData:function(e){return this.each(function(){Q.remove(this,e)})}}),T.extend({queue:function(e,t,n){var r;if(e)return t=(t||"fx")+"queue",r=K.get(e,t),n&&(!r||Array.isArray(n)?r=K.access(e,t,T.makeArray(n)):r.push(n)),r||[]},dequeue:function(e,t){t=t||"fx";var n=T.queue(e,t),r=n.length,i=n.shift(),o=T._queueHooks(e,t);"inprogress"===i&&(i=n.shift(),r--),i&&("fx"===t&&n.unshift("inprogress"),delete o.stop,i.call(e,function(){T.dequeue(e,t)},o)),!r&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return K.get(e,n)||K.access(e,n,{empty:T.Callbacks("once memory").add(function(){K.remove(e,[t+"queue",n])})})}}),T.fn.extend({queue:function(e,t){var n=2;return"string"!=typeof e&&(t=e,e="fx",n--),arguments.length\x20\t\r\n\f]+)/i,he=/^$|^module$|\/(?:java|ecma)script/i,ve={option:[1,""],thead:[1,"
+@endif
\ No newline at end of file
diff --git a/packages/Webkul/Admin/src/Resources/views/catalog/products/field-types/multiselect.blade.php b/packages/Webkul/Admin/src/Resources/views/catalog/products/field-types/multiselect.blade.php
index f05e1be55..6d2ce65f8 100755
--- a/packages/Webkul/Admin/src/Resources/views/catalog/products/field-types/multiselect.blade.php
+++ b/packages/Webkul/Admin/src/Resources/views/catalog/products/field-types/multiselect.blade.php
@@ -1,7 +1,7 @@
@stop
\ No newline at end of file
diff --git a/packages/Webkul/Admin/src/Resources/views/customers/groups/create.blade.php b/packages/Webkul/Admin/src/Resources/views/customers/groups/create.blade.php
index 9dae7d4d6..3a6973457 100755
--- a/packages/Webkul/Admin/src/Resources/views/customers/groups/create.blade.php
+++ b/packages/Webkul/Admin/src/Resources/views/customers/groups/create.blade.php
@@ -28,6 +28,13 @@