/**
  * Returns aggregate discount amount applicable to order.
  * 
  * @param array $order Order data array
  * @param bool $apply Whether discount-related information must be added to order parameters (where appropriate)
  * @return float Total discount value expressed in order currency
  */
 public static function calculate(&$order, $apply = false)
 {
     $currency = isset($order['currency']) ? $order['currency'] : wa('shop')->getConfig()->getCurrency(false);
     $applicable_discounts = array();
     $contact = self::getContact($order);
     // Discount by contact category applicable?
     if (self::isEnabled('category')) {
         $applicable_discounts[] = self::byCategory($order, $contact, $apply);
     }
     // Discount by coupon applicable?
     if (self::isEnabled('coupons')) {
         $applicable_discounts[] = self::byCoupons($order, $contact, $apply);
     }
     // Discount by order total applicable?
     if (self::isEnabled('order_total')) {
         $crm = new shopCurrencyModel();
         $dbsm = new shopDiscountBySumModel();
         // Order total in default currency
         $order_total = (double) $crm->convert($order['total'], $currency, wa('shop')->getConfig()->getCurrency());
         $applicable_discounts[] = max(0.0, min(100.0, (double) $dbsm->getDiscount('order_total', $order_total))) * $order['total'] / 100.0;
     }
     // Discount by customer total spent applicable?
     if (self::isEnabled('customer_total')) {
         $applicable_discounts[] = self::byCustomerTotal($order, $contact, $apply);
     }
     /**
      * @event order_calculate_discount
      * @param array $params
      * @param array[string] $params['order'] order info array('total' => '', 'items' => array(...))
      * @param array[string] $params['contact'] contact info
      * @param array[string] $params['apply'] calculate or apply discount
      * @return float discount
      */
     $event_params = array('order' => &$order, 'contact' => $contact, 'apply' => $apply);
     $plugins_discounts = wa('shop')->event('order_calculate_discount', $event_params);
     foreach ($plugins_discounts as $plugin_discount) {
         $applicable_discounts[] = $plugin_discount;
     }
     // Select max discount or sum depending on global setting.
     $discount = 0.0;
     if ($applicable_discounts = array_filter($applicable_discounts, 'is_numeric')) {
         if (wa('shop')->getSetting('discounts_combine') == 'sum') {
             $discount = (double) array_sum($applicable_discounts);
         } else {
             $discount = (double) max($applicable_discounts);
         }
     }
     // Discount based on affiliate bonus?
     if (shopAffiliate::isEnabled()) {
         $discount = $discount + (double) shopAffiliate::discount($order, $contact, $apply, $discount);
     }
     return min(max(0, $discount), ifset($order['total'], 0));
 }