PageRenderTime 59ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 1ms

/app/code/core/Mage/Checkout/Model/Type/Onepage.php

https://bitbucket.org/claudiu_marginean/magento-hg-mirror
PHP | 1117 lines | 551 code | 98 blank | 468 comment | 108 complexity | 8ac6ae488332a9981d4f67a747c317db MD5 | raw file
Possible License(s): CC-BY-SA-3.0, LGPL-2.1, GPL-2.0, WTFPL
  1. <?php
  2. /**
  3. * Magento
  4. *
  5. * NOTICE OF LICENSE
  6. *
  7. * This source file is subject to the Open Software License (OSL 3.0)
  8. * that is bundled with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://opensource.org/licenses/osl-3.0.php
  11. * If you did not receive a copy of the license and are unable to
  12. * obtain it through the world-wide-web, please send an email
  13. * to license@magentocommerce.com so we can send you a copy immediately.
  14. *
  15. * DISCLAIMER
  16. *
  17. * Do not edit or add to this file if you wish to upgrade Magento to newer
  18. * versions in the future. If you wish to customize Magento for your
  19. * needs please refer to http://www.magentocommerce.com for more information.
  20. *
  21. * @category Mage
  22. * @package Mage_Checkout
  23. * @copyright Copyright (c) 2010 Magento Inc. (http://www.magentocommerce.com)
  24. * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
  25. */
  26. /**
  27. * One page checkout processing model
  28. */
  29. class Mage_Checkout_Model_Type_Onepage
  30. {
  31. /**
  32. * Checkout types: Checkout as Guest, Register, Logged In Customer
  33. */
  34. const METHOD_GUEST = 'guest';
  35. const METHOD_REGISTER = 'register';
  36. const METHOD_CUSTOMER = 'customer';
  37. /**
  38. * Error message of "customer already exists"
  39. *
  40. * @var string
  41. */
  42. private $_customerEmailExistsMessage = '';
  43. /**
  44. * @var Mage_Customer_Model_Session
  45. */
  46. protected $_customerSession;
  47. /**
  48. * @var Mage_Checkout_Model_Session
  49. */
  50. protected $_checkoutSession;
  51. /**
  52. * @var Mage_Sales_Model_Quote
  53. */
  54. protected $_quote = null;
  55. /**
  56. * @var Mage_Checkout_Helper_Data
  57. */
  58. protected $_helper;
  59. /**
  60. * Class constructor
  61. * Set customer already exists message
  62. */
  63. public function __construct()
  64. {
  65. $this->_helper = Mage::helper('checkout');
  66. $this->_customerEmailExistsMessage = $this->_helper->__('There is already a customer registered using this email address. Please login using this email address or enter a different email address to register your account.');
  67. $this->_checkoutSession = Mage::getSingleton('checkout/session');
  68. $this->_customerSession = Mage::getSingleton('customer/session');
  69. }
  70. /**
  71. * Get frontend checkout session object
  72. *
  73. * @return Mage_Checkout_Model_Session
  74. */
  75. public function getCheckout()
  76. {
  77. return $this->_checkoutSession;
  78. }
  79. /**
  80. * Quote object getter
  81. *
  82. * @return Mage_Sales_Model_Quote
  83. */
  84. public function getQuote()
  85. {
  86. if ($this->_quote === null) {
  87. return $this->_checkoutSession->getQuote();
  88. }
  89. return $this->_quote;
  90. }
  91. /**
  92. * Declare checkout quote instance
  93. *
  94. * @param Mage_Sales_Model_Quote $quote
  95. */
  96. public function setQuote(Mage_Sales_Model_Quote $quote)
  97. {
  98. $this->_quote = $quote;
  99. return $this;
  100. }
  101. /**
  102. * Get customer session object
  103. *
  104. * @return Mage_Customer_Model_Session
  105. */
  106. public function getCustomerSession()
  107. {
  108. return $this->_customerSession;
  109. }
  110. /**
  111. * Initialize quote state to be valid for one page checkout
  112. *
  113. * @return Mage_Checkout_Model_Type_Onepage
  114. */
  115. public function initCheckout()
  116. {
  117. $checkout = $this->getCheckout();
  118. $customerSession = $this->getCustomerSession();
  119. if (is_array($checkout->getStepData())) {
  120. foreach ($checkout->getStepData() as $step=>$data) {
  121. if (!($step==='login' || $customerSession->isLoggedIn() && $step==='billing')) {
  122. $checkout->setStepData($step, 'allow', false);
  123. }
  124. }
  125. }
  126. /**
  127. * Reset multishipping flag before any manipulations with quote address
  128. * addAddress method for quote object related on this flag
  129. */
  130. if ($this->getQuote()->getIsMultiShipping()) {
  131. $this->getQuote()->setIsMultiShipping(false);
  132. $this->getQuote()->save();
  133. }
  134. /*
  135. * want to laod the correct customer information by assiging to address
  136. * instead of just loading from sales/quote_address
  137. */
  138. $customer = $customerSession->getCustomer();
  139. if ($customer) {
  140. $this->getQuote()->assignCustomer($customer);
  141. }
  142. return $this;
  143. }
  144. /**
  145. * Get quote checkout method
  146. *
  147. * @return string
  148. */
  149. public function getCheckoutMethod()
  150. {
  151. if ($this->getCustomerSession()->isLoggedIn()) {
  152. return self::METHOD_CUSTOMER;
  153. }
  154. if (!$this->getQuote()->getCheckoutMethod()) {
  155. if ($this->_helper->isAllowedGuestCheckout($this->getQuote())) {
  156. $this->getQuote()->setCheckoutMethod(self::METHOD_GUEST);
  157. } else {
  158. $this->getQuote()->setCheckoutMethod(self::METHOD_REGISTER);
  159. }
  160. }
  161. return $this->getQuote()->getCheckoutMethod();
  162. }
  163. /**
  164. * Get quote checkout method
  165. *
  166. * @deprecated since 1.4.0.1
  167. * @return string
  168. */
  169. public function getCheckoutMehod()
  170. {
  171. return $this->getCheckoutMethod();
  172. }
  173. /**
  174. * Specify chceckout method
  175. *
  176. * @param string $method
  177. * @return array
  178. */
  179. public function saveCheckoutMethod($method)
  180. {
  181. if (empty($method)) {
  182. return array('error' => -1, 'message' => $this->_helper->__('Invalid data.'));
  183. }
  184. $this->getQuote()->setCheckoutMethod($method)->save();
  185. $this->getCheckout()->setStepData('billing', 'allow', true);
  186. return array();
  187. }
  188. /**
  189. * Get customer address by identifier
  190. *
  191. * @param int $addressId
  192. * @return Mage_Customer_Model_Address
  193. */
  194. public function getAddress($addressId)
  195. {
  196. $address = Mage::getModel('customer/address')->load((int)$addressId);
  197. $address->explodeStreetAddress();
  198. if ($address->getRegionId()) {
  199. $address->setRegion($address->getRegionId());
  200. }
  201. return $address;
  202. }
  203. /**
  204. * Save billing address information to quote
  205. * This method is called by One Page Checkout JS (AJAX) while saving the billing information.
  206. *
  207. * @param array $data
  208. * @param int $customerAddressId
  209. * @return Mage_Checkout_Model_Type_Onepage
  210. */
  211. public function saveBilling($data, $customerAddressId)
  212. {
  213. if (empty($data)) {
  214. return array('error' => -1, 'message' => $this->_helper->__('Invalid data.'));
  215. }
  216. $address = $this->getQuote()->getBillingAddress();
  217. /* @var $addressForm Mage_Customer_Model_Form */
  218. $addressForm = Mage::getModel('customer/form');
  219. $addressForm->setFormCode('customer_address_edit')
  220. ->setEntityType('customer_address')
  221. ->setIsAjaxRequest(Mage::app()->getRequest()->isAjax());
  222. if (!empty($customerAddressId)) {
  223. $customerAddress = Mage::getModel('customer/address')->load($customerAddressId);
  224. if ($customerAddress->getId()) {
  225. if ($customerAddress->getCustomerId() != $this->getQuote()->getCustomerId()) {
  226. return array('error' => 1,
  227. 'message' => $this->_helper->__('Customer Address is not valid.')
  228. );
  229. }
  230. $address->importCustomerAddress($customerAddress)->setSaveInAddressBook(0);
  231. $addressForm->setEntity($address);
  232. $addressErrors = $addressForm->validateData($address->getData());
  233. if ($addressErrors !== true) {
  234. return array('error' => 1, 'message' => $addressErrors);
  235. }
  236. }
  237. } else {
  238. $addressForm->setEntity($address);
  239. // emulate request object
  240. $addressData = $addressForm->extractData($addressForm->prepareRequest($data));
  241. $addressErrors = $addressForm->validateData($addressData);
  242. if ($addressErrors !== true) {
  243. return array('error' => 1, 'message' => $addressErrors);
  244. }
  245. $addressForm->compactData($addressData);
  246. // Additional form data, not fetched by extractData (as it fetches only attributes)
  247. $address->setSaveInAddressBook(empty($data['save_in_address_book']) ? 0 : 1);
  248. }
  249. // validate billing address
  250. if (($validateRes = $address->validate()) !== true) {
  251. return array('error' => 1, 'message' => $validateRes);
  252. }
  253. $address->implodeStreetAddress();
  254. if (true !== ($result = $this->_validateCustomerData($data))) {
  255. return $result;
  256. }
  257. if (!$this->getQuote()->getCustomerId() && self::METHOD_REGISTER == $this->getQuote()->getCheckoutMethod()) {
  258. if ($this->_customerEmailExists($address->getEmail(), Mage::app()->getWebsite()->getId())) {
  259. return array('error' => 1, 'message' => $this->_customerEmailExistsMessage);
  260. }
  261. }
  262. if (!$this->getQuote()->isVirtual()) {
  263. /**
  264. * Billing address using otions
  265. */
  266. $usingCase = isset($data['use_for_shipping']) ? (int)$data['use_for_shipping'] : 0;
  267. switch($usingCase) {
  268. case 0:
  269. $shipping = $this->getQuote()->getShippingAddress();
  270. $shipping->setSameAsBilling(0);
  271. break;
  272. case 1:
  273. $billing = clone $address;
  274. $billing->unsAddressId()->unsAddressType();
  275. $shipping = $this->getQuote()->getShippingAddress();
  276. $shippingMethod = $shipping->getShippingMethod();
  277. $shipping->addData($billing->getData())
  278. ->setSameAsBilling(1)
  279. ->setSaveInAddressBook(0)
  280. ->setShippingMethod($shippingMethod)
  281. ->setCollectShippingRates(true);
  282. $this->getCheckout()->setStepData('shipping', 'complete', true);
  283. break;
  284. }
  285. }
  286. $this->getQuote()->collectTotals();
  287. $this->getQuote()->save();
  288. $this->getCheckout()
  289. ->setStepData('billing', 'allow', true)
  290. ->setStepData('billing', 'complete', true)
  291. ->setStepData('shipping', 'allow', true);
  292. return array();
  293. }
  294. /**
  295. * Validate customer data and set some its data for further usage in quote
  296. * Will return either true or array with error messages
  297. *
  298. * @param array $data
  299. * @return true|array
  300. */
  301. protected function _validateCustomerData(array $data)
  302. {
  303. /* @var $customerForm Mage_Customer_Model_Form */
  304. $customerForm = Mage::getModel('customer/form');
  305. $customerForm->setFormCode('checkout_register')
  306. ->setIsAjaxRequest(Mage::app()->getRequest()->isAjax());
  307. $quote = $this->getQuote();
  308. if ($quote->getCustomerId()) {
  309. $customer = $quote->getCustomer();
  310. $customerForm->setEntity($customer);
  311. $customerData = $quote->getCustomer()->getData();
  312. } else {
  313. /* @var $customer Mage_Customer_Model_Customer */
  314. $customer = Mage::getModel('customer/customer');
  315. $customerForm->setEntity($customer);
  316. $customerRequest = $customerForm->prepareRequest($data);
  317. $customerData = $customerForm->extractData($customerRequest);
  318. }
  319. $customerErrors = $customerForm->validateData($customerData);
  320. if ($customerErrors !== true) {
  321. return array(
  322. 'error' => -1,
  323. 'message' => implode(', ', $customerErrors)
  324. );
  325. }
  326. if ($quote->getCustomerId()) {
  327. return true;
  328. }
  329. $customerForm->compactData($customerData);
  330. if ($quote->getCheckoutMethod() == self::METHOD_REGISTER) {
  331. // set customer password
  332. $customer->setPassword($customerRequest->getParam('customer_password'));
  333. $customer->setConfirmation($customerRequest->getParam('confirm_password'));
  334. } else {
  335. // emulate customer password for quest
  336. $password = $customer->generatePassword();
  337. $customer->setPassword($password);
  338. $customer->setConfirmation($password);
  339. }
  340. $result = $customer->validate();
  341. if (true !== $result && is_array($result)) {
  342. return array(
  343. 'error' => -1,
  344. 'message' => implode(', ', $result)
  345. );
  346. }
  347. if ($quote->getCheckoutMethod() == self::METHOD_REGISTER) {
  348. // save customer encrypted password in quote
  349. $quote->setPasswordHash($customer->encryptPassword($customer->getPassword()));
  350. }
  351. // copy customer/guest email to address
  352. $quote->getBillingAddress()->setEmail($customer->getEmail());
  353. // copy customer data to quote
  354. Mage::helper('core')->copyFieldset('customer_account', 'to_quote', $customer, $quote);
  355. return true;
  356. }
  357. /**
  358. * Validate customer data and set some its data for further usage in quote
  359. * Will return either true or array with error messages
  360. *
  361. * @deprecated since 1.4.0.1
  362. * @param Mage_Sales_Model_Quote_Address $address
  363. * @return true|array
  364. */
  365. protected function _processValidateCustomer(Mage_Sales_Model_Quote_Address $address)
  366. {
  367. // set customer date of birth for further usage
  368. $dob = '';
  369. if ($address->getDob()) {
  370. $dob = Mage::app()->getLocale()->date($address->getDob(), null, null, false)->toString('yyyy-MM-dd');
  371. $this->getQuote()->setCustomerDob($dob);
  372. }
  373. // set customer tax/vat number for further usage
  374. if ($address->getTaxvat()) {
  375. $this->getQuote()->setCustomerTaxvat($address->getTaxvat());
  376. }
  377. // set customer gender for further usage
  378. if ($address->getGender()) {
  379. $this->getQuote()->setCustomerGender($address->getGender());
  380. }
  381. // invoke customer model, if it is registering
  382. if (self::METHOD_REGISTER == $this->getQuote()->getCheckoutMethod()) {
  383. // set customer password hash for further usage
  384. $customer = Mage::getModel('customer/customer');
  385. $this->getQuote()->setPasswordHash($customer->encryptPassword($address->getCustomerPassword()));
  386. // validate customer
  387. foreach (array(
  388. 'firstname' => 'firstname',
  389. 'lastname' => 'lastname',
  390. 'email' => 'email',
  391. 'password' => 'customer_password',
  392. 'confirmation' => 'confirm_password',
  393. 'taxvat' => 'taxvat',
  394. 'gender' => 'gender',
  395. ) as $key => $dataKey) {
  396. $customer->setData($key, $address->getData($dataKey));
  397. }
  398. if ($dob) {
  399. $customer->setDob($dob);
  400. }
  401. $validationResult = $customer->validate();
  402. if (true !== $validationResult && is_array($validationResult)) {
  403. return array(
  404. 'error' => -1,
  405. 'message' => implode(', ', $validationResult)
  406. );
  407. }
  408. } else if (self::METHOD_GUEST == $this->getQuote()->getCheckoutMethod()) {
  409. $email = $address->getData('email');
  410. if (!Zend_Validate::is($email, 'EmailAddress')) {
  411. return array(
  412. 'error' => -1,
  413. 'message' => $this->_helper->__('Invalid email address "%s"', $email)
  414. );
  415. }
  416. }
  417. return true;
  418. }
  419. /**
  420. * Save checkout shipping address
  421. *
  422. * @param array $data
  423. * @param int $customerAddressId
  424. * @return Mage_Checkout_Model_Type_Onepage
  425. */
  426. public function saveShipping($data, $customerAddressId)
  427. {
  428. if (empty($data)) {
  429. return array('error' => -1, 'message' => $this->_helper->__('Invalid data.'));
  430. }
  431. $address = $this->getQuote()->getShippingAddress();
  432. /* @var $addressForm Mage_Customer_Model_Form */
  433. $addressForm = Mage::getModel('customer/form');
  434. $addressForm->setFormCode('customer_address_edit')
  435. ->setEntityType('customer_address')
  436. ->setIsAjaxRequest(Mage::app()->getRequest()->isAjax());
  437. if (!empty($customerAddressId)) {
  438. $customerAddress = Mage::getModel('customer/address')->load($customerAddressId);
  439. if ($customerAddress->getId()) {
  440. if ($customerAddress->getCustomerId() != $this->getQuote()->getCustomerId()) {
  441. return array('error' => 1,
  442. 'message' => $this->_helper->__('Customer Address is not valid.')
  443. );
  444. }
  445. $address->importCustomerAddress($customerAddress)->setSaveInAddressBook(0);
  446. $addressForm->setEntity($address);
  447. $addressErrors = $addressForm->validateData($address->getData());
  448. if ($addressErrors !== true) {
  449. return array('error' => 1, 'message' => $addressErrors);
  450. }
  451. }
  452. } else {
  453. $addressForm->setEntity($address);
  454. // emulate request object
  455. $addressData = $addressForm->extractData($addressForm->prepareRequest($data));
  456. $addressErrors = $addressForm->validateData($addressData);
  457. if ($addressErrors !== true) {
  458. return array('error' => 1, 'message' => $addressErrors);
  459. }
  460. $addressForm->compactData($addressData);
  461. // Additional form data, not fetched by extractData (as it fetches only attributes)
  462. $address->setSaveInAddressBook(empty($data['save_in_address_book']) ? 0 : 1);
  463. $address->setSameAsBilling(empty($data['same_as_billing']) ? 0 : 1);
  464. }
  465. $address->implodeStreetAddress();
  466. $address->setCollectShippingRates(true);
  467. if (($validateRes = $address->validate())!==true) {
  468. return array('error' => 1, 'message' => $validateRes);
  469. }
  470. $this->getQuote()->collectTotals()->save();
  471. $this->getCheckout()
  472. ->setStepData('shipping', 'complete', true)
  473. ->setStepData('shipping_method', 'allow', true);
  474. return array();
  475. }
  476. /**
  477. * Specify quote shipping method
  478. *
  479. * @param string $shippingMethod
  480. * @return array
  481. */
  482. public function saveShippingMethod($shippingMethod)
  483. {
  484. if (empty($shippingMethod)) {
  485. return array('error' => -1, 'message' => $this->_helper->__('Invalid shipping method.'));
  486. }
  487. $rate = $this->getQuote()->getShippingAddress()->getShippingRateByCode($shippingMethod);
  488. if (!$rate) {
  489. return array('error' => -1, 'message' => $this->_helper->__('Invalid shipping method.'));
  490. }
  491. $this->getQuote()->getShippingAddress()
  492. ->setShippingMethod($shippingMethod);
  493. $this->getQuote()->collectTotals()
  494. ->save();
  495. $this->getCheckout()
  496. ->setStepData('shipping_method', 'complete', true)
  497. ->setStepData('payment', 'allow', true);
  498. return array();
  499. }
  500. /**
  501. * Specify quote payment method
  502. *
  503. * @param array $data
  504. * @return array
  505. */
  506. public function savePayment($data)
  507. {
  508. if (empty($data)) {
  509. return array('error' => -1, 'message' => $this->_helper->__('Invalid data.'));
  510. }
  511. $quote = $this->getQuote();
  512. if ($quote->isVirtual()) {
  513. $quote->getBillingAddress()->setPaymentMethod(isset($data['method']) ? $data['method'] : null);
  514. } else {
  515. $quote->getShippingAddress()->setPaymentMethod(isset($data['method']) ? $data['method'] : null);
  516. }
  517. // shipping totals may be affected by payment method
  518. if (!$quote->isVirtual() && $quote->getShippingAddress()) {
  519. $quote->getShippingAddress()->setCollectShippingRates(true);
  520. }
  521. $payment = $quote->getPayment();
  522. $payment->importData($data);
  523. $quote->save();
  524. $this->getCheckout()
  525. ->setStepData('payment', 'complete', true)
  526. ->setStepData('review', 'allow', true);
  527. return array();
  528. }
  529. /**
  530. * Validate quote state to be integrated with one page checkout process
  531. */
  532. public function validate()
  533. {
  534. $helper = Mage::helper('checkout');
  535. $quote = $this->getQuote();
  536. if ($quote->getIsMultiShipping()) {
  537. Mage::throwException($helper->__('Invalid checkout type.'));
  538. }
  539. if ($quote->getCheckoutMethod() == self::METHOD_GUEST && !$quote->isAllowedGuestCheckout()) {
  540. Mage::throwException($this->_helper->__('Sorry, guest checkout is not enabled. Please try again or contact store owner.'));
  541. }
  542. }
  543. /**
  544. * Prepare quote for guest checkout order submit
  545. *
  546. * @return Mage_Checkout_Model_Type_Onepage
  547. */
  548. protected function _prepareGuestQuote()
  549. {
  550. $quote = $this->getQuote();
  551. $quote->setCustomerId(null)
  552. ->setCustomerEmail($quote->getBillingAddress()->getEmail())
  553. ->setCustomerIsGuest(true)
  554. ->setCustomerGroupId(Mage_Customer_Model_Group::NOT_LOGGED_IN_ID);
  555. return $this;
  556. }
  557. /**
  558. * Prepare quote for customer registration and customer order submit
  559. *
  560. * @return Mage_Checkout_Model_Type_Onepage
  561. */
  562. protected function _prepareNewCustomerQuote()
  563. {
  564. $quote = $this->getQuote();
  565. $billing = $quote->getBillingAddress();
  566. $shipping = $quote->isVirtual() ? null : $quote->getShippingAddress();
  567. //$customer = Mage::getModel('customer/customer');
  568. $customer = $quote->getCustomer();
  569. /* @var $customer Mage_Customer_Model_Customer */
  570. $customerBilling = $billing->exportCustomerAddress();
  571. $customer->addAddress($customerBilling);
  572. $billing->setCustomerAddress($customerBilling);
  573. $customerBilling->setIsDefaultBilling(true);
  574. if ($shipping && !$shipping->getSameAsBilling()) {
  575. $customerShipping = $shipping->exportCustomerAddress();
  576. $customer->addAddress($customerShipping);
  577. $shipping->setCustomerAddress($customerShipping);
  578. $customerShipping->setIsDefaultShipping(true);
  579. } else {
  580. $customerBilling->setIsDefaultShipping(true);
  581. }
  582. Mage::helper('core')->copyFieldset('checkout_onepage_quote', 'to_customer', $quote, $customer);
  583. $customer->setPassword($customer->decryptPassword($quote->getPasswordHash()));
  584. $customer->setPasswordHash($customer->hashPassword($customer->getPassword()));
  585. $quote->setCustomer($customer)
  586. ->setCustomerId(true);
  587. }
  588. /**
  589. * Prepare quote for customer order submit
  590. *
  591. * @return Mage_Checkout_Model_Type_Onepage
  592. */
  593. protected function _prepareCustomerQuote()
  594. {
  595. $quote = $this->getQuote();
  596. $billing = $quote->getBillingAddress();
  597. $shipping = $quote->isVirtual() ? null : $quote->getShippingAddress();
  598. $customer = $this->getCustomerSession()->getCustomer();
  599. if (!$billing->getCustomerId() || $billing->getSaveInAddressBook()) {
  600. $customerBilling = $billing->exportCustomerAddress();
  601. $customer->addAddress($customerBilling);
  602. $billing->setCustomerAddress($customerBilling);
  603. }
  604. if ($shipping && !$shipping->getSameAsBilling() && (!$shipping->getCustomerId() || $shipping->getSaveInAddressBook())) {
  605. $customerShipping = $shipping->exportCustomerAddress();
  606. $customer->addAddress($customerShipping);
  607. $shipping->setCustomerAddress($customerShipping);
  608. }
  609. if (isset($customerBilling) && !$customer->getDefaultBilling()) {
  610. $customerBilling->setIsDefaultBilling(true);
  611. }
  612. if ($shipping && isset($customerShipping) && !$customer->getDefaultShipping()) {
  613. $customerShipping->setIsDefaultShipping(true);
  614. } else if (isset($customerBilling) && !$customer->getDefaultShipping()) {
  615. $customerBilling->setIsDefaultShipping(true);
  616. }
  617. $quote->setCustomer($customer);
  618. }
  619. /**
  620. * Involve new customer to system
  621. *
  622. * @return Mage_Checkout_Model_Type_Onepage
  623. */
  624. protected function _involveNewCustomer()
  625. {
  626. $customer = $this->getQuote()->getCustomer();
  627. if ($customer->isConfirmationRequired()) {
  628. $customer->sendNewAccountEmail('confirmation');
  629. $url = Mage::helper('customer')->getEmailConfirmationUrl($customer->getEmail());
  630. $this->getCustomerSession()->addSuccess(
  631. Mage::helper('customer')->__('Account confirmation is required. Please, check your e-mail for confirmation link. To resend confirmation email please <a href="%s">click here</a>.', $url)
  632. );
  633. } else {
  634. $customer->sendNewAccountEmail();
  635. $this->getCustomerSession()->loginById($customer->getId());
  636. }
  637. return $this;
  638. }
  639. /**
  640. * Create order based on checkout type. Create customer if necessary.
  641. *
  642. * @return Mage_Checkout_Model_Type_Onepage
  643. */
  644. public function saveOrder()
  645. {
  646. $this->validate();
  647. $isNewCustomer = false;
  648. switch ($this->getCheckoutMethod()) {
  649. case self::METHOD_GUEST:
  650. $this->_prepareGuestQuote();
  651. break;
  652. case self::METHOD_REGISTER:
  653. $this->_prepareNewCustomerQuote();
  654. $isNewCustomer = true;
  655. break;
  656. default:
  657. $this->_prepareCustomerQuote();
  658. break;
  659. }
  660. $service = Mage::getModel('sales/service_quote', $this->getQuote());
  661. $service->submitAll();
  662. if ($isNewCustomer) {
  663. try {
  664. $this->_involveNewCustomer();
  665. } catch (Exception $e) {
  666. Mage::logException($e);
  667. }
  668. }
  669. $this->_checkoutSession->setLastQuoteId($this->getQuote()->getId())
  670. ->setLastSuccessQuoteId($this->getQuote()->getId())
  671. ->clearHelperData();
  672. $order = $service->getOrder();
  673. if ($order) {
  674. Mage::dispatchEvent('checkout_type_onepage_save_order_after', array('order'=>$order, 'quote'=>$this->getQuote()));
  675. /**
  676. * a flag to set that there will be redirect to third party after confirmation
  677. * eg: paypal standard ipn
  678. */
  679. $redirectUrl = $this->getQuote()->getPayment()->getOrderPlaceRedirectUrl();
  680. /**
  681. * we only want to send to customer about new order when there is no redirect to third party
  682. */
  683. if (!$redirectUrl && $order->getCanSendNewEmailFlag()) {
  684. try {
  685. $order->sendNewOrderEmail();
  686. } catch (Exception $e) {
  687. Mage::logException($e);
  688. }
  689. }
  690. // add order information to the session
  691. $this->_checkoutSession->setLastOrderId($order->getId())
  692. ->setRedirectUrl($redirectUrl)
  693. ->setLastRealOrderId($order->getIncrementId());
  694. // as well a billing agreement can be created
  695. $agreement = $order->getPayment()->getBillingAgreement();
  696. if ($agreement) {
  697. $this->_checkoutSession->setLastBillingAgreementId($agreement->getId());
  698. }
  699. }
  700. // add recurring profiles information to the session
  701. $profiles = $service->getRecurringPaymentProfiles();
  702. if ($profiles) {
  703. $ids = array();
  704. foreach ($profiles as $profile) {
  705. $ids[] = $profile->getId();
  706. }
  707. $this->_checkoutSession->setLastRecurringProfileIds($ids);
  708. // TODO: send recurring profile emails
  709. }
  710. Mage::dispatchEvent(
  711. 'checkout_submit_all_after',
  712. array('order' => $order, 'quote' => $this->getQuote(), 'recurring_profiles' => $profiles)
  713. );
  714. return $this;
  715. }
  716. /**
  717. * Validate quote state to be able submited from one page checkout page
  718. *
  719. * @deprecated after 1.4 - service model doing quote validation
  720. * @return Mage_Checkout_Model_Type_Onepage
  721. */
  722. protected function validateOrder()
  723. {
  724. $helper = Mage::helper('checkout');
  725. if ($this->getQuote()->getIsMultiShipping()) {
  726. Mage::throwException($helper->__('Invalid checkout type.'));
  727. }
  728. if (!$this->getQuote()->isVirtual()) {
  729. $address = $this->getQuote()->getShippingAddress();
  730. $addressValidation = $address->validate();
  731. if ($addressValidation !== true) {
  732. Mage::throwException($helper->__('Please check shipping address information.'));
  733. }
  734. $method= $address->getShippingMethod();
  735. $rate = $address->getShippingRateByCode($method);
  736. if (!$this->getQuote()->isVirtual() && (!$method || !$rate)) {
  737. Mage::throwException($helper->__('Please specify shipping method.'));
  738. }
  739. }
  740. $addressValidation = $this->getQuote()->getBillingAddress()->validate();
  741. if ($addressValidation !== true) {
  742. Mage::throwException($helper->__('Please check billing address information.'));
  743. }
  744. if (!($this->getQuote()->getPayment()->getMethod())) {
  745. Mage::throwException($helper->__('Please select valid payment method.'));
  746. }
  747. }
  748. /**
  749. * Check if customer email exists
  750. *
  751. * @param string $email
  752. * @param int $websiteId
  753. * @return false|Mage_Customer_Model_Customer
  754. */
  755. protected function _customerEmailExists($email, $websiteId = null)
  756. {
  757. $customer = Mage::getModel('customer/customer');
  758. if ($websiteId) {
  759. $customer->setWebsiteId($websiteId);
  760. }
  761. $customer->loadByEmail($email);
  762. if ($customer->getId()) {
  763. return $customer;
  764. }
  765. return false;
  766. }
  767. /**
  768. * Get last order increment id by order id
  769. *
  770. * @return string
  771. */
  772. public function getLastOrderId()
  773. {
  774. $lastId = $this->getCheckout()->getLastOrderId();
  775. $orderId = false;
  776. if ($lastId) {
  777. $order = Mage::getModel('sales/order');
  778. $order->load($lastId);
  779. $orderId = $order->getIncrementId();
  780. }
  781. return $orderId;
  782. }
  783. /**
  784. * Enter description here...
  785. *
  786. * @return array
  787. */
  788. // public function saveOrder1()
  789. // {
  790. // $this->validateOrder();
  791. // $billing = $this->getQuote()->getBillingAddress();
  792. // if (!$this->getQuote()->isVirtual()) {
  793. // $shipping = $this->getQuote()->getShippingAddress();
  794. // }
  795. //
  796. // /*
  797. // * Check if before this step checkout method was not defined use default values.
  798. // * Related to issue with some browsers when checkout method was not saved during first step.
  799. // */
  800. // if (!$this->getQuote()->getCheckoutMethod()) {
  801. // if ($this->_helper->isAllowedGuestCheckout($this->getQuote(), $this->getQuote()->getStore())) {
  802. // $this->getQuote()->setCheckoutMethod(Mage_Sales_Model_Quote::CHECKOUT_METHOD_GUEST);
  803. // } else {
  804. // $this->getQuote()->setCheckoutMethod(Mage_Sales_Model_Quote::CHECKOUT_METHOD_REGISTER);
  805. // }
  806. // }
  807. //
  808. // switch ($this->getQuote()->getCheckoutMethod()) {
  809. // case Mage_Sales_Model_Quote::CHECKOUT_METHOD_GUEST:
  810. // if (!$this->getQuote()->isAllowedGuestCheckout()) {
  811. // Mage::throwException($this->_helper->__('Sorry, guest checkout is not enabled. Please try again or contact the store owner.'));
  812. // }
  813. // $this->getQuote()->setCustomerId(null)
  814. // ->setCustomerEmail($billing->getEmail())
  815. // ->setCustomerIsGuest(true)
  816. // ->setCustomerGroupId(Mage_Customer_Model_Group::NOT_LOGGED_IN_ID);
  817. // break;
  818. //
  819. // case Mage_Sales_Model_Quote::CHECKOUT_METHOD_REGISTER:
  820. // $customer = Mage::getModel('customer/customer');
  821. // /* @var $customer Mage_Customer_Model_Customer */
  822. //
  823. // $customerBilling = $billing->exportCustomerAddress();
  824. // $customer->addAddress($customerBilling);
  825. //
  826. // if (!$this->getQuote()->isVirtual() && !$shipping->getSameAsBilling()) {
  827. // $customerShipping = $shipping->exportCustomerAddress();
  828. // $customer->addAddress($customerShipping);
  829. // }
  830. //
  831. // if ($this->getQuote()->getCustomerDob() && !$billing->getCustomerDob()) {
  832. // $billing->setCustomerDob($this->getQuote()->getCustomerDob());
  833. // }
  834. //
  835. // if ($this->getQuote()->getCustomerTaxvat() && !$billing->getCustomerTaxvat()) {
  836. // $billing->setCustomerTaxvat($this->getQuote()->getCustomerTaxvat());
  837. // }
  838. //
  839. // if ($this->getQuote()->getCustomerGender() && !$billing->getCustomerGender()) {
  840. // $billing->setCustomerGender($this->getQuote()->getCustomerGender());
  841. // }
  842. //
  843. // Mage::helper('core')->copyFieldset('checkout_onepage_billing', 'to_customer', $billing, $customer);
  844. //
  845. // $customer->setPassword($customer->decryptPassword($this->getQuote()->getPasswordHash()));
  846. // $customer->setPasswordHash($customer->hashPassword($customer->getPassword()));
  847. //
  848. // $this->getQuote()->setCustomer($customer);
  849. // break;
  850. //
  851. // default:
  852. // $customer = Mage::getSingleton('customer/session')->getCustomer();
  853. //
  854. // if (!$billing->getCustomerId() || $billing->getSaveInAddressBook()) {
  855. // $customerBilling = $billing->exportCustomerAddress();
  856. // $customer->addAddress($customerBilling);
  857. // }
  858. // if (!$this->getQuote()->isVirtual() &&
  859. // ((!$shipping->getCustomerId() && !$shipping->getSameAsBilling()) ||
  860. // (!$shipping->getSameAsBilling() && $shipping->getSaveInAddressBook()))) {
  861. //
  862. // $customerShipping = $shipping->exportCustomerAddress();
  863. // $customer->addAddress($customerShipping);
  864. // }
  865. // $customer->setSavedFromQuote(true);
  866. // $customer->save();
  867. //
  868. // $changed = false;
  869. // if (isset($customerBilling) && !$customer->getDefaultBilling()) {
  870. // $customer->setDefaultBilling($customerBilling->getId());
  871. // $changed = true;
  872. // }
  873. // if (!$this->getQuote()->isVirtual() && isset($customerBilling) && !$customer->getDefaultShipping() && $shipping->getSameAsBilling()) {
  874. // $customer->setDefaultShipping($customerBilling->getId());
  875. // $changed = true;
  876. // }
  877. // elseif (!$this->getQuote()->isVirtual() && isset($customerShipping) && !$customer->getDefaultShipping()){
  878. // $customer->setDefaultShipping($customerShipping->getId());
  879. // $changed = true;
  880. // }
  881. //
  882. // if ($changed) {
  883. // $customer->save();
  884. // }
  885. // }
  886. //
  887. // $this->getQuote()->reserveOrderId();
  888. // $convertQuote = Mage::getModel('sales/convert_quote');
  889. // /* @var $convertQuote Mage_Sales_Model_Convert_Quote */
  890. // //$order = Mage::getModel('sales/order');
  891. // if ($this->getQuote()->isVirtual()) {
  892. // $order = $convertQuote->addressToOrder($billing);
  893. // }
  894. // else {
  895. // $order = $convertQuote->addressToOrder($shipping);
  896. // }
  897. // /* @var $order Mage_Sales_Model_Order */
  898. // $order->setBillingAddress($convertQuote->addressToOrderAddress($billing));
  899. //
  900. // if (!$this->getQuote()->isVirtual()) {
  901. // $order->setShippingAddress($convertQuote->addressToOrderAddress($shipping));
  902. // }
  903. //
  904. // $order->setPayment($convertQuote->paymentToOrderPayment($this->getQuote()->getPayment()));
  905. //
  906. // foreach ($this->getQuote()->getAllItems() as $item) {
  907. // $orderItem = $convertQuote->itemToOrderItem($item);
  908. // if ($item->getParentItem()) {
  909. // $orderItem->setParentItem($order->getItemByQuoteItemId($item->getParentItem()->getId()));
  910. // }
  911. // $order->addItem($orderItem);
  912. // }
  913. //
  914. // /**
  915. // * We can use configuration data for declare new order status
  916. // */
  917. // Mage::dispatchEvent('checkout_type_onepage_save_order', array('order'=>$order, 'quote'=>$this->getQuote()));
  918. // // check again, if customer exists
  919. // if ($this->getQuote()->getCheckoutMethod() == Mage_Sales_Model_Quote::CHECKOUT_METHOD_REGISTER) {
  920. // if ($this->_customerEmailExists($customer->getEmail(), Mage::app()->getWebsite()->getId())) {
  921. // Mage::throwException($this->_customerEmailExistsMessage);
  922. // }
  923. // }
  924. // $order->place();
  925. //
  926. // if ($this->getQuote()->getCheckoutMethod()==Mage_Sales_Model_Quote::CHECKOUT_METHOD_REGISTER) {
  927. // $customer->save();
  928. // $customerBillingId = $customerBilling->getId();
  929. // if (!$this->getQuote()->isVirtual()) {
  930. // $customerShippingId = isset($customerShipping) ? $customerShipping->getId() : $customerBillingId;
  931. // $customer->setDefaultShipping($customerShippingId);
  932. // }
  933. // $customer->setDefaultBilling($customerBillingId);
  934. // $customer->save();
  935. //
  936. // $this->getQuote()->setCustomerId($customer->getId());
  937. //
  938. // $order->setCustomerId($customer->getId());
  939. // Mage::helper('core')->copyFieldset('customer_account', 'to_order', $customer, $order);
  940. //
  941. // $billing->setCustomerId($customer->getId())->setCustomerAddressId($customerBillingId);
  942. // if (!$this->getQuote()->isVirtual()) {
  943. // $shipping->setCustomerId($customer->getId())->setCustomerAddressId($customerShippingId);
  944. // }
  945. //
  946. // try {
  947. // if ($customer->isConfirmationRequired()) {
  948. // $customer->sendNewAccountEmail('confirmation');
  949. // }
  950. // else {
  951. // $customer->sendNewAccountEmail();
  952. // }
  953. // } catch (Exception $e) {
  954. // Mage::logException($e);
  955. // }
  956. // }
  957. //
  958. // /**
  959. // * a flag to set that there will be redirect to third party after confirmation
  960. // * eg: paypal standard ipn
  961. // */
  962. // $redirectUrl = $this->getQuote()->getPayment()->getOrderPlaceRedirectUrl();
  963. // if(!$redirectUrl){
  964. // $order->setEmailSent(true);
  965. // }
  966. //
  967. // $order->save();
  968. //
  969. // Mage::dispatchEvent('checkout_type_onepage_save_order_after', array('order'=>$order, 'quote'=>$this->getQuote()));
  970. //
  971. // /**
  972. // * need to have somelogic to set order as new status to make sure order is not finished yet
  973. // * quote will be still active when we send the customer to paypal
  974. // */
  975. //
  976. // $orderId = $order->getIncrementId();
  977. // $this->getCheckout()->setLastQuoteId($this->getQuote()->getId());
  978. // $this->getCheckout()->setLastOrderId($order->getId());
  979. // $this->getCheckout()->setLastRealOrderId($order->getIncrementId());
  980. // $this->getCheckout()->setRedirectUrl($redirectUrl);
  981. //
  982. // /**
  983. // * we only want to send to customer about new order when there is no redirect to third party
  984. // */
  985. // if(!$redirectUrl){
  986. // try {
  987. // $order->sendNewOrderEmail();
  988. // } catch (Exception $e) {
  989. // Mage::logException($e);
  990. // }
  991. // }
  992. //
  993. // if ($this->getQuote()->getCheckoutMethod(true)==Mage_Sales_Model_Quote::CHECKOUT_METHOD_REGISTER
  994. // && !Mage::getSingleton('customer/session')->isLoggedIn()) {
  995. // /**
  996. // * we need to save quote here to have it saved with Customer Id.
  997. // * so when loginById() executes checkout/session method loadCustomerQuote
  998. // * it would not create new quotes and merge it with old one.
  999. // */
  1000. // $this->getQuote()->save();
  1001. // if ($customer->isConfirmationRequired()) {
  1002. // Mage::getSingleton('checkout/session')->addSuccess(Mage::helper('customer')->__('Account confirmation is required. Please, check your e-mail for confirmation link. To resend confirmation email please <a href="%s">click here</a>.', Mage::helper('customer')->getEmailConfirmationUrl($customer->getEmail())));
  1003. // }
  1004. // else {
  1005. // Mage::getSingleton('customer/session')->loginById($customer->getId());
  1006. // }
  1007. // }
  1008. //
  1009. // //Setting this one more time like control flag that we haves saved order
  1010. // //Must be checkout on success page to show it or not.
  1011. // $this->getCheckout()->setLastSuccessQuoteId($this->getQuote()->getId());
  1012. //
  1013. // $this->getQuote()->setIsActive(false);
  1014. // $this->getQuote()->save();
  1015. //
  1016. // return $this;
  1017. // }
  1018. //
  1019. }