00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "kptappointment.h"
00021
00022 #include "kptproject.h"
00023 #include "kpttask.h"
00024 #include "kptdatetime.h"
00025 #include "kptcalendar.h"
00026 #include "kpteffortcostmap.h"
00027 #include "kptschedule.h"
00028
00029 #include <kdebug.h>
00030
00031 namespace KPlato
00032 {
00033
00034 class Resource;
00035
00036 AppointmentInterval::AppointmentInterval() {
00037 m_load = 100.0;
00038 }
00039 AppointmentInterval::AppointmentInterval(const AppointmentInterval &interval) {
00040
00041 m_start = interval.startTime();
00042 m_end = interval.endTime();
00043 m_load = interval.load();
00044 }
00045 AppointmentInterval::AppointmentInterval(const DateTime &start, const DateTime end, double load) {
00046
00047 m_start = start;
00048 m_end = end;
00049 m_load = load;
00050 }
00051 AppointmentInterval::~AppointmentInterval() {
00052
00053 }
00054
00055 Duration AppointmentInterval::effort(const DateTime &start, const DateTime end) const {
00056 if (start >= m_end || end <= m_start) {
00057 return Duration::zeroDuration;
00058 }
00059 DateTime s = (start > m_start ? start : m_start);
00060 DateTime e = (end < m_end ? end : m_end);
00061 return (e - s) * m_load / 100;
00062 }
00063
00064 Duration AppointmentInterval::effort(const DateTime &time, bool upto) const {
00065 if (upto) {
00066 if (time <= m_start) {
00067 return Duration::zeroDuration;
00068 }
00069 DateTime e = (time < m_end ? time : m_end);
00070 return (e - m_start) * m_load / 100;
00071 }
00072
00073 if (time >= m_end) {
00074 return Duration::zeroDuration;
00075 }
00076 DateTime s = (time > m_start ? time : m_start);
00077 return (m_end - s) * m_load / 100;
00078 }
00079
00080 bool AppointmentInterval::loadXML(QDomElement &element) {
00081
00082 bool ok;
00083 QString s = element.attribute("start");
00084 if (s != "")
00085 m_start = DateTime::fromString(s);
00086 s = element.attribute("end");
00087 if (s != "")
00088 m_end = DateTime::fromString(s);
00089 m_load = element.attribute("load", "100").toDouble(&ok);
00090 if (!ok) m_load = 100;
00091 return m_start.isValid() && m_end.isValid();
00092 }
00093
00094 void AppointmentInterval::saveXML(QDomElement &element) const {
00095 QDomElement me = element.ownerDocument().createElement("interval");
00096 element.appendChild(me);
00097
00098 me.setAttribute("start", m_start.toString(Qt::ISODate));
00099 me.setAttribute("end", m_end.toString(Qt::ISODate));
00100 me.setAttribute("load", m_load);
00101 }
00102
00103 bool AppointmentInterval::isValid() const {
00104 return m_start.isValid() && m_end.isValid();
00105 }
00106
00107 AppointmentInterval AppointmentInterval::firstInterval(const AppointmentInterval &interval, const DateTime &from) const {
00108
00109 DateTime f = from;
00110 DateTime s1 = m_start;
00111 DateTime e1 = m_end;
00112 DateTime s2 = interval.startTime();
00113 DateTime e2 = interval.endTime();
00114 AppointmentInterval a;
00115 if (f.isValid() && f >= e1 && f >= e2) {
00116 return a;
00117 }
00118 if (f.isValid()) {
00119 if (s1 < f && f < e1) {
00120 s1 = f;
00121 }
00122 if (s2 < f && f < e2) {
00123 s2 = f;
00124 }
00125 } else {
00126 f = s1 < s2 ? s1 : s2;
00127 }
00128 if (s1 < s2) {
00129 a.setStartTime(s1);
00130 if (e1 <= s2) {
00131 a.setEndTime(e1);
00132 } else {
00133 a.setEndTime(s2);
00134 }
00135 a.setLoad(m_load);
00136 } else if (s1 > s2) {
00137 a.setStartTime(s2);
00138 if (e2 <= s1) {
00139 a.setEndTime(e2);
00140 } else {
00141 a.setEndTime(s1);
00142 }
00143 a.setLoad(interval.load());
00144 } else {
00145 a.setStartTime(s1);
00146 if (e1 <= e2)
00147 a.setEndTime(e1);
00148 else
00149 a.setEndTime(e2);
00150 a.setLoad(m_load + interval.load());
00151 }
00152
00153 return a;
00154 }
00155
00157
00158 Appointment::UsedEffortItem::UsedEffortItem(QDate date, Duration effort, bool overtime) {
00159 m_date = date;
00160 m_effort = effort;
00161 m_overtime = overtime;
00162 }
00163 QDate Appointment::UsedEffortItem::date() {
00164 return m_date;
00165 }
00166 Duration Appointment::UsedEffortItem::effort() {
00167 return m_effort;
00168 }
00169 bool Appointment::UsedEffortItem::isOvertime() {
00170 return m_overtime;
00171 }
00172
00173 Appointment::UsedEffort::UsedEffort() {
00174 }
00175
00176 Appointment::UsedEffort::~UsedEffort() {
00177 while (!isEmpty())
00178 delete takeFirst();
00179 }
00180
00181 void Appointment::UsedEffort::inSort(QDate date, Duration effort, bool overtime) {
00182 UsedEffortItem *item = new UsedEffortItem(date, effort, overtime);
00183 this->append(item);
00184
00185 }
00186
00187 Duration Appointment::UsedEffort::usedEffort(bool includeOvertime) const {
00188 Duration eff;
00189 QListIterator<UsedEffortItem*> it(*this);
00190 while (it.hasNext()) {
00191 UsedEffortItem *i = it.next();
00192 if (includeOvertime || !i->isOvertime()) {
00193 eff += i->effort();
00194 }
00195 }
00196 return eff;
00197 }
00198
00199 Duration Appointment::UsedEffort::usedEffort(const QDate &date, bool includeOvertime) const {
00200 Duration eff;
00201 QListIterator<UsedEffortItem*> it(*this);
00202 while (it.hasNext()) {
00203 UsedEffortItem *i = it.next();
00204 if ((includeOvertime || !i->isOvertime()) &&
00205 i->date() == date) {
00206 eff += i->effort();
00207 }
00208 }
00209 return eff;
00210 }
00211
00212 Duration Appointment::UsedEffort::usedEffortTo(const QDate &date, bool includeOvertime) const {
00213 Duration eff;
00214 QListIterator<UsedEffortItem*> it(*this);
00215 while (it.hasNext()) {
00216 UsedEffortItem *i = it.next();
00217 if ((includeOvertime || !i->isOvertime()) &&
00218 i->date() <= date) {
00219 eff += i->effort();
00220 }
00221 }
00222 return eff;
00223 }
00224
00225 Duration Appointment::UsedEffort::usedOvertime() const {
00226 if (isEmpty()) {
00227 return 0;
00228 }
00229 return usedOvertime(first()->date());
00230 }
00231
00232 Duration Appointment::UsedEffort::usedOvertime(const QDate &date) const {
00233 Duration eff;
00234 QListIterator<UsedEffortItem*> it(*this);
00235 while (it.hasNext()) {
00236 UsedEffortItem *i = it.next();
00237 if (i->isOvertime() && i->date() == date) {
00238 eff += i->effort();
00239 }
00240 }
00241 return eff;
00242 }
00243
00244 Duration Appointment::UsedEffort::usedOvertimeTo(const QDate &date) const {
00245 Duration eff;
00246 QListIterator<UsedEffortItem*> it(*this);
00247 while (it.hasNext()) {
00248 UsedEffortItem *i = it.next();
00249 if (i->isOvertime() && i->date() <= date) {
00250 eff += i->effort();
00251 }
00252 }
00253 return eff;
00254 }
00255
00256 bool Appointment::UsedEffort::load(QDomElement &element) {
00257 QString s;
00258 QDomNodeList list = element.childNodes();
00259 for (unsigned int i=0; i<list.count(); ++i) {
00260 if (list.item(i).isElement()) {
00261 QDomElement e = list.item(i).toElement();
00262 if (e.tagName() == "actual-effort") {
00263 QDate date;
00264 s = e.attribute("date");
00265 if (s != "")
00266 date = QDate::fromString(s, Qt::ISODate);
00267 Duration eff = Duration::fromString(e.attribute("effort"));
00268 bool ot = e.attribute("overtime", "0").toInt();
00269 if (date.isValid()) {
00270 inSort(date, eff, ot);
00271 } else {
00272 kError()<<k_funcinfo<<"Load failed, illegal date: "<<e.attribute("date")<<endl;
00273 }
00274 }
00275 }
00276 }
00277 return true;
00278 }
00279
00280 void Appointment::UsedEffort::save(QDomElement &element) const {
00281 if (isEmpty()) return;
00282 QListIterator<UsedEffortItem*> it = *this;
00283 while (it.hasNext()) {
00284 UsedEffortItem *i = it.next();
00285 QDomElement me = element.ownerDocument().createElement("actual-effort");
00286 element.appendChild(me);
00287 me.setAttribute("date",i->date().toString(Qt::ISODate));
00288 me.setAttribute("effort",i->effort().toString());
00289 me.setAttribute("overtime",i->isOvertime());
00290 }
00291 }
00292
00294 Appointment::Appointment()
00295 : m_extraRepeats(), m_skipRepeats() {
00296
00297 m_resource=0;
00298 m_node=0;
00299 m_repeatInterval=Duration();
00300 m_repeatCount=0;
00301 }
00302
00303 Appointment::Appointment(Schedule *resource, Schedule *node, DateTime start, DateTime end, double load)
00304 : m_extraRepeats(),
00305 m_skipRepeats() {
00306
00307 m_node = node;
00308 m_resource = resource;
00309 m_repeatInterval = Duration();
00310 m_repeatCount = 0;
00311
00312 addInterval(start, end, load);
00313 }
00314
00315 Appointment::Appointment(Schedule *resource, Schedule *node, DateTime start, Duration duration, double load)
00316 : m_extraRepeats(),
00317 m_skipRepeats() {
00318
00319 m_node = node;
00320 m_resource = resource;
00321 m_repeatInterval = Duration();
00322 m_repeatCount = 0;
00323
00324 addInterval(start, duration, load);
00325
00326 }
00327
00328 Appointment::~Appointment() {
00329 kDebug()<<k_funcinfo<<"("<<this<<")"<<endl;
00330 detach();
00331 while (m_intervals.isEmpty())
00332 delete m_intervals.takeFirst();
00333 }
00334
00335 void Appointment::addInterval(AppointmentInterval *a) {
00336
00337 m_intervals.inSort(a);
00338 }
00339 void Appointment::addInterval(const DateTime &start, const DateTime &end, double load) {
00340 addInterval(new AppointmentInterval(start, end, load));
00341 }
00342 void Appointment::addInterval(const DateTime &start, const Duration &duration, double load) {
00343 DateTime e = start+duration;
00344 addInterval(start, e, load);
00345 }
00346
00347 double Appointment::maxLoad() const {
00348 double v = 0.0;
00349 QListIterator<AppointmentInterval*> it = m_intervals;
00350 while (it.hasNext()) {
00351 AppointmentInterval *i = it.next();
00352 if (v < i->load())
00353 v = i->load();
00354 }
00355 return v;
00356 }
00357
00358 DateTime Appointment::startTime() const {
00359 DateTime t;
00360 QListIterator<AppointmentInterval*> it = m_intervals;
00361 while (it.hasNext()) {
00362 AppointmentInterval *i = it.next();
00363 if (!t.isValid() || t > i->startTime())
00364 t = i->startTime();
00365 }
00366 return t;
00367 }
00368
00369 DateTime Appointment::endTime() const {
00370 DateTime t;
00371 QListIterator<AppointmentInterval*> it = m_intervals;
00372 while (it.hasNext()) {
00373 AppointmentInterval *i = it.next();
00374 if (!t.isValid() || t < i->endTime())
00375 t = i->endTime();
00376 }
00377 return t;
00378 }
00379
00380 void Appointment::deleteAppointmentFromRepeatList(DateTime) {
00381 }
00382
00383 void Appointment::addAppointmentToRepeatList(DateTime) {
00384 }
00385
00386 bool Appointment::isBusy(const DateTime &, const DateTime &) {
00387 return false;
00388 }
00389
00390 bool Appointment::loadXML(QDomElement &element, Project &project, Schedule &sch) {
00391
00392 Node *node = project.findNode(element.attribute("task-id"));
00393 if (node == 0) {
00394 kError()<<k_funcinfo<<"The referenced task does not exists: "<<element.attribute("task-id")<<endl;
00395 return false;
00396 }
00397 Resource *res = project.resource(element.attribute("resource-id"));
00398 if (res == 0) {
00399 kError()<<k_funcinfo<<"The referenced resource does not exists: resource id="<<element.attribute("resource-id")<<endl;
00400 return false;
00401 }
00402 if (!res->addAppointment(this, sch)) {
00403 kError()<<k_funcinfo<<"Failed to add appointment to resource: "<<res->name()<<endl;
00404 return false;
00405 }
00406 if (!node->addAppointment(this, sch)) {
00407 kError()<<k_funcinfo<<"Failed to add appointment to node: "<<node->name()<<endl;
00408 m_resource->takeAppointment(this);
00409 return false;
00410 }
00411
00412 QDomNodeList list = element.childNodes();
00413 for (unsigned int i=0; i<list.count(); ++i) {
00414 if (list.item(i).isElement()) {
00415 QDomElement e = list.item(i).toElement();
00416 if (e.tagName() == "interval") {
00417 AppointmentInterval *a = new AppointmentInterval();
00418 if (a->loadXML(e)) {
00419 addInterval(a);
00420 } else {
00421 kError()<<k_funcinfo<<"Could not load interval"<<endl;
00422 delete a;
00423 }
00424 }
00425 }
00426 }
00427 if (m_intervals.isEmpty()) {
00428 return false;
00429 }
00430 m_actualEffort.load(element);
00431 return true;
00432 }
00433
00434 void Appointment::saveXML(QDomElement &element) const {
00435 if (m_intervals.isEmpty()) {
00436 kError()<<k_funcinfo<<"Incomplete appointment data: No intervals"<<endl;
00437 }
00438 if (m_resource == 0 || m_resource->resource() == 0) {
00439 kError()<<k_funcinfo<<"Incomplete appointment data: No resource"<<endl;
00440 return;
00441 }
00442 if (m_node == 0 || m_node->node() == 0) {
00443 kError()<<k_funcinfo<<"Incomplete appointment data: No node"<<endl;
00444 return;
00445 }
00446
00447 QDomElement me = element.ownerDocument().createElement("appointment");
00448 element.appendChild(me);
00449
00450 me.setAttribute("resource-id", m_resource->resource()->id());
00451 me.setAttribute("task-id", m_node->node()->id());
00452 QListIterator<AppointmentInterval*> it = m_intervals;
00453 while (it.hasNext()) {
00454 AppointmentInterval *i = it.next();
00455 i->saveXML(me);
00456 }
00457 m_actualEffort.save(me);
00458 }
00459
00460
00461 Duration Appointment::plannedEffort() const {
00462 Duration d;
00463 QListIterator<AppointmentInterval*> it = m_intervals;
00464 while (it.hasNext()) {
00465 AppointmentInterval *i = it.next();
00466 d += i->effort();
00467 }
00468 return d;
00469 }
00470
00471
00472 Duration Appointment::plannedEffort(const QDate &date) const {
00473 Duration d;
00474 DateTime s(date);
00475 DateTime e(date.addDays(1));
00476 QListIterator<AppointmentInterval*> it = m_intervals;
00477 while (it.hasNext()) {
00478 AppointmentInterval *i = it.next();
00479 d += i->effort(s, e);
00480 }
00481 return d;
00482 }
00483
00484
00485 Duration Appointment::plannedEffortTo(const QDate& date) const {
00486 Duration d;
00487 DateTime e(date.addDays(1));
00488 QListIterator<AppointmentInterval*> it = m_intervals;
00489 while (it.hasNext()) {
00490 AppointmentInterval *i = it.next();
00491 d += i->effort(e, true);
00492 }
00493 return d;
00494 }
00495
00496
00497
00498 EffortCostMap Appointment::plannedPrDay(const QDate& start, const QDate& end) const {
00499
00500 EffortCostMap ec;
00501 Duration eff;
00502 DateTime dt(start);
00503 DateTime ndt(dt.addDays(1));
00504 double rate = m_resource->normalRatePrHour();
00505 AppointmentIntervalListIterator it = m_intervals;
00506 while (it.hasNext()) {
00507 AppointmentInterval *i = it.next();
00508 DateTime st = i->startTime();
00509 DateTime e = i->endTime();
00510 if (end < st.date())
00511 break;
00512 if (dt.date() < st.date()) {
00513 dt.setDate(st.date());
00514 }
00515 ndt = dt.addDays(1);
00516
00517 while (dt.date() <= e.date()) {
00518 eff = i->effort(dt, ndt);
00519 ec.add(dt.date(), eff, eff.toDouble(Duration::Unit_h) * rate);
00520 dt = ndt;
00521 ndt = ndt.addDays(1);
00522 }
00523 }
00524 return ec;
00525 }
00526
00527
00528
00529 Duration Appointment::actualEffort() const {
00530 return m_actualEffort.usedEffort();
00531 }
00532
00533
00534 Duration Appointment::actualEffort(const QDate &date) const {
00535 return m_actualEffort.usedEffort(date);
00536 }
00537
00538
00539 Duration Appointment::actualEffortTo(const QDate &date) const {
00540 return m_actualEffort.usedEffortTo(date);
00541 }
00542
00543 double Appointment::plannedCost() {
00544 if (m_resource && m_resource->resource()) {
00545 return plannedEffort().toDouble(Duration::Unit_h) * m_resource->resource()->normalRate();
00546 }
00547 return 0.0;
00548 }
00549
00550
00551 double Appointment::plannedCost(const QDate &date) {
00552 if (m_resource && m_resource->resource()) {
00553 return plannedEffort(date).toDouble(Duration::Unit_h) * m_resource->resource()->normalRate();
00554 }
00555 return 0.0;
00556 }
00557
00558
00559 double Appointment::plannedCostTo(const QDate &date) {
00560 if (m_resource && m_resource->resource()) {
00561 return plannedEffortTo(date).toDouble(Duration::Unit_h) * m_resource->resource()->normalRate();
00562 }
00563 return 0.0;
00564 }
00565
00566
00567 double Appointment::actualCost() {
00568
00569 if (m_resource && m_resource->resource()) {
00570 return (m_actualEffort.usedEffort(false ).toDouble(Duration::Unit_h)*m_resource->resource()->normalRate()) + (m_actualEffort.usedOvertime().toDouble(Duration::Unit_h)*m_resource->resource()->overtimeRate());
00571 }
00572 return 0.0;
00573 }
00574
00575
00576 double Appointment::actualCost(const QDate &date) {
00577 if (m_resource && m_resource->resource()) {
00578 return (m_actualEffort.usedEffort(date, false ).toDouble(Duration::Unit_h)*m_resource->resource()->normalRate()) + (m_actualEffort.usedOvertime(date).toDouble(Duration::Unit_h)*m_resource->resource()->overtimeRate());
00579 }
00580 return 0.0;
00581 }
00582
00583
00584 double Appointment::actualCostTo(const QDate &date) {
00585 if (m_resource && m_resource->resource()) {
00586 return (m_actualEffort.usedEffortTo(date, false ).toDouble(Duration::Unit_h)*m_resource->resource()->normalRate()) + (m_actualEffort.usedOvertimeTo(date).toDouble(Duration::Unit_h)*m_resource->resource()->overtimeRate());
00587 }
00588 return 0.0;
00589 }
00590
00591 void Appointment::addActualEffort(QDate date, Duration effort, bool overtime) {
00592 m_actualEffort.inSort(date, effort, overtime);
00593 }
00594
00595 bool Appointment::attach() {
00596
00597 if (m_resource && m_node) {
00598 m_resource->add(this);
00599 m_node->add(this);
00600 return true;
00601 }
00602 kWarning()<<k_funcinfo<<"Failed: "<<(m_resource ? "" : "resource=0 ")
00603 <<(m_node ? "" : "node=0")<<endl;
00604 return false;
00605 }
00606
00607 void Appointment::detach() {
00608 kDebug()<<k_funcinfo<<"("<<this<<")"<<endl;
00609 if (m_resource) {
00610 m_resource->takeAppointment(this);
00611 }
00612 if (m_node) {
00613 m_node->takeAppointment(this);
00614 }
00615 }
00616
00617
00618 Duration Appointment::effort(const DateTime &start, const DateTime &end) const {
00619 Duration d;
00620 QListIterator<AppointmentInterval*> it = m_intervals;
00621 while (it.hasNext()) {
00622 AppointmentInterval *i = it.next();
00623 d += i->effort(start, end);
00624 }
00625 return d;
00626 }
00627
00628 Duration Appointment::effort(const DateTime &start, const Duration &duration) const {
00629 Duration d;
00630 QListIterator<AppointmentInterval*> it = m_intervals;
00631 while (it.hasNext()) {
00632 AppointmentInterval *i = it.next();
00633 d += i->effort(start, start+duration);
00634 }
00635 return d;
00636 }
00637
00638 Duration Appointment::effortFrom(const DateTime &time) const {
00639 Duration d;
00640 QListIterator<AppointmentInterval*> it = m_intervals;
00641 while (it.hasNext()) {
00642 AppointmentInterval *i = it.next();
00643 d += i->effort(time, false);
00644 }
00645 return d;
00646 }
00647
00648 Appointment &Appointment::operator=(const Appointment &app) {
00649 m_resource = app.resource();
00650 m_node = app.node();
00651 m_repeatInterval = app.repeatInterval();
00652 m_repeatCount = app.repeatCount();
00653
00654 m_intervals.clear();
00655 QListIterator<AppointmentInterval*> it = m_intervals;
00656 while (it.hasNext()) {
00657 AppointmentInterval *i = it.next();
00658 addInterval(new AppointmentInterval(*i));
00659 }
00660 return *this;
00661 }
00662
00663 Appointment &Appointment::operator+=(const Appointment &app) {
00664 *this = *this + app;
00665 return *this;
00666 }
00667
00668 Appointment Appointment::operator+(const Appointment &app) {
00669 Appointment a;
00670 AppointmentIntervalList lst1 = m_intervals;
00671 AppointmentInterval *i1;
00672 AppointmentIntervalList lst2 = app.intervals();
00673 AppointmentInterval *i2;
00674 int index1 = 0, index2 = 0;
00675 DateTime from;
00676 while (index1 < lst1.size() || index2 < lst2.size()) {
00677 if (index1 >= lst1.size()) {
00678 i2 = lst2[index2];
00679 if (!from.isValid() || from < i2->startTime())
00680 from = i2->startTime();
00681 a.addInterval(from, i2->endTime(), i2->load());
00682
00683 from = i2->endTime();
00684 ++index2;
00685 continue;
00686 }
00687 if (index2 >= lst2.size()) {
00688 i1 = lst1[index1];
00689 if (!from.isValid() || from < i1->startTime())
00690 from = i1->startTime();
00691 a.addInterval(from, i1->endTime(), i1->load());
00692
00693 from = i1->endTime();
00694 ++index1;
00695 continue;
00696 }
00697 i1 = lst1[index1];
00698 i2 = lst2[index2];
00699 AppointmentInterval i = i1->firstInterval(*i2, from);
00700 if (!i.isValid()) {
00701 break;
00702 }
00703 a.addInterval(i);
00704 from = i.endTime();
00705
00706 if (a.endTime() >= i1->endTime()) {
00707 ++index1;
00708 }
00709 if (a.endTime() >= i2->endTime()) {
00710 ++index2;
00711 }
00712 }
00713 return a;
00714 }
00715
00716 #ifndef NDEBUG
00717 void Appointment::printDebug(QString indent)
00718 {
00719 bool err = false;
00720 if (m_node == 0) {
00721 kDebug()<<indent<<" No node schedule"<<endl;
00722 err = true;
00723 } else if (m_node->node() == 0) {
00724 kDebug()<<indent<<" No node"<<endl;
00725 err = true;
00726 }
00727 if (m_resource == 0) {
00728 kDebug()<<indent<<" No resource schedule"<<endl;
00729 err = true;
00730 } else if (m_resource->resource() == 0) {
00731 kDebug()<<indent<<" No resource"<<endl;
00732 err = true;
00733 }
00734 if (err)
00735 return;
00736 kDebug()<<indent<<" + Appointment to schedule: "<<m_node->name()<<" ("<<m_node->type()<<")"<<" resource: "<<m_resource->resource()->name()<<endl;
00737 indent += " ! ";
00738 QListIterator<AppointmentInterval*> it = m_intervals;
00739 while (it.hasNext()) {
00740 AppointmentInterval *i = it.next();
00741 kDebug()<<indent<<i->startTime()<<" - "<<i->endTime()<<" load="<<i->load()<<endl;
00742 }
00743 }
00744 #endif
00745
00746 }