Main Page   Namespace List   Class Hierarchy   Compound List   File List   Compound Members   File Members  

print.cc

Go to the documentation of this file.
00001 /*
00002 ** Copyright (C) 2000 Alan McIvor <alan@mcivor.gen.nz>
00003 **  
00004 ** This program is free software; you can redistribute it and/or modify
00005 ** it under the terms of the GNU General Public License as published by
00006 ** the Free Software Foundation; either version 2 of the License, or
00007 ** (at your option) any later version.
00008 ** 
00009 ** This program is distributed in the hope that it will be useful,
00010 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 ** GNU General Public License for more details.
00013 ** 
00014 ** You should have received a copy of the GNU General Public License
00015 ** along with this program; if not, write to the Free Software 
00016 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
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;       // 1 day in seconds
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   Returns day index (in range 0 through MAX_TIME-1 inclusive)
00096   or -1 if not valid.
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             // we may want to print even if afinish in still not defined
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             /* QQQ */
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, "&amp;");
01207             ptr += 5;
01208         }
01209         else if ( *txt == '<' )
01210         {
01211             strcpy(ptr, "&lt;");
01212             ptr += 4;
01213         }
01214         else if ( *txt == '>' )
01215         {
01216             strcpy(ptr, "&gt;");
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>&nbsp;</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>&nbsp;</td>\n",
01285                     project->sDays(t->bstart()));
01286         }
01287         else if (t->bfinish() != INVALIDDAYNO)
01288         {
01289             fprintf(f, "<td>&nbsp;</td><td>%s</td>\n",
01290                     project->sDays(t->bfinish()));
01291         }
01292         else
01293         {
01294             fprintf(f, "<td>&nbsp;</td><td>&nbsp;</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>&nbsp;</td>\n",
01304                     project->sDays(t->astart()));
01305         }
01306         else if (t->afinish() != INVALIDDAYNO)
01307         {
01308             fprintf(f, "<td>&nbsp;</td><td>%s</td>\n",
01309                     project->sDays(t->afinish()));
01310         }
01311         else
01312         {
01313             fprintf(f, "<td>&nbsp;</td><td>&nbsp;</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>&nbsp;</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>&nbsp;</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             /* QQQ */
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&nbsp;-&nbsp;%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&nbsp;-&nbsp;%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&nbsp;-&nbsp;%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 

Generated on Wed Feb 18 22:23:54 2004 for Opensched by doxygen1.2.15