Close an item when all its children are closed

📘

If an item has multiple final states, it will be moved to the default final state

📘

How to apply this rule?

Close a User Story when all its Tasks are closed

The filter by Project.Name is optional.

[
  {
    "type": "source:targetprocess:EntityChanged",
    "entityTypes": [
      "Task"
    ],
    "modifications": {
      "created": false,
      "deleted": false,
      "updated": [
        "EntityState"
      ]
    }
  },
  {
    "or": [
      {
        "and": [
          {
            "target": {
              "type": "field",
              "name": "IsFinal",
              "target": {
                "type": "field",
                "name": "EntityState",
                "target": {
                  "type": "pipelineBlockOutput"
                }
              }
            },
            "value": {
              "type": "constant",
              "value": true
            },
            "operator": {
              "type": "is"
            }
          },
          {
            "target": {
              "type": "field",
              "name": "IsFinal",
              "target": {
                "type": "field",
                "name": "EntityState",
                "target": {
                  "type": "field",
                  "name": "UserStory",
                  "target": {
                    "type": "pipelineBlockOutput"
                  }
                }
              }
            },
            "value": {
              "type": "constant",
              "value": false
            },
            "operator": {
              "type": "is"
            }
          },
          {
            "target": {
              "type": "field",
              "name": "Name",
              "target": {
                "type": "field",
                "name": "Project",
                "target": {
                  "type": "pipelineBlockOutput"
                }
              }
            },
            "value": {
              "type": "constant",
              "value": "Pilot"
            },
            "operator": {
              "type": "is"
            }
          }
        ]
      }
    ],
    "type": "filter:Relational"
  },
  {
    "type": "filter:JavaScript",
    "script": "const api = context.getService(\"targetprocess/api/v2\");\nconst count = await api.queryAsync(\"task\", {\n  where: \"entitystate.isfinal == false and userstory.id == \" + args.Changed.UserStory.Id,\n  result: \"count\"\n});\n\n//the total number of not finished tasks\nreturn count === 0;"
  },
  {
    "type": "action:targetprocess:MoveToState",
    "stateKind": "Final",
    "target": {
      "type": "field",
      "name": "UserStory",
      "target": {
        "type": "pipelineBlockOutput"
      }
    }
  }
]

Close a User Story when all its Bugs and Tasks are closed

The filter by Project.Name is optional.

[
  {
    "type": "source:targetprocess:EntityChanged",
    "entityTypes": [
      "Bug",
      "Task"
    ],
    "modifications": {
      "created": false,
      "deleted": false,
      "updated": [
        "EntityState"
      ]
    }
  },
  {
    "or": [
      {
        "and": [
          {
            "value": {
              "type": "constant",
              "value": true
            },
            "target": {
              "name": "IsFinal",
              "type": "field",
              "target": {
                "name": "EntityState",
                "type": "field",
                "target": {
                  "type": "pipelineBlockOutput"
                }
              }
            },
            "operator": {
              "type": "is true"
            }
          },
          {
            "value": {
              "type": "pipelineBlockOutput"
            },
            "target": {
              "name": "UserStory",
              "type": "field",
              "target": {
                "type": "pipelineBlockOutput"
              }
            },
            "operator": {
              "type": "exists"
            }
          },
          {
            "value": null,
            "target": {
              "name": "IsFinal",
              "type": "field",
              "target": {
                "name": "EntityState",
                "type": "field",
                "target": {
                  "name": "UserStory",
                  "type": "field",
                  "target": {
                    "type": "pipelineBlockOutput"
                  }
                }
              }
            },
            "operator": {
              "type": "is false"
            }
          },
          {
            "value": {
              "type": "constant",
              "value": "Pilot"
            },
            "target": {
              "name": "Name",
              "type": "field",
              "target": {
                "name": "Project",
                "type": "field",
                "target": {
                  "type": "pipelineBlockOutput"
                }
              }
            },
            "operator": {
              "type": "is"
            }
          }
        ]
      }
    ],
    "type": "filter:Relational"
  },
  {
    "type": "filter:JavaScript",
    "script": "const api = context.getService(\"targetprocess/api/v2\");\nconst story = await api.queryAsync(\"userstory\", {\n  \"where\": \"id=\" + args.Changed.UserStory.Id,\n  \"select\": \"{closed:(tasks.count(entityState.isFinal=false)=0 and bugs.count(entityState.isFinal=false)=0)}\"\n});\n\n//Are all the bugs and tasks closed?\nreturn story[0].closed === true;"
  },
  {
    "type": "action:targetprocess:MoveToState",
    "target": {
      "name": "UserStory",
      "type": "field",
      "target": {
        "type": "pipelineBlockOutput"
      }
    },
    "stateKind": "Final"
  }
]

