From 42af2a594c1f5567614e21b89218dd99a9c4795c Mon Sep 17 00:00:00 2001 From: Mauricio Baeza Date: Thu, 10 Dec 2020 22:20:16 -0600 Subject: [PATCH] Agregar test de timbrado --- source/tests/certificados/comercio.cer | Bin 0 -> 1471 bytes source/tests/certificados/comercio.enc | 30 ++ source/tests/certificados/comercio.key | Bin 0 -> 1298 bytes source/tests/pycert/__init__.py | 3 + source/tests/pycert/cfdi_cert.py | 255 +++++++++++++ source/tests/pycert/conf.py.example | 7 + source/tests/tests_comercio.py | 95 +++++ source/tests/xslt/cadena.xslt | 345 ++++++++++++++++++ source/tests/xslt/comercioexterior11.xslt | 181 ++++++++++ source/tests/xslt/divisas.xslt | 13 + source/tests/xslt/donat11.xslt | 13 + source/tests/xslt/iedu.xslt | 26 ++ source/tests/xslt/implocal.xslt | 39 ++ source/tests/xslt/ine11.xslt | 51 +++ source/tests/xslt/leyendasFisc.xslt | 28 ++ source/tests/xslt/nomina12.xslt | 412 ++++++++++++++++++++++ source/tests/xslt/pagos10.xslt | 165 +++++++++ source/tests/xslt/utilerias.xslt | 22 ++ 18 files changed, 1685 insertions(+) create mode 100644 source/tests/certificados/comercio.cer create mode 100644 source/tests/certificados/comercio.enc create mode 100644 source/tests/certificados/comercio.key create mode 100644 source/tests/pycert/__init__.py create mode 100644 source/tests/pycert/cfdi_cert.py create mode 100644 source/tests/pycert/conf.py.example create mode 100644 source/tests/tests_comercio.py create mode 100644 source/tests/xslt/cadena.xslt create mode 100644 source/tests/xslt/comercioexterior11.xslt create mode 100644 source/tests/xslt/divisas.xslt create mode 100644 source/tests/xslt/donat11.xslt create mode 100644 source/tests/xslt/iedu.xslt create mode 100644 source/tests/xslt/implocal.xslt create mode 100644 source/tests/xslt/ine11.xslt create mode 100644 source/tests/xslt/leyendasFisc.xslt create mode 100644 source/tests/xslt/nomina12.xslt create mode 100644 source/tests/xslt/pagos10.xslt create mode 100644 source/tests/xslt/utilerias.xslt diff --git a/source/tests/certificados/comercio.cer b/source/tests/certificados/comercio.cer new file mode 100644 index 0000000000000000000000000000000000000000..471d7393d808ec3e33fca1d325e1ae6ab2ebf360 GIT binary patch literal 1471 zcmXqLV%=@f#JqR`GZP~dlZdf_fq@|q1Az&MFfuVVG2mt6)N1o+`_9YA$j!=N(8Q>1 z$PW}`4rO8HVRLj=2z3lG)HBcl32^bK2D=7@c{+RgE4a8SIJ)?H`gsP21UUi){1ifh zJe@*A9D_U^4W$euKoTrEhHWJ7;+nMg7|F0Oui9@k_O@+4hN5bvuCJ_qYKErzOE6T&i;mi2K*o?b{-CA z|44sFXGcGnkghO?k)ElZiJpn6p{jv0!kJ9MVnwON1^Ic!iAg!BRtk>JF20VsK))Ht ziSrs-8kiZH8(Nx}7@9m)Y8Df*wEbA*-}AYA;L4z$->gm(9kT< z)x=QFKnA3YRag{7%GW)}H!8@$6eiCtEb3aET$-AbsNkKNTaa3$5L%R;Sdt1%GfK$G zh>?|nxrvb1(e_v9f^w+vo`xb`j=zI-v|F|f(vrY57$DG2V zXJM=_p4{jw;@FqTS1Ki)lj#&JJTd;a_ojG>>>Fw?yR2I(&+!U)@VzRRXlXqo|M#W5 z*Pk;t9G>eG9MWJh5X@Fr*ZZ?uELh)q|LdudZ#-BEQ-$|v+e=RJR=#Z&mo($1vfBRp z>+2R|O_&@m?B@95`K5gImiu}B-#dEdKd3)3Pd}aYeN1AOiBZvt{0)b<|9(@Zm&<&z zXA6Jjooy@46=o_JOmyT7k+{LUvcLXATw2iAgo($EH*~O-egC`X2*2mw$2}Td{X2f` zJd=9;VS#Gq?0w8>ol6D(d+nH=_3ZsgS0-jg2FAs}QEZv-RBVH)Kci zvPMPE5pvOXzff@ZMBRmgP0X$(5g}W2Hr$I|b5*4?=TEXu$u7}jklV79BJ%an0Uu9>c-NS;y2l!A9Mcr zSNUr9yf`l3sX{OG>r6I2d=PxNRnzqAub`XyKVPm|AlBG0u|Q(`#iAz;vuuxYD}E~F zaeEW9W@3rld#T$Y%8ZlNWZekk7Gm zs)4%UQGrDUen;FE%CsE6x5liXu){TH-FpgmR+kO{dbnN zHg7n_w)GnKiA^h?w%pQ^E@$G{S$x?rYC?YOva1(VR73opTz8-I|ID(*>#dkxEu7#h zlhfGTxN3GclS;ux=5QOK@LM-Ugt>fmnJrWGyU)$(b(3@KoWHJck>i?7KgI{PzmCb> li`xG9@vnr4%C!p&B(l#Kdvlpd2F$cNzif*KpM!kqKLCSQ2jTz# literal 0 HcmV?d00001 diff --git a/source/tests/certificados/comercio.enc b/source/tests/certificados/comercio.enc new file mode 100644 index 0000000..e2e9aa4 --- /dev/null +++ b/source/tests/certificados/comercio.enc @@ -0,0 +1,30 @@ +-----BEGIN ENCRYPTED PRIVATE KEY----- +MIIFLTBXBgkqhkiG9w0BBQ0wSjApBgkqhkiG9w0BBQwwHAQI6siSTwKyr/QCAggA +MAwGCCqGSIb3DQIJBQAwHQYJYIZIAWUDBAEqBBCI0ZtyIVL+Lutw1HiX9yiABIIE +0NVK6M/HDydtFkytzQO0x5iZGKZ4rQQOvSaPItX0k/kOUX/fcMEmHvqGs3jE+HgL +I57mW7lxC4cM5mc746p9RQI/FYGZH7t9u3KVdL5+muJ8Khs7GRu7hWK3qFOtfdxY +8VE+1bq+3rd2Cj464An3OVKryUC16szIfTZNXJU6Ftxaq3uSDSJRct8zG4JgTMhj +I+W1XJxUWb+56FI2dJK3MMI8IDR7ctED9XoGBP7lksqqcUmzqolgrWppfcJNoGAF +t5Cz6ZAZShPzhbrkZ7xweMWgHYJlghMcm40D6OTr51l4mxvIOU7vKIIswYZwn1jz +SGfo8icrhsDRpigL5vB4y0asPHFt5AvYWx0hx0CDcxDj71s09svwuSQtTEtQdNDQ +acrffuK2miv6sxXD8DL7+cQ7Q/fdWRhELJ8HRU98YOHVJchutF7LCcAbA/iti195 +YFr10krT5xZyCb/6J33B6UY1LXu94GfmLQA2mdTwucQd0zN5mvmrlG/SXnq5LG36 +dxyXwY4uehLunKWEJu9lX/pdVB7TuNU1sA7411x0hlHi4OepTVgCOsx5nYDWviOa +v02pUPD/ddDtJ45u6cTDGBIeeeo9ZebVUAYz7C4FS1wEspJ/Ux10gC3NPYai7m8T +0HjE5fUXXgeeHI6AGDwzSTFxvLgVYUHGNfvf8Xuz/6/B1JQAxUWslrcI8px2WD0j +xgot2omFbNTZkvKAfn13lZcx8dR0K5qittVFxBwOZkGg+honwzn4TzQp8ZL3E1mQ +2DOgquSlxgT0McUivFTera6OMXMrQSmEbwkuFZh/YN4FE7uhpqB0XKM79v4cmYkD +ze2eX46hG9nVwFXo1jPcVbMuxzwLXmVibvSsTWidqV4CKxyZB9o+B2N00dRe1bh6 +keshRlNWz3drxDCiglKz+BV84OxizWAeCQmBKNqF9umzIM/5/Cg/KnUinG5Vcw52 +5UUiIBGN4a7NQZHtTqTLRYE9vpb/7AkniTQXeQ9ZKUAF1Z+8bkxCTW7Gdmpfku2t ++5SL1qeD3bvUlShBoONJBa21KIsjZsNxEI35n9898xufs4VoNIFzsyhMlcnkoNar +eQ+1rYigmOeKTq3T1grHujFTjVGUe8yYvgoUQjn29LH8zJkypBkL9wmY7/KBb8xK +ZwUguw1y0hYSReMSxKqWThrQwmtkARFu2F0lUbuEXMvDVVpSfNd7w2ij1OP1nwwL +g0q3Sd5d+cYhAGC/FioUL4vFb38DBEjCbUeezc5l8eYNfKrU8JCGSENAv1e756Vu +xb+7mkw/YqL6vMeqq6/S58Naz2IXCM+1iH9KuRS2xqayMCuISbyb/QtzWNnDrTPN +/8qCHO9yijP2/1mQURCnj8lqUbr7nbp9mzuaC+eAaVFEGSfDLx1wV8mFH0rko5Lr +/o5bs/15uCCXxfPWsbViDc+5nCnm0qvLBzUWZfps10CklvcU5Gq5f2VyBrMKyP1X +cQnS6RogrJ6kEYTBc1/VGTTw4RKR6CnCmYNi921stLu9ayMfDroegmEPuM+59+Tn +2Jw2mw/jL0m0stIoAgBEfc4i8a+uabtbD01yJEBnaTomfUUJNckJf3RPZrnDYmGr +lOaDNKIu+f1GcLrahHqbXXVTGVVGqezOUn/IdYubufYw +-----END ENCRYPTED PRIVATE KEY----- diff --git a/source/tests/certificados/comercio.key b/source/tests/certificados/comercio.key new file mode 100644 index 0000000000000000000000000000000000000000..0155f0af4f867893e8a6a85e2be2fc5eec37ed25 GIT binary patch literal 1298 zcmV+t1?~DUf&~sRKn4jahDe6@4FLrWFf%Y41_>&LNQU&4g?4S0RRGm0RaF4 z0tf&w6b1+?hDe6@4Fd-R2rz;KyaE9LFa&}G$aoNWduY^xXu!bLSy7>IndL<$s7kEb=uTxQCw~xbt?E#!>!F0+xGu-}#hK(8zR1g$GxCM)qxpX| zF0rn3gwu>SU@VOUb+=XYB?-Z1;%_?D#yfyjC{c$_*F3+&h)g$HO}>%bxN-HSGWc{; zo@vn%nWB?qTIE$r`uA!s*)%K%Wnk5+MFXb*!x`MI(nb*OstRgyF~9IV!v3C;tqVi^ zi5nb=3tsCnBEH!u#5Z-IeDw*KGUoW;?sES@SJ~7ldpbIdYO{Xjz zkrY@uPCL_lrC5y9eb8mCo|Tv|V{|Ti+i|rV40lKTexvO?`{YfCR*lo5^5q8EX87lM zsY87tv(-|O9cPz<2A1=><>Gx3IOV6krpmL1Rz-Bu(b!fi;)DMt7(*&kvQW}p3g*bk zDRWj_Z;E|IIOuhJMhRzZN0_3|n65Y>$TH8Q1vVdv+}NANQnneKY(W^lH*wc^rY)I>h z4A^`+Ed$cUf?-O7*wu#D9MxUxww8(J#+&ljK}_@VH}%u;@H874NMGnX|Bi9yU8o?`>W!*@td}8)XND)A5`T_eml`w ze-09;Y^2FChKEb_fHAy!!l_MeOeonsbsPgUaV8*MtrMeOTsd>1_xx3Ev-FTU0aYY| zA!82m)MJw%$vTe*)JZhNfMgu&k(d|Ad1e3F@W` zVFvpk4M+u_P4m%BlD)k>;SN_E$B^KoKb*yr5kS82%$s5y6_Qd^>`-O)eC+G2Br%#* zh>F!)1cBO5QP#iNLCKyk;?enRAPUrM;EQ#v)nvtd7#=$XGhm+Mq}GMCOc(fj0-hx~ zG_~YG!too(1Q!w84Pqzl>0ToqiV!PILe-rM65mz#lNQ0JcSgLs*6jR4mkb?I1DBl2 zBAGyl{v9qo)R9oLz(9Bsr{9ypqBK&>8|}d&UUPguB#q@cHPg_TCNioE8*X0js5#^n z*pKv*bPIQE=$Gt>%+llKugAY5evs%$8ZMKpRN=ZMTW;CYwG%Z9GOZMAu;x}P!pS6( z_otyE&0|A+-O$WFB_! literal 0 HcmV?d00001 diff --git a/source/tests/pycert/__init__.py b/source/tests/pycert/__init__.py new file mode 100644 index 0000000..dbe4529 --- /dev/null +++ b/source/tests/pycert/__init__.py @@ -0,0 +1,3 @@ +#!/usr/bin/env python3 + +from .cfdi_cert import SATCertificate diff --git a/source/tests/pycert/cfdi_cert.py b/source/tests/pycert/cfdi_cert.py new file mode 100644 index 0000000..c493b88 --- /dev/null +++ b/source/tests/pycert/cfdi_cert.py @@ -0,0 +1,255 @@ +#!/usr/bin/env python3 + +import argparse +import base64 +import datetime +import getpass +from pathlib import Path + +import xmlsec +from cryptography.hazmat.backends import default_backend +from cryptography.hazmat.primitives import serialization +from cryptography import x509 +from cryptography.x509.oid import NameOID +from cryptography.x509.oid import ExtensionOID +from cryptography.hazmat.primitives import hashes +from cryptography.hazmat.primitives.asymmetric import padding + +from .conf import TOKEN + + +class SATCertificate(object): + + def __init__(self, cer=b'', key=b'', password=''): + self._error = '' + self._init_values() + self._get_data_cer(cer) + self._get_data_key(key, password) + + def _init_values(self): + self._rfc = '' + self._serial_number = '' + self._not_before = None + self._not_after = None + self._is_fiel = False + self._are_couple = False + self._is_valid_time = False + self._cer_pem = '' + self._cer_txt = '' + self._key_enc = b'' + self._p12 = b'' + self._cer_modulus = 0 + self._key_modulus = 0 + return + + def __str__(self): + msg = '\tRFC: {}\n'.format(self.rfc) + msg += '\tNo de Serie: {}\n'.format(self.serial_number) + msg += '\tVálido desde: {}\n'.format(self.not_before) + msg += '\tVálido hasta: {}\n'.format(self.not_after) + msg += '\tEs vigente: {}\n'.format(self.is_valid_time) + msg += '\tSon pareja: {}\n'.format(self.are_couple) + msg += '\tEs FIEL: {}\n'.format(self.is_fiel) + return msg + + def __bool__(self): + return self.is_valid + + def _get_hash(self): + digest = hashes.Hash(hashes.SHA512(), default_backend()) + digest.update(self._rfc.encode()) + digest.update(self._serial_number.encode()) + digest.update(TOKEN.encode()) + return digest.finalize() + + def _get_data_cer(self, cer): + obj = x509.load_der_x509_certificate(cer, default_backend()) + self._rfc = obj.subject.get_attributes_for_oid( + NameOID.X500_UNIQUE_IDENTIFIER)[0].value.split(' ')[0] + self._serial_number = '{0:x}'.format(obj.serial_number)[1::2] + self._not_before = obj.not_valid_before + self._not_after = obj.not_valid_after + now = datetime.datetime.utcnow() + self._is_valid_time = (now > self.not_before) and (now < self.not_after) + if not self._is_valid_time: + msg = 'El certificado no es vigente' + self._error = msg + + self._is_fiel = obj.extensions.get_extension_for_oid( + ExtensionOID.KEY_USAGE).value.key_agreement + + self._cer_pem = obj.public_bytes(serialization.Encoding.PEM).decode() + self._cer_txt = ''.join(self._cer_pem.split('\n')[1:-2]) + self._cer_modulus = obj.public_key().public_numbers().n + return + + def _get_data_key(self, key, password): + self._key_enc = key + if not key or not password: + return + + try: + obj = serialization.load_der_private_key( + key, password.encode(), default_backend()) + except ValueError: + msg = 'La contraseña es incorrecta' + self._error = msg + return + + p = self._get_hash() + self._key_enc = obj.private_bytes( + encoding=serialization.Encoding.PEM, + format=serialization.PrivateFormat.PKCS8, + encryption_algorithm=serialization.BestAvailableEncryption(p) + ) + + self._key_modulus = obj.public_key().public_numbers().n + self._are_couple = self._cer_modulus == self._key_modulus + if not self._are_couple: + msg = 'El CER y el KEY no son pareja' + self._error = msg + return + + def _get_key(self, password): + if not password: + password = self._get_hash() + private_key = serialization.load_pem_private_key( + self._key_enc, password=password, backend=default_backend()) + return private_key + + def _get_key_pem(self): + obj = self._get_key('') + key_pem = obj.private_bytes( + encoding=serialization.Encoding.PEM, + format=serialization.PrivateFormat.PKCS8, + encryption_algorithm=serialization.NoEncryption() + ) + return key_pem + + # Not work + def _get_p12(self): + obj = serialization.pkcs12.serialize_key_and_certificates('test', + self.key_pem, self.cer_pem, None, + encryption_algorithm=serialization.NoEncryption() + ) + return obj + + def sign(self, data, password=''): + private_key = self._get_key(password) + firma = private_key.sign(data, padding.PKCS1v15(), hashes.SHA256()) + return base64.b64encode(firma).decode() + + def sign_xml(self, tree): + node = xmlsec.tree.find_node(tree, xmlsec.constants.NodeSignature) + ctx = xmlsec.SignatureContext() + key = xmlsec.Key.from_memory(self.key_pem, xmlsec.constants.KeyDataFormatPem) + ctx.key = key + ctx.sign(node) + node = xmlsec.tree.find_node(tree, 'X509Certificate') + node.text = self.cer_txt + return tree + + @property + def rfc(self): + return self._rfc + + @property + def serial_number(self): + return self._serial_number + + @property + def not_before(self): + return self._not_before + + @property + def not_after(self): + return self._not_after + + @property + def is_fiel(self): + return self._is_fiel + + @property + def are_couple(self): + return self._are_couple + + @property + def is_valid(self): + return not bool(self.error) + + @property + def is_valid_time(self): + return self._is_valid_time + + @property + def cer_pem(self): + return self._cer_pem.encode() + + @property + def cer_txt(self): + return self._cer_txt + + @property + def key_pem(self): + return self._get_key_pem() + + @property + def key_enc(self): + return self._key_enc + + @property + def p12(self): + return self._get_p12() + + @property + def error(self): + return self._error + + +def main(args): + # ~ contra = getpass.getpass('Introduce la contraseña del archivo KEY: ') + contra = '12345678a' + if not contra.strip(): + msg = 'La contraseña es requerida' + print(msg) + return + + path_cer = Path(args.cer) + path_key = Path(args.key) + + if not path_cer.is_file(): + msg = 'El archivo CER es necesario' + print(msg) + return + + if not path_key.is_file(): + msg = 'El archivo KEY es necesario' + print(msg) + return + + cer = path_cer.read_bytes() + key = path_key.read_bytes() + cert = SATCertificate(cer, key, contra) + + if cert.error: + print(cert.error) + else: + print(cert) + return + + +def _process_command_line_arguments(): + parser = argparse.ArgumentParser(description='CFDI Certificados') + + help = 'Archivo CER' + parser.add_argument('-c', '--cer', help=help, default='') + help = 'Archivo KEY' + parser.add_argument('-k', '--key', help=help, default='') + + args = parser.parse_args() + return args + + +if __name__ == '__main__': + args = _process_command_line_arguments() + main(args) diff --git a/source/tests/pycert/conf.py.example b/source/tests/pycert/conf.py.example new file mode 100644 index 0000000..4e350fb --- /dev/null +++ b/source/tests/pycert/conf.py.example @@ -0,0 +1,7 @@ +#!/usr/bin/env python3 + +# ~ Establece un token personalizado para encriptar las claves +# ~ from secrets import token_hex +# ~ token_hex(32) + +TOKEN = '' diff --git a/source/tests/tests_comercio.py b/source/tests/tests_comercio.py new file mode 100644 index 0000000..831d9ee --- /dev/null +++ b/source/tests/tests_comercio.py @@ -0,0 +1,95 @@ +#!/usr/bin/env python3 + +import datetime +import sys +import unittest +import uuid +import lxml.etree as ET +from io import BytesIO +from pathlib import Path + +sys.path.append('..') +from pycert import SATCertificate +from comerciodigital import PACComercioDigital + + +NAME = 'comercio' + +TEMPLATE_CFDI = """ + + + + + + + + + + + + + + + + + +""" + +class TestCfdi(object): + + def __init__(self): + self._xml = '' + self._make_cfdi() + + @property + def xml(self): + return self._xml.decode() + + def _make_cfdi(self): + path = Path(__file__) + path_cer = Path(path.parent).joinpath('certificados', f'{NAME}.cer') + path_key = Path(path.parent).joinpath('certificados', f'{NAME}.enc') + path_xslt = Path(path.parent).joinpath('xslt', 'cadena.xslt') + cer = path_cer.read_bytes() + key = path_key.read_bytes() + + self._cert = SATCertificate(cer, key) + self._doc = ET.parse(BytesIO(TEMPLATE_CFDI.encode())) + self._root = self._doc.getroot() + self._root.attrib['Fecha'] = datetime.datetime.now().isoformat()[:19] + self._root.attrib['NoCertificado'] = self._cert.serial_number + self._root.attrib['Certificado'] = self._cert.cer_txt + + self._add_stamp(path_xslt) + + self._xml = ET.tostring(self._root, + pretty_print=True, doctype='') + return + + def _add_stamp(self, path_xslt): + xslt = open(path_xslt, 'rb') + transfor = ET.XSLT(ET.parse(xslt)) + cadena = str(transfor(self._doc)).encode() + stamp = self._cert.sign(cadena) + self._root.attrib['Sello'] = stamp + xslt.close() + return + + +class TestStamp(unittest.TestCase): + + def setUp(self): + print(f'In method: {self._testMethodName}') + self.pac = PACComercioDigital() + + def test_cfdi_stamp(self): + cfdi = TestCfdi().xml + result = self.pac.stamp(cfdi) + cfdi_uuid = self.pac.cfdi_uuid + + self.assertFalse(bool(self.pac.error)) + self.assertTrue(bool(uuid.UUID(cfdi_uuid))) + + +if __name__ == '__main__': + unittest.main() diff --git a/source/tests/xslt/cadena.xslt b/source/tests/xslt/cadena.xslt new file mode 100644 index 0000000..4c6e2d5 --- /dev/null +++ b/source/tests/xslt/cadena.xslt @@ -0,0 +1,345 @@ + + + + + + + + + + + + + + + + + + + + + + ||| + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/source/tests/xslt/comercioexterior11.xslt b/source/tests/xslt/comercioexterior11.xslt new file mode 100644 index 0000000..fd71841 --- /dev/null +++ b/source/tests/xslt/comercioexterior11.xslt @@ -0,0 +1,181 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/source/tests/xslt/divisas.xslt b/source/tests/xslt/divisas.xslt new file mode 100644 index 0000000..dc8988e --- /dev/null +++ b/source/tests/xslt/divisas.xslt @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/source/tests/xslt/donat11.xslt b/source/tests/xslt/donat11.xslt new file mode 100644 index 0000000..24d4363 --- /dev/null +++ b/source/tests/xslt/donat11.xslt @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/source/tests/xslt/iedu.xslt b/source/tests/xslt/iedu.xslt new file mode 100644 index 0000000..eb285cb --- /dev/null +++ b/source/tests/xslt/iedu.xslt @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/source/tests/xslt/implocal.xslt b/source/tests/xslt/implocal.xslt new file mode 100644 index 0000000..80b8d23 --- /dev/null +++ b/source/tests/xslt/implocal.xslt @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/source/tests/xslt/ine11.xslt b/source/tests/xslt/ine11.xslt new file mode 100644 index 0000000..05c1e56 --- /dev/null +++ b/source/tests/xslt/ine11.xslt @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/source/tests/xslt/leyendasFisc.xslt b/source/tests/xslt/leyendasFisc.xslt new file mode 100644 index 0000000..e0587a2 --- /dev/null +++ b/source/tests/xslt/leyendasFisc.xslt @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/source/tests/xslt/nomina12.xslt b/source/tests/xslt/nomina12.xslt new file mode 100644 index 0000000..2570170 --- /dev/null +++ b/source/tests/xslt/nomina12.xslt @@ -0,0 +1,412 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/source/tests/xslt/pagos10.xslt b/source/tests/xslt/pagos10.xslt new file mode 100644 index 0000000..98b41f2 --- /dev/null +++ b/source/tests/xslt/pagos10.xslt @@ -0,0 +1,165 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/source/tests/xslt/utilerias.xslt b/source/tests/xslt/utilerias.xslt new file mode 100644 index 0000000..d5dd14e --- /dev/null +++ b/source/tests/xslt/utilerias.xslt @@ -0,0 +1,22 @@ + + + + + + | + + + + + + + + | + + + + + + + +