The answer to this is quite complex. I will try to provide some hints hopefully i will save somebody's time:
First, coupons (from view cart page) are submitted to Magento\Checkout\Controller\Cart\CouponPost execute() method. Coupons from the checkout page are posted to APIs via ajax, check the actual url in browser's network tab from Tools.
After this, the situation gets complicated :-) It starts from
- vendor/magento/module-sales-rule/Model/RulesApplier.php applyRules()
foreach ($rules as $rule) {
if (!$this->validatorUtility->canProcessRule($rule, $address)) {
...
and canProcessRule() goes to
- vendor/magento/module-sales-rule/Model/Utility.php canProcessRule - method which checks if a rule can be applied for a specific address/quote/customer
The applyRules() method from RulesApplier.php also has the following code:
$rule->getActions()->validate($childItem)
which takes us to
- vendor/magento/module-rule/Model/Condition/Combine.php _isValid(). This method validates the coupon's conditions, and it's the starting point in the validation process. It has this line of code
$validated = $cond->validate($entity);
which actually goes into the next file/method:
- vendor/magento/module-sales-rule/Model/Rule/Condition/Product/Found.php validate(). This method validates individual coupon's conditions and uses the following code
$validated = $cond->validate($item);
which goes to the next file/method:
- vendor/magento/module-sales-rule/Model/Rule/Condition/Product.php validate() which validates a product rule condition. This validates things related to products - like categories and price and through this code
return parent::validate($product);
goes into the MOST IMPORT VALIDATION part which is in the file
- vendor/magento/module-rule/Model/Condition/Product/AbstractProduct.php validate() which validates product attributes.
If you think this can't get more complicated, you're wrong, it goes further down, but you get the idea.