1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25:
26:
27: 28: 29:
30: class Mage_Sales_Model_Service_Quote
31: {
32: 33: 34: 35: 36:
37: protected $_quote;
38:
39: 40: 41: 42: 43:
44: protected $_convertor;
45:
46: 47: 48: 49: 50:
51: protected $_orderData = array();
52:
53: 54: 55: 56: 57:
58: protected $_recurringPaymentProfiles = array();
59:
60: 61: 62: 63: 64:
65: protected $_order = null;
66:
67: 68: 69: 70: 71:
72: protected $_shouldInactivateQuote = true;
73:
74: 75: 76: 77: 78:
79: public function __construct(Mage_Sales_Model_Quote $quote)
80: {
81: $this->_quote = $quote;
82: $this->_convertor = Mage::getModel('sales/convert_quote');
83: }
84:
85: 86: 87: 88: 89: 90:
91: public function setConvertor(Mage_Sales_Model_Convert_Quote $convertor)
92: {
93: $this->_convertor = $convertor;
94: return $this;
95: }
96:
97: 98: 99: 100: 101:
102: public function getQuote()
103: {
104: return $this->_quote;
105: }
106:
107: 108: 109: 110: 111: 112:
113: public function setOrderData(array $data)
114: {
115: $this->_orderData = $data;
116: return $this;
117: }
118:
119: 120: 121: 122: 123:
124: public function submit()
125: {
126: return $this->submitOrder();
127: }
128:
129: 130: 131: 132: 133:
134: public function submitOrder()
135: {
136: $this->_deleteNominalItems();
137: $this->_validate();
138: $quote = $this->_quote;
139: $isVirtual = $quote->isVirtual();
140:
141: $transaction = Mage::getModel('core/resource_transaction');
142: if ($quote->getCustomerId()) {
143: $transaction->addObject($quote->getCustomer());
144: }
145: $transaction->addObject($quote);
146:
147: $quote->reserveOrderId();
148: if ($isVirtual) {
149: $order = $this->_convertor->addressToOrder($quote->getBillingAddress());
150: } else {
151: $order = $this->_convertor->addressToOrder($quote->getShippingAddress());
152: }
153: $order->setBillingAddress($this->_convertor->addressToOrderAddress($quote->getBillingAddress()));
154: if ($quote->getBillingAddress()->getCustomerAddress()) {
155: $order->getBillingAddress()->setCustomerAddress($quote->getBillingAddress()->getCustomerAddress());
156: }
157: if (!$isVirtual) {
158: $order->setShippingAddress($this->_convertor->addressToOrderAddress($quote->getShippingAddress()));
159: if ($quote->getShippingAddress()->getCustomerAddress()) {
160: $order->getShippingAddress()->setCustomerAddress($quote->getShippingAddress()->getCustomerAddress());
161: }
162: }
163: $order->setPayment($this->_convertor->paymentToOrderPayment($quote->getPayment()));
164:
165: foreach ($this->_orderData as $key => $value) {
166: $order->setData($key, $value);
167: }
168:
169: foreach ($quote->getAllItems() as $item) {
170: $orderItem = $this->_convertor->itemToOrderItem($item);
171: if ($item->getParentItem()) {
172: $orderItem->setParentItem($order->getItemByQuoteItemId($item->getParentItem()->getId()));
173: }
174: $order->addItem($orderItem);
175: }
176:
177: $order->setQuote($quote);
178:
179: $transaction->addObject($order);
180: $transaction->addCommitCallback(array($order, 'place'));
181: $transaction->addCommitCallback(array($order, 'save'));
182:
183: 184: 185:
186: Mage::dispatchEvent('checkout_type_onepage_save_order', array('order'=>$order, 'quote'=>$quote));
187: Mage::dispatchEvent('sales_model_service_quote_submit_before', array('order'=>$order, 'quote'=>$quote));
188: try {
189: $transaction->save();
190: $this->_inactivateQuote();
191: Mage::dispatchEvent('sales_model_service_quote_submit_success', array('order'=>$order, 'quote'=>$quote));
192: } catch (Exception $e) {
193:
194: if (!Mage::getSingleton('customer/session')->isLoggedIn()) {
195:
196: $quote->getCustomer()->setId(null);
197: }
198:
199:
200: $order->setId(null);
201:
202: foreach ($order->getItemsCollection() as $item) {
203: $item->setOrderId(null);
204: $item->setItemId(null);
205: }
206:
207: Mage::dispatchEvent('sales_model_service_quote_submit_failure', array('order'=>$order, 'quote'=>$quote));
208: throw $e;
209: }
210: Mage::dispatchEvent('sales_model_service_quote_submit_after', array('order'=>$order, 'quote'=>$quote));
211: $this->_order = $order;
212: return $order;
213: }
214:
215: 216: 217: 218: 219:
220: public function submitNominalItems()
221: {
222: $this->_validate();
223: $this->_submitRecurringPaymentProfiles();
224: $this->_inactivateQuote();
225: $this->_deleteNominalItems();
226: }
227:
228: 229: 230: 231:
232: public function submitAll()
233: {
234:
235: $shouldInactivateQuoteOld = $this->_shouldInactivateQuote;
236: $this->_shouldInactivateQuote = false;
237: try {
238: $this->submitNominalItems();
239: $this->_shouldInactivateQuote = $shouldInactivateQuoteOld;
240: } catch (Exception $e) {
241: $this->_shouldInactivateQuote = $shouldInactivateQuoteOld;
242: throw $e;
243: }
244:
245: if (!$this->_quote->getAllVisibleItems()) {
246: $this->_inactivateQuote();
247: return;
248: }
249: $this->submitOrder();
250: }
251:
252: 253: 254: 255: 256:
257: public function getRecurringPaymentProfiles()
258: {
259: return $this->_recurringPaymentProfiles;
260: }
261:
262: 263: 264: 265: 266:
267: public function getOrder()
268: {
269: return $this->_order;
270: }
271:
272: 273: 274: 275: 276:
277: protected function _inactivateQuote()
278: {
279: if ($this->_shouldInactivateQuote) {
280: $this->_quote->setIsActive(false);
281: }
282: return $this;
283: }
284:
285: 286: 287: 288: 289:
290: protected function _validate()
291: {
292: if (!$this->getQuote()->isVirtual()) {
293: $address = $this->getQuote()->getShippingAddress();
294: $addressValidation = $address->validate();
295: if ($addressValidation !== true) {
296: Mage::throwException(
297: Mage::helper('sales')->__('Please check shipping address information. %s', implode(' ', $addressValidation))
298: );
299: }
300: $method= $address->getShippingMethod();
301: $rate = $address->getShippingRateByCode($method);
302: if (!$this->getQuote()->isVirtual() && (!$method || !$rate)) {
303: Mage::throwException(Mage::helper('sales')->__('Please specify a shipping method.'));
304: }
305: }
306:
307: $addressValidation = $this->getQuote()->getBillingAddress()->validate();
308: if ($addressValidation !== true) {
309: Mage::throwException(
310: Mage::helper('sales')->__('Please check billing address information. %s', implode(' ', $addressValidation))
311: );
312: }
313:
314: if (!($this->getQuote()->getPayment()->getMethod())) {
315: Mage::throwException(Mage::helper('sales')->__('Please select a valid payment method.'));
316: }
317:
318: return $this;
319: }
320:
321: 322: 323:
324: protected function _submitRecurringPaymentProfiles()
325: {
326: $profiles = $this->_quote->prepareRecurringPaymentProfiles();
327: foreach ($profiles as $profile) {
328: if (!$profile->isValid()) {
329: Mage::throwException($profile->getValidationErrors(true, true));
330: }
331: $profile->submit();
332: }
333: $this->_recurringPaymentProfiles = $profiles;
334: }
335:
336: 337: 338:
339: protected function _deleteNominalItems()
340: {
341: foreach ($this->_quote->getAllVisibleItems() as $item) {
342: if ($item->isNominal()) {
343: $item->isDeleted(true);
344: }
345: }
346: }
347: }
348: