public List < TimephasedWork > getCompleteWork ( ProjectCalendar calendar , ResourceAssignment resourceAssignment , byte [ ] data ) { LinkedList < TimephasedWork > list = new LinkedList < TimephasedWork > ( ) ; if ( calendar != null && data != null && data . length > 2 && MPPUtility . getShort ( data , 0 ) > 0 ) { Date startDate = resourceAssignment . getStart ( ) ; double finishTime = MPPUtility . getInt ( data , 24 ) ; int blockCount = MPPUtility . getShort ( data , 0 ) ; double previousCumulativeWork = 0 ; TimephasedWork previousAssignment = null ; int index = 32 ; int currentBlock = 0 ; while ( currentBlock < blockCount && index + 20 <= data . length ) { double time = MPPUtility . getInt ( data , index + 0 ) ; // If the start of this block is before the start of the assignment, or after the end of the assignment // the values don't make sense, so we'll just set the start of this block to be the start of the assignment. // This deals with an issue where odd timephased data like this was causing an MPP file to be read // extremely slowly. if ( time < 0 || time > finishTime ) { time = 0 ; } else { time /= 80 ; } Duration startWork = Duration . getInstance ( time , TimeUnit . MINUTES ) ; double currentCumulativeWork = ( long ) MPPUtility . getDouble ( data , index + 4 ) ; double assignmentDuration = currentCumulativeWork - previousCumulativeWork ; previousCumulativeWork = currentCumulativeWork ; assignmentDuration /= 1000 ; Duration totalWork = Duration . getInstance ( assignmentDuration , TimeUnit . MINUTES ) ; time = ( long ) MPPUtility . getDouble ( data , index + 12 ) ; time /= 125 ; time *= 6 ; Duration workPerDay = Duration . getInstance ( time , TimeUnit . MINUTES ) ; Date start ; if ( startWork . getDuration ( ) == 0 ) { start = startDate ; } else { start = calendar . getDate ( startDate , startWork , true ) ; } TimephasedWork assignment = new TimephasedWork ( ) ; assignment . setStart ( start ) ; assignment . setAmountPerDay ( workPerDay ) ; assignment . setTotalAmount ( totalWork ) ; if ( previousAssignment != null ) { Date finish = calendar . getDate ( startDate , startWork , false ) ; previousAssignment . setFinish ( finish ) ; if ( previousAssignment . getStart ( ) . getTime ( ) == previousAssignment . getFinish ( ) . getTime ( ) ) { list . removeLast ( ) ; } } list . add ( assignment ) ; previousAssignment = assignment ; index += 20 ; ++ currentBlock ; } if ( previousAssignment != null ) { Duration finishWork = Duration . getInstance ( finishTime / 80 , TimeUnit . MINUTES ) ; Date finish = calendar . getDate ( startDate , finishWork , false ) ; previousAssignment . setFinish ( finish ) ; if ( previousAssignment . getStart ( ) . getTime ( ) == previousAssignment . getFinish ( ) . getTime ( ) ) { list . removeLast ( ) ; } } } return list ; }
Given a block of data representing completed work this method will retrieve a set of TimephasedWork instances which represent the day by day work carried out for a specific resource assignment .