Page MenuHomeIn-Portal Phabricator

order_items_event_handler.php
No OneTemporary

File Metadata

Created
Wed, Oct 1, 1:23 PM

order_items_event_handler.php

<?php
/**
* @version $Id: order_items_event_handler.php 16522 2017-01-20 20:28:16Z alex $
* @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);
/** @var ProductsItem $product_object */
$product_object = $this->Application->recallObject('p.-item', null, array('skip_autoload' => true));
foreach ($product_ids as $product_id) {
$product_object->Load($product_id);
$sql = 'SELECT COUNT(*)
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 {
/** @var OrdersEventHandler $orders_h */
$orders_h = $this->Application->recallObject('ord_EventHandler');
// 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;
}
/** @var kDBItem $object */
$object = $event->getObject(Array ('skip_autoload' => true));
$table_info = $object->getLinkedInfo();
/** @var OrdersItem $main_object */
$main_object = $this->Application->recallObject($table_info['ParentPrefix']);
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);
$event->setEventParam('form_data', $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;
}
/** @var kDBItem $object */
$object = $event->getObject();
$changed_fields = $object->GetChangedFields();
if ( $changed_fields ) {
$table_info = $object->getLinkedInfo();
/** @var OrdersItem $main_object */
$main_object = $this->Application->recallObject($table_info['ParentPrefix']);
$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);
$config = $event->getUnitConfig();
$sql = 'UPDATE ' . $config->getTableName() . '
SET QuantityReserved = NULL
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);
/** @var kDBItem $object */
$object = $event->getObject();
$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);
/** @var kDBList $object */
$object = $event->getObject();
$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;
}
/** @var kDBItem $object */
$object = $event->getObject();
if ( !$object->isLoaded() ) {
return true;
}
/** @var kDBItem $order */
$order = $this->Application->recallObject('ord');
if ( $order->isLoaded() && ($order->GetID() == $object->GetDBField('OrderId')) ) {
return $order->GetDBField('PortalUserId') == $this->Application->RecallVar('user_id');
}
return false;
}
}

Event Timeline