Example #1
0
WriMoImp* wrimoimp::WriMoImpTest::getNovemberImp()
{
	Date startDate(CalendarYear::NOVEMBER, 1, 2015);
	Date endDate(CalendarYear::NOVEMBER, 30, 2015);

	return new WriMoImp(startDate, endDate);
}
Example #2
0
static Opm::TimeMapPtr createXDaysTimeMap(size_t numDays) {
    boost::gregorian::date startDate( 2010 , boost::gregorian::Jan , 1);
    Opm::TimeMapPtr timeMap(new Opm::TimeMap(boost::posix_time::ptime(startDate)));
    for (size_t i = 0; i < numDays; i++)
        timeMap->addTStep( boost::posix_time::hours( (i+1) * 24 ));
    return timeMap;
}
Example #3
0
void Task::processTemplate() {
    Template* temp = readTemplate(*_templateName);
    std::vector<string> subtasks = temp->subTaskList();
    int subId = 1;
    for (std::vector<string>::iterator iterSub = subtasks.begin(); iterSub != subtasks.end(); iterSub++) {
        string subtask = *iterSub;
        int posPar = subtask.find('(');
        int posFin = subtask.find(')');

        string tempSub = subtask.substr(posPar + 1, posFin - posPar - 1);
        string subTaskName = subtask.substr(0, posPar);

        Task* sub = new Task(_project);
        std::stringstream ssId;
        ssId << *id() << "." << subId++;
        sub->setId(new string(ssId.str()));
        sub->setDuration(Duration(1, 0, 0));
        sub->setEndDate(endDate());
        sub->setShortDescription(new string(subTaskName));
        sub->setStartDate(startDate());
        sub->setStatus(status());
        sub->setTemplateName(new string(tempSub));

        _project->addTask(sub);
        if (errorOcurred()) {
            return;
        }
        sub->processTemplate();
    }
}
Example #4
0
void tst_storage::tst_alldayUtc()
{
  // test event saved with UTC time
  auto event = KCalCore::Event::Ptr(new KCalCore::Event);
  QDate startDate(2013, 12, 1);
  event->setDtStart(KDateTime(startDate, QTime(), KDateTime::UTC));
  event->setAllDay(true);
  event->setSummary("test event utc");

  QCOMPARE(event->allDay(), true);

  m_calendar->addEvent(event, NotebookId);
  m_storage->save();
  QString uid = event->uid();
  reloadDb();

  auto fetchedEvent = m_calendar->event(uid);
  QVERIFY(fetchedEvent.data());
  QVERIFY(fetchedEvent->dtStart().isUtc());

  KDateTime localStart = fetchedEvent->dtStart().toLocalZone();
  QVERIFY(localStart.time() == QTime(2, 0));

  KDateTime localEnd = fetchedEvent->dtEnd().toLocalZone();
  QVERIFY(localEnd.time() == QTime(2, 0));

  QCOMPARE(localEnd.date(), localStart.date().addDays(1));
}
Example #5
0
static std::shared_ptr< Opm::TimeMap > createXDaysTimeMap(size_t numDays) {
    boost::gregorian::date startDate( 2010 , boost::gregorian::Jan , 1);
    auto timeMap = std::make_shared< Opm::TimeMap >(boost::posix_time::ptime(startDate));
    for (size_t i = 0; i < numDays; i++)
        timeMap->addTStep( boost::posix_time::hours( (i+1) * 24 ));
    return timeMap;
}
Example #6
0
void tst_storage::tst_rawEvents()
{
  // TODO: Should split tests if making more cases outside storage
  auto event = KCalCore::Event::Ptr(new KCalCore::Event);
  // NOTE: no other events should be made happening this day
  QDate startDate(2010, 12, 1);
  event->setDtStart(KDateTime(startDate, QTime(12, 0), KDateTime::ClockTime));
  event->setDtEnd(KDateTime(startDate, QTime(13, 0), KDateTime::ClockTime));

  KCalCore::Recurrence *recurrence = event->recurrence();
  recurrence->setDaily(1);
  recurrence->setStartDateTime(event->dtStart());

  m_calendar->addEvent(event, NotebookId);
  m_storage->save();
  QString uid = event->uid();
  reloadDb();

  auto fetchEvent = m_calendar->event(uid);
  QVERIFY(fetchEvent);
  KCalCore::Recurrence *fetchRecurrence = fetchEvent->recurrence();
  QVERIFY(fetchRecurrence);

  // should return occurrence for both days
  mKCal::ExtendedCalendar::ExpandedIncidenceList events
      = m_calendar->rawExpandedEvents(startDate, startDate.addDays(1), false, false, KDateTime::Spec(KDateTime::LocalZone));

  QCOMPARE(events.size(), 2);
}
Example #7
0
int DiagramList::readList(const SensorData* data, std::vector<DiagramList*> &lists)
{
	const std::vector<SensorDataType::type> time_series_names (data->getTimeSeriesNames());
	int nLists(time_series_names.size());

	std::vector<size_t> time_steps;
	if (data->getStepSize()>0)
	{
		const size_t start    = data->getStartTime();
		const size_t end      = data->getEndTime();
		const size_t stepsize = data->getStepSize();
		for (size_t i = start; i <= end;  i+=stepsize)
			time_steps.push_back(i);
	}
	else
		time_steps = data->getTimeSteps();

	bool is_date (false);

	if (!(BaseLib::int2date(time_steps[0])).empty())
		is_date = true;


	size_t nValues (time_steps.size());

	for (int i = 0; i < nLists; i++)
	{
		DiagramList* l = new DiagramList;
		l->setName(QString::fromStdString(SensorData::convertSensorDataType2String(time_series_names[i])));
		l->setXLabel("Time");
		lists.push_back(l);

		const std::vector<float> *time_series = data->getTimeSeries(time_series_names[i]);

		if (is_date)
		{
			l->setXUnit("day");
			QDateTime startDate(getDateTime(QString::fromStdString(BaseLib::int2date(time_steps[0]))));
			lists[i]->setStartDate(startDate);
			int numberOfSecs(0);
			for (size_t j = 0; j < nValues; j++)
			{
				numberOfSecs = startDate.secsTo(getDateTime(QString::fromStdString(BaseLib::int2date(time_steps[j]))));
				lists[i]->addNextPoint(numberOfSecs, (*time_series)[j]);
			}
		}
		else
		{
			l->setXUnit("time step");
			for (size_t j = 0; j < nValues; j++)
				lists[i]->addNextPoint(time_steps[j], (*time_series)[j]);
		}

		lists[i]->update();
	}

	return nLists;
}
QVariant ChartItemModel::bcwpCost( int day ) const
{
    QVariant res;
    QDate date = startDate().addDays( day );
    if ( m_bcws.days().contains( date ) ) {
        res = m_bcws.bcwpCost( date );
    }
    return res;
}
Example #9
0
QDate DailyRecurrence::nextOccurrence(const QDate &date, bool include_equals) const {
	const KCalendarSystem *calSys = KGlobal::locale()->calendar();
	if(include_equals) {
		if(date == startDate()) return date;
	}
	QDate nextdate = date;
	if(!include_equals) nextdate = calSys->addDays(nextdate, 1);
	if(!endDate().isNull() && nextdate > endDate()) return QDate();
	if(nextdate <= startDate()) return firstOccurrence();
	if(i_frequency != 1) {
		int days = startDate().daysTo(nextdate);
		if(days % i_frequency != 0) {
			nextdate = calSys->addDays(nextdate, i_frequency - (days % i_frequency));
		}
	}
	if(!endDate().isNull() && nextdate > endDate()) return QDate();
	if(hasException(nextdate)) return nextOccurrence(nextdate);
	return nextdate;
}
Example #10
0
QDate DailyRecurrence::prevOccurrence(const QDate &date, bool include_equals) const {
	const KCalendarSystem *calSys = KGlobal::locale()->calendar();
	if(!include_equals) {
		if(date > endDate()) return lastOccurrence();
	}
	QDate prevdate = date;
	if(!include_equals) prevdate = calSys->addDays(prevdate, -1);
	if(prevdate < startDate()) return QDate();
	if(prevdate == startDate()) return startDate();
	if(i_frequency != 1) {
		int days = startDate().daysTo(prevdate);
		if(days % i_frequency != 0) {
			prevdate = calSys->addDays(prevdate, -(days % i_frequency));
		}
	}
	if(prevdate < startDate()) return QDate();
	if(hasException(prevdate)) return prevOccurrence(prevdate);
	return prevdate;
}
Example #11
0
double ChartItemModel::bcwpEffort( int day ) const
{
    double res = 0.0;
    QDate date = startDate().addDays( day );
    if ( m_bcws.days().contains( date ) ) {
        res = m_bcws.bcwpEffort( date );
    } else if ( date > m_bcws.endDate() ) {
        res = m_bcws.bcwpEffort( date );
    }
    return res;
}
Example #12
0
QDate WeeklyRecurrence::nextOccurrence(const QDate &date, bool include_equals) const {
	const KCalendarSystem *calSys = KGlobal::locale()->calendar();
	if(!include_equals) {
		if(date < startDate()) return firstOccurrence();
	} else {
		if(date <= startDate()) return firstOccurrence();
	}
	QDate nextdate = date;
	if(!include_equals) nextdate = calSys->addDays(nextdate, 1);
	if(!endDate().isNull() && nextdate > endDate()) return QDate();
	if(i_frequency != 1 && calSys->weekNumber(nextdate) != calSys->weekNumber(startDate())) {
		int i = weeks_between_dates(startDate(), nextdate) % i_frequency;
		if(i != 0) {
			nextdate = calSys->addDays(nextdate, (i_frequency - i) * 7 - (calSys->dayOfWeek(nextdate) - 1));
		}
	}
	int dow = calSys->dayOfWeek(nextdate);
	int i = dow;
	for(; i <= 7; i++) {
		if(b_daysofweek[i - 1]) {
			break;
		}
	}
	if(i > 7) {
		for(i = 1; i <= 7; i++) {
			if(b_daysofweek[i - 1]) {
				break;
			}
		}
		if(i > 7) return QDate();
	}
	if(i < dow) {
		nextdate = calSys->addDays(nextdate, (i_frequency * 7) + i - dow);
	} else if(i > dow) {
		nextdate = calSys->addDays(nextdate, i - dow);
	}
	if(!endDate().isNull() && nextdate > endDate()) return QDate();
	if(hasException(nextdate)) return nextOccurrence(nextdate);
	return nextdate;
}
boost::optional<IdfObject> ForwardTranslator::translateScheduleYear( ScheduleYear & modelObject )
{
  IdfObject scheduleYear = createRegisterAndNameIdfObject(openstudio::IddObjectType::Schedule_Year,
                                                          modelObject);

  std::vector<ScheduleWeek> scheduleWeeks = modelObject.scheduleWeeks();
  std::vector<openstudio::Date> dates = modelObject.dates();
  
  unsigned N = scheduleWeeks.size();

  if( N != dates.size() )
  {
    LOG(Error,"Could not translate " << modelObject.briefDescription() << ", because the number of week schedules does not match the number of dates.");

    return boost::none;
  }

  boost::optional<ScheduleTypeLimits> scheduleTypeLimits = modelObject.scheduleTypeLimits();
  if (scheduleTypeLimits){
    boost::optional<IdfObject> idfScheduleTypeLimits = translateAndMapModelObject(*scheduleTypeLimits);
    if (idfScheduleTypeLimits){
      scheduleYear.setString(Schedule_YearFields::ScheduleTypeLimitsName, idfScheduleTypeLimits->name().get());
    }
  }

  openstudio::Date startDate(MonthOfYear::Jan, 1);

  scheduleYear.clearExtensibleGroups();

  for (unsigned i = 0; i < N; ++i){
    IdfExtensibleGroup group = scheduleYear.pushExtensibleGroup();

    boost::optional<IdfObject> idfScheduleWeek = translateAndMapModelObject(scheduleWeeks[i]);
    if (idfScheduleWeek){
      group.setString(Schedule_YearExtensibleFields::Schedule_WeekName, idfScheduleWeek->name().get());
    }

    group.setInt(Schedule_YearExtensibleFields::StartMonth, startDate.monthOfYear().value());
    group.setUnsigned(Schedule_YearExtensibleFields::StartDay, startDate.dayOfMonth());
    group.setInt(Schedule_YearExtensibleFields::EndMonth, dates[i].monthOfYear().value());
    group.setUnsigned(Schedule_YearExtensibleFields::EndDay, dates[i].dayOfMonth());

    startDate = dates[i] + openstudio::Time(1,0,0);
  }

  return scheduleYear;
}
Example #14
0
	//=============================================================================
	// Compare two DateTimes  and calculate the elapsed time
	//==============================================================================
	PeriodData TimeComparer::Compare(const DateTime& start, const DateTime& end)
	{
		PeriodData pd;
		//Convert both DateTime to ISO for comparison
		PartialDateTime endDate(end);
		PartialDateTime startDate(start);

		if (calmath::ExtractTime(endDate.GetFixed()) < calmath::ExtractTime(startDate.GetFixed()))
		{
			endDate = PartialDateTime(start);
			startDate = PartialDateTime(end);
		}

		pd.elapsedHours = endDate.GetHour() - startDate.GetHour();
		pd.elapsedMinutes = endDate.GetMinute() - startDate.GetMinute();
		pd.elapsedSeconds = endDate.GetSecond() - startDate.GetSecond();
		pd.elapsedMilliseconds = endDate.GetMilliSecond() - startDate.GetMilliSecond();


		//borrow to avoid negatives
		if (pd.elapsedMilliseconds < 0)
		{
			pd.elapsedSeconds -= 1;
			pd.elapsedMilliseconds += 1000;
		}

		if (pd.elapsedSeconds < 0)
		{
			pd.elapsedMinutes -= 1;
			pd.elapsedSeconds += 60;
		}

		if (pd.elapsedMinutes < 0)
		{
			pd.elapsedHours -= 1;
			pd.elapsedMinutes += 60;
		}

		// set unused date fields
		pd.elapsedYears = 0;
		pd.elapsedMonths = 0;
		pd.elapsedWeeks = 0;
		pd.elapsedDays = 0;

		return pd;
	}
