/**
  * populateSeedData
  *
  * This is a static function to create TimePeriods.
  *
  * @static
  * @return array Array of TimePeriods created
  */
 public static function populateSeedData()
 {
     //Simulate settings to create 2 forward and 2 backward timeperiods
     $settings = array();
     $settings['timeperiod_start_date'] = date("Y") . "-01-01";
     $settings['timeperiod_interval'] = TimePeriod::ANNUAL_TYPE;
     $settings['timeperiod_leaf_interval'] = TimePeriod::QUARTER_TYPE;
     $settings['timeperiod_shown_backward'] = 2;
     $settings['timeperiod_shown_forward'] = 2;
     $timePeriod = TimePeriod::getByType(TimePeriod::ANNUAL_TYPE);
     $timePeriod->rebuildForecastingTimePeriods(array(), $settings);
     $ids = TimePeriod::get_not_fiscal_timeperiods_dom();
     $timeperiods = array();
     foreach ($ids as $id => $name) {
         $timeperiods[$id] = TimePeriod::getBean($id);
     }
     return $timeperiods;
 }
 /**
  * Collect up the timeperiod data
  *
  * @return array
  * @throws SugarQueryException
  */
 private function getCurrentTimePeriod()
 {
     $admin = BeanFactory::getBean('Administration');
     $settings = $admin->getConfigForModule('Forecasts', 'base');
     $forward = $settings['timeperiod_shown_forward'];
     $backward = $settings['timeperiod_shown_backward'];
     $type = $settings['timeperiod_interval'];
     $leafType = $settings['timeperiod_leaf_interval'];
     $timeDate = TimeDate::getInstance();
     $timePeriods = array();
     $current = TimePeriod::getCurrentTimePeriod($type);
     //If the current TimePeriod cannot be found for the type, just create one using the current date as a reference point
     if (empty($current)) {
         $current = TimePeriod::getByType($type);
         $current->setStartDate($timeDate->getNow()->asDbDate());
     }
     $startDate = $timeDate->fromDbDate($current->start_date);
     //Move back for the number of backward TimePeriod(s)
     while ($backward-- > 0) {
         $startDate->modify($current->previous_date_modifier);
     }
     $endDate = $timeDate->fromDbDate($current->end_date);
     //Increment for the number of forward TimePeriod(s)
     while ($forward-- > 0) {
         $endDate->modify($current->next_date_modifier);
     }
     $db = DBManagerFactory::getInstance();
     $sq = new SugarQuery();
     $sq->from(BeanFactory::getBean('TimePeriods'));
     $sq->select(array('id', 'name'));
     $sq->where()->notNull('parent_id')->gte('start_date', $startDate->asDbDate())->lte('start_date', $endDate->asDbDate())->addRaw("coalesce({$db->convert('type', 'length')},0) > 0");
     $sq->orderBy('start_date', 'ASC');
     $beans = $sq->execute();
     //I am gather all of these as I might have to update more than one time period in the future
     foreach ($beans as $row) {
         $timePeriods['list'][$row['id']] = $row;
     }
     //the one is the current time period
     $current = TimePeriod::getCurrentTimePeriod();
     $timePeriods['current'] = $current->id;
     return $timePeriods;
 }
 /**
  * This method implements the run function of RunnableSchedulerJob and handles processing a SchedulersJob
  *
  * @param Mixed $data parameter passed in from the job_queue.data column when a SchedulerJob is run
  * @return bool true on success, false on error
  */
 public function run($data)
 {
     global $app_strings, $language;
     $app_strings = return_application_language($language);
     $admin = BeanFactory::getBean('Administration');
     $config = $admin->getConfigForModule('Forecasts', 'base');
     $timeperiodInterval = $config['timeperiod_interval'];
     $timeperiodLeafInterval = $config['timeperiod_leaf_interval'];
     $parentTimePeriod = TimePeriod::getLatest($timeperiodInterval);
     $latestTimePeriod = TimePeriod::getLatest($timeperiodLeafInterval);
     $currentTimePeriod = TimePeriod::getCurrentTimePeriod($timeperiodLeafInterval);
     if (empty($latestTimePeriod)) {
         $GLOBALS['log']->error(string_format($app_strings['ERR_TIMEPERIOD_TYPE_DOES_NOT_EXIST'], array($timeperiodLeafInterval)) . '[latest]');
         return false;
     } else {
         if (empty($currentTimePeriod)) {
             $GLOBALS['log']->error(string_format($app_strings['ERR_TIMEPERIOD_TYPE_DOES_NOT_EXIST'], array($timeperiodLeafInterval)) . ' [current]');
             return false;
         } else {
             if (empty($parentTimePeriod)) {
                 $GLOBALS['log']->error(string_format($app_strings['ERR_TIMEPERIOD_TYPE_DOES_NOT_EXIST'], array($timeperiodLeafInterval)) . ' [parent]');
                 return false;
             }
         }
     }
     $timedate = TimeDate::getInstance();
     //We run the rebuild command if the latest TimePeriod is less than the specified configuration interval
     //from the current TimePeriod
     $correctStartDate = $timedate->fromDbDate($currentTimePeriod->start_date);
     $latestStartDate = $timedate->fromDbDate($latestTimePeriod->start_date);
     $shownForward = $config['timeperiod_shown_forward'];
     //Move the current start date forward by the leaf period amounts
     for ($x = 0; $x < $shownForward; $x++) {
         $correctStartDate->modify($parentTimePeriod->next_date_modifier);
     }
     $leafCycle = $latestTimePeriod->leaf_cycle;
     //If the current start data that was modified according to the shown forward period is past the latest
     //leaf period we need to build more timeperiods
     while ($correctStartDate > $latestStartDate) {
         //We need to keep creating leaf periods until we are in sync.
         //If the leaf period we need to create is the start of the leaf cycle
         //then we should also create the parent TimePeriod record.
         $startDate = $latestStartDate->modify($latestTimePeriod->next_date_modifier);
         $leafCycle = $leafCycle == $parentTimePeriod->leaf_periods ? 1 : $leafCycle + 1;
         if ($leafCycle == 1) {
             $parentTimePeriod = TimePeriod::getByType($timeperiodInterval);
             $parentTimePeriod->setStartDate($startDate->asDbDate());
             $parentTimePeriod->name = $parentTimePeriod->getTimePeriodName($leafCycle);
             $parentTimePeriod->save();
         }
         $leafTimePeriod = TimePeriod::getByType($timeperiodLeafInterval);
         $leafTimePeriod->setStartDate($startDate->asDbDate());
         $leafTimePeriod->name = $leafTimePeriod->getTimePeriodName($leafCycle, $parentTimePeriod);
         $leafTimePeriod->leaf_cycle = $leafCycle;
         $leafTimePeriod->parent_id = $parentTimePeriod->id;
         $leafTimePeriod->save();
     }
     $this->job->succeedJob();
     return true;
 }
