From 513b07e4cf4fca3834d8204a97cad9450a8c573f Mon Sep 17 00:00:00 2001 From: jitendra Date: Sat, 21 Dec 2019 10:55:32 +0530 Subject: [PATCH 01/13] Added new cart rule and catalog rule --- composer.json | 4 +- config/app.php | 4 +- config/concord.php | 3 +- packages/Webkul/Admin/src/Config/acl.php | 18 +- packages/Webkul/Admin/src/Config/menu.php | 20 +- .../Admin/src/DataGrids/CartRuleDataGrid.php | 123 +-- .../src/DataGrids/CatalogRuleDataGrid.php | 70 +- packages/Webkul/Admin/src/Http/routes.php | 76 +- .../Admin/src/Resources/lang/en/app.php | 259 ++--- .../promotions/cart-rule/create.blade.php | 630 ----------- .../views/promotions/cart-rule/edit.blade.php | 740 ------------- .../promotions/cart-rules/create.blade.php | 612 +++++++++++ .../promotions/cart-rules/edit.blade.php | 751 +++++++++++++ .../{cart-rule => cart-rules}/index.blade.php | 8 +- .../promotions/catalog-rule/create.blade.php | 415 -------- .../promotions/catalog-rule/edit.blade.php | 414 -------- .../promotions/catalog-rule/index.blade.php | 35 - .../promotions/catalog-rules/create.blade.php | 528 ++++++++++ .../promotions/catalog-rules/edit.blade.php | 533 ++++++++++ .../promotions/catalog-rules/index.blade.php | 27 + .../CartRule/src/Contracts/CartRule.php | 7 + .../CartRule/src/Contracts/CartRuleCoupon.php | 7 + .../src/Contracts/CartRuleCouponUsage.php | 7 + .../src/Contracts/CartRuleCustomer.php | 7 + .../src/Contracts/CartRuleTranslation.php | 7 + .../2019_05_13_024320_remove_tables.php | 43 + ..._05_13_024321_create_cart_rules_table.php} | 41 +- ...24322_create_cart_rule_channels_table.php} | 7 +- ...reate_cart_rule_customer_groups_table.php} | 8 +- ...4_create_cart_rule_translations_table.php} | 14 +- ...4325_create_cart_rule_customers_table.php} | 7 +- ...024326_create_cart_rule_coupons_table.php} | 13 +- ...27_create_cart_rule_coupon_usage_table.php | 37 + .../Webkul/CartRule/src/Helpers/CartRule.php | 494 +++++++++ .../Http/Controllers/CartRuleController.php | 206 ++++ .../Controllers/CartRuleCouponController.php | 55 + .../src/Http/Controllers/Controller.php | 4 +- .../Webkul/CartRule/src/Listeners/Cart.php | 14 + .../Webkul/CartRule/src/Listeners/Order.php | 139 +++ .../Webkul/CartRule/src/Models/CartRule.php | 66 ++ .../CartRule/src/Models/CartRuleCoupon.php | 19 + .../src/Models/CartRuleCouponProxy.php | 10 + .../src/Models/CartRuleCouponUsage.php | 15 + .../src/Models/CartRuleCouponUsageProxy.php | 9 + .../CartRule/src/Models/CartRuleCustomer.php | 13 + .../src/Models/CartRuleCustomerProxy.php | 10 + .../src/Models/CartRuleProxy.php | 2 +- .../src/Models/CartRuleTranslation.php | 13 + .../src/Models/CartRuleTranslationProxy.php | 10 + .../src/Providers/CartRuleServiceProvider.php | 30 + .../src/Providers/EventServiceProvider.php | 19 + .../src/Providers/ModuleServiceProvider.php | 16 + .../Repositories/CartRuleCouponRepository.php | 74 ++ .../CartRuleCouponUsageRepository.php | 24 + .../CartRuleCustomerRepository.php | 24 + .../src/Repositories/CartRuleRepository.php | 478 +++++++++ .../src/Console/Commands/PriceRuleIndex.php | 53 + .../CatalogRule/src/Contracts/CatalogRule.php | 7 + .../src/Contracts/CatalogRuleProduct.php | 7 + .../src/Contracts/CatalogRuleProductPrice.php | 7 + ...253_create_remove_catalog_rule_tables.php} | 18 +- ..._03_184613_create_catalog_rules_table.php} | 15 +- ...51_create_catalog_rule_channels_table.php} | 9 +- ...te_catalog_rule_customer_groups_table.php} | 10 +- ...10_create_catalog_rule_products_table.php} | 27 +- ...ate_catalog_rule_product_prices_table.php} | 32 +- .../src/Helpers/CatalogRuleIndex.php | 138 +++ .../src/Helpers/CatalogRuleProduct.php | 236 +++++ .../src/Helpers/CatalogRuleProductPrice.php | 217 ++++ .../Controllers/CatalogRuleController.php | 183 ++++ .../src/Http/Controllers/Controller.php | 13 + .../CatalogRule/src/Listeners/Product.php | 41 + .../CatalogRule/src/Models/CatalogRule.php | 33 + .../src/Models/CatalogRuleProduct.php | 13 + .../src/Models/CatalogRuleProductPrice.php | 13 + .../Models/CatalogRuleProductPriceProxy.php | 10 + .../src/Models/CatalogRuleProductProxy.php | 10 + .../src/Models/CatalogRuleProxy.php | 4 +- .../Providers/CatalogRuleServiceProvider.php | 42 + .../src/Providers/ModuleServiceProvider.php | 14 + .../CatalogRuleProductPriceRepository.php | 24 + .../CatalogRuleProductRepository.php | 24 + .../Repositories/CatalogRuleRepository.php | 225 ++++ packages/Webkul/Checkout/src/Cart.php | 4 + packages/Webkul/Core/src/Config/concord.php | 3 +- packages/Webkul/Discount/composer.json | 27 - .../Discount/src/Actions/Cart/Action.php | 98 -- .../Discount/src/Actions/Cart/FixedAmount.php | 87 -- .../src/Actions/Cart/PercentOfProduct.php | 102 -- .../src/Actions/Cart/WholeCartToFixed.php | 24 - .../src/Actions/Cart/WholeCartToPercent.php | 24 - .../Discount/src/Actions/Catalog/Action.php | 8 - .../Actions/Catalog/AdjustToDiscountValue.php | 22 - .../src/Actions/Catalog/AdjustToPercent.php | 19 - .../src/Actions/Catalog/FixedAmount.php | 20 - .../src/Actions/Catalog/PercentOfOriginal.php | 19 - .../Discount/src/Config/discount-rules.php | 18 - .../Discount/src/Config/rule-conditions.php | 174 --- .../Discount/src/Contracts/CartRule.php | 7 - .../Discount/src/Contracts/CartRuleCart.php | 7 - .../src/Contracts/CartRuleChannels.php | 6 - .../src/Contracts/CartRuleCoupons.php | 7 - .../src/Contracts/CartRuleCouponsUsage.php | 7 - .../src/Contracts/CartRuleCustomerGroups.php | 8 - .../src/Contracts/CartRuleCustomers.php | 7 - .../Discount/src/Contracts/CartRuleLabels.php | 7 - .../Discount/src/Contracts/CatalogRule.php | 7 - .../src/Contracts/CatalogRuleChannels.php | 7 - .../Contracts/CatalogRuleCustomerGroups.php | 7 - .../src/Contracts/CatalogRuleProducts.php | 8 - .../Contracts/CatalogRuleProductsPrice.php | 8 - ...6_094238_create_cart_rule_labels_table.php | 38 - ...9_create_cart_rule_coupons_usage_table.php | 39 - ..._remove_is_guest_from_cart_rules_table.php | 32 - .../src/Helpers/Cart/ConvertXToProductId.php | 292 ------ .../src/Helpers/Cart/CouponAbleRule.php | 57 - .../Discount/src/Helpers/Cart/Discount.php | 987 ------------------ .../src/Helpers/Cart/NonCouponAbleRule.php | 46 - .../src/Helpers/Cart/ValidatesDiscount.php | 26 - .../Discount/src/Helpers/Catalog/Apply.php | 541 ---------- .../Helpers/Catalog/ConvertXToProductId.php | 271 ----- .../Discount/src/Helpers/Catalog/Sale.php | 85 -- .../Http/Controllers/CartRuleController.php | 573 ---------- .../Controllers/CatalogRuleController.php | 437 -------- .../Webkul/Discount/src/Models/CartRule.php | 39 - .../Discount/src/Models/CartRuleCart.php | 22 - .../Discount/src/Models/CartRuleCartProxy.php | 10 - .../Discount/src/Models/CartRuleChannels.php | 13 - .../src/Models/CartRuleChannelsProxy.php | 10 - .../Discount/src/Models/CartRuleCoupons.php | 24 - .../src/Models/CartRuleCouponsProxy.php | 10 - .../src/Models/CartRuleCouponsUsage.php | 14 - .../src/Models/CartRuleCouponsUsageProxy.php | 9 - .../src/Models/CartRuleCustomerGroups.php | 19 - .../Models/CartRuleCustomerGroupsProxy.php | 10 - .../Discount/src/Models/CartRuleCustomers.php | 19 - .../src/Models/CartRuleCustomersProxy.php | 10 - .../src/Models/CartRuleLabelProxy.php | 10 - .../Discount/src/Models/CartRuleLabels.php | 33 - .../Discount/src/Models/CatalogRule.php | 25 - .../src/Models/CatalogRuleChannels.php | 19 - .../src/Models/CatalogRuleChannelsProxy.php | 10 - .../src/Models/CatalogRuleCustomerGroups.php | 19 - .../Models/CatalogRuleCustomerGroupsProxy.php | 10 - .../src/Models/CatalogRuleProducts.php | 15 - .../src/Models/CatalogRuleProductsPrice.php | 13 - .../Models/CatalogRuleProductsPriceProxy.php | 10 - .../src/Models/CatalogRuleProductsProxy.php | 10 - .../src/Providers/DiscountServiceProvider.php | 42 - .../src/Providers/ModuleServiceProvider.php | 24 - .../Repositories/CartRuleCartRepository.php | 24 - .../CartRuleChannelsRepository.php | 24 - .../CartRuleCouponsRepository.php | 24 - .../CartRuleCustomerGroupsRepository.php | 24 - .../Repositories/CartRuleLabelsRepository.php | 24 - .../src/Repositories/CartRuleRepository.php | 205 ---- .../CatalogRuleChannelsRepository.php | 24 - .../CatalogRuleCustomerGroupsRepository.php | 24 - .../CatalogRuleProductsPriceRepository.php | 51 - .../CatalogRuleProductsRepository.php | 39 - .../Repositories/CatalogRuleRepository.php | 155 --- .../Webkul/Rule/src/Helpers/Validator.php | 190 ++++ .../src/Providers/RuleServiceProvider.php | 26 + 163 files changed, 6230 insertions(+), 7863 deletions(-) delete mode 100644 packages/Webkul/Admin/src/Resources/views/promotions/cart-rule/create.blade.php delete mode 100644 packages/Webkul/Admin/src/Resources/views/promotions/cart-rule/edit.blade.php create mode 100644 packages/Webkul/Admin/src/Resources/views/promotions/cart-rules/create.blade.php create mode 100644 packages/Webkul/Admin/src/Resources/views/promotions/cart-rules/edit.blade.php rename packages/Webkul/Admin/src/Resources/views/promotions/{cart-rule => cart-rules}/index.blade.php (60%) delete mode 100644 packages/Webkul/Admin/src/Resources/views/promotions/catalog-rule/create.blade.php delete mode 100644 packages/Webkul/Admin/src/Resources/views/promotions/catalog-rule/edit.blade.php delete mode 100644 packages/Webkul/Admin/src/Resources/views/promotions/catalog-rule/index.blade.php create mode 100644 packages/Webkul/Admin/src/Resources/views/promotions/catalog-rules/create.blade.php create mode 100644 packages/Webkul/Admin/src/Resources/views/promotions/catalog-rules/edit.blade.php create mode 100644 packages/Webkul/Admin/src/Resources/views/promotions/catalog-rules/index.blade.php create mode 100644 packages/Webkul/CartRule/src/Contracts/CartRule.php create mode 100644 packages/Webkul/CartRule/src/Contracts/CartRuleCoupon.php create mode 100644 packages/Webkul/CartRule/src/Contracts/CartRuleCouponUsage.php create mode 100644 packages/Webkul/CartRule/src/Contracts/CartRuleCustomer.php create mode 100644 packages/Webkul/CartRule/src/Contracts/CartRuleTranslation.php create mode 100644 packages/Webkul/CartRule/src/Database/Migrations/2019_05_13_024320_remove_tables.php rename packages/Webkul/{Discount/src/Database/Migrations/2019_05_13_024326_create_cart_rule_table.php => CartRule/src/Database/Migrations/2019_05_13_024321_create_cart_rules_table.php} (52%) rename packages/Webkul/{Discount/src/Database/Migrations/2019_05_13_024340_create_cart_rule_channels_table.php => CartRule/src/Database/Migrations/2019_05_13_024322_create_cart_rule_channels_table.php} (91%) rename packages/Webkul/{Discount/src/Database/Migrations/2019_05_13_024419_create_cart_rule_customer_groups_table.php => CartRule/src/Database/Migrations/2019_05_13_024323_create_cart_rule_customer_groups_table.php} (90%) rename packages/Webkul/{Discount/src/Database/Migrations/2019_05_30_141207_create_cart_rule_cart_table.php => CartRule/src/Database/Migrations/2019_05_13_024324_create_cart_rule_translations_table.php} (54%) rename packages/Webkul/{Discount/src/Database/Migrations/2019_05_23_175727_create_cart_rule_customers_table.php => CartRule/src/Database/Migrations/2019_05_13_024325_create_cart_rule_customers_table.php} (84%) rename packages/Webkul/{Discount/src/Database/Migrations/2019_05_23_180457_create_cart_rule_coupons_table.php => CartRule/src/Database/Migrations/2019_05_13_024326_create_cart_rule_coupons_table.php} (80%) create mode 100644 packages/Webkul/CartRule/src/Database/Migrations/2019_05_13_024327_create_cart_rule_coupon_usage_table.php create mode 100644 packages/Webkul/CartRule/src/Helpers/CartRule.php create mode 100644 packages/Webkul/CartRule/src/Http/Controllers/CartRuleController.php create mode 100644 packages/Webkul/CartRule/src/Http/Controllers/CartRuleCouponController.php rename packages/Webkul/{Discount => CartRule}/src/Http/Controllers/Controller.php (87%) create mode 100644 packages/Webkul/CartRule/src/Listeners/Cart.php create mode 100755 packages/Webkul/CartRule/src/Listeners/Order.php create mode 100644 packages/Webkul/CartRule/src/Models/CartRule.php create mode 100644 packages/Webkul/CartRule/src/Models/CartRuleCoupon.php create mode 100644 packages/Webkul/CartRule/src/Models/CartRuleCouponProxy.php create mode 100644 packages/Webkul/CartRule/src/Models/CartRuleCouponUsage.php create mode 100644 packages/Webkul/CartRule/src/Models/CartRuleCouponUsageProxy.php create mode 100644 packages/Webkul/CartRule/src/Models/CartRuleCustomer.php create mode 100644 packages/Webkul/CartRule/src/Models/CartRuleCustomerProxy.php rename packages/Webkul/{Discount => CartRule}/src/Models/CartRuleProxy.php (73%) create mode 100644 packages/Webkul/CartRule/src/Models/CartRuleTranslation.php create mode 100644 packages/Webkul/CartRule/src/Models/CartRuleTranslationProxy.php create mode 100644 packages/Webkul/CartRule/src/Providers/CartRuleServiceProvider.php create mode 100755 packages/Webkul/CartRule/src/Providers/EventServiceProvider.php create mode 100644 packages/Webkul/CartRule/src/Providers/ModuleServiceProvider.php create mode 100755 packages/Webkul/CartRule/src/Repositories/CartRuleCouponRepository.php create mode 100755 packages/Webkul/CartRule/src/Repositories/CartRuleCouponUsageRepository.php create mode 100755 packages/Webkul/CartRule/src/Repositories/CartRuleCustomerRepository.php create mode 100755 packages/Webkul/CartRule/src/Repositories/CartRuleRepository.php create mode 100644 packages/Webkul/CatalogRule/src/Console/Commands/PriceRuleIndex.php create mode 100644 packages/Webkul/CatalogRule/src/Contracts/CatalogRule.php create mode 100644 packages/Webkul/CatalogRule/src/Contracts/CatalogRuleProduct.php create mode 100644 packages/Webkul/CatalogRule/src/Contracts/CatalogRuleProductPrice.php rename packages/Webkul/{Discount/src/Database/Migrations/2019_07_14_070809_add_products_selection_column_in_cart_rules_table.php => CatalogRule/src/Database/Migrations/2019_12_03_175253_create_remove_catalog_rule_tables.php} (50%) rename packages/Webkul/{Discount/src/Database/Migrations/2019_08_08_130433_create_catalog_rules_table.php => CatalogRule/src/Database/Migrations/2019_12_03_184613_create_catalog_rules_table.php} (62%) rename packages/Webkul/{Discount/src/Database/Migrations/2019_08_08_130458_create_catalog_rule_channels_table.php => CatalogRule/src/Database/Migrations/2019_12_03_184651_create_catalog_rule_channels_table.php} (91%) rename packages/Webkul/{Discount/src/Database/Migrations/2019_08_08_130451_create_catalog_rule_customer_groups_table.php => CatalogRule/src/Database/Migrations/2019_12_03_184732_create_catalog_rule_customer_groups_table.php} (86%) rename packages/Webkul/{Discount/src/Database/Migrations/2019_08_08_130550_create_catalog_rule_products_table.php => CatalogRule/src/Database/Migrations/2019_12_06_101110_create_catalog_rule_products_table.php} (80%) rename packages/Webkul/{Discount/src/Database/Migrations/2019_08_08_130583_create_catalog_rule_products_price_table.php => CatalogRule/src/Database/Migrations/2019_12_06_110507_create_catalog_rule_product_prices_table.php} (76%) create mode 100644 packages/Webkul/CatalogRule/src/Helpers/CatalogRuleIndex.php create mode 100644 packages/Webkul/CatalogRule/src/Helpers/CatalogRuleProduct.php create mode 100644 packages/Webkul/CatalogRule/src/Helpers/CatalogRuleProductPrice.php create mode 100644 packages/Webkul/CatalogRule/src/Http/Controllers/CatalogRuleController.php create mode 100644 packages/Webkul/CatalogRule/src/Http/Controllers/Controller.php create mode 100755 packages/Webkul/CatalogRule/src/Listeners/Product.php create mode 100644 packages/Webkul/CatalogRule/src/Models/CatalogRule.php create mode 100644 packages/Webkul/CatalogRule/src/Models/CatalogRuleProduct.php create mode 100644 packages/Webkul/CatalogRule/src/Models/CatalogRuleProductPrice.php create mode 100644 packages/Webkul/CatalogRule/src/Models/CatalogRuleProductPriceProxy.php create mode 100644 packages/Webkul/CatalogRule/src/Models/CatalogRuleProductProxy.php rename packages/Webkul/{Discount => CatalogRule}/src/Models/CatalogRuleProxy.php (70%) create mode 100644 packages/Webkul/CatalogRule/src/Providers/CatalogRuleServiceProvider.php create mode 100644 packages/Webkul/CatalogRule/src/Providers/ModuleServiceProvider.php create mode 100644 packages/Webkul/CatalogRule/src/Repositories/CatalogRuleProductPriceRepository.php create mode 100644 packages/Webkul/CatalogRule/src/Repositories/CatalogRuleProductRepository.php create mode 100644 packages/Webkul/CatalogRule/src/Repositories/CatalogRuleRepository.php delete mode 100644 packages/Webkul/Discount/composer.json delete mode 100644 packages/Webkul/Discount/src/Actions/Cart/Action.php delete mode 100644 packages/Webkul/Discount/src/Actions/Cart/FixedAmount.php delete mode 100644 packages/Webkul/Discount/src/Actions/Cart/PercentOfProduct.php delete mode 100644 packages/Webkul/Discount/src/Actions/Cart/WholeCartToFixed.php delete mode 100644 packages/Webkul/Discount/src/Actions/Cart/WholeCartToPercent.php delete mode 100644 packages/Webkul/Discount/src/Actions/Catalog/Action.php delete mode 100644 packages/Webkul/Discount/src/Actions/Catalog/AdjustToDiscountValue.php delete mode 100644 packages/Webkul/Discount/src/Actions/Catalog/AdjustToPercent.php delete mode 100644 packages/Webkul/Discount/src/Actions/Catalog/FixedAmount.php delete mode 100644 packages/Webkul/Discount/src/Actions/Catalog/PercentOfOriginal.php delete mode 100644 packages/Webkul/Discount/src/Config/discount-rules.php delete mode 100644 packages/Webkul/Discount/src/Config/rule-conditions.php delete mode 100644 packages/Webkul/Discount/src/Contracts/CartRule.php delete mode 100644 packages/Webkul/Discount/src/Contracts/CartRuleCart.php delete mode 100644 packages/Webkul/Discount/src/Contracts/CartRuleChannels.php delete mode 100644 packages/Webkul/Discount/src/Contracts/CartRuleCoupons.php delete mode 100644 packages/Webkul/Discount/src/Contracts/CartRuleCouponsUsage.php delete mode 100644 packages/Webkul/Discount/src/Contracts/CartRuleCustomerGroups.php delete mode 100644 packages/Webkul/Discount/src/Contracts/CartRuleCustomers.php delete mode 100644 packages/Webkul/Discount/src/Contracts/CartRuleLabels.php delete mode 100644 packages/Webkul/Discount/src/Contracts/CatalogRule.php delete mode 100644 packages/Webkul/Discount/src/Contracts/CatalogRuleChannels.php delete mode 100644 packages/Webkul/Discount/src/Contracts/CatalogRuleCustomerGroups.php delete mode 100644 packages/Webkul/Discount/src/Contracts/CatalogRuleProducts.php delete mode 100644 packages/Webkul/Discount/src/Contracts/CatalogRuleProductsPrice.php delete mode 100644 packages/Webkul/Discount/src/Database/Migrations/2019_05_16_094238_create_cart_rule_labels_table.php delete mode 100644 packages/Webkul/Discount/src/Database/Migrations/2019_05_24_113949_create_cart_rule_coupons_usage_table.php delete mode 100644 packages/Webkul/Discount/src/Database/Migrations/2019_06_25_110122_remove_is_guest_from_cart_rules_table.php delete mode 100644 packages/Webkul/Discount/src/Helpers/Cart/ConvertXToProductId.php delete mode 100644 packages/Webkul/Discount/src/Helpers/Cart/CouponAbleRule.php delete mode 100644 packages/Webkul/Discount/src/Helpers/Cart/Discount.php delete mode 100644 packages/Webkul/Discount/src/Helpers/Cart/NonCouponAbleRule.php delete mode 100644 packages/Webkul/Discount/src/Helpers/Cart/ValidatesDiscount.php delete mode 100644 packages/Webkul/Discount/src/Helpers/Catalog/Apply.php delete mode 100644 packages/Webkul/Discount/src/Helpers/Catalog/ConvertXToProductId.php delete mode 100644 packages/Webkul/Discount/src/Helpers/Catalog/Sale.php delete mode 100644 packages/Webkul/Discount/src/Http/Controllers/CartRuleController.php delete mode 100644 packages/Webkul/Discount/src/Http/Controllers/CatalogRuleController.php delete mode 100644 packages/Webkul/Discount/src/Models/CartRule.php delete mode 100644 packages/Webkul/Discount/src/Models/CartRuleCart.php delete mode 100644 packages/Webkul/Discount/src/Models/CartRuleCartProxy.php delete mode 100644 packages/Webkul/Discount/src/Models/CartRuleChannels.php delete mode 100644 packages/Webkul/Discount/src/Models/CartRuleChannelsProxy.php delete mode 100644 packages/Webkul/Discount/src/Models/CartRuleCoupons.php delete mode 100644 packages/Webkul/Discount/src/Models/CartRuleCouponsProxy.php delete mode 100644 packages/Webkul/Discount/src/Models/CartRuleCouponsUsage.php delete mode 100644 packages/Webkul/Discount/src/Models/CartRuleCouponsUsageProxy.php delete mode 100644 packages/Webkul/Discount/src/Models/CartRuleCustomerGroups.php delete mode 100644 packages/Webkul/Discount/src/Models/CartRuleCustomerGroupsProxy.php delete mode 100644 packages/Webkul/Discount/src/Models/CartRuleCustomers.php delete mode 100644 packages/Webkul/Discount/src/Models/CartRuleCustomersProxy.php delete mode 100644 packages/Webkul/Discount/src/Models/CartRuleLabelProxy.php delete mode 100644 packages/Webkul/Discount/src/Models/CartRuleLabels.php delete mode 100644 packages/Webkul/Discount/src/Models/CatalogRule.php delete mode 100644 packages/Webkul/Discount/src/Models/CatalogRuleChannels.php delete mode 100644 packages/Webkul/Discount/src/Models/CatalogRuleChannelsProxy.php delete mode 100644 packages/Webkul/Discount/src/Models/CatalogRuleCustomerGroups.php delete mode 100644 packages/Webkul/Discount/src/Models/CatalogRuleCustomerGroupsProxy.php delete mode 100644 packages/Webkul/Discount/src/Models/CatalogRuleProducts.php delete mode 100644 packages/Webkul/Discount/src/Models/CatalogRuleProductsPrice.php delete mode 100644 packages/Webkul/Discount/src/Models/CatalogRuleProductsPriceProxy.php delete mode 100644 packages/Webkul/Discount/src/Models/CatalogRuleProductsProxy.php delete mode 100644 packages/Webkul/Discount/src/Providers/DiscountServiceProvider.php delete mode 100644 packages/Webkul/Discount/src/Providers/ModuleServiceProvider.php delete mode 100644 packages/Webkul/Discount/src/Repositories/CartRuleCartRepository.php delete mode 100644 packages/Webkul/Discount/src/Repositories/CartRuleChannelsRepository.php delete mode 100644 packages/Webkul/Discount/src/Repositories/CartRuleCouponsRepository.php delete mode 100644 packages/Webkul/Discount/src/Repositories/CartRuleCustomerGroupsRepository.php delete mode 100644 packages/Webkul/Discount/src/Repositories/CartRuleLabelsRepository.php delete mode 100644 packages/Webkul/Discount/src/Repositories/CartRuleRepository.php delete mode 100644 packages/Webkul/Discount/src/Repositories/CatalogRuleChannelsRepository.php delete mode 100644 packages/Webkul/Discount/src/Repositories/CatalogRuleCustomerGroupsRepository.php delete mode 100644 packages/Webkul/Discount/src/Repositories/CatalogRuleProductsPriceRepository.php delete mode 100644 packages/Webkul/Discount/src/Repositories/CatalogRuleProductsRepository.php delete mode 100644 packages/Webkul/Discount/src/Repositories/CatalogRuleRepository.php create mode 100644 packages/Webkul/Rule/src/Helpers/Validator.php create mode 100644 packages/Webkul/Rule/src/Providers/RuleServiceProvider.php diff --git a/composer.json b/composer.json index 143e4c3b9..7b0f8e7ea 100755 --- a/composer.json +++ b/composer.json @@ -88,7 +88,9 @@ "Webkul\\Sales\\": "packages/Webkul/Sales/src", "Webkul\\Tax\\": "packages/Webkul/Tax/src", "Webkul\\API\\": "packages/Webkul/API", - "Webkul\\Discount\\": "packages/Webkul/Discount/src", + "Webkul\\CatalogRule\\": "packages/Webkul/CatalogRule/src", + "Webkul\\CartRule\\": "packages/Webkul/CartRule/src", + "Webkul\\Rule\\": "packages/Webkul/Rule/src", "Webkul\\CMS\\": "packages/Webkul/CMS/src" } }, diff --git a/config/app.php b/config/app.php index 8e675f952..1ea3304be 100755 --- a/config/app.php +++ b/config/app.php @@ -245,7 +245,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 22fe5e904..ce1da1d85 100755 --- a/packages/Webkul/Admin/src/Config/menu.php +++ b/packages/Webkul/Admin/src/Config/menu.php @@ -183,22 +183,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/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 95984bc46..da28c17f3 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/lang/en/app.php b/packages/Webkul/Admin/src/Resources/lang/en/app.php index 926e6648a..923824e7c 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' => [ @@ -940,125 +950,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' ] ], 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') - -
- -
- - @push('scripts') - - - - @endpush -@stop \ No newline at end of file diff --git a/packages/Webkul/Admin/src/Resources/views/promotions/cart-rule/edit.blade.php b/packages/Webkul/Admin/src/Resources/views/promotions/cart-rule/edit.blade.php deleted file mode 100644 index 27312c327..000000000 --- a/packages/Webkul/Admin/src/Resources/views/promotions/cart-rule/edit.blade.php +++ /dev/null @@ -1,740 +0,0 @@ -@extends('admin::layouts.content') - -@section('page_title') - {{ __('admin::app.promotion.edit-cart-rule') }} -@stop - -@section('content') - -
- -
- - @push('scripts') - - - - @endpush -@stop \ No newline at end of file diff --git a/packages/Webkul/Admin/src/Resources/views/promotions/cart-rules/create.blade.php b/packages/Webkul/Admin/src/Resources/views/promotions/cart-rules/create.blade.php new file mode 100644 index 000000000..c687601ac --- /dev/null +++ b/packages/Webkul/Admin/src/Resources/views/promotions/cart-rules/create.blade.php @@ -0,0 +1,612 @@ +@extends('admin::layouts.content') + +@section('page_title') + {{ __('admin::app.promotions.cart-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/cart-rules/edit.blade.php b/packages/Webkul/Admin/src/Resources/views/promotions/cart-rules/edit.blade.php new file mode 100644 index 000000000..4af87ddf2 --- /dev/null +++ b/packages/Webkul/Admin/src/Resources/views/promotions/cart-rules/edit.blade.php @@ -0,0 +1,751 @@ +@extends('admin::layouts.content') + +@section('page_title') + {{ __('admin::app.promotions.cart-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/cart-rule/index.blade.php b/packages/Webkul/Admin/src/Resources/views/promotions/cart-rules/index.blade.php similarity index 60% rename from packages/Webkul/Admin/src/Resources/views/promotions/cart-rule/index.blade.php rename to packages/Webkul/Admin/src/Resources/views/promotions/cart-rules/index.blade.php index cf172412a..d07bbfaef 100644 --- a/packages/Webkul/Admin/src/Resources/views/promotions/cart-rule/index.blade.php +++ b/packages/Webkul/Admin/src/Resources/views/promotions/cart-rules/index.blade.php @@ -1,7 +1,7 @@ @extends('admin::layouts.content') @section('page_title') - {{ __('admin::app.promotion.cart-rule') }} + {{ __('admin::app.promotions.cart-rules.title') }} @stop @section('content') @@ -9,12 +9,12 @@
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/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..faef6fa22 --- /dev/null +++ b/packages/Webkul/CartRule/src/Helpers/CartRule.php @@ -0,0 +1,494 @@ +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); + } + + $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; + + 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; + } + + $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(); + } +} \ 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 +{ + +} \ 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..a935da915 --- /dev/null +++ b/packages/Webkul/CartRule/src/Providers/EventServiceProvider.php @@ -0,0 +1,19 @@ + + * @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 @@ +json('products_selection')->nullable(); - }); + Schema::dropIfExists('catalog_rule_customer_groups'); + + Schema::dropIfExists('catalog_rule_channels'); + + Schema::dropIfExists('catalog_rule_products'); + + Schema::dropIfExists('catalog_rule_products_price'); + + Schema::dropIfExists('catalog_rules'); } /** @@ -25,8 +31,6 @@ class AddProductsSelectionColumnInCartRulesTable extends Migration */ public function down() { - Schema::table('cart_rules', function (Blueprint $table) { - $table->dropColumn('products_selection'); - }); + // } } diff --git a/packages/Webkul/Discount/src/Database/Migrations/2019_08_08_130433_create_catalog_rules_table.php b/packages/Webkul/CatalogRule/src/Database/Migrations/2019_12_03_184613_create_catalog_rules_table.php similarity index 62% rename from packages/Webkul/Discount/src/Database/Migrations/2019_08_08_130433_create_catalog_rules_table.php rename to packages/Webkul/CatalogRule/src/Database/Migrations/2019_12_03_184613_create_catalog_rules_table.php index 69a4a8bcc..049a531ce 100644 --- a/packages/Webkul/Discount/src/Database/Migrations/2019_08_08_130433_create_catalog_rules_table.php +++ b/packages/Webkul/CatalogRule/src/Database/Migrations/2019_12_03_184613_create_catalog_rules_table.php @@ -15,16 +15,17 @@ class CreateCatalogRulesTable extends Migration { Schema::create('catalog_rules', function (Blueprint $table) { $table->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..3d8336caf --- /dev/null +++ b/packages/Webkul/CatalogRule/src/Helpers/CatalogRuleIndex.php @@ -0,0 +1,138 @@ +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 { + $productIds = []; + + if ($product->type == 'configurable') { + $productIds = $product->variants()->pluck('id')->toArray(); + } else { + $productIds[] = $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..31a046554 --- /dev/null +++ b/packages/Webkul/CatalogRule/src/Helpers/CatalogRuleProduct.php @@ -0,0 +1,236 @@ +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') + ->where('product_flat.status', 1) + ->whereIn('channels.id', $rule->channels()->pluck('id')->toArray()); + + if ($product) + $qb->where('products.id', $product->id); + + foreach ($rule->conditions as $condition) { + if (! $condition['attribute'] || ! $condition['value']) + continue; + + $chunks = explode('|', $condition['attribute']); + + $qb = $this->addAttributeToSelect(end($chunks), $qb); + } + + return $qb; + }); + + $validatedProductIds = []; + + foreach ($qb->get() as $product) { + if ($this->validator->validate($rule, $product)) { + if ($product->type == 'configurable') { + $validatedProductIds = array_merge($validatedProductIds, $product->variants()->pluck('id')->toArray()); + } 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('product_flat', 'catalog_rule_products.product_id', '=', 'product_flat.product_id') + ->where('product_flat.status', 1) + ->addSelect('product_flat.price') + ->orderBy('channel_id', 'asc') + ->orderBy('customer_group_id', 'asc') + ->orderBy('product_id', 'asc') + ->orderBy('catalog_rule_id', 'asc'); + + if ($product) { + if ($product->type == 'configurable') { + $qb->whereIn('catalog_rule_products.product_id', $product->variants()->pluck('id')->toArray()); + } 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..7ac80d9fb 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; @@ -650,6 +652,8 @@ class Cart { $cart->items_qty = $quantities; $cart->save(); + + Event::fire('checkout.cart.collect.totals.after', $cart); } /** 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 2bcacf39d..000000000 --- a/packages/Webkul/Discount/src/Actions/Cart/Action.php +++ /dev/null @@ -1,98 +0,0 @@ -matchedItems = collect(); - } - - abstract public function calculate($rule); - - /** - * To find the eligble items for the current rule, - * - * @param CartRule $rule - * @return Collection $matchedItems - */ - public function getEligibleItems() - { - $rule = $this->rule; - - $cart = \Cart::getCart(); - - $items = $cart->items()->get(); - - if ($this->rule->action_type == 'whole_cart_to_percent' || $this->rule->action_type == 'whole_cart_to_fixed_amount') - $this->matchedItems = $items; - - if (! $rule->uses_attribute_conditions) { - $this->matchedItems = $items; - - return $this->matchedItems; - } 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) - $this->matchedItems->push($children); - } - - if ($item->product_id == $productID) - $this->matchedItems->push($item); - } - } - - return $this->matchedItems; - } - } - - /** - * 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 db3907920..000000000 --- a/packages/Webkul/Discount/src/Actions/Cart/FixedAmount.php +++ /dev/null @@ -1,87 +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(); - - $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) * $rule->disc_amount; - - $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($rule->disc_amount, 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 a21db2d8f..000000000 --- a/packages/Webkul/Discount/src/Actions/Cart/PercentOfProduct.php +++ /dev/null @@ -1,102 +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(); - - foreach ($eligibleItems as $item) { - $report = array(); - - $report['item_id'] = $item->id; - $report['child_items'] = collect(); - - $itemPrice = $item->base_price; - $itemQuantity = $item->quantity; - - $discQuantity = $this->rule->disc_quantity; - $discQuantity = $itemQuantity <= $discQuantity ? $itemQuantity : $discQuantity; - - $discountAmount = ($this->rule->disc_amount > 100) ? 100 : $this->rule->disc_amount; - - $discount = $itemPrice * ($discountAmount / 100) * $discQuantity; - $discount = $discount <= $itemPrice * $discQuantity ? $discount : $itemPrice * $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) * ($item->base_total * ($this->rule->disc_amount / 100)); - - $children->discount = $children->base_total > $children->discount ? $children->discount : $children->base_total; - - $report['child_items']->push($children); - } - } - } else { - $report['product_id'] = $item->product_id; - } - - $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/Database/Migrations/2019_06_25_110122_remove_is_guest_from_cart_rules_table.php b/packages/Webkul/Discount/src/Database/Migrations/2019_06_25_110122_remove_is_guest_from_cart_rules_table.php deleted file mode 100644 index a34fe12d9..000000000 --- a/packages/Webkul/Discount/src/Database/Migrations/2019_06_25_110122_remove_is_guest_from_cart_rules_table.php +++ /dev/null @@ -1,32 +0,0 @@ -dropColumn('is_guest'); - }); - } - - /** - * Reverse the migrations. - * - * @return void - */ - public function down() - { - Schema::table('cart_rules', function (Blueprint $table) { - $table->boolean('is_guest')->default(0); - }); - } -} 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 59436eadc..000000000 --- a/packages/Webkul/Discount/src/Helpers/Cart/Discount.php +++ /dev/null @@ -1,987 +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; - } - } - } - - 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 962d65389..000000000 --- a/packages/Webkul/Discount/src/Helpers/Catalog/Apply.php +++ /dev/null @@ -1,541 +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 ($product->type == 'configurable') { - $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 c71d6c4e4..000000000 --- a/packages/Webkul/Discount/src/Helpers/Catalog/ConvertXToProductId.php +++ /dev/null @@ -1,271 +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->name != 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', '!=', 'configurable'] - ])->flatten()->all(); - } else if ($testCondition == '!{}') { - $foundProducts = $this->product->findWhere([ - ['sku', 'not like', '%' . $testValue . '%'], - ['type', '!=', 'configurable'] - ])->flatten()->all(); - } else if ($testCondition == '=') { - $foundProducts = $this->product->findWhere([ - ['sku', '=', $testValue], - ['type', '!=', 'configurable'] - ])->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/Rule/src/Helpers/Validator.php b/packages/Webkul/Rule/src/Helpers/Validator.php new file mode 100644 index 000000000..06a623f43 --- /dev/null +++ b/packages/Webkul/Rule/src/Helpers/Validator.php @@ -0,0 +1,190 @@ +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++; + + $attributeValue = $this->getAttributeValue($condition, $entity); + + if ($rule->condition_type == 1) { + if (! $this->validateAttribute($condition['operator'], $attributeValue, $condition['value'])) { + return false; + } else { + $validConditionCount++; + } + } else { + if ($this->validateAttribute($condition['operator'], $attributeValue, $condition['value'])) + return true; + } + } + + return $validConditionCount == $totalConditionCount ? true : false; + } + + /** + * Return value for the attribute + * + * @param array $condition + * @param Cart|CartItem|Product $entity + * @return boolean + */ + public function getAttributeValue($condition, $entity) + { + $chunks = explode('|', $condition['attribute']); + + $attributeNameChunks = explode('::', $chunks[1]); + + $attributeCode = $attributeNameChunks[count($attributeNameChunks) - 1]; + + $attributeScope = count($attributeNameChunks) == 2 ? $attributeNameChunks[0] : null; + + 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 = $attributeScope == 'children' + ? ($entity->child ? $entity->child->product->categories()->pluck('id')->toArray() : []) + : ($entity->product + ? $entity->product->categories()->pluck('id')->toArray() + : $entity->categories()->pluck('id')->toArray() + ); + + return $value; + } else { + $value = $attributeScope == 'children' + ? ($entity->child ? $entity->child->product->{$attributeCode} : null) + : ($entity->product ? $entity->product->{$attributeCode} : $entity->{$attributeCode}); + + if (! in_array($condition['attribute_type'], ['multiselect', 'checkbox'])) + return $value; + + return $value ? explode(',', $value) : []; + } + } + } + + /** + * Validate attribute value for condition + * + * @param string $operator + * @param mixed $attributeValue + * @param mixed $conditionValue + * @return boolean + */ + public function validateAttribute($operator, $attributeValue, $conditionValue) + { + switch ($operator) { + case '==': case '!=': + if (is_array($conditionValue)) { + if (! is_array($attributeValue)) + return false; + + $result = ! empty(array_intersect($conditionValue, $attributeValue)); + } else { + if (is_array($attributeValue)) { + $result = count($attributeValue) == 1 && array_shift($attributeValue) == $conditionValue; + } else { + $result = $attributeValue == $conditionValue; + } + } + + break; + + case '<=': case '>': + if (! is_scalar($attributeValue)) + return false; + + $result = $attributeValue <= $conditionValue; + + break; + + case '>=': case '<': + if (! is_scalar($attributeValue)) + return false; + + $result = $attributeValue >= $conditionValue; + + break; + + case '{}': case '!{}': + if (is_scalar($attributeValue) && is_array($conditionValue)) { + foreach ($conditionValue as $item) { + if (stripos($attributeValue, $item) !== false) { + $result = true; + + break; + } + } + } else if (is_array($conditionValue)) { + if (! is_array($attributeValue)) + return false; + + $result = ! empty(array_intersect($conditionValue, $attributeValue)); + } else { + if (is_array($attributeValue)) { + $result = in_array($conditionValue, $attributeValue); + } else { + $result = (strpos($attributeValue, $conditionValue) !== false) ? true : false; + } + } + + break; + } + + if (in_array($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 @@ + Date: Sat, 21 Dec 2019 13:01:16 +0530 Subject: [PATCH 02/13] Added changes on core packages for discount --- .../assets/sass/partials/_configuration.scss | 25 ++++ .../src/Helpers/CatalogRuleProduct.php | 3 + packages/Webkul/Checkout/src/Cart.php | 43 ++++++- ...ied_cart_rule_ids_column_in_cart_table.php | 32 +++++ ...rt_rule_ids_column_in_cart_items_table.php | 32 +++++ ...t_columns_in_cart_shipping_rates_table.php | 33 +++++ .../Checkout/src/Models/CartShippingRate.php | 2 +- ...d_cart_rule_ids_column_in_orders_table.php | 32 +++++ .../src/Http/Controllers/CartController.php | 48 +++++++ packages/Webkul/Shop/src/Http/routes.php | 6 +- .../Shop/src/Resources/assets/sass/app.scss | 26 ++++ .../views/checkout/cart/coupon.blade.php | 119 ++++++++++++++++++ 12 files changed, 395 insertions(+), 6 deletions(-) create mode 100644 packages/Webkul/Checkout/src/Database/Migrations/2019_11_25_171136_add_applied_cart_rule_ids_column_in_cart_table.php create mode 100644 packages/Webkul/Checkout/src/Database/Migrations/2019_11_25_171208_add_applied_cart_rule_ids_column_in_cart_items_table.php create mode 100644 packages/Webkul/Checkout/src/Database/Migrations/2019_11_30_165644_add_discount_columns_in_cart_shipping_rates_table.php create mode 100644 packages/Webkul/Sales/src/Database/Migrations/2019_11_30_124437_add_applied_cart_rule_ids_column_in_orders_table.php create mode 100644 packages/Webkul/Shop/src/Resources/views/checkout/cart/coupon.blade.php 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/CatalogRule/src/Helpers/CatalogRuleProduct.php b/packages/Webkul/CatalogRule/src/Helpers/CatalogRuleProduct.php index 31a046554..f700fb5fe 100644 --- a/packages/Webkul/CatalogRule/src/Helpers/CatalogRuleProduct.php +++ b/packages/Webkul/CatalogRule/src/Helpers/CatalogRuleProduct.php @@ -130,6 +130,9 @@ class CatalogRuleProduct if ($product) $qb->where('products.id', $product->id); + if (! $rule->conditions) + return $qb; + foreach ($rule->conditions as $condition) { if (! $condition['attribute'] || ! $condition['value']) continue; diff --git a/packages/Webkul/Checkout/src/Cart.php b/packages/Webkul/Checkout/src/Cart.php index 7ac80d9fb..8d772a56c 100755 --- a/packages/Webkul/Checkout/src/Cart.php +++ b/packages/Webkul/Checkout/src/Cart.php @@ -638,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; } @@ -839,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']), @@ -976,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/Checkout/src/Database/Migrations/2019_11_25_171136_add_applied_cart_rule_ids_column_in_cart_table.php b/packages/Webkul/Checkout/src/Database/Migrations/2019_11_25_171136_add_applied_cart_rule_ids_column_in_cart_table.php new file mode 100644 index 000000000..b6423d3be --- /dev/null +++ b/packages/Webkul/Checkout/src/Database/Migrations/2019_11_25_171136_add_applied_cart_rule_ids_column_in_cart_table.php @@ -0,0 +1,32 @@ +string('applied_cart_rule_ids')->nullable(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('cart', function (Blueprint $table) { + // + }); + } +} diff --git a/packages/Webkul/Checkout/src/Database/Migrations/2019_11_25_171208_add_applied_cart_rule_ids_column_in_cart_items_table.php b/packages/Webkul/Checkout/src/Database/Migrations/2019_11_25_171208_add_applied_cart_rule_ids_column_in_cart_items_table.php new file mode 100644 index 000000000..cb22375bf --- /dev/null +++ b/packages/Webkul/Checkout/src/Database/Migrations/2019_11_25_171208_add_applied_cart_rule_ids_column_in_cart_items_table.php @@ -0,0 +1,32 @@ +string('applied_cart_rule_ids')->nullable(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + 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/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/Sales/src/Database/Migrations/2019_11_30_124437_add_applied_cart_rule_ids_column_in_orders_table.php b/packages/Webkul/Sales/src/Database/Migrations/2019_11_30_124437_add_applied_cart_rule_ids_column_in_orders_table.php new file mode 100644 index 000000000..6ee96be4b --- /dev/null +++ b/packages/Webkul/Sales/src/Database/Migrations/2019_11_30_124437_add_applied_cart_rule_ids_column_in_orders_table.php @@ -0,0 +1,32 @@ +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/routes.php b/packages/Webkul/Shop/src/Http/routes.php index 129c625fa..2ba7c3ff9 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' 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/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 From 795561ea58608bc96d81c1afcf89c7f4b6900dcc Mon Sep 17 00:00:00 2001 From: jitendra Date: Sat, 21 Dec 2019 16:00:22 +0530 Subject: [PATCH 03/13] Made all changes for discount packages --- .../src/DataGrids/CartRuleCouponDataGrid.php | 86 ++++++++++++ .../views/sales/orders/view.blade.php | 8 +- .../Webkul/CartRule/src/Helpers/CartRule.php | 2 + .../Webkul/CartRule/src/Listeners/Cart.php | 29 ++++ .../src/Providers/EventServiceProvider.php | 2 + .../src/Helpers/CatalogRuleProduct.php | 3 +- packages/Webkul/Checkout/src/Models/Cart.php | 2 - .../Http/Controllers/OnepageController.php | 132 ++++++------------ .../Webkul/Shop/src/Resources/lang/en/app.php | 11 +- .../views/checkout/cart/index.blade.php | 3 + .../views/checkout/onepage.blade.php | 77 ++-------- .../views/checkout/total/summary.blade.php | 39 +----- 12 files changed, 194 insertions(+), 200 deletions(-) create mode 100644 packages/Webkul/Admin/src/DataGrids/CartRuleCouponDataGrid.php 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/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/Helpers/CartRule.php b/packages/Webkul/CartRule/src/Helpers/CartRule.php index faef6fa22..942fe77ea 100644 --- a/packages/Webkul/CartRule/src/Helpers/CartRule.php +++ b/packages/Webkul/CartRule/src/Helpers/CartRule.php @@ -380,6 +380,8 @@ class CartRule break; } + $selectedShipping->save(); + $cartAppliedCartRuleIds = array_merge(explode(',', $cart->applied_cart_rule_ids), $appliedRuleIds); $cartAppliedCartRuleIds = array_filter($cartAppliedCartRuleIds); diff --git a/packages/Webkul/CartRule/src/Listeners/Cart.php b/packages/Webkul/CartRule/src/Listeners/Cart.php index f886166b4..f039059c1 100644 --- a/packages/Webkul/CartRule/src/Listeners/Cart.php +++ b/packages/Webkul/CartRule/src/Listeners/Cart.php @@ -2,6 +2,8 @@ namespace Webkul\CartRule\Listeners; +use Webkul\CartRule\Helpers\CartRule; + /** * Cart event handler * @@ -10,5 +12,32 @@ namespace Webkul\CartRule\Listeners; */ 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/Providers/EventServiceProvider.php b/packages/Webkul/CartRule/src/Providers/EventServiceProvider.php index a935da915..a5b5d7133 100755 --- a/packages/Webkul/CartRule/src/Providers/EventServiceProvider.php +++ b/packages/Webkul/CartRule/src/Providers/EventServiceProvider.php @@ -15,5 +15,7 @@ class EventServiceProvider extends ServiceProvider public function boot() { Event::listen('checkout.order.save.after', 'Webkul\CartRule\Listeners\Order@manageCartRule'); + + Event::listen('checkout.cart.collect.totals.before', 'Webkul\CartRule\Listeners\Cart@applyCartRules'); } } \ No newline at end of file diff --git a/packages/Webkul/CatalogRule/src/Helpers/CatalogRuleProduct.php b/packages/Webkul/CatalogRule/src/Helpers/CatalogRuleProduct.php index f700fb5fe..5be4b124f 100644 --- a/packages/Webkul/CatalogRule/src/Helpers/CatalogRuleProduct.php +++ b/packages/Webkul/CatalogRule/src/Helpers/CatalogRuleProduct.php @@ -134,7 +134,7 @@ class CatalogRuleProduct return $qb; foreach ($rule->conditions as $condition) { - if (! $condition['attribute'] || ! $condition['value']) + if (! $condition['attribute'] || ! isset($condition['value']) || is_null($condition['value']) || $condition['value'] == '') continue; $chunks = explode('|', $condition['attribute']); @@ -204,6 +204,7 @@ class CatalogRuleProduct ->orderBy('channel_id', 'asc') ->orderBy('customer_group_id', 'asc') ->orderBy('product_id', 'asc') + ->orderBy('sort_order', 'asc') ->orderBy('catalog_rule_id', 'asc'); if ($product) { 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/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/Resources/lang/en/app.php b/packages/Webkul/Shop/src/Resources/lang/en/app.php index 7095c10b6..c538d53b8 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,13 @@ 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.', + 'remove-coupon' => 'Coupon code removed successfully.', + 'coupon-apply-issue' => 'Coupon code can\'t be applied.' ], 'success' => [ 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..72aa3c9bd 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 @@ -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>
@@ -43,36 +40,4 @@ {{ core()->currency($cart->base_grand_total) }} - -
is('checkout/cart')) v-if="parseInt(discount)" @endif> - @if (! request()->is('checkout/cart')) - @if (! $cart->coupon_code) -
-
-
-
- -
- -
* @{{ error_message }}
- - -
-
-
- @else -
-
- - - -
-
- @endif - @endif -
\ No newline at end of file From 7aba45486f2ce974e42865715c1ff77895f3927b Mon Sep 17 00:00:00 2001 From: jitendra Date: Wed, 25 Dec 2019 19:57:05 +0530 Subject: [PATCH 04/13] Indexes created for all product types --- CHANGELOG for v0.1.x.md | 64 ++++++++++ CHANGELOG for v0.2.x.md | 17 +++ .../promotions/cart-rules/create.blade.php | 8 +- .../promotions/cart-rules/edit.blade.php | 10 +- .../Webkul/CartRule/src/Helpers/CartRule.php | 27 ++++ .../src/Helpers/CatalogRuleIndex.php | 13 +- .../src/Helpers/CatalogRuleProduct.php | 25 +++- .../Webkul/Product/src/Type/AbstractType.php | 39 +++++- packages/Webkul/Product/src/Type/Bundle.php | 27 ++++ .../Webkul/Product/src/Type/Configurable.php | 10 ++ packages/Webkul/Product/src/Type/Grouped.php | 10 ++ .../Webkul/Rule/src/Helpers/Validator.php | 118 +++++++++++++----- .../Webkul/Shop/src/Resources/lang/en/app.php | 1 - 13 files changed, 314 insertions(+), 55 deletions(-) create mode 100644 CHANGELOG for v0.2.x.md 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/packages/Webkul/Admin/src/Resources/views/promotions/cart-rules/create.blade.php b/packages/Webkul/Admin/src/Resources/views/promotions/cart-rules/create.blade.php index c687601ac..6ced9889a 100644 --- a/packages/Webkul/Admin/src/Resources/views/promotions/cart-rules/create.blade.php +++ b/packages/Webkul/Admin/src/Resources/views/promotions/cart-rules/create.blade.php @@ -199,7 +199,7 @@
- @@ -236,7 +236,7 @@
- @@ -380,7 +380,9 @@ condition_type: 1, - conditions: [] + conditions: [], + + action_type: "{{ old('action_type') ?: 'by_percent' }}" } }, diff --git a/packages/Webkul/Admin/src/Resources/views/promotions/cart-rules/edit.blade.php b/packages/Webkul/Admin/src/Resources/views/promotions/cart-rules/edit.blade.php index 4af87ddf2..cdc051a59 100644 --- a/packages/Webkul/Admin/src/Resources/views/promotions/cart-rules/edit.blade.php +++ b/packages/Webkul/Admin/src/Resources/views/promotions/cart-rules/edit.blade.php @@ -164,7 +164,7 @@
- +
@@ -205,7 +205,7 @@ action_type ?> - @@ -246,7 +246,7 @@ apply_to_shipping ?> - @@ -472,7 +472,9 @@ condition_type: {{ old('condition_type') ?: $cartRule->condition_type }}, - conditions: @json($cartRule->conditions ?: []) + conditions: @json($cartRule->conditions ?: []), + + action_type: "{{ old('action_type') ?: $cartRule->action_type }}" } }, diff --git a/packages/Webkul/CartRule/src/Helpers/CartRule.php b/packages/Webkul/CartRule/src/Helpers/CartRule.php index 942fe77ea..8ad0c4dac 100644 --- a/packages/Webkul/CartRule/src/Helpers/CartRule.php +++ b/packages/Webkul/CartRule/src/Helpers/CartRule.php @@ -106,6 +106,9 @@ class CartRule foreach ($cart->items()->get() as $item) { $this->process($item); + + if ($item->children()->count() && $item->product->getTypeInstance()->isChildrenCalculated()) + $this->devideDiscount($item); } $this->processShippingDiscount($cart); @@ -231,6 +234,8 @@ class CartRule $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); @@ -493,4 +498,26 @@ class CartRule 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/CatalogRule/src/Helpers/CatalogRuleIndex.php b/packages/Webkul/CatalogRule/src/Helpers/CatalogRuleIndex.php index 3d8336caf..fd9b6cc5f 100644 --- a/packages/Webkul/CatalogRule/src/Helpers/CatalogRuleIndex.php +++ b/packages/Webkul/CatalogRule/src/Helpers/CatalogRuleIndex.php @@ -78,13 +78,12 @@ class CatalogRuleIndex public function reindexProduct($product) { try { - $productIds = []; - - if ($product->type == 'configurable') { - $productIds = $product->variants()->pluck('id')->toArray(); - } else { - $productIds[] = $product->id; - } + if (! $product->getTypeInstance()->priceRuleCanBeApplied()) + return; + + $productIds = $product->getTypeInstance()->isComposite() + ? $product->getTypeInstance()->getChildrenIds() + : [$product->id]; $this->cleanIndexes($productIds); diff --git a/packages/Webkul/CatalogRule/src/Helpers/CatalogRuleProduct.php b/packages/Webkul/CatalogRule/src/Helpers/CatalogRuleProduct.php index 5be4b124f..38eb6e439 100644 --- a/packages/Webkul/CatalogRule/src/Helpers/CatalogRuleProduct.php +++ b/packages/Webkul/CatalogRule/src/Helpers/CatalogRuleProduct.php @@ -133,9 +133,17 @@ class CatalogRuleProduct if (! $rule->conditions) return $qb; + $appliedAttributes = []; + foreach ($rule->conditions as $condition) { - if (! $condition['attribute'] || ! isset($condition['value']) || is_null($condition['value']) || $condition['value'] == '') + 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']); @@ -148,9 +156,12 @@ class CatalogRuleProduct $validatedProductIds = []; foreach ($qb->get() as $product) { + if (! $product->getTypeInstance()->priceRuleCanBeApplied()) + continue; + if ($this->validator->validate($rule, $product)) { - if ($product->type == 'configurable') { - $validatedProductIds = array_merge($validatedProductIds, $product->variants()->pluck('id')->toArray()); + if ($product->getTypeInstance()->isComposite()) { + $validatedProductIds = array_merge($validatedProductIds, $product->getTypeInstance()->getChildrenIds()); } else { $validatedProductIds[] = $product->id; } @@ -208,8 +219,12 @@ class CatalogRuleProduct ->orderBy('catalog_rule_id', 'asc'); if ($product) { - if ($product->type == 'configurable') { - $qb->whereIn('catalog_rule_products.product_id', $product->variants()->pluck('id')->toArray()); + + 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); } diff --git a/packages/Webkul/Product/src/Type/AbstractType.php b/packages/Webkul/Product/src/Type/AbstractType.php index 39568653d..a761d5b2a 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. * @@ -250,6 +257,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 * @@ -289,11 +316,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 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..ec2fc4c39 100644 --- a/packages/Webkul/Product/src/Type/Grouped.php +++ b/packages/Webkul/Product/src/Type/Grouped.php @@ -104,6 +104,16 @@ 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()); + } + /** * Get product minimal price * diff --git a/packages/Webkul/Rule/src/Helpers/Validator.php b/packages/Webkul/Rule/src/Helpers/Validator.php index 06a623f43..ac510f314 100644 --- a/packages/Webkul/Rule/src/Helpers/Validator.php +++ b/packages/Webkul/Rule/src/Helpers/Validator.php @@ -29,16 +29,14 @@ class Validator $totalConditionCount++; - $attributeValue = $this->getAttributeValue($condition, $entity); - if ($rule->condition_type == 1) { - if (! $this->validateAttribute($condition['operator'], $attributeValue, $condition['value'])) { + if (! $this->validateObject($condition, $entity)) { return false; } else { $validConditionCount++; } } else { - if ($this->validateAttribute($condition['operator'], $attributeValue, $condition['value'])) + if ($this->validateObject($condition, $entity)) return true; } } @@ -49,8 +47,8 @@ class Validator /** * Return value for the attribute * - * @param array $condition - * @param Cart|CartItem|Product $entity + * @param array $condition + * @param CartItem|Product $entity * @return boolean */ public function getAttributeValue($condition, $entity) @@ -61,8 +59,6 @@ class Validator $attributeCode = $attributeNameChunks[count($attributeNameChunks) - 1]; - $attributeScope = count($attributeNameChunks) == 2 ? $attributeNameChunks[0] : null; - switch (current($chunks)) { case 'cart': $cart = $entity instanceof \Webkul\Checkout\Contracts\Cart ? $entity : $entity->cart; @@ -93,18 +89,15 @@ class Validator case 'product': if ($attributeCode == 'category_ids') { - $value = $attributeScope == 'children' - ? ($entity->child ? $entity->child->product->categories()->pluck('id')->toArray() : []) - : ($entity->product + $value = $entity->product ? $entity->product->categories()->pluck('id')->toArray() - : $entity->categories()->pluck('id')->toArray() - ); + : $entity->categories()->pluck('id')->toArray(); return $value; } else { - $value = $attributeScope == 'children' - ? ($entity->child ? $entity->child->product->{$attributeCode} : null) - : ($entity->product ? $entity->product->{$attributeCode} : $entity->{$attributeCode}); + $value = $entity->product + ? $entity->product->{$attributeCode} + : $entity->{$attributeCode}; if (! in_array($condition['attribute_type'], ['multiselect', 'checkbox'])) return $value; @@ -114,28 +107,85 @@ class Validator } } + /** + * 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 string $operator - * @param mixed $attributeValue - * @param mixed $conditionValue + * @param array $condition + * @param mixed $attributeValue * @return boolean */ - public function validateAttribute($operator, $attributeValue, $conditionValue) + public function validateAttribute($condition, $attributeValue) { - switch ($operator) { + switch ($condition['operator']) { case '==': case '!=': - if (is_array($conditionValue)) { + if (is_array($condition['value'])) { if (! is_array($attributeValue)) return false; - $result = ! empty(array_intersect($conditionValue, $attributeValue)); + $result = ! empty(array_intersect($condition['value'], $attributeValue)); } else { if (is_array($attributeValue)) { - $result = count($attributeValue) == 1 && array_shift($attributeValue) == $conditionValue; + $result = count($attributeValue) == 1 && array_shift($attributeValue) == $condition['value']; } else { - $result = $attributeValue == $conditionValue; + $result = $attributeValue == $condition['value']; } } @@ -145,7 +195,7 @@ class Validator if (! is_scalar($attributeValue)) return false; - $result = $attributeValue <= $conditionValue; + $result = $attributeValue <= $condition['value']; break; @@ -153,36 +203,36 @@ class Validator if (! is_scalar($attributeValue)) return false; - $result = $attributeValue >= $conditionValue; + $result = $attributeValue >= $condition['value']; break; case '{}': case '!{}': - if (is_scalar($attributeValue) && is_array($conditionValue)) { - foreach ($conditionValue as $item) { + 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($conditionValue)) { + } else if (is_array($condition['value'])) { if (! is_array($attributeValue)) return false; - $result = ! empty(array_intersect($conditionValue, $attributeValue)); + $result = ! empty(array_intersect($condition['value'], $attributeValue)); } else { if (is_array($attributeValue)) { - $result = in_array($conditionValue, $attributeValue); + $result = in_array($condition['value'], $attributeValue); } else { - $result = (strpos($attributeValue, $conditionValue) !== false) ? true : false; + $result = (strpos($attributeValue, $condition['value']) !== false) ? true : false; } } break; } - if (in_array($operator, ['!=', '>', '<', '!{}'])) + if (in_array($condition['operator'], ['!=', '>', '<', '!{}'])) $result = ! $result; return $result; diff --git a/packages/Webkul/Shop/src/Resources/lang/en/app.php b/packages/Webkul/Shop/src/Resources/lang/en/app.php index c538d53b8..27547f8c4 100755 --- a/packages/Webkul/Shop/src/Resources/lang/en/app.php +++ b/packages/Webkul/Shop/src/Resources/lang/en/app.php @@ -519,7 +519,6 @@ return [ 'cannot-apply-coupon' => 'Cannot Apply Coupon', 'invalid-coupon' => 'Coupon code is invalid.', 'success-coupon' => 'Coupon code applied successfully.', - 'remove-coupon' => 'Coupon code removed successfully.', 'coupon-apply-issue' => 'Coupon code can\'t be applied.' ], From dc89cd651194ffb5f9d84a3c71dbf1714cbd5186 Mon Sep 17 00:00:00 2001 From: MonaHartdegen Date: Thu, 2 Jan 2020 13:14:53 +0100 Subject: [PATCH 05/13] fixed product links in two views (replaced hard coded link with route) --- .../Shop/src/Resources/views/checkout/cart/index.blade.php | 4 ++-- .../Resources/views/customers/account/reviews/index.blade.php | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) 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..6e34cc901 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]) !!} diff --git a/packages/Webkul/Shop/src/Resources/views/customers/account/reviews/index.blade.php b/packages/Webkul/Shop/src/Resources/views/customers/account/reviews/index.blade.php index 0e24927d6..a456ae557 100755 --- a/packages/Webkul/Shop/src/Resources/views/customers/account/reviews/index.blade.php +++ b/packages/Webkul/Shop/src/Resources/views/customers/account/reviews/index.blade.php @@ -36,13 +36,13 @@
getProductBaseImage($review->product); ?> - +
From 297165859f551d2b501d3d9d17cae167bb514709 Mon Sep 17 00:00:00 2001 From: rahul shukla Date: Fri, 3 Jan 2020 15:35:56 +0530 Subject: [PATCH 06/13] foter text change --- packages/Webkul/Admin/src/Resources/lang/ar/app.php | 6 +++++- packages/Webkul/Admin/src/Resources/lang/en/app.php | 6 +++++- packages/Webkul/Admin/src/Resources/lang/fa/app.php | 6 +++++- .../Webkul/Admin/src/Resources/lang/pt_BR/app.php | 6 +++++- .../src/Resources/views/layouts/master.blade.php | 12 +++++++++++- 5 files changed, 31 insertions(+), 5 deletions(-) diff --git a/packages/Webkul/Admin/src/Resources/lang/ar/app.php b/packages/Webkul/Admin/src/Resources/lang/ar/app.php index 12f184e84..6938e5bcc 100644 --- a/packages/Webkul/Admin/src/Resources/lang/ar/app.php +++ b/packages/Webkul/Admin/src/Resources/lang/ar/app.php @@ -852,7 +852,11 @@ return [ ], 'footer' => [ - 'copy-right' => '© Copyright 2018 Webkul Software, All rights reserved.' + 'copy-right' => '© Copyright 2018 Webkul Software, All rights reserved.', + 'powered-by' => 'Powered by', + 'community-by' => 'Community Project by', + 'bagisto' => 'Bagisto', + 'webkul' => '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 8b9c7028d..e7e5392a7 100755 --- a/packages/Webkul/Admin/src/Resources/lang/en/app.php +++ b/packages/Webkul/Admin/src/Resources/lang/en/app.php @@ -1171,7 +1171,11 @@ return [ ], 'footer' => [ - 'copy-right' => '© Copyright 2018 Webkul Software, All rights reserved.' + 'copy-right' => '© Copyright 2018 Webkul Software, All rights reserved.', + 'powered-by' => 'Powered by', + 'community-by' => 'Community Project by', + 'bagisto' => 'Bagisto', + 'webkul' => '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..3046ffb55 100644 --- a/packages/Webkul/Admin/src/Resources/lang/fa/app.php +++ b/packages/Webkul/Admin/src/Resources/lang/fa/app.php @@ -998,7 +998,11 @@ return [ ], 'footer' => [ - 'copy-right' => '© کپی رایت 2019 کلیه حقوق محفوظ است.' + 'copy-right' => '© کپی رایت 2019 کلیه حقوق محفوظ است.', + 'powered-by' => 'Powered by', + 'community-by' => 'Community Project by', + 'bagisto' => 'Bagisto', + 'webkul' => '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..335f2a41f 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,11 @@ return [ ], 'footer' => [ - 'copy-right' => '© Copyright '.date('Y').' Webkul Software, Todos os direitos reservados.' + 'copy-right' => '© Copyright '.date('Y').' Webkul Software, Todos os direitos reservados.', + 'powered-by' => 'Powered by', + 'community-by' => 'Community Project by', + 'bagisto' => 'Bagisto', + 'webkul' => 'Webkul' ], 'admin' => [ diff --git a/packages/Webkul/Shop/src/Resources/views/layouts/master.blade.php b/packages/Webkul/Shop/src/Resources/views/layouts/master.blade.php index 6880d5204..4af765ef7 100755 --- a/packages/Webkul/Shop/src/Resources/views/layouts/master.blade.php +++ b/packages/Webkul/Shop/src/Resources/views/layouts/master.blade.php @@ -76,7 +76,17 @@ @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.powered-by') }} + + + {{ trans('admin::app.footer.bagisto') }} + , + + {{ trans('admin::app.footer.community-by') }} + + + {{ trans('admin::app.footer.webkul') }} + @endif

