Esempio n. 1
0
		protected function editOrder()
		{
			$orderId = $_GET['orderId'];
			if (!isId($orderId)) {
				exit;
			}

			$entity = new ISC_ENTITY_ORDER;
			$order = $entity->get($orderId);
			$quote = $entity->convertOrderToQuote($orderId, false);
			unset($entity);

			if (!$quote) {
				exit;
			}

			do {
				$sessionId = md5(uniqid($orderId));
			} while(isset($_SESSION['QUOTE_SESSIONS'][$sessionId]));
			$_SESSION['QUOTE_SESSIONS'][$sessionId] = $quote;

			if ($order['deleted']) {
				FlashMessage(GetLang('EditDeletedOrderNotice'), MSG_ERROR);
			} else {
				FlashMessage(GetLang('EditOrderNotice'), MSG_INFO);
			}

			return $this->displayAddEditOrder($sessionId, $orderId);
		}
Esempio n. 2
0
		protected function editOrderSaveAction()
		{
			if (empty($_POST['quoteSession'])) {
				exit;
			}

			$quoteSession = $_POST['quoteSession'];

			/** @var ISC_QUOTE */
			$quote = getClass('ISC_ADMIN_ORDERS')->getQuoteSession($quoteSession);
			if(!$quote) {
				$this->sendEditOrderNoQuoteResponse('saveError');
			}

			try {
				$quote->setCustomerMessage(Interspire_Request::post('customerMessage'));
				$quote->setStaffNotes(Interspire_Request::post('staffNotes'));

				$entity = new ISC_ENTITY_ORDER;

				$currency = GetDefaultCurrency();
				$order = array(
					'ordcurrencyid' => $currency['currencyid'],
					'ordcurrencyexchangerate' => $currency['currencyexchangerate'],
					'ordipaddress' => getIp(),
					'extraInfo' => array(),
					'quote' => $quote,
				);

				$createAccount = false;

				// process customer details to see if an account should be made
				if (Interspire_Request::post('orderFor') == 'new') {
					// this really needs to be split off into another method because it's done both at the front end checkout, in save billing, and in here! -ge
					$password = '';
					$confirmedPassword = '';
					$email = '';
					$accountFormFields = $GLOBALS['ISC_CLASS_FORM']->getFormFields(FORMFIELDS_FORM_ACCOUNT, true);
					$accountCustomFields = array();
					foreach($accountFormFields as $formFieldId => $formField) {
						$formFieldPrivateId = $formField->record['formfieldprivateid'];

						if (!$formFieldPrivateId) {
							$accountCustomFields[$formFieldId] = $formField->getValue();
						} else if($formFieldPrivateId == 'EmailAddress') {
							$email = $formField->getValue();
						} else if($formFieldPrivateId == 'Password') {
							$password = $formField->getValue();
						} else if($formFieldPrivateId == 'ConfirmPassword') {
							$confirmedPassword = $formField->getValue();
						}
					}

					// shouldn't reach this point with a valid email without all the details already being validated after step 1 > next, so go ahead and assign it to the order
					if ($email) {
						$createAccount = array(
							'addresses' => array(),
							'password' => $password,
							'customFormFields' => $accountCustomFields,
						);

						foreach ($quote->getAllAddresses() as /** @var ISC_QUOTE_ADDRESS */$address) {
							if (!$address->getSaveAddress()) {
								continue;
							}

							$customerAddress = $address->getAsArray();
							$customFields = $address->getCustomFields();
							if (!empty($customFields)) {
								$customerAddress['customFormFields'] = $customFields;

								// Shipping fields need to be mapped back to billing so they can be stored
								if ($address->getType() == ISC_QUOTE_ADDRESS::TYPE_SHIPPING) {
									$newCustomFields = array();
									$map = $GLOBALS['ISC_CLASS_FORM']->mapAddressFieldList(FORMFIELDS_FORM_SHIPPING, array_keys($customFields));
									foreach($map as $oldId => $newId) {
										$newCustomFields[$newId] = $customFields[$oldId];
									}
									$customerAddress['customFormFields'] = $newCustomFields;
								}
							}

							$createAccount['addresses'][] = $customerAddress;
						}
					}
				}

				if ($quote->getOrderId()) {
					$editing = true;
					$adding = false;

					$orderId = $quote->getOrderId();

					$existingOrder = $entity->get($orderId);
					if ($existingOrder['deleted']) {
						// don't allow saving changes for a deleted order
						$errors[] = GetLang('EditDeletedOrderError');
					} else {
						$order['orderid'] = $orderId;
						if (!$entity->edit($order)) {
							$errors[] = $entity->getError();
						}
					}
				} else {
					$editing = false;
					$adding = true;

					$order['orderpaymentmodule'] = '';

					$orderId = $entity->add($order);

					if ($orderId) {
						$quote->setOrderId($orderId);
					} else {
						$errors[] = $entity->getError();
					}
				}

				if (!empty($errors)) {
					$this->sendEditOrderResponse(array(
						'errors' => $errors,
						'stateTransition' => 'saveError',
					));
				}

				// retrieve the created/edited order record
				$order = GetOrder($orderId);

				if ($createAccount) {
					// this function doesn't return anything for error testing
					createOrderCustomerAccount($order, $createAccount);
				}

				// Process a payment
				$paymentMethod = Interspire_Request::post('paymentMethod');

				$providerSuccess = false;

				// Retrieve the payment method details
				$paymentFields = Interspire_Request::post('paymentField');
				if (!empty($paymentFields[$paymentMethod])) {
					$paymentFields = $paymentFields[$paymentMethod];
				}
				else {
					$paymentFields = array();
				}

				if ($quote->getGrandTotalWithStoreCredit() > 0 && ($adding || empty($order['ordpaymentstatus']) || empty($order['orderpaymentmodule'])) && !empty($paymentMethod)) {
					$gatewayAmount = $quote->getGrandTotalWithStoreCredit();

					$provider = null;

					// was a custom payment specified?
					if ($paymentMethod == 'custom') {
						$paymentMethodName = $paymentFields['custom_name'];
						$providerSuccess = true;
					}
					// actual payment module
					else {
						GetModuleById('checkout', $provider, $paymentMethod);
						if(is_object($provider)) {
							$paymentMethodName = $provider->GetDisplayName();

							if (method_exists($provider, 'ProcessManualPayment')) {
								// set the order token as required by various payment methods
								ISC_SetCookie('SHOP_ORDER_TOKEN', $order['ordtoken'], time() + (3600*24), true);
								// make the token immediately available
								$_COOKIE['SHOP_ORDER_TOKEN'] = $order['ordtoken'];

								// process the payment
								$result = $provider->ProcessManualPayment($order, $paymentFields);
								if ($result['result']) {
									$providerSuccess = true;
									$gatewayAmount = $result['amount'];

									FlashMessage(GetLang('OrderPaymentSuccess', array('amount' => FormatPrice($gatewayAmount), 'orderId' => $orderId, 'provider' => $paymentMethodName)), MSG_SUCCESS);
								}
								else {
									$errors[] = GetLang('OrderPaymentFail', array('orderId' => $orderId, 'provider' => $paymentMethodName, 'reason' => $result['message']));
								}
							}
							else {
								// all manual/offline methods will always be successfull
								$providerSuccess = true;
							}
						}
						else {
							// failed to get a payment module
						}
					}
				// if the grand total after minus the coupon,etc is 0 and it's adding order also the payment method is custom.
				} else if ($quote->getGrandTotalWithStoreCredit() == 0 && ($adding || empty($order['ordpaymentstatus']) || empty($order['orderpaymentmodule'])) && $paymentMethod == 'custom') {
					$paymentMethodName = $paymentFields['custom_name'];
					$providerSuccess = true;
				}

				// was payment successfull?
				if ($providerSuccess) {
					// record payment info for the order
					$updatedOrder = array(
						'orderpaymentmethod' 	=> $paymentMethodName,
						'orderpaymentmodule'	=> $paymentMethod,
					);

					$this->db->UpdateQuery("orders", $updatedOrder, "orderid = " . $orderId);

					// set appropriate status for the order
					if ($quote->isDigital()) {
						$newStatus = ORDER_STATUS_COMPLETED;
					}
					else {
						$newStatus = ORDER_STATUS_AWAITING_FULFILLMENT;
					}
					UpdateOrderStatus($orderId, $newStatus, false);

					// email invoice
					if (Interspire_Request::post('emailInvoiceToCustomer')) {
						EmailInvoiceToCustomer($orderId);
					}
				}

				if (!empty($errors)) {
					$response = array(
						'errors' => $errors,
						'stateTransition' => 'saveError',
					);
				}
				else {
					if ($editing) {
						FlashMessage(GetLang('OrderUpdated', array('orderId' => $orderId)), MSG_SUCCESS);
					} else {
						FlashMessage(GetLang('OrderCreated', array('orderId' => $orderId)), MSG_SUCCESS);
					}

					$response = array(
						'stateTransition' => 'saveOk',
					);

					// remove quote object from session after successful save and successful payment
					getClass('ISC_ADMIN_ORDERS')->deleteQuoteSession($quoteSession);
				}

				if ($adding) {
					$response['updateOrderId'] = $orderId;
				}

				$this->sendEditOrderResponse($response);
			} catch (ISC_QUOTE_EXCEPTION $exception) {
				$this->sendEditOrderResponse(array(
					'stateTransition' => 'saveError',
					'errors' => array(
						$exception->getMessage(),
					),
				));
			}
		}