Example #15
0
	//=============================================================================
	// Compare two DateTimes  and calculate the elapsed time
	//==============================================================================
	PeriodData YearWeekDayComparer::Compare(const DateTime& start, const DateTime& end)
	{
		PeriodData pd;
		//Convert both DateTime to ISO for comparison
		PartialDateTime endDate(end);
		PartialDateTime startDate(start);

		SwapPositiveElapsed(startDate, endDate);

		CalcBaseDateDiff(pd, startDate, endDate);

		if (pd.elapsedMonths< 0 || (pd.elapsedMonths == 0 && pd.elapsedDays < 0))
		{
			//Need to move years back 1
			pd.elapsedYears -= 1;

		}

		//We create a PartialDateTime for the last full year then count remaining days and weeks
		PartialDateTime pDt(startDate.GetYear() + pd.elapsedYears, startDate.GetMonth(), 1, CalType::CalType_ISO);
		//we set to first of month in case the start date is on a leap year
		FixedDateTime intermediateDT = calmath::ExtractDate(pDt.GetFixed());
		if (startDate.GetMonth() == 2 && startDate.GetDay() == 29)
		{
			if (pDt.IsLeapYear())
				intermediateDT += (29 - 1);
			else
				intermediateDT += (28 - 1);
		}
		else
			intermediateDT += (startDate.GetDay() - 1);

		//Find diffrence in days
		pd.elapsedDays = static_cast<int>(calmath::ExtractDate(endDate.GetFixed()) - intermediateDT);
		pd.elapsedWeeks = pd.elapsedDays / 7;
		pd.elapsedDays = pd.elapsedDays % 7;

		// set elapsed months to unused
		SetUnusedDateFields(pd, false, true, false, false);
		// set time to unused
		SetUnusedTimeFields(pd, true, true, true, true);

		return pd;
	}
