markguinn / silverstripe-shop-extendedpricing

Submodule for Silverstripe Shop adding pricing levels based on group (wholesale, etc) and per-item sale pricing.
MIT License
3 stars 5 forks source link

Using both HasPriceTiers and HasPromotionalPricing extensions discards tier price #7

Open TheBnl opened 7 years ago

TheBnl commented 7 years ago

Hi,

I found that by using both the HasPriceTiers and HasPromotionalPricing extensions discards price tier price. So on a product with both extensions enabled, with set price tiers and no promotion active, the tier price gets discarded on the HasPromotionalPricing extension in the updateSellingPrice method.

On the method getPrices on line 70 the updateSellingPrice gets called that goes trough the extension hook on HasPromotionalPricing.

// HasPriceTiers::getPrices()
foreach ($tiers as $tier) {
    /** @var PriceTier $tier */
    // calculate a price if needed
    if ($tier->Price == 0 && $tier->Percentage > 0) {
        $tier->Price = $tier->calcPrice($base->Price);
    } elseif ($tier->Price > 0 && $tier->Percentage == 0 && $base->Price > 0) {
        $price = $tier->Price;
        // Here the price goes to the HasPromotionalPricing hook
        $this->owner->extend('updateSellingPrice', $price); // make sure discounts still apply
        $price = $price < 0 ? 0 : $price;
        $tier->Price = $price;
        $tier->Percentage = $price / $base->Price;
}
// HasPromotionalPricing
public function updateSellingPrice(&$price) {
    if (self::$bypass || Config::inst()->get('HasPromotionalPricing', 'disable_discounts')) return;

    // Here the tier price gets discarded
    // It finds the base price in the cache and overwrites the tier price
    if (PriceCache::inst()->fetch($this->owner, 'Promo', $price)) return;

A fix could be adding a check for the HasPriceTiers extension on the HasPromotionalPricing::updateSellingPrice() method.

// original method
if (PriceCache::inst()->fetch($this->owner, 'Promo', $price)) return;

// with the check 
if (!$this->owner->hasExtension('HasPriceTiers') && PriceCache::inst()->fetch($this->owner, 'Promo', $price)) return;
TheBnl commented 7 years ago

8