Esempio n. 3
0
	public function __construct($orderId = null)
	{
		$this->setDoubleOptIn(GetConfig('EmailIntegrationOrderDoubleOptin'));
		$this->setSendWelcome(GetConfig('EmailIntegrationOrderSendWelcome'));
		$this->setSubscriptionIP(GetIP());

		if (!$orderId) {
			return;
		}

		$entity = new ISC_ENTITY_ORDER;

		$data = $entity->get($orderId);
		if (!$data) {
			throw new Interspire_EmailIntegration_Subscription_Exception;
		}
		$this->_data = $data;
		unset($data);

		// copy any form fields associated with the order + associated customer and place into local subscription data

		if (isId($this->_data['ordformsessionid'])) {
			/** @var ISC_FORM */
			$form = $GLOBALS["ISC_CLASS_FORM"];

			$customFields = array();

			$formData = $form->getSavedSessionData($this->_data['customer']['custformsessionid']);
			if ($formData && !empty($formData)) {
				$customFields += $formData;
			}

			$formData = $form->getSavedSessionData($this->_data['ordformsessionid']);
			if ($formData && !empty($formData)) {
				$customFields += $formData;
			}

			foreach ($customFields as $fieldId => $value) {
				$this->_data['FormField_' . $fieldId] = $value;
			}
		}

		// generate fields specifically for email integration based on order data (ones that aren't covered by simple order data or by Form Fields)

		// get the first shipping address record because IEM had shipping method as mappable field
		$this->_data['shipping_method'] = '';
		$shippingMethod = $GLOBALS['ISC_CLASS_DB']->FetchOne("SELECT `method` FROM [|PREFIX|]order_shipping WHERE order_id = " . (int)$orderId . " LIMIT 1", 'method');
		if ($shippingMethod) {
			$this->_data['shipping_method'] = $shippingMethod;
		}

		// pre-formated 'full address' mappable field to pass to providers like mailchimp
		$this->_data['OrderSubscription_BillingAddress'] = array(
			'addr1' => $this->_data['ordbillstreet1'],
			'addr2' => $this->_data['ordbillstreet2'],
			'city' => $this->_data['ordbillsuburb'],
			'state' => $this->_data['ordbillstate'],
			'zip' => $this->_data['ordbillzip'],
			'country' => $this->_data['ordbillcountrycode'],
		);

		// country-code specific fields to pass to providers like MailChimp or IEM that support (or require in IEM's case) country codes
		$this->_data['OrderSubscription_BillingAddress_countryiso2'] = $this->_data['ordbillcountrycode'];
		$this->_data['OrderSubscription_BillingAddress_countryiso3'] = GetCountryISO3ById($this->_data['ordbillcountryid']);

		// for email integration, we prefer sending the value of an order as the total amount rather than the stored (charged) total - which could be less than the value due to store credit or gift certificates
		// so, generate some columns which are internal to this subscription data and map to those instead of total_ex and total_inc
		$this->_data['total_ex_tax'] = $this->_data['subtotal_ex_tax'] + $this->_data['shipping_cost_ex_tax'] + $this->_data['handling_cost_ex_tax'] + $this->_data['wrapping_cost_ex_tax'];
		$this->_data['total_inc_tax'] = $this->_data['subtotal_inc_tax'] + $this->_data['shipping_cost_inc_tax'] + $this->_data['handling_cost_inc_tax'] + $this->_data['wrapping_cost_inc_tax'];

		// generated fields: end

		// currency values must be stored in the subscription data as both numeric and formatted so that, when translated to the mail provider, it can be sent as either a number or string depending on the destination field
		$moneyFields = array(
			'subtotal_ex_tax',
			'subtotal_inc_tax',
			'subtotal_tax',
			'total_ex_tax',
			'total_inc_tax',
			'total_tax',
			'shipping_cost_ex_tax',
			'shipping_cost_inc_tax',
			'shipping_cost_tax',
			'handling_cost_ex_tax',
			'handling_cost_inc_tax',
			'handling_cost_tax',
			'wrapping_cost_ex_tax',
			'wrapping_cost_inc_tax',
			'wrapping_cost_tax',
			'ordrefundedamount',
			'ordstorecreditamount',
			'ordgiftcertificateamount',
			'orddiscountamount',
			'coupon_discount',
		);

		foreach ($moneyFields as $moneyFieldId) {
			$this->_data[$moneyFieldId] = array(
				'numeric' => $this->_data[$moneyFieldId],
				'formatted' => FormatPriceInCurrency($this->_data[$moneyFieldId], $this->_data['orddefaultcurrencyid']),
			);
		}

		$set = new ISC_NESTEDSET_CATEGORIES;

		// instead of storing full product information, just store the data pertinent to integration rules
		foreach ($this->_data['products'] as $product) {
			$this->_products[] = $product['productid'];
			$this->_brands[] = $product['prodbrandid'];

			if ($product['prodcatids']) {
				foreach (explode(',', $product['prodcatids']) as $categoryId) {
					$this->_categories[] = $categoryId;

					// also include parent categories to trigger rules related to them
					$parents = $set->getParentPath(array('categoryid'), (int)$categoryId);
					foreach ($parents as $parentCategory) {
						$this->_categories[] = $parentCategory['categoryid'];
					}
				}
			}
		}

		$this->_products = array_unique($this->_products);
		$this->_brands = array_unique($this->_brands);
		$this->_categories = array_unique($this->_categories);

		sort($this->_products);
		sort($this->_brands);
		sort($this->_categories);

		// for now, don't need to store these - may need to store products when this is changed to supply ecommerce info
		unset($this->_data['customer']);
		unset($this->_data['products']);
	}