/** Calculate shipping cost (Also set free shipping) * @param Money $totalSubtotal * @param $orderItems * @return array * @internal param Money $credits */ public function getShippingTotal(Money $totalSubtotal, $orderItems, $zipCode = null) { $hasFreeShipping = FALSE; $shipping = []; $market_check = Configure::read('market_id'); if (!empty($market_check)) { $market_id = Configure::read('market_id'); } else { $market_id = $this->getMarketId(); } //shipping tiers // market touch point $trait = ClassRegistry::init('TraitCountry'); $defaultShipping = Money::fromFloat($trait->getTrait($market_id, 'default_shipping')); $midTierShipping = Money::fromFloat($trait->getTrait($market_id, 'mid_shipping_tier')); $marketShippingTierMid = Money::fromFloat($trait->getTrait($market_id, 'market_shipping_mid_tier')); $marketShippingTierFree = Money::fromFloat($trait->getTrait($market_id, 'market_shipping_free_tier')); $total_weight = 0.0; $no_expedite_reason = array(); $backordered_items = false; $items = 0; $backorder_num = 0; $expedite = true; if (Configure::read('market_id') != MARKET::MARKET_USA) { $expedite = false; $no_expedite_reason[] = 1; //Currently none expeditable market } $expedite_check = $this->getExpeditedShipCount(); if (!$expedite_check) { $expedite = false; $no_expedite_reason[] = 2; //Limit exceeded for expedited shipping requests } foreach ($orderItems as $key => $item) { $items++; if ($item['backordered'] == true) { $backordered_items = true; $this->orderObject->backOrderCount += (int) $item['qty']; //backorder } if ($item['childBackordered'] == true) { $backordered_items = true; } if ($item['sku'] == 'US-12001-01') { $expedite = false; $no_expedite_reason[] = 4; //hazmat } if ($item['hazmat'] == TRUE) { $expedite = false; $no_expedite_reason[] = 4; //hazmat } if (!empty($item['weight'])) { $total_weight += $item['weight']; } else { $total_weight += 0.35; } $shipping[$key] = $defaultShipping; // Convention tickets have free shipping + Presenter Kits if (in_array($item['item_type_id'], [Item::TYPE_CONVENTION_TICKET])) { $hasFreeShipping = TRUE; } // Items with free shipping (guest passes) if (in_array($item['sku'], ProductGlobal::freeShipping())) { $hasFreeShipping = TRUE; } // Remove business supplies from subtotal if ($item['item_type_id'] == Item::TYPE_SUPPLIES || $item['item_type_id'] == Item::TYPE_SUPPLIES_SETS) { $totalSubtotal->subtract($item['subtotal']); } // Remove presenter kits from subtotal if ($item['item_type_id'] == Item::TYPE_PRESENTER_KIT) { $totalSubtotal->subtract($item['subtotal']); } } if (CakeSession::read('market_id') != $market_id) { $this->orderObject->backOrderCount = 0; $wid = WarehouseUtil::idByMarket($market_id); Configure::write('ns_warehouse_id', $wid); $locale = CakeSession::read('Config'); $locale = $locale['language']; /** * Get Cart */ $results = ['backordered' => [], 'unavailable' => []]; /** * Get availability for cart items */ $this->Item = ClassRegistry::init('Item'); $this->NsWarehouse = ClassRegistry::init('NsWarehouse'); foreach ($orderItems as $key => $item) { $itemCheck = $this->Item->detailsBySku($item['sku'], $locale, true); /** * Unavailable items */ if ($this->NsWarehouse->unorderable($itemCheck['sku'], $wid)) { $results['unavailable'][] = ['sku' => $itemCheck['sku'], 'name' => $itemCheck['name']]; /** * Backordered items */ } elseif ($this->NsWarehouse->backordered($itemCheck['sku'], $wid)) { $results['backordered'][] = ['sku' => $itemCheck['sku'], 'name' => $itemCheck['name']]; $backordered_items = true; $this->orderObject->backOrderCount += $item['qty']; } } } if ($this->orderObject->backOrderCount == $this->orderObject->totalItemCount && $this->orderObject->totalItemCount > 0) { $backordered_items = false; $no_expedite_reason[] = 3; $expedite = false; } $total_weight = ceil($total_weight); $this->ShippingZone = ClassRegistry::init('ShippingZone'); $this->ShippingRate = ClassRegistry::init('ShippingRate'); if ($zipCode && $expedite) { $zone = $this->ShippingZone->find('first', array('fields' => array('ShippingZone.id'), 'conditions' => array('ShippingZone.zip_min <=' => (int) $zipCode, 'ShippingZone.zip_max >=' => (int) $zipCode, 'ShippingZone.warehouse_id' => '1'))); $results = $this->ShippingRate->find('first', array('fields' => array('ShippingRate.rate_ground', 'ShippingRate.rate_2day'), 'conditions' => array('ShippingRate.zone_id' => $zone['ShippingZone']['id'], 'ShippingRate.weight' => $total_weight))); $newDate = new DateTime(); $newDate = $newDate->format('Y-m-d H:i:s'); $promo_dates = $this->SystemSetting->find('all', array('conditions' => array('id' => array('expedited_promo_start_date', 'expedited_promo_end_date', 'two_day_shipping_promo_price')))); foreach ($promo_dates as $promo) { if ($promo['SystemSetting']['id'] == 'expedited_promo_start_date') { $beginDate = $promo['SystemSetting']['value']; } if ($promo['SystemSetting']['id'] == 'expedited_promo_end_date') { $endDate = $promo['SystemSetting']['value']; } if ($promo['SystemSetting']['id'] == 'two_day_shipping_promo_price') { $promo_2day = $promo['SystemSetting']['value']; } } $hide_ground = false; if (!empty($beginDate) && !empty($endDate) && isset($promo_2day)) { if ($newDate >= $beginDate && $newDate <= $endDate) { $results['ShippingRate']['rate_2day'] = $promo_2day; $hide_ground = true; } } $estimated_shipoutdate = $this->shipByDate(); $shipped_by_dates = $this->estimatedShippingDates(); $shipping['rate_ground'] = array('price' => $results['ShippingRate']['rate_ground'], 'date' => $shipped_by_dates['Ground']); $shipping['rate_2day'] = array('price' => $results['ShippingRate']['rate_2day'], 'date' => $shipped_by_dates['TwoDay']); } if ($hasFreeShipping || $totalSubtotal->isGreaterThan($marketShippingTierFree)) { $shipping["total"] = Money::fromFloat(0); } else { if ($totalSubtotal->isGreaterThan($marketShippingTierMid)) { $shipping["total"] = $midTierShipping; } else { $shipping["total"] = $defaultShipping; } } $shipping["no_expedite_reason"] = $no_expedite_reason; $shipping["backordered_items"] = $backordered_items; $shipping['ship_out_date'] = $estimated_shipoutdate; $shipping['hide_ground'] = $hide_ground; return $shipping; }
/** * @covers \SebastianBergmann\Money\Money::subtract * @covers \SebastianBergmann\Money\Money::assertSameCurrency * @uses \SebastianBergmann\Money\Money::__construct * @uses \SebastianBergmann\Money\Money::handleCurrencyArgument * @uses \SebastianBergmann\Money\Money::getAmount * @uses \SebastianBergmann\Money\Money::getCurrency * @uses \SebastianBergmann\Money\Currency * @expectedException \SebastianBergmann\Money\CurrencyMismatchException */ public function testExceptionIsRaisedWhenMoneyObjectWithDifferentCurrencyIsSubtracted() { $a = new Money(1, new Currency('EUR')); $b = new Money(2, new Currency('USD')); $b->subtract($a); }
/** * subtractMoney * * Adds two instances of Money together, returning a new instance in the * same currency as the first instance. * * @param Money $first * @param Money $second * @return type */ public function subtractMoney(Money $first, Money $second) { return $first->subtract($this->normalizeMoneyValue($first, $second)); }