That was the hint I needed, thank you Boris (I actually needed to override the ShoppingCartItemInfoProvider.GetDiscountsInternal method in order to accomplish what I needed). For future reference, here is my custom provider implementation:
using System;
using System.Linq;
using System.Collections.Generic;
using CMS;
using CMS.Ecommerce;
using CMS.Base;
[assembly: RegisterCustomProvider(typeof(CustomShoppingCartItemInfoProvider))]
public class CustomShoppingCartItemInfoProvider : ShoppingCartItemInfoProvider
{
/// <summary>
/// Returns list of all discounts which should be applied to the specified shopping cart item.
/// </summary>
/// <param name="item">Shopping cart item</param>
protected override List<IItemDiscount> GetDiscountsInternal(ShoppingCartItemInfo item)
{
// CUSTOM - temporarily set qty of the line item to the total number of any variant in the same parent product
int? originalQty = null;
if (item.SKU.IsProductVariant)
{
// Save the original quantity so we can restore it when we're done
originalQty = item.CartItemUnits;
item.CartItemUnits = item.ShoppingCart.CartItems.Where(i => i.SKU.SKUParentSKUID == item.SKU.SKUParentSKUID).Sum(i => i.CartItemUnits);
}
// Get default discounts
List<IItemDiscount> discounts = base.GetDiscountsInternal(item);
// Restore the original quantity
if (originalQty != null)
{
item.CartItemUnits = originalQty.Value;
}
return discounts;
}
}