00001 <?php
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 class Mage_Checkout_Model_Type_Multishipping extends Mage_Checkout_Model_Type_Abstract
00035 {
00036 public function __construct()
00037 {
00038 parent::__construct();
00039 $this->_init();
00040 }
00041
00042
00043
00044
00045
00046
00047 protected function _init()
00048 {
00049
00050
00051
00052 $this->getQuote()->setIsMultiShipping(true);
00053 if (!$this->getCustomer()->getId()) {
00054 return $this;
00055 }
00056
00057 if ($this->getCheckoutSession()->getCheckoutState() === Mage_Checkout_Model_Session::CHECKOUT_STATE_BEGIN) {
00058 $this->getCheckoutSession()->setCheckoutState(true);
00059
00060
00061
00062
00063 $addresses = $this->getQuote()->getAllAddresses();
00064 foreach ($addresses as $address) {
00065 $this->getQuote()->removeAddress($address->getId());
00066 }
00067
00068 if ($defaultShipping = $this->getCustomerDefaultShippingAddress()) {
00069 $this->getQuote()->getShippingAddress()
00070 ->importCustomerAddress($defaultShipping);
00071
00072 foreach ($this->getQuoteItems() as $item) {
00073
00074
00075
00076 if ($item->getParentItemId()) {
00077 continue;
00078 }
00079 if ($item->getProduct()->getIsVirtual()) {
00080 continue;
00081 }
00082 $this->getQuote()->getShippingAddress()
00083 ->addItem($item);
00084 }
00085 }
00086
00087 if ($this->getCustomerDefaultBillingAddress()) {
00088 $this->getQuote()->getBillingAddress()
00089 ->importCustomerAddress($this->getCustomerDefaultBillingAddress());
00090 foreach ($this->getQuoteItems() as $item) {
00091 if ($item->getParentItemId()) {
00092 continue;
00093 }
00094 if ($item->getProduct()->getIsVirtual()) {
00095 $this->getQuote()->getBillingAddress()->addItem($item);
00096 }
00097 }
00098 }
00099
00100 $this->save();
00101 }
00102 $this->getQuote()->collectTotals();
00103 return $this;
00104 }
00105
00106 public function getQuoteShippingAddressesItems()
00107 {
00108 $items = array();
00109 $addresses = $this->getQuote()->getAllAddresses();
00110 foreach ($addresses as $address) {
00111 foreach ($address->getAllItems() as $item) {
00112 if ($item->getParentItemId()) {
00113 continue;
00114 }
00115
00116 if ($item->getProduct()->getIsVirtual()) {
00117 $items[] = $item;
00118 continue;
00119 }
00120 else {
00121 if ($item->getQty() > 1) {
00122 for ($i = 0, $n = $item->getQty(); $i < $n; $i++) {
00123 if ($i == 0) {
00124 $addressItem = $item;
00125 }
00126 else {
00127 $addressItem = clone $item;
00128 }
00129 $addressItem->setQty(1)
00130 ->setCustomerAddressId($address->getCustomerAddressId())
00131 ->save();
00132 $items[] = $addressItem;
00133 }
00134 }
00135 else {
00136 $item->setCustomerAddressId($address->getCustomerAddressId());
00137 $items[] = $item;
00138 }
00139 }
00140 }
00141 }
00142 return $items;
00143 }
00144
00145 public function removeAddressItem($addressId, $itemId)
00146 {
00147 $address = $this->getQuote()->getAddressById($addressId);
00148
00149 if ($address) {
00150 if ($item = $address->getItemById($itemId)) {
00151 if ($item->getQty()>1 && !$item->getProduct()->getIsVirtual()) {
00152 $item->setQty($item->getQty()-1);
00153 }
00154 else {
00155 $address->removeItem($item->getId());
00156 }
00157
00158 if (count($address->getAllItems()) == 0) {
00159 $address->isDeleted(true);
00160 }
00161
00162 if ($quoteItem = $this->getQuote()->getItemById($item->getQuoteItemId())) {
00163 $newItemQty = $quoteItem->getQty()-1;
00164 if ($newItemQty > 0 && !$item->getProduct()->getIsVirtual()) {
00165 $quoteItem->setQty($quoteItem->getQty()-1);
00166 }
00167 else {
00168 $this->getQuote()->removeItem($quoteItem->getId());
00169 }
00170 }
00171
00172 $this->save();
00173 }
00174 }
00175 return $this;
00176 }
00177
00178 public function setShippingItemsInformation($info)
00179 {
00180 if (is_array($info)) {
00181 $allQty = 0;
00182 foreach ($info as $itemData) {
00183 foreach ($itemData as $quoteItemId => $data) {
00184 $allQty += $data['qty'];
00185 }
00186 }
00187
00188 $maxQty = (int)Mage::getStoreConfig('shipping/option/checkout_multiple_maximum_qty');
00189 if ($allQty > $maxQty) {
00190 Mage::throwException(Mage::helper('checkout')->__('Maximum qty allowed for Shipping to multiple addresses is %s', $maxQty));
00191 }
00192
00193 $addresses = $this->getQuote()->getAllShippingAddresses();
00194 foreach ($addresses as $address) {
00195 $this->getQuote()->removeAddress($address->getId());
00196 }
00197
00198 foreach ($info as $itemData) {
00199 foreach ($itemData as $quoteItemId => $data) {
00200 $this->_addShippingItem($quoteItemId, $data);
00201 }
00202 }
00203
00204 if ($billingAddress = $this->getQuote()->getBillingAddress()) {
00205 $this->getQuote()->removeAddress($billingAddress->getId());
00206 }
00207
00208 $this->getQuote()->getBillingAddress()
00209 ->importCustomerAddress($this->getCustomerDefaultBillingAddress());
00210
00211 foreach ($this->getQuote()->getAllItems() as $_item) {
00212 if (!$_item->getProduct()->getIsVirtual()) {
00213 continue;
00214 }
00215 if (isset($itemData[$_item->getId()]['qty']) && ($qty = (int)$itemData[$_item->getId()]['qty'])) {
00216 $_item->setQty($qty);
00217 }
00218 $this->getQuote()->getBillingAddress()->addItem($_item);
00219 }
00220
00221 $this->save();
00222 Mage::dispatchEvent('checkout_type_multishipping_set_shipping_items', array('quote'=>$this->getQuote()));
00223 }
00224 return $this;
00225 }
00226
00227 protected function _addShippingItem($quoteItemId, $data)
00228 {
00229 $qty = isset($data['qty']) ? (int) $data['qty'] : 0;
00230 $qty = $qty > 0 ? $qty : 1;
00231 $addressId = isset($data['address']) ? (int) $data['address'] : false;
00232 $quoteItem = $this->getQuote()->getItemById($quoteItemId);
00233
00234 if ($addressId && $quoteItem) {
00235 $quoteItem->setMultisippingQty((int)$quoteItem->getMultisippingQty()+$qty);
00236 $quoteItem->setQty($quoteItem->getMultisippingQty());
00237
00238 $address = $this->getCustomer()->getAddressById($addressId);
00239 if ($address) {
00240 if (!$quoteAddress = $this->getQuote()->getShippingAddressByCustomerAddressId($addressId)) {
00241 $quoteAddress = Mage::getModel('sales/quote_address')
00242 ->importCustomerAddress($address);
00243 $this->getQuote()->addShippingAddress($quoteAddress);
00244 }
00245
00246 $quoteAddress = $this->getQuote()->getShippingAddressByCustomerAddressId($address->getId());
00247
00248 if ($quoteAddressItem = $quoteAddress->getItemByQuoteItemId($quoteItemId)) {
00249 $quoteAddressItem->setQty((int)($quoteAddressItem->getQty()+$qty));
00250 }
00251 else {
00252 $quoteAddress->addItem($quoteItem, $qty);
00253 }
00254
00255
00256
00257
00258 $quoteAddress->setCollectShippingRates((boolean) $this->getCollectRatesFlag());
00259 }
00260 }
00261 return $this;
00262 }
00263
00264 public function updateQuoteCustomerShippingAddress($addressId)
00265 {
00266 if ($address = $this->getCustomer()->getAddressById($addressId)) {
00267 $this->getQuote()->getShippingAddressByCustomerAddressId($addressId)
00268 ->setCollectShippingRates(true)
00269 ->importCustomerAddress($address)
00270 ->collectTotals();
00271 $this->getQuote()->save();
00272 }
00273 return $this;
00274 }
00275
00276 public function setQuoteCustomerBillingAddress($addressId)
00277 {
00278 if ($address = $this->getCustomer()->getAddressById($addressId)) {
00279 $this->getQuote()->getBillingAddress($addressId)
00280 ->importCustomerAddress($address)
00281 ->collectTotals();
00282 $this->getQuote()->collectTotals()->save();
00283 }
00284 return $this;
00285 }
00286
00287 public function setShippingMethods($methods)
00288 {
00289 $addresses = $this->getQuote()->getAllShippingAddresses();
00290 foreach ($addresses as $address) {
00291 if (isset($methods[$address->getId()])) {
00292 $address->setShippingMethod($methods[$address->getId()]);
00293 }
00294 elseif (!$address->getShippingMethod()) {
00295 Mage::throwException(Mage::helper('checkout')->__('Please select shipping methods for all addresses'));
00296 }
00297 }
00298 $addresses = $this->getQuote()
00299 ->collectTotals()
00300 ->save();
00301 return $this;
00302 }
00303
00304 public function setPaymentMethod($payment)
00305 {
00306 if (!isset($payment['method'])) {
00307 Mage::throwException(Mage::helper('checkout')->__('Payment method is not defined'));
00308 }
00309 $this->getQuote()->getPayment()
00310 ->importData($payment)
00311 ->save();
00312 return $this;
00313 }
00314
00315
00316
00317
00318
00319
00320
00321 protected function _prepareOrder(Mage_Sales_Model_Quote_Address $address)
00322 {
00323 $this->getQuote()->unsReservedOrderId();
00324 $this->getQuote()->reserveOrderId();
00325 $convertQuote = Mage::getSingleton('sales/convert_quote');
00326 $order = $convertQuote->addressToOrder($address);
00327 $order->setBillingAddress(
00328 $convertQuote->addressToOrderAddress($this->getQuote()->getBillingAddress())
00329 );
00330
00331 if ($address->getAddressType() == 'billing') {
00332 $order->setIsVirtual(1);
00333 }
00334 else {
00335 $order->setShippingAddress($convertQuote->addressToOrderAddress($address));
00336 }
00337 $order->setPayment($convertQuote->paymentToOrderPayment($this->getQuote()->getPayment()));
00338
00339 foreach ($address->getAllItems() as $item) {
00340 $item->setProductType($item->getQuoteItem()->getProductType())
00341 ->setProductOptions($item->getQuoteItem()->getProduct()->getTypeInstance(true)->getOrderOptions($item->getQuoteItem()->getProduct()));
00342 $orderItem = $convertQuote->itemToOrderItem($item);
00343 if ($item->getParentItem()) {
00344 $orderItem->setParentItem($order->getItemByQuoteItemId($item->getParentItem()->getId()));
00345 }
00346 $order->addItem($orderItem);
00347 }
00348
00349 return $order;
00350 }
00351
00352 protected function _validate()
00353 {
00354 $helper = Mage::helper('checkout');
00355 if (!$this->getQuote()->getIsMultiShipping()) {
00356 Mage::throwException($helper->__('Invalid checkout type.'));
00357 }
00358
00359 $addresses = $this->getQuote()->getAllShippingAddresses();
00360 foreach ($addresses as $address) {
00361 $addressValidation = $address->validate();
00362 if ($addressValidation !== true) {
00363 Mage::throwException($helper->__('Please check shipping addresses information.'));
00364 }
00365 $method= $address->getShippingMethod();
00366 $rate = $address->getShippingRateByCode($method);
00367 if (!$method || !$rate) {
00368 Mage::throwException($helper->__('Please specify shipping methods for all addresses.'));
00369 }
00370 }
00371 $addressValidation = $this->getQuote()->getBillingAddress()->validate();
00372 if ($addressValidation !== true) {
00373 Mage::throwException($helper->__('Please check billing address information.'));
00374 }
00375 return $this;
00376 }
00377
00378 public function createOrders()
00379 {
00380 $orderIds = array();
00381 $this->_validate();
00382 $shippingAddresses = $this->getQuote()->getAllShippingAddresses();
00383 $orders = array();
00384
00385 if ($this->getQuote()->hasVirtualItems()) {
00386 $shippingAddresses[] = $this->getQuote()->getBillingAddress();
00387 }
00388
00389 foreach ($shippingAddresses as $address) {
00390 $order = $this->_prepareOrder($address);
00391
00392 $orders[] = $order;
00393 Mage::dispatchEvent(
00394 'checkout_type_multishipping_create_orders_single',
00395 array('order'=>$order, 'address'=>$address)
00396 );
00397 }
00398
00399 foreach ($orders as $order) {
00400 #$order->save();
00401 $order->place();
00402 $order->save();
00403
00404 $order->sendNewOrderEmail();
00405 $orderIds[$order->getId()] = $order->getIncrementId();
00406 }
00407
00408 Mage::getSingleton('core/session')->setOrderIds($orderIds);
00409 $this->getQuote()
00410 ->setIsActive(false)
00411 ->save();
00412
00413 return $this;
00414 }
00415
00416 public function save()
00417 {
00418 $this->getQuote()->collectTotals()
00419 ->save();
00420 return $this;
00421 }
00422
00423 public function reset()
00424 {
00425 $this->getCheckoutSession()->setCheckoutState(Mage_Checkout_Model_Session::CHECKOUT_STATE_BEGIN);
00426 return $this;
00427 }
00428
00429 public function validateMinimumAmount()
00430 {
00431 return !(Mage::getStoreConfigFlag('sales/minimum_order/active')
00432 && Mage::getStoreConfigFlag('sales/minimum_order/multi_address')
00433 && !$this->getQuote()->validateMinimumAmount());
00434 }
00435
00436 public function getMinimumAmountDescription()
00437 {
00438 $descr = Mage::getStoreConfig('sales/minimum_order/multi_address_description');
00439 if (empty($descr)) {
00440 $descr = Mage::getStoreConfig('sales/minimum_order/description');
00441 }
00442 return $descr;
00443 }
00444
00445 public function getMinimumAmountError()
00446 {
00447 $error = Mage::getStoreConfig('sales/minimum_order/multi_address_error_message');
00448 if (empty($error)) {
00449 $error = Mage::getStoreConfig('sales/minimum_order/error_message');
00450 }
00451 return $error;
00452 }
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462 public function isCheckoutAvailable()
00463 {
00464 return Mage::helper('checkout')->isMultishippingCheckoutAvailable();
00465 }
00466 }