basing everything on variable nodeset

This commit is contained in:
skyanth 2019-06-20 14:57:55 +02:00
parent c65cc36910
commit 703e769545
10 changed files with 577 additions and 215 deletions

View File

@ -6,6 +6,7 @@
schemaLocation="http://www.w3.org/2001/xml.xsd"/>
<xs:import namespace="http://www.w3.org/2001/XInclude"
schemaLocation="http://www.w3.org/2001/XInclude/XInclude.xsd"/>
<xs:include schemaLocation="servicebreakdown.xsd"/>
<xs:include schemaLocation="common.xsd"/>
<xs:element name="offerte">
@ -46,7 +47,7 @@
<xs:element name="activityinfo">
<xs:complexType>
<xs:sequence>
<xs:all>
<xs:element ref="duration" minOccurs="1"/>
<xs:element ref="persondays" minOccurs="1"/>
<xs:element ref="planning" minOccurs="1"/>
@ -59,10 +60,11 @@
<xs:element ref="technical_artefact_analysis" minOccurs="0"/>
<xs:element minOccurs="0" ref="target_application"/>
<xs:element minOccurs="0" ref="target_application_producer"/>
</xs:sequence>
<xs:element ref="breakdown" minOccurs="0"/>
</xs:all>
</xs:complexType>
</xs:element>
<xs:element name="organizational_readiness_assessment">
<xs:complexType>
<xs:sequence>
@ -71,7 +73,7 @@
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="team">
<xs:complexType>
<xs:sequence>
@ -79,7 +81,7 @@
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="member">
<xs:complexType>
<xs:sequence>
@ -88,34 +90,17 @@
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="expertise" type="xs:string"/>
<xs:element name="security_incident_management" type="ir_service"/>
<xs:element name="technical_artefact_analysis" type="ir_service"/>
<xs:complexType name="ir_service">
<xs:sequence>
<xs:element ref="rate"/>
</xs:sequence>
<xs:sequence>
<xs:element ref="rate"/>
</xs:sequence>
</xs:complexType>
<xs:element name="fee">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:integer">
<xs:attribute name="denomination" use="required">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="eur"/>
<xs:enumeration value="gbp"/>
<xs:enumeration value="usd"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
<xs:element name="annex">
<xs:complexType>
@ -203,6 +188,18 @@
<xs:element ref="contact"/>
<xs:element ref="generate_targets"/>
<xs:element name="generate_teammembers"/>
<xs:element name="generate_service_breakdown">
<xs:complexType>
<xs:attribute name="format" use="required">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="list"/>
<xs:enumeration value="table"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:complexType>
</xs:element>
<xs:element ref="generate_offer_signature_box"/>
</xs:choice>
</xs:sequence>

View File

@ -114,6 +114,7 @@
<xs:element ref="name"/>
<xs:element ref="bio"/>
</xs:sequence>
<xs:attributeGroup ref="xml:specialAttrs"/>
</xs:complexType>
</xs:element>
@ -289,8 +290,8 @@
<xs:element ref="recommendation_summary"/>
</xs:choice>
</xs:sequence>
<xs:attribute ref="xml:base"/>
<xs:attribute ref="xml:lang"/>
<xs:attribute name="id" use="required" type="xs:ID"/>
<xs:attribute ref="threatLevel" use="optional" default="N/A"/>
<xs:attribute name="status" use="optional">
<xs:simpleType>
@ -311,7 +312,6 @@
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute ref="xml:base"/>
</xs:complexType>
</xs:element>
<xs:element name="description">

View File