Close a Feature when all its Bugs and User Stories are closed

The filter by Project.Name is optional.

[
  {
    "type": "source:targetprocess:EntityChanged",
    "entityTypes": [
      "Bug",
      "UserStory"
    ],
    "modifications": {
      "created": false,
      "deleted": false,
      "updated": [
        "EntityState"
      ]
    }
  },
  {
    "or": [
      {
        "and": [
          {
            "value": {
              "type": "constant",
              "value": true
            },
            "target": {
              "name": "IsFinal",
              "type": "field",
              "target": {
                "name": "EntityState",
                "type": "field",
                "target": {
                  "type": "pipelineBlockOutput"
                }
              }
            },
            "operator": {
              "type": "is true"
            }
          },
          {
            "value": {
              "type": "pipelineBlockOutput"
            },
            "target": {
              "name": "Feature",
              "type": "field",
              "target": {
                "type": "pipelineBlockOutput"
              }
            },
            "operator": {
              "type": "exists"
            }
          },
          {
            "value": null,
            "target": {
              "name": "IsFinal",
              "type": "field",
              "target": {
                "name": "EntityState",
                "type": "field",
                "target": {
                  "name": "Feature",
                  "type": "field",
                  "target": {
                    "type": "pipelineBlockOutput"
                  }
                }
              }
            },
            "operator": {
              "type": "is false"
            }
          },
          {
            "value": {
              "type": "constant",
              "value": "Pilot"
            },
            "target": {
              "name": "Name",
              "type": "field",
              "target": {
                "name": "Project",
                "type": "field",
                "target": {
                  "type": "pipelineBlockOutput"
                }
              }
            },
            "operator": {
              "type": "is"
            }
          }
        ]
      }
    ],
    "type": "filter:Relational"
  },
  {
    "type": "filter:JavaScript",
    "script": "const api = context.getService(\"targetprocess/api/v2\");\nconst feature = await api.queryAsync(\"Feature\", {\n  \"where\": \"id=\" + args.Changed.Feature.Id,\n  \"select\": \"{closed:(userstories.count(entityState.isFinal=false)=0 and bugs.count(entityState.isFinal=false)=0)}\"\n});\n\n//Are all the bugs and tasks closed?\nreturn feature[0].closed === true;"
  },
  {
    "type": "action:targetprocess:MoveToState",
    "target": {
      "name": "Feature",
      "type": "field",
      "target": {
        "type": "pipelineBlockOutput"
      }
    },
    "stateKind": "Final"
  }
]

Close an Epic when all its Features are closed

The filter by Project.Name is optional.