Example #16
0
QDate WeeklyRecurrence::prevOccurrence(const QDate &date, bool include_equals) const {
	const KCalendarSystem *calSys = KGlobal::locale()->calendar();
	if(!include_equals) {
		if(date > endDate()) return lastOccurrence();
	}
	QDate prevdate = date;
	if(!include_equals) prevdate = calSys->addDays(prevdate, -1);
	if(prevdate < startDate()) return QDate();
	if(prevdate == startDate()) return startDate();
	if(i_frequency != 1 && calSys->weekNumber(prevdate) != calSys->weekNumber(startDate())) {
		int i = weeks_between_dates(startDate(), prevdate) % i_frequency;
		if(i != 0) {
			prevdate = calSys->addDays(prevdate, -(i * 7) + 7 - calSys->dayOfWeek(prevdate));
		}
	}
	int dow_s = calSys->dayOfWeek(startDate());
	bool s_week = calSys->weekNumber(prevdate) == calSys->weekNumber(startDate());
	int dow = calSys->dayOfWeek(prevdate);
	int i = dow;
	for(; i <= 7; i++) {
		if(b_daysofweek[i - 1] || (s_week && dow_s == i)) {
			break;
		}
	}
	if(i > 7) {
		for(i = 1; i <= 7; i++) {
			if(b_daysofweek[i - 1] || (s_week && dow_s == i)) {
				break;
			}
		}
		if(i > 7) return QDate();
	}
	if(i > dow) {
		prevdate = calSys->addDays(prevdate, -(i_frequency * 7) + dow - i);
	} else if(i < dow) {
		prevdate = calSys->addDays(prevdate, dow - i);
	}
	if(prevdate < startDate()) return QDate();
	if(hasException(prevdate)) return prevOccurrence(prevdate);
	return prevdate;
}
int DateTime::WeekOfMonth() const
{
    int year, month, day;
    GetDateFromTimeValue( Value(), year, month, day);

    //get the first day of the month and determine its weekday
    //then use this weekday as offset
    DateTime startDate( year, month, 1, 0, 0, 0);
    int nWeekday = startDate.Weekday();
    int arWeek[6];
    arWeek[0] = 0;
    arWeek[1] = 7 - nWeekday;

    //init the week array
    for( int i = 2; i < 6; ++i) arWeek[i] = arWeek[i-1] + 7;

    int week = 5;
    while( day <= arWeek[week] ) week--;
    return week + 1;
}
  openstudio::TimeSeries ScheduleFixedInterval_Impl::timeSeries() const
  {
    Date startDate(openstudio::MonthOfYear(this->startMonth()), this->startDay());
    Time intervalLength(0, 0, this->intervalLength());

    Vector values(this->numExtensibleGroups());
    unsigned i = 0;
    for (const ModelExtensibleGroup& group : castVector<ModelExtensibleGroup>(extensibleGroups()))
    {
      OptionalDouble x = group.getDouble(0);
      OS_ASSERT(x);
      values[i] = *x;
      ++i;
    }

    TimeSeries result(startDate, intervalLength, values, "");
    result.setOutOfRangeValue(this->outOfRangeValue());

    return result;
  }
