DTM (Digital Trace Matrix) Export

DTM (Digital Trace Matrix) Export

DTM (Digital Trace Matrix) Export

DTM stands for Digital Trace Matrix. The DTM Excel template has been created to export the DTM report based on the model and the already-defined reference structure.

The configuration diagram associated with the DTM export template is as shown below: -


Steps to create a report using the DTM Export template: -

  1. Login to Arthrex using the URL ...

  2. Go to the Projects tab and select the project.


  3. Go to the Trackers tab. Select User Needs. Right-click on it and click Open.


    This will open a new window.

  4. If you want to export every item in the User Needs, click on the three dots (more) option and choose Export to Office.


    1. If you want to export a few selected items in the User Needs, select all the items you wish to export and then click on the three dots (more) option and choose Export selection (and their children) to Office.


  5. Click on the MS Excel tab. Select Simple Excel Export and check box the option Multiple-values go to multiple rows. Choose the template DTM Export.xlsx from the dropdown and then click Export.


  6. The report will be exported and downloaded to your Downloads folder.

    The report contains 8 columns - User Needs, User Needs Source, Design Inputs, Requirement Category, Design Input Source, Design Output, Risk Trace, KPC (Y or N), Design Verification, and Design Validation.


Steps to download the custom DTM Export template: -

  1. Go to the Projects tab and select the project.


  2. Go to the Documents tab and select the Trackers folder.

  3. Click on the three dots beside the template DTM EXport.xlsx.


  4. Click on Download.


    The template will be downloaded to your local device.

Steps to upload the custom DTM Export template: -

  1. Go to the Projects tab and select the project where you want to upload the template.


  2. Go to the Documents tab and select the Trackers folder.

  3. Click on Browser and upload the template from your device.         

How to modify/update the DTM Export Template

DTM Export Template is a single Excel file that includes a special "code" embedded directly in the cells that loop over data and print that in the cells. This code is a combination of JETT tags and Groovy scripts as detailed in the Codebeamer Help Center.

Modifying the DTM export template assumes that you have an understanding of the underlying technology and the Configuration diagram that traces different columns in the DTM export template viz. User Needs, Validation, Design Input, Design Output, and Verification items. This explains the data structure used to store that hierarchy of related items in memory while iterating over them and producing the final report output.

Opening the template shows the various template tags and scripts:


Excel can be difficult to edit cells with a large amount of text, especially cell L2 which contains the main groovy code that accumulates and assembles the data for use by the other JETT and Groovy tags in cells B3:L3.

Because the desired output rearranges the data from what is defined by the trace sequence in Codebeamer, the template uses several Map objects to and other variables to capture this information, including things like number of children so rows can be merged appropriately.

When the export first begins, the Groovy code in cell L2 iterates over the items that are included in the User Needs tracker from where the export is initiated and assembles the data structure for the User Needs and downstream items that need to be included in the export. This does not print anything to any cells as that is left to the code in cells B3:L3.

The concept is that for each item, regardless of type/level, may have zero or more downstream items referred to as "children" in the code. The code will iterate over the child levels and continue to assemble relevant downstream items into the appropriate Map. While doing this, the code will also determine if any rows need to be merged and will capture the number of spanning rows for the merge. This provides the visual representation of one type of item having multiple downstream related items.

The main data structures that are defined by this Groovy code are:

Variable Name

Description

unMap

The Map containing User Needs

unMapSize

The number of rows to span for a given User Need

diMap

The Map of Design Inputs

diMapSize

The number of rows to span for a given Design Input

doMap

The Map of Design Outputs

verMap

The Map of Verifications

valMap

The Map of Validations

           

The B3:L3 cells iterate over those various data structures in those variables to print into each cell some value that is relevant for that column of data. This mixes a combination of JETT <jt:forEach/> tags with optional <jt:span/> tags to achieve the desired visual parent-child hierarchy.

An example of the Groovy code from cell L2 is shown below for reference. The B3:L3 cells are omitted for brevity.

