xsl-list
[Top] [All Lists]

Re: Total of calculated values from separate templates.

2006-03-04 14:03:55
On Friday 03 March 2006 11:23 am, Neil Williams wrote:

Is it possible to calculate values from other calculated values?

No matter how I arrange it, I cannot get a simple total!

The variables are always out of scope and when I scope them, I can't sum them 
because one or other gets dumped out as NaN and the whole thing is trashed.

From this XML:
(a snippet of a larger file)

<?xml version="1.0" encoding="UTF-8"?>
<qof-qsf xmlns="http://qof.sourceforge.net/";>
  <book count="1">
    <object type="pilot_datebook" count="1">
      <date type="start_time">2005-11-04T09:00:00Z</date>
      <date type="end_time">2005-11-04T17:30:00Z</date>
    </object>
    <object type="pilot_expenses" count="2">
      <string type="type_of_expense">Parking</string>
      <numeric type="expense_amount">160/100</numeric>
      <date type="expense_date">2005-11-04T00:00:00Z</date>
    </object>
    <object type="pilot_expenses" count="3">
      <string type="type_of_expense">Mileage</string>
      <numeric type="expense_amount">4000/100</numeric>
      <date type="expense_date">2005-11-04T00:00:00Z</date>
    </object>
  </book>
</qof-qsf>

I can calculate the duration of the event, multiply that by a default rate
to get an invoice entry and then process the two expenses to create their
own invoice entries: one for parking, one for the mileage, using a default
mileage rate. The numeric string represents amount/denominator.

I can't see how to:
 Generate a total for the entire invoice.

I still can't generate the simplest of totals - let alone subtotals for 
multiple invoices.

basic stylesheet:
<?xml version='1.0'?>
<xsl:stylesheet version="1.1"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
 xmlns:qof-qsf="http://qof.sourceforge.net/";
 xmlns:html="http://www.w3.org/1999/xhtml";
 xmlns:dt="http://xsltsl.org/date-time";
 xmlns:date="http://exslt.org/dates-and-times";
 xmlns:str="http://xsltsl.org/string";>
<xsl:import href="date-time.xsl"/>
<xsl:import href="string.xsl"/>
<xsl:import href="./date/functions/difference/date.difference.xsl" />
<xsl:output method="html"/>

<!-- user configuration  -->
<xsl:param name="mileage-rate">0.3</xsl:param>
<xsl:param name="hourly-rate">20</xsl:param>
<!-- end configuration -->

<xsl:template match="/">
<html lang="en"><head></head><body>
<xsl:text>
</xsl:text>
<xsl:apply-templates
select="/*/qof-qsf:book/qof-qsf:object[(_at_)type='pilot_datebook']"/>
<xsl:apply-templates
select="/*/qof-qsf:book/qof-qsf:object[(_at_)type='pilot_expenses']"/>
<xsl:text>
Total: </xsl:text>

<xsl:text>
</xsl:text>
</body>
</html>
</xsl:template>

<xsl:template
match="/*/qof-qsf:book/qof-qsf:object[(_at_)type='pilot_datebook']">

<xsl:variable name="diff_string">
<xsl:call-template name="date:difference">
   <xsl:with-param name="start" select="qof-qsf:date[(_at_)type='start_time']"
/> <xsl:with-param name="end" select="qof-qsf:date[(_at_)type='end_time']" />
</xsl:call-template>
</xsl:variable>
<xsl:variable name="diff_secs" select="date:seconds($diff_string)"/>
<xsl:value-of select="floor($diff_secs div 3600)"/>
<xsl:text> hours, </xsl:text>
<xsl:value-of select="($diff_secs mod 3600) div 60"/>
<xsl:text> minutes @ </xsl:text>
<xsl:value-of select="format-number($hourly-rate, '######.00')"/>
<xsl:text>/hr = </xsl:text>
<xsl:param name="value">
<xsl:value-of select="number($diff_secs div 3600 * $hourly-rate)"/>
</xsl:param>
<xsl:value-of select="format-number(($value), '#####.00')"/>

<xsl:text>
</xsl:text>
</xsl:template>

<xsl:template
match="/*/qof-qsf:book/qof-qsf:object[(_at_)type='pilot_expenses']"> 
<xsl:param
name="numeric_string" select="qof-qsf:numeric"/>
<xsl:param name="before" select="substring-before($numeric_string, '/')"/>
<xsl:param name="after" select="substring-after($numeric_string, '/')"/>
<xsl:param name="numeric" select="$before div $after"/>

<xsl:param name="type" select="qof-qsf:string[(_at_)type='type_of_expense']"/>
<xsl:choose>
<xsl:when test="$type='Mileage'">
<xsl:param name="miles" select='number($numeric)'/>
<xsl:param name="value" select="(number($miles * $mileage-rate))"/>
<xsl:value-of select="format-number(($miles), '#####.#')"/>
<xsl:text> miles @ </xsl:text>
<xsl:value-of select="format-number($mileage-rate * 100, '##')"/>
<xsl:text>p/mile = </xsl:text>
<xsl:value-of select="format-number(($value), '#####.00')"/>
<xsl:variable name="subtotal">
<span><xsl:value-of select="number($value)"/></span>
</xsl:variable>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$type"/>
<xsl:text> = </xsl:text>
<xsl:param name="value" select='(number($numeric))'/>
<xsl:value-of select="format-number(($value), '#####.00')"/>
<xsl:variable name="subtotal">
<span><xsl:value-of select="number($value)"/></span>
</xsl:variable>
<xsl:text>
</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:template>

</xsl:stylesheet>

Output from the XML above using xsltproc:
<html lang="en">
<head><meta http-equiv="Content-Type" content="text/html;
charset=UTF-8"></head>
<body>
8 hours, 30 minutes @ 20.00/hr = 170.00
Parking = 1.60
40 miles @ 30p/mile = 12.00
Total:
</body>
</html>

What I wanted was:
<html lang="en">
<head><meta http-equiv="Content-Type" content="text/html;
charset=UTF-8"></head>
<body>
8 hours, 30 minutes @ 20.00/hr = 170.00
Parking = 1.60
40 miles @ 30p/mile = 12.00
Total: 183.60
</body>
</html>

Do I have to create an intermediate nodeset/tree? (how?)

:-)

Help!

-- 

Neil Williams
=============
http://www.data-freedom.org/
http://www.nosoftwarepatents.com/
http://www.linux.codehelp.co.uk/


--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--



<Prev in Thread] Current Thread [Next in Thread>