Array ('subitem' => 'add|edit'), 'OnInfinity' => Array ('subitem' => 'add|edit'), 'OnArrange' => Array ('subitem' => 'add|edit'), 'OnDeleteBrackets' => Array ('subitem' => 'add|edit'), ); $this->permMapping = array_merge($this->permMapping, $permissions); } /** * Define alternative event processing method names * * @return void * @see kEventHandler::$eventMethods * @access protected */ protected function mapEvents() { parent::mapEvents(); // ensure auto-adding of approve/decline and so on events $brackets_events = Array( 'OnMoreBrackets' => 'PricingBracketsAction', 'OnArrange' => 'PricingBracketsAction', 'OnInfinity' => 'PricingBracketsAction', 'OnDeleteBrackets' => 'PricingBracketsAction', ); $this->eventMethods = array_merge($this->eventMethods, $brackets_events); } function PricingBracketsAction($event) { $event->redirect=false; $temp = $this->Application->GetVar($event->getPrefixSpecial(true)); // $object = $event->getObject(); // $formatter = $this->Application->recallObject('kFormatter'); // $temp = $formatter->TypeCastArray($temp, $object); //uasort($temp, 'pr_bracket_comp'); $bracket = $this->Application->recallObject($event->getPrefixSpecial()); foreach($temp as $id => $record) { if( $record['MaxQty'] == '∞' || $record['MaxQty'] == '∞') { $temp[$id]['MaxQty'] = -1; } } $group_id = $this->Application->getVar('group_id'); if($group_id>0){ $where_group=' GroupId = '.$group_id.' '; } else { $where_group= ' TRUE '; } switch ($event->Name) { case 'OnMoreBrackets': $new_id = (int)$this->Conn->GetOne('SELECT MIN('.$bracket->IDField.') FROM '.$bracket->TableName); if($new_id > 0) $new_id = 0; do { $new_id--; } while ($this->check_array($this->Application->GetVar($event->getPrefixSpecial(true)), 'PriceId', $new_id)); $last_max_qty = $this->Conn->GetOne('SELECT MAX(MaxQty) FROM '.$bracket->TableName.' WHERE '.$where_group); $min_qty = $this->Conn->GetOne('SELECT MIN(MaxQty) FROM '.$bracket->TableName.' WHERE '.$where_group); if ($min_qty==-1) $last_max_qty = -1; if (!$last_max_qty) $last_max_qty=1; for($i = $new_id; $i > $new_id - 5; $i--) { $temp[$i]['PriceId'] = $i; $temp[$i]['MinQty'] = ($i == $new_id-4 && $last_max_qty != -1) ? $last_max_qty : ''; $temp[$i]['MaxQty'] = ($i == $new_id-4 && $last_max_qty != -1) ? -1 : ''; $temp[$i]['Price'] = ''; $temp[$i]['Cost'] = ''; $temp[$i]['Points'] = ''; $temp[$i]['Negotiated'] = '0'; $temp[$i]['IsPrimary'] = '0'; $temp[$i]['GroupId'] = $group_id; } $this->Application->SetVar($event->getPrefixSpecial(true), $temp); $event->CallSubEvent('OnPreSaveBrackets'); break; case 'OnArrange': $temp=$this->OnArrangeBrackets($event, $temp, $bracket); $this->Application->SetVar($event->getPrefixSpecial(true), $temp); $event->CallSubEvent('OnPreSaveBrackets'); break; case 'OnInfinity': $temp=$this->OnArrangeBrackets($event, $temp, $bracket); $this->Application->SetVar($event->getPrefixSpecial(true), $temp); $event->CallSubEvent('OnPreSaveBrackets'); $infinite_exists = $this->Conn->GetOne('SELECT count(*) FROM '.$bracket->TableName.' WHERE MaxQty=-1 '.' AND '.$where_group); if($infinite_exists==0){ reset($temp); $last_bracket=end($temp); $new_id = (int)$this->Conn->GetOne('SELECT MIN('.$bracket->IDField.') FROM '.$bracket->TableName); $brackets_exist = (int)$this->Conn->GetOne('SELECT COUNT(*) FROM '.$bracket->TableName.' WHERE '.$where_group); if($new_id > 0) $new_id = 0; do { $new_id--; } while ($this->check_array($this->Application->GetVar($event->getPrefixSpecial(true)), 'PriceId', $new_id)); $infinite_bracket['PriceId'] = $new_id; $infinite_bracket['MinQty'] = ($brackets_exist>0)?$last_bracket['MaxQty']:1; $infinite_bracket['MaxQty'] = '-1'; $infinite_bracket['Price'] = ''; $infinite_bracket['Cost'] = ''; $infinite_bracket['Points'] = ''; $infinite_bracket['Negotiated'] = '0'; $infinite_bracket['IsPrimary'] = '0'; $infinite_bracket['GroupId'] = $group_id; $temp[$new_id]=$infinite_bracket; reset($temp); } $this->Application->SetVar($event->getPrefixSpecial(true), $temp); $event->CallSubEvent('OnPreSaveBrackets'); break; case 'OnDeleteBrackets': if ($group_id) { $temp = ''; // delete all pricings from "pr_tang" var $sql = 'DELETE FROM ' . $bracket->TableName . ' WHERE ProductId = ' . $this->Application->GetVar('p_id') . ' AND GroupId = ' . $group_id; $this->Conn->Query($sql); } break; default: } $this->Application->SetVar($event->getPrefixSpecial(true), $temp); // store pr_tang var } function OnPreSaveBrackets(kEvent $event) { if( $this->Application->GetVar('pr_tang') ) { /** @var kDBItem $object */ $object = $event->getObject(); $product_id = $this->Application->GetVar('p_id'); $group_id = $this->Application->getVar('group_id'); $sql = 'SELECT PriceId FROM ' . $object->TableName . ' WHERE ProductId = ' . $product_id . ' ' . ($group_id? 'AND GroupId = ' . $group_id : ''); $stored_ids = $this->Conn->GetCol($sql); $items_info = $this->Application->GetVar( $event->getPrefixSpecial(true) ); // get pr_tang var uasort($items_info, 'pr_bracket_comp'); foreach ($items_info as $item_id => $field_values) { if (in_array($item_id, $stored_ids)) { //if it's already exist $object->Load($item_id); $object->SetFieldsFromHash($field_values); $event->setEventParam('form_data', $field_values); if (!$object->Validate()) { unset($stored_ids[array_search($item_id, $stored_ids)]); $event->redirect = false; continue; } if( $object->Update($item_id) ) { $event->status=kEvent::erSUCCESS; } else { $event->status=kEvent::erFAIL; $event->redirect=false; break; } unset($stored_ids[array_search($item_id, $stored_ids)]); } else { $object->Clear(0); $object->SetFieldsFromHash($field_values); $event->setEventParam('form_data', $field_values); $object->SetDBField('ProductId', $product_id); if( $object->Create() ) { $event->status=kEvent::erSUCCESS; } } } // delete foreach ($stored_ids as $stored_id) { $this->Conn->Query('DELETE FROM ' . $object->TableName . ' WHERE PriceId = ' . $stored_id); } } } /** * Apply custom processing to item * * @param kEvent $event * @param string $type * @return void * @access protected */ protected function customProcessing(kEvent $event, $type) { /** @var kDBItem $bracket */ $bracket = $event->getObject(); switch ($type) { case 'before': $bracket->SetDBField('ProductId', $this->Application->GetVar('p_id')); if ( $bracket->GetDBField('MaxQty') == '∞' || $bracket->GetDBField('MaxQty') == '∞' ) { $bracket->SetDBField('MaxQty', -1); } break; } } function OnArrangeBrackets($event, &$temp, &$bracket) { $temp_orig = $temp; reset($temp); if (is_array($temp)) { // array to store max values (2nd column) $end_values = Array(); // get minimal value of Min $first_elem=current($temp); $start = $first_elem['MinQty']; if (!$start){ $start = 1; } foreach($temp as $id => $record) { /* This 3-ifs logic fixes collision with invalid input values having 1 pricing record. The logic is: 1) If we got Max less than Min, we set Min to 1 that gives us integrity. 2) If we got equal values for Min and Max, we set range 1..Max like in previous. But if Min was 1 and Max was 1 we set full range 1..infinity 3) If we got Max = 0 we just set it tom infinity because we can't guess what user meant */ if (sizeof($temp) == 1 && $record['MinQty'] > ($record['MaxQty'] == -1 ? $record['MinQty']+1 : $record['MaxQty']) ){ $record['MinQty'] = 1; $temp[$id]['MinQty'] = 1; $start = 1; } if (sizeof($temp) == 1 && $record['MinQty'] == $record['MaxQty']){ if ($record['MaxQty'] == 1){ $record['MaxQty'] = -1; $temp[$id]['MaxQty'] = -1; } else { $record['MinQty'] = 1; $temp[$id]['MinQty'] = 1; } } if (sizeof($temp) == 1 && $record['MaxQty'] == 0){ $record['MaxQty'] = -1; $temp[$id]['MaxQty'] = -1; } if( // MAX is less than start ($record['MaxQty'] <= $start && $record['MaxQty'] != -1) || // Max is empty !$record['MaxQty'] || // Max already defined in $end_values (array_search($record['MaxQty'], $end_values) !== false) ) { // then delete from brackets list unset($temp[$id]); } else { // this is when ok - add to end_values list $end_values[] = $record['MaxQty']; } } // sort brackets by 2nd column (Max values) uasort($temp, 'pr_bracket_comp'); reset($temp); $first_item_key = key($temp); $group_id = $this->Application->getVar('group_id'); $default_group = $this->Application->ConfigValue('User_LoggedInGroup'); if($group_id>0){ $where_group=' AND GroupId = '.$group_id.' '; } $ids = $this->Conn->GetCol('SELECT PriceId FROM '.$bracket->TableName.' WHERE ProductId='.$this->Application->GetVar('p_id').' '.$where_group); if(is_array($ids)) { usort($ids, 'pr_bracket_id_sort'); } $min_id = min( min($ids) - 1, -1 ); foreach($temp as $key => $record) { $temp[$key]['MinQty']=$start; $temp[$key]['IsPrimary']=0; $temp[$key]['GroupId']=$group_id; $start=$temp[$key]['MaxQty']; } if ($temp[$first_item_key]['GroupId'] == $default_group) { $temp[$first_item_key]['IsPrimary']=1; } } return $temp; } /** * Set's price as primary for product * * @param kEvent $event */ function OnSetPrimary($event) { $object = $event->getObject( Array('skip_autoload' => true) ); $this->StoreSelectedIDs($event); $ids=$this->getSelectedIDs($event); if($ids) { $id = array_shift($ids); $table_info = $object->getLinkedInfo(); $this->Conn->Query('UPDATE '.$object->TableName.' SET IsPrimary = 0 WHERE '.$table_info['ForeignKey'].' = '.$table_info['ParentId']); $this->Conn->Query('UPDATE '.$object->TableName.' SET IsPrimary = 1 WHERE ('.$table_info['ForeignKey'].' = '.$table_info['ParentId'].') AND (PriceId = '.$id.')'); } $event->SetRedirectParam('opener', 's'); } /** * Resets primary mark for other prices of given product, when current pricing is primary * * @param kEvent $event * @return void * @access protected */ protected function OnBeforeItemUpdate(kEvent $event) { parent::OnBeforeItemUpdate($event); /** @var kDBItem $object */ $object = $event->getObject(); if ( $object->GetDBField('IsPrimary') == 1 ) { // make all prices non primary, when this one is $sql = 'UPDATE ' . $object->TableName . ' SET IsPrimary = 0 WHERE (ProductId = ' . $object->GetDBField('ProductId') . ') AND (' . $object->IDField . ' <> ' . $object->GetID() . ')'; $this->Conn->Query($sql); } } /** * Occurs before creating item * * @param kEvent $event * @return void * @access protected */ protected function OnBeforeItemCreate(kEvent $event) { parent::OnBeforeItemCreate($event); /** @var kDBItem $object */ $object = $event->getObject(); $table_info = $object->getLinkedInfo($event->Special); $table_info['ParentId'] = ($table_info['ParentId'] ? $table_info['ParentId'] : 0); if ( $object->GetDBField('IsPrimary') == 1 ) { $sql = 'UPDATE ' . $object->TableName . ' SET IsPrimary = 0 WHERE ' . $table_info['ForeignKey'] . ' = ' . $table_info['ParentId']; $this->Conn->Query($sql); } else { $sql = 'SELECT COUNT(*) FROM ' . $object->TableName . ' WHERE ' . $table_info['ForeignKey'] . ' = ' . $table_info['ParentId']; $prices_qty = $this->Conn->GetOne($sql); if ( $prices_qty == 0 ) { $object->SetDBField('IsPrimary', 1); } } } /** * Apply any custom changes to list's sql query * * @param kEvent $event * @return void * @access protected * @see kDBEventHandler::OnListBuild() */ protected function SetCustomQuery(kEvent $event) { /** @var kDBList $object */ $object = $event->getObject(); if ( $this->Application->isAdminUser ) { return; } if ( $this->Application->ConfigValue('Comm_PriceBracketCalculation') == 1 ) { $sql = 'SELECT PrimaryGroupId FROM ' . TABLE_PREFIX . 'Users WHERE PortalUserId = ' . $this->Application->GetVar('u_id'); $pricing_group = $this->Conn->GetOne($sql); if ( $pricing_group ) { $sql = 'SELECT COUNT(*) FROM ' . TABLE_PREFIX . 'ProductsPricing WHERE ProductId = ' . $this->Application->GetVar('p_id') . ' AND GroupId = ' . $pricing_group . ' AND Price IS NOT NULL'; $pricing_for_group_exists = $this->Conn->GetOne($sql); } if ( !$pricing_group || !$pricing_for_group_exists ) { $pricing_group = $this->Application->ConfigValue('User_LoggedInGroup'); } } else { $user_groups = $this->Application->RecallVar('UserGroups'); //$cheapest_group = $this->Conn->GetOne('SELECT GroupId FROM '.$object->TableName.' WHERE ProductId='.$this->Application->GetVar('p_id').' AND Price IS NOT NULL AND GroupId IN ('.$user_groups.') AND MinQty = 1 GROUP BY GroupId ORDER BY Price ASC'); $sql = 'SELECT PriceId, Price, GroupId FROM ' . $object->TableName . ' WHERE ProductId = ' . $this->Application->GetVar('p_id') . ' AND Price IS NOT NULL AND GroupId IN (' . $user_groups . ') ORDER BY GroupId ASC, MinQty ASC'; $effective_brackets = $this->Conn->Query($sql, 'PriceId'); $group_prices = array (); $min_price = -1; $cheapest_group = 0; foreach ($effective_brackets as $bracket) { if ( !isset($group_prices[$bracket['GroupId']]) ) { $group_prices[$bracket['GroupId']] = $bracket['Price']; if ( $bracket['Price'] < $min_price || $min_price == -1 ) { $min_price = $bracket['Price']; $cheapest_group = $bracket['GroupId']; } } } if ( !$cheapest_group ) { $cheapest_group = $this->Application->ConfigValue('User_LoggedInGroup'); } $pricing_group = $cheapest_group; } $object->addFilter('price_user_group', $object->TableName . '.GroupId=' . $pricing_group); } }