├── .gitignore ├── README.rst ├── admin-cfdi ├── admin-cfdi.pyw ├── admincfdi ├── __init__.py ├── bin │ ├── cadena3.2.xslt │ ├── cfdi_3.2.xsd │ ├── cfdi_3.2.xslt │ ├── get_certificado.xslt │ ├── get_sello.xslt │ ├── get_sello_sat.xslt │ ├── iconv.dll │ ├── libeay32.dll │ ├── libexslt.dll │ ├── libxml2.dll │ ├── libxslt.dll │ ├── openssl.exe │ ├── ssleay32.dll │ ├── timbre.xslt │ ├── timbre_1.0.xslt │ ├── xsltproc.exe │ └── zlib1.dll ├── cer_pac │ ├── 00001000000103834451.cer │ ├── 00001000000104731997.cer │ ├── 00001000000104750010.cer │ ├── 00001000000104871381.cer │ ├── 00001000000104888042.cer │ ├── 00001000000200005634.cer │ ├── 00001000000200011997.cer │ ├── 00001000000200365214.cer │ ├── 00001000000200795916.cer │ ├── 00001000000201345662.cer │ ├── 00001000000201345708.cer │ ├── 00001000000201395217.cer │ ├── 00001000000201455572.cer │ ├── 00001000000201614141.cer │ ├── 00001000000201629292.cer │ ├── 00001000000201748120.cer │ ├── 00001000000202241710.cer │ ├── 00001000000202453260.cer │ ├── 00001000000202638162.cer │ ├── 00001000000202639096.cer │ ├── 00001000000202639521.cer │ ├── 00001000000202693892.cer │ ├── 00001000000202695775.cer │ ├── 00001000000202700691.cer │ ├── 00001000000202771790.cer │ ├── 00001000000202772539.cer │ ├── 00001000000202809550.cer │ ├── 00001000000202864285.cer │ ├── 00001000000202864530.cer │ ├── 00001000000202864883.cer │ ├── 00001000000202865018.cer │ ├── 00001000000202905407.cer │ ├── 00001000000203015571.cer │ ├── 00001000000203051706.cer │ ├── 00001000000203082087.cer │ ├── 00001000000203092957.cer │ ├── 00001000000203093174.cer │ ├── 00001000000203159220.cer │ ├── 00001000000203159375.cer │ ├── 00001000000203191015.cer │ ├── 00001000000203220518.cer │ ├── 00001000000203220546.cer │ ├── 00001000000203253077.cer │ ├── 00001000000203285726.cer │ ├── 00001000000203285735.cer │ ├── 00001000000203292609.cer │ ├── 00001000000203312933.cer │ ├── 00001000000203352843.cer │ ├── 00001000000203392777.cer │ ├── 00001000000203430011.cer │ ├── 00001000000203495276.cer │ ├── 00001000000203495475.cer │ ├── 00001000000203631919.cer │ ├── 00001000000300091673.cer │ ├── 00001000000300171291.cer │ ├── 00001000000300171326.cer │ ├── 00001000000300209963.cer │ ├── 00001000000300250292.cer │ ├── 00001000000300392385.cer │ ├── 00001000000300407877.cer │ ├── 00001000000300439968.cer │ ├── 00001000000300494998.cer │ ├── 00001000000300627194.cer │ ├── 00001000000300716418.cer │ ├── 00001000000300716428.cer │ ├── 00001000000300774022.cer │ ├── 00001000000300915978.cer │ ├── 00001000000300969660.cer │ ├── 00001000000301021501.cer │ ├── 00001000000301032322.cer │ ├── 00001000000301062628.cer │ ├── 00001000000301083052.cer │ ├── 00001000000301100488.cer │ ├── 00001000000301160463.cer │ ├── 00001000000301205071.cer │ ├── 00001000000301251152.cer │ ├── 00001000000301280594.cer │ ├── 00001000000301567711.cer │ ├── 00001000000301634628.cer │ ├── 00001000000301751173.cer │ ├── 00001000000301914249.cer │ ├── 00001000000301927035.cer │ ├── 00001000000301949314.cer │ ├── 00001000000304339685.cer │ ├── 00001000000304691381.cer │ └── 20001000000100005868.cer ├── img │ ├── calc.gif │ ├── calc.png │ ├── csv.gif │ ├── csv.png │ ├── delete.gif │ ├── delete.png │ ├── down.gif │ ├── down.png │ ├── exit.gif │ ├── exit.png │ ├── favicon.gif │ ├── favicon.png │ ├── folder.gif │ ├── folder.png │ ├── pdf.gif │ ├── pdf.png │ ├── report.gif │ ├── report.png │ ├── save.gif │ ├── save.png │ ├── xml.gif │ └── xml.png ├── pyutil.py ├── template │ ├── default.csv │ └── plantilla_factura.ods ├── tests │ └── test_pyutil.py ├── ui │ └── mainwindow.ui └── values.py ├── cfdi2pdf ├── cfdi2pdf.cmd ├── contributors.txt ├── descarga-cfdi ├── descarga-cfdi.cmd ├── docs ├── Makefile ├── conf.py ├── devel.rst ├── glosario.rst ├── img │ ├── admin-cfdi-ventana-ppal.png │ └── ejemplo-pdf.png ├── index.rst ├── install.rst ├── intro.rst ├── make.bat ├── reference.rst └── uso.rst ├── functional_DescargaSAT.conf.sample ├── functional_DescargaSAT.py ├── pwd.sample ├── requirements.txt └── setup.py /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | *.ini 3 | *.log 4 | *.swp 5 | ======= 6 | docs/_build 7 | build 8 | dist 9 | Admin_CFDI.egg-info 10 | -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | admin-cfdi 2 | ========== 3 | 4 | :Autores: 5 | Ver archivo contributors.txt 6 | 7 | :Fecha: 8 | 07/12/2015 9 | 10 | :Ultima Versión: 11 | 0.3.0 12 | 13 | 14 | Descripción 15 | ----------- 16 | Administrador de CFDIs / Proyecto de colaboración con PythonCabal_ 17 | 18 | Pequeño sistema para administrar CFDIs; facturas electrónicas de México. Entre sus funcionalidades están: 19 | 20 | * Descarga facturas del SAT, tanto emitidas como recibidas. 21 | * Descarga facturas de correos electrónicos. 22 | * Organiza las facturas en carpetas y las puede renombrar. 23 | * Valida las facturas en el SAT y valida los sellos. 24 | * Generar los PDF de las facturas. 25 | * Reportea directamente de las facturas. 26 | 27 | 28 | Requerimientos 29 | -------------- 30 | * Python 3.2+ 31 | * Tk si usas Linux. Si usas Windows, ya lo integra Python. 32 | * Firefox para la automatización de la descarga del SAT. 33 | * Selenium para la automatización de la descarga del SAT. 34 | * PyGubu para la interfaz gráfica. 35 | * LibreOffice si usas la plantilla ODS. 36 | * Extensiones win32 para Python si usas Windows. 37 | 38 | Instalación 39 | ----------- 40 | Si tienes instalado correctamente Python 3.2+, puedes instalar con Pip. 41 | 42 | GNU & LInux 43 | ########### 44 | 45 | :: 46 | 47 | sudo python setup.py install 48 | admin-cfdi 49 | 50 | 51 | Linux Mint 52 | __________ 53 | 54 | :: 55 | 56 | sudo apt-get install python3-pip python3-tk 57 | sudo python setup.py install 58 | admin-cfdi 59 | 60 | 61 | Windows 62 | ####### 63 | 64 | Si usas Windows, asegúrate de abrir el script con el ejecutable pythonw.exe localizado en la carpeta de instalación de Python. 65 | 66 | :: 67 | 68 | python setup.py install 69 | 70 | 71 | Ligas 72 | ----- 73 | Mauricio Baeza 74 | https://github.com/mauriciobaeza 75 | 76 | PythonCabal 77 | http://wiki.cabal.mx/wiki/PythonCabal 78 | 79 | 80 | .. Links 81 | .. _Mauricio Baeza: https://github.com/mauriciobaeza 82 | .. _PythonCabal: http://wiki.cabal.mx/wiki/PythonCabal 83 | -------------------------------------------------------------------------------- /admin-cfdi.pyw: -------------------------------------------------------------------------------- 1 | import sys 2 | import os.path 3 | 4 | 5 | ac_path = os.path.join(sys.path[0], "admin-cfdi") 6 | exec(open(ac_path, encoding='utf-8').read()) 7 | -------------------------------------------------------------------------------- /admincfdi/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | """Admin CFDI""" 5 | 6 | 7 | __author__ = "PythonCabal" 8 | __author_email__ = "correo@mauriciobaeza.net" 9 | __copyright__ = "Copyright (C) 2015 Universo Libre" 10 | __license__ = "GPL 3.0" 11 | __version__ = "0.2.7" 12 | -------------------------------------------------------------------------------- /admincfdi/bin/cadena3.2.xslt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 25 | 26 | 27 | 28 | | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | ||| 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | 457 | 458 | 459 | 460 | 461 | 464 | 465 | 466 | 467 | 468 | 469 | 470 | 471 | 472 | 473 | 474 | 475 | 476 | 477 | 478 | 479 | 480 | 481 | 482 | 483 | 484 | 485 | 486 | 487 | 488 | 489 | 490 | 491 | 492 | 493 | 494 | 495 | 496 | 497 | 498 | 499 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 509 | 510 | 511 | 512 | 513 | 514 | 515 | 516 | 517 | 518 | 519 | 522 | 523 | 524 | 525 | 526 | 527 | 528 | 529 | 530 | 531 | 532 | 533 | 534 | 535 | 536 | 537 | 538 | 539 | 540 | 541 | 542 | 546 | 547 | 548 | 549 | 550 | 551 | 552 | 553 | 554 | 555 | 556 | 557 | 558 | 559 | 560 | 561 | 562 | 563 | 564 | 565 | 566 | 567 | 568 | 569 | 570 | 571 | 572 | 573 | 574 | 575 | 576 | 577 | 578 | 579 | 580 | 581 | 582 | 583 | 584 | 585 | 586 | 587 | 588 | 589 | 590 | 591 | 592 | 593 | 594 | 595 | 596 | 597 | 598 | 599 | 600 | 601 | 602 | 603 | 604 | 605 | 606 | 607 | 608 | 609 | 610 | 611 | 612 | 613 | 614 | 615 | 616 | 617 | 618 | 619 | 620 | 621 | 622 | 623 | 624 | 625 | 626 | 627 | 628 | 629 | 630 | 631 | 632 | 633 | 634 | 635 | 636 | 637 | 638 | 639 | 640 | 641 | 642 | 643 | 644 | 645 | 646 | 647 | 648 | 649 | 650 | 651 | 652 | 653 | -------------------------------------------------------------------------------- /admincfdi/bin/cfdi_3.2.xslt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 25 | 26 | 27 | 28 | | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | 457 | 458 | 459 | 460 | 461 | 462 | 463 | 464 | 465 | 466 | 467 | 468 | 469 | 470 | 471 | 472 | 473 | 474 | 475 | 476 | 477 | 478 | 479 | 480 | 481 | 482 | 483 | 484 | 485 | 486 | 487 | 488 | 489 | 490 | 491 | 492 | 493 | 494 | 495 | 496 | 497 | 498 | 499 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 509 | 510 | 511 | 512 | 513 | 514 | 515 | ||| 516 | 517 | 518 | 519 | 520 | 521 | 522 | 523 | 524 | 525 | 526 | 527 | 528 | 529 | 530 | 531 | 532 | 533 | 534 | 535 | 536 | 537 | 538 | 539 | 540 | 541 | 542 | 543 | 544 | 545 | 546 | 547 | 548 | 549 | 550 | 551 | 552 | 553 | 554 | 555 | 556 | 557 | 558 | 559 | 560 | 561 | 562 | 563 | 564 | 565 | 566 | 567 | 568 | 569 | 570 | 573 | 574 | 575 | 576 | 577 | 578 | 579 | 580 | 581 | 582 | 583 | 584 | 585 | 586 | 587 | 588 | 591 | 592 | 593 | 594 | 595 | 596 | 597 | 598 | 599 | 600 | 601 | 602 | 603 | 604 | 605 | 606 | 607 | 608 | 609 | 610 | 611 | 612 | 615 | 616 | 617 | 618 | 619 | 620 | 621 | 622 | 623 | 624 | 625 | 626 | 627 | 628 | 629 | 630 | 631 | 632 | 633 | 634 | 635 | 636 | 637 | 638 | 639 | 640 | 641 | 642 | 643 | 644 | 645 | 646 | 647 | 648 | 649 | 650 | 651 | 652 | 653 | 654 | 655 | 656 | 657 | 658 | 659 | 660 | 661 | 662 | 663 | 664 | 665 | 666 | 667 | 668 | 669 | 670 | 673 | 674 | 675 | 676 | 677 | 678 | 679 | 680 | 681 | 682 | 683 | 684 | 685 | 686 | 687 | 688 | 689 | 690 | 691 | 692 | 693 | 697 | 698 | 699 | 700 | 701 | 702 | 703 | 704 | 705 | 706 | 707 | 708 | 709 | 710 | 711 | 712 | 713 | 714 | 715 | 716 | 717 | 718 | 719 | 720 | 721 | 722 | 723 | 724 | 725 | 726 | 727 | 728 | 729 | 730 | 731 | 732 | 733 | 734 | 735 | 736 | 737 | 738 | 739 | 740 | 741 | 742 | 743 | 744 | 745 | 746 | 747 | 748 | 749 | 750 | 751 | 752 | 753 | 754 | 755 | 756 | 757 | 758 | 759 | 760 | 761 | 762 | 763 | 764 | 765 | 766 | 767 | 768 | 769 | 770 | 771 | 772 | 773 | 774 | 775 | 776 | 777 | 778 | 779 | 780 | 781 | 782 | 783 | 784 | 785 | 786 | 787 | 788 | 789 | 790 | 791 | 792 | 793 | 794 | 795 | 796 | 797 | 798 | 799 | 800 | 801 | 802 | 803 | 804 | -------------------------------------------------------------------------------- /admincfdi/bin/get_certificado.xslt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -----BEGIN CERTIFICATE----- 6 | 7 | -----END CERTIFICATE----- 8 | 9 | 10 | 11 | 12 | 13 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /admincfdi/bin/get_sello.xslt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /admincfdi/bin/get_sello_sat.xslt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /admincfdi/bin/iconv.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/bin/iconv.dll -------------------------------------------------------------------------------- /admincfdi/bin/libeay32.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/bin/libeay32.dll -------------------------------------------------------------------------------- /admincfdi/bin/libexslt.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/bin/libexslt.dll -------------------------------------------------------------------------------- /admincfdi/bin/libxml2.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/bin/libxml2.dll -------------------------------------------------------------------------------- /admincfdi/bin/libxslt.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/bin/libxslt.dll -------------------------------------------------------------------------------- /admincfdi/bin/openssl.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/bin/openssl.exe -------------------------------------------------------------------------------- /admincfdi/bin/ssleay32.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/bin/ssleay32.dll -------------------------------------------------------------------------------- /admincfdi/bin/timbre.xslt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | | 5 | 6 | 7 | 8 | 9 | 10 | 11 | ||| 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /admincfdi/bin/timbre_1.0.xslt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | | 5 | 6 | 7 | 8 | 9 | 10 | 11 | ||| 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /admincfdi/bin/xsltproc.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/bin/xsltproc.exe -------------------------------------------------------------------------------- /admincfdi/bin/zlib1.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/bin/zlib1.dll -------------------------------------------------------------------------------- /admincfdi/cer_pac/00001000000103834451.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/cer_pac/00001000000103834451.cer -------------------------------------------------------------------------------- /admincfdi/cer_pac/00001000000104731997.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/cer_pac/00001000000104731997.cer -------------------------------------------------------------------------------- /admincfdi/cer_pac/00001000000104750010.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/cer_pac/00001000000104750010.cer -------------------------------------------------------------------------------- /admincfdi/cer_pac/00001000000104871381.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/cer_pac/00001000000104871381.cer -------------------------------------------------------------------------------- /admincfdi/cer_pac/00001000000104888042.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/cer_pac/00001000000104888042.cer -------------------------------------------------------------------------------- /admincfdi/cer_pac/00001000000200005634.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/cer_pac/00001000000200005634.cer -------------------------------------------------------------------------------- /admincfdi/cer_pac/00001000000200011997.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/cer_pac/00001000000200011997.cer -------------------------------------------------------------------------------- /admincfdi/cer_pac/00001000000200365214.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/cer_pac/00001000000200365214.cer -------------------------------------------------------------------------------- /admincfdi/cer_pac/00001000000200795916.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/cer_pac/00001000000200795916.cer -------------------------------------------------------------------------------- /admincfdi/cer_pac/00001000000201345662.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/cer_pac/00001000000201345662.cer -------------------------------------------------------------------------------- /admincfdi/cer_pac/00001000000201345708.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/cer_pac/00001000000201345708.cer -------------------------------------------------------------------------------- /admincfdi/cer_pac/00001000000201395217.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/cer_pac/00001000000201395217.cer -------------------------------------------------------------------------------- /admincfdi/cer_pac/00001000000201455572.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/cer_pac/00001000000201455572.cer -------------------------------------------------------------------------------- /admincfdi/cer_pac/00001000000201614141.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/cer_pac/00001000000201614141.cer -------------------------------------------------------------------------------- /admincfdi/cer_pac/00001000000201629292.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/cer_pac/00001000000201629292.cer -------------------------------------------------------------------------------- /admincfdi/cer_pac/00001000000201748120.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/cer_pac/00001000000201748120.cer -------------------------------------------------------------------------------- /admincfdi/cer_pac/00001000000202241710.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/cer_pac/00001000000202241710.cer -------------------------------------------------------------------------------- /admincfdi/cer_pac/00001000000202453260.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/cer_pac/00001000000202453260.cer -------------------------------------------------------------------------------- /admincfdi/cer_pac/00001000000202638162.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/cer_pac/00001000000202638162.cer -------------------------------------------------------------------------------- /admincfdi/cer_pac/00001000000202639096.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/cer_pac/00001000000202639096.cer -------------------------------------------------------------------------------- /admincfdi/cer_pac/00001000000202639521.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/cer_pac/00001000000202639521.cer -------------------------------------------------------------------------------- /admincfdi/cer_pac/00001000000202693892.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/cer_pac/00001000000202693892.cer -------------------------------------------------------------------------------- /admincfdi/cer_pac/00001000000202695775.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/cer_pac/00001000000202695775.cer -------------------------------------------------------------------------------- /admincfdi/cer_pac/00001000000202700691.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/cer_pac/00001000000202700691.cer -------------------------------------------------------------------------------- /admincfdi/cer_pac/00001000000202771790.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/cer_pac/00001000000202771790.cer -------------------------------------------------------------------------------- /admincfdi/cer_pac/00001000000202772539.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/cer_pac/00001000000202772539.cer -------------------------------------------------------------------------------- /admincfdi/cer_pac/00001000000202809550.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/cer_pac/00001000000202809550.cer -------------------------------------------------------------------------------- /admincfdi/cer_pac/00001000000202864285.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/cer_pac/00001000000202864285.cer -------------------------------------------------------------------------------- /admincfdi/cer_pac/00001000000202864530.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/cer_pac/00001000000202864530.cer -------------------------------------------------------------------------------- /admincfdi/cer_pac/00001000000202864883.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/cer_pac/00001000000202864883.cer -------------------------------------------------------------------------------- /admincfdi/cer_pac/00001000000202865018.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/cer_pac/00001000000202865018.cer -------------------------------------------------------------------------------- /admincfdi/cer_pac/00001000000202905407.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/cer_pac/00001000000202905407.cer -------------------------------------------------------------------------------- /admincfdi/cer_pac/00001000000203015571.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/cer_pac/00001000000203015571.cer -------------------------------------------------------------------------------- /admincfdi/cer_pac/00001000000203051706.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/cer_pac/00001000000203051706.cer -------------------------------------------------------------------------------- /admincfdi/cer_pac/00001000000203082087.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/cer_pac/00001000000203082087.cer -------------------------------------------------------------------------------- /admincfdi/cer_pac/00001000000203092957.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/cer_pac/00001000000203092957.cer -------------------------------------------------------------------------------- /admincfdi/cer_pac/00001000000203093174.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/cer_pac/00001000000203093174.cer -------------------------------------------------------------------------------- /admincfdi/cer_pac/00001000000203159220.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/cer_pac/00001000000203159220.cer -------------------------------------------------------------------------------- /admincfdi/cer_pac/00001000000203159375.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/cer_pac/00001000000203159375.cer -------------------------------------------------------------------------------- /admincfdi/cer_pac/00001000000203191015.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/cer_pac/00001000000203191015.cer -------------------------------------------------------------------------------- /admincfdi/cer_pac/00001000000203220518.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/cer_pac/00001000000203220518.cer -------------------------------------------------------------------------------- /admincfdi/cer_pac/00001000000203220546.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/cer_pac/00001000000203220546.cer -------------------------------------------------------------------------------- /admincfdi/cer_pac/00001000000203253077.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/cer_pac/00001000000203253077.cer -------------------------------------------------------------------------------- /admincfdi/cer_pac/00001000000203285726.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/cer_pac/00001000000203285726.cer -------------------------------------------------------------------------------- /admincfdi/cer_pac/00001000000203285735.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/cer_pac/00001000000203285735.cer -------------------------------------------------------------------------------- /admincfdi/cer_pac/00001000000203292609.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/cer_pac/00001000000203292609.cer -------------------------------------------------------------------------------- /admincfdi/cer_pac/00001000000203312933.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/cer_pac/00001000000203312933.cer -------------------------------------------------------------------------------- /admincfdi/cer_pac/00001000000203352843.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/cer_pac/00001000000203352843.cer -------------------------------------------------------------------------------- /admincfdi/cer_pac/00001000000203392777.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/cer_pac/00001000000203392777.cer -------------------------------------------------------------------------------- /admincfdi/cer_pac/00001000000203430011.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/cer_pac/00001000000203430011.cer -------------------------------------------------------------------------------- /admincfdi/cer_pac/00001000000203495276.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/cer_pac/00001000000203495276.cer -------------------------------------------------------------------------------- /admincfdi/cer_pac/00001000000203495475.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/cer_pac/00001000000203495475.cer -------------------------------------------------------------------------------- /admincfdi/cer_pac/00001000000203631919.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/cer_pac/00001000000203631919.cer -------------------------------------------------------------------------------- /admincfdi/cer_pac/00001000000300091673.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/cer_pac/00001000000300091673.cer -------------------------------------------------------------------------------- /admincfdi/cer_pac/00001000000300171291.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/cer_pac/00001000000300171291.cer -------------------------------------------------------------------------------- /admincfdi/cer_pac/00001000000300171326.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/cer_pac/00001000000300171326.cer -------------------------------------------------------------------------------- /admincfdi/cer_pac/00001000000300209963.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/cer_pac/00001000000300209963.cer -------------------------------------------------------------------------------- /admincfdi/cer_pac/00001000000300250292.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/cer_pac/00001000000300250292.cer -------------------------------------------------------------------------------- /admincfdi/cer_pac/00001000000300392385.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/cer_pac/00001000000300392385.cer -------------------------------------------------------------------------------- /admincfdi/cer_pac/00001000000300407877.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/cer_pac/00001000000300407877.cer -------------------------------------------------------------------------------- /admincfdi/cer_pac/00001000000300439968.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/cer_pac/00001000000300439968.cer -------------------------------------------------------------------------------- /admincfdi/cer_pac/00001000000300494998.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/cer_pac/00001000000300494998.cer -------------------------------------------------------------------------------- /admincfdi/cer_pac/00001000000300627194.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/cer_pac/00001000000300627194.cer -------------------------------------------------------------------------------- /admincfdi/cer_pac/00001000000300716418.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/cer_pac/00001000000300716418.cer -------------------------------------------------------------------------------- /admincfdi/cer_pac/00001000000300716428.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/cer_pac/00001000000300716428.cer -------------------------------------------------------------------------------- /admincfdi/cer_pac/00001000000300774022.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/cer_pac/00001000000300774022.cer -------------------------------------------------------------------------------- /admincfdi/cer_pac/00001000000300915978.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/cer_pac/00001000000300915978.cer -------------------------------------------------------------------------------- /admincfdi/cer_pac/00001000000300969660.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/cer_pac/00001000000300969660.cer -------------------------------------------------------------------------------- /admincfdi/cer_pac/00001000000301021501.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/cer_pac/00001000000301021501.cer -------------------------------------------------------------------------------- /admincfdi/cer_pac/00001000000301032322.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/cer_pac/00001000000301032322.cer -------------------------------------------------------------------------------- /admincfdi/cer_pac/00001000000301062628.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/cer_pac/00001000000301062628.cer -------------------------------------------------------------------------------- /admincfdi/cer_pac/00001000000301083052.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/cer_pac/00001000000301083052.cer -------------------------------------------------------------------------------- /admincfdi/cer_pac/00001000000301100488.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/cer_pac/00001000000301100488.cer -------------------------------------------------------------------------------- /admincfdi/cer_pac/00001000000301160463.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/cer_pac/00001000000301160463.cer -------------------------------------------------------------------------------- /admincfdi/cer_pac/00001000000301205071.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/cer_pac/00001000000301205071.cer -------------------------------------------------------------------------------- /admincfdi/cer_pac/00001000000301251152.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/cer_pac/00001000000301251152.cer -------------------------------------------------------------------------------- /admincfdi/cer_pac/00001000000301280594.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/cer_pac/00001000000301280594.cer -------------------------------------------------------------------------------- /admincfdi/cer_pac/00001000000301567711.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/cer_pac/00001000000301567711.cer -------------------------------------------------------------------------------- /admincfdi/cer_pac/00001000000301634628.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/cer_pac/00001000000301634628.cer -------------------------------------------------------------------------------- /admincfdi/cer_pac/00001000000301751173.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/cer_pac/00001000000301751173.cer -------------------------------------------------------------------------------- /admincfdi/cer_pac/00001000000301914249.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/cer_pac/00001000000301914249.cer -------------------------------------------------------------------------------- /admincfdi/cer_pac/00001000000301927035.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/cer_pac/00001000000301927035.cer -------------------------------------------------------------------------------- /admincfdi/cer_pac/00001000000301949314.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/cer_pac/00001000000301949314.cer -------------------------------------------------------------------------------- /admincfdi/cer_pac/00001000000304339685.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/cer_pac/00001000000304339685.cer -------------------------------------------------------------------------------- /admincfdi/cer_pac/00001000000304691381.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/cer_pac/00001000000304691381.cer -------------------------------------------------------------------------------- /admincfdi/cer_pac/20001000000100005868.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/cer_pac/20001000000100005868.cer -------------------------------------------------------------------------------- /admincfdi/img/calc.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/img/calc.gif -------------------------------------------------------------------------------- /admincfdi/img/calc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/img/calc.png -------------------------------------------------------------------------------- /admincfdi/img/csv.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/img/csv.gif -------------------------------------------------------------------------------- /admincfdi/img/csv.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/img/csv.png -------------------------------------------------------------------------------- /admincfdi/img/delete.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/img/delete.gif -------------------------------------------------------------------------------- /admincfdi/img/delete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/img/delete.png -------------------------------------------------------------------------------- /admincfdi/img/down.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/img/down.gif -------------------------------------------------------------------------------- /admincfdi/img/down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/img/down.png -------------------------------------------------------------------------------- /admincfdi/img/exit.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/img/exit.gif -------------------------------------------------------------------------------- /admincfdi/img/exit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/img/exit.png -------------------------------------------------------------------------------- /admincfdi/img/favicon.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/img/favicon.gif -------------------------------------------------------------------------------- /admincfdi/img/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/img/favicon.png -------------------------------------------------------------------------------- /admincfdi/img/folder.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/img/folder.gif -------------------------------------------------------------------------------- /admincfdi/img/folder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/img/folder.png -------------------------------------------------------------------------------- /admincfdi/img/pdf.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/img/pdf.gif -------------------------------------------------------------------------------- /admincfdi/img/pdf.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/img/pdf.png -------------------------------------------------------------------------------- /admincfdi/img/report.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/img/report.gif -------------------------------------------------------------------------------- /admincfdi/img/report.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/img/report.png -------------------------------------------------------------------------------- /admincfdi/img/save.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/img/save.gif -------------------------------------------------------------------------------- /admincfdi/img/save.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/img/save.png -------------------------------------------------------------------------------- /admincfdi/img/xml.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/img/xml.gif -------------------------------------------------------------------------------- /admincfdi/img/xml.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/img/xml.png -------------------------------------------------------------------------------- /admincfdi/template/default.csv: -------------------------------------------------------------------------------- 1 | 'headers','x','y','w','h','font','size','style','foreground','background','align','priority','multiline','border', 'text' 2 | 'emisor_logo',30,5,35,30,'',0,'',0,0,'',0,0,'' 3 | 'emisor_nombre',85,5,100,4,'Helvetica',10,'B',6291456,14803425,'C',0,0,'0','' 4 | 'emisor_rfc',85,9,100,4,'Helvetica',10,'B',6291456,14803425,'C',0,0,'0','' 5 | 'emisor_direccion1',85,13,100,4,'Helvetica',9,'B',0,0,'C',0,0,'0','' 6 | 'emisor_direccion2',85,17,100,4,'Helvetica',9,'B',0,0,'C',0,0,'0','' 7 | 'emisor_direccion3',85,21,100,4,'Helvetica',9,'B',0,0,'C',0,0,'0','' 8 | 'emisor_direccion4',85,25,100,4,'Helvetica',9,'B',0,0,'C',0,0,'0','' 9 | 'expedido_titulo',130,5,75,4,'Helvetica',7,'B',6291456,14803425,'C',0,0,'0','Expedido En' 10 | 'expedido_direccion1',130,9,75,4,'Helvetica',8,'B',0,0,'C',0,0,'0','' 11 | 'expedido_direccion2',130,13,75,4,'Helvetica',8,'B',0,0,'C',0,0,'0','' 12 | 'expedido_direccion3',130,17,75,4,'Helvetica',8,'B',0,0,'C',0,0,'0','' 13 | 'expedido_direccion4',130,21,75,4,'Helvetica',8,'B',0,0,'C',0,0,'0','' 14 | 'receptor_titulo',10,40,100,4,'Helvetica',7,'B',6291456,14803425,'C',0,0,'0','Receptor' 15 | 'receptor_nombre',15,45,95,4,'Helvetica',10,'B',6291456,0,'L',0,0,'0','' 16 | 'receptor_rfc',15,49,95,4,'Helvetica',10,'B',6291456,0,'L',0,0,'0','' 17 | 'receptor_direccion1',15,53,100,4,'Helvetica',9,'B',0,0,'L',0,0,'0','' 18 | 'receptor_direccion2',15,57,100,4,'Helvetica',9,'B',0,0,'L',0,0,'0','' 19 | 'receptor_direccion3',15,61,100,4,'Helvetica',9,'B',0,0,'L',0,0,'0','' 20 | 'receptor_direccion4',15,65,100,4,'Helvetica',8,'B',0,0,'L',0,0,'0','' 21 | 'cfdi_titulo',120,40,85,4,'Helvetica',7,'B',6291456,14803425,'C',0,0,'0','' 22 | 'cfdi_fecha',10,35,170,4,'Helvetica',8,'',0,0,'R',0,0,'0','' 23 | 'cfdi_hora',180,35,20,4,'Helvetica',6,'B',0,0,'R',0,0,'0','' 24 | 'cfdi_titulo1',120,44,30,4,'Helvetica',7,'B',6291456,14803425,'R',0,0,'0','Serie CSD Emisor' 25 | 'cfdi_titulo2',120,48,30,4,'Helvetica',7,'B',6291456,14803425,'R',0,0,'0','' 26 | 'cfdi_titulo3',120,52,30,4,'Helvetica',7,'B',6291456,14803425,'R',0,0,'0','' 27 | 'cfdi_titulo4',120,56,30,4,'Helvetica',7,'B',6291456,14803425,'R',0,0,'0','Tipo de Comprobante' 28 | 'cfdi_titulo5',120,60,30,4,'Helvetica',7,'B',6291456,14803425,'R',0,0,'0','Folio' 29 | 'cfdi_regimen',120,64,85,4,'Helvetica',7,'B',6291456,14803425,'C',0,0,'0','' 30 | 'cfdi_csd',150,44,55,4,'Helvetica',7,'',0,0,'C',0,0,'0','' 31 | 'cfdi_csdsat',150,48,55,4,'Helvetica',7,'',0,0,'C',0,0,'0','' 32 | 'cfdi_uuid',150,52,55,4,'Helvetica',7,'',0,0,'C',0,0,'0','' 33 | 'cfdi_tipo',150,56,55,4,'Helvetica',7,'',0,0,'C',0,0,'0','' 34 | 'cfdi_folio',150,60,55,4,'Helvetica',12,'B',16711680,0,'C',0,0,'0','' 35 | 'clave_titulo',10,70,20,3,'Helvetica',7,'B',6291456,14803425,'C',0,0,'R','Clave' 36 | 'descripcion_titulo',30,70,85,3,'Helvetica',7,'B',6291456,14803425,'C',0,0,'R','Descripcion' 37 | 'unidad_titulo',115,70,15,3,'Helvetica',7,'B',6291456,14803425,'C',0,0,'R','Unidad' 38 | 'cantidad_titulo',130,70,20,3,'Helvetica',7,'B',6291456,14803425,'C',0,0,'R','Cantidad' 39 | 'pu_titulo',150,70,25,3,'Helvetica',7,'B',6291456,14803425,'C',0,0,'R','Valor Unitario' 40 | 'importe_titulo',175,70,30,3,'Helvetica',7,'B',6291456,14803425,'C',0,0,'','Importe' 41 | 'clave',10,73,20,3,'Helvetica',7,'',0,0,'C',0,0,'T','Sin' 42 | 'descripcion',30,73,85,3,'Helvetica',7,'',0,0,'J',0,1,'T','' 43 | 'unidad',115,73,15,3,'Helvetica',7,'',0,0,'C',0,0,'T','' 44 | 'cantidad',130,73,20,3,'Helvetica',7,'',0,0,'R',0,0,'T','' 45 | 'pu',150,73,25,3,'Helvetica',7,'',0,0,'R',0,0,'T','' 46 | 'importe',175,73,30,3,'Helvetica',7,'',0,0,'R',0,0,'T','' 47 | 'subtotal_titulo',150,0,25,4,'Helvetica',8,'B',6291456,14803425,'R',0,0,'0','Subtotal' 48 | 'subtotal',175,0,30,4,'Helvetica',8,'B',0,0,'R',0,0,'0','' 49 | 'motivo_titulo',10,0,40,4,'Helvetica',8,'B',6291456,14803425,'R',0,0,'0','Motivo del descuento' 50 | 'motivo_descuento',50,0,95,4,'Helvetica',8,'',0,0,'L',0,0,'0','' 51 | 'imp_tras_titulo',10,0,40,4,'Helvetica',8,'B',6291456,14803425,'R',0,0,'0','Total impuestos trasladados' 52 | 'imp_rete_titulo',80,0,40,4,'Helvetica',8,'B',6291456,14803425,'R',0,0,'0','Total impuestos retenidos' 53 | 'imp_trasladado',50,0,25,4,'Helvetica',8,'B',0,0,'R',0,0,'0','' 54 | 'imp_retenido',120,0,25,4,'Helvetica',8,'B',0,0,'R',0,0,'0','' 55 | 'en_letras',10,0,195,4,'Helvetica',7,'B',0,0,'C',0,0,'0','' 56 | 'otros_titulo',10,0,25,3,'Helvetica',7,'B',6291456,14803425,'R',0,0,'0','' 57 | 'otros',35,0,40,3,'Helvetica',7,'',0,0,'L',0,0,'0','' 58 | 'dona_aut_titulo',10,0,40,4,'Helvetica',8,'B',6291456,14803425,'R',0,0,'0','No. Autorizacion' 59 | 'dona_fecha_titulo',80,0,40,4,'Helvetica',8,'B',6291456,14803425,'R',0,0,'0','Fecha de Autorizacion' 60 | 'dona_aut',50,0,25,4,'Helvetica',8,'B',0,0,'L',0,0,'0','' 61 | 'dona_fecha',120,0,25,4,'Helvetica',8,'B',0,0,'L',0,0,'0','' 62 | 'dona_leyenda',10,0,195,4,'Helvetica',6,'',6291456,14803425,'J',0,0,'0','' 63 | 'fiscal1_titulo',10,0,40,4,'Helvetica',8,'B',6291456,14803425,'R',0,0,'0','Disposicion Fiscal' 64 | 'fiscal2_titulo',80,0,40,4,'Helvetica',8,'B',6291456,14803425,'R',0,0,'0','Norma' 65 | 'fiscal1',50,0,25,4,'Helvetica',8,'B',0,0,'C',0,0,'0','' 66 | 'fiscal2',120,0,85,4,'Helvetica',8,'B',0,0,'L',0,0,'0','' 67 | 'fiscal_leyenda',10,0,195,4,'Helvetica',6,'',6291456,14803425,'J',0,1,'0','' 68 | 'qr_cbb',10,0,30,30,'',0,'',0,0,'',0,0,'' 69 | 'sello_cfd_titulo',45,0,160,4,'Helvetica',6,'B',0,0,'L',0,0,'0','Sello Digital del CFD' 70 | 'sello_cfd',45,0,160,4,'Helvetica',6,'',6291456,14803425,'J',0,1,'0','' 71 | 'sello_sat_titulo',45,0,160,4,'Helvetica',6,'B',0,0,'L',0,0,'0','Sello del SAT' 72 | 'sello_sat',45,0,160,4,'Helvetica',6,'',6291456,14803425,'J',0,1,'0','' 73 | 'fecha_titulo',45,0,35,4,'Helvetica',6,'B',0,0,'L',0,0,'0','Fecha y hora de certificacion:' 74 | 'fecha',80,0,50,4,'Helvetica',6,'',0,0,'L',0,0,'0','' 75 | 'cadena_titulo',10,0,195,4,'Helvetica',6,'B',0,0,'L',0,0,'0','Cadena original del complemento de certificacion digital del SAT' 76 | 'cadena',10,0,195,4,'Helvetica',6,'',6291456,14803425,'J',0,1,'0','' 77 | 'leyenda',65.5,0,80,4,'Helvetica',6,'',6291456,14803425,'C',0,0,'0','Este documento es una representacion impresa de CFD' -------------------------------------------------------------------------------- /admincfdi/template/plantilla_factura.ods: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/admincfdi/template/plantilla_factura.ods -------------------------------------------------------------------------------- /admincfdi/tests/test_pyutil.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | 3 | 4 | class LeeCredenciales(unittest.TestCase): 5 | 6 | def setUp(self): 7 | from unittest.mock import Mock 8 | from admincfdi import pyutil 9 | 10 | self.onefile = Mock() 11 | self.onefile.readline.return_value = 'rfc pwd' 12 | pyutil.open = Mock(return_value=self.onefile) 13 | 14 | def tearDown(self): 15 | from admincfdi import pyutil 16 | 17 | del pyutil.open 18 | 19 | def test_file_not_found(self): 20 | from admincfdi import pyutil 21 | 22 | pyutil.open.side_effect = FileNotFoundError 23 | util = pyutil.Util() 24 | status, rfc, pwd = util.lee_credenciales('ruta') 25 | self.assertEqual('Archivo no encontrado: ruta', status) 26 | 27 | def test_not_two_fields(self): 28 | from admincfdi import pyutil 29 | 30 | self.onefile.readline.return_value = '' 31 | util = pyutil.Util() 32 | status, rfc, pwd = util.lee_credenciales('ruta') 33 | self.assertEqual('No contiene dos campos: ruta', status) 34 | 35 | def test_success(self): 36 | from admincfdi import pyutil 37 | 38 | util = pyutil.Util() 39 | status, rfc, pwd = util.lee_credenciales('ruta') 40 | self.assertEqual('Ok', status) 41 | 42 | def test_surplus_whitespace_is_ok(self): 43 | from admincfdi import pyutil 44 | 45 | self.onefile.readline.return_value = ' \t rfc \t pwd \r\n' 46 | util = pyutil.Util() 47 | status, rfc, pwd = util.lee_credenciales('ruta') 48 | self.assertEqual('rfc', rfc) 49 | self.assertEqual('pwd', pwd) 50 | 51 | 52 | class DescargaSAT(unittest.TestCase): 53 | 54 | def setUp(self): 55 | import time 56 | from unittest.mock import Mock 57 | from selenium import webdriver 58 | from admincfdi import pyutil 59 | 60 | self.webdriver = pyutil.webdriver 61 | pyutil.webdriver = Mock() 62 | pyutil.webdriver.FirefoxProfile = webdriver.FirefoxProfile 63 | 64 | self.WebDriverWait = pyutil.WebDriverWait 65 | self.wait = Mock() 66 | pyutil.WebDriverWait = Mock(return_value=self.wait) 67 | 68 | self.sleep = time.sleep 69 | time.sleep = Mock() 70 | 71 | self.status = Mock() 72 | self.transfer = Mock() 73 | 74 | pyutil.print = Mock() 75 | 76 | def tearDown(self): 77 | import time 78 | from admincfdi import pyutil 79 | 80 | pyutil.webdriver = self.webdriver 81 | pyutil.WebDriverWait = self.WebDriverWait 82 | time.sleep = self.sleep 83 | del pyutil.print 84 | 85 | def test_get_firefox_profile(self): 86 | from admincfdi.pyutil import DescargaSAT 87 | from selenium import webdriver 88 | 89 | descarga = DescargaSAT() 90 | profile = descarga.get_firefox_profile('carpeta_destino') 91 | self.assertIsInstance(profile, webdriver.FirefoxProfile) 92 | 93 | def test_connect(self): 94 | from admincfdi.pyutil import DescargaSAT 95 | from selenium import webdriver 96 | 97 | profile = webdriver.FirefoxProfile() 98 | descarga = DescargaSAT(status_callback=self.status) 99 | profile = descarga.connect(profile, rfc='x', ciec='y') 100 | self.assertEqual(3, self.status.call_count) 101 | 102 | def test_connect_fail(self): 103 | from unittest.mock import Mock 104 | from admincfdi.pyutil import DescargaSAT 105 | from admincfdi.pyutil import WebDriverWait 106 | from selenium import webdriver 107 | from selenium.common.exceptions import TimeoutException 108 | 109 | self.wait.until.side_effect = TimeoutException 110 | profile = webdriver.FirefoxProfile() 111 | descarga = DescargaSAT(status_callback=self.status) 112 | profile = descarga.connect(profile, rfc='x', ciec='y') 113 | self.assertRaises(TimeoutException) 114 | 115 | def test_disconnect_not_connected(self): 116 | from admincfdi.pyutil import DescargaSAT 117 | from selenium import webdriver 118 | 119 | descarga = DescargaSAT(status_callback=self.status) 120 | descarga.disconnect() 121 | self.assertEqual(0, self.status.call_count) 122 | 123 | def test_disconnect(self): 124 | from unittest.mock import Mock 125 | from admincfdi.pyutil import DescargaSAT 126 | from selenium import webdriver 127 | 128 | descarga = DescargaSAT(status_callback=self.status) 129 | descarga.browser = Mock() 130 | descarga.disconnect() 131 | self.assertEqual(2, self.status.call_count) 132 | 133 | def test_search_not_connected(self): 134 | from admincfdi.pyutil import DescargaSAT 135 | from selenium import webdriver 136 | 137 | profile = webdriver.FirefoxProfile() 138 | descarga = DescargaSAT(status_callback=self.status) 139 | results = descarga.search(uuid='uuid') 140 | self.assertEqual(0, len(results)) 141 | 142 | def test_search_uuid(self): 143 | from unittest.mock import MagicMock 144 | from admincfdi.pyutil import DescargaSAT 145 | from selenium import webdriver 146 | 147 | profile = webdriver.FirefoxProfile() 148 | descarga = DescargaSAT(status_callback=self.status) 149 | descarga.browser = MagicMock() 150 | results = descarga.search(uuid='uuid', día='00') 151 | self.assertEqual(0, len(results)) 152 | 153 | def test_search_facturas_emitidas(self): 154 | from unittest.mock import MagicMock 155 | from admincfdi.pyutil import DescargaSAT 156 | from selenium import webdriver 157 | 158 | profile = webdriver.FirefoxProfile() 159 | descarga = DescargaSAT(status_callback=self.status) 160 | descarga.browser = MagicMock() 161 | results = descarga.search(facturas_emitidas=True, 162 | año=1, mes=1) 163 | self.assertEqual(0, len(results)) 164 | 165 | def test_search_rfc_emisor(self): 166 | from unittest.mock import MagicMock 167 | from admincfdi.pyutil import DescargaSAT 168 | from selenium import webdriver 169 | 170 | profile = webdriver.FirefoxProfile() 171 | descarga = DescargaSAT(status_callback=self.status) 172 | descarga.browser = MagicMock() 173 | results = descarga.search(rfc_emisor='x') 174 | self.assertEqual(0, len(results)) 175 | 176 | def test_search_not_found(self): 177 | from unittest.mock import MagicMock 178 | from admincfdi.pyutil import DescargaSAT 179 | from selenium import webdriver 180 | 181 | profile = webdriver.FirefoxProfile() 182 | descarga = DescargaSAT(status_callback=self.status) 183 | descarga.g.SAT['found'] = 'no' 184 | descarga.browser = MagicMock() 185 | c = MagicMock() 186 | descarga.browser.find_elements_by_class_name.return_value = [c] 187 | c.get_attribute.return_value = 'x no x' 188 | c.is_displayed.return_value = True 189 | results = descarga.search() 190 | self.assertEqual(0, len(results)) 191 | 192 | def test_search_not_found_exception(self): 193 | from unittest.mock import MagicMock 194 | from admincfdi.pyutil import DescargaSAT 195 | from selenium import webdriver 196 | 197 | profile = webdriver.FirefoxProfile() 198 | descarga = DescargaSAT(status_callback=self.status) 199 | descarga.browser = MagicMock() 200 | c = MagicMock() 201 | descarga.browser.find_elements_by_class_name.side_effect = Exception() 202 | results = descarga.search() 203 | self.assertEqual(0, len(results)) 204 | 205 | def test_search_mes_eq_día(self): 206 | from unittest.mock import MagicMock 207 | from admincfdi.pyutil import DescargaSAT 208 | from selenium import webdriver 209 | 210 | profile = webdriver.FirefoxProfile() 211 | descarga = DescargaSAT(status_callback=self.status) 212 | descarga.browser = MagicMock() 213 | link = MagicMock() 214 | descarga.browser.find_elements_by_link_text.return_value = [link] 215 | combo = descarga.browser.find_element_by_id.return_value 216 | combo.get_attribute.return_value = 'sb' 217 | r = link.find_element_by_xpath.return_value 218 | p = r.find_element_by_xpath.return_value 219 | p.get_attribute.return_value = 'sb2' 220 | results = descarga.search(día='01', mes='01') 221 | self.assertEqual(0, len(results)) 222 | 223 | def test_search_minuto_final_cero(self): 224 | from unittest.mock import MagicMock 225 | from admincfdi.pyutil import DescargaSAT 226 | from selenium import webdriver 227 | 228 | profile = webdriver.FirefoxProfile() 229 | descarga = DescargaSAT(status_callback=self.status) 230 | descarga.browser = MagicMock() 231 | results = descarga.search(día='01', mes='02', minuto_final='0') 232 | 233 | expected = "document.getElementById('ctl00_MainContent_CldFecha_DdlMinutoFin').value='0';" 234 | descarga.browser.execute_script.assert_any_call(expected) 235 | 236 | def test_search_mes_completo_por_día(self): 237 | from unittest.mock import MagicMock, Mock 238 | from admincfdi.pyutil import DescargaSAT 239 | from selenium import webdriver 240 | 241 | profile = webdriver.FirefoxProfile() 242 | descarga = DescargaSAT(status_callback=self.status) 243 | descarga.browser = MagicMock() 244 | descarga._download_sat_month = Mock(return_value=[]) 245 | results = descarga.search(día='00', 246 | mes_completo_por_día=True) 247 | self.assertEqual(0, len(results)) 248 | 249 | def test_search_mes_ne_día(self): 250 | from unittest.mock import MagicMock 251 | from admincfdi.pyutil import DescargaSAT 252 | from selenium import webdriver 253 | 254 | profile = webdriver.FirefoxProfile() 255 | descarga = DescargaSAT(status_callback=self.status) 256 | descarga.browser = MagicMock() 257 | results = descarga.search(día='01', mes='02') 258 | self.assertEqual(0, len(results)) 259 | 260 | def test_download(self): 261 | from unittest.mock import MagicMock 262 | from admincfdi.pyutil import DescargaSAT 263 | from selenium import webdriver 264 | 265 | profile = webdriver.FirefoxProfile() 266 | descarga = DescargaSAT(status_callback=self.status, 267 | download_callback=self.transfer) 268 | descarga.browser = MagicMock() 269 | docs = [MagicMock()] 270 | descarga.download(docs) 271 | 272 | 273 | if __name__ == '__main__': 274 | unittest.main() 275 | -------------------------------------------------------------------------------- /admincfdi/values.py: -------------------------------------------------------------------------------- 1 | #! 2 | # -*- coding: utf-8 -*- 3 | 4 | # This program is free software; you can redistribute it and/or modify 5 | # it under the terms of the GNU General Public License as published by the 6 | # Free Software Foundation; either version 3, or (at your option) any later 7 | # version. 8 | # 9 | # This program is distributed in the hope that it will be useful, but 10 | # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY 11 | # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 | # for more details. 13 | 14 | import os 15 | import sys 16 | import logging 17 | import logging.config 18 | 19 | 20 | class Global(object): 21 | DEBUG = False 22 | WIN = 'win32' 23 | OS = sys.platform 24 | MAIN = 'mainwindow' 25 | TITLE = 'Admin CFDI - Factura Libre' 26 | CWD = os.path.dirname(__file__) 27 | PATHS = { 28 | 'current': CWD, 29 | 'img': os.path.join(CWD, 'img'), 30 | 'ui': os.path.join(CWD, 'ui'), 31 | 'OPENSSL': 'openssl', 32 | 'XSLTPROC': 'xsltproc', 33 | 'CER': os.path.join(CWD, 'cer_pac'), 34 | 'BIN': os.path.join(CWD, 'bin'), 35 | 'XSLT_CER': os.path.join(CWD, 'bin', 'get_certificado.xslt'), 36 | 'XSLT_SELLO': os.path.join(CWD, 'bin', 'get_sello.xslt'), 37 | 'XSLT_SELLO_SAT': os.path.join(CWD, 'bin', 'get_sello_sat.xslt'), 38 | 'XSLT_CADENA': os.path.join(CWD, 'bin', 'cfdi_{}.xslt'), 39 | 'XSLT_TIMBRE': os.path.join(CWD, 'bin', 'timbre_1.0.xslt'), 40 | 'TEMPLATE': os.path.join(CWD, 'template'), 41 | 'USER': os.path.expanduser('~') 42 | } 43 | SCRIPTS = { 44 | 'CFDI2PDF': os.path.abspath(os.path.join(CWD, '..', 'cfdi2pdf')), 45 | } 46 | EXT_XML = '.xml' 47 | EXT_ODS = '.ods' 48 | EXT_CSV = '.csv' 49 | EXT_PDF = '.pdf' 50 | EXT_JSON = '.json' 51 | EXT_CER = '.cer' 52 | EXT_EXE = '.exe' 53 | if OS == WIN: 54 | PATHS['XSLTPROC'] = os.path.join( 55 | PATHS['BIN'], PATHS['XSLTPROC'] + EXT_EXE) 56 | PATHS['OPENSSL'] = os.path.join( 57 | PATHS['BIN'], PATHS['OPENSSL'] + EXT_EXE) 58 | FILES = { 59 | 'main': os.path.join(PATHS['ui'], 'mainwindow.ui'), 60 | 'config': os.path.join(PATHS['ui'], 'config.ini'), 61 | 'log': os.path.join(PATHS['USER'], 'admincfdi.log'), 62 | } 63 | FILE_NAME = '{serie}{folio:06d}_{fecha}_{receptor_rfc}' 64 | CADENA = '||{version}|{UUID}|{FechaTimbrado}|{selloCFD}|{noCertificadoSAT}||' 65 | CELL_TYPE = 'ScCellObj' 66 | LIMIT_MARGIN = 23000 67 | CLEAN = "\{(\w.+)\}" 68 | PESO = ('mxn', 'mxp', 'm.n.', 'p', 'mn', 'pmx', 'mex') 69 | DOLAR = ('dólar', 'dólares', 'dolar', 'dolares', 'usd') 70 | ICON = os.path.join(PATHS['img'], 'favicon.png') 71 | YEAR_INIT = 2011 72 | FIELDS_REPORT = '{UUID}|{serie}|{folio}|{emisor_rfc}|{emisor_nombre}|' \ 73 | '{receptor_rfc}|{receptor_nombre}|{fecha}|{FechaTimbrado}|' \ 74 | '{tipoDeComprobante}|{Moneda}|{TipoCambio}|{subTotal}|' \ 75 | '{totalImpuestosTrasladados}|{total}' 76 | FIELDS_CURRENCY = ( 77 | 'TipoCambio', 78 | 'subTotal', 79 | 'totalImpuestosTrasladados', 80 | 'totalImpuestosRetenidos', 81 | 'total', 82 | 'descuento') 83 | COLORS = { 84 | 'FOCUS_IN': '#ffffca', 85 | 'FOCUS_OUT': '#ffffff', 86 | 'DEFAULT': '#d9d9d9', 87 | } 88 | CONTROLS = { 89 | 'button_save_emisor': { 90 | 'width': 100, 91 | }, 92 | 'button_delete_emisor': { 93 | 'width': 100, 94 | }, 95 | 'button_download_sat': { 96 | 'width': 100, 97 | }, 98 | 'button_exit': { 99 | 'width': 100, 100 | }, 101 | 'button_save_mail_server': { 102 | 'width': 100, 103 | }, 104 | 'button_delete_mail_server': { 105 | 'width': 100, 106 | }, 107 | 'button_download_mail': { 108 | 'width': 100, 109 | }, 110 | 'button_organizate_xml': { 111 | 'width': 100, 112 | }, 113 | 'button_generate_pdf': { 114 | 'width': 100, 115 | }, 116 | 'button_generate_report': { 117 | 'width': 120, 118 | }, 119 | 'button_save_xml_user': { 120 | 'width': 100, 121 | }, 122 | 'button_delete_xml_user': { 123 | 'width': 100, 124 | }, 125 | 'button_save_pdf_user': { 126 | 'width': 100, 127 | }, 128 | 'button_delete_pdf_user': { 129 | 'width': 100, 130 | }, 131 | 'button_save_report_user': { 132 | 'width': 100, 133 | }, 134 | 'button_delete_report_user': { 135 | 'width': 100, 136 | }, 137 | 'button_save_report_title': { 138 | 'width': 100, 139 | }, 140 | 'button_delete_report_title': { 141 | 'width': 100, 142 | }, 143 | 144 | } 145 | PREFIX = { 146 | '2.0': '{http://www.sat.gob.mx/cfd/2}', 147 | '2.2': '{http://www.sat.gob.mx/cfd/2}', 148 | '3.0': '{http://www.sat.gob.mx/cfd/3}', 149 | '3.2': '{http://www.sat.gob.mx/cfd/3}', 150 | 'TIMBRE': '{http://www.sat.gob.mx/TimbreFiscalDigital}', 151 | 'NOMINA': '{http://www.sat.gob.mx/nomina}', 152 | 'IMP_LOCAL': '{http://www.sat.gob.mx/implocal}', 153 | 'IEDU': '{http://www.sat.gob.mx/iedu}', 154 | 'DONATARIA': '{http://www.sat.gob.mx/donat}', 155 | 'LEYENDAS': '{http://www.sat.gob.mx/leyendasFiscales}', 156 | } 157 | page_init = 'https://cfdiau.sat.gob.mx/nidp/app/login?id=SATUPCFDiCon&' \ 158 | 'sid=0&option=credential&sid=0' 159 | page_cfdi = 'https://portalcfdi.facturaelectronica.sat.gob.mx/{}' 160 | SAT = { 161 | 'ftp': 'ftp2.sat.gob.mx', 162 | 'folder': '/Certificados/FEA', 163 | 'form_login': 'IDPLogin', 164 | 'user': 'Ecom_User_ID', 165 | 'password': 'Ecom_Password', 166 | 'date': 'ctl00_MainContent_RdoFechas', 167 | 'date_from': 'ctl00_MainContent_CldFechaInicial2_Calendario_text', 168 | 'date_from_name': 'ctl00$MainContent$CldFechaInicial2$Calendario_text', 169 | 'date_to': 'ctl00_MainContent_CldFechaFinal2_Calendario_text', 170 | 'date_to_name': 'ctl00$MainContent$CldFechaFinal2$Calendario_text', 171 | 'year': 'DdlAnio', 172 | 'month': 'ctl00_MainContent_CldFecha_DdlMes', 173 | 'day': 'ctl00_MainContent_CldFecha_DdlDia', 174 | 'hour': 'ctl00_MainContent_CldFechaFinal2_DdlHora', 175 | 'minute': 'ctl00_MainContent_CldFechaFinal2_DdlMinuto', 176 | 'second': 'ctl00_MainContent_CldFechaFinal2_DdlSegundo', 177 | 'submit': 'ctl00_MainContent_BtnBusqueda', 178 | 'download': 'BtnDescarga', 179 | 'emisor': 'ctl00_MainContent_TxtRfcReceptor', 180 | 'receptor': 'ctl00_MainContent_TxtRfcReceptor', 181 | 'uuid': 'ctl00_MainContent_TxtUUID', 182 | 'combos': 'sbToggle_{}', 183 | 'found': 'No existen registros que cumplan con los criterios de', 184 | 'subtitle': 'subtitle', 185 | 'page_init': page_init, 186 | 'page_cfdi': page_cfdi, 187 | 'page_receptor': page_cfdi.format('ConsultaReceptor.aspx'), 188 | 'page_emisor': page_cfdi.format('ConsultaEmisor.aspx'), 189 | 'resultados': 'ctl00_MainContent_PnlResultados', 190 | 'noresultados': 'ctl00_MainContent_PnlNoResultados', 191 | 'start_hour': 'ctl00_MainContent_CldFecha_DdlHora', 192 | 'start_minute': 'ctl00_MainContent_CldFecha_DdlMinuto', 193 | 'start_second': 'ctl00_MainContent_CldFecha_DdlSegundo', 194 | 'end_hour': 'ctl00_MainContent_CldFecha_DdlHoraFin', 195 | 'end_minute': 'ctl00_MainContent_CldFecha_DdlMinutoFin', 196 | 'end_second': 'ctl00_MainContent_CldFecha_DdlSegundoFin', 197 | } 198 | 199 | frm_1 = '%(asctime)s - %(levelname)s - %(lineno)s - %(message)s' 200 | CONF_LOG = { 201 | 'version': 1, 202 | 'disable_existing_loggers': False, 203 | 'handlers': { 204 | 'to_file': { 205 | 'class': 'logging.FileHandler', 206 | 'formatter': 'myFormat', 207 | 'filename': FILES['log'] 208 | }, 209 | 'to_screen': { 210 | 'class': 'logging.StreamHandler', 211 | 'formatter': 'myFormat', 212 | }, 213 | }, 214 | 'loggers': { 215 | 'AdminCFDI':{ 216 | 'handlers': ['to_file'], 217 | 'level': 'ERROR', 218 | }, 219 | 'AdminCFDI_screen':{ 220 | 'handlers': ['to_screen'], 221 | 'level': 'DEBUG', 222 | 'propagate': True, 223 | }, 224 | }, 225 | 'formatters': { 226 | 'myFormat': { 227 | 'format': frm_1, 228 | 'datefmt': '%d-%b-%Y %H:%M:%S' 229 | } 230 | } 231 | } 232 | logging.config.dictConfig(CONF_LOG) 233 | if DEBUG: 234 | LOG = logging.getLogger('AdminCFDI_screen') 235 | else: 236 | LOG = logging.getLogger('AdminCFDI') 237 | -------------------------------------------------------------------------------- /cfdi2pdf: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import argparse 3 | import sys 4 | 5 | from admincfdi.pyutil import CSVPDF 6 | from admincfdi.pyutil import Util 7 | 8 | def process_command_line_arguments(): 9 | parser = argparse.ArgumentParser( 10 | description='Crea un PDF desde una plantilla CSV') 11 | 12 | help = 'Archivo XML origen.' 13 | parser.add_argument('-a', '--archivo-xml', help=help, default='') 14 | 15 | help = 'Directorio origen.' 16 | parser.add_argument('-o', '--directorio-origen', help=help, default='') 17 | 18 | help = 'Directorio destino.' 19 | parser.add_argument('-d', '--directorio-destino', help=help, default='') 20 | 21 | help = 'Plantilla CSV.' 22 | parser.add_argument('-p', '--plantilla', help=help, default='') 23 | 24 | args = parser.parse_args() 25 | return args 26 | 27 | 28 | def main(): 29 | ext_pdf = '.pdf' 30 | args = process_command_line_arguments() 31 | util = Util() 32 | 33 | if args.archivo_xml and util.exists(args.archivo_xml): 34 | if args.directorio_destino: 35 | info = util.get_path_info(args.archivo_xml) 36 | path_pdf = util.join(args.directorio_destino, info[0][len(args.directorio_origen)+1:]) 37 | util.makedirs(path_pdf) 38 | path_pdf = util.join(path_pdf, info[2] + ext_pdf) 39 | else: 40 | path_pdf = util.replace_extension(args.archivo_xml, ext_pdf) 41 | pdf = CSVPDF(args.archivo_xml, args.plantilla) 42 | if pdf.xml: 43 | pdf.make_pdf() 44 | pdf.output(path_pdf, 'F') 45 | sys.exit(0) 46 | if args.directorio_origen: 47 | files = util.get_files(args.directorio_origen) 48 | for f in files: 49 | path_pdf = util.replace_extension(f, ext_pdf) 50 | pdf = CSVPDF(f, args.plantilla) 51 | if pdf.xml: 52 | pdf.make_pdf() 53 | pdf.output(path_pdf, 'F') 54 | 55 | if __name__ == '__main__': 56 | main() 57 | -------------------------------------------------------------------------------- /cfdi2pdf.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | set PYTHONIOENCODING=utf-8 3 | set c2p_path="%~d0\%~p0cfdi2pdf" 4 | py %c2p_path% %* 5 | -------------------------------------------------------------------------------- /contributors.txt: -------------------------------------------------------------------------------- 1 | Mauricio Baeza 2 | Miguel Trujillo 3 | Patricio Paez 4 | Sergio Gutierrez 5 | Jonathan Lopez 6 | -------------------------------------------------------------------------------- /descarga-cfdi: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | #! coding: utf-8 3 | 4 | # This program is free software; you can redistribute it and/or modify 5 | # it under the terms of the GNU General Public License as published by the 6 | # Free Software Foundation; either version 3, or (at your option) any later 7 | # version. 8 | # 9 | # This program is distributed in the hope that it will be useful, but 10 | # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY 11 | # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 | # for more details. 13 | 14 | 15 | import argparse 16 | import time 17 | import datetime 18 | import os 19 | import getpass 20 | import sys 21 | 22 | from admincfdi.pyutil import DescargaSAT 23 | from admincfdi.pyutil import Util 24 | 25 | 26 | def process_command_line_arguments(): 27 | parser = argparse.ArgumentParser(description='Descarga CFDIs del SAT a una carpeta local') 28 | 29 | default_archivo_credenciales = 'credenciales.conf' 30 | help = 'Archivo con credenciales para el SAT. ' \ 31 | 'RFC y CIEC en el primer renglón y ' \ 32 | 'separadas por un espacio. ' \ 33 | 'El predeterminado es %(default)s' 34 | parser.add_argument('--archivo-de-credenciales', 35 | help=help, default=default_archivo_credenciales) 36 | 37 | help = 'Solicitar credenciales para el SAT al inicio. ' 38 | parser.add_argument('--solicitar-credenciales', 39 | action='store_const', const=True, 40 | help=help, default=False) 41 | 42 | home_path = os.environ.get('HOME') 43 | if not home_path: 44 | home_path = os.environ.get('HOMEPATH', '') 45 | default_carpeta_destino = os.path.join( 46 | home_path, 'cfdi-descarga') 47 | help = 'Carpeta local para guardar los CFDIs descargados ' \ 48 | 'El predeterminado es %(default)s' 49 | parser.add_argument('--carpeta-destino', 50 | help=help, default=default_carpeta_destino) 51 | 52 | help = 'Descargar facturas emitidas. ' \ 53 | 'Por omisión se descargan facturas recibidas' 54 | parser.add_argument('--facturas-emitidas', 55 | action='store_const', const=True, 56 | help=help, default=False) 57 | 58 | help = 'UUID. Por omisión no se usa en la búsqueda. ' \ 59 | 'Esta opción tiene precedencia sobre las demás ' \ 60 | 'opciones de búsqueda.' 61 | parser.add_argument('--uuid', 62 | help=help, default='') 63 | 64 | help = 'RFC del emisor. Por omisión no se usa en la búsqueda.' 65 | parser.add_argument('--rfc-emisor', 66 | help=help, default='') 67 | 68 | today = datetime.date.today() 69 | help = 'Año. El valor por omisión es el año en curso' 70 | parser.add_argument('--año', 71 | help=help, default=str(today.year)) 72 | 73 | help = 'Mes. El valor por omisión es el mes en curso' 74 | parser.add_argument('--mes', 75 | help=help, default='{:02d}'.format(today.month)) 76 | 77 | help = 'Día. Por omisión no se usa en la búsqueda.' 78 | parser.add_argument('--día', 79 | help=help, default='00') 80 | 81 | help = 'Hora inicial. Por omisión es 0.' 82 | parser.add_argument('--hora-inicial', 83 | help=help, default='0') 84 | 85 | help = 'Minuto inicial. Por omisión es 0.' 86 | parser.add_argument('--minuto-inicial', 87 | help=help, default='0') 88 | 89 | help = 'Segundo inicial. Por omisión es 0.' 90 | parser.add_argument('--segundo-inicial', 91 | help=help, default='0') 92 | 93 | help = 'Hora final. Por omisión es 23.' 94 | parser.add_argument('--hora-final', 95 | help=help, default='23') 96 | 97 | help = 'Minuto final. Por omisión es 59.' 98 | parser.add_argument('--minuto-final', 99 | help=help, default='59') 100 | 101 | help = 'Segundo final. Por omisión es 59.' 102 | parser.add_argument('--segundo-final', 103 | help=help, default='59') 104 | 105 | help = 'Mes completo por día. Por omisión no se usa en la búsqueda.' 106 | parser.add_argument('--mes-completo-por-día', action='store_const', const=True, 107 | help=help, default=False) 108 | 109 | args=parser.parse_args() 110 | return args 111 | 112 | def main(): 113 | 114 | args = process_command_line_arguments() 115 | if args.solicitar_credenciales: 116 | rfc = input('RFC: ') 117 | pwd = getpass.getpass('CIEC: ') 118 | else: 119 | util = Util() 120 | status, rfc, pwd = util.lee_credenciales(args.archivo_de_credenciales) 121 | if status != 'Ok': 122 | print(status) 123 | sys.exit(1) 124 | descarga = DescargaSAT() 125 | profile = descarga.get_firefox_profile(args.carpeta_destino) 126 | try: 127 | descarga.connect(profile, rfc=rfc, ciec=pwd) 128 | docs = descarga.search(facturas_emitidas= args.facturas_emitidas, 129 | uuid=args.uuid, 130 | rfc_emisor=args.rfc_emisor, 131 | año=args.año, 132 | mes=args.mes, 133 | día=args.día, 134 | hora_inicial=args.hora_inicial, 135 | minuto_inicial=args.minuto_inicial, 136 | segundo_inicial=args.segundo_inicial, 137 | hora_final=args.hora_final, 138 | minuto_final=args.minuto_final, 139 | segundo_final=args.segundo_final, 140 | mes_completo_por_día=args.mes_completo_por_día) 141 | descarga.download(docs) 142 | except Exception as e: 143 | print (e) 144 | finally: 145 | descarga.disconnect() 146 | 147 | 148 | if __name__ == '__main__': 149 | main() 150 | -------------------------------------------------------------------------------- /descarga-cfdi.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | set PYTHONIOENCODING=utf-8 3 | set dc_path="%~d0\%~p0descarga-cfdi" 4 | py %dc_path% %* 5 | -------------------------------------------------------------------------------- /docs/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line. 5 | SPHINXOPTS = 6 | SPHINXBUILD = sphinx-build 7 | PAPER = 8 | BUILDDIR = _build 9 | 10 | # User-friendly check for sphinx-build 11 | ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1) 12 | $(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/) 13 | endif 14 | 15 | # Internal variables. 16 | PAPEROPT_a4 = -D latex_paper_size=a4 17 | PAPEROPT_letter = -D latex_paper_size=letter 18 | ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . 19 | # the i18n builder cannot share the environment and doctrees with the others 20 | I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . 21 | 22 | .PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext 23 | 24 | help: 25 | @echo "Please use \`make ' where is one of" 26 | @echo " html to make standalone HTML files" 27 | @echo " dirhtml to make HTML files named index.html in directories" 28 | @echo " singlehtml to make a single large HTML file" 29 | @echo " pickle to make pickle files" 30 | @echo " json to make JSON files" 31 | @echo " htmlhelp to make HTML files and a HTML help project" 32 | @echo " qthelp to make HTML files and a qthelp project" 33 | @echo " devhelp to make HTML files and a Devhelp project" 34 | @echo " epub to make an epub" 35 | @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" 36 | @echo " latexpdf to make LaTeX files and run them through pdflatex" 37 | @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx" 38 | @echo " text to make text files" 39 | @echo " man to make manual pages" 40 | @echo " texinfo to make Texinfo files" 41 | @echo " info to make Texinfo files and run them through makeinfo" 42 | @echo " gettext to make PO message catalogs" 43 | @echo " changes to make an overview of all changed/added/deprecated items" 44 | @echo " xml to make Docutils-native XML files" 45 | @echo " pseudoxml to make pseudoxml-XML files for display purposes" 46 | @echo " linkcheck to check all external links for integrity" 47 | @echo " doctest to run all doctests embedded in the documentation (if enabled)" 48 | 49 | clean: 50 | rm -rf $(BUILDDIR)/* 51 | 52 | html: 53 | $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html 54 | @echo 55 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." 56 | 57 | dirhtml: 58 | $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml 59 | @echo 60 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." 61 | 62 | singlehtml: 63 | $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml 64 | @echo 65 | @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." 66 | 67 | pickle: 68 | $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle 69 | @echo 70 | @echo "Build finished; now you can process the pickle files." 71 | 72 | json: 73 | $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json 74 | @echo 75 | @echo "Build finished; now you can process the JSON files." 76 | 77 | htmlhelp: 78 | $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp 79 | @echo 80 | @echo "Build finished; now you can run HTML Help Workshop with the" \ 81 | ".hhp project file in $(BUILDDIR)/htmlhelp." 82 | 83 | qthelp: 84 | $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp 85 | @echo 86 | @echo "Build finished; now you can run "qcollectiongenerator" with the" \ 87 | ".qhcp project file in $(BUILDDIR)/qthelp, like this:" 88 | @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/admin-cfdi.qhcp" 89 | @echo "To view the help file:" 90 | @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/admin-cfdi.qhc" 91 | 92 | devhelp: 93 | $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp 94 | @echo 95 | @echo "Build finished." 96 | @echo "To view the help file:" 97 | @echo "# mkdir -p $$HOME/.local/share/devhelp/admin-cfdi" 98 | @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/admin-cfdi" 99 | @echo "# devhelp" 100 | 101 | epub: 102 | $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub 103 | @echo 104 | @echo "Build finished. The epub file is in $(BUILDDIR)/epub." 105 | 106 | latex: 107 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex 108 | @echo 109 | @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." 110 | @echo "Run \`make' in that directory to run these through (pdf)latex" \ 111 | "(use \`make latexpdf' here to do that automatically)." 112 | 113 | latexpdf: 114 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex 115 | @echo "Running LaTeX files through pdflatex..." 116 | $(MAKE) -C $(BUILDDIR)/latex all-pdf 117 | @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." 118 | 119 | latexpdfja: 120 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex 121 | @echo "Running LaTeX files through platex and dvipdfmx..." 122 | $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja 123 | @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." 124 | 125 | text: 126 | $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text 127 | @echo 128 | @echo "Build finished. The text files are in $(BUILDDIR)/text." 129 | 130 | man: 131 | $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man 132 | @echo 133 | @echo "Build finished. The manual pages are in $(BUILDDIR)/man." 134 | 135 | texinfo: 136 | $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo 137 | @echo 138 | @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." 139 | @echo "Run \`make' in that directory to run these through makeinfo" \ 140 | "(use \`make info' here to do that automatically)." 141 | 142 | info: 143 | $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo 144 | @echo "Running Texinfo files through makeinfo..." 145 | make -C $(BUILDDIR)/texinfo info 146 | @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." 147 | 148 | gettext: 149 | $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale 150 | @echo 151 | @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." 152 | 153 | changes: 154 | $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes 155 | @echo 156 | @echo "The overview file is in $(BUILDDIR)/changes." 157 | 158 | linkcheck: 159 | $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck 160 | @echo 161 | @echo "Link check complete; look for any errors in the above output " \ 162 | "or in $(BUILDDIR)/linkcheck/output.txt." 163 | 164 | doctest: 165 | $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest 166 | @echo "Testing of doctests in the sources finished, look at the " \ 167 | "results in $(BUILDDIR)/doctest/output.txt." 168 | 169 | xml: 170 | $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml 171 | @echo 172 | @echo "Build finished. The XML files are in $(BUILDDIR)/xml." 173 | 174 | pseudoxml: 175 | $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml 176 | @echo 177 | @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." 178 | -------------------------------------------------------------------------------- /docs/conf.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | # 4 | # admin-cfdi documentation build configuration file, created by 5 | # sphinx-quickstart on Tue Feb 17 22:35:26 2015. 6 | # 7 | # This file is execfile()d with the current directory set to its 8 | # containing dir. 9 | # 10 | # Note that not all possible configuration values are present in this 11 | # autogenerated file. 12 | # 13 | # All configuration values have a default; values that are commented out 14 | # serve to show the default. 15 | 16 | import sys 17 | import os 18 | 19 | # If extensions (or modules to document with autodoc) are in another directory, 20 | # add these directories to sys.path here. If the directory is relative to the 21 | # documentation root, use os.path.abspath to make it absolute, like shown here. 22 | sys.path.insert(0, os.path.abspath('..')) 23 | 24 | # -- General configuration ------------------------------------------------ 25 | 26 | # If your documentation needs a minimal Sphinx version, state it here. 27 | #needs_sphinx = '1.0' 28 | 29 | # Add any Sphinx extension module names here, as strings. They can be 30 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom 31 | # ones. 32 | extensions = ['sphinx.ext.autodoc'] 33 | 34 | # Add any paths that contain templates here, relative to this directory. 35 | templates_path = ['_templates'] 36 | 37 | # The suffix of source filenames. 38 | source_suffix = '.rst' 39 | 40 | # The encoding of source files. 41 | #source_encoding = 'utf-8-sig' 42 | 43 | # The master toctree document. 44 | master_doc = 'index' 45 | 46 | # General information about the project. 47 | project = 'admin-cfdi' 48 | copyright = '2015, Python Cabal' 49 | 50 | # The version info for the project you're documenting, acts as replacement for 51 | # |version| and |release|, also used in various other places throughout the 52 | # built documents. 53 | # 54 | # The short X.Y version. 55 | version = '0.3' 56 | # The full version, including alpha/beta/rc tags. 57 | release = '0.3' 58 | 59 | # The language for content autogenerated by Sphinx. Refer to documentation 60 | # for a list of supported languages. 61 | language = 'es' 62 | 63 | # There are two options for replacing |today|: either, you set today to some 64 | # non-false value, then it is used: 65 | #today = '' 66 | # Else, today_fmt is used as the format for a strftime call. 67 | #today_fmt = '%B %d, %Y' 68 | 69 | # List of patterns, relative to source directory, that match files and 70 | # directories to ignore when looking for source files. 71 | exclude_patterns = ['_build'] 72 | 73 | # The reST default role (used for this markup: `text`) to use for all 74 | # documents. 75 | #default_role = None 76 | 77 | # If true, '()' will be appended to :func: etc. cross-reference text. 78 | #add_function_parentheses = True 79 | 80 | # If true, the current module name will be prepended to all description 81 | # unit titles (such as .. function::). 82 | #add_module_names = True 83 | 84 | # If true, sectionauthor and moduleauthor directives will be shown in the 85 | # output. They are ignored by default. 86 | #show_authors = False 87 | 88 | # The name of the Pygments (syntax highlighting) style to use. 89 | pygments_style = 'sphinx' 90 | 91 | # A list of ignored prefixes for module index sorting. 92 | #modindex_common_prefix = [] 93 | 94 | # If true, keep warnings as "system message" paragraphs in the built documents. 95 | #keep_warnings = False 96 | 97 | 98 | # -- Options for HTML output ---------------------------------------------- 99 | 100 | # The theme to use for HTML and HTML Help pages. See the documentation for 101 | # a list of builtin themes. 102 | html_theme = 'default' 103 | 104 | # Theme options are theme-specific and customize the look and feel of a theme 105 | # further. For a list of options available for each theme, see the 106 | # documentation. 107 | #html_theme_options = {} 108 | 109 | # Add any paths that contain custom themes here, relative to this directory. 110 | #html_theme_path = [] 111 | 112 | # The name for this set of Sphinx documents. If None, it defaults to 113 | # " v documentation". 114 | html_title = "Documentacion de {} v{}".format(project, release) 115 | 116 | # A shorter title for the navigation bar. Default is the same as html_title. 117 | html_short_title = html_title 118 | 119 | # The name of an image file (relative to this directory) to place at the top 120 | # of the sidebar. 121 | #html_logo = None 122 | 123 | # The name of an image file (within the static path) to use as favicon of the 124 | # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 125 | # pixels large. 126 | #html_favicon = None 127 | 128 | # Add any paths that contain custom static files (such as style sheets) here, 129 | # relative to this directory. They are copied after the builtin static files, 130 | # so a file named "default.css" will overwrite the builtin "default.css". 131 | html_static_path = ['_static'] 132 | 133 | # Add any extra paths that contain custom files (such as robots.txt or 134 | # .htaccess) here, relative to this directory. These files are copied 135 | # directly to the root of the documentation. 136 | #html_extra_path = [] 137 | 138 | # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, 139 | # using the given strftime format. 140 | #html_last_updated_fmt = '%b %d, %Y' 141 | 142 | # If true, SmartyPants will be used to convert quotes and dashes to 143 | # typographically correct entities. 144 | #html_use_smartypants = True 145 | 146 | # Custom sidebar templates, maps document names to template names. 147 | #html_sidebars = {} 148 | 149 | # Additional templates that should be rendered to pages, maps page names to 150 | # template names. 151 | #html_additional_pages = {} 152 | 153 | # If false, no module index is generated. 154 | #html_domain_indices = True 155 | 156 | # If false, no index is generated. 157 | #html_use_index = True 158 | 159 | # If true, the index is split into individual pages for each letter. 160 | #html_split_index = False 161 | 162 | # If true, links to the reST sources are added to the pages. 163 | #html_show_sourcelink = True 164 | 165 | # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. 166 | #html_show_sphinx = True 167 | 168 | # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. 169 | #html_show_copyright = True 170 | 171 | # If true, an OpenSearch description file will be output, and all pages will 172 | # contain a tag referring to it. The value of this option must be the 173 | # base URL from which the finished HTML is served. 174 | #html_use_opensearch = '' 175 | 176 | # This is the file name suffix for HTML files (e.g. ".xhtml"). 177 | #html_file_suffix = None 178 | 179 | # Output file base name for HTML help builder. 180 | htmlhelp_basename = 'admin-cfdidoc' 181 | 182 | 183 | # -- Options for LaTeX output --------------------------------------------- 184 | 185 | latex_elements = { 186 | # The paper size ('letterpaper' or 'a4paper'). 187 | #'papersize': 'letterpaper', 188 | 189 | # The font size ('10pt', '11pt' or '12pt'). 190 | #'pointsize': '10pt', 191 | 192 | # Additional stuff for the LaTeX preamble. 193 | #'preamble': '', 194 | } 195 | 196 | # Grouping the document tree into LaTeX files. List of tuples 197 | # (source start file, target name, title, 198 | # author, documentclass [howto, manual, or own class]). 199 | latex_documents = [ 200 | ('index', 'admin-cfdi.tex', 'admin-cfdi Documentation', 201 | 'Mauricio Baeza', 'manual'), 202 | ] 203 | 204 | # The name of an image file (relative to this directory) to place at the top of 205 | # the title page. 206 | #latex_logo = None 207 | 208 | # For "manual" documents, if this is true, then toplevel headings are parts, 209 | # not chapters. 210 | #latex_use_parts = False 211 | 212 | # If true, show page references after internal links. 213 | #latex_show_pagerefs = False 214 | 215 | # If true, show URL addresses after external links. 216 | #latex_show_urls = False 217 | 218 | # Documents to append as an appendix to all manuals. 219 | #latex_appendices = [] 220 | 221 | # If false, no module index is generated. 222 | #latex_domain_indices = True 223 | 224 | 225 | # -- Options for manual page output --------------------------------------- 226 | 227 | # One entry per manual page. List of tuples 228 | # (source start file, name, description, authors, manual section). 229 | man_pages = [ 230 | ('index', 'admin-cfdi', 'admin-cfdi Documentation', 231 | ['Mauricio Baeza'], 1) 232 | ] 233 | 234 | # If true, show URL addresses after external links. 235 | #man_show_urls = False 236 | 237 | 238 | # -- Options for Texinfo output ------------------------------------------- 239 | 240 | # Grouping the document tree into Texinfo files. List of tuples 241 | # (source start file, target name, title, author, 242 | # dir menu entry, description, category) 243 | texinfo_documents = [ 244 | ('index', 'admin-cfdi', 'admin-cfdi Documentation', 245 | 'Mauricio Baeza', 'admin-cfdi', 'One line description of project.', 246 | 'Miscellaneous'), 247 | ] 248 | 249 | # Documents to append as an appendix to all manuals. 250 | #texinfo_appendices = [] 251 | 252 | # If false, no module index is generated. 253 | #texinfo_domain_indices = True 254 | 255 | # How to display URL addresses: 'footnote', 'no', or 'inline'. 256 | #texinfo_show_urls = 'footnote' 257 | 258 | # If true, do not generate a @detailmenu in the "Top" node's menu. 259 | #texinfo_no_detailmenu = False 260 | -------------------------------------------------------------------------------- /docs/devel.rst: -------------------------------------------------------------------------------- 1 | ========== 2 | Desarrollo 3 | ========== 4 | Este capítulo contiene información útil para quienes desean 5 | desarrollar aplicaciones que trabajen con CFDIs, para lo 6 | cual pueden usar una o más de las clases disponibles dentro 7 | del paquete `admincfdi`. 8 | 9 | 10 | Estructura 11 | ========== 12 | 13 | El paquete `admincfdi` incluye los siguientes módulos: 14 | 15 | - `pyutil` Tiene varias clases que implementan 16 | las funcionalidades usadas por las aplicaciones. 17 | 18 | - `values` Tiene la clase Global que centraliza 19 | valores que se usan en los otros módulos. Por 20 | ejemplo, las URLs y valores id de la página web 21 | de CFDIs del SAT están en el atributo SAT, 22 | es un diccionario que es usado 23 | en la descarga de CFDIs. 24 | 25 | admin-cfdi 26 | ========== 27 | 28 | El botón ``Descargar`` está ligado al método 29 | :func:`admin-cfdi.Application.button_download_sat_click` 30 | de la aplicación, que ejecuta 31 | estos dos métodos: 32 | 33 | - :func:`admin-cfdi.Application._validate_download_sat` 34 | 35 | - :func:`admin-cfdi.Application._download_sat` 36 | 37 | Descarga de facturas del SAT 38 | ============================ 39 | 40 | El proceso de descarga mediante la aplicación de CFDIs 41 | del SAT consiste en estos pasos: 42 | 43 | #. Conectar 44 | #. Buscar 45 | #. Descargar 46 | #. Desconectar 47 | 48 | Los detalles de cada paso: 49 | 50 | #. Conectar 51 | 52 | - Lanzar el navegador 53 | - Navegar a la página de login de CFDIs 54 | - Llenar el usuario y la contraseña (RFC y CIEC) 55 | - Enviar los datos al servidor 56 | - Esperar la respuesta 57 | - En caso de éxito, se carga una página con el título 58 | *NetIQ Access Manager* 59 | - En caso de falla, un elemento ``div`` con id ``xacerror`` 60 | deja de estar oculto y muestra su texto que empieza 61 | con *El RFC o contraseña son incorrectos.* 62 | 63 | #. Buscar 64 | 65 | - Navegar a la página de búsqueda de facturas emitidas, 66 | o a la de facturas recibidas 67 | - Esperar a que el título cambie a *Buscar CFDI* 68 | - Llenar los datos de la búsqueda 69 | - Si la búsqueda es por UUID, llenar el UUID en 70 | el input con id ``ctl00_MainContent_TxtUUID``. 71 | - Si la búsqueda es por fecha: 72 | - Hacer clic en el botón de radio a la izquierda 73 | de Fecha de Emisión con id 74 | ``ctl00_MainContent_RdoFechas``. 75 | - Esperar a que el input a la derecha de RFC Emisor 76 | con id ``ctl00_MainContent_TxtRfcReceptor`` 77 | esté habilitado y se pueda hacer clic en él. 78 | - Si se buscan facturas emitidas: 79 | - Habilitar los inputs con id 80 | 81 | - ``ctl00_MainContent_CldFechaInicial2_Calendario_text`` 82 | - ``ctl00_MainContent_CldFechaFinal2_Calendario_text`` 83 | 84 | y asignar valor de fecha inicial y fecha final de emisión 85 | usando formato ``dd/mm/aaaa`` 86 | - Asignar a los selects no visibles de tiempo final con ids 87 | 88 | - ``ctl00_MainContent_CldFechaFinal2_DdlHora`` 89 | - ``ctl00_MainContent_CldFechaFinal2_DdlMinuto`` 90 | - ``ctl00_MainContent_CldFechaFinal2_DdlSegundo`` 91 | 92 | una cadena con un valor en el rango que corresponde 93 | respectivamente: 1 a 23, 1 a 59 y 1 a 59. 94 | No usar ceros a la izquierda para valores menores 95 | a 10: usar 5, no 05. Por omisión hay que llenar cada 96 | select con el valor máximo correspondiente. 97 | - Se se buscan facturas recibidas: 98 | - Asignar a los selects no visibles con ids 99 | 100 | - ``DdlAnio`` 101 | - ``ctl00_MainContent_CldFecha_DdlMes`` 102 | - ``ctl00_MainContent_CldFecha_DdlDia`` 103 | - ``ctl00_MainContent_CldFecha_DdlHora`` 104 | - ``ctl00_MainContent_CldFecha_DdlMinuto`` 105 | - ``ctl00_MainContent_CldFecha_DdlSegundo`` 106 | - ``ctl00_MainContent_CldFecha_DdlHoraFin`` 107 | - ``ctl00_MainContent_CldFecha_DdlMinutoFin`` 108 | - ``ctl00_MainContent_CldFecha_DdlSegundoFin`` 109 | 110 | los valores de los parámetros año, mes, día, 111 | hora_inicial, minuto_inicial, segundo_inicial, 112 | hora_final, minuto_final y segundo_final respectivamente. 113 | Los valores de horas, minutos y segundos 114 | no deben llevar 0 a la izquierda. El valor de 115 | día requiere 0 a la izquierda para valores menores 116 | a 10. 117 | 118 | - Enviar la forma de búsqueda al servidor mediante método POST, los 119 | datos que se envían se muestran más bajo. 120 | 121 | - Esperar a que no sea visible el elemento div de los 122 | resultados, o el botón mismo de enviar 123 | - Esperar a que uno de los dos div con id 124 | ``ctl00_MainContent_PnlResultados`` o id 125 | ``ctl00_MainContent_PnlNoResultados`` esté 126 | visible. 127 | - Si el div con id ``ctl00_MainContent_PnlResultados`` 128 | es visible: 129 | 130 | - Esperar que un elemento con name ``BtnDescarga`` 131 | se le pueda hacer clic 132 | - Encontrar la lista todos los elementos con name 133 | ``BtnDescarga``. Son los íconos 134 | de descarga a la izquierda en cada renglón. 135 | 136 | - La lista de resultados está paginada en 500 elementos. 137 | Si los 138 | resultados son más de 500, una opción es dividir 139 | la búsqueda en dos o más búsquedas 140 | en las que se agregan criterios: La búsqueda de un 141 | mes se puede dividir en búsquedas por día; la 142 | búsqueda de un día puede dividirse en búsquedas en 143 | un rango de horas en ese día. 144 | 145 | 146 | 147 | #. Descargar 148 | 149 | - Iterar en cada elemento de la lista 150 | de resultados: 151 | 152 | - Concatenar la URL base 153 | de CFDIs con el valor del atributo ``onclick`` 154 | del elemento 155 | - Hacer la solicitud GET a esta URL 156 | 157 | #. Desconectar 158 | - Cerrar la sesión 159 | - Cerrar el navegador. Este paso se realiza 160 | a pesar de que ocurra una falla en el paso 161 | anterior. 162 | 163 | En caso de alguna falla en los primeros tres pasos, 164 | la aplicación debe realizar el paso 4. 165 | 166 | Los datos que se envían por la forma de búsqueda de facturas recibidas: 167 | 168 | - ctl00$ScriptManager1=ctl00$MainContent$UpnlBusqueda|ctl00$MainContent$BtnBusqueda 169 | - __CSRFTOKEN=%2FwEFJGNjZmIzNzZmLTE4OWUtNDQwNS1iNmZiLWU2NWE4MDQ0Y2EwZA%3D%3D 170 | - ctl00$MainContent$TxtUUID= 171 | - ctl00$MainContent$FiltroCentral=RdoFechas 172 | - ctl00$MainContent$CldFecha$DdlAnio=2014 173 | - ctl00$MainContent$CldFecha$DdlMes=1 174 | - ctl00$MainContent$CldFecha$DdlDia=0 175 | - ctl00$MainContent$CldFecha$DdlHora=0 176 | - ctl00$MainContent$CldFecha$DdlMinuto=0 177 | - ctl00$MainContent$CldFecha$DdlSegundo=0 178 | - ctl00$MainContent$CldFecha$DdlHoraFin=23 179 | - ctl00$MainContent$CldFecha$DdlMinutoFin=59 180 | - ctl00$MainContent$CldFecha$DdlSegundoFin=59 181 | - ctl00$MainContent$TxtRfcReceptor= 182 | - ctl00$MainContent$DdlEstadoComprobante=-1 183 | - ctl00$MainContent$hfInicialBool=false 184 | - ctl00$MainContent$ddlComplementos=-1 185 | - __EVENTTARGET= 186 | - __EVENTARGUMENT= 187 | - __LASTFOCUS= 188 | - __VIEWSTATE= 189 | - __VIEWSTATEGENERATOR=FE9DB3F4 190 | - __VIEWSTATEENCRYPTED= 191 | - __ASYNCPOST=true 192 | - ctl00$MainContent$BtnBusqueda=Buscar CFDI 193 | 194 | Los datos que se envían por la forma de búsqueda de facturas emitidas: 195 | 196 | - ctl00$ScriptManager1=ctl00$MainContent$UpnlBusqueda|ctl00$MainContent$BtnBusqueda 197 | - __CSRFTOKEN=%2FwEFJGNjZmIzNzZmLTE4OWUtNDQwNS1iNmZiLWU2NWE4MDQ0Y2EwZA%3D%3D 198 | - ctl00$MainContent$TxtUUID= 199 | - ctl00$MainContent$FiltroCentral=RdoFechas 200 | - ctl00$MainContent$hfInicial=2015 201 | - ctl00$MainContent$hfInicialBool=false 202 | - ctl00$MainContent$CldFechaInicial2$Calendario_text=18/05/2015 203 | - ctl00$MainContent$CldFechaInicial2$DdlHora=0 204 | - ctl00$MainContent$CldFechaInicial2$DdlMinuto=0 205 | - ctl00$MainContent$CldFechaInicial2$DdlSegundo=0 206 | - ctl00$MainContent$hfFinal=2015 207 | - ctl00$MainContent$CldFechaFinal2$Calendario_text=19/05/2015 208 | - ctl00$MainContent$CldFechaFinal2$DdlHora=23 209 | - ctl00$MainContent$CldFechaFinal2$DdlMinuto=59 210 | - ctl00$MainContent$CldFechaFinal2$DdlSegundo=59 211 | - ctl00$MainContent$TxtRfcReceptor= 212 | - ctl00$MainContent$DdlEstadoComprobante=-1 213 | - ctl00$MainContent$ddlComplementos=-1 214 | - ctl00$MainContent$hfDatos= 215 | - ctl00$MainContent$hfFlag= 216 | - ctl00$MainContent$hfAux= 217 | - __EVENTTARGET= 218 | - __EVENTARGUMENT= 219 | - __LASTFOCUS= 220 | - __VIEWSTATE= 221 | - __VIEWSTATEGENERATOR=3D1378D8 222 | - __VIEWSTATEENCRYPTED= 223 | - __ASYNCPOST=true 224 | - ctl00$MainContent$BtnBusqueda=Buscar CFDI 225 | 226 | 227 | 228 | API 229 | === 230 | El módulo :mod:`admincfdi.pyutil` provee varias clases, las cuales 231 | pueden ser usadas por las aplicaciones. En las siguientes 232 | secciones se explican y dan ejemplos de uso cada una de estas clases. 233 | 234 | 235 | SAT 236 | --- 237 | 238 | ValidCFDI 239 | --------- 240 | 241 | Util 242 | ---- 243 | 244 | Mail 245 | ---- 246 | 247 | LibO 248 | ---- 249 | 250 | NumerosLetras 251 | ------------- 252 | 253 | CFDIPDF 254 | ------- 255 | 256 | DescargaSAT 257 | ----------- 258 | Lleva a cabo al descarga de CFDIs del sitio del SAT. Para descargar 259 | un conjunto de CFDIs con ciertos criterios de búsqueda, se 260 | utilizan los siguientes pasos: 261 | 262 | #. Instanciar :class:`~admincfdi.pyutil.DescargaSAT`:: 263 | 264 | descarga = DescargaSAT() 265 | 266 | #. Crear un perfil de Firefox:: 267 | 268 | profile = descarga.get_firefox_profile(carpeta_destino) 269 | 270 | #. Conectar al sitio del SAT, lanzando Firefox:: 271 | 272 | descarga.connect(profile, rfc=rfc, ciec=pwd) 273 | 274 | #. Realizar una búsqueda, guardando la lista de resultados 275 | obtenida:: 276 | 277 | docs = descarga.search(facturas_emitidas=facturas_emitidas, 278 | uuid=uuid, 279 | rfc_emisor=rfc_emisor, 280 | año=año, 281 | mes=mes, 282 | día=día, 283 | mes_completo_por_día=mes_completo_por_día) 284 | 285 | #. Descargar los CFDIs:: 286 | 287 | descarga.download(docs) 288 | 289 | #. Desconectar la sesión del sitio del SAT y terminar 290 | Firefox:: 291 | 292 | descarga.disconnect() 293 | 294 | Los pasos 4. de búsqueda y 5. de descarga pueden repetirse, si 295 | se desean descargar dos o más conjuntos de CFDIs con diferentes 296 | criterios de búsqueda, manteniendo la sesión original abierta. 297 | 298 | Como ejemplo, a continuación se muestra el uso de los 299 | pasos en las aplicaciones ``admin-cfdi`` y ``descarga-cfdi`` 300 | que son parte del proyecto:: 301 | 302 | descarga = DescargaSAT() 303 | profile = descarga.get_firefox_profile(args.carpeta_destino) 304 | try: 305 | descarga.connect(profile, rfc=rfc, ciec=pwd) 306 | docs = descarga.search(facturas_emitidas= args.facturas_emitidas, 307 | uuid=args.uuid, 308 | rfc_emisor=args.rfc_emisor, 309 | año=args.año, 310 | mes=args.mes, 311 | día=args.día, 312 | mes_completo_por_día=args.mes_completo_por_día) 313 | descarga.download(docs) 314 | except Exception as e: 315 | print (e) 316 | finally: 317 | descarga.disconnect() 318 | 319 | Las cláusulas ``try/except/finally`` son para manejar alguna 320 | excepción que ocurra en cualquiera de los pasos, y garantizar 321 | que en cualquier caso se hace la desconexión de la sesión 322 | y se termina Firefox. 323 | 324 | CSVPDF 325 | ------ 326 | -------------------------------------------------------------------------------- /docs/glosario.rst: -------------------------------------------------------------------------------- 1 | ======== 2 | Glosario 3 | ======== 4 | 5 | .. glossary:: 6 | 7 | admin-cfdi 8 | Un administrador de documentos CFDI 9 | 10 | CFDI 11 | Comprobante Fiscal Digital por Internet 12 | 13 | SAT 14 | Servicio de Administración Tributaria 15 | -------------------------------------------------------------------------------- /docs/img/admin-cfdi-ventana-ppal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/docs/img/admin-cfdi-ventana-ppal.png -------------------------------------------------------------------------------- /docs/img/ejemplo-pdf.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinuxCabal/admin-cfdi/b508c531f8ba839c10322bd920a0148d20fad139/docs/img/ejemplo-pdf.png -------------------------------------------------------------------------------- /docs/index.rst: -------------------------------------------------------------------------------- 1 | .. admin-cfdi documentation master file, created by 2 | sphinx-quickstart on Tue Feb 17 22:35:26 2015. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | Bienvenido a la documentación de admin-cfdi 7 | =========================================== 8 | 9 | Contents: 10 | 11 | .. toctree:: 12 | :maxdepth: 2 13 | 14 | intro 15 | install 16 | uso 17 | devel 18 | reference 19 | glosario 20 | 21 | 22 | Indices and tables 23 | ================== 24 | 25 | * :ref:`genindex` 26 | * :ref:`modindex` 27 | * :ref:`search` 28 | 29 | -------------------------------------------------------------------------------- /docs/install.rst: -------------------------------------------------------------------------------- 1 | =========== 2 | Instalación 3 | =========== 4 | 5 | Para instalar :term:`admin-cfdi` descarga la ultima versión de producción desde 6 | `Github`_ e instala con el comando. 7 | 8 | :: 9 | 10 | sudo python setup.py install 11 | 12 | Si lo prefieres usa un entorno virtual. 13 | 14 | #. Para `LinuxMint`_ 15 | 16 | * Crea el entorno virtual 17 | 18 | :: 19 | 20 | pyvenv-3.4 test_admin --without-pip 21 | 22 | * Activalo 23 | 24 | :: 25 | 26 | cd test_admin/ 27 | source bin/activate 28 | 29 | * Instala pip 30 | 31 | :: 32 | 33 | wget https://bootstrap.pypa.io/get-pip.py 34 | python get-pip.py 35 | 36 | * Instala :term:`admin-cfdi` 37 | 38 | :: 39 | 40 | python setup.py install 41 | 42 | #. Para `ArchLinux`_ 43 | 44 | * Crea el entorno virtual 45 | 46 | :: 47 | 48 | pyvenv test_admin 49 | 50 | * Activalo 51 | 52 | :: 53 | 54 | cd test_admin/ 55 | source bin/activate 56 | 57 | * Instala :term:`admin-cfdi` 58 | 59 | :: 60 | 61 | python setup.py install 62 | 63 | 64 | .. _Github: https://github.com/LinuxCabal/admin-cfdi 65 | .. _LinuxMint: http://linuxmint.com/ 66 | .. _ArchLinux: https://www.archlinux.org/ 67 | -------------------------------------------------------------------------------- /docs/intro.rst: -------------------------------------------------------------------------------- 1 | ============ 2 | Introducción 3 | ============ 4 | 5 | :term:`admin-cfdi` es una aplicación de escritorio desarrollada en `Python`_ para descargar 6 | documentos :term:`CFDI` (facturas electrónicas) directamente del :term:`SAT`, 7 | permite también, descargar CFDIs desde correos electrónicos, validarlos y administrarlos. 8 | 9 | .. _Python: http://python.org/ 10 | 11 | .. image:: img/admin-cfdi-ventana-ppal.png 12 | :align: center 13 | :width: 714 14 | :height: 762 15 | :scale: 50 % 16 | :alt: Haz clic para agrandar 17 | 18 | `admin-cfdi` es `software libre`_ bajo la licencia `GNU GPL 3`_ y corre en GNU/Linux y 19 | otros sistemas operativos. 20 | Se tienen también dos aplicaciones de línea de comando que permiten 21 | automatizar operaciones mediante un script: 22 | 23 | .. _software libre: https://www.gnu.org/philosophy/free-sw.es.html 24 | .. _GNU GPL 3: https://www.gnu.org/licenses/gpl.html 25 | 26 | ``descarga-cfdi`` descarga CFDIs que cumplan determinado criterio, por 27 | ejemplo todos los CFDIs recibidos en el mes de enero de 2015:: 28 | 29 | descarga-cfdi --año 2015 --mes 01 30 | 31 | Abriendo Firefox... 32 | Conectando... 33 | Conectado... 34 | Buscando... 35 | Factura 1 de 13 36 | Factura 2 de 13 37 | Factura 3 de 13 38 | Factura 4 de 13 39 | Factura 5 de 13 40 | Factura 6 de 13 41 | Factura 7 de 13 42 | Factura 8 de 13 43 | Factura 9 de 13 44 | Factura 10 de 13 45 | Factura 11 de 13 46 | Factura 12 de 13 47 | Factura 13 de 13 48 | Desconectando... 49 | Desconectado.. 50 | 51 | Los CFDIs se guardan por omisión en la carpeta `cfdi-descarga`:: 52 | 53 | 12FB2D4B-CAE0-41CF-B344-13FE5135C773.xml 5A5108B2-2171-49B0-86D4-539DD205786A.xml CB969AF4-0E13-441B-9CC7-0AA11831317F.xml 54 | 1FBFA93D-F171-0B0E-CF71-4216C214E66F.xml 61F50926-7C47-4269-B612-3777881050A4.xml F1ABE4CE-9444-4F77-A3E5-57A6559F6CB3.xml 55 | 2968F314-90D6-4000-BBA5-E17988F2870F.xml 79FE35B0-636E-4163-8BA2-38E053E97E4C.xml FF31423C-E1BC-4A3D-9A7B-472FFE9988F9.xml 56 | 2CF33F44-2E2A-4F4C-904C-6213D3E8F12C.xml 57 | 58 | ``cfdi2pdf`` convierte los CFDIs de una carpeta origen a formato PDF:: 59 | 60 | cfdi2pdf -o cfdi-descarga/ -d cfdi-pdf/ 61 | 62 | Generando: ../cfdi-descarga/2CF33F44-2E2A-4F4C-904C-6213D3E8F12C.xml 63 | Generando: ../cfdi-descarga/79FE35B0-636E-4163-8BA2-38E053E97E4C.xml 64 | Generando: ../cfdi-descarga/61F50926-7C47-4269-B612-3777881050A4.xml 65 | Generando: ../cfdi-descarga/1FBFA93D-F171-0B0E-CF71-4216C214E66F.xml 66 | Generando: ../cfdi-descarga/F1ABE4CE-9444-4F77-A3E5-57A6559F6CB3.xml 67 | Generando: ../cfdi-descarga/2968F314-90D6-4000-BBA5-E17988F2870F.xml 68 | Generando: ../cfdi-descarga/FF31423C-E1BC-4A3D-9A7B-472FFE9988F9.xml 69 | Generando: ../cfdi-descarga/CB969AF4-0E13-441B-9CC7-0AA11831317F.xml 70 | Generando: ../cfdi-descarga/5A5108B2-2171-49B0-86D4-539DD205786A.xml 71 | Generando: ../cfdi-descarga/12FB2D4B-CAE0-41CF-B344-13FE5135C773.xml 72 | 73 | Un ejemplo de los archivos PDF generados: 74 | 75 | .. image:: img/ejemplo-pdf.png 76 | :align: center 77 | :width: 1366 78 | :height: 768 79 | :scale: 50 % 80 | :alt: Haz clic para agrandar 81 | -------------------------------------------------------------------------------- /docs/make.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | REM Command file for Sphinx documentation 4 | 5 | if "%SPHINXBUILD%" == "" ( 6 | set SPHINXBUILD=sphinx-build 7 | ) 8 | set BUILDDIR=_build 9 | set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% . 10 | set I18NSPHINXOPTS=%SPHINXOPTS% . 11 | if NOT "%PAPER%" == "" ( 12 | set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% 13 | set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS% 14 | ) 15 | 16 | if "%1" == "" goto help 17 | 18 | if "%1" == "help" ( 19 | :help 20 | echo.Please use `make ^` where ^ is one of 21 | echo. html to make standalone HTML files 22 | echo. dirhtml to make HTML files named index.html in directories 23 | echo. singlehtml to make a single large HTML file 24 | echo. pickle to make pickle files 25 | echo. json to make JSON files 26 | echo. htmlhelp to make HTML files and a HTML help project 27 | echo. qthelp to make HTML files and a qthelp project 28 | echo. devhelp to make HTML files and a Devhelp project 29 | echo. epub to make an epub 30 | echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter 31 | echo. text to make text files 32 | echo. man to make manual pages 33 | echo. texinfo to make Texinfo files 34 | echo. gettext to make PO message catalogs 35 | echo. changes to make an overview over all changed/added/deprecated items 36 | echo. xml to make Docutils-native XML files 37 | echo. pseudoxml to make pseudoxml-XML files for display purposes 38 | echo. linkcheck to check all external links for integrity 39 | echo. doctest to run all doctests embedded in the documentation if enabled 40 | goto end 41 | ) 42 | 43 | if "%1" == "clean" ( 44 | for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i 45 | del /q /s %BUILDDIR%\* 46 | goto end 47 | ) 48 | 49 | 50 | %SPHINXBUILD% 2> nul 51 | if errorlevel 9009 ( 52 | echo. 53 | echo.The 'sphinx-build' command was not found. Make sure you have Sphinx 54 | echo.installed, then set the SPHINXBUILD environment variable to point 55 | echo.to the full path of the 'sphinx-build' executable. Alternatively you 56 | echo.may add the Sphinx directory to PATH. 57 | echo. 58 | echo.If you don't have Sphinx installed, grab it from 59 | echo.http://sphinx-doc.org/ 60 | exit /b 1 61 | ) 62 | 63 | if "%1" == "html" ( 64 | %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html 65 | if errorlevel 1 exit /b 1 66 | echo. 67 | echo.Build finished. The HTML pages are in %BUILDDIR%/html. 68 | goto end 69 | ) 70 | 71 | if "%1" == "dirhtml" ( 72 | %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml 73 | if errorlevel 1 exit /b 1 74 | echo. 75 | echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. 76 | goto end 77 | ) 78 | 79 | if "%1" == "singlehtml" ( 80 | %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml 81 | if errorlevel 1 exit /b 1 82 | echo. 83 | echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml. 84 | goto end 85 | ) 86 | 87 | if "%1" == "pickle" ( 88 | %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle 89 | if errorlevel 1 exit /b 1 90 | echo. 91 | echo.Build finished; now you can process the pickle files. 92 | goto end 93 | ) 94 | 95 | if "%1" == "json" ( 96 | %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json 97 | if errorlevel 1 exit /b 1 98 | echo. 99 | echo.Build finished; now you can process the JSON files. 100 | goto end 101 | ) 102 | 103 | if "%1" == "htmlhelp" ( 104 | %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp 105 | if errorlevel 1 exit /b 1 106 | echo. 107 | echo.Build finished; now you can run HTML Help Workshop with the ^ 108 | .hhp project file in %BUILDDIR%/htmlhelp. 109 | goto end 110 | ) 111 | 112 | if "%1" == "qthelp" ( 113 | %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp 114 | if errorlevel 1 exit /b 1 115 | echo. 116 | echo.Build finished; now you can run "qcollectiongenerator" with the ^ 117 | .qhcp project file in %BUILDDIR%/qthelp, like this: 118 | echo.^> qcollectiongenerator %BUILDDIR%\qthelp\admin-cfdi.qhcp 119 | echo.To view the help file: 120 | echo.^> assistant -collectionFile %BUILDDIR%\qthelp\admin-cfdi.ghc 121 | goto end 122 | ) 123 | 124 | if "%1" == "devhelp" ( 125 | %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp 126 | if errorlevel 1 exit /b 1 127 | echo. 128 | echo.Build finished. 129 | goto end 130 | ) 131 | 132 | if "%1" == "epub" ( 133 | %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub 134 | if errorlevel 1 exit /b 1 135 | echo. 136 | echo.Build finished. The epub file is in %BUILDDIR%/epub. 137 | goto end 138 | ) 139 | 140 | if "%1" == "latex" ( 141 | %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex 142 | if errorlevel 1 exit /b 1 143 | echo. 144 | echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. 145 | goto end 146 | ) 147 | 148 | if "%1" == "latexpdf" ( 149 | %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex 150 | cd %BUILDDIR%/latex 151 | make all-pdf 152 | cd %BUILDDIR%/.. 153 | echo. 154 | echo.Build finished; the PDF files are in %BUILDDIR%/latex. 155 | goto end 156 | ) 157 | 158 | if "%1" == "latexpdfja" ( 159 | %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex 160 | cd %BUILDDIR%/latex 161 | make all-pdf-ja 162 | cd %BUILDDIR%/.. 163 | echo. 164 | echo.Build finished; the PDF files are in %BUILDDIR%/latex. 165 | goto end 166 | ) 167 | 168 | if "%1" == "text" ( 169 | %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text 170 | if errorlevel 1 exit /b 1 171 | echo. 172 | echo.Build finished. The text files are in %BUILDDIR%/text. 173 | goto end 174 | ) 175 | 176 | if "%1" == "man" ( 177 | %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man 178 | if errorlevel 1 exit /b 1 179 | echo. 180 | echo.Build finished. The manual pages are in %BUILDDIR%/man. 181 | goto end 182 | ) 183 | 184 | if "%1" == "texinfo" ( 185 | %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo 186 | if errorlevel 1 exit /b 1 187 | echo. 188 | echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo. 189 | goto end 190 | ) 191 | 192 | if "%1" == "gettext" ( 193 | %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale 194 | if errorlevel 1 exit /b 1 195 | echo. 196 | echo.Build finished. The message catalogs are in %BUILDDIR%/locale. 197 | goto end 198 | ) 199 | 200 | if "%1" == "changes" ( 201 | %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes 202 | if errorlevel 1 exit /b 1 203 | echo. 204 | echo.The overview file is in %BUILDDIR%/changes. 205 | goto end 206 | ) 207 | 208 | if "%1" == "linkcheck" ( 209 | %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck 210 | if errorlevel 1 exit /b 1 211 | echo. 212 | echo.Link check complete; look for any errors in the above output ^ 213 | or in %BUILDDIR%/linkcheck/output.txt. 214 | goto end 215 | ) 216 | 217 | if "%1" == "doctest" ( 218 | %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest 219 | if errorlevel 1 exit /b 1 220 | echo. 221 | echo.Testing of doctests in the sources finished, look at the ^ 222 | results in %BUILDDIR%/doctest/output.txt. 223 | goto end 224 | ) 225 | 226 | if "%1" == "xml" ( 227 | %SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml 228 | if errorlevel 1 exit /b 1 229 | echo. 230 | echo.Build finished. The XML files are in %BUILDDIR%/xml. 231 | goto end 232 | ) 233 | 234 | if "%1" == "pseudoxml" ( 235 | %SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml 236 | if errorlevel 1 exit /b 1 237 | echo. 238 | echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml. 239 | goto end 240 | ) 241 | 242 | :end 243 | -------------------------------------------------------------------------------- /docs/reference.rst: -------------------------------------------------------------------------------- 1 | ========== 2 | Referencia 3 | ========== 4 | 5 | admincfdi 6 | --------- 7 | 8 | .. automodule:: admincfdi 9 | :members: 10 | :undoc-members: 11 | :private-members: 12 | 13 | pyutil 14 | ------ 15 | 16 | .. automodule:: admincfdi.pyutil 17 | :members: 18 | :undoc-members: 19 | :private-members: 20 | 21 | values 22 | ------ 23 | 24 | .. automodule:: admincfdi.values 25 | :members: 26 | :undoc-members: 27 | :private-members: 28 | -------------------------------------------------------------------------------- /docs/uso.rst: -------------------------------------------------------------------------------- 1 | === 2 | Uso 3 | === 4 | 5 | Aplicaciones 6 | ------------ 7 | Admincfdi incluye las siguientes aplicaciones: 8 | 9 | - `admin-cfdi` 10 | 11 | - `descarga-cfdi` 12 | 13 | - `cfdi2pdf` 14 | 15 | `admin-cfdi` es una aplicación gráfica, `descarga-cfdi` 16 | y `cfdi2pdf` son aplicaciones de línea de comando. 17 | 18 | admin-cfdi 19 | ========== 20 | 21 | La descarga de los archivos XML del sitio web del SAT se 22 | maneja en la primera pestaña de la interfase gráfica. 23 | 24 | Primeramente el usuario debe llenar 25 | datos y/o seleccionar opciones en estos tres apartados: 26 | 27 | - Datos de acceso 28 | - Tipo de consulta 29 | - Opciones de búsqueda 30 | 31 | El proceso de la descarga se inicia mediante el botón 32 | ``Descargar``. 33 | 34 | descarga-cfdi 35 | ============= 36 | 37 | El avance del proceso se indica al usuario mediante 38 | textos cortos que se muestran en una línea de estado 39 | de la interfase gráfica, en esta secuencia:: 40 | 41 | Abriendo Firefox... 42 | Conectando... 43 | Conectado... 44 | Buscando... 45 | Factura 1 de 12 46 | Factura 2 de 12 47 | Factura 3 de 12 48 | Factura 4 de 12 49 | Factura 5 de 12 50 | Factura 6 de 12 51 | Factura 7 de 12 52 | Factura 8 de 12 53 | Factura 9 de 12 54 | Factura 10 de 12 55 | Factura 11 de 12 56 | Factura 12 de 12 57 | Desconectando... 58 | Desconectado... 59 | 60 | 61 | Pruebas funcionales de descarga del SAT 62 | --------------------------------------- 63 | Estas pruebas sirven para varios propósitos: 64 | 65 | - Saber si el sitio del SAT esta funcionando 66 | normalmente, 67 | 68 | - Saber si nuestra conexión entre la PC 69 | y el sito del SAT está funcionando y si 70 | su desempeño es el esperado, 71 | 72 | - Saber si el sitio del SAT cambió su 73 | funcionamiento del tal forma que sea 74 | necesario actualizar la librería de 75 | descarga de admincfdi. 76 | 77 | Las pruebas realizan descargas mediante 78 | varios modos de búsqueda y validan 79 | que la cantidad de archivos descargados 80 | sea la esperada. No requieren interacción 81 | mientas corren. 82 | 83 | Es necesario crear un archivo de credenciales y un archivo de 84 | configuración para las pruebas. El archivo de configuración 85 | especifica los criterios de cada búsqueda. Este es un ejemplo:: 86 | 87 | [uuid] 88 | uuid=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX 89 | expected=1 90 | 91 | [rfc_emisor] 92 | rfc_emisor=XXXXXXXXXXXX 93 | año=2014 94 | mes=09 95 | día=26 96 | expected=1 97 | 98 | [año_mes_día] 99 | año=2014 100 | mes=09 101 | día=26 102 | expected=1 103 | 104 | [mes_completo_por_día] 105 | año=2014 106 | mes=09 107 | expected=5 108 | 109 | Se necesitan estas cuatro secciones. Hay que ajustar los 110 | valores para que la cantidad de CFDIs no sea muy grande. La 111 | variable ``expected`` se ajusta a la cantidad de CFDIs que se 112 | descargan, para las credenciales que se utilicen. 113 | 114 | Para ejecutar:: 115 | 116 | python functional_DescargaSAT.py 117 | .... 118 | ---------------------------------------------------------------------- 119 | Ran 4 tests in 254.376s 120 | 121 | Agregar el parámetro ``-v`` para tener un renglón por 122 | cada prueba que se ejecuta:: 123 | 124 | python functional_DescargaSAT.py -v 125 | test_año_mes_día (__main__.DescargaSAT) ... ok 126 | test_mes_completo (__main__.DescargaSAT) ... ok 127 | test_rfc (__main__.DescargaSAT) ... ok 128 | test_uuid (__main__.DescargaSAT) ... ok 129 | 130 | ---------------------------------------------------------------------- 131 | Ran 4 tests in 254.376s 132 | -------------------------------------------------------------------------------- /functional_DescargaSAT.conf.sample: -------------------------------------------------------------------------------- 1 | [uuid] 2 | uuid=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX 3 | expected=1 4 | 5 | [rfc_emisor] 6 | rfc_emisor=XXXXXXXXXXXX 7 | año=2014 8 | mes=09 9 | día=26 10 | expected=1 11 | 12 | [año_mes_día] 13 | año=2014 14 | mes=09 15 | día=26 16 | expected=1 17 | 18 | [mes_completo_por_día] 19 | año=2014 20 | mes=09 21 | expected=5 22 | -------------------------------------------------------------------------------- /functional_DescargaSAT.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | 3 | 4 | class DescargaSAT(unittest.TestCase): 5 | 6 | def setUp(self): 7 | import configparser 8 | from admincfdi.pyutil import Util 9 | 10 | self.config = configparser.ConfigParser() 11 | self.config.read('functional_DescargaSAT.conf' ) 12 | 13 | util = Util() 14 | status, self.rfc, self.ciec = util.lee_credenciales('credenciales.conf') 15 | self.assertEqual('Ok', status) 16 | 17 | def test_connect_disconnect(self): 18 | from admincfdi.pyutil import DescargaSAT 19 | from selenium import webdriver 20 | 21 | profile = webdriver.FirefoxProfile() 22 | 23 | def no_op(*args): 24 | pass 25 | 26 | descarga = DescargaSAT(status_callback=no_op) 27 | status = descarga.connect(profile, rfc=self.rfc, ciec=self.ciec) 28 | self.assertTrue(status) 29 | descarga.disconnect() 30 | 31 | def test_connect_fail(self): 32 | from admincfdi.pyutil import DescargaSAT 33 | from selenium import webdriver 34 | 35 | profile = webdriver.FirefoxProfile() 36 | 37 | def no_op(*args): 38 | pass 39 | 40 | descarga = DescargaSAT(status_callback=no_op) 41 | status = descarga.connect(profile, rfc='x', ciec='y') 42 | self.assertFalse(status) 43 | descarga.browser.close() 44 | 45 | def test_search_uuid(self): 46 | import os 47 | import tempfile 48 | from admincfdi.pyutil import DescargaSAT 49 | 50 | def no_op(*args): 51 | pass 52 | 53 | seccion = self.config['uuid'] 54 | uuid = seccion['uuid'] 55 | expected = int(seccion['expected']) 56 | descarga = DescargaSAT(status_callback=no_op, 57 | download_callback=no_op) 58 | profile = descarga.get_firefox_profile('destino') 59 | descarga.connect(profile, rfc=self.rfc, ciec=self.ciec) 60 | result = descarga.search(uuid=uuid, 61 | día='00') 62 | descarga.disconnect() 63 | self.assertEqual(expected, len(result)) 64 | 65 | def test_uuid(self): 66 | import os 67 | import tempfile 68 | from admincfdi.pyutil import DescargaSAT 69 | 70 | def no_op(*args): 71 | pass 72 | 73 | seccion = self.config['uuid'] 74 | uuid = seccion['uuid'] 75 | expected = int(seccion['expected']) 76 | descarga = DescargaSAT(status_callback=no_op, 77 | download_callback=no_op) 78 | with tempfile.TemporaryDirectory() as tempdir: 79 | destino = os.path.join(tempdir, 'cfdi-descarga') 80 | profile = descarga.get_firefox_profile(destino) 81 | descarga.connect(profile, rfc=self.rfc, ciec=self.ciec) 82 | docs = descarga.search(uuid=uuid, día='00') 83 | descarga.download(docs) 84 | descarga.disconnect() 85 | self.assertEqual(expected, len(os.listdir(destino))) 86 | 87 | def test_rfc(self): 88 | import os 89 | import tempfile 90 | from admincfdi.pyutil import DescargaSAT 91 | 92 | def no_op(*args): 93 | pass 94 | 95 | seccion = self.config['rfc_emisor'] 96 | rfc_emisor = seccion['rfc_emisor'] 97 | año = seccion['año'] 98 | mes = seccion['mes'] 99 | día = seccion['día'] 100 | expected = int(seccion['expected']) 101 | descarga = DescargaSAT(status_callback=no_op, 102 | download_callback=no_op) 103 | with tempfile.TemporaryDirectory() as tempdir: 104 | destino = os.path.join(tempdir, 'cfdi-descarga') 105 | profile = descarga.get_firefox_profile(destino) 106 | descarga.connect(profile, rfc=self.rfc, ciec=self.ciec) 107 | docs = descarga.search(año=año, mes=mes, día=día, 108 | rfc_emisor=rfc_emisor) 109 | descarga.download(docs) 110 | descarga.disconnect() 111 | self.assertEqual(expected, len(os.listdir(destino))) 112 | 113 | def test_año_mes_día(self): 114 | import os 115 | import tempfile 116 | from admincfdi.pyutil import DescargaSAT 117 | 118 | def no_op(*args): 119 | pass 120 | 121 | seccion = self.config['año_mes_día'] 122 | año = seccion['año'] 123 | mes = seccion['mes'] 124 | día = seccion['día'] 125 | expected = int(seccion['expected']) 126 | descarga = DescargaSAT(status_callback=no_op, 127 | download_callback=no_op) 128 | with tempfile.TemporaryDirectory() as tempdir: 129 | destino = os.path.join(tempdir, 'cfdi-descarga') 130 | profile = descarga.get_firefox_profile(destino) 131 | descarga.connect(profile, rfc=self.rfc, ciec=self.ciec) 132 | docs = descarga.search(año=año, mes=mes, día=día) 133 | descarga.download(docs) 134 | descarga.disconnect() 135 | self.assertEqual(expected, len(os.listdir(destino))) 136 | 137 | def test_hora_minuto_inicial(self): 138 | import os 139 | import tempfile 140 | from admincfdi.pyutil import DescargaSAT 141 | 142 | def no_op(*args): 143 | pass 144 | 145 | seccion = self.config['hora_minuto_inicial'] 146 | año = seccion['año'] 147 | mes = seccion['mes'] 148 | día = seccion['día'] 149 | hora_inicial = seccion['hora_inicial'] 150 | minuto_inicial = seccion['minuto_inicial'] 151 | expected = int(seccion['expected']) 152 | descarga = DescargaSAT(status_callback=no_op, 153 | download_callback=no_op) 154 | with tempfile.TemporaryDirectory() as tempdir: 155 | destino = os.path.join(tempdir, 'cfdi-descarga') 156 | profile = descarga.get_firefox_profile(destino) 157 | descarga.connect(profile, rfc=self.rfc, ciec=self.ciec) 158 | docs = descarga.search(año=año, mes=mes, día=día, 159 | hora_inicial=hora_inicial, 160 | minuto_inicial=minuto_inicial) 161 | descarga.download(docs) 162 | descarga.disconnect() 163 | self.assertEqual(expected, len(os.listdir(destino))) 164 | 165 | def test_hora_minuto_final(self): 166 | import os 167 | import tempfile 168 | from admincfdi.pyutil import DescargaSAT 169 | 170 | def no_op(*args): 171 | pass 172 | 173 | seccion = self.config['hora_minuto_final'] 174 | año = seccion['año'] 175 | mes = seccion['mes'] 176 | día = seccion['día'] 177 | hora_final = seccion['hora_final'] 178 | minuto_final = seccion['minuto_final'] 179 | expected = int(seccion['expected']) 180 | descarga = DescargaSAT(status_callback=no_op, 181 | download_callback=no_op) 182 | with tempfile.TemporaryDirectory() as tempdir: 183 | destino = os.path.join(tempdir, 'cfdi-descarga') 184 | profile = descarga.get_firefox_profile(destino) 185 | descarga.connect(profile, rfc=self.rfc, ciec=self.ciec) 186 | docs = descarga.search(año=año, mes=mes, día=día, 187 | hora_final=hora_final, minuto_final=minuto_final) 188 | descarga.download(docs) 189 | descarga.disconnect() 190 | self.assertEqual(expected, len(os.listdir(destino))) 191 | 192 | def test_segundo_inicial_final(self): 193 | import os 194 | import tempfile 195 | from admincfdi.pyutil import DescargaSAT 196 | 197 | def no_op(*args): 198 | pass 199 | 200 | seccion = self.config['segundo_inicial_final'] 201 | año = seccion['año'] 202 | mes = seccion['mes'] 203 | día = seccion['día'] 204 | hora_inicial = seccion['hora_inicial'] 205 | minuto_inicial = seccion['minuto_inicial'] 206 | segundo_inicial = seccion['segundo_inicial'] 207 | hora_final = seccion['hora_final'] 208 | minuto_final = seccion['minuto_final'] 209 | segundo_final = seccion['segundo_final'] 210 | expected = int(seccion['expected']) 211 | descarga = DescargaSAT(status_callback=no_op, 212 | download_callback=no_op) 213 | with tempfile.TemporaryDirectory() as tempdir: 214 | destino = os.path.join(tempdir, 'cfdi-descarga') 215 | profile = descarga.get_firefox_profile(destino) 216 | descarga.connect(profile, rfc=self.rfc, ciec=self.ciec) 217 | docs = descarga.search(año=año, mes=mes, día=día, 218 | hora_inicial=hora_inicial, minuto_inicial=minuto_inicial, 219 | segundo_inicial=segundo_inicial, 220 | hora_final=hora_final, minuto_final=minuto_final, 221 | segundo_final=segundo_final) 222 | descarga.download(docs) 223 | descarga.disconnect() 224 | self.assertEqual(expected, len(os.listdir(destino))) 225 | 226 | def test_mes_completo(self): 227 | import os 228 | import tempfile 229 | from admincfdi.pyutil import DescargaSAT 230 | 231 | def no_op(*args): 232 | pass 233 | 234 | seccion = self.config['mes_completo_por_día'] 235 | año = seccion['año'] 236 | mes = seccion['mes'] 237 | expected = int(seccion['expected']) 238 | descarga = DescargaSAT(status_callback=no_op, 239 | download_callback=no_op) 240 | with tempfile.TemporaryDirectory() as tempdir: 241 | destino = os.path.join(tempdir, 'cfdi-descarga') 242 | profile = descarga.get_firefox_profile(destino) 243 | descarga.connect(profile, rfc=self.rfc, ciec=self.ciec) 244 | docs = descarga.search(año=año, mes=mes, día='00', 245 | mes_completo_por_día=True) 246 | descarga.download(docs) 247 | descarga.disconnect() 248 | self.assertEqual(expected, len(os.listdir(destino))) 249 | 250 | def test_emitidas(self): 251 | import os 252 | import tempfile 253 | from admincfdi.pyutil import DescargaSAT 254 | 255 | def no_op(*args): 256 | pass 257 | 258 | seccion = self.config['emitidas'] 259 | año = seccion['año'] 260 | mes = seccion['mes'] 261 | expected = int(seccion['expected']) 262 | descarga = DescargaSAT(status_callback=no_op, 263 | download_callback=no_op) 264 | with tempfile.TemporaryDirectory() as tempdir: 265 | destino = os.path.join(tempdir, 'cfdi-descarga') 266 | profile = descarga.get_firefox_profile(destino) 267 | descarga.connect(profile, rfc=self.rfc, ciec=self.ciec) 268 | docs = descarga.search(año=año, mes=mes, día='00', 269 | facturas_emitidas=True) 270 | descarga.disconnect() 271 | self.assertEqual(expected, len(docs)) 272 | 273 | 274 | if __name__ == '__main__': 275 | unittest.main() 276 | -------------------------------------------------------------------------------- /pwd.sample: -------------------------------------------------------------------------------- 1 | rfc ciec 2 | # escribe en el renglón de arriba tu RFC y tu CIEC 3 | # separados por un espacio 4 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | pypng 2 | fpdf 3 | pygubu 4 | selenium 5 | pyqrcode 6 | requests 7 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | ''' Setup for Admin CFDI ''' 4 | 5 | from setuptools import setup, find_packages 6 | from pip.req import parse_requirements 7 | 8 | 9 | install_reqs = parse_requirements('requirements.txt', session=False) 10 | reqs = [str(ir.req) for ir in install_reqs] 11 | 12 | setup(name='Admin-CFDI', 13 | version='0.3.0', 14 | description='Herramienta para administracion de CFDIs', 15 | license='GPL 3.0', 16 | author='Ver contributors.txt', 17 | author_email='public@mauriciobaeza.net', 18 | url='https://facturalibre.net/servicios/', 19 | packages=find_packages(), 20 | install_requires=reqs, 21 | package_data={'': ['img/*.png', 'img/*.gif', 'ui/*', 'template/*']}, 22 | scripts=[ 23 | 'admin-cfdi','descarga-cfdi', 'cfdi2pdf', 'admin-cfdi.pyw', 24 | 'descarga-cfdi.cmd', 'cfdi2pdf.cmd'] 25 | ) 26 | 27 | # vim: ts=4 et sw=4 28 | --------------------------------------------------------------------------------