@ -38,28 +38,30 @@
</targets>
<!-- How long would you like the test to be? (in days) -->
<days>0</days>
<!-- How many persondays (if you don't know, try days * number of assigned pentesters) -->
<!-- How many persondays -->
<persondays>0</persondays>
<!-- LAAT PERSONDAYS OP 0 STAAN OM AUTOMATISCH TE LATEN BEREKENEN VIA SERVICE BREAKDOWN -->
<!-- Service execution (Use one of the following values: time-boxed, subscription) -->
<nature>time-boxed</nature>
<!-- Testing type (Use one of the following values: crystal-box, black-box, grey-box) -->
<type>crystal-box</type>
<!-- Test planning (when would you like the test to be executed -->
<!-- dates should be in ISO format (YYY-MM-DD) -->
<!-- dates should be in ISO format (YYYY-MM-DD) -->
<!-- if unknown, write TBD -->
<planning><start>YYYY-MM-DD</start><end>TBD</end></planning>
<!-- Pentest report delivery date (please allow at least 1 week between the end of the pentest and the report delivery date) -->
<!-- date should be in ISO format (YYY-MM-DD) -->
<!-- date should be in ISO format (YYYY-MM-DD) -->
<!-- if unknown, write TBD -->
<delivery>TBD</delivery>
<!-- Do you need/want a code audit? (possible values: yes/no), only for pentest -->
<!-- Do you need/want an additional code audit? (possible values: yes/no), only for pentest -->
<codeaudit perform="yes"/>
<!-- Is there an application that needs to be tested? Add an <application_name> element below. -->
<!-- INSERT OPTIONAL APPLICATION NAME HERE -->
<!-- ___________________________________ -->
<!-- <application_name>AppToTest</application_name> -->
<!-- rate (to be filled in by ROS ;) -->
<rate>0</rate>
<!-- LAAT RATE OP 0 STAAN OM FEE AUTOMATISCH TE LATEN BEREKENEN VIA SERVICE BREAKDOWN -->
</activityinfo>
</quickscope>

View File

@ -1,39 +1,75 @@
<?xml version="1.0" encoding="UTF-8"?>
<service_list>
<breakdown xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../dtd/servicebreakdown.xsd">
<service>
<description>Determine and set up attack vectors</description>
<duration in="days">2</duration>
<hourly_rate vat="excl" denomination="eur">1</hourly_rate>
<fee>
<description>Example Service 1: set duration in days and with hourly rate.</description>
<effort in="days">2</effort>
<hourly_rate>10</hourly_rate>
<fee denomination="eur">
<computed/>
</fee>
</service>
<service>
<description>Set up infrastructure and support</description>
<duration in="hours">20</duration>
<hourly_rate vat="excl" denomination="eur">2</hourly_rate>
<fee>
<description>Example Service 2: variable duration with min/max parameters and with hourly
rate.</description>
<effort in="days">
<min>3</min>
<max>4</max>
</effort>
<hourly_rate>10</hourly_rate>
<fee denomination="eur">
<computed/>
</fee>
</service>
<service>
<description>Attacking and reporting</description>
<duration in="days">5</duration>
<hourly_rate vat="excl" denomination="eur">3</hourly_rate>
<fee>
<computed/>
<description>Example Service 3: set duration in days with CUSTOM (non-computed) set
fee.</description>
<effort in="days">5</effort>
<fee denomination="eur">500</fee>
</service>
<service>
<description>Example Service 4: set duration in hours with CUSTOM (non-computed) variable fee
(min/max).</description>
<effort in="hours">4</effort>
<fee denomination="eur">
<min>100</min>
<max>200</max>
</fee>
</service>
<service>
<description>Travel and hotel</description>
<fee vat="excl" denomination="eur">50</fee>
<description>Example Service 5: set duration in days with CUSTOM (non-computed) estimated
fee.</description>
<effort in="hours">4</effort>
<fee denomination="eur" estimate="yes">1000</fee>
</service>
<service>
<description>Optional: presentation of findings</description>
<duration in="days"><min>0</min><max>2</max></duration>
<hourly_rate vat="incl" denomination="eur">100</hourly_rate>
<fee>
<service optional="yes">
<description>Example Service 6: optional service</description>
<effort in="days">
<min>1</min>
<max>2</max>
</effort>
<hourly_rate>50</hourly_rate>
<fee denomination="eur">
<computed/>
</fee>
</service>
</service_list>
<extra>
<description>Example Extra Cost 1: set fee</description>
<fee denomination="eur">1000</fee>
</extra>
<extra>
<description>Example Extra Cost 2: variable min/max fee</description>
<fee denomination="eur">
<min>1000</min>
<max>1200</max>
</fee>
</extra>
<extra>
<description>Example Extra Cost 3: estimated fee</description>
<fee denomination="eur" estimate="yes">600</fee>
</extra>
<extra>
<description>Example Extra Cost 4: with duration</description>
<effort in="days">6</effort>
<fee denomination="eur">600</fee>
</extra>
</breakdown>

View File

@ -6,10 +6,12 @@
</p>
<ul>
<li><company_short/> performs a <p_duration/>-day <company_svc_short/> starting <p_startdate/>.</li>
<li><company_short/> delivers the final report on <p_reportdue/>.</li>
<li><company_short/> delivers the final report on
<p_reportdue/>.</li>
</ul>
<p>
Our fixed-fee price quote for the above described <company_svc_short/> is <p_fee/>.-
Our fixed-fee price quote for the above described <company_svc_short/> is
<p_fee/>
excl. VAT and out-of-pocket expenses.
<company_short/> will send an invoice after the completion of this assignment.
<client_short/> will pay the agreed amount within 14 days of the invoice date.

View File

@ -461,8 +461,8 @@
<xsl:choose>
<xsl:when test="@format = 'list'">
<fo:list-block xsl:use-attribute-sets="list">
<xsl:for-each select="//service_list/service">
<xsl:if test="duration">
<xsl:for-each select="$serviceNodeSet/entry[@type = 'service']">
<xsl:if test="d">
<fo:list-item xsl:use-attribute-sets="li">
<!-- insert a bullet -->
<fo:list-item-label end-indent="label-end()">
@ -473,31 +473,26 @@
<!-- list text -->
<fo:list-item-body start-indent="body-start()">
<fo:block>
<xsl:value-of select="description"/>
<xsl:value-of select="desc"/>
<xsl:text>: </xsl:text>
<xsl:value-of select="duration"/>
<xsl:text> </xsl:text>
<xsl:value-of select="duration/@in"/>
<xsl:value-of select="d"/>
</fo:block>
</fo:list-item-body>
</fo:list-item>
</xsl:if>
</xsl:for-each>
</fo:list-block>
<xsl:call-template name="displayErrorText">
<xsl:with-param name="string">TODO: total!</xsl:with-param>
</xsl:call-template>
</xsl:when>
<xsl:when test="@format = 'table'">
<fo:block>
<fo:table xsl:use-attribute-sets="fwtable borders">
<fo:table-column column-width="proportional-column-width(70)"
<fo:table-column column-width="proportional-column-width(6)"
xsl:use-attribute-sets="borders"/>
<fo:table-column column-width="proportional-column-width(10)"
<fo:table-column column-width="proportional-column-width(2)"
xsl:use-attribute-sets="borders"/>
<fo:table-column column-width="proportional-column-width(10)"
<fo:table-column column-width="proportional-column-width(3)"
xsl:use-attribute-sets="borders"/>
<fo:table-column column-width="proportional-column-width(10)"
<fo:table-column column-width="proportional-column-width(4)"
xsl:use-attribute-sets="borders"/>
<fo:table-body>
<fo:table-row>
@ -505,7 +500,7 @@
<fo:block> Description </fo:block>
</fo:table-cell>
<fo:table-cell xsl:use-attribute-sets="th">
<fo:block> Duration </fo:block>
<fo:block> Effort </fo:block>
</fo:table-cell>
<fo:table-cell xsl:use-attribute-sets="th">
<fo:block> Hourly rate </fo:block>
@ -514,84 +509,107 @@
<fo:block> Fee </fo:block>
</fo:table-cell>
</fo:table-row>
<xsl:for-each select="//service_list/service">
<xsl:for-each select="$serviceNodeSet/entry">
<fo:table-row>
<fo:table-cell xsl:use-attribute-sets="td">
<fo:block>
<xsl:value-of select="description"/>
</fo:block>
</fo:table-cell>
<fo:table-cell xsl:use-attribute-sets="td">
<xsl:choose>
<xsl:when test="duration and duration/@in">
<fo:block>
<xsl:value-of select="duration"/>
<xsl:text> </xsl:text>
<xsl:value-of select="duration/@in"/>
</fo:block>
</xsl:when>
<xsl:otherwise>
<xsl:attribute name="number-columns-spanned"
>2</xsl:attribute>
<fo:block>(flat rate)</fo:block>
</xsl:otherwise>
</xsl:choose>
</fo:table-cell>
<xsl:if test="duration and hourly_rate">
<fo:table-cell xsl:use-attribute-sets="td">
<fo:block>
<xsl:call-template name="getDenomination">
<xsl:with-param name="placeholderElement"
select="hourly_rate"/>
</xsl:call-template>
<xsl:value-of select="hourly_rate"/>
</fo:block>
</fo:table-cell>
<xsl:if test="position() mod 2 != 0">
<xsl:attribute name="background-color"
>#ededed</xsl:attribute>
</xsl:if>
<fo:table-cell xsl:use-attribute-sets="td">
<xsl:if
test="not(normalize-space(d)) and not(normalize-space(h))">
<xsl:attribute name="number-columns-spanned"
>3</xsl:attribute>
</xsl:if>
<fo:block>
<xsl:value-of select="desc"/>
</fo:block>
</fo:table-cell>
<xsl:if test="d">
<fo:table-cell xsl:use-attribute-sets="td">
<fo:block>
<xsl:value-of select="d"/>
</fo:block>
</fo:table-cell>
<xsl:choose>
<xsl:when test="not(fee/computed)">
<!-- hardcoded fee, we'll need a denomination -->
<fo:block xsl:use-attribute-sets="moneycell">
<xsl:when test="normalize-space(h)">
<fo:table-cell xsl:use-attribute-sets="td">
<fo:block text-align="right">
<xsl:call-template name="getDenomination">
<xsl:with-param name="placeholderElement"
select="fee"/>
select="."/>
</xsl:call-template>
<fo:leader leader-pattern="space"/>
<xsl:value-of select="fee"/>
</fo:block>
<xsl:call-template name="prettyMissingDecimal">
<xsl:with-param name="n" select="h"/>
</xsl:call-template>
<xsl:text> excl. VAT</xsl:text>
</fo:block>
</fo:table-cell>
</xsl:when>
<xsl:otherwise>
<!-- computed fee; compute using duration and use hourly rate denomination -->
<fo:block xsl:use-attribute-sets="moneycell">
<xsl:call-template name="getDenomination">
<xsl:with-param name="placeholderElement"
select="hourly_rate"/>
</xsl:call-template>
<fo:leader leader-pattern="space"/>
<xsl:choose>
<xsl:when test="duration/@in = 'hours'">
<!-- multiply with hourly rate -->
<xsl:value-of select="duration * hourly_rate"/>
</xsl:when>
<xsl:when test="duration/@in = 'days'">
<!-- multiply with hourly rate * 8 -->
<xsl:value-of select="duration * hourly_rate * 8"
/>
</xsl:when>
</xsl:choose>
</fo:block>
<fo:table-cell xsl:use-attribute-sets="td">
<fo:block text-align="right">-</fo:block>
</fo:table-cell>
</xsl:otherwise>
</xsl:choose>
</xsl:if>
<fo:table-cell xsl:use-attribute-sets="td">
<fo:block text-align="right">
<xsl:choose>
<xsl:when test="not(f/min = f/max)">
<xsl:call-template name="getDenomination">
<xsl:with-param name="placeholderElement"
select="."/>
</xsl:call-template>
<xsl:value-of select="f/min"/>
<xsl:text> - </xsl:text>
<xsl:call-template name="getDenomination">
<xsl:with-param name="placeholderElement"
select="."/>
</xsl:call-template>
<xsl:call-template name="prettyMissingDecimal">
<xsl:with-param name="n" select="f/max"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="getDenomination">
<xsl:with-param name="placeholderElement"
select="."/>
</xsl:call-template>
<xsl:call-template name="prettyMissingDecimal">
<xsl:with-param name="n" select="f/min"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
<xsl:text> excl. VAT</xsl:text>
<xsl:if test="@estimate = true()">*</xsl:if>
</fo:block>
</fo:table-cell>
</fo:table-row>
</xsl:for-each>
<fo:table-row xsl:use-attribute-sets="totalRow">
<fo:table-cell number-columns-spanned="4"
xsl:use-attribute-sets="td">
<fo:block xsl:use-attribute-sets="totalcell">
<xsl:text>Total</xsl:text>
<xsl:if test="$serviceNodeSet/entry/@estimate">
(estimate)</xsl:if>
<xsl:text>:</xsl:text>
<fo:leader leader-pattern="space"/>
<xsl:call-template name="calculateTotal"/>
<xsl:text> excl. VAT</xsl:text>
</fo:block>
</fo:table-cell>
</fo:table-row>
</fo:table-body>
</fo:table>
</fo:block>
<xsl:call-template name="displayErrorText">
<xsl:with-param name="string">TODO total</xsl:with-param>
</xsl:call-template>
<xsl:if test="$serviceNodeSet/entry/@estimate = true()">
<fo:block text-align="right">
<xsl:text>* Estimate</xsl:text>
</fo:block>
</xsl:if>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="displayErrorText">
@ -602,4 +620,94 @@
</xsl:choose>
</xsl:template>
<xsl:template name="calculateTotal">
<xsl:param name="denoms" tunnel="yes">
<xsl:for-each-group select="$serviceNodeSet/entry" group-by="@denomination">
<denom denomination="{current-grouping-key()}"/>
</xsl:for-each-group>
</xsl:param>
<xsl:variable name="allDenominationsAreEqual" select="count($denoms/denom) = 1"/>
<xsl:variable name="minmaxesPresent"
select="boolean($serviceNodeSet/entry/f/min and $serviceNodeSet/entry/f/max)"/>
<xsl:variable name="estimatePresent" select="$serviceNodeSet/entry/@estimate"/>
<xsl:variable name="totalMinFees" select="sum($serviceNodeSet/entry/f/min)"/>
<xsl:variable name="totalMaxFees" select="sum($serviceNodeSet/entry/f/max)"/>
<xsl:choose>
<xsl:when test="not($totalMinFees = $totalMaxFees)">
<!-- We have different min and max fees, print range -->
<xsl:call-template name="checkDenomination">
<xsl:with-param name="allDenominationsAreEqual"
select="$allDenominationsAreEqual"/>
<xsl:with-param name="denoms" select="$denoms"/>
</xsl:call-template>
<xsl:value-of select="$totalMinFees"/>
<xsl:text> - </xsl:text>
<xsl:call-template name="checkDenomination">
<xsl:with-param name="allDenominationsAreEqual"
select="$allDenominationsAreEqual"/>
<xsl:with-param name="denoms" select="$denoms"/>
</xsl:call-template>
<xsl:call-template name="prettyMissingDecimal">
<xsl:with-param name="n" select="$totalMaxFees"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<!-- Min and max are equal; print single price -->
<xsl:call-template name="checkDenomination">
<xsl:with-param name="allDenominationsAreEqual"
select="$allDenominationsAreEqual"/>
<xsl:with-param name="denoms" select="$denoms"/>
</xsl:call-template>
<xsl:call-template name="prettyMissingDecimal">
<xsl:with-param name="n" select="$totalMinFees"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="checkDenomination">
<xsl:param name="allDenominationsAreEqual"/>
<xsl:param name="denoms"/>
<xsl:choose>
<xsl:when test="$allDenominationsAreEqual">
<xsl:call-template name="getDenomination">
<xsl:with-param name="placeholderElement" select="$denoms/denom"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="displayErrorText">
<xsl:with-param name="string">Cannot print denomination: not all fees in
service_breakdown have an equal denomination (tip: if most services are in
eur but one is in usd, add the usd fee to the description for that service
and use an estimated eur for the hourly rate or fee).</xsl:with-param>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="calculatePersonDays">
<xsl:variable name="totalMinDurations"
select="sum($serviceNodeSet/entry[@type = 'service']/dh/min)"/>
<xsl:variable name="totalMaxDurations"
select="sum($serviceNodeSet/entry[@type = 'service']/dh/max)"/>
<xsl:choose>
<xsl:when test="not($totalMinDurations = $totalMaxDurations)">
<xsl:value-of select="sum($totalMinDurations) div 8"/>
<xsl:text> - </xsl:text>
<xsl:value-of select="sum($totalMaxDurations) div 8"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="sum($totalMinDurations) div 8"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="prettyMissingDecimal">
<xsl:param name="n"/>
<xsl:if test="floor($n) = $n">
<xsl:value-of select="$n"/>
<xsl:text>.-</xsl:text>
</xsl:if>
</xsl:template>
</xsl:stylesheet>

View File

@ -2,15 +2,17 @@
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:my="http://www.radical.sexy"
exclude-result-prefixes="xs my" version="2.0">
<!-- color scheme, just change these to change colors throughout the suite -->
<xsl:variable name="c_main">#e2632a</xsl:variable>
<xsl:variable name="c_support_light">#ededed</xsl:variable>
<xsl:variable name="c_support_subtlydarkerlight">#e4e4e4</xsl:variable><!-- used for subtle light border around support_light background -->
<xsl:variable name="c_support_medium">#999999</xsl:variable><!-- used for subtle light border around support_light background -->
<xsl:variable name="c_support_subtlydarkerlight">#e4e4e4</xsl:variable>
<!-- used for subtle light border around support_light background -->
<xsl:variable name="c_support_medium">#999999</xsl:variable>
<!-- used for subtle light border around support_light background -->
<xsl:variable name="c_support_dark">#444444</xsl:variable>
<xsl:variable name="c_main_contrast">white</xsl:variable>
<xsl:variable name="border-color">#444444</xsl:variable>
<!-- auto numbering format (used in various docs) -->
@ -32,7 +34,7 @@
<xsl:variable name="hourly_fee" select="/contract/meta/contractor/hourly_fee * 1"/>
<xsl:variable name="plannedHours" select="/contract/meta/work/planning/hours * 1"/>
<xsl:variable name="total_fee" select="$hourly_fee * $plannedHours"/>
<!-- current second ('random' seed) -->
<xsl:variable name="current_second" select="ceiling(seconds-from-dateTime(current-dateTime()))"/>
@ -75,7 +77,194 @@
<xsl:variable name="generic_piecolor_20">mediumturquoise</xsl:variable>
<xsl:variable name="generic_piecolor_21">navy</xsl:variable>
<xsl:variable name="generic_piecolor_other">black</xsl:variable>
<xsl:variable name="serviceNodeSet">
<!-- putting the logic for all calculation in this imaginary nodeset; output to fo comes below -->
<xsl:for-each select="//breakdown/service | //breakdown/extra">
<xsl:variable name="minmaxeffortPresent"
select="boolean(effort/min and effort/max)"/>
<xsl:variable name="minmaxFeePresent" select="boolean(fee/min and fee/max)"/>
<xsl:variable name="effortPresent"
select="boolean(normalize-space(effort) and normalize-space(effort/@in))"/>
<xsl:variable name="optional" select="@optional = 'yes'"/>
<entry>
<xsl:attribute name="denomination">
<xsl:value-of select="fee/@denomination"/>
</xsl:attribute>
<xsl:attribute name="estimate">
<xsl:value-of select="fee/@estimate = 'yes'"/>
</xsl:attribute>
<xsl:attribute name="type">
<xsl:value-of select="local-name(.)"/>
</xsl:attribute>
<xsl:attribute name="optional">
<xsl:value-of select="@optional"/>
</xsl:attribute>
<desc>
<xsl:if test="$optional">
<xsl:text>(Optional) </xsl:text>
</xsl:if>
<xsl:value-of select="description"/>
</desc>
<xsl:if test="$effortPresent">
<d>
<xsl:choose>
<xsl:when test="$minmaxeffortPresent">
<!-- Estimated effort -->
<xsl:value-of select="effort/min"/>
<xsl:text>-</xsl:text>
<xsl:value-of select="effort/max"/>
<xsl:text> </xsl:text>
<xsl:value-of select="effort/@in"/>
</xsl:when>
<xsl:otherwise>
<!-- Actual effort -->
<xsl:value-of select="effort"/>
<xsl:text> </xsl:text>
<xsl:value-of select="effort/@in"/>
</xsl:otherwise>
</xsl:choose>
</d>
<dh>
<!-- effort in hours, for calculation of persondays -->
<xsl:choose>
<xsl:when test="$minmaxeffortPresent">
<!-- computed + estimated fee; compute for min and max using effort and use hourly rate denomination -->
<min>
<xsl:choose>
<xsl:when test="$optional">0</xsl:when>
<xsl:when test="effort/@in = 'hours'">
<xsl:value-of select="effort/min"/>
</xsl:when>
<xsl:when test="effort/@in = 'days'">
<xsl:value-of select="effort/min * 8"/>
</xsl:when>
</xsl:choose>
</min>
<max>
<xsl:choose>
<xsl:when test="effort/@in = 'hours'">
<xsl:value-of select="effort/max"/>
</xsl:when>
<xsl:when test="effort/@in = 'days'">
<xsl:value-of select="effort/max * 8"/>
</xsl:when>
</xsl:choose>
</max>
</xsl:when>
<xsl:otherwise>
<min>
<xsl:choose>
<xsl:when test="$optional">0</xsl:when>
<xsl:when test="effort/@in = 'hours'">
<xsl:value-of select="effort"/>
</xsl:when>
<xsl:when test="effort/@in = 'days'">
<xsl:value-of select="effort * 8"/>
</xsl:when>
</xsl:choose>
</min>
<max>
<xsl:choose>
<xsl:when test="effort/@in = 'hours'">
<xsl:value-of select="effort"/>
</xsl:when>
<xsl:when test="effort/@in = 'days'">
<xsl:value-of select="effort * 8"/>
</xsl:when>
</xsl:choose>
</max>
</xsl:otherwise>
</xsl:choose>
</dh>
<h>
<xsl:value-of select="hourly_rate"/>
</h>
</xsl:if>
<f>
<xsl:choose>
<xsl:when test="fee/computed">
<!-- Fee computed; need effort and rate -->
<xsl:choose>
<xsl:when test="not($effortPresent) or not(hourly_rate)">
<xsl:message terminate="yes">ERROR: cannot compute fee for
<xsl:value-of select="local-name(.)"/> "<xsl:value-of
select="description"/>" - effort and/or hourly rate
missing </xsl:message>
</xsl:when>
<xsl:when test="$effortPresent and $minmaxeffortPresent">
<!-- computed + estimated fee; compute for min and max using effort and use hourly rate denomination -->
<min>
<xsl:choose>
<xsl:when test="$optional">0</xsl:when>
<xsl:otherwise>
<xsl:call-template name="computeFee">
<xsl:with-param name="for" select="effort/min"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</min>
<max>
<xsl:call-template name="computeFee">
<xsl:with-param name="for" select="effort/max"/>
</xsl:call-template>
</max>
</xsl:when>
<xsl:otherwise>
<!-- computed fee; compute using effort and use hourly rate denomination -->
<min>
<xsl:choose>
<xsl:when test="$optional">0</xsl:when>
<xsl:otherwise>
<xsl:call-template name="computeFee">
<xsl:with-param name="for" select="effort"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</min>
<max>
<xsl:call-template name="computeFee">
<xsl:with-param name="for" select="effort"/>
</xsl:call-template>
</max>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
<!-- Fee set by user -->
<xsl:choose>
<xsl:when test="$minmaxFeePresent">
<xsl:copy-of select="fee/node()"/>
</xsl:when>
<xsl:otherwise>
<min>
<xsl:copy-of select="fee/text()"/>
</min>
<max>
<xsl:copy-of select="fee/text()"/>
</max>
</xsl:otherwise>
</xsl:choose>
</xsl:otherwise>
</xsl:choose>
</f>
</entry>
</xsl:for-each>
</xsl:variable>
<xsl:template name="computeFee">
<xsl:param name="for"/>
<xsl:choose>
<xsl:when test="effort/@in = 'hours'">
<!-- multiply with hourly rate -->
<xsl:value-of select="$for * hourly_rate"/>
</xsl:when>
<xsl:when test="effort/@in = 'days'">
<!-- multiply with hourly rate * 8 -->
<xsl:value-of select="$for * hourly_rate * 8"/>
</xsl:when>
</xsl:choose>
</xsl:template>
<xsl:template name="selectColor">
<xsl:param name="label"/>
<xsl:param name="position"/>
@ -239,57 +428,11 @@
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<!-- Finding stuff -->
<xsl:variable name="unsortedFindingSummaryTable">
<xsl:for-each-group select="//finding" group-by="@threatLevel">
<xsl:for-each select="current-group()">
<findingEntry>
<xsl:attribute name="Ref">
<xsl:value-of select="@Ref"/>
</xsl:attribute>
<xsl:attribute name="status">
<xsl:value-of select="@status"/>
</xsl:attribute>
<xsl:attribute name="findingId">
<xsl:value-of select="@id"/>
</xsl:attribute>
<findingNumber>
<xsl:apply-templates select="." mode="number"/>
</findingNumber>
<findingType>
<xsl:value-of select="@type"/>
</findingType>
<findingDescription>
<xsl:choose>
<xsl:when test="description_summary">
<xsl:value-of select="description_summary"/>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="description" mode="summarytable"/>
</xsl:otherwise>
</xsl:choose>
</findingDescription>
<findingThreatLevel>
<xsl:value-of select="current-grouping-key()"/>
</findingThreatLevel>
</findingEntry>
</xsl:for-each>
</xsl:for-each-group>
</xsl:variable>
<xsl:variable name="findingSummaryTable">
<xsl:for-each select="$unsortedFindingSummaryTable/findingEntry">
<xsl:sort data-type="number" order="descending"
select="
(number(findingThreatLevel = 'Extreme') * 10)
+ (number(findingThreatLevel = 'High') * 9)
+ (number(findingThreatLevel = 'Elevated') * 8)
+ (number(findingThreatLevel = 'Moderate') * 7)
+ (number(findingThreatLevel = 'Low') * 6)
+ (number(findingThreatLevel = 'Unknown') * 3)
+ (number(findingThreatLevel = 'N/A') * 1)"/>
<xsl:variable name="findingThreatLevelClean"
select="translate(findingThreatLevel, '/', '_')"/>
<xsl:variable name="unsortedFindingSummaryTable">
<xsl:for-each-group select="//finding" group-by="@threatLevel">
<xsl:for-each select="current-group()">
<findingEntry>
<xsl:attribute name="Ref">
<xsl:value-of select="@Ref"/>
@ -298,29 +441,75 @@
<xsl:value-of select="@status"/>
</xsl:attribute>
<xsl:attribute name="findingId">
<xsl:value-of select="@findingId"/>
<xsl:value-of select="@id"/>
</xsl:attribute>
<!-- add an id for the first entry of each type so that we can link to it -->
<xsl:if
test="not(preceding-sibling::findingEntry/findingThreatLevel = findingThreatLevel)">
<xsl:attribute name="id">summaryTableThreatLevel<xsl:value-of
select="$findingThreatLevelClean"/></xsl:attribute>
</xsl:if>
<findingNumber>
<xsl:value-of select="findingNumber"/>
<xsl:apply-templates select="." mode="number"/>
</findingNumber>
<findingType>
<xsl:value-of select="findingType"/>
<xsl:value-of select="@type"/>
</findingType>
<findingDescription>
<xsl:value-of select="findingDescription"/>
<xsl:choose>
<xsl:when test="description_summary">
<xsl:value-of select="description_summary"/>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="description" mode="summarytable"/>
</xsl:otherwise>
</xsl:choose>
</findingDescription>
<findingThreatLevel>
<xsl:value-of select="findingThreatLevel"/>
<xsl:value-of select="current-grouping-key()"/>
</findingThreatLevel>
</findingEntry>
</xsl:for-each>
</xsl:variable>
</xsl:for-each-group>
</xsl:variable>
<xsl:variable name="findingSummaryTable">
<xsl:for-each select="$unsortedFindingSummaryTable/findingEntry">
<xsl:sort data-type="number" order="descending"
select="
(number(findingThreatLevel = 'Extreme') * 10)
+ (number(findingThreatLevel = 'High') * 9)
+ (number(findingThreatLevel = 'Elevated') * 8)
+ (number(findingThreatLevel = 'Moderate') * 7)
+ (number(findingThreatLevel = 'Low') * 6)
+ (number(findingThreatLevel = 'Unknown') * 3)
+ (number(findingThreatLevel = 'N/A') * 1)"/>
<xsl:variable name="findingThreatLevelClean"
select="translate(findingThreatLevel, '/', '_')"/>
<findingEntry>
<xsl:attribute name="Ref">
<xsl:value-of select="@Ref"/>
</xsl:attribute>
<xsl:attribute name="status">
<xsl:value-of select="@status"/>
</xsl:attribute>
<xsl:attribute name="findingId">
<xsl:value-of select="@findingId"/>
</xsl:attribute>
<!-- add an id for the first entry of each type so that we can link to it -->
<xsl:if
test="not(preceding-sibling::findingEntry/findingThreatLevel = findingThreatLevel)">
<xsl:attribute name="id">summaryTableThreatLevel<xsl:value-of
select="$findingThreatLevelClean"/></xsl:attribute>
</xsl:if>
<findingNumber>
<xsl:value-of select="findingNumber"/>
</findingNumber>
<findingType>
<xsl:value-of select="findingType"/>
</findingType>
<findingDescription>
<xsl:value-of select="findingDescription"/>
</findingDescription>
<findingThreatLevel>
<xsl:value-of select="findingThreatLevel"/>
</findingThreatLevel>
</findingEntry>
</xsl:for-each>
</xsl:variable>
<!-- Money stuff -->
<xsl:variable name="eur" select="'eur'"/>
@ -402,7 +591,7 @@
</xsl:otherwise>
</xsl:choose>
</xsl:function>
<xsl:function name="my:calculatePeriod">
<xsl:param name="enddate"/>
<xsl:param name="startdate"/>

View File

@ -189,9 +189,17 @@
</xsl:template>
<xsl:template match="p_persondays">
<xsl:param name="placeholderElement" select="/*/meta/activityinfo/persondays"/>
<xsl:call-template name="checkPlaceholder">
<xsl:with-param name="placeholderElement" select="$placeholderElement"/>
</xsl:call-template>
<xsl:choose>
<xsl:when
test="$placeholderElement = '' or $placeholderElement = '0' or not($placeholderElement)">
<xsl:call-template name="calculatePersonDays"/>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="checkPlaceholder">
<xsl:with-param name="placeholderElement" select="$placeholderElement"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="p_boxtype">
<xsl:param name="placeholderElement" select="/*/meta/activityinfo/type"/>
@ -201,13 +209,21 @@
</xsl:template>
<xsl:template match="p_fee">
<xsl:param name="placeholderElement" select="/*/meta/activityinfo/fee"/>
<xsl:call-template name="getDenomination">
<xsl:with-param name="placeholderElement" select="$placeholderElement"/>
</xsl:call-template>
<xsl:text>&#160;</xsl:text>
<xsl:call-template name="checkPlaceholder">
<xsl:with-param name="placeholderElement" select="$placeholderElement"/>
</xsl:call-template>
<xsl:choose>
<xsl:when
test="$placeholderElement = '' or $placeholderElement = '0' or not($placeholderElement)">
<xsl:call-template name="calculateTotal"/>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="getDenomination">
<xsl:with-param name="placeholderElement" select="$placeholderElement"/>
</xsl:call-template>
<xsl:text>&#160;</xsl:text>
<xsl:call-template name="checkPlaceholder">
<xsl:with-param name="placeholderElement" select="$placeholderElement"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="p_startdate">
<xsl:param name="placeholderElement" select="/*/meta/activityinfo/planning/start"/>
@ -496,17 +512,17 @@
</xsl:when>
<!-- PRETTY FORMATTING FOR DATES -->
<xsl:when
test="(self::contract_end_date or self::contract_start_date or self::generate_raterevisiondate or self::p_startdate or self::p_enddate) and string($placeholderElement) castable as xs:date">
test="(self::contract_end_date or self::contract_start_date or self::generate_raterevisiondate or self::p_startdate or self::p_enddate or self::p_reportdue) and string($placeholderElement) castable as xs:date">
<!-- pretty printing for date -->
<xsl:value-of
select="format-date($placeholderElement, '[MNn] [D1], [Y]', 'en', (), ())"
/>
</xsl:when>
<xsl:when
test="(self::contract_end_date or self::contract_start_date or self::generate_raterevisiondate or self::p_startdate or self::p_enddate) and normalize-space(.) = 'TBD'">
test="(self::contract_end_date or self::contract_start_date or self::generate_raterevisiondate or self::p_startdate or self::p_enddate or self::p_reportdue) and normalize-space(.) = 'TBD'">
<!-- actual TBD, don't mess with it --> TBD </xsl:when>
<xsl:when
test="(self::contract_end_date or self::contract_start_date or self::generate_raterevisiondate or self::p_startdate or self::p_enddate) and not(string($placeholderElement) castable as xs:date)">
test="(self::contract_end_date or self::contract_start_date or self::generate_raterevisiondate or self::p_startdate or self::p_enddate or self::p_reportdue) and not(string($placeholderElement) castable as xs:date)">
<xsl:call-template name="displayErrorText">
<xsl:with-param name="string">TBD</xsl:with-param>
</xsl:call-template>

View File

@ -442,4 +442,7 @@
<xsl:attribute name="start-indent">0</xsl:attribute>
<xsl:attribute name="end-indent">0</xsl:attribute>
</xsl:attribute-set>
<xsl:attribute-set name="totalRow"/>
<xsl:attribute-set name="totalcell"/>
</xsl:stylesheet>

View File

@ -26,4 +26,13 @@
<xsl:attribute-set name="region-body-cover">
</xsl:attribute-set>
<!-- service breakdown -->
<xsl:attribute-set name="totalcell">
<xsl:attribute name="text-align-last">justify</xsl:attribute>
<xsl:attribute name="font-weight">bold</xsl:attribute>
</xsl:attribute-set>
<xsl:attribute-set name="totalRow">
<xsl:attribute name="border-top">1px solid black</xsl:attribute>
</xsl:attribute-set>
</xsl:stylesheet>