HorizonReportTest

    Table of contents
    No headers

     

    /***
        USAGE:
        
        HorizonReportTest(query, start, iteration)
            show report for designated iteration +n iterations
    ***/
    
    // check that prerequisites are met
    if(!__env.youtrack) {
        return "YouTrack extension is not enabled";
    }
    if(!__env.google) {
        return "Google extension is not enabled";
    }
    
    // read and validate parameters
    var query = $0 ?? $query;
    if(!query) {
        return "Missing query";
    }
    var start = $1 ?? $start ?? date.today;
    var number_of_iterations = $2 ?? $number_of_iterations;
    var iteration = $3 ?? $iteration;
    var availability = $team;
    var capacity = list.sum(availability);
    var prod_capacity = capacity * 0.5;
    var padding_percentage = 0.25;
    var svcs_capacity = (capacity - prod_capacity) * (1 - padding_percentage);
    var limit = 1000;
    <br />
    
    // retrieve id's of issues with an interation tag, issues with multiple iteration tags will be put in the latest iteration
    var iteration_n_issues = {};
    foreach(var i in num.series(1, number_of_iterations)){
        var iteration_issues = youtrack.issues{ query: query .. ' tag: {iteration ' .. iteration+i .. '}', limit: limit };
        foreach(var issue in iteration_issues){
        let iteration_n_issues ..= {(issue.id): iteration+i};
        };
    };
    
    // retrieve the list of sow issues and build their dependency trees
    var sow_issues = youtrack.issues{ query: query .. ' tag:sow', limit: limit };
    var sow_tree = {}; // sow and all its dependents in a tree form
    
    foreach(var sow_id in sow_issues){
        let sow_tree ..= {(sow_id.id): {"id": sow_id.id,
                                       "summary": sow_id.summary,
                                       "issue":{
                                       (story_id.id):{"id": story_id.id,
                                                      "summary": story_id.summary,
                                                      "hours": story_id.fields["Hours Planned"],
                                                      "iteration": (map.contains(iteration_n_issues, story_id.id) ? iteration_n_issues[story_id.id] : iteration),
                                                      "issue":{
                                                       (task_id.id):{"id": task_id.id,
                                                                     "summary": task_id.summary,
                                                                     "hours": task_id.fields["Hours Planned"],
                                                                     "iteration": (map.contains(iteration_n_issues, task_id.id) ? iteration_n_issues[task_id.id] : iteration)
                                                                    }
                                                                    foreach var task_id in youtrack.issues{query: query .. ' required by:' .. story_id.id, limit: limit}
                                                              }
                                                      }
                                                      foreach var story_id in youtrack.issues{query: query .. ' required by:' .. sow_id.id, limit: limit}
                                                }
                                       }
                          }
    };
    
    
    
    // Show breakdown of sprint iterations with SOW stacked
    
    //var sow_list = map.keys(list.groupby(sow_issues, "$.summary")); // list of sow issues by 'summary'
    var sow_list = [];
    var sow_sums = list.new(number_of_iterations, [0]); // list of total hours per sow per iteration
    
    foreach(var sow_id in sow_tree){
        var story_iteration_hours = list.new(number_of_iterations, 0);
        let sow_list ..= [sow_id.summary];
        foreach(var story_id in sow_id.issue){
            if (story_id.hours && (story_id.iteration < (iteration + number_of_iterations))){
                let story_iteration_hours = list.splice(story_iteration_hours, story_id.iteration - iteration, 1, [story_iteration_hours[story_id.iteration -iteration]+story_id.hours]);
            };  
            foreach(var task_id in story_id.issue){
                if (task_id.hours && (task_id.iteration < (iteration + number_of_iterations))){
                    let story_iteration_hours = list.splice(story_iteration_hours, task_id.iteration - iteration, 1, [story_iteration_hours[task_id.iteration -iteration]+task_id.hours]);
                };
            };
        };
        foreach(var i in num.series(0, number_of_iterations-1)){
        let sow_sums = list.splice(sow_sums, i, 1, [sow_sums[i]..[story_iteration_hours[i]]]);
        };
    };
    <div>
    
    var width = 300;
    var height = 300;
    var values = [[svcs_capacity]]..sow_sums;
    var colors = [ "ff0000", "0000ff", "00ff00", "00CCCC", "CC00CC", "CCCC00", "7733DD", "33DD77", "DD7733", "aa4400", "00aa44", "4400aa", "ffff00", "00ffff", "ff00ff", "224466", "446622", "662244" ];
    var legends = ["Services Capacity"]..sow_list;
    var xaxis = [""];
    //var yaxis = [0, max*0.2, max*0.4, max*0.6, max*0.8, max];
    
    
    foreach (var i in num.series(0, number_of_iterations-1)){
        let xaxis ..= ["I" .. iteration+i]
    };
    
    google.barchart {
        width: width,
        height: height,
        values: values,
        colors: colors,
        vertical: true,
        stacked: true,
        legends: legends,
        xaxis: xaxis
        //yaxis: yaxis
    };
    
    </div>
    
    /*
    List iteration requirements due, dev start, and dev finish dates
    */
    
    <br />
    <p>
    foreach (var i in num.series(0, number_of_iterations -1)){
        var begin_date = date.adddays(start, 14*i);
        var end_date = date.adddays(start, 14*(i+1));
        <strong>
        'Iteration '; iteration+i;
        </strong><br />
        'Requirements due by: '; date.format(date.adddays(begin_date, -2), "d");
        ', Development start: '; date.format(begin_date, "d");
        ' Development end: '; date.format(end_date, "d");
        <br />
    };
    </p>
    <hr></hr>
    foreach(var sow_id in sow_tree){
    <strong>
    youtrack.querylink{
        query: sow_id.id,
        text: sow_id.id.. ' ' .. sow_id.summary,
        target: '_blank'
     };
      </strong>
    <ul>
        foreach(var story_id in sow_id.issue){
        <li>
        youtrack.querylink{
            query: story_id.id,
            text: story_id.id.. ' ' .. story_id.summary,
            target: '_blank'
        };
        if (!string.startswith(story_id.id, "PRD")){ ' - Planned hours: '; story_id.hours; ', Iteration '; story_id.iteration;};
        </li>
        <ul>
            foreach(var task_id in story_id.issue){
            <li>
            youtrack.querylink{
                query: task_id.id,
                text: task_id.id.. ' ' .. task_id.summary,
                target: '_blank'
            };
            ' - Planned hours: '; task_id.hours; ', Iteration: '; task_id.iteration; </li>
            };
        </ul>
        };
    </ul>
    <br />
    };
    
    
    Tag page
    You must login to post a comment.

    Copyright © 2011 MindTouch, Inc. Powered by