00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifdef HAVE_CONFIG_H
00019 #include <config.h>
00020 #endif
00021
00022 using namespace std;
00023
00024 #include "messenger.h"
00025 #include "project.h"
00026 #include "reporter.h"
00027
00028 char *longMonthNames[] =
00029 {
00030 "January", "February", "March", "April", "May", "June",
00031 "July", "August", "September", "October", "November", "December"
00032 };
00033
00034 FILE *Reporter::OpenOutputFile(char *filename)
00035 {
00036 FILE *f;
00037
00038 if ( filename == NULL )
00039 return NULL;
00040
00041 if ( strcmp(filename, "-") == 0 )
00042 return stdout;
00043
00044 f = fopen(filename, "w");
00045 if ( f == NULL )
00046 Error("Cannot open file [%s]", filename);
00047
00048 return f;
00049 }
00050
00051 void Project::LoadDays()
00052 {
00053 int i;
00054 int dayNo = 1;
00055 time_t t = startTime;
00056 struct tm *tm;
00057 char buf[BUFLEN];
00058 const int fullDay = 24*60*60;
00059
00060 if ( days[0].t != 0 )
00061 return;
00062
00063 for ( i = 0 ; i < MAX_TIME ; ++i )
00064 {
00065 tm = localtime( &t );
00066 while ( tm->tm_wday == 0 || tm->tm_wday == 6 )
00067 {
00068 t += fullDay;
00069 ++ dayNo;
00070 tm = localtime( &t );
00071 }
00072 days[i].t = t;
00073 days[i].num = dayNo;
00074
00075 if ( date_format == NULL || strcasecmp(date_format, "calendar") == 0 )
00076 sprintf(buf, "%04d.%s.%02d",
00077 1900+tm->tm_year, monthNames[tm->tm_mon], tm->tm_mday);
00078 else if ( strcasecmp(date_format, "count") == 0 )
00079 sprintf(buf, "%03d", dayNo);
00080 else if ( strcasecmp(date_format, "raw") == 0 )
00081 sprintf(buf, "%03d", i);
00082 else if ( strcasecmp(date_format, "iso") == 0 )
00083 sprintf(buf, "%04d-%02d-%02d",
00084 1900+tm->tm_year, tm->tm_mon+1, tm->tm_mday);
00085 else
00086 Error("Invalid date format: [%s]", date_format);
00087
00088 days[i].s = strdup(buf);
00089 t += fullDay;
00090 ++dayNo;
00091 }
00092 }
00093
00094
00095
00096
00097
00098 int Project::FindDay(char *name)
00099 {
00100 int i;
00101
00102 LoadDays();
00103 for ( i = 0 ; i < MAX_TIME ; ++i )
00104 {
00105 if ( strcasecmp(days[i].s, name) == 0 )
00106 {
00107 return i;
00108 }
00109 }
00110
00111 return -1;
00112 }
00113
00114 int Reporter::Month(time_t t)
00115 {
00116 struct tm *tm;
00117
00118 tm = localtime( &t );
00119 return tm->tm_mon;
00120 }
00121
00122 int Reporter::Year(time_t t)
00123 {
00124 struct tm *tm;
00125
00126 tm = localtime( &t );
00127 return tm->tm_year + 1900;
00128 }
00129
00130 int Reporter::Mday(time_t t)
00131 {
00132 struct tm *tm;
00133
00134 tm = localtime( &t );
00135 return tm->tm_mday;
00136 }
00137
00138 int Reporter::Wday(time_t t)
00139 {
00140 struct tm *tm;
00141
00142 tm = localtime( &t );
00143 return tm->tm_wday;
00144 }
00145
00146
00147 int UserTaskWorkedDays(TASK *t, RESOURCE *r)
00148 {
00149 int tot = 0;
00150 for ( TaskTimeBlockIterator tb = t->begin_when(); tb != t->end_when(); tb++ )
00151 {
00152 if ( tb->type() == TimeBlock::WORK_DONE )
00153 {
00154 tot += tb->finish() - tb->start() + 1;
00155 }
00156 }
00157
00158 if ( tot == 0 && t->percent_complete() > 0 )
00159 tot = (int)(t->percent_complete() / 100.0 * (double)t->duration());
00160
00161 return tot;
00162 }
00163
00164 void Reporter::TextReport( Project *project, char *filename)
00165 {
00166 MILESTONE *m;
00167 int j;
00168 int ndays;
00169
00170 project->SortTasks( tg_sortbyresource );
00171
00172 FILE * f = OpenOutputFile(filename);
00173
00174 fprintf(f, "Time Frame:\n");
00175 fprintf(f, "==========:\n");
00176 fprintf(f, " Start Date: %s\n", project->sStartDay() );
00177 fprintf(f, "Finish Date: %s\n", project->sFinishDay() );
00178 fprintf(f,"\n\n\n");
00179
00180 fprintf(f,"Task list:\n");
00181 fprintf(f,"=========:\n");
00182 for ( int i = 0; i < project->nTasks(); ++i )
00183 {
00184 TASK * t = project->sortedTask(i);
00185 if ( t->isVacation() )
00186 continue;
00187 fprintf(f,"%s %s %-20s ",
00188 project->sDays(t->start()), project->sDays(t->finish()), t->assigned()->name());
00189 if ( task_ids )
00190 fprintf(f,"%s %s\n", t->id(), t->name());
00191 else
00192 fprintf(f,"%s\n", t->name());
00193 if ((t->bstart() != INVALIDDAYNO) && (t->bfinish() != INVALIDDAYNO))
00194 {
00195 fprintf(f,"%s %s Baseline\n",
00196 project->sDays(t->bstart()), project->sDays(t->bfinish()));
00197 }
00198 if ((t->astart() != INVALIDDAYNO) && (t->afinish() != INVALIDDAYNO))
00199
00200 {
00201 fprintf(f,"%s %s Actual\n",
00202 project->sDays(t->astart()), project->sDays(t->afinish()));
00203 }
00204 }
00205 fprintf(f,"\n\n\n");
00206
00207 project->SortMilestones();
00208 fprintf(f, "Milestone List:\n");
00209 fprintf(f, "==============:\n");
00210 for ( int i = 0; i < project->nMilestones(); ++i )
00211 {
00212 m = project->sortedMilestone(i);
00213
00214 fprintf(f, "%s ",
00215 project->sDays(m->day()));
00216 if ( milestone_ids )
00217 fprintf(f, "%s ", m->id());
00218 fprintf(f, "%s\n", m->name());
00219 if ( m->bday() != INVALIDDAYNO )
00220 fprintf(f, "%s Baseline\n", project->sDays(m->bday()));
00221 }
00222 fprintf(f,"\n\n\n");
00223
00224 fprintf(f,"Resources and Task Assignment:\n");
00225 fprintf(f,"=============================:\n");
00226 for ( Project::RPLCI rl = project->beginResourceList();
00227 rl != project->endResourceList() ; rl++ )
00228 {
00229 RESOURCE * r = *rl;
00230 if ( r->is_group )
00231 {
00232 fprintf(f, "Group( ");
00233 for ( Project::RPLCI rl2 = r->contains.begin(); rl2 != r->contains.end(); rl2++ )
00234 fprintf(f,"%s%s ", (*rl2)->name(), rl2 == r->contains.end()?"":",");
00235 fprintf(f, ")\n");
00236 }
00237 else
00238 fprintf(f,"%s\n",r->name());
00239 for ( int i = 0; i < project->nTasks(); ++i )
00240 {
00241 TASK * t = project->sortedTask(i);
00242 if( t->assigned() != r )
00243 continue;
00244 if ( t->isVacation() )
00245 continue;
00246 fprintf(f," %s %s ",
00247 project->sDays(t->start()), project->sDays(t->finish()));
00248 if ( task_ids )
00249 fprintf(f, "%s ", t->id());
00250 fprintf(f, "%s\n", t->name());
00251 }
00252 fprintf(f,"\n");
00253 }
00254 fprintf(f,"\n\n\n");
00255
00256 if ( dependencies )
00257 {
00258 fprintf(f,"Dependencies:\n");
00259 fprintf(f,"============:\n");
00260 for ( int i = 0; i < project->nTasks(); ++i )
00261 {
00262 TASK * t = project->sortedTask(i);
00263 if ( t->begin_depends() == t->end_depends() )
00264 continue;
00265 fprintf(f, "%s %s ", project->sDays(t->start()), project->sDays(t->finish()));
00266 if ( task_ids )
00267 fprintf(f, "%s ", t->id());
00268 fprintf(f, " %s\n", t->name());
00269 for ( TASK::PTRLIST::const_iterator pt = t->begin_depends();
00270 pt != t->end_depends();
00271 pt++ )
00272 {
00273 TASK * tt = *pt;
00274 fprintf(f, " %s %s ",
00275 project->sDays(tt->start()), project->sDays(tt->finish()));
00276 if ( task_ids )
00277 fprintf(f, "%s ", tt->id());
00278 fprintf(f, "%s\n", tt->name());
00279 }
00280 fprintf(f, "\n");
00281 }
00282 }
00283 fprintf(f,"\n\n\n");
00284
00285 if ( vacations )
00286 {
00287 fprintf(f,"Vacations:\n");
00288 fprintf(f,"=========:\n");
00289 for ( Project::RPLCI rl = project->beginResourceList();
00290 rl != project->endResourceList() ; rl++ )
00291 {
00292 RESOURCE * r = *rl;
00293
00294 if ( r->is_group )
00295 {
00296 fprintf(f, "Group( ");
00297 for ( Project::RPLCI rl2 = r->contains.begin(); rl2 != r->contains.end(); rl2++ )
00298 fprintf(f,"%s%s ", (*rl2)->name(), rl2 == r->contains.end() ? "" : "," );
00299 fprintf(f, ")\n");
00300 }
00301 else
00302 fprintf(f,"%s\n",r->name());
00303 for ( int i = 0; i < project->nTasks(); ++i )
00304 {
00305 TASK * t = project->sortedTask(i);
00306 if ( t->assigned() != r )
00307 continue;
00308 if ( !t->isVacation() )
00309 continue;
00310 ndays = 0;
00311 for ( j = t->start(); j <= t->finish(); ++j )
00312 {
00313 if ( project->ResourceIsUsedForTask(r,t,j) )
00314 ++ndays;
00315 }
00316
00317 fprintf(f," %s %s %5d\n",
00318 project->sDays(t->start()), project->sDays(t->finish()), ndays);
00319 }
00320 fprintf(f,"\n");
00321 }
00322 fprintf(f,"\n\n\n");
00323 }
00324
00325 if ( f != stdout )
00326 fclose(f);
00327 }
00328
00329 void Reporter::XMLReport( Project *project, char *filename)
00330 {
00331 MILESTONE *m;
00332 int j;
00333 int ndays;
00334
00335 project->SortTasks( tg_sortbyresource );
00336
00337 FILE * f = OpenOutputFile(filename);
00338
00339 fprintf(f, "<?xml version=\"1.0\"?>\n");
00340 fprintf(f, "<project dateformat=\"%s\" startdate=\"%s\" enddate=\"%s\">\n",
00341 project->date_format, project->sStartDay(), project->sFinishDay() );
00342
00343 for ( Project::IPLCI pi = project->begin_items() ; pi != project->end_items() ; pi++ )
00344 fprintf(f, "\t<item cost=\"%3.2f\">%s</item>\n", (*pi)->cost(), (*pi)->description().c_str() );
00345
00346 fprintf(f,"\t<tasks>\n");
00347 for ( int i = 0; i < project->nTasks(); ++i )
00348 {
00349 TASK * t = project->sortedTask(i);
00350
00351 if ( t->isVacation() )
00352 continue;
00353
00354 double time_cost = t->timeCost();
00355 double item_cost = t->itemCost();
00356
00357 fprintf(f, "\t\t<task start=\"%s\" finish=\"%s\" assigned=\"%s\" uid=\"%s\" name=\"%s\" ",
00358 project->sDays(t->start()), project->sDays(t->finish()), t->assigned()->id(),
00359 t->id(), t->name());
00360 if ((t->bstart() != INVALIDDAYNO) && (t->bfinish() != INVALIDDAYNO))
00361 {
00362 fprintf(f,"bstart=\"%s\" bfinish=\"%s\" ",
00363 project->sDays(t->bstart()), project->sDays(t->bfinish()));
00364 }
00365
00366 if (t->astart() != INVALIDDAYNO)
00367 fprintf(f,"astart=\"%s\" ", project->sDays(t->astart()));
00368
00369 if (t->afinish() != INVALIDDAYNO)
00370 fprintf(f,"afinish=\"%s\" ", project->sDays(t->afinish()));
00371
00372 fprintf(f," completed=\"%3.2f%%\" timecost=\"%3.2f\" itemcost=\"%3.2f\">\n",
00373 t->percent_complete(), time_cost, item_cost);
00374
00375 for ( Project::IPLCI pi = t->begin_items() ; pi != t->end_items() ; pi++ )
00376 fprintf(f,"\t\t\t<item cost=\"%3.2f\">%s</item>\n",
00377 (*pi)->cost(),
00378 (*pi)->description().c_str());
00379
00380 for ( TASK::PTRLIST::const_iterator pt = t->begin_depends();
00381 pt != t->end_depends();
00382 pt++ )
00383 {
00384 TASK * tt = *pt;
00385 fprintf(f, "\t\t\t<depends uid=\"%s\" name=\"%s\" />\n",
00386 tt->id(), tt->name());
00387 }
00388
00389 for ( NOTE_ITERATOR n = t->begin_notes(); n != t->end_notes(); n++ )
00390 {
00391 fprintf(f, "\t\t\t<note>%s</note>\n", n->c_str());
00392 }
00393
00394 fprintf(f,"\t\t</task>\n");
00395 }
00396 fprintf(f,"\t</tasks>\n\n");
00397
00398 if (project->nMilestones())
00399 {
00400 project->SortMilestones();
00401 fprintf(f, "\t<milestones>\n");
00402 for ( int i = 0; i < project->nMilestones(); ++i )
00403 {
00404 m = project->sortedMilestone(i);
00405
00406 fprintf(f, "\t\t<milestone date=\"%s\" ", project->sDays(m->day()));
00407 if ( milestone_ids )
00408 fprintf(f, "uid=\"%s\" ", m->id());
00409 fprintf(f, "name=\"%s\" ", m->name());
00410 if ( m->bday() != INVALIDDAYNO )
00411 fprintf(f, "baseline=\"%s\" ", project->sDays(m->bday()));
00412 fprintf(f, "/>\n");
00413 }
00414 fprintf(f,"\t</milestones>\n");
00415 }
00416
00417 fprintf(f,"\t<resources>\n");
00418 for ( Project::RPLCI rl = project->beginResourceList();
00419 rl != project->endResourceList() ; rl++ )
00420 {
00421 RESOURCE * r = *rl;
00422 if ( r->is_group )
00423 {
00424 fprintf(f, "\t\t<group uid=\"%s\" name=\"%s\">\n", r->id(), r->name());
00425 for ( Project::RPLCI rl2 = r->contains.begin(); rl2 != r->contains.end(); rl2++ )
00426 fprintf(f,"\t\t\t<resource uid=\"%s\" name=\"%s\" efficiency=\"%.2f\" rate=\"%.2f\">\n",
00427 (*rl2)->id(), (*rl2)->name(), (*rl2)->efficiency(), (*rl2)->rate());
00428 }
00429 else
00430 fprintf(f,"\t\t<resource uid=\"%s\" name=\"%s\" efficiency=\"%.2f\" rate=\"%.2f\">\n",
00431 r->id(), r->name(), r->efficiency(), r->rate());
00432 for ( int i = 0; i < project->nTasks(); ++i )
00433 {
00434 TASK * t = project->sortedTask(i);
00435 if( t->assigned() != r )
00436 continue;
00437 if ( t->isVacation() )
00438 continue;
00439 fprintf(f,"\t\t\t<task uid=\"%s\" name=\"%s\" />\n", t->id(), t->name());
00440 }
00441 for ( int i = 0; i < project->nTasks(); ++i )
00442 {
00443 TASK * t = project->sortedTask(i);
00444 if ( t->assigned() != r )
00445 continue;
00446 if ( !t->isVacation() )
00447 continue;
00448 ndays = 0;
00449 for ( j = t->start(); j <= t->finish(); ++j )
00450 {
00451 if ( project->ResourceIsUsedForTask(r,t,j) )
00452 ++ndays;
00453 }
00454
00455 fprintf(f,"\t\t\t<vacation start=\"%s\" end=\"%s\" days=\"%d\" />\n",
00456 project->sDays(t->start()), project->sDays(t->finish()), ndays);
00457 }
00458 for ( NOTE_ITERATOR n = r->begin_notes(); n != r->end_notes(); n++ )
00459 fprintf(f, "\t\t\t<note>%s</note>\n", n->c_str());
00460 if ( r->is_group )
00461 fprintf(f,"\t\t</group>\n");
00462 else
00463 fprintf(f,"\t\t</resource>\n");
00464 }
00465 fprintf(f,"\t</resources>\n");
00466
00467 fprintf(f,"</project>\n");
00468 if ( f != stdout )
00469 fclose(f);
00470 }
00471
00472 void Reporter::HardSchedule( Project *project, char *filename)
00473 {
00474 FILE *f;
00475 TASK *t;
00476 int i;
00477
00478 project->SortTasks( tg_sortbyresource );
00479
00480 f = OpenOutputFile(filename);
00481
00482 for( i=0; i<project->nTasks(); ++i )
00483 {
00484 t = project->sortedTask(i);
00485 if ( t->isVacation() )
00486 continue;
00487 fprintf(f,"start %s %s\n", t->id(), project->sDays(t->start()));
00488 fprintf(f,"finish %s %s\n\n", t->id(), project->sDays(t->finish()));
00489 }
00490
00491 if( f!=stdout )
00492 fclose(f);
00493 }
00494
00495
00496 char *Reporter::TeXFix(char *buf, const char *txt)
00497 {
00498 char *ptr = buf;
00499 for( ; *txt!=0; ++txt )
00500 {
00501 if( *txt=='\\' )
00502 {
00503 strcpy(ptr,"$\\backslash$");
00504 ptr += strlen(ptr);
00505 }
00506 else if( *txt=='_' )
00507 {
00508 strcpy(ptr,"\\_");
00509 ptr += strlen(ptr);
00510 }
00511 else if( *txt=='%' )
00512 {
00513 strcpy(ptr,"\\%");
00514 ptr += strlen(ptr);
00515 }
00516 else if( *txt=='&' )
00517 {
00518 strcpy(ptr,"\\&");
00519 ptr += strlen(ptr);
00520 }
00521 else
00522 *(ptr++) = *txt;
00523 }
00524 *ptr = 0;
00525 return buf;
00526 }
00527
00528 void Reporter::TexReport( Project *project, char *filename)
00529 {
00530 char buf1[BUFLEN], buf2[BUFLEN], buf3[BUFLEN];
00531
00532 project->SortTasks( tg_sortbyresource );
00533
00534 FILE * f = OpenOutputFile(filename);
00535
00536 fprintf(f, "\\subsection{Time Frame}\n\\label{times}\n\n");
00537 fprintf(f, "\\begin{tabular}{rl}\n");
00538 fprintf(f, "Start Date: & %s \\\\\n", project->sStartDay());
00539 fprintf(f, "Finish Date: & %s \\\\\n", project->sFinishDay());
00540 fprintf(f, "\\end{tabular}\n\n");
00541 fprintf(f,"\\subsection{Task list}\n\n");
00542 fprintf(f,"\\begin{itemize}\n");
00543 for ( int i = 0 ; i < project->nTasks() ; ++i )
00544 {
00545 TASK * t = project->sortedTask(i);
00546 if ( t->isVacation() )
00547 continue;
00548 if ( task_ids )
00549 {
00550 fprintf(f, "\\item %s %s ",
00551 TeXFix(buf3,t->id()),
00552 TeXFix(buf1,t->name()));
00553 }
00554 else
00555 {
00556 fprintf(f, "\\item %s ",
00557 TeXFix(buf3,t->name()));
00558 }
00559 fprintf(f, "\\\\{\\em %s - %s; assigned to %s}\n",
00560 project->sDays(t->start()), project->sDays(t->finish()),
00561 TeXFix(buf2, t->assigned()->name()));
00562 if ( ( t->bstart() != INVALIDDAYNO )
00563 && ( t->bfinish() != INVALIDDAYNO ) )
00564 {
00565 fprintf(f, "\nBaseline\\\\{\\em %s - %s}\n",
00566 project->sDays(t->bstart()),
00567 project->sDays(t->bfinish()));
00568 }
00569 else if ( t->bstart() != INVALIDDAYNO )
00570 {
00571 fprintf(f, "\nBaseline\\\\{\\em %s - }\n",
00572 project->sDays(t->bstart()) );
00573 }
00574 else if ( t->bfinish() != INVALIDDAYNO )
00575 {
00576 fprintf(f, "\nBaseline\\\\{\\em - %s }\n",
00577 project->sDays(t->bfinish()) );
00578 }
00579 if ( ( t->astart() != INVALIDDAYNO )
00580 && ( t->afinish() != INVALIDDAYNO ) )
00581 {
00582 fprintf(f, "\nActual\\\\{\\em %s - %s}\n",
00583 project->sDays(t->astart()),
00584 project->sDays(t->afinish()));
00585 }
00586 else if ( t->astart() != INVALIDDAYNO )
00587 {
00588 fprintf(f, "\nActual\\\\{\\em %s - }\n",
00589 project->sDays(t->astart()) );
00590 }
00591 else if ( t->afinish() != INVALIDDAYNO )
00592 {
00593 fprintf(f, "\nActual\\\\{\\em - %s }\n",
00594 project->sDays(t->afinish()) );
00595 }
00596 if ( t->desc() != NULL && *t->desc() != 0 )
00597 fprintf(f, "\n{\\em %s}\n", t->desc());
00598 if ( t->overrun() != NULL && *t->overrun() != 0 )
00599 {
00600 char buf[4096];
00601 fprintf(f, "\n\\framebox{\\em %s}\n", TeXFix(buf, t->overrun()));
00602 }
00603 if ( task_notes && ( t->begin_notes() != t->end_notes() ) )
00604 {
00605 char buf[4096];
00606 fprintf(f, " \\begin{itemize}\n");
00607 for ( NOTE_ITERATOR n = t->begin_notes(); n != t->end_notes(); n++ )
00608 fprintf(f, " \\item %s\n", TeXFix(buf, n->c_str()));
00609 fprintf(f, " \\end{itemize}\n");
00610 }
00611 }
00612 fprintf(f, "\\end{itemize}\n\n\n");
00613
00614 project->SortMilestones();
00615
00616 fprintf(f, "\\subsection{Milestone List}\n\\label{milestones}\n\n");
00617
00618 if ( project->nMilestones() > 0 )
00619 {
00620 fprintf(f, "\\begin{itemize}\n");
00621
00622 for ( int i = 0; i < project->nMilestones(); ++i )
00623 {
00624 MILESTONE * m = project->sortedMilestone(i);
00625
00626 fprintf(f, "\\item ");
00627 if ( milestone_ids )
00628 fprintf(f, "%s %s\\\\",
00629 TeXFix(buf1,m->id()),
00630 TeXFix(buf2,m->name()));
00631 else
00632 fprintf(f, "%s\\\\",
00633 TeXFix(buf2,m->name()));
00634 fprintf(f, " \\emph{%s}\n\n",
00635 project->sDays(m->day()));
00636 if ( m->bday() != INVALIDDAYNO )
00637 {
00638 fprintf(f, "Baseline\\\\\emph{%s}\n",
00639 project->sDays(m->bday()));
00640 }
00641 fprintf(f, "\n\n");
00642 }
00643
00644 fprintf(f, "\\end{itemize}\n\n");
00645 }
00646
00647 fprintf(f,"\\subsection{Resources And Task Assignment}\n\n");
00648
00649 for( Project::RPLCI rl = project->beginResourceList() ;
00650 rl != project->endResourceList() ; rl++ )
00651 {
00652 int total_days = 0;
00653 int total_worked = 0;
00654 RESOURCE * r = *rl;
00655
00656 fprintf(f, "\\subsubsection{");
00657 if ( r->is_group )
00658 {
00659 for ( Project::RPLCI rl2 = r->contains.begin(); rl2 != r->contains.end(); rl2++ )
00660 fprintf(f,"%s%s ",
00661 TeXFix(buf1, (*rl2)->name()),
00662 rl2 == r->contains.end() ? "" : "," );
00663 }
00664 else
00665 fprintf(f, "%s ", TeXFix(buf1, r->name()));
00666 fprintf(f,"}\n\n");
00667
00668 fprintf(f,"\\begin{supertabular}{|p{20mm}|p{20mm}|r|r|p{75mm}|}\n");
00669
00670 fprintf(f, "\\hline\n");
00671 fprintf(f, "{\\bf Start} & {\\bf Finish} & {\\bf Days} & {\\bf Done} & {\\bf Task} \\\\\n");
00672 fprintf(f, "\\hline\n");
00673
00674 for ( int i = 0; i < project->nTasks(); ++i )
00675 {
00676 int j = 0, ndays = 0, worked = 0;
00677 TASK * t = project->sortedTask(i);
00678 if( t->assigned() != r )
00679 continue;
00680 if ( t->isVacation() )
00681 continue;
00682
00683 for ( j = t->start(); j <= t->finish(); ++j )
00684 {
00685 if ( project->ResourceIsUsedForTask(r,t,j) )
00686 ++ndays;
00687 }
00688
00689 total_days += ndays;
00690 worked = UserTaskWorkedDays(t, t->assigned());
00691 total_worked += worked;
00692
00693 fprintf(f, " %s & %s & %d & %d & ",
00694 project->sDays(t->start()), project->sDays(t->finish()), ndays, worked);
00695 if ( task_ids )
00696 fprintf(f,"%s %s \\\\\n",
00697 TeXFix(buf2,t->id()),
00698 TeXFix(buf1,t->name()));
00699 else
00700 fprintf(f,"%s \\\\\n",
00701 TeXFix(buf1,t->name()));
00702
00703
00704 if ( print_task_days )
00705 {
00706 RESOURCE *r = t->assigned();
00707 fprintf(f,"&&&& ");
00708 for ( ResourceTimeBlockIterator tb = r->begin_booked() ;
00709 tb != r->end_booked() ; tb++ )
00710 {
00711 if ( tb->task() == t )
00712 {
00713 if ( tb->start() == tb->finish() )
00714 fprintf(f, "%s, ", project->sDays(tb->start()));
00715 else
00716 fprintf(f, "%s~-~%s, ", project->sDays(tb->start()),
00717 project->sDays(tb->finish()));
00718 }
00719 }
00720 fprintf(f,"\\\\\n");
00721 }
00722 }
00723
00724 fprintf(f, "\\hline\n");
00725 fprintf(f, "\\multicolumn{5}{l}{\\bf Total: %d days scheduled, %d days completed.}\\\\\n",
00726 total_days, total_worked);
00727 fprintf(f, "\\end{supertabular}\n\n\n");
00728
00729 if ( resource_notes && ( r->begin_notes() != r->end_notes() ) )
00730 {
00731 char buf[4096];
00732 fprintf(f, " \\begin{itemize}\n");
00733 for ( NOTE_ITERATOR n = r->begin_notes(); n != r->end_notes(); n++ )
00734 fprintf(f, " \\item %s\n", TeXFix(buf, n->c_str()));
00735 fprintf(f, " \\end{itemize}\n");
00736 }
00737 }
00738
00739 if ( dependencies )
00740 {
00741 fprintf(f, "\\subsection{Dependencies}\n\n");
00742 fprintf(f, "\\begin{itemize}\n");
00743 for ( int i = 0; i < project->nTasks(); ++i )
00744 {
00745 TASK * t = project->sortedTask(i);
00746 if ( t->begin_depends() == t->end_depends() )
00747 continue;
00748 fprintf(f, "\\item (%s -- %s) %s\n",
00749 project->sDays(t->start()), project->sDays(t->finish()),
00750 TeXFix(buf1,t->name()) );
00751 fprintf(f," \\begin{itemize}\n");
00752 for ( TASK::PTRLIST::const_iterator pt = t->begin_depends();
00753 pt != t->end_depends();
00754 pt++ )
00755 {
00756 TASK * tt = *pt;
00757 fprintf(f, " \\item (%s -- %s) %s\n",
00758 project->sDays(tt->start()), project->sDays(tt->finish()),
00759 TeXFix(buf1,tt->name()) );
00760 }
00761 fprintf(f, " \\end{itemize}\n");
00762 fprintf(f, "\n");
00763 }
00764 fprintf(f, "\\end{itemize}\n\n\n");
00765 }
00766
00767 if ( vacations )
00768 {
00769 fprintf(f, "\\subsection{Vacations}\n\\label{vacations}\n\n");
00770
00771 for ( Project::RPLCI rl = project->beginResourceList() ;
00772 rl != project->endResourceList() ; rl++ )
00773 {
00774 RESOURCE * r = *rl;
00775
00776 fprintf(f, "\\subsubsection{");
00777 if ( r->is_group )
00778 {
00779 for ( Project::RPLCI rl2 = r->contains.begin(); rl2 != r->contains.end(); rl2++ )
00780 fprintf(f,"%s%s ",
00781 TeXFix(buf1, (*rl2)->name()),
00782 rl2 == r->contains.end() ? "" : "," );
00783 }
00784 else
00785 fprintf(f, "%s ", TeXFix(buf1, r->name()));
00786 fprintf(f,"}\n\n");
00787
00788 fprintf(f,"\\begin{supertabular}{|p{0.8in}|p{0.8in}|r|}\n");
00789 fprintf(f, "\\hline\n");
00790 fprintf(f, "{\\bf Start} & {\\bf Finish} & {\\bf Days} \\\\\n");
00791 fprintf(f, "\\hline\n");
00792
00793 for ( int i = 0; i < project->nTasks(); ++i )
00794 {
00795 int j = 0, ndays = 0;
00796 TASK * t = project->sortedTask(i);
00797 if ( t->assigned() != r )
00798 continue;
00799 if ( !t->isVacation() )
00800 continue;
00801
00802 for ( j = t->start(); j <= t->finish(); ++j )
00803 {
00804 if ( project->ResourceIsUsedForTask(r,t,j) )
00805 ++ndays;
00806 }
00807
00808 fprintf(f, " %s &", project->sDays(t->start()));
00809 fprintf(f, " %s &", project->sDays(t->finish()));
00810 fprintf(f, " %d \\\\\n", ndays);
00811 }
00812
00813 fprintf(f, "\\hline\n\\end{supertabular}\n\n");
00814 }
00815 }
00816
00817 if ( f != stdout )
00818 fclose(f);
00819 }
00820
00821 void Reporter::PrintResourcePeriod( Project *project,
00822 FILE *f, RESOURCE *r, int dayNo, int lastDay,
00823 REPORTTYPE rep_type)
00824 {
00825 TASK *t;
00826 int nDays;
00827 char buf1[BUFLEN], buf2[BUFLEN];
00828
00829 if ( MESSENGER::getGlobalDebug() )
00830 fprintf(f," %% PrintResourcePeriod(%s,%s / %d)\n",
00831 r->id(), project->sDays(dayNo), dayNo);
00832
00833 if ( r->is_group==0 )
00834 {
00835 for ( ResourceTimeBlockIterator tb = r->begin_booked() ;
00836 tb != r->end_booked() ; tb++ )
00837 {
00838 if ( ! tb->overlap( dayNo, lastDay ) )
00839 continue;
00840
00841 if( MESSENGER::getGlobalDebug() )
00842 fprintf(f," %% PrintResourcePeriod(%s,%s) - *something* booked\n",r->id(),project->sDays(dayNo));
00843
00844 t = tb->task();
00845 if ( t->isVacation() )
00846 continue;
00847
00848 nDays = 0;
00849 for ( int i = dayNo; i <= lastDay; ++i )
00850 {
00851 if( tb->start()<=i && tb->finish()>=i )
00852 {
00853 ++nDays;
00854 if( MESSENGER::getGlobalDebug() )
00855 fprintf(f," %% %s / %s / %s\n",r->id(),t->id(),project->sDays(i));
00856 }
00857 }
00858
00859 if( nDays==0 )
00860 {
00861 switch ( rep_type )
00862 {
00863 case TXT_REPORT:
00864 fprintf(f," - Paused: %s - %s.\n", t->id(), t->name() );
00865 break;
00866
00867 case TEX_REPORT:
00868 fprintf(f," \\item Paused: {\\tt %s} - %s.\n",
00869 TeXFix(buf1,t->id()), TeXFix(buf2,t->name()) );
00870 break;
00871
00872 case HTML_REPORT:
00873 fprintf(f,"<li> Paused: <tt>%s</tt> - %s.\n",
00874 HTMLFix(buf1,t->id()), HTMLFix(buf2,t->name()) );
00875 break;
00876
00877 default:
00878 fprintf(stderr, "Unhandled case 5\n");
00879 exit(1);
00880 }
00881 }
00882 else
00883 {
00884 int nworked;
00885 switch ( rep_type )
00886 {
00887 case TXT_REPORT:
00888 fprintf(f," - %d days - %s - %s.\n", nDays, t->id(), t->name() );
00889 break;
00890
00891 case TEX_REPORT:
00892 fprintf(f," \\item %d days - {\\tt %s} - %s.\n",
00893 nDays, TeXFix(buf1,t->id()), TeXFix(buf2,t->name()) );
00894 break;
00895
00896 case HTML_REPORT:
00897 fprintf(f,"<li> %d days - <tt>%s</tt> - %s.\n",
00898 nDays, HTMLFix(buf1,t->id()), HTMLFix(buf2,t->name()) );
00899 break;
00900
00901 default:
00902 fprintf(stderr, "Unhandled case 6\n");
00903 exit(1);
00904 }
00905 nworked = UserTaskWorkedDays(t,t->assigned());
00906 if( nworked>0 )
00907 {
00908 switch ( rep_type )
00909 {
00910 case TXT_REPORT:
00911 fprintf(f," (%d days completed.)\n",nworked);
00912 break;
00913
00914 case TEX_REPORT:
00915 fprintf(f," \\\\(%d days completed.)\n",nworked);
00916 break;
00917
00918 case HTML_REPORT:
00919 fprintf(f,"<br>(%d days completed.)\n",nworked);
00920 break;
00921
00922 default:
00923 fprintf(stderr, "Unhandled case 7\n");
00924 exit(1);
00925 }
00926 }
00927 }
00928 }
00929 }
00930
00931 for ( Project::RPLCI rl = r->belongs_to.begin() ;
00932 rl != r->belongs_to.end() ; rl++ )
00933 PrintResourcePeriod(project, f, *rl, dayNo, lastDay, rep_type);
00934 }
00935
00936
00937 void Reporter::PrintPeriod(Project *project,
00938 FILE *f, int dayNo, int lastDay, char *weekName,
00939 REPORTTYPE rep_type)
00940 {
00941 bool something = false;
00942 char buf1[BUFLEN];
00943
00944 Debug("PrintPeriod(%p,%d,%d,%s,%d)",f,dayNo,lastDay,weekName,rep_type);
00945
00946 for ( Project::TPLCI pt = project->beginTaskList();
00947 pt != project->endTaskList();
00948 pt++ )
00949 {
00950 if ( ! (*pt)->isVacation() && (*pt)->isActiveDuring(dayNo, lastDay) )
00951 {
00952 something = true;
00953 break;
00954 }
00955 }
00956 if ( !something )
00957 {
00958 Debug("Nothing in %s",weekName);
00959 return;
00960 }
00961
00962 switch ( rep_type )
00963 {
00964 case TXT_REPORT:
00965 fprintf(f,"\n\n----------------------------------------\n\n");
00966 fprintf(f,"%s\n",weekName);
00967 fprintf(f,"\n");
00968 break;
00969
00970 case TEX_REPORT:
00971 fprintf(f,"\\clearpage\n");
00972 fprintf(f,"\\subsection{%s}\n",weekName);
00973 fprintf(f,"\\begin{itemize}\n");
00974 break;
00975
00976 case HTML_REPORT:
00977 fprintf(f,"\n");
00978 fprintf(f,"<h1>%s</h1>\n",weekName);
00979 fprintf(f,"<ul>\n");
00980 break;
00981
00982 default:
00983 fprintf(stderr, "Unhandled case 1\n");
00984 exit(1);
00985 }
00986
00987 something = false;
00988 for ( Project::RPLCI rl = project->beginResourceList() ;
00989 rl != project->endResourceList() ; rl++ )
00990 {
00991 int r_used = 0;
00992
00993 RESOURCE * r = *rl;
00994
00995 if( r->is_group )
00996 continue;
00997
00998 for ( ResourceTimeBlockIterator tb = r->begin_booked() ;
00999 tb != r->end_booked() ; tb++ )
01000 {
01001 if ( tb->overlap( dayNo, lastDay) && !tb->task()->isVacation() )
01002 {
01003 r_used = 1;
01004 break;
01005 }
01006 }
01007 if ( r_used==0 )
01008 continue;
01009
01010 something = true;
01011
01012 switch ( rep_type )
01013 {
01014 case TXT_REPORT:
01015 fprintf(f,"* %s:\n", r->name() );
01016 PrintResourcePeriod(project, f, r, dayNo, lastDay, rep_type);
01017 break;
01018
01019 case TEX_REPORT:
01020 fprintf(f,"\\item {\\bf %s}\n", TeXFix(buf1,r->name() ) );
01021 fprintf(f," \\begin{itemize}\n");
01022 PrintResourcePeriod(project, f, r, dayNo, lastDay, rep_type);
01023 fprintf(f," \\end{itemize}\n\n");
01024 break;
01025
01026 case HTML_REPORT:
01027 fprintf(f,"<li> <strong>%s</strong>\n", HTMLFix(buf1,r->name()) );
01028 fprintf(f,"<ul>\n");
01029 PrintResourcePeriod(project, f, r, dayNo, lastDay, rep_type);
01030 fprintf(f,"</ul>\n\n");
01031 break;
01032
01033 default:
01034 fprintf(stderr, "Unhandled case 2\n");
01035 exit(1);
01036 }
01037
01038 }
01039
01040 if ( ! something )
01041 {
01042 switch ( rep_type )
01043 {
01044 case TXT_REPORT:
01045 fprintf(f,"* Nothing in %s\n",weekName);
01046 break;
01047
01048 case TEX_REPORT:
01049 fprintf(f,"\\item Nothing in %s\n",weekName);
01050 break;
01051
01052 case HTML_REPORT:
01053 fprintf(f,"<li> Nothing in %s\n",weekName);
01054 break;
01055
01056 default:
01057 fprintf(stderr, "Unhandled case 3\n");
01058 exit(1);
01059 }
01060 }
01061
01062 switch ( rep_type )
01063 {
01064 case TXT_REPORT:
01065 fprintf(f,"\n\n\n");
01066 break;
01067
01068 case TEX_REPORT:
01069 fprintf(f,"\\end{itemize}\n\n\n");
01070 break;
01071
01072 case HTML_REPORT:
01073 fprintf(f,"</ul>\n\n\n");
01074 break;
01075
01076 default:
01077 fprintf(stderr, "Unhandled case \n");
01078 exit(1);
01079 }
01080 }
01081
01082
01083 void Reporter::PeriodicReport( Project * project,
01084 Pperfunc IsPeriod,
01085 char *filename,
01086 REPORTTYPE rep_type)
01087 {
01088 int dayNo;
01089 int lastDay=0;
01090 char weekName[BUFLEN];
01091
01092 project->SortTasks( tg_sortbyresource );
01093
01094 FILE * f = OpenOutputFile(filename);
01095 switch ( rep_type )
01096 {
01097 case TXT_REPORT:
01098 break;
01099
01100 case TEX_REPORT:
01101 break;
01102
01103 case HTML_REPORT:
01104 fprintf(f,"<html>\n<body>\n\n");
01105 break;
01106
01107 default:
01108 fprintf(stderr, "Unhandled case 4\n");
01109 exit(1);
01110 }
01111
01112 if( MESSENGER::getGlobalDebug() )
01113 fprintf(f,"%% time period / people / tasks report\n");
01114
01115 for( dayNo=0; dayNo<MAX_TIME; ++dayNo )
01116 {
01117 if( (lastDay=(this->*IsPeriod)(project, dayNo, weekName)) )
01118 {
01119 PrintPeriod( project, f, dayNo, lastDay, weekName, rep_type );
01120 }
01121 }
01122
01123 switch ( rep_type )
01124 {
01125 case TXT_REPORT:
01126 break;
01127
01128 case TEX_REPORT:
01129 break;
01130
01131 case HTML_REPORT:
01132 fprintf(f,"\n\n</body>\n</html>\n");
01133 break;
01134
01135 default:
01136 fprintf(stderr, "Unhandled case 4\n");
01137 exit(1);
01138 }
01139
01140 if( f!=stdout )
01141 fclose(f);
01142 }
01143
01144
01145 int Reporter::IsWeek(Project *project, int dayNo, char *name)
01146 {
01147 if( dayNo==0 )
01148 {
01149 sprintf(name,"Week of %s",project->sDays(dayNo));
01150 while( Wday(project->tDays(dayNo))!=5 )
01151 ++dayNo;
01152 return dayNo;
01153 }
01154
01155 if( Wday(project->tDays(dayNo))==1 )
01156 {
01157 sprintf(name,"Week of %s",project->sDays(dayNo));
01158 return dayNo+4;
01159 }
01160
01161 *name = 0;
01162 return 0;
01163 }
01164
01165 void Reporter::WeeklyReport(Project *project, char *filename, REPORTTYPE rep_type)
01166 {
01167 PeriodicReport(project, &Reporter::IsWeek, filename, rep_type);
01168 }
01169
01170
01171 int Reporter::IsMonth(Project *project, int dayNo, char *name)
01172 {
01173 static int lastMonth = -1;
01174 int thisMonth;
01175
01176 thisMonth = Month( project->tDays(dayNo) );
01177
01178 if( lastMonth != thisMonth )
01179 {
01180 lastMonth = thisMonth;
01181 sprintf(name,"Month of %s, %d",longMonthNames[thisMonth],
01182 Year(project->tDays(dayNo)));
01183 while( Month(project->tDays(dayNo))==thisMonth )
01184 ++dayNo;
01185 return dayNo-1;
01186 }
01187
01188 *name = 0;
01189 return 0;
01190 }
01191
01192 void Reporter::MonthlyReport(Project *project, char *filename, REPORTTYPE rep_type)
01193 {
01194 PeriodicReport(project, &Reporter::IsMonth,filename,rep_type);
01195 }
01196
01197
01198
01199 char *Reporter::HTMLFix(char *buf, const char *txt)
01200 {
01201 char *ptr = buf;
01202 for( ; *txt!=0; ++txt )
01203 {
01204 if ( *txt == '&' )
01205 {
01206 strcpy(ptr, "&");
01207 ptr += 5;
01208 }
01209 else if ( *txt == '<' )
01210 {
01211 strcpy(ptr, "<");
01212 ptr += 4;
01213 }
01214 else if ( *txt == '>' )
01215 {
01216 strcpy(ptr, ">");
01217 ptr += 4;
01218 }
01219 else
01220 {
01221 *(ptr++) = *txt;
01222 }
01223 }
01224 *ptr = 0;
01225 return buf;
01226 }
01227
01228 void Reporter::HTMLReport(Project *project, char *filename)
01229 {
01230 char buf1[BUFLEN], buf2[BUFLEN], buf3[BUFLEN];
01231
01232 project->SortTasks( tg_sortbyresource );
01233
01234 FILE * f = OpenOutputFile(filename);
01235
01236 fprintf(f, "<html>\n<body>\n\n");
01237
01238 fprintf(f, "<h1><a name=\"times\">Time Frame</a></h1>\n");
01239 fprintf(f, "<table BORDER=0 CELLPADDING=5>\n");
01240 fprintf(f, "<tr>\n<td align=right>Start Date:</td><td>%s</td>\n</tr>\n",
01241 project->sStartDay());
01242 fprintf(f, "<tr>\n<td align=right>Finish Date:</td><td>%s</td>\n</tr>\n",
01243 project->sFinishDay());
01244 fprintf(f, "</table>\n\n");
01245
01246 fprintf(f, "<h1><a name=\"tasks\">Task List</a></h1>\n");
01247 fprintf(f, "<table BORDER=1 CELLPADDING=2>\n");
01248 fprintf(f, "<tr><th>Task</th><th>Start</th><th>Finish</th>");
01249 fprintf(f, "<th>Resource</th><th>Description</th>");
01250 fprintf(f, "<th COLSPAN=2>Baseline</th><th COLSPAN=2>Actual</th></tr>\n");
01251 for ( int i = 0 ; i < project->nTasks(); ++i )
01252 {
01253 TASK * t = project->sortedTask(i);
01254 if ( t->isVacation() )
01255 continue;
01256
01257 fprintf(f, "<tr>\n");
01258 if ( task_ids )
01259 fprintf(f, "<td>%s %s</td>\n",
01260 HTMLFix(buf3,t->id()),
01261 HTMLFix(buf1,t->name()));
01262 else
01263 fprintf(f, "<td>%s</td>\n",
01264 HTMLFix(buf1,t->name()));
01265 fprintf(f, "<td>%s</td><td>%s</td><td>%s</td>\n",
01266 project->sDays(t->start()), project->sDays(t->finish()),
01267 HTMLFix(buf2,t->assigned()->name()));
01268 if (( t->desc() != NULL ) && ( *t->desc() != 0 ))
01269 {
01270 fprintf(f, "<td>%s</td>\n",t->desc());
01271 }
01272 else
01273 {
01274 fprintf(f, "<td> </td>\n");
01275 }
01276
01277 if ((t->bstart() != INVALIDDAYNO) && (t->bfinish() != INVALIDDAYNO))
01278 {
01279 fprintf(f, "<td>%s</td><td>%s</td>\n",
01280 project->sDays(t->bstart()), project->sDays(t->bfinish()));
01281 }
01282 else if (t->bstart() != INVALIDDAYNO)
01283 {
01284 fprintf(f, "<td>%s</td><td> </td>\n",
01285 project->sDays(t->bstart()));
01286 }
01287 else if (t->bfinish() != INVALIDDAYNO)
01288 {
01289 fprintf(f, "<td> </td><td>%s</td>\n",
01290 project->sDays(t->bfinish()));
01291 }
01292 else
01293 {
01294 fprintf(f, "<td> </td><td> </td>\n");
01295 }
01296 if ((t->astart() != INVALIDDAYNO) && (t->afinish() != INVALIDDAYNO))
01297 {
01298 fprintf(f, "<td>%s</td><td>%s</td>\n",
01299 project->sDays(t->astart()), project->sDays(t->afinish()));
01300 }
01301 else if (t->astart() != INVALIDDAYNO)
01302 {
01303 fprintf(f, "<td>%s</td><td> </td>\n",
01304 project->sDays(t->astart()));
01305 }
01306 else if (t->afinish() != INVALIDDAYNO)
01307 {
01308 fprintf(f, "<td> </td><td>%s</td>\n",
01309 project->sDays(t->afinish()));
01310 }
01311 else
01312 {
01313 fprintf(f, "<td> </td><td> </td>\n");
01314 }
01315 fprintf(f, "</tr>\n");
01316 if (( t->overrun()!=NULL ) && ( *t->overrun()!=0 ))
01317 {
01318 char buf[4096];
01319 fprintf(f,
01320 "<tr><td COLSPAN=9><strong>%s</strong></td></tr>\n",
01321 HTMLFix(buf,t->overrun()));
01322 }
01323 if ( task_notes && ( t->begin_notes() != t->end_notes() ) )
01324 {
01325 char buf[4096];
01326 fprintf(f, "<tr><td> </td><td COLSPAN=8>\n");
01327 for ( NOTE_ITERATOR n = t->begin_notes(); n != t->end_notes(); n++ )
01328 fprintf(f, "%s<br>\n", HTMLFix(buf,n->c_str()));
01329 fprintf(f, "</td></tr>\n");
01330 }
01331 }
01332 fprintf(f, "</table>\n\n");
01333
01334 project->SortMilestones();
01335
01336 fprintf(f, "<h1><a name=\"milestones\">Milestone List</a></h1>\n\n");
01337
01338 fprintf(f, "<table BORDER=1 CELLPADDING=2>\n");
01339 fprintf(f, "<tr>");
01340 fprintf(f, "<th>Milestone</th><th>Date</th>");
01341 fprintf(f, "<th>Baseline</th>");
01342 fprintf(f, "</tr>\n");
01343
01344 for ( int i = 0; i < project->nMilestones(); ++i )
01345 {
01346 MILESTONE * m = project->sortedMilestone(i);
01347
01348 fprintf(f, "<tr>\n");
01349 if ( milestone_ids )
01350 fprintf(f, "<td>%s %s</td>",
01351 HTMLFix(buf1,m->id()),
01352 HTMLFix(buf2,m->name()));
01353 else
01354 fprintf(f, "<td>%s</td>",
01355 HTMLFix(buf2,m->name()));
01356 fprintf(f, "<td>%s</td>",
01357 project->sDays(m->day()));
01358 if ( m->bday() != INVALIDDAYNO )
01359 {
01360 fprintf(f, "<td>%s</td>",
01361 project->sDays(m->bday()));
01362 }
01363 else
01364 {
01365 fprintf(f, "<td> </td>");
01366 }
01367 fprintf(f, "\n</tr>\n");
01368 }
01369
01370 fprintf(f, "</table>\n\n");
01371
01372 fprintf(f, "<h1><a name=\"assignments\">Resources And Task Assignment</a></h1>\n\n");
01373
01374 for ( Project::RPLCI rl = project->beginResourceList() ;
01375 rl != project->endResourceList() ; rl++ )
01376 {
01377 int total_days = 0;
01378 int total_worked = 0;
01379 RESOURCE * r = *rl;
01380
01381 fprintf(f, "<h2>");
01382 if ( r->is_group )
01383 {
01384 for ( Project::RPLCI rl2 = r->contains.begin(); rl2 != r->contains.end(); rl2++ )
01385 fprintf(f, "%s%s ",
01386 HTMLFix(buf1,(*rl2)->name()),
01387 rl2 == r->contains.end()?"":"," );
01388 }
01389 else
01390 fprintf(f, "%s ",HTMLFix(buf1,r->name()));
01391 fprintf(f, "</h2>\n\n");
01392
01393 fprintf(f, "<table BORDER=1 CELLPADDING=2>\n");
01394
01395 fprintf(f, "<tr><th>Start</th> <th>Finish</th> <th>Days</th> <th>Done</th> <th>Task</th>");
01396 if ( print_task_days )
01397 fprintf(f, "<th>Dates</th>");
01398 fprintf(f, "</tr>\n");
01399
01400 for ( int i = 0; i < project->nTasks(); ++i )
01401 {
01402 int j = 0, ndays = 0, worked = 0;
01403 TASK * t = project->sortedTask(i);
01404 if ( t->assigned() != r )
01405 continue;
01406 if ( t->isVacation() )
01407 continue;
01408
01409 for ( j = t->start(); j <= t->finish(); ++j )
01410 {
01411 if ( project->ResourceIsUsedForTask(r,t,j) )
01412 ++ndays;
01413 }
01414
01415 total_days += ndays;
01416 worked = UserTaskWorkedDays(t, t->assigned());
01417 total_worked += worked;
01418
01419 fprintf(f, "<tr><td>%s</td> <td>%s</td> <td ALIGN=\"RIGHT\">%d</td> <td ALIGN=\"RIGHT\">%d</td> ",
01420 project->sDays(t->start()), project->sDays(t->finish()), ndays, worked);
01421 if ( task_ids )
01422 fprintf(f, "<td>%s %s</td>\n",
01423 HTMLFix(buf2,t->id()), HTMLFix(buf1,t->name()));
01424 else
01425 fprintf(f, "<td>%s</td>\n",
01426 HTMLFix(buf1,t->name()));
01427
01428
01429 if ( print_task_days )
01430 {
01431 RESOURCE *r = t->assigned();
01432 fprintf(f, "<td>");
01433 for ( ResourceTimeBlockIterator tb = r->begin_booked() ;
01434 tb != r->end_booked() ;
01435 tb++ )
01436 {
01437 if( tb->task() == t )
01438 {
01439 if ( tb->start() == tb->finish() )
01440 fprintf(f, "%s, ", project->sDays(tb->start()));
01441 else
01442 fprintf(f, "%s - %s, ",
01443 project->sDays(tb->start()),
01444 project->sDays(tb->finish()));
01445 }
01446 }
01447 fprintf(f, "</td></tr>\n");
01448 }
01449 fprintf(f, "</tr>\n");
01450 }
01451
01452 if ( print_task_days )
01453 fprintf(f, "<tr><td colspan=6>");
01454 else
01455 fprintf(f, "<tr><td colspan=5>");
01456 fprintf(f,
01457 "<strong>Total: %d days scheduled, %d days completed.</strong></td></tr>\n",
01458 total_days, total_worked);
01459 fprintf(f, "</table>\n");
01460
01461 if ( resource_notes && ( r->begin_notes() != r->end_notes() ) )
01462 {
01463 char buf[4096];
01464 fprintf(f, " <ul>\n");
01465 for ( NOTE_ITERATOR n = r->begin_notes(); n != r->end_notes(); n++ )
01466 fprintf(f, " <li> %s\n", HTMLFix(buf,n->c_str()));
01467 fprintf(f, " </ul>\n");
01468 }
01469 }
01470
01471 if ( dependencies )
01472 {
01473 fprintf(f, "<h1>Dependencies</h1>\n\n");
01474 fprintf(f, "<ul>\n");
01475 for ( int i = 0; i < project->nTasks(); ++i )
01476 {
01477 TASK * t = project->sortedTask(i);
01478 if ( t->begin_depends() == t->end_depends() )
01479 continue;
01480 fprintf(f, "<li> (%s - %s) ",
01481 project->sDays(t->start()), project->sDays(t->finish()));
01482 if ( task_ids )
01483 fprintf(f, "%s ", HTMLFix(buf2,t->id()));
01484 fprintf(f, "%s\n", HTMLFix(buf1,t->name()));
01485 fprintf(f, " <ul>\n");
01486 for ( Project::TPLCI pt = t->begin_depends(); pt != t->end_depends(); pt++ )
01487 {
01488 TASK * tt = *pt;
01489 fprintf(f, " <li> (%s - %s) ",
01490 project->sDays(tt->start()), project->sDays(tt->finish()));
01491 if ( task_ids )
01492 fprintf(f, "%s ", HTMLFix(buf2,tt->id()));
01493 fprintf(f, "%s\n", HTMLFix(buf1,tt->name()));
01494 }
01495 fprintf(f, " </ul>\n");
01496 fprintf(f, "\n");
01497 }
01498 fprintf(f, "</ul>\n\n\n");
01499 }
01500
01501 if ( vacations )
01502 {
01503 fprintf(f, "<h1>Vacations</h1>\n\n");
01504
01505 for ( Project::RPLCI rl = project->beginResourceList() ;
01506 rl != project->endResourceList() ; rl++ )
01507 {
01508 RESOURCE * r = *rl;
01509
01510 fprintf(f, "<h2>");
01511 if ( r->is_group )
01512 {
01513 for ( Project::RPLCI rl2 = r->contains.begin(); rl2 != r->contains.end(); rl2++ )
01514 fprintf(f, "%s%s ",
01515 HTMLFix(buf1,(*rl2)->name()),
01516 rl2 == r->contains.end()?"":"," );
01517 }
01518 else
01519 fprintf(f, "%s ",HTMLFix(buf1,r->name()));
01520 fprintf(f, "</h2>\n\n");
01521
01522 fprintf(f, "<table BORDER=1 CELLPADDING=2>\n");
01523
01524 fprintf(f, "<tr><th>Start</th> <th>Finish</th> <th>Days</th>");
01525 fprintf(f, "</tr>\n");
01526
01527 for ( int i = 0; i < project->nTasks(); ++i )
01528 {
01529 TASK * t = project->sortedTask(i);
01530 if ( t->assigned() != r )
01531 continue;
01532 if ( !t->isVacation() )
01533 continue;
01534
01535 int ndays = 0;
01536 for ( int j = t->start(); j <= t->finish(); ++j )
01537 {
01538 if ( project->ResourceIsUsedForTask(r,t,j) )
01539 ++ndays;
01540 }
01541
01542 fprintf(f, "<tr><td>%s</td>", project->sDays(t->start()));
01543 fprintf(f, " <td>%s</td>", project->sDays(t->finish()));
01544 fprintf(f, "<td ALIGN=\"RIGHT\">%d</td></tr>\n", ndays);
01545 }
01546
01547 fprintf(f, "</table>\n");
01548 }
01549 }
01550
01551 fprintf(f, "\n\n</body>\n</html>\n");
01552
01553 if ( f != stdout )
01554 fclose(f);
01555 }
01556