From a283ebdb44a172b0fb5f42b5983a844018ab3b46 Mon Sep 17 00:00:00 2001 From: rahul shukla Date: Fri, 3 Jan 2020 15:42:18 +0530 Subject: [PATCH 07/13] link in installer --- public/installer/index.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/public/installer/index.php b/public/installer/index.php index 46036f5d8..c49424f86 100755 --- a/public/installer/index.php +++ b/public/installer/index.php @@ -28,6 +28,11 @@
From 9b120a978dc995bad68a8d0d7779ca5734529496 Mon Sep 17 00:00:00 2001 From: rahul shukla Date: Fri, 3 Jan 2020 15:57:43 +0530 Subject: [PATCH 08/13] foter text change --- packages/Webkul/Admin/src/Resources/lang/ar/app.php | 6 +----- packages/Webkul/Admin/src/Resources/lang/en/app.php | 6 +----- packages/Webkul/Admin/src/Resources/lang/fa/app.php | 6 +----- .../Webkul/Admin/src/Resources/lang/pt_BR/app.php | 6 +----- .../src/Resources/views/layouts/master.blade.php | 12 +----------- 5 files changed, 5 insertions(+), 31 deletions(-) diff --git a/packages/Webkul/Admin/src/Resources/lang/ar/app.php b/packages/Webkul/Admin/src/Resources/lang/ar/app.php index 6938e5bcc..91cfa8efa 100644 --- a/packages/Webkul/Admin/src/Resources/lang/ar/app.php +++ b/packages/Webkul/Admin/src/Resources/lang/ar/app.php @@ -852,11 +852,7 @@ return [ ], 'footer' => [ - 'copy-right' => '© Copyright 2018 Webkul Software, All rights reserved.', - 'powered-by' => 'Powered by', - 'community-by' => 'Community Project by', - 'bagisto' => 'Bagisto', - 'webkul' => 'Webkul' + 'copy-right' => 'Powered by Bagisto, A Community Project by 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 e7e5392a7..68c37ff5b 100755 --- a/packages/Webkul/Admin/src/Resources/lang/en/app.php +++ b/packages/Webkul/Admin/src/Resources/lang/en/app.php @@ -1171,11 +1171,7 @@ return [ ], 'footer' => [ - 'copy-right' => '© Copyright 2018 Webkul Software, All rights reserved.', - 'powered-by' => 'Powered by', - 'community-by' => 'Community Project by', - 'bagisto' => 'Bagisto', - 'webkul' => 'Webkul' + '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 3046ffb55..ef2219ed8 100644 --- a/packages/Webkul/Admin/src/Resources/lang/fa/app.php +++ b/packages/Webkul/Admin/src/Resources/lang/fa/app.php @@ -998,11 +998,7 @@ return [ ], 'footer' => [ - 'copy-right' => '© کپی رایت 2019 کلیه حقوق محفوظ است.', - 'powered-by' => 'Powered by', - 'community-by' => 'Community Project by', - 'bagisto' => 'Bagisto', - 'webkul' => 'Webkul' + 'copy-right' => 'Powered by Bagisto, A Community Project by 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 335f2a41f..17e36dc6c 100755 --- a/packages/Webkul/Admin/src/Resources/lang/pt_BR/app.php +++ b/packages/Webkul/Admin/src/Resources/lang/pt_BR/app.php @@ -976,11 +976,7 @@ return [ ], 'footer' => [ - 'copy-right' => '© Copyright '.date('Y').' Webkul Software, Todos os direitos reservados.', - 'powered-by' => 'Powered by', - 'community-by' => 'Community Project by', - 'bagisto' => 'Bagisto', - 'webkul' => 'Webkul' + 'copy-right' => 'Powered by Bagisto, A Community Project by Webkul', ], 'admin' => [ diff --git a/packages/Webkul/Shop/src/Resources/views/layouts/master.blade.php b/packages/Webkul/Shop/src/Resources/views/layouts/master.blade.php index 4af765ef7..b315da0f1 100755 --- a/packages/Webkul/Shop/src/Resources/views/layouts/master.blade.php +++ b/packages/Webkul/Shop/src/Resources/views/layouts/master.blade.php @@ -76,17 +76,7 @@ @if (core()->getConfigData('general.content.footer.footer_content')) {{ core()->getConfigData('general.content.footer.footer_content') }} @else - {{ trans('admin::app.footer.powered-by') }} - - - {{ trans('admin::app.footer.bagisto') }} - , - - {{ trans('admin::app.footer.community-by') }} - - - {{ trans('admin::app.footer.webkul') }} - + {!! trans('admin::app.footer.copy-right') !!} @endif

From 25dff89054b0129272553553086087ef81aa7a5f Mon Sep 17 00:00:00 2001 From: rahul shukla Date: Fri, 3 Jan 2020 16:12:23 +0530 Subject: [PATCH 09/13] translation added for locales --- packages/Webkul/Admin/src/Resources/lang/ar/app.php | 2 +- packages/Webkul/Admin/src/Resources/lang/fa/app.php | 2 +- packages/Webkul/Admin/src/Resources/lang/pt_BR/app.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/Webkul/Admin/src/Resources/lang/ar/app.php b/packages/Webkul/Admin/src/Resources/lang/ar/app.php index 91cfa8efa..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' => 'Powered by Bagisto, A Community Project by Webkul', + 'copy-right' => ' مدعوم من Bagisto ، مشروع مجتمع بواسطة 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 ef2219ed8..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' => 'Powered by Bagisto, A Community Project by Webkul', + '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 17e36dc6c..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' => 'Powered by Bagisto, A Community Project by Webkul', + 'copy-right' => 'Desenvolvido por Bagisto, um projeto comunitário da Webkul' ], 'admin' => [ From d52ef533c733d119d8d925258db7635abc645d8d Mon Sep 17 00:00:00 2001 From: MonaHartdegen Date: Fri, 3 Jan 2020 13:09:06 +0100 Subject: [PATCH 10/13] replace wildcard route for products and categories with fallback route --- composer.json | 3 +- .../ProductsCategoriesProxyController.php | 31 ++++++++++--------- packages/Webkul/Shop/src/Http/routes.php | 5 +-- 3 files changed, 19 insertions(+), 20 deletions(-) diff --git a/composer.json b/composer.json index 04f267c58..6a87f07e1 100755 --- a/composer.json +++ b/composer.json @@ -131,7 +131,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/packages/Webkul/Shop/src/Http/Controllers/ProductsCategoriesProxyController.php b/packages/Webkul/Shop/src/Http/Controllers/ProductsCategoriesProxyController.php index d8dfad45f..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,26 +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) { + $slugOrPath = trim($request->getPathInfo(), '/'); - if ($category = $this->categoryRepository->findByPath($slugOrPath)) { + if (preg_match('/^([a-z0-9-]+\/?)+$/', $slugOrPath)) { - return view($this->_config['category_view'], compact('category')); - } + if ($category = $this->categoryRepository->findByPath($slugOrPath)) { - if ($product = $this->productRepository->findBySlug($slugOrPath)) { + return view($this->_config['category_view'], compact('category')); + } - $customer = auth()->guard('customer')->user(); + 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..6d0aef0f9 100755 --- a/packages/Webkul/Shop/src/Http/routes.php +++ b/packages/Webkul/Shop/src/Http/routes.php @@ -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'); }); From 97c63ad035a62b5861ced679fd690bfab2b4acad Mon Sep 17 00:00:00 2001 From: rahul shukla Date: Fri, 3 Jan 2020 18:05:14 +0530 Subject: [PATCH 11/13] review missing variavle and admin footer text --- .../src/Resources/views/layouts/anonymous-master.blade.php | 2 +- .../Shop/src/Resources/views/products/reviews/create.blade.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) 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/Shop/src/Resources/views/products/reviews/create.blade.php b/packages/Webkul/Shop/src/Resources/views/products/reviews/create.blade.php index 0ce797b32..2c1867cfc 100755 --- a/packages/Webkul/Shop/src/Resources/views/products/reviews/create.blade.php +++ b/packages/Webkul/Shop/src/Resources/views/products/reviews/create.blade.php @@ -64,7 +64,7 @@ @{{ errors.first('title') }}
- @if ($guest_review && ! auth()->guard('customer')->user()) + @if (core()->getConfigData('catalog.products.review.guest_review') && ! auth()->guard('customer')->user())