Page MenuHomeIn-Portal Phabricator

in-commerce
No OneTemporary

File Metadata

Created
Sun, Apr 20, 6:14 PM

in-commerce

This file is larger than 256 KB, so syntax highlighting was skipped.
Index: branches/5.3.x/units/affiliate_plans/affiliate_plans_event_handler.php
===================================================================
--- branches/5.3.x/units/affiliate_plans/affiliate_plans_event_handler.php (revision 15694)
+++ branches/5.3.x/units/affiliate_plans/affiliate_plans_event_handler.php (revision 15695)
@@ -1,126 +1,130 @@
<?php
/**
* @version $Id$
* @package In-Commerce
* @copyright Copyright (C) 1997 - 2009 Intechnic. All rights reserved.
* @license Commercial License
* This software 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
* See http://www.in-portal.org/commercial-license for copyright notices and details.
*/
defined('FULL_PATH') or die('restricted access!');
class AffiliatePlansEventHandler extends kDBEventHandler {
/**
* 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);
if ( $event->Special == 'active' ) {
$object = $event->getObject();
/* @var $object kDBList */
$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)
{
$object = $event->getObject();
/* @var $object kDBItem */
- $live_table = $this->Application->getUnitOption($event->Prefix, 'TableName');
+ $config = $event->getUnitConfig();
+
+ $live_table = $config->getTableName();
$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') . '
+ $sql = 'UPDATE ' . $config->getTableName() . '
SET IsPrimary = 0';
$this->Conn->Query($sql);
- $object->SetDBField($object->getStatusField(), 1);
+ $object->SetDBField($config->getStatusField(true), 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' ) {
+ $config = $event->getUnitConfig();
$ids = $event->getEventParam('ids');
- $sql = 'SELECT ' . $this->Application->getUnitOption($event->Prefix, 'IDField') . '
- FROM ' . $this->Application->getUnitOption($event->Prefix, 'TableName') . '
+ $sql = 'SELECT ' . $config->getIDField() . '
+ FROM ' . $config->getTableName() . '
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
Index: branches/5.3.x/units/affiliate_plans_items/affiliate_plans_items_tag_processor.php
===================================================================
--- branches/5.3.x/units/affiliate_plans_items/affiliate_plans_items_tag_processor.php (revision 15694)
+++ branches/5.3.x/units/affiliate_plans_items/affiliate_plans_items_tag_processor.php (revision 15695)
@@ -1,48 +1,49 @@
<?php
/**
* @version $Id$
* @package In-Commerce
* @copyright Copyright (C) 1997 - 2009 Intechnic. All rights reserved.
* @license Commercial License
* This software 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
* See http://www.in-portal.org/commercial-license for copyright notices and details.
*/
defined('FULL_PATH') or die('restricted access!');
class AffiliatePlansItemsTagProcessor extends kDBTagProcessor {
function IsEntireOrder($params)
{
- $table_name = $this->Application->getUnitOption($this->Prefix, 'TableName');
+ $table_name = $this->getUnitConfig()->getTableName();
- if ($this->Application->IsTempMode($this->Prefix)) {
+ 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)
{
$object = $this->getObject($params);
/* @var $object kDBList */
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
Index: branches/5.3.x/units/affiliate_plans_items/affiliate_plans_items_event_handler.php
===================================================================
--- branches/5.3.x/units/affiliate_plans_items/affiliate_plans_items_event_handler.php (revision 15694)
+++ branches/5.3.x/units/affiliate_plans_items/affiliate_plans_items_event_handler.php (revision 15695)
@@ -1,94 +1,93 @@
<?php
/**
* @version $Id$
* @package In-Commerce
* @copyright Copyright (C) 1997 - 2009 Intechnic. All rights reserved.
* @license Commercial License
* This software 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
* See http://www.in-portal.org/commercial-license for copyright notices and details.
*/
defined('FULL_PATH') or die('restricted access!');
// NOT IN USE RIGHT NOW (by Alex)
class AffiliatePlansItemsEventHandler extends kDBEventHandler {
/**
* Adds selected items to affiliate products
*
* @param kEvent $event
*/
function OnProcessSelected($event)
{
// uses another handler event, because does the same stuff but on different table
$di_handler = $this->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');
+ /* @var $main_object kDBItem */
- $table = $this->Application->getUnitOption($event->Prefix,'TableName');
- $sql = 'DELETE FROM '.$table.' WHERE ItemResourceId = '.$resource_id;
+ $sql = 'DELETE FROM ' . $event->getUnitConfig()->getTableName() . '
+ WHERE ItemResourceId = ' . $main_object->GetDBField('ResourceId');
$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);
+ $event->getUnitConfig()->addCalculatedFieldsBySpecial('', Array (
+ 'ItemName' => 'COALESCE(p.l' . $language_id . '_Name, p.l' . $primary_language_id . '_Name)',
+ ));
}
}
\ No newline at end of file
Index: branches/5.3.x/units/gateways/gw_classes/verisign_pflink.php
===================================================================
--- branches/5.3.x/units/gateways/gw_classes/verisign_pflink.php (revision 15694)
+++ branches/5.3.x/units/gateways/gw_classes/verisign_pflink.php (revision 15695)
@@ -1,137 +1,137 @@
<?php
/**
* @version $Id$
* @package In-Commerce
* @copyright Copyright (C) 1997 - 2009 Intechnic. All rights reserved.
* @license Commercial License
* This software 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
* See http://www.in-portal.org/commercial-license for copyright notices and details.
*/
require_once GW_CLASS_PATH.'/gw_base.php';
$class_name = 'kVerisignPfLinkGW'; // for automatic installation
class kVerisignPfLinkGW extends kGWBase
{
function InstallData()
{
$data = array(
'Gateway' => 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').'
+ $billing_email = $this->Conn->GetOne(' SELECT Email FROM '.$this->Application->getUnitConfig('u')->getTableName().'
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
Index: branches/5.3.x/units/gateways/gw_classes/atosorigin.php
===================================================================
--- branches/5.3.x/units/gateways/gw_classes/atosorigin.php (revision 15694)
+++ branches/5.3.x/units/gateways/gw_classes/atosorigin.php (revision 15695)
@@ -1,192 +1,191 @@
<?php
/**
* @version $Id$
* @package In-Commerce
* @copyright Copyright (C) 1997 - 2009 Intechnic. All rights reserved.
* @license Commercial License
* This software 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
* See http://www.in-portal.org/commercial-license for copyright notices and details.
*/
require_once GW_CLASS_PATH.'/gw_base.php';
$class_name = 'kAtosOriginGW'; // for automatic installation
class kAtosOriginGW extends kGWBase
{
function InstallData()
{
$data = array(
'Gateway' => 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'));
+ $billing_email = $this->_getUserEmail();
}
$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 '</form>'.$ret.'<form>';
}
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
Index: branches/5.3.x/units/gateways/gw_classes/paypal_direct.php
===================================================================
--- branches/5.3.x/units/gateways/gw_classes/paypal_direct.php (revision 15694)
+++ branches/5.3.x/units/gateways/gw_classes/paypal_direct.php (revision 15695)
@@ -1,241 +1,240 @@
<?php
/**
* @version $Id$
* @package In-Commerce
* @copyright Copyright (C) 1997 - 2009 Intechnic. All rights reserved.
* @license Commercial License
* This software 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
* See http://www.in-portal.org/commercial-license for copyright notices and details.
*/
require_once GW_CLASS_PATH.'/gw_base.php';
$class_name = 'kGWPaypalDirect'; // for automatic installation
class kGWPaypalDirect extends kGWBase
{
function InstallData()
{
$data = array(
'Gateway' => 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'];
$cs_helper = $this->Application->recallObject('CountryStatesHelper');
/* @var $cs_helper kCountryStatesHelper */
$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'));
+ $billing_email = $this->_getUserEmail();
}
$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 '<pre>';
// print_r($post_fields);
// exit;
$curl_helper = $this->Application->recallObject('CurlHelper');
/* @var $curl_helper kCurlHelper */
$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 '<pre>';
// 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
Index: branches/5.3.x/units/gateways/gw_classes/authorizenet.php
===================================================================
--- branches/5.3.x/units/gateways/gw_classes/authorizenet.php (revision 15694)
+++ branches/5.3.x/units/gateways/gw_classes/authorizenet.php (revision 15695)
@@ -1,180 +1,180 @@
<?php
/**
* @version $Id$
* @package In-Commerce
* @copyright Copyright (C) 1997 - 2009 Intechnic. All rights reserved.
* @license Commercial License
* This software 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
* See http://www.in-portal.org/commercial-license for copyright notices and details.
*/
require_once GW_CLASS_PATH.'/gw_base.php';
class kGWAuthorizeNet extends kGWBase
{
function DirectPayment($item_data, $gw_params)
{
$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'] = $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'));
+ $billing_email = $this->_getUserEmail();
}
+
$post_fields['x_email'] = $billing_email;
$post_fields['x_phone'] = $item_data['BillingPhone'];
$cs_helper = $this->Application->recallObject('CountryStatesHelper');
/* @var $cs_helper kCountryStatesHelper */
$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';
$curl_helper = $this->Application->recallObject('CurlHelper');
/* @var $curl_helper kCurlHelper */
$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';
$curl_helper = $this->Application->recallObject('CurlHelper');
/* @var $curl_helper kCurlHelper */
$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
Index: branches/5.3.x/units/gateways/gw_classes/paybox.php
===================================================================
--- branches/5.3.x/units/gateways/gw_classes/paybox.php (revision 15694)
+++ branches/5.3.x/units/gateways/gw_classes/paybox.php (revision 15695)
@@ -1,182 +1,182 @@
<?php
/**
* @version $Id$
* @package In-Commerce
* @copyright Copyright (C) 1997 - 2009 Intechnic. All rights reserved.
* @license Commercial License
* This software 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
* See http://www.in-portal.org/commercial-license for copyright notices and details.
*/
require_once GW_CLASS_PATH.'/gw_base.php';
$class_name = 'kPayboxGW'; // for automatic installation
class kPayboxGW extends kGWBase
{
function InstallData()
{
$data = array(
'Gateway' => 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').'
+ $billing_email = $this->Conn->GetOne(' SELECT Email FROM '.$this->Application->getUnitConfig('u')->getTableName().'
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 '</form>'.$ret.'<form>';
}
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
Index: branches/5.3.x/units/gateways/gw_classes/gw_base.php
===================================================================
--- branches/5.3.x/units/gateways/gw_classes/gw_base.php (revision 15694)
+++ branches/5.3.x/units/gateways/gw_classes/gw_base.php (revision 15695)
@@ -1,261 +1,276 @@
<?php
/**
* @version $Id$
* @package In-Commerce
* @copyright Copyright (C) 1997 - 2009 Intechnic. All rights reserved.
* @license Commercial License
* This software 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
* See http://www.in-portal.org/commercial-license for copyright notices and details.
*/
defined('FULL_PATH') or die('restricted access!');
class kGWBase extends kBase
{
/**
* gateway received responce
*
* @var string
*/
var $gw_responce = '';
var $parsed_responce = Array();
/**
* Returns payment form submit url
*
* @return string
*/
function getFormAction($gw_params)
{
return $this->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)
{
$converter = $this->Application->recallObject('CurrencyRates');
/* @var $converter 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)
$payment_type = $this->Application->recallObject('pt.-item', null, Array ('skip_autoload' => true));
/* @var $payment_type kDBItem */
$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);
}
+
+ /**
+ * Returns currently logged-in user's e-mail
+ *
+ * @return string
+ * @access protected
+ */
+ protected function _getUserEmail()
+ {
+ $sql = 'SELECT Email
+ FROM ' . $this->Application->getUnitConfig('u')->getTableName() . '
+ WHERE PortalUserId = ' . $this->Application->RecallVar('user_id');
+
+ return $this->Conn->GetOne($sql);
+ }
}
\ No newline at end of file
Index: branches/5.3.x/units/gateways/gw_classes/multicards.php
===================================================================
--- branches/5.3.x/units/gateways/gw_classes/multicards.php (revision 15694)
+++ branches/5.3.x/units/gateways/gw_classes/multicards.php (revision 15695)
@@ -1,122 +1,122 @@
<?php
/**
* @version $Id$
* @package In-Commerce
* @copyright Copyright (C) 1997 - 2009 Intechnic. All rights reserved.
* @license Commercial License
* This software 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
* See http://www.in-portal.org/commercial-license for copyright notices and details.
*/
require_once GW_CLASS_PATH.'/gw_base.php';
$class_name = 'kMultiCardsGW'; // for automatic installation
class kMultiCardsGW extends kGWBase
{
function InstallData()
{
$data = array(
'Gateway' => 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').'
+ $billing_email = $this->Conn->GetOne(' SELECT Email FROM '.$this->Application->getUnitConfig('u')->getTableName().'
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 '<!--success--><a href="'.$url.'">'.$this->Application->Phrase('lu_text_MulticardsContinue').'</a>';
return 1;
}
}
\ No newline at end of file
Index: branches/5.3.x/units/gateways/gw_tag_processor.php
===================================================================
--- branches/5.3.x/units/gateways/gw_tag_processor.php (revision 15694)
+++ branches/5.3.x/units/gateways/gw_tag_processor.php (revision 15695)
@@ -1,127 +1,127 @@
<?php
/**
* @version $Id$
* @package In-Commerce
* @copyright Copyright (C) 1997 - 2009 Intechnic. All rights reserved.
* @license Commercial License
* This software 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
* See http://www.in-portal.org/commercial-license for copyright notices and details.
*/
defined('FULL_PATH') or die('restricted access!');
class GatewayTagProcessor extends kDBTagProcessor {
/**
* Payment gateway config values for current payment type
*
* @var Array
* @access private
*/
var $ConfigValues=Array();
/**
* Payment type id for current gateway values
*
* @var int
* @access private
*/
var $PaymentTypeID=0;
function initGWConfigValues()
{
$payment_type_id = $this->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)
{
$object = $this->getObject($params);
/* @var $object kDBItem */
$id = $object->GetID();
$value = isset($this->ConfigValues[$id]) ? $this->ConfigValues[$id] : '';
if ( !array_key_exists('no_special', $params) || !$params['no_special'] ) {
$value = htmlspecialchars($value, null, CHARSET);
}
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');
+ $id_field = $this->getUnitConfig()->getIDField();
$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)
{
$object = $this->getObject($params);
/* @var $object kDBItem */
$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
Index: branches/5.3.x/units/sections/section_eh.php
===================================================================
--- branches/5.3.x/units/sections/section_eh.php (revision 15694)
+++ branches/5.3.x/units/sections/section_eh.php (revision 15695)
@@ -1,101 +1,104 @@
<?php
/**
* @version $Id$
* @package In-Commerce
* @copyright Copyright (C) 1997 - 2010 Intechnic. All rights reserved.
* @license Commercial License
* This software 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
* See http://www.in-portal.org/commercial-license for copyright notices and details.
*/
defined('FULL_PATH') or die('restricted access!');
class InCommerceEventHandler extends kEventHandler {
/**
* [HOOK] Creates site domain editing tab
*
* @param kEvent $event
*/
function OnModifySiteDomainConfig($event)
{
- $edit_tab_presets = $this->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);
+ $master_config = $event->MasterEvent->getUnitConfig();
+
+ $master_config->addEditTabPresetTabs('Default', Array (
+ 'in-commerce' => Array (
+ 'title' => 'la_title_In-Commerce', 't' => 'in-commerce/site_domains/site_domain_edit', 'priority' => 2.1
+ ),
+ ));
+
+
+ $master_config->addTitlePresets(Array (
+ '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'),
+ ),
+ ));
- $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));
+ $master_config->addFields($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);
+ $master_config->addGridFields('Default', $new_columns);
+
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();
}
}
}
Index: branches/5.3.x/units/downloads/download_helper.php
===================================================================
--- branches/5.3.x/units/downloads/download_helper.php (revision 15694)
+++ branches/5.3.x/units/downloads/download_helper.php (revision 15695)
@@ -1,77 +1,83 @@
<?php
/**
* @version $Id$
* @package In-Commerce
* @copyright Copyright (C) 1997 - 2009 Intechnic. All rights reserved.
* @license Commercial License
* This software 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
* See http://www.in-portal.org/commercial-license for copyright notices and details.
*/
defined('FULL_PATH') or die('restricted access!');
class DownloadHelper extends kHelper {
function CheckAccess($file_id, $product_id)
{
$sql = 'SELECT FileAccessId FROM '.TABLE_PREFIX.'UserFileAccess
WHERE PortalUserId = '.$this->Application->RecallVar('user_id').'
AND ProductId = '.$product_id;
return $this->Conn->GetOne($sql);
}
function SendFile($file_id, $product_id)
{
$file_object = $this->Application->recallObject('file', null, Array('skip_autoload' => true));
/* @var $file_object kDBItem */
- $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';
+ if ( $file_id ) {
+ $sql = 'SELECT FileId, FilePath, RealPath, MIMEType
+ FROM ' . $this->Application->getUnitConfig('file')->getTableName() . '
+ WHERE FileId = ' . $file_id;
+ }
+ else {
+ $sql = 'SELECT FileId, FilePath, RealPath, MIMEType
+ FROM ' . $this->Application->getUnitConfig('file')->getTableName() . '
+ 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
Index: branches/5.3.x/units/reports/reports_event_handler.php
===================================================================
--- branches/5.3.x/units/reports/reports_event_handler.php (revision 15694)
+++ branches/5.3.x/units/reports/reports_event_handler.php (revision 15695)
@@ -1,844 +1,819 @@
<?php
/**
* @version $Id$
* @package In-Commerce
* @copyright Copyright (C) 1997 - 2009 Intechnic. All rights reserved.
* @license Commercial License
* This software 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
* See http://www.in-portal.org/commercial-license for copyright notices and details.
*/
defined('FULL_PATH') or die('restricted access!');
class ReportsEventHandler extends kDBEventHandler {
/**
* Allows to override standard permission mapping
*
* @return void
* @access protected
* @see kEventHandler::$permMapping
*/
protected function mapPermissions()
{
parent::mapPermissions();
$permissions = Array (
// user can view any form on front-end
'OnRunReport' => 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($event)
{
$this->Application->LinkVar('reports_finish_t');
$progress_t = $this->Application->GetVar('progress_t');
$event->redirect = $progress_t;
$items_info = $this->Application->GetVar( $event->getPrefixSpecial(true) );
if($items_info) $field_values = array_shift($items_info);
$object = $event->getObject( Array('skip_autoload' => true) );
$object->SetFieldsFromHash($field_values, $this->getRequestProtectedFields($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)
+ function OnUpdateConfig(kEvent $event)
{
$report = $this->Application->RecallVar('report_options');
- if (!$report) {
- return ;
+
+ if ( !$report ) {
+ return;
}
$field_values = unserialize($report);
- $rep_options = $this->Application->getUnitOptions('rep');
- $new_options = Array ();
-
- $new_options['TableName'] = $field_values['table_name'];
+ $config = $event->getUnitConfig('rep');
+ $config->setTableName($field_values['table_name']);
- $new_options['Fields'] = Array (
+ $config->addFields(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 (
+ if ( in_array($field_values['ReportType'], Array (1, 5)) ) {
+ $config->addFields(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']);
+ if ( $field_values['ReportType'] == 1 ) { // by Category
+ $config->setListSQLsBySpecial('', ' SELECT %1$s.* %2$s
+ FROM %1$s
+ LEFT JOIN ' . TABLE_PREFIX . 'Categories AS c ON c.CategoryId = %1$s.CategoryId');
+
+ if ( $this->Application->isModuleEnabled('in-auction') ) {
+ $config->addGrids(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'),
+ ),
+ ), 'Default');
+ }
+ else {
+ $config->addGrids(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'),
+ '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'),
+ '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'),
+ ),
+ ), 'Default');
}
- $new_options['VirtualFields'] = array_merge($rep_options['VirtualFields'], Array (
+ $config->addVirtualFields(Array (
'CategoryName' => Array ('type' => 'string', 'default' => ''),
- 'Metric' => Array (
- 'type' => 'int',
- 'formatter' => 'kOptionsFormatter',
- 'options' => $this->GetMetricOptions($new_options, 'CategoryName'),
- 'use_phrases' => 1,
- 'default' => 0,
- ),
+ 'Metric' => Array (
+ 'type' => 'int',
+ 'formatter' => 'kOptionsFormatter',
+ 'options' => $this->GetMetricOptions($config, '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.'), "&|&", " > ")',
- );
+ $config->addCalculatedFieldsBySpecial('', 'REPLACE(SUBSTR(c.l'.$lang.'_CachedNavbar, '.$root_length.'), "&|&", " > ")', 'CategoryName');
}
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',
- ),
+ $config->setListSQLsBySpecial('', ' SELECT %1$s.* %2$s
+ FROM %1$s
+ LEFT JOIN ' . TABLE_PREFIX . 'Users AS u ON u.PortalUserId = %1$s.PortalUserId');
+
+ $config->addGrids(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'),
),
- );
+ ), 'Default');
- $new_options['VirtualFields'] = array_merge($rep_options['VirtualFields'], Array (
+ $config->addVirtualFields(Array (
'Login' => Array ('type' => 'string', 'default' => ''),
'FirstName' => Array ('type' => 'string', 'default' => ''),
'LastName' => Array ('type' => 'string', 'default' => ''),
));
- $new_options['CalculatedFields'][''] = Array (
+ $config->addCalculatedFieldsBySpecial('', 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',
+ $config->setListSQLsBySpecial('', ' SELECT %1$s.* %2$s
+ FROM %1$s
+ LEFT JOIN '.TABLE_PREFIX.'Products AS p ON p.ProductId = %1$s.ProductId');
+
+ if ( $this->Application->isModuleEnabled('in-auction') ) {
+ $config->addGrids(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'),
),
- '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']);
+ ), 'Default');
+ }
+ else {
+ $config->addGrids(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'),
+ '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'),
+ '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'),
+ ),
+ ), 'Default');
}
-
- $new_options['VirtualFields'] = array_merge($rep_options['VirtualFields'], Array (
+ $config->addVirtualFields(Array (
'ProductName' => Array ('type' => 'string', 'default' => ''),
- 'Metric' => Array (
- 'type' => 'int',
- 'formatter' => 'kOptionsFormatter',
- 'options' => $this->GetMetricOptions($new_options, 'ProductName'),
- 'use_phrases' => 1,
- 'default' => 0
- ),
+ 'Metric' => Array (
+ 'type' => 'int',
+ 'formatter' => 'kOptionsFormatter',
+ 'options' => $this->GetMetricOptions($config, 'ProductName'),
+ 'use_phrases' => 1,
+ 'default' => 0
+ )
));
$lang = $this->Application->GetVar('m_lang');
-
- $new_options['CalculatedFields'][''] = Array (
- 'ProductName' => 'p.l'.$lang.'_Name',
- );
+ $config->addCalculatedFieldsBySpecial('', 'p.l' . $lang . '_Name', 'ProductName');
}
elseif ($field_values['ReportType'] == 12) { // Overall
+ $config->setListSQLsBySpecial('', 'SELECT %1$s.* %2$s FROM %1$s');
- $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
- );
+ $config->addFields(Array (
+ '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',
- ),
+ $config->addGrids(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'),
),
+ ), 'Default');
- );
-
-
- $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');
-
+ $config->addVirtualFields(Array (
+ 'type' => 'int',
+ 'formatter' => 'kOptionsFormatter',
+ 'options' => $this->GetMetricOptions($config, 'Marketplace'),
+ 'use_phrases' => 1,
+ 'default' => 0
+ ), 'Metric');
}
- $new_options['ListSortings'] = Array(
- '' => Array(
- 'Sorting' => Array('Amount' => 'desc'),
- )
- );
-
- foreach ($new_options as $key => $val) {
- $this->Application->setUnitOption('rep', $key, $val);
- }
+ $config->setListSortingsBySpecial('', Array(
+ 'Sorting' => Array('Amount' => 'desc'),
+ ));
}
/**
* 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 kUnitConfig $config
* @param string $exclude_field
+ * @return Array
*/
- function GetMetricOptions(&$a_config_options, $exclude_field)
+ function GetMetricOptions(kUnitConfig $config, $exclude_field)
{
- $a_ret = Array();
- foreach ($a_config_options['Grids']['Default']['Fields'] AS $field => $a_options)
- {
- if ($field == $exclude_field)
- {
+ $grid = $config->getGridByName('Default');
+
+ $ret = Array ();
+ foreach ($grid['Fields'] as $field => $field_options) {
+ if ( $field == $exclude_field ) {
continue;
}
- $a_ret[$field] = $a_options['title'];
+
+ $ret[$field] = $field_options['title'];
}
- return $a_ret;
+
+ return $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)
{
$report = $this->Application->recallObject($event->getPrefixSpecial(),'rep_List',Array('skip_counting'=>true,'per_page'=>-1) );
/* @var $report kDBList*/
$ReportItem = $this->Application->recallObject('rep.item', 'rep', Array('skip_autoload' => true));
/* @var $ReportItem kDBItem*/
- $a_grids = $this->Application->getUnitOption('rep', 'Grids');
- $a_fields = $a_grids['Default']['Fields'];
+ $grid = $this->Application->getUnitConfig('rep')->getGridByName('Default');
+ $a_fields = $grid['Fields'];
$ret = '';
foreach ($a_fields AS $field => $a_props)
{
$ret .= '<commas>'.$field.'<commas><tab>';
}
$ret = substr($ret, 0, strlen($ret) - 5).'<cr>';
$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) {
$ReportItem->SetFieldsFromHash($a_row);
$row = '';
foreach ($a_fields AS $field => $a_props)
{
$row .= '<commas>'.$ReportItem->GetField($field).'<commas><tab>';
$a_totals[$field] += $a_row[$field];
}
$ret .= substr($row, 0, strlen($row) - 5).'<cr>';
}
// totals
$ReportItem->SetFieldsFromHash($a_totals);
$counter = 0;
foreach ($a_fields AS $field => $a_props)
{
$counter++;
if ($counter == 1)
{
$row = '<commas><commas><tab>';
continue;
}
$row .= '<commas>'.$ReportItem->GetField($field).'<commas><tab>';
}
$ret .= substr($row, 0, strlen($row) - 5).'<cr>';
$ret = str_replace("\r",'', $ret);
$ret = str_replace("\n",'', $ret);
$ret = str_replace('"','\'\'', $ret);
$ret = str_replace('<commas>','"', $ret);
$ret = str_replace('<tab>',',', $ret);
$ret = str_replace('<cr>',"\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();
}
}
\ No newline at end of file
Index: branches/5.3.x/units/reports/reports_tag_processor.php
===================================================================
--- branches/5.3.x/units/reports/reports_tag_processor.php (revision 15694)
+++ branches/5.3.x/units/reports/reports_tag_processor.php (revision 15695)
@@ -1,438 +1,439 @@
<?php
/**
* @version $Id$
* @package In-Commerce
* @copyright Copyright (C) 1997 - 2009 Intechnic. All rights reserved.
* @license Commercial License
* This software 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
* See http://www.in-portal.org/commercial-license for copyright notices and details.
*/
defined('FULL_PATH') or die('restricted access!');
class ReportsTagProcessor extends kDBTagProcessor {
function ReportStatus($params)
{
$field_values = $this->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');
+ $a_virtual_fields = $this->Application->getUnitConfig('rep')->getVirtualFields();
+
foreach ($a_virtual_fields['Metric']['options'] AS $field => $label)
{
$metric = $field;
break;
}
}
$object = $this->Application->recallObject('rep.params', null, Array('skip_autoload' => true));
/* @var $object kDBItem */
$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
Index: branches/5.3.x/units/helpers/currency_rates.php
===================================================================
--- branches/5.3.x/units/helpers/currency_rates.php (revision 15694)
+++ branches/5.3.x/units/helpers/currency_rates.php (revision 15695)
@@ -1,153 +1,152 @@
<?php
/**
* @version $Id$
* @package In-Commerce
* @copyright Copyright (C) 1997 - 2009 Intechnic. All rights reserved.
* @license Commercial License
* This software 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
* See http://www.in-portal.org/commercial-license for copyright notices and details.
*/
defined('FULL_PATH') or die('restricted access!');
class CurrencyRates extends kBase {
var $RateSource;
var $ExchangeRates = Array();
/**
* Creates currency rate update class
*
* @access public
*/
public function __construct()
{
parent::__construct();
$this->GetRatesData();
}
function GetRatesData()
{
$cache_key = 'currency_rates[%CurrSerial%]';
$rates = $this->Application->getCache($cache_key);
$primary = $this->Application->GetPrimaryCurrency();
- if ($rates === false) {
+ if ( $rates === false ) {
$this->Conn->nextQueryCachable = true;
$sql = 'SELECT ISO, RateToPrimary
- FROM ' . $this->Application->getUnitOption('curr', 'TableName') . '
+ FROM ' . $this->Application->getUnitConfig('curr')->getTableName() . '
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)
- {
+
+ 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'];
+ 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)
- {
+ elseif ( $this->ExchangeRates[$source_cur]['TARGET'] == $target_cur ) {
$rate = $this->ExchangeRates[$source_cur]['RATE'];
}
- else
- {
+ 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, "&nbsp;"), Symbol)';
$sql = 'SELECT IF(SymbolPosition = 0, CONCAT(' . $symbol_sql . ', "%s"), CONCAT("%s", ' . $symbol_sql . ')), LOWER(ISO) AS ISO
- FROM ' . $this->Application->getUnitOption('curr', 'TableName') . '
+ FROM ' . $this->Application->getUnitConfig('curr')->getTableName() . '
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 ) {
$language = $this->Application->recallObject('lang.current');
/* @var $language LanguagesItem */
$decimal_separator = $language->GetDBField('DecimalPoint');
}
list ($integer_part, $decimal_part) = explode($decimal_separator, $value);
$value = $integer_part . $decimal_separator . '<' . $decimal_tag . '>' . $decimal_part . '</' . $decimal_tag . '>';
}
$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)
{
$curr_object = $this->Application->recallObject('curr', null, Array ('skip_autoload' => true));
/* @var $curr_object kDBItem */
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();
}
}
}
}
Index: branches/5.3.x/units/affiliate_payment_types/affiliate_payment_types_event_handler.php
===================================================================
--- branches/5.3.x/units/affiliate_payment_types/affiliate_payment_types_event_handler.php (revision 15694)
+++ branches/5.3.x/units/affiliate_payment_types/affiliate_payment_types_event_handler.php (revision 15695)
@@ -1,123 +1,126 @@
<?php
/**
* @version $Id$
* @package In-Commerce
* @copyright Copyright (C) 1997 - 2009 Intechnic. All rights reserved.
* @license Commercial License
* This software 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
* See http://www.in-portal.org/commercial-license for copyright notices and details.
*/
defined('FULL_PATH') or die('restricted access!');
class AffiliatePaymentTypesEventHandler extends kDBEventHandler {
/**
* Lists only active affiliate payment types on Front-End
*
* @param kEvent $event
* @return void
* @access protected
* @see kDBEventHandler::OnListBuild()
*/
protected function SetCustomQuery(kEvent $event)
{
parent::SetCustomQuery($event);
if ( !$this->Application->isAdmin ) {
$object = $event->getObject();
/* @var $object kDBList */
$object->addFilter('active', '%1$s.Status = ' . STATUS_ACTIVE);
}
}
/**
* Enter description here...
*
* @param kEvent $event
*/
function OnSetPrimary($event)
{
$object = $event->getObject();
/* @var $object kDBItem */
$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)
{
$object = $event->getObject();
/* @var $object kDBItem */
if ( $object->GetDBField('IsPrimary') && $object->Validate() ) {
- $sql = 'UPDATE ' . $this->Application->getUnitOption($event->Prefix, 'TableName') . '
+ $config = $event->getUnitConfig();
+
+ $sql = 'UPDATE ' . $config->getTableName() . '
SET IsPrimary = 0';
$this->Conn->Query($sql);
- $object->SetDBField($object->getStatusField(), 1);
+ $object->SetDBField($config->getStatusField(true), 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' ) {
+ $config = $event->getUnitConfig();
$ids = $event->getEventParam('ids');
- $sql = 'SELECT ' . $this->Application->getUnitOption($event->Prefix, 'IDField') . '
- FROM ' . $this->Application->getUnitOption($event->Prefix, 'TableName') . '
+ $sql = 'SELECT ' . $config->getIDField() . '
+ FROM ' . $config->getTableName() . '
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
Index: branches/5.3.x/units/shipping_quote_engines/usps.php
===================================================================
--- branches/5.3.x/units/shipping_quote_engines/usps.php (revision 15694)
+++ branches/5.3.x/units/shipping_quote_engines/usps.php (revision 15695)
@@ -1,1339 +1,1341 @@
<?php
/**
* @version $Id$
* @package In-Commerce
* @copyright Copyright (C) 1997 - 2009 Intechnic. All rights reserved.
* @license Commercial License
* This software 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
* See http://www.in-portal.org/commercial-license for copyright notices and details.
*/
defined('FULL_PATH') or die('restricted access!');
define('MODULE_SHIPPING_USPS_TEXT_TITLE', 'United States Postal Service');
define('MODULE_SHIPPING_USPS_TEXT_DESCRIPTION', 'You will need to have registered an account with USPS. Click <a target="_blank" href="https://secure.shippingapis.com/registration/"><strong>HERE</strong></a> 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.<br>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='<?xml version="1.0"?>';
// PASSWORD="'.$this->usps_password.'"
$request.= '<RateV3Request USERID="'.$this->usps_userid.'">';
$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 .= '<Package ID="'.$services_count.'">'.
'<Service>'.$key.'</Service>'.
'<ZipOrigination>'.$this->store_zip5.'</ZipOrigination>'.
'<ZipDestination>'.$dest_zip.'</ZipDestination>'.
'<Pounds>'.$this->pounds.'</Pounds>'.
'<Ounces>'.$this->ounces.'</Ounces>'.
'<Size>'.$this->size.'</Size>'.
'<Machinable>'.$this->machinable.'</Machinable>'.
'</Package>';
$services_count++;
}
$request .= '</RateV3Request>';
$api_query = 'RateV3';
}
else {
$request = '<IntlRateRequest USERID="'.$this->usps_userid.'">'.
'<Package ID="0">'.
'<Pounds>'.$this->pounds.'</Pounds>'.
'<Ounces>'.$this->ounces.'</Ounces>'.
'<MailType>Package</MailType>'.
'<Country>'.$this->countries[$this->order['ShippingCountry']].'</Country>'.
'</Package>'.
'</IntlRateRequest>';
$api_query = 'IntlRate';
}
$request = 'API='.$api_query.'&XML=' . urlencode($request);
$body = $this->PostQuery($request);
$body = str_replace(chr(146), '', $body); // for bad `
// check for errors
if (strpos($body, '<Error>') !== false) {
$errors = Array ();
preg_match_all('/<Number>(.*?)<\/Number>/s', $body, $error_numbers);
preg_match_all('/<Description>(.*?)<\/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('<br/>', $errors));
}
// parse response
$xml_helper = $this->Application->recallObject('kXMLHelper');
/* @var $xml_helper kXMLHelper */
$root_node =& $xml_helper->Parse($body);
/* @var $root_node kXMLNode */
$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 ='
<Option>1</Option>
<ImageParameters></ImageParameters>
<FromName>'.$this->store_name.'</FromName>
<FromFirm>'.$this->company_name.'</FromFirm>
<FromAddress1>'.$this->store_address1.'</FromAddress1>
<FromAddress2>'.$this->store_address2.'</FromAddress2>
<FromCity>'.$this->store_city.'</FromCity>
<FromState>'.$this->store_state.'</FromState>
<FromZip5>'.$this->store_zip5.'</FromZip5>
<FromZip4>'.$this->store_zip4.'</FromZip4>
<ToName>'.$this->order['FirstName'].' '.$this->order['LastName'].'</ToName>
<ToFirm>'.$this->order['ShippingCompany'].'</ToFirm>
<ToAddress1>'.$this->order['ShippingAddress2'].'</ToAddress1>
<ToAddress2>'.$this->order['ShippingAddress1'].'</ToAddress2>
<ToCity>'.$this->order['ShippingCity'].'</ToCity>
<ToState>'.$this->order['ShippingState'].'</ToState>
<ToZip5>'.$this->order['ShippingZip5'].'</ToZip5>
<ToZip4>'.$this->order['ShippingZip4'].'</ToZip4>
<WeightInOunces>'.$WeightInOunces.'</WeightInOunces>
<ServiceType>'.$this->order['ShippingService'].'</ServiceType>
<ImageType>PDF</ImageType>
<LabelDate>'.date('m/d/Y',time()).'</LabelDate>
<CustomerRefNo></CustomerRefNo>
<AddressServiceRequested></AddressServiceRequested>
<SenderName></SenderName><SenderEMail></SenderEMail>
<RecipientName></RecipientName>
<RecipientEMail></RecipientEMail>
';
$api_query = 'DeliveryConfirmationV3';
$xml_request = 'DeliveryConfirmationV3.0Request';
}
else {
// International Order(s)
$shipping_service = strtolower($this->order['ShippingService']);
$base_request = '<Option/>
<ImageParameters/>
<FromFirstName>'.$this->store_first_name.'</FromFirstName>
<FromLastName>'.$this->store_last_name.'</FromLastName>
<FromFirm>'.$this->company_name.'</FromFirm>
<FromAddress1>'.$this->store_address1.'</FromAddress1>
<FromAddress2>'.$this->store_address2.'</FromAddress2>
<FromCity>'.$this->store_city.'</FromCity>
<FromState>'.$this->store_state.'</FromState>
<FromZip5>'.$this->store_zip5.'</FromZip5>
<FromPhone>'.$this->PhoneClean($this->store_phone).'</FromPhone>
<ToName>'.$this->order['FirstName'].' '.$this->order['LastName'].'</ToName>
<ToFirm>'.$this->order['ShippingCompany'].'</ToFirm>
<ToAddress1></ToAddress1>
<ToAddress2>'.$this->order['ShippingAddress2'].'</ToAddress2>
<ToAddress3>'.$this->order['ShippingAddress1'].'</ToAddress3>
<ToCity>'.$this->order['ShippingCity'].'</ToCity>';
if ( $this->order['ShippingProvince'] != '' ) {
$base_request.='
<ToProvince>'.$this->order['ShippingProvince'].'</ToProvince>';
}
$base_request.='
<ToCountry>'.$this->countries[$this->order['ShippingCountry']].'</ToCountry>
<ToPostalCode>'.$this->order['ShippingZip'].'</ToPostalCode>
<ToPOBoxFlag>N</ToPOBoxFlag>
<ToPhone>'.$this->PhoneClean($this->order['ShippingPhone']).'</ToPhone>
<ToFax>'.$this->PhoneClean($this->order['ShippingFax']).'</ToFax>
<ToEmail>'.$this->order['Email'].'</ToEmail>
<ShippingContents>';
// add items
foreach ( $this->order['Items'] as $k => $value ) {
$base_request.='
<ItemDetail>
<Description>Computer Parts</Description>
<Quantity>'.$value['Qty'].'</Quantity>
<Value>'.($value['Price'] * $value['Qty']).'</Value>
<NetPounds>'.$value['NetPounds'].'</NetPounds>
<NetOunces>'.$value['NetOunces'].'</NetOunces>
<HSTariffNumber>123456</HSTariffNumber>
<CountryOfOrigin>United States</CountryOfOrigin>
</ItemDetail>';
}
// end add items
$base_request.='
</ShippingContents>
<GrossPounds>'.$this->pounds.'</GrossPounds>
<GrossOunces>'.$this->ounces.'</GrossOunces>
<ContentType>MERCHANDISE</ContentType>
<Agreement>Y</Agreement>
<InvoiceNumber>'.$this->order['InvoiceNumber'].'</InvoiceNumber>
<ImageType>PDF</ImageType>
<ImageLayout>ALLINONEFILE</ImageLayout>
<LabelDate>'.date('m/d/Y',time()).'</LabelDate>
';
if (strpos($shipping_service, 'express') !== false) {
$xml_request = 'ExpressMailIntlRequest';
$api_query = 'ExpressMailIntl';
}
elseif (strpos($shipping_service, 'priority') !== false) {
$xml_request = 'PriorityMailIntlRequest';
$api_query = 'PriorityMailIntl';
}
else {
$xml_request = 'FirstClassMailIntlRequest';
$api_query = 'FirstClassMailIntl';
}
}
$request.= '<'.$xml_request.' USERID="'.$this->usps_userid.'">';
$request.= $base_request;
$request.= '</'.$xml_request.'>';
// die($request);
$request = 'API='.$api_query.'&XML='.urlencode($request);
$body = $this->PostQuery($request, 1);
// check for errors
if (strpos($body, '<Error>') !== false) {
$errors = Array ();
preg_match_all('/<Number>(.*?)<\/Number>/s', $body, $error_numbers);
preg_match_all('/<Description>(.*?)<\/Description>/s', $body, $error_descriptions);
foreach ($error_numbers[1] as $index => $error_number) {
$errors[$index] = Array ('error_number' => $error_number, 'error_description' => $error_descriptions[1][$index]);
}
// TODO: find a way to return other error messages in same package as well
return $errors[0];
}
// parse response
$xml_helper = $this->Application->recallObject('kXMLHelper');
$root_node =& $xml_helper->Parse($body);
/* @var $root_node kXMLNode */
$Postage = 0;
$label_file = $TrackingNumber = $PostnetBarCode = '';
// Domestic shipping
if ($this->order['ShippingCountry'] == $this->shipping_origin_country ) {
$delivery_node =& $root_node->FindChild('DeliveryConfirmationV3.0Response');
do {
$TrackingNumber = $delivery_node->FindChildValue('DeliveryConfirmationNumber');
$PostnetBarCode = $delivery_node->FindChildValue('Postnet');
$DeliveryConfirmationLabel = base64_decode($delivery_node->FindChildValue('DeliveryConfirmationLabel'));
}
while ( $delivery_node =& $delivery_node->NextSibling());
}
else {
if (strpos($shipping_service, 'express') !== false) {
$node_title = 'ExpressMailIntlResponse';
}
elseif (strpos($shipping_service, 'priority') !== false) {
$node_title = 'PriorityMailIntlResponse';
}
else {
$node_title = 'FirstClassMailIntlResponse';
}
$delivery_node =& $root_node->FindChild($node_title);
$PostnetBarCode = $delivery_node->FindChildValue('BarcodeNumber');
$Postage = $delivery_node->FindChildValue('Postage');
$DeliveryConfirmationLabel = base64_decode($delivery_node->FindChildValue('LabelImage'));
}
if ( $TrackingNumber != '' ) {
$label_file = USPS_LABEL_FOLDER.$TrackingNumber.".pdf";
}
elseif ( $PostnetBarCode != '' ) {
$label_file = USPS_LABEL_FOLDER.$PostnetBarCode.".pdf";
}
if ( $label_file != '' ) {
$file_helper = $this->Application->recallObject('FileHelper');
/* @var $file_helper FileHelper */
$file_helper->CheckFolder(USPS_LABEL_FOLDER);
if (!$handle = fopen($label_file, 'a')) echo "Cannot open file ($label_file)";
if ( @fwrite($handle, $DeliveryConfirmationLabel) === FALSE) echo "Cannot write to file ($label_file)";
}
return array('TrackingNumber' => $TrackingNumber, 'PostnetBarCode' => $PostnetBarCode, 'Postage' => $Postage);
}
function GetUSPSCountry($country, $default = 'US')
{
$cs_helper = $this->Application->recallObject('CountryStatesHelper');
/* @var $cs_helper kCountryStatesHelper */
$country = $cs_helper->getCountryIso($country);
return $country == '' ? $default : $country;
}
function GetShippingQuotes($params = null)
{
$weights = kUtil::Kg2Pounds($params['packages']['0']['weight']);
$weight = '';
$weight = $weights[0];
if ( $weights[1] != '' ) {
$weight.='.'.$weights[1];
}
$country = $this->GetUSPSCountry($params['dest_country']);
$this->order = Array();
$this->order['ShippingWeight'] = $weight;
$this->order['ShippingNumBoxes'] = 1;
$this->order['ShippingZip'] = $params['dest_postal'];
$this->order['SubTotal'] = $params['amount'];
$this->order['ShippingCountry'] = $country;
$shipping_types = Array();
$rates = $this->GetQuote();
if ( !isset($rates['error']) ) {
$this->Application->RemoveVar('sqe_error');
$i = 1;
foreach ($rates as $k => $rate ) {
$shipping_types['USPS_'.$i] = Array(
'ShippingId' => 'USPS_'.$i,
'TotalCost' => $rate['Rate'],
'ShippingName' => $rate['Title'],
'Type' => '1',
'CODFlat' => '0',
'CODPercent' => '0',
'PortalGroups' => ',15,',
'InsuranceFee' => '',
'COD' => '0',
'SelectedOnly' => '0',
'Code' => $rate['Title']
);
$i++;
}
}
else {
// for Front-End (shipping screen) and Admin (Shipping Tab on editing order)
$this->Application->StoreVar('sqe_error', $rates['error']);
}
$this->Application->StoreVar('current_usps_shipping_types', serialize($shipping_types));
return $shipping_types;
}
function TrackOrder($TrackingNumber='')
{
if ( $TrackingNumber != '' ) {
// http://testing.shippingapis.com/ShippingAPITest.dll?API=TrackV2&XML=<TrackFieldRequest USERID="402INTEC7634"><TrackID ID="EJ958083578US"></TrackID></TrackFieldRequest>
$request = '<TrackRequest USERID="'.$this->usps_userid.'"><TrackID ID="'.$TrackingNumber.'"></TrackID></TrackRequest>';
$api_query = 'TrackV2';
$request = 'API='.$api_query.'&XML='.urlencode($request);
$body = $this->PostQuery($request);
// check for errors
if (strpos($body, '<Error>') !== false) {
$errors = Array ();
preg_match_all('/<Number>(.*?)<\/Number>/s', $body, $error_numbers);
preg_match_all('/<Description>(.*?)<\/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('<br/>', $errors));
}
$xml_helper = $this->Application->recallObject('kXMLHelper');
$root_node =& $xml_helper->Parse($body);
/* @var $root_node kXMLNode */
// Tracking Shipping
$delivery_node =& $root_node->FindChild('TrackInfo');
$TrackSummary = $delivery_node->FindChildValue('TrackSummary');
// echo ' TrackSummary ('.$TrackingNumber.') = '.$TrackSummary.'<br>';
return strpos($TrackSummary, 'delivered') !== false ? 1 : 0;
}
else
return false;
}
function ProcessTrackOrders()
{
$sql = sprintf('SELECT `OrderId`, `ShippingTracking` FROM %s WHERE `Status` > 3 AND `Delivered` = 0', TABLE_PREFIX.'Orders');
$orders = $this->Application->Conn->Query($sql);
foreach ( $orders as $k => $order ) {
// try to track order
if ( $order['ShippingTracking'] != '' && $this->TrackOrder($order['ShippingTracking']) ) {
+ $config = $this->Application->getUnitConfig('ord');
+
$update_order = sprintf("UPDATE %s SET `Delivered` = 1 WHERE %s = %s",
TABLE_PREFIX.'Orders',
- $this->Application->getUnitOption('ord', 'IDField'),
- $order[$this->Application->getUnitOption('ord', 'IDField')]
+ $config->getIDField(),
+ $order[$config->getIDField()]
);
$this->Application->Conn->Query($update_order);
}
}
}
function PostQuery($request, $secure=0)
{
switch (MODULE_SHIPPING_USPS_SERVER) {
case 'production':
$usps_server = $secure > 0 ? 'https://secure.shippingapis.com' : 'http://production.shippingapis.com' ;
$api_dll = 'ShippingAPI.dll';
break;
case 'test':
$usps_server = $secure > 0 ? 'https://secure.shippingapis.com' : 'http://testing.shippingapis.com';
$api_dll = 'ShippingAPITest.dll';
break;
}
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $usps_server.'/'.$api_dll.'?'.$request);
curl_setopt($curl, CURLOPT_HEADER, 0);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
$body = curl_exec($curl);
curl_close($curl);
if ($this->logFilePath) {
$fp = fopen($this->logFilePath, 'a');
if ($fp) {
$request_url = sprintf("Date %s : IP %s\n\nPost\n\n%s\n\nReplay\n\n%s\n\n",
adodb_date('m/d/Y H:i:s'),
$this->Application->getClientIp(),
$usps_server . '/' . $api_dll . '?' . urldecode($request),
$body
);
fwrite($fp, $request_url);
fclose($fp);
}
}
return $body;
}
/**
* Returns available shipping types
*
* @return Array
* @todo Get possible shipping types based on MODULE_SHIPPING_USPS_TYPES and MODULE_SHIPPING_USPS_TYPES_INTL consntants
*/
function GetAvailableTypes()
{
return Array (
Array (
'_ClassName' => get_class($this),
'_Id' => 'USPS',
'_Name' => 'USPS (Default)'
)
);
}
function LoadParams()
{
- $sql = 'SELECT Properties FROM '.$this->Application->getUnitOption('sqe', 'TableName').'
+ $sql = 'SELECT Properties FROM '.$this->Application->getUnitConfig('sqe')->getTableName().'
WHERE ClassName="USPS"';
$params = $this->Conn->GetOne($sql);
return unserialize($params);
}
function _prepare_xml_param($value) {
return strip_tags($value);
}
/**
* Returns virtual field names, that will be saved as properties
*
* @return Array
*/
function GetEngineFields()
{
return Array ('AccountLogin');
}
/**
* Creates new USPS order
*
* @param OrdersItem $object
* @param bool $dry_run
* @return Array
*/
function MakeOrder(&$object, $dry_run = false)
{
$ShippingInfo = unserialize($object->GetDBField('ShippingInfo'));
$ShippingCode = $USPSMethod = '';
$ShippingCountry = $this->GetUSPSCountry($object->GetDBField('ShippingCountry'));
$UserName = explode(" ", $object->GetDBField('ShippingTo'));
$item_table = TABLE_PREFIX.'OrderItems';
if ($this->Application->isAdminUser) {
// this strange contraption actually uses temp table from object (when in temp mode)
$order_table = $object->TableName;
$item_table = str_replace('Orders', 'OrderItems', $order_table);
}
$sOrder = Array (
'FirstName' => $UserName[0],
'LastName' => $UserName[1],
'ShippingCompany' => $object->GetDBField('ShippingCompany'),
'ShippingAddress1' => $object->GetDBField('ShippingAddress1'),
'ShippingAddress2' => $object->GetDBField('ShippingAddress2'),
'ShippingCity' => $object->GetDBField('ShippingCity'),
'ShippingZip' => $object->GetDBField('ShippingZip'),
'ShippingCountry' => $ShippingCountry,
'ShippingPhone' => $this->PhoneClean($object->GetDBField('ShippingPhone')),
'ShippingFax' => $this->PhoneClean($object->GetDBField('ShippingFax')),
'ShippingNumBoxes' => '1',
);
$sql = 'SELECT SUM(`Quantity` * `Weight`)
FROM ' . $item_table . '
WHERE ' . $object->IDField . ' = ' . $object->GetID();
$weight = $this->Application->Conn->GetOne($sql);
$f_weight = kUtil::Kg2Pounds($weight);
$sOrder['ShippingWeight'] = $f_weight[0].'.'.$f_weight[1];
foreach ($ShippingInfo as $k => $ShippingRow) {
$ShippingCode = $ShippingRow['Code'];
}
if ( $object->GetDBField('ShippingCountry') == 'USA' ) {
$sOrder['ShippingState'] = $object->GetDBField('ShippingState');
$USPSMethod = $ShippingCode;
unset($sOrder['ShippingZip']);
$sOrder['ShippingZip5'] = substr(trim($object->GetDBField('ShippingZip')), 0, 5);
$sOrder['ShippingZip4'] = '';
$sOrder['SubTotal'] = $object->GetDBField('SubTotal');
}
else {
$USPSMethod = array_search($ShippingCode, $this->intl_types);
$sOrder['ShippingProvince'] = '';
if ( $ShippingCountry == 'CA' ) {
$sOrder['ShippingProvince'] = $object->GetField('ShippingState');
}
// add items
$sql = 'SELECT `Quantity`, `Weight`, `Price`
FROM ' . $item_table . '
WHERE ' . $object->IDField . ' = ' . $object->GetID();
$order_items = $this->Application->Conn->Query($sql);
$i = 1;
$Items = Array();
foreach ($order_items as $k => $order_item) {
$p_weight = Array();
$p_weight = kUtil::Kg2Pounds($order_item['Weight']);
$Items[$i] = Array('Qty' => $order_item['Quantity'], 'Price' => $order_item['Price'], 'NetPounds' => $p_weight[0], 'NetOunces' => $p_weight[1]);
$i++;
}
$sOrder['Items'] = $Items;
$sOrder['InvoiceNumber'] = $object->GetDBField('OrderNumber');
}
$sOrder['ShippingService'] = $USPSMethod;
// make USPS order
$this->order = $sOrder;
$usps_data = $this->PostOrder();
// if errors
if ( array_key_exists('error_number', $usps_data) ) {
return $usps_data;
}
if ( array_key_exists('Postage', $usps_data) ) {
$ShippingPrice = '';
$ShippingPrice = $usps_data['Postage'];
}
$ShippingTracking = '';
if ( isset($usps_data['TrackingNumber']) && $usps_data['TrackingNumber'] != '' ) {
$ShippingTracking = $usps_data['TrackingNumber'];
}
if ( isset($usps_data['PostnetBarCode']) && $usps_data['PostnetBarCode'] != '' && $ShippingTracking == '' ) {
$ShippingTracking = $usps_data['PostnetBarCode'];
}
if ($dry_run == false) {
$object->SetDBField('ShippingTracking', $ShippingTracking);
$object->Update();
}
else {
$full_path = USPS_LABEL_FOLDER . $ShippingTracking . ".pdf";
if (file_exists($full_path)) {
unlink($full_path);
}
}
return $usps_data;
}
}
\ No newline at end of file
Index: branches/5.3.x/units/shipping_quote_engines/intershipper.php
===================================================================
--- branches/5.3.x/units/shipping_quote_engines/intershipper.php (revision 15694)
+++ branches/5.3.x/units/shipping_quote_engines/intershipper.php (revision 15695)
@@ -1,517 +1,517 @@
<?php
/**
* @version $Id$
* @package In-Commerce
* @copyright Copyright (C) 1997 - 2009 Intechnic. All rights reserved.
* @license Commercial License
* This software 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
* See http://www.in-portal.org/commercial-license for copyright notices and details.
*/
defined('FULL_PATH') or die('restricted access!');
class Intershipper extends ShippingQuoteEngine {
var $state = Array();
var $quote = Array();
var $quotes = Array();
var $package_id;
var $box_id;
var $shipment_id;
var $FlatSurcharge = 0;
var $PercentSurcharge = 0;
function _stripTags($params)
{
foreach ($params as $param_name => $param_value) {
if (is_array($param_value)) {
$params[$param_name] = $this->_stripTags($param_value);
}
else {
$params[$param_name] = strip_tags($param_value);
}
}
return $params;
}
function BuildUrl($params = null)
{
$params = $this->_stripTags($params);
$this->shipment_id = isset($params['shipment_id']) ? $params['shipment_id'] : $this->GenerateId();
$url = 'www.intershipper.com/Interface/Intershipper/XML/v2.0/HTTP.jsp';
$uri = 'Username='. $params['AccountLogin'].
'&Password='. $params['AccountPassword'].
'&Version='. '2.0.0.0'.
'&ShipmentID='. $this->shipment_id.
'&QueryID='. $this->shipment_id.
'&TotalCarriers='. count($params['carriers']);
$i = 0;
foreach($params['carriers'] as $carrier)
{
$i++;
$uri .= '&CarrierCode'.$i.'='. rawurlencode($carrier['name']).
'&CarrierAccount'.$i.'='. rawurlencode($carrier['account']).
'&CarrierInvoiced'.$i.'='. $carrier['invoiced'];
}
$uri .= '&TotalClasses='. count($params['classes']);
$i = 0;
foreach($params['classes'] as $class)
{
$i++;
$uri .= '&ClassCode'.$i.'='. $class;
}
$uri .= '&DeliveryType='. 'COM'.
'&ShipMethod='. $params['ShipMethod'].
'&OriginationName='. rawurlencode( $params['orig_name'] ).
'&OriginationAddress1='.rawurlencode( $params['orig_addr1'] ).
'&OriginationAddress2='.rawurlencode( $params['orig_addr2'] ).
'&OriginationCity='. rawurlencode( $params['orig_city'] ).
'&OriginationState='. rawurlencode( $params['orig_state'] ).
'&OriginationPostal='. rawurlencode( $params['orig_postal'] ).
'&OriginationCountry='. rawurlencode( $params['orig_country'] ).
'&DestinationName='. rawurlencode( $params['dest_name'] ).
'&DestinationAddress1='.rawurlencode( $params['dest_addr1'] ).
'&DestinationAddress2='.rawurlencode( $params['dest_addr2'] ).
'&DestinationCity='. rawurlencode( $params['dest_city'] ).
'&DestinationState='. rawurlencode( $params['dest_state'] ).
'&DestinationPostal='. rawurlencode( $params['dest_postal'] ).
'&DestinationCountry='. rawurlencode( $params['dest_country'] ).
'&Currency='. 'USD'.
'&TotalPackages='. count($params['packages']);
$i = 0;
foreach($params['packages'] as $package)
{
$i++;
$uri .= '&BoxID'.$i.'='. urlencode( $package['package_key'] ).
'&Weight'.$i.'='. $package['weight'].
'&WeightUnit'.$i.'='. $package['weight_unit'].
'&Length'.$i.'='. $package['length'].
'&Width'.$i.'='. $package['width'].
'&Height'.$i.'='. $package['height'].
'&DimensionalUnit'.$i.'='. $package['dim_unit'].
'&Packaging'.$i.'='. $package['packaging'].
'&Contents'.$i.'='. $package['contents'].
'&Insurance'.$i.'='. $package['insurance'];
}
return Array('url' => $url, 'uri' => $uri);
}
function MergeParams($custom_params)
{
$params = $this->LoadParams();
$this->FlatSurcharge = $params['FlatSurcharge'];
$this->PercentSurcharge = $params['PercentSurcharge'];
if($custom_params['carriers'])
{
$params['carriers'] = $custom_params['carriers'];
}
else
{
$carrier_codes = Array('UPS', 'FDX', 'DHL', 'USP', 'ARB');
$i = 0;
foreach($carrier_codes as $carrier)
{
if(isset($params[$carrier.'Enabled']) && $params[$carrier.'Enabled'])
{
$i++;
$params['carriers'][$i]['name'] = $carrier;
$params['carriers'][$i]['account'] = $params[$carrier.'Account'];
$params['carriers'][$i]['invoiced'] = (int) $params[$carrier.'Invoiced'];
}
}
}
if($custom_params['classes'])
{
$params['classes'] = $custom_params['classes'];
}
else
{
$classes = Array('1DY', '2DY', '3DY', 'GND');
foreach($classes as $class)
{
if(isset($params[$class.'Enabled']) && $params[$class.'Enabled'])
{
$params['classes'][] = $class;
}
}
}
if (isset($custom_params['orig_addr1'])) {
$params['orig_name'] = $custom_params['orig_name'];
$params['orig_addr1'] = $custom_params['orig_addr1'];
$params['orig_addr2'] = $custom_params['orig_addr2'];
$params['orig_city'] = $custom_params['orig_city'];
$params['orig_state'] = $custom_params['orig_state'];
$params['orig_postal'] = $custom_params['orig_postal'];
$params['orig_country'] = $custom_params['orig_country'];
}
else {
$params['orig_name'] = $this->Application->ConfigValue('Comm_StoreName');
$params['orig_addr1'] = $this->Application->ConfigValue('Comm_Shipping_AddressLine1');
$params['orig_addr2'] = $this->Application->ConfigValue('Comm_Shipping_AddressLine2');
$params['orig_city'] = $this->Application->ConfigValue('Comm_Shipping_City');
$params['orig_state'] = $this->Application->ConfigValue('Comm_Shipping_State');
$params['orig_postal'] = $this->Application->ConfigValue('Comm_Shipping_ZIP');
$params['orig_country'] = $this->Application->ConfigValue('Comm_Shipping_Country');
}
$cs_helper = $this->Application->recallObject('CountryStatesHelper');
/* @var $cs_helper kCountryStatesHelper */
if (strlen($params['orig_country']) == 3) {
// got 3symbol ISO code -> resolve to 2symbol ISO code
$params['orig_country'] = $cs_helper->getCountryIso( $params['orig_country'] );
}
if (strlen($params['orig_state']) != 2) {
// got state name instead of ISO code -> resolve it to ISO code
$country_iso = $cs_helper->getCountryIso($params['orig_country'], true);
$params['orig_state'] = $cs_helper->getStateIso($params['orig_state'], $country_iso);
}
if (isset($custom_params['ShipMethod'])) {
$params['ShipMethod'] = $custom_params['ShipMethod'];
}
$params['packages'] = $custom_params['packages'];
$params['dest_name'] = $custom_params['dest_name'];
$params['dest_addr1'] = $custom_params['dest_addr1'];
$params['dest_addr2'] = $custom_params['dest_addr2'];
$params['dest_city'] = $custom_params['dest_city'];
$params['dest_state'] = $custom_params['dest_state'];
$params['dest_postal'] = $custom_params['dest_postal'];
$params['dest_country'] = $custom_params['dest_country'];
if (strlen($params['dest_country']) == 3) {
// got 3symbol ISO code -> resolve to 2symbol ISO code
$params['dest_country'] = $cs_helper->getCountryIso( $params['dest_country'] );
}
if(!$params['dest_city'] || !$params['dest_country'] ||
(($params['dest_country'] == 'US' || $params['dest_country'] == 'CA') && !$params['dest_state']) ||
!$params['dest_postal'] || !$params['packages'])
{
$valid = false;
}
else
{
$valid = true;
}
return $valid ? $params : false;
}
function GenerateId()
{
static $id;
if(!$id)
{
$id = rand(0, 1000000);
}
return $id;
}
function getShipmentId()
{
return $this->shipment_id;
}
function GetShippingQuotes($params = null)
{
if(!is_array($params)) $params = unserialize($params);
$params = $this->MergeParams($params);
if($params == false)
{
trigger_error('Incorrect params given to <em>intershipper</em> engine', E_USER_WARNING);
return;
}
$target_url = $this->BuildUrl($params);
// print_r($target_url);
$depth = Array();
$xml_parser = xml_parser_create();
xml_set_element_handler( $xml_parser, Array(&$this, 'startElement'), Array(&$this, 'endElement') );
xml_set_character_data_handler( $xml_parser, Array(&$this, 'characterData') );
$curl_helper = $this->Application->recallObject('CurlHelper');
/* @var $curl_helper kCurlHelper */
$curl_helper->SetPostData($target_url['uri']);
$newdata = $curl_helper->Send($target_url['url']);
$newdata = substr($newdata, strpos($newdata, '<'));
if (!xml_parse($xml_parser, $newdata, 1)) {
trigger_error(sprintf('XML error: %s at line %d'),
xml_error_string(xml_get_error_code($xml_parser)),
xml_get_current_line_number($xml_parser), E_USER_WARNING);
}
xml_parser_free($xml_parser);
return array_shift($this->quotes); // array_shift must be removed after!!!
}
function startElement(&$Parser, &$Elem, $Attr)
{
array_push($this->state, $Elem);
$states = implode(' ',$this->state);
//check what state we are in
if($states == 'SHIPMENT PACKAGE') {
$this->package_id = $Attr['ID'];
}
elseif($states == 'SHIPMENT PACKAGE QUOTE') {
$quote = Array('package_id' => $this->package_id, 'id' => $Attr['ID']);
}
}
function characterData($Parser, $Line)
{
$states = join (' ',$this->state);
switch($states)
{
case 'SHIPMENT ERROR':
trigger_error($error = $Line, E_USER_WARNING);
break;
case 'SHIPMENT SHIPMENTID':
$this->shipment_id = $Line;
break;
case 'SHIPMENT PACKAGE BOXID':
$this->box_id = $Line;
break;
case 'SHIPMENT PACKAGE QUOTE CARRIER NAME':
$this->quote['carrier_name'] = $Line;
break;
case 'SHIPMENT PACKAGE QUOTE CARRIER CODE':
$this->quote['carrier_code'] = $Line;
break;
case 'SHIPMENT PACKAGE QUOTE CLASS NAME':
$this->quote['class_name'] = $Line;
break;
case 'SHIPMENT PACKAGE QUOTE CLASS CODE':
$this->quote['class_code'] = $Line;
break;
case 'SHIPMENT PACKAGE QUOTE SERVICE NAME':
$this->quote['service_name'] = $Line;
break;
case 'SHIPMENT PACKAGE QUOTE SERVICE CODE':
$this->quote['service_code'] = $Line;
break;
case 'SHIPMENT PACKAGE QUOTE RATE AMOUNT':
$this->quote['amount'] = $Line / 100;
break;
default:
}
}
function endElement($Parser, $Elem)
{
$states = implode(' ',$this->state);
if ($states == 'SHIPMENT PACKAGE QUOTE') {
unset($this->quote['id']);
unset($this->quote['package_id']);
// the $key is a combo of the carrier_code and service_code
// this is the logical way to key each quote returned
$this->quote['amount'] = $this->quote['amount']*(1+$this->PercentSurcharge/100) + $this->FlatSurcharge;
$amount_plain = $this->quote['amount'] * 100;
$key = 'INTSH_'.$this->quote['carrier_code'].'_'.$this->quote['class_code'].'_'.$amount_plain;
$this->quote['ShippingId'] = $key;
$this->quote['ShippingName'] = $this->quote['carrier_code'].' - '.$this->quote['service_name'];
$this->quote['TotalCost'] = $this->quote['amount'];
$this->quotes[$this->box_id][$key] = $this->quote;
}
array_pop($this->state);
}
function LoadParams()
{
- $sql = 'SELECT Properties, FlatSurcharge, PercentSurcharge FROM '.$this->Application->getUnitOption('sqe', 'TableName').'
+ $sql = 'SELECT Properties, FlatSurcharge, PercentSurcharge FROM '.$this->Application->getUnitConfig('sqe')->getTableName().'
WHERE Name="Intershipper.com"';
$data = $this->Conn->GetRow($sql);
$params = unserialize(getArrayValue($data, 'Properties'));
return array_merge($params, array('FlatSurcharge' => $data['FlatSurcharge'], 'PercentSurcharge' => $data['PercentSurcharge']));
}
function GetAvailableTypes()
{
$params = $this->LoadParams();
$carrier_codes = Array('UPS', 'FDX', 'DHL', 'USP', 'ARB');
$classes = Array('1DY', '2DY', '3DY', 'GND');
$i = 0;
foreach($carrier_codes as $carrier)
{
if(isset($params[$carrier.'Enabled']) && $params[$carrier.'Enabled'])
{
foreach($classes as $class)
{
if(isset($params[$class.'Enabled']) && $params[$class.'Enabled'])
{
$a_type['_ClassName'] = get_class($this);
$a_type['_Id'] = 'INTSH_'.$carrier.'_'.$class;
$a_type['_Name'] = '(Intershipper) '.$carrier.' '.$class;
$ret[] = $a_type;
}
}
}
}
return $ret;
}
/**
* Returns virtual field names, that will be saved as properties
*
* @return Array
*/
function GetEngineFields()
{
return Array (
'AccountLogin',
'UPSEnabled', 'UPSAccount', 'UPSInvoiced', 'FDXEnabled', 'FDXAccount', 'FDXInvoiced',
'DHLEnabled', 'DHLAccount', 'DHLInvoiced', 'USPEnabled', 'USPAccount', 'USPInvoiced',
'ARBEnabled', 'ARBAccount', 'ARBInvoiced', '1DYEnabled', '2DYEnabled', '3DYEnabled',
'GNDEnabled', 'ShipMethod',
);
}
}
/*$params = Array(
'AccountLogin' => 'login',
'AccountPassword' => 'password',
'carriers' => Array(
Array(
'name' => 'UPS',
'account' => '',
'invoiced' => '0'
),
Array(
'name' => 'DHL',
'account' => '',
'invoiced' => '0'
),
Array(
'name' => 'FDX',
'account' => '',
'invoiced' => '0'
),
Array(
'name' => 'USP',
'account' => '',
'invoiced' => '0'
),
Array(
'name' => 'ARB',
'account' => '',
'invoiced' => '0'
),
),
'classes' => Array('1DY', '2DY', '3DY', 'GND'),
'ShipMethod' => 'DRP',
'orig_name' => 'John%20Smith',
'orig_addr1' => '2275%20Union%20Road',
'orig_city' => 'Cheektowaga',
'orig_state' => 'NY',
'orig_postal' => '14227',
'orig_country' => 'US',
// this section is required
'dest_name' => 'Vasya%20Pupkin',
'dest_addr1' => '175%20E.Hawthorn%20pkwy.',
'dest_city' => 'Vernon%20Hills',
'dest_state' => 'IL',
'dest_postal' => '60061',
'dest_country' => 'US',
// this section is required
'packages' => Array(
Array(
'package_key' => 'package1',
'weight' => '50',
'weight_unit' => 'LB',
'length' => '25',
'width' => '15',
'height' => '15',
'dim_unit' => 'IN',
'packaging' => 'BOX',
'contents' => 'OTR',
'insurance' => '0'
),
Array(
'package_key' => 'package2',
'weight' => '50',
'weight_unit' => 'LB',
'length' => '25',
'width' => '15',
'height' => '15',
'dim_unit' => 'IN',
'packaging' => 'BOX',
'contents' => 'OTR',
'insurance' => '0'
),
),
'shipment_id' => 1234;
);
*/
/*
Returns:
$quotes = Array(
'package1' =>
Array(
Array(
'id' => 'INTSH_FDX_2DY',
'type' => 'FDX',
..
'amount' => 24.24,
)
Array(
'type' => 'FDX',
..
'amount' => 24.24,
)
),
'package2' =>
Array(
Array(
'id' => 'INTSH_FDX_3DY',
'type' => 'FDX',
..
'amount' => 24.24,
)
Array(
'type' => 'FDX',
..
'amount' => 24.24,
)
),
)
*/
\ No newline at end of file
Index: branches/5.3.x/units/shipping_quote_engines/shipping_quote_engine.php
===================================================================
--- branches/5.3.x/units/shipping_quote_engines/shipping_quote_engine.php (revision 15694)
+++ branches/5.3.x/units/shipping_quote_engines/shipping_quote_engine.php (revision 15695)
@@ -1,209 +1,209 @@
<?php
/**
* @version $Id$
* @package In-Commerce
* @copyright Copyright (C) 1997 - 2009 Intechnic. All rights reserved.
* @license Commercial License
* This software 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
* See http://www.in-portal.org/commercial-license for copyright notices and details.
*/
defined('FULL_PATH') or die('restricted access!');
class ShippingQuoteEngine extends kHelper {
/**
* Quote engine specific properties
*
* @var Array
*/
var $properties = Array ();
public function __construct()
{
parent::__construct();
$this->initProperties();
}
/**
* $params = Array(
* 'AccountLogin' => 'login',
* 'AccountPassword' => 'pass',
* 'carriers' => Array(
* Array(
* 'name' => 'UPS',
* 'account' => '',
* 'invoiced' => '0'
* ),
* Array(
* 'name' => 'DHL',
* 'account' => '',
* 'invoiced' => '0'
* ),
* Array(
* 'name' => 'FDX',
* 'account' => '',
* 'invoiced' => '0'
* ),
* Array(
* 'name' => 'USP',
* 'account' => '',
* 'invoiced' => '0'
* ),
* Array(
* 'name' => 'ARB',
* 'account' => '',
* 'invoiced' => '0'
* ),
* ),
* 'classes' => Array('1DY', '2DY', '3DY', 'GND'),
*
* 'ShipMethod' => 'DRP',
*
* 'orig_name' => 'John%20Smith',
* 'orig_addr1' => '2275%20Union%20Road',
* 'orig_city' => 'Cheektowaga',
* 'orig_state' => 'NY',
* 'orig_postal' => '14227',
* 'orig_country' => 'US',
*
* // this section is required
* 'dest_name' => 'Vasya%20Pupkin',
* 'dest_addr1' => '175%20E.Hawthorn%20pkwy.',
* 'dest_city' => 'Vernon%20Hills',
* 'dest_state' => 'IL',
* 'dest_postal' => '60061',
* 'dest_country' => 'US',
*
* // this section is required
* 'packages' => Array(
* Array(
* 'package_key' => 'package1',
* 'weight' => '50',
* 'weight_unit' => 'LB',
* 'length' => '25',
* 'width' => '15',
* 'height' => '15',
* 'dim_unit' => 'IN',
* 'packaging' => 'BOX',
* 'contents' => 'OTR',
* 'insurance' => '0'
* ),
* Array(
* 'package_key' => 'package2',
* 'weight' => '50',
* 'weight_unit' => 'LB',
* 'length' => '25',
* 'width' => '15',
* 'height' => '15',
* 'dim_unit' => 'IN',
* 'packaging' => 'BOX',
* 'contents' => 'OTR',
* 'insurance' => '0'
* ),
* ),
*
* 'shipment_id' => 1234;
* );
*
*
* Returns:
*
* $quotes = Array(
* 'package1' =>
* Array(
* Array(
* 'id' => 'INTSH_FDX_2DY',
* 'type' => 'FDX',
* ..
* 'amount' => 24.24,
* )
* Array(
* 'type' => 'FDX',
* ..
* 'amount' => 24.24,
* )
* ),
* 'package2' =>
* Array(
* Array(
* 'id' => 'INTSH_FDX_3DY',
* 'type' => 'FDX',
* ..
* 'amount' => 24.24,
* )
* Array(
* 'type' => 'FDX',
* ..
* 'amount' => 24.24,
* )
* ),
* )
*
* @param Array $params
*/
function GetShippingQuotes($params)
{
}
/**
* Returns list of shipping types, that can be selected on product editing page
*
* @return Array
*/
function GetAvailableTypes()
{
return Array ();
}
/**
* Returns virtual field names, that will be saved as properties
*
* @return Array
*/
function GetEngineFields()
{
return Array ();
}
/**
* Sends order to shipping quote engine
*
* @param OrdersItem $object
* @param bool $dry_run
* @return Array
*/
function MakeOrder(&$object, $dry_run = false)
{
return Array ();
}
/**
* Loads properties of shipping quote engine
*
*/
function initProperties()
{
$sql = 'SELECT Properties, FlatSurcharge, PercentSurcharge
- FROM ' . $this->Application->getUnitOption('sqe', 'TableName') . '
+ FROM ' . $this->Application->getUnitConfig('sqe')->getTableName() . '
WHERE LOWER(ClassName) = ' . $this->Conn->qstr( strtolower( get_class($this) ) );
$data = $this->Conn->GetRow($sql);
if (is_array($data)) {
$properties = $data['Properties'] ? unserialize($data['Properties']) : Array ();
$properties['FlatSurcharge'] = $data['FlatSurcharge'];
$properties['PercentSurcharge'] = $data['PercentSurcharge'];
$this->properties = $properties;
}
else {
$this->properties = Array ();
}
}
}
\ No newline at end of file
Index: branches/5.3.x/units/shipping_quote_engines/shipping_quote_collector.php
===================================================================
--- branches/5.3.x/units/shipping_quote_engines/shipping_quote_collector.php (revision 15694)
+++ branches/5.3.x/units/shipping_quote_engines/shipping_quote_collector.php (revision 15695)
@@ -1,197 +1,197 @@
<?php
/**
* @version $Id$
* @package In-Commerce
* @copyright Copyright (C) 1997 - 2009 Intechnic. All rights reserved.
* @license Commercial License
* This software 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
* See http://www.in-portal.org/commercial-license for copyright notices and details.
*/
defined('FULL_PATH') or die('restricted access!');
class ShippingQuoteCollector extends ShippingQuoteEngine {
function GetShippingQuotes($params)
{
$cs_helper = $this->Application->recallObject('CountryStatesHelper');
/* @var $cs_helper kCountryStatesHelper */
$has_states = $cs_helper->CountryHasStates( $cs_helper->getCountryIso($params['dest_country'], true) );
if (
!$params['dest_city'] || !$params['dest_country'] ||
($has_states && !$params['dest_state']) ||
!$params['dest_postal'] || !$params['packages']
) {
return Array ();
}
$cached_var_name = 'ShippingQuotes' . crc32(serialize($params));
$shipping_types = $this->Application->getDBCache($cached_var_name);
if ($shipping_types) {
return unserialize($shipping_types);
}
$quotes_valid = true;
$shipping_types = Array();
$classes = $this->getEngineClasses();
foreach ($classes as $class) {
$object = $this->Application->recallObject($class);
/* @var $object ShippingQuoteEngine */
$new_shipping_types = $object->GetShippingQuotes($params);
if (is_array($new_shipping_types)) {
$shipping_types = array_merge($shipping_types, $new_shipping_types);
}
else {
$quotes_valid = false;
}
}
uasort($shipping_types, Array(&$this, 'price_sort'));
// exclude not available shipping quotes by products
$limit_types = unserialize($params['limit_types']);
if (is_array($limit_types) && !in_array('ANY', $limit_types)) {
if (count($limit_types) == 0) {
break;
}
$available_types = Array ();
foreach ($shipping_types as $a_type) {
$include = false; // exclude by default
foreach ($limit_types as $limit) {
$include = $include || preg_match("/^$limit/", $a_type['ShippingId']);
if ($include) {
break;
}
}
if (!$include) {
continue;
}
$available_types[ $a_type['ShippingId'] ] = $a_type;
}
$shipping_types = $available_types;
}
// exclude Selected Products Only shipping types, not matching products
$available_types = Array();
foreach ($shipping_types as $a_type) {
if (getArrayValue($a_type, 'SelectedOnly')) {
if (!is_array($limit_types) || !in_array($a_type['ShippingId'], $limit_types)) {
continue;
}
}
$available_types[ $a_type['ShippingId'] ] = $a_type;
}
$shipping_types = $available_types;
if ($quotes_valid) {
$this->Application->setDBCache($cached_var_name, serialize($shipping_types), 24 * 3600);
}
return $shipping_types;
}
function GetAvailableShippingTypes()
{
$shipping_types = Array ();
$classes = $this->getEngineClasses();
foreach ($classes as $class) {
$object = $this->Application->recallObject($class);
/* @var $object ShippingQuoteEngine */
$new_shipping_types = $object->GetAvailableTypes();
$shipping_types = array_merge($shipping_types, $new_shipping_types);
}
uasort($shipping_types, Array(&$this, 'SortShippingTypes'));
return $shipping_types;
}
/**
* Returns all enabled shipping quote engine classes
*
* @return Array
*/
function getEngineClasses()
{
$sql = 'SELECT Classname
- FROM ' . $this->Application->getUnitOption('sqe', 'TableName') . '
+ FROM ' . $this->Application->getUnitConfig('sqe')->getTableName() . '
WHERE Status = ' . STATUS_ACTIVE;
$classes = $this->Conn->GetCol($sql);
// always persists
$classes[] = 'CustomShippingQuoteEngine';
return $classes;
}
/**
* Returns shipping quote engine, that matches shipping type used in order
*
* @param Array $shipping_info
* @param int $package_num
* @return ShippingQuoteEngine
*/
function &GetClassByType($shipping_info, $package_num = 1)
{
if ( !$shipping_info || !array_key_exists($package_num, $shipping_info) ) {
return false;
}
$classes = $this->getEngineClasses();
$shipping_id = $shipping_info[$package_num]['ShippingId'];
foreach ($classes as $class) {
$object = $this->Application->recallObject($class);
/* @var $object ShippingQuoteEngine */
$shipping_types = $object->GetAvailableTypes();
foreach ($shipping_types as $index => $shipping_type) {
if ( preg_match('/^' . preg_quote($shipping_type['_Id'], '/') . '/', $shipping_id) ) {
return $class;
}
}
}
return false;
}
function SortShippingTypes($elem1, $elem2)
{
if ($elem1['_Name'] == $elem2['_Name']) {
return 0;
}
return $elem1['_Name'] < $elem2['_Name'] ? -1 : 1;
}
function price_sort($elem1, $elem2)
{
if ($elem1['TotalCost'] == $elem2['TotalCost']) {
return 0;
}
return $elem1['TotalCost'] < $elem2['TotalCost'] ? -1 : 1;
}
}
\ No newline at end of file
Index: branches/5.3.x/units/product_option_combinations/product_option_combinations_event_handler.php
===================================================================
--- branches/5.3.x/units/product_option_combinations/product_option_combinations_event_handler.php (revision 15694)
+++ branches/5.3.x/units/product_option_combinations/product_option_combinations_event_handler.php (revision 15695)
@@ -1,443 +1,443 @@
<?php
/**
* @version $Id$
* @package In-Commerce
* @copyright Copyright (C) 1997 - 2009 Intechnic. All rights reserved.
* @license Commercial License
* This software 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
* See http://www.in-portal.org/commercial-license for copyright notices and details.
*/
defined('FULL_PATH') or die('restricted access!');
class ProductOptionCombinationsEventHandler extends kDBEventHandler {
/**
* Apply custom processing to item
*
* @param kEvent $event
* @param string $type
* @return void
* @access protected
*/
protected function customProcessing(kEvent $event, $type)
{
if ( $type == 'after' ) {
return;
}
switch ($event->Name) {
case 'OnCreate':
case 'OnUpdate':
$object = $event->getObject();
/* @var $object kDBItem */
$options = unserialize($object->GetDBField('Combination'));
ksort($options);
$object->SetDBField('CombinationCRC', kUtil::crc32(serialize($options)));
break;
case 'OnMassDelete':
// delete only option combinations that has no associated inventory
$object = $event->getObject();
/* @var $object kDBItem */
$ids = $event->getEventParam('ids');
$sql = 'SELECT ' . $object->IDField . '
FROM ' . $object->TableName . '
WHERE (' . $object->IDField . ' IN (' . implode(',', $ids) . ')) AND
(QtyInStock = 0) AND (QtyReserved = 0) AND (QtyBackOrdered = 0) AND (QtyOnOrder = 0)';
$event->setEventParam('ids', $this->Conn->GetCol($sql));
break;
}
}
/**
* GetOptionValues
*
* @param kEvent $event
*/
function GetOptionValues($event, $option_id)
{
$object = $event->getObject();
if ($object->IsTempTable()) {
$table = $this->Application->GetTempName(TABLE_PREFIX.'ProductOptions', 'prefix:'.$event->Prefix);
}
else {
$table = TABLE_PREFIX.'ProductOptions';
}
$query = 'SELECT `Values` FROM '.$table.' WHERE ProductOptionId = '.$option_id;
return explode(',', $this->Conn->GetOne($query));
}
function CreateCombinations($event, $fields, $current_option=null)
{
$recursed = false;
$combination = $fields['Combination'];
foreach ($combination as $option_id => $option)
{
if ($option_id == $current_option || $recursed) continue;
if ($option == '_ANY_') {
$recursed = true;
$values = $this->GetOptionValues($event, $option_id);
foreach ($values as $a_value) {
$fields['Combination'][$option_id] = $a_value;
$this->CreateCombinations($event, $fields, $option_id);
}
}
}
if (!$recursed) {
$object = $event->getObject();
/* @var $object kDBItem */
$salt = $fields['Combination'];
ksort($salt);
$object->Load(kUtil::crc32(serialize($salt)), 'CombinationCRC');
$object->SetFieldsFromHash($fields);
$this->customProcessing($event,'before');
if ( $object->isLoaded() ) { // Update if such combination already exists
if( $object->Update() )
{
$this->customProcessing($event,'after');
$event->status=kEvent::erSUCCESS;
}
}
else {
if( $object->Create($event->getEventParam('ForceCreateId')) )
{
$this->customProcessing($event,'after');
$event->status=kEvent::erSUCCESS;
}
}
}
}
function UpdateCombinations($event, $fields, $current_option=null)
{
$recursed = false;
$combination = $fields['Combination'];
foreach ($combination as $option_id => $option)
{
if ($option_id == $current_option || $recursed) continue;
if ($option == '_ANY_') {
$recursed = true;
$values = $this->GetOptionValues($event, $option_id);
foreach ($values as $a_value) {
$fields['Combination'][$option_id] = $a_value;
$this->UpdateCombinations($event, $fields, $option_id);
}
}
}
if (!$recursed) {
$object = $event->getObject();
/* @var $object kDBItem */
$edit_id = $object->GetId();
$salt = $fields['Combination'];
ksort($salt);
// try to load combination by salt - if loaded, it will update the combination
$object->Load(kUtil::crc32(serialize($salt)), 'CombinationCRC');
if ( !$object->isLoaded() ) {
$object->Load($edit_id);
}
$object->SetFieldsFromHash($fields);
$this->customProcessing($event,'before');
if( $object->Update() )
{
$this->customProcessing($event,'after');
$event->status=kEvent::erSUCCESS;
}
}
}
/**
* Creates new kDBItem
*
* @param kEvent $event
* @return void
* @access protected
*/
protected function OnCreate(kEvent $event)
{
$object = $event->getObject(Array ('skip_autoload' => true));
/* @var $object kDBItem */
$items_info = $this->Application->GetVar($event->getPrefixSpecial(true));
if ( !$items_info ) {
return;
}
list($id, $field_values) = each($items_info);
$object->SetFieldsFromHash($field_values, $this->getRequestProtectedFields($field_values));
if ( !$object->Validate() ) {
$event->status = kEvent::erFAIL;
$event->redirect = false;
$this->Application->SetVar($event->getPrefixSpecial() . '_SaveEvent', 'OnCreate');
$object->setID($id);
return;
}
$this->CreateCombinations($event, $field_values);
}
/**
* Updates kDBItem
*
* @param kEvent $event
* @return void
* @access protected
*/
protected function OnUpdate(kEvent $event)
{
$object = $event->getObject( Array('skip_autoload' => true) );
/* @var $object kDBItem */
$items_info = $this->Application->GetVar( $event->getPrefixSpecial(true) );
if($items_info)
{
foreach($items_info as $id => $field_values)
{
$object->Load($id);
$object->SetFieldsFromHash($field_values, $this->getRequestProtectedFields($field_values));
if (!$object->Validate()) {
$event->status = kEvent::erFAIL;
$event->redirect = false;
return;
}
$this->UpdateCombinations($event, $field_values);
/*$this->customProcessing($event, 'before');
if( $object->Update($id) )
{
$this->customProcessing($event, 'after');
$event->status=kEvent::erSUCCESS;
}
else
{
$event->status=kEvent::erFAIL;
$event->redirect=false;
break;
}*/
}
}
$this->Application->SetVar($event->GetPrefixSpecial().'_id', '');
}
/**
* Builds item (loads if needed)
*
* Pattern: Prototype Manager
*
* @param kEvent $event
* @access protected
*/
protected function OnItemBuild(kEvent $event)
{
$object = $event->getObject();
/* @var $object kDBItem */
$this->dbBuild($object, $event);
$sql = $this->ItemPrepareQuery($event);
$sql = $this->Application->ReplaceLanguageTags($sql);
$object->setSelectSQL($sql);
// 2. loads if allowed
- $auto_load = $this->Application->getUnitOption($event->Prefix, 'AutoLoad');
+ $auto_load = $event->getUnitConfig()->getAutoLoad();
$skip_autoload = $event->getEventParam('skip_autoload');
if ( $auto_load && !$skip_autoload ) {
$this->LoadItem($event);
}
$actions = $this->Application->recallObject('kActions');
/* @var $actions Params */
$actions->Set($event->getPrefixSpecial() . '_GoTab', '');
$actions->Set($event->getPrefixSpecial() . '_GoId', '');
}
/**
* Load item if id is available
*
* @param kEvent $event
* @return void
* @access protected
*/
protected function LoadItem(kEvent $event)
{
$object = $event->getObject();
/* @var $object kDBItem */
$id = $this->getPassedID($event);
if ( !$id ) {
$event->CallSubEvent('OnNew');
return;
}
if ( $object->Load($id) ) {
$actions = $this->Application->recallObject('kActions');
/* @var $actions Params */
$actions->Set($event->getPrefixSpecial() . '_id', $object->GetId());
}
}
/**
* Returns special of main item for linking with sub-item
*
* @param kEvent $event
* @return string
* @access protected
*/
protected function getMainSpecial(kEvent $event)
{
$special = $event->getEventParam('main_special');
if ( $special === false || $special == '$main_special' ) {
$special = $event->Special;
}
if ( $special == 'grid' ) {
$special = '';
}
return $special;
}
/**
* Occurs before 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 OnBeforeClone(kEvent $event)
{
parent::OnBeforeClone($event);
$event->Init($event->Prefix, '-item');
$object = $event->getObject();
/* @var $object kDBItem */
$options_mapping = $this->Application->GetVar('poc_mapping');
if ( !$options_mapping ) {
return;
}
foreach ($options_mapping as $original => $new) {
$n_combs = array ();
$comb_data = unserialize($object->GetDBField('Combination'));
foreach ($comb_data as $key => $val) {
$n_key = $key == $original ? $new : $key;
$n_combs[$n_key] = $val;
}
ksort($n_combs);
$n_combs = serialize($n_combs);
$n_crc = kUtil::crc32($n_combs);
$object->SetDBField('Combination', $n_combs);
$object->SetDBField('CombinationCRC', $n_crc);
}
}
/**
* Restore back values from live table to temp table before overwriting live with temp
*
* @param kEvent $event
* @return void
* @access protected
*/
protected function OnBeforeDeleteFromLive(kEvent $event)
{
parent::OnBeforeDeleteFromLive($event);
// check if product inventory management is via options and then proceed
$id = $event->getEventParam('id');
- $products_table = $this->Application->getUnitOption('p', 'TableName');
- $table_name = $this->Application->getUnitOption($event->Prefix, 'TableName');
- $id_field = $this->Application->getUnitOption($event->Prefix, 'IDField');
+ $products_table = $this->Application->getUnitConfig('p')->getTableName();
+
+ $config = $event->getUnitConfig();;
$sql = 'SELECT p.InventoryStatus
FROM ' . $products_table . ' p
- LEFT JOIN ' . $table_name . ' poc ON poc.ProductId = p.ProductId
- WHERE poc.' . $id_field . ' = ' . $id;
+ LEFT JOIN ' . $config->getTableName() . ' poc ON poc.ProductId = p.ProductId
+ WHERE poc.' . $config->getIDField() . ' = ' . $id;
$inventory_status = $this->Conn->GetOne($sql);
if ( $inventory_status == ProductInventory::BY_OPTIONS ) {
$live_object = $this->Application->recallObject($event->Prefix . '.itemlive', null, Array ('skip_autoload' => true));
/* @var $live_object kDBItem */
$live_object->SwitchToLive();
$live_object->Load($id);
$temp_object = $this->Application->recallObject($event->Prefix . '.itemtemp', null, Array ('skip_autoload' => true));
/* @var $temp_object kDBItem */
$temp_object->SwitchToTemp();
$temp_object->Load($id);
$temp_object->SetDBFieldsFromHash($live_object->GetFieldValues(), null, Array ('QtyInStock', 'QtyReserved', 'QtyBackOrdered', 'QtyOnOrder'));
$temp_object->Update();
}
}
/**
* Create search filters based on search query
*
* @param kEvent $event
* @return void
* @access protected
*/
protected function OnSearch(kEvent $event)
{
parent::OnSearch($event);
$this->_saveProduct($event);
}
/**
* Clear search keywords
*
* @param kEvent $event
* @return void
* @access protected
*/
protected function OnSearchReset(kEvent $event)
{
parent::OnSearchReset($event);
$this->_saveProduct($event);
}
/**
* Makes event remember product id (if passed)
*
* @param kEvent $event
*/
function _saveProduct($event)
{
$product_id = $this->Application->GetVar('p_id');
if ($product_id) {
$event->SetRedirectParam('p_id', $product_id);
}
}
}
\ No newline at end of file
Index: branches/5.3.x/units/payment_type/payment_type_event_handler.php
===================================================================
--- branches/5.3.x/units/payment_type/payment_type_event_handler.php (revision 15694)
+++ branches/5.3.x/units/payment_type/payment_type_event_handler.php (revision 15695)
@@ -1,295 +1,296 @@
<?php
/**
* @version $Id$
* @package In-Commerce
* @copyright Copyright (C) 1997 - 2009 Intechnic. All rights reserved.
* @license Commercial License
* This software 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
* See http://www.in-portal.org/commercial-license for copyright notices and details.
*/
defined('FULL_PATH') or die('restricted access!');
class PaymentTypeEventHandler extends kDBEventHandler
{
/**
* Define alternative event processing method names
*
* @return void
* @see kEventHandler::$eventMethods
* @access protected
*/
protected function mapEvents()
{
parent::mapEvents();
$common_events = Array (
'OnMassApprove'=>'iterateItems',
'OnMassDecline'=>'OnMassDecline',
'OnMassMoveUp'=>'iterateItems',
'OnMassMoveDown'=>'iterateItems',
);
$this->eventMethods = array_merge($this->eventMethods, $common_events);
}
/**
* Allows to override standard permission mapping
*
* @return void
* @access protected
* @see kEventHandler::$permMapping
*/
protected function mapPermissions()
{
parent::mapPermissions();
$permissions = Array (
'OnItemBuild' => Array ('self' => true),
);
$this->permMapping = array_merge($this->permMapping, $permissions);
}
/**
* Set's new category 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 ');
$this->Conn->Query('UPDATE '.$object->TableName.' SET IsPrimary = 1, Status = 1 WHERE PaymentTypeId = '.$id.' ');
}
$event->SetRedirectParam('opener', 's');
}
- function OnMassDecline($event)
+ function OnMassDecline(kEvent $event)
{
$object = $event->getObject(Array ('skip_autoload' => true));
/* @var $object kDBItem */
$this->StoreSelectedIDs($event);
$ids = $this->getSelectedIDs($event);
if ( $ids ) {
- $status_field = $object->getStatusField();
+ $status_field = $event->getUnitConfig()->getStatusField(true);
foreach ($ids as $id) {
$object->Load($id);
if ( !$object->GetDBField("IsPrimary") ) {
$object->SetDBField($status_field, 0);
}
if ( $object->Update() ) {
$event->status = kEvent::erSUCCESS;
$event->SetRedirectParam('opener', 's');
}
else {
$event->status = kEvent::erFAIL;
$event->redirect = false;
break;
}
}
}
}
/**
* Occurs before updating item
*
* @param kEvent $event
* @return void
* @access protected
*/
protected function OnBeforeItemUpdate(kEvent $event)
{
parent::OnBeforeItemUpdate($event);
$object = $event->getObject();
/* @var $object kDBItem */
- $status_field = $object->getStatusField();
+ $status_field = $event->getUnitConfig()->getStatusField(true);
if ( $object->GetDBField('IsPrimary') == 1 && $object->GetDBField($status_field) == 0 ) {
$object->SetDBField($status_field, 1);
}
$this->convertGroups($event);
}
/**
* Occurs before creating item
*
* @param kEvent $event
* @return void
* @access protected
*/
protected function OnBeforeItemCreate(kEvent $event)
{
parent::OnBeforeItemCreate($event);
$this->convertGroups($event);
}
/**
* Disable delete on primary payment type
*
* @param kEvent $event
* @param string $type
* @return void
* @access protected
*/
protected function customProcessing(kEvent $event, $type)
{
if ( $event->Name == 'OnMassDelete' && $type == 'before' ) {
$object = $event->getObject();
/* @var $object kDBItem */
$ids_ok = Array ();
$ids = $event->getEventParam('ids');
foreach ($ids as $id) {
$object->Load($id);
if ( $object->GetDBField('IsPrimary') ) {
$this->Application->StoreVar('pt_delete_error', '1');
}
else {
$ids_ok[] = $id;
}
}
$event->setEventParam('ids', $ids_ok);
}
}
/**
* Saves content of temp table into live and
* redirects to event' default redirect (normally grid template)
*
* @param kEvent $event
* @return void
* @access protected
*/
protected function OnSave(kEvent $event)
{
$this->Application->StoreVar('check_unused_currencies', 1);
parent::OnSave($event);
}
/**
* Sets default payment type group
*
* @param kEvent $event
* @return void
* @access protected
*/
protected function OnAfterConfigRead(kEvent $event)
{
parent::OnAfterConfigRead($event);
+ $config = $event->getUnitConfig();
$default_group = $this->Application->ConfigValue('User_LoggedInGroup');
- $fields = $this->Application->getUnitOption($event->Prefix, 'Fields');
+ $fields = $config->getFields();
$fields['PortalGroups']['default'] = ','.$default_group.',';
- $this->Application->setUnitOption($event->Prefix, 'Fields', $fields);
+ $config->setFields($fields);
}
/**
* Earlier version of group selector control needs such conversion (also used in shipping)
*
* @param kEvent $event
*/
function convertGroups($event)
{
$object = $event->getObject();
$selected_groups = $object->GetDBField('PortalGroups');
if ($selected_groups) {
$selected_groups = str_replace('|', ',', $selected_groups);
$selected_groups = ','.trim($selected_groups, ',').',';
$object->SetDBField('PortalGroups', $selected_groups);
}
}
/**
* Returns ID of current item to be edited
* by checking ID passed in get/post as prefix_id
* or by looking at first from selected ids, stored.
* Returned id is also stored in Session in case
* it was explicitly passed as get/post
*
* @param kEvent $event
* @return int
* @access public
*/
public function getPassedID(kEvent $event)
{
if ( $event->Special == 'auto-ord' ) {
$main_object = $this->Application->recallObject('ord');
/* @var $main_object kDBItem */
return $main_object->GetDBField('PaymentType');
}
elseif ( substr($event->Special, 0, 3) == 'gw-' ) {
// returns first matched enabled payment type
return Array (
'Status' => STATUS_ACTIVE,
TABLE_PREFIX . 'Gateways.Name' => $event->getEventParam('gateway')
);
}
return parent::getPassedID($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);
$object = $event->getObject();
/* @var $object kDBList */
if ( in_array($event->Special, Array ('enabled', 'selected', 'available')) || !$this->Application->isAdminUser ) {
// "enabled" special or Front-End
$object->addFilter('enabled_filter', '%1$s.Status = ' . STATUS_ACTIVE);
}
// site domain payment type picker
if ( $event->Special == 'selected' || $event->Special == 'available' ) {
$edit_picker_helper = $this->Application->recallObject('EditPickerHelper');
/* @var $edit_picker_helper EditPickerHelper */
$edit_picker_helper->applyFilter($event, 'PaymentTypes');
}
// apply domain-based payment type filtering
$payment_types = $this->Application->siteDomainField('PaymentTypes');
if ( strlen($payment_types) ) {
$payment_types = explode('|', substr($payment_types, 1, -1));
$object->addFilter('domain_filter', '%1$s.PaymentTypeId IN (' . implode(',', $payment_types) . ')');
}
}
}
\ No newline at end of file
Index: branches/5.3.x/units/taxes/taxes_tag_processor.php
===================================================================
--- branches/5.3.x/units/taxes/taxes_tag_processor.php (revision 15694)
+++ branches/5.3.x/units/taxes/taxes_tag_processor.php (revision 15695)
@@ -1,273 +1,277 @@
<?php
/**
* @version $Id$
* @package In-Commerce
* @copyright Copyright (C) 1997 - 2009 Intechnic. All rights reserved.
* @license Commercial License
* This software 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
* See http://www.in-portal.org/commercial-license for copyright notices and details.
*/
defined('FULL_PATH') or die('restricted access!');
class TaxesTagProcessor extends kDBTagProcessor
{
function ShowCountries($params)
{
$object = $this->getObject($params);
/* @var $object kDBItem */
$destination_table = $this->getDestinationsTable($params);
$selected_country_id = (int)$this->Application->GetVar('CountrySelector');
$name_field = 'l' . $this->Application->GetVar('m_lang') . '_Name';
- $id_field = $this->Application->getUnitOption('country-state', 'IDField');
- $table_name = $this->Application->getUnitOption('country-state', 'TableName');
+
+ $country_config = $this->Application->getUnitConfig('country-state');
+ $id_field = $country_config->getIDField();
+ $table_name = $country_config->getTableName();
switch ($params['show']) {
case 'current':
// selected countries in current zone
$sql = 'SELECT cs.' . $name_field . ', cs.' . $id_field . '
FROM ' . $table_name . ' cs
LEFT JOIN ' . $destination_table . ' zd ON zd.StdDestId = cs.' . $id_field . '
WHERE cs.Type = ' . DESTINATION_TYPE_COUNTRY . ' AND zd.TaxZoneId = ' . $object->GetID() . '
ORDER BY cs.' . $name_field;
break;
case 'available':
// available countries in current zone
$sql = 'SELECT cs.' . $name_field . ', cs.' . $id_field . '
FROM ' . $table_name . ' cs
LEFT JOIN ' . $destination_table . ' zd ON zd.StdDestId = cs.' . $id_field . '
WHERE cs.Type = ' . DESTINATION_TYPE_COUNTRY . ' AND zd.TaxZoneId IS NULL
ORDER BY cs.' . $name_field;
break;
case 'all':
// always preselect 1st country, when user haven't selected any
if (!$selected_country_id) {
$sql = 'SELECT StdDestId
FROM ' . $destination_table . '
WHERE TaxZoneId = ' . $object->GetID();
$selected_country_id = $this->Conn->GetOne($sql);
if ($selected_country_id) {
$this->Application->SetVar('CountrySelector', $selected_country_id);
}
}
// all countries
$sql = 'SELECT ' . $name_field . ', ' . $id_field . '
FROM ' . $table_name . '
WHERE Type = ' . DESTINATION_TYPE_COUNTRY . '
ORDER BY ' . $name_field;
break;
case 'has_states':
$cs_helper = $this->Application->recallObject('CountryStatesHelper');
/* @var $cs_helper kCountryStatesHelper */
$has_states = $cs_helper->getCountriesWithStates();
if ($selected_country_id && !array_key_exists($selected_country_id, $has_states)) {
list ($selected_country_id, ) = each($has_states);
$this->Application->SetVar('CountrySelector', $selected_country_id);
}
// preselect country from 1st found state
if (!$selected_country_id) {
$sql = 'SELECT cs.StateCountryId
FROM ' . $table_name . ' cs
LEFT JOIN ' . $destination_table . ' zd ON zd.StdDestId = cs.' . $id_field . '
WHERE (cs.Type = ' . DESTINATION_TYPE_STATE . ') AND (zd.TaxZoneId = ' . $object->GetID() . ')';
$selected_country_id = $this->Conn->GetOne($sql);
if ($selected_country_id) {
$this->Application->SetVar('CountrySelector', $selected_country_id);
}
else {
list ($selected_country_id, ) = each($has_states);
$this->Application->SetVar('CountrySelector', $selected_country_id);
}
}
// gets only countries with states
$sql = 'SELECT ' . $name_field . ', ' . $id_field . '
FROM ' . $table_name . '
WHERE Type = ' . DESTINATION_TYPE_COUNTRY . ' AND ' . $id_field . ' IN (' . implode(',', array_keys($has_states)) . ')
ORDER BY ' . $name_field;
break;
default:
throw new Exception('Unknown "show" parameter value "' . $params['show'] . '" used');
break;
}
$ret = '';
$countries = $this->Conn->GetCol($sql, $id_field);
$block_params = $this->prepareTagParams($params);
$block_params['name'] = $params['block'];
foreach ($countries as $country_id => $country_name) {
$block_params['id'] = $country_id;
$block_params['destination_title'] = $country_name;
$block_params['selected'] = $selected_country_id == $country_id ? ' selected="selected"' : '';
$ret .= $this->Application->ParseBlock($block_params);
}
return $ret;
}
function ShowStates($params)
{
$object = $this->getObject($params);
/* @var $object kDBItem */
$destination_table = $this->getDestinationsTable($params);
$name_field = 'l' . $this->Application->GetVar('m_lang') . '_Name';
- $id_field = $this->Application->getUnitOption('country-state', 'IDField');
- $table_name = $this->Application->getUnitOption('country-state', 'TableName');
+
+ $country_config = $this->Application->getUnitConfig('country-state');
+ $id_field = $country_config->getIDField();
+ $table_name = $country_config->getTableName();
$country_id = $this->Application->GetVar('CountrySelector');
switch ($params['show']) {
case 'current':
// selected states for current country and zone
$sql = 'SELECT cs.' . $name_field . ', cs.' . $id_field . '
FROM ' . $table_name . ' cs
LEFT JOIN ' . $destination_table . ' zd ON zd.StdDestId = cs.' . $id_field . '
WHERE
cs.Type = ' . DESTINATION_TYPE_STATE . ' AND
cs.StateCountryId = ' . $country_id . ' AND
zd.TaxZoneId = ' . $object->GetID() . '
ORDER BY cs.' . $name_field;
break;
case 'available':
// available states for current country and zone
$sql = 'SELECT cs.' . $name_field . ', cs.' . $id_field . '
FROM ' . $table_name . ' cs
LEFT JOIN ' . $destination_table . ' zd ON zd.StdDestId = cs.' . $id_field . '
WHERE
cs.Type = ' . DESTINATION_TYPE_STATE . '
AND zd.TaxZoneId IS NULL
AND cs.StateCountryId = ' . $country_id . '
ORDER BY cs.' . $name_field;
break;
case 'all':
// all possible states for selected country
$sql = 'SELECT ' . $name_field . ', ' . $id_field . '
FROM ' . $table_name . '
WHERE Type = ' . DESTINATION_TYPE_STATE . ' AND StateCountryId = ' . $country_id . '
ORDER BY ' . $name_field;
break;
default:
throw new Exception('Unknown "show" parameter value "' . $params['show'] . '" used');
break;
}
$ret = '';
$states = $this->Conn->GetCol($sql, $id_field);
$block_params = $this->prepareTagParams($params);
$block_params['name'] = $params['block'];
foreach($states as $state_id => $state_name) {
$block_params['id'] = $state_id;
$block_params['destination_title'] = $state_name;
$ret .= $this->Application->ParseBlock($block_params);
}
return $ret;
}
function ShowZips($params)
{
$object = $this->getObject($params);
/* @var $object kDBItem */
$destination_table = $this->getDestinationsTable($params);
$country_id = (int)$this->Application->GetVar('CountrySelector');
$current_sql = 'SELECT DestValue
FROM ' . $destination_table . '
WHERE
COALESCE(DestValue, "") <> "" AND
TaxZoneId = ' . $object->GetID() . '
ORDER BY DestValue';
switch ($params['show']) {
case 'current':
$sql = $current_sql;
break;
case 'available':
$selected_zips = $this->Conn->GetCol($current_sql);
$selected_zips = $this->Conn->qstrArray($selected_zips);
$sql = 'SELECT DISTINCT DestValue
- FROM ' . $this->Application->getUnitOption('taxdst', 'TableName') . '
+ FROM ' . $this->Application->getUnitConfig('taxdst')->getTableName() . '
WHERE
COALESCE(DestValue, "") <> "" AND
TaxZoneId <> ' . $object->GetID() . ' AND
' . ($selected_zips ? 'DestValue NOT IN (' . implode(',', $selected_zips) . ') AND' : '') . '
StdDestId = ' . $country_id . '
ORDER BY DestValue';
break;
default:
throw new Exception('Unknown "show" parameter value "' . $params['show'] . '" used');
break;
}
$zips = $this->Conn->GetCol($sql);
$ret = '';
$block_params = $this->prepareTagParams($params);
$block_params['name'] = $params['block'];
foreach($zips as $zip) {
$block_params['id'] = '0|' . $zip;
$block_params['destination_title'] = $zip;
$ret .= $this->Application->ParseBlock($block_params);
}
return $ret;
}
/**
* Returns table for shipping zone destinations
*
* @param Array $params
* @return string
*/
function getDestinationsTable($params)
{
static $table_name = '';
if (!$table_name) {
$object = $this->getObject($params);
/* @var $object kDBItem */
- $table_name = $this->Application->getUnitOption('taxdst', 'TableName');
+ $table_name = $this->Application->getUnitConfig('taxdst')->getTableName();
if ($object->IsTempTable()) {
$table_name = $this->Application->GetTempName($table_name, 'prefix:' . $this->Prefix);
}
}
return $table_name;
}
}
\ No newline at end of file
Index: branches/5.3.x/units/discount_items/discount_items_tag_processor.php
===================================================================
--- branches/5.3.x/units/discount_items/discount_items_tag_processor.php (revision 15694)
+++ branches/5.3.x/units/discount_items/discount_items_tag_processor.php (revision 15695)
@@ -1,48 +1,49 @@
<?php
/**
* @version $Id$
* @package In-Commerce
* @copyright Copyright (C) 1997 - 2009 Intechnic. All rights reserved.
* @license Commercial License
* This software 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
* See http://www.in-portal.org/commercial-license for copyright notices and details.
*/
defined('FULL_PATH') or die('restricted access!');
class DiscountItemsTagProcessor extends kDBTagProcessor {
function IsEntireOrder($params)
{
- $table_name = $this->Application->getUnitOption($this->Prefix, 'TableName');
+ $table_name = $this->getUnitConfig()->getTableName();
- if ($this->Application->IsTempMode($this->Prefix)) {
+ 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 (DiscountId = ' . $this->Application->GetVar('d_id') . ')';
+
return $this->Conn->GetOne($sql);
}
function ItemIcon($params)
{
$object = $this->getObject($params);
/* @var $object kDBList */
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
Index: branches/5.3.x/units/discount_items/discount_items_event_handler.php
===================================================================
--- branches/5.3.x/units/discount_items/discount_items_event_handler.php (revision 15694)
+++ branches/5.3.x/units/discount_items/discount_items_event_handler.php (revision 15695)
@@ -1,161 +1,169 @@
<?php
/**
* @version $Id$
* @package In-Commerce
* @copyright Copyright (C) 1997 - 2009 Intechnic. All rights reserved.
* @license Commercial License
* This software 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
* See http://www.in-portal.org/commercial-license for copyright notices and details.
*/
defined('FULL_PATH') or die('restricted access!');
class DiscountItemsEventHandler extends kDBEventHandler {
/**
* Allows to override standard permission mapping
*
* @return void
* @access protected
* @see kEventHandler::$permMapping
*/
protected function mapPermissions()
{
parent::mapPermissions();
$permissions = Array(
'OnEntireOrder' => Array ('subitem' => 'add|edit'),
);
$this->permMapping = array_merge($this->permMapping, $permissions);
}
/**
* Adds products from selected categories and their sub-categories and directly selected products to discount items with duplicate checking
*
* @param kEvent $event
*/
function OnProcessSelected($event)
{
- $object = $event->getObject( Array('skip_autoload' => true) );
+ $object = $event->getObject(Array ('skip_autoload' => true));
+ /* @var $object kDBItem */
+
$selected_ids = $this->Application->GetVar('selected_ids');
- if ($selected_ids['c'] == $this->Application->GetVar('m_cat_id')) {
+ if ( $selected_ids['c'] == $this->Application->GetVar('m_cat_id') ) {
// no categories were selected, so selector returned current in catalog. This is not needed here
$selected_ids['c'] = '';
}
$table_data = $object->getLinkedInfo();
// in selectors we could select category & item together
- $prefixes = Array('c', 'p');
+ $prefixes = Array ('c', 'p');
foreach ($prefixes as $prefix) {
- $item_ids = $selected_ids[$prefix] ? explode(',', $selected_ids[$prefix]) : Array();
- if (!$item_ids) continue;
+ $item_ids = $selected_ids[$prefix] ? explode(',', $selected_ids[$prefix]) : Array ();
+
+ if ( !$item_ids ) {
+ continue;
+ }
- if ($prefix == 'c') {
+ if ( $prefix == 'c' ) {
// select all products from selected categories and their subcategories
$sql = 'SELECT DISTINCT p.ResourceId
- FROM '.TABLE_PREFIX.'Categories c
- LEFT JOIN '.TABLE_PREFIX.'CategoryItems ci ON c.CategoryId = ci.CategoryId
- LEFT JOIN '.TABLE_PREFIX.'Products p ON p.ResourceId = ci.ItemResourceId
- WHERE (p.ProductId IS NOT NULL) AND (c.ParentPath LIKE "%|'.implode('|%" OR c.ParentPath LIKE "%|', $item_ids).'|%")';
+ FROM ' . TABLE_PREFIX . 'Categories c
+ LEFT JOIN ' . TABLE_PREFIX . 'CategoryItems ci ON c.CategoryId = ci.CategoryId
+ LEFT JOIN ' . TABLE_PREFIX . 'Products p ON p.ResourceId = ci.ItemResourceId
+ WHERE (p.ProductId IS NOT NULL) AND (c.ParentPath LIKE "%|' . implode('|%" OR c.ParentPath LIKE "%|', $item_ids) . '|%")';
$resource_ids = $this->Conn->GetCol($sql);
}
else {
- // select selected prodcts
+ // select selected products
+ $config = $this->Application->getUnitConfig($prefix);
+
$sql = 'SELECT ResourceId
- FROM '.$this->Application->getUnitOption($prefix, 'TableName').'
- WHERE '.$this->Application->getUnitOption($prefix, 'IDField').' IN ('.implode(',', $item_ids).')';
+ FROM ' . $config->getTableName() . '
+ WHERE ' . $config->getIDField() . ' IN (' . implode(',', $item_ids) . ')';
$resource_ids = $this->Conn->GetCol($sql);
}
- if (!$resource_ids) continue;
+ if ( !$resource_ids ) {
+ continue;
+ }
$sql = 'SELECT ItemResourceId
- FROM '.$object->TableName.'
- WHERE ('.$table_data['ForeignKey'].' = '.$table_data['ParentId'].') AND (ItemResourceId IN ('.implode(',', $resource_ids).'))';
+ FROM ' . $object->TableName . '
+ WHERE (' . $table_data['ForeignKey'] . ' = ' . $table_data['ParentId'] . ') AND (ItemResourceId IN (' . implode(',', $resource_ids) . '))';
// 1. don't insert items, that are already in
$skip_resource_ids = $this->Conn->GetCol($sql);
$resource_ids = array_diff($resource_ids, $skip_resource_ids); // process only not already in db resourceids for current discount
// 2. insert ids, that left
foreach ($resource_ids as $resource_id) {
$object->SetDBField($table_data['ForeignKey'], $table_data['ParentId']);
$object->SetDBField('ItemResourceId', $resource_id);
$object->SetDBField('ItemType', 1);
$object->Create();
}
}
$this->finalizePopup($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 DiscountId='.$this->Application->GetVar('d_id');
$this->Conn->Query($sql);
$object->SetDBField('DiscountId', $this->Application->GetVar('d_id'));
$object->SetDBField('ItemResourceId', -1);
$object->SetDBField('ItemType', 0);
if ( $object->Create() ) {
$this->customProcessing($event,'after');
$event->status = kEvent::erSUCCESS;
$event->SetRedirectParam('opener', 's');
}
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');
+ /* @var $main_object kDBItem */
- $table = $this->Application->getUnitOption($event->Prefix,'TableName');
- $sql = 'DELETE FROM '.$table.' WHERE ItemResourceId = '.$resource_id;
+ $sql = 'DELETE FROM ' . $event->getUnitConfig()->getTableName() . '
+ WHERE ItemResourceId = ' . $main_object->GetDBField('ResourceId');
$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);
+ $event->getUnitConfig()->addCalculatedFieldsBySpecial('', Array (
+ 'ItemName' => 'COALESCE(p.l' . $language_id . '_Name, p.l' . $primary_language_id . '_Name)'
+ ));
}
}
\ No newline at end of file
Index: branches/5.3.x/units/zones/zones_tag_processor.php
===================================================================
--- branches/5.3.x/units/zones/zones_tag_processor.php (revision 15694)
+++ branches/5.3.x/units/zones/zones_tag_processor.php (revision 15695)
@@ -1,272 +1,276 @@
<?php
/**
* @version $Id$
* @package In-Commerce
* @copyright Copyright (C) 1997 - 2009 Intechnic. All rights reserved.
* @license Commercial License
* This software 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
* See http://www.in-portal.org/commercial-license for copyright notices and details.
*/
defined('FULL_PATH') or die('restricted access!');
class ZonesTagProcessor extends kDBTagProcessor
{
function ShowCountries($params)
{
$object = $this->getObject($params);
/* @var $object kDBItem */
$destination_table = $this->getDestinationsTable($params);
$selected_country_id = (int)$this->Application->GetVar('CountrySelector');
$name_field = 'l' . $this->Application->GetVar('m_lang') . '_Name';
- $id_field = $this->Application->getUnitOption('country-state', 'IDField');
- $table_name = $this->Application->getUnitOption('country-state', 'TableName');
+
+ $countries_config = $this->Application->getUnitConfig('country-state');
+ $id_field = $countries_config->getIDField();
+ $table_name = $countries_config->getTableName();
switch ($params['show']) {
case 'current':
// selected countries in current zone
$sql = 'SELECT cs.' . $name_field . ', cs.' . $id_field . '
FROM ' . $table_name . ' cs
LEFT JOIN ' . $destination_table . ' zd ON zd.StdDestId = cs.' . $id_field . '
WHERE cs.Type = ' . DESTINATION_TYPE_COUNTRY . ' AND zd.ShippingZoneId = ' . $object->GetID() . '
ORDER BY cs.' . $name_field;
break;
case 'available':
// available countries in current zone
$sql = 'SELECT cs.' . $name_field . ', cs.' . $id_field . '
FROM ' . $table_name . ' cs
LEFT JOIN ' . $destination_table . ' zd ON zd.StdDestId = cs.' . $id_field . '
WHERE cs.Type = ' . DESTINATION_TYPE_COUNTRY . ' AND zd.ShippingZoneId IS NULL
ORDER BY cs.' . $name_field;
break;
case 'all':
// always preselect 1st country, when user haven't selected any
if (!$selected_country_id) {
$sql = 'SELECT StdDestId
FROM ' . $destination_table . '
WHERE ShippingZoneId = ' . $object->GetID();
$selected_country_id = $this->Conn->GetOne($sql);
if ($selected_country_id) {
$this->Application->SetVar('CountrySelector', $selected_country_id);
}
}
// all countries
$sql = 'SELECT ' . $name_field . ', ' . $id_field . '
FROM ' . $table_name . '
WHERE Type = ' . DESTINATION_TYPE_COUNTRY . '
ORDER BY ' . $name_field;
break;
case 'has_states':
$cs_helper = $this->Application->recallObject('CountryStatesHelper');
/* @var $cs_helper kCountryStatesHelper */
$has_states = $cs_helper->getCountriesWithStates();
if ($selected_country_id && !array_key_exists($selected_country_id, $has_states)) {
list ($selected_country_id, ) = each($has_states);
$this->Application->SetVar('CountrySelector', $selected_country_id);
}
// preselect country from 1st found state
if (!$selected_country_id) {
$sql = 'SELECT cs.StateCountryId
FROM ' . $table_name . ' cs
LEFT JOIN ' . $destination_table . ' zd ON zd.StdDestId = cs.' . $id_field . '
WHERE (cs.Type = ' . DESTINATION_TYPE_STATE . ') AND (zd.ShippingZoneId = ' . $object->GetID() . ')';
$selected_country_id = $this->Conn->GetOne($sql);
if ($selected_country_id) {
$this->Application->SetVar('CountrySelector', $selected_country_id);
}
else {
list ($selected_country_id, ) = each($has_states);
$this->Application->SetVar('CountrySelector', $selected_country_id);
}
}
// gets only countries with states
$sql = 'SELECT ' . $name_field . ', ' . $id_field . '
FROM ' . $table_name . '
WHERE Type = ' . DESTINATION_TYPE_COUNTRY . ' AND ' . $id_field . ' IN (' . implode(',', array_keys($has_states)) . ')
ORDER BY ' . $name_field;
break;
default:
throw new Exception('Unknown "show" parameter value "' . $params['show'] . '" used');
break;
}
$ret = '';
$countries = $this->Conn->GetCol($sql, $id_field);
$block_params = $this->prepareTagParams($params);
$block_params['name'] = $params['block'];
foreach ($countries as $country_id => $country_name) {
$block_params['id'] = $country_id;
$block_params['destination_title'] = $country_name;
$block_params['selected'] = $selected_country_id == $country_id ? ' selected="selected"' : '';
$ret .= $this->Application->ParseBlock($block_params);
}
return $ret;
}
function ShowStates($params)
{
$object = $this->getObject($params);
/* @var $object kDBItem */
$destination_table = $this->getDestinationsTable($params);
$name_field = 'l' . $this->Application->GetVar('m_lang') . '_Name';
- $id_field = $this->Application->getUnitOption('country-state', 'IDField');
- $table_name = $this->Application->getUnitOption('country-state', 'TableName');
+
+ $countries_config = $this->Application->getUnitConfig('country-state');
+ $id_field = $countries_config->getIDField();
+ $table_name = $countries_config->getTableName();
$country_id = $this->Application->GetVar('CountrySelector');
switch ($params['show']) {
case 'current':
// selected states for current country and zone
$sql = 'SELECT cs.' . $name_field . ', cs.' . $id_field . '
FROM ' . $table_name . ' cs
LEFT JOIN ' . $destination_table . ' zd ON zd.StdDestId = cs.' . $id_field . '
WHERE
cs.Type = ' . DESTINATION_TYPE_STATE . ' AND
cs.StateCountryId = ' . $country_id . ' AND
zd.ShippingZoneId = ' . $object->GetID() . '
ORDER BY cs.' . $name_field;
break;
case 'available':
// available states for current country and zone
$sql = 'SELECT cs.' . $name_field . ', cs.' . $id_field . '
FROM ' . $table_name . ' cs
LEFT JOIN ' . $destination_table . ' zd ON zd.StdDestId = cs.' . $id_field . '
WHERE
cs.Type = ' . DESTINATION_TYPE_STATE . '
AND zd.ShippingZoneId IS NULL
AND cs.StateCountryId = ' . $country_id . '
ORDER BY cs.' . $name_field;
break;
case 'all':
// all possible states for selected country
$sql = 'SELECT ' . $name_field . ', ' . $id_field . '
FROM ' . $table_name . '
WHERE Type = ' . DESTINATION_TYPE_STATE . ' AND StateCountryId = ' . $country_id . '
ORDER BY ' . $name_field;
break;
default:
throw new Exception('Unknown "show" parameter value "' . $params['show'] . '" used');
break;
}
$ret = '';
$states = $this->Conn->GetCol($sql, $id_field);
$block_params = $this->prepareTagParams($params);
$block_params['name'] = $params['block'];
foreach($states as $state_id => $state_name) {
$block_params['id'] = $state_id;
$block_params['destination_title'] = $state_name;
$ret .= $this->Application->ParseBlock($block_params);
}
return $ret;
}
function ShowZips($params)
{
$object = $this->getObject($params);
/* @var $object kDBItem */
$destination_table = $this->getDestinationsTable($params);
$country_id = (int)$this->Application->GetVar('CountrySelector');
$current_sql = 'SELECT DestValue
FROM ' . $destination_table . '
WHERE
COALESCE(DestValue, "") <> "" AND
ShippingZoneID = ' . $object->GetID() . '
ORDER BY DestValue';
switch ($params['show']) {
case 'current':
$sql = $current_sql;
break;
case 'available':
$selected_zips = $this->Conn->GetCol($current_sql);
$selected_zips = $this->Conn->qstrArray($selected_zips);
$sql = 'SELECT DISTINCT DestValue
- FROM ' . $this->Application->getUnitOption('dst', 'TableName') . '
+ FROM ' . $this->Application->getUnitConfig('dst')->getTableName() . '
WHERE
COALESCE(DestValue, "") <> "" AND
ShippingZoneID <> ' . $object->GetID() . ' AND
' . ($selected_zips ? 'DestValue NOT IN (' . implode(',', $selected_zips) . ') AND' : '') . '
StdDestId = ' . $country_id . '
ORDER BY DestValue';
break;
default:
throw new Exception('Unknown "show" parameter value "' . $params['show'] . '" used');
break;
}
$zips = $this->Conn->GetCol($sql);
$ret = '';
$block_params = $this->prepareTagParams($params);
$block_params['name'] = $params['block'];
foreach($zips as $zip) {
$block_params['id'] = '0|' . $zip;
$block_params['destination_title'] = $zip;
$ret .= $this->Application->ParseBlock($block_params);
}
return $ret;
}
/**
* Returns table for shipping zone destinations
*
* @param Array $params
* @return string
*/
function getDestinationsTable($params)
{
static $table_name = '';
if (!$table_name) {
$object = $this->getObject($params);
/* @var $object kDBItem */
- $table_name = $this->Application->getUnitOption('dst', 'TableName');
+ $table_name = $this->Application->getUnitConfig('dst')->getTableName();
if ($object->IsTempTable()) {
$table_name = $this->Application->GetTempName($table_name, 'prefix:' . $this->Prefix);
}
}
return $table_name;
}
}
\ No newline at end of file
Index: branches/5.3.x/units/orders/orders_event_handler.php
===================================================================
--- branches/5.3.x/units/orders/orders_event_handler.php (revision 15694)
+++ branches/5.3.x/units/orders/orders_event_handler.php (revision 15695)
@@ -1,4003 +1,4019 @@
<?php
/**
* @version $Id$
* @package In-Commerce
* @copyright Copyright (C) 1997 - 2009 Intechnic. All rights reserved.
* @license Commercial License
* This software 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
* See http://www.in-portal.org/commercial-license for copyright notices and details.
*/
defined('FULL_PATH') or die('restricted access!');
class OrdersEventHandler extends kDBEventHandler
{
/**
* Checks user permission to execute given $event
*
* @param kEvent $event
* @return bool
* @access public
*/
public function CheckPermission(kEvent $event)
{
if ( !$this->Application->isAdminUser ) {
if ( $event->Name == 'OnCreate' ) {
// user can't initiate custom order creation directly
return false;
}
$user_id = $this->Application->RecallVar('user_id');
$items_info = $this->Application->GetVar($event->getPrefixSpecial(true));
if ( $items_info ) {
// when POST is present, then check when is beeing submitted
$order_session_id = $this->Application->RecallVar($event->getPrefixSpecial(true) . '_id');
$order_dummy = $this->Application->recallObject($event->Prefix . '.-item', null, Array ('skip_autoload' => true));
/* @var $order_dummy OrdersItem */
foreach ($items_info as $id => $field_values) {
if ( $order_session_id != $id ) {
// user is trying update not his order, even order from other guest
return false;
}
$order_dummy->Load($id);
// session_id matches order_id from submit
if ( $order_dummy->GetDBField('PortalUserId') != $user_id ) {
// user performs event on other user order
return false;
}
- $status_field = $order_dummy->getStatusField();
+ $status_field = $event->getUnitConfig()->getStatusField(true);
if ( isset($field_values[$status_field]) && $order_dummy->GetDBField($status_field) != $field_values[$status_field] ) {
// user can't change status by himself
return false;
}
if ( $order_dummy->GetDBField($status_field) != ORDER_STATUS_INCOMPLETE ) {
// user can't edit orders being processed
return false;
}
if ( $event->Name == 'OnUpdate' ) {
// all checks were ok -> it's user's order -> allow to modify
return true;
}
}
}
}
if ( $event->Name == 'OnQuietPreSave' ) {
$section = $event->getSection();
if ( $this->isNewItemCreate($event) ) {
return $this->Application->CheckPermission($section . '.add', 1);
}
else {
return $this->Application->CheckPermission($section . '.add', 1) || $this->Application->CheckPermission($section . '.edit', 1);
}
}
return parent::CheckPermission($event);
}
/**
* Allows to override standard permission mapping
*
* @return void
* @access protected
* @see kEventHandler::$permMapping
*/
protected function mapPermissions()
{
parent::mapPermissions();
$permissions = Array (
// admin
'OnRecalculateItems' => Array('self' => 'add|edit'),
'OnResetToUser' => Array('self' => 'add|edit'),
'OnResetToBilling' => Array('self' => 'add|edit'),
'OnResetToShipping' => Array('self' => 'add|edit'),
'OnMassOrderApprove' => Array('self' => 'advanced:approve'),
'OnMassOrderDeny' => Array('self' => 'advanced:deny'),
'OnMassOrderArchive' => Array('self' => 'advanced:archive'),
'OnMassPlaceOrder' => Array('self' => 'advanced:place'),
'OnMassOrderProcess' => Array('self' => 'advanced:process'),
'OnMassOrderShip' => Array('self' => 'advanced:ship'),
'OnResetToPending' => Array('self' => 'advanced:reset_to_pending'),
'OnLoadSelected' => Array('self' => 'view'), // print in this case
'OnGoToOrder' => Array('self' => 'view'),
// front-end
'OnViewCart' => Array('self' => true),
'OnAddToCart' => Array('self' => true),
'OnRemoveFromCart' => Array('self' => true),
'OnUpdateCart' => Array('self' => true),
'OnUpdateCartJSON' => Array('self' => true),
'OnUpdateItemOptions' => Array('self' => true),
'OnCleanupCart' => Array('self' => true),
'OnContinueShopping' => Array('self' => true),
'OnCheckout' => Array('self' => true),
'OnSelectAddress' => Array('self' => true),
'OnProceedToBilling' => Array('self' => true),
'OnProceedToPreview' => Array('self' => true),
'OnCompleteOrder' => Array('self' => true),
'OnUpdateAjax' => Array('self' => true),
'OnRemoveCoupon' => Array('self' => true),
'OnRemoveGiftCertificate' => Array('self' => true),
'OnCancelRecurring' => Array('self' => true),
'OnAddVirtualProductToCart' => Array('self' => true),
'OnItemBuild' => Array('self' => true),
'OnDownloadLabel' => Array('self' => true, 'subitem' => true),
);
$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();
$common_events = Array (
'OnResetToUser' => 'OnResetAddress',
'OnResetToBilling' => 'OnResetAddress',
'OnResetToShipping' => 'OnResetAddress',
'OnMassOrderProcess' => 'MassInventoryAction',
'OnMassOrderApprove' => 'MassInventoryAction',
'OnMassOrderDeny' => 'MassInventoryAction',
'OnMassOrderArchive' => 'MassInventoryAction',
'OnMassOrderShip' => 'MassInventoryAction',
'OnOrderProcess' => 'InventoryAction',
'OnOrderApprove' => 'InventoryAction',
'OnOrderDeny' => 'InventoryAction',
'OnOrderArchive' => 'InventoryAction',
'OnOrderShip' => 'InventoryAction',
);
$this->eventMethods = array_merge($this->eventMethods, $common_events);
}
/* ======================== FRONT ONLY ======================== */
function OnQuietPreSave($event)
{
$object = $event->getObject();
/* @var $object kDBItem */
$object->IgnoreValidation = true;
$event->CallSubEvent('OnPreSave');
$object->IgnoreValidation = false;
}
/**
* Sets new address to order
*
* @param kEvent $event
*/
function OnSelectAddress($event)
{
if ($this->Application->isAdminUser) {
return ;
}
$object = $event->getObject();
/* @var $object OrdersItem */
$shipping_address_id = $this->Application->GetVar('shipping_address_id');
$billing_address_id = $this->Application->GetVar('billing_address_id');
if ($shipping_address_id || $billing_address_id) {
$cs_helper = $this->Application->recallObject('CountryStatesHelper');
/* @var $cs_helper kCountryStatesHelper */
$address = $this->Application->recallObject('addr.-item','addr', Array('skip_autoload' => true));
/* @var $address AddressesItem */
$addr_list = $this->Application->recallObject('addr', 'addr_List', Array('per_page'=>-1, 'skip_counting'=>true) );
/* @var $addr_list AddressesList */
$addr_list->Query();
}
if ($shipping_address_id > 0) {
$addr_list->CopyAddress($shipping_address_id, 'Shipping');
$address->Load($shipping_address_id);
$address->MarkAddress('Shipping');
$cs_helper->PopulateStates($event, 'ShippingState', 'ShippingCountry');
$object->setRequired('ShippingState', false);
}
elseif ($shipping_address_id == -1) {
$object->ResetAddress('Shipping');
}
if ($billing_address_id > 0) {
$addr_list->CopyAddress($billing_address_id, 'Billing');
$address->Load($billing_address_id);
$address->MarkAddress('Billing');
$cs_helper->PopulateStates($event, 'BillingState', 'BillingCountry');
$object->setRequired('BillingState', false);
}
elseif ($billing_address_id == -1) {
$object->ResetAddress('Billing');
}
$event->redirect = false;
$object->IgnoreValidation = true;
$this->RecalculateTax($event);
$object->Update();
}
/**
* Updates order with registred user id
*
* @param kEvent $event
*/
function OnUserCreate($event)
{
if( !($event->MasterEvent->status == kEvent::erSUCCESS) ) return false;
$ses_id = $this->Application->RecallVar('front_order_id');
if($ses_id)
{
$this->updateUserID($ses_id, $event);
$this->Application->RemoveVar('front_order_id');
}
}
/**
* Updates shopping cart with logged-in user details
*
* @param kEvent $event
* @return void
* @access protected
*/
protected function OnUserLogin($event)
{
if ( ($event->MasterEvent->status != kEvent::erSUCCESS) || kUtil::constOn('IS_INSTALL') ) {
// login failed OR login during installation
return;
}
$ses_id = $this->Application->RecallVar('ord_id');
if ( $ses_id ) {
$this->updateUserID($ses_id, $event);
}
$user_id = $this->Application->RecallVar('user_id');
$affiliate_id = $this->isAffiliate($user_id);
if ( $affiliate_id ) {
$this->Application->setVisitField('AffiliateId', $affiliate_id);
}
$event->CallSubEvent('OnRecalculateItems');
}
/**
* Puts ID of just logged-in user into current order
*
* @param int $order_id
* @param kEvent $event
* @return void
*/
function updateUserID($order_id, $event)
{
$user = $this->Application->recallObject('u.current');
/* @var $user UsersItem */
$affiliate_id = $this->isAffiliate( $user->GetID() );
$fields_hash = Array (
'PortalUserId' => $user->GetID(),
'BillingEmail' => $user->GetDBField('Email'),
);
if ( $affiliate_id ) {
$fields_hash['AffiliateId'] = $affiliate_id;
}
- $id_field = $this->Application->getUnitOption($event->Prefix, 'IDField');
- $table_name = $this->Application->getUnitOption($event->Prefix, 'TableName');
-
- $this->Conn->doUpdate($fields_hash, $table_name, $id_field . ' = ' . $order_id);
+ $config = $event->getUnitConfig();
+ $this->Conn->doUpdate($fields_hash, $config->getTableName(), $config->getIDField() . ' = ' . $order_id);
$object = $event->getObject();
/* @var $object kDBItem */
// set user id to object, since it will be used during order update from OnRecalculateItems event
$object->SetDBField('PortalUserId', $user->GetID());
}
function isAffiliate($user_id)
{
$affiliate_user = $this->Application->recallObject('affil.-item', null, Array('skip_autoload' => true) );
/* @var $affiliate_user kDBItem */
$affiliate_user->Load($user_id, 'PortalUserId');
return $affiliate_user->isLoaded() ? $affiliate_user->GetDBField('AffiliateId') : 0;
}
/**
* Charge order
*
* @param OrdersItem $order
* @return Array
*/
function ChargeOrder(&$order)
{
$gw_data = $order->getGatewayData();
$this->Application->registerClass( $gw_data['ClassName'], GW_CLASS_PATH.'/'.$gw_data['ClassFile'] );
$gateway_object = $this->Application->recallObject( $gw_data['ClassName'] );
/* @var $gateway_object kGWBase */
$payment_result = $gateway_object->DirectPayment($order->GetFieldValues(), $gw_data['gw_params']);
$sql = 'UPDATE %s SET GWResult1 = %s WHERE %s = %s';
$sql = sprintf($sql, $order->TableName, $this->Conn->qstr($gateway_object->getGWResponce()), $order->IDField, $order->GetID() );
$this->Conn->Query($sql);
$order->SetDBField('GWResult1', $gateway_object->getGWResponce() );
return array('result'=>$payment_result, 'data'=>$gateway_object->parsed_responce, 'gw_data' => $gw_data, 'error_msg'=>$gateway_object->getErrorMsg());
}
/**
* Returns parameters, used to send order-related e-mails
*
* @param OrdersItem $order
* @return array
*/
function OrderEmailParams(&$order)
{
$billing_email = $order->GetDBField('BillingEmail');
$sql = 'SELECT Email
- FROM ' . $this->Application->getUnitOption('u', 'TableName') . '
+ FROM ' . $this->Application->getUnitConfig('u')->getTableName() . '
WHERE PortalUserId = ' . $order->GetDBField('PortalUserId');
$user_email = $this->Conn->GetOne($sql);
$ret = Array (
'_user_email' => $user_email, // for use when shipping vs user is required in InventoryAction
'to_name' => $order->GetDBField('BillingTo'),
'to_email' => $billing_email ? $billing_email : $user_email,
);
return $ret;
}
function PrepareCoupons($event, &$order)
{
$order_items = $this->Application->recallObject('orditems.-inv','orditems_List',Array('skip_counting'=>true,'per_page'=>-1) );
/* @var $order_items kDBList */
$order_items->linkToParent($order->Special);
$order_items->Query();
$order_items->GoFirst();
$assigned_coupons = array();
$coup_handler = $this->Application->recallObject('coup_EventHandler');
foreach($order_items->Records as $product_item)
{
if ($product_item['ItemData']) {
$item_data = unserialize($product_item['ItemData']);
if (isset($item_data['AssignedCoupon']) && $item_data['AssignedCoupon']) {
$coupon_id = $item_data['AssignedCoupon'];
// clone coupon, get new coupon ID
$coupon = $this->Application->recallObject('coup',null,array('skip_autload' => true));
/* @var $coupon kDBItem */
$coupon->Load($coupon_id);
if (!$coupon->isLoaded()) continue;
$coup_handler->SetNewCode($coupon);
$coupon->NameCopy();
$coupon->SetDBField('Name', $coupon->GetDBField('Name').' (Order #'.$order->GetField('OrderNumber').')');
$coupon->Create();
// add coupon code to array
array_push($assigned_coupons, $coupon->GetDBField('Code'));
}
}
}
/* @var $order OrdersItem */
if ($assigned_coupons) {
$comments = $order->GetDBField('AdminComment');
if ($comments) $comments .= "\r\n";
$comments .= "Issued coupon(s): ". join(',', $assigned_coupons);
$order->SetDBField('AdminComment', $comments);
$order->Update();
}
if ($assigned_coupons) $this->Application->SetVar('order_coupons', join(',', $assigned_coupons));
}
/**
* Completes order if possible
*
* @param kEvent $event
* @return bool
*/
function OnCompleteOrder($event)
{
$this->LockTables($event);
if ( !$this->CheckQuantites($event) ) {
return;
}
$this->ReserveItems($event);
$order = $event->getObject();
/* @var $order OrdersItem */
$charge_result = $this->ChargeOrder($order);
if (!$charge_result['result']) {
$this->FreeItems($event);
$this->Application->StoreVar('gw_error', $charge_result['error_msg']);
//$this->Application->StoreVar('gw_error', getArrayValue($charge_result, 'data', 'responce_reason_text') );
$event->redirect = $this->Application->GetVar('failure_template');
$event->SetRedirectParam('m_cat_id', 0);
if ($event->Special == 'recurring') { // if we set failed status for other than recurring special the redirect will not occur
$event->status = kEvent::erFAIL;
}
return false;
}
// call CompleteOrder events for items in order BEFORE SplitOrder (because ApproveEvents are called there)
$order_items = $this->Application->recallObject('orditems.-inv','orditems_List',Array('skip_counting'=>true,'per_page'=>-1) );
/* @var $order_items kDBList */
$order_items->linkToParent($order->Special);
$order_items->Query(true);
$order_items->GoFirst();
foreach($order_items->Records as $product_item)
{
if (!$product_item['ProductId']) continue; // product may have been deleted
$this->raiseProductEvent('CompleteOrder', $product_item['ProductId'], $product_item);
}
$shipping_control = getArrayValue($charge_result, 'gw_data', 'gw_params', 'shipping_control');
if ($event->Special != 'recurring') {
if ($shipping_control && $shipping_control != SHIPPING_CONTROL_PREAUTH ) {
// we have to do it here, because the coupons are used in the e-mails
$this->PrepareCoupons($event, $order);
}
$this->Application->emailUser('ORDER.SUBMIT', null, $this->OrderEmailParams($order));
$this->Application->emailAdmin('ORDER.SUBMIT');
}
if ($shipping_control === false || $shipping_control == SHIPPING_CONTROL_PREAUTH ) {
$order->SetDBField('Status', ORDER_STATUS_PENDING);
$order->Update();
}
else {
$this->SplitOrder($event, $order);
}
if (!$this->Application->isAdminUser) {
// for tracking code
$this->Application->StoreVar('last_order_amount', $order->GetDBField('TotalAmount'));
$this->Application->StoreVar('last_order_number', $order->GetDBField('OrderNumber'));
$this->Application->StoreVar('last_order_customer', $order->GetDBField('BillingTo'));
$this->Application->StoreVar('last_order_user', $order->GetDBField('Username'));
$event->redirect = $this->Application->GetVar('success_template');
$event->SetRedirectParam('m_cat_id', 0);
}
else
{
// $event->CallSubEvent('OnSave');
}
- $order_id = $order->GetId();
- $order_idfield = $this->Application->getUnitOption('ord','IDField');
- $order_table = $this->Application->getUnitOption('ord','TableName');
+ $order_id = $order->GetID();
+ $config = $event->getUnitConfig();
+
$original_amount = $order->GetDBField('SubTotal') + $order->GetDBField('ShippingCost') + $order->GetDBField('VAT') + $order->GetDBField('ProcessingFee') + $order->GetDBField('InsuranceFee') - $order->GetDBField('GiftCertificateDiscount');
- $sql = 'UPDATE '.$order_table.'
+
+ $sql = 'UPDATE '. $config->getTableName() .'
SET OriginalAmount = '.$original_amount.'
- WHERE '.$order_idfield.' = '.$order_id;
+ WHERE '. $config->getIDField() .' = '.$order_id;
$this->Conn->Query($sql);
$this->Application->StoreVar('front_order_id', $order_id);
$this->Application->RemoveVar('ord_id');
$this->Application->Session->SetCookie('shop_cart_cookie', '', strtotime('-1 month'));
}
/**
* Set billing address same as shipping
*
* @param kEvent $event
*/
function setBillingAddress($event)
{
$object = $event->getObject();
/* @var $object OrdersItem */
if ( $object->HasTangibleItems() ) {
if ( $this->Application->GetVar('same_address') ) {
// copy shipping address to billing
$items_info = $this->Application->GetVar($event->getPrefixSpecial(true));
list($id, $field_values) = each($items_info);
$address_fields = Array (
'To', 'Company', 'Phone', 'Fax', 'Email',
'Address1', 'Address2', 'City', 'State',
'Zip', 'Country'
);
foreach ($address_fields as $address_field) {
$items_info[$id]['Billing' . $address_field] = $object->GetDBField('Shipping' . $address_field);
}
$this->Application->SetVar($event->getPrefixSpecial(true), $items_info);
}
}
}
/**
* Enter description here...
*
* @param kEvent $event
*/
function OnProceedToPreview($event)
{
$this->setBillingAddress($event);
$event->CallSubEvent('OnUpdate');
$event->redirect = $this->Application->GetVar('preview_template');
}
function OnViewCart($event)
{
$this->StoreContinueShoppingLink();
$event->redirect = $this->Application->GetVar('viewcart_template');
}
function OnContinueShopping($event)
{
$order_helper = $this->Application->recallObject('OrderHelper');
/* @var $order_helper OrderHelper */
$template = $this->Application->GetVar('continue_shopping_template');
$event->redirect = $order_helper->getContinueShoppingTemplate($template);
}
/**
* Enter description here...
*
* @param kEvent $event
*/
function OnCheckout($event)
{
$this->OnUpdateCart($event);
if ( !$event->getEventParam('RecalculateChangedCart') ) {
$object = $event->getObject();
/* @var $object OrdersItem */
if ( !$object->HasTangibleItems() ) {
$object->SetDBField('ShippingTo', '');
$object->SetDBField('ShippingCompany', '');
$object->SetDBField('ShippingPhone', '');
$object->SetDBField('ShippingFax', '');
$object->SetDBField('ShippingEmail', '');
$object->SetDBField('ShippingAddress1', '');
$object->SetDBField('ShippingAddress2', '');
$object->SetDBField('ShippingCity', '');
$object->SetDBField('ShippingState', '');
$object->SetDBField('ShippingZip', '');
$object->SetDBField('ShippingCountry', '');
$object->SetDBField('ShippingType', 0);
$object->SetDBField('ShippingCost', 0);
$object->SetDBField('ShippingCustomerAccount', '');
$object->SetDBField('ShippingTracking', '');
$object->SetDBField('ShippingDate', 0);
$object->SetDBField('ShippingOption', 0);
$object->SetDBField('ShippingInfo', '');
$object->Update();
}
$event->redirect = $this->Application->GetVar('next_step_template');
$order_id = $this->Application->GetVar('order_id');
if ( $order_id !== false ) {
$event->SetRedirectParam('ord_id', $order_id);
}
}
}
/**
* Restores order from cookie
*
* @param kEvent $event
* @return void
* @access protected
*/
protected function OnRestoreOrder(kEvent $event)
{
if ( $this->Application->isAdmin || $this->Application->RecallVar('ord_id') ) {
// admin OR there is an active order -> don't restore from cookie
return;
}
$shop_cart_cookie = $this->Application->GetVarDirect('shop_cart_cookie', 'Cookie');
if ( !$shop_cart_cookie ) {
return;
}
$user_id = $this->Application->RecallVar('user_id');
$sql = 'SELECT OrderId
FROM ' . TABLE_PREFIX . 'Orders
WHERE (OrderId = ' . (int)$shop_cart_cookie . ') AND (Status = ' . ORDER_STATUS_INCOMPLETE . ') AND (PortalUserId = ' . $user_id . ')';
$order_id = $this->Conn->GetOne($sql);
if ( $order_id ) {
$this->Application->StoreVar('ord_id', $order_id);
}
}
/**
* Redirect user to Billing checkout step
*
* @param kEvent $event
*/
function OnProceedToBilling($event)
{
$items_info = $this->Application->GetVar($event->getPrefixSpecial(true));
if ( $items_info ) {
list($id, $field_values) = each($items_info);
$object = $event->getObject();
/* @var $object kDBItem */
$payment_type_id = $object->GetDBField('PaymentType');
if ( !$payment_type_id ) {
$default_type = $this->_getDefaultPaymentType();
if ( $default_type ) {
$field_values['PaymentType'] = $default_type;
$items_info[$id] = $field_values;
$this->Application->SetVar($event->getPrefixSpecial(true), $items_info);
}
}
}
$event->CallSubEvent('OnUpdate');
$event->redirect = $this->Application->GetVar('next_step_template');
}
/**
* Removes reoccurring mark from the order
*
* @param kEvent $event
* @return void
*/
protected function OnCancelRecurring($event)
{
$order = $event->getObject();
/* @var $order OrdersItem */
$order->SetDBField('IsRecurringBilling', 0);
$order->Update();
if ( $this->Application->GetVar('cancelrecurring_ok_template') ) {
$event->redirect = $this->Application->GetVar('cancelrecurring_ok_template');
}
}
/**
* Occurs after updating item
*
* @param kEvent $event
* @return void
* @access protected
*/
protected function OnAfterItemUpdate(kEvent $event)
{
parent::OnAfterItemUpdate($event);
$object = $event->getObject();
/* @var $object OrdersItem */
$cvv2 = $object->GetDBField('PaymentCVV2');
if ( $cvv2 !== false ) {
$this->Application->StoreVar('CVV2Code', $cvv2);
}
}
/**
* Updates kDBItem
*
* @param kEvent $event
* @return void
* @access protected
*/
protected function OnUpdate(kEvent $event)
{
$this->setBillingAddress($event);
parent::OnUpdate($event);
if ($this->Application->isAdminUser) {
return ;
}
else {
$event->SetRedirectParam('opener', 's');
}
if ($event->status == kEvent::erSUCCESS) {
$this->createMissingAddresses($event);
}
else {
// strange: recalculate total amount on error
$object = $event->getObject();
/* @var $object OrdersItem */
$object->SetDBField('TotalAmount', $object->getTotalAmount());
}
}
/**
* Creates new address
*
* @param kEvent $event
*/
function createMissingAddresses($event)
{
if ( !$this->Application->LoggedIn() ) {
return ;
}
$object = $event->getObject();
/* @var $object kDBItem */
$addr_list = $this->Application->recallObject('addr', 'addr_List', Array ('per_page' => -1, 'skip_counting' => true));
/* @var $addr_list kDBList */
$addr_list->Query();
$address_dummy = $this->Application->recallObject('addr.-item', null, Array ('skip_autoload' => true));
/* @var $address_dummy AddressesItem */
$address_prefixes = Array ('Billing', 'Shipping');
$address_fields = Array (
'To', 'Company', 'Phone', 'Fax', 'Email', 'Address1',
'Address2', 'City', 'State', 'Zip', 'Country'
);
foreach ($address_prefixes as $address_prefix) {
$address_id = $this->Application->GetVar(strtolower($address_prefix) . '_address_id');
if ( !$this->Application->GetVar('check_' . strtolower($address_prefix) . '_address') ) {
// form type doesn't match check type, e.g. shipping check on billing form
continue;
}
if ( $address_id > 0 ) {
$address_dummy->Load($address_id);
}
else {
$address_dummy->SetDBField('PortalUserId', $this->Application->RecallVar('user_id'));
}
foreach ($address_fields as $address_field) {
$address_dummy->SetDBField($address_field, $object->GetDBField($address_prefix . $address_field));
}
$address_dummy->MarkAddress($address_prefix, false);
$ret = ($address_id > 0) ? $address_dummy->Update() : $address_dummy->Create();
}
}
/**
* Updates shopping cart content
*
* @param kEvent $event
* @return void
* @access protected
*/
protected function OnUpdateCart($event)
{
$this->Application->HandleEvent(new kEvent('orditems:OnUpdate'));
$event->CallSubEvent('OnRecalculateItems');
}
/**
* Updates cart and returns various info in JSON format
*
* @param kEvent $event
*/
function OnUpdateCartJSON($event)
{
if ( $this->Application->GetVar('ajax') != 'yes' ) {
return;
}
$object = $event->getObject();
/* @var $object kDBItem */
// 1. delete given order item by id
$delete_id = $this->Application->GetVar('delete_id');
if ( $delete_id !== false ) {
$sql = 'DELETE FROM ' . TABLE_PREFIX . 'OrderItems
WHERE OrderId = ' . $object->GetID() . ' AND OrderItemId = ' . (int)$delete_id;
$this->Conn->Query($sql);
}
// 2. remove coupon
$remove = $this->Application->GetVar('remove');
if ( $remove == 'coupon' ) {
$this->RemoveCoupon($object);
$object->setCheckoutError(OrderCheckoutErrorType::COUPON, OrderCheckoutError::COUPON_REMOVED);
}
elseif ( $remove == 'gift_certificate' ) {
$this->RemoveGiftCertificate($object);
$object->setCheckoutError(OrderCheckoutErrorType::GIFT_CERTIFICATE, OrderCheckoutError::GC_REMOVED);
}
// 3. update product quantities and recalculate all discounts
$this->Application->HandleEvent(new kEvent('orditems:OnUpdate'));
$event->CallSubEvent('OnRecalculateItems');
// 4. remove "orditems" object of kDBItem class, since getOrderInfo uses kDBList object under same prefix
$this->Application->removeObject('orditems');
$order_helper = $this->Application->recallObject('OrderHelper');
/* @var $order_helper OrderHelper */
$event->status = kEvent::erSTOP;
$currency = $this->Application->GetVar('currency', 'selected');
echo json_encode( $order_helper->getOrderInfo($object, $currency) );
}
/**
* Adds item to cart
*
* @param kEvent $event
*/
function OnAddToCart($event)
{
$this->StoreContinueShoppingLink();
$qty = $this->Application->GetVar('qty');
$options = $this->Application->GetVar('options');
// multiple or options add
$items = Array();
if (is_array($qty)) {
foreach ($qty as $item_id => $combinations)
{
if (is_array($combinations)) {
foreach ($combinations as $comb_id => $comb_qty) {
if ($comb_qty == 0) continue;
$items[] = array('item_id' => $item_id, 'qty' => $comb_qty, 'comb' => $comb_id);
}
}
else {
$items[] = array('item_id' => $item_id, 'qty' => $combinations);
}
}
}
if (!$items) {
if (!$qty || is_array($qty)) $qty = 1;
$item_id = $this->Application->GetVar('p_id');
if (!$item_id) return ;
$items = array(array('item_id' => $item_id, 'qty' => $qty));
}
// remember item data passed to event when called
$default_item_data = $event->getEventParam('ItemData');
$default_item_data = $default_item_data ? unserialize($default_item_data) : Array();
foreach ($items as $an_item) {
$item_id = $an_item['item_id'];
$qty = $an_item['qty'];
$comb = getArrayValue($an_item, 'comb');
$item_data = $default_item_data;
$product = $this->Application->recallObject('p', null, Array('skip_autoload' => true));
/* @var $product ProductsItem */
$product->Load($item_id);
$event->setEventParam('ItemData', null);
if ($product->GetDBField('AssignedCoupon')) {
$item_data['AssignedCoupon'] = $product->GetDBField('AssignedCoupon');
}
// 1. store options information OR
if ($comb) {
$combination = $this->Conn->GetOne('SELECT Combination FROM '.TABLE_PREFIX.'ProductOptionCombinations WHERE CombinationId = '.$comb);
$item_data['Options'] = unserialize($combination);
}
elseif (is_array($options)) {
$item_data['Options'] = $options[$item_id];
}
// 2. store subscription information OR
if( $product->GetDBField('Type') == 2 ) // subscriptions
{
$item_data = $this->BuildSubscriptionItemData($item_id, $item_data);
}
// 3. store package information
if( $product->GetDBField('Type') == 5 ) // package
{
$package_content_ids = $product->GetPackageContentIds();
$product_package_item = $this->Application->recallObject('p.-packageitem');
/* @var $product_package_item ProductsItem */
$package_item_data = array();
foreach ($package_content_ids as $package_item_id){
$product_package_item->Load($package_item_id);
$package_item_data[$package_item_id] = array();
if( $product_package_item->GetDBField('Type') == 2 ) // subscriptions
{
$package_item_data[$package_item_id] = $this->BuildSubscriptionItemData($package_item_id, $item_data);
}
}
$item_data['PackageContent'] = $product->GetPackageContentIds();
$item_data['PackageItemsItemData'] = $package_item_data;
}
$event->setEventParam('ItemData', serialize($item_data));
// 1 for PacakgeNum when in admin - temporary solution to overcome splitting into separate sub-orders
// of orders with items added through admin when approving them
$this->AddItemToOrder($event, $item_id, $qty, $this->Application->isAdminUser ? 1 : null);
}
if ($event->status == kEvent::erSUCCESS && !$event->redirect) {
$event->SetRedirectParam('pass', 'm');
$event->SetRedirectParam('pass_category', 0); //otherwise mod-rewrite shop-cart URL will include category
$event->redirect = true;
}
else {
if ($this->Application->isAdminUser) {
$event->SetRedirectParam('opener', 'u');
}
}
}
/**
* Returns table prefix from event (temp or live)
*
* @param kEvent $event
* @return string
* @todo Needed? Should be refactored (by Alex)
*/
function TablePrefix(kEvent $event)
{
return $this->UseTempTables($event) ? $this->Application->GetTempTablePrefix('prefix:' . $event->Prefix) . TABLE_PREFIX : TABLE_PREFIX;
}
/**
* Check if required options are selected & selected option combination is in stock
*
* @param kEvent $event
* @param Array $options
* @param int $product_id
* @param int $qty
* @param int $selection_mode
* @return bool
*/
function CheckOptions($event, &$options, $product_id, $qty, $selection_mode)
{
// 1. check for required options
$selection_filter = $selection_mode == 1 ? ' AND OptionType IN (1,3,6) ' : '';
$req_options = $this->Conn->GetCol('SELECT ProductOptionId FROM '.TABLE_PREFIX.'ProductOptions WHERE ProductId = '.$product_id.' AND Required = 1 '.$selection_filter);
$result = true;
foreach ($req_options as $opt_id) {
if (!getArrayValue($options, $opt_id)) {
$this->Application->SetVar('opt_error', 1); //let the template know we have an error
$result = false;
}
}
// 2. check for option combinations in stock
$comb_salt = $this->OptionsSalt($options, true);
if ($comb_salt) {
+ $poc_config = $this->Application->getUnitConfig('poc');
+
// such option combination is defined explicitly
- $poc_table = $this->Application->getUnitOption('poc', 'TableName');
+ $poc_table = $poc_config->getTableName();
$sql = 'SELECT Availability
FROM '.$poc_table.'
WHERE CombinationCRC = '.$comb_salt;
$comb_availble = $this->Conn->GetOne($sql);
// 2.1. check if Availability flag is set, then
if ($comb_availble == 1) {
// 2.2. check for quantity in stock
$table = Array();
- $table['poc'] = $this->Application->getUnitOption('poc', 'TableName');
- $table['p'] = $this->Application->getUnitOption('p', 'TableName');
+ $table['poc'] = $poc_config->getTableName();
+ $table['p'] = $this->Application->getUnitConfig('p')->getTableName();
$table['oi'] = $this->TablePrefix($event).'OrderItems';
$object = $event->getObject();
$ord_id = $object->GetID();
// 2.3. check if some amount of same combination & product are not already in shopping cart
$sql = 'SELECT '.
$table['p'].'.InventoryStatus,'.
$table['p'].'.BackOrder,
IF('.$table['p'].'.InventoryStatus = 2, '.$table['poc'].'.QtyInStock, '.$table['p'].'.QtyInStock) AS QtyInStock,
IF('.$table['oi'].'.OrderItemId IS NULL, 0, '.$table['oi'].'.Quantity) AS Quantity
FROM '.$table['p'].'
LEFT JOIN '.$table['poc'].' ON
'.$table['p'].'.ProductId = '.$table['poc'].'.ProductId
LEFT JOIN '.$table['oi'].' ON
('.$table['oi'].'.OrderId = '.$ord_id.') AND
('.$table['oi'].'.OptionsSalt = '.$comb_salt.') AND
('.$table['oi'].'.ProductId = '.$product_id.') AND
('.$table['oi'].'.BackOrderFlag = 0)
WHERE '.$table['poc'].'.CombinationCRC = '.$comb_salt;
$product_info = $this->Conn->GetRow($sql);
if ($product_info['InventoryStatus']) {
$backordering = $this->Application->ConfigValue('Comm_Enable_Backordering');
if (!$backordering || $product_info['BackOrder'] == 0) {
// backordering is not enabled generally or for this product directly, then check quantities in stock
if ($qty + $product_info['Quantity'] > $product_info['QtyInStock']) {
$this->Application->SetVar('opt_error', 2);
$result = false;
}
}
}
}
elseif ($comb_availble !== false) {
$this->Application->SetVar('opt_error', 2);
$result = false;
}
}
if ($result) {
$event->status = kEvent::erSUCCESS;
$shop_cart_template = $this->Application->GetVar('shop_cart_template');
$event->redirect = $this->Application->isAdminUser || !$shop_cart_template ? true : $shop_cart_template;
}
else {
$event->status = kEvent::erFAIL;
}
return $result;
}
/**
* Enter description here...
*
* @param kEvent $event
*/
function OnUpdateItemOptions($event)
{
$opt_data = $this->Application->GetVar('options');
$options = getArrayValue($opt_data, $this->Application->GetVar('p_id'));
if (!$options) {
$qty_data = $this->Application->GetVar('qty');
$comb_id = key(getArrayValue($qty_data, $this->Application->GetVar('p_id')));
$options = unserialize($this->Conn->GetOne('SELECT Combination FROM '.TABLE_PREFIX.'ProductOptionCombinations WHERE CombinationId = '.$comb_id));
}
if (!$options) return;
$ord_item = $this->Application->recallObject('orditems.-opt', null, Array ('skip_autoload' => true));
/* @var $ord_item kDBItem */
$ord_item->Load($this->Application->GetVar('orditems_id'));
// assuming that quantity cannot be changed during order item editing
if (!$this->CheckOptions($event, $options, $ord_item->GetDBField('ProductId'), 0, $ord_item->GetDBField('OptionsSelectionMode'))) return;
$item_data = unserialize($ord_item->GetDBField('ItemData'));
$item_data['Options'] = $options;
$ord_item->SetDBField('ItemData', serialize($item_data));
$ord_item->SetDBField('OptionsSalt', $this->OptionsSalt($options));
$ord_item->Update();
$event->CallSubEvent('OnRecalculateItems');
if ($event->status == kEvent::erSUCCESS && $this->Application->isAdminUser) {
$event->SetRedirectParam('opener', 'u');
}
}
function BuildSubscriptionItemData($item_id, $item_data)
{
- $products_table = $this->Application->getUnitOption('p', 'TableName');
- $products_idfield = $this->Application->getUnitOption('p', 'IDField');
- $sql = 'SELECT AccessGroupId FROM %s WHERE %s = %s';
- $item_data['PortalGroupId'] = $this->Conn->GetOne( sprintf($sql, $products_table, $products_idfield, $item_id) );
+ $products_config = $this->Application->getUnitConfig('p');
- $pricing_table = $this->Application->getUnitOption('pr', 'TableName');
- $pricing_idfield = $this->Application->getUnitOption('pr', 'IDField');
+ $sql = 'SELECT AccessGroupId
+ FROM ' . $products_config->getTableName() . '
+ WHERE ' . $products_config->getIDField() . ' = ' . $item_id;
+ $item_data['PortalGroupId'] = $this->Conn->GetOne($sql);
/* TODO check on implementation
- $sql = 'SELECT AccessDuration, AccessUnit, DurationType, AccessExpiration FROM %s WHERE %s = %s';
+ $sql = 'SELECT AccessDuration, AccessUnit, DurationType, AccessExpiration
+ FROM %s
+ WHERE %s = %s';
*/
- $sql = 'SELECT * FROM %s WHERE %s = %s';
+ $pricing_config = $this->Application->getUnitConfig('pr');
$pricing_id = $this->GetPricingId($item_id, $item_data);
+
+ $sql = 'SELECT *
+ FROM ' . $pricing_config->getTableName() . '
+ WHERE ' . $pricing_config->getIDField() . ' = ' . $pricing_id;
+ $pricing_info = $this->Conn->GetRow($sql);
+
$item_data['PricingId'] = $pricing_id;
- $pricing_info = $this->Conn->GetRow( sprintf($sql, $pricing_table, $pricing_idfield, $pricing_id ) );
$unit_secs = Array(1 => 1, 2 => 60, 3 => 3600, 4 => 86400, 5 => 604800, 6 => 2592000, 7 => 31536000);
/* TODO check on implementation (code from customization healtheconomics.org)
$item_data['DurationType'] = $pricing_info['DurationType'];
$item_data['AccessExpiration'] = $pricing_info['AccessExpiration'];
*/
$item_data['Duration'] = $pricing_info['AccessDuration'] * $unit_secs[ $pricing_info['AccessUnit'] ];
return $item_data;
}
/**
* Enter description here...
*
* @param kEvent $event
*/
function OnApplyCoupon($event)
{
$code = $this->Application->GetVar('coupon_code');
if ($code == '') {
return ;
}
$object = $event->getObject();
/* @var $object OrdersItem */
$coupon = $this->Application->recallObject('coup', null, Array ('skip_autoload' => true));
/* @var $coupon kDBItem */
$coupon->Load($code, 'Code');
if ( !$coupon->isLoaded() ) {
$event->status = kEvent::erFAIL;
$object->setCheckoutError(OrderCheckoutErrorType::COUPON, OrderCheckoutError::COUPON_CODE_INVALID);
$event->redirect = false; // check!!!
return ;
}
$expire_date = $coupon->GetDBField('Expiration');
$number_of_use = $coupon->GetDBField('NumberOfUses');
if ( $coupon->GetDBField('Status') != 1 || ($expire_date && $expire_date < adodb_mktime()) ||
(isset($number_of_use) && $number_of_use <= 0))
{
$event->status = kEvent::erFAIL;
$object->setCheckoutError(OrderCheckoutErrorType::COUPON, OrderCheckoutError::COUPON_CODE_EXPIRED);
$event->redirect = false;
return ;
}
$last_used = adodb_mktime();
$coupon->SetDBField('LastUsedBy', $this->Application->RecallVar('user_id'));
$coupon->SetDBField('LastUsedOn_date', $last_used);
$coupon->SetDBField('LastUsedOn_time', $last_used);
if ( isset($number_of_use) ) {
$coupon->SetDBField('NumberOfUses', $number_of_use - 1);
if ($number_of_use == 1) {
$coupon->SetDBField('Status', 2);
}
}
$coupon->Update();
- $this->Application->setUnitOption('ord', 'AutoLoad', true);
+ $this->Application->getUnitConfig('ord')->setAutoLoad(true);
$order = $this->Application->recallObject('ord');
/* @var $order OrdersItem */
$order->SetDBField('CouponId', $coupon->GetDBField('CouponId'));
$order->SetDBField('CouponName', $coupon->GetDBField('Name')); // calculated field
$order->Update();
$object->setCheckoutError(OrderCheckoutErrorType::COUPON, OrderCheckoutError::COUPON_APPLIED);
// OnApplyCoupon is called as hook for OnUpdateCart/OnCheckout, which calls OnRecalcualate themself
}
/**
* Removes coupon from order
*
* @param kEvent $event
* @deprecated
*/
function OnRemoveCoupon($event)
{
$object = $event->getObject();
/* @var $object OrdersItem */
$this->RemoveCoupon($object);
$object->setCheckoutError(OrderCheckoutErrorType::COUPON, OrderCheckoutError::COUPON_REMOVED);
$event->CallSubEvent('OnRecalculateItems');
}
/**
* Removes coupon from a given order
*
* @param OrdersItem $object
*/
function RemoveCoupon(&$object)
{
$coupon = $this->Application->recallObject('coup', null, Array('skip_autoload' => true));
/* @var $coupon kDBItem */
$coupon->Load( $object->GetDBField('CouponId') );
if ( $coupon->isLoaded() ) {
$coupon->SetDBField('NumberOfUses', $coupon->GetDBField('NumberOfUses') + 1);
$coupon->SetDBField('Status', STATUS_ACTIVE);
$coupon->Update();
}
$object->SetDBField('CouponId', 0);
$object->SetDBField('CouponName', ''); // calculated field
$object->SetDBField('CouponDiscount', 0);
}
/**
* Enter description here...
*
* @param kEvent $event
*/
function OnAddVirtualProductToCart($event)
{
$l_info = $this->Application->GetVar('l');
if($l_info)
{
foreach($l_info as $link_id => $link_info) {}
$item_data['LinkId'] = $link_id;
$item_data['ListingTypeId'] = $link_info['ListingTypeId'];
}
else
{
$link_id = $this->Application->GetVar('l_id');
- $sql = 'SELECT ResourceId FROM '.$this->Application->getUnitOption('l', 'TableName').'
+ $sql = 'SELECT ResourceId FROM '.$this->Application->getUnitConfig('l')->getTableName().'
WHERE LinkId = '.$link_id;
- $sql = 'SELECT ListingTypeId FROM '.$this->Application->getUnitOption('ls', 'TableName').'
+ $sql = 'SELECT ListingTypeId FROM '.$this->Application->getUnitConfig('ls')->getTableName().'
WHERE ItemResourceId = '.$this->Conn->GetOne($sql);
$item_data['LinkId'] = $link_id;
$item_data['ListingTypeId'] = $this->Conn->GetOne($sql);
}
- $sql = 'SELECT VirtualProductId FROM '.$this->Application->getUnitOption('lst', 'TableName').'
+ $sql = 'SELECT VirtualProductId FROM '.$this->Application->getUnitConfig('lst')->getTableName().'
WHERE ListingTypeId = '.$item_data['ListingTypeId'];
$item_id = $this->Conn->GetOne($sql);
$event->setEventParam('ItemData', serialize($item_data));
$this->AddItemToOrder($event, $item_id);
$shop_cart_template = $this->Application->GetVar('shop_cart_template');
if ( $shop_cart_template ) {
$event->redirect = $shop_cart_template;
}
// don't pass unused info to shopping cart, brokes old mod-rewrites
$event->SetRedirectParam('pass', 'm'); // not to pass link id
$event->SetRedirectParam('m_cat_id', 0); // not to pass link id
}
function OnRemoveFromCart($event)
{
$ord_item_id = $this->Application->GetVar('orditems_id');
$ord_id = $this->getPassedID($event);
$this->Conn->Query('DELETE FROM '.TABLE_PREFIX.'OrderItems WHERE OrderId = '.$ord_id.' AND OrderItemId = '.$ord_item_id);
$this->OnRecalculateItems($event);
}
function OnCleanupCart($event)
{
$object = $event->getObject();
$sql = 'DELETE FROM '.TABLE_PREFIX.'OrderItems
WHERE OrderId = '.$this->getPassedID($event);
$this->Conn->Query($sql);
$this->RemoveCoupon($object);
$this->RemoveGiftCertificate($object);
$this->OnRecalculateItems($event);
}
/**
* Returns order id from session or last used
*
* @param kEvent $event
* @return int
* @access public
*/
public function getPassedID(kEvent $event)
{
$event->setEventParam('raise_warnings', 0);
$passed = parent::getPassedID($event);
if ( $this->Application->isAdminUser ) {
// work as usual in admin
return $passed;
}
if ( $event->Special == 'last' ) {
// return last order id (for using on thank you page)
$order_id = $this->Application->RecallVar('front_order_id');
return $order_id > 0 ? $order_id : FAKE_ORDER_ID; // FAKE_ORDER_ID helps to keep parent filter for order items set in "kDBList::linkToParent"
}
$ses_id = $this->Application->RecallVar($event->getPrefixSpecial(true) . '_id');
if ( $passed && ($passed != $ses_id) ) {
// order id given in url doesn't match our current order id
$sql = 'SELECT PortalUserId
FROM ' . TABLE_PREFIX . 'Orders
WHERE OrderId = ' . $passed;
$user_id = $this->Conn->GetOne($sql);
if ( $user_id == $this->Application->RecallVar('user_id') ) {
// current user is owner of order with given id -> allow him to view order details
return $passed;
}
else {
// current user is not owner of given order -> hacking attempt
$this->Application->SetVar($event->getPrefixSpecial() . '_id', 0);
return 0;
}
}
// not passed or equals to ses_id
return $ses_id > 0 ? $ses_id : FAKE_ORDER_ID; // FAKE_ORDER_ID helps to keep parent filter for order items set in "kDBList::linkToParent"
}
/**
* Load item if id is available
*
* @param kEvent $event
* @return void
* @access protected
*/
protected function LoadItem(kEvent $event)
{
$id = $this->getPassedID($event);
if ( $id == FAKE_ORDER_ID ) {
// if we already know, that there is no such order,
// then don't run database query, that will confirm that
$object = $event->getObject();
/* @var $object kDBItem */
$object->Clear($id);
return;
}
parent::LoadItem($event);
}
/**
* Creates new shopping cart
*
* @param kEvent $event
*/
function _createNewCart($event)
{
$object = $event->getObject( Array('skip_autoload' => true) );
/* @var $object kDBItem */
$this->setNextOrderNumber($event);
$object->SetDBField('Status', ORDER_STATUS_INCOMPLETE);
$object->SetDBField('VisitId', $this->Application->RecallVar('visit_id') );
// get user
if ( $this->Application->LoggedIn() ) {
$user = $this->Application->recallObject('u.current');
/* @var $user UsersItem */
$user_id = $user->GetID();
$object->SetDBField('BillingEmail', $user->GetDBField('Email'));
}
else {
$user_id = USER_GUEST;
}
$object->SetDBField('PortalUserId', $user_id);
// get affiliate
$affiliate_id = $this->isAffiliate($user_id);
if ( $affiliate_id ) {
$object->SetDBField('AffiliateId', $affiliate_id);
}
else {
$affiliate_storage_method = $this->Application->ConfigValue('Comm_AffiliateStorageMethod');
if ( $affiliate_storage_method == 1 ) {
$object->SetDBField('AffiliateId', (int)$this->Application->RecallVar('affiliate_id'));
}
else {
$object->SetDBField('AffiliateId', (int)$this->Application->GetVar('affiliate_id'));
}
}
// get payment type
$default_type = $this->_getDefaultPaymentType();
if ( $default_type ) {
$object->SetDBField('PaymentType', $default_type);
}
// vat setting
$object->SetDBField('VATIncluded', $this->Application->ConfigValue('OrderVATIncluded'));
$created = $object->Create();
if ( $created ) {
$id = $object->GetID();
$this->Application->SetVar($event->getPrefixSpecial(true) . '_id', $id);
$this->Application->StoreVar($event->getPrefixSpecial(true) . '_id', $id);
$this->Application->Session->SetCookie('shop_cart_cookie', $id, strtotime('+1 month'));
return $id;
}
return 0;
}
/**
* Returns default payment type for order
*
* @return int
*/
function _getDefaultPaymentType()
{
$default_type = $this->Application->siteDomainField('PrimaryPaymentTypeId');
if (!$default_type) {
$sql = 'SELECT PaymentTypeId
FROM ' . TABLE_PREFIX . 'PaymentTypes
WHERE IsPrimary = 1';
$default_type = $this->Conn->GetOne($sql);
}
return $default_type;
}
function StoreContinueShoppingLink()
{
$this->Application->StoreVar('continue_shopping', 'external:'.PROTOCOL.SERVER_NAME.$this->Application->RecallVar('last_url'));
}
/**
* Sets required fields for order, based on current checkout step
* !!! Do not use switch here, since all cases may be on the same form simultaneously
*
* @param kEvent $event
*/
function SetStepRequiredFields($event)
{
$order = $event->getObject();
/* @var $order OrdersItem */
$cs_helper = $this->Application->recallObject('CountryStatesHelper');
/* @var $cs_helper kCountryStatesHelper */
$items_info = $this->Application->GetVar($event->getPrefixSpecial(true));
if ($items_info) {
// updated address available from SUBMIT -> use it
list($id, $field_values) = each($items_info);
}
else {
// no updated address -> use current address
$field_values = Array (
'ShippingCountry' => $order->GetDBField('ShippingCountry'),
'BillingCountry' => $order->GetDBField('BillingCountry'),
'PaymentType' => $order->GetDBField('PaymentType'),
);
}
// shipping address required fields
if ($this->Application->GetVar('check_shipping_address')) {
$has_tangibles = $order->HasTangibleItems();
$req_fields = array('ShippingTo', 'ShippingAddress1', 'ShippingCity', 'ShippingZip', 'ShippingCountry', /*'ShippingPhone',*/ 'BillingEmail');
$order->setRequired($req_fields, $has_tangibles);
$order->setRequired('ShippingState', $cs_helper->CountryHasStates( $field_values['ShippingCountry'] ));
}
// billing address required fields
if ($this->Application->GetVar('check_billing_address')) {
$req_fields = array('BillingTo', 'BillingAddress1', 'BillingCity', 'BillingZip', 'BillingCountry', 'BillingPhone', 'BillingEmail');
$order->setRequired($req_fields);
$order->setRequired('BillingState', $cs_helper->CountryHasStates( $field_values['BillingCountry'] ));
}
$check_cc = $this->Application->GetVar('check_credit_card');
if ( $check_cc && ($field_values['PaymentType'] == $order->GetDBField('PaymentType')) ) {
// cc check required AND payment type was not changed during SUBMIT
if ( $this->Application->isAdminUser ) {
$req_fields = Array (/*'PaymentCardType',*/ 'PaymentAccount', /*'PaymentNameOnCard',*/ 'PaymentCCExpDate');
}
else {
$req_fields = Array (/*'PaymentCardType',*/ 'PaymentAccount', /*'PaymentNameOnCard',*/ 'PaymentCCExpDate', 'PaymentCVV2');
}
$order->setRequired($req_fields);
}
}
/**
* Set's order's user_id to user from session or Guest otherwise
*
* @param kEvent $event
*/
function CheckUser($event)
{
if ($this->Application->isAdminUser || defined('GW_NOTIFY')) {
// don't check for user in order while processing payment
// gateways, because they can do cross-domain ssl redirects
return;
}
$order = $event->getObject();
/* @var $order OrdersItem */
$ses_user = $this->Application->RecallVar('user_id');
if ( $order->GetDBField('PortalUserId') != $ses_user ) {
if ( $ses_user == 0 ) {
$ses_user = USER_GUEST;
}
$order->SetDBField('PortalUserId', $ses_user);
// since CheckUser is called in OnBeforeItemUpdate, we don't need to call udpate here, just set the field
}
}
/* ======================== ADMIN ONLY ======================== */
/**
* Prepare temp tables for creating new item
* but does not create it. Actual create is
* done in OnPreSaveCreated
*
* @param kEvent $event
* @return void
* @access protected
*/
protected function OnPreCreate(kEvent $event)
{
parent::OnPreCreate($event);
$object = $event->getObject();
/* @var $object kDBItem */
$this->setNextOrderNumber($event);
$object->SetDBField('OrderIP', $this->Application->getClientIp());
$order_type = $this->getTypeBySpecial( $this->Application->GetVar('order_type') );
$object->SetDBField('Status', $order_type);
}
/**
* When cloning orders set new order number to them
*
* @param kEvent $event
* @return void
* @access protected
*/
protected function OnBeforeClone(kEvent $event)
{
parent::OnBeforeClone($event);
$object = $event->getObject();
/* @var $object OrdersItem */
if ( substr($event->Special, 0, 9) == 'recurring' ) {
$object->SetDBField('SubNumber', $object->getNextSubNumber());
$object->SetDBField('OriginalAmount', 0); // needed in this case ?
}
else {
$this->setNextOrderNumber($event);
$object->SetDBField('OriginalAmount', 0);
}
$object->SetDBField('OrderDate', adodb_mktime());
$object->UpdateFormattersSubFields();
$object->SetDBField('GWResult1', '');
$object->SetDBField('GWResult2', '');
}
function OnReserveItems($event)
{
$order_items = $this->Application->recallObject('orditems.-inv','orditems_List',Array('skip_counting'=>true,'per_page'=>-1) );
/* @var $order_items kDBList */
$order_items->linkToParent('-inv');
// force re-query, since we are updateing through orditem ITEM, not the list, and
// OnReserveItems may be called 2 times when fullfilling backorders through product edit - first time
// from FullFillBackorders and second time from OnOrderProcess
$order_items->Query(true);
$order_items->GoFirst();
// query all combinations used in this order
$product_object = $this->Application->recallObject('p', null, Array('skip_autoload' => true));
/* @var $product_object kCatDBItem */
$product_object->SwitchToLive();
$order_item = $this->Application->recallObject('orditems.-item', null, Array('skip_autoload' => true));
/* @var $order_item kDBItem */
$combination_item = $this->Application->recallObject('poc.-item', null, Array('skip_autoload' => true));
/* @var $combination_item kDBItem */
$combinations = $this->queryCombinations($order_items);
$event->status = kEvent::erSUCCESS;
while (!$order_items->EOL()) {
$rec = $order_items->getCurrentRecord();
$product_object->Load( $rec['ProductId'] );
if (!$product_object->GetDBField('InventoryStatus')) {
$order_items->GoNext();
continue;
}
$inv_object =& $this->getInventoryObject($product_object, $combination_item, $combinations[ $rec['ProductId'].'_'.$rec['OptionsSalt'] ]);
$lack = $rec['Quantity'] - $rec['QuantityReserved'];
if ($lack > 0) {
// reserve lack or what is available (in case if we need to reserve anything, by Alex)
$to_reserve = min($lack, $inv_object->GetDBField('QtyInStock') - $product_object->GetDBField('QtyInStockMin'));
if ($to_reserve < $lack) $event->status = kEvent::erFAIL; // if we can't reserve the full lack
//reserve in order
$order_item->SetDBFieldsFromHash($rec);
$order_item->SetDBField('QuantityReserved', $rec['QuantityReserved'] + $to_reserve);
$order_item->SetId($rec['OrderItemId']);
$order_item->Update();
//update product - increase reserved, decrease in stock
$inv_object->SetDBField('QtyReserved', $inv_object->GetDBField('QtyReserved') + $to_reserve);
$inv_object->SetDBField('QtyInStock', $inv_object->GetDBField('QtyInStock') - $to_reserve);
$inv_object->SetDBField('QtyBackOrdered', $inv_object->GetDBField('QtyBackOrdered') - $to_reserve);
$inv_object->Update();
if ($product_object->GetDBField('InventoryStatus') == 2) {
// inventory by options, then restore changed combination values back to common $combinations array !!!
$combinations[ $rec['ProductId'].'_'.$rec['OptionsSalt'] ] = $inv_object->GetFieldValues();
}
}
$order_items->GoNext();
}
return true;
}
function OnOrderPrint($event)
{
$event->SetRedirectParam('opener', 's');
}
/**
* Processes order each tab info resetting to other tab info / to user info
*
* @param kEvent $event
* @access public
*/
function OnResetAddress($event)
{
$to_tab = $this->Application->GetVar('to_tab');
$from_tab = substr($event->Name, strlen('OnResetTo'));
// load values from db
$object = $event->getObject();
/* @var $object kDBItem */
// update values from submit
$field_values = $this->getSubmittedFields($event);
$object->SetFieldsFromHash($field_values, $this->getRequestProtectedFields($field_values));
$this->DoResetAddress($object, $from_tab, $to_tab);
$object->Update();
$event->redirect = false;
}
/**
* Processes item selection from popup item selector
*
* @todo Is this called ? (by Alex)
* @param kEvent $event
*/
function OnProcessSelected($event)
{
$selected_ids = $this->Application->GetVar('selected_ids');
$product_ids = $selected_ids['p'];
if ($product_ids) {
$product_ids = explode(',', $product_ids);
// !!! LOOK OUT - Adding items to Order in admin is handled in order_ITEMS_event_handler !!!
foreach ($product_ids as $product_id) {
$this->AddItemToOrder($event, $product_id);
}
}
$event->SetRedirectParam('opener', 'u');
}
function OnMassPlaceOrder($event)
{
$object = $event->getObject( Array('skip_autoload' => true) );
$ids = $this->StoreSelectedIDs($event);
if($ids)
{
foreach($ids as $id)
{
$object->Load($id);
$this->DoPlaceOrder($event);
}
}
$event->status = kEvent::erSUCCESS;
}
/**
* Universal
* Checks if QtyInStock is enough to fullfill backorder (Qty - QtyReserved in order)
*
* @param int $ord_id
* @return bool
*/
function ReadyToProcess($ord_id)
{
- $poc_table = $this->Application->getUnitOption('poc', 'TableName');
+ $poc_table = $this->Application->getUnitConfig('poc')->getTableName();
+
$query = ' SELECT SUM(IF( IF('.TABLE_PREFIX.'Products.InventoryStatus = 2, '.$poc_table.'.QtyInStock, '.TABLE_PREFIX.'Products.QtyInStock) - '.TABLE_PREFIX.'Products.QtyInStockMin >= ('.TABLE_PREFIX.'OrderItems.Quantity - '.TABLE_PREFIX.'OrderItems.QuantityReserved), 0, 1))
FROM '.TABLE_PREFIX.'OrderItems
LEFT JOIN '.TABLE_PREFIX.'Products ON '.TABLE_PREFIX.'Products.ProductId = '.TABLE_PREFIX.'OrderItems.ProductId
LEFT JOIN '.$poc_table.' ON ('.$poc_table.'.CombinationCRC = '.TABLE_PREFIX.'OrderItems.OptionsSalt) AND ('.$poc_table.'.ProductId = '.TABLE_PREFIX.'OrderItems.ProductId)
WHERE OrderId = '.$ord_id.'
GROUP BY OrderId';
// IF (IF(InventoryStatus = 2, poc.QtyInStock, p.QtyInStock) - QtyInStockMin >= (Quantity - QuantityReserved), 0, 1
return ($this->Conn->GetOne($query) == 0);
}
/**
* Return all option combinations used in order
*
* @param kDBList $order_items
* @return Array
*/
function queryCombinations(&$order_items)
{
// 1. collect combination crc used in order
$combinations = Array();
while (!$order_items->EOL()) {
$row = $order_items->getCurrentRecord();
if ($row['OptionsSalt'] == 0) {
$order_items->GoNext();
continue;
}
$combinations[] = '(poc.ProductId = '.$row['ProductId'].') AND (poc.CombinationCRC = '.$row['OptionsSalt'].')';
$order_items->GoNext();
}
$order_items->GoFirst();
$combinations = array_unique($combinations); // if same combination+product found as backorder & normal order item
if ($combinations) {
// 2. query data about combinations
- $poc_table = $this->Application->getUnitOption('poc', 'TableName');
+ $poc_table = $this->Application->getUnitConfig('poc')->getTableName();
+
$sql = 'SELECT CONCAT(poc.ProductId, "_", poc.CombinationCRC) AS CombinationKey, poc.*
FROM '.$poc_table.' poc
WHERE ('.implode(') OR (', $combinations).')';
return $this->Conn->Query($sql, 'CombinationKey');
}
return Array();
}
/**
* Returns object to perform inventory actions on
*
* @param ProductsItem $product current product object in order
* @param kDBItem $combination combination dummy object
* @param Array $combination_data pre-queried combination data
* @return kDBItem
*/
function &getInventoryObject(&$product, &$combination, $combination_data)
{
if ($product->GetDBField('InventoryStatus') == 2) {
// inventory by option combinations
$combination->SetDBFieldsFromHash($combination_data);
$combination->setID($combination_data['CombinationId']);
$change_item =& $combination;
}
else {
// inventory by product ifself
$change_item =& $product;
}
return $change_item;
}
/**
* Approve order ("Pending" tab)
*
* @param kDBList $order_items
* @return int new status of order if any
*/
function approveOrder(&$order_items)
{
$product_object = $this->Application->recallObject('p', null, Array('skip_autoload' => true));
$order_item = $this->Application->recallObject('orditems.-item', null, Array('skip_autoload' => true));
$combination_item = $this->Application->recallObject('poc.-item', null, Array('skip_autoload' => true));
$combinations = $this->queryCombinations($order_items);
while (!$order_items->EOL()) {
$rec = $order_items->getCurrentRecord();
$order_item->SetDBFieldsFromHash($rec);
$order_item->SetId($rec['OrderItemId']);
$order_item->SetDBField('QuantityReserved', 0);
$order_item->Update();
$product_object->Load( $rec['ProductId'] );
if (!$product_object->GetDBField('InventoryStatus')) {
// if no inventory info is collected, then skip this order item
$order_items->GoNext();
continue;
}
$inv_object =& $this->getInventoryObject($product_object, $combination_item, $combinations[ $rec['ProductId'].'_'.$rec['OptionsSalt'] ]);
// decrease QtyReserved by amount of product used in order
$inv_object->SetDBField('QtyReserved', $inv_object->GetDBField('QtyReserved') - $rec['Quantity']);
$inv_object->Update();
if ($product_object->GetDBField('InventoryStatus') == 2) {
// inventory by options, then restore changed combination values back to common $combinations array !!!
$combinations[ $rec['ProductId'].'_'.$rec['OptionsSalt'] ] = $inv_object->GetFieldValues();
}
$order_items->GoNext();
}
return true;
}
/**
* Restores reserved items in the order
*
* @param kDBList $order_items
* @return bool
*/
function restoreOrder(&$order_items)
{
$product_object = $this->Application->recallObject('p', null, Array('skip_autoload' => true));
/* @var $product_object kCatDBItem */
$product_object->SwitchToLive();
$order_item = $this->Application->recallObject('orditems.-item', null, Array('skip_autoload' => true));
/* @var $order_item kDBItem */
$combination_item = $this->Application->recallObject('poc.-item', null, Array('skip_autoload' => true));
/* @var $combination_item kDBItem */
$combinations = $this->queryCombinations($order_items);
while( !$order_items->EOL() )
{
$rec = $order_items->getCurrentRecord();
$product_object->Load( $rec['ProductId'] );
if (!$product_object->GetDBField('InventoryStatus')) {
// if no inventory info is collected, then skip this order item
$order_items->GoNext();
continue;
}
$inv_object =& $this->getInventoryObject($product_object, $combination_item, $combinations[ $rec['ProductId'].'_'.$rec['OptionsSalt'] ]);
// cancelling backorderd qty if any
$lack = $rec['Quantity'] - $rec['QuantityReserved'];
if ($lack > 0 && $rec['BackOrderFlag'] > 0) { // lack should have been recorded as QtyBackOrdered
$inv_object->SetDBField('QtyBackOrdered', $inv_object->GetDBField('QtyBackOrdered') - $lack);
}
// canceling reservation in stock
$inv_object->SetDBField('QtyReserved', $inv_object->GetDBField('QtyReserved') - $rec['QuantityReserved']);
// putting remaining freed qty back to stock
$inv_object->SetDBField('QtyInStock', $inv_object->GetDBField('QtyInStock') + $rec['QuantityReserved']);
$inv_object->Update();
$product_h = $this->Application->recallObject('p_EventHandler');
/* @var $product_h ProductsEventHandler */
if ($product_object->GetDBField('InventoryStatus') == 2) {
// inventory by options, then restore changed combination values back to common $combinations array !!!
$combinations[ $rec['ProductId'].'_'.$rec['OptionsSalt'] ] = $inv_object->GetFieldValues();
// using freed qty to fulfill possible backorders
$product_h->FullfillBackOrders($product_object, $inv_object->GetID());
}
else {
// using freed qty to fulfill possible backorders
$product_h->FullfillBackOrders($product_object, 0);
}
$order_item->SetDBFieldsFromHash($rec);
$order_item->SetId($rec['OrderItemId']);
$order_item->SetDBField('QuantityReserved', 0);
$order_item->Update();
$order_items->GoNext();
}
return true;
}
/**
* Approve order + special processing
*
* @param kEvent $event
*/
function MassInventoryAction($event)
{
if ( $this->Application->CheckPermission('SYSTEM_ACCESS.READONLY', 1) ) {
$event->status = kEvent::erFAIL;
return;
}
// process order products
$object = $this->Application->recallObject($event->Prefix . '.-inv', null, Array ('skip_autoload' => true));
/* @var $object kDBItem */
$ids = $this->StoreSelectedIDs($event);
if ( $ids ) {
foreach ($ids as $id) {
$object->Load($id);
$this->InventoryAction($event);
}
}
}
function InventoryAction($event)
{
if ($this->Application->CheckPermission('SYSTEM_ACCESS.READONLY', 1)) {
$event->status = kEvent::erFAIL;
return;
}
$event_status_map = Array(
'OnMassOrderApprove' => ORDER_STATUS_TOSHIP,
'OnOrderApprove' => ORDER_STATUS_TOSHIP,
'OnMassOrderDeny' => ORDER_STATUS_DENIED,
'OnOrderDeny' => ORDER_STATUS_DENIED,
'OnMassOrderArchive' => ORDER_STATUS_ARCHIVED,
'OnOrderArchive' => ORDER_STATUS_ARCHIVED,
'OnMassOrderShip' => ORDER_STATUS_PROCESSED,
'OnOrderShip' => ORDER_STATUS_PROCESSED,
'OnMassOrderProcess' => ORDER_STATUS_TOSHIP,
'OnOrderProcess' => ORDER_STATUS_TOSHIP,
);
$order_items = $this->Application->recallObject('orditems.-inv','orditems_List',Array('skip_counting'=>true,'per_page'=>-1) );
/* @var $order_items kDBList */
$order_items->linkToParent('-inv');
$order_items->Query();
$order_items->GoFirst();
$object = $this->Application->recallObject($event->Prefix.'.-inv');
/* @var $object OrdersItem */
if ($object->GetDBField('OnHold')) {
// any actions have no effect while on hold
return ;
}
// save original order status
$original_order_status = $object->GetDBField('Status');
// preparing new status, but not setting it yet
$object->SetDBField('Status', $event_status_map[$event->Name]);
$set_new_status = false;
$event->status = kEvent::erSUCCESS;
$email_params = $this->OrderEmailParams($object);
switch ($event->Name) {
case 'OnMassOrderApprove':
case 'OnOrderApprove':
$set_new_status = false; //on successful approve order will be split and new orders will have new statuses
if ($object->GetDBField('ChargeOnNextApprove')) {
$charge_info = $this->ChargeOrder($object);
if (!$charge_info['result']) {
break;
}
// removing ChargeOnNextApprove
$object->SetDBField('ChargeOnNextApprove', 0);
$sql = 'UPDATE '.$object->TableName.' SET ChargeOnNextApprove = 0 WHERE '.$object->IDField.' = '.$object->GetID();
$this->Conn->Query($sql);
}
// charge user for order in case if we user 2step charging (e.g. AUTH_ONLY + PRIOR_AUTH_CAPTURE)
$gw_data = $object->getGatewayData();
$this->Application->registerClass( $gw_data['ClassName'], GW_CLASS_PATH.'/'.$gw_data['ClassFile'] );
$gateway_object = $this->Application->recallObject( $gw_data['ClassName'] );
/* @var $gateway_object kGWBase */
$charge_result = $gateway_object->Charge($object->GetFieldValues(), $gw_data['gw_params']);
$sql = 'UPDATE %s SET GWResult2 = %s WHERE %s = %s';
$sql = sprintf($sql, $object->TableName, $this->Conn->qstr($gateway_object->getGWResponce()), $object->IDField, $object->GetID() );
$this->Conn->Query($sql);
$object->SetDBField('GWResult2', $gateway_object->getGWResponce() );
if ($charge_result) {
$product_object = $this->Application->recallObject('p', null, Array('skip_autoload' => true));
/* @var $product_object ProductsItem */
foreach ($order_items->Records as $product_item) {
if (!$product_item['ProductId']) {
// product may have been deleted
continue;
}
$product_object->Load($product_item['ProductId']);
$hits = floor( $product_object->GetDBField('Hits') ) + 1;
- $sql = 'SELECT MAX(Hits) FROM '.$this->Application->getUnitOption('p', 'TableName').'
+ $sql = 'SELECT MAX(Hits) FROM '.$this->Application->getUnitConfig('p')->getTableName().'
WHERE FLOOR(Hits) = '.$hits;
$hits = ( $res = $this->Conn->GetOne($sql) ) ? $res + 0.000001 : $hits;
$product_object->SetDBField('Hits', $hits);
$product_object->Update();
- /*$sql = 'UPDATE '.$this->Application->getUnitOption('p', 'TableName').'
- SET Hits = Hits + '.$product_item['Quantity'].'
- WHERE ProductId = '.$product_item['ProductId'];
+ /*$sql = 'UPDATE ' . $this->Application->getUnitConfig('p')->getTableName() . '
+ SET Hits = Hits + ' . $product_item['Quantity'] . '
+ WHERE ProductId = ' . $product_item['ProductId'];
$this->Conn->Query($sql);*/
}
$this->PrepareCoupons($event, $object);
$this->SplitOrder($event, $object);
- if ( $object->GetDBField('IsRecurringBilling') != 1 ) {
+ if ($object->GetDBField('IsRecurringBilling') != 1) {
$this->Application->emailUser('ORDER.APPROVE', null, $email_params);
// Mask credit card with XXXX
- if ( $this->Application->ConfigValue('Comm_MaskProcessedCreditCards') ) {
+ if ($this->Application->ConfigValue('Comm_MaskProcessedCreditCards')) {
$this->maskCreditCard($object, 'PaymentAccount');
$set_new_status = 1;
}
}
}
break;
case 'OnMassOrderDeny':
case 'OnOrderDeny':
foreach ($order_items->Records as $product_item) {
if (!$product_item['ProductId']) {
// product may have been deleted
continue;
}
$this->raiseProductEvent('Deny', $product_item['ProductId'], $product_item);
}
- if ( ($original_order_status != ORDER_STATUS_INCOMPLETE) && ($event->Name == 'OnMassOrderDeny' || $event->Name == 'OnOrderDeny') ) {
+ if ( ($original_order_status != ORDER_STATUS_INCOMPLETE ) && ($event->Name == 'OnMassOrderDeny' || $event->Name == 'OnOrderDeny') ) {
$this->Application->emailUser('ORDER.DENY', null, $email_params);
// inform payment gateway that order was declined
$gw_data = $object->getGatewayData();
if ( $gw_data ) {
- $this->Application->registerClass($gw_data['ClassName'], GW_CLASS_PATH . '/' . $gw_data['ClassFile']);
- $gateway_object = $this->Application->recallObject($gw_data['ClassName']);
+ $this->Application->registerClass( $gw_data['ClassName'], GW_CLASS_PATH . '/' . $gw_data['ClassFile'] );
+ $gateway_object = $this->Application->recallObject( $gw_data['ClassName'] );
$gateway_object->OrderDeclined($object->GetFieldValues(), $gw_data['gw_params']);
}
}
// !!! LOOK HERE !!!
// !!!! no break !!!! here on purpose!!!
case 'OnMassOrderArchive':
case 'OnOrderArchive':
// it's critical to update status BEFORE processing items because
// FullfillBackorders could be called during processing and in case
// of order denial/archive fullfill could reserve the qtys back for current backorder
$object->Update();
$this->restoreOrder($order_items);
$set_new_status = false; // already set
break;
case 'OnMassOrderShip':
case 'OnOrderShip':
$ret = Array ();
$shipping_info = $object->GetDBField('ShippingInfo');
if ($shipping_info) {
$quote_engine_collector = $this->Application->recallObject('ShippingQuoteCollector');
/* @var $quote_engine_collector ShippingQuoteCollector */
$shipping_info = unserialize($shipping_info);
$sqe_class_name = $quote_engine_collector->GetClassByType($shipping_info, 1);
}
// try to create usps order
if (($object->GetDBField('ShippingType') == 0) && ($sqe_class_name !== false)) {
$shipping_quote_engine = $this->Application->recallObject($sqe_class_name);
/* @var $shipping_quote_engine ShippingQuoteEngine */
$ret = $shipping_quote_engine->MakeOrder($object);
}
if ( !array_key_exists('error_number', $ret) ) {
$set_new_status = $this->approveOrder($order_items);
-// $set_new_status = $this->shipOrder($order_items);
+ // $set_new_status = $this->shipOrder($order_items);
$object->SetDBField('ShippingDate', adodb_mktime());
$object->UpdateFormattersSubFields();
$shipping_email = $object->GetDBField('ShippingEmail');
$email_params['to_email'] = $shipping_email ? $shipping_email : $email_params['_user_email'];
$this->Application->emailUser('ORDER.SHIP', null, $email_params);
// inform payment gateway that order was shipped
$gw_data = $object->getGatewayData();
- $this->Application->registerClass($gw_data['ClassName'], GW_CLASS_PATH . '/' . $gw_data['ClassFile']);
- $gateway_object = $this->Application->recallObject($gw_data['ClassName']);
+ $this->Application->registerClass( $gw_data['ClassName'], GW_CLASS_PATH.'/'.$gw_data['ClassFile'] );
+ $gateway_object = $this->Application->recallObject( $gw_data['ClassName'] );
$gateway_object->OrderShipped($object->GetFieldValues(), $gw_data['gw_params']);
}
else {
$sqe_errors = $this->Application->RecallVar('sqe_errors');
$sqe_errors = $sqe_errors ? unserialize($sqe_errors) : Array ();
$sqe_errors[ $object->GetField('OrderNumber') ] = $ret['error_description'];
$this->Application->StoreVar('sqe_errors', serialize($sqe_errors));
}
break;
case 'OnMassOrderProcess':
case 'OnOrderProcess':
- if ( $this->ReadyToProcess($object->GetID()) ) {
+ if ($this->ReadyToProcess($object->GetID())) {
$event->CallSubEvent('OnReserveItems');
if ( $event->status == kEvent::erSUCCESS ) {
$set_new_status = true;
}
$this->Application->emailUser('BACKORDER.PROCESS', null, $email_params);
}
else {
$event->status = kEvent::erFAIL;
}
break;
}
- if ( $set_new_status ) {
+ if ($set_new_status) {
$object->Update();
}
}
/**
* Hides last 4 digits from credit card number
*
* @param OrdersItem $object
* @param string $field
*/
function maskCreditCard(&$object, $field)
{
$value = $object->GetDBField($field);
$value = preg_replace('/'.substr($value, -4).'$/', str_repeat('X', 4), $value);
$object->SetDBField($field, $value);
}
/**
* Set next available order number
*
* @param kEvent $event
*/
function setNextOrderNumber($event)
{
$object = $event->getObject();
/* @var $object OrdersItem */
$sql = 'SELECT MAX(Number)
FROM ' . $this->Application->GetLiveName($object->TableName);
$next_order_number = $this->Conn->GetOne($sql) + 1;
$next_order_number = max($next_order_number, $this->Application->ConfigValue('Comm_Next_Order_Number'));
$this->Application->SetConfigValue('Comm_Next_Order_Number', $next_order_number + 1);
$object->SetDBField('Number', $next_order_number);
$object->SetDBField('SubNumber', 0);
// set virtual field too
$number_format = (int)$this->Application->ConfigValue('Comm_Order_Number_Format_P');
$sub_number_format = (int)$this->Application->ConfigValue('Comm_Order_Number_Format_S');
$order_number = sprintf('%0' . $number_format . 'd', $next_order_number) . '-' . str_repeat('0', $sub_number_format);
$object->SetDBField('OrderNumber', $order_number);
}
/**
* Set's new order address based on another address from order (e.g. billing from shipping)
*
* @param unknown_type $object
* @param unknown_type $from
* @param unknown_type $to
*/
function DoResetAddress(&$object, $from, $to)
{
$fields = Array('To','Company','Phone','Fax','Email','Address1','Address2','City','State','Zip','Country');
if ($from == 'User') {
// skip these fields when coping from user, because they are not present in user profile
$tmp_fields = array_flip($fields);
// unset($tmp_fields['Company'], $tmp_fields['Fax'], $tmp_fields['Address2']);
$fields = array_flip($tmp_fields);
}
// apply modification
foreach ($fields as $field_name) {
$object->SetDBField($to.$field_name, $object->GetDBField($from.$field_name));
}
}
/**
* Set's status incomplete to all cloned orders
*
* @param kEvent $event
* @return void
* @access protected
*/
protected function OnAfterClone(kEvent $event)
{
parent::OnAfterClone($event);
$id = $event->getEventParam('id');
- $table = $this->Application->getUnitOption($event->Prefix, 'TableName');
- $id_field = $this->Application->getUnitOption($event->Prefix, 'IDField');
+ $config = $event->getUnitConfig();
// set cloned order status to Incomplete
- $sql = 'UPDATE ' . $table . '
+ $sql = 'UPDATE ' . $config->getTableName() . '
SET Status = 0
- WHERE ' . $id_field . ' = ' . $id;
+ WHERE ' . $config->getIDField() . ' = ' . $id;
$this->Conn->Query($sql);
}
/* ======================== COMMON CODE ======================== */
/**
* Split one timestamp field into 2 virtual fields
*
* @param kEvent $event
* @return void
* @access protected
*/
protected function OnAfterItemLoad(kEvent $event)
{
parent::OnAfterItemLoad($event);
$object = $event->getObject();
/* @var $object kDBItem */
// get user fields
$user_id = $object->GetDBField('PortalUserId');
if ( $user_id ) {
$sql = 'SELECT *, CONCAT(FirstName,\' \',LastName) AS UserTo
FROM ' . TABLE_PREFIX . 'Users
WHERE PortalUserId = ' . $user_id;
$user_info = $this->Conn->GetRow($sql);
$fields = Array(
'UserTo'=>'UserTo','UserPhone'=>'Phone','UserFax'=>'Fax','UserEmail'=>'Email',
'UserAddress1'=>'Street','UserAddress2'=>'Street2','UserCity'=>'City','UserState'=>'State',
'UserZip'=>'Zip','UserCountry'=>'Country','UserCompany'=>'Company'
);
foreach ($fields as $object_field => $user_field) {
$object->SetDBField($object_field, $user_info[$user_field]);
}
}
$object->SetDBField('PaymentCVV2', $this->Application->RecallVar('CVV2Code'));
$cs_helper = $this->Application->recallObject('CountryStatesHelper');
/* @var $cs_helper kCountryStatesHelper */
$cs_helper->PopulateStates($event, 'ShippingState', 'ShippingCountry');
$cs_helper->PopulateStates($event, 'BillingState', 'BillingCountry');
$this->SetStepRequiredFields($event);
// needed in OnAfterItemUpdate
$this->Application->SetVar('OriginalShippingOption', $object->GetDBField('ShippingOption'));
}
/**
* Processes states
*
* @param kEvent $event
* @return void
* @access protected
*/
protected function OnBeforeItemCreate(kEvent $event)
{
parent::OnBeforeItemCreate($event);
$cs_helper = $this->Application->recallObject('CountryStatesHelper');
/* @var $cs_helper kCountryStatesHelper */
$cs_helper->PopulateStates($event, 'ShippingState', 'ShippingCountry');
$cs_helper->PopulateStates($event, 'BillingState', 'BillingCountry');
}
/**
* Processes states
*
* @param kEvent $event
* @return void
* @access protected
*/
protected function OnBeforeItemUpdate(kEvent $event)
{
parent::OnBeforeItemUpdate($event);
$object = $event->getObject();
/* @var $object OrdersItem */
$old_payment_type = $object->GetOriginalField('PaymentType');
$new_payment_type = $object->GetDBField('PaymentType');
if ( $new_payment_type != $old_payment_type ) {
// payment type changed -> check that it's allowed
$available_payment_types = $this->Application->siteDomainField('PaymentTypes');
if ( $available_payment_types ) {
if ( strpos($available_payment_types, '|' . $new_payment_type . '|') === false ) {
// payment type isn't allowed in site domain
$object->SetDBField('PaymentType', $old_payment_type);
}
}
}
$cs_helper = $this->Application->recallObject('CountryStatesHelper');
/* @var $cs_helper kCountryStatesHelper */
$cs_helper->PopulateStates($event, 'ShippingState', 'ShippingCountry');
$cs_helper->PopulateStates($event, 'BillingState', 'BillingCountry');
if ( $object->HasTangibleItems() ) {
$cs_helper->CheckStateField($event, 'ShippingState', 'ShippingCountry', false);
}
$cs_helper->CheckStateField($event, 'BillingState', 'BillingCountry', false);
if ( $object->GetDBField('Status') > ORDER_STATUS_PENDING ) {
return ;
}
$this->CheckUser($event);
if ( !$object->GetDBField('OrderIP') ) {
$object->SetDBField('OrderIP', $this->Application->getClientIp());
}
$shipping_option = $this->Application->GetVar('OriginalShippingOption');
$new_shipping_option = $object->GetDBField('ShippingOption');
if ( $shipping_option != $new_shipping_option ) {
$this->UpdateShippingOption($event);
}
else {
$this->UpdateShippingTypes($event);
}
$this->RecalculateProcessingFee($event);
$this->UpdateShippingTotal($event);
$this->RecalculateGift($event);
// guess fields from "One Step Checkout" form
if ( $object->GetDBField('PaymentAccount') ) {
$order_helper = $this->Application->recallObject('OrderHelper');
/* @var $order_helper OrderHelper */
$object->SetDBField('PaymentCardType', $order_helper->getCreditCartType($object->GetDBField('PaymentAccount')));
}
else {
$object->SetDBField('PaymentCardType', '');
}
if ( !$object->GetDBField('PaymentNameOnCard') ) {
$object->SetDBField('PaymentNameOnCard', $object->GetDBField('BillingTo'));
}
if ( is_object($event->MasterEvent) && $event->MasterEvent->Name == 'OnUpdateAjax' && $this->Application->GetVar('create_account') && $object->Validate() ) {
$this->createAccountFromOrder($event);
}
}
/**
* Creates user account
*
* @param kEvent $event
* @return void
* @access protected
*/
protected function createAccountFromOrder($event)
{
$order = $event->getObject();
/* @var $order OrdersItem */
$order_helper = $this->Application->recallObject('OrderHelper');
/* @var $order_helper OrderHelper */
$user_fields = $order_helper->getUserFields($order);
$user_fields['Password'] = $order->GetDBField('UserPassword_plain');
$user_fields['VerifyPassword'] = $order->GetDBField('VerifyUserPassword_plain');
if ( $order->GetDBField('PortalUserId') == USER_GUEST ) {
// will also auto-login user when created
$this->Application->SetVar('u_register', Array (USER_GUEST => $user_fields));
$this->Application->HandleEvent(new kEvent('u.register:OnCreate'));
}
else {
$user = $this->Application->recallObject('u.current');
/* @var $user UsersItem */
$user->SetFieldsFromHash($user_fields);
if ( !$user->Update() ) {
$order->SetError('BillingEmail', $user->GetErrorPseudo('Email'));
}
}
}
/**
* Apply any custom changes to list's sql query
*
* @param kEvent $event
* @return void
* @access protected
* @see kDBEventHandler::OnListBuild()
*/
protected function SetCustomQuery(kEvent $event)
{
parent::SetCustomQuery($event);
$object = $event->getObject();
/* @var $object kDBList */
$types = $event->getEventParam('types');
if ( $types == 'myorders' || $types == 'myrecentorders' ) {
$user_id = $this->Application->RecallVar('user_id');
$object->addFilter('myitems_user1', '%1$s.PortalUserId = ' . $user_id);
$object->addFilter('myitems_user2', '%1$s.PortalUserId > 0');
$object->addFilter('Status', '%1$s.Status != 0');
}
else if ($event->Special == 'returns') {
// $object->addFilter('returns_filter',TABLE_PREFIX.'Orders.Status = '.ORDER_STATUS_PROCESSED.' AND (
// SELECT SUM(ReturnType)
// FROM '.TABLE_PREFIX.'OrderItems oi
// WHERE oi.OrderId = '.TABLE_PREFIX.'Orders.OrderId
// ) > 0');
$object->addFilter('returns_filter', TABLE_PREFIX . 'Orders.Status = ' . ORDER_STATUS_PROCESSED . ' AND ' . TABLE_PREFIX . 'Orders.ReturnTotal > 0');
}
else if ( $event->Special == 'user' ) {
$user_id = $this->Application->GetVar('u_id');
$object->addFilter('user_filter', '%1$s.PortalUserId = ' . $user_id);
}
else {
$special = $event->Special ? $event->Special : $this->Application->GetVar('order_type');
if ( $special != 'search' ) {
// don't filter out orders by special in case of search tab
$object->addFilter('status_filter', '%1$s.Status=' . $this->getTypeBySpecial($special));
}
if ( $event->getEventParam('selected_only') ) {
$ids = $this->StoreSelectedIDs($event);
$object->addFilter('selected_filter', '%1$s.OrderId IN (' . implode(',', $ids) . ')');
}
}
}
function getTypeBySpecial($special)
{
$special2type = Array('incomplete'=>0,'pending'=>1,'backorders'=>2,'toship'=>3,'processed'=>4,'denied'=>5,'archived'=>6);
return $special2type[$special];
}
function getSpecialByType($type)
{
$type2special = Array(0=>'incomplete',1=>'pending',2=>'backorders',3=>'toship',4=>'processed',5=>'denied',6=>'archived');
return $type2special[$type];
}
function LockTables($event)
{
$read = Array();
$write_lock = '';
$read_lock = '';
$write = Array('Orders','OrderItems','Products');
foreach ($write as $tbl) {
$write_lock .= TABLE_PREFIX.$tbl.' WRITE,';
}
foreach ($read as $tbl) {
$read_lock .= TABLE_PREFIX.$tbl.' READ,';
}
$write_lock = rtrim($write_lock, ',');
$read_lock = rtrim($read_lock, ',');
$lock = trim($read_lock.','.$write_lock, ',');
//$this->Conn->Query('LOCK TABLES '.$lock);
}
/**
* Checks shopping cart products quantities
*
* @param kEvent $event
* @return bool
*/
function CheckQuantites($event)
{
if ( $this->OnRecalculateItems($event) ) { // if something has changed in the order
if ( $this->Application->isAdminUser ) {
if ( $this->UseTempTables($event) ) {
$event->redirect = 'in-commerce/orders/orders_edit_items';
}
}
else {
$event->redirect = $this->Application->GetVar('viewcart_template');
}
return false;
}
return true;
}
function DoPlaceOrder($event)
{
$order = $event->getObject();
$table_prefix = $this->TablePrefix($event);
$this->LockTables($event);
if (!$this->CheckQuantites($event)) return false;
//everything is fine - we could reserve items
$this->ReserveItems($event);
$this->SplitOrder($event, $order);
return true;
}
function &queryOrderItems($event, $table_prefix)
{
$order = $event->getObject();
$ord_id = $order->GetId();
// TABLE_PREFIX and $table_prefix are NOT the same !!!
- $poc_table = $this->Application->getUnitOption('poc', 'TableName');
+ $poc_table = $this->Application->getUnitConfig('poc')->getTableName();
$query = ' SELECT
BackOrderFlag, '.
$table_prefix.'OrderItems.OrderItemId, '.
$table_prefix.'OrderItems.Quantity, '.
$table_prefix.'OrderItems.QuantityReserved,
IF('.TABLE_PREFIX.'Products.InventoryStatus = 2, '.$poc_table.'.QtyInStock, '.TABLE_PREFIX.'Products.QtyInStock) AS QtyInStock, '.
TABLE_PREFIX.'Products.QtyInStockMin, '.
$table_prefix.'OrderItems.ProductId, '.
TABLE_PREFIX.'Products.InventoryStatus,'.
$table_prefix.'OrderItems.OptionsSalt AS CombinationCRC
FROM '.$table_prefix.'OrderItems
LEFT JOIN '.TABLE_PREFIX.'Products ON '.TABLE_PREFIX.'Products.ProductId = '.$table_prefix.'OrderItems.ProductId
LEFT JOIN '.$poc_table.' ON ('.$poc_table.'.CombinationCRC = '.$table_prefix.'OrderItems.OptionsSalt) AND ('.$poc_table.'.ProductId = '.$table_prefix.'OrderItems.ProductId)
WHERE OrderId = '.$ord_id.' AND '.TABLE_PREFIX.'Products.Type = 1
ORDER BY BackOrderFlag ASC';
$items = $this->Conn->Query($query);
return $items;
}
function ReserveItems($event)
{
$table_prefix = $this->TablePrefix($event);
$items =& $this->queryOrderItems($event, $table_prefix);
foreach ($items as $an_item) {
if (!$an_item['InventoryStatus']) {
$to_reserve = $an_item['Quantity'] - $an_item['QuantityReserved'];
}
else {
if ($an_item['BackOrderFlag'] > 0) { // we don't need to reserve if it's backordered item
$to_reserve = 0;
}
else {
$to_reserve = min($an_item['Quantity']-$an_item['QuantityReserved'], $an_item['QtyInStock']-$an_item['QtyInStockMin']); //it should be equal, but just in case
}
$to_backorder = $an_item['BackOrderFlag'] > 0 ? $an_item['Quantity']-$an_item['QuantityReserved'] : 0;
}
if ($to_backorder < 0) $to_backorder = 0; //just in case
$query = ' UPDATE '.$table_prefix.'OrderItems
SET QuantityReserved = IF(QuantityReserved IS NULL, '.$to_reserve.', QuantityReserved + '.$to_reserve.')
WHERE OrderItemId = '.$an_item['OrderItemId'];
$this->Conn->Query($query);
if (!$an_item['InventoryStatus']) continue;
$update_clause = ' QtyInStock = QtyInStock - '.$to_reserve.',
QtyReserved = QtyReserved + '.$to_reserve.',
QtyBackOrdered = QtyBackOrdered + '.$to_backorder;
if ($an_item['InventoryStatus'] == 1) {
// inventory by product, then update it's quantities
$query = ' UPDATE '.TABLE_PREFIX.'Products
SET '.$update_clause.'
WHERE ProductId = '.$an_item['ProductId'];
}
else {
// inventory = 2 -> by product option combinations
- $poc_idfield = $this->Application->getUnitOption('poc', 'IDField');
- $poc_table = $this->Application->getUnitOption('poc', 'TableName');
+ $poc_table = $this->Application->getUnitConfig('poc')->getTableName();
+
$query = ' UPDATE '.$poc_table.'
SET '.$update_clause.'
WHERE (ProductId = '.$an_item['ProductId'].') AND (CombinationCRC = '.$an_item['CombinationCRC'].')';
}
$this->Conn->Query($query);
}
}
function FreeItems($event)
{
$table_prefix = $this->TablePrefix($event);
$items =& $this->queryOrderItems($event, $table_prefix);
foreach ($items as $an_item) {
$to_free = $an_item['QuantityReserved'];
if ($an_item['InventoryStatus']) {
if ($an_item['BackOrderFlag'] > 0) { // we don't need to free if it's backordered item
$to_free = 0;
}
// what's not reserved goes to backorder in stock for orderitems marked with BackOrderFlag
$to_backorder_free = $an_item['BackOrderFlag'] > 0 ? $an_item['Quantity'] - $an_item['QuantityReserved'] : 0;
if ($to_backorder_free < 0) $to_backorder_free = 0; //just in case
$update_clause = ' QtyInStock = QtyInStock + '.$to_free.',
QtyReserved = QtyReserved - '.$to_free.',
QtyBackOrdered = QtyBackOrdered - '.$to_backorder_free;
if ($an_item['InventoryStatus'] == 1) {
// inventory by product
$query = ' UPDATE '.TABLE_PREFIX.'Products
SET '.$update_clause.'
WHERE ProductId = '.$an_item['ProductId'];
}
else {
// inventory by option combinations
- $poc_idfield = $this->Application->getUnitOption('poc', 'IDField');
- $poc_table = $this->Application->getUnitOption('poc', 'TableName');
+ $poc_table = $this->Application->getUnitConfig('poc')->getTableName();
+
$query = ' UPDATE '.$poc_table.'
SET '.$update_clause.'
WHERE (ProductId = '.$an_item['ProductId'].') AND (CombinationCRC = '.$an_item['CombinationCRC'].')';
}
$this->Conn->Query($query);
}
$query = ' UPDATE '.$table_prefix.'OrderItems
SET QuantityReserved = IF(QuantityReserved IS NULL, 0, QuantityReserved - '.$to_free.')
WHERE OrderItemId = '.$an_item['OrderItemId'];
$this->Conn->Query($query);
}
}
/**
* Enter description here...
*
* @param kEvent $event
* @param OrdersItem $object
*/
function SplitOrder($event, &$object)
{
$affiliate_event = new kEvent('affil:OnOrderApprove');
$affiliate_event->setEventParam('Order_PrefixSpecial', $object->getPrefixSpecial() );
$this->Application->HandleEvent($affiliate_event);
$table_prefix = $this->TablePrefix($event);
$order =& $object;
$ord_id = $order->GetId();
$shipping_option = $order->GetDBField('ShippingOption');
$backorder_select = $shipping_option == 0 ? '0' : 'oi.BackOrderFlag';
// setting PackageNum to 0 for Non-tangible items, for tangibles first package num is always 1
$query = ' SELECT oi.OrderItemId
FROM ' . $table_prefix . 'OrderItems oi
LEFT JOIN ' . TABLE_PREFIX . 'Products p ON p.ProductId = oi.ProductId
WHERE p.Type > 1 AND oi.OrderId = ' . $ord_id;
$non_tangibles = $this->Conn->GetCol($query);
if ($non_tangibles) {
$query = ' UPDATE ' . $table_prefix . 'OrderItems
SET PackageNum = 0
WHERE OrderItemId IN (' . implode(',', $non_tangibles) . ')';
$this->Conn->Query($query);
}
// grouping_data:
// 0 => Product Type
// 1 => if NOT tangibale and NOT downloadable - OrderItemId,
// 2 => ProductId
// 3 => Shipping PackageNum
$query = 'SELECT
'.$backorder_select.' AS BackOrderFlagCalc,
PackageNum,
ProductName,
ShippingTypeId,
CONCAT('.TABLE_PREFIX.'Products.Type,
"_",
IF ('.TABLE_PREFIX.'Products.Type NOT IN ('.PRODUCT_TYPE_DOWNLOADABLE.','.PRODUCT_TYPE_TANGIBLE.'),
CONCAT(OrderItemId, "_", '.TABLE_PREFIX.'Products.ProductId),
""),
"_",
PackageNum
) AS Grouping,
SUM(Quantity) AS TotalItems,
SUM('.$table_prefix.'OrderItems.Weight*Quantity) AS TotalWeight,
SUM(Price * Quantity) AS TotalAmount,
SUM(QuantityReserved) AS TotalReserved,
'.TABLE_PREFIX.'Products.Type AS ProductType
FROM '.$table_prefix.'OrderItems
LEFT JOIN '.TABLE_PREFIX.'Products
ON '.TABLE_PREFIX.'Products.ProductId = '.$table_prefix.'OrderItems.ProductId
WHERE OrderId = '.$ord_id.'
GROUP BY BackOrderFlagCalc, Grouping
ORDER BY BackOrderFlagCalc ASC, PackageNum ASC, ProductType ASC';
$sub_orders = $this->Conn->Query($query);
$processed_sub_orders = Array();
// in case of recurring billing this will not be 0 as usual
//$first_sub_number = ($event->Special == 'recurring') ? $object->getNextSubNumber() - 1 : 0;
$first_sub_number = $object->GetDBField('SubNumber');
$next_sub_number = $first_sub_number;
$group = 1;
$order_has_gift = $order->GetDBField('GiftCertificateDiscount') > 0 ? 1 : 0;
$skip_types = Array (PRODUCT_TYPE_TANGIBLE, PRODUCT_TYPE_DOWNLOADABLE);
foreach ($sub_orders as $sub_order_data) {
$sub_order = $this->Application->recallObject('ord.-sub'.$next_sub_number, 'ord');
/* @var $sub_order OrdersItem */
if ($this->UseTempTables($event) && $next_sub_number == 0) {
$sub_order =& $order;
}
$sub_order->SetDBFieldsFromHash($order->GetFieldValues());
$sub_order->SetDBField('SubNumber', $next_sub_number);
$sub_order->SetDBField('SubTotal', $sub_order_data['TotalAmount']);
$grouping_data = explode('_', $sub_order_data['Grouping']);
$named_grouping_data['Type'] = $grouping_data[0];
if (!in_array($named_grouping_data['Type'], $skip_types)) {
$named_grouping_data['OrderItemId'] = $grouping_data[1];
$named_grouping_data['ProductId'] = $grouping_data[2];
$named_grouping_data['PackageNum'] = $grouping_data[3];
}
else {
$named_grouping_data['PackageNum'] = $grouping_data[2];
}
if ($named_grouping_data['Type'] == PRODUCT_TYPE_TANGIBLE) {
$sub_order->SetDBField('ShippingCost', getArrayValue( unserialize($order->GetDBField('ShippingInfo')), $sub_order_data['PackageNum'], 'TotalCost') );
$sub_order->SetDBField('InsuranceFee', getArrayValue( unserialize($order->GetDBField('ShippingInfo')), $sub_order_data['PackageNum'], 'InsuranceFee') );
$sub_order->SetDBField('ShippingInfo', serialize(Array(1 => getArrayValue( unserialize($order->GetDBField('ShippingInfo')), $sub_order_data['PackageNum']))));
}
else {
$sub_order->SetDBField('ShippingCost', 0);
$sub_order->SetDBField('InsuranceFee', 0);
$sub_order->SetDBField('ShippingInfo', ''); //otherwise orders w/o shipping wills still have shipping info!
}
$amount_percent = $sub_order->getTotalAmount() * 100 / $order->getTotalAmount();
// proportional affiliate commission splitting
if ($order->GetDBField('AffiliateCommission') > 0) {
$sub_order->SetDBField('AffiliateCommission', $order->GetDBField('AffiliateCommission') * $amount_percent / 100 );
}
$amount_percent = ($sub_order->GetDBField('SubTotal') + $sub_order->GetDBField('ShippingCost')) * 100 / ($order->GetDBField('SubTotal') + $order->GetDBField('ShippingCost'));
if ($order->GetDBField('ProcessingFee') > 0) {
$sub_order->SetDBField('ProcessingFee', round($order->GetDBField('ProcessingFee') * $amount_percent / 100, 2));
}
$sub_order->RecalculateTax();
$original_amount = $sub_order->GetDBField('SubTotal') + $sub_order->GetDBField('ShippingCost') + $sub_order->GetDBField('VAT') + $sub_order->GetDBField('ProcessingFee') + $sub_order->GetDBField('InsuranceFee') - $sub_order->GetDBField('GiftCertificateDiscount');
$sub_order->SetDBField('OriginalAmount', $original_amount);
if ($named_grouping_data['Type'] == 1 && ($sub_order_data['BackOrderFlagCalc'] > 0
||
($sub_order_data['TotalItems'] != $sub_order_data['TotalReserved'])) ) {
$sub_order->SetDBField('Status', ORDER_STATUS_BACKORDERS);
if ($event->Special != 'recurring') { // just in case if admin uses tangible backordered products in recurring orders
$this->Application->emailUser('BACKORDER.ADD', null, $this->OrderEmailParams($sub_order));
$this->Application->emailAdmin('BACKORDER.ADD');
}
}
else {
switch ($named_grouping_data['Type']) {
case PRODUCT_TYPE_DOWNLOADABLE:
$sql = 'SELECT oi.*
FROM '.TABLE_PREFIX.'OrderItems oi
LEFT JOIN '.TABLE_PREFIX.'Products p ON p.ProductId = oi.ProductId
WHERE (OrderId = %s) AND (p.Type = '.PRODUCT_TYPE_DOWNLOADABLE.')';
$downl_products = $this->Conn->Query( sprintf($sql, $ord_id) );
$product_ids = Array();
foreach ($downl_products as $downl_product) {
$this->raiseProductEvent('Approve', $downl_product['ProductId'], $downl_product, $next_sub_number);
$product_ids[] = $downl_product['ProductId'];
}
break;
case PRODUCT_TYPE_TANGIBLE:
$sql = 'SELECT '.$backorder_select.' AS BackOrderFlagCalc, oi.*
FROM '.TABLE_PREFIX.'OrderItems oi
LEFT JOIN '.TABLE_PREFIX.'Products p ON p.ProductId = oi.ProductId
WHERE (OrderId = %s) AND (BackOrderFlagCalc = 0) AND (p.Type = '.PRODUCT_TYPE_TANGIBLE.')';
$products = $this->Conn->Query( sprintf($sql, $ord_id) );
foreach ($products as $product) {
$this->raiseProductEvent('Approve', $product['ProductId'], $product, $next_sub_number);
}
break;
default:
$order_item_fields = $this->Conn->GetRow('SELECT * FROM '.TABLE_PREFIX.'OrderItems WHERE OrderItemId = '.$named_grouping_data['OrderItemId']);
$this->raiseProductEvent('Approve', $named_grouping_data['ProductId'], $order_item_fields, $next_sub_number);
break;
}
$sub_order->SetDBField('Status', $named_grouping_data['Type'] == PRODUCT_TYPE_TANGIBLE ? ORDER_STATUS_TOSHIP : ORDER_STATUS_PROCESSED);
}
if ($next_sub_number == $first_sub_number) {
$sub_order->SetId($order->GetId());
$sub_order->Update();
}
else {
$sub_order->Create();
}
switch ($named_grouping_data['Type']) {
case PRODUCT_TYPE_TANGIBLE:
$query = 'UPDATE '.$table_prefix.'OrderItems SET OrderId = %s WHERE OrderId = %s AND PackageNum = %s';
$query = sprintf($query, $sub_order->GetId(), $ord_id, $sub_order_data['PackageNum']);
break;
case PRODUCT_TYPE_DOWNLOADABLE:
$query = 'UPDATE '.$table_prefix.'OrderItems SET OrderId = %s WHERE OrderId = %s AND ProductId IN (%s)';
$query = sprintf($query, $sub_order->GetId(), $ord_id, implode(',', $product_ids) );
break;
default:
$query = 'UPDATE '.$table_prefix.'OrderItems SET OrderId = %s WHERE OrderId = %s AND OrderItemId = %s';
$query = sprintf($query, $sub_order->GetId(), $ord_id, $named_grouping_data['OrderItemId']);
break;
}
$this->Conn->Query($query);
if ($order_has_gift) {
// gift certificate can be applied only after items are assigned to suborder
$sub_order->RecalculateGift($event);
$original_amount = $sub_order->GetDBField('SubTotal') + $sub_order->GetDBField('ShippingCost') + $sub_order->GetDBField('VAT') + $sub_order->GetDBField('ProcessingFee') + $sub_order->GetDBField('InsuranceFee') - $sub_order->GetDBField('GiftCertificateDiscount');
$sub_order->SetDBField('OriginalAmount', $original_amount);
$sub_order->Update();
}
$processed_sub_orders[] = $sub_order->GetID();
$next_sub_number++;
$group++;
}
foreach ($processed_sub_orders as $sub_id) {
// update DiscountTotal field
$sql = 'SELECT SUM(ROUND(FlatPrice-Price,2)*Quantity) FROM '.$table_prefix.'OrderItems WHERE OrderId = '.$sub_id;
$discount_total = $this->Conn->GetOne($sql);
$sql = 'UPDATE '.$sub_order->TableName.'
SET DiscountTotal = '.$this->Conn->qstr($discount_total).'
WHERE OrderId = '.$sub_id;
$this->Conn->Query($sql);
}
}
/**
* Call products linked event when spefcfic action is made to product in order
*
* @param string $event_type type of event to get from product ProcessingData = {Approve,Deny,CompleteOrder}
* @param int $product_id ID of product to gather processing data from
* @param Array $order_item_fields OrderItems table record fields (with needed product & order in it)
*/
function raiseProductEvent($event_type, $product_id, $order_item_fields, $next_sub_number=null)
{
$sql = 'SELECT ProcessingData
FROM '.TABLE_PREFIX.'Products
WHERE ProductId = '.$product_id;
$processing_data = $this->Conn->GetOne($sql);
if ($processing_data) {
$processing_data = unserialize($processing_data);
$event_key = getArrayValue($processing_data, $event_type.'Event');
// if requested type of event is defined for product, only then process it
if ($event_key) {
$event = new kEvent($event_key);
$event->setEventParam('field_values', $order_item_fields);
$event->setEventParam('next_sub_number', $next_sub_number);
$this->Application->HandleEvent($event);
}
}
}
function OptionsSalt($options, $comb_only=false)
{
$helper = $this->Application->recallObject('kProductOptionsHelper');
return $helper->OptionsSalt($options, $comb_only);
}
/**
* Enter description here...
*
* @param kEvent $event
* @param int $item_id
*/
function AddItemToOrder($event, $item_id, $qty = null, $package_num = null)
{
if (!isset($qty)) {
$qty = 1;
}
// Loading product to add
$product = $this->Application->recallObject('p.toadd', null, Array('skip_autoload' => true));
/* @var $product kDBItem */
$product->Load($item_id);
$object = $this->Application->recallObject('orditems.-item', null, Array('skip_autoload' => true));
/* @var $object kDBItem */
$order = $this->Application->recallObject('ord');
/* @var $order kDBItem */
if (!$order->isLoaded() && !$this->Application->isAdmin) {
// no order was created before -> create one now
if ($this->_createNewCart($event)) {
$this->LoadItem($event);
}
}
if (!$order->isLoaded()) {
// was unable to create new order
return false;
}
$item_data = $event->getEventParam('ItemData');
$item_data = $item_data ? unserialize($item_data) : Array ();
$options = getArrayValue($item_data, 'Options');
if ( !$this->CheckOptions($event, $options, $item_id, $qty, $product->GetDBField('OptionsSelectionMode')) ) {
return;
}
$manager = $this->Application->recallObject('OrderManager');
/* @var $manager OrderManager */
$manager->setOrder($order);
$manager->addProduct($product, $event->getEventParam('ItemData'), $qty, $package_num);
$this->Application->HandleEvent(new kEvent('ord:OnRecalculateItems'));
}
/**
* Enter description here...
*
* @param kEvent $event
*/
function UpdateShippingTotal($event)
{
if ( $this->Application->GetVar('ebay_notification') == 1 ) {
// TODO: get rid of this "if"
return;
}
$object = $event->getObject();
/* @var $object OrdersItem */
$shipping_total = $insurance_fee = 0;
$shipping_info = $object->GetDBField('ShippingInfo') ? unserialize($object->GetDBField('ShippingInfo')) : false;
if ( is_array($shipping_info) ) {
foreach ($shipping_info as $a_shipping) {
// $id_elements = explode('_', $a_shipping['ShippingTypeId']);
$shipping_total += $a_shipping['TotalCost'];
$insurance_fee += $a_shipping['InsuranceFee'];
}
}
$object->SetDBField('ShippingCost', $shipping_total);
$object->SetDBField('InsuranceFee', $insurance_fee);
// no need to update, it will be called in calling method
$this->RecalculateTax($event);
}
/**
* Recompile shopping cart, splitting or grouping orders and backorders depending on total quantities.
* First it counts total qty for each ProductId, and then creates order for available items
* and backorder for others. It also updates the sub-total for the order
*
* @param kEvent $event
* @return bool Returns true if items splitting/grouping were changed
*/
function OnRecalculateItems($event)
{
if (is_object($event->MasterEvent) && ($event->MasterEvent->status != kEvent::erSUCCESS)) {
// e.g. master order update failed, don't recalculate order products
return ;
}
$order = $event->getObject();
/* @var $order OrdersItem */
if ( !$order->isLoaded() ) {
$this->LoadItem($event); // try to load
}
$ord_id = (int)$order->GetID();
if ( !$order->isLoaded() ) return; //order has not been created yet
if( $order->GetDBField('Status') != ORDER_STATUS_INCOMPLETE )
{
return;
}
$manager = $this->Application->recallObject('OrderManager');
/* @var $manager OrderManager */
$manager->setOrder($order);
$result = $manager->calculate();
if ( $order->GetDBField('CouponId') && $order->GetDBField('CouponDiscount') == 0 ) {
$this->RemoveCoupon($order);
$order->setCheckoutError(OrderCheckoutErrorType::COUPON, OrderCheckoutError::COUPON_REMOVED_AUTOMATICALLY);
}
if ( $result ) {
$this->UpdateShippingOption($event);
}
$this->UpdateShippingTotal($event);
$this->RecalculateProcessingFee($event);
$this->RecalculateTax($event);
$this->RecalculateGift($event);
if ( $event->Name != 'OnAfterItemUpdate' ) {
$order->Update();
}
$event->setEventParam('RecalculateChangedCart', $result);
if ( is_object($event->MasterEvent) ) {
$event->MasterEvent->setEventParam('RecalculateChangedCart', $result);
}
/*if ( $result && !getArrayValue($event->redirect_params, 'checkout_error') ) {
$event->SetRedirectParam('checkout_error', OrderCheckoutError::STATE_CHANGED);
}*/
if ( $result && is_object($event->MasterEvent) && $event->MasterEvent->Name == 'OnUserLogin' ) {
$shop_cart_template = $this->Application->GetVar('shop_cart_template');
if ( $shop_cart_template && is_object($event->MasterEvent->MasterEvent) ) {
// $event->MasterEvent->MasterEvent->SetRedirectParam('checkout_error', OrderCheckoutError::CHANGED_AFTER_LOGIN);
$event->MasterEvent->MasterEvent->redirect = $shop_cart_template;
}
}
return $result;
}
/* function GetShippingCost($user_country_id, $user_state_id, $user_zip, $weight, $items, $amount, $shipping_type)
{
$this->Application->recallObject('ShippingQuoteEngine');
$shipping_h = $this->Application->recallObject('CustomShippingQuoteEngine');
$query = $shipping_h->QueryShippingCost($user_country_id, $user_state_id, $user_zip, $weight, $items, $amount, $shipping_type);
$cost = $this->Conn->GetRow($query);
return $cost['TotalCost'];
}*/
/**
* Return product pricing id for given product, if not passed - return primary pricing ID
*
* @param int $product_id ProductId
* @return float
*/
function GetPricingId($product_id, $item_data) {
if (!is_array($item_data)) {
$item_data = unserialize($item_data);
}
$price_id = getArrayValue($item_data, 'PricingId');
if (!$price_id) {
$price_id = $this->Application->GetVar('pr_id');
}
if (!$price_id){
$price_id = $this->Conn->GetOne('SELECT PriceId FROM '.TABLE_PREFIX.'ProductsPricing WHERE ProductId='.$product_id.' AND IsPrimary=1');
}
return $price_id;
}
function UpdateShippingOption($event)
{
$object = $event->getObject();
$shipping_option = $object->GetDBField('ShippingOption');
if($shipping_option == '') return;
$table_prefix = $this->TablePrefix($event);
if ($shipping_option == 1 || $shipping_option == 0) { // backorder separately
$query = 'UPDATE '.$table_prefix.'OrderItems SET BackOrderFlag = 1 WHERE OrderId = '.$object->GetId().' AND BackOrderFlag > 1';
$this->Conn->Query($query);
}
if ($shipping_option == 2) {
$query = 'SELECT * FROM '.$table_prefix.'OrderItems WHERE OrderId = '.$object->GetId().' AND BackOrderFlag >= 1 ORDER By ProductName asc';
$items = $this->Conn->Query($query);
$backorder_flag = 2;
foreach ($items as $an_item) {
$query = 'UPDATE '.$table_prefix.'OrderItems SET BackOrderFlag = '.$backorder_flag.' WHERE OrderItemId = '.$an_item['OrderItemId'];
$this->Conn->Query($query);
$backorder_flag++;
}
}
}
/**
* Updates shipping types
*
* @param kEvent $event
* @return bool
*/
function UpdateShippingTypes($event)
{
$object = $event->getObject();
/* @var $object OrdersItem */
$ord_id = $object->GetID();
$order_info = $this->Application->GetVar('ord');
$shipping_ids = getArrayValue($order_info, $ord_id, 'ShippingTypeId');
if (!$shipping_ids) {
return;
}
$ret = true;
$shipping_types = Array();
$last_shippings = unserialize( $this->Application->RecallVar('LastShippings') );
$template = $this->Application->GetVar('t');
$shipping_templates = Array ('in-commerce/checkout/shipping', 'in-commerce/orders/orders_edit_shipping');
$quote_engine_collector = $this->Application->recallObject('ShippingQuoteCollector');
/* @var $quote_engine_collector ShippingQuoteCollector */
foreach ($shipping_ids as $package => $id) {
// try to validate
$shipping_types[$package] = $last_shippings[$package][$id];
$sqe_class_name = $quote_engine_collector->GetClassByType($shipping_types, $package);
if (($object->GetDBField('ShippingType') == 0) && ($sqe_class_name !== false) && in_array($template, $shipping_templates)) {
$shipping_quote_engine = $this->Application->recallObject($sqe_class_name);
/* @var $shipping_quote_engine ShippingQuoteEngine */
// USPS related part
// TODO: remove USPS condition from here
// set first of found shippings just to check if any errors are returned
$current_usps_shipping_types = unserialize($this->Application->RecallVar('current_usps_shipping_types'));
$object->SetDBField('ShippingInfo', serialize( Array($package => $current_usps_shipping_types[$id])) );
$sqe_data = $shipping_quote_engine->MakeOrder($object, true);
if ( $sqe_data ) {
if ( !isset($sqe_data['error_number']) ) {
// update only international shipping
if ( $object->GetDBField('ShippingCountry') != 'USA') {
$shipping_types[$package]['TotalCost'] = $sqe_data['Postage'];
}
}
else {
$ret = false;
$this->Application->StoreVar('sqe_error', $sqe_data['error_description']);
}
}
$object->SetDBField('ShippingInfo', '');
}
}
$object->SetDBField('ShippingInfo', serialize($shipping_types));
return $ret;
}
/*function shipOrder(&$order_items)
{
$product_object = $this->Application->recallObject('p', null, Array('skip_autoload' => true));
$order_item = $this->Application->recallObject('orditems.-item');
while( !$order_items->EOL() )
{
$rec = $order_items->getCurrentRecord();
$order_item->SetDBFieldsFromHash($rec);
$order_item->SetId($rec['OrderItemId']);
$order_item->SetDBField('QuantityReserved', 0);
$order_item->Update();
$order_items->GoNext();
}
return true;
}*/
function RecalculateTax($event)
{
$object = $event->getObject();
/* @var $object OrdersItem */
if ($object->GetDBField('Status') > ORDER_STATUS_PENDING) {
return;
}
$object->RecalculateTax();
}
function RecalculateProcessingFee($event)
{
$object = $event->getObject();
// Do not reset processing fee while orders are being split (see SplitOrder)
if (preg_match("/^-sub/", $object->Special)) return;
if ($object->GetDBField('Status') > ORDER_STATUS_PENDING) return; //no changes for orders other than incomple or pending
$pt = $object->GetDBField('PaymentType');
- $processing_fee = $this->Conn->GetOne('SELECT ProcessingFee FROM '.$this->Application->getUnitOption('pt', 'TableName').' WHERE PaymentTypeId = '.$pt);
+
+ $sql = 'SELECT ProcessingFee
+ FROM ' . $this->Application->getUnitConfig('pt')->getTableName() . '
+ WHERE PaymentTypeId = ' . $pt;
+ $processing_fee = $this->Conn->GetOne($sql);
+
$object->SetDBField( 'ProcessingFee', $processing_fee );
$this->UpdateTotals($event);
}
function UpdateTotals($event)
{
$object = $event->getObject();
/* @var $object OrdersItem */
$object->UpdateTotals();
}
/*function CalculateDiscount($event)
{
$object = $event->getObject();
$coupon = $this->Application->recallObject('coup', null, Array('skip_autoload' => true));
if(!$coupon->Load( $object->GetDBField('CouponId'), 'CouponId' ))
{
return false;
}
- $sql = 'SELECT Price * Quantity AS Amount, ProductId FROM '.$this->Application->getUnitOption('orditems', 'TableName').'
+ $sql = 'SELECT Price * Quantity AS Amount, ProductId FROM '.$this->Application->getUnitConfig('orditems')->getTableName().'
WHERE OrderId = '.$object->GetDBField('OrderId');
$orditems = $this->Conn->GetCol($sql, 'ProductId');
- $sql = 'SELECT coupi.ItemType, p.ProductId FROM '.$this->Application->getUnitOption('coupi', 'TableName').' coupi
- LEFT JOIN '.$this->Application->getUnitOption('p', 'TableName').' p
+ $sql = 'SELECT coupi.ItemType, p.ProductId FROM '.$this->Application->getUnitConfig('coupi')->getTableName().' coupi
+ LEFT JOIN '.$this->Application->getUnitConfig('p')->getTableName().' p
ON coupi.ItemResourceId = p.ResourceId
WHERE CouponId = '.$object->GetDBField('CouponId');
$discounts = $this->Conn->GetCol($sql, 'ProductId');
$discount_amount = 0;
foreach($orditems as $product_id => $amount)
{
if(isset($discounts[$product_id]) || array_search('0', $discounts, true) !== false)
{
switch($coupon->GetDBField('Type'))
{
case 1:
$discount_amount += $coupon->GetDBField('Amount') < $amount ? $coupon->GetDBField('Amount') : $amount;
break;
case 2:
$discount_amount += $amount * $coupon->GetDBField('Amount') / 100;
break;
default:
}
break;
}
}
$object->SetDBField('CouponDiscount', $discount_amount);
return $discount_amount;
}*/
/**
* Jumps to selected order in order's list from search tab
*
* @param kEvent $event
*/
function OnGoToOrder($event)
{
$id = current($this->StoreSelectedIDs($event));
- $id_field = $this->Application->getUnitOption($event->Prefix,'IDField');
- $table = $this->Application->getUnitOption($event->Prefix,'TableName');
+ $config = $event->getUnitConfig();
+ $id_field = $config->getIDField();
- $sql = 'SELECT Status FROM %s WHERE %s = %s';
-
- $order_status = $this->Conn->GetOne( sprintf($sql, $table, $id_field, $id) );
+ $sql = 'SELECT Status
+ FROM ' . $config->getTableName() . '
+ WHERE ' . $id_field . ' = ' . $id;
+ $order_status = $this->Conn->GetOne($sql);
$prefix_special = $event->Prefix.'.'.$this->getSpecialByType($order_status);
$orders_list = $this->Application->recallObject($prefix_special, $event->Prefix.'_List', Array('per_page'=>-1) );
/* @var $orders_list kDBList */
$orders_list->Query();
foreach ($orders_list->Records as $row_num => $record) {
if ( $record[$id_field] == $id ) {
break;
}
}
$per_page = $this->getPerPage( new kEvent($prefix_special.':OnDummy') );
$page = ceil( ($row_num+1) / $per_page );
$this->Application->StoreVar($prefix_special.'_Page', $page);
$event->redirect = 'in-commerce/orders/orders_'.$this->getSpecialByType($order_status).'_list';
}
/**
* Reset's any selected order state to pending
*
* @param kEvent $event
*/
function OnResetToPending($event)
{
$object = $event->getObject( Array('skip_autoload' => true) );
/* @var $object kDBItem */
$items_info = $this->Application->GetVar($event->getPrefixSpecial(true));
if ( $items_info ) {
foreach ($items_info as $id => $field_values) {
$object->Load($id);
$object->SetDBField('Status', ORDER_STATUS_PENDING);
if ( $object->Update() ) {
$event->status = kEvent::erSUCCESS;
}
else {
$event->status = kEvent::erFAIL;
$event->redirect = false;
break;
}
}
}
}
/**
* Creates list from items selected in grid
*
* @param kEvent $event
*/
function OnLoadSelected($event)
{
$event->setPseudoClass('_List');
$object = $event->getObject( Array('selected_only' => true) );
$event->redirect = false;
}
/**
* Return orders list, that will expire in time specified
*
* @param int $pre_expiration timestamp
* @return Array
*/
function getRecurringOrders($pre_expiration)
{
- $ord_table = $this->Application->getUnitOption('ord', 'TableName');
- $ord_idfield = $this->Application->getUnitOption('ord', 'IDField');
+ $config = $this->Application->getUnitConfig('ord');
+ $ord_id_field = $config->getIDField();
$processing_allowed = Array(ORDER_STATUS_PROCESSED, ORDER_STATUS_ARCHIVED);
- $sql = 'SELECT '.$ord_idfield.', PortalUserId, GroupId, NextCharge
- FROM '.$ord_table.'
+ $sql = 'SELECT '.$ord_id_field.', PortalUserId, GroupId, NextCharge
+ FROM '. $config->getTableName() .'
WHERE (IsRecurringBilling = 1) AND (NextCharge < '.$pre_expiration.') AND Status IN ('.implode(',', $processing_allowed).')';
- return $this->Conn->Query($sql, $ord_idfield);
+ return $this->Conn->Query($sql, $ord_id_field);
}
/**
* [SCHEDULED TASK] Checks what orders should expire and renew automatically (if such flag set)
*
* @param kEvent $event
*/
function OnCheckRecurringOrders($event)
{
$skip_clause = Array();
- $ord_table = $this->Application->getUnitOption($event->Prefix, 'TableName');
- $ord_idfield = $this->Application->getUnitOption($event->Prefix, 'IDField');
-
$pre_expiration = adodb_mktime() + $this->Application->ConfigValue('Comm_RecurringChargeInverval') * 3600 * 24;
$to_charge = $this->getRecurringOrders($pre_expiration);
+
if ($to_charge) {
$order_ids = Array();
foreach ($to_charge as $order_id => $record) {
// skip virtual users (e.g. root, guest, etc.) & invalid subscriptions (with no group specified, no next charge, but Recurring flag set)
if (!$record['PortalUserId'] || !$record['GroupId'] || !$record['NextCharge']) continue;
$order_ids[] = $order_id;
// prevent duplicate user+group pairs
$skip_clause[ 'PortalUserId = '.$record['PortalUserId'].' AND GroupId = '.$record['GroupId'] ] = $order_id;
}
// process only valid orders
$temp_handler = $this->Application->recallObject($event->Prefix.'_TempHandler', 'kTempTablesHandler');
$cloned_order_ids = $temp_handler->CloneItems($event->Prefix, 'recurring', $order_ids);
$order =& $this->Application->recallObject($event->Prefix.'.recurring', null, Array('skip_autoload' => true));
foreach ($cloned_order_ids as $order_id) {
$order->Load($order_id);
$this->Application->HandleEvent($complete_event, $event->Prefix.'.recurring:OnCompleteOrder' );
if ($complete_event->status == kEvent::erSUCCESS) {
//send recurring ok email
$this->Application->emailUser('ORDER.RECURRING.PROCESSED', null, $this->OrderEmailParams($order));
$this->Application->emailAdmin('ORDER.RECURRING.PROCESSED');
}
else {
//send Recurring failed event
$order->SetDBField('Status', ORDER_STATUS_DENIED);
$order->Update();
$this->Application->emailUser('ORDER.RECURRING.DENIED', null, $this->OrderEmailParams($order));
$this->Application->emailAdmin('ORDER.RECURRING.DENIED');
}
}
// remove recurring flag from all orders found, not to select them next time script runs
- $sql = 'UPDATE '.$ord_table.'
+ $config = $event->getUnitConfig();
+
+ $sql = 'UPDATE '. $config->getTableName() .'
SET IsRecurringBilling = 0
- WHERE '.$ord_idfield.' IN ('.implode(',', array_keys($to_charge)).')';
+ WHERE '. $config->getIDField() .' IN ('.implode(',', array_keys($to_charge)).')';
$this->Conn->Query($sql);
}
if ( !is_object($event->MasterEvent) ) {
// not called as hook
return ;
}
$pre_expiration = adodb_mktime() + $this->Application->ConfigValue('User_MembershipExpirationReminder') * 3600 * 24;
$to_charge = $this->getRecurringOrders($pre_expiration);
foreach ($to_charge as $order_id => $record) {
// skip virtual users (e.g. root, guest, etc.) & invalid subscriptions (with no group specified, no next charge, but Recurring flag set)
if (!$record['PortalUserId'] || !$record['GroupId'] || !$record['NextCharge']) continue;
// prevent duplicate user+group pairs
$skip_clause[ 'PortalUserId = '.$record['PortalUserId'].' AND GroupId = '.$record['GroupId'] ] = $order_id;
}
$skip_clause = array_flip($skip_clause);
$event->MasterEvent->setEventParam('skip_clause', $skip_clause);
}
function OnGeneratePDF($event)
{
$this->OnLoadSelected($event);
$this->Application->InitParser();
$o = $this->Application->ParseBlock(array('name'=>'in-commerce/orders/orders_pdf'));
$file_helper = $this->Application->recallObject('FileHelper');
/* @var $file_helper FileHelper */
$file_helper->CheckFolder(EXPORT_PATH);
$htmlFile = EXPORT_PATH . '/tmp.html';
$fh = fopen($htmlFile, 'w');
fwrite($fh, $o);
fclose($fh);
// return;
// require_once (FULL_PATH.'html2pdf/PDFEncryptor.php');
// Full path to the file to be converted
// $htmlFile = dirname(__FILE__) . '/test.html';
// The default domain for images that use a relative path
// (you'll need to change the paths in the test.html page
// to an image on your server)
$defaultDomain = DOMAIN;
// Full path to the PDF we are creating
$pdfFile = EXPORT_PATH . '/tmp.pdf';
// Remove old one, just to make sure we are making it afresh
@unlink($pdfFile);
$pdf_helper = $this->Application->recallObject('kPDFHelper');
$pdf_helper->FileToFile($htmlFile, $pdfFile);
return ;
// DOM PDF VERSION
/*require_once(FULL_PATH.'/dompdf/dompdf_config.inc.php');
$dompdf = new DOMPDF();
$dompdf->load_html_file($htmlFile);
if ( isset($base_path) ) {
$dompdf->set_base_path($base_path);
}
$dompdf->set_paper($paper, $orientation);
$dompdf->render();
file_put_contents($pdfFile, $dompdf->output());
return ;*/
// Instnatiate the class with our variables
require_once (FULL_PATH.'/html2pdf/HTML_ToPDF.php');
$pdf = new HTML_ToPDF($htmlFile, $defaultDomain, $pdfFile);
$pdf->setHtml2Ps('/usr/bin/html2ps');
$pdf->setPs2Pdf('/usr/bin/ps2pdf');
$pdf->setGetUrl('/usr/local/bin/curl -i');
// Set headers/footers
$pdf->setHeader('color', 'black');
$pdf->setFooter('left', '');
$pdf->setFooter('right', '$D');
$pdf->setDefaultPath(BASE_PATH.'/kernel/admin_templates/');
$result = $pdf->convert();
// Check if the result was an error
if (PEAR::isError($result)) {
$this->Application->ApplicationDie($result->getMessage());
}
else {
$download_url = rtrim($this->Application->BaseURL(), '/') . EXPORT_BASE_PATH . '/tmp.pdf';
echo "PDF file created successfully: $result";
echo '<br />Click <a href="' . $download_url . '">here</a> to view the PDF file.';
}
}
/**
* Occurs, when config was parsed, allows to change config data dynamically
*
* @param kEvent $event
* @return void
* @access protected
*/
protected function OnAfterConfigRead(kEvent $event)
{
parent::OnAfterConfigRead($event);
if (defined('IS_INSTALL') && IS_INSTALL) {
return ;
}
$order_number = (int)$this->Application->ConfigValue('Comm_Order_Number_Format_P');
$order_sub_number = (int)$this->Application->ConfigValue('Comm_Order_Number_Format_S');
- $calc_fields = $this->Application->getUnitOption($event->Prefix, 'CalculatedFields');
+ $config = $event->getUnitConfig();
+ $calc_fields = $config->getSetting('CalculatedFields');
+
foreach ($calc_fields as $special => $fields) {
$calc_fields[$special]['OrderNumber'] = str_replace('6', $order_number, $calc_fields[$special]['OrderNumber']);
$calc_fields[$special]['OrderNumber'] = str_replace('3', $order_sub_number, $calc_fields[$special]['OrderNumber']);
}
- $this->Application->setUnitOption($event->Prefix, 'CalculatedFields', $calc_fields);
+ $config->setSetting('CalculatedFields', $calc_fields);
- $fields = $this->Application->getUnitOption($event->Prefix, 'Fields');
+ $fields = $config->getFields();
$fields['Number']['format'] = str_replace('%06d', '%0'.$order_number.'d', $fields['Number']['format']);
$fields['SubNumber']['format'] = str_replace('%03d', '%0'.$order_sub_number.'d', $fields['SubNumber']['format']);
$site_helper = $this->Application->recallObject('SiteHelper');
/* @var $site_helper SiteHelper */
$fields['BillingCountry']['default'] = $site_helper->getDefaultCountry('Billing');
$fields['ShippingCountry']['default'] = $site_helper->getDefaultCountry('Shipping');
if (!$this->Application->isAdminUser) {
$user_groups = explode(',', $this->Application->RecallVar('UserGroups'));
$default_group = $this->Application->ConfigValue('User_LoggedInGroup');
if (!in_array($default_group, $user_groups)){
$user_groups[] = $default_group;
}
$sql_part = '';
// limit payment types by domain
$payment_types = $this->Application->siteDomainField('PaymentTypes');
if (strlen($payment_types)) {
$payment_types = explode('|', substr($payment_types, 1, -1));
$sql_part .= ' AND PaymentTypeId IN (' . implode(',', $payment_types) . ')';
}
// limit payment types by user group
$sql_part .= ' AND (PortalGroups LIKE "%%,'.implode(',%%" OR PortalGroups LIKE "%%,', $user_groups).',%%")';
$fields['PaymentType']['options_sql'] = str_replace(
'ORDER BY ',
$sql_part . ' ORDER BY ',
$fields['PaymentType']['options_sql']
);
}
- $this->Application->setUnitOption($event->Prefix, 'Fields', $fields);
+ $config->setFields($fields);
- $user_forms = $this->Application->getUnitOption('u', 'Forms');
+ $user_default_form = $this->Application->getUnitConfig('u')->getFieldByName('default');
- $virtual_fields = $this->Application->getUnitOption($event->Prefix, 'VirtualFields');
- $virtual_fields['UserPassword']['hashing_method'] = $user_forms['default']['Fields']['PasswordHashingMethod']['default'];
- $this->Application->setUnitOption($event->Prefix, 'VirtualFields', $virtual_fields);
+ $virtual_fields = $config->getVirtualFields();
+ $virtual_fields['UserPassword']['hashing_method'] = $user_default_form['Fields']['PasswordHashingMethod']['default'];
+ $config->setVirtualFields($virtual_fields);
}
/**
* Allows configuring export options
*
* @param kEvent $event
* @return void
* @access protected
*/
protected function OnBeforeExportBegin(kEvent $event)
{
parent::OnBeforeExportBegin($event);
$options = $event->getEventParam('options');
$items_list = $this->Application->recallObject($event->Prefix . '.' . $this->Application->RecallVar('export_oroginal_special'), $event->Prefix . '_List');
/* @var $items_list kDBList */
$items_list->SetPerPage(-1);
if ( $options['export_ids'] != '' ) {
$items_list->AddFilter('export_ids', $items_list->TableName . '.' . $items_list->IDField . ' IN (' . implode(',', $options['export_ids']) . ')');
}
$options['ForceCountSQL'] = $items_list->getCountSQL($items_list->GetSelectSQL(true, false));
$options['ForceSelectSQL'] = $items_list->GetSelectSQL();
$event->setEventParam('options', $options);
$object = $this->Application->recallObject($event->Prefix . '.export');
/* @var $object kDBItem */
$object->SetField('Number', 999999);
$object->SetField('SubNumber', 999);
}
/**
* Returns specific to each item type columns only
*
* @param kEvent $event
* @return Array
* @access protected
*/
public function getCustomExportColumns(kEvent $event)
{
$columns = parent::getCustomExportColumns($event);
$new_columns = Array (
'__VIRTUAL__CustomerName' => 'CustomerName',
'__VIRTUAL__TotalAmount' => 'TotalAmount',
'__VIRTUAL__AmountWithoutVAT' => 'AmountWithoutVAT',
'__VIRTUAL__SubtotalWithDiscount' => 'SubtotalWithDiscount',
'__VIRTUAL__SubtotalWithoutDiscount' => 'SubtotalWithoutDiscount',
'__VIRTUAL__OrderNumber' => 'OrderNumber',
);
return array_merge($columns, $new_columns);
}
/**
* Saves content of temp table into live and
* redirects to event' default redirect (normally grid template)
*
* @param kEvent $event
* @return void
* @access protected
*/
protected function OnSave(kEvent $event)
{
parent::OnSave($event);
if ( $event->status != kEvent::erSUCCESS ) {
return ;
}
$copied_ids = unserialize($this->Application->RecallVar($event->Prefix . '_copied_ids' . $this->Application->GetVar('wid'), serialize(Array ())));
foreach ($copied_ids as $id) {
$an_event = new kEvent($this->Prefix . ':Dummy');
$this->Application->SetVar($this->Prefix . '_id', $id);
$this->Application->SetVar($this->Prefix . '_mode', ''); // this is to fool ReserveItems to use live table
$this->ReserveItems($an_event);
}
}
/**
* Occurs before an item is copied to live table (after all foreign keys have been updated)
* Id of item being copied is passed as event' 'id' param
*
* @param kEvent $event
* @return void
* @access protected
*/
protected function OnBeforeCopyToLive(kEvent $event)
{
parent::OnBeforeCopyToLive($event);
$id = $event->getEventParam('id');
$copied_ids = unserialize($this->Application->RecallVar($event->Prefix . '_copied_ids' . $this->Application->GetVar('wid'), serialize(array ())));
array_push($copied_ids, $id);
$this->Application->StoreVar($event->Prefix . '_copied_ids' . $this->Application->GetVar('wid'), serialize($copied_ids));
}
/**
* Checks, that currently loaded item is allowed for viewing (non permission-based)
*
* @param kEvent $event
* @return bool
* @access protected
*/
protected function checkItemStatus(kEvent $event)
{
if ( $this->Application->isAdminUser ) {
return true;
}
$object = $event->getObject();
/* @var $object kDBItem */
if ( !$object->isLoaded() ) {
return true;
}
return $object->GetDBField('PortalUserId') == $this->Application->RecallVar('user_id');
}
// ===== Gift Certificates Related =====
/**
* Enter description here...
*
* @param kEvent $event
*/
function OnApplyGiftCertificate($event)
{
$code = $this->Application->GetVar('giftcert_code');
if ( $code == '' ) {
return;
}
$object = $event->getObject();
/* @var $object OrdersItem */
$gift_certificate = $this->Application->recallObject('gc', null, Array ('skip_autoload' => true));
/* @var $gift_certificate kDBItem */
$gift_certificate->Load($code, 'Code');
if ( !$gift_certificate->isLoaded() ) {
$event->status = kEvent::erFAIL;
$object->setCheckoutError(OrderCheckoutErrorType::GIFT_CERTIFICATE, OrderCheckoutError::GC_CODE_INVALID);
$event->redirect = false; // check!!!
return;
}
$debit = $gift_certificate->GetDBField('Debit');
$expire_date = $gift_certificate->GetDBField('Expiration');
if ( $gift_certificate->GetDBField('Status') != 1 || ($expire_date && $expire_date < adodb_mktime()) || ($debit <= 0) ) {
$event->status = kEvent::erFAIL;
$object->setCheckoutError(OrderCheckoutErrorType::GIFT_CERTIFICATE, OrderCheckoutError::GC_CODE_EXPIRED);
$event->redirect = false;
return;
}
$object->SetDBField('GiftCertificateId', $gift_certificate->GetDBField('GiftCertificateId'));
$object->Update();
$object->setCheckoutError(OrderCheckoutErrorType::GIFT_CERTIFICATE, OrderCheckoutError::GC_APPLIED);
}
/**
* Removes gift certificate from order
*
* @param kEvent $event
* @deprecated
*/
function OnRemoveGiftCertificate($event)
{
$object = $event->getObject();
/* @var $object OrdersItem */
$this->RemoveGiftCertificate($object);
$object->setCheckoutError(OrderCheckoutErrorType::GIFT_CERTIFICATE, OrderCheckoutError::GC_REMOVED);
$event->CallSubEvent('OnRecalculateItems');
}
function RemoveGiftCertificate(&$object)
{
$object->RemoveGiftCertificate();
}
function RecalculateGift($event)
{
$object = $event->getObject();
/* @var $object OrdersItem */
if ($object->GetDBField('Status') > ORDER_STATUS_PENDING) {
return ;
}
$object->RecalculateGift($event);
}
function GetWholeOrderGiftCertificateDiscount($gift_certificate_id)
{
if (!$gift_certificate_id) {
return 0;
}
$sql = 'SELECT Debit
FROM '.TABLE_PREFIX.'GiftCertificates
WHERE GiftCertificateId = '.$gift_certificate_id;
return $this->Conn->GetOne($sql);
}
/**
* Downloads shipping tracking bar code, that was already generated by USPS service
*
* @param kEvent $event
*/
function OnDownloadLabel($event)
{
$event->status = kEvent::erSTOP;
ini_set('memory_limit', '300M');
ini_set('max_execution_time', '0');
$object = $event->getObject();
/* @var $object kDBItem */
$file = $object->GetDBField('ShippingTracking') . '.pdf';
$full_path = USPS_LABEL_FOLDER . $file;
if ( !file_exists($full_path) || !is_file($full_path) ) {
return;
}
$this->Application->setContentType(kUtil::mimeContentType($full_path), false);
header('Content-Disposition: attachment; filename="' . $file . '"');
readfile($full_path);
}
/**
* Occurs before validation attempt
*
* @param kEvent $event
* @return void
* @access protected
*/
protected function OnBeforeItemValidate(kEvent $event)
{
parent::OnBeforeItemValidate($event);
$create_account = $this->Application->GetVar('create_account');
$object = $event->getObject();
/* @var $object kDBItem */
$required_fields = Array ('UserPassword', 'UserPassword_plain', 'VerifyUserPassword', 'VerifyUserPassword_plain');
$object->setRequired($required_fields, $create_account);
$billing_email = $object->GetDBField('BillingEmail');
if ( $create_account && $object->GetDBField('PortalUserId') == USER_GUEST && $billing_email ) {
// check that e-mail available
$sql = 'SELECT PortalUserId
FROM ' . TABLE_PREFIX . 'Users
WHERE Email = ' . $this->Conn->qstr($billing_email);
$user_id = $this->Conn->GetOne($sql);
if ( $user_id ) {
$object->SetError('BillingEmail', 'unique');
}
}
}
/**
* Performs order update and returns results in format, needed by FormManager
*
* @param kEvent $event
*/
function OnUpdateAjax($event)
{
$ajax_form_helper = $this->Application->recallObject('AjaxFormHelper');
/* @var $ajax_form_helper AjaxFormHelper */
$ajax_form_helper->transitEvent($event, 'OnUpdate');
}
}
\ No newline at end of file
Index: branches/5.3.x/units/orders/orders_item.php
===================================================================
--- branches/5.3.x/units/orders/orders_item.php (revision 15694)
+++ branches/5.3.x/units/orders/orders_item.php (revision 15695)
@@ -1,381 +1,381 @@
<?php
/**
* @version $Id$
* @package In-Commerce
* @copyright Copyright (C) 1997 - 2009 Intechnic. All rights reserved.
* @license Commercial License
* This software 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
* See http://www.in-portal.org/commercial-license for copyright notices and details.
*/
defined('FULL_PATH') or die('restricted access!');
class OrdersItem extends kDBItem
{
/**
* Sets item' fields corresponding to elements in passed $hash values.
*
* The function sets current item fields to values passed in $hash, by matching $hash keys with field names
* of current item. If current item' fields are unknown {@link kDBItem::PrepareFields()} is called before actually setting the fields
*
* @param Array $hash
* @param Array $skip_fields Optional param, field names in target object to skip, other fields will be set
* @param Array $set_fields Optional param, field names in target object to set, other fields will be skipped
* @return void
* @access public
*/
public function SetFieldsFromHash($hash, $skip_fields = Array (), $set_fields = Array ())
{
parent::SetFieldsFromHash($hash, $skip_fields, $set_fields);
$options = $this->GetFieldOptions('PaymentCCExpDate');
if ( $this->GetDirtyField($options['month_field']) || $this->GetDirtyField($options['year_field']) ) {
$this->SetDirtyField('PaymentCCExpDate', 0);
$this->SetField('PaymentCCExpDate', 0);
}
}
/**
* Returns gateway data based on payment type used in order
*
* @param int $pt_id
* @return Array
* @access public
*/
public function getGatewayData($pt_id = null)
{
// get Gateway fields
if ( !isset($pt_id) || !$pt_id ) {
$pt_id = $this->GetDBField('PaymentType');
if ( !$pt_id ) {
// no Payment Type Id found for this order - escape SQL fatal below
return false;
}
}
- $pt_table = $this->Application->getUnitOption('pt', 'TableName');
+ $pt_table = $this->Application->getUnitConfig('pt')->getTableName();
$sql = 'SELECT GatewayId
FROM %s
WHERE PaymentTypeId = %s';
$gw_id = $this->Conn->GetOne(sprintf($sql, $pt_table, $pt_id));
$sql = 'SELECT *
FROM %s
WHERE GatewayId = %s';
$ret = $this->Conn->GetRow(sprintf($sql, TABLE_PREFIX . 'Gateways', $gw_id));
// get Gateway parameters based on payment type
- $gwf_table = $this->Application->getUnitOption('gwf', 'TableName');
- $gwfv_table = $this->Application->getUnitOption('gwfv', 'TableName');
+ $gwf_table = $this->Application->getUnitConfig('gwf')->getTableName();
+ $gwfv_table = $this->Application->getUnitConfig('gwfv')->getTableName();
$sql = 'SELECT gwfv.Value, gwf.SystemFieldName
FROM %s gwf
LEFT JOIN %s gwfv ON gwf.GWConfigFieldId = gwfv.GWConfigFieldId
WHERE gwfv.PaymentTypeId = %s AND gwf.GatewayId = %s';
$ret['gw_params'] = $this->Conn->GetCol(sprintf($sql, $gwf_table, $gwfv_table, $pt_id, $gw_id), 'SystemFieldName');
$ret['gw_params']['gateway_id'] = $gw_id;
if ( $this->GetDBField('IsRecurringBilling') && $this->Application->ConfigValue('Comm_AutoProcessRecurringOrders') ) {
if ( isset($ret['gw_params']['shipping_control']) ) {
$ret['gw_params']['shipping_control'] = SHIPPING_CONTROL_DIRECT;
}
}
return $ret;
}
/**
* Checks if tangible items are present in order
*
* @return bool
*/
function HasTangibleItems()
{
$sql = 'SELECT COUNT(*)
FROM '.TABLE_PREFIX.'OrderItems orditems
LEFT JOIN '.TABLE_PREFIX.'Products p ON p.ProductId = orditems.ProductId
WHERE (orditems.OrderId = '.$this->GetID().') AND (p.Type = '.PRODUCT_TYPE_TANGIBLE.')';
return $this->Conn->GetOne($sql) ? true : false;
}
/**
* Calculates tax value of order items based on billing & shipping country specified
*
* @return double
*/
function getTaxPercent()
{
$cs_helper = $this->Application->recallObject('CountryStatesHelper');
/* @var $cs_helper kCountryStatesHelper */
$shipping_country_id = $cs_helper->getCountryStateId($this->GetDBField('ShippingCountry'), DESTINATION_TYPE_COUNTRY);
$shipping_state_id = $cs_helper->getCountryStateId($this->GetDBField('ShippingState'), DESTINATION_TYPE_STATE);
$shipping_zip = (string) $this->GetDBField('ShippingZip');
$billing_country_id = $cs_helper->getCountryStateId($this->GetDBField('BillingCountry'), DESTINATION_TYPE_COUNTRY);
$billing_state_id = $cs_helper->getCountryStateId($this->GetDBField('BillingState'), DESTINATION_TYPE_STATE);
$billing_zip = (string) $this->GetDBField('BillingZip');
/*
$dest_ids = array_diff( array_unique( Array( $shipping_country_id, $shipping_state_id, $billing_country_id, $billing_state_id ) ), Array(0) );
$dest_values = array_diff( array_unique( Array( $this->Conn->qstr($shipping_zip), $this->Conn->qstr($billing_zip) ) ), Array('\'\'') );
*/
$tax = false;
$sql = 'SELECT tx.*
- FROM '.$this->Application->getUnitOption('tax', 'TableName').' tx
- LEFT JOIN '.$this->Application->getUnitOption('taxdst', 'TableName').' txd ON tx.TaxZoneId = txd.TaxZoneId
+ FROM '.$this->Application->getUnitConfig('tax')->getTableName().' tx
+ LEFT JOIN '.$this->Application->getUnitConfig('taxdst')->getTableName().' txd ON tx.TaxZoneId = txd.TaxZoneId
WHERE
( txd.StdDestId IN ('.$shipping_country_id.','.$shipping_state_id.')
AND
( (txd.DestValue = "" OR txd.DestValue IS NULL)
OR
txd.DestValue = '.$this->Conn->qstr($shipping_zip).'
)
)
OR
( txd.StdDestId IN ('.$billing_country_id.','.$billing_state_id.')
AND
( (txd.DestValue = "" OR txd.DestValue IS NULL)
OR
txd.DestValue = '.$this->Conn->qstr($billing_zip).'
)
)
ORDER BY tx.TaxValue DESC';
$tax = $this->Conn->GetRow($sql);
if ($tax == false) {
$tax['TaxValue'] = 0;
$tax['ApplyToShipping'] = 0;
$tax['ApplyToProcessing'] = 0;
}
return $tax;
}
function RecalculateTax()
{
$tax = $this->getTaxPercent();
$this->SetDBField('VATPercent', $tax['TaxValue']);
$this->SetDBField('ShippingTaxable', $tax['ApplyToShipping']);
$this->SetDBField('ProcessingTaxable', $tax['ApplyToProcessing']);
$this->UpdateTotals();
if ( !$this->GetDBField('VATIncluded') ) {
$subtotal = $this->GetDBField('AmountWithoutVAT');
$tax_exempt = $this->getTaxExempt();
if ( $tax_exempt ) {
$subtotal -= $tax_exempt;
}
$this->SetDBField('VAT', round($subtotal * $tax['TaxValue'] / 100, 2));
$this->UpdateTotals();
}
}
/**
* Returns order amount, that is excluded from tax calculations
*
* @return float
* @access protected
*/
protected function getTaxExempt()
{
$sql = 'SELECT SUM(oi.Quantity * oi.Price)
FROM ' . TABLE_PREFIX . 'OrderItems AS oi
LEFT JOIN ' . TABLE_PREFIX . 'Products AS p ON p.ProductId = oi.ProductId
WHERE p.Type = 6 AND oi.OrderId = ' . $this->GetDBField('OrderId');
return $this->Conn->GetOne($sql);
}
function UpdateTotals()
{
$total = 0;
$total += $this->GetDBField('SubTotal');
if ( $this->GetDBField('ShippingTaxable') ) {
$total += $this->GetDBField('ShippingCost');
}
if ( $this->GetDBField('ProcessingTaxable') ) {
$total += $this->GetDBField('ProcessingFee');
}
if ( $this->GetDBField('VATIncluded') ) {
$tax_exempt = $this->getTaxExempt();
$vat_percent = $this->GetDBField('VATPercent');
$this->SetDBField('VAT', round(($total - $tax_exempt) * $vat_percent / (100 + $vat_percent), 2));
$this->SetDBField('AmountWithoutVAT', $total - $this->GetDBField('VAT'));
}
else {
$this->SetDBField('AmountWithoutVAT', $total);
$total += $this->GetDBField('VAT');
}
if ( !$this->GetDBField('ShippingTaxable') ) {
$total += $this->GetDBField('ShippingCost');
}
if ( !$this->GetDBField('ProcessingTaxable') ) {
$total += $this->GetDBField('ProcessingFee');
}
$total += $this->GetDBField('InsuranceFee');
$this->SetDBField('TotalAmount', $total);
}
function getTotalAmount()
{
return $this->GetDBField('SubTotal') +
$this->GetDBField('ShippingCost') +
($this->GetDBField('VATIncluded') ? 0 : $this->GetDBField('VAT')) +
$this->GetDBField('ProcessingFee') +
$this->GetDBField('InsuranceFee') -
$this->GetDBField('GiftCertificateDiscount');
}
function requireCreditCard()
{
$sql = 'SELECT RequireCCFields
- FROM ' . $this->Application->getUnitOption('pt', 'TableName') . ' pt
+ FROM ' . $this->Application->getUnitConfig('pt')->getTableName() . ' pt
LEFT JOIN '.TABLE_PREFIX.'Gateways gw ON gw.GatewayId = pt.GatewayId
WHERE pt.PaymentTypeId = ' . $this->GetDBField('PaymentType');
return $this->Conn->GetOne($sql);
}
function getNextSubNumber()
{
$table = $this->Application->GetLiveName($this->TableName);
$sql = 'SELECT MAX(SubNumber) FROM '.$table.' WHERE Number = '.$this->GetDBField('Number');
return $this->Conn->GetOne($sql) + 1;
}
function ResetAddress($prefix)
{
$fields = Array('To','Company','Phone','Fax','Email','Address1','Address2','City','State','Zip','Country');
foreach($fields as $field)
{
$this->SetDBField($prefix.$field, $this->Fields[$prefix.$field]['default']);
}
}
function IsProfileAddress($address_type)
{
return $this->Application->GetVar($this->Prefix.'_IsProfileAddress');
}
// ===== Gift Certificates Related =====
function RecalculateGift($event)
{
$gc_id = $this->GetDBField('GiftCertificateId');
if ($gc_id < 1) {
return;
}
$gc = $this->Application->recallObject('gc', null, Array('skip_autoload' => true));
/* @var $gc kDBItem */
$gc->Load($gc_id);
if ($gc->GetDBField('Status') == gcDISABLED) {
// disabled GC
$this->SetDBField('GiftCertificateId', 0);
$this->SetDBField('GiftCertificateDiscount', 0);
// disabled
return;
}
$debit = $gc->GetDBField('Debit') + $this->GetDBField('GiftCertificateDiscount');
$this->UpdateTotals();
$total = $this->GetDBField('TotalAmount');
$gift_certificate_discount = $debit >= $total ? $total : $debit;
$this->SetDBField('TotalAmount', $total - $gift_certificate_discount);
$this->GetDBField('GiftCertificateDiscount', $gift_certificate_discount);
$debit -= $gift_certificate_discount;
$gc->SetDBField('Debit', $debit);
$gc->SetDBField('Status', $debit > 0 ? gcENABLED : gcUSED);
$gc->Update();
if ($gift_certificate_discount == 0) {
$this->RemoveGiftCertificate($object);
$this->setCheckoutError(OrderCheckoutErrorType::GIFT_CERTIFICATE, OrderCheckoutError::GC_REMOVED_AUTOMATICALLY);
}
$this->SetDBField('GiftCertificateDiscount', $gift_certificate_discount);
}
function RemoveGiftCertificate()
{
$gc_id = $this->GetDBField('GiftCertificateId');
$gc = $this->Application->recallObject('gc', null, Array('skip_autoload' => true));
/* @var $gc kDBItem */
$gc->Load($gc_id);
$debit = $gc->GetDBField('Debit') + $this->GetDBField('GiftCertificateDiscount');
if ($gc->isLoaded() && ($debit > 0)) {
$gc->SetDBField('Debit', $debit);
$gc->SetDBField('Status', gcENABLED);
$gc->Update();
}
$this->SetDBField('GiftCertificateId', 0);
$this->SetDBField('GiftCertificateDiscount', 0);
}
/**
* Sets checkout error
*
* @param int $error_type = {product,coupon,gc}
* @param int $error_code
* @param int $product_id - {ProductId}:{OptionsSalt}:{BackOrderFlag}:{FieldName}
*/
function setCheckoutError($error_type, $error_code, $product_id = null)
{
$errors = $this->Application->RecallVar('checkout_errors');
$errors = $errors ? unserialize($errors) : Array ();
if ( isset($product_id) ) {
$error_type .= ':' . $product_id;
// any error takes priority over FIELD_UPDATE_SUCCESS error
if ( isset($errors[$error_type]) && $error_code == OrderCheckoutError::FIELD_UPDATE_SUCCESS ) {
return ;
}
}
if ( is_numeric($error_code) ) {
$errors[$error_type] = $error_code;
}
else {
unset($errors[$error_type]);
}
if ( $this->Application->isDebugMode() ) {
$this->Application->Debugger->appendHTML('CO_ERROR: ' . $error_type . ' - ' . $error_code);
}
$this->Application->StoreVar('checkout_errors', serialize($errors));
}
}
\ No newline at end of file
Index: branches/5.3.x/units/orders/order_calculator.php
===================================================================
--- branches/5.3.x/units/orders/order_calculator.php (revision 15694)
+++ branches/5.3.x/units/orders/order_calculator.php (revision 15695)
@@ -1,859 +1,859 @@
<?php
/**
* @version $Id$
* @package In-Commerce
* @copyright Copyright (C) 1997 - 2009 Intechnic. All rights reserved.
* @license Commercial License
* This software 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
* See http://www.in-portal.org/commercial-license for copyright notices and details.
*/
defined('FULL_PATH') or die('restricted access!');
/**
* Performs order price calculations
*
*/
class OrderCalculator extends kBase {
/**
* Order manager instance
*
* @var OrderManager
*/
protected $manager = null;
/**
* Items, associated with current order
*
* @var Array
*/
protected $items = Array ();
/**
* Creates new clean instance of calculator
*
*/
public function __construct()
{
parent::__construct();
$this->reset();
}
/**
* Sets order manager instance to calculator
*
* @param OrderManager $manager
*/
public function setManager(&$manager)
{
$this->manager =& $manager;
}
public function reset()
{
$this->items = Array ();
}
/**
* Returns order object used in order manager
*
* @return OrdersItem
*/
protected function &getOrder()
{
$order =& $this->manager->getOrder();
return $order;
}
/**
* Sets checkout error
*
* @param int $error_type = {product,coupon,gc}
* @param int $error_code
* @param int $product_id - {ProductId}:{OptionsSalt}:{BackOrderFlag}:{FieldName}
* @return void
* @access protected
*/
protected function setError($error_type, $error_code, $product_id = null)
{
$this->manager->setError($error_type, $error_code, $product_id);
}
/**
* Perform order calculations and prepares operations for order manager
*
*/
public function calculate()
{
$this->queryItems();
$this->groupItems();
$this->generateOperations();
$this->applyWholeOrderFlatDiscount();
}
/**
* Groups order items, when requested
*
* @return Array
*/
protected function groupItems()
{
$skipped_items = Array ();
foreach ($this->items as $item_id => $item_data) {
if ( in_array($item_id, $skipped_items) ) {
continue;
}
$group_items = $this->getItemsToGroupWith($item_id);
if (!$group_items) {
continue;
}
foreach ($group_items as $group_item_id) {
$this->items[$item_id]['Quantity'] += $this->items[$group_item_id]['Quantity'];
$this->items[$group_item_id]['Quantity'] = 0;
}
$skipped_items = array_merge($skipped_items, $group_items);
}
}
/**
* Returns order item ids, that can be grouped with given order item id
*
* @param int $target_item_id
* @return Array
* @see OrderCalculator::canBeGrouped
*/
protected function getItemsToGroupWith($target_item_id)
{
$ret = Array ();
foreach ($this->items as $item_id => $item_data) {
if ( $this->canBeGrouped($this->items[$item_id], $this->items[$target_item_id]) ) {
$ret[] = $item_id;
}
}
return array_diff($ret, Array ($target_item_id));
}
/**
* Checks if 2 given order items can be grouped together
*
* @param Array $src_item
* @param Array $dst_item
* @return bool
*/
public function canBeGrouped($src_item, $dst_item)
{
if ($dst_item['Type'] != PRODUCT_TYPE_TANGIBLE) {
return false;
}
return ($src_item['ProductId'] == $dst_item['ProductId']) && ($src_item['OptionsSalt'] == $dst_item['OptionsSalt']);
}
/**
* Retrieves order contents from database
*
*/
protected function queryItems()
{
- $poc_table = $this->Application->getUnitOption('poc', 'TableName');
+ $poc_table = $this->Application->getUnitConfig('poc')->getTableName();
$query = ' SELECT oi.ProductId, oi.OptionsSalt, oi.ItemData, oi.Quantity,
IF(p.InventoryStatus = ' . ProductInventory::BY_OPTIONS . ', poc.QtyInStock, p.QtyInStock) AS QtyInStock,
p.QtyInStockMin, p.BackOrder, p.InventoryStatus,
p.Type, oi.OrderItemId
FROM ' . $this->getTable('orditems') . ' AS oi
LEFT JOIN ' . TABLE_PREFIX . 'Products AS p ON oi.ProductId = p.ProductId
LEFT JOIN ' . $poc_table . ' poc ON (poc.CombinationCRC = oi.OptionsSalt) AND (oi.ProductId = poc.ProductId)
WHERE oi.OrderId = ' . $this->getOrder()->GetID();
$this->items = $this->Conn->Query($query, 'OrderItemId');
}
/**
* Generates operations and returns true, when something was changed
*
* @return bool
*/
protected function generateOperations()
{
$this->manager->resetOperationTotals();
foreach ($this->items as $item) {
$this->ensureMinQty($item);
$to_order = $back_order = 0;
$available = $this->getAvailableQty($item);
if ( $this->allowBackordering($item) ) {
// split order into order & backorder
if ($item['BackOrder'] == ProductBackorder::ALWAYS) {
$to_order = $available = 0;
$back_order = $item['Quantity'];
}
elseif ($item['BackOrder'] == ProductBackorder::AUTO) {
$to_order = $available;
$back_order = $item['Quantity'] - $available;
}
$qty = $to_order + $back_order;
$price = $this->getPlainProductPrice($item, $qty);
$cost = $this->getProductCost($item, $qty);
$discount_info = $this->getDiscountInfo( $item['ProductId'], $price, $qty );
$this->manager->addOperation($item, 0, $to_order, $price, $cost, $discount_info);
$this->manager->addOperation($item, 1, $back_order, $price, $cost, $discount_info);
}
else {
// store as normal order (and remove backorder)
// we could get here with backorder=never then we should order only what's available
$to_order = min($item['Quantity'], $available);
$price = $this->getPlainProductPrice($item, $to_order);
$cost = $this->getProductCost($item, $to_order);
$discount_info = $this->getDiscountInfo( $item['ProductId'], $price, $to_order );
$this->manager->addOperation($item, 0, $to_order, $price, $cost, $discount_info, $item['OrderItemId']);
$this->manager->addOperation($item, 1, 0, $price, $cost, $discount_info); // remove backorder record
if ($to_order < $item['Quantity']) {
// ordered less, then requested -> inform user
if ( $to_order > 0 ) {
$this->setError(OrderCheckoutErrorType::PRODUCT, OrderCheckoutError::QTY_UNAVAILABLE, $item['ProductId'] . ':' . $item['OptionsSalt'] . ':0:Quantity');
}
else {
$this->setError(OrderCheckoutErrorType::PRODUCT, OrderCheckoutError::QTY_OUT_OF_STOCK, $item['ProductId'] . ':' . $item['OptionsSalt'] . ':0:Quantity');
}
}
}
}
}
/**
* Adds product to order (not to db)
*
* @param Array $item
* @param kCatDBItem $product
* @param int $qty
*/
public function addProduct($item, &$product, $qty)
{
$this->updateItemDataFromProduct($item, $product);
$price = $this->getPlainProductPrice($item, $qty);
$cost = $this->getProductCost($item, $qty);
$discount_info = $this->getDiscountInfo( $item['ProductId'], $price, $qty );
$this->manager->addOperation( $item, 0, $qty, $price, $cost, $discount_info, $item['OrderItemId'] );
}
/**
* Apply whole order flat discount after sub-total been calculated
*
*/
protected function applyWholeOrderFlatDiscount()
{
$sub_total_flat = $this->manager->getOperationTotal('SubTotalFlat');
$flat_discount = min( $sub_total_flat, $this->getWholeOrderPlainDiscount($global_discount_id) );
$coupon_flat_discount = min( $sub_total_flat, $this->getWholeOrderCouponDiscount() );
if ($coupon_flat_discount && $coupon_flat_discount > $flat_discount) {
$global_discount_type = 'coupon';
$flat_discount = $coupon_flat_discount;
$global_discount_id = $coupon_id;
}
else {
$global_discount_type = 'discount';
}
$sub_total = $this->manager->getOperationTotal('SubTotal');
if ($sub_total_flat - $sub_total < $flat_discount) {
// individual item discounts together are smaller when order flat discount
$this->manager->setOperationTotal('CouponDiscount', $flat_discount == $coupon_flat_discount ? $flat_discount : 0);
$this->manager->setOperationTotal('SubTotal', $sub_total_flat - $flat_discount);
// replace discount for each operation
foreach ($this->operations as $index => $operation) {
$discounted_price = ($operation['Price'] / $sub_total_flat) * $sub_total;
$this->operations[$index]['DiscountInfo'] = Array ($global_discount_id, $global_discount_type, $discounted_price, 0);
}
}
}
/**
* Returns discount information for given product price and qty
*
* @param int $product_id
* @param float $price
* @param int $qty
* @return Array
*/
protected function getDiscountInfo($product_id, $price, $qty)
{
$discounted_price = $this->getDiscountedProductPrice($product_id, $price, $discount_id);
$couponed_price = $this->getCouponDiscountedPrice($product_id, $price);
if ($couponed_price < $discounted_price) {
$discount_type = 'coupon';
$discount_id = $coupon_id;
$discounted_price = $couponed_price;
$coupon_discount = ($price - $couponed_price) * $qty;
}
else {
$coupon_discount = 0;
$discount_type = 'discount';
}
return Array ($discount_id, $discount_type, $discounted_price, $coupon_discount);
}
/**
* Returns product qty, available for ordering
*
* @param Array $item
* @return int
*/
protected function getAvailableQty($item)
{
if ( $item['InventoryStatus'] == ProductInventory::DISABLED ) {
// always available
return $item['Quantity'] * 2;
}
return max(0, $item['QtyInStock'] - $item['QtyInStockMin']);
}
/**
* Checks, that product in given order item can be backordered
*
* @param Array $item
* @return bool
*/
protected function allowBackordering($item)
{
if ($item['BackOrder'] == ProductBackorder::ALWAYS) {
return true;
}
$available = $this->getAvailableQty($item);
$backordering = $this->Application->ConfigValue('Comm_Enable_Backordering');
return $backordering && ($item['Quantity'] > $available) && ($item['BackOrder'] == ProductBackorder::AUTO);
}
/**
* Make sure, that user can't order less, then minimal required qty of product
*
* @param Array $item
*/
protected function ensureMinQty(&$item)
{
$sql = 'SELECT MIN(MinQty)
FROM ' . TABLE_PREFIX . 'ProductsPricing
WHERE ProductId = ' . $item['ProductId'];
$min_qty = max(1, $this->Conn->GetOne($sql));
$qty = $item['Quantity'];
if ($qty > 0 && $qty < $min_qty) {
// qty in cart increased to meat minimal qry requirements of given product
$this->setError(OrderCheckoutErrorType::PRODUCT, OrderCheckoutError::QTY_CHANGED_TO_MINIMAL, $item['ProductId'] . ':' . $item['OptionsSalt'] . ':0:Quantity');
$item['Quantity'] = $min_qty;
}
}
/**
* Return product price for given qty, taking no discounts into account
*
* @param Array $item
* @param int $qty
* @return float
*/
public function getPlainProductPrice($item, $qty)
{
$item_data = $this->getItemData($item);
if ( isset($item_data['ForcePrice']) ) {
return $item_data['ForcePrice'];
}
$pricing_id = $this->getPriceBracketByQty($item, $qty);
$sql = 'SELECT Price
FROM ' . TABLE_PREFIX . 'ProductsPricing
WHERE PriceId = ' . $pricing_id;
$price = (float)$this->Conn->GetOne($sql);
if ( isset($item_data['Options']) ) {
$price += $this->getOptionPriceAddition($price, $item_data);
$price = $this->getCombinationPriceOverride($price, $item_data);
}
return max($price, 0);
}
/**
* Return product cost for given qty, taking no discounts into account
*
* @param Array $item
* @param int $qty
* @return float
*/
public function getProductCost($item, $qty)
{
$pricing_id = $this->getPriceBracketByQty($item, $qty);
$sql = 'SELECT Cost
FROM ' . TABLE_PREFIX . 'ProductsPricing
WHERE PriceId = ' . $pricing_id;
return (float)$this->Conn->GetOne($sql);
}
/**
* Return product price for given qty, taking no discounts into account
*
* @param Array $item
* @param int $qty
* @return float
*/
protected function getPriceBracketByQty($item, $qty)
{
$orderby_clause = '';
$where_clause = Array ();
$product_id = $item['ProductId'];
if ( $this->usePriceBrackets($item) ) {
$user_id = $this->getOrder()->GetDBField('PortalUserId');
$where_clause = Array (
'GroupId IN (' . $this->Application->getUserGroups($user_id) . ')',
'pp.ProductId = ' . $product_id,
'pp.MinQty <= ' . $qty,
$qty . ' < pp.MaxQty OR pp.MaxQty = -1',
);
$orderby_clause = $this->getPriceBracketOrderClause($user_id);
}
else {
$item_data = $this->getItemData($item);
$where_clause = Array(
'pp.ProductId = ' . $product_id,
'pp.PriceId = ' . $this->getPriceBracketFromRequest($product_id, $item_data),
);
}
$sql = 'SELECT pp.PriceId
FROM ' . TABLE_PREFIX . 'ProductsPricing AS pp
LEFT JOIN ' . TABLE_PREFIX . 'Products AS p ON p.ProductId = pp.ProductId
WHERE (' . implode(') AND (', $where_clause) . ')';
if ($orderby_clause) {
$sql .= ' ORDER BY ' . $orderby_clause;
}
return (float)$this->Conn->GetOne($sql);
}
/**
* Checks if price brackets should be used in price calculations
*
* @param Array $item
* @return bool
*/
protected function usePriceBrackets($item)
{
return $item['Type'] == PRODUCT_TYPE_TANGIBLE;
}
/**
* Return product pricing id for given product.
* If not passed - return primary pricing ID
*
* @param int $product_id
* @return int
*/
public function getPriceBracketFromRequest($product_id, $item_data)
{
if ( !is_array($item_data) ) {
$item_data = unserialize($item_data);
}
// remembered pricing during checkout
if ( isset($item_data['PricingId']) && $item_data['PricingId'] ) {
return $item_data['PricingId'];
}
// selected pricing from product detail page
$price_id = $this->Application->GetVar('pr_id');
if ($price_id) {
return $price_id;
}
$sql = 'SELECT PriceId
FROM ' . TABLE_PREFIX . 'ProductsPricing
WHERE ProductId = ' . $product_id . ' AND IsPrimary = 1';
return $this->Conn->GetOne($sql);
}
/**
* Returns order clause for price bracket selection based on configration
*
* @param int $user_id
* @return string
*/
protected function getPriceBracketOrderClause($user_id)
{
if ($this->Application->ConfigValue('Comm_PriceBracketCalculation') == 1) {
// if we have to stick to primary group, then its pricing will go first,
// but if there is no pricing for primary group, then next optimal will be taken
$primary_group = $this->getUserPrimaryGroup($user_id);
return '( IF(GroupId = ' . $primary_group . ', 1, 2) ) ASC, pp.Price ASC';
}
return 'pp.Price ASC';
}
/**
* Returns addition to product price based on used product option
*
* @param float $price
* @param Array $item_data
* @return float
*/
protected function getOptionPriceAddition($price, $item_data)
{
$addition = 0;
$opt_helper = $this->Application->recallObject('kProductOptionsHelper');
/* @var $opt_helper kProductOptionsHelper */
foreach ($item_data['Options'] as $opt => $val) {
$sql = 'SELECT *
FROM ' . TABLE_PREFIX . 'ProductOptions
WHERE ProductOptionId = ' . $opt;
$data = $this->Conn->GetRow($sql);
$parsed = $opt_helper->ExplodeOptionValues($data);
if ( !$parsed ) {
continue;
}
if ( is_array($val) ) {
foreach ($val as $a_val) {
$addition += $this->formatPrice($a_val, $price, $parsed);
}
}
else {
$addition += $this->formatPrice($val, $price, $parsed);
}
}
return $addition;
}
protected function formatPrice($a_val, $price, $parsed)
{
$a_val = htmlspecialchars_decode($a_val);
$addition = 0;
$conv_prices = $parsed['Prices'];
$conv_price_types = $parsed['PriceTypes'];
if ( isset($conv_prices[$a_val]) && $conv_prices[$a_val] ) {
if ($conv_price_types[$a_val] == '$') {
$addition += $conv_prices[$a_val];
}
elseif ($conv_price_types[$a_val] == '%') {
$addition += $price * $conv_prices[$a_val] / 100;
}
}
return $addition;
}
/**
* Returns product price after applying combination price override
*
* @param float $price
* @param Array $item_data
* @return float
*/
protected function getCombinationPriceOverride($price, $item_data)
{
$combination_salt = $this->generateOptionsSalt( $item_data['Options'] );
if (!$combination_salt) {
return $price;
}
$sql = 'SELECT *
FROM ' . TABLE_PREFIX . 'ProductOptionCombinations
WHERE CombinationCRC = ' . $combination_salt;
$combination = $this->Conn->GetRow($sql);
if (!$combination) {
return $price;
}
switch ( $combination['PriceType'] ) {
case OptionCombinationPriceType::EQUALS:
return $combination['Price'];
break;
case OptionCombinationPriceType::FLAT:
return $price + $combination['Price'];
break;
case OptionCombinationPriceType::PECENT:
return $price * (1 + $combination['Price'] / 100);
break;
}
return $price;
}
/**
* Generates salt for given option set
*
* @param Array $options
* @return int
*/
public function generateOptionsSalt($options)
{
$opt_helper = $this->Application->recallObject('kProductOptionsHelper');
/* @var $opt_helper kProductOptionsHelper */
return $opt_helper->OptionsSalt($options, true);
}
/**
* Return product price for given qty, taking possible discounts into account
*
* @param int $product_id
* @param int $price
* @param int $discount_id
* @return float
*/
public function getDiscountedProductPrice($product_id, $price, &$discount_id)
{
$discount_id = 0;
$user_id = $this->getOrder()->GetDBField('PortalUserId');
$join_clause = Array (
'd.DiscountId = di.DiscountId',
'di.ItemType = ' . DiscountItemType::PRODUCT . ' OR (di.ItemType = ' . DiscountItemType::WHOLE_ORDER . ' AND d.Type = ' . DiscountType::PERCENT . ')',
'd.Status = ' . STATUS_ACTIVE,
'd.GroupId IN (' . $this->Application->getUserGroups($user_id) . ')',
'd.Start IS NULL OR d.Start < ' . $this->getOrder()->GetDBField('OrderDate'),
'd.End IS NULL OR d.End > ' . $this->getOrder()->GetDBField('OrderDate'),
);
$sql = 'SELECT
CASE d.Type
WHEN ' . DiscountType::FLAT . ' THEN ' . $price . ' - d.Amount
WHEN ' . DiscountType::PERCENT . ' THEN ' . $price . ' * (1 - d.Amount / 100)
ELSE ' . $price . '
END, d.DiscountId
FROM ' . TABLE_PREFIX . 'Products AS p
LEFT JOIN ' . TABLE_PREFIX . 'ProductsDiscountItems AS di ON (di.ItemResourceId = p.ResourceId) OR (di.ItemType = ' . DiscountItemType::WHOLE_ORDER . ')
LEFT JOIN ' . TABLE_PREFIX . 'ProductsDiscounts AS d ON (' . implode(') AND (', $join_clause) . ')
WHERE (p.ProductId = ' . $product_id . ') AND (d.DiscountId IS NOT NULL)';
$pricing = $this->Conn->GetCol($sql, 'DiscountId');
if (!$pricing) {
return $price;
}
// get minimal price + discount
$discounted_price = min($pricing);
$pricing = array_flip($pricing);
$discount_id = $pricing[$discounted_price];
// optimal discount, but prevent negative price
return max( min($discounted_price, $price), 0 );
}
public function getWholeOrderPlainDiscount(&$discount_id)
{
$discount_id = 0;
$user_id = $this->getOrder()->GetDBField('PortalUserId');
$join_clause = Array (
'd.DiscountId = di.DiscountId',
'di.ItemType = ' . DiscountItemType::WHOLE_ORDER . ' AND d.Type = ' . DiscountType::FLAT,
'd.Status = ' . STATUS_ACTIVE,
'd.GroupId IN (' . $this->Application->getUserGroups($user_id) . ')',
'd.Start IS NULL OR d.Start < ' . $this->getOrder()->GetDBField('OrderDate'),
'd.End IS NULL OR d.End > ' . $this->getOrder()->GetDBField('OrderDate'),
);
$sql = 'SELECT d.Amount AS Discount, d.DiscountId
FROM ' . TABLE_PREFIX . 'ProductsDiscountItems AS di
LEFT JOIN ' . TABLE_PREFIX . 'ProductsDiscounts AS d ON (' . implode(') AND (', $join_clause) . ')
WHERE d.DiscountId IS NOT NULL';
$pricing = $this->Conn->GetCol($sql, 'DiscountId');
if (!$pricing) {
return 0;
}
$discounted_price = max($pricing);
$pricing = array_flip($pricing);
$discount_id = $pricing[$discounted_price];
return max($discounted_price, 0);
}
public function getCouponDiscountedPrice($product_id, $price)
{
if ( !$this->getCoupon() ) {
return $price;
}
$join_clause = Array (
'c.CouponId = ci.CouponId',
'ci.ItemType = ' . CouponItemType::PRODUCT . ' OR (ci.ItemType = ' . CouponItemType::WHOLE_ORDER . ' AND c.Type = ' . CouponType::PERCENT . ')',
);
$sql = 'SELECT
MIN(
CASE c.Type
WHEN ' . CouponType::FLAT . ' THEN ' . $price . ' - c.Amount
WHEN ' . CouponType::PERCENT . ' THEN ' . $price . ' * (1 - c.Amount / 100)
ELSE ' . $price . '
END
)
FROM ' . TABLE_PREFIX . 'Products AS p
LEFT JOIN ' . TABLE_PREFIX . 'ProductsCouponItems AS ci ON (ci.ItemResourceId = p.ResourceId) OR (ci.ItemType = ' . CouponItemType::WHOLE_ORDER . ')
LEFT JOIN ' . TABLE_PREFIX . 'ProductsCoupons AS c ON (' . implode(') AND (', $join_clause) . ')
WHERE p.ProductId = ' . $product_id . ' AND ci.CouponId = ' . $this->getCoupon() . '
GROUP BY p.ProductId';
$coupon_price = $this->Conn->GetOne($sql);
if ($coupon_price === false) {
return $price;
}
return max( min($price, $coupon_price), 0 );
}
public function getWholeOrderCouponDiscount()
{
if ( !$this->getCoupon() ) {
return 0;
}
$where_clause = Array (
'ci.CouponId = ' . $this->getCoupon(),
'ci.ItemType = ' . CouponItemType::WHOLE_ORDER,
'c.Type = ' . CouponType::FLAT,
);
$sql = 'SELECT Amount
FROM ' . TABLE_PREFIX . 'ProductsCouponItems AS ci
LEFT JOIN ' . TABLE_PREFIX . 'ProductsCoupons AS c ON c.CouponId = ci.CouponId
WHERE (' . implode(') AND (', $where_clause) . ')';
return $this->Conn->GetOne($sql);
}
protected function getCoupon()
{
return $this->getOrder()->GetDBField('CouponId');
}
/**
* Returns primary group of given user
*
* @param int $user_id
* @return int
*/
protected function getUserPrimaryGroup($user_id)
{
if ($user_id > 0) {
$sql = 'SELECT PrimaryGroupId
FROM ' . TABLE_PREFIX . 'Users
WHERE PortalUserId = ' . $user_id;
return $this->Conn->GetOne($sql);
}
return $this->Application->ConfigValue('User_LoggedInGroup');
}
/**
* Returns ItemData associated with given order item
*
* @param Array $item
* @return Array
*/
protected function getItemData($item)
{
$item_data = $item['ItemData'];
if ( is_array($item_data) ) {
return $item_data;
}
return $item_data ? unserialize($item_data) : Array ();
}
/**
* Sets ItemData according to product
*
* @param Array $item
* @param kCatDBItem $product
*/
protected function updateItemDataFromProduct(&$item, &$product)
{
$item_data = $this->getItemData($item);
$item_data['IsRecurringBilling'] = $product->GetDBField('IsRecurringBilling');
// it item is processed in order using new style, then put such mark in orderitem record
$processing_data = $product->GetDBField('ProcessingData');
if ($processing_data) {
$processing_data = unserialize($processing_data);
if ( isset($processing_data['HasNewProcessing']) ) {
$item_data['HasNewProcessing'] = 1;
}
}
$item['ItemData'] = serialize($item_data);
}
/**
* Returns table name according to order temp mode
*
* @param string $prefix
* @return string
*/
protected function getTable($prefix)
{
return $this->manager->getTable($prefix);
}
}
\ No newline at end of file
Index: branches/5.3.x/units/orders/order_manager.php
===================================================================
--- branches/5.3.x/units/orders/order_manager.php (revision 15694)
+++ branches/5.3.x/units/orders/order_manager.php (revision 15695)
@@ -1,485 +1,485 @@
<?php
/**
* @version $Id$
* @package In-Commerce
* @copyright Copyright (C) 1997 - 2009 Intechnic. All rights reserved.
* @license Commercial License
* This software 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
* See http://www.in-portal.org/commercial-license for copyright notices and details.
*/
defined('FULL_PATH') or die('restricted access!');
/**
* Manages order contents
*
*/
class OrderManager extends kBase {
protected $errorMessages = Array (
1 => 'state_changed',
2 => 'qty_unavailable',
3 => 'outofstock',
4 => 'invalid_code',
5 => 'code_expired',
6 => 'min_qty',
7 => 'code_removed',
8 => 'code_removed_automatically',
9 => 'changed_after_login',
10 => 'coupon_applied',
104 => 'invalid_gc_code',
105 => 'gc_code_expired',
107 => 'gc_code_removed',
108 => 'gc_code_removed_automatically',
110 => 'gift_certificate_applied',
);
/**
* Order, used in calculator
*
* @var OrdersItem
*/
protected $order = null;
/**
* Order calculator instance
*
* @var OrderCalculator
*/
protected $calculator = null;
/**
* Operations to be performed on order items later
*
* @var Array
*/
protected $operations = Array ();
/**
* Totals override
*
* @var Array
*/
protected $totalsOverride = Array ();
public function __construct()
{
parent::__construct();
$this->calculator = $this->Application->makeClass('OrderCalculator');
$this->calculator->setManager($this);
$this->reset();
}
/**
* Sets order to be used in calculator
*
* @param OrdersItem $order
*/
public function setOrder(&$order)
{
$this->order =& $order;
$this->reset();
}
function reset()
{
$this->operations = Array ();
$this->totalsOverride = Array ();
$this->calculator->reset();
}
public function resetOperationTotals()
{
$this->totalsOverride = Array ();
}
/**
* Sets checkout error
*
* @param int $error_type = {product,coupon,gc}
* @param int $error_code
* @param int $product_id - {ProductId}:{OptionsSalt}:{BackOrderFlag}:{FieldName}
* @return void
* @access public
*/
public function setError($error_type, $error_code, $product_id = null)
{
$this->order->setCheckoutError($error_type, $error_code, $product_id);
}
/**
* Gets error count
*
* @return int
* @access public
*/
public function getErrorCount()
{
$errors = $this->Application->RecallVar('checkout_errors');
if ( !$errors ) {
return 0;
}
return count( unserialize($errors) );
}
/**
* Returns order object reference
*
* @return OrdersItem
*/
public function &getOrder()
{
return $this->order;
}
/**
* Calculates given order
*
*/
public function calculate()
{
$this->calculator->calculate();
$changed = $this->applyOperations() || ($this->getErrorCount() > 0);
$this->setOrderTotals();
return $changed;
}
public function addOperation($item, $backorder_flag, $qty, $price, $cost, $discount_info, $order_item_id = 0)
{
$operation = Array (
'ProductId' => $item['ProductId'],
'BackOrderFlag' => $backorder_flag,
'Quantity' => $qty,
'Price' => $price,
'Cost' => $cost,
'DiscountInfo' => $discount_info,
'OrderItemId' => $order_item_id,
'OptionsSalt' => $item['OptionsSalt'],
'ItemData' => $item['ItemData'],
'PackageNum' => array_key_exists('PackageNum', $item) ? $item['PackageNum'] : 1,
);
$this->operations[] = $operation;
}
/**
* Returns total based on added operations
*
* @param string $type
* @return float
*/
public function getOperationTotal($type)
{
if ( isset($this->totalsOverride[$type]) ) {
return $this->totalsOverride[$type];
}
$ret = 0;
foreach ($this->operations as $operation) {
if ($type == 'SubTotalFlat') {
$ret += $operation['Quantity'] * $operation['Price'];
}
elseif ($type == 'CostTotal') {
$ret += $operation['Quantity'] * $operation['Cost'];
}
elseif ($type == 'SubTotal') {
$ret += $operation['Quantity'] * $operation['DiscountInfo'][2]; // discounted price
}
elseif ($type == 'CouponDiscount') {
$ret += $operation['DiscountInfo'][3];
}
}
return $ret;
}
public function setOperationTotal($type, $value)
{
$this->totalsOverride[$type] = $value;
}
/**
* Apply scheduled operations
*
*/
public function applyOperations()
{
$ret = false;
$order_item = $this->Application->recallObject('orditems.-item', null, Array('skip_autoload' => true));
/* @var $order_item kDBItem */
foreach ($this->operations as $operation) {
$item = $this->getOrderItemByOperation($operation);
$item_id = $item['OrderItemId'];
if ($item_id) { // if Product already exists in the order
if ( $this->noChangeRequired($item, $operation) ) {
continue;
}
$order_item->Load($item_id);
if ($operation['Quantity'] > 0) { // Update Price by _TOTAL_ qty
$item_data = $order_item->GetDBField('ItemData');
$item_data = $item_data ? unserialize($item_data) : Array ();
$item_data['DiscountId'] = $operation['DiscountInfo'][0];
$item_data['DiscountType'] = $operation['DiscountInfo'][1];
$fields_hash = Array (
'Quantity' => $operation['Quantity'],
'FlatPrice' => $operation['Price'],
'Price' => $operation['DiscountInfo'][2],
'Cost' => $operation['Cost'],
'ItemData' => serialize($item_data),
);
$order_item->SetDBFieldsFromHash($fields_hash);
$order_item->Update();
}
else { // delete products with 0 qty
$order_item->Delete();
}
}
elseif ($operation['Quantity'] > 0) {
// if we are adding product
// discounts are saved from OrdersEvetnHandler::AddItemToOrder method
$item_data = $operation['ItemData'];
$item_data = $item_data ? unserialize($item_data) : Array ();
$item_data['DiscountId'] = $operation['DiscountInfo'][0];
$item_data['DiscountType'] = $operation['DiscountInfo'][1];
$fields_hash = Array (
'ProductId' => $operation['ProductId'],
'ProductName' => $this->getProductField( $operation['ProductId'], 'Name' ),
'Quantity' => $operation['Quantity'],
'FlatPrice' => $operation['Price'],
'Price' => $operation['DiscountInfo'][2],
'Cost' => $operation['Cost'],
'Weight' => $this->getProductField( $operation['ProductId'], 'Weight' ),
'OrderId' => $this->order->GetID(),
'BackOrderFlag' => $operation['BackOrderFlag'],
'ItemData' => serialize($item_data),
'PackageNum' => $operation['PackageNum'],
);
$order_item->SetDBFieldsFromHash($fields_hash);
$order_item->Create();
}
else {
// item requiring to set qty to 0, meaning already does not exist
continue;
}
$ret = true;
}
return $ret;
}
/**
* Sets order fields, containing total values
*
*/
public function setOrderTotals()
{
$sub_total = $this->getOperationTotal('SubTotal');
$this->order->SetDBField('SubTotal', $sub_total);
$cost_total = $this->getOperationTotal('CostTotal');
$this->order->SetDBField('CostTotal', $cost_total);
$sub_total_flat = $this->getOperationTotal('SubTotalFlat');
$this->order->SetDBField('DiscountTotal', $sub_total_flat - $sub_total);
$coupon_discount = $this->getOperationTotal('CouponDiscount');
$this->order->SetDBField('CouponDiscount', $coupon_discount);
}
/**
* Returns exising order item data, based on operation details
*
* @param Array $operation
* @return Array
*/
protected function getOrderItemByOperation($operation)
{
if ( $operation['OrderItemId'] ) {
$where_clause = Array (
'OrderItemId = ' . $operation['OrderItemId'],
);
}
else {
$where_clause = Array (
'OrderId = ' . $this->order->GetID(),
'ProductId = ' . $operation['ProductId'],
'BackOrderFlag ' . ($operation['BackOrderFlag'] ? ' >= 1' : ' = 0'),
'OptionsSalt = ' . $operation['OptionsSalt'],
);
}
$sql = 'SELECT OrderItemId, Quantity, FlatPrice, Price, BackOrderFlag, ItemData
FROM ' . $this->getTable('orditems') . '
WHERE (' . implode(') AND (', $where_clause) . ')';
return $this->Conn->GetRow($sql);
}
/**
* Checks, that there are no database changes required to order item from operation
*
* @param Array $item
* @param Array $operation
* @return bool
*/
protected function noChangeRequired($item, $operation)
{
$item_data = $item['ItemData'] ? unserialize( $item['ItemData'] ) : Array ();
$conditions = Array (
$operation['Quantity'] > 0,
$item['Quantity'] == $operation['Quantity'],
round($item['FlatPrice'], 3) == round($operation['Price'], 3),
round($item['Price'], 3) == round($operation['DiscountInfo'][2], 3),
(string)getArrayValue($item_data, 'DiscountType') == $operation['DiscountInfo'][1],
(int)getArrayValue($item_data, 'DiscountId') == $operation['DiscountInfo'][0],
);
foreach ($conditions as $condition) {
if (!$condition) {
return false;
}
}
return true;
}
/**
* Returns product name by id
*
* @param int $product_id
* @param string $field
* @return string
*/
protected function getProductField($product_id, $field)
{
$product = $this->Application->recallObject('p', null, Array ('skip_autoload' => true));
/* @var $product kCatDBItem */
if ( !$product->isLoaded() || ($product->GetID() != $product_id) ) {
$product->Load($product_id);
}
return $field == 'Name' ? $product->GetField($field) : $product->GetDBField($field);
}
/**
* Returns table name according to order temp mode
*
* @param string $prefix
* @return string
*/
public function getTable($prefix)
{
- $table_name = $this->Application->getUnitOption($prefix, 'TableName');
+ $table_name = $this->Application->getUnitConfig($prefix)->getTableName();
if ( $this->order->IsTempTable() ) {
return $this->Application->GetTempName($table_name, 'prefix:' . $this->order->Prefix);
}
return $table_name;
}
/**
* Adds product to order
*
* @param kCatDBItem $product
* @param string $item_data
* @param int $qty
* @param int $package_num
*/
public function addProduct(&$product, $item_data, $qty = null, $package_num = null)
{
if ( !isset($qty) ) {
$qty = 1;
}
$item = $this->getItemFromProduct($product, $item_data);
$order_item = $this->getOrderItem($item);
if ( $this->calculator->canBeGrouped($item, $item) && $order_item ) {
$qty += $order_item['Quantity'];
}
$item['OrderItemId'] = $order_item ? $order_item['OrderItemId'] : 0;
if ( isset($package_num) ) {
$item['PackageNum'] = $package_num;
}
$this->calculator->addProduct($item, $product, $qty);
$this->applyOperations();
}
/**
* Returns virtual $item based on given product
*
* @param kCatDBItem $product
* @param string $item_data
* @return Array
*/
protected function getItemFromProduct(&$product, $item_data)
{
$item_data_array = unserialize($item_data);
$options = isset($item_data_array['Options']) ? $item_data_array['Options'] : false;
$options_salt = $options ? $this->calculator->generateOptionsSalt($options) : 0;
$item = Array (
'ProductId' => $product->GetID(),
'OptionsSalt' => $options_salt,
'ItemData' => $item_data,
'Type' => $product->GetDBField('Type'),
'OrderItemId' => 0,
);
return $item;
}
/**
* Returns OrderItem formed from $item
*
* @param Array $item
* @return Array
*/
protected function getOrderItem($item)
{
$where_clause = Array (
'OrderId = ' . $this->order->GetID(),
'ProductId = ' . $item['ProductId'],
);
if ( $item['OptionsSalt'] ) {
$where_clause[] = 'OptionsSalt = ' . $item['OptionsSalt'];
}
$sql = 'SELECT Quantity, OrderItemId
FROM ' . $this->getTable('orditems') . '
WHERE (' . implode(') AND (', $where_clause) . ')';
return $this->Conn->GetRow($sql);
}
}
\ No newline at end of file
Index: branches/5.3.x/units/orders/orders_tag_processor.php
===================================================================
--- branches/5.3.x/units/orders/orders_tag_processor.php (revision 15694)
+++ branches/5.3.x/units/orders/orders_tag_processor.php (revision 15695)
@@ -1,1653 +1,1659 @@
<?php
/**
* @version $Id$
* @package In-Commerce
* @copyright Copyright (C) 1997 - 2009 Intechnic. All rights reserved.
* @license Commercial License
* This software 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
* See http://www.in-portal.org/commercial-license for copyright notices and details.
*/
defined('FULL_PATH') or die('restricted access!');
class OrdersTagProcessor extends kDBTagProcessor
{
/**
* Print location using only filled in fields
*
* @param Array $params
* @access public
*/
function PrintLocation($params)
{
$object = $this->getObject($params);
$type = getArrayValue($params,'type');
if($type == 'Company')
{
return $this->PrintCompanyLocation($params);
}
$fields = Array('City','State','Zip','Country');
$ret = '';
foreach($fields as $field)
{
$value = $object->GetField($type.$field);
if ($field == 'Country' && $value) $ret .= '<br/>';
if($value) $ret .= $value.', ';
}
return rtrim($ret,', ');
}
function PrintCompanyLocation($params)
{
$ret = '';
$fields = Array ('City','State','ZIP','Country');
foreach ($fields as $field) {
$value = $this->Application->ConfigValue('Comm_'.$field);
if ($field == 'Country') {
$current_language = $this->Application->GetVar('m_lang');
$primary_language = $this->Application->GetDefaultLanguageId();
$sql = 'SELECT IF(l' . $current_language . '_Name = "", l' . $primary_language . '_Name, l' . $current_language . '_Name)
FROM ' . TABLE_PREFIX . 'CountryStates
WHERE IsoCode = ' . $this->Conn->qstr($value);
$value = $this->Conn->GetOne($sql);
}
if ($field == 'Country' && $value) {
$ret .= '<br/>';
}
if ($value) {
$ret .= $value.', ';
}
}
return rtrim($ret,', ');
}
function Orditems_LinkRemoveFromCart($params)
{
return $this->Application->HREF($this->Application->GetVar('t'), '', Array('pass' => 'm,orditems,ord', 'ord_event' => 'OnRemoveFromCart', 'm_cat_id'=>0));
}
function Orderitems_ProductLink($params)
{
$object = $this->Application->recallObject('orditems');
$url_params = Array (
'p_id' => $object->GetDBField('ProductId'),
'pass' => 'm,p',
);
return $this->Application->HREF($params['template'], '', $url_params);
}
function Orderitems_ProductExists($params)
{
$object = $this->Application->recallObject('orditems');
return $object->GetDBField('ProductId') > 0;
}
function PrintCart($params)
{
$o = '';
$params['render_as'] = $params['item_render_as'];
$tag_params = array_merge($params, Array ('per_page' => -1));
$o_items = $this->Application->ProcessParsedTag(rtrim('orditems.' . $this->Special, '.'), 'PrintList', $tag_params);
if ( $o_items ) {
if ( isset($params['header_render_as']) ) {
$cart_params = array ('name' => $params['header_render_as']);
$o .= $this->Application->ParseBlock($cart_params);
}
$o .= $o_items;
if ( isset($params['footer_render_as']) ) {
$cart_params = array ('name' => $params['footer_render_as']);
$o .= $this->Application->ParseBlock($cart_params);
}
}
elseif ( isset($params['empty_cart_render_as']) ) {
$cart_params = array ('name' => $params['empty_cart_render_as']);
$o = $this->Application->ParseBlock($cart_params);
}
return $o;
}
function ShopCartForm($params)
{
return $this->Application->ProcessParsedTag('m', 'ParseBlock', array_merge($params, Array(
'name' => 'kernel_form', 'PrefixSpecial'=>'ord'
)) );
}
function BackOrderFlag($params)
{
$object = $this->Application->recallObject('orditems');
return $object->GetDBField('BackOrderFlag');
}
function OrderIcon($params)
{
$object = $this->Application->recallObject('orditems');
if ($object->GetDBField('BackOrderFlag') == 0) {
return $params['ordericon'];
} else {
return $params['backordericon'];
}
}
function Status($params)
{
$status_map = Array(
'incomplete' => ORDER_STATUS_INCOMPLETE,
'pending' => ORDER_STATUS_PENDING,
'backorder' => ORDER_STATUS_BACKORDERS,
'toship' => ORDER_STATUS_TOSHIP,
'processed' => ORDER_STATUS_PROCESSED,
'denied' => ORDER_STATUS_DENIED,
'archived' => ORDER_STATUS_ARCHIVED,
);
$object = $this->getObject($params);
$status = $object->GetDBField('Status');
$result = true;
if (isset($params['is'])) {
$result = $result && ($status == $status_map[$params['is']]);
}
if (isset($params['is_not'])) {
$result = $result && ($status != $status_map[$params['is_not']]);
}
return $result;
}
function ItemsInCart($params)
{
$object = $this->getObject($params);
/* @var $object kDBItem */
if ( $object->GetDBField('Status') != ORDER_STATUS_INCOMPLETE || $object->GetID() == FAKE_ORDER_ID ) {
return 0;
}
$object = $this->Application->recallObject('orditems', 'orditems_List');
/* @var $object kDBList */
$object->Query();
return array_sum($object->GetCol('Quantity')); // $object->GetRecordsCount();
}
function CartNotEmpty($params)
{
$object = $this->getObject($params);
if ($object->GetDBField('Status') != ORDER_STATUS_INCOMPLETE || $object->GetID() == FAKE_ORDER_ID) {
return 0;
}
$order_id = $this->Application->RecallVar('ord_id');
if ($order_id) {
$sql = 'SELECT COUNT(*)
FROM ' . TABLE_PREFIX . 'OrderItems
WHERE OrderId = ' . $order_id;
return $this->Conn->GetOne($sql);
}
return 0;
}
function CartIsEmpty($params)
{
return $this->CartNotEmpty($params) ? false : true;
}
function CartHasBackorders($params = Array ())
{
$object = $this->getObject($params);
$sql = 'SELECT COUNT(*)
FROM ' . TABLE_PREFIX . 'OrderItems
WHERE OrderId = ' . $object->GetID() . '
GROUP BY BackOrderFlag';
$different_types = $this->Conn->GetCol($sql);
return count($different_types) > 1;
}
function PrintShippings($params)
{
$o = '';
$limitations_cache = Array ();
$object = $this->getObject($params);
/* @var $object kDBItem */
$ord_id = $object->GetID();
- $oi_table = $this->Application->getUnitOption('orditems', 'TableName');
+ $oi_table = $this->Application->getUnitConfig('orditems')->getTableName();
if ( $object->IsTempTable() ) {
$oi_table = $this->Application->GetTempName($oi_table, 'prefix:' . $object->Prefix);
}
list ($split_shipments, $limit_types) = $this->GetShippingLimitations($ord_id);
foreach ($split_shipments as $group => $data) {
$sql = 'UPDATE ' . $oi_table . '
SET SplitShippingGroup = ' . $group . '
WHERE ProductId IN (' . implode(',', $data['Products']) . ')';
$this->Conn->Query($sql);
$limitations_cache[$group] = $data['Types'];
}
$shipping_group_option = $object->GetDBField('ShippingGroupOption');
$shipping_group_select = $shipping_group_option == ORDER_GROUP_SHIPPMENTS_AUTO ? '0' : 'oi.SplitShippingGroup';
if ( count($split_shipments) > 1 ) {
// different shipping limitations apply
$this->Application->SetVar('shipping_limitations_apply', 1);
if ( $limit_types == 'NONE' ) {
// order can't be shipped with single shipping type
$shipping_group_option = ORDER_GROUP_SHIPPMENTS_MANUAL;
$shipping_group_select = 'oi.SplitShippingGroup';
$this->Application->SetVar('shipping_limitations_apply', 2);
}
}
else {
$this->Application->SetVar('shipping_limitations_apply', 0);
}
$shipping_option = $object->GetDBField('ShippingOption');
$weight_sql = 'IF(oi.Weight IS NULL, 0, oi.Weight * oi.Quantity)';
$sql = 'SELECT
' . ($shipping_option == ORDER_SHIP_ALL_TOGETHER ? '0' : 'oi.BackOrderFlag') . ' AS BackOrderFlagCalc,
oi.ProductName,
oi.ShippingTypeId,
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,
' . $shipping_group_select . ' AS SplitShippingGroupCalc
FROM ' . $oi_table . ' oi
LEFT JOIN ' . TABLE_PREFIX . 'Products p ON oi.ProductId = p.ProductId
WHERE oi.OrderId = ' . $ord_id . ' AND p.Type = ' . PRODUCT_TYPE_TANGIBLE . '
GROUP BY BackOrderFlagCalc, SplitShippingGroupCalc
ORDER BY BackOrderFlagCalc ASC, SplitShippingGroupCalc ASC';
$shipments = $this->Conn->Query($sql);
$block_params = Array ();
$block_params['name'] = $this->SelectParam($params, 'render_as,block');
$block_params['user_country_id'] = $object->GetDBField('ShippingCountry');
$block_params['user_state_id'] = $object->GetDBField('ShippingState');
$block_params['user_zip'] = $object->GetDBField('ShippingZip');
$block_params['user_city'] = $object->GetDBField('ShippingCity');
$block_params['user_addr1'] = $object->GetDBField('ShippingAddress1');
$block_params['user_addr2'] = $object->GetDBField('ShippingAddress2');
$block_params['user_name'] = $object->GetDBField('ShippingTo');
$group = 1;
foreach ($shipments as $shipment) {
$where = Array ('OrderId = ' . $ord_id);
if ( $shipping_group_option == ORDER_GROUP_SHIPPMENTS_MANUAL ) {
$where[] = 'SplitShippingGroup = ' . $shipment['SplitShippingGroupCalc'];
}
if ( $shipping_option != ORDER_SHIP_ALL_TOGETHER ) {
$where[] = 'BackOrderFlag = ' . $shipment['BackOrderFlagCalc'];
}
$sql = 'UPDATE ' . $oi_table . '
SET PackageNum = ' . $group . '
WHERE ' . implode(' AND ', $where);
$this->Conn->Query($sql);
$group++;
}
$group = 1;
$this->Application->RemoveVar('LastShippings');
$this->Application->SetVar('ShipmentsExists', 1);
foreach ($shipments as $shipment) {
$block_params['package_num'] = $group;
$block_params['limit_types'] = $shipping_group_option == ORDER_GROUP_SHIPPMENTS_AUTO ? $limit_types : $limitations_cache[ $shipment['SplitShippingGroupCalc'] ];
$this->Application->SetVar('ItemShipmentsExists', 1); // also set from Order_PrintShippingTypes tag
switch ( $shipment['BackOrderFlagCalc'] ) {
case 0:
if ( $this->CartHasBackOrders() && $shipping_option == ORDER_SHIP_ALL_TOGETHER ) {
$block_params['shipment'] = $this->Application->Phrase('lu_all_available_backordered');
}
else {
$block_params['shipment'] = $this->Application->Phrase('lu_ship_all_available');;
}
break;
case 1:
$block_params['shipment'] = $this->Application->Phrase('lu_ship_all_backordered');;
break;
default:
$block_params['shipment'] = $this->Application->Phrase('lu_ship_backordered');
break;
}
$block_params['promo_weight_metric'] = $shipment['TotalWeightPromo'];
$block_params['promo_amount'] = $shipment['TotalAmountPromo'];
$block_params['promo_items'] = $shipment['TotalItemsPromo'];
$block_params['weight_metric'] = $shipment['TotalWeight'];
$block_params['weight'] = $shipment['TotalWeight'];
if ( $block_params['weight_metric'] == '' ) {
$block_params['weight'] = $this->Application->Phrase('lu_NotAvailable');
}
else {
$block_params['weight'] = $this->_formatWeight( $block_params['weight'] );
}
$block_params['items'] = $shipment['TotalItems'];
$amount = $this->ConvertCurrency($shipment['TotalAmount'], $this->GetISO( $params['currency'] ));
$amount = sprintf("%.2f", $amount);
$block_params['amount'] = $shipment['TotalAmount'];
$block_params['field_name'] = $this->InputName( Array('field' => 'ShippingTypeId') ) . '[' . $group . ']';
$parsed_block = $this->Application->ParseBlock($block_params);
if ( $this->Application->GetVar('ItemShipmentsExists') ) {
$o .= $parsed_block;
}
else {
$this->Application->SetVar('ShipmentsExists', 0);
if ( getArrayValue($params, 'no_shipments_render_as') ) {
$block_params['name'] = $params['no_shipments_render_as'];
return $this->Application->ParseBlock($block_params);
}
}
$group++;
}
if ( getArrayValue($params, 'table_header_render_as') ) {
$o = $this->Application->ParseBlock(Array ('name' => $params['table_header_render_as'])) . $o;
}
if ( getArrayValue($params, 'table_footer_render_as') ) {
$o .= $this->Application->ParseBlock(Array ('name' => $params['table_footer_render_as']));
}
return $o;
}
/**
* Checks, that all given address fields are valid
*
* @param Array $params
* @return bool
*/
function AddressValid($params)
{
$object = $this->getObject($params);
/* @var $object kDBItem */
$address_type = isset($params['type']) ? strtolower($params['type']) : 'shipping';
$address_type = ucfirst($address_type);
$check_fields = Array ('Address1', 'City', 'Zip', 'Country');
foreach ($check_fields as $check_field) {
if ( $object->GetDBField($address_type . $check_field) == '' ) {
return false;
}
}
return true;
}
function GetShippingLimitations($ord_id)
{
$limit_types = false;
$types_index = $split_shipments = $cat_limitations = Array ();
$sql = 'SELECT p.ShippingLimitation, p.ShippingMode, oi.ProductId AS ProductId
FROM ' . TABLE_PREFIX . 'Products p
LEFT JOIN ' . TABLE_PREFIX . 'OrderItems AS oi ON oi.ProductId = p.ProductId
WHERE oi.OrderId = ' . $ord_id . ' AND p.Type = ' . PRODUCT_TYPE_TANGIBLE;
$limitations = $this->Conn->Query($sql, 'ProductId');
// group products by shipping type range and calculate intersection of all types available for ALL products
// the intersection calculation is needed to determine if the order can be shipped with single type or not
if ($limitations) {
foreach ($limitations as $product_id => $row) {
// if shipping types are limited - get the types
$types = $row['ShippingLimitation'] != '' ? explode('|', substr($row['ShippingLimitation'], 1, -1)) : Array ('ANY');
// if shipping is NOT limited to selected types (default - so products with no limitations at all also counts)
if ($row['ShippingMode'] == PRODUCT_SHIPPING_MODE_ANY_AND_SELECTED) {
array_push($types, 'ANY'); // can be shipped with ANY (literally) type
$types = array_unique($types);
}
//adding product id to split_shipments group by types range
$i = array_search(serialize($types), $types_index);
if ($i === false) {
$types_index[] = serialize($types);
$i = count($types_index) - 1;
}
$split_shipments[$i]['Products'][] = $product_id;
$split_shipments[$i]['Types'] = serialize($types);
if ($limit_types === false) {
// it is false only when we process first item with limitations
$limit_types = $types; // initial scope
}
// this is to avoid ANY intersect CUST_1 = (), but allows ANY intersect CUST_1,ANY = (ANY)
if ( in_array('ANY', $limit_types) && !in_array('ANY', $types) ) {
array_splice($limit_types, array_search('ANY', $limit_types), 1, $types);
}
// this is to avoid CUST_1 intersect ANY = (), but allows CUST_1 intersect CUST_1,ANY = (ANY)
if ( !in_array('ANY', $limit_types) && in_array('ANY', $types) ) {
array_splice($types, array_search('ANY', $types), 1, $limit_types);
}
$limit_types = array_intersect($limit_types, $types);
}
$limit_types = count($limit_types) > 0 ? serialize(array_unique($limit_types)) : 'NONE';
}
return Array ($split_shipments, $limit_types);
}
function PaymentTypeForm($params)
{
$object = $this->getObject($params);
$payment_type_id = $object->GetDBField('PaymentType');
if($payment_type_id)
{
$this->Application->SetVar('pt_id', $payment_type_id);
$block_params['name'] = $this->SelectParam($params, $this->UsingCreditCard($params) ? 'cc_render_as,block_cc' : 'default_render_as,block_default' );
return $this->Application->ParseBlock($block_params);
}
return '';
}
/**
* Returns true in case if credit card was used as payment type for order
*
* @param Array $params
* @return bool
*/
function UsingCreditCard($params)
{
$object = $this->getObject($params);
$pt = $object->GetDBField('PaymentType');
if (!$pt) {
$pt = $this->Conn->GetOne('SELECT PaymentTypeId FROM '.TABLE_PREFIX.'PaymentTypes WHERE IsPrimary = 1');
$object->SetDBField('PaymentType', $pt);
}
- $pt_table = $this->Application->getUnitOption('pt','TableName');
+ $pt_table = $this->Application->getUnitConfig('pt')->getTableName();
$sql = 'SELECT GatewayId FROM %s WHERE PaymentTypeId = %s';
$gw_id = $this->Conn->GetOne( sprintf( $sql, $pt_table, $pt ) );
$sql = 'SELECT RequireCCFields FROM %s WHERE GatewayId = %s';
return $this->Conn->GetOne( sprintf($sql, TABLE_PREFIX.'Gateways', $gw_id) );
}
function PaymentTypeDescription($params)
{
return $this->Application->ProcessParsedTag('pt', 'Field', array_merge($params, Array(
'field' => 'Description'
)) );
}
function PaymentTypeInstructions($params)
{
return $this->Application->ProcessParsedTag('pt', 'Field', array_merge($params, Array(
'field' => 'Instructions'
)) );
}
function PrintMonthOptions($params)
{
$object = $this->getObject($params);
$date = explode('/', $object->GetDBField($params['date_field_name']));
if (!$date || sizeof($date) != 2) {
$date=array("", "");
}
$o = '';
$params['name'] = $params['block'];
for ($i = 1; $i <= 12; $i++) {
$month_str = str_pad($i, 2, "0", STR_PAD_LEFT);
if ($date[0] == $month_str) {
$params['selected'] = ' selected';
}else {
$params['selected'] = '';
}
$params['mm'] = $month_str;
$o .= $this->Application->ParseBlock($params);
}
return $o;
}
function PrintYearOptions($params)
{
$object = $this->getObject($params);
$value = $object->GetDBField( $params['field'] );
$block_params = $this->prepareTagParams($params);
$block_params['name'] = $this->SelectParam($params, 'render_as,block');
$o = '';
$this_year = adodb_date('y');
for($i = $this_year; $i <= $this_year + 10; $i++)
{
$year_str = str_pad($i, 2, '0', STR_PAD_LEFT);
$block_params['selected'] = ($value == $year_str) ? $params['selected'] : '';
$block_params['key'] = $year_str;
$block_params['option'] = $year_str;
$o .= $this->Application->ParseBlock($block_params);
}
return $o;
}
function PrintMyOrders($params)
{
}
/**
* Checks, that order data can be editied based on it's status
*
* @param Array $params
* @return bool
*/
function OrderEditable($params)
{
- $id_field = $this->Application->getUnitOption($this->Prefix, 'IDField');
- $table_name = $this->Application->getUnitOption($this->Prefix, 'TableName');
+ $config = $this->getUnitConfig();
+ $id_field = $config->getIDField();
+ $table_name = $config->getTableName();
if ($this->Application->IsTempMode($this->Prefix, $this->Special)) {
$table_name = $this->Application->GetTempName($table_name, 'prefix:' . $this->Prefix);
}
// use direct select here (not $this->getObject) because this tag is
// used even before "combined_header" block is used (on "orders_edit_items" template)
$sql = 'SELECT Status, PaymentType
FROM ' . $table_name . '
WHERE ' . $id_field . ' = ' . $this->Application->GetVar( $this->getPrefixSpecial() . '_id' );
$order_data = $this->Conn->GetRow($sql);
if (!$order_data) {
// new order adding, when even not in database
return true;
}
switch ($order_data['Status']) {
case ORDER_STATUS_INCOMPLETE:
$ret = true;
break;
case ORDER_STATUS_PENDING:
case ORDER_STATUS_BACKORDERS:
+ $config = $this->Application->getUnitConfig('pt');
+
$sql = 'SELECT PlacedOrdersEdit
- FROM ' . $this->Application->getUnitOption('pt', 'TableName') . '
- WHERE ' . $this->Application->getUnitOption('pt', 'IDField') . ' = ' . $order_data['PaymentType'];
+ FROM ' . $config->getTableName() . '
+ WHERE ' . $config->getIDField() . ' = ' . $order_data['PaymentType'];
$ret = $this->Conn->GetOne($sql);
break;
default:
$ret = false;
break;
}
return $ret;
}
function CheckoutSteps($params)
{
$steps = explode(',', $params['steps']);
foreach ($steps as $key => $item)
{
$templates[$key] = trim($item);
}
$templates = explode(',', $params['templates']);
foreach ($templates as $key => $item)
{
$templates[$key] = trim($item);
}
$total_steps = count($templates);
$t = $this->Application->GetVar('t');
$o = '';
$block_params = array();
$i = 0;
$passed_current = preg_match("/".preg_quote($templates[count($templates)-1], '/')."/", $t);
foreach ($steps as $step => $name)
{
if (preg_match("/".preg_quote($templates[$step], '/')."/", $t)) {
$block_params['name'] = $this->SelectParam($params, 'current_step_render_as,block_current_step');
$passed_current = true;
}
else {
$block_params['name'] = $passed_current ? $this->SelectParam($params, 'render_as,block') : $this->SelectParam($params, 'passed_step_render_as,block_passed_step');
}
$block_params['title'] = $this->Application->Phrase($name);
$block_params['template'] = $templates[$i];
$block_params['template_link'] = $this->Application->HREF($templates[$step], '', Array('pass'=>'m'));
$block_params['next_step_template'] = isset($templates[$i + 1]) ? $templates[$i + 1] : '';
$block_params['number'] = $i + 1;
$i++;
$o.= $this->Application->ParseBlock($block_params, 1);
}
return $o;
}
function ShowOrder($params)
{
$order_params = $this->prepareTagParams($params);
// $order_params['Special'] = 'myorders';
// $order_params['PrefixSpecial'] = 'ord.myorders';
$order_params['name'] = $this->SelectParam($order_params, 'render_as,block');
// $this->Application->SetVar('ord.myorders_id', $this->Application->GetVar('ord_id'));
$object = $this->getObject($params);
if (!$object->GetDBField('OrderId')) {
return;
}
return $this->Application->ParseBlock($order_params);
}
function BuildListSpecial($params)
{
if ($this->Special != '') {
return $this->Special;
}
$list_unique_key = $this->getUniqueListKey($params);
if ($list_unique_key == '') {
return parent::BuildListSpecial($params);
}
return crc32($list_unique_key);
}
function ListOrders($params)
{
$o = '';
$params['render_as'] = $params['item_render_as'];
$o_orders = $this->PrintList2($params);
if ($o_orders) {
$orders_params = array('name' => $params['header_render_as']);
$o = $this->Application->ParseBlock($orders_params);
$o .= $o_orders;
} else {
$orders_params = array('name' => $params['empty_myorders_render_as']);
$o = $this->Application->ParseBlock($orders_params);
}
return $o;
}
function HasRecentOrders($params)
{
$per_page = $this->SelectParam($params, 'per_page,max_items');
if ($per_page !== false) {
$params['per_page'] = $per_page;
}
return (int)$this->TotalRecords($params) > 0 ? 1 : 0;
}
function ListOrderItems($params)
{
$prefix_special = rtrim('orditems.'.$this->Special, '.');
return $this->Application->ProcessParsedTag($prefix_special, 'PrintList', array_merge($params, Array(
'per_page' => -1
)) );
}
function OrdersLink(){
$params['pass']='m,ord';
$main_processor = $this->Application->recallObject('m_TagProcessor');
return $main_processor->Link($params);
}
function PrintAddresses($params)
{
$object = $this->getObject($params);
$address_list = $this->Application->recallObject('addr','addr_List', Array('per_page'=>-1, 'skip_counting'=>true) );
$address_list->Query();
$address_id = $this->Application->GetVar($params['type'].'_address_id');
if (!$address_id) {
$sql = 'SELECT '.$address_list->IDField.'
FROM '.$address_list->TableName.'
WHERE PortalUserId = '.$object->GetDBField('PortalUserId').' AND LastUsedAs'.ucfirst($params['type']).' = 1';
$address_id = (int)$this->Conn->GetOne($sql);
}
$ret = '';
$block_params = $this->prepareTagParams($params);
$block_params['name'] = $this->SelectParam($params, 'render_as,block');
$address_list->GoFirst();
while (!$address_list->EOL()) {
$selected = ($address_list->GetID() == $address_id);
if ($selected && $address_list->GetDBField('IsProfileAddress')) {
$this->Application->SetVar($this->Prefix.'_IsProfileAddress', true);
}
$block_params['key'] = $address_list->GetID();
$block_params['value'] = $address_list->GetDBField('ShortAddress');
$block_params['selected'] = $selected ? ' selected="selected"' : '';
$ret .= $this->Application->ParseBlock($block_params, 1);
$address_list->GoNext();
}
return $ret;
}
function PrefillRegistrationFields($params)
{
if ( $this->Application->GetVar('fields_prefilled') ) {
return false;
}
if ( isset($params['user_prefix']) ) {
$user = $this->Application->recallObject($params['user_prefix']);
/* @var $user kDBItem */
}
else {
$user = $this->Application->recallObject('u', null, Array ('skip_autoload' => true));
/* @var $user kDBItem */
}
$order = $this->Application->recallObject($this->Prefix . '.last');
/* @var $order OrdersItem */
$order_helper = $this->Application->recallObject('OrderHelper');
/* @var $order_helper OrderHelper */
$user_fields = $order_helper->getUserFields($order, $params['type'] == 'billing' ? 'Billing' : 'Shipping');
foreach ($user_fields as $field => $value) {
if ( !$user->GetDBField($field) ) {
$user->SetDBField($field, $value);
}
}
$cs_helper = $this->Application->recallObject('CountryStatesHelper');
/* @var $cs_helper kCountryStatesHelper */
$cs_helper->PopulateStates(new kEvent('u:OnBuild'), 'State', 'Country');
}
function UserLink($params)
{
$object = $this->getObject($params);
$user_id = $object->GetDBField( $params['user_field'] );
if ($user_id) {
$url_params = Array (
'm_opener' => 'd',
'u_mode' => 't',
'u_event' => 'OnEdit',
'u_id' => $user_id,
'pass' => 'all,u',
'no_pass_through' => 1,
);
return $this->Application->HREF($params['edit_template'], '', $url_params);
}
}
function UserFound($params)
{
$virtual_users = Array(USER_ROOT, USER_GUEST, 0);
$object = $this->getObject($params);
return !in_array( $object->GetDBField( $params['user_field'] ) , $virtual_users );
}
/**
* Returns a link for editing order
*
* @param Array $params
* @return string
*/
function OrderLink($params)
{
$object = $this->getObject($params);
$url_params = Array (
'm_opener' => 'd',
$this->Prefix.'_mode' => 't',
$this->Prefix.'_event' => 'OnEdit',
$this->Prefix.'_id' => $object->GetID(),
'pass' => 'all,'.$this->Prefix,
'no_pass_through' => 1,
);
return $this->Application->HREF($params['edit_template'], '', $url_params);
}
function HasOriginalAmount($params)
{
$object = $this->getObject($params);
$original_amount = $object->GetDBField('OriginalAmount');
return $original_amount && ($original_amount != $object->GetDBField('TotalAmount') );
}
/**
* Returns true, when order has tangible items
*
* @param Array $params
* @return bool
*
* @todo This is copy from OrdersItem::HasTangibleItems. Copy to helper (and create it) and use here.
*/
function OrderHasTangibleItems($params)
{
$object = $this->getObject($params);
if ($object->GetID() == FAKE_ORDER_ID) {
return false;
}
$sql = 'SELECT COUNT(*)
FROM '.TABLE_PREFIX.'OrderItems orditems
LEFT JOIN '.TABLE_PREFIX.'Products p ON p.ProductId = orditems.ProductId
WHERE (orditems.OrderId = '.$object->GetID().') AND (p.Type = '.PRODUCT_TYPE_TANGIBLE.')';
return $this->Conn->GetOne($sql) ? true : false;
}
function ShipmentsExists($params)
{
return $this->Application->GetVar('ShipmentsExists') ? 1 : 0;
}
function Field($params)
{
$value = parent::Field($params);
$field = $this->SelectParam($params,'name,field');
if( ($field == 'PaymentAccount') && getArrayValue($params,'masked') )
{
$value = str_repeat('X',12).substr($value,-4);
}
return $value;
}
function CartHasError($params)
{
return $this->Application->RecallVar('checkout_errors');
}
function CheckoutError($params)
{
$errors = $this->Application->RecallVar('checkout_errors');
if ( !$errors ) {
return '';
}
$this->Application->RemoveVar('checkout_errors');
$errors = unserialize($errors);
if ( isset($errors[OrderCheckoutErrorType::COUPON]) ) {
$mapping = Array (
OrderCheckoutError::COUPON_APPLIED => 'coupon_applied',
OrderCheckoutError::COUPON_REMOVED => 'code_removed',
OrderCheckoutError::COUPON_REMOVED_AUTOMATICALLY => 'code_removed_automatically',
OrderCheckoutError::COUPON_CODE_INVALID => 'invalid_code',
OrderCheckoutError::COUPON_CODE_EXPIRED => 'code_expired',
);
$error_phrase = $mapping[ $errors[OrderCheckoutErrorType::COUPON] ];
}
elseif ( isset($errors[OrderCheckoutErrorType::GIFT_CERTIFICATE]) ) {
$mapping = Array (
OrderCheckoutError::GC_APPLIED => 'gift_certificate_applied',
OrderCheckoutError::GC_REMOVED => 'gc_code_removed',
OrderCheckoutError::GC_REMOVED_AUTOMATICALLY => 'gc_code_removed_automatically',
OrderCheckoutError::GC_CODE_INVALID => 'invalid_gc_code',
OrderCheckoutError::GC_CODE_EXPIRED => 'gc_code_expired',
);
$error_phrase = $mapping[ $errors[OrderCheckoutErrorType::GIFT_CERTIFICATE] ];
}
else {
$mapping = Array (
OrderCheckoutError::QTY_UNAVAILABLE => 'qty_unavailable',
OrderCheckoutError::QTY_OUT_OF_STOCK => 'outofstock',
OrderCheckoutError::QTY_CHANGED_TO_MINIMAL => 'min_qty',
);
foreach ($errors as $error_type => $error_code) {
if ( isset($mapping[$error_code]) ) {
$error_phrase = $mapping[$error_code];
break;
}
}
if ( !isset($error_phrase) ) {
$error_phrase = 'state_changed'; // 'changed_after_login'
}
}
return $this->Application->Phrase( $params[$error_phrase] );
}
/**
* Returns checkout errors in JSON format
*
* @param Array $params
* @return string
*/
function PrintOrderInfo($params)
{
$order_helper = $this->Application->recallObject('OrderHelper');
/* @var $order_helper OrderHelper */
$object = $this->getObject($params);
/* @var $object kDBItem */
$currency = isset($params['currency']) ? $params['currency'] : 'selected';
return json_encode( $order_helper->getOrderInfo($object, $currency) );
}
/**
* Returns currency mark (%s is $amount placemark)
*
* @param Array $params
* @return string
*/
function CurrencyMask($params)
{
$iso = $this->GetISO( $params['currency'] );
return $this->AddCurrencySymbol('%s', $iso);
}
function CheckoutErrorNew($params)
{
$errors = $this->Application->RecallVar('checkout_errors');
if ( !$errors ) {
return '';
}
// $this->Application->RemoveVar('checkout_errors');
$errors = unserialize($errors);
$reflection = new ReflectionClass('OrderCheckoutErrorType');
$error_types = $reflection->getConstants();
$reflection = new ReflectionClass('OrderCheckoutError');
$error_codes = $reflection->getConstants();
$ret = Array ();
foreach ($errors as $error_type => $error_code) {
$error_type = explode(':', $error_type);
$error_explained = '<strong>' . array_search($error_type[0], $error_types) . '</strong>';
if ( $error_type[0] == OrderCheckoutErrorType::PRODUCT ) {
$error_explained .= ' (ProductId = <strong>' . $error_type[1] . '</strong>; OptionsSalt: <strong>' . $error_type[2] . '</strong>; BackOrderFlag: ' . $error_type[3] . '; Field: <strong>' . $error_type[4] . '</strong>)';
}
$error_explained .= ' - <strong>' . array_search($error_code, $error_codes) . '</strong>';
$ret[] = $error_explained;
}
return implode('<br/>', $ret);
}
function GetFormAction($params)
{
$object = $this->getObject($params);
/* @var $object OrdersItem */
$gw_data = $object->getGatewayData( isset($params['payment_type_id']) ? $params['payment_type_id'] : null );
$this->Application->registerClass( $gw_data['ClassName'], GW_CLASS_PATH.'/'.$gw_data['ClassFile'] );
$gateway_object = $this->Application->recallObject( $gw_data['ClassName'] );
/* @var $gateway_object kGWBase */
return $gateway_object->getFormAction($gw_data['gw_params']);
}
function GetFormHiddenFields($params)
{
$object = $this->getObject($params);
/* @var $object OrdersItem */
$gw_data = $object->getGatewayData( isset($params['payment_type_id']) ? $params['payment_type_id'] : null );
$this->Application->registerClass( $gw_data['ClassName'], GW_CLASS_PATH.'/'.$gw_data['ClassFile'] );
$gateway_object = $this->Application->recallObject( $gw_data['ClassName'] );
/* @var $gateway_object kGWBase */
$tpl = '<input type="hidden" name="%s" value="%s" />'."\n";
$hidden_fields = $gateway_object->getHiddenFields($object->GetFieldValues(), $params, $gw_data['gw_params']);
if ( !is_array($hidden_fields) ) {
return $hidden_fields;
}
$ret = '';
foreach ($hidden_fields as $hidden_name => $hidden_value) {
$ret .= sprintf($tpl, $hidden_name, $hidden_value);
}
return $ret;
}
function NeedsPlaceButton($params)
{
$object = $this->getObject($params);
/* @var $object OrdersItem */
$gw_data = $object->getGatewayData( isset($params['payment_type_id']) ? $params['payment_type_id'] : null );
$this->Application->registerClass( $gw_data['ClassName'], GW_CLASS_PATH.'/'.$gw_data['ClassFile'] );
$gateway_object = $this->Application->recallObject( $gw_data['ClassName'] );
/* @var $gateway_object kGWBase */
return $gateway_object->NeedPlaceButton($object->GetFieldValues(), $params, $gw_data['gw_params']);
}
function HasGatewayError($params)
{
return $this->Application->RecallVar('gw_error');
}
function ShowGatewayError($params)
{
$ret = $this->Application->RecallVar('gw_error');
$this->Application->RemoveVar('gw_error');
return $ret;
}
function ShippingType($params)
{
$object = $this->getObject($params);
/* @var $object kDBItem */
$shipping_info = unserialize($object->GetDBField('ShippingInfo'));
if ( count($shipping_info) > 1 ) {
return $this->Application->Phrase('lu_MultipleShippingTypes');
}
if ( $shipping_info ) {
$shipping_info = array_shift($shipping_info);
return $shipping_info['ShippingName'];
}
return '';
}
function DiscountHelpLink($params)
{
$params['pass'] = 'all,orditems';
$params['m_cat_id'] = 0;
$m_tag_processor = $this->Application->recallObject('m_TagProcessor');
return $m_tag_processor->Link($params);
}
function DiscountField($params)
{
$orditems = $this->Application->recallObject( 'orditems' );
$item_data = $orditems->GetDBField('ItemData');
if(!$item_data) return '';
$item_data = unserialize($item_data);
$discount_prefix = ($item_data['DiscountType'] == 'coupon') ? 'coup' : 'd';
$discount = $this->Application->recallObject($discount_prefix, null, Array('skip_autoload' => true));
if(!$discount->isLoaded())
{
$discount->Load($item_data['DiscountId']);
}
return $discount->GetField( $this->SelectParam($params, 'field,name') );
}
function HasDiscount($params)
{
$object = $this->getObject($params);
return (float)$object->GetDBField('DiscountTotal') ? 1 : 0;
}
/**
* Allows to check if required product types are present in order
*
* @param Array $params
*/
function HasProductType($params)
{
$product_types = Array('tangible' => 1, 'subscription' => 2, 'service' => 3, 'downloadable' => 4, 'package' => 5, 'gift' => 6);
$object = $this->getObject($params);
$sql = 'SELECT COUNT(*)
FROM '.TABLE_PREFIX.'OrderItems oi
LEFT JOIN '.TABLE_PREFIX.'Products p ON p.ProductId = oi.ProductId
WHERE (oi.OrderId = '.$object->GetID().') AND (p.Type = '.$product_types[ $params['type'] ].')';
return $this->Conn->GetOne($sql);
}
function PrintSerializedFields($params)
{
$object = $this->getObject($params);
$field = $this->SelectParam($params, 'field');
if (!$field) $field = $this->Application->GetVar('field');
$data = unserialize($object->GetDBField($field));
$o = '';
$block_params['name'] = $params['render_as'];
foreach ($data as $field => $value) {
$block_params['field'] = $field;
$block_params['value'] = $value;
$o .= $this->Application->ParseBlock($block_params);
}
return $o;
}
/**
* Prints order totals
*
* @param Array $params
* @return string
* @access protected
*/
protected function PrintTotals($params)
{
$object = $this->getObject($params);
/* @var $object OrdersItem */
if ( isset($params['element_order']) ) {
// TODO: implement
}
else {
// default element order
$element_order = Array (
'products' => 1, 'return' => 4, 'sub_total' => 5, 'discount' => 6,
'vat' => 7, 'shipping' => 8, 'processing' => 9,
);
// show shipping & processing costs before tax, when they are taxable
if ( $object->GetDBField('ShippingTaxable') ) {
$element_order['shipping'] = 2;
}
if ( $object->GetDBField('ProcessingTaxable') ) {
$element_order['processing'] = 3;
}
}
$totals = Array ();
if ( abs($object->GetDBField('SubTotal') - $object->GetDBField('AmountWithoutVAT')) > 0.01 ) {
$totals[] = 'products';
}
if ( $this->OrderHasTangibleItems($params) ) {
$totals[] = 'shipping';
}
if ( $object->GetDBField('ProcessingFee') > 0 ) {
$totals[] = 'processing';
}
if ( $object->GetDBField('ReturnTotal') > 0 ) {
$totals[] = 'return';
}
if ( $this->HasDiscount($params) ) {
$totals[] = 'discount';
}
$totals[] = 'sub_total';
if ( $object->GetDBField('VAT') > 0 ) {
$totals[] = 'vat';
}
$o = '';
asort($element_order, SORT_NUMERIC);
$block_params = $this->prepareTagParams($params);
foreach ($element_order as $type => $order) {
$element = getArrayValue($params, $type . '_render_as');
if ( !in_array($type, $totals) || !$element ) {
continue;
}
$block_params['name'] = $element;
$o .= $this->Application->ParseBlock($block_params);
}
return $o;
}
function ShowDefaultAddress($params)
{
$address_type = ucfirst($params['type']);
if ($this->Application->GetVar('check_'.strtolower($address_type).'_address')) {
// form type doesn't match check type, e.g. shipping check on billing form
return '';
}
// for required field highlighting on form when no submit made
$this->Application->SetVar('check_'.strtolower($address_type).'_address', 'true');
/*if ((strtolower($address_type) == 'billing') && $this->UsingCreditCard($params)) {
$this->Application->SetVar('check_credit_card', 'true');
}*/
$this->Application->HandleEvent(new kEvent('ord:SetStepRequiredFields'));
$user_id = $this->Application->RecallVar('user_id');
$sql = 'SELECT AddressId
FROM '.TABLE_PREFIX.'Addresses
WHERE PortalUserId = '.$user_id.' AND LastUsedAs'.$address_type.' = 1';
$address_id = $this->Conn->GetOne($sql);
if (!$address_id) {
return '';
}
$addr_list = $this->Application->recallObject('addr', 'addr_List', Array('per_page'=>-1, 'skip_counting'=>true) );
$addr_list->Query();
$object = $this->getObject();
if (!$addr_list->CheckAddress($object->GetFieldValues(), $address_type)) {
$addr_list->CopyAddress($address_id, $address_type);
}
}
function IsProfileAddress($params)
{
$object = $this->getObject($params);
$address_type = ucfirst($params['type']);
return $object->IsProfileAddress($address_type);
}
function HasPayPalSubscription($params)
{
$object = $this->getObject($params);
$sql = 'SELECT COUNT(*)
FROM '.TABLE_PREFIX.'OrderItems oi
LEFT JOIN '.TABLE_PREFIX.'Products p ON p.ProductId = oi.ProductId
WHERE (oi.OrderId = '.$object->GetID().') AND (p.PayPalRecurring = 1)';
return $this->Conn->GetOne($sql);
}
function GetPayPalSubscriptionForm($params)
{
$object = $this->getObject($params);
$gw_data = $object->getGatewayData($params['payment_type_id']);
$this->Application->registerClass( $gw_data['ClassName'], GW_CLASS_PATH.'/'.$gw_data['ClassFile'] );
$gateway_object = $this->Application->recallObject( $gw_data['ClassName'] );
$sql = 'SELECT oi.*
FROM '.TABLE_PREFIX.'OrderItems oi
LEFT JOIN '.TABLE_PREFIX.'Products p ON p.ProductId = oi.ProductId
WHERE (oi.OrderId = '.$object->GetID().') AND (p.PayPalRecurring = 1)';
$order_item = $this->Conn->GetRow($sql);
$order_item_data = unserialize($order_item['ItemData']);
$cycle = ceil($order_item_data['Duration'] / 86400);
$cycle_units = 'D';
$item_data = $object->GetFieldValues();
$item_data['item_name'] = $order_item['ProductName'];
$item_data['item_number'] = $order_item['OrderItemId'];
$item_data['custom'] = $order_item['OrderId'];
$item_data['a1'] = '';
$item_data['p1'] = '';
$item_data['t1'] = '';
$item_data['a2'] = '';
$item_data['p2'] = '';
$item_data['t2'] = '';
$item_data['a3'] = $order_item['Price']; //rate
$item_data['p3'] = $cycle; //cycle
$item_data['t3'] = $cycle_units; //cycle units D (days), W (weeks), M (months), Y (years)
$item_data['src'] = '1'; // Recurring payments. If set to 1, the payment will recur unless your customer cancels the subscription before the end of the billing cycle.
$item_data['sra'] = '1'; // Reattempt on failure. If set to 1, and the payment fails, the payment will be reattempted two more times. After the third failure, the subscription will be cancelled.
$item_data['srt'] = ''; // Recurring Times. This is the number of payments which will occur at the regular rate.
$hidden_fields = $gateway_object->getSubscriptionFields($item_data, $params, $gw_data['gw_params']);
$ret = '';
if (!is_array($hidden_fields)) {
return $hidden_fields;
}
$tpl = '<input type="hidden" name="%s" value="%s" />'."\n";
foreach($hidden_fields as $hidden_name => $hidden_value)
{
$ret .= sprintf($tpl, $hidden_name, $hidden_value);
}
return $ret;
}
function UserHasPendingOrders($params)
{
- $sql = 'SELECT OrderId FROM '.$this->Application->getUnitOption($this->Prefix, 'TableName').'
- WHERE PortalUserId = '.$this->Application->RecallVar('user_id').'
- AND Status = '.ORDER_STATUS_PENDING;
+ $user_id = $this->Application->RecallVar('user_id');
+
+ $sql = 'SELECT OrderId
+ FROM '.$this->getUnitConfig()->getTableName().'
+ WHERE PortalUserId = '. $user_id .' AND Status = '.ORDER_STATUS_PENDING;
+
return $this->Conn->GetOne($sql) ? 1 : 0;
}
function AllowAddAddress($params)
{
$user = $this->Application->recallObject('u.current');
if ($user->GetDBField('cust_shipping_addr_block')) return false;
$address_list = $this->Application->recallObject('addr','addr_List', Array('per_page'=>-1, 'skip_counting'=>true) );
$address_list->Query();
$max = $this->Application->ConfigValue('MaxAddresses');
return $max <= 0 ? true : $address_list->GetRecordsCount() < $max;
}
/**
* Creates link for removing coupon or gift certificate
*
* @param Array $params
* @return string
*/
function RemoveCouponLink($params)
{
$type = strtolower($params['type']);
$url_params = Array (
'pass' => 'm,ord',
'ord_event' => ($type == 'coupon') ? 'OnRemoveCoupon' : 'OnRemoveGiftCertificate',
'm_cat_id' => 0,
);
return $this->Application->HREF('', '', $url_params);
}
/**
* Calculates total weight of items in shopping cart
*
* @param Array $params
* @return float
*/
function TotalOrderWeight($params)
{
$object = $this->getObject($params);
/* @var $object kDBItem */
$sql = 'SELECT SUM( IF(oi.Weight IS NULL, 0, oi.Weight * oi.Quantity) )
FROM '.TABLE_PREFIX.'OrderItems oi
WHERE oi.OrderId = '.$object->GetID();
$total_weight = $this->Conn->GetOne($sql);
if ($total_weight == '') {
// zero weight -> return text about it
return $this->Application->Phrase('lu_NotAvailable');
}
return $this->_formatWeight($total_weight);
}
function _formatWeight($weight)
{
$regional = $this->Application->recallObject('lang.current');
/* @var $regional kDBItem */
switch ( $regional->GetDBField('UnitSystem') ) {
case 1:
// metric system -> add kg sign
$weight .= ' ' . $this->Application->Phrase('lu_kg');
break;
case 2:
// uk system -> convert to pounds
list ($pounds, $ounces) = kUtil::Kg2Pounds($weight);
$weight = $pounds . ' ' . $this->Application->Phrase('lu_pounds') . ' ' . $ounces . ' ' . $this->Application->Phrase('lu_ounces');
break;
}
return $weight;
}
function InitCatalogTab($params)
{
$tab_params['mode'] = $this->Application->GetVar('tm'); // single/multi selection possible
$tab_params['special'] = $this->Application->GetVar('ts'); // use special for this tab
$tab_params['dependant'] = $this->Application->GetVar('td'); // is grid dependant on categories grid
// set default params (same as in catalog)
if ($tab_params['mode'] === false) $tab_params['mode'] = 'multi';
if ($tab_params['special'] === false) $tab_params['special'] = '';
if ($tab_params['dependant'] === false) $tab_params['dependant'] = 'yes';
// pass params to block with tab content
$params['name'] = $params['render_as'];
$params['prefix'] = trim($this->Prefix.'.'.($tab_params['special'] ? $tab_params['special'] : $this->Special), '.');
$params['cat_prefix'] = trim('c.'.($tab_params['special'] ? $tab_params['special'] : $this->Special), '.');
$params['tab_mode'] = $tab_params['mode'];
$params['grid_name'] = ($tab_params['mode'] == 'multi') ? $params['default_grid'] : $params['radio_grid'];
$params['tab_dependant'] = $tab_params['dependant'];
$params['show_category'] = $tab_params['special'] == 'showall' ? 1 : 0; // this is advanced view -> show category name
// use $pass_params to be able to pass 'tab_init' parameter from m_ModuleInclude tag
return $this->Application->ParseBlock($params, 1);
}
/**
* Checks if required payment method is available
*
* @param Array $params
* @return bool
*/
function HasPaymentGateway($params)
{
static $payment_types = Array ();
$gw_name = $params['name'];
if (!array_key_exists($gw_name, $payment_types)) {
$sql = 'SELECT pt.PaymentTypeId, pt.PortalGroups
FROM '.TABLE_PREFIX.'PaymentTypes pt
LEFT JOIN '.TABLE_PREFIX.'Gateways g ON pt.GatewayId = g.GatewayId
WHERE (g.Name = '.$this->Conn->qstr($params['name']).') AND (pt.Status = '.STATUS_ACTIVE.')';
$payment_types[$gw_name] = $this->Conn->GetRow($sql);
}
if (!$payment_types[$gw_name]) {
return false;
}
$pt_groups = explode(',', substr($payment_types[$gw_name]['PortalGroups'], 1, -1));
$user_groups = explode(',', $this->Application->RecallVar('UserGroups'));
return array_intersect($user_groups, $pt_groups) ? $payment_types[$gw_name]['PaymentTypeId'] : false;
}
function DisplayPaymentGateway($params)
{
$payment_type_id = $this->HasPaymentGateway($params);
if (!$payment_type_id) {
return '';
}
$object = $this->getObject($params);
/* @var $object OrdersItem */
$gw_data = $object->getGatewayData($payment_type_id);
$block_params = $gw_data['gw_params'];
$block_params['name'] = $params['render_as'];
$block_params['payment_type_id'] = $payment_type_id;
return $this->Application->ParseBlock($block_params);
}
/**
* Checks, that USPS returned valid label
*
* @param Array $params
* @return bool
*/
function USPSLabelFound($params)
{
$object = $this->getObject($params);
/* @var $object kDBItem */
$full_path = USPS_LABEL_FOLDER . $object->GetDBField( $params['field'] ) . '.pdf';
return file_exists($full_path) && is_file($full_path);
}
/**
* Prints SQE errors from session
*
* @param Array $params
* @return string
*/
function PrintSQEErrors($params)
{
$sqe_errors = $this->Application->RecallVar('sqe_errors');
if (!$sqe_errors) {
return '';
}
$o = '';
$block_params = $this->prepareTagParams($params);
$block_params['name'] = $params['render_as'];
$sqe_errors = unserialize($sqe_errors);
foreach ($sqe_errors as $order_number => $error_description) {
$block_params['order_number'] = $order_number;
$block_params['error_description'] = $error_description;
$o .= $this->Application->ParseBlock($block_params);
}
$this->Application->RemoveVar('sqe_errors');
return $o;
}
/**
* Creates a continue shopping link
*
* @param Array $params
* @return string
* @access protected
*/
protected function ContinueShoppingLink($params)
{
$order_helper = $this->Application->recallObject('OrderHelper');
/* @var $order_helper OrderHelper */
if ( isset($params['template']) ) {
$template = $params['template'];
unset($params['template']);
}
else {
$template = '';
}
return $this->Application->HREF($order_helper->getContinueShoppingTemplate($template), '', $params);
}
/**
* Checks that billing address and shipping address are the same
*
* @param Array $params
* @return string
* @access protected
*/
protected function AddressesTheSame($params)
{
$object = $this->getObject($params);
/* @var $object kDBItem */
$address_fields = Array ('To', 'Company', 'Address1', 'Address2', 'City', 'Country', 'State', 'Zip');
foreach ($address_fields as $address_field) {
if ( $object->GetDBField('Shipping' . $address_field) != $object->GetDBField('Billing' . $address_field) ) {
return false;
}
}
return true;
}
}
\ No newline at end of file
Index: branches/5.3.x/units/currencies/currencies_tag_processor.php
===================================================================
--- branches/5.3.x/units/currencies/currencies_tag_processor.php (revision 15694)
+++ branches/5.3.x/units/currencies/currencies_tag_processor.php (revision 15695)
@@ -1,99 +1,105 @@
<?php
/**
* @version $Id$
* @package In-Commerce
* @copyright Copyright (C) 1997 - 2009 Intechnic. All rights reserved.
* @license Commercial License
* This software 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
* See http://www.in-portal.org/commercial-license for copyright notices and details.
*/
defined('FULL_PATH') or die('restricted access!');
class CurrenciesTagProcessor extends kDBTagProcessor {
function DisableUnusedWarning($params)
{
- $saved_ids = $this->Application->RecallVar('saved_curr_ids'); // when saving currency(-ies)
- $check_all = $this->Application->RecallVar('check_unused_currencies'); // when saving payment type
$ret = '';
- if($saved_ids || $check_all)
- {
- $sql = 'SELECT DISTINCT CurrencyId FROM '.$this->Application->getUnitOption('ptc', 'TableName');
+ $saved_ids = $this->Application->RecallVar('saved_curr_ids'); // when saving currency(-ies)
+ $check_all = $this->Application->RecallVar('check_unused_currencies'); // when saving payment type
+
+ $config = $this->getUnitConfig();
+
+ if ( $saved_ids || $check_all ) {
+ $sql = 'SELECT DISTINCT CurrencyId
+ FROM ' . $this->Application->getUnitConfig('ptc')->getTableName();
$used_ids = $this->Conn->GetCol($sql);
- if($check_all)
- {
- $sql = 'SELECT DISTINCT CurrencyId FROM '.$this->Application->getUnitOption('curr', 'TableName');
+
+ if ( $check_all ) {
+ $sql = 'SELECT DISTINCT CurrencyId
+ FROM ' . $config->getTableName();
$all_ids = $this->Conn->GetCol($sql);
- $unused_ids = implode(',', array_diff($all_ids, $used_ids) );
+
+ $unused_ids = implode(',', array_diff($all_ids, $used_ids));
$this->Application->RemoveVar('check_unused_currencies');
}
- else
- {
+ else {
$saved_ids = explode(',', $saved_ids);
- $unused_ids = implode(',', array_diff($saved_ids, $used_ids) );
+ $unused_ids = implode(',', array_diff($saved_ids, $used_ids));
$this->Application->RemoveVar('saved_curr_ids');
}
if ( $unused_ids ) {
$this->Application->SetVar('unused_ids', $unused_ids);
+
$sql = 'SELECT ISO
- FROM '.$this->Application->getUnitOption($this->Prefix, 'TableName').'
- WHERE CurrencyId IN('.$unused_ids.') AND Status = 1';
+ FROM ' . $config->getTableName() . '
+ WHERE CurrencyId IN(' . $unused_ids . ') AND Status = 1';
$params['unused_iso'] = implode(', ', $this->Conn->GetCol($sql));
if ( $params['unused_iso'] ) {
$params['unused_ids'] = $unused_ids;
$params['name'] = $params['block'];
$ret = $this->Application->ParseBlock($params);
}
}
}
+
return $ret;
}
function ListCurrencies($params)
{
return $this->PrintList2($params);
}
function CurrencyLink($params)
{
$object = $this->getObject($params);
/* @var $object kDBItem */
$params['pass'] = 'm,curr';
$params['curr_event'] = 'OnChangeCurrency';
$params['curr_iso'] = $object->GetDBField('ISO');
return $this->Application->ProcessParsedTag('m', 'Link', $params);
}
function SelectedCurrency($params)
{
$object = $this->Application->recallObject($this->getPrefixSpecial());
return $object->GetDBField('ISO') == $this->Application->RecallVar('curr_iso');
}
function PrimaryCurrencyISO($params)
{
$sql = 'SELECT ISO
- FROM ' . $this->Application->getUnitOption($this->Prefix, 'TableName') . '
+ FROM ' . $this->getUnitConfig()->getTableName() . '
WHERE IsPrimary = 1';
return $this->Conn->GetOne($sql);
}
function PrimaryCurrencyName($params)
{
$sql = 'SELECT Name
- FROM ' . $this->Application->getUnitOption($this->Prefix, 'TableName') . '
+ FROM ' . $this->getUnitConfig()->getTableName() . '
WHERE IsPrimary = 1';
return $this->Application->Phrase( $this->Conn->GetOne($sql) );
}
}
\ No newline at end of file
Index: branches/5.3.x/units/currencies/currencies_event_handler.php
===================================================================
--- branches/5.3.x/units/currencies/currencies_event_handler.php (revision 15694)
+++ branches/5.3.x/units/currencies/currencies_event_handler.php (revision 15695)
@@ -1,300 +1,300 @@
<?php
/**
* @version $Id$
* @package In-Commerce
* @copyright Copyright (C) 1997 - 2009 Intechnic. All rights reserved.
* @license Commercial License
* This software 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
* See http://www.in-portal.org/commercial-license for copyright notices and details.
*/
defined('FULL_PATH') or die('restricted access!');
class CurrenciesEventHandler extends kDBEventHandler {
/**
* Allows to override standard permission mapping
*
* @return void
* @access protected
* @see kEventHandler::$permMapping
*/
protected function mapPermissions()
{
parent::mapPermissions();
$permissions = Array (
// admin
'OnUpdateRate' => Array ('self' => 'add|edit'),
'OnUpdateRates' => Array ('self' => 'advanced:update_rate|add|edit'),
'OnDisableUnused' => Array ('self' => 'edit'),
// front
'OnChangeCurrency' => Array ('self' => true),
'OnItemBuild' => Array ('self' => true),
);
$this->permMapping = array_merge($this->permMapping, $permissions);
}
/**
* Returns ID of current item to be edited
* by checking ID passed in get/post as prefix_id
* or by looking at first from selected ids, stored.
* Returned id is also stored in Session in case
* it was explicitly passed as get/post
*
* @param kEvent $event
* @return int
* @access public
*/
public function getPassedID(kEvent $event)
{
if ( $event->Special == 'current' ) {
return Array ('ISO' => $this->Application->RecallVar('curr_iso'));
}
return parent::getPassedID($event);
}
/**
* Enter description here...
*
* @param kEvent $event
*/
function OnSetPrimary($event)
{
if ($this->Application->CheckPermission('SYSTEM_ACCESS.READONLY', 1)) {
$event->status = kEvent::erFAIL;
return;
}
$object = $event->getObject();
/* @var $object kDBItem */
$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);
$object = $event->getObject();
/* @var $object kDBItem */
if ( $object->GetDBField('IsPrimary') && $object->Validate() ) {
- $sql = 'UPDATE ' . $this->Application->getUnitOption($this->Prefix, 'TableName') . '
+ $sql = 'UPDATE ' . $event->getUnitConfig()->getTableName() . '
SET IsPrimary = 0
WHERE CurrencyId <> ' . $object->GetDBField('CurrencyId');
$this->Conn->Query($sql);
$object->SetDBField('Status', 1);
}
$object->SetDBField('Modified_date', adodb_mktime());
$object->SetDBField('Modified_time', adodb_mktime());
if ( $object->GetDBField('Status') == 0 ) {
- $sql = 'DELETE FROM ' . $this->Application->getUnitOption('ptc', 'TableName') . '
+ $sql = 'DELETE FROM ' . $this->Application->getUnitConfig('ptc')->getTableName() . '
WHERE CurrencyId = ' . $object->GetDBField('CurrencyId');
$this->Conn->Query($sql);
}
}
/**
* 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);
$object = $event->getObject();
/* @var $object kDBList */
if ( $event->Special == 'active' ) {
$object->addFilter('status_filter', '%1$s.Status = 1');
}
if ( !$this->Application->isAdminUser ) {
$object->addFilter('status_filter', $object->TableName . '.Status = 1');
}
// site domain currency picker
if ( $event->Special == 'selected' || $event->Special == 'available' ) {
$edit_picker_helper = $this->Application->recallObject('EditPickerHelper');
/* @var $edit_picker_helper EditPickerHelper */
$edit_picker_helper->applyFilter($event, 'Currencies');
$object->addFilter('status_filter', '%1$s.Status = ' . STATUS_ACTIVE);
}
// apply domain-based currency filtering
$currencies = $this->Application->siteDomainField('Currencies');
if ( strlen($currencies) ) {
$currencies = explode('|', substr($currencies, 1, -1));
$object->addFilter('domain_filter', '%1$s.CurrencyId IN (' . implode(',', $currencies) . ')');
}
}
/**
* Saves content of temp table into live and
* redirects to event' default redirect (normally grid template)
*
* @param kEvent $event
* @return void
* @access protected
*/
protected function OnSave(kEvent $event)
{
$this->Application->StoreVar('saved_curr_ids', $this->Application->RecallVar($event->Prefix . '_selected_ids'));
parent::OnSave($event);
}
/**
* Enter description here...
*
* @param kEvent $event
*/
function OnDisableUnused($event)
{
$unused_ids = $this->Application->GetVar('unused_ids');
if ( $unused_ids ) {
- $sql = 'UPDATE ' . $this->Application->getUnitOption($event->Prefix, 'TableName') . '
+ $sql = 'UPDATE ' . $event->getUnitConfig()->getTableName() . '
SET Status = 0
WHERE CurrencyId IN(' . $unused_ids . ') AND IsPrimary <> 1';
$this->Conn->Query($sql);
}
}
/**
* Enter description here...
*
* @param kEvent $event
*/
function OnUpdateRate($event)
{
if ($this->Application->CheckPermission('SYSTEM_ACCESS.READONLY', 1)) {
$event->status = kEvent::erFAIL;
return;
}
$event->CallSubEvent('OnPreSave');
$rate_source = $this->Application->ConfigValue('Comm_ExchangeRateSource');
$rate_source_classes = Array( 2 => 'FRNYCurrencyRates',
3 => 'ECBCurrencyRates',
1 => 'BankLVCurrencyRates'
);
$rates_class = $rate_source_classes[$rate_source];
$rates = $this->Application->recallObject($rates_class);
$rates->GetRatesData();
$object = $event->getObject();
/* @var $object kDBItem */
$iso = $object->GetDBField('ISO');
$rates->StoreRates($iso);
if($rates->GetRate($iso, 'PRIMARY'))
{
$event->status=kEvent::erSUCCESS;
}
else
{
$event->status=kEvent::erFAIL;
$event->redirect=false;
$object->SetError('RateToPrimary', 'couldnt_retrieve_rate', 'la_couldnt_retrieve_rate');
}
}
/**
* Enter description here...
*
* @param kEvent $event
*/
function OnUpdateRates($event)
{
if ($this->Application->CheckPermission('SYSTEM_ACCESS.READONLY', 1)) {
$event->status = kEvent::erFAIL;
return;
}
$ids = $this->StoreSelectedIDs($event);
$event->setEventParam('ids', $ids);
$ids = $event->getEventParam('ids');
$object = $event->getObject();
if(is_array($ids) && $ids[0])
{
$sql = 'SELECT ISO FROM '.$object->TableName.' WHERE CurrencyId IN ('.implode(',', $ids).')';
$iso_list = $this->Conn->GetCol($sql);
}
$rate_source = $this->Application->ConfigValue('Comm_ExchangeRateSource');
$rate_source_classes = Array( 2 => 'FRNYCurrencyRates',
3 => 'ECBCurrencyRates',
1 => 'BankLVCurrencyRates'
);
$rates_class = $rate_source_classes[$rate_source];
$rates = $this->Application->recallObject($rates_class);
$rates->GetRatesData();
if($iso_list)
{
$rates->StoreRates($iso_list);
}
else
{
$rates->StoreRates();
}
}
/**
* Allows to change currency to given one
*
* @param kEvent $event
* @return void
* @access protected
*/
protected function OnChangeCurrency($event)
{
$currency_iso = $this->Application->GetVar('curr_iso');
$available_currencies = $this->Application->siteDomainField('Currencies');
if ($available_currencies) {
if (strpos($available_currencies, '|' . $currency_iso . '|') === false) {
// currency isn't allowed in site domain
return ;
}
}
$this->Application->StoreVar('curr_iso', $currency_iso);
$passed = explode(',', $this->Application->GetVar('passed'));
$prefix_index = array_search($event->getPrefixSpecial(), $passed);
if ( $prefix_index !== false ) {
unset($passed[$prefix_index]);
$this->Application->SetVar('passed', implode(',', $passed));
}
}
}
\ No newline at end of file
Index: branches/5.3.x/units/products/products_tag_processor.php
===================================================================
--- branches/5.3.x/units/products/products_tag_processor.php (revision 15694)
+++ branches/5.3.x/units/products/products_tag_processor.php (revision 15695)
@@ -1,861 +1,861 @@
<?php
/**
* @version $Id$
* @package In-Commerce
* @copyright Copyright (C) 1997 - 2009 Intechnic. All rights reserved.
* @license Commercial License
* This software 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
* See http://www.in-portal.org/commercial-license for copyright notices and details.
*/
defined('FULL_PATH') or die('restricted access!');
class ProductsTagProcessor extends kCatDBTagProcessor {
function Rating($params)
{
$object = $this->getObject($params);
$rating = round($object->GetDBField('CachedRating') );
$o = '';
for ($i = 0; $i < $rating; $i++) {
$o .= $this->Application->ParseBlock( Array('name' => $this->SelectParam($params, 'star_on_render_as,block_star_on')) );
}
for ($i = 0; $i < 5 - $rating; $i++) {
$o .= $this->Application->ParseBlock( Array('name' => $this->SelectParam($params, 'star_off_render_as,block_star_off')) );
}
return $o;
}
function NewMark($params)
{
$object = $this->getObject($params);
$o = '';
if($object->GetDBField('IsNew'))
{
$o .= $this->Application->ParseBlock( Array('name' => $this->SelectParam($params, 'render_as,block')) );
}
return $o;
}
function HotMark($params)
{
$object = $this->getObject($params);
$o = '';
if($object->GetDBField('IsHot'))
{
$o .= $this->Application->ParseBlock( Array('name' => $this->SelectParam($params, 'render_as,block')) );
}
return $o;
}
function TopSellerMark($params)
{
return $this->HotMark($params);
}
function PopMark($params)
{
$object = $this->getObject($params);
$o = '';
if($object->GetDBField('IsPop'))
{
$o .= $this->Application->ParseBlock( Array('name' => $this->SelectParam($params, 'render_as,block')) );
}
return $o;
}
function EdPickMark($params)
{
$object = $this->getObject($params);
$o = '';
if($object->GetDBField('EditorsPick'))
{
$o .= $this->Application->ParseBlock( Array('name' => $this->SelectParam($params, 'render_as,block')) );
}
return $o;
}
/**
* Parses block only if item is favorite
*
* @param Array $params
* @return string
* @deprecated used only in default,onlinestore
*/
function FavoriteMark($params)
{
if ($this->IsFavorite($params)) {
return $this->Application->ParseBlock( Array( 'name' => $this->SelectParam($params, 'render_as,block') ) );
}
return '';
}
function CurrentCategory($params)
{
$sql = "SELECT Name
FROM " . TABLE_PREFIX . "Categories
WHERE CategoryId=" . $this->Application->GetVar("m_cat_id");
return $this->Conn->GetOne($sql);
}
function RateForm($params)
{
$params['name'] = $this->SelectParam($params, 'render_as,block');
$labels = explode(',', $params['labels']);
$o = '';
$star_block = $this->SelectParam($params, 'star_render_as,star_block');
for($i = 5; $i >= 0; $i--)
{
$params['rating'] = $i;
$params['label'] = $this->Application->Phrase($labels[5 - $i]);
$params['stars'] = '';
for($j = $i; $j > 0; $j--)
{
$params['stars'] .= $this->Application->ParseBlock(Array('name' => $star_block));
}
$o .= $this->Application->ParseBlock($params);
}
return $o;
}
/**
* Parses block for changing favorite status
*
* @param Array $params
* @return string
* @deprecated used only in default,onlinestore
*/
function FavoriteToggle($params)
{
$block_params = Array ();
$block_names = $this->IsFavorite($params) ? 'remove_favorite_render_as,block_remove_favorite' : 'add_favorite_render_as,block_add_favorite';
$block_params['name'] = $this->SelectParam($params, $block_names);
$params['template'] = $params[$this->IsFavorite($params) ? 'template_on_remove' : 'template_on_add'];
$remove_params = Array (
'remove_favorite_render_as', 'block_remove_favorite', 'add_to_wish_list_render_as', 'block_add_to_wish_list',
'add_favorite_render_as', 'block_add_favorite', 'remove_from_wish_list_render_as', 'block_remove_from_wish_list',
'template_on_remove', 'template_on_add'
);
foreach ($params as $param_name => $param_value) {
if (in_array($param_name, $remove_params)) {
unset($params[$param_name]);
}
}
$block_params['wish_list_toggle_link'] = $this->FavoriteToggleLink($params);
return $this->Application->ParseBlock($block_params);
}
function WishListToggleLink($params)
{
$params['block_add_favorite'] = $this->SelectParam($params, 'add_to_wish_list_render_as,block_add_to_wish_list');
$params['block_remove_favorite'] = $this->SelectParam($params, 'remove_from_wish_list_render_as,block_remove_from_wish_list');
return $this->FavoriteToggle($params);
}
function AddReviewLink($params)
{
$o = $this->Application->ParseBlock( Array('name' => $this->SelectParam($params, 'render_as,block')) );
return $o;
}
function ListProducts($params)
{
return $this->PrintList2($params);
}
function ListRelatedProducts($params)
{
// $related = $this->Application->recallObject('rel');
return $this->PrintList2($params);
}
function BuildListSpecial($params)
{
if ($this->Special != '') return $this->Special;
if ( isset($params['parent_cat_id']) ) {
$parent_cat_id = $params['parent_cat_id'];
}
else {
$parent_cat_id = $this->Application->GetVar('c_id');
if (!$parent_cat_id) {
$parent_cat_id = $this->Application->GetVar('m_cat_id');
}
}
if ( isset($params['manufacturer']) ) {
$manufacturer = $params['manufacturer'];
}
else {
$manufacturer = $this->Application->GetVar('manuf_id');
}
$recursive = isset($params['recursive']);
$list_unique_key = $this->getUniqueListKey($params).$recursive;
if ($list_unique_key == '') {
return parent::BuildListSpecial($params);
}
return crc32($parent_cat_id.$list_unique_key.$manufacturer);
}
function ProductList($params)
{
if($params['shortlist'])
{
$params['per_page'] = $this->Application->ConfigValue('Comm_Perpage_Products_Short');
}
$object = $this->Application->recallObject( $this->getPrefixSpecial() , $this->Prefix.'_List', $params );
switch($params['ListType'])
{
case 'favorites':
return $this->PrintList($params);
break;
case 'search':
default:
if(isset($params['block']))
{
return $this->PrintList($params);
}
else
{
$params['block'] = $params['block_main'];
$params['row_start_block'] = $params['block_row_start'];
$params['row_end_block'] = $params['block_row_end'];
return $this->PrintList2($params);
}
}
}
/**
* Adds product to recently viewed list (only in case, when not already there)
*
* @param Array $params
*/
function AddToRecent($params)
{
$recent_products = $this->Application->RecallVar('recent_products');
if (!$recent_products) {
$recent_products = Array();
}
else {
$recent_products = unserialize($recent_products);
}
$product_id = $this->Application->GetVar('p_id');
if (!in_array($product_id, $recent_products)) {
array_push($recent_products, $product_id);
$this->Application->StoreVar('recent_products', serialize($recent_products));
}
}
function SearchMoreLink($params)
{
$object =& $this->GetList($params);
$o = '';
if($object->GetPerPage() < $this->SearchResultsCount())
{
$o = $this->Application->ParseBlock( Array('name' => $params['block']) );
}
return $o;
}
function AddToCartLink($params)
{
$object = $this->getObject($params);
if ($object->GetDBField('HasRequiredOptions')) {
$t = $params['product_template'];
if (!$t) {
$theme = $this->Application->recallObject('theme.current');
if ($theme->GetDBField('Name') == 'onlinestore') {
$t = 'in-commerce/product/details';
}
elseif ($theme->GetDBField('Name') == 'default') {
$t = 'in-commerce/product';
}
}
$link_params = Array('m_cat_id' => $object->GetDBField('CategoryId'), 'pass' => 'm,p');
}
else {
$t = $params['template'];
$link_params = Array('m_cat_id' => $object->GetDBField('CategoryId'), 'pass' => 'm,p,ord', 'ord_event' => 'OnAddToCart');
}
$this->Application->SetVar('p_id', $this->Application->GetVar($this->getPrefixSpecial().'_id'));
return $this->Application->HREF($t, '', $link_params);
}
function SearchResultsCount($params)
{
$search_results_table = TABLE_PREFIX.'ses_'.$this->Application->GetSID().'_'.TABLE_PREFIX.'Search';
$sql = ' SELECT COUNT(ResourceId)
FROM '.$search_results_table.'
WHERE ItemType=11';
return $this->Conn->GetOne($sql);
}
function DetailsLink($params)
{
$this->Application->SetVar( $this->Prefix.'_id', $this->Application->GetVar($this->getPrefixSpecial().'_id') );
$ret = $this->Application->HREF('in-commerce/details', '', Array('pass' => 'all,p'));
return $ret;
}
function ProductLink($params)
{
return $this->ItemLink($params, 'product');
}
function ProductFileLink($params)
{
// 'p_id'=>'0', ??
$params = array_merge($params, Array('pass'=>'all,m,p,file.downl'));
$product_id = getArrayValue($params,'product_id');
if (!$product_id) {
$product_id = $this->Application->GetVar($this->Prefix.'_id');
}
$params['p_id'] = $product_id;
$product = $this->Application->recallObject($this->getPrefixSpecial());
$params['m_cat_id'] = $product->GetDBField('CategoryId');
$main_processor = $this->Application->recallObject('m_TagProcessor');
return $main_processor->T($params);
}
function GetMarkedVal($params)
{
$list =& $this->GetList($params);
return $this->Application->RecallVar($list->getPrefixSpecial().$params['name']);
}
function SortingOptions($params)
{
$list =& $this->GetList($params);
$sorting_field_selected = $this->Application->RecallVar($list->getPrefixSpecial() . $params['sorting_select_name']);
if ( !$sorting_field_selected ) {
$sorting_field_selected = $this->Application->ConfigValue('product_OrderProductsBy');
}
$sql = 'SELECT ValueList
FROM ' . TABLE_PREFIX . 'SystemSettings
WHERE VariableName = "product_OrderProductsBy"';
$field_list_plain = $this->Conn->GetOne($sql);
$field_list = explode(',', $field_list_plain);
$o = '';
$option_params = $this->prepareTagParams($params);
foreach ($field_list as $field) {
list($fieldname, $fieldlabel) = explode('=', $field);
$option_params['fieldname'] = $fieldname;
$option_params['fieldlabel'] = $this->Application->Phrase($fieldlabel);
$option_params['name'] = $params['block_options'];
$option_params['selected'] = $fieldname == $sorting_field_selected ? 'selected' : '';
$o .= $this->Application->ParseBlock($option_params);
}
return $o;
}
function SortingDirectionOptions($params)
{
$list =& $this->GetList($params);
$sorting_dir_selected = $this->Application->RecallVar($list->getPrefixSpecial() . $params['sorting_select_name']);
if ( !$sorting_dir_selected ) {
$sorting_dir_selected = $this->Application->ConfigValue('product_OrderProductsByDir');
}
$o = '';
$field_list = array ('asc' => 'lu_Ascending', 'desc' => 'lu_Descending');
$option_params = $this->prepareTagParams($params);
foreach ($field_list as $fieldname => $fieldlabel) {
$option_params['fieldname'] = $fieldname;
$option_params['fieldlabel'] = $this->Application->Phrase($fieldlabel);
$option_params['name'] = $params['block_options'];
$option_params['selected'] = $fieldname == $sorting_dir_selected ? 'selected' : '';
$o .= $this->Application->ParseBlock($option_params);
}
return $o;
}
function ErrorMessage($params)
{
if( $this->Application->GetVar('keywords_too_short') )
{
$ret = $this->Application->ParseBlock(Array('name' => $this->SelectParam($params, 'keywords_too_short_render_as,block_keywords_too_short')));
}
elseif( $this->Application->GetVar('adv_search_error') )
{
$ret = $this->Application->ParseBlock(Array('name' => $this->SelectParam($params, 'adv_search_error_render_as,block_adv_search_error')));
}
else
{
$ret = $this->Application->ParseBlock(Array('name' => $this->SelectParam($params, 'no_found_render_as,block_no_found')));
}
return $ret;
}
function ListReviews($params)
{
$review_tag_processor = $this->Application->recallObject('rev.product_TagProcessor');
return $review_tag_processor->PrintList($params);
}
function ReviewCount($params)
{
$review_tag_processor = $this->Application->recallObject('rev.product_TagProcessor');
return $review_tag_processor->TotalRecords($params);
}
function InitList($params){
$passed_manuf_id = $this->Application->GetVar('manuf_id');
if ($passed_manuf_id && !isset($params['manufacturer'])){
$params['manufacturer'] = $passed_manuf_id;
}
parent::InitList($params);
}
/**
* Builds link to manufacturer page
*
* @param Array $params
* @return string
*/
function ManufacturerLink($params)
{
if ( array_key_exists('manufacturer_id', $params) ) {
// use direct manufacturer from tag
$params['manuf_id'] = $params['manufacturer_id'];
unset($params['manufacturer_id']);
}
else {
// use product's manufacturer
$object = $this->getObject($params);
$item_manufacturer_id = $object->GetDBField('ManufacturerId');
if ($item_manufacturer_id){
$params['manuf_id'] = $item_manufacturer_id;
}
}
$params['pass'] = 'm,manuf';
$params['m_cat_id'] = 0;
return $this->Application->ProcessParsedTag('m', 'Link', $params);
}
function AlreadyReviewed($params)
{
$rev_tag_processor = $this->Application->recallObject('rev_TagProcessor');
return $rev_tag_processor->AlreadyReviewed($params);
}
function PrepareSearchResults($params)
{
$names_mapping = $this->Application->GetVar('NamesToSpecialMapping', Array ());
if($this->Application->GetVar('search_type') == 'advanced' || !getArrayValue($names_mapping, $this->Prefix, 'search_results'))
{
$params = Array('list_name' => 'search_results',
'types' => 'search',
'parent_cat_id' => 'any',
'recursive' => 'true',
'per_page' => 'short_list'
);
$this->InitList($params);
}
return '';
}
function Available($params)
{
$object = $this->getObject($params);
/* @var $object kDBItem */
if ( !$object->GetDBField('InventoryStatus') ) {
return true;
}
$backordering = $this->Application->ConfigValue('Comm_Enable_Backordering');
if ( $object->GetDBField('InventoryStatus') == 2 ) {
- $poc_table = $this->Application->getUnitOption('poc', 'TableName');
+ $poc_table = $this->Application->getUnitConfig('poc')->getTableName();
+
$sql = 'SELECT SUM(IF(QtyInStock > ' . $object->GetDBField('QtyInStockMin') . ', 1, 0))
FROM ' . $poc_table . '
WHERE (ProductId = ' . $object->GetID() . ') AND (Availability = 1)';
$stock_available = $this->Conn->GetOne($sql) > 0; // at least one option combination present
}
else {
$stock_available = $object->GetDBField('QtyInStock') > $object->GetDBField('QtyInStockMin');
}
$prod_backordering = $object->GetDBField('BackOrder');
if ( $stock_available ) {
return true;
}
// stock is NOT available:
if ( !$backordering || $prod_backordering == 0 ) {
// if backordering is generaly disabled or disabled for product (Never)
return false;
}
// backordering enabled; (auto or always mode)
return true;
}
function IsSubscription($params)
{
$object = $this->getObject($params);
/* @var $object kDBItem */
return ($object->GetDBField('Type') == 2);
}
function IsTangible($params)
{
$object = $this->getObject($params);
/* @var $object kDBItem */
return ($object->GetDBField('Type') == 1);
}
function HasFiles($params)
{
- $sql = 'SELECT COUNT(FileId) FROM '.$this->Application->getUnitOption('file', 'TableName').'
+ $sql = 'SELECT COUNT(FileId)
+ FROM '.$this->Application->getUnitConfig('file')->getTableName().'
WHERE ProductId = '.$this->Application->GetVar('p_id').' AND Status = 1';
+
return $this->Conn->GetOne($sql) ? 1 : 0;
}
function UniqueFileName($params)
{
$file_object = $this->Application->recallObject('file.downl');
return ($file_object->GetDBField('Name') &&
$file_object->GetDBField('Name') != $file_object->GetDBField('FilePath'))
? 1 : 0;
}
function FileDownload($params)
{
$file_id = $this->Application->GetVar('file.downl_id');
$product_id = $file_id ? $this->Conn->GetOne('SELECT ProductId
- FROM '.$this->Application->getUnitOption('file', 'TableName').'
+ FROM '.$this->Application->getUnitConfig('file')->getTableName().'
WHERE FileId = '.$file_id) :
$this->Application->GetVar($this->getPrefixSpecial().'_id');
- $download_helper_class = $this->Application->getUnitOption($this->Prefix, 'DownloadHelperClass');
+ $download_helper_class = $this->getUnitConfig()->getDownloadHelperClass('DownloadHelper');
+
- if (!$download_helper_class) {
- $download_helper_class = 'DownloadHelper';
- }
$download_helper = $this->Application->recallObject($download_helper_class);
if (!$download_helper->CheckAccess($file_id, $product_id)) {
$this->Application->ApplicationDie('File Access permission check failed!');
}
$file_info = $download_helper->SendFile($file_id, $product_id);
$download_helper->LogDownload($product_id, $file_info);
define('DBG_SKIP_REPORTING', 1);
$this->Application->ApplicationDie();
}
function PictureLink($params)
{
if (getArrayValue($params, 'picture_list')) {
$params['img_id'] = $this->Application->GetVar('img_id');
$params['pass'] = 'all,p,img';
unset($params['picture_list']);
}
else {
$params['pass'] = 'all,p';
}
return $this->Application->ProcessParsedTag('m', 'Link', $params);
}
function ShouldListOptions($params)
{
$object = $this->getObject($params);
$req_filter = '';
if (getArrayValue($params, 'required_only')) {
$req_filter = ' AND Required = 1';
}
$query = 'SELECT COUNT(*) FROM '.TABLE_PREFIX.'ProductOptions WHERE ProductId = '.$object->GetID().$req_filter;
$res = $this->Conn->GetOne($query);
return $res > 0;
}
function CountOptions($params)
{
$object = $this->getObject($params);
$query = 'SELECT COUNT(*) FROM '.TABLE_PREFIX.'ProductOptions WHERE ProductId = '.$object->GetID();
$res = $this->Conn->GetOne($query);
$max = $this->SelectParam($params, 'greater');
if (!$max) $max = 0;
return $res > $max;
}
function OptionsUpdateMode($params)
{
return $this->Application->GetVar('orditems_id') !== false;
}
function OptionsHaveError($params)
{
return $this->Application->GetVar('opt_error') > 0;
}
function OptionsError($params)
{
switch ($this->Application->GetVar('opt_error')) {
case 1:
return $this->Application->Phrase($params['required']);
case 2:
return $this->Application->Phrase($params['not_available']);
}
}
function ListShippingTypes($params)
{
$quote_engine_collector = $this->Application->recallObject('ShippingQuoteCollector');
/* @var $quote_engine_collector ShippingQuoteCollector */
$types = $quote_engine_collector->GetAvailableShippingTypes();
$object = $this->getObject($params);
$selected = $object->GetDBField('ShippingLimitation');
$selected = explode('|', substr($selected, 1, -1));
$o = '';
foreach ($types as $a_type)
{
$is_selected = in_array($a_type['_Id'], $selected);
$continue = $params['mode'] == 'selected' ? !$is_selected : $is_selected;
if ($continue) continue;
$block_params = $a_type;
$block_params['name'] = $params['render_as'];
$o .= $this->Application->ParseBlock($block_params);
}
return $o;
}
function PageLink($params)
{
$manufacturer_id = $this->Application->GetVar('manuf_id');
if ($manufacturer_id) {
$params['pass'] = 'm,'.$this->getPrefixSpecial().',manuf';
}
return parent::PageLink($params);
}
/**
* Calculate savings based on price & market price relationship
*
* @param Array $params
* @return int
*/
function Savings($params)
{
$object = $this->getObject($params);
/* @var $object kDBItem */
$price = $object->GetDBField('Price');
$msrp = $object->GetDBField('MSRP');
$value = 0;
if (isset($params['type']) && ($params['type'] == 'percent')) {
if ($msrp > 0) {
return 100 - round($price * 100 / $msrp);
}
}
else {
if ($msrp > $price) {
$value = $msrp - $price;
}
}
if (isset($params['currency'])) {
$lang = $this->Application->recallObject('lang.current');
/* @var $lang LanguagesItem */
$iso = $this->GetISO($params['currency']);
$value = $this->ConvertCurrency($value, $iso);
$value = $lang->formatNumber( sprintf('%.2f', $value) );
$value = $this->AddCurrencySymbol($value, $iso);
}
return $value;
}
/**
* Hides permission tab, when it's not allowed by configuration settings
*
* @param Array $params
*/
function ModifyUnitConfig($params)
{
- $edit_tab_presets = $this->Application->getUnitOption($this->Prefix, 'EditTabPresets');
- $edit_tab_preset = $edit_tab_presets['Default'];
+ $config = $this->getUnitConfig();
+ $edit_tab_preset = $config->getEditTabPresetByName('Default');
$object = $this->getObject($params);
/* @var $object kDBItem */
$product_type = $object->GetDBField('Type');
if ($product_type != PRODUCT_TYPE_TANGIBLE) {
unset($edit_tab_preset['inventory']);
}
if ($product_type == PRODUCT_TYPE_SUBSCRIPTION) {
unset($edit_tab_preset['options']);
}
else {
unset($edit_tab_preset['access_and_pricing']);
}
if ($product_type != PRODUCT_TYPE_TANGIBLE && $product_type != PRODUCT_TYPE_PACKAGE) {
unset($edit_tab_preset['pricing']);
}
else {
unset($edit_tab_preset['pricing2']);
}
if ($product_type != PRODUCT_TYPE_DOWNLOADABLE) {
unset($edit_tab_preset['files_and_pricing']);
}
if ($product_type != PRODUCT_TYPE_PACKAGE) {
unset($edit_tab_preset['package_content']);
}
- $edit_tab_presets['Default'] = $edit_tab_preset;
- $this->Application->setUnitOption($this->Prefix, 'EditTabPresets', $edit_tab_presets);
+ $config->addEditTabPresets($edit_tab_preset, 'Default');
}
/**
* Checks, that current product is in compare products list
*
* @param Array $params
* @return string
* @access protected
*/
protected function InCompare($params)
{
$object = $this->getObject($params);
/* @var $object kDBItem */
$products = $this->Application->GetVarDirect('compare_products', 'Cookie');
$products = $products ? explode('|', $products) : Array ();
return in_array($object->GetID(), $products);
}
/**
* Checks, that one more product can be added to comparison list
*
* @param Array $params
* @return string
* @access protected
*/
protected function ComparePossible($params)
{
$products = $this->Application->GetVarDirect('compare_products', 'Cookie');
$products = $products ? explode('|', $products) : Array ();
return count($products) < $this->Application->ConfigValue('MaxCompareProducts');
}
/**
* Checks if given field is filled for at least one product in comparison page
*
* @param Array $params
* @return string
* @access protected
*/
protected function HasCompareField($params)
{
$object =& $this->GetList($params);
$object->GoFirst();
$field = $this->SelectParam($params, 'name,field');
while ( !$object->EOL() ) {
if ( $object->GetField($field) ) {
// don't use GetCol, since it fails to process ML fields
return true;
}
$object->GoNext();
}
return false;
}
/**
* Builds link to product compare page
*
* @param Array $params
* @return string
* @access protected
*/
protected function CompareLink($params)
{
$params['continue'] = urlencode($this->Application->HREF('__default__', '', Array ('pass_category' => 1)));
return $this->Application->ProcessParsedTag('m', 'Link', $params);
}
/**
* Builds link to continue website browsing from compare products page
*
* @param Array $params
* @return string
* @access protected
*/
protected function ContinueLink($params)
{
$url = $this->Application->GetVar('continue');
if ( isset($params['redirect']) && $params['redirect'] ) {
$this->Application->Redirect('external:' . $url);
}
return $url;
}
}
\ No newline at end of file
Index: branches/5.3.x/units/products/products_event_handler.php
===================================================================
--- branches/5.3.x/units/products/products_event_handler.php (revision 15694)
+++ branches/5.3.x/units/products/products_event_handler.php (revision 15695)
@@ -1,1595 +1,1599 @@
<?php
/**
* @version $Id$
* @package In-Commerce
* @copyright Copyright (C) 1997 - 2009 Intechnic. All rights reserved.
* @license Commercial License
* This software 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
* See http://www.in-portal.org/commercial-license for copyright notices and details.
*/
defined('FULL_PATH') or die('restricted access!');
class ProductsEventHandler extends kCatDBEventHandler {
/**
* Allows to override standard permission mapping
*
* @return void
* @access protected
* @see kEventHandler::$permMapping
*/
protected function mapPermissions()
{
parent::mapPermissions();
$permissions = Array(
// front
'OnCancelAction' => Array('self' => true),
'OnRateProduct' => Array('self' => true),
'OnClearRecent' => Array('self' => true),
'OnRecommendProduct' => Array('self' => true),
'OnAddToCompare' => Array('self' => true),
'OnRemoveFromCompare' => Array('self' => true),
'OnCancelCompare' => Array('self' => true),
// admin
'OnQtyAdd' => Array('self' => 'add|edit'),
'OnQtyRemove' => Array('self' => 'add|edit'),
'OnQtyOrder' => Array('self' => 'add|edit'),
'OnQtyReceiveOrder' => Array('self' => 'add|edit'),
'OnQtyCancelOrder' => Array('self' => '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/decine and so on events
$product_events = Array (
'OnQtyAdd'=>'InventoryAction',
'OnQtyRemove'=>'InventoryAction',
'OnQtyOrder'=>'InventoryAction',
'OnQtyReceiveOrder'=>'InventoryAction',
'OnQtyCancelOrder'=>'InventoryAction',
);
$this->eventMethods = array_merge($this->eventMethods, $product_events);
}
/**
* Sets default processing data for subscriptions
*
* @param kEvent $event
* @return void
* @access protected
*/
protected function OnBeforeItemCreate(kEvent $event)
{
parent::OnBeforeItemCreate($event);
$object = $event->getObject();
/* @var $object kDBItem */
$product_approve_events = Array (
2 => 'p:OnSubscriptionApprove',
4 => 'p:OnDownloadableApprove',
5 => 'p:OnPackageApprove'
);
$product_type = $object->GetDBField('Type');
$type_found = in_array($product_type, array_keys($product_approve_events));
if ( $type_found && !$object->GetDBField('ProcessingData') ) {
$processing_data = Array ('ApproveEvent' => $product_approve_events[$product_type]);
$object->SetDBField('ProcessingData', serialize($processing_data));
}
}
/**
* Process product count manipulations
*
* @param kEvent $event
* @access private
*/
function InventoryAction($event)
{
$object = $event->getObject();
/* @var $object kDBItem */
$field_values = $this->getSubmittedFields($event);
$object->SetFieldsFromHash($field_values, $this->getRequestProtectedFields($field_values));
if ($object->GetDBField('InventoryStatus') == 2) {
// inventory by options (use first selected combination in grid)
$combinations = $this->Application->GetVar('poc_grid');
list ($combination_id, ) = each($combinations);
}
else {
// inventory by product
$combination_id = 0;
}
// save id of selected option combination & preselect it in grid
$this->Application->SetVar('combination_id', $combination_id);
$this->ScheduleInventoryAction($event->Name, $object->GetId(), $object->GetDBField('Qty'), $combination_id);
$object->Validate();
if ( !$object->GetErrorPseudo('Qty') ){
// only update, when no error on that field
$this->modifyInventory($event->Name, $object, $object->GetDBField('Qty'), $combination_id);
}
$object->SetDBField('Qty', null);
$event->redirect = false;
}
/**
* Perform inventory action on supplied object
*
* @param string $action event name which is actually called by user
* @param ProductsItem $product
* @param int $qty
* @param int $combination_id
*/
function modifyInventory($action, &$product, $qty, $combination_id)
{
if ($product->GetDBField('InventoryStatus') == 2) {
// save inventory changes to option combination instead of product
$object = $this->Application->recallObject('poc.-item', null, Array('skip_autoload' => true));
$object->Load($combination_id);
}
elseif ($combination_id > 0) {
// combination id present, but not inventory by combinations => skip
return false;
}
elseif ($product->GetDBField('InventoryStatus') == 1) {
// save inventory changes to product
$object =& $product;
}
else {
// product has inventory actions, but don't use inventory => skip
return false;
}
if (!$object->isLoaded()) {
// product/combination in action doesn't exist in database by now
return false;
}
switch ($action) {
case 'OnQtyAdd':
$object->SetDBField('QtyInStock', $object->GetDBField('QtyInStock') + $qty);
break;
case 'OnQtyRemove':
if ($object->GetDBField('QtyInStock') < $qty) {
$qty = $object->GetDBField('QtyInStock');
}
$object->SetDBField('QtyInStock', $object->GetDBField('QtyInStock') - $qty);
break;
case 'OnQtyOrder':
$object->SetDBField('QtyOnOrder', $object->GetDBField('QtyOnOrder') + $qty);
break;
case 'OnQtyReceiveOrder':
$object->SetDBField('QtyOnOrder', $object->GetDBField('QtyOnOrder') - $qty);
$object->SetDBField('QtyInStock', $object->GetDBField('QtyInStock') + $qty);
break;
case 'OnQtyCancelOrder':
$object->SetDBField('QtyOnOrder', $object->GetDBField('QtyOnOrder') - $qty);
break;
}
return $object->Update();
}
function ScheduleInventoryAction($action, $prod_id, $qty, $combination_id = 0)
{
$inv_actions = $this->Application->RecallVar('inventory_actions');
if (!$inv_actions) {
$inv_actions = Array();
}
else {
$inv_actions = unserialize($inv_actions);
}
array_push($inv_actions, Array('action' => $action, 'product_id' => $prod_id, 'combination_id' => $combination_id, 'qty' => $qty));
$this->Application->StoreVar('inventory_actions', serialize($inv_actions));
}
function RealInventoryAction($action, $prod_id, $qty, $combination_id)
{
$product = $this->Application->recallObject('p.liveitem', null, Array('skip_autoload' => true));
$product->SwitchToLive();
$product->Load($prod_id);
$this->modifyInventory($action, $product, $qty, $combination_id);
}
function RunScheduledInventoryActions($event)
{
$inv_actions = $this->Application->GetVar('inventory_actions');
if (!$inv_actions) {
return;
}
$inv_actions = unserialize($inv_actions);
$products = array();
foreach($inv_actions as $an_action) {
$this->RealInventoryAction($an_action['action'], $an_action['product_id'], $an_action['qty'], $an_action['combination_id']);
array_push($products, $an_action['product_id'].'_'.$an_action['combination_id']);
}
$products = array_unique($products);
if ($products) {
$product_obj = $this->Application->recallObject('p.liveitem', null, Array('skip_autoload' => true));
$product_obj->SwitchToLive();
foreach ($products as $product_key) {
list($prod_id, $combination_id) = explode('_', $product_key);
$product_obj->Load($prod_id);
$this->FullfillBackOrders($product_obj, $combination_id);
}
}
}
/**
* In case if products arrived into inventory and they are required by old (non processed) orders, then use them (products) in that orders
*
* @param ProductsItem $product
* @param int $combination_id
*/
function FullfillBackOrders(&$product, $combination_id)
{
if ( !$this->Application->ConfigValue('Comm_Process_Backorders_Auto') ) return;
if ($combination_id && ($product->GetDBField('InventoryStatus') == 2)) {
// if combination id present and inventory by combinations
- $poc_idfield = $this->Application->getUnitOption('poc', 'IDField');
- $poc_tablename = $this->Application->getUnitOption('poc', 'TableName');
+ $poc_config = $this->Application->getUnitConfig('poc');
+
$sql = 'SELECT QtyInStock
- FROM '.$poc_tablename.'
- WHERE '.$poc_idfield.' = '.$combination_id;
+ FROM '. $poc_config->getTableName() .'
+ WHERE '. $poc_config->getIDField() .' = '.$combination_id;
$stock_qty = $this->Conn->GetOne($sql);
}
else {
// inventory by product
$stock_qty = $product->GetDBField('QtyInStock');
}
$qty = (int) $stock_qty - $product->GetDBField('QtyInStockMin');
$prod_id = $product->GetID();
if ($prod_id <= 0 || !$prod_id || $qty <= 0) return;
//selecting up to $qty backorders with $prod_id where full qty is not reserved
$query = 'SELECT '.TABLE_PREFIX.'Orders.OrderId
FROM '.TABLE_PREFIX.'OrderItems
LEFT JOIN '.TABLE_PREFIX.'Orders ON '.TABLE_PREFIX.'Orders.OrderId = '.TABLE_PREFIX.'OrderItems.OrderId
WHERE (ProductId = '.$prod_id.') AND (Quantity > QuantityReserved) AND (Status = '.ORDER_STATUS_BACKORDERS.')
GROUP BY '.TABLE_PREFIX.'Orders.OrderId
ORDER BY OrderDate ASC
LIMIT 0,'.$qty; //assuming 1 item per order - minimum possible
$orders = $this->Conn->GetCol($query);
if (!$orders) return;
$order = $this->Application->recallObject('ord.-inv', null, Array('skip_autoload' => true));
foreach ($orders as $ord_id) {
$order->Load($ord_id);
$this->Application->emailAdmin('BACKORDER.FULLFILL');
//reserve what's possible in any case
$event = new kEvent('ord:OnReserveItems');
$this->Application->HandleEvent($event);
if ( $event->status == kEvent::erSUCCESS ) { //
//in case the order is ready to process - process it
$this->Application->HandleEvent($event, 'ord:OnOrderProcess');
}
}
}
/**
* Occurs before an item is deleted from live table when copying from temp
* (temp handler deleted all items from live and then copy over all items from temp)
* Id of item being deleted is passed as event' 'id' param
*
* @param kEvent $event
* @return void
* @access protected
*/
protected function OnBeforeDeleteFromLive(kEvent $event)
{
parent::OnBeforeDeleteFromLive($event);
$product = $this->Application->recallObject($event->Prefix . '.itemlive', null, Array ('skip_autoload' => true));
/* @var $product kCatDBItem */
$product->SwitchToLive();
$id = $event->getEventParam('id');
if ( !$product->Load($id) ) {
// this will make sure New product will not be overwritten with empty data
return ;
}
$temp = $this->Application->recallObject($event->Prefix . '.itemtemp', null, Array ('skip_autoload' => true));
/* @var $temp kCatDBItem */
$temp->SwitchToTemp();
$temp->Load($id);
$temp->SetDBFieldsFromHash($product->GetFieldValues(), null, Array ('QtyInStock', 'QtyReserved', 'QtyBackOrdered', 'QtyOnOrder'));
$temp->Update();
}
/**
* Removes any information about current/selected ids
* from Application variables and Session
*
* @param kEvent $event
* @return void
* @access protected
*/
protected function clearSelectedIDs(kEvent $event)
{
parent::clearSelectedIDs($event);
$this->Application->SetVar('inventory_actions', $this->Application->RecallVar('inventory_actions'));
$this->Application->RemoveVar('inventory_actions');
}
/**
* Saves content of temp table into live and
* redirects to event' default redirect (normally grid template)
*
* @param kEvent $event
* @return void
* @access protected
*/
protected function OnSave(kEvent $event)
{
parent::OnSave($event);
if ( $event->status == kEvent::erSUCCESS ) {
$this->RunScheduledInventoryActions($event);
}
}
/**
* Prepare temp tables for creating new item
* but does not create it. Actual create is
* done in OnPreSaveCreated
*
* @param kEvent $event
* @return void
* @access protected
*/
protected function OnPreCreate(kEvent $event)
{
parent::onPreCreate($event);
$object = $event->getObject();
/* @var $object kDBItem */
$object->SetDBField('Type', $this->Application->GetVar($event->getPrefixSpecial(true) . '_new_type'));
}
/**
* Saves edited item in temp table and loads
* item with passed id in current template
* Used in Prev/Next buttons
*
* @param kEvent $event
* @return void
* @access protected
*/
protected function OnPreSaveAndGo(kEvent $event)
{
$event->CallSubEvent('OnPreSave');
$this->LoadItem($event);
$object = $event->getObject();
/* @var $object kDBItem */
$from_type = $object->GetDBField('Type');
if ( $event->status == kEvent::erSUCCESS ) {
$this->Application->SetVar($event->getPrefixSpecial() . '_id', $this->Application->GetVar($event->getPrefixSpecial(true) . '_GoId'));
$this->LoadItem($event);
$to_type = $object->GetDBField('Type');
if ( $from_type != $to_type ) {
$from_tabs = $this->GetTabs($from_type);
$from_tab_i = array_search($this->Application->GetVar('t'), $from_tabs);
$to_tabs = $this->GetTabs($to_type);
$to_tab = $this->Application->GetVar('t');
$found = false;
while (!isset($to_tabs[$from_tab_i]) && $from_tab_i < count($to_tabs)) {
$from_tab_i++;
}
if ( !isset($to_tabs[$from_tab_i]) ) {
$from_tab_i = 0;
}
$to_tab = $to_tabs[$from_tab_i];
$event->redirect = $to_tab;
}
}
}
function GetTabs($type)
{
switch($type)
{
case 1:
return Array(
0 => 'in-commerce/products/products_edit',
1 => 'in-commerce/products/products_inventory',
2 => 'in-commerce/products/products_pricing',
3 => 'in-commerce/products/products_categories',
4 => 'in-commerce/products/products_images',
5 => 'in-commerce/products/products_reviews',
6 => 'in-commerce/products/products_custom',
);
case 2:
return Array(
0 => 'in-commerce/products/products_edit',
1 => 'in-commerce/products/products_access',
/*2 => 'in-commerce/products/products_access_pricing',*/
3 => 'in-commerce/products/products_categories',
4 => 'in-commerce/products/products_images',
5 => 'in-commerce/products/products_reviews',
6 => 'in-commerce/products/products_custom',
);
case 3:
return Array(
0 => 'in-commerce/products/products_edit',
2 => 'in-commerce/products/products_access_pricing',
3 => 'in-commerce/products/products_categories',
4 => 'in-commerce/products/products_images',
5 => 'in-commerce/products/products_reviews',
6 => 'in-commerce/products/products_custom',
);
case 4:
return Array(
0 => 'in-commerce/products/products_edit',
2 => 'in-commerce/products/products_files',
3 => 'in-commerce/products/products_categories',
4 => 'in-commerce/products/products_images',
5 => 'in-commerce/products/products_reviews',
6 => 'in-commerce/products/products_custom',
);
}
}
/**
* Return type clauses for list bulding on front
*
* @param kEvent $event
* @return Array
*/
function getTypeClauses($event)
{
$types = $event->getEventParam('types');
$types = $types ? explode(',', $types) : Array ();
$except_types = $event->getEventParam('except');
$except_types = $except_types ? explode(',', $except_types) : Array ();
$object = $event->getObject();
/* @var $object kDBList */
$type_clauses = parent::getTypeClauses($event);
$type_clauses['featured']['include'] = '%1$s.Featured = 1 AND ' . TABLE_PREFIX . 'CategoryItems.PrimaryCat = 1';
$type_clauses['featured']['except'] = '%1$s.Featured != 1 AND ' . TABLE_PREFIX . 'CategoryItems.PrimaryCat = 1';
$type_clauses['featured']['having_filter'] = false;
$type_clauses['onsale']['include'] = '%1$s.OnSale = 1 AND ' . TABLE_PREFIX . 'CategoryItems.PrimaryCat = 1';
$type_clauses['onsale']['except'] = '%1$s.OnSale != 1 AND ' . TABLE_PREFIX . 'CategoryItems.PrimaryCat = 1';
$type_clauses['onsale']['having_filter'] = false;
// products from selected manufacturer: begin
$manufacturer = $event->getEventParam('manufacturer');
if ( !$manufacturer ) {
$manufacturer = $this->Application->GetVar('manuf_id');
}
if ( $manufacturer ) {
$type_clauses['manufacturer']['include'] = '%1$s.ManufacturerId = ' . $manufacturer . ' AND PrimaryCat = 1';
$type_clauses['manufacturer']['except'] = '%1$s.ManufacturerId != ' . $manufacturer . ' AND PrimaryCat = 1';
$type_clauses['manufacturer']['having_filter'] = false;
}
// products from selected manufacturer: end
// recent products: begin
$recent = $this->Application->RecallVar('recent_products');
if ( $recent ) {
$recent = unserialize($recent);
$type_clauses['recent']['include'] = '%1$s.ProductId IN (' . implode(',', $recent) . ') AND PrimaryCat = 1';
$type_clauses['recent']['except'] = '%1$s.ProductId NOT IN (' . implode(',', $recent) . ') AND PrimaryCat = 1';
}
else {
$type_clauses['recent']['include'] = '0';
$type_clauses['recent']['except'] = '1';
}
$type_clauses['recent']['having_filter'] = false;
// recent products: end
// compare products: begin
if ( in_array('compare', $types) || in_array('compare', $except_types) ) {
$compare_products = $this->getCompareProducts();
if ( $compare_products ) {
$compare_products = $this->Conn->qstrArray($compare_products);
$type_clauses['compare']['include'] = '%1$s.ProductId IN (' . implode(',', $compare_products) . ') AND PrimaryCat = 1';
$type_clauses['compare']['except'] = '%1$s.ProductId NOT IN (' . implode(',', $compare_products) . ') AND PrimaryCat = 1';
}
else {
$type_clauses['compare']['include'] = '0';
$type_clauses['compare']['except'] = '1';
}
$type_clauses['compare']['having_filter'] = false;
if ( $event->getEventParam('per_page') === false ) {
$event->setEventParam('per_page', $this->Application->ConfigValue('MaxCompareProducts'));
}
}
// compare products: end
// products already in shopping cart: begin
if ( in_array('in_cart', $types) || in_array('in_cart', $except_types) ) {
$order_id = $this->Application->RecallVar('ord_id');
if ( $order_id ) {
$sql = 'SELECT ProductId
FROM ' . TABLE_PREFIX . 'OrderItems
WHERE OrderId = ' . $order_id;
$in_cart = $this->Conn->GetCol($sql);
if ( $in_cart ) {
$type_clauses['in_cart']['include'] = '%1$s.ProductId IN (' . implode(',', $in_cart) . ') AND PrimaryCat = 1';
$type_clauses['in_cart']['except'] = '%1$s.ProductId NOT IN (' . implode(',', $in_cart) . ') AND PrimaryCat = 1';
}
else {
$type_clauses['in_cart']['include'] = '0';
$type_clauses['in_cart']['except'] = '1';
}
}
else {
$type_clauses['in_cart']['include'] = '0';
$type_clauses['in_cart']['except'] = '1';
}
$type_clauses['in_cart']['having_filter'] = false;
}
// products already in shopping cart: end
// my downloadable products: begin
if ( in_array('my_downloads', $types) || in_array('my_downloads', $except_types) ) {
$user_id = $this->Application->RecallVar('user_id');
$sql = 'SELECT ProductId
FROM ' . TABLE_PREFIX . 'UserFileAccess
WHERE PortalUserId = ' . $user_id;
$my_downloads = $user_id > 0 ? $this->Conn->GetCol($sql) : false;
if ( $my_downloads ) {
$type_clauses['my_downloads']['include'] = '%1$s.ProductId IN (' . implode(',', $my_downloads) . ') AND PrimaryCat = 1';
$type_clauses['my_downloads']['except'] = '%1$s.ProductId NOT IN (' . implode(',', $my_downloads) . ') AND PrimaryCat = 1';
}
else {
$type_clauses['my_downloads']['include'] = '0';
$type_clauses['my_downloads']['except'] = '1';
}
$type_clauses['my_downloads']['having_filter'] = false;
}
// my downloadable products: end
// my favorite products: begin
if ( in_array('wish_list', $types) || in_array('wish_list', $except_types) ) {
$sql = 'SELECT ResourceId
- FROM ' . $this->Application->getUnitOption('fav', 'TableName') . '
+ FROM ' . $this->Application->getUnitConfig('fav')->getTableName() . '
WHERE PortalUserId = ' . (int)$this->Application->RecallVar('user_id');
- $wishlist_ids = $this->Conn->GetCol($sql);
+ $wish_list_ids = $this->Conn->GetCol($sql);
- if ( $wishlist_ids ) {
- $type_clauses['wish_list']['include'] = '%1$s.ResourceId IN (' . implode(',', $wishlist_ids) . ') AND PrimaryCat = 1';
- $type_clauses['wish_list']['except'] = '%1$s.ResourceId NOT IN (' . implode(',', $wishlist_ids) . ') AND PrimaryCat = 1';
+ if ( $wish_list_ids ) {
+ $type_clauses['wish_list']['include'] = '%1$s.ResourceId IN (' . implode(',', $wish_list_ids) . ') AND PrimaryCat = 1';
+ $type_clauses['wish_list']['except'] = '%1$s.ResourceId NOT IN (' . implode(',', $wish_list_ids) . ') AND PrimaryCat = 1';
}
else {
$type_clauses['wish_list']['include'] = '0';
$type_clauses['wish_list']['except'] = '1';
}
$type_clauses['wish_list']['having_filter'] = false;
}
// my favorite products: end
// products from package: begin
if ( in_array('content', $types) || in_array('content', $except_types) ) {
$object->removeFilter('category_filter');
$object->AddGroupByField('%1$s.ProductId');
$object_product = $this->Application->recallObject($event->Prefix);
/* @var $object_product ProductsItem */
$content_ids_array = $object_product->GetPackageContentIds();
if ( sizeof($content_ids_array) == 0 ) {
$content_ids_array = array ('-1');
}
if ( sizeof($content_ids_array) > 0 ) {
$type_clauses['content']['include'] = '%1$s.ProductId IN (' . implode(',', $content_ids_array) . ')';
}
else {
$type_clauses['content']['include'] = '0';
}
$type_clauses['related']['having_filter'] = false;
}
// products from package: end
$object->addFilter('not_virtual', '%1$s.Virtual = 0');
if ( !$this->Application->isAdminUser ) {
$object->addFilter('expire_filter', '%1$s.Expire IS NULL OR %1$s.Expire > ' . adodb_mktime());
}
return $type_clauses;
}
function OnClearRecent($event)
{
$this->Application->RemoveVar('recent_products');
}
/**
* Occurs, when user rates a product
*
* @param kEvent $event
*/
function OnRateProduct($event)
{
$event->SetRedirectParam('pass', 'all,p');
$event->redirect = $this->Application->GetVar('success_template');
$object = $event->getObject();
/* @var $object kDBItem */
$user_id = $this->Application->RecallVar('user_id');
$sql = ' SELECT * FROM ' . TABLE_PREFIX . 'SpamControl
WHERE ItemResourceId=' . $object->GetDBField('ResourceId') . '
AND IPaddress="' . $this->Application->getClientIp() . '"
AND PortalUserId=' . $user_id . '
AND DataType="Rating"';
$res = $this->Conn->GetRow($sql);
if ( $res && $res['Expire'] < adodb_mktime() ) {
$sql = ' DELETE FROM ' . TABLE_PREFIX . 'SpamControl
WHERE ItemResourceId=' . $object->GetDBField('ResourceId') . '
AND IPaddress="' . $this->Application->getClientIp() . '"
AND PortalUserId=' . $user_id . '
AND DataType="Rating"';
$this->Conn->Query($sql);
unset($res);
}
$new_rating = $this->Application->GetVar('rating');
if ( $new_rating !== false && !$res ) {
$rating = $object->GetDBField('CachedRating');
$votes = $object->GetDBField('CachedVotesQty');
$new_votes = $votes + 1;
$rating = (($rating * $votes) + $new_rating) / $new_votes;
$object->SetDBField('CachedRating', $rating);
$object->SetDBField('CachedVotesQty', $new_votes);
$object->Update();
$expire = adodb_mktime() + $this->Application->ConfigValue('product_ReviewDelay_Value') * $this->Application->ConfigValue('product_ReviewDelay_Interval');
$sql = ' INSERT INTO ' . TABLE_PREFIX . 'SpamControl
(ItemResourceId, IPaddress, PortalUserId, DataType, Expire)
VALUES (' . $object->GetDBField('ResourceId') . ',
"' . $this->Application->getClientIp() . '",
' . $user_id . ',
"Rating",
' . $expire . ')';
$this->Conn->Query($sql);
}
else {
$event->status == kEvent::erFAIL;
$event->redirect = false;
$object->SetError('CachedRating', 'too_frequent', 'lu_ferror_rate_duplicate');
}
}
/**
* Enter description here...
*
* @param kEvent $event
*/
function OnCancelAction($event)
{
$event->SetRedirectParam('pass', 'all,p');
$event->redirect = $this->Application->GetVar('cancel_template');
}
/**
* Enter description here...
*
* @param kEvent $event
*/
function OnRecommendProduct($event)
{
// used for error reporting only -> rewrite code + theme (by Alex)
$object = $this->Application->recallObject('u', null, Array('skip_autoload' => true)); // TODO: change theme too
/* @var $object kDBItem */
$friend_email = $this->Application->GetVar('friend_email');
$friend_name = $this->Application->GetVar('friend_name');
$my_email = $this->Application->GetVar('your_email');
$my_name = $this->Application->GetVar('your_name');
$my_message = $this->Application->GetVar('your_message');
$send_params = array();
$send_params['to_email']=$friend_email;
$send_params['to_name']=$friend_name;
$send_params['from_email']=$my_email;
$send_params['from_name']=$my_name;
$send_params['message']=$my_message;
if ( preg_match('/' . REGEX_EMAIL_USER . '@' . REGEX_EMAIL_DOMAIN . '/', $friend_email) ) {
$user_id = $this->Application->RecallVar('user_id');
$email_sent = $this->Application->emailUser('PRODUCT.SUGGEST', $user_id, $send_params);
$this->Application->emailAdmin('PRODUCT.SUGGEST');
if ( $email_sent ) {
$event->setRedirectParams(Array ('opener' => 's', 'pass' => 'all'));
$event->redirect = $this->Application->GetVar('template_success');
}
else {
// $event->setRedirectParams(Array('opener' => 's', 'pass' => 'all'));
// $event->redirect = $this->Application->GetVar('template_fail');
$object->SetError('Email', 'send_error', 'lu_email_send_error');
$event->status = kEvent::erFAIL;
}
}
else {
$object->SetError('Email', 'invalid_email', 'lu_InvalidEmail');
$event->status = kEvent::erFAIL;
}
}
/**
* Creates/updates virtual product based on listing type data
*
* @param kEvent $event
*/
function OnSaveVirtualProduct($event)
{
$object = $event->getObject( Array('skip_autoload' => true) );
$listing_type = $this->Application->recallObject('lst', null, Array('skip_autoload' => true));
$listing_type->Load($event->MasterEvent->getEventParam('id'));
$product_id = $listing_type->GetDBField('VirtualProductId');
if ($product_id) {
$object->Load($product_id);
}
if (!$listing_type->GetDBField('EnableBuying')) {
if ($product_id) {
// delete virtual product here
$temp_handler = $this->Application->recallObject($event->getPrefixSpecial().'_TempHandler', 'kTempTablesHandler');
$temp_handler->DeleteItems($event->Prefix, $event->Special, Array($product_id));
$listing_type->SetDBField('VirtualProductId', 0);
$listing_type->Update();
}
return true;
}
$ml_formatter = $this->Application->recallObject('kMultiLanguage');
$object->SetDBField($ml_formatter->LangFieldName('Name'), $listing_type->GetDBField('ShopCartName') );
$object->SetDBField($ml_formatter->LangFieldName('Description'), $listing_type->GetDBField('Description'));
$object->SetDBField('SKU', 'ENHANCE_LINK_'.abs( crc32( $listing_type->GetDBField('Name') ) ) );
if ($product_id) {
$object->Update();
}
else {
$object->SetDBField('Type', 2);
$object->SetDBField('Status', 1);
$object->SetDBField('HotItem', 0);
$object->SetDBField('PopItem', 0);
$object->SetDBField('NewItem', 0);
$object->SetDBField('Virtual', 1);
// $processing_data = Array('ApproveEvent' => 'ls:EnhanceLinkAfterOrderApprove', 'ExpireEvent' => 'ls:ExpireLink');
$processing_data = Array( 'ApproveEvent' => 'ls:EnhanceLinkAfterOrderApprove',
'DenyEvent' => 'ls:EnhanceLinkAfterOrderDeny',
'CompleteOrderEvent' => 'ls:EnhancedLinkOnCompleteOrder',
'ExpireEvent' => 'ls:ExpireLink',
'HasNewProcessing' => 1);
$object->SetDBField('ProcessingData', serialize($processing_data));
$object->Create();
$listing_type->SetDBField('VirtualProductId', $object->GetID());
$listing_type->Update();
}
$additiona_fields = Array( 'AccessDuration' => $listing_type->GetDBField('Duration'),
'AccessUnit' => $listing_type->GetDBField('DurationType'),
);
$this->setPrimaryPrice($object->GetID(), (double)$listing_type->GetDBField('Price'), $additiona_fields);
}
/**
* [HOOK] Deletes virtual product when listing type is deleted
*
* @param kEvent $event
*/
function OnDeleteListingType($event)
{
$listing_type = $event->MasterEvent->getObject();
/* @var $listing_type kDBItem */
$product_id = $listing_type->GetDBField('VirtualProductId');
if ( $product_id ) {
$temp_handler = $this->Application->recallObject($event->getPrefixSpecial() . '_TempHandler', 'kTempTablesHandler');
$temp_handler->DeleteItems($event->Prefix, $event->Special, Array ($product_id));
}
}
/**
* Extends user membership in group when his order is approved
*
* @param kEvent $event
*/
function OnSubscriptionApprove($event)
{
$field_values = $event->getEventParam('field_values');
$item_data = unserialize($field_values['ItemData']);
if ( !getArrayValue($item_data,'PortalGroupId') ) {
// is subscription product, but no group defined in it's properties
trigger_error('Invalid product <b>'.$field_values['ProductName'].'</b> (id: '.$field_values['ProductId'].')', E_USER_WARNING);
return false;
}
+ $orders_config = $this->Application->getUnitConfig('ord');
+
$sql = 'SELECT PortalUserId
- FROM ' . $this->Application->getUnitOption('ord', 'TableName') . '
- WHERE ' . $this->Application->getUnitOption('ord', 'IDField') . ' = ' . $field_values['OrderId'];
+ FROM ' . $orders_config->getTableName() . '
+ WHERE ' . $orders_config->getIDField() . ' = ' . $field_values['OrderId'];
$user_id = $this->Conn->GetOne($sql);
$group_id = $item_data['PortalGroupId'];
$duration = $item_data['Duration'];
$sql = 'SELECT *
FROM ' . TABLE_PREFIX . 'UserGroupRelations
WHERE PortalUserId = ' . $user_id;
$user_groups = $this->Conn->Query($sql, 'GroupId');
if ( !isset($user_groups[$group_id]) ) {
$expire = adodb_mktime() + $duration;
}
else {
$expire = $user_groups[$group_id]['MembershipExpires'];
$expire = $expire < adodb_mktime() ? adodb_mktime() + $duration : $expire + $duration;
}
/*// Customization healtheconomics.org
if ($item_data['DurationType'] == 2) {
$expire = $item_data['AccessExpiration'];
}
// Customization healtheconomics.org --*/
$fields_hash = Array (
'PortalUserId' => $user_id,
'GroupId' => $group_id,
'MembershipExpires' => $expire,
);
$this->Conn->doInsert($fields_hash, TABLE_PREFIX . 'UserGroupRelations', 'REPLACE');
$sub_order = $this->Application->recallObject('ord.-sub'.$event->getEventParam('next_sub_number'), 'ord');
$sub_order->SetDBField('IsRecurringBilling', getArrayValue($item_data, 'IsRecurringBilling') ? 1 : 0);
$sub_order->SetDBField('GroupId', $group_id);
$sub_order->SetDBField('NextCharge_date', $expire);
$sub_order->SetDBField('NextCharge_time', $expire);
}
- function OnDownloadableApprove($event)
+ function OnDownloadableApprove(kEvent $event)
{
$field_values = $event->getEventParam('field_values');
$product_id = $field_values['ProductId'];
- $sql = 'SELECT PortalUserId FROM '.$this->Application->getUnitOption('ord', 'TableName').'
+ $sql = 'SELECT PortalUserId FROM '.$this->Application->getUnitConfig('ord')->getTableName().'
WHERE OrderId = '.$field_values['OrderId'];
$user_id = $this->Conn->GetOne($sql);
$sql = 'INSERT INTO '.TABLE_PREFIX.'UserFileAccess VALUES("", '.$product_id.', '.$user_id.')';
$this->Conn->Query($sql);
}
- protected function OnPackageApprove(kEvent $event)
- {
+ function OnPackageApprove(kEvent $event){
$field_values = $event->getEventParam('field_values');
$item_data = unserialize($field_values['ItemData']);
$package_content_ids = $item_data['PackageContent'];
$object_item = $this->Application->recallObject('p.packageitem', null, array ('skip_autoload' => true));
/* @var $object_item ProductsItem */
foreach ($package_content_ids as $package_item_id) {
- $object_field_values = array ();
+ $object_field_values = array();
- // query processing data from product and run approve event
+ // query processing data from product and run approve event
$sql = 'SELECT ProcessingData
FROM ' . TABLE_PREFIX . 'Products
WHERE ProductId = ' . $package_item_id;
$processing_data = $this->Conn->GetOne($sql);
if ( $processing_data ) {
$processing_data = unserialize($processing_data);
$approve_event = new kEvent($processing_data['ApproveEvent']);
//$order_item_fields = $this->Conn->GetRow('SELECT * FROM '.TABLE_PREFIX.'OrderItems WHERE OrderItemId = '.$grouping_data[1]);
$object_item->Load($package_item_id);
$object_field_values['OrderId'] = $field_values['OrderId'];
$object_field_values['ProductId'] = $package_item_id;
$object_field_values['ItemData'] = serialize($item_data['PackageItemsItemData'][$package_item_id]);
$approve_event->setEventParam('field_values', $object_field_values);
$this->Application->HandleEvent($approve_event);
}
}
}
/**
* Saves edited item into temp table
* If there is no id, new item is created in temp table
*
* @param kEvent $event
* @return void
* @access protected
*/
protected function OnPreSave(kEvent $event)
{
$this->CheckRequiredOptions($event);
parent::OnPreSave($event);
}
/**
* Set new price to ProductsPricing
*
* @param kEvent $event
* @return void
* @access protected
*/
protected function OnAfterItemCreate(kEvent $event)
{
parent::OnAfterItemCreate($event);
$this->_updateProductPrice($event);
}
/**
* Set new price to ProductsPricing
*
* @param kEvent $event
* @return void
* @access protected
*/
protected function OnAfterItemUpdate(kEvent $event)
{
parent::OnAfterItemUpdate($event);
$this->_updateProductPrice($event);
}
/**
* Updates product's primary price based on Price virtual field value
*
* @param kEvent $event
*/
function _updateProductPrice($event)
{
$object = $event->getObject();
/* @var $object kDBItem */
$price = $object->GetDBField('Price');
// always create primary pricing, to show on Pricing tab (in admin) for tangible products
$force_create = ($object->GetDBField('Type') == PRODUCT_TYPE_TANGIBLE) && is_null($price);
if ($force_create || ($price != $object->GetOriginalField('Price'))) {
// new product OR price was changed in virtual field
$this->setPrimaryPrice($object->GetID(), (float)$price);
}
}
function CheckRequiredOptions($event)
{
$object = $event->getObject();
if ($object->GetDBField('ProductId') == '') return ; // if product does not have ID - it's not yet created
$opt_object = $this->Application->recallObject('po', null, Array('skip_autoload' => true) );
$has_required = $this->Conn->GetOne('SELECT COUNT(*) FROM '.$opt_object->TableName.' WHERE Required = 1 AND ProductId = '.$object->GetDBField('ProductId'));
//we need to imitate data sumbit, as parent' PreSave sets object values from $items_info
$items_info = $this->Application->GetVar( $event->getPrefixSpecial(true) );
$items_info[$object->GetDBField('ProductId')]['HasRequiredOptions'] = $has_required ? '1' : '0';
$this->Application->SetVar($event->getPrefixSpecial(true), $items_info);
$object->SetDBField('HasRequiredOptions', $has_required ? 1 : 0);
}
/**
* Sets required price in primary price backed, if it's missing, then create it
*
* @param int $product_id
* @param double $price
* @param Array $additional_fields
* @return bool
*/
function setPrimaryPrice($product_id, $price, $additional_fields = Array())
{
$pr_object = $this->Application->recallObject('pr.-item', null, Array('skip_autoload' => true) );
/* @var $pr_object kDBItem */
$pr_object->Load( Array('ProductId' => $product_id, 'IsPrimary' => 1) );
$sql = 'SELECT COUNT(*) FROM '.$pr_object->TableName.' WHERE ProductId = '.$product_id;
$has_pricings = $this->Conn->GetOne($sql);
if ($additional_fields) {
$pr_object->SetDBFieldsFromHash($additional_fields);
}
if( ($price === false) && $has_pricings ) return false;
if( $pr_object->isLoaded() )
{
$pr_object->SetField('Price', $price);
return $pr_object->Update();
}
else
{
$group_id = $this->Application->ConfigValue('User_LoggedInGroup');
$field_values = Array('ProductId' => $product_id, 'IsPrimary' => 1, 'MinQty' => 1, 'MaxQty' => -1, 'GroupId'=>$group_id);
$pr_object->SetDBFieldsFromHash($field_values);
$pr_object->SetField('Price', $price);
return $pr_object->Create();
}
}
/**
* Occurs after deleting item, id of deleted item
* is stored as 'id' param of event
*
* @param kEvent $event
* @return void
* @access protected
*/
protected function OnAfterItemDelete(kEvent $event)
{
parent::OnAfterItemDelete($event);
$product_id = $event->getEventParam('id');
if ( !$product_id ) {
return;
}
$sql = 'DELETE FROM ' . TABLE_PREFIX . 'UserFileAccess
WHERE ProductId = ' . $product_id;
$this->Conn->Query($sql);
}
/**
* Load price from temp table if product mode is temp table
*
* @param kEvent $event
*/
/**
* Load price from temp table if product mode is temp table
*
* @param kEvent $event
* @return void
* @access protected
*/
protected function OnAfterItemLoad(kEvent $event)
{
parent::OnAfterItemLoad($event);
$object = $event->getObject();
/* @var $object ProductsItem */
$a_pricing = $object->getPrimaryPricing();
if ( !$a_pricing ) {
// pricing doesn't exist for new products
$price = $cost = null;
}
else {
$price = (float)$a_pricing['Price'];
$cost = (float)$a_pricing['Cost'];
}
// set original fields to use them in OnAfterItemCreate/OnAfterItemUpdate later
$object->SetDBField('Price', $price);
$object->SetOriginalField('Price', $price);
$object->SetDBField('Cost', $cost);
$object->SetOriginalField('Cost', $cost);
}
/**
* Allows to add products to package besides all that parent method does
*
* @param kEvent $event
*/
function OnProcessSelected($event)
{
$dst_field = $this->Application->RecallVar('dst_field');
if ($dst_field == 'PackageContent') {
$this->OnAddToPackage($event);
}
elseif ($dst_field == 'AssignedCoupon') {
$coupon_id = $this->Application->GetVar('selected_ids');
$object = $event->getObject();
$object->SetDBField('AssignedCoupon', $coupon_id);
$this->RemoveRequiredFields($object);
$object->Update();
}
else {
parent::OnProcessSelected($event);
}
$this->finalizePopup($event);
}
/**
* Called when some products are selected in products selector for this prefix
*
* @param kEvent $event
*/
function OnAddToPackage($event)
{
$selected_ids = $this->Application->GetVar('selected_ids');
// update current package content with selected products
$object = $event->getObject();
/* @var $object ProductsItem */
$product_ids = $selected_ids['p'] ? explode(',', $selected_ids['p']) : Array();
if ($product_ids) {
$current_ids = $object->GetPackageContentIds();
$current_ids = array_unique(array_merge($current_ids, $product_ids));
// remove package product from selected list
$this_product = array_search($object->GetID(), $current_ids);
if ($this_product !== false) {
unset($current_ids[$this_product]);
}
$dst_field = $this->Application->RecallVar('dst_field');
$object->SetDBField($dst_field, '|'.implode('|', $current_ids).'|');
$object->Update();
$this->ProcessPackageItems($event);
}
$this->finalizePopup($event);
}
function ProcessPackageItems(kEvent $event)
{
//$this->Application->SetVar('p_mode', 't');
$object = $event->getObject();
/* @var $object ProductsItem */
$content_ids = $object->GetPackageContentIds();
if (sizeof($content_ids) > 0) {
$total_weight = $this->Conn->GetOne('SELECT SUM(Weight) FROM '.TABLE_PREFIX.'Products WHERE ProductId IN ('.implode(', ', $content_ids).') AND Type=1');
if (!$total_weight) $total_weight = 0;
$this->Conn->Query('UPDATE '.$object->TableName.' SET Weight='.$total_weight.' WHERE ProductId='.$object->GetID());
}
/*
$this->Application->SetVar('p_mode', false);
$list = $this->Application->recallObject('p.content', 'p_List', array('types'=>'content'));
$this->Application->SetVar('p_mode', 't');
$list->Query();
$total_weight_a = 0;
$total_weight_b = 0;
$list->GoFirst();
while (!$list->EOL())
{
if ($list->GetDBField('Type')==1){
$total_weight_a += $list->GetField('Weight_a');
$total_weight_b += $list->GetField('Weight_b');
}
$list->GoNext();
}
$object->SetField('Weight_a', $total_weight_a);
$object->SetField('Weight_b', $total_weight_b);
*/
//$object->Update();
}
/**
* Enter description here...
*
* @param kEvent $event
*/
function OnSaveItems($event)
{
//$event->CallSubEvent('OnUpdate');
$event->redirect = false;
//$event->setRedirectParams(Array ('opener' => 's', 'pass' => 'all,p'));
}
/**
* Removes product from package
*
* @param kEvent $event
*/
function OnRemovePackageItem($event) {
$this->Application->SetVar('p_mode', 't');
$object = $event->getObject();
$items_info = $this->Application->GetVar('p_content');
if($items_info)
{
$product_ids = array_keys($items_info);
$current_ids = $object->GetPackageContentIds();
$current_ids_flip = array_flip($current_ids);
foreach($product_ids as $key=>$val){
unset($current_ids_flip[$val]);
}
$current_ids = array_keys($current_ids_flip);
$current_ids_str = '|'.implode('|', array_unique($current_ids)).'|';
$object->SetDBField('PackageContent', $current_ids_str);
}
$object->Update();
$this->ProcessPackageItems($event);
}
/**
* Occurs before deleting item, id of item being
* deleted is stored as 'id' event param
*
* @param kEvent $event
* @return void
* @access protected
*/
protected function OnBeforeItemDelete(kEvent $event)
{
parent::OnBeforeItemDelete($event);
$object = $event->getObject();
/* @var $object kDBItem */
$sql = 'SELECT COUNT(*)
FROM ' . TABLE_PREFIX . 'Products
WHERE PackageContent LIKE "%|' . $object->GetID() . '%"';
$product_includes_in = $this->Conn->GetOne($sql);
if ( $product_includes_in > 0 ) {
$event->status = kEvent::erFAIL;
}
}
/**
* Returns specific to each item type columns only
*
* @param kEvent $event
* @return Array
* @access protected
*/
public function getCustomExportColumns(kEvent $event)
{
$columns = parent::getCustomExportColumns($event);
$new_columns = Array (
'__VIRTUAL__Price' => 'Price',
'__VIRTUAL__Cost' => 'Cost',
);
return array_merge($columns, $new_columns);
}
/**
* Sets non standart virtual fields (e.g. to other tables)
*
* @param kEvent $event
*/
function setCustomExportColumns($event)
{
parent::setCustomExportColumns($event);
$object = $event->getObject();
/* @var $object kDBItem */
$this->setPrimaryPrice($object->GetID(), (double)$object->GetDBField('Price'), Array ('Cost' => (double)$object->GetDBField('Cost')));
}
function OnPreSaveAndOpenPopup($event)
{
$object = $event->getObject();
/* @var $object kDBItem */
$this->RemoveRequiredFields($object);
$event->CallSubEvent('OnPreSave');
$event->redirect = $this->Application->GetVar('t');
// pass ID too, in case if product is created by OnPreSave call to ensure proper editing
$event->SetRedirectParam('pass', 'all');
$event->SetRedirectParam($event->getPrefixSpecial(true) . '_id', $object->GetID());
}
/**
* Returns ID of current item to be edited
* by checking ID passed in get/post as prefix_id
* or by looking at first from selected ids, stored.
* Returned id is also stored in Session in case
* it was explicitly passed as get/post
*
* @param kEvent $event
* @return int
* @access public
*/
public function getPassedID(kEvent $event)
{
if ( $this->Application->isAdminUser ) {
$event->setEventParam('raise_warnings', 0);
}
$passed = parent::getPassedID($event);
if ( $passed ) {
return $passed;
}
if ( $this->Application->isAdminUser ) {
// we may get product id out of OrderItem, if it exists
$ord_item = $this->Application->recallObject('orditems', null, Array ('raise_warnings' => 0));
/* @var $ord_item OrdersItem */
if ( $ord_item->GetDBField('ProductId') ) {
$passed = $ord_item->GetDBField('ProductId');
}
}
return $passed;
}
/**
* Occurs, when config was parsed, allows to change config data dynamically
*
* @param kEvent $event
* @return void
* @access protected
*/
protected function OnAfterConfigRead(kEvent $event)
{
parent::OnAfterConfigRead($event);
if (!$this->Application->LoggedIn()) {
return ;
}
$user_id = $this->Application->RecallVar('user_id');
$sql = 'SELECT PrimaryGroupId
FROM ' . TABLE_PREFIX . 'Users
WHERE PortalUserId = ' . $user_id;
$primary_group_id = $this->Conn->GetOne($sql);
if (!$primary_group_id) {
return;
}
$sub_select = ' SELECT pp.Price
FROM ' . TABLE_PREFIX . 'ProductsPricing AS pp
WHERE pp.ProductId = %1$s.ProductId AND GroupId = ' . $primary_group_id . '
ORDER BY MinQty
LIMIT 0,1';
- $calculated_fields = $this->Application->getUnitOption($event->Prefix, 'CalculatedFields');
- $calculated_fields['']['Price'] = 'IFNULL((' . $sub_select . '), ' . $calculated_fields['']['Price'] . ')';
- $this->Application->setUnitOption($event->Prefix, 'CalculatedFields', $calculated_fields);
+ $config = $event->getUnitConfig();
+
+ $calculated_fields = $config->getCalculatedFieldsBySpecial('');
+ $calculated_fields['Price'] = 'IFNULL((' . $sub_select . '), ' . $calculated_fields['Price'] . ')';
+ $config->setCalculatedFieldsBySpecial('', $calculated_fields);
}
/**
* Starts product editing, remove any pending inventory actions
*
* @param kEvent $event
* @return void
* @access protected
*/
protected function OnEdit(kEvent $event)
{
$this->Application->RemoveVar('inventory_actions');
parent::OnEdit($event);
}
/**
* Adds "Shop Cart" tab on paid listing type editing tab
*
* @param kEvent $event
*/
function OnModifyPaidListingConfig($event)
{
- $edit_tab_presets = $this->Application->getUnitOption($event->MasterEvent->Prefix, 'EditTabPresets');
- $edit_tab_presets['Default']['shopping_cart'] = Array ('title' => 'la_tab_ShopCartEntry', 't' => 'in-commerce/paid_listings/paid_listing_type_shopcart', 'priority' => 2);
- $this->Application->setUnitOption($event->MasterEvent->Prefix, 'EditTabPresets', $edit_tab_presets);
+ $event->MasterEvent->getUnitConfig()->addEditTabPresetTabs('Default', Array (
+ 'shopping_cart' => Array ('title' => 'la_tab_ShopCartEntry', 't' => 'in-commerce/paid_listings/paid_listing_type_shopcart', 'priority' => 2),
+ ));
}
/**
* [HOOK] Allows to add cloned subitem to given prefix
*
* @param kEvent $event
* @return void
* @access protected
*/
protected function OnCloneSubItem(kEvent $event)
{
parent::OnCloneSubItem($event);
if ( $event->MasterEvent->Prefix == 'rev' ) {
- $clones = $this->Application->getUnitOption($event->MasterEvent->Prefix, 'Clones');
- $subitem_prefix = $event->Prefix . '-' . $event->MasterEvent->Prefix;
+ $sub_item_prefix = $event->Prefix . '-' . $event->MasterEvent->Prefix;
- $clones[$subitem_prefix]['ConfigMapping'] = Array (
+ $event->MasterEvent->getUnitConfig()->addClones(Array (
+ $sub_item_prefix => Array (
+ 'ConfigMapping' => Array (
'PerPage' => 'Comm_Perpage_Reviews',
'ReviewDelayInterval' => 'product_ReviewDelay_Value',
'ReviewDelayValue' => 'product_ReviewDelay_Interval',
- );
-
- $this->Application->setUnitOption($event->MasterEvent->Prefix, 'Clones', $clones);
+ ),
+ ),
+ ));
}
}
/**
* Adds product to comparison list
*
* @param kEvent $event
* @return void
* @access protected
*/
protected function OnAddToCompare(kEvent $event)
{
$products = $this->getCompareProducts();
$product_id = (int)$this->Application->GetVar($event->Prefix . '_id');
if ( $product_id ) {
$max_products = $this->Application->ConfigValue('MaxCompareProducts');
if ( count($products) < $max_products ) {
$products[] = $product_id;
$this->Application->Session->SetCookie('compare_products', implode('|', array_unique($products)));
$event->SetRedirectParam('result', 'added');
}
else {
$event->SetRedirectParam('result', 'error');
}
}
$event->SetRedirectParam('pass', 'm,p');
}
/**
* Adds product to comparison list
*
* @param kEvent $event
* @return void
* @access protected
*/
protected function OnRemoveFromCompare(kEvent $event)
{
$products = $this->getCompareProducts();
$product_id = (int)$this->Application->GetVar($event->Prefix . '_id');
if ( $product_id && in_array($product_id, $products) ) {
$products = array_diff($products, Array ($product_id));
$this->Application->Session->SetCookie('compare_products', implode('|', array_unique($products)));
$event->SetRedirectParam('result', 'removed');
}
$event->SetRedirectParam('pass', 'm,p');
}
/**
* Cancels product compare
*
* @param kEvent $event
* @return void
* @access protected
*/
protected function OnCancelCompare(kEvent $event)
{
$this->Application->Session->SetCookie('compare_products', '', -1);
$event->SetRedirectParam('result', 'all_removed');
}
/**
* Returns products, that needs to be compared with each other
*
* @return Array
* @access protected
*/
protected function getCompareProducts()
{
$products = $this->Application->GetVarDirect('compare_products', 'Cookie');
$products = $products ? explode('|', $products) : Array ();
return $products;
}
}
\ No newline at end of file
Index: branches/5.3.x/units/products/products_item.php
===================================================================
--- branches/5.3.x/units/products/products_item.php (revision 15694)
+++ branches/5.3.x/units/products/products_item.php (revision 15695)
@@ -1,85 +1,85 @@
<?php
/**
* @version $Id$
* @package In-Commerce
* @copyright Copyright (C) 1997 - 2009 Intechnic. All rights reserved.
* @license Commercial License
* This software 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
* See http://www.in-portal.org/commercial-license for copyright notices and details.
*/
defined('FULL_PATH') or die('restricted access!');
class ProductsItem extends kCatDBItem
{
function GetPackageContentIds()
{
$ids_string = trim($this->GetDBField('PackageContent'), '|');
if ($ids_string) {
$ids_array = explode('|', $ids_string);
return $ids_array;
}
else {
return array();
}
}
/**
* Returns field values from primary pricing for product
*
* @return array
*/
function getPrimaryPricing()
{
// product + pricing based
$cache_key = 'product_primary_pricing[%PIDSerial:' . $this->GetID() . '%][%PrIDSerial:ProductId:' . $this->GetID() . '%]';
if (!$this->Application->isAdmin && $this->Application->LoggedIn()) {
// also group based
$primary_group = (int)$this->Application->Session->GetField('GroupId');
$cache_key .= ':group=' . $primary_group;
}
// don't cache, while in temp table
$price_info = $this->IsTempTable() ? false : $this->Application->getCache($cache_key);
if ($price_info === false) {
if (!$this->Application->isAdmin && $this->Application->LoggedIn()) {
// logged in user on front-end
$this->Conn->nextQueryCachable = true;
$sql = 'SELECT Price, Cost
FROM ' . TABLE_PREFIX . 'ProductsPricing
WHERE (ProductId = ' . $this->GetID() . ') AND (GroupId = ' . $primary_group . ')
ORDER BY MinQty';
$price_info = $this->Conn->GetRow($sql);
if ($price_info !== false) {
$this->Application->setCache($cache_key, $price_info);
return $price_info;
}
}
// not logged-in user on front-end or in administrative console
- $pr_table = $this->Application->getUnitOption('pr', 'TableName');
+ $pr_table = $this->Application->getUnitConfig('pr')->getTableName();
if ($this->IsTempTable()) {
$pr_table = $this->Application->GetTempName($pr_table, 'prefix:' . $this->Prefix);
}
$this->Conn->nextQueryCachable = true;
$sql = 'SELECT Price, Cost
FROM ' . $pr_table . '
WHERE (' . $this->IDField . ' = ' . $this->GetID() . ') AND (IsPrimary = 1)';
$price_info = $this->Conn->GetRow($sql);
$this->Application->setCache($cache_key, $price_info);
}
return $price_info;
}
}
\ No newline at end of file
Index: branches/5.3.x/units/coupon_items/coupon_items_tag_processor.php
===================================================================
--- branches/5.3.x/units/coupon_items/coupon_items_tag_processor.php (revision 15694)
+++ branches/5.3.x/units/coupon_items/coupon_items_tag_processor.php (revision 15695)
@@ -1,48 +1,53 @@
<?php
/**
* @version $Id$
* @package In-Commerce
* @copyright Copyright (C) 1997 - 2009 Intechnic. All rights reserved.
* @license Commercial License
* This software 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
* See http://www.in-portal.org/commercial-license for copyright notices and details.
*/
defined('FULL_PATH') or die('restricted access!');
class CouponItemsTagProcessor extends kDBTagProcessor {
function IsEntireOrder($params)
{
- $table_name = $this->Application->getUnitOption($this->Prefix, 'TableName');
+ $table_name = $this->getUnitConfig()->getTableName();
- if ($this->Application->IsTempMode($this->Prefix)) {
+ 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 (CouponId = ' . $this->Application->GetVar('coup_id') . ')';
+
return $this->Conn->GetOne($sql);
}
function ItemIcon($params)
{
$object = $this->getObject($params);
/* @var $object kDBList */
- if ($object->GetDBField('ItemType') == 2) {
+ if ( $object->GetDBField('ItemType') == 2 ) {
$cat_object = $this->Application->recallObject('c');
- $cat_object->Load( $object->GetDBField('CategoryId') );
+ /* @var $cat_object CategoriesItem */
+
+ $cat_object->Load($object->GetDBField('CategoryId'));
+
$cat_tag_processor = $this->Application->recallObject('c_TagProcessor');
+ /* @var $cat_tag_processor CategoriesTagProcessor */
- return $cat_tag_processor->ItemIcon();
+ return $cat_tag_processor->ItemIcon($params);
}
return parent::ItemIcon($params);
}
}
\ No newline at end of file
Index: branches/5.3.x/units/coupon_items/coupon_items_event_handler.php
===================================================================
--- branches/5.3.x/units/coupon_items/coupon_items_event_handler.php (revision 15694)
+++ branches/5.3.x/units/coupon_items/coupon_items_event_handler.php (revision 15695)
@@ -1,111 +1,110 @@
<?php
/**
* @version $Id$
* @package In-Commerce
* @copyright Copyright (C) 1997 - 2009 Intechnic. All rights reserved.
* @license Commercial License
* This software 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
* See http://www.in-portal.org/commercial-license for copyright notices and details.
*/
defined('FULL_PATH') or die('restricted access!');
class CouponItemsEventHandler extends kDBEventHandler {
/**
* Allows to override standard permission mapping
*
* @return void
* @access protected
* @see kEventHandler::$permMapping
*/
protected function mapPermissions()
{
parent::mapPermissions();
$permissions = Array (
'OnEntireOrder' => Array ('subitem' => 'add|edit'),
);
$this->permMapping = array_merge($this->permMapping, $permissions);
}
/**
* Adds products from selected categories and their sub-categories and directly selected products to coupon items with duplicate checking
*
* @param kEvent $event
*/
function OnProcessSelected($event)
{
// uses another handler event, because does the same stuff but on different table
$di_handler = $this->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 CouponId='.$this->Application->GetVar('coup_id');
$this->Conn->Query($sql);
$object->SetDBField('CouponId', $this->Application->GetVar('coup_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 OnDeleteCouponItem($event)
{
$main_object = $event->MasterEvent->getObject();
- $resource_id = $main_object->GetDBField('ResourceId');
+ /* @var $main_object kDBItem */
- $table = $this->Application->getUnitOption($event->Prefix,'TableName');
- $sql = 'DELETE FROM '.$table.' WHERE ItemResourceId = '.$resource_id;
+ $sql = 'DELETE FROM ' . $event->getUnitConfig()->getTableName() . '
+ WHERE ItemResourceId = ' . $main_object->GetDBField('ResourceId');
$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);
+ $event->getUnitConfig()->addCalculatedFieldsBySpecial('', Array (
+ 'ItemName' => 'COALESCE(p.l' . $language_id . '_Name, p.l' . $primary_language_id . '_Name)'
+ ));
}
}
\ No newline at end of file
Index: branches/5.3.x/units/affiliates/affiliates_event_handler.php
===================================================================
--- branches/5.3.x/units/affiliates/affiliates_event_handler.php (revision 15694)
+++ branches/5.3.x/units/affiliates/affiliates_event_handler.php (revision 15695)
@@ -1,663 +1,667 @@
<?php
/**
* @version $Id$
* @package In-Commerce
* @copyright Copyright (C) 1997 - 2009 Intechnic. All rights reserved.
* @license Commercial License
* This software 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
* See http://www.in-portal.org/commercial-license for copyright notices and details.
*/
defined('FULL_PATH') or die('restricted access!');
class AffiliatesEventHandler extends kDBEventHandler {
/**
* Allows to override standard permission mapping
*
* @return void
* @access protected
* @see kEventHandler::$permMapping
*/
protected function mapPermissions()
{
parent::mapPermissions();
$permissions = Array (
'OnItemBuild' => Array ('self' => true),
);
$this->permMapping = array_merge($this->permMapping, $permissions);
}
/**
* Checks user permission to execute given $event
*
* @param kEvent $event
* @return bool
* @access public
*/
public function CheckPermission(kEvent $event)
{
if ( $event->Name == 'OnBecomeAffiliate' || $event->Name == 'OnChangePaymentType' ) {
return $this->Application->LoggedIn() && $this->Application->ConfigValue('Comm_RegisterAsAffiliate');
}
return parent::CheckPermission($event);
}
/**
* Allows to get ID of affiliate record, associated with currently logged-in user
*
* @param kEvent $event
* @return int
* @access public
*/
public function getPassedID(kEvent $event)
{
if ( $event->Special == 'user' ) {
+ $config = $event->getUnitConfig();
$event->setEventParam('raise_warnings', 0);
- $sql = 'SELECT ' . $this->Application->getUnitOption($event->Prefix, 'IDField') . '
- FROM ' . $this->Application->getUnitOption($event->Prefix, 'TableName') . '
+ $sql = 'SELECT ' . $config->getIDField() . '
+ FROM ' . $config->getTableName() . '
WHERE PortalUserId = ' . (int)$this->Application->RecallVar('user_id');
$id = $this->Conn->GetOne($sql);
if ( $id ) {
return $id;
}
}
return parent::getPassedID($event);
}
/**
* Generate new affiliate code
*
* @param kEvent $event
* @return string
*/
function generateAffiliateCode($event)
{
// accepts 1 - 36
$number_length = 11;
$num_chars = Array( '1'=>'a','2'=>'b','3'=>'c','4'=>'d','5'=>'e','6'=>'f',
'7'=>'g','8'=>'h','9'=>'i','10'=>'j','11'=>'k','12'=>'l',
'13'=>'m','14'=>'n','15'=>'o','16'=>'p','17'=>'q','18'=>'r',
'19'=>'s','20'=>'t','21'=>'u','22'=>'v','23'=>'w','24'=>'x',
'25'=>'y','26'=>'z','27'=>'0','28'=>'1','29'=>'2','30'=>'3',
'31'=>'4','32'=>'5','33'=>'6','34'=>'7','35'=>'8','36'=>'9');
$ret = '';
- for($i=1; $i<=$number_length; $i++)
- {
+ for ($i = 1; $i <= $number_length; $i++) {
mt_srand((double)microtime() * 1000000);
$num = mt_rand(1,36);
$ret .= $num_chars[$num];
}
- $ret = strtoupper($ret);
- $id_field = $this->Application->getUnitOption($event->Prefix, 'IDField');
- $table = $this->Application->getUnitOption($event->Prefix, 'TableName');
+ $ret = strtoupper($ret);
- $sql = 'SELECT %s FROM %s WHERE AffiliateCode = %s';
+ $config = $event->getUnitConfig();
+ $id_field = $config->getIDField();
+ $table = $config->getTableName();
+
+ $sql = 'SELECT %s
+ FROM %s
+ WHERE AffiliateCode = %s';
$code_found = $this->Conn->GetOne( sprintf($sql, $id_field, $table, $this->Conn->qstr($ret) ) );
- if($code_found) return $this->generateAffiliateCode($event);
- return $ret;
+ return $code_found ? $this->generateAffiliateCode($event) : $ret;
}
/**
* Creates new affiliate code when new affiliate is created
*
* @param kEvent $event
* @return void
* @access protected
*/
protected function OnBeforeItemCreate(kEvent $event)
{
parent::OnBeforeItemCreate($event);
$object = $event->getObject();
/* @var $object kDBItem */
$object->SetDBField('AffiliateCode', $this->generateAffiliateCode($event));
if ( $object->getFormName() == 'registration' ) {
if ( $this->Application->LoggedIn() ) {
$object->SetDBField('PortalUserId', $this->Application->RecallVar('user_id'));
}
$object->SetDBField('AffiliatePlanId', $this->_getPrimaryAffiliatePlan());
}
}
/**
* Ensures, that user can only update his affiliate record
*
* @param kEvent $event
* @return void
* @access protected
*/
protected function OnBeforeItemUpdate(kEvent $event)
{
parent::OnBeforeItemUpdate($event);
if ( !$this->Application->isAdmin ) {
$object = $event->getObject();
/* @var $object kDBItem */
$object->SetDBField('PortalUserId', $object->GetOriginalField('PortalUserId'));
if ( $object->GetDBField('PortalUserId') != $this->Application->RecallVar('user_id') ) {
$object->SetError('PortalUserId', 'not_owner');
}
}
}
/**
* [HOOK] Stores affiliate id using method from Config (session or cookie) if correct code is present in url
*
* @param kEvent $event
* @return bool
*/
function OnStoreAffiliate($event)
{
if ( defined('IS_INSTALL') && IS_INSTALL ) {
return;
}
$object = $this->Application->recallObject($event->Prefix . '.-item', null, Array ('skip_autoload' => true));
/* @var $object kDBItem */
$affiliate_storage_method = $this->Application->ConfigValue('Comm_AffiliateStorageMethod');
$affiliate = $this->Application->GetVar('affiliate');
if ( $affiliate ) {
$object->Load($affiliate, 'AffiliateCode');
}
elseif ( $affiliate_storage_method == 2 ) {
$affiliate_id = $this->Application->GetVar('affiliate_id');
$object->Load($affiliate_id);
}
if ( $object->isLoaded() && ($object->GetDBField('Status') == 1) ) {
// user is found with such email
$affiliate_user = $this->Application->recallObject('u.affiliate', null, Array ('skip_autoload' => true));
/* @var $affiliate_user UsersItem */
$affiliate_user->Load($object->GetDBField('PortalUserId'));
if ( $affiliate_user->GetDBField('Status') == 1 ) {
$affiliate_id = $object->GetDBField('AffiliateId');
$this->Application->setVisitField('AffiliateId', $affiliate_id);
if ( $affiliate_storage_method == 1 ) {
$this->Application->StoreVar('affiliate_id', $affiliate_id); // per session
}
else {
// in cookie
$this->Application->Session->SetCookie('affiliate_id', $affiliate_id, $this->getCookieExpiration());
}
}
}
}
/**
* Returns affiliate cookie expiration date
*
* @return int
*/
function getCookieExpiration()
{
$expire = $this->Application->ConfigValue('Comm_AffiliateCookieDuration'); // days
return adodb_mktime() + $expire * 24 * 60 * 60;
}
/**
* Calculate what amount is earned by affiliate based on it's affiliate plan & store it
*
* @param kEvent $event
* @author Alex
*/
function OnOrderApprove($event)
{
$order = $this->Application->recallObject($event->getEventParam('Order_PrefixSpecial'));
/* @var $order OrdersItem */
$affiliate_id = $order->GetDBField('AffiliateId');
if ( !$affiliate_id ) {
return false;
}
$object = $event->getObject(Array ('ship_autoload' => true));
/* @var $object kDBItem */
if ( $object->Load($affiliate_id) ) {
$affiliate_plan = $this->Application->recallObject('ap', null, Array ('skip_autoload' => true));
/* @var $affiliate_plan kDBItem */
$affiliate_plan->Load($object->GetDBField('AffiliatePlanId'));
if ( $affiliate_plan->isLoaded() ) {
$sql = 'SELECT SUM(Quantity) FROM %s WHERE OrderId = %s';
- $orderitems_table = $this->Application->getUnitOption('orditems', 'TableName');
+ $orderitems_table = $this->Application->getUnitConfig('orditems')->getTableName();
$items_sold = $this->Conn->GetOne(sprintf($sql, $orderitems_table, $order->GetID()));
$object->SetDBField('AccumulatedAmount', $object->GetDBField('AccumulatedAmount') + $order->GetDBField('TotalAmount'));
$object->SetDBField('ItemsSold', $object->GetDBField('ItemsSold') + $items_sold);
switch ($affiliate_plan->GetDBField('PlanType')) {
case 1: // by amount
$value = $object->GetDBField('AccumulatedAmount');
break;
case 2: // by items sold (count)
$value = $object->GetDBField('ItemsSold');
break;
}
- $apb_table = $this->Application->getUnitOption('apbrackets', 'TableName');
+ $apb_table = $this->Application->getUnitConfig('apbrackets')->getTableName();
$sql = 'SELECT Percent FROM %1$s WHERE (%2$s >= FromAmount) AND ( (%2$s <= ToAmount) OR (ToAmount = -1) ) AND (AffiliatePlanId = %3$s)';
$commission_percent = $this->Conn->GetOne(sprintf($sql, $apb_table, $this->Conn->qstr($value), $affiliate_plan->GetID()));
// process only orders of current affiliate from period start to this order date
$period_ends = $order->GetDBField('OrderDate');
$period_starts = $this->getPeriodStartTS($period_ends, $affiliate_plan->GetDBField('ResetInterval'));
$sql = 'SELECT AffiliateCommission, (SubTotal+ShippingCost+VAT) AS TotalAmount, OrderId
FROM ' . $order->TableName . '
WHERE OrderDate >= %s AND OrderDate <= %s AND AffiliateId = ' . $affiliate_id;
$amount_to_pay_before = 0;
$amount_to_pay_after = 0;
$order_update_sql = 'UPDATE ' . $order->TableName . ' SET AffiliateCommission = %s WHERE ' . $order->IDField . ' = %s';
$orders = $this->Conn->Query(sprintf($sql, $period_starts, $period_ends), 'OrderId');
if ( $orders ) {
foreach ($orders as $order_id => $order_data) {
$amount_to_pay_before += $order_data['AffiliateCommission'];
$commission = $order_data['TotalAmount'] * ($commission_percent / 100);
$this->Conn->Query(sprintf($order_update_sql, $this->Conn->qstr($commission), $order_id));
$amount_to_pay_after += $commission;
}
}
$object->SetDBField('AmountToPay', $object->GetDBField('AmountToPay') - $amount_to_pay_before + $amount_to_pay_after);
$object->SetDBField('LastOrderDate_date', $order->GetDBField('OrderDate_date'));
$object->SetDBField('LastOrderDate_time', $order->GetDBField('OrderDate_time'));
$object->Update();
$order->SetDBField('AffiliateCommission', $commission); // set last commission to this order, because ApproveEvent was called for him
}
}
}
/**
* [HOOK] Validates affiliate fields on user registration form
*
* @param kEvent $event
* @return void
* @access protected
*/
protected function OnValidateAffiliate($event)
{
if ( $this->Application->GetVar('RegisterAsAffiliate') != 'on' || $event->MasterEvent->status != kEvent::erSUCCESS ) {
return;
}
$object = $event->getObject( Array('form_name' => 'registration', 'skip_autoload' => true) );
/* @var $object kDBItem */
$field_values = $this->getSubmittedFields($event);
$object->SetFieldsFromHash($field_values, $this->getRequestProtectedFields($field_values));
$object->setID(0);
if ( !$object->Validate() ) {
$user = $event->MasterEvent->getObject();
/* @var $user kDBItem */
$user->Validate();
$event->MasterEvent->status = kEvent::erFAIL;
}
}
/**
* [AFTER HOOK] to u:OnCreate
*
* @param kEvent $event
*/
function OnRegisterAffiliate($event)
{
if ( $this->Application->GetVar('RegisterAsAffiliate') != 'on' || $event->MasterEvent->status != kEvent::erSUCCESS ) {
return;
}
$object = $event->getObject();
/* @var $object kDBItem */
$user = $event->MasterEvent->getObject();
/* @var $user UsersItem */
$object->SetDBField('PortalUserId', $user->GetID());
if ( $object->Create() ) {
$this->Application->emailUser('AFFILIATE.REGISTER', $user->GetID());
$this->Application->emailAdmin('AFFILIATE.REGISTER');
}
}
/**
* Returns primary affiliate plan
*
* @return int
* @access protected
*/
protected function _getPrimaryAffiliatePlan()
{
$sql = 'SELECT AffiliatePlanId
- FROM ' . $this->Application->getUnitOption('ap', 'TableName') . '
+ FROM ' . $this->Application->getUnitConfig('ap')->getTableName() . '
WHERE IsPrimary = 1';
return (int)$this->Conn->GetOne($sql);
}
/**
* Creates affiliate record for logged-in user
*
* @param kEvent $event
*/
function OnBecomeAffiliate($event)
{
$object = $event->getObject( Array('form_name' => 'registration', 'skip_autoload' => true) );
/* @var $object UsersItem */
$event->CallSubEvent('OnCreate');
if ( $event->status == kEvent::erSUCCESS ) {
$event->SetRedirectParam('opener', 's');
$next_template = $this->Application->GetVar('next_template');
if ( $next_template ) {
$event->redirect = $next_template;
}
}
}
/**
* Change affiliate payment type of affiliate record associated with logged-in user
*
* @param kEvent $event
* @return void
* @access protected
*/
protected function OnChangePaymentType($event)
{
$event->CallSubEvent('OnUpdate');
if ( $event->status == kEvent::erSUCCESS ) {
$object = $event->getObject();
/* @var $object kDBItem */
$this->Application->emailUser('AFFILIATE.PAYMENT.TYPE.CHANGED', $object->GetDBField('PortalUserId'));
$this->Application->emailAdmin('AFFILIATE.PAYMENT.TYPE.CHANGED');
$next_template = $this->Application->GetVar('next_template');
if ( $next_template ) {
$event->redirect = $this->Application->GetVar('next_template');
}
$event->SetRedirectParam('opener', 's');
}
}
/**
* If new payments made, then send email about that
*
* @param kEvent $event
* @return void
* @access protected
*/
protected function OnBeforeDeleteFromLive(kEvent $event)
{
parent::OnBeforeDeleteFromLive($event);
$payment_object = $this->Application->recallObject('apayments', 'apayments', Array ('skip_autoload' => true));
/* @var $payment_object kDBItem */
$id = $event->getEventParam('id');
- $ap_table = $this->Application->getUnitOption('apayments', 'TableName');
+ $ap_table = $this->Application->getUnitConfig('apayments')->getTableName();
$sql = 'SELECT AffiliatePaymentId
FROM ' . $ap_table . '
WHERE AffiliateId = ' . $id;
$live_ids = $this->Conn->GetCol($sql);
$sql = 'SELECT AffiliatePaymentId
FROM ' . $payment_object->TableName . '
WHERE AffiliateId = ' . $id;
$temp_ids = $this->Conn->GetCol($sql);
$new_ids = array_diff($temp_ids, $live_ids);
foreach ($new_ids as $payment_id) {
$payment_object->Load($payment_id);
$this->Application->emailUser('AFFILIATE.PAYMENT', $payment_object->GetDBField('PortalUserId'));
$this->Application->emailAdmin('AFFILIATE.PAYMENT');
}
$object = $event->getObject();
/* @var $object kDBItem */
$passed_id = $event->getEventParam('id');
if ( $object->GetID() != $passed_id ) {
$object->Load($passed_id);
}
$sql = 'SELECT Status
- FROM ' . $this->Application->getUnitOption($event->Prefix, 'TableName') . '
+ FROM ' . $event->getUnitConfig()->getTableName() . '
WHERE ' . $object->IDField . ' = ' . $object->GetID();
$old_status = $this->Conn->GetOne($sql);
if ( $old_status == 2 && $object->GetDBField('Status') == 1 ) {
$this->Application->emailUser('AFFILIATE.REGISTRATION.APPROVED', $object->GetDBField('PortalUserId'));
$this->Application->emailAdmin('AFFILIATE.REGISTRATION.APPROVED');
}
}
/**
* [HOOK] Resets statistics (accumulated amount & items sold) for affiliates based on ResetInterval in their plan
*
* @param kEvent $event
* @author Alex
*/
function OnResetStatistics($event)
{
if ( defined('IS_INSTALL') && IS_INSTALL ) {
return;
}
$intervals = Array (86400 => 'la_day', 604800 => 'la_week', 2628000 => 'la_month', 7884000 => 'la_quartely', 31536000 => 'la_year');
- $affiliates_table = $this->Application->getUnitOption($event->Prefix, 'TableName');
- $affiliate_plan_table = $this->Application->getUnitOption('ap', 'TableName');
+ $affiliates_table = $event->getUnitConfig()->getTableName();
+ $affiliate_plan_table = $this->Application->getUnitConfig('ap')->getTableName();
$base_time = adodb_mktime();
$where_clause = Array ();
foreach ($intervals as $interval_length => $interval_description) {
$start_timestamp = $this->getPeriodStartTS($base_time, $interval_length);
$where_clause[] = 'ap.ResetInterval = ' . $interval_length . ' AND LastOrderDate < ' . $start_timestamp;
}
$sql = 'SELECT AffiliateId
FROM ' . $affiliates_table . ' a
LEFT JOIN ' . $affiliate_plan_table . ' ap ON a.AffiliatePlanId = ap.AffiliatePlanId
WHERE (' . implode(') OR (', $where_clause) . ')';
$affiliate_ids = $this->Conn->GetCol($sql);
if ( !$affiliate_ids ) {
return;
}
if ( defined('DEBUG_MODE') && DEBUG_MODE && $this->Application->isDebugMode() ) {
$this->Application->Debugger->appendHTML('Affiliates Pending Totals Reset: ');
$this->Application->Debugger->dumpVars($affiliate_ids);
}
$fields_hash = Array (
'AccumulatedAmount' => 0,
'ItemsSold' => 0,
'LastOrderDate' => $base_time,
);
$this->Conn->doUpdate($fields_hash, $affiliates_table, 'AffiliateId IN (' . implode(',', $affiliate_ids) . ')');
}
/**
* Returns calendar period start timestamp based on current timestamp ($base_time) and $period_length
*
* @param int $base_time
* @param int $period_length
* @return int
* @author Alex
*/
function getPeriodStartTS($base_time, $period_length)
{
$start_timestamp = 0;
switch ($period_length) {
case 86400: // day
$start_timestamp = adodb_mktime(0, 0, 0, adodb_date('m', $base_time), adodb_date('d', $base_time), adodb_date('Y', $base_time));
break;
case 604800: // week
$day_seconds = 86400;
$first_week_day = $this->Application->ConfigValue('FirstDayOfWeek');
$morning = adodb_mktime(0, 0, 0, adodb_date('m', $base_time), adodb_date('d', $base_time), adodb_date('Y', $base_time));
$week_day = adodb_date('w', $morning);
if ( $week_day == $first_week_day ) {
// if it is already first week day, then don't search for previous week day
$day_diff = 0;
}
else {
// this way, because sunday is 0, but not 7 as it should be
$day_diff = $week_day != 0 ? $week_day - $first_week_day : 7 - $first_week_day;
}
$start_timestamp = $morning - $day_diff * $day_seconds;
break;
case 2628000: // month
$start_timestamp = adodb_mktime(0, 0, 0, adodb_date('m', $base_time), 1, adodb_date('Y', $base_time));
break;
case 7884000: // quartal
$first_quartal_month = (ceil(adodb_date('m', $base_time) / 3) - 1) * 3 + 1;
$start_timestamp = adodb_mktime(0, 0, 0, $first_quartal_month, 1, adodb_date('Y', $base_time));
break;
case 31536000:
$start_timestamp = adodb_mktime(0, 0, 0, 1, 1, adodb_date('Y', $base_time));
break;
}
return $start_timestamp;
}
/**
* Apply same processing to each item being selected in grid
*
* @param kEvent $event
* @return void
* @access protected
*/
protected function iterateItems(kEvent $event)
{
if ( $this->Application->CheckPermission('SYSTEM_ACCESS.READONLY', 1) ) {
$event->status = kEvent::erFAIL;
+
return;
}
$object = $event->getObject(Array ('skip_autoload' => true));
/* @var $object kDBItem */
$ids = $this->StoreSelectedIDs($event);
if ( $ids ) {
- $status_field = $object->getStatusField();
+ $status_field = $event->getUnitConfig()->getStatusField(true);
foreach ($ids as $id) {
$object->Load($id);
switch ($event->Name) {
case 'OnMassApprove':
$object->SetDBField($status_field, 1);
break;
case 'OnMassDecline':
$object->SetDBField($status_field, 0);
break;
case 'OnMassMoveUp':
$object->SetDBField('Priority', $object->GetDBField('Priority') + 1);
break;
case 'OnMassMoveDown':
$object->SetDBField('Priority', $object->GetDBField('Priority') - 1);
break;
}
if ( $object->Update() ) {
switch ($event->Name) {
case 'OnMassApprove':
$this->Application->emailUser('AFFILIATE.REGISTRATION.APPROVED', $object->GetDBField('PortalUserId'));
$this->Application->emailAdmin('AFFILIATE.REGISTRATION.APPROVED');
break;
case 'OnMassDecline':
$this->Application->emailUser('AFFILIATE.REGISTRATION.DENIED', $object->GetDBField('PortalUserId'));
$this->Application->emailAdmin('AFFILIATE.REGISTRATION.DENIED');
break;
}
$event->status = kEvent::erSUCCESS;
$event->SetRedirectParam('opener', 's'); //stay!
}
else {
$event->status = kEvent::erFAIL;
$event->redirect = false;
break;
}
}
}
}
/**
* Checks that user in affiliate record matches current user
* (non permission-based)
*
* @param kEvent $event
* @return bool
* @access protected
*/
protected function checkItemStatus(kEvent $event)
{
if ( $this->Application->isAdminUser ) {
return true;
}
$object = $event->getObject();
/* @var $object kDBItem */
if ( !$object->isLoaded() ) {
return true;
}
return $object->GetDBField('PortalUserId') == $this->Application->RecallVar('user_id');
}
}
\ No newline at end of file
Index: branches/5.3.x/units/order_items/order_items_event_handler.php
===================================================================
--- branches/5.3.x/units/order_items/order_items_event_handler.php (revision 15694)
+++ branches/5.3.x/units/order_items/order_items_event_handler.php (revision 15695)
@@ -1,370 +1,368 @@
<?php
/**
* @version $Id$
* @package In-Commerce
* @copyright Copyright (C) 1997 - 2009 Intechnic. All rights reserved.
* @license Commercial License
* This software 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
* See http://www.in-portal.org/commercial-license for copyright notices and details.
*/
defined('FULL_PATH') or die('restricted access!');
class OrderItemsEventHandler extends kDBEventHandler
{
/**
* Allows to override standard permission mapping
*
* @return void
* @access protected
* @see kEventHandler::$permMapping
*/
protected function mapPermissions()
{
parent::mapPermissions();
$permissions = Array (
'OnItemBuild' => Array ('subitem' => true),
'OnSaveItems' => Array ('subitem' => 'add|edit'),
);
$this->permMapping = array_merge($this->permMapping, $permissions);
}
/**
* Processes item selection from popup item selector
*
* @param kEvent $event
*/
function OnProcessSelected($event)
{
$object = $event->getObject( Array('skip_autoload' => true) );
$selected_ids = $this->Application->GetVar('selected_ids');
$product_ids = $selected_ids['p'];
if ($product_ids) {
//after adding Options Selection during adding products to order in admin, selector is in single mode
// = allows selecting one item at a time, but we leave this code just in case :)
$product_ids = explode(',', $product_ids);
$product_object = $this->Application->recallObject('p.-item', null, array('skip_autoload' => true));
/* @var $product_object ProductsItem */
foreach ($product_ids as $product_id) {
$product_object->Load($product_id);
$sql = 'SELECT COUNT(*)
- FROM ' . $this->Application->getUnitOption('po', 'TableName') . '
+ FROM ' . $this->Application->getUnitConfig('po')->getTableName() . '
WHERE (Required = 1) AND (ProductId = ' . $product_id . ')';
if ( $this->Conn->GetOne($sql) ) {
$url_params = Array (
$event->Prefix . '_event' => 'OnNew',
'p_id' => $product_id,
'm_opener' => 's',
'pass' => 'm,ord,p',
);
$this->Application->EventManager->openerStackPush('in-commerce/orders/order_product_edit', $url_params);
}
else {
$orders_h = $this->Application->recallObject('ord_EventHandler');
/* @var $orders_h OrdersEventHandler */
// 1 for PacakgeNum - temporary solution to overcome splitting into separate sub-orders
// of orders with items added through admin when approving them
$orders_h->AddItemToOrder($event, $product_id, null, 1);
}
}
}
$event->SetRedirectParam('opener', 'u');
}
/**
* Updates subtotal field in order record.
* Only for "Items" tab in "Orders -> Order Edit" in Admin
*
* @param kEvent $event
* @return void
* @access protected
*/
protected function OnUpdate(kEvent $event)
{
$items_info = $this->Application->GetVar($event->getPrefixSpecial(true));
if ( !$items_info ) {
return;
}
$object = $event->getObject(Array ('skip_autoload' => true));
/* @var $object kDBItem */
$table_info = $object->getLinkedInfo();
$main_object = $this->Application->recallObject($table_info['ParentPrefix']);
/* @var $main_object OrdersItem */
foreach ($items_info as $id => $field_values) {
$object->Clear(); // otherwise validation errors will be passed to next object
$object->Load($id);
$object->SetFieldsFromHash($field_values, $this->getRequestProtectedFields($field_values));
$this->customProcessing($event, 'before');
if ( $object->Update($id) ) {
$this->customProcessing($event, 'after');
$event->status = kEvent::erSUCCESS;
}
else {
$oi_string = $object->GetDBField('ProductId') . ':' . $object->GetDBField('OptionsSalt') . ':' . $object->GetDBField('BackOrderFlag');
$field_errors = $object->GetFieldErrors();
foreach ($field_errors as $field => $error_params) {
$error_msg = $object->GetErrorMsg($field);
if ( $error_msg ) {
$main_object->setCheckoutError(OrderCheckoutErrorType::PRODUCT, OrderCheckoutError::FIELD_UPDATE_ERROR, $oi_string . ':' . $field);
}
}
$event->status = kEvent::erFAIL;
$event->redirect = false;
// break;
}
}
if ( $this->Application->GetVar('t') != 'in-commerce/orders/orders_edit_items' ) {
return;
}
$sub_total = $this->getSubTotal($items_info);
if ( $sub_total !== false ) {
$main_object->SetDBField('SubTotal', $sub_total);
}
$main_object->SetDBField('ReturnTotal', $this->getReturnTotal($items_info));
$main_object->Update();
}
/**
* Remembers what fields were changed
*
* @param kEvent $event
* @return void
* @access protected
*/
protected function OnAfterItemUpdate(kEvent $event)
{
parent::OnAfterItemUpdate($event);
if ( $this->Application->isAdmin ) {
return;
}
$object = $event->getObject();
/* @var $object kDBItem */
$changed_fields = $object->GetChangedFields();
if ( $changed_fields ) {
$table_info = $object->getLinkedInfo();
$main_object = $this->Application->recallObject($table_info['ParentPrefix']);
/* @var $main_object OrdersItem */
$oi_string = $object->GetDBField('ProductId') . ':' . $object->GetDBField('OptionsSalt') . ':' . $object->GetDBField('BackOrderFlag');
foreach ($changed_fields as $changed_field => $change_info) {
$error_code = OrderCheckoutError::FIELD_UPDATE_SUCCESS;
if ( $changed_field == 'ItemData' ) {
$item_data_old = unserialize($change_info['old']);
$item_data_new = unserialize($change_info['new']);
if ( $item_data_old['DiscountId'] != $item_data_new['DiscountId'] || $item_data_old['DiscountType'] != $item_data_new['DiscountType'] ) {
if ( $item_data_new['DiscountId'] > 0 ) {
$error_code = $item_data_new['DiscountType'] == 'discount' ? OrderCheckoutError::DISCOUNT_APPLIED : OrderCheckoutError::COUPON_APPLIED;
}
else {
$error_code = $item_data_old['DiscountType'] == 'discount' ? OrderCheckoutError::DISCOUNT_REMOVED : OrderCheckoutError::COUPON_REMOVED;
}
}
if ( $error_code == OrderCheckoutError::DISCOUNT_APPLIED || $error_code == OrderCheckoutError::DISCOUNT_REMOVED ) {
// set general error too
$main_object->setCheckoutError(OrderCheckoutErrorType::DISCOUNT, $error_code);
}
}
elseif ( $changed_field == 'Quantity' && $this->Application->isDebugMode() ) {
// here is how qty is changed:
// OLD QTY -> NEW QTY
// RECALCULATE
// NEW QTY = IN_STOCK_QTY
// NEW ORDER ITEM with LEFTOVER QTY
$this->Application->Debugger->appendTrace();
$this->Application->Debugger->appendHTML('QTY_CHANGE (' . $oi_string . '): ' . $change_info['old'] . ' => ' . $change_info['new']);
}
$main_object->setCheckoutError(OrderCheckoutErrorType::PRODUCT, $error_code, $oi_string . ':' . $changed_field);
}
}
}
/**
* Returns subtotal
*
* @param Array $items_info
* @return float
*/
function getSubTotal($items_info)
{
$sub_total = 0;
foreach ($items_info as $id => $field_values) {
if (!array_key_exists('Price', $field_values)) {
return false;
}
$sub_total += $field_values['Quantity'] * $field_values['Price'];
}
return $sub_total;
}
/**
* Returns total returned amount (refund)
*
* @param Array $items_info
* @return float
*/
function getReturnTotal($items_info)
{
$return_total = 0;
foreach ($items_info as $id => $field_values) {
$return_total += $field_values['ReturnAmount'];
}
return $return_total;
}
/**
* Saves selected items
*
* @param kEvent $event
*/
function OnSaveItems($event)
{
$event->CallSubEvent('OnUpdate');
$event->redirect = false;
$event->SetRedirectParam('opener', 's');
$event->SetRedirectParam('pass', 'all');
}
/**
* 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');
- $table = $this->Application->getUnitOption($event->Prefix, 'TableName');
- $id_field = $this->Application->getUnitOption($event->Prefix, 'IDField');
+ $config = $event->getUnitConfig();
- $sql = 'UPDATE ' . $table . '
+ $sql = 'UPDATE ' . $config->getTableName() . '
SET QuantityReserved = NULL
- WHERE ' . $id_field . ' = ' . $id;
+ WHERE ' . $config->getIDField() . ' = ' . $event->getEventParam('id');
$this->Conn->Query($sql);
}
/**
* Occurs after loading item, 'id' parameter
* allows to get id of item that was loaded
*
* @param kEvent $event
* @return void
* @access protected
*/
protected function OnAfterItemLoad(kEvent $event)
{
parent::OnAfterItemLoad($event);
$object = $event->getObject();
/* @var $object kDBItem */
$item_info = $object->GetDBField('ItemData');
if ( $item_info ) {
$item_info = unserialize($item_info);
$object->SetDBField('DiscountType', getArrayValue($item_info, 'DiscountType'));
$object->SetDBField('DiscountId', getArrayValue($item_info, 'DiscountId'));
}
}
/**
* 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);
$object = $event->getObject();
/* @var $object kDBList */
$package_num = $event->getEventParam('package_num');
if ( $package_num ) {
$object->addFilter('package_num', 'PackageNum = ' . $package_num);
}
$type = $event->getEventParam('product_type');
if ( $type ) {
$object->addFilter('product_type', 'p.Type =' . $type);
}
}
/**
* Checks, that currently loaded item is allowed for viewing (non permission-based)
*
* @param kEvent $event
* @return bool
* @access protected
*/
protected function checkItemStatus(kEvent $event)
{
if ( $this->Application->isAdmin ) {
return true;
}
$object = $event->getObject();
/* @var $object kDBItem */
if ( !$object->isLoaded() ) {
return true;
}
$order = $this->Application->recallObject('ord');
/* @var $order kDBItem */
if ( $order->isLoaded() && ($order->GetID() == $object->GetDBField('OrderId')) ) {
return $order->GetDBField('PortalUserId') == $this->Application->RecallVar('user_id');
}
return false;
}
}
\ No newline at end of file
Index: branches/5.3.x/units/order_items/order_items_tag_processor.php
===================================================================
--- branches/5.3.x/units/order_items/order_items_tag_processor.php (revision 15694)
+++ branches/5.3.x/units/order_items/order_items_tag_processor.php (revision 15695)
@@ -1,300 +1,300 @@
<?php
/**
* @version $Id$
* @package In-Commerce
* @copyright Copyright (C) 1997 - 2009 Intechnic. All rights reserved.
* @license Commercial License
* This software 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
* See http://www.in-portal.org/commercial-license for copyright notices and details.
*/
defined('FULL_PATH') or die('restricted access!');
class OrderItemsTagProcessor extends kDBTagProcessor
{
function PrintGrid($params)
{
$order = $this->Application->recallObject('ord');
/* @var $order kDBList */
if ( $order->GetDBField('Status') != ORDER_STATUS_INCOMPLETE ) {
$params['grid'] = $params['NotEditable'];
}
else {
$params['grid'] = $params['Editable'];
}
return $this->Application->ProcessParsedTag('m', 'ParseBlock', $params);
}
function IsTangible($params)
{
$object = $this->getObject($params);
/* @var $object kDBItem */
return $object->GetDBField('Type') == PRODUCT_TYPE_TANGIBLE;
}
function HasQty($params)
{
$object = $this->getObject($params);
/* @var $object kDBItem */
return in_array($object->GetDBField('Type'), Array (PRODUCT_TYPE_TANGIBLE, 6));
}
function HasDiscount($params)
{
$object = $this->getObject($params);
/* @var $object kDBItem */
return (float)$object->GetDBField('ItemDiscount') ? 1 : 0;
}
function HasOptions($params)
{
$object = $this->getObject($params);
$item_data = @unserialize($object->GetDBField('ItemData'));
return isset($item_data['Options']);
}
function PrintOptions($params)
{
$object = $this->getObject($params);
/* @var $object kDBItem */
$item_data = @unserialize($object->GetDBField('ItemData'));
$render_as = $this->SelectParam($params, 'render_as');
$block_params['name'] = $render_as;
$opt_helper = $this->Application->recallObject('kProductOptionsHelper');
/* @var $opt_helper kProductOptionsHelper */
$o = '';
$options = $item_data['Options'];
foreach ($options as $opt => $val) {
if ( !is_array($val) ) {
$val = htmlspecialchars_decode($val);
}
$key_data = $opt_helper->ConvertKey($opt, $object->GetDBField('ProductId'));
$parsed = $opt_helper->ExplodeOptionValues($key_data);
if ( $parsed ) {
$values = $parsed['Values'];
$prices = $parsed['Prices'];
$price_types = $parsed['PriceTypes'];
}
else {
$values = array ();
$prices = array ();
$price_types = array ();
}
$key = $key_data['Name'];
/*if (is_array($val)) {
$val = join(',', $val);
}*/
$lang = $this->Application->recallObject('lang.current');
/* @var $lang LanguagesItem */
if ( $render_as ) {
$block_params['option'] = $key;
if ( is_array($val) ) {
$block_params['value'] = $val;
$block_params['type'] = $key_data['OptionType'];
$block_params['price'] = $prices;
$block_params['price_type'] = $price_types;
}
else {
$price_type = array_key_exists($val, $price_types) ? $price_types[$val] : '';
$price = array_key_exists($val, $prices) ? $prices[$val] : '';
if ( $price_type == '$' ) {
$iso = $this->GetISO($params['currency']);
$value = $this->AddCurrencySymbol($lang->formatNumber($this->ConvertCurrency($price, $iso), 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'] = $price;
$block_params['price_type'] = $price_type;
$block_params['sign'] = $price >= 0 ? '+' : '-';
}
$block_params['value'] = htmlspecialchars($val, null, CHARSET);
$block_params['type'] = $key_data['OptionType'];
}
$o .= $this->Application->ParseBlock($block_params, 1);
}
else {
$o .= $key . ': ' . $val . '<br>';
}
}
return $o;
}
function ProductsInStock($params)
{
$object = $this->getObject($params);
if (!$object->GetDBField('InventoryStatus')) {
// unlimited count available
return false;
}
if ($object->GetDBField('InventoryStatus') == 2) {
- $poc_table = $this->Application->getUnitOption('poc', 'TableName');
+ $poc_table = $this->Application->getUnitConfig('poc')->getTableName();
$sql = 'SELECT QtyInStock
FROM '.$poc_table.'
WHERE (ProductId = '.$object->GetDBField('ProductId').') AND (Availability = 1) AND (CombinationCRC = '.$object->GetDBField('OptionsSalt').')';
$ret = $this->Conn->GetOne($sql);
}
else {
$ret = $object->GetDBField('QtyInStock');
}
return $ret;
}
function PrintOptionValues($params)
{
$block_params['name'] = $params['render_as'];
$values = $this->Application->Parser->GetParam('value');
/* @var $values Array */
$prices = $this->Application->Parser->GetParam('price');
$price_types = $this->Application->Parser->GetParam('price_type');
$o = '';
$i = 0;
foreach ($values as $val) {
$i++;
$val = htmlspecialchars_decode($val);
$block_params['value'] = htmlspecialchars($val, null, CHARSET);
if ($price_types[$val] == '$') {
$iso = $this->GetISO($params['currency']);
$value = $this->AddCurrencySymbol(sprintf("%.2f", $this->ConvertCurrency($prices[$val], $iso)), $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'] = $prices[$val];
$block_params['price_type'] = $price_types[$val];
$block_params['sign'] = $prices[$val] >= 0 ? '+' : '-';
}
$block_params['is_last'] = $i == count($values);
$o.= $this->Application->ParseBlock($block_params, 1);
}
return $o;
}
/*function ConvertKey($key, &$object)
{
static $mapping = null;
if (is_null($mapping) || !isset($mapping[$object->GetDBField('ProductId')])) {
$table = TABLE_PREFIX.'ProductOptions';
$sql = 'SELECT * FROM '.$table.' WHERE ProductId = '.$object->GetDBField('ProductId');
$mapping[$object->GetDBField('ProductId')] = $this->Conn->Query($sql, 'ProductOptionId');
}
return $mapping[$object->GetDBField('ProductId')][$key];
}*/
function PrintList($params)
{
$list =& $this->GetList($params);
- $id_field = $this->Application->getUnitOption($this->Prefix, 'IDField');
+ $id_field = $this->getUnitConfig()->getIDField();
$list->Query();
$o = '';
$list->GoFirst();
$block_params = $this->prepareTagParams($params);
$block_params['name'] = $this->SelectParam($params, 'render_as,block');
$block_params['pass_params'] = 'true';
$product_object = $this->Application->recallObject('p', 'p', Array ('skip_autoload' => true));
/* @var $product_object kCatDBItem */
$i = 0;
$product_id = $product_object->GetID();
$product_id_get = $this->Application->GetVar('p_id');
while (!$list->EOL()) {
// load product used in orderitem
$this->Application->SetVar($this->getPrefixSpecial() . '_id', $list->GetDBField($id_field)); // for edit/delete links using GET
$this->Application->SetVar('p_id', $list->GetDBField('ProductId'));
$product_object->Load($list->GetDBField('ProductId')); // correct product load
$this->Application->SetVar('m_cat_id', $product_object->GetDBField('CategoryId'));
$block_params['is_last'] = ($i == $list->GetSelectedCount() - 1);
$o .= $this->Application->ParseBlock($block_params, 1);
$list->GoNext();
$i++;
}
// restore IDs used in cycle
$this->Application->SetVar('p_id', $product_id_get);
$this->Application->DeleteVar($this->getPrefixSpecial() . '_id');
if ( $product_id ) {
$product_object->Load($product_id);
}
return $o;
}
function DisplayOptionsPricing($params)
{
$object = $this->getObject($params);
/* @var $object kDBItem */
if ( $object->GetDBField('OptionsSelectionMode') == 1 ) {
return false;
}
$item_data = unserialize($object->GetDBField('ItemData'));
if ( !is_array($item_data) ) {
return false;
}
$options = getArrayValue($item_data, 'Options');
$helper = $this->Application->recallObject('kProductOptionsHelper');
/* @var $helper kProductOptionsHelper */
$crc = $helper->OptionsSalt($options, true);
$sql = 'SELECT COUNT(*)
FROM ' . TABLE_PREFIX . 'ProductOptionCombinations
WHERE CombinationCRC = ' . $crc . ' AND ProductId = ' . $object->GetDBField('ProductId') . ' AND (Price != 0 OR (PriceType = 1 AND Price = 0))';
return $this->Conn->GetOne($sql) == 0; // no overriding combinations found
}
function RowIndex($params)
{
$object = $this->getObject($params);
/* @var $object kDBItem */
return $object->GetDBField('ProductId') . ':' . $object->GetDBField('OptionsSalt') . ':' . $object->GetDBField('BackOrderFlag');
}
function FreePromoShippingAvailable($params)
{
$object = $this->getObject($params);
/* @var $object kDBItem */
$order_helper = $this->Application->recallObject('OrderHelper');
/* @var $order_helper OrderHelper */
return $order_helper->eligibleForFreePromoShipping($object);
}
}
\ No newline at end of file
Index: branches/5.3.x/units/addresses/addresses_event_handler.php
===================================================================
--- branches/5.3.x/units/addresses/addresses_event_handler.php (revision 15694)
+++ branches/5.3.x/units/addresses/addresses_event_handler.php (revision 15695)
@@ -1,458 +1,458 @@
<?php
/**
* @version $Id$
* @package In-Commerce
* @copyright Copyright (C) 1997 - 2009 Intechnic. All rights reserved.
* @license Commercial License
* This software 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
* See http://www.in-portal.org/commercial-license for copyright notices and details.
*/
defined('FULL_PATH') or die('restricted access!');
class AddressesEventHandler extends kDBEventHandler {
/**
* Allows to override standard permission mapping
*
* @return void
* @access protected
* @see kEventHandler::$permMapping
*/
protected function mapPermissions()
{
parent::mapPermissions();
$permissions = Array (
// user can view any form on front-end
'OnItemBuild' => Array ('subitem' => true),
'OnUpdate' => Array ('subitem' => true),
'OnCreate' => Array ('subitem' => true),
'OnDelete' => Array ('subitem' => true),
);
$this->permMapping = array_merge($this->permMapping, $permissions);
}
/**
* Returns special of main item for linking with sub-item
*
* @param kEvent $event
* @return string
* @access protected
*/
protected function getMainSpecial(kEvent $event)
{
return '';
}
/**
* 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);
if ( $this->Application->isAdminUser ) {
return;
}
$object = $event->getObject();
/* @var $object kDBList */
$user_id = $this->Application->RecallVar('user_id');
$object->addFilter('myitems_user', '%1$s.PortalUserId = ' . $user_id);
}
/**
* Makes "use as $type" mark unique among user addresses
*
* @param kDBItem $object
* @param string $type
*/
protected function processLastUsed(&$object, $type)
{
$is_last = $object->GetDBField('LastUsedAs' . $type);
if ( $is_last ) {
$fields_hash = Array ('LastUsedAs' . $type => 0);
$this->Conn->doUpdate($fields_hash, $object->TableName, 'PortalUserId = ' . $object->GetDBField('PortalUserId'));
}
}
/**
* 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);
$object = $event->getObject();
/* @var $object kDBItem */
if ( !$object->isLoaded() || !$this->checkItemStatus($event) ) {
// not trivially loaded object OR not current user address
$event->status = kEvent::erPERM_FAIL;
return ;
}
$cs_helper = $this->Application->recallObject('CountryStatesHelper');
/* @var $cs_helper kCountryStatesHelper */
$cs_helper->CheckStateField($event, 'State', 'Country');
$cs_helper->PopulateStates($event, 'State', 'Country');
$this->processLastUsed($object, 'Shipping');
$this->processLastUsed($object, 'Billing');
}
/**
* Updates kDBItem
*
* @param kEvent $event
* @return void
* @access protected
*/
protected function OnUpdate(kEvent $event)
{
parent::OnUpdate($event);
$this->setNextTemplate($event);
}
/**
* Creates new kDBItem
*
* @param kEvent $event
* @return void
* @access protected
*/
protected function OnCreate(kEvent $event)
{
parent::OnCreate($event);
$this->setNextTemplate($event);
}
/**
* Sets next template to be shown after address is added/updated
*
* @param kEvent $event
* @return void
* @access protected
*/
protected function setNextTemplate(kEvent $event)
{
if ( $this->Application->isAdminUser ) {
return;
}
$event->SetRedirectParam('opener', 's');
$next_template = $this->Application->GetVar('next_template');
if ( $next_template ) {
$event->redirect = $next_template;
}
}
/**
* Fills states for object country
*
* @param kEvent $event
* @return void
* @access protected
*/
protected function OnAfterItemLoad(kEvent $event)
{
parent::OnAfterItemLoad($event);
$cs_helper = $this->Application->recallObject('CountryStatesHelper');
/* @var $cs_helper kCountryStatesHelper */
$cs_helper->PopulateStates($event, 'State', 'Country');
}
/**
* [HOOK] Update Users table when address marked as ProfileAddress is changed via addr prefix object
*
* @param kEvent $event
* @return bool
* @access protected
*/
protected function OnUpdateProfileAddress(kEvent $event)
{
$object = $event->getObject(Array ('skip_autoload' => true));
/* @var $object kDBItem */
if ( !$this->Application->isAdmin ) {
$address_id = $this->getOrderAddressId();
if ( !$address_id ) {
return true;
}
$object->Load($address_id);
}
if ( !$object->GetDBField('IsProfileAddress') ) {
return true;
}
$field_map = Array (
'Company' => 1,
'Phone' => 1,
'Fax' => 1,
'Email' => 1,
'Address1' => 'Street',
'Address2' => 'Street2',
'City' => 1,
'State' => 1,
'Zip' => 1,
'Country' => 1,
);
$user = $this->Application->recallObject($this->Application->isAdmin ? 'u' : 'u.current');
/* @var $user UsersItem */
$user->setName( $object->GetDBField('To') );
foreach ($field_map as $src_field => $dst_field) {
if ( $dst_field == 1 ) {
$dst_field = $src_field;
}
$user->SetDBField($dst_field, $object->GetDBField($src_field));
}
return $user->Update();
}
/**
* Returns ID of address, that is selected in address dropdown on shipping/billing step of checkout
*
* @return int
* @access protected
*/
protected function getOrderAddressId()
{
$ret = false;
if ( $this->Application->GetVar('billing_address_id') > 0 ) {
$ret = $this->Application->GetVar('billing_address_id');
}
elseif ( $this->Application->GetVar('shipping_address_id') > 0 ) {
$ret = $this->Application->GetVar('shipping_address_id');
}
return $ret;
}
/**
* [HOOK] Create user profile address based on Users table data
*
* @param kEvent $event
* @return bool
* @access protected
*/
protected function OnUpdateUserProfile(kEvent $event)
{
$user = $event->MasterEvent->getObject();
/* @var $user UsersItem */
$load_keys = Array ('PortalUserId' => $user->GetID(), 'IsProfileAddress' => 1);
$object = $this->Application->recallObject($event->Prefix . '.-item', null, Array ('skip_autoload' => true));
/* @var $object kDBItem */
$object->Load($load_keys);
$field_map = Array (
'PortalUserId' => 1,
'Company' => 1,
'Phone' => 1,
'Fax' => 1,
'Email' => 1,
'Address1' => 'Street',
'Address2' => 'Street2',
'City' => 1,
'State' => 1,
'Zip' => 1,
'Country' => 1,
);
$full_name = trim($user->GetDBField('FirstName') . ' ' . $user->GetDBField('LastName'));
$object->SetDBField('To', $full_name);
$object->SetDBField('IsProfileAddress', 1);
foreach ($field_map as $dst_field => $src_field) {
if ( $src_field == 1 ) {
$src_field = $dst_field;
}
$object->SetDBField($dst_field, $user->GetDBField($src_field));
}
$sql = 'SELECT SUM(IF(LastUsedAsBilling = 1, 1, 0 )) AS HasBilling, SUM(IF(LastUsedAsShipping = 1, 1, 0)) AS HasShipping
FROM ' . $object->TableName . '
WHERE PortalUserId = ' . $user->GetID();
$address_status = $this->Conn->GetRow($sql);
if ( !$address_status['HasBilling'] ) {
$object->SetDBField('LastUsedAsBilling', 1);
}
if ( !$address_status['HasShipping'] ) {
$object->SetDBField('LastUsedAsShipping', 1);
}
return $object->isLoaded() ? $object->Update() : $object->Create();
}
/**
* Checks if user trying to manipulate address that he Owns (exception for Admins)
* (non permission-based)
*
* @param kEvent $event
* @return bool
* @access protected
*/
protected function checkItemStatus(kEvent $event)
{
if ( $this->Application->isAdminUser ) {
return true;
}
if ( !$this->Application->LoggedIn() ) {
return false;
}
$object = $event->getObject();
/* @var $object kDBItem */
if ( !$object->isLoaded() ) {
return true;
}
return $object->GetDBField('PortalUserId') == $this->Application->RecallVar('user_id');
}
/**
* Ensures, that user have only one "use as billing" / "use as shipping" address
* Disables Guest ability to create addresses
*
* @param kEvent $event
* @return void
* @access protected
*/
protected function OnBeforeItemCreate(kEvent $event)
{
parent::OnBeforeItemCreate($event);
if ( !$this->Application->LoggedIn() ) {
$event->status = kEvent::erPERM_FAIL;
return ;
}
$object = $event->getObject();
/* @var $object kDBItem */
if ( !$this->Application->isAdmin ) {
$object->SetDBField('PortalUserId', $this->Application->RecallVar('user_id'));
}
$cs_helper = $this->Application->recallObject('CountryStatesHelper');
/* @var $cs_helper kCountryStatesHelper */
$cs_helper->CheckStateField($event, 'State', 'Country');
$cs_helper->PopulateStates($event, 'State', 'Country');
$this->processLastUsed($object, 'Shipping');
$this->processLastUsed($object, 'Billing');
}
/**
* Occurs before deleting item, id of item being
* deleted is stored as 'id' event param
*
* @param kEvent $event
* @return void
* @access protected
*/
protected function OnBeforeItemDelete(kEvent $event)
{
parent::OnBeforeItemDelete($event);
$object = $event->getObject();
/* @var $object kDBItem */
if ( !$object->isLoaded() || !$this->checkItemStatus($event) ) {
// not trivially loaded object OR not current user address
$event->status = kEvent::erPERM_FAIL;
return;
}
}
/**
* Sets default country for new addresses to Latvia
*
* @param kEvent $event
* @return void
* @access protected
*/
protected function OnAfterConfigRead(kEvent $event)
{
parent::OnAfterConfigRead($event);
$site_helper = $this->Application->recallObject('SiteHelper');
/* @var $site_helper SiteHelper */
- $fields = $this->Application->getUnitOption($event->Prefix, 'Fields');
+ $config = $this->Application->getUnitConfig($event->Prefix);
+
+ $fields = $config->getFields();
$fields['Country']['default'] = $site_helper->getDefaultCountry('Shipping');
- $this->Application->setUnitOption($event->Prefix, 'Fields', $fields);
+ $config->setFields($fields);
}
/**
* [HOOK] Creates user addresses editing tab
*
* @param kEvent $event
*/
function OnModifyUsersConfig($event)
{
- $title_presets = $this->Application->getUnitOption($event->MasterEvent->Prefix, 'TitlePresets');
-
- $title_presets['user_edit_addresses'] = Array (
- 'prefixes' => Array ('u', $event->Prefix . '_List'),
- 'format' => "#u_status# '#u_titlefield#' - !la_title_Addresses! (#" . $event->Prefix . "_recordcount#)"
- );
-
- $title_presets['user_address_edit'] = Array (
- 'prefixes' => Array ('u', $event->Prefix),
- 'new_status_labels' => Array ($event->Prefix => '!la_title_AddingAddress!'),
- 'edit_status_labels' => Array ($event->Prefix => '!la_title_EditingAddress!'),
- 'new_titlefield' => Array ($event->Prefix => '!la_title_NewAddress!'),
- 'format' => "#u_status# '#u_titlefield#' - #{$event->Prefix}_status#"
- );
- $this->Application->setUnitOption($event->MasterEvent->Prefix, 'TitlePresets', $title_presets);
-
- $edit_tab_presets = $this->Application->getUnitOption($event->MasterEvent->Prefix, 'EditTabPresets');
-
- $edit_tab_presets['Default'][] = Array (
- 'title' => 'la_tab_Addresses', 't' => 'in-commerce/users/user_edit_addresses', 'priority' => 6
- );
+ $config = $this->Application->getUnitConfig($event->MasterEvent->Prefix);
- $this->Application->setUnitOption($event->MasterEvent->Prefix, 'EditTabPresets', $edit_tab_presets);
+ $config->addTitlePresets(Array (
+ 'user_edit_addresses' => Array (
+ 'prefixes' => Array ('u', $event->Prefix . '_List'),
+ 'format' => "#u_status# '#u_titlefield#' - !la_title_Addresses! (#" . $event->Prefix . "_recordcount#)"
+ ),
+ 'user_address_edit' => Array (
+ 'prefixes' => Array ('u', $event->Prefix),
+ 'new_status_labels' => Array ($event->Prefix => '!la_title_AddingAddress!'),
+ 'edit_status_labels' => Array ($event->Prefix => '!la_title_EditingAddress!'),
+ 'new_titlefield' => Array ($event->Prefix => '!la_title_NewAddress!'),
+ 'format' => "#u_status# '#u_titlefield#' - #{$event->Prefix}_status#"
+ )
+ ));
+
+ $config->addEditTabPresetTabs('Default', Array (
+ 'addresses' => Array (
+ 'title' => 'la_tab_Addresses', 't' => 'in-commerce/users/user_edit_addresses', 'priority' => 6
+ )
+ ));
}
}
\ No newline at end of file
Index: branches/5.3.x/install/upgrades.php
===================================================================
--- branches/5.3.x/install/upgrades.php (revision 15694)
+++ branches/5.3.x/install/upgrades.php (revision 15695)
@@ -1,189 +1,190 @@
<?php
/**
* @version $Id$
* @package In-Commerce
* @copyright Copyright (C) 1997 - 2009 Intechnic. All rights reserved.
* @license Commercial License
* This software 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
* See http://www.in-portal.org/commercial-license for copyright notices and details.
*/
defined('FULL_PATH') or die('restricted access!');
$upgrade_class = 'InCommerceUpgrades';
/**
* Class, that holds all upgrade scripts for "In-Commerce" module
*
*/
class InCommerceUpgrades extends kUpgradeHelper {
public function __construct()
{
parent::__construct();
$this->dependencies = Array (
'4.3.9' => Array ('Core' => '4.3.9'),
'5.0.0' => Array ('Core' => '5.0.0'),
'5.0.1' => Array ('Core' => '5.0.1'),
'5.0.2-B1' => Array ('Core' => '5.0.2-B1'),
'5.0.2-B2' => Array ('Core' => '5.0.2-B2'),
'5.0.2-RC1' => Array ('Core' => '5.0.2-RC1'),
'5.0.2' => Array ('Core' => '5.0.2'),
'5.0.3-B1' => Array ('Core' => '5.0.3-B1'),
'5.0.3-B2' => Array ('Core' => '5.0.3-B2'),
'5.0.3-RC1' => Array ('Core' => '5.0.3-RC1'),
'5.0.3' => Array ('Core' => '5.0.3'),
'5.0.4-B1' => Array ('Core' => '5.0.4-B1'),
'5.0.4-B2' => Array ('Core' => '5.0.4-B2'),
'5.0.4' => Array ('Core' => '5.0.4'),
'5.1.0-B1' => Array ('Core' => '5.1.0-B1'),
'5.1.0-B2' => Array ('Core' => '5.1.0-B2'),
'5.1.0-RC1' => Array ('Core' => '5.1.0-RC1'),
'5.1.0' => Array ('Core' => '5.1.0'),
'5.1.1-B1' => Array ('Core' => '5.1.1-B1'),
'5.1.1-B2' => Array ('Core' => '5.1.1-B2'),
'5.1.1-RC1' => Array ('Core' => '5.1.1-RC1'),
'5.1.1' => Array ('Core' => '5.1.1'),
'5.1.2-B1' => Array ('Core' => '5.1.2-B1'),
'5.1.2-B2' => Array ('Core' => '5.1.2-B2'),
'5.1.2-RC1' => Array ('Core' => '5.1.2-RC1'),
'5.1.2' => Array ('Core' => '5.1.2'),
'5.1.3-B1' => Array ('Core' => '5.1.3-B1'),
'5.1.3-B2' => Array ('Core' => '5.1.3-B2'),
'5.1.3-RC1' => Array ('Core' => '5.1.3-RC1'),
'5.1.3-RC2' => Array ('Core' => '5.1.3-RC2'),
'5.1.3' => Array ('Core' => '5.1.3'),
'5.2.0-B1' => Array ('Core' => '5.2.0-B1'),
'5.2.0-B2' => Array ('Core' => '5.2.0-B2'),
'5.2.0-B3' => Array ('Core' => '5.2.0-B3'),
'5.2.0-RC1' => Array ('Core' => '5.2.0-RC1'),
'5.2.0' => Array ('Core' => '5.2.0'),
'5.2.1-B1' => Array ('Core' => '5.2.1-B1'),
);
}
/**
* Changes table structure, where multilingual fields of TEXT type are present
*
* @param string $mode when called mode {before, after)
*/
function Upgrade_5_0_0($mode)
{
if ($mode == 'after') {
// update icon
+ $categories_config = $this->Application->getUnitConfig('c');
$root_category = $this->Application->findModule('Name', 'In-Commerce', 'RootCat');
- $sql = 'UPDATE ' . $this->Application->getUnitOption('c', 'TableName') . '
+ $sql = 'UPDATE ' . $categories_config->getTableName() . '
SET UseMenuIconUrl = 1, MenuIconUrl = "in-commerce/img/menu_products.gif"
- WHERE ' . $this->Application->getUnitOption('c', 'IDField') . ' = ' . $root_category;
+ WHERE ' . $categories_config->getIDField() . ' = ' . $root_category;
$this->Conn->Query($sql);
$this->_updateDetailTemplate('p', 'in-commerce/product/details', 'in-commerce/designs/detail');
// copy store name to company name
$store_name = $this->Application->ConfigValue('Comm_StoreName');
$sql = 'UPDATE ' . TABLE_PREFIX . 'ConfigurationValues
SET VariableValue = ' . $this->Conn->qstr($store_name) . '
WHERE VariableName = "Comm_CompanyName"';
$this->Conn->Query($sql);
}
}
/**
* Update to 5.0.1, update details template
*
* @param string $mode when called mode {before, after)
*/
function Upgrade_5_0_1($mode)
{
if ($mode == 'after') {
$this->_updateDetailTemplate('p', 'in-commerce/designs/detail', 'in-commerce/products/product_detail');
// clean incomplete orders 5+ hours old
// don't use ORDER_STATUS_INCOMPLETE constant, since it's not available upgrade
$delete_timestamp = time() - (3600 * 5);
$sql = 'SELECT OrderId FROM ' . TABLE_PREFIX . 'Orders
WHERE Status = ' . 0 . '
AND OrderDate < ' . $delete_timestamp;
$orders_to_delete = $this->Conn->GetCol($sql);
if ( $orders_to_delete && is_array($orders_to_delete) ) {
$this->Conn->Query( 'DELETE FROM ' . TABLE_PREFIX . 'OrderItems
WHERE OrderId IN ( ' . implode(',', $orders_to_delete) . ' )' );
$this->Conn->Query( 'DELETE FROM ' . TABLE_PREFIX . 'Orders
WHERE Status = ' . 0 . '
AND OrderDate < ' . $delete_timestamp );
}
// delete old events
$events_to_delete = Array ( 'SITE.SUGGEST' );
$sql = 'SELECT EventId FROM ' . TABLE_PREFIX . 'Events
WHERE Event IN ("' . implode('","', $events_to_delete) . '")';
$event_ids = $this->Conn->GetCol($sql);
if ($event_ids) {
$sql = 'DELETE FROM ' . TABLE_PREFIX . 'EmailMessage
WHERE EventId IN (' . implode(',', $event_ids) . ')';
$this->Conn->Query($sql);
$sql = 'DELETE FROM ' . TABLE_PREFIX . 'Events
WHERE EventId IN (' . implode(',', $event_ids) . ')';
$this->Conn->Query($sql);
$sql = 'DELETE FROM ' . TABLE_PREFIX . 'Phrase
WHERE Phrase IN ("la_event_user.suggest_site")';
$this->Conn->Query($sql);
}
}
}
/**
* Update to 5.2.0-RC1
*
* @param string $mode when called mode {before, after)
*/
public function Upgrade_5_2_0_RC1($mode)
{
if ( $mode != 'before' ) {
return;
}
- $table_name = $this->Application->getUnitOption('pt', 'TableName');
+ $table_name = $this->Application->getUnitConfig('pt')->getTableName();
$table_structure = $this->Conn->Query('DESCRIBE ' . $table_name, 'Field');
if ( isset($table_structure['Description']) ) {
$sql = 'UPDATE ' . $table_name . '
SET Description = ""
WHERE Description IS NULL';
$this->Conn->Query($sql);
$sql = 'ALTER TABLE ' . $table_name . '
CHANGE `Description` `Description` VARCHAR(255) NOT NULL DEFAULT ""';
$this->Conn->Query($sql);
}
$ml_helper = $this->Application->recallObject('kMultiLanguageHelper');
/* @var $ml_helper kMultiLanguageHelper */
$ml_helper->createFields('pt');
if ( isset($table_structure['Description']) ) {
$sql = 'UPDATE ' . $table_name . '
SET
l' . $this->Application->GetDefaultLanguageId() . '_Description = Description,
l' . $this->Application->GetDefaultLanguageId() . '_Instructions = Instructions';
$this->Conn->Query($sql);
$sql = 'ALTER TABLE ' . $table_name . ' DROP Description, DROP Instructions';
$this->Conn->Query($sql);
}
}
}
\ No newline at end of file
Index: branches/5.3.x/gw_notify.php
===================================================================
--- branches/5.3.x/gw_notify.php (revision 15694)
+++ branches/5.3.x/gw_notify.php (revision 15695)
@@ -1,63 +1,63 @@
<?php
/**
* @version $Id$
* @package In-Commerce
* @copyright Copyright (C) 1997 - 2009 Intechnic. All rights reserved.
* @license Commercial License
* This software 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
* See http://www.in-portal.org/commercial-license for copyright notices and details.
*/
define('GW_NOTIFY', 1);
define('FULL_PATH', realpath(dirname(__FILE__) . '/../..'));
include_once(FULL_PATH . '/core/kernel/startup.php');
$application =& kApplication::Instance();
$application->Init();
// for debugging payment gateway notifications, don't remove
/*$fh = fopen((defined('RESTRICTED') ? RESTRICTED : WRITEABLE) . '/gw.log', 'a');
fwrite ($fh, "\n\n".date('d/m/y h:i:s').":\n");
foreach ($_REQUEST as $key => $val) {
fwrite($fh, "<input type=\"text\" name=\"$key\" value=\"$val\">\n");
}
fclose($fh);*/
$db =& $application->GetADODBConnection();
- $application->setUnitOption('ord','AutoLoad',false);
+ $application->getUnitConfig('ord')->setAutoLoad(false);
$order = $application->recallObject('ord');
$order_id = $application->GetVar('order_id');
if ($order_id) {
$order->Load($order_id);
}
$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 %s SET GWResult1 = %s WHERE %s = %s';
$sql = sprintf($sql, $order->TableName, $db->qstr($gateway_object->getGWResponce()), $order->IDField, $order->GetID() );
$db->Query($sql);
$order->SetDBField('GWResult1', $gateway_object->getGWResponce() );
$sql = 'UPDATE %s SET TransactionStatus = %s WHERE %s = %s';
$db->Query( sprintf($sql, $order->TableName, $transaction_status, $order->IDField, $order->GetID()) );
$order->SetDBField('TransactionStatus', $transaction_status);
if($transaction_status == 1)
{
$application->HandleEvent(new kEvent('ord:OnCompleteOrder'));
}
else {
$application->StoreVar('gw_error', $gateway_object->getErrorMsg());
}
$application->Done();
\ No newline at end of file

Event Timeline