Pierwowzorem był znaleziony w necie, pewien algorytm napisany w C#, który to w międzyczasie przerobiłem na Javascript (tego użyłem w innym projekcie związanym z PDF).
I tak oto powstał ten szbalon.
<xsl:template name="get-gr">
<xsl:param name="amount"/>
<xsl:variable name="a1" select="floor($amount)"/>
<xsl:variable name="len" select="string-length($a1)"/>
<xsl:variable name="a2" select="substring($a1,$len,1)"/>
<xsl:choose>
<xsl:when test="$a1 = 1"><xsl:value-of select="document('amount-in-words.xml')/amount-in-words/grosze[1]"/></xsl:when>
<xsl:when test="$a2 > 1 and $a2 < 5"><xsl:value-of select="document('amount-in-words.xml')/amount-in-words/grosze[2]"/></xsl:when>
<xsl:otherwise><xsl:value-of select="document('amount-in-words.xml')/amount-in-words/grosze[3]"/></xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="get-zl">
<xsl:param name="amount"/>
<xsl:variable name="a1" select="floor($amount)"/>
<xsl:variable name="len" select="string-length($a1)"/>
<xsl:variable name="a2" select="substring($a1,$len,1)"/>
<xsl:choose>
<xsl:when test="$a1 = 1"><xsl:value-of select="document('amount-in-words.xml')/amount-in-words/zlote[1]"/></xsl:when>
<xsl:when test="$a2 > 1 and $a2 < 5"><xsl:value-of select="document('amount-in-words.xml')/amount-in-words/zlote[2]"/></xsl:when>
<xsl:otherwise><xsl:value-of select="document('amount-in-words.xml')/amount-in-words/zlote[3]"/></xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="get-words">
<xsl:param name="amount"/>
<xsl:variable name="zl" select="floor($amount)"/>
<xsl:variable name="len" select="string-length($zl)"/>
<xsl:if test="$len > 6">
<xsl:variable name="million2" select="substring($zl,$len -6,1)"/>
<xsl:variable name="million">
<xsl:if test="$len > 8"><xsl:value-of select="substring($zl,$len -8,1)"/></xsl:if>
<xsl:if test="$len > 7"><xsl:value-of select="substring($zl,$len -7,1)"/></xsl:if>
<xsl:value-of select="substring($zl,$len -6,1)"/>
</xsl:variable>
<xsl:if test="$million > 1">
<xsl:call-template name="get-words">
<xsl:with-param name="amount" select="$million"/>
</xsl:call-template>
</xsl:if>
<xsl:choose>
<xsl:when test="$million = 1">
<xsl:value-of select="document('amount-in-words.xml')//millions[1]"/>
</xsl:when>
<xsl:when test="$million > 1 and $million < 5">
<xsl:value-of select="document('amount-in-words.xml')//millions[2]"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="document('amount-in-words.xml')//millions[3]"/>
</xsl:otherwise>
</xsl:choose>
</xsl:if>
<xsl:if test="$len > 3">
<xsl:variable name="thousend2" select="substring($zl,$len -3,1)"/>
<xsl:variable name="thousend">
<xsl:if test="$len > 5"><xsl:value-of select="substring($zl,$len -5,1)"/></xsl:if>
<xsl:if test="$len > 4"><xsl:value-of select="substring($zl,$len -4,1)"/></xsl:if>
<xsl:value-of select="substring($zl,$len -3,1)"/>
</xsl:variable>
<xsl:if test="$thousend > 1">
<xsl:call-template name="get-words">
<xsl:with-param name="amount" select="$thousend"/>
</xsl:call-template>
</xsl:if>
<xsl:choose>
<xsl:when test="$thousend = 1">
<xsl:value-of select="document('amount-in-words.xml')//thousends[1]"/>
</xsl:when>
<xsl:when test="$thousend2 > 1 and $thousend2 < 5">
<xsl:value-of select="document('amount-in-words.xml')//thousends[2]"/>
</xsl:when>
<xsl:when test="$thousend = '000' and $len > 6">
<xsl:text></xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="document('amount-in-words.xml')//thousends[3]"/>
</xsl:otherwise>
</xsl:choose>
</xsl:if>
<xsl:if test="$len > 2">
<xsl:if test="substring($zl,$len -2,1) != 0">
<xsl:value-of select="document('amount-in-words.xml')//hundrets[substring($zl,$len -2,1) + 1]"/>
</xsl:if>
</xsl:if>
<xsl:if test="$len > 0">
<xsl:variable name="to99">
<xsl:choose>
<xsl:when test="$len = 1">
<xsl:value-of select="substring($zl,$len,1)"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="substring($zl,$len -1,2)"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:choose>
<xsl:when test="$to99 < 20">
<xsl:choose>
<xsl:when test="substring($to99,1,1) = 0">
<xsl:if test="substring($to99,2,1) != 0">
<xsl:value-of select="document('amount-in-words.xml')//units[substring($to99,2,1) + 1]"/>
</xsl:if>
</xsl:when>
<xsl:otherwise>
<xsl:if test="$to99 != 0">
<xsl:value-of select="document('amount-in-words.xml')//units[$to99 + 1]"/>
</xsl:if>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="document('amount-in-words.xml')//tens[substring($to99,1,1)+1]"/>
<xsl:if test="substring($to99,2,2) != 0">
<xsl:value-of select="document('amount-in-words.xml')//units[substring($to99,2,2) + 1]"/>
</xsl:if>
</xsl:otherwise>
</xsl:choose>
</xsl:if>
<xsl:if test="$zl = 0">
<xsl:value-of select="document('amount-in-words.xml')//units[1]"/>
</xsl:if>
</xsl:template>
<xsl:template name="amount-in-words">
<xsl:param name="amount"/>
<xsl:call-template name="get-words"><xsl:with-param name="amount" select="$amount"/></xsl:call-template>
<xsl:call-template name="get-zl"><xsl:with-param name="amount" select="$amount"/></xsl:call-template>
<xsl:call-template name="get-words"><xsl:with-param name="amount" select="round(($amount - floor($amount))*100)"/></xsl:call-template>
<xsl:call-template name="get-gr"><xsl:with-param name="amount" select="round(($amount - floor($amount))*100)"/></xsl:call-template>
</xsl:template>Powyższy fragment kody należy umieścić w dowolnym miejscu istniejącego szablonu. Dodatkowo w katalogu z szablonem, należy umieścić poniższy plik o nazwie amount-in-words.xml:<?xml version="1.0" encoding="UTF-8"?> <amount-in-words> <grosze>grosz </grosze> <grosze>grosze </grosze> <grosze>groszy </grosze> <zlote>złoty </zlote> <zlote>złote </zlote> <zlote>złotych </zlote> <units>zero </units> <units>jeden </units> <units>dwa </units> <units>trzy </units> <units>cztery </units> <units>pięć </units> <units>sześć </units> <units>siedem </units> <units>osiem </units> <units>dziewięć </units> <units>dziesięć </units> <units>jedenaście </units> <units>dwanaście </units> <units>trzynaście </units> <units>czternaście </units> <units>piętnaście </units> <units>szesnaście </units> <units>siedemnaście </units> <units>osiemnaście </units> <units>dziewiętnaście </units> <tens></tens> <tens>dziesięć </tens> <tens>dwadzieścia </tens> <tens>trzydzieści </tens> <tens>czterdzieści </tens> <tens>pięćdziesiąt </tens> <tens>sześćdziesiąt </tens> <tens>siedemdziesiąt </tens> <tens>osiemdziesiąt </tens> <tens>dziewięćdziesiąt </tens> <hundrets></hundrets> <hundrets>sto </hundrets> <hundrets>dwieście </hundrets> <hundrets>trzysta </hundrets> <hundrets>czterysta </hundrets> <hundrets>pięćset </hundrets> <hundrets>sześćset </hundrets> <hundrets>siedemset </hundrets> <hundrets>osiemset </hundrets> <hundrets>dziewięćset </hundrets> <thousends>tysiąc </thousends> <thousends>tysiące </thousends> <thousends>tysięcy </thousends> <millions>milion </millions> <millions>miliony </millions> <millions>milionów </millions> </amount-in-words>Wywołanie jest proste, polega na wstawieniu poniższego fragmentu w interesującym nas miejscu szblonu:
<xsl:call-template name="amount-in-words"> <xsl:with-param name="amount" select="value"/> </xsl:call-template>Jak na razie, u mnie ma to status beta, jeśli ktoś znajdzie jakieś błędy, zaproponuje poprawki, zapraszam do dyskusji.
1 komentarz:
Niedawno wykorzystałem ten szablon przy generowaniu faktur korygujących i zabrakło w tym szablonie jednej poważnej rzeczy... obsługi wartości ujemnych :)
Stosowną poprawkę już naniosłem w swoim projekcie ale brakuje jej tutaj... przy najbliższej okazji zamieszczę poprawkę...
Prześlij komentarz