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