/** * Formats the bean so it is ready to be handed back to the API's client. Certain fields will get extra processing * to make them easier to work with from the client end. * * @param $bean SugarBean|ForecastManagerWorksheet The bean you want formatted * @param $fieldList array Which fields do you want formatted and returned (leave blank for all fields) * @param $options array Currently no options are supported * @return array The bean in array format, ready for passing out the API to clients. */ public function formatForApi(SugarBean $bean, array $fieldList = array(), array $options = array()) { $data = parent::formatForApi($bean, $fieldList, $options); $sq = new SugarQuery(); $sq->select('date_modified'); $sq->from($bean)->where()->equals('assigned_user_id', $bean->assigned_user_id)->equals('user_id', $bean->user_id)->equals('draft', 0)->equals('timeperiod_id', $bean->timeperiod_id); $beans = $sq->execute(); $data['show_history_log'] = 0; if (empty($beans) && !empty($bean->fetched_row['date_modified'])) { /* @var $tp TimePeriod */ $tp = BeanFactory::getBean('TimePeriods', $bean->timeperiod_id); // When reportee has committed but manager has not // make sure that the reportee actually has a commit for the timeperiod, // this is to handle the case where the manager saves draft before the reportee can commit $sq = new SugarQuery(); $sq->select('id'); $sq->from(BeanFactory::getBean('ForecastWorksheets'))->where()->equals('assigned_user_id', $bean->user_id)->equals('draft', 0)->queryAnd()->gte('date_closed_timestamp', $tp->start_date_timestamp)->lte('date_closed_timestamp', $tp->end_date_timestamp); $worksheets = $sq->execute(); if (!empty($worksheets)) { $data['show_history_log'] = 1; } } else { if (!empty($beans)) { $fBean = $beans[0]; $committed_date = $bean->db->fromConvert($fBean["date_modified"], "datetime"); if (strtotime($committed_date) < strtotime($bean->fetched_row['date_modified'])) { $db = DBManagerFactory::getInstance(); // find the differences via the audit table // we use a direct query since SugarQuery can't do the audit tables... $sql = sprintf("SELECT field_name, before_value_string, after_value_string FROM %s\n WHERE parent_id = %s AND date_created >= " . $db->convert('%s', 'datetime'), $bean->get_audit_table_name(), $db->quoted($bean->id), $db->quoted($committed_date)); $results = $db->query($sql); // get the setting for which fields to compare on /* @var $admin Administration */ $admin = BeanFactory::getBean('Administration'); $settings = $admin->getConfigForModule('Forecasts', 'base'); while ($row = $db->fetchByAssoc($results)) { $field = substr($row['field_name'], 0, strpos($row['field_name'], '_')); if ($settings['show_worksheet_' . $field] == "1") { // calculate the difference to make sure it actually changed at 2 digits vs changed at 6 $diff = SugarMath::init($row['after_value_string'], 6)->sub($row['before_value_string'])->result(); // due to decimal rounding on the front end, we only want to know about differences greater // of two decimal places. // todo-sfa: This hardcoded 0.01 value needs to be changed to a value determined by userprefs if (abs($diff) >= 0.01) { $data['show_history_log'] = 1; break; } } } } } } if (!empty($bean->user_id)) { $data['is_manager'] = User::isManager($bean->user_id); } return $data; }
/** * Shows a particular model. */ public function actionShow() { if (!User::isClient() && !User::isManager() && !User::isAdministrator()) { // not enough rights MUserFlash::setTopError(Yii::t('hint', 'We are sorry, but you don\'t have enough rights to browse company payments.')); $this->redirect($this->getGotoUrl()); } $with = array('company'); /*if(User::isClient()) $with[]='company.allUser2Company';*/ $model = $this->loadModel(array('with' => $with)); // may member view this record? if (User::isClient()) { /*$allOwner=array(); if(isset($model->company->allUser2Company)) { foreach($model->company->allUser2Company as $user2Company) { if($user2Company->position===Company::OWNER) $allOwner[]=$user2Company->userId; } } if(!in_array(Yii::app()->user->id,$allOwner))*/ if (!isset($model->company->id) || !$model->company->isOwner()) { MUserFlash::setTopError(Yii::t('hint', 'We are sorry, but you don\'t have enough rights to view the company payment record number {id}.', array('{id}' => MHtml::wrapInTag($model->id, 'strong')))); $this->redirect($this->getGotoUrl()); } } // render the view file $this->render($this->action->id, array('model' => $model)); }
/** * Build out the chart for the sales rep view in the forecast module * * @param ServiceBase $api The Api Class * @param array $args Service Call Arguments * @return mixed */ public function chart($api, $args) { $args['timeperiod_id'] = clean_string($args['timeperiod_id']); $args['user_id'] = clean_string($args['user_id']); $args['group_by'] = !isset($args['group_by']) ? "forecast" : $args['group_by']; // default to the Individual Code $file = 'include/SugarForecasting/Chart/Individual.php'; $klass = 'SugarForecasting_Chart_Individual'; // test to see if we need to display the manager if ((bool) $args['display_manager'] && User::isManager($api->user->id)) { // we have a manager view, pull in the manager classes $file = 'include/SugarForecasting/Chart/Manager.php'; $klass = 'SugarForecasting_Chart_Manager'; } // check for a custom file exists SugarAutoLoader::requireWithCustom($file); $klass = SugarAutoLoader::customClass($klass); // create the class /* @var $obj SugarForecasting_Chart_AbstractChart */ $obj = new $klass($args); return $obj->process(); }
/** * Utility Method to create the filter for the filer API to use * * @param ServiceBase $api Service Api Class * @param mixed $user_id Passed in User ID, if false, it will use the current use from $api->user * @param mixed $timeperiod_id TimePeriod Id, if false, the current time period will be found an used * @param string $forecast_type Type of forecast to return, direct or rollup * @return array The Filer array to be passed back into the filerList Api * @throws SugarApiExceptionNotAuthorized * @throws SugarApiExceptionInvalidParameter */ protected function createFilter(ServiceBase $api, $user_id, $timeperiod_id, $forecast_type) { $filter = array(); // if we did not find a user in the filters array, set it to the current user's id if ($user_id == false) { // use the current user, since on one was passed in $user_id = $api->user->id; } else { // make sure that the passed in user is a valid user /* @var $user User */ // we use retrieveBean so it will return NULL and not an empty bean if the $args['user_id'] is invalid $user = BeanFactory::retrieveBean('Users', $user_id); if (is_null($user) || is_null($user->id)) { throw new SugarApiExceptionInvalidParameter('Provided User is not valid'); } # if they are not a manager, don't show them committed number for others global $mod_strings, $current_language; $mod_strings = return_module_language($current_language, 'Forecasts'); if ($user_id != $api->user->id && !User::isManager($api->user->id)) { throw new SugarApiExceptionNotAuthorized(string_format($mod_strings['LBL_ERROR_NOT_MANAGER'], array($api->user->id, $user_id))); } } // set the assigned_user_id array_push($filter, array('user_id' => $user_id)); if ($forecast_type !== false) { // make sure $forecast_type is valid (e.g. Direct or Rollup) switch (strtolower($forecast_type)) { case 'direct': case 'rollup': break; default: throw new SugarApiExceptionInvalidParameter('Forecast Type of ' . $forecast_type . ' is not valid. Valid options Direct or Rollup.'); } // set the forecast type, make sure it's always capitalized array_push($filter, array('forecast_type' => ucfirst($forecast_type))); } // if we didn't find a time period, set the time period to be the current time period if ($timeperiod_id == false) { $timeperiod_id = TimePeriod::getCurrentId(); } // fix up the timeperiod filter /* @var $tp TimePeriod */ // we use retrieveBean so it will return NULL and not an empty bean if the $args['timeperiod_id'] is invalid $tp = BeanFactory::retrieveBean('TimePeriods', $timeperiod_id); if (is_null($tp) || is_null($tp->id)) { throw new SugarApiExceptionInvalidParameter('Provided TimePeriod is not valid'); } array_push($filter, array('timeperiod_id' => $tp->id)); return $filter; }
/** * @static * This function is used to determine if a given user id is a top level manager. A top level manager is defined as someone * who has direct reports, but does not have to report to anyone (reports_to_id is null). * * This is functionally equivalent to User::isManager($user->id) && empty($user->reports_to_id) * * @param String user_id The id of the user to check * @param boolean include_deleted Boolean value indicating whether or not to include deleted records of reportees (defaults to FALSE) * @return boolean TRUE if user id is a top level manager; FALSE otherwise */ public static function isTopLevelManager($user_id, $include_deleted = false) { if (User::isManager($user_id, $include_deleted)) { $query = 'SELECT reports_to_id FROM users WHERE id = ' . $GLOBALS['db']->quoted(clean_string($user_id)); $reports_to_id = $GLOBALS['db']->getOne($query); return empty($reports_to_id); } return false; }
public static function reassignForecast($fromUserId, $toUserId) { global $current_user; $db = DBManagerFactory::getInstance(); // reassign Opportunities $_object = BeanFactory::getBean('Opportunities'); $_query = "update {$_object->table_name} set " . "assigned_user_id = '{$toUserId}', " . "date_modified = '" . TimeDate::getInstance()->nowDb() . "', " . "modified_user_id = '{$current_user->id}' " . "where {$_object->table_name}.deleted = 0 and {$_object->table_name}.assigned_user_id = '{$fromUserId}'"; $res = $db->query($_query, true); $affected_rows = $db->getAffectedRowCount($res); // Products // reassign only products that have related opportunity - products created from opportunity::save() // other products will be reassigned if module Product is selected by user $_object = BeanFactory::getBean('RevenueLineItems'); $_query = "update {$_object->table_name} set " . "assigned_user_id = '{$toUserId}', " . "date_modified = '" . TimeDate::getInstance()->nowDb() . "', " . "modified_user_id = '{$current_user->id}' " . "where {$_object->table_name}.deleted = 0 and {$_object->table_name}.assigned_user_id = '{$fromUserId}' and {$_object->table_name}.opportunity_id IS NOT NULL "; $res = $db->query($_query, true); $affected_rows += $db->getAffectedRowCount($res); // delete Forecasts $_object = BeanFactory::getBean('Forecasts'); $_query = "update {$_object->table_name} set " . "deleted = 1, " . "date_modified = '" . TimeDate::getInstance()->nowDb() . "' " . "where {$_object->table_name}.deleted = 0 and {$_object->table_name}.user_id = '{$fromUserId}'"; $res = $db->query($_query, true); $affected_rows += $db->getAffectedRowCount($res); // delete Quotas $_object = BeanFactory::getBean('Quotas'); $_query = "update {$_object->table_name} set " . "deleted = 1, " . "date_modified = '" . TimeDate::getInstance()->nowDb() . "' " . "where {$_object->table_name}.deleted = 0 and {$_object->table_name}.user_id = '{$fromUserId}'"; $res = $db->query($_query, true); $affected_rows += $db->getAffectedRowCount($res); // clear reports_to for inactive users $objFromUser = BeanFactory::getBean('Users', $fromUserId, array('deleted' => false)); $fromUserReportsTo = !empty($objFromUser->reports_to_id) ? $objFromUser->reports_to_id : ''; $objFromUser->reports_to_id = ''; $objFromUser->save(); if (User::isManager($fromUserId)) { // setup report_to for user $objToUserId = BeanFactory::getBean('Users'); $objToUserId->retrieve($toUserId); $objToUserId->reports_to_id = $fromUserReportsTo; $objToUserId->save(); // reassign users (reportees) $_object = BeanFactory::getBean('Users'); $_query = "update {$_object->table_name} set " . "reports_to_id = '{$toUserId}', " . "date_modified = '" . TimeDate::getInstance()->nowDb() . "', " . "modified_user_id = '{$current_user->id}' " . "where {$_object->table_name}.deleted = 0 and {$_object->table_name}.reports_to_id = '{$fromUserId}' " . "and {$_object->table_name}.id != '{$toUserId}'"; $db->query($_query, true); } // ForecastWorksheets // reassign entries in forecast_worksheets for the draft rows $_object = BeanFactory::getBean('ForecastWorksheets'); $_query = "update {$_object->table_name} set " . "assigned_user_id = '{$toUserId}', " . "date_modified = '" . TimeDate::getInstance()->nowDb() . "', " . "modified_user_id = '{$current_user->id}' " . "where {$_object->table_name}.deleted = 0 and {$_object->table_name}.draft = 1\n and {$_object->table_name}.assigned_user_id = '{$fromUserId}'"; $res = $db->query($_query, true); $affected_rows += $db->getAffectedRowCount($res); // delete all the committed rows as they are no longer needed $_query = "update {$_object->table_name} set " . "deleted = 1, " . "date_modified = '" . TimeDate::getInstance()->nowDb() . "', " . "modified_user_id = '{$current_user->id}' " . "where {$_object->table_name}.deleted = 0 and {$_object->table_name}.draft = 0\n and {$_object->table_name}.assigned_user_id = '{$fromUserId}'"; $res = $db->query($_query, true); $affected_rows += $db->getAffectedRowCount($res); // ForecastManagerWorksheets // reassign entries in forecast_manager_worksheets $_object = BeanFactory::getBean('ForecastManagerWorksheets'); // delete all manager worksheets for the user we are migrating away from $_query = "update {$_object->table_name} set " . "deleted = 1, " . "date_modified = '" . TimeDate::getInstance()->nowDb() . "', " . "modified_user_id = '{$current_user->id}' " . "where {$_object->table_name}.deleted = 0\n and {$_object->table_name}.user_id = '{$fromUserId}'"; $res = $db->query($_query, true); $affected_rows += $db->getAffectedRowCount($res); // Remove any committed rows that are assigned to the user we are migration away from, since we don't // want to migration committed records $_query = "update {$_object->table_name} set " . "deleted = 1, " . "date_modified = '" . TimeDate::getInstance()->nowDb() . "', " . "modified_user_id = '{$current_user->id}' " . "where {$_object->table_name}.deleted = 0 and {$_object->table_name}.draft = 0\n and {$_object->table_name}.assigned_user_id = '{$fromUserId}'"; $res = $db->query($_query, true); $affected_rows += $db->getAffectedRowCount($res); // move all draft records left over that have not been deleted to the new user. $_query = "update {$_object->table_name} set " . "assigned_user_id = '{$toUserId}', " . "user_id = '{$toUserId}', " . "date_modified = '" . TimeDate::getInstance()->nowDb() . "', " . "modified_user_id = '{$current_user->id}' " . "where {$_object->table_name}.deleted = 0 and {$_object->table_name}.assigned_user_id = '{$fromUserId}' "; $res = $db->query($_query, true); $affected_rows += $db->getAffectedRowCount($res); return $affected_rows; }
/** * Shows a particular model. */ public function actionShow() { if (!User::isClient() && !User::isManager() && !User::isAdministrator()) { // not enough rights MUserFlash::setTopError(Yii::t('hint', 'We are sorry, but you don\'t have enough rights to browse companies.')); $this->redirect($this->getGotoUrl()); } if (isset($_GET['my'])) { // show client's company if (Yii::app()->user->isGuest) { // guest may not have any company MUserFlash::setTopError(Yii::t('hint', 'Please authorize to view your company.')); $this->redirect($this->getGotoUrl()); } if (($user2Company = User2Company::model()->findByAttributes(array('userId' => Yii::app()->user->id, 'position' => Company::OWNER), array('order' => "`companyPriority` ASC"))) !== null) { $id = $user2Company->companyId; } else { // user is not an owner yet MUserFlash::setTopError(Yii::t('hint', 'We are sorry, but you are not the owner of any company yet.')); $this->redirect($this->getGotoUrl()); } } else { // get id from the url $id = isset($_GET['id']) ? $_GET['id'] : 0; } // load model $with = array('allUser'); /*if(User::isClient()) $with[]='allUser2Company';*/ $model = $this->loadModel(array('id' => $id, 'with' => $with)); // may member view this record? if (User::isClient()) { /*$allOwner=array(); foreach($model->allUser2Company as $user2Company) { if($user2Company->position===Company::OWNER) $allOwner[]=$user2Company->userId; } if(!in_array(Yii::app()->user->id,$allOwner))*/ if (!$model->isOwner()) { MUserFlash::setTopError(Yii::t('hint', 'We are sorry, but you don\'t have enough rights to view the company record number {id}.', array('{id}' => MHtml::wrapInTag($model->id, 'strong')))); $this->redirect($this->getGotoUrl()); } } // FIXME: check is owner or manager or admin // transaction's payments $companyPayments = CompanyPayment::model()->findAllByAttributes(array('companyId' => $model->id), new CDbCriteria(array('order' => "`t`.`paymentDate` ASC, `t`.`id` ASC"))); // transaction's invoices $invoices = Invoice::model()->findAllByAttributes(array('companyId' => $model->id), new CDbCriteria(array('order' => "`t`.`invoiceDate` ASC, `t`.`id` ASC"))); // construct tmp array of all transactions. use time as index $array = array(); foreach ($companyPayments as $companyPayment) { $time = strtotime($companyPayment->paymentDate); while (array_key_exists($time, $array)) { $time++; } $array[$time] = array('date' => $companyPayment->paymentDate, 'credit' => $companyPayment->amount, 'number' => $companyPayment->paymentNumber, 'method' => $companyPayment->getAttributeView('paymentMethod'), 'id' => $companyPayment->id, 'controllerId' => 'companyPayment'); } foreach ($invoices as $invoice) { $time = strtotime($invoice->invoiceDate); while (array_key_exists($time, $array)) { $time++; } $array[$time] = array('date' => $invoice->invoiceDate, 'debit' => $invoice->amountTotal, 'id' => $invoice->id, 'controllerId' => 'invoice'); } // sort by index ksort($array); // construct transaction history array $transactions = array(); $balance = $debit = $credit = 0; foreach ($array as $row) { $d = isset($row['debit']) ? $row['debit'] : 0; $c = isset($row['credit']) ? $row['credit'] : 0; $balance = $balance - $d + $c; $debit += $d; $credit += $c; $transactions[] = array('date' => $row['date'], 'debit' => isset($row['debit']) ? $row['debit'] : null, 'credit' => isset($row['credit']) ? $row['credit'] : null, 'number' => isset($row['number']) ? $row['number'] : null, 'method' => isset($row['method']) ? $row['method'] : null, 'balance' => $balance, 'id' => $row['id'], 'controllerId' => $row['controllerId']); } // rows for the static grid $gridRows = array(); foreach ($transactions as $transaction) { $gridRows[] = array(array('align' => 'right', 'content' => CHtml::encode(MDate::format($transaction['date'], 'long', null)), 'title' => CHtml::encode(MDate::format($transaction['date'], 'full', null))), array('content' => CHtml::link($transaction['controllerId'] === 'invoice' ? Yii::t('link', 'Invoice {number}', array('{number}' => $transaction['number'] === null ? $transaction['id'] : $transaction['number'])) : Yii::t('link', 'Payment {number} ({method})', array('{number}' => $transaction['number'] === null ? $transaction['id'] : $transaction['number'], '{method}' => $transaction['method'])), array($transaction['controllerId'] . '/show', 'id' => $transaction['id']))), array('align' => 'right', 'content' => is_numeric($transaction['debit']) ? CHtml::encode(MCurrency::format($transaction['debit'])) : ''), array('align' => 'right', 'content' => is_numeric($transaction['credit']) ? CHtml::encode(MCurrency::format($transaction['credit'])) : ''), array('align' => 'right', 'content' => CHtml::encode(MCurrency::format($transaction['balance'])))); } // render the view file $this->render($this->action->id, array('model' => $model, 'debit' => $debit, 'credit' => $credit, 'balance' => $credit - $debit, 'gridRows' => $gridRows)); }
/** * Returns all the user data to be sent in the REST API call for a normal * `/me` call. * * This data is dependent on the platform used. Each own platform has a * different data set to be sent in the response. * * @param string $platform The platform of the request. * @param array $options A list of options like `category` to retrieve the * basic user info. Will use `global` if no `category` is supplied. * @return array The user's data to be used in a `/me` request. */ protected function getUserData($platform, array $options) { $current_user = $this->getUserBean(); // Get the basics $category = isset($options['category']) ? $options['category'] : 'global'; $user_data = $this->getBasicUserInfo($platform, $category); // Fill in the rest $user_data['type'] = self::TYPE_USER; if ($current_user->isAdmin()) { $user_data['type'] = self::TYPE_ADMIN; } $user_data['show_wizard'] = $this->shouldShowWizard($category); $user_data['id'] = $current_user->id; $current_user->_create_proper_name_field(); $user_data['full_name'] = $current_user->full_name; $user_data['user_name'] = $current_user->user_name; $user_data['roles'] = ACLRole::getUserRoles($current_user->id); $user_data = $this->setExpiredPassword($user_data); $user_data['picture'] = $current_user->picture; $user_data['acl'] = $this->getAcls($platform); $user_data['is_manager'] = User::isManager($current_user->id); $user_data['is_top_level_manager'] = false; $user_data['reports_to_id'] = $current_user->reports_to_id; $user_data['reports_to_name'] = $current_user->reports_to_name; if ($user_data['is_manager']) { $user_data['is_top_level_manager'] = User::isTopLevelManager($current_user->id); } // Address information $user_data['address_street'] = $current_user->address_street; $user_data['address_city'] = $current_user->address_city; $user_data['address_state'] = $current_user->address_state; $user_data['address_country'] = $current_user->address_country; $user_data['address_postalcode'] = $current_user->address_postalcode; require_once 'modules/Teams/TeamSetManager.php'; $teams = $current_user->get_my_teams(); $my_teams = array(); foreach ($teams as $id => $name) { $my_teams[] = array('id' => $id, 'name' => $name); } $user_data['my_teams'] = $my_teams; $defaultTeams = TeamSetManager::getTeamsFromSet($current_user->team_set_id); foreach ($defaultTeams as $id => $team) { $defaultTeams[$id]['primary'] = false; if ($team['id'] == $current_user->team_id) { $defaultTeams[$id]['primary'] = true; } } $user_data['preferences']['default_teams'] = $defaultTeams; // Send back a hash of this data for use by the client $user_data['_hash'] = $current_user->getUserMDHash(); return array('current_user' => $user_data); }
/** * Utility method to build out a tree node array * @param User $user * @param string $rel * @return array */ protected function getTreeArray(User $user, $rel = 'rep') { global $locale; $fullName = $locale->formatName($user); $qa_id = 'jstree_node_'; if ($rel == "my_opportunities") { $qa_id .= 'myopps_'; } $state = ''; if ($rel == 'rep' && User::isManager($user->id)) { // check if the user is a manager and if they are change the rel to be 'manager' $rel = 'manager'; $state = 'closed'; } return array('data' => $fullName, 'children' => array(), 'metadata' => array('id' => $user->id, 'user_name' => $user->user_name, 'full_name' => $fullName, 'first_name' => $user->first_name, 'last_name' => $user->last_name, 'picture' => $user->picture, 'reports_to_id' => $user->reports_to_id, 'reports_to_name' => $user->reports_to_name, 'title' => $user->title, 'is_manager' => User::isManager($user->id), 'is_top_level_manager' => User::isTopLevelManager($user->id)), 'state' => $state, 'attr' => array('rel' => $rel, 'id' => $qa_id . $user->user_name)); }
/** * Print out array of models for the jqGrid rows. */ public function actionGridData() { if (!Yii::app()->request->isPostRequest) { throw new CHttpException(400, Yii::t('http', 'Invalid request. Please do not repeat this request again.')); exit; } // specify request details $jqGrid = $this->processJqGridRequest(); // specify filter parameters $company = isset($_GET['company']) ? $_GET['company'] : null; if ($company !== 'all' && !ctype_digit($company)) { $company = 'all'; } $project = isset($_GET['project']) ? $_GET['project'] : null; if ($project !== 'all' && !ctype_digit($project)) { $project = 'all'; } $billToCompany = isset($_GET['billToCompany']) ? $_GET['billToCompany'] : null; if ($billToCompany !== 'all' && $billToCompany !== (string) Expense::BILL_TO_COMPANY && $billToCompany !== (string) Expense::DO_NOT_BILL_TO_COMPANY) { $billToCompany = 'all'; } // criteria $criteria = new CDbCriteria(); $criteria->group = "`t`.`id`"; // required by together() $criteria->select = "`t`.amount, `t`.billToCompany, `t`.expenseDate"; //$criteria->select="`t`.`amount`, `t`.`billToCompany`, `t`.`expenseDate`"; // uncomment in yii-1.1.2 if ($jqGrid['searchField'] !== null && $jqGrid['searchString'] !== null && $jqGrid['searchOper'] !== null) { $field = array('amount' => "`t`.`amount`", 'billToCompany' => "`t`.`billToCompany`", 'expenseDate' => "`t`.`expenseDate`", 'company' => "`Expense_Company`.`title`", 'project' => "`Expense_Project`.`title`"); $operation = $this->getJqGridOperationArray(); $keywordFormula = $this->getJqGridKeywordFormulaArray(); if (isset($field[$jqGrid['searchField']]) && isset($operation[$jqGrid['searchOper']])) { $criteria->condition = '(' . $field[$jqGrid['searchField']] . ' ' . $operation[$jqGrid['searchOper']] . ' :keyword)'; $criteria->params = array(':keyword' => str_replace('keyword', $jqGrid['searchString'], $keywordFormula[$jqGrid['searchOper']])); // search by special field types if ($jqGrid['searchField'] === 'createTime' && ($keyword = strtotime($jqGrid['searchString'])) !== false) { $criteria->params = array(':keyword' => str_replace('keyword', $keyword, $keywordFormula[$jqGrid['searchOper']])); if (date('H:i:s', $keyword) === '00:00:00') { // visitor is looking for a precision by day, not by second $criteria->condition = '(TO_DAYS(FROM_UNIXTIME(' . $field[$jqGrid['searchField']] . ',"%Y-%m-%d")) ' . $operation[$jqGrid['searchOper']] . ' TO_DAYS(FROM_UNIXTIME(:keyword,"%Y-%m-%d")))'; } } } } if ($company !== 'all') { $criteria->addCondition("`Expense_Company`.`id`=:companyId"); $criteria->params[':companyId'] = $company; } if ($project !== 'all') { $criteria->addCondition("`Expense_Project`.`id`=:projectId"); $criteria->params[':projectId'] = $project; } if ($billToCompany === (string) Expense::BILL_TO_COMPANY) { $criteria->addCondition("`t`.`billToCompany`=:billToCompany"); $criteria->params[':billToCompany'] = Expense::BILL_TO_COMPANY; } else { if ($billToCompany === (string) Expense::DO_NOT_BILL_TO_COMPANY) { $criteria->addCondition("`t`.`billToCompany`=:doNotBillToCompany"); $criteria->params[':doNotBillToCompany'] = Expense::DO_NOT_BILL_TO_COMPANY; } } if (User::isClient()) { $criteria->addCondition("`Company_User2Company`.`userId`=:clientId AND `Company_User2Company`.`position`=:clientPosition"); $criteria->params[':clientId'] = Yii::app()->user->id; $criteria->params[':clientPosition'] = Company::OWNER; } // pagination $with = array(); if (strpos($criteria->condition, 'Expense_Company') !== false) { $with[] = 'company'; } if (strpos($criteria->condition, 'Expense_Project') !== false) { $with[] = 'project'; } if (strpos($criteria->condition, 'Company_User2Company') !== false) { $with[] = 'company.allUser2Company'; } if (count($with) >= 1) { $pages = new CPagination(Expense::model()->with($with)->count($criteria)); } else { $pages = new CPagination(Expense::model()->count($criteria)); } $pages->pageSize = $jqGrid['pageSize'] !== null ? $jqGrid['pageSize'] : self::GRID_PAGE_SIZE; $pages->applyLimit($criteria); //sort $sort = new CSort('Expense'); $sort->attributes = array('amount' => array('asc' => "`t`.`amount`", 'desc' => "`t`.`amount` desc", 'label' => Expense::model()->getAttributeLabel('amount')), 'billToCompany' => array('asc' => "`t`.`billToCompany`", 'desc' => "`t`.`billToCompany` desc", 'label' => Expense::model()->getAttributeLabel('Bill')), 'expenseDate' => array('asc' => "`t`.`expenseDate`", 'desc' => "`t`.`expenseDate` desc", 'label' => Expense::model()->getAttributeLabel('Date')), 'company' => array('asc' => "`Expense_Company`.`title`", 'desc' => "`Expense_Company`.`title` desc", 'label' => Expense::model()->getAttributeLabel('companyId')), 'project' => array('asc' => "`Expense_Project`.`title`", 'desc' => "`Expense_Project`.`title` desc", 'label' => Expense::model()->getAttributeLabel('projectId'))); $sort->defaultOrder = "`t`.`expenseDate` DESC, `t`.`id` DESC"; $sort->applyOrder($criteria); // find all $with = array('company' => array('select' => 'title'), 'project' => array('select' => 'title')); if (strpos($criteria->condition, 'Company_User2Company') !== false) { $with['company.allUser2Company'] = array('select' => 'id'); } $together = strpos($criteria->condition, 'Company_User2Company') !== false; if ($together) { $models = Expense::model()->with($with)->together()->findAll($criteria); } else { $models = Expense::model()->with($with)->findAll($criteria); } // create resulting data array $data = array('page' => $pages->getCurrentPage() + 1, 'total' => $pages->getPageCount(), 'records' => $pages->getItemCount(), 'rows' => array()); foreach ($models as $model) { $data['rows'][] = array('id' => $model->id, 'cell' => array(isset($model->company->id) ? CHtml::link(CHtml::encode($model->company->title), array('company/show', 'id' => $model->company->id)) : '', isset($model->project->id) ? CHtml::link(CHtml::encode($model->project->title), array('project/show', 'id' => $model->project->id)) : '', CHtml::encode(MDate::format($model->expenseDate, 'medium', null)), CHtml::encode($model->amount), CHtml::encode($model->getAttributeView('billToCompany', 'grid')), User::isManager() && empty($model->invoiceId) || User::isAdministrator() ? CHtml::link('<span class="ui-icon ui-icon-zoomin"></span>', array('show', 'id' => $model->id), array('class' => 'w3-ig w3-link-icon w3-border-1px-transparent w3-first ui-corner-all', 'title' => Yii::t('link', 'Show'))) . CHtml::link('<span class="ui-icon ui-icon-pencil"></span>', array('update', 'id' => $model->id), array('class' => 'w3-ig w3-link-icon w3-border-1px-transparent ui-corner-all', 'title' => Yii::t('link', 'Edit'))) . CHtml::link('<span class="ui-icon ui-icon-trash"></span>', array('delete', 'id' => $model->id), array('class' => 'w3-ig w3-link-icon w3-border-1px-transparent w3-last ui-corner-all', 'title' => Yii::t('link', 'Delete the record number {id}', array('{id}' => $model->id)))) : CHtml::link('<span class="ui-icon ui-icon-zoomin"></span>', array('show', 'id' => $model->id), array('class' => 'w3-ig w3-link-icon w3-border-1px-transparent w3-first w3-last ui-corner-all', 'title' => Yii::t('link', 'Show'))))); } $this->printJson($data); }
/** * Retrieves user data for a given user id * * @param ServiceBase $api * @param array $args * @return array */ public function retrieveSelectedUser(ServiceBase $api, $args) { global $locale; $uid = $args['user_id']; /* @var $user User */ $user = BeanFactory::getBean('Users', $uid); $data = array(); $data['id'] = $user->id; $data['user_name'] = $user->user_name; $data['full_name'] = $locale->formatName($user); $data['first_name'] = $user->first_name; $data['last_name'] = $user->last_name; $data['reports_to_id'] = $user->reports_to_id; $data['reports_to_name'] = $user->reports_to_name; $data['is_manager'] = User::isManager($user->id); $data['is_top_level_manager'] = User::isTopLevelManager($user->id); return $data; }
/** * Recalculates a specific user's direct quota * * @param string $userId User Id of quota that needs recalculated. * @param string $timeperiodId the timeperiod to use * @return number The New total for the passed in user */ protected function recalcUserQuota($userId, $timeperiodId) { global $current_user; $isCurrentUser = $current_user->id === $userId; $reporteeTotal = $this->getQuotaSum($userId, $timeperiodId); $managerQuota = $this->getManagerQuota($userId, $timeperiodId); $managerAmount = isset($managerQuota['amount']) && !empty($managerQuota['amount']) ? $managerQuota['amount'] : '0'; $newTotal = SugarMath::init($managerAmount, 6)->sub($reporteeTotal)->result(); $quota = BeanFactory::getBean('Quotas', isset($managerQuota['id']) ? $managerQuota['id'] : null); $quotaAmount = isset($quota->amount) ? $quota->amount : '0'; /** * if this is the current user, we need to use the manager assigned amount to figure out if we need to adjust * their quota to make sure that the reporteeTotal + the current assigned Quota is > the manager assigned * quota, if it's not we need to adjust the mid level managers quota to make up the gap. */ if ($isCurrentUser) { $quotaAmount = $managerAmount; } /** * If the reporteeTotal + the current assigned direct amount is greater than quotaAmount (see above), * then we should just return the current assigned direct quota amount, * * this is also true for top level managers */ if (SugarMath::init($reporteeTotal, 6)->add($quota->amount)->result() > $quotaAmount || $isCurrentUser && empty($current_user->reports_to_id)) { return $quota->amount; } // if a user is not a manager, then just take the value that the manager assigned to them as the rollup and use // it for their direct amount if (User::isManager($userId) === false) { $newTotal = $managerAmount; } //save Manager quota if ($newTotal != $quota->amount) { $quota->user_id = $userId; $quota->timeperiod_id = $timeperiodId; $quota->quota_type = 'Direct'; $quota->amount = $newTotal; $quota->committed = 1; $quota->save(); } return $newTotal; }
/** * Utility Method to create the filter for the filer API to use * * @param ServiceBase $api Service Api Class * @param mixed $user_id Passed in User ID, if false, it will use the current use from $api->user * @param mixed $timeperiod_id TimePeriod Id, if false, the current time period will be found an used * @return array The Filer array to be passed back into the filerList Api * @throws SugarApiExceptionNotAuthorized * @throws SugarApiExceptionInvalidParameter */ protected function createFilter(ServiceBase $api, $user_id, $timeperiod_id) { // we need to check if the $api->user is a manager // if they are not a manager, throw back a 403 (Not Authorized) error if (!User::isManager($api->user->id)) { throw new SugarApiExceptionNotAuthorized(); } $filter = array(); // default draft to be 1 $draft = 1; // if we did not find a user in the filters array, set it to the current user's id if ($user_id == false) { // use the current user, since on one was passed in $user_id = $api->user->id; } else { // make sure that the passed in user is a valid user /* @var $user User */ // we use retrieveBean so it will return NULL and not an empty bean if the $args['user_id'] is invalid $user = BeanFactory::retrieveBean('Users', $user_id); if (is_null($user)) { throw new SugarApiExceptionInvalidParameter('Provided User is not valid'); } // we found a user, so check to make sure that if it's not the current user, they only see committed data $draft = $user_id == $api->user->id ? 1 : 0; } // todo-sfa: Make sure that the passed in user can be viewed by the $api->user, need to check reportee tree // set the assigned_user_id array_push($filter, array('assigned_user_id' => $user_id)); // set the draft flag depending on the assigned_user_id that is set from above array_push($filter, array('draft' => $draft)); // if we didn't find a time period, set the time period to be the current time period if (!is_guid($timeperiod_id) && is_numeric($timeperiod_id) && $timeperiod_id != 0) { // we have a timestamp, find timeperiod it belongs in $timeperiod_id = TimePeriod::getIdFromTimestamp($timeperiod_id); } if (!is_guid($timeperiod_id)) { $timeperiod_id = TimePeriod::getCurrentId(); } // fix up the timeperiod filter /* @var $tp TimePeriod */ // we use retrieveBean so it will return NULL and not an empty bean if the $args['timeperiod_id'] is invalid $tp = BeanFactory::retrieveBean('TimePeriods', $timeperiod_id); if (is_null($tp)) { throw new SugarApiExceptionInvalidParameter('Provided TimePeriod is not valid'); } array_push($filter, array('timeperiod_id' => $tp->id)); return $filter; }
/** * Utility Method to create the filter for the filer API to use * * @param ServiceBase $api Service Api Class * @param mixed $user_id Passed in User ID, if false, it will use the current use from $api->user * @param mixed $timeperiod_id TimePeriod Id, if false, the current time period will be found an used * @param string $parent_type Type of worksheet to return, defaults to 'opportunities', but can be 'products' * @return array The Filer array to be passed back into the filerList Api * @throws SugarApiExceptionNotAuthorized * @throws SugarApiExceptionInvalidParameter */ protected function createFilter(ServiceBase $api, $user_id, $timeperiod_id, $parent_type = 'Opportunities') { $filter = array(); // default draft to be 1 $draft = 1; // if we did not find a user in the filters array, set it to the current user's id if ($user_id == false) { // use the current user, since on one was passed in $user_id = $api->user->id; } else { // make sure that the passed in user is a valid user /* @var $user User */ // we use retrieveBean so it will return NULL and not an empty bean if the $args['user_id'] is invalid $user = BeanFactory::retrieveBean('Users', $user_id); if (is_null($user)) { throw new SugarApiExceptionInvalidParameter('Provided User is not valid'); } // we found a user, so check to make sure that if it's not the current user, they only see committed data $draft = $user_id == $api->user->id ? 1 : 0; } // so we have a valid user, and it's not the $api->user, we need to check if the $api->user is a manager // if they are not a manager, throw back a 403 (Not Authorized) error if ($draft == 0 && !User::isManager($api->user->id)) { throw new SugarApiExceptionNotAuthorized(); } // todo-sfa: Make sure that the passed in user can be viewed by the $api->user, need to check reportee tree // set the assigned_user_id array_push($filter, array('assigned_user_id' => $user_id)); // set the draft flag depending on the assigned_user_id that is set from above array_push($filter, array('draft' => $draft)); // if we didn't find a time period, set the time period to be the current time period if (!is_guid($timeperiod_id) && is_numeric($timeperiod_id) && $timeperiod_id != 0) { // we have a timestamp, find timeperiod it belongs in $timeperiod_id = TimePeriod::getIdFromTimestamp($timeperiod_id); } if (!is_guid($timeperiod_id)) { $timeperiod_id = TimePeriod::getCurrentId(); } // fix up the timeperiod filter /* @var $tp TimePeriod */ // we use retrieveBean so it will return NULL and not an empty bean if the $args['timeperiod_id'] is invalid $tp = BeanFactory::retrieveBean('TimePeriods', $timeperiod_id); if (is_null($tp)) { throw new SugarApiExceptionInvalidParameter('Provided TimePeriod is not valid'); } array_push($filter, array('$and' => array(array('date_closed_timestamp' => array('$gte' => $tp->start_date_timestamp)), array('date_closed_timestamp' => array('$lte' => $tp->end_date_timestamp))))); if (empty($parent_type)) { // get the forecast_by setting /* @var $admin Administration */ $admin = BeanFactory::getBean('Administration'); $settings = $admin->getConfigForModule('Forecasts', $api->platform); $parent_type = $settings['forecast_by']; } // we only want to view parent_types of 'Opportunities' here array_push($filter, array('parent_type' => $parent_type)); return $filter; }