Magento提供购物车价格规则营销功能,允许根据一组条件对购物车中的商品应用折扣。只要满足条件,或者客户输入有效的优惠券代码,就可以自动应用折扣。优惠券代码可以通过管理面板的Marketing -> Cart Price Rules
部分按购物车价格规则生成。但是,有时我们需要自动执行此过程。让我们来看看如何在Magento 2中以编程方式创建购物车价格规则并生成优惠券代码。
首先,我们创建一个服务类,旨在使用默认优惠券生成器(\Magento\SalesRule\Model\CouponGenerator
)生成优惠券代码。如果我们想要通过预定的CRON计划任务生成优惠券代码,将来可以重复使用该服务。或者我们甚至可以另外创建一个新的CLI命令,它允许通过简单地调用\Atwix\CartCouponSample\Service\GenerateCouponCodesService::execute
方法为指定的购物车价格规则生成许多代码。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | <?php /* File: app/code/Atwix/CartCouponSample/Service/GenerateCouponCodesService.php */ namespace Atwix\CartCouponSample\Service; use Magento\SalesRule\Model\CouponGenerator; /** * Class GenerateCouponListService */ class GenerateCouponCodesService { /** * Coupon Generator * * @var CouponGenerator */ protected $couponGenerator; /** * GenerateCouponCodesService constructor * * @param CouponGenerator $couponGenerator */ public function __construct(CouponGenerator $couponGenerator) { $this->couponGenerator = $couponGenerator; } /** * Generate coupon list for specified cart price rule * * @param int|null $qty * @param int|null $ruleId * @param array $params * * @return void */ public function execute(int $qty, int $ruleId, array $params = []): void { if (!$qty || !$ruleId) { return; } $params['rule_id'] = $ruleId; $params['qty'] = $qty; $this->couponGenerator->generateCodes($params); } } |
然后,我们实现一个设置服务类,用于创建购物车价格规则并将优惠券代码分配给新创建的规则。我们将此逻辑移至专用的安装服务类,只是为了遵循单一责任原则并避免存储在安装脚本中的大量逻辑。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 | <?php /* File: app/code/Atwix/CartCouponSample/Setup/SetupService/CreateCartPriceRuleService.php */ namespace Atwix\CartCouponSample\Setup\SetupService; use Atwix\CartCouponSample\Service\GenerateCouponCodesService; use Exception; use Magento\Backend\App\Area\FrontNameResolver as BackendFrontNameResolver; use Magento\Customer\Model\ResourceModel\Group\Collection as CustomerGroupCollection; use Magento\Customer\Model\ResourceModel\Group\CollectionFactory as CustomerGroupCollectionFactory; use Magento\Framework\App\State as AppState; use Magento\SalesRule\Api\Data\RuleInterface; use Magento\SalesRule\Api\Data\RuleInterfaceFactory; use Magento\SalesRule\Api\RuleRepositoryInterface; use Magento\Store\Model\StoreManagerInterface; /** * Class CreateCartPriceRuleService */ class CreateCartPriceRuleService { /** * The initial number of generated coupon codes */ const INITIAL_COUPON_CODES_QTY = 1000; /** * Coupon Code Length */ const LENGTH = 10; /** * Coupon Code Prefix */ const PREFIX = 'TEST-'; /** * Generate Coupon Codes Service * * @var GenerateCouponCodesService */ protected $generateCouponCodesService; /** * Rule Repository * * @var RuleRepositoryInterface */ protected $ruleRepository; /** * Store Manager * * @var StoreManagerInterface */ protected $storeManager; /** * Catalog Price Rule Factory * * @var RuleInterfaceFactory */ protected $cartPriceRuleFactory; /** * Customer Group Collection Factory * * @var CustomerGroupCollectionFactory */ protected $customerGroupCollectionFactory; /** * App State * * @var AppState */ protected $appState; /** * CreateCartPriceRuleService constructor * * @param GenerateCouponCodesService $generateCouponCodesService * @param RuleRepositoryInterface $ruleRepository * @param StoreManagerInterface $storeManager * @param AppState $appState * @param RuleInterfaceFactory $cartPriceRuleFactory * @param CustomerGroupCollectionFactory $customerGroupCollectionFactory */ public function __construct( GenerateCouponCodesService $generateCouponCodesService, RuleRepositoryInterface $ruleRepository, StoreManagerInterface $storeManager, AppState $appState, RuleInterfaceFactory $cartPriceRuleFactory, CustomerGroupCollectionFactory $customerGroupCollectionFactory ) { $this->generateCouponCodesService = $generateCouponCodesService; $this->ruleRepository = $ruleRepository; $this->storeManager = $storeManager; $this->appState = $appState; $this->cartPriceRuleFactory = $cartPriceRuleFactory; $this->customerGroupCollectionFactory = $customerGroupCollectionFactory; } /** * Create cart price rule and generate coupon codes * * @return void * * @throws Exception */ public function execute() { $customerGroupIds = $this->getAvailableCustomerGroupIds(); $websiteIds = $this->getAvailableWebsiteIds(); /** @var RuleInterface $cartPriceRule */ $cartPriceRule = $this->cartPriceRuleFactory->create(); // Set the required parameters. $cartPriceRule->setName('Sample Cart Price Rule'); $cartPriceRule->setIsActive(true); $cartPriceRule->setCouponType(RuleInterface::COUPON_TYPE_SPECIFIC_COUPON); $cartPriceRule->setCustomerGroupIds($customerGroupIds); $cartPriceRule->setWebsiteIds($websiteIds); // Set the usage limit per customer. $cartPriceRule->setUsesPerCustomer(1); // Make the multiple coupon codes generation possible. $cartPriceRule->setUseAutoGeneration(true); // We need to set the area code due to the existent implementation of RuleRepository. // The specific area need to be emulated while running the RuleRepository::save method from CLI in order to // avoid the corresponding error ("Area code is not set"). $savedCartPriceRule = $this->appState->emulateAreaCode( BackendFrontNameResolver::AREA_CODE, [$this->ruleRepository, 'save'], [$cartPriceRule] ); // Generate and assign coupon codes to the newly created Cart Price Rule. $ruleId = (int) $savedCartPriceRule->getRuleId(); $params = ['length' => self::LENGTH, 'prefix' => self::PREFIX]; $this->generateCouponCodesService->execute(self::INITIAL_COUPON_CODES_QTY, $ruleId, $params); } /** * Get all available customer group IDs * * @return int[] */ protected function getAvailableCustomerGroupIds() { /** @var CustomerGroupCollection $collection */ $collection = $this->customerGroupCollectionFactory->create(); $collection->addFieldToSelect('customer_group_id'); $customerGroupIds = $collection->getAllIds(); return $customerGroupIds; } /** * Get all available website IDs * * @return int[] */ protected function getAvailableWebsiteIds() { $websiteIds = []; $websites = $this->storeManager->getWebsites(); foreach ($websites as $website) { $websiteIds[] = $website->getId(); } return $websiteIds; } } |
以下步骤通过以下\Atwix\CartCouponSample\Setup\SetupService\CreateCartPriceRuleService::execute
方法执行:
- 使用工厂创建购物车价格规则对象。
- 将所需数据和其他配置设置为购物车价格规则对象。我们还使用优惠券类型“特定优惠券”并设置“使用自动生成”标志以使多个优惠券代码生成成为可能。
- 使用相应的存储库保存购物车价格规则。注意,在这种情况下,由于现有的实现,我们需要设置区号
RuleRepository
。RuleRepository::save
从CLI 运行方法时需要模拟特定区域,以避免相应的错误(“区域代码未设置”)。 - 使用,生成优惠券代码并将其分配给新创建的购物车价格规则
Atwix\CartCouponSample\Service\GenerateCouponCodesService
。
现在,让我们为我们的模块创建数据安装脚本:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | <?php /* File: app/code/Atwix/CartCouponSample/Setup/InstallData.php */ namespace Atwix\CartCouponSample\Setup; use Atwix\CartCouponSample\Setup\SetupService\CreateCartPriceRuleService; use Magento\Framework\Setup\InstallDataInterface; use Magento\Framework\Setup\ModuleContextInterface; use Magento\Framework\Setup\ModuleDataSetupInterface; /** * Class InstallData */ class InstallData implements InstallDataInterface { /** * Create Cart Price Rule Service * * @var CreateCartPriceRuleService */ protected $createCartPriceRuleService; /** * InstallData constructor * * @param CreateCartPriceRuleService $createCartPriceRuleService */ public function __construct(CreateCartPriceRuleService $createCartPriceRuleService) { $this->createCartPriceRuleService = $createCartPriceRuleService; } /** * @inheritdoc */ public function install(ModuleDataSetupInterface $setup, ModuleContextInterface $context) { $this->createCartPriceRuleService->execute(); } } |
执行数据升级后,您将能够在管理面板中查看结果。