In the end I hacking ProductsService::apply_sales() to apply a discount before the foreach ($this->get_active_sales() as $sale)
loop.
public function apply_sales(Product $product)
{
// set initial option sale prices
if (isset($product->modifiers)) {
foreach ($product->modifiers as $modifier) {
foreach ($modifier->options as $option) {
$option->sale_price_mod = $option->opt_price_mod;
}
}
}
// find any sales which apply to this product
$member_group_id = (int) $this->ee->session->userdata['group_id'];
/**
* HACK ^LG
* Added 10% Discount Member Price
*/
if($member_group_id) {
$product->setPriceAttribute(store_round_currency($product->price - (10 * $product->price / 100)));
}
foreach ($this->get_active_sales() as $sale) {
if ($this->sale_applies_to_product($sale, $product, $member_group_id)) {
if ((float) $sale->per_item_discount) {
$product->sale_price = store_round_currency($product->sale_price - $sale->per_item_discount);
}
if ((float) $sale->percent_discount) {
$product->sale_price = store_round_currency($product->sale_price - ($sale->percent_discount * $product->sale_price / 100));
// percentage discount also needs to be applied to loaded modifiers
if (isset($product->modifiers)) {
foreach ($product->modifiers as $modifier) {
foreach ($modifier->options as $option) {
if ($option->opt_price_mod) {
$option->sale_price_mod = store_round_currency($option->sale_price_mod - ($sale->percent_discount * $option->sale_price_mod / 100), true);
}
}
}
}
}
$product->on_sale = true;
}
}
return $product;
}