0

I'm trying to override salesRule module adding a new field customer_id for creating rules based on an unique customer.

I've already added the new field, but now, how this module applies the rules if it matches? I'm searching aroung the module and the only thing I found is this class: SalesRule\Model\Quote\Discount on the function collect seems it applies discount but only for the shipping. I don't know where I have to add some code, adding this conditionality of if matches customer_id

Days ago, I made the same thing with CatalogRule and things were a lot more intuitive, I had to made a few changes but the main goal was here:

CatalogRule\Model\ResourceModel\Rule on this function:

public function getRulePrices(\DateTime $date, $websiteId, $customerGroupId, $productIds, $customerId = 0)
{
    $connection = $this->getConnection();
    $select = $connection->select()
        ->from($this->getTable('catalogrule_product_price'), ['product_id', 'rule_price'])
        ->where('rule_date = ?', $date->format('Y-m-d'))
        ->where('website_id = ?', $websiteId)
        ->where('customer_group_id = ?', $customerGroupId)
        ->where('product_id IN(?)', $productIds)
        ->where('customer_id = ? OR customer_id = 0', $customerId)
        ->order('sort_order', 'ASC')
        ->limit(1);

    return $connection->fetchPairs($select);
}

As you can see, it was easy to find this query and manipulate it for achieve my objectives. But now with SalesRule seems more complicated.

Can anyone help? I can't find documentation about this. I need to know how works all this stuff.

2

Finally I found it.

This is the class I had to override: \Magento\SalesRule\Model\ResourceModel\Rule\Collection

public function setValidationFilter(
    $websiteId,
    $customerGroupId,
    $couponCode = '',
    $now = null,
    \Magento\Quote\Model\Quote\Address $address = null,
    $customerId = 0
)
{
    if (!$this->getFlag('validation_filter')) {
        /* We need to overwrite joinLeft if coupon is applied */
        $this->getSelect()->reset();
        parent::_initSelect();

        $this->addWebsiteGroupDateFilter($websiteId, $customerGroupId, $now);
        $select = $this->getSelect();

        $connection = $this->getConnection();
        if (strlen($couponCode)) {
            $select->joinLeft(
                ['rule_coupons' => $this->getTable('salesrule_coupon')],
                $connection->quoteInto(
                    'main_table.rule_id = rule_coupons.rule_id AND main_table.coupon_type != ?',
                    \Magento\SalesRule\Model\Rule::COUPON_TYPE_NO_COUPON
                ),
                ['code']
            );

            $noCouponWhereCondition = $connection->quoteInto(
                'main_table.coupon_type = ? ',
                \Magento\SalesRule\Model\Rule::COUPON_TYPE_NO_COUPON
            );

            $orWhereConditions = [
                $connection->quoteInto(
                    '(main_table.coupon_type = ? AND rule_coupons.type = 0)',
                    \Magento\SalesRule\Model\Rule::COUPON_TYPE_AUTO
                ),
                $connection->quoteInto(
                    '(main_table.coupon_type = ? AND main_table.use_auto_generation = 1 AND rule_coupons.type = 1)',
                    \Magento\SalesRule\Model\Rule::COUPON_TYPE_SPECIFIC
                ),
                $connection->quoteInto(
                    '(main_table.coupon_type = ? AND main_table.use_auto_generation = 0 AND rule_coupons.type = 0)',
                    \Magento\SalesRule\Model\Rule::COUPON_TYPE_SPECIFIC
                ),
            ];

            $andWhereConditions = [
                $connection->quoteInto(
                    'rule_coupons.code = ?',
                    $couponCode
                ),
                $connection->quoteInto(
                    '(rule_coupons.expiration_date IS NULL OR rule_coupons.expiration_date >= ?)',
                    $this->_date->date()->format('Y-m-d')
                ),
            ];

            $orWhereCondition = implode(' OR ', $orWhereConditions);
            $andWhereCondition = implode(' AND ', $andWhereConditions);

            $select->where(
                $noCouponWhereCondition . ' OR ((' . $orWhereCondition . ') AND ' . $andWhereCondition . ')'
            );
        } else {
            $this->addFieldToFilter(
                'main_table.coupon_type',
                \Magento\SalesRule\Model\Rule::COUPON_TYPE_NO_COUPON
            );
        }

        $select->where('customer_id = ? OR customer_id = 0', $customerId);

        $this->setOrder('sort_order', self::SORT_ORDER_ASC);
        $this->setFlag('validation_filter', true);
    }

    return $this;
}
0

Touching Magento core files are highly discouraged try to use relevant events given by Magento probably this event could help you salesrule_rule_condition_combine

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.