/** * Updates the status of the Order with the given ID * * If the order exists and has the pending status (status == 0), * it is updated according to the payment and distribution type. * Note that status other than pending are never changed! * If the optional argument $newOrderStatus is set and not pending, * the order status is set to that value instead. * Returns the new Order status on success. * If either the order ID is invalid, or if the update fails, returns * the Order status "pending" (zero). * @access private * @static * @param integer $order_id The ID of the current order * @param integer $newOrderStatus The optional new order status. * @param string $handler The Payment type name in use * @return integer The new order status (may be zero) * if the order status can be changed * accordingly, zero otherwise */ static function update_status($order_id, $newOrderStatus = 0, $handler = NULL) { global $objDatabase, $_ARRAYLANG; if (is_null($handler) && isset($_REQUEST['handler'])) { $handler = contrexx_input2raw($_REQUEST['handler']); } $order_id = intval($order_id); if ($order_id == 0) { return Order::STATUS_CANCELLED; } $query = "\n SELECT status, payment_id, shipment_id\n FROM " . DBPREFIX . "module_shop" . MODULE_INDEX . "_orders\n WHERE id={$order_id}"; $objResult = $objDatabase->Execute($query); if (!$objResult || $objResult->EOF) { return Order::STATUS_CANCELLED; } $status = $objResult->fields['status']; // Never change a non-pending status! // Whether a payment was successful or not, the status must be // left alone. if ($status != Order::STATUS_PENDING) { // The status of the order is not pending. // This may be due to a wrong order ID, a page reload, // or a PayPal IPN that has been received already. // No order status is changed automatically in these cases! // Leave it as it is. return $status; } // Determine and verify the payment handler $payment_id = $objResult->fields['payment_id']; //if (!$payment_id) DBG::log("update_status($order_id, $newOrderStatus): Failed to find Payment ID for Order ID $order_id"); $processor_id = Payment::getPaymentProcessorId($payment_id); //if (!$processor_id) DBG::log("update_status($order_id, $newOrderStatus): Failed to find Processor ID for Payment ID $payment_id"); $processorName = PaymentProcessing::getPaymentProcessorName($processor_id); //if (!$processorName) DBG::log("update_status($order_id, $newOrderStatus): Failed to find Processor Name for Processor ID $processor_id"); // The payment processor *MUST* match the handler returned. if (!preg_match("/^{$handler}/i", $processorName)) { //DBG::log("update_status($order_id, $newOrderStatus): Mismatching Handlers: Order $processorName, Request ".$_GET['handler']); return Order::STATUS_CANCELLED; } // Only if the optional new order status argument is zero, // determine the new status automatically. if ($newOrderStatus == Order::STATUS_PENDING) { // The new order status is determined by two properties: // - The method of payment (instant/deferred), and // - The method of delivery (if any). // If the payment takes place instantly (currently, all // external payments processors are considered to do so), // and there is no delivery needed (because it's all // downloads), the order status is switched to 'completed' // right away. // If only one of these conditions is met, the status is set to // 'paid', or 'delivered' respectively. // If neither condition is met, the status is set to 'confirmed'. $newOrderStatus = Order::STATUS_CONFIRMED; $processorType = PaymentProcessing::getCurrentPaymentProcessorType($processor_id); $shipmentId = $objResult->fields['shipment_id']; if ($processorType == 'external') { // External payment types are considered instant. // See $_SESSION['shop']['isInstantPayment']. if ($shipmentId == 0) { // instant, download -> completed $newOrderStatus = Order::STATUS_COMPLETED; } else { // There is a shipper, so this order will bedelivered. // See $_SESSION['shop']['isDelivery']. // instant, delivery -> paid $newOrderStatus = Order::STATUS_PAID; } } else { // Internal payment types are considered deferred. if ($shipmentId == 0) { // deferred, download -> shipped $newOrderStatus = Order::STATUS_SHIPPED; } //else { deferred, delivery -> confirmed } } } $query = "\n UPDATE " . DBPREFIX . "module_shop" . MODULE_INDEX . "_orders\n SET status='{$newOrderStatus}'\n WHERE id={$order_id}"; $objResult = $objDatabase->Execute($query); if (!$objResult) { // The query failed, but all the data is okay. // Don't cancel the order, leave it as it is and let the shop // manager handle this. Return pending status. return Order::STATUS_PENDING; } if ($newOrderStatus == Order::STATUS_CONFIRMED || $newOrderStatus == Order::STATUS_PAID || $newOrderStatus == Order::STATUS_SHIPPED || $newOrderStatus == Order::STATUS_COMPLETED) { if (!ShopLibrary::sendConfirmationMail($order_id)) { // Note that this message is only shown when the page is // displayed, which may be on another request! \Message::error($_ARRAYLANG['TXT_SHOP_UNABLE_TO_SEND_EMAIL']); } } // The shopping cart *MUST* be flushed right after this method // returns a true value (greater than zero). // If the new order status is zero however, the cart may // be left alone and the payment process can be tried again. return $newOrderStatus; }
/** * Processes the Order * * Verifies all data, updates and stores it in the database, and * initializes payment * @return boolean True on successs, false otherwise */ static function process() { global $objDatabase, $_ARRAYLANG; // FOR TESTING ONLY (repeatedly process/store the order, also disable self::destroyCart()) //$_SESSION['shop']['order_id'] = NULL; // Verify that the order hasn't yet been saved // (and has thus not yet been confirmed) if (isset($_SESSION['shop']['order_id'])) { return \Message::error($_ARRAYLANG['TXT_ORDER_ALREADY_PLACED']); } // No more confirmation self::$objTemplate->hideBlock('shopConfirm'); // Store the customer, register the order $customer_ip = $_SERVER['REMOTE_ADDR']; $customer_host = substr(@gethostbyaddr($_SERVER['REMOTE_ADDR']), 0, 100); $customer_browser = substr(getenv('HTTP_USER_AGENT'), 0, 100); $new_customer = false; //\DBG::log("Shop::process(): E-Mail: ".$_SESSION['shop']['email']); if (self::$objCustomer) { //\DBG::log("Shop::process(): Existing User username ".$_SESSION['shop']['username'].", email ".$_SESSION['shop']['email']); } else { // Registered Customers are required to be logged in! self::$objCustomer = Customer::getRegisteredByEmail($_SESSION['shop']['email']); if (self::$objCustomer) { \Message::error($_ARRAYLANG['TXT_SHOP_CUSTOMER_REGISTERED_EMAIL']); \Cx\Core\Csrf\Controller\Csrf::redirect(\Cx\Core\Routing\Url::fromModuleAndCmd('Shop', 'login') . '?redirect=' . base64_encode(\Cx\Core\Routing\Url::fromModuleAndCmd('Shop', 'confirm'))); } // Unregistered Customers are stored as well, as their information is needed // nevertheless. Their active status, however, is set to false. self::$objCustomer = Customer::getUnregisteredByEmail($_SESSION['shop']['email']); if (!self::$objCustomer) { self::$objCustomer = new Customer(); // Currently, the e-mail address is set as the user name $_SESSION['shop']['username'] = $_SESSION['shop']['email']; //\DBG::log("Shop::process(): New User username ".$_SESSION['shop']['username'].", email ".$_SESSION['shop']['email']); self::$objCustomer->username($_SESSION['shop']['username']); self::$objCustomer->email($_SESSION['shop']['email']); // Note that the password is unset when the Customer chooses // to order without registration. The generated one // defaults to length 8, fulfilling the requirements for // complex passwords. And it's kept absolutely secret. $password = empty($_SESSION['shop']['password']) ? \User::make_password() : $_SESSION['shop']['password']; //\DBG::log("Password: $password (session: {$_SESSION['shop']['password']})"); if (!self::$objCustomer->password($password)) { \Message::error($_ARRAYLANG['TXT_INVALID_PASSWORD']); \Cx\Core\Csrf\Controller\Csrf::redirect(\Cx\Core\Routing\Url::fromModuleAndCmd('Shop', 'account')); } self::$objCustomer->active(empty($_SESSION['shop']['dont_register'])); $new_customer = true; } } // Update the Customer object from the session array // (whether new or not -- it may have been edited) self::$objCustomer->gender($_SESSION['shop']['gender']); self::$objCustomer->firstname($_SESSION['shop']['firstname']); self::$objCustomer->lastname($_SESSION['shop']['lastname']); self::$objCustomer->company($_SESSION['shop']['company']); self::$objCustomer->address($_SESSION['shop']['address']); self::$objCustomer->city($_SESSION['shop']['city']); self::$objCustomer->zip($_SESSION['shop']['zip']); self::$objCustomer->country_id($_SESSION['shop']['countryId']); self::$objCustomer->phone($_SESSION['shop']['phone']); self::$objCustomer->fax($_SESSION['shop']['fax']); $arrGroups = self::$objCustomer->getAssociatedGroupIds(); $usergroup_id = \Cx\Core\Setting\Controller\Setting::getValue('usergroup_id_reseller', 'Shop'); if (empty($usergroup_id)) { //\DBG::log("Shop::process(): ERROR: Missing reseller group"); \Message::error($_ARRAYLANG['TXT_SHOP_ERROR_USERGROUP_INVALID']); \Cx\Core\Csrf\Controller\Csrf::redirect(\Cx\Core\Routing\Url::fromModuleAndCmd('Shop', '')); } if (!in_array($usergroup_id, $arrGroups)) { //\DBG::log("Shop::process(): Customer is not in Reseller group (ID $usergroup_id)"); // Not a reseller. See if she's a final customer $usergroup_id = \Cx\Core\Setting\Controller\Setting::getValue('usergroup_id_customer', 'Shop'); if (empty($usergroup_id)) { //\DBG::log("Shop::process(): ERROR: Missing final customer group"); \Message::error($_ARRAYLANG['TXT_SHOP_ERROR_USERGROUP_INVALID']); \Cx\Core\Csrf\Controller\Csrf::redirect(\Cx\Core\Routing\Url::fromModuleAndCmd('Shop', '')); } if (!in_array($usergroup_id, $arrGroups)) { //\DBG::log("Shop::process(): Customer is not in final customer group (ID $usergroup_id), either"); // Neither one, add to the final customer group (default) $arrGroups[] = $usergroup_id; self::$objCustomer->setGroups($arrGroups); //\DBG::log("Shop::process(): Added Customer to final customer group (ID $usergroup_id): ".var_export(self::$objCustomer->getAssociatedGroupIds(), true)); } else { //\DBG::log("Shop::process(): Customer is a final customer (ID $usergroup_id) already: ".var_export(self::$objCustomer->getAssociatedGroupIds(), true)); } } else { //\DBG::log("Shop::process(): Customer is a Reseller (ID $usergroup_id) already: ".var_export(self::$objCustomer->getAssociatedGroupIds(), true)); } // Insert or update the customer //\DBG::log("Shop::process(): Storing Customer: ".var_export(self::$objCustomer, true)); if (!self::$objCustomer->store()) { return \Message::error($_ARRAYLANG['TXT_SHOP_CUSTOMER_ERROR_STORING']); } // Authenticate new Customer if ($new_customer) { // Fails for "unregistered" Customers! if (self::$objCustomer->auth($_SESSION['shop']['username'], $_SESSION['shop']['password'], false, true)) { if (!self::_authenticate()) { return \Message::error($_ARRAYLANG['TXT_SHOP_CUSTOMER_ERROR_STORING']); } } } //die(); // Clear the ship-to country if there is no shipping if (!Cart::needs_shipment()) { $_SESSION['shop']['countryId2'] = 0; } $shipper_id = empty($_SESSION['shop']['shipperId']) ? null : $_SESSION['shop']['shipperId']; $payment_id = empty($_SESSION['shop']['paymentId']) ? null : $_SESSION['shop']['paymentId']; $objOrder = new Order(); $objOrder->customer_id(self::$objCustomer->id()); $objOrder->billing_gender($_SESSION['shop']['gender']); $objOrder->billing_firstname($_SESSION['shop']['firstname']); $objOrder->billing_lastname($_SESSION['shop']['lastname']); $objOrder->billing_company($_SESSION['shop']['company']); $objOrder->billing_address($_SESSION['shop']['address']); $objOrder->billing_city($_SESSION['shop']['city']); $objOrder->billing_zip($_SESSION['shop']['zip']); $objOrder->billing_country_id($_SESSION['shop']['countryId']); $objOrder->billing_phone($_SESSION['shop']['phone']); $objOrder->billing_fax($_SESSION['shop']['fax']); $objOrder->billing_email($_SESSION['shop']['email']); $objOrder->currency_id($_SESSION['shop']['currencyId']); $objOrder->sum($_SESSION['shop']['grand_total_price']); $objOrder->date_time(date(ASCMS_DATE_FORMAT_INTERNATIONAL_DATETIME)); $objOrder->status(0); $objOrder->company($_SESSION['shop']['company2']); $objOrder->gender($_SESSION['shop']['gender2']); $objOrder->firstname($_SESSION['shop']['firstname2']); $objOrder->lastname($_SESSION['shop']['lastname2']); $objOrder->address($_SESSION['shop']['address2']); $objOrder->city($_SESSION['shop']['city2']); $objOrder->zip($_SESSION['shop']['zip2']); $objOrder->country_id($_SESSION['shop']['countryId2']); $objOrder->phone($_SESSION['shop']['phone2']); $objOrder->vat_amount($_SESSION['shop']['vat_price']); $objOrder->shipment_amount($_SESSION['shop']['shipment_price']); $objOrder->shipment_id($shipper_id); $objOrder->payment_id($payment_id); $objOrder->payment_amount($_SESSION['shop']['payment_price']); $objOrder->ip($customer_ip); $objOrder->host($customer_host); $objOrder->lang_id(FRONTEND_LANG_ID); $objOrder->browser($customer_browser); $objOrder->note($_SESSION['shop']['note']); if (!$objOrder->insert()) { // $order_id is unset! return \Message::error($_ARRAYLANG['TXT_SHOP_ORDER_ERROR_STORING']); } $order_id = $objOrder->id(); $_SESSION['shop']['order_id'] = $order_id; // The products will be tested one by one below. // If any single one of them requires delivery, this // flag will be set to true. // This is used to determine the order status at the // end of the shopping process. $_SESSION['shop']['isDelivery'] = false; // Try to redeem the Coupon, if any $coupon_code = isset($_SESSION['shop']['coupon_code']) ? $_SESSION['shop']['coupon_code'] : null; //\DBG::log("Cart::update(): Coupon Code: $coupon_code"); $items_total = 0; // Suppress Coupon messages (see Coupon::available()) \Message::save(); foreach (Cart::get_products_array() as $arrProduct) { $objProduct = Product::getById($arrProduct['id']); if (!$objProduct) { unset($_SESSION['shop']['order_id']); return \Message::error($_ARRAYLANG['TXT_ERROR_LOOKING_UP_ORDER']); } $product_id = $arrProduct['id']; $name = $objProduct->name(); $priceOptions = !empty($arrProduct['optionPrice']) ? $arrProduct['optionPrice'] : 0; $quantity = $arrProduct['quantity']; $price = $objProduct->get_custom_price(self::$objCustomer, $priceOptions, $quantity); $item_total = $price * $quantity; $items_total += $item_total; $productVatId = $objProduct->vat_id(); $vat_rate = $productVatId && Vat::getRate($productVatId) ? Vat::getRate($productVatId) : '0.00'; // Test the distribution method for delivery $productDistribution = $objProduct->distribution(); if ($productDistribution == 'delivery') { $_SESSION['shop']['isDelivery'] = true; } $weight = $productDistribution == 'delivery' ? $objProduct->weight() : 0; // grams if ($weight == '') { $weight = 0; } // Add to order items table $result = $objOrder->insertItem($order_id, $product_id, $name, $price, $quantity, $vat_rate, $weight, $arrProduct['options']); if (!$result) { unset($_SESSION['shop']['order_id']); // TODO: Verify error message set by Order::insertItem() return false; } // Store the Product Coupon, if applicable. // Note that it is not redeemed yet (uses=0)! if ($coupon_code) { $objCoupon = Coupon::available($coupon_code, $item_total, self::$objCustomer->id(), $product_id, $payment_id); if ($objCoupon) { //\DBG::log("Shop::process(): Got Coupon for Product ID $product_id: ".var_export($objCoupon, true)); if (!$objCoupon->redeem($order_id, self::$objCustomer->id(), $price * $quantity, 0)) { // TODO: Do something if the Coupon does not work \DBG::log("Shop::process(): ERROR: Failed to store Coupon for Product ID {$product_id}"); } $coupon_code = null; } } } // foreach product in cart // Store the Global Coupon, if applicable. // Note that it is not redeemed yet (uses=0)! //\DBG::log("Shop::process(): Looking for global Coupon $coupon_code"); if ($coupon_code) { $objCoupon = Coupon::available($coupon_code, $items_total, self::$objCustomer->id(), null, $payment_id); if ($objCoupon) { //\DBG::log("Shop::process(): Got global Coupon: ".var_export($objCoupon, true)); if (!$objCoupon->redeem($order_id, self::$objCustomer->id(), $items_total, 0)) { \DBG::log("Shop::process(): ERROR: Failed to store global Coupon"); } } } \Message::restore(); $processor_id = Payment::getProperty($_SESSION['shop']['paymentId'], 'processor_id'); $processor_name = PaymentProcessing::getPaymentProcessorName($processor_id); // other payment methods PaymentProcessing::initProcessor($processor_id); // TODO: These arguments are no longer valid. Set them up later? // Currency::getActiveCurrencyCode(), // FWLanguage::getLanguageParameter(FRONTEND_LANG_ID, 'lang')); // if the processor is Internal_LSV, and there is account information, // store the information. if ($processor_name == 'internal_lsv') { if (!self::lsv_complete()) { // Missing mandatory data; return to payment unset($_SESSION['shop']['order_id']); \Message::error($_ARRAYLANG['TXT_ERROR_ACCOUNT_INFORMATION_NOT_AVAILABLE']); \Cx\Core\Csrf\Controller\Csrf::redirect(\Cx\Core\Routing\Url::fromModuleAndCmd('Shop', 'payment')); } $query = "\n INSERT INTO " . DBPREFIX . "module_shop" . MODULE_INDEX . "_lsv (\n order_id, holder, bank, blz\n ) VALUES (\n {$order_id},\n '" . contrexx_raw2db($_SESSION['shop']['account_holder']) . "',\n '" . contrexx_raw2db($_SESSION['shop']['account_bank']) . "',\n '" . contrexx_raw2db($_SESSION['shop']['account_blz']) . "'\n )"; $objResult = $objDatabase->Execute($query); if (!$objResult) { // Return to payment unset($_SESSION['shop']['order_id']); \Message::error($_ARRAYLANG['TXT_ERROR_INSERTING_ACCOUNT_INFORMATION']); \Cx\Core\Csrf\Controller\Csrf::redirect(\Cx\Core\Routing\Url::fromModuleAndCmd('Shop', 'payment')); } } $_SESSION['shop']['order_id_checkin'] = $order_id; $strProcessorType = PaymentProcessing::getCurrentPaymentProcessorType(); // Test whether the selected payment method can be // considered an instant or deferred one. // This is used to set the order status at the end // of the shopping process. // TODO: Invert this flag, as it may no longer be present after paying // online using one of the external payment methods! Ensure that it is set // instead when paying "deferred". $_SESSION['shop']['isInstantPayment'] = false; if ($strProcessorType == 'external') { // For the sake of simplicity, all external payment // methods are considered to be 'instant'. // All currently implemented internal methods require // further action from the merchant, and thus are // considered to be 'deferred'. $_SESSION['shop']['isInstantPayment'] = true; } // Send the Customer login separately, as the password possibly // won't be available later if (!empty($_SESSION['shop']['password'])) { self::sendLogin(self::$objCustomer->email(), $_SESSION['shop']['password']); } // Show payment processing page. // Note that some internal payments are redirected away // from this page in checkOut(): // 'internal', 'internal_lsv' self::$objTemplate->setVariable('SHOP_PAYMENT_PROCESSING', PaymentProcessing::checkOut()); // Clear the order ID. // The order may be resubmitted and the payment retried. unset($_SESSION['shop']['order_id']); // Custom. // Enable if Discount class is customized and in use. //self::showCustomerDiscount(Cart::get_price()); return true; }
/** * Set up the detail view of the selected order * @access public * @param \Cx\Core\Html\Sigma $objTemplate The Template, by reference * @param boolean $edit Edit if true, view otherwise * @global ADONewConnection $objDatabase Database connection object * @global array $_ARRAYLANG Language array * @return boolean True on success, * false otherwise * @static * @author Reto Kohli <*****@*****.**> (parts) * @version 3.1.0 */ static function view_detail(&$objTemplate = null, $edit = false) { global $objDatabase, $_ARRAYLANG, $objInit; $backend = $objInit->mode == 'backend'; if ($objTemplate->blockExists('order_list')) { $objTemplate->hideBlock('order_list'); } $have_option = false; // The order total -- in the currency chosen by the customer $order_sum = 0; // recalculated VAT total $total_vat_amount = 0; $order_id = intval($_REQUEST['order_id']); if (!$order_id) { return \Message::error($_ARRAYLANG['TXT_SHOP_ORDER_ERROR_INVALID_ORDER_ID']); } if (!$objTemplate) { $template_name = $edit ? 'module_shop_order_edit.html' : 'module_shop_order_details.html'; $objTemplate = new \Cx\Core\Html\Sigma(\Cx\Core\Core\Controller\Cx::instanciate()->getCodeBaseModulePath() . '/Shop/View/Template/Backend'); //DBG::log("Orders::view_list(): new Template: ".$objTemplate->get()); $objTemplate->loadTemplateFile($template_name); //DBG::log("Orders::view_list(): loaded Template: ".$objTemplate->get()); } $objOrder = Order::getById($order_id); if (!$objOrder) { //DBG::log("Shop::shopShowOrderdetails(): Failed to find Order ID $order_id"); return \Message::error(sprintf($_ARRAYLANG['TXT_SHOP_ORDER_NOT_FOUND'], $order_id)); } // lsv data $query = "\n SELECT `holder`, `bank`, `blz`\n FROM " . DBPREFIX . "module_shop" . MODULE_INDEX . "_lsv\n WHERE order_id={$order_id}"; $objResult = $objDatabase->Execute($query); if (!$objResult) { return self::errorHandler(); } if ($objResult->RecordCount() == 1) { $objTemplate->setVariable(array('SHOP_ACCOUNT_HOLDER' => contrexx_raw2xhtml($objResult->fields['holder']), 'SHOP_ACCOUNT_BANK' => contrexx_raw2xhtml($objResult->fields['bank']), 'SHOP_ACCOUNT_BLZ' => contrexx_raw2xhtml($objResult->fields['blz']))); } $customer_id = $objOrder->customer_id(); if (!$customer_id) { //DBG::log("Shop::shopShowOrderdetails(): Invalid Customer ID $customer_id"); \Message::error(sprintf($_ARRAYLANG['TXT_SHOP_INVALID_CUSTOMER_ID'], $customer_id)); } $objCustomer = Customer::getById($customer_id); if (!$objCustomer) { //DBG::log("Shop::shopShowOrderdetails(): Failed to find Customer ID $customer_id"); \Message::error(sprintf($_ARRAYLANG['TXT_SHOP_CUSTOMER_NOT_FOUND'], $customer_id)); $objCustomer = new Customer(); // No editing allowed! $have_option = true; } Vat::is_reseller($objCustomer->is_reseller()); Vat::is_home_country(\Cx\Core\Setting\Controller\Setting::getValue('country_id', 'Shop') == $objOrder->country_id()); $objTemplate->setGlobalVariable($_ARRAYLANG + array('SHOP_CURRENCY' => Currency::getCurrencySymbolById($objOrder->currency_id()))); //DBG::log("Order sum: ".Currency::formatPrice($objOrder->sum())); $objTemplate->setVariable(array('SHOP_CUSTOMER_ID' => $customer_id, 'SHOP_ORDERID' => $order_id, 'SHOP_DATE' => date(ASCMS_DATE_FORMAT_INTERNATIONAL_DATETIME, strtotime($objOrder->date_time())), 'SHOP_ORDER_STATUS' => $edit ? Orders::getStatusMenu($objOrder->status(), false, null, 'swapSendToStatus(this.value)') : $_ARRAYLANG['TXT_SHOP_ORDER_STATUS_' . $objOrder->status()], 'SHOP_SEND_MAIL_STYLE' => $objOrder->status() == Order::STATUS_CONFIRMED ? 'display: inline;' : 'display: none;', 'SHOP_SEND_MAIL_STATUS' => $edit ? $objOrder->status() != Order::STATUS_CONFIRMED ? \Html::ATTRIBUTE_CHECKED : '' : '', 'SHOP_ORDER_SUM' => Currency::formatPrice($objOrder->sum()), 'SHOP_DEFAULT_CURRENCY' => Currency::getDefaultCurrencySymbol(), 'SHOP_GENDER' => $edit ? Customer::getGenderMenu($objOrder->billing_gender(), 'billing_gender') : $_ARRAYLANG['TXT_SHOP_' . strtoupper($objOrder->billing_gender())], 'SHOP_COMPANY' => $objOrder->billing_company(), 'SHOP_FIRSTNAME' => $objOrder->billing_firstname(), 'SHOP_LASTNAME' => $objOrder->billing_lastname(), 'SHOP_ADDRESS' => $objOrder->billing_address(), 'SHOP_ZIP' => $objOrder->billing_zip(), 'SHOP_CITY' => $objOrder->billing_city(), 'SHOP_COUNTRY' => $edit ? \Cx\Core\Country\Controller\Country::getMenu('billing_country_id', $objOrder->billing_country_id()) : \Cx\Core\Country\Controller\Country::getNameById($objOrder->billing_country_id()), 'SHOP_PHONE' => $objOrder->billing_phone(), 'SHOP_FAX' => $objOrder->billing_fax(), 'SHOP_EMAIL' => $objOrder->billing_email(), 'SHOP_SHIP_GENDER' => $edit ? Customer::getGenderMenu($objOrder->gender(), 'shipPrefix') : $_ARRAYLANG['TXT_SHOP_' . strtoupper($objOrder->gender())], 'SHOP_SHIP_COMPANY' => $objOrder->company(), 'SHOP_SHIP_FIRSTNAME' => $objOrder->firstname(), 'SHOP_SHIP_LASTNAME' => $objOrder->lastname(), 'SHOP_SHIP_ADDRESS' => $objOrder->address(), 'SHOP_SHIP_ZIP' => $objOrder->zip(), 'SHOP_SHIP_CITY' => $objOrder->city(), 'SHOP_SHIP_COUNTRY' => $edit ? \Cx\Core\Country\Controller\Country::getMenu('shipCountry', $objOrder->country_id()) : \Cx\Core\Country\Controller\Country::getNameById($objOrder->country_id()), 'SHOP_SHIP_PHONE' => $objOrder->phone(), 'SHOP_PAYMENTTYPE' => Payment::getProperty($objOrder->payment_id(), 'name'), 'SHOP_CUSTOMER_NOTE' => $objOrder->note(), 'SHOP_COMPANY_NOTE' => $objCustomer->companynote(), 'SHOP_SHIPPING_TYPE' => $objOrder->shipment_id() ? Shipment::getShipperName($objOrder->shipment_id()) : ' ')); if ($backend) { $objTemplate->setVariable(array('SHOP_CUSTOMER_IP' => $objOrder->ip() ? '<a href="index.php?cmd=NetTools&tpl=whois&address=' . $objOrder->ip() . '" title="' . $_ARRAYLANG['TXT_SHOW_DETAILS'] . '">' . $objOrder->ip() . '</a>' : ' ', 'SHOP_CUSTOMER_HOST' => $objOrder->host() ? '<a href="index.php?cmd=NetTools&tpl=whois&address=' . $objOrder->host() . '" title="' . $_ARRAYLANG['TXT_SHOW_DETAILS'] . '">' . $objOrder->host() . '</a>' : ' ', 'SHOP_CUSTOMER_LANG' => \FWLanguage::getLanguageParameter($objOrder->lang_id(), 'name'), 'SHOP_CUSTOMER_BROWSER' => $objOrder->browser() ? $objOrder->browser() : ' ', 'SHOP_LAST_MODIFIED' => $objOrder->modified_on() && $objOrder->modified_on() != '0000-00-00 00:00:00' ? $objOrder->modified_on() . ' ' . $_ARRAYLANG['TXT_EDITED_BY'] . ' ' . $objOrder->modified_by() : $_ARRAYLANG['TXT_ORDER_WASNT_YET_EDITED'])); } else { // Frontend: Order history ONLY. Repeat the Order, go to cart $objTemplate->setVariable(array('SHOP_ACTION_URI_ENCODED' => \Cx\Core\Routing\Url::fromModuleAndCmd('Shop', 'cart'))); } $ppName = ''; $psp_id = Payment::getPaymentProcessorId($objOrder->payment_id()); if ($psp_id) { $ppName = PaymentProcessing::getPaymentProcessorName($psp_id); } $objTemplate->setVariable(array('SHOP_SHIPPING_PRICE' => $objOrder->shipment_amount(), 'SHOP_PAYMENT_PRICE' => $objOrder->payment_amount(), 'SHOP_PAYMENT_HANDLER' => $ppName, 'SHOP_LAST_MODIFIED_DATE' => $objOrder->modified_on())); if ($edit) { // edit order $strJsArrShipment = Shipment::getJSArrays(); $objTemplate->setVariable(array('SHOP_SEND_TEMPLATE_TO_CUSTOMER' => sprintf($_ARRAYLANG['TXT_SEND_TEMPLATE_TO_CUSTOMER'], $_ARRAYLANG['TXT_ORDER_COMPLETE']), 'SHOP_SHIPPING_TYP_MENU' => Shipment::getShipperMenu($objOrder->country_id(), $objOrder->shipment_id(), "calcPrice(0);"), 'SHOP_JS_ARR_SHIPMENT' => $strJsArrShipment, 'SHOP_PRODUCT_IDS_MENU_NEW' => Products::getMenuoptions(null, null, $_ARRAYLANG['TXT_SHOP_PRODUCT_MENU_FORMAT']), 'SHOP_JS_ARR_PRODUCT' => Products::getJavascriptArray($objCustomer->group_id(), $objCustomer->is_reseller()))); } $options = $objOrder->getOptionArray(); if (!empty($options[$order_id])) { $have_option = true; } // Order items $total_weight = $i = 0; $total_net_price = $objOrder->view_items($objTemplate, $edit, $total_weight, $i); // Show VAT with the individual products: // If VAT is enabled, and we're both in the same country // ($total_vat_amount has been set above if both conditions are met) // show the VAT rate. // If there is no VAT, the amount is 0 (zero). //if ($total_vat_amount) { // distinguish between included VAT, and additional VAT added to sum $tax_part_percentaged = Vat::isIncluded() ? $_ARRAYLANG['TXT_TAX_PREFIX_INCL'] : $_ARRAYLANG['TXT_TAX_PREFIX_EXCL']; $objTemplate->setVariable(array('SHOP_TAX_PRICE' => Currency::formatPrice($total_vat_amount), 'SHOP_PART_TAX_PROCENTUAL' => $tax_part_percentaged)); //} else { // No VAT otherwise // remove it from the details overview if empty //$objTemplate->hideBlock('taxprice'); //$tax_part_percentaged = $_ARRAYLANG['TXT_NO_TAX']; //} // Parse Coupon if applicable to this product // Coupon $objCoupon = Coupon::getByOrderId($order_id); if ($objCoupon) { $discount = $objCoupon->discount_amount() != 0 ? $objCoupon->discount_amount() : $total_net_price / 100 * $objCoupon->discount_rate(); $objTemplate->setVariable(array('SHOP_COUPON_NAME' => $_ARRAYLANG['TXT_SHOP_DISCOUNT_COUPON_CODE'], 'SHOP_COUPON_CODE' => $objCoupon->code(), 'SHOP_COUPON_AMOUNT' => Currency::formatPrice(-$discount))); $total_net_price -= $discount; //DBG::log("Order::view_detail(): Coupon: ".var_export($objCoupon, true)); } $objTemplate->setVariable(array('SHOP_ROWCLASS_NEW' => 'row' . (++$i % 2 + 1), 'SHOP_TOTAL_WEIGHT' => Weight::getWeightString($total_weight), 'SHOP_NET_PRICE' => Currency::formatPrice($total_net_price))); $objTemplate->setVariable(array('TXT_PRODUCT_ID' => $_ARRAYLANG['TXT_ID'], 'TXT_TAX_RATE' => Vat::isIncluded() ? $_ARRAYLANG['TXT_TAX_PREFIX_INCL'] : $_ARRAYLANG['TXT_TAX_PREFIX_EXCL'], 'TXT_SHOP_ACCOUNT_VALIDITY' => $_ARRAYLANG['TXT_SHOP_VALIDITY'])); // Disable the "edit" button when there are Attributes if ($backend && !$edit) { if ($have_option) { if ($objTemplate->blockExists('order_no_edit')) { $objTemplate->touchBlock('order_no_edit'); } } else { if ($objTemplate->blockExists('order_edit')) { $objTemplate->touchBlock('order_edit'); } } } return true; }