QVariant ChartItemModel::headerData( int section, Qt::Orientation orientation, int role ) const
{
    QVariant result;
    if ( role == Qt::DisplayRole ) {
        if ( orientation == Qt::Horizontal ) {
            switch ( section ) {
                case 0: return i18nc( "Cost based Budgeted Cost of Work Scheduled", "BCWS Cost" );
                case 1: return i18nc( "Cost based Budgeted Cost of Work Performed", "BCWP Cost" );
                case 2: return i18nc( "Cost based Actual Cost of Work Performed", "ACWP Cost" );
                case 3: return i18nc( "Effort based Budgeted Cost of Work Scheduled", "BCWS Effort" );
                case 4: return i18nc( "Effort based Budgeted Cost of Work Performed", "BCWP Effort" );
                case 5: return i18nc( "Effort based Actual Cost of Work Performed", "ACWP Effort" );
                default: return QVariant();
            }
        } else {
            return startDate().addDays( section ).toString( i18nc( "Date format used as chart axis labels. Must follow QDate specification.", "MM.dd" ) );
        }
    }  else if ( role == KDChart::DatasetBrushRole ) {
        if ( orientation == Qt::Horizontal ) {
            switch ( section ) {
                case 0: result = QBrush( Qt::red ); break;
                case 1: result = QBrush( Qt::green ); break;
                case 2: result = QBrush( Qt::blue ); break;
                case 3: result = QBrush( Qt::cyan ); break;
                case 4: result = QBrush( Qt::magenta ); break;
                case 5: result = QBrush( Qt::darkYellow ); break;
                default: break;
            }
            //kDebug()<<this<<orientation<<section<<"DatasetBrushRole"<<result;
            return result;
        }
    }  else if ( role == KDChart::DatasetPenRole ) {
        QPen p;
        p.setBrush( headerData( section, orientation, KDChart::DatasetBrushRole ).value<QBrush>() );
        result = p;
        //kDebug()<<section<<"DatasetPenRole"<<result;
        return result;
    }
    return ItemModelBase::headerData(section, orientation, role);
}
Example #20
0
void tst_storage::tst_alldayRecurrence()
{
  auto event = KCalCore::Event::Ptr(new KCalCore::Event);

  QDate startDate(2013, 12, 1);
  event->setDtStart(KDateTime(startDate, QTime(), KDateTime::ClockTime));
  event->setAllDay(true);

  KCalCore::Recurrence *recurrence = event->recurrence();
  recurrence->setWeekly(1);
  recurrence->setStartDateTime(event->dtStart());

  m_calendar->addEvent(event, NotebookId);
  m_storage->save();
  QString uid = event->uid();
  reloadDb();

  auto fetchEvent = m_calendar->event(uid);
  QVERIFY(fetchEvent);
  KCalCore::Recurrence *fetchRecurrence = fetchEvent->recurrence();
  QVERIFY(fetchRecurrence);
  KDateTime match = recurrence->getNextDateTime(KDateTime(startDate));
  QCOMPARE(match, KDateTime(startDate.addDays(7), QTime(), KDateTime::ClockTime));
}
Example #21
0
QDate YearlyRecurrence::nextOccurrence(const QDate &date, bool include_equals) const {
	const KCalendarSystem *calSys = KGlobal::locale()->calendar();
	if(!include_equals) {
		if(date < startDate()) return firstOccurrence();
	} else {
		if(date <= startDate()) return firstOccurrence();
	}
	QDate nextdate = date;
	if(!include_equals) nextdate = calSys->addDays(nextdate, 1);
	if(!endDate().isNull() && nextdate > endDate()) return QDate();
	if(calSys->year(nextdate) == calSys->year(startDate())) {
		nextdate = calSys->addYears(nextdate, i_frequency);
		calSys->setYMD(nextdate, calSys->year(nextdate), 1, 1);
	} else if(i_frequency != 1) {
		int i = (calSys->year(nextdate) - calSys->year(startDate())) % i_frequency;
		if(i != 0) {
			nextdate = calSys->addYears(nextdate, i_frequency - i);
			calSys->setYMD(nextdate, calSys->year(nextdate), 1, 1);
		}
	}
	if(i_dayofyear > 0) {
		if(calSys->dayOfYear(nextdate) > i_dayofyear) {
			nextdate = calSys->addYears(nextdate, i_frequency);
		}
		if(i_dayofyear > calSys->daysInYear(nextdate)) {
			int i = 10;
			do {
				if(i == 0) return QDate();
				nextdate = calSys->addYears(nextdate, i_frequency);
				i--;
			} while(i_dayofyear > calSys->daysInYear(nextdate));
		}
		nextdate = calSys->addDays(nextdate, i_dayofyear - calSys->dayOfYear(nextdate));
	} else {
		int day = i_dayofmonth;
		if(i_dayofweek > 0) day = get_day_in_month(calSys->year(nextdate), i_month, i_week, i_dayofweek);
		if(day == 0 || calSys->month(nextdate) > i_month || (calSys->month(nextdate) == i_month && calSys->day(nextdate) > day)) {
			do {
				nextdate = calSys->addYears(nextdate, i_frequency);
				day = get_day_in_month(calSys->year(nextdate), i_month, i_week, i_dayofweek);
				if(!endDate().isNull() && calSys->year(nextdate) > calSys->year(endDate())) return QDate();
			} while(day == 0);
		}
		if(i_dayofweek <= 0) {
			calSys->setYMD(nextdate, calSys->year(nextdate), i_month, 1);
			if(day > calSys->daysInMonth(nextdate)) {
				int i = 10;
				do {
					if(i == 0) return QDate();
					nextdate = calSys->addYears(nextdate, i_frequency);
					calSys->setYMD(nextdate, calSys->year(nextdate), i_month, 1);
					i--;
				} while(day > calSys->daysInMonth(nextdate));
			}
		}
		calSys->setYMD(nextdate, calSys->year(nextdate), i_month, day);
	}
	if(!endDate().isNull() && nextdate > endDate()) return QDate();
	if(hasException(nextdate)) return nextOccurrence(nextdate);
	return nextdate;
}
double ChartItemModel::acwpCost( int day ) const
{
    return m_acwp.costTo( startDate().addDays( day ) );
}
double ChartItemModel::acwpEffort( int day ) const
{
    return m_acwp.hoursTo( startDate().addDays( day ) );
}
bool RecurrenceWidget::save(bool externaltxn, RecurrenceChangePolicy cp, QString *message)
{
  if (! message)
    message = new QString();

  if (DEBUG)
    qDebug("%s::save(%d, %d, %p) entered with id %d type %s",
           qPrintable(objectName()), externaltxn, cp, message, _parentId,
           qPrintable(_parentType));

  if (! modified())
    return true;

  if (_parentId < 0 || _parentType.isEmpty())
  {
    *message = tr("Could not save Recurrence information. The "
                  "parent object/event has not been set.");
    if (! externaltxn)
      QMessageBox::warning(this, tr("Missing Data"), *message);
    else
      qWarning("%s", qPrintable(*message));
    return false;
  }

  if (! externaltxn && cp == NoPolicy)
  {
    cp = getChangePolicy();
    if (cp == NoPolicy)
      return false;
  }
  else if (externaltxn && cp == NoPolicy)
  {
    *message = tr("You must choose how open events are to be handled");
    qWarning("%s", qPrintable(*message));
    return false;
  }

  XSqlQuery rollbackq;
  if (! externaltxn)
  {
    XSqlQuery beginq("BEGIN;");
    rollbackq.prepare("ROLLBACK;");
  }

  XSqlQuery recurq;
  if (isRecurring())
  {
    if (_id > 0)
    {
      if (cp == ChangeFuture)
      {
        XSqlQuery futureq;
        futureq.prepare("SELECT splitRecurrence(:parent_id, :parent_type,"
                        "                       :splitdate) AS newrecurid;");
        futureq.bindValue(":parent_id",   _parentId);
        futureq.bindValue(":parent_type", _parentType);
        futureq.bindValue(":splitdate",   startDate());
        futureq.exec();
        if (futureq.first())
        {
          int result = futureq.value("newrecurid").toInt();
          if (result > 0)
          {
            _id = result;
            futureq.prepare("SELECT recur_parent_id"
                            "  FROM recur"
                            " WHERE recur_id=:recur_id;");
            futureq.bindValue(":recur_id", _id);
            futureq.exec();
            if (futureq.first())
              _parentId = futureq.value("recur_parent_id").toInt();
          }
          else if (result < 0)
          {
            *message = storedProcErrorLookup("splitRecurrence", result);
            if (! externaltxn)
            {
              rollbackq.exec();
              QMessageBox::warning(this, tr("Processing Error"), *message);
            }
            else
              qWarning("%s", qPrintable(*message));
            return false;
          }
        }
        // one check for potentially 2 queries
        if (futureq.lastError().type() != QSqlError::NoError)
        {
          *message = futureq.lastError().text();
          if (! externaltxn)
          {
            rollbackq.exec();
            QMessageBox::warning(this, tr("Database Error"), *message);
          }
          else
            qWarning("%s", qPrintable(*message));
          return false;
        }
      }

      recurq.prepare("UPDATE recur SET"
                     "  recur_parent_id=:recur_parent_id,"
                     "  recur_parent_type=UPPER(:recur_parent_type),"
                     "  recur_period=:recur_period,"
                     "  recur_freq=:recur_freq,"
                     "  recur_start=:recur_start,"
                     "  recur_end=:recur_end,"
                     "  recur_max=:recur_max"
                     " WHERE (recur_id=:recurid)"
                     " RETURNING recur_id;");
      recurq.bindValue(":recurid", _id);
    }
    else
    {
      recurq.prepare("INSERT INTO recur ("
                     "  recur_parent_id,  recur_parent_type,"
                     "  recur_period,     recur_freq,"
                     "  recur_start,      recur_end,"
                     "  recur_max"
                     ") VALUES ("
                     "  :recur_parent_id, UPPER(:recur_parent_type),"
                     "  :recur_period,    :recur_freq,"
                     "  :recur_start,     :recur_end,"
                     "  :recur_max"
                     ") RETURNING recur_id;");
    }

    recurq.bindValue(":recur_parent_id",   _parentId);
    recurq.bindValue(":recur_parent_type", _parentType);
    recurq.bindValue(":recur_period",      periodCode());
    recurq.bindValue(":recur_freq",        frequency());
    recurq.bindValue(":recur_start",       startDateTime());
    if (endDate() < _eot.date())
      recurq.bindValue(":recur_end",       endDateTime());
    recurq.bindValue(":recur_max",         max());
    recurq.exec();
    if (recurq.first())
    {
      _id = recurq.value("recur_id").toInt();
      _prevParentId      = _parentId;
      _prevParentType    = _parentType;
      _prevEndDateTime   = endDateTime();
      _prevFrequency     = frequency();
      _prevMax           = max();
      _prevPeriod        = period();
      _prevRecurring     = isRecurring();
      _prevStartDateTime = startDateTime();
    }
  }
  else // ! isRecurring()
  {
    recurq.prepare("DELETE FROM recur"
                   " WHERE ((recur_parent_id=:recur_parent_id)"
                   "    AND (UPPER(recur_parent_type)=UPPER(:recur_parent_type)));");
    recurq.bindValue(":recur_parent_id",   _parentId);
    recurq.bindValue(":recur_parent_type", _parentType);
    recurq.exec();
  }

  if (recurq.lastError().type() != QSqlError::NoError)
  {
    *message = recurq.lastError().text();
    if (! externaltxn)
    {
      rollbackq.exec();
      QMessageBox::warning(this, tr("Database Error"), *message);
    }
    else
      qWarning("%s", qPrintable(*message));
    return false;
  }

  if (cp == ChangeFuture)
  {
    int procresult = -1;
    QString procname = "deleteOpenRecurringItems";
    XSqlQuery cfq;
    cfq.prepare("SELECT deleteOpenRecurringItems(:parentId, :parentType,"
                "                                :splitdate, false) AS result;");
    cfq.bindValue(":parentId",   _parentId);
    cfq.bindValue(":parentType", _parentType);
    cfq.bindValue(":splitdate",  startDate());
    cfq.exec();
    if (cfq.first())
    {
      procresult = cfq.value("result").toInt();
      if (procresult >= 0)
      {
        QString procname = "createOpenRecurringItems";
        cfq.prepare("SELECT createRecurringItems(:parentId, :parentType)"
                    "       AS result;");
        cfq.bindValue(":parentId",   _parentId);
        cfq.bindValue(":parentType", _parentType);
        cfq.exec();
        if (cfq.first())
          procresult = cfq.value("result").toInt();
      }
    }

    // error handling for either 1 or 2 queries so not elseif
    // check cfq.lastError() first to avoid misreporting db errs as -1
    if (cfq.lastError().type() != QSqlError::NoError)
    {
      *message = cfq.lastError().text();
      if (! externaltxn)
      {
        rollbackq.exec();
        QMessageBox::critical(this, tr("Database Error"), *message);
      }
      else
        qWarning("%s", qPrintable(*message));
      return false;
    }
    else if (procresult < 0)
    {
      *message = storedProcErrorLookup(procname, procresult);
      if (! externaltxn)
      {
        rollbackq.exec();
        QMessageBox::critical(this, tr("Processing Error"), *message);
      }
      else
        qWarning("%s", qPrintable(*message));
      return false;
    }
  }

  if (! externaltxn)
    XSqlQuery commitq("COMMIT;");
  return true;
}
Example #25
0
QDate MonthlyRecurrence::prevOccurrence(const QDate &date, bool include_equals) const {
	const KCalendarSystem *calSys = KGlobal::locale()->calendar();
	if(!include_equals) {
		if(date > endDate()) return lastOccurrence();
	}
	QDate prevdate = date;
	if(!include_equals) prevdate = calSys->addDays(prevdate, -1);
	if(prevdate < startDate()) return QDate();
	if(prevdate == startDate()) return startDate();
	int prevday = -1;
	if(i_frequency != 1 && calSys->month(prevdate) != calSys->month(startDate())) {
		int i = months_between_dates(startDate(), prevdate) % i_frequency;
		if(i != 0) {
			if(i > 1) prevday = 1;
			else prevday = calSys->day(prevdate);
			prevdate = calSys->addMonths(prevdate, -i);
			calSys->setYMD(prevdate, calSys->year(prevdate), calSys->month(prevdate), calSys->daysInMonth(prevdate));
		}
	}
	if(calSys->month(prevdate) == calSys->month(startDate())) return startDate();
	int day = i_day;
	if(i_dayofweek > 0) day = get_day_in_month(prevdate, i_week, i_dayofweek);
	else if(i_day < 1) day = calSys->daysInMonth(prevdate) + i_day;
	if(wh_weekendhandling == WEEKEND_HANDLING_BEFORE) {
		QDate date;
		calSys->setYMD(date, calSys->year(prevdate), calSys->month(prevdate), day);
		int wday = calSys->dayOfWeek(date);
		if(wday == 6) day -= 1;
		else if(wday == 7) day -= 2;
		if(day <= 0) {
			prevdate = calSys->addMonths(prevdate, -1);
			day = calSys->daysInMonth(prevdate) + day;
		}
	} else if(wh_weekendhandling == WEEKEND_HANDLING_AFTER) {
		QDate date;
		calSys->setYMD(date, calSys->year(prevdate), calSys->month(prevdate), day);
		int wday = calSys->dayOfWeek(date);
		if(wday == 6) day += 2;
		else if(wday == 7) day += 1;
		if(day > calSys->daysInMonth(prevdate) && prevday > 0 && prevday >= day - calSys->daysInMonth(prevdate)) {
			day -= calSys->daysInMonth(prevdate);
			prevdate = calSys->addMonths(prevdate, 1);
			calSys->setYMD(prevdate, calSys->year(prevdate), calSys->month(prevdate), day);
		}
	}
	if(day <= 0 || calSys->day(prevdate) < day) {
		do {
			if(i_frequency > 1) prevday = 1;
			else prevday = calSys->day(prevdate);
			prevdate = calSys->addMonths(prevdate, -i_frequency);
			if(calSys->month(prevdate) == calSys->month(startDate())) return startDate();
			if(calSys->month(prevdate) < calSys->month(startDate())) return QDate();
			day = i_day;
			if(i_dayofweek > 0) day = get_day_in_month(prevdate, i_week, i_dayofweek);
			else if(i_day < 1) day = calSys->daysInMonth(prevdate) + i_day;
			if(wh_weekendhandling == WEEKEND_HANDLING_BEFORE) {
				QDate date;
				calSys->setYMD(date, calSys->year(prevdate), calSys->month(prevdate), day);
				int wday = calSys->dayOfWeek(date);
				if(wday == 6) day -= 1;
				else if(wday == 7) day -= 2;
				if(day <= 0) {
					prevdate = calSys->addMonths(prevdate, -1);
					day = calSys->daysInMonth(prevdate) + day;
				}
			} else if(wh_weekendhandling == WEEKEND_HANDLING_AFTER) {
				QDate date;
				calSys->setYMD(date, calSys->year(prevdate), calSys->month(prevdate), day);
				int wday = calSys->dayOfWeek(date);
				if(wday == 6) day += 2;
				else if(wday == 7) day += 1;
				if(day > calSys->daysInMonth(prevdate) && prevday > 0 && prevday >= day - calSys->daysInMonth(prevdate)) {
					day -= calSys->daysInMonth(prevdate);
					prevdate = calSys->addMonths(prevdate, 1);
					calSys->setYMD(prevdate, calSys->year(prevdate), calSys->month(prevdate), day);
				} else {
					calSys->setYMD(prevdate, calSys->year(prevdate), calSys->month(prevdate), calSys->daysInMonth(prevdate));
				}
			}
		} while(day <= 0 || day > calSys->daysInMonth(prevdate));
	}
	calSys->setYMD(prevdate, calSys->year(prevdate), calSys->month(prevdate), day);
	if(prevdate < startDate()) return QDate();
	if(hasException(prevdate)) return prevOccurrence(prevdate);
	return prevdate;
}
Example #26
0
// [[Rcpp::export]]
Rcpp::List affineWithRebuiltCurveEngine(Rcpp::List rparam,
                                        Rcpp::List legparams,
                                        std::vector<QuantLib::Date> dateVec, 
                                        std::vector<double> zeroVec,
                                        Rcpp::NumericVector swaptionMat,
                                        Rcpp::NumericVector swapLengths,
                                        Rcpp::NumericVector swaptionVols) {
    
    // std::vector<std::string> tsnames = tslist.names();

    
    QuantLib::Size i;
    //int *swaptionMat=0, *swapLengths=0;
    //double **swaptionVols=0;

    double notional = 10000; // prices in basis points

    QuantLib::Date todaysDate(Rcpp::as<QuantLib::Date>(rparam["tradeDate"])); 
    QuantLib::Date settlementDate(Rcpp::as<QuantLib::Date>(rparam["settleDate"])); 
    QuantLib::Date startDate(Rcpp::as<QuantLib::Date>(rparam["startDate"])); 
    QuantLib::Date maturity(Rcpp::as<QuantLib::Date>(rparam["maturity"])); 
    bool payfix = Rcpp::as<bool>(rparam["payFixed"]);
    bool european = Rcpp::as<bool>(rparam["european"]);
    
    
    //cout << "TradeDate: " << todaysDate << endl << "Settle: " << settlementDate << endl;
    
    RQLContext::instance().settleDate = settlementDate;
    QuantLib::Settings::instance().evaluationDate() = todaysDate;
    
    // initialise from the singleton instance
    QuantLib::Calendar calendar = RQLContext::instance().calendar;
    //Integer fixingDays = RQLContext::instance().fixingDays;
    
    double strike = Rcpp::as<double>(rparam["strike"]);
    std::string method = Rcpp::as<std::string>(rparam["method"]);

    QuantLib::Handle<QuantLib::YieldTermStructure> 
        rhTermStructure(rebuildCurveFromZeroRates(dateVec, zeroVec));
    
    // Get swaption maturities
    //Rcpp::NumericVector swaptionMat(maturities);
    int numRows = swaptionMat.size(); 

    // Create dummy swap to get schedules.
    QuantLib::Frequency fixedLegFrequency = getFrequency(Rcpp::as<double>(legparams["fixFreq"]));
    QuantLib::BusinessDayConvention fixedLegConvention = QuantLib::Unadjusted;
    QuantLib::BusinessDayConvention floatingLegConvention = QuantLib::ModifiedFollowing;
    QuantLib::DayCounter swFixedLegDayCounter = getDayCounter(Rcpp::as<double>(legparams["dayCounter"]));
    boost::shared_ptr<QuantLib::IborIndex> swFloatingLegIndex(new QuantLib::Euribor(QuantLib::Period(Rcpp::as<int>(legparams["floatFreq"]),QuantLib::Months),rhTermStructure));


    QuantLib::Rate dummyFixedRate = 0.03;

    QuantLib::Schedule fixedSchedule(startDate,maturity,
                                     QuantLib::Period(fixedLegFrequency),calendar,
                                     fixedLegConvention,fixedLegConvention,
                                     QuantLib::DateGeneration::Forward,false);
    QuantLib::Schedule floatSchedule(startDate,maturity,QuantLib::Period(Rcpp::as<int>(legparams["floatFreq"]),QuantLib::Months),
                                     calendar,
                                     floatingLegConvention,floatingLegConvention,
                                     QuantLib::DateGeneration::Forward,false);
    
    QuantLib::VanillaSwap::Type type;
    
    if(payfix){
        type = QuantLib::VanillaSwap::Payer;} 
    else{
        type = QuantLib::VanillaSwap::Receiver;    
    }
    boost::shared_ptr<QuantLib::VanillaSwap> 
        swap(new QuantLib::VanillaSwap(type, notional,
                                       fixedSchedule, dummyFixedRate, swFixedLegDayCounter,
                                       floatSchedule, swFloatingLegIndex, 0.0,
                                       swFloatingLegIndex->dayCounter()));
    swap->setPricingEngine(boost::shared_ptr<QuantLib::PricingEngine>(new QuantLib::DiscountingSwapEngine(rhTermStructure)));

    // Find the ATM or break-even rate
    QuantLib::Rate fixedATMRate = swap->fairRate();

    QuantLib::Rate fixedRate;
    if(strike < 0) // factor instead of real strike
        fixedRate = fixedATMRate * (-strike);
    else
        fixedRate = strike;

    // The swap underlying the Affine swaption.
    boost::shared_ptr<QuantLib::VanillaSwap> 
        mySwap(new QuantLib::VanillaSwap(type, notional,
                                         fixedSchedule, fixedRate,swFixedLegDayCounter,
                                         floatSchedule, swFloatingLegIndex, 0.0,
                                         swFloatingLegIndex->dayCounter()));
    swap->setPricingEngine(boost::shared_ptr<QuantLib::PricingEngine>(new QuantLib::DiscountingSwapEngine(rhTermStructure)));

    
    // Build swaptions that will be used to calibrate model to
    // the volatility matrix.
    std::vector<QuantLib::Period> swaptionMaturities;
    for(i = 0; i < (QuantLib::Size)numRows; i++)
        swaptionMaturities.push_back(QuantLib::Period(swaptionMat[i], QuantLib::Years));
    
    // Swaptions used for calibration
    std::vector<boost::shared_ptr<QuantLib::BlackCalibrationHelper> > swaptions;

    // List of times that have to be included in the timegrid
    std::list<QuantLib::Time> times;
    for (i=0; i<(QuantLib::Size)numRows; i++) {
        //boost::shared_ptr<QuantLib::Quote> vol(new QuantLib::SimpleQuote(swaptionVols[i][numCols-i-1]));
        boost::shared_ptr<QuantLib::Quote> vol(new QuantLib::SimpleQuote(swaptionVols(i)));
        swaptions.push_back(boost::shared_ptr<QuantLib::BlackCalibrationHelper>(new QuantLib::SwaptionHelper(swaptionMaturities[i],
                                                                                                             QuantLib::Period(swapLengths[i], QuantLib::Years),
                                                                                                             QuantLib::Handle<QuantLib::Quote>(vol),
                                                                                                             swFloatingLegIndex,
                                                                                                             swFloatingLegIndex->tenor(),
                                                                                                             swFloatingLegIndex->dayCounter(),
                                                                                                             swFloatingLegIndex->dayCounter(),
                                                                                                             rhTermStructure)));
        swaptions.back()->addTimesTo(times);
    }
    
    // Building time-grid
    QuantLib::TimeGrid grid(times.begin(), times.end(), 30);

    
    // Get Affine swaption exercise dates, single date if europen, coupon dates if bermudan
    std::vector<QuantLib::Date> affineDates;
    const std::vector<boost::shared_ptr<QuantLib::CashFlow> >& leg = swap->fixedLeg();
    if(european){
        boost::shared_ptr<QuantLib::Coupon> coupon = boost::dynamic_pointer_cast<QuantLib::Coupon>(leg[0]);
        affineDates.push_back(coupon->accrualStartDate());
    } else{
        for (i=0; i<leg.size(); i++) {
            boost::shared_ptr<QuantLib::Coupon> coupon = boost::dynamic_pointer_cast<QuantLib::Coupon>(leg[i]);
            affineDates.push_back(coupon->accrualStartDate());
        }

    }
    
    boost::shared_ptr<QuantLib::Exercise> affineExercise(new QuantLib::BermudanExercise(affineDates));
    
    // Price based on method selected.
    if (method.compare("G2Analytic") == 0) {
        boost::shared_ptr<QuantLib::G2> modelG2(new QuantLib::G2(rhTermStructure));
        Rprintf((char*)"G2/Jamshidian (analytic) calibration\n");
        for(i = 0; i < swaptions.size(); i++)
            swaptions[i]->setPricingEngine(boost::shared_ptr<QuantLib::PricingEngine>(new QuantLib::G2SwaptionEngine(modelG2, 6.0, 16)));
        calibrateModel2(modelG2, swaptions, 0.05, swaptionMat, swapLengths, swaptionVols); 
        boost::shared_ptr<QuantLib::PricingEngine> engine(new QuantLib::TreeSwaptionEngine(modelG2, 50));
        QuantLib::Swaption affineSwaption(mySwap, affineExercise); 
        affineSwaption.setPricingEngine(engine);
        return Rcpp::List::create(Rcpp::Named("a")         = modelG2->params()[0],
                                  Rcpp::Named("sigma")     = modelG2->params()[1],
                                  Rcpp::Named("b")         = modelG2->params()[2],
                                  Rcpp::Named("eta")       = modelG2->params()[3],
                                  Rcpp::Named("rho")       = modelG2->params()[4],
                                  Rcpp::Named("NPV")       = affineSwaption.NPV(),
                                  Rcpp::Named("ATMStrike") = fixedATMRate);
        //Rcpp::Named("params")    = params);
        
    } else if (method.compare("HWAnalytic") == 0) {
        boost::shared_ptr<QuantLib::HullWhite> modelHW(new QuantLib::HullWhite(rhTermStructure));
        Rprintf((char*)"Hull-White (analytic) calibration\n");
        for (i=0; i<swaptions.size(); i++)
            swaptions[i]->setPricingEngine(boost::shared_ptr<QuantLib::PricingEngine>(new QuantLib::JamshidianSwaptionEngine(modelHW)));
        calibrateModel2(modelHW, swaptions, 0.05, swaptionMat, swapLengths, swaptionVols);
        boost::shared_ptr<QuantLib::PricingEngine> engine(new QuantLib::TreeSwaptionEngine(modelHW, 50));
        QuantLib::Swaption affineSwaption(mySwap, affineExercise);
        affineSwaption.setPricingEngine(engine);
        return Rcpp::List::create(Rcpp::Named("a") = modelHW->params()[0],
                                  Rcpp::Named("sigma") = modelHW->params()[1],
                                  Rcpp::Named("NPV") = affineSwaption.NPV(),
                                  Rcpp::Named("ATMStrike") = fixedATMRate);
        //Rcpp::Named("params") = params);
        
    } else if (method.compare("HWTree") == 0) {
        boost::shared_ptr<QuantLib::HullWhite> modelHW2(new QuantLib::HullWhite(rhTermStructure));
        Rprintf((char*)"Hull-White (tree) calibration\n");
        for (i=0; i<swaptions.size(); i++)
            swaptions[i]->setPricingEngine(boost::shared_ptr<QuantLib::PricingEngine>(new QuantLib::TreeSwaptionEngine(modelHW2,grid)));

        calibrateModel2(modelHW2, swaptions, 0.05, swaptionMat, swapLengths, swaptionVols);
        boost::shared_ptr<QuantLib::PricingEngine> engine(new QuantLib::TreeSwaptionEngine(modelHW2, 50));
        QuantLib::Swaption affineSwaption(mySwap, affineExercise);
        affineSwaption.setPricingEngine(engine);
        return Rcpp::List::create(Rcpp::Named("a") = modelHW2->params()[0],
                                  Rcpp::Named("sigma") = modelHW2->params()[1],
                                  Rcpp::Named("NPV") = affineSwaption.NPV(),
                                  Rcpp::Named("ATMStrike") = fixedATMRate);
        //Rcpp::Named("params") = params);
        
            
    } else if (method.compare("BKTree") == 0) {
        boost::shared_ptr<QuantLib::BlackKarasinski> modelBK(new QuantLib::BlackKarasinski(rhTermStructure));
        Rprintf((char*)"Black-Karasinski (tree) calibration\n");
        for (i=0; i<swaptions.size(); i++)
            swaptions[i]->setPricingEngine(boost::shared_ptr<QuantLib::PricingEngine>(new QuantLib::TreeSwaptionEngine(modelBK,grid)));
        calibrateModel2(modelBK, swaptions, 0.05, swaptionMat, swapLengths, swaptionVols);
            
        boost::shared_ptr<QuantLib::PricingEngine> engine(new QuantLib::TreeSwaptionEngine(modelBK, 50));
        QuantLib::Swaption affineSwaption(mySwap, affineExercise);
        affineSwaption.setPricingEngine(engine);
        return Rcpp::List::create(Rcpp::Named("a") = modelBK->params()[0],
                                  Rcpp::Named("sigma") = modelBK->params()[1],
                                  Rcpp::Named("price") = affineSwaption.NPV(),
                                  Rcpp::Named("ATMStrike") = fixedATMRate);
        //Rcpp::Named("params") = params);
            
    } else {
        throw std::range_error("Unknown method in AffineSwaption\n");
    }
    
}
int ChartItemModel::rowCount( const QModelIndex &/*parent */) const
{
    return startDate().daysTo( endDate() ) + 1;
}
double ChartItemModel::bcwsEffort( int day ) const
{
    return m_bcws.hoursTo( startDate().addDays( day ) );
}
Example #29
0
QDate YearlyRecurrence::prevOccurrence(const QDate &date, bool include_equals) const {
	const KCalendarSystem *calSys = KGlobal::locale()->calendar();
	if(!include_equals) {
		if(date > endDate()) return lastOccurrence();
	}
	QDate prevdate = date;
	if(!include_equals) prevdate = calSys->addDays(prevdate, -1);
	if(prevdate < startDate()) return QDate();
	if(prevdate == startDate()) return startDate();
	if(i_frequency != 1) {
		int i = (calSys->year(prevdate) - calSys->year(startDate())) % i_frequency;
		if(i != 0) {
			prevdate = calSys->addYears(prevdate, - i);
		}
	}
	if(calSys->year(prevdate) == calSys->year(startDate())) return startDate();
	if(i_dayofyear > 0) {
		if(calSys->dayOfYear(prevdate) < i_dayofyear) {
			prevdate = calSys->addYears(prevdate, -i_frequency);
			if(calSys->year(prevdate) == calSys->year(startDate())) return startDate();
		}
		if(i_dayofyear > calSys->daysInYear(prevdate)) {
			do {
				prevdate = calSys->addYears(prevdate, -i_frequency);
				if(calSys->year(prevdate) <= calSys->year(startDate())) return startDate();
			} while(i_dayofyear > calSys->daysInYear(prevdate));
		}
		prevdate = calSys->addDays(prevdate, i_dayofyear - calSys->dayOfYear(prevdate));
	} else {
		int day = i_dayofmonth;
		if(i_dayofweek > 0) day = get_day_in_month(calSys->year(prevdate), i_month, i_week, i_dayofweek);
		if(day <= 0 || calSys->month(prevdate) < i_month || (calSys->month(prevdate) == i_month && calSys->day(prevdate) < day)) {
			do {
				prevdate = calSys->addYears(prevdate, -i_frequency);
				if(i_dayofweek > 0) day = get_day_in_month(calSys->year(prevdate), i_month, i_week, i_dayofweek);
				if(calSys->year(prevdate) == calSys->year(startDate())) return startDate();
			} while(day <= 0);
		}
		if(i_dayofweek <= 0) {
			calSys->setYMD(prevdate, calSys->year(prevdate), i_month, 1);
			if(day > calSys->daysInMonth(prevdate)) {
				do {
					prevdate = calSys->addYears(prevdate, -i_frequency);
					calSys->setYMD(prevdate, calSys->year(prevdate), i_month, 1);
					if(calSys->year(prevdate) <= calSys->year(startDate())) return startDate();
				} while(day > calSys->daysInMonth(prevdate));
			}
		}
		calSys->setYMD(prevdate, calSys->year(prevdate), i_month, day);
	}
	if(prevdate < startDate()) return QDate();
	if(hasException(prevdate)) return prevOccurrence(prevdate);
	return prevdate;
}
double ChartItemModel::bcwsCost( int day ) const
{
    return m_bcws.costTo( startDate().addDays( day ) );
}