Esempio n. 1
0
 /**
  * createTimePeriodsForUpgrade
  *
  * This function creates the TimePeriods for the case where the system is handling upgrades
  *
  * In the case of upgrades we take the following steps:
  * 1) We find out what the current TimePeriod is (if one exists)
  * 2) We then use the supplied start date of the fiscal period and build leaf TimePeriods backwards until we reach
  * the current TimePeriod
  * 3) The current TimePeriod's end date is adjusted to extend up to the most recent backward leaf TimePeriod(s), if
  * available, or extend out to the day before the start date of the fiscal period
  * 4) We then build out any new forward TimePeriod(s) based on the configuration settings
  *
  * @param $currentSettings Array of the current forecast settings
  * @param $currentDate TimeDate instance of the current date when upgrade was run
  * @return Array of TimePeriod instances created for the upgrade
  */
 public function createTimePeriodsForUpgrade($currentSettings, $currentDate)
 {
     $created = array();
     $isLeafTimePeriod = true;
     $timeperiodInterval = $currentSettings['timeperiod_interval'];
     $timePeriodLeafInterval = $currentSettings['timeperiod_leaf_interval'];
     //Now try to find the current leaf TimePeriod.  We have no way of knowing what the leaf type is so we cannot use TimePeriod::getCurrentId since
     //that assumes a type argument is supplied or it will use the defaults from the config.  So instead we just search based on the closest TimePeriod
     $timedate = TimeDate::getInstance();
     $db = DBManagerFactory::getInstance();
     $query = sprintf("SELECT id FROM timeperiods WHERE start_date <= %s AND (parent_id IS NOT NULL OR parent_id <> '') AND deleted = 0 ORDER BY start_date DESC", $db->convert($db->quoted($currentDate->asDbDate()), 'date'));
     $result = $db->limitQuery($query, 0, 1);
     $currentTimePeriod = null;
     if (!empty($result)) {
         $row = $db->fetchByAssoc($result);
         if (!empty($row)) {
             $currentTimePeriod = new TimePeriod();
             $currentTimePeriod->retrieve($row['id']);
         }
     }
     if (empty($currentTimePeriod)) {
         //If no currentTimePeriod instance was found, just use the most recent upcoming TimePeriod instance
         $query = sprintf("SELECT id FROM timeperiods WHERE start_date > %s AND parent_id IS NOT NULL AND deleted = 0 ORDER BY start_date ASC", $db->convert($db->quoted($currentDate->asDbDate()), 'date'));
         $result = $db->limitQuery($query, 0, 1);
         $row = $db->fetchByAssoc($result);
         if (!empty($row)) {
             $currentTimePeriod = new TimePeriod();
             $currentTimePeriod->retrieve($row['id']);
         }
         if (empty($currentTimePeriod)) {
             //One last attempt using timeperiods without parent_id
             $query = sprintf("SELECT id FROM timeperiods WHERE start_date <= %s AND end_date >= %s AND parent_id IS NULL AND deleted = 0 ORDER BY start_date ASC", $db->convert($db->quoted($currentDate->asDbDate()), 'date'), $db->convert($db->quoted($currentDate->asDbDate()), 'date'));
             $result = $db->limitQuery($query, 0, 1);
             $row = $db->fetchByAssoc($result);
             if (!empty($row)) {
                 $currentTimePeriod = new TimePeriod();
                 $currentTimePeriod->retrieve($row['id']);
                 $isLeafTimePeriod = false;
             }
             //If a current TimePeriod still cannot be determined, just create a leaf with the correct current start date for the current date
             if (empty($currentTimePeriod)) {
                 $currentTimePeriod = TimePeriod::getByType($timePeriodLeafInterval);
                 $currentTimePeriod->setStartDate($this->determineCurrentStartDateByType($timePeriodLeafInterval, $timedate->getNow()->asDbDate()));
                 $currentTimePeriod->save();
                 $created[] = $currentTimePeriod;
             }
         }
     }
     //Now mark all TimePeriods that start after the current TimePeriod to be deleted
     $db->query(sprintf("UPDATE timeperiods SET deleted = 1 WHERE start_date >= %s", $db->convert($db->quoted($currentTimePeriod->start_date), 'date')));
     //Delete the current TimePeriod itself since we will re-create it with the appropriate type attributes and adjusted end date
     $db->query(sprintf("DELETE FROM timeperiods WHERE id = %s", $db->quoted($currentTimePeriod->id)));
     $currentEndDate = $timedate->fromDbDate($currentTimePeriod->end_date);
     $selectedStartDate = $timedate->fromDbDate($currentSettings["timeperiod_start_date"]);
     $targetStartDate = $timedate->getNow()->setDate($currentEndDate->format('Y'), $selectedStartDate->format('m'), $selectedStartDate->format('d'));
     //Now create the new TimePeriods with the forward date modifier
     $timePeriod = TimePeriod::getByType($timeperiodInterval);
     //If the target starting date is before the current year's starting date, keep incrementing the year until we are past the current TimePeriod's end date
     while ($targetStartDate < $currentEndDate) {
         $targetStartDate->modify($timePeriod->next_date_modifier);
     }
     //Create a parent TimePeriod instance
     $currentParentTimePeriodInstance = TimePeriod::getByType($timeperiodInterval);
     $currentParentTimePeriodInstance->setStartDate($timedate->fromDbDate($targetStartDate->asDbDate())->modify($currentParentTimePeriodInstance->previous_date_modifier)->asDbDate());
     $currentParentTimePeriodInstance->name = $currentParentTimePeriodInstance->getTimePeriodName(1);
     $currentParentTimePeriodInstance->save();
     $created[] = $currentParentTimePeriodInstance;
     //Now get the leaf type we will be building
     $leaf = TimePeriod::getByType($timePeriodLeafInterval);
     $leafCycle = $timePeriod->leaf_periods;
     //If we are to create any TimePeriods leading back to the current TimePeriod's end date, we'd first start with
     //a TimePeriod one back of the target start date
     $previousLeafTimePeriodStartDate = $timedate->fromDbDate($targetStartDate->asDbDate())->modify($leaf->previous_date_modifier);
     //While the current date is before any potential previous leaf TimePeriod start date, create leaf TimePeriod
     while ($isLeafTimePeriod && $currentEndDate < $previousLeafTimePeriodStartDate || $currentDate < $previousLeafTimePeriodStartDate && $isLeafTimePeriod == false) {
         $previousLeafTimePeriod = TimePeriod::getByType($leaf->type);
         $previousLeafTimePeriod->setStartDate($previousLeafTimePeriodStartDate->asDbDate());
         $previousLeafTimePeriod->leaf_cycle = $leafCycle;
         $previousLeafTimePeriod->name = $previousLeafTimePeriod->getTimePeriodName($leafCycle);
         $previousLeafTimePeriod->parent_id = $currentParentTimePeriodInstance->id;
         $previousLeafTimePeriod->save();
         $created[] = $previousLeafTimePeriod;
         $leafCycle--;
         $previousLeafTimePeriodStartDate = $previousLeafTimePeriodStartDate->modify($leaf->previous_date_modifier);
     }
     //The current TimePeriod end date is now the last unadjusted previousLeafTimePeriodStartDate value
     $newCurrentTimePeriod = TimePeriod::getByType($leaf->type);
     $newCurrentTimePeriod->new_with_id = true;
     $newCurrentTimePeriod->id = $currentTimePeriod->id;
     $newCurrentTimePeriod->parent_id = $currentParentTimePeriodInstance->id;
     if ($isLeafTimePeriod) {
         $newCurrentTimePeriod->setStartDate($currentTimePeriod->start_date);
     } else {
         $newCurrentTimePeriod->setStartDate($previousLeafTimePeriodStartDate->asDbDate());
     }
     $newCurrentTimePeriod->end_date = $previousLeafTimePeriodStartDate->modify($leaf->next_date_modifier)->modify('-1 day')->asDbDate();
     $newCurrentTimePeriod->leaf_cycle = $leafCycle;
     $newCurrentTimePeriod->name = $newCurrentTimePeriod->getTimePeriodName($leafCycle);
     $newCurrentTimePeriod->save();
     $created[] = $newCurrentTimePeriod;
     //We set it back once here since the buildTimePeriods code triggers the modification immediately
     //$targetStartDate->modify($timePeriod->previous_date_modifier);
     $timePeriod->setStartDate($targetStartDate->asDbDate());
     return array_merge($created, $timePeriod->buildTimePeriods($currentSettings['timeperiod_shown_forward'], 'forward'));
 }