[
  {
    "type": "source:targetprocess:EntityChanged",
    "entityTypes": [
      "Feature"
    ],
    "modifications": {
      "created": false,
      "deleted": false,
      "updated": [
        "EntityState"
      ]
    }
  },
  {
    "or": [
      {
        "and": [
          {
            "value": {
              "type": "constant",
              "value": true
            },
            "target": {
              "name": "IsFinal",
              "type": "field",
              "target": {
                "name": "EntityState",
                "type": "field",
                "target": {
                  "type": "pipelineBlockOutput"
                }
              }
            },
            "operator": {
              "type": "is true"
            }
          },
          {
            "value": {
              "type": "pipelineBlockOutput"
            },
            "target": {
              "name": "Epic",
              "type": "field",
              "target": {
                "type": "pipelineBlockOutput"
              }
            },
            "operator": {
              "type": "exists"
            }
          },
          {
            "value": null,
            "target": {
              "name": "IsFinal",
              "type": "field",
              "target": {
                "name": "EntityState",
                "type": "field",
                "target": {
                  "name": "Epic",
                  "type": "field",
                  "target": {
                    "type": "pipelineBlockOutput"
                  }
                }
              }
            },
            "operator": {
              "type": "is false"
            }
          },
          {
            "value": {
              "type": "constant",
              "value": "Pilot"
            },
            "target": {
              "name": "Name",
              "type": "field",
              "target": {
                "name": "Project",
                "type": "field",
                "target": {
                  "type": "pipelineBlockOutput"
                }
              }
            },
            "operator": {
              "type": "is"
            }
          }
        ]
      }
    ],
    "type": "filter:Relational"
  },
  {
    "type": "filter:JavaScript",
    "script": "const api = context.getService(\"targetprocess/api/v2\");\nconst count = await api.queryAsync(\"Feature\", {\n  where: \"entitystate.isfinal == false and epic.id == \" + args.Changed.Epic.Id,\n  result: \"count\"\n});\n\n//the total number of not finished features\nreturn count === 0;"
  },
  {
    "type": "action:targetprocess:MoveToState",
    "target": {
      "name": "Epic",
      "type": "field",
      "target": {
        "type": "pipelineBlockOutput"
      }
    },
    "stateKind": "Final"
  }
]

Close a Portfolio Epic when all its Features and Epics are closed

The filter by Project.Name is optional.

[
  {
    "type": "source:targetprocess:EntityChanged",
    "entityTypes": [
      "Feature",
      "Epic"
    ],
    "modifications": {
      "created": false,
      "deleted": false,
      "updated": [
        "EntityState"
      ]
    }
  },
  {
    "or": [
      {
        "and": [
          {
            "value": {
              "type": "constant",
              "value": true
            },
            "target": {
              "name": "IsFinal",
              "type": "field",
              "target": {
                "name": "EntityState",
                "type": "field",
                "target": {
                  "type": "pipelineBlockOutput"
                }
              }
            },
            "operator": {
              "type": "is true"
            }
          },
          {
            "value": {
              "type": "pipelineBlockOutput"
            },
            "target": {
              "name": "PortfolioEpic",
              "type": "field",
              "target": {
                "type": "pipelineBlockOutput"
              }
            },
            "operator": {
              "type": "exists"
            }
          },
          {
            "value": null,
            "target": {
              "name": "IsFinal",
              "type": "field",
              "target": {
                "name": "EntityState",
                "type": "field",
                "target": {
                  "name": "PortfolioEpic",
                  "type": "field",
                  "target": {
                    "type": "pipelineBlockOutput"
                  }
                }
              }
            },
            "operator": {
              "type": "is false"
            }
          },
          {
            "value": {
              "type": "constant",
              "value": "Pilot"
            },
            "target": {
              "name": "Name",
              "type": "field",
              "target": {
                "name": "Project",
                "type": "field",
                "target": {
                  "type": "pipelineBlockOutput"
                }
              }
            },
            "operator": {
              "type": "is"
            }
          }
        ]
      }
    ],
    "type": "filter:Relational"
  },
  {
    "type": "filter:JavaScript",
    "script": "const api = context.getService(\"targetprocess/api/v2\");\nconst pe = await api.queryAsync(\"PortfolioEpic\", {\n  \"where\": \"id=\" + args.Changed.PortfolioEpic.Id,\n  \"select\": \"{closed:(epics.count(entityState.isFinal=false)=0 and features.count(entityState.isFinal=false)=0)}\"\n});\n\n//Are all the bugs and tasks closed?\nreturn pe[0].closed === true;"
  },
  {
    "type": "action:targetprocess:MoveToState",
    "target": {
      "name": "PortfolioEpic",
      "type": "field",
      "target": {
        "type": "pipelineBlockOutput"
      }
    },
    "stateKind": "Final"
  }
]