Example #4
0
 /**
  * Returns the latest TimePeriod bean instance for the given timeperiod interval type
  *
  * @param $type String value of the TimePeriod interval type
  * @return $bean The latest TimePeriod bean instance; null if none found
  */
 public static function getLatest($type)
 {
     $db = DBManagerFactory::getInstance();
     $result = $db->limitQuery(sprintf("SELECT * FROM timeperiods WHERE type = '%s' AND deleted = 0 ORDER BY start_date_timestamp DESC", $type), 0, 1);
     if ($result) {
         $row = $db->fetchByAssoc($result);
         if (!empty($row)) {
             return TimePeriod::getByType($type, $row['id']);
         }
     }
     return null;
 }
 /**
  * Forecast Override since we have custom logic that needs to be ran
  *
  * {@inheritdoc}
  */
 public function forecastsConfigSave(ServiceBase $api, array $args)
 {
     //acl check, only allow if they are module admin
     if (!$api->user->isAdmin() && !$api->user->isDeveloperForModule('Forecasts')) {
         // No create access so we construct an error message and throw the exception
         $failed_module_strings = return_module_language($GLOBALS['current_language'], 'forecasts');
         $moduleName = $failed_module_strings['LBL_MODULE_NAME'];
         $args = null;
         if (!empty($moduleName)) {
             $args = array('moduleName' => $moduleName);
         }
         throw new SugarApiExceptionNotAuthorized($GLOBALS['app_strings']['EXCEPTION_CHANGE_MODULE_CONFIG_NOT_AUTHORIZED'], $args);
     }
     $admin = BeanFactory::getBean('Administration');
     //track what settings have changed to determine if timeperiods need rebuilt
     $prior_forecasts_settings = $admin->getConfigForModule('Forecasts', $api->platform);
     //If this is a first time setup, default prior settings for timeperiods to 0 so we may correctly recalculate
     //how many timeperiods to build forward and backward.  If we don't do this we would need the defaults to be 0
     if (empty($prior_forecasts_settings['is_setup'])) {
         $prior_forecasts_settings['timeperiod_shown_forward'] = 0;
         $prior_forecasts_settings['timeperiod_shown_backward'] = 0;
     }
     $upgraded = 0;
     if (!empty($prior_forecasts_settings['is_upgrade'])) {
         $db = DBManagerFactory::getInstance();
         // check if we need to upgrade opportunities when coming from version below 6.7.x.
         $upgraded = $db->getOne("SELECT count(id) AS total FROM upgrade_history\n                    WHERE type = 'patch' AND status = 'installed' AND version LIKE '6.7.%'");
         if ($upgraded == 1) {
             //TODO-sfa remove this once the ability to map buckets when they get changed is implemented (SFA-215).
             $args['has_commits'] = true;
         }
     }
     if (isset($args['show_custom_buckets_options'])) {
         $json = getJSONobj();
         $_args = array('dropdown_lang' => isset($_SESSION['authenticated_user_language']) ? $_SESSION['authenticated_user_language'] : $GLOBALS['current_language'], 'dropdown_name' => 'commit_stage_custom_dom', 'view_package' => 'studio', 'list_value' => $json->encode($args['show_custom_buckets_options']), 'skip_sync' => true);
         $_REQUEST['view_package'] = 'studio';
         require_once 'modules/ModuleBuilder/parsers/parser.dropdown.php';
         $parser = new ParserDropDown();
         $parser->saveDropDown($_args);
         unset($args['show_custom_buckets_options']);
     }
     // we do the double check here since the front ent will send one one value if the input is empty
     if (empty($args['worksheet_columns']) || empty($args['worksheet_columns'][0])) {
         // set the defaults
         $args['worksheet_columns'] = array('commit_stage', 'parent_name', 'likely_case');
         if ($args['show_worksheet_best'] == 1) {
             $args['worksheet_columns'][] = 'best_case';
         }
         if ($args['show_worksheet_worst'] == 1) {
             $args['worksheet_columns'][] = 'worst_case';
         }
     }
     //reload the settings to get the current settings
     $current_forecasts_settings = parent::configSave($api, $args);
     // setting are saved, reload the setting in the ForecastBean just in case.
     Forecast::getSettings(true);
     // now that we have saved the setting, we need to sync all the data if
     // this is being upgraded or the forecast was not setup before.
     if ($upgraded || empty($prior_forecasts_settings['is_setup'])) {
         if ($args['forecast_by'] === 'Opportunities') {
             SugarAutoLoader::load('include/SugarQueue/jobs/SugarJobUpdateOpportunities.php');
             SugarJobUpdateOpportunities::updateOpportunitiesForForecasting();
         } else {
             SugarAutoLoader::load('include/SugarQueue/jobs/SugarJobUpdateRevenueLineItems.php');
             SugarJobUpdateRevenueLineItems::scheduleRevenueLineItemUpdateJobs();
         }
     }
     // did this change?
     if ($prior_forecasts_settings['worksheet_columns'] !== $args['worksheet_columns']) {
         $this->setWorksheetColumns($api, $args['worksheet_columns'], $current_forecasts_settings['forecast_by']);
     }
     //if primary settings for timeperiods have changed, then rebuild them
     if ($this->timePeriodSettingsChanged($prior_forecasts_settings, $current_forecasts_settings)) {
         $timePeriod = TimePeriod::getByType($current_forecasts_settings['timeperiod_interval']);
         $timePeriod->rebuildForecastingTimePeriods($prior_forecasts_settings, $current_forecasts_settings);
     }
     return $current_forecasts_settings;
 }
Example #6
0
 /**
  * @return TimePeriod
  */
 public function getTimeperiod()
 {
     $config = $this->getForecastConfig();
     $type = $config['timeperiod_leaf_interval'];
     $id = $this->getArg('timeperiod_id');
     if (!is_guid($id) && is_numeric($id)) {
         $id = TimePeriod::getIdFromTimestamp($id, $type);
     }
     return TimePeriod::getByType($type, $id);
 }