Cart rule inside promotions, various improvements and fixes. (#964)
* Some syntax issue fixes * Adding discount things inside promotions in admin * routes updated for creating discount rules * fixed customer profile redirect parameter issue * added cart and catalog rule routes to admin section * migrations for discount almost to be finished, final revision left * migrations for discounts complete * catalog rule form underway * catalog rule * Made some dynamic form fields in catalog rule create form * made some changes for custom validations used in ProductForm request class * working on prepopulating the values fields in conditions * need another revisit on discount rules tables and then prepare for actions * removed discounts table * catalog rule form changed to muliti attribute set for single condition * new icons added for promotion and customer note. new action for customer added to take notes on the customers * catalog and cart rule designs stable, now moving towards validations on client side and backend * catalog rules migrations added * catalog rule models added with contracts and proxies * fixed customer group bug in customer registration controller * fixed customer registration bug due to last fix * fixed product card image not found issue * catalog rule translations added * Added migrations for cart rules and catalog rule products their contracts and remaining necessary files related to them. * making cart attributes for cart rules * Added more fields for cart rules * working on conditions for cart rule form * minor changes in migrations related to price rules * currency and locale switcher now only available for a channel on storefront when more than on locale and currency are assigned to that channel * part of conditions on the cart rule form added * daily sync * cart rate migrations updated * Added select and multi select attributes options fetching with ajax on catalog rule form * changed some migrations and data being populated at runtime inside catalog rule form * catalog rule create complete, migrations changes, translations added * catalog rule edit form complete * catalog rule form complete, now moving towards catalog rule products * added delete functionality for catalog rules * added cart rule preferences for coupon codes * cart rule submission problem due to repository issue * Cart rule form and migrations complete * Models and Repositories updated for cart rule usage * base sync with master * designing process to get suitable discount rules * cart rule form completed * added helpers in cart and discount to apply rules on cart at checkout or not * cart rule coupon implementation in progress for discount coupon in shop checkout pages * cart rules working * added coupon box on checkout screen * removed the conditions empty bug * Nearing to completion of coupon based rules * made some changes in cart rule coupon application on checkout related to new designs * some bug fixes * calculation for automatic cart rules complete * non couponable cart rules implemented, now moving on to binding them on frontend * some conditions improvements in couponable cart rules * some bug fixes * removed some bugs from summary blade for cart rule * added the table for cart rule cart for managing rules with cart and removed various bug fixes * some bug fixes * Removed bugs and added coupon based cart rule removal functionality * some bug fixes * cart rule labels refactoring in midway * Cart rule labels bug fixed * removed margin classes from shop to UI * Refactoring cart rule on front end * added checks * Discount rule implemented. * cart rule bug fixes * provision to remove the couponable and non couponable rule had been added * Cart rule frontend work done * altered some frontend variables on onepage checkout * Altered cart rules to some extent
This commit is contained in:
parent
b37ac65e13
commit
6da603530e
|
|
@ -1,6 +1,6 @@
|
|||
APP_NAME=Laravel
|
||||
APP_ENV=local
|
||||
APP_VERSION=0.1.5
|
||||
APP_VERSION=0.1.6
|
||||
APP_KEY=
|
||||
APP_DEBUG=true
|
||||
APP_URL=http://localhost
|
||||
|
|
|
|||
|
|
@ -27,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)
|
||||
|
|
@ -45,6 +47,7 @@ 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**:
|
||||
|
|
@ -137,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.
|
||||
~~~
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@
|
|||
"laravel/dusk": "^4.0",
|
||||
"mockery/mockery": "^1.0",
|
||||
"nunomaduro/collision": "^2.0",
|
||||
"phploc/phploc": "^5.0@dev",
|
||||
"phpunit/phpunit": "^7.0"
|
||||
},
|
||||
"replace": {
|
||||
|
|
@ -57,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": [
|
||||
|
|
@ -84,7 +88,8 @@
|
|||
"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"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
|
|
|
|||
|
|
@ -138,7 +138,7 @@ return [
|
|||
/*
|
||||
Application Version
|
||||
*/
|
||||
'version' => env('APP_VERSION', '0.1.5'),
|
||||
'version' => env('APP_VERSION', '0.1.6'),
|
||||
|
||||
/**
|
||||
* Blacklisting attributes while debugging
|
||||
|
|
@ -245,6 +245,7 @@ return [
|
|||
Webkul\Sales\Providers\SalesServiceProvider::class,
|
||||
Webkul\Tax\Providers\TaxServiceProvider::class,
|
||||
Webkul\API\Providers\APIServiceProvider::class,
|
||||
Webkul\Discount\Providers\DiscountServiceProvider::class
|
||||
],
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -17,6 +17,6 @@ return [
|
|||
\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\User\Providers\ModuleServiceProvider::class,\Webkul\Discount\Providers\ModuleServiceProvider::class
|
||||
]
|
||||
];
|
||||
|
|
@ -1,6 +1,4 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
];
|
||||
|
||||
?>
|
||||
];
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
|
||||
];
|
||||
|
|
@ -2,6 +2,4 @@
|
|||
|
||||
return [
|
||||
|
||||
];
|
||||
|
||||
?>
|
||||
];
|
||||
|
|
@ -29,7 +29,7 @@ return [
|
|||
|
|
||||
*/
|
||||
|
||||
'lifetime' => env('SESSION_LIFETIME', 10),
|
||||
'lifetime' => env('SESSION_LIFETIME', 30),
|
||||
|
||||
'expire_on_close' => true,
|
||||
|
||||
|
|
|
|||
|
|
@ -1,31 +0,0 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class CreateDiscountsTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('discounts', function (Blueprint $table) {
|
||||
$table->increments('id');
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('discounts');
|
||||
}
|
||||
}
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class CreateDiscountRulesTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('discount_rules', function (Blueprint $table) {
|
||||
$table->increments('id');
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('discount_rules');
|
||||
}
|
||||
}
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class CreateDiscountChannelsTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('discount_channels', function (Blueprint $table) {
|
||||
$table->increments('id');
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('discount_channels');
|
||||
}
|
||||
}
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class CreateDiscountCustomerGroupsTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('discount_customer_group', function (Blueprint $table) {
|
||||
$table->increments('id');
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('discount_customer_group');
|
||||
}
|
||||
}
|
||||
|
|
@ -26,4 +26,4 @@
|
|||
}
|
||||
},
|
||||
"minimum-stability": "dev"
|
||||
}
|
||||
}
|
||||
|
|
@ -176,5 +176,24 @@ return [
|
|||
'route' => 'admin.tax-rates.index',
|
||||
'sort' => 2,
|
||||
'icon-class' => '',
|
||||
], [
|
||||
'key' => 'promotion',
|
||||
'name' => 'admin::app.layouts.promotion',
|
||||
'route' => 'admin.cart-rule.index',
|
||||
'sort' => 7,
|
||||
'icon-class' => 'promotion-icon',
|
||||
], [
|
||||
'key' => 'promotion.cart-rule',
|
||||
'name' => 'admin::app.promotion.cart-rule',
|
||||
'route' => 'admin.cart-rule.index',
|
||||
'sort' => 1,
|
||||
'icon-class' => '',
|
||||
]
|
||||
// , [
|
||||
// 'key' => 'promotion.catalog-rule',
|
||||
// 'name' => 'admin::app.promotion.catalog-rule',
|
||||
// 'route' => 'admin.catalog-rule.index',
|
||||
// 'sort' => 1,
|
||||
// 'icon-class' => '',
|
||||
// ]
|
||||
];
|
||||
|
|
@ -0,0 +1,139 @@
|
|||
<?php
|
||||
|
||||
namespace Webkul\Admin\DataGrids;
|
||||
|
||||
use Webkul\Ui\DataGrid\DataGrid;
|
||||
use DB;
|
||||
|
||||
/**
|
||||
* Cart Rule DataGrid class
|
||||
*
|
||||
* @author Prashant Singh <prashant.singh852@webkul.com> @prashant-webkul
|
||||
* @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com)
|
||||
*/
|
||||
class CartRuleDataGrid extends DataGrid
|
||||
{
|
||||
protected $index = 'id'; //the column that needs to be treated as index column
|
||||
|
||||
protected $sortOrder = 'desc'; //asc or desc
|
||||
|
||||
public function prepareQueryBuilder()
|
||||
{
|
||||
$queryBuilder = DB::table('cart_rules')
|
||||
->select('id')
|
||||
->addSelect('id', 'name', 'starts_from', 'ends_till', 'priority', 'usage_limit', 'per_customer', 'status', 'end_other_rules', 'is_guest', 'action_type');
|
||||
|
||||
$this->setQueryBuilder($queryBuilder);
|
||||
}
|
||||
|
||||
public function addColumns()
|
||||
{
|
||||
$this->addColumn([
|
||||
'index' => 'id',
|
||||
'label' => trans('admin::app.datagrid.id'),
|
||||
'type' => 'number',
|
||||
'searchable' => false,
|
||||
'sortable' => true,
|
||||
'filterable' => true
|
||||
]);
|
||||
|
||||
$this->addColumn([
|
||||
'index' => 'name',
|
||||
'label' => trans('admin::app.datagrid.name'),
|
||||
'type' => 'string',
|
||||
'searchable' => false,
|
||||
'sortable' => true,
|
||||
'filterable' => true
|
||||
]);
|
||||
|
||||
$this->addColumn([
|
||||
'index' => 'priority',
|
||||
'label' => trans('admin::app.datagrid.priority'),
|
||||
'type' => 'number',
|
||||
'searchable' => false,
|
||||
'sortable' => true,
|
||||
'filterable' => true,
|
||||
]);
|
||||
|
||||
$this->addColumn([
|
||||
'index' => 'status',
|
||||
'label' => trans('admin::app.datagrid.status'),
|
||||
'type' => 'boolean',
|
||||
'searchable' => false,
|
||||
'sortable' => true,
|
||||
'filterable' => true,
|
||||
'wrapper' => function($value) {
|
||||
if ($value->status == 1)
|
||||
return 'True';
|
||||
else
|
||||
return 'False';
|
||||
}
|
||||
]);
|
||||
|
||||
$this->addColumn([
|
||||
'index' => 'is_guest',
|
||||
'label' => trans('admin::app.datagrid.for-guest'),
|
||||
'type' => 'boolean',
|
||||
'searchable' => false,
|
||||
'sortable' => true,
|
||||
'filterable' => true,
|
||||
'wrapper' => function($value) {
|
||||
if ($value->is_guest == 1)
|
||||
return 'True';
|
||||
else
|
||||
return 'False';
|
||||
}
|
||||
]);
|
||||
|
||||
$this->addColumn([
|
||||
'index' => 'end_other_rules',
|
||||
'label' => 'End Other Rules',
|
||||
'type' => 'boolean',
|
||||
'searchable' => false,
|
||||
'sortable' => true,
|
||||
'filterable' => true,
|
||||
'wrapper' => function($value) {
|
||||
if ($value->end_other_rules == 1)
|
||||
return 'True';
|
||||
else
|
||||
return 'False';
|
||||
}
|
||||
]);
|
||||
|
||||
$this->addColumn([
|
||||
'index' => 'action_type',
|
||||
'label' => 'Action Type',
|
||||
'type' => 'string',
|
||||
'searchable' => false,
|
||||
'sortable' => true,
|
||||
'filterable' => true
|
||||
]);
|
||||
}
|
||||
|
||||
public function prepareActions()
|
||||
{
|
||||
$this->addAction([
|
||||
'type' => 'Edit',
|
||||
'method' => 'GET', //use post only for redirects only
|
||||
'route' => 'admin.cart-rule.edit',
|
||||
'icon' => 'icon pencil-lg-icon'
|
||||
]);
|
||||
|
||||
$this->addAction([
|
||||
'type' => 'Delete',
|
||||
'method' => 'POST', //use post only for requests other than redirects
|
||||
'route' => 'admin.cart-rule.delete',
|
||||
'icon' => 'icon trash-icon'
|
||||
]);
|
||||
}
|
||||
|
||||
public function prepareMassActions()
|
||||
{
|
||||
// $this->addMassAction([
|
||||
// 'type' => 'delete',
|
||||
// 'action' => route('admin.catalog.attributes.massdelete'),
|
||||
// 'label' => 'Delete',
|
||||
// 'method' => 'DELETE'
|
||||
// ]);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,149 @@
|
|||
<?php
|
||||
|
||||
namespace Webkul\Admin\DataGrids;
|
||||
|
||||
use Webkul\Ui\DataGrid\DataGrid;
|
||||
use DB;
|
||||
|
||||
/**
|
||||
* Catalog Rule DataGrid class
|
||||
*
|
||||
* @author Prashant Singh <prashant.singh852@webkul.com> @prashant-webkul
|
||||
* @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com)
|
||||
*/
|
||||
class CatalogRuleDataGrid extends DataGrid
|
||||
{
|
||||
protected $index = 'id'; //the column that needs to be treated as index column
|
||||
|
||||
protected $sortOrder = 'desc'; //asc or desc
|
||||
|
||||
public function prepareQueryBuilder()
|
||||
{
|
||||
$queryBuilder = DB::table('catalog_rules')
|
||||
->select('id')
|
||||
->addSelect('id', 'name', 'starts_from', 'ends_till', 'priority', 'status', 'end_other_rules', 'action_type');
|
||||
|
||||
$this->setQueryBuilder($queryBuilder);
|
||||
}
|
||||
|
||||
public function addColumns()
|
||||
{
|
||||
$this->addColumn([
|
||||
'index' => 'id',
|
||||
'label' => trans('admin::app.datagrid.id'),
|
||||
'type' => 'number',
|
||||
'searchable' => false,
|
||||
'sortable' => true,
|
||||
'filterable' => true
|
||||
]);
|
||||
|
||||
$this->addColumn([
|
||||
'index' => 'name',
|
||||
'label' => trans('admin::app.datagrid.name'),
|
||||
'type' => 'string',
|
||||
'searchable' => false,
|
||||
'sortable' => true,
|
||||
'filterable' => true
|
||||
]);
|
||||
|
||||
$this->addColumn([
|
||||
'index' => 'starts_from',
|
||||
'label' => trans('admin::app.datagrid.starts-from'),
|
||||
'type' => 'date',
|
||||
'searchable' => false,
|
||||
'sortable' => true,
|
||||
'filterable' => true
|
||||
]);
|
||||
|
||||
$this->addColumn([
|
||||
'index' => 'ends_till',
|
||||
'label' => trans('admin::app.datagrid.ends-till'),
|
||||
'type' => 'date',
|
||||
'searchable' => false,
|
||||
'sortable' => true,
|
||||
'filterable' => true
|
||||
]);
|
||||
|
||||
$this->addColumn([
|
||||
'index' => 'priority',
|
||||
'label' => trans('admin::app.datagrid.priority'),
|
||||
'type' => 'number',
|
||||
'searchable' => false,
|
||||
'sortable' => true,
|
||||
'filterable' => true
|
||||
]);
|
||||
|
||||
$this->addColumn([
|
||||
'index' => 'status',
|
||||
'label' => trans('admin::app.datagrid.status'),
|
||||
'type' => 'boolean',
|
||||
'searchable' => false,
|
||||
'sortable' => true,
|
||||
'filterable' => true,
|
||||
'wrapper' => function ($value) {
|
||||
if ($value->status == 1)
|
||||
return 'True';
|
||||
else
|
||||
return 'False';
|
||||
}
|
||||
]);
|
||||
|
||||
$this->addColumn([
|
||||
'index' => 'end_other_rules',
|
||||
'label' => 'End Other Rules',
|
||||
'type' => 'boolean',
|
||||
'searchable' => false,
|
||||
'sortable' => true,
|
||||
'filterable' => true,
|
||||
'wrapper' => function ($value) {
|
||||
if ($value->end_other_rules == 1)
|
||||
return 'True';
|
||||
else
|
||||
return 'False';
|
||||
}
|
||||
]);
|
||||
|
||||
$this->addColumn([
|
||||
'index' => 'action_type',
|
||||
'label' => 'Action Type',
|
||||
'type' => 'string',
|
||||
'searchable' => false,
|
||||
'sortable' => true,
|
||||
'filterable' => true,
|
||||
'wrapper' => function ($value) {
|
||||
foreach(config('pricerules.catalog.actions') as $key => $action) {
|
||||
if ($value->action_type == $key) {
|
||||
return trans($action);
|
||||
}
|
||||
}
|
||||
}
|
||||
]);
|
||||
}
|
||||
|
||||
public function prepareActions()
|
||||
{
|
||||
$this->addAction([
|
||||
'type' => 'Edit',
|
||||
'method' => 'GET', //use post only for redirects only
|
||||
'route' => 'admin.catalog-rule.edit',
|
||||
'icon' => 'icon pencil-lg-icon'
|
||||
]);
|
||||
|
||||
$this->addAction([
|
||||
'type' => 'Delete',
|
||||
'method' => 'POST', //use post only for requests other than redirects
|
||||
'route' => 'admin.catalog-rule.delete',
|
||||
'icon' => 'icon trash-icon'
|
||||
]);
|
||||
}
|
||||
|
||||
public function prepareMassActions()
|
||||
{
|
||||
// $this->addMassAction([
|
||||
// 'type' => 'delete',
|
||||
// 'action' => route('admin.catalog.attributes.massdelete'),
|
||||
// 'label' => 'Delete',
|
||||
// 'method' => 'DELETE'
|
||||
// ]);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,96 @@
|
|||
<?php
|
||||
|
||||
namespace Webkul\Admin\DataGrids;
|
||||
|
||||
use Webkul\Ui\DataGrid\DataGrid;
|
||||
use DB;
|
||||
|
||||
/**
|
||||
* Cart Rule DataGrid class
|
||||
*
|
||||
* @author Prashant Singh <prashant.singh852@webkul.com> @prashant-webkul
|
||||
* @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com)
|
||||
*/
|
||||
class CartRuleCouponsDataGrid extends DataGrid
|
||||
{
|
||||
protected $index = 'id'; //the column that needs to be treated as index column
|
||||
|
||||
protected $sortOrder = 'desc'; //asc or desc
|
||||
|
||||
public function prepareQueryBuilder()
|
||||
{
|
||||
$queryBuilder = DB::table('cart_rules')
|
||||
->select('id')
|
||||
->addSelect('id', 'code', 'limit', 'usage_per_customer', 'usage_throttle');
|
||||
|
||||
$this->setQueryBuilder($queryBuilder);
|
||||
}
|
||||
|
||||
public function addColumns()
|
||||
{
|
||||
$this->addColumn([
|
||||
'index' => 'id',
|
||||
'label' => trans('admin::app.datagrid.id'),
|
||||
'type' => 'number',
|
||||
'searchable' => false,
|
||||
'sortable' => true,
|
||||
'filterable' => true
|
||||
]);
|
||||
|
||||
$this->addColumn([
|
||||
'index' => 'code',
|
||||
'label' => trans('admin::app.datagrid.code'),
|
||||
'type' => 'string',
|
||||
'searchable' => false,
|
||||
'sortable' => true,
|
||||
'filterable' => true
|
||||
]);
|
||||
|
||||
$this->addColumn([
|
||||
'index' => 'limit',
|
||||
'label' => trans('admin::app.datagrid.limit'),
|
||||
'type' => 'string',
|
||||
'searchable' => false,
|
||||
'sortable' => true,
|
||||
'filterable' => true
|
||||
]);
|
||||
|
||||
$this->addColumn([
|
||||
'index' => 'limit',
|
||||
'label' => trans('admin::app.datagrid.limit'),
|
||||
'type' => 'string',
|
||||
'searchable' => false,
|
||||
'sortable' => true,
|
||||
'filterable' => true
|
||||
]);
|
||||
|
||||
$this->addColumn([
|
||||
'index' => 'usage_per_customer',
|
||||
'label' => trans('admin::app.datagrid.usage-per-customer'),
|
||||
'type' => 'boolean',
|
||||
'searchable' => false,
|
||||
'sortable' => true,
|
||||
'filterable' => true,
|
||||
'wrapper' => function($value) {
|
||||
if ($value->end_other_rules == 1)
|
||||
return 'true';
|
||||
else
|
||||
return 'false';
|
||||
}
|
||||
]);
|
||||
}
|
||||
|
||||
public function prepareActions()
|
||||
{
|
||||
}
|
||||
|
||||
public function prepareMassActions()
|
||||
{
|
||||
// $this->addMassAction([
|
||||
// 'type' => 'delete',
|
||||
// 'action' => route('admin.catalog.attributes.massdelete'),
|
||||
// 'label' => 'Delete',
|
||||
// 'method' => 'DELETE'
|
||||
// ]);
|
||||
}
|
||||
}
|
||||
|
|
@ -76,14 +76,24 @@ class CustomerDataGrid extends DataGrid
|
|||
'type' => 'Edit',
|
||||
'method' => 'GET', // use GET request only for redirect purposes
|
||||
'route' => 'admin.customer.edit',
|
||||
'icon' => 'icon pencil-lg-icon'
|
||||
'icon' => 'icon pencil-lg-icon',
|
||||
'title' => trans('admin::app.customers.customers.edit-help-title')
|
||||
]);
|
||||
|
||||
$this->addAction([
|
||||
'type' => 'Delete',
|
||||
'method' => 'POST', // use GET request only for redirect purposes
|
||||
'route' => 'admin.customer.delete',
|
||||
'icon' => 'icon trash-icon'
|
||||
'icon' => 'icon trash-icon',
|
||||
'title' => trans('admin::app.customers.customers.delete-help-title')
|
||||
]);
|
||||
|
||||
$this->addAction([
|
||||
'type' => 'Add Note',
|
||||
'method' => 'GET',
|
||||
'route' => 'admin.customer.note.create',
|
||||
'icon' => 'icon note-icon',
|
||||
'title' => trans('admin::app.customers.note.help-title')
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
@ -186,4 +186,42 @@ class CustomerController extends Controller
|
|||
|
||||
return response()->json(['message' => false], 400);
|
||||
}
|
||||
|
||||
/**
|
||||
* To load the note taking screen for the customers
|
||||
*
|
||||
* @return View
|
||||
*/
|
||||
public function createNote($id)
|
||||
{
|
||||
$customer = $this->customer->find($id);
|
||||
|
||||
return view($this->_config['view'])->with('customer', $customer);
|
||||
}
|
||||
|
||||
/**
|
||||
* To store the response of the note in storage
|
||||
*
|
||||
* @return Redirect
|
||||
*/
|
||||
public function storeNote()
|
||||
{
|
||||
$this->validate(request(), [
|
||||
'notes' => 'required|string'
|
||||
]);
|
||||
|
||||
$customer = $this->customer->find(request()->input('_customer'));
|
||||
|
||||
$noteTaken = $customer->update([
|
||||
'notes' => request()->input('notes')
|
||||
]);
|
||||
|
||||
if ($noteTaken) {
|
||||
session()->flash('success', 'Note taken');
|
||||
} else {
|
||||
session()->flash('error', 'Note cannot be taken');
|
||||
}
|
||||
|
||||
return redirect()->route($this->_config['redirect']);
|
||||
}
|
||||
}
|
||||
|
|
@ -60,6 +60,14 @@ Route::group(['middleware' => ['web']], function () {
|
|||
'view' => 'admin::customers.edit'
|
||||
])->name('admin.customer.edit');
|
||||
|
||||
Route::get('customers/note/{id}', 'Webkul\Admin\Http\Controllers\Customer\CustomerController@createNote')->defaults('_config',[
|
||||
'view' => 'admin::customers.note'
|
||||
])->name('admin.customer.note.create');
|
||||
|
||||
Route::put('customers/note/{id}', 'Webkul\Admin\Http\Controllers\Customer\CustomerController@storeNote')->defaults('_config',[
|
||||
'redirect' => 'admin.customer.index'
|
||||
])->name('admin.customer.note.store');
|
||||
|
||||
Route::put('customers/edit/{id}', 'Webkul\Admin\Http\Controllers\Customer\CustomerController@update')->defaults('_config', [
|
||||
'redirect' => 'admin.customer.index'
|
||||
])->name('admin.customer.update');
|
||||
|
|
@ -186,7 +194,6 @@ Route::group(['middleware' => ['web']], function () {
|
|||
])->name('admin.sales.shipments.view');
|
||||
});
|
||||
|
||||
|
||||
// Catalog Routes
|
||||
Route::prefix('catalog')->group(function () {
|
||||
Route::get('/sync', 'Webkul\Product\Http\Controllers\ProductController@sync');
|
||||
|
|
@ -609,6 +616,57 @@ Route::group(['middleware' => ['web']], function () {
|
|||
//DataGrid Export
|
||||
Route::post('admin/export', 'Webkul\Admin\Http\Controllers\ExportController@export')->name('admin.datagrid.export');
|
||||
|
||||
Route::prefix('promotion')->group(function () {
|
||||
// Route::get('/catalog-rule', 'Webkul\Discount\Http\Controllers\CatalogRuleController@index')->defaults('_config', [
|
||||
// 'view' => 'admin::promotions.catalog-rule.index'
|
||||
// ])->name('admin.catalog-rule.index');
|
||||
|
||||
// Route::get('/catalog-rule/create', 'Webkul\Discount\Http\Controllers\CatalogRuleController@create')->defaults('_config', [
|
||||
// 'view' => 'admin::promotions.catalog-rule.create'
|
||||
// ])->name('admin.catalog-rule.create');
|
||||
|
||||
// Route::post('/catalog-rule/create', 'Webkul\Discount\Http\Controllers\CatalogRuleController@store')->defaults('_config', [
|
||||
// 'redirect' => 'admin.catalog-rule.index'
|
||||
// ])->name('admin.catalog-rule.store');
|
||||
|
||||
// Route::get('/catalog-rule/edit/{id}', 'Webkul\Discount\Http\Controllers\CatalogRuleController@edit')->defaults('_config', [
|
||||
// 'view' => 'admin::promotions.catalog-rule.edit'
|
||||
// ])->name('admin.catalog-rule.edit');
|
||||
|
||||
// Route::post('/catalog-rule/edit/{id}', 'Webkul\Discount\Http\Controllers\CatalogRuleController@update')->defaults('_config', [
|
||||
// 'redirect' => 'admin.catalog-rule.index'
|
||||
// ])->name('admin.catalog-rule.update');
|
||||
|
||||
// Route::get('/catalog-rule/apply', 'Webkul\Discount\Http\Controllers\CatalogRuleController@applyRules')->defaults('_config', [
|
||||
// 'view' => 'admin::promotions.catalog-rule.index'
|
||||
// ])->name('admin.catalog-rule.apply');
|
||||
|
||||
// Route::post('/catalog-rule/delete/{id}', 'Webkul\Discount\Http\Controllers\CatalogRuleController@destroy')->name('admin.catalog-rule.delete');
|
||||
|
||||
// Route::post('fetch/options', 'Webkul\Discount\Http\Controllers\CatalogRuleController@fetchAttributeOptions')->name('admin.catalog-rule.options');
|
||||
|
||||
Route::get('/cart-rule', 'Webkul\Discount\Http\Controllers\CartRuleController@index')->defaults('_config', [
|
||||
'view' => 'admin::promotions.cart-rule.index'
|
||||
])->name('admin.cart-rule.index');
|
||||
|
||||
Route::get('/cart-rule/create', 'Webkul\Discount\Http\Controllers\CartRuleController@create')->defaults('_config', [
|
||||
'view' => 'admin::promotions.cart-rule.create'
|
||||
])->name('admin.cart-rule.create');
|
||||
|
||||
Route::post('/cart-rule/store', 'Webkul\Discount\Http\Controllers\CartRuleController@store')->defaults('_config', [
|
||||
'redirect' => 'admin.cart-rule.index'
|
||||
])->name('admin.cart-rule.store');
|
||||
|
||||
Route::get('/cart-rule/edit/{id}', 'Webkul\Discount\Http\Controllers\CartRuleController@edit')->defaults('_config', [
|
||||
'view' => 'admin::promotions.cart-rule.edit'
|
||||
])->name('admin.cart-rule.edit');
|
||||
|
||||
Route::post('/cart-rule/update/{id}', 'Webkul\Discount\Http\Controllers\CartRuleController@update')->defaults('_config', [
|
||||
'redirect' => 'admin.cart-rule.index'
|
||||
])->name('admin.cart-rule.update');
|
||||
|
||||
Route::post('/cart-rule/delete/{id}', 'Webkul\Discount\Http\Controllers\CartRuleController@destroy')->name('admin.cart-rule.delete');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -173,23 +173,6 @@ body {
|
|||
height: 90%;
|
||||
}
|
||||
|
||||
// .close-nav-aside {
|
||||
// width: 100%;
|
||||
// padding: 20px;
|
||||
// text-align: center;
|
||||
// border: 1px solid $border-color;
|
||||
|
||||
// .icon {
|
||||
// height: 24px;
|
||||
// width: 24px;
|
||||
// }
|
||||
// }
|
||||
|
||||
// .close-nav-aside:hover {
|
||||
// background: white;
|
||||
// cursor: pointer;
|
||||
// }
|
||||
|
||||
a {
|
||||
padding: 15px;
|
||||
display: block;
|
||||
|
|
@ -235,7 +218,7 @@ body {
|
|||
width: 24px;
|
||||
height: 24px;
|
||||
cursor: pointer;
|
||||
margin-top: 5px;
|
||||
margin-top: -2px;
|
||||
}
|
||||
|
||||
h1 {
|
||||
|
|
@ -278,6 +261,54 @@ body {
|
|||
}
|
||||
}
|
||||
|
||||
.control-container {
|
||||
border: 1px solid #c7c7c7;
|
||||
padding: 10px;
|
||||
width: 63%;
|
||||
|
||||
.title-bar {
|
||||
display: inline-flex;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
|
||||
.icon {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.icon.cross-icon {
|
||||
height: 24px;
|
||||
width: 24px;
|
||||
}
|
||||
}
|
||||
|
||||
.control-group {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-content: center;
|
||||
justify-content: flex-start;
|
||||
padding: 10px;
|
||||
border: 1px solid #c7c7c7;
|
||||
border-radius: 2px;
|
||||
margin-right: 15px;
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
|
||||
.control-group::last-child {
|
||||
margin-right: 0px;
|
||||
}
|
||||
}
|
||||
|
||||
.boolean-control-container {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: flex-start;
|
||||
width: 750px;
|
||||
|
||||
.control-group {
|
||||
width: 200px;
|
||||
}
|
||||
}
|
||||
|
||||
.control-group {
|
||||
label {
|
||||
width: 70%;
|
||||
|
|
|
|||
|
|
@ -39,7 +39,9 @@ return [
|
|||
'sliders' => 'Sliders',
|
||||
'taxes' => 'Taxes',
|
||||
'tax-categories' => 'Tax Categories',
|
||||
'tax-rates' => 'Tax Rates'
|
||||
'tax-rates' => 'Tax Rates',
|
||||
'promotion' => 'Promotions',
|
||||
'discount' => 'Discount'
|
||||
],
|
||||
|
||||
'acl' => [
|
||||
|
|
@ -151,7 +153,12 @@ return [
|
|||
'role' => 'Role',
|
||||
'sub-total' => 'Sub Total',
|
||||
'no-of-products' => 'Number of Products',
|
||||
'attribute-family' => 'Attribute Family'
|
||||
'attribute-family' => 'Attribute Family',
|
||||
'starts-from' => 'Starts From',
|
||||
'ends-till' => 'Ends Till',
|
||||
'per-cust' => 'Per Customer',
|
||||
'usage-throttle' => 'Usage Times',
|
||||
'for-guest' => 'For Guest'
|
||||
],
|
||||
|
||||
'account' => [
|
||||
|
|
@ -732,6 +739,14 @@ return [
|
|||
'is_user_defined' => 'User Defined',
|
||||
'yes' => 'Yes'
|
||||
],
|
||||
|
||||
'note' => [
|
||||
'title' => 'Add Note',
|
||||
'save-note' => 'Save Note',
|
||||
'enter-note' => 'Enter Note',
|
||||
'help-title' => 'Add Note On This Customer'
|
||||
],
|
||||
|
||||
'customers' => [
|
||||
'add-title' => 'Add Customer',
|
||||
'edit-title' => 'Edit Customer',
|
||||
|
|
@ -752,7 +767,10 @@ return [
|
|||
'female' => 'Female',
|
||||
'phone' => 'Phone',
|
||||
'group-default' => 'Cannot delete the default group.',
|
||||
'edit-help-title' => 'Edit Customer',
|
||||
'delete-help-title' => 'Delete Customer'
|
||||
],
|
||||
|
||||
'reviews' => [
|
||||
'title' => 'Reviews',
|
||||
'edit-title' => 'Edit Review',
|
||||
|
|
@ -777,6 +795,85 @@ return [
|
|||
]
|
||||
],
|
||||
|
||||
'promotion' => [
|
||||
'catalog-rule' => 'Catalog Rules',
|
||||
'cart-rule' => 'Cart Rule',
|
||||
'add-catalog-rule' => 'Add Catalog Rule',
|
||||
'add-cart-rule' => 'Add Cart Rule',
|
||||
'edit-cart-rule' => 'Edit Cart Rule',
|
||||
'edit-catalog-rule' => 'Edit Catalog Rule',
|
||||
'create-catalog-rule' => 'Create Catalog Rule',
|
||||
'create-cart-rule' => 'Create Cart Rule',
|
||||
'save-btn-title' => 'Create',
|
||||
'edit-btn-title' => 'Edit',
|
||||
'select-attr' => 'Select Attribute',
|
||||
'select-attr-fam' => 'Select Attribute Family',
|
||||
'select-cart-attr' => 'Select Cart Attribute',
|
||||
'general-info' => [
|
||||
'name' => 'Rule Name',
|
||||
'description' => 'Description',
|
||||
'starts-from' => 'Start',
|
||||
'ends-till' => 'End',
|
||||
'channels' => 'Channels',
|
||||
'cust-groups' => 'Customer Groups',
|
||||
'priority' => 'Priority',
|
||||
'add-condition' => 'Add Conditions',
|
||||
'disc_amt' => 'Discount Amount',
|
||||
'disc_percent' => 'Discount Percentage',
|
||||
'is-coupon' => 'Use Coupon',
|
||||
'is-coupon-yes' => 'Yes',
|
||||
'is-coupon-no' => 'No',
|
||||
'uses-per-cust' => 'Uses per customer',
|
||||
'all' => 'All',
|
||||
'any' => 'Any',
|
||||
'end-other-rules' => 'End other rules',
|
||||
'status' => 'Is Active',
|
||||
'all-conditions-true' => 'Assuming all conditions are true',
|
||||
'assuming' => 'Assuming',
|
||||
'any' => 'Any',
|
||||
'all' => 'All',
|
||||
'conditions' => 'Conditions',
|
||||
'are' => 'are',
|
||||
'true' => 'true',
|
||||
'false' => 'false',
|
||||
'limit' => 'Usage Limit',
|
||||
'specific-coupon' => 'Specific Coupon(Check) / Auto Generated(Unheck)',
|
||||
'free-shipping' => 'Free Shipping',
|
||||
'is-guest' => 'For Guests',
|
||||
'disc_qty' => 'Max. Quantity Allowed To Be Discounted',
|
||||
],
|
||||
|
||||
'status' => [
|
||||
'success' => 'Success! rule created',
|
||||
'success-coupon' => 'Success! rule created along with coupon',
|
||||
'failed' => 'Error! failed to create rule',
|
||||
'update-success' => 'Success! rule updated',
|
||||
'update-coupon-success' => 'Success! rule updated along with coupon',
|
||||
'update-failed' => 'Error! cannot update',
|
||||
'delete-success' => 'Sucess! rule deleted',
|
||||
'delete-failed' => 'Error! cannot delete',
|
||||
'coupon-applied' => 'Coupon used',
|
||||
'coupon-failed' => 'Coupon failed to apply',
|
||||
'no-coupon' => '* Coupon not applicable',
|
||||
'coupon-removed' => 'Coupon removed successfully',
|
||||
'coupon-remove-failed' => 'Coupon removal failed'
|
||||
],
|
||||
|
||||
'catalog' => [
|
||||
'name' => 'Name',
|
||||
'description' => 'Description',
|
||||
'apply-percent' => 'Apply as percentage',
|
||||
'apply-fixed' => 'Apply as fixed amount',
|
||||
'adjust-to-percent' => 'Adjust to percentage',
|
||||
'adjust-to-value' => 'Adjust to discount value',
|
||||
'condition-missing' => 'Please check conditons, some values might be missing'
|
||||
],
|
||||
'cart' => [
|
||||
'buy-atleast' => 'Buy Atleast (N)',
|
||||
'apply-to-shipping' => 'Apply to shipping'
|
||||
]
|
||||
],
|
||||
|
||||
'error' => [
|
||||
'go-to-home' => 'GO TO HOME',
|
||||
'in-maitainace' => 'In Maintenance',
|
||||
|
|
|
|||
|
|
@ -677,6 +677,14 @@ return [
|
|||
'is_user_defined' => 'Usuário Definido',
|
||||
'yes' => 'Sim'
|
||||
],
|
||||
|
||||
'note' => [
|
||||
'title' => 'Add Note',
|
||||
'save-note' => 'Save Note',
|
||||
'enter-note' => 'Enter Note',
|
||||
'help-title' => 'Add Note On This Customer'
|
||||
],
|
||||
|
||||
'customers' => [
|
||||
'add-title' => 'Add Cliente',
|
||||
'edit-title' => 'Editar Cliente',
|
||||
|
|
|
|||
|
|
@ -1,24 +0,0 @@
|
|||
@extends('admin::layouts.content')
|
||||
|
||||
@section('page_title')
|
||||
{{ __('admin::app.customers.customers.title') }}
|
||||
@stop
|
||||
|
||||
@section('content')
|
||||
<div class="content">
|
||||
<div class="page-header">
|
||||
<div class="page-title">
|
||||
<h1>{{ __('admin::app.customers.customers.title') }}</h1>
|
||||
</div>
|
||||
<div class="page-action">
|
||||
<a href="{{ route('admin.customer.create') }}" class="btn btn-lg btn-primary">
|
||||
{{ __('admin::app.customers.customers.add-title') }}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="page-content">
|
||||
<h1>Test the grid here</h1>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
|
|
@ -22,7 +22,7 @@
|
|||
{{ __('admin::app.catalog.products.related-products') }}
|
||||
</label>
|
||||
|
||||
<input type="text" class="control" autocomplete="off" v-model="search_term[key]" placeholder="{{ __('admin::app.catalog.products.product-search-hint') }}" v-on:keyup="search(key)">
|
||||
<input type="text" class="control" autocomplete="off" v-model="search_term[key]" placeholder="{{ __('admin::app.catalog.products.product-search-hint') }}" v-on:keyup="search(key)">
|
||||
|
||||
<div class="linked-product-search-result">
|
||||
<ul>
|
||||
|
|
|
|||
|
|
@ -21,9 +21,6 @@
|
|||
{!! view_render_event('bagisto.admin.catalog.products.list.before') !!}
|
||||
|
||||
<div class="page-content">
|
||||
{{-- @inject('product','Webkul\Admin\DataGrids\ProductDataGrid')
|
||||
{!! $product->render() !!} --}}
|
||||
|
||||
@inject('products', 'Webkul\Admin\DataGrids\ProductDataGrid')
|
||||
{!! $products->render() !!}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@
|
|||
|
||||
<div class="page-content">
|
||||
@inject('customerGrid','Webkul\Admin\DataGrids\CustomerDataGrid')
|
||||
|
||||
|
||||
{!! $customerGrid->render() !!}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,45 @@
|
|||
@extends('admin::layouts.content')
|
||||
|
||||
@section('page_title')
|
||||
{{ __('admin::app.customers.note.title') }}
|
||||
@stop
|
||||
|
||||
@section('content')
|
||||
<div class="content">
|
||||
<form method="POST" action="{{ route('admin.customer.note.store', $customer->id) }}">
|
||||
<div class="page-header">
|
||||
<div class="page-title">
|
||||
<h1>
|
||||
<i class="icon angle-left-icon back-link" onclick="history.length > 1 ? history.go(-1) : window.location = '{{ url('/admin/dashboard') }}';"></i>
|
||||
|
||||
{{ __('admin::app.customers.note.title') }}
|
||||
</h1>
|
||||
</div>
|
||||
|
||||
<div class="page-action">
|
||||
<button type="submit" class="btn btn-lg btn-primary">
|
||||
{{ __('admin::app.customers.note.save-note') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="page-content">
|
||||
<div class="form-container">
|
||||
@csrf()
|
||||
|
||||
<input name="_method" type="hidden" value="PUT">
|
||||
|
||||
<input name="_customer" type="hidden" value="{{ $customer->id }}">
|
||||
|
||||
<div class="control-group" :class="[errors.has('channel_id') ? 'has-error' : '']">
|
||||
<label for="notes">{{ __('admin::app.customers.note.enter-note') }} for {{ $customer->name }}</label>
|
||||
|
||||
<textarea class="control" name="notes" v-validate="'required'">{{ $customer->notes }}</textarea>
|
||||
|
||||
<span class="control-error" v-if="errors.has('notes')">@{{ errors.first('notes') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
@stop
|
||||
|
|
@ -62,7 +62,7 @@
|
|||
@elseif ($error = session('error'))
|
||||
window.flashMessages = [{'type': 'alert-error', 'message': "{{ $error }}" }];
|
||||
@elseif ($info = session('info'))
|
||||
window.flashMessages = [{'type': 'alert-error', 'message': "{{ $info }}" }];
|
||||
window.flashMessages = [{'type': 'alert-info', 'message': "{{ $info }}" }];
|
||||
@endif
|
||||
|
||||
window.serverErrors = [];
|
||||
|
|
|
|||
|
|
@ -0,0 +1,539 @@
|
|||
@extends('admin::layouts.content')
|
||||
|
||||
@section('page_title')
|
||||
{{ __('admin::app.promotion.add-cart-rule') }}
|
||||
@stop
|
||||
|
||||
@section('content')
|
||||
|
||||
<div class="content">
|
||||
<cart-rule></cart-rule>
|
||||
</div>
|
||||
|
||||
@push('scripts')
|
||||
<script type="text/x-template" id="cart-rule-form-template">
|
||||
<form method="POST" action="{{ route('admin.cart-rule.store') }}" @submit.prevent="onSubmit">
|
||||
@csrf
|
||||
|
||||
<div class="page-header">
|
||||
<div class="page-title">
|
||||
<h1>
|
||||
<i class="icon angle-left-icon back-link" onclick="history.length > 1 ? history.go(-1) : window.location = '{{ url('/admin/dashboard') }}';"></i>
|
||||
|
||||
{{ __('admin::app.promotion.add-cart-rule') }}
|
||||
</h1>
|
||||
</div>
|
||||
|
||||
<div class="page-action">
|
||||
<button type="submit" class="btn btn-lg btn-primary">
|
||||
{{ __('admin::app.promotion.save-btn-title') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="page-content">
|
||||
<div class="form-container">
|
||||
<div>
|
||||
@csrf()
|
||||
|
||||
<accordian :active="true" title="Information">
|
||||
<div slot="body">
|
||||
<div class="control-group" :class="[errors.has('name') ? 'has-error' : '']">
|
||||
<label for="name" class="required">{{ __('admin::app.promotion.general-info.name') }}</label>
|
||||
|
||||
<input type="text" class="control" name="name" v-model="name" v-validate="'required|alpha_spaces'" value="{{ old('name') }}" data-vv-as=""{{ __('admin::app.promotion.general-info.name') }}"">
|
||||
|
||||
<span class="control-error" v-if="errors.has('name')">@{{ errors.first('name') }}</span>
|
||||
</div>
|
||||
|
||||
<div class="control-group" :class="[errors.has('description') ? 'has-error' : '']">
|
||||
<label for="description">{{ __('admin::app.promotion.general-info.description') }}</label>
|
||||
|
||||
<textarea class="control" name="description" v-model="description" v-validate="'alpha_spaces'" value="{{ old('description') }}" data-vv-as=""{{ __('admin::app.promotion.general-info.description') }}""></textarea>
|
||||
|
||||
<span class="control-error" v-if="errors.has('description')">@{{ errors.first('description') }}</span>
|
||||
</div>
|
||||
|
||||
<datetime :name="starts_from">
|
||||
<div class="control-group" :class="[errors.has('starts_from') ? 'has-error' : '']">
|
||||
<label for="starts_from">{{ __('admin::app.promotion.general-info.starts-from') }}</label>
|
||||
|
||||
<input type="text" class="control" v-model="starts_from" name="starts_from" data-vv-as=""{{ __('admin::app.promotion.general-info.starts-from') }}"">
|
||||
|
||||
<span class="control-error" v-if="errors.has('starts_from')">@{{ errors.first('starts_from') }}</span>
|
||||
</div>
|
||||
</datetime>
|
||||
|
||||
<datetime :name="starts_from">
|
||||
<div class="control-group" :class="[errors.has('ends_till') ? 'has-error' : '']">
|
||||
<label for="ends_till">{{ __('admin::app.promotion.general-info.ends-till') }}</label>
|
||||
|
||||
<input type="text" class="control" v-model="ends_till" name="ends_till" data-vv-as=""{{ __('admin::app.promotion.general-info.ends-till') }}"">
|
||||
|
||||
<span class="control-error" v-if="errors.has('ends_till')">@{{ errors.first('ends_till') }}</span>
|
||||
</div>
|
||||
</datetime>
|
||||
|
||||
{{-- <div class="control-group" :class="[errors.has('customer_groups[]') ? 'has-error' : '']">
|
||||
<label for="customer_groups" class="required">{{ __('admin::app.promotion.general-info.cust-groups') }}</label>
|
||||
|
||||
<select type="text" class="control" name="customer_groups[]" v-model="customer_groups" v-validate="'required'" value="{{ old('customer_groups[]') }}" data-vv-as=""{{ __('admin::app.promotion.general-info.cust-groups') }}"" multiple="multiple">
|
||||
<option disabled="disabled">Select Customer Groups</option>
|
||||
@foreach(app('Webkul\Customer\Repositories\CustomerGroupRepository')->all() as $channel)
|
||||
<option value="{{ $channel->id }}">{{ $channel->name }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
|
||||
<span class="control-error" v-if="errors.has('customer_groups')">@{{ errors.first('customer_groups') }}</span>
|
||||
</div> --}}
|
||||
|
||||
<div class="control-group" :class="[errors.has('channels[]') ? 'has-error' : '']">
|
||||
<label for="channels" class="required">{{ __('admin::app.promotion.general-info.channels') }}</label>
|
||||
|
||||
<select type="text" class="control" name="channels[]" v-model="channels" v-validate="'required'" value="{{ old('channels[]') }}" data-vv-as=""{{ __('admin::app.promotion.general-info.channels') }}"" multiple="multiple">
|
||||
<option disabled="disabled">Select Channels</option>
|
||||
@foreach(app('Webkul\Core\Repositories\ChannelRepository')->all() as $channel)
|
||||
<option value="{{ $channel->id }}">{{ $channel->name }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
|
||||
<span class="control-error" v-if="errors.has('channels')">@{{ errors.first('channels') }}</span>
|
||||
</div>
|
||||
|
||||
<div class="control-group" :class="[errors.has('status') ? 'has-error' : '']">
|
||||
<label for="status" class="required">{{ __('admin::app.promotion.general-info.status') }}</label>
|
||||
|
||||
<select type="text" class="control" name="status" v-model="status" v-validate="'required'" data-vv-as=""{{ __('admin::app.promotion.general-info.status') }}"">
|
||||
<option disabled="disabled">Select status</option>
|
||||
<option value="1">Yes</option>
|
||||
<option value="0">No</option>
|
||||
</select>
|
||||
|
||||
<span class="control-error" v-if="errors.has('status')">@{{ errors.first('status') }}</span>
|
||||
</div>
|
||||
|
||||
<div class="control-group" :class="[errors.has('use_coupon') ? 'has-error' :
|
||||
'']">
|
||||
<label for="customer_groups" class="required">{{ __('admin::app.promotion.general-info.is-coupon') }}</label>
|
||||
|
||||
<select type="text" class="control" name="use_coupon" v-model="use_coupon" v-validate="'required'" value="{{ old('use_coupon')}}" data-vv-as=""{{ __('admin::app.promotion.general-info.is-coupon') }}"">
|
||||
<option value="1" :selected="use_coupon == 1">{{ __('admin::app.promotion.general-info.is-coupon-yes') }}</option>
|
||||
<option value="0" :selected="use_coupon == 0">{{ __('admin::app.promotion.general-info.is-coupon-no') }}</option>
|
||||
</select>
|
||||
|
||||
<span class="control-error" v-if="errors.has('use_coupon')">@{{ errors.first('use_coupon') }}</span>
|
||||
</div>
|
||||
|
||||
{{-- <div class="control-group" :class="[errors.has('auto_generation') ? 'has-error' : '']" v-if="use_coupon == 1">
|
||||
<label for="auto_generation" class="required">{{ __('admin::app.promotion.general-info.specific-coupon') }}</label>
|
||||
|
||||
<input type="checkbox" class="control" name="auto_generation" v-model="auto_generation" value="{{ old('auto_generation') }}" data-vv-as=""Specific Coupon"" v-on:change="checkAutogen">
|
||||
|
||||
<span class="control-error" v-if="errors.has('auto_generation')">@{{ errors.first('auto_generation') }}</span>
|
||||
</div> --}}
|
||||
|
||||
{{-- <input type="hidden" name="auto_generation" v-model="auto_generation"> --}}
|
||||
|
||||
{{-- <div class="control-group" :class="[errors.has('per_customer') ? 'has-error' : '']">
|
||||
<label for="per_customer" class="required">{{ __('admin::app.promotion.general-info.uses-per-cust') }}</label>
|
||||
|
||||
<input type="number" step="1" class="control" name="per_customer" v-model="per_customer" v-validate="'required|numeric|min_value:0'" value="{{ old('per_customer') }}" data-vv-as=""{{ __('admin::app.promotion.general-info.uses-per-cust') }}"">
|
||||
|
||||
<span class="control-error" v-if="errors.has('per_customer')">@{{ errors.first('per_customer') }}</span>
|
||||
</div> --}}
|
||||
|
||||
<div class="control-group" :class="[errors.has('is_guest') ? 'has-error' : '']">
|
||||
<label for="is_guest" class="required">{{ __('admin::app.promotion.general-info.is-guest') }}</label>
|
||||
|
||||
<select type="text" class="control" name="is_guest" v-model="is_guest" v-validate="'required'" value="{{ old('is_guest')}}" data-vv-as=""{{ __('admin::app.promotion.general-info.is-guest') }}"">
|
||||
<option value="1" :selected="is_guest == 1">{{ __('admin::app.promotion.general-info.is-coupon-yes') }}</option>
|
||||
<option value="0" :selected="is_guest == 0">{{ __('admin::app.promotion.general-info.is-coupon-no') }}</option>
|
||||
</select>
|
||||
|
||||
<span class="control-error" v-if="errors.has('is_guest')">@{{ errors.first('is_guest') }}</span>
|
||||
</div>
|
||||
|
||||
{{-- <div class="control-group" :class="[errors.has('usage_limit') ? 'has-error' : '']">
|
||||
<label for="usage_limit" class="required">{{ __('admin::app.promotion.general-info.limit') }}</label>
|
||||
|
||||
<input type="number" step="1" class="control" name="usage_limit" v-model="usage_limit" v-validate="'required|numeric|min_value:0'" value="{{ old('usage_limit') }}" data-vv-as=""{{ __('admin::app.promotion.general-info.uses-per-cust') }}"">
|
||||
|
||||
<span class="control-error" v-if="errors.has('usage_limit')">@{{ errors.first('usage_limit') }}</span>
|
||||
</div> --}}
|
||||
|
||||
<div class="control-group" :class="[errors.has('priority') ? 'has-error' : '']">
|
||||
<label for="priority" class="required">{{ __('admin::app.promotion.general-info.priority') }}</label>
|
||||
|
||||
<input type="number" class="control" step="1" name="priority" v-model="priority" v-validate="'required|numeric|min_value:1'" value="{{ old('priority') }}" data-vv-as=""{{ __('admin::app.promotion.general-info.priority') }}"">
|
||||
|
||||
<span class="control-error" v-if="errors.has('priority')">@{{ errors.first('priority') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</accordian>
|
||||
|
||||
<accordian :active="false" title="Conditions">
|
||||
<div slot="body">
|
||||
<input type="hidden" name="all_conditions" v-model="all_conditions">
|
||||
|
||||
<div class="add-condition">
|
||||
<div class="control-group">
|
||||
<label for="criteria" class="required">{{ __('admin::app.promotion.general-info.add-condition') }}</label>
|
||||
|
||||
<select type="text" class="control" name="criteria" v-model="criteria">
|
||||
<option value="cart">Cart Properties</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<span class="btn btn-primary btn-lg" v-on:click="addCondition">Add Condition</span>
|
||||
</div>
|
||||
|
||||
<div class="mt-10 mb-10"><b>Any of the condition is true</b></div>
|
||||
|
||||
<div class="condition-set">
|
||||
<!-- Cart Attributes -->
|
||||
<div v-for="(condition, index) in conditions_list" :key="index">
|
||||
<div class="control-container mt-20">
|
||||
<div class="title-bar">
|
||||
<span>Cart Attribute is </span>
|
||||
<span class="icon cross-icon" v-on:click="removeCartAttr(index)"></span>
|
||||
</div>
|
||||
|
||||
<div class="control-group mt-10" :key="index">
|
||||
<select class="control" name="cart_attributes[]" v-model="conditions_list[index].attribute" title="You Can Make Multiple Selections Here" style="margin-right: 15px;" v-on:change="enableCondition($event, index)">
|
||||
<option disabled="disabled">Select Option</option>
|
||||
<option v-for="(cart_ip, index1) in cart_input" :value="cart_ip.code" :key="index1">@{{ cart_ip.name }}</option>
|
||||
</select>
|
||||
|
||||
<div v-if='conditions_list[index].type == "string"'>
|
||||
<select class="control" name="cart_attributes[]" v-model="conditions_list[index].condition" style="margin-right: 15px;">
|
||||
<option v-for="(condition, index) in conditions.numeric" :value="index" :key="index">@{{ condition }}</option>
|
||||
</select>
|
||||
|
||||
<div v-if='conditions_list[index].attribute == "shipping_state"'>
|
||||
<select class="control" v-model="conditions_list[index].value">
|
||||
<option disabled="disabled">Select State</option>
|
||||
<optgroup v-for='(state, code) in country_and_states.states' :label="code">
|
||||
<option v-for="(stateObj, index) in state" :value="stateObj.code">@{{ stateObj.default_name }}</option>
|
||||
</optgroup>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div v-if='conditions_list[index].attribute == "shipping_country"'>
|
||||
<select class="control" v-model="conditions_list[index].value">
|
||||
<option disabled="disabled">Select Country</option>
|
||||
<option v-for="(country, index) in country_and_states.countries" :value="country.code">@{{ country.name }}</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<input type="text" class="control" name="cart_attributes[]" v-model="conditions_list[index].value" placeholder="Enter Value" v-if='conditions_list[index].attribute != "shipping_state" && conditions_list[index].attribute != "shipping_country"'>
|
||||
</div>
|
||||
|
||||
<div v-if='conditions_list[index].type == "numeric"'>
|
||||
<select class="control" name="attributes[]" v-model="conditions_list[index].condition" style="margin-right: 15px;">
|
||||
<option v-for="(condition, index) in conditions.numeric" :value="index" :key="index">@{{ condition }}</option>
|
||||
</select>
|
||||
|
||||
<input type="number" step="0.1000" class="control" name="cart_attributes[]" v-model="conditions_list[index].value" placeholder="Enter Value">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</accordian>
|
||||
|
||||
<accordian :active="false" title="Actions">
|
||||
<div slot="body">
|
||||
<div class="control-group" :class="[errors.has('action_type') ? 'has-error' : '']">
|
||||
<label for="action_type" class="required">Apply</label>
|
||||
|
||||
<select class="control" name="action_type" v-model="action_type" v-validate="'required'" value="{{ old('action_type') }}" data-vv-as=""Apply As"" v-on:change="detectApply">
|
||||
<option v-for="(action, index) in actions" :value="index">@{{ action }}</option>
|
||||
</select>
|
||||
|
||||
<span class="control-error" v-if="errors.has('action_type')">@{{ errors.first('action_type') }}</span>
|
||||
</div>
|
||||
|
||||
<div class="control-group" :class="[errors.has('disc_amount') ? 'has-error' : '']">
|
||||
<label for="disc_amount" class="required">{{ __('admin::app.promotion.general-info.disc_amt') }}</label>
|
||||
|
||||
<input type="number" step="0.5000" class="control" name="disc_amount" v-model="disc_amount" v-validate="'required|decimal|min_value:0.0001'" value="{{ old('disc_amount') }}" data-vv-as=""{{ __('admin::app.promotion.general-info.disc_amt') }}"">
|
||||
|
||||
<span class="control-error" v-if="errors.has('disc_amount')">@{{ errors.first('disc_amount') }}</span>
|
||||
</div>
|
||||
|
||||
<div class="control-group" :class="[errors.has('disc_threshold') ? 'has-error' : '']">
|
||||
<label for="disc_threshold" class="required">{{ __('admin::app.promotion.cart.buy-atleast') }}</label>
|
||||
|
||||
<input type="number" step="1" class="control" name="disc_threshold" v-model="disc_threshold" v-validate="'required|numeric|min_value:1'" value="{{ old('disc_threshold') }}" data-vv-as=""{{ __('admin::app.promotion.cart.buy-atleast') }}"">
|
||||
|
||||
<span class="control-error" v-if="errors.has('disc_threshold')">@{{ errors.first('disc_threshold') }}</span>
|
||||
</div>
|
||||
|
||||
<div class="control-group" :class="[errors.has('disc_quantity') ? 'has-error' : '']">
|
||||
<label for="disc_quantity" class="required">{{ __('admin::app.promotion.general-info.disc_qty') }}</label>
|
||||
|
||||
<input type="number" step="1" class="control" name="disc_quantity" v-model="disc_quantity" v-validate="'required|decimal|min_value:0'" value="{{ old('disc_quantity') }}" data-vv-as=""{{ __('admin::app.promotion.general-info.disc_qty') }}"">
|
||||
|
||||
<span class="control-error" v-if="errors.has('disc_quantity')">@{{ errors.first('disc_quantity') }}</span>
|
||||
</div>
|
||||
|
||||
<div class="boolean-control-container">
|
||||
<div class="control-group" :class="[errors.has('free_shipping') ? 'has-error' : '']">
|
||||
<label for="free_shipping" class="required">{{ __('admin::app.promotion.general-info.free-shipping') }}</label>
|
||||
|
||||
<select type="text" class="control" name="free_shipping" v-model="free_shipping" v-validate="'required'" value="{{ old('free_shipping') }}" data-vv-as=""{{ __('admin::app.promotion.general-info.free-shipping') }}"">
|
||||
<option value="0" :selected="free_shipping == 0">{{ __('admin::app.promotion.general-info.is-coupon-yes') }}</option>
|
||||
|
||||
<option value="1" :selected="free_shipping == 1">{{ __('admin::app.promotion.general-info.is-coupon-no') }}</option>
|
||||
</select>
|
||||
|
||||
<span class="control-error" v-if="errors.has('free_shipping')">@{{ errors.first('free_shipping') }}</span>
|
||||
</div>
|
||||
|
||||
<div class="control-group" :class="[errors.has('apply_to_shipping') ? 'has-error' : '']">
|
||||
<label for="customer_groups" class="required">{{ __('admin::app.promotion.cart.apply-to-shipping') }}</label>
|
||||
|
||||
<select type="text" class="control" name="apply_to_shipping" v-model="apply_to_shipping" v-validate="'required'" value="{{ old('apply_to_shipping') }}" data-vv-as=""{{ __('admin::app.promotion.cart.apply-to-shipping') }}"">
|
||||
<option value="0" :selected="apply_to_shipping == 0">{{ __('admin::app.promotion.general-info.is-coupon-yes') }}</option>
|
||||
|
||||
<option value="1" :selected="apply_to_shipping == 1">{{ __('admin::app.promotion.general-info.is-coupon-no') }}</option>
|
||||
</select>
|
||||
|
||||
<span class="control-error" v-if="errors.has('apply_to_shipping')">@{{ errors.first('apply_to_shipping') }}</span>
|
||||
</div>
|
||||
|
||||
<div class="control-group" :class="[errors.has('end_other_rules') ? 'has-error' : '']">
|
||||
<label for="end_other_rules" class="required">{{ __('admin::app.promotion.general-info.end-other-rules') }}</label>
|
||||
|
||||
<select type="text" class="control" name="end_other_rules" v-model="end_other_rules" v-validate="'required'" value="{{ old('end_other_rules')}}" data-vv-as=""{{ __('admin::app.promotion.general-info.end-other-rules') }}"">
|
||||
<option value="1" :selected="end_other_rules == 1">{{ __('admin::app.promotion.general-info.is-coupon-yes') }}</option>
|
||||
<option value="0" :selected="end_other_rules == 0">{{ __('admin::app.promotion.general-info.is-coupon-no') }}</option>
|
||||
</select>
|
||||
|
||||
<span class="control-error" v-if="errors.has('end_other_rules')">@{{ errors.first('end_other_rules') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</accordian>
|
||||
|
||||
<accordian :active="false" title="Coupons" v-if="use_coupon == 1">
|
||||
<div slot="body">
|
||||
|
||||
{{-- <div v-if="!auto_generation">
|
||||
<div class="control-group" :class="[errors.has('prefix') ? 'has-error' : '']">
|
||||
<label for="prefix" class="required">Prefix</label>
|
||||
|
||||
<input type="text" class="control" name="prefix" v-model="prefix" v-validate="'alpha'" value="{{ old('prefix') }}" data-vv-as=""Prefix"">
|
||||
|
||||
<span class="control-error" v-if="errors.has('prefix')">@{{ errors.first('prefix') }}</span>
|
||||
</div>
|
||||
|
||||
<div class="control-group" :class="[errors.has('suffix') ? 'has-error' : '']"">
|
||||
<label for="suffix" class="required">Suffix</label>
|
||||
|
||||
<input type="text" class="control" name="suffix" v-model="suffix" v-validate="'alpha'" value="{{ old('suffix') }}" data-vv-as=""suffix"">
|
||||
|
||||
<span class="control-error" v-if="errors.has('suffix')">@{{ errors.first('suffix') }}</span>
|
||||
</div>
|
||||
</div> --}}
|
||||
|
||||
<div>
|
||||
<div class="control-group" :class="[errors.has('code') ? 'has-error' : '']">
|
||||
<label for="code" class="required">Code</label>
|
||||
|
||||
<input type="text" class="control" name="code" v-model="code" v-validate="'required'" value="{{ old('code') }}" data-vv-as=""Code"">
|
||||
|
||||
<span class="control-error" v-if="errors.has('code')">@{{ errors.first('code') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</accordian>
|
||||
|
||||
<accordian :active="false" title="labels">
|
||||
<div slot="body">
|
||||
<div class="control-group" :class="[errors.has('label') ? 'has-error' : '']" v-if="dedicated_label">
|
||||
<label for="label" class="required">Global Label</label>
|
||||
|
||||
<input type="text" class="control" name="label[global]" v-model="label.global" v-validate="'required'" data-vv-as=""label"">
|
||||
|
||||
<span class="control-error" v-if="errors.has('label')">@{{ errors.first('label') }}</span>
|
||||
</div>
|
||||
|
||||
<div v-if="label.global == null || label.global == ''">
|
||||
@foreach(core()->getAllChannels() as $channel)
|
||||
<span>[{{ $channel->code }}]</span>
|
||||
@foreach($channel->locales as $locale)
|
||||
<div class="control-group" :class="[errors.has('label') ? 'has-error' : '']">
|
||||
<label for="code">{{ $locale->code }}</label>
|
||||
|
||||
<input type="text" class="control" name="label[{{ $channel->code }}][{{ $locale->code }}]" v-model="label.{{ $channel->code }}.{{ $locale->code }}" v-validate="'alpha_spaces'" data-vv-as=""Label"">
|
||||
|
||||
<span class="control-error" v-if="errors.has('label')">@{{ errors.first('label') }}</span>
|
||||
</div>
|
||||
@endforeach
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
</accordian>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</script>
|
||||
|
||||
<script>
|
||||
Vue.component('cart-rule', {
|
||||
template: '#cart-rule-form-template',
|
||||
|
||||
inject: ['$validator'],
|
||||
|
||||
data () {
|
||||
return {
|
||||
name: null,
|
||||
description: null,
|
||||
conditions_list: [],
|
||||
channels: [],
|
||||
customer_groups: [],
|
||||
ends_till: null,
|
||||
starts_from: null,
|
||||
priority: 0,
|
||||
per_customer: 0,
|
||||
status: null,
|
||||
use_coupon: null,
|
||||
auto_generation: false,
|
||||
usage_limit: 0,
|
||||
is_guest: 0,
|
||||
|
||||
action_type: null,
|
||||
apply: null,
|
||||
apply_amt: false,
|
||||
apply_prct: false,
|
||||
apply_to_shipping: null,
|
||||
disc_amount: null,
|
||||
disc_threshold: null,
|
||||
disc_quantity: null,
|
||||
end_other_rules: null,
|
||||
coupon_type: null,
|
||||
free_shipping: null,
|
||||
|
||||
all_conditions: [],
|
||||
|
||||
code: null,
|
||||
suffix: null,
|
||||
prefix: null,
|
||||
dedicated_label: true,
|
||||
|
||||
label: {
|
||||
global: null,
|
||||
@foreach(core()->getAllChannels() as $channel)
|
||||
@foreach($channel->locales as $locale)
|
||||
{{ trim($channel->code) }} : {
|
||||
{{ trim($locale->code) }}: ''
|
||||
},
|
||||
@endforeach
|
||||
@endforeach
|
||||
},
|
||||
|
||||
criteria: null,
|
||||
conditions: @json($cart_rule[0]).conditions,
|
||||
cart_input: @json($cart_rule[0]).attributes,
|
||||
actions: @json($cart_rule[0]).actions,
|
||||
conditions_list:[],
|
||||
cart_object: {
|
||||
criteria: null,
|
||||
attribute: null,
|
||||
condition: null,
|
||||
value: []
|
||||
},
|
||||
country_and_states: @json($cart_rule[2])
|
||||
}
|
||||
},
|
||||
|
||||
mounted () {
|
||||
},
|
||||
|
||||
methods: {
|
||||
addCondition () {
|
||||
if (this.criteria == 'product_subselection' || this.criteria == 'cart') {
|
||||
this.condition_on = this.criteria;
|
||||
} else {
|
||||
alert('please try again');
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.condition_on == 'cart') {
|
||||
this.conditions_list.push(this.cart_object);
|
||||
|
||||
this.cart_object = {
|
||||
criteria: null,
|
||||
attribute: null,
|
||||
condition: null,
|
||||
value: []
|
||||
};
|
||||
}
|
||||
},
|
||||
|
||||
checkAutogen() {
|
||||
},
|
||||
|
||||
detectApply() {
|
||||
if (this.apply == 'percent_of_product' || this.apply == 'buy_a_get_b') {
|
||||
this.apply_prct = true;
|
||||
this.apply_amt = false;
|
||||
} else if (this.apply == 'fixed_amount' || this.apply == 'fixed_amount_cart') {
|
||||
this.apply_prct = false;
|
||||
this.apply_amt = true;
|
||||
}
|
||||
},
|
||||
|
||||
enableCondition(event, index) {
|
||||
selectedIndex = event.target.selectedIndex - 1;
|
||||
|
||||
for (i in this.cart_input) {
|
||||
if (i == selectedIndex) {
|
||||
this.conditions_list[index].type = this.cart_input[i].type;
|
||||
console.log(this.conditions_list[index]);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// useCoupon() {
|
||||
// if (this.use_coupon == 0) {
|
||||
// this.auto_generation = null;
|
||||
// } else {
|
||||
// this.auto_generation = true;
|
||||
// }
|
||||
// },
|
||||
|
||||
removeCartAttr(index) {
|
||||
this.conditions_list.splice(index, 1);
|
||||
},
|
||||
|
||||
removeCat(index) {
|
||||
this.cats.splice(index, 1);
|
||||
},
|
||||
|
||||
onSubmit: function (e) {
|
||||
this.$validator.validateAll().then(result => {
|
||||
if (result) {
|
||||
e.target.submit();
|
||||
}
|
||||
});
|
||||
|
||||
this.all_conditions = JSON.stringify(this.conditions_list);
|
||||
},
|
||||
|
||||
addFlashMessages() {
|
||||
const flashes = this.$refs.flashes;
|
||||
|
||||
flashMessages.forEach(function(flash) {
|
||||
flashes.addFlash(flash);
|
||||
}, this);
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
@endpush
|
||||
@stop
|
||||
|
|
@ -0,0 +1,582 @@
|
|||
@extends('admin::layouts.content')
|
||||
|
||||
@section('page_title')
|
||||
{{ __('admin::app.promotion.edit-cart-rule') }}
|
||||
@stop
|
||||
|
||||
@section('content')
|
||||
|
||||
<div class="content">
|
||||
<cart-rule></cart-rule>
|
||||
</div>
|
||||
|
||||
@push('scripts')
|
||||
<script type="text/x-template" id="cart-rule-form-template">
|
||||
<form method="POST" action="{{ route('admin.cart-rule.update', $cart_rule[3]->id) }}" @submit.prevent="onSubmit">
|
||||
@csrf
|
||||
|
||||
<div class="page-header">
|
||||
<div class="page-title">
|
||||
<h1>
|
||||
<i class="icon angle-left-icon back-link" onclick="history.length > 1 ? history.go(-1) : window.location = '{{ url('/admin/dashboard') }}';"></i>
|
||||
|
||||
{{ __('admin::app.promotion.edit-cart-rule') }}
|
||||
</h1>
|
||||
</div>
|
||||
|
||||
<div class="page-action">
|
||||
<button type="submit" class="btn btn-lg btn-primary">
|
||||
{{ __('admin::app.promotion.edit-btn-title') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="page-content">
|
||||
<div class="form-container">
|
||||
<div>
|
||||
@csrf()
|
||||
|
||||
<accordian :active="true" title="Information">
|
||||
<div slot="body">
|
||||
<input type="hidden" name="all_conditions" v-model="all_conditions">
|
||||
|
||||
<div class="control-group" :class="[errors.has('name') ? 'has-error' : '']">
|
||||
<label for="name" class="required">{{ __('admin::app.promotion.general-info.name') }}</label>
|
||||
|
||||
<input type="text" class="control" name="name" v-model="name" v-validate="'required|alpha_spaces'" value="{{ old('name') }}" data-vv-as=""{{ __('admin::app.promotion.general-info.name') }}"">
|
||||
|
||||
<span class="control-error" v-if="errors.has('name')">@{{ errors.first('name') }}</span>
|
||||
</div>
|
||||
|
||||
<div class="control-group" :class="[errors.has('description') ? 'has-error' : '']">
|
||||
<label for="description">{{ __('admin::app.promotion.general-info.description') }}</label>
|
||||
|
||||
<textarea class="control" name="description" v-model="description" v-validate="'alpha_spaces'" value="{{ old('description') }}" data-vv-as=""{{ __('admin::app.promotion.general-info.description') }}""></textarea>
|
||||
|
||||
<span class="control-error" v-if="errors.has('description')">@{{ errors.first('description') }}</span>
|
||||
</div>
|
||||
|
||||
<datetime :name="starts_from">
|
||||
<div class="control-group" :class="[errors.has('starts_from') ? 'has-error' : '']">
|
||||
<label for="starts_from">{{ __('admin::app.promotion.general-info.starts-from') }}</label>
|
||||
|
||||
<input type="text" class="control" v-model="starts_from" name="starts_from" data-vv-as=""{{ __('admin::app.promotion.general-info.starts-from') }}"">
|
||||
|
||||
<span class="control-error" v-if="errors.has('starts_from')">@{{ errors.first('starts_from') }}</span>
|
||||
</div>
|
||||
</datetime>
|
||||
|
||||
<datetime :name="starts_from">
|
||||
<div class="control-group" :class="[errors.has('ends_till') ? 'has-error' : '']">
|
||||
<label for="ends_till">{{ __('admin::app.promotion.general-info.ends-till') }}</label>
|
||||
|
||||
<input type="text" class="control" v-model="ends_till" name="ends_till" data-vv-as=""{{ __('admin::app.promotion.general-info.ends-till') }}"">
|
||||
|
||||
<span class="control-error" v-if="errors.has('ends_till')">@{{ errors.first('ends_till') }}</span>
|
||||
</div>
|
||||
</datetime>
|
||||
|
||||
{{-- <div class="control-group" :class="[errors.has('customer_groups[]') ? 'has-error' : '']">
|
||||
<label for="customer_groups" class="required">{{ __('admin::app.promotion.general-info.cust-groups') }}</label>
|
||||
|
||||
<select type="text" class="control" name="customer_groups[]" v-model="customer_groups" v-validate="'required'" value="{{ old('customer_groups[]') }}" data-vv-as=""{{ __('admin::app.promotion.general-info.cust-groups') }}"" multiple="multiple">
|
||||
<option disabled="disabled">Select Customer Groups</option>
|
||||
@foreach(app('Webkul\Customer\Repositories\CustomerGroupRepository')->all() as $customerGroup)
|
||||
<option value="{{ $customerGroup->id }}">{{ $customerGroup->name }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
|
||||
<span class="control-error" v-if="errors.has('customer_groups')">@{{ errors.first('customer_groups') }}</span>
|
||||
</div> --}}
|
||||
|
||||
<div class="control-group" :class="[errors.has('channels[]') ? 'has-error' : '']">
|
||||
<label for="channels" class="required">{{ __('admin::app.promotion.general-info.channels') }}</label>
|
||||
|
||||
<select type="text" class="control" name="channels[]" v-model="channels" v-validate="'required'" value="{{ old('channels[]') }}" data-vv-as=""{{ __('admin::app.promotion.general-info.channels') }}"" multiple="multiple">
|
||||
<option disabled="disabled">Select Channels</option>
|
||||
@foreach(app('Webkul\Core\Repositories\ChannelRepository')->all() as $channel)
|
||||
<option value="{{ $channel->id }}">{{ $channel->name }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
|
||||
<span class="control-error" v-if="errors.has('channels')">@{{ errors.first('channels') }}</span>
|
||||
</div>
|
||||
|
||||
<div class="control-group" :class="[errors.has('status') ? 'has-error' : '']">
|
||||
<label for="status" class="required">{{ __('admin::app.promotion.general-info.status') }}</label>
|
||||
|
||||
<select type="text" class="control" name="status" v-model="status" v-validate="'required'" data-vv-as=""{{ __('admin::app.promotion.general-info.status') }}"">
|
||||
<option disabled="disabled">Select status</option>
|
||||
<option value="1">Yes</option>
|
||||
<option value="0">No</option>
|
||||
</select>
|
||||
|
||||
<span class="control-error" v-if="errors.has('status')">@{{ errors.first('status') }}</span>
|
||||
</div>
|
||||
|
||||
<div class="control-group" :class="[errors.has('use_coupon') ? 'has-error' :
|
||||
'']">
|
||||
<label for="customer_groups" class="required">{{ __('admin::app.promotion.general-info.is-coupon') }}</label>
|
||||
|
||||
<select type="text" class="control" name="use_coupon" v-model="use_coupon" v-validate="'required'" value="{{ old('use_coupon')}}" data-vv-as=""{{ __('admin::app.promotion.general-info.is-coupon') }}"" v-on:change="useCoupon">
|
||||
<option value="1" :selected="use_coupon == 1">{{ __('admin::app.promotion.general-info.is-coupon-yes') }}</option>
|
||||
<option value="0" :selected="use_coupon == 0">{{ __('admin::app.promotion.general-info.is-coupon-no') }}</option>
|
||||
</select>
|
||||
|
||||
<span class="control-error" v-if="errors.has('use_coupon')">@{{ errors.first('use_coupon') }}</span>
|
||||
</div>
|
||||
|
||||
{{-- <div class="control-group" :class="[errors.has('auto_generation') ? 'has-error' : '']" v-if="use_coupon == 1">
|
||||
<label for="auto_generation" class="required">{{ __('admin::app.promotion.general-info.specific-coupon') }}</label>
|
||||
|
||||
<input type="checkbox" class="control" name="auto_generation" v-model="auto_generation" value="{{ old('auto_generation') }}" data-vv-as=""Specific Coupon"" v-on:change="checkAutogen">
|
||||
|
||||
<span class="control-error" v-if="errors.has('auto_generation')">@{{ errors.first('auto_generation') }}</span>
|
||||
</div> --}}
|
||||
|
||||
{{-- <input type="hidden" name="auto_generation" v-model="auto_generation"> --}}
|
||||
|
||||
{{-- <div class="control-group" :class="[errors.has('per_customer') ? 'has-error' : '']">
|
||||
<label for="per_customer" class="required">{{ __('admin::app.promotion.general-info.uses-per-cust') }}</label>
|
||||
|
||||
<input type="number" step="1" class="control" name="per_customer" v-model="per_customer" v-validate="'required|numeric|min_value:0'" value="{{ old('per_customer') }}" data-vv-as=""{{ __('admin::app.promotion.general-info.uses-per-cust') }}"">
|
||||
|
||||
<span class="control-error" v-if="errors.has('per_customer')">@{{ errors.first('per_customer') }}</span>
|
||||
</div> --}}
|
||||
|
||||
<div class="control-group" :class="[errors.has('is_guest') ? 'has-error' : '']">
|
||||
<label for="is_guest" class="required">{{ __('admin::app.promotion.general-info.is-guest') }}</label>
|
||||
|
||||
<select type="text" class="control" name="is_guest" v-model="is_guest" v-validate="'required'" value="{{ old('is_guest')}}" data-vv-as=""{{ __('admin::app.promotion.general-info.is-guest') }}"">
|
||||
<option value="1" :selected="is_guest == 1">{{ __('admin::app.promotion.general-info.is-coupon-yes') }}</option>
|
||||
<option value="0" :selected="is_guest == 0">{{ __('admin::app.promotion.general-info.is-coupon-no') }}</option>
|
||||
</select>
|
||||
|
||||
<span class="control-error" v-if="errors.has('is_guest')">@{{ errors.first('is_guest') }}</span>
|
||||
</div>
|
||||
|
||||
{{-- <div class="control-group" :class="[errors.has('usage_limit') ? 'has-error' : '']">
|
||||
<label for="usage_limit" class="required">{{ __('admin::app.promotion.general-info.limit') }}</label>
|
||||
|
||||
<input type="number" step="1" class="control" name="usage_limit" v-model="usage_limit" v-validate="'required|numeric|min_value:0'" value="{{ old('usage_limit') }}" data-vv-as=""{{ __('admin::app.promotion.general-info.uses-per-cust') }}"">
|
||||
|
||||
<span class="control-error" v-if="errors.has('usage_limit')">@{{ errors.first('usage_limit') }}</span>
|
||||
</div> --}}
|
||||
|
||||
<div class="control-group" :class="[errors.has('priority') ? 'has-error' : '']">
|
||||
<label for="priority" class="required">{{ __('admin::app.promotion.general-info.priority') }}</label>
|
||||
|
||||
<input type="number" class="control" step="1" name="priority" v-model="priority" v-validate="'required|numeric|min_value:1'" value="{{ old('priority') }}" data-vv-as=""{{ __('admin::app.promotion.general-info.priority') }}"">
|
||||
|
||||
<span class="control-error" v-if="errors.has('priority')">@{{ errors.first('priority') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</accordian>
|
||||
|
||||
<accordian :active="false" title="Conditions">
|
||||
<div slot="body">
|
||||
<div class="add-condition">
|
||||
<div class="control-group">
|
||||
<label for="criteria" class="required">{{ __('admin::app.promotion.general-info.add-condition') }}</label>
|
||||
|
||||
<select type="text" class="control" name="criteria" v-model="criteria">
|
||||
<option value="cart">Cart Properties</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<span class="btn btn-primary btn-lg" v-on:click="addCondition">Add Condition</span>
|
||||
</div>
|
||||
|
||||
<div class="mt-10 mb-10"><b>Any of the condition is true</b></div>
|
||||
|
||||
<div class="condition-set">
|
||||
<!-- Cart Attributes -->
|
||||
<div v-for="(condition, index) in conditions_list" :key="index">
|
||||
<div class="control-container mt-20">
|
||||
<div class="title-bar">
|
||||
<span>Cart Attribute is </span>
|
||||
<span class="icon cross-icon" v-on:click="removeCartAttr(index)"></span>
|
||||
</div>
|
||||
|
||||
<div class="control-group mt-10" :key="index">
|
||||
<select class="control" name="cart_attributes[]" v-model="conditions_list[index].attribute" title="You Can Make Multiple Selections Here" style="margin-right: 15px;" v-on:change="enableCondition($event, index)">
|
||||
<option disabled="disabled">Select Option</option>
|
||||
<option v-for="(cart_ip, index1) in cart_input" :value="cart_ip.code" :key="index1">@{{ cart_ip.name }}</option>
|
||||
</select>
|
||||
|
||||
<div v-if='conditions_list[index].type == "string"'>
|
||||
<select class="control" name="cart_attributes[]" v-model="conditions_list[index].condition" style="margin-right: 15px;">
|
||||
<option v-for="(condition, index) in conditions.numeric" :value="index" :key="index">@{{ condition }}</option>
|
||||
</select>
|
||||
|
||||
<div v-if='conditions_list[index].attribute == "shipping_state"'>
|
||||
<select class="control" v-model="conditions_list[index].value">
|
||||
<option disabled="disabled">Select State</option>
|
||||
<optgroup v-for='(state, code) in country_and_states.states' :label="code">
|
||||
<option v-for="(stateObj, index) in state" :value="stateObj.code">@{{ stateObj.default_name }}</option>
|
||||
</optgroup>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div v-if='conditions_list[index].attribute == "shipping_country"'>
|
||||
<select class="control" v-model="conditions_list[index].value">
|
||||
<option disabled="disabled">Select Country</option>
|
||||
<option v-for="(country, index) in country_and_states.countries" :value="country.code">@{{ country.name }}</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<input type="text" class="control" name="cart_attributes[]" v-model="conditions_list[index].value" placeholder="Enter Value" v-if='conditions_list[index].attribute != "shipping_state" && conditions_list[index].attribute != "shipping_country"'>
|
||||
</div>
|
||||
|
||||
<div v-if='conditions_list[index].type == "numeric"'>
|
||||
<select class="control" name="attributes[]" v-model="conditions_list[index].condition" style="margin-right: 15px;">
|
||||
<option v-for="(condition, index) in conditions.numeric" :value="index" :key="index">@{{ condition }}</option>
|
||||
</select>
|
||||
|
||||
<input type="number" step="0.1000" class="control" name="cart_attributes[]" v-model="conditions_list[index].value" placeholder="Enter Value">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</accordian>
|
||||
|
||||
<accordian :active="false" title="Actions">
|
||||
<div slot="body">
|
||||
<div class="control-group" :class="[errors.has('action_type') ? 'has-error' : '']">
|
||||
<label for="action_type" class="required">Apply</label>
|
||||
|
||||
<select class="control" name="action_type" v-model="action_type" v-validate="'required'" value="{{ old('action_type') }}" data-vv-as=""Apply As"" v-on:change="detectApply">
|
||||
<option v-for="(action, index) in actions" :value="index">@{{ action }}</option>
|
||||
</select>
|
||||
|
||||
<span class="control-error" v-if="errors.has('action_type')">@{{ errors.first('action_type') }}</span>
|
||||
</div>
|
||||
|
||||
<div class="control-group" :class="[errors.has('disc_amount') ? 'has-error' : '']">
|
||||
<label for="disc_amount" class="required">{{ __('admin::app.promotion.general-info.disc_amt') }}</label>
|
||||
|
||||
<input type="number" step="0.5000" class="control" name="disc_amount" v-model="disc_amount" v-validate="'required|decimal|min_value:0.0001'" value="{{ old('disc_amount') }}" data-vv-as=""{{ __('admin::app.promotion.general-info.disc_amt') }}"">
|
||||
|
||||
<span class="control-error" v-if="errors.has('disc_amount')">@{{ errors.first('disc_amount') }}</span>
|
||||
</div>
|
||||
|
||||
<div class="control-group" :class="[errors.has('disc_threshold') ? 'has-error' : '']">
|
||||
<label for="disc_threshold" class="required">{{ __('admin::app.promotion.cart.buy-atleast') }}</label>
|
||||
|
||||
<input type="number" step="1" class="control" name="disc_threshold" v-model="disc_threshold" v-validate="'required|numeric|min_value:1'" value="{{ old('disc_threshold') }}" data-vv-as=""{{ __('admin::app.promotion.cart.buy-atleast') }}"">
|
||||
|
||||
<span class="control-error" v-if="errors.has('disc_threshold')">@{{ errors.first('disc_threshold') }}</span>
|
||||
</div>
|
||||
|
||||
<div class="control-group" :class="[errors.has('disc_quantity') ? 'has-error' : '']">
|
||||
<label for="disc_amount" class="required">{{ __('admin::app.promotion.general-info.disc_qty') }}</label>
|
||||
|
||||
<input type="number" step="1" class="control" name="disc_quantity" v-model="disc_quantity" v-validate="'required|decimal|min_value:1'" value="{{ old('disc_quantity') }}" data-vv-as=""{{ __('admin::app.promotion.general-info.disc_qty') }}"">
|
||||
|
||||
<span class="control-error" v-if="errors.has('disc_quantity')">@{{ errors.first('disc_quantity') }}</span>
|
||||
</div>
|
||||
|
||||
<div class="boolean-control-container">
|
||||
<div class="control-group" :class="[errors.has('free_shipping') ? 'has-error' : '']">
|
||||
<label for="free_shipping" class="required">{{ __('admin::app.promotion.general-info.free-shipping') }}</label>
|
||||
|
||||
<select type="text" class="control" name="free_shipping" v-model="free_shipping" v-validate="'required'" value="{{ old('free_shipping') }}" data-vv-as=""{{ __('admin::app.promotion.general-info.free-shipping') }}"">
|
||||
<option value="0" :selected="free_shipping == 0">{{ __('admin::app.promotion.general-info.is-coupon-yes') }}</option>
|
||||
|
||||
<option value="1" :selected="free_shipping == 1">{{ __('admin::app.promotion.general-info.is-coupon-no') }}</option>
|
||||
</select>
|
||||
|
||||
<span class="control-error" v-if="errors.has('free_shipping')">@{{ errors.first('free_shipping') }}</span>
|
||||
</div>
|
||||
|
||||
<div class="control-group" :class="[errors.has('apply_to_shipping') ? 'has-error' : '']">
|
||||
<label for="customer_groups" class="required">{{ __('admin::app.promotion.cart.apply-to-shipping') }}</label>
|
||||
|
||||
<select type="text" class="control" name="apply_to_shipping" v-model="apply_to_shipping" v-validate="'required'" value="{{ old('apply_to_shipping') }}" data-vv-as=""{{ __('admin::app.promotion.cart.apply-to-shipping') }}"">
|
||||
<option value="0" :selected="apply_to_shipping == 0">{{ __('admin::app.promotion.general-info.is-coupon-yes') }}</option>
|
||||
|
||||
<option value="1" :selected="apply_to_shipping == 1">{{ __('admin::app.promotion.general-info.is-coupon-no') }}</option>
|
||||
</select>
|
||||
|
||||
<span class="control-error" v-if="errors.has('apply_to_shipping')">@{{ errors.first('apply_to_shipping') }}</span>
|
||||
</div>
|
||||
|
||||
<div class="control-group" :class="[errors.has('end_other_rules') ? 'has-error' : '']">
|
||||
<label for="end_other_rules" class="required">{{ __('admin::app.promotion.general-info.end-other-rules') }}</label>
|
||||
|
||||
<select type="text" class="control" name="end_other_rules" v-model="end_other_rules" v-validate="'required'" value="{{ old('end_other_rules')}}" data-vv-as=""{{ __('admin::app.promotion.general-info.end-other-rules') }}"">
|
||||
<option value="1" :selected="end_other_rules == 1">{{ __('admin::app.promotion.general-info.is-coupon-yes') }}</option>
|
||||
<option value="0" :selected="end_other_rules == 0">{{ __('admin::app.promotion.general-info.is-coupon-no') }}</option>
|
||||
</select>
|
||||
|
||||
<span class="control-error" v-if="errors.has('end_other_rules')">@{{ errors.first('end_other_rules') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</accordian>
|
||||
|
||||
<accordian :active="false" title="Coupons" v-if="use_coupon == 1">
|
||||
<div slot="body">
|
||||
{{-- <div v-if="!auto_generation">
|
||||
<div class="control-group" :class="[errors.has('prefix') ? 'has-error' : '']">
|
||||
<label for="prefix" class="required">Prefix</label>
|
||||
|
||||
<input type="text" class="control" name="prefix" v-model="prefix" value="{{ old('prefix') }}" data-vv-as=""Prefix"">
|
||||
|
||||
<span class="control-error" v-if="errors.has('prefix')">@{{ errors.first('prefix') }}</span>
|
||||
</div>
|
||||
|
||||
<div class="control-group" :class="[errors.has('suffix') ? 'has-error' : '']"">
|
||||
<label for="suffix" class="required">Suffix</label>
|
||||
|
||||
<input type="text" class="control" name="suffix" v-model="suffix" value="{{ old('suffix') }}" data-vv-as=""suffix"">
|
||||
|
||||
<span class="control-error" v-if="errors.has('suffix')">@{{ errors.first('suffix') }}</span>
|
||||
</div>
|
||||
</div> --}}
|
||||
|
||||
{{-- <div v-if="auto_generation != 0"> --}}
|
||||
<div class="control-group" :class="[errors.has('code') ? 'has-error' : '']">
|
||||
<label for="code" class="required">Code</label>
|
||||
|
||||
<input type="text" class="control" name="code" v-model="code" v-validate="'required'" value="{{ old('code') }}" data-vv-as=""Code"">
|
||||
|
||||
<span class="control-error" v-if="errors.has('code')">@{{ errors.first('code') }}</span>
|
||||
</div>
|
||||
{{-- </div> --}}
|
||||
</div>
|
||||
</accordian>
|
||||
|
||||
<accordian :active="false" title="labels">
|
||||
<div slot="body">
|
||||
@foreach($cart_rule[3]->labels as $label)
|
||||
<span>[{{ $label->channel->code }}]</span>
|
||||
<div class="control-group" :class="[errors.has('label') ? 'has-error' : '']">
|
||||
<label for="code">{{ $label->locale->code }}</label>
|
||||
|
||||
<input type="text" class="control" name="label[{{ $label->channel->code }}][{{ $label->locale->code }}]" value="{{ $label->label }}" v-validate="'required'" data-vv-as=""Label"">
|
||||
|
||||
<span class="control-error" v-if="errors.has('label')">@{{ errors.first('label') }}</span>
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
</accordian>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</script>
|
||||
|
||||
<script>
|
||||
Vue.component('cart-rule', {
|
||||
template: '#cart-rule-form-template',
|
||||
|
||||
inject: ['$validator'],
|
||||
|
||||
data () {
|
||||
return {
|
||||
name: 'Name of rule',
|
||||
description: 'Enter Some Description',
|
||||
channels: [],
|
||||
customer_groups: [],
|
||||
ends_till: null,
|
||||
starts_from: null,
|
||||
priority: 0,
|
||||
per_customer: 0,
|
||||
status: null,
|
||||
use_coupon: null,
|
||||
// auto_generation: 0,
|
||||
usage_limit: 0,
|
||||
is_guest: 0,
|
||||
|
||||
action_type: null,
|
||||
apply: null,
|
||||
apply_amt: false,
|
||||
apply_prct: false,
|
||||
apply_to_shipping: null,
|
||||
buy_atleast: null,
|
||||
disc_amount: null,
|
||||
disc_threshold: null,
|
||||
disc_quantity: null,
|
||||
end_other_rules: null,
|
||||
coupon_type: null,
|
||||
free_shipping: null,
|
||||
|
||||
all_conditions: null,
|
||||
|
||||
code: null,
|
||||
suffix: null,
|
||||
prefix: null,
|
||||
dedicated_label: true,
|
||||
|
||||
global_label: null,
|
||||
labels: [],
|
||||
// label: {
|
||||
// @foreach(core()->getAllChannels() as $channel)
|
||||
// @foreach($channel->locales as $locale)
|
||||
// {{ trim($channel->code) }} : null,
|
||||
// @endforeach
|
||||
// @endforeach
|
||||
// },
|
||||
|
||||
criteria: null,
|
||||
conditions: @json($cart_rule[0]).conditions,
|
||||
cart_input: @json($cart_rule[0]).attributes,
|
||||
actions: @json($cart_rule[0]).actions,
|
||||
conditions_list:[],
|
||||
cart_object: {
|
||||
criteria: null,
|
||||
attribute: null,
|
||||
condition: null,
|
||||
value: []
|
||||
},
|
||||
country_and_states: @json($cart_rule[2])
|
||||
}
|
||||
},
|
||||
|
||||
mounted () {
|
||||
data = @json($cart_rule[3]);
|
||||
this.name = data.name;
|
||||
this.description = data.description;
|
||||
this.conditions_list = [];
|
||||
this.channels = [];
|
||||
for (i in data.channels) {
|
||||
this.channels.push(data.channels[i].channel_id);
|
||||
}
|
||||
|
||||
this.customer_groups = data.customer_groups;
|
||||
for (i in data.customer_groups) {
|
||||
this.customer_groups.push(data.customer_groups[i].customer_group_id);
|
||||
}
|
||||
|
||||
this.ends_till = data.ends_till;
|
||||
this.starts_from = data.starts_from;
|
||||
this.priority = data.priority;
|
||||
this.per_customer = data.per_customer;
|
||||
this.status = data.status;
|
||||
if (data.use_coupon == 0) {
|
||||
// this.auto_generation = null;
|
||||
this.use_coupon = 0;
|
||||
} else {
|
||||
this.use_coupon = 1;
|
||||
// this.auto_generation = data.auto_generation;
|
||||
this.code = data.coupons.code;
|
||||
// this.suffix = data.coupons.suffix;
|
||||
// this.prefix = data.coupons.prefix;
|
||||
|
||||
// if (data.auto_generation == 0)
|
||||
// this.auto_generation = true;
|
||||
// else
|
||||
// this.auto_generation = false;
|
||||
}
|
||||
|
||||
this.usage_limit = data.usage_limit;
|
||||
this.is_guest = data.is_guest;
|
||||
|
||||
this.action_type = data.action_type;
|
||||
this.apply = null;
|
||||
this.apply_amt = false;
|
||||
this.apply_prct = false;
|
||||
this.apply_to_shipping = data.apply_to_shipping;
|
||||
this.buy_atleast = data.disc_threshold;
|
||||
this.disc_amount = data.disc_amount;
|
||||
this.disc_threshold = data.disc_threshold;
|
||||
this.disc_quantity = data.disc_quantity;
|
||||
this.end_other_rules = data.end_other_rules;
|
||||
this.coupon_type = data.coupon_type;
|
||||
this.free_shipping = data.free_shipping;
|
||||
|
||||
this.all_conditions = null;
|
||||
|
||||
if (data.conditions != null) {
|
||||
this.conditions_list = JSON.parse(JSON.parse(data.conditions));
|
||||
}
|
||||
|
||||
criteria = null;
|
||||
},
|
||||
|
||||
methods: {
|
||||
addCondition () {
|
||||
if (this.criteria == 'product_subselection' || this.criteria == 'cart') {
|
||||
this.condition_on = this.criteria;
|
||||
} else {
|
||||
alert('please try again');
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.condition_on == 'cart') {
|
||||
this.conditions_list.push(this.cart_object);
|
||||
|
||||
this.cart_object = {
|
||||
criteria: null,
|
||||
attribute: null,
|
||||
condition: null,
|
||||
value: []
|
||||
};
|
||||
}
|
||||
},
|
||||
|
||||
checkAutogen() {
|
||||
},
|
||||
|
||||
detectApply() {
|
||||
if (this.apply == 'percent_of_product' || this.apply == 'buy_a_get_b') {
|
||||
this.apply_prct = true;
|
||||
this.apply_amt = false;
|
||||
} else if (this.apply == 'fixed_amount' || this.apply == 'fixed_amount_cart') {
|
||||
this.apply_prct = false;
|
||||
this.apply_amt = true;
|
||||
}
|
||||
},
|
||||
|
||||
enableCondition(event, index) {
|
||||
selectedIndex = event.target.selectedIndex - 1;
|
||||
|
||||
for (i in this.cart_input) {
|
||||
if (i == selectedIndex) {
|
||||
this.conditions_list[index].type = this.cart_input[i].type;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
useCoupon() {
|
||||
if (this.use_coupon == 0) {
|
||||
this.auto_generation = null;
|
||||
} else {
|
||||
this.auto_generation = true;
|
||||
}
|
||||
},
|
||||
|
||||
removeCartAttr(index) {
|
||||
this.conditions_list.splice(index, 1);
|
||||
},
|
||||
|
||||
removeCat(index) {
|
||||
this.cats.splice(index, 1);
|
||||
},
|
||||
|
||||
onSubmit: function (e) {
|
||||
this.$validator.validateAll().then(result => {
|
||||
if (result) {
|
||||
e.target.submit();
|
||||
}
|
||||
});
|
||||
|
||||
this.all_conditions = JSON.stringify(this.conditions_list);
|
||||
},
|
||||
|
||||
addFlashMessages() {
|
||||
const flashes = this.$refs.flashes;
|
||||
|
||||
flashMessages.forEach(function(flash) {
|
||||
flashes.addFlash(flash);
|
||||
}, this);
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
@endpush
|
||||
@stop
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
@extends('admin::layouts.content')
|
||||
|
||||
@section('page_title')
|
||||
{{ __('admin::app.promotion.cart-rule') }}
|
||||
@stop
|
||||
|
||||
@section('content')
|
||||
|
||||
<div class="content">
|
||||
<div class="page-header">
|
||||
<div class="page-title">
|
||||
<h1>{{ __('admin::app.promotion.cart-rule') }}</h1>
|
||||
</div>
|
||||
|
||||
<div class="page-action">
|
||||
<a href="{{ route('admin.cart-rule.create') }}" class="btn btn-lg btn-primary">
|
||||
{{ __('admin::app.promotion.add-cart-rule') }}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="page-content">
|
||||
@inject('cartRuleGrid','Webkul\Admin\DataGrids\CartRuleDataGrid')
|
||||
{!! $cartRuleGrid->render() !!}
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
|
|
@ -0,0 +1,539 @@
|
|||
@extends('admin::layouts.content')
|
||||
|
||||
@section('page_title')
|
||||
{{ __('admin::app.promotion.add-catalog-rule') }}
|
||||
@stop
|
||||
|
||||
@section('content')
|
||||
<div class="content">
|
||||
<catalog-rule></catalog-rule>
|
||||
</div>
|
||||
|
||||
@push('scripts')
|
||||
<script type="text/x-template" id="catalog-rule-form-template">
|
||||
<div>
|
||||
<form method="POST" action="{{ route('admin.catalog-rule.store') }}" @submit.prevent="onSubmit">
|
||||
@csrf
|
||||
|
||||
<div class="page-header">
|
||||
<div class="page-title">
|
||||
<h1>
|
||||
<i class="icon angle-left-icon back-link" onclick="history.length > 1 ? history.go(-1) : window.location = '{{ url('/admin/dashboard') }}';"></i>
|
||||
|
||||
{{ __('admin::app.promotion.add-catalog-rule') }}
|
||||
</h1>
|
||||
</div>
|
||||
|
||||
<div class="page-action">
|
||||
<button type="submit" class="btn btn-lg btn-primary">
|
||||
{{ __('admin::app.promotion.save-btn-title') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="page-content">
|
||||
<div class="form-container">
|
||||
@csrf()
|
||||
|
||||
<accordian :active="true" title="Information">
|
||||
<div slot="body">
|
||||
<div class="control-group" :class="[errors.has('name') ? 'has-error' : '']">
|
||||
<label for="name" class="required">{{ __('admin::app.promotion.general-info.name') }}</label>
|
||||
|
||||
<input type="text" class="control" name="name" v-model="name" v-validate="'required'" value="{{ old('name') }}" data-vv-as=""{{ __('admin::app.promotion.general-info.name') }}"">
|
||||
|
||||
<span class="control-error" v-if="errors.has('name')">@{{ errors.first('name') }}</span>
|
||||
</div>
|
||||
|
||||
<div class="control-group" :class="[errors.has('description') ? 'has-error' : '']">
|
||||
<label for="description">{{ __('admin::app.promotion.general-info.description') }}</label>
|
||||
|
||||
<textarea class="control" name="description" v-model="description" v-validate="'required'" value="{{ old('description') }}" data-vv-as=""{{ __('admin::app.promotion.general-info.description') }}""></textarea>
|
||||
|
||||
<span class="control-error" v-if="errors.has('description')">@{{ errors.first('description') }}</span>
|
||||
</div>
|
||||
|
||||
<div class="control-group" :class="[errors.has('customer_groups[]') ? 'has-error' : '']">
|
||||
<label for="customer_groups" class="required">{{ __('admin::app.promotion.general-info.cust-groups') }}</label>
|
||||
|
||||
<select type="text" class="control" name="customer_groups[]" v-model="customer_groups" v-validate="'required'" data-vv-as=""{{ __('admin::app.promotion.general-info.cust-groups') }}"" multiple="multiple">
|
||||
<option disabled="disabled">Select Customer Groups</option>
|
||||
@foreach(app('Webkul\Customer\Repositories\CustomerGroupRepository')->all() as $channel)
|
||||
<option value="{{ $channel->id }}">{{ $channel->name }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
|
||||
<span class="control-error" v-if="errors.has('customer_groups[]')">@{{ errors.first('customer_groups[]') }}</span>
|
||||
</div>
|
||||
|
||||
<div class="control-group" :class="[errors.has('channels[]') ? 'has-error' : '']">
|
||||
<label for="channels" class="required">{{ __('admin::app.promotion.general-info.channels') }}</label>
|
||||
|
||||
<select type="text" class="control" name="channels[]" v-model="channels" v-validate="'required'" data-vv-as=""{{ __('admin::app.promotion.general-info.channels') }}"" multiple="multiple">
|
||||
<option disabled="disabled">Select Channels</option>
|
||||
@foreach(app('Webkul\Core\Repositories\ChannelRepository')->all() as $channel)
|
||||
<option value="{{ $channel->id }}">{{ $channel->name }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
|
||||
<span class="control-error" v-if="errors.has('channels[]')">@{{ errors.first('status') }}</span>
|
||||
</div>
|
||||
|
||||
<div class="control-group" :class="[errors.has('status') ? 'has-error' : '']">
|
||||
<label for="status" class="required">{{ __('admin::app.promotion.general-info.status') }}</label>
|
||||
|
||||
<select type="text" class="control" name="status" v-model="status" v-validate="'required'" data-vv-as=""{{ __('admin::app.promotion.general-info.status') }}"">
|
||||
<option disabled="disabled">Select status</option>
|
||||
<option value="1">Yes</option>
|
||||
<option value="0">No</option>
|
||||
</select>
|
||||
|
||||
<span class="control-error" v-if="errors.has('status')">@{{ errors.first('status') }}</span>
|
||||
</div>
|
||||
|
||||
<div class="control-group" :class="[errors.has('end_other_rules') ? 'has-error' : '']">
|
||||
<label for="end_other_rules" class="required">{{ __('admin::app.promotion.general-info.end_other_rules') }}</label>
|
||||
|
||||
<select type="text" class="control" name="end_other_rules" v-model="end_other_rules" v-validate="'required'" data-vv-as=""{{ __('admin::app.promotion.general-info.end_other_rules') }}"">
|
||||
<option disabled="disabled">Select option</option>
|
||||
<option value="1">Yes</option>
|
||||
<option value="0">No</option>
|
||||
</select>
|
||||
|
||||
<span class="control-error" v-if="errors.has('end_other_rules')">@{{ errors.first('end_other_rules') }}</span>
|
||||
</div>
|
||||
|
||||
<datetime :name="starts_from">
|
||||
<div class="control-group" :class="[errors.has('starts_from') ? 'has-error' : '']">
|
||||
<label for="starts_from" class="required">{{ __('admin::app.promotion.general-info.starts-from') }}</label>
|
||||
|
||||
<input type="text" class="control" v-model="starts_from" name="starts_from" v-validate="'required'" data-vv-as=""{{ __('admin::app.promotion.general-info.starts-from') }}"">
|
||||
|
||||
<span class="control-error" v-if="errors.has('starts_from')">@{{ errors.first('starts_from') }}</span>
|
||||
</div>
|
||||
</datetime>
|
||||
|
||||
<datetime :name="starts_from">
|
||||
<div class="control-group" :class="[errors.has('ends_till') ? 'has-error' : '']">
|
||||
<label for="ends_till" class="required">{{ __('admin::app.promotion.general-info.ends-till') }}</label>
|
||||
|
||||
<input type="text" class="control" v-model="ends_till" name="ends_till" v-validate="'required'" data-vv-as=""{{ __('admin::app.promotion.general-info.ends-till') }}"">
|
||||
|
||||
<span class="control-error" v-if="errors.has('ends_till')">@{{ errors.first('ends_till') }}</span>
|
||||
</div>
|
||||
</datetime>
|
||||
|
||||
<div class="control-group" :class="[errors.has('priority') ? 'has-error' : '']">
|
||||
<label for="priority" class="required">{{ __('admin::app.promotion.general-info.priority') }}</label>
|
||||
|
||||
<input type="number" class="control" step="1" name="priority" v-model="priority" v-validate="'required|numeric|min_value:1'" value="{{ old('priority') }}" data-vv-as=""{{ __('admin::app.promotion.general-info.priority') }}"">
|
||||
|
||||
<span class="control-error" v-if="errors.has('priority')">@{{ errors.first('priority') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</accordian>
|
||||
|
||||
<accordian :active="false" title="Conditions">
|
||||
<div slot="body">
|
||||
<div class="add-condition">
|
||||
<input type="hidden" v-model="global_condition.allorany">
|
||||
<input type="hidden" v-model="global_condition.alltrueorfalse">
|
||||
<div class="control-group" :class="[errors.has('criteria') ? 'has-error' : '']">
|
||||
<label for="criteria" class="required">{{ __('admin::app.promotion.general-info.add-condition') }}</label>
|
||||
|
||||
<select type="text" class="control" name="criteria" v-model="criteria" v-validate="'required'" value="" data-vv-as=""{{ __('admin::app.promotion.general-info.cust-groups') }}"">
|
||||
<option value="attribute">Attribute</option>
|
||||
<option value="category">Category</option>
|
||||
<option value="attribute_family">Attribute Family</option>
|
||||
</select>
|
||||
|
||||
<span class="control-error" v-if="errors.has('criteria')">@{{ errors.first('criteria') }}</span>
|
||||
</div>
|
||||
|
||||
<span class="btn btn-primary btn-lg" v-on:click="addCondition">Add Condition</span>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="condition-set" v-if="conditions_list.length">
|
||||
{{-- <span class="control-group" v-on:click="genericGroupCondition" v-if="generic_condition">
|
||||
{{ __('admin::app.promotion.general-info.all-conditions-true') }}
|
||||
</span>
|
||||
|
||||
<span class="control-group" v-on:click="genericGroupCondition" v-if="! generic_condition">
|
||||
{{ __('admin::app.promotion.general-info.assuming') }}
|
||||
<select>
|
||||
<option selected="selected">All</option>
|
||||
<option>Any</option>
|
||||
</select>
|
||||
{{ __('admin::app.promotion.general-info.are') }}
|
||||
<select>
|
||||
<option selected="selected">True</option>
|
||||
<option>False</option>
|
||||
</select>
|
||||
</span> --}}
|
||||
|
||||
<!-- Conditions -->
|
||||
<div v-for="(condition, index) in conditions_list" :key="index">
|
||||
<div class="control-container mt-20" v-if='conditions_list[index].criteria == "attribute"'>
|
||||
<div class="title-bar">
|
||||
{{-- <span>Group </span>
|
||||
<input type="checkbox" v-model="condition_groups" v-on:click="groupSelected(index)" /> --}}
|
||||
|
||||
<span>Attribute is </span>
|
||||
<span class="icon cross-icon" v-on:click="removeAttr(index)"></span>
|
||||
</div>
|
||||
|
||||
<div class="control-group mt-10" :key="index">
|
||||
<select class="control" name="attributes[]" v-model="conditions_list[index].attribute" v-validate="'required'" title="You Can Make Multiple Selections Here" style="margin-right: 15px;" v-on:change="enableCondition($event, index)">
|
||||
<option disabled="disabled">Select attribute</option>
|
||||
<option v-for="(attr_ip, i) in attrs_input" :value="attr_ip.code">@{{ attr_ip.name }}</option>
|
||||
</select>
|
||||
|
||||
<div v-if='conditions_list[index].type == "text" || conditions_list[index].type == "textarea"'>
|
||||
<select class="control" name="attributes[]" v-model="conditions_list[index].condition" v-validate="'required'" style="margin-right: 15px;">
|
||||
@foreach($catalog_rule[4]['text'] as $key => $value)
|
||||
<option value="{{ $key }}">{{ __($value) }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
|
||||
<input type="text" class="control" name="attributes[]" v-model="conditions_list[index].value" placeholder="Enter Value">
|
||||
</div>
|
||||
|
||||
<div v-if='conditions_list[index].type == "price"'>
|
||||
<select class="control" name="attributes[]" v-model="conditions_list[index].condition" v-validate="'required'" style="margin-right: 15px;">
|
||||
@foreach($catalog_rule[4]['numeric'] as $key => $value)
|
||||
<option value="{{ $key }}">{{ __($value) }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
|
||||
<input type="number" step="0.1000" class="control" name="attributes[]" v-model="conditions_list[index].value" placeholder="Enter Value">
|
||||
</div>
|
||||
|
||||
<div v-else-if='conditions_list[index].type == "boolean"'>
|
||||
<select class="control" name="attributes[]" v-model="conditions_list[index].condition" v-validate="'required'" style="margin-right: 15px;">
|
||||
<option selected="selected">is</option>
|
||||
</select>
|
||||
|
||||
<select class="control" name="attributes[]" v-model="conditions_list[index].value">
|
||||
@foreach($catalog_rule[4]['boolean'] as $key => $value)
|
||||
<option value="{{ $key }}">{{ __($value) }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div v-else-if='conditions_list[index].type == "date"'>
|
||||
<select class="control" name="attributes[]" v-model="conditions_list[index].condition" v-validate="'required'" style="margin-right: 15px;">
|
||||
@foreach($catalog_rule[4]['numeric'] as $key => $value)
|
||||
<option value="{{ $key }}">{{ __($value) }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
|
||||
<date>
|
||||
<input type="text" class="control" v-model="conditions_list[index].value" name="attributes[]" v-validate="'required'" value="Enter Value">
|
||||
</date>
|
||||
</div>
|
||||
|
||||
<div v-else-if='conditions_list[index].type == "datetime"'>
|
||||
<select class="control" name="attributes[]" v-model="conditions_list[index].condition" v-validate="'required'" style="margin-right: 15px;">
|
||||
@foreach($catalog_rule[4]['numeric'] as $key => $value)
|
||||
<option value="{{ $key }}">{{ __($value) }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
|
||||
<datetime>
|
||||
<input type="text" class="control" v-model="conditions_list[index].value" name="attributes[]" v-validate="'required'" value="Enter Value">
|
||||
</datetime>
|
||||
</div>
|
||||
|
||||
<div v-else-if='conditions_list[index].type == "select" || conditions_list[index].type == "multiselect"'>
|
||||
<select class="control" name="attributes[]" v-model="conditions_list[index].condition" v-validate="'required'" style="margin-right: 15px;">
|
||||
@foreach($catalog_rule[4]['text'] as $key => $value)
|
||||
<option value="{{ $key }}">{{ __($value) }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
|
||||
<select class="control" v-model="conditions_list[index].value" name="attributes[]" v-validate="'required'" multiple>
|
||||
<option v-for="option in conditions_list[index].options" :value="option.id">@{{ option.admin_name }}</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="control-container mt-20" v-if='conditions_list[index].criteria == "category"'>
|
||||
<div class="title-bar">
|
||||
<span>Category </span>
|
||||
|
||||
{{-- <span>Group </span>
|
||||
<input type="checkbox" v-model="condition_groups" v-on:click="groupSelected(index)" /> --}}
|
||||
|
||||
<span class="icon cross-icon" v-on:click="removeAttr(index)"></span>
|
||||
</div>
|
||||
|
||||
<div class="control-group mt-10" :key="index">
|
||||
<input type="hidden" class="control" name="attributes[]" v-model="conditions_list[index].category" v-validate="'required'" style="margin-right: 15px;" v-on:change="enableCondition($event, index)">
|
||||
|
||||
<select class="control" name="attributes[]" v-model="conditions_list[index].condition" v-validate="'required'" style="margin-right: 15px;">
|
||||
@foreach($catalog_rule[4]['text'] as $key => $value)
|
||||
<option value="{{ $key }}">{{ __($value) }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
|
||||
<select class="control" name="attributes[]" v-model="conditions_list[index].value" placeholder="Enter Value" multiple>
|
||||
<option v-for="(category, index) in categories" :value="category.id">@{{ category.name }}</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="control-container mt-20" v-if='conditions_list[index].criteria == "attribute_family"'>
|
||||
<div class="title-bar">
|
||||
<span>Attribute Family </span>
|
||||
|
||||
{{-- <span>Group </span>
|
||||
<input type="checkbox" v-model="condition_groups" v-on:click="groupSelected(index)" /> --}}
|
||||
|
||||
<span class="icon cross-icon" v-on:click="removeAttr(index)"></span>
|
||||
</div>
|
||||
|
||||
<div class="control-group mt-10" :key="index">
|
||||
<input type="hidden" class="control" name="attributes[]" v-model="conditions_list[index].family" v-validate="'required'" style="margin-right: 15px;" v-on:change="enableCondition($event, index)">
|
||||
|
||||
<select class="control" name="attributes[]" v-model="conditions_list[index].condition" v-validate="'required'" style="margin-right: 15px;">
|
||||
@foreach($catalog_rule[4]['boolean'] as $key => $value)
|
||||
<option value="{{ $key }}">{{ __($value) }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
|
||||
<select class="control" name="attributes[]" v-model="conditions_list[index].value" placeholder="Enter Value">
|
||||
<option v-for="(attr_family, index) in attr_families" :value="attr_family.id">@{{ attr_family.name }}</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<input type="hidden" name="all_conditions[]" v-model="all_conditions">
|
||||
</div>
|
||||
</div>
|
||||
</accordian>
|
||||
|
||||
<accordian :active="false" title="Actions">
|
||||
<div slot="body">
|
||||
<div class="control-group" :class="[errors.has('apply') ? 'has-error' : '']">
|
||||
<label for="apply" class="required">Apply</label>
|
||||
|
||||
<select class="control" name="apply" v-model="apply" v-validate="'required'" value="{{ old('apply') }}" data-vv-as=""Apply As"" v-on:change="detectApply">
|
||||
@foreach($catalog_rule[3]['actions'] as $key => $value)
|
||||
<option value="{{ $key }}">{{ __($value) }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
|
||||
<span class="control-error" v-if="errors.has('apply')">@{{ errors.first('apply') }}</span>
|
||||
</div>
|
||||
|
||||
<div class="control-group" :class="[errors.has('disc_amount') ? 'has-error' : '']" v-if="apply_amt">
|
||||
<label for="disc_amount" class="required">{{ __('admin::app.promotion.general-info.disc_amt') }}</label>
|
||||
|
||||
<input type="number" step="1.0000" class="control" name="disc_amount" v-model="disc_amount" v-validate="'required|decimal|min_value:0.0001'" value="{{ old('disc_amount') }}" data-vv-as=""{{ __('admin::app.promotion.general-info.disc_amt') }}"">
|
||||
|
||||
<span class="control-error" v-if="errors.has('disc_amount')">@{{ errors.first('disc_amount') }}</span>
|
||||
</div>
|
||||
|
||||
<div class="control-group" :class="[errors.has('disc_percent') ? 'has-error' : '']" v-if="apply_prct">
|
||||
<label for="disc_percent" class="required">{{ __('admin::app.promotion.general-info.disc_percent') }}</label>
|
||||
|
||||
<input type="number" step="0.5000" class="control" name="disc_percent" v-model="disc_percent" v-validate="'required|decimal|min_value:0.0001'" value="{{ old('disc_percent') }}" data-vv-as=""{{ __('admin::app.promotion.general-info.disc_percent') }}"">
|
||||
|
||||
<span class="control-error" v-if="errors.has('disc_percent')">@{{ errors.first('disc_percent') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</accordian>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script>
|
||||
Vue.component('catalog-rule', {
|
||||
template: '#catalog-rule-form-template',
|
||||
|
||||
inject: ['$validator'],
|
||||
|
||||
data () {
|
||||
return {
|
||||
all_conditions: [],
|
||||
apply: null,
|
||||
apply_amt: false,
|
||||
apply_prct: false,
|
||||
applied_config: @json($catalog_rule[3]),
|
||||
conditions_list: [],
|
||||
attr_families: @json($catalog_rule[5]),
|
||||
attrs_input: @json($catalog_rule[0]),
|
||||
attrs_options: @json($catalog_rule[2]),
|
||||
global_condition: {
|
||||
allorany: false,
|
||||
alltrueorfalse: true
|
||||
},
|
||||
attr_object: {
|
||||
criteria: 'attribute',
|
||||
attribute: null,
|
||||
condition: null,
|
||||
type: null,
|
||||
value: null
|
||||
},
|
||||
cat_object: {
|
||||
criteria: 'category',
|
||||
category: 'category',
|
||||
condition: null,
|
||||
value: []
|
||||
},
|
||||
fam_object: {
|
||||
criteria: 'attribute_family',
|
||||
family: 'attribute_family',
|
||||
condition: null,
|
||||
value: null
|
||||
},
|
||||
categories: @json($catalog_rule[1]),
|
||||
cats_count: 0,
|
||||
channels: [],
|
||||
conditions: [],
|
||||
condition_groups: [],
|
||||
criteria: null,
|
||||
customer_groups: [],
|
||||
description: null,
|
||||
disc_amount: 0.0,
|
||||
disc_percent: 0.0,
|
||||
ends_till: null,
|
||||
end_other_rules: null,
|
||||
generic_condition: true,
|
||||
name: null,
|
||||
priority: 0,
|
||||
starts_from: null,
|
||||
status: null
|
||||
}
|
||||
},
|
||||
|
||||
mounted () {
|
||||
},
|
||||
|
||||
methods: {
|
||||
addCondition () {
|
||||
if (this.criteria == 'attribute' || this.criteria == 'attribute_family' || this.criteria == 'category') {
|
||||
this.condition_on = this.criteria;
|
||||
} else {
|
||||
alert('please try again');
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.condition_on == 'attribute') {
|
||||
this.conditions_list.push(this.attr_object);
|
||||
|
||||
this.attr_object = {
|
||||
criteria: this.condition_on,
|
||||
attribute: null,
|
||||
condition: null,
|
||||
value: null,
|
||||
type: null,
|
||||
options: null
|
||||
};
|
||||
} else if (this.condition_on == 'category') {
|
||||
this.conditions_list.push(this.cat_object);
|
||||
|
||||
this.cat_object = {
|
||||
criteria: this.condition_on,
|
||||
category: 'category',
|
||||
condition: null,
|
||||
value: []
|
||||
};
|
||||
} else if (this.condition_on == 'attribute_family') {
|
||||
this.conditions_list.push(this.fam_object);
|
||||
|
||||
this.fam_object = {
|
||||
criteria: this.condition_on,
|
||||
family: 'attribute_family',
|
||||
condition: null,
|
||||
value: null
|
||||
};
|
||||
}
|
||||
},
|
||||
|
||||
enableCondition(event, index) {
|
||||
this.conditions_list[index].type = this.attrs_input[event.target.selectedIndex - 1].type;
|
||||
var this_this = this;
|
||||
|
||||
if (this.attrs_input[event.target.selectedIndex - 1].type == 'select' || this.attrs_input[event.target.selectedIndex - 1].type == 'multiselect') {
|
||||
|
||||
this.conditions_list[index].options = this.attrs_options[this.attrs_input[event.target.selectedIndex - 1].code];
|
||||
this.conditions_list[index].value = [];
|
||||
}
|
||||
},
|
||||
|
||||
detectApply() {
|
||||
if (this.apply == 0 || this.apply == 2) {
|
||||
this.apply_prct = true;
|
||||
this.apply_amt = false;
|
||||
} else if (this.apply == 1 || this.apply == 3) {
|
||||
this.apply_prct = false;
|
||||
this.apply_amt = true;
|
||||
}
|
||||
},
|
||||
|
||||
removeAttr(index) {
|
||||
this.conditions_list.splice(index, 1);
|
||||
},
|
||||
|
||||
removeCat(index) {
|
||||
this.cats.splice(index, 1);
|
||||
},
|
||||
|
||||
onSubmit: function (e) {
|
||||
this.$validator.validateAll().then(result => {
|
||||
if (result) {
|
||||
e.target.submit();
|
||||
}
|
||||
});
|
||||
|
||||
for (index in this.conditions_list) {
|
||||
if (this.conditions_list[index].condition == null || this.conditions_list[index].condition == "" || this.conditions_list[index].condition == undefined) {
|
||||
window.flashMessages = [{'type': 'alert-error', 'message': "{{ __('admin::app.promotion.catalog.condition-missing') }}" }];
|
||||
|
||||
this.$root.addFlashMessages();
|
||||
|
||||
return false;
|
||||
} else if (this.conditions_list[index].value == null || this.conditions_list[index].value == "" || this.conditions_list[index].value == undefined) {
|
||||
window.flashMessages = [{'type': 'alert-error', 'message': "{{ __('admin::app.promotion.catalog.condition-missing') }}" }];
|
||||
|
||||
this.$root.addFlashMessages();
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (this.conditions_list.length == 0) {
|
||||
window.flashMessages = [{'type': 'alert-error', 'message': "{{ __('admin::app.promotion.catalog.condition-missing') }}" }];
|
||||
|
||||
this.$root.addFlashMessages();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
this.all_conditions = JSON.stringify(this.conditions_list);
|
||||
},
|
||||
|
||||
genericGroupCondition() {
|
||||
this.generic_condition = false;
|
||||
},
|
||||
|
||||
addFlashMessages() {
|
||||
const flashes = this.$refs.flashes;
|
||||
|
||||
flashMessages.forEach(function(flash) {
|
||||
flashes.addFlash(flash);
|
||||
}, this);
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
@endpush
|
||||
@stop
|
||||
|
|
@ -0,0 +1,542 @@
|
|||
@extends('admin::layouts.content')
|
||||
|
||||
@section('page_title')
|
||||
{{ __('admin::app.promotion.edit-catalog-rule') }}
|
||||
@stop
|
||||
|
||||
@section('content')
|
||||
<div class="content">
|
||||
<catalog-rule></catalog-rule>
|
||||
</div>
|
||||
|
||||
@push('scripts')
|
||||
<script type="text/x-template" id="catalog-rule-form-template">
|
||||
<div>
|
||||
<form method="POST" action="{{ route('admin.catalog-rule.update', $catalog_rule[5]->id) }}" @submit.prevent="onSubmit">
|
||||
@csrf
|
||||
|
||||
<div class="page-header">
|
||||
<div class="page-title">
|
||||
<h1>
|
||||
<i class="icon angle-left-icon back-link" onclick="history.length > 1 ? history.go(-1) : window.location = '{{ url('/admin/dashboard') }}';"></i>
|
||||
|
||||
{{ __('admin::app.promotion.edit-catalog-rule') }}
|
||||
</h1>
|
||||
</div>
|
||||
|
||||
<div class="page-action">
|
||||
<button type="submit" class="btn btn-lg btn-primary">
|
||||
{{ __('admin::app.promotion.edit-btn-title') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="page-content">
|
||||
<div class="form-container">
|
||||
@csrf()
|
||||
|
||||
<accordian :active="true" title="Information">
|
||||
<div slot="body">
|
||||
<div class="control-group" :class="[errors.has('name') ? 'has-error' : '']">
|
||||
<label for="name" class="required">{{ __('admin::app.promotion.general-info.name') }}</label>
|
||||
|
||||
<input type="text" class="control" name="name" v-model="name" v-validate="'required'" value="{{ old('name') }}" data-vv-as=""{{ __('admin::app.promotion.general-info.name') }}"">
|
||||
|
||||
<span class="control-error" v-if="errors.has('name')">@{{ errors.first('name') }}</span>
|
||||
</div>
|
||||
|
||||
<div class="control-group" :class="[errors.has('description') ? 'has-error' : '']">
|
||||
<label for="description">{{ __('admin::app.promotion.general-info.description') }}</label>
|
||||
|
||||
<textarea class="control" name="description" v-model="description" v-validate="'required'" value="{{ old('description') }}" data-vv-as=""{{ __('admin::app.promotion.general-info.description') }}""></textarea>
|
||||
|
||||
<span class="control-error" v-if="errors.has('description')">@{{ errors.first('description') }}</span>
|
||||
</div>
|
||||
|
||||
<div class="control-group" :class="[errors.has('customer_groups[]') ? 'has-error' : '']">
|
||||
<label for="customer_groups" class="required">{{ __('admin::app.promotion.general-info.cust-groups') }}</label>
|
||||
|
||||
<select type="text" class="control" name="customer_groups[]" v-model="customer_groups" v-validate="'required'" data-vv-as=""{{ __('admin::app.promotion.general-info.cust-groups') }}"" multiple="multiple">
|
||||
<option disabled="disabled">Select Customer Groups</option>
|
||||
@foreach(app('Webkul\Customer\Repositories\CustomerGroupRepository')->all() as $channel)
|
||||
<option value="{{ $channel->id }}">{{ $channel->name }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
|
||||
<span class="control-error" v-if="errors.has('customer_groups[]')">@{{ errors.first('customer_groups[]') }}</span>
|
||||
</div>
|
||||
|
||||
<div class="control-group" :class="[errors.has('channels[]') ? 'has-error' : '']">
|
||||
<label for="channels" class="required">{{ __('admin::app.promotion.general-info.channels') }}</label>
|
||||
|
||||
<select type="text" class="control" name="channels[]" v-model="channels" v-validate="'required'" data-vv-as=""{{ __('admin::app.promotion.general-info.channels') }}"" multiple="multiple">
|
||||
<option disabled="disabled">Select Channels</option>
|
||||
@foreach(app('Webkul\Core\Repositories\ChannelRepository')->all() as $channel)
|
||||
<option value="{{ $channel->id }}">{{ $channel->name }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
|
||||
<span class="control-error" v-if="errors.has('channels[]')">@{{ errors.first('channels[]') }}</span>
|
||||
</div>
|
||||
|
||||
<div class="control-group" :class="[errors.has('status') ? 'has-error' : '']">
|
||||
<label for="status" class="required">{{ __('admin::app.promotion.general-info.status') }}</label>
|
||||
|
||||
<select type="text" class="control" name="status" v-model="status" v-validate="'required'" data-vv-as=""{{ __('admin::app.promotion.general-info.status') }}"">
|
||||
<option disabled="disabled">Select status</option>
|
||||
<option value="1">Yes</option>
|
||||
<option value="0">No</option>
|
||||
</select>
|
||||
|
||||
<span class="control-error" v-if="errors.has('status')">@{{ errors.first('status') }}</span>
|
||||
</div>
|
||||
|
||||
<div class="control-group" :class="[errors.has('end_other_rules') ? 'has-error' : '']">
|
||||
<label for="end_other_rules" class="required">{{ __('admin::app.promotion.general-info.end_other_rules') }}</label>
|
||||
|
||||
<select type="text" class="control" name="end_other_rules" v-model="end_other_rules" v-validate="'required'" data-vv-as=""{{ __('admin::app.promotion.general-info.end_other_rules') }}"">
|
||||
<option disabled="disabled">Select option</option>
|
||||
<option value="1">Yes</option>
|
||||
<option value="0">No</option>
|
||||
</select>
|
||||
|
||||
<span class="control-error" v-if="errors.has('end_other_rules')">@{{ errors.first('end_other_rules') }}</span>
|
||||
</div>
|
||||
|
||||
<datetime :name="starts_from">
|
||||
<div class="control-group" :class="[errors.has('starts_from') ? 'has-error' : '']">
|
||||
<label for="starts_from" class="required">{{ __('admin::app.promotion.general-info.starts-from') }}</label>
|
||||
|
||||
<input type="text" class="control" v-model="starts_from" name="starts_from" v-validate="'required'" data-vv-as=""{{ __('admin::app.promotion.general-info.starts-from') }}"">
|
||||
|
||||
<span class="control-error" v-if="errors.has('starts_from')">@{{ errors.first('starts_from') }}</span>
|
||||
</div>
|
||||
</datetime>
|
||||
|
||||
<datetime :name="starts_from">
|
||||
<div class="control-group" :class="[errors.has('ends_till') ? 'has-error' : '']">
|
||||
<label for="ends_till" class="required">{{ __('admin::app.promotion.general-info.ends-till') }}</label>
|
||||
|
||||
<input type="text" class="control" v-model="ends_till" name="ends_till" v-validate="'required'" data-vv-as=""{{ __('admin::app.promotion.general-info.ends-till') }}"">
|
||||
|
||||
<span class="control-error" v-if="errors.has('ends_till')">@{{ errors.first('ends_till') }}</span>
|
||||
</div>
|
||||
</datetime>
|
||||
|
||||
<div class="control-group" :class="[errors.has('priority') ? 'has-error' : '']">
|
||||
<label for="priority" class="required">{{ __('admin::app.promotion.general-info.priority') }}</label>
|
||||
|
||||
<input type="number" class="control" step="1" name="priority" v-model="priority" v-validate="'required|numeric|min_value:1'" value="{{ old('priority') }}" data-vv-as=""{{ __('admin::app.promotion.general-info.priority') }}"">
|
||||
|
||||
<span class="control-error" v-if="errors.has('priority')">@{{ errors.first('priority') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</accordian>
|
||||
|
||||
<accordian :active="true" title="Conditions">
|
||||
<div slot="body">
|
||||
<div class="add-condition">
|
||||
<div class="control-group" :class="[errors.has('criteria') ? 'has-error' : '']">
|
||||
<label for="criteria" class="required">{{ __('admin::app.promotion.general-info.add-condition') }}</label>
|
||||
|
||||
<select type="text" class="control" name="criteria" v-model="criteria" v-validate="'required'" value="" data-vv-as=""{{ __('admin::app.promotion.general-info.cust-groups') }}"">
|
||||
<option value="attribute">Attribute</option>
|
||||
<option value="category">Category</option>
|
||||
<option value="attribute_family">Attribute Family</option>
|
||||
</select>
|
||||
|
||||
<span class="control-error" v-if="errors.has('criteria')">@{{ errors.first('criteria') }}</span>
|
||||
</div>
|
||||
|
||||
<span class="btn btn-primary btn-lg" v-on:click="addCondition">Add Condition</span>
|
||||
</div>
|
||||
|
||||
<div class="condition-set" v-if="conditions_list.length">
|
||||
<!-- Attribute -->
|
||||
<div v-for="(condition, index) in conditions_list" :key="index">
|
||||
<div class="control-container mt-20" v-if='conditions_list[index].criteria == "attribute"'>
|
||||
<div class="title-bar">
|
||||
{{-- <span>Group </span>
|
||||
<input type="checkbox" v-model="condition_groups" v-on:click="groupSelected(index)" /> --}}
|
||||
|
||||
<span>Attribute is </span>
|
||||
<span class="icon cross-icon" v-on:click="removeAttr(index)"></span>
|
||||
</div>
|
||||
|
||||
<div class="control-group mt-10" :key="index">
|
||||
<select class="control" name="attributes[]" v-model="conditions_list[index].attribute" v-validate="'required'" title="You Can Make Multiple Selections Here" style="margin-right: 15px;" v-on:change="enableCondition($event, index)">
|
||||
<option disabled="disabled">Select attribute</option>
|
||||
<option v-for="(attr_ip, i) in attrs_input" :value="attr_ip.code">@{{ attr_ip.name }}</option>
|
||||
</select>
|
||||
|
||||
<div v-if='conditions_list[index].type == "text" || conditions_list[index].type == "textarea"'>
|
||||
<select class="control" name="attributes[]" v-model="conditions_list[index].condition" v-validate="'required'" style="margin-right: 15px;">
|
||||
@foreach($catalog_rule[4]['text'] as $key => $value)
|
||||
<option value="{{ $key }}">{{ __($value) }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
|
||||
<input type="text" class="control" name="attributes[]" v-model="conditions_list[index].value" placeholder="Enter Value">
|
||||
</div>
|
||||
|
||||
<div v-if='conditions_list[index].type == "price"'>
|
||||
<select class="control" name="attributes[]" v-model="conditions_list[index].condition" v-validate="'required'" style="margin-right: 15px;">
|
||||
@foreach($catalog_rule[4]['numeric'] as $key => $value)
|
||||
<option value="{{ $key }}">{{ __($value) }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
|
||||
<input type="number" step="0.1000" class="control" name="attributes[]" v-model="conditions_list[index].value" placeholder="Enter Value">
|
||||
</div>
|
||||
|
||||
<div v-else-if='conditions_list[index].type == "boolean"'>
|
||||
<select class="control" name="attributes[]" v-model="conditions_list[index].condition" v-validate="'required'" style="margin-right: 15px;">
|
||||
<option selected="selected">is</option>
|
||||
</select>
|
||||
|
||||
<select class="control" name="attributes[]" v-model="conditions_list[index].value">
|
||||
@foreach($catalog_rule[4]['boolean'] as $key => $value)
|
||||
<option value="{{ $key }}">{{ __($value) }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div v-else-if='conditions_list[index].type == "date"'>
|
||||
<select class="control" name="attributes[]" v-model="conditions_list[index].condition" v-validate="'required'" style="margin-right: 15px;">
|
||||
@foreach($catalog_rule[4]['numeric'] as $key => $value)
|
||||
<option value="{{ $key }}">{{ __($value) }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
|
||||
<date>
|
||||
<input type="text" class="control" v-model="conditions_list[index].value" name="attributes[]" v-validate="'required'" value="Enter Value">
|
||||
</date>
|
||||
</div>
|
||||
|
||||
<div v-else-if='conditions_list[index].type == "datetime"'>
|
||||
<select class="control" name="attributes[]" v-model="conditions_list[index].condition" v-validate="'required'" style="margin-right: 15px;">
|
||||
@foreach($catalog_rule[4]['numeric'] as $key => $value)
|
||||
<option value="{{ $key }}">{{ __($value) }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
|
||||
<datetime>
|
||||
<input type="text" class="control" v-model="conditions_list[index].value" name="attributes[]" v-validate="'required'" value="Enter Value">
|
||||
</datetime>
|
||||
</div>
|
||||
|
||||
<div v-else-if='conditions_list[index].type == "select" || conditions_list[index].type == "multiselect"'>
|
||||
<select class="control" name="attributes[]" v-model="conditions_list[index].condition" v-validate="'required'" style="margin-right: 15px;">
|
||||
@foreach($catalog_rule[4]['text'] as $key => $value)
|
||||
<option value="{{ $key }}">{{ __($value) }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
|
||||
<select class="control" v-model="conditions_list[index].value" name="attributes[]" v-validate="'required'" multiple>
|
||||
<option v-for="option in conditions_list[index].options" :value="option.id">@{{ option.admin_name }}</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="control-container mt-20" v-if='conditions_list[index].criteria == "category"'>
|
||||
<div class="title-bar">
|
||||
<span>Category </span>
|
||||
|
||||
{{-- <span>Group </span>
|
||||
<input type="checkbox" v-model="condition_groups" v-on:click="groupSelected(index)" /> --}}
|
||||
|
||||
<span class="icon cross-icon" v-on:click="removeAttr(index)"></span>
|
||||
</div>
|
||||
|
||||
<div class="control-group mt-10" :key="index">
|
||||
<input type="hidden" class="control" name="attributes[]" v-model="conditions_list[index].category" v-validate="'required'" style="margin-right: 15px;" v-on:change="enableCondition($event, index)">
|
||||
|
||||
<select class="control" name="attributes[]" v-model="conditions_list[index].condition" v-validate="'required'" style="margin-right: 15px;">
|
||||
@foreach($catalog_rule[4]['text'] as $key => $value)
|
||||
<option value="{{ $key }}">{{ __($value) }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
|
||||
<select class="control" name="attributes[]" v-model="conditions_list[index].value" placeholder="Enter Value" multiple>
|
||||
<option v-for="(category, index) in categories" :value="category.id">@{{ category.name }}</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="control-container mt-20" v-if='conditions_list[index].criteria == "attribute_family"'>
|
||||
<div class="title-bar">
|
||||
<span>Attribute Family </span>
|
||||
|
||||
{{-- <span>Group </span>
|
||||
<input type="checkbox" v-model="condition_groups" v-on:click="groupSelected(index)" /> --}}
|
||||
|
||||
<span class="icon cross-icon" v-on:click="removeAttr(index)"></span>
|
||||
</div>
|
||||
|
||||
<div class="control-group mt-10" :key="index">
|
||||
<input type="hidden" class="control" name="attributes[]" v-model="conditions_list[index].family" v-validate="'required'" style="margin-right: 15px;" v-on:change="enableCondition($event, index)">
|
||||
|
||||
<select class="control" name="attributes[]" v-model="conditions_list[index].condition" v-validate="'required'" style="margin-right: 15px;">
|
||||
@foreach($catalog_rule[4]['boolean'] as $key => $value)
|
||||
<option value="{{ $key }}">{{ __($value) }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
|
||||
<select class="control" name="attributes[]" v-model="conditions_list[index].value" placeholder="Enter Value">
|
||||
<option v-for="(attr_family, index) in attr_families" :value="attr_family.id">@{{ attr_family.name }}</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<input type="hidden" name="all_conditions[]" v-model="all_conditions">
|
||||
</div>
|
||||
</div>
|
||||
</accordian>
|
||||
|
||||
<accordian :active="true" title="Actions">
|
||||
<div slot="body">
|
||||
<div class="control-group" :class="[errors.has('apply') ? 'has-error' : '']">
|
||||
<label for="apply" class="required">Apply</label>
|
||||
|
||||
<select class="control" name="apply" v-model="apply" v-validate="'required'" value="{{ old('apply') }}" data-vv-as=""Apply As"" v-on:change="detectApply">
|
||||
@foreach($catalog_rule[3]['actions'] as $key => $value)
|
||||
<option value="{{ $key }}">{{ __($value) }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
|
||||
<span class="control-error" v-if="errors.has('apply')">@{{ errors.first('apply') }}</span>
|
||||
</div>
|
||||
|
||||
<div class="control-group" :class="[errors.has('disc_amount') ? 'has-error' : '']" v-if="apply_amt">
|
||||
<label for="disc_amount" class="required">{{ __('admin::app.promotion.general-info.disc_amt') }}</label>
|
||||
|
||||
<input type="number" step="1.0000" class="control" name="disc_amount" v-model="disc_amount" v-validate="'required|decimal|min_value:0.0001'" value="{{ old('disc_amount') }}" data-vv-as=""{{ __('admin::app.promotion.general-info.disc_amt') }}"">
|
||||
|
||||
<span class="control-error" v-if="errors.has('disc_amount')">@{{ errors.first('disc_amount') }}</span>
|
||||
</div>
|
||||
|
||||
<div class="control-group" :class="[errors.has('disc_percent') ? 'has-error' : '']" v-if="apply_prct">
|
||||
<label for="disc_percent" class="required">{{ __('admin::app.promotion.general-info.disc_percent') }}</label>
|
||||
|
||||
<input type="number" step="0.5000" class="control" name="disc_percent" v-model="disc_percent" v-validate="'required|decimal|min_value:0.0001'" value="{{ old('disc_percent') }}" data-vv-as=""{{ __('admin::app.promotion.general-info.disc_percent') }}"">
|
||||
|
||||
<span class="control-error" v-if="errors.has('disc_percent')">@{{ errors.first('disc_percent') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</accordian>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script>
|
||||
Vue.component('catalog-rule', {
|
||||
template: '#catalog-rule-form-template',
|
||||
|
||||
inject: ['$validator'],
|
||||
|
||||
data () {
|
||||
return {
|
||||
all_conditions: [],
|
||||
apply: null,
|
||||
apply_amt: false,
|
||||
apply_prct: false,
|
||||
applied_config: @json($catalog_rule[3]),
|
||||
conditions_list: [],
|
||||
attr_families: @json($catalog_rule[8]),
|
||||
attrs_input: @json($catalog_rule[0]),
|
||||
attrs_options: @json($catalog_rule[2]),
|
||||
global_condition: {
|
||||
all_conditions: false,
|
||||
all_condition: true
|
||||
},
|
||||
attr_object: {
|
||||
criteria: 'attribute',
|
||||
attribute: null,
|
||||
condition: null,
|
||||
type: null,
|
||||
value: null
|
||||
},
|
||||
cat_object: {
|
||||
criteria: 'category',
|
||||
category: 'category',
|
||||
condition: null,
|
||||
value: []
|
||||
},
|
||||
fam_object: {
|
||||
criteria: 'attribute_family',
|
||||
family: 'attribute_family',
|
||||
condition: null,
|
||||
value: null
|
||||
},
|
||||
categories: @json($catalog_rule[1]),
|
||||
cats: [],
|
||||
cats_count: 0,
|
||||
channels: [],
|
||||
conditions: [],
|
||||
criteria: null,
|
||||
customer_groups: [],
|
||||
description: null,
|
||||
disc_amount: 0.0,
|
||||
disc_percent: 0.0,
|
||||
ends_till: null,
|
||||
end_other_rules: null,
|
||||
name: null,
|
||||
priority: 0,
|
||||
starts_from: null,
|
||||
status: null,
|
||||
}
|
||||
},
|
||||
|
||||
mounted () {
|
||||
all = @json($catalog_rule[5]);
|
||||
this.name = all.name;
|
||||
this.description = all.description;
|
||||
this.apply = all.action_type;
|
||||
this.end_other_rules = all.end_other_rules;
|
||||
this.criteria = 'attribute';
|
||||
|
||||
channels = @json($catalog_rule[6]);
|
||||
for (i in channels) {
|
||||
this.channels.push(channels[i].channel_id);
|
||||
}
|
||||
|
||||
customer_groups = @json($catalog_rule[7]);
|
||||
for (i in customer_groups) {
|
||||
this.customer_groups.push(customer_groups[i].customer_group_id);
|
||||
}
|
||||
|
||||
this.conditions_list = JSON.parse(JSON.parse(all.conditions)[0]);
|
||||
this.status = @json($catalog_rule[5]).status;
|
||||
this.starts_from = @json($catalog_rule[5]).starts_from;
|
||||
this.ends_till = @json($catalog_rule[5]).ends_till;
|
||||
this.priority = @json($catalog_rule[5]).priority;
|
||||
|
||||
if (this.apply == 0 || this.apply == 2) {
|
||||
this.apply_prct = true;
|
||||
|
||||
this.disc_percent = @json($catalog_rule[5]).disc_percent;
|
||||
} else if (this.apply == 1 || this.apply == 3) {
|
||||
this.apply_amt = true;
|
||||
|
||||
this.disc_amount = @json($catalog_rule[5]).disc_amount;
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
addCondition () {
|
||||
if (this.criteria == 'attribute' || this.criteria == 'attribute_family' || this.criteria == 'category') {
|
||||
this.condition_on = this.criteria;
|
||||
} else {
|
||||
alert('please try again');
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.condition_on == 'attribute') {
|
||||
this.conditions_list.push(this.attr_object);
|
||||
|
||||
this.attr_object = {
|
||||
criteria: this.condition_on,
|
||||
attribute: null,
|
||||
condition: null,
|
||||
value: null,
|
||||
type: null,
|
||||
options: null
|
||||
};
|
||||
} else if (this.condition_on == 'category') {
|
||||
this.conditions_list.push(this.cat_object);
|
||||
|
||||
this.cat_object = {
|
||||
criteria: this.condition_on,
|
||||
category: 'category',
|
||||
condition: null,
|
||||
value: []
|
||||
};
|
||||
} else if (this.condition_on == 'attribute_family') {
|
||||
this.conditions_list.push(this.fam_object);
|
||||
|
||||
this.fam_object = {
|
||||
criteria: this.condition_on,
|
||||
family: 'attribute_family',
|
||||
condition: null,
|
||||
value: null
|
||||
};
|
||||
}
|
||||
},
|
||||
|
||||
enableCondition(event, index) {
|
||||
this.conditions_list[index].type = this.attrs_input[event.target.selectedIndex - 1].type;
|
||||
|
||||
var this_this = this;
|
||||
|
||||
if (this.attrs_input[event.target.selectedIndex - 1].type == 'select' || this.attrs_input[event.target.selectedIndex - 1].type == 'multiselect') {
|
||||
this.conditions_list[index].options = this.attrs_options[this.attrs_input[event.target.selectedIndex - 1].name];
|
||||
|
||||
this.conditions_list[index].value = [];
|
||||
}
|
||||
},
|
||||
|
||||
detectApply() {
|
||||
if (this.apply == 0 || this.apply == 2) {
|
||||
this.apply_prct = true;
|
||||
this.apply_amt = false;
|
||||
} else if (this.apply == 1 || this.apply == 3) {
|
||||
this.apply_prct = false;
|
||||
this.apply_amt = true;
|
||||
}
|
||||
},
|
||||
|
||||
removeAttr(index) {
|
||||
this.conditions_list.splice(index, 1);
|
||||
},
|
||||
|
||||
onSubmit: function (e) {
|
||||
this.$validator.validateAll().then(result => {
|
||||
if (result) {
|
||||
e.target.submit();
|
||||
}
|
||||
});
|
||||
|
||||
for (index in this.conditions_list) {
|
||||
if (this.conditions_list[index].condition == null || this.conditions_list[index].condition == "" || this.conditions_list[index].condition == undefined) {
|
||||
window.flashMessages = [{'type': 'alert-error', 'message': "{{ __('admin::app.promotion.catalog.condition-missing') }}" }];
|
||||
|
||||
this.$root.addFlashMessages();
|
||||
|
||||
return false;
|
||||
} else if (this.conditions_list[index].value == null || this.conditions_list[index].value == "" || this.conditions_list[index].value == undefined) {
|
||||
window.flashMessages = [{'type': 'alert-error', 'message': "{{ __('admin::app.promotion.catalog.condition-missing') }}" }];
|
||||
|
||||
this.$root.addFlashMessages();
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (this.conditions_list.length == 0) {
|
||||
window.flashMessages = [{'type': 'alert-error', 'message': "{{ __('admin::app.promotion.catalog.condition-missing') }}" }];
|
||||
|
||||
this.$root.addFlashMessages();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
this.all_conditions = JSON.stringify(this.conditions_list);
|
||||
},
|
||||
|
||||
addFlashMessages() {
|
||||
const flashes = this.$refs.flashes;
|
||||
|
||||
flashMessages.forEach(function(flash) {
|
||||
flashes.addFlash(flash);
|
||||
}, this);
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
@endpush
|
||||
@stop
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
@extends('admin::layouts.content')
|
||||
|
||||
@section('page_title')
|
||||
{{ __('admin::app.promotion.catalog-rule') }}
|
||||
@stop
|
||||
|
||||
@section('content')
|
||||
|
||||
<div class="content">
|
||||
<div class="page-header">
|
||||
<div class="page-title">
|
||||
<h1>{{ __('admin::app.promotion.catalog-rule') }}</h1>
|
||||
</div>
|
||||
|
||||
<div class="page-action">
|
||||
<a href="{{ route('admin.catalog-rule.apply') }}" class="btn btn-lg btn-primary">
|
||||
{{ __('Apply Rules') }}
|
||||
</a>
|
||||
|
||||
<a href="{{ route('admin.catalog-rule.create') }}" class="btn btn-lg btn-primary">
|
||||
{{ __('admin::app.promotion.add-catalog-rule') }}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="page-content">
|
||||
@inject('catalogRuleGrid','Webkul\Admin\DataGrids\CatalogRuleDataGrid')
|
||||
{!! $catalogRuleGrid->render() !!}
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
|
|
@ -13,27 +13,27 @@ class AttributeOptionTableSeeder extends Seeder
|
|||
DB::table('attribute_options')->delete();
|
||||
|
||||
DB::table('attribute_options')->insert([
|
||||
['id' => '1','admin_name' => 'Red','sort_order' => '1','attribute_id' => '23'],
|
||||
['id' => '2','admin_name' => 'Green','sort_order' => '2','attribute_id' => '23'],
|
||||
['id' => '3','admin_name' => 'Yellow','sort_order' => '3','attribute_id' => '23'],
|
||||
['id' => '4','admin_name' => 'Black','sort_order' => '4','attribute_id' => '23'],
|
||||
['id' => '5','admin_name' => 'White','sort_order' => '5','attribute_id' => '23'],
|
||||
['id' => '6','admin_name' => 'S','sort_order' => '1','attribute_id' => '24'],
|
||||
['id' => '7','admin_name' => 'M','sort_order' => '2','attribute_id' => '24'],
|
||||
['id' => '8','admin_name' => 'L','sort_order' => '3','attribute_id' => '24'],
|
||||
['id' => '9','admin_name' => 'XL','sort_order' => '4','attribute_id' => '24']
|
||||
['id' => '1', 'admin_name' => 'Red', 'sort_order' => '1', 'attribute_id' => '23'],
|
||||
['id' => '2', 'admin_name' => 'Green', 'sort_order' => '2', 'attribute_id' => '23'],
|
||||
['id' => '3', 'admin_name' => 'Yellow', 'sort_order' => '3', 'attribute_id' => '23'],
|
||||
['id' => '4', 'admin_name' => 'Black', 'sort_order' => '4', 'attribute_id' => '23'],
|
||||
['id' => '5', 'admin_name' => 'White', 'sort_order' => '5', 'attribute_id' => '23'],
|
||||
['id' => '6', 'admin_name' => 'S', 'sort_order' => '1', 'attribute_id' => '24'],
|
||||
['id' => '7', 'admin_name' => 'M', 'sort_order' => '2', 'attribute_id' => '24'],
|
||||
['id' => '8', 'admin_name' => 'L', 'sort_order' => '3', 'attribute_id' => '24'],
|
||||
['id' => '9', 'admin_name' => 'XL', 'sort_order' => '4', 'attribute_id' => '24']
|
||||
]);
|
||||
|
||||
DB::table('attribute_option_translations')->insert([
|
||||
['id' => '1','locale' => 'en','label' => 'Red','attribute_option_id' => '1'],
|
||||
['id' => '2','locale' => 'en','label' => 'Green','attribute_option_id' => '2'],
|
||||
['id' => '3','locale' => 'en','label' => 'Yellow','attribute_option_id' => '3'],
|
||||
['id' => '4','locale' => 'en','label' => 'Black','attribute_option_id' => '4'],
|
||||
['id' => '5','locale' => 'en','label' => 'White','attribute_option_id' => '5'],
|
||||
['id' => '6','locale' => 'en','label' => 'S','attribute_option_id' => '6'],
|
||||
['id' => '7','locale' => 'en','label' => 'M','attribute_option_id' => '7'],
|
||||
['id' => '8','locale' => 'en','label' => 'L','attribute_option_id' => '8'],
|
||||
['id' => '9','locale' => 'en','label' => 'XL','attribute_option_id' => '9']
|
||||
['id' => '1', 'locale' => 'en', 'label' => 'Red', 'attribute_option_id' => '1'],
|
||||
['id' => '2', 'locale' => 'en', 'label' => 'Green', 'attribute_option_id' => '2'],
|
||||
['id' => '3', 'locale' => 'en', 'label' => 'Yellow', 'attribute_option_id' => '3'],
|
||||
['id' => '4', 'locale' => 'en', 'label' => 'Black', 'attribute_option_id' => '4'],
|
||||
['id' => '5', 'locale' => 'en', 'label' => 'White', 'attribute_option_id' => '5'],
|
||||
['id' => '6', 'locale' => 'en', 'label' => 'S', 'attribute_option_id' => '6'],
|
||||
['id' => '7', 'locale' => 'en', 'label' => 'M', 'attribute_option_id' => '7'],
|
||||
['id' => '8', 'locale' => 'en', 'label' => 'L', 'attribute_option_id' => '8'],
|
||||
['id' => '9', 'locale' => 'en', 'label' => 'XL', 'attribute_option_id' => '9']
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
@ -153,6 +153,24 @@ class AttributeFamilyRepository extends Repository
|
|||
return $family;
|
||||
}
|
||||
|
||||
public function getPartial()
|
||||
{
|
||||
$attributeFamilies = $this->model->all();
|
||||
$trimmed = array();
|
||||
|
||||
foreach($attributeFamilies as $key => $attributeFamily) {
|
||||
if ($attributeFamily->name != null || $attributeFamily->name != "") {
|
||||
$trimmed[$key] = [
|
||||
'id' => $attributeFamily->id,
|
||||
'code' => $attributeFamily->code,
|
||||
'name' => $attributeFamily->name
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
return $trimmed;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $id
|
||||
* @return void
|
||||
|
|
|
|||
|
|
@ -210,4 +210,26 @@ class AttributeRepository extends Repository
|
|||
|
||||
return $attributes[$attributeFamily->id] = $attributeFamily->custom_attributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Object
|
||||
*/
|
||||
public function getPartial()
|
||||
{
|
||||
$attributes = $this->model->all();
|
||||
$trimmed = array();
|
||||
|
||||
foreach($attributes as $key => $attribute) {
|
||||
if ($attribute->code != 'tax_category_id' && ($attribute->type == 'select' || $attribute->type == 'multiselect' || $attribute->code == 'sku')) {
|
||||
array_push($trimmed, [
|
||||
'id' => $attribute->id,
|
||||
'name' => $attribute->name,
|
||||
'type' => $attribute->type,
|
||||
'code' => $attribute->code
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
return $trimmed;
|
||||
}
|
||||
}
|
||||
|
|
@ -212,4 +212,21 @@ class CategoryRepository extends Repository
|
|||
$category->save();
|
||||
}
|
||||
}
|
||||
|
||||
public function getPartial()
|
||||
{
|
||||
$categories = $this->model->all();
|
||||
$trimmed = array();
|
||||
|
||||
foreach ($categories as $key => $category) {
|
||||
if ($category->name != null || $category->name != "") {
|
||||
$trimmed[$key] = [
|
||||
'id' => $category->id,
|
||||
'name' => $category->name
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
return $trimmed;
|
||||
}
|
||||
}
|
||||
|
|
@ -12,6 +12,8 @@ use Webkul\Tax\Repositories\TaxCategoryRepository;
|
|||
use Webkul\Checkout\Models\CartPayment;
|
||||
use Webkul\Customer\Repositories\WishlistRepository;
|
||||
use Webkul\Customer\Repositories\CustomerAddressRepository;
|
||||
use Webkul\Discount\Repositories\CartRuleRepository as CartRule;
|
||||
use Webkul\Discount\Helpers\Discount;
|
||||
use Webkul\Product\Helpers\Price;
|
||||
|
||||
/**
|
||||
|
|
@ -24,81 +26,94 @@ use Webkul\Product\Helpers\Price;
|
|||
class Cart {
|
||||
|
||||
/**
|
||||
* CartRepository model
|
||||
* CartRepository instance
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
protected $cart;
|
||||
|
||||
/**
|
||||
* CartItemRepository model
|
||||
* CartItemRepository instance
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
protected $cartItem;
|
||||
|
||||
/**
|
||||
* CustomerRepository model
|
||||
* CustomerRepository instance
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
protected $customer;
|
||||
|
||||
/**
|
||||
* CartAddressRepository model
|
||||
* CartAddressRepository instance
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
protected $cartAddress;
|
||||
|
||||
/**
|
||||
* ProductRepository model
|
||||
* ProductRepository instance
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
protected $product;
|
||||
|
||||
/**
|
||||
* TaxCategoryRepository model
|
||||
* TaxCategoryRepository instance
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
protected $taxCategory;
|
||||
|
||||
/**
|
||||
* WishlistRepository model
|
||||
* WishlistRepository instance
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
protected $wishlist;
|
||||
|
||||
/**
|
||||
* CustomerAddressRepository model
|
||||
* CustomerAddressRepository instance
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
protected $customerAddress;
|
||||
protected $customerAddress;
|
||||
|
||||
/**
|
||||
* CartRule Repository instance
|
||||
*/
|
||||
protected $cartRule;
|
||||
|
||||
/**
|
||||
* Discount helper instance
|
||||
*/
|
||||
protected $discount;
|
||||
|
||||
/**
|
||||
* Suppress the session flash messages
|
||||
*/
|
||||
*/
|
||||
protected $suppressFlash;
|
||||
|
||||
/**
|
||||
* Product price helper instance
|
||||
*/
|
||||
*/
|
||||
protected $price;
|
||||
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
*
|
||||
* @param Webkul\Checkout\Repositories\CartRepository $cart
|
||||
* @param Webkul\Checkout\Repositories\CartItemRepository $cartItem
|
||||
* @param Webkul\Checkout\Repositories\CartAddressRepository $cartAddress
|
||||
* @param Webkul\Customer\Repositories\CustomerRepository $customer
|
||||
* @param Webkul\Product\Repositories\ProductRepository $product
|
||||
* @param Webkul\Product\Repositories\TaxCategoryRepository $taxCategory
|
||||
* @param Webkul\Checkout\Repositories\CartRepository $cart
|
||||
* @param Webkul\Checkout\Repositories\CartItemRepository $cartItem
|
||||
* @param Webkul\Checkout\Repositories\CartAddressRepository $cartAddress
|
||||
* @param Webkul\Customer\Repositories\CustomerRepository $customer
|
||||
* @param Webkul\Product\Repositories\ProductRepository $product
|
||||
* @param Webkul\Product\Repositories\TaxCategoryRepository $taxCategory
|
||||
* @param Webkul\Product\Repositories\CustomerAddressRepository $customerAddress
|
||||
* @param Webkul\Product\Repositories\CustomerAddressRepository $customerAddress
|
||||
* @param Webkul\Discount\Repositories\CartRuleRepository $cartRule
|
||||
* @param Webkul\Helpers\Discount $discount
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(
|
||||
|
|
@ -110,6 +125,8 @@ class Cart {
|
|||
TaxCategoryRepository $taxCategory,
|
||||
WishlistRepository $wishlist,
|
||||
CustomerAddressRepository $customerAddress,
|
||||
CartRule $cartRule,
|
||||
Discount $discount,
|
||||
Price $price
|
||||
)
|
||||
{
|
||||
|
|
@ -129,12 +146,15 @@ class Cart {
|
|||
|
||||
$this->customerAddress = $customerAddress;
|
||||
|
||||
$this->cartRule = $cartRule;
|
||||
|
||||
$this->discount = $discount;
|
||||
|
||||
$this->price = $price;
|
||||
|
||||
$this->suppressFlash = false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return current logged in customer
|
||||
*
|
||||
|
|
@ -1072,6 +1092,59 @@ class Cart {
|
|||
return $finalData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Save discount data for cart
|
||||
*/
|
||||
public function saveDiscount()
|
||||
{
|
||||
$rule = $impact['rule'];
|
||||
|
||||
$cart = $this->getCart();
|
||||
|
||||
//update the cart items
|
||||
foreach($cart->items as $item) {
|
||||
if ($rule->use_coupon) {
|
||||
if ($rule->action_type != config('pricerules.cart.validation.0')) {
|
||||
$item->update([
|
||||
'coupon_code' => $rule->coupon->code,
|
||||
'discount_amount' => core()->convertPrice($impact['amount'], $cart->channel_currency_code),
|
||||
'base_discount_amount' => $impact['amount']
|
||||
]);
|
||||
} else {
|
||||
$item->update([
|
||||
'coupon_code' => $rule->coupon->code,
|
||||
'discount_percent' => $rule->disc_amount
|
||||
]);
|
||||
}
|
||||
} else {
|
||||
if ($rule->action_type != config('pricerules.cart.validation.0')) {
|
||||
$item->update([
|
||||
'discount_amount' => core()->convertPrice($impact['amount'], $cart->channel_currency_code),
|
||||
'base_discount_amount' => $impact['amount']
|
||||
]);
|
||||
} else {
|
||||
$item->update([
|
||||
'discount_percent' => $rule->disc_amount
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// update the cart
|
||||
if ($rule->use_coupon) {
|
||||
$cart->update([
|
||||
'coupon_code' => $rule->coupons->code,
|
||||
'discount_amount' => core()->convertPrice($impact['amount'], $cart->channel_currency_code),
|
||||
'base_discount_amount' => $impact['amount']
|
||||
]);
|
||||
} else {
|
||||
$cart->update([
|
||||
'discount_amount' => core()->convertPrice($impact['amount'], $cart->channel_currency_code),
|
||||
'base_discount_amount' => $impact['amount']
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares data for order item
|
||||
*
|
||||
|
|
@ -1212,4 +1285,67 @@ class Cart {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function applyCoupon($code)
|
||||
{
|
||||
$result = $this->discount->applyCouponAbleRule($code);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function applyNonCoupon()
|
||||
{
|
||||
$result = $this->discount->applyNonCouponAbleRule();
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function removeCoupon()
|
||||
{
|
||||
$result = $this->discount->removeCoupon();
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function leastWorthItem()
|
||||
{
|
||||
$cart = $this->getCart();
|
||||
$leastValue = 999999999999;
|
||||
$leastSubTotal = [];
|
||||
|
||||
foreach ($cart->items as $item) {
|
||||
if ($item->price < $leastValue) {
|
||||
$leastValue = $item->price;
|
||||
$leastSubTotal = [
|
||||
'id' => $item->id,
|
||||
'total' => $item->total,
|
||||
'base_total' => $leastValue,
|
||||
'quantity' => $item->quantity
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
return $leastSubTotal;
|
||||
}
|
||||
|
||||
public function maxWorthItem()
|
||||
{
|
||||
$cart = $this->getCart();
|
||||
$maxValue = 0;
|
||||
$maxSubTotal = [];
|
||||
|
||||
foreach ($cart->items as $item) {
|
||||
if ($item->base_total > $maxValue) {
|
||||
$maxValue = $item->total;
|
||||
$maxSubTotal = [
|
||||
'id' => $item->id,
|
||||
'total' => $item->total,
|
||||
'base_total' => $maxValue,
|
||||
'quantity' => $item->quantity
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
return $maxSubTotal;
|
||||
}
|
||||
}
|
||||
|
|
@ -17,6 +17,6 @@ return [
|
|||
\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\User\Providers\ModuleServiceProvider::class,\Webkul\Discount\Providers\ModuleServiceProvider::class,
|
||||
]
|
||||
];
|
||||
|
|
@ -19,6 +19,10 @@ class CustomerGroupTableSeeder extends Seeder
|
|||
'id' => 2,
|
||||
'name' => 'Wholesale',
|
||||
'is_user_defined' => 0,
|
||||
], [
|
||||
'id' => 3,
|
||||
'name' => 'Not Logged In',
|
||||
'is_user_defined' => 0,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
Discount Condition:
|
||||
Attribute Family is all the attributes
|
||||
Cart Attribute such as
|
||||
base_total,
|
||||
grand_total,
|
||||
shipping_free,
|
||||
shipping_not_free,
|
||||
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
{
|
||||
"name": "bagisto/laravel-discount",
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Prashant Singh",
|
||||
"email": "prashant.singh852@webkul.com"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"propaganistas/laravel-intl": "^2.0"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Webkul\\Discount\\": "src/"
|
||||
}
|
||||
},
|
||||
"extra": {
|
||||
"laravel": {
|
||||
"providers": [
|
||||
"Webkul\\Discount\\DiscountServiceProvider"
|
||||
],
|
||||
"aliases": {}
|
||||
}
|
||||
},
|
||||
"minimum-stability": "dev"
|
||||
}
|
||||
|
|
@ -0,0 +1,179 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
'conditions' => [
|
||||
'numeric' => [
|
||||
0 => 'Equals',
|
||||
1 => 'Equals or greater',
|
||||
2 => 'Equals or lesser',
|
||||
3 => 'Greater than',
|
||||
4 => 'Lesser than'
|
||||
],
|
||||
|
||||
'text' => [
|
||||
0 => 'is',
|
||||
1 => 'is not',
|
||||
2 => 'contains',
|
||||
3 => 'does not contains'
|
||||
],
|
||||
|
||||
'boolean' => [
|
||||
0 => 'True/Yes',
|
||||
1 => 'False/No',
|
||||
]
|
||||
],
|
||||
|
||||
'catalog' => [
|
||||
'actions' => [
|
||||
0 => 'admin::app.promotion.catalog.apply-percent',
|
||||
1 => 'admin::app.promotion.catalog.apply-fixed',
|
||||
2 => 'admin::app.promotion.catalog.adjust-to-percent',
|
||||
3 => 'admin::app.promotion.catalog.adjust-to-value'
|
||||
],
|
||||
|
||||
'attributes' => [
|
||||
0 => [
|
||||
'name' => 'Sub-total',
|
||||
'type' => 'numeric'
|
||||
],
|
||||
1 => [
|
||||
'name' => 'Total Items Quantity',
|
||||
'type' => 'numeric'
|
||||
],
|
||||
2 => [
|
||||
'name' => 'Total Weight',
|
||||
'type' => 'numeric'
|
||||
],
|
||||
3 => [
|
||||
'name' => 'Payment Method',
|
||||
'type' => 'string'
|
||||
],
|
||||
4 => [
|
||||
'name' => 'Shipping Postcode',
|
||||
'type' => 'string'
|
||||
],
|
||||
5 => [
|
||||
'name' => 'Shipping State',
|
||||
'type' => 'string'
|
||||
],
|
||||
6 => [
|
||||
'name' => 'Shipping Country',
|
||||
'type' => 'string'
|
||||
]
|
||||
]
|
||||
],
|
||||
|
||||
'cart' => [
|
||||
'actions' => [
|
||||
'percent_of_product' => 'Percentage of product',
|
||||
'fixed_amount' => 'Apply as fixed amount',
|
||||
'buy_a_get_b' => 'Get B amount back',
|
||||
// 'fixed_amount_cart' => 'Fixed amount for whole cart'
|
||||
],
|
||||
|
||||
'validation' => [
|
||||
0 => 'percent_of_product',
|
||||
1 => 'fixed_amount',
|
||||
2 => 'buy_a_get_b',
|
||||
3 => 'fixed_amount_cart'
|
||||
],
|
||||
|
||||
'conditions' => [
|
||||
'numeric' => [
|
||||
'=' => 'Equals',
|
||||
'>=' => 'Greater or equals',
|
||||
'<=' => 'Lesser or equals',
|
||||
'>' => 'Greater than',
|
||||
'<' => 'Lesser than',
|
||||
'{}' => 'Contains'
|
||||
// '!{}' => 'Does not contains',
|
||||
// '()' => 'Is one of',
|
||||
// '!()' => 'Not is one of'
|
||||
],
|
||||
|
||||
'text' => [
|
||||
'=' => 'Equals',
|
||||
'>=' => 'Greater or equals',
|
||||
'<=' => 'Lesser or equals',
|
||||
'>' => 'Greater than',
|
||||
'<' => 'Lesser than',
|
||||
'{}' => 'Contains',
|
||||
'!{}' => 'Does not contains'
|
||||
// '()' => 'Is one of',
|
||||
// '!()' => 'Not is one of'
|
||||
],
|
||||
|
||||
'string' => [
|
||||
'=' => 'Equals',
|
||||
'>=' => 'Greater or equals',
|
||||
'<=' => 'Lesser or equals',
|
||||
'>' => 'Greater than',
|
||||
'<' => 'Lesser than',
|
||||
'{}' => 'Contains',
|
||||
'!{}' => 'Does not contains'
|
||||
// '()' => 'Is one of',
|
||||
// '!()' => 'Not is one of'
|
||||
],
|
||||
|
||||
'boolean' => [
|
||||
0 => 'True/Yes',
|
||||
1 => 'False/No'
|
||||
]
|
||||
],
|
||||
|
||||
'attributes' => [
|
||||
0 => [
|
||||
'code' => 'sub_total',
|
||||
'name' => 'Sub Total',
|
||||
'type' => 'numeric'
|
||||
],
|
||||
1 => [
|
||||
'code' => 'total_items',
|
||||
'name' => 'Total Items',
|
||||
'type' => 'numeric'
|
||||
],
|
||||
2 => [
|
||||
'code' => 'total_weight',
|
||||
'name' => 'Total Weight',
|
||||
'type' => 'numeric'
|
||||
],
|
||||
3 => [
|
||||
'code' => 'shipping_method',
|
||||
'name' => 'Shipping Method',
|
||||
'type' => 'string'
|
||||
],
|
||||
4 => [
|
||||
'code' => 'payment_method',
|
||||
'name' => 'Payment Method',
|
||||
'type' => 'string'
|
||||
],
|
||||
5 => [
|
||||
'code' => 'shipping_postcode',
|
||||
'name' => 'Shipping Postcode',
|
||||
'type' => 'string'
|
||||
],
|
||||
6 => [
|
||||
'code' => 'shipping_state',
|
||||
'name' => 'Shipping State',
|
||||
'type' => 'string'
|
||||
],
|
||||
7 => [
|
||||
'code' => 'shipping_country',
|
||||
'name' => 'Shipping Country',
|
||||
'type' => 'string'
|
||||
],
|
||||
8 => [
|
||||
'code' => 'shipping_city',
|
||||
'name' => 'Shipping City',
|
||||
'type' => 'string'
|
||||
]
|
||||
]
|
||||
],
|
||||
|
||||
'test_mode' => [
|
||||
0 => 'all_are_true',
|
||||
1 => 'all_are_false',
|
||||
2 => 'any_of_true',
|
||||
3 => 'all_of_false'
|
||||
]
|
||||
];
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
<?php
|
||||
|
||||
namespace Webkul\Discount\Contracts;
|
||||
|
||||
interface CartRule
|
||||
{
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
<?php
|
||||
|
||||
namespace Webkul\Discount\Contracts;
|
||||
|
||||
interface CartRuleCart
|
||||
{
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
<?php
|
||||
|
||||
namespace Webkul\Discount\Contracts;
|
||||
|
||||
interface CartRuleChannels
|
||||
{ }
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
<?php
|
||||
|
||||
namespace Webkul\Discount\Contracts;
|
||||
|
||||
interface CartRuleCoupons
|
||||
{
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
<?php
|
||||
|
||||
namespace Webkul\Discount\Contracts;
|
||||
|
||||
interface CartRuleCouponsUsage
|
||||
{
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
<?php
|
||||
|
||||
namespace Webkul\Discount\Contracts;
|
||||
|
||||
interface CartRuleCustomerGroups
|
||||
{
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
<?php
|
||||
|
||||
namespace Webkul\Discount\Contracts;
|
||||
|
||||
interface CartRuleCustomers
|
||||
{
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
<?php
|
||||
|
||||
namespace Webkul\Discount\Contracts;
|
||||
|
||||
interface CartRuleLabels
|
||||
{
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
<?php
|
||||
|
||||
namespace Webkul\Discount\Contracts;
|
||||
|
||||
interface CatalogRule
|
||||
{
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
<?php
|
||||
|
||||
namespace Webkul\Discount\Contracts;
|
||||
|
||||
interface CatalogRuleChannels
|
||||
{
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
<?php
|
||||
|
||||
namespace Webkul\Discount\Contracts;
|
||||
|
||||
interface CatalogRuleCustomerGroups
|
||||
{
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
<?php
|
||||
|
||||
namespace Webkul\Discount\Contracts;
|
||||
|
||||
interface CatalogRuleProducts
|
||||
{
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
<?php
|
||||
|
||||
namespace Webkul\Discount\Contracts;
|
||||
|
||||
interface CatalogRuleProductsPrice
|
||||
{
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class CreateCartRuleTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::dropIfExists('discount_customer_group');
|
||||
Schema::dropIfExists('discount_channels');
|
||||
Schema::dropIfExists('discount_rules');
|
||||
Schema::dropIfExists('discounts');
|
||||
Schema::dropIfExists('products_grid');
|
||||
|
||||
Schema::create('cart_rules', function (Blueprint $table) {
|
||||
$table->increments('id');
|
||||
$table->string('name')->nullable();
|
||||
$table->string('description')->nullable();
|
||||
$table->datetime('starts_from')->nullable();
|
||||
$table->datetime('ends_till')->nullable();
|
||||
$table->boolean('status')->default(0);
|
||||
$table->integer('per_customer')->unsigned()->default(0);
|
||||
$table->boolean('is_guest')->default(0);
|
||||
$table->boolean('use_coupon')->default(0);
|
||||
$table->integer('usage_limit')->unsigned()->default(0);
|
||||
$table->json('conditions')->nullable();
|
||||
$table->json('actions')->nullable();
|
||||
$table->boolean('end_other_rules')->default(0);
|
||||
$table->integer('priority')->unsigned()->default(0);
|
||||
$table->boolean('uses_attribute_conditions')->default(0);
|
||||
$table->longtext('product_ids')->nullable();
|
||||
$table->integer('sort_order')->unsigned()->default(0);
|
||||
$table->string('action_type')->nullable();
|
||||
$table->decimal('disc_amount', 12, 4)->default(0);
|
||||
$table->decimal('disc_quantity', 12, 4)->default(0);
|
||||
$table->string('disc_threshold')->default(0);
|
||||
$table->integer('coupon_type')->default(1);
|
||||
$table->boolean('auto_generation')->default(0);
|
||||
$table->boolean('apply_to_shipping')->default(0);
|
||||
$table->boolean('free_shipping')->default(0);
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('cart_rule');
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class CreateCartRuleChannelsTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('cart_rule_channels', function (Blueprint $table) {
|
||||
$table->increments('id');
|
||||
$table->integer('cart_rule_id')->unsigned();
|
||||
$table->foreign('cart_rule_id')->references('id')->on('cart_rules')->onDelete('cascade');
|
||||
$table->integer('channel_id')->unsigned();
|
||||
$table->foreign('channel_id')->references('id')->on('channels')->onDelete('cascade');
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('cart_rule_channels');
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class CreateCartRuleCustomerGroupsTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('cart_rule_customer_groups', function (Blueprint $table) {
|
||||
$table->increments('id');
|
||||
$table->integer('cart_rule_id')->unsigned();
|
||||
$table->foreign('cart_rule_id')->references('id')->on('cart_rules')->onDelete('cascade');
|
||||
$table->integer('customer_group_id')->unsigned();
|
||||
$table->foreign('customer_group_id')->references('id')->on('customer_groups')->onDelete('cascade');
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('cart_rule_customer_groups');
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class CreateCartRuleLabelsTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('cart_rule_labels', function (Blueprint $table) {
|
||||
$table->increments('id');
|
||||
$table->integer('channel_id')->unsigned()->nullable();
|
||||
$table->foreign('channel_id')->references('id')->on('channels')->onDelete('cascade');
|
||||
$table->integer('locale_id')->unsigned()->nullable();
|
||||
$table->foreign('locale_id')->references('id')->on('locales')->onDelete('cascade');
|
||||
$table->integer('cart_rule_id')->unsigned()->nullable();
|
||||
$table->foreign('cart_rule_id')->references('id')->on('cart_rules')->onDelete('cascade');
|
||||
$table->text('label')->nullable();
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('cart_rule_labels');
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class CreateCartruleCustomersTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('cart_rule_customers', function (Blueprint $table) {
|
||||
$table->increments('id');
|
||||
$table->integer('cart_rule_id')->unsigned();
|
||||
$table->foreign('cart_rule_id')->references('id')->on('cart_rules')->onDelete('cascade');
|
||||
$table->integer('customer_id')->unsigned();
|
||||
$table->foreign('customer_id')->references('id')->on('customers')->onDelete('cascade');
|
||||
$table->bigInteger('usage_throttle')->unsigned()->default(0);
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('cartrule_customers');
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class CreateCartruleCouponsTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('cart_rule_coupons', function (Blueprint $table) {
|
||||
$table->increments('id');
|
||||
$table->integer('cart_rule_id')->unsigned();
|
||||
$table->foreign('cart_rule_id')->references('id')->on('cart_rules')->onDelete('cascade');
|
||||
$table->string('prefix')->nullable();
|
||||
$table->string('suffix')->nullable();
|
||||
$table->string('code')->nullable();
|
||||
$table->integer('usage_limit')->unsigned()->default(0);
|
||||
$table->integer('usage_per_customer')->unsigned()->default(0);
|
||||
$table->integer('usage_throttle')->unsigned()->default(0);
|
||||
$table->integer('type')->unsigned()->default(0);
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('cartrule_coupons');
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class CreateCartRuleCouponsUsageTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('cart_rule_coupons_usage', function (Blueprint $table) {
|
||||
$table->increments('id');
|
||||
$table->integer('coupon_id')->unsigned();
|
||||
$table->foreign('coupon_id')->references('id')->on('cart_rules')->onDelete('cascade');
|
||||
$table->integer('channel_id')->unsigned();
|
||||
$table->foreign('channel_id')->references('id')->on('channels')->onDelete('cascade');
|
||||
$table->integer('customer_id')->unsigned();
|
||||
$table->foreign('customer_id')->references('id')->on('customers')->onDelete('cascade');
|
||||
$table->bigInteger('usage')->unsigned()->default(0);
|
||||
$table->date('expired_on');
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('cart_rule_coupons_usage');
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class CreateCartRuleCartTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('cart_rule_cart', function (Blueprint $table) {
|
||||
$table->increments('id');
|
||||
$table->integer('cart_rule_id')->unsigned()->nullable();
|
||||
$table->foreign('cart_rule_id')->references('id')->on('cart_rules')->onDelete('cascade');
|
||||
$table->integer('cart_id')->unsigned()->nullable();
|
||||
$table->foreign('cart_id')->references('id')->on('cart')->onDelete('cascade');
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('cart_rule_order');
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,440 @@
|
|||
<?php
|
||||
|
||||
namespace Webkul\Discount\Helpers;
|
||||
|
||||
use Webkul\Discount\Repositories\CartRuleRepository as CartRule;
|
||||
use Webkul\Discount\Repositories\CartRuleCartRepository as CartRuleCart;
|
||||
use Carbon\Carbon;
|
||||
|
||||
|
||||
class Discount
|
||||
{
|
||||
/**
|
||||
* To hold the cart rule repository instance
|
||||
*/
|
||||
protected $cartRule;
|
||||
|
||||
/**
|
||||
* To hold the cart rule cart repository instance
|
||||
*/
|
||||
protected $cartRuleCart;
|
||||
|
||||
/**
|
||||
* To hold if end rules are present or not.
|
||||
*/
|
||||
protected $endRuleActive = false;
|
||||
|
||||
/**
|
||||
* disable coupon
|
||||
*/
|
||||
protected $disableCoupon = false;
|
||||
|
||||
public function __construct(CartRule $cartRule, CartRuleCart $cartRuleCart)
|
||||
{
|
||||
$this->cartRule = $cartRule;
|
||||
$this->endRuleActive = false;
|
||||
$this->cartRuleCart = $cartRuleCart;
|
||||
}
|
||||
|
||||
public function applyNonCouponAbleRule()
|
||||
{
|
||||
if (auth()->guard('customer')->check()) {
|
||||
$nonCouponAbleRules = $this->cartRule->findWhere([
|
||||
'use_coupon' => 0,
|
||||
'status' => 1
|
||||
]);
|
||||
} else {
|
||||
$nonCouponAbleRules = $this->cartRule->findWhere([
|
||||
'use_coupon' => 0,
|
||||
'is_guest' => 1,
|
||||
'status' => 1
|
||||
]);
|
||||
}
|
||||
|
||||
$canBeApplied = array();
|
||||
|
||||
// time based filter
|
||||
foreach($nonCouponAbleRules as $rule) {
|
||||
$report = $this->checkApplicability($rule);
|
||||
$report['rule'] = $rule;
|
||||
|
||||
$passed = 0;
|
||||
if ($rule->starts_from != null && $rule->ends_till == null) {
|
||||
if (Carbon::parse($rule->starts_from) < now()) {
|
||||
$passed = 1;
|
||||
}
|
||||
} else if ($rule->starts_from == null && $rule->ends_till != null) {
|
||||
if (Carbon::parse($rule->ends_till) > now()) {
|
||||
$passed = 1;
|
||||
}
|
||||
} else if ($rule->starts_from != null && $rule->ends_till != null) {
|
||||
if (Carbon::parse($rule->starts_from) < now() && now() < Carbon::parse($rule->ends_till)) {
|
||||
$passed = 1;
|
||||
}
|
||||
} else {
|
||||
$passed = 1;
|
||||
}
|
||||
|
||||
if ($passed) {
|
||||
$report['used_coupon'] = false;
|
||||
array_push($canBeApplied, $report);
|
||||
}
|
||||
}
|
||||
|
||||
//min priority
|
||||
$minPriority = collect($canBeApplied)->min('priority');
|
||||
|
||||
$canBeApplied = collect($canBeApplied)->where('priority', $minPriority);
|
||||
|
||||
if (count($canBeApplied) > 1) {
|
||||
$maxDiscount = collect($canBeApplied)->max('discount');
|
||||
|
||||
$canBeApplied = collect($canBeApplied)->where('discount', $maxDiscount);
|
||||
|
||||
$leastId = 999999999999;
|
||||
if (count($canBeApplied) > 1) {
|
||||
foreach($canBeApplied as $rule) {
|
||||
if ($rule['rule']->id < $leastId) {
|
||||
$leastId = $rule['rule']->id;
|
||||
}
|
||||
}
|
||||
|
||||
// fighting the edge case for non couponable discount rule
|
||||
foreach($canBeApplied as $rule) {
|
||||
if ($rule['rule']->id == $leastId) {
|
||||
$rule['used_coupon'] = false;
|
||||
|
||||
$this->save($rule['rule']);
|
||||
|
||||
return $rule;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->save($canBeApplied[0]['rule']);
|
||||
|
||||
return $canBeApplied[0];
|
||||
}
|
||||
|
||||
public function applyCouponAbleRule($code)
|
||||
{
|
||||
if (auth()->guard('customer')->check()) {
|
||||
$couponAbleRules = $this->cartRule->findWhere([
|
||||
'use_coupon' => 1,
|
||||
'status' => 1
|
||||
]);
|
||||
} else {
|
||||
$couponAbleRules = $this->cartRule->findWhere([
|
||||
'use_coupon' => 1,
|
||||
'is_guest' => 1,
|
||||
'status' => 1
|
||||
]);
|
||||
}
|
||||
|
||||
$rule;
|
||||
foreach ($couponAbleRules as $couponAbleRule) {
|
||||
if ($couponAbleRule->coupons->code == $code) {
|
||||
$rule = $couponAbleRule;
|
||||
}
|
||||
}
|
||||
|
||||
$useCouponable = false;
|
||||
if (isset($rule)) {
|
||||
$canBeApplied = array();
|
||||
|
||||
// time based filter
|
||||
$report = $this->checkApplicability($rule);
|
||||
$report['rule'] = $rule;
|
||||
|
||||
$passed = 0;
|
||||
if ($rule->starts_from != null && $rule->ends_till == null) {
|
||||
if (Carbon::parse($rule->starts_from) < now()) {
|
||||
$passed = 1;
|
||||
}
|
||||
} else if ($rule->starts_from == null && $rule->ends_till != null) {
|
||||
if (Carbon::parse($rule->ends_till) > now()) {
|
||||
$passed = 1;
|
||||
}
|
||||
} else if ($rule->starts_from != null && $rule->ends_till != null) {
|
||||
if (Carbon::parse($rule->starts_from) < now() && now() < Carbon::parse($rule->ends_till)) {
|
||||
$passed = 1;
|
||||
}
|
||||
} else {
|
||||
$passed = 1;
|
||||
}
|
||||
|
||||
if ($passed) {
|
||||
array_push($canBeApplied, $report);
|
||||
|
||||
$useCouponable = true;
|
||||
$alreadyAppliedRule = $this->cartRuleCart->findWhere([
|
||||
'cart_id' => \Cart::getCart()->id
|
||||
]);
|
||||
|
||||
if ($alreadyAppliedRule->count() && ! ($alreadyAppliedRule->first()->cart_rule->priority < $canBeApplied[0]['rule']->priority)) {
|
||||
unset($report);
|
||||
|
||||
$alreadyAppliedRule = $alreadyAppliedRule->first()->cart_rule;
|
||||
|
||||
// analyze impact
|
||||
$report = $this->checkApplicability($alreadyAppliedRule);
|
||||
$report['rule'] = $alreadyAppliedRule;
|
||||
|
||||
array_push($canBeApplied, $report);
|
||||
|
||||
//min priority
|
||||
$minPriority = collect($canBeApplied)->min('priority');
|
||||
//min priority rule
|
||||
$canBeApplied = collect($canBeApplied)->where('priority', $minPriority);
|
||||
|
||||
if (count($canBeApplied) > 1) {
|
||||
$maxDiscount = collect($canBeApplied)->max('discount');
|
||||
|
||||
$canBeApplied = collect($canBeApplied)->where('discount', $maxDiscount);
|
||||
|
||||
$leastId = 999999999999;
|
||||
if (count($canBeApplied) > 1) {
|
||||
foreach($canBeApplied as $rule) {
|
||||
if ($rule['rule']->id < $leastId) {
|
||||
$leastId = $rule['rule']->id;
|
||||
}
|
||||
}
|
||||
|
||||
// fighting the edge case for couponable discount rule
|
||||
foreach($canBeApplied as $rule) {
|
||||
if ($rule['rule']->id == $leastId) {
|
||||
if($rule['rule']->use_coupon) {
|
||||
$useCouponable = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ($canBeApplied[0]['rule']->use_coupon) {
|
||||
$useCouponable = true;
|
||||
}
|
||||
}
|
||||
} else if (count($canBeApplied)) {
|
||||
if ($canBeApplied[0]['rule']->use_coupon) {
|
||||
$useCouponable = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ($alreadyAppliedRule->end_other_rules) {
|
||||
$useCouponable = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$canBeApplied = array();
|
||||
if ($useCouponable) {
|
||||
$report = $this->checkApplicability($rule);
|
||||
$report['rule'] = $rule;
|
||||
$report['used_coupon'] = $useCouponable;
|
||||
|
||||
$this->save($rule);
|
||||
|
||||
return $report;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public function checkApplicability($rule = null)
|
||||
{
|
||||
$cart = \Cart::getCart();
|
||||
$report = array();
|
||||
$result = 0;
|
||||
|
||||
//check conditions
|
||||
if ($rule->conditions != null) {
|
||||
$conditions = json_decode(json_decode($rule->conditions));
|
||||
$test_mode = config('pricerules.test_mode.0');
|
||||
|
||||
if ($test_mode == config('pricerules.test_mode.0')) {
|
||||
$result = $this->testIfAllConditionAreTrue($conditions, $cart);
|
||||
} else if ($test_mode == config('pricerules.test_mode.1')) {
|
||||
$result = $this->testIfAllConditionAreFalse($conditions, $cart);
|
||||
} else if ($test_mode == config('pricerules.test_mode.2')) {
|
||||
$result = $this->testIfAnyConditionIsTrue($conditions, $cart);
|
||||
} else if ($test_mode == config('pricerules.test_mode.3')) {
|
||||
$result = $this->testIfAnyConditionIsFalse($conditions, $cart);
|
||||
}
|
||||
}
|
||||
|
||||
if ($result) {
|
||||
$report['conditions'] = true;
|
||||
} else {
|
||||
if ($rule->conditions == null)
|
||||
$report['conditions'] = true;
|
||||
else
|
||||
$report['conditions'] = false;
|
||||
}
|
||||
|
||||
//check endrule
|
||||
if ($rule->end_other_rules) {
|
||||
$report['end_other_rules'] = true;
|
||||
} else {
|
||||
$report['end_other_rules'] = false;
|
||||
}
|
||||
|
||||
//calculate discount amount
|
||||
$action_type = $rule->action_type; // action type used
|
||||
$disc_threshold = $rule->disc_threshold; // atleast quantity by default 1 --> may be omitted in near future
|
||||
$disc_amount = $rule->disc_amount; // value of discount
|
||||
$disc_quantity = $rule->disc_quantity; //max quantity allowed to be discounted
|
||||
|
||||
$amountDiscounted = 0;
|
||||
$leastWorthItem = \Cart::leastWorthItem();
|
||||
$realQty = $leastWorthItem['quantity'];
|
||||
|
||||
if ($cart->items_qty >= $disc_threshold && $realQty >= $disc_quantity) {
|
||||
if ($action_type == config('pricerules.cart.validation.0')) {
|
||||
$amountDiscounted = $leastWorthItem['total'] * ($disc_amount / 100);
|
||||
} else if ($action_type == config('pricerules.cart.validation.1')) {
|
||||
$amountDiscounted = $leastWorthItem['total'] - $disc_amount;
|
||||
|
||||
if ($amountDiscounted < 0) {
|
||||
$amountDiscounted = $leastWorthItem['total'];
|
||||
}
|
||||
} else if ($action_type == config('pricerules.cart.validation.2')) {
|
||||
$amountDiscounted = $disc_amount;
|
||||
}
|
||||
}
|
||||
|
||||
$report['discount'] = $amountDiscounted;
|
||||
$report['formatted_discount'] = core()->formatPrice($amountDiscounted, $cart->cart_currency_code);
|
||||
$report['new_grand_total'] = $cart->grand_total - $amountDiscounted;
|
||||
$report['formatted_new_grand_total'] = core()->formatPrice($cart->grand_total - $amountDiscounted, $cart->cart_currency_code);
|
||||
$report['priority'] = $rule->priority;
|
||||
|
||||
return $report;
|
||||
}
|
||||
|
||||
public function save($rule)
|
||||
{
|
||||
$cart = \Cart::getCart();
|
||||
|
||||
// create or update
|
||||
$existingRule = $this->cartRuleCart->findWhere([
|
||||
'cart_id' => $cart->id
|
||||
]);
|
||||
|
||||
if (count($existingRule)) {
|
||||
if ($existingRule->first()->cart_rule_id != $rule->id) {
|
||||
$existingRule->first()->update([
|
||||
'cart_rule_id' => $rule->id
|
||||
]);
|
||||
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
$this->cartRuleCart->create([
|
||||
'cart_id' => $cart->id,
|
||||
'cart_rule_id' => $rule->id
|
||||
]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function removeCoupon()
|
||||
{
|
||||
$cart = \Cart::getCart();
|
||||
|
||||
$existingRule = $this->cartRuleCart->findWhere([
|
||||
'cart_id' => $cart->id
|
||||
]);
|
||||
|
||||
if ($existingRule->count()) {
|
||||
if ($existingRule->first()->delete()) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
protected function testIfAllConditionAreTrue($conditions, $cart) {
|
||||
$shipping_address = $cart->getShippingAddressAttribute();
|
||||
|
||||
$shipping_method = $cart->shipping_method;
|
||||
$shipping_country = $shipping_address->country;
|
||||
$shipping_state = $shipping_address->state;
|
||||
$shipping_postcode = $shipping_address->postcode;
|
||||
$shipping_city = $shipping_address->city;
|
||||
|
||||
$payment_method = $cart->payment->method;
|
||||
$sub_total = $cart->base_sub_total;
|
||||
|
||||
$total_items = $cart->items_qty;
|
||||
$total_weight = 0;
|
||||
|
||||
foreach($cart->items as $item) {
|
||||
$total_weight = $total_weight + $item->base_total_weight;
|
||||
}
|
||||
|
||||
$test_mode = config('pricerules.test_mode.0');
|
||||
$test_conditions = config('pricerules.cart.conditions');
|
||||
|
||||
$result = 1;
|
||||
foreach ($conditions as $condition) {
|
||||
$actual_value = ${$condition->attribute};
|
||||
$test_value = $condition->value;
|
||||
$test_condition = $condition->condition;
|
||||
|
||||
if ($condition->type == 'numeric' || $condition->type == 'string' || $condition->type == 'text') {
|
||||
if ($test_condition == '=') {
|
||||
if ($actual_value != $test_value) {
|
||||
$result = 0;
|
||||
|
||||
break;
|
||||
}
|
||||
} else if ($test_condition == '>=') {
|
||||
if (! ($actual_value >= $test_value)) {
|
||||
$result = 0;
|
||||
|
||||
break;
|
||||
}
|
||||
} else if ($test_condition == '<=') {
|
||||
if (! ($actual_value <= $test_value)) {
|
||||
$result = 0;
|
||||
|
||||
break;
|
||||
}
|
||||
} else if ($test_condition == '>') {
|
||||
if (! ($actual_value > $test_value)) {
|
||||
$result = 0;
|
||||
|
||||
break;
|
||||
}
|
||||
} else if ($test_condition == '<') {
|
||||
if (! ($actual_value < $test_value)) {
|
||||
$result = 0;
|
||||
|
||||
break;
|
||||
}
|
||||
} else if ($test_condition == '{}') {
|
||||
if (! str_contains($actual_value, $test_value)) {
|
||||
$result = 0;
|
||||
|
||||
break;
|
||||
}
|
||||
} else if ($test_condition == '!{}') {
|
||||
if (str_contains($actual_value, $test_value)) {
|
||||
$result = 0;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
<?php
|
||||
|
||||
namespace Webkul\Discount\Helpers;
|
||||
|
||||
use Webkul\Product\Repositories\ProductRepository as Product;
|
||||
use Webkul\Product\Repositories\ProductFlatRepository as ProductFlat;
|
||||
use Webkul\Attribute\Repositories\AttributeRepository as Attribute;
|
||||
use Webkul\Core\Repositories\LocaleRepository as Locale;
|
||||
|
||||
class FindProducts
|
||||
{
|
||||
/**
|
||||
* To hold the product repository instance
|
||||
*/
|
||||
protected $product;
|
||||
|
||||
/**
|
||||
* To hold the attribute repository instance
|
||||
*/
|
||||
protected $attribute;
|
||||
|
||||
public function __construct(Product $product, Attribute $attribute, ProductFlat $productFlat, Locale $locale)
|
||||
{
|
||||
$this->product = $product;
|
||||
|
||||
$this->attribute = $attribute;
|
||||
|
||||
$this->productFlat = $productFlat;
|
||||
|
||||
$this->locale = $locale;
|
||||
}
|
||||
|
||||
public function findByConditions($conditions)
|
||||
{
|
||||
dd($conditions);
|
||||
/**
|
||||
* Empty collection instance to hold all the products that satisfy the conditions
|
||||
*/
|
||||
$products = array();
|
||||
|
||||
foreach ($conditions as $condition) {
|
||||
$attribute = $this->attribute->findOneByField('code', $condition->attribute);
|
||||
dump($attribute->type);
|
||||
if ($condition->type == 'select' || $condition->type == 'multiselect') {
|
||||
$values = $condition->value;
|
||||
$attributeValues = array();
|
||||
|
||||
foreach ($condition->options as $option) {
|
||||
foreach ($values as $value) {
|
||||
if ($value == $option->id) {
|
||||
array_push($attributeValues, $option);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$defaultChannelCode = core()->getDefaultChannel()->code;
|
||||
$defaultLocaleCode = $this->locale->find(core()->getDefaultChannel()->default_locale_id)->code;
|
||||
|
||||
foreach ($attributeValues as $attributeValue) {
|
||||
$productFound = $this->productFlat->findByField([$attribute->code => $attributeValue->id, 'locale' => $defaultLocaleCode, 'channel' => $defaultChannelCode]);
|
||||
|
||||
if ($productFound->count()) {
|
||||
array_push($products, $productFound->toArray());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
}
|
||||
}
|
||||
|
||||
dd(array_flatten($products, 1));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,426 @@
|
|||
<?php
|
||||
|
||||
namespace Webkul\Discount\Http\Controllers;
|
||||
|
||||
use Webkul\Attribute\Repositories\AttributeRepository as Attribute;
|
||||
use Webkul\Attribute\Repositories\AttributeFamilyRepository as AttributeFamily;
|
||||
use Webkul\Category\Repositories\CategoryRepository as Category;
|
||||
use Webkul\Product\Repositories\ProductFlatRepository as Product;
|
||||
use Webkul\Discount\Repositories\CatalogRuleRepository as CatalogRule;
|
||||
use Webkul\Discount\Repositories\CartRuleRepository as CartRule;
|
||||
use Webkul\Checkout\Repositories\CartRepository as Cart;
|
||||
use Webkul\Discount\Repositories\CartRuleLabelsRepository as CartRuleLabels;
|
||||
use Webkul\Discount\Repositories\CartRuleCouponsRepository as CartRuleCoupons;
|
||||
use Validator;
|
||||
|
||||
/**
|
||||
* Cart Rule controller
|
||||
*
|
||||
* @author Prashant Singh <prashant.singh852@webkul.com> @prashant-webkul
|
||||
* @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com)
|
||||
*/
|
||||
class CartRuleController extends Controller
|
||||
{
|
||||
/**
|
||||
* Initialize _config, a default request parameter with route
|
||||
*/
|
||||
protected $_config;
|
||||
|
||||
/**
|
||||
* Attribute $attribute
|
||||
*/
|
||||
protected $attribute;
|
||||
|
||||
/**
|
||||
* AttributeFamily $attributeFamily
|
||||
*/
|
||||
protected $attributeFamily;
|
||||
|
||||
/**
|
||||
* Category $category
|
||||
*/
|
||||
protected $category;
|
||||
|
||||
/**
|
||||
* Product $product
|
||||
*/
|
||||
protected $product;
|
||||
|
||||
/**
|
||||
* Property for Cart rule application
|
||||
*/
|
||||
protected $appliedConfig;
|
||||
|
||||
/**
|
||||
* To hold Cart repository instance
|
||||
*/
|
||||
protected $cartRule;
|
||||
|
||||
/**
|
||||
* To hold Rule Label repository instance
|
||||
*/
|
||||
protected $cartRuleLabel;
|
||||
|
||||
/**
|
||||
* To hold Coupons Repository instance
|
||||
*/
|
||||
protected $cartRuleCoupon;
|
||||
|
||||
/**
|
||||
* To hold the cart repository instance
|
||||
*/
|
||||
protected $cart;
|
||||
|
||||
public function __construct(Attribute $attribute, AttributeFamily $attributeFamily, Category $category, Product $product, CatalogRule $catalogRule, CartRule $cartRule, CartRuleCoupons $cartRuleCoupon, CartRuleLabels $cartRuleLabel)
|
||||
{
|
||||
$this->_config = request('_config');
|
||||
$this->attribute = $attribute;
|
||||
$this->attributeFamily = $attributeFamily;
|
||||
$this->category = $category;
|
||||
$this->product = $product;
|
||||
$this->cartRule = $cartRule;
|
||||
$this->cartRuleCoupon = $cartRuleCoupon;
|
||||
$this->cartRuleLabel = $cartRuleLabel;
|
||||
$this->appliedConfig = config('pricerules.cart');
|
||||
}
|
||||
|
||||
public function index()
|
||||
{
|
||||
return view($this->_config['view']);
|
||||
}
|
||||
|
||||
public function create()
|
||||
{
|
||||
return view($this->_config['view'])->with('cart_rule', [$this->appliedConfig, $this->fetchOptionableAttributes(), $this->getStatesAndCountries()]);
|
||||
}
|
||||
|
||||
public function store()
|
||||
{
|
||||
$data = request()->all();
|
||||
|
||||
$validated = Validator::make($data, [
|
||||
'name' => 'required|string',
|
||||
'description' => 'string',
|
||||
// 'customer_groups' => 'required|array',
|
||||
'channels' => 'required|array',
|
||||
'status' => 'required|boolean',
|
||||
'use_coupon' => 'boolean|required',
|
||||
// 'usage_limit' => 'numeric|min:0',
|
||||
// 'per_customer' => 'numeric|min:0',
|
||||
'action_type' => 'required|string',
|
||||
'disc_amount' => 'required|numeric',
|
||||
'disc_quantity' => 'numeric',
|
||||
'disc_threshold' => 'numeric',
|
||||
'free_shipping' => 'required|boolean',
|
||||
'apply_to_shipping' => 'required|boolean',
|
||||
'code' => 'string|required_if:auto_generation,0',
|
||||
'all_conditions' => 'sometimes|nullable',
|
||||
'label' => 'array|nullable'
|
||||
]);
|
||||
|
||||
$data['usage_limit'] = 0;
|
||||
$data['per_customer'] = 0;
|
||||
|
||||
if ($validated->fails()) {
|
||||
session()->flash('error', 'Validation failed');
|
||||
return redirect()->route('admin.cart-rule.create')
|
||||
->withErrors($validated)
|
||||
->withInput();
|
||||
}
|
||||
|
||||
if ($data['starts_from'] == "" || $data['ends_till'] == "") {
|
||||
$data['starts_from'] = null;
|
||||
$data['ends_till'] = null;
|
||||
}
|
||||
|
||||
unset($data['_token']);
|
||||
|
||||
$channels = $data['channels'];
|
||||
unset($data['channels']);
|
||||
|
||||
$customer_groups = $data['customer_groups'];
|
||||
unset($data['customer_groups']);
|
||||
unset($data['criteria']);
|
||||
|
||||
$labels = $data['label'];
|
||||
unset($data['label']);
|
||||
unset($data['cart_attributes']);
|
||||
unset($data['attributes']);
|
||||
|
||||
if (isset($data['disc_amount']) && $data['action_type'] == config('pricerules.cart.validations.2')) {
|
||||
$data['actions'] = [
|
||||
'action_type' => $data['action_type'],
|
||||
'disc_amount' => $data['disc_amount'],
|
||||
'disc_threshold' => $data['disc_threshold']
|
||||
];
|
||||
|
||||
$data['disc_quantity'] = $data['disc_amount'];
|
||||
} else {
|
||||
$data['actions'] = [
|
||||
'action_type' => $data['action_type'],
|
||||
'disc_amount' => $data['disc_amount'],
|
||||
'disc_quantity' => $data['disc_quantity']
|
||||
];
|
||||
}
|
||||
|
||||
$data['actions'] = json_encode($data['actions']);
|
||||
|
||||
if (! isset($data['all_conditions']) || $data['all_conditions'] == "[]") {
|
||||
$data['conditions'] = null;
|
||||
} else {
|
||||
$data['conditions'] = json_encode($data['all_conditions']);
|
||||
}
|
||||
unset($data['all_conditions']);
|
||||
|
||||
if ($data['use_coupon']) {
|
||||
// if (isset($data['auto_generation']) && $data['auto_generation']) {
|
||||
$data['auto_generation'] = 0;
|
||||
|
||||
$coupons['code'] = $data['code'];
|
||||
unset($data['code']);
|
||||
// } else {
|
||||
// $data['auto_generation'] = 1;
|
||||
// }
|
||||
|
||||
// if (isset($data['prefix'])) {
|
||||
// $coupons['prefix'] = $data['prefix'];
|
||||
// unset($data['prefix']);
|
||||
// }
|
||||
|
||||
// if (isset($data['suffix'])) {
|
||||
// $coupons['suffix'] = $data['suffix'];
|
||||
// unset($data['suffix']);
|
||||
// }
|
||||
}
|
||||
|
||||
if(isset($data['usage_limit'])) {
|
||||
$coupons['usage_limit'] = $data['usage_limit'];
|
||||
}
|
||||
|
||||
$ruleCreated = $this->cartRule->create($data);
|
||||
|
||||
$ruleGroupCreated = $this->cartRule->CustomerGroupSync($customer_groups, $ruleCreated);
|
||||
$ruleChannelCreated = $this->cartRule->ChannelSync($channels, $ruleCreated);
|
||||
|
||||
if (isset($labels['global'])) {
|
||||
foreach (core()->getAllChannels() as $channel) {
|
||||
$label1['channel_id'] = $channel->id;
|
||||
foreach($channel->locales as $locale) {
|
||||
$label1['locale_id'] = $locale->id;
|
||||
$label1['label'] = $labels['global'];
|
||||
$label1['cart_rule_id'] = $ruleCreated->id;
|
||||
|
||||
$ruleLabelCreated = $this->cartRuleLabel->create($label1);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$label2['label'] = $labels['global'];
|
||||
$label2['cart_rule_id'] = $ruleCreated->id;
|
||||
$ruleLabelCreated = $this->cartRuleLabel->create($label2);
|
||||
}
|
||||
|
||||
if(isset($coupons)) {
|
||||
$coupons['cart_rule_id'] = $ruleCreated->id;
|
||||
$coupons['usage_per_customer'] = $data['per_customer']; //0 is for unlimited usage
|
||||
|
||||
$couponCreated = $this->cartRuleCoupon->create($coupons);
|
||||
}
|
||||
|
||||
if ($ruleCreated && $ruleGroupCreated && $ruleChannelCreated) {
|
||||
if (isset($couponCreated) && $couponCreated) {
|
||||
session()->flash('success', trans('admin::app.promotion.status.success-coupon'));
|
||||
}
|
||||
|
||||
session()->flash('success', trans('admin::app.promotion.status.success'));
|
||||
} else {
|
||||
session()->flash('success', trans('admin::app.promotion.status.success'));
|
||||
|
||||
return redirect()->back();
|
||||
}
|
||||
|
||||
return redirect()->route($this->_config['redirect']);
|
||||
}
|
||||
|
||||
public function edit($id)
|
||||
{
|
||||
$cart_rule = $this->cartRule->find($id);
|
||||
|
||||
return view($this->_config['view'])->with('cart_rule', [$this->appliedConfig, $this->fetchOptionableAttributes(), $this->getStatesAndCountries(), $cart_rule]);
|
||||
}
|
||||
|
||||
public function update($id)
|
||||
{
|
||||
$types = config('price_rules.cart.validations');
|
||||
|
||||
$validated = Validator::make(request()->all(), [
|
||||
'name' => 'required|string',
|
||||
'description' => 'string',
|
||||
// 'customer_groups' => 'required|array',
|
||||
'channels' => 'required|array',
|
||||
'status' => 'required|boolean',
|
||||
'use_coupon' => 'boolean|required',
|
||||
// 'usage_limit' => 'numeric|min:0',
|
||||
// 'per_customer' => 'numeric|min:0',
|
||||
'action_type' => 'required|string',
|
||||
'disc_amount' => 'required|numeric',
|
||||
'disc_quantity' => 'required|numeric',
|
||||
'disc_threshold' => 'required|numeric',
|
||||
'free_shipping' => 'required|boolean',
|
||||
'apply_to_shipping' => 'required|boolean',
|
||||
'code' => 'string|required_if:user_coupon,1',
|
||||
'all_conditions' => 'present',
|
||||
'label' => 'array|nullable'
|
||||
]);
|
||||
|
||||
$data['usage_limit'] = 0;
|
||||
$data['per_customer'] = 0;
|
||||
|
||||
if ($validated->fails()) {
|
||||
session()->flash('error', 'Validation failed');
|
||||
return redirect()->route('admin.cart-rule.create')
|
||||
->withErrors($validated)
|
||||
->withInput();
|
||||
}
|
||||
|
||||
$data = request()->all();
|
||||
|
||||
if ($data['starts_from'] == "" || $data['ends_till'] == "") {
|
||||
$data['starts_from'] = null;
|
||||
$data['ends_till'] = null;
|
||||
}
|
||||
|
||||
unset($data['_token']);
|
||||
|
||||
$channels = $data['channels'];
|
||||
unset($data['channels']);
|
||||
|
||||
// $customer_groups = $data['customer_groups'];
|
||||
// unset($data['customer_groups']);
|
||||
// unset($data['criteria']);
|
||||
|
||||
if (isset($data['label'])) {
|
||||
$labels = $data['label'];
|
||||
unset($data['label']);
|
||||
}
|
||||
|
||||
unset($data['cart_attributes']);
|
||||
unset($data['attributes']);
|
||||
|
||||
if (isset($data['disc_amount']) && $data['action_type'] == config('pricerules.cart.validations.2')) {
|
||||
$data['actions'] = [
|
||||
'action_type' => $data['action_type'],
|
||||
'disc_amount' => $data['disc_amount'],
|
||||
'disc_threshold' => $data['disc_threshold']
|
||||
];
|
||||
|
||||
$data['disc_quantity'] = $data['disc_amount'];
|
||||
} else {
|
||||
$data['actions'] = [
|
||||
'action_type' => $data['action_type'],
|
||||
'disc_amount' => $data['disc_amount'],
|
||||
'disc_quantity' => $data['disc_quantity']
|
||||
];
|
||||
}
|
||||
|
||||
$data['actions'] = json_encode($data['actions']);
|
||||
if (! isset($data['all_conditions']) || $data['all_conditions'] == "[]") {
|
||||
$data['conditions'] = null;
|
||||
} else {
|
||||
$data['conditions'] = json_encode($data['all_conditions']);
|
||||
}
|
||||
|
||||
unset($data['all_conditions']);
|
||||
|
||||
if ($data['use_coupon']) {
|
||||
// if (isset($data['auto_generation']) && $data['auto_generation']) {
|
||||
$data['auto_generation'] = 0;
|
||||
|
||||
$coupons['code'] = $data['code'];
|
||||
unset($data['code']);
|
||||
// } else {
|
||||
// $data['auto_generation'] = 1;
|
||||
// }
|
||||
|
||||
// if (isset($data['prefix'])) {
|
||||
// $coupons['prefix'] = $data['prefix'];
|
||||
// unset($data['prefix']);
|
||||
// }
|
||||
|
||||
// if (isset($data['suffix'])) {
|
||||
// $coupons['suffix'] = $data['suffix'];
|
||||
// unset($data['suffix']);
|
||||
// }
|
||||
}
|
||||
|
||||
if (isset($data['usage_limit'])) {
|
||||
$coupons['usage_limit'] = $data['usage_limit'];
|
||||
}
|
||||
|
||||
$ruleUpdated = $this->cartRule->update($data, $id);
|
||||
|
||||
// $ruleGroupUpdated = $this->cartRule->CustomerGroupSync($customer_groups, $ruleUpdated);
|
||||
$ruleChannelUpdated = $this->cartRule->ChannelSync($channels, $ruleUpdated);
|
||||
|
||||
$labelsUpdated = $this->cartRule->LabelSync($labels, $ruleUpdated);
|
||||
|
||||
if (isset($coupons)) {
|
||||
$coupons['cart_rule_id'] = $ruleUpdated->id;
|
||||
$coupons['usage_per_customer'] = $data['per_customer']; //0 is for unlimited usage
|
||||
|
||||
$couponUpdated = $ruleUpdated->coupons->update($coupons);
|
||||
}
|
||||
|
||||
if ($ruleUpdated && $ruleChannelUpdated) {
|
||||
if (isset($couponUpdated) && $couponUpdated) {
|
||||
session()->flash('info', trans('admin::app.promotion.status.success-coupon'));
|
||||
}
|
||||
|
||||
session()->flash('info', trans('admin::app.promotion.status.update-success'));
|
||||
} else {
|
||||
session()->flash('info', trans('admin::app.promotion.status.update-success'));
|
||||
|
||||
return redirect()->back();
|
||||
}
|
||||
|
||||
return redirect()->route($this->_config['redirect']);
|
||||
}
|
||||
|
||||
public function destroy($id)
|
||||
{
|
||||
$cartRule = $this->cartRule->findOrFail($id);
|
||||
|
||||
if ($cartRule->delete()) {
|
||||
session()->flash('success', trans('admin::app.promotion.status.delete-success'));
|
||||
|
||||
return response()->json(['message' => true], 200);
|
||||
} else {
|
||||
session()->flash('success', trans('admin::app.promotion.status.delete-failed'));
|
||||
|
||||
return response()->json(['message' => false], 400);
|
||||
}
|
||||
}
|
||||
|
||||
public function getStatesAndCountries()
|
||||
{
|
||||
$countries = core()->countries()->toArray();
|
||||
$states = core()->groupedStatesByCountries();
|
||||
|
||||
return [
|
||||
'countries' => $countries,
|
||||
'states' => $states
|
||||
];
|
||||
}
|
||||
|
||||
public function fetchOptionableAttributes()
|
||||
{
|
||||
$attributesWithOptions = array();
|
||||
|
||||
foreach($this->attribute->all() as $attribute) {
|
||||
if (($attribute->type == 'select' || $attribute->type == 'multiselect') && $attribute->code != 'tax_category_id') {
|
||||
$attributesWithOptions[$attribute->admin_name] = $attribute->options->toArray();
|
||||
}
|
||||
}
|
||||
|
||||
return $attributesWithOptions;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,307 @@
|
|||
<?php
|
||||
|
||||
namespace Webkul\Discount\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Response;
|
||||
|
||||
use Webkul\Attribute\Repositories\AttributeRepository as Attribute;
|
||||
use Webkul\Attribute\Repositories\AttributeFamilyRepository as AttributeFamily;
|
||||
use Webkul\Category\Repositories\CategoryRepository as Category;
|
||||
use Webkul\Product\Repositories\ProductFlatRepository as Product;
|
||||
use Webkul\Discount\Repositories\CatalogRuleRepository as CatalogRule;
|
||||
use Webkul\Discount\Repositories\CatalogRuleChannelsRepository as CatalogRuleChannels;
|
||||
use Webkul\Discount\Repositories\CatalogRuleCustomerGroupsRepository as CatalogRuleCustomerGroups;
|
||||
use Webkul\Discount\Helpers\FindProducts;
|
||||
|
||||
/**
|
||||
* Catalog Rule controller
|
||||
*
|
||||
* @author Prashant Singh <prashant.singh852@webkul.com> @prashant-webkul
|
||||
* @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com)
|
||||
*/
|
||||
class CatalogRuleController extends Controller
|
||||
{
|
||||
/**
|
||||
* Initialize _config, a default request parameter with route
|
||||
*/
|
||||
protected $_config;
|
||||
|
||||
/**
|
||||
* Attribute $attribute
|
||||
*/
|
||||
protected $attribute;
|
||||
|
||||
/**
|
||||
* AttributeFamily $attributeFamily
|
||||
*/
|
||||
protected $attributeFamily;
|
||||
|
||||
/**
|
||||
* Category $category
|
||||
*/
|
||||
protected $category;
|
||||
|
||||
/**
|
||||
* Product $product
|
||||
*/
|
||||
protected $product;
|
||||
|
||||
/**
|
||||
* Property for catalog rule application
|
||||
*/
|
||||
protected $appliedConfig;
|
||||
|
||||
/**
|
||||
* Property for catalog rule application
|
||||
*/
|
||||
protected $appliedConditions;
|
||||
|
||||
/**
|
||||
* Property to hold Catalog Rule Channels Repository
|
||||
*/
|
||||
protected $catalogRuleChannels;
|
||||
|
||||
/**
|
||||
* Property to hold Catalog Rule Customer Groups Repository
|
||||
*/
|
||||
protected $catalogRuleCustomerGroups;
|
||||
|
||||
/**
|
||||
* To hold the catalog repository instance
|
||||
*/
|
||||
protected $catalogRule;
|
||||
|
||||
/**
|
||||
* Find products using conditions helper instance
|
||||
*/
|
||||
protected $findProducts;
|
||||
|
||||
public function __construct(Attribute $attribute, AttributeFamily $attributeFamily, Category $category, Product $product, CatalogRule $catalogRule, CatalogRuleChannels $catalogRuleChannels, CatalogRuleCustomerGroups $catalogRuleCustomerGroups, FindProducts $findProducts)
|
||||
{
|
||||
$this->_config = request('_config');
|
||||
$this->attribute = $attribute;
|
||||
$this->attributeFamily = $attributeFamily;
|
||||
$this->category = $category;
|
||||
$this->product = $product;
|
||||
$this->catalogRule = $catalogRule;
|
||||
$this->catalogRuleChannels = $catalogRuleChannels;
|
||||
$this->catalogRuleCustomerGroups = $catalogRuleCustomerGroups;
|
||||
$this->appliedConfig = config('pricerules.catalog');
|
||||
$this->appliedConditions = config('pricerules.conditions');
|
||||
$this->findProducts = $findProducts;
|
||||
}
|
||||
|
||||
public function index()
|
||||
{
|
||||
return view($this->_config['view']);
|
||||
}
|
||||
|
||||
public function create()
|
||||
{
|
||||
return view($this->_config['view'])->with('catalog_rule', [$this->attribute->getPartial(), $this->category->getPartial(), $this->fetchOptionableAttributes(), $this->appliedConfig, $this->appliedConditions, $this->attributeFamily->getPartial()]);
|
||||
}
|
||||
|
||||
public function store()
|
||||
{
|
||||
$this->validate(request(), [
|
||||
'name' => 'required|string',
|
||||
'description' => 'string',
|
||||
'customer_groups' => 'required',
|
||||
'channels' => 'required',
|
||||
'starts_from' => 'required|date',
|
||||
'ends_till' => 'required|date',
|
||||
'status' => 'required|boolean',
|
||||
'end_other_rules' => 'required|boolean',
|
||||
'priority' => 'required|numeric',
|
||||
'criteria' => 'required',
|
||||
'all_conditions' => 'required|array',
|
||||
'apply' => 'required|numeric|min:0|max:3',
|
||||
'disc_amount' => 'sometimes',
|
||||
'disc_percent' => 'sometimes',
|
||||
]);
|
||||
|
||||
$catalog_rule = request()->all();
|
||||
|
||||
$catalog_rule_channels = array();
|
||||
$catalog_rule_customer_groups = array();
|
||||
|
||||
$catalog_rule_channels = $catalog_rule['channels'];
|
||||
$catalog_rule_customer_groups = $catalog_rule['customer_groups'];
|
||||
unset($catalog_rule['channels']); unset($catalog_rule['customer_groups']);
|
||||
|
||||
unset($catalog_rule['criteria']);
|
||||
|
||||
$catalog_rule['conditions'] = $catalog_rule['all_conditions'];
|
||||
unset($catalog_rule['all_conditions']);
|
||||
|
||||
if (isset($catalog_rule['disc_amount'])) {
|
||||
$catalog_rule['action_type'] = $catalog_rule['apply'];
|
||||
$catalog_rule['actions'] = [
|
||||
'action_type' => $catalog_rule['apply'],
|
||||
'disc_amount' => $catalog_rule['disc_amount']
|
||||
];
|
||||
} else if (isset($catalog_rule['disc_percent'])) {
|
||||
$catalog_rule['action_type'] = $catalog_rule['apply'];
|
||||
$catalog_rule['actions'] = [
|
||||
'action_type' => $catalog_rule['apply'],
|
||||
'disc_percent' => $catalog_rule['disc_percent'],
|
||||
];
|
||||
}
|
||||
|
||||
unset($catalog_rule['apply']);
|
||||
unset($catalog_rule['attributes']);
|
||||
unset($catalog_rule['_token']);
|
||||
unset($catalog_rule['all_actions']);
|
||||
|
||||
$catalog_rule['actions'] = json_encode($catalog_rule['actions']);
|
||||
$catalog_rule['conditions'] = json_encode($catalog_rule['conditions']);
|
||||
|
||||
$catalogRule = $this->catalogRule->create($catalog_rule);
|
||||
|
||||
foreach($catalog_rule_channels as $catalog_rule_channel) {
|
||||
$data['catalog_rule_id'] = $catalogRule->id;
|
||||
$data['channel_id'] = $catalog_rule_channel;
|
||||
|
||||
$catalogRuleChannels = $this->catalogRuleChannels->create($data);
|
||||
}
|
||||
|
||||
unset($data);
|
||||
foreach ($catalog_rule_customer_groups as $catalog_rule_customer_group) {
|
||||
$data['catalog_rule_id'] = $catalogRule->id;
|
||||
$data['customer_group_id'] = $catalog_rule_customer_group;
|
||||
|
||||
$catalogRuleCustomerGroups = $this->catalogRuleCustomerGroups->create($data);
|
||||
}
|
||||
|
||||
if($catalogRule && $catalogRuleChannels && $catalogRuleCustomerGroups) {
|
||||
session()->flash('success', trans('admin::app.promotion.status.success'));
|
||||
|
||||
return redirect()->route('admin.catalog-rule.index');
|
||||
} else {
|
||||
session()->flash('error', trans('admin::app.promotion.status.failed'));
|
||||
|
||||
return redirect()->back();
|
||||
}
|
||||
}
|
||||
|
||||
public function edit($id)
|
||||
{
|
||||
$catalog_rule = $this->catalogRule->find($id);
|
||||
$catalog_rule_channels = $this->catalogRuleChannels->findByField('catalog_rule_id', $id);
|
||||
$catalog_rule_customer_groups = $this->catalogRuleCustomerGroups->findByField('catalog_rule_id', $id);
|
||||
|
||||
return view($this->_config['view'])->with('catalog_rule', [$this->attribute->getPartial(), $this->category->getPartial(), $this->fetchOptionableAttributes(), $this->appliedConfig, $this->appliedConditions, $catalog_rule, $catalog_rule_channels, $catalog_rule_customer_groups, $this->attributeFamily->getPartial()]);
|
||||
}
|
||||
|
||||
public function update($id)
|
||||
{
|
||||
$this->validate(request(), [
|
||||
'name' => 'required|string',
|
||||
'description' => 'string',
|
||||
'customer_groups' => 'required',
|
||||
'channels' => 'required',
|
||||
'starts_from' => 'required|date',
|
||||
'ends_till' => 'required|date',
|
||||
'status' => 'required|boolean',
|
||||
'end_other_rules' => 'required|boolean',
|
||||
'priority' => 'required|numeric',
|
||||
'criteria' => 'required',
|
||||
'all_conditions' => 'required|array',
|
||||
'apply' => 'required|numeric|min:0|max:3',
|
||||
'disc_amount' => 'sometimes',
|
||||
'disc_percent' => 'sometimes',
|
||||
]);
|
||||
|
||||
$catalog_rule = request()->all();
|
||||
|
||||
$catalog_rule_channels = array();
|
||||
$catalog_rule_customer_groups = array();
|
||||
|
||||
$catalog_rule_channels = $catalog_rule['channels'];
|
||||
$catalog_rule_customer_groups = $catalog_rule['customer_groups'];
|
||||
unset($catalog_rule['channels']); unset($catalog_rule['customer_groups']);
|
||||
|
||||
unset($catalog_rule['criteria']);
|
||||
|
||||
$catalog_rule['conditions'] = $catalog_rule['all_conditions'];
|
||||
unset($catalog_rule['all_conditions']);
|
||||
|
||||
if (isset($catalog_rule['disc_amount'])) {
|
||||
$catalog_rule['action_type'] = $catalog_rule['apply'];
|
||||
$catalog_rule['actions'] = [
|
||||
'action_type' => $catalog_rule['apply'],
|
||||
'disc_amount' => $catalog_rule['disc_amount']
|
||||
];
|
||||
} else if (isset($catalog_rule['disc_percent'])) {
|
||||
$catalog_rule['action_type'] = $catalog_rule['apply'];
|
||||
$catalog_rule['actions'] = [
|
||||
'action_type' => $catalog_rule['apply'],
|
||||
'disc_percent' => $catalog_rule['disc_percent'],
|
||||
];
|
||||
}
|
||||
|
||||
unset($catalog_rule['apply']);
|
||||
unset($catalog_rule['attributes']);
|
||||
unset($catalog_rule['_token']);
|
||||
unset($catalog_rule['all_actions']);
|
||||
|
||||
$catalog_rule['actions'] = json_encode($catalog_rule['actions']);
|
||||
$catalog_rule['conditions'] = json_encode($catalog_rule['conditions']);
|
||||
|
||||
$catalogRule = $this->catalogRule->update($catalog_rule, $id);
|
||||
|
||||
$catalogRuleChannels = $this->catalogRule->ChannelSync($catalog_rule_channels, $catalogRule);
|
||||
$catalogRuleCustomerGroups = $this->catalogRule->CustomerGroupSync($catalog_rule_customer_groups, $catalogRule);
|
||||
|
||||
if($catalogRule && $catalogRuleChannels && $catalogRuleCustomerGroups) {
|
||||
session()->flash('info', trans('admin::app.promotion.status.update-success'));
|
||||
|
||||
return redirect()->route($this->_config['redirect']);
|
||||
} else {
|
||||
session()->flash('error', trans('admin::app.promotion.status.update-failed'));
|
||||
|
||||
return redirect()->back();
|
||||
}
|
||||
}
|
||||
|
||||
public function applyRules()
|
||||
{
|
||||
$catalogRules = $this->catalogRule->all();
|
||||
$decoded = json_decode($catalogRules->first()->conditions);
|
||||
$conditions = json_decode($decoded[0]);
|
||||
$optionableAttributes = $this->fetchOptionableAttributes();
|
||||
|
||||
$results = $this->findProducts->findByConditions($conditions);
|
||||
|
||||
dd($results);
|
||||
}
|
||||
|
||||
public function fetchOptionableAttributes()
|
||||
{
|
||||
$attributesWithOptions = array();
|
||||
|
||||
foreach($this->attribute->all() as $attribute) {
|
||||
if (($attribute->type == 'select' || $attribute->type == 'multiselect') && $attribute->code != 'tax_category_id') {
|
||||
$attributesWithOptions[$attribute->code] = $attribute->options->toArray();
|
||||
}
|
||||
}
|
||||
|
||||
return $attributesWithOptions;
|
||||
}
|
||||
|
||||
public function destroy($id)
|
||||
{
|
||||
$catalogRule = $this->catalogRule->findOrFail($id);
|
||||
|
||||
if ($catalogRule->delete()) {
|
||||
session()->flash('success', trans('admin::app.promotion.delete-success'));
|
||||
|
||||
return response()->json(['message' => true], 200);
|
||||
} else {
|
||||
session()->flash('success', trans('admin::app.promotion.delete-failed'));
|
||||
|
||||
return response()->json(['message' => false], 400);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
|
||||
namespace Webkul\Discount\Http\Controllers;
|
||||
|
||||
use Illuminate\Foundation\Bus\DispatchesJobs;
|
||||
use Illuminate\Routing\Controller as BaseController;
|
||||
use Illuminate\Foundation\Validation\ValidatesRequests;
|
||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||
|
||||
class Controller extends BaseController
|
||||
{
|
||||
use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
<?php
|
||||
|
||||
namespace Webkul\Discount\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Webkul\Discount\Contracts\CartRule as CartRuleContract;
|
||||
use Webkul\Discount\Models\CartRuleChannelsProxy as CartRuleChannels;
|
||||
use Webkul\Discount\Models\CartRuleCustomerGroupsProxy as CartRuleCustomerGroups;
|
||||
use Webkul\Discount\Models\CartRuleCouponsProxy as CartRuleCoupons;
|
||||
use Webkul\Discount\Models\CartRuleLabelsProxy as CartRuleLabels;
|
||||
|
||||
class CartRule extends Model implements CartRuleContract
|
||||
{
|
||||
protected $table = 'cart_rules';
|
||||
|
||||
protected $guarded = ['created_at', 'updated_at'];
|
||||
|
||||
protected $with = ['channels', 'customer_groups', 'coupons', 'labels'];
|
||||
|
||||
public function channels()
|
||||
{
|
||||
return $this->hasMany(CartRuleChannels::modelClass());
|
||||
}
|
||||
|
||||
public function customer_groups()
|
||||
{
|
||||
return $this->hasMany(CartRuleCustomerGroups::modelClass());
|
||||
}
|
||||
|
||||
public function coupons()
|
||||
{
|
||||
return $this->hasOne(CartRuleCoupons::modelClass());
|
||||
}
|
||||
|
||||
public function labels()
|
||||
{
|
||||
return $this->hasMany(CartRuleLabels::modelClass());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
|
||||
namespace Webkul\Discount\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Webkul\Discount\Models\CartRuleProxy as CartRule;
|
||||
use Webkul\Discount\Contracts\CartRuleCart as CartRuleCartContract;
|
||||
|
||||
|
||||
class CartRuleCart extends Model implements CartRuleCartContract
|
||||
{
|
||||
protected $table = 'cart_rule_cart';
|
||||
|
||||
protected $guarded = ['created_at', 'updated_at'];
|
||||
|
||||
protected $with = ['cart_rule'];
|
||||
|
||||
public function cart_rule()
|
||||
{
|
||||
return $this->hasOne(CartRule::modelClass(), 'id', 'cart_rule_id');
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
|
||||
namespace Webkul\Discount\Models;
|
||||
|
||||
use Konekt\Concord\Proxies\ModelProxy;
|
||||
|
||||
class CartRuleCartProxy extends ModelProxy
|
||||
{
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
|
||||
namespace Webkul\Discount\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Webkul\Discount\Contracts\CartRuleChannels as CartRuleChannelsContract;
|
||||
|
||||
class CartRuleChannels extends Model implements CartRuleChannelsContract
|
||||
{
|
||||
protected $table = 'cart_rule_channels';
|
||||
|
||||
protected $guarded = ['created_at', 'updated_at'];
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
|
||||
namespace Webkul\Discount\Models;
|
||||
|
||||
use Konekt\Concord\Proxies\ModelProxy;
|
||||
|
||||
class CartRuleChannelsProxy extends ModelProxy
|
||||
{
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
|
||||
namespace Webkul\Discount\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Webkul\Discount\Contracts\CartRuleCoupons as CartRuleCouponsContract;
|
||||
use Webkul\Discount\Models\CartRuleProxy as CartRule;
|
||||
|
||||
class CartRuleCoupons extends Model implements CartRuleCouponsContract
|
||||
{
|
||||
protected $table = 'cart_rule_coupons';
|
||||
|
||||
protected $guarded = ['created_at', 'updated_at'];
|
||||
|
||||
public function cart_rule()
|
||||
{
|
||||
return $this->belongsTo(CartRule::modelClass(), 'cart_rule_id');
|
||||
}
|
||||
|
||||
public function coupons_usage()
|
||||
{
|
||||
return $this->hasOne(CartRuleCouponsUsage::modelClass());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
|
||||
namespace Webkul\Discount\Models;
|
||||
|
||||
use Konekt\Concord\Proxies\ModelProxy;
|
||||
|
||||
class CartRuleCouponsProxy extends ModelProxy
|
||||
{
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
<?php
|
||||
|
||||
namespace Webkul\Discount\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Webkul\Discount\Contracts\CartRuleCouponsUsage as CartRuleCouponsUsageContract;
|
||||
use Webkul\Discount\Models\CartRuleProxy as CartRule;
|
||||
|
||||
class CartRuleCouponsUsage extends Model implements CartRuleCouponsUsageContract
|
||||
{
|
||||
protected $table = 'cart_rule_coupons_usage';
|
||||
|
||||
protected $guarded = ['created_at', 'updated_at'];
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
namespace Webkul\Discount\Models;
|
||||
|
||||
use Konekt\Concord\Proxies\ModelProxy;
|
||||
|
||||
class CartRuleCouponsUsageProxy extends ModelProxy
|
||||
{
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
|
||||
namespace Webkul\Discount\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Webkul\Discount\Contracts\CartRuleCustomerGroups as CartRuleCustomerGroupContract;
|
||||
|
||||
class CartRuleCustomerGroups extends Model implements CartRuleCustomerGroupContract
|
||||
{
|
||||
protected $table = 'cart_rule_customer_groups';
|
||||
|
||||
protected $guarded = ['created_at', 'updated_at'];
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
|
||||
namespace Webkul\Discount\Models;
|
||||
|
||||
use Konekt\Concord\Proxies\ModelProxy;
|
||||
|
||||
class CartRuleCustomerGroupsProxy extends ModelProxy
|
||||
{
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
<?php
|
||||
|
||||
namespace Webkul\Discount\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Webkul\Discount\Contracts\CartRuleCustomers as CartRuleCustomersContract;
|
||||
use Webkul\Discount\Models\CartRuleProxy as CartRule;
|
||||
|
||||
class CartRuleCustomers extends Model implements CartRuleCustomersContract
|
||||
{
|
||||
protected $table = 'cart_rule_customers';
|
||||
|
||||
protected $guarded = ['created_at', 'updated_at'];
|
||||
|
||||
public function cart_rule()
|
||||
{
|
||||
return $this->belongsTo(CartRule::modelClass(), 'cart_rule_id');
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
|
||||
namespace Webkul\Discount\Models;
|
||||
|
||||
use Konekt\Concord\Proxies\ModelProxy;
|
||||
|
||||
class CartRuleCustomersProxy extends ModelProxy
|
||||
{
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
|
||||
namespace Webkul\Discount\Models;
|
||||
|
||||
use Konekt\Concord\Proxies\ModelProxy;
|
||||
|
||||
class CartRuleLabelsProxy extends ModelProxy
|
||||
{
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
<?php
|
||||
|
||||
namespace Webkul\Discount\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Webkul\Discount\Contracts\CartRuleLabels as CartRuleLabelsContract;
|
||||
use Webkul\Discount\Models\CartRuleProxy as CartRule;
|
||||
use Webkul\Core\Models\LocaleProxy as Locale;
|
||||
use Webkul\Core\Models\ChannelProxy as Channel;
|
||||
|
||||
class CartRuleLabels extends Model implements CartRuleLabelsContract
|
||||
{
|
||||
protected $table = 'cart_rule_labels';
|
||||
|
||||
protected $guarded = ['created_at', 'updated_at'];
|
||||
|
||||
protected $with = ['locale', 'channel'];
|
||||
|
||||
public function cart_rule()
|
||||
{
|
||||
return $this->belongsTo(CartRule::modelClass(), 'cart_rule_id');
|
||||
}
|
||||
|
||||
public function locale()
|
||||
{
|
||||
return $this->hasOne(Locale::modelClass(), 'id', 'locale_id');
|
||||
}
|
||||
|
||||
public function channel()
|
||||
{
|
||||
return $this->hasOne(Channel::modelClass(), 'id', 'channel_id');
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
|
||||
namespace Webkul\Discount\Models;
|
||||
|
||||
use Konekt\Concord\Proxies\ModelProxy;
|
||||
|
||||
class CartRuleProxy extends ModelProxy
|
||||
{
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
<?php
|
||||
|
||||
namespace Webkul\Discount\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Webkul\Discount\Contracts\CatalogRule as CatalogRuleContract;
|
||||
use Webkul\Discount\Models\CatalogRuleChannelsProxy as CatalogRuleChannels;
|
||||
use Webkul\Discount\Models\CatalogRuleCustomerGroupsProxy as CatalogRuleCustomerGroups;
|
||||
|
||||
class CatalogRule extends Model implements CatalogRuleContract
|
||||
{
|
||||
protected $table = 'catalog_rules';
|
||||
|
||||
protected $guarded = ['created_at', 'updated_at'];
|
||||
|
||||
public function channels()
|
||||
{
|
||||
return $this->hasMany(CatalogRuleChannels::modelClass());
|
||||
}
|
||||
|
||||
public function customer_groups()
|
||||
{
|
||||
return $this->hasMany(CatalogRuleCustomerGroups::modelClass());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
<?php
|
||||
|
||||
namespace Webkul\Discount\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Webkul\Discount\Contracts\CatalogRuleChannels as CatalogRuleChannelsContract;
|
||||
use Webkul\Discount\Models\CatalogRuleProxy as CatalogRule;
|
||||
|
||||
class CatalogRuleChannels extends Model implements CatalogRuleChannelsContract
|
||||
{
|
||||
protected $table = 'catalog_rule_channels';
|
||||
|
||||
protected $guarded = ['created_at', 'updated_at'];
|
||||
|
||||
public function catalog_rule()
|
||||
{
|
||||
return $this->belongsTo(CatalogRule::modelClass(), 'catalog_rule_id');
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
|
||||
namespace Webkul\Discount\Models;
|
||||
|
||||
use Konekt\Concord\Proxies\ModelProxy;
|
||||
|
||||
class CatalogRuleChannelsProxy extends ModelProxy
|
||||
{
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
<?php
|
||||
|
||||
namespace Webkul\Discount\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Webkul\Discount\Contracts\CatalogRuleCustomerGroups as CatalogRuleCustomerGroupsContract;
|
||||
use Webkul\Discount\Models\CatalogRuleProxy as CatalogRule;
|
||||
|
||||
class CatalogRuleCustomerGroups extends Model implements CatalogRuleCustomerGroupsContract
|
||||
{
|
||||
protected $table = 'catalog_rule_customer_groups';
|
||||
|
||||
protected $guarded = ['created_at', 'updated_at'];
|
||||
|
||||
public function catalog_rule()
|
||||
{
|
||||
return $this->belongsTo(CatalogRule::modelClass(), 'catalog_rule_id');
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
|
||||
namespace Webkul\Discount\Models;
|
||||
|
||||
use Konekt\Concord\Proxies\ModelProxy;
|
||||
|
||||
class CatalogRuleCustomerGroupsProxy extends ModelProxy
|
||||
{
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
|
||||
namespace Webkul\Discount\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Webkul\Discount\Contracts\CatalogRuleProducts as CatalogRuleProductsContract;
|
||||
|
||||
class CatalogRuleProducts extends Model implements CatalogRuleProductsContract
|
||||
{
|
||||
protected $table = 'cart_rules_products';
|
||||
|
||||
protected $guarded = ['created_at', 'updated_at'];
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
|
||||
namespace Webkul\Discount\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Webkul\Discount\Contracts\CatalogRuleProductsPrice as CatalogRuleProductsPriceContract;
|
||||
|
||||
class CatalogRuleProductsPrice extends Model implements CatalogRuleProductsPriceContract
|
||||
{
|
||||
protected $table = 'cart_rules_products_price';
|
||||
|
||||
protected $guarded = ['created_at', 'updated_at'];
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
|
||||
namespace Webkul\Discount\Models;
|
||||
|
||||
use Konekt\Concord\Proxies\ModelProxy;
|
||||
|
||||
class CatalogRuleProductsProxy extends ModelProxy
|
||||
{
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
|
||||
namespace Webkul\Discount\Models;
|
||||
|
||||
use Konekt\Concord\Proxies\ModelProxy;
|
||||
|
||||
class CatalogRuleProxy extends ModelProxy
|
||||
{
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
|
||||
namespace Webkul\Discount\Models;
|
||||
|
||||
use Konekt\Concord\Proxies\ModelProxy;
|
||||
|
||||
class CatalogRuleProductsPriceProxy extends ModelProxy
|
||||
{
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
<?php
|
||||
|
||||
namespace Webkul\Discount\Providers;
|
||||
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use Illuminate\Routing\Router;
|
||||
|
||||
class DiscountServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* Bootstrap services.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function boot(Router $router)
|
||||
{
|
||||
$this->loadMigrationsFrom(__DIR__ . '/../Database/Migrations');
|
||||
}
|
||||
|
||||
/**
|
||||
* Register services.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register()
|
||||
{
|
||||
$this->registerConfig();
|
||||
}
|
||||
|
||||
/**
|
||||
* To merge the price rule configuration in price rule configuration
|
||||
*/
|
||||
protected function registerConfig()
|
||||
{
|
||||
$this->mergeConfigFrom(
|
||||
dirname(__DIR__) . '/Config/rule-conditions.php', 'pricerules'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
<?php
|
||||
|
||||
namespace Webkul\Discount\Providers;
|
||||
|
||||
use Konekt\Concord\BaseModuleServiceProvider;
|
||||
|
||||
class ModuleServiceProvider extends BaseModuleServiceProvider
|
||||
{
|
||||
protected $models = [
|
||||
\Webkul\Discount\Models\CatalogRule::class,
|
||||
\Webkul\Discount\Models\CatalogRuleChannels::class,
|
||||
\Webkul\Discount\Models\CatalogRuleCustomerGroups::class,
|
||||
\Webkul\Discount\Models\CatalogRuleProducts::class,\Webkul\Discount\Models\CatalogRuleProductsPrice::class,
|
||||
\Webkul\Discount\Models\CartRule::class,
|
||||
\Webkul\Discount\Models\CartRuleChannels::class,
|
||||
\Webkul\Discount\Models\CartRuleCustomerGroups::class,
|
||||
\Webkul\Discount\Models\CartRuleCoupons::class,
|
||||
\Webkul\Discount\Models\CartRuleLabels::class,
|
||||
\Webkul\Discount\Models\CartRuleCouponsUsage::class,
|
||||
\Webkul\Discount\Models\CartRuleCustomers::class,
|
||||
\Webkul\Discount\Models\CartRuleCart::class,
|
||||
];
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue