Index: branches/5.3.x/units/orders/orders_tag_processor.php =================================================================== diff -u -r15925 -r16398 --- branches/5.3.x/units/orders/orders_tag_processor.php (.../orders_tag_processor.php) (revision 15925) +++ branches/5.3.x/units/orders/orders_tag_processor.php (.../orders_tag_processor.php) (revision 16398) @@ -1,6 +1,6 @@ Application->HREF($this->Application->GetVar('t'), '', Array('pass' => 'm,orditems,ord', 'ord_event' => 'OnRemoveFromCart', 'm_cat_id'=>0)); + $params['m_cat_id'] = 0; + $params['ord_event'] = 'OnRemoveFromCart'; + + if ( !isset($params['pass']) ) { + $params['pass'] = 'm,orditems,ord'; + } + + // Remove parameters, that indicate from where this aggregated tag was called. + unset($params['PrefixSpecial'], $params['original_tag']); + + return $this->Application->ProcessParsedTag('m', 'Link', $params); } function Orderitems_ProductLink($params) @@ -516,29 +526,58 @@ } /** - * Returns true in case if credit card was used as payment type for order + * Returns true in case if credit card was used as payment type for order. * - * @param Array $params - * @return bool + * @param array $params Tag params. + * + * @return boolean + * @throws Exception When payment type not found. */ - function UsingCreditCard($params) + protected function UsingCreditCard(array $params) { + static $payment_types; + + if ( !isset($payment_types) ) { + $pt_table = $this->Application->getUnitConfig('pt')->getTableName(); + $sql = 'SELECT g.RequireCCFields, pt.PaymentTypeId + FROM ' . $pt_table . ' pt + JOIN ' . TABLE_PREFIX . 'Gateways g ON g.GatewayId = pt.GatewayId'; + + $payment_types = $this->Conn->GetCol($sql, 'PaymentTypeId'); + } + + /** @var kDBItem $object */ $object = $this->getObject($params); + $payment_type = $object->GetDBField('PaymentType'); - $pt = $object->GetDBField('PaymentType'); + if ( !$payment_type ) { + $payment_type = $this->getPrimaryPaymentType(); + $object->SetDBField('PaymentType', $payment_type); + } - if (!$pt) { - $pt = $this->Conn->GetOne('SELECT PaymentTypeId FROM '.TABLE_PREFIX.'PaymentTypes WHERE IsPrimary = 1'); - $object->SetDBField('PaymentType', $pt); + if ( !isset($payment_types[$payment_type]) ) { + throw new Exception('Unknown payment type: ' . $payment_type); } - $pt_table = $this->Application->getUnitConfig('pt')->getTableName(); - $sql = 'SELECT GatewayId FROM %s WHERE PaymentTypeId = %s'; - $gw_id = $this->Conn->GetOne( sprintf( $sql, $pt_table, $pt ) ); + return $payment_types[$payment_type]; + } - $sql = 'SELECT RequireCCFields FROM %s WHERE GatewayId = %s'; + /** + * Get primary payment type. + * + * @return string + */ + protected function getPrimaryPaymentType() + { + static $primary_payment_type; - return $this->Conn->GetOne( sprintf($sql, TABLE_PREFIX.'Gateways', $gw_id) ); + if ( !isset($primary_payment_type) ) { + $pt_table = $this->Application->getUnitConfig('pt')->getTableName(); + $sql = 'SELECT PaymentTypeId FROM ' . $pt_table . ' WHERE IsPrimary = 1'; + $primary_payment_type = $this->Conn->GetOne($sql); + } + + return $primary_payment_type; } function PaymentTypeDescription($params) @@ -1075,10 +1114,9 @@ /* @var $object OrdersItem */ $gw_data = $object->getGatewayData( isset($params['payment_type_id']) ? $params['payment_type_id'] : null ); - $this->Application->registerClass( $gw_data['ClassName'], GW_CLASS_PATH.'/'.$gw_data['ClassFile'] ); - $gateway_object = $this->Application->recallObject( $gw_data['ClassName'] ); - /* @var $gateway_object kGWBase */ + /** @var kGWBase $gateway_object */ + $gateway_object = $this->Application->recallObject($gw_data['ClassName']); return $gateway_object->getFormAction($gw_data['gw_params']); } @@ -1089,10 +1127,9 @@ /* @var $object OrdersItem */ $gw_data = $object->getGatewayData( isset($params['payment_type_id']) ? $params['payment_type_id'] : null ); - $this->Application->registerClass( $gw_data['ClassName'], GW_CLASS_PATH.'/'.$gw_data['ClassFile'] ); - $gateway_object = $this->Application->recallObject( $gw_data['ClassName'] ); - /* @var $gateway_object kGWBase */ + /** @var kGWBase $gateway_object */ + $gateway_object = $this->Application->recallObject($gw_data['ClassName']); $tpl = ''."\n"; $hidden_fields = $gateway_object->getHiddenFields($object->GetFieldValues(), $params, $gw_data['gw_params']); @@ -1116,10 +1153,9 @@ /* @var $object OrdersItem */ $gw_data = $object->getGatewayData( isset($params['payment_type_id']) ? $params['payment_type_id'] : null ); - $this->Application->registerClass( $gw_data['ClassName'], GW_CLASS_PATH.'/'.$gw_data['ClassFile'] ); - $gateway_object = $this->Application->recallObject( $gw_data['ClassName'] ); - /* @var $gateway_object kGWBase */ + /** @var kGWBase $gateway_object */ + $gateway_object = $this->Application->recallObject($gw_data['ClassName']); return $gateway_object->NeedPlaceButton($object->GetFieldValues(), $params, $gw_data['gw_params']); } @@ -1358,10 +1394,9 @@ $object = $this->getObject($params); $gw_data = $object->getGatewayData($params['payment_type_id']); - $this->Application->registerClass( $gw_data['ClassName'], GW_CLASS_PATH.'/'.$gw_data['ClassFile'] ); - $gateway_object = $this->Application->recallObject( $gw_data['ClassName'] ); + /** @var kGWBase $gateway_object */ + $gateway_object = $this->Application->recallObject($gw_data['ClassName']); - $sql = 'SELECT oi.* FROM '.TABLE_PREFIX.'OrderItems oi LEFT JOIN '.TABLE_PREFIX.'Products p ON p.ProductId = oi.ProductId @@ -1436,14 +1471,18 @@ */ function RemoveCouponLink($params) { - $type = strtolower($params['type']); - $url_params = Array ( - 'pass' => 'm,ord', - 'ord_event' => ($type == 'coupon') ? 'OnRemoveCoupon' : 'OnRemoveGiftCertificate', - 'm_cat_id' => 0, - ); + if ( !isset($params['pass']) ) { + $params['pass'] = 'm,ord'; + } - return $this->Application->HREF('', '', $url_params); + $params['m_cat_id'] = 0; + + $link_type = $params['type']; + unset($params['type']); + + $params['ord_event'] = strtolower($link_type) == 'coupon' ? 'OnRemoveCoupon' : 'OnRemoveGiftCertificate'; + + return $this->ItemLink($params); } /** @@ -1656,4 +1695,4 @@ return true; } - } \ No newline at end of file + } Index: branches/5.3.x/units/order_items/order_items_tag_processor.php =================================================================== diff -u -r16106 -r16398 --- branches/5.3.x/units/order_items/order_items_tag_processor.php (.../order_items_tag_processor.php) (revision 16106) +++ branches/5.3.x/units/order_items/order_items_tag_processor.php (.../order_items_tag_processor.php) (revision 16398) @@ -1,6 +1,6 @@ GetID(); $product_id_get = $this->Application->GetVar('p_id'); + $category_id_backup = $this->Application->GetVar('m_cat_id'); while (!$list->EOL()) { // load product used in orderitem @@ -248,6 +249,7 @@ // restore IDs used in cycle $this->Application->SetVar('p_id', $product_id_get); + $this->Application->SetVar('m_cat_id', $category_id_backup); $this->Application->DeleteVar($this->getPrefixSpecial() . '_id'); if ( $product_id ) { Index: branches/5.3.x/units/products/products_tag_processor.php =================================================================== diff -u -r15971 -r16398 --- branches/5.3.x/units/products/products_tag_processor.php (.../products_tag_processor.php) (revision 15971) +++ branches/5.3.x/units/products/products_tag_processor.php (.../products_tag_processor.php) (revision 16398) @@ -1,6 +1,6 @@ Application->GetSID().'_'.TABLE_PREFIX.'Search'; + /** @var kSearchHelper $search_helper */ + $search_helper = $this->Application->recallObject('SearchHelper'); + $sql = ' SELECT COUNT(ResourceId) - FROM '.$search_results_table.' + FROM ' . $search_helper->getSearchTable() . ' WHERE ItemType=11'; + return $this->Conn->GetOne($sql); } @@ -482,10 +485,9 @@ function PrepareSearchResults($params) { - $names_mapping = $this->Application->GetVar('NamesToSpecialMapping', Array ()); - - if($this->Application->GetVar('search_type') == 'advanced' || !getArrayValue($names_mapping, $this->Prefix, 'search_results')) - { + if ( $this->Application->GetVar('search_type') == 'advanced' + || !getArrayValue($this->nameToSpecialMapping, 'search_results') + ) { $params = Array('list_name' => 'search_results', 'types' => 'search', 'parent_cat_id' => 'any', @@ -858,4 +860,4 @@ return $url; } -} \ No newline at end of file +} Index: branches/5.3.x/units/orders/orders_config.php =================================================================== diff -u -r16392 -r16398 --- branches/5.3.x/units/orders/orders_config.php (.../orders_config.php) (revision 16392) +++ branches/5.3.x/units/orders/orders_config.php (.../orders_config.php) (revision 16398) @@ -1,6 +1,6 @@ hAFTER, 'Conditional' => false, 'HookToPrefix' => 'u', - 'HookToSpecial' => '', + 'HookToSpecial' => '*', 'HookToEvent' => Array ( 'OnCreate' ), 'DoPrefix' => '', - 'DoSpecial' => '', + 'DoSpecial' => '*', 'DoEvent' => 'OnUserCreate', ), @@ -116,6 +116,16 @@ 'DoSpecial' => '', 'DoEvent' => 'OnRestoreOrder', ), + array( + 'Mode' => hAFTER, + 'Conditional' => false, + 'HookToPrefix' => 'conf', + 'HookToSpecial' => '', + 'HookToEvent' => array('OnBeforeItemValidate'), + 'DoPrefix' => '', + 'DoSpecial' => '', + 'DoEvent' => 'OnBeforeNextOrderNumberChange', + ), ), 'AggregateTags' => Array ( @@ -254,11 +264,11 @@ '' => Array ( 'CustomerName' => 'IF( ISNULL(u.Username), IF (%1$s.PortalUserId = ' . USER_ROOT . ', "root", IF (%1$s.PortalUserId = ' . USER_GUEST . ', "Guest", "n/a")), CONCAT(u.FirstName," ",u.LastName) )', 'Username' => 'IF( ISNULL(u.Username),"root",IF(u.Username = "", u.Email, u.Username))', - 'OrderNumber' => 'CONCAT(LPAD(Number,6,"0"),\'-\',LPAD(SubNumber,3,"0") )', - 'SubtotalWithoutDiscount' => '(SubTotal + DiscountTotal)', - 'SubtotalWithDiscount' => '(SubTotal)', - 'AmountWithoutVAT' => '(SubTotal+IF(ShippingTaxable=1, ShippingCost, 0)+IF(ProcessingTaxable=1, ProcessingFee, 0)-IF(VATIncluded=1,VAT,0))', - 'TotalAmount' => 'SubTotal+ShippingCost+IF(VATIncluded=1,0,VAT)+ProcessingFee+InsuranceFee-GiftCertificateDiscount', + 'OrderNumber' => 'CONCAT(LPAD(%1$s.Number,6,"0"),\'-\',LPAD(%1$s.SubNumber,3,"0") )', + 'SubtotalWithoutDiscount' => '(%1$s.SubTotal + %1$s.DiscountTotal)', + 'SubtotalWithDiscount' => '(%1$s.SubTotal)', + 'AmountWithoutVAT' => '(%1$s.SubTotal+IF(%1$s.ShippingTaxable=1, %1$s.ShippingCost, 0)+IF(%1$s.ProcessingTaxable=1, %1$s.ProcessingFee, 0)-IF(%1$s.VATIncluded=1,%1$s.VAT,0))', + 'TotalAmount' => '%1$s.SubTotal+%1$s.ShippingCost+IF(%1$s.VATIncluded=1,0,%1$s.VAT)+%1$s.ProcessingFee+%1$s.InsuranceFee-%1$s.GiftCertificateDiscount', 'CouponCode' => 'pc.Code', 'CouponName' => 'pc.Name', 'AffiliateUser' => 'IF(au.PortalUserId IS NULL, "!la_None!", IF(au.Username = "", au.Email, au.Username))', @@ -269,11 +279,11 @@ ), 'myorders' => Array ( - 'OrderNumber' => 'CONCAT(LPAD(Number,6,"0"),\'-\',LPAD(SubNumber,3,"0") )', - 'SubtotalWithoutDiscount' => '(SubTotal + DiscountTotal)', - 'SubtotalWithDiscount' => '(SubTotal)', - 'AmountWithoutVAT' => '(SubTotal+IF(ShippingTaxable=1, ShippingCost, 0)+IF(ProcessingTaxable=1, ProcessingFee, 0)-IF(VATIncluded=1,VAT,0))', - 'TotalAmount' => 'SubTotal+ShippingCost+IF(VATIncluded=1,0,VAT)+ProcessingFee+InsuranceFee-GiftCertificateDiscount', + 'OrderNumber' => 'CONCAT(LPAD(%1$s.Number,6,"0"),\'-\',LPAD(%1$s.SubNumber,3,"0") )', + 'SubtotalWithoutDiscount' => '(%1$s.SubTotal + %1$s.DiscountTotal)', + 'SubtotalWithDiscount' => '(%1$s.SubTotal)', + 'AmountWithoutVAT' => '(%1$s.SubTotal+IF(%1$s.ShippingTaxable=1, %1$s.ShippingCost, 0)+IF(%1$s.ProcessingTaxable=1, %1$s.ProcessingFee, 0)-IF(%1$s.VATIncluded=1,%1$s.VAT,0))', + 'TotalAmount' => '%1$s.SubTotal+%1$s.ShippingCost+IF(%1$s.VATIncluded=1,0,%1$s.VAT)+%1$s.ProcessingFee+%1$s.InsuranceFee-%1$s.GiftCertificateDiscount', /*'ItemsCount' => 'COUNT(%1$s.OrderId)',*/ 'ShippingSubTotal' => '%1$s.ShippingCost + %1$s.InsuranceFee', ), @@ -446,7 +456,7 @@ 'TransactionStatus' => Array ( 'type' => 'int', 'formatter' => 'kOptionsFormatter', - 'options' => Array (0 => 'la_opt_Invalid', 1 => 'la_opt_Verified', 2 => 'la_opt_Penging'), + 'options' => Array (0 => 'la_opt_Invalid', 1 => 'la_opt_Verified', 2 => 'la_opt_Pending'), 'use_phrases' =>1, 'not_null' => 1, 'default' => 2, ), 'GWResult1' => Array ('type' => 'string', 'formatter' => 'kSerializedFormatter', 'default' => NULL), Index: branches/5.3.x/units/orders/orders_item.php =================================================================== diff -u -r16106 -r16398 --- branches/5.3.x/units/orders/orders_item.php (.../orders_item.php) (revision 16106) +++ branches/5.3.x/units/orders/orders_item.php (.../orders_item.php) (revision 16398) @@ -1,6 +1,6 @@ IsTempTable() ) { + $oi_table = $this->Application->GetTempName($oi_table, 'prefix:' . $this->Prefix); + } + $sql = 'SELECT COUNT(*) - FROM '.TABLE_PREFIX.'OrderItems orditems - LEFT JOIN '.TABLE_PREFIX.'Products p ON p.ProductId = orditems.ProductId - WHERE (orditems.OrderId = '.$this->GetID().') AND (p.Type = '.PRODUCT_TYPE_TANGIBLE.')'; - return $this->Conn->GetOne($sql) ? true : false; + FROM ' . $oi_table . ' orditems + LEFT JOIN ' . TABLE_PREFIX . 'Products p ON p.ProductId = orditems.ProductId + WHERE (orditems.OrderId = ' . $this->GetID() . ') AND (p.Type = ' . PRODUCT_TYPE_TANGIBLE . ')'; + + return $this->Conn->GetOne($sql) > 0; } /** Index: branches/5.3.x/units/orders/order_validator.php =================================================================== diff -u -r15925 -r16398 --- branches/5.3.x/units/orders/order_validator.php (.../order_validator.php) (revision 15925) +++ branches/5.3.x/units/orders/order_validator.php (.../order_validator.php) (revision 16398) @@ -1,6 +1,6 @@ dataSource->getGatewayData(); - $this->Application->registerClass( $gw_data['ClassName'], GW_CLASS_PATH.'/'.$gw_data['ClassFile'] ); - $gateway_object = $this->Application->recallObject( $gw_data['ClassName'] ); - + /** @var kGWBase $gateway_object */ + $gateway_object = $this->Application->recallObject($gw_data['ClassName']); $test_numbers = $gateway_object->GetTestCCNumbers(); if ( in_array($value, $test_numbers) ) { @@ -244,4 +243,4 @@ return true; } -} \ No newline at end of file +} Index: branches/5.3.x/units/shipping/shipping_tag_processor.php =================================================================== diff -u -r16192 -r16398 --- branches/5.3.x/units/shipping/shipping_tag_processor.php (.../shipping_tag_processor.php) (revision 16192) +++ branches/5.3.x/units/shipping/shipping_tag_processor.php (.../shipping_tag_processor.php) (revision 16398) @@ -1,6 +1,6 @@ Application->isAdminUser ? $original_shipping['TotalCost'] : $shipping_types[$key]['TotalCost']; - $shipping_types[$key]['ShippingName'] = $this->Application->isAdminUser ? 'Original: '.$original_shipping['ShippingName'] : $shipping_types[$key]['ShippingName']; - $shipping_types[$key]['ShippingId'] = $key; + + // When changing shipping type (via dropdown), then prefer current order's actual + // shipping info over one from Shipping Quote Engines. + if ( $this->Application->isAdminUser ) { + $shipping_types[$key] = $original_shipping; + $shipping_types[$key]['ShippingName'] = 'Original: ' . $original_shipping['ShippingName']; + } + $selected_id = $key; } Index: branches/5.3.x/units/products/products_event_handler.php =================================================================== diff -u -r16106 -r16398 --- branches/5.3.x/units/products/products_event_handler.php (.../products_event_handler.php) (revision 16106) +++ branches/5.3.x/units/products/products_event_handler.php (.../products_event_handler.php) (revision 16398) @@ -1,6 +1,6 @@ Conn->GetCol($query); - if (!$orders) return; + if ( !$orders ) { + return; + } - $order = $this->Application->recallObject('ord.-inv', null, Array('skip_autoload' => true)); + /** @var OrdersItem $order */ + $order = $this->Application->recallObject('ord.-inv', null, array('skip_autoload' => true)); + /* @var $order OrdersItem */ foreach ($orders as $ord_id) { $order->Load($ord_id); $this->Application->emailAdmin('BACKORDER.FULLFILL', null, $order->getEmailParams()); - //reserve what's possible in any case - $event = new kEvent('ord:OnReserveItems'); - $this->Application->HandleEvent($event); + // Reserve what's possible in any case. + $reserve_event = new kEvent('ord:OnReserveItems'); + $this->Application->HandleEvent($reserve_event); - if ( $event->status == kEvent::erSUCCESS ) { // - //in case the order is ready to process - process it - $this->Application->HandleEvent($event, 'ord:OnOrderProcess'); + // In case the order is ready to process - process it. + if ( $reserve_event->status == kEvent::erSUCCESS ) { + $this->Application->HandleEvent(new kEvent('ord:OnOrderProcess')); } } } Index: branches/5.3.x/admin_templates/orders/orders_search_list.tpl =================================================================== diff -u -r15492 -r16398 --- branches/5.3.x/admin_templates/orders/orders_search_list.tpl (.../orders_search_list.tpl) (revision 15492) +++ branches/5.3.x/admin_templates/orders/orders_search_list.tpl (.../orders_search_list.tpl) (revision 16398) @@ -29,6 +29,7 @@ a_toolbar.AddButton( new ToolBarButton('export', '', function() { set_hidden_field('export_finish_t', 'in-commerce/orders/export/export_finish'); set_hidden_field('export_progress_t', 'in-commerce/orders/export/export_progress'); + set_hidden_field('grid', 'Search'); open_popup('ord.search', 'OnExport', 'in-commerce/orders/export/export'); } ) ); @@ -68,4 +69,4 @@ \ No newline at end of file + Index: branches/5.3.x/units/gateways/gateways_config.php =================================================================== diff -u -r15656 -r16398 --- branches/5.3.x/units/gateways/gateways_config.php (.../gateways_config.php) (revision 15656) +++ branches/5.3.x/units/gateways/gateways_config.php (.../gateways_config.php) (revision 16398) @@ -1,6 +1,6 @@ Array ('class' => 'GatewayEventHandler', 'file' => 'gw_event_handler.php', 'build_event' => 'OnBuild'), 'TagProcessorClass' => Array ('class' => 'GatewayTagProcessor', 'file' => 'gw_tag_processor.php', 'build_event' => 'OnBuild'), + 'RegisterClasses' => array( + array('pseudo' => 'kGWBase', 'class' => 'kGWBase', 'file' => 'gw_classes/gw_base.php', 'build_event' => ''), + array('pseudo' => 'kAtosOriginGW', 'class' => 'kAtosOriginGW', 'file' => 'gw_classes/atosorigin.php', 'build_event' => '', 'require_classes' => 'kGWBase'), + array('pseudo' => 'kGWAuthorizeNet', 'class' => 'kGWAuthorizeNet', 'file' => 'gw_classes/authorizenet.php', 'build_event' => '', 'require_classes' => 'kGWBase'), + array('pseudo' => 'kGWGoogleCheckout', 'class' => 'kGWGoogleCheckout', 'file' => 'gw_classes/google_checkout.php', 'build_event' => '', 'require_classes' => 'kGWBase'), + array('pseudo' => 'kGWiDEALnl', 'class' => 'kGWiDEALnl', 'file' => 'gw_classes/ideal_nl.php', 'build_event' => '', 'require_classes' => 'kGWBase'), + array('pseudo' => 'kMultiCardsGW', 'class' => 'kMultiCardsGW', 'file' => 'gw_classes/multicards.php', 'build_event' => '', 'require_classes' => 'kGWBase'), + array('pseudo' => 'kPayboxGW', 'class' => 'kPayboxGW', 'file' => 'gw_classes/paybox.php', 'build_event' => '', 'require_classes' => 'kGWBase'), + array('pseudo' => 'kPaymentechGW', 'class' => 'kPaymentechGW', 'file' => 'gw_classes/paymentech.php', 'build_event' => '', 'require_classes' => 'kGWBase'), + array('pseudo' => 'kGWPayPal', 'class' => 'kGWPayPal', 'file' => 'gw_classes/paypal.php', 'build_event' => '', 'require_classes' => 'kGWBase'), + array('pseudo' => 'kGWPaypalDirect', 'class' => 'kGWPaypalDirect', 'file' => 'gw_classes/paypal_direct.php', 'build_event' => '', 'require_classes' => 'kGWBase'), + array('pseudo' => 'kGWRightConnect', 'class' => 'kGWRightConnect', 'file' => 'gw_classes/rightconnect.php', 'build_event' => '', 'require_classes' => 'kGWBase'), + array('pseudo' => 'kSellaGuestPayGW', 'class' => 'kSellaGuestPayGW', 'file' => 'gw_classes/sella_guestpay.php', 'build_event' => '', 'require_classes' => 'kGWBase'), + array('pseudo' => 'kVerisignPfLinkGW', 'class' => 'kVerisignPfLinkGW', 'file' => 'gw_classes/verisign_pflink.php', 'build_event' => '', 'require_classes' => 'kGWBase'), + array('pseudo' => 'kGWWorldPay', 'class' => 'kGWWorldPay', 'file' => 'gw_classes/worldpay.php', 'build_event' => '', 'require_classes' => 'kGWBase'), + ), + 'AutoLoad' => true, 'Hooks' => Array ( @@ -72,4 +89,4 @@ 'VirtualFields' => Array ( 'Value' => Array ('type' => 'string', 'default' => ''), ), -); \ No newline at end of file +); Index: branches/5.3.x/units/orders/orders_event_handler.php =================================================================== diff -u -r16223 -r16398 --- branches/5.3.x/units/orders/orders_event_handler.php (.../orders_event_handler.php) (revision 16223) +++ branches/5.3.x/units/orders/orders_event_handler.php (.../orders_event_handler.php) (revision 16398) @@ -1,6 +1,6 @@ getUnitConfig(); - $this->Conn->doUpdate($fields_hash, $config->getTableName(), $config->getIDField() . ' = ' . $order_id); + /** @var OrdersItem $object */ + $object = $this->Application->recallObject($event->Prefix . '.-item', null, array('skip_autoload' => true)); + $object->Load($order_id); - $object = $event->getObject(); - /* @var $object kDBItem */ - - // set user id to object, since it will be used during order update from OnRecalculateItems event - $object->SetDBField('PortalUserId', $user->GetID()); + if ( $object->isLoaded() ) { + $object->SetDBFieldsFromHash($fields_hash); + $object->Update(); + } } function isAffiliate($user_id) @@ -348,9 +348,8 @@ { $gw_data = $order->getGatewayData(); - $this->Application->registerClass( $gw_data['ClassName'], GW_CLASS_PATH.'/'.$gw_data['ClassFile'] ); - $gateway_object = $this->Application->recallObject( $gw_data['ClassName'] ); - /* @var $gateway_object kGWBase */ + /** @var kGWBase $gateway_object */ + $gateway_object = $this->Application->recallObject($gw_data['ClassName']); $payment_result = $gateway_object->DirectPayment($order->GetFieldValues(), $gw_data['gw_params']); $sql = 'UPDATE %s SET GWResult1 = %s WHERE %s = %s'; @@ -1585,9 +1584,10 @@ */ function CheckUser($event) { - if ($this->Application->isAdminUser || defined('GW_NOTIFY')) { - // don't check for user in order while processing payment - // gateways, because they can do cross-domain ssl redirects + if ( $this->Application->isAdminUser || defined('GW_NOTIFY') || defined('CRON') ) { + // 1. don't check, when Administrator is editing the order. + // 2. don't check while processing payment gateways, because they can do cross-domain ssl redirects. + // 3. don't check from CRON, because it's like Admin updates orders on other user behalf. return; } @@ -1643,21 +1643,29 @@ { parent::OnBeforeClone($event); + /** @var OrdersItem $object */ $object = $event->getObject(); - /* @var $object OrdersItem */ if ( substr($event->Special, 0, 9) == 'recurring' ) { $object->SetDBField('SubNumber', $object->getNextSubNumber()); - $object->SetDBField('OriginalAmount', 0); // needed in this case ? } else { $this->setNextOrderNumber($event); - $object->SetDBField('OriginalAmount', 0); } - $object->SetDBField('OrderDate', time()); + + $reset_fields = array( + 'OnHold', 'OrderDate', 'ShippingCost', 'ShippingTracking', 'ShippingDate', 'ReturnTotal', + 'OriginalAmount', 'ShippingInfo', 'GWResult1', 'GWResult2', 'AffiliateCommission', + 'ProcessingFee', 'InsuranceFee', + ); + + foreach ( $reset_fields as $reset_field ) { + $field_options = $object->GetFieldOptions($reset_field); + $object->SetDBField($reset_field, $field_options['default']); + } + + $object->SetDBField('OrderIP', $this->Application->getClientIp()); $object->UpdateFormattersSubFields(); - $object->SetDBField('GWResult1', ''); - $object->SetDBField('GWResult2', ''); } function OnReserveItems($event) @@ -2102,9 +2110,8 @@ // charge user for order in case if we user 2step charging (e.g. AUTH_ONLY + PRIOR_AUTH_CAPTURE) $gw_data = $object->getGatewayData(); - $this->Application->registerClass( $gw_data['ClassName'], GW_CLASS_PATH.'/'.$gw_data['ClassFile'] ); - $gateway_object = $this->Application->recallObject( $gw_data['ClassName'] ); - /* @var $gateway_object kGWBase */ + /** @var kGWBase $gateway_object */ + $gateway_object = $this->Application->recallObject($gw_data['ClassName']); $charge_result = $gateway_object->Charge($object->GetFieldValues(), $gw_data['gw_params']); $sql = 'UPDATE %s SET GWResult2 = %s WHERE %s = %s'; @@ -2168,9 +2175,8 @@ $gw_data = $object->getGatewayData(); if ( $gw_data ) { - $this->Application->registerClass( $gw_data['ClassName'], GW_CLASS_PATH . '/' . $gw_data['ClassFile'] ); - $gateway_object = $this->Application->recallObject( $gw_data['ClassName'] ); - + /** @var kGWBase $gateway_object */ + $gateway_object = $this->Application->recallObject($gw_data['ClassName']); $gateway_object->OrderDeclined($object->GetFieldValues(), $gw_data['gw_params']); } } @@ -2222,9 +2228,8 @@ // inform payment gateway that order was shipped $gw_data = $object->getGatewayData(); - $this->Application->registerClass( $gw_data['ClassName'], GW_CLASS_PATH.'/'.$gw_data['ClassFile'] ); - $gateway_object = $this->Application->recallObject( $gw_data['ClassName'] ); - + /** @var kGWBase $gateway_object */ + $gateway_object = $this->Application->recallObject($gw_data['ClassName']); $gateway_object->OrderShipped($object->GetFieldValues(), $gw_data['gw_params']); } else { @@ -2272,22 +2277,19 @@ } /** - * Set next available order number + * Set next available order number. * - * @param kEvent $event + * @param kEvent $event Event. + * + * @return void */ - function setNextOrderNumber($event) + protected function setNextOrderNumber(kEvent $event) { + /** @var OrdersItem $object */ $object = $event->getObject(); - /* @var $object OrdersItem */ - $sql = 'SELECT MAX(Number) - FROM ' . $this->Application->GetLiveName($object->TableName); - $next_order_number = $this->Conn->GetOne($sql) + 1; + $next_order_number = $this->getNextOrderNumber(); - $next_order_number = max($next_order_number, $this->Application->ConfigValue('Comm_Next_Order_Number')); - $this->Application->SetConfigValue('Comm_Next_Order_Number', $next_order_number + 1); - $object->SetDBField('Number', $next_order_number); $object->SetDBField('SubNumber', 0); @@ -2300,6 +2302,63 @@ } /** + * Returns order number to be used next. + * + * @return integer + */ + protected function getNextOrderNumber() + { + $config_table = $this->Application->getUnitConfig('conf')->getTableName(); + $this->Conn->Query('LOCK TABLES ' . $config_table . ' WRITE'); + + $sql = 'UPDATE ' . $config_table . ' + SET VariableValue = VariableValue + 1 + WHERE VariableName = "Comm_Next_Order_Number"'; + $this->Conn->Query($sql); + + $sql = 'SELECT VariableValue + FROM ' . $config_table . ' + WHERE VariableName = "Comm_Next_Order_Number"'; + $next_order_number = $this->Conn->GetOne($sql); + + $this->Conn->Query('UNLOCK TABLES'); + $this->Application->SetConfigValue('Comm_Next_Order_Number', $next_order_number); + + return $next_order_number - 1; + } + + /** + * [HOOK] Ensures, that "Next Order Number" system setting is within allowed limits. + * + * @param kEvent $event Event. + * + * @return void + */ + protected function OnBeforeNextOrderNumberChange(kEvent $event) + { + /** @var kDBItem $system_setting */ + $system_setting = $event->MasterEvent->getObject(); + + $old_value = $system_setting->GetOriginalField('VariableValue'); + $new_value = $system_setting->GetDBField('VariableValue'); + + if ( $system_setting->GetDBField('VariableName') != 'Comm_Next_Order_Number' || $new_value == $old_value ) { + return; + } + + $sql = 'SELECT MAX(Number) + FROM ' . $event->getUnitConfig()->getTableName(); + $next_order_number = (int)$this->Conn->GetOne($sql) + 1; + + if ( $new_value < $next_order_number ) { + $system_setting->SetError('VariableValue', 'value_out_of_range', null, array( + 'min_value' => $next_order_number, + 'max_value' => '∞', + )); + } + } + + /** * Set's new order address based on another address from order (e.g. billing from shipping) * * @param unknown_type $object @@ -2790,7 +2849,7 @@ $ord_id = $order->GetId(); $shipping_option = $order->GetDBField('ShippingOption'); - $backorder_select = $shipping_option == 0 ? '0' : 'oi.BackOrderFlag'; + $backorder_select = $shipping_option == 0 ? '0' : '%s.BackOrderFlag'; // setting PackageNum to 0 for Non-tangible items, for tangibles first package num is always 1 @@ -2813,7 +2872,7 @@ // 2 => ProductId // 3 => Shipping PackageNum $query = 'SELECT - '.$backorder_select.' AS BackOrderFlagCalc, + ' . sprintf($backorder_select, $table_prefix . 'OrderItems') . ' AS BackOrderFlagCalc, PackageNum, ProductName, ShippingTypeId, @@ -2855,9 +2914,15 @@ $sub_order = $this->Application->recallObject('ord.-sub'.$next_sub_number, 'ord'); /* @var $sub_order OrdersItem */ - if ($this->UseTempTables($event) && $next_sub_number == 0) { + if ( $this->UseTempTables($event) && $next_sub_number == 0 ) { $sub_order =& $order; } + else { + foreach ( $order->GetFieldValues() as $field => $value ) { + $sub_order->SetOriginalField($field, $value); + } + } + $sub_order->SetDBFieldsFromHash($order->GetFieldValues()); $sub_order->SetDBField('SubNumber', $next_sub_number); $sub_order->SetDBField('SubTotal', $sub_order_data['TotalAmount']); @@ -2927,10 +2992,10 @@ break; case PRODUCT_TYPE_TANGIBLE: - $sql = 'SELECT '.$backorder_select.' AS BackOrderFlagCalc, oi.* - FROM '.TABLE_PREFIX.'OrderItems oi - LEFT JOIN '.TABLE_PREFIX.'Products p ON p.ProductId = oi.ProductId - WHERE (OrderId = %s) AND (p.Type = '.PRODUCT_TYPE_TANGIBLE.') + $sql = 'SELECT ' . sprintf($backorder_select, 'oi') . ' AS BackOrderFlagCalc, oi.* + FROM ' . TABLE_PREFIX . 'OrderItems oi + LEFT JOIN ' . TABLE_PREFIX . 'Products p ON p.ProductId = oi.ProductId + WHERE (OrderId = %s) AND (p.Type = ' . PRODUCT_TYPE_TANGIBLE . ') HAVING BackOrderFlagCalc = 0'; $products = $this->Conn->Query( sprintf($sql, $ord_id) ); @@ -2958,18 +3023,24 @@ switch ($named_grouping_data['Type']) { case PRODUCT_TYPE_TANGIBLE: - $query = 'UPDATE '.$table_prefix.'OrderItems SET OrderId = %s WHERE OrderId = %s AND PackageNum = %s'; - $query = sprintf($query, $sub_order->GetId(), $ord_id, $sub_order_data['PackageNum']); + $query = ' UPDATE ' . $table_prefix . 'OrderItems + SET OrderId = %s, PackageNum = 1 + WHERE OrderId = %s AND PackageNum = %s'; + $query = sprintf($query, $sub_order->GetID(), $ord_id, $sub_order_data['PackageNum']); break; case PRODUCT_TYPE_DOWNLOADABLE: - $query = 'UPDATE '.$table_prefix.'OrderItems SET OrderId = %s WHERE OrderId = %s AND ProductId IN (%s)'; - $query = sprintf($query, $sub_order->GetId(), $ord_id, implode(',', $product_ids) ); + $query = ' UPDATE ' . $table_prefix . 'OrderItems + SET OrderId = %s, PackageNum = 1 + WHERE OrderId = %s AND ProductId IN (%s)'; + $query = sprintf($query, $sub_order->GetID(), $ord_id, implode(',', $product_ids)); break; default: - $query = 'UPDATE '.$table_prefix.'OrderItems SET OrderId = %s WHERE OrderId = %s AND OrderItemId = %s'; - $query = sprintf($query, $sub_order->GetId(), $ord_id, $named_grouping_data['OrderItemId']); + $query = ' UPDATE ' . $table_prefix . 'OrderItems + SET OrderId = %s, PackageNum = 1 + WHERE OrderId = %s AND OrderItemId = %s'; + $query = sprintf($query, $sub_order->GetID(), $ord_id, $named_grouping_data['OrderItemId']); break; } @@ -2985,7 +3056,7 @@ $processed_sub_orders[] = $sub_order->GetID(); - $next_sub_number++; + $next_sub_number = $sub_order->getNextSubNumber(); $group++; } @@ -3497,7 +3568,10 @@ function OnLoadSelected($event) { $event->setPseudoClass('_List'); - $object = $event->getObject( Array('selected_only' => true) ); + + /** @var kDBList $object */ + $object = $event->getObject(array('selected_only' => true, 'per_page' => -1)); + $event->redirect = false; } @@ -3759,24 +3833,8 @@ { parent::OnBeforeExportBegin($event); - $options = $event->getEventParam('options'); - - $items_list = $this->Application->recallObject($event->Prefix . '.' . $this->Application->RecallVar('export_oroginal_special'), $event->Prefix . '_List'); - /* @var $items_list kDBList */ - - $items_list->SetPerPage(-1); - - if ( $options['export_ids'] != '' ) { - $items_list->AddFilter('export_ids', $items_list->TableName . '.' . $items_list->IDField . ' IN (' . implode(',', $options['export_ids']) . ')'); - } - - $options['ForceCountSQL'] = $items_list->getCountSQL($items_list->GetSelectSQL(true, false)); - $options['ForceSelectSQL'] = $items_list->GetSelectSQL(); - - $event->setEventParam('options', $options); - + /** @var kDBItem $object */ $object = $this->Application->recallObject($event->Prefix . '.export'); - /* @var $object kDBItem */ $object->SetField('Number', 999999); $object->SetField('SubNumber', 999); @@ -3822,6 +3880,8 @@ } foreach ( $this->trackCopiedOrderIDs($event) as $id ) { + $this->Application->removeObject($event->getPrefixSpecial()); + $an_event = new kEvent($this->Prefix . ':Dummy'); $this->Application->SetVar($this->Prefix . '_id', $id); $this->Application->SetVar($this->Prefix . '_mode', ''); // this is to fool ReserveItems to use live table Index: branches/5.3.x/units/orders/order_calculator.php =================================================================== diff -u -r16106 -r16398 --- branches/5.3.x/units/orders/order_calculator.php (.../order_calculator.php) (revision 16106) +++ branches/5.3.x/units/orders/order_calculator.php (.../order_calculator.php) (revision 16398) @@ -1,6 +1,6 @@