taskjuggler 0.0.7 → 0.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +119 -0
- data/benchmarks/allocatedSlots.tjp +1602 -0
- data/benchmarks/booking.tjp +40 -30
- data/{test/TestSuite/ReportGenerator/Errors → benchmarks}/css/tjmanual.css +0 -0
- data/{test/TestSuite/Scheduler/Correct → benchmarks}/css/tjreport.css +1 -0
- data/benchmarks/gantt.tjp +57 -0
- data/benchmarks/htmltaskreport.tjp +26 -1
- data/{test/TestSuite/ReportGenerator/Errors → benchmarks}/icons/details.png +0 -0
- data/{test/TestSuite/ReportGenerator/Errors → benchmarks}/icons/flag-green.png +0 -0
- data/{test/TestSuite/ReportGenerator/Errors → benchmarks}/icons/flag-red.png +0 -0
- data/{test/TestSuite/ReportGenerator/Errors → benchmarks}/icons/flag-yellow.png +0 -0
- data/{test/TestSuite/ReportGenerator/Errors → benchmarks}/icons/resource.png +0 -0
- data/{test/TestSuite/ReportGenerator/Errors → benchmarks}/icons/resourcegroup.png +0 -0
- data/{test/TestSuite/ReportGenerator/Errors → benchmarks}/icons/task.png +0 -0
- data/{test/TestSuite/ReportGenerator/Errors → benchmarks}/icons/taskgroup.png +0 -0
- data/{test/TestSuite/ReportGenerator/Errors → benchmarks}/icons/trend-down.png +0 -0
- data/{test/TestSuite/ReportGenerator/Errors → benchmarks}/icons/trend-flat.png +0 -0
- data/{test/TestSuite/ReportGenerator/Errors → benchmarks}/icons/trend-up.png +0 -0
- data/benchmarks/profile.clt +36082 -0
- data/benchmarks/profile.html +58182 -0
- data/benchmarks/runbench.rb +6 -0
- data/{test/TestSuite/ReportGenerator/Errors → benchmarks}/scripts/wz_tooltip.js +0 -0
- data/doc/AppConfig.html +85 -37
- data/doc/Arguments.html +11 -1
- data/doc/CHANGELOG.html +131 -2
- data/doc/COPYING.html +11 -1
- data/doc/Object.html +12 -3
- data/doc/README.html +11 -1
- data/doc/RuntimeConfig.html +11 -1
- data/doc/String.html +11 -1
- data/doc/StringIO.html +11 -1
- data/doc/TaskJuggler.html +250 -219
- data/doc/TaskJuggler/Account.html +11 -1
- data/doc/TaskJuggler/AccountAttribute.html +11 -1
- data/doc/TaskJuggler/AccountScenario.html +11 -1
- data/doc/TaskJuggler/Allocation.html +11 -1
- data/doc/TaskJuggler/AllocationAttribute.html +11 -1
- data/doc/TaskJuggler/AttributeBase.html +11 -1
- data/doc/TaskJuggler/AttributeDefinition.html +11 -1
- data/doc/TaskJuggler/BatchProcessor.html +11 -1
- data/doc/TaskJuggler/Booking.html +11 -1
- data/doc/TaskJuggler/BookingListAttribute.html +11 -1
- data/doc/TaskJuggler/BooleanAttribute.html +11 -1
- data/doc/TaskJuggler/CSVFile.html +12 -2
- data/doc/TaskJuggler/CellSettingPattern.html +11 -1
- data/doc/TaskJuggler/CellSettingPatternList.html +11 -1
- data/doc/TaskJuggler/Charge.html +11 -1
- data/doc/TaskJuggler/ChargeListAttribute.html +11 -1
- data/doc/TaskJuggler/ChargeSet.html +11 -1
- data/doc/TaskJuggler/ChargeSetListAttribute.html +11 -1
- data/doc/TaskJuggler/CollisionDetector.html +1063 -0
- data/doc/TaskJuggler/ColumnListAttribute.html +11 -1
- data/doc/TaskJuggler/ColumnTable.html +11 -1
- data/doc/TaskJuggler/Daemon.html +11 -1
- data/doc/TaskJuggler/{OnShiftCache.html → DataCache.html} +127 -139
- data/doc/TaskJuggler/DataCacheEntry.html +711 -0
- data/doc/TaskJuggler/DateAttribute.html +11 -1
- data/doc/TaskJuggler/DefinitionListAttribute.html +11 -1
- data/doc/TaskJuggler/DependencyListAttribute.html +11 -1
- data/doc/TaskJuggler/DurationAttribute.html +16 -5
- data/doc/TaskJuggler/FileList.html +11 -1
- data/doc/TaskJuggler/FileRecord.html +11 -1
- data/doc/TaskJuggler/FixnumAttribute.html +19 -9
- data/doc/TaskJuggler/FlagListAttribute.html +29 -19
- data/doc/TaskJuggler/FloatAttribute.html +23 -13
- data/doc/TaskJuggler/FormatListAttribute.html +19 -9
- data/doc/TaskJuggler/GanttChart.html +94 -133
- data/doc/TaskJuggler/GanttContainer.html +11 -1
- data/doc/TaskJuggler/GanttHeader.html +11 -1
- data/doc/TaskJuggler/GanttHeaderScaleItem.html +11 -1
- data/doc/TaskJuggler/GanttLine.html +11 -1
- data/doc/TaskJuggler/GanttLoadStack.html +11 -1
- data/doc/TaskJuggler/GanttMilestone.html +11 -1
- data/doc/TaskJuggler/GanttRouter.html +247 -596
- data/doc/TaskJuggler/GanttTaskBar.html +11 -1
- data/doc/TaskJuggler/HTMLDocument.html +11 -1
- data/doc/TaskJuggler/HTMLGraphics.html +11 -1
- data/doc/TaskJuggler/Interval.html +11 -1
- data/doc/TaskJuggler/IntervalListAttribute.html +33 -23
- data/doc/TaskJuggler/JobInfo.html +11 -1
- data/doc/TaskJuggler/Journal.html +11 -1
- data/doc/TaskJuggler/JournalEntry.html +11 -1
- data/doc/TaskJuggler/JournalEntryList.html +11 -1
- data/doc/TaskJuggler/KeywordArray.html +11 -1
- data/doc/TaskJuggler/KeywordDocumentation.html +16 -6
- data/doc/TaskJuggler/Limits.html +11 -1
- data/doc/TaskJuggler/Limits/Limit.html +11 -1
- data/doc/TaskJuggler/LimitsAttribute.html +24 -14
- data/doc/TaskJuggler/ListAttributeBase.html +11 -1
- data/doc/TaskJuggler/Log.html +11 -1
- data/doc/TaskJuggler/LogFile.html +11 -1
- data/doc/TaskJuggler/LogicalAttribute.html +11 -1
- data/doc/TaskJuggler/LogicalExpression.html +11 -1
- data/doc/TaskJuggler/LogicalExpressionAttribute.html +19 -9
- data/doc/TaskJuggler/LogicalFlag.html +11 -1
- data/doc/TaskJuggler/LogicalFunction.html +11 -1
- data/doc/TaskJuggler/LogicalOperation.html +11 -1
- data/doc/TaskJuggler/Macro.html +11 -1
- data/doc/TaskJuggler/MacroTable.html +11 -1
- data/doc/TaskJuggler/ManagerResponsibilities.html +11 -1
- data/doc/TaskJuggler/ManagerStatusRecord.html +11 -1
- data/doc/TaskJuggler/Message.html +11 -1
- data/doc/TaskJuggler/MessageHandler.html +11 -1
- data/doc/TaskJuggler/Navigator.html +12 -2
- data/doc/TaskJuggler/NavigatorElement.html +11 -1
- data/doc/TaskJuggler/NikuProject.html +11 -1
- data/doc/TaskJuggler/NikuReport.html +11 -1
- data/doc/TaskJuggler/NikuResource.html +11 -1
- data/doc/TaskJuggler/NodeListAttribute.html +17 -7
- data/doc/TaskJuggler/PlaceHolderCell.html +722 -0
- data/doc/TaskJuggler/ProcessIntercom.html +11 -1
- data/doc/TaskJuggler/ProcessIntercomIface.html +11 -1
- data/doc/TaskJuggler/Project.html +587 -500
- data/doc/TaskJuggler/ProjectBroker.html +11 -1
- data/doc/TaskJuggler/ProjectBrokerIface.html +11 -1
- data/doc/TaskJuggler/ProjectFileParser.html +205 -192
- data/doc/TaskJuggler/ProjectFileScanner.html +230 -207
- data/doc/TaskJuggler/ProjectRecord.html +11 -1
- data/doc/TaskJuggler/ProjectServer.html +11 -1
- data/doc/TaskJuggler/ProjectServerIface.html +11 -1
- data/doc/TaskJuggler/PropertyAttribute.html +19 -9
- data/doc/TaskJuggler/PropertyList.html +95 -83
- data/doc/TaskJuggler/PropertySet.html +11 -1
- data/doc/TaskJuggler/PropertyTreeNode.html +11 -1
- data/doc/TaskJuggler/Query.html +234 -232
- data/doc/TaskJuggler/RTFHandlers.html +11 -1
- data/doc/TaskJuggler/RTFNavigator.html +11 -1
- data/doc/TaskJuggler/RTFQuery.html +11 -1
- data/doc/TaskJuggler/RTFReport.html +11 -1
- data/doc/TaskJuggler/RTFReportLink.html +11 -1
- data/doc/TaskJuggler/RTFWithQuerySupport.html +11 -1
- data/doc/TaskJuggler/RealFormat.html +12 -2
- data/doc/TaskJuggler/RealFormatAttribute.html +15 -5
- data/doc/TaskJuggler/ReferenceAttribute.html +38 -28
- data/doc/TaskJuggler/Report.html +96 -113
- data/doc/TaskJuggler/ReportBase.html +161 -152
- data/doc/TaskJuggler/ReportContext.html +11 -1
- data/doc/TaskJuggler/ReportServer.html +59 -48
- data/doc/TaskJuggler/ReportServerIface.html +51 -41
- data/doc/TaskJuggler/ReportServerRecord.html +11 -1
- data/doc/TaskJuggler/ReportServlet.html +11 -1
- data/doc/TaskJuggler/ReportTable.html +46 -25
- data/doc/TaskJuggler/ReportTableCell.html +296 -275
- data/doc/TaskJuggler/ReportTableColumn.html +14 -4
- data/doc/TaskJuggler/ReportTableLegend.html +11 -1
- data/doc/TaskJuggler/ReportTableLine.html +19 -7
- data/doc/TaskJuggler/Resource.html +12 -2
- data/doc/TaskJuggler/ResourceListAttribute.html +40 -30
- data/doc/TaskJuggler/ResourceListRE.html +11 -1
- data/doc/TaskJuggler/ResourceScenario.html +708 -565
- data/doc/TaskJuggler/RichText.html +54 -36
- data/doc/TaskJuggler/RichTextAttribute.html +31 -21
- data/doc/TaskJuggler/RichTextDocument.html +11 -1
- data/doc/TaskJuggler/RichTextElement.html +11 -1
- data/doc/TaskJuggler/RichTextFunctionExample.html +11 -1
- data/doc/TaskJuggler/RichTextFunctionHandler.html +11 -1
- data/doc/TaskJuggler/RichTextImage.html +11 -1
- data/doc/TaskJuggler/RichTextIntermediate.html +81 -71
- data/doc/TaskJuggler/RichTextParser.html +88 -33
- data/doc/TaskJuggler/RichTextScanner.html +45 -35
- data/doc/TaskJuggler/RichTextSnip.html +11 -1
- data/doc/TaskJuggler/RichTextSyntaxRules.html +436 -389
- data/doc/TaskJuggler/Scenario.html +11 -1
- data/doc/TaskJuggler/ScenarioData.html +11 -1
- data/doc/TaskJuggler/ScenarioListAttribute.html +23 -13
- data/doc/TaskJuggler/Scoreboard.html +92 -73
- data/doc/TaskJuggler/SheetHandlerBase.html +11 -1
- data/doc/TaskJuggler/SheetReceiver.html +11 -1
- data/doc/TaskJuggler/SheetSender.html +11 -1
- data/doc/TaskJuggler/Shift.html +11 -1
- data/doc/TaskJuggler/ShiftAssignment.html +11 -1
- data/doc/TaskJuggler/ShiftAssignments.html +11 -1
- data/doc/TaskJuggler/ShiftAssignmentsAttribute.html +24 -14
- data/doc/TaskJuggler/ShiftScenario.html +11 -1
- data/doc/TaskJuggler/SimpleQueryExpander.html +11 -1
- data/doc/TaskJuggler/SortListAttribute.html +21 -11
- data/doc/TaskJuggler/SourceFileInfo.html +11 -1
- data/doc/TaskJuggler/StatusSheetReceiver.html +11 -1
- data/doc/TaskJuggler/StatusSheetReport.html +11 -1
- data/doc/TaskJuggler/StatusSheetSender.html +112 -11
- data/doc/TaskJuggler/StringAttribute.html +23 -13
- data/doc/TaskJuggler/SymbolAttribute.html +19 -9
- data/doc/TaskJuggler/SyntaxReference.html +80 -71
- data/doc/TaskJuggler/TOCEntry.html +11 -1
- data/doc/TaskJuggler/TSResourceRecord.html +11 -1
- data/doc/TaskJuggler/TSTaskRecord.html +11 -1
- data/doc/TaskJuggler/TableColumnDefinition.html +11 -1
- data/doc/TaskJuggler/TableOfContents.html +11 -1
- data/doc/TaskJuggler/TableReport.html +422 -411
- data/doc/TaskJuggler/Task.html +11 -1
- data/doc/TaskJuggler/TaskDependency.html +11 -1
- data/doc/TaskJuggler/TaskListAttribute.html +33 -23
- data/doc/TaskJuggler/TaskListRE.html +11 -1
- data/doc/TaskJuggler/TaskScenario.html +2007 -1919
- data/doc/TaskJuggler/TextFormatter.html +11 -1
- data/doc/TaskJuggler/TextParser.html +421 -612
- data/doc/TaskJuggler/TextParser/Pattern.html +410 -211
- data/doc/TaskJuggler/TextParser/Rule.html +224 -152
- data/doc/TaskJuggler/TextParser/StackElement.html +190 -28
- data/doc/TaskJuggler/TextParser/State.html +989 -0
- data/doc/TaskJuggler/TextParser/StateTransition.html +782 -0
- data/doc/TaskJuggler/TextParser/TextParserResultArray.html +25 -14
- data/doc/TaskJuggler/TextParser/TokenDoc.html +11 -1
- data/doc/TaskJuggler/TextReport.html +11 -1
- data/doc/TaskJuggler/TextScanner.html +285 -273
- data/doc/TaskJuggler/TextScanner/BufferStreamHandle.html +17 -7
- data/doc/TaskJuggler/TextScanner/FileStreamHandle.html +24 -14
- data/doc/TaskJuggler/TextScanner/MacroStackEntry.html +11 -1
- data/doc/TaskJuggler/TextScanner/StreamHandle.html +64 -52
- data/doc/TaskJuggler/TimeSheet.html +11 -1
- data/doc/TaskJuggler/TimeSheetReceiver.html +11 -1
- data/doc/TaskJuggler/TimeSheetRecord.html +11 -1
- data/doc/TaskJuggler/TimeSheetReport.html +11 -1
- data/doc/TaskJuggler/TimeSheetSender.html +11 -1
- data/doc/TaskJuggler/TimeSheetSummary.html +11 -1
- data/doc/TaskJuggler/TimeSheets.html +11 -1
- data/doc/TaskJuggler/Tj3AppBase.html +11 -1
- data/doc/TaskJuggler/Tj3Client.html +11 -1
- data/doc/TaskJuggler/Tj3Daemon.html +11 -1
- data/doc/TaskJuggler/Tj3SheetAppBase.html +11 -1
- data/doc/TaskJuggler/Tj3SsReceiver.html +11 -1
- data/doc/TaskJuggler/Tj3SsSender.html +11 -1
- data/doc/TaskJuggler/Tj3TsReceiver.html +11 -1
- data/doc/TaskJuggler/Tj3TsSender.html +11 -1
- data/doc/TaskJuggler/Tj3TsSummary.html +11 -1
- data/doc/TaskJuggler/TjException.html +11 -1
- data/doc/TaskJuggler/TjTime.html +474 -324
- data/doc/TaskJuggler/TjpExample.html +11 -1
- data/doc/TaskJuggler/TjpExportRE.html +11 -1
- data/doc/TaskJuggler/TjpSyntaxRules.html +3731 -3662
- data/doc/TaskJuggler/URLParameter.html +11 -1
- data/doc/TaskJuggler/UserManual.html +11 -1
- data/doc/TaskJuggler/VimSyntax.html +11 -1
- data/doc/TaskJuggler/WebServer.html +11 -1
- data/doc/TaskJuggler/WorkingHours.html +295 -221
- data/doc/TaskJuggler/WorkingHoursAttribute.html +11 -1
- data/doc/TaskJuggler/XMLBlob.html +11 -1
- data/doc/TaskJuggler/XMLComment.html +11 -1
- data/doc/TaskJuggler/XMLDocument.html +11 -1
- data/doc/TaskJuggler/XMLElement.html +11 -1
- data/doc/TaskJuggler/XMLNamedText.html +11 -1
- data/doc/TaskJuggler/XMLText.html +11 -1
- data/doc/index.html +694 -624
- data/doc/lib/AppConfig_rb.html +1 -1
- data/doc/lib/Attributes_rb.html +1 -1
- data/doc/lib/Booking_rb.html +1 -1
- data/doc/lib/DataCache_rb.html +69 -0
- data/doc/lib/KeywordDocumentation_rb.html +1 -1
- data/doc/lib/ProjectFileParser_rb.html +1 -1
- data/doc/lib/ProjectFileScanner_rb.html +1 -1
- data/doc/lib/Project_rb.html +1 -1
- data/doc/lib/PropertyList_rb.html +1 -1
- data/doc/lib/Query_rb.html +1 -1
- data/doc/lib/RealFormat_rb.html +1 -1
- data/doc/lib/ResourceScenario_rb.html +1 -1
- data/doc/lib/Resource_rb.html +1 -1
- data/doc/lib/RichTextParser_rb.html +1 -1
- data/doc/lib/RichTextScanner_rb.html +1 -1
- data/doc/lib/RichTextSyntaxRules_rb.html +1 -1
- data/doc/lib/RichText_rb.html +1 -1
- data/doc/lib/Scoreboard_rb.html +1 -1
- data/doc/lib/StatusSheetSender_rb.html +1 -1
- data/doc/lib/SyntaxReference_rb.html +1 -1
- data/doc/lib/TaskJuggler_rb.html +1 -1
- data/doc/lib/TaskScenario_rb.html +3 -1
- data/doc/lib/TextParser/Pattern_rb.html +3 -1
- data/doc/lib/TextParser/Rule_rb.html +3 -1
- data/doc/lib/TextParser/StackElement_rb.html +3 -1
- data/doc/lib/TextParser/State_rb.html +65 -0
- data/doc/lib/TextParser_rb.html +1 -1
- data/doc/lib/TextScanner_rb.html +1 -1
- data/doc/lib/Tj3Config_rb.html +1 -1
- data/doc/lib/TjTime_rb.html +1 -1
- data/doc/lib/TjpSyntaxRules_rb.html +1 -1
- data/doc/lib/WorkingHours_rb.html +3 -1
- data/doc/lib/daemon/ReportServer_rb.html +1 -1
- data/doc/lib/reports/CSVFile_rb.html +1 -1
- data/doc/lib/reports/CollisionDetector_rb.html +67 -0
- data/doc/lib/reports/GanttChart_rb.html +1 -1
- data/doc/lib/reports/GanttRouter_rb.html +3 -1
- data/doc/lib/reports/Navigator_rb.html +1 -1
- data/doc/lib/reports/ReportBase_rb.html +1 -1
- data/doc/lib/reports/ReportTableCell_rb.html +1 -1
- data/doc/lib/reports/ReportTableColumn_rb.html +1 -1
- data/doc/lib/reports/ReportTableLine_rb.html +1 -1
- data/doc/lib/reports/ReportTable_rb.html +1 -1
- data/doc/lib/reports/Report_rb.html +1 -1
- data/doc/lib/reports/TableReport_rb.html +1 -1
- data/doc/lib/taskjuggler3_rb.html +1 -1
- data/examples/tutorial.tjp +1 -2
- data/lib/AppConfig.rb +10 -4
- data/lib/Attributes.rb +4 -4
- data/lib/DataCache.rb +124 -0
- data/lib/KeywordDocumentation.rb +5 -5
- data/lib/Project.rb +54 -10
- data/lib/ProjectFileParser.rb +10 -9
- data/lib/ProjectFileScanner.rb +38 -25
- data/lib/PropertyList.rb +6 -4
- data/lib/Query.rb +0 -8
- data/lib/RealFormat.rb +1 -1
- data/lib/Resource.rb +1 -1
- data/lib/ResourceScenario.rb +96 -31
- data/lib/RichText.rb +17 -5
- data/lib/RichTextParser.rb +22 -9
- data/lib/RichTextScanner.rb +34 -34
- data/lib/RichTextSyntaxRules.rb +41 -36
- data/lib/Scoreboard.rb +16 -7
- data/lib/StatusSheetSender.rb +63 -0
- data/lib/SyntaxReference.rb +9 -10
- data/lib/TaskJuggler.rb +28 -4
- data/lib/TaskScenario.rb +66 -19
- data/lib/TextParser.rb +219 -384
- data/lib/TextParser/Pattern.rb +168 -49
- data/lib/TextParser/Rule.rb +33 -17
- data/lib/TextParser/StackElement.rb +42 -2
- data/lib/TextParser/State.rb +175 -0
- data/lib/TextScanner.rb +19 -15
- data/lib/Tj3Config.rb +1 -1
- data/lib/TjTime.rb +111 -3
- data/lib/TjpSyntaxRules.rb +122 -66
- data/lib/WorkingHours.rb +91 -186
- data/lib/daemon/ReportServer.rb +3 -2
- data/lib/reports/CSVFile.rb +1 -1
- data/lib/reports/CollisionDetector.rb +177 -0
- data/lib/reports/GanttChart.rb +25 -41
- data/lib/reports/GanttRouter.rb +104 -233
- data/lib/reports/Navigator.rb +1 -1
- data/lib/reports/Report.rb +9 -33
- data/lib/reports/ReportBase.rb +0 -1
- data/lib/reports/ReportTable.rb +19 -8
- data/lib/reports/ReportTableCell.rb +61 -25
- data/lib/reports/ReportTableColumn.rb +2 -2
- data/lib/reports/ReportTableLine.rb +4 -2
- data/lib/reports/TableReport.rb +1 -0
- data/lib/taskjuggler3.rb +0 -1
- data/manual/Installation +7 -3
- data/manual/Intro +12 -10
- data/manual/The_TaskJuggler_Syntax +4 -4
- data/test/TestSuite/CSV-Reports/celltext-Reference.csv +14 -14
- data/test/TestSuite/CSV-Reports/genrefs +1 -1
- data/test/TestSuite/CSV-Reports/resourcereport-Reference.csv +4 -4
- data/test/TestSuite/CSV-Reports/resourcereport_with_tasks-Reference.csv +22 -22
- data/test/TestSuite/CSV-Reports/sortByTree-Reference.csv +14 -14
- data/test/TestSuite/CSV-Reports/sortBy_duration.down-Reference.csv +14 -14
- data/test/TestSuite/CSV-Reports/sortBy_effort.up-Reference.csv +14 -14
- data/test/TestSuite/CSV-Reports/sortBy_plan.start.down-Reference.csv +14 -14
- data/test/TestSuite/CSV-Reports/taskreport-Reference.csv +14 -14
- data/test/TestSuite/CSV-Reports/taskreport_with_resources-Reference.csv +32 -24
- data/test/TestSuite/CSV-Reports/weekly-Reference.csv +13 -0
- data/test/TestSuite/CSV-Reports/weekly.tjp +9 -0
- data/test/TestSuite/HTML-Reports/css/tjreport.css +7 -2
- data/test/TestSuite/HTML-Reports/depArrows.html +839 -830
- data/test/TestSuite/HTML-Reports/depArrows.tjp +12 -12
- data/test/TestSuite/HTML-Reports/profile.html +37581 -0
- data/test/TestSuite/ReportGenerator/Errors/no_report_defined.tjp +7 -0
- data/test/TestSuite/ReportGenerator/Errors/rtp_report_recursion.tjp +1 -1
- data/test/TestSuite/StatusSheets/TimeSheets/2002-03-01/missing-reports +2 -0
- data/test/TestSuite/StatusSheets/run +2 -0
- data/test/TestSuite/Syntax/Correct/Booking.tjp +13 -5
- data/test/TestSuite/Syntax/Correct/ResourceRoot.tjp +21 -0
- data/test/TestSuite/Syntax/Correct/RollupResource.tjp +21 -0
- data/test/TestSuite/Syntax/Correct/TaskRoot.tjp +1 -1
- data/test/TestSuite/Syntax/Errors/empty.tjp +1 -1
- data/test/TestSuite/Syntax/Errors/include_before_project.tjp +2 -0
- data/test/TestSuite/Syntax/Errors/no_reduce.tjp +6 -0
- data/test/TestSuite/Syntax/Errors/unsupported_token.tjp +1 -1
- data/test/TestSuite/TimeSheets/run +1 -1
- data/test/test_CSV-Reports.rb +2 -4
- data/test/test_CollisionDetector.rb +85 -0
- data/test/test_Project.rb +2 -2
- data/test/test_ProjectFileScanner.rb +73 -31
- data/test/test_Query.rb +2 -2
- data/test/test_ReportGenerator.rb +1 -1
- data/test/test_RichText.rb +4 -4
- data/test/test_WorkingHours.rb +150 -11
- metadata +75 -67
- data/test/TestSuite/ReportGenerator/Errors/css/tjreport.css +0 -407
- data/test/TestSuite/ReportGenerator/Errors/rtp_report_recursion.html +0 -26
- data/test/TestSuite/Scheduler/Correct/Allocate.html +0 -3210
- data/test/TestSuite/Scheduler/Correct/Container.html +0 -349
- data/test/TestSuite/Scheduler/Correct/Limits.html +0 -4964
- data/test/TestSuite/Scheduler/Correct/Shift.html +0 -1719
- data/test/TestSuite/Scheduler/Correct/Shift2.html +0 -476
- data/test/TestSuite/Scheduler/Correct/css/tjmanual.css +0 -66
- data/test/TestSuite/Scheduler/Correct/icons/details.png +0 -0
- data/test/TestSuite/Scheduler/Correct/icons/flag-green.png +0 -0
- data/test/TestSuite/Scheduler/Correct/icons/flag-red.png +0 -0
- data/test/TestSuite/Scheduler/Correct/icons/flag-yellow.png +0 -0
- data/test/TestSuite/Scheduler/Correct/icons/resource.png +0 -0
- data/test/TestSuite/Scheduler/Correct/icons/resourcegroup.png +0 -0
- data/test/TestSuite/Scheduler/Correct/icons/task.png +0 -0
- data/test/TestSuite/Scheduler/Correct/icons/taskgroup.png +0 -0
- data/test/TestSuite/Scheduler/Correct/icons/trend-down.png +0 -0
- data/test/TestSuite/Scheduler/Correct/icons/trend-flat.png +0 -0
- data/test/TestSuite/Scheduler/Correct/icons/trend-up.png +0 -0
- data/test/TestSuite/Scheduler/Correct/scripts/wz_tooltip.js +0 -1301
- data/test/TestSuite/Scheduler/Errors/css/tjmanual.css +0 -66
- data/test/TestSuite/Scheduler/Errors/css/tjreport.css +0 -407
- data/test/TestSuite/Scheduler/Errors/icons/details.png +0 -0
- data/test/TestSuite/Scheduler/Errors/icons/flag-green.png +0 -0
- data/test/TestSuite/Scheduler/Errors/icons/flag-red.png +0 -0
- data/test/TestSuite/Scheduler/Errors/icons/flag-yellow.png +0 -0
- data/test/TestSuite/Scheduler/Errors/icons/resource.png +0 -0
- data/test/TestSuite/Scheduler/Errors/icons/resourcegroup.png +0 -0
- data/test/TestSuite/Scheduler/Errors/icons/task.png +0 -0
- data/test/TestSuite/Scheduler/Errors/icons/taskgroup.png +0 -0
- data/test/TestSuite/Scheduler/Errors/icons/trend-down.png +0 -0
- data/test/TestSuite/Scheduler/Errors/icons/trend-flat.png +0 -0
- data/test/TestSuite/Scheduler/Errors/icons/trend-up.png +0 -0
- data/test/TestSuite/Scheduler/Errors/scripts/wz_tooltip.js +0 -1301
- data/test/TestSuite/StatusSheets/resrep.tji +0 -7
- data/test/TestSuite/StatusSheets/tj3d.log +0 -312
- data/test/TestSuite/Syntax/Correct/Managers.html +0 -263
- data/test/TestSuite/TimeSheets/acceptable_intervals +0 -1
- data/test/TestSuite/TimeSheets/statussheets.log +0 -1
data/lib/Project.rb
CHANGED
|
@@ -78,7 +78,7 @@ class TaskJuggler
|
|
|
78
78
|
'flags' => [],
|
|
79
79
|
'journal' => Journal.new,
|
|
80
80
|
'limits' => nil,
|
|
81
|
-
'loadUnit' => :
|
|
81
|
+
'loadUnit' => :days,
|
|
82
82
|
'name' => name,
|
|
83
83
|
'navigators' => {},
|
|
84
84
|
'now' => TjTime.now.align(3600),
|
|
@@ -97,7 +97,7 @@ class TaskJuggler
|
|
|
97
97
|
'vacations' => [],
|
|
98
98
|
'version' => version || "1.0",
|
|
99
99
|
'weekStartsMonday' => true,
|
|
100
|
-
'workinghours' =>
|
|
100
|
+
'workinghours' => nil,
|
|
101
101
|
'yearlyworkingdays' => 260.714
|
|
102
102
|
}
|
|
103
103
|
|
|
@@ -430,6 +430,23 @@ class TaskJuggler
|
|
|
430
430
|
raise "Unknown project attribute #{name}"
|
|
431
431
|
end
|
|
432
432
|
@attributes[name] = value
|
|
433
|
+
|
|
434
|
+
# If the start, end or schedule granularity have been changed, we have
|
|
435
|
+
# to reset the working hours.
|
|
436
|
+
if %w(start end scheduleGranularity timezone timingresolution).
|
|
437
|
+
include?(name)
|
|
438
|
+
if @attributes['start'] && @attributes['end']
|
|
439
|
+
@attributes['workinghours'] =
|
|
440
|
+
WorkingHours.new(@attributes['scheduleGranularity'],
|
|
441
|
+
@attributes['start'], @attributes['end'])
|
|
442
|
+
# WorkingHours is using a copy-on-write scheme to prevent multiple
|
|
443
|
+
# copies of the same Scoreboard. All other WorkingHours objects are
|
|
444
|
+
# created as copies of this object. By calling
|
|
445
|
+
# WorkingHours::onShift? we make sure this instance has got a
|
|
446
|
+
# Scoreboard than gets reused by the other instances.
|
|
447
|
+
@attributes['workinghours'].onShift?(@attributes['start'])
|
|
448
|
+
end
|
|
449
|
+
end
|
|
433
450
|
end
|
|
434
451
|
|
|
435
452
|
# Return the number of defined scenarios for the project.
|
|
@@ -440,7 +457,7 @@ class TaskJuggler
|
|
|
440
457
|
# Try to match _levelName_ to a defined alert level name and return the
|
|
441
458
|
# index of it. If no level is found, nil is returned.
|
|
442
459
|
def alertLevelIndex(levelName)
|
|
443
|
-
|
|
460
|
+
@attributes['alertLevels'].length.times do |i|
|
|
444
461
|
if @attributes['alertLevels'][i][0] == levelName
|
|
445
462
|
return i
|
|
446
463
|
end
|
|
@@ -602,6 +619,24 @@ class TaskJuggler
|
|
|
602
619
|
true
|
|
603
620
|
end
|
|
604
621
|
|
|
622
|
+
# Make sure that we have a least one report defined that has an output
|
|
623
|
+
# format.
|
|
624
|
+
def checkReports
|
|
625
|
+
if @reports.empty?
|
|
626
|
+
@messageHandler.warning('no_report_defined',
|
|
627
|
+
"This project has no reports defined. " +
|
|
628
|
+
"No output data will be generated.")
|
|
629
|
+
end
|
|
630
|
+
|
|
631
|
+
@reports.each do |report|
|
|
632
|
+
return unless report.get('formats').empty?
|
|
633
|
+
end
|
|
634
|
+
|
|
635
|
+
@messageHandler.warning('all_formats_empty',
|
|
636
|
+
"None of the reports has a 'formats' attribute. " +
|
|
637
|
+
"No output data will be generated.")
|
|
638
|
+
end
|
|
639
|
+
|
|
605
640
|
# Call this function to generate the reports based on the scheduling result.
|
|
606
641
|
# This function may only be called after Project#schedule has been called.
|
|
607
642
|
def generateReports(maxCpuCores)
|
|
@@ -652,6 +687,12 @@ class TaskJuggler
|
|
|
652
687
|
error('unknown_report_id',
|
|
653
688
|
"Request to generate unknown report #{id}")
|
|
654
689
|
end
|
|
690
|
+
if report.get('formats').empty?
|
|
691
|
+
@messageHandler.error('formats_empty',
|
|
692
|
+
"The report #{report.fullId} has no 'formats' attribute. " +
|
|
693
|
+
"No output data will be generated.")
|
|
694
|
+
end
|
|
695
|
+
|
|
655
696
|
Log.startProgressMeter("Report #{report.name}")
|
|
656
697
|
@reportContexts.push(context = ReportContext.new(self, report))
|
|
657
698
|
|
|
@@ -834,7 +875,7 @@ class TaskJuggler
|
|
|
834
875
|
|
|
835
876
|
# Print the attribute values. It's used for debugging only.
|
|
836
877
|
def to_s
|
|
837
|
-
raise "STOP!"
|
|
878
|
+
#raise "STOP!"
|
|
838
879
|
str = ''
|
|
839
880
|
@attributes.each do |attribute, value|
|
|
840
881
|
if value
|
|
@@ -921,19 +962,22 @@ class TaskJuggler
|
|
|
921
962
|
|
|
922
963
|
def finishScenario(scIdx)
|
|
923
964
|
Log.startProgressMeter("Checking scenario #{scenario(scIdx).get('name')}")
|
|
924
|
-
total = @tasks.items
|
|
925
|
-
i = 0
|
|
926
965
|
@tasks.each do |task|
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
966
|
+
# Recursively traverse the top-level tasks to finish all tasks.
|
|
967
|
+
task.finishScheduling(scIdx) unless task.parent
|
|
968
|
+
end
|
|
969
|
+
|
|
970
|
+
@resources.each do |resource|
|
|
971
|
+
# Recursively traverse the top-level resources to finish them all.
|
|
972
|
+
resource.finishScheduling(scIdx) unless resource.parent
|
|
930
973
|
end
|
|
931
974
|
|
|
932
975
|
i = 0
|
|
976
|
+
total = @tasks.items
|
|
933
977
|
@tasks.each do |task|
|
|
934
978
|
task.postScheduleCheck(scIdx) if task.parent.nil?
|
|
935
979
|
i += 1
|
|
936
|
-
Log.progress(
|
|
980
|
+
Log.progress(i.to_f / total)
|
|
937
981
|
end
|
|
938
982
|
|
|
939
983
|
# This should be really fast so we don't log progess.
|
data/lib/ProjectFileParser.rb
CHANGED
|
@@ -39,10 +39,11 @@ class TaskJuggler
|
|
|
39
39
|
|
|
40
40
|
# Define the token types that the ProjectFileScanner may return for
|
|
41
41
|
# variable elements.
|
|
42
|
-
@variables =
|
|
43
|
-
|
|
42
|
+
@variables = [ :INTEGER, :FLOAT, :DATE, :TIME, :STRING, :LITERAL,
|
|
43
|
+
:ID, :ID_WITH_COLON, :ABSOLUTE_ID, :MACRO ]
|
|
44
44
|
|
|
45
45
|
initRules
|
|
46
|
+
updateParserTables
|
|
46
47
|
|
|
47
48
|
@project = nil
|
|
48
49
|
end
|
|
@@ -196,7 +197,7 @@ class TaskJuggler
|
|
|
196
197
|
# Add the new user-defined attribute as reportable attribute to the parser
|
|
197
198
|
# rule.
|
|
198
199
|
oldCurrentRule = @cr
|
|
199
|
-
@cr = @rules[
|
|
200
|
+
@cr = @rules[:reportableAttributes]
|
|
200
201
|
singlePattern('_' + @val[1])
|
|
201
202
|
descr(@val[2])
|
|
202
203
|
@cr = oldCurrentRule
|
|
@@ -209,11 +210,10 @@ class TaskJuggler
|
|
|
209
210
|
# data into a MessageHandler message that points to the correct location.
|
|
210
211
|
# This is necessary, because the RichText parser knows nothing about the
|
|
211
212
|
# actual input file. So we have to map the error location in the RichText
|
|
212
|
-
# input stream back to the position in the project file.
|
|
213
|
-
# To limit the supported set of
|
|
214
|
-
# by _tokenSet_.
|
|
215
|
-
def newRichText(text, tokenSet = nil)
|
|
216
|
-
sfi = sourceFileInfo
|
|
213
|
+
# input stream back to the position in the project file. _sfi_ is the
|
|
214
|
+
# SourceFileInfo of the input string. To limit the supported set of
|
|
215
|
+
# variable tokens, a subset can be provided by _tokenSet_.
|
|
216
|
+
def newRichText(text, sfi, tokenSet = nil)
|
|
217
217
|
rText = RichText.new(text, RTFHandlers.create(@project, sfi))
|
|
218
218
|
unless (rti = rText.generateIntermediateFormat( [ 0, 0, 0], tokenSet))
|
|
219
219
|
rText.messageHandler.messages.each do |msg|
|
|
@@ -357,7 +357,8 @@ class TaskJuggler
|
|
|
357
357
|
# token.
|
|
358
358
|
def descr(text)
|
|
359
359
|
if @cr.patterns[-1].length != 1 ||
|
|
360
|
-
(@cr.patterns[-1][0][0] !=
|
|
360
|
+
(@cr.patterns[-1][0][0] != :literal &&
|
|
361
|
+
@cr.patterns[-1][0][0] != :variable)
|
|
361
362
|
raise 'descr() may only be used for patterns with terminal tokens.'
|
|
362
363
|
end
|
|
363
364
|
arg(0, nil, text)
|
data/lib/ProjectFileScanner.rb
CHANGED
|
@@ -71,25 +71,25 @@ class TaskJuggler
|
|
|
71
71
|
[ nil, /.*\n/, :macroCall, method('midMacroCall') ],
|
|
72
72
|
|
|
73
73
|
# An ID with a colon suffix: foo:
|
|
74
|
-
[
|
|
74
|
+
[ :ID_WITH_COLON, /[a-zA-Z_]\w*:/, :tjp, method('chop') ],
|
|
75
75
|
|
|
76
76
|
# An absolute ID: a.b.c
|
|
77
|
-
[
|
|
77
|
+
[ :ABSOLUTE_ID, /[a-zA-Z_]\w*(\.[a-zA-Z_]\w*)+/ ],
|
|
78
78
|
|
|
79
79
|
# A normal ID: bar
|
|
80
|
-
[
|
|
80
|
+
[ :ID, /[a-zA-Z_]\w*/ ],
|
|
81
81
|
|
|
82
82
|
# A date
|
|
83
|
-
[
|
|
83
|
+
[ :DATE, /\d{4}-\d{1,2}-\d{1,2}(-\d{1,2}:\d{1,2}(:\d{1,2})?(-[-+]?\d{4})?)?/, :tjp, method('to_date') ],
|
|
84
84
|
|
|
85
85
|
# A time of day
|
|
86
|
-
[
|
|
86
|
+
[ :TIME, /\d{1,2}:\d{2}/, :tjp, method('to_time') ],
|
|
87
87
|
|
|
88
88
|
# A floating point number (e. g. 3.143)
|
|
89
|
-
[
|
|
89
|
+
[ :FLOAT, /\d*\.\d+/, :tjp, method('to_f') ],
|
|
90
90
|
|
|
91
91
|
# An integer number
|
|
92
|
-
[
|
|
92
|
+
[ :INTEGER, /\d+/, :tjp, method('to_i') ],
|
|
93
93
|
|
|
94
94
|
# Multi line string enclosed with double quotes. The string may
|
|
95
95
|
# contain double quotes prefixed by a backslash. The first rule
|
|
@@ -98,14 +98,14 @@ class TaskJuggler
|
|
|
98
98
|
# Any line not containing the start or end.
|
|
99
99
|
[ 'nil', /^(\\"|[^"])*\n/, :dqString, method('midStringDQ') ],
|
|
100
100
|
# The end of the string.
|
|
101
|
-
[
|
|
101
|
+
[ :STRING, /(\\"|[^"])*"/, :dqString, method('endStringDQ') ],
|
|
102
102
|
|
|
103
103
|
# Multi line string enclosed with single quotes.
|
|
104
104
|
[ 'nil', /'(\\'|[^'])*/, :tjp, method('startStringSQ') ],
|
|
105
105
|
# Any line not containing the start or end.
|
|
106
106
|
[ 'nil', /^(\\'|[^'])*\n/, :sqString, method('midStringSQ') ],
|
|
107
107
|
# The end of the string.
|
|
108
|
-
[
|
|
108
|
+
[ :STRING, /(\\'|[^'])*'/, :sqString, method('endStringSQ') ],
|
|
109
109
|
|
|
110
110
|
# Scizzors marked string -8<- ... ->8-: The opening mark must be the
|
|
111
111
|
# last thing in the line. The indentation of the first line after the
|
|
@@ -115,8 +115,8 @@ class TaskJuggler
|
|
|
115
115
|
# Since the first line can be the last line (empty string case), we
|
|
116
116
|
# need to detect the end in szrString1 and szrString mode. The
|
|
117
117
|
# patterns switch the scanner back to tjp mode.
|
|
118
|
-
[
|
|
119
|
-
[
|
|
118
|
+
[ :STRING, /\s*->8-/, :szrString1, method('endStringSZR') ],
|
|
119
|
+
[ :STRING, /\s*->8-/, :szrString, method('endStringSZR') ],
|
|
120
120
|
# This rule handles macros inside of sizzors strings.
|
|
121
121
|
[ nil, /.*?\$\{\s*([a-zA-Z_]\w*)(\s*"(\\"|[^"])*")*/,
|
|
122
122
|
[ :szrString, :szrString1 ], method('startMacroCall') ],
|
|
@@ -125,24 +125,24 @@ class TaskJuggler
|
|
|
125
125
|
[ 'nil', /.*\n/, :szrString, method('midStringSZR') ],
|
|
126
126
|
|
|
127
127
|
# Single line macro definition
|
|
128
|
-
[
|
|
128
|
+
[ :MACRO, /\[.*\]\n/, :tjp, method('chop2nl') ],
|
|
129
129
|
|
|
130
130
|
# Multi line macro definition: The pattern switches the scanner into
|
|
131
131
|
# macroDef mode.
|
|
132
132
|
[ nil, /\[.*\n/, :tjp, method('startMacroDef') ],
|
|
133
133
|
# The end of the macro is marked by a ']' that is immediately followed
|
|
134
134
|
# by a line break. It switches the scanner back to tjp mode.
|
|
135
|
-
[
|
|
135
|
+
[ :MACRO, /.*\]\n/, :macroDef, method('endMacroDef') ],
|
|
136
136
|
# Any line not containing the start or end.
|
|
137
137
|
[ nil, /.*\n/, :macroDef, method('midMacroDef') ],
|
|
138
138
|
|
|
139
139
|
# Some multi-char literals.
|
|
140
|
-
[
|
|
141
|
-
[
|
|
142
|
-
[
|
|
140
|
+
[ :LITERAL, /<=?/ ],
|
|
141
|
+
[ :LITERAL, />=?/ ],
|
|
142
|
+
[ :LITERAL, /!=?/ ],
|
|
143
143
|
|
|
144
144
|
# Everything else is returned as a single-char literal.
|
|
145
|
-
[
|
|
145
|
+
[ :LITERAL, /./ ]
|
|
146
146
|
]
|
|
147
147
|
|
|
148
148
|
super(masterFile, messageHandler, tokenPatterns, :tjp)
|
|
@@ -159,15 +159,28 @@ class TaskJuggler
|
|
|
159
159
|
end
|
|
160
160
|
|
|
161
161
|
def to_time(type, match)
|
|
162
|
-
h, m
|
|
162
|
+
h, m = match.split(':')
|
|
163
163
|
h = h.to_i
|
|
164
|
+
if h < 0 || h > 24
|
|
165
|
+
error('time_bad_hour', "Hour #{h} out of range (0 - 24)")
|
|
166
|
+
end
|
|
164
167
|
m = m.to_i
|
|
165
|
-
|
|
166
|
-
|
|
168
|
+
if m < 0 || h > 59
|
|
169
|
+
error('time_bad_minute', "Minute #{m} out of range (0 - 59)")
|
|
170
|
+
end
|
|
171
|
+
if h == 24 && m != 0
|
|
172
|
+
error('time_bad_time', "Time #{match} cannot be larger then 24:00")
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
[ type, (h * 60 + m) * 60 ]
|
|
167
176
|
end
|
|
168
177
|
|
|
169
178
|
def to_date(type, match)
|
|
170
|
-
|
|
179
|
+
begin
|
|
180
|
+
[ type, TjTime.new(match) ]
|
|
181
|
+
rescue TjException => msg
|
|
182
|
+
error('time_error', msg)
|
|
183
|
+
end
|
|
171
184
|
end
|
|
172
185
|
|
|
173
186
|
def newPos(type, match)
|
|
@@ -216,7 +229,7 @@ class TaskJuggler
|
|
|
216
229
|
self.mode = :tjp
|
|
217
230
|
# Remove the trailing " and remove the backslashes from escaped ".
|
|
218
231
|
@string += match[0..-2].gsub(/\\"/, '"')
|
|
219
|
-
[
|
|
232
|
+
[ :STRING, @string ]
|
|
220
233
|
end
|
|
221
234
|
|
|
222
235
|
def startStringSQ(type, match)
|
|
@@ -236,7 +249,7 @@ class TaskJuggler
|
|
|
236
249
|
self.mode = :tjp
|
|
237
250
|
# Remove the trailing ' and remove the backslashes from escaped '.
|
|
238
251
|
@string += match[0..-2].gsub(/\\'/, "'")
|
|
239
|
-
[
|
|
252
|
+
[ :STRING, @string ]
|
|
240
253
|
end
|
|
241
254
|
|
|
242
255
|
def startStringSZR(type, match)
|
|
@@ -274,7 +287,7 @@ class TaskJuggler
|
|
|
274
287
|
|
|
275
288
|
def endStringSZR(type, match)
|
|
276
289
|
self.mode = :tjp
|
|
277
|
-
[
|
|
290
|
+
[ :STRING, @string ]
|
|
278
291
|
end
|
|
279
292
|
|
|
280
293
|
def startMacroDef(type, match)
|
|
@@ -293,7 +306,7 @@ class TaskJuggler
|
|
|
293
306
|
self.mode = :tjp
|
|
294
307
|
# Remove "]\n"
|
|
295
308
|
@macroDef += match[0..-3]
|
|
296
|
-
[
|
|
309
|
+
[ :MACRO, @macroDef ]
|
|
297
310
|
end
|
|
298
311
|
|
|
299
312
|
def startMacroCall(type, match)
|
data/lib/PropertyList.rb
CHANGED
|
@@ -168,19 +168,21 @@ class TaskJuggler
|
|
|
168
168
|
def addSortingCriteria(criteria, up, scIdx)
|
|
169
169
|
unless @propertySet.knownAttribute?(criteria) ||
|
|
170
170
|
@propertySet.hasQuery?(criteria, scIdx)
|
|
171
|
-
raise
|
|
171
|
+
raise TjException.new,
|
|
172
|
+
"Unknown attribute #{criteria} used for sorting criterium"
|
|
172
173
|
end
|
|
173
174
|
if scIdx == -1
|
|
174
175
|
if @propertySet.scenarioSpecific?(criteria)
|
|
175
|
-
raise
|
|
176
|
+
raise TjException.new,
|
|
177
|
+
"Attribute #{criteria} is scenario specific." +
|
|
176
178
|
"You must specify a scenario id."
|
|
177
179
|
end
|
|
178
180
|
else
|
|
179
181
|
if @propertySet.project.scenario(scIdx).nil?
|
|
180
|
-
raise "Unknown scenario index #{scIdx} used."
|
|
182
|
+
raise TjException.new, "Unknown scenario index #{scIdx} used."
|
|
181
183
|
end
|
|
182
184
|
if !@propertySet.scenarioSpecific?(criteria)
|
|
183
|
-
raise "Attribute #{criteria} is not scenario specific"
|
|
185
|
+
raise TjException.new, "Attribute #{criteria} is not scenario specific"
|
|
184
186
|
end
|
|
185
187
|
end
|
|
186
188
|
@sortingCriteria.push(criteria)
|
data/lib/Query.rb
CHANGED
|
@@ -70,8 +70,6 @@ class TaskJuggler
|
|
|
70
70
|
if date.is_a?(TjTime)
|
|
71
71
|
@start = date
|
|
72
72
|
@startIdx = @project.dateToIdx(date, true)
|
|
73
|
-
#elsif date.is_a?(Fixnum)
|
|
74
|
-
# self.startIdx=(date)
|
|
75
73
|
else
|
|
76
74
|
raise "Unsupported type #{date.class}"
|
|
77
75
|
end
|
|
@@ -81,8 +79,6 @@ class TaskJuggler
|
|
|
81
79
|
if idx.is_a?(Fixnum)
|
|
82
80
|
@startIdx = idx
|
|
83
81
|
@start = @project.idxToDate(idx)
|
|
84
|
-
#elsif idx.is_a?(TjTime)
|
|
85
|
-
# self.start=(idx)
|
|
86
82
|
else
|
|
87
83
|
raise "Unsupported type #{idx.class}"
|
|
88
84
|
end
|
|
@@ -92,8 +88,6 @@ class TaskJuggler
|
|
|
92
88
|
if date.is_a?(TjTime)
|
|
93
89
|
@end = date
|
|
94
90
|
@endIdx = @project.dateToIdx(date, true)
|
|
95
|
-
#elsif date.is_a?(Fixnum)
|
|
96
|
-
# self.endIdx=(date)
|
|
97
91
|
else
|
|
98
92
|
raise "Unsupported type #{date.class}"
|
|
99
93
|
end
|
|
@@ -103,8 +97,6 @@ class TaskJuggler
|
|
|
103
97
|
if idx.is_a?(Fixnum)
|
|
104
98
|
@endIdx = idx
|
|
105
99
|
@end = @project.idxToDate(idx)
|
|
106
|
-
#elsif idx.is_a?(TjTime)
|
|
107
|
-
# self.end=(idx)
|
|
108
100
|
else
|
|
109
101
|
raise "Unsupported type #{idx.class}"
|
|
110
102
|
end
|
data/lib/RealFormat.rb
CHANGED
data/lib/Resource.rb
CHANGED
|
@@ -56,7 +56,7 @@ class TaskJuggler
|
|
|
56
56
|
# Sort all entries in buckets by their alert level.
|
|
57
57
|
numberOfLevels = project['alertLevels'].length
|
|
58
58
|
listByLevel = []
|
|
59
|
-
|
|
59
|
+
numberOfLevels.times { |i| listByLevel[i] = [] }
|
|
60
60
|
list.each do |entry|
|
|
61
61
|
listByLevel[entry.alertLevel] << entry
|
|
62
62
|
end
|
data/lib/ResourceScenario.rb
CHANGED
|
@@ -37,15 +37,23 @@ class TaskJuggler
|
|
|
37
37
|
# subset.
|
|
38
38
|
@scoreboard = nil
|
|
39
39
|
|
|
40
|
+
# The index of the earliest booked time slot.
|
|
40
41
|
@firstBookedSlot = nil
|
|
42
|
+
# Same but for each assigned resource.
|
|
43
|
+
@firstBookedSlots = {}
|
|
44
|
+
# The index of the last booked time Slot.
|
|
41
45
|
@lastBookedSlot = nil
|
|
46
|
+
# Same but for each assigned resource.
|
|
47
|
+
@lastBookedSlots = {}
|
|
48
|
+
|
|
49
|
+
@dCache = DataCache.instance
|
|
42
50
|
end
|
|
43
51
|
|
|
44
52
|
# This method must be called at the beginning of each scheduling run. It
|
|
45
53
|
# initializes variables used during the scheduling process.
|
|
46
54
|
def prepareScheduling
|
|
47
55
|
@property['effort', @scenarioIdx] = 0
|
|
48
|
-
initScoreboard
|
|
56
|
+
initScoreboard if @property.leaf?
|
|
49
57
|
|
|
50
58
|
setDirectReports
|
|
51
59
|
end
|
|
@@ -91,7 +99,6 @@ class TaskJuggler
|
|
|
91
99
|
end
|
|
92
100
|
end
|
|
93
101
|
|
|
94
|
-
|
|
95
102
|
def preScheduleCheck
|
|
96
103
|
a('managers').each do |manager|
|
|
97
104
|
unless manager.leaf?
|
|
@@ -106,6 +113,25 @@ class TaskJuggler
|
|
|
106
113
|
end
|
|
107
114
|
end
|
|
108
115
|
|
|
116
|
+
# This method does some housekeeping work after the scheduling is
|
|
117
|
+
# completed. It's meant to be called for top-level resources and then
|
|
118
|
+
# recursively descends into all child resources.
|
|
119
|
+
def finishScheduling
|
|
120
|
+
# Recursively descend into all child resources.
|
|
121
|
+
@property.children.each do |resource|
|
|
122
|
+
resource.finishScheduling(@scenarioIdx)
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
if (parent = @property.parent)
|
|
126
|
+
# Add the assigned task to the parent duties list.
|
|
127
|
+
a('duties').each do |task|
|
|
128
|
+
unless parent['duties', @scenarioIdx].include?(task)
|
|
129
|
+
parent['duties', @scenarioIdx] << task
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
|
|
109
135
|
def postScheduleCheck
|
|
110
136
|
if a('fail') || a('warn')
|
|
111
137
|
queryAttrs = { 'project' => @project,
|
|
@@ -158,6 +184,11 @@ class TaskJuggler
|
|
|
158
184
|
def book(sbIdx, task, force = false)
|
|
159
185
|
return false if !force && !available?(sbIdx)
|
|
160
186
|
|
|
187
|
+
# Make sure the task is in the list of duties.
|
|
188
|
+
unless a('duties').include?(task)
|
|
189
|
+
@property['duties', @scenarioIdx] << task
|
|
190
|
+
end
|
|
191
|
+
|
|
161
192
|
#puts "Booking resource #{@property.fullId} at " +
|
|
162
193
|
# "#{@scoreboard.idxToDate(sbIdx)}/#{sbIdx} for task #{task.fullId}\n"
|
|
163
194
|
@scoreboard[sbIdx] = task
|
|
@@ -170,17 +201,24 @@ class TaskJuggler
|
|
|
170
201
|
end
|
|
171
202
|
a('limits').inc(@scoreboard.idxToDate(sbIdx)) if a('limits')
|
|
172
203
|
|
|
173
|
-
#
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
204
|
+
# Scoreboard iterations are fairly expensive but they are very frequent
|
|
205
|
+
# operations in later processing. To limit the interations to the
|
|
206
|
+
# relevant intervals, we store the interval for all bookings and for
|
|
207
|
+
# each individual task.
|
|
178
208
|
if @firstBookedSlot.nil? || @firstBookedSlot > sbIdx
|
|
179
209
|
@firstBookedSlot = sbIdx
|
|
180
210
|
end
|
|
181
211
|
if @lastBookedSlot.nil? || @lastBookedSlot < sbIdx
|
|
182
212
|
@lastBookedSlot = sbIdx
|
|
183
213
|
end
|
|
214
|
+
if task
|
|
215
|
+
if @firstBookedSlots[task].nil? || @firstBookedSlots[task] > sbIdx
|
|
216
|
+
@firstBookedSlots[task] = sbIdx
|
|
217
|
+
end
|
|
218
|
+
if @lastBookedSlots[task].nil? || @lastBookedSlots[task] < sbIdx
|
|
219
|
+
@lastBookedSlots[task] = sbIdx
|
|
220
|
+
end
|
|
221
|
+
end
|
|
184
222
|
true
|
|
185
223
|
end
|
|
186
224
|
|
|
@@ -291,6 +329,16 @@ class TaskJuggler
|
|
|
291
329
|
# Returns the work of the resource (and its children) weighted by their
|
|
292
330
|
# efficiency.
|
|
293
331
|
def getEffectiveWork(startIdx, endIdx, task = nil)
|
|
332
|
+
# There can't be any effective work if the start is after the end or the
|
|
333
|
+
# todo list doesn't contain the specified task.
|
|
334
|
+
return 0.0 if startIdx >= endIdx || (task && !a('duties').include?(task))
|
|
335
|
+
|
|
336
|
+
# The unique key we use to address the result in the cache.
|
|
337
|
+
key = [ self, :ResourceScenarioEffectiveWork, startIdx, endIdx,
|
|
338
|
+
task ].hash
|
|
339
|
+
work = @dCache.load(key)
|
|
340
|
+
return work if work
|
|
341
|
+
|
|
294
342
|
# Convert the interval dates to indexes if needed.
|
|
295
343
|
startIdx = @project.dateToIdx(startIdx, true) if startIdx.is_a?(TjTime)
|
|
296
344
|
endIdx = @project.dateToIdx(endIdx, true) if endIdx.is_a?(TjTime)
|
|
@@ -307,7 +355,7 @@ class TaskJuggler
|
|
|
307
355
|
getAllocatedSlots(startIdx, endIdx, task) *
|
|
308
356
|
@project['scheduleGranularity']) * a('efficiency')
|
|
309
357
|
end
|
|
310
|
-
work
|
|
358
|
+
@dCache.store(work, key)
|
|
311
359
|
end
|
|
312
360
|
|
|
313
361
|
# Returns the allocated accumulated time of this resource and its children.
|
|
@@ -419,16 +467,13 @@ class TaskJuggler
|
|
|
419
467
|
# the period specified with the Interval _iv_. If task is not nil
|
|
420
468
|
# only allocations to this tasks are respected.
|
|
421
469
|
def allocated?(iv, task = nil)
|
|
422
|
-
|
|
470
|
+
return false if task && !a('duties').include?(task)
|
|
423
471
|
|
|
424
|
-
startIdx = @
|
|
425
|
-
endIdx = @
|
|
472
|
+
startIdx = @project.dateToIdx(iv.start, true)
|
|
473
|
+
endIdx = @project.dateToIdx(iv.end, true)
|
|
426
474
|
|
|
427
|
-
startIdx =
|
|
428
|
-
|
|
429
|
-
endIdx = @lastBookedSlot + 1 if @lastBookedSlot &&
|
|
430
|
-
endIdx < @lastBookedSlot + 1
|
|
431
|
-
return false if startIdx > endIdx
|
|
475
|
+
startIdx, endIdx = fitIndicies(startIdx, endIdx, task)
|
|
476
|
+
return false if startIdx >= endIdx
|
|
432
477
|
|
|
433
478
|
return allocatedSub(startIdx, endIdx, task)
|
|
434
479
|
end
|
|
@@ -461,8 +506,6 @@ class TaskJuggler
|
|
|
461
506
|
bookings[lastTask] = Booking.new(@property, lastTask, [])
|
|
462
507
|
end
|
|
463
508
|
|
|
464
|
-
# Make sure the index is correct even for the last task block.
|
|
465
|
-
idx += 1 if idx == endIdx
|
|
466
509
|
# Append the new interval to the Booking.
|
|
467
510
|
bookings[lastTask].intervals <<
|
|
468
511
|
Interval.new(@scoreboard.idxToDate(bookingStart),
|
|
@@ -494,18 +537,15 @@ class TaskJuggler
|
|
|
494
537
|
# Count the booked slots between the start and end index. If _task_ is not
|
|
495
538
|
# nil count only those slots that are assigned to this particular task.
|
|
496
539
|
def getAllocatedSlots(startIdx, endIdx, task)
|
|
497
|
-
#
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
endIdx > @lastBookedSlot + 1
|
|
540
|
+
# If there is no scoreboard, we don't have any allocations.
|
|
541
|
+
return 0 unless @scoreboard
|
|
542
|
+
|
|
543
|
+
startIdx, endIdx = fitIndicies(startIdx, endIdx, task)
|
|
544
|
+
return 0 if startIdx >= endIdx
|
|
503
545
|
|
|
504
|
-
initScoreboard if @scoreboard.nil?
|
|
505
546
|
bookedSlots = 0
|
|
506
|
-
|
|
507
|
-
if (task.nil? &&
|
|
508
|
-
(task && @scoreboard[idx] == task)
|
|
547
|
+
@scoreboard.each(startIdx, endIdx) do |slot|
|
|
548
|
+
if (task.nil? && slot.is_a?(Task)) || (task && slot == task)
|
|
509
549
|
bookedSlots += 1
|
|
510
550
|
end
|
|
511
551
|
end
|
|
@@ -515,7 +555,9 @@ class TaskJuggler
|
|
|
515
555
|
|
|
516
556
|
# Count the free slots between the start and end index.
|
|
517
557
|
def getFreeSlots(startIdx, endIdx)
|
|
518
|
-
|
|
558
|
+
return 0 if startIdx >= endIdx
|
|
559
|
+
|
|
560
|
+
initScoreboard unless @scoreboard
|
|
519
561
|
|
|
520
562
|
freeSlots = 0
|
|
521
563
|
startIdx.upto(endIdx - 1) do |idx|
|
|
@@ -528,7 +570,9 @@ class TaskJuggler
|
|
|
528
570
|
# Count the regular work time slots between the start and end index that
|
|
529
571
|
# have been blocked by a vacation.
|
|
530
572
|
def getVacationSlots(startIdx, endIdx)
|
|
531
|
-
|
|
573
|
+
return 0 if startIdx >= endIdx
|
|
574
|
+
|
|
575
|
+
initScoreboard unless @scoreboard
|
|
532
576
|
|
|
533
577
|
vacationSlots = 0
|
|
534
578
|
startIdx.upto(endIdx - 1) do |idx|
|
|
@@ -603,6 +647,24 @@ class TaskJuggler
|
|
|
603
647
|
end
|
|
604
648
|
end
|
|
605
649
|
|
|
650
|
+
# Limit the _startIdx_ and _endIdx_ to the actually assigned interval.
|
|
651
|
+
# If _task_ is provided, fit it for the bookings of this particular task.
|
|
652
|
+
def fitIndicies(startIdx, endIdx, task = nil)
|
|
653
|
+
if task
|
|
654
|
+
startIdx = @firstBookedSlots[task] if @firstBookedSlots[task] &&
|
|
655
|
+
startIdx < @firstBookedSlots[task]
|
|
656
|
+
endIdx = @lastBookedSlots[task] + 1 if @lastBookedSlots[task] &&
|
|
657
|
+
endIdx >
|
|
658
|
+
@lastBookedSlots[task] + 1
|
|
659
|
+
else
|
|
660
|
+
startIdx = @firstBookedSlot if @firstBookedSlot &&
|
|
661
|
+
startIdx < @firstBookedSlot
|
|
662
|
+
endIdx = @lastBookedSlot + 1 if @lastBookedSlot &&
|
|
663
|
+
endIdx > @lastBookedSlot + 1
|
|
664
|
+
end
|
|
665
|
+
[ startIdx, endIdx ]
|
|
666
|
+
end
|
|
667
|
+
|
|
606
668
|
def setReports_i(reports)
|
|
607
669
|
if reports.include?(@property)
|
|
608
670
|
# A manager must never show up in the list of his/her own reports.
|
|
@@ -638,7 +700,10 @@ class TaskJuggler
|
|
|
638
700
|
task)
|
|
639
701
|
end
|
|
640
702
|
else
|
|
641
|
-
return false unless a('duties').include?(task)
|
|
703
|
+
return false unless @scoreboard && a('duties').include?(task)
|
|
704
|
+
|
|
705
|
+
startIdx, endIdx = fitIndicies(startIdx, endIdx, task)
|
|
706
|
+
return false if startIdx >= endIdx
|
|
642
707
|
|
|
643
708
|
startIdx.upto(endIdx - 1) do |idx|
|
|
644
709
|
return true if @scoreboard[idx] == task
|