diff --git a/CHANGELOG for v0.1.x.md b/CHANGELOG for v0.1.x.md
index 1359bdd27..be4c3b3c1 100755
--- a/CHANGELOG for v0.1.x.md
+++ b/CHANGELOG for v0.1.x.md
@@ -2,6 +2,70 @@
#### This changelog consists the bug & security fixes and new features being included in the releases listed below.
+## **v0.1.9 (20th of December, 2019)** - *Release*
+
+* #1875 [fixed] - Discount gets applied on cart if condition is "Visible Individually" is set to yes and product added in cart is not visible individually.
+
+* #1868 [fixed] - Getting exception on checkout if action Buy X Get Y free is selected in cart rule.
+
+* #1838 [fixed] - Cart rule not working for condition sku(children only) and sku(parent only).
+
+* #1835 [fixed] - Getting exception if condition value remains blank.
+
+* #1831 [fixed] - Negative sign is not required in discount amount.
+
+* #1830 [fixed] - If Coupon type is selected as "No Coupon" then coupon code should not generate for that particular cart rule.
+
+* #1904 [fixed] - Existing tax should display as list on creating catalog rule if in condition "Tax Category" is selected.
+
+* #1903 [fixed] - UI issue in condition field
+
+* #1895 [fixed] - Translation issue Action Type field while creating catalog rule.
+
+* #1883 [fixed] - Free shipping not applied on cart, if from action "Free Shipping" is selected and discount amount is given as zero.
+
+* #1882 [fixed] - If from Action "Apply on shipping " is selected as yes then the discounted amount is applying on both product and shipping charge.
+
+* #1861 [fixed] - Getting exception on checkout if applying invalid coupon code and proceed for checkout.
+
+* #1857 [fixed] - Getting exception when creating cart rule with condition URL KEY(children only).
+
+* #1856 [fixed] - Getting exception on creating cart rule with condition Name(children only).
+
+* #1847 [fixed] - If cart rule condition does not match the cart then on applying coupon it should display message "Coupon cannot be applied".
+
+* #1839 [fixed] - Getting exception on filtering cart rule through id.
+
+* #1836 [fixed] - Back button on Edit cart rule page doesn't work.
+
+* #1834 [fixed] - On editing any cart rule, its priority updates to 1.
+
+* #1833 [fixed] - Discount not applied if "Payment Method", "Shipping Method", "Shipping State" or "Shipping Country" is selected in condition.
+
+* #1832 [fixed] - Able to use coupon irrespective of the number given in "Uses per coupon" field.
+
+* #1828 [fixed] - Updated changes are not saved on editing cart rule.
+
+* #1825 [fixed] - Not able to generate coupon code while creating cart rule.
+
+* #1823 [fixed] - Getting exception after clicking on developement.
+
+* #1929 [fixed] - Actual product amount and discounted amount both should display on product page for configurable product
+
+* #1928 [fixed] - Catalog rule should not apply if any of the condition doesn't match, if condition type"All Condition are true"
+
+* #1931 [fixed] - Catalog rule not applying if in condition type"Any Condition is true" is selected, and some of the condition doesn't match the product.
+
+* #1935 [fixed] - Categories are not displaying if in condition Categories(children only) or Categories(Parent Only) is selected.
+
+* #1938 [fixed] - multiple cart rules are getting applied by using only single coupon.
+
+* #1939 [fixed] - Invalid coupon gets applied, if clicking on apply coupon multiple time, although there is no discount amount but its displaying message that coupon code applied successfully.
+
+* #1942 [fixed] - When editing the cart rule, selected category is not checked.
+
+
+
## **v0.1.8 (4th of October, 2019)** - *Release*
* [feature] - Refund is added for orders.
diff --git a/CHANGELOG for v0.2.x.md b/CHANGELOG for v0.2.x.md
new file mode 100644
index 000000000..bf693debb
--- /dev/null
+++ b/CHANGELOG for v0.2.x.md
@@ -0,0 +1,17 @@
+# CHANGELOG for v0.2.x
+
+#### This changelog consists the bug & security fixes and new features being included in the releases listed below.
+
+## **v0.2.0 (23th of December, 2019)** - *Release*
+
+* #1955 [fixed] - Message need to be changed on mouse hover on cross symbol next to applied coupon.
+
+* #1959 [fixed] - if admin has set the same condition twice, then catalog rule is not getting apply
+
+* #1958 [fixed] - getting exception on front end, if action type is Buy x get y free in non couponable cart rule.
+
+* #1957 [fixed] - if action type is Fixed Amount to Whole Cart, then apply to shipping option should get hide.
+
+* #1954 [fixed] - If any different tax category has been assigned to variants in configurable product, then while using tax category condition in cart rule, rule is not working properly.
+
+* #1950 [fixed] - multiple catalog rule should not get get applied, if 1st one has been created as End Other Rules = yes
\ No newline at end of file
diff --git a/composer.json b/composer.json
index 48d7ac945..fbf39f708 100755
--- a/composer.json
+++ b/composer.json
@@ -132,7 +132,8 @@
"set -e",
"@php artisan migrate:fresh --env=testing",
"vendor/bin/codecept run unit",
- "vendor/bin/codecept run functional"
+ "vendor/bin/codecept run functional",
+ "vendor/bin/codecept run trigger"
]
},
"config": {
diff --git a/config/app.php b/config/app.php
index 3763cd6d3..d3384a7f9 100755
--- a/config/app.php
+++ b/config/app.php
@@ -246,7 +246,9 @@ return [
Webkul\Sales\Providers\SalesServiceProvider::class,
Webkul\Tax\Providers\TaxServiceProvider::class,
Webkul\API\Providers\APIServiceProvider::class,
- Webkul\Discount\Providers\DiscountServiceProvider::class,
+ Webkul\CatalogRule\Providers\CatalogRuleServiceProvider::class,
+ Webkul\CartRule\Providers\CartRuleServiceProvider::class,
+ Webkul\Rule\Providers\RuleServiceProvider::class,
Webkul\CMS\Providers\CMSServiceProvider::class
],
diff --git a/config/concord.php b/config/concord.php
index 311ede347..24c40b47a 100755
--- a/config/concord.php
+++ b/config/concord.php
@@ -19,7 +19,8 @@ return [
\Webkul\Sales\Providers\ModuleServiceProvider::class,
\Webkul\Tax\Providers\ModuleServiceProvider::class,
\Webkul\User\Providers\ModuleServiceProvider::class,
- \Webkul\Discount\Providers\ModuleServiceProvider::class,
+ \Webkul\CatalogRule\Providers\ModuleServiceProvider::class,
+ \Webkul\CartRule\Providers\ModuleServiceProvider::class,
\Webkul\CMS\Providers\ModuleServiceProvider::class
]
];
\ No newline at end of file
diff --git a/packages/Webkul/Admin/src/Config/acl.php b/packages/Webkul/Admin/src/Config/acl.php
index db7edbff7..8b28872db 100755
--- a/packages/Webkul/Admin/src/Config/acl.php
+++ b/packages/Webkul/Admin/src/Config/acl.php
@@ -394,27 +394,27 @@ return [
], [
'key' => 'promotions',
'name' => 'admin::app.acl.promotions',
- 'route' => 'admin.cart-rule.index',
+ 'route' => 'admin.cart-rules.index',
'sort' => 7
], [
- 'key' => 'promotions.cart-rule',
+ 'key' => 'promotions.cart-rules',
'name' => 'admin::app.acl.cart-rules',
- 'route' => 'admin.cart-rule.index',
+ 'route' => 'admin.cart-rules.index',
'sort' => 1
], [
- 'key' => 'promotions.cart-rule.create',
+ 'key' => 'promotions.cart-rules.create',
'name' => 'admin::app.acl.create',
- 'route' => 'admin.cart-rule.create',
+ 'route' => 'admin.cart-rules.create',
'sort' => 1
], [
- 'key' => 'promotions.cart-rule.edit',
+ 'key' => 'promotions.cart-rules.edit',
'name' => 'admin::app.acl.edit',
- 'route' => 'admin.cart-rule.edit',
+ 'route' => 'admin.cart-rules.edit',
'sort' => 2
], [
- 'key' => 'promotions.cart-rule.delete',
+ 'key' => 'promotions.cart-rules.delete',
'name' => 'admin::app.acl.delete',
- 'route' => 'admin.cart-rule.delete',
+ 'route' => 'admin.cart-rules.delete',
'sort' => 3
],
];
diff --git a/packages/Webkul/Admin/src/Config/menu.php b/packages/Webkul/Admin/src/Config/menu.php
index cfa9d6877..a1420eb85 100755
--- a/packages/Webkul/Admin/src/Config/menu.php
+++ b/packages/Webkul/Admin/src/Config/menu.php
@@ -189,22 +189,22 @@ return [
'icon-class' => ''
],[
'key' => 'promotions',
- 'name' => 'admin::app.layouts.promotion',
- 'route' => 'admin.cart-rule.index',
+ 'name' => 'admin::app.layouts.promotions',
+ 'route' => 'admin.catalog-rules.index',
'sort' => 5,
'icon-class' => 'promotion-icon'
], [
- 'key' => 'promotions.cart-rule',
- 'name' => 'admin::app.promotion.cart-rule',
- 'route' => 'admin.cart-rule.index',
+ 'key' => 'promotions.catalog-rules',
+ 'name' => 'admin::app.promotions.catalog-rules.title',
+ 'route' => 'admin.catalog-rules.index',
'sort' => 1,
'icon-class' => ''
], [
- 'key' => 'promotions.catalog-rule',
- 'name' => 'admin::app.promotion.catalog-rule',
- 'route' => 'admin.catalog-rule.index',
- 'sort' => 1,
- 'icon-class' => '',
+ 'key' => 'promotions.cart-rules',
+ 'name' => 'admin::app.promotions.cart-rules.title',
+ 'route' => 'admin.cart-rules.index',
+ 'sort' => 2,
+ 'icon-class' => ''
], [
'key' => 'cms',
'name' => 'admin::app.layouts.cms',
diff --git a/packages/Webkul/Admin/src/DataGrids/CartRuleCouponDataGrid.php b/packages/Webkul/Admin/src/DataGrids/CartRuleCouponDataGrid.php
new file mode 100644
index 000000000..ccf8c6375
--- /dev/null
+++ b/packages/Webkul/Admin/src/DataGrids/CartRuleCouponDataGrid.php
@@ -0,0 +1,86 @@
+
+ * @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com)
+ */
+class CartRuleCouponDataGrid extends DataGrid
+{
+ protected $index = 'id';
+
+ protected $sortOrder = 'desc';
+
+ public function prepareQueryBuilder()
+ {
+ $queryBuilder = DB::table('cart_rule_coupons')
+ ->addSelect('id', 'code', 'created_at', 'expired_at', 'times_used')
+ ->where('cart_rule_coupons.cart_rule_id', request('id'));
+
+ $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.coupon-code'),
+ 'type' => 'string',
+ 'searchable' => true,
+ 'sortable' => true,
+ 'filterable' => true
+ ]);
+
+ $this->addColumn([
+ 'index' => 'created_at',
+ 'label' => trans('admin::app.datagrid.created-date'),
+ 'type' => 'datetime',
+ 'sortable' => true,
+ 'searchable' => false,
+ 'filterable' => true
+ ]);
+
+ $this->addColumn([
+ 'index' => 'expired_at',
+ 'label' => trans('admin::app.datagrid.expiration-date'),
+ 'type' => 'datetime',
+ 'sortable' => true,
+ 'searchable' => false,
+ 'filterable' => true
+ ]);
+
+ $this->addColumn([
+ 'index' => 'times_used',
+ 'label' => trans('admin::app.datagrid.times-used'),
+ 'type' => 'number',
+ 'searchable' => true,
+ 'sortable' => true,
+ 'filterable' => true
+ ]);
+ }
+
+ public function prepareMassActions()
+ {
+ $this->addMassAction([
+ 'type' => 'delete',
+ 'action' => route('admin.cart-rule-coupons.mass-delete'),
+ 'label' => trans('admin::app.datagrid.delete'),
+ 'method' => 'DELETE'
+ ]);
+ }
+}
diff --git a/packages/Webkul/Admin/src/DataGrids/CartRuleDataGrid.php b/packages/Webkul/Admin/src/DataGrids/CartRuleDataGrid.php
index 7eb57ffd7..c6efb9517 100644
--- a/packages/Webkul/Admin/src/DataGrids/CartRuleDataGrid.php
+++ b/packages/Webkul/Admin/src/DataGrids/CartRuleDataGrid.php
@@ -8,20 +8,27 @@ use DB;
/**
* Cart Rule DataGrid class
*
- * @author Prashant Singh @prashant-webkul
+ * @author Jitendra Singh
* @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 $index = 'id';
- protected $sortOrder = 'desc'; //asc or desc
+ protected $sortOrder = 'desc';
public function prepareQueryBuilder()
{
$queryBuilder = DB::table('cart_rules')
- ->select('id')
- ->addSelect('id', 'name', 'status', 'end_other_rules', 'action_type', 'disc_amount', 'use_coupon');
+ ->leftJoin('cart_rule_coupons', function($leftJoin) {
+ $leftJoin->on('cart_rule_coupons.cart_rule_id', '=', 'cart_rules.id')
+ ->where('cart_rule_coupons.is_primary', 1);
+ })
+ ->addSelect('cart_rules.id', 'name', 'cart_rule_coupons.code as coupon_code', 'status', 'starts_from', 'ends_till', 'sort_order');
+
+ $this->addFilter('id', 'cart_rules.id');
+
+ $this->addFilter('coupon_code', 'cart_rule_coupons.code');
$this->setQueryBuilder($queryBuilder);
}
@@ -30,7 +37,7 @@ class CartRuleDataGrid extends DataGrid
{
$this->addColumn([
'index' => 'id',
- 'label' => trans('admin::app.id'),
+ 'label' => trans('admin::app.datagrid.id'),
'type' => 'number',
'searchable' => false,
'sortable' => true,
@@ -39,13 +46,40 @@ class CartRuleDataGrid extends DataGrid
$this->addColumn([
'index' => 'name',
- 'label' => trans('admin::app.name'),
+ 'label' => trans('admin::app.datagrid.name'),
'type' => 'string',
'searchable' => true,
'sortable' => true,
'filterable' => true
]);
+ $this->addColumn([
+ 'index' => 'coupon_code',
+ 'label' => trans('admin::app.datagrid.coupon-code'),
+ 'type' => 'string',
+ 'searchable' => true,
+ 'sortable' => true,
+ 'filterable' => true
+ ]);
+
+ $this->addColumn([
+ 'index' => 'starts_from',
+ 'label' => trans('admin::app.datagrid.start'),
+ 'type' => 'datetime',
+ 'sortable' => true,
+ 'searchable' => false,
+ 'filterable' => true
+ ]);
+
+ $this->addColumn([
+ 'index' => 'ends_till',
+ 'label' => trans('admin::app.datagrid.end'),
+ 'type' => 'datetime',
+ 'sortable' => true,
+ 'searchable' => false,
+ 'filterable' => true
+ ]);
+
$this->addColumn([
'index' => 'status',
'label' => trans('admin::app.status'),
@@ -55,89 +89,36 @@ class CartRuleDataGrid extends DataGrid
'filterable' => true,
'wrapper' => function($value) {
if ($value->status == 1)
- return 'Active';
+ return trans('admin::app.datagrid.active');
else
- return 'In Active';
+ return trans('admin::app.datagrid.inactive');
}
]);
$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' => true,
- 'sortable' => true,
- 'filterable' => true,
- 'wrapper' => function($value) {
- return config('pricerules.cart.actions')[$value->action_type];
- }
- ]);
-
- $this->addColumn([
- 'index' => 'disc_amount',
- 'label' => 'Discount Amount',
+ 'index' => 'sort_order',
+ 'label' => trans('admin::app.datagrid.priority'),
'type' => 'number',
- 'searchable' => false,
+ 'searchable' => true,
'sortable' => true,
'filterable' => true
]);
-
- $this->addColumn([
- 'index' => 'use_coupon',
- 'label' => 'Use Coupon',
- 'type' => 'boolean',
- 'searchable' => true,
- 'sortable' => true,
- 'filterable' => true,
- 'wrapper' => function($value) {
- if ($value->use_coupon == 1) {
- return 'True';
- } else {
- return 'False';
- }
- }
- ]);
}
public function prepareActions()
{
$this->addAction([
- 'title' => 'Edit CartRule',
- 'method' => 'GET', //use post only for redirects only
- 'route' => 'admin.cart-rule.edit',
+ 'title' => 'Edit Cart Rule',
+ 'method' => 'GET',
+ 'route' => 'admin.cart-rules.edit',
'icon' => 'icon pencil-lg-icon'
]);
$this->addAction([
- 'title' => 'Delete CartRule',
- 'method' => 'POST', //use post only for requests other than redirects
- 'route' => 'admin.cart-rule.delete',
+ 'title' => 'Delete Cart Rule',
+ 'method' => 'POST',
+ 'route' => 'admin.cart-rules.delete',
'icon' => 'icon trash-icon'
]);
}
-
- public function prepareMassActions()
- {
- // $this->addMassAction([
- // 'type' => 'delete',
- // 'action' => route('admin.catalog.attributes.massdelete'),
- // 'label' => 'Delete',
- // 'method' => 'DELETE'
- // ]);
- }
}
diff --git a/packages/Webkul/Admin/src/DataGrids/CatalogRuleDataGrid.php b/packages/Webkul/Admin/src/DataGrids/CatalogRuleDataGrid.php
index 506af12eb..e57e977a1 100644
--- a/packages/Webkul/Admin/src/DataGrids/CatalogRuleDataGrid.php
+++ b/packages/Webkul/Admin/src/DataGrids/CatalogRuleDataGrid.php
@@ -8,20 +8,19 @@ use DB;
/**
* Catalog Rule DataGrid class
*
- * @author Prashant Singh @prashant-webkul
+ * @author Jitendra Singh
* @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 $index = 'id';
- protected $sortOrder = 'desc'; //asc or desc
+ protected $sortOrder = 'desc';
public function prepareQueryBuilder()
{
$queryBuilder = DB::table('catalog_rules')
- ->select('id')
- ->addSelect('id', 'name', 'starts_from', 'ends_till', 'status', 'end_other_rules', 'action_code');
+ ->addSelect('catalog_rules.id', 'name', 'status', 'starts_from', 'ends_till', 'sort_order');
$this->setQueryBuilder($queryBuilder);
}
@@ -48,56 +47,41 @@ class CatalogRuleDataGrid extends DataGrid
$this->addColumn([
'index' => 'starts_from',
- 'label' => trans('admin::app.datagrid.starts-from'),
+ 'label' => trans('admin::app.datagrid.start'),
'type' => 'datetime',
- 'searchable' => false,
'sortable' => true,
+ 'searchable' => false,
'filterable' => true
]);
$this->addColumn([
'index' => 'ends_till',
- 'label' => trans('admin::app.datagrid.ends-till'),
+ 'label' => trans('admin::app.datagrid.end'),
'type' => 'datetime',
- 'searchable' => false,
'sortable' => true,
+ 'searchable' => false,
'filterable' => true
]);
$this->addColumn([
'index' => 'status',
- 'label' => trans('admin::app.datagrid.status'),
+ 'label' => trans('admin::app.status'),
'type' => 'boolean',
- 'searchable' => false,
+ 'searchable' => true,
'sortable' => true,
'filterable' => true,
- 'wrapper' => function ($value) {
+ 'wrapper' => function($value) {
if ($value->status == 1)
- return 'True';
+ return trans('admin::app.datagrid.active');
else
- return 'False';
+ return trans('admin::app.datagrid.inactive');
}
]);
$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_code',
- 'label' => 'Action Type',
- 'type' => 'string',
+ 'index' => 'sort_order',
+ 'label' => trans('admin::app.datagrid.priority'),
+ 'type' => 'number',
'searchable' => true,
'sortable' => true,
'filterable' => true
@@ -107,27 +91,17 @@ class CatalogRuleDataGrid extends DataGrid
public function prepareActions()
{
$this->addAction([
- 'title' => 'Edit CatalogRule',
- 'method' => 'GET', //use post only for redirects only
- 'route' => 'admin.catalog-rule.edit',
+ 'title' => 'Edit Catalog Rule',
+ 'method' => 'GET',
+ 'route' => 'admin.catalog-rules.edit',
'icon' => 'icon pencil-lg-icon'
]);
$this->addAction([
- 'title' => 'Delete CatalogRule',
- 'method' => 'POST', //use post only for requests other than redirects
- 'route' => 'admin.catalog-rule.delete',
+ 'title' => 'Delete Catalog Rule',
+ 'method' => 'POST',
+ 'route' => 'admin.catalog-rules.delete',
'icon' => 'icon trash-icon'
]);
}
-
- public function prepareMassActions()
- {
- // $this->addMassAction([
- // 'type' => 'delete',
- // 'action' => route('admin.catalog.attributes.massdelete'),
- // 'label' => 'Delete',
- // 'method' => 'DELETE'
- // ]);
- }
}
diff --git a/packages/Webkul/Admin/src/Http/routes.php b/packages/Webkul/Admin/src/Http/routes.php
index 50c6557bd..6da6f2068 100755
--- a/packages/Webkul/Admin/src/Http/routes.php
+++ b/packages/Webkul/Admin/src/Http/routes.php
@@ -669,60 +669,56 @@ 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-rules', 'Webkul\Discount\Http\Controllers\CatalogRuleController@index')->defaults('_config', [
- 'view' => 'admin::promotions.catalog-rule.index'
- ])->name('admin.catalog-rule.index');
+ Route::prefix('promotions')->group(function () {
+ Route::get('cart-rules', 'Webkul\CartRule\Http\Controllers\CartRuleController@index')->defaults('_config', [
+ 'view' => 'admin::promotions.cart-rules.index'
+ ])->name('admin.cart-rules.index');
- Route::get('/catalog-rules/create', 'Webkul\Discount\Http\Controllers\CatalogRuleController@create')->defaults('_config', [
- 'view' => 'admin::promotions.catalog-rule.create'
- ])->name('admin.catalog-rule.create');
+ Route::get('cart-rules/create', 'Webkul\CartRule\Http\Controllers\CartRuleController@create')->defaults('_config', [
+ 'view' => 'admin::promotions.cart-rules.create'
+ ])->name('admin.cart-rules.create');
- Route::post('/catalog-rules/create', 'Webkul\Discount\Http\Controllers\CatalogRuleController@store')->defaults('_config', [
- 'redirect' => 'admin.catalog-rule.index'
- ])->name('admin.catalog-rule.store');
+ Route::post('cart-rules/create', 'Webkul\CartRule\Http\Controllers\CartRuleController@store')->defaults('_config', [
+ 'redirect' => 'admin.cart-rules.index'
+ ])->name('admin.cart-rules.store');
- Route::get('/catalog-rules/edit/{id}', 'Webkul\Discount\Http\Controllers\CatalogRuleController@edit')->defaults('_config', [
- 'view' => 'admin::promotions.catalog-rule.edit'
- ])->name('admin.catalog-rule.edit');
+ Route::get('cart-rules/edit/{id}', 'Webkul\CartRule\Http\Controllers\CartRuleController@edit')->defaults('_config', [
+ 'view' => 'admin::promotions.cart-rules.edit'
+ ])->name('admin.cart-rules.edit');
- Route::post('/catalog-rules/edit/{id}', 'Webkul\Discount\Http\Controllers\CatalogRuleController@update')->defaults('_config', [
- 'redirect' => 'admin.catalog-rule.index'
- ])->name('admin.catalog-rule.update');
+ Route::post('cart-rules/edit/{id}', 'Webkul\CartRule\Http\Controllers\CartRuleController@update')->defaults('_config', [
+ 'redirect' => 'admin.cart-rules.index'
+ ])->name('admin.cart-rules.update');
- Route::get('/catalog-rules/apply', 'Webkul\Discount\Http\Controllers\CatalogRuleController@applyRules')->defaults('_config', [
- 'view' => 'admin::promotions.catalog-rule.index'
- ])->name('admin.catalog-rule.apply');
+ Route::post('cart-rules/delete/{id}', 'Webkul\CartRule\Http\Controllers\CartRuleController@destroy')->name('admin.cart-rules.delete');
- Route::post('/catalog-rules/delete/{id}', 'Webkul\Discount\Http\Controllers\CatalogRuleController@destroy')->name('admin.catalog-rule.delete');
+ Route::post('cart-rules/generate-coupons/{id?}', 'Webkul\CartRule\Http\Controllers\CartRuleController@generateCoupons')->name('admin.cart-rules.generate-coupons');
- Route::get('/catalog-rules/declutter', 'Webkul\Discount\Http\Controllers\CatalogRuleController@deClutter')->defaults('_config', [
- 'redirect' => 'admin.catalog-rule.index'
- ])->name('admin.catalog-rule.declut');
+ Route::post('/massdelete', 'Webkul\CartRule\Http\Controllers\CartRuleCouponController@massDelete')->name('admin.cart-rule-coupons.mass-delete');
- Route::post('fetch/options', 'Webkul\Discount\Http\Controllers\CatalogRuleController@fetchAttributeOptions')->name('admin.catalog-rule.options');
- Route::get('cart-rules', 'Webkul\Discount\Http\Controllers\CartRuleController@index')->defaults('_config', [
- 'view' => 'admin::promotions.cart-rule.index'
- ])->name('admin.cart-rule.index');
+ //Catalog rules
+ Route::get('catalog-rules', 'Webkul\CatalogRule\Http\Controllers\CatalogRuleController@index')->defaults('_config', [
+ 'view' => 'admin::promotions.catalog-rules.index'
+ ])->name('admin.catalog-rules.index');
- Route::get('cart-rules/create', 'Webkul\Discount\Http\Controllers\CartRuleController@create')->defaults('_config', [
- 'view' => 'admin::promotions.cart-rule.create'
- ])->name('admin.cart-rule.create');
+ Route::get('catalog-rules/create', 'Webkul\CatalogRule\Http\Controllers\CatalogRuleController@create')->defaults('_config', [
+ 'view' => 'admin::promotions.catalog-rules.create'
+ ])->name('admin.catalog-rules.create');
- Route::post('cart-rules/store', 'Webkul\Discount\Http\Controllers\CartRuleController@store')->defaults('_config', [
- 'redirect' => 'admin.cart-rule.index'
- ])->name('admin.cart-rule.store');
+ Route::post('catalog-rules/create', 'Webkul\CatalogRule\Http\Controllers\CatalogRuleController@store')->defaults('_config', [
+ 'redirect' => 'admin.catalog-rules.index'
+ ])->name('admin.catalog-rules.store');
- Route::get('cart-rules/edit/{id}', 'Webkul\Discount\Http\Controllers\CartRuleController@edit')->defaults('_config', [
- 'view' => 'admin::promotions.cart-rule.edit'
- ])->name('admin.cart-rule.edit');
+ Route::get('catalog-rules/edit/{id}', 'Webkul\CatalogRule\Http\Controllers\CatalogRuleController@edit')->defaults('_config', [
+ 'view' => 'admin::promotions.catalog-rules.edit'
+ ])->name('admin.catalog-rules.edit');
- Route::post('cart-rules/update/{id}', 'Webkul\Discount\Http\Controllers\CartRuleController@update')->defaults('_config', [
- 'redirect' => 'admin.cart-rule.index'
- ])->name('admin.cart-rule.update');
+ Route::post('catalog-rules/edit/{id}', 'Webkul\CatalogRule\Http\Controllers\CatalogRuleController@update')->defaults('_config', [
+ 'redirect' => 'admin.catalog-rules.index'
+ ])->name('admin.catalog-rules.update');
- Route::post('cart-rules/delete/{id}', 'Webkul\Discount\Http\Controllers\CartRuleController@destroy')->name('admin.cart-rule.delete');
+ Route::post('catalog-rules/delete/{id}', 'Webkul\CatalogRule\Http\Controllers\CatalogRuleController@destroy')->name('admin.catalog-rules.delete');
});
Route::prefix('cms')->group(function () {
diff --git a/packages/Webkul/Admin/src/Resources/assets/sass/partials/_configuration.scss b/packages/Webkul/Admin/src/Resources/assets/sass/partials/_configuration.scss
index 2e2b3258d..c66e1bda9 100644
--- a/packages/Webkul/Admin/src/Resources/assets/sass/partials/_configuration.scss
+++ b/packages/Webkul/Admin/src/Resources/assets/sass/partials/_configuration.scss
@@ -48,4 +48,29 @@
border-bottom: 1px solid #e8e8e8;
cursor: pointer;
}
+}
+
+.cart-rule-conditions,
+.catalog-rule-conditions {
+ table {
+ td {
+ &.attribute {
+ width: 250px;
+ padding-left: 0;
+ }
+
+ &.operator,
+ &.value {
+ width: 260px;
+ }
+
+ &.actions {
+ width: 44px;
+
+ .icon {
+ margin-top: 6px;
+ }
+ }
+ }
+ }
}
\ No newline at end of file
diff --git a/packages/Webkul/Admin/src/Resources/lang/ar/app.php b/packages/Webkul/Admin/src/Resources/lang/ar/app.php
index 12f184e84..2f7acfa1d 100644
--- a/packages/Webkul/Admin/src/Resources/lang/ar/app.php
+++ b/packages/Webkul/Admin/src/Resources/lang/ar/app.php
@@ -852,7 +852,7 @@ return [
],
'footer' => [
- 'copy-right' => '© Copyright 2018 Webkul Software, All rights reserved.'
+ 'copy-right' => ' مدعوم من Bagisto ، مشروع مجتمع بواسطة Webkul '
],
'admin' => [
diff --git a/packages/Webkul/Admin/src/Resources/lang/en/app.php b/packages/Webkul/Admin/src/Resources/lang/en/app.php
index 6ddbe5966..5d0b7d911 100755
--- a/packages/Webkul/Admin/src/Resources/lang/en/app.php
+++ b/packages/Webkul/Admin/src/Resources/lang/en/app.php
@@ -73,7 +73,7 @@ return [
'taxes' => 'Taxes',
'tax-categories' => 'Tax Categories',
'tax-rates' => 'Tax Rates',
- 'promotion' => 'Promotions',
+ 'promotions' => 'Promotions',
'discount' => 'Discount',
'cms' => 'CMS'
],
@@ -110,7 +110,8 @@ return [
'create' => 'Add',
'delete' => 'Delete',
'promotions' => 'Promotions',
- 'cart-rules' => 'Cart Rules'
+ 'cart-rules' => 'Cart Rules',
+ 'catalog-rules' => 'Catalog Rules',
],
'dashboard' => [
@@ -203,7 +204,16 @@ return [
'for-guest' => 'For Guest',
'order_number' => 'Order Number',
'refund-date' => 'Refund Date',
- 'refunded' => 'Refunded'
+ 'refunded' => 'Refunded',
+ 'start' => 'Start',
+ 'end' => 'End',
+ 'active' => 'Active',
+ 'inactive' => 'Inactive',
+ 'coupon-code' => 'Coupon Code',
+ 'times-used' => 'Times Used',
+ 'created-date' => 'Created Date',
+ 'expiration-date' => 'Expiration Date',
+ 'delete' => 'Delete'
],
'account' => [
@@ -944,125 +954,138 @@ return [
]
],
- 'promotion' => [
- 'information' => 'Information',
- 'conditions' => 'Conditions',
- 'actions' => 'Actions',
- 'coupons' => 'Coupons',
- 'zero-unlimited' => 'Zero denotes unlimited usage here',
- 'catalog-rule' => 'Catalog Rules',
- 'cart-rule' => 'Cart Rules',
- 'add-catalog-rule' => 'Add 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' => 'Save',
- 'save' => 'Save',
- 'select-cart-attr' => 'Select Cart Attribute',
- 'select-products' => 'How to choose products ?',
- 'select-category' => 'Select by Categories',
- 'select-attribute' => 'Select by Attributes',
- 'cannot-activate-catalog-rule' => 'Cannot activate catalog rule',
- 'catalog-rule-already-activated' => 'Catalog rule is already activated',
- 'catalog-rule-activated' => 'Catalog rule is activated',
- 'select-attribute' => 'Select :attribute',
- 'enter-attribute' => 'Enter :attribute',
- 'add-condition' => 'Add Condition',
- 'cart-properties' => 'Cart Properties',
- 'yes' => 'Yes',
- 'no' => 'No',
- 'note' => 'Note',
- 'apply' => 'Apply',
- 'rule-name' => 'Enter Rule Name',
- 'rule-desc' => 'Enter Rule Description',
- 'convert-x-note' => 'If this section is left empty, then rule will get applied to all the products in the cart.',
- 'declut' => 'Declutter',
- 'processing-done' => 'Rules processing done',
- 'declut-success' => 'Catalog rules decluttering successful',
- 'declut-failure' => 'Catalog rules decluttering failed',
- 'add-attr-condition' => 'Add Attribute Condition',
- 'general-info' => [
- 'sku-like' => 'SKU Like',
- 'on-shipping' => 'If applied on shipping',
- 'discount' => 'Discount',
- 'shipping-apply-info' => 'It signifies how rule behaves when it is used for shipping',
- 'general-info' => 'General Info',
- 'options' => 'Options',
- 'name' => 'Rule Name',
- 'description' => 'Description',
- 'starts-from' => 'Start',
- 'ends-till' => 'End',
- 'channels' => 'Channels',
- 'channels-req' => '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',
- 'apply' => 'Apply',
- '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',
- 'test-mode' => 'Choose how to test conditions',
- 'labels' => 'Labels',
- 'prefix' => 'Prefix',
- 'suffix' => 'Suffix',
- 'code' => 'Code',
- 'global-label' => 'Global Label',
- 'label' => 'Label'
- ],
-
- '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' => 'Success! 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',
- 'duplicate-coupon' => 'Coupon already exists, please try again with a different coupon'
- ],
-
- 'catalog' => [
+ 'promotions' => [
+ 'cart-rules' => [
+ 'title' => 'Cart Rules',
+ 'add-title' => 'Add Cart Rule',
+ 'edit-title' => 'Edit Cart Rule',
+ 'save-btn-title' => 'Save Cart Rule',
+ 'rule-information' => 'Rule Information',
'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'
+ 'status' => 'Status',
+ 'is-active' => 'Cart Rule is Active',
+ 'channels' => 'Channels',
+ 'customer-groups' => 'Customer Groups',
+ 'coupon-type' => 'Coupon Type',
+ 'no-coupon' => 'No Coupon',
+ 'specific-coupon' => 'Specific Coupon',
+ 'auto-generate-coupon' => 'Auto Generate Coupon',
+ 'no' => 'No',
+ 'yes' => 'Yes',
+ 'coupon-code' => 'Coupon Code',
+ 'uses-per-coupon' => 'Uses Per Coupon',
+ 'uses-per-customer' => 'Uses Per Customer',
+ 'uses-per-customer-control-info' => 'Will be used for logged in customers only.',
+ 'from' => 'From',
+ 'to' => 'To',
+ 'priority' => 'Priority',
+ 'conditions' => 'Conditions',
+ 'condition-type' => 'Condition Type',
+ 'all-conditions-true' => 'All Conditions are True',
+ 'any-condition-true' => 'Any Condition is True',
+ 'add-condition' => 'Add Condition',
+ 'choose-condition-to-add' => 'Choose a condition to add',
+ 'cart-attribute' => 'Cart Attribute',
+ 'subtotal' => 'Subtotal',
+ 'total-items-qty' => 'Total Items Qty',
+ 'total-weight' => 'Total Weight',
+ 'payment-method' => 'Payment Method',
+ 'shipping-method' => 'Shipping Method',
+ 'shipping-postcode' => 'Shipping Zip/Postcode',
+ 'shipping-state' => 'Shipping State',
+ 'shipping-country' => 'Shipping Country',
+ 'cart-item-attribute' => 'Cart Item Attribute',
+ 'price-in-cart' => 'Price in Cart',
+ 'qty-in-cart' => 'Qty in Cart',
+ 'product-attribute' => 'Product Attribute',
+ 'attribute-name-children-only' => ':attribute_name (Children Only)',
+ 'attribute-name-parent-only' => ':attribute_name (Parent Only)',
+ 'is-equal-to' => 'Is equal to',
+ 'is-not-equal-to' => 'Is not equal to',
+ 'equals-or-greater-than' => 'Equals or greater than',
+ 'equals-or-less-than' => 'Equals or less than',
+ 'greater-than' => 'Greater than',
+ 'less-than' => 'Less than',
+ 'contain' => 'Contain',
+ 'contains' => 'Contains',
+ 'does-not-contain' => 'Does not contain',
+ 'actions' => 'Actions',
+ 'action-type' => 'Action Type',
+ 'percentage-product-price' => 'Percentage of Product Price',
+ 'fixed-amount' => 'Fixed Amount',
+ 'fixed-amount-whole-cart' => 'Fixed Amount to Whole Cart',
+ 'buy-x-get-y-free' => 'Buy X Get Y Free',
+ 'discount-amount' => 'Discount Amount',
+ 'discount-quantity' => 'Maximum Quantity Allowed to be Discounted',
+ 'discount-step' => 'Buy X Quantity',
+ 'free-shipping' => 'Free Shipping',
+ 'apply-to-shipping' => 'Apply to Shipping',
+ 'coupon-codes' => 'Coupon Codes',
+ 'coupon-qty' => 'Coupon Qty',
+ 'code-length' => 'Code Length',
+ 'code-format' => 'Code Format',
+ 'alphanumeric' => 'Alphanumeric',
+ 'alphabetical' => 'Alphabetical',
+ 'numeric' => 'Numeric',
+ 'code-prefix' => 'Code Prefix',
+ 'code-suffix' => 'Code Suffix',
+ 'generate' => 'Generate',
+ 'cart-rule-not-defind-error' => 'Cart rule is not defined',
+ 'mass-delete-success' => 'All the selected index of coupons have been deleted successfully.',
+ 'end-other-rules' => 'End Other Rules',
+ 'children-categories' => 'Categories (Children Only)',
+ 'parent-categories' => 'Categories (Parent Only)',
+ 'categories' => 'Categories',
+ 'attribute_family' => 'Attribute Family'
],
- 'cart' => [
- 'buy-atleast' => 'Buy Atleast',
- 'apply-to-shipping' => 'Apply to shipping'
+ 'catalog-rules' => [
+ 'title' => 'Catalog Rules',
+ 'add-title' => 'Add Catalog Rule',
+ 'edit-title' => 'Edit Catalog Rule',
+ 'save-btn-title' => 'Save Catalog Rule',
+ 'rule-information' => 'Rule Information',
+ 'name' => 'Name',
+ 'description' => 'Description',
+ 'status' => 'Status',
+ 'is-active' => 'Catalog Rule is Active',
+ 'channels' => 'Channels',
+ 'customer-groups' => 'Customer Groups',
+ 'no' => 'No',
+ 'yes' => 'Yes',
+ 'from' => 'From',
+ 'to' => 'To',
+ 'priority' => 'Priority',
+ 'conditions' => 'Conditions',
+ 'condition-type' => 'Condition Type',
+ 'all-conditions-true' => 'All Conditions are True',
+ 'any-condition-true' => 'Any Condition is True',
+ 'add-condition' => 'Add Condition',
+ 'choose-condition-to-add' => 'Choose a condition to add',
+ 'product-attribute' => 'Product Attribute',
+ 'attribute-name-children-only' => ':attribute_name (Children Only)',
+ 'attribute-name-parent-only' => ':attribute_name (Parent Only)',
+ 'is-equal-to' => 'Is equal to',
+ 'is-not-equal-to' => 'Is not equal to',
+ 'equals-or-greater-than' => 'Equals or greater than',
+ 'equals-or-less-than' => 'Equals or less than',
+ 'greater-than' => 'Greater than',
+ 'less-than' => 'Less than',
+ 'contain' => 'Contain',
+ 'contains' => 'Contains',
+ 'does-not-contain' => 'Does not contain',
+ 'actions' => 'Actions',
+ 'action-type' => 'Action Type',
+ 'percentage-product-price' => 'Percentage of Product Price',
+ 'fixed-amount' => 'Fixed Amount',
+ 'fixed-amount-whole-cart' => 'Fixed Amount to Whole Catalog',
+ 'buy-x-get-y-free' => 'Buy X Get Y Free',
+ 'discount-amount' => 'Discount Amount',
+ 'mass-delete-success' => 'All the selected index of coupons have been deleted successfully.',
+ 'end-other-rules' => 'End Other Rules',
+ 'categories' => 'Categories',
+ 'attribute_family' => 'Attribute Family'
]
],
@@ -1172,7 +1195,7 @@ return [
],
'footer' => [
- 'copy-right' => '© Copyright 2018 Webkul Software, All rights reserved.'
+ 'copy-right' => 'Powered by Bagisto , A Community Project by Webkul ',
],
'admin' => [
diff --git a/packages/Webkul/Admin/src/Resources/lang/fa/app.php b/packages/Webkul/Admin/src/Resources/lang/fa/app.php
index ad5d4ca54..7c8d247f6 100644
--- a/packages/Webkul/Admin/src/Resources/lang/fa/app.php
+++ b/packages/Webkul/Admin/src/Resources/lang/fa/app.php
@@ -998,7 +998,7 @@ return [
],
'footer' => [
- 'copy-right' => '© کپی رایت 2019 کلیه حقوق محفوظ است.'
+ 'copy-right' => 'طراحی شده توسط Bagisto ، یک پروژه عمومی توسط Webkul '
],
'admin' => [
diff --git a/packages/Webkul/Admin/src/Resources/lang/pt_BR/app.php b/packages/Webkul/Admin/src/Resources/lang/pt_BR/app.php
index 3aeb94034..1c8a5d7d2 100755
--- a/packages/Webkul/Admin/src/Resources/lang/pt_BR/app.php
+++ b/packages/Webkul/Admin/src/Resources/lang/pt_BR/app.php
@@ -976,7 +976,7 @@ return [
],
'footer' => [
- 'copy-right' => '© Copyright '.date('Y').' Webkul Software, Todos os direitos reservados.'
+ 'copy-right' => 'Desenvolvido por Bagisto , um projeto comunitário da Webkul '
],
'admin' => [
diff --git a/packages/Webkul/Admin/src/Resources/views/layouts/anonymous-master.blade.php b/packages/Webkul/Admin/src/Resources/views/layouts/anonymous-master.blade.php
index 1dcca7d44..0357d8f43 100755
--- a/packages/Webkul/Admin/src/Resources/views/layouts/anonymous-master.blade.php
+++ b/packages/Webkul/Admin/src/Resources/views/layouts/anonymous-master.blade.php
@@ -96,7 +96,7 @@
@if (core()->getConfigData('general.content.footer.footer_content'))
{{ core()->getConfigData('general.content.footer.footer_content') }}
@else
- {{ trans('admin::app.footer.copy-right') }}
+ {!! trans('admin::app.footer.copy-right') !!}
@endif
diff --git a/packages/Webkul/Admin/src/Resources/views/promotions/cart-rule/create.blade.php b/packages/Webkul/Admin/src/Resources/views/promotions/cart-rule/create.blade.php
deleted file mode 100644
index 857b36306..000000000
--- a/packages/Webkul/Admin/src/Resources/views/promotions/cart-rule/create.blade.php
+++ /dev/null
@@ -1,630 +0,0 @@
-@extends('admin::layouts.content')
-
-@section('page_title')
- {{ __('admin::app.promotion.add-cart-rule') }}
-@stop
-
-@section('content')
-
-
diff --git a/packages/Webkul/Admin/src/Resources/views/promotions/catalog-rule/create.blade.php b/packages/Webkul/Admin/src/Resources/views/promotions/catalog-rule/create.blade.php
deleted file mode 100644
index ca386c453..000000000
--- a/packages/Webkul/Admin/src/Resources/views/promotions/catalog-rule/create.blade.php
+++ /dev/null
@@ -1,415 +0,0 @@
-@extends('admin::layouts.content')
-
-@section('page_title')
- {{ __('admin::app.promotion.add-catalog-rule') }}
-@stop
-
-@section('content')
-
-
-
-
- @push('scripts')
-
-
-
- @endpush
-@stop
\ No newline at end of file
diff --git a/packages/Webkul/Admin/src/Resources/views/promotions/catalog-rule/edit.blade.php b/packages/Webkul/Admin/src/Resources/views/promotions/catalog-rule/edit.blade.php
deleted file mode 100644
index f7b68da7b..000000000
--- a/packages/Webkul/Admin/src/Resources/views/promotions/catalog-rule/edit.blade.php
+++ /dev/null
@@ -1,414 +0,0 @@
-@extends('admin::layouts.content')
-
-@section('page_title')
- {{ __('admin::app.promotion.edit-catalog-rule') }}
-@stop
-
-@section('content')
-
-
-
-
- @push('scripts')
-
-
-
- @endpush
-@stop
\ No newline at end of file
diff --git a/packages/Webkul/Admin/src/Resources/views/promotions/catalog-rule/index.blade.php b/packages/Webkul/Admin/src/Resources/views/promotions/catalog-rule/index.blade.php
deleted file mode 100644
index 6790810ea..000000000
--- a/packages/Webkul/Admin/src/Resources/views/promotions/catalog-rule/index.blade.php
+++ /dev/null
@@ -1,35 +0,0 @@
-@extends('admin::layouts.content')
-
-@section('page_title')
- {{ __('admin::app.promotion.catalog-rule') }}
-@stop
-
-@section('content')
-
-
-
-
-
- @inject('catalogRuleGrid','Webkul\Admin\DataGrids\CatalogRuleDataGrid')
- {!! $catalogRuleGrid->render() !!}
-
-
-@endsection
\ No newline at end of file
diff --git a/packages/Webkul/Admin/src/Resources/views/promotions/catalog-rules/create.blade.php b/packages/Webkul/Admin/src/Resources/views/promotions/catalog-rules/create.blade.php
new file mode 100644
index 000000000..30745564b
--- /dev/null
+++ b/packages/Webkul/Admin/src/Resources/views/promotions/catalog-rules/create.blade.php
@@ -0,0 +1,528 @@
+@extends('admin::layouts.content')
+
+@section('page_title')
+ {{ __('admin::app.promotions.catalog-rules.add-title') }}
+@stop
+
+@section('content')
+
+
+
+
+
+@stop
+
+@push('scripts')
+ @parent
+
+
+
+
+
+
+@endpush
\ No newline at end of file
diff --git a/packages/Webkul/Admin/src/Resources/views/promotions/catalog-rules/edit.blade.php b/packages/Webkul/Admin/src/Resources/views/promotions/catalog-rules/edit.blade.php
new file mode 100644
index 000000000..d1a6aed4a
--- /dev/null
+++ b/packages/Webkul/Admin/src/Resources/views/promotions/catalog-rules/edit.blade.php
@@ -0,0 +1,533 @@
+@extends('admin::layouts.content')
+
+@section('page_title')
+ {{ __('admin::app.promotions.catalog-rules.edit-title') }}
+@stop
+
+@section('content')
+
+
+
+
+
+@stop
+
+@push('scripts')
+ @parent
+
+
+
+
+
+
+@endpush
\ No newline at end of file
diff --git a/packages/Webkul/Admin/src/Resources/views/promotions/catalog-rules/index.blade.php b/packages/Webkul/Admin/src/Resources/views/promotions/catalog-rules/index.blade.php
new file mode 100644
index 000000000..0139be19f
--- /dev/null
+++ b/packages/Webkul/Admin/src/Resources/views/promotions/catalog-rules/index.blade.php
@@ -0,0 +1,27 @@
+@extends('admin::layouts.content')
+
+@section('page_title')
+ {{ __('admin::app.promotions.catalog-rules.title') }}
+@stop
+
+@section('content')
+
+
+
+
+
+ @inject('catalogRuleGrid','Webkul\Admin\DataGrids\CatalogRuleDataGrid')
+ {!! $catalogRuleGrid->render() !!}
+
+
+@endsection
\ No newline at end of file
diff --git a/packages/Webkul/Admin/src/Resources/views/sales/orders/view.blade.php b/packages/Webkul/Admin/src/Resources/views/sales/orders/view.blade.php
index c635af49e..a1b28cbd0 100755
--- a/packages/Webkul/Admin/src/Resources/views/sales/orders/view.blade.php
+++ b/packages/Webkul/Admin/src/Resources/views/sales/orders/view.blade.php
@@ -332,7 +332,13 @@
@if ($order->base_discount_amount > 0)
- {{ __('admin::app.sales.orders.discount') }}
+
+ {{ __('admin::app.sales.orders.discount') }}
+
+ @if ($order->coupon_code)
+ ({{ $order->coupon_code }})
+ @endif
+
-
{{ core()->formatBasePrice($order->base_discount_amount) }}
diff --git a/packages/Webkul/CartRule/src/Contracts/CartRule.php b/packages/Webkul/CartRule/src/Contracts/CartRule.php
new file mode 100644
index 000000000..bbc60e2e2
--- /dev/null
+++ b/packages/Webkul/CartRule/src/Contracts/CartRule.php
@@ -0,0 +1,7 @@
+increments('id');
$table->string('name')->nullable();
$table->string('description')->nullable();
- $table->datetime('starts_from')->nullable();
- $table->datetime('ends_till')->nullable();
+ $table->date('starts_from')->nullable();
+ $table->date('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(1);
- $table->string('disc_threshold')->default(1);
$table->integer('coupon_type')->default(1);
- $table->boolean('auto_generation')->default(0);
+ $table->boolean('use_auto_generation')->default(0);
+ $table->integer('usage_per_customer')->default(0);
+ $table->integer('uses_per_coupon')->default(0);
+ $table->integer('times_used')->unsigned()->default(0);
+ $table->boolean('condition_type')->default(1);
+ $table->json('conditions')->nullable();
+ $table->boolean('end_other_rules')->default(0);
+ $table->boolean('uses_attribute_conditions')->default(0);
+ $table->string('action_type')->nullable();
+ $table->decimal('discount_amount', 12, 4)->default(0);
+ $table->integer('discount_quantity')->default(1);
+ $table->string('discount_step')->default(1);
$table->boolean('apply_to_shipping')->default(0);
$table->boolean('free_shipping')->default(0);
+ $table->integer('sort_order')->unsigned()->default(0);
$table->timestamps();
});
}
diff --git a/packages/Webkul/Discount/src/Database/Migrations/2019_05_13_024340_create_cart_rule_channels_table.php b/packages/Webkul/CartRule/src/Database/Migrations/2019_05_13_024322_create_cart_rule_channels_table.php
similarity index 91%
rename from packages/Webkul/Discount/src/Database/Migrations/2019_05_13_024340_create_cart_rule_channels_table.php
rename to packages/Webkul/CartRule/src/Database/Migrations/2019_05_13_024322_create_cart_rule_channels_table.php
index 3808c6545..067a452fa 100644
--- a/packages/Webkul/Discount/src/Database/Migrations/2019_05_13_024340_create_cart_rule_channels_table.php
+++ b/packages/Webkul/CartRule/src/Database/Migrations/2019_05_13_024322_create_cart_rule_channels_table.php
@@ -14,12 +14,13 @@ class CreateCartRuleChannelsTable extends Migration
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->primary(['cart_rule_id', 'channel_id']);
+
+ $table->foreign('cart_rule_id')->references('id')->on('cart_rules')->onDelete('cascade');
$table->foreign('channel_id')->references('id')->on('channels')->onDelete('cascade');
- $table->timestamps();
});
}
diff --git a/packages/Webkul/Discount/src/Database/Migrations/2019_05_13_024419_create_cart_rule_customer_groups_table.php b/packages/Webkul/CartRule/src/Database/Migrations/2019_05_13_024323_create_cart_rule_customer_groups_table.php
similarity index 90%
rename from packages/Webkul/Discount/src/Database/Migrations/2019_05_13_024419_create_cart_rule_customer_groups_table.php
rename to packages/Webkul/CartRule/src/Database/Migrations/2019_05_13_024323_create_cart_rule_customer_groups_table.php
index 4396b999a..312237d98 100644
--- a/packages/Webkul/Discount/src/Database/Migrations/2019_05_13_024419_create_cart_rule_customer_groups_table.php
+++ b/packages/Webkul/CartRule/src/Database/Migrations/2019_05_13_024323_create_cart_rule_customer_groups_table.php
@@ -14,12 +14,14 @@ class CreateCartRuleCustomerGroupsTable extends Migration
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->primary(['cart_rule_id', 'customer_group_id']);
+
+ $table->foreign('cart_rule_id')->references('id')->on('cart_rules')->onDelete('cascade');
$table->foreign('customer_group_id')->references('id')->on('customer_groups')->onDelete('cascade');
- $table->timestamps();
});
}
diff --git a/packages/Webkul/Discount/src/Database/Migrations/2019_05_30_141207_create_cart_rule_cart_table.php b/packages/Webkul/CartRule/src/Database/Migrations/2019_05_13_024324_create_cart_rule_translations_table.php
similarity index 54%
rename from packages/Webkul/Discount/src/Database/Migrations/2019_05_30_141207_create_cart_rule_cart_table.php
rename to packages/Webkul/CartRule/src/Database/Migrations/2019_05_13_024324_create_cart_rule_translations_table.php
index 82c7505a0..9c71333d7 100644
--- a/packages/Webkul/Discount/src/Database/Migrations/2019_05_30_141207_create_cart_rule_cart_table.php
+++ b/packages/Webkul/CartRule/src/Database/Migrations/2019_05_13_024324_create_cart_rule_translations_table.php
@@ -4,7 +4,7 @@ use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
-class CreateCartRuleCartTable extends Migration
+class CreateCartRuleTranslationsTable extends Migration
{
/**
* Run the migrations.
@@ -13,13 +13,13 @@ class CreateCartRuleCartTable extends Migration
*/
public function up()
{
- Schema::create('cart_rule_cart', function (Blueprint $table) {
+ Schema::create('cart_rule_translations', function (Blueprint $table) {
$table->increments('id');
- $table->integer('cart_rule_id')->unsigned()->nullable();
+ $table->string('locale');
+ $table->text('label')->nullable();
+ $table->integer('cart_rule_id')->unsigned();
+ $table->unique(['cart_rule_id', 'locale']);
$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();
});
}
@@ -30,6 +30,6 @@ class CreateCartRuleCartTable extends Migration
*/
public function down()
{
- Schema::dropIfExists('cart_rule_cart');
+ Schema::dropIfExists('cart_rule_translations');
}
}
diff --git a/packages/Webkul/Discount/src/Database/Migrations/2019_05_23_175727_create_cart_rule_customers_table.php b/packages/Webkul/CartRule/src/Database/Migrations/2019_05_13_024325_create_cart_rule_customers_table.php
similarity index 84%
rename from packages/Webkul/Discount/src/Database/Migrations/2019_05_23_175727_create_cart_rule_customers_table.php
rename to packages/Webkul/CartRule/src/Database/Migrations/2019_05_13_024325_create_cart_rule_customers_table.php
index fbe323ab1..a16452c6f 100644
--- a/packages/Webkul/Discount/src/Database/Migrations/2019_05_23_175727_create_cart_rule_customers_table.php
+++ b/packages/Webkul/CartRule/src/Database/Migrations/2019_05_13_024325_create_cart_rule_customers_table.php
@@ -15,12 +15,13 @@ class CreateCartruleCustomersTable extends Migration
{
Schema::create('cart_rule_customers', function (Blueprint $table) {
$table->increments('id');
+ $table->bigInteger('times_used')->unsigned()->default(0);
+
$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();
});
}
@@ -31,6 +32,6 @@ class CreateCartruleCustomersTable extends Migration
*/
public function down()
{
- Schema::dropIfExists('cart_rule_customers');
+ Schema::dropIfExists('cartrule_customers');
}
}
diff --git a/packages/Webkul/Discount/src/Database/Migrations/2019_05_23_180457_create_cart_rule_coupons_table.php b/packages/Webkul/CartRule/src/Database/Migrations/2019_05_13_024326_create_cart_rule_coupons_table.php
similarity index 80%
rename from packages/Webkul/Discount/src/Database/Migrations/2019_05_23_180457_create_cart_rule_coupons_table.php
rename to packages/Webkul/CartRule/src/Database/Migrations/2019_05_13_024326_create_cart_rule_coupons_table.php
index 67eea0030..89741800e 100644
--- a/packages/Webkul/Discount/src/Database/Migrations/2019_05_23_180457_create_cart_rule_coupons_table.php
+++ b/packages/Webkul/CartRule/src/Database/Migrations/2019_05_13_024326_create_cart_rule_coupons_table.php
@@ -15,15 +15,16 @@ class CreateCartruleCouponsTable extends Migration
{
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('times_used')->unsigned()->default(0);
$table->integer('type')->unsigned()->default(0);
+ $table->boolean('is_primary')->default(0);
+ $table->date('expired_at')->nullable();
+
+ $table->integer('cart_rule_id')->unsigned();
+ $table->foreign('cart_rule_id')->references('id')->on('cart_rules')->onDelete('cascade');
$table->timestamps();
});
}
@@ -35,6 +36,6 @@ class CreateCartruleCouponsTable extends Migration
*/
public function down()
{
- Schema::dropIfExists('cart_rule_coupons');
+ Schema::dropIfExists('cartrule_coupons');
}
}
diff --git a/packages/Webkul/CartRule/src/Database/Migrations/2019_05_13_024327_create_cart_rule_coupon_usage_table.php b/packages/Webkul/CartRule/src/Database/Migrations/2019_05_13_024327_create_cart_rule_coupon_usage_table.php
new file mode 100644
index 000000000..ae0339b0a
--- /dev/null
+++ b/packages/Webkul/CartRule/src/Database/Migrations/2019_05_13_024327_create_cart_rule_coupon_usage_table.php
@@ -0,0 +1,37 @@
+increments('id');
+ $table->integer('times_used')->default(0);
+
+ $table->integer('cart_rule_coupon_id')->unsigned();
+ $table->foreign('cart_rule_coupon_id')->references('id')->on('cart_rule_coupons')->onDelete('cascade');
+
+ $table->integer('customer_id')->unsigned();
+ $table->foreign('customer_id')->references('id')->on('customers')->onDelete('cascade');
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ *
+ * @return void
+ */
+ public function down()
+ {
+ Schema::dropIfExists('cart_rule_coupon_usage');
+ }
+}
diff --git a/packages/Webkul/CartRule/src/Helpers/CartRule.php b/packages/Webkul/CartRule/src/Helpers/CartRule.php
new file mode 100644
index 000000000..8ad0c4dac
--- /dev/null
+++ b/packages/Webkul/CartRule/src/Helpers/CartRule.php
@@ -0,0 +1,523 @@
+cartRuleRepository = $cartRuleRepository;
+
+ $this->cartRuleCouponRepository = $cartRuleCouponRepository;
+
+ $this->cartRuleCouponUsageRepository = $cartRuleCouponUsageRepository;
+
+ $this->cartRuleCustomerRepository = $cartRuleCustomerRepository;
+
+ $this->customerGroupRepository = $customerGroupRepository;
+
+ $this->validator = $validator;
+ }
+
+ /**
+ * Collect discount on cart
+ *
+ * @return void
+ */
+ public function collect()
+ {
+ $cart = Cart::getCart();
+
+ $this->calculateCartItemTotals($cart->items()->get());
+
+ foreach ($cart->items()->get() as $item) {
+ $this->process($item);
+
+ if ($item->children()->count() && $item->product->getTypeInstance()->isChildrenCalculated())
+ $this->devideDiscount($item);
+ }
+
+ $this->processShippingDiscount($cart);
+
+ $this->processFreeShippingDiscount($cart);
+
+ $this->validateCouponCode();
+ }
+
+ /**
+ * Returns cart rules
+ *
+ * @return Collection
+ */
+ public function getCartRules()
+ {
+ static $cartRules;
+
+ if ($cartRules)
+ return $cartRules;
+
+ $customerGroupId = null;
+
+ if (Cart::getCurrentCustomer()->check()) {
+ $customerGroupId = Cart::getCurrentCustomer()->user()->customer_group_id;
+ } else {
+ if ($customerGuestGroup = $this->customerGroupRepository->findOneByField('code', 'guest'))
+ $customerGroupId = $customerGuestGroup->id;
+ }
+
+ $cartRules = $this->cartRuleRepository->scopeQuery(function($query) use ($customerGroupId) {
+ return $query->leftJoin('cart_rule_customer_groups', 'cart_rules.id', '=', 'cart_rule_customer_groups.cart_rule_id')
+ ->leftJoin('cart_rule_channels', 'cart_rules.id', '=', 'cart_rule_channels.cart_rule_id')
+ ->where('cart_rule_customer_groups.customer_group_id', $customerGroupId)
+ ->where('cart_rule_channels.channel_id', core()->getCurrentChannel()->id)
+ ->where(function ($query1) {
+ $query1->where('cart_rules.starts_from', '<=', Carbon::now()->format('Y-m-d'))->orWhereNull('cart_rules.starts_from');
+ })
+ ->where(function ($query2) {
+ $query2->where('cart_rules.ends_till', '>=', Carbon::now()->format('Y-m-d'))->orWhereNull('cart_rules.ends_till');
+ })
+ ->orderBy('sort_order', 'asc');
+ })->findWhere(['status' => 1]);
+
+ return $cartRules;
+ }
+
+ /**
+ * Check if cart rule can be applied
+ *
+ * @param CartRule $rule
+ * @return boolean
+ */
+ public function canProcessRule($rule)
+ {
+ $cart = Cart::getCart();
+
+ if ($rule->coupon_type) {
+ if (strlen($cart->coupon_code)) {
+ $coupon = $this->cartRuleCouponRepository->findOneWhere([
+ 'cart_rule_id' => $rule->id,
+ 'code' => $cart->coupon_code,
+ ]);
+
+ if ($coupon) {
+ if ($coupon->usage_limit && $coupon->times_used >= $coupon->usage_limit)
+ return false;
+
+ if ($cart->customer_id && $coupon->usage_per_customer) {
+ $couponUsage = $this->cartRuleCouponUsageRepository->findOneWhere([
+ 'cart_rule_coupon_id' => $coupon->id,
+ 'customer_id' => $cart->customer_id
+ ]);
+
+ if ($couponUsage && $couponUsage->times_used >= $coupon->usage_per_customer)
+ return false;
+ }
+ } else {
+ return false;
+ }
+ } else {
+ return false;
+ }
+ }
+
+ if ($rule->usage_per_customer) {
+ $ruleCustomer = $this->cartRuleCustomerRepository->findOneWhere([
+ 'cart_rule_id' => $rule->id,
+ 'customer_id' => $cart->customer_id,
+ ]);
+
+ if ($ruleCustomer && $ruleCustomer->times_used >= $rule->usage_per_customer)
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Cart item discount calculation process
+ *
+ * @param CartItem $item
+ * @return void
+ */
+ public function process($item)
+ {
+ $item->discount_percent = 0;
+ $item->discount_amount = 0;
+ $item->base_discount_amount = 0;
+
+ $cart = $item->cart;
+
+ $cart->applied_cart_rule_ids = null;
+
+ $appliedRuleIds = [];
+
+ foreach ($this->getCartRules() as $rule) {
+ if (! $this->canProcessRule($rule))
+ continue;
+
+ if (! $this->validator->validate($rule, $item))
+ continue;
+
+ $quantity = $rule->discount_quantity ? min($item->quantity, $rule->discount_quantity) : $item->quantity;
+
+ $discountAmount = $baseDiscountAmount = 0;
+
+ switch ($rule->action_type) {
+ case 'by_percent':
+ $rulePercent = min(100, $rule->discount_amount);
+
+ $discountAmount = ($quantity * $item->price - $item->discount_amount) * ($rulePercent / 100);
+
+ $baseDiscountAmount = ($quantity * $item->base_price - $item->base_discount_amount) * ($rulePercent / 100);
+
+ if (! $rule->discount_quantity || $rule->discount_quantity > $quantity) {
+ $discountPercent = min(100, $item->discount_percent + $rulePercent);
+
+ $item->discount_percent = $discountPercent;
+ }
+
+ break;
+
+ case 'by_fixed':
+ $discountAmount = $quantity * core()->convertPrice($rule->discount_amount);
+
+ $baseDiscountAmount = $quantity * $rule->discount_amount;
+
+ break;
+
+ case 'cart_fixed':
+ if ($this->itemTotals[$rule->id]['total_items'] <= 1) {
+ $discountAmount = core()->convertPrice($rule->discount_amount);
+
+ $baseDiscountAmount = min($item->base_price * $quantity, $rule->discount_amount);
+ } else {
+ $discountRate = $item->base_price * $quantity / $this->itemTotals[$rule->id]['base_total_price'];
+
+ $maxDiscount = $rule->discount_amount * $discountRate;
+
+ $discountAmount = core()->convertPrice($maxDiscount);
+
+ $baseDiscountAmount = min($item->base_price * $quantity, $maxDiscount);
+ }
+
+ $discountAmount = min($item->price * $quantity, $discountAmount);
+
+ break;
+
+ case 'buy_x_get_y':
+ if (! $rule->discount_step || $rule->discount_amount > $rule->discount_step)
+ break;
+
+ $buyAndDiscountQty = $rule->discount_step + $rule->discount_amount;
+
+ $qtyPeriod = floor($quantity / $buyAndDiscountQty);
+
+ $freeQty = $quantity - $qtyPeriod * $buyAndDiscountQty;
+
+ $discountQty = $qtyPeriod * $rule->discount_amount;
+
+ if ($freeQty > $rule->discount_step)
+ $discountQty += $freeQty - $rule->discount_step;
+
+ $discountAmount = $discountQty * $item->price;
+
+ $baseDiscountAmount = $discountQty * $item->base_price;
+
+ break;
+ }
+
+ $item->discount_amount = min($item->discount_amount + $discountAmount, $item->price * $quantity);
+ $item->base_discount_amount = min($item->base_discount_amount + $baseDiscountAmount, $item->base_price * $quantity);
+
+ $appliedRuleIds[$rule->id] = $rule->id;
+
+ if ($rule->end_other_rules)
+ break;
+ }
+
+ $item->applied_cart_rule_ids = join(',', $appliedRuleIds);
+
+ $item->save();
+
+ $cartAppliedCartRuleIds = array_merge(explode(',', $cart->applied_cart_rule_ids), $appliedRuleIds);
+
+ $cartAppliedCartRuleIds = array_filter($cartAppliedCartRuleIds);
+
+ $cartAppliedCartRuleIds = array_unique($cartAppliedCartRuleIds);
+
+ $cart->applied_cart_rule_ids = join(',', $cartAppliedCartRuleIds);
+
+ $cart->save();
+ }
+
+ /**
+ * Cart shipping discount calculation process
+ *
+ * @param Cart $cart
+ * @return void
+ */
+ public function processShippingDiscount($cart)
+ {
+ if (! $selectedShipping = $cart->selected_shipping_rate)
+ return;
+
+ $selectedShipping->discount_amount = 0;
+ $selectedShipping->base_discount_amount = 0;
+
+ $appliedRuleIds = [];
+
+ foreach ($this->getCartRules() as $rule) {
+ if (! $this->canProcessRule($rule))
+ continue;
+
+ if (! $this->validator->validate($rule, $cart))
+ continue;
+
+ if (! $rule || ! $rule->apply_to_shipping)
+ continue;
+
+ $discountAmount = $baseDiscountAmount = 0;
+
+ switch ($rule->action_type) {
+ case 'by_percent':
+ $rulePercent = min(100, $rule->discount_amount);
+
+ $discountAmount = ($selectedShipping->price - $selectedShipping->discount_amount) * $rulePercent / 100;
+
+ $baseDiscountAmount = ($selectedShipping->base_price - $selectedShipping->base_discount_amount) * $rulePercent / 100;
+
+ break;
+
+ case 'by_fixed':
+ $discountAmount = core()->convertPrice($rule->discount_amount);
+
+ $baseDiscountAmount = $rule->discount_amount;
+
+ break;
+ }
+
+ $selectedShipping->discount_amount = min($selectedShipping->discount_amount + $discountAmount, $selectedShipping->price);
+
+ $selectedShipping->base_discount_amount = min(
+ $selectedShipping->base_discount_amount + $baseDiscountAmount,
+ $selectedShipping->base_price
+ );
+
+ $selectedShipping->save();
+
+ $appliedRuleIds[$rule->id] = $rule->id;
+
+ if ($rule->end_other_rules)
+ break;
+ }
+
+ $selectedShipping->save();
+
+ $cartAppliedCartRuleIds = array_merge(explode(',', $cart->applied_cart_rule_ids), $appliedRuleIds);
+
+ $cartAppliedCartRuleIds = array_filter($cartAppliedCartRuleIds);
+
+ $cartAppliedCartRuleIds = array_unique($cartAppliedCartRuleIds);
+
+ $cart->applied_cart_rule_ids = join(',', $cartAppliedCartRuleIds);
+
+ $cart->save();
+
+ return $this;
+ }
+
+ /**
+ * Cart free shipping discount calculation process
+ *
+ * @param Cart $cart
+ * @return void
+ */
+ public function processFreeShippingDiscount($cart)
+ {
+ if (! $selectedShipping = $cart->selected_shipping_rate)
+ return;
+
+ $selectedShipping->discount_amount = 0;
+
+ $selectedShipping->base_discount_amount = 0;
+
+ $appliedRuleIds = [];
+
+ foreach ($this->getCartRules() as $rule) {
+ if (! $this->canProcessRule($rule))
+ continue;
+
+ if (! $this->validator->validate($rule, $cart))
+ continue;
+
+ if (! $rule || ! $rule->free_shipping)
+ continue;
+
+ $selectedShipping->price = 0;
+
+ $selectedShipping->base_price = 0;
+
+ $selectedShipping->save();
+
+ $appliedRuleIds[$rule->id] = $rule->id;
+
+ if ($rule->end_other_rules)
+ break;
+ }
+
+ $cartAppliedCartRuleIds = array_merge(explode(',', $cart->applied_cart_rule_ids), $appliedRuleIds);
+
+ $cartAppliedCartRuleIds = array_filter($cartAppliedCartRuleIds);
+
+ $cartAppliedCartRuleIds = array_unique($cartAppliedCartRuleIds);
+
+ $cart->applied_cart_rule_ids = join(',', $cartAppliedCartRuleIds);
+
+ $cart->save();
+ }
+
+ /**
+ * Calculate cart item totals for each rule
+ *
+ * @param mixed $items
+ * @return Validator
+ */
+ public function calculateCartItemTotals($items)
+ {
+ foreach ($this->getCartRules() as $rule) {
+ if ($rule->action_type == 'cart_fixed') {
+ $totalPrice = $totalBasePrice = $validCount = 0;
+
+ foreach ($items as $item) {
+ if (! $this->canProcessRule($rule, $item))
+ continue;
+
+ $quantity = $rule->discount_quantity ? min($item->quantity, $rule->discount_quantity) : $item->quantity;
+
+ $totalBasePrice += $item->base_price * $quantity;
+
+ $validCount++;
+ }
+
+ $this->itemTotals[$rule->id] = [
+ 'base_total_price' => $totalBasePrice,
+ 'total_items' => $validCount,
+ ];
+ }
+ }
+ }
+
+ /**
+ * Check if coupon code is valid or not, if not remove from cart
+ *
+ * @return void
+ */
+ public function validateCouponCode()
+ {
+ $cart = Cart::getCart();
+
+ if (! $cart->coupon_code)
+ return;
+
+ $coupon = $this->cartRuleCouponRepository->findOneByField('code', $cart->coupon_code);
+
+ if (! $coupon || ! in_array($coupon->cart_rule_id, explode(',', $cart->applied_cart_rule_ids)))
+ Cart::removeCouponCode();
+ }
+
+ /**
+ * Devide discount amount to children
+ *
+ * @param CartItem $item
+ * @return void
+ */
+ protected function devideDiscount($item)
+ {
+ foreach ($item->children as $child) {
+ $ratio = $item->base_total != 0 ? $child->base_total / $item->base_total : 0;
+
+ foreach (['discount_amount', 'base_discount_amount'] as $column) {
+ if (! $item->{$column})
+ continue;
+
+ $child->{$column} = round(($item->{$column} * $ratio), 4);
+
+ $child->save();
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/packages/Webkul/CartRule/src/Http/Controllers/CartRuleController.php b/packages/Webkul/CartRule/src/Http/Controllers/CartRuleController.php
new file mode 100644
index 000000000..dc90a01b5
--- /dev/null
+++ b/packages/Webkul/CartRule/src/Http/Controllers/CartRuleController.php
@@ -0,0 +1,206 @@
+
+ * @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com)
+ */
+class CartRuleController extends Controller
+{
+ /**
+ * Initialize _config, a default request parameter with route
+ *
+ * @param array
+ */
+ protected $_config;
+
+ /**
+ * To hold Cart repository instance
+ *
+ * @var CartRuleRepository
+ */
+ protected $cartRuleRepository;
+
+ /**
+ * To hold CartRuleCouponRepository repository instance
+ *
+ * @var CartRuleCouponRepository
+ */
+ protected $cartRuleCouponRepository;
+
+ /**
+ * Create a new controller instance.
+ *
+ * @param \Webkul\CartRule\Repositories\CartRuleRepository $cartRuleRepository
+ * @param \Webkul\CartRule\Repositories\CartRuleCouponRepository $cartRuleCouponRepository
+ * @return void
+ */
+ public function __construct(
+ CartRuleRepository $cartRuleRepository,
+ CartRuleCouponRepository $cartRuleCouponRepository
+ )
+ {
+ $this->_config = request('_config');
+
+ $this->cartRuleRepository = $cartRuleRepository;
+
+ $this->cartRuleCouponRepository = $cartRuleCouponRepository;
+ }
+
+ /**
+ * Display a listing of the resource.
+ *
+ * @return \Illuminate\Http\Response
+ */
+ public function index()
+ {
+ return view($this->_config['view']);
+ }
+
+ /**
+ * Show the form for creating a new resource.
+ *
+ * @return \Illuminate\Http\Response
+ */
+ public function create()
+ {
+ return view($this->_config['view']);
+ }
+
+ /**
+ * Store a newly created resource in storage.
+ *
+ * @return \Illuminate\Http\Response
+ */
+ public function store()
+ {
+ $this->validate(request(), [
+ 'name' => 'required',
+ 'channels' => 'required|array|min:1',
+ 'customer_groups' => 'required|array|min:1',
+ 'coupon_type' => 'required',
+ 'use_auto_generation' => 'required_if:coupon_type,==,1',
+ 'coupon_code' => 'required_if:use_auto_generation,==,0',
+ 'starts_from' => 'nullable|date',
+ 'ends_till' => 'nullable|date|after_or_equal:starts_from',
+ 'action_type' => 'required',
+ 'discount_amount' => 'required|numeric'
+ ]);
+
+ $data = request()->all();
+
+ Event::fire('promotions.cart_rule.create.before');
+
+ $cartRule = $this->cartRuleRepository->create($data);
+
+ Event::fire('promotions.cart_rule.create.after', $cartRule);
+
+ session()->flash('success', trans('admin::app.response.create-success', ['name' => 'Cart Rule']));
+
+ return redirect()->route($this->_config['redirect']);
+ }
+
+ /**
+ * Show the form for editing the specified resource.
+ *
+ * @param int $id
+ * @return \Illuminate\Http\Response
+ */
+ public function edit($id)
+ {
+ $cartRule = $this->cartRuleRepository->findOrFail($id);
+
+ return view($this->_config['view'], compact('cartRule'));
+ }
+
+ /**
+ * Update the specified resource in storage.
+ *
+ * @param \Illuminate\Http\Request $request
+ * @param int $id
+ * @return \Illuminate\Http\Response
+ */
+ public function update(Request $request, $id)
+ {
+ $this->validate(request(), [
+ 'name' => 'required',
+ 'channels' => 'required|array|min:1',
+ 'customer_groups' => 'required|array|min:1',
+ 'coupon_type' => 'required',
+ 'use_auto_generation' => 'required_if:coupon_type,==,1',
+ 'coupon_code' => 'required_if:use_auto_generation,==,0',
+ 'starts_from' => 'nullable|date',
+ 'ends_till' => 'nullable|date|after_or_equal:starts_from',
+ 'action_type' => 'required',
+ 'discount_amount' => 'required|numeric'
+ ]);
+
+ $cartRule = $this->cartRuleRepository->findOrFail($id);
+
+ Event::fire('promotions.cart_rule.update.before', $cartRule);
+
+ $cartRule = $this->cartRuleRepository->update(request()->all(), $id);
+
+ Event::fire('promotions.cart_rule.update.after', $cartRule);
+
+ session()->flash('success', trans('admin::app.response.update-success', ['name' => 'Cart Rule']));
+
+ return redirect()->route($this->_config['redirect']);
+ }
+
+ /**
+ * Remove the specified resource from storage.
+ *
+ * @param int $id
+ * @return \Illuminate\Http\Response
+ */
+ public function destroy($id)
+ {
+ $cartRule = $this->cartRuleRepository->findOrFail($id);
+
+ try {
+ Event::fire('promotions.cart_rule.delete.before', $id);
+
+ $this->cartRuleRepository->delete($id);
+
+ Event::fire('promotions.cart_rule.delete.after', $id);
+
+ session()->flash('success', trans('admin::app.response.delete-success', ['name' => 'Cart Rule']));
+
+ return response()->json(['message' => true], 200);
+ } catch(\Exception $e) {
+ session()->flash('error', trans('admin::app.response.delete-failed', ['name' => 'Cart Rule']));
+ }
+
+ return response()->json(['message' => false], 400);
+ }
+
+ /**
+ * Generate coupon code for cart rule
+ *
+ * @return \Illuminate\Http\JsonResponse
+ */
+ public function generateCoupons()
+ {
+ $this->validate(request(), [
+ 'coupon_qty' => 'required|integer|min:1',
+ 'code_length' => 'required|integer|min:10',
+ 'code_format' => 'required'
+ ]);
+
+ if (! request('id'))
+ return response()->json(['message' => trans('admin::app.promotions.cart-rules.cart-rule-not-defind-error')], 400);
+
+ $this->cartRuleCouponRepository->generateCoupons(request()->all(), request('id'));
+
+ return response()->json(['message' => trans('admin::app.response.create-success', ['name' => 'Cart rule coupons'])]);
+ }
+}
\ No newline at end of file
diff --git a/packages/Webkul/CartRule/src/Http/Controllers/CartRuleCouponController.php b/packages/Webkul/CartRule/src/Http/Controllers/CartRuleCouponController.php
new file mode 100644
index 000000000..7da633cb8
--- /dev/null
+++ b/packages/Webkul/CartRule/src/Http/Controllers/CartRuleCouponController.php
@@ -0,0 +1,55 @@
+
+ * @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com)
+ */
+class CartRuleCouponController extends Controller
+{
+ /**
+ * To hold CartRuleCouponRepository repository instance
+ *
+ * @var CartRuleCouponRepository
+ */
+ protected $cartRuleCouponRepository;
+
+ /**
+ * Create a new controller instance.
+ *
+ * @param \Webkul\CartRule\Repositories\CartRuleCouponRepository $cartRuleCouponRepository
+ * @return void
+ */
+ public function __construct(CartRuleCouponRepository $cartRuleCouponRepository)
+ {
+ $this->cartRuleCouponRepository = $cartRuleCouponRepository;
+ }
+
+ /**
+ * Mass Delete the coupons
+ *
+ * @param int $id
+ * @return \Illuminate\Http\Response
+ */
+ public function massDelete()
+ {
+ $couponIds = explode(',', request()->input('indexes'));
+
+ foreach ($couponIds as $couponId) {
+ $coupon = $this->cartRuleCouponRepository->find($couponId);
+
+ if ($coupon)
+ $this->cartRuleCouponRepository->delete($couponId);
+ }
+
+ session()->flash('success', trans('admin::app.promotions.cart-rules.mass-delete-success'));
+
+ return redirect()->back();
+ }
+}
\ No newline at end of file
diff --git a/packages/Webkul/Discount/src/Http/Controllers/Controller.php b/packages/Webkul/CartRule/src/Http/Controllers/Controller.php
similarity index 87%
rename from packages/Webkul/Discount/src/Http/Controllers/Controller.php
rename to packages/Webkul/CartRule/src/Http/Controllers/Controller.php
index dc4b61e7c..259457d89 100644
--- a/packages/Webkul/Discount/src/Http/Controllers/Controller.php
+++ b/packages/Webkul/CartRule/src/Http/Controllers/Controller.php
@@ -1,9 +1,9 @@
+ * @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com)
+ */
+class Cart
+{
+ /**
+ * CartRule object
+ *
+ * @var CartRule
+ */
+ protected $cartRuleHepler;
+
+ /**
+ * Create a new listener instance.
+ *
+ * @param Webkul\CartRule\Repositories\CartRule $cartRuleHepler
+ * @return void
+ */
+ public function __construct(CartRule $cartRuleHepler)
+ {
+ $this->cartRuleHepler = $cartRuleHepler;
+ }
+
+ /**
+ * Aplly valid cart rules to cart
+ *
+ * @param Cart $cart
+ * @return void
+ */
+ public function applyCartRules($cart)
+ {
+ $this->cartRuleHepler->collect();
+ }
+}
\ No newline at end of file
diff --git a/packages/Webkul/CartRule/src/Listeners/Order.php b/packages/Webkul/CartRule/src/Listeners/Order.php
new file mode 100755
index 000000000..f22fdfa35
--- /dev/null
+++ b/packages/Webkul/CartRule/src/Listeners/Order.php
@@ -0,0 +1,139 @@
+
+ * @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com)
+ */
+class Order
+{
+ /**
+ * CartRuleRepository object
+ *
+ * @var CartRuleRepository
+ */
+ protected $cartRuleRepository;
+
+ /**
+ * CartRuleCustomerRepository object
+ *
+ * @var CartRuleCustomerRepository
+ */
+ protected $cartRuleCustomerRepository;
+
+ /**
+ * CartRuleCouponRepository object
+ *
+ * @var CartRuleCouponRepository
+ */
+ protected $cartRuleCouponRepository;
+
+ /**
+ * CartRuleCouponUsageRepository object
+ *
+ * @var CartRuleCouponUsageRepository
+ */
+ protected $cartRuleCouponUsageRepository;
+
+ /**
+ * Create a new listener instance.
+ *
+ * @param Webkul\CartRule\Repositories\CartRuleRepository $cartRuleRepository
+ * @param Webkul\CartRule\Repositories\CartRuleCustomerRepository $cartRuleCustomerRepository
+ * @param Webkul\CartRule\Repositories\CartRuleCouponRepository $cartRuleCouponRepository
+ * @param Webkul\CartRule\Repositories\CartRuleCouponUsageRepository $cartRuleCouponUsageRepository
+ * @return void
+ */
+ public function __construct(
+ CartRuleRepository $cartRuleRepository,
+ CartRuleCustomerRepository $cartRuleCustomerRepository,
+ CartRuleCouponRepository $cartRuleCouponRepository,
+ CartRuleCouponUsageRepository $cartRuleCouponUsageRepository
+ )
+ {
+ $this->cartRuleRepository = $cartRuleRepository;
+
+ $this->cartRuleCustomerRepository = $cartRuleCustomerRepository;
+
+ $this->cartRuleCouponRepository = $cartRuleCouponRepository;
+
+ $this->cartRuleCouponUsageRepository = $cartRuleCouponUsageRepository;
+ }
+
+ /**
+ * Save cart rule and cart rule coupon properties after place order
+ *
+ * @param Order $order
+ * @return void
+ */
+ public function manageCartRule($order)
+ {
+ if (! $order->discount_amount)
+ return;
+
+ $cartRuleIds = explode(',', $order->applied_cart_rule_ids);
+
+ $cartRuleIds = array_unique($cartRuleIds);
+
+ foreach ($cartRuleIds as $ruleId) {
+ $rule = $this->cartRuleRepository->find($ruleId);
+
+ if (! $rule)
+ continue;
+
+ $rule->update(['times_used' => $rule->times_used + 1]);
+
+ if (! $order->customer_id)
+ continue;
+
+ $ruleCustomer = $this->cartRuleCustomerRepository->findOneWhere([
+ 'customer_id' => $order->customer_id,
+ 'cart_rule_id' => $ruleId
+ ]);
+
+ if ($ruleCustomer) {
+ $this->cartRuleCustomerRepository->update(['times_used' => $ruleCustomer->times_used + 1], $ruleCustomer->id);
+ } else {
+ $this->cartRuleCustomerRepository->create([
+ 'customer_id' => $order->customer_id,
+ 'cart_rule_id' => $ruleId,
+ 'times_used' => 1
+ ]);
+ }
+ }
+
+ if (! $order->coupon_code)
+ return;
+
+ $coupon = $this->cartRuleCouponRepository->findOneByField('code', $order->coupon_code);
+
+ if ($coupon) {
+ $this->cartRuleCouponRepository->update(['times_used' => $coupon->times_used + 1], $coupon->id);
+
+ if ($order->customer_id) {
+ $couponUsage = $this->cartRuleCouponUsageRepository->findOneWhere([
+ 'customer_id' => $order->customer_id,
+ 'cart_rule_coupon_id' => $coupon->id
+ ]);
+
+ if ($couponUsage) {
+ $this->cartRuleCouponUsageRepository->update(['times_used' => $couponUsage->times_used + 1], $couponUsage->id);
+ } else {
+ $this->cartRuleCouponUsageRepository->create([
+ 'customer_id' => $order->customer_id,
+ 'cart_rule_coupon_id' => $coupon->id,
+ 'times_used' => 1
+ ]);
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/packages/Webkul/CartRule/src/Models/CartRule.php b/packages/Webkul/CartRule/src/Models/CartRule.php
new file mode 100644
index 000000000..6392a1c59
--- /dev/null
+++ b/packages/Webkul/CartRule/src/Models/CartRule.php
@@ -0,0 +1,66 @@
+ 'array',
+ ];
+
+ // public $translatedAttributes = ['name'];
+
+ /**
+ * Get the channels that owns the cart rule.
+ */
+ public function channels()
+ {
+ return $this->belongsToMany(ChannelProxy::modelClass(), 'cart_rule_channels');
+ }
+
+ /**
+ * Get the customer groups that owns the cart rule.
+ */
+ public function customer_groups()
+ {
+ return $this->belongsToMany(CustomerGroupProxy::modelClass(), 'cart_rule_customer_groups');
+ }
+
+ /**
+ * Get the coupons that owns the cart rule.
+ */
+ public function coupons()
+ {
+ return $this->hasOne(CartRuleCouponProxy::modelClass());
+ }
+
+ /**
+ * Get primary coupon code for cart rule.
+ */
+ public function coupon_code()
+ {
+ return $this->coupons()->where('is_primary', 1);
+ }
+
+ /**
+ * Get primary coupon code for cart rule.
+ */
+ public function getCouponCodeAttribute()
+ {
+ $coupon = $this->coupon_code()->first();
+
+ if (! $coupon)
+ return;
+
+ return $coupon->code;
+ }
+}
\ No newline at end of file
diff --git a/packages/Webkul/CartRule/src/Models/CartRuleCoupon.php b/packages/Webkul/CartRule/src/Models/CartRuleCoupon.php
new file mode 100644
index 000000000..045af59a1
--- /dev/null
+++ b/packages/Webkul/CartRule/src/Models/CartRuleCoupon.php
@@ -0,0 +1,19 @@
+belongsTo(CartRuleProxy::modelClass());
+ }
+}
\ No newline at end of file
diff --git a/packages/Webkul/CartRule/src/Models/CartRuleCouponProxy.php b/packages/Webkul/CartRule/src/Models/CartRuleCouponProxy.php
new file mode 100644
index 000000000..4a8f20030
--- /dev/null
+++ b/packages/Webkul/CartRule/src/Models/CartRuleCouponProxy.php
@@ -0,0 +1,10 @@
+loadMigrationsFrom(__DIR__ . '/../Database/Migrations');
+
+ $this->app->register(EventServiceProvider::class);
+ }
+
+ /**
+ * Register services.
+ *
+ * @return void
+ */
+ public function register()
+ {
+ }
+}
\ No newline at end of file
diff --git a/packages/Webkul/CartRule/src/Providers/EventServiceProvider.php b/packages/Webkul/CartRule/src/Providers/EventServiceProvider.php
new file mode 100755
index 000000000..a5b5d7133
--- /dev/null
+++ b/packages/Webkul/CartRule/src/Providers/EventServiceProvider.php
@@ -0,0 +1,21 @@
+
+ * @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com)
+ */
+class CartRuleCouponRepository extends Repository
+{
+ /**
+ * @var array
+ */
+ protected $charsets = [
+ 'alphanumeric' => 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789',
+ 'alphabetical' => 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
+ 'numeric' => '0123456789'
+ ];
+
+ /**
+ * Specify Model class name
+ *
+ * @return mixed
+ */
+ function model()
+ {
+ return 'Webkul\CartRule\Contracts\CartRuleCoupon';
+ }
+
+ /**
+ * Creates coupons for cart rule
+ *
+ * @param array $data
+ * @param integer $cartRuleId
+ * @return void
+ */
+ public function generateCoupons($data, $cartRuleId)
+ {
+ $cartRule = app('Webkul\CartRule\Repositories\CartRuleRepository')->findOrFail($cartRuleId);
+
+ for ($i = 0; $i < $data['coupon_qty']; $i++) {
+ parent::create([
+ 'cart_rule_id' => $cartRuleId,
+ 'code' => $data['code_prefix'] . $this->getRandomString($data['code_format'], $data['code_length']) . $data['code_suffix'],
+ 'usage_limit' => $cartRule->uses_per_coupon ?? 0,
+ 'usage_per_customer' => $cartRule->usage_per_customer ?? 0,
+ 'is_primary' => 0,
+ 'expired_at' => $cartRule->ends_till ?: null
+ ]);
+ }
+ }
+
+ /**
+ * Creates coupons for cart rule
+ *
+ * @param string $format
+ * @param integer $length
+ * @return string
+ */
+ public function getRandomString($format, $length)
+ {
+ $couponCode = '';
+
+ for ($i = 0; $i < $length; $i++) {
+ $couponCode .= $this->charsets[$format][rand(0, strlen($this->charsets[$format]) - 1)];
+ }
+
+ return $couponCode;
+ }
+}
\ No newline at end of file
diff --git a/packages/Webkul/CartRule/src/Repositories/CartRuleCouponUsageRepository.php b/packages/Webkul/CartRule/src/Repositories/CartRuleCouponUsageRepository.php
new file mode 100755
index 000000000..5d6350ba8
--- /dev/null
+++ b/packages/Webkul/CartRule/src/Repositories/CartRuleCouponUsageRepository.php
@@ -0,0 +1,24 @@
+
+ * @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com)
+ */
+class CartRuleCouponUsageRepository extends Repository
+{
+ /**
+ * Specify Model class name
+ *
+ * @return mixed
+ */
+ function model()
+ {
+ return 'Webkul\CartRule\Contracts\CartRuleCouponUsage';
+ }
+}
\ No newline at end of file
diff --git a/packages/Webkul/CartRule/src/Repositories/CartRuleCustomerRepository.php b/packages/Webkul/CartRule/src/Repositories/CartRuleCustomerRepository.php
new file mode 100755
index 000000000..e3218eb94
--- /dev/null
+++ b/packages/Webkul/CartRule/src/Repositories/CartRuleCustomerRepository.php
@@ -0,0 +1,24 @@
+
+ * @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com)
+ */
+class CartRuleCustomerRepository extends Repository
+{
+ /**
+ * Specify Model class name
+ *
+ * @return mixed
+ */
+ function model()
+ {
+ return 'Webkul\CartRule\Contracts\CartRuleCustomer';
+ }
+}
\ No newline at end of file
diff --git a/packages/Webkul/CartRule/src/Repositories/CartRuleRepository.php b/packages/Webkul/CartRule/src/Repositories/CartRuleRepository.php
new file mode 100755
index 000000000..80847ee67
--- /dev/null
+++ b/packages/Webkul/CartRule/src/Repositories/CartRuleRepository.php
@@ -0,0 +1,478 @@
+
+ * @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com)
+ */
+class CartRuleRepository extends Repository
+{
+ /**
+ * AttributeFamilyRepository object
+ *
+ * @var AttributeFamilyRepository
+ */
+ protected $attributeFamilyRepository;
+
+ /**
+ * AttributeRepository object
+ *
+ * @var AttributeRepository
+ */
+ protected $attributeRepository;
+
+ /**
+ * CategoryRepository class
+ *
+ * @var CategoryRepository
+ */
+ protected $categoryRepository;
+
+ /**
+ * CartRuleCouponRepository object
+ *
+ * @var CartRuleCouponRepository
+ */
+ protected $cartRuleCouponRepository;
+
+ /**
+ * TaxCategoryRepository class
+ *
+ * @var TaxCategoryRepository
+ */
+ protected $taxCategoryRepository;
+
+ /**
+ * CountryRepository class
+ *
+ * @var CountryRepository
+ */
+ protected $countryRepository;
+
+ /**
+ * CountryStateRepository class
+ *
+ * @var CountryStateRepository
+ */
+ protected $countryStateRepository;
+
+ /**
+ * Create a new repository instance.
+ *
+ * @param Webkul\Attribute\Repositories\AttributeFamilyRepository $attributeFamilyRepository
+ * @param Webkul\Attribute\Repositories\AttributeRepository $attributeRepository
+ * @param Webkul\Category\Repositories\CategoryRepository $categoryRepository
+ * @param Webkul\CartRule\Repositories\CartRuleCouponRepository $cartRuleCouponRepository
+ * @param Webkul\Tax\Repositories\TaxCategoryRepository $taxCategoryRepository
+ * @param Webkul\Core\Repositories\CountryRepository $countryRepository
+ * @param Webkul\Core\Repositories\CountryStateRepository $countryStateRepository
+ * @param Illuminate\Container\Container $app
+ * @return void
+ */
+ public function __construct(
+ AttributeFamilyRepository $attributeFamilyRepository,
+ AttributeRepository $attributeRepository,
+ CategoryRepository $categoryRepository,
+ CartRuleCouponRepository $cartRuleCouponRepository,
+ TaxCategoryRepository $taxCategoryRepository,
+ CountryRepository $countryRepository,
+ CountryStateRepository $countryStateRepository,
+ App $app
+ )
+ {
+ $this->attributeFamilyRepository = $attributeFamilyRepository;
+
+ $this->attributeRepository = $attributeRepository;
+
+ $this->categoryRepository = $categoryRepository;
+
+ $this->cartRuleCouponRepository = $cartRuleCouponRepository;
+
+ $this->taxCategoryRepository = $taxCategoryRepository;
+
+ $this->countryRepository = $countryRepository;
+
+ $this->countryStateRepository = $countryStateRepository;
+
+ parent::__construct($app);
+ }
+
+ /**
+ * Specify Model class name
+ *
+ * @return mixed
+ */
+ function model()
+ {
+ return 'Webkul\CartRule\Contracts\CartRule';
+ }
+
+ /**
+ * @param array $data
+ * @return mixed
+ */
+ public function create(array $data)
+ {
+ $data['starts_from'] = $data['starts_from'] ?: null;
+
+ $data['ends_till'] = $data['ends_till'] ?: null;
+
+ $data['status'] = ! isset($data['status']) ? 0 : 1;
+
+ $cartRule = parent::create($data);
+
+ $cartRule->channels()->sync($data['channels']);
+
+ $cartRule->customer_groups()->sync($data['customer_groups']);
+
+ if ($data['coupon_type'] && ! $data['use_auto_generation']) {
+ $this->cartRuleCouponRepository->create([
+ 'cart_rule_id' => $cartRule->id,
+ 'code' => $data['coupon_code'],
+ 'usage_limit' => $data['usage_per_customer'] ?? 0,
+ 'usage_per_customer' => $data['usage_per_customer'] ?? 0,
+ 'is_primary' => 1,
+ 'expired_at' => $data['ends_till'] ?: null
+ ]);
+ }
+
+ return $cartRule;
+ }
+
+ /**
+ * @param array $data
+ * @param array $id
+ * @param string $attribute
+ * @return mixed
+ */
+ public function update(array $data, $id, $attribute = "id")
+ {
+ $data['starts_from'] = $data['starts_from'] ?: null;
+
+ $data['ends_till'] = $data['ends_till'] ?: null;
+
+ $data['status'] = ! isset($data['status']) ? 0 : 1;
+
+ $data['conditions'] = $data['conditions'] ?? [];
+
+ $cartRule = $this->find($id);
+
+ parent::update($data, $id, $attribute);
+
+ $cartRule->channels()->sync($data['channels']);
+
+ $cartRule->customer_groups()->sync($data['customer_groups']);
+
+ if ($data['coupon_type']) {
+ if (! $data['use_auto_generation']) {
+ $cartRuleCoupon = $this->cartRuleCouponRepository->findOneWhere(['is_primary' => 1, 'cart_rule_id' => $cartRule->id]);
+
+ if ($cartRuleCoupon) {
+ $this->cartRuleCouponRepository->update([
+ 'code' => $data['coupon_code'],
+ 'usage_limit' => $data['uses_per_coupon'] ?? 0,
+ 'usage_per_customer' => $data['usage_per_customer'] ?? 0,
+ 'expired_at' => $data['ends_till'] ?: null
+ ], $cartRuleCoupon->id);
+ } else {
+ $this->cartRuleCouponRepository->create([
+ 'cart_rule_id' => $cartRule->id,
+ 'code' => $data['coupon_code'],
+ 'usage_limit' => $data['uses_per_coupon'] ?? 0,
+ 'usage_per_customer' => $data['usage_per_customer'] ?? 0,
+ 'is_primary' => 1,
+ 'expired_at' => $data['ends_till'] ?: null
+ ]);
+ }
+ } else {
+ $this->cartRuleCouponRepository->deleteWhere(['is_primary' => 1, 'cart_rule_id' => $cartRule->id]);
+
+ $this->cartRuleCouponRepository->getModel()->where('cart_rule_id', $cartRule->id)->update([
+ 'usage_limit' => $data['uses_per_coupon'] ?? 0,
+ 'usage_per_customer' => $data['usage_per_customer'] ?? 0,
+ 'expired_at' => $data['ends_till'] ?: null
+ ]);
+ }
+ } else {
+ $cartRuleCoupon = $this->cartRuleCouponRepository->deleteWhere(['is_primary' => 1, 'cart_rule_id' => $cartRule->id]);
+ }
+
+ return $cartRule;
+ }
+
+ /**
+ * Returns attributes for cart rule conditions
+ *
+ * @return array
+ */
+ public function getConditionAttributes()
+ {
+ $attributes = [
+ [
+ 'key' => 'cart',
+ 'label' => trans('admin::app.promotions.cart-rules.cart-attribute'),
+ 'children' => [
+ [
+ 'key' => 'cart|base_sub_total',
+ 'type' => 'price',
+ 'label' => trans('admin::app.promotions.cart-rules.subtotal')
+ ], [
+ 'key' => 'cart|items_qty',
+ 'type' => 'integer',
+ 'label' => trans('admin::app.promotions.cart-rules.total-items-qty')
+ ], [
+ 'key' => 'cart|payment_method',
+ 'type' => 'select',
+ 'options' => $this->getPaymentMethods(),
+ 'label' => trans('admin::app.promotions.cart-rules.payment-method')
+ ], [
+ 'key' => 'cart|shipping_method',
+ 'type' => 'select',
+ 'options' => $this->getShippingMethods(),
+ 'label' => trans('admin::app.promotions.cart-rules.shipping-method')
+ ], [
+ 'key' => 'cart|postcode',
+ 'type' => 'text',
+ 'label' => trans('admin::app.promotions.cart-rules.shipping-postcode')
+ ], [
+ 'key' => 'cart|state',
+ 'type' => 'select',
+ 'options' => $this->groupedStatesByCountries(),
+ 'label' => trans('admin::app.promotions.cart-rules.shipping-state')
+ ], [
+ 'key' => 'cart|country',
+ 'type' => 'select',
+ 'options' => $this->getCountries(),
+ 'label' => trans('admin::app.promotions.cart-rules.shipping-country')
+ ]
+ ]
+ ], [
+ 'key' => 'cart_item',
+ 'label' => trans('admin::app.promotions.cart-rules.cart-item-attribute'),
+ 'children' => [
+ [
+ 'key' => 'cart_item|base_price',
+ 'type' => 'price',
+ 'label' => trans('admin::app.promotions.cart-rules.price-in-cart')
+ ], [
+ 'key' => 'cart_item|quantity',
+ 'type' => 'integer',
+ 'label' => trans('admin::app.promotions.cart-rules.qty-in-cart')
+ ], [
+ 'key' => 'cart_item|base_total_weight',
+ 'type' => 'decimal',
+ 'label' => trans('admin::app.promotions.cart-rules.total-weight')
+ ], [
+ 'key' => 'cart_item|base_total',
+ 'type' => 'price',
+ 'label' => trans('admin::app.promotions.cart-rules.subtotal')
+ ]
+ ]
+ ], [
+ 'key' => 'product',
+ 'label' => trans('admin::app.promotions.cart-rules.product-attribute'),
+ 'children' => [
+ [
+ 'key' => 'product|category_ids',
+ 'type' => 'multiselect',
+ 'label' => trans('admin::app.promotions.cart-rules.categories'),
+ 'options' => $categories = $this->categoryRepository->getCategoryTree()
+ ], [
+ 'key' => 'product|children::category_ids',
+ 'type' => 'multiselect',
+ 'label' => trans('admin::app.promotions.cart-rules.children-categories'),
+ 'options' => $categories
+ ], [
+ 'key' => 'product|parent::category_ids',
+ 'type' => 'multiselect',
+ 'label' => trans('admin::app.promotions.cart-rules.parent-categories'),
+ 'options' => $categories
+ ], [
+ 'key' => 'product|attribute_family_id',
+ 'type' => 'select',
+ 'label' => trans('admin::app.promotions.cart-rules.attribute_family'),
+ 'options' => $this->getAttributeFamilies()
+ ]
+ ]
+ ]
+ ];
+
+ foreach ($this->attributeRepository->findWhereNotIn('type', ['textarea', 'image', 'file']) as $attribute) {
+ $attributeType = $attribute->type;
+
+ if ($attribute->code == 'tax_category_id') {
+ $options = $this->getTaxCategories();
+ } else {
+ $options = $attribute->options;
+ }
+
+ if ($attribute->validation == 'decimal')
+ $attributeType = 'decimal';
+
+ if ($attribute->validation == 'numeric')
+ $attributeType = 'integer';
+
+ $attributes[2]['children'][] = [
+ 'key' => 'product|' . $attribute->code,
+ 'type' => $attribute->type,
+ 'label' => $attribute->name,
+ 'options' => $options
+ ];
+
+ $attributes[2]['children'][] = [
+ 'key' => 'product|children::' . $attribute->code,
+ 'type' => $attribute->type,
+ 'label' => trans('admin::app.promotions.cart-rules.attribute-name-children-only', ['attribute_name' => $attribute->name]),
+ 'options' => $options
+ ];
+
+ $attributes[2]['children'][] = [
+ 'key' => 'product|parent::' . $attribute->code,
+ 'type' => $attribute->type,
+ 'label' => trans('admin::app.promotions.cart-rules.attribute-name-parent-only', ['attribute_name' => $attribute->name]),
+ 'options' => $options
+ ];
+ }
+
+ return $attributes;
+ }
+
+ /**
+ * Returns all payment methods
+ *
+ * @return array
+ */
+ public function getPaymentMethods()
+ {
+ $methods = [];
+
+ foreach (config('paymentmethods') as $paymentMethod) {
+ $object = app($paymentMethod['class']);
+
+ $methods[] = [
+ 'id' => $object->getCode(),
+ 'admin_name' => $object->getTitle()
+ ];
+ }
+
+ return $methods;
+ }
+
+ /**
+ * Returns all shipping methods
+ *
+ * @return array
+ */
+ public function getShippingMethods()
+ {
+ $methods = [];
+
+ foreach (config('carriers') as $shippingMethod) {
+ $object = app($shippingMethod['class']);
+
+ $methods[] = [
+ 'id' => $object->getCode(),
+ 'admin_name' => $object->getTitle()
+ ];
+ }
+
+ return $methods;
+ }
+
+ /**
+ * Returns all countries
+ *
+ * @return array
+ */
+ public function getTaxCategories()
+ {
+ $taxCategories = [];
+
+ foreach ($this->taxCategoryRepository->all() as $taxCategory) {
+ $taxCategories[] = [
+ 'id' => $taxCategory->id,
+ 'admin_name' => $taxCategory->name,
+ ];
+ }
+
+ return $taxCategories;
+ }
+
+ /**
+ * Returns all attribute families
+ *
+ * @return array
+ */
+ public function getAttributeFamilies()
+ {
+ $attributeFamilies = [];
+
+ foreach ($this->attributeFamilyRepository->all() as $attributeFamily) {
+ $attributeFamilies[] = [
+ 'id' => $attributeFamily->id,
+ 'admin_name' => $attributeFamily->name,
+ ];
+ }
+
+ return $attributeFamilies;
+ }
+
+ /**
+ * Returns all countries
+ *
+ * @return array
+ */
+ public function getCountries()
+ {
+ $countries = [];
+
+ foreach ($this->countryRepository->all() as $country) {
+ $countries[] = [
+ 'id' => $country->code,
+ 'admin_name' => $country->name,
+ ];
+ }
+
+ return $countries;
+ }
+
+ /**
+ * Retrieve all grouped states by country code
+ *
+ * @return array
+ */
+ public function groupedStatesByCountries()
+ {
+ $collection = [];
+
+ foreach ($this->countryRepository->all() as $country) {
+ $countryStates = $this->countryStateRepository->findWhere(
+ ['country_id' => $country->id],
+ ['code', 'default_name as admin_name']
+ )->toArray();
+
+ if (! count($countryStates))
+ continue;
+
+ $collection[] = [
+ 'id' => $country->code,
+ 'admin_name' => $country->name,
+ 'states' => $countryStates
+ ];
+ }
+
+ return $collection;
+ }
+}
\ No newline at end of file
diff --git a/packages/Webkul/CatalogRule/src/Console/Commands/PriceRuleIndex.php b/packages/Webkul/CatalogRule/src/Console/Commands/PriceRuleIndex.php
new file mode 100644
index 000000000..4f856c979
--- /dev/null
+++ b/packages/Webkul/CatalogRule/src/Console/Commands/PriceRuleIndex.php
@@ -0,0 +1,53 @@
+catalogRuleIndexHelper = $catalogRuleIndexHelper;
+
+ parent::__construct();
+ }
+
+ /**
+ * Execute the console command.
+ *
+ * @return mixed
+ */
+ public function handle()
+ {
+ // $this->catalogRuleIndexHelper->reindexComplete();
+ }
+}
\ No newline at end of file
diff --git a/packages/Webkul/CatalogRule/src/Contracts/CatalogRule.php b/packages/Webkul/CatalogRule/src/Contracts/CatalogRule.php
new file mode 100644
index 000000000..c322bdc78
--- /dev/null
+++ b/packages/Webkul/CatalogRule/src/Contracts/CatalogRule.php
@@ -0,0 +1,7 @@
+increments('id');
- $table->string('name');
- $table->text('description');
- $table->datetime('starts_from')->nullable();
- $table->datetime('ends_till')->nullable();
+ $table->string('name')->nullable();
+ $table->string('description')->nullable();
+ $table->date('starts_from')->nullable();
+ $table->date('ends_till')->nullable();
$table->boolean('status')->default(0);
+ $table->boolean('condition_type')->default(1);
$table->json('conditions')->nullable();
- $table->json('actions')->nullable();
$table->boolean('end_other_rules')->default(0);
- $table->string('action_code')->nullable();
- $table->decimal('discount_amount', 20, 4)->default(0.0000);
+ $table->string('action_type')->nullable();
+ $table->decimal('discount_amount', 12, 4)->default(0);
+ $table->integer('sort_order')->unsigned()->default(0);
$table->timestamps();
});
}
diff --git a/packages/Webkul/Discount/src/Database/Migrations/2019_08_08_130458_create_catalog_rule_channels_table.php b/packages/Webkul/CatalogRule/src/Database/Migrations/2019_12_03_184651_create_catalog_rule_channels_table.php
similarity index 91%
rename from packages/Webkul/Discount/src/Database/Migrations/2019_08_08_130458_create_catalog_rule_channels_table.php
rename to packages/Webkul/CatalogRule/src/Database/Migrations/2019_12_03_184651_create_catalog_rule_channels_table.php
index 32e0ea36e..8f0053237 100644
--- a/packages/Webkul/Discount/src/Database/Migrations/2019_08_08_130458_create_catalog_rule_channels_table.php
+++ b/packages/Webkul/CatalogRule/src/Database/Migrations/2019_12_03_184651_create_catalog_rule_channels_table.php
@@ -14,12 +14,13 @@ class CreateCatalogRuleChannelsTable extends Migration
public function up()
{
Schema::create('catalog_rule_channels', function (Blueprint $table) {
- $table->increments('id');
- $table->integer('channel_id')->unsigned();
- $table->foreign('channel_id')->references('id')->on('channels')->onDelete('cascade');
$table->integer('catalog_rule_id')->unsigned();
+ $table->integer('channel_id')->unsigned();
+
+ $table->primary(['catalog_rule_id', 'channel_id']);
+
$table->foreign('catalog_rule_id')->references('id')->on('catalog_rules')->onDelete('cascade');
- $table->timestamps();
+ $table->foreign('channel_id')->references('id')->on('channels')->onDelete('cascade');
});
}
diff --git a/packages/Webkul/Discount/src/Database/Migrations/2019_08_08_130451_create_catalog_rule_customer_groups_table.php b/packages/Webkul/CatalogRule/src/Database/Migrations/2019_12_03_184732_create_catalog_rule_customer_groups_table.php
similarity index 86%
rename from packages/Webkul/Discount/src/Database/Migrations/2019_08_08_130451_create_catalog_rule_customer_groups_table.php
rename to packages/Webkul/CatalogRule/src/Database/Migrations/2019_12_03_184732_create_catalog_rule_customer_groups_table.php
index 7337cef44..5670c6a80 100644
--- a/packages/Webkul/Discount/src/Database/Migrations/2019_08_08_130451_create_catalog_rule_customer_groups_table.php
+++ b/packages/Webkul/CatalogRule/src/Database/Migrations/2019_12_03_184732_create_catalog_rule_customer_groups_table.php
@@ -14,12 +14,14 @@ class CreateCatalogRuleCustomerGroupsTable extends Migration
public function up()
{
Schema::create('catalog_rule_customer_groups', function (Blueprint $table) {
- $table->increments('id');
- $table->integer('customer_group_id')->unsigned();
- $table->foreign('customer_group_id')->references('id')->on('customer_groups')->onDelete('cascade');
$table->integer('catalog_rule_id')->unsigned();
+ $table->integer('customer_group_id')->unsigned();
+
+
+ $table->primary(['catalog_rule_id', 'customer_group_id'], 'catalog_rule_id_customer_group_id_primary');
+
$table->foreign('catalog_rule_id')->references('id')->on('catalog_rules')->onDelete('cascade');
- $table->timestamps();
+ $table->foreign('customer_group_id')->references('id')->on('customer_groups')->onDelete('cascade');
});
}
diff --git a/packages/Webkul/Discount/src/Database/Migrations/2019_08_08_130550_create_catalog_rule_products_table.php b/packages/Webkul/CatalogRule/src/Database/Migrations/2019_12_06_101110_create_catalog_rule_products_table.php
similarity index 80%
rename from packages/Webkul/Discount/src/Database/Migrations/2019_08_08_130550_create_catalog_rule_products_table.php
rename to packages/Webkul/CatalogRule/src/Database/Migrations/2019_12_06_101110_create_catalog_rule_products_table.php
index 2f456559e..8628050ac 100644
--- a/packages/Webkul/Discount/src/Database/Migrations/2019_08_08_130550_create_catalog_rule_products_table.php
+++ b/packages/Webkul/CatalogRule/src/Database/Migrations/2019_12_06_101110_create_catalog_rule_products_table.php
@@ -14,20 +14,25 @@ class CreateCatalogRuleProductsTable extends Migration
public function up()
{
Schema::create('catalog_rule_products', function (Blueprint $table) {
- $table->bigIncrements('id');
- $table->integer('catalog_rule_id')->unsigned();
- $table->foreign('catalog_rule_id')->references('id')->on('catalog_rules')->onDelete('cascade');
+ $table->increments('id');
$table->datetime('starts_from')->nullable();
$table->datetime('ends_till')->nullable();
- $table->integer('customer_group_id')->unsigned();
- $table->foreign('customer_group_id')->references('id')->on('customer_groups')->onDelete('cascade');
- $table->integer('channel_id')->unsigned();
- $table->foreign('channel_id')->references('id')->on('channels')->onDelete('cascade');
+ $table->boolean('end_other_rules')->default(0);
+ $table->string('action_type')->nullable();
+ $table->decimal('discount_amount', 12, 4)->default(0);
+ $table->integer('sort_order')->unsigned()->default(0);
+
$table->integer('product_id')->unsigned();
$table->foreign('product_id')->references('id')->on('products')->onDelete('cascade');
- $table->string('action_code')->nullable();
- $table->decimal('action_amount', 20, 4)->default(0.0000);
- $table->timestamps();
+
+ $table->integer('customer_group_id')->unsigned();
+ $table->foreign('customer_group_id')->references('id')->on('customer_groups')->onDelete('cascade');
+
+ $table->integer('catalog_rule_id')->unsigned();
+ $table->foreign('catalog_rule_id')->references('id')->on('catalog_rules')->onDelete('cascade');
+
+ $table->integer('channel_id')->unsigned();
+ $table->foreign('channel_id')->references('id')->on('channels')->onDelete('cascade');
});
}
@@ -40,4 +45,4 @@ class CreateCatalogRuleProductsTable extends Migration
{
Schema::dropIfExists('catalog_rule_products');
}
-}
\ No newline at end of file
+}
diff --git a/packages/Webkul/Discount/src/Database/Migrations/2019_08_08_130583_create_catalog_rule_products_price_table.php b/packages/Webkul/CatalogRule/src/Database/Migrations/2019_12_06_110507_create_catalog_rule_product_prices_table.php
similarity index 76%
rename from packages/Webkul/Discount/src/Database/Migrations/2019_08_08_130583_create_catalog_rule_products_price_table.php
rename to packages/Webkul/CatalogRule/src/Database/Migrations/2019_12_06_110507_create_catalog_rule_product_prices_table.php
index a5af74b08..dab445de0 100644
--- a/packages/Webkul/Discount/src/Database/Migrations/2019_08_08_130583_create_catalog_rule_products_price_table.php
+++ b/packages/Webkul/CatalogRule/src/Database/Migrations/2019_12_06_110507_create_catalog_rule_product_prices_table.php
@@ -4,7 +4,7 @@ use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
-class CreateCatalogRuleProductsPriceTable extends Migration
+class CreateCatalogRuleProductPricesTable extends Migration
{
/**
* Run the migrations.
@@ -13,20 +13,24 @@ class CreateCatalogRuleProductsPriceTable extends Migration
*/
public function up()
{
- Schema::create('catalog_rule_products_price', function (Blueprint $table) {
- $table->bigIncrements('id');
- $table->integer('channel_id')->unsigned();
- $table->foreign('channel_id')->references('id')->on('channels')->onDelete('cascade');
- $table->integer('customer_group_id')->unsigned();
- $table->foreign('customer_group_id')->references('id')->on('customer_groups')->onDelete('cascade');
- $table->integer('product_id')->unsigned();
- $table->foreign('product_id')->references('id')->on('products')->onDelete('cascade');
- $table->integer('catalog_rule_id')->unsigned();
- $table->foreign('catalog_rule_id')->references('id')->on('catalog_rules')->onDelete('cascade');
- $table->decimal('rule_price', 20, 4)->default(0.0000);
+ Schema::create('catalog_rule_product_prices', function (Blueprint $table) {
+ $table->increments('id');
+ $table->decimal('price', 12, 4)->default(0);
+ $table->date('rule_date');
$table->datetime('starts_from')->nullable();
$table->datetime('ends_till')->nullable();
- $table->timestamps();
+
+ $table->integer('product_id')->unsigned();
+ $table->foreign('product_id')->references('id')->on('products')->onDelete('cascade');
+
+ $table->integer('customer_group_id')->unsigned();
+ $table->foreign('customer_group_id')->references('id')->on('customer_groups')->onDelete('cascade');
+
+ $table->integer('catalog_rule_id')->unsigned();
+ $table->foreign('catalog_rule_id')->references('id')->on('catalog_rules')->onDelete('cascade');
+
+ $table->integer('channel_id')->unsigned();
+ $table->foreign('channel_id')->references('id')->on('channels')->onDelete('cascade');
});
}
@@ -37,6 +41,6 @@ class CreateCatalogRuleProductsPriceTable extends Migration
*/
public function down()
{
- Schema::dropIfExists('catalog_rule_products_price');
+ Schema::dropIfExists('catalog_rule_product_prices');
}
}
diff --git a/packages/Webkul/CatalogRule/src/Helpers/CatalogRuleIndex.php b/packages/Webkul/CatalogRule/src/Helpers/CatalogRuleIndex.php
new file mode 100644
index 000000000..fd9b6cc5f
--- /dev/null
+++ b/packages/Webkul/CatalogRule/src/Helpers/CatalogRuleIndex.php
@@ -0,0 +1,137 @@
+catalogRuleRepository = $catalogRuleRepository;
+
+ $this->catalogRuleProductHelper = $catalogRuleProductHelper;
+
+ $this->catalogRuleProductPriceHelper = $catalogRuleProductPriceHelper;
+ }
+
+ /**
+ * Full reindex
+ *
+ * @return void
+ */
+ public function reindexComplete()
+ {
+ try {
+ $this->cleanIndexes();
+
+ foreach ($this->getCatalogRules() as $rule) {
+ $this->catalogRuleProductHelper->insertRuleProduct($rule);
+ }
+
+ $this->catalogRuleProductPriceHelper->indexRuleProductPrice(1000);
+ } catch (\Exception $e) {
+
+ }
+ }
+
+ /**
+ * Full reindex
+ *
+ * @param Product $product
+ * @return void
+ */
+ public function reindexProduct($product)
+ {
+ try {
+ if (! $product->getTypeInstance()->priceRuleCanBeApplied())
+ return;
+
+ $productIds = $product->getTypeInstance()->isComposite()
+ ? $product->getTypeInstance()->getChildrenIds()
+ : [$product->id];
+
+ $this->cleanIndexes($productIds);
+
+ foreach ($this->getCatalogRules() as $rule) {
+ $this->catalogRuleProductHelper->insertRuleProduct($rule, 1000, $product);
+ }
+
+ $this->catalogRuleProductPriceHelper->indexRuleProductPrice(1000, $product);
+ } catch (\Exception $e) {
+
+ }
+ }
+
+ /**
+ * Deletes catalog rule product and catalog rule product price indexes
+ *
+ * @param array $productIds
+ * @return void
+ */
+ public function cleanIndexes($productIds = [])
+ {
+ $this->catalogRuleProductHelper->cleanProductIndex($productIds);
+
+ $this->catalogRuleProductPriceHelper->cleanProductPriceIndex($productIds);
+ }
+
+ /**
+ * Returns catalog rules
+ *
+ * @return Collection
+ */
+ public function getCatalogRules()
+ {
+ static $catalogRules;
+
+ if ($catalogRules)
+ return $catalogRules;
+
+ $catalogRules = $this->catalogRuleRepository->scopeQuery(function($query) {
+ return $query->where(function ($query1) {
+ $query1->where('catalog_rules.starts_from', '<=', Carbon::now()->format('Y-m-d'))->orWhereNull('catalog_rules.starts_from');
+ })
+ ->where(function ($query2) {
+ $query2->where('catalog_rules.ends_till', '>=', Carbon::now()->format('Y-m-d'))->orWhereNull('catalog_rules.ends_till');
+ })
+ ->orderBy('sort_order', 'asc');
+ })->findWhere(['status' => 1]);
+
+ return $catalogRules;
+ }
+}
\ No newline at end of file
diff --git a/packages/Webkul/CatalogRule/src/Helpers/CatalogRuleProduct.php b/packages/Webkul/CatalogRule/src/Helpers/CatalogRuleProduct.php
new file mode 100644
index 000000000..60e3aa629
--- /dev/null
+++ b/packages/Webkul/CatalogRule/src/Helpers/CatalogRuleProduct.php
@@ -0,0 +1,253 @@
+attributeRepository = $attributeRepository;
+
+ $this->productRepository = $productRepository;
+
+ $this->catalogRuleProductRepository = $catalogRuleProductRepository;
+
+ $this->validator = $validator;
+ }
+
+ /**
+ * Collect discount on cart
+ *
+ * @param CatalogRule $rule
+ * @param integer $batchCount
+ * @return void
+ */
+ public function insertRuleProduct($rule, $batchCount = 1000, $product = null)
+ {
+ $productIds = $this->getMatchingProductIds($rule, $product);
+
+ $rows = [];
+
+ $startsFrom = $rule->starts_from ? Carbon::createFromTimeString($rule->starts_from . " 00:00:01") : null;
+
+ $endsTill = $rule->ends_till ? Carbon::createFromTimeString($rule->ends_till . " 23:59:59") : null;
+
+ foreach ($productIds as $productId) {
+ foreach ($rule->channels()->pluck('id') as $channelId) {
+ foreach ($rule->customer_groups()->pluck('id') as $customerGroupId) {
+ $rows[] = [
+ 'starts_from' => $startsFrom,
+ 'ends_till' => $endsTill,
+ 'catalog_rule_id' => $rule->id,
+ 'channel_id' => $channelId,
+ 'customer_group_id' => $customerGroupId,
+ 'product_id' => $productId,
+ 'discount_amount' => $rule->discount_amount,
+ 'action_type' => $rule->action_type,
+ 'end_other_rules' => $rule->end_other_rules,
+ 'sort_order' => $rule->sort_order,
+ ];
+
+ if (count($rows) == $batchCount) {
+ $this->catalogRuleProductRepository->getModel()->insert($rows);
+
+ $rows = [];
+ }
+ }
+ }
+ }
+
+ if (! empty($rows))
+ $this->catalogRuleProductRepository->getModel()->insert($rows);
+ }
+
+ /**
+ * Get array of product ids which are matched by rule
+ *
+ * @param CatalogRule $rule
+ * @param Product $product
+ * @return array
+ */
+ public function getMatchingProductIds($rule, $product = null)
+ {
+ $qb = $this->productRepository->scopeQuery(function($query) use($rule, $product) {
+ $qb = $query->distinct()
+ ->addSelect('products.*')
+ ->leftJoin('product_flat', 'products.id', '=', 'product_flat.product_id')
+ ->leftJoin('channels', 'product_flat.channel', '=', 'channels.code')
+ ->whereIn('channels.id', $rule->channels()->pluck('id')->toArray());
+
+ if ($product)
+ $qb->where('products.id', $product->id);
+
+ if (! $rule->conditions)
+ return $qb;
+
+ $appliedAttributes = [];
+
+ foreach ($rule->conditions as $condition) {
+ if (! $condition['attribute']
+ || ! isset($condition['value'])
+ || is_null($condition['value'])
+ || $condition['value'] == ''
+ || in_array($condition['attribute'], $appliedAttributes))
+ continue;
+
+ $appliedAttributes[] = $condition['attribute'];
+
+ $chunks = explode('|', $condition['attribute']);
+
+ $qb = $this->addAttributeToSelect(end($chunks), $qb);
+ }
+
+ return $qb;
+ });
+
+ $validatedProductIds = [];
+
+ foreach ($qb->get() as $product) {
+ if (! $product->getTypeInstance()->priceRuleCanBeApplied())
+ continue;
+
+ if ($this->validator->validate($rule, $product)) {
+ if ($product->getTypeInstance()->isComposite()) {
+ $validatedProductIds = array_merge($validatedProductIds, $product->getTypeInstance()->getChildrenIds());
+ } else {
+ $validatedProductIds[] = $product->id;
+ }
+ }
+ }
+
+ return array_unique($validatedProductIds);
+ }
+
+ /**
+ * Add product attribute condition to query
+ *
+ * @param string $attributeCode
+ * @param QueryBuilder $query
+ * @return QueryBuilder
+ */
+ public function addAttributeToSelect($attributeCode, $query)
+ {
+ $attribute = $this->attributeRepository->findOneByField('code', $attributeCode);
+
+ if (! $attribute)
+ return $query;
+
+ $query = $query->leftJoin('product_attribute_values as ' . 'pav_' . $attribute->code, function($qb) use($attribute) {
+ $qb = $qb->where('pav_' . $attribute->code . '.channel', $attribute->value_per_channel ? core()->getDefaultChannelCode() : null)
+ ->where('pav_' . $attribute->code . '.locale', $attribute->value_per_locale ? app()->getLocale() : null);
+
+ $qb->on('products.id', 'pav_' . $attribute->code . '.product_id')
+ ->where('pav_' . $attribute->code . '.attribute_id', $attribute->id);
+ });
+
+ $query = $query->addSelect('pav_' . $attribute->code . '.' . ProductAttributeValue::$attributeTypeFields[$attribute->type] . ' as ' . $attribute->code);
+
+ return $query;
+ }
+
+ /**
+ * Returns catalog rule products
+ *
+ * @param Product $product
+ * @return Collection
+ */
+ public function getCatalogRuleProducts($product = null)
+ {
+ $results = $this->catalogRuleProductRepository->scopeQuery(function($query) use($product) {
+ $qb = $query->distinct()
+ ->select('catalog_rule_products.*')
+ ->leftJoin('products', 'catalog_rule_products.product_id', '=', 'products.id')
+ ->orderBy('channel_id', 'asc')
+ ->orderBy('customer_group_id', 'asc')
+ ->orderBy('product_id', 'asc')
+ ->orderBy('sort_order', 'asc')
+ ->orderBy('catalog_rule_id', 'asc');
+
+ $qb = $this->addAttributeToSelect('price', $qb);
+
+ if ($product) {
+ if (! $product->getTypeInstance()->priceRuleCanBeApplied())
+ return $qb;
+
+ if ($product->getTypeInstance()->isComposite()) {
+ $qb->whereIn('catalog_rule_products.product_id', $product->getTypeInstance()->getChildrenIds());
+ } else {
+ $qb->where('catalog_rule_products.product_id', $product->id);
+ }
+ }
+
+ return $qb;
+ })->get();
+
+ return $results;
+ }
+
+ /**
+ * Returns catalog rules
+ *
+ * @param CatalogRule $rule
+ * @return void
+ */
+ public function cleanProductIndex($productIds = [])
+ {
+ if (count($productIds)) {
+ $this->catalogRuleProductRepository->getModel()->whereIn('product_id', $productIds)->delete();
+ } else {
+ $this->catalogRuleProductRepository->deleteWhere([
+ ['product_id', 'like', '%%']
+ ]);
+ }
+ }
+}
\ No newline at end of file
diff --git a/packages/Webkul/CatalogRule/src/Helpers/CatalogRuleProductPrice.php b/packages/Webkul/CatalogRule/src/Helpers/CatalogRuleProductPrice.php
new file mode 100644
index 000000000..358b37cd5
--- /dev/null
+++ b/packages/Webkul/CatalogRule/src/Helpers/CatalogRuleProductPrice.php
@@ -0,0 +1,217 @@
+catalogRuleProductPriceRepository = $catalogRuleProductPriceRepository;
+
+ $this->catalogRuleProductHelper = $catalogRuleProductHelper;
+
+ $this->customerGroupRepository = $customerGroupRepository;
+ }
+
+ /**
+ * Return current logged in customer
+ *
+ * @return Customer | Boolean
+ */
+ public function getCurrentCustomer()
+ {
+ $guard = request()->has('token') ? 'api' : 'customer';
+
+ return auth()->guard($guard);
+ }
+
+ /**
+ * Collect discount on cart
+ *
+ * @param integer $batchCount
+ * @param Product $product
+ * @return void
+ */
+ public function indexRuleProductPrice($batchCount, $product = null)
+ {
+ $dates = [
+ 'current' => $currentDate = Carbon::now(),
+ 'previous' => (clone $currentDate)->subDays('1')->setTime(23, 59, 59),
+ 'next' => (clone $currentDate)->addDays('1')->setTime(0, 0, 0),
+ ];
+
+ $prices = $endRuleFlags = [];
+
+ $previousKey = null;
+
+ $catalogRuleProducts = $this->catalogRuleProductHelper->getCatalogRuleProducts($product);
+
+ foreach ($catalogRuleProducts as $row) {
+ $productKey = $row->product_id . '-' . $row->channel_id . '-' . $row->customer_group_id;
+
+ if ($previousKey && $previousKey != $productKey) {
+ $endRuleFlags = [];
+
+ if (count($prices) > $batchCount) {
+ $this->catalogRuleProductPriceRepository->getModel()->insert($prices);
+
+ $prices = [];
+ }
+ }
+
+ foreach ($dates as $key => $date) {
+ if ((! $row->starts_from || $date >= $row->starts_from)
+ && (! $row->ends_till || $date <= $row->ends_till))
+ {
+ $priceKey = $date->getTimestamp() . '-' . $productKey;
+
+ if (isset($endRuleFlags[$priceKey]))
+ continue;
+
+ if (! isset($prices[$priceKey])) {
+ $prices[$priceKey] = [
+ 'rule_date' => $date,
+ 'catalog_rule_id' => $row->catalog_rule_id,
+ 'channel_id' => $row->channel_id,
+ 'customer_group_id' => $row->customer_group_id,
+ 'product_id' => $row->product_id,
+ 'price' => $this->calculate($row),
+ 'starts_from' => $row->starts_from,
+ 'ends_till' => $row->ends_till,
+ ];
+ } else {
+ $prices[$priceKey]['price'] = $this->calculate($row, $prices[$priceKey]);
+
+ $prices[$priceKey]['starts_from'] = max($prices[$priceKey]['starts_from'], $row->starts_from);
+
+ $prices[$priceKey]['ends_till'] = min($prices[$priceKey]['ends_till'], $row->ends_till);
+ }
+
+ if ($row->end_other_rules)
+ $endRuleFlags[$priceKey] = true;
+ }
+ }
+
+ $previousKey = $productKey;
+ }
+
+ $this->catalogRuleProductPriceRepository->getModel()->insert($prices);
+ }
+
+ /**
+ * Calculates product price based on rule
+ *
+ * @param array $rule
+ * @param Product|null $productData
+ * @return float
+ */
+ public function calculate($rule, $productData = null)
+ {
+ $price = $productData && isset($productData['price']) ? $productData['price'] : $rule->price;
+
+ switch ($rule->action_type) {
+ case 'to_fixed':
+ $price = min($rule->discount_amount, $price);
+
+ break;
+
+ case 'to_percent':
+ $price = $price * $rule->discount_amount / 100;
+
+ break;
+
+ case 'by_fixed':
+ $price = max(0, $price - $rule->discount_amount);
+
+ break;
+
+ case 'by_percent':
+ $price = $price * (1 - $rule->discount_amount / 100);
+
+ break;
+ }
+
+ return $price;
+ }
+
+ /**
+ * Clean product price index
+ *
+ * @param array $productIds
+ * @return void
+ */
+ public function cleanProductPriceIndex($productIds = [])
+ {
+ if (count($productIds)) {
+ $this->catalogRuleProductPriceRepository->getModel()->whereIn('product_id', $productIds)->delete();
+ } else {
+ $this->catalogRuleProductPriceRepository->deleteWhere([
+ ['product_id', 'like', '%%']
+ ]);
+ }
+ }
+
+ /**
+ * Get catalog rules product price for specific date, channel and customer group
+ *
+ * @param Product $product
+ * @return void
+ */
+ public function getRulePrice($product)
+ {
+ if ($this->getCurrentCustomer()->check()) {
+ $customerGroupId = $this->getCurrentCustomer()->user()->customer_group_id;
+ } else {
+ $customerGroup = $this->customerGroupRepository->findOneByField('code', 'guest');
+
+ if (! $customerGroup)
+ return;
+
+ $customerGroupId = $customerGroup->id;
+ }
+
+ return $this->catalogRuleProductPriceRepository->findOneWhere([
+ 'product_id' => $product->id,
+ 'channel_id' => core()->getCurrentChannel()->id,
+ 'customer_group_id' => $customerGroupId,
+ 'rule_date' => Carbon::now()->format('Y-m-d'),
+ ]);
+ }
+}
\ No newline at end of file
diff --git a/packages/Webkul/CatalogRule/src/Http/Controllers/CatalogRuleController.php b/packages/Webkul/CatalogRule/src/Http/Controllers/CatalogRuleController.php
new file mode 100644
index 000000000..3bcceb50f
--- /dev/null
+++ b/packages/Webkul/CatalogRule/src/Http/Controllers/CatalogRuleController.php
@@ -0,0 +1,183 @@
+
+ * @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com)
+ */
+class CatalogRuleController extends Controller
+{
+ /**
+ * Initialize _config, a default request parameter with route
+ *
+ * @param array
+ */
+ protected $_config;
+
+ /**
+ * To hold Catalog repository instance
+ *
+ * @var CatalogRuleRepository
+ */
+ protected $catalogRuleRepository;
+
+ /**
+ * CatalogRuleIndex
+ *
+ * @var CatalogRuleIndex
+ */
+ protected $catalogRuleIndexHelper;
+
+ /**
+ * Create a new controller instance.
+ *
+ * @param \Webkul\CatalogRule\Repositories\CatalogRuleRepository $catalogRuleRepository
+ * @param \Webkul\CatalogRule\Helpers\CatalogRuleIndex $catalogRuleIndexHelper
+ * @return void
+ */
+ public function __construct(
+ CatalogRuleRepository $catalogRuleRepository,
+ CatalogRuleIndex $catalogRuleIndexHelper
+ )
+ {
+ $this->_config = request('_config');
+
+ $this->catalogRuleRepository = $catalogRuleRepository;
+
+ $this->catalogRuleIndexHelper = $catalogRuleIndexHelper;
+ }
+
+ /**
+ * Display a listing of the resource.
+ *
+ * @return \Illuminate\Http\Response
+ */
+ public function index()
+ {
+ return view($this->_config['view']);
+ }
+
+ /**
+ * Show the form for creating a new resource.
+ *
+ * @return \Illuminate\Http\Response
+ */
+ public function create()
+ {
+ return view($this->_config['view']);
+ }
+
+ /**
+ * Store a newly created resource in storage.
+ *
+ * @return \Illuminate\Http\Response
+ */
+ public function store()
+ {
+ $this->validate(request(), [
+ 'name' => 'required',
+ 'channels' => 'required|array|min:1',
+ 'customer_groups' => 'required|array|min:1',
+ 'starts_from' => 'nullable|date',
+ 'ends_till' => 'nullable|date|after_or_equal:starts_from',
+ 'action_type' => 'required',
+ 'discount_amount' => 'required|numeric'
+ ]);
+
+ $data = request()->all();
+
+ Event::fire('promotions.catalog_rule.create.before');
+
+ $catalogRule = $this->catalogRuleRepository->create($data);
+
+ Event::fire('promotions.catalog_rule.create.after', $catalogRule);
+
+ $this->catalogRuleIndexHelper->reindexComplete();
+
+ session()->flash('success', trans('admin::app.response.create-success', ['name' => 'Catalog Rule']));
+
+ return redirect()->route($this->_config['redirect']);
+ }
+
+ /**
+ * Show the form for editing the specified resource.
+ *
+ * @param int $id
+ * @return \Illuminate\Http\Response
+ */
+ public function edit($id)
+ {
+ $catalogRule = $this->catalogRuleRepository->findOrFail($id);
+
+ return view($this->_config['view'], compact('catalogRule'));
+ }
+
+ /**
+ * Update the specified resource in storage.
+ *
+ * @param \Illuminate\Http\Request $request
+ * @param int $id
+ * @return \Illuminate\Http\Response
+ */
+ public function update(Request $request, $id)
+ {
+ $this->validate(request(), [
+ 'name' => 'required',
+ 'channels' => 'required|array|min:1',
+ 'customer_groups' => 'required|array|min:1',
+ 'starts_from' => 'nullable|date',
+ 'ends_till' => 'nullable|date|after_or_equal:starts_from',
+ 'action_type' => 'required',
+ 'discount_amount' => 'required|numeric'
+ ]);
+
+ $catalogRule = $this->catalogRuleRepository->findOrFail($id);
+
+ Event::fire('promotions.catalog_rule.update.before', $catalogRule);
+
+ $catalogRule = $this->catalogRuleRepository->update(request()->all(), $id);
+
+ Event::fire('promotions.catalog_rule.update.after', $catalogRule);
+
+ $this->catalogRuleIndexHelper->reindexComplete();
+
+ session()->flash('success', trans('admin::app.response.update-success', ['name' => 'Catalog Rule']));
+
+ return redirect()->route($this->_config['redirect']);
+ }
+
+ /**
+ * Remove the specified resource from storage.
+ *
+ * @param int $id
+ * @return \Illuminate\Http\Response
+ */
+ public function destroy($id)
+ {
+ $catalogRule = $this->catalogRuleRepository->findOrFail($id);
+
+ try {
+ Event::fire('promotions.catalog_rule.delete.before', $id);
+
+ $this->catalogRuleRepository->delete($id);
+
+ Event::fire('promotions.catalog_rule.delete.after', $id);
+
+ session()->flash('success', trans('admin::app.response.delete-success', ['name' => 'Catalog Rule']));
+
+ return response()->json(['message' => true], 200);
+ } catch(\Exception $e) {
+ session()->flash('error', trans('admin::app.response.delete-failed', ['name' => 'Catalog Rule']));
+ }
+
+ return response()->json(['message' => false], 400);
+ }
+}
\ No newline at end of file
diff --git a/packages/Webkul/CatalogRule/src/Http/Controllers/Controller.php b/packages/Webkul/CatalogRule/src/Http/Controllers/Controller.php
new file mode 100644
index 000000000..78181ceb7
--- /dev/null
+++ b/packages/Webkul/CatalogRule/src/Http/Controllers/Controller.php
@@ -0,0 +1,13 @@
+
+ * @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com)
+ */
+class Product
+{
+ /**
+ * Product Repository Object
+ *
+ * @var Object
+ */
+ protected $catalogRuleIndexHelper;
+
+ /**
+ * Create a new listener instance.
+ *
+ * @param Webkul\CatalogRule\Helpers\CatalogRuleIndex $catalogRuleIndexHelper
+ * @return void
+ */
+ public function __construct(CatalogRuleIndex $catalogRuleIndexHelper)
+ {
+ $this->catalogRuleIndexHelper = $catalogRuleIndexHelper;
+ }
+
+ /**
+ * @param Product $product
+ * @return void
+ */
+ public function createProductRuleIndex($product)
+ {
+ $this->catalogRuleIndexHelper->reindexProduct($product);
+ }
+}
\ No newline at end of file
diff --git a/packages/Webkul/CatalogRule/src/Models/CatalogRule.php b/packages/Webkul/CatalogRule/src/Models/CatalogRule.php
new file mode 100644
index 000000000..00e991506
--- /dev/null
+++ b/packages/Webkul/CatalogRule/src/Models/CatalogRule.php
@@ -0,0 +1,33 @@
+ 'array'
+ ];
+
+ /**
+ * Get the channels that owns the catalog rule.
+ */
+ public function channels()
+ {
+ return $this->belongsToMany(ChannelProxy::modelClass(), 'catalog_rule_channels');
+ }
+
+ /**
+ * Get the customer groups that owns the catalog rule.
+ */
+ public function customer_groups()
+ {
+ return $this->belongsToMany(CustomerGroupProxy::modelClass(), 'catalog_rule_customer_groups');
+ }
+}
\ No newline at end of file
diff --git a/packages/Webkul/CatalogRule/src/Models/CatalogRuleProduct.php b/packages/Webkul/CatalogRule/src/Models/CatalogRuleProduct.php
new file mode 100644
index 000000000..dfa513113
--- /dev/null
+++ b/packages/Webkul/CatalogRule/src/Models/CatalogRuleProduct.php
@@ -0,0 +1,13 @@
+loadMigrationsFrom(__DIR__ . '/../Database/Migrations');
+
+ Event::listen('catalog.product.update.after', 'Webkul\CatalogRule\Listeners\Product@createProductRuleIndex');
+ }
+
+ /**
+ * Register services.
+ *
+ * @return void
+ */
+ public function register()
+ {
+ $this->registerCommands();
+ }
+
+ /**
+ * Register the console commands of this package
+ */
+ protected function registerCommands()
+ {
+ if ($this->app->runningInConsole())
+ $this->commands([PriceRuleIndex::class]);
+ }
+}
\ No newline at end of file
diff --git a/packages/Webkul/CatalogRule/src/Providers/ModuleServiceProvider.php b/packages/Webkul/CatalogRule/src/Providers/ModuleServiceProvider.php
new file mode 100644
index 000000000..778b8a1d9
--- /dev/null
+++ b/packages/Webkul/CatalogRule/src/Providers/ModuleServiceProvider.php
@@ -0,0 +1,14 @@
+
+ * @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com)
+ */
+class CatalogRuleProductPriceRepository extends Repository
+{
+ /**
+ * Specify Model class name
+ *
+ * @return mixed
+ */
+ function model()
+ {
+ return 'Webkul\CatalogRule\Contracts\CatalogRuleProductPrice';
+ }
+}
\ No newline at end of file
diff --git a/packages/Webkul/CatalogRule/src/Repositories/CatalogRuleProductRepository.php b/packages/Webkul/CatalogRule/src/Repositories/CatalogRuleProductRepository.php
new file mode 100644
index 000000000..565781c29
--- /dev/null
+++ b/packages/Webkul/CatalogRule/src/Repositories/CatalogRuleProductRepository.php
@@ -0,0 +1,24 @@
+
+ * @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com)
+ */
+class CatalogRuleProductRepository extends Repository
+{
+ /**
+ * Specify Model class name
+ *
+ * @return mixed
+ */
+ function model()
+ {
+ return 'Webkul\CatalogRule\Contracts\CatalogRuleProduct';
+ }
+}
\ No newline at end of file
diff --git a/packages/Webkul/CatalogRule/src/Repositories/CatalogRuleRepository.php b/packages/Webkul/CatalogRule/src/Repositories/CatalogRuleRepository.php
new file mode 100644
index 000000000..16a59b5ee
--- /dev/null
+++ b/packages/Webkul/CatalogRule/src/Repositories/CatalogRuleRepository.php
@@ -0,0 +1,225 @@
+
+ * @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com)
+ */
+class CatalogRuleRepository extends Repository
+{
+ /**
+ * AttributeFamilyRepository object
+ *
+ * @var AttributeFamilyRepository
+ */
+ protected $attributeFamilyRepository;
+
+ /**
+ * AttributeRepository object
+ *
+ * @var AttributeRepository
+ */
+ protected $attributeRepository;
+
+ /**
+ * CategoryRepository class
+ *
+ * @var CategoryRepository
+ */
+ protected $categoryRepository;
+
+ /**
+ * TaxCategoryRepository class
+ *
+ * @var TaxCategoryRepository
+ */
+ protected $taxCategoryRepository;
+
+ /**
+ * Create a new repository instance.
+ *
+ * @param Webkul\Attribute\Repositories\AttributeFamilyRepository $attributeFamilyRepository
+ * @param Webkul\Attribute\Repositories\AttributeRepository $attributeRepository
+ * @param Webkul\Category\Repositories\CategoryRepository $categoryRepository
+ * @param Webkul\Tax\Repositories\TaxCategoryRepository $taxCategoryRepository
+ * @param Illuminate\Container\Container $app
+ * @return void
+ */
+ public function __construct(
+ AttributeFamilyRepository $attributeFamilyRepository,
+ AttributeRepository $attributeRepository,
+ CategoryRepository $categoryRepository,
+ TaxCategoryRepository $taxCategoryRepository,
+ App $app
+ )
+ {
+ $this->attributeFamilyRepository = $attributeFamilyRepository;
+
+ $this->attributeRepository = $attributeRepository;
+
+ $this->categoryRepository = $categoryRepository;
+
+ $this->taxCategoryRepository = $taxCategoryRepository;
+
+ parent::__construct($app);
+ }
+
+ /**
+ * Specify Model class name
+ *
+ * @return mixed
+ */
+ function model()
+ {
+ return 'Webkul\CatalogRule\Contracts\CatalogRule';
+ }
+
+ /**
+ * @param array $data
+ * @return mixed
+ */
+ public function create(array $data)
+ {
+ $data['starts_from'] = $data['starts_from'] ?: null;
+
+ $data['ends_till'] = $data['ends_till'] ?: null;
+
+ $data['status'] = ! isset($data['status']) ? 0 : 1;
+
+ $catalogRule = parent::create($data);
+
+ $catalogRule->channels()->sync($data['channels']);
+
+ $catalogRule->customer_groups()->sync($data['customer_groups']);
+
+ return $catalogRule;
+ }
+
+ /**
+ * @param array $data
+ * @param array $id
+ * @param string $attribute
+ * @return mixed
+ */
+ public function update(array $data, $id, $attribute = "id")
+ {
+ $data['starts_from'] = $data['starts_from'] ?: null;
+
+ $data['ends_till'] = $data['ends_till'] ?: null;
+
+ $data['status'] = ! isset($data['status']) ? 0 : 1;
+
+ $data['conditions'] = $data['conditions'] ?? [];
+
+ $catalogRule = $this->find($id);
+
+ parent::update($data, $id, $attribute);
+
+ $catalogRule->channels()->sync($data['channels']);
+
+ $catalogRule->customer_groups()->sync($data['customer_groups']);
+
+ return $catalogRule;
+ }
+
+ /**
+ * Returns attributes for catalog rule conditions
+ *
+ * @return array
+ */
+ public function getConditionAttributes()
+ {
+ $attributes = [
+ [
+ 'key' => 'product',
+ 'label' => trans('admin::app.promotions.catalog-rules.product-attribute'),
+ 'children' => [
+ [
+ 'key' => 'product|category_ids',
+ 'type' => 'multiselect',
+ 'label' => trans('admin::app.promotions.catalog-rules.categories'),
+ 'options' => $this->categoryRepository->getCategoryTree()
+ ], [
+ 'key' => 'product|attribute_family_id',
+ 'type' => 'select',
+ 'label' => trans('admin::app.promotions.catalog-rules.attribute_family'),
+ 'options' => $this->getAttributeFamilies()
+ ]
+ ]
+ ]
+ ];
+
+ foreach ($this->attributeRepository->findWhereNotIn('type', ['textarea', 'image', 'file']) as $attribute) {
+ $attributeType = $attribute->type;
+
+ if ($attribute->code == 'tax_category_id') {
+ $options = $this->getTaxCategories();
+ } else {
+ $options = $attribute->options;
+ }
+
+ if ($attribute->validation == 'decimal')
+ $attributeType = 'decimal';
+
+ if ($attribute->validation == 'numeric')
+ $attributeType = 'integer';
+
+ $attributes[0]['children'][] = [
+ 'key' => 'product|' . $attribute->code,
+ 'type' => $attribute->type,
+ 'label' => $attribute->name,
+ 'options' => $options
+ ];
+ }
+
+ return $attributes;
+ }
+
+ /**
+ * Returns all tax categories
+ *
+ * @return array
+ */
+ public function getTaxCategories()
+ {
+ $taxCategories = [];
+
+ foreach ($this->taxCategoryRepository->all() as $taxCategory) {
+ $taxCategories[] = [
+ 'id' => $taxCategory->id,
+ 'admin_name' => $taxCategory->name,
+ ];
+ }
+
+ return $taxCategories;
+ }
+
+ /**
+ * Returns all attribute families
+ *
+ * @return array
+ */
+ public function getAttributeFamilies()
+ {
+ $attributeFamilies = [];
+
+ foreach ($this->attributeFamilyRepository->all() as $attributeFamily) {
+ $attributeFamilies[] = [
+ 'id' => $attributeFamily->id,
+ 'admin_name' => $attributeFamily->name,
+ ];
+ }
+
+ return $attributeFamilies;
+ }
+}
\ No newline at end of file
diff --git a/packages/Webkul/Checkout/src/Cart.php b/packages/Webkul/Checkout/src/Cart.php
index c640a30d0..8d772a56c 100755
--- a/packages/Webkul/Checkout/src/Cart.php
+++ b/packages/Webkul/Checkout/src/Cart.php
@@ -614,6 +614,8 @@ class Cart {
if (! $cart = $this->getCart())
return false;
+ Event::fire('checkout.cart.collect.totals.before', $cart);
+
$this->calculateItemsTax();
$cart->grand_total = $cart->base_grand_total = 0;
@@ -636,11 +638,15 @@ class Cart {
}
if ($shipping = $cart->selected_shipping_rate) {
- $cart->grand_total = (float) $cart->grand_total + $shipping->price;
- $cart->base_grand_total = (float) $cart->base_grand_total + $shipping->base_price;
+ $cart->grand_total = (float) $cart->grand_total + $shipping->price - $shipping->discount_amount;
+ $cart->base_grand_total = (float) $cart->base_grand_total + $shipping->base_price - $shipping->base_discount_amount;
+
+ $cart->discount_amount += $shipping->discount_amount;
+ $cart->base_discount_amount += $shipping->base_discount_amount;
}
$quantities = 0;
+
foreach ($cart->items as $item) {
$quantities = $quantities + $item->quantity;
}
@@ -650,6 +656,8 @@ class Cart {
$cart->items_qty = $quantities;
$cart->save();
+
+ Event::fire('checkout.cart.collect.totals.after', $cart);
}
/**
@@ -835,6 +843,8 @@ class Cart {
'base_sub_total' => $data['base_sub_total'],
'tax_amount' => $data['tax_total'],
'base_tax_amount' => $data['base_tax_total'],
+ 'coupon_code' => $data['coupon_code'],
+ 'applied_cart_rule_ids' => $data['applied_cart_rule_ids'],
'discount_amount' => $data['discount_amount'],
'base_discount_amount' => $data['base_discount_amount'],
'billing_address' => array_except($data['billing_address'], ['id', 'cart_id']),
@@ -972,4 +982,37 @@ class Cart {
return true;
}
+
+ /**
+ * Set coupon code to the cart
+ *
+ * @param string $code
+ * @return Cart
+ */
+ public function setCouponCode($code)
+ {
+ $cart = $this->getCart();
+
+ $cart->coupon_code = $code;
+
+ $cart->save();
+
+ return $this;
+ }
+
+ /**
+ * Remove coupon code from cart
+ *
+ * @return Cart
+ */
+ public function removeCouponCode()
+ {
+ $cart = $this->getCart();
+
+ $cart->coupon_code = null;
+
+ $cart->save();
+
+ return $this;
+ }
}
\ No newline at end of file
diff --git a/packages/Webkul/Discount/src/Database/Migrations/2019_07_14_070809_add_products_selection_column_in_cart_rules_table.php b/packages/Webkul/Checkout/src/Database/Migrations/2019_11_25_171136_add_applied_cart_rule_ids_column_in_cart_table.php
similarity index 55%
rename from packages/Webkul/Discount/src/Database/Migrations/2019_07_14_070809_add_products_selection_column_in_cart_rules_table.php
rename to packages/Webkul/Checkout/src/Database/Migrations/2019_11_25_171136_add_applied_cart_rule_ids_column_in_cart_table.php
index c8c86276b..b6423d3be 100644
--- a/packages/Webkul/Discount/src/Database/Migrations/2019_07_14_070809_add_products_selection_column_in_cart_rules_table.php
+++ b/packages/Webkul/Checkout/src/Database/Migrations/2019_11_25_171136_add_applied_cart_rule_ids_column_in_cart_table.php
@@ -4,7 +4,7 @@ use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
-class AddProductsSelectionColumnInCartRulesTable extends Migration
+class AddAppliedCartRuleIdsColumnInCartTable extends Migration
{
/**
* Run the migrations.
@@ -13,8 +13,8 @@ class AddProductsSelectionColumnInCartRulesTable extends Migration
*/
public function up()
{
- Schema::table('cart_rules', function (Blueprint $table) {
- $table->json('products_selection')->nullable();
+ Schema::table('cart', function (Blueprint $table) {
+ $table->string('applied_cart_rule_ids')->nullable();
});
}
@@ -25,8 +25,8 @@ class AddProductsSelectionColumnInCartRulesTable extends Migration
*/
public function down()
{
- Schema::table('cart_rules', function (Blueprint $table) {
- $table->dropColumn('products_selection');
+ Schema::table('cart', function (Blueprint $table) {
+ //
});
}
}
diff --git a/packages/Webkul/Discount/src/Database/Migrations/2019_06_25_110122_remove_is_guest_from_cart_rules_table.php b/packages/Webkul/Checkout/src/Database/Migrations/2019_11_25_171208_add_applied_cart_rule_ids_column_in_cart_items_table.php
similarity index 57%
rename from packages/Webkul/Discount/src/Database/Migrations/2019_06_25_110122_remove_is_guest_from_cart_rules_table.php
rename to packages/Webkul/Checkout/src/Database/Migrations/2019_11_25_171208_add_applied_cart_rule_ids_column_in_cart_items_table.php
index a34fe12d9..cb22375bf 100644
--- a/packages/Webkul/Discount/src/Database/Migrations/2019_06_25_110122_remove_is_guest_from_cart_rules_table.php
+++ b/packages/Webkul/Checkout/src/Database/Migrations/2019_11_25_171208_add_applied_cart_rule_ids_column_in_cart_items_table.php
@@ -4,7 +4,7 @@ use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
-class RemoveIsGuestFromCartRulesTable extends Migration
+class AddAppliedCartRuleIdsColumnInCartItemsTable extends Migration
{
/**
* Run the migrations.
@@ -13,8 +13,8 @@ class RemoveIsGuestFromCartRulesTable extends Migration
*/
public function up()
{
- Schema::table('cart_rules', function (Blueprint $table) {
- $table->dropColumn('is_guest');
+ Schema::table('cart_items', function (Blueprint $table) {
+ $table->string('applied_cart_rule_ids')->nullable();
});
}
@@ -25,8 +25,8 @@ class RemoveIsGuestFromCartRulesTable extends Migration
*/
public function down()
{
- Schema::table('cart_rules', function (Blueprint $table) {
- $table->boolean('is_guest')->default(0);
+ Schema::table('cart_items', function (Blueprint $table) {
+ //
});
}
}
diff --git a/packages/Webkul/Checkout/src/Database/Migrations/2019_11_30_165644_add_discount_columns_in_cart_shipping_rates_table.php b/packages/Webkul/Checkout/src/Database/Migrations/2019_11_30_165644_add_discount_columns_in_cart_shipping_rates_table.php
new file mode 100644
index 000000000..8c7b48e44
--- /dev/null
+++ b/packages/Webkul/Checkout/src/Database/Migrations/2019_11_30_165644_add_discount_columns_in_cart_shipping_rates_table.php
@@ -0,0 +1,33 @@
+decimal('discount_amount', 12, 4)->default(0);
+ $table->decimal('base_discount_amount', 12, 4)->default(0);
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ *
+ * @return void
+ */
+ public function down()
+ {
+ Schema::table('cart_shipping_rates', function (Blueprint $table) {
+ //
+ });
+ }
+}
diff --git a/packages/Webkul/Checkout/src/Models/Cart.php b/packages/Webkul/Checkout/src/Models/Cart.php
index 01cddea2b..9088531fa 100755
--- a/packages/Webkul/Checkout/src/Models/Cart.php
+++ b/packages/Webkul/Checkout/src/Models/Cart.php
@@ -12,8 +12,6 @@ class Cart extends Model implements CartContract
protected $guarded = ['id', 'created_at', 'updated_at'];
- protected $hidden = ['coupon_code'];
-
protected $with = ['items', 'items.children'];
/**
diff --git a/packages/Webkul/Checkout/src/Models/CartShippingRate.php b/packages/Webkul/Checkout/src/Models/CartShippingRate.php
index 6ecf168cb..7c4447e33 100755
--- a/packages/Webkul/Checkout/src/Models/CartShippingRate.php
+++ b/packages/Webkul/Checkout/src/Models/CartShippingRate.php
@@ -7,7 +7,7 @@ use Webkul\Checkout\Contracts\CartShippingRate as CartShippingRateContract;
class CartShippingRate extends Model implements CartShippingRateContract
{
- protected $fillable = ['carrier', 'carrier_title', 'method', 'method_title', 'method_description', 'price', 'base_price'];
+ protected $fillable = ['carrier', 'carrier_title', 'method', 'method_title', 'method_description', 'price', 'base_price', 'discount_amount', 'base_discount_amount'];
/**
* Get the post that owns the comment.
diff --git a/packages/Webkul/Core/src/Config/concord.php b/packages/Webkul/Core/src/Config/concord.php
index 311ede347..24c40b47a 100644
--- a/packages/Webkul/Core/src/Config/concord.php
+++ b/packages/Webkul/Core/src/Config/concord.php
@@ -19,7 +19,8 @@ return [
\Webkul\Sales\Providers\ModuleServiceProvider::class,
\Webkul\Tax\Providers\ModuleServiceProvider::class,
\Webkul\User\Providers\ModuleServiceProvider::class,
- \Webkul\Discount\Providers\ModuleServiceProvider::class,
+ \Webkul\CatalogRule\Providers\ModuleServiceProvider::class,
+ \Webkul\CartRule\Providers\ModuleServiceProvider::class,
\Webkul\CMS\Providers\ModuleServiceProvider::class
]
];
\ No newline at end of file
diff --git a/packages/Webkul/Discount/composer.json b/packages/Webkul/Discount/composer.json
deleted file mode 100644
index 78ac3d63e..000000000
--- a/packages/Webkul/Discount/composer.json
+++ /dev/null
@@ -1,27 +0,0 @@
-{
- "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"
-}
\ No newline at end of file
diff --git a/packages/Webkul/Discount/src/Actions/Cart/Action.php b/packages/Webkul/Discount/src/Actions/Cart/Action.php
deleted file mode 100644
index cabe673a4..000000000
--- a/packages/Webkul/Discount/src/Actions/Cart/Action.php
+++ /dev/null
@@ -1,88 +0,0 @@
-rule;
-
- $cart = \Cart::getCart();
-
- $items = $cart->items()->get();
-
- $eligibleItems = collect();
-
- if ($this->rule->action_type == 'whole_cart_to_percent' || $this->rule->action_type == 'whole_cart_to_fixed_amount')
- $this->eligibleItems = $items;
-
- if (! $rule->uses_attribute_conditions) {
- return $items;
- } else {
- $productIDs = explode(',', $rule->product_ids);
-
- foreach ($items as $item) {
- foreach ($productIDs as $productID) {
- $childrens = $item->children;
-
- foreach ($childrens as $children) {
- if ($children->product_id == $productID)
- $eligibleItems->push($item);
- }
-
- if ($item->product_id == $productID)
- $eligibleItems->push($item);
- }
- }
-
- return $eligibleItems;
- }
- }
-
- /**
- * To check the items applicability
- */
- public function checkApplicability()
- {
- $rule = $this->rule;
-
- $eligibleItems = $this->getEligibleItems($rule);
-
- $apply = function () use($rule, $eligibleItems) {
- if ($rule->action_type == 'percent_of_product') {
- return true;
- } else {
- if ($rule->action_type == 'whole_cart_to_percent' && $rule->uses_attribute_condition) {
- $matchingIds = explode(',', $rule->product_ids);
-
- foreach ($matchingIds as $matchingId) {
- foreach ($eligibleItems as $item) {
- if (($item->child ? $item->child->product_id : $item->product_id) == $matchingId)
- return true;
- }
- }
-
- return false;
- } else {
- return true;
- }
- }
- };
-
- return $apply();
- }
-}
\ No newline at end of file
diff --git a/packages/Webkul/Discount/src/Actions/Cart/FixedAmount.php b/packages/Webkul/Discount/src/Actions/Cart/FixedAmount.php
deleted file mode 100644
index 12f86396c..000000000
--- a/packages/Webkul/Discount/src/Actions/Cart/FixedAmount.php
+++ /dev/null
@@ -1,88 +0,0 @@
-rule = $rule;
- }
-
- public function calculate($rule)
- {
- $impact = collect();
-
- $totalDiscount = 0;
-
- if ($this->checkApplicability()) {
- $eligibleItems = $this->getEligibleItems();
-
- foreach ($eligibleItems as $item) {
- $report = array();
-
- $report['item_id'] = $item->id;
- $report['child_items'] = collect();
-
- $perItemDiscount = $rule->disc_amount / $eligibleItems->count();
-
- $itemPrice = $item->base_price;
-
- $itemQuantity = $item->quantity;
-
- $discQuantity = $rule->disc_quantity;
- $discQuantity = $itemQuantity <= $discQuantity ? $itemQuantity : $discQuantity;
-
- if ($item->product->getTypeInstance()->isComposite()) {
- $isQtyZero = true;
-
- foreach ($item->children as $children) {
- if ($children->quantity > 0)
- $isQtyZero = false;
- }
-
- if ($isQtyZero) {
- // case for configurable products
- $report['product_id'] = $item->children->first()->product_id;
- } else {
- // composites other than configurable
- $report['product_id'] = $item->product_id;
-
- foreach ($item->children as $children) {
- $childBaseTotal = $children->base_total;
-
- $itemDiscount = $childBaseTotal / ($item->base_total / 100);
-
- $children->discount = ($itemDiscount / 100) * $perItemDiscount;
-
- $children->discount = $children->base_total > $children->discount ? $children->discount : $children->base_total;
-
- $report['child_items']->push($children);
- }
- }
- } else {
- $report['product_id'] = $item->product_id;
- }
-
- $discount = round($perItemDiscount, 4) * $discQuantity;
- $discount = $discount <= $itemPrice * $discQuantity ? $discount : $itemPrice * $discQuantity;
-
- $report['discount'] = $discount;
- $report['formatted_discount'] = core()->currency($discount);
-
- $impact->push($report);
-
- $totalDiscount = $totalDiscount + $discount;
-
- unset($report);
- }
- }
-
- $impact->discount = $totalDiscount;
- $impact->formatted_discount = core()->currency($impact->discount);
-
- return $impact;
- }
-}
\ No newline at end of file
diff --git a/packages/Webkul/Discount/src/Actions/Cart/PercentOfProduct.php b/packages/Webkul/Discount/src/Actions/Cart/PercentOfProduct.php
deleted file mode 100644
index 2f372a1e8..000000000
--- a/packages/Webkul/Discount/src/Actions/Cart/PercentOfProduct.php
+++ /dev/null
@@ -1,110 +0,0 @@
-rule = $rule;
- }
-
- /**
- * To calculate impact of cart rule's action of current items of cart instance
- *
- * @param CartRule $rule
- *
- * @return boolean
- */
- public function calculate($rule)
- {
- $impact = collect();
-
- $totalDiscount = 0;
-
- $applicability = $this->checkApplicability();
-
- if ($applicability) {
- $eligibleItems = $this->getEligibleItems();
-
- $applicableDiscount = function () use ($eligibleItems) {
- $total = 0;
-
- foreach ($eligibleItems as $item) {
- $total = $total + $item->base_total;
- }
-
- return $total;
- };
-
- foreach ($eligibleItems as $item) {
- $report = array();
-
- $report['item_id'] = $item->id;
- $report['child_items'] = collect();
-
- $perItemDiscount = $applicableDiscount() * ($rule->disc_amount / 100) / $eligibleItems->count();
-
- $itemPrice = $item->base_price;
-
- $itemQuantity = $item->quantity;
-
- $discQuantity = $rule->disc_quantity;
- $discQuantity = $itemQuantity <= $discQuantity ? $itemQuantity : $discQuantity;
-
- if ($item->product->getTypeInstance()->isComposite()) {
- $isQtyZero = true;
-
- foreach ($item->children as $children) {
- if ($children->quantity > 0)
- $isQtyZero = false;
- }
-
- if ($isQtyZero) {
- // case for configurable products
- $report['product_id'] = $item->children->first()->product_id;
- } else {
- // composites other than configurable
- $report['product_id'] = $item->product_id;
-
- foreach ($item->children as $children) {
- $childBaseTotal = $children->base_total;
-
- $itemDiscount = $childBaseTotal / ($item->base_total / 100);
-
- $children->discount = ($itemDiscount / 100) * $perItemDiscount;
-
- $children->discount = $children->base_total > $children->discount ? $children->discount : $children->base_total;
-
- $report['child_items']->push($children);
- }
- }
- } else {
- $report['product_id'] = $item->product_id;
- }
-
- $discount = round($perItemDiscount, 4) * $discQuantity;
- $discount = $discount <= $itemPrice * $discQuantity ? $discount : $itemPrice * $discQuantity;
-
- $report['discount'] = $discount;
- $report['formatted_discount'] = core()->currency($discount);
-
- $impact->push($report);
-
- $totalDiscount = $totalDiscount + $discount;
-
- unset($report);
- }
-
- $impact->discount = $totalDiscount;
- $impact->formatted_discount = core()->currency($impact->discount);
-
- return $impact;
- }
- }
-}
\ No newline at end of file
diff --git a/packages/Webkul/Discount/src/Actions/Cart/WholeCartToFixed.php b/packages/Webkul/Discount/src/Actions/Cart/WholeCartToFixed.php
deleted file mode 100644
index 7fbc39cd4..000000000
--- a/packages/Webkul/Discount/src/Actions/Cart/WholeCartToFixed.php
+++ /dev/null
@@ -1,24 +0,0 @@
-calculate($rule);
-
- return $result;
- }
-}
\ No newline at end of file
diff --git a/packages/Webkul/Discount/src/Actions/Cart/WholeCartToPercent.php b/packages/Webkul/Discount/src/Actions/Cart/WholeCartToPercent.php
deleted file mode 100644
index ffd334370..000000000
--- a/packages/Webkul/Discount/src/Actions/Cart/WholeCartToPercent.php
+++ /dev/null
@@ -1,24 +0,0 @@
-calculate($rule);
-
- return $result;
- }
-}
\ No newline at end of file
diff --git a/packages/Webkul/Discount/src/Actions/Catalog/Action.php b/packages/Webkul/Discount/src/Actions/Catalog/Action.php
deleted file mode 100644
index ddd2ddc56..000000000
--- a/packages/Webkul/Discount/src/Actions/Catalog/Action.php
+++ /dev/null
@@ -1,8 +0,0 @@
-discount_amount;
- $price = $product->price;
-
- if ($discountAmount <= $price) {
- $discount = $price - $discountAmount;
-
- return $discount;
- } else {
- return $price;
- }
- }
-}
\ No newline at end of file
diff --git a/packages/Webkul/Discount/src/Actions/Catalog/AdjustToPercent.php b/packages/Webkul/Discount/src/Actions/Catalog/AdjustToPercent.php
deleted file mode 100644
index 6c085a63a..000000000
--- a/packages/Webkul/Discount/src/Actions/Catalog/AdjustToPercent.php
+++ /dev/null
@@ -1,19 +0,0 @@
-discount_amount;
-
- $price = $product->price;
-
- $discount = ($discountAmount / 100) * $price;
-
- return $discount;
- }
-}
\ No newline at end of file
diff --git a/packages/Webkul/Discount/src/Actions/Catalog/FixedAmount.php b/packages/Webkul/Discount/src/Actions/Catalog/FixedAmount.php
deleted file mode 100644
index d37f65df9..000000000
--- a/packages/Webkul/Discount/src/Actions/Catalog/FixedAmount.php
+++ /dev/null
@@ -1,20 +0,0 @@
-discount_amount;
- $price = $product->price;
-
- if ($discountAmount <= $price) {
- return $discountAmount;
- } else {
- return $price;
- }
- }
-}
\ No newline at end of file
diff --git a/packages/Webkul/Discount/src/Actions/Catalog/PercentOfOriginal.php b/packages/Webkul/Discount/src/Actions/Catalog/PercentOfOriginal.php
deleted file mode 100644
index 4fc7c0408..000000000
--- a/packages/Webkul/Discount/src/Actions/Catalog/PercentOfOriginal.php
+++ /dev/null
@@ -1,19 +0,0 @@
-discount_amount;
-
- $price = $product->price;
-
- $discount = ($discountAmount / 100) * $price;
-
- return $discount;
- }
-}
\ No newline at end of file
diff --git a/packages/Webkul/Discount/src/Config/discount-rules.php b/packages/Webkul/Discount/src/Config/discount-rules.php
deleted file mode 100644
index 7f33b90e5..000000000
--- a/packages/Webkul/Discount/src/Config/discount-rules.php
+++ /dev/null
@@ -1,18 +0,0 @@
- [
- 'fixed_amount' => 'Webkul\Discount\Actions\Cart\FixedAmount',
- 'percent_of_product' => 'Webkul\Discount\Actions\Cart\PercentOfProduct',
- 'whole_cart_to_fixed' => 'Webkul\Discount\Actions\Cart\WholeCartToFixed',
- 'whole_cart_to_percent' => 'Webkul\Discount\Actions\Cart\WholeCartToPercent'
- ],
-
- 'catalog' => [
- 'fixed_amount' => 'Webkul\Discount\Actions\Catalog\FixedAmount',
- 'final_price_to_percent' => 'Webkul\Discount\Actions\Catalog\AdjustToPercent',
- 'percent_of_original' => 'Webkul\Discount\Actions\Catalog\PercentOfOriginal',
- 'to_discount_value' => 'Webkul\Discount\Actions\Catalog\AdjustToDiscountValue'
- ]
-];
\ No newline at end of file
diff --git a/packages/Webkul/Discount/src/Config/rule-conditions.php b/packages/Webkul/Discount/src/Config/rule-conditions.php
deleted file mode 100644
index f12629492..000000000
--- a/packages/Webkul/Discount/src/Config/rule-conditions.php
+++ /dev/null
@@ -1,174 +0,0 @@
- [
- 'all_are_true' => 'All conditions are true',
- 'any_is_true' => 'Any condition is true',
- ],
-
- 'cart' => [
- 'actions' => [
- 'fixed_amount' => 'Apply as fixed amount',
- 'percent_of_product' => 'Percentage of product',
- 'whole_cart_to_fixed' => 'Adjust whole cart to fixed amount',
- 'whole_cart_to_percent' => 'Adjust whole cart to percent'
- ],
-
- 'validation' => [
- 0 => 'percent_of_product',
- 1 => 'fixed_amount',
- 2 => 'whole_cart_to_percent',
- 3 => 'whole_cart_to_fixed'
- ],
-
- 'conditions' => [
- 'numeric' => [
- '=' => 'Equals',
- '>=' => 'Greater or equals',
- '<=' => 'Lesser or equals',
- '>' => 'Greater than',
- '<' => 'Lesser than'
- ],
-
- 'string' => [
- '=' => 'Equals',
- // '>=' => 'Greater or equals',
- // '<=' => 'Lesser or equals',
- // '>' => 'Greater than',
- // '<' => 'Lesser than',
- '{}' => 'Contains',
- '!{}' => 'Does not contains'
- ],
-
- 'boolean' => [
- 0 => 'True/Yes',
- 1 => 'False/No'
- ],
-
- 'symbols' => [
- '=' => 'equals',
- '>=' => 'greater_or_equals',
- '<=' => 'lesser_or_equals',
- '>' => 'greater_than',
- '<' => 'lesser_than',
- '{}' => 'contains',
- '={}' => 'is_one_of',
- '!={}' => 'is_not_one_of',
- '!{}' => 'does_not_contains'
- ]
- ],
-
- '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'
- ]
- ]
- ],
-
- 'catalog' => [
- 'actions' => [
- 'percent_of_original' => 'Percentage of product',
- 'fixed_amount' => 'Apply as fixed amount',
- 'final_price_to_percent' => 'Adjust price to percentage',
- 'to_discount_value' => 'Adjust price to given amount'
- ],
-
- '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',
- ],
-
- 'string' => [
- '=' => 'Equals',
- '>=' => 'Greater or equals',
- '<=' => 'Lesser or equals',
- '>' => 'Greater than',
- '<' => 'Lesser than',
- '{}' => 'Contains',
- '!{}' => 'Does not contains'
- ],
-
- 'select' => [
- '=' => 'Equals',
- '{}' => 'Contains',
- '!{}' => 'Does not contains'
- ],
-
- 'multiselect' => [
- '=' => 'Equals',
- '{}' => 'Contains',
- '!{}' => 'Does not contains'
- ],
-
- 'boolean' => [
- 0 => 'True/Yes',
- 1 => 'False/No'
- ],
-
- 'symbols' => [
- '=' => 'equals',
- '>=' => 'greater_or_equals',
- '<=' => 'lesser_or_equals',
- '>' => 'greater_than',
- '<' => 'lesser_than',
- '{}' => 'contains',
- '={}' => 'is_one_of',
- '!={}' => 'is_not_one_of',
- '!{}' => 'does_not_contains'
- ]
- ]
- ]
-];
\ No newline at end of file
diff --git a/packages/Webkul/Discount/src/Contracts/CartRule.php b/packages/Webkul/Discount/src/Contracts/CartRule.php
deleted file mode 100644
index c6da453eb..000000000
--- a/packages/Webkul/Discount/src/Contracts/CartRule.php
+++ /dev/null
@@ -1,7 +0,0 @@
-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');
- }
-}
diff --git a/packages/Webkul/Discount/src/Database/Migrations/2019_05_24_113949_create_cart_rule_coupons_usage_table.php b/packages/Webkul/Discount/src/Database/Migrations/2019_05_24_113949_create_cart_rule_coupons_usage_table.php
deleted file mode 100644
index 60f23900e..000000000
--- a/packages/Webkul/Discount/src/Database/Migrations/2019_05_24_113949_create_cart_rule_coupons_usage_table.php
+++ /dev/null
@@ -1,39 +0,0 @@
-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');
- }
-}
diff --git a/packages/Webkul/Discount/src/Helpers/Cart/ConvertXToProductId.php b/packages/Webkul/Discount/src/Helpers/Cart/ConvertXToProductId.php
deleted file mode 100644
index 9c49d609b..000000000
--- a/packages/Webkul/Discount/src/Helpers/Cart/ConvertXToProductId.php
+++ /dev/null
@@ -1,292 +0,0 @@
-category = $category;
-
- $this->attribute = $attributeRepository;
-
- $this->product = $product;
-
- $this->attributeOptionRepository = $attributeOptionRepository;
-
- $this->cartRule = $cartRule;
-
- $this->pav = $pav;
-
- $this->conditionSymbols = config('pricerules.cart.conditions.symbols');
- }
-
- /**
- * Collects the attribute and category conditions
- *
- * @param Integer $ruleId
- *
- * @param Object $attrribute_conditions
- */
- public function convertX($ruleId, $attribute_conditions)
- {
- $attributeConditions = $attribute_conditions;
-
- $categoryValues = $attributeConditions->categories ?? null;
-
- $attributeValues = $attributeConditions->attributes ?? null;
-
- if (! isset($categoryValues) && ! isset($attributeValues))
- return false;
-
- $categoryResult = collect();
-
- if (isset($categoryValues) && count($categoryValues))
- $categoryResult = $this->convertFromCategories($categoryValues);
-
- $attributeResult = collect();
-
- if (isset($attributeValues) && count($attributeValues))
- $attributeResult = $this->convertFromAttributes($attributeValues);
-
- // now call the function that will find all the unique product ids
- $productIDs = $this->findAllUniqueIds($attributeResult, $categoryResult);
-
- // save the product ids against the cart rules
- return $this->saveIDs($ruleId, $productIDs) ? true : false;
- }
-
- /**
- * This method will return product id from the attribute and attribute option params
- *
- * @return array
- */
- public function convertFromAttributes($attributeOptions)
- {
- $products = collect();
-
- foreach ($attributeOptions as $attributeOption) {
- $selectedOptions = $attributeOption->value;
-
- if ($attributeOption->type == 'select' || $attributeOption->type == 'multiselect') {
- $attribute = $this->attribute->findWhere(['code' => $attributeOption->attribute]);
-
- $attributeOptions = $attribute->first()->options;
-
- $selectedAttributeOptions = collect();
-
- foreach ($attributeOptions as $attributeOption) {
- foreach ($selectedOptions as $key => $value) {
- if ($attributeOption->id == $value)
- $selectedAttributeOptions->push($attributeOption);
- }
- }
-
- foreach($selectedAttributeOptions as $selectedAttributeOption) {
- $typeColumn = $this->pav::$attributeTypeFields[$attribute->first()->type];
-
- $pavResults = $this->pav->where(
- "{$typeColumn}", $selectedAttributeOption->id
- )->get();
-
- foreach ($pavResults as $pavResult) {
- if ($pavResult->product->type == 'simple')
- $products->push($pavResult->product);
- }
- }
- } else {
- $attribute = $this->attribute->findWhere([
- 'code' => $attributeOption->attribute
- ]);
-
- $pavValues = $attribute->first();
-
- $selectedAttributeValues = collect();
-
- $foundProducts = collect();
-
- if ($attributeOption->attribute == 'sku') {
- $testValue = $attributeOption->value;
- $testCondition = $attributeOption->condition;
-
- if ($testCondition == '{}') {
- $foundProducts = $this->product->findWhere([
- ['sku', 'like', '%'.$testValue.'%'],
- ])->flatten()->all();
- } else if ($testCondition == '!{}') {
- $foundProducts = $this->product->findWhere([
- ['sku', 'not like', '%'.$testValue.'%'],
- ])->flatten()->all();
- } else if ($testCondition == '=') {
- $foundProducts = $this->product->findWhere([
- ['sku', '=', $testValue],
- ])->flatten()->all();
- }
- }
-
- foreach($foundProducts as $foundProduct) {
- $products->push($foundProduct);
- }
- }
- }
-
- return $products;
- }
-
- /**
- * This method will return product id from the attribute and attribute option params
- *
- * @param Collection $categories
- *
- * @return array
- */
- public function convertFromCategories($categories)
- {
- $products = collect();
-
- foreach ($categories as $category) {
- $data = $this->getAll($category->id);
-
- if ($data->count()) {
- $products->push($data);
-
- unset($data);
- }
- }
-
- return $products->flatten()->all();
- }
-
- /**
- * This method will remove the duplicates from the array and merge all the items into single array
- *
- * @param array
- *
- * @return array
- */
- public function findAllUniqueIds(...$data)
- {
- $attributeResult = $data[0] ?? collect();
- $categoryResult = $data[1] ?? collect();
-
- // find matched attribute options product ids
- $mergedCollection = $attributeResult->merge($categoryResult);
-
- $productIDs = collect();
-
- foreach ($mergedCollection as $merged) {
- $productIDs->push($merged->id);
- }
-
- // find all the unique product ids
- return $productIDs->unique()->flatten()->all();
- }
-
- /**
- * This method will save the product ids in the datastore
- *
- * @param integer $ruleId
- *
- * @param array $productIDs
- *
- * @return boolean
- */
- public function saveIDs($ruleId, $productIDs)
- {
- $cartRule = $this->cartRule->find($ruleId);
-
- $productIDs = implode(',', $productIDs);
-
- return $cartRule->update(['product_ids' => $productIDs]);
- }
-
- /**
- * To get all product ids lying in the criteria
- *
- * @param integer $categoryId
- *
- * @return Collection
- */
- public function getAll($categoryId = null)
- {
- return app('Webkul\Product\Repositories\ProductFlatRepository')->scopeQuery(function($query) use($categoryId) {
- $channel = request()->get('channel') ?: (core()->getCurrentChannelCode() ?: core()->getDefaultChannelCode());
-
- $locale = request()->get('locale') ?: app()->getLocale();
-
- $qb = $query->distinct()
- ->addSelect('product_flat.*')
- ->leftJoin('products', 'product_flat.product_id', '=', 'products.id')
- ->leftJoin('product_categories', 'products.id', '=', 'product_categories.product_id')
- ->where('product_flat.channel', $channel)
- ->where('product_flat.locale', $locale)
- ->whereNotNull('product_flat.url_key');
-
- if ($categoryId)
- $qb->where('product_categories.category_id', $categoryId);
-
- $qb->where('product_flat.status', 1);
-
- $qb->where('product_flat.visible_individually', 1);
-
- $queryBuilder = $qb->leftJoin('product_flat as flat_variants', function($qb) use($channel, $locale) {
- $qb->on('product_flat.id', '=', 'flat_variants.parent_id')
- ->where('flat_variants.channel', $channel)
- ->where('flat_variants.locale', $locale);
- });
-
- $qb = $qb->leftJoin('products as variants', 'products.id', '=', 'variants.parent_id');
-
- return $qb->groupBy('product_flat.id');
- })->get();
- }
-}
\ No newline at end of file
diff --git a/packages/Webkul/Discount/src/Helpers/Cart/CouponAbleRule.php b/packages/Webkul/Discount/src/Helpers/Cart/CouponAbleRule.php
deleted file mode 100644
index 892bcd14e..000000000
--- a/packages/Webkul/Discount/src/Helpers/Cart/CouponAbleRule.php
+++ /dev/null
@@ -1,57 +0,0 @@
-validateIfAlreadyApplied();
-
- $rules = $this->getApplicableRules($code);
-
- if ($rules->count() == 1) {
- $rule = $rules->first();
-
- $canApply = $this->canApply($rule);
-
- if ($canApply) {
- $this->save($rule);
-
- $this->updateCartItemAndCart($rule);
-
- return true;
- }
- } else {
- return false;
- }
-
- return false;
- }
-
- /**
- * Removes the already applied coupon on the current cart instance
- *
- * @return boolean
- */
- public function remove()
- {
- $cart = Cart::getCart();
-
- $existingRule = $this->cartRuleCart->findWhere(['cart_id' => $cart->id]);
-
- $this->clearDiscount();
-
- return true;
- }
-}
\ No newline at end of file
diff --git a/packages/Webkul/Discount/src/Helpers/Cart/Discount.php b/packages/Webkul/Discount/src/Helpers/Cart/Discount.php
deleted file mode 100644
index 415a6b657..000000000
--- a/packages/Webkul/Discount/src/Helpers/Cart/Discount.php
+++ /dev/null
@@ -1,994 +0,0 @@
-cartRule = $cartRule;
-
- $this->cartRuleCart = $cartRuleCart;
-
- $this->cartItem = $cartItem;
-
- $this->rules = config('discount-rules');
- }
-
- /**
- * Abstract method apply
- */
- abstract public function apply($code);
-
- /**
- * To find all the suitable rules that can be applied on the current cart
- *
- * @return collection $rules
- */
- public function getApplicableRules($code = null)
- {
- $rules = collect();
-
- if ($code != null) {
- $eligibleRules = $this->cartRule->findWhere(['use_coupon' => 1, 'status' => 1]);
-
- foreach($eligibleRules as $rule) {
- if ($rule->coupons->code == $code) {
- $rules->push($rule);
-
- break;
- }
- }
- } else {
- $rules = $this->cartRule->findWhere(['use_coupon' => 0, 'status' => 1]);
- }
-
- $filteredRules = collect();
-
- // time based constraints
- foreach ($rules as $rule) {
- if ($this->checkApplicability($rule)) {
- if ($rule->starts_from != null && $rule->ends_till == null) {
- if (Carbon::parse($rule->starts_from) < now()) {
- $rule->impact = $this->calculateImpact($rule);
-
- $filteredRules->push($rule);
- }
- } else if ($rule->starts_from == null && $rule->ends_till != null) {
- if (Carbon::parse($rule->ends_till) > now()) {
- $rule->impact = $this->calculateImpact($rule);
-
- $filteredRules->push($rule);
- }
- } else if ($rule->starts_from != null && $rule->ends_till != null) {
- if (Carbon::parse($rule->starts_from) < now() && now() < Carbon::parse($rule->ends_till)) {
- $rule->impact = $this->calculateImpact($rule);
-
- $filteredRules->push($rule);
- }
- } else {
- $rule->impact = $this->calculateImpact($rule);
-
- $filteredRules->push($rule);
- }
- }
- }
-
- return $filteredRules;
- }
-
- /**
- * To find that one rule that is going to be applied on the current cart
- *
- * @param Collection $rules
- *
- * @return CartRule $rule
- */
- public function breakTie($rules)
- {
- $result = $this->sortByLeastPriority($rules);
-
- if (count($result) > 1) {
- // check for max impact criteria
- if (count($result) > 1) {
- $result = $this->findMaxImpact($result);
-
- if (count($result) > 1) {
- $result = $this->findOldestRule($result);
-
- return $result;
- } else if (count($result) == 1) {
- return $result->first();
- } else {
- return collect();
- }
- } else if (count($result) == 1) {
- return $result->first();
- } else {
- return collect();
- }
- } else if (count($result) == 1) {
- return $result->first();
- } else {
- return collect();
- }
-
- return collect();
- }
-
- /**
- * To find the oldes rule
- *
- * @param Collection $rules
- *
- * @return CartRule $oldestRule
- */
- public function findOldestRule($rules)
- {
- $leastID = 999999999999;
-
- foreach ($rules as $index => $rule) {
- if ($rule->id < $leastID) {
- $leastID = $rule->id;
- $oldestRule = $rule;
- }
- }
-
- return $oldestRule;
- }
-
- /**
- * To sort the rules by the least priority
- *
- * @param Collection $rules
- *
- * @return Collection $rule
- */
- public function sortByLeastPriority($rules)
- {
- $sortedRules = collect();
-
- $minPriority = $rules->min('priority');
-
- foreach ($rules as $rule) {
- if ($rule->priority == $minPriority)
- $sortedRules->push($rule);
- }
-
- return $sortedRules;
- }
-
- /**
- * To check where rule ends other rules
- *
- * @param CartRule $rule
- *
- * @return $rule
- */
- public function isEndRule($rule)
- {
- if ($rule->end_other_rules) {
- return true;
- } else {
- return false;
- }
- }
-
- /**
- * To find whether rule can be applied or not
- *
- * @param CartRule $rule
- *
- * @return boolean
- */
- public function canApply($rule)
- {
- $cart = \Cart::getCart();
-
- $alreadyApplied = $this->cartRuleCart->findWhere(['cart_id' => $cart->id]);
-
- if ($alreadyApplied->count() && $alreadyApplied->first()->cart_rule->id == $rule->id) {
- if ($this->validateRule($alreadyApplied->first()->cart_rule)) {
- $this->reassess($alreadyApplied->first()->cart_rule, $cart);
-
- return false;
- } else {
- $this->clearDiscount();
-
- return true;
- }
- } else if ($alreadyApplied->count() && $alreadyApplied->first()->cart_rule->id != $rule->id && ! $alreadyApplied->first()->cart_rule->end_other_rules) {
- if ($rule->use_coupon) {
- if ($alreadyApplied->first()->cart_rule->use_coupon) {
- $rules = collect();
-
- $alreadyAppliedRule = $alreadyApplied->first()->cart_rule;
- $alreadyAppliedRule->impact = $this->calculateImpact($alreadyAppliedRule);
-
- $rule->impact = $this->calculateImpact($alreadyAppliedRule);
-
- $rules->push($alreadyAppliedRule);
- $rules->push($rule);
-
- $result = $this->breakTie($rules);
-
- if ($result->id == $rule->id) {
- return true;
- } else {
- return false;
- }
- } else {
- return true;
- }
- } else {
- // this case will work when non couponable rule is applied and another non couponable rule is created
- // again break tie
- $rules = collect();
-
- $alreadyAppliedRule = $alreadyApplied->first()->cart_rule;
- $alreadyAppliedRule->impact = $this->calculateImpact($alreadyAppliedRule);
-
- $rule->impact = $this->calculateImpact($alreadyAppliedRule);
-
- $rules->push($alreadyAppliedRule);
- $rules->push($rule);
-
- $result = $this->breakTie($rules);
-
- if ($result) {
- if ($result->id != $rule->id) {
- return true;
- } else {
- return false;
- }
- }
- }
- } else {
- return true;
- }
- }
-
- /**
- * To reassess the discount in case no. of items gets changed
- *
- * @return Void
- */
- public function reassess($rule)
- {
- $rule->impact = $this->calculateImpact($rule);
-
- $this->updateCartItemAndCart($rule);
-
- return $rule;
- }
-
- /**
- * To return cart rule which has the max impact
- *
- * @param Collection $rules
- *
- * @return Collection $rule
- */
- public function findMaxImpact($rules)
- {
- $maxImpact = collect();
-
- $maxDiscount = 0;
-
- if ($rules->count()) {
- $maxDiscount = $rules->max('impact.discount');
-
- foreach ($rules as $rule) {
- if ($rule->impact->discount == $maxDiscount)
- $maxImpact = $maxImpact->push($rule);
- }
- } else {
- return collect();
- }
-
- return $maxImpact;
- }
-
- /**
- * To calculate the impact of the rule
- *
- * @return collection
- */
- public function calculateImpact($rule)
- {
- $impact = $this->getActionInstance($rule);
-
- $outcome = $impact->calculate($rule);
-
- return $outcome;
- }
-
- /**
- * Return the instance of the related rule's action type
- *
- * @param CartRule $rule
- *
- * @return Object
- */
- public function getActionInstance($rule)
- {
- $this->rules = config('discount-rules');
-
- $actionType = new $this->rules['cart'][$rule->action_type]($rule);
-
- return $actionType;
- }
-
- /**
- * Checks whether rules is getting applied on current cart instance or not
- *
- * @param CartRule $rule
- *
- * @return Boolean
- */
- public function checkApplicability($rule)
- {
- $cart = \Cart::getCart();
-
- $timeBased = false;
-
- $channelBased = false;
-
- // time based constraints
- if ($rule->starts_from != null && $rule->ends_till == null) {
- if (Carbon::parse($rule->starts_from) < now())
- $timeBased = true;
- } else if ($rule->starts_from == null && $rule->ends_till != null) {
- if (Carbon::parse($rule->ends_till) > now())
- $timeBased = true;
- } else if ($rule->starts_from != null && $rule->ends_till != null) {
- if (Carbon::parse($rule->starts_from) < now() && now() < Carbon::parse($rule->ends_till))
- $timeBased = true;
- } else {
- $timeBased = true;
- }
-
- // channel based constraints
- foreach ($rule->channels as $channel) {
- if ($channel->channel_id == core()->getCurrentChannel()->id)
- $channelBased = true;
- }
-
- $customerGroupBased = false;
-
- // customer groups based constraints
- if (auth()->guard('customer')->check()) {
- foreach ($rule->customer_groups as $customer_group) {
- if (auth()->guard('customer')->user()->group->exists()) {
- if ($customer_group->customer_group_id == auth()->guard('customer')->user()->group->id)
- $customerGroupBased = true;
- }
- }
- } else {
- foreach ($rule->customer_groups as $customer_group) {
- if ($customer_group->customer_group->code == 'guest')
- $customerGroupBased = true;
- }
- }
-
- $conditionsBased = true;
-
- //check conditions
- if ($rule->conditions != null) {
- $conditions = json_decode(json_decode($rule->conditions));
-
- $test_mode = array_last($conditions);
-
- if ($test_mode->criteria == 'any_is_true')
- $conditionsBased = $this->testIfAnyConditionIsTrue($conditions, $cart);
-
- if ($test_mode->criteria == 'all_are_true')
- $conditionsBased = $this->testIfAllConditionAreTrue($conditions, $cart);
- }
-
- $partialMatch = 0;
-
- if ($rule->uses_attribute_conditions) {
- $productIDs = explode(',', $rule->product_ids);
-
- foreach ($productIDs as $productID) {
- foreach ($cart->items as $item) {
- if ($item->product_id == $productID)
- $partialMatch = 1;
- }
-
- $childrens = $item->children;
-
- foreach ($childrens as $children) {
- if ($children->product_id == $productID)
- $partialMatch = 1;
- }
- }
- }
-
- if ($channelBased && $customerGroupBased && $timeBased && $conditionsBased) {
- if ($rule->uses_attribute_conditions == 1 && $partialMatch) {
- return true;
- } else if ($rule->uses_attribute_conditions == 0) {
- return true;
- } else {
- return false;
- }
- } else {
- return false;
- }
- }
-
- /**
- * Save the rule in the CartRule for current cart instance
- *
- * @param CartRule $rule
- *
- * @return Boolean
- */
- public function save($rule)
- {
- $cart = \Cart::getCart();
-
- $alreadyApplied = $this->cartRuleCart->findWhere(['cart_id' => $cart->id]);
-
- if ($alreadyApplied->count()) {
- $result = $alreadyApplied->first()->update(['cart_rule_id' => $rule->id]);
- } else {
- $result = $this->cartRuleCart->create(['cart_id' => $cart->id, 'cart_rule_id' => $rule->id]);
- }
-
- return $result ? true : false;
- }
-
- /**
- * Apply on shipping
- *
- * @param CartRule $apploedRule
- *
- * @param Cart $cart
- *
- * @return void
- */
- public function applyOnShipping($appliedRule, $cart)
- {
- $cart = \Cart::getCart();
-
- if (isset($cart->selected_shipping_rate)) {
- if ($appliedRule->free_shipping && $cart->selected_shipping_rate->base_price > 0) {
- $cart->selected_shipping_rate->update(['price' => 0, 'base_price' => 0]);
- } else if ($appliedRule->free_shipping == 0 && $appliedRule->apply_to_shipping && $cart->selected_shipping_rate->base_price > 0) {
- $actionType = config('discount-rules')[$appliedRule->action_type];
-
- if ($appliedRule->apply_to_shipping) {
- $actionInstance = new $actionType;
-
- $discountOnShipping = $actionInstance->calculateOnShipping($cart);
-
- $discountOnShipping = ($discountOnShipping / 100) * $cart->selected_shipping_rate->base_price;
-
- $cart->selected_shipping_rate->update([
- 'price' => $cart->selected_shipping_rate->price - core()->convertPrice($discountOnShipping, $cart->cart_currency_code),
- 'base_price' => $cart->selected_shipping_rate->base_price - $discountOnShipping
- ]);
- }
- }
- }
- }
-
- /**
- * Resets the shipping for the current items in the cart
- *
- * @param Cart $cart
- *
- * @return Void
- */
- public function resetShipping($cart)
- {
- $cart = \Cart::getCart();
-
- if (isset($cart->selected_shipping_rate->carrier)) {
- $shippingRate = config('carriers')[$cart->selected_shipping_rate->carrier]['class'];
-
- $actualShippingRate = new $shippingRate;
- $actualShippingRate = $actualShippingRate->calculate();
-
- if (is_array($actualShippingRate)) {
- foreach($actualShippingRate as $actualRate) {
- if ($actualRate->method == $cart->selected_shipping_rate->method) {
- $actualShippingRate = $actualRate;
-
- break;
- }
- }
- }
-
- $actualShippingPrice = $actualShippingRate->price;
- $actualShippingBasePrice = $actualShippingRate->base_price;
- $cartShippingRate = $cart->selected_shipping_rate;
-
- $cartShippingRate->update(['price' => $actualShippingPrice, 'base_price' => $actualShippingBasePrice]);
- }
- }
-
- /**
- * Update discount for least worth item
- *
- * @param CartRule $rule
- *
- * @return Boolean
- */
- public function updateCartItemAndCart($rule)
- {
- $cart = Cart::getCart();
-
- $itemImpacts = $rule->impact;
-
- foreach ($itemImpacts as $itemImpact) {
- $item = $this->cartItem->findOneWhere(['id' => $itemImpact['item_id']]);
-
- if (isset($itemImpact['child_items']) && $itemImpact['child_items']->count()) {
- $totalItemDiscount = 0.0000;
-
- foreach ($itemImpact['child_items'] as $child) {
- $discount = $child->discount;
-
- $totalItemDiscount = $totalItemDiscount + $discount;
-
- unset($child->discount);
-
- $child->update([
- 'discount_amount' => core()->convertPrice($discount, $cart->cart_currency_code),
- 'base_discount_amount' => $discount
- ]);
-
- if ($rule->action_type == 'percent_of_product') {
- $child->update(['discount_percent' => $rule->discount_amount]);
- }
-
- if ($rule->use_coupon) {
- $coupon = $rule->coupons->code;
-
- $child->update(['coupon_code' => $coupon]);
- }
-
- $this->updateParent($child, $totalItemDiscount, $cartCurrencyCode = $cart->cart_currency_code);
- }
- } else {
- $item->update([
- 'discount_amount' => core()->convertPrice($itemImpact['discount'], $cart->cart_currency_code),
- 'base_discount_amount' => $itemImpact['discount']
- ]);
-
- if ($rule->action_type == 'percent_of_product') {
- $item->update(['discount_percent' => $rule->discount_amount]);
- }
-
- if ($rule->use_coupon) {
- $coupon = $rule->coupons->code;
-
- $item->update(['coupon_code' => $coupon]);
- }
- }
- }
-
- if ($rule->use_coupon) {
- $cart->update(['coupon_code' => $rule->coupons->code]);
- }
-
- // if ($rule->free_shipping || $rule->apply_on_shipping) {
- // $this->applyOnShipping($rule);
- // }
-
- Cart::collectTotals();
-
- return true;
- }
-
- /**
- * To update the discount on parent CartItem
- */
- private function updateParent($item, $discount, $currencyCode)
- {
- $parentItem = $this->cartItem->findOneWhere(['id' => $item->parent_id]);
-
- $parentItem->update([
- 'base_discount_amount' => $discount,
- 'discount_amount' => core()->convertPrice($discount, $currencyCode)
- ]);
- }
-
- /**
- * Removes any cart rule from the current cart instance
- *
- * @return Boolean
- */
- public function clearDiscount()
- {
- $cart = Cart::getCart();
-
- $cartItems = $cart->items;
-
- // remove all the discount properties from items
- foreach ($cartItems as $item) {
- $item->update([
- 'coupon_code' => NULL,
- 'discount_percent' => 0,
- 'discount_amount' => 0,
- 'base_discount_amount' => 0
- ]);
- }
-
- // remove all the discount properties from cart
- $cart->update([
- 'coupon_code' => NULL,
- 'discount_amount' => 0,
- 'base_discount_amount' => 0
- ]);
-
- // find & remove cart rule from cart rule cart resource
- $cartRuleCart = $this->cartRuleCart->findWhere(['cart_id' => $cart->id]);
-
- $cartRuleCart->first()->delete();
-
- return true;
- }
-
- /**
- * Validate the currently applied cart rule
- *
- * @param CartRule $rule
- *
- * @return Boolean
- */
- public function validateRule($rule)
- {
- $applicability = $this->checkApplicability($rule);
-
- if ($applicability && $rule->status) {
- return true;
- } else {
- return false;
- }
- }
-
- /**
- * Will validate already applied rule
- *
- * @return Void
- */
- public function validateIfAlreadyApplied()
- {
- $cart = \Cart::getCart();
-
- $alreadyAppliedRule = $this->cartRuleCart->findWhere(['cart_id' => $cart->id]);
-
- if ($alreadyAppliedRule->count()) {
- $alreadyAppliedCartRule = $alreadyAppliedRule->first()->cart_rule;
-
- $result = $this->validateRule($alreadyAppliedCartRule);
-
- if (! $result) {
- $this->clearDiscount();
-
- $alreadyAppliedRule->first()->delete();
- } else {
- $this->reassess($alreadyAppliedCartRule);
- }
- }
- }
-
- /**
- * Retreives all the payment methods from application config
- *
- * @return Array
- */
- public function getPaymentMethods()
- {
- $paymentMethods = config('paymentmethods');
-
- return $paymentMethods;
- }
-
- /**
- * Retreives all the shippin methods from the application config
- *
- * @return array
- */
- public function getShippingMethods()
- {
- $shippingMethods = config('carriers');
-
- return $shippingMethods;
- }
-
- /**
- * Checks the rule against the current cart instance whether rule conditions are applicable
- * or not
- *
- * @param Array $conditions
- *
- * @param Cart $cart
- *
- * @return Boolean
- */
- protected function testIfAllConditionAreTrue($conditions, $cart)
- {
- $paymentMethods = $this->getPaymentMethods();
-
- $shippingMethods = $this->getShippingMethods();
-
- array_pop($conditions);
-
- $shipping_address = $cart->getShippingAddressAttribute() ?? null;
-
- $shipping_method = $cart->selected_shipping_rate->method_title ?? null;
-
- $shipping_country = $shipping_address->country ?? null;
-
- $shipping_state = $shipping_address->state ?? null;
-
- $shipping_postcode = $shipping_address->postcode ?? null;
-
- $shipping_city = $shipping_address->city ?? null;
-
- $payment_method = isset($cart->payment) ? $paymentMethods[$cart->payment->method]['title'] : null;
-
- $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;
- }
-
- $result = true;
-
- foreach ($conditions as $condition) {
- $result = true;
-
- if (! isset($condition->attribute) || ! isset($condition->condition) || ! isset($condition->value) || ! isset($condition->type) || ! $condition->value != []) {
- $result = false;
-
- continue;
- }
-
- if (isset($condition->attribute)) {
- $actual_value = ${$condition->attribute};
- } else {
- $result = false;
- }
-
- if (isset($condition->value)) {
- $test_value = $condition->value;
-
- } else {
- $result = false;
- }
-
- if (isset($condition->condition)) {
- $test_condition = $condition->condition;
- }
- else {
- $result = false;
- }
-
- if ($condition->type == 'string') {
- $actual_value = strtolower($actual_value);
-
- $test_value = strtolower($test_value);
- }
-
- if ($test_condition == '=') {
- if ($actual_value != $test_value) {
- $result = false;
-
- break;
- }
- } else if ($test_condition == '>=') {
- if (! ($actual_value >= $test_value)) {
- $result = false;
-
- break;
- }
- } else if ($test_condition == '<=') {
- if (! ($actual_value <= $test_value)) {
- $result = false;
-
- break;
- }
- } else if ($test_condition == '>') {
- if (! ($actual_value > $test_value)) {
- $result = false;
-
- break;
- }
- } else if ($test_condition == '<') {
- if (! ($actual_value < $test_value)) {
- $result = false;
-
- break;
- }
- } else if ($test_condition == '{}') {
- if (! str_contains($actual_value, $test_value)) {
- $result = false;
-
- break;
- }
- } else if ($test_condition == '!{}') {
- if (str_contains($actual_value, $test_value)) {
- $result = false;
-
- break;
- }
- }
- }
-
- return $result;
- }
-
- /**
- * Checks the rule against the current cart instance whether rule conditions are applicable
- * or not
- *
- * @param Array $conditions
- *
- * @param Cart $cart
- *
- * @return Boolean
- */
- protected function testIfAnyConditionIsTrue($conditions, $cart)
- {
- $paymentMethods = $this->getPaymentMethods();
-
- $shippingMethods = $this->getShippingMethods();
-
- array_pop($conditions);
-
- $result = false;
-
- $shipping_address = $cart->getShippingAddressAttribute() ?? null;
-
- $shipping_method = $cart->selected_shipping_rate->method_title ?? null;
-
- $shipping_country = $shipping_address->country ?? null;
-
- $shipping_state = $shipping_address->state ?? null;
-
- $shipping_postcode = $shipping_address->postcode ?? null;
-
- $shipping_city = $shipping_address->city ?? null;
-
- $payment_method = isset($cart->payment) ? $paymentMethods[$cart->payment->method]['title'] : null;
-
- $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;
- }
-
- foreach ($conditions as $condition) {
- if (! isset($condition->attribute) || ! isset($condition->condition) || ! isset($condition->value)) {
- continue;
- }
-
- if (isset($condition->attribute)) {
- $actual_value = ${$condition->attribute};
- } else {
- $result = false;
- }
-
- if (isset($condition->value)) {
- $test_value = $condition->value;
- } else {
- $result = false;
- }
-
- if (isset($condition->condition)) {
- $test_condition = $condition->condition;
- } else {
- $result = false;
- }
-
- if ($condition->type == 'numeric' || $condition->type == 'string' || $condition->type == 'text') {
- if ($condition->type == 'string') {
- $actual_value = strtolower($actual_value);
-
- $test_value = strtolower($test_value);
- }
-
- if ($test_condition == '=') {
- if ($actual_value == $test_value) {
- $result = true;
-
- break;
- }
- } else if ($test_condition == '>=') {
- if ($actual_value >= $test_value) {
- $result = true;
-
- break;
- }
- } else if ($test_condition == '<=') {
- if ($actual_value <= $test_value) {
- $result = true;
-
- break;
- }
- } else if ($test_condition == '>') {
- if ($actual_value > $test_value) {
- $result = true;
-
- break;
- }
- } else if ($test_condition == '<') {
- if ($actual_value < $test_value) {
- $result = true;
-
- break;
- }
- } else if ($test_condition == '{}') {
- if (str_contains($actual_value, $test_value)) {
- $result = true;
-
- break;
- }
- } else if ($test_condition == '!{}') {
- if (! str_contains($actual_value, $test_value)) {
- $result = true;
-
- break;
- }
- }
- }
- }
-
- return $result;
- }
-}
\ No newline at end of file
diff --git a/packages/Webkul/Discount/src/Helpers/Cart/NonCouponAbleRule.php b/packages/Webkul/Discount/src/Helpers/Cart/NonCouponAbleRule.php
deleted file mode 100644
index 713cce2d4..000000000
--- a/packages/Webkul/Discount/src/Helpers/Cart/NonCouponAbleRule.php
+++ /dev/null
@@ -1,46 +0,0 @@
-validateIfAlreadyApplied();
-
- $rules = $this->getApplicableRules();
-
- if ($rules->count() == 1) {
- $rule = $rules->first();
-
- $canApply = $this->canApply($rule);
-
- if ($canApply && isset($rule->impact)) {
- $result = $this->save($rule);
-
- $this->updateCartItemAndCart($rule);
- }
- } else if ($rules->count() > 1) {
- $rule = $this->breakTie($rules);
-
- $canApply = $this->canApply($rule);
-
- if ($canApply) {
- $this->save($rule);
-
- $this->updateCartItemAndCart($rule);
- }
- } else {
- return false;
- }
- }
-}
\ No newline at end of file
diff --git a/packages/Webkul/Discount/src/Helpers/Cart/ValidatesDiscount.php b/packages/Webkul/Discount/src/Helpers/Cart/ValidatesDiscount.php
deleted file mode 100644
index f6b0b68c3..000000000
--- a/packages/Webkul/Discount/src/Helpers/Cart/ValidatesDiscount.php
+++ /dev/null
@@ -1,26 +0,0 @@
-validateIfAlreadyApplied();
- }
-}
\ No newline at end of file
diff --git a/packages/Webkul/Discount/src/Helpers/Catalog/Apply.php b/packages/Webkul/Discount/src/Helpers/Catalog/Apply.php
deleted file mode 100644
index 95c8f22e0..000000000
--- a/packages/Webkul/Discount/src/Helpers/Catalog/Apply.php
+++ /dev/null
@@ -1,542 +0,0 @@
- @prashant-webkul
- * @copyright 2019 Webkul Software Pvt Ltd (http://www.webkul.com)
- */
-class Apply extends Sale
-{
- /**
- * To hold the catalog rule repository instance
- */
- protected $catalogRule;
-
- /**
- * To maintain the list of deceased rules and remove their records if present
- */
- protected $activeRules;
-
- /**
- * To maintain the list of deceased rules and remove their records if present
- */
- protected $deceased;
-
- /**
- * Holds convertXToProductId instance
- */
- protected $convertX;
-
- /**
- * Hold catalog rule products repository instance
- */
- protected $catalogRuleProduct;
-
- /**
- * Hold catalog rule products price repository instance
- */
- protected $catalogRuleProductPrice;
-
- /**
- * Hold ProductRepository instance
- */
- protected $product;
-
- /**
- * To hold the rule classes
- */
- protected $rules;
-
- /**
- * @param CatalogRule $catalogRule
- */
- public function __construct(
- CatalogRule $catalogRule,
- ConvertX $convertX,
- CatalogRuleProducts $catalogRuleProduct,
- CatalogRuleProductsPrice $catalogRuleProductPrice,
- Product $product
- ) {
- $this->catalogRule = $catalogRule;
-
- $this->convertX = $convertX;
-
- $this->catalogRuleProduct = $catalogRuleProduct;
-
- $this->catalogRuleProductPrice = $catalogRuleProductPrice;
-
- $this->product = $product;
-
- $this->active = collect();
-
- $this->activeRules = collect();
-
- $this->deceased = collect();
-
- $this->rules = config('discount-rules.catalog');
- }
-
- /**
- * To apply the new catalog rules and sync previous rules changes,
- */
- public function apply()
- {
- $rules = $this->catalogRule->all();
-
- foreach ($rules as $rule) {
- $validated = $this->checkApplicability($rule);
-
- if ($validated) {
- $this->active->push($rule->id);
-
- $this->activeRules->push($rule);
- } else {
- $this->deceased->push($rule->id);
- }
- }
-
- if ($this->active->count()) {
- $productIDs = array();
-
- foreach ($this->activeRules as $rule) {
- $productIDs = $this->getProductIds($rule);
-
- if ($productIDs) {
- $productIDs = $this->expandProducts($productIDs);
-
- $this->setSale($rule, $productIDs);
- }
- }
- } else {
- // handle the deceased rules here or call the declutter handler over here
- // dd($this->deceased);
- }
- }
-
- /**
- * To set the sale price for products falling catalog rule criteria
- *
- * @param CatalogRule $catalogRule
- *
- * @return Void
- */
- public function setSale($rule, $productIDs)
- {
- if (is_array($productIDs)) {
- // apply on selected products
- foreach ($productIDs as $productID) {
- // catalog rule product resource is updated here
- $this->createOrUpdateCatalogRuleProduct($rule, $productID);
-
- // catalog rule product price resource is updated here
- $this->createOrUpdateCatalogRuleProductPrice($rule, $productID);
- }
- } else if ($productIDs == '*') {
- $this->catalogRuleProduct->createOrUpdateCatalogRuleProduct($rule, $productIDs);
-
- $this->catalogRuleProductPrice->createOrUpdateCatalogRuleProductPrice($rule, $productIDs);
- }
- }
-
- /**
- * Create or update catalog rule product resource
- *
- * @param CatalogRule $rule
- * @param Integer $productID
- *
- * @return Void
- */
- public function createOrUpdateCatalogRuleProduct($rule, $productID)
- {
- $channels = $rule->channels;
- $customerGroups = $rule->customer_groups;
-
- $channelsGroupsCross = $channels->crossJoin($customerGroups);
-
- if ($productID == '*') {
- $products = $this->product->all('id');
-
- foreach ($channelsGroupsCross as $channelGroup) {
- $channelId = $channelGroup[0]->channel_id;
- $groupId = $channelGroup[1]->customer_group_id;
-
- foreach ($products as $product) {
- $productID = $product->id;
-
- $catalogRuleProduct = $this->catalogRuleProduct->findWhere([
- 'channel_id' => $channelId,
- 'customer_group_id' => $groupId,
- 'product_id' => $productID
- ]);
-
- if ($catalogRuleProduct->count()) {
- // check for tie breaker rules and then update
- $product = $this->product->find($productID);
-
- $productPrice = $product->price;
-
- // check for tie breaker rules and then update
- $previousRuleID = $catalogRuleProduct->first()->catalog_rule_id;
-
- $newRuleID = $rule->id;
-
- $winnerRuleId = $this->breakTie($previousRuleID, $newRuleID, $product);
-
- $discountAmount = $this->getDiscountAmount($product, $rule);
-
- $data = [
- 'catalog_rule_id' => $rule->id,
- 'starts_from' => $rule->starts_from,
- 'ends_till' => $rule->ends_till,
- 'customer_group_id' => $groupId,
- 'channel_id' => $channelId,
- 'product_id' => $productID,
- 'action_code' => $rule->action_code,
- 'action_amount' => $discountAmount
- ];
-
- if ($rule->id == $winnerRuleId) {
- $this->catalogRuleProduct->create($data);
- } else {
- $this->catalogRuleProduct->update($data, $catalogRuleProduct->first()->id);
- }
- } else {
- $data = [
- 'catalog_rule_id' => $rule->id,
- 'starts_from' => $rule->starts_from,
- 'ends_till' => $rule->ends_till,
- 'customer_group_id' => $groupId,
- 'channel_id' => $channelId,
- 'product_id' => $productID,
- 'action_code' => $rule->action_code,
- 'action_amount' => $rule->discount_amount
- ];
-
- $this->catalogRuleProduct->create($data);
- }
- }
- }
- } else {
- foreach ($channelsGroupsCross as $channelGroup) {
- $channelId = $channelGroup[0]->channel_id;
- $groupId = $channelGroup[1]->customer_group_id;
-
- $catalogRuleProduct = $this->catalogRuleProduct->findWhere([
- 'channel_id' => $channelId,
- 'customer_group_id' => $groupId,
- 'product_id' => $productID
- ]);
-
- if ($catalogRuleProduct->count()) {
- $product = $this->product->find($productID);
- $productPrice = $product->price;
-
- // check for tie breaker rules and then update
- $previousRuleID = $catalogRuleProduct->first()->catalog_rule_id;
-
- $newRuleID = $rule->id;
-
- $winnerRuleId = $this->breakTie($previousRuleID, $newRuleID, $product);
-
- // update
- if ($winnerRuleId != $rule->id) {
- $discountAmount = $this->getDiscountAmount($product, $rule);
-
- $catalogRuleProduct->first()->update([
- 'catalog_rule_id' => $rule->id,
- 'starts_from' => $rule->starts_from,
- 'ends_till' => $rule->ends_till,
- 'customer_group_id' => $groupId,
- 'channel_id' => $channelId,
- 'product_id' => $productID,
- 'action_code' => $rule->action_code,
- 'action_amount' => $discountAmount
- ]);
- } else {
- //do reassessment
- }
- } else if ($catalogRuleProduct->count() == 0) {
- $product = $this->product->find($productID);
-
- $discountAmount = $this->getDiscountAmount($product, $rule);
-
- $data = [
- 'catalog_rule_id' => $rule->id,
- 'starts_from' => $rule->starts_from,
- 'ends_till' => $rule->ends_till,
- 'customer_group_id' => $groupId,
- 'channel_id' => $channelId,
- 'product_id' => $productID,
- 'action_code' => $rule->action_code,
- 'action_amount' => $discountAmount
- ];
-
- $this->catalogRuleProduct->create($data);
- } else {
- // do the reassessment updation if the cart rule action changes the new action and its amount needs to be updated
- }
- }
- }
- }
-
- /**
- * Create or update catalog rule product resource
- *
- * @param CatalogRule $rule
- * @param Integer $productID
- *
- * @return Void
- */
- public function createOrUpdateCatalogRuleProductPrice($rule, $productID)
- {
- $channels = $rule->channels;
- $customerGroups = $rule->customer_groups;
-
- $channelsGroupsCross = $channels->crossJoin($customerGroups);
-
- if ($productID == '*') {
- $products = $this->product->all('id');
-
- foreach ($channelsGroupsCross as $channelGroup) {
- $channelId = $channelGroup[0]->channel_id;
- $groupId = $channelGroup[1]->customer_group_id;
-
- foreach ($products as $product) {
- $productID = $product->id;
-
- $catalogRuleProductPrice = $this->catalogRuleProductPrice->findWhere([
- 'channel_id' => $channelId,
- 'customer_group_id' => $groupId,
- 'product_id' => $productID
- ]);
-
- if ($catalogRuleProductPrice->count()) {
- // check for tie breaker rules and then update
- $data = [
- 'catalog_rule_id' => $rule->id,
- 'starts_from' => $rule->starts_from,
- 'ends_till' => $rule->ends_till,
- 'customer_group_id' => $groupId,
- 'channel_id' => $channelId,
- 'product_id' => $productID,
- 'action_code' => $rule->action_code,
- 'action_amount' => $rule->discount_amount
- ];
-
- $this->catalogRuleProductPrice->update($data, $catalogRuleProductPrice->first()->id);
- } else {
- $data = [
- 'catalog_rule_id' => $rule->id,
- 'starts_from' => $rule->starts_from,
- 'ends_till' => $rule->ends_till,
- 'customer_group_id' => $groupId,
- 'channel_id' => $channelId,
- 'product_id' => $productID,
- 'action_code' => $rule->action_code,
- 'action_amount' => $rule->discount_amount
- ];
-
- $this->catalogRuleProductPrice->create($data);
- }
- }
- }
- } else {
- foreach ($channelsGroupsCross as $channelGroup) {
- $channelId = $channelGroup[0]->channel_id;
- $groupId = $channelGroup[1]->customer_group_id;
-
- $catalogRuleProduct = $this->catalogRuleProduct->findWhere([
- 'channel_id' => $channelId,
- 'customer_group_id' => $groupId,
- 'product_id' => $productID
- ]);
-
- $catalogRuleProductPrice = $this->catalogRuleProductPrice->findWhere([
- 'channel_id' => $channelId,
- 'customer_group_id' => $groupId,
- 'product_id' => $productID
- ]);
-
- if ($catalogRuleProductPrice->count()) {
- $catalogRuleProduct = $catalogRuleProduct->first();
-
- $product = $this->product->find($productID);
-
- $productPrice = $product->price - $catalogRuleProduct->action_amount;
-
- $winnerRuleId = $this->breakTie($catalogRuleProduct->catalog_rule_id, $rule->id, $product);
-
- if ($winnerRuleId != $rule->id) {
- $data = [
- 'catalog_rule_id' => $rule->id,
- 'starts_from' => $rule->starts_from,
- 'ends_till' => $rule->ends_till,
- 'customer_group_id' => $groupId,
- 'channel_id' => $channelId,
- 'product_id' => $productID,
- 'rule_price' => $productPrice
- ];
-
- $catalogRuleProductPrice->first()->update($data);
- } else {
- // do reassement
- }
- } else if ($catalogRuleProductPrice->count() == 0) {
- $catalogRuleProduct = $catalogRuleProduct->first();
-
- $discountAmount = $catalogRuleProduct->action_amount;
-
- $product = $this->product->find($productID);
-
- $productPrice = $product->price - $discountAmount;
-
- $data = [
- 'catalog_rule_id' => $rule->id,
- 'starts_from' => $rule->starts_from,
- 'ends_till' => $rule->ends_till,
- 'customer_group_id' => $groupId,
- 'channel_id' => $channelId,
- 'product_id' => $productID,
- 'rule_price' => $productPrice
- ];
-
- $this->catalogRuleProductPrice->create($data);
- } else {
- // do the reassessment updation if the cart rule action changes the new action and its amount needs to be updated
- }
- }
- }
- }
-
- /**
- * Get discount amount for the rule and product
- *
- * @return Decimal $discountAmount
- */
- public function getDiscountAmount($product, $rule)
- {
-
- $actionClass = config('discount-rules.catalog')[$rule->action_code];
-
- $actionInstance = new $actionClass();
-
- $discountAmount = $actionInstance->calculate($rule, $product);
-
- return $discountAmount;
- }
-
- /**
- * To expand the productIDs of configurable products
- *
- * @param Array $productIDs
- *
- * @return Array
- */
- protected function expandProducts($productIDs)
- {
- $products = app('Webkul\Product\Repositories\ProductRepository');
-
- $newProductIDs = collect();
-
- foreach ($productIDs as $productID) {
- $product = $products->find($productID);
-
- if (ProductType::hasVariants($product->type)) {
- $variants = $product->variants;
-
- foreach($variants as $variant) {
- $newProductIDs->push($variant->id);
- }
- } else {
- $newProductIDs->push($productID);
- }
- }
-
- if ($newProductIDs->count()) {
- return $newProductIDs->toArray();
- } else {
- return [];
- }
- }
-
- /**
- * To break tie between two rules
- *
- * @param Integer $previousRuleID
- * @param Integer $newRuleID
- *
- * @return String $id
- */
- public function breakTie($previousRuleID, $newRuleID, $product)
- {
- $oldRule = $this->catalogRule->find($previousRuleID);
-
- $newRule = $this->catalogRule->find($newRuleID);
-
- if ($oldRule->ends_other_rules) {
- return $oldRule->id;
- } else {
- $oldRuleDiscount = $this->getDiscountAmount($product, $oldRule);
-
- $newRuleDiscount = $this->getDiscountAmount($product, $newRule);
-
- if ($newRuleDiscount > $oldRuleDiscount) {
- return $newRule->id;
- } else {
- return $oldRule->id;
- }
- }
- }
-
- /**
- * To declutter the catalog rules that are either inactive or deleted
- *
- * @return Boolean
- */
- public function deClutter()
- {
- $rules = $this->catalogRule->all();
-
- foreach ($rules as $rule) {
- $validated = $this->checkApplicability($rule);
-
- if (! $validated) {
- $this->deceased->push($rule->id);
- }
- }
-
- if (count($this->deceased)) {
- $count = 0;
-
- foreach ($this->deceased as $deceased) {
- $cartRuleProducts = $this->catalogRuleProduct->findWhere(['catalog_rule_id' => $deceased]);
-
- $cartRuleProductsPrice = $this->catalogRuleProductPrice->findWhere(['catalog_rule_id' => $deceased]);
-
- // obvious logic for removing entries as entries in both storage needs to be exactly equal for a product
- foreach ($cartRuleProducts as $cartRuleProduct) {
- // deletes cartRuleProducts resource
- $cartRuleProduct->delete();
-
- // deletes cartRuleProductsPrice resource
- $cartRuleProductsPrice->delete();
- }
- }
-
- return true;
- } else {
- return false;
- }
- }
-}
\ No newline at end of file
diff --git a/packages/Webkul/Discount/src/Helpers/Catalog/ConvertXToProductId.php b/packages/Webkul/Discount/src/Helpers/Catalog/ConvertXToProductId.php
deleted file mode 100644
index b44eaea8b..000000000
--- a/packages/Webkul/Discount/src/Helpers/Catalog/ConvertXToProductId.php
+++ /dev/null
@@ -1,272 +0,0 @@
- @prashant-webkul
- * @copyright 2019 Webkul Software Pvt Ltd (http://www.webkul.com)
- */
-class ConvertXToProductId
-{
- /**
- * CategoryRepository instance
- */
- protected $category;
-
- /**
- * AttributeRepository instance
- */
- protected $attribute;
-
- /**
- * ProductRepository instance
- */
- protected $product;
-
- /**
- * AttributeOptionRepository instance
- */
- protected $attributeOption;
-
- /**
- * CatalogRuleRepository instance
- */
- protected $catalogRule;
-
- /**
- * ProductAttributeValueRepository instance
- */
- protected $pav;
-
- /**
- * Condition symbols for matching the criteria with attributes selected
- */
- protected $symbols;
-
- public function __construct(
- Category $category,
- Attribute $attribute,
- Product $product,
- AttributeOption $attributeOption,
- CatalogRule $catalogRule,
- ProductAttributeValue $pav
- ) {
- $this->category = $category;
-
- $this->attribute = $attribute;
-
- $this->product = $product;
-
- $this->attributeOption = $attributeOption;
-
- $this->catalogRule = $catalogRule;
-
- $this->pav = $pav;
-
- $this->conditionSymbols = config('pricerules.cart.conditions.symbols');
- }
-
- public function convertX($attributeConditions)
- {
- $categoryValues = $attributeConditions->categories;
-
- $attributeValues = $attributeConditions->attributes;
-
- if (! isset($categoryValues) && ! isset($attributeValues))
- return false;
-
- $categoryResult = collect();
-
- if (isset($categoryValues) && count($categoryValues))
- $categoryResult = $this->convertFromCategories($categoryValues);
-
- $attributeResult = collect();
-
- if (isset($attributeValues) && count($attributeValues))
- $attributeResult = $this->convertFromAttributes($attributeValues);
-
- // now call the function that will find all the unique product ids
- $productIDs = $this->findAllUniqueIds($attributeResult, $categoryResult);
-
- return $productIDs;
- }
-
- /**
- * This method will return product id from the attribute and attribute option params
- *
- * @return array
- */
- public function convertFromAttributes($attributeOptions)
- {
- $products = collect();
-
- foreach ($attributeOptions as $attributeOption) {
- if (isset($attributeOption->type) && $attributeOption->attribute != null && $attributeOption->condition != null && $attributeOption->value != [] && $attributeOption->type != null) {
- $selectedOptions = $attributeOption->value;
-
- if ($attributeOption->type == 'select' || $attributeOption->type == 'multiselect') {
- $attribute = $this->attribute->findWhere(['code' => $attributeOption->attribute]);
-
- $attributeOptions = $attribute->first()->options;
-
- $selectedAttributeOptions = collect();
-
- foreach ($attributeOptions as $attributeOption) {
- foreach ($selectedOptions as $key => $value) {
- if ($attributeOption->id == $value)
- $selectedAttributeOptions->push($attributeOption);
- }
- }
-
- foreach ($selectedAttributeOptions as $selectedAttributeOption) {
- $typeColumn = $this->pav::$attributeTypeFields[$attribute->first()->type];
-
- $pavResults = $this->pav->where(
- "{$typeColumn}",
- $selectedAttributeOption->id
- )->get();
-
- foreach ($pavResults as $pavResult) {
- if ($pavResult->product->type == 'simple')
- $products->push($pavResult->product);
- }
- }
- } else {
- $attribute = $this->attribute->findWhere(['code' => $attributeOption->attribute]);
-
- $pavValues = $attribute->first();
-
- $selectedAttributeValues = collect();
-
- if ($attributeOption->attribute == 'sku') {
- $testValue = $attributeOption->value;
- $testCondition = $attributeOption->condition;
-
- if ($testCondition == '{}') {
- $foundProducts = $this->product->findWhere([
- ['sku', 'like', '%' . $testValue . '%'],
- ['type', 'NOT IN', ProductType::getAllTypesHavingVariants()]
- ])->flatten()->all();
- } else if ($testCondition == '!{}') {
- $foundProducts = $this->product->findWhere([
- ['sku', 'not like', '%' . $testValue . '%'],
- ['type', 'NOT IN', ProductType::getAllTypesHavingVariants()]
- ])->flatten()->all();
- } else if ($testCondition == '=') {
- $foundProducts = $this->product->findWhere([
- ['sku', '=', $testValue],
- ['type', 'NOT IN', ProductType::getAllTypesHavingVariants()]
- ])->flatten()->all();
- }
- }
-
- foreach ($foundProducts as $foundProduct) {
- $products->push($foundProduct);
- }
- }
- }
- }
-
- return $products;
- }
-
- /**
- * This method will return product id from the attribute and attribute option params
- *
- * @param Collection $categories
- *
- * @return array
- */
- public function convertFromCategories($categories)
- {
- $products = collect();
-
- foreach ($categories as $category) {
- $data = $this->getAll($category->id);
-
- if ($data->count()) {
- $products->push($data);
-
- unset($data);
- }
- }
-
- return $products->flatten()->all();
- }
-
- /**
- * This method will remove the duplicates from the array and merge all the items into single array
- *
- * @param array
- *
- * @return array
- */
- public function findAllUniqueIds(...$data)
- {
- $attributeResult = $data[0] ?? collect();
- $categoryResult = $data[1] ?? collect();
-
- // find matched attribute options product ids
- $mergedCollection = $attributeResult->merge($categoryResult);
-
- $productIDs = collect();
-
- foreach ($mergedCollection as $merged) {
- $productIDs->push($merged->id);
- }
-
- // find all the unique product ids
- $productIDs = $productIDs->unique();
-
- return $productIDs->flatten()->all();
- }
-
- /**
- * To get all product ids lying in the criteria
- *
- * @param integer $categoryId
- *
- * @return Collection
- */
- public function getAll($categoryId = null)
- {
- $results = app('Webkul\Product\Repositories\ProductFlatRepository')->scopeQuery(function ($query) use ($categoryId) {
-
- $channel = request()->get('channel') ?: (core()->getCurrentChannelCode() ?: core()->getDefaultChannelCode());
-
- $locale = request()->get('locale') ?: app()->getLocale();
-
- $qb = $query->distinct()
- ->select('products.id')
- ->leftJoin('products', 'product_flat.product_id', '=', 'products.id')
- ->leftJoin('product_categories', 'products.id', '=', 'product_categories.product_id')
- ->whereNotNull('product_flat.url_key');
-
- if ($categoryId) {
- $qb->where('product_categories.category_id', $categoryId);
- }
-
- $qb->where('product_flat.status', 1);
-
- $qb->where('product_flat.visible_individually', 1);
-
- $queryBuilder = $qb->leftJoin('product_flat as flat_variants', function ($qb) use ($channel, $locale) {
- $qb->on('product_flat.id', '=', 'flat_variants.parent_id');
- });
-
- return $qb->groupBy('product_flat.id');
- })->get();
-
- return $results;
- }
-}
diff --git a/packages/Webkul/Discount/src/Helpers/Catalog/Sale.php b/packages/Webkul/Discount/src/Helpers/Catalog/Sale.php
deleted file mode 100644
index 294e61ef2..000000000
--- a/packages/Webkul/Discount/src/Helpers/Catalog/Sale.php
+++ /dev/null
@@ -1,85 +0,0 @@
- @prashant-webkul
- * @copyright 2019 Webkul Software Pvt Ltd (http://www.webkul.com)
- */
-abstract class Sale
-{
- abstract function apply();
-
- /**
- * To validate rule
- *
- * @param CatalogRule $rule
- *
- * @return Boolean
- */
- public function checkApplicability($rule)
- {
- $cart = \Cart::getCart();
-
- $timeBased = false;
-
- $status = false;
-
- // time based constraints
- if ($rule->starts_from != null && $rule->ends_till == null) {
- if (Carbon::parse($rule->starts_from) < now())
- $timeBased = true;
- } else if ($rule->starts_from == null && $rule->ends_till != null) {
- if (Carbon::parse($rule->ends_till) > now())
- $timeBased = true;
- } else if ($rule->starts_from != null && $rule->ends_till != null) {
- if (Carbon::parse($rule->starts_from) < now() && now() < Carbon::parse($rule->ends_till))
- $timeBased = true;
- } else {
- $timeBased = true;
- }
-
- if ($rule->status)
- $status = true;
-
- if ($timeBased && $status) {
- return true;
- } else {
- return false;
- }
- }
-
- /**
- * Function to maintain products and catalog rule
- *
- * @param CatalogRule $rule
- *
- * @return String|NULL
- */
- public function getProductIds($rule)
- {
- if ($rule->conditions) {
- $conditions = $rule->conditions;
-
- while(gettype($conditions) == 'string') {
- $conditions = json_decode($conditions);
- }
-
- $productIDs = $this->convertX->convertX($conditions);
- } else {
- $productIDs = '*';
- }
-
- return $productIDs;
- }
-
- /**
- * Function to maintain products, catalog rule, price
- */
-
-}
\ No newline at end of file
diff --git a/packages/Webkul/Discount/src/Http/Controllers/CartRuleController.php b/packages/Webkul/Discount/src/Http/Controllers/CartRuleController.php
deleted file mode 100644
index cd85e7638..000000000
--- a/packages/Webkul/Discount/src/Http/Controllers/CartRuleController.php
+++ /dev/null
@@ -1,573 +0,0 @@
- @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;
-
- /**
- * 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 category repository instance
- */
- protected $category;
-
- /**
- * To hold attribute repository instance
- */
- protected $attribute;
-
- /**
- * To hold the cart repository instance
- */
- protected $cart;
-
- /**
- * Convert X To Product ID.
- *
- */
- protected $convertX;
-
- public function __construct(
- CartRule $cartRule,
- CartRuleCoupons $cartRuleCoupon,
- CartRuleLabels $cartRuleLabel,
- Attribute $attribute,
- Category $category,
- ConvertX $convertX
- )
- {
- $this->_config = request('_config');
-
- $this->cartRule = $cartRule;
-
- $this->cartRuleCoupon = $cartRuleCoupon;
-
- $this->cartRuleLabel = $cartRuleLabel;
-
- $this->attribute = $attribute;
-
- $this->category = $category;
-
- $this->convertX = $convertX;
-
- $this->appliedConfig = config('pricerules.cart');
- }
-
- /**
- * @return \Illuminate\View\View
- */
- public function index()
- {
- return view($this->_config['view']);
- }
-
- /**
- * @return \Illuminate\View\View
- */
- public function create()
- {
- return view($this->_config['view'])->with('cart_rule', [$this->appliedConfig, $this->category->getPartial(), $this->getStatesAndCountries(), $this->attribute->getPartial()]);
- }
-
- /**
- * Stores the response from cart rule store page to datastore
- *
- * @return redirect
- */
- public function store()
- {
- $this->validate(request(), [
- 'name' => 'required|string|unique:cart_rules,name',
- 'description' => 'string',
- 'starts_from' => 'nullable|date',
- 'ends_till' => 'nullable|date|after_or_equal:starts_from',
- '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 = request()->all();
-
- $attribute_conditions = $data['all_attributes'];
- unset($data['all_attributes']);
-
- // unset token
- unset($data['_token']);
-
- // check if starts_from is null
- if ($data['starts_from'] == "") {
- $data['starts_from'] = null;
- }
-
- // check if end_till is null
- if ($data['ends_till'] == "") {
- $data['ends_till'] = null;
- }
-
- // customer groups
- $customer_groups = $data['customer_groups'];
-
- // unset customer groups
- unset($data['customer_groups']);
-
- // unset criteria
- unset($data['criteria']);
-
- // channels
- $channels = $data['channels'];
-
- // unset channels
- unset($data['channels']);
-
- // make labels
- $labels = $data['label'];
-
- // unset labels
- unset($data['label']);
-
- while (gettype($attribute_conditions) == 'string') {
- $attribute_conditions = json_decode($attribute_conditions);
- }
-
- if (! isset($attribute_conditions) || ! (count($attribute_conditions->categories) || count($attribute_conditions->attributes))) {
- $data['uses_attribute_conditions'] = 0;
-
- $data['actions'] = [
- 'action_type' => $data['action_type'],
- 'disc_amount' => $data['disc_amount'],
- 'disc_quantity' => $data['disc_quantity']
- ];
- } else {
- $data['uses_attribute_conditions'] = 1;
-
- $data['actions'] = [
- 'action_type' => $data['action_type'],
- 'disc_amount' => $data['disc_amount'],
- 'disc_quantity' => $data['disc_quantity'],
- 'attribute_conditions' => $attribute_conditions
- ];
- }
-
- // prepare json object from conditions
- $data['actions'] = json_encode($data['actions']);
-
- // check if all
- if (! isset($data['all_conditions']) || $data['all_conditions'] == "[]" || $data['all_conditions'] == "") {
- $data['conditions'] = null;
- } else {
- $data['conditions'] = json_encode($data['all_conditions']);
- }
-
- // unset cart_attributes from conditions
- unset($data['cart_attributes']);
-
- // unset attributes from conditions
- unset($data['attributes']);
-
- // unset all_conditions from conditions
- unset($data['all_conditions']);
-
- // prepare coupons if coupons are used
- if ($data['use_coupon']) {
- // if (isset($data['auto_generation']) && $data['auto_generation']) {
- // auto generation is off for now
- $data['auto_generation'] = 0;
-
- // save the coupon used in coupon section
- $coupons['code'] = $data['code'];
-
- $couponExists = $this->cartRuleCoupon->findWhere([
- 'code' => $coupons['code']
- ]);
-
- if ($couponExists->count()) {
- session()->flash('warning', trans('admin::app.promotion.status.duplicate-coupon'));
-
- return redirect()->back();
- }
-
- // set coupon usage per customer same as per_customer limit which is disabled for now
- // $coupons['usage_per_customer'] = $data['per_customer']; //0 is for unlimited usage
- // unset coupon code from coupon section
- 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']);
- // }
-
- // $coupons['limit'] = 0;
- }
-
- // per coupon usage limit
- // if(isset($data['usage_limit'])) {
- // $coupons['limit'] = $data['usage_limit'];
- // }
-
- // create a cart rule
- $ruleCreated = $this->cartRule->create($data);
-
- // can execute convertX here after when the rule is updated
- if (isset($attribute_conditions) && $data['uses_attribute_conditions']) {
- $this->convertX->convertX($ruleCreated->id, $attribute_conditions);
- }
-
- // create customer groups for cart rule
- $ruleGroupCreated = $this->cartRule->CustomerGroupSync($customer_groups, $ruleCreated);
-
- // create customer groups for channels
- $ruleChannelCreated = $this->cartRule->ChannelSync($channels, $ruleCreated);
-
- // prepare labels
- 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);
- }
-
- // create coupon if present
- if (isset($coupons)) {
- $coupons['cart_rule_id'] = $ruleCreated->id;
- $couponCreated = $this->cartRuleCoupon->create($coupons);
- }
-
- if ($ruleCreated && $ruleChannelCreated && $ruleGroupCreated) {
- 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']);
- }
-
- /**
- * @return \Illuminate\View\View
- */
- public function edit($id)
- {
- $cart_rule = $this->cartRule->find($id);
-
- return view($this->_config['view'])->with('cart_rule', [
- $this->appliedConfig,
- $this->category->getPartial(),
- $this->getStatesAndCountries(),
- $cart_rule,
- $this->attribute->getPartial()
- ]);
- }
-
- /**
- * Collects the response from cart rule update page and update datastore
- *
- * @return redirect
- */
- public function update($id)
- {
- $this->validate(request(), [
- 'name' => 'required|string|unique:cart_rules,name,'.$id,
- 'description' => 'string',
- 'starts_from' => 'nullable|date',
- 'ends_till' => 'nullable|date|after_or_equal:starts_from',
- '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'
- ]);
-
- // collecting request in $data
- $data = request()->all();
-
- $attribute_conditions = $data['all_attributes'];
- unset($data['all_attributes']);
-
- // unset request token from $data
- unset($data['_token']);
-
- // check if starts_from is null
- if ($data['starts_from'] == "") {
- $data['starts_from'] = null;
- }
-
- // check if end_till is null
- if ($data['ends_till'] == "") {
- $data['ends_till'] = null;
- }
-
- // set channels
- $channels = $data['channels'];
-
- // unset the channels from $data
- unset($data['channels']);
-
- // set customer_groups
- $customer_groups = $data['customer_groups'];
-
- // unset customer groups
- unset($data['customer_groups']);
-
- // set labels and unset them from $data
- if (isset($data['label'])) {
- $labels = $data['label'];
-
- unset($data['label']);
- }
-
- // unset cart_attributes and attributes from $data
- unset($data['cart_attributes']);
- unset($data['attributes']);
-
- // prepare actions from data for json action
- $attribute_conditions = json_decode($attribute_conditions);
-
- while (gettype($attribute_conditions) == 'string') {
- $attribute_conditions = json_decode($attribute_conditions);
- }
-
- if (! isset($attribute_conditions) || ! (count($attribute_conditions->categories) || count($attribute_conditions->attributes))) {
- $data['uses_attribute_conditions'] = 0;
-
- $data['actions'] = [
- 'action_type' => $data['action_type'],
- 'disc_amount' => $data['disc_amount'],
- 'disc_quantity' => $data['disc_quantity']
- ];
- } else {
- $data['uses_attribute_conditions'] = 1;
-
- $data['actions'] = [
- 'action_type' => $data['action_type'],
- 'disc_amount' => $data['disc_amount'],
- 'disc_quantity' => $data['disc_quantity'],
- 'attribute_conditions' => $attribute_conditions
- ];
- }
-
- // encode php array to json for actions
- $data['actions'] = json_encode($data['actions']);
-
- // Prepares conditions from all conditions
- if (! isset($data['all_conditions']) || $data['all_conditions'] == "[]" || $data['all_conditions'] == "") {
- $data['conditions'] = null;
- } else {
- $data['conditions'] = json_encode($data['all_conditions']);
- }
-
- unset($data['match_criteria']);
-
- // unset all_conditions from conditions
- unset($data['all_conditions']);
-
- // set coupons from $data
- if ($data['use_coupon']) {
- // if (isset($data['auto_generation']) && $data['auto_generation']) {
- $data['auto_generation'] = 0;
-
- $coupons['code'] = $data['code'];
-
- $couponExists = $this->cartRuleCoupon->findWhere([
- 'code' => $coupons['code']
- ]);
-
- if ($couponExists->count()) {
- if ($couponExists->first()->cart_rule_id != $id) {
- session()->flash('warning', trans('admin::app.promotion.status.duplicate-coupon'));
-
- return redirect()->back();
- }
- }
-
- 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']);
- // }
- // $coupons['limit'] = 0;
- }
-
- // if (isset($data['usage_limit'])) {
- // $coupons['limit'] = $data['usage_limit'];
- // }
-
- // update cart rule
- $ruleUpdated = $this->cartRule->update($data, $id);
-
- if (isset($attribute_conditions) && $data['uses_attribute_conditions']) {
- // can execute convert X here after when the rule is updated
- $this->convertX->convertX($ruleUpdated->id, $attribute_conditions);
- } else {
- $ruleUpdated->update([
- 'product_ids' => null
- ]);
- }
-
- // update customer groups for cart rule
- $ruleGroupUpdated = $this->cartRule->CustomerGroupSync($customer_groups, $ruleUpdated);
-
- // update customer groups for cart rule
- $ruleChannelUpdated = $this->cartRule->ChannelSync($channels, $ruleUpdated);
-
- // update labels
- $labelsUpdated = $this->cartRule->LabelSync($labels, $ruleUpdated);
-
- // check coupons set conditions
- if (isset($coupons)) {
- // $coupons['usage_per_customer'] = $data['per_customer']; //0 is for unlimited usage
- $coupons['cart_rule_id'] = $ruleUpdated->id;
-
- if ($ruleUpdated->coupons == null) {
- $couponCreatedOrUpdated = $this->cartRuleCoupon->create($coupons);
- } else {
- $couponCreatedOrUpdated = $ruleUpdated->coupons->update($coupons);
- }
- } else {
- if ($ruleUpdated->coupons != null) {
- $ruleUpdated->coupons->delete();
- }
- }
-
- if ($ruleUpdated && $ruleGroupUpdated && $ruleChannelUpdated) {
- if (isset($couponCreatedOrUpdated) && $couponCreatedOrUpdated) {
- session()->flash('success', trans('admin::app.promotion.status.success-coupon'));
- }
-
- session()->flash('success', trans('admin::app.promotion.status.update-success'));
- } else {
- session()->flash('success', trans('admin::app.promotion.status.update-success'));
-
- return redirect()->back();
- }
-
- return redirect()->route($this->_config['redirect']);
- }
-
- /**
- * Deletes the cart rule
- *
- * @return JSON
- */
- 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('error', trans('admin::app.promotion.status.delete-failed'));
-
- return response()->json(['message' => false], 400);
- }
- }
-
- /**
- * Get Countries and states list from core helpers
- *
- * @return Array
- */
- public function getStatesAndCountries()
- {
- $countries = core()->countries()->toArray();
- $states = core()->groupedStatesByCountries();
-
- return [
- 'countries' => $countries,
- 'states' => $states
- ];
- }
-}
\ No newline at end of file
diff --git a/packages/Webkul/Discount/src/Http/Controllers/CatalogRuleController.php b/packages/Webkul/Discount/src/Http/Controllers/CatalogRuleController.php
deleted file mode 100644
index 9bb650a8f..000000000
--- a/packages/Webkul/Discount/src/Http/Controllers/CatalogRuleController.php
+++ /dev/null
@@ -1,437 +0,0 @@
- @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 catalog repository instance
- */
- protected $catalogRule;
-
- /**
- * To hold Sale instance
- */
- protected $apply;
-
- public function __construct(
- Attribute $attribute,
- AttributeFamily $attributeFamily,
- Category $category, Product $product,
- CatalogRule $catalogRule,
- CatalogRuleChannels $catalogRuleChannels,
- CatalogRuleCustomerGroups $catalogRuleCustomerGroups,
- Apply $sale
- ) {
- $this->_config = request('_config');
- $this->attribute = $attribute;
- $this->attributeFamily = $attributeFamily;
- $this->category = $category;
- $this->product = $product;
- $this->sale = $sale;
- $this->catalogRule = $catalogRule;
- $this->catalogRuleChannels = $catalogRuleChannels;
- $this->catalogRuleCustomerGroups = $catalogRuleCustomerGroups;
- $this->appliedConfig = config('pricerules.catalog');
- $this->appliedConditions = config('pricerules.conditions');
- }
-
- public function index()
- {
- return view($this->_config['view']);
- }
-
- /**
- * To load create form for catalog rule
- *
- * @return View
- */
- public function create()
- {
- return view($this->_config['view'])->with('catalog_rule', [$this->appliedConfig, $this->category->getPartial(), $this->getStatesAndCountries(), $this->attribute->getPartial()]);
- }
-
- /**
- * To store newly created catalog rule and store it
- *
- * @return Redirect
- */
- public function store()
- {
- $this->validate(request(), [
- 'name' => 'required|string|unique:catalog_rules,name',
- 'description' => 'string',
- 'starts_from' => 'nullable|date',
- 'ends_till' => 'nullable|date|after_or_equal:starts_from',
- 'starts_from' => 'present|nullable|date',
- 'ends_till' => 'present|nullable|date',
- 'customer_groups' => 'required',
- 'channels' => 'required',
- 'status' => 'required|boolean',
- 'end_other_rules' => 'required|boolean',
- 'all_conditions' => 'present',
- 'disc_amount' => 'sometimes',
- 'disc_percent' => 'sometimes',
- ]);
-
- $catalog_rule = request()->all();
-
- $catalog_rule_channels = array();
- $catalog_rule_customer_groups = array();
-
- // check if starts_from is null
- if ($catalog_rule['starts_from'] == "") {
- $catalog_rule['starts_from'] = null;
- }
-
- // check if end_till is null
- if ($catalog_rule['ends_till'] == "") {
- $catalog_rule['ends_till'] = null;
- }
-
- $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']);
-
- $catalog_rule['conditions'] = json_encode($catalog_rule['conditions']);
-
- if (isset($catalog_rule['disc_amount'])) {
- $catalog_rule['actions'] = [
- 'action_code' => $catalog_rule['action_type'],
- 'disc_amount' => $catalog_rule['disc_amount']
- ];
- } else if (isset($catalog_rule['disc_percent'])) {
- $catalog_rule['actions'] = [
- 'action_code' => $catalog_rule['action_type'],
- 'disc_percent' => $catalog_rule['disc_percent'],
- ];
- }
-
- $catalog_rule['discount_amount'] = $catalog_rule['disc_amount'];
-
- $catalog_rule['action_code'] = $catalog_rule['action_type'];
-
- unset($catalog_rule['disc_amount']);
- 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']);
-
- $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();
- }
- }
-
- /**
- * To load edit for previously created catalog rule
- *
- * @param $id
- *
- * @return View
- */
- 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()
- ]);
- }
-
- /**
- * To update previously created catalog rule
- *
- * @param $id
- *
- * @return Redirect
- */
- public function update($id)
- {
- $data = request()->input();
-
- // $validated = \Validator::make($data, [
- // 'name' => 'required|string|unique:catalog_rules,name,' . $id,
- // 'starts_from' => 'present|nullable|date',
- // 'ends_till' => 'present|nullable|date',
- // 'description' => 'string',
- // 'customer_groups' => 'required',
- // 'channels' => 'required',
- // 'status' => 'required|boolean',
- // 'end_other_rules' => 'required|boolean',
- // 'all_conditions' => 'present',
- // 'disc_amount' => 'sometimes',
- // 'disc_percent' => 'sometimes'
- // ]);
-
- // if ($validated->fails()) {
- // dd($validated->errors());
- // } else {
- // dd('passed');
- // }
-
- $this->validate(request(), [
- 'name' => 'required|string|unique:catalog_rules,name,'.$id,
- // 'name' => 'required|string',
- 'starts_from' => 'nullable|date',
- 'ends_till' => 'nullable|date|after_or_equal:starts_from',
- 'description' => 'string',
- 'customer_groups' => 'required',
- 'channels' => 'required',
- 'status' => 'required|boolean',
- 'end_other_rules' => 'required|boolean',
- 'all_conditions' => 'present',
- 'disc_amount' => 'sometimes',
- 'disc_percent' => 'sometimes'
- ]);
-
- $catalog_rule = request()->all();
-
- $catalog_rule_channels = array();
- $catalog_rule_customer_groups = array();
-
- // check if starts_from is null
- if ($catalog_rule['starts_from'] == "") {
- $catalog_rule['starts_from'] = null;
- }
-
- // check if end_till is null
- if ($catalog_rule['ends_till'] == "") {
- $catalog_rule['ends_till'] = null;
- }
-
- $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_code'] = $catalog_rule['action_type'];
- $catalog_rule['actions'] = [
- 'action_code' => $catalog_rule['action_type'],
- 'disc_amount' => $catalog_rule['disc_amount']
- ];
- } else if (isset($catalog_rule['disc_percent'])) {
- $catalog_rule['action_code'] = $catalog_rule['action_type'];
- $catalog_rule['actions'] = [
- 'action_code' => $catalog_rule['action'],
- 'disc_percent' => $catalog_rule['disc_percent'],
- ];
- }
-
- $catalog_rule['discount_amount'] = $catalog_rule['disc_amount'];
-
- unset($catalog_rule['disc_amount']);
- 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('success', 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();
- }
- }
-
- /**
- * To apply the catalog rules
- *
- * @return Redirect
- */
- public function applyRules()
- {
- $this->sale->apply();
-
- session()->flash('success', trans('admin::app.promotion.processing-done'));
-
- return redirect()->route('admin.catalog-rule.index');
- }
-
- /**
- * Initiates decluttering of rules and even reindexes the table if empty
- *
- * @return Response redirect
- */
- public function deClutter()
- {
- $result = $this->sale->deClutter();
-
- if ($result) {
- session()->flash('success', trans('admin::app.promotion.declut-success'));
- } else {
- session()->flash('warning', trans('admin::app.promotion.declut-failure'));
- }
-
- return redirect()->route($this->_config['redirect']);
- }
-
- 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;
- }
-
- /**
- * To delete existing catalog rule
- *
- * @param Integer $id
- *
- * @return Redirect
- */
- public function destroy($id)
- {
- $catalogRule = $this->catalogRule->findOrFail($id);
-
- if ($catalogRule->delete()) {
- session()->flash('success', trans('admin::app.promotion.status.delete-success'));
-
- return response()->json(['message' => true], 200);
- } else {
- session()->flash('error', trans('admin::app.promotion.status.delete-failed'));
-
- return response()->json(['message' => false], 400);
- }
- }
-
- /**
- * Get Countries and states list from core helpers
- *
- * @return Array
- */
- public function getStatesAndCountries()
- {
- $countries = core()->countries()->toArray();
- $states = core()->groupedStatesByCountries();
-
- return [
- 'countries' => $countries,
- 'states' => $states
- ];
- }
-}
\ No newline at end of file
diff --git a/packages/Webkul/Discount/src/Models/CartRule.php b/packages/Webkul/Discount/src/Models/CartRule.php
deleted file mode 100644
index 6ea8b664d..000000000
--- a/packages/Webkul/Discount/src/Models/CartRule.php
+++ /dev/null
@@ -1,39 +0,0 @@
-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());
- }
-}
\ No newline at end of file
diff --git a/packages/Webkul/Discount/src/Models/CartRuleCart.php b/packages/Webkul/Discount/src/Models/CartRuleCart.php
deleted file mode 100644
index 66d2b503c..000000000
--- a/packages/Webkul/Discount/src/Models/CartRuleCart.php
+++ /dev/null
@@ -1,22 +0,0 @@
-hasOne(CartRule::modelClass(), 'id', 'cart_rule_id');
- }
-}
\ No newline at end of file
diff --git a/packages/Webkul/Discount/src/Models/CartRuleCartProxy.php b/packages/Webkul/Discount/src/Models/CartRuleCartProxy.php
deleted file mode 100644
index 98245e4d8..000000000
--- a/packages/Webkul/Discount/src/Models/CartRuleCartProxy.php
+++ /dev/null
@@ -1,10 +0,0 @@
-belongsTo(CartRule::modelClass(), 'cart_rule_id');
- }
-
- public function coupons_usage()
- {
- return $this->hasOne(CartRuleCouponsUsage::modelClass());
- }
-}
\ No newline at end of file
diff --git a/packages/Webkul/Discount/src/Models/CartRuleCouponsProxy.php b/packages/Webkul/Discount/src/Models/CartRuleCouponsProxy.php
deleted file mode 100644
index 8f2fb7f23..000000000
--- a/packages/Webkul/Discount/src/Models/CartRuleCouponsProxy.php
+++ /dev/null
@@ -1,10 +0,0 @@
-hasOne(CustomerGroupProxy::modelClass(), 'id', 'customer_group_id');
- }
-}
diff --git a/packages/Webkul/Discount/src/Models/CartRuleCustomerGroupsProxy.php b/packages/Webkul/Discount/src/Models/CartRuleCustomerGroupsProxy.php
deleted file mode 100644
index e402be089..000000000
--- a/packages/Webkul/Discount/src/Models/CartRuleCustomerGroupsProxy.php
+++ /dev/null
@@ -1,10 +0,0 @@
-belongsTo(CartRule::modelClass(), 'cart_rule_id');
- }
-}
\ No newline at end of file
diff --git a/packages/Webkul/Discount/src/Models/CartRuleCustomersProxy.php b/packages/Webkul/Discount/src/Models/CartRuleCustomersProxy.php
deleted file mode 100644
index fed8df2c8..000000000
--- a/packages/Webkul/Discount/src/Models/CartRuleCustomersProxy.php
+++ /dev/null
@@ -1,10 +0,0 @@
-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');
- }
-}
\ No newline at end of file
diff --git a/packages/Webkul/Discount/src/Models/CatalogRule.php b/packages/Webkul/Discount/src/Models/CatalogRule.php
deleted file mode 100644
index 1c29bc299..000000000
--- a/packages/Webkul/Discount/src/Models/CatalogRule.php
+++ /dev/null
@@ -1,25 +0,0 @@
-hasMany(CatalogRuleChannels::modelClass());
- }
-
- public function customer_groups()
- {
- return $this->hasMany(CatalogRuleCustomerGroups::modelClass());
- }
-}
\ No newline at end of file
diff --git a/packages/Webkul/Discount/src/Models/CatalogRuleChannels.php b/packages/Webkul/Discount/src/Models/CatalogRuleChannels.php
deleted file mode 100644
index d31ebf9de..000000000
--- a/packages/Webkul/Discount/src/Models/CatalogRuleChannels.php
+++ /dev/null
@@ -1,19 +0,0 @@
-belongsTo(CatalogRule::modelClass(), 'catalog_rule_id');
- }
-}
\ No newline at end of file
diff --git a/packages/Webkul/Discount/src/Models/CatalogRuleChannelsProxy.php b/packages/Webkul/Discount/src/Models/CatalogRuleChannelsProxy.php
deleted file mode 100644
index c723f5482..000000000
--- a/packages/Webkul/Discount/src/Models/CatalogRuleChannelsProxy.php
+++ /dev/null
@@ -1,10 +0,0 @@
-hasOne(CustomerGroupProxy::modelClass(), 'id', 'customer_group_id');
- }
-}
\ No newline at end of file
diff --git a/packages/Webkul/Discount/src/Models/CatalogRuleCustomerGroupsProxy.php b/packages/Webkul/Discount/src/Models/CatalogRuleCustomerGroupsProxy.php
deleted file mode 100644
index 12de4951a..000000000
--- a/packages/Webkul/Discount/src/Models/CatalogRuleCustomerGroupsProxy.php
+++ /dev/null
@@ -1,10 +0,0 @@
-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'
- );
-
- $this->mergeConfigFrom(
- dirname(__DIR__) . '/Config/discount-rules.php', 'discount-rules'
- );
- }
-}
\ No newline at end of file
diff --git a/packages/Webkul/Discount/src/Providers/ModuleServiceProvider.php b/packages/Webkul/Discount/src/Providers/ModuleServiceProvider.php
deleted file mode 100644
index 4332e00dc..000000000
--- a/packages/Webkul/Discount/src/Providers/ModuleServiceProvider.php
+++ /dev/null
@@ -1,24 +0,0 @@
-
- * @copyright 2019 Webkul Software Pvt Ltd (http://www.webkul.com)
- */
-class CartRuleCartRepository extends Repository
-{
- /**
- * Specify Model class name
- *
- * @return mixed
- */
- function model()
- {
- return 'Webkul\Discount\Contracts\CartRuleCart';
- }
-}
\ No newline at end of file
diff --git a/packages/Webkul/Discount/src/Repositories/CartRuleChannelsRepository.php b/packages/Webkul/Discount/src/Repositories/CartRuleChannelsRepository.php
deleted file mode 100644
index 2d6209445..000000000
--- a/packages/Webkul/Discount/src/Repositories/CartRuleChannelsRepository.php
+++ /dev/null
@@ -1,24 +0,0 @@
- @prashant-webkul
- * @copyright 2019 Webkul Software Pvt Ltd (http://www.webkul.com)
- */
-class CartRuleChannelsRepository extends Repository
-{
- /**
- * Specify Model class name
- *
- * @return mixed
- */
- function model()
- {
- return 'Webkul\Discount\Contracts\CartRuleChannels';
- }
-}
diff --git a/packages/Webkul/Discount/src/Repositories/CartRuleCouponsRepository.php b/packages/Webkul/Discount/src/Repositories/CartRuleCouponsRepository.php
deleted file mode 100644
index 8b0e53f99..000000000
--- a/packages/Webkul/Discount/src/Repositories/CartRuleCouponsRepository.php
+++ /dev/null
@@ -1,24 +0,0 @@
- @prashant-webkul
- * @copyright 2019 Webkul Software Pvt Ltd (http://www.webkul.com)
- */
-class CartRuleCouponsRepository extends Repository
-{
- /**
- * Specify Model class name
- *
- * @return mixed
- */
- function model()
- {
- return 'Webkul\Discount\Contracts\CartRuleCoupons';
- }
-}
\ No newline at end of file
diff --git a/packages/Webkul/Discount/src/Repositories/CartRuleCustomerGroupsRepository.php b/packages/Webkul/Discount/src/Repositories/CartRuleCustomerGroupsRepository.php
deleted file mode 100644
index cfd4dbe75..000000000
--- a/packages/Webkul/Discount/src/Repositories/CartRuleCustomerGroupsRepository.php
+++ /dev/null
@@ -1,24 +0,0 @@
-
- * @copyright 2019 Webkul Software Pvt Ltd (http://www.webkul.com)
- */
-class CartRuleCustomerGroupsRepository extends Repository
-{
- /**
- * Specify Model class name
- *
- * @return mixed
- */
- function model()
- {
- return 'Webkul\Discount\Contracts\CartRuleCustomerGroups';
- }
-}
diff --git a/packages/Webkul/Discount/src/Repositories/CartRuleLabelsRepository.php b/packages/Webkul/Discount/src/Repositories/CartRuleLabelsRepository.php
deleted file mode 100644
index 2a4d03be7..000000000
--- a/packages/Webkul/Discount/src/Repositories/CartRuleLabelsRepository.php
+++ /dev/null
@@ -1,24 +0,0 @@
-
- * @copyright 2019 Webkul Software Pvt Ltd (http://www.webkul.com)
- */
-class CartRuleLabelsRepository extends Repository
-{
- /**
- * Specify Model class name
- *
- * @return mixed
- */
- function model()
- {
- return 'Webkul\Discount\Contracts\CartRuleLabels';
- }
-}
\ No newline at end of file
diff --git a/packages/Webkul/Discount/src/Repositories/CartRuleRepository.php b/packages/Webkul/Discount/src/Repositories/CartRuleRepository.php
deleted file mode 100644
index 6005f8d0f..000000000
--- a/packages/Webkul/Discount/src/Repositories/CartRuleRepository.php
+++ /dev/null
@@ -1,205 +0,0 @@
-
- * @copyright 2019 Webkul Software Pvt Ltd (http://www.webkul.com)
- */
-class CartRuleRepository extends Repository
-{
- /**
- * Will hold cartRuleChannelsRepository instance
- */
- protected $cartRuleChannels;
-
- /**
- * Will hold cartRuleCustomerGroupsRepository instance
- */
- protected $cartRuleCustomerGroups;
-
- /**
- * Will hold cartRuleCoupons instance
- */
- protected $cartRuleCoupons;
-
- /**
- * Will hold cartRuleCustomerGroupsRepository instance
- */
- protected $cartRuleLabels;
-
- /**
- * @param CartRuleChannels $cartRuleChannels
- * @param CartRuleCustomerGroups $cartRuleCustomerGroups
- * @param CartRuleCoupons $cartRuleCoupons
- * @param
- */
- public function __construct(
- CartRuleChannels $cartRuleChannels,
- CartRuleCustomerGroups $cartRuleCustomerGroups,
- CartRuleCoupons $cartRuleCoupons,
- CartRuleLabels $cartRuleLabels,
- App $app
- ) {
- $this->cartRuleChannels = $cartRuleChannels;
- $this->cartRuleCustomerGroups = $cartRuleCustomerGroups;
- $this->cartRuleCoupons = $cartRuleCoupons;
- $this->cartRuleLabel = $cartRuleLabels;
-
- parent::__construct($app);
- }
-
- /**
- * Specify Model class name
- *
- * @return mixed
- */
- function model()
- {
- return 'Webkul\Discount\Contracts\CartRule';
- }
-
- /**
- * To sync the customer groups related records
- */
- public function CustomerGroupSync($newCustomerGroups, $cartRule)
- {
- $oldCustomerGroups = array();
- foreach ($cartRule->customer_groups as $oldCustomerGroup) {
- array_push($oldCustomerGroups, ['id' => $oldCustomerGroup->id, 'customer_group_id' => $oldCustomerGroup->customer_group_id]);
- }
-
- foreach ($oldCustomerGroups as $key => $oldCustomerGroup) {
- $found = 0;
- foreach ($newCustomerGroups as $newCustomerGroup) {
- if ($oldCustomerGroup['customer_group_id'] == $newCustomerGroup)
- $found = 1;
- }
-
- if ($found == 0) {
- $this->cartRuleCustomerGroups->find($oldCustomerGroup['id'])->delete();
- } else {
- $found = 0;
- }
- }
-
- //unset the commons
- if (count($newCustomerGroups) && count($oldCustomerGroups)) {
- foreach ($oldCustomerGroups as $oldCustomerGroup) {
- $found = 0;
- foreach ($newCustomerGroups as $key => $newCustomerGroup) {
- if ($oldCustomerGroup['customer_group_id'] == $newCustomerGroup)
- unset($newCustomerGroups[$key]);
- }
- }
- }
-
- //create the left ones
- foreach ($newCustomerGroups as $newCustomerGroup) {
- $data['customer_group_id'] = $newCustomerGroup;
- $data['cart_rule_id'] = $cartRule->id;
-
- $this->cartRuleCustomerGroups->create($data);
- }
-
- return true;
- }
-
- /**
- * To sync the channels related records
- */
- public function ChannelSync($newChannels, $cartRule)
- {
- $oldChannels = array();
-
- foreach ($cartRule->channels as $oldChannel) {
- array_push($oldChannels, ['id' => $oldChannel->id, 'channel_id' => $oldChannel->channel_id]);
- }
-
- foreach ($oldChannels as $key => $oldChannel) {
- $found = 0;
- foreach ($newChannels as $newChannel) {
- if ($oldChannel['channel_id'] == $newChannel)
- $found = 1;
- }
-
- if ($found == 0) {
- $this->cartRuleChannels->find($oldChannel['id'])->delete();
- } else {
- $found = 0;
- }
- }
-
- //unset the commons
- if (count($newChannels) && count($oldChannels)) {
- foreach ($oldChannels as $oldChannel) {
- $found = 0;
-
- foreach ($newChannels as $key => $newChannel) {
- if ($oldChannel['channel_id'] == $newChannel)
- unset($newChannels[$key]);
- }
- }
- }
-
- //create the left ones
- foreach ($newChannels as $newChannel) {
- $data['channel_id'] = $newChannel;
- $data['cart_rule_id'] = $cartRule->id;
-
- $this->cartRuleChannels->create($data);
- }
-
- return true;
- }
-
- /**
- * To sync the labels associated with the cart rule
- */
- public function LabelSync($labels, $cartRule)
- {
- foreach ($labels as $channelCode => $value) {
- $localeCode = array_keys($value)[0];
- $localeValue = array_values($value)[0];
-
- $updated = 0;
- foreach ($cartRule->labels as $label) {
- if ($label->channel->code == $channelCode && $label->locale->code == $localeCode) {
- $label->update(['label' => $localeValue]);
-
- $updated = 1;
- }
- }
-
- if ($updated == 0) {
- foreach (core()->getAllChannels() as $channel) {
- if ($channel->code == $channelCode)
- $newLabel['channel_id'] = $channel->id;
-
- foreach($channel->locales as $locale) {
- if ($localeCode == $locale->code) {
- $newLabel['locale_id'] = $locale->id;
- $newLabel['label'] = $localeValue;
- $newLabel['cart_rule_id'] = $cartRule->id;
-
- $ruleLabelCreated = $this->CartRuleLabels->create($newLabel);
- }
- }
- }
- }
-
- $updated = 0;
- }
-
- return true;
- }
-}
\ No newline at end of file
diff --git a/packages/Webkul/Discount/src/Repositories/CatalogRuleChannelsRepository.php b/packages/Webkul/Discount/src/Repositories/CatalogRuleChannelsRepository.php
deleted file mode 100644
index 50ade8dbc..000000000
--- a/packages/Webkul/Discount/src/Repositories/CatalogRuleChannelsRepository.php
+++ /dev/null
@@ -1,24 +0,0 @@
-
- * @copyright 2019 Webkul Software Pvt Ltd (http://www.webkul.com)
- */
-class CatalogRuleChannelsRepository extends Repository
-{
- /**
- * Specify Model class name
- *
- * @return String
- */
- function model()
- {
- return 'Webkul\Discount\Contracts\CatalogRuleChannels';
- }
-}
diff --git a/packages/Webkul/Discount/src/Repositories/CatalogRuleCustomerGroupsRepository.php b/packages/Webkul/Discount/src/Repositories/CatalogRuleCustomerGroupsRepository.php
deleted file mode 100644
index 2d7184610..000000000
--- a/packages/Webkul/Discount/src/Repositories/CatalogRuleCustomerGroupsRepository.php
+++ /dev/null
@@ -1,24 +0,0 @@
-
- * @copyright 2019 Webkul Software Pvt Ltd (http://www.webkul.com)
- */
-class CatalogRuleCustomerGroupsRepository extends Repository
-{
- /**
- * Specify Model class name
- *
- * @return String
- */
- function model()
- {
- return 'Webkul\Discount\Contracts\CatalogRuleCustomerGroups';
- }
-}
\ No newline at end of file
diff --git a/packages/Webkul/Discount/src/Repositories/CatalogRuleProductsPriceRepository.php b/packages/Webkul/Discount/src/Repositories/CatalogRuleProductsPriceRepository.php
deleted file mode 100644
index 5becbb9eb..000000000
--- a/packages/Webkul/Discount/src/Repositories/CatalogRuleProductsPriceRepository.php
+++ /dev/null
@@ -1,51 +0,0 @@
- @prashant-webkul
- * @copyright 2019 Webkul Software Pvt Ltd (http://www.webkul.com)
- */
-class CatalogRuleProductsPriceRepository extends Repository
-{
- /**
- * To hold ProductRepository instance
- */
- protected $product;
-
- /**
- * To hold CatalogRuleProductRepository instance
- *
- */
- protected $catalogRuleProduct;
-
- /**
- * @param Product $product
- */
- public function __construct(Product $product, CatalogRuleProduct $catalogRuleProduct,App $app)
- {
-
- $this->product = $product;
-
- $this->catalogRuleProduct = $catalogRuleProduct;
-
- parent::__construct($app);
- }
-
- /**
- * Specify Model class name
- *
- * @return String
- */
- function model()
- {
- return 'Webkul\Discount\Contracts\CatalogRuleProductsPrice';
- }
-}
\ No newline at end of file
diff --git a/packages/Webkul/Discount/src/Repositories/CatalogRuleProductsRepository.php b/packages/Webkul/Discount/src/Repositories/CatalogRuleProductsRepository.php
deleted file mode 100644
index aedf092fd..000000000
--- a/packages/Webkul/Discount/src/Repositories/CatalogRuleProductsRepository.php
+++ /dev/null
@@ -1,39 +0,0 @@
- @prashant-webkul
- * @copyright 2019 Webkul Software Pvt Ltd (http://www.webkul.com)
- */
-class CatalogRuleProductsRepository extends Repository
-{
- /**
- * CatalogRule Apply instance
- */
- protected $apply;
-
- /**
- * @param App $app
- */
- public function __construct(App $app)
- {
- parent::__construct($app);
- }
-
- /**
- * Specify Model class name
- *
- * @return String
- */
- function model()
- {
- return 'Webkul\Discount\Contracts\CatalogRuleProducts';
- }
-}
diff --git a/packages/Webkul/Discount/src/Repositories/CatalogRuleRepository.php b/packages/Webkul/Discount/src/Repositories/CatalogRuleRepository.php
deleted file mode 100644
index da6b684ae..000000000
--- a/packages/Webkul/Discount/src/Repositories/CatalogRuleRepository.php
+++ /dev/null
@@ -1,155 +0,0 @@
-
- * @copyright 2019 Webkul Software Pvt Ltd (http://www.webkul.com)
- */
-class CatalogRuleRepository extends Repository
-{
- /**
- * Will hold catalogRuleChannelsRepository instance
- */
- protected $catalogRuleChannels;
-
- /**
- * Will hold catalogRuleCustomerGroupsRepository instance
- */
- protected $catalogRuleCustomerGroups;
-
- /**
- * @param CatalogRuleChannels $catalogRuleChannels
- * @param CatalogRuleCustomerGroups $catalogRuleCustomerGroups
- * @param App $app
- */
- public function __construct(CatalogRuleChannels $catalogRuleChannels, CatalogRuleCustomerGroups $catalogRuleCustomerGroups, App $app)
- {
- $this->catalogRuleChannels = $catalogRuleChannels;
-
- $this->catalogRuleCustomerGroups = $catalogRuleCustomerGroups;
-
- parent::__construct($app);
- }
-
- /**
- * Specify Model class name
- *
- * @return String
- */
- function model()
- {
- return 'Webkul\Discount\Contracts\CatalogRule';
- }
-
- /**
- * To sync the customer groups related records
- *
- * @param Array $newCustomerGroups
- * @param CatalogRule $catalogRule
- *
- * @return Boolean
- */
- public function CustomerGroupSync($newCustomerGroups, $catalogRule)
- {
- $oldCustomerGroups = array();
- foreach ($catalogRule->customer_groups as $oldCustomerGroup) {
- array_push($oldCustomerGroups, ['id' => $oldCustomerGroup->id, 'customer_group_id' => $oldCustomerGroup->customer_group_id]);
- }
-
- foreach ($oldCustomerGroups as $key => $oldCustomerGroup) {
- $found = 0;
-
- foreach($newCustomerGroups as $newCustomerGroup) {
- if ($oldCustomerGroup['customer_group_id'] == $newCustomerGroup)
- $found = 1;
- }
-
- if ($found == 0) {
- $this->catalogRuleCustomerGroups->find($oldCustomerGroup['id'])->delete();
- } else {
- $found = 0;
- }
- }
-
- //unset the commons
- if (count($newCustomerGroups) && count($oldCustomerGroups)) {
- foreach ($oldCustomerGroups as $oldCustomerGroup) {
- $found = 0;
-
- foreach ($newCustomerGroups as $key => $newCustomerGroup) {
- if ($oldCustomerGroup['customer_group_id'] == $newCustomerGroup)
- unset($newCustomerGroups[$key]);
- }
- }
- }
-
- //create the left ones
- foreach ($newCustomerGroups as $newCustomerGroup) {
- $data['customer_group_id'] = $newCustomerGroup;
- $data['catalog_rule_id'] = $catalogRule->id;
-
- $this->catalogRuleCustomerGroups->create($data);
- }
-
- return true;
- }
-
- /**
- * To sync the channels related records
- *
- * @param Array $newChannels
- * @param CatalogRule $catalogRule
- *
- * @return Boolean
- */
- public function ChannelSync($newChannels, $catalogRule)
- {
- $oldChannels = array();
- foreach ($catalogRule->channels as $oldChannel) {
- array_push($oldChannels, ['id' => $oldChannel->id, 'channel_id' => $oldChannel->channel_id]);
- }
-
- foreach ($oldChannels as $key => $oldChannel) {
- $found = 0;
- foreach($newChannels as $newChannel) {
- if ($oldChannel['channel_id'] == $newChannel)
- $found = 1;
- }
-
- if ($found == 0) {
- $this->catalogRuleChannels->find($oldChannel['id'])->delete();
- } else {
- $found = 0;
- }
- }
-
- //unset the commons
- if (count($newChannels) && count($oldChannels)) {
- foreach ($oldChannels as $oldChannel) {
- $found = 0;
-
- foreach ($newChannels as $key => $newChannel) {
- if ($oldChannel['channel_id'] == $newChannel)
- unset($newChannels[$key]);
- }
- }
- }
-
- //create the left ones
- foreach ($newChannels as $newChannel) {
- $data['channel_id'] = $newChannel;
- $data['catalog_rule_id'] = $catalogRule->id;
- $this->catalogRuleChannels->create($data);
- }
-
- return true;
- }
-}
\ No newline at end of file
diff --git a/packages/Webkul/Discount/src/resources/manifest.php b/packages/Webkul/Discount/src/resources/manifest.php
deleted file mode 100644
index a5d9bb930..000000000
--- a/packages/Webkul/Discount/src/resources/manifest.php
+++ /dev/null
@@ -1,6 +0,0 @@
- 'Webkul Bagisto Discount',
- 'version' => '0.0.1'
- ];
diff --git a/packages/Webkul/Product/src/Type/AbstractType.php b/packages/Webkul/Product/src/Type/AbstractType.php
index d257ae928..8ca737dd9 100644
--- a/packages/Webkul/Product/src/Type/AbstractType.php
+++ b/packages/Webkul/Product/src/Type/AbstractType.php
@@ -112,6 +112,13 @@ abstract class AbstractType
*/
protected $hasVariants = false;
+ /**
+ * Product children price can be calculated or not
+ *
+ * @var boolean
+ */
+ protected $isChildrenCalculated = false;
+
/**
* Create a new product type instance.
*
@@ -252,6 +259,26 @@ abstract class AbstractType
return $this;
}
+ /**
+ * Returns children ids
+ *
+ * @return array
+ */
+ public function getChildrenIds()
+ {
+ return [];
+ }
+
+ /**
+ * Check if catalog rule can be applied
+ *
+ * @return bool
+ */
+ public function priceRuleCanBeApplied()
+ {
+ return true;
+ }
+
/**
* Return true if this product type is saleable
*
@@ -291,11 +318,21 @@ abstract class AbstractType
*
* @return bool
*/
- public function hasVariants(): bool
+ public function hasVariants()
{
return $this->hasVariants;
}
+ /**
+ * Product children price can be calculated or not
+ *
+ * @return bool
+ */
+ public function isChildrenCalculated()
+ {
+ return $this->isChildrenCalculated;
+ }
+
/**
* @param integer $qty
* @return bool
@@ -452,12 +489,26 @@ abstract class AbstractType
*/
public function haveSpecialPrice()
{
- if (is_null($this->product->special_price) || ! (float) $this->product->special_price) {
- return false;
- }
+ $rulePrice = app('Webkul\CatalogRule\Helpers\CatalogRuleProductPrice')->getRulePrice($this->product);
- if (core()->isChannelDateInInterval($this->product->special_price_from, $this->product->special_price_to)) {
- return true;
+ if ((is_null($this->product->special_price) || ! (float) $this->product->special_price) && ! $rulePrice)
+ return false;
+
+ if (! (float) $this->product->special_price) {
+ if ($rulePrice) {
+ $this->product->special_price = $rulePrice->price;
+
+ return true;
+ }
+ } else {
+ if ($rulePrice && $rulePrice->price <= $this->product->special_price) {
+ $this->product->special_price = $rulePrice->price;
+
+ return true;
+ } else {
+ if (core()->isChannelDateInInterval($this->product->special_price_from, $this->product->special_price_to))
+ return true;
+ }
}
return false;
diff --git a/packages/Webkul/Product/src/Type/Bundle.php b/packages/Webkul/Product/src/Type/Bundle.php
index dad347cec..52a1345da 100644
--- a/packages/Webkul/Product/src/Type/Bundle.php
+++ b/packages/Webkul/Product/src/Type/Bundle.php
@@ -68,6 +68,13 @@ class Bundle extends AbstractType
*/
protected $isComposite = true;
+ /**
+ * Product children price can be calculated or not
+ *
+ * @var boolean
+ */
+ protected $isChildrenCalculated = true;
+
/**
* Create a new product type instance.
*
@@ -126,6 +133,26 @@ class Bundle extends AbstractType
return $product;
}
+ /**
+ * Returns children ids
+ *
+ * @return array
+ */
+ public function getChildrenIds()
+ {
+ return array_unique($this->product->bundle_options()->pluck('product_id')->toArray());
+ }
+
+ /**
+ * Check if catalog rule can be applied
+ *
+ * @return bool
+ */
+ public function priceRuleCanBeApplied()
+ {
+ return false;
+ }
+
/**
* Get product minimal price
*
diff --git a/packages/Webkul/Product/src/Type/Configurable.php b/packages/Webkul/Product/src/Type/Configurable.php
index e0f1c3eea..db2890f1d 100644
--- a/packages/Webkul/Product/src/Type/Configurable.php
+++ b/packages/Webkul/Product/src/Type/Configurable.php
@@ -286,6 +286,16 @@ class Configurable extends AbstractType
return false;
}
+ /**
+ * Returns children ids
+ *
+ * @return array
+ */
+ public function getChildrenIds()
+ {
+ return $this->product->variants()->pluck('id')->toArray();
+ }
+
/**
* @param CartItem $cartItem
* @return bool
diff --git a/packages/Webkul/Product/src/Type/Grouped.php b/packages/Webkul/Product/src/Type/Grouped.php
index 2af33ccb6..0d1559f43 100644
--- a/packages/Webkul/Product/src/Type/Grouped.php
+++ b/packages/Webkul/Product/src/Type/Grouped.php
@@ -104,6 +104,26 @@ class Grouped extends AbstractType
return $product;
}
+ /**
+ * Returns children ids
+ *
+ * @return array
+ */
+ public function getChildrenIds()
+ {
+ return array_unique($this->product->grouped_products()->pluck('product_id')->toArray());
+ }
+
+ /**
+ * Check if catalog rule can be applied
+ *
+ * @return bool
+ */
+ public function priceRuleCanBeApplied()
+ {
+ return false;
+ }
+
/**
* Get product minimal price
*
@@ -113,17 +133,8 @@ class Grouped extends AbstractType
{
$minPrices = [];
- $result = $this->product->grouped_products()
- ->join('product_flat', 'product_grouped_products.associated_product_id', '=', 'product_flat.product_id')
- ->selectRaw('IF( product_flat.special_price_from IS NOT NULL
- AND product_flat.special_price_to IS NOT NULL , IF( NOW( ) >= product_flat.special_price_from
- AND NOW( ) <= product_flat.special_price_to, IF( product_flat.special_price IS NULL OR product_flat.special_price = 0 , product_flat.price, LEAST( product_flat.special_price, product_flat.price ) ) , product_flat.price ) , IF( product_flat.special_price_from IS NULL , IF( product_flat.special_price_to IS NULL , IF( product_flat.special_price IS NULL OR product_flat.special_price = 0 , product_flat.price, LEAST( product_flat.special_price, product_flat.price ) ) , IF( NOW( ) <= product_flat.special_price_to, IF( product_flat.special_price IS NULL OR product_flat.special_price = 0 , product_flat.price, LEAST( product_flat.special_price, product_flat.price ) ) , product_flat.price ) ) , IF( product_flat.special_price_to IS NULL , IF( NOW( ) >= product_flat.special_price_from, IF( product_flat.special_price IS NULL OR product_flat.special_price = 0 , product_flat.price, LEAST( product_flat.special_price, product_flat.price ) ) , product_flat.price ) , product_flat.price ) ) ) AS min_price')
- ->where('product_flat.channel', core()->getCurrentChannelCode())
- ->where('product_flat.locale', app()->getLocale())
- ->get();
-
- foreach ($result as $price) {
- $minPrices[] = $price->min_price;
+ foreach ($this->product->grouped_products as $groupOptionProduct) {
+ $minPrices[] = $groupOptionProduct->associated_product->getTypeInstance()->getMinimalPrice();
}
if (empty($minPrices))
diff --git a/packages/Webkul/Rule/src/Helpers/Validator.php b/packages/Webkul/Rule/src/Helpers/Validator.php
new file mode 100644
index 000000000..ac510f314
--- /dev/null
+++ b/packages/Webkul/Rule/src/Helpers/Validator.php
@@ -0,0 +1,240 @@
+conditions)
+ return true;
+
+ $validConditionCount = $totalConditionCount = 0;
+
+ foreach ($rule->conditions as $condition) {
+ if (! $condition['attribute'] || ! isset($condition['value']) || is_null($condition['value']) || $condition['value'] == '')
+ continue;
+
+ if ($entity instanceof \Webkul\Checkout\Contracts\Cart && strpos($condition['attribute'], 'cart|') === false)
+ continue;
+
+ $totalConditionCount++;
+
+ if ($rule->condition_type == 1) {
+ if (! $this->validateObject($condition, $entity)) {
+ return false;
+ } else {
+ $validConditionCount++;
+ }
+ } else {
+ if ($this->validateObject($condition, $entity))
+ return true;
+ }
+ }
+
+ return $validConditionCount == $totalConditionCount ? true : false;
+ }
+
+ /**
+ * Return value for the attribute
+ *
+ * @param array $condition
+ * @param CartItem|Product $entity
+ * @return boolean
+ */
+ public function getAttributeValue($condition, $entity)
+ {
+ $chunks = explode('|', $condition['attribute']);
+
+ $attributeNameChunks = explode('::', $chunks[1]);
+
+ $attributeCode = $attributeNameChunks[count($attributeNameChunks) - 1];
+
+ switch (current($chunks)) {
+ case 'cart':
+ $cart = $entity instanceof \Webkul\Checkout\Contracts\Cart ? $entity : $entity->cart;
+
+ if (in_array($attributeCode, ['postcode', 'state', 'country'])) {
+ if (! $cart->shipping_address)
+ return;
+
+ return $cart->shipping_address->{$attributeCode};
+ } else if ($attributeCode == 'shipping_method') {
+ if (! $cart->shipping_method)
+ return;
+
+ $shippingChunks = explode('_', $cart->shipping_method);
+
+ return current($shippingChunks);
+ } else if ($attributeCode == 'payment_method') {
+ if (! $cart->payment)
+ return;
+
+ return $cart->payment->method;
+ } else {
+ return $cart->{$attributeCode};
+ }
+
+ case 'cart_item':
+ return $entity->{$attributeCode};
+
+ case 'product':
+ if ($attributeCode == 'category_ids') {
+ $value = $entity->product
+ ? $entity->product->categories()->pluck('id')->toArray()
+ : $entity->categories()->pluck('id')->toArray();
+
+ return $value;
+ } else {
+ $value = $entity->product
+ ? $entity->product->{$attributeCode}
+ : $entity->{$attributeCode};
+
+ if (! in_array($condition['attribute_type'], ['multiselect', 'checkbox']))
+ return $value;
+
+ return $value ? explode(',', $value) : [];
+ }
+ }
+ }
+
+ /**
+ * Validate object
+ *
+ * @param array $condition
+ * @param CartItem $entity
+ * @return bool
+ */
+ private function validateObject($condition, $entity)
+ {
+ $validated = false;
+
+ foreach ($this->getAllItems($this->getAttributeScope($condition), $entity) as $item) {
+ $attributeValue = $this->getAttributeValue($condition, $item);
+
+ if ($validated = $this->validateAttribute($condition, $attributeValue))
+ break;
+ }
+
+ return $validated;
+ }
+
+ /**
+ * Return all cart items
+ *
+ * @param string $attributeScope
+ * @param Cart|CartItem|Product $item
+ * @return array
+ */
+ private function getAllItems($attributeScope, $item)
+ {
+ if ($attributeScope === 'parent') {
+ return [$item];
+ } elseif ($attributeScope === 'children') {
+ return $item->children ?: [$item];
+ } else {
+ $items = $item->children ?: [];
+
+ $items[] = $item;
+ }
+
+ return $items;
+ }
+
+ /**
+ * Validate object
+ *
+ * @param array $condition
+ * @return string
+ */
+ private function getAttributeScope($condition)
+ {
+ $chunks = explode('|', $condition['attribute']);
+
+ $attributeNameChunks = explode('::', $chunks[1]);
+
+ return count($attributeNameChunks) == 2 ? $attributeNameChunks[0] : null;
+ }
+
+ /**
+ * Validate attribute value for condition
+ *
+ * @param array $condition
+ * @param mixed $attributeValue
+ * @return boolean
+ */
+ public function validateAttribute($condition, $attributeValue)
+ {
+ switch ($condition['operator']) {
+ case '==': case '!=':
+ if (is_array($condition['value'])) {
+ if (! is_array($attributeValue))
+ return false;
+
+ $result = ! empty(array_intersect($condition['value'], $attributeValue));
+ } else {
+ if (is_array($attributeValue)) {
+ $result = count($attributeValue) == 1 && array_shift($attributeValue) == $condition['value'];
+ } else {
+ $result = $attributeValue == $condition['value'];
+ }
+ }
+
+ break;
+
+ case '<=': case '>':
+ if (! is_scalar($attributeValue))
+ return false;
+
+ $result = $attributeValue <= $condition['value'];
+
+ break;
+
+ case '>=': case '<':
+ if (! is_scalar($attributeValue))
+ return false;
+
+ $result = $attributeValue >= $condition['value'];
+
+ break;
+
+ case '{}': case '!{}':
+ if (is_scalar($attributeValue) && is_array($condition['value'])) {
+ foreach ($condition['value'] as $item) {
+ if (stripos($attributeValue, $item) !== false) {
+ $result = true;
+
+ break;
+ }
+ }
+ } else if (is_array($condition['value'])) {
+ if (! is_array($attributeValue))
+ return false;
+
+ $result = ! empty(array_intersect($condition['value'], $attributeValue));
+ } else {
+ if (is_array($attributeValue)) {
+ $result = in_array($condition['value'], $attributeValue);
+ } else {
+ $result = (strpos($attributeValue, $condition['value']) !== false) ? true : false;
+ }
+ }
+
+ break;
+ }
+
+ if (in_array($condition['operator'], ['!=', '>', '<', '!{}']))
+ $result = ! $result;
+
+ return $result;
+ }
+}
\ No newline at end of file
diff --git a/packages/Webkul/Rule/src/Providers/RuleServiceProvider.php b/packages/Webkul/Rule/src/Providers/RuleServiceProvider.php
new file mode 100644
index 000000000..2a48f4d5d
--- /dev/null
+++ b/packages/Webkul/Rule/src/Providers/RuleServiceProvider.php
@@ -0,0 +1,26 @@
+string('applied_cart_rule_ids')->nullable();
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ *
+ * @return void
+ */
+ public function down()
+ {
+ Schema::table('orders', function (Blueprint $table) {
+ //
+ });
+ }
+}
diff --git a/packages/Webkul/Shop/src/Http/Controllers/CartController.php b/packages/Webkul/Shop/src/Http/Controllers/CartController.php
index b23c42b4c..ddd139e7e 100755
--- a/packages/Webkul/Shop/src/Http/Controllers/CartController.php
+++ b/packages/Webkul/Shop/src/Http/Controllers/CartController.php
@@ -155,4 +155,52 @@ class CartController extends Controller
return redirect()->back();
}
+
+ /**
+ * Apply coupon to the cart
+ *
+ * @return \Illuminate\Http\JsonResponse
+ */
+ public function applyCoupon()
+ {
+ $couponCode = request()->get('code');
+
+ try {
+ if (strlen($couponCode)) {
+ Cart::setCouponCode($couponCode)->collectTotals();
+
+ if (Cart::getCart()->coupon_code == $couponCode) {
+ return response()->json([
+ 'success' => true,
+ 'message' => trans('shop::app.checkout.total.success-coupon')
+ ]);
+ }
+ }
+
+ return response()->json([
+ 'success' => false,
+ 'message' => trans('shop::app.checkout.total.invalid-coupon')
+ ]);
+ } catch (\Exception $e) {
+ return response()->json([
+ 'success' => false,
+ 'message' => trans('shop::app.checkout.total.coupon-apply-issue')
+ ]);
+ }
+ }
+
+ /**
+ * Apply coupon to the cart
+ *
+ * @return \Illuminate\Http\JsonResponse
+ */
+ public function removeCoupon()
+ {
+ Cart::removeCouponCode()->collectTotals();
+
+ return response()->json([
+ 'success' => true,
+ 'message' => trans('shop::app.checkout.total.remove-coupon')
+ ]);
+ }
}
\ No newline at end of file
diff --git a/packages/Webkul/Shop/src/Http/Controllers/OnepageController.php b/packages/Webkul/Shop/src/Http/Controllers/OnepageController.php
index a77f66752..12dad01aa 100755
--- a/packages/Webkul/Shop/src/Http/Controllers/OnepageController.php
+++ b/packages/Webkul/Shop/src/Http/Controllers/OnepageController.php
@@ -8,9 +8,6 @@ use Webkul\Shipping\Facades\Shipping;
use Webkul\Payment\Facades\Payment;
use Webkul\Checkout\Http\Requests\CustomerAddressForm;
use Webkul\Sales\Repositories\OrderRepository;
-use Webkul\Discount\Helpers\Cart\CouponAbleRule as Coupon;
-use Webkul\Discount\Helpers\Cart\NonCouponAbleRule as NonCoupon;
-use Webkul\Discount\Helpers\Cart\ValidatesDiscount;
use Webkul\Customer\Repositories\CustomerRepository;
/**
@@ -22,13 +19,6 @@ use Webkul\Customer\Repositories\CustomerRepository;
*/
class OnepageController extends Controller
{
- /**
- * OrderRepository object
- *
- * @var array
- */
- protected $orderRepository;
-
/**
* Contains route related configuration
*
@@ -37,21 +27,11 @@ class OnepageController extends Controller
protected $_config;
/**
- * CouponAbleRule instance object
+ * OrderRepository object
*
+ * @var array
*/
- protected $coupon;
-
- /**
- * NoncouponAbleRule instance object
- *
- */
- protected $nonCoupon;
-
- /**
- * ValidatesDiscount instance object
- */
- protected $validatesDiscount;
+ protected $orderRepository;
/**
* customerRepository instance object
@@ -61,25 +41,17 @@ class OnepageController extends Controller
/**
* Create a new controller instance.
*
- * @param \Webkul\Attribute\Repositories\OrderRepository $orderRepository
+ * @param \Webkul\Attribute\Repositories\OrderRepository $orderRepository
+ * @param \Webkul\Customer\Repositories\CustomerRepository $customerRepository
* @return void
*/
public function __construct(
OrderRepository $orderRepository,
- Coupon $coupon,
- NonCoupon $nonCoupon,
- ValidatesDiscount $validatesDiscount,
CustomerRepository $customerRepository
)
{
- $this->coupon = $coupon;
-
- $this->nonCoupon = $nonCoupon;
-
$this->orderRepository = $orderRepository;
- $this->validatesDiscount = $validatesDiscount;
-
$this->customerRepository = $customerRepository;
$this->_config = request('_config');
@@ -100,8 +72,6 @@ class OnepageController extends Controller
if (! auth()->guard('customer')->check() && $cart->haveDownloadableItems())
return redirect()->route('customer.session.index');
- $this->nonCoupon->apply();
-
Cart::collectTotals();
return view($this->_config['view'], compact('cart'));
@@ -139,8 +109,6 @@ class OnepageController extends Controller
} else {
$cart = Cart::getCart();
- $this->nonCoupon->apply();
-
Cart::collectTotals();
if ($cart->haveStockableItems()) {
@@ -166,8 +134,6 @@ class OnepageController extends Controller
if (Cart::hasError() || !$shippingMethod || !Cart::saveShippingMethod($shippingMethod))
return response()->json(['redirect_url' => route('shop.checkout.cart.index')], 403);
- $this->nonCoupon->apply();
-
Cart::collectTotals();
return response()->json(Payment::getSupportedPaymentMethods());
@@ -185,8 +151,6 @@ class OnepageController extends Controller
if (Cart::hasError() || ! $payment || ! Cart::savePaymentMethod($payment))
return response()->json(['redirect_url' => route('shop.checkout.cart.index')], 403);
- $this->nonCoupon->apply();
-
Cart::collectTotals();
$cart = Cart::getCart();
@@ -253,23 +217,53 @@ class OnepageController extends Controller
{
$cart = Cart::getCart();
- $this->validatesDiscount->validate();
-
- if ($cart->haveStockableItems() && ! $cart->shipping_address) {
+ if ($cart->haveStockableItems() && ! $cart->shipping_address)
throw new \Exception(trans('Please check shipping address.'));
- }
- if (! $cart->billing_address) {
+ if (! $cart->billing_address)
throw new \Exception(trans('Please check billing address.'));
- }
- if ($cart->haveStockableItems() && ! $cart->selected_shipping_rate) {
+ if ($cart->haveStockableItems() && ! $cart->selected_shipping_rate)
throw new \Exception(trans('Please specify shipping method.'));
- }
- if (! $cart->payment) {
+ if (! $cart->payment)
throw new \Exception(trans('Please specify payment method.'));
- }
+ }
+
+ /**
+ * Check Customer is exist or not
+ *
+ * @return Response
+ */
+ public function checkExistCustomer()
+ {
+ $customer = $this->customerRepository->findOneWhere([
+ 'email' => request()->email
+ ]);
+
+ if (! is_null($customer))
+ return 'true';
+
+ return 'false';
+ }
+
+ /**
+ * Login for checkout
+ *
+ * @return Response
+ */
+ public function loginForCheckout()
+ {
+ $this->validate(request(), [
+ 'email' => 'required|email'
+ ]);
+
+ if (! auth()->guard('customer')->attempt(request(['email', 'password'])))
+ return response()->json(['error' => trans('shop::app.customer.login-form.invalid-creds')]);
+
+ Cart::mergeCart();
+
+ return response()->json(['success' => 'Login successfully']);
}
/**
@@ -333,40 +327,4 @@ class OnepageController extends Controller
], 422);
}
}
-
- /**
- * Check Customer is exist or not
- *
- * @return Response
- */
- public function checkExistCustomer()
- {
- //check customer is exist or not
- $customer = $this->customerRepository->findOneWhere([
- 'email' => request()->email
- ]);
-
- //if customer is exist
- if (! is_null($customer)) {
- return 'true';
- }
- return 'false';
- }
-
- //login for checkout
- public function loginForCheckout()
- {
- $this->validate(request(), [
- 'email' => 'required|email'
- ]);
-
- if (! auth()->guard('customer')->attempt(request(['email', 'password']))) {
- return response()->json(['error' => trans('shop::app.customer.login-form.invalid-creds')]);
- }
-
- //Event passed to prepare cart after login
- Cart::mergeCart();
-
- return response()->json(['success' => 'Login successfully']);
- }
}
\ No newline at end of file
diff --git a/packages/Webkul/Shop/src/Http/Controllers/ProductsCategoriesProxyController.php b/packages/Webkul/Shop/src/Http/Controllers/ProductsCategoriesProxyController.php
index 6a8a0bc7b..f10fd3196 100644
--- a/packages/Webkul/Shop/src/Http/Controllers/ProductsCategoriesProxyController.php
+++ b/packages/Webkul/Shop/src/Http/Controllers/ProductsCategoriesProxyController.php
@@ -3,11 +3,7 @@
namespace Webkul\Shop\Http\Controllers;
-use Illuminate\Database\Eloquent\ModelNotFoundException;
-use Illuminate\Support\Facades\DB;
-use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
-use Webkul\Category\Models\CategoryTranslation;
-use Webkul\Product\Models\ProductFlat;
+use Illuminate\Http\Request;
use Webkul\Category\Repositories\CategoryRepository;
use Webkul\Product\Repositories\ProductRepository;
@@ -51,24 +47,31 @@ class ProductsCategoriesProxyController extends Controller
}
/**
- * Display a listing of the resource which can be a category or a product.
+ * Show product or category view. If neither category nor product matches,
+ * abort with code 404.
*
- *
- * @param string $slugOrPath
+ * @param Request $request
*
* @return \Illuminate\View\View
*/
- public function index(string $slugOrPath)
+ public function index(Request $request)
{
- if ($category = $this->categoryRepository->findByPath($slugOrPath)) {
- return view($this->_config['category_view'], compact('category'));
- }
+ $slugOrPath = trim($request->getPathInfo(), '/');
- if ($product = $this->productRepository->findBySlug($slugOrPath)) {
+ if (preg_match('/^([a-z0-9-]+\/?)+$/', $slugOrPath)) {
- $customer = auth()->guard('customer')->user();
+ if ($category = $this->categoryRepository->findByPath($slugOrPath)) {
+
+ return view($this->_config['category_view'], compact('category'));
+ }
+
+ if ($product = $this->productRepository->findBySlug($slugOrPath)) {
+
+ $customer = auth()->guard('customer')->user();
+
+ return view($this->_config['product_view'], compact('product', 'customer'));
+ }
- return view($this->_config['product_view'], compact('product', 'customer'));
}
abort(404);
diff --git a/packages/Webkul/Shop/src/Http/routes.php b/packages/Webkul/Shop/src/Http/routes.php
index 129c625fa..db644a6d0 100755
--- a/packages/Webkul/Shop/src/Http/routes.php
+++ b/packages/Webkul/Shop/src/Http/routes.php
@@ -34,10 +34,10 @@ Route::group(['middleware' => ['web', 'locale', 'theme', 'currency']], function
'view' => 'shop::checkout.cart.index'
])->name('shop.checkout.cart.index');
- Route::post('checkout/check/coupons', 'Webkul\Shop\Http\Controllers\OnepageController@applyCoupon')->name('shop.checkout.check.coupons');
-
- Route::post('checkout/remove/coupon', 'Webkul\Shop\Http\Controllers\OnepageController@removeCoupon')->name('shop.checkout.remove.coupon');
+ Route::post('checkout/cart/coupon', 'Webkul\Shop\Http\Controllers\CartController@applyCoupon')->name('shop.checkout.cart.coupon.apply');
+ Route::delete('checkout/cart/coupon', 'Webkul\Shop\Http\Controllers\CartController@removeCoupon')->name('shop.checkout.coupon.remove.coupon');
+
//Cart Items Add
Route::post('checkout/cart/add/{id}', 'Webkul\Shop\Http\Controllers\CartController@add')->defaults('_config', [
'redirect' => 'shop.checkout.cart.index'
@@ -297,13 +297,10 @@ Route::group(['middleware' => ['web', 'locale', 'theme', 'currency']], function
Route::get('page/{slug}', 'Webkul\CMS\Http\Controllers\Shop\PagePresenterController@presenter')->name('shop.cms.page');
- Route::get('{slugOrPath}', \Webkul\Shop\Http\Controllers\ProductsCategoriesProxyController::class . '@index')
+ Route::fallback(\Webkul\Shop\Http\Controllers\ProductsCategoriesProxyController::class . '@index')
->defaults('_config', [
'product_view' => 'shop::products.view',
'category_view' => 'shop::products.index'
])
- ->where('slugOrPath', '^([a-z0-9-]+\/?)+$')
->name('shop.productOrCategory.index');
-
- Route::fallback('Webkul\Shop\Http\Controllers\HomeController@notFound');
});
diff --git a/packages/Webkul/Shop/src/Resources/assets/sass/app.scss b/packages/Webkul/Shop/src/Resources/assets/sass/app.scss
index 6b4e35b19..4f6ae0e9b 100755
--- a/packages/Webkul/Shop/src/Resources/assets/sass/app.scss
+++ b/packages/Webkul/Shop/src/Resources/assets/sass/app.scss
@@ -2478,6 +2478,32 @@ section.cart {
}
}
+.coupon-container {
+ .discount-control {
+ .control-group {
+ margin-top: 20px;
+
+ .control {
+ width: 100%;
+ }
+ }
+ }
+
+ .applied-coupon-details {
+ margin-top: 30px;
+
+ .right {
+ float: right;
+
+ .icon {
+ vertical-align: text-bottom;
+ margin-bottom: 1px;
+ cursor: pointer;
+ }
+ }
+ }
+}
+
.order-summary {
h3 {
font-size: 16px;
diff --git a/packages/Webkul/Shop/src/Resources/lang/en/app.php b/packages/Webkul/Shop/src/Resources/lang/en/app.php
index 7095c10b6..27547f8c4 100755
--- a/packages/Webkul/Shop/src/Resources/lang/en/app.php
+++ b/packages/Webkul/Shop/src/Resources/lang/en/app.php
@@ -499,7 +499,8 @@ return [
'free-desc' => 'This is a free shipping',
'flat-desc' => 'This is a flat rate',
'password' => 'Password',
- 'login-exist-message' => 'You already have an account with us, Sign in or continue as guest.'
+ 'login-exist-message' => 'You already have an account with us, Sign in or continue as guest.',
+ 'enter-coupon-code' => 'Enter Coupon Code'
],
'total' => [
@@ -513,9 +514,12 @@ return [
'disc-amount' => 'Amount discounted',
'new-grand-total' => 'New Grand Total',
'coupon' => 'Coupon',
- 'coupon-applied' => 'Coupon Applied',
+ 'coupon-applied' => 'Applied Coupon',
'remove-coupon' => 'Remove Coupon',
- 'cannot-apply-coupon' => 'Cannot Apply Coupon'
+ 'cannot-apply-coupon' => 'Cannot Apply Coupon',
+ 'invalid-coupon' => 'Coupon code is invalid.',
+ 'success-coupon' => 'Coupon code applied successfully.',
+ 'coupon-apply-issue' => 'Coupon code can\'t be applied.'
],
'success' => [
diff --git a/packages/Webkul/Shop/src/Resources/views/checkout/cart/coupon.blade.php b/packages/Webkul/Shop/src/Resources/views/checkout/cart/coupon.blade.php
new file mode 100644
index 000000000..090740935
--- /dev/null
+++ b/packages/Webkul/Shop/src/Resources/views/checkout/cart/coupon.blade.php
@@ -0,0 +1,119 @@
+@if ($cart)
+
+
+
+@endif
\ No newline at end of file
diff --git a/packages/Webkul/Shop/src/Resources/views/checkout/cart/index.blade.php b/packages/Webkul/Shop/src/Resources/views/checkout/cart/index.blade.php
index 269fc5ca4..294c0c5b6 100755
--- a/packages/Webkul/Shop/src/Resources/views/checkout/cart/index.blade.php
+++ b/packages/Webkul/Shop/src/Resources/views/checkout/cart/index.blade.php
@@ -25,7 +25,7 @@
-
+
@@ -33,7 +33,7 @@
{!! view_render_event('bagisto.shop.checkout.cart.item.name.before', ['item' => $item]) !!}
@@ -127,6 +127,8 @@
@include('shop::checkout.total.summary', ['cart' => $cart])
+
+
{!! view_render_event('bagisto.shop.checkout.cart.summary.after', ['cart' => $cart]) !!}
@@ -155,6 +157,7 @@
@endsection
@push('scripts')
+ @include('shop::checkout.cart.coupon')
diff --git a/packages/Webkul/Shop/src/Resources/views/checkout/total/summary.blade.php b/packages/Webkul/Shop/src/Resources/views/checkout/total/summary.blade.php
index bbab890a3..70d5d87d6 100755
--- a/packages/Webkul/Shop/src/Resources/views/checkout/total/summary.blade.php
+++ b/packages/Webkul/Shop/src/Resources/views/checkout/total/summary.blade.php
@@ -24,15 +24,12 @@
@endif
-
base_discount_amount && $cart->base_discount_amount > 0) style="display: block;" @else style="display: none;" @endif>
- {{ __('shop::app.checkout.total.disc-amount') }}
+ {{ __('shop::app.checkout.total.disc-amount') }}
-
- {{ core()->currency($cart->base_discount_amount) }}
-
+ -{{ core()->currency($cart->base_discount_amount) }}
@@ -43,36 +40,4 @@
{{ core()->currency($cart->base_grand_total) }}
-
-