<cb:groovy template="false" silent="false">
// v2024-06-19-06:53
def manager = com.intland.codebeamer.manager.TrackerItemManager.getInstance();
def resolver = com.intland.codebeamer.persistence.dao.impl.EntityCache.getInstance(user);
def logger = org.slf4j.LoggerFactory.getLogger(this.class);
unMap = new TreeMap(); // item.id
unMapSize = new TreeMap(); // item.id
diMap = new TreeMap(); // item.id
diMapSize = new TreeMap(); // item.id
doMap = new TreeMap(); // item.id/diItem.id
verMap = new TreeMap(); // item.id/diItem.id/doItem.id
valMap = new TreeMap(); // item.id/diItem.id/doItem.id
lineNumber = 1;
items = items.sort {it.getId()}; // sort the items by the id
items.each({
    def userNeedItem = it;
    def userNeedDownRefs = issueReferences.getIncomingReferences(userNeedItem);
    def outgoingRefs = issueReferences.getOutgoingReferences(userNeedItem);
    def diChildren = [];
    def valChildren = [];
    def userNeedChildren = [];
    def unRows = 0;
    userNeedDownRefs.each({
        resolver.resolve(it);
        def userNeedDownItem = manager.findById(user, it.getId());
        //logger.warn("IQNOX: user need " + userNeedItem.getId() + " incoming ref: "+userNeedDownItem.getTracker().getName()+"-"+userNeedDownItem.getId());
        if (userNeedDownItem.getTracker().getName() == "Design Input") {
            def designInputSourceValues = fields.getByLabel(userNeedDownItem, "Design Input Source");
            def designInputSource = [];
            designInputSourceValues.each({designInputSource.add(it.name)});
            def requirementCategory = [];
            def requirementCategoryValues = fields.getByLabel(userNeedDownItem,"Requirement Category");
            requirementCategoryValues.each({requirementCategory.add(it.name)})
            def diItem = [lineNumber: lineNumber++, urlLink: userNeedDownItem.urlLink, id: userNeedDownItem.id, name: userNeedDownItem.name, requirementCategory: requirementCategory.join(", "), designInputSource: designInputSource.join(", "),description: userNeedDownItem.description, descriptionPlain: com.intland.codebeamer.text.WikiToPlainTextConverter.extractTextFromWiki(userNeedDownItem.description, null).getLeft()];
            diChildren.push(diItem);
            userNeedChildren.push(userNeedDownItem);
            def diDownRefs = issueReferences.getIncomingReferences(userNeedDownItem);
            def doChildren = [];
            def doRows = 0;
            def verChildren = [];
            diDownRefs.each({
                resolver.resolve(it);
                def diDownItem = manager.findById(user, it.getId());
                if (diDownItem.getTracker().getName() == "Design Output") {
                    def riskTrace = [];
                    def riskTraceValues = fields.getByLabel(diDownItem,"Risk Trace");
                    riskTraceValues.each({riskTrace.add("[dFMEA-"+it.id+"] "+it.name)})
                    def kpcValue = fields.getByLabel(diDownItem,"KPC");
                    def kpc = "";
                    if (kpcValue != null) {
                        kpc = kpcValue.get(0).name;
                    }
                    def doItem = [urlLink: diDownItem.urlLink, id: diDownItem.id, riskTrace: riskTrace.join(", "), kpc: kpc, name: diDownItem.name, description: diDownItem.description, descriptionPlain: com.intland.codebeamer.text.WikiToPlainTextConverter.extractTextFromWiki(diDownItem.description, null).getLeft()];
                    doChildren.push(doItem);
                    doRows++;
                } else if (diDownItem.getTracker().getName() == "Verification") {
                    verChildren.push(diDownItem);
                }
            });
            doMap.put(userNeedItem.getId() + "#" + userNeedDownItem.getId(), doChildren);
            diMapSize.put(userNeedItem.getId() + "#" + userNeedDownItem.getId(), Math.max(1, doRows));
            unRows += Math.max(1, doRows);
            // remove dups from verification and concatenate result to single value then put in verMap.
            // all items are concatenated into a single string separated by a blank line.
            def verItems = verChildren.unique(false);
            def verString = "";
            def i = 0;
            verItems.each({
                def verItem = it;
                if (i > 0) {
                    verString += "\n\n";
                }
                i++;
                // cell length limit of 32,767 so trucate at 32,000 to leave a little room for the id and name
                verString += "[VER-" + verItem.id + "] " + verItem.name + "\n" + org.apache.commons.lang3.StringUtils.abbreviate(com.intland.codebeamer.text.WikiToPlainTextConverter.extractTextFromWiki(verItem.description, null).getLeft(), 32000);
            });
            verMap.put(userNeedItem.getId() + "#" + userNeedDownItem.getId(), [verString]);
        } else if (userNeedDownItem.getTracker().getName() == "Validation") {
            valChildren.push(userNeedDownItem);
        }
    }); 
    // remove dups from validation and concatenate result to single value then put in valMap.
    // all items are concatenated into a single string separated by a blank line.
    def valItems = valChildren.unique(false);
    def valString = "";
    def i = 0;
    valItems.each({
        def valItem = it;
        if (i > 0) {
            valString += "\n\n";
        }
        i++;
        // cell length limit of 32,767 so trucate at 32,000 to leave a little room for the id and name
        valString += "[VAL-" + valItem.id + "] " + valItem.name + "\n" + org.apache.commons.lang3.StringUtils.abbreviate(com.intland.codebeamer.text.WikiToPlainTextConverter.extractTextFromWiki(valItem.description, null).getLeft(), 32000);
    });
    valMap.put(userNeedItem.getId(), [valString]);
    diMap.put(userNeedItem.getId(), diChildren);
    unMap.put(userNeedItem.getId(), userNeedChildren);
    unMapSize.put(userNeedItem.getId(), Math.max(1, unRows));
});
return "";
</cb:groovy>

    • Related Articles

    • Updating DTM Export

      Basics The DTM (and all) excel exports are written in a markdown language called Java Excel Template Translator (JETT). Fundamentals The most fundamental keys to understanding and the most important takeaway from the DTM export file are that: The ...
    • Exporting fields with hide if logic

      Exporting Fields with “Hide If” Logic A set of macros has been added to mergeFields.v m to allow for conditionally exporting those fields in templates. For each of the following tracker names, there's a table that represents: What field will be ...
    • Draft to Approval Report (UC - 2)

      This can be used to build metadata to calculate the Length of Time from Draft to Approval for the Length of Time Draft to Approval Report. Used By: - System Administrator General User Steps to run the Draft to Approval Report: - Login to Arthrex ...
    • Content Rejection Report (UC -1)

      UC-1 Content Rejection Report This can be used to build metadata to track the number of iterations for the Content Rejection Report. Used By: - System Administrator General User Steps to run the Content Rejection Report: - Login to Arthrex using the ...
    • Approval to Draft Count Report (UC - 3)

      This can be used to build metadata to calculate Approval to Draft Count for Approval to Draft Count Report. Used By: - System Administrator General User Steps to run the Approval to Draft Count Report: - Login to Arthrex using the URL ... Go to the ...