Index: releases/5.2.2-B2/LICENSE =================================================================== --- releases/5.2.2-B2/LICENSE (revision 0) +++ releases/5.2.2-B2/LICENSE (revision 16630) @@ -0,0 +1,250 @@ +In-Commerce is a commecial module of In-Portal software that provides +enterprise level Online Shopping cart and store management solution. + +This is NOT a free program and protected by copyrights law. + +Copyright (C) 1997 - 2009 Intechnic. All rights reserved. + + +LICENSE & DISCLAIMERS + +INTECHNIC CORPORATION, IN-COMMERCE, IN-AUCTION + +SOFTWARE END USER LICENSE AGREEMENT + +IMPORTANT: THIS SOFTWARE END USER LICENSE AGREEMENT IS A +LEGAL AGREEMENT BETWEEN YOU (LICENSEE) AND INTECHNIC +CORPORATION. READ IT CAREFULLY BEFORE DOWNLOADING, +INSTALLING AND USING THE SOFTWARE. IT PROVIDES A LICENSE TO USE +THE SOFTWARE AND CONTAINS WARRANTY INFORMATION AND +LIABILITY DISCLAIMERS. BY DOWNLOADING, INSTALLING AND USING +THE SOFTWARE, YOU ARE CONFIRMING YOUR ACCEPTANCE OF THE +SOFTWARE AND AGREEING TO BECOME BOUND BY THE TERMS OF THIS +END USER LICENSE AGREEMENT. + + +2.1. Recitals + +(a) Intechnic is the owner of the Software and Documentation (as defined below). +(b) Intechnic desires to grant to you and you desire to obtain from Intechnic a nonexclusive +license to use the Software and Documentation solely in accordance with +the terms and on the conditions set forth in this End User License Agreement. +NOW, THEREFORE, the parties hereto agree as follows: + + +2.2. Definitions + +(a) "Intechnic" means Intechnic Corporation. +(b) "You" means Licensee, the end user of the Software: the customer purchasing or +downloading the Software. +(c) "Software" means the Intechnic In-portal software program supplied by Intechnic +herewith, which may also include online and electronic documentation. The term +"Software" also includes In-Commerce and In-Auction supplied by Intechnic herewith +in conjunction with the Intechnic In-Portal, software program. +(d) "Documentation" shall mean all manuals, user documentation, and other related +materials pertaining to the Software which are furnished to you by Intechnic in +connection with the Software. +(e) "Intechnic", "In-Commerce" and "In-Auction" are trademarks or registered +trademarks of Intechnic Corporation in the United States and/or other countries. +Other marks are the properties of their respective owners. + + +2.3. License Agreement + +Intechnic Corporation hereby grants you the right to use all or a portion of Software +accompanying this License, regardless of media, and the related Documentation. All rights +of any kind in Software, which are not expressly granted in this License, are entirely and +exclusively reserved to and by Intechnic Corporation. You may not rent, lease, reverse +engineer or create other branded software for resale based on the Software. +This License Agreement permits you to: +(a) Install and use the Software on a single computer; OR install and store the Software +on a storage device, such as a network server, used only to run or install the Software +on your other computers over an internal network, provided you have a license for +each separate computer on which the Software is installed or run from the storage +device. A license for the Software may not be shared or used concurrently on +different computers or on different servers. +(b) Make one copy of the Software in machine-readable form solely for backup +purposes. You must reproduce on any such copy all copyright notices and any other +proprietary legends on the original copy of the Software. + + +2.4. License Restrictions + +This computer program is protected by copyright law and international treaties. +Unauthorized reproduction or unlicensed usage of the code of this program, or any portion +of it may result in severe civil and criminal penalties, and will be prosecuted to the maximum +extent possible under the law. +(a) Other than as set forth in Section III, you may not make or distribute copies of the +Software, or electronically transfer the Software from one computer to another or +over a network. +(b) You may not decompile, reverse engineer, disassemble, or otherwise reduce the +obfuscated portions of the Software to a human-perceivable form. +(c) You may not rent, lease, sublicense or create other branded software for resale based +on this Software, unless expressly permitted by Intechnic Corporation. +(d) You may not export the Software into any country prohibited by the United States +Export Administration Act and the regulations hereunder. +(e) In the event that you fail to comply with this End User License Agreement, +Intechnic may terminate the license and you must destroy all copies of the Software. + + +2.5. License Term + +This license will become effective on the date you purchase the Software and will +remain in force until terminated. You may terminate the license at any time by removing the +Software from your computer and destroying the original Software and all copies. This +license will automatically terminate if you breach any of the terms or conditions set out in +this License Agreement. You agree to remove the Software from your computer, and +destroy the original Software and all copies of the Software, upon termination of this license +for any reason. + + +2.6. License Transfer + +You may transfer your license of the Software to another party by transferring the +original program media and all applicable documentation, including the original of this End +User License Agreement, to the recipient, who agrees to the terms of this End User License +Agreement. All other copies of the Software must be deleted and/or destroyed. Any +transfer of possession of the Software terminates your license and all associated benefits +under this End User License Agreement. You must notify Intechnic in writing or by e-mail +of such transfer. + + +2.7. Title and Ownership + +The foregoing license gives you limited rights to use the Software. Title, ownership +rights, and intellectual property rights, including all copyrights, in and to the Software and +documentation and derivative works, if any, shall remain the property of Intechnic +Corporation. All rights not specifically granted in this End User License Agreement, +including Federal and International Copyrights, are reserved by Intechnic Corporation +You agree to respect and not to remove, obliterate, or cancel from view any copyright, +trademark, confidentiality or other proprietary notice, mark, or legend appearing on any of +the Software or output generated by the Software, and to reproduce and include same on +each copy of the Software, unless expressly permitted by Intechnic Corporation. + + +2.8. Limited Warranty and Disclaimer. + +(a) LIMITED WARRANTY. INTECHNIC WARRANTS THAT, FOR A PERIOD +OF THIRTY (30) DAYS FROM THE DATE OF PURCHASE (AS +EVIDENCED BY A COPY OF YOUR PURCHASE RECEIPT): (I) WHEN +USED WITH A RECOMMENDED ENVIRONMENT AND HARDWARE +CONFIGURATION, THE SOFTWARE WILL PERFORM IN SUBSTANTIAL +CONFORMANCE WITH THE DOCUMENTATION SUPPLIED WITH THE +SOFTWARE; AND (II) THAT THE SOFTWARE WILL NOT BE TAMPERED +WITH OR ALTERED IN ANY WAY OR ABUSE OR MISAPPLICATION. +(b) NO OTHER WARRANTY. EXCEPT AS SET FORTH IN THE FOREGOING +LIMITED WARRANTY, INTECHNIC CORPORATION DISCLAIMS ALL +OTHER WARRANTIES, EITHER EXPRESS OR IMPLIED, OR OTHERWISE +INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE. ALSO, THERE IS NO WARRANTY OF +NONINFRINGEMENT, TITLE OR QUIET ENJOYMENT. IF APPLICABLE +LAW IMPLIES ANY WARRANTIES WITH RESPECT TO THE SOFTWARE, +ALL SUCH WARRANTIES ARE LIMITED IN DURATION TO THIRTY (30) +DAYS FROM THE DATE OF PURCHASE. NO ORAL OR WRITTEN +INFORMATION OR ADVICE GIVEN BY INTECHNIC, ITS EMPLOYEES, +DISTRIBUTORS, AGENTS OR DEALERS SHALL CREATE A WARRANTY +OR IN ANY WAY INCREASE THE SCOPE OF THIS WARRANTY. + + +2.9. Exclusive Remedy + +Intechnic Corporation offers limited and conditional refunds for downloadable +Software purchases in case the Software does not perform on the customer's server +satisfying the recommended server, hardware or environment configuration and according to +the provided documentation. Intechnic will use reasonable commercial efforts to supply you +with a replacement copy of the Software that substantially conforms to the documentation, +provide installation, configuration or programming services to fix the problem, or refund to +you your purchase price for the Software, at its option. Intechnic shall have no +responsibility if the Software has been tampered with or altered in any way, abused or +misapplied, or if the failure arises out of use of the Software with other than a recommended +server, hardware or environment configuration. + + +2.10. Limitation of Liability + +(a) IN NO EVENT SHALL INTECHNIC CORPORATION, OR ITS PRINCIPALS, +SHAREHOLDERS, OFFICERS, EMPLOYEES, AFFILIATES, CONTRACTORS, +SUBSIDIARIES, OR PARENT ORGANIZATIONS, BE LIABLE FOR ANY +INCIDENTAL, CONSEQUENTIAL, OR PUNITIVE DAMAGES +(INCLUDING DAMAGES FOR LOSS OF BUSINESS, LOSS OF PROFITS, +BUSINESS, INTERRUPTION OR THE LIKE), ARISING OUT OF THE USE +OR INABILITY TO USE THE SOFTWARE, OR THIS END USER LICENSE +AGREEMENT BASED ON ANY THEORY OF LIABILITY INCLUDING +BREACH OF CONTRACT, BREACH OF WARRANTY, TORT (INCLUDING +NEGLIGENCE), PRODUCT LIABILITY OR OTHERWISE, EVEN IF +INTECHNIC CORPORATION OR ITS REPRESENTATIVES HAVE BEEN +ADVISED OF THE POSSIBILITY OF SUCH DAMAGES AND EVEN IF A +REMEDY SET FORTH HEREIN IS FOUND TO HAVE FAILED OF ITS +ESSENTIAL PURPOSE. IN ADDITION, IN NO EVENT DOES INTECHNIC +CORPORATION AUTHORIZE YOU TO USE THE SOFTWARE IN +APPLICATIONS OR SYSTEMS WHERE THE SOFTWARE’S FAILURE TO +PERFORM CAN REASONABLY BE EXPECTED TO RESULT IN A +SIGNIFICANT PHYSICAL INJURY, OR IN LOSS OF LIFE. ANY SUCH USE +BY YOU IS ENTIRELY AT YOUR OWN RISK, AND YOU AGREE TO +HOLD INTECHNIC CORPORATION HARMLESS FROM ANY CLAIMS OR +LOSSES RELATING TO SUCH UNAUTHORIZED USE. +(b) TOTAL LIABILITY TO YOU FOR ACTUAL DAMAGES FOR ANY CAUSE +WHATSOEVER WILL BE LIMITED TO THE AMOUNT PAID BY YOU FOR +THE SOFTWARE THAT CAUSED SUCH DAMAGE. + + +2.11. Upgrades + +If this copy of the Software is an upgrade from an earlier version of the Software, it is +provided to you on a license exchange basis. You agree by installation and use of this copy +of the Software to voluntarily terminate the earlier End User License Agreement and that +you will not transfer it to another person or entity. + + +2.12. Export Controls + +You may not download or otherwise export or re-export the Software or any underlying +information or technology except in full compliance with all United States and other +applicable laws and regulations. In particular, but without limitation, none of the Software +or underlying information or technology may be downloaded or otherwise exported or reexported +(i) into (or to a national or resident of) Cuba, Haiti, Iraq, Libya, Yugoslavia, North +Korea, Iran, Syria or any other country to which the U.S. has embargoed goods; or (ii) to +anyone on the U.S. Treasury Department's list of Specially Designated Nationals or the U.S. +Commerce Department's Table of Deny Orders. By downloading or using the Software, +you are agreeing to the foregoing and you are representing and warranting that you are not +located in, under the control of, or a national or resident of any such country or on any such +list. + + +2.13. Severability + +The provisions of this Agreement shall be deemed severable, and the invalidity or +unenforceability of any one or more of the provisions hereof shall not affect the validity and +enforceability of the other provisions hereof. If any provision of this Agreement is held to +be unenforceable for any reason, such provision shall be reformed only to the extent +necessary to make it enforceable, and such decision shall not affect the enforceability (i) of +such provision under other circumstances or (ii) of the remaining provisions hereof under all +circumstances. Headings shall not be considered in interpreting this Agreement. + + +2.14. Governing Law + +This Agreement is the complete statement of the Agreement between the parties on the +subject matter, and merges and supersedes all other or prior understandings, purchase orders, +agreements and arrangements. This Agreement shall be governed by the laws of the State of +Illinois. Exclusive jurisdiction and venue for all matters relating to this Agreement shall be +in courts and fora located in the State of Illinois, and you consent to such jurisdiction and +venue. This Agreement will not be governed by the United Nations Convention of +Contracts for the International Sale of Goods, the application of which is hereby expressly +excluded. All questions concerning this should be directed to Attn. Legal Department, +Intechnic Corporation of 333 E IL 83, Suite 201, Mundelein, IL 60060. + + +2.15. U.S. Government Restricted Usage + +Use, duplication or disclosure by the Government is subject to restrictions set forth in +subparagraphs (a) through (d) of the Commercial Computer-Restricted Rights clause at FAR +52.227-19 when applicable, or in subparagraph (c)(1)(ii) of the Rights in Technical Data and +Computer, Intechnic Corporation of 333 E IL 83, Suite 201, Mundelein, IL 60060. + + +2.16. Consumer End Users Outside of the U.S. + +The limitations or exclusions of warranties and liability contained in this End User +License Agreement do not affect or prejudice the statutory rights of a consumer, i.e., a +person acquiring goods otherwise than in the course of a business. \ No newline at end of file Property changes on: releases/5.2.2-B2/LICENSE ___________________________________________________________________ Added: svn:eol-style + LF Index: releases/5.2.2-B2/constants.php =================================================================== --- releases/5.2.2-B2/constants.php (revision 0) +++ releases/5.2.2-B2/constants.php (revision 16630) @@ -0,0 +1,137 @@ +Special == 'active' ) { + /** @var kDBList $object */ + $object = $event->getObject(); + + $object->addFilter('active', '%1$s.Enabled = 1'); + } + } + + /** + * Enter description here... + * + * @param kEvent $event + */ + function OnSetPrimary($event) + { + $object = $event->getObject(); + $object->SetDBField('IsPrimary', 1); + $object->Update(); + } + + /** + * Occurs before updating item + * + * @param kEvent $event + * @return void + * @access protected + */ + protected function OnBeforeItemUpdate(kEvent $event) + { + parent::OnBeforeItemUpdate($event); + + $this->itemChanged($event); + } + + /** + * Occurs before creating item + * + * @param kEvent $event + * @return void + * @access protected + */ + protected function OnBeforeItemCreate(kEvent $event) + { + parent::OnBeforeItemCreate($event); + + $this->itemChanged($event); + } + + /** + * Occurs before item is changed + * + * @param kEvent $event + */ + function itemChanged($event) + { + /** @var kDBItem $object */ + $object = $event->getObject(); + + $live_table = $this->Application->getUnitOption($event->Prefix, 'TableName'); + $plans_count = $this->Conn->GetOne('SELECT COUNT(*) FROM ' . $live_table); + if ( !$plans_count ) { + $object->SetDBField('IsPrimary', 1); + } + + if ( $object->GetDBField('IsPrimary') && $object->Validate() ) { + $sql = 'UPDATE ' . $this->Application->getUnitOption($event->Prefix, 'TableName') . ' + SET IsPrimary = 0'; + $this->Conn->Query($sql); + + $object->SetDBField($object->getStatusField(), 1); + } + } + + /** + * Don't allow to delete primary affiliate plan + * + * @param kEvent $event + * @param string $type + * @return void + * @access protected + */ + protected function customProcessing(kEvent $event, $type) + { + if ( $event->Name == 'OnMassDelete' && $type == 'before' ) { + $ids = $event->getEventParam('ids'); + + $sql = 'SELECT ' . $this->Application->getUnitOption($event->Prefix, 'IDField') . ' + FROM ' . $this->Application->getUnitOption($event->Prefix, 'TableName') . ' + WHERE IsPrimary = 1'; + $primary_id = $this->Conn->GetOne($sql); + + $ids = array_diff($ids, Array ($primary_id)); + + $event->setEventParam('ids', $ids); + } + } + } \ No newline at end of file Property changes on: releases/5.2.2-B2/units/affiliate_plans/affiliate_plans_event_handler.php ___________________________________________________________________ Added: cvs2svn:cvs-rev + 1.9 Added: svn:keywords + Id Added: svn:eol-style + LF Index: releases/5.2.2-B2/units/affiliate_plans/affiliate_plans_config.php =================================================================== --- releases/5.2.2-B2/units/affiliate_plans/affiliate_plans_config.php (revision 0) +++ releases/5.2.2-B2/units/affiliate_plans/affiliate_plans_config.php (revision 16630) @@ -0,0 +1,126 @@ + 'ap', + 'ItemClass' => Array ('class' => 'kDBItem', 'file' => '', 'build_event' => 'OnItemBuild'), + 'ListClass' => Array ('class' => 'kDBList', 'file' => '', 'build_event' => 'OnListBuild'), + 'EventHandlerClass' => Array ('class' => 'AffiliatePlansEventHandler', 'file' => 'affiliate_plans_event_handler.php', 'build_event' => 'OnBuild'), + 'TagProcessorClass' => Array ('class' => 'kDBTagProcessor', 'file' => '', 'build_event' => 'OnBuild'), + 'AutoLoad' => true, + + 'QueryString' => Array ( + 1 => 'id', + 2 => 'Page', + 3 => 'PerPage', + 4 => 'event', + 5 => 'mode', + ), + + 'IDField' => 'AffiliatePlanId', + 'StatusField' => Array ('Enabled', 'IsPrimary'), // field, that is affected by Approve/Decline events + + 'TitleField' => 'Name', + 'TitlePresets' => Array ( + 'default' => Array ( + 'new_status_labels' => Array ('ap' => '!la_title_Adding_Affiliate_Plan!'), + 'edit_status_labels' => Array ('ap' => '!la_title_Editing_Affiliate_Plan!'), + 'new_titlefield' => Array ('ap' => '!la_title_New_Affiliate_Plan!'), + ), + + 'affiliate_plans_list' => Array ('prefixes' => Array ('ap_List'), 'format' => "!la_title_AffiliatePlans!"), + 'affiliate_plans_edit' => Array ('prefixes' => Array ('ap'), 'format' => "#ap_status# '#ap_titlefield#' - !la_title_General!"), + 'affiliate_plans_brackets' => Array ('prefixes' => Array ('ap', 'apbrackets_List'), 'format' => "#ap_status# '#ap_titlefield#' - !la_title_AffiliatePlansBrackets!"), + 'affiliate_plans_items' => Array ('prefixes' => Array ('ap', 'api_List'), 'format' => "#ap_status# '#ap_titlefield#' - !la_title_AffiliatePlansBrackets!"), + ), + + 'EditTabPresets' => Array ( + 'Default' => Array ( + 'general' => Array ('title' => 'la_tab_General', 't' => 'in-commerce/affiliate_plans/affiliate_plans_edit', 'priority' => 1), + 'brackets' => Array ('title' => 'la_tab_Brackets', 't' => 'in-commerce/affiliate_plans/affiliate_plans_brackets', 'priority' => 2), +// 'items' => Array ('title' => 'la_tab_Items', 't' => 'in-commerce/affiliate_plans/affiliate_plans_items', 'priority' => 3), + ), + ), + + 'PermSection' => Array ('main' => 'in-commerce:affiliate_plans'), + + 'Sections' => Array ( + 'in-commerce:affiliate_plans' => Array ( + 'parent' => 'in-commerce:affiliates_folder', + 'icon' => 'affiliates', + 'label' => 'la_tab_AffiliatePlans', + 'url' => Array ('t' => 'in-commerce/affiliate_plans/affiliate_plans_list', 'pass' => 'm'), + 'permissions' => Array ('view', 'add', 'edit', 'delete', 'advanced:approve', 'advanced:decline', 'advanced:set_primary'), + 'priority' => 5.2, // ., because this section replaces parent in tree + 'type' => stTAB, + ), + ), + + 'TableName' => TABLE_PREFIX.'AffiliatePlans', + + 'ListSQLs' => Array ( + '' => ' SELECT * + FROM %s' + ), + + 'SubItems' => Array ('apbrackets', /*'api'*/), + + 'ListSortings' => Array ( + '' => Array ( + 'ForcedSorting' => Array ('IsPrimary' => 'desc'), + 'Sorting' => Array ('Name' => 'desc'), + ) + ), + + 'Fields' => Array ( + 'AffiliatePlanId' => Array ('type' => 'int', 'not_null' => 1, 'default' => 0,), + 'Name' => Array ('type' => 'string', 'unique' => Array (), 'not_null' => 1, 'required' => 1, 'default' => ''), + 'PlanType' => Array ('type' => 'int', 'formatter' => 'kOptionsFormatter', 'options' => Array (/*0 => 'la_by_amount',*/ 1 => 'la_by_amount', 2 => 'la_by_items_sold'), 'use_phrases' => 1, 'required' => 1, 'not_null' => 1, 'default' => 1), + 'ResetInterval' => Array ('type' => 'int', 'formatter' => 'kOptionsFormatter', 'options' => Array (86400 => 'la_day', 604800 => 'la_week', 2628000 => 'la_month', 7884000 => 'la_quartely', 31536000 => 'la_year'), 'use_phrases' => 1, 'not_null' => 1, 'default' => 0), + 'PaymentType' => Array ('type' => 'int', 'formatter' => 'kOptionsFormatter', 'options' => Array (0 => 'la_regular', 1 => 'la_by_request'), 'use_phrases' => 1, 'not_null' => 1, 'default' => 0), + 'MinPaymentAmount' => Array ('type' => 'string', 'not_null' => 1, 'default' => ''), + 'Enabled' => Array ( + 'type' => 'int', + 'formatter' => 'kOptionsFormatter', + 'options' => Array ( 0 => 'la_Disabled', 1 => 'la_Active', ), 'use_phrases' => 1, + 'not_null' => 1, 'default' => 0, + ), + 'IsPrimary' => Array ( + 'type' => 'int', + 'formatter' => 'kOptionsFormatter', + 'options' => Array ( 0 => 'la_No', 1 => 'la_Yes', ), 'use_phrases' => 1, + 'not_null' => 1, 'default' => 0, + ), + ), + + 'Grids' => Array ( + 'Default' => Array ( + 'Icons' => Array ( + 'default' => 'icon16_item.png', + '0_0' => 'icon16_disabled.png', + '0_1' => 'icon16_disabled.png', + '1_0' => 'icon16_item.png', + '1_1' => 'icon16_primary.png', + 'module' => 'core', + ), + 'Fields' => Array ( + 'AffiliatePlanId' => Array ( 'title' => 'column:la_fld_Id', 'data_block' => 'grid_checkbox_td', 'filter_block' => 'grid_range_filter', 'width' => 60, ), + 'Name' => Array ( 'filter_block' => 'grid_like_filter', 'width' => 200, ), + 'PlanType' => Array ( 'filter_block' => 'grid_options_filter', 'width' => 150, ), + 'Enabled' => Array ( 'title' => 'column:la_fld_Status', 'filter_block' => 'grid_options_filter', 'width' => 80, ), + ), + ), + ), +); \ No newline at end of file Property changes on: releases/5.2.2-B2/units/affiliate_plans/affiliate_plans_config.php ___________________________________________________________________ Added: cvs2svn:cvs-rev + 1.28.2.1 Added: svn:keywords + Id Added: svn:eol-style + LF Index: releases/5.2.2-B2/units/affiliate_plans_items/affiliate_plans_items_tag_processor.php =================================================================== --- releases/5.2.2-B2/units/affiliate_plans_items/affiliate_plans_items_tag_processor.php (revision 0) +++ releases/5.2.2-B2/units/affiliate_plans_items/affiliate_plans_items_tag_processor.php (revision 16630) @@ -0,0 +1,48 @@ +Application->getUnitOption($this->Prefix, 'TableName'); + + if ($this->Application->IsTempMode($this->Prefix)) { + $table_name = $this->Application->GetTempName($table_name, 'prefix:' . $this->Prefix); + } + + $sql = 'SELECT COUNT(*) + FROM ' . $table_name . ' + WHERE (ItemType = 0) AND (AffiliatePlanId = ' . $this->Application->GetVar('ap_id') . ')'; + return $this->Conn->GetOne($sql); + } + + function ItemIcon($params) + { + /** @var kDBList $object */ + $object = $this->getObject($params); + + if ($object->GetDBField('ItemType') == 2) { + $cat_object = $this->Application->recallObject('c'); + $cat_object->Load( $object->GetDBField('CategoryId') ); + $cat_tag_processor = $this->Application->recallObject('c_TagProcessor'); + + return $cat_tag_processor->ItemIcon(); + } + + return parent::ItemIcon($params); + } + + } \ No newline at end of file Property changes on: releases/5.2.2-B2/units/affiliate_plans_items/affiliate_plans_items_tag_processor.php ___________________________________________________________________ Added: cvs2svn:cvs-rev + 1.2.8.1 Added: svn:keywords + Id Added: svn:eol-style + LF Index: releases/5.2.2-B2/units/affiliate_plans_items/affiliate_plans_items_event_handler.php =================================================================== --- releases/5.2.2-B2/units/affiliate_plans_items/affiliate_plans_items_event_handler.php (revision 0) +++ releases/5.2.2-B2/units/affiliate_plans_items/affiliate_plans_items_event_handler.php (revision 16630) @@ -0,0 +1,94 @@ +Application->recallObject('di_EventHandler'); + $di_handler->OnProcessSelected($event); + } + + /** + * Allows to set discount on entire order + * + * @param kEvent $event + * @todo get parent item id through $object->getLinkedInfo()['ParentId'] + * @access public + */ + function OnEntireOrder($event) + { + $object = $event->getObject(); + $sql = 'DELETE FROM '.$object->TableName.' WHERE AffiliatePlanId='.$this->Application->GetVar('ap_id'); + $this->Conn->Query($sql); + + $object->SetDBField('AffiliatePlanId', $this->Application->GetVar('ap_id')); + $object->SetDBField('ItemResourceId', -1); + $object->SetDBField('ItemType', 0); + + if ( $object->Create() ) { + $this->customProcessing($event, 'after'); + $event->status = kEvent::erSUCCESS; + $event->SetRedirectParam('opener', 's'); //stay! + } + else { + $event->status = kEvent::erFAIL; + $this->Application->SetVar($event->getPrefixSpecial().'_SaveEvent','OnCreate'); + $object->setID(0); + } + } + + /** + * Deletes discount items where hooked item (product) is used + * + * @param kEvent $event + */ + function OnDeleteDiscountedItem($event) + { + $main_object = $event->MasterEvent->getObject(); + $resource_id = $main_object->GetDBField('ResourceId'); + + $table = $this->Application->getUnitOption($event->Prefix,'TableName'); + $sql = 'DELETE FROM '.$table.' WHERE ItemResourceId = '.$resource_id; + $this->Conn->Query($sql); + } + + /** + * Makes ItemName calculated field from primary language + * + * @param kEvent $event + * @return void + * @access protected + */ + protected function OnAfterConfigRead(kEvent $event) + { + parent::OnAfterConfigRead($event); + + $calculated_fields = $this->Application->getUnitOption($event->Prefix, 'CalculatedFields'); + + $language_id = $this->Application->GetVar('m_lang'); + $primary_language_id = $this->Application->GetDefaultLanguageId(); + + $calculated_fields['']['ItemName'] = 'COALESCE(p.l' . $language_id . '_Name, p.l' . $primary_language_id . '_Name)'; + $this->Application->setUnitOption($event->Prefix, 'CalculatedFields', $calculated_fields); + } + } \ No newline at end of file Property changes on: releases/5.2.2-B2/units/affiliate_plans_items/affiliate_plans_items_event_handler.php ___________________________________________________________________ Added: cvs2svn:cvs-rev + 1.7 Added: svn:keywords + Id Added: svn:eol-style + LF Index: releases/5.2.2-B2/units/affiliate_plans_items/affiliate_plans_items_config.php =================================================================== --- releases/5.2.2-B2/units/affiliate_plans_items/affiliate_plans_items_config.php (revision 0) +++ releases/5.2.2-B2/units/affiliate_plans_items/affiliate_plans_items_config.php (revision 16630) @@ -0,0 +1,127 @@ + 'api', + 'ItemClass' => Array ('class' => 'kDBItem', 'file' => '', 'build_event' => 'OnItemBuild'), + 'ListClass' => Array ('class' => 'kDBList', 'file' => '', 'build_event' => 'OnListBuild'), + 'EventHandlerClass' => Array ('class' => 'AffiliatePlansItemsEventHandler', 'file' => 'affiliate_plans_items_event_handler.php', 'build_event' => 'OnBuild'), + 'TagProcessorClass' => Array ('class' => 'AffiliatePlansItemsTagProcessor', 'file' => 'affiliate_plans_items_tag_processor.php', 'build_event' => 'OnBuild'), + + 'AutoLoad' => true, + + 'Hooks' => Array ( + Array ( + 'Mode' => hAFTER, + 'Conditional' => false, + 'HookToPrefix' => '#PARENT#', + 'HookToSpecial' => '', + 'HookToEvent' => Array ('OnAfterItemDelete'), + 'DoPrefix' => '', + 'DoSpecial' => '', + 'DoEvent' => 'OnDeleteDiscountedItem', + ), + ), + + 'QueryString' => Array ( + 1 => 'id', + 2 => 'Page', + 3 => 'PerPage', + 4 => 'event', + ), + + 'IDField' => 'AffiliateItemId', + 'StatusField' => Array ('Status'), + 'TitleField' => 'Name', + 'TableName' => TABLE_PREFIX.'AffiliatePlansItems', + + 'CalculatedFields' => Array ( + '' => Array ( + 'ProductId' => 'p.ProductId', + 'ItemName' => 'IF(p.Name IS NULL,c.Name,p.l1_Name)', + 'SKU' => 'p.SKU', + 'Weight' => 'p.Weight', + 'CreatedOn' => 'p.CreatedOn', + 'BackOrderDate' => 'p.BackOrderDate', + 'Status' => 'p.Status', + 'CategoryId' => 'c.CategoryId', + ), + ), + + 'ListSQLs' => Array ( + '' => ' SELECT %1$s.* %2$s + FROM %1$s + LEFT JOIN '.TABLE_PREFIX.'Products p ON %1$s.ItemResourceId = p.ResourceId + LEFT JOIN '.TABLE_PREFIX.'Categories c ON %1$s.ItemResourceId = c.ResourceId', + ), + + 'ForeignKey' => 'AffiliatePlanId', + 'ParentTableKey' => 'AffiliatePlanId', + 'ParentPrefix' => 'ap', + 'AutoDelete' => true, + 'AutoClone' => true, + + 'ListSortings' => Array ( + '' => Array ( + 'Sorting' => Array ('ItemName' => 'asc'), + ) + ), + + 'Fields' => Array ( + 'AffiliateItemId' => Array ('type' => 'int', 'not_null' => 1, 'default' => 0, ), + 'AffiliatePlanId' => Array ('type' => 'int', 'not_null' => 1, 'default' => 0, ), + 'ItemResourceId' => Array ('type' => 'int', 'not_null' => 1, 'default' => 0, ), + 'ItemType' => Array ('type' => 'int', 'formatter' => 'kOptionsFormatter', 'use_phrases' => 1, 'options' => Array ( 1 => 'la_Product', 2 => 'la_Category', 0 => 'la_WholeOrder' ), 'not_null' => 1, 'default' => 1, ), + ), + + 'VirtualFields' => Array ( + 'ProductId' => Array ('type' => 'int', 'default' => 0), + 'ItemName' => Array ('type' => 'string', 'default' => ''), + 'SKU' => Array ('type' => 'string', 'default' => ''), + 'Weight' => Array ('type' => 'float', 'min_value_exc' => 0, 'formatter' => 'kFormatter', 'format' => '%0.2f', 'default' => NULL), + 'CreatedOn' => Array ('type' => 'int', 'formatter' => 'kDateFormatter', 'default' => '#NOW#'), + 'BackOrderDate' => Array ('type' => 'int', 'formatter' => 'kDateFormatter', 'default' => NULL), + 'Status' => Array ( + 'type' => 'int', + 'formatter' => 'kOptionsFormatter', + 'options' => Array (1 => 'la_Active', 2 => 'la_Pending', 0 => 'la_Disabled'), 'use_phrases' => 1, + 'default' => 2, + ), + 'CategoryId' => Array ('type' => 'int', 'default' => 0), + ), + + 'Grids' => Array ( + 'Default' => Array ( + 'Icons' => Array ('default' => 'icon16_entire_order.gif'), + 'Fields' => Array ( + 'ItemType' => Array ( 'title' => 'la_col_ItemType', 'data_block' => 'grid_checkbox_td' ), + ), + ), + + 'AffiliatePlansItems' => Array ( + 'Icons' => Array ( + 'default' => 'icon16_product.png', + 0 => 'icon16_product_disabled.png', + 1 => 'icon16_product.png', + 2 => 'icon16_product_pending.png', + ), + 'Fields' => Array ( + 'ProductId' => Array ('title' => 'column:la_fld_Id', 'data_block' => 'grid_item_checkbox_td', 'filter_block' => 'grid_range_filter'), + 'ItemName' => Array ('filter_block' => 'grid_like_filter'), + 'ItemType' => Array ('title' => 'la_col_ItemType', 'filter_block' => 'grid_options_filter'), + ), + ), + ), +); \ No newline at end of file Property changes on: releases/5.2.2-B2/units/affiliate_plans_items/affiliate_plans_items_config.php ___________________________________________________________________ Added: cvs2svn:cvs-rev + 1.6 Added: svn:keywords + Id Added: svn:eol-style + LF Index: releases/5.2.2-B2/units/gateways/gateways_config.php =================================================================== --- releases/5.2.2-B2/units/gateways/gateways_config.php (revision 0) +++ releases/5.2.2-B2/units/gateways/gateways_config.php (revision 16630) @@ -0,0 +1,92 @@ + 'gwf', + 'ItemClass' => Array ('class' => 'kDBItem', 'file' => '', 'build_event' => 'OnItemBuild'), + 'ListClass' => Array ('class' => 'kDBList', 'file' => '', 'build_event' => 'OnListBuild'), + 'EventHandlerClass' => 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 ( + Array ( + 'Mode' => hBEFORE, + 'Conditional' => false, + 'HookToPrefix' => 'pt', + 'HookToSpecial' => '', + 'HookToEvent' => Array ( 'OnListBuild' ), + 'DoPrefix' => '', + 'DoSpecial' => '', + 'DoEvent' => 'OnCheckGateways', + ), + Array ( + 'Mode' => hBEFORE, + 'Conditional' => true, + 'HookToPrefix' => 'pt', + 'HookToSpecial' => '', + 'HookToEvent' => Array ( 'OnCreate', 'OnSave', 'OnUpdate', 'onPreSaveAndGoToTab', 'onPreSaveAndGo' ), + 'DoPrefix' => '', + 'DoSpecial' => '', + 'DoEvent' => 'OnSaveValues', + ), + ), + + 'QueryString' => Array ( + 1 => 'id', + 2 => 'Page', + 3 => 'PerPage', + 4 => 'event', + ), + + 'IDField' => 'GWConfigFieldId', + 'TableName' => TABLE_PREFIX.'GatewayConfigFields', + + 'ListSQLs' => Array ( + '' => ' SELECT * + FROM %s', + ), + + 'Fields' => Array ( + 'GWConfigFieldId' => Array ('type' => 'int', 'not_null' => 1, 'default' => 0, ), + 'SystemFieldName' => Array ('type' => 'string', 'not_null' => 1, 'default' => '', ), + 'FieldName' => Array ('type' => 'string', 'required' => true, 'max_len' => 100, 'not_null' => 1, 'default' => '', ), + 'ElementType' => Array ('type' => 'string', 'not_null' => 1, 'default' => 'text', ), + 'ValueList' => Array ('type' => 'string', 'default' => NULL), + 'GatewayId' => Array ('type' => 'int', 'not_null' => 1, 'default' => 0, ), + ), + + 'VirtualFields' => Array ( + 'Value' => Array ('type' => 'string', 'default' => ''), + ), +); Property changes on: releases/5.2.2-B2/units/gateways/gateways_config.php ___________________________________________________________________ Added: cvs2svn:cvs-rev + 1.9 Added: svn:keywords + Id Added: svn:eol-style + LF Index: releases/5.2.2-B2/units/gateways/gw_event_handler.php =================================================================== --- releases/5.2.2-B2/units/gateways/gw_event_handler.php (revision 0) +++ releases/5.2.2-B2/units/gateways/gw_event_handler.php (revision 16630) @@ -0,0 +1,85 @@ +getPassedID($event); + $event->setPseudoClass('_List'); + + $items_info = $this->Application->GetVar( $event->getPrefixSpecial(true) ); + $PaymentType_info = $this->Application->GetVar( 'pt' ); + $GWConfigValue = $this->Application->recallObject('gwfv'); + $GWConfigValue->SetDBField('PaymentTypeId', $this->Application->GetVar('pt_id')); + + //deleting old values + $sql = 'DELETE FROM '.$GWConfigValue->TableName.' WHERE PaymentTypeId = '.$this->Application->GetVar('pt_id'); + $res = $this->Conn->Query($sql); + + //selecting fields for selected gateway only + $sql = 'SELECT GWConfigFieldId FROM '.TABLE_PREFIX.'GatewayConfigFields + WHERE GatewayId = '.$PaymentType_info[$this->Application->GetVar('pt_id')]['GatewayId']; + $res = $this->Conn->GetCol($sql); + + if($items_info) + { + foreach($res as $gw_field_id) + { + $field_values = $items_info[$gw_field_id]; + $field_values['GWConfigFieldId'] = $gw_field_id; + + $GWConfigValue->SetFieldsFromHash($field_values); + if( $GWConfigValue->Create() ) + { + $event->status=kEvent::erSUCCESS; + } + else + { + $event->status=kEvent::erFAIL; + break; + } + } + } + } + + protected function OnCheckGateways($event) + { + if ( !$this->Application->isAdminUser ) { + return; + } + + $gateways = glob(GW_CLASS_PATH . DIRECTORY_SEPARATOR . '*.php'); + + if ( !$gateways ) { + return; + } + + foreach ($gateways as $gateway_file) { + $class_name = false; + include_once($gateway_file); + + if ( !$class_name ) { + continue; + } + + /** @var kGWBase $tmp */ + $tmp = new $class_name(); + + $tmp->Install(); + } + } +} \ No newline at end of file Property changes on: releases/5.2.2-B2/units/gateways/gw_event_handler.php ___________________________________________________________________ Added: cvs2svn:cvs-rev + 1.6.2.1 Added: svn:keywords + Id Added: svn:eol-style + LF Index: releases/5.2.2-B2/units/gateways/gw_classes/notify_scripts/google_checkout_notify.php =================================================================== --- releases/5.2.2-B2/units/gateways/gw_classes/notify_scripts/google_checkout_notify.php (revision 0) +++ releases/5.2.2-B2/units/gateways/gw_classes/notify_scripts/google_checkout_notify.php (revision 16630) @@ -0,0 +1,50 @@ +Init(); + + $sql = 'SELECT PaymentTypeId FROM '.TABLE_PREFIX.'PaymentTypes AS pt + LEFT JOIN '.TABLE_PREFIX.'Gateways AS g ON g.GatewayId = pt.GatewayId + WHERE g.ClassName = "kGWGoogleCheckout"'; + $payment_type_id = $application->Conn->GetOne($sql); + + $application->SetVar('payment_type_id', $payment_type_id); // keep, because kGWGoogleCheckout::processNewOrderNotification relies on this + + /** @var OrdersItem $order */ + $order = $application->recallObject('ord', null, Array ('skip_autoload' => true)); + + $gw_data = $order->getGatewayData($application->GetVar('payment_type_id')); + $application->registerClass( $gw_data['ClassName'], GW_CLASS_PATH.'/'.$gw_data['ClassFile'] ); + $gateway_object = $application->recallObject( $gw_data['ClassName'] ); + + $transaction_status = $gateway_object->processNotification($gw_data['gw_params']); + + $sql = 'UPDATE '.$order->TableName.' + SET TransactionStatus = '.$transaction_status.' + WHERE '.$order->IDField.' = '.$order->GetID(); + $application->Conn->Query($sql); + + $order->SetDBField('TransactionStatus', $transaction_status); + + if ($transaction_status == 1) { + $application->SetVar('ord_id', $order->GetID()); // used in OrdersEventHandler::UpdateOrderItem + $application->HandleEvent(new kEvent('ord:OnCompleteOrder')); + } + + $application->Done(); \ No newline at end of file Property changes on: releases/5.2.2-B2/units/gateways/gw_classes/notify_scripts/google_checkout_notify.php ___________________________________________________________________ Added: cvs2svn:cvs-rev + 1.1.2.2 Added: svn:keywords + Id Added: svn:eol-style + LF Index: releases/5.2.2-B2/units/gateways/gw_classes/notify_scripts/sella_error.php =================================================================== --- releases/5.2.2-B2/units/gateways/gw_classes/notify_scripts/sella_error.php (revision 0) +++ releases/5.2.2-B2/units/gateways/gw_classes/notify_scripts/sella_error.php (revision 16630) @@ -0,0 +1,31 @@ +Init(); + + $application->SetVar('sella_error', 1); + + $application->SetVar('payment_type_id', + $application->Conn->GetOne( + 'SELECT PaymentTypeId FROM '.TABLE_PREFIX.'PaymentTypes AS pt + LEFT JOIN '.TABLE_PREFIX.'Gateways AS g + ON g.GatewayId = pt.GatewayId + WHERE g.ClassName = '.$application->Conn->qstr('kSellaGuestPayGW'))); + + include(MODULES_PATH.'/in-commerce/gw_notify.php'); \ No newline at end of file Property changes on: releases/5.2.2-B2/units/gateways/gw_classes/notify_scripts/sella_error.php ___________________________________________________________________ Added: cvs2svn:cvs-rev + 1.3 Added: svn:keywords + Id Added: svn:eol-style + LF Index: releases/5.2.2-B2/units/gateways/gw_classes/notify_scripts/sella_ok.php =================================================================== --- releases/5.2.2-B2/units/gateways/gw_classes/notify_scripts/sella_ok.php (revision 0) +++ releases/5.2.2-B2/units/gateways/gw_classes/notify_scripts/sella_ok.php (revision 16630) @@ -0,0 +1,31 @@ +Init(); + + $application->SetVar('sella_ok', 1); + + $application->SetVar('payment_type_id', + $application->Conn->GetOne( + 'SELECT PaymentTypeId FROM '.TABLE_PREFIX.'PaymentTypes AS pt + LEFT JOIN '.TABLE_PREFIX.'Gateways AS g + ON g.GatewayId = pt.GatewayId + WHERE g.ClassName = '.$application->Conn->qstr('kSellaGuestPayGW'))); + + include(MODULES_PATH.'/in-commerce/gw_notify.php'); \ No newline at end of file Property changes on: releases/5.2.2-B2/units/gateways/gw_classes/notify_scripts/sella_ok.php ___________________________________________________________________ Added: cvs2svn:cvs-rev + 1.3 Added: svn:keywords + Id Added: svn:eol-style + LF Index: releases/5.2.2-B2/units/gateways/gw_classes/notify_scripts/paybox_notify.php =================================================================== --- releases/5.2.2-B2/units/gateways/gw_classes/notify_scripts/paybox_notify.php (revision 0) +++ releases/5.2.2-B2/units/gateways/gw_classes/notify_scripts/paybox_notify.php (revision 16630) @@ -0,0 +1,29 @@ +Init(); + + $application->SetVar('payment_type_id', + $application->Conn->GetOne( + 'SELECT PaymentTypeId FROM '.TABLE_PREFIX.'PaymentTypes AS pt + LEFT JOIN '.TABLE_PREFIX.'Gateways AS g + ON g.GatewayId = pt.GatewayId + WHERE g.ClassName = '.$application->Conn->qstr('kPayboxGW'))); + + include(MODULES_PATH.'/in-commerce/gw_notify.php'); \ No newline at end of file Property changes on: releases/5.2.2-B2/units/gateways/gw_classes/notify_scripts/paybox_notify.php ___________________________________________________________________ Added: cvs2svn:cvs-rev + 1.2 Added: svn:keywords + Id Added: svn:eol-style + LF Index: releases/5.2.2-B2/units/gateways/gw_classes/notify_scripts/multicards_notify.php =================================================================== --- releases/5.2.2-B2/units/gateways/gw_classes/notify_scripts/multicards_notify.php (revision 0) +++ releases/5.2.2-B2/units/gateways/gw_classes/notify_scripts/multicards_notify.php (revision 16630) @@ -0,0 +1,29 @@ +Init(); + + $application->SetVar('payment_type_id', + $application->Conn->GetOne( + 'SELECT PaymentTypeId FROM '.TABLE_PREFIX.'PaymentTypes AS pt + LEFT JOIN '.TABLE_PREFIX.'Gateways AS g + ON g.GatewayId = pt.GatewayId + WHERE g.ClassName = '.$application->Conn->qstr('kMultiCardsGW'))); + + include(MODULES_PATH.'/in-commerce/gw_notify.php'); \ No newline at end of file Property changes on: releases/5.2.2-B2/units/gateways/gw_classes/notify_scripts/multicards_notify.php ___________________________________________________________________ Added: cvs2svn:cvs-rev + 1.3 Added: svn:keywords + Id Added: svn:eol-style + LF Index: releases/5.2.2-B2/units/gateways/gw_classes/notify_scripts/verisign_pflink_notify.php =================================================================== --- releases/5.2.2-B2/units/gateways/gw_classes/notify_scripts/verisign_pflink_notify.php (revision 0) +++ releases/5.2.2-B2/units/gateways/gw_classes/notify_scripts/verisign_pflink_notify.php (revision 16630) @@ -0,0 +1,29 @@ +Init(); + + $application->SetVar('payment_type_id', + $application->Conn->GetOne( + 'SELECT PaymentTypeId FROM '.TABLE_PREFIX.'PaymentTypes AS pt + LEFT JOIN '.TABLE_PREFIX.'Gateways AS g + ON g.GatewayId = pt.GatewayId + WHERE g.ClassName = '.$application->Conn->qstr('kVerisignPfLinkGW'))); + + include(MODULES_PATH.'/in-commerce/gw_notify.php'); \ No newline at end of file Property changes on: releases/5.2.2-B2/units/gateways/gw_classes/notify_scripts/verisign_pflink_notify.php ___________________________________________________________________ Added: cvs2svn:cvs-rev + 1.3 Added: svn:keywords + Id Added: svn:eol-style + LF Index: releases/5.2.2-B2/units/gateways/gw_classes/notify_scripts/.htaccess =================================================================== --- releases/5.2.2-B2/units/gateways/gw_classes/notify_scripts/.htaccess (revision 0) +++ releases/5.2.2-B2/units/gateways/gw_classes/notify_scripts/.htaccess (revision 16630) @@ -0,0 +1 @@ +allow from all \ No newline at end of file Property changes on: releases/5.2.2-B2/units/gateways/gw_classes/notify_scripts/.htaccess ___________________________________________________________________ Added: svn:eol-style + LF Index: releases/5.2.2-B2/units/gateways/gw_classes/notify_scripts/google_checkout_shippings.php =================================================================== --- releases/5.2.2-B2/units/gateways/gw_classes/notify_scripts/google_checkout_shippings.php (revision 0) +++ releases/5.2.2-B2/units/gateways/gw_classes/notify_scripts/google_checkout_shippings.php (revision 16630) @@ -0,0 +1,38 @@ +Init(); + + $sql = 'SELECT PaymentTypeId FROM '.TABLE_PREFIX.'PaymentTypes AS pt + LEFT JOIN '.TABLE_PREFIX.'Gateways AS g ON g.GatewayId = pt.GatewayId + WHERE g.ClassName = "kGWGoogleCheckout"'; + $payment_type_id = $application->Conn->GetOne($sql); + + /** @var OrdersItem $order */ + $order = $application->recallObject('ord', null, Array ('skip_autoload' => true)); + + $gw_data = $order->getGatewayData($payment_type_id); + $application->registerClass( $gw_data['ClassName'], GW_CLASS_PATH.'/'.$gw_data['ClassFile'] ); + + /** @var kGWGoogleCheckout $gateway_object */ + $gateway_object = $application->recallObject( $gw_data['ClassName'] ); + + $gateway_object->processNotification($gw_data['gw_params'], 'shippings'); + + $application->Done(); \ No newline at end of file Property changes on: releases/5.2.2-B2/units/gateways/gw_classes/notify_scripts/google_checkout_shippings.php ___________________________________________________________________ Added: cvs2svn:cvs-rev + 1.1.2.1 Added: svn:keywords + Id Added: svn:eol-style + LF Index: releases/5.2.2-B2/units/gateways/gw_classes/notify_scripts/atosorigin_notify.php =================================================================== --- releases/5.2.2-B2/units/gateways/gw_classes/notify_scripts/atosorigin_notify.php (revision 0) +++ releases/5.2.2-B2/units/gateways/gw_classes/notify_scripts/atosorigin_notify.php (revision 16630) @@ -0,0 +1,29 @@ +Init(); + + $application->SetVar('payment_type_id', + $application->Conn->GetOne( + 'SELECT PaymentTypeId FROM '.TABLE_PREFIX.'PaymentTypes AS pt + LEFT JOIN '.TABLE_PREFIX.'Gateways AS g + ON g.GatewayId = pt.GatewayId + WHERE g.ClassName = '.$application->Conn->qstr('kAtosOriginGW'))); + + include(MODULES_PATH.'/in-commerce/gw_notify.php'); \ No newline at end of file Property changes on: releases/5.2.2-B2/units/gateways/gw_classes/notify_scripts/atosorigin_notify.php ___________________________________________________________________ Added: cvs2svn:cvs-rev + 1.4 Added: svn:keywords + Id Added: svn:eol-style + LF Index: releases/5.2.2-B2/units/gateways/gw_classes/notify_scripts/sella_notify.php =================================================================== --- releases/5.2.2-B2/units/gateways/gw_classes/notify_scripts/sella_notify.php (revision 0) +++ releases/5.2.2-B2/units/gateways/gw_classes/notify_scripts/sella_notify.php (revision 16630) @@ -0,0 +1,29 @@ +Init(); + + $application->SetVar('payment_type_id', + $application->Conn->GetOne( + 'SELECT PaymentTypeId FROM '.TABLE_PREFIX.'PaymentTypes AS pt + LEFT JOIN '.TABLE_PREFIX.'Gateways AS g + ON g.GatewayId = pt.GatewayId + WHERE g.ClassName = '.$application->Conn->qstr('kSellaGuestPayGW'))); + + include(MODULES_PATH.'/in-commerce/gw_notify.php'); \ No newline at end of file Property changes on: releases/5.2.2-B2/units/gateways/gw_classes/notify_scripts/sella_notify.php ___________________________________________________________________ Added: cvs2svn:cvs-rev + 1.3 Added: svn:keywords + Id Added: svn:eol-style + LF Index: releases/5.2.2-B2/units/gateways/gw_classes/verisign_pflink.php =================================================================== --- releases/5.2.2-B2/units/gateways/gw_classes/verisign_pflink.php (revision 0) +++ releases/5.2.2-B2/units/gateways/gw_classes/verisign_pflink.php (revision 16630) @@ -0,0 +1,137 @@ + Array('Name' => 'Verisign Payflow Link', 'ClassName' => 'kVerisignPfLinkGW', 'ClassFile' => 'verisign_pflink.php', 'RequireCCFields' => 0), + 'ConfigFields' => Array( + 'submit_url' => Array('Name' => 'Submit URL', 'Type' => 'text', 'ValueList' => '', 'Default' => 'https://payments.verisign.com/payflowlink'), + 'login' => Array('Name' => 'Login', 'Type' => 'text', 'ValueList' => '', 'Default' => ''), + 'partner' => Array('Name' => 'Partner', 'Type' => 'text', 'ValueList' => '', 'Default' => ''), + 'transaction_type' => Array('Name' => 'Transaction Type (S/A)', 'Type' => 'text', 'ValueList' => '', 'Default' => 'S'), + 'shipping_control' => Array('Name' => 'Shipping Control', 'Type' => 'select', 'ValueList' => '3=la_CreditDirect,4=la_CreditPreAuthorize', 'Default' => '3'), + ) + ); + return $data; + } + + /** + * Returns payment form submit url + * + * @param Array $gw_params gateway params from payment type config + * @return string + */ + function getFormAction($gw_params) + { + return $gw_params['submit_url']; + } + + /** + * Processed input data and convets it to fields understandable by gateway + * + * @param Array $item_data + * @param Array $tag_params additional params for gateway passed through tag + * @param Array $gw_params gateway params from payment type config + * @return Array + */ + function getHiddenFields($item_data, $tag_params, $gw_params) + { + $params['LOGIN'] = $gw_params['login']; + $params['PARTNER'] = $gw_params['partner']; + $params['TYPE'] = $gw_params['transaction_type']; + + $params['AMOUNT'] = $item_data['TotalAmount']; + + + $billing_email = $item_data['BillingEmail']; + if (!$billing_email) { + $billing_email = $this->Conn->GetOne(' SELECT Email FROM '.$this->Application->getUnitOption('u', 'TableName').' + WHERE PortalUserId = '.$this->Application->RecallVar('user_id')); + } + + $params['NAME'] = $item_data['BillingTo']; + $params['PHONE'] = $item_data['BillingPhone']; + $params['ADDRESS'] = $item_data['BillingAddress1'] . ' ' . $item_data['BillingAddress2']; + $params['CITY'] = $item_data['BillingCity']; + $params['ZIP'] = $item_data['BillingZip']; + $params['COUNTRY'] = $item_data['BillingCountry']; + $params['EMAIL'] = $billing_email; + + $params['COMMENT1'] = ''; + + $params['DESCRIPTION'] = 'Order #'.$item_data['OrderNumber']; + + $params['INVOICE'] = $item_data['OrderNumber']; + + $params['CUSTID'] = $item_data['PortalUserId']; + $params['USER1'] = $item_data['OrderId']; + $params['USER2'] = $this->Application->GetSID(); + + return $params; + } + + function processNotification($gw_params) + { + $result = $this->parseGWResponce($_POST, $gw_params); + + $session = $this->Application->recallObject('Session'); + $session->SID = $_POST['USER2']; + + $order_id = $this->Conn->GetOne('SELECT OrderId FROM '.TABLE_PREFIX.'Orders WHERE OrderId = '.$_POST['USER1']); + $this->Application->SetVar('ord_id', $order_id); + $order = $this->Application->recallObject('ord'); + $order->Load($order_id); + + define('ADMIN', 1); + if (!$this->Application->GetVar('silent')) { + if ($result['RESULT'] == '0') { + $this->Application->Redirect('in-commerce/checkout/checkout_success', array('pass'=>'m', 'm_cat_id'=>0), '_FRONT_END_', 'index.php'); + } + else { + $this->Application->StoreVar('gw_error', $this->getErrorMsg()); + $this->Application->Redirect('in-commerce/checkout/billing', array('pass'=>'m', 'm_cat_id'=>0), '_FRONT_END_', 'index.php'); + } + } + + return $result['RESULT'] == '0' ? 1 : 0; + } + + function parseGWResponce($res, $gw_params) + { + $this->parsed_responce = $res; + return $res; + } + + function getGWResponce() + { + return serialize($this->parsed_responce); + } + + function getErrorMsg() + { + $msg = $this->parsed_responce['RESPMSG']; + if (!$msg) { + if ($this->parsed_responce['RESULT'] != '0') { + $msg = 'Transaction failed'; + } + } + return $msg; + } + } \ No newline at end of file Property changes on: releases/5.2.2-B2/units/gateways/gw_classes/verisign_pflink.php ___________________________________________________________________ Added: cvs2svn:cvs-rev + 1.3 Added: svn:keywords + Id Added: svn:eol-style + LF Index: releases/5.2.2-B2/units/gateways/gw_classes/paymentech.php =================================================================== --- releases/5.2.2-B2/units/gateways/gw_classes/paymentech.php (revision 0) +++ releases/5.2.2-B2/units/gateways/gw_classes/paymentech.php (revision 16630) @@ -0,0 +1,327 @@ + Array('Name' => 'Patmentech/Orbital', 'ClassName' => 'kPaymentechGW', 'ClassFile' => 'paymentech.php', 'RequireCCFields' => 1), + 'ConfigFields' => Array( + 'submit_url' => Array('Name' => 'Submit URL', 'Type' => 'text', 'ValueList' => '', 'Default' => ''), + 'user_account' => Array('Name' => 'Merchant ID', 'Type' => 'text', 'ValueList' => '', 'Default' => ''), + 'user_bin' => Array('Name' => 'BIN Number', 'Type' => 'text', 'ValueList' => '', 'Default' => ''), + 'shipping_control' => Array('Name' => 'Shipping Control', 'Type' => 'select', 'ValueList' => '3=la_CreditDirect,4=la_CreditPreAuthorize', 'Default' => '3'), + 'deny_cvv' => Array('Name' => 'Decline the following CVV response codes (ex: N,P)', 'Type' => 'text', 'ValueList' => '', 'Default' => 'N,P,S'), + 'deny_avs' => Array('Name' => 'Decline the following AVS response codes (ex: 1,3,R,5,6,G)', 'Type' => 'text', 'ValueList' => '', 'Default' => '1,2,3,4,R,5,6,7,8,A,C,D,E,F,G,Z'), + ) + ); + return $data; + } + + function DirectPayment($item_data, $gw_params) + { + // if( $this->IsTestMode() ) $post_fields['x_test_request'] = 'True'; + + $data = array( + //sys default + 'TzCode' => 705, + 'CurrencyCode' => 840, + 'CurrencyExponent' => 2, + 'TxDateTime' => '', //gateway will set current timestamp + + //merchant info + 'MerchantID' => $gw_params['user_account'], + 'BIN' => $gw_params['user_bin'], + + //transaction + // A - Authorize Only // AC - Authorize & Capture // C - Prior Auth Capture + 'MessageType' => $gw_params['shipping_control'] == SHIPPING_CONTROL_PREAUTH ? 'A' : 'AC', + + 'Amount' => str_replace('.', '', sprintf('%.2f', $item_data['TotalAmount'])), + 'AccountNum' => $item_data['PaymentAccount'], //card num + 'Exp' => str_replace('/', '', $item_data['PaymentCCExpDate']), //expiration + 'CardSecVal' => $item_data['PaymentCVV2'], //cvv2 + + //customer info + 'AVSname' => $item_data['PaymentNameOnCard'], + 'AVSaddress1' => $item_data['BillingAddress1'], + 'AVSaddress2' => $item_data['BillingAddress2'], + 'AVScity' => $item_data['BillingCity'], + 'AVSstate' => $item_data['BillingState'], + 'AVSzip' => $item_data['BillingZip'], + + // order info + 'OrderID' => $item_data['OrderNumber'], + 'ECOrderNum' => $item_data['OrderNumber'], + 'Comments' => 'Invoice #'.$item_data['OrderNumber'], + 'ShippingRef' => '', + ); + + /** @var kCountryStatesHelper $cs_helper */ + $cs_helper = $this->Application->recallObject('CountryStatesHelper'); + + $data['AVScountryCode'] = $cs_helper->getCountryIso( $item_data['BillingCountry'] ); + + if ($data['AVScountryCode'] != 'US') { + $data['AVSstate'] = ''; + } + + $headers = Array( + 'POST /AUTHORIZE HTTP/1.0', + 'MIME-Version: 1.0', + 'Content-type: application/PTI34', + 'Content-transfer-encoding: text', + 'Request-number: 1', + 'Document-type: Request' + ); + $xml = $this->PrepareXML($data); + + $this->setGWResponce($gw_params, $headers, $xml); + $gw_responce = $this->parseGWResponce(null, $gw_params); + + $this->CheckCVV_AVS($gw_params); + return ($this->parsed_responce['ProcStatus'] != 0 || $this->parsed_responce['ApprovalStatus'] != 1) ? false : true; + } + + function CheckCVV_AVS($gw_params) + { + $cvv_reject = explode(',', $gw_params['deny_cvv']); + if (in_array(trim($this->parsed_responce['CVV2RespCode']), $cvv_reject)) { + $this->parsed_responce['ApprovalStatus'] = 0; + } + $avs_reject = explode(',', $gw_params['deny_avs']); + if (in_array(trim($this->parsed_responce['AVSRespCode']), $avs_reject)) { + $this->parsed_responce['ApprovalStatus'] = 0; + } + } + + /** + * Perform SALE type transaction direct from php script wihtout redirecting to 3rd-party website + * + * @param Array $item_data + * @param Array $gw_params + * @return bool + */ + function Charge($item_data, $gw_params) + { + $gw_responce = unserialize( $item_data['GWResult1'] ); + + if( ( strtoupper($gw_responce['MessageType']) == 'A') ) + { + $data = array( + //sys default + 'TzCode' => 705, + 'CurrencyCode' => 840, + 'CurrencyExponent' => 2, + 'TxDateTime' => '', //gateway will set current timestamp + + //merchant info + 'MerchantID' => $gw_params['user_account'], + 'BIN' => $gw_params['user_bin'], + + //transaction + // A - Authorize Only // AC - Authorize & Capture // C - Prior Auth Capture + 'Amount' => str_replace('.', '', sprintf('%.2f', $item_data['TotalAmount'])), + 'MessageType' => 'C', + 'OrderID' => $gw_responce['OrderID'], + 'TxRefNum' => $gw_responce['TxRefNum'], + ); + + $headers = Array( + 'POST /AUTHORIZE HTTP/1.0', + 'MIME-Version: 1.0', + 'Content-type: application/PTI34', + 'Content-transfer-encoding: text', + 'Request-number: 1', + 'Document-type: Request' + ); + + $xml = $this->PrepareXML($data); + + $this->setGWResponce($gw_params, $headers, $xml); + $gw_responce = $this->parseGWResponce(null, $gw_params); + + return ($gw_responce['ProcStatus'] != 0 || $gw_responce['ApprovalStatus'] != 1) ? false : true; + } + else + { + return true; + } + } + + function setGWResponce($gw_params, $headers, $xml) + { + /** @var kCurlHelper $curl_helper */ + $curl_helper = $this->Application->recallObject('CurlHelper'); + + $curl_helper->SetHeaders($headers); + $curl_helper->SetPostData($xml); + + $this->gw_responce = $curl_helper->Send( $gw_params['submit_url'] ); + } + + /** + * Parse previosly saved gw responce into associative array + * + * @param string $gw_responce + * @param Array $gw_params + * @return Array + */ + function parseGWResponce($gw_responce = null, $gw_params) + { + if( !isset($gw_responce) ) $gw_responce = $this->gw_responce; + + $parser = $this->Application->recallObject('kXMLHelper'); + $parser->Clear(); + $res = $parser->Parse($gw_responce); + + $parsed = array(); + $parsed['ProcStatus'] = $res->FindChildValue('ProcStatus'); + $parsed['StatusMsg'] = $res->FindChildValue('StatusMsg'); + + $parsed['ApprovalStatus'] = $res->FindChildValue('ApprovalStatus'); + $parsed['RespCode'] = $res->FindChildValue('RespCode'); + $parsed['AuthCode'] = $res->FindChildValue('AuthCode'); + $parsed['AVSRespCode'] = $res->FindChildValue('AVSRespCode'); + $parsed['CVV2RespCode'] = $res->FindChildValue('CVV2RespCode'); + $parsed['StatusMsg'] = $res->FindChildValue('StatusMsg'); + $parsed['RespMsg'] = $res->FindChildValue('RespMsg'); + $parsed['TxRefNum'] = $res->FindChildValue('TxRefNum'); + $parsed['TxRefIdx'] = $res->FindChildValue('TxRefIdx'); + $parsed['RespTime'] = $res->FindChildValue('RespTime'); + $parsed['Amount'] = $res->FindChildValue('Amount'); + $parsed['OrderID'] = $res->FindChildValue('OrderNumber'); + + $parsed['MessageType'] = $res->FindChildValue('CommonMandatoryResponse', 'MessageType'); + + $this->parsed_responce = $parsed; + return $parsed; + } + + function getErrorMsg() + { + $code = $this->parsed_responce['ApprovalStatus']; + switch ($this->parsed_responce['ApprovalStatus']) { + case '0': + return 'The transaction has been declined'; + case '1': + return 'The transaction has been approved'; + default: + return 'An error has occured while processing the transaction ('.$this->parsed_responce['StatusMsg'].')'; + } + + } + + function getGWResponce() + { + return serialize($this->parsed_responce); + } + + function GetTestCCNumbers() + { + return array('4012888888881', '4055011111111111', '5454545454545454', '5405222222222226', '371449635398431', + '6011000995500000', '36438999960016', '3566002020140006'); + } + + function PrepareXML($data) + { + if ($data['MessageType'] == 'A' || + $data['MessageType'] == 'AC') { + $xml = << + + + + + {$data['AccountNum']} + + {$data['MerchantID']} + 001 + {$data['BIN']} + {$data['OrderID']} + + {$data['Amount']} + + + + + + {$data['Exp']} + + + {$data['TxDateTime']} + + + {$data['Comments']} + {$data['ShippingRef']} + {$data['CardSecVal']} + + {$data['ECOrderNum']} + + + + + + + + {$data['AVSname']} + {$data['AVSaddress1']} + {$data['AVSaddress2']} + {$data['AVScity']} + {$data['AVSstate']} + {$data['AVSzip']} + + + + + + 02 + + + + + +END_XML; + } + elseif ($data['MessageType'] == 'C') { + $xml = << + + + + + {$data['MerchantID']} + 001 + {$data['BIN']} + {$data['OrderID']} + + {$data['Amount']} + + {$data['TxDateTime']} + + + {$data['TxRefNum']} + + + + +END_XML; + } + return $xml; + } + } \ No newline at end of file Property changes on: releases/5.2.2-B2/units/gateways/gw_classes/paymentech.php ___________________________________________________________________ Added: cvs2svn:cvs-rev + 1.4 Added: svn:keywords + Id Added: svn:eol-style + LF Index: releases/5.2.2-B2/units/gateways/gw_classes/atosorigin.php =================================================================== --- releases/5.2.2-B2/units/gateways/gw_classes/atosorigin.php (revision 0) +++ releases/5.2.2-B2/units/gateways/gw_classes/atosorigin.php (revision 16630) @@ -0,0 +1,192 @@ + Array('Name' => 'Atos Origin', 'ClassName' => 'kAtosOriginGW', 'ClassFile' => 'atosorigin.php', 'RequireCCFields' => 0), + 'ConfigFields' => Array( + 'request_binary' => Array('Name' => 'API Request Executable', 'Type' => 'text', 'ValueList' => '', 'Default' => ''), + 'response_binary' => Array('Name' => 'API Response Executable', 'Type' => 'text', 'ValueList' => '', 'Default' => ''), + 'pathfile' => Array('Name' => 'Pathfile', 'Type' => 'text', 'ValueList' => '', 'Default' => ''), + 'merchant_id' => Array('Name' => 'Merchant ID', 'Type' => 'text', 'ValueList' => '', 'Default' => ''), + 'merchant_country' => Array('Name' => 'Merchant Country Code', 'Type' => 'text', 'ValueList' => '', 'Default' => ''), + 'currency_code' => Array('Name' => 'Currency Code', 'Type' => 'text', 'ValueList' => '', 'Default' => '978'), + 'shipping_control' => Array('Name' => 'Shipping Control', 'Type' => 'select', 'ValueList' => '3=la_CreditDirect,4=la_CreditPreAuthorize', 'Default' => '3'), + ) + ); + return $data; + } + + /** + * Returns payment form submit url + * + * @param Array $gw_params gateway params from payment type config + * @return string + */ + function getFormAction($gw_params) + { + return $gw_params['submit_url']; + } + + /** + * Processed input data and convets it to fields understandable by gateway + * + * @param Array $item_data + * @param Array $tag_params additional params for gateway passed through tag + * @param Array $gw_params gateway params from payment type config + * @return Array + */ + function getHiddenFields($item_data, $tag_params, $gw_params) + { + $params['pathfile'] = $gw_params['pathfile']; + $params['merchant_id'] = $gw_params['merchant_id']; + $params['merchant_country'] = $gw_params['merchant_country']; + $params['currency_code'] = $gw_params['currency_code']; + $params['currency_code'] = $gw_params['currency_code']; + + $params['normal_return_url'] = $this->Application->HREF($tag_params['return_template'],'',Array('pass'=>'m')); + $params['cancel_return_url'] = $this->Application->HREF($tag_params['cancel_template'],'',Array('pass'=>'m')); + $params['automatic_response_url'] = $this->getNotificationUrl('units/gateways/gw_classes/notify_scripts/atosorigin_notify.php'); + + $txt_amount = sprintf("%.2f", $item_data['TotalAmount']); + + $params['amount'] = str_replace( Array('.', ','), '', $txt_amount); + $params['caddie'] = $this->Application->GetSID() . ',' . MD5($item_data['OrderId']); + $params['order_id'] = $item_data['OrderId']; + $params['customer_ip_address'] = $this->Application->getClientIp(); + $params['customer_id'] = $item_data['PortalUserId']; + + $billing_email = $item_data['BillingEmail']; + if (!$billing_email) { + $billing_email = $this->Conn->GetOne(' SELECT Email FROM '.$this->Application->getUnitOption('u', 'TableName').' + WHERE PortalUserId = '.$this->Application->RecallVar('user_id')); + } + $params['customer_email'] = $billing_email; + + $params_str = ''; + foreach ($params as $key => $val) { + $params_str .= ' '.$key . '="'.$val.'"'; + } + $run_line = $gw_params['request_binary'].' '.$params_str; + +// $run_line = escapeshellcmd($run_line); +// echo $run_line; + + exec ($run_line, $rets); + + $ret = $rets[0]; + + $ret = preg_replace('/^(.*)!!/is', '', $ret); + $ret = rtrim($ret, '!'); + + return ''.$ret.'
'; + } + + function NeedPlaceButton($item_data, $tag_params, $gw_params) + { + return false; + } + + function processNotification($gw_params) + { + $params['pathfile'] = $gw_params['pathfile']; + $params['message'] = $_POST['DATA']; + + $params_str = ''; + foreach ($params as $key => $val) { + $params_str .= ' '.$key . '="'.$val.'"'; + } + $run_line = $gw_params['response_binary'].' '.$params_str; + + exec ($run_line, $rets); + $ret = $rets[0]; + + $result = $this->parseGWResponce($ret, $gw_params); + + list ($sid, $auth_code) = explode(',', $result['caddie']); + $session = $this->Application->recallObject('Session'); + $session->SID = $sid; + + $order_id = $this->Conn->GetOne('SELECT OrderId FROM '.TABLE_PREFIX.'Orders WHERE md5(OrderId) = '.$this->Conn->qstr($auth_code)); + $this->Application->SetVar('ord_id', $order_id); + $order = $this->Application->recallObject('ord'); + $order->Load($order_id); + + return $result['response_code'] === '00' ? 1 : 0; + } + + function parseGWResponce($str, $gw_params) + { + $response = explode ("!", $str); + + $result = Array ( + 'code' => $response[1], + 'error' => $response[2], + 'merchant_id' => $response[3], + 'merchant_country' => $response[4], + 'amount' => $response[5], + 'transaction_id' => $response[6], + 'payment_means' => $response[7], + 'transmission_date' => $response[8], + 'payment_time' => $response[9], + 'payment_date' => $response[10], + 'response_code' => $response[11], + 'payment_certificate' => $response[12], + 'authorisation_id' => $response[13], + 'currency_code' => $response[14], + 'card_number' => $response[15], + 'cvv_flag' => $response[16], + 'cvv_response_code' => $response[17], + 'bank_response_code' => $response[18], + 'complementary_code' => $response[19], + 'complementary_info' => $response[20], + 'return_context' => $response[21], + 'caddie' => $response[22], + 'receipt_complement' => $response[23], + 'merchant_language' => $response[24], + 'language' => $response[25], + 'customer_id' => $response[26], + 'order_id' => $response[27], + 'customer_email' => $response[28], + 'customer_ip_address' => $response[29], + 'capture_day' => $response[30], + 'capture_mode' => $response[31], + 'data' => $response[32], + ); + $this->parsed_responce = $result; + return $result; + } + + function getGWResponce() + { + return serialize($this->parsed_responce); + } + + function getErrorMsg() + { + $msg = $this->parsed_responce['error']; + if (!$msg) { + if ($this->parsed_responce['response_code'] != '00') { + $msg = 'Transaction failed'; + } + } + return $msg; + } + } \ No newline at end of file Property changes on: releases/5.2.2-B2/units/gateways/gw_classes/atosorigin.php ___________________________________________________________________ Added: cvs2svn:cvs-rev + 1.3 Added: svn:keywords + Id Added: svn:eol-style + LF Index: releases/5.2.2-B2/units/gateways/gw_classes/paypal_direct.php =================================================================== --- releases/5.2.2-B2/units/gateways/gw_classes/paypal_direct.php (revision 0) +++ releases/5.2.2-B2/units/gateways/gw_classes/paypal_direct.php (revision 16630) @@ -0,0 +1,241 @@ + Array('Name' => 'PayPal Pro', 'ClassName' => 'kGWPaypalDirect', 'ClassFile' => 'paypal_direct.php', 'RequireCCFields' => 1), + 'ConfigFields' => Array( + 'submit_url' => Array('Name' => 'Submit URL', 'Type' => 'text', 'ValueList' => '', 'Default' => 'https://api-3t.paypal.com/nvp'), + 'api_username' => Array('Name' => 'PayPal Pro API Username', 'Type' => 'text', 'ValueList' => '', 'Default' => ''), + 'api_password' => Array('Name' => 'PayPal Pro API Password', 'Type' => 'text', 'ValueList' => '', 'Default' => ''), + 'signature' => Array('Name' => 'PayPal Pro API Signature', 'Type' => 'text', 'ValueList' => '', 'Default' => ''), + 'shipping_control' => Array('Name' => 'Shipping Control', 'Type' => 'select', 'ValueList' => '3=la_CreditDirect', 'Default' => '3'), + ) + ); + return $data; + } + + function DirectPayment($item_data, $gw_params) + { + $post_fields = Array(); + // -- Login Information -- + $post_fields['METHOD'] = 'DoDirectPayment'; + $post_fields['VERSION'] = '52.0'; + $post_fields['IPADDRESS'] = $this->Application->getClientIp(); + $post_fields['USER'] = $gw_params['api_username']; + $post_fields['PWD'] = $gw_params['api_password']; + $post_fields['SIGNATURE'] = $gw_params['signature']; + $post_fields['PAYMENTACTION'] = 'Sale'; + $post_fields['AMT'] = sprintf('%.2f', $item_data['TotalAmount']); + + switch ($item_data['PaymentCardType']) { + case 1: + $post_fields['CREDITCARDTYPE'] = 'Visa'; + break; + case 2: + $post_fields['CREDITCARDTYPE'] = 'MasterCard'; + break; + case 3: + $post_fields['CREDITCARDTYPE'] = 'Amex'; + break; + case 4: + $post_fields['CREDITCARDTYPE'] = 'Discover'; + break; + default: + $this->parsed_responce['responce_reason_text'] = 'Invalid Credit Card Type'; + return false; + } + + $post_fields['ACCT'] = $item_data['PaymentAccount']; + $date_parts = explode('/', $item_data['PaymentCCExpDate']); + $post_fields['EXPDATE'] = $date_parts[0].'20'.$date_parts[1]; + $post_fields['CVV2'] = $item_data['PaymentCVV2']; + + $names = explode(' ', $item_data['PaymentNameOnCard'], 2); + $post_fields['FIRSTNAME'] = getArrayValue($names, 0); + $post_fields['LASTNAME'] = getArrayValue($names, 1); + + $post_fields['STREET'] = $item_data['BillingAddress1']; + $post_fields['STREET2'] = $item_data['BillingAddress2']; + $post_fields['CITY'] = $item_data['BillingCity']; + $post_fields['STATE'] = $item_data['BillingState']; + + /** @var kCountryStatesHelper $cs_helper */ + $cs_helper = $this->Application->recallObject('CountryStatesHelper'); + + $post_fields['COUNTRYCODE'] = $cs_helper->getCountryIso( $item_data['BillingCountry'] ); + $post_fields['ZIP'] = $item_data['BillingZip']; + $post_fields['INVNUM'] = $item_data['OrderNumber']; + $post_fields['CUSTOM'] = $item_data['PortalUserId']; + +/* + $post_fields['x_encap_char'] = $gw_params['encapsulate_char']; + $post_fields['x_relay_response'] = 'False'; + $post_fields['x_type'] = $gw_params['shipping_control'] == SHIPPING_CONTROL_PREAUTH ? 'AUTH_ONLY' : 'AUTH_CAPTURE'; + $post_fields['x_login'] = $gw_params['user_account']; + $post_fields['x_tran_key'] = $gw_params['transaction_key']; + + if( $this->IsTestMode() ) $post_fields['x_test_request'] = 'True'; + + // -- Payment Details -- + $names = explode(' ', $item_data['PaymentNameOnCard'], 2); + $post_fields['x_first_name'] = getArrayValue($names, 0); + $post_fields['x_last_name'] = getArrayValue($names, 1); + $post_fields['x_amount'] = sprintf('%.2f', $item_data['TotalAmount']); + $post_fields['x_company'] = $item_data['BillingCompany']; + $post_fields['x_card_num'] = $item_data['PaymentAccount']; + $post_fields['x_card_code'] = $item_data['PaymentCVV2']; + $post_fields['x_exp_date'] = $item_data['PaymentCCExpDate']; + $post_fields['x_address'] = $item_data['BillingAddress1'].' '.$item_data['BillingAddress2']; + $post_fields['x_city'] = $item_data['BillingCity']; + $post_fields['x_state'] = $item_data['BillingState']; + $post_fields['x_zip'] = $item_data['BillingZip']; + + $recurring = getArrayValue($item_data, 'IsRecurringBilling') ? 'YES' : 'NO'; + $post_fields['x_recurring_billing'] = $recurring; + + $billing_email = $item_data['BillingEmail']; + if (!$billing_email) { + $billing_email = $this->Conn->GetOne(' SELECT Email FROM '.$this->Application->getUnitOption('u', 'TableName').' + WHERE PortalUserId = '.$this->Application->RecallVar('user_id')); + } + $post_fields['x_email'] = $billing_email; + $post_fields['x_phone'] = $item_data['BillingPhone']; + $post_fields['x_country'] = $cs_helper->getCountryIso( $item_data['BillingCountry'] ); + + $post_fields['x_cust_id'] = $item_data['PortalUserId']; + $post_fields['x_invoice_num'] = $item_data['OrderNumber']; + $post_fields['x_description'] = 'Invoice #'.$item_data['OrderNumber']; + $post_fields['x_email_customer'] = 'FALSE'; +*/ +// echo '
';
+//			print_r($post_fields);
+//			exit;
+
+			/** @var kCurlHelper $curl_helper */
+			$curl_helper = $this->Application->recallObject('CurlHelper');
+
+			$curl_helper->SetPostData($post_fields);
+			$this->gw_responce = $curl_helper->Send($gw_params['submit_url']);
+
+//			echo $this->gw_responce;
+//			exit;
+			$gw_responce = $this->parseGWResponce(null, $gw_params);
+			// gw_error_msg: $gw_response['responce_reason_text']
+			// gw_error_code: $gw_response['responce_reason_code']
+//			echo '
';
+//			print_r($this->parsed_responce);
+//			exit;
+			return (isset($gw_responce['ACK']) && (substr($gw_responce['ACK'], 0, 7) == 'Success')) ? true : false;
+		}
+
+		/**
+		 * Perform SALE type transaction direct from php script wihtout redirecting to 3rd-party website
+		 *
+		 * @param Array $item_data
+		 * @param Array $gw_params
+		 * @return bool
+		 */
+/*
+		function Charge($item_data, $gw_params)
+		{
+			$gw_responce = unserialize( $item_data['GWResult1'] );
+
+			if( $item_data['PortalUserId'] != $gw_responce['customer_id'] ) return false;
+
+			if( ( strtolower($gw_responce['transaction_type']) == 'auth_only') )
+			{
+				$post_fields = Array();
+				// -- Login Information --
+				$post_fields['x_version']			=	'3.1';
+				$post_fields['x_delim_data']		=	'True';
+				$post_fields['x_encap_char']		=	$gw_params['encapsulate_char'];
+				$post_fields['x_relay_response']	=	'False';
+				$post_fields['x_type']				=	'PRIOR_AUTH_CAPTURE'; // $gw_params['shipping_control'] == SHIPPING_CONTROL_PREAUTH ? 'PRIOR_AUTH_CAPTURE' : 'AUTH_CAPTURE'; // AUTH_CAPTURE not fully impletemnted/needed here
+				$post_fields['x_login']				=	$gw_params['user_account'];
+				$post_fields['x_tran_key']			=	$gw_params['transaction_key'];
+				$post_fields['x_trans_id']			=	$gw_responce['transaction_id'];
+
+				if( $this->IsTestMode() ) $post_fields['x_test_request'] = 'True';
+
+				$curl_helper = $this->Application->recallObject('CurlHelper');
+
+				$curl_helper->SetPostData($post_fields);
+				$this->gw_responce = $curl_helper->Send($gw_params['submit_url']);
+
+				$gw_responce = $this->parseGWResponce(null, $gw_params);
+
+				// gw_error_msg: $gw_response['responce_reason_text']
+				// gw_error_code: $gw_response['responce_reason_code']
+				return (is_numeric($gw_responce['responce_code']) && $gw_responce['responce_code'] != 1 && !$this->IsTestMode()) ? false : true;
+			}
+			else
+			{
+				return true;
+			}
+		}
+*/
+		/**
+		 * Parse previosly saved gw responce into associative array
+		 *
+		 * @param string $gw_responce
+		 * @param Array $gw_params
+		 * @return Array
+		 */
+		function parseGWResponce($gw_responce = null, $gw_params)
+		{
+			if( !isset($gw_responce) ) $gw_responce = $this->gw_responce;
+
+			if ($this->Application->isDebugMode()) {
+				$this->Application->Debugger->appendHTML('Curl Error #'.$GLOBALS['curl_errorno'].'; Error Message: '.$GLOBALS['curl_error']);
+
+				$this->Application->Debugger->appendHTML('Authorize.Net Responce:');
+				$this->Application->Debugger->dumpVars($gw_responce);
+			}
+
+			$a_responce = explode('&', $gw_responce);
+			$ret = Array();
+			foreach($a_responce as $field)
+			{
+				$pos = strpos($field, '=');
+				if ($pos) {
+					$ret[substr($field, 0, $pos)] = urldecode(substr($field, $pos + 1));
+				}
+			}
+			$this->parsed_responce = $ret;
+//			$ret['unparsed'] = $gw_responce;
+			return $ret;
+		}
+
+		function getGWResponce()
+		{
+			return serialize($this->parsed_responce);
+		}
+
+		function getErrorMsg()
+		{
+			return $this->parsed_responce['L_LONGMESSAGE0'];
+		}
+
+		function GetTestCCNumbers()
+		{
+			return array('370000000000002', '6011000000000012', '5424000000000015', '4007000000027', '4222222222222');
+		}
+	}
\ No newline at end of file

Property changes on: releases/5.2.2-B2/units/gateways/gw_classes/paypal_direct.php
___________________________________________________________________
Added: cvs2svn:cvs-rev
   + 1.1.2.1
Added: svn:keywords
   + Id
Added: svn:eol-style
   + LF

Index: releases/5.2.2-B2/units/gateways/gw_classes/authorizenet.php
===================================================================
--- releases/5.2.2-B2/units/gateways/gw_classes/authorizenet.php	(revision 0)
+++ releases/5.2.2-B2/units/gateways/gw_classes/authorizenet.php	(revision 16630)
@@ -0,0 +1,180 @@
+IsTestMode() ) $post_fields['x_test_request'] = 'True';
+
+			// -- Payment Details --
+			$names = explode(' ', $item_data['PaymentNameOnCard'], 2);
+			$post_fields['x_first_name']		=	getArrayValue($names, 0);
+			$post_fields['x_last_name']			=	getArrayValue($names, 1);
+			$post_fields['x_amount']			=	sprintf('%.2f', $item_data['TotalAmount']);
+			$post_fields['x_company']			=	$item_data['BillingCompany'];
+			$post_fields['x_card_num']			=	$item_data['PaymentAccount'];
+			$post_fields['x_card_code']			=	$item_data['PaymentCVV2'];
+			$post_fields['x_exp_date']			=	$item_data['PaymentCCExpDate'];
+			$post_fields['x_address']			=	$item_data['BillingAddress1'].' '.$item_data['BillingAddress2'];
+			$post_fields['x_city']				=	$item_data['BillingCity'];
+			$post_fields['x_state']				=	$item_data['BillingState'];
+			$post_fields['x_zip']				=	$item_data['BillingZip'];
+
+			$recurring = getArrayValue($item_data, 'IsRecurringBilling') ? 'YES' : 'NO';
+			$post_fields['x_recurring_billing'] = $recurring;
+
+			$billing_email = $item_data['BillingEmail'];
+			if (!$billing_email) {
+				$billing_email = $this->Conn->GetOne('	SELECT Email FROM '.$this->Application->getUnitOption('u', 'TableName').'
+											WHERE PortalUserId = '.$this->Application->RecallVar('user_id'));
+			}
+			$post_fields['x_email'] = $billing_email;
+			$post_fields['x_phone'] = $item_data['BillingPhone'];
+
+			/** @var kCountryStatesHelper $cs_helper */
+			$cs_helper = $this->Application->recallObject('CountryStatesHelper');
+
+			$post_fields['x_country']			=	$cs_helper->getCountryIso( $item_data['BillingCountry'] );
+			$post_fields['x_cust_id']			=	$item_data['PortalUserId'];
+			$post_fields['x_invoice_num']		=	$item_data['OrderNumber'];
+			$post_fields['x_description']		=	'Invoice #'.$item_data['OrderNumber'];
+			$post_fields['x_email_customer']	=	'FALSE';
+
+			/** @var kCurlHelper $curl_helper */
+			$curl_helper = $this->Application->recallObject('CurlHelper');
+
+			$curl_helper->SetPostData($post_fields);
+			$this->gw_responce = $curl_helper->Send($gw_params['submit_url']);
+
+			$gw_responce = $this->parseGWResponce(null, $gw_params);
+
+			// gw_error_msg: $gw_response['responce_reason_text']
+			// gw_error_code: $gw_response['responce_reason_code']
+			return (is_numeric($gw_responce['responce_code']) && $gw_responce['responce_code'] == 1) ? true : false;
+		}
+
+		/**
+		 * Perform SALE type transaction direct from php script wihtout redirecting to 3rd-party website
+		 *
+		 * @param Array $item_data
+		 * @param Array $gw_params
+		 * @return bool
+		 */
+		function Charge($item_data, $gw_params)
+		{
+			$gw_responce = unserialize( $item_data['GWResult1'] );
+
+			if( ($item_data['PortalUserId'] != $gw_responce['customer_id']) && ($gw_repsponce['customer_id'] != USER_GUEST && !$this->Application->isAdmin)) return false;
+
+			if( ( strtolower($gw_responce['transaction_type']) == 'auth_only') )
+			{
+				$post_fields = Array();
+				// -- Login Information --
+				$post_fields['x_version']			=	'3.1';
+				$post_fields['x_delim_data']		=	'True';
+				$post_fields['x_encap_char']		=	$gw_params['encapsulate_char'];
+				$post_fields['x_relay_response']	=	'False';
+				$post_fields['x_type']				=	'PRIOR_AUTH_CAPTURE'; // $gw_params['shipping_control'] == SHIPPING_CONTROL_PREAUTH ? 'PRIOR_AUTH_CAPTURE' : 'AUTH_CAPTURE'; // AUTH_CAPTURE not fully impletemnted/needed here
+				$post_fields['x_login']				=	$gw_params['user_account'];
+				$post_fields['x_tran_key']			=	$gw_params['transaction_key'];
+				$post_fields['x_trans_id']			=	$gw_responce['transaction_id'];
+
+				if( $this->IsTestMode() ) $post_fields['x_test_request'] = 'True';
+
+				/** @var kCurlHelper $curl_helper */
+				$curl_helper = $this->Application->recallObject('CurlHelper');
+
+				$curl_helper->SetPostData($post_fields);
+				$this->gw_responce = $curl_helper->Send($gw_params['submit_url']);
+
+				$gw_responce = $this->parseGWResponce(null, $gw_params);
+
+				// gw_error_msg: $gw_response['responce_reason_text']
+				// gw_error_code: $gw_response['responce_reason_code']
+				return (is_numeric($gw_responce['responce_code']) && $gw_responce['responce_code'] == 1) || $this->IsTestMode() ? true : false;
+			}
+			else
+			{
+				return true;
+			}
+		}
+
+		/**
+		 * Parse previosly saved gw responce into associative array
+		 *
+		 * @param string $gw_responce
+		 * @param Array $gw_params
+		 * @return Array
+		 */
+		function parseGWResponce($gw_responce = null, $gw_params)
+		{
+			if( !isset($gw_responce) ) $gw_responce = $this->gw_responce;
+
+			if ($this->Application->isDebugMode()) {
+				$this->Application->Debugger->appendHTML('Curl Error #'.$GLOBALS['curl_errorno'].'; Error Message: '.$GLOBALS['curl_error']);
+
+				$this->Application->Debugger->appendHTML('Authorize.Net Responce:');
+				$this->Application->Debugger->dumpVars($gw_responce);
+			}
+
+			$fields = Array('responce_code','responce_sub_code','responce_reason_code','responce_reason_text',
+							'approval_code','avs_result_code','transaction_id','invoice_number','description',
+							'amount','method','transaction_type','customer_id','first_name','last_name','company',
+							'address','city','state','zip','country','phone','fax','email');
+
+			$encapsulate_char = $gw_params['encapsulate_char'];
+			if($encapsulate_char)
+			{
+				$ec_length = strlen($encapsulate_char);
+				$gw_responce = substr($gw_responce, $ec_length, $ec_length * -1);
+			}
+
+			$gw_responce = explode($encapsulate_char.','.$encapsulate_char, $gw_responce);
+			$ret = Array();
+			foreach($fields as $field_index => $field_name)
+			{
+				$ret[$field_name] = $gw_responce[$field_index];
+				unset($gw_responce[$field_index]);
+			}
+			$this->parsed_responce = $ret;
+			return kUtil::array_merge_recursive($ret, $gw_responce); // returns unparsed fields with they original indexes together with parsed ones
+		}
+
+		function getGWResponce()
+		{
+			return serialize($this->parsed_responce);
+		}
+
+		function getErrorMsg()
+		{
+			return $this->parsed_responce['responce_reason_text'];
+		}
+
+		function GetTestCCNumbers()
+		{
+			return array('370000000000002', '6011000000000012', '5424000000000015', '4007000000027', '4222222222222');
+		}
+	}
\ No newline at end of file

Property changes on: releases/5.2.2-B2/units/gateways/gw_classes/authorizenet.php
___________________________________________________________________
Added: cvs2svn:cvs-rev
   + 1.17
Added: svn:keywords
   + Id
Added: svn:eol-style
   + LF

Index: releases/5.2.2-B2/units/gateways/gw_classes/google_checkout.php
===================================================================
--- releases/5.2.2-B2/units/gateways/gw_classes/google_checkout.php	(revision 0)
+++ releases/5.2.2-B2/units/gateways/gw_classes/google_checkout.php	(revision 16630)
@@ -0,0 +1,942 @@
+ Array('Name' => 'Google Checkout', 'ClassName' => 'kGWGoogleCheckout', 'ClassFile' => 'google_checkout.php', 'RequireCCFields' => 0),
+				'ConfigFields' => Array(
+					'submit_url' => Array('Name' => 'Submit URL', 'Type' => 'text', 'ValueList' => '', 'Default' => 'https://checkout.google.com/api/checkout/v2'),
+					'merchant_id' => Array('Name' => 'Google merchant ID', 'Type' => 'text', 'ValueList' => '', 'Default' => ''),
+					'merchant_key' => Array('Name' => 'Google merchant key', 'Type' => 'text', 'ValueList' => '', 'Default' => ''),
+					'shipping_control' => Array('Name' => 'Shipping Control', 'Type' => 'select', 'ValueList' => '3=la_CreditDirect,4=la_CreditPreAuthorize', 'Default' => 3),
+				)
+			);
+			return $data;
+		}
+
+		/**
+		 * Returns payment form submit url
+		 *
+		 * @param Array $gw_params gateway params from payment type config
+		 * @return string
+		 */
+		function getFormAction($gw_params)
+		{
+			return $gw_params['submit_url'].'/checkout/Merchant/'.$gw_params['merchant_id'];
+		}
+
+		/**
+		 * Processed input data and convets it to fields understandable by gateway
+		 *
+		 * @param Array $item_data current order fields
+		 * @param Array $tag_params additional params for gateway passed through tag
+		 * @param Array $gw_params gateway params from payment type config
+		 * @return Array
+		 */
+		function getHiddenFields($item_data, $tag_params, $gw_params)
+		{
+			$ret = Array();
+			$this->gwParams = $gw_params;
+
+			$cart_xml = $this->getCartXML($item_data);
+
+			$ret['cart'] = base64_encode($cart_xml);
+    		$ret['signature'] = base64_encode( $this->CalcHmacSha1($cart_xml, $gw_params) );
+
+			return $ret;
+		}
+
+		function getCartXML($cart_fields)
+		{
+			// 1. prepare shopping cart content
+			$sql = 'SELECT *
+					FROM '.TABLE_PREFIX.'OrderItems oi
+					LEFT JOIN '.TABLE_PREFIX.'Products p ON p.ProductId = oi.ProductId
+					WHERE oi.OrderId = '.$cart_fields['OrderId'];
+			$order_items = $this->Conn->Query($sql);
+
+			/** @var kMultiLanguage $ml_formatter */
+			$ml_formatter = $this->Application->recallObject('kMultiLanguage');
+
+			$cart_xml = Array ();
+			foreach ($order_items as $order_item) {
+				$cart_xml[] = '	
+					        		'.kUtil::escape($order_item['ProductName'], kUtil::ESCAPE_HTML).'
+					        		'.kUtil::escape($order_item[$ml_formatter->LangFieldName('DescriptionExcerpt')], kUtil::ESCAPE_HTML).''.
+									$this->getPriceXML('unit-price', $order_item['Price']).'
+					        		'.$order_item['Quantity'].'
+								';
+			}
+			$cart_xml = ''.implode("\n", $cart_xml).'';
+
+			// 2. add order identification info (for google checkout notification)
+			$cart_xml .= '	
+								'.$this->Application->GetSID().'
+								'.$cart_fields['OrderId'].'
+							';
+
+			// 3. add all shipping types (with no costs)
+			$sql = 'SELECT Name
+					FROM '.TABLE_PREFIX.'ShippingType
+					WHERE Status = '.STATUS_ACTIVE;
+			$shipping_types = $this->Conn->GetCol($sql);
+
+			$shipping_xml = '';
+			foreach ($shipping_types as $shipping_name) {
+				$shipping_xml .= '	
+										0.00
+									';
+			}
+
+			$use_ssl = substr($this->gwParams['submit_url'], 0, 8) == 'https://' ? true : null;
+			$shipping_url = $this->getNotificationUrl('units/gateways/gw_classes/notify_scripts/google_checkout_shippings.php', $use_ssl);
+
+			$shipping_xml = '
+								'.$shipping_xml.'
+					      		
+					      			'.$shipping_url.'
+					      		
+					    	';
+
+			$xml = '
+					  '.$cart_xml.'
+					  '.$shipping_xml.'
+					';
+
+			return $xml;
+		}
+
+		/**
+		 * Returns price formatted as xml tag
+		 *
+		 * @param string $tag_name
+		 * @param float $price
+		 * @return string
+		 */
+		function getPriceXML($tag_name, $price)
+		{
+			$currency = $this->Application->RecallVar('curr_iso');
+			return '<'.$tag_name.' currency="'.$currency.'">'.sprintf('%.2f', $price).'';
+		}
+
+	    /**
+	     * Calculates the cart's hmac-sha1 signature, this allows google to verify
+	     * that the cart hasn't been tampered by a third-party.
+	     *
+	     * {@link http://code.google.com/apis/checkout/developer/index.html#create_signature}
+	     *
+	     * @param string $data the cart's xml
+	     * @return string the cart's signature (in binary format)
+	     */
+	    function CalcHmacSha1($data, $gw_params) {
+	      $key = $gw_params['merchant_key'];
+	      $blocksize = 64;
+	      $hashfunc = 'sha1';
+	      if (mb_strlen($key) > $blocksize) {
+	        $key = pack('H*', $hashfunc($key));
+	      }
+	      $key = str_pad($key, $blocksize, chr(0x00));
+	      $ipad = str_repeat(chr(0x36), $blocksize);
+	      $opad = str_repeat(chr(0x5c), $blocksize);
+	      $hmac = pack(
+	                    'H*', $hashfunc(
+	                            ($key^$opad).pack(
+	                                    'H*', $hashfunc(
+	                                            ($key^$ipad).$data
+	                                    )
+	                            )
+	                    )
+	                );
+	      return $hmac;
+	    }
+
+	    /**
+	     * Returns XML request, that GoogleCheckout posts to notification / shipping calculation scripts
+	     *
+	     * @return string
+	     */
+	    function getRequestXML()
+	    {
+	    	$xml_data = file_get_contents('php://input');
+
+	    	if ( $this->Application->isDebugMode() ) {
+	    		$this->toLog($xml_data, 'xml_request.html');
+	    	}
+
+	    	return $xml_data;
+
+	    	// for debugging
+	    	/*return '
+					    434532759516557
+					    CHARGEABLE
+					    NEW
+					    REVIEWING
+					    NEW
+					    2007-03-19T15:06:29.051Z
+					';*/
+	    }
+
+	    /**
+	     * Processes notifications from google checkout
+	     *
+	     * @param Array $gw_params
+	     * @return int
+	     */
+		function processNotification($gw_params)
+		{
+    		// parse xml & get order_id from there, like sella pay
+    		$this->gwParams = $gw_params;
+
+    		/** @var kXMLHelper $xml_helper */
+    		$xml_helper = $this->Application->recallObject('kXMLHelper');
+
+    		/** @var kXMLNode $root_node */
+			$root_node =& $xml_helper->Parse( $this->getRequestXML() );
+
+    		$this->Application->XMLHeader();
+			define('DBG_SKIP_REPORTING', 1);
+
+			$order_approvable = false;
+
+			switch ($root_node->Name) {
+				case 'MERCHANT-CALCULATION-CALLBACK':
+					$xml_responce = $this->getShippingXML($root_node);
+					break;
+
+				case 'NEW-ORDER-NOTIFICATION':
+				case 'RISK-INFORMATION-NOTIFICATION':
+				case 'ORDER-STATE-CHANGE-NOTIFICATION':
+					// http://code.google.com/apis/checkout/developer/Google_Checkout_XML_API_Notification_API.html#new_order_notifications
+					list ($order_approvable, $xml_responce) = $this->getNotificationResponceXML($root_node);
+					break;
+			}
+
+			echo $xml_responce;
+
+			if ( $this->Application->isDebugMode() ) {
+				$this->toLog($xml_responce, 'xml_responce.html');
+			}
+
+    		return $order_approvable ? 1 : 0;
+		}
+
+		/**
+	     * Writes XML requests and responces to a file
+	     *
+	     * @param string $xml_data
+	     * @param string $xml_file
+	     */
+	    function toLog($xml_data, $xml_file)
+	    {
+	    	$fp = fopen( (defined('RESTRICTED') ? RESTRICTED : FULL_PATH) . '/' . $xml_file, 'a' );
+			fwrite($fp, '--- ' . adodb_date('Y-m-d H:i:s') . ' ---' . "\n" . $xml_data);
+			fclose($fp);
+	    }
+
+		/**
+		 * Processes notification
+		 *
+		 * @param kXMLNode $root_node
+		 */
+		function getNotificationResponceXML(&$root_node)
+		{
+			// we can get notification type by "$root_node->Name"
+
+			$order_approvable = false;
+			switch ($root_node->Name) {
+				case 'NEW-ORDER-NOTIFICATION':
+					$order_approvable = $this->processNewOrderNotification($root_node);
+					break;
+
+				case 'RISK-INFORMATION-NOTIFICATION':
+					$order_approvable = $this->processRiskInformationNotification($root_node);
+					break;
+
+				case 'ORDER-STATE-CHANGE-NOTIFICATION':
+					$order_approvable = $this->processOrderStateChangeNotification($root_node);
+					break;
+			}
+
+
+
+			// !!! globally set order id, so gw_responce.php will not fail in setting TransactionStatus
+
+			// 1. receive new order notification
+			// put address & payment type in our order using id found in merchant-private-data (Make order status: Incomplete)
+
+			// 2. receive risk information
+			// don't know what to do, just mark order some how (Make order status: Incomplete)
+
+			// 3. receive status change notification to CHARGEABLE (Make order status: Pending)
+			// only mark order status
+
+			// 4. admin approves order
+			// make api call, that changes order state (fulfillment-order-state) to PROCESSING or DELIVERED (see manual)
+
+			// 5. admin declines order
+			// make api call, that changes order state (fulfillment-order-state) to WILL_NOT_DELIVER
+
+			// Before you ship the items in an order, you should ensure that you have already received the new order notification for the order,
+			// the risk information notification for the order and an order state change notification informing you that the order's financial
+			// state has been updated to CHARGEABLE
+
+			return Array ($order_approvable, '');
+		}
+
+		/**
+		 * Returns shipping calculations and places part of shipping address into order (1st step)
+		 *
+		 * http://code.google.com/apis/checkout/developer/Google_Checkout_XML_API_Merchant_Calculations_API.html#Returning_Merchant_Calculation_Results
+		 *
+		 * @param kXMLNode $node
+		 * @return string
+		 */
+		function getShippingXML(&$root_node)
+		{
+			// 1. extract data from xml
+			$search_nodes = Array (
+				'SHOPPING-CART:MERCHANT-PRIVATE-DATA',
+				'CALCULATE:ADDRESSES:ANONYMOUS-ADDRESS',
+				'CALCULATE:SHIPPING',
+			);
+
+			foreach ($search_nodes as $search_string) {
+				/** @var kXMLNode $found_node */
+				$found_node =& $root_node;
+
+				$search_string = explode(':', $search_string);
+				foreach ($search_string as $search_node) {
+					$found_node =& $found_node->FindChild($search_node);
+				}
+
+				$node_data = Array ();
+
+				/** @var kXMLNode $sub_node */
+				$sub_node =& $found_node->firstChild;
+
+				do {
+					if ($found_node->Name == 'SHIPPING') {
+						$node_data[] = $sub_node->Attributes['NAME'];
+					}
+					else {
+						$node_data[$sub_node->Name] = $sub_node->Data;
+					}
+				} while ( ($sub_node =& $sub_node->NextSibling()) );
+
+
+				switch ($found_node->Name) {
+					case 'MERCHANT-PRIVATE-DATA':
+						$order_id = $node_data['ORDER_ID'];
+						$session_id = $node_data['SESSION_ID'];
+						break;
+
+					case 'ANONYMOUS-ADDRESS':
+						$address_info = $node_data;
+						$address_id = $found_node->Attributes['ID'];
+						break;
+
+					case 'SHIPPING':
+						$process_shippings = $node_data;
+						break;
+				}
+			}
+
+			// 2. update shipping address in order
+			/** @var OrdersItem $order */
+			$order = $this->Application->recallObject('ord', null, Array ('skip_autoload' => true));
+
+			$order->Load($order_id);
+
+			$shipping_address = Array (
+				'ShippingCity' => $address_info['CITY'],
+				'ShippingState' => $address_info['REGION'],
+				'ShippingZip' => $address_info['POSTAL-CODE'],
+			);
+
+			/** @var kCountryStatesHelper $cs_helper */
+			$cs_helper = $this->Application->recallObject('CountryStatesHelper');
+
+			$shipping_address['ShippingCountry'] = $cs_helper->getCountryIso($address_info['COUNTRY-CODE'], true);
+
+			$order->SetDBFieldsFromHash($shipping_address);
+			$order->Update();
+
+			// 3. get shipping rates based on given address
+
+			$shipping_types_xml = '';
+			$shipping_types = $this->getOrderShippings($order);
+
+			// add available shipping types
+			foreach ($shipping_types as $shipping_type) {
+				$shipping_name = $shipping_type['ShippingName'];
+				$processable_shipping_index = array_search($shipping_name, $process_shippings);
+				if ($processable_shipping_index !== false) {
+					$shipping_types_xml .= '
+				    	        				'.sprintf('%01.2f', $shipping_type['TotalCost']).'
+				        	    				true
+				        					';
+
+					// remove available shipping type from processable list
+					unset($process_shippings[$processable_shipping_index]);
+				}
+			}
+
+			// add unavailable shipping types
+			foreach ($process_shippings as $shipping_name) {
+				$shipping_types_xml .= '
+											0.00
+				            				false
+				        				';
+			}
+
+			$shipping_types_xml = '
+									
+				  						'.$shipping_types_xml.'
+									';
+			return $shipping_types_xml;
+		}
+
+		/**
+		 * Places all information from google checkout into order (2nd step)
+		 *
+		 * @param kXMLNode $root_node
+		 */
+		function processNewOrderNotification(&$root_node)
+		{
+			// 1. extract data from xml
+			$search_nodes = Array (
+				'SHOPPING-CART:MERCHANT-PRIVATE-DATA',
+				'ORDER-ADJUSTMENT:SHIPPING:MERCHANT-CALCULATED-SHIPPING-ADJUSTMENT',
+				'BUYER-ID',
+				'GOOGLE-ORDER-NUMBER',
+				'BUYER-SHIPPING-ADDRESS',
+				'BUYER-BILLING-ADDRESS',
+			);
+
+			$user_address = Array ();
+			foreach ($search_nodes as $search_string) {
+				/** @var kXMLNode $found_node */
+				$found_node =& $root_node;
+
+				$search_string = explode(':', $search_string);
+				foreach ($search_string as $search_node) {
+					$found_node =& $found_node->FindChild($search_node);
+				}
+
+				$node_data = Array ();
+				if ($found_node->Children) {
+					/** @var kXMLNode $sub_node */
+					$sub_node =& $found_node->firstChild;
+
+					do {
+						$node_data[$sub_node->Name] = $sub_node->Data;
+					} while ( ($sub_node =& $sub_node->NextSibling()) );
+				}
+
+				switch ($found_node->Name) {
+					case 'MERCHANT-PRIVATE-DATA':
+						$order_id = $node_data['ORDER_ID'];
+						$session_id = $node_data['SESSION_ID'];
+						break;
+
+					case 'MERCHANT-CALCULATED-SHIPPING-ADJUSTMENT':
+						$shpipping_info = $node_data;
+						break;
+
+					case 'BUYER-ID':
+						$buyer_id = $found_node->Data;
+						break;
+
+					case 'GOOGLE-ORDER-NUMBER':
+						$google_order_number = $found_node->Data;
+						break;
+
+					case 'BUYER-SHIPPING-ADDRESS':
+						$user_address['Shipping'] = $node_data;
+						break;
+
+					case 'BUYER-BILLING-ADDRESS':
+						$user_address['Billing'] = $node_data;
+						break;
+				}
+			}
+
+			// 2. update shipping address in order
+			/** @var OrdersItem $order */
+			$order = $this->Application->recallObject('ord', null, Array ('skip_autoload' => true));
+
+			$order->Load($order_id);
+
+			if (!$order->isLoaded()) {
+				return false;
+			}
+
+			// 2.1. this is 100% notification from google -> mark order with such payment type
+			$order->SetDBField('PaymentType', $this->Application->GetVar('payment_type_id'));
+
+			$this->parsed_responce = Array (
+				'GOOGLE-ORDER-NUMBER' => $google_order_number,
+				'BUYER-ID' => $buyer_id
+			);
+
+			// 2.2. save google checkout order information (maybe needed for future notification processing)
+			$order->SetDBField('GWResult1', serialize($this->parsed_responce));
+			$order->SetDBField('GoogleOrderNumber', $google_order_number);
+
+			// 2.3. set user-selected shipping type
+			$shipping_types = $this->getOrderShippings($order);
+
+			foreach ($shipping_types as $shipping_type) {
+				if ($shipping_type['ShippingName'] == $shpipping_info['SHIPPING-NAME']) {
+					$order->SetDBField('ShippingInfo', serialize(Array (1 => $shipping_type))); // minimal package number is 1
+					$order->SetDBField('ShippingCost', $shipping_type['TotalCost']); // set total shipping cost
+					break;
+				}
+			}
+
+			// 2.4. set full shipping & billing address
+			$address_mapping = Array (
+				'CONTACT-NAME' => 'To',
+				'COMPANY-NAME' => 'Company',
+				'EMAIL' => 'Email',
+				'PHONE' => 'Phone',
+				'FAX' => 'Fax',
+				'ADDRESS1' => 'Address1',
+				'ADDRESS2' => 'Address2',
+				'CITY' => 'City',
+				'REGION' => 'State',
+				'POSTAL-CODE' => 'Zip',
+			);
+
+			/** @var kCountryStatesHelper $cs_helper */
+			$cs_helper = $this->Application->recallObject('CountryStatesHelper');
+
+			foreach ($user_address as $field_prefix => $address_details) {
+				foreach ($address_mapping as $src_field => $dst_field) {
+					$order->SetDBField($field_prefix.$dst_field, $address_details[$src_field]);
+				}
+
+				if (!$order->GetDBField($field_prefix.'Phone')) {
+					$order->SetDBField($field_prefix.'Phone', '-'); // required field
+				}
+
+				$order->SetDBField( $field_prefix.'Country', $cs_helper->getCountryIso($address_details['COUNTRY-CODE'], true) );
+			}
+
+			$order->SetDBField('OnHold', 1);
+			$order->SetDBField('Status', ORDER_STATUS_PENDING);
+
+			$order->Update();
+
+			// unlink order, that GoogleCheckout used from shopping cart on site
+			$sql = 'DELETE
+					FROM '.TABLE_PREFIX.'UserSessionData
+					WHERE VariableName = "ord_id" AND VariableValue = '.$order->GetID();
+			$this->Conn->Query($sql);
+
+			// simulate visiting shipping screen
+			$sql = 'UPDATE '.TABLE_PREFIX.'OrderItems
+					SET PackageNum = 1
+					WHERE OrderId = '.$order->GetID();
+			$this->Conn->Query($sql);
+
+			return false;
+		}
+
+		/**
+		 * Saves risk information in order record (3rd step)
+		 *
+		 * @param kXMLNode $root_node
+		 */
+		function processRiskInformationNotification(&$root_node)
+		{
+			// 1. extract data from xml
+			$search_nodes = Array (
+				'GOOGLE-ORDER-NUMBER',
+				'RISK-INFORMATION',
+			);
+
+			foreach ($search_nodes as $search_string) {
+				/** @var kXMLNode $found_node */
+				$found_node =& $root_node;
+
+				$search_string = explode(':', $search_string);
+				foreach ($search_string as $search_node) {
+					$found_node =& $found_node->FindChild($search_node);
+				}
+
+				$node_data = Array ();
+				if ($found_node->Children) {
+					/** @var kXMLNode $sub_node */
+					$sub_node =& $found_node->firstChild;
+
+					do {
+						$node_data[$sub_node->Name] = $sub_node->Data;
+					} while ( ($sub_node =& $sub_node->NextSibling()) );
+				}
+
+				switch ($found_node->Name) {
+					case 'GOOGLE-ORDER-NUMBER':
+						$google_order_number = $found_node->Data;
+						break;
+
+					case 'RISK-INFORMATION':
+						$risk_information = $node_data;
+						unset( $risk_information['BILLING-ADDRESS'] );
+						break;
+				}
+			}
+
+			// 2. update shipping address in order
+			/** @var OrdersItem $order */
+			$order = $this->Application->recallObject('ord', null, Array ('skip_autoload' => true));
+
+			$order->Load($google_order_number, 'GoogleOrderNumber');
+
+			if (!$order->isLoaded()) {
+				return false;
+			}
+
+			// 2.1. save risk information in order
+			$this->parsed_responce = unserialize($order->GetDBField('GWResult1'));
+			$this->parsed_responce = array_merge_recursive($this->parsed_responce, $risk_information);
+			$order->SetDBField('GWResult1', serialize($this->parsed_responce));
+
+			$order->Update();
+
+			return false;
+		}
+
+		/**
+		 * Perform PREAUTH/SALE type transaction direct from php script wihtout redirecting to 3rd-party website
+		 *
+		 * @param Array $item_data
+		 * @param Array $gw_params
+		 * @return bool
+		 */
+		function DirectPayment($item_data, $gw_params)
+		{
+			$this->gwParams = $gw_params;
+
+			if ($gw_params['shipping_control'] == SHIPPING_CONTROL_PREAUTH) {
+				// when shipping control is Pre-Authorize -> do nothing and charge when admin approves order
+				return true;
+			}
+
+			$this->_chargeOrder($item_data);
+
+			return false;
+		}
+
+		/**
+		 * Issue charge-order api call
+		 *
+		 * @param Array $item_data
+		 * @return bool
+		 */
+		function _chargeOrder($item_data)
+		{
+			$charge_xml = '	
+			    				'.sprintf('%.2f', $item_data['TotalAmount']).'
+							';
+
+			$root_node =& $this->executeAPICommand($charge_xml);
+
+    		$this->parsed_responce = unserialize($item_data['GWResult1']);
+
+    		if ($root_node->Name == 'REQUEST-RECEIVED') {
+				$this->parsed_responce['FINANCIAL-ORDER-STATE'] = 'CHARGING';
+				return true;
+    		}
+
+    		return false;
+		}
+
+		/**
+		 * Perform SALE type transaction direct from php script wihtout redirecting to 3rd-party website
+		 *
+		 * @param Array $item_data
+		 * @param Array $gw_params
+		 * @return bool
+		 */
+		function Charge($item_data, $gw_params)
+		{
+			$this->gwParams = $gw_params;
+
+			if ($gw_params['shipping_control'] == SHIPPING_CONTROL_DIRECT) {
+				// when shipping control is Direct Payment -> do nothing and auto-charge on notification received
+				return true;
+			}
+
+			$this->_chargeOrder($item_data);
+
+			/** @var OrdersItem $order */
+			$order = $this->Application->recallObject('ord.-item', null, Array ('skip_autoload' => true));
+
+			$order->Load($item_data['OrderId']);
+			if (!$order->isLoaded()) {
+				return false;
+			}
+
+			$order->SetDBField('OnHold', 1);
+			$order->Update();
+
+			return false;
+		}
+
+		/**
+		 * Executes API command for order and returns result
+		 *
+		 * @param string $command_xml
+		 * @return kXMLNode
+		 */
+		function &executeAPICommand($command_xml)
+		{
+			$submit_url = $this->gwParams['submit_url'].'/request/Merchant/'.$this->gwParams['merchant_id'];
+
+			/** @var kCurlHelper $curl_helper */
+			$curl_helper = $this->Application->recallObject('CurlHelper');
+
+    		/** @var kXMLHelper $xml_helper */
+			$xml_helper = $this->Application->recallObject('kXMLHelper');
+
+			$curl_helper->SetPostData($command_xml);
+			$auth_options = Array (
+				CURLOPT_USERPWD => $this->gwParams['merchant_id'].':'.$this->gwParams['merchant_key'],
+			);
+			$curl_helper->setOptions($auth_options);
+
+			$xml_responce = $curl_helper->Send($submit_url);
+
+    		/** @var kXMLNode $root_node */
+			$root_node =& $xml_helper->Parse($xml_responce);
+
+    		return $root_node;
+		}
+
+		/**
+		 * Marks order as pending, when it's google status becomes CHARGEABLE (4th step)
+		 *
+		 * @param kXMLNode $root_node
+		 */
+		function processOrderStateChangeNotification(&$root_node)
+		{
+			// 1. extract data from xml
+			$search_nodes = Array (
+				'GOOGLE-ORDER-NUMBER',
+				'NEW-FINANCIAL-ORDER-STATE',
+				'PREVIOUS-FINANCIAL-ORDER-STATE',
+			);
+
+			$order_state = Array ();
+			foreach ($search_nodes as $search_string) {
+				/** @var kXMLNode $found_node */
+				$found_node =& $root_node;
+
+				$search_string = explode(':', $search_string);
+				foreach ($search_string as $search_node) {
+					$found_node =& $found_node->FindChild($search_node);
+				}
+
+				switch ($found_node->Name) {
+					case 'GOOGLE-ORDER-NUMBER':
+						$google_order_number = $found_node->Data;
+						break;
+
+					case 'NEW-FINANCIAL-ORDER-STATE':
+						$order_state['new'] = $found_node->Data;
+						break;
+
+					case 'PREVIOUS-FINANCIAL-ORDER-STATE':
+						$order_state['old'] = $found_node->Data;
+						break;
+				}
+			}
+
+			// 2. update shipping address in order
+			/** @var OrdersItem $order */
+			$order = $this->Application->recallObject('ord', null, Array ('skip_autoload' => true));
+
+			$order->Load($google_order_number, 'GoogleOrderNumber');
+
+			if (!$order->isLoaded()) {
+				return false;
+			}
+
+			$state_changed = ($order_state['old'] != $order_state['new']);
+
+			if ($state_changed) {
+				$order_charged = ($order_state['new'] == 'CHARGED') && ($order->GetDBField('Status') == ORDER_STATUS_PENDING);
+
+				$this->parsed_responce = unserialize($order->GetDBField('GWResult1'));
+				$this->parsed_responce['FINANCIAL-ORDER-STATE'] = $order_state['new'];
+				$order->SetDBField('GWResult1', serialize($this->parsed_responce));
+
+				if ($order_charged) {
+					// when using Pre-Authorize
+					$order->SetDBField('OnHold', 0);
+				}
+
+				$order->Update();
+
+				if ($order_charged) {
+					// when using Pre-Authorize
+					/** @var OrdersEventHandler $order_eh */
+					$order_eh = $this->Application->recallObject('ord_EventHandler');
+
+					$order_eh->SplitOrder( new kEvent('ord:OnMassOrderApprove'), $order);
+				}
+			}
+
+			// update order record in "google_checkout_notify.php" only when such state change happens
+			$order_chargeable = ($order_state['new'] == 'CHARGEABLE') && $state_changed;
+
+			if ($order_chargeable) {
+				if ($this->gwParams['shipping_control'] == SHIPPING_CONTROL_PREAUTH) {
+					$order->SetDBField('OnHold', 0);
+					$order->Update();
+				}
+
+				$process_xml = '';
+				$root_node =& $this->executeAPICommand($process_xml);
+			}
+
+			return $order_chargeable;
+		}
+
+		/**
+		 * Retrieves shipping types available for given order
+		 *
+		 * @param OrdersItem $order
+		 * @return Array
+		 */
+		function getOrderShippings(&$order)
+		{
+			$weight_sql = 'IF(oi.Weight IS NULL, 0, oi.Weight * oi.Quantity)';
+
+			$query = '	SELECT
+							SUM(oi.Quantity) AS TotalItems,
+							SUM('.$weight_sql.') AS TotalWeight,
+							SUM(oi.Price * oi.Quantity) AS TotalAmount,
+							SUM(oi.Quantity) - SUM(IF(p.MinQtyFreePromoShipping > 0 AND p.MinQtyFreePromoShipping <= oi.Quantity, oi.Quantity, 0)) AS TotalItemsPromo,
+							SUM('.$weight_sql.') - SUM(IF(p.MinQtyFreePromoShipping > 0 AND p.MinQtyFreePromoShipping <= oi.Quantity, '.$weight_sql.', 0)) AS TotalWeightPromo,
+							SUM(oi.Price * oi.Quantity) - SUM(IF(p.MinQtyFreePromoShipping > 0 AND p.MinQtyFreePromoShipping <= oi.Quantity, oi.Price * oi.Quantity, 0)) AS TotalAmountPromo
+						FROM '.TABLE_PREFIX.'OrderItems oi
+						LEFT JOIN '.TABLE_PREFIX.'Products p ON oi.ProductId = p.ProductId
+						WHERE oi.OrderId = '.$order->GetID().' AND p.Type = 1';
+			$shipping_totals = $this->Conn->GetRow($query);
+
+			$this->Application->recallObject('ShippingQuoteEngine');
+
+			/** @var ShippingQuoteCollector $quote_engine_collector */
+			$quote_engine_collector = $this->Application->recallObject('ShippingQuoteCollector');
+
+			$shipping_quote_params = Array(
+				'dest_country'	=>	$order->GetDBField('ShippingCountry'),
+				'dest_state'	=>	$order->GetDBField('ShippingState'),
+				'dest_postal'	=>	$order->GetDBField('ShippingZip'),
+				'dest_city'		=>	$order->GetDBField('ShippingCity'),
+				'dest_addr1'	=>	'',
+				'dest_addr2'	=>	'',
+				'dest_name'		=>	'user-' . $order->GetDBField('PortalUserId'),
+				'packages' 		=>	Array(
+										Array(
+											'package_key'	=>	'package1',
+											'weight'		=>	$shipping_totals['TotalWeight'],
+											'weight_unit'	=>	'KG',
+											'length'		=>	'',
+											'width'			=>	'',
+											'height'		=>	'',
+											'dim_unit'		=>	'IN',
+											'packaging'		=>	'BOX',
+											'contents'		=>	'OTR',
+											'insurance'		=>	'0'
+										),
+									),
+				'amount'		=>	$shipping_totals['TotalAmount'],
+				'items'			=>	$shipping_totals['TotalItems'],
+				'limit_types' 	=> 	serialize(Array ('ANY')),
+
+				'promo_params'	=>	Array (
+					'items'		=>	$shipping_totals['TotalItemsPromo'],
+					'amount'	=>	$shipping_totals['TotalAmountPromo'],
+					'weight'	=>	$shipping_totals['TotalWeightPromo'],
+				),
+			);
+
+			return $quote_engine_collector->GetShippingQuotes($shipping_quote_params);
+		}
+
+		/**
+		 * Returns gateway responce from last operation
+		 *
+		 * @return string
+		 */
+		function getGWResponce()
+		{
+			return serialize($this->parsed_responce);
+		}
+
+		/**
+		 * Informs payment gateway, that order has been shipped
+		 *
+		 * http://code.google.com/apis/checkout/developer/Google_Checkout_XML_API_Order_Level_Shipping.html#Deliver_Order
+		 *
+		 * @param Array $item_data
+		 * @param Array $gw_params
+		 * @return bool
+		 */
+		function OrderShipped($item_data, $gw_params)
+		{
+			$this->gwParams = $gw_params;
+
+			$shipping_info = unserialize($item_data['ShippingInfo']);
+			if (getArrayValue($shipping_info, 'Code')) {
+				$traking_carrier = ''.$item_data['Code'].'';
+			}
+
+			if ($item_data['ShippingTracking']) {
+				$tracking_data = ''.$traking_carrier.'
+        							 '.$item_data['ShippingTracking'].'
+        						  ';
+			}
+
+			$ship_xml = '	
+								'.$traking_data.'
+    							true
+							';
+			$root_node =& $this->executeAPICommand($ship_xml);
+		}
+
+		/**
+		 * Informs payment gateway, that order has been declined
+		 *
+		 * @param Array $item_data
+		 * @param Array $gw_params
+		 * @return bool
+		 */
+		function OrderDeclined($item_data, $gw_params)
+		{
+
+		}
+	}

Property changes on: releases/5.2.2-B2/units/gateways/gw_classes/google_checkout.php
___________________________________________________________________
Added: cvs2svn:cvs-rev
   + 1.1.2.9
Added: svn:keywords
   + Id
Added: svn:eol-style
   + LF

Index: releases/5.2.2-B2/units/gateways/gw_classes/sella_guestpay.php
===================================================================
--- releases/5.2.2-B2/units/gateways/gw_classes/sella_guestpay.php	(revision 0)
+++ releases/5.2.2-B2/units/gateways/gw_classes/sella_guestpay.php	(revision 16630)
@@ -0,0 +1,163 @@
+ Array('Name' => 'Sella/GuestPay', 'ClassName' => 'kSellaGuestPayGW', 'ClassFile' => 'sella_guestpay.php', 'RequireCCFields' => 0),
+				'ConfigFields' => Array(
+					'merchant_id' => Array('Name' => 'Merchant ID', 'Type' => 'text', 'ValueList' => '', 'Default' => ''),
+					'merchant_country' => Array('Name' => 'Merchant Country Code', 'Type' => 'text', 'ValueList' => '', 'Default' => ''),
+					'currency_code' => Array('Name' => 'Currency Code', 'Type' => 'text', 'ValueList' => '', 'Default' => '978'),
+					'language_code' => Array('Name' => 'Language Code', 'Type' => 'text', 'ValueList' => '', 'Default' => '2'),
+					'shipping_control' => Array('Name' => 'Shipping Control', 'Type' => 'select', 'ValueList' => '3=la_CreditDirect,4=la_CreditPreAuthorize', 'Default' => '3'),
+				)
+			);
+			return $data;
+		}
+
+		/**
+		 * Returns payment form submit url
+		 *
+		 * @param Array $gw_params gateway params from payment type config
+		 * @return string
+		 */
+		function getFormAction($gw_params)
+		{
+			return 'https://ecomm.sella.it/gestpay/pagam.asp';
+		}
+
+		/**
+		 * Processed input data and convets it to fields understandable by gateway
+		 *
+		 * @param Array $item_data
+		 * @param Array $tag_params additional params for gateway passed through tag
+		 * @param Array $gw_params gateway params from payment type config
+		 * @return Array
+		 */
+		function getHiddenFields($item_data, $tag_params, $gw_params)
+		{
+			$a = $gw_params['merchant_id'];
+			$params['PAY1_UICCODE'] = $gw_params['currency_code'];
+			$params['PAY1_AMOUNT'] = $item_data['TotalAmount'];
+			$params['PAY1_SHOPTRANSACTIONID'] = $item_data['OrderId'];
+			$params['PAY1_IDLANGUAGE'] = $gw_params['language_code'];
+			$params['CUSTOM_INFO'] = $this->Application->GetSID().','.MD5($item_data['OrderId']);
+
+			$separator = '*P1*';
+			$b = array();
+			foreach ($params as $key=>$val) {
+				$b[] = $key.'='.kUtil::escape(trim($val), kUtil::ESCAPE_URL);
+			}
+			//the last one is CUSTOMINFO according to GW specs, passing the atosorigin-style 'caddie'
+			$b = join($separator, $b);
+			$url = 'https://ecomm.sella.it/CryptHTTPS/Encrypt.asp?a='.$a.'&b='.$b.'&c=2.0';
+
+			/** @var kCurlHelper $curl_helper */
+			$curl_helper = $this->Application->recallObject('CurlHelper');
+
+			$res = $curl_helper->Send($url);
+
+			preg_match('/#cryptstring#(.*)#\/cryptstring#/', $res, $matches);
+			$b = $matches[1];
+
+			$res = '';
+			return $res;
+		}
+
+		function NeedPlaceButton($item_data, $tag_params, $gw_params)
+		{
+			return true;
+		}
+
+		function processNotification($gw_params)
+		{
+			$a = $gw_params['merchant_id'];
+			$b = $_GET['b'];
+			$url = 'https://ecomm.sella.it/CryptHTTPS/Decrypt.asp?a='.$a.'&b='.$b.'&c=2.0';
+
+			/** @var kCurlHelper $curl_helper */
+			$curl_helper = $this->Application->recallObject('CurlHelper');
+
+			$ret = $curl_helper->Send($url);
+			$result = $this->parseGWResponce($ret, $gw_params);
+
+			list ($sid, $auth_code) = explode(',', $result['CUSTOM_INFO']);
+			$session = $this->Application->recallObject('Session');
+			$session->SID = $sid;
+
+			$order_id = $this->Conn->GetOne('SELECT OrderId FROM '.TABLE_PREFIX.'Orders WHERE md5(OrderId) = '.$this->Conn->qstr($auth_code));
+			$this->Application->SetVar('ord_id', $order_id);
+			$order = $this->Application->recallObject('ord');
+			$order->Load($order_id);
+
+			if ($this->Application->GetVar('sella_ok')) {
+				if ($result['PAY1_TRANSACTIONRESULT'] == 'OK') {
+					$this->Application->Redirect('in-commerce/checkout/checkout_success', null, '_FRONT_END_', 'index.php');
+				}
+				else {
+					$this->Application->SetVar('sella_error', 1);
+				}
+			}
+			if ($this->Application->GetVar('sella_error')) {
+				$this->Application->StoreVar('gw_error', $this->getErrorMsg());
+				$this->Application->Redirect('in-commerce/checkout/billing', null, '_FRONT_END_', 'index.php');
+			}
+
+			return $result['PAY1_TRANSACTIONRESULT'] == 'OK' ? 1 : 0;
+		}
+
+		function parseGWResponce($str, $gw_params)
+		{
+			if (preg_match('/#decryptstring#(.*)#\/decryptstring#/', $str, $matches)) {
+				$separator = '*P1*';
+				$pairs = explode($separator, $matches[1]);
+				foreach ($pairs as $a_pair) {
+					list($key, $val) = explode('=', $a_pair);
+					$result[$key] = $val;
+				}
+			}
+			elseif (preg_match('/#error#(.*)#\/error#/', $str, $matches))
+			{
+				$result['PAY1_ERRORDESCRIPTION'] = $matches[1];
+			}
+			else { //unknown error
+				$result['PAY1_ERRORDESCRIPTION'] = 'Unknown error';
+			}
+
+			$this->parsed_responce = $result;
+			return $result;
+		}
+
+		function getGWResponce()
+		{
+			return serialize($this->parsed_responce);
+		}
+
+		function getErrorMsg()
+		{
+			$msg = $this->parsed_responce['PAY1_ERRORDESCRIPTION'];
+			if (!$msg) {
+				if ($this->parsed_responce['response_code'] != 'OK') {
+					$msg = 'Transaction failed';
+				}
+			}
+			return $msg;
+		}
+	}
\ No newline at end of file

Property changes on: releases/5.2.2-B2/units/gateways/gw_classes/sella_guestpay.php
___________________________________________________________________
Added: cvs2svn:cvs-rev
   + 1.2
Added: svn:keywords
   + Id
Added: svn:eol-style
   + LF

Index: releases/5.2.2-B2/units/gateways/gw_classes/worldpay.php
===================================================================
--- releases/5.2.2-B2/units/gateways/gw_classes/worldpay.php	(revision 0)
+++ releases/5.2.2-B2/units/gateways/gw_classes/worldpay.php	(revision 16630)
@@ -0,0 +1,117 @@
+ Array('Name' => 'Worldpay', 'ClassName' => 'kGWWorldPay', 'ClassFile' => 'worldpay.php', 'RequireCCFields' => 0),
+				'ConfigFields' => Array(
+					'submit_url' => Array('Name' => 'Submit URL', 'Type' => 'text', 'ValueList' => '', 'Default' => 'https://select.worldpay.com/wcc/purchase'),
+					'instId' => Array('Name' => 'Installation ID', 'Type' => 'text', 'ValueList' => '', 'Default' => ''),
+					'callback_pw' => Array('Name' => 'Callback Password', 'Type' => 'text', 'ValueList' => '', 'Default' => ''),
+				)
+			);
+			return $data;
+		}
+
+		/**
+		 * Returns payment form submit url
+		 *
+		 * @param Array $gw_params gateway params from payment type config
+		 * @return string
+		 */
+		function getFormAction($gw_params)
+		{
+			return $gw_params['submit_url'];
+		}
+
+		/**
+		 * Processed input data and convets it to fields understandable by gateway
+		 *
+		 * @param Array $item_data
+		 * @param Array $tag_params additional params for gateway passed through tag
+		 * @param Array $gw_params gateway params from payment type config
+		 * @return Array
+		 */
+		function getHiddenFields($item_data, $tag_params, $gw_params)
+		{
+			$ret = Array();
+
+			$ret['instId'] = $gw_params['instId'];
+			$ret['cartId'] = $item_data['OrderNumber'];
+
+			if (!$this->IsTestMode()) {
+				$ret['amount'] = sprintf('%.2f', $item_data['TotalAmount']); // the total amount to be billed, in decimal form, without a currency symbol. (8 characters, decimal, 2 characters: Example: 99999999.99)
+			}
+			else {
+				$ret['testMode'] = 100; // 100 - success, 101 - failure
+				$ret['amount'] = 1;
+			}
+
+			$ret['currency'] = 'USD';
+			$ret['desc'] = 'Order #'.$item_data['OrderNumber'];
+
+			$ret['name'] = $item_data['BillingTo'];
+			$ret['address'] = $item_data['BillingAddress1'];
+			if ($item_data['BillingAddress2']) {
+				$ret['address'] .= '
'.$item_data['BillingAddress2'];
+			}
+			$ret['postcode'] = $item_data['BillingZip'];
+
+			/** @var kCountryStatesHelper $cs_helper */
+			$cs_helper = $this->Application->recallObject('CountryStatesHelper');
+
+			$ret['country'] = $cs_helper->getCountryIso( $item_data['BillingCountry'] );
+			$ret['tel'] = $item_data['BillingPhone'];
+			$ret['fax'] = $item_data['BillingFax'];
+			$ret['email'] = $item_data['BillingEmail'];
+			$ret['fixContact'] = 1; // contact-info not editable ?
+
+			$return_params = Array ('pass' => 'm', 'sid' => $this->Application->GetSID(), 'admin' => 1);
+			$ret['MC_return_page'] = $this->Application->HREF($tag_params['return_template'], '', $return_params);
+			$ret['MC_cancel_return_page'] = $this->Application->HREF($tag_params['cancel_template'], '', $return_params);
+			$ret['MC_callback'] = $this->getNotificationUrl() . '?sid='.$this->Application->GetSID().'&admin=1&order_id='.$item_data['OrderId'];
+
+			return $ret;
+		}
+
+		function processNotification($gw_params)
+		{
+    		// http://support.worldpay.com/kb/integration_guides/junior/integration/help/appendicies/sjig_10100.html
+    		// SubmitURL: https://select.worldpay.com/wcc/purchase
+			// for Notification to work do this in gateway Admin Console:
+    		// Callback URL: 
+    		// Callback enabled? [x]
+    		// Use callback response?[x]
+			$transaction_verified = ($this->Application->GetVar('callbackPW') == $gw_params['callback_pw']);
+    		if (!$transaction_verified) {
+    			return 0;
+    		}
+
+    		$transaction_status = $this->Application->GetVar('transStatus') == 'Y' ? 1 : 0;
+
+			/** @var kCurlHelper $curl_helper */
+    		$curl_helper = $this->Application->recallObject('CurlHelper');
+
+			$url = $this->Application->GetVar($transaction_status ? 'MC_return_page' : 'MC_cancel_return_page');
+			echo $curl_helper->Send($url);
+
+    		return $transaction_status;
+		}
+	}
\ No newline at end of file

Property changes on: releases/5.2.2-B2/units/gateways/gw_classes/worldpay.php
___________________________________________________________________
Added: cvs2svn:cvs-rev
   + 1.1.8.1
Added: svn:keywords
   + Id
Added: svn:eol-style
   + LF

Index: releases/5.2.2-B2/units/gateways/gw_classes/paybox.php
===================================================================
--- releases/5.2.2-B2/units/gateways/gw_classes/paybox.php	(revision 0)
+++ releases/5.2.2-B2/units/gateways/gw_classes/paybox.php	(revision 16630)
@@ -0,0 +1,182 @@
+ Array('Name' => 'Paybox.com', 'ClassName' => 'kPayboxGW', 'ClassFile' => 'paybox.php', 'RequireCCFields' => 0),
+				'ConfigFields' => Array(
+					'binary' => Array('Name' => 'API Executable', 'Type' => 'text', 'ValueList' => '', 'Default' => ''),
+					'params_file' => Array('Name' => 'OPT Params File', 'Type' => 'text', 'ValueList' => '', 'Default' => ''),
+					'site_number' => Array('Name' => 'Site Number', 'Type' => 'text', 'ValueList' => '', 'Default' => ''),
+					'rank_number' => Array('Name' => 'Rank Number', 'Type' => 'text', 'ValueList' => '', 'Default' => ''),
+					'identity_number' => Array('Name' => 'Identity Number', 'Type' => 'text', 'ValueList' => '', 'Default' => ''),
+					'currency_code' => Array('Name' => 'Currency Code', 'Type' => 'text', 'ValueList' => '', 'Default' => '978'),
+					'shipping_control' => Array('Name' => 'Shipping Control', 'Type' => 'select', 'ValueList' => '3=la_CreditDirect,4=la_CreditPreAuthorize', 'Default' => '3'),
+				)
+			);
+			return $data;
+		}
+
+		/**
+		 * Returns payment form submit url
+		 *
+		 * @param Array $gw_params gateway params from payment type config
+		 * @return string
+		 */
+		function getFormAction($gw_params)
+		{
+			return $gw_params['submit_url'];
+		}
+
+		/**
+		 * Processed input data and convets it to fields understandable by gateway
+		 *
+		 * @param Array $item_data
+		 * @param Array $tag_params additional params for gateway passed through tag
+		 * @param Array $gw_params gateway params from payment type config
+		 * @return Array
+		 */
+		function getHiddenFields($item_data, $tag_params, $gw_params)
+		{
+			$params['PBX_MODE'] = $gw_params['params_file'] ? '34' : '4';
+			$params['PBX_OUTPUT'] = 'B';
+			$params['PBX_SITE'] = $gw_params['site_number'];
+			$params['PBX_RANG'] = $gw_params['rank_number'];
+			$params['PBX_IDENTIFIANT'] = $gw_params['identity_number'];
+			$params['PBX_OPT'] = $gw_params['params_file'];
+			$params['PBX_DEVISE'] = $gw_params['currency_code']; // 978 for the euro. 840 for the US dollar.
+
+			$params['PBX_RETOUR'] = 'amount:M;reference:R;trans:T;autorization:A;subscription:B;payment:P;card:C;trans_id:S;country:Y;error:E;expiration:D';
+
+			$params['PBX_EFFECTUE'] = $this->Application->HREF($tag_params['return_template'],'',Array('pass'=>'m'));
+			$params['PBX_REFUSE'] = $this->Application->HREF($tag_params['cancel_template'],'',Array('pass'=>'m'));
+
+			$txt_amount = sprintf("%.2f", $item_data['TotalAmount']);
+			$params['PBX_TOTAL'] = str_replace( Array('.', ','), '', $txt_amount);
+			$params['PBX_CMD'] = $this->Application->GetSID().','.MD5($item_data['OrderId']);
+
+			/*$params['order_id'] = $item_data['OrderId'];
+			$params['customer_ip_address'] = $this->Application->getClientIp();
+			$params['customer_id'] = $item_data['PortalUserId'];*/
+
+			$billing_email = $item_data['BillingEmail'];
+			if (!$billing_email) {
+				$billing_email = $this->Conn->GetOne('	SELECT Email FROM '.$this->Application->getUnitOption('u', 'TableName').'
+											WHERE PortalUserId = '.$this->Application->RecallVar('user_id'));
+			}
+			$params['PBX_PORTEUR'] = $billing_email;
+
+			$params_str = '';
+			foreach ($params as $key => $val) {
+				$params_str .= ' '.$key . '="'.$val.'"';
+			}
+			$run_line = $gw_params['binary'].' '.$params_str;
+
+//			$run_line = escapeshellcmd($run_line);
+//			echo escapeshellcmd($run_line);
+
+			exec ($run_line, $rets);
+
+			$ret = implode("\n", $rets);
+
+			$ret = preg_replace('/^(.*)!!/is', '', $ret);
+			$ret = rtrim($ret, '!');
+
+			return ''.$ret.'
'; + } + + function NeedPlaceButton($item_data, $tag_params, $gw_params) + { + return false; + } + + function processNotification($gw_params) + { + $result = $this->Application->HttpQuery->GetParams(); + $this->parsed_responce = $result; + + list ($sid, $auth_code) = explode(',', $result['reference']); + $session = $this->Application->recallObject('Session'); + $session->SID = $sid; + + $order_id = $this->Conn->GetOne('SELECT OrderId FROM '.TABLE_PREFIX.'Orders WHERE md5(OrderId) = '.$this->Conn->qstr($auth_code)); + $this->Application->SetVar('ord_id', $order_id); + $order = $this->Application->recallObject('ord'); + $order->Load($order_id); + + return $result['error'] === '00000' ? 1 : 0; + } + + function parseGWResponce($str, $gw_params) + { + $response = explode ("!", $str); + + $result = Array ( + 'code' => $response[1], + 'error' => $response[2], + 'merchant_id' => $response[3], + 'merchant_country' => $response[4], + 'amount' => $response[5], + 'transaction_id' => $response[6], + 'payment_means' => $response[7], + 'transmission_date' => $response[8], + 'payment_time' => $response[9], + 'payment_date' => $response[10], + 'response_code' => $response[11], + 'payment_certificate' => $response[12], + 'authorisation_id' => $response[13], + 'currency_code' => $response[14], + 'card_number' => $response[15], + 'cvv_flag' => $response[16], + 'cvv_response_code' => $response[17], + 'bank_response_code' => $response[18], + 'complementary_code' => $response[19], + 'complementary_info' => $response[20], + 'return_context' => $response[21], + 'caddie' => $response[22], + 'receipt_complement' => $response[23], + 'merchant_language' => $response[24], + 'language' => $response[25], + 'customer_id' => $response[26], + 'order_id' => $response[27], + 'customer_email' => $response[28], + 'customer_ip_address' => $response[29], + 'capture_day' => $response[30], + 'capture_mode' => $response[31], + 'data' => $response[32], + ); + $this->parsed_responce = $result; + return $result; + } + + function getGWResponce() + { + return serialize($this->parsed_responce); + } + + function getErrorMsg() + { + $msg = ''; + if ($this->parsed_responce['response_code'] != '00000') { + $msg = 'Transaction failed'; + } + return $msg; + } + } \ No newline at end of file Property changes on: releases/5.2.2-B2/units/gateways/gw_classes/paybox.php ___________________________________________________________________ Added: cvs2svn:cvs-rev + 1.2 Added: svn:keywords + Id Added: svn:eol-style + LF Index: releases/5.2.2-B2/units/gateways/gw_classes/paypal.php =================================================================== --- releases/5.2.2-B2/units/gateways/gw_classes/paypal.php (revision 0) +++ releases/5.2.2-B2/units/gateways/gw_classes/paypal.php (revision 16630) @@ -0,0 +1,269 @@ +Application->RecallVar('curr_iso'); + $available = explode(',', $gw_params['currency_code']); + $target = in_array($selected_cur, $available) ? $selected_cur : $available[0]; + + if( !$this->IsTestMode() ) + { + $currency_iso = $gw_params['currency_code']; + $ret['amount'] = $this->ConvertCurrency($item_data['SubTotal'], $target); + $ret['shipping'] = $this->ConvertCurrency($item_data['ShippingCost'], $target); + $ret['tax'] = $this->ConvertCurrency($item_data['VAT'], $target); + } + else + { + $ret['amount'] = 1; + $ret['shipping'] = 0; + $ret['tax'] = 0; + } + + $ret['quantity'] = 1; + $ret['cancel_return'] = $this->Application->HREF($tag_params['cancel_template'],'',Array('pass'=>'m')); + $ret['return'] = $this->Application->HREF($tag_params['return_template'],'',Array('pass'=>'m')); + $ret['no_note'] = 1; // customer is not prompted for notes + $ret['no_shipping'] = 1; // customer is not prompted for shipping address + $ret['rm'] = 2; // return method - POST + $ret['currency_code'] = $target; + $ret['invoice'] = $item_data['OrderNumber']; + $ret['business'] = $gw_params['business_account']; + + // prepopulated fields + $ret['address_override'] = 1; // override user's stored address + $ret['email'] = $item_data['BillingEmail']; + list($first_name, $last_name) = explode(' ', $item_data['BillingTo']); + $ret['first_name'] = $first_name; + $ret['last_name'] = $last_name; + $ret['address1'] = $item_data['BillingAddress1']; + $ret['address2'] = $item_data['BillingAddress2']; + $ret['city'] = $item_data['BillingCity']; + $ret['state'] = $item_data['BillingState']; + $ret['zip'] = $item_data['BillingZip']; + + /** @var kCountryStatesHelper $cs_helper */ + $cs_helper = $this->Application->recallObject('CountryStatesHelper'); + + $ret['country'] = $cs_helper->getCountryIso( $item_data['BillingCountry'] ); + $ret['notify_url'] = $this->getNotificationUrl() . '?sid=' . $this->Application->GetSID() . '&admin=1&order_id=' . $item_data['OrderId']; + + $ret['cmd'] = '_xclick'; // act as "Buy Now" PayPal button + return $ret; + } + + function getSubscriptionFields($item_data, $tag_params, $gw_params) + { + + $ret = Array(); + $ret['item_name'] = $item_data['item_name']; + $ret['item_number'] = $item_data['item_number']; + $ret['a1'] = $item_data['a1']; + $ret['p1'] = $item_data['p1']; + $ret['t1'] = $item_data['t1']; + $ret['a2'] = $item_data['a2']; + $ret['p2'] = $item_data['p2']; + $ret['t2'] = $item_data['t2']; + + $ret['p3'] = $item_data['p3']; + $ret['t3'] = $item_data['t3']; + $ret['src'] = $item_data['src']; + $ret['sra'] = $item_data['sra']; + $ret['srt'] = $item_data['srt']; + + $ret['custom'] = $item_data['OrderId']; + + $currency_iso = $gw_params['currency_code']; + $ret['a3'] = $this->ConvertCurrency($item_data['a3'], $currency_iso);; + $ret['tax'] = $this->ConvertCurrency($item_data['VAT'], $currency_iso); + if( $this->Application->isDebugMode() ) + { + + } + else + { + + } + +// $ret['quantity'] = 1; + $ret['cancel_return'] = $this->Application->HREF($tag_params['cancel_template'],'',Array('pass'=>'m')); + $ret['return'] = $this->Application->HREF($tag_params['return_template'],'',Array('pass'=>'m')); + $ret['no_note'] = 1; // customer is not prompted for notes + $ret['no_shipping'] = 1; // customer is not prompted for shipping address + $ret['rm'] = 2; // return method - POST + $ret['currency_code'] = $gw_params['currency_code']; + $ret['invoice'] = $item_data['OrderNumber']; + $ret['business'] = $gw_params['business_account']; + + // prepopulated fields + $ret['address_override'] = 1; // override user's stored address + $ret['email'] = $item_data['BillingEmail']; + list($first_name, $last_name) = explode(' ', $item_data['BillingTo']); + $ret['first_name'] = $first_name; + $ret['last_name'] = $last_name; + $ret['address1'] = $item_data['BillingAddress1']; + $ret['address2'] = $item_data['BillingAddress2']; + $ret['city'] = $item_data['BillingCity']; + $ret['state'] = $item_data['BillingState']; + $ret['zip'] = $item_data['BillingZip']; + + /** @var kCountryStatesHelper $cs_helper */ + $cs_helper = $this->Application->recallObject('CountryStatesHelper'); + + $ret['country'] = $cs_helper->getCountryIso( $item_data['BillingCountry'] ); + $ret['notify_url'] = $this->getNotificationUrl() . '?sid='.$this->Application->GetSID().'&admin=1&order_id='.$item_data['OrderId'].'&payment_type_id='.$tag_params['payment_type_id']; + $ret['cmd'] = '_xclick-subscriptions'; // act as "Buy Now" PayPal button + + $real_ret = array(); + foreach ($ret as $key => $val) + { + if ($val == '') continue; + $real_ret[$key] = $val; + } + + return $real_ret; + } + + function processNotification($gw_params) + { + $payment_status = $_POST['payment_status']; // save payment_status for later proceeding + + $_POST['cmd'] = '_notify-validate'; + + // status, of that PayPal server really has sent such notification to us + $status_map = Array('INVALID' => 0, 'VERIFIED' => 1); + + /** @var kCurlHelper $curl_helper */ + $curl_helper = $this->Application->recallObject('CurlHelper'); + + $curl_helper->SetPostData($_POST); + $n_status = $curl_helper->Send($gw_params['submit_url']); // INVALID, VERIFIED + + $n_status = $status_map[$n_status]; + + $success = ($n_status == 1) && ($payment_status == 'Completed') ? 1:0 ; // 1:0 is on purpose, false will result an SQL error ! + + if (!$success) return; + + $type = $_POST['txn_type']; + switch ($type) + { + case 'subscr_signup': + break; + case 'subscr_cancel': + break; + case 'subscr_failed': + break; + case 'subscr_payment': + $field_values = $this->Conn->GetRow('SELECT * FROM '.TABLE_PREFIX.'OrderItems WHERE OrderItemId = '.$_POST['item_number']); + $this->Application->HandleEvent(new kEvent('p:OnSubscriptionApprove', array('field_values' => $field_values))); + $success = 0; //this will eliminate OnCompleteOrder in gw_notify! + + /** @var kDBItem $org_order */ + $org_order = $this->Application->recallObject('ord.-original', 'ord', Array('skip_autoload' => true)); + + $org_order->Load($field_values['OrderId']); + + $order = $this->Application->recallObject('ord.-paypal', 'ord'); + $order->SetDBFieldsFromHash($org_order->GetFieldValues()); + $order->SetDBField('SubTotal', $field_values['Price']); + $order->SetDBField('OriginalAmout', $field_values['Price']); + $order->SetDBField('OrderDate', adodb_mktime()); + $order->UpdateFormattersSubFields(); + + $dup_item = false; + if ($org_order->GetDBField('Status') >= ORDER_STATUS_PROCESSED) { + $sql = 'SELECT MAX(SubNumber) FROM '.TABLE_PREFIX.'Orders WHERE Number = '.$org_order->GetDBField('Number'); + $num = $this->Conn->GetOne($sql) + 1; + $order->SetDBField('SubNumber', $num); + $dup_item = true; + } + else { + $sql = 'SELECT MAX(Number) FROM '.TABLE_PREFIX.'Orders'; + $num = $this->Conn->GetOne($sql) + 1; + $order->SetDBField('Number', $num); + $order->SetDBField('SubNumber', 0); + } + $order->SetDBField('PaymentType', $this->Application->GetVar('payment_type_id')); + $info = array( + 'BillingTo' => $_POST['first_name'].' '.$_POST['last_name'], + 'BillingCompany' => 'n/a (PayPal)', + 'BillingPhone' => 'n/a (PayPal)', + 'BillingFax' => '', + 'BillingEmail' => $_POST['payer_email'], + 'BillingAddress1' => 'n/a (PayPal)', + 'BillingCity' => 'n/a (PayPal)', + 'BillingState' => 'n/a (PayPal)', + 'BillingZip' => 'n/a (PayPal)', + 'BillingCountry' => '???', + ); + + // TODO: maybe this should be SetDBFieldsFromHash instead, because all data comes from inside. + $order->SetFieldsFromHash($info); + + $order->SetDBField('Status', ORDER_STATUS_PROCESSED); + + $order->Create(); + if ($dup_item) { + $query = 'INSERT INTO '.TABLE_PREFIX.'OrderItems + (OrderId, ProductId, ProductName, Quantity, QuantityReserved, FlatPrice, Price, BackOrderFlag, Weight, ShippingTypeId, ItemData, OptionsSalt) + SELECT + '.$order->GetId().' AS OrderId, ProductId, ProductName, Quantity, QuantityReserved, FlatPrice, Price, BackOrderFlag, Weight, ShippingTypeId, ItemData, OptionsSalt + FROM '.TABLE_PREFIX.'OrderItems + WHERE OrderItemId = '.$field_values['OrderItemId']; + } + else { + $query = 'UPDATE '.TABLE_PREFIX.'OrderItems SET OrderId = %s WHERE OrderItemId = %s'; + $query = sprintf($query, $order->GetId(), $field_values['OrderItemId']); + } + $this->Conn->Query($query); + + break; + case 'subscr_eot': + break; + case 'subscr_modify': + break; + } + + return $success; + } + } Property changes on: releases/5.2.2-B2/units/gateways/gw_classes/paypal.php ___________________________________________________________________ Added: cvs2svn:cvs-rev + 1.7 Added: svn:keywords + Id Added: svn:eol-style + LF Index: releases/5.2.2-B2/units/gateways/gw_classes/gw_base.php =================================================================== --- releases/5.2.2-B2/units/gateways/gw_classes/gw_base.php (revision 0) +++ releases/5.2.2-B2/units/gateways/gw_classes/gw_base.php (revision 16630) @@ -0,0 +1,261 @@ +Application->ProcessParsedTag('m', 'FormAction', Array() ); + } + + /** + * Processed input data and convets it to fields understandable by gateway + * + * @param Array $item_data + * @param Array $tag_params additional params for gateway passed through tag + * @param Array $gw_params gateway params from payment type config + * @return Array + */ + function getHiddenFields($item_data, $tag_params, $gw_params) + { + return Array( 'events[ord]' => 'OnCompleteOrder', + 'success_template' => $tag_params['return_template'], + 'failure_template' => $tag_params['cancel_template']); + } + + function NeedPlaceButton($item_data, $tag_params, $gw_params) + { + return true; + } + + /** + * Process notification about payment from payment gateway + * + * @param Array $gw_params + * @return bool + */ + function processNotification($gw_params) + { + + } + + /** + * Perform PREAUTH/SALE type transaction direct from php script wihtout redirecting to 3rd-party website + * + * @param Array $item_data + * @param Array $gw_params + * @return bool + */ + function DirectPayment($item_data, $gw_params) + { + return true; + } + + /** + * Perform SALE type transaction direct from php script wihtout redirecting to 3rd-party website + * + * @param Array $item_data + * @param Array $gw_params + * @return bool + */ + function Charge($item_data, $gw_params) + { + return true; + } + + /** + * Informs payment gateway, that order has been shipped + * + * @param Array $item_data + * @param Array $gw_params + * @return bool + */ + function OrderShipped($item_data, $gw_params) + { + + } + + /** + * Informs payment gateway, that order has been declined + * + * @param Array $item_data + * @param Array $gw_params + * @return bool + */ + function OrderDeclined($item_data, $gw_params) + { + + } + + /** + * Returns gateway responce from last operation + * + * @return string + */ + function getGWResponce() + { + return $this->gw_responce; + } + + /** + * Parse previously saved gw responce into associative array + * + * @param string $gw_responce + * @param Array $gw_params + * @return Array + */ + function parseGWResponce($gw_responce, $gw_params) + { + return $this->gw_responce; + } + + /** + * Returns true if we should use testing mode + * + * @return bool + */ + function IsTestMode() + { + return defined('DEBUG_MODE') && kUtil::constOn('DBG_PAYMENT_GW'); + } + + /** + * Convery primary currency to selected (if they are the same, converter will just return) + * + * @param double $value + * @param string $iso + * @param bool $format_value + * @return double + */ + function ConvertCurrency($value, $iso, $format_value = true) + { + /** @var CurrencyRates $converter */ + $converter = $this->Application->recallObject('CurrencyRates'); + + $value = $converter->Convert($value, 'PRIMARY', $iso); + return $format_value ? sprintf('%.2f', $value) : $value; + } + + function InstallData() + { + return array(); + } + + function Install() + { + if ($this->IsInstalled()) { + return; + } + + $data = $this->InstallData(); + if (!$data) { + return ; + } + + // 1. create gateway record + $fields_hash = Array (); + $gw_fields = Array ('Name', 'ClassName', 'ClassFile', 'RequireCCFields'); + foreach ($gw_fields as $gw_field) { + $fields_hash[$gw_field] = $data['Gateway'][$gw_field]; + } + $this->Conn->doInsert($fields_hash, TABLE_PREFIX.'Gateways'); + $gw_id = $this->Conn->getInsertID(); + + // 2. create DISABLED payment type, that uses this gateway (used for storing configuration properties of gateway) + /** @var kDBItem $payment_type */ + $payment_type = $this->Application->recallObject('pt.-item', null, Array ('skip_autoload' => true)); + + $payment_type->Clear(); + $fields_hash = Array ( + 'Name' => $data['Gateway']['Name'], + 'l' . $this->Application->GetDefaultLanguageId() . '_Description' => $data['Gateway']['Name'], + 'BuiltIn' => 1, + 'GatewayId' => $gw_id, + ); + $payment_type->SetDBFieldsFromHash($fields_hash); + $created = $payment_type->Create(); + if (!$created) { + return ; + } + + // 3. create gateway configuration fields + foreach ($data['ConfigFields'] as $field => $properties) { + $fields_hash = Array ( + 'SystemFieldName' => $field, + 'GatewayId' => $gw_id, + 'FieldName' => $properties['Name'], + 'ElementType' => $properties['Type'], + 'ValueList' => $properties['ValueList'], + ); + $this->Conn->doInsert($fields_hash, TABLE_PREFIX.'GatewayConfigFields'); + $fld_id = $this->Conn->getInsertID(); + + // 4. set default value for configuration property of gateway + $fields_hash = Array ( + 'GWConfigFieldId' => $fld_id, + 'PaymentTypeId' => $payment_type->GetID(), + 'Value' => $properties['Default'], + ); + $this->Conn->doInsert($fields_hash, TABLE_PREFIX.'GatewayConfigValues'); + } + } + + function IsInstalled() + { + $data = $this->InstallData(); + if (!$data) { + return true; + } + + $sql = 'SELECT GatewayId + FROM '.TABLE_PREFIX.'Gateways + WHERE ClassName = '.$this->Conn->qstr($data['Gateway']['ClassName']); + return $this->Conn->GetOne($sql); + } + + function getErrorMsg() + { + return ''; + } + + function gettestccnumbers() + { + return array(); + } + + function getNotificationUrl($script = 'gw_notify.php', $use_ssl = null) + { + // custom path can be: units/gateways/gw_classes/notify_scripts/google_checkout_shippings.php' + + $ret = MODULES_PATH . '/in-commerce/' . $script; + $ret = preg_replace('/^' . preg_quote(FULL_PATH . '/', '/') . '/', $this->Application->BaseURL('', $use_ssl), $ret); + + return str_replace(DIRECTORY_SEPARATOR, '/', $ret); + } + } \ No newline at end of file Property changes on: releases/5.2.2-B2/units/gateways/gw_classes/gw_base.php ___________________________________________________________________ Added: cvs2svn:cvs-rev + 1.12.2.2 Added: svn:keywords + Id Added: svn:eol-style + LF Index: releases/5.2.2-B2/units/gateways/gw_classes/ideal_nl.php =================================================================== --- releases/5.2.2-B2/units/gateways/gw_classes/ideal_nl.php (revision 0) +++ releases/5.2.2-B2/units/gateways/gw_classes/ideal_nl.php (revision 16630) @@ -0,0 +1,170 @@ + Array('Name' => 'iDEAL.nl', 'ClassName' => 'kGWiDEALnl', 'ClassFile' => 'ideal_nl.php', 'RequireCCFields' => 0), + 'ConfigFields' => Array( + 'partner_id' => Array('Name' => 'Partner ID', 'Type' => 'text', 'ValueList' => '', 'Default' => ''), + 'request_url' => Array('Name' => 'Request URL', 'Type' => 'text', 'ValueList' => '', 'Default' => 'http://www.mollie.nl/xml/ideals'), + 'shipping_control' => Array('Name' => 'Shipping Control', 'Type' => 'select', 'ValueList' => '3=la_CreditDirect,4=la_CreditPreAuthorize', 'Default' => '3'), + ) + ); + return $data; + } + + /** + * Processed input data and convets it to fields understandable by gateway + * + * @param Array $item_data + * @param Array $tag_params additional params for gateway passed through tag + * @param Array $gw_params gateway params from payment type config + * @return Array + */ + function getHiddenFields($item_data, $tag_params, $gw_params) + { + $this->Application->StoreVar('gw_success_template',$tag_params['return_template']); + $this->Application->StoreVar('gw_cancel_template',$tag_params['cancel_template']); + + /** @var kCurlHelper $curl_helper */ + $curl_helper = $this->Application->recallObject('CurlHelper'); + + $banks = $curl_helper->Send($gw_params['request_url'].'?a=banklist'); + + /** @var kXMLHelper $parser */ + $parser = $this->Application->recallObject('kXMLHelper'); + $bank_data =& $parser->Parse($banks); + + $bank_data->FindChild('response'); + $banks = array(); + foreach ($bank_data->Children as $a_child) { + if ($a_child->Name != 'BANK') continue; + $banks[$a_child->FindChildValue('bank_id')] = $a_child->FindChildValue('bank_name'); + } + + $ret = $this->Application->Phrase('lu_Select_iDEAL_bank').': '; + $ret .= ''."\n"; + return $ret; + } + + function DirectPayment($item_data, $gw_params) + { + $fields = array(); + + $fields['a'] = 'fetch'; + $fields['partnerid'] = $gw_params['partner_id']; + $txt_amount = sprintf("%.2f", $item_data['TotalAmount']); + $fields['amount'] = str_replace( Array('.', ','), '', $txt_amount); + $fields['bank_id'] = $this->Application->GetVar('ideal_nl_bank_id'); + $fields['description'] = 'Invoice #'.$item_data['OrderNumber']; + $fields['returnurl'] = $this->getNotificationUrl() . '?order_id='.$item_data['OrderId']; + $fields['reporturl'] = $this->getNotificationUrl() . '?mode=report&order_id='.$item_data['OrderId']; + + /** @var kCurlHelper $curl_helper */ + $curl_helper = $this->Application->recallObject('CurlHelper'); + + $curl_helper->SetRequestData($fields); + $transaction_xml = $curl_helper->Send($gw_params['request_url']); + + /** @var kXMLHelper $parser */ + $parser = $this->Application->recallObject('kXMLHelper'); + $trans_data =& $parser->Parse($transaction_xml); + $transaction_id = $trans_data->FindChildValue('transaction_id'); + $url = $trans_data->FindChildValue('url'); + + if ($transaction_id && $url) { + $this->Application->Redirect('external:'.$url); + } + else { + $error_msg = $trans_data->FindChildValue('message'); + $this->parsed_responce['XML'] = $transaction_xml; + $this->Application->SetVar('failure_template', $this->Application->RecallVar('gw_cancel_template')); + $this->parsed_responce['MESSAGE'] = $error_msg ? $error_msg : 'Unknown gateway error ('.kUtil::escape($transaction_xml, kUtil::ESCAPE_HTML).')'; + return false; + } + + return true; + } + + function getErrorMsg() + { + return $this->parsed_responce['MESSAGE']; + } + + function getGWResponce() + { + return serialize($this->parsed_responce); + } + + function processNotification($gw_params) + { + // silent mode + if ($this->Application->GetVar('mode') == 'report') { + $fields = array(); + + $fields['a'] = 'check'; + $fields['partnerid'] = $gw_params['partner_id']; + $fields['transaction_id'] = $this->Application->GetVar('transaction_id'); + $fields['bank_id'] = $this->Application->GetVar('ideal_nl_bank_id'); + + /** @var kCurlHelper $curl_helper */ + $curl_helper = $this->Application->recallObject('CurlHelper'); + + $curl_helper->SetRequestData($fields); + $check_xml = $curl_helper->Send($gw_params['request_url']); + + /** @var kXMLHelper $parser */ + $parser = $this->Application->recallObject('kXMLHelper'); + $trans_data =& $parser->Parse($check_xml); + + $response = $trans_data->FindChild('order'); + foreach ($response->Children as $a_child) { + $this->parsed_responce[$a_child->Name] = $a_child->Data; + } + $this->parsed_responce['XML'] = $check_xml; + + $result = $trans_data->FindChildValue('payed') == 'true' ? 1:0; + return $result; + } + else { + $order = $this->Application->recallObject('ord'); + if ($order->GetDBField('Status') == ORDER_STATUS_INCOMPLETE) { + // error + $t = $this->Application->RecallVar('gw_cancel_template'); + $this->parsed_responce = unserialize($order->GetDBField('GWResult1')); + $this->Application->StoreVar('gw_error', $this->getErrorMsg()); + $this->Application->Redirect($t, array('pass'=>'m', 'm_cat_id'=>0)); + } + else { + // ok + $t = $this->Application->RecallVar('gw_success_template'); + $this->Application->Redirect($t, array('pass'=>'m', 'm_cat_id'=>0)); + + } + } + } + } \ No newline at end of file Property changes on: releases/5.2.2-B2/units/gateways/gw_classes/ideal_nl.php ___________________________________________________________________ Added: cvs2svn:cvs-rev + 1.2 Added: svn:keywords + Id Added: svn:eol-style + LF Index: releases/5.2.2-B2/units/gateways/gw_classes/multicards.php =================================================================== --- releases/5.2.2-B2/units/gateways/gw_classes/multicards.php (revision 0) +++ releases/5.2.2-B2/units/gateways/gw_classes/multicards.php (revision 16630) @@ -0,0 +1,122 @@ + Array('Name' => 'Multicards', 'ClassName' => 'kMultiCardsGW', 'ClassFile' => 'multicards.php', 'RequireCCFields' => 0), + 'ConfigFields' => Array( + 'submit_url' => Array('Name' => 'Submit URL', 'Type' => 'text', 'ValueList' => '', 'Default' => 'https://secure.multicards.com/cgi-bin/order2/processorder1.pl'), + 'merchant_id' => Array('Name' => 'Merchant ID', 'Type' => 'text', 'ValueList' => '', 'Default' => ''), + 'merchant_url_idx' => Array('Name' => 'Merchant Order Page Id', 'Type' => 'text', 'ValueList' => '', 'Default' => ''), + ) + ); + return $data; + } + + /** + * Returns payment form submit url + * + * @param Array $gw_params gateway params from payment type config + * @return string + */ + function getFormAction($gw_params) + { + return $gw_params['submit_url']; + } + + /** + * Processed input data and convets it to fields understandable by gateway + * + * @param Array $item_data + * @param Array $tag_params additional params for gateway passed through tag + * @param Array $gw_params gateway params from payment type config + * @return Array + */ + function getHiddenFields($item_data, $tag_params, $gw_params) + { + $ret = Array(); + + $ret['mer_id'] = $gw_params['merchant_id']; + $ret['mer_url_idx'] = $gw_params['merchant_url_idx']; + + $ret['num_items'] = 100; + $ret['item1_price'] = $item_data['TotalAmount']; + $ret['item1_desc'] = 'Order #'.$item_data['OrderNumber']; + $ret['item1_qty'] = 1; + + +// $ret['cancel_return'] = $this->Application->HREF($tag_params['cancel_template'],'',Array('pass'=>'m')); +// $ret['return'] = $this->Application->HREF($tag_params['return_template'],'',Array('pass'=>'m')); +// $ret['notify_url'] = $this->getNotificationUrl() . '?sid='.$this->Application->GetSID().'&admin=1&order_id='.$item_data['OrderId']; +// $ret['cmd'] = '_xclick'; // act as "Buy Now" PayPal button + + $ret['no_note'] = 1; // customer is not prompted for notes + $ret['no_shipping'] = 1; // customer is not prompted for shipping address + $ret['rm'] = 2; // return method - POST + $ret['currency_code'] = $target; + $ret['invoice'] = $item_data['OrderNumber']; + $ret['business'] = $gw_params['business_account']; + + // prepopulated fields + $billing_email = $item_data['BillingEmail']; + if (!$billing_email) { + $billing_email = $this->Conn->GetOne(' SELECT Email FROM '.$this->Application->getUnitOption('u', 'TableName').' + WHERE PortalUserId = '.$this->Application->RecallVar('user_id')); + } + $ret['cust_email'] = $billing_email; + + $ret['cust_name'] = $item_data['BillingTo']; + $ret['cust_company'] = $item_data['BillingCompany']; + $ret['cust_phone'] = $item_data['BillingPhone']; + $ret['cust_address1'] = $item_data['BillingAddress1']; + $ret['cust_address2'] = $item_data['BillingAddress2']; + $ret['cust_city'] = $item_data['BillingCity']; + $ret['cust_state'] = $item_data['BillingState']; + $ret['cust_zip'] = $item_data['BillingZip'] ? $item_data['BillingZip'] : '99999'; + $ret['cust_country'] = $item_data['BillingCountry']; + + $ret['user1'] = $this->Application->GetSID().','.MD5($item_data['OrderId']); + + $url = $this->Application->HREF($tag_params['return_template'], '', array('pass'=>'m')); + $ret['user2'] = $url; + + return $ret; + } + + function processNotification($gw_params) + { + $this->parsed_responce = $_POST; + + list ($sid, $auth_code) = explode(',', $this->Application->GetVar('user1')); + $session = $this->Application->recallObject('Session'); + $session->SID = $sid; + + $order_id = $this->Conn->GetOne('SELECT OrderId FROM '.TABLE_PREFIX.'Orders WHERE md5(OrderId) = '.$this->Conn->qstr($auth_code)); + $this->Application->SetVar('ord_id', $order_id); + $order = $this->Application->recallObject('ord'); + $order->Load($order_id); + + $url = $this->Application->GetVar('user2'); + echo ''.$this->Application->Phrase('lu_text_MulticardsContinue').''; + + return 1; + } + } \ No newline at end of file Property changes on: releases/5.2.2-B2/units/gateways/gw_classes/multicards.php ___________________________________________________________________ Added: cvs2svn:cvs-rev + 1.3 Added: svn:keywords + Id Added: svn:eol-style + LF Index: releases/5.2.2-B2/units/gateways/gw_classes/rightconnect.php =================================================================== --- releases/5.2.2-B2/units/gateways/gw_classes/rightconnect.php (revision 0) +++ releases/5.2.2-B2/units/gateways/gw_classes/rightconnect.php (revision 16630) @@ -0,0 +1,224 @@ +Conn->Query($query); + $id = $this->Conn->getInsertID(); + + $query = "INSERT INTO `".TABLE_PREFIX."GatewayConfigFields` ( `GWConfigFieldId` , `SystemFieldName` , `FieldName` , `ElementType` , `ValueList` , `GatewayId` ) + VALUES ( + '', 'submit_url', 'Submit URL', 'text', '', '$id' + ), ( + '', 'user_account', 'User Account', 'text', '', '$id' + ), ( + '', 'password', 'User Account', 'text', '', '$id' + ), + ( + '', 'encapsulate_char', 'Encapsualte Char', 'text', '', '$id' + )"; + $this->Conn->Query($query); + }*/ + + function DirectPayment($item_data, $gw_params) + { + + /*$post_fields["card_holder"] = "test test"; + $post_fields["cardtype"] = "Visa"; + $post_fields["card_number"] = "4444333322221111"; + $post_fields["cvv2"] = "123"; + $post_fields["exp_mon"] = "05"; + $post_fields["exp_year"] = "05"; + $post_fields["address1"] = "test"; + $post_fields["city"] = "test"; + $post_fields["state"] = "CA"; + $post_fields["zip"] = "90069"; + $post_fields["country"] = "USA"; + $post_fields["firstname"] = "test"; + $post_fields["lastname"] = "test"; + $post_fields["email"] = "customer@yourdomain.com"; + $post_fields["merchant_account"] = "demo"; + $post_fields["trans_amount"] = "8.98"; + $post_fields["user1"] = "DELIM"; + $post_fields["ALIAS"] = "www.yourdomain.com"; + $post_fields["customer_ip"] = $this->Application->getClientIp(); + $post_fields["ADMIN_EMAIL"] = "admin@yourdomain.com";*/ + + + $post_fields = Array(); + // -- Login Information -- + //$post_fields['x_version'] = '3.1'; + $post_fields["user1"] = "DELIM"; + + //$post_fields['x_type'] = $gw_params['shipping_control'] == SHIPPING_CONTROL_PREAUTH ? 'AUTH_ONLY' : 'AUTH_CAPTURE'; + + $post_fields['merchant_account'] = $gw_params['user_account']; + $post_fields['merchant_pass'] = $gw_params['password']; + + if( $this->IsTestMode() ) $post_fields['x_test_request'] = 'True'; + + // -- Payment Details -- + $names = explode(' ', $item_data['BillingTo'], 2); + $post_fields['firstname'] = getArrayValue($names, 0); + $post_fields['lastname'] = getArrayValue($names, 1); + $post_fields['trans_amount'] = sprintf('%.2f', $item_data['TotalAmount']); + + //$post_fields['x_company'] = $item_data['BillingCompany']; + + $post_fields['card_number'] = $item_data['PaymentAccount']; + $post_fields['card_holder'] = $item_data['PaymentNameOnCard']; + $post_fields['cvv2'] = $item_data['PaymentCVV2']; + + list($exp_mon,$exp_year) = explode('/', $item_data['PaymentCCExpDate']); + $post_fields['exp_mon'] = $exp_mon; + $post_fields['exp_year'] = $exp_year; + + $post_fields['address1'] = $item_data['BillingAddress1']; + $post_fields['address2'] = $item_data['BillingAddress2']; + $post_fields['city'] = $item_data['BillingCity']; + $post_fields['state'] = $item_data['BillingState']; + $post_fields['zip'] = $item_data['BillingZip']; + + $post_fields['country'] = $item_data['BillingCountry']; + + $post_fields['user2'] = $item_data['PortalUserId']; + $post_fields['user3'] = $item_data['OrderNumber']; + $post_fields['customer_email'] = 'FALSE'; + + $post_fields['customer_addr'] = $item_data['OrderIP']; // according to fields list in doc + $post_fields['customer_ip'] = $item_data['OrderIP']; // according to example from doc + $post_fields["email"] = $item_data['BillingEmail']; + $post_fields["ADMIN_EMAIL"] = $this->Application->ConfigValue('DefaultEmailSender'); + + /** @var kCurlHelper $curl_helper */ + $curl_helper = $this->Application->recallObject('CurlHelper'); + + $curl_helper->SetPostData($post_fields); + $this->gw_responce = $curl_helper->Send($gw_params['submit_url']); + + $gw_responce = $this->parseGWResponce(null, $gw_params); + + // gw_error_msg: $gw_response['responce_reason_text'] + // gw_error_code: $gw_response['responce_reason_code'] + return ($gw_responce['responce_code'] != 1) ? false : true; + } + + /** + * Captures Authorized transaction by transaction ID + * + * @param Array $item_data + * @param Array $gw_params + * @return bool + */ + function Charge($item_data, $gw_params) + { + return true; + } + + /** + * Parse previosly saved gw responce into associative array + * + * @param string $gw_responce + * @param Array $gw_params + * @return Array + */ + function parseGWResponce($gw_responce = null, $gw_params) + { + if( !isset($gw_responce) ) $gw_responce = $this->gw_responce; + + $fields = Array( + 'responce_code', // 0 + 'responce_sub_code', // 1 + 'responce_reason_code', // 2 + 'responce_reason_text', // 3 + 'approval_code', // 4 + 'avs_result_code', // 5 + 'transaction_id', // 6 + 'fraud_score', // 7 + 'not_used8', // 8 + 'amount', // 9 + 'not_used10', // 10 + 'transaction_type', // 11 + 'not_used_customer_id', // 12 + 'first_name', // 13 + 'last_name', // 14 + 'not_documented_empty_field', // 15 !!!!!!!!!!! DOES NOT MATCH DOCUMENTATION + 'address', // 16 + 'city', // 17 + 'state', // 18 + 'zip', // 19 + 'country', // 20 + 'phone', // 21 + 'fax', // 22 + 'email', // 23 + 'ship_name', // 24 + 'not_used25', // 25 + 'not_used26', // 26 + 'ship_address', // 27 + 'ship_city', // 28 + 'ship_state', // 29 + 'ship_zip', // 30 + 'ship_country', // 31 + 'tax', // 32 + 'not_used32', // 33 + 'not_used33', // 34 + 'not_used34', // 35 + 'not_used35', // 36 + 'not_used36', // 37 + 'cvv_responce', // 38 + 'receipt_number', // 39 + 'passthru1', // 40 + 'passthru2', // 41 + 'passthru3', // 42 + 'passthru4', // 43 + 'passthru5', // 44 + 'passthru6', // 45 + 'passthru7', // 46 + 'passthru8', // 47 + 'passthru9', // 48 + 'passthru10', // 49 + ); + + $encapsulate_char = $gw_params['encapsulate_char']; + if($encapsulate_char) + { + $ec_length = strlen($encapsulate_char); + $gw_responce = substr($gw_responce, $ec_length, $ec_length * -1); + } + + $gw_responce = explode($encapsulate_char.','.$encapsulate_char, $gw_responce); + $ret = Array(); + foreach($fields as $field_index => $field_name) + { + $ret[$field_name] = $gw_responce[$field_index]; + unset($gw_responce[$field_index]); + } + $this->parsed_responce = $ret; + return kUtil::array_merge_recursive($ret, $gw_responce); // returns unparsed fields with they original indexes together with parsed ones + } + + function getGWResponce() + { + return serialize($this->parsed_responce); + } + + } \ No newline at end of file Property changes on: releases/5.2.2-B2/units/gateways/gw_classes/rightconnect.php ___________________________________________________________________ Added: cvs2svn:cvs-rev + 1.5 Added: svn:keywords + Id Added: svn:eol-style + LF Index: releases/5.2.2-B2/units/gateways/gw_tag_processor.php =================================================================== --- releases/5.2.2-B2/units/gateways/gw_tag_processor.php (revision 0) +++ releases/5.2.2-B2/units/gateways/gw_tag_processor.php (revision 16630) @@ -0,0 +1,127 @@ +Application->GetVar('pt_id'); + $GWConfigValue = $this->Application->recallObject('gwfv'); + + $sql = 'SELECT Value, GWConfigFieldId FROM '.$GWConfigValue->TableName.' WHERE PaymentTypeId = '.$payment_type_id; + $this->ConfigValues = $this->Conn->GetCol($sql,'GWConfigFieldId'); + } + + function gwConfigValue($params) + { + /** @var kDBItem $object */ + $object = $this->getObject($params); + + $id = $object->GetID(); + + $value = isset($this->ConfigValues[$id]) ? $this->ConfigValues[$id] : ''; + if ( !array_key_exists('no_special', $params) || !$params['no_special'] ) { + $value = kUtil::escape($value); + } + + if ( getArrayValue($params, 'checked') ) { + $value = ($value == 1) ? 'checked' : ''; + } + + return $value; + } + + function PrintList($params) + { + $list = $this->Application->recallObject( $this->getPrefixSpecial(), $this->Prefix.'_List', $params); + $id_field = $this->Application->getUnitOption($this->Prefix,'IDField'); + + $list->Query(); + $list->GoFirst(); + + $block_params=$this->prepareTagParams($params); + $block_params['name']=$params['block']; + $block_params['pass_params']='true'; + + $payment_type_object = $this->Application->recallObject('pt'); + + $o = ''; + + while (!$list->EOL()) + { + $this->Application->SetVar( $this->getPrefixSpecial().'_id', $list->GetDBField($id_field) ); + + $display_style = $payment_type_object->GetDBField('GatewayId') == $list->GetDBField('GatewayId') ? 'table-row' : 'none'; + $block_params['input_block'] = $params['input_block_prefix'].$list->GetDBField('ElementType'); + $block_params['gateway_id'] = $list->GetDBField('GatewayId'); + $block_params['display'] = $display_style; + + $o .= $this->Application->ParseBlock($block_params, 1); + + $list->GoNext(); + } + + return $o; + } + + /** + * Prints list a all possible field options + * + * @param Array $params + * @return string + * @access protected + */ + protected function PredefinedOptions($params) + { + /** @var kDBItem $object */ + $object = $this->getObject($params); + + $block_params = $this->prepareTagParams($params); + $block_params['name'] = $this->SelectParam($params, 'render_as,block'); + $block_params['pass_params'] = 'true'; + + $o = ''; + $value = $this->gwConfigValue($params); + $options = explode(',', $object->GetDBField('ValueList')); + + foreach ($options as $key_val) { + list($key, $val) = explode('=', $key_val); + $block_params['key'] = $key; + $block_params['option'] = $val; + $block_params['selected'] = ($key == $value ? ' ' . $params['selected'] : ''); + $block_params['PrefixSpecial'] = $this->getPrefixSpecial(); + $o .= $this->Application->ParseBlock($block_params, 1); + } + + return $o; + } +} \ No newline at end of file Property changes on: releases/5.2.2-B2/units/gateways/gw_tag_processor.php ___________________________________________________________________ Added: cvs2svn:cvs-rev + 1.7.2.1 Added: svn:keywords + Id Added: svn:eol-style + LF Index: releases/5.2.2-B2/units/sections/sections_config.php =================================================================== --- releases/5.2.2-B2/units/sections/sections_config.php (revision 0) +++ releases/5.2.2-B2/units/sections/sections_config.php (revision 16630) @@ -0,0 +1,34 @@ + 'in-commerce-sections', + + 'EventHandlerClass' => Array ('class' => 'InCommerceEventHandler', 'file' => 'section_eh.php', 'build_event' => 'OnBuild'), // for OnAfterConfigRead event + 'TagProcessorClass' => Array ('class' => 'kTagProcessor', 'file' => '', 'build_event' => 'OnBuild'), // for tree drawing + + 'Hooks' => Array ( + Array ( + 'Mode' => hBEFORE, + 'Conditional' => false, + 'HookToPrefix' => 'site-domain', + 'HookToSpecial' => '*', + 'HookToEvent' => Array ('OnAfterConfigRead'), + 'DoPrefix' => '', + 'DoSpecial' => '*', + 'DoEvent' => 'OnModifySiteDomainConfig', + ), + ), + ); Property changes on: releases/5.2.2-B2/units/sections/sections_config.php ___________________________________________________________________ Added: svn:keywords + Id Added: svn:eol-style + LF Index: releases/5.2.2-B2/units/sections/section_eh.php =================================================================== --- releases/5.2.2-B2/units/sections/section_eh.php (revision 0) +++ releases/5.2.2-B2/units/sections/section_eh.php (revision 16630) @@ -0,0 +1,101 @@ +Application->getUnitOption($event->MasterEvent->Prefix, 'EditTabPresets'); + $edit_tab_presets['Default']['in-commerce'] = Array ( + 'title' => 'la_title_In-Commerce', 't' => 'in-commerce/site_domains/site_domain_edit', 'priority' => 2.1 + ); + $this->Application->setUnitOption($event->MasterEvent->Prefix, 'EditTabPresets', $edit_tab_presets); + + $title_presets = $this->Application->getUnitOption($event->MasterEvent->Prefix, 'TitlePresets'); + $title_presets['site_domain_edit_in_commerce'] = Array ( + 'prefixes' => Array ('site-domain'), 'format' => "#site-domain_status# '#site-domain_titlefield#' - !la_title_In-Commerce!", + 'toolbar_buttons' => Array ('select', 'cancel', 'reset_edit', 'prev', 'next'), + ); + $this->Application->setUnitOption($event->MasterEvent->Prefix, 'TitlePresets', $title_presets); + + $new_fields = Array ( + 'BillingCountry' => Array ( + 'type' => 'string', 'max_len' => 3, + 'formatter' => 'kOptionsFormatter', + 'options_sql' => ' SELECT IF(l%2$s_Name = "", l%3$s_Name, l%2$s_Name) AS Name, IsoCode + FROM ' . TABLE_PREFIX . 'CountryStates + WHERE Type = ' . DESTINATION_TYPE_COUNTRY . ' + ORDER BY Name', + 'option_key_field' => 'IsoCode', 'option_title_field' => 'Name', + 'not_null' => 1, 'default' => '' + ), + 'ShippingCountry' => Array ( + 'type' => 'string', 'max_len' => 3, + 'formatter' => 'kOptionsFormatter', + 'options_sql' => ' SELECT IF(l%2$s_Name = "", l%3$s_Name, l%2$s_Name) AS Name, IsoCode + FROM ' . TABLE_PREFIX . 'CountryStates + WHERE Type = ' . DESTINATION_TYPE_COUNTRY . ' + ORDER BY Name', + 'option_key_field' => 'IsoCode', 'option_title_field' => 'Name', + 'not_null' => 1, 'default' => '' + ), + 'PrimaryCurrencyId' => Array ( + 'type' => 'int', + 'formatter' => 'kOptionsFormatter', 'options_sql' => 'SELECT %s FROM ' . TABLE_PREFIX . 'Currencies WHERE Status = 1 ORDER BY ISO', 'option_key_field' => 'CurrencyId', 'option_title_field' => 'Name', 'use_phrases' => 1, + 'not_null' => 1, 'default' => 0 + ), + 'Currencies' => Array ( + 'type' => 'string', 'max_len' => 255, + 'formatter' => 'kOptionsFormatter', 'options_sql' => 'SELECT %s FROM ' . TABLE_PREFIX . 'Currencies WHERE Status = 1 ORDER BY ISO', 'option_key_field' => 'CurrencyId', 'option_title_field' => 'Name', 'use_phrases' => 1, + 'not_null' => 1, 'default' => '' + ), + 'PrimaryPaymentTypeId' => Array ( + 'type' => 'int', + 'formatter' => 'kOptionsFormatter', 'options_sql' => 'SELECT %s FROM ' . TABLE_PREFIX . 'PaymentTypes WHERE Status = 1 ORDER BY Name ASC', 'option_key_field' => 'PaymentTypeId', 'option_title_field' => 'Name', + 'not_null' => 1, 'default' => 0 + ), + 'PaymentTypes' => Array ( + 'type' => 'string', 'max_len' => 255, + 'formatter' => 'kOptionsFormatter', 'options_sql' => 'SELECT %s FROM ' . TABLE_PREFIX . 'PaymentTypes WHERE Status = 1 ORDER BY Name ASC', 'option_key_field' => 'PaymentTypeId', 'option_title_field' => 'Name', + 'not_null' => 1, 'default' => '' + ), + ); + + $fields = $this->Application->getUnitOption($event->MasterEvent->Prefix, 'Fields'); + $this->Application->setUnitOption($event->MasterEvent->Prefix, 'Fields', array_merge($fields, $new_fields)); + + $new_columns = Array ( + 'BillingCountry' => Array ('filter_block' => 'grid_options_filter', 'width' => 250, ), + 'ShippingCountry' => Array ('filter_block' => 'grid_options_filter', 'width' => 250, ), + 'PrimaryCurrencyId' => Array ('title' => 'column:la_fld_Currency', 'filter_block' => 'grid_options_filter', 'width' => 250, ), + 'PrimaryPaymentTypeId' => Array ('title' => 'column:la_fld_PaymentType', 'filter_block' => 'grid_options_filter', 'width' => 250, ), + ); + + $grids = $this->Application->getUnitOption($event->MasterEvent->Prefix, 'Grids'); + $grids['Default']['Fields'] = array_merge($grids['Default']['Fields'], $new_columns); + $this->Application->setUnitOption($event->MasterEvent->Prefix, 'Grids', $grids); + + if (!$this->Application->isAdmin && is_object($this->Application->siteDomain)) { + // re-configure object, because it's recalled before kUnitConfigReader::AfterConfigRead is called + $this->Application->siteDomain->Configure(); + } + } + + } Property changes on: releases/5.2.2-B2/units/sections/section_eh.php ___________________________________________________________________ Added: svn:keywords + Id Added: svn:eol-style + LF Index: releases/5.2.2-B2/units/downloads/downloads_config.php =================================================================== --- releases/5.2.2-B2/units/downloads/downloads_config.php (revision 0) +++ releases/5.2.2-B2/units/downloads/downloads_config.php (revision 16630) @@ -0,0 +1,116 @@ + 'down', + 'ItemClass' => Array ('class' => 'kDBItem', 'file' => '', 'build_event' => 'OnItemBuild'), + 'ListClass' => Array ('class' => 'kDBList', 'file' => '', 'build_event' => 'OnListBuild'), + 'EventHandlerClass' => Array ('class' => 'kDBEventHandler', 'file' => '', 'build_event' => 'OnBuild'), + 'TagProcessorClass' => Array ('class' => 'kDBTagProcessor', 'file' => '', 'build_event' => 'OnBuild'), + + 'RegisterClasses' => Array ( + Array ('pseudo' => 'DownloadHelper', 'class' => 'DownloadHelper', 'file' => 'download_helper.php', 'build_event' => ''), + ), + + 'AutoLoad' => true, + + /*'Hooks' => Array ( + Array ( + 'Mode' => hBEFORE, + 'Conditional' => true, + 'HookToPrefix' => 'p', + 'HookToSpecial' => '', + 'HookToEvent' => Array ( 'onPreSave' ), + 'DoPrefix' => 'pr', + 'DoSpecial' => 'tang', + 'DoEvent' => 'OnArrange', + ), + ),*/ + + 'QueryString' => Array ( + 1 => 'id', + 2 => 'Page', + 3 => 'PerPage', + 4 => 'event', + 5 => 'mode', + ), + + 'TitlePresets' => Array ( + 'downloads_list' => Array ( + 'prefixes' => Array ('down_List'), 'format' => "!la_title_FileDownloads!", + ), + ), + + 'PermSection' => Array ('main' => 'in-commerce:downloadlog'), + + 'Sections' => Array ( + 'in-commerce:downloadlog' => Array ( + 'parent' => 'in-portal:reports', + 'icon' => 'download_log', + 'label' => 'la_tab_DownloadLog', + 'url' => Array ('t' => 'in-commerce/downloads/downloads_list', 'pass' => 'm'), + 'permissions' => Array ('view', 'delete'), + 'priority' => 7, + 'type' => stTREE, + ), + ), + + 'IDField' => 'DownloadId', + 'TitleField' => 'Name', + 'TableName' => TABLE_PREFIX.'UserDownloads', + + 'ListSQLs' => Array ( + '' => ' SELECT * + FROM %s', + ), + + 'ListSortings' => Array ( + '' => Array ( + 'Sorting' => Array ('StartedOn' => 'desc'), + ) + ), + + 'Fields' => Array ( + 'DownloadId' => Array ('type' => 'int', 'not_null' => 1, 'default' => 0), + 'PortalUserId' => Array ('type' => 'int', 'not_null' => 1, 'default' => 0), + 'Username' => Array ('type' => 'string', 'not_null' => 1, 'default' => ''), + 'ProductId' => Array ('type' => 'int', 'not_null' => 1, 'default' => 0), + 'ProductName' => Array ('type' => 'string', 'not_null' => 1, 'default' => ''), + 'FileId' => Array ('type' => 'int', 'not_null' => 1, 'default' => 0), + 'Filename' => Array ('type' => 'string', 'not_null' => 1, 'default' => ''), + 'IPAddress' => Array ('type' => 'string', 'not_null' => 1, 'default' => ''), + 'StartedOn' => Array ('type' => 'int', 'formatter' => 'kDateFormatter', 'default' => NULL), + 'EndedOn' => Array ('type' => 'int', 'formatter' => 'kDateFormatter', 'default' => NULL), + ), + + 'Grids' => Array ( + 'Default' => Array ( + 'Icons' => Array ( + 'default' => 'icon16_item.png', + 0 => 'icon16_disabled.png', + 1 => 'icon16_item.png', + 'module' => 'core', + ), + 'Fields' => Array ( + 'DownloadId' => Array ( 'title' => 'column:la_fld_Id', 'data_block' => 'grid_checkbox_td', 'filter_block' => 'grid_range_filter', 'width' => 60, ), + 'Username' => Array ( 'filter_block' => 'grid_like_filter', 'width' => 100, ), + 'ProductName' => Array ( 'title' => 'la_col_DownloadedProductName', 'filter_block' => 'grid_like_filter', 'width' => 150, ), + 'Filename' => Array ( 'title' => 'la_col_DownloadedFileName', 'filter_block' => 'grid_like_filter', 'width' => 150, ), + 'IPAddress' => Array ( 'filter_block' => 'grid_like_filter', 'width' => 150, ), + 'StartedOn' => Array ( 'title' => 'la_col_StartedOn', 'filter_block' => 'grid_date_range_filter', 'width' => 150, ), + ), + ), + ), +); \ No newline at end of file Property changes on: releases/5.2.2-B2/units/downloads/downloads_config.php ___________________________________________________________________ Added: cvs2svn:cvs-rev + 1.12.2.2 Added: svn:keywords + Id Added: svn:eol-style + LF Index: releases/5.2.2-B2/units/downloads/download_helper.php =================================================================== --- releases/5.2.2-B2/units/downloads/download_helper.php (revision 0) +++ releases/5.2.2-B2/units/downloads/download_helper.php (revision 16630) @@ -0,0 +1,77 @@ +Application->RecallVar('user_id').' + AND ProductId = '.$product_id; + return $this->Conn->GetOne($sql); + } + + function SendFile($file_id, $product_id) + { + /** @var kDBItem $file_object */ + $file_object = $this->Application->recallObject('file', null, Array('skip_autoload' => true)); + + $sql = $file_id ? + 'SELECT FileId, FilePath, RealPath, MIMEType FROM '.$this->Application->getUnitOption('file', 'TableName').' + WHERE FileId = '.$file_id : + 'SELECT FileId, FilePath, RealPath, MIMEType FROM '.$this->Application->getUnitOption('file', 'TableName').' + WHERE ProductId = '.$product_id.' AND IsPrimary = 1'; + $file_info = $this->Conn->GetRow($sql); + + $field_options = $file_object->GetFieldOptions('RealPath'); + $file_info['real_path'] = FULL_PATH.$field_options['upload_dir'].'/'.$file_info['RealPath']; + $file_info = $this->DoSendFile($file_info); + return $file_info; + } + + function DoSendFile($file_info) + { + $this->Application->setContentType(kUtil::mimeContentType($file_info['real_path']), false); + header('Content-Disposition: attachment; filename="' . $file_info['FilePath'] . '"'); + header('Content-Length: ' . filesize($file_info['real_path'])); + + $file_info['download_start'] = adodb_mktime(); + readfile($file_info['real_path']); + flush(); + $file_info['download_end'] = adodb_mktime(); // this is incorrect + define('SKIP_OUT_COMPRESSION', 1); + return $file_info; + } + + function LogDownload($product_id, $file_info) + { + $down_object = $this->Application->recallObject('down', null, Array('skip_autoload' => true)); + $user_object = $this->Application->recallObject('u.current'); + $product_object = $this->Application->recallObject( 'p' ); + + $down_object->SetDBField('PortalUserId', $this->Application->RecallVar('user_id')); + $down_object->SetDBField('Username', $user_object->GetDBField('Username')); + $down_object->SetDBField('ProductId', $product_id); + $down_object->SetDBField('ProductName', $product_object->GetField('Name')); + $down_object->SetDBField('FileId', $file_info['FileId']); + $down_object->SetDBField('Filename', $file_info['FilePath']); + $down_object->SetDBField('IPAddress', $this->Application->getClientIp()); + $down_object->SetDBField('StartedOn_date', $file_info['download_start']); + $down_object->SetDBField('StartedOn_time', $file_info['download_start']); + + $down_object->Create(); + } + + } \ No newline at end of file Property changes on: releases/5.2.2-B2/units/downloads/download_helper.php ___________________________________________________________________ Added: cvs2svn:cvs-rev + 1.3 Added: svn:keywords + Id Added: svn:eol-style + LF Index: releases/5.2.2-B2/units/product_options/product_options_event_handler.php =================================================================== --- releases/5.2.2-B2/units/product_options/product_options_event_handler.php (revision 0) +++ releases/5.2.2-B2/units/product_options/product_options_event_handler.php (revision 16630) @@ -0,0 +1,110 @@ +getEventParam('selectable_only'); + + if ( $selectable_only ) { + /** @var kDBList $object */ + $object = $event->getObject(); + + $object->addFilter('types_filter', 'OptionType IN (1,3,6)'); + } + } + + /** + * Updates temp_id to live_id in options combinations + * + * !Not called when "po" doesn't have subitems (temp handler problem) + * + * @param kEvent $event + * @return void + * @access protected + */ + protected function OnAfterCopyToLive(kEvent $event) + { + parent::OnAfterCopyToLive($event); + + $id = $event->getEventParam('id'); + $temp_id = $event->getEventParam('temp_id'); + + if ( $id == $temp_id ) { + return; + } + + $poc_table = $this->Application->GetTempName(TABLE_PREFIX . 'ProductOptionCombinations', 'prefix:p'); + + $sql = 'SELECT * + FROM ' . $poc_table; + $combs = $this->Conn->Query($sql); + + foreach ($combs as $a_comb) { + $comb_data = unserialize($a_comb['Combination']); + $n_combs = array (); + foreach ($comb_data as $key => $val) { + $n_key = $key == $temp_id ? $id : $key; + $n_combs[$n_key] = $val; + } + ksort($n_combs); + $n_combs = serialize($n_combs); + $n_crc = kUtil::crc32($n_combs); + $sql = 'UPDATE ' . $poc_table . ' + SET + Combination = ' . $this->Conn->qstr($n_combs) . ', + CombinationCRC = ' . $n_crc . ' + WHERE CombinationId = ' . $a_comb['CombinationId']; + $this->Conn->Query($sql); + } + } + + /** + * Occurs after an item has been cloned + * Id of newly created item is passed as event' 'id' param + * + * @param kEvent $event + * @return void + * @access protected + */ + protected function OnAfterClone(kEvent $event) + { + parent::OnAfterClone($event); + + $id = $event->getEventParam('id'); + $org_id = $event->getEventParam('original_id'); + + // storing original to new ids mapping to use in poc:OnBeforeClone + $options_mapping = $this->Application->GetVar('poc_mapping'); + if ( !$options_mapping ) { + $options_mapping = array (); + } + + $options_mapping[$org_id] = $id; + $this->Application->SetVar('poc_mapping', $options_mapping); + } + + } \ No newline at end of file Property changes on: releases/5.2.2-B2/units/product_options/product_options_event_handler.php ___________________________________________________________________ Added: cvs2svn:cvs-rev + 1.8 Added: svn:keywords + Id Added: svn:eol-style + LF Index: releases/5.2.2-B2/units/product_options/product_options_helper.php =================================================================== --- releases/5.2.2-B2/units/product_options/product_options_helper.php (revision 0) +++ releases/5.2.2-B2/units/product_options/product_options_helper.php (revision 16630) @@ -0,0 +1,98 @@ +UnEscape($conv_prices); + $conv_price_types = $this->UnEscape($conv_price_types); + + return array('Values'=>$values, 'Prices'=>$conv_prices, 'PriceTypes'=>$conv_price_types); + } + + function UnEscape($data) + { + $res = array(); + foreach ($data as $key=>$val) + { + $n_key = str_replace('\\|', '|', $key); + $n_key = str_replace('\\=', '=', $n_key); + $n_val = str_replace('\\|', '|', $val); + $n_val = str_replace('\\=', '=', $n_val); + $res[$n_key] = $n_val; + } + return $res; + } + + function ConvertKey($key, $product_id, $use_temp=0) + { + static $mapping = null; + + if (is_null($mapping) || !isset($mapping[$product_id])) { + $table = TABLE_PREFIX.'ProductOptions'; + if ($use_temp) $table = $this->Application->GetTempName($table, 'prefix:p'); + $sql = 'SELECT * FROM '.$table.' WHERE ProductId = '.$product_id; + + $mapping[$product_id] = $this->Conn->Query($sql, 'ProductOptionId'); + } + + return $mapping[$product_id][$key]; + } + + function OptionsSalt($options, $comb_only=false) + { + if ( !is_array($options) ) { + return 0; + } + if ( !$comb_only ) { + ksort($options); + return kUtil::crc32(serialize($options)); + } + + $option_keys = array_keys($options); + if ( !$option_keys ) { + return ''; + } + + $sql = 'SELECT ProductOptionId + FROM ' . TABLE_PREFIX . 'ProductOptions + WHERE ProductOptionId IN (' . join(',', $option_keys) . ') AND OptionType IN (1,3,6)'; + $included = $this->Conn->GetCol($sql); + + foreach ($option_keys as $key) { + if ( !in_array($key, $included) ) { + unset($options[$key]); + } + } + + return $this->OptionsSalt($options); + } + } \ No newline at end of file Property changes on: releases/5.2.2-B2/units/product_options/product_options_helper.php ___________________________________________________________________ Added: cvs2svn:cvs-rev + 1.7 Added: svn:keywords + Id Added: svn:eol-style + LF Index: releases/5.2.2-B2/units/product_options/product_options_config.php =================================================================== --- releases/5.2.2-B2/units/product_options/product_options_config.php (revision 0) +++ releases/5.2.2-B2/units/product_options/product_options_config.php (revision 16630) @@ -0,0 +1,104 @@ + 'po', + 'ItemClass' => Array ('class' => 'kDBItem', 'file' => '', 'build_event' => 'OnItemBuild'), + 'ListClass' => Array ('class' => 'kDBList', 'file' => '', 'build_event' => 'OnListBuild'), + 'EventHandlerClass' => Array ('class' => 'ProductOptionsEventHandler', 'file' => 'product_options_event_handler.php', 'build_event' => 'OnBuild'), + 'TagProcessorClass' => Array ('class' => 'ProductOptionsTagProcessor', 'file' => 'product_options_tag_processor.php', 'build_event' => 'OnBuild'), + + 'RegisterClasses' => Array ( + Array ('pseudo' => 'kProductOptionsHelper', 'class' => 'kProductOptionsHelper', 'file' => 'product_options_helper.php', 'build_event' => ''), + ), + + 'AutoLoad' => true, + + 'AggregateTags' => Array ( + Array ( + 'AggregateTo' => '#PARENT#', + 'AggregatedTagName' => 'ListOptions', + 'LocalTagName' => 'ListOptions', + ), + ), + + 'QueryString' => Array ( + 1 => 'id', + 2 => 'Page', + 3 => 'PerPage', + 4 => 'event', + ), + + 'TitleField' => 'Name', + 'IDField' => 'ProductOptionId', + 'TableName' => TABLE_PREFIX.'ProductOptions', + 'ForeignKey' => 'ProductId', + 'ParentTableKey' => 'ProductId', + 'ParentPrefix' => 'p', + 'AutoDelete' => true, + 'AutoClone' => true, + 'SubItems' => Array ('poc'), + + 'ListSQLs' => Array ( + '' => ' SELECT * + FROM %s', + ), + + 'ListSortings' => Array ( + '' => Array ( + 'Sorting' => Array ('Name' => 'asc'), + 'ForcedSorting' => Array ('Priority' => 'desc'), + ) + ), + + 'Fields' => Array ( + 'ProductOptionId' => Array ('type' => 'int', 'not_null' => 1, 'default' => 0), + 'ProductId' => Array ('type' => 'int', 'not_null' => 1, 'default' => 0), + 'Name' => Array ('type' => 'string', 'required' => 1, 'max_len' => 255, 'not_null' => 1, 'default' => '',), + 'OptionType' => Array ('type' => 'int', 'required' => 1, 'formatter' => 'kOptionsFormatter', 'use_phrases' => 1, 'options' =>Array (1 => '!la_type_select!', 5 => '!la_type_text!', 4 => '!la_type_textarea!', 3 => '!la_type_radio!', 6 => '!la_type_checkbox!' /*, 2 => '!la_type_password!' */), 'not_null' => 1, 'default' => 0), + 'Required' => Array ( + 'type' => 'int', + 'formatter' => 'kOptionsFormatter', + 'options' => Array (0 => 'la_No', 1 => 'la_Yes'), 'use_phrases' => 1, + 'not_null' => 1, 'default' => 0, + ), + 'Listable' => Array ( + 'type' => 'int', + 'formatter' => 'kOptionsFormatter', + 'options' => Array (0 => 'la_No', 1 => 'la_Yes'), 'use_phrases' => 1, + 'not_null' => 1, 'default' => 0, + ), + 'Priority' => Array ('type' => 'int', 'not_null' =>1, 'default' =>0), + 'Values' => Array ('type' => 'string', 'default' => NULL), + 'Prices' => Array ('type' => 'string', 'default' => NULL), + 'PriceTypes' => Array ('type' => 'string', 'default' => NULL), + ), + + 'Grids' => Array ( + 'Default' => Array ( + 'Icons' => Array ( + 'default' => 'icon16_item.png', + 'module' => 'core', + ), // icons for each StatusField values, if no matches or no statusfield selected, then "default" icon is used + 'Fields' => Array ( + 'ProductOptionId' => Array ( 'title' => 'column:la_fld_Id', 'data_block' => 'grid_checkbox_td', 'filter_block' => 'grid_range_filter'), + 'Name' => Array ( 'data_block' => 'option_name_td', 'filter_block' => 'grid_like_filter'), + 'OptionType' => Array ( 'filter_block' => 'grid_options_filter'), + 'Required' => Array ( 'filter_block' => 'grid_options_filter'), +// 'Listable' => Array ('filter_block' => 'grid_options_filter'), + ), + ), + ), +); \ No newline at end of file Property changes on: releases/5.2.2-B2/units/product_options/product_options_config.php ___________________________________________________________________ Added: cvs2svn:cvs-rev + 1.10.2.2 Added: svn:keywords + Id Added: svn:eol-style + LF Index: releases/5.2.2-B2/units/product_options/product_options_tag_processor.php =================================================================== --- releases/5.2.2-B2/units/product_options/product_options_tag_processor.php (revision 0) +++ releases/5.2.2-B2/units/product_options/product_options_tag_processor.php (revision 16630) @@ -0,0 +1,176 @@ +getObject($params); + + /** @var kProductOptionsHelper $opt_helper */ + $opt_helper = $this->Application->recallObject('kProductOptionsHelper'); + + $parsed = $opt_helper->ExplodeOptionValues($object->GetFieldValues()); + if ( !$parsed ) { + return ''; + } + + $values = $parsed['Values']; + $conv_prices = $parsed['Prices']; + $conv_price_types = $parsed['PriceTypes']; + + $options =& $this->GetOptions(); + + $mode = $this->SelectParam($params, 'mode'); + $combination_prefix = $this->SelectParam($params, 'combination_prefix'); + $combination_field = $this->SelectParam($params, 'combination_field'); + + if ( $mode == 'selected' ) { + /** @var kDBItem $comb */ + $comb = $this->Application->recallObject($combination_prefix); + + $options = unserialize($comb->GetDBField($combination_field)); + } + + $block_params['name'] = $params['render_as']; + $block_params['selected'] = ''; + $block_params['pass_params'] = 1; + + /** @var LanguagesItem $lang */ + $lang = $this->Application->recallObject('lang.current'); + + $o = ''; + $first_selected = false; + + foreach ($values as $option) { +// list($val, $label) = explode('|', $option); + $val = $option; + + if ( getArrayValue($params, 'js') ) { + $block_params['id'] = kUtil::escape($val, kUtil::ESCAPE_JS); + $block_params['value'] = kUtil::escape($val); + } + else { + $block_params['id'] = kUtil::escape($val); + $block_params['value'] = kUtil::escape($val); + } + + if ( $conv_prices[$val] ) { + if ( $conv_price_types[$val] == '$' && !getArrayValue($params, 'js') && !getArrayValue($params, 'no_currency') ) { + $iso = $this->GetISO($params['currency']); + $value = sprintf("%.2f", $this->ConvertCurrency($conv_prices[$val], $iso)); + + $value = $this->AddCurrencySymbol($lang->formatNumber($value, 2), $iso, true); // true to force sign + $block_params['price'] = $value; + $block_params['price_type'] = ''; + $block_params['sign'] = ''; //sign is included in the formatted value + } + else { + $block_params['price'] = isset($params['js']) ? $conv_prices[$val] : $lang->formatNumber($conv_prices[$val], 2); + $block_params['price_type'] = $conv_price_types[$val]; + $block_params['sign'] = $conv_prices[$val] >= 0 ? '+' : '-'; + } + } + else { + $block_params['price'] = ''; + $block_params['price_type'] = ''; + $block_params['sign'] = ''; + } + + /*if ($mode == 'selected') { + $selected = $combination[$object->GetID()] == $val; + } + else*/ + $selected = false; + + if ( !$options && isset($params['preselect_first']) && $params['preselect_first'] && !$first_selected ) { + $selected = true; + $first_selected = true; + } + + if ( is_array($options) ) { + $option_value = array_key_exists($object->GetID(), $options) ? $options[$object->GetID()] : ''; + + if ( $object->GetDBField('OptionType') == OptionType::CHECKBOX ) { + $selected = is_array($option_value) && in_array(kUtil::escape($val), $option_value); + } + else { // radio buttons ? + // TODO: Not sure why we're unescaping. + $selected = kUtil::unescape($option_value, kUtil::ESCAPE_HTML) == $val; + } + } + + if ( $selected ) { + if ( $mode == 'selected' ) { + if ( $object->GetDBField('OptionType') != OptionType::CHECKBOX ) { + $block_params['selected'] = ' selected="selected" '; + } + else { + $block_params['selected'] = ' checked="checked" '; + } + } + else { + switch ($object->GetDBField('OptionType')) { + case OptionType::DROPDOWN: + $block_params['selected'] = ' selected="selected" '; + break; + case OptionType::RADIO: + case OptionType::CHECKBOX: + $block_params['selected'] = ' checked="checked" '; + break; + } + } + } + else { + $block_params['selected'] = ''; + } + + $o .= $this->Application->ParseBlock($block_params); + } + + return $o; + } + + function &GetOptions() + { + $opt_data = $this->Application->GetVar('options'); + $options = getArrayValue($opt_data, $this->Application->GetVar('p_id')); + if (!$options && $this->Application->GetVar('orditems_id')) { + /** @var kDBItem $ord_item */ + $ord_item = $this->Application->recallObject('orditems.-opt', null, Array ('skip_autoload' => true)); + + $ord_item->Load($this->Application->GetVar('orditems_id')); + $item_data = unserialize($ord_item->GetDBField('ItemData')); + $options = getArrayValue($item_data, 'Options'); + } + return $options; + } + + function OptionData($params) + { + /** @var kDBItem $object */ + $object = $this->getObject($params); + + $options =& $this->GetOptions(); + + return getArrayValue($options, $object->GetID()); + } + + function ListOptions($params) + { + return $this->PrintList2($params); + } +} Property changes on: releases/5.2.2-B2/units/product_options/product_options_tag_processor.php ___________________________________________________________________ Added: cvs2svn:cvs-rev + 1.10.2.1 Added: svn:keywords + Id Added: svn:eol-style + LF Index: releases/5.2.2-B2/units/pricing/pricing_event_handler.php =================================================================== --- releases/5.2.2-B2/units/pricing/pricing_event_handler.php (revision 0) +++ releases/5.2.2-B2/units/pricing/pricing_event_handler.php (revision 16630) @@ -0,0 +1,525 @@ + Array ('subitem' => 'add|edit'), + 'OnInfinity' => Array ('subitem' => 'add|edit'), + 'OnArrange' => Array ('subitem' => 'add|edit'), + 'OnDeleteBrackets' => Array ('subitem' => 'add|edit'), + ); + + $this->permMapping = array_merge($this->permMapping, $permissions); + } + + /** + * Define alternative event processing method names + * + * @return void + * @see kEventHandler::$eventMethods + * @access protected + */ + protected function mapEvents() + { + parent::mapEvents(); // ensure auto-adding of approve/decline and so on events + + $brackets_events = Array( + 'OnMoreBrackets' => 'PricingBracketsAction', + 'OnArrange' => 'PricingBracketsAction', + 'OnInfinity' => 'PricingBracketsAction', + 'OnDeleteBrackets' => 'PricingBracketsAction', + ); + + $this->eventMethods = array_merge($this->eventMethods, $brackets_events); + } + + function PricingBracketsAction($event) + { + $event->redirect=false; + $temp = $this->Application->GetVar($event->getPrefixSpecial(true)); + +// $object = $event->getObject(); +// $formatter = $this->Application->recallObject('kFormatter'); +// $temp = $formatter->TypeCastArray($temp, $object); + + //uasort($temp, 'pr_bracket_comp'); + $bracket = $this->Application->recallObject($event->getPrefixSpecial()); + foreach($temp as $id => $record) + { + if( $record['MaxQty'] == '∞' || $record['MaxQty'] == '∞') + { + $temp[$id]['MaxQty'] = -1; + } + } + + $group_id = $this->Application->getVar('group_id'); + if($group_id>0){ + $where_group=' GroupId = '.$group_id.' '; + } + else { + $where_group= ' TRUE '; + } + + switch ($event->Name) + { + case 'OnMoreBrackets': + + $new_id = (int)$this->Conn->GetOne('SELECT MIN('.$bracket->IDField.') FROM '.$bracket->TableName); + if($new_id > 0) $new_id = 0; + do + { + $new_id--; + } while + ($this->check_array($this->Application->GetVar($event->getPrefixSpecial(true)), 'PriceId', $new_id)); + + + $last_max_qty = $this->Conn->GetOne('SELECT MAX(MaxQty) FROM '.$bracket->TableName.' WHERE '.$where_group); + $min_qty = $this->Conn->GetOne('SELECT MIN(MaxQty) FROM '.$bracket->TableName.' WHERE '.$where_group); + + if ($min_qty==-1) $last_max_qty = -1; + if (!$last_max_qty) $last_max_qty=1; + + for($i = $new_id; $i > $new_id - 5; $i--) + { + $temp[$i]['PriceId'] = $i; + $temp[$i]['MinQty'] = ($i == $new_id-4 && $last_max_qty != -1) ? $last_max_qty : ''; + $temp[$i]['MaxQty'] = ($i == $new_id-4 && $last_max_qty != -1) ? -1 : ''; + $temp[$i]['Price'] = ''; + $temp[$i]['Cost'] = ''; + $temp[$i]['Points'] = ''; + $temp[$i]['Negotiated'] = '0'; + $temp[$i]['IsPrimary'] = '0'; + $temp[$i]['GroupId'] = $group_id; + } + + $this->Application->SetVar($event->getPrefixSpecial(true), $temp); + $event->CallSubEvent('OnPreSaveBrackets'); + break; + + case 'OnArrange': + $temp=$this->OnArrangeBrackets($event, $temp, $bracket); + $this->Application->SetVar($event->getPrefixSpecial(true), $temp); + $event->CallSubEvent('OnPreSaveBrackets'); + break; + + case 'OnInfinity': + $temp=$this->OnArrangeBrackets($event, $temp, $bracket); + $this->Application->SetVar($event->getPrefixSpecial(true), $temp); + $event->CallSubEvent('OnPreSaveBrackets'); + + $infinite_exists = $this->Conn->GetOne('SELECT count(*) FROM '.$bracket->TableName.' WHERE MaxQty=-1 '.' AND '.$where_group); + + if($infinite_exists==0){ + reset($temp); + $last_bracket=end($temp); + $new_id = (int)$this->Conn->GetOne('SELECT MIN('.$bracket->IDField.') FROM '.$bracket->TableName); + + $brackets_exist = (int)$this->Conn->GetOne('SELECT COUNT(*) FROM '.$bracket->TableName.' WHERE '.$where_group); + + if($new_id > 0) $new_id = 0; + do + { + $new_id--; + } while + ($this->check_array($this->Application->GetVar($event->getPrefixSpecial(true)), 'PriceId', $new_id)); + + + $infinite_bracket['PriceId'] = $new_id; + $infinite_bracket['MinQty'] = ($brackets_exist>0)?$last_bracket['MaxQty']:1; + $infinite_bracket['MaxQty'] = '-1'; + $infinite_bracket['Price'] = ''; + $infinite_bracket['Cost'] = ''; + $infinite_bracket['Points'] = ''; + $infinite_bracket['Negotiated'] = '0'; + $infinite_bracket['IsPrimary'] = '0'; + $infinite_bracket['GroupId'] = $group_id; + $temp[$new_id]=$infinite_bracket; + reset($temp); + } + + $this->Application->SetVar($event->getPrefixSpecial(true), $temp); + $event->CallSubEvent('OnPreSaveBrackets'); + break; + + case 'OnDeleteBrackets': + if ($group_id) { + $temp = ''; // delete all pricings from "pr_tang" var + + $sql = 'DELETE FROM ' . $bracket->TableName . ' + WHERE ProductId = ' . $this->Application->GetVar('p_id') . ' AND GroupId = ' . $group_id; + $this->Conn->Query($sql); + } + break; + + default: + } + + $this->Application->SetVar($event->getPrefixSpecial(true), $temp); // store pr_tang var + } + + function OnPreSaveBrackets(kEvent $event) + { + if( $this->Application->GetVar('pr_tang') ) { + + /** @var kDBItem $object */ + $object = $event->getObject(); + + $product_id = $this->Application->GetVar('p_id'); + $group_id = $this->Application->getVar('group_id'); + + $sql = 'SELECT PriceId + FROM ' . $object->TableName . ' + WHERE ProductId = ' . $product_id . ' ' . ($group_id? 'AND GroupId = ' . $group_id : ''); + $stored_ids = $this->Conn->GetCol($sql); + + $items_info = $this->Application->GetVar( $event->getPrefixSpecial(true) ); // get pr_tang var + uasort($items_info, 'pr_bracket_comp'); + + foreach ($items_info as $item_id => $field_values) { + + if (in_array($item_id, $stored_ids)) { //if it's already exist + $object->Load($item_id); + $object->SetFieldsFromHash($field_values); + $event->setEventParam('form_data', $field_values); + + if (!$object->Validate()) { + unset($stored_ids[array_search($item_id, $stored_ids)]); + $event->redirect = false; + continue; + } + if( $object->Update($item_id) ) { + $event->status=kEvent::erSUCCESS; + } + else { + $event->status=kEvent::erFAIL; + $event->redirect=false; + break; + } + unset($stored_ids[array_search($item_id, $stored_ids)]); + } + else { + $object->Clear(0); + $object->SetFieldsFromHash($field_values); + $event->setEventParam('form_data', $field_values); + + $object->SetDBField('ProductId', $product_id); + + if( $object->Create() ) { + $event->status=kEvent::erSUCCESS; + } + } + } + + // delete + foreach ($stored_ids as $stored_id) { + $this->Conn->Query('DELETE FROM ' . $object->TableName . ' WHERE PriceId = ' . $stored_id); + } + + } + } + + /** + * Apply custom processing to item + * + * @param kEvent $event + * @param string $type + * @return void + * @access protected + */ + protected function customProcessing(kEvent $event, $type) + { + /** @var kDBItem $bracket */ + $bracket = $event->getObject(); + + switch ($type) { + case 'before': + $bracket->SetDBField('ProductId', $this->Application->GetVar('p_id')); + + if ( $bracket->GetDBField('MaxQty') == '∞' || $bracket->GetDBField('MaxQty') == '∞' ) { + $bracket->SetDBField('MaxQty', -1); + } + break; + } + } + + function OnArrangeBrackets($event, &$temp, &$bracket) + { + $temp_orig = $temp; + reset($temp); + if (is_array($temp)) + { + // array to store max values (2nd column) + $end_values = Array(); + + // get minimal value of Min + $first_elem=current($temp); + $start = $first_elem['MinQty']; + if (!$start){ + $start = 1; + } + foreach($temp as $id => $record) + { + + /* + This 3-ifs logic fixes collision with invalid input values having + 1 pricing record. + The logic is: + 1) If we got Max less than Min, we set Min to 1 that gives us + integrity. + 2) If we got equal values for Min and Max, we set range 1..Max like + in previous. But if Min was 1 and Max was 1 we set full range 1..infinity + 3) If we got Max = 0 we just set it tom infinity because we can't + guess what user meant + */ + + if (sizeof($temp) == 1 && $record['MinQty'] > ($record['MaxQty'] == -1 ? $record['MinQty']+1 : $record['MaxQty']) ){ + $record['MinQty'] = 1; + $temp[$id]['MinQty'] = 1; + $start = 1; + } + + if (sizeof($temp) == 1 && $record['MinQty'] == $record['MaxQty']){ + if ($record['MaxQty'] == 1){ + $record['MaxQty'] = -1; + $temp[$id]['MaxQty'] = -1; + } + else { + $record['MinQty'] = 1; + $temp[$id]['MinQty'] = 1; + } + } + + if (sizeof($temp) == 1 && $record['MaxQty'] == 0){ + $record['MaxQty'] = -1; + $temp[$id]['MaxQty'] = -1; + } + + if( + // MAX is less than start + ($record['MaxQty'] <= $start && $record['MaxQty'] != -1) || + // Max is empty + !$record['MaxQty'] || + // Max already defined in $end_values + (array_search($record['MaxQty'], $end_values) !== false) + ) { // then delete from brackets list + unset($temp[$id]); + } + else { // this is when ok - add to end_values list + $end_values[] = $record['MaxQty']; + } + } + + // sort brackets by 2nd column (Max values) + uasort($temp, 'pr_bracket_comp'); + reset($temp); + $first_item=each($temp); + $first_item_key=$first_item['key']; + + $group_id = $this->Application->getVar('group_id'); + + + $default_group = $this->Application->ConfigValue('User_LoggedInGroup'); + if($group_id>0){ + $where_group=' AND GroupId = '.$group_id.' '; + } + + $ids = $this->Conn->GetCol('SELECT PriceId FROM '.$bracket->TableName.' WHERE ProductId='.$this->Application->GetVar('p_id').' '.$where_group); + if(is_array($ids)) { + usort($ids, 'pr_bracket_id_sort'); + } + $min_id = min( min($ids) - 1, -1 ); + + + foreach($temp as $key => $record) + { + $temp[$key]['MinQty']=$start; + $temp[$key]['IsPrimary']=0; + $temp[$key]['GroupId']=$group_id; + $start=$temp[$key]['MaxQty']; + + } + if ($temp[$first_item_key]['GroupId'] == $default_group) { + $temp[$first_item_key]['IsPrimary']=1; + } + + } + return $temp; + } + + /** + * Set's price as primary for product + * + * @param kEvent $event + */ + function OnSetPrimary($event) + { + $object = $event->getObject( Array('skip_autoload' => true) ); + $this->StoreSelectedIDs($event); + $ids=$this->getSelectedIDs($event); + if($ids) + { + $id = array_shift($ids); + $table_info = $object->getLinkedInfo(); + + $this->Conn->Query('UPDATE '.$object->TableName.' SET IsPrimary = 0 WHERE '.$table_info['ForeignKey'].' = '.$table_info['ParentId']); + $this->Conn->Query('UPDATE '.$object->TableName.' SET IsPrimary = 1 WHERE ('.$table_info['ForeignKey'].' = '.$table_info['ParentId'].') AND (PriceId = '.$id.')'); + } + $event->SetRedirectParam('opener', 's'); + } + + /** + * Resets primary mark for other prices of given product, when current pricing is primary + * + * @param kEvent $event + * @return void + * @access protected + */ + protected function OnBeforeItemUpdate(kEvent $event) + { + parent::OnBeforeItemUpdate($event); + + /** @var kDBItem $object */ + $object = $event->getObject(); + + if ( $object->GetDBField('IsPrimary') == 1 ) { + // make all prices non primary, when this one is + $sql = 'UPDATE ' . $object->TableName . ' + SET IsPrimary = 0 + WHERE (ProductId = ' . $object->GetDBField('ProductId') . ') AND (' . $object->IDField . ' <> ' . $object->GetID() . ')'; + $this->Conn->Query($sql); + } + } + + /** + * Occurs before creating item + * + * @param kEvent $event + * @return void + * @access protected + */ + protected function OnBeforeItemCreate(kEvent $event) + { + parent::OnBeforeItemCreate($event); + + /** @var kDBItem $object */ + $object = $event->getObject(); + + $table_info = $object->getLinkedInfo($event->Special); + + $table_info['ParentId'] = ($table_info['ParentId'] ? $table_info['ParentId'] : 0); + + if ( $object->GetDBField('IsPrimary') == 1 ) { + $sql = 'UPDATE ' . $object->TableName . ' + SET IsPrimary = 0 + WHERE ' . $table_info['ForeignKey'] . ' = ' . $table_info['ParentId']; + $this->Conn->Query($sql); + } + else { + $sql = 'SELECT COUNT(*) + FROM ' . $object->TableName . ' + WHERE ' . $table_info['ForeignKey'] . ' = ' . $table_info['ParentId']; + $prices_qty = $this->Conn->GetOne($sql); + + if ( $prices_qty == 0 ) { + $object->SetDBField('IsPrimary', 1); + } + } + } + + /** + * Apply any custom changes to list's sql query + * + * @param kEvent $event + * @return void + * @access protected + * @see kDBEventHandler::OnListBuild() + */ + protected function SetCustomQuery(kEvent $event) + { + /** @var kDBList $object */ + $object = $event->getObject(); + + if ( $this->Application->isAdminUser ) { + return; + } + + if ( $this->Application->ConfigValue('Comm_PriceBracketCalculation') == 1 ) { + $sql = 'SELECT PrimaryGroupId + FROM ' . TABLE_PREFIX . 'Users + WHERE PortalUserId = ' . $this->Application->GetVar('u_id'); + $pricing_group = $this->Conn->GetOne($sql); + + if ( $pricing_group ) { + $sql = 'SELECT COUNT(*) + FROM ' . TABLE_PREFIX . 'ProductsPricing + WHERE ProductId = ' . $this->Application->GetVar('p_id') . ' AND GroupId = ' . $pricing_group . ' AND Price IS NOT NULL'; + $pricing_for_group_exists = $this->Conn->GetOne($sql); + } + + if ( !$pricing_group || !$pricing_for_group_exists ) { + $pricing_group = $this->Application->ConfigValue('User_LoggedInGroup'); + } + } + else { + $user_groups = $this->Application->RecallVar('UserGroups'); + + //$cheapest_group = $this->Conn->GetOne('SELECT GroupId FROM '.$object->TableName.' WHERE ProductId='.$this->Application->GetVar('p_id').' AND Price IS NOT NULL AND GroupId IN ('.$user_groups.') AND MinQty = 1 GROUP BY GroupId ORDER BY Price ASC'); + + $sql = 'SELECT PriceId, Price, GroupId + FROM ' . $object->TableName . ' + WHERE ProductId = ' . $this->Application->GetVar('p_id') . ' AND Price IS NOT NULL AND GroupId IN (' . $user_groups . ') + ORDER BY GroupId ASC, MinQty ASC'; + $effective_brackets = $this->Conn->Query($sql, 'PriceId'); + + $group_prices = array (); + $min_price = -1; + $cheapest_group = 0; + + foreach ($effective_brackets as $bracket) { + if ( !isset($group_prices[$bracket['GroupId']]) ) { + $group_prices[$bracket['GroupId']] = $bracket['Price']; + if ( $bracket['Price'] < $min_price || $min_price == -1 ) { + $min_price = $bracket['Price']; + $cheapest_group = $bracket['GroupId']; + } + } + } + + if ( !$cheapest_group ) { + $cheapest_group = $this->Application->ConfigValue('User_LoggedInGroup'); + } + + $pricing_group = $cheapest_group; + } + + $object->addFilter('price_user_group', $object->TableName . '.GroupId=' . $pricing_group); + } + +} Property changes on: releases/5.2.2-B2/units/pricing/pricing_event_handler.php ___________________________________________________________________ Added: cvs2svn:cvs-rev + 1.22 Added: svn:keywords + Id Added: svn:eol-style + LF Index: releases/5.2.2-B2/units/pricing/pricing_config.php =================================================================== --- releases/5.2.2-B2/units/pricing/pricing_config.php (revision 0) +++ releases/5.2.2-B2/units/pricing/pricing_config.php (revision 16630) @@ -0,0 +1,142 @@ + 'pr', + 'ItemClass' => Array ('class'=> 'kDBItem', 'file'=> '', 'build_event'=> 'OnItemBuild'), + 'ListClass' => Array ('class'=> 'kDBList', 'file'=> '', 'build_event'=> 'OnListBuild'), + 'EventHandlerClass' => Array ('class'=> 'PricingEventHandler', 'file'=> 'pricing_event_handler.php', 'build_event'=> 'OnBuild'), + 'TagProcessorClass' => Array ('class'=> 'PricingTagProcessor', 'file'=> 'pricing_tag_processor.php', 'build_event'=> 'OnBuild'), + + 'AutoLoad' => true, + + 'Hooks' => Array ( + // for tangible products: pricings are always aranged before saveing product + Array ( + 'Mode' => hBEFORE, + 'Conditional' => true, + 'HookToPrefix' => '#PARENT#', + 'HookToSpecial' => '', + 'HookToEvent' => Array ('OnPreSave'), + 'DoPrefix' => '', + 'DoSpecial' => 'tang', + 'DoEvent' => 'OnArrange', + ), + ), + + 'AggregateTags' => Array ( + Array ( + 'AggregateTo' => '#PARENT#', + 'AggregatedTagName' => 'Price', + 'LocalTagName' => 'ProductPrice', + ), + Array ( + 'AggregateTo' => '#PARENT#', + 'AggregatedTagName' => 'ListPriceBrackets', + 'LocalTagName' => 'Product_ListPriceBrackets', + ), + Array ( + 'AggregateTo' => '#PARENT#', + 'AggregatedTagName' => 'HasQuantityPricing', + 'LocalTagName' => 'Product_HasQuantityPricing', + ), + ), + + 'QueryString' => Array ( + 1 => 'id', + 2 => 'Page', + 3 => 'PerPage', + 4 => 'event', + ), + + 'StatusField' => Array ('IsPrimary'), + 'IDField' => 'PriceId', + 'TableName' => TABLE_PREFIX.'ProductsPricing', + + 'ForeignKey' => 'ProductId', + 'ParentTableKey' => 'ProductId', + 'ParentPrefix' => 'p', + 'AutoDelete' => true, + 'AutoClone' => true, + + 'ListSQLs' => Array ( + ''=> ' SELECT * + FROM %s', + ), + + 'ListSortings' => Array ( + '' => Array ( + 'Sorting' => Array ('MinQty' => 'asc'), + ) + ), + + 'Fields' => Array ( + 'PriceId' => Array ('type' => 'int', 'not_null' => 1, 'default' => 0,), + 'ProductId' => Array ('type' => 'int', 'not_null' => 1, 'default' => 0), + 'MinQty' => Array ('type' => 'int', 'default' => null), + 'MaxQty' => Array ('type' => 'int', 'default' => null), + 'Cost' => Array ('type' => 'float', 'formatter' => 'kFormatter', 'format' => '%.2f', 'default' => 0), + 'Price' => Array ('type' => 'float', 'not_null' => 1, 'formatter' => 'kFormatter', 'min_value_inc' => 0, 'format' => '%.2f', 'default' => 0), + 'Negotiated' => Array ( + 'type' => 'int', + 'formatter' => 'kOptionsFormatter', + 'options' => Array ( 0 => 'la_No', 1 => 'la_Yes', ), 'use_phrases' => 1, + 'default' => NULL, + ), + 'Points' => Array ('type' => 'int', 'default' => null), + 'AccessDuration'=> Array ('type' => 'int', 'not_null' => 1, 'default' => 0,), + 'AccessUnit' => Array ('type' => 'int', 'formatter' => 'kOptionsFormatter', 'use_phrases' => 1, 'options' => Array (1 => 'la_opt_sec', 2 => 'la_opt_min', 3 => 'la_opt_hour', 4 => 'la_opt_day', 5 => 'la_opt_week', 6 => 'la_opt_month', 7 => 'la_opt_year'), 'not_null' => 1, 'default' => 0,), + 'Description' => Array ('type' => 'string', 'max_len' => 255, 'default' => NULL), + 'IsPrimary' => Array ( + 'type' => 'int', + 'formatter' => 'kOptionsFormatter', + 'options' => Array ( 0 => 'la_No', 1 => 'la_Yes', ), 'use_phrases' => 1, + 'not_null' => 1, 'default' => 0, + ), + 'GroupId' => Array ('type' => 'int', 'default' => 0, 'not_null' => 1), + + /* TODO implement these fields in business logic + 'AccessRebillDate' => Array ( + 'type'=> 'int', 'min_value' => 0, 'max_value' => 31, 'not_null'=> '1', 'default' => 0, + ), + 'DurationType' => Array ( + 'type' => 'int', + 'formatter' => 'kOptionsFormatter', + 'options' => Array ( + 1 => 'la_opt_Interval', 2 => 'la_opt_Date', + ), + 'use_phrases' => 1, 'not_null' => 1, 'default' => 1, + ), + 'AccessExpiration' => Array ('type' => 'int', 'formatter' => 'kDateFormatter'), + */ + ), + + 'Grids' => array( + 'Access' => array( + 'Icons' => array( + 'default' => 'icon16_item.png', + '0' => 'icon16_item.png', + '1' => 'icon16_primary.png', + 'module' => 'core', + ), + 'Fields' => array( + 'AccessDuration' => array('data_block' => 'grid_checkbox_td', 'filter_block' => 'grid_range_filter'), + 'AccessUnit' => array('title' => 'column:la_fld_AccessDurationUnit', 'filter_block' => 'grid_options_filter'), + 'Description' => array('filter_block' => 'grid_like_filter'), + 'Price' => array('filter_block' => 'grid_range_filter'), + ), + ), + ), +); Property changes on: releases/5.2.2-B2/units/pricing/pricing_config.php ___________________________________________________________________ Added: cvs2svn:cvs-rev + 1.20.2.1 Added: svn:keywords + Id Added: svn:eol-style + LF Index: releases/5.2.2-B2/units/pricing/globals.php =================================================================== --- releases/5.2.2-B2/units/pricing/globals.php (revision 0) +++ releases/5.2.2-B2/units/pricing/globals.php (revision 16630) @@ -0,0 +1,71 @@ +$elem2['MaxQty'] && $elem2['MaxQty']!=-1) || ($elem1['MaxQty'] == -1 && $elem2['MaxQty'] != -1 )) + { + return 1; + } + elseif ( ($elem1['MaxQty']<$elem2['MaxQty']) || ($elem2['MaxQty'] == -1 && $elem1['MaxQty'] != -1 )) + { + return -1; + } + else + { + return 0; + } + } + + function pr_bracket_id_sort($first_id, $second_id) + { + $first_abs = abs($first_id); + $second_abs = abs($second_id); + $first_sign = ($first_id == 0) ? 0 : $first_id / $first_abs; + $second_sign = ($second_id == 0) ? 0 : $second_id / $second_abs; + if($first_sign != $second_sign) + { + if($first_id > $second_id) { + $bigger =& $first_abs; + $smaller =& $second_abs; + } + else { + $bigger =& $second_abs; + $smaller =& $first_abs; + } + $smaller = $bigger + $smaller; + } + + if($first_abs > $second_abs) { + return 1; + } + elseif ($first_abs < $second_abs) + { + return -1; + } + else + { + return 0; + } + } \ No newline at end of file Property changes on: releases/5.2.2-B2/units/pricing/globals.php ___________________________________________________________________ Added: cvs2svn:cvs-rev + 1.4 Added: svn:keywords + Id Added: svn:eol-style + LF Index: releases/5.2.2-B2/units/pricing/pricing_tag_processor.php =================================================================== --- releases/5.2.2-B2/units/pricing/pricing_tag_processor.php (revision 0) +++ releases/5.2.2-B2/units/pricing/pricing_tag_processor.php (revision 16630) @@ -0,0 +1,166 @@ +Application->recallObject($params['PrefixSpecial']); + $price = $object->GetField('Price'); + + // display selected currency by default + if (!isset($params['currency']) || $params['currency'] == 'selected') { + $iso = $this->Application->RecallVar('curr_iso'); + } + elseif ($params['currency'] == 'primary') { + $iso = 'USD'; + } + else { //explicit currency + $iso = $params['currency']; + } + + // convert primary currency to selected (if they are the same, converter will just return) + + /** @var CurrencyRates $converter */ + $converter = $this->Application->recallObject('CurrencyRates'); + + $price = $converter->Convert($price, 'PRIMARY', $iso); + + $currency = $this->Application->recallObject('curr.-'.$iso, null, Array('skip_autoload' => true)); + if( !$currency->isLoaded() ) $currency->Load($iso, 'ISO'); + + $symbol = $currency->GetDBField('Symbol'); + if (!$symbol) $symbol = $currency->GetDBField('ISO'); + $formatted = ''; + if ($currency->GetDBField('SymbolPosition') == 0) { + $formatted .= $symbol; + } + $formatted .= $price; + if ($currency->GetDBField('SymbolPosition') == 1) { + $formatted .= $symbol; + } + + return $formatted; + } + + function Product_ListPriceBrackets($params) + { + return $this->PrintList2($params); + } + + function Field($params) + { + $field = $this->SelectParam($params, 'name,field'); + $value = parent::Field($params); + if (($field == 'MaxQty') && ($value == -1)) { + $value = '∞'; + } + return $value; + } + + function Product_HasQuantityPricing($params) + { + return (int)$this->TotalRecords($params) > 1; + } + + + function ShowPricingForm($params) + { + $br_object = $this->getObject( Array('skip_autoload' => true) ); + + $br_data = $this->Application->GetVar("pr_tang"); + + $group_id = $this->Application->getVar('group_id'); + if($group_id>0){ + $where_group=' AND GroupId = '.$group_id.' '; + } + + if(!$br_data) + { + $sql = 'SELECT * FROM '.$br_object->TableName.' WHERE ProductId = '.$this->Application->GetVar('p_id').' '.$where_group; + $brackets = $this->Conn->Query($sql, 'PriceId'); + + usort($brackets, 'pr_bracket_comp'); + + /** @var kDBItem $dummy */ + $dummy = $this->Application->recallObject($this->Prefix.'.-dummy', null, array('skip_autoload' => true)); + + foreach($brackets as $id => $values) + { + foreach($values as $value_key=>$value_val){ + $dummy->SetDBField($value_key, $value_val); + $brackets[$id][$value_key] = $dummy->GetField($value_key); + } + } + + $br_data=$brackets; + $this->Application->SetVar($this->getPrefixSpecial(true), $brackets); + } + else + { + usort($br_data , 'pr_bracket_comp'); + + } + + $ret = ''; + if( is_array($br_data) ) + { + + $block_params=$this->prepareTagParams($params); + $block_params['IdField']='PriceId'; + $block_params['name'] = $params['block']; + $first = true; + + // this is needed to find next id + $br_data_copy=$br_data; + foreach($br_data as $id => $values) + { + + foreach($values as $value_key=>$value_val){ + $block_params[$value_key] = $value_val; + } + reset($values); + + next($br_data_copy); + $next_bracket=current($br_data_copy); + + $block_params['id'] = $values["PriceId"]; + $block_params['min'] = ($id == -1) ? ($values['MinQty'] ? $values['MinQty'] : 0) : $values['MinQty']; + $block_params['max'] = ($values['MaxQty'] == -1) ? '∞' : $values['MaxQty']; + $block_params['next_min_id']=$next_bracket['PriceId']; + + if ($first) + { + $block_params['first'] = 1; + $first = false; + } + else + { + $block_params['first'] = 0; + } + $ret .= $this->Application->ParseBlock($block_params, 1); + } + } + return $ret; + } + + function AddToCartLink($params) + { + $value = $this->Field(array('name'=>'PriceId')); + //$this->Application->SetVar('p_id', $this->Application->GetVar($this->getPrefixSpecial().'_id')); + $this->Application->SetVar('pr_id', $value); + return $this->Application->HREF($params['template'], '', Array('pass' => 'm,p,pr,ord', 'ord_event' => 'OnAddToCart')); + } +} \ No newline at end of file Property changes on: releases/5.2.2-B2/units/pricing/pricing_tag_processor.php ___________________________________________________________________ Added: cvs2svn:cvs-rev + 1.15.2.1 Added: svn:keywords + Id Added: svn:eol-style + LF Index: releases/5.2.2-B2/units/reports/reports_event_handler.php =================================================================== --- releases/5.2.2-B2/units/reports/reports_event_handler.php (revision 0) +++ releases/5.2.2-B2/units/reports/reports_event_handler.php (revision 16630) @@ -0,0 +1,848 @@ + Array ('self' => 'view'), + 'OnUpdateConfig' => Array ('self' => 'view'), + 'OnChangeStatistics' => Array ('self' => 'view'), + 'OnPieChart' => Array ('self' => 'view'), + 'OnPrintChart' => Array ('self' => 'view'), + 'OnExportReport' => Array ('self' => 'view'), + ); + + $this->permMapping = array_merge($this->permMapping, $permissions); + } + + function OnRunReport(kEvent $event) + { + $this->Application->LinkVar('reports_finish_t'); + $progress_t = $this->Application->GetVar('progress_t'); + $event->redirect = $progress_t; + + $field_values = $this->getSubmittedFields($event); + + /** @var kDBItem $object */ + $object = $event->getObject( Array('skip_autoload' => true) ); + $object->SetFieldsFromHash($field_values); + $event->setEventParam('form_data', $field_values); + + $object->UpdateFormattersMasterFields(); + + $field_values['offset'] = 0; + $table_name = TABLE_PREFIX.'ses_'.$this->Application->GetSID().'_SaleReport'; + $field_values['table_name'] = $table_name; + $this->Conn->Query('DROP TABLE IF EXISTS '.$table_name); + + $filter_value = ''; + $from = $object->GetDBField('FromDateTime'); + $to = $object->GetDBField('ToDateTime'); + + $day_seconds = 23 * 60 * 60 + 59 * 60 + 59; + if ($from && !$to) { + $to = $from + $day_seconds; + } + elseif (!$from && $to) { + $from = $to - $day_seconds; + } + + if ($from && $to) { + $filter_value = 'AND o.OrderDate >= '.$from.' AND o.OrderDate <= '.$to; + } + + $ebay_table_fields = ''; + $ebay_joins = ''; + $ebay_query_fields = ''; + + $user_id = $this->Application->RecallVar('user_id'); + $sql = 'DELETE FROM '.TABLE_PREFIX.'UserPersistentSessionData + WHERE + PortalUserId = "'.$user_id.'" + AND VariableName LIKE \'rep_columns_%\''; + $this->Conn->Query($sql); + + if ($this->Application->isModuleEnabled('in-auction')) + { + if (in_array($field_values['ReportType'], Array(1,5))) // not overall. + { + $ebay_table_fields = ', + StoreQty int(11) NOT NULL DEFAULT 0, + eBayQty int(11) NOT NULL DEFAULT 0, + StoreAmount double(10,4) NOT NULL DEFAULT 0, + eBayAmount double(10,4) NOT NULL DEFAULT 0, + StoreProfit double(10,4) NOT NULL DEFAULT 0, + eBayProfit double(10,4) NOT NULL DEFAULT 0'; + + $ebay_joins = ' + LEFT JOIN '.TABLE_PREFIX.'eBayOrderItems AS eod + ON od.OptionsSalt = eod.OptionsSalt + '; + + $ebay_query_fields = ', + SUM(IF(ISNULL(eod.OptionsSalt), od.Quantity, 0)) as StoreQty, + SUM(IF(ISNULL(eod.OptionsSalt), 0, od.Quantity)) as eBayQty, + SUM(IF(ISNULL(eod.OptionsSalt), od.Price * od.Quantity, 0)) as StoreAmount, + SUM(IF(ISNULL(eod.OptionsSalt), 0, od.Price * od.Quantity)) as eBayAmount, + SUM(IF(ISNULL(eod.OptionsSalt), (od.Price - od.Cost) * od.Quantity, 0)) as StoreProfit, + SUM(IF(ISNULL(eod.OptionsSalt), 0, (od.Price - od.Cost) * od.Quantity)) as eBayProfit + '; + } + + } + + if ($field_values['ReportType'] == 1) { // by Category + $q = 'CREATE TABLE '.$table_name.' ( + CategoryId int(11) NOT NULL DEFAULT 0, + Qty int(11) NOT NULL DEFAULT 0, + Cost double(10,4) NOT NULL DEFAULT 0, + Amount double(10,4) NOT NULL DEFAULT 0, + Tax double(10,4) NOT NULL DEFAULT 0, + Shipping double(10,4) NOT NULL DEFAULT 0, + Processing double(10,4) NOT NULL DEFAULT 0, + Profit double(10,4) NOT NULL DEFAULT 0 + '.$ebay_table_fields.' + )'; + $field_values['total'] = $this->Conn->GetOne('SELECT COUNT(*) FROM '.TABLE_PREFIX.'Categories'); + $this->Conn->Query($q); + + $q = 'INSERT INTO '.$field_values['table_name'].' + SELECT + c.CategoryId, + SUM(od.Quantity) as Qty, + SUM(od.Cost * od.Quantity) as Cost, + SUM(od.Price * od.Quantity) as SaleAmount, + SUM(o.VAT * od.Price * od.Quantity / o.SubTotal) as Tax, + SUM(o.ShippingCost * od.Price * od.Quantity / o.SubTotal) as Shipping, + SUM(o.ProcessingFee * od.Price * od.Quantity / o.SubTotal) as Processing, + SUM((od.Price - od.Cost) * od.Quantity) as Profit' + .$ebay_query_fields.' + FROM '.TABLE_PREFIX.'Orders AS o + LEFT JOIN '.TABLE_PREFIX.'OrderItems AS od + ON od.OrderId = o.OrderId + LEFT JOIN '.TABLE_PREFIX.'Products AS p + ON p.ProductId = od.ProductId + LEFT JOIN '.TABLE_PREFIX.'CategoryItems AS ci + ON ci.ItemResourceId = p.ResourceId + LEFT JOIN '.TABLE_PREFIX.'Categories AS c + ON c.CategoryId = ci.CategoryId + '.$ebay_joins.' + WHERE + o.Status IN (4,6) + AND + ci.PrimaryCat = 1 + '.$filter_value.' + GROUP BY c.CategoryId + HAVING NOT ISNULL(CategoryId) + '; + $this->Conn->Query($q); + } + elseif ($field_values['ReportType'] == 2) { // by User + $q = 'CREATE TABLE '.$table_name.' ( + PortalUserId int(11) NOT NULL DEFAULT 0, + Qty int(11) NOT NULL DEFAULT 0, + Cost double(10,4) NOT NULL DEFAULT 0, + Amount double(10,4) NOT NULL DEFAULT 0, + Tax double(10,4) NOT NULL DEFAULT 0, + Shipping double(10,4) NOT NULL DEFAULT 0, + Processing double(10,4) NOT NULL DEFAULT 0, + Profit double(10,4) NOT NULL DEFAULT 0 + )'; + $field_values['total'] = $this->Conn->GetOne('SELECT COUNT(*) FROM '.TABLE_PREFIX.'Categories'); + $this->Conn->Query($q); + + $q = 'INSERT INTO '.$field_values['table_name'].' + SELECT + u.PortalUserId, + SUM(od.Quantity) as Qty, + SUM(od.Cost * od.Quantity) as Cost, + SUM(od.Price * od.Quantity) as SaleAmount, + SUM(o.VAT * od.Price * od.Quantity / o.SubTotal) as Tax, + SUM(o.ShippingCost * od.Price * od.Quantity / o.SubTotal) as Shipping, + SUM(o.ProcessingFee * od.Price * od.Quantity / o.SubTotal) as Processing, + SUM((od.Price - od.Cost) * od.Quantity) as Profit + FROM '.TABLE_PREFIX.'Orders AS o + LEFT JOIN '.TABLE_PREFIX.'OrderItems AS od + ON od.OrderId = o.OrderId + LEFT JOIN '.TABLE_PREFIX.'Users AS u + ON u.PortalUserId = o.PortalUserId + WHERE + o.Status IN (4,6) + '.$filter_value.' + GROUP BY u.PortalUserId + HAVING NOT ISNULL(PortalUserId) + '; + $this->Conn->Query($q); + } + elseif ($field_values['ReportType'] == 5) { // by Product + $q = 'CREATE TABLE '.$table_name.' ( + ProductId int(11) NOT NULL DEFAULT 0, + Qty int(11) NOT NULL DEFAULT 0, + Cost double(10,4) NOT NULL DEFAULT 0, + Amount double(10,4) NOT NULL DEFAULT 0, + Tax double(10,4) NOT NULL DEFAULT 0, + Shipping double(10,4) NOT NULL DEFAULT 0, + Processing double(10,4) NOT NULL DEFAULT 0, + Profit double(10,4) NOT NULL DEFAULT 0' + .$ebay_table_fields.' + )'; + $field_values['total'] = $this->Conn->GetOne('SELECT COUNT(*) FROM '.TABLE_PREFIX.'Products'); + $this->Conn->Query($q); + + $q = 'INSERT INTO '.$field_values['table_name'].' + SELECT + p.ProductId, + SUM(od.Quantity) as Qty, + SUM(od.Cost * od.Quantity) as Cost, + SUM(od.Price * od.Quantity) as SaleAmount, + SUM(o.VAT * od.Price * od.Quantity / o.SubTotal) as Tax, + SUM(o.ShippingCost * od.Price * od.Quantity / o.SubTotal) as Shipping, + SUM(o.ProcessingFee * od.Price * od.Quantity / o.SubTotal) as Processing, + SUM((od.Price - od.Cost) * od.Quantity) as Profit' + .$ebay_query_fields.' + FROM '.TABLE_PREFIX.'Orders AS o + LEFT JOIN '.TABLE_PREFIX.'OrderItems AS od + ON od.OrderId = o.OrderId + LEFT JOIN '.TABLE_PREFIX.'Products AS p + ON p.ProductId = od.ProductId + '.$ebay_joins.' + WHERE + o.Status IN (4,6) + '.$filter_value.' + GROUP BY p.ProductId + HAVING NOT ISNULL(ProductId) + '; + $this->Conn->Query($q); + } + elseif ($field_values['ReportType'] == 12) { // Overall + $q = 'CREATE TABLE '.$table_name.' ( + Marketplace tinyint(1) NOT NULL DEFAULT 0, + Qty int(11) NOT NULL DEFAULT 0, + Cost double(10,4) NOT NULL DEFAULT 0, + Amount double(10,4) NOT NULL DEFAULT 0, + Tax double(10,4) NOT NULL DEFAULT 0, + Shipping double(10,4) NOT NULL DEFAULT 0, + Processing double(10,4) NOT NULL DEFAULT 0, + Profit double(10,4) NOT NULL DEFAULT 0 + )'; + $this->Conn->Query($q); + + if ($this->Application->isModuleEnabled('in-auction')) + { + $field_values['total'] = 2; + + $q = 'INSERT INTO '.$field_values['table_name'].' + SELECT + 1 AS Marketplace, + SUM(IF(ISNULL(eod.OptionsSalt), od.Quantity, 0)) as Qty, + SUM(IF(ISNULL(eod.OptionsSalt), od.Cost * od.Quantity, 0)) as Cost, + SUM(IF(ISNULL(eod.OptionsSalt), od.Price * od.Quantity, 0)) as SaleAmount, + SUM(IF(ISNULL(eod.OptionsSalt), o.VAT * od.Price * od.Quantity / o.SubTotal, 0)) as Tax, + SUM(IF(ISNULL(eod.OptionsSalt), o.ShippingCost * od.Price * od.Quantity / o.SubTotal, 0)) as Shipping, + SUM(IF(ISNULL(eod.OptionsSalt), o.ProcessingFee * od.Price * od.Quantity / o.SubTotal, 0)) as Processing, + SUM(IF(ISNULL(eod.OptionsSalt), (od.Price - od.Cost) * od.Quantity, 0)) as Profit + FROM '.TABLE_PREFIX.'Orders AS o + LEFT JOIN '.TABLE_PREFIX.'OrderItems AS od + ON od.OrderId = o.OrderId + LEFT JOIN '.TABLE_PREFIX.'eBayOrderItems AS eod + ON od.OptionsSalt = eod.OptionsSalt + WHERE + o.Status IN (4,6) + '.$filter_value; + $this->Conn->Query($q); + + + $q = 'INSERT INTO '.$field_values['table_name'].' + SELECT + 2 AS Marketplace, + SUM(IF(ISNULL(eod.OptionsSalt), 0, od.Quantity)) as Qty, + SUM(IF(ISNULL(eod.OptionsSalt), 0, od.Cost * od.Quantity)) as Cost, + SUM(IF(ISNULL(eod.OptionsSalt), 0, od.Price * od.Quantity)) as SaleAmount, + SUM(IF(ISNULL(eod.OptionsSalt), 0, o.VAT * od.Price * od.Quantity / o.SubTotal)) as Tax, + SUM(IF(ISNULL(eod.OptionsSalt), 0, o.ShippingCost * od.Price * od.Quantity / o.SubTotal)) as Shipping, + SUM(IF(ISNULL(eod.OptionsSalt), 0, o.ProcessingFee * od.Price * od.Quantity / o.SubTotal)) as Processing, + SUM(IF(ISNULL(eod.OptionsSalt), 0, (od.Price - od.Cost) * od.Quantity)) as Profit + FROM '.TABLE_PREFIX.'Orders AS o + LEFT JOIN '.TABLE_PREFIX.'OrderItems AS od + ON od.OrderId = o.OrderId + LEFT JOIN '.TABLE_PREFIX.'eBayOrderItems AS eod + ON od.OptionsSalt = eod.OptionsSalt + WHERE + o.Status IN (4,6) + '.$filter_value; + $this->Conn->Query($q); + } else { + $field_values['total'] = 1; + $q = 'INSERT INTO '.$field_values['table_name'].' + SELECT + 1 AS Marketplace, + SUM(od.Quantity) as Qty, + SUM(od.Cost * od.Quantity) as Cost, + SUM(od.Price * od.Quantity) as SaleAmount, + SUM(o.VAT * od.Price * od.Quantity / o.SubTotal) as Tax, + SUM(o.ShippingCost * od.Price * od.Quantity / o.SubTotal) as Shipping, + SUM(o.ProcessingFee * od.Price * od.Quantity / o.SubTotal) as Processing, + SUM((od.Price - od.Cost) * od.Quantity) as Profit + FROM '.TABLE_PREFIX.'Orders AS o + LEFT JOIN '.TABLE_PREFIX.'OrderItems AS od + ON od.OrderId = o.OrderId + WHERE + o.Status IN (4,6) + '.$filter_value; + $this->Conn->Query($q); + + } + } + + $vars = array('rep_Page', 'rep_Sort1', 'rep_Sort1_Dir', 'rep_Sort2', 'rep_Sort2_Dir'); + foreach ($vars as $var_name) { + $this->Application->RemoveVar($var_name); + } + + //temporary + $event->redirect = $this->Application->GetVar('reports_finish_t'); + + $field_values['from'] = $from; + $field_values['to'] = $to; + + $this->Application->StoreVar('report_options', serialize($field_values)); + } + + function OnUpdateConfig($event) + { + $report = $this->Application->RecallVar('report_options'); + if (!$report) { + return ; + } + + $field_values = unserialize($report); + + $rep_options = $this->Application->getUnitOptions('rep'); + $new_options = Array (); + + $new_options['TableName'] = $field_values['table_name']; + + $new_options['Fields'] = Array ( + 'Qty' => Array ('type' => 'float', 'formatter' => 'kFormatter', 'format' => '%d', 'default' => 0, 'totals' => 'sum'), + 'Cost' => Array ('type' => 'float', 'formatter' => 'kFormatter', 'format' => '%.2f', 'default' => 0, 'totals' => 'sum'), + 'Amount' => Array ('type' => 'float', 'formatter' => 'kFormatter', 'format' => '%.2f', 'default' => 0, 'totals' => 'sum'), + 'Tax' => Array ('type' => 'float', 'formatter' => 'kFormatter', 'format' => '%.2f', 'default' => 0, 'totals' => 'sum'), + 'Shipping' => Array ('type' => 'float', 'formatter' => 'kFormatter', 'format' => '%.2f', 'default' => 0, 'totals' => 'sum'), + 'Processing' => Array ('type' => 'float', 'formatter' => 'kFormatter', 'format' => '%.2f', 'default' => 0, 'totals' => 'sum'), + 'Profit' => Array ('type' => 'float', 'formatter' => 'kFormatter', 'format' => '%.2f', 'default' => 0, 'totals' => 'sum'), + ); + + if ( $this->Application->isModuleEnabled('in-auction') ) { + if ( in_Array ($field_values['ReportType'], Array (1, 5)) ) { + $new_options['Fields'] += Array ( + 'StoreQty' => Array ('type' => 'int', 'formatter' => 'kFormatter', 'format' => '%d', 'default' => 0, 'totals' => 'sum'), + 'StoreAmount' => Array ('type' => 'float', 'formatter' => 'kFormatter', 'format' => '%.2f', 'default' => 0, 'totals' => 'sum'), + 'StoreProfit' => Array ('type' => 'float', 'formatter' => 'kFormatter', 'format' => '%.2f', 'default' => 0, 'totals' => 'sum'), + 'eBayQty' => Array ('type' => 'int', 'formatter' => 'kFormatter', 'format' => '%d', 'default' => 0, 'totals' => 'sum'), + 'eBayAmount' => Array ('type' => 'float', 'formatter' => 'kFormatter', 'format' => '%.2f', 'default' => 0, 'totals' => 'sum'), + 'eBayProfit' => Array ('type' => 'float', 'formatter' => 'kFormatter', 'format' => '%.2f', 'default' => 0, 'totals' => 'sum'), + ); + } + } + + if ($field_values['ReportType'] == 1) { // by Category + + $new_options['ListSQLs'][''] = + 'SELECT %1$s.* %2$s FROM %1$s + LEFT JOIN '.TABLE_PREFIX.'Categories AS c + ON c.CategoryId = %1$s.CategoryId'; + $new_options['Grids']['Default'] = Array ( + 'Icons' => Array ( + 'default' => 'icon16_item.png', + 'module' => 'core', + ), + 'Fields' => Array ( + 'CategoryName' => Array ('title' => 'la_col_CategoryName', 'filter_block' => 'grid_like_filter'), + 'Qty' => Array ('td_style' => 'text-align: center', 'total' => 'sum', 'filter_block' => 'grid_range_filter'), + 'StoreQty' => Array ('title' => 'la_col_StoreQty', 'td_style' => 'text-align: center', 'total' => 'sum', 'filter_block' => 'grid_range_filter'), + 'eBayQty' => Array ('title' => 'la_col_eBayQty', 'td_style' => 'text-align: center', 'total' => 'sum', 'filter_block' => 'grid_range_filter'), + 'Cost' => Array ('td_style' => 'text-align: right', 'total' => 'sum', 'hidden' => 1, 'filter_block' => 'grid_range_filter'), + 'Amount' => Array ('title' => 'la_col_GMV', 'td_style' => 'text-align: right', 'total' => 'sum', 'filter_block' => 'grid_range_filter'), + 'StoreAmount' => Array ('title' => 'la_col_StoreGMV', 'td_style' => 'text-align: right', 'total' => 'sum', 'filter_block' => 'grid_range_filter'), + 'eBayAmount' => Array ('title' => 'la_col_eBayGMV', 'td_style' => 'text-align: right', 'total' => 'sum', 'filter_block' => 'grid_range_filter'), + 'Tax' => Array ('title' => 'la_col_Tax', 'td_style' => 'text-align: right', 'total' => 'sum', 'hidden' => 1, 'filter_block' => 'grid_range_filter'), + 'Shipping' => Array ('title' => 'la_col_Shipping', 'td_style' => 'text-align: right', 'total' => 'sum', 'hidden' => 1, 'filter_block' => 'grid_range_filter'), + 'Processing' => Array ('title' => 'la_col_Processing', 'td_style' => 'text-align: right', 'total' => 'sum', 'hidden' => 1, 'filter_block' => 'grid_range_filter'), + 'Profit' => Array ('title' => 'la_col_Profit', 'td_style' => 'text-align: right', 'total' => 'sum', 'filter_block' => 'grid_range_filter'), + 'StoreProfit' => Array ('title' => 'la_col_StoreProfit', 'td_style' => 'text-align: right', 'total' => 'sum', 'filter_block' => 'grid_range_filter'), + 'eBayProfit' => Array ('title' => 'la_col_eBayProfit', 'td_style' => 'text-align: right', 'total' => 'sum', 'filter_block' => 'grid_range_filter'), + ), + + ); + + if (!$this->Application->isModuleEnabled('in-auction')) { + $a_fields =& $new_options['Grids']['Default']['Fields']; + unset($a_fields['StoreQty']); + unset($a_fields['eBayQty']); + unset($a_fields['StoreAmount']); + unset($a_fields['eBayAmount']); + unset($a_fields['StoreProfit']); + unset($a_fields['eBayProfit']); + } + + $new_options['VirtualFields'] = array_merge($rep_options['VirtualFields'], Array ( + 'CategoryName' => Array ('type' => 'string', 'default' => ''), + 'Metric' => Array ( + 'type' => 'int', + 'formatter' => 'kOptionsFormatter', + 'options' => $this->GetMetricOptions($new_options, 'CategoryName'), + 'use_phrases' => 1, + 'default' => 0, + ), + )); + + $lang = $this->Application->GetVar('m_lang'); + + // products root category + $products_category_id = $this->Application->findModule('Name', 'In-Commerce', 'RootCat'); + // get root category name + $sql = 'SELECT LENGTH(l' . $lang . '_CachedNavbar) + FROM ' . TABLE_PREFIX . 'Categories + WHERE CategoryId = '.$products_category_id; + $root_length = $this->Conn->GetOne($sql) + 4; + + $new_options['CalculatedFields'][''] = array( + 'CategoryName' => 'REPLACE(SUBSTR(c.l'.$lang.'_CachedNavbar, '.$root_length.'), "&|&", " > ")', + ); + } + elseif ($field_values['ReportType'] == 2) { // by User + $new_options['ListSQLs'][''] = + 'SELECT %1$s.* %2$s FROM %1$s + LEFT JOIN '.TABLE_PREFIX.'Users AS u + ON u.PortalUserId = %1$s.PortalUserId'; + + $new_options['Grids']['Default'] = Array ( + 'Icons' => Array ( + 'default' => 'icon16_item.png', + 'module' => 'core', + ), + 'Fields' => Array ( + 'Login' => Array ('filter_block' => 'grid_like_filter'), + 'FirstName' => Array ('filter_block' => 'grid_like_filter'), + 'LastName' => Array ('filter_block' => 'grid_like_filter'), + 'Qty' => Array ('td_style' => 'text-align: center', 'total' => 'sum', 'filter_block' => 'grid_range_filter'), + 'Cost' => Array ('td_style' => 'text-align: right', 'total' => 'sum', 'filter_block' => 'grid_range_filter'), + 'Amount' => Array ('title' => 'la_col_GMV', 'td_style' => 'text-align: right', 'total' => 'sum', 'filter_block' => 'grid_range_filter'), + 'Tax' => Array ('title' => 'la_col_Tax', 'td_style' => 'text-align: right', 'total' => 'sum', 'filter_block' => 'grid_range_filter'), + 'Shipping' => Array ('title' => 'la_col_Shipping', 'td_style' => 'text-align: right', 'total' => 'sum', 'filter_block' => 'grid_range_filter'), + 'Processing' => Array ('title' => 'la_col_Processing', 'td_style' => 'text-align: right', 'total' => 'sum', 'filter_block' => 'grid_range_filter'), + 'Profit' => Array ('title' => 'la_col_Profit', 'td_style' => 'text-align: right', 'total' => 'sum', 'filter_block' => 'grid_range_filter'), + ), + ); + + $new_options['VirtualFields'] = array_merge($rep_options['VirtualFields'], Array ( + 'Login' => Array ('type' => 'string', 'default' => ''), + 'FirstName' => Array ('type' => 'string', 'default' => ''), + 'LastName' => Array ('type' => 'string', 'default' => ''), + )); + + $new_options['CalculatedFields'][''] = Array ( + 'Login' => 'u.Username', + 'FirstName' => 'u.FirstName', + 'LastName' => 'u.LastName', + ); + } + elseif ($field_values['ReportType'] == 5) { // by Product + + $new_options['ListSQLs'][''] = + 'SELECT %1$s.* %2$s FROM %1$s + LEFT JOIN '.TABLE_PREFIX.'Products AS p + ON p.ProductId = %1$s.ProductId'; + + $new_options['Grids']['Default'] = Array ( + 'Icons' => Array ( + 'default' => 'icon16_item.png', + 'module' => 'core', + ), + 'Fields' => Array ( + 'ProductName' => Array ('title' => 'la_col_ProductName', 'filter_block' => 'grid_like_filter'), + 'Qty' => Array ('td_style' => 'text-align: center', 'total' => 'sum', 'filter_block' => 'grid_range_filter'), + 'StoreQty' => Array ('title' => 'la_col_StoreQty', 'td_style' => 'text-align: center', 'total' => 'sum', 'filter_block' => 'grid_range_filter'), + 'eBayQty' => Array ('title' => 'la_col_eBayQty', 'td_style' => 'text-align: center', 'total' => 'sum', 'filter_block' => 'grid_range_filter'), + 'Cost' => Array ('td_style' => 'text-align: right', 'total' => 'sum', 'hidden' => 1, 'filter_block' => 'grid_range_filter'), + 'Amount' => Array ('title' => 'la_col_GMV', 'td_style' => 'text-align: right', 'total' => 'sum', 'filter_block' => 'grid_range_filter'), + 'StoreAmount' => Array ('title' => 'la_col_StoreGMV', 'td_style' => 'text-align: right', 'total' => 'sum', 'filter_block' => 'grid_range_filter'), + 'eBayAmount' => Array ('title' => 'la_col_eBayGMV', 'td_style' => 'text-align: right', 'total' => 'sum', 'filter_block' => 'grid_range_filter'), + 'Tax' => Array ('title' => 'la_col_Tax', 'td_style' => 'text-align: right', 'total' => 'sum', 'hidden' => 1, 'filter_block' => 'grid_range_filter'), + 'Shipping' => Array ('title' => 'la_col_Shipping', 'td_style' => 'text-align: right', 'total' => 'sum', 'hidden' => 1, 'filter_block' => 'grid_range_filter'), + 'Processing' => Array ('title' => 'la_col_Processing', 'td_style' => 'text-align: right', 'total' => 'sum', 'hidden' => 1, 'filter_block' => 'grid_range_filter'), + 'Profit' => Array ('title' => 'la_col_Profit', 'td_style' => 'text-align: right', 'total' => 'sum', 'filter_block' => 'grid_range_filter'), + 'StoreProfit' => Array ('title' => 'la_col_StoreProfit', 'td_style' => 'text-align: right', 'total' => 'sum', 'filter_block' => 'grid_range_filter'), + 'eBayProfit' => Array ('title' => 'la_col_eBayProfit', 'td_style' => 'text-align: right', 'total' => 'sum', 'filter_block' => 'grid_range_filter'), + ), + + ); + + if (!$this->Application->isModuleEnabled('in-auction')) + { + $a_fields =& $new_options['Grids']['Default']['Fields']; + unset($a_fields['StoreQty']); + unset($a_fields['eBayQty']); + unset($a_fields['StoreAmount']); + unset($a_fields['eBayAmount']); + unset($a_fields['StoreProfit']); + unset($a_fields['eBayProfit']); + } + + + $new_options['VirtualFields'] = array_merge($rep_options['VirtualFields'], Array ( + 'ProductName' => Array ('type' => 'string', 'default' => ''), + 'Metric' => Array ( + 'type' => 'int', + 'formatter' => 'kOptionsFormatter', + 'options' => $this->GetMetricOptions($new_options, 'ProductName'), + 'use_phrases' => 1, + 'default' => 0 + ), + )); + + $lang = $this->Application->GetVar('m_lang'); + + $new_options['CalculatedFields'][''] = Array ( + 'ProductName' => 'p.l'.$lang.'_Name', + ); + } + elseif ($field_values['ReportType'] == 12) { // Overall + + $new_options['ListSQLs'][''] = + 'SELECT %1$s.* %2$s FROM %1$s'; + + $new_options['Fields']['Marketplace'] = Array ( + 'formatter' => 'kOptionsFormatter', + 'options' => Array ( + 1 => 'la_OnlineStore', + 2 => 'la_eBayMarketplace', + ), + 'use_phrases' => 1, + 'default' => 1 + ); + + $new_options['Grids']['Default'] = Array( + 'Icons' => Array( + 'default' => 'icon16_item.png', + 'module' => 'core', + ), + 'Fields' => Array( + 'Marketplace' => Array ('title' => 'la_col_Marketplace', 'filter_block' => 'grid_options_filter'), + 'Qty' => Array ('td_style' => 'text-align: center', 'total' => 'sum', 'filter_block' => 'grid_range_filter'), + 'Cost' => Array ('td_style' => 'text-align: right', 'total' => 'sum', 'filter_block' => 'grid_range_filter'), + 'Amount' => Array ('title' => 'la_col_GMV', 'td_style' => 'text-align: right', 'total' => 'sum', 'filter_block' => 'grid_range_filter'), + 'Tax' => Array ('title' => 'la_col_Tax', 'td_style' => 'text-align: right', 'total' => 'sum', 'filter_block' => 'grid_range_filter'), + 'Shipping' => Array ('title' => 'la_col_Shipping', 'td_style' => 'text-align: right', 'total' => 'sum', 'filter_block' => 'grid_range_filter'), + 'Processing' => Array ('title' => 'la_col_Processing', 'td_style' => 'text-align: right', 'total' => 'sum', 'filter_block' => 'grid_range_filter'), + 'Profit' => Array ('title' => 'la_col_Profit', 'td_style' => 'text-align: right', 'total' => 'sum', 'filter_block' => 'grid_range_filter'), + ), + + ); + + + $new_options['VirtualFields'] = array_merge($rep_options['VirtualFields'], array( + 'Metric' => Array ( + 'type' => 'int', + 'formatter' => 'kOptionsFormatter', + 'options' => $this->GetMetricOptions($new_options, 'Marketplace'), + 'use_phrases' => 1, + 'default' => 0 + ), + )); + + $lang = $this->Application->GetVar('m_lang'); + + } + + $new_options['ListSortings'] = Array( + '' => Array( + 'Sorting' => Array('Amount' => 'desc'), + ) + ); + + foreach ($new_options as $key => $val) { + $this->Application->setUnitOption('rep', $key, $val); + } + } + + /** + * Enter description here... + * + * @param kdbItem $object + * @param string $search_field + * @param string $value + * @param string $type + */ + function processRangeField(&$object, $search_field, $type) + { + $value = $object->GetField($search_field); + if (!$value) return false; + + $lang_current = $this->Application->recallObject('lang.current'); + $dt_separator = getArrayValue($object->GetFieldOptions($search_field), 'date_time_separator'); + if (!$dt_separator) { + $dt_separator = ' '; + } + + $time = ($type == 'from') ? adodb_mktime(0, 0, 0) : adodb_mktime(23, 59, 59); + $time = adodb_date($lang_current->GetDBField('InputTimeFormat'), $time); + + $full_value = $value.$dt_separator.$time; + + $formatter = $this->Application->recallObject( $object->GetFieldOption($search_field, 'formatter') ); + + $value_ts = $formatter->Parse($full_value, $search_field, $object); + + if ( $object->GetErrorPseudo($search_field) ) { + // invalid format -> ignore this date in search + $object->RemoveError($search_field); + + return false; + } + return $value_ts; + } + + /** + * Generate Metric Field Options + * + * @param array $a_config_options + * @param string $exclude_field + */ + function GetMetricOptions(&$a_config_options, $exclude_field) + { + $a_ret = Array(); + foreach ($a_config_options['Grids']['Default']['Fields'] AS $field => $a_options) + { + if ($field == $exclude_field) + { + continue; + } + $a_ret[$field] = $a_options['title']; + } + return $a_ret; + } + + function OnChangeStatistics($event) + { + $this->Application->StoreVar('ChartMetric', $this->Application->GetVar('metric')); + } + + function OnPieChart($event) + { + + $ChartHelper = $this->Application->recallObject('ChartHelper'); + + $this->Application->setContentType('image/png'); + + $width = $event->getEventParam('width'); + if (!$width) { + $width = 800; + } + + $height = $event->getEventParam('height'); + if (!$height) { + $height = 600; + } + + $a_data = unserialize($this->Application->RecallVar('graph_data')); + $chart = new LibchartPieChart($width, $height); + + $dataSet = new LibchartXYDataSet(); + foreach ($a_data AS $key=>$a_values) + { + $dataSet->addPoint(new LibchartPoint($a_values['Name'], $a_values['Metric'])); +// $dataSet->addPoint(new LibchartPoint($a_values['Name'].' ('.$a_values['Metric'].')', $a_values['Metric'])); + } + + $chart->setDataSet($dataSet); + + $chart->setTitle($this->Application->RecallVar('graph_metric')); + $chart->render(); + $event->status = kEvent::erSTOP; + } + + /** Generates png-chart output + * + * @param kEvent $event + */ + + function OnPrintChart($event) + { + $ChartHelper = $this->Application->recallObject('ChartHelper'); + + $this->Application->setContentType('image/png'); + + $width = $this->Application->GetVar('width'); + if ($width == 0) + { + $width = 800; + } + + $height = $this->Application->GetVar('height'); + if ($height == 0) + { + $height = 400; + } + + $chart = new LibchartLineChart($width, $height); + + $a_labels = unserialize($this->Application->RecallVar('graph_labels')); + + if ($this->Application->isModuleEnabled('in-auction')) + { + $serie1 = new LibchartXYDataSet(); + $a_serie = unserialize($this->Application->RecallVar('graph_serie1')); + foreach ($a_labels AS $key=>$value) + { + $serie1->addPoint(new LibchartPoint($value, $a_serie[$key])); + } + } + + $serie2 = new LibchartXYDataSet(); + $a_serie = unserialize($this->Application->RecallVar('graph_serie2')); + foreach ($a_labels AS $key=>$value) + { + $serie2->addPoint(new LibchartPoint($value, $a_serie[$key])); + } + + $dataSet = new LibchartXYSeriesDataSet(); + if ($this->Application->isModuleEnabled('in-auction')) + { + $dataSet->addSerie($this->Application->RecallVar('graph_serie1_label'), $serie1); + } + + $dataSet->addSerie($this->Application->RecallVar('graph_serie2_label'), $serie2); + + $chart->setDataSet($dataSet); + + $chart->setTitle($this->Application->RecallVar('graph_metric')); + $Plot =& $chart->getPlot(); + $Plot->setGraphCaptionRatio(0.7); + $chart->render(); + + $event->status = kEvent::erSTOP; + + } + + function OnExportReport($event) + { + /** @var kDBList $report */ + $report = $this->Application->recallObject($event->getPrefixSpecial(),'rep_List',Array('skip_counting'=>true,'per_page'=>-1) ); + + /** @var kDBItem $ReportItem */ + $ReportItem = $this->Application->recallObject('rep.item', 'rep', Array('skip_autoload' => true)); + + $a_grids = $this->Application->getUnitOption('rep', 'Grids'); + $a_fields = $a_grids['Default']['Fields']; + $ret = ''; + + foreach ($a_fields AS $field => $a_props) + { + $ret .= ''.$field.''; + } + + $ret = substr($ret, 0, strlen($ret) - 5).''; + + + $report->Query(true); + $report->GoFirst(); + + $counter = 0; + $a_totals = Array(); + + foreach ($a_fields AS $field => $a_props) { + $counter++; + if ($counter == 1) + { + continue; + } + $a_totals[$field] = 0; + } + + foreach($report->Records as $a_row) { + // TODO: maybe this should be SetDBFieldsFromHash instead, because all data comes from inside. + $ReportItem->SetFieldsFromHash($a_row); + $row = ''; + foreach ($a_fields AS $field => $a_props) + { + $row .= ''.$ReportItem->GetField($field).''; + $a_totals[$field] += $a_row[$field]; + } + $ret .= substr($row, 0, strlen($row) - 5).''; + } + + // totals + // TODO: maybe this should be SetDBFieldsFromHash instead, because all data comes from inside. + $ReportItem->SetFieldsFromHash($a_totals); + $counter = 0; + foreach ($a_fields AS $field => $a_props) + { + $counter++; + if ($counter == 1) + { + $row = ''; + continue; + } + $row .= ''.$ReportItem->GetField($field).''; + } + $ret .= substr($row, 0, strlen($row) - 5).''; + + $ret = str_replace("\r",'', $ret); + $ret = str_replace("\n",'', $ret); + $ret = str_replace('"','\'\'', $ret); + + $ret = str_replace('','"', $ret); + $ret = str_replace('',',', $ret); + $ret = str_replace('',"\r", $ret); + + $report_options = unserialize($this->Application->RecallVar('report_options')); + + switch ($report_options['ReportType']) + { + case 1: + $file_name = '-ByCategory'; + break; + case 2: + $file_name = '-ByUser'; + break; + case 5: + $file_name = '-ByProduct'; + break; + case 12: + $file_name = ''; + break; + } + + header("Content-type: application/txt"); + header("Content-length: ".(string)strlen($ret)); + header("Content-Disposition: attachment; filename=\"".html_entity_decode('SalesReport'.$file_name.'-'.date('d-M-Y').'.csv')."\""); + header("Pragma: no-cache"); //some IE-fixing stuff + echo $ret; + exit(); + } +} Property changes on: releases/5.2.2-B2/units/reports/reports_event_handler.php ___________________________________________________________________ Added: cvs2svn:cvs-rev + 1.1.4.3 Added: svn:keywords + Id Added: svn:eol-style + LF Index: releases/5.2.2-B2/units/reports/reports_config.php =================================================================== --- releases/5.2.2-B2/units/reports/reports_config.php (revision 0) +++ releases/5.2.2-B2/units/reports/reports_config.php (revision 16630) @@ -0,0 +1,132 @@ + 'rep', + 'ItemClass' => Array ('class' => 'kDBItem', 'file' => '', 'build_event' => 'OnItemBuild'), + 'ListClass' => Array ('class' => 'kDBList', 'file' => '', 'build_event' => 'OnListBuild'), + 'EventHandlerClass' => Array ('class' => 'ReportsEventHandler', 'file' => 'reports_event_handler.php', 'build_event' => 'OnBuild'), + 'TagProcessorClass' => Array ('class' => 'ReportsTagProcessor', 'file' => 'reports_tag_processor.php', 'build_event' => 'OnBuild'), + 'AutoLoad' => true, + + 'QueryString' => Array ( + 1 => 'id', + 2 => 'Page', + 3 => 'PerPage', + 4 => 'event', + 5 => 'mode', + ), + + 'Hooks' => Array ( + Array ( + 'Mode' => hBEFORE, + 'Conditional' => false, + 'HookToPrefix' => 'rep', + 'HookToSpecial' => '*', + 'HookToEvent' => Array ('OnAfterConfigRead'), + 'DoPrefix' => '', + 'DoSpecial' => '', + 'DoEvent' => 'OnUpdateConfig', + ), + ), + + 'IDField' => 'CategoryId', + + 'TitlePresets' => Array ( + 'default' => Array ( + 'new_status_labels' => Array ('d' => '!la_title_Adding_Discount!'), + 'edit_status_labels' => Array ('d' => '!la_title_Editing_Discount!'), + 'new_titlefield' => Array ('d' => '!la_title_New_Discount!'), + ), + + 'report_options' =>Array ('format' => "!la_title_ReportOptions!"), + 'report_results' =>Array ('format' => "!la_title_ReportResults!"), + 'report_chart' =>Array ('format' => "!la_title_SalesReportChart!"), + ), + + 'PermSection' => Array ('main' => 'in-commerce:reports'), + + 'Sections' => Array ( + 'in-commerce:reports' => Array ( + 'parent' => 'in-commerce', + 'icon' => 'in-commerce:sales_report', + 'label' => 'la_tab_SaleReports', + 'url' => Array ('t' => 'in-commerce/reports/reports', 'pass' => 'm,rep', 'rep_event' => 'OnNew'), + 'permissions' => Array ('view', 'add'), + 'priority' => 2, + 'type' => stTREE, + ), + ), + + 'ListSQLs' => Array ( + '' => ' SELECT %1$s.* %2$s + FROM %1$s', + ), + + 'ListSortings' => Array ( + '' => Array ( + 'Sorting' => Array ('Name' => 'asc'), + ) + ), + + 'CalculatedFields' => Array ( + '' => Array ( + 'CategoryId' => '0', + ), + ), + + 'VirtualFields' => Array ( + 'ReportType' => array('formatter' => 'kOptionsFormatter', 'options' =>array( + 12 => 'la_Overall', + 1 => 'la_ByCategory', + 2 => 'la_ByUser', + 5 => 'la_byProduct' + ), + 'use_phrases' => 1, 'default' => 12, + ), + 'FromDateTime' => Array ('formatter' => 'kDateFormatter', 'default' => '', 'filter_type' => 'range_from', 'filter_field' => 'OrderDate' ), + 'ToDateTime' => Array ('formatter' => 'kDateFormatter', 'default' => '', 'filter_type' => 'range_to', 'filter_field' => 'OrderDate', 'empty_time' => adodb_mktime(23,59,59) ), + 'Recursive' => Array ( + 'type' => 'int', + 'formatter' => 'kOptionsFormatter', + 'options' => Array (0 => 'la_No', 1 => 'la_Yes'), + 'use_phrases' => 1, 'not_null' => 1, 'default' => 1, + ), + 'SkipEmpty' => Array ( + 'type' => 'int', + 'formatter' => 'kOptionsFormatter', + 'options' => Array (0 => 'la_No', 1 => 'la_Yes'), + 'use_phrases' => 1, 'not_null' => 1, 'default' => 1, + ), + 'CategoryId' => Array ('type' => 'int', 'default' => 0), + ), + + 'Grids' => Array ( + 'Default' => Array ( + 'Icons' => Array ( + 'default' => 'icon16_item.png', + 'module' => 'core', + ), + 'Fields' => Array ( + 'Name' => Array ('data_block' => 'grid_checkbox_td', 'filter_block' => 'grid_range_filter'), + 'Start' => Array ('filter_block' => 'grid_date_range_filter'), + 'End' => Array ('filter_block' => 'grid_date_range_filter'), + 'GroupId' => Array ( 'title' => 'column:la_fld_Group', 'filter_block' => 'grid_options_filter'), + 'Type' => Array ('filter_block' => 'grid_options_filter'), + 'Amount' => Array ('filter_block' => 'grid_range_filter'), + ), + ), + ), +); Property changes on: releases/5.2.2-B2/units/reports/reports_config.php ___________________________________________________________________ Added: cvs2svn:cvs-rev + 1.1.4.4 Added: svn:keywords + Id Added: svn:eol-style + LF Index: releases/5.2.2-B2/units/reports/reports_tag_processor.php =================================================================== --- releases/5.2.2-B2/units/reports/reports_tag_processor.php (revision 0) +++ releases/5.2.2-B2/units/reports/reports_tag_processor.php (revision 16630) @@ -0,0 +1,438 @@ +CalcReport($params); + + if ($field_values['offset'] == $field_values['total']) { + $this->Application->Redirect($this->Application->RecallVar('reports_finish_t')); + $this->Application->RemoveVar('report_options'); + } + else { + $this->Application->StoreVar('report_options', serialize($field_values)); + } + + return $field_values['offset'] * 100 / $field_values['total']; + } + + function CalcReport($params) + { + $field_values = unserialize($this->Application->RecallVar('report_options')); + $per_step = 20; + + $cats = $this->Conn->Query('SELECT * FROM '.TABLE_PREFIX.'Categories ORDER BY CategoryId LIMIT '.$field_values['offset'].', '.$per_step); + + foreach ($cats as $a_cat) { + if ($field_values['Recursive']) { + $cat_filter = 'c.ParentPath LIKE '.$this->Conn->qstr($a_cat['ParentPath'].'%'); + } + else { + $cat_filter = 'c.CategoryId = '.$a_cat['CategoryId']; + } + + $q = 'INSERT INTO '.$field_values['table_name'].' + SELECT + c.CategoryId, + SUM(od.Quantity) as Qty, + SUM(od.Cost) as Cost, + SUM(od.Price) as SaleAmount, + 0 as Tax, + 0 as Shipping, + 0 as Processing, + SUM(od.Price - od.Cost) as Profit + FROM '.TABLE_PREFIX.'Orders AS o + LEFT JOIN '.TABLE_PREFIX.'OrderItems AS od + ON od.OrderId = o.OrderId + LEFT JOIN '.TABLE_PREFIX.'Products AS p + ON p.ProductId = od.ProductId + LEFT JOIN '.TABLE_PREFIX.'CategoryItems AS ci + ON ci.ItemResourceId = p.ResourceId + LEFT JOIN '.TABLE_PREFIX.'Categories AS c + ON c.CategoryId = ci.CategoryId + WHERE + o.Status = 4 + AND + ci.PrimaryCat = 1 + AND + '.$cat_filter.' + GROUP BY c.CategoryId'; + $this->Conn->Query($q); + + $field_values['offset']++; + } + + return $field_values; + } + + function ReportTypeEquals($params) + { + $field_values = unserialize($this->Application->RecallVar('report_options')); + return ($field_values['ReportType'] == $params['value']); + } + + function CalculateChart($params) + { + + $a_report_options = unserialize($this->Application->RecallVar('report_options')); + $metric = $this->Application->RecallVar('ChartMetric'); + if ($metric == '') + { + // get first option from unit config + $a_virtual_fields = $this->Application->getUnitOption('rep', 'VirtualFields'); + foreach ($a_virtual_fields['Metric']['options'] AS $field => $label) + { + $metric = $field; + break; + } + } + + + /** @var kDBItem $object */ + $object = $this->Application->recallObject('rep.params', null, Array('skip_autoload' => true)); + + $object->setID(1); + $object->SetDBField('Metric', $metric); + + if (!($a_report_options['from'] && $a_report_options['to'])) { + // calculate from & to as extreme order dates + $sql = 'SELECT MAX(OrderDate) AS date_to, MIN(OrderDate) AS date_frm + FROM '.TABLE_PREFIX.'Orders + WHERE + Status IN (4,6) + '; + $a_dates = $this->Conn->GetRow($sql); + $a_report_options['from'] = adodb_mktime(0, 0, 0, date('m', $a_dates['date_frm']), date('d', $a_dates['date_frm']), date('Y', $a_dates['date_frm'])); + $a_report_options['to'] = adodb_mktime(0, 0, 0, date('m', $a_dates['date_to']), date('d', $a_dates['date_to']) + 1, date('Y', $a_dates['date_to'])) - 1; + } + + $filter_value = 'AND o.OrderDate >= '.$a_report_options['from'].' AND o.OrderDate <= '.$a_report_options['to']; + + + if ($a_report_options['ReportType'] == 12) + { + // Overall + + $selected_days = round(($a_report_options['to'] - $a_report_options['from'] + 1) / 3600 / 24); + // determine date interval + if ($selected_days < 2) + { + $step_seconds = 3600; + $step_labels = Array(); + for ($i=0; $i<24; $i++) + { + $hour = str_pad($i, 2, '0', STR_PAD_LEFT); + $step_labels[$i] = $hour; + } + } elseif ( + ($selected_days < 31) + || (date('mY', $a_report_options['from']) == date('mY', $a_report_options['to'])) + ) + { + $step_seconds = 24*3600; + $step_labels = Array(); + $curr_date = $a_report_options['from']; + while ($curr_date <= $a_report_options['to']) + { + $curr_date += $step_seconds; + $step_labels[] = date('d-M', $curr_date); + } + } else { + $start_year = date('Y', $a_report_options['from']); + $start_month = date('m', $a_report_options['from']); + $end_month_year = date('Ym', $a_report_options['to']); + // big interval - move from date to the first day ot the month + $a_report_options['from'] = adodb_mktime(0, 0, 0, date('m', $a_report_options['from']), 1, date('Y', $a_report_options['from'])); + $curr_time = $a_report_options['from']; + while (date('Ym', $curr_time) <= $end_month_year) + { + $step_labels[date('Ym', $curr_time)] = date('M-Y', $curr_time); + // add month + $curr_time = adodb_mktime(0,0,0, date('m', $curr_time) + 1, 1, date('Y', $curr_time)); + } + $step_seconds = 0; + } + + $a_expressions = Array( + 'Qty' => 'od.Quantity', + 'Cost' => 'od.Cost * od.Quantity', + 'Amount' => 'od.Price * od.Quantity', + 'Tax' => 'o.VAT * od.Price * od.Quantity / o.SubTotal', + 'Shipping' => 'o.ShippingCost * od.Price * od.Quantity / o.SubTotal', + 'Processing' => 'o.ProcessingFee * od.Price * od.Quantity / o.SubTotal', + 'Profit' => '(od.Price - od.Cost) * od.Quantity', + ); + + if ($step_seconds) + { + $period_sql = 'FLOOR( + (o.OrderDate - '.$a_report_options['from'].') + /'.$step_seconds.' + )'; + } else { + $period_sql = 'CONCAT(YEAR(FROM_UNIXTIME(o.OrderDate)),LPAD(MONTH(FROM_UNIXTIME(o.OrderDate)), 2, \'0\'))'; + } + + if ($this->Application->isModuleEnabled('in-auction')) + { + $sql = 'SELECT + '.$period_sql.' AS Period, + SUM(IF(ISNULL(eod.OptionsSalt), '.$a_expressions[$metric].', 0)) as StoreMetric, + SUM(IF(ISNULL(eod.OptionsSalt), 0, '.$a_expressions[$metric].')) as eBayMetric + FROM '.TABLE_PREFIX.'Orders AS o + LEFT JOIN '.TABLE_PREFIX.'OrderItems AS od + ON od.OrderId = o.OrderId + LEFT JOIN '.TABLE_PREFIX.'eBayOrderItems AS eod + ON od.OptionsSalt = eod.OptionsSalt + WHERE + o.Status IN (4,6) + '.$filter_value.' + GROUP BY Period'; + } else { + + $sql = 'SELECT + '.$period_sql.' AS Period, + SUM('.$a_expressions[$metric].') as StoreMetric, + 0 as eBayMetric + FROM '.TABLE_PREFIX.'Orders AS o + LEFT JOIN '.TABLE_PREFIX.'OrderItems AS od + ON od.OrderId = o.OrderId + WHERE + o.Status IN (4,6) + '.$filter_value.' + GROUP BY Period'; + + } + + $a_data = $this->Conn->Query($sql, 'Period'); + + // create series array + $a_serie1 = Array(); + $a_serie2 = Array(); + foreach ($step_labels AS $key => $label) + { + $a_serie1[$key] = (isset($a_data[$key]['eBayMetric']) && !is_null($a_data[$key]['eBayMetric'])) ? $a_data[$key]['eBayMetric'] : 0; + $a_serie2[$key] = (isset($a_data[$key]['StoreMetric']) && !is_null($a_data[$key]['StoreMetric'])) ? $a_data[$key]['StoreMetric'] : 0; + } + + $show_date_from = date('m/d/Y', $a_report_options['from']); + $show_date_to = date('m/d/Y', $a_report_options['to']); + $show_date = ($show_date_from == $show_date_to) ? $show_date_to : $show_date_from.' - '.$show_date_to; + + $this->Application->StoreVar('graph_metric', $object->GetField('Metric').' :: ('.$show_date.') :: '.DOMAIN); + $this->Application->StoreVar('graph_serie1', serialize($a_serie1)); + $this->Application->StoreVar('graph_serie2', serialize($a_serie2)); + + $this->Application->StoreVar('graph_serie1_label', $this->Application->Phrase('la_eBayMarketplace')); + $this->Application->StoreVar('graph_serie2_label', $this->Application->Phrase('la_OnlineStore')); + $this->Application->StoreVar('graph_labels', serialize($step_labels)); + + return; + + } + + + $ebay_joins = ''; + if ($this->Application->isModuleEnabled('in-auction')) + { + $ebay_joins = ' + LEFT JOIN '.TABLE_PREFIX.'eBayOrderItems AS eod + ON od.OptionsSalt = eod.OptionsSalt + '; + } + + if ($a_report_options['ReportType'] == 1) + { + // pie chart by category + + $a_expressions = Array( + 'Qty' => 'od.Quantity', + 'Cost' => 'od.Cost * od.Quantity', + 'Amount' => 'od.Price * od.Quantity', + 'Tax' => 'o.VAT * od.Price * od.Quantity / o.SubTotal', + 'Shipping' => 'o.ShippingCost * od.Price * od.Quantity / o.SubTotal', + 'Processing' => 'o.ProcessingFee * od.Price * od.Quantity / o.SubTotal', + 'Profit' => '(od.Price - od.Cost) * od.Quantity', + 'StoreQty' => 'IF(ISNULL(eod.OptionsSalt), od.Quantity, 0)', + 'eBayQty' => 'IF(ISNULL(eod.OptionsSalt), 0, od.Quantity)', + 'StoreAmount' => 'IF(ISNULL(eod.OptionsSalt), od.Price * od.Quantity, 0)', + 'eBayAmount' => 'IF(ISNULL(eod.OptionsSalt), 0, od.Price * od.Quantity)', + 'StoreProfit' => 'IF(ISNULL(eod.OptionsSalt), (od.Price - od.Cost) * od.Quantity, 0)', + 'eBayProfit' => 'IF(ISNULL(eod.OptionsSalt), 0, (od.Price - od.Cost) * od.Quantity)', + ); + + $lang = $this->Application->GetVar('m_lang'); + + $sql = 'SELECT + LEFT(c.l'.$lang.'_Name, 60) AS Name, + c.CategoryId, + SUM('.$a_expressions[$metric].') as Metric + FROM '.TABLE_PREFIX.'Orders AS o + LEFT JOIN '.TABLE_PREFIX.'OrderItems AS od + ON od.OrderId = o.OrderId + LEFT JOIN '.TABLE_PREFIX.'Products AS p + ON p.ProductId = od.ProductId + LEFT JOIN '.TABLE_PREFIX.'CategoryItems AS ci + ON ci.ItemResourceId = p.ResourceId + LEFT JOIN '.TABLE_PREFIX.'Categories AS c + ON c.CategoryId = ci.CategoryId + '.$ebay_joins.' + WHERE + o.Status IN (4,6) + '.$filter_value.' + GROUP BY c.CategoryId + HAVING NOT ISNULL(CategoryId) + ORDER BY Metric DESC + LIMIT 0,8 + '; + $a_data = $this->Conn->Query($sql, 'CategoryId'); + + $other_metric = 0; + if (count($a_data) > 7) + { + // gather ids for "others" call + $ids = join(',', array_keys($a_data)); + $sql = 'SELECT + SUM('.$a_expressions[$metric].') + FROM '.TABLE_PREFIX.'Orders AS o + LEFT JOIN '.TABLE_PREFIX.'OrderItems AS od + ON od.OrderId = o.OrderId + LEFT JOIN '.TABLE_PREFIX.'Products AS p + ON p.ProductId = od.ProductId + LEFT JOIN '.TABLE_PREFIX.'CategoryItems AS ci + ON ci.ItemResourceId = p.ResourceId + LEFT JOIN '.TABLE_PREFIX.'Categories AS c + ON c.CategoryId = ci.CategoryId + '.$ebay_joins.' + WHERE + o.Status IN (4,6) + '.$filter_value.' + AND c.CategoryId NOT IN ('.$ids.') + '; + $other_metric = $this->Conn->GetOne($sql); + if ($other_metric != 0) + { + $a_data[0] = Array( + 'Metric' => $other_metric, + 'Name' => $this->Application->Phrase('la_text_Others'), + ); + } + } + + + $show_date_from = date('m/d/Y', $a_report_options['from']); + $show_date_to = date('m/d/Y', $a_report_options['to']); + $show_date = ($show_date_from == $show_date_to) ? $show_date_to : $show_date_from.' - '.$show_date_to; + + $this->Application->StoreVar('graph_metric', $this->Application->Phrase('la_text_ReportByTopProductCategories').' '.$object->GetField('Metric').' :: ('.$show_date.') :: '.DOMAIN); + $this->Application->StoreVar('graph_data', serialize($a_data)); + return; + } + + + if ($a_report_options['ReportType'] == 5) + { + // pie chart by product + + $a_expressions = Array( + 'Qty' => 'od.Quantity', + 'Cost' => 'od.Cost * od.Quantity', + 'Amount' => 'od.Price * od.Quantity', + 'Tax' => 'o.VAT * od.Price * od.Quantity / o.SubTotal', + 'Shipping' => 'o.ShippingCost * od.Price * od.Quantity / o.SubTotal', + 'Processing' => 'o.ProcessingFee * od.Price * od.Quantity / o.SubTotal', + 'Profit' => '(od.Price - od.Cost) * od.Quantity', + 'StoreQty' => 'IF(ISNULL(eod.OptionsSalt), od.Quantity, 0)', + 'eBayQty' => 'IF(ISNULL(eod.OptionsSalt), 0, od.Quantity)', + 'StoreAmount' => 'IF(ISNULL(eod.OptionsSalt), od.Price * od.Quantity, 0)', + 'eBayAmount' => 'IF(ISNULL(eod.OptionsSalt), 0, od.Price * od.Quantity)', + 'StoreProfit' => 'IF(ISNULL(eod.OptionsSalt), (od.Price - od.Cost) * od.Quantity, 0)', + 'eBayProfit' => 'IF(ISNULL(eod.OptionsSalt), 0, (od.Price - od.Cost) * od.Quantity)', + ); + + $lang = $this->Application->GetVar('m_lang'); + + $sql = 'SELECT + LEFT(p.l'.$lang.'_Name, 60) AS Name, + p.ProductId, + SUM('.$a_expressions[$metric].') as Metric + FROM '.TABLE_PREFIX.'Orders AS o + LEFT JOIN '.TABLE_PREFIX.'OrderItems AS od + ON od.OrderId = o.OrderId + LEFT JOIN '.TABLE_PREFIX.'Products AS p + ON p.ProductId = od.ProductId + '.$ebay_joins.' + WHERE + o.Status IN (4,6) + '.$filter_value.' + GROUP BY p.ProductId + HAVING NOT ISNULL(ProductId) + ORDER BY Metric DESC + LIMIT 0,8 + '; + $a_data = $this->Conn->Query($sql, 'ProductId'); + + $other_metric = 0; + if (count($a_data) > 7) + { + // gather ids for "others" call + $ids = join(',', array_keys($a_data)); + $sql = 'SELECT + SUM('.$a_expressions[$metric].') + FROM '.TABLE_PREFIX.'Orders AS o + LEFT JOIN '.TABLE_PREFIX.'OrderItems AS od + ON od.OrderId = o.OrderId + LEFT JOIN '.TABLE_PREFIX.'Products AS p + ON p.ProductId = od.ProductId + '.$ebay_joins.' + WHERE + o.Status IN (4,6) + '.$filter_value.' + AND p.ProductId NOT IN ('.$ids.') + '; + $other_metric = $this->Conn->GetOne($sql); + if ($other_metric != 0) + { + $a_data[0] = Array( + 'Metric' => $other_metric, + 'Name' => $this->Application->Phrase('la_Others'), + ); + } + } + + + $show_date_from = date('m/d/Y', $a_report_options['from']); + $show_date_to = date('m/d/Y', $a_report_options['to']); + $show_date = ($show_date_from == $show_date_to) ? $show_date_to : $show_date_from.' - '.$show_date_to; + + $this->Application->StoreVar('graph_metric', $this->Application->Phrase('la_text_ReportByTopProducts').' '.$object->GetField('Metric').' :: ('.$show_date.') :: '.DOMAIN); + $this->Application->StoreVar('graph_data', serialize($a_data)); + } + + } + + function GetRandom($params) + { + return rand(1,10000000); + } + + function IsPHPxOrGreater($params) + { + $curver = explode(".", phpversion()); + return ($curver[0] >= $params['version']); + } +} \ No newline at end of file Property changes on: releases/5.2.2-B2/units/reports/reports_tag_processor.php ___________________________________________________________________ Added: cvs2svn:cvs-rev + 1.1.4.4 Added: svn:keywords + Id Added: svn:eol-style + LF Index: releases/5.2.2-B2/units/brackets/brackets_event_handler.php =================================================================== --- releases/5.2.2-B2/units/brackets/brackets_event_handler.php (revision 0) +++ releases/5.2.2-B2/units/brackets/brackets_event_handler.php (revision 16630) @@ -0,0 +1,231 @@ + Array ('subitem' => 'add|edit'), + 'OnInfinity' => Array ('subitem' => 'add|edit'), + 'OnArrange' => Array ('subitem' => 'add|edit'), + ); + + $this->permMapping = array_merge($this->permMapping, $permissions); + } + + /** + * Apply some special processing to object being + * recalled before using it in other events that + * call prepareObject + * + * @param kDBItem|kDBList $object + * @param kEvent $event + * @return void + * @access protected + */ + protected function prepareObject(&$object, kEvent $event) + { + if ( $this->Application->GetVar('s_id') === false ) { + return; + } + + /** @var kDBItem $shipping_object */ + $shipping_object = $this->Application->recallObject('s'); + + /** @var LanguagesItem $lang_object */ + $lang_object = $this->Application->recallObject('lang.current'); + + if ( $lang_object->GetDBField('UnitSystem') == 2 && $shipping_object->GetDBField('Type') == 1 ) { + $fields = Array ('Start', 'End'); + + /** @var kUnitFormatter $formatter */ + $formatter = $this->Application->recallObject('kUnitFormatter'); + + foreach ($fields as $field) { + $object->SetFieldOption($field, 'formatter', 'kUnitFormatter'); + $options = $object->GetFieldOptions($field); + + $formatter->prepareOptions($field, $options, $object); + } + } + } + + function prepareBrackets($event) + { + /** @var LanguagesItem $lang_object */ + $lang_object = $this->Application->recallObject('lang.current'); + + /** @var kDBItem $shipping_object */ + $shipping_object = $this->Application->recallObject('s'); + + if ( $lang_object->GetDBField('UnitSystem') != 2 || $shipping_object->GetDBField('Type') != 1 ) { + return; + } + + $item_info = $this->Application->GetVar( $event->getPrefixSpecial() ); + + foreach ($item_info as $id => $item_data) { + if ( $item_info[$id]['Start_a'] === '' && $item_info[$id]['Start_b'] === '' ) { + $item_info[$id]['Start'] = ''; + } + else { + $item_info[$id]['Start'] = kUtil::Pounds2Kg($item_info[$id]['Start_a'], $item_info[$id]['Start_b']); + } + + if ( $item_info[$id]['End_a'] == '∞' || $item_info[$id]['End_a'] == '∞' ) { + $item_info[$id]['End'] = '∞'; + } + elseif ( $item_info[$id]['End_a'] === '' && $item_info[$id]['End_b'] === '' ) { + $item_info[$id]['End'] = ''; + } + else { + $item_info[$id]['End'] = kUtil::Pounds2Kg($item_info[$id]['End_a'], $item_info[$id]['End_b']); + } + } + + $this->Application->SetVar($event->getPrefixSpecial(), $item_info); + } + + /** + * Adds additional 5 empty brackets + * + * @param kEvent $event + */ + function OnMoreBrackets($event) + { + $brackets_helper =& $this->getHelper($event); + + $brackets_helper->OnMoreBrackets($event); + } + + /** + * Arrange brackets + * + * @param kEvent $event + */ + function OnArrange($event) + { + $brackets_helper =& $this->getHelper($event); + + $brackets_helper->arrangeBrackets($event); + $event->CallSubEvent('OnPreSaveBrackets'); + } + + /** + * Arrange infinity brackets + * + * @param kEvent $event + */ + function OnInfinity($event) + { + $brackets_helper =& $this->getHelper($event); + + $brackets_helper->arrangeBrackets($event); + $event->CallSubEvent('OnPreSaveBrackets'); + + $brackets_helper->OnInfinity($event); + $event->CallSubEvent('OnPreSaveBrackets'); + } + + /** + * Initializes kBracketsHelper class based on event + * + * @param kEvent $event + * @param bool $event_readonly + * @return kBracketsHelper + */ + protected function &getHelper($event, $event_readonly = false) + { + /** @var kDBItem $shipping_object */ + $shipping_object = $this->Application->recallObject('s'); + + $default_start = $shipping_object->GetDBField('Type') == 1 ? 0 : 1; + + if ( !$event_readonly ) { + $this->prepareBrackets($event); + $event->redirect = false; + } + + /** @var kBracketsHelper $brackets_helper */ + $brackets_helper = $this->Application->recallObject('BracketsHelper'); + + $brackets_helper->InitHelper('Start', 'End', Array (), $default_start); + + return $brackets_helper; + } + + /** + * Occurs before updating item + * + * @param kEvent $event + * @return void + * @access protected + */ + protected function OnBeforeItemUpdate(kEvent $event) + { + parent::OnBeforeItemUpdate($event); + + /** @var kDBItem $object */ + $object = $event->getObject(); + + $linked_info = $object->getLinkedInfo(); + $object->SetDBField($linked_info['ParentTableKey'], $linked_info['ParentId']); + + $brackets_helper =& $this->getHelper($event, true); + $brackets_helper->replaceInfinity($event); + } + + /** + * Enter description here... + * + * @param kEvent $event + */ + function OnPreSaveBrackets($event) + { + /** @var LanguagesItem $lang_object */ + $lang_object = $this->Application->recallObject('lang.current'); + + /** @var kDBItem $shipping_object */ + $shipping_object = $this->Application->recallObject('s'); + + if ( $lang_object->GetDBField('UnitSystem') == 2 && $shipping_object->GetDBField('Type') == 1 ) { + $item_info = $this->Application->GetVar($event->getPrefixSpecial()); + + if ( is_array($item_info) ) { + foreach ($item_info as $id => $values) { + if ( $values['End'] == -1 ) { + $item_info[$id]['End_a'] = -1 / kUtil::POUND_TO_KG; + $item_info[$id]['End_b'] = 0; + } + } + $this->Application->SetVar($event->getPrefixSpecial(), $item_info); + } + } + + $brackets_helper =& $this->getHelper($event, true); + $brackets_helper->OnPreSaveBrackets($event); + } + +} \ No newline at end of file Property changes on: releases/5.2.2-B2/units/brackets/brackets_event_handler.php ___________________________________________________________________ Added: cvs2svn:cvs-rev + 1.15.2.1 Added: svn:keywords + Id Added: svn:eol-style + LF Index: releases/5.2.2-B2/units/brackets/brackets_config.php =================================================================== --- releases/5.2.2-B2/units/brackets/brackets_config.php (revision 0) +++ releases/5.2.2-B2/units/brackets/brackets_config.php (revision 16630) @@ -0,0 +1,66 @@ + 'br', + 'ItemClass' => Array ('class' => 'kDBItem', 'file' => '', 'build_event' => 'OnItemBuild'), + 'ListClass' => Array ('class' => 'kDBList', 'file' => '', 'build_event' => 'OnListBuild'), + 'EventHandlerClass' => Array ('class' => 'BracketsEventHandler', 'file' => 'brackets_event_handler.php', 'build_event' => 'OnBuild'), + 'TagProcessorClass' => Array ('class' => 'BracketsTagProcessor', 'file' => 'brackets_tag_processor.php', 'build_event' => 'OnBuild'), + + 'AutoLoad' => true, + + 'Hooks' => Array ( + Array ( + 'Mode' => hBEFORE, + 'Conditional' => true, + 'HookToPrefix' => '#PARENT#', + 'HookToSpecial' => '', + 'HookToEvent' => Array ('OnPreSave'), + 'DoPrefix' => '', + 'DoSpecial' => '', + 'DoEvent' => 'OnArrange', + ), + ), + + 'QueryString' => Array ( + 1 => 'id', + 2 => 'Page', + 3 => 'PerPage', + 4 => 'event', + ), + + 'IDField' => 'BracketId', + 'TableName' => TABLE_PREFIX.'ShippingBrackets', + 'ForeignKey' => 'ShippingTypeID', + 'ParentTableKey' => 'ShippingID', + 'ParentPrefix' => 's', + 'AutoDelete' => true, + 'AutoClone' => true, + + 'SubItems' => Array ('sc'), + + 'ListSQLs' => Array ( + '' => ' SELECT * + FROM %s' + ), + + 'Fields' => Array ( + 'BracketId' => Array ('type' => 'int', 'not_null' => 1, 'default' => 0,), + 'ShippingTypeID' => Array ('type' => 'int', 'not_null' => 1, 'default' => 0,), + 'Start' => Array ('type' => 'double', 'formatter' => 'kFormatter', 'not_null' => true, 'default' => 0), + 'End' => Array ('type' => 'double', 'formatter' => 'kFormatter', 'not_null' => true, 'default' => 0), + ), +); \ No newline at end of file Property changes on: releases/5.2.2-B2/units/brackets/brackets_config.php ___________________________________________________________________ Added: cvs2svn:cvs-rev + 1.12 Added: svn:keywords + Id Added: svn:eol-style + LF Index: releases/5.2.2-B2/units/brackets/globals.php =================================================================== --- releases/5.2.2-B2/units/brackets/globals.php (revision 0) +++ releases/5.2.2-B2/units/brackets/globals.php (revision 16630) @@ -0,0 +1,62 @@ +$elem2['End'] || $elem1['End'] == -1) && $elem2['End'] != -1 ) + { + return 1; + } + elseif ( ($elem1['End']<$elem2['End'] || $elem2['End'] == -1) && $elem1['End'] != -1 ) + { + return -1; + } + else + { + return 0; + } +} + +function bracket_id_sort($first_id, $second_id) +{ + $first_abs = abs($first_id); + $second_abs = abs($second_id); + $first_sign = ($first_id == 0) ? 0 : $first_id / $first_abs; + $second_sign = ($second_id == 0) ? 0 : $second_id / $second_abs; + if($first_sign != $second_sign) + { + if($first_id > $second_id) { + $bigger =& $first_abs; + $smaller =& $second_abs; + } + else { + $bigger =& $second_abs; + $smaller =& $first_abs; + } + $smaller = $bigger + $smaller; + } + + if($first_abs > $second_abs) { + return 1; + } + elseif ($first_abs < $second_abs) + { + return -1; + } + else + { + return 0; + } +} \ No newline at end of file Property changes on: releases/5.2.2-B2/units/brackets/globals.php ___________________________________________________________________ Added: cvs2svn:cvs-rev + 1.4 Added: svn:keywords + Id Added: svn:eol-style + LF Index: releases/5.2.2-B2/units/brackets/brackets_tag_processor.php =================================================================== --- releases/5.2.2-B2/units/brackets/brackets_tag_processor.php (revision 0) +++ releases/5.2.2-B2/units/brackets/brackets_tag_processor.php (revision 16630) @@ -0,0 +1,202 @@ +SelectParam($params, 'name,field'); + + if ( ($field == 'Start' || $field == 'End') && $value == -1 ) { + $value = '∞'; + } + + return $value; + } + + function ShowBracketsForm($params) + { + /** @var kDBItem $shipping_object */ + $shipping_object = $this->Application->recallObject('s'); + + $default_start = ($shipping_object->GetDBField('Type') == 1) ? 0 : 1; + + /** @var kBracketsHelper $brackets_helper */ + $brackets_helper = $this->Application->recallObject('BracketsHelper'); + + $brackets_helper->InitHelper('Start', 'End', Array(), $default_start ); + + $br_object = $this->Application->recallObject( $this->getPrefixSpecial() ); + + $event = new kEvent($this->getPrefixSpecial(true) . ':OnArrange'); + $br_data = $brackets_helper->getBrackets($event); + $linked_info = $br_object->getLinkedInfo($this->Special); + + if (!$br_data) { + $sql = 'SELECT * FROM '.$br_object->TableName.' WHERE '.$linked_info['ForeignKey'].' = '.$linked_info['ParentId']; + $brackets = $this->Conn->Query($sql, $br_object->IDField); + + usort($brackets, Array(&$brackets_helper, 'compareBrackets')); + + /** @var kDBItem $dummy */ + $dummy = $this->Application->recallObject($this->Prefix.'.-dummy', null, array('skip_autoload' => true)); + + // performs number formatting + foreach($brackets as $id => $values) + { + foreach($values as $value_key=>$value_val){ + $dummy->SetDBField($value_key, $value_val); + $brackets[$id][$value_key] = $dummy->GetField($value_key); + } + } + + $br_data = $brackets; + $brackets_helper->setBrackets($event, $brackets); + } + else { + usort($br_data, Array(&$brackets_helper, 'compareBrackets')); + $br_data = $brackets_helper->formatBrackets($br_data); + } + + $ret = ''; + if ( is_array($br_data) ) { + $block_params = $this->prepareTagParams($params); + $block_params['IdField'] = $br_object->IDField; + $block_params['name'] = $params['block']; + $first = true; + + $main_object = $this->Application->recallObject($linked_info['ParentPrefix'].'.'.$this->Special); +// $plan_type = $main_object->GetDBField('PlanType'); +// $limits_format = ($plan_type == 2) ? '%d' : $br_object->getFieldOption('Start', 'format'); + + // this is needed to find next id + $br_data_copy = $br_data; + foreach($br_data as $id => $values) + { + + foreach($values as $value_key => $value_val) + { + $block_params[$value_key] = $value_val; + } + reset($values); + + next($br_data_copy); + $next_bracket = current($br_data_copy); + +// $values['Start'] = sprintf($limits_format, $values['Start']); +// $values['End'] = sprintf($limits_format, $values['End']); + + $block_params['id'] = $values[$br_object->IDField]; + $block_params['min'] = ($id == -1) ? ($values['Start'] ? $values['Start'] : 0) : $values['Start']; + $block_params['max'] = ($values['End'] == -1) ? '∞' : $values['End']; + $block_params['next_min_id'] = $next_bracket[$br_object->IDField]; + + $lang_object = $this->Application->recallObject('lang.current'); + if($lang_object->GetDBField('UnitSystem') == 2 && $main_object->GetDBField('Type') == 1) + { + if($block_params['min'] === '') + { + $block_params['min_a'] = ''; + $block_params['min_b'] = ''; + } + else + { + list($block_params['min_a'], $block_params['min_b']) = kUtil::Kg2Pounds($block_params['min']); + } + + if($block_params['max'] == '∞') + { + $block_params['max_a'] = '∞'; + $block_params['max_b'] = ''; + } + else + { + list($block_params['max_a'], $block_params['max_b']) = kUtil::Kg2Pounds($block_params['max']); + } + } + + if($first) + { + $block_params['first'] = 1; + $first = false; + } + else + { + $block_params['first'] = 0; + } + $ret .= $this->Application->ParseBlock($block_params, 1); + } + } + return $ret; + } + + + /* + function ShowBracketsForm($params) + { + $br_object = $this->Application->recallObject( $this->getPrefixSpecial() ); + + $br_data = $this->Application->GetVar('br'); + + if(!$br_data) + { + $sql = 'SELECT * FROM '.$br_object->TableName. + ' WHERE ShippingTypeID = '.$this->Application->GetVar('s_id'); + $brackets = $this->Conn->Query($sql, 'BracketId'); + usort($brackets, 'bracket_comp'); + + $br_data = array_reverse($brackets); + $this->Application->SetVar('br', $br_data); + } + else + { + $br_data = array_reverse($br_data); + } + + $ret = ''; + if( is_array($br_data) ) + { + $i = -count($br_data); + ksort($br_data); + foreach($br_data as $record) + { + $temp_sorted[$i] = $record; + $i++; + } + $br_data = array_reverse($temp_sorted, true); + + $block_params['name'] = $params['block']; + $first = true; + foreach($br_data as $id => $values) + { + $block_params['id'] = $id; + $block_params['start'] = ($id == -1) ? ($values['Start'] ? $values['Start'] : 0) : $values['Start']; + $block_params['end'] = ($values['End'] == -1) ? '∞' : $values['End']; + if ($first) + { + $block_params['first'] = 1; + $first = false; + } + else + { + $block_params['first'] = 0; + } + $ret .= $this->Application->ParseBlock($block_params); + } + } + return $ret; + }*/ +} \ No newline at end of file Property changes on: releases/5.2.2-B2/units/brackets/brackets_tag_processor.php ___________________________________________________________________ Added: cvs2svn:cvs-rev + 1.12.2.2 Added: svn:keywords + Id Added: svn:eol-style + LF Index: releases/5.2.2-B2/units/payment_type_currencies/payment_type_currencies_tag_processor.php =================================================================== --- releases/5.2.2-B2/units/payment_type_currencies/payment_type_currencies_tag_processor.php (revision 0) +++ releases/5.2.2-B2/units/payment_type_currencies/payment_type_currencies_tag_processor.php (revision 16630) @@ -0,0 +1,33 @@ +Application->recallObject($this->Prefix); + $payment_type_object = $this->Application->recallObject('pt'); + $currency_object = $this->Application->recallObject('curr.active'); + + $pt_id = $payment_type_object->GetDBField('PaymentTypeId'); + $curr_id = $currency_object->GetDBField('CurrencyId'); + $sql = 'SELECT * FROM '.$object->TableName.' + WHERE PaymentTypeId='.$pt_id.' AND + CurrencyId='.$curr_id; + $res = $this->Conn->GetOne($sql); + return $res ? 1 : 0; + } + + } \ No newline at end of file Property changes on: releases/5.2.2-B2/units/payment_type_currencies/payment_type_currencies_tag_processor.php ___________________________________________________________________ Added: cvs2svn:cvs-rev + 1.2 Added: svn:keywords + Id Added: svn:eol-style + LF Index: releases/5.2.2-B2/units/payment_type_currencies/payment_type_currencies_event_handler.php =================================================================== --- releases/5.2.2-B2/units/payment_type_currencies/payment_type_currencies_event_handler.php (revision 0) +++ releases/5.2.2-B2/units/payment_type_currencies/payment_type_currencies_event_handler.php (revision 16630) @@ -0,0 +1,63 @@ +Application->GetVar('currency_list'); + + if ( !$currency_id_list ) { + return; + } + + /** @var kDBItem $object */ + $object = $event->getObject(Array ('skip_autoload' => true)); + + $pt_id = $this->Application->GetVar('pt_id'); + + if ( $pt_id === false ) { + return; + } + + $sql = 'DELETE FROM ' . $object->TableName . ' + WHERE PaymentTypeId = ' . $pt_id; + $this->Conn->Query($sql); + + foreach ($currency_id_list as $id) { + $object->SetDBField('CurrencyId', $id); + $object->SetDBField('PaymentTypeId', $pt_id); + $this->customProcessing($event, 'before'); + + if ( $object->Create() ) { + $this->customProcessing($event, 'after'); + $event->status = kEvent::erSUCCESS; + } + else { + $event->status = kEvent::erFAIL; + $event->redirect = false; + $this->Application->SetVar($event->getPrefixSpecial() . '_SaveEvent', 'OnCreate'); + $object->setID(0); + } + } + } + } \ No newline at end of file Property changes on: releases/5.2.2-B2/units/payment_type_currencies/payment_type_currencies_event_handler.php ___________________________________________________________________ Added: cvs2svn:cvs-rev + 1.5.2.1 Added: svn:keywords + Id Added: svn:eol-style + LF Index: releases/5.2.2-B2/units/payment_type_currencies/payment_type_currencies_config.php =================================================================== --- releases/5.2.2-B2/units/payment_type_currencies/payment_type_currencies_config.php (revision 0) +++ releases/5.2.2-B2/units/payment_type_currencies/payment_type_currencies_config.php (revision 16630) @@ -0,0 +1,67 @@ + 'ptc', + 'ItemClass' => Array ('class' => 'kDBItem', 'file' => '', 'build_event' => 'OnItemBuild'), + 'ListClass' => Array ('class' => 'kDBList', 'file' => '', 'build_event' => 'OnListBuild'), + 'EventHandlerClass' => Array ('class' => 'PaymentTypeCurrenciesEventHandler', 'file' => 'payment_type_currencies_event_handler.php', 'build_event' => 'OnBuild'), + 'TagProcessorClass' => Array ('class' => 'PaymentTypeCurrenciesTagProcessor', 'file' => 'payment_type_currencies_tag_processor.php', 'build_event' => 'OnBuild'), + + 'AutoLoad' => true, + + 'QueryString' => Array ( + 1 => 'id', + 2 => 'Page', + 3 => 'PerPage', + 4 => 'event', + 5 => 'mode', + ), + + 'Hooks' => Array ( + Array ( + 'Mode' => hBEFORE, + 'Conditional' => false, + 'HookToPrefix' => '#PARENT#', + 'HookToSpecial' => '', + 'HookToEvent' => Array ( 'OnPreSaveAndGoToTab', 'OnPreSaveAndGo', 'OnPreSave' ), + 'DoPrefix' => '', + 'DoSpecial' => '', + 'DoEvent' => 'OnCreate', + ), + ), + + 'IDField' => 'PaymentTypeCurrencyId', + 'TableName' => TABLE_PREFIX.'PaymentTypeCurrencies', + 'ParentTableKey' => 'PaymentTypeId', // linked field in master table + 'ForeignKey' => 'PaymentTypeId', // linked field in subtable + 'ParentPrefix' => 'pt', + 'AutoDelete' => true, + + 'SubItems' => Array (), + + 'ListSQLs' => Array ( + ''=> ' SELECT * + FROM %s' + ), + + 'ListSortings' => Array (), + + 'Fields' => Array ( + 'PaymentTypeCurrencyId' => Array ('type' => 'int', 'not_null' => 1, 'default' => 0), + 'PaymentTypeId' => Array ('type' => 'int', 'not_null' => 1, 'default' => 0), + 'CurrencyId' => Array ('type' => 'int', 'not_null' => 1, 'default' => 0), + ), +); \ No newline at end of file Property changes on: releases/5.2.2-B2/units/payment_type_currencies/payment_type_currencies_config.php ___________________________________________________________________ Added: cvs2svn:cvs-rev + 1.5 Added: svn:keywords + Id Added: svn:eol-style + LF Index: releases/5.2.2-B2/units/helpers/order_helper.php =================================================================== --- releases/5.2.2-B2/units/helpers/order_helper.php (revision 0) +++ releases/5.2.2-B2/units/helpers/order_helper.php (revision 16630) @@ -0,0 +1,248 @@ +Application->RecallVar('checkout_errors'); + + $ret = Array ( + 'order' => Array ( + 'CouponId' => (int)$object->GetDBField('CouponId'), + 'CouponName' => (string)$object->GetDBField('CouponName'), + 'GiftCertificateId' => (int)$object->GetDBField('GiftCertificateDiscount'), + 'GiftCertificateDiscount' => $this->convertCurrency($object->GetDBField('GiftCertificateDiscount'), $currency), + 'DiscountTotal' => $this->convertCurrency($object->GetDBField('DiscountTotal'), $currency), + 'SubTotal' => $this->convertCurrency($object->GetDBField('SubTotal'), $currency), + ), + 'items' => Array (), + 'errors' => $errors ? unserialize($errors) : Array (), + ); + + /** @var kDBList $items */ + $items = $this->Application->recallObject('orditems', 'orditems_List', Array ('per_page' => -1)); + + $items->Query(); + $items->GoFirst(); + + $ret['order']['ItemsInCart'] = array_sum( $items->GetCol('Quantity') ); + + if ( $items->EOL() ) { + return $ret; + } + + /** @var kCatDBItem $product */ + $product = $this->Application->recallObject('p', null, Array ('skip_autoload' => true)); + + $sql = $product->GetSelectSQL() . ' + WHERE ' . $product->TableName . '.' . $product->IDField . ' IN (' . implode(',', $items->GetCol('ProductId')) . ')'; + $products = $this->Conn->Query($sql, $product->IDField); + + while ( !$items->EOL() ) { + // prepare product from order item + $product->LoadFromHash( $products[ $items->GetDBField('ProductId') ] ); + $this->Application->SetVar('orditems_id', $items->GetID()); // for edit/delete links using GET + + // weird code from orditems:PrintList + $this->Application->SetVar('p_id', $product->GetID()); + $this->Application->SetVar('m_cat_id', $product->GetDBField('CategoryId')); + + // collect order item info + $url_params = Array ( + 'p_id' => $product->GetID(), + 'm_cat_id' => $product->GetDBField('CategoryId'), + 'pass' => 'm,p', + ); + + $product_url = $this->Application->HREF('__default__', '', $url_params); + + $item_data = $items->GetDBField('ItemData'); + $item_data = $item_data ? unserialize($item_data) : Array (); + + $row_index = $items->GetDBField('ProductId') . ':' . $items->GetDBField('OptionsSalt') . ':' . $items->GetDBField('BackOrderFlag'); + + /** @var ImageHelper $image_helper */ + $image_helper = $this->Application->recallObject('ImageHelper'); + + // TODO: find a way to specify thumbnail size & default image + + $ret['items'][$row_index] = Array ( + 'product_url' => $product_url, + 'product_type' => $product->GetDBField('Type'), + 'options' => isset($item_data['Options']) ? $item_data['Options'] : false, + 'free_promo_shipping' => $this->eligibleForFreePromoShipping($items), + + 'fields' => Array ( + 'OrderItemId' => $items->GetDBField('OrderItemId'), + 'ProductName' => $items->GetDBField('ProductName'), + 'PrimaryImage' => $product->GetField('PrimaryImage', 'resize:58x58;default:img/no_picture.gif'), + 'BackOrderFlag' => (int)$items->GetDBField('BackOrderFlag'), + 'FlatPrice' => $this->convertCurrency($items->GetDBField('FlatPrice'), $currency), + 'Price' => $this->convertCurrency($items->GetDBField('Price'), $currency), + 'Quantity' => (int)$items->GetDBField('Quantity'), + 'Virtual' => (int)$items->GetDBField('Virtual'), + 'Type' => (int)$product->GetDBField('Type'), + + 'cust_Availability' => $product->GetDBField('cust_Availability'), + ), + ); + + $items->GoNext(); + } + + if ( $remove_errors ) { + $this->Application->RemoveVar('checkout_errors'); + } + + return $ret; + } + + function convertCurrency($amount, $currency) + { + /** @var CurrencyRates $converter */ + $converter = $this->Application->recallObject('CurrencyRates'); + + // convert primary currency to selected (if they are the same, converter will just return) + return (float)$converter->Convert($amount, 'PRIMARY', $this->getISO($currency)); + } + + function getISO($currency) + { + if ($currency == 'selected') { + $iso = $this->Application->RecallVar('curr_iso'); + } + elseif ($currency == 'primary' || $currency == '') { + $iso = $this->Application->GetPrimaryCurrency(); + } + else { //explicit currency + $iso = strtoupper($currency); + } + + return $iso; + } + + /** + * Checks, that given order item is eligible for free promo shipping + * + * @param kDBItem|kDBList $order_item + * @return bool + */ + function eligibleForFreePromoShipping(&$order_item) + { + if ( $order_item->GetDBField('Type') != PRODUCT_TYPE_TANGIBLE ) { + return false; + } + + $free_shipping = $order_item->GetDBField('MinQtyFreePromoShipping'); + + return $free_shipping > 0 && $free_shipping <= $order_item->GetDBField('Quantity'); + } + + /** + * Returns a template, that will be used to continue shopping from "shopping cart" template + * + * @param string $template + * @return string + * @access public + */ + public function getContinueShoppingTemplate($template = '') + { + if ( !$template || $template == '__default__' ) { + $template = $this->Application->RecallVar('continue_shopping'); + } + + if ( !$template ) { + $template = 'in-commerce/index'; + } + + return $template; + } + + /** + * Detects credit card type by it's number. + * + * @param string $number Credit card number. + * + * @return integer + * @deprecated 5.2.2-B1 + * @see OrderHelper::getCreditCardType() + */ + public function getCreditCartType($number) + { + kUtil::deprecatedMethod(__METHOD__, '5.2.2-B1', 'OrderHelper::getCreditCardType'); + + return $this->getCreditCardType($number); + } + + /** + * Detects credit card type by it's number. + * + * @param string $number Credit card number. + * + * @return integer + */ + public function getCreditCardType($number) + { + // Get rid of any non-digits. + $number = preg_replace('/[^\d]/', '', $number); + + $mapping = Array ( + '/^4.{15}$|^4.{12}$/' => 1, // Visa + '/^5[1-5].{14}$/' => 2, // MasterCard + '/^3[47].{13}$/' => 3, // American Express + '/^6011.{12}$/' => 4, // Discover + '/^30[0-5].{11}$|^3[68].{12}$/' => 5, // Diners Club + '/^3.{15}$|^2131|1800.{11}$/' => 6, // JBC + ); + + foreach ($mapping as $number_regex => $card_type) { + if ( preg_match($number_regex, $number) ) { + return $card_type; + } + } + + 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; + } + } Property changes on: releases/5.2.2-B2/units/helpers/order_helper.php ___________________________________________________________________ Added: svn:keywords + Id Added: svn:eol-style + LF Index: releases/5.2.2-B2/units/helpers/ecb_currency_rates.php =================================================================== --- releases/5.2.2-B2/units/helpers/ecb_currency_rates.php (revision 0) +++ releases/5.2.2-B2/units/helpers/ecb_currency_rates.php (revision 16630) @@ -0,0 +1,62 @@ +RateSource = 'http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml'; + + parent::__construct(); + } + + function GetRatesData() + { + $xml_parser = xml_parser_create(); + + /** @var kCurlHelper $curl_helper */ + $curl_helper = $this->Application->recallObject('CurlHelper'); + $curl_helper->followLocation = true; + + $xml = $curl_helper->Send($this->RateSource); + + if ( !$curl_helper->isGoodResponseCode() || strlen($xml) == 0 ) { + return; + } + + xml_parse_into_struct($xml_parser, $xml, $struct, $index); + $data_res = Array(); + foreach($struct as $element) + { + if(isset($element['attributes']) && isset($element['attributes']['CURRENCY'])) + { + $currency = $element['attributes']['CURRENCY']; + $data_res[$currency]['ID'] = $currency; + $data_res[$currency]['TARGET'] = 'EUR'; + $data_res[$currency]['UNITS'] = 1; + $data_res[$currency]['RATE'] = ($element['attributes']['RATE'] == 0) ? 0 : 1 / $element['attributes']['RATE']; + } + } + + if ( !isset($data_res['EUR']) ) { + $data_res['EUR']['ID'] = 'EUR'; + $data_res['EUR']['UNITS'] = 1; + $data_res['EUR']['TARGET'] = 'EUR'; + $data_res['EUR']['RATE'] = 1; + } + + $this->ExchangeRates = $data_res; + } +} Property changes on: releases/5.2.2-B2/units/helpers/ecb_currency_rates.php ___________________________________________________________________ Added: svn:keywords + Id Added: svn:eol-style + LF Index: releases/5.2.2-B2/units/helpers/bank_lv_currency_rates.php =================================================================== --- releases/5.2.2-B2/units/helpers/bank_lv_currency_rates.php (revision 0) +++ releases/5.2.2-B2/units/helpers/bank_lv_currency_rates.php (revision 16630) @@ -0,0 +1,70 @@ +RateSource = 'http://www.bank.lv/ValutuKursi/XML/xml.cfm'; + + parent::__construct(); + } + + function GetRatesData() + { + $xml_parser = xml_parser_create(); + + /** @var kCurlHelper $curl_helper */ + $curl_helper = $this->Application->recallObject('CurlHelper'); + $curl_helper->followLocation = true; + + $xml = $curl_helper->Send($this->RateSource); + + if ( !$curl_helper->isGoodResponseCode() || strlen($xml) == 0 ) { + return; + } + + xml_parse_into_struct($xml_parser, $xml, $struct, $index); + $data_res = Array(); + $currency = ''; + foreach($struct as $element) + { + switch($element['tag']) + { + case 'ID': + $currency = $element['value']; + $data_res[$currency]['ID'] = $currency; + $data_res[$currency]['TARGET'] = 'LVL'; + break; + case 'UNITS': + $data_res[$currency]['UNITS'] = $element['value']; + break; + case 'RATE': + $data_res[$currency]['RATE'] = $element['value']; + break; + default: + } + } + + if(!$data_res['LVL']) + { + $data_res['LVL']['ID'] = 'LVL'; + $data_res['LVL']['UNITS'] = 1; + $data_res['LVL']['TARGET'] = 'LVL'; + $data_res['LVL']['RATE'] = 1; + } + $this->ExchangeRates = $data_res; + } +} Property changes on: releases/5.2.2-B2/units/helpers/bank_lv_currency_rates.php ___________________________________________________________________ Added: svn:keywords + Id Added: svn:eol-style + LF Index: releases/5.2.2-B2/units/helpers/frny_currency_rates.php =================================================================== --- releases/5.2.2-B2/units/helpers/frny_currency_rates.php (revision 0) +++ releases/5.2.2-B2/units/helpers/frny_currency_rates.php (revision 16630) @@ -0,0 +1,91 @@ +RateSource = 'http://www.ny.frb.org/markets/fxrates/FXtoXML.cfm?FEXdate=%s&FEXtime=1200'; + + parent::__construct(); + } + + function GetRatesData() + { + /** @var kCurlHelper $curl_helper */ + $curl_helper = $this->Application->recallObject('CurlHelper'); + $curl_helper->followLocation = true; + + for($i = 0; $i < 10; $i++) + { + $time = adodb_mktime() - $i * 3600 * 24; + $source_file = sprintf($this->RateSource, adodb_date('Y-m-d', $time)); + $xml = $curl_helper->Send($source_file); + + if ( !$curl_helper->isGoodResponseCode() || strlen($xml) == 0 ) { + continue; + } + + $xml_parser = xml_parser_create(); + xml_parse_into_struct($xml_parser, $xml, $struct, $index); + foreach($struct as $element) + { + if($element['tag'] == 'FRBNY:DATASET') + { + break; + } + } + if($element['type'] == 'open') + { + break; + } + } + if($element['type'] != 'open') + { + return false; + } + + foreach($struct as $element) + { + switch($element['tag']) + { + case 'FRBNY:SERIES': + $currency = $element['attributes']['UNIT']; + if($currency) + { + $data_res[$currency]['ID'] = $currency; + $data_res[$currency]['UNITS'] = 1; + } + break; + case 'FRBNY:CURR': + $data_res[$currency]['TARGET'] = $element['value']; + break; + case 'FRBNY:OBS_VALUE': + $data_res[$currency]['RATE'] = ($element['value'] == 0) ? 0 : 1 / $element['value']; + break; + default: + } + } + if(!$data_res['USD']) + { + $data_res['USD']['ID'] = 'USD'; + $data_res['USD']['UNITS'] = 1; + $data_res['USD']['TARGET'] = 'USD'; + $data_res['USD']['RATE'] = 1; + } + $this->ExchangeRates = $data_res; + } + +} Property changes on: releases/5.2.2-B2/units/helpers/frny_currency_rates.php ___________________________________________________________________ Added: svn:keywords + Id Added: svn:eol-style + LF Index: releases/5.2.2-B2/units/helpers/helpers_config.php =================================================================== --- releases/5.2.2-B2/units/helpers/helpers_config.php (revision 0) +++ releases/5.2.2-B2/units/helpers/helpers_config.php (revision 16630) @@ -0,0 +1,17 @@ + 'in-commerce-helpers', + + 'EventHandlerClass' => Array ('class' => 'kEventHandler', 'file' => '', 'build_event' => 'OnBuild'), + + 'RegisterClasses' => Array ( + Array ('pseudo' => 'OrderHelper', 'class' => 'OrderHelper', 'file' => 'order_helper.php', 'build_event' => ''), + Array ('pseudo' => 'CurrencyRates', 'class' => 'CurrencyRates', 'file' => 'currency_rates.php', 'build_event' => ''), + Array ('pseudo' => 'BankLVCurrencyRates', 'class' => 'BankLVCurrencyRates', 'file' => 'bank_lv_currency_rates.php', 'build_event' => ''), + Array ('pseudo' => 'ECBCurrencyRates', 'class' => 'ECBCurrencyRates', 'file' => 'ecb_currency_rates.php', 'build_event' => ''), + Array ('pseudo' => 'FRNYCurrencyRates', 'class' => 'FRNYCurrencyRates', 'file' => 'frny_currency_rates.php', 'build_event' => ''), + ), +); \ No newline at end of file Property changes on: releases/5.2.2-B2/units/helpers/helpers_config.php ___________________________________________________________________ Added: svn:keywords + Id Added: svn:eol-style + LF Index: releases/5.2.2-B2/units/helpers/currency_rates.php =================================================================== --- releases/5.2.2-B2/units/helpers/currency_rates.php (revision 0) +++ releases/5.2.2-B2/units/helpers/currency_rates.php (revision 16630) @@ -0,0 +1,153 @@ +GetRatesData(); + } + + function GetRatesData() + { + $cache_key = 'currency_rates[%CurrSerial%]'; + $rates = $this->Application->getCache($cache_key); + $primary = $this->Application->GetPrimaryCurrency(); + + if ($rates === false) { + $this->Conn->nextQueryCachable = true; + $sql = 'SELECT ISO, RateToPrimary + FROM ' . $this->Application->getUnitOption('curr', 'TableName') . ' + WHERE Status = ' . STATUS_ACTIVE; + $rates = $this->Conn->Query($sql); + + $this->Application->setCache($cache_key, $rates); + } + + foreach ($rates as $rate) { + $this->SetRate($primary, $rate['ISO'], $rate['RateToPrimary']); + } + } + + function GetRate($source_cur, $target_cur, $units = 1) + { + $source_cur = ($source_cur == 'PRIMARY') ? $this->Application->GetPrimaryCurrency() : $source_cur; + $target_cur = ($target_cur == 'PRIMARY') ? $this->Application->GetPrimaryCurrency() : $target_cur; + if($source_cur == $target_cur) + { + return 1; + } + + if($this->ExchangeRates[$target_cur]['TARGET'] == $source_cur) + { + $rate = ($this->ExchangeRates[$target_cur]['RATE'] == 0) ? false : 1 / $this->ExchangeRates[$target_cur]['RATE']; + } + elseif($this->ExchangeRates[$source_cur]['TARGET'] == $target_cur) + { + $rate = $this->ExchangeRates[$source_cur]['RATE']; + } + else + { + $rate = ($this->ExchangeRates[$target_cur]['RATE'] == 0) ? false : $this->ExchangeRates[$source_cur]['RATE'] / $this->ExchangeRates[$target_cur]['RATE']; + } + $rate *= $units; + return $rate; + } + + function Convert($amount, $source_cur, $target_cur) + { + return $amount * $this->GetRate($source_cur, $target_cur); + } + + function AddCurrencySymbol($value, $iso, $decimal_tag = '') + { + static $decimal_separator = false; + + $cache_key = 'iso_masks[%CurrSerial%]'; + $iso_masks = $this->Application->getCache($cache_key); + + if ( $iso_masks === false ) { + $this->Conn->nextQueryCachable = true; + $symbol_sql = 'IF(COALESCE(Symbol, "") = "", CONCAT(ISO, " "), Symbol)'; + + $sql = 'SELECT IF(SymbolPosition = 0, CONCAT(' . $symbol_sql . ', "%s"), CONCAT("%s", ' . $symbol_sql . ')), LOWER(ISO) AS ISO + FROM ' . $this->Application->getUnitOption('curr', 'TableName') . ' + WHERE Status = ' . STATUS_ACTIVE; + $iso_masks = $this->Conn->GetCol($sql, 'ISO'); + $this->Application->setCache($cache_key, $iso_masks); + } + + if ( $decimal_tag ) { + if ( $decimal_separator === false ) { + /** @var LanguagesItem $language */ + $language = $this->Application->recallObject('lang.current'); + + $decimal_separator = $language->GetDBField('DecimalPoint'); + } + + list ($integer_part, $decimal_part) = explode($decimal_separator, $value); + $value = $integer_part . $decimal_separator . '<' . $decimal_tag . '>' . $decimal_part . ''; + } + + $iso = strtolower($iso); + + return array_key_exists($iso, $iso_masks) ? sprintf($iso_masks[$iso], $value) : $value; + } + + function SetRate($source_cur, $target_cur, $rate, $units = 1) + { + $this->ExchangeRates[$target_cur]['TARGET'] = $source_cur; + $this->ExchangeRates[$target_cur]['ID'] = $target_cur; + $this->ExchangeRates[$target_cur]['RATE'] = $rate; + $this->ExchangeRates[$target_cur]['UNITS'] = $units; + } + + function StoreRates($currencies=null) + { + /** @var kDBItem $curr_object */ + $curr_object = $this->Application->recallObject('curr', null, Array ('skip_autoload' => true)); + + if ($currencies) { + if (!is_array($currencies)) { + $currencies = explode(',', $currencies); + } + } + else { + $currencies = array_keys($this->ExchangeRates); + } + + foreach ($currencies as $id) { + $rate = $this->GetRate($id, 'PRIMARY'); + if ($rate) { + $curr_object->Clear(); + $curr_object->Load($id, 'ISO'); + $curr_object->SetDBField('RateToPrimary', $rate); + $curr_object->SetDBField('Modified_date', adodb_mktime()); + $curr_object->SetDBField('Modified_time', adodb_mktime()); + $curr_object->Update(); + } + } + } +} Property changes on: releases/5.2.2-B2/units/helpers/currency_rates.php ___________________________________________________________________ Added: svn:keywords + Id Added: svn:eol-style + LF Index: releases/5.2.2-B2/units/files/files_event_handler.php =================================================================== --- releases/5.2.2-B2/units/files/files_event_handler.php (revision 0) +++ releases/5.2.2-B2/units/files/files_event_handler.php (revision 16630) @@ -0,0 +1,188 @@ +Special == 'downl' ) { + return ''; + } + + return parent::getMainSpecial($event); + } + + /** + * Apply any custom changes to list's sql query + * + * @param kEvent $event + * @return void + * @access protected + * @see kDBEventHandler::OnListBuild() + */ + protected function SetCustomQuery(kEvent $event) + { + parent::SetCustomQuery($event); + + /** @var kDBList $object */ + $object = $event->getObject(); + + switch ($event->Special) { + case 'downl': + $object->addFilter('is_active', '%1$s.Status = 1'); + break; + } + } + + /** + * Occurs before updating item + * + * @param kEvent $event + * @return void + * @access protected + */ + protected function OnBeforeItemUpdate(kEvent $event) + { + parent::OnBeforeItemUpdate($event); + + $this->itemChanged($event); + } + + /** + * Occurs before creating item + * + * @param kEvent $event + * @return void + * @access protected + */ + protected function OnBeforeItemCreate(kEvent $event) + { + parent::OnBeforeItemCreate($event); + + $this->itemChanged($event); + + /** @var kDBItem $object */ + $object = $event->getObject(); + + $parent_info = $object->getLinkedInfo($event->Special); + + $sql = 'SELECT FileId + FROM ' . $object->TableName . ' + WHERE IsPrimary = 1 AND ' . $parent_info['ForeignKey'] . ' = ' . $parent_info['ParentId']; + $file_id = $this->Conn->GetOne($sql); + + if ( !$file_id ) { + $object->SetDBField('IsPrimary', 1); + $object->SetDBField('Status', 1); + } + + $object->SetDBField('AddedById', $this->Application->RecallVar('user_id')); + } + + /** + * Occurs before item is changed + * + * @param kEvent $event + */ + function itemChanged($event) + { + /** @var kDBItem $object */ + $object = $event->getObject(); + + if ( $object->GetDBField('IsPrimary') ) { + $parent_info = $object->getLinkedInfo($event->Special); + + $sql = 'UPDATE ' . $object->TableName . ' + SET IsPrimary = 0 + WHERE ' . $parent_info['ForeignKey'] . ' = ' . $parent_info['ParentId']; + $this->Conn->Query($sql); + + $object->SetDBField('Status', 1); + } + + if ( $object->GetDBField('Name') == '' ) { + $object->SetDBField('Name', $object->GetDBField('FilePath')); + } + } + + /** + * Enter description here... + * + * @param kEvent $event + */ + function OnSetPrimary($event) + { + $ids = $this->StoreSelectedIDs($event); + $id = array_shift($ids); + + /** @var kDBItem $object */ + $object = $event->getObject( Array('skip_autoload' => true) ); + + $object->Load($id); + + $object->SetDBField('IsPrimary', 1); + $object->Update(); + } + + /** + * Don't allow to delete primary product file, when there are no more files + * + * @param kEvent $event + * @param string $type + * @return void + * @access protected + */ + protected function customProcessing(kEvent $event, $type) + { + if ( $event->Name == 'OnMassDelete' && $type == 'before' ) { + $ids = $event->getEventParam('ids'); + + /** @var kDBItem $object */ + $object = $event->getObject(); + + $parent_info = $object->getLinkedInfo($event->Special); + + $sql = 'SELECT FileId + FROM ' . $object->TableName . ' + WHERE IsPrimary = 1 AND ' . $parent_info['ForeignKey'] . ' = ' . $parent_info['ParentId']; + $primary_file_id = $this->Conn->GetOne($sql); + + if ( $primary_file_id ) { + $file_id_index = array_search($primary_file_id, $ids); + + if ( $file_id_index ) { + // allow deleting of primary product file, when there is another file to make primary + $sql = 'SELECT COUNT(*) + FROM ' . $object->TableName . ' + WHERE IsPrimary = 0 AND ' . $parent_info['ForeignKey'] . ' = ' . $parent_info['ParentId']; + $non_primary_file_count = $this->Conn->GetOne($sql); + + if ( $non_primary_file_count ) { + unset($ids[$file_id_index]); + } + } + } + + $event->setEventParam('ids', $ids); + } + } +} \ No newline at end of file Property changes on: releases/5.2.2-B2/units/files/files_event_handler.php ___________________________________________________________________ Added: cvs2svn:cvs-rev + 1.9 Added: svn:keywords + Id Added: svn:eol-style + LF Index: releases/5.2.2-B2/units/files/files.php =================================================================== --- releases/5.2.2-B2/units/files/files.php (revision 0) +++ releases/5.2.2-B2/units/files/files.php (revision 16630) @@ -0,0 +1,37 @@ +Load($id); + $upload_dir = $this->Fields['FilePath']['upload_dir']; + $file_path = FULL_PATH . $upload_dir . $this->GetDBField('FilePath'); + + if ( file_exists($file_path) ) { + unlink($file_path); + } + + return parent::Delete($id); + } +} \ No newline at end of file Property changes on: releases/5.2.2-B2/units/files/files.php ___________________________________________________________________ Added: cvs2svn:cvs-rev + 1.2 Added: svn:keywords + Id Added: svn:eol-style + LF Index: releases/5.2.2-B2/units/files/files_config.php =================================================================== --- releases/5.2.2-B2/units/files/files_config.php (revision 0) +++ releases/5.2.2-B2/units/files/files_config.php (revision 16630) @@ -0,0 +1,141 @@ + 'file', + 'ItemClass' => Array ('class' => 'FilesItem', 'file' => 'files.php', 'build_event' => 'OnItemBuild'), + 'ListClass' => Array ('class' => 'kDBList', 'file' => '', 'build_event' => 'OnListBuild'), + 'EventHandlerClass' => Array ('class' => 'FilesEventHandler', 'file' => 'files_event_handler.php', 'build_event' => 'OnBuild'), + 'TagProcessorClass' => Array ('class' => 'kDBTagProcessor', 'file' => '', 'build_event' => 'OnBuild'), + + 'AutoLoad' => true, + + 'AggregateTags' => Array ( + Array ( + 'AggregateTo' => '#PARENT#', + 'AggregatedTagName' => 'ListFiles', + 'LocalTagName' => 'PrintList', + 'LocalSpecial' => 'downl', + ), + ), + + /*'Hooks' => Array ( + Array ( + 'Mode' => hBEFORE, + 'Conditional' => true, + 'HookToPrefix' => 'p', + 'HookToSpecial' => '', + 'HookToEvent' => Array ( 'onPreSave' ), + 'DoPrefix' => 'pr', + 'DoSpecial' => 'tang', + 'DoEvent' => 'OnArrange', + ), + ),*/ + + 'QueryString' => Array ( + 1 => 'id', + 2 => 'Page', + 3 => 'PerPage', + 4 => 'event', + ), + + 'StatusField' => Array ('Status', 'IsPrimary'), + 'IDField' => 'FileId', + 'TitleField' => 'Name', + 'TableName' => TABLE_PREFIX.'ProductFiles', + 'ForeignKey' => 'ProductId', + 'ParentTableKey' => 'ProductId', + 'ParentPrefix' => 'p', + 'AutoDelete' => true, + 'AutoClone' => true, + + 'ListSQLs' => Array ( + '' => ' SELECT * + FROM %s' + ), + + 'ListSortings' => Array ( + '' => Array ( + 'ForcedSorting' => Array ('IsPrimary' => 'desc', 'Priority' => 'desc'), + 'Sorting' => Array ('AddedOn' => 'desc', 'Version' => 'desc'), + ) + ), + + 'Fields' => Array ( + 'FileId' => Array ('type' => 'int', 'not_null' => 1, 'default' => 0,), + 'ProductId' => Array ('type' => 'int', 'not_null' => 1, 'default' => 0,), + 'Name' => Array ('type' => 'string', 'not_null' => '1', 'default' => ''), + 'Version' => Array ('type' => 'string', 'not_null' => '1', 'default' => ''), + 'FilePath' => Array ('type' => 'string', 'not_null' => '1', 'default' => ''), + 'RealPath' => Array ( + 'type' => 'string', + 'formatter' => 'kUploadFormatter', + 'upload_dir' => ITEM_FILES_PATH, 'include_path' => 0, + 'size_field' => 'Size', 'max_size' => 50000000, + 'orig_name_field' => 'FilePath', + 'content_type_field' => 'MIMEType', + 'not_null' => 1, 'skip_empty' =>1, 'default' => '', + 'required' => 1, + 'error_msgs' => Array ( + 'bad_file_format' => '!la_error_InvalidFileFormat!', + 'bad_file_size' => '!la_error_FileTooLarge!', + 'cant_save_file' => '!la_error_cant_save_file!', + ), + ), + 'Size' => Array ( + 'type' => 'int', + 'formatter' => 'kFilesizeFormatter', + 'not_null' => 1, 'default' => 0, + ), + 'Status' => Array ( + 'type' => 'int', + 'formatter' => 'kOptionsFormatter', + 'options' => Array ( 0 => 'la_Disabled', 1 => 'la_Active', ), 'use_phrases' => 1, + 'not_null' => 1, 'default' => 0, + ), + 'IsPrimary' => Array ( + 'type' => 'int', + 'formatter' => 'kOptionsFormatter', + 'options' => Array ( 0 => 'la_No', 1 => 'la_Yes', ), 'use_phrases' => 1, + 'not_null' => 1, 'default' => 0, + ), + 'Priority' => Array ('type' => 'int', 'not_null' => 1, 'default' => 0), + 'AddedOn' => Array ('type' => 'int', 'formatter' => 'kDateFormatter', 'default' => '#NOW#'), + 'AddedById' => Array ('type' => 'int', 'default' => NULL), + 'MIMEType' => Array ('type' => 'string', 'not_null' => '1', 'default' => ''), + ), + + 'Grids' => Array ( + 'Default' => Array ( + 'Icons' => Array ( + 'default' => 'icon16_item.png', + '0_0' => 'icon16_disabled.png', + '0_1' => 'icon16_disabled.png', + '1_0' => 'icon16_item.png', + '1_1' => 'icon16_primary.png', + 'module' => 'core', + ), + 'Fields' => Array ( + 'FileId' => Array ( 'title' => 'column:la_fld_Id', 'data_block' => 'grid_checkbox_td', 'module' => 'In-Portal', 'filter_block' => 'grid_range_filter'), + 'Name' => Array ( 'title' => 'column:la_fld_FileName', 'data_block' => 'file_caption_td', 'filter_block' => 'grid_like_filter'), + 'FilePath' => Array ( 'filter_block' => 'grid_like_filter'), + 'Version' => Array ( 'filter_block' => 'grid_like_filter'), + 'Size' => Array ( 'title' => 'la_col_Size', 'filter_block' => 'grid_range_filter'), + 'AddedOn' => Array ( 'format' => '_regional_DateFormat', 'filter_block' => 'grid_date_range_filter'), + 'Status' => Array ( 'filter_block' => 'grid_options_filter'), + ), + ), + ), +); \ No newline at end of file Property changes on: releases/5.2.2-B2/units/files/files_config.php ___________________________________________________________________ Added: cvs2svn:cvs-rev + 1.12.2.3 Added: svn:keywords + Id Added: svn:eol-style + LF Index: releases/5.2.2-B2/units/affiliate_payments/affiliate_payments_config.php =================================================================== --- releases/5.2.2-B2/units/affiliate_payments/affiliate_payments_config.php (revision 0) +++ releases/5.2.2-B2/units/affiliate_payments/affiliate_payments_config.php (revision 16630) @@ -0,0 +1,151 @@ + 'apayments', + 'ItemClass' => Array ('class' => 'kDBItem', 'file' => '', 'build_event' => 'OnItemBuild'), + 'ListClass' => Array ('class' => 'kDBList', 'file' => '', 'build_event' => 'OnListBuild'), + 'EventHandlerClass' => Array ('class' => 'AffiliatePaymentsEventHandler', 'file' => 'affiliate_payments_event_handler.php', 'build_event' => 'OnBuild'), + 'TagProcessorClass' => Array ('class' => 'AffiliatePaymentsTagProcessor', 'file' => 'affiliate_payments_tag_processor.php', 'build_event' => 'OnBuild'), + 'AutoLoad' => true, + + 'AggregateTags' => Array ( + Array ( + 'AggregateTo' => 'ord', + 'AggregatedTagName' => 'InitPaymentsList', + 'LocalTagName' => 'InitList', + ), + Array ( + 'AggregateTo' => 'ord', + 'AggregatedTagName' => 'ListPayments', + 'LocalTagName' => 'ListPayments', + ), + Array ( + 'AggregateTo' => 'ord', + 'AggregatedTagName' => 'PaymentsPaginationBar', + 'LocalTagName' => 'PaginationBar', + ), + Array ( + 'AggregateTo' => 'ord', + 'AggregatedTagName' => 'PaymentsCount', + 'LocalTagName' => 'TotalRecords', + ), + ), + + 'QueryString' => Array ( + 1 => 'id', + 2 => 'Page', + 3 => 'PerPage', + 4 => 'event', + ), + + 'IDField' => 'AffiliatePaymentId', + + 'TitlePresets' => Array ( + 'payments_log' => Array ( + 'prefixes' => Array ('apayments.log_List'), 'format' => "!la_title_AffiliatePayments!", + ), + ), + + 'Sections' => Array ( + 'in-commerce:paymentlog' => Array ( + 'parent' => 'in-commerce', + 'icon' => 'transactions', + 'label' => 'la_tab_PaymentLog', + 'url' => Array ('t' => 'in-commerce/payments/payments_list', 'pass' => 'm'), + 'permissions' => Array ('view'), + 'priority' => 6, + 'type' => stTREE, + ), + ), + + 'TableName' => TABLE_PREFIX.'AffiliatePayments', + + 'ListSQLs' => Array ( + '' => ' SELECT %1$s.* %2$s + FROM %1$s + LEFT JOIN '.TABLE_PREFIX.'Affiliates af ON %1$s.AffiliateId = af.AffiliateId + LEFT JOIN '.TABLE_PREFIX.'Users au ON af.PortalUserId = au.PortalUserId' + ), + + 'CalculatedFields' => Array ( + '' => Array ( + 'PortalUserId' => 'af.PortalUserId', + ), + 'log' => Array ( + 'Username' => 'IF(au.Username = "", au.Email, au.Username)', + 'PortalUserId' => 'af.PortalUserId', + ), + ), + + 'ForeignKey' => 'AffiliateId', + 'ParentTableKey' => 'AffiliateId', + 'ParentPrefix' => 'affil', + 'AutoDelete' => true, + 'AutoClone' => true, + + 'ListSortings' => Array ( + '' => Array ( + 'Sorting' => Array ('PaymentDate' => 'desc'), + ) + ), + + 'Fields' => Array ( + 'AffiliatePaymentId' => Array ('type' => 'int', 'not_null' => 1, 'default' => 0), + 'AffiliateId' => Array ('type' => 'int', 'formatter' => 'kLEFTFormatter', 'error_msgs' => Array ('invalid_option' => '!la_error_UserNotFound!'), 'options' => Array (0 => 'lu_None'), 'left_sql' => 'SELECT %s FROM '.TABLE_PREFIX.'Affiliates af LEFT JOIN '.TABLE_PREFIX.'Users u ON u.PortalUserId = af.PortalUserId WHERE %s', 'left_key_field' => 'af.AffiliateId', 'left_title_field' => 'IF(u.Email = "", u.Username, u.Email)', 'not_null'=>1,'default'=>0), + 'PaymentDate' => Array ('type' => 'int', 'formatter' => 'kDateFormatter', 'default' => '#NOW#'), + 'Amount' => Array ('type' => 'double', 'formatter' => 'kFormatter', 'format' => '%.02f', 'not_null' => '1', 'required'=>1, 'default' => '0.00'), + 'Comment' => Array ('type' => 'string', 'default' => NULL), + 'PaymentReference' => Array ('type' => 'string', 'not_null' => '1', 'default' => ''), + 'PaymentTypeId' => Array ('type' => 'int', 'formatter' => 'kOptionsFormatter', 'options_sql' => 'SELECT Name, PaymentTypeId FROM '.TABLE_PREFIX.'AffiliatePaymentTypes WHERE Status = 1 ORDER BY IsPrimary DESC, Priority DESC, Name ASC', 'option_key_field' => 'PaymentTypeId', 'option_title_field' => 'Name', 'not_null' => 1, 'default' => 0), + ), + + 'VirtualFields' => Array ( + 'Username' => Array ('type' => 'string', 'default' => ''), + 'PortalUserId' => Array ('type' => 'int', 'default' => 0), + ), + + 'Grids' => Array ( + 'Default' => Array ( + 'Icons' => Array ( + 'default' => 'icon16_item.png', + 'module' => 'core', + ), + 'Fields' => Array ( + 'AffiliatePaymentId'=> Array ( 'title' => 'column:la_fld_Id', 'data_block' => 'grid_checkbox_td', 'filter_block' => 'grid_range_filter', 'width' => 60, ), + 'PaymentDate' => Array ( 'filter_block' => 'grid_date_range_filter', 'width' => 140, ), + 'Amount' => Array ( 'filter_block' => 'grid_range_filter'), + 'Comment' => Array ( 'filter_block' => 'grid_like_filter', 'first_chars' => 50), + 'PaymentTypeId' => Array ( 'title' => 'column:la_fld_PaymentType', 'filter_block' => 'grid_options_filter'), + 'PaymentReference' => Array ( 'filter_block' => 'grid_like_filter', 'first_chars' => 50), + ), + ), + 'Log' => Array ( + 'Icons' => Array ( + 'default' => 'icon16_item.png', + 'module' => 'core', + ), + 'Fields' => Array ( + 'AffiliatePaymentId'=> Array ( 'title' => 'column:la_fld_Id', 'data_block' => 'grid_checkbox_td', 'filter_block' => 'grid_range_filter', 'width' => 60, ), + 'Username' => Array ( 'data_block' => 'grid_userlink_td', 'filter_block' => 'grid_like_filter'), + 'PaymentDate' => Array ( 'filter_block' => 'grid_date_range_filter', 'width' => 140, ), + 'Amount' => Array ( 'data_block' => 'grid_currency_td', 'filter_block' => 'grid_range_filter'), + 'Comment' => Array ( 'filter_block' => 'grid_like_filter', 'first_chars' => 50), + 'PaymentTypeId' => Array ( 'title' => 'column:la_fld_PaymentType', 'filter_block' => 'grid_options_filter'), + 'PaymentReference' => Array ( 'filter_block' => 'grid_like_filter', 'first_chars' => 50), + ), + ), + ), +); Property changes on: releases/5.2.2-B2/units/affiliate_payments/affiliate_payments_config.php ___________________________________________________________________ Added: cvs2svn:cvs-rev + 1.17.2.2 Added: svn:keywords + Id Added: svn:eol-style + LF Index: releases/5.2.2-B2/units/affiliate_payments/affiliate_payments_tag_processor.php =================================================================== --- releases/5.2.2-B2/units/affiliate_payments/affiliate_payments_tag_processor.php (revision 0) +++ releases/5.2.2-B2/units/affiliate_payments/affiliate_payments_tag_processor.php (revision 16630) @@ -0,0 +1,65 @@ +getObject($params); + $user_id = $object->GetDBField('PortalUserId'); + + if (!$user_id) { + return ''; + } + + $url_params = Array ( + 'm_opener' => 'd', + 'u_mode' => 't', + 'u_event' => 'OnEdit', + 'u_id' => $user_id, + 'pass' => 'all,u' + ); + + return $this->Application->HREF($params['edit_template'], '', $url_params); + } + + function ListPayments($params) + { + $o = ''; + $params['render_as'] = $params['item_render_as']; + $o_payments = $this->PrintList($params); + + if ($o_payments) + { + $payments_params = Array('name' => $params['header_render_as']); + $o = $this->Application->ParseBlock($payments_params); + $o .= $o_payments; + } + else + { + $payments_params = array('name' => $params['empty_mypayments_render_as']); + $o = $this->Application->ParseBlock($payments_params); + } + + return $o; + } + + } \ No newline at end of file Property changes on: releases/5.2.2-B2/units/affiliate_payments/affiliate_payments_tag_processor.php ___________________________________________________________________ Added: cvs2svn:cvs-rev + 1.1.32.1 Added: svn:keywords + Id Added: svn:eol-style + LF Index: releases/5.2.2-B2/units/affiliate_payments/affiliate_payments_event_handler.php =================================================================== --- releases/5.2.2-B2/units/affiliate_payments/affiliate_payments_event_handler.php (revision 0) +++ releases/5.2.2-B2/units/affiliate_payments/affiliate_payments_event_handler.php (revision 16630) @@ -0,0 +1,138 @@ +Special == 'log' ) { + return ; + } + + $parent_info = $object->getLinkedInfo(); + + /** @var kDBItem $parent_object */ + $parent_object = $this->Application->recallObject($parent_info['ParentPrefix']); + + $options = $object->GetFieldOptions('PaymentTypeId'); + + if ( $parent_object->isLoaded() ) { + $options['default'] = $parent_object->GetDBField('PaymentTypeId'); + $object->SetDBField('PaymentTypeId', $parent_object->GetDBField('PaymentTypeId')); + } + + if ( $this->Application->GetVar($event->getPrefixSpecial() . '_event') != 'OnNew' && $this->Application->GetVar($event->getPrefixSpecial() . '_event') != 'OnCreate' ) { + $options['options'][0] = ''; + } + + $object->setFieldOptions('PaymentTypeId', $options); + } + + /** + * Set's fields based on affiliate currently being edited + * + * @param kEvent $event + * @return void + * @access protected + */ + protected function OnNew(kEvent $event) + { + parent::OnNew($event); + + /** @var kDBItem $affiliate */ + $affiliate = $this->Application->recallObject('affil'); + + /** @var kDBItem $object */ + $object = $event->getObject(Array ('skip_autoload' => true)); + + $object->SetDBField('Amount', $affiliate->GetDBField('AmountToPay')); + $object->SetDBField('AffiliateId', $affiliate->GetID()); + } + + /** + * Updates Affiliate Record On Successfully payment creation + * + * @param kEvent $event + * @return void + * @access protected + */ + protected function OnAfterItemCreate(kEvent $event) + { + parent::OnAfterItemCreate($event); + + /** @var kDBItem $object */ + $object = $event->getObject(); + + $parent_info = $object->getLinkedInfo(); + + $sql = 'SELECT MAX(PaymentDate) + FROM ' . $object->TableName . ' + WHERE ' . $parent_info['ParentTableKey'] . ' = ' . $parent_info['ParentId']; + $payment_date = $this->Conn->GetOne($sql); + + /** @var kDBItem $affiliate */ + $affiliate = $this->Application->recallObject('affil'); + + $affiliate->SetDBField('AmountToPay', $affiliate->GetDBField('AmountToPay') - $object->GetDBField('Amount')); + $affiliate->SetDBField('LastPaymentDate_date', $payment_date); + $affiliate->SetDBField('LastPaymentDate_time', $payment_date); + $affiliate->Update(); + } + + /** + * Apply any custom changes to list's sql query + * + * @param kEvent $event + * @return void + * @access protected + * @see kDBEventHandler::OnListBuild() + */ + protected function SetCustomQuery(kEvent $event) + { + parent::SetCustomQuery($event); + + /** @var kDBList $object */ + $object = $event->getObject(); + + if ( $event->Special == 'log' ) { + $object->removeFilter('parent_filter'); + } + + $types = $event->getEventParam('types'); + if ( $types == 'my_payments' ) { + $user_id = $this->Application->RecallVar('user_id'); + $object->removeFilter('parent_filter'); + $object->addFilter('my_payments', 'au.PortalUserId = ' . $user_id); + } + + if ( $types == 'myvisitororders' ) { + $user_id = $this->Application->RecallVar('user_id'); + $object->addFilter('myitems_orders', 'ord.OrderId IS NOT NULL'); + $object->addFilter('myitems_user1', 'au.PortalUserId = ' . $user_id); + $object->addFilter('myitems_user2', 'au.PortalUserId > 0'); + } + } + + } \ No newline at end of file Property changes on: releases/5.2.2-B2/units/affiliate_payments/affiliate_payments_event_handler.php ___________________________________________________________________ Added: cvs2svn:cvs-rev + 1.10 Added: svn:keywords + Id Added: svn:eol-style + LF Index: releases/5.2.2-B2/units/destinations/destinations_config.php =================================================================== --- releases/5.2.2-B2/units/destinations/destinations_config.php (revision 0) +++ releases/5.2.2-B2/units/destinations/destinations_config.php (revision 16630) @@ -0,0 +1,64 @@ + 'dst', + 'ItemClass' => Array ('class' => 'kDBItem', 'file' => 'images.php', 'build_event' => 'OnItemBuild'), + 'ListClass' => Array ('class' => 'kDBList', 'file' => '', 'build_event' => 'OnListBuild'), + 'EventHandlerClass' => Array ('class' => 'DstEventHandler', 'file' => 'dst_event_handler.php', 'build_event' => 'OnBuild'), + 'TagProcessorClass' => Array ('class' => 'kDBTagProcessor', 'file' => '', 'build_event' => 'OnBuild'), + + 'AutoLoad' => true, + + 'Hooks' => Array ( + Array ( + 'Mode' => hAFTER, + 'Conditional' => false, + 'HookToPrefix' => '#PARENT#', + 'HookToSpecial' => '', + 'HookToEvent' => Array ( 'OnCreate', 'OnUpdate'), + 'DoPrefix' => '', + 'DoSpecial' => '', + 'DoEvent' => 'OnZoneUpdate', + ), + ), + + 'QueryString' => Array ( + 1 => 'id', + 2 => 'Page', + 3 => 'PerPage', + 4 => 'event', + ), + + 'IDField' => 'ZoneDestId', + 'TableName' => TABLE_PREFIX.'ShippingZonesDestinations', + 'ForeignKey' => 'ShippingZoneId', + 'ParentTableKey' => 'ZoneID', + 'ParentPrefix' => 'z', + 'AutoDelete' => true, + 'AutoClone' => true, + + 'ListSQLs' => Array ( + '' => ' SELECT * + FROM %s', + ), + + 'Fields' => Array ( + 'ZoneDestId' => Array ('type' => 'int', 'not_null' => 1, 'default' => 0, ), + 'ShippingZoneId' => Array ('type' => 'int', 'not_null' => 1, 'default' => 0, ), + 'StdDestId' => Array ('type' => 'int', 'default' => 0, ), + 'DestValue' => Array ('type' => 'string', 'max_len' => 255, 'default' => null, ), + ), +); \ No newline at end of file Property changes on: releases/5.2.2-B2/units/destinations/destinations_config.php ___________________________________________________________________ Added: cvs2svn:cvs-rev + 1.8 Added: svn:keywords + Id Added: svn:eol-style + LF Index: releases/5.2.2-B2/units/destinations/dst_event_handler.php =================================================================== --- releases/5.2.2-B2/units/destinations/dst_event_handler.php (revision 0) +++ releases/5.2.2-B2/units/destinations/dst_event_handler.php (revision 16630) @@ -0,0 +1,136 @@ +getObject(Array ('skip_autoload' => true)); + + // creates multiple db records from single request (OnCreate event only creates 1 record) + $items_info = $this->Application->GetVar($event->getPrefixSpecial(true)); + + if ( !$items_info ) { + return; + } + + foreach ($items_info as $field_values) { + $object->setID(0); + $object->SetFieldsFromHash($field_values); + $event->setEventParam('form_data', $field_values); + $this->customProcessing($event, 'before'); + + if ( $object->Create() ) { + $this->customProcessing($event, 'after'); + $event->status = kEvent::erSUCCESS; + } + else { + $event->status = kEvent::erFAIL; + $event->redirect = false; + $this->Application->SetVar($event->getPrefixSpecial() . '_SaveEvent', 'OnCreate'); + $object->setID(0); + } + } + } + + /** + * Apply custom processing to item + * + * @param kEvent $event + * @param string $type + * @return void + * @access protected + */ + protected function customProcessing(kEvent $event, $type) + { + if ( $type != 'before' ) { + return; + } + + /** @var kDBItem $object */ + $object = $event->getObject(); + + $events = $this->Application->GetVar('events'); + + if ( $events['z'] == 'OnUpdate' ) { + $object->SetDBField('ShippingZoneId', $this->Application->GetVar('z_id')); + } + + /** @var kDBItem $zone_object */ + $zone_object = $this->Application->recallObject('z'); + + if ( $zone_object->GetDBField('Type') == 3 ) { + $object->SetDBField('StdDestId', $this->Application->GetVar('ZIPCountry')); + } + } + + /** + * + * + * @param kEvent $event + */ + function OnZoneUpdate($event) { + + /** @var kDBItem $object */ + $object = $event->getObject(); + + /** @var kDBItem $zone_object */ + $zone_object = $this->Application->recallObject('z'); + + $zone_id = (int)$zone_object->GetID(); + $zone_type = $zone_object->GetDBField('Type'); + + $delete_zones_sql = 'DELETE FROM '.$object->TableName.' WHERE ShippingZoneId = '.$zone_id; + $this->Conn->Query($delete_zones_sql); + + if ($zone_id != 0){ + $delete_zones_sql = 'DELETE FROM '.$object->TableName.' WHERE ShippingZoneId = 0'; + $this->Conn->Query($delete_zones_sql); + } + + $selected_destinations = $this->Application->GetVar('selected_destinations'); + $selected_destinations_array = explode(',', $selected_destinations); + $selected_destinations_array = array_unique($selected_destinations_array); + foreach ($selected_destinations_array as $key => $dest_id) { + + if ($zone_object->GetDBField('Type') == 3){ + list ($zone_dest_id, $dest_value) = explode('|', $dest_id); + $dest_id = $this->Application->GetVar('CountrySelector'); + } + else { + $dest_value = ''; + } + + if ($dest_id > 0){ + $object->SetDBField('ShippingZoneId', $zone_id); + $object->SetDBField('StdDestId', $dest_id); + $object->SetDBField('DestValue', $dest_value); + $object->Create(); + } + + } + + + } + +} Property changes on: releases/5.2.2-B2/units/destinations/dst_event_handler.php ___________________________________________________________________ Added: cvs2svn:cvs-rev + 1.9 Added: svn:keywords + Id Added: svn:eol-style + LF Index: releases/5.2.2-B2/units/affiliate_payment_types/affiliate_payment_types_config.php =================================================================== --- releases/5.2.2-B2/units/affiliate_payment_types/affiliate_payment_types_config.php (revision 0) +++ releases/5.2.2-B2/units/affiliate_payment_types/affiliate_payment_types_config.php (revision 16630) @@ -0,0 +1,115 @@ + 'apt', + 'ItemClass' => Array ('class' => 'kDBItem', 'file' => '', 'build_event' => 'OnItemBuild'), + 'ListClass' => Array ('class' => 'kDBList', 'file' => '', 'build_event' => 'OnListBuild'), + 'EventHandlerClass' => Array ('class' => 'AffiliatePaymentTypesEventHandler', 'file' => 'affiliate_payment_types_event_handler.php', 'build_event' => 'OnBuild'), + 'TagProcessorClass' => Array ('class' => 'AffiliatePaymentTypeTagProcessor', 'file' => 'affiliate_payment_types_tp.php', 'build_event' => 'OnBuild'), + + 'AutoLoad' => true, + + 'QueryString' => Array ( + 1 => 'id', + 2 => 'Page', + 3 => 'PerPage', + 4 => 'event', + 5 => 'mode', + ), + + 'IDField' => 'PaymentTypeId', + 'StatusField' => Array ('Status', 'IsPrimary'), // field, that is affected by Approve/Decline events + + 'TitleField' => 'Name', + 'TitlePresets' => Array ( + 'default' => Array ( + 'new_status_labels' => Array ('apt' => '!la_title_Adding_Affiliate_Payment_Type!'), + 'edit_status_labels' => Array ('apt' => '!la_title_Editing_Affiliate_Payment_Type!'), + 'new_titlefield' => Array ('apt' => '!la_title_New_Affiliate_Payment_Type!'), + ), + + 'affiliate_payment_types_list' => Array ('prefixes' => Array ('apt_List'), 'format' => "!la_title_AffiliatePaymentTypes!"), + 'affiliate_payment_types_edit' => Array ('prefixes' => Array ('apt'), 'format' => "#apt_status# '#apt_titlefield#' - !la_title_General!"), + ), + + 'PermSection' => Array ('main' => 'in-commerce:affiliate_payment_types'), + + 'Sections' => Array ( + 'in-commerce:affiliate_payment_types' => Array ( + 'parent' => 'in-commerce:affiliates_folder', + 'icon' => 'affiliates', + 'label' => 'la_tab_AffiliatePaymentTypes', + 'url' => Array ('t' => 'in-commerce/affiliate_plans/affiliate_payment_types_list', 'pass' => 'm'), + 'permissions' => Array ( + 'view', 'add', 'edit', 'delete', 'advanced:approve', + 'advanced:decline', 'advanced:set_primary', 'advanced:move_up', 'advanced:move_down' + ), + 'priority' => 5.3, // ., because this section replaces parent in tree + 'type' => stTAB, + ), + ), + + 'TableName' => TABLE_PREFIX.'AffiliatePaymentTypes', + + 'ListSQLs' => Array ( + '' => ' SELECT * + FROM %s' + ), + + 'ListSortings' => Array ( + '' => Array ( + 'ForcedSorting' => Array ('IsPrimary' => 'desc', 'Priority' => 'desc'), + 'Sorting' => Array ('Name' => 'asc'), + ) + ), + + 'Fields' => Array ( + 'PaymentTypeId' => Array ('type' => 'int', 'not_null' => 1, 'default' => 0), + 'Name' => Array ('type' => 'string', 'not_null' => 1, 'required' => 1, 'default' => ''), + 'Description' => Array ('type' => 'string', 'formatter' => 'kFormatter', 'using_fck' => 1, 'default' => NULL), + 'Status' => Array ( + 'type' => 'int', + 'formatter' => 'kOptionsFormatter', + 'options' => Array ( 0 => 'la_Disabled', 1 => 'la_Active', ), 'use_phrases' => 1, + 'not_null' => 1, 'default' => 0, + ), + 'IsPrimary' => Array ( + 'type' => 'int', + 'formatter' => 'kOptionsFormatter', + 'options' => Array ( 0 => 'la_No', 1 => 'la_Yes', ), 'use_phrases' => 1, + 'not_null' => 1, 'default' => 0, + ), + 'Priority' => Array ('type' => 'int', 'not_null' => 1, 'default' => 0), + ), + + 'Grids' => Array ( + 'Default' => Array ( + 'Icons' => Array ( + 'default' => 'icon16_item.png', + '0_0' => 'icon16_disabled.png', + '0_1' => 'icon16_disabled.png', + '1_0' => 'icon16_item.png', + '1_1' => 'icon16_primary.png', + 'module' => 'core', + ), + 'Fields' => Array ( + 'PaymentTypeId' => Array ( 'title' => 'column:la_fld_Id', 'data_block' => 'grid_checkbox_td', 'filter_block' => 'grid_range_filter', 'width' => 60, ), + 'Name' => Array ( 'data_block' => 'affiliate_payment_type_caption_td', 'filter_block' => 'grid_like_filter', 'width' => 200, ), + 'Description' => Array ( 'filter_block' => 'grid_like_filter', 'width' => 200, ), + ), + ), + ), +); \ No newline at end of file Property changes on: releases/5.2.2-B2/units/affiliate_payment_types/affiliate_payment_types_config.php ___________________________________________________________________ Added: cvs2svn:cvs-rev + 1.7.2.1 Added: svn:keywords + Id Added: svn:eol-style + LF Index: releases/5.2.2-B2/units/affiliate_payment_types/affiliate_payment_types_event_handler.php =================================================================== --- releases/5.2.2-B2/units/affiliate_payment_types/affiliate_payment_types_event_handler.php (revision 0) +++ releases/5.2.2-B2/units/affiliate_payment_types/affiliate_payment_types_event_handler.php (revision 16630) @@ -0,0 +1,123 @@ +Application->isAdmin ) { + /** @var kDBList $object */ + $object = $event->getObject(); + + $object->addFilter('active', '%1$s.Status = ' . STATUS_ACTIVE); + } + } + + /** + * Enter description here... + * + * @param kEvent $event + */ + function OnSetPrimary($event) + { + /** @var kDBItem $object */ + $object = $event->getObject(); + + $object->SetDBField('IsPrimary', 1); + $object->Update(); + } + + + /** + * Ensures, that user have only one "use as billing" / "use as shipping" address + * + * @param kEvent $event + * @return void + * @access protected + */ + protected function OnBeforeItemUpdate(kEvent $event) + { + parent::OnBeforeItemUpdate($event); + + $this->itemChanged($event); + } + + /** + * Occurs before creating item + * + * @param kEvent $event + * @return void + * @access protected + */ + protected function OnBeforeItemCreate(kEvent $event) + { + parent::OnBeforeItemCreate($event); + + $this->itemChanged($event); + } + + /** + * Occurs before item is changed + * + * @param kEvent $event + */ + function itemChanged($event) + { + /** @var kDBItem $object */ + $object = $event->getObject(); + + if ( $object->GetDBField('IsPrimary') && $object->Validate() ) { + $sql = 'UPDATE ' . $this->Application->getUnitOption($event->Prefix, 'TableName') . ' + SET IsPrimary = 0'; + $this->Conn->Query($sql); + + $object->SetDBField($object->getStatusField(), 1); + } + } + + /** + * Don't allow to delete primary affiliate payment type + * + * @param kEvent $event + * @param string $type + * @return void + * @access protected + */ + protected function customProcessing(kEvent $event, $type) + { + if ( $event->Name == 'OnMassDelete' && $type == 'before' ) { + $ids = $event->getEventParam('ids'); + + $sql = 'SELECT ' . $this->Application->getUnitOption($event->Prefix, 'IDField') . ' + FROM ' . $this->Application->getUnitOption($event->Prefix, 'TableName') . ' + WHERE IsPrimary = 1'; + $primary_id = $this->Conn->GetOne($sql); + + $ids = array_diff($ids, Array ($primary_id)); + + $event->setEventParam('ids', $ids); + } + } + } \ No newline at end of file Property changes on: releases/5.2.2-B2/units/affiliate_payment_types/affiliate_payment_types_event_handler.php ___________________________________________________________________ Added: cvs2svn:cvs-rev + 1.7 Added: svn:keywords + Id Added: svn:eol-style + LF Index: releases/5.2.2-B2/units/affiliate_payment_types/affiliate_payment_types_tp.php =================================================================== --- releases/5.2.2-B2/units/affiliate_payment_types/affiliate_payment_types_tp.php (revision 0) +++ releases/5.2.2-B2/units/affiliate_payment_types/affiliate_payment_types_tp.php (revision 16630) @@ -0,0 +1,51 @@ +Application->recallObject( $params['prefix'] ); + + $payment_type = $affiliate->GetDBField( $params['field'] ); + + if ( $payment_type ) { + /** @var kDBList $object */ + $object = $this->getObject($params); + + return $payment_type == $object->GetID(); + } + + if ( !$checked ) { + // make first listed affiliate payment type selected + $checked = true; + + return true; + } + + return false; + } +} \ No newline at end of file Property changes on: releases/5.2.2-B2/units/affiliate_payment_types/affiliate_payment_types_tp.php ___________________________________________________________________ Added: svn:keywords + Id Added: svn:eol-style + LF Index: releases/5.2.2-B2/units/shipping_quote_engines/usps.php =================================================================== --- releases/5.2.2-B2/units/shipping_quote_engines/usps.php (revision 0) +++ releases/5.2.2-B2/units/shipping_quote_engines/usps.php (revision 16630) @@ -0,0 +1,1341 @@ +HERE for registration details. USPS expects you to use pounds as weight measure for your products.'); +define('MODULE_SHIPPING_USPS_TEXT_ERROR', 'An error occured with the USPS shipping calculations.
If you prefer to use USPS as your shipping method, please contact the store owner.'); +define('MODULE_SHIPPING_USPS_TEXT_DAY', 'Day'); +define('MODULE_SHIPPING_USPS_TEXT_DAYS', 'Days'); +define('MODULE_SHIPPING_USPS_TEXT_WEEKS', 'Weeks'); + +define('MODULE_SHIPPING_USPS_STATUS', 'True'); // Do you want to offer USPS shipping? +define('MODULE_SHIPPING_USPS_SERVER', 'production'); // An account at USPS is needed to use the Production server // production othervise value may be 'test' +define('MODULE_SHIPPING_USPS_HANDLING', '0'); // Handling fee for this shipping method +define('MODULE_SHIPPING_USPS_TAX_CLASS', '0'); // Use the following tax class on the shipping fee +define('MODULE_SHIPPING_USPS_ZONE', '0'); // If a zone is selected, only enable this shipping method for that zone. +define('MODULE_SHIPPING_USPS_SORT_ORDER', '0'); // Sort order of display. +define('MODULE_SHIPPING_USPS_TYPES', 'PRIORITY, PARCEL'); // EXPRESS, FIRST CLASS, BMP, MEDIA 'Select the domestic services to be offered: +define('MODULE_SHIPPING_USPS_TYPES_INTL', 'EXPRESS MAIL INTERNATIONAL (EMS), EXPRESS MAIL INT, EXPRESS MAIL INT FLAT RATE ENV, PRIORITY MAIL INT, PRIORITY MAIL INT FLAT RATE ENV, PRIORITY MAILINT FLAT RATE BOX, FIRST-CLASS MAIL INT');// 'GLOBAL EXPRESS, GLOBAL EXPRESS NON-DOC RECT, GLOBAL EXPRESS NON-DOC NON-RECT, Select the international services to be offered: +define('MODULE_SHIPPING_USPS_OPTIONS', 'Display weight, Display transit time'); // + +//configuration values for insurance +define('MODULE_SHIPPING_USPS_INS1', '1.65');// 'US/Canada insurance for totals $.01-$50.00 +define('MODULE_SHIPPING_USPS_INS2', '2.05');// 'US/Canada insurance for totals $50.01-$100 +define('MODULE_SHIPPING_USPS_INS3', '2.45');// 'US/Canada insurance for totals $100.01-$200 +define('MODULE_SHIPPING_USPS_INS4', '4.60');// 'US/Canada insurance for totals $200.01-$300 +define('MODULE_SHIPPING_USPS_INS5', '.90');// 'US/Canada insurance for every $100 over $300 (add) +define('MODULE_SHIPPING_USPS_INS6', '2.40');// 'International insurance for totals $.01-$50.00 +define('MODULE_SHIPPING_USPS_INS7', '3.30');// 'International insurance for totals $50.01-$100 +define('MODULE_SHIPPING_USPS_INS8', '4.20');// 'International insurance for totals $100.01-$200 +define('MODULE_SHIPPING_USPS_INS9', '5.10');// 'International insurance for totals $200.01-$300 +define('MODULE_SHIPPING_USPS_INS10', '.90');// 'International insurance for every $100 over $300 (add) +define('MODULE_SHIPPING_USPS_INSURE', 'True');// 'Insure packages shipped by USPS? +define('MODULE_SHIPPING_USPS_INSURE_TAX', 'True');// 'Insure tax on packages shipped by USPS? + +class USPS extends ShippingQuoteEngine +{ + var $countries, $pounds, $ounces, $insurance_cost = 0, $shipping_origin_country, $store_first_name, $store_last_name, $company_name, $store_name, $store_address1, $store_address2, $store_city, $store_state, $store_zip5, $store_zip4, $store_phone, $usps_userid; + var $order = Array(); + var $types = Array(); + var $intl_types = Array(); + + /** + * Path to a request log file + * + * @var string + */ + var $logFilePath = ''; + + /** + * Creates USPS processing class + * + */ + public function __construct() + { + parent::__construct(); + + $this->logFilePath = (defined('RESTRICTED') ? RESTRICTED : WRITEABLE . '/user_files') . '/usps.log'; + + // EXPRESS, FIRST CLASS, PRIORITY, PARCEL, BMP, MEDIA + $this->types = Array( + 'EXPRESS' => 'Express Mail', + 'FIRST CLASS' => 'First Class Mail', + 'PRIORITY' => 'Priority Mail', + 'PARCEL' => 'Parcel Post', + 'BPM' => 'Bound Printed Matter', + 'MEDIA' => 'Media Mail' + ); + + $this->intl_types = Array( + // 'GLOBAL EXPRESS' => 'Global Express Guaranteed', + // 'GLOBAL EXPRESS NON-DOC RECT' => 'Global Express Guaranteed Non-Document Rectangular', + // 'GLOBAL EXPRESS NON-DOC NON-RECT' => 'Global Express Guaranteed Non-Document Non-Rectangular', + 'EXPRESS MAIL INT' => 'Express Mail International (EMS)', + 'EXPRESS MAIL INT FLAT RATE ENV' => 'Express Mail International (EMS) Flat Rate Envelope', + 'PRIORITY MAIL INT' => 'Priority Mail International', + 'PRIORITY MAIL INT FLAT RATE ENV' => 'Priority Mail International Flat Rate Envelope', + 'PRIORITY MAIL INT FLAT RATE BOX' => 'Priority Mail International Flat Rate Box', + 'FIRST-CLASS MAIL INT' => 'First-Class Mail International' + ); + + // get 2-symbol country code + $country = $this->Application->ConfigValue('Comm_Shipping_Country'); + + if ($country != '') { + $this->shipping_origin_country = $this->GetUSPSCountry($country, ''); + } + + $contact_name = trim($this->_prepare_xml_param($this->Application->ConfigValue('Comm_Contacts_Name'))); + $split_pos = strpos($contact_name, ' '); + if ($split_pos === false) { + $this->store_first_name = $contact_name; + $this->store_last_name = ''; + } else { + $this->store_first_name = substr($contact_name, 0, $split_pos); + $this->store_last_name = trim(substr($contact_name, $split_pos)); + } + $this->company_name = $this->_prepare_xml_param($this->Application->ConfigValue('Comm_CompanyName')); + $this->store_name = $this->_prepare_xml_param($this->Application->ConfigValue('Comm_StoreName')); + $this->store_address1 = $this->_prepare_xml_param($this->Application->ConfigValue('Comm_Shipping_AddressLine1')); + $this->store_address2 = $this->_prepare_xml_param($this->Application->ConfigValue('Comm_Shipping_AddressLine2')); + + if ($this->store_address2 == '') { + $this->store_address2 = $this->store_address1; + $this->store_address1 = ''; + } + + $this->store_city = $this->_prepare_xml_param($this->Application->ConfigValue('Comm_Shipping_City')); + $this->store_state = $this->_prepare_xml_param($this->Application->ConfigValue('Comm_Shipping_State')); + $zip = $this->_prepare_xml_param($this->Application->ConfigValue('Comm_Shipping_ZIP')); + $this->store_zip5 = substr($zip, 0, 5); + $this->store_zip4 = trim(substr($zip, 6), '-'); + $this->store_phone = $this->_prepare_xml_param($this->Application->ConfigValue('Comm_Contacts_Phone')); + + // get username and password fron config. + $a_params = $this->LoadParams(); + $this->usps_userid = $a_params['AccountLogin']; + + // Note by Erik: DO NOT CHANGE THIS ARRAY. It's values are sent to USPS service and any changes may impact class main functionality. + $this->countries = array( + 'AF' => 'Afghanistan', + 'AL' => 'Albania', + 'DZ' => 'Algeria', + 'AD' => 'Andorra', + 'AO' => 'Angola', + 'AI' => 'Anguilla', + 'AG' => 'Antigua and Barbuda', + 'AR' => 'Argentina', + 'AM' => 'Armenia', + 'AW' => 'Aruba', + 'AU' => 'Australia', + 'AT' => 'Austria', + 'AZ' => 'Azerbaijan', + 'BS' => 'Bahamas', + 'BH' => 'Bahrain', + 'BD' => 'Bangladesh', + 'BB' => 'Barbados', + 'BY' => 'Belarus', + 'BE' => 'Belgium', + 'BZ' => 'Belize', + 'BJ' => 'Benin', + 'BM' => 'Bermuda', + 'BT' => 'Bhutan', + 'BO' => 'Bolivia', + 'BA' => 'Bosnia-Herzegovina', + 'BW' => 'Botswana', + 'BR' => 'Brazil', + 'VG' => 'British Virgin Islands', + 'BN' => 'Brunei Darussalam', + 'BG' => 'Bulgaria', + 'BF' => 'Burkina Faso', + 'MM' => 'Burma', + 'BI' => 'Burundi', + 'KH' => 'Cambodia', + 'CM' => 'Cameroon', + 'CA' => 'Canada', + 'CV' => 'Cape Verde', + 'KY' => 'Cayman Islands', + 'CF' => 'Central African Republic', + 'TD' => 'Chad', + 'CL' => 'Chile', + 'CN' => 'China', + 'CX' => 'Christmas Island (Australia)', + 'CC' => 'Cocos Island (Australia)', + 'CO' => 'Colombia', + 'KM' => 'Comoros', + 'CG' => 'Congo (Brazzaville),Republic of the', + 'ZR' => 'Congo, Democratic Republic of the', + 'CK' => 'Cook Islands (New Zealand)', + 'CR' => 'Costa Rica', + 'CI' => 'Cote d\'Ivoire (Ivory Coast)', + 'HR' => 'Croatia', + 'CU' => 'Cuba', + 'CY' => 'Cyprus', + 'CZ' => 'Czech Republic', + 'DK' => 'Denmark', + 'DJ' => 'Djibouti', + 'DM' => 'Dominica', + 'DO' => 'Dominican Republic', + 'TP' => 'East Timor (Indonesia)', + 'EC' => 'Ecuador', + 'EG' => 'Egypt', + 'SV' => 'El Salvador', + 'GQ' => 'Equatorial Guinea', + 'ER' => 'Eritrea', + 'EE' => 'Estonia', + 'ET' => 'Ethiopia', + 'FK' => 'Falkland Islands', + 'FO' => 'Faroe Islands', + 'FJ' => 'Fiji', + 'FI' => 'Finland', + 'FR' => 'France', + 'GF' => 'French Guiana', + 'PF' => 'French Polynesia', + 'GA' => 'Gabon', + 'GM' => 'Gambia', + 'GE' => 'Georgia, Republic of', + 'DE' => 'Germany', + 'GH' => 'Ghana', + 'GI' => 'Gibraltar', + 'GB' => 'Great Britain and Northern Ireland', + 'GR' => 'Greece', + 'GL' => 'Greenland', + 'GD' => 'Grenada', + 'GP' => 'Guadeloupe', + 'GT' => 'Guatemala', + 'GN' => 'Guinea', + 'GW' => 'Guinea-Bissau', + 'GY' => 'Guyana', + 'HT' => 'Haiti', + 'HN' => 'Honduras', + 'HK' => 'Hong Kong', + 'HU' => 'Hungary', + 'IS' => 'Iceland', + 'IN' => 'India', + 'ID' => 'Indonesia', + 'IR' => 'Iran', + 'IQ' => 'Iraq', + 'IE' => 'Ireland', + 'IL' => 'Israel', + 'IT' => 'Italy', + 'JM' => 'Jamaica', + 'JP' => 'Japan', + 'JO' => 'Jordan', + 'KZ' => 'Kazakhstan', + 'KE' => 'Kenya', + 'KI' => 'Kiribati', + 'KW' => 'Kuwait', + 'KG' => 'Kyrgyzstan', + 'LA' => 'Laos', + 'LV' => 'Latvia', + 'LB' => 'Lebanon', + 'LS' => 'Lesotho', + 'LR' => 'Liberia', + 'LY' => 'Libya', + 'LI' => 'Liechtenstein', + 'LT' => 'Lithuania', + 'LU' => 'Luxembourg', + 'MO' => 'Macao', + 'MK' => 'Macedonia, Republic of', + 'MG' => 'Madagascar', + 'MW' => 'Malawi', + 'MY' => 'Malaysia', + 'MV' => 'Maldives', + 'ML' => 'Mali', + 'MT' => 'Malta', + 'MQ' => 'Martinique', + 'MR' => 'Mauritania', + 'MU' => 'Mauritius', + 'YT' => 'Mayotte (France)', + 'MX' => 'Mexico', + 'MD' => 'Moldova', + 'MC' => 'Monaco (France)', + 'MN' => 'Mongolia', + 'MS' => 'Montserrat', + 'MA' => 'Morocco', + 'MZ' => 'Mozambique', + 'NA' => 'Namibia', + 'NR' => 'Nauru', + 'NP' => 'Nepal', + 'NL' => 'Netherlands', + 'AN' => 'Netherlands Antilles', + 'NC' => 'New Caledonia', + 'NZ' => 'New Zealand', + 'NI' => 'Nicaragua', + 'NE' => 'Niger', + 'NG' => 'Nigeria', + 'KP' => 'North Korea (Korea, Democratic People\'s Republic of)', + 'NO' => 'Norway', + 'OM' => 'Oman', + 'PK' => 'Pakistan', + 'PA' => 'Panama', + 'PG' => 'Papua New Guinea', + 'PY' => 'Paraguay', + 'PE' => 'Peru', + 'PH' => 'Philippines', + 'PN' => 'Pitcairn Island', + 'PL' => 'Poland', + 'PT' => 'Portugal', + 'QA' => 'Qatar', + 'RE' => 'Reunion', + 'RO' => 'Romania', + 'RU' => 'Russia', + 'RW' => 'Rwanda', + 'SH' => 'Saint Helena', + 'KN' => 'Saint Kitts (St. Christopher and Nevis)', + 'LC' => 'Saint Lucia', + 'PM' => 'Saint Pierre and Miquelon', + 'VC' => 'Saint Vincent and the Grenadines', + 'SM' => 'San Marino', + 'ST' => 'Sao Tome and Principe', + 'SA' => 'Saudi Arabia', + 'SN' => 'Senegal', + 'YU' => 'Serbia-Montenegro', + 'SC' => 'Seychelles', + 'SL' => 'Sierra Leone', + 'SG' => 'Singapore', + 'SK' => 'Slovak Republic', + 'SI' => 'Slovenia', + 'SB' => 'Solomon Islands', + 'SO' => 'Somalia', + 'ZA' => 'South Africa', + 'GS' => 'South Georgia (Falkland Islands)', + 'KR' => 'South Korea (Korea, Republic of)', + 'ES' => 'Spain', + 'LK' => 'Sri Lanka', + 'SD' => 'Sudan', + 'SR' => 'Suriname', + 'SZ' => 'Swaziland', + 'SE' => 'Sweden', + 'CH' => 'Switzerland', + 'SY' => 'Syrian Arab Republic', + 'TW' => 'Taiwan', + 'TJ' => 'Tajikistan', + 'TZ' => 'Tanzania', + 'TH' => 'Thailand', + 'TG' => 'Togo', + 'TK' => 'Tokelau (Union) Group (Western Samoa)', + 'TO' => 'Tonga', + 'TT' => 'Trinidad and Tobago', + 'TN' => 'Tunisia', + 'TR' => 'Turkey', + 'TM' => 'Turkmenistan', + 'TC' => 'Turks and Caicos Islands', + 'TV' => 'Tuvalu', + 'UG' => 'Uganda', + 'UA' => 'Ukraine', + 'AE' => 'United Arab Emirates', + 'UY' => 'Uruguay', + 'UZ' => 'Uzbekistan', + 'VU' => 'Vanuatu', + 'VA' => 'Vatican City', + 'VE' => 'Venezuela', + 'VN' => 'Vietnam', + 'WF' => 'Wallis and Futuna Islands', + 'WS' => 'Western Samoa', + 'YE' => 'Yemen', + 'ZM' => 'Zambia', + 'ZW' => 'Zimbabwe' + ); + + $this->countryinsure = array( + 'AF' => 0, + 'AL' => 0, + 'DZ' => 2185, + 'AD' => 5000, + 'AO' => 0, + 'AI' => 415, + 'AG' => 60, + 'AR' => 5000, + 'AM' => 1350, + 'AW' => 830, + 'AU' => 3370, + 'AT' => 5000, + 'AZ' => 5000, + 'BS' => 2795, + 'BH' => 0, + 'BD' => 5000, + 'BB' => 220, + 'BY' => 1323, + 'BE' => 5000, + 'BZ' => 1600, + 'BJ' => 170, + 'BM' => 440, + 'BT' => 440, + 'BO' => 0, + 'BA' => 5000, + 'BW' => 145, + 'BR' => 5000, + 'VG' => 165, + 'BN' => 4405, + 'BG' => 1030, + 'BF' => 530, + 'MM' => 4045, + 'BI' => 790, + 'KH' => 0, + 'CM' => 5000, + 'CA' => 675, + 'CV' => 0, + 'KY' => 0, + 'CF' => 4405, + 'TD' => 440, + 'CL' => 0, + 'CN' => 1130, + 'CX' => 3370, + 'CC' => 3370, + 'CO' => 0, + 'KM' => 690, + 'CG' => 1685, + 'ZR' => 0, + 'CK' => 980, + 'CR' => 0, + 'CI' => 5000, + 'HR' => 5000, + 'CU' => 0, + 'CY' => 5000, + 'CZ' => 5000, + 'DK' => 5000, + 'DJ' => 880, + 'DM' => 0, + 'DO' => 0, + 'TP' => 0, + 'EC' => 0, + 'EG' => 1685, + 'SV' => 0, + 'GQ' => 0, + 'ER' => 0, + 'EE' => 2020, + 'ET' => 1000, + 'FK' => 510, + 'FO' => 5000, + 'FJ' => 600, + 'FI' => 5000, + 'FR' => 5000, + 'GF' => 5000, + 'PF' => 1015, + 'GA' => 485, + 'GM' => 2575, + 'GE' => 1350, + 'DE' => 5000, + 'GH' => 5000, + 'GI' => 5000, + 'GB' => 857, + 'GR' => 5000, + 'GL' => 5000, + 'GD' => 350, + 'GP' => 5000, + 'GT' => 0, + 'GN' => 875, + 'GW' => 21, + 'GY' => 10, + 'HT' => 0, + 'HN' => 0, + 'HK' => 5000, + 'HU' => 5000, + 'IS' => 5000, + 'IN' => 2265, + 'ID' => 0, + 'IR' => 0, + 'IQ' => 0, + 'IE' => 5000, + 'IL' => 0, + 'IT' => 5000, + 'JM' => 0, + 'JP' => 5000, + 'JO' => 0, + 'KZ' => 5000, + 'KE' => 815, + 'KI' => 0, + 'KW' => 1765, + 'KG' => 1350, + 'LA' => 0, + 'LV' => 1350, + 'LB' => 440, + 'LS' => 440, + 'LR' => 440, + 'LY' => 0, + 'LI' => 5000, + 'LT' => 5000, + 'LU' => 5000, + 'MO' => 4262, + 'MK' => 2200, + 'MG' => 675, + 'MW' => 50, + 'MY' => 1320, + 'MV' => 0, + 'ML' => 950, + 'MT' => 5000, + 'MQ' => 5000, + 'MR' => 635, + 'MU' => 270, + 'YT' => 5000, + 'MX' => 0, + 'MD' => 1350, + 'MC' => 5000, + 'MN' => 440, + 'MS' => 2200, + 'MA' => 5000, + 'MZ' => 0, + 'NA' => 4405, + 'NR' => 220, + 'NP' => 0, + 'NL' => 5000, + 'AN' => 830, + 'NC' => 1615, + 'NZ' => 980, + 'NI' => 440, + 'NE' => 810, + 'NG' => 205, + 'KP' => 0, + 'NO' => 0, + 'OM' => 575, + 'PK' => 270, + 'PA' => 0, + 'PG' => 445, + 'PY' => 0, + 'PE' => 0, + 'PH' => 270, + 'PN' => 0, + 'PL' => 1350, + 'PT' => 5000, + 'QA' => 2515, + 'RE' => 5000, + 'RO' => 5000, + 'RU' => 5000, + 'RW' => 0, + 'SH' => 170, + 'KN' => 210, + 'LC' => 400, + 'PM' => 5000, + 'VC' => 130, + 'SM' => 5000, + 'ST' => 440, + 'SA' => 0, + 'SN' => 865, + 'YU' => 5000, + 'SC' => 0, + 'SL' => 0, + 'SG' => 4580, + 'SK' => 5000, + 'SI' => 4400, + 'SB' => 0, + 'SO' => 440, + 'ZA' => 1760, + 'GS' => 510, + 'KR' => 5000, + 'ES' => 5000, + 'LK' => 35, + 'SD' => 0, + 'SR' => 535, + 'SZ' => 560, + 'SE' => 5000, + 'CH' => 5000, + 'SY' => 3080, + 'TW' => 1350, + 'TJ' => 1350, + 'TZ' => 230, + 'TH' => 1350, + 'TG' => 2190, + 'TK' => 295, + 'TO' => 515, + 'TT' => 930, + 'TN' => 2200, + 'TR' => 880, + 'TM' => 675, + 'TC' => 0, + 'TV' => 4715, + 'UG' => 0, + 'UA' => 5000, + 'AE' => 5000, + 'UY' => 0, + 'UZ' => 5000, + 'VU' => 0, + 'VA' => 5000, + 'VE' => 0, + 'VN' => 0, + 'WF' => 1615, + 'WS' => 295, + 'YE' => 0, + 'ZM' => 540, + 'ZW' => 600, + 'US' => 5000 + ); + } + + function SetInsurance() + { + $this->insurance_cost = 0; + + // Insurance module by Kevin Shelton + // divide the value of the order among the packages based on the order total or subtotal depending on whether or not you have configured to insure tax + $shipping_weight = $this->order['ShippingWeight']; + $shipping_num_boxes = $this->order['ShippingNumBoxes']; + $costperpkg = $this->order['SubTotal'] / $shipping_num_boxes; + + // retrieve the maximum allowed insurance for the destination country and if the package value exceeds it then set package value to the maximum allowed + + $maxins = $this->countryinsure[$this->order['ShippingCountry']]; + if ($costperpkg > $maxins) $costperpkg = $maxins; + + // if insurance not allowed for destination or insurance is turned off add nothing to shipping cost + + if (($maxins == 0) || (MODULE_SHIPPING_USPS_INSURE == 'False')) { + $insurance = 0; + } + // US and Canada share the same insurance calculation (though not the same maximum) + else if (($this->order['ShippingCountry'] == 'US') || ($this->order['ShippingCountry'] == 'CA')) + { + if ($costperpkg<=50) { + $insurance=MODULE_SHIPPING_USPS_INS1; + } + else if ($costperpkg<=100) { + $insurance=MODULE_SHIPPING_USPS_INS2; + } + else if ($costperpkg<=200) { + $insurance=MODULE_SHIPPING_USPS_INS3; + } + else if ($costperpkg<=300) { + $insurance=MODULE_SHIPPING_USPS_INS4; + } + else { + $insurance = MODULE_SHIPPING_USPS_INS4 + ((ceil($costperpkg/100) -3) * MODULE_SHIPPING_USPS_INS5); + } + } + // if insurance allowed and is not US or Canada then calculate international insurance + else { + if ($costperpkg<=50) { + $insurance=MODULE_SHIPPING_USPS_INS6; + } + else if ($costperpkg<=100) { + $insurance=MODULE_SHIPPING_USPS_INS7; + } + else if ($costperpkg<=200) { + $insurance=MODULE_SHIPPING_USPS_INS8; + } + else if ($costperpkg<=300) { + $insurance=MODULE_SHIPPING_USPS_INS9; + } + else { + $insurance = MODULE_SHIPPING_USPS_INS9 + ((ceil($costperpkg/100) - 3) * MODULE_SHIPPING_USPS_INS10); + } + } + // usps doesnt accept zero weight + $shipping_weight = ($shipping_weight < 0.1 ? 0.1 : $shipping_weight); + $shipping_pounds = floor ($shipping_weight); + $shipping_ounces = round(16 * ($shipping_weight - floor($shipping_weight))); + $this->_setWeight($shipping_pounds, $shipping_ounces); + // Added by Kevin Chen (kkchen@uci.edu); Fixes the Parcel Post Bug July 1, 2004 + // Refer to http://www.usps.com/webtools/htm/Domestic-Rates.htm documentation + // Thanks Ryan + if($shipping_pounds > 35 || ($shipping_pounds == 0 && $shipping_ounces < 6)){ + $this->_setMachinable('False'); + } + else{ + $this->_setMachinable('True'); + } + + $this->insurance_cost = $insurance; + // End Kevin Chen July 1, 2004 + } + + function _setService($service) + { + $this->service = $service; + } + + function _setWeight($pounds, $ounces=0) + { + $this->pounds = $pounds; + $this->ounces = $ounces; + } + + function _setContainer($container) + { + $this->container = $container; + } + + function _setSize($size) + { + $this->size = $size; + } + + function _setMachinable($machinable) + { + $this->machinable = $machinable; + } + + function PhoneClean($phone) + { + $res = preg_replace('/[(]|[)]|[\-]|[ ]|[#]|[\.]|[a-z](.*)|[A-Z](.*)/g', '', $phone); + if ( strlen($res) > 10 ) { + $res = substr($res, 0, 10); + } + return $res != '' ? $res : $phone; + } + + function GetQuote($method = '') + { + if ( isset($this->types[$method]) || in_array($method, $this->intl_types)) { + $this->_setService($method); + } + $this -> _setContainer('None'); + $this -> _setSize('REGULAR'); + $this -> SetInsurance(); // ??? + if ($this->order['ShippingCountry'] == $this->shipping_origin_country) { + $request=''; + // PASSWORD="'.$this->usps_password.'" + $request.= ''; + $services_count = 0; + if (isset($this->service)) { + $this->types = array($this->service => $this->types[$this->service]); + } + $dest_zip = str_replace(' ', '', $this->order['ShippingZip']); + $dest_zip = substr($dest_zip, 0, 5); + reset($this->types); + $allowed_types = explode(", ", MODULE_SHIPPING_USPS_TYPES); + + while (list($key, $value) = each($this->types)) + { + if ( !in_array($key, $allowed_types) ) continue; + $request .= ''. + ''.$key.''. + ''.$this->store_zip5.''. + ''.$dest_zip.''. + ''.$this->pounds.''. + ''.$this->ounces.''. + ''.$this->size.''. + ''.$this->machinable.''. + ''; + $services_count++; + } + $request .= ''; + $api_query = 'RateV3'; + } + else { + $request = ''. + ''. + ''.$this->pounds.''. + ''.$this->ounces.''. + 'Package'. + ''.$this->countries[$this->order['ShippingCountry']].''. + ''. + ''; + $api_query = 'IntlRate'; + } + $request = 'API='.$api_query.'&XML=' . kUtil::escape($request, kUtil::ESCAPE_URL); + $body = $this->PostQuery($request); + $body = str_replace(chr(146), '', $body); // for bad ` + + // check for errors + if (strpos($body, '') !== false) { + $errors = Array (); + preg_match_all('/(.*?)<\/Number>/s', $body, $error_numbers); + preg_match_all('/(.*?)<\/Description>/s', $body, $error_descriptions); + + foreach ($error_numbers[1] as $index => $error_number) { + $errors[$index] = $error_descriptions[1][$index]; + if ($this->Application->isDebugMode()) { + $errors[$index] .= ' (' . $error_number . ')'; + } + } + + $errors = array_unique($errors); // we may have same errors on many packages, so don't show duplicates + return Array('error' => implode('
', $errors)); + } + + // parse response + + /** @var kXMLHelper $xml_helper */ + $xml_helper = $this->Application->recallObject('kXMLHelper'); + + /** @var kXMLNode $root_node */ + $root_node =& $xml_helper->Parse($body); + + $rates = Array(); + // Domestic shipping + if ($this->order['ShippingCountry'] == $this->shipping_origin_country) { + $i = 0; + $postage_node =& $root_node->FindChild('Package'); + do { + // $parcel_node =& $postage_node->firstChild; + $service = $postage_node->FindChildValue('MailService'); + if ( $service != '' ) { + $i++; + $rates[$i] = Array(); + $rates[$i]['Title'] = $service; + $rates[$i]['Rate'] = $this->insurance_cost + $postage_node->FindChildValue('Rate'); + } + } + while ( $postage_node =& $postage_node->NextSibling()); + } + else { + // for International Rates !!! + $allowed_types = array(); + foreach( explode(", ", MODULE_SHIPPING_USPS_TYPES_INTL) as $value ) { + $allowed_types[$value] = $this->intl_types[$value]; + } + $i = 0; + $service_node =& $root_node->FindChild('Service'); + do { + $service = trim($service_node->FindChildValue('SvcDescription')); + if( !in_array($service, $allowed_types) ) continue; + $i++; + if ( $service_node->FindChildValue('MaxWeight') >= $this->pounds ) { + $rates[$i] = Array(); + $rates[$i]['Title'] = $service; + $rates[$i]['MaxDimensions'] = $service_node->FindChildValue('MaxDimensions'); + $rates[$i]['MaxWeight'] = $service_node->FindChildValue('MaxWeight'); + $rates[$i]['SvcCommitments'] = $service_node->FindChildValue('SvcCommitments'); + $rates[$i]['Rate'] = $this->insurance_cost + $service_node->FindChildValue('Postage'); + } + } + while ( $service_node =& $service_node->NextSibling()); + } + // print_r($rates); + // die('here'); + return $rates; + } + + function PostOrder() + { + $request=''; + $base_request = ''; + $this->SetInsurance(); + // $this->order['ShippingCountry'] = $this->GetUSPSCountry($this->order['ShippingCountry']); + + // Domestic Order + if ($this->order['ShippingCountry'] == $this->shipping_origin_country) { + + // $dest_zip = str_replace(' ', '', $this->order['ShippingZip5']); + $this->order['ShippingZip5'] = substr($this->order['ShippingZip5'], 0, 5); + $WeightInOunces = floor($this->pounds * 16 + $this->ounces); + + $base_request =' + + + '.$this->store_name.' + '.$this->company_name.' + '.$this->store_address1.' + '.$this->store_address2.' + '.$this->store_city.' + '.$this->store_state.' + '.$this->store_zip5.' + '.$this->store_zip4.' + '.$this->order['FirstName'].' '.$this->order['LastName'].' + '.$this->order['ShippingCompany'].' + '.$this->order['ShippingAddress2'].' + '.$this->order['ShippingAddress1'].' + '.$this->order['ShippingCity'].' + '.$this->order['ShippingState'].' + '.$this->order['ShippingZip5'].' + '.$this->order['ShippingZip4'].' + '.$WeightInOunces.' + '.$this->order['ShippingService'].' + PDF + '.date('m/d/Y',time()).' + + + + + + '; + + $api_query = 'DeliveryConfirmationV3'; + $xml_request = 'DeliveryConfirmationV3.0Request'; + } + else { + + // International Order(s) + $shipping_service = strtolower($this->order['ShippingService']); + + $base_request = '