| 1 | == ClientsPlugin Recipe: Weekly Summary Email == |
| 2 | |
| 3 | 1. Create an event called "Weekly Summary" which has the "Milestone Summary" summary and the "Send Email" action. |
| 4 | 2. Trigger the event every week and run: {{{run-client-event -e /path/to/env -c "Weekly Summary"}}} |
| 5 | 3. For each client you wish to receive the summary, edit the client and enter the email address under the options section for "Weekly Summary" |
| 6 | 4. Edit the event and add the following XSLT: |
| 7 | |
| 8 | {{{ |
| 9 | #!xml |
| 10 | <?xml version="1.0" encoding="utf-8"?> |
| 11 | <!DOCTYPE xsl:stylesheet [ <!ENTITY nbsp " "> ]> |
| 12 | <xsl:stylesheet |
| 13 | xmlns:xsl="http://www.w3.org/1999/XSL/Transform" |
| 14 | version="1.0"> |
| 15 | |
| 16 | <xsl:output method="html" indent="yes" encoding="UTF-8" omit-xml-declaration="yes"/> |
| 17 | <xsl:decimal-format name="GBP" decimal-separator="." grouping-separator=","/> |
| 18 | |
| 19 | <!-- Match the root of the XML render the three views --> |
| 20 | <xsl:template match="/"> |
| 21 | <xsl:choose> |
| 22 | <xsl:when test="$view='html'"> |
| 23 | <!-- Should return HTML as you see fit --> |
| 24 | <xsl:call-template name="html"/> |
| 25 | </xsl:when> |
| 26 | <xsl:when test="$view='images'"> |
| 27 | <!-- |
| 28 | Should return a list of images to embed in the following format: |
| 29 | |
| 30 | <images> |
| 31 | <img id="myimage" src="/local/path/to/image"/> |
| 32 | </images> |
| 33 | |
| 34 | Where "myimage" is references in your HTML image as <img src="cid:myimage" /> |
| 35 | --> |
| 36 | <xsl:call-template name="images"/> |
| 37 | </xsl:when> |
| 38 | <xsl:otherwise> |
| 39 | <!-- The plain text portion of the email --> |
| 40 | <xsl:call-template name="plain"/> |
| 41 | </xsl:otherwise> |
| 42 | </xsl:choose> |
| 43 | </xsl:template> |
| 44 | |
| 45 | <!-- Simple (cop-out) implementation of a plain text message --> |
| 46 | <xsl:template name="plain"> |
| 47 | <xsl:text> |
| 48 | This message contains HTML content for a rich display. |
| 49 | |
| 50 | Please enable the HTML view or use an HTML compatible email client. |
| 51 | </xsl:text> |
| 52 | </xsl:template> |
| 53 | |
| 54 | <!-- This HTML version does not contain any images --> |
| 55 | <xsl:template name="images"/> |
| 56 | |
| 57 | <xsl:template name="html"> |
| 58 | <!-- The root element needs to be created with xsl:element to prevent namespaces sneaking in. --> |
| 59 | <xsl:element name="html"> |
| 60 | <head> |
| 61 | <title>Ticket Summary for <xsl:value-of select="/clientsplugin/client/name"/></title> |
| 62 | <style type="text/css"> |
| 63 | body { |
| 64 | background: #f3f3f3; |
| 65 | } |
| 66 | fieldset.milestone { |
| 67 | margin-top: 3em; |
| 68 | } |
| 69 | fieldset.ticket { |
| 70 | margin-top: 2em; |
| 71 | background: #eee; |
| 72 | } |
| 73 | .description { |
| 74 | margin: 0.5em; |
| 75 | padding: 0.5em; |
| 76 | border: 1px solid #222; |
| 77 | background: #fff; |
| 78 | } |
| 79 | .status { |
| 80 | margin: 4px; |
| 81 | padding: 0; |
| 82 | font-variant: small-caps; |
| 83 | } |
| 84 | dl.milestone dt { |
| 85 | float: left; |
| 86 | margin-right: 0.5em; |
| 87 | font-style: italic; |
| 88 | } |
| 89 | dl.milestone dt:after { |
| 90 | content: ':'; |
| 91 | } |
| 92 | </style> |
| 93 | </head> |
| 94 | <body> |
| 95 | <h1>Ticket Summary for <xsl:value-of select="/clientsplugin/client/name"/></h1> |
| 96 | <xsl:choose> |
| 97 | <xsl:when test="/clientsplugin/summary/ticket"> |
| 98 | <xsl:for-each select="/clientsplugin/milestones/milestone"> |
| 99 | <xsl:sort select="duetimestamp" order="asscending"/> |
| 100 | <xsl:variable name="ms" select="./name" /> |
| 101 | <xsl:if test="/clientsplugin/summary/ticket[milestone=$ms]"> |
| 102 | <fieldset class="milestone"> |
| 103 | <legend class="milestone"> |
| 104 | <xsl:text>Milestone: </xsl:text> |
| 105 | <xsl:value-of select="$ms" /> |
| 106 | </legend> |
| 107 | <xsl:if test="./description!=''"> |
| 108 | <div class="milestone description"> |
| 109 | <xsl:value-of select="./description" /> |
| 110 | </div> |
| 111 | </xsl:if> |
| 112 | <xsl:if test="./due"> |
| 113 | <dl class="milestone"> |
| 114 | <dt>Estimated delivery date</dt> |
| 115 | <dd><xsl:value-of select="./due" /></dd> |
| 116 | <xsl:if test="./completed"> |
| 117 | <dt>Completed on</dt> |
| 118 | <dd><xsl:value-of select="./completed" /></dd> |
| 119 | </xsl:if> |
| 120 | <xsl:if test="./estimatedhours"> |
| 121 | <dt>Total estimated development time</dt> |
| 122 | <dd><xsl:value-of select="./estimatedhours" /></dd> |
| 123 | </xsl:if> |
| 124 | </dl> |
| 125 | </xsl:if> |
| 126 | <xsl:for-each select="/clientsplugin/summary/ticket[milestone=$ms]"> |
| 127 | <xsl:call-template name="print-ticket" /> |
| 128 | </xsl:for-each> |
| 129 | </fieldset> |
| 130 | </xsl:if> |
| 131 | </xsl:for-each> |
| 132 | <xsl:variable name="ms" select="''" /> |
| 133 | <xsl:if test="/clientsplugin/summary/ticket[milestone=$ms]"> |
| 134 | <fieldset class="milestone"> |
| 135 | <legend class="milestone"> |
| 136 | Tickets not allocated to specific milestones |
| 137 | </legend> |
| 138 | <div class="milestone description"> |
| 139 | <p>The following tickets are not allocated to any specific milestone.</p> |
| 140 | </div> |
| 141 | <xsl:for-each select="/clientsplugin/summary/ticket[milestone=$ms]"> |
| 142 | <xsl:call-template name="print-ticket" /> |
| 143 | </xsl:for-each> |
| 144 | </fieldset> |
| 145 | </xsl:if> |
| 146 | </xsl:when> |
| 147 | <xsl:otherwise> |
| 148 | <p>You do not currently have any active tickets</p> |
| 149 | </xsl:otherwise> |
| 150 | </xsl:choose> |
| 151 | </body> |
| 152 | </xsl:element> |
| 153 | </xsl:template> |
| 154 | |
| 155 | <xsl:template name="print-ticket"> |
| 156 | <fieldset class="ticket"> |
| 157 | <legend class="ticket"> |
| 158 | Ticket #<xsl:value-of select="id"/>: <xsl:value-of select="summary"/> |
| 159 | </legend> |
| 160 | <xsl:if test="description!=''"> |
| 161 | <div class="ticket description"><xsl:copy-of select="description"/></div> |
| 162 | </xsl:if> |
| 163 | <div class="status">Status: <xsl:value-of select="status"/></div> |
| 164 | <xsl:if test="estimatedhours"> |
| 165 | <div class="estimate">Estimated development time: <xsl:value-of select="estimatedhours"/></div> |
| 166 | </xsl:if> |
| 167 | <!-- <div class="due"><xsl:value-of select="due"/></div> --> |
| 168 | </fieldset> |
| 169 | </xsl:template> |
| 170 | </xsl:stylesheet> |
| 171 | |
| 172 | }}} |