/** * @return Double **/ protected function LiveCalculatedTotal() { //________________ start caching mechanism if (self::$calculations_done) { return self::$actual_charges; } self::$calculations_done = true; //________________ end caching mechanism self::$actual_charges = 0; //do we have enough information $obj = $this->liveOptionObject(); if ($items = $this->Order()->Items() && is_object($obj) && $obj->exists()) { $this->debugMessage .= "<hr />option selected: " . $obj->Title . ", and items present"; //lets check sub-total $subTotalAmount = $this->LiveSubTotalAmount(); $this->debugMessage .= "<hr />sub total amount is: \$" . $subTotalAmount; // no need to charge, order is big enough $minForZeroRate = floatval($obj->MinimumOrderAmountForZeroRate); $maxForZeroRate = floatval($obj->FreeShippingUpToThisOrderAmount); if ($minForZeroRate > 0 && $minForZeroRate < $subTotalAmount) { self::$actual_charges = 0; $this->debugMessage .= "<hr />Minimum Order Amount For Zero Rate: " . $obj->MinimumOrderAmountForZeroRate . " is lower than amount ordered" . self::$actual_charges; } elseif ($maxForZeroRate > 0 && $maxForZeroRate > $subTotalAmount) { self::$actual_charges = 0; $this->debugMessage .= "<hr />Maximum Order Amount For Zero Rate: " . $obj->FreeShippingUpToThisOrderAmount . " is higher than amount ordered" . self::$actual_charges; } else { $weight = $this->LiveTotalWeight(); if ($weight) { $this->debugMessage .= "<hr />there is weight: {$weight}gr."; //weight brackets $weightBrackets = $obj->WeightBrackets(); $foundWeightBracket = null; $weightBracketQuantity = 1; $additionalWeightBracket = null; if ($weightBrackets && $weightBrackets->Count()) { $minimumMinimum = null; $maximumMaximum = null; foreach ($weightBrackets as $weightBracket) { if (!$foundWeightBracket && $weightBracket->MinimumWeight <= $weight && $weight <= $weightBracket->MaximumWeight) { $foundWeightBracket = $weightBracket; } //look for absolute min and max if ($minimumMinimum == null || $weightBracket->MinimumWeight > $minimumMinimum->MinimumWeight) { $minimumMinimum = $weightBracket; } if ($maximumMaximum == null || $weightBracket->MaximumWeight > $maximumMaximum->MaximumWeight) { $maximumMaximum = $weightBracket; } } if (!$foundWeightBracket) { if ($weight < $minimumMinimum->MinimumWeight) { $foundWeightBracket = $minimumMinimum; } elseif ($weight > $maximumMaximum->MaximumWeight) { $foundWeightBracket = $maximumMaximum; $weightBracketQuantity = floor($weight / $maximumMaximum->MaximumWeight); $restWeight = $weight - $maximumMaximum->MaximumWeight * $weightBracketQuantity; $additionalWeightBracket = null; foreach ($weightBrackets as $weightBracket) { if ($weightBracket->MinimumWeight <= $restWeight && $restWeight <= $weightBracket->MaximumWeight) { $additionalWeightBracket = $weightBracket; break; } } } } } //we found some applicable weight brackets if ($foundWeightBracket) { self::$actual_charges += $foundWeightBracket->FixedCost * $weightBracketQuantity; $this->debugMessage .= "<hr />found Weight Bracket (from {$foundWeightBracket->MinimumWeight}gr. to {$foundWeightBracket->MaximumWeight}gr.): \${$foundWeightBracket->FixedCost} ({$foundWeightBracket->Name}) from times {$weightBracketQuantity}"; if ($additionalWeightBracket) { self::$actual_charges += $additionalWeightBracket->FixedCost; $this->debugMessage .= "<hr />+ additional Weight Bracket (from {$additionalWeightBracket->MinimumWeight}gr. to {$additionalWeightBracket->MaximumWeight}gr.): \${$additionalWeightBracket->FixedCost} ({$foundWeightBracket->Name})"; } } elseif ($weight && $obj->WeightMultiplier) { // add weight based shipping if (!$obj->WeightUnit) { $obj->WeightUnit = 1; } $this->debugMessage .= "<hr />actual weight:" . $weight . " multiplier = " . $obj->WeightMultiplier . " weight unit = " . $obj->WeightUnit . " "; //legacy fix $units = ceil($weight / $obj->WeightUnit); $weightCharge = $units * $obj->WeightMultiplier; self::$actual_charges += $weightCharge; $this->debugMessage .= "<hr />weight charge: " . $weightCharge; } } // add percentage if ($obj->Percentage) { $percentageCharge = $subTotalAmount * $obj->Percentage; self::$actual_charges += $percentageCharge; $this->debugMessage .= "<hr />percentage charge: \$" . $percentageCharge; } // add fixed price if ($obj->FixedCost != 0) { self::$actual_charges += $obj->FixedCost; $this->debugMessage .= "<hr />fixed charge: \$" . $obj->FixedCost; } //is it enough? if (self::$actual_charges < $obj->MinimumDeliveryCharge && $obj->MinimumDeliveryCharge > 0) { $oldActualCharge = self::$actual_charges; self::$actual_charges = $obj->MinimumDeliveryCharge; $this->debugMessage .= "<hr />too little: actual charge: " . $oldActualCharge . ", minimum delivery charge: " . $obj->MinimumDeliveryCharge; } // is it too much if (self::$actual_charges > $obj->MaximumDeliveryCharge && $obj->MaximumDeliveryCharge > 0) { self::$actual_charges = $obj->MaximumDeliveryCharge; $this->debugMessage .= "<hr />too much: " . self::$actual_charges . ", maximum delivery charge is " . $obj->MaximumDeliveryCharge; } } } else { if (!$items) { $this->debugMessage .= "<hr />no items present"; } else { $this->debugMessage .= "<hr />no delivery option available"; } } $this->debugMessage .= "<hr />final score: \$" . self::$actual_charges; //special case, we are using weight and there is no weight! return self::$actual_charges; }