Index: branches/5.2.x/units/orders/orders_config.php =================================================================== diff -u -N -r14821 -r14827 --- branches/5.2.x/units/orders/orders_config.php (.../orders_config.php) (revision 14821) +++ branches/5.2.x/units/orders/orders_config.php (.../orders_config.php) (revision 14827) @@ -1,6 +1,6 @@ 'string', 'formatter' => 'kFormatter', 'regexp' => '/^(' . REGEX_EMAIL_USER . '@' . REGEX_EMAIL_DOMAIN . ')$/i', + 'error_msgs' => Array ('invalid_format' => '!la_invalid_email!', 'unique' => '!lu_email_already_exist!'), 'not_null' => 1, 'default' => '', ), 'BillingAddress1' => Array ('type' => 'string', 'not_null' => 1, 'default' => ''), @@ -372,6 +373,7 @@ 'type' => 'string', 'formatter' => 'kFormatter', 'regexp' => '/^(' . REGEX_EMAIL_USER . '@' . REGEX_EMAIL_DOMAIN . ')$/i', + 'error_msgs' => Array ('invalid_format' => '!la_invalid_email!'), 'not_null' => 1, 'default' => '', ), 'ShippingAddress1' => Array ('type' => 'string', 'not_null' => 1, 'default' => ''), Index: branches/5.2.x/units/orders/orders_event_handler.php =================================================================== diff -u -N -r14821 -r14827 --- branches/5.2.x/units/orders/orders_event_handler.php (.../orders_event_handler.php) (revision 14821) +++ branches/5.2.x/units/orders/orders_event_handler.php (.../orders_event_handler.php) (revision 14827) @@ -1,6 +1,6 @@ Application->RecallVar($event->getPrefixSpecial(true).'_id'); + $order_dummy =& $this->Application->recallObject($event->Prefix.'.-item', null, Array('skip_autoload' => true)); + /* @var $order_dummy OrdersItem */ + foreach ($items_info as $id => $field_values) { if ($order_session_id != $id) { // user is trying update not his order, even order from other guest @@ -182,7 +185,7 @@ } $object =& $event->getObject(); - /* @var $object kDBItem */ + /* @var $object OrdersItem */ $shipping_address_id = $this->Application->GetVar('shipping_address_id'); $billing_address_id = $this->Application->GetVar('billing_address_id'); @@ -192,7 +195,11 @@ /* @var $cs_helper kCountryStatesHelper */ $address =& $this->Application->recallObject('addr.-item','addr', Array('skip_autoload' => true)); + /* @var $address AddressesItem */ + $addr_list =& $this->Application->recallObject('addr', 'addr_List', Array('per_page'=>-1, 'skip_counting'=>true) ); + /* @var $addr_list AddressesList */ + $addr_list->Query(); } @@ -274,6 +281,13 @@ $event->CallSubEvent('OnRecalculateItems'); } + /** + * Puts ID of just logged-in user into current order + * + * @param int $order_id + * @param kEvent $event + * @return void + */ function updateUserID($order_id, &$event) { $user =& $this->Application->recallObject('u.current'); @@ -294,6 +308,12 @@ $table_name = $this->Application->getUnitOption($event->Prefix, 'TableName'); $this->Conn->doUpdate($fields_hash, $table_name, $id_field . ' = ' . $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()); } function isAffiliate($user_id) @@ -704,6 +724,8 @@ } $object =& $event->getObject(); + /* @var $object kDBItem */ + $addr_list =& $this->Application->recallObject('addr', 'addr_List', Array ('per_page' => -1, 'skip_counting' => true)); /* @var $addr_list kDBList */ @@ -854,7 +876,10 @@ $comb = getArrayValue($an_item, 'comb'); $item_data = $default_item_data; + $product =& $this->Application->recallObject('p', null, Array('skip_autoload' => true)); + /* @var $product ProductsItem */ + $product->Load($item_id); $event->setEventParam('ItemData', null); @@ -882,7 +907,10 @@ if( $product->GetDBField('Type') == 5 ) // package { $package_content_ids = $product->GetPackageContentIds(); + $product_package_item =& $this->Application->recallObject('p.-packageitem'); + /* @var $product_package_item ProductsItem */ + $package_item_data = array(); foreach ($package_content_ids as $package_item_id){ @@ -1547,6 +1575,8 @@ function OnReserveItems(&$event) { $order_items =& $this->Application->recallObject('orditems.-inv','orditems_List',Array('skip_counting'=>true,'per_page'=>-1) ); + /* @var $order_items kDBList */ + $order_items->linkToParent('-inv'); // force re-query, since we are updateing through orditem ITEM, not the list, and // OnReserveItems may be called 2 times when fullfilling backorders through product edit - first time @@ -1558,10 +1588,15 @@ $product_object =& $this->Application->recallObject('p', null, Array('skip_autoload' => true)); + /* @var $product_object kCatDBItem */ + $product_object->SwitchToLive(); $order_item =& $this->Application->recallObject('orditems.-item', null, Array('skip_autoload' => true)); + /* @var $order_item kDBItem */ + $combination_item =& $this->Application->recallObject('poc.-item', null, Array('skip_autoload' => true)); + /* @var $combination_item kDBItem */ $combinations = $this->queryCombinations($order_items); @@ -1619,14 +1654,18 @@ function OnResetAddress(&$event) { $to_tab = $this->Application->GetVar('to_tab'); - $from_tab = substr($event->Name,strlen('OnResetTo')); + $from_tab = substr($event->Name, strlen('OnResetTo')); // load values from db $object =& $event->getObject(); + /* @var $object kDBItem */ // update values from submit - $items_info = $this->Application->GetVar( $event->getPrefixSpecial(true) ); - if($items_info) $field_values = array_shift($items_info); + $items_info = $this->Application->GetVar($event->getPrefixSpecial(true)); + if ( $items_info ) { + $field_values = array_shift($items_info); + } + $object->SetFieldsFromHash($field_values); $this->DoResetAddress($object, $from_tab, $to_tab); @@ -1802,13 +1841,24 @@ return true; } + /** + * Restores reserved items in the order + * + * @param kDBList $order_items + * @return bool + */ function restoreOrder(&$order_items) { $product_object =& $this->Application->recallObject('p', null, Array('skip_autoload' => true)); + /* @var $product_object kCatDBItem */ + $product_object->SwitchToLive(); $order_item =& $this->Application->recallObject('orditems.-item', null, Array('skip_autoload' => true)); + /* @var $order_item kDBItem */ + $combination_item =& $this->Application->recallObject('poc.-item', null, Array('skip_autoload' => true)); + /* @var $combination_item kDBItem */ $combinations = $this->queryCombinations($order_items); @@ -1838,15 +1888,17 @@ $inv_object->Update(); $product_h =& $this->Application->recallObject('p_EventHandler'); + /* @var $product_h ProductsEventHandler */ + if ($product_object->GetDBField('InventoryStatus') == 2) { // inventory by options, then restore changed combination values back to common $combinations array !!! $combinations[ $rec['ProductId'].'_'.$rec['OptionsSalt'] ] = $inv_object->GetFieldValues(); - // using freed qty to fullfill possible backorders + // using freed qty to fulfill possible backorders $product_h->FullfillBackOrders($product_object, $inv_object->GetID()); } else { - // using freed qty to fullfill possible backorders + // using freed qty to fulfill possible backorders $product_h->FullfillBackOrders($product_object, 0); } @@ -1857,6 +1909,7 @@ $order_items->GoNext(); } + return true; } @@ -1867,20 +1920,19 @@ */ function MassInventoryAction(&$event) { - if ($this->Application->CheckPermission('SYSTEM_ACCESS.READONLY', 1)) { + if ( $this->Application->CheckPermission('SYSTEM_ACCESS.READONLY', 1) ) { $event->status = kEvent::erFAIL; return; } // process order products - $object =& $this->Application->recallObject($event->Prefix.'.-inv', null, Array('skip_autoload' => true)); + $object =& $this->Application->recallObject($event->Prefix . '.-inv', null, Array ('skip_autoload' => true)); + /* @var $object kDBItem */ $ids = $this->StoreSelectedIDs($event); - if($ids) - { - foreach($ids as $id) - { + if ( $ids ) { + foreach ($ids as $id) { $object->Load($id); $this->InventoryAction($event); } @@ -1936,7 +1988,7 @@ switch ($event->Name) { case 'OnMassOrderApprove': case 'OnOrderApprove': - $set_new_status = false; //on succsessfull approve order will be split and new orders will have new statuses + $set_new_status = false; //on successful approve order will be split and new orders will have new statuses if ($object->GetDBField('ChargeOnNextApprove')) { $charge_info = $this->ChargeOrder($object); @@ -1989,7 +2041,7 @@ $this->PrepareCoupons($event, $object); $this->SplitOrder($event, $object); if ($object->GetDBField('IsRecurringBilling') != 1) { - $email_event_user =& $this->Application->EmailEventUser('ORDER.APPROVE', $object->GetDBField('PortalUserId'), $email_params); + $this->Application->EmailEventUser('ORDER.APPROVE', $object->GetDBField('PortalUserId'), $email_params); // Mask credit card with XXXX if ($this->Application->ConfigValue('Comm_MaskProcessedCreditCards')) { @@ -2353,9 +2405,49 @@ if ( !$object->GetDBField('PaymentNameOnCard') ) { $object->SetDBField('PaymentNameOnCard', $object->GetDBField('BillingTo')); } + + if ( $event->MasterEvent->Name == 'OnUpdateAjax' && $this->Application->GetVar('create_account') && $object->Validate() ) { + $this->createAccountFromOrder($event); + } } /** + * Creates user account + * + * @param kEvent $event + * @return void + * @access protected + */ + protected function createAccountFromOrder(&$event) + { + $order =& $event->getObject(); + /* @var $order OrdersItem */ + + $order_helper =& $this->Application->recallObject('OrderHelper'); + /* @var $order_helper OrderHelper */ + + $user_fields = $order_helper->getUserFields($order); + $user_fields['Password'] = $order->GetDBField('UserPassword_plain'); + $user_fields['VerifyPassword'] = $order->GetDBField('VerifyUserPassword_plain'); + + if ( $order->GetDBField('PortalUserId') == USER_GUEST ) { + // will also auto-login user when created + $this->Application->SetVar('u_register', Array (USER_GUEST => $user_fields)); + $user_event = new kEvent('u.register:OnCreate'); + $this->Application->HandleEvent($user_event); + } + else { + $user =& $this->Application->recallObject('u.current'); + /* @var $user UsersItem */ + + $user->SetFieldsFromHash($user_fields); + if ( !$user->Update() ) { + $order->SetError('BillingEmail', $user->GetErrorPseudo('Email')); + } + } + } + + /** * Apply any custom changes to list's sql query * * @param kEvent $event @@ -2366,6 +2458,7 @@ protected function SetCustomQuery(&$event) { $object =& $event->getObject(); + /* @var $object kDBList */ $types = $event->getEventParam('types'); if($types == 'myorders' || $types == 'myrecentorders') @@ -3780,6 +3873,20 @@ $required_fields = Array ('UserPassword', 'UserPassword_plain', 'VerifyUserPassword', 'VerifyUserPassword_plain'); $object->setRequired($required_fields, $create_account); + + $billing_email = $object->GetDBField('BillingEmail'); + + if ( $create_account && $object->GetDBField('PortalUserId') == USER_GUEST && $billing_email ) { + // check that e-mail available + $sql = 'SELECT PortalUserId + FROM ' . TABLE_PREFIX . 'PortalUser + WHERE Email = ' . $this->Conn->qstr($billing_email); + $user_id = $this->Conn->GetOne($sql); + + if ( $user_id ) { + $object->SetError('BillingEmail', 'unique'); + } + } } /** Index: branches/5.2.x/units/helpers/order_helper.php =================================================================== diff -u -N -r14813 -r14827 --- branches/5.2.x/units/helpers/order_helper.php (.../order_helper.php) (revision 14813) +++ branches/5.2.x/units/helpers/order_helper.php (.../order_helper.php) (revision 14827) @@ -195,4 +195,36 @@ return false; } + + /** + * Extracts fields, used to created user from order + * + * @param OrdersItem $order + * @param string $field_prefix + * @return Array + * @access public + */ + public function getUserFields(&$order, $field_prefix = 'Billing') + { + $fields_hash = Array (); + $names = explode(' ', $order->GetDBField($field_prefix . 'To'), 2); + + $fields_hash['FirstName'] = (string)getArrayValue($names, 0); + $fields_hash['LastName'] = (string)getArrayValue($names, 1); + + $order_fields = Array ( + 'Company', 'Phone', 'Fax', 'Email', 'Address1' => 'Street', + 'Address2' => 'Street2', 'City', 'State', 'Zip', 'Country' + ); + + foreach ($order_fields as $src_field => $dst_field) { + if ( is_numeric($src_field) ) { + $src_field = $dst_field; + } + + $fields_hash[$dst_field] = $order->GetDBField($field_prefix . $src_field); + } + + return $fields_hash; + } } Index: branches/5.2.x/units/orders/orders_tag_processor.php =================================================================== diff -u -N -r14821 -r14827 --- branches/5.2.x/units/orders/orders_tag_processor.php (.../orders_tag_processor.php) (revision 14821) +++ branches/5.2.x/units/orders/orders_tag_processor.php (.../orders_tag_processor.php) (revision 14827) @@ -1,6 +1,6 @@ Application->recallObject($this->Prefix . '.last'); /* @var $order OrdersItem */ - $order_prefix = $params['type'] == 'billing' ? 'Billing' : 'Shipping'; - $names = explode(' ', $order->GetDBField($order_prefix . 'To'), 2); + $order_helper =& $this->Application->recallObject('OrderHelper'); + /* @var $order_helper OrderHelper */ - if ( !$user->GetDBField('FirstName') ) { - $user->SetDBField('FirstName', getArrayValue($names, 0)); - } + $user_fields = $order_helper->getUserFields($order, $params['type'] == 'billing' ? 'Billing' : 'Shipping'); - if ( !$user->GetDBField('LastName') ) { - $user->SetDBField('LastName', getArrayValue($names, 1)); - } - - $order_fields = Array ( - 'Company', 'Phone', 'Fax', 'Email', 'Address1' => 'Street', - 'Address2' => 'Street2', 'City', 'State', 'Zip', 'Country' - ); - - foreach ($order_fields as $src_field => $dst_field) { - if ( is_numeric($src_field) ) { - $src_field = $dst_field; + foreach ($user_fields as $field => $value) { + if ( !$user->GetDBField($field) ) { + $user->SetDBField($field, $value); } - - if ( !$user->GetDBField($dst_field) ) { - $user->SetDBField($dst_field, $order->GetDBField($order_prefix . $src_field)); - } } $cs_helper =& $this->Application->recallObject('CountryStatesHelper');