Compare commits

...

279 Commits

Author SHA1 Message Date
El Mau 34a981a2dd Fix: en mercancias en Carta porte al generar el PDF 2024-04-10 20:54:26 -06:00
El Mau 66549e271b Fix: en mercancias en Carta porte al generar el PDF 2024-04-10 20:54:01 -06:00
El Mau 884b10bd79 Fix in js 2024-04-02 10:59:54 -06:00
El Mau fd050159ba Fix in js 2024-04-02 10:59:23 -06:00
El Mau 8199667188 Fix in Carta Porte 3.0 2024-04-02 10:31:58 -06:00
El Mau 05d3f617eb Fix in Carta Porte 2024-04-02 10:31:28 -06:00
El Mau 0ec4f0c2c9 Add support for Carta Porte 3.0 2024-04-02 00:25:41 -06:00
El Mau 29bfb42abc PDF from Carta Porte v3 2024-04-02 00:20:44 -06:00
El Mau 7f129b84b2 Stamp Carta Porte v3 2024-04-01 14:09:57 -06:00
El Mau 13a3c106c6 UI for Carta Porte v3 2024-03-31 22:28:13 -06:00
El Mau 0c7abf634b Update changelog 2024-03-04 14:07:10 -06:00
El Mau f0c4423fc8 Add support for Comercio Exterior 2.0 2024-01-24 15:07:26 -06:00
El Mau d925587a98 PDF from CE in version 2.0 2024-01-24 13:45:23 -06:00
El Mau 510ebdd1e5 Stamp CE in version 2.0 2024-01-21 23:20:27 -06:00
El Mau d2e92098da Import from ODS 2024-01-18 22:29:49 -06:00
El Mau c1ce206835 Import from json 2024-01-17 23:49:58 -06:00
El Mau 1efa280920 Import from json 2024-01-16 22:51:58 -06:00
El Mau 6fd8f9e2ea Add UI for CE 2024-01-14 22:42:26 -06:00
El Mau e3a44e6400 Add filter by day 2023-12-26 21:38:22 -06:00
El Mau 390ec60fdd Add filter by day 2023-12-26 21:37:45 -06:00
El Mau 957160755a Fix issue #98 and #107 2023-12-20 18:55:18 -06:00
El Mau 070ee31a1b Update changelog 2023-12-20 18:54:25 -06:00
El Mau 2620159408 Fix issue #98 2023-12-20 18:51:38 -06:00
El Mau 4d9bc4a172 Fix issue #107 2023-12-20 18:36:44 -06:00
El Mau 17ed56e9d7 Fix for CFDI egreso for General Public 2023-11-05 22:15:17 -06:00
El Mau 5057ac57ae Fix for CFDI egreso for General Public 2023-11-05 22:13:45 -06:00
El Mau 410a7080da Modify name for Public RFC 2023-10-30 16:51:38 -06:00
El Mau edd8d560bd Update changelog and version 2023-10-30 00:12:40 -06:00
El Mau bd1699d082 Add support for change time zone 2023-10-30 00:02:48 -06:00
El Mau 6d4023bb17 Update SATA catalog 2023-10-29 22:40:05 -06:00
Mauricio beda45690f Fix in retention tax for RESICOs 2023-07-06 11:16:04 -06:00
Mauricio 8feba167af Fix in retention tax for RESICOs 2023-07-06 11:15:15 -06:00
Mauricio 4dbb797d99 Fix tax retention in pay complement 2023-06-14 21:42:17 -06:00
Mauricio cd424b71dc Update changelog 2023-06-14 20:20:30 -06:00
Mauricio ea13d11319 Fix - Retencion tax in pay complement 2023-06-14 20:19:21 -06:00
Mauricio d9c863820a Merge pull request 'Añade información de desarrollo al readme' (#105) from categulario/empresa-libre:improve-readme into develop
Reviewed-on: #105
2023-06-06 15:23:46 -06:00
Categulario 6815d6c64c
improve readme with information on how to run locally 2023-06-05 22:34:09 -06:00
Mauricio 402cb7d70c Fix #103 2023-06-05 16:25:37 -06:00
Mauricio a5f1114774 Update changelog 2023-06-05 16:25:07 -06:00
Mauricio 2588a5f0b8 Fix #103 2023-06-05 16:22:53 -06:00
Mauricio eeae157772 Fix in complement pays 2023-05-25 21:59:13 -06:00
Mauricio 7cad4093d4 Fix in global invoice 2023-04-20 13:21:19 -06:00
Mauricio 7caf6423e1 Fix in global invoice 2023-04-20 13:20:48 -06:00
Mauricio 8a3aea41eb Add index in tickets 2023-04-15 19:23:56 -06:00
Mauricio bd49356d3f Add index in tickets 2023-04-15 18:13:45 -06:00
Mauricio 3b54ef0a36 Fix in global invoice 2023-04-14 17:56:12 -06:00
Mauricio 497a4be392 Update version 2023-04-14 17:55:48 -06:00
Mauricio 7fc6264322 Fix in global invoice 2023-04-14 17:55:00 -06:00
Mauricio c5d0e97212 Fix: al obtener la clave del sat al facturar en lote 2023-04-01 15:10:07 -06:00
Mauricio 5bbad9ef58 Fix: al obtener la clave del sat al facturar en lote 2023-04-01 15:09:27 -06:00
Mauricio 8e7aa23d1b Validate exists partner in edit 2023-03-29 17:36:17 -06:00
Mauricio f3d8b1dae5 Fix issue #97 2023-03-29 13:32:31 -06:00
Mauricio 2c684ae6bd Fix issue #97 2023-03-29 13:31:23 -06:00
el Mau febea3f289 Fix #96 2023-03-21 10:56:55 -06:00
el Mau 5facb96662 Fix #96 2023-03-21 10:55:16 -06:00
el Mau 6411c2e51e Fix in taxes in invoice pay 2023-03-13 17:16:30 -06:00
el Mau eeb128fda6 Fix in taxes in invoice pay 2023-03-13 17:16:15 -06:00
el Mau a078e27703 Fix in taxes in invoice pay 2023-03-13 14:01:26 -06:00
el Mau 28ef53043f Fix in taxes in invoice pay 2023-03-13 13:59:24 -06:00
el Mau e956c243f7 Fix in invoice pay 2023-03-10 14:56:19 -06:00
el Mau 1b33413de2 Fix in invoice pay 2023-03-10 14:55:57 -06:00
el Mau 64541a84b9 Fix in invoice pay with tax IVA 0 2023-03-07 11:53:28 -06:00
el Mau 834c1faae6 Fix in invoice pay with tax IVA 0 2023-03-07 11:53:04 -06:00
el Mau affe57bfcd Add validate for cancel movement bank 2023-03-06 16:10:07 -06:00
el Mau 4dc54ade1e Add validate for cancel movement bank 2023-03-06 16:09:37 -06:00
el Mau e72739a5fe Add cancel invoice pay in admin list 2023-03-06 00:48:01 -06:00
el Mau dd7b9c1680 Add cancel invoice pay in admin list 2023-03-06 00:47:34 -06:00
el Mau 9823bd967f Fix for exempted tax 2023-03-03 01:38:37 -06:00
el Mau aee467d98f Fix for exempted tax 2023-03-03 01:38:19 -06:00
el Mau 64917527f7 Validate tax object 2023-03-01 22:24:26 -06:00
el Mau 5f56179ebb Validate tax object 2023-03-01 22:24:00 -06:00
el Mau 955a0348f8 Can select month in global invoice 2023-03-01 18:45:50 -06:00
el Mau 0826b0cea2 Can select month in global invoice 2023-03-01 18:45:21 -06:00
el Mau 8b0f9fbc64 Can select global options for public invoice 2023-03-01 18:17:56 -06:00
el Mau f3d827364b Can select global options for public invoice 2023-03-01 18:16:52 -06:00
el Mau 50cbb3bae8 Fix in tax IVA retention 2023-03-01 14:32:33 -06:00
el Mau a7c8d80219 Fix in tax IVA retention 2023-03-01 14:32:01 -06:00
el Mau ca9d7a02e3 Update requirements.txt 2023-02-24 14:08:14 -06:00
el Mau 31fcb63e51 Update requirements.txt 2023-02-24 14:07:44 -06:00
el Mau bd7a31ea8a Fix global invoice 2023-02-24 12:45:52 -06:00
el Mau 6a6b6ca395 Fix global invoice 2023-02-23 18:20:10 -06:00
el Mau 3148c5ba82 Fix type change in deposit 2023-02-22 11:07:38 -06:00
el Mau 5f62ad7750 Fix type change in deposit 2023-02-22 11:06:37 -06:00
el Mau ff44162622 Fix type change in deposit 2023-02-21 22:16:25 -06:00
el Mau a37b3a5c23 Fix type change in deposit 2023-02-21 22:09:42 -06:00
el Mau 4fdea6173b Fix invoice pay in others currencies 2023-02-20 19:15:40 -06:00
el Mau 968c2744ec Fix pay invoice in other currencies 2023-02-20 19:10:29 -06:00
el Mau c9d85ca2e7 Fix make PDF from pays 1.0 2023-02-19 14:00:06 -06:00
el Mau 93e64eafd8 Fix make PDF from pays 1.0 2023-02-18 12:56:22 -06:00
el Mau 1984103ff5 Fix make PDF from pays 1.0 2023-02-18 12:40:05 -06:00
el Mau e4ba06c0ff Fix in tax object 04 2023-02-17 14:24:33 -06:00
el Mau 38bb267e55 Fix in tax object 04 2023-02-17 14:24:17 -06:00
el Mau 602467c8e9 Fix in tax object 04 2023-02-17 13:44:42 -06:00
el Mau 4020237f68 Fix in tax object 04 2023-02-17 13:43:43 -06:00
el Mau 933c9820e6 Fix with tax exento 2023-02-16 23:38:03 -06:00
el Mau 51daf0ad5e Stamp with tax exento 2023-02-16 23:09:35 -06:00
el Mau 709c524830 Show message when delete product 2023-02-16 22:30:08 -06:00
el Mau 434e15bb5b Fix in cancel with Finkok 2023-02-08 21:43:38 -06:00
el Mau af5fa3c812 Fix in templates 2023-02-01 22:45:48 -06:00
el Mau 8003fc42b9 Add template in json for 4.0 2023-02-01 22:27:13 -06:00
el Mau 83bebde169 Fix use cfdi P01 2023-02-01 08:56:55 -06:00
el Mau 5f641c632e Get message error in import invoice by lote 2023-01-31 22:07:43 -06:00
el Mau 1c11a1b013 Fix get sum by tax ISR 2023-01-30 22:16:07 -06:00
el Mau f13491d983 Fix get sum basy pay for IVA 2023-01-30 20:12:09 -06:00
el Mau a90f218c76 Fix node tax in invoice pay 2023-01-27 12:00:36 -06:00
el Mau 746c827492 Validate regimen fiscal in pay invoice 2023-01-23 16:18:11 -06:00
el Mau 661eff1dc3 Validate regimen fiscal in pay invoice 2023-01-23 16:05:38 -06:00
el Mau 2526a8f5aa Validate regimen fiscal in pay invoice 2023-01-23 15:39:04 -06:00
el Mau 296874a9b1 Admin regimenes 2023-01-22 12:57:35 -06:00
el Mau 86e7f50621 Fix in validate CP 2023-01-13 22:25:48 -06:00
el Mau 260ba62b2e Fix in validate CP 2023-01-12 12:02:02 -06:00
el Mau 8e2446e8f5 Fix in complement pay without taxes 2023-01-12 00:33:39 -06:00
el Mau 29e02e649d Fix error in nomina 2023-01-11 00:27:42 -06:00
el Mau d47e059d93 CFDI 4.0 2023-01-10 00:07:17 -06:00
el Mau 24777f691e CFDI 4.0 2023-01-07 07:37:32 -06:00
El Mau 3a5fbc609b Regresar productos en orden al refacturar 2022-04-01 09:50:10 -06:00
El Mau 5e888d2337 Regresar productos en orden al refacturar 2022-04-01 09:49:15 -06:00
El Mau de856f28ab Soporte basico para complemento Comercio Exterior 2022-03-28 21:34:10 -06:00
El Mau ae21403c59 Error al timbrar nomina 2022-03-10 20:26:27 -06:00
El Mau b68d79d0ca Fix issue #54 2022-02-18 14:59:01 -06:00
El Mau 68c0203039 Fix issue #53 2022-02-15 23:51:27 -06:00
El Mau 51af15f311 Error al generar Carta Porte sin remolque 2022-02-01 21:31:49 -06:00
El Mau 64ef75fbf5 Mejoras en Carta Porte 2022-01-30 14:50:05 -06:00
El Mau bd6ba5d4d0 Mejoras en Carta Porte 2022-01-27 22:18:28 -06:00
El Mau dd606be46b Arreglado el error al cancelar con CD 2022-01-26 22:32:38 -06:00
El Mau cc0eee1443 Fix - Issue #40 2022-01-23 23:11:08 -06:00
El Mau a609c0c6f5 Actualizar cancelación con XML firmado con CD 2022-01-21 17:09:29 -06:00
El Mau 9daf07693a Corregir error al enviar correo 2022-01-20 17:04:35 -06:00
El Mau d2f879c224 Importar carta porte desde json 2022-01-20 00:10:22 -06:00
El Mau ff8bc31f50 Agregar opción STARTTLS para envío de correo 2022-01-19 15:03:26 -06:00
El Mau d2c361e174 Representación impresa para Carta Porte 2022-01-19 13:30:22 -06:00
El Mau 6de30c3417 Actualizar lista de cambios 2022-01-10 14:28:16 -06:00
El Mau 47ec5ad360 Resolver conflictos 2021-12-12 22:30:15 -06:00
Mauricio Baeza 416bc65174 Can products without taxes 2021-09-14 21:53:00 -05:00
Mauricio Baeza 3dd88f14d6 Update version 2021-09-14 21:51:58 -05:00
Mauricio Baeza fb24346601 Can add or edit products without taxes 2021-09-14 21:49:21 -05:00
Mauricio Baeza a518278b55 Ticket #5 2021-05-31 13:01:03 -05:00
Mauricio Baeza 565f36be3a Option cancel only by admins 2021-05-24 12:54:11 -05:00
Mauricio Baeza 1a9087b13a Fix ticket #4 2021-04-13 22:29:29 -05:00
Mauricio Baeza 952dcba7ae Fix issue #3 2021-02-12 19:37:11 -06:00
Mauricio Baeza 12a24c1117 Fix issue #2 2021-02-12 12:23:34 -06:00
Mauricio Baeza fa01e6cf01 Fix issue #1 2021-02-11 18:10:37 -06:00
Mauricio Baeza b5bdcbbeb3 Import clients form CSV 2021-02-10 23:02:12 -06:00
Mauricio Baeza b03fbebe09 Fix get status sat, issue #422 2021-02-09 23:04:49 -06:00
Mauricio Baeza c98cdd7fff Fix get status sat, issue #422 2021-02-09 23:01:28 -06:00
Mauricio Baeza 537cecbb0b Fix get status sat, issue #422 2021-02-09 22:49:57 -06:00
Mauricio Baeza 5b8cd0ecb2 Fix show version of Empresa Libre 2021-02-02 22:10:13 -06:00
Mauricio Baeza 5c047ee9d5 Update changelog 2021-01-19 12:16:41 -06:00
Mauricio Baeza 431422361b Fix passed argument to pac 2021-01-18 19:06:59 -06:00
Mauricio Baeza 739ac08205 Add migrate auth 2021-01-13 19:15:38 -06:00
Mauricio Baeza de06f706a6 Fix get version in proforma 2021-01-11 14:43:50 -06:00
Mauricio Baeza aaccece897 Fix get folios 2021-01-10 19:18:48 -06:00
Mauricio Baeza f813fb4dd8 Fix set error in pac Finkok 2021-01-10 15:24:35 -06:00
Mauricio Baeza 51b4386b24 Fix add backend in cert 2021-01-10 14:23:58 -06:00
Mauricio Baeza e678083eea Fix add backend in cert 2021-01-10 14:21:51 -06:00
Mauricio Baeza 32679fced3 Fix in function name export cert 2021-01-10 14:17:32 -06:00
Mauricio Baeza 0084197906 Fix in get year for preinvoices 2021-01-08 20:53:29 -06:00
Mauricio Baeza 17fa99e45b Add migrate certificates 2021-01-06 22:15:30 -06:00
Mauricio Baeza cca598310b Fix in import conf for pacs 2021-01-05 18:53:13 -06:00
Mauricio Baeza 21fd903943 Refactory stamp and cancel 2021-01-05 17:32:38 -06:00
Mauricio Baeza 1f3e51861d Update version 2020-09-17 13:53:01 -05:00
Mauricio Baeza 1c6f9cd5f7 Fix - Namespaces for IEDU 2020-09-17 13:46:41 -05:00
Mauricio Baeza 8d815bf570 Update date in change log 2020-08-25 23:03:12 -05:00
Mauricio Baeza 443b916056 Fix - Validate namespace 2020-08-25 15:17:59 -05:00
Mauricio Baeza 980a7aafdb Fix: nomina stamp asimilados 2020-03-30 19:04:50 -06:00
Mauricio Baeza 267a96ebbc Global invoice by ticket 2020-03-08 15:27:53 -06:00
Mauricio Baeza 763f3c21fb Support for tax legends 2020-03-02 17:27:28 -06:00
Mauricio Baeza 26e4ce3d13 Options for show documents 2020-02-25 21:52:17 -06:00
Mauricio Baeza a202f12a17 Add filter by sucursal 2020-02-24 22:35:24 -06:00
Mauricio Baeza a17345c0fd Fix stamp nomina 2020-02-09 22:34:58 -06:00
Mauricio Baeza d509bfb8be Fix new validate nomina SAT 2020-01-29 16:03:20 -06:00
Mauricio Baeza 71bd536cb1 Update catalog SAT 2020-01-27 22:40:57 -06:00
Mauricio Baeza e94cda3577 Fix import conf.py 2020-01-24 10:02:24 -06:00
Mauricio Baeza 77b35f8322 Add new PAC 2020-01-22 15:25:40 -06:00
Mauricio Baeza 1c55fbd7c7 Fix #355 2020-01-07 21:48:57 -06:00
Mauricio Baeza 6f3d9cc3fa Fix - al crear PDF 2019-10-28 20:04:28 -06:00
Mauricio Baeza ce0e960534 Merge branch 'develop'
Fix #369
2019-08-29 09:13:43 -05:00
Mauricio Baeza abbb4cc608 Merge branch 'develop'
Envío de nómina por correo
Actualización de catalogos del SAT
2019-04-23 23:12:25 -05:00
Mauricio Baeza 692477f41a Merge branch 'develop'
Actualización de catálogos del SAT en Nómina
2019-03-24 21:49:26 -06:00
Mauricio Baeza 519a61e132 Merge branch 'develop'
Permitir editar la descripción en un movimiento bancario
Fix #343
2019-03-08 22:10:19 -06:00
Mauricio Baeza 4bff2703a4 Merge branch 'develop'
Fix - Send pay invoice
2019-03-04 19:44:59 -06:00
Mauricio Baeza 6cef8fe669 Merge branch 'develop'
Fix - In filter invoice by dates
2019-03-04 19:22:56 -06:00
Mauricio Baeza 2cacb786b6 Merge branch 'develop'
Error al enviar prefactura por correo
2019-02-20 23:40:07 -06:00
Mauricio Baeza 79cea5b092 Merge branch 'develop'
Soporte para complemento de divisas
2019-02-17 22:12:39 -06:00
Mauricio Baeza 43684b7fe9 Merge branch 'develop'
Fix - Al cancelar nómina
2019-01-23 13:33:32 -06:00
Mauricio Baeza 3d300146f1 Merge branch 'develop'
Permitir capturar folio manualmente
2019-01-17 22:10:17 -06:00
Mauricio Baeza dbf3a342bf Merge branch 'develop'
Guardar logos de emisor en carpeta correcta
2019-01-16 23:38:05 -06:00
Mauricio Baeza 997dfe90ba Merge branch 'develop'
Generar PDF desde plantilla JSON
2019-01-15 00:51:05 -06:00
Mauricio Baeza ff0ee73a73 Merge branch 'develop'
Error al importar nómina y factura en lote
2018-11-07 19:15:54 -06:00
Mauricio Baeza 4660e1d4e0 Merge branch 'develop'
Error: Consulta de  estatus en el SAT
2018-11-06 22:57:06 -06:00
Mauricio Baeza dc8aeaebba Merge branch 'develop'
Mejora: Permitir importar CFDI 3.2
2018-10-30 16:37:15 -06:00
Mauricio Baeza 0bddc189b4 Merge branch 'develop'
Mejora al generar factura en lote
2018-10-27 01:15:42 -05:00
Mauricio Baeza bbaf709e0e Merge branch 'develop'
Error unicode
2018-10-24 00:02:08 -05:00
Mauricio Baeza 2765958a23 Merge branch 'develop'
Error #307
2018-10-14 22:24:34 -05:00
Mauricio Baeza 2090aa743d Merge branch 'develop'
Error #287
Mejora - Facturas de pago con datos bancarios
2018-10-12 01:23:17 -05:00
Mauricio Baeza 63fc8e9a78 Merge branch 'develop'
Error #295
Cuentas de banco para clientes
2018-10-08 01:14:24 -05:00
Mauricio Baeza 425f2ee079 Merge branch 'develop'
Relacionar facturas v3.2
2018-10-03 23:40:52 -05:00
Mauricio Baeza acd8604e92 Merge branch 'develop'
Error #291
2018-10-03 15:23:17 -05:00
Mauricio Baeza 71d773f999 Merge branch 'develop'
Mejora #280
Mejora #288
Error #290
2018-09-28 02:24:12 -05:00
Mauricio Baeza 2e98d69685 Merge branch 'develop'
Error #282
2018-09-27 00:37:29 -05:00
Mauricio Baeza 135d469f3e Merge branch 'develop'
Soporte para facturas de pagos con documentos en otras monedas
2018-09-26 01:30:34 -05:00
Mauricio Baeza 18b1880772 Merge branch 'develop'
Aactualizar versión 1.16.1
2018-09-18 10:58:04 -05:00
Mauricio Baeza 66111d9080 Merge branch 'develop'
Error #268
2018-09-18 10:52:34 -05:00
Mauricio Baeza 127ceceada Merge branch 'develop'
Se puede modidicar el saldo del cliente
Se muestra la cantidad de facturas de pago en los movimientos
2018-09-16 22:10:15 -05:00
Mauricio Baeza b6b5aa3447 Merge branch 'develop'
Fix # 257
2018-09-12 23:23:58 -05:00
Mauricio Baeza b0de7655cc Merge branch 'develop'
Personalizar plantilla para factura de pago
2018-09-10 23:08:38 -05:00
Mauricio Baeza dea511d161 Merge branch 'develop'
Fix - Al agregar cuenta de banco
2018-09-10 17:35:28 -05:00
Mauricio Baeza 9081d54865 Merge branch 'develop'
Cancelar factura de pago
2018-09-10 00:18:39 -05:00
Mauricio Baeza f0ab9246e0 Merge branch 'develop'
Fix - al migrar tablas
2018-09-03 02:18:29 -05:00
Mauricio Baeza 8de2b20dcf Merge branch 'develop'
Soporte para Factura de pagos
2018-09-03 00:55:28 -05:00
Mauricio Baeza 4608246b7d Merge branch 'develop'
Quitar columnas en tabla facturaspagos
Actualizar version y lista de cambios
2018-08-21 18:52:55 -05:00
Mauricio Baeza 94240f2356 Merge branch 'develop'
Error al cerrar plantilla
2018-08-09 15:51:34 -05:00
Mauricio Baeza 3163fef0d5 Merge branch 'develop'
Cambio en consulta de timbres
2018-07-25 16:28:22 -05:00
Mauricio Baeza 32ec443a19 Merge branch 'develop'
Precios con cuatro decimales. Ticket #229
2018-07-10 23:37:35 -05:00
Mauricio Baeza 64caf4f415 Merge branch 'develop'
Actualizar versión
2018-07-08 23:46:21 -05:00
Mauricio Baeza 13836add29 Merge branch 'develop'
Fix - Ticket #231
2018-07-08 23:43:19 -05:00
Mauricio Baeza f3309429e6 Merge branch 'develop'
Actualizar versión
2018-07-05 23:56:08 -05:00
Mauricio Baeza f9e4bced15 Merge branch 'develop'
Fix - Ticket #230
2018-07-05 23:53:02 -05:00
Mauricio Baeza c3d92ff45e Merge branch 'develop'
Fix - Al mostrar el título
2018-06-25 22:58:03 -05:00
Mauricio Baeza 3424f7f78a Merge branch 'develop'
Add - Ticket #223
Fix - Ticket #224
2018-06-18 14:11:26 -05:00
Mauricio Baeza de40cb0453 Merge branch 'develop'
Fix - Ticket #222
2018-06-14 22:22:30 -05:00
Mauricio Baeza da84fbafb6 Merge branch 'develop'
- Se permiten 4 decimales en Tipo de cambio
- Se agrega el campo {total_cantidades} al generar el PDF
- Se agrega opción para generar respaldos de la BD en MV
- Fix: Al generar con complemento EDU
2018-06-03 22:45:23 -05:00
Mauricio Baeza 32926740be Merge branch 'develop'
Actualizar lista de cambios
2018-05-23 23:47:38 -05:00
Mauricio Baeza 57dce9670b Merge branch 'develop'
Soporte para truncar impuestos
2018-05-23 23:44:38 -05:00
Mauricio Baeza 03ac074c66 Merge branch 'develop'
Fix - Formato de celdas en conceptos
2018-05-08 13:22:43 -05:00
Mauricio Baeza 1f043746dd Merge branch 'develop'
Fix - Nómina separación
2018-04-09 21:43:09 -05:00
Mauricio Baeza 5b15166c7a Merge branch 'develop'
Fix - Issue #211
2018-03-29 16:20:56 -06:00
Mauricio Baeza 0a48580f0c Merge branch 'develop'
Fix - Issue #209
2018-03-20 22:51:47 -06:00
Mauricio Baeza 2f797af8b2 Merge branch 'develop'
Ejecutar LibreOffice como otra instancia
2018-03-09 00:23:46 -06:00
Mauricio Baeza aac5c04a3f Merge branch 'develop'
Fix - CFDI sin folio
2018-03-06 21:33:05 -06:00
Mauricio Baeza 348f2d4443 Merge branch 'develop'
Quitar registro patronal en contrato 09, 10 y 99
2018-03-06 10:42:01 -06:00
Mauricio Baeza 313af2cce1 Merge branch 'develop'
Fix - Issue #199
2018-03-01 22:29:34 -06:00
Mauricio Baeza 7308ec86ae Merge branch 'develop'
Traslados
2018-03-01 22:07:37 -06:00
Mauricio Baeza dc68b54f08 Merge branch 'develop'
Timbrar XML grandes con Ecodex
2018-02-22 15:12:19 -06:00
Mauricio Baeza b90e0a26ba Merge branch 'develop'
Quitar forma de pago en PDF
2018-02-20 18:05:01 -06:00
Mauricio Baeza 9ae0d7d924 Merge branch 'develop'
Quitar forma de pago en traslado
2018-02-20 16:07:46 -06:00
Mauricio Baeza 07d51db625 Merge branch 'develop'
Fix - Issue #191
2018-02-20 11:03:40 -06:00
Mauricio Baeza eedd253e6a Merge branch 'develop'
Timbrar a extranjeros
2018-02-18 23:57:58 -06:00
Mauricio Baeza 73eb2f0b8c Merge branch 'develop'
Fix - Issue #190
2018-02-16 22:17:18 -06:00
Mauricio Baeza fd334eade4 Merge branch 'develop'
Fix - Issue #189
2018-02-16 14:55:54 -06:00
Mauricio Baeza 7bbfcd6cae Merge branch 'develop'
Fix - Issue #188
2018-02-16 13:54:22 -06:00
Mauricio Baeza 6381975518 Merge branch 'develop'
Obtener timbres disponibles
2018-02-13 23:15:18 -06:00
Mauricio Baeza edd1be81ed Merge branch 'develop'
Fix - Issue #185
2018-02-13 12:07:29 -06:00
Mauricio Baeza e7a4d38681 Merge branch 'develop'
Fix - Issue #172
2018-02-12 23:52:00 -06:00
Mauricio Baeza 9a0f74eb52 Merge branch 'develop'
Fix - Issue #136
2018-02-12 23:14:57 -06:00
Mauricio Baeza cf73669e3a Merge branch 'develop'
Activar, desactivar cuentas de banco
2018-02-12 21:49:48 -06:00
Mauricio Baeza 3db6775f57 Merge branch 'develop'
Fix - Issue #174
2018-02-12 17:44:46 -06:00
Mauricio Baeza 8a03dba323 Merge branch 'develop'
Fix - Precio con impuestos al facturar
2018-02-10 12:13:13 -06:00
Mauricio Baeza 874bf11447 Merge branch 'develop'
Fix - En notas
2018-02-10 11:00:46 -06:00
Mauricio Baeza bb3f6d3aed Merge branch 'develop'
Permitir repetir productos al facturar
2018-02-09 20:38:46 -06:00
Mauricio Baeza 0ee99296a6 Merge branch 'develop'
Cambiar orden en movimientos bancarios
2018-02-07 21:36:56 -06:00
Mauricio Baeza e1424e2e70 Merge branch 'develop'
Quitar namespace de Nómina cuando no se usa
2018-02-07 12:54:41 -06:00
Mauricio Baeza 5bfcc4ca07 Merge branch 'develop'
Importar XML
2018-02-07 00:48:26 -06:00
Mauricio Baeza b2148e1789 Merge branch 'develop'
Plantilla Nómina #173
2018-02-06 12:07:54 -06:00
Mauricio Baeza badf1b0f5f Merge branch 'develop'
Borrar temporales
2018-02-06 00:01:27 -06:00
Mauricio Baeza 1c65205bea Merge branch 'develop'
Generar PDF de Nómina
2018-02-03 01:26:26 -06:00
Mauricio Baeza 4bd7e335d8 Merge branch 'develop'
Fix Issue #170
2018-02-02 13:49:09 -06:00
Mauricio Baeza 09ccffdc62 Merge branch 'develop'
Eliminar tabla de estatod del SAT
2018-02-01 18:50:53 -06:00
Mauricio Baeza 0207b9fa78 Merge branch 'develop'
Fix - Issue #160
2018-01-31 23:41:28 -06:00
Mauricio Baeza 785cb32773 Merge branch 'develop'
Fix - Issue #167
2018-01-31 22:46:51 -06:00
Mauricio Baeza 77ff862400 Merge branch 'develop'
Fix - Fecha de ingreso vacía
2018-01-31 22:41:09 -06:00
Mauricio Baeza da730801d6 Merge branch 'develop'
Importar nóminas canceladas
2018-01-31 16:13:38 -06:00
Mauricio Baeza 13d82f1df8 Merge branch 'develop'
Fix - Al generar PDF de una línea
Fix - Al mostrar buscar alumno
2018-01-31 01:47:19 -06:00
Mauricio Baeza dcfc80edc8 Merge branch 'develop'
Cookies no seguras cuando no hay HTTPS
2018-01-30 23:41:05 -06:00
Mauricio Baeza 3376505ea1 Merge branch 'develop'
Actualizar changelog y requerimientos
2018-01-30 22:17:33 -06:00
Mauricio Baeza 21eafd9e4a Merge branch 'develop'
Timbrado de Nómina
Complemento EDU
2018-01-30 22:01:48 -06:00
Mauricio Baeza b7b96611a6 Fix - Al eliminar nivel educativo 2018-01-30 10:10:09 -06:00
Mauricio Baeza 2141f84402 EDU - Quitar RFC como obligatorio 2018-01-29 14:23:37 -06:00
Mauricio Baeza 0e909628dc Complemento EDU 2018-01-29 13:21:48 -06:00
Mauricio Baeza 012331b523 Validar clave SAT al importar productos 2018-01-26 14:01:27 -06:00
Mauricio Baeza 64f5dd9170 Fix - Issue #153 2018-01-26 13:46:56 -06:00
Mauricio Baeza e1b975f0f9 Change in default template 2018-01-25 23:10:40 -06:00
Mauricio Baeza b73d0d6284 Config title app 2018-01-25 23:06:23 -06:00
Mauricio Baeza 83dff5bc5f Fix - Issue #149 2018-01-25 22:07:30 -06:00
Mauricio Baeza ac481862d9 Fix - Issue #150 2018-01-25 21:43:38 -06:00
Mauricio Baeza 14f17a6188 Fix - Issue #148 2018-01-25 15:44:40 -06:00
Mauricio Baeza 7e91476e47 Fix - Issue #147 2018-01-25 12:51:16 -06:00
Mauricio Baeza e728d948d0 Fix - Issue #147 2018-01-25 12:07:23 -06:00
Mauricio Baeza 5a791eec7c Fix - Al agregar empresa en MV 2018-01-25 10:22:22 -06:00
36 changed files with 3182 additions and 523 deletions

2
.gitignore vendored
View File

@ -2,6 +2,7 @@
__pycache__/ __pycache__/
*.py[cod] *.py[cod]
*$py.class *$py.class
Pipfile*
# Django stuff: # Django stuff:
*.log *.log
@ -33,4 +34,5 @@ credenciales.conf
*.orig *.orig
rfc.db rfc.db
Dockerfile Dockerfile
chuletas/

View File

@ -1,3 +1,89 @@
v 2.3.2 [10-Abr-2024]
- Fix: En las mercancias en la Carta Porte al generar el PDF.
v 2.3.1 [02-Abr-2024]
- Fix: En la cantidad de la mercancia en la Carta Porte.
v 2.3.0 [01-Abr-2024]
- Mejora: Soporte para complemento Carta Porte 3.0
- **IMPORTANTE**: Aunque no lo uses, esto afecta al JS de facturación, por
lo que tienes que forzar el refresco (CTRL+F5) si tienes algún problema.
v 2.2.0 [24-Ene-2024]
- Mejora: Soporte para complemento Comercio Exterior 2.0
- **IMPORTANTE**: Aunque no lo uses, esto afecta al JS de facturación, por
lo que tienes que forzar el refresco (CTRL+F5) si tienes algún problema.
v 2.1.0 [26-Dic-2023]
- Mejora: Se agrega filtro por día en facturas.
v 2.0.9 [20-Dic-2023]
- Fix: Issue 98 y 107
v 2.0.8 [30-Oct-2023]
---------------------
- Fix: Permitir generar CFDI de egreso para facturas globales sin datos globales.
- Fix: Permitir cambiar la zona horaria para cuando se usa en servidor.
Es necesario hacer una migración:
```
cd /opt/empresa-libre
git pull origin master
cd source/app/models
python main.py -bk
python main.py -m -r RFC
```
v 2.0.7 [06-Ju1-2023]
---------------------
- Fix: En tasa de retención de un Resico a una Persona Moral.
v 2.0.6 [14-Jun-2023]
---------------------
- Fix: Al generar complementos de pago con facturas con retención de impuestos.
v 2.0.5 [05-Jun-2023]
---------------------
- Fix: Al generar complementos de pago con facturas con varios impuestos.
- Fix: ticket #103, hay que usar {receptor.correo_facturas} y {receptor.telefonos}
v 2.0.2 [01-Abr-2023]
---------------------
- Fix: Obtener la clave del sat al facturar por lote.
v 2.0.1 [29-Mar-2023]
---------------------
- Fix ticket #97
Es necesario hacer una migración:
```
cd /opt/empresa-libre
git pull origin master
cd source/app/models
python main.py -bk
python main.py -m -r RFC
```
v 2.0.0 [08-Ene-2023] v 2.0.0 [08-Ene-2023]
---------------------- ----------------------
- Liberamos para todos la versión CFDI 4.0 - Liberamos para todos la versión CFDI 4.0
@ -168,7 +254,7 @@ v 1.42.2 [14-Sep-2021]
- Los productos pueden no llevar ningún impuesto. - Los productos pueden no llevar ningún impuesto.
v 1.42.1 [31-May-2021] v 1.42.1 [01-Jun-2021]
---------------------- ----------------------
- Error - Ticket #5 - Error - Ticket #5

View File

@ -12,3 +12,4 @@
* Crea nueva documentación * Crea nueva documentación
* Propon nuevas funcionalidades * Propon nuevas funcionalidades
* Difunde Empresa Libre * Difunde Empresa Libre

View File

@ -15,12 +15,11 @@ contratar: administracion ARROBA empresalibre.net
G1: `A5DdXxCKPw3QKWVdDVs7CzkNugNUW1sHu5zDJFWxCU2h` G1: `A5DdXxCKPw3QKWVdDVs7CzkNugNUW1sHu5zDJFWxCU2h`
BCH: `qztd3l00xle5tffdqvh2snvadkuau2ml0uqm4n875d` BCH: `qztd3l00xle5tffdqvh2snvadkuau2ml0uqm4n875d`
## Requerimientos:
### Requerimientos:
* Servidor web, recomendado Nginx * Servidor web, recomendado Nginx
* uwsgi * uwsgi
* python3.7+ * python 3.8
* xsltproc * xsltproc
* openssl * openssl
* xmlsec * xmlsec
@ -37,5 +36,25 @@ aplicaciones Python.
El sistema tiene soporte solo para PostgreSQL, debes de instalar el servidor de El sistema tiene soporte solo para PostgreSQL, debes de instalar el servidor de
la base de datos y su driver respectivo. la base de datos y su driver respectivo.
## Configuración para desarrollo local
* Crea un entorno virtual con python 3.8 y actívalo. Por ejemplo con virtualenv:
virtualenv .venv
source .venv/bin/activate
* Instala las dependencias
pip install -r requirements.txt
* Copia y ajusta algunos archivos necesarios.
- `source/app/conf.py`
- `source/app/controllers/pacs/comerciodigital/conf.py.example`
- `source/app/controllers/pacs/finkok/conf.py.example`
* Finalmente ejecutamos la aplicación. Para esto vamos a necesitar un servidor
wsgi como uwsgi:
pip install uwsgi
cd source/app
uwsgi main_debug.ini
* Ahora puedes ver la aplicación en http://localhost:8000

View File

@ -1,2 +1,3 @@
[ ] Permitir más de un remolque en la Carta Porte [ ] Permitir más de un remolque en la Carta Porte
[ ] Campos de captura de Comercio Exterior
[ ] Representación impresa de Comercio Exterior [ ] Representación impresa de Comercio Exterior

View File

@ -1 +1 @@
2.0.0 2.3.2

View File

@ -14,9 +14,4 @@ cryptography==3.4.8
xmlsec xmlsec
segno segno
# pyqrcode
# pypng
# python-escpos # python-escpos
# pyusb
# pyserial
# qrcode

View File

@ -27,6 +27,8 @@ from logbook import Logger
log = Logger('XML') log = Logger('XML')
CFDI_ACTUAL = 'cfdi40' CFDI_ACTUAL = 'cfdi40'
NOMINA_ACTUAL = 'nomina12' NOMINA_ACTUAL = 'nomina12'
PUBLIC = 'PUBLICO EN GENERAL'
CFDI_EGRESO = 'E'
DEFAULT = { DEFAULT = {
'exportacion': '01', 'exportacion': '01',
@ -109,16 +111,16 @@ SAT = {
'schema': ' http://www.sat.gob.mx/leyendasFiscales http://www.sat.gob.mx/sitio_internet/cfd/leyendasFiscales/leyendasFisc.xsd', 'schema': ' http://www.sat.gob.mx/leyendasFiscales http://www.sat.gob.mx/sitio_internet/cfd/leyendasFiscales/leyendasFisc.xsd',
}, },
'cartaporte': { 'cartaporte': {
'version': '2.0', 'version': '3.0',
'prefix': 'cartaporte20', 'prefix': 'cartaporte30',
'xmlns': 'http://www.sat.gob.mx/CartaPorte20', 'xmlns': 'http://www.sat.gob.mx/CartaPorte30',
'schema': ' http://www.sat.gob.mx/CartaPorte20 http://www.sat.gob.mx/sitio_internet/cfd/CartaPorte/CartaPorte20.xsd', 'schema': ' http://www.sat.gob.mx/CartaPorte30 http://www.sat.gob.mx/sitio_internet/cfd/CartaPorte/CartaPorte30.xsd',
}, },
'comercioe': { 'comercioe': {
'version': '1.1', 'version': '2.0',
'prefix': 'cce11', 'prefix': 'cce20',
'xmlns': 'http://www.sat.gob.mx/ComercioExterior11', 'xmlns': 'http://www.sat.gob.mx/ComercioExterior20',
'schema': ' http://www.sat.gob.mx/ComercioExterior11 http://www.sat.gob.mx/sitio_internet/cfd/ComercioExterior11/ComercioExterior11.xsd', 'schema': ' http://www.sat.gob.mx/ComercioExterior20 http://www.sat.gob.mx/sitio_internet/cfd/ComercioExterior20/ComercioExterior20.xsd',
} }
} }
@ -141,6 +143,8 @@ class CFDI(object):
self._carta_porte = False self._carta_porte = False
self._comercio_exterior = False self._comercio_exterior = False
self._divisas = '' self._divisas = ''
self._tipo_de_comprobante = ''
self._exportacion = DEFAULT['exportacion']
self.error = '' self.error = ''
def _now(self): def _now(self):
@ -165,7 +169,9 @@ class CFDI(object):
if 'nomina' in datos: if 'nomina' in datos:
self._nomina(datos['nomina']) self._nomina(datos['nomina'])
return self._to_pretty_xml(ET.tostring(self._cfdi, encoding='utf-8')) xml = self._to_pretty_xml(ET.tostring(self._cfdi, encoding='utf-8'))
return xml
def add_sello(self, sello, cert_txt): def add_sello(self, sello, cert_txt):
self._cfdi.attrib['Sello'] = sello self._cfdi.attrib['Sello'] = sello
@ -195,6 +201,8 @@ class CFDI(object):
self._leyendas = bool(datos['complementos'].get('leyendas', False)) self._leyendas = bool(datos['complementos'].get('leyendas', False))
self._carta_porte = bool(datos['complementos'].get('cartaporte', False)) self._carta_porte = bool(datos['complementos'].get('cartaporte', False))
self._comercio_exterior = bool(datos['complementos'].get('comercioe', False)) self._comercio_exterior = bool(datos['complementos'].get('comercioe', False))
if self._comercio_exterior:
self._exportacion = datos['complementos']['comercioe'].pop('Exportacion')
self._divisas = datos['comprobante'].pop('divisas', '') self._divisas = datos['comprobante'].pop('divisas', '')
@ -285,7 +293,9 @@ class CFDI(object):
# ~ cfdi4 # ~ cfdi4
if not 'Exportacion' in attributes: if not 'Exportacion' in attributes:
attributes['Exportacion'] = DEFAULT['exportacion'] attributes['Exportacion'] = self._exportacion
self._tipo_de_comprobante = attributes['TipoDeComprobante']
self._cfdi = ET.Element('{}:Comprobante'.format(self._pre), attributes) self._cfdi = ET.Element('{}:Comprobante'.format(self._pre), attributes)
return return
@ -317,7 +327,10 @@ class CFDI(object):
return return
def _receptor(self, datos): def _receptor(self, datos):
datos['Nombre'] = datos['Nombre'].upper() receptor_name = datos['Nombre'].upper()
if receptor_name == PUBLIC and self._tipo_de_comprobante == CFDI_EGRESO:
receptor_name = datos['Nombre']
datos['Nombre'] = receptor_name
node_name = '{}:Receptor'.format(self._pre) node_name = '{}:Receptor'.format(self._pre)
emisor = ET.SubElement(self._cfdi, node_name, datos) emisor = ET.SubElement(self._cfdi, node_name, datos)
return return
@ -387,6 +400,10 @@ class CFDI(object):
for field in fields: for field in fields:
if field in datos: if field in datos:
attributes[field] = datos[field] attributes[field] = datos[field]
if not attributes:
return
node_name = '{}:Impuestos'.format(self._pre) node_name = '{}:Impuestos'.format(self._pre)
impuestos = ET.SubElement(self._cfdi, node_name, attributes) impuestos = ET.SubElement(self._cfdi, node_name, attributes)
@ -503,6 +520,47 @@ class CFDI(object):
return return
def _complemento_comercio_exterior(self, datos):
prefix = SAT['comercioe']['prefix']
emisor = datos.pop('emisor')
propietarios = datos.pop('propietarios', {})
receptor = datos.pop('receptor')
destinatario = datos.pop('destinatario', {})
mercancias = datos.pop('mercancias')
attr = {'Version': SAT['comercioe']['version']}
attr.update(datos)
ce = ET.SubElement(
self._complemento, f'{prefix}:ComercioExterior', attr)
attributes = {}
if 'Curp' in emisor:
attributes = {'Curp': emisor.pop('Curp')}
node = ET.SubElement(ce, '{}:Emisor'.format(prefix), attributes)
ET.SubElement(node, '{}:Domicilio'.format(prefix), emisor)
attributes = {}
if 'NumRegIdTrib' in receptor:
attributes = {'NumRegIdTrib': receptor.pop('NumRegIdTrib')}
node = ET.SubElement(ce, '{}:Receptor'.format(prefix), attributes)
ET.SubElement(node, '{}:Domicilio'.format(prefix), receptor)
node = ET.SubElement(ce, '{}:Mercancias'.format(prefix))
fields = ('Marca', 'Modelo', 'SubModelo', 'NumeroSerie')
for row in mercancias:
detalle = {}
for f in fields:
if f in row and row[f]:
detalle[f] = row[f]
row.pop(f)
concepto = ET.SubElement(node, '{}:Mercancia'.format(prefix), row)
if detalle:
ET.SubElement(
concepto, '{}:DescripcionesEspecificas'.format(prefix), detalle)
return
def _complementos(self, datos): def _complementos(self, datos):
if not datos: if not datos:
return return
@ -517,6 +575,11 @@ class CFDI(object):
mercancias = datos.pop('mercancias', ()) mercancias = datos.pop('mercancias', ())
tiposfigura = datos.pop('tiposfigura', ()) tiposfigura = datos.pop('tiposfigura', ())
autotransporte = datos.pop('autotransporte', {})
identificacion = autotransporte.pop('identificacion')
seguros = autotransporte.pop('seguros')
remolques = autotransporte.pop('remolques')
atributos = {'Version': SAT['cartaporte']['version']} atributos = {'Version': SAT['cartaporte']['version']}
atributos.update(datos) atributos.update(datos)
@ -534,10 +597,6 @@ class CFDI(object):
attr = mercancias attr = mercancias
mercancias = attr.pop('mercancias') mercancias = attr.pop('mercancias')
autotransporte = attr.pop('autotransporte')
identificacion = autotransporte.pop('identificacion')
seguros = autotransporte.pop('seguros')
remolque = autotransporte.pop('remolque')
node = ET.SubElement(node_carta, f'{prefix}:Mercancias', attr) node = ET.SubElement(node_carta, f'{prefix}:Mercancias', attr)
for mercancia in mercancias: for mercancia in mercancias:
@ -546,10 +605,10 @@ class CFDI(object):
sub_node = ET.SubElement(node, f'{prefix}:Autotransporte', autotransporte) sub_node = ET.SubElement(node, f'{prefix}:Autotransporte', autotransporte)
ET.SubElement(sub_node, f'{prefix}:IdentificacionVehicular', identificacion) ET.SubElement(sub_node, f'{prefix}:IdentificacionVehicular', identificacion)
ET.SubElement(sub_node, f'{prefix}:Seguros', seguros) ET.SubElement(sub_node, f'{prefix}:Seguros', seguros)
if 'SubTipoRem' in remolque and 'Placa' in remolque \ if remolques:
and remolque['SubTipoRem'] and remolque['Placa']: node_remolques = ET.SubElement(sub_node, f'{prefix}:Remolques')
tmp = ET.SubElement(sub_node, f'{prefix}:Remolques') for remolque in remolques:
ET.SubElement(tmp, f'{prefix}:Remolque', remolque) ET.SubElement(node_remolques, f'{prefix}:Remolque', remolque)
if tiposfigura: if tiposfigura:
sub_node = ET.SubElement(node_carta, f'{prefix}:FiguraTransporte') sub_node = ET.SubElement(node_carta, f'{prefix}:FiguraTransporte')
@ -572,7 +631,9 @@ class CFDI(object):
atributos.update(datos['ine']) atributos.update(datos['ine'])
node_ine = ET.SubElement(self._complemento, 'ine:INE', atributos) node_ine = ET.SubElement(self._complemento, 'ine:INE', atributos)
if ine_key_entidad: if ine_key_entidad:
attr = {'ClaveEntidad': ine_key_entidad, 'Ambito': ine_ambito} attr = {'ClaveEntidad': ine_key_entidad}
if ine_ambito:
attr['Ambito'] = ine_ambito
node_entidad = ET.SubElement(node_ine, 'ine:Entidad', attr) node_entidad = ET.SubElement(node_ine, 'ine:Entidad', attr)
attr = {'IdContabilidad': ine_id_conta} attr = {'IdContabilidad': ine_id_conta}
ET.SubElement(node_entidad, 'ine:Contabilidad', attr) ET.SubElement(node_entidad, 'ine:Contabilidad', attr)
@ -627,58 +688,7 @@ class CFDI(object):
ET.SubElement(node_leyend, '{}:Leyenda'.format(pre), leyend) ET.SubElement(node_leyend, '{}:Leyenda'.format(pre), leyend)
if self._comercio_exterior: if self._comercio_exterior:
prefix = SAT['comercioe']['prefix']
datos = datos.pop('comercioe') datos = datos.pop('comercioe')
emisor = datos.pop('emisor') self._complemento_comercio_exterior(datos)
# ~ propietario = datos.pop('propietario')
receptor = datos.pop('receptor')
destinatario = datos.pop('destinatario')
conceptos = datos.pop('mercancias')
# ~ attributes = {}
# ~ attributes['xmlns:{}'.format(pre)] = \
# ~ 'http://www.sat.gob.mx/ComercioExterior11'
# ~ attributes['xsi:schemaLocation'] = \
# ~ 'http://www.sat.gob.mx/ComercioExterior11 ' \
# ~ 'http://www.sat.gob.mx/sitio_internet/cfd/ComercioExterior11/ComercioExterior11.xsd'
attr = {'Version': SAT['comercioe']['version']}
attr.update(datos)
ce = ET.SubElement(
self._complemento, f'{prefix}:ComercioExterior', attr)
attributes = {}
if 'Curp' in emisor:
attributes = {'Curp': emisor.pop('Curp')}
node = ET.SubElement(ce, '{}:Emisor'.format(prefix), attributes)
ET.SubElement(node, '{}:Domicilio'.format(prefix), emisor)
# ~ if propietario:
# ~ ET.SubElement(ce, '{}:Propietario'.format(prefix), propietario)
attributes = {}
if 'NumRegIdTrib' in receptor:
attributes = {'NumRegIdTrib': receptor.pop('NumRegIdTrib')}
node = ET.SubElement(ce, '{}:Receptor'.format(prefix), attributes)
ET.SubElement(node, '{}:Domicilio'.format(prefix), receptor)
attributes = {}
if 'NumRegIdTrib' in destinatario:
attributes = {'NumRegIdTrib': destinatario.pop('NumRegIdTrib')}
if 'Nombre' in destinatario:
attributes.update({'Nombre': destinatario.pop('Nombre')})
node = ET.SubElement(ce, '{}:Destinatario'.format(prefix), attributes)
ET.SubElement(node, '{}:Domicilio'.format(prefix), destinatario)
node = ET.SubElement(ce, '{}:Mercancias'.format(prefix))
fields = ('Marca', 'Modelo', 'SubModelo', 'NumeroSerie')
for row in conceptos:
detalle = {}
for f in fields:
if f in row:
detalle[f] = row.pop(f)
concepto = ET.SubElement(node, '{}:Mercancia'.format(prefix), row)
if detalle:
ET.SubElement(
concepto, '{}:DescripcionesEspecificas'.format(prefix), detalle)
return return

View File

@ -549,7 +549,7 @@ class AppDocumentos(object):
if not type_doc in ('pdf', 'pre', 'tpdf', 'pdfpago', 'html', 'nompdf'): if not type_doc in ('pdf', 'pre', 'tpdf', 'pdfpago', 'html', 'nompdf'):
resp.append_header('Content-Disposition', resp.append_header('Content-Disposition',
'attachment; filename={}'.format(file_name)) 'attachment; filename={}'.format(file_name))
if type_doc in ('pdf', 'nompdf'): if type_doc in ('pdf', 'nompdf', 'pdfpago'):
resp.append_header('Content-Disposition', resp.append_header('Content-Disposition',
'inline; filename={}'.format(file_name)) 'inline; filename={}'.format(file_name))
resp.content_type = content_type resp.content_type = content_type

View File

@ -30,6 +30,7 @@ import requests
import sqlite3 import sqlite3
import socket import socket
import subprocess import subprocess
import sys
import tempfile import tempfile
import textwrap import textwrap
import threading import threading
@ -44,7 +45,6 @@ from pathlib import Path
from xml.etree import ElementTree as ET from xml.etree import ElementTree as ET
from xml.dom.minidom import parseString from xml.dom.minidom import parseString
try: try:
import uno import uno
from com.sun.star.beans import PropertyValue from com.sun.star.beans import PropertyValue
@ -52,9 +52,20 @@ try:
from com.sun.star.view.PaperFormat import LETTER from com.sun.star.view.PaperFormat import LETTER
APP_LIBO = True APP_LIBO = True
except ImportError: except ImportError:
APP_LIBO = False path_fun = '/usr/lib/libreoffice/program/fundamentalrc'
path_uno = '/usr/lib/libreoffice/program/'
os.environ['URE_BOOTSTRAP'] = f'vnd.sun.star.pathname:{path_fun}'
os.environ['UNO_PATH'] = path_uno
sys.path.append(path_uno)
try:
import uno
from com.sun.star.beans import PropertyValue
from com.sun.star.awt import Size
from com.sun.star.view.PaperFormat import LETTER
APP_LIBO = True
except ImportError:
APP_LIBO = False
# ~ import pyqrcode
from dateutil import parser from dateutil import parser
from lxml import etree from lxml import etree
@ -69,7 +80,6 @@ from settings import DEBUG, MV, log, template_lookup, COMPANIES, DB_SAT, \
PATH_XMLSEC, TEMPLATE_CANCEL, DEFAULT_SAT_PRODUCTO, DECIMALES, DIR_FACTURAS PATH_XMLSEC, TEMPLATE_CANCEL, DEFAULT_SAT_PRODUCTO, DECIMALES, DIR_FACTURAS
from settings import USAR_TOKEN, API, DECIMALES_TAX from settings import USAR_TOKEN, API, DECIMALES_TAX
# ~ from .configpac import AUTH
from .utils import get_qr from .utils import get_qr
@ -293,7 +303,8 @@ def get_sat_productos(key):
def now(): def now():
return datetime.datetime.now().replace(microsecond=0) n = datetime.datetime.now().replace(microsecond=0)
return n
def today(): def today():
@ -741,7 +752,12 @@ class LIBO(object):
if pakings: if pakings:
col8.append((pakings[i],)) col8.append((pakings[i],))
self._total_cantidades += float(cantidad) self._total_cantidades += float(cantidad)
if not count: if not count:
if not cell_5 is None:
cell_5.CellStyle = self._get_style(cell_5)
if not cell_6 is None:
cell_6.CellStyle = self._get_style(cell_6)
return return
style_5 = self._get_style(cell_5) style_5 = self._get_style(cell_5)
@ -945,6 +961,7 @@ class LIBO(object):
return return
# ~ print(data) # ~ print(data)
qr = data.pop('qr', False)
figuras = data.pop('figuras') figuras = data.pop('figuras')
mercancias = data.pop('mercancias') mercancias = data.pop('mercancias')
detalle = mercancias.pop('detalle') detalle = mercancias.pop('detalle')
@ -1003,6 +1020,10 @@ class LIBO(object):
cell_3 = self._set_cell('{cp.ClaveUnidad}', unidad) cell_3 = self._set_cell('{cp.ClaveUnidad}', unidad)
cell_4 = self._set_cell('{cp.Cantidad}', cantidad) cell_4 = self._set_cell('{cp.Cantidad}', cantidad)
cell_5 = self._set_cell('{cp.PesoEnKg}', peso) cell_5 = self._set_cell('{cp.PesoEnKg}', peso)
if cell_1 is None:
break
if count > 0: if count > 0:
row = cell_1.CellAddress.Row + 1 row = cell_1.CellAddress.Row + 1
self._sheet.getRows().insertByIndex(row, count) self._sheet.getRows().insertByIndex(row, count)
@ -1013,7 +1034,72 @@ class LIBO(object):
cell_3 = self._set_cell(v=unidad, cell=cell_3) cell_3 = self._set_cell(v=unidad, cell=cell_3)
cell_4 = self._set_cell(v=cantidad, cell=cell_4) cell_4 = self._set_cell(v=cantidad, cell=cell_4)
cell_5 = self._set_cell(v=peso, cell=cell_5) cell_5 = self._set_cell(v=peso, cell=cell_5)
if qr:
self._timbre_carta(qr)
return
def _timbre_carta(self, qr):
pd = self._sheet.getDrawPage()
image = self._template.createInstance('com.sun.star.drawing.GraphicObjectShape')
gp = self._create_instance('com.sun.star.graphic.GraphicProvider')
pd.add(image)
instance = 'com.sun.star.io.SequenceInputStream'
stream = self._create_instance(instance)
stream.initialize((uno.ByteSequence(qr.getvalue()),))
properties = self._set_properties({'InputStream': stream})
image.Graphic = gp.queryGraphic(properties)
s = Size()
s.Width = 4000
s.Height = 4000
image.setSize(s)
image.Anchor = self._set_cell('{cp.qr}')
return
def _comercio_exterior(self, data):
if not data:
return
emisor = data.pop('emisor')
receptor = data.pop('receptor')
mercancias = data.pop('mercancias')
for k, v in data.items():
self._set_cell(f'{{cce.{k}}}', v)
for k, v in emisor.items():
self._set_cell(f'{{cce.emisor.{k}}}', v)
for k, v in receptor.items():
self._set_cell(f'{{cce.receptor.{k}}}', v)
first = True
count = len(mercancias) - 1
for i, mercancia in enumerate(mercancias):
no_identificacion = mercancia['NoIdentificacion']
fraccion = mercancia['FraccionArancelaria']
unidad = mercancia['UnidadAduana']
cantidad = mercancia['CantidadAduana']
valor_unitario = mercancia['ValorUnitarioAduana']
valor_dolares = mercancia['ValorDolares']
if first:
first = False
cell_1 = self._set_cell('{cce.mercancia.noidentificacion}', no_identificacion)
cell_2 = self._set_cell('{cce.mercancia.fraccionarancelaria}', fraccion)
cell_3 = self._set_cell('{cce.mercancia.unidadaduana}', unidad)
cell_4 = self._set_cell('{cce.mercancia.cantidadaduana}', cantidad)
cell_5 = self._set_cell('{cce.mercancia.valorunitarioaduana}', valor_unitario)
cell_6 = self._set_cell('{cce.mercancia.valordolares}', valor_dolares)
if count > 0:
row = cell_1.CellAddress.Row + 1
self._sheet.getRows().insertByIndex(row, count)
self._copy_paste_rows(cell_1, count)
else:
cell_1 = self._set_cell(v=no_identificacion, cell=cell_1)
cell_2 = self._set_cell(v=fraccion, cell=cell_2)
cell_3 = self._set_cell(v=unidad, cell=cell_3)
cell_4 = self._set_cell(v=cantidad, cell=cell_4)
cell_5 = self._set_cell(v=valor_unitario, cell=cell_5)
cell_6 = self._set_cell(v=valor_dolares, cell=cell_6)
return return
def _nomina(self, data): def _nomina(self, data):
@ -1125,6 +1211,7 @@ class LIBO(object):
return return
def _cfdipays(self, data): def _cfdipays(self, data):
VERSION2 = '2.0'
version = data['Version'] version = data['Version']
related = data.pop('related', []) related = data.pop('related', [])
@ -1158,7 +1245,8 @@ class LIBO(object):
cell_1 = self._set_cell('{doc.uuid}', uuid) cell_1 = self._set_cell('{doc.uuid}', uuid)
cell_2 = self._set_cell('{doc.serie}', serie) cell_2 = self._set_cell('{doc.serie}', serie)
cell_3 = self._set_cell('{doc.folio}', folio) cell_3 = self._set_cell('{doc.folio}', folio)
cell_4 = self._set_cell('{doc.metodopago}', metodo_pago) if version != VERSION2:
cell_4 = self._set_cell('{doc.metodopago}', metodo_pago)
cell_5 = self._set_cell('{doc.moneda}', moneda) cell_5 = self._set_cell('{doc.moneda}', moneda)
cell_6 = self._set_cell('{doc.parcialidad}', parcialidad) cell_6 = self._set_cell('{doc.parcialidad}', parcialidad)
cell_7 = self._set_cell('{doc.saldoanterior}', saldo_anterior, value=True) cell_7 = self._set_cell('{doc.saldoanterior}', saldo_anterior, value=True)
@ -1168,7 +1256,8 @@ class LIBO(object):
col1.append((uuid,)) col1.append((uuid,))
col2.append((serie,)) col2.append((serie,))
col3.append((folio,)) col3.append((folio,))
col4.append((metodo_pago,)) if version != VERSION2:
col4.append((metodo_pago,))
col5.append((moneda,)) col5.append((moneda,))
col6.append((parcialidad,)) col6.append((parcialidad,))
col7.append((float(saldo_anterior),)) col7.append((float(saldo_anterior),))
@ -1194,8 +1283,9 @@ class LIBO(object):
target2 = self._sheet.getCellRangeByPosition(col, row1, col, row2) target2 = self._sheet.getCellRangeByPosition(col, row1, col, row2)
col = cell_3.getCellAddress().Column col = cell_3.getCellAddress().Column
target3 = self._sheet.getCellRangeByPosition(col, row1, col, row2) target3 = self._sheet.getCellRangeByPosition(col, row1, col, row2)
col = cell_4.getCellAddress().Column if version != VERSION2:
target4 = self._sheet.getCellRangeByPosition(col, row1, col, row2) col = cell_4.getCellAddress().Column
target4 = self._sheet.getCellRangeByPosition(col, row1, col, row2)
col = cell_5.getCellAddress().Column col = cell_5.getCellAddress().Column
target5 = self._sheet.getCellRangeByPosition(col, row1, col, row2) target5 = self._sheet.getCellRangeByPosition(col, row1, col, row2)
col = cell_6.getCellAddress().Column col = cell_6.getCellAddress().Column
@ -1210,7 +1300,8 @@ class LIBO(object):
target1.setFormulaArray(tuple(col1)) target1.setFormulaArray(tuple(col1))
target2.setDataArray(tuple(col2)) target2.setDataArray(tuple(col2))
target3.setFormulaArray(tuple(col3)) target3.setFormulaArray(tuple(col3))
target4.setDataArray(tuple(col4)) if version != VERSION2:
target4.setDataArray(tuple(col4))
target5.setDataArray(tuple(col5)) target5.setDataArray(tuple(col5))
target6.setDataArray(tuple(col6)) target6.setDataArray(tuple(col6))
target7.setDataArray(tuple(col7)) target7.setDataArray(tuple(col7))
@ -1247,6 +1338,7 @@ class LIBO(object):
self._divisas(data.get('divisas', {})) self._divisas(data.get('divisas', {}))
self._leyendas(data.get('leyendas', '')) self._leyendas(data.get('leyendas', ''))
self._carta_porte(data.get('carta_porte', {})) self._carta_porte(data.get('carta_porte', {}))
self._comercio_exterior(data.get('comercio_exterior', {}))
self._timbre(data['timbre']) self._timbre(data['timbre'])
@ -1298,6 +1390,7 @@ class LIBO(object):
except KeyError: except KeyError:
msg = 'Hoja no existe' msg = 'Hoja no existe'
return (), msg return (), msg
return cursor.getDataArray(), '' return cursor.getDataArray(), ''
def products(self, path): def products(self, path):
@ -1558,8 +1651,62 @@ class LIBO(object):
return (), msg return (), msg
rows = tuple(data[1:]) rows = tuple(data[1:])
return rows, '' return rows, ''
def _data_to_dict(self, rows):
data = {k: v for k, v in rows if v}
return data
def _current_region_to_tuple(self, cursor):
data = []
cursor.collapseToCurrentRegion()
rows = cursor.getDataArray()[1:]
if len(rows) == 1:
return data
keys = rows[0]
data = [dict(zip(keys, values)) for values in rows[1:]]
return data
def _get_data_ce(self, doc):
msg = ''
data = {}
try:
sheet = doc.Sheets[0]
rango = sheet['A2:B10']
data = self._data_to_dict(rango.DataArray)
rango = sheet['A13:B23']
data['emisor'] = self._data_to_dict(rango.DataArray)
rango = sheet['A26:B36']
data['receptor'] = self._data_to_dict(rango.DataArray)
rango = sheet['A39:B50']
data['destinatario'] = self._data_to_dict(rango.DataArray)
cursor = sheet.createCursorByRange(sheet['E12'])
data['propietarios'] = self._current_region_to_tuple(cursor)
cursor = sheet.createCursorByRange(sheet['A53'])
data['mercancias'] = self._current_region_to_tuple(cursor)
except Exception as e:
msg = str(e)
return data, msg
def get_ce(self, path):
options = {'AsTemplate': True, 'Hidden': True}
doc = self._doc_open(path, options)
if doc is None:
return (), 'No se pudo abrir la plantilla'
data, msg = self._get_data_ce(doc)
doc.close(True)
if len(data) == 1:
msg = 'Sin datos para importar'
return (), msg
return data, ''
def to_pdf(data, emisor_rfc, ods=False, pdf_from='1'): def to_pdf(data, emisor_rfc, ods=False, pdf_from='1'):
rfc = data['emisor']['rfc'] rfc = data['emisor']['rfc']
@ -1578,7 +1725,7 @@ def to_pdf(data, emisor_rfc, ods=False, pdf_from='1'):
version = f'{version}_cn_{version_nomina}' version = f'{version}_cn_{version_nomina}'
if 'carta_porte' in data: if 'carta_porte' in data:
default = 'plantilla_factura_ccp.ods' default = 'plantilla_ccp.ods'
version = '{}_ccp_{}'.format(version, data['carta_porte']['version']) version = '{}_ccp_{}'.format(version, data['carta_porte']['version'])
if data.get('pagos', False): if data.get('pagos', False):
@ -1591,8 +1738,13 @@ def to_pdf(data, emisor_rfc, ods=False, pdf_from='1'):
default = f'plantilla_donatarias_{version}_{version_donatarias}.ods' default = f'plantilla_donatarias_{version}_{version_donatarias}.ods'
version = f'{version}_cd_{version_donatarias}' version = f'{version}_cd_{version_donatarias}'
if 'comercio_exterior' in data:
version_cce = data['comercio_exterior']['version']
default = f'plantilla_cce_{version}_{version_cce}.ods'
version = f'{version}_cce_{version_cce}'
template_name = f'{rfc.lower()}_{version}.ods' template_name = f'{rfc.lower()}_{version}.ods'
# ~ print('T', template_name, default) # ~ print('\nT', template_name, default)
if APP_LIBO: if APP_LIBO:
app = LIBO() app = LIBO()
@ -1727,24 +1879,6 @@ def to_letters(value, currency):
return NumLet(value, currency).letras return NumLet(value, currency).letras
# ~ def get_qr(data, p=True):
# ~ qr = pyqrcode.create(data, mode='binary')
# ~ if p:
# ~ path = get_path_temp('.qr')
# ~ qr.png(path, scale=7)
# ~ return path
# ~ buffer = io.BytesIO()
# ~ qr.png(buffer, scale=8)
# ~ return base64.b64encode(buffer.getvalue()).decode()
# ~ def get_qr2(data, kind='svg'):
# ~ buffer = io.BytesIO()
# ~ segno.make(data).save(buffer, kind=kind, scale=8, border=2)
# ~ return buffer
def _get_relacionados(doc, version): def _get_relacionados(doc, version):
node = doc.find('{}CfdiRelacionados'.format(PRE[version])) node = doc.find('{}CfdiRelacionados'.format(PRE[version]))
if node is None: if node is None:
@ -1939,11 +2073,14 @@ def _totales(doc, cfdi, version):
for n in list(node): for n in list(node):
tmp = CaseInsensitiveDict(n.attrib.copy()) tmp = CaseInsensitiveDict(n.attrib.copy())
if version in CFDI_VERSIONS: if version in CFDI_VERSIONS:
tasa = round(float(tmp['tasaocuota']), DECIMALES) tasa = ''
if 'tasaocuota' in tmp:
tasa = round(float(tmp['tasaocuota']), DECIMALES)
title = 'Traslado {} {}'.format(tn.get(tmp['impuesto']), tasa) title = 'Traslado {} {}'.format(tn.get(tmp['impuesto']), tasa)
else: else:
title = 'Traslado {} {}'.format(tmp['impuesto'], tmp['tasa']) title = 'Traslado {} {}'.format(tmp['impuesto'], tmp['tasa'])
traslados.append((title, float(tmp['importe']))) if 'importe' in tmp:
traslados.append((title, float(tmp['importe'])))
node = imp.find('{}Retenciones'.format(PRE[version])) node = imp.find('{}Retenciones'.format(PRE[version]))
if node is not None: if node is not None:
@ -2137,15 +2274,16 @@ def _get_info_pays_2(node):
def _cfdipays(doc, data, version): def _cfdipays(doc, data, version):
#todo: Obtener versión de complemento pre_pays = PRE_DEFAULT['PAGOS']['PRE']
if version == '4.0': path = f"{PRE[version]}Complemento/{pre_pays}Pagos"
pre_pays = PRE_DEFAULT['PAGOS']['PRE'] node = doc.find(path)
if node is None:
pre_pays = PRE['PAGOS']['1.0']
path = f"{PRE[version]}Complemento/{pre_pays}Pagos" path = f"{PRE[version]}Complemento/{pre_pays}Pagos"
node = doc.find(path) node = doc.find(path)
else:
node = doc.find('{}Complemento/{}Pagos'.format(PRE[version], PRE['pagos']))
if node is None: if node is None:
log.error('Node pays not found...')
return {} return {}
if version == '4.0': if version == '4.0':
@ -2296,12 +2434,14 @@ def upload_file(rfc, opt, file_obj):
ext = tmp[-1].lower() ext = tmp[-1].lower()
versions = ('_3.2.ods', versions = ('_3.2.ods',
'_3.3.ods', '_3.3_cn_1.2.ods', '_3.3_ccp_2.0.ods', '_3.3.json', '_3.3.ods', '_3.3_cd_1.1.ods', '_3.3_cp_1.0.ods', '_3.3_cn_1.2.ods', '_3.3_ccp_2.0.ods', '_3.3.json',
'_4.0.ods', '_4.0.ods',
'_4.0_cn_1.2.ods', '_4.0_cn_1.2.ods',
'_4.0_cp_2.0.ods', '_4.0_cp_2.0.ods',
'_4.0_ccp_2.0.ods', '_4.0_ccp_2.0.ods',
'_4.0_ccp_3.0.ods',
'_4.0_cd_1.1.ods', '_4.0_cd_1.1.ods',
'_4.0_cce_2.0.ods',
'_4.0.json', '_4.0.json',
) )
if opt in versions: if opt in versions:
@ -2423,6 +2563,15 @@ def upload_file(rfc, opt, file_obj):
name = '{}_nomina.ods'.format(rfc.lower()) name = '{}_nomina.ods'.format(rfc.lower())
path = _join(PATH_MEDIA, 'tmp', name) path = _join(PATH_MEDIA, 'tmp', name)
elif opt == 'ceods':
tmp = file_obj.filename.split('.')
ext = tmp[-1].lower()
if ext != 'ods':
msg = 'Extensión de archivo incorrecta, selecciona un archivo ODS'
return {'status': 'server', 'name': msg, 'ok': False}
name = '{}_ce.ods'.format(rfc.lower())
path = _join(PATH_MEDIA, 'tmp', name)
if save_file(path, file_obj.file.read()): if save_file(path, file_obj.file.read()):
return {'status': 'server', 'name': file_obj.filename, 'ok': True} return {'status': 'server', 'name': file_obj.filename, 'ok': True}
@ -2900,6 +3049,20 @@ def import_invoice(rfc):
return (), 'No se encontro LibreOffice' return (), 'No se encontro LibreOffice'
def import_ceods(rfc):
name = '{}_ce.ods'.format(rfc.lower())
path = _join(PATH_MEDIA, 'tmp', name)
if not is_file(path):
return (), 'No se encontró la plantilla'
if APP_LIBO:
app = LIBO()
if app.is_running:
return app.get_ce(path)
return (), 'No se encontro LibreOffice'
def calc_to_date(value): def calc_to_date(value):
return datetime.date.fromordinal(int(value) + 693594) return datetime.date.fromordinal(int(value) + 693594)
@ -2999,4 +3162,8 @@ def parse_xml2(xml_str):
return etree.fromstring(xml_str.encode('utf-8')) return etree.fromstring(xml_str.encode('utf-8'))
def get_idccp():
uuid4 = str(uuid.uuid4()).upper()
custom_uuid_str = f'CCC{uuid4[3:]}'
return custom_uuid_str

View File

@ -261,10 +261,13 @@ class CfdiToDict(object):
'cfdi4.0': 'http://www.sat.gob.mx/cfd/4', 'cfdi4.0': 'http://www.sat.gob.mx/cfd/4',
} }
NS = { NS = {
'tfd': 'http://www.sat.gob.mx/TimbreFiscalDigital',
'divisas': 'http://www.sat.gob.mx/divisas', 'divisas': 'http://www.sat.gob.mx/divisas',
'leyendasFisc': 'http://www.sat.gob.mx/leyendasFiscales', 'leyendasFisc': 'http://www.sat.gob.mx/leyendasFiscales',
'cartaporte20': 'http://www.sat.gob.mx/CartaPorte20', 'cartaporte20': 'http://www.sat.gob.mx/CartaPorte20',
'cartaporte30': 'http://www.sat.gob.mx/CartaPorte30',
'nomina12': 'http://www.sat.gob.mx/nomina12', 'nomina12': 'http://www.sat.gob.mx/nomina12',
'cce20': 'http://www.sat.gob.mx/ComercioExterior20',
} }
tipo_figura = { tipo_figura = {
'01': '[01] Operador', '01': '[01] Operador',
@ -396,11 +399,23 @@ class CfdiToDict(object):
self.version = self._root.attrib['Version'] self.version = self._root.attrib['Version']
ns = f'cfdi{self.version}' ns = f'cfdi{self.version}'
self.NS['cfdi'] = self.NS_VERSION[ns] self.NS['cfdi'] = self.NS_VERSION[ns]
self._timbre_fiscal()
self._informacion_global() self._informacion_global()
self._receptor() self._receptor()
self._complementos() self._complementos()
return return
def _timbre_fiscal(self):
path = '//tfd:TimbreFiscalDigital'
data = self._root.xpath(path, namespaces=self.NS)
if not data:
return
data = data[0]
attr = CaseInsensitiveDict(data.attrib)
self._fecha_timbrado = attr['FechaTimbrado']
return
def _informacion_global(self): def _informacion_global(self):
self._values['informacion_global'] = {} self._values['informacion_global'] = {}
@ -513,6 +528,94 @@ class CfdiToDict(object):
self._values['carta_porte'] = values self._values['carta_porte'] = values
self._complemento_carta_porte(complemento)
self._complemento_comercio_exterior(complemento)
return
def _complemento_carta_porte(self, complemento):
path = '//cartaporte30:CartaPorte'
carta_porte = complemento.xpath(path, namespaces=self.NS)
if carta_porte:
self._get_carta_porte_3(carta_porte)
return
def _get_carta_porte_3(self, carta_porte):
URL = 'https://verificacfdi.facturaelectronica.sat.gob.mx/verificaccp/default.aspx'
PRE = '//cartaporte30'
values = CaseInsensitiveDict(carta_porte[0].attrib)
idccp = values['idccp']
for node in carta_porte[0]:
if 'FiguraTransporte' in node.tag:
figuras = CaseInsensitiveDict(node[0].attrib)
figuras['TipoFigura'] = self.tipo_figura[figuras['TipoFigura']]
values['figuras'] = figuras
elif 'Mercancias' in node.tag:
mercancias = CaseInsensitiveDict(node.attrib)
detalle = [CaseInsensitiveDict(n.attrib)
for n in node if 'Mercancia' in n.tag]
values['mercancias'] = {
'mercancias': mercancias,
'detalle': detalle,
}
path = f'{PRE}:Autotransporte'
node_auto = node.xpath(path, namespaces=self.NS)[0]
values_auto = CaseInsensitiveDict(node_auto.attrib)
values['autotransporte'] = values_auto
path = f'{PRE}:IdentificacionVehicular'
node_tmp = node_auto.xpath(path, namespaces=self.NS)[0]
values_auto = CaseInsensitiveDict(node_tmp.attrib)
values['autotransporte'].update(values_auto)
path = f'{PRE}:Seguros'
node_tmp = node_auto.xpath(path, namespaces=self.NS)[0]
values_auto = CaseInsensitiveDict(node_tmp.attrib)
values['autotransporte'].update(values_auto)
path = f'{PRE}:Remolques'
try:
node_tmp = node_auto.xpath(path, namespaces=self.NS)[0][0]
values_auto = CaseInsensitiveDict(node_tmp.attrib)
values['autotransporte'].update(values_auto)
except IndexError:
pass
elif 'Ubicaciones' in node.tag:
ubicaciones = []
for n in node:
ubicacion = CaseInsensitiveDict(n.attrib)
if ubicacion['TipoUbicacion'] == 'Origen':
fecha_origen = ubicacion['FechaHoraSalidaLlegada']
ubicacion['domicilio'] = self._set_carta_porte_domicilio(
CaseInsensitiveDict(n[0].attrib))
ubicaciones.append(ubicacion)
values['FechaOrigen'] = fecha_origen
values['ubicaciones'] = ubicaciones
qr_data = f'{URL}?IdCCP={idccp}&FechaOrig={fecha_origen}&FechaTimb={self._fecha_timbrado}'
values['qr'] = get_qr(qr_data, 'png')
self._values['carta_porte'] = values
return
def _complemento_comercio_exterior(self, complemento):
path = '//cce20:ComercioExterior'
comercio_exterior = complemento.xpath(path, namespaces=self.NS)
if comercio_exterior:
values = CaseInsensitiveDict(comercio_exterior[0].attrib)
for node in comercio_exterior[0]:
if 'Emisor' in node.tag:
values['emisor'] = CaseInsensitiveDict(node.attrib)
values['emisor'].update(CaseInsensitiveDict(node[0].attrib))
elif 'Receptor' in node.tag:
values['receptor'] = CaseInsensitiveDict(node.attrib)
values['receptor'].update(CaseInsensitiveDict(node[0].attrib))
elif 'Mercancias' in node.tag:
mercancias = [
CaseInsensitiveDict(m.attrib) for m in node]
values['mercancias'] = mercancias
self._values['comercio_exterior'] = values
return return
@ -772,7 +875,8 @@ def db_backup_local():
def now(): def now():
return datetime.datetime.now().replace(microsecond=0) n = datetime.datetime.now().replace(microsecond=0)
return n
def get_days(date): def get_days(date):
@ -860,9 +964,6 @@ def get_cert(args):
def make_xml(data, certificado): def make_xml(data, certificado):
cert = SATCertificate(certificado.cer, certificado.key_enc.encode()) cert = SATCertificate(certificado.cer, certificado.key_enc.encode())
# ~ if DEBUG:
# ~ data['emisor']['Rfc'] = certificado.rfc
# ~ data['emisor']['RegimenFiscal'] = '603'
cfdi = CFDI() cfdi = CFDI()
xml = ET.parse(BytesIO(cfdi.get_xml(data).encode())) xml = ET.parse(BytesIO(cfdi.get_xml(data).encode()))
@ -1086,6 +1187,7 @@ def _save_template(rfc, name, file_obj):
rfc = rfc.lower() rfc = rfc.lower()
path = _join(PATHS['USER'], f'{rfc}{name}') path = _join(PATHS['USER'], f'{rfc}{name}')
if save_file(path, file_obj.file.read()): if save_file(path, file_obj.file.read()):
result['ok'] = True result['ok'] = True
@ -1106,3 +1208,18 @@ def get_qr(data, kind='svg', in_base64=False):
if in_base64: if in_base64:
qr = base64.b64encode(qr.getvalue()).decode() qr = base64.b64encode(qr.getvalue()).decode()
return qr return qr
def to_date(value):
t = now().time()
d = datetime.datetime.strptime(value.split(' ')[0], '%Y-%m-%d')
dt = datetime.datetime.combine(d, t)
return dt
def adjust_time(date_invoice, hours):
new_date = date_invoice
if hours:
time_change = datetime.timedelta(hours=hours)
new_date = date_invoice + time_change
return new_date

View File

@ -70,6 +70,9 @@ class StorageEngine(object):
def _get_importinvoice(self, values): def _get_importinvoice(self, values):
return main.import_invoice() return main.import_invoice()
def _get_importceods(self, values):
return main.import_ceods()
def _get_main(self, values, session): def _get_main(self, values, session):
return main.config_main(session['userobj']) return main.config_main(session['userobj'])

View File

@ -23,6 +23,7 @@ import sqlite3
from peewee import * from peewee import *
from playhouse.fields import PasswordField, ManyToManyField from playhouse.fields import PasswordField, ManyToManyField
from playhouse.shortcuts import case, SQL, cast from playhouse.shortcuts import case, SQL, cast
from psycopg2.errors import UniqueViolation
if __name__ == '__main__': if __name__ == '__main__':
@ -54,6 +55,7 @@ from settings import (
URL, URL,
VALUES_PDF, VALUES_PDF,
VERSION as VERSION_EMPRESA_LIBRE, VERSION as VERSION_EMPRESA_LIBRE,
RESICO,
RFCS, RFCS,
) )
@ -77,7 +79,6 @@ def conectar(opt):
db = { db = {
'sqlite': SqliteDatabase, 'sqlite': SqliteDatabase,
'postgres': PostgresqlDatabase, 'postgres': PostgresqlDatabase,
'mysql': MySQLDatabase,
} }
db_type = opt.pop('type') db_type = opt.pop('type')
db_name = opt.pop('name') db_name = opt.pop('name')
@ -155,7 +156,7 @@ def upload_file(rfc, opt, file_obj):
result = util.upload_file(rfc, opt, file_obj) result = util.upload_file(rfc, opt, file_obj)
if result['ok']: if result['ok']:
names = ('bdfl', 'employees', 'nomina', 'products', 'invoiceods') names = ('bdfl', 'employees', 'nomina', 'products', 'invoiceods', 'ceods')
if not opt in names: if not opt in names:
Configuracion.add({opt: file_obj.filename}) Configuracion.add({opt: file_obj.filename})
return result return result
@ -226,6 +227,7 @@ def import_invoice():
return {'ok': False, 'msg': msg} return {'ok': False, 'msg': msg}
obj = Productos.get(Productos.clave==row[0]) obj = Productos.get(Productos.clave==row[0])
if isinstance(row[2], str): if isinstance(row[2], str):
msg = 'El Precio Unitario debe ser un número, debe ser 0.00, si no quieres cambiarlo' msg = 'El Precio Unitario debe ser un número, debe ser 0.00, si no quieres cambiarlo'
return {'ok': False, 'msg': msg} return {'ok': False, 'msg': msg}
@ -247,6 +249,7 @@ def import_invoice():
'id_product': obj.id, 'id_product': obj.id,
'delete': '-', 'delete': '-',
'clave': obj.clave, 'clave': obj.clave,
'clave_sat': obj.clave_sat,
'descripcion': description or obj.descripcion, 'descripcion': description or obj.descripcion,
'pedimento': pedimento, 'pedimento': pedimento,
'unidad': obj.unidad.id, 'unidad': obj.unidad.id,
@ -264,6 +267,18 @@ def import_invoice():
return {'ok': True, 'rows': tuple(products)} return {'ok': True, 'rows': tuple(products)}
def import_ceods():
log.info('Importando plantilla...')
emisor = Emisor.select()[0]
data, msg = util.import_ceods(emisor.rfc)
if not data:
return {'ok': False, 'msg': msg}
log.info('Plantilla importada...')
return {'ok': True, 'data': data}
def get_doc(type_doc, id, rfc): def get_doc(type_doc, id, rfc):
types = { types = {
'xml': 'application/xml', 'xml': 'application/xml',
@ -323,7 +338,8 @@ def config_main(user):
'timbres': 0, 'timbres': 0,
'decimales_precios': DECIMALES, 'decimales_precios': DECIMALES,
'pagos': Configuracion.get_bool('chk_config_pagos'), 'pagos': Configuracion.get_bool('chk_config_pagos'),
'pays_data_bank': Configuracion.get_bool('chk_cfg_pays_data_bank') 'pays_data_bank': Configuracion.get_bool('chk_cfg_pays_data_bank'),
'show_filter_by_day': Configuracion.get_bool('chk_config_show_filter_by_day'),
} }
dp = Configuracion.get_bool('chk_config_decimales_precios') dp = Configuracion.get_bool('chk_config_decimales_precios')
if dp: if dp:
@ -365,6 +381,7 @@ def config_timbrar():
'cfdi_folio_custom': Configuracion.get_bool('chk_folio_custom'), 'cfdi_folio_custom': Configuracion.get_bool('chk_folio_custom'),
'cfdi_leyendasfiscales': Configuracion.get_bool('chk_config_leyendas_fiscales'), 'cfdi_leyendasfiscales': Configuracion.get_bool('chk_config_leyendas_fiscales'),
'cfdi_show_total_cant': Configuracion.get_bool('chk_config_show_total_cant'), 'cfdi_show_total_cant': Configuracion.get_bool('chk_config_show_total_cant'),
'cfdi_change_date_invoice': Configuracion.get_bool('chk_config_change_date_invoice'),
} }
return conf return conf
@ -677,7 +694,9 @@ class Configuracion(BaseModel):
'chk_config_invoice_by_ticket', 'chk_config_invoice_by_ticket',
'chk_config_show_total_cant', 'chk_config_show_total_cant',
'chk_cancel_invoices_by_admin', 'chk_cancel_invoices_by_admin',
'chk_config_change_date_invoice',
'chk_cancel_tickets_by_admin', 'chk_cancel_tickets_by_admin',
'chk_config_show_filter_by_day',
) )
data = (Configuracion data = (Configuracion
.select() .select()
@ -1011,6 +1030,7 @@ class Emisor(BaseModel):
logo = TextField(default='') logo = TextField(default='')
registro_patronal = TextField(default='') registro_patronal = TextField(default='')
regimenes = ManyToManyField(SATRegimenes, related_name='emisores') regimenes = ManyToManyField(SATRegimenes, related_name='emisores')
hours = IntegerField(default=0)
class Meta: class Meta:
order_by = ('nombre',) order_by = ('nombre',)
@ -1071,7 +1091,8 @@ class Emisor(BaseModel):
'ong_fecha_dof': obj.fecha_dof, 'ong_fecha_dof': obj.fecha_dof,
'token_soporte': obj.token_soporte, 'token_soporte': obj.token_soporte,
'emisor_registro_patronal': obj.registro_patronal, 'emisor_registro_patronal': obj.registro_patronal,
'regimenes': [row.id for row in obj.regimenes] 'regimenes': [row.id for row in obj.regimenes],
'emisor_hours': obj.hours
} }
else: else:
row['emisor'] = {'emisor_rfc': rfc} row['emisor'] = {'emisor_rfc': rfc}
@ -1150,6 +1171,8 @@ class Emisor(BaseModel):
fields['registro_patronal'] = fields.pop('emisor_registro_patronal', '') fields['registro_patronal'] = fields.pop('emisor_registro_patronal', '')
fields['regimenes'] = SATRegimenes.get_( fields['regimenes'] = SATRegimenes.get_(
util.loads(fields['regimenes'])) util.loads(fields['regimenes']))
fields['hours'] = int(fields.pop('emisor_hours', 0))
return fields return fields
@classmethod @classmethod
@ -1204,10 +1227,11 @@ class Certificado(BaseModel):
return result return result
obj = Certificado.get(Certificado.es_fiel==False) obj = Certificado.get(Certificado.es_fiel==False)
if obj.rfc != cert.rfc: if not DEBUG:
result['ok'] = False if obj.rfc != cert.rfc:
result['msg'] = 'El RFC del certificado no corresponde.' result['ok'] = False
return result result['msg'] = 'El RFC del certificado no corresponde.'
return result
obj.key = cert._key obj.key = cert._key
obj.key_enc = cert.key_enc obj.key_enc = cert.key_enc
@ -2221,7 +2245,7 @@ class CuentasBanco(BaseModel):
with database_proxy.transaction(): with database_proxy.transaction():
try: try:
obj = CuentasBanco.create(**values) obj = CuentasBanco.create(**values)
except IntegrityError: except (IntegrityError, UniqueViolation):
msg = 'Esta cuenta ya existe' msg = 'Esta cuenta ya existe'
return {'ok': False, 'msg': msg} return {'ok': False, 'msg': msg}
@ -2963,6 +2987,16 @@ class Socios(BaseModel):
fields.pop('accounts', '') fields.pop('accounts', '')
regimenes = fields.pop('regimenes', ()) regimenes = fields.pop('regimenes', ())
w = (
(Socios.rfc==fields['rfc']) &
(Socios.slug==fields['slug']) &
(Socios.id!=id)
)
if Socios.select().where(w).exists():
msg = 'Ya existe otro emisor con este RFC y Razón Social'
data = {'ok': False, 'row': {}, 'new': True, 'msg': msg}
return data
try: try:
q = Socios.update(**fields).where(Socios.id==id) q = Socios.update(**fields).where(Socios.id==id)
q.execute() q.execute()
@ -3381,11 +3415,25 @@ class MovimientosBanco(BaseModel):
msg = 'El movimiento esta conciliado, no se puede cancelar' msg = 'El movimiento esta conciliado, no se puede cancelar'
return {'ok': False, 'msg': msg} return {'ok': False, 'msg': msg}
# ~ filters = (CfdiPagos.movimiento==obj) filters = (
# ~ cp = CfdiPagos.select().where(filters).count() (CfdiPagos.movimiento==obj) &
# ~ if cp > 0: (CfdiPagos.uuid.is_null(False)) &
# ~ msg = 'El movimiento tiene Factura de Pago, no se puede cancelar' (CfdiPagos.cancelada==False)
# ~ return {'ok': False, 'msg': msg} )
cp = CfdiPagos.select().where(filters).count()
if cp > 0:
msg = 'El movimiento tiene Factura de Pago activas, no se puede cancelar'
return {'ok': False, 'msg': msg}
filters = (
(CfdiPagos.movimiento==obj) &
(CfdiPagos.uuid.is_null(True)) &
(CfdiPagos.error!='')
)
cp = CfdiPagos.select().where(filters).count()
if cp > 0:
msg = 'El movimiento tiene Factura de Pago con error, no se puede cancelar'
return {'ok': False, 'msg': msg}
with database_proxy.transaction(): with database_proxy.transaction():
obj.cancelado = True obj.cancelado = True
@ -4335,6 +4383,14 @@ class Productos(BaseModel):
if count: if count:
return False return False
count = (TicketsDetalle
.select(fn.COUNT(TicketsDetalle.id)).join(Productos)
.where(Productos.id==id)
.count()
)
if count:
return False
with database_proxy.transaction(): with database_proxy.transaction():
obj = Productos.get(Productos.id==id) obj = Productos.get(Productos.id==id)
obj.impuestos.clear() obj.impuestos.clear()
@ -4487,7 +4543,7 @@ class Facturas(BaseModel):
version = TextField(default=PRE_DEFAULT['CFDI']['VERSION']) version = TextField(default=PRE_DEFAULT['CFDI']['VERSION'])
serie = TextField(default='') serie = TextField(default='')
folio = BigIntegerField(default=0) folio = BigIntegerField(default=0)
fecha = DateTimeField(default=util.now, formats=['%Y-%m-%d %H:%M:%S']) fecha = DateTimeField(default=utils.now, formats=['%Y-%m-%d %H:%M:%S'])
fecha_timbrado = DateTimeField(null=True) fecha_timbrado = DateTimeField(null=True)
forma_pago = TextField(default='') forma_pago = TextField(default='')
condiciones_pago = TextField(default='') condiciones_pago = TextField(default='')
@ -4642,7 +4698,11 @@ class Facturas(BaseModel):
fm = (Facturas.fecha.month > 0) fm = (Facturas.fecha.month > 0)
else: else:
fm = (Facturas.fecha.month == int(values['month'])) fm = (Facturas.fecha.month == int(values['month']))
filters = (fy & fm) if values['day'] == '-1':
filters = (fy & fm)
else:
fd = (Facturas.fecha.day == int(values['day']))
filters = (fy & fm & fd)
if 'client' in values: if 'client' in values:
filters &= (Socios.nombre==values['client']) filters &= (Socios.nombre==values['client'])
@ -4763,16 +4823,6 @@ class Facturas(BaseModel):
obj = SATTipoRelacion.get(SATTipoRelacion.key==invoice.tipo_relacion) obj = SATTipoRelacion.get(SATTipoRelacion.key==invoice.tipo_relacion)
values['tiporelacion'] = str(obj) values['tiporelacion'] = str(obj)
# ~ use_packing = Configuracion.get_bool('chk_use_packing')
# ~ if use_packing:
# ~ w = FacturasDetalle.factura == invoice
# ~ q = (FacturasDetalle
# ~ .select(FacturasDetalle.empaques)
# ~ .where(w)
# ~ .order_by(FacturasDetalle.id.asc())
# ~ .tuples())
# ~ values['pakings'] = [str(int(r[0])) for r in q]
return values return values
def _get_not_in_xml2(self, invoice, data): def _get_not_in_xml2(self, invoice, data):
@ -4784,6 +4834,8 @@ class Facturas(BaseModel):
Socios.municipio, Socios.municipio,
Socios.estado, Socios.estado,
Socios.pais, Socios.pais,
Socios.correo_facturas,
Socios.telefonos,
) )
where = (Socios.id==invoice.cliente.id) where = (Socios.id==invoice.cliente.id)
partner = Socios.select(*fields).where(where).dicts()[0] partner = Socios.select(*fields).where(where).dicts()[0]
@ -5513,16 +5565,39 @@ class Facturas(BaseModel):
if not valores: if not valores:
return return
info = {}
values = utils.loads(valores) values = utils.loads(valores)
info['IdCCP'] = util.get_idccp()
info['TranspInternac'] = values['TranspInternac']
autotransporte = {
'PermSCT': values['autotransporte'].pop('PermSCT'),
'NumPermisoSCT': values['autotransporte'].pop('NumPermisoSCT'),
}
identificacion = values['autotransporte']
if 'PesoBrutoVehicular' in identificacion \
and isinstance(identificacion['PesoBrutoVehicular'], float):
identificacion['PesoBrutoVehicular'] = f"{identificacion['PesoBrutoVehicular']:.2f}"
info['autotransporte'] = autotransporte
info['autotransporte']['identificacion'] = identificacion
info['autotransporte']['seguros'] = values['seguros']
info['autotransporte']['remolques'] = values['remolques']
total_distance = 0.00 total_distance = 0.00
total_weight = 0.00 total_weight = 0.00
mercancias = values['mercancias'] mercancias = values['mercancias']
for mercancia in mercancias['mercancias']: for mercancia in mercancias:
total_weight += float(mercancia['PesoEnKg']) total_weight += float(mercancia['PesoEnKg'])
if isinstance(mercancia['PesoEnKg'], (int, float)): if isinstance(mercancia['PesoEnKg'], (int, float)):
mercancia['PesoEnKg'] = f"{mercancia['PesoEnKg']:.2f}" mercancia['PesoEnKg'] = f"{mercancia['PesoEnKg']:.2f}"
mercancias['PesoBrutoTotal'] = f"{total_weight:.2f}" if isinstance(mercancia['Cantidad'], str):
mercancia['Cantidad'] = float(mercancia['Cantidad'])
mercancia['Cantidad'] = f"{mercancia['Cantidad']:.2f}"
info['mercancias'] = {}
info['mercancias']['UnidadPeso'] = values['unidad_peso']
info['mercancias']['PesoBrutoTotal'] = f"{total_weight:.2f}"
info['mercancias']['NumTotalMercancias'] = f"{len(mercancias):,}"
info['mercancias']['mercancias'] = mercancias
ubicaciones = values['ubicaciones'] ubicaciones = values['ubicaciones']
for ubicacion in ubicaciones: for ubicacion in ubicaciones:
@ -5546,12 +5621,15 @@ class Facturas(BaseModel):
'CodigoPostal': cp, 'CodigoPostal': cp,
} }
values['TotalDistRec'] = f"{total_distance:.2f}" info['TotalDistRec'] = f"{total_distance:.2f}"
# ~ print(2, values) info['ubicaciones'] = ubicaciones
info['tiposfigura'] = values['tiposfigura']
# ~ print(2, info)
data = { data = {
'factura': invoice, 'factura': invoice,
'nombre': 'cartaporte', 'nombre': 'cartaporte',
'valores': utils.dumps(values), 'valores': utils.dumps(info),
} }
FacturasComplementos.create(**data) FacturasComplementos.create(**data)
return return
@ -5560,12 +5638,9 @@ class Facturas(BaseModel):
if not valores: if not valores:
return return
# ~ values = utils.loads(valores)
data = { data = {
'factura': invoice, 'factura': invoice,
'nombre': 'comercioe', 'nombre': 'comercioe',
# ~ 'valores': utils.dumps(values),
'valores': valores, 'valores': valores,
} }
FacturasComplementos.create(**data) FacturasComplementos.create(**data)
@ -5595,7 +5670,19 @@ class Facturas(BaseModel):
leyendas_fiscales = utils.loads(values.pop('leyendas_fiscales', '[]')) leyendas_fiscales = utils.loads(values.pop('leyendas_fiscales', '[]'))
values['fecha'] = utils.now()
date_invoice = values.pop('date')
if Configuracion.get_bool('chk_config_change_date_invoice'):
values['fecha'] = utils.to_date(date_invoice)
days = (utils.now() - values['fecha']).days
if days > 2:
msg = 'Fecha inválida'
data = {'ok': False, 'row': {}, 'new': True, 'msg': msg}
return data
emisor = Emisor.select()[0] emisor = Emisor.select()[0]
values['fecha'] = utils.adjust_time(values['fecha'], emisor.hours)
values['serie'] = cls._get_serie(cls, user, values['serie']) values['serie'] = cls._get_serie(cls, user, values['serie'])
if Configuracion.get_bool('chk_folio_custom') and folio_custom: if Configuracion.get_bool('chk_folio_custom') and folio_custom:
fc = {'folio': folio_custom, 'serie': values['serie']} fc = {'folio': folio_custom, 'serie': values['serie']}
@ -5676,13 +5763,14 @@ class Facturas(BaseModel):
decimales_precios = Configuracion.get_bool('chk_config_decimales_precios') decimales_precios = Configuracion.get_bool('chk_config_decimales_precios')
invoice_by_ticket = Configuracion.get_bool('chk_config_invoice_by_ticket') invoice_by_ticket = Configuracion.get_bool('chk_config_invoice_by_ticket')
is_global = bool(invoice.periodicidad) is_global = bool(invoice.periodicidad)
base_iva_exento = 0.0
data_global = {} data_global = {}
if is_global: if is_global:
now = utils.now() values = invoice.periodicidad.split('|')
data_global['Periodicidad'] = invoice.periodicidad data_global['Periodicidad'] = values[0]
data_global['Meses'] = now.strftime('%m') data_global['Meses'] = values[1]
data_global['Año'] = now.strftime('%Y') data_global['Año'] = values[2]
frm_vu = FORMAT frm_vu = FORMAT
if decimales_precios: if decimales_precios:
@ -5768,6 +5856,10 @@ class Facturas(BaseModel):
rows = FacturasDetalle.select().where(FacturasDetalle.factura==invoice) rows = FacturasDetalle.select().where(FacturasDetalle.factura==invoice)
for row in rows: for row in rows:
object_tax = '02'
if not row.producto is None:
object_tax = row.producto.objeto_impuesto
if is_global: if is_global:
key_sat = row.clave_sat key_sat = row.clave_sat
key = row.clave key = row.clave
@ -5782,6 +5874,7 @@ class Facturas(BaseModel):
'Descripcion': row.descripcion, 'Descripcion': row.descripcion,
'ValorUnitario': frm_vu.format(row.valor_unitario), 'ValorUnitario': frm_vu.format(row.valor_unitario),
'Importe': FORMAT.format(row.importe), 'Importe': FORMAT.format(row.importe),
'ObjetoImp': object_tax,
} }
if not is_global: if not is_global:
concepto['Unidad'] = SATUnidades.get(SATUnidades.key==row.unidad).name[:20] concepto['Unidad'] = SATUnidades.get(SATUnidades.key==row.unidad).name[:20]
@ -5811,58 +5904,76 @@ class Facturas(BaseModel):
if invoice.tipo_comprobante != 'T': if invoice.tipo_comprobante != 'T':
if is_global: if is_global:
ticket = (Tickets ticket = None
.get(fn.Concat(Tickets.serie, Tickets.folio)==row.clave) try:
) where = (
product_taxes = (TicketsImpuestos (fn.Concat(Tickets.serie, Tickets.folio)==row.clave) &
.select() (Tickets.estatus=='Facturado')
.where(TicketsImpuestos.ticket==ticket) )
) ticket = (Tickets
.get(where)
)
product_taxes = (TicketsImpuestos
.select()
.where(TicketsImpuestos.ticket==ticket)
)
except Tickets.DoesNotExist:
product_taxes = row.producto.impuestos
else: else:
product_taxes = row.producto.impuestos product_taxes = row.producto.impuestos
for impuesto in product_taxes: if object_tax == '02':
base = float(row.importe - row.descuento) for impuesto in product_taxes:
if is_global: base = float(row.importe - row.descuento)
base = float(impuesto.base) if is_global and not ticket is None:
impuesto = impuesto.impuesto base = float(impuesto.base)
impuesto = impuesto.impuesto
if impuesto.tipo == 'E':
tax = {
'Base': FORMAT.format(base),
'Impuesto': '002',
'TipoFactor': 'Exento',
}
traslados.append(tax)
base_iva_exento += base
continue
if impuesto.key == '000':
continue
tasa = float(impuesto.tasa)
if tax_decimals:
import_tax = round(tasa * base, DECIMALES_TAX)
tmp += import_tax
xml_importe = FORMAT_TAX.format(import_tax)
else:
import_tax = round(tasa * base, DECIMALES)
xml_importe = FORMAT.format(import_tax)
tipo_factor = 'Tasa'
if impuesto.factor != 'T':
tipo_factor = 'Cuota'
tasa_cuota = str(impuesto.tasa)
if emisor['RegimenFiscal'] == RESICO \
and len(emisor['Rfc']) == 13 \
and len(receptor['Rfc']) == 12 \
and tasa_cuota == '0.012500':
tasa_cuota = '0.0125'
if impuesto.tipo == 'E':
tax = { tax = {
'Base': FORMAT.format(base), "Base": FORMAT.format(base),
'Impuesto': '002', "Impuesto": impuesto.key,
'TipoFactor': 'Exento', "TipoFactor": tipo_factor,
"TasaOCuota": tasa_cuota,
"Importe": xml_importe,
} }
traslados.append(tax) if impuesto.tipo == 'T':
continue traslados.append(tax)
else:
if impuesto.key == '000': retenciones.append(tax)
continue
tasa = float(impuesto.tasa)
if tax_decimals:
import_tax = round(tasa * base, DECIMALES_TAX)
tmp += import_tax
xml_importe = FORMAT_TAX.format(import_tax)
else:
import_tax = round(tasa * base, DECIMALES)
xml_importe = FORMAT.format(import_tax)
tipo_factor = 'Tasa'
if impuesto.factor != 'T':
tipo_factor = 'Cuota'
tax = {
"Base": FORMAT.format(base),
"Impuesto": impuesto.key,
"TipoFactor": tipo_factor,
"TasaOCuota": str(impuesto.tasa),
"Importe": xml_importe,
}
if impuesto.tipo == 'T':
traslados.append(tax)
else:
retenciones.append(tax)
if traslados: if traslados:
taxes['traslados'] = traslados taxes['traslados'] = traslados
@ -5871,15 +5982,6 @@ class Facturas(BaseModel):
concepto['impuestos'] = taxes concepto['impuestos'] = taxes
# cfdi4
if not is_global:
concepto['ObjetoImp'] = row.producto.objeto_impuesto
else:
if taxes:
concepto['ObjetoImp'] = '02'
else:
concepto['ObjetoImp'] = '01'
conceptos.append(concepto) conceptos.append(concepto)
impuestos = {} impuestos = {}
@ -5949,6 +6051,14 @@ class Facturas(BaseModel):
} }
retenciones.append(retencion) retenciones.append(retencion)
if base_iva_exento:
traslado = {
'Base': FORMAT.format(base_iva_exento),
'Impuesto': '002',
'TipoFactor': 'Exento',
}
traslados.append(traslado)
impuestos['traslados'] = traslados impuestos['traslados'] = traslados
impuestos['retenciones'] = retenciones impuestos['retenciones'] = retenciones
impuestos['total_locales_trasladados'] = '' impuestos['total_locales_trasladados'] = ''
@ -7238,12 +7348,14 @@ class FacturasPagos(BaseModel):
fac = Facturas.get(Facturas.id==int(i)) fac = Facturas.get(Facturas.id==int(i))
this_pay = values['this_pay'] this_pay = values['this_pay']
importe = values['importe'] importe = values['importe']
type_change = round(1 / values['type_change'], 6)
validate = round(this_pay / type_change, 2) type_change = 1.00
while validate > importe: if mov.moneda != fac.moneda:
type_change += 0.000001 type_change = round(1 / values['type_change'], 6)
validate = round(this_pay / type_change, 2) validate = round(this_pay / type_change, 2)
while validate > importe:
type_change += 0.000001
validate = round(this_pay / type_change, 2)
mov_ant, numero = cls._movimiento_anterior(cls, mov, fac) mov_ant, numero = cls._movimiento_anterior(cls, mov, fac)
nuevo = { nuevo = {
@ -7414,6 +7526,33 @@ class CfdiPagos(BaseModel):
return {'ok': result['ok'], 'msg': result['msg'], 'id': last.id} return {'ok': result['ok'], 'msg': result['msg'], 'id': last.id}
def _cancel2(self, values):
args = utils.loads(values['args'])
id = args.pop('id')
obj = CfdiPagos.get(CfdiPagos.id==id)
if not obj.uuid:
msg = 'La Factura de Pago no esta timbrada'
data = {'ok': False, 'msg': msg}
return data
pac = utils.get_pac_by_rfc(obj.xml)
auth = Configuracion.get_({'fields': 'auth_by_pac', 'pac': pac})
certificado = Certificado.get(Certificado.es_fiel==False)
result = utils.cancel_xml_sign(obj, args, auth, certificado)
if result['ok']:
obj.estatus = 'Cancelada'
obj.error = ''
obj.cancelada = True
obj.fecha_cancelacion = result['date']
else:
obj.error = result['msg']
obj.save()
return {'ok': result['ok'], 'msg': result['msg']}
def _get_folio(self, serie): def _get_folio(self, serie):
folio = int(Configuracion.get_('txt_config_cfdipay_folio') or '0') folio = int(Configuracion.get_('txt_config_cfdipay_folio') or '0')
start = (CfdiPagos start = (CfdiPagos
@ -7556,9 +7695,16 @@ class CfdiPagos(BaseModel):
tipo_factor = 'Cuota' tipo_factor = 'Cuota'
import_dr = round(tax.importe * tax_proporcion, 2) import_dr = round(tax.importe * tax_proporcion, 2)
xml_importe = FORMAT.format(import_dr)
base_dr = round(tax.base * tax_proporcion, 2) base_dr = round(tax.base * tax_proporcion, 2)
new_import_tax = round(base_dr * tax.impuesto.tasa, 2)
while new_import_tax > import_dr:
base_dr -= Decimal(0.01)
new_import_tax = round(base_dr * tax.impuesto.tasa, 2)
import_dr = new_import_tax
xml_tax_base = FORMAT.format(base_dr) xml_tax_base = FORMAT.format(base_dr)
xml_importe = FORMAT.format(import_dr)
values = { values = {
"BaseDR": xml_tax_base, "BaseDR": xml_tax_base,
@ -7567,7 +7713,8 @@ class CfdiPagos(BaseModel):
"TasaOCuotaDR": str(tax.impuesto.tasa), "TasaOCuotaDR": str(tax.impuesto.tasa),
"ImporteDR": xml_importe, "ImporteDR": xml_importe,
} }
tax_key = tax.impuesto.key # ~ tax_key = tax.impuesto.key
tax_key = f"{values['ImpuestoDR']}|{values['TasaOCuotaDR']}"
if tax.impuesto.tipo == 'T': if tax.impuesto.tipo == 'T':
traslados.append(values) traslados.append(values)
if tax_key in taxes_pay['traslados']: if tax_key in taxes_pay['traslados']:
@ -7583,6 +7730,7 @@ class CfdiPagos(BaseModel):
} }
taxes_pay['traslados'][tax_key] = values taxes_pay['traslados'][tax_key] = values
elif tax.impuesto.tipo == 'R': elif tax.impuesto.tipo == 'R':
tax_key = tax.impuesto.key
retenciones.append(values) retenciones.append(values)
if tax_key in taxes_pay['retenciones']: if tax_key in taxes_pay['retenciones']:
taxes_pay['retenciones'][tax_key] += import_dr taxes_pay['retenciones'][tax_key] += import_dr
@ -7594,9 +7742,10 @@ class CfdiPagos(BaseModel):
return impuestos return impuestos
# ~ Revisar Pagos
def _get_related_xml(self, id_mov, currency): def _get_related_xml(self, id_mov, currency):
#TAX ToDo
TAX_IVA_16 = '002|0.160000' TAX_IVA_16 = '002|0.160000'
TAX_IVA_0 = '002|0.000000'
filters = (FacturasPagos.movimiento==id_mov) filters = (FacturasPagos.movimiento==id_mov)
related = tuple(FacturasPagos.select( related = tuple(FacturasPagos.select(
@ -7604,8 +7753,7 @@ class CfdiPagos(BaseModel):
Facturas.serie.alias('Serie'), Facturas.serie.alias('Serie'),
Facturas.folio.alias('Folio'), Facturas.folio.alias('Folio'),
Facturas.moneda.alias('MonedaDR'), Facturas.moneda.alias('MonedaDR'),
FacturasPagos.tipo_cambio.alias('TipoCambioDR'), FacturasPagos.tipo_cambio.alias('EquivalenciaDR'),
# ~ Facturas.metodo_pago.alias('MetodoDePagoDR'),
FacturasPagos.numero.alias('NumParcialidad'), FacturasPagos.numero.alias('NumParcialidad'),
FacturasPagos.saldo_anterior.alias('ImpSaldoAnt'), FacturasPagos.saldo_anterior.alias('ImpSaldoAnt'),
FacturasPagos.importe.alias('ImpPagado'), FacturasPagos.importe.alias('ImpPagado'),
@ -7618,15 +7766,15 @@ class CfdiPagos(BaseModel):
for r in related: for r in related:
r['taxes'] = self._get_taxes_by_pay(self, r, taxes_pay) r['taxes'] = self._get_taxes_by_pay(self, r, taxes_pay)
# ~ print('\n\nMONEDA', currency, r['MonedaDR'])
r['IdDocumento'] = str(r['IdDocumento']) r['IdDocumento'] = str(r['IdDocumento'])
r['Folio'] = str(r['Folio']) r['Folio'] = str(r['Folio'])
r['NumParcialidad'] = str(r['NumParcialidad']) r['NumParcialidad'] = str(r['NumParcialidad'])
r['TipoCambioDR'] = FORMAT6.format(r['TipoCambioDR'])
# ~ r['MetodoDePagoDR'] = DEFAULT_CFDIPAY['WAYPAY']
# REVISAR equivalencia = r['EquivalenciaDR']
r['EquivalenciaDR'] = '1' if currency == r['MonedaDR']:
r['EquivalenciaDR'] = '1'
else:
r['EquivalenciaDR'] = FORMAT6.format(equivalencia)
r['ObjetoImpDR'] = '01' r['ObjetoImpDR'] = '01'
if r['taxes']['traslados'] or r['taxes']['retenciones']: if r['taxes']['traslados'] or r['taxes']['retenciones']:
@ -7638,38 +7786,61 @@ class CfdiPagos(BaseModel):
r['ImpSaldoInsoluto'] = '0.00' r['ImpSaldoInsoluto'] = '0.00'
else: else:
r['ImpSaldoInsoluto'] = FORMAT.format(r['ImpSaldoInsoluto']) r['ImpSaldoInsoluto'] = FORMAT.format(r['ImpSaldoInsoluto'])
if currency == r['MonedaDR']:
del r['TipoCambioDR']
if not r['Serie']: if not r['Serie']:
del r['Serie'] del r['Serie']
total_tax_iva_16_base = 0 total_tax_iva_16_base = 0
total_tax_iva_0_base = 0
total_tax_iva_16_importe = 0 total_tax_iva_16_importe = 0
total_tax_retenciones_isr_importe = 0 total_tax_retenciones_isr_importe = 0
total_tax_retenciones_iva_importe = 0
for key, importe in taxes_pay['retenciones'].items(): for key, importe in taxes_pay['retenciones'].items():
taxes_pay['retenciones'][key] = FORMAT.format(importe) taxes_pay['retenciones'][key] = FORMAT.format(importe)
total_tax_retenciones_isr_importe += importe if key == '002':
total_tax_retenciones_iva_importe += importe
else:
total_tax_retenciones_isr_importe += importe
for k, tax in taxes_pay['traslados'].items(): for k, tax in taxes_pay['traslados'].items():
tax_type = taxes_pay['traslados'][k]['ImpuestoP'] tax_type = taxes_pay['traslados'][k]['ImpuestoP']
tax_tasa = taxes_pay['traslados'][k]['TasaOCuotaP'] tax_tasa = taxes_pay['traslados'][k]['TasaOCuotaP']
tax_base = taxes_pay['traslados'][k]['BaseP'] tax_base = taxes_pay['traslados'][k]['BaseP']
importe = taxes_pay['traslados'][k]['ImporteP'] importe = taxes_pay['traslados'][k]['ImporteP']
if f'{tax_type}|{tax_tasa}' == TAX_IVA_16:
tax_base /= equivalencia
importe /= equivalencia
current_tax = f'{tax_type}|{tax_tasa}'
if current_tax == TAX_IVA_16:
# ~ new_import_tax = round(Decimal(tax_tasa) * tax_base, 2)
# ~ while new_import_tax > importe:
# ~ tax_base -= Decimal(0.01)
# ~ new_import_tax = round(Decimal(tax_tasa) * tax_base, 2)
total_tax_iva_16_base += tax_base total_tax_iva_16_base += tax_base
total_tax_iva_16_importe += importe total_tax_iva_16_importe += importe
elif current_tax == TAX_IVA_0:
total_tax_iva_0_base += tax_base
taxes_pay['traslados'][k]['BaseP'] = FORMAT.format(tax_base) taxes_pay['traslados'][k]['BaseP'] = FORMAT.format(tax_base)
taxes_pay['traslados'][k]['ImporteP'] = FORMAT.format(importe) taxes_pay['traslados'][k]['ImporteP'] = FORMAT.format(importe)
taxes_pay['totales'] = {} taxes_pay['totales'] = {}
if taxes_pay['traslados']: if taxes_pay['traslados']:
taxes_pay['totales']['TotalTrasladosBaseIVA16'] = FORMAT.format(total_tax_iva_16_base) if total_tax_iva_16_base:
taxes_pay['totales']['TotalTrasladosImpuestoIVA16'] = FORMAT.format(total_tax_iva_16_importe) taxes_pay['totales']['TotalTrasladosBaseIVA16'] = FORMAT.format(total_tax_iva_16_base)
taxes_pay['totales']['TotalTrasladosImpuestoIVA16'] = FORMAT.format(total_tax_iva_16_importe)
if total_tax_iva_0_base:
taxes_pay['totales']['TotalTrasladosBaseIVA0'] = FORMAT.format(total_tax_iva_0_base)
taxes_pay['totales']['TotalTrasladosImpuestoIVA0'] = FORMAT.format(0.0)
if taxes_pay['retenciones']: if taxes_pay['retenciones']:
taxes_pay['totales']['TotalRetencionesISR'] = FORMAT.format(total_tax_retenciones_isr_importe) if total_tax_retenciones_isr_importe:
taxes_pay['totales']['TotalRetencionesISR'] = FORMAT.format(total_tax_retenciones_isr_importe)
if total_tax_retenciones_iva_importe:
taxes_pay['totales']['TotalRetencionesIVA'] = FORMAT.format(total_tax_retenciones_iva_importe)
return related, taxes_pay return related, taxes_pay
@ -7891,6 +8062,7 @@ class CfdiPagos(BaseModel):
target = emisor.rfc + '/' + str(obj.fecha)[:7].replace('-', '/') target = emisor.rfc + '/' + str(obj.fecha)[:7].replace('-', '/')
values = cls._get_not_in_xml(cls, obj, emisor) values = cls._get_not_in_xml(cls, obj, emisor)
data = util.get_data_from_xml(obj, values) data = util.get_data_from_xml(obj, values)
data.update(utils.CfdiToDict(obj.xml).values)
data['informacion_global'] = {} data['informacion_global'] = {}
obj = SATFormaPago.get(SATFormaPago.key==data['pays']['FormaDePagoP']) obj = SATFormaPago.get(SATFormaPago.key==data['pays']['FormaDePagoP'])
@ -8109,6 +8281,9 @@ class Tickets(BaseModel):
class Meta: class Meta:
order_by = ('fecha',) order_by = ('fecha',)
indexes = (
(('serie', 'folio'), True),
)
def _get_folio(self, serie): def _get_folio(self, serie):
inicio = (Tickets inicio = (Tickets
@ -8125,7 +8300,9 @@ class Tickets(BaseModel):
return inicio return inicio
def _without_tax(self, importe, obj): def _without_tax(self, importe, obj):
# ~ todo
# ~ Por ahora se asume que solo tiene IVA trasladado 0.16 # ~ Por ahora se asume que solo tiene IVA trasladado 0.16
for tax in obj.impuestos: for tax in obj.impuestos:
tasa = 1.0 + float(tax.tasa) tasa = 1.0 + float(tax.tasa)
base = round(importe / tasa, DECIMALES) base = round(importe / tasa, DECIMALES)
@ -8189,9 +8366,6 @@ class Tickets(BaseModel):
for tax in totals_tax.values(): for tax in totals_tax.values():
if tax.tipo == 'E':
continue
ticket_tax = { ticket_tax = {
'ticket': ticket.id, 'ticket': ticket.id,
'impuesto': tax.id, 'impuesto': tax.id,
@ -8433,7 +8607,6 @@ class Tickets(BaseModel):
descuento_cfdi += details['descuento'] descuento_cfdi += details['descuento']
subtotal += details['importe'] subtotal += details['importe']
FacturasDetalle.create(**details) FacturasDetalle.create(**details)
taxes = (TicketsImpuestos taxes = (TicketsImpuestos
@ -8448,7 +8621,6 @@ class Tickets(BaseModel):
tax_id = r.impuesto.id tax_id = r.impuesto.id
tasa = r.impuesto.tasa tasa = r.impuesto.tasa
tax_importe = round(tasa * r.base, DECIMALES) tax_importe = round(tasa * r.base, DECIMALES)
if tax_id in tax_sum: if tax_id in tax_sum:
tax_sum[tax_id]['base'] += r.base tax_sum[tax_id]['base'] += r.base
tax_sum[tax_id]['importe'] += tax_importe tax_sum[tax_id]['importe'] += tax_importe
@ -8495,19 +8667,21 @@ class Tickets(BaseModel):
@classmethod @classmethod
def invoice(cls, values, user): def invoice(cls, values, user):
is_invoice_day = util.get_bool(values['is_invoice_day']) is_invoice_day = util.get_bool(values['is_invoice_day'])
periodicidad = values['periodicidad'] periodicidad = values.get('periodicidad', '')
id_client = int(values['client']) id_client = int(values['client'])
tickets = util.loads(values['tickets']) tickets = util.loads(values['tickets'])
invoice_by_ticket = Configuracion.get_bool('chk_config_invoice_by_ticket') # ~ invoice_by_ticket = Configuracion.get_bool('chk_config_invoice_by_ticket')
invoice_by_ticket = True
if is_invoice_day: if is_invoice_day:
filters = ( filters = (
Socios.rfc == RFCS['PUBLIC'] and Socios.rfc == RFCS['PUBLIC'] and
Socios.slug == 'publico_en_general') Socios.slug == 'publico_en_general'
)
try: try:
client = Socios.get(filters) client = Socios.get(filters)
except Socios.DoesNotExist: except Socios.DoesNotExist:
msg = 'No existe el cliente Público en General. Agregalo primero.' msg = 'No existe el cliente PUBLICO EN GENERAL. Agregalo primero.'
data = {'ok': False, 'msg': msg} data = {'ok': False, 'msg': msg}
return data return data
else: else:
@ -9361,6 +9535,18 @@ class CfdiNomina(BaseModel):
if msg: if msg:
return {}, msg return {}, msg
if isinstance(row['fecha_pago'], str):
msg = f"La Fecha de Pago debe ser una fecha: {row['fecha_pago']}"
return {}, msg
if isinstance(row['fecha_inicial_pago'], str):
msg = f"La Fecha Inicial de Pago debe ser una fecha: {row['fecha_inicial_pago']}"
return {}, msg
if isinstance(row['fecha_final_pago'], str):
msg = f"La Fecha Final de Pago debe ser una fecha: {row['fecha_final_pago']}"
return {}, msg
data['serie'] = self._get_serie(self) data['serie'] = self._get_serie(self)
data['folio'] = self._get_folio(self, data['serie']) data['folio'] = self._get_folio(self, data['serie'])
data['forma_pago'] = DEFAULT_SAT_NOMINA['FORMA_PAGO'] data['forma_pago'] = DEFAULT_SAT_NOMINA['FORMA_PAGO']
@ -10803,7 +10989,8 @@ def get_title_app(by=1):
2: '<font color="#610B0B">Bienvenido a {}</font>', 2: '<font color="#610B0B">Bienvenido a {}</font>',
3: '<font color="#000000">{}</font>', 3: '<font color="#000000">{}</font>',
} }
return html[by].format(TITLE_APP) # ~ return html[by].format(TITLE_APP)
return html[by].format(f'Empresa Libre v{VERSION_EMPRESA_LIBRE}')
def test_correo(values): def test_correo(values):
@ -10978,8 +11165,10 @@ def _migrate_tables(rfc=''):
'emisor', 'registro_patronal', registro_patronal)) 'emisor', 'registro_patronal', registro_patronal))
if not 'curp' in columns: if not 'curp' in columns:
curp = TextField(default='') curp = TextField(default='')
migrations.append( migrations.append(migrator.add_column('emisor', 'curp', curp))
migrator.add_column('emisor', 'curp', curp)) if not 'hours' in columns:
hours = IntegerField(default=0)
migrations.append(migrator.add_column('emisor', 'hours', hours))
columns = [c.name for c in database_proxy.get_columns('socios')] columns = [c.name for c in database_proxy.get_columns('socios')]
if not 'id_fiscal' in columns: if not 'id_fiscal' in columns:
@ -11146,6 +11335,8 @@ def _migrate_tables(rfc=''):
regimen_fiscal = TextField(default='') regimen_fiscal = TextField(default='')
migrations.append(migrator.add_column(table, field, regimen_fiscal)) migrations.append(migrator.add_column(table, field, regimen_fiscal))
# migrations.append(migrator.add_index('tickets', ('serie', 'folio'), True))
if migrations: if migrations:
with database_proxy.atomic() as txn: with database_proxy.atomic() as txn:
migrate(*migrations) migrate(*migrations)
@ -11172,6 +11363,10 @@ def _migrate_tables(rfc=''):
else: else:
log.info('Valores actualizados...') log.info('Valores actualizados...')
q = Configuracion.delete().where(Configuracion.clave=='chk_config_tax_decimals')
q.execute()
log.info('Config Tax Update...')
return return

View File

@ -28,12 +28,9 @@ from conf import DEBUG, MV, LOG_PATH
try: try:
from conf import DEFAULT_PASSWORD from conf import DEFAULT_PASSWORD
except ImportError: except ImportError:
DEFAULT_PASSWORD = 'salgueiro3.3' DEFAULT_PASSWORD = 'salgueiro4.0'
try: TITLE_APP = 'Empresa Libre'
from conf import TITLE_APP
except ImportError:
TITLE_APP = 'Empresa Libre'
try: try:
from conf import NO_HTTPS from conf import NO_HTTPS
@ -42,7 +39,7 @@ except ImportError:
DEBUG = DEBUG DEBUG = DEBUG
VERSION = '2.0.0' VERSION = '2.3.2'
EMAIL_SUPPORT = ('soporte@empresalibre.mx',) EMAIL_SUPPORT = ('soporte@empresalibre.mx',)
TITLE_APP = '{} v{}'.format(TITLE_APP, VERSION) TITLE_APP = '{} v{}'.format(TITLE_APP, VERSION)
@ -260,6 +257,8 @@ VALUES_PDF = {
}, },
} }
RESICO = '626'
RFCS = { RFCS = {
'PUBLIC': 'XAXX010101000', 'PUBLIC': 'XAXX010101000',
'FOREIGN': 'XEXX010101000', 'FOREIGN': 'XEXX010101000',

View File

@ -682,7 +682,7 @@
{"key": "D08", "name": "Gastos de transportación escolar obligatoria.", "activo": false}, {"key": "D08", "name": "Gastos de transportación escolar obligatoria.", "activo": false},
{"key": "D09", "name": "Depósitos en cuentas para el ahorro, primas que tengan como base planes de pensiones.", "activo": false}, {"key": "D09", "name": "Depósitos en cuentas para el ahorro, primas que tengan como base planes de pensiones.", "activo": false},
{"key": "D10", "name": "Pagos por servicios educativos (colegiaturas)", "activo": true}, {"key": "D10", "name": "Pagos por servicios educativos (colegiaturas)", "activo": true},
{"key": "P01", "name": "Por definir", "moral": true, "activo": true}, {"key": "P01", "name": "Por definir", "moral": true, "activo": false},
{"key": "S01", "name": "Sin efectos fiscales.", "moral": true, "activo": true}, {"key": "S01", "name": "Sin efectos fiscales.", "moral": true, "activo": true},
{"key": "CP01", "name": "Pagos", "moral": true, "activo": true}, {"key": "CP01", "name": "Pagos", "moral": true, "activo": true},
{"key": "CN01", "name": "Nómina", "moral": true, "activo": true} {"key": "CN01", "name": "Nómina", "moral": true, "activo": true}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 754 B

After

Width:  |  Height:  |  Size: 380 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

View File

@ -134,7 +134,9 @@ var controllers = {
$$('chk_config_user_show_doc').attachEvent('onItemClick', chk_config_item_click) $$('chk_config_user_show_doc').attachEvent('onItemClick', chk_config_item_click)
$$('chk_config_invoice_by_ticket').attachEvent('onItemClick', chk_config_item_click) $$('chk_config_invoice_by_ticket').attachEvent('onItemClick', chk_config_item_click)
$$('chk_config_show_total_cant').attachEvent('onItemClick', chk_config_item_click) $$('chk_config_show_total_cant').attachEvent('onItemClick', chk_config_item_click)
$$('chk_config_show_filter_by_day').attachEvent('onItemClick', chk_config_item_click)
$$('chk_cancel_invoices_by_admin').attachEvent('onItemClick', chk_config_item_click) $$('chk_cancel_invoices_by_admin').attachEvent('onItemClick', chk_config_item_click)
$$('chk_config_change_date_invoice').attachEvent('onItemClick', chk_config_item_click)
$$('chk_config_anticipo').attachEvent('onItemClick', chk_config_item_click) $$('chk_config_anticipo').attachEvent('onItemClick', chk_config_item_click)

View File

@ -81,6 +81,7 @@ var bancos_controllers = {
$$('grid_bank_invoice_pay').attachEvent('onItemClick', grid_bank_invoice_pay_click) $$('grid_bank_invoice_pay').attachEvent('onItemClick', grid_bank_invoice_pay_click)
$$('grid_cuentabanco').attachEvent('onItemDblClick', grid_cuentabanco_double_click) $$('grid_cuentabanco').attachEvent('onItemDblClick', grid_cuentabanco_double_click)
$$('cmd_invoice_pay_sat').attachEvent('onItemClick', cmd_invoice_pay_sat_click) $$('cmd_invoice_pay_sat').attachEvent('onItemClick', cmd_invoice_pay_sat_click)
$$('cmd_invoice_pay_cancel').attachEvent('onItemClick', cmd_invoice_pay_cancel_click)
init_config_bank() init_config_bank()
} }
@ -578,13 +579,13 @@ function validate_deposito(values){
return false return false
} }
if(grid.count() && current_currency!=CURRENCY_MN){ //~ if(grid.count() && current_currency!=CURRENCY_MN){
if(type_change <= 1.0){ //~ if(type_change <= 1.0){
msg = 'El Tipo de Cambio debe ser mayor a 1.00' //~ msg = 'El Tipo de Cambio debe ser mayor a 1.00'
msg_error(msg) //~ msg_error(msg)
return false //~ return false
} //~ }
} //~ }
var today = new Date() var today = new Date()
if(values.deposito_fecha > today){ if(values.deposito_fecha > today){
@ -1426,3 +1427,83 @@ function cmd_invoice_pay_sat_click(){
}) })
} }
function cmd_invoice_pay_cancel_click(){
var g = $$('grid_bank_invoice_pay')
if(g.count() == 0){
return
}
var row = g.getSelectedItem()
if (row == undefined){
msg_error('Selecciona una factura de pago')
return
}
if (row instanceof Array){
msg_error('Selecciona solo una factura de pago')
return
}
if(!row.uuid){
msg_error('La factura de pago no esta timbrada')
return
}
win_invoice_cancel_pay2.init()
$$('win_invoice_cancel_pay2').show()
}
function cmd_invoice_cancel_pay2_click(){
var reason = $$('lst_reasons_cancel2').getValue()
var uuid = $$('txt_cancel_uuid2').getValue()
if(!reason){
msg = 'Selecciona un motivo para esta cancelación'
msg_error(msg)
return
}
if(reason=='01' & !uuid){
msg = 'Debes de capturar el UUID que reemplaza a este CFDI'
msg_error(msg)
return
}
send_invoice_cancel_pay2(reason, uuid)
$$('win_invoice_cancel_pay2').close()
}
function cmd_win_cancel_pay_close2_click(){
$$('win_invoice_cancel_pay2').close()
}
function send_invoice_cancel_pay2(reason='', uuid=''){
var grid = $$('grid_bank_invoice_pay')
var row = grid.getSelectedItem()
var data = {
'opt': 'cancel2',
args: {
id: row.id,
reason: reason,
uuid: uuid,
}
}
webix.ajax().post('cfdipay', data, function(text, data){
var values = data.json()
if(values.ok){
msg_ok(values.msg)
grid.updateItem(row.id, {'estatus': 'Cancelada'})
}else{
msg_error('No fue posible cancelar')
webix.alert({
title: 'Error al Cancelar',
text: values.msg,
type: 'alert-error'
})
}
})
}

View File

@ -22,7 +22,8 @@ var tipo_relacion = ''
var anticipo = false var anticipo = false
var donativo = false var donativo = false
var cfg_invoice = new Object() var cfg_invoice = new Object()
var values_comercioe = null //~ var values_comercioe = null
var values_global = ''
function init_config_invoices(){ function init_config_invoices(){
@ -33,6 +34,7 @@ function init_config_invoices(){
g.showColumn('total') g.showColumn('total')
g.showColumn('currency') g.showColumn('currency')
} }
show('cmd_show_global_information', false)
} }
@ -67,6 +69,11 @@ var invoices_controllers = {
$$('filter_year').attachEvent('onChange', filter_year_change) $$('filter_year').attachEvent('onChange', filter_year_change)
$$('filter_month').attachEvent('onChange', filter_month_change) $$('filter_month').attachEvent('onChange', filter_month_change)
var show_filter_by_day = get_config('show_filter_by_day')
show('filter_day', show_filter_by_day)
if(show_filter_by_day){
$$('filter_day').attachEvent('onChange', filter_day_change)
}
$$('filter_dates').attachEvent('onChange', filter_dates_change) $$('filter_dates').attachEvent('onChange', filter_dates_change)
$$('cmd_prefactura').attachEvent('onItemClick', cmd_prefactura_click) $$('cmd_prefactura').attachEvent('onItemClick', cmd_prefactura_click)
$$('cmd_preinvoice_generate_delete').attachEvent('onItemClick', cmd_preinvoice_generate_delete_click) $$('cmd_preinvoice_generate_delete').attachEvent('onItemClick', cmd_preinvoice_generate_delete_click)
@ -90,12 +97,27 @@ var invoices_controllers = {
tv_invoice = $$('tv_invoice').getTabbar() tv_invoice = $$('tv_invoice').getTabbar()
tv_invoice.attachEvent('onChange', tv_invoice_change) tv_invoice.attachEvent('onChange', tv_invoice_change)
$$('grid_carta_mercancias').attachEvent('onItemClick', grid_carta_mercancias_click) //~ CartaPorte
$$('grid_carta_ubicaciones').attachEvent('onBeforeEditStop', grid_carta_ubicaciones_before_edit_stop) $$('grid_ccp_ubicaciones').attachEvent('onBeforeEditStop', grid_ccp_ubicaciones_before_edit_stop)
$$('cmd_carta_add_product').attachEvent('onItemClick', cmd_carta_add_product_click) $$('grid_ccp_ubicaciones').attachEvent('onItemClick', grid_ccp_ubicaciones_click)
$$('cmd_carta_copy_from_invoice').attachEvent('onItemClick', cmd_carta_copy_from_invoice_click) $$('grid_ccp_mercancias').attachEvent('onItemClick', grid_ccp_mercancias_click)
$$('grid_ccp_remolques').attachEvent('onItemClick', grid_ccp_remolques_click)
$$('cmd_ccp_agregar_ubicacion').attachEvent('onItemClick', cmd_ccp_agregar_ubicacion_click)
$$('cmd_ccp_add_product').attachEvent('onItemClick', cmd_ccp_add_product_click)
$$('cmd_ccp_agregar_remolque').attachEvent('onItemClick', cmd_ccp_agregar_remolque_click)
//~ $$('cmd_carta_copy_from_invoice').attachEvent('onItemClick', cmd_carta_copy_from_invoice_click)
$$('cmd_carta_import_json').attachEvent('onItemClick', cmd_carta_import_json_click) $$('cmd_carta_import_json').attachEvent('onItemClick', cmd_carta_import_json_click)
//~ ComercioExterior
$$('cmd_import_json_comercioe').attachEvent('onItemClick', cmd_import_json_comercioe_click) $$('cmd_import_json_comercioe').attachEvent('onItemClick', cmd_import_json_comercioe_click)
$$('cmd_ce_import_ods').attachEvent('onItemClick', cmd_ce_import_ods_click)
$$('cmd_ce_tipo_cambio').attachEvent('onItemClick', cmd_ce_tipo_cambio_click)
$$('cmd_ce_add_propietario').attachEvent('onItemClick', cmd_ce_add_propietario_click)
$$('cmd_ce_add_mercancia').attachEvent('onItemClick', cmd_ce_add_mercancia_click)
$$('grid_ce_propietarios').attachEvent('onItemClick', grid_ce_propietarios_click)
$$('grid_ce_mercancias').attachEvent('onItemClick', grid_ce_mercancias_click)
$$('cmd_show_global_information').attachEvent('onItemClick', cmd_show_global_information_click)
webix.extend($$('grid_invoices'), webix.ProgressBar) webix.extend($$('grid_invoices'), webix.ProgressBar)
@ -207,7 +229,6 @@ function default_config(){
webix.ajax().sync().get('/values/configtimbrar', function(text, data){ webix.ajax().sync().get('/values/configtimbrar', function(text, data){
var values = data.json() var values = data.json()
//~ showvar(values)
show('chk_cfdi_anticipo', values.cfdi_anticipo) show('chk_cfdi_anticipo', values.cfdi_anticipo)
show('chk_cfdi_donativo', values.cfdi_donativo) show('chk_cfdi_donativo', values.cfdi_donativo)
show('lst_metodo_pago', !values.cfdi_metodo_pago) show('lst_metodo_pago', !values.cfdi_metodo_pago)
@ -232,6 +253,7 @@ function default_config(){
$$('tv_invoice').getTabbar().hideOption('Comercio Exterior') $$('tv_invoice').getTabbar().hideOption('Comercio Exterior')
}else{ }else{
$$('tv_invoice').getTabbar().showOption('Comercio Exterior') $$('tv_invoice').getTabbar().showOption('Comercio Exterior')
_set_default_comercio_exterior()
} }
cfg_invoice['leyendasfiscales'] = values.cfdi_leyendasfiscales cfg_invoice['leyendasfiscales'] = values.cfdi_leyendasfiscales
cfg_invoice['edu'] = values.cfdi_edu cfg_invoice['edu'] = values.cfdi_edu
@ -254,7 +276,10 @@ function default_config(){
show('fs_divisas', values.cfdi_divisas) show('fs_divisas', values.cfdi_divisas)
show('txt_folio_custom', values.cfdi_folio_custom) show('txt_folio_custom', values.cfdi_folio_custom)
show('txt_total_cant', values.cfdi_show_total_cant) show('txt_total_cant', values.cfdi_show_total_cant)
show('date_invoice', values.cfdi_change_date_invoice)
}) })
values_global = ''
} }
@ -296,6 +321,9 @@ function cmd_new_invoice_click(){
lst.setValue('') lst.setValue('')
lst.getList().clearAll() lst.getList().clearAll()
$$('date_invoice').setValue(new Date())
show('cmd_show_global_information', false)
form.focus('search_client_name') form.focus('search_client_name')
} }
@ -360,14 +388,19 @@ function cmd_delete_invoice_click(id, e, node){
function validate_invoice(values){ function validate_invoice(values){
var usar_cartaporte = $$('chk_cfdi_usar_cartaporte').getValue() var date_invoice = $$('date_invoice').getValue()
if(usar_cartaporte){ if(date_invoice == null){
value = $$('lst_carta_UnidadPeso').getValue() msg = 'La fecha es requerida'
if(!value){ msg_error(msg)
msg = 'Es necesario seleccionar una Unidad de Peso' $$('date_invoice').setFocus()
msg_error(msg) return false
return false }
}
var now = new Date()
var difference = (now.getTime() - date_invoice.getTime()) / (1000 * 3600 * 24)
if(difference > 3){
msg_error('Fecha inválida')
return false
} }
var tipo_comprobante = $$('lst_tipo_comprobante').getValue() var tipo_comprobante = $$('lst_tipo_comprobante').getValue()
@ -410,6 +443,14 @@ function validate_invoice(values){
return false return false
} }
var metodo_pago = $$('lst_metodo_pago').getValue()
if(metodo_pago=='PPD' && forma_pago!='99'){
webix.UIManager.setFocus('lst_forma_pago')
msg = 'La Forma de pago debe ser: [99] Por definir'
msg_error(msg)
return false
}
var tipo_cambio = $$('txt_tipo_cambio').getValue() var tipo_cambio = $$('txt_tipo_cambio').getValue()
if(tipo_cambio.trim() == ""){ if(tipo_cambio.trim() == ""){
webix.UIManager.setFocus('txt_tipo_cambio') webix.UIManager.setFocus('txt_tipo_cambio')
@ -442,8 +483,8 @@ function validate_invoice(values){
anticipo = $$('chk_cfdi_anticipo').getValue() anticipo = $$('chk_cfdi_anticipo').getValue()
if(anticipo){ if(anticipo){
var mp = $$('lst_metodo_pago').getValue() //~ var mp = $$('lst_metodo_pago').getValue()
if(mp != 'PUE'){ if(metodo_pago != 'PUE'){
msg = 'En anticipos, el método de pago debe ser: Pago en una sola exhibición' msg = 'En anticipos, el método de pago debe ser: Pago en una sola exhibición'
msg_error(msg) msg_error(msg)
return false return false
@ -509,8 +550,27 @@ function validate_invoice(values){
} }
var is_global = $$('cmd_show_global_information').isVisible()
if(is_global){
if(values_global=='' && tipo_comprobante=='I'){
msg = 'Captura los datos de la Factura Global'
msg_error(msg)
return false
}
}
var rows = grid.data.getRange() var rows = grid.data.getRange()
for (i = 0; i < rows.length; i++) { for (i = 0; i < rows.length; i++) {
if(is_global){
var key_sat = rows[i]['clave_sat']
if(key_sat!=KEY_SAT_01){
var msg = 'Clave SAT inválida para Factura Global en la línea: ' + (i + 1)
msg_error(msg)
return false
}
}
var importe = rows[i]['importe'] var importe = rows[i]['importe']
if(!importe){ if(!importe){
var msg = 'No es posible facturar importes en cero, revisa la línea: ' + (i + 1) var msg = 'No es posible facturar importes en cero, revisa la línea: ' + (i + 1)
@ -519,10 +579,106 @@ function validate_invoice(values){
} }
} }
//~ validate comercio exterior
var usar_comercioe = $$('chk_cfdi_usar_comercioe').getValue()
if(usar_comercioe){
var values = _get_values_comercio_exterior()
}
//~ validate carta porte
var usar_cartaporte = $$('chk_cfdi_usar_cartaporte').getValue()
if(usar_cartaporte){
var result = _get_values_carta_porte()
if(!result.ok){
return false
}
}
return true return true
} }
function _get_values_carta_porte(){
var ok = false
var values = new Object()
unidad_peso = $$('lst_carta_UnidadPeso').getValue()
if(!unidad_peso){
msg = 'Es necesario seleccionar una Unidad de Peso'
msg_error(msg)
return {ok: ok, values: values}
}
var ubicaciones = $$('grid_ccp_ubicaciones').data.getRange()
if (ubicaciones.length < 2){
msg = 'Se requieren al menos dos ubicaciones'
msg_error(msg)
return {ok: ok, values: values}
}
ubicaciones.forEach(function(row, index){
delete row['id']
delete row['delete']
//~ delete row['IDUbicacion']
})
var mercancias = $$('grid_ccp_mercancias').data.getRange()
if (mercancias.length < 1){
msg = 'Se requieren al menos una mercancía'
msg_error(msg)
return {ok: ok, values: values}
}
mercancias.forEach(function(row, index){
delete row['id']
delete row['delete']
})
var autotransporte = $$('grid_ccp_autotransporte').data.getRange()[0]
delete autotransporte['id']
if(autotransporte['PermSCT'] === undefined){
msg = 'El campo PermSCT es requerido'
msg_error(msg)
return {ok: ok, values: values}
}
var remolques = $$('grid_ccp_remolques').data.getRange()
remolques.forEach(function(row, index){
delete row['id']
delete row['delete']
})
var seguros = $$('grid_ccp_seguros').data.getRange()[0]
delete seguros['id']
if(seguros['AseguraRespCivil'] === undefined){
msg = 'El campo AseguraRespCivil es requerido'
msg_error(msg)
return {ok: ok, values: values}
}
if(seguros['PolizaRespCivil'] === undefined){
msg = 'El campo PolizaRespCivil es requerido'
msg_error(msg)
return {ok: ok, values: values}
}
var tipos_figuras = $$('grid_ccp_tipos_figuras').data.getRange()
tipos_figuras.forEach(function(row, index){
delete row['id']
})
values['TranspInternac'] = $$('lst_cp_TranspInternac').getValue()
values['unidad_peso'] = unidad_peso
values['ubicaciones'] = ubicaciones
values['mercancias'] = mercancias
values['autotransporte'] = autotransporte
values['remolques'] = remolques
values['seguros'] = seguros
values['tiposfigura'] = tipos_figuras
ok = true
return {ok: ok, values: values}
}
function update_grid_invoices(values){ function update_grid_invoices(values){
if(values.new){ if(values.new){
gi.add(values.row) gi.add(values.row)
@ -687,6 +843,7 @@ function guardar_y_timbrar(values){
data['id'] = values.id data['id'] = values.id
data['cliente'] = values.id_partner data['cliente'] = values.id_partner
data['productos'] = rows data['productos'] = rows
data['date'] = $$('date_invoice').getValue()
data['serie'] = $$('lst_serie').getText() data['serie'] = $$('lst_serie').getText()
data['forma_pago'] = $$('lst_forma_pago').getValue() data['forma_pago'] = $$('lst_forma_pago').getValue()
data['condiciones_pago'] = $$('txt_condicion_pago').getValue().trim() data['condiciones_pago'] = $$('txt_condicion_pago').getValue().trim()
@ -705,6 +862,8 @@ function guardar_y_timbrar(values){
data['folio_custom'] = $$('txt_folio_custom').getValue() data['folio_custom'] = $$('txt_folio_custom').getValue()
data['divisas'] = $$('opt_divisas').getValue() data['divisas'] = $$('opt_divisas').getValue()
data['leyendas_fiscales'] = $$('grid_leyendas_fiscales').getSelectedId(true, true) data['leyendas_fiscales'] = $$('grid_leyendas_fiscales').getSelectedId(true, true)
data['periodicidad'] = values_global
$$('grid_leyendas_fiscales').unselectAll() $$('grid_leyendas_fiscales').unselectAll()
var usar_ine = $$('chk_cfdi_usar_ine').getValue() var usar_ine = $$('chk_cfdi_usar_ine').getValue()
@ -724,80 +883,22 @@ function guardar_y_timbrar(values){
var usar_cartaporte = $$('chk_cfdi_usar_cartaporte').getValue() var usar_cartaporte = $$('chk_cfdi_usar_cartaporte').getValue()
if(usar_cartaporte){ if(usar_cartaporte){
//~ var total_distance = 0.00 var result = _get_values_carta_porte()
//~ var total_weight = 0.00 data['cartaporte'] = result.values
var cartaporte = { $$('chk_cfdi_usar_cartaporte').setValue(false)
TranspInternac: $$('lst_carta_TranspInternac').getValue(),
//~ TotalDistRec: total_distance,
}
var ubicaciones = $$('grid_carta_ubicaciones').data.getRange()
ubicaciones.forEach(function(row, index){
delete row['id']
delete row['delete']
//~ if(row['DistanciaRecorrida']){
//~ total_distance += parseFloat(row['DistanciaRecorrida'])
//~ }
})
//~ cartaporte['TotalDistRec'] = total_distance
cartaporte['ubicaciones'] = ubicaciones
var row = $$('grid_carta_autotransporte').data.getRange()[0]
var autotransporte = {
PermSCT: row['PermSCT'],
NumPermisoSCT: row['NumPermisoSCT'],
identificacion: {
ConfigVehicular: row['ConfigVehicular'],
PlacaVM: row['PlacaVM'],
AnioModeloVM: row['AnioModeloVM'],
},
seguros: {
AseguraRespCivil: row['AseguraRespCivil'],
PolizaRespCivil: row['PolizaRespCivil'],
},
remolque: {
SubTipoRem: row['SubTipoRem'],
Placa: row['Placa'],
}
}
var mercancias = $$('grid_carta_mercancias').data.getRange()
mercancias.forEach(function(row, index){
delete row['id']
delete row['delete']
row['Cantidad'] = String(row['Cantidad'])
//~ row['ValorMercancia'] = String(row['ValorMercancia'])
//~ if(row['PesoEnKg']){
//~ total_weight += parseFloat(row['PesoEnKg'])
//~ }
})
var mercancias = {
'PesoBrutoTotal': 0.00,
'UnidadPeso': $$('lst_carta_UnidadPeso').getValue(),
'NumTotalMercancias': String(mercancias.length),
mercancias: mercancias,
autotransporte: autotransporte,
}
cartaporte['mercancias'] = mercancias
var tiposfigura = $$('grid_carta_tipos_figuras').data.getRange()
tiposfigura.forEach(function(row, index){
delete row['id']
})
cartaporte['tiposfigura'] = tiposfigura
data['cartaporte'] = cartaporte
} }
var usar_comercioe = $$('chk_cfdi_usar_comercioe').getValue() var usar_comercioe = $$('chk_cfdi_usar_comercioe').getValue()
if(usar_comercioe){ if(usar_comercioe){
data['comercioe'] = values_comercioe data['comercioe'] = _get_values_comercio_exterior()
} }
if(!save_invoice(data)){ if(!save_invoice(data)){
return return
} }
values_comercioe = null //~ values_comercioe = null
values_global = ''
$$('chk_cfdi_usar_comercioe').setValue(false) $$('chk_cfdi_usar_comercioe').setValue(false)
table_relaciones.clear() table_relaciones.clear()
@ -806,6 +907,7 @@ function guardar_y_timbrar(values){
$$('chk_cfdi_anticipo').setValue(0) $$('chk_cfdi_anticipo').setValue(0)
$$('chk_cfdi_donativo').setValue(0) $$('chk_cfdi_donativo').setValue(0)
$$('chk_cfdi_usar_ine').setValue(0) $$('chk_cfdi_usar_ine').setValue(0)
show('cmd_show_global_information', false)
$$('form_invoice').setValues({id_partner: 0, lbl_partner: 'Ninguno', notas:''}) $$('form_invoice').setValues({id_partner: 0, lbl_partner: 'Ninguno', notas:''})
$$('multi_invoices').setValue('invoices_home') $$('multi_invoices').setValue('invoices_home')
@ -822,6 +924,7 @@ function cmd_timbrar_click(id, e, node){
} }
var values = form.getValues() var values = form.getValues()
if(!validate_invoice(values)){ if(!validate_invoice(values)){
return return
} }
@ -846,16 +949,16 @@ function cmd_timbrar_click(id, e, node){
usar_ine = $$('chk_cfdi_usar_ine').getValue() usar_ine = $$('chk_cfdi_usar_ine').getValue()
if(usar_ine){ if(usar_ine){
msg += 'Estas usando el complemento INE<BR><BR>' msg += 'Estas usando el complemento: INE<BR><BR>'
} }
if($$('chk_cfdi_usar_comercioe').getValue()){ if($$('chk_cfdi_usar_comercioe').getValue()){
msg += 'Estas usando el complemento Comercio Exterior<BR><BR>' msg += 'Estas usando el complemento:<BR>Comercio Exterior<BR><BR>'
if(values_comercioe === null){ }
msg = 'El complemento de Comercio Exterior esta vacío'
msg_error(msg) usar_carta_porte = $$('chk_cfdi_usar_cartaporte').getValue()
return if(usar_carta_porte){
} msg += 'Estas usando el complemento:<BR>Carta Porte<BR><BR>'
} }
if(tipo_comprobante == 'T'){ if(tipo_comprobante == 'T'){
@ -873,6 +976,10 @@ function cmd_timbrar_click(id, e, node){
} }
} }
if($$('cmd_show_global_information').isVisible()){
msg += 'Es una Factura Global<BR><BR>'
}
msg += '¿Estás seguro de timbrar esta factura?<BR><BR>' msg += '¿Estás seguro de timbrar esta factura?<BR><BR>'
webix.confirm({ webix.confirm({
@ -945,6 +1052,12 @@ function set_client(row){
} }
lst.setValue(lst.getPopup().getList().getFirstId()) lst.setValue(lst.getPopup().getList().getFirstId())
if(row.nombre.toUpperCase() == PUBLICO && row.rfc == RFC_PUBLICO){
show('cmd_show_global_information', true)
}else{
show('cmd_show_global_information', false)
}
form.focus('search_product_id') form.focus('search_product_id')
} }
@ -1178,8 +1291,8 @@ function grid_details_before_edit_start(id){
} }
function grid_carta_ubicaciones_before_edit_stop(state, editor){ function grid_ccp_ubicaciones_before_edit_stop(state, editor){
var g = $$('grid_carta_ubicaciones') var g = $$('grid_ccp_ubicaciones')
var row = g.getItem(editor.row) var row = g.getItem(editor.row)
if(editor.column != 'CodigoPostal'){ if(editor.column != 'CodigoPostal'){
@ -1623,6 +1736,10 @@ function get_filters_invoices(){
filters['year'] = $$('filter_year').getValue() filters['year'] = $$('filter_year').getValue()
filters['month'] = $$('filter_month').getValue() filters['month'] = $$('filter_month').getValue()
filters['day'] = '-1'
if(get_config('show_filter_by_day')){
filters['day'] = $$('filter_day').getValue()
}
filters['client'] = $$('grid_invoices').getFilter('cliente').value filters['client'] = $$('grid_invoices').getFilter('cliente').value
return filters return filters
} }
@ -1660,6 +1777,11 @@ function filter_month_change(nv, ov){
} }
function filter_day_change(nv, ov){
get_invoices()
}
function filter_dates_change(range){ function filter_dates_change(range){
if(range.start != null && range.end != null){ if(range.start != null && range.end != null){
get_invoices() get_invoices()
@ -2716,12 +2838,26 @@ function cmd_invoice_ask_cancel_click(){
} }
function cmd_carta_add_product_click(){ function cmd_ccp_agregar_ubicacion_click(){
var g = $$('grid_carta_mercancias') var g = $$('grid_ccp_ubicaciones')
g.add({delete: '-', Pais: 'MEX'})
}
function cmd_ccp_add_product_click(){
var g = $$('grid_ccp_mercancias')
g.add({delete: '-'}) g.add({delete: '-'})
} }
function cmd_ccp_agregar_remolque_click(){
var g = $$('grid_ccp_remolques')
if(g.count() < 2){
g.add({delete: '-'})
}
}
function _copy_from_invoice(){ function _copy_from_invoice(){
var g1 = $$('grid_details') var g1 = $$('grid_details')
var g2 = $$('grid_carta_mercancias') var g2 = $$('grid_carta_mercancias')
@ -2765,7 +2901,23 @@ function cmd_carta_copy_from_invoice_click(){
} }
function grid_carta_mercancias_click(id, e, node){ function grid_ccp_ubicaciones_click(id, e, node){
if(id.column != 'delete'){
return
}
this.remove(id.row)
}
function grid_ccp_mercancias_click(id, e, node){
if(id.column != 'delete'){
return
}
this.remove(id.row)
}
function grid_ccp_remolques_click(id, e, node){
if(id.column != 'delete'){ if(id.column != 'delete'){
return return
} }
@ -2786,26 +2938,17 @@ function _set_carta_porte_from_json(data){
return return
} }
var mercancias = values['mercancias'] $$('lst_cp_TranspInternac').setValue(values['TranspInternac'])
$$('lst_carta_UnidadPeso').setValue(values['UnidadPeso'])
var ubicaciones = values['ubicaciones'] var ubicaciones = values['ubicaciones']
var mercancias = values['mercancias']
var autotransporte = values['autotransporte'] var autotransporte = values['autotransporte']
var operador = values['operador'] var remolques = values['remolques']
var seguros = values['seguros']
var figura = values['figura']
$$('lst_carta_UnidadPeso').setValue(values['unidad_de_peso']) var grid = $$('grid_ccp_ubicaciones')
var grid = $$('grid_carta_mercancias')
grid.clearAll()
mercancias.forEach(function(row, index){
var data = new Object()
data['delete'] = '-'
data['BienesTransp'] = row.clave_sat
data['Descripcion'] = row.descripcion
data['Cantidad'] = row.cantidad
data['ClaveUnidad'] = row.clave_unidad
data['PesoEnKg'] = row.peso_en_kg
grid.add(data)
})
var grid = $$('grid_carta_ubicaciones')
grid.clearAll() grid.clearAll()
ubicaciones.forEach(function(row, index){ ubicaciones.forEach(function(row, index){
var data = new Object() var data = new Object()
@ -2824,32 +2967,55 @@ function _set_carta_porte_from_json(data){
grid.add(data) grid.add(data)
}) })
var grid = $$('grid_carta_autotransporte') var grid = $$('grid_ccp_mercancias')
grid.clearAll()
mercancias.forEach(function(row, index){
var data = new Object()
data['delete'] = '-'
data['BienesTransp'] = row.clave_sat
data['Descripcion'] = row.descripcion
data['Cantidad'] = row.cantidad
data['ClaveUnidad'] = row.clave_unidad
data['PesoEnKg'] = row.peso_en_kg
grid.add(data)
})
var grid = $$('grid_ccp_autotransporte')
grid.clearAll() grid.clearAll()
var data = new Object() var data = new Object()
data['PermSCT'] = autotransporte.tipo_permiso data['PermSCT'] = autotransporte.PermSCT
data['NumPermisoSCT'] = autotransporte.numero data['NumPermisoSCT'] = autotransporte.NumPermisoSCT
data['ConfigVehicular'] = autotransporte.clave data['ConfigVehicular'] = autotransporte.ConfigVehicular
data['PlacaVM'] = autotransporte.placa data['PesoBrutoVehicular'] = autotransporte.PesoBrutoVehicular
data['AnioModeloVM'] = autotransporte.modelo data['PlacaVM'] = autotransporte.PlacaVM
if('remolque' in autotransporte){ data['AnioModeloVM'] = autotransporte.AnioModeloVM
data['SubTipoRem'] = autotransporte.remolque
data['Placa'] = autotransporte.placa_remolque
}
data['AseguraRespCivil'] = autotransporte.aseguradora
data['PolizaRespCivil'] = autotransporte.poliza
grid.add(data) grid.add(data)
var grid = $$('grid_carta_tipos_figuras') var grid = $$('grid_ccp_remolques')
//~ if(remolques.length > 0){
grid.clearAll()
remolques.forEach(function(row, index){
var data = new Object()
data['SubTipoRem'] = row.SubTipoRem
data['Placa'] = row.Placa
grid.add(data)
})
//~ }
var grid = $$('grid_ccp_seguros')
grid.clearAll() grid.clearAll()
var data = new Object() var data = new Object()
data['TipoFigura'] = '01' data['AseguraRespCivil'] = seguros.AseguraRespCivil
if('tipo' in operador){ data['PolizaRespCivil'] = seguros.PolizaRespCivil
data['TipoFigura'] = operador.tipo grid.add(data)
}
data['RFCFigura'] = operador.rfc var grid = $$('grid_ccp_tipos_figuras')
data['NombreFigura'] = operador.nombre grid.clearAll()
data['NumLicencia'] = operador.licencia var data = new Object()
data['TipoFigura'] = figura.TipoFigura
data['RFCFigura'] = figura.RFCFigura
data['NumLicencia'] = figura.NumLicencia
data['NombreFigura'] = figura.NombreFigura
grid.add(data) grid.add(data)
$$('chk_cfdi_usar_cartaporte').setValue(1) $$('chk_cfdi_usar_cartaporte').setValue(1)
@ -2872,9 +3038,54 @@ function up_invoice_json_on_after_file_add(obj){
} }
function _set_from_json_comercioe(data){ function _set_default_comercio_exterior(){
const controls = {
lst_ce_exportacion: '02',
lst_ce_motivo_traslado: '',
lst_ce_clave_pedimento: 'A1',
lst_ce_certificado_origen: '0',
txt_ce_numero_certificado: '',
txt_ce_numero_exportador: '',
lst_ce_incoterm: 'CFR',
txt_ce_observaciones: '',
txt_ce_tipo_cambio_usd: '',
txt_ce_total_usd: '',
};
Object.keys(controls).forEach(key => {
$$(key).setValue(controls[key])
});
var grid = $$('grid_ce_emisor')
grid.clearAll()
grid.add({id: 0})
var grid = $$('grid_ce_receptor')
grid.clearAll()
grid.add({id: 0})
var grid = $$('grid_ce_destinatario')
grid.clearAll()
grid.add({id: 0})
var grid = $$('grid_ce_propietarios')
grid.clearAll()
var grid = $$('grid_ce_mercancias')
grid.clearAll()
}
function _set_from_json_comercioe(data, json){
_set_default_comercio_exterior()
try{ try{
values_comercioe = JSON.parse(data) if(json){
values = JSON.parse(data)
}else{
values = data
}
}catch(e){ }catch(e){
msg_error('Revisa el archivo JSON') msg_error('Revisa el archivo JSON')
webix.alert({ webix.alert({
@ -2884,6 +3095,66 @@ function _set_from_json_comercioe(data){
}) })
return return
} }
const controls = {
Exportacion: 'lst_ce_exportacion',
MotivoTraslado: 'lst_ce_motivo_traslado',
ClaveDePedimento: 'lst_ce_clave_pedimento',
CertificadoOrigen: 'lst_ce_certificado_origen',
NumCertificadoOrigen: 'txt_ce_numero_certificado',
NumeroExportadorConfiable: 'txt_ce_numero_exportador',
Incoterm: 'lst_ce_incoterm',
Observaciones: 'txt_ce_observaciones',
TipoCambioUSD: 'txt_ce_tipo_cambio_usd',
TotalUSD: 'txt_ce_total_usd',
};
Object.keys(controls).forEach(key => {
if(key in values){
$$(controls[key]).setValue(values[key])
}
});
var grid = $$('grid_ce_emisor')
grid.clearAll()
if ('emisor' in values) {
grid.add(values['emisor'])
} else {
grid.add({id: 0})
}
var grid = $$('grid_ce_receptor')
grid.clearAll()
if ('receptor' in values) {
grid.add(values['receptor'])
} else {
grid.add({id: 0})
}
var grid = $$('grid_ce_destinatario')
grid.clearAll()
if ('destinatario' in values) {
grid.add(values['destinatario'])
} else {
grid.add({id: 0})
}
var grid = $$('grid_ce_propietarios')
grid.clearAll()
if ('propietarios' in values) {
values['propietarios'].forEach(function(row, index){
row['delete'] = '-'
grid.add(row)
})
}
var grid = $$('grid_ce_mercancias')
grid.clearAll()
values['mercancias'].forEach(function(row, index){
row['delete'] = '-'
grid.add(row)
})
msg = 'Valores cargados correctamente' msg = 'Valores cargados correctamente'
msg_ok(msg) msg_ok(msg)
} }
@ -2899,7 +3170,196 @@ function up_invoice_json_comercioe_on_after_file_add(obj){
let reader = new FileReader() let reader = new FileReader()
reader.readAsText(obj.file) reader.readAsText(obj.file)
reader.onload = function(){ reader.onload = function(){
_set_from_json_comercioe(reader.result) _set_from_json_comercioe(reader.result, true)
} }
$$('win_import_json_comercioe').close() $$('win_import_json_comercioe').close()
} }
function cmd_show_global_information_click(){
win_global_information.init()
$$('win_global_information').show()
}
function cmd_save_global_information_click(){
values_global = $$('lst_global_periodicidad').getValue() + "|"
values_global += $$('lst_global_months').getValue() + "|"
values_global += $$('lst_global_year').getValue()
$$('win_global_information').close()
}
function cmd_win_global_close_click(){
$$('win_global_information').close()
}
function cmd_ce_tipo_cambio_click(){
window.open('https://www.banxico.org.mx/tipcamb/tipCamMIAction.do?idioma=sp', '_blank')
}
function cmd_ce_add_propietario_click(){
var g = $$('grid_ce_propietarios')
g.add({delete: '-'})
}
function grid_ce_propietarios_click(id, e, node){
if(id.column != 'delete'){
return
}
this.remove(id.row)
}
function cmd_ce_add_mercancia_click(){
var g = $$('grid_ce_mercancias')
g.add({delete: '-'})
}
function grid_ce_mercancias_click(id, e, node){
if(id.column != 'delete'){
return
}
this.remove(id.row)
}
function _get_values_comercio_exterior(){
var form = $$('form_comercio_exterior')
if(!form.validate()) {
msg_error('Valores inválidos en Comercio Exterior')
return
}
const controls = {
Exportacion: 'lst_ce_exportacion',
MotivoTraslado: 'lst_ce_motivo_traslado',
ClaveDePedimento: 'lst_ce_clave_pedimento',
CertificadoOrigen: 'lst_ce_certificado_origen',
NumCertificadoOrigen: 'txt_ce_numero_certificado',
NumeroExportadorConfiable: 'txt_ce_numero_exportador',
Incoterm: 'lst_ce_incoterm',
Observaciones: 'txt_ce_observaciones',
TipoCambioUSD: 'txt_ce_tipo_cambio_usd',
TotalUSD: 'txt_ce_total_usd',
};
var values = new Object()
Object.keys(controls).forEach(key => {
var value = $$(controls[key]).getValue().trim()
if(value){
values[key] = value
}
});
var propietarios = $$('grid_ce_propietarios').data.getRange()
propietarios.forEach(function(row, index){
delete row['id']
delete row['delete']
})
var mercancias = $$('grid_ce_mercancias').data.getRange()
mercancias.forEach(function(row, index){
delete row['id']
delete row['delete']
})
var emisor = $$('grid_ce_emisor').data.getRange()[0]
delete emisor['id']
var receptor = $$('grid_ce_receptor').data.getRange()[0]
delete receptor['id']
var destinatario = $$('grid_ce_destinatario').data.getRange()[0]
delete destinatario['id']
values['emisor'] = emisor
values['propietarios'] = propietarios
values['receptor'] = receptor
values['destinatario'] = destinatario
values['mercancias'] = mercancias
return values
}
function cmd_ce_import_ods_click(){
win_ce_import_ods.init()
$$('win_ce_import_ods').show()
}
function cmd_ce_upload_ods_click(){
var form = $$('form_ce_import_ods')
var values = form.getValues()
if(!$$('lst_ce_up_template').count()){
$$('win_ce_import_ods').close()
return
}
if($$('lst_ce_up_template').count() > 1){
msg = 'Selecciona solo un archivo'
msg_error(msg)
return
}
var template = $$('ce_up_template').files.getItem($$('ce_up_template').files.getFirstId())
if(template.type.toLowerCase() != 'ods'){
msg = 'Archivo inválido.\n\nSe requiere un archivo ODS'
msg_error(msg)
return
}
msg = '¿Estás seguro de importar este archivo?'
webix.confirm({
title: 'Importar datos de plantilla',
ok: 'Si',
cancel: 'No',
type: 'confirm-error',
text: msg,
callback:function(result){
if(result){
$$('ce_up_template').send()
}
}
})
}
function ce_up_template_complete(response){
if(response.status != 'server'){
msg = 'Ocurrio un error al subir el archivo'
msg_error(msg)
return
}
msg = 'Archivo subido correctamente.\n\nComenzando importación.'
msg_ok(msg)
$$('win_ce_import_ods').close()
webix.ajax().get('/values/importceods', {
error: function(text, data, xhr) {
msg_error('Error al consultar')
},
success: function(text, data, xhr){
var values = data.json()
if (values.ok){
_set_from_json_comercioe(values.data, false)
//~ msg_ok('Plantilla importada correctamente...')
}else{
webix.alert({
title: 'Error al importar',
text: values.msg,
type: 'alert-error',
})
}
}
})
}

View File

@ -40,6 +40,7 @@ function configuracion_inicial(){
add_config({'key': 'used_cfdi_pays', 'value': values.pagos}) add_config({'key': 'used_cfdi_pays', 'value': values.pagos})
add_config({'key': 'multi_currency', 'value': values.multi_currency}) add_config({'key': 'multi_currency', 'value': values.multi_currency})
add_config({'key': 'pays_data_bank', 'value': values.pays_data_bank}) add_config({'key': 'pays_data_bank', 'value': values.pays_data_bank})
add_config({'key': 'show_filter_by_day', 'value': values.show_filter_by_day})
}) })
@ -115,16 +116,19 @@ function menu_user_click(id, e, node){
function current_dates(){ function current_dates(){
var fy = $$('filter_year') var fy = $$('filter_year')
var fm = $$('filter_month') var fm = $$('filter_month')
var fd = $$('filter_day')
var pfy = $$('prefilter_year') var pfy = $$('prefilter_year')
var pfm = $$('prefilter_month') var pfm = $$('prefilter_month')
var d = new Date() var d = new Date()
fy.blockEvent() fy.blockEvent()
fm.blockEvent() fm.blockEvent()
fd.blockEvent()
pfy.blockEvent() pfy.blockEvent()
pfm.blockEvent() pfm.blockEvent()
fm.setValue(d.getMonth() + 1) fm.setValue(d.getMonth() + 1)
fd.setValue(d.getDate())
pfm.setValue(d.getMonth() + 1) pfm.setValue(d.getMonth() + 1)
webix.ajax().sync().get('/values/filteryears', function(text, data){ webix.ajax().sync().get('/values/filteryears', function(text, data){
var values = data.json() var values = data.json()
@ -136,6 +140,7 @@ function current_dates(){
fy.unblockEvent() fy.unblockEvent()
fm.unblockEvent() fm.unblockEvent()
fd.unblockEvent()
pfy.unblockEvent() pfy.unblockEvent()
pfm.unblockEvent() pfm.unblockEvent()
} }

View File

@ -232,18 +232,9 @@ function cmd_save_product_click(id, e, node){
} }
var rows = $$('grid_product_taxes').getSelectedId(true, true) var rows = $$('grid_product_taxes').getSelectedId(true, true)
//~ if (rows.length == 0){
//~ msg_error('Selecciona un impuesto')
//~ return
//~ }
var values = form.getValues(); var values = form.getValues();
//~ if(!isFinite(values.cant_by_packing)){
//~ msg_error('La cantidad por empaque debe ser un número')
//~ return
//~ }
if(!validate_sat_key_product(values.clave_sat, false)){ if(!validate_sat_key_product(values.clave_sat, false)){
msg_error('La clave SAT no existe') msg_error('La clave SAT no existe')
return return
@ -254,7 +245,19 @@ function cmd_save_product_click(id, e, node){
return return
} }
if(values['objeto_impuesto']=='01' && rows.length > 0){
msg = 'Si Objeto de Impuestos = 01, no debes seleccionar ningún impuesto'
msg_error(msg)
return
}
if(values['objeto_impuesto']=='02' && rows.length == 0){
msg = 'Si Objeto de Impuestos = 02, debes de seleccionar al menos un impuesto'
msg_error(msg)
return
}
values['taxes'] = JSON.stringify(rows) values['taxes'] = JSON.stringify(rows)
webix.ajax().sync().post('products', values, { webix.ajax().sync().post('products', values, {
error:function(text, data, XmlHttpRequest){ error:function(text, data, XmlHttpRequest){
msg = 'Ocurrio un error, consulta a soporte técnico' msg = 'Ocurrio un error, consulta a soporte técnico'

View File

@ -149,7 +149,9 @@ function configuracion_inicial_ticket_to_invoice(){
var grid = $$('grid_tickets_active') var grid = $$('grid_tickets_active')
var gridt = $$('grid_tickets_invoice') var gridt = $$('grid_tickets_invoice')
var form = $$('form_ticket_invoice') var form = $$('form_ticket_invoice')
var chk = $$('chk_is_invoice_day')
chk.setValue(false)
get_active_tickets(grid) get_active_tickets(grid)
form.setValues({id_partner: 0, lbl_tclient: 'Ninguno'}) form.setValues({id_partner: 0, lbl_tclient: 'Ninguno'})
gridt.attachEvent('onAfterAdd', function(id, index){ gridt.attachEvent('onAfterAdd', function(id, index){
@ -613,7 +615,12 @@ function chk_is_invoice_day_change(new_value, old_value){
var value = Boolean(new_value) var value = Boolean(new_value)
show('fs_ticket_search_client', !value) show('fs_ticket_search_client', !value)
enable('lst_periodicidad', value) enable('lst_global_periodicidad_2', value)
enable('lst_global_months_2', value)
var current_date = new Date()
var current_month = (current_date.getMonth() + 1).toString().padStart(2, '0')
$$('lst_global_months_2').setValue(current_month)
} }
@ -645,6 +652,7 @@ function save_ticket_to_invoice(data){
if(values.ok){ if(values.ok){
msg_ok(values.msg) msg_ok(values.msg)
send_timbrar_invoice(values.id) send_timbrar_invoice(values.id)
$$('chk_is_invoice_day').setValue(false)
$$('multi_tickets').setValue('tickets_home') $$('multi_tickets').setValue('tickets_home')
}else{ }else{
msg_error(values.msg) msg_error(values.msg)
@ -681,13 +689,26 @@ function cmd_new_invoice_from_ticket_click(){
}) })
var data = new Object() var data = new Object()
data['opt'] = 'invoice'
data['client'] = values.id_partner data['client'] = values.id_partner
data['tickets'] = tickets data['tickets'] = tickets
data['is_invoice_day'] = chk.getValue() data['is_invoice_day'] = chk.getValue()
data['periodicidad'] = $$('lst_periodicidad').getValue()
data['opt'] = 'invoice'
msg = 'Todos los datos son correctos.<BR><BR>¿Estás seguro de generar esta factura?' var periodicidad = ''
if(data['is_invoice_day']){
periodicidad = $$('lst_global_periodicidad_2').getValue() + '|'
periodicidad += $$('lst_global_months_2').getValue() + '|'
periodicidad += new Date().getFullYear()
}
data['periodicidad'] = periodicidad
msg = 'Todos los datos son correctos.<BR><BR>'
if(data['is_invoice_day']){
msg += 'Es Factura Global.<BR><BR>'
}
msg += '¿Estás seguro de generar esta factura?'
webix.confirm({ webix.confirm({
title: 'Generar Factura', title: 'Generar Factura',
ok: 'Si', ok: 'Si',

View File

@ -15,7 +15,7 @@
//~ along with this program. If not, see <http://www.gnu.org/licenses/>. //~ along with this program. If not, see <http://www.gnu.org/licenses/>.
var PUBLICO = "Público en general"; var PUBLICO = "PUBLICO EN GENERAL";
var RFC_PUBLICO = "XAXX010101000"; var RFC_PUBLICO = "XAXX010101000";
var RFC_EXTRANJERO = "XEXX010101000"; var RFC_EXTRANJERO = "XEXX010101000";
var PAIS = "México"; var PAIS = "México";
@ -24,6 +24,7 @@ var DECIMALES = 2;
var DECIMALES_TAX = 4; var DECIMALES_TAX = 4;
var CLAVE_ANTICIPOS = '84111506'; var CLAVE_ANTICIPOS = '84111506';
var CURRENCY_MN = 'MXN'; var CURRENCY_MN = 'MXN';
var KEY_SAT_01 = '01010101';
var db = new loki('data.db'); var db = new loki('data.db');
@ -54,6 +55,42 @@ var months = [
{id: 12, value: 'Diciembre'}, {id: 12, value: 'Diciembre'},
] ]
var days = [
{id: -1, value: '00'},
{id: 1, value: '01'},
{id: 2, value: '02'},
{id: 3, value: '03'},
{id: 4, value: '04'},
{id: 5, value: '05'},
{id: 6, value: '06'},
{id: 7, value: '07'},
{id: 8, value: '08'},
{id: 9, value: '09'},
{id: 10, value: '10'},
{id: 11, value: '11'},
{id: 12, value: '12'},
{id: 13, value: '13'},
{id: 14, value: '14'},
{id: 15, value: '15'},
{id: 16, value: '16'},
{id: 17, value: '17'},
{id: 18, value: '18'},
{id: 19, value: '19'},
{id: 20, value: '20'},
{id: 21, value: '21'},
{id: 22, value: '22'},
{id: 23, value: '23'},
{id: 24, value: '24'},
{id: 25, value: '25'},
{id: 26, value: '26'},
{id: 27, value: '27'},
{id: 28, value: '28'},
{id: 29, value: '29'},
{id: 30, value: '30'},
{id: 31, value: '31'},
]
function get_icon(tipo){ function get_icon(tipo){
icons = { icons = {
@ -627,3 +664,33 @@ function grid_parse(grid_name, values){
function activate_tab(parent, name){ function activate_tab(parent, name){
$$(parent).getTabbar().setValue(name) $$(parent).getTabbar().setValue(name)
} }
var opt_global_periodicidad = [
{id: '01', value: '[01] Diario'},
{id: '02', value: '[02] Semanal'},
{id: '03', value: '[03] Quincenal'},
{id: '04', value: '[04] Mensual'},
{id: '05', value: '[05] Bimestral'},
]
var opt_global_months = [
{id: '01', value: '[01] Enero'},
{id: '02', value: '[02] Febrero'},
{id: '03', value: '[03] Marzo'},
{id: '04', value: '[04] Abril'},
{id: '05', value: '[05] Mayo'},
{id: '06', value: '[06] Junio'},
{id: '07', value: '[07] Julio'},
{id: '08', value: '[08] Agosto'},
{id: '09', value: '[09] Septiembre'},
{id: '10', value: '[10] Octubre'},
{id: '11', value: '[11] Noviembre'},
{id: '12', value: '[12] Diciembre'},
{id: '13', value: '[13] Enero-Febrero'},
{id: '14', value: '[14] Marzo-Abril'},
{id: '15', value: '[15] Mayo-Junio'},
{id: '16', value: '[16] Julio-Agosto'},
{id: '17', value: '[17] Septiembre-Octubre'},
{id: '18', value: '[18] Noviembre-Diciembre'},
]

View File

@ -176,7 +176,9 @@ var emisor_datos_fiscales = [
invalidMessage: 'El C.P. es requerido'}, invalidMessage: 'El C.P. es requerido'},
{view: 'text', id: 'emisor_cp2', name: 'emisor_cp2', width: 300, {view: 'text', id: 'emisor_cp2', name: 'emisor_cp2', width: 300,
label: 'C.P. de Expedición: ', attributes: {maxlength: 5}}, label: 'C.P. de Expedición: ', attributes: {maxlength: 5}},
{}]}, {view: 'counter', id: 'emisor_hours', name: 'emisor_hours', value: 0,
required: false, label: 'Horas Dif.: ', step: 1, min: -1, max: 3}
]},
{cols: [ {cols: [
{view: 'label', label: 'Regimenes Fiscales *', required: true}, {}]}, {view: 'label', label: 'Regimenes Fiscales *', required: true}, {}]},
{cols: [{view: 'list', id: 'lst_emisor_regimen', select: 'multiselect', {cols: [{view: 'list', id: 'lst_emisor_regimen', select: 'multiselect',
@ -602,7 +604,9 @@ var opt_templates_cfdi = [
{id: '_4.0_cn_1.2.ods', value: 'CFDI v4.0 - Nómina v1.2'}, {id: '_4.0_cn_1.2.ods', value: 'CFDI v4.0 - Nómina v1.2'},
{id: '_4.0_cp_2.0.ods', value: 'CFDI v4.0 - Pagos v2.0'}, {id: '_4.0_cp_2.0.ods', value: 'CFDI v4.0 - Pagos v2.0'},
{id: '_4.0_ccp_2.0.ods', value: 'CFDI v4.0 - Carta Porte v2.0'}, {id: '_4.0_ccp_2.0.ods', value: 'CFDI v4.0 - Carta Porte v2.0'},
{id: '_4.0_ccp_3.0.ods', value: 'CFDI v4.0 - Carta Porte v3.0'},
{id: '_4.0_cd_1.1.ods', value: 'CFDI v4.0 - Donativos v1.1'}, {id: '_4.0_cd_1.1.ods', value: 'CFDI v4.0 - Donativos v1.1'},
{id: '_4.0_cce_2.0.ods', value: 'CFDI v4.0 - Comercio Exterior v2.0'},
{id: '_4.0.json', value: 'CFDI v4.0 - JSON'}, {id: '_4.0.json', value: 'CFDI v4.0 - JSON'},
{id: '_3.3.ods', value: 'CFDI v3.3'}, {id: '_3.3.ods', value: 'CFDI v3.3'},
{id: '_3.3_cn_1.2.ods', value: 'CFDI v3.3 - Nómina v1.2'}, {id: '_3.3_cn_1.2.ods', value: 'CFDI v3.3 - Nómina v1.2'},
@ -668,7 +672,7 @@ var options_admin_otros = [
{view: 'checkbox', id: 'chk_config_tax_locales', labelWidth: 0, {view: 'checkbox', id: 'chk_config_tax_locales', labelWidth: 0,
labelRight: 'Impuestos locales, calcular antes del descuento'}, labelRight: 'Impuestos locales, calcular antes del descuento'},
{view: 'checkbox', id: 'chk_config_tax_decimals', labelWidth: 0, {view: 'checkbox', id: 'chk_config_tax_decimals', labelWidth: 0,
labelRight: 'Calcular impuestos con 4 decimales'}, labelRight: 'Calcular impuestos con 4 decimales', hidden: true},
{view: 'checkbox', id: 'chk_config_price_with_taxes_in_invoice', labelWidth: 0, {view: 'checkbox', id: 'chk_config_price_with_taxes_in_invoice', labelWidth: 0,
labelRight: 'Precio incluye impuestos'}, labelRight: 'Precio incluye impuestos'},
{view: 'checkbox', id: 'chk_config_add_same_product', labelWidth: 0, {view: 'checkbox', id: 'chk_config_add_same_product', labelWidth: 0,
@ -687,6 +691,8 @@ var options_admin_otros = [
labelRight: 'Factura global por ticket'}, labelRight: 'Factura global por ticket'},
{view: 'checkbox', id: 'chk_config_show_total_cant', labelWidth: 0, {view: 'checkbox', id: 'chk_config_show_total_cant', labelWidth: 0,
labelRight: 'Mostrar total de cantidades'}, labelRight: 'Mostrar total de cantidades'},
{view: 'checkbox', id: 'chk_config_show_filter_by_day', labelWidth: 0,
labelRight: 'Mostrar filtro por día'},
{} {}
]}, ]},
{cols: [{maxWidth: 15}, {cols: [{maxWidth: 15},
@ -694,6 +700,11 @@ var options_admin_otros = [
labelRight: 'Solo admins pueden cancelar'}, labelRight: 'Solo admins pueden cancelar'},
{} {}
]}, ]},
{cols: [{maxWidth: 15},
{view: 'checkbox', id: 'chk_config_change_date_invoice', labelWidth: 0,
labelRight: 'Permitir cambiar fecha al facturar [No recomendable]'},
{}
]},
{maxHeight: 15}, {maxHeight: 15},
{template: 'Timbrado', type: 'section'}, {template: 'Timbrado', type: 'section'},

View File

@ -367,11 +367,13 @@ var toolbar_bank_invoice_pay_filter = [
{view: 'richselect', id: 'filter_invoice_pay_year', label: 'Año', {view: 'richselect', id: 'filter_invoice_pay_year', label: 'Año',
labelAlign: 'right', labelWidth: 50, width: 150, options: []}, labelAlign: 'right', labelWidth: 50, width: 150, options: []},
{view: 'richselect', id: 'filter_invoice_pay_month', label: 'Mes', {view: 'richselect', id: 'filter_invoice_pay_month', label: 'Mes',
labelAlign: 'right', labelWidth: 50, width: 200, options: months}, labelAlign: 'right', labelWidth: 50, width: 175, options: months},
{view: 'daterangepicker', id: 'filter_invoice_pay_dates', label: 'Fechas', {view: 'daterangepicker', id: 'filter_invoice_pay_dates', label: 'Fechas',
labelAlign: 'right', width: 300}, labelAlign: 'right', width: 275},
{view: 'button', id: 'cmd_invoice_pay_sat', label: 'SAT', {view: 'button', id: 'cmd_invoice_pay_sat', label: 'SAT',
type: 'iconButton', autowidth: true, icon: 'check-circle'}, type: 'iconButton', autowidth: true, icon: 'check-circle'},
{view: 'button', id: 'cmd_invoice_pay_cancel', label: 'Cancelar',
type: 'iconButton', autowidth: true, icon: 'ban'},
{}, {},
] ]
@ -626,7 +628,7 @@ var body_invoice_cancel_pay = {rows: [{minHeight: 15},
{view: 'richselect', id: 'lst_reasons_cancel', labelPosition: 'top', label: 'Razón de cancelación', options: opt_reasons_cancel_pay, value: '', width: 400}, {view: 'richselect', id: 'lst_reasons_cancel', labelPosition: 'top', label: 'Razón de cancelación', options: opt_reasons_cancel_pay, value: '', width: 400},
{view: 'text', id: 'txt_cancel_uuid', labelPosition: 'top', label: 'UUID que sustituye', width: 400}, {view: 'text', id: 'txt_cancel_uuid', labelPosition: 'top', label: 'UUID que sustituye', width: 400},
{view: 'label', label: 'Esta acción no se puede deshacer', autowidth: true, align: 'center'}, {view: 'label', label: 'Esta acción no se puede deshacer', autowidth: true, align: 'center'},
{view: 'label', label: '¿Estás segura de continuar?', autowidth: true, align: 'center'}, {view: 'label', label: '¿Estás seguro de continuar?', autowidth: true, align: 'center'},
{cols: [{}, {cols: [{},
{view: 'button', id: 'cmd_invoice_cancel_pay', width: 100, label: 'Cancelar', type: 'danger', icon: 'ban'}, {view: 'button', id: 'cmd_invoice_cancel_pay', width: 100, label: 'Cancelar', type: 'danger', icon: 'ban'},
{maxWidth: 25}, {maxWidth: 25},
@ -652,3 +654,35 @@ var win_invoice_cancel_pay = {
$$('cmd_win_cancel_pay_close').attachEvent('onItemClick', cmd_win_cancel_pay_close_click) $$('cmd_win_cancel_pay_close').attachEvent('onItemClick', cmd_win_cancel_pay_close_click)
} }
} }
var body_invoice_cancel_pay2 = {rows: [{minHeight: 15},
{view: 'richselect', id: 'lst_reasons_cancel2', labelPosition: 'top', label: 'Razón de cancelación', options: opt_reasons_cancel_pay, value: '', width: 400},
{view: 'text', id: 'txt_cancel_uuid2', labelPosition: 'top', label: 'UUID que sustituye', width: 400},
{view: 'label', label: 'Esta acción no se puede deshacer', autowidth: true, align: 'center'},
{view: 'label', label: '¿Estás seguro de continuar?', autowidth: true, align: 'center'},
{cols: [{},
{view: 'button', id: 'cmd_invoice_cancel_pay2', width: 100, label: 'Cancelar', type: 'danger', icon: 'ban'},
{maxWidth: 25},
{view: 'button', id: 'cmd_win_cancel_pay_close2', width: 100, label: 'Cerrar'},
{}
]},
{minHeight: 20},
]}
var win_invoice_cancel_pay2 = {
init: function(){
webix.ui({
view: 'window',
id: 'win_invoice_cancel_pay2',
modal: true,
width: 400,
position: 'center',
head: 'Cancelar CFDI de Pago',
body: body_invoice_cancel_pay2,
})
$$('cmd_invoice_cancel_pay2').attachEvent('onItemClick', cmd_invoice_cancel_pay2_click)
$$('cmd_win_cancel_pay_close2').attachEvent('onItemClick', cmd_win_cancel_pay_close2_click)
}
}

View File

@ -224,6 +224,8 @@ var toolbar_invoices_generate = {view: 'toolbar', elements: [{},
labelWidth: 0, width: 100, hidden: true}, labelWidth: 0, width: 100, hidden: true},
{view: 'checkbox', id: 'chk_cfdi_donativo', labelRight: 'Es Donativo', {view: 'checkbox', id: 'chk_cfdi_donativo', labelRight: 'Es Donativo',
labelWidth: 0, width: 100, hidden: true}, labelWidth: 0, width: 100, hidden: true},
{view: 'button', id: 'cmd_show_global_information', label: 'Global',
type: 'iconButton', autowidth: true, hidden: false, icon: 'file-code-o'},
{}]} {}]}
@ -232,6 +234,8 @@ var toolbar_invoices_filter = [
labelWidth: 50, width: 150, options: []}, labelWidth: 50, width: 150, options: []},
{view: 'richselect', id: 'filter_month', label: 'Mes', labelAlign: 'right', {view: 'richselect', id: 'filter_month', label: 'Mes', labelAlign: 'right',
labelWidth: 50, width: 200, options: months}, labelWidth: 50, width: 200, options: months},
{view: 'richselect', id: 'filter_day', label: 'Día', labelAlign: 'right',
labelWidth: 50, width: 125, options: days},
{view: 'daterangepicker', id: 'filter_dates', label: 'Fechas', {view: 'daterangepicker', id: 'filter_dates', label: 'Fechas',
labelAlign: 'right', width: 300}, labelAlign: 'right', width: 300},
{}, {},
@ -485,8 +489,11 @@ var suggest_students = {
} }
var body_comprobante = {rows: [{ var body_comprobante = {rows: [
cols: [ {view: 'datepicker', id: 'date_invoice', label: 'Fecha', format: '%d-%F-%Y',
required: true, invalidMessage: 'Selecciona una fecha', hidden: true
},
{cols: [
{ {
view: 'richselect', view: 'richselect',
id: 'lst_tipo_comprobante', id: 'lst_tipo_comprobante',
@ -838,20 +845,66 @@ var controls_leyendas_fiscales = [
] ]
var opt_transporte_internacional = [ var opt_ccp_transporte_internacional = [
{id: 'Sí', value: 'Sí'}, {id: 'Sí', value: 'Sí'},
{id: 'No', value: 'No'}, {id: 'No', value: 'No'},
] ]
var opt_entrada_salida = [ var opt_ccp_regimen_aduanero = [
{id: '', value: ''},
{id: 'IMD', value: '[IMD] Definitivo de importación.'},
{id: 'EXD', value: '[EXD] Definitivo de exportación.'},
{id: 'ITR', value: '[ITR] Temporales de importación para retomar al extranjero en el mismo estado.'},
{id: 'ITE', value: '[ITE] Temporales de importación para elaboración, transformación o reparación para empresas con programa IMMEX.'},
{id: 'ETR', value: '[ETR] Temporales de exportación para retornar al país en el mismo estado.'},
{id: 'ETE', value: '[ETE] Temporales de exportación para elaboración, transformación o reparación.'},
{id: 'DFI', value: '[DFI] Depósito Fiscal.'},
{id: 'RFE', value: '[RFE] Elaboración, transformación o reparación en recinto fiscalizado.'},
{id: 'RFS', value: '[RFS] Recinto fiscalizado estratégico.'},
{id: 'TRA', value: '[TRA] Tránsitos.'},
]
var opt_ccp_entrada_salida = [
{id: '', value: ''}, {id: '', value: ''},
{id: 'Entrada', value: 'Entrada'}, {id: 'Entrada', value: 'Entrada'},
{id: 'Salida', value: 'Salida'}, {id: 'Salida', value: 'Salida'},
] ]
var opt_origen_destino = [ var opt_ccp_pais_origen = [
{id: '', value: ''},
]
var opt_ccp_via_entrada = [
{id: '', value: ''},
{id: '01', value: '[01] Autotransporte'},
{id: '02', value: '[02] Marítimo'},
{id: '03', value: '[03] Aéreo'},
{id: '04', value: '[04] Ferroviario'},
]
var opt_ccp_ubicacion_polo = [
{id: '', value: ''},
{id: '01', value: '[01] Coatzacoalcos I'},
{id: '02', value: '[02] Coatzacoalcos II'},
{id: '03', value: '[03] Texistepec'},
{id: '04', value: '[04] San Juan Evangelista'},
{id: '05', value: '[05] Salina Cruz'},
{id: '06', value: '[06] San Blas Atempa'},
]
var opt_ccp_registro_istmo = [
{id: '', value: ''},
{id: 'Si', value: 'Sí'},
]
var opt_ccp_origen_destino = [
{id: 'Origen', value: 'Origen'}, {id: 'Origen', value: 'Origen'},
{id: 'Destino', value: 'Destino'}, {id: 'Destino', value: 'Destino'},
] ]
@ -866,12 +919,12 @@ var date_suggest = {
} }
var opt_countries = [ var opt_ccp_countries = [
{id: 'MEX', value: 'México'}, {id: 'MEX', value: 'México'},
] ]
var opt_carta_estados = [ var opt_ccp_carta_estados = [
{id: 'AGU', value: 'Aguascalientes'}, {id: 'AGU', value: 'Aguascalientes'},
{id: 'BCN', value: 'Baja California'}, {id: 'BCN', value: 'Baja California'},
{id: 'BCS', value: 'Baja California Sur'}, {id: 'BCS', value: 'Baja California Sur'},
@ -908,18 +961,25 @@ var opt_carta_estados = [
] ]
var grid_cols_carta_ubicaciones = [ var grid_cols_ccp_ubicaciones = [
{id: 'id', header: 'ID', hidden: true}, {id: 'id', header: 'ID', hidden: true},
{id: 'delete', header: '', hidden: true, width: 30, css: 'delete'}, {id: 'delete', header: '', width: 30, css: 'delete'},
{id: 'TipoUbicacion', header: 'Tipo de Ubicación', editor: 'select', options: opt_origen_destino, fillspace: 1}, {id: 'TipoUbicacion', header: 'TipoUbicacion', editor: 'select', options: opt_ccp_origen_destino, fillspace: 1},
//~ {id: 'IDUbicacion', header: 'IDUbicacion', hidden: true, editor: 'text', fillspace: 1},
{id: 'RFCRemitenteDestinatario', header: 'RFC Rem/Des', editor: 'text', fillspace: 1}, {id: 'RFCRemitenteDestinatario', header: 'RFC Rem/Des', editor: 'text', fillspace: 1},
{id: 'NombreRemitenteDestinatario', header: 'Nombre Rem/Des', editor: 'text', fillspace: 1}, {id: 'NombreRemitenteDestinatario', header: 'Nombre Rem/Des', editor: 'text', fillspace: 1},
//~ {id: 'NumRegIdTrib', header: 'NumRegIdTrib', hidden: true, editor: 'text', fillspace: 1},
//~ {id: 'ResidenciaFiscal', header: 'ResidenciaFiscal', hidden: true, editor: 'text', fillspace: 1},
//~ {id: 'NumEstacion', header: 'NumEstacion', hidden: true, editor: 'text', fillspace: 1},
//~ {id: 'NombreEstacion', header: 'NombreEstacion', hidden: true, editor: 'text', fillspace: 1},
//~ {id: 'NavegacionTrafico', header: 'NavegacionTrafico', hidden: true, editor: 'text', fillspace: 1},
{id: 'FechaHoraSalidaLlegada', header: 'Fecha/Hora', editor: 'date', suggest: date_suggest, format: webix.Date.dateToStr("%D, %d-%M-%Y %h:%i"), footer: 'Total distancia:', fillspace: 1}, {id: 'FechaHoraSalidaLlegada', header: 'Fecha/Hora', editor: 'date', suggest: date_suggest, format: webix.Date.dateToStr("%D, %d-%M-%Y %h:%i"), footer: 'Total distancia:', fillspace: 1},
//~ {id: 'TipoEstacion', header: 'TipoEstacion', hidden: true, editor: 'text', fillspace: 1},
{id: 'DistanciaRecorrida', header: 'Distancia (KM)', editor: 'text', format: webix.i18n.numberFormat, css: 'right', footer: {content: 'summColumn', css: 'right'}, fillspace: 1}, {id: 'DistanciaRecorrida', header: 'Distancia (KM)', editor: 'text', format: webix.i18n.numberFormat, css: 'right', footer: {content: 'summColumn', css: 'right'}, fillspace: 1},
{id: 'Municipio', headerd: 'Municipio', editor: 'text', fillspace: 1}, {id: 'Municipio', header: 'Municipio', editor: 'text', fillspace: 1},
{id: 'Estado', headerd: 'Estado', editor: 'select', options: opt_carta_estados, fillspace: 1}, {id: 'Estado', header: 'Estado', editor: 'select', options: opt_ccp_carta_estados, fillspace: 1},
{id: 'Pais', headerd: 'Pais', editor: 'select', options: opt_countries, fillspace: 1}, {id: 'Pais', header: 'País', editor: 'select', options: opt_ccp_countries, fillspace: 1},
{id: 'CodigoPostal', headerd: 'C.P.', editor: 'text', fillspace: 1}, {id: 'CodigoPostal', header: 'C.P.', editor: 'text', fillspace: 1},
] ]
//~ Calle //~ Calle
//~ NumeroExterior //~ NumeroExterior
@ -929,19 +989,29 @@ var grid_cols_carta_ubicaciones = [
//~ Referencia //~ Referencia
var grid_cols_carta_mercancias = [ var grid_cols_ccp_mercancias = [
{id: 'id', header: 'ID', hidden: true}, {id: 'id', header: 'ID', hidden: true},
{id: 'delete', header: '', width: 30, css: 'delete'}, {id: 'delete', header: '', width: 30, css: 'delete'},
{id: 'BienesTransp', header: 'Clave SAT', editor: 'text', fillspace: 1}, {id: 'BienesTransp', header: 'Clave SAT', editor: 'text', fillspace: 1},
//~ {id: 'ClaveSTCC', header: 'ClaveSTCC', editor: 'text', fillspace: 1},
{id: 'Descripcion', header: 'Descripción', editor: 'text', fillspace: 1}, {id: 'Descripcion', header: 'Descripción', editor: 'text', fillspace: 1},
{id: 'Cantidad', header: 'Cantidad', editor: 'text', format: webix.i18n.numberFormat, css: 'right', fillspace: 1}, {id: 'Cantidad', header: 'Cantidad', editor: 'text', format: webix.i18n.numberFormat, css: 'right', fillspace: 1},
{id: 'ClaveUnidad', header: 'Unidad', editor: 'select', options: 'values/unitbykey', footer: 'Total peso:', fillspace: 1}, {id: 'ClaveUnidad', header: 'Unidad', editor: 'select', options: 'values/unitbykey', footer: 'Total peso:', fillspace: 1},
//~ {id: 'ValorMercancia', header: 'Valor Mercancia', format: webix.i18n.priceFormat, css: 'right', footer: 'Total peso:', fillspace: 1}, //~ {id: 'Unidad', header: 'Unidad', editor: 'text', fillspace: 1},
//~ {id: 'Dimensiones', header: 'Dimensiones', editor: 'text', fillspace: 1},
//~ {id: 'MaterialPeligroso', header: 'MaterialPeligroso', editor: 'text', fillspace: 1},
//~ {id: 'CveMaterialPeligroso', header: 'CveMaterialPeligroso', editor: 'text', fillspace: 1},
//~ {id: 'Embalaje', header: 'Embalaje', editor: 'text', fillspace: 1},
//~ {id: 'DescripEmbalaje', header: 'DescripEmbalaje', editor: 'text', fillspace: 1},
//~ {id: 'SectorCOFEPRIS', header: 'SectorCOFEPRIS', editor: 'text', fillspace: 1},
{id: 'PesoEnKg', header: 'Peso (Kg)', format: webix.i18n.numberFormat, css: 'right', editor: 'text', footer: {content: 'summColumn', css: 'right'}, fillspace: 1}, {id: 'PesoEnKg', header: 'Peso (Kg)', format: webix.i18n.numberFormat, css: 'right', editor: 'text', footer: {content: 'summColumn', css: 'right'}, fillspace: 1},
//~ {id: 'ValorMercancia', header: 'Valor Mercancia', format: webix.i18n.priceFormat, css: 'right', footer: 'Total peso:', fillspace: 1},
//~ {id: 'Moneda', header: 'Moneda', editor: 'text', fillspace: 1},
//~ {id: 'FraccionArancelaria', header: 'FraccionArancelaria', editor: 'text', fillspace: 1},
] ]
var opt_carta_tipo_permiso_sct = [ var opt_ccp_tipo_permiso_sct = [
{id: 'TPAF01', value: '[TPAF01] Autotransporte Federal de carga general.'}, {id: 'TPAF01', value: '[TPAF01] Autotransporte Federal de carga general.'},
{id: 'TPAF02', value: '[TPAF02] Transporte privado de carga.'}, {id: 'TPAF02', value: '[TPAF02] Transporte privado de carga.'},
{id: 'TPAF03', value: '[TPAF03] Autotransporte Federal de Carga Especializada de materiales y residuos peligrosos.'}, {id: 'TPAF03', value: '[TPAF03] Autotransporte Federal de Carga Especializada de materiales y residuos peligrosos.'},
@ -971,7 +1041,7 @@ var opt_carta_tipo_permiso_sct = [
] ]
var opt_config_auto = [ var opt_ccp_config_auto = [
{id: '', value: ''}, {id: '', value: ''},
{id: 'VL', value: '[VL] Vehículo ligero de carga (2 llantas en el eje delantero y 2 llantas en el eje trasero)'}, {id: 'VL', value: '[VL] Vehículo ligero de carga (2 llantas en el eje delantero y 2 llantas en el eje trasero)'},
{id: 'C2', value: '[C2] Camión Unitario (2 llantas en el eje delantero y 4 llantas en el eje trasero)'}, {id: 'C2', value: '[C2] Camión Unitario (2 llantas en el eje delantero y 4 llantas en el eje trasero)'},
@ -1010,7 +1080,7 @@ var opt_config_auto = [
] ]
var opt_carta_tipo_remolque = [ var opt_ccp_tipo_remolque = [
{id: '', value: ''}, {id: '', value: ''},
{id: 'CTR001', value: '[CTR001] Caballete'}, {id: 'CTR001', value: '[CTR001] Caballete'},
{id: 'CTR002', value: '[CTR002] Caja'}, {id: 'CTR002', value: '[CTR002] Caja'},
@ -1046,27 +1116,42 @@ var opt_carta_tipo_remolque = [
] ]
var opt_carta_aseguradoras = [ //~ var opt_carta_aseguradoras = [
{id: 'General de Seguros', value: 'General de Seguros'}, //~ {id: 'General de Seguros', value: 'General de Seguros'},
{id: 'Qualitas', value: 'Qualitas'}, //~ {id: 'Qualitas', value: 'Qualitas'},
] //~ ]
var grid_cols_carta_autotransporte = [ var grid_cols_ccp_autotransporte = [
{id: 'id', header: 'ID', hidden: true}, {id: 'id', header: 'ID', hidden: true},
{id: 'PermSCT', header: 'Tipo Permiso SCT', editor: 'select', options: opt_carta_tipo_permiso_sct, fillspace: 1}, {id: 'PermSCT', header: 'PermSCT', editor: 'select', options: opt_ccp_tipo_permiso_sct, fillspace: 1},
{id: 'NumPermisoSCT', header: 'Número Permiso SCT', editor: 'text', fillspace: 1}, {id: 'NumPermisoSCT', header: 'NumPermisoSCT', editor: 'text', fillspace: 1},
{id: 'ConfigVehicular', header: 'Clave Autotransporte', editor: 'select', options: opt_config_auto, fillspace: 1}, {id: 'ConfigVehicular', header: 'ConfigVehicular', editor: 'select', options: opt_ccp_config_auto, fillspace: 1},
{id: 'PesoBrutoVehicular', header: 'PesoBrutoVehicular', editor: 'text', format: webix.i18n.numberFormat, css: 'right', fillspace: 1},
{id: 'PlacaVM', header: 'Placa', editor: 'text', fillspace: 1}, {id: 'PlacaVM', header: 'Placa', editor: 'text', fillspace: 1},
{id: 'AnioModeloVM', header: 'Modelo (Año)', editor: 'text', fillspace: 1}, {id: 'AnioModeloVM', header: 'Modelo (Año)', editor: 'text', fillspace: 1},
{id: 'SubTipoRem', header: 'ST Remolque', editor: 'select', options: opt_carta_tipo_remolque, fillspace: 1}, //~ {id: 'SubTipoRem', header: 'ST Remolque', editor: 'select', options: opt_ccp_tipo_remolque, fillspace: 1},
//~ {id: 'Placa', header: 'Placa', editor: 'text', fillspace: 1},
]
var grid_cols_ccp_remolques = [
{id: 'id', header: 'ID', hidden: true},
{id: 'delete', header: '', width: 30, css: 'delete'},
{id: 'SubTipoRem', header: 'SubTipo Remolque', editor: 'select', options: opt_ccp_tipo_remolque, fillspace: 1},
{id: 'Placa', header: 'Placa', editor: 'text', fillspace: 1}, {id: 'Placa', header: 'Placa', editor: 'text', fillspace: 1},
]
var grid_cols_ccp_seguros = [
{id: 'id', header: 'ID', hidden: true},
{id: 'AseguraRespCivil', header: 'Aseguradora', editor: 'text', fillspace: 1}, {id: 'AseguraRespCivil', header: 'Aseguradora', editor: 'text', fillspace: 1},
{id: 'PolizaRespCivil', header: 'Póliza', editor: 'text', fillspace: 1}, {id: 'PolizaRespCivil', header: 'Póliza', editor: 'text', fillspace: 1},
//~ {id: 'AseguraMedAmbiente', header: 'AseguraMedAmbiente', editor: 'text', fillspace: 1},
//~ {id: 'PolizaMedAmbiente', header: 'PolizaMedAmbiente', editor: 'text', fillspace: 1},
//~ {id: 'AseguraCarga', header: 'AseguraCarga', editor: 'text', fillspace: 1},
//~ {id: 'PolizaCarga', header: 'PolizaCarga', editor: 'text', fillspace: 1},
//~ {id: 'PrimaSeguro', header: 'PrimaSeguro', editor: 'text', format: webix.i18n.numberFormat, css: 'right', fillspace: 1},
] ]
var opt_tipos_figura = [ var opt_ccp_tipos_figura = [
{id: '', value: ''}, {id: '', value: ''},
{id: '01', value: '[01] Operador'}, {id: '01', value: '[01] Operador'},
{id: '02', value: '[02] Propietario'}, {id: '02', value: '[02] Propietario'},
@ -1075,101 +1160,167 @@ var opt_tipos_figura = [
] ]
var grid_cols_carta_tipos_figuras = [ var grid_cols_ccp_tipos_figuras = [
{id: 'id', header: 'ID', hidden: true}, {id: 'id', header: 'ID', hidden: true},
{id: 'TipoFigura', header: 'Tipo Figura', editor: 'select', options: opt_tipos_figura, fillspace: 1}, {id: 'TipoFigura', header: 'TipoFigura', editor: 'select', options: opt_ccp_tipos_figura, fillspace: 1},
{id: 'RFCFigura', header: 'RFC Figura', editor: 'text', fillspace: 1}, {id: 'RFCFigura', header: 'RFCFigura', editor: 'text', fillspace: 1},
{id: 'NombreFigura', header: 'Nombre Figura', editor: 'text', fillspace: 1}, {id: 'NumLicencia', header: 'NumLicencia', editor: 'text', fillspace: 1},
{id: 'NumLicencia', header: 'Número de Licencia', editor: 'text', fillspace: 1}, {id: 'NombreFigura', header: 'NombreFigura', editor: 'text', fillspace: 1},
//~ {id: 'NumRegIdTribFigura', header: 'NumRegIdTribFigura', editor: 'text', fillspace: 1},
//~ {id: 'ResidenciaFiscalFigura', header: 'ResidenciaFiscalFigura', editor: 'text', fillspace: 1},
//~ {id: 'Municipio', header: 'Municipio', editor: 'text', fillspace: 1},
//~ {id: 'Estado', header: 'Estado', editor: 'select', options: opt_ccp_carta_estados, fillspace: 1},
//~ {id: 'Pais', header: 'País', editor: 'select', options: opt_ccp_countries, fillspace: 1},
//~ {id: 'CodigoPostal', header: 'C.P.', editor: 'text', fillspace: 1},
] ]
var grid_carta_ubicaciones = { var grid_ccp_ubicaciones = {
view: 'datatable', view: 'datatable',
id: 'grid_carta_ubicaciones', id: 'grid_ccp_ubicaciones',
multiselect: false, multiselect: false,
adjust: true, adjust: true,
autoheight: true, autoheight: true,
headermenu: true, headermenu: true,
editable: true, editable: true,
footer: true, footer: true,
columns: grid_cols_carta_ubicaciones, columns: grid_cols_ccp_ubicaciones,
//~ data: data_tmp1,
data: [
{delete: '-', TipoUbicacion: 'Origen', Pais: 'MEX'},
{delete: '-', TipoUbicacion: 'Destino', Pais: 'MEX'},
]
} }
var grid_carta_mercancias = { var grid_ccp_mercancias = {
view: 'datatable', view: 'datatable',
id: 'grid_carta_mercancias', id: 'grid_ccp_mercancias',
multiselect: false, multiselect: false,
adjust: true, adjust: true,
autoheight: true, autoheight: true,
headermenu: true, headermenu: true,
editable: true, editable: true,
footer: true, footer: true,
columns: grid_cols_carta_mercancias, columns: grid_cols_ccp_mercancias,
} }
var grid_carta_autotransporte = { var grid_ccp_autotransporte = {
view: 'datatable', view: 'datatable',
id: 'grid_carta_autotransporte', id: 'grid_ccp_autotransporte',
multiselect: false, multiselect: false,
adjust: true, adjust: true,
autoheight: true, autoheight: true,
headermenu: true, headermenu: true,
editable: true, editable: true,
columns: grid_cols_carta_autotransporte, columns: grid_cols_ccp_autotransporte,
data: [{id: 0}], data: [{id: 0}],
//~ data: data_tmp2,
} }
var grid_ccp_remolques = {
var grid_carta_tipos_figuras = {
view: 'datatable', view: 'datatable',
id: 'grid_carta_tipos_figuras', id: 'grid_ccp_remolques',
multiselect: false, multiselect: false,
adjust: true, adjust: true,
autoheight: true, autoheight: true,
headermenu: true, headermenu: true,
editable: true, editable: true,
columns: grid_cols_carta_tipos_figuras, columns: grid_cols_ccp_remolques,
}
var grid_ccp_seguros = {
view: 'datatable',
id: 'grid_ccp_seguros',
multiselect: false,
adjust: true,
autoheight: true,
headermenu: true,
editable: true,
columns: grid_cols_ccp_seguros,
data: [{id: 0}], data: [{id: 0}],
//~ data: data_tmp3,
} }
var body_carta_mercancias = {rows:[ var grid_ccp_tipos_figuras = {
view: 'datatable',
id: 'grid_ccp_tipos_figuras',
multiselect: false,
adjust: true,
autoheight: true,
headermenu: true,
editable: true,
columns: grid_cols_ccp_tipos_figuras,
data: [{id: 0}],
}
var body_ccp_ubicaciones = {rows:[
{cols: [ {cols: [
{view: 'button', id: 'cmd_carta_add_product', label: 'Agregar Mercancía', icon: 'plus', {view: 'button', id: 'cmd_ccp_agregar_ubicacion', label: 'Agregar Ubicación', icon: 'plus',
type: 'iconButton', autowidth: true, align: 'center'}, type: 'iconButton', autowidth: true, align: 'center'},
{view: 'button', id: 'cmd_carta_copy_from_invoice', label: 'Copiar de CFDI', icon: 'copy', {}]},
{maxHeight: 10},
grid_ccp_ubicaciones,
]}
var body_ccp_mercancias = {rows:[
{cols: [
{view: 'button', id: 'cmd_ccp_add_product', label: 'Agregar Mercancía', icon: 'plus',
type: 'iconButton', autowidth: true, align: 'center'}, type: 'iconButton', autowidth: true, align: 'center'},
//~ {view: 'button', id: 'cmd_carta_copy_from_invoice', label: 'Copiar de CFDI', icon: 'copy',
//~ type: 'iconButton', autowidth: true, align: 'center'},
{}, {},
{view: 'richselect', id: 'lst_carta_UnidadPeso', label: 'Unidad de Peso: ', {view: 'richselect', id: 'lst_carta_UnidadPeso', label: 'Unidad de Peso: ',
labelWidth: 110, maxWidth: 300, options: '/satunidadespeso?opt=active'} labelWidth: 110, maxWidth: 300, options: '/satunidadespeso?opt=active'}
]}, ]},
{maxHeight: 10}, {maxHeight: 10},
grid_carta_mercancias, grid_ccp_mercancias,
]} ]}
var body_carta_ubicaciones = {rows:[ var body_ccp_autotransporte = {rows:[
grid_carta_ubicaciones, grid_ccp_autotransporte,
{minHeight: 10},
{cols: [
{view: 'button', id: 'cmd_ccp_agregar_remolque', label: 'Agregar Remolque', icon: 'plus',
type: 'iconButton', autowidth: true, align: 'center'},
{}]},
{minHeight: 10},
grid_ccp_remolques,
{minHeight: 10},
grid_ccp_seguros,
]} ]}
var body_carta_autotransporte = {rows:[ var body_ccp_tipos_figuras = {rows:[
grid_carta_autotransporte, grid_ccp_tipos_figuras,
]} ]}
var body_carta_tipos_figuras = {rows:[ var body_cp_datos_generales = {rows:[
grid_carta_tipos_figuras, {cols: [{maxWidth: 15},
{view: 'richselect', id: 'lst_cp_TranspInternac', labelPosition: 'top',
label: 'TranspInternac', options: opt_ccp_transporte_internacional,
value: 'No', readonly: true},
{view: 'richselect', id: 'lst_cp_RegimenAduanero', labelPosition: 'top',
label: 'RegimenAduanero', options: opt_ccp_regimen_aduanero,
value: '', disabled: true},
{view: 'richselect', id: 'lst_cp_EntradaSalidaMerc', labelPosition: 'top',
label: 'EntradaSalidaMerc', options: opt_ccp_entrada_salida,
value: '', disabled: true},
{view: 'richselect', id: 'lst_cp_PaisOrigenDestino', labelPosition: 'top',
label: 'PaisOrigenDestino', options: opt_ccp_pais_origen,
value: '', disabled: true},
{view: 'richselect', id: 'lst_cp_ViaEntradaSalida', labelPosition: 'top',
label: 'ViaEntradaSalida', options: opt_ccp_via_entrada,
value: '', disabled: true},
]},
{cols: [{maxWidth: 15},
{view: 'richselect', id: 'lst_cp_RegistroISTMO', labelPosition: 'top',
label: 'RegistroISTMO', options: opt_ccp_registro_istmo,
value: '', readonly: false},
{view: 'richselect', id: 'lst_cp_UbicacionPoloOrigen', labelPosition: 'top',
label: 'UbicacionPoloOrigen', options: opt_ccp_ubicacion_polo,
value: '', disabled: true},
{view: 'richselect', id: 'lst_cp_UbicacionPoloDestino', labelPosition: 'top',
label: 'UbicacionPoloDestino', options: opt_ccp_ubicacion_polo,
value: '', disabled: true},
{}]},
]} ]}
@ -1182,34 +1333,276 @@ var controls_carta_porte = [
{view: 'button', id: 'cmd_carta_import_ods', label: 'Importar ODS', {view: 'button', id: 'cmd_carta_import_ods', label: 'Importar ODS',
icon: 'upload', type: 'iconButton', autowidth: true, align: 'center'}, icon: 'upload', type: 'iconButton', autowidth: true, align: 'center'},
{maxWidth: 15}]}, {maxWidth: 15}]},
{view: 'fieldset', label: 'Mercancias', body: body_carta_mercancias}, {view: 'fieldset', label: 'Datos generales', body: body_cp_datos_generales},
{cols: [{maxWidth: 15}, {view: 'fieldset', label: 'Ubicaciones', body: body_ccp_ubicaciones},
{view: 'richselect', id: 'lst_carta_TranspInternac', labelPosition: 'top', {view: 'fieldset', label: 'Mercancias', body: body_ccp_mercancias},
label: 'Transporte Internacional', options: opt_transporte_internacional, {view: 'fieldset', label: 'Autotransporte', body: body_ccp_autotransporte},
value: 'No', readonly: true}, {view: 'fieldset', label: 'Tipos Figura', body: body_ccp_tipos_figuras},
{view: 'richselect', id: 'lst_carta_EntradaSalidaMerc', labelPosition: 'top',
label: 'Entrada o Salida', options: opt_entrada_salida,
value: '', disabled: true},
{view: 'richselect', id: 'lst_carta_PaisOrigenDestino', labelPosition: 'top',
label: 'País Origen/Destino', options: [],
value: '', disabled: true},
{view: 'richselect', id: 'lst_carta_ViaEntradaSalida', labelPosition: 'top',
label: 'Vía de Entrada o Salida', options: [],
value: '', disabled: true},
]},
{view: 'fieldset', label: 'Ubicaciones', body: body_carta_ubicaciones},
{view: 'fieldset', label: 'Autotransporte', body: body_carta_autotransporte},
{view: 'fieldset', label: 'Tipos Figura', body: body_carta_tipos_figuras},
] ]
var opt_ce_exportacion = [
{id: '02', value: '[02] Definitiva con clave A1'},
{id: '03', value: '[03] Temporal'},
{id: '04', value: '[04] Definitiva con clave distinta a A1'},
]
var opt_ce_motivo_traslado = [
{id: '', value: ''},
{id: '01', value: '[01] Envío de mercancias facturadas con anterioridad'},
{id: '02', value: '[02] Reubicación de mercancías propias'},
{id: '03', value: '[03] Envío de mercancías objeto de contrato de consignación'},
{id: '04', value: '[04] Envío de mercancías para posterior enajenación'},
{id: '05', value: '[05] Envío de mercancías propiedad de terceros'},
{id: '99', value: '[99] Otros'},
]
var opt_ce_clave_pedimento = [
{id: 'A1', value: '[A1] Definitiva'},
]
var opt_ce_certificado_origen = [
{id: '0', value: '[0] No funge'},
{id: '1', value: '[1] Funge'},
]
var opt_ce_incoterm = [
{id: 'CFR', value: '[CFR] Coste y flete (puerto de destino convenido)'},
{id: 'CIF', value: '[CIF] Coste, seguro y flete (puerto de destino convenido)'},
{id: 'CPT', value: '[CPT] Trasnporte pagado hasta el lugar de destino convenido'},
{id: 'CIP', value: '[CIP] Trasnporte y seguro pagado hasta el lugar de destino convenido'},
{id: 'DAP', value: '[DAP] Entregada en lugar'},
{id: 'DDP', value: '[DDP] Entregada derechos pagados en lugar de destino convenido'},
{id: 'DPU', value: '[DPU] Entregada y descargada en lugar acordado'},
{id: 'EXW', value: '[EXW] En fábrica (lugar convenido)'},
{id: 'FCA', value: '[FCA] Franco transportista (lugar designado)'},
{id: 'FAS', value: '[FAS] Franco al costado del buque (puerto de carga convenido)'},
{id: 'FOB', value: '[FOB] Franco a bordo (puerto de carga convenido)'},
]
var body_ce_datos_generales = {rows:[
{cols: [{maxWidth: 15},
{view: 'richselect', id: 'lst_ce_exportacion', label: 'Exportación: ',
value: '02', labelWidth: 130, minWidth: 400, options: opt_ce_exportacion},
{view: 'richselect', id: 'lst_ce_motivo_traslado', label: 'Motivo Traslado: ',
labelWidth: 130, minWidth: 500, options: opt_ce_motivo_traslado},
{},
{maxWidth: 15}]},
{cols: [{maxWidth: 15},
{view: 'richselect', id: 'lst_ce_clave_pedimento', label: 'Clave de Pedimento: ',
value: 'A1', labelWidth: 130, minWidth: 400, maxWidth: 400, options: opt_ce_clave_pedimento},
{view: 'richselect', id: 'lst_ce_certificado_origen', label: 'Certificado Origen: ',
value: '0', labelWidth: 130, maxWidth: 300, options: opt_ce_certificado_origen},
{view: 'text', id: 'txt_ce_numero_certificado', label: 'Nº Certificado:', labelWidth: 100},
{maxWidth: 15}]},
{cols: [{maxWidth: 15},
{view: 'text', id: 'txt_ce_numero_exportador', label: 'Nº Exportador: ',
labelWidth: 130, minWidth: 400, maxWidth: 500},
{view: 'richselect', id: 'lst_ce_incoterm', label: 'Incoterm: ', value: 'CFR',
labelWidth: 130, minWidth: 500, maxWidth: 500, options: opt_ce_incoterm},
{view: 'text', id: 'txt_ce_observaciones', label: 'Observaciones:', labelWidth: 100},
{maxWidth: 15}]},
{cols: [{maxWidth: 15},
{view: 'text', id: 'txt_ce_total_usd', label: 'Total USD: ',
labelWidth: 130, minWidth: 400, inputAlign: 'right'},
{view: 'text', id: 'txt_ce_tipo_cambio_usd', label: 'Tipo Cambio USD:', labelWidth: 130,
inputAlign: 'right'},
{},
{view: 'button', id: 'cmd_ce_tipo_cambio', label: 'TC Banxico',
type: 'iconButton', autowidth: true, icon: ''},
{maxWidth: 15}]},
]}
var grid_cols_ce_emisor = [
{id: 'id', header: 'ID', hidden: true},
{id: 'Curp', header: 'Curp', editor: 'text', fillspace: 1},
{id: 'Calle', header: 'Calle *', editor: 'text', fillspace: 1},
{id: 'NumeroExterior', header: 'Numero Exterior', editor: 'text', fillspace: 1},
{id: 'NumeroInterior', header: 'Número Interior', editor: 'text', fillspace: 1},
{id: 'Colonia', header: 'Colonia', editor: 'text', fillspace: 1},
{id: 'Municipio', header: 'Municipio', editor: 'text', fillspace: 1},
{id: 'Estado', header: 'Estado *', editor: 'text', fillspace: 1},
{id: 'Pais', header: 'País *', editor: 'text', fillspace: 1},
{id: 'CodigoPostal', header: 'C.P. *', editor: 'text', fillspace: 1},
]
var grid_ce_emisor = {
view: 'datatable',
id: 'grid_ce_emisor',
multiselect: false,
adjust: true,
autoheight: true,
headermenu: true,
editable: true,
columns: grid_cols_ce_emisor,
data: [{id: 0}],
}
var body_ce_emisor = {rows:[
grid_ce_emisor
]}
var grid_cols_ce_propietarios = [
{id: 'id', header: 'ID', hidden: true},
{id: 'delete', header: '', width: 30, css: 'delete'},
{id: 'NumRegIdTrib', header: 'Registro Fiscal', editor: 'text', fillspace: 1},
{id: 'ResidenciaFiscal', header: 'Residencia Fiscal', editor: 'text', fillspace: 1},
]
var grid_ce_propietarios = {
view: 'datatable',
id: 'grid_ce_propietarios',
multiselect: false,
adjust: true,
autoheight: true,
headermenu: true,
editable: true,
footer: false,
columns: grid_cols_ce_propietarios,
}
var body_ce_propietarios = {rows:[
{cols: [
{view: 'button', id: 'cmd_ce_add_propietario', label: 'Agregar Propietario',
icon: 'plus', type: 'iconButton', autowidth: true, align: 'center'},
{},
]},
{maxHeight: 10},
grid_ce_propietarios
]}
var grid_cols_ce_receptor = [
{id: 'id', header: 'ID', hidden: true},
{id: 'NumRegIdTrib', header: 'Registro Fiscal', editor: 'text', fillspace: 1},
{id: 'Calle', header: 'Calle *', editor: 'text', fillspace: 1},
{id: 'NumeroExterior', header: 'Numero Exterior', editor: 'text', fillspace: 1},
{id: 'NumeroInterior', header: 'Número Interior', editor: 'text', fillspace: 1},
{id: 'Colonia', header: 'Colonia', editor: 'text', fillspace: 1},
{id: 'Municipio', header: 'Municipio', editor: 'text', fillspace: 1},
{id: 'Estado', header: 'Estado *', editor: 'text', fillspace: 1},
{id: 'Pais', header: 'País *', editor: 'text', fillspace: 1},
{id: 'CodigoPostal', header: 'C.P. *', editor: 'text', fillspace: 1},
]
var grid_ce_receptor = {
view: 'datatable',
id: 'grid_ce_receptor',
multiselect: false,
adjust: true,
autoheight: true,
headermenu: true,
editable: true,
columns: grid_cols_ce_receptor,
data: [{id: 0}],
}
var body_ce_receptor = {rows:[
grid_ce_receptor
]}
var grid_cols_ce_destinatario = [
{id: 'id', header: 'ID', hidden: true},
{id: 'NumRegIdTrib', header: 'Registro Fiscal', editor: 'text', fillspace: 1},
{id: 'Nombre', header: 'Nombre', editor: 'text', fillspace: 1},
{id: 'Calle', header: 'Calle *', editor: 'text', fillspace: 1},
{id: 'NumeroExterior', header: 'No Exterior', editor: 'text', fillspace: 1},
{id: 'NumeroInterior', header: 'No Interior', editor: 'text', fillspace: 1},
{id: 'Colonia', header: 'Colonia', editor: 'text', fillspace: 1},
{id: 'Municipio', header: 'Municipio', editor: 'text', fillspace: 1},
{id: 'Estado', header: 'Estado *', editor: 'text', fillspace: 1},
{id: 'Pais', header: 'País *', editor: 'text', fillspace: 1},
{id: 'CodigoPostal', header: 'C.P. *', editor: 'text', fillspace: 1},
]
var grid_ce_destinatario = {
view: 'datatable',
id: 'grid_ce_destinatario',
multiselect: false,
adjust: true,
autoheight: true,
headermenu: true,
editable: true,
columns: grid_cols_ce_destinatario,
data: [{id: 0}],
}
var body_ce_destinatario = {rows:[
grid_ce_destinatario
]}
var grid_cols_ce_mercancias = [
{id: 'id', header: 'ID', hidden: true},
{id: 'delete', header: '', width: 30, css: 'delete'},
{id: 'NoIdentificacion', header: 'Clave', editor: 'text', fillspace: 1},
{id: 'FraccionArancelaria', header: 'Fraccion Arancelaria', editor: 'text', fillspace: 1},
{id: 'CantidadAduana', header: 'Cantidad Aduana', editor: 'text', fillspace: 1},
{id: 'UnidadAduana', header: 'Unidad Aduana', editor: 'text', fillspace: 1},
{id: 'ValorUnitarioAduana', header: 'PU Aduana', editor: 'text', fillspace: 1},
{id: 'ValorDolares', header: 'Valor USD', editor: 'text', fillspace: 1},
{id: 'Marca', header: 'Marca', editor: 'text', hidden: true, fillspace: 1},
{id: 'Modelo', header: 'Modelo', editor: 'text', hidden: true, fillspace: 1},
{id: 'SubModelo', header: 'SubModelo', editor: 'text', hidden: true, fillspace: 1},
{id: 'NumeroSerie', header: 'Serie', editor: 'text', hidden: true, fillspace: 1},
]
var grid_ce_mercancias = {
view: 'datatable',
id: 'grid_ce_mercancias',
multiselect: false,
adjust: true,
autoheight: true,
headermenu: true,
editable: true,
footer: true,
columns: grid_cols_ce_mercancias,
}
var body_ce_mercancias = {rows:[
{cols: [
{view: 'button', id: 'cmd_ce_add_mercancia', label: 'Agregar Mercancía',
icon: 'plus', type: 'iconButton', autowidth: true, align: 'center'},
{},
]},
{maxHeight: 10},
grid_ce_mercancias
]}
var controls_comercio_exterior = [ var controls_comercio_exterior = [
{cols: [{maxWidth: 15}, {cols: [{maxWidth: 15},
{view: 'checkbox', id: 'chk_cfdi_usar_comercioe', labelWidth: 0, {view: 'checkbox', id: 'chk_cfdi_usar_comercioe', labelWidth: 0,
labelRight: 'Usar el complemento Comercio Exterior'}, {}, labelRight: 'Usar el complemento Comercio Exterior'},
{},
{view: 'button', id: 'cmd_import_json_comercioe', label: 'Importar JSON', {view: 'button', id: 'cmd_import_json_comercioe', label: 'Importar JSON',
icon: 'upload', type: 'iconButton', autowidth: true, align: 'center'}, icon: 'upload', type: 'iconButton', autowidth: true, align: 'center'},
{maxWidth: 15}]} {view: 'button', id: 'cmd_ce_import_ods', label: 'Importar ODS',
icon: 'upload', type: 'iconButton', autowidth: true, align: 'center'},
{maxWidth: 15}]},
{view: 'fieldset', label: 'Datos generales', body: body_ce_datos_generales},
{view: 'fieldset', label: 'Emisor', body: body_ce_emisor},
{view: 'fieldset', label: 'Propietario', body: body_ce_propietarios},
{view: 'fieldset', label: 'Receptor', body: body_ce_receptor},
{view: 'fieldset', label: 'Destinatario', body: body_ce_destinatario},
{view: 'fieldset', label: 'Mercancías', body: body_ce_mercancias},
] ]
@ -1317,7 +1710,13 @@ var win_import_invoice = {
width: 400, width: 400,
modal: true, modal: true,
position: 'center', position: 'center',
head: 'Importar Factura de Plantilla', head: {view: 'toolbar',
elements: [
{view: 'label', label: 'Importar Factura en Lote'},
{view: 'icon', icon: 'times-circle',
click: '$$("win_import_invoice").close()'},
]
},
body: body_upload_invoice, body: body_upload_invoice,
}) })
$$('cmd_upload_invoice').attachEvent('onItemClick', cmd_upload_invoice_click) $$('cmd_upload_invoice').attachEvent('onItemClick', cmd_upload_invoice_click)
@ -1425,3 +1824,82 @@ var win_import_json_comercioe = {
$$('up_invoice_json').attachEvent('onAfterFileAdd', up_invoice_json_comercioe_on_after_file_add) $$('up_invoice_json').attachEvent('onAfterFileAdd', up_invoice_json_comercioe_on_after_file_add)
} }
} }
var body_global_information = {rows: [{minHeight: 5},
{view: 'richselect', id: 'lst_global_periodicidad', label: 'Periodicidad:', options: opt_global_periodicidad, value: '01'},
{view: 'richselect', id: 'lst_global_months', label: 'Mes:', options: opt_global_months, value: '01'},
{view: 'richselect', id: 'lst_global_year', label: 'Año:', options: []},
{view: 'label', label: '¿Guardar estos datos?', width: 300, align: 'center'},
{cols: [{},
{view: 'button', id: 'cmd_save_global_information', width: 100, label: 'Si Guardar'},
{maxWidth: 25},
{view: 'button', id: 'cmd_win_global_close', width: 100, label: 'No, Cerrar'},
{}
]},
{minHeight: 10},
]}
var win_global_information = {
init: function(){
webix.ui({
view: 'window',
id: 'win_global_information',
modal: true,
width: 400,
position: 'center',
head: 'Información Global',
body: body_global_information,
})
var current_date = new Date()
var current_month = (current_date.getMonth() + 1).toString().padStart(2, '0')
$$('lst_global_months').setValue(current_month)
var current_year = current_date.getFullYear()
$$('lst_global_year').getList().parse([{id: current_year, value: current_year}])
$$('lst_global_year').setValue(current_year)
$$('cmd_save_global_information').attachEvent('onItemClick', cmd_save_global_information_click)
$$('cmd_win_global_close').attachEvent('onItemClick', cmd_win_global_close_click)
}
}
var body_win_ce_import_ods = {rows: [
{view: 'form', id: 'form_ce_import_ods', rows: [
{cols: [{},
{view: 'uploader', id: 'ce_up_template', autosend: false,
link: 'lst_ce_up_template', value: 'Seleccionar Archivo',
upload: '/files/ceods'}, {}]},
{cols: [
{view: 'list', id: 'lst_ce_up_template',
type: 'uploader', autoheight: true, borderless: true}]},
{cols: [{}, {view: 'button', id: 'cmd_ce_upload_ods',
label: 'Importar Plantilla'}, {}]},
]},
]}
var win_ce_import_ods = {
init: function(){
webix.ui({
view: 'window',
id: 'win_ce_import_ods',
width: 400,
modal: true,
position: 'center',
head: {view: 'toolbar',
elements: [
{view: 'label', label: 'Importar desde archivo ODS'},
{view: 'icon', icon: 'times-circle',
click: '$$("win_ce_import_ods").close()'},
]
},
body: body_win_ce_import_ods,
})
$$('cmd_ce_upload_ods').attachEvent('onItemClick', cmd_ce_upload_ods_click)
$$('ce_up_template').attachEvent('onUploadComplete', ce_up_template_complete)
}
}

View File

@ -116,6 +116,7 @@ var opt_tax_object = [
{id: '02', value: '[02] Sí objeto de impuesto.'}, {id: '02', value: '[02] Sí objeto de impuesto.'},
{id: '03', value: '[03] Sí objeto del impuesto y no obligado al desglose.'}, {id: '03', value: '[03] Sí objeto del impuesto y no obligado al desglose.'},
{id: '04', value: '[04] Sí objeto del impuesto y no causa impuesto.'}, {id: '04', value: '[04] Sí objeto del impuesto y no causa impuesto.'},
{id: '05', value: '[05] Sí objeto del impuesto, IVA crédito PODEBI.'},
] ]
@ -153,13 +154,6 @@ var controls_generals = [
width: 500, labelWidth: 150, labelAlign: "right", required: true, width: 500, labelWidth: 150, labelAlign: "right", required: true,
invalidMessage: 'Este campo es requerido', options: opt_tax_object}, invalidMessage: 'Este campo es requerido', options: opt_tax_object},
{}, {},
//~ {view: 'text', id: 'cant_by_packing', name: 'cant_by_packing',
//~ labelAlign: 'right', labelWidth: 150, inputAlign: "right",
//~ label: 'Cantidad por empaque:'},
//~ {},
//~ {view: 'text', id: 'tags_producto', name: 'tags_producto',
//~ labelAlign: 'right', label: 'Etiquetas',
//~ placeholder: 'Separadas por comas'}
]}, ]},
{cols: [ {cols: [
{view: "currency", type: "text", id: "valor_unitario", {view: "currency", type: "text", id: "valor_unitario",

View File

@ -233,20 +233,13 @@ var cells_new_ticket = [
] ]
var opt_periodicidad = [
{id: '01', value: '[01] Diario'},
{id: '02', value: '[02] Semanal'},
{id: '03', value: '[03] Quincenal'},
{id: '04', value: '[04] Mensual'},
//~ {id: '05', value: '[05] Bimestral'},
]
var toolbar_ticket_invoice = {view: 'toolbar', elements: [{}, var toolbar_ticket_invoice = {view: 'toolbar', elements: [{},
{view: 'checkbox', id: 'chk_is_invoice_day', labelWidth: 0, width: 150, {view: 'checkbox', id: 'chk_is_invoice_day', labelWidth: 0, width: 150,
labelRight: 'Es factura del día'}, labelRight: 'Es Factura Global'},
{view: 'richselect', id: 'lst_periodicidad', labelWidth: 90, width: 250, {view: 'richselect', id: 'lst_global_periodicidad_2', labelWidth: 90, width: 225,
label: 'Periodicidad:', options: opt_periodicidad, value: '01', disabled: true}, label: 'Periodicidad:', options: opt_global_periodicidad, value: '01', disabled: true},
{view: 'richselect', id: 'lst_global_months_2', labelWidth: 50, width: 250,
label: 'Mes:', options: opt_global_months, value: '01', disabled: true},
{}, {},
{view: 'button', id: 'cmd_close_ticket_invoice', label: 'Cerrar', {view: 'button', id: 'cmd_close_ticket_invoice', label: 'Cerrar',
type: 'danger', autowidth: true, align: 'center'} type: 'danger', autowidth: true, align: 'center'}

Binary file not shown.

Binary file not shown.

View File

@ -10,8 +10,8 @@
<xsl:include href="ine11.xslt"/> <xsl:include href="ine11.xslt"/>
<xsl:include href="iedu.xslt"/> <xsl:include href="iedu.xslt"/>
<xsl:include href="leyendasFisc.xslt"/> <xsl:include href="leyendasFisc.xslt"/>
<xsl:include href="cartaporte20.xslt"/> <xsl:include href="cartaporte30.xslt"/>
<xsl:include href="comercioexterior11.xslt"/> <xsl:include href="comercioexterior20.xslt"/>
<xsl:include href="donat11.xslt"/> <xsl:include href="donat11.xslt"/>
<xsl:include href="pagos20.xslt"/> <xsl:include href="pagos20.xslt"/>
<xsl:include href="implocal.xslt"/> <xsl:include href="implocal.xslt"/>

View File

@ -0,0 +1,744 @@
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:cartaporte30="http://www.sat.gob.mx/CartaPorte30">
<xsl:template match="cartaporte30:CartaPorte">
<!--Manejador de nodos tipo CartaPorte-->
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@Version"/>
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@IdCCP"/>
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@TranspInternac"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@RegimenAduanero"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@EntradaSalidaMerc"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@PaisOrigenDestino"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@ViaEntradaSalida"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@TotalDistRec"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@RegistroISTMO"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@UbicacionPoloOrigen"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@UbicacionPoloDestino"/>
</xsl:call-template>
<!-- Iniciamos el manejo de los elementos hijo en la secuencia -->
<xsl:for-each select="./cartaporte30:Ubicaciones">
<xsl:apply-templates select="."/>
</xsl:for-each>
<xsl:for-each select="./cartaporte30:Mercancias">
<xsl:apply-templates select="."/>
</xsl:for-each>
<xsl:for-each select="./cartaporte30:FiguraTransporte">
<xsl:apply-templates select="."/>
</xsl:for-each>
</xsl:template>
<!-- Iniciamos el manejo de los elementos hijo en la secuencia Ubicaciones-->
<xsl:template match="cartaporte30:Ubicaciones">
<!-- Iniciamos el tratamiento de los atributos de Ubicacion-->
<xsl:for-each select="./cartaporte30:Ubicacion">
<xsl:apply-templates select="."/>
</xsl:for-each>
</xsl:template>
<!-- Iniciamos el manejo de los elementos hijo en la secuencia Ubicacion-->
<xsl:template match="cartaporte30:Ubicacion">
<!--Manejador de nodos tipo Ubicacion-->
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@TipoUbicacion"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@IDUbicacion"/>
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@RFCRemitenteDestinatario"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@NombreRemitenteDestinatario"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@NumRegIdTrib"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@ResidenciaFiscal"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@NumEstacion"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@NombreEstacion"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@NavegacionTrafico"/>
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@FechaHoraSalidaLlegada"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@TipoEstacion"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@DistanciaRecorrida"/>
</xsl:call-template>
<!-- Iniciamos el tratamiento de los atributos de cartaporte30:Domicilio-->
<xsl:for-each select="./cartaporte30:Domicilio">
<!-- Iniciamos el manejo de los elementos hijo en la secuencia Domicilio-->
<!-- Iniciamos el manejo de los nodos dependientes -->
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@Calle"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@NumeroExterior"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@NumeroInterior"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@Colonia"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@Localidad"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@Referencia"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@Municipio"/>
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@Estado"/>
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@Pais"/>
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@CodigoPostal"/>
</xsl:call-template>
</xsl:for-each>
</xsl:template>
<!-- Iniciamos el manejo de los elementos hijo en la secuencia Origen-->
<xsl:template match="cartaporte30:Mercancias">
<!--Manejador de nodos tipo cartaporte30:Mercancias-->
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@PesoBrutoTotal"/>
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@UnidadPeso"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@PesoNetoTotal"/>
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@NumTotalMercancias"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@CargoPorTasacion"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@LogisticaInversaRecoleccionDevolucion"/>
</xsl:call-template>
<!-- Iniciamos el tratamiento de los atributos de cartaporte30:Mercancia-->
<xsl:for-each select="./cartaporte30:Mercancia">
<xsl:apply-templates select="."/>
</xsl:for-each>
<!-- Iniciamos el tratamiento de los atributos de cartaporte30:Autotransporte-->
<xsl:for-each select="./cartaporte30:Autotransporte">
<xsl:apply-templates select="."/>
</xsl:for-each>
<!-- Iniciamos el tratamiento de los atributos de cartaporte30:TransporteMaritimo-->
<xsl:for-each select="./cartaporte30:TransporteMaritimo">
<xsl:apply-templates select="."/>
</xsl:for-each>
<!-- Iniciamos el tratamiento de los atributos de cartaporte30:TransporteAereo-->
<xsl:for-each select="./cartaporte30:TransporteAereo">
<xsl:apply-templates select="."/>
</xsl:for-each>
<!-- Iniciamos el tratamiento de los atributos de cartaporte30:TransporteFerroviario-->
<xsl:for-each select="./cartaporte30:TransporteFerroviario">
<xsl:apply-templates select="."/>
</xsl:for-each>
</xsl:template>
<!-- Iniciamos el manejo de los elementos hijo en la secuencia Mercancia-->
<xsl:template match="cartaporte30:Mercancia">
<!--Manejador de nodos tipo cartaporte30:Mercancia-->
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@BienesTransp"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@ClaveSTCC"/>
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@Descripcion"/>
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@Cantidad"/>
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@ClaveUnidad"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@Unidad"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@Dimensiones"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@MaterialPeligroso"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@CveMaterialPeligroso"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@Embalaje"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@DescripEmbalaje"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@SectorCOFEPRIS"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@NombreIngredienteActivo"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@NomQuimico"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@DenominacionGenericaProd"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@DenominacionDistintivaProd"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@Fabricante"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@FechaCaducidad"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@LoteMedicamento"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@FormaFarmaceutica"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@CondicionesEspTransp"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@RegistroSanitarioFolioAutorizacion"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@PermisoImportacion"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@FolioImpoVUCEM"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@NumCAS"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@RazonSocialEmpImp"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@NumRegSanPlagCOFEPRIS"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@DatosFabricante"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@DatosFormulador"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@DatosMaquilador"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@UsoAutorizado"/>
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@PesoEnKg"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@ValorMercancia"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@Moneda"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@FraccionArancelaria"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@UUIDComercioExt"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@TipoMateria"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@DescripcionMateria"/>
</xsl:call-template>
<!-- Iniciamos el tratamiento de los atributos de cartaporte30:DocumentacionAduanera-->
<xsl:for-each select="./cartaporte30:DocumentacionAduanera">
<xsl:apply-templates select="."/>
</xsl:for-each>
<!-- Iniciamos el tratamiento de los atributos de cartaporte30:GuiasIdentificacion-->
<xsl:for-each select="./cartaporte30:GuiasIdentificacion">
<xsl:apply-templates select="."/>
</xsl:for-each>
<!-- Iniciamos el tratamiento de los atributos de cartaporte30:CantidadTransporta-->
<xsl:for-each select="./cartaporte30:CantidadTransporta">
<xsl:apply-templates select="."/>
</xsl:for-each>
<!-- Iniciamos el tratamiento de los atributos de cartaporte30:DetalleMercancia-->
<xsl:for-each select="./cartaporte30:DetalleMercancia">
<xsl:apply-templates select="."/>
</xsl:for-each>
</xsl:template>
<!-- Iniciamos el manejo de los elementos hijo en la secuencia DocumentacionAduanera-->
<xsl:template match="cartaporte30:DocumentacionAduanera">
<!-- Iniciamos el manejo de los nodos dependientes -->
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@TipoDocumento"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@NumPedimento"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@IdentDocAduanero"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@RFCImpo"/>
</xsl:call-template>
</xsl:template>
<!-- Iniciamos el manejo de los elementos hijo en la secuencia GuiasIdentificacion-->
<xsl:template match="cartaporte30:GuiasIdentificacion">
<!-- Iniciamos el manejo de los nodos dependientes -->
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@NumeroGuiaIdentificacion"/>
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@DescripGuiaIdentificacion"/>
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@PesoGuiaIdentificacion"/>
</xsl:call-template>
</xsl:template>
<!-- Iniciamos el manejo de los elementos hijo en la secuencia CantidadTransporta-->
<xsl:template match="cartaporte30:CantidadTransporta">
<!-- Iniciamos el manejo de los nodos dependientes -->
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@Cantidad"/>
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@IDOrigen"/>
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@IDDestino"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@CvesTransporte"/>
</xsl:call-template>
</xsl:template>
<!-- Iniciamos el manejo de los elementos hijo en la secuencia DetalleMercancia-->
<xsl:template match="cartaporte30:DetalleMercancia">
<!-- Iniciamos el manejo de los nodos dependientes -->
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@UnidadPesoMerc"/>
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@PesoBruto"/>
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@PesoNeto"/>
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@PesoTara"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@NumPiezas"/>
</xsl:call-template>
</xsl:template>
<!-- Iniciamos el manejo de los elementos hijo en la secuencia Autotransporte-->
<xsl:template match="cartaporte30:Autotransporte">
<!--Manejador de nodos tipo cartaporte30:Autotransporte-->
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@PermSCT"/>
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@NumPermisoSCT"/>
</xsl:call-template>
<!-- Iniciamos el tratamiento de los atributos de cartaporte30:IdentificacionVehicular-->
<xsl:for-each select="./cartaporte30:IdentificacionVehicular">
<xsl:apply-templates select="."/>
</xsl:for-each>
<!-- Iniciamos el tratamiento de los atributos de cartaporte30:Seguros-->
<xsl:for-each select="./cartaporte30:Seguros">
<xsl:apply-templates select="."/>
</xsl:for-each>
<!-- Iniciamos el tratamiento de los atributos de cartaporte30:Remolques-->
<xsl:for-each select="./cartaporte30:Remolques">
<xsl:apply-templates select="."/>
</xsl:for-each>
</xsl:template>
<!-- Iniciamos el manejo de los elementos hijo en la secuencia IdentificacionVehicular-->
<xsl:template match="cartaporte30:IdentificacionVehicular">
<!-- Iniciamos el manejo de los nodos dependientes -->
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@ConfigVehicular"/>
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@PesoBrutoVehicular"/>
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@PlacaVM"/>
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@AnioModeloVM"/>
</xsl:call-template>
</xsl:template>
<!-- Iniciamos el manejo de los elementos hijo en la secuencia Seguros-->
<xsl:template match="cartaporte30:Seguros">
<!-- Iniciamos el manejo de los nodos dependientes -->
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@AseguraRespCivil"/>
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@PolizaRespCivil"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@AseguraMedAmbiente"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@PolizaMedAmbiente"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@AseguraCarga"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@PolizaCarga"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@PrimaSeguro"/>
</xsl:call-template>
</xsl:template>
<!-- Iniciamos el manejo de los elementos hijo en la secuencia Remolques-->
<xsl:template match="cartaporte30:Remolques">
<!-- Iniciamos el tratamiento de los atributos de cartaporte30:Remolque-->
<xsl:for-each select="./cartaporte30:Remolque">
<xsl:apply-templates select="."/>
</xsl:for-each>
</xsl:template>
<!-- Iniciamos el manejo de los elementos hijo en la secuencia Remolque-->
<xsl:template match="cartaporte30:Remolque">
<!-- Iniciamos el manejo de los nodos dependientes -->
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@SubTipoRem"/>
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@Placa"/>
</xsl:call-template>
</xsl:template>
<!-- Iniciamos el manejo de los elementos hijo en la secuencia TransporteMaritimo-->
<xsl:template match="cartaporte30:TransporteMaritimo">
<!--Manejador de nodos tipo cartaporte30:TransporteMaritimo-->
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@PermSCT"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@NumPermisoSCT"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@NombreAseg"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@NumPolizaSeguro"/>
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@TipoEmbarcacion"/>
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@Matricula"/>
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@NumeroOMI"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@AnioEmbarcacion"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@NombreEmbarc"/>
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@NacionalidadEmbarc"/>
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@UnidadesDeArqBruto"/>
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@TipoCarga"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@Eslora"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@Manga"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@Calado"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@Puntal"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@LineaNaviera"/>
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@NombreAgenteNaviero"/>
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@NumAutorizacionNaviero"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@NumViaje"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@NumConocEmbarc"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@PermisoTempNavegacion"/>
</xsl:call-template>
<!-- Iniciamos el tratamiento de los atributos de cartaporte30:Contenedor-->
<xsl:for-each select="./cartaporte30:Contenedor">
<!-- Iniciamos el manejo de los elementos hijo en la secuencia Contenedor-->
<!-- Iniciamos el manejo de los nodos dependientes -->
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@TipoContenedor"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@MatriculaContenedor"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@NumPrecinto"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@IdCCPRelacionado"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@PlacaVMCCP"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@FechaCertificacionCCP"/>
</xsl:call-template>
</xsl:for-each>
<!-- Iniciamos el tratamiento de los atributos de cartaporte30:RemolquesCCP-->
<xsl:for-each select="./cartaporte30:RemolquesCCP">
<xsl:apply-templates select="."/>
</xsl:for-each>
</xsl:template>
<!-- Iniciamos el manejo de los elementos hijo en la secuencia RemolquesCCP-->
<xsl:template match="cartaporte30:RemolquesCCP">
<!-- Iniciamos el tratamiento de los atributos de cartaporte30:RemolqueCCP-->
<xsl:for-each select="./cartaporte30:RemolqueCCP">
<xsl:apply-templates select="."/>
</xsl:for-each>
</xsl:template>
<!-- Iniciamos el manejo de los elementos hijo en la secuencia RemolqueCCP-->
<xsl:template match="cartaporte30:RemolqueCCP">
<!-- Iniciamos el manejo de los nodos dependientes -->
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@SubTipoRemCCP"/>
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@PlacaCCP"/>
</xsl:call-template>
</xsl:template>
<!-- Iniciamos el manejo de los elementos hijo en la secuencia TransporteAereo-->
<xsl:template match="cartaporte30:TransporteAereo">
<!--Manejador de nodos tipo cartaporte30:TransporteAereo-->
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@PermSCT"/>
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@NumPermisoSCT"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@MatriculaAeronave"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@NombreAseg"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@NumPolizaSeguro"/>
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@NumeroGuia"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@LugarContrato"/>
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@CodigoTransportista"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@RFCEmbarcador"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@NumRegIdTribEmbarc"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@ResidenciaFiscalEmbarc"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@NombreEmbarcador"/>
</xsl:call-template>
</xsl:template>
<!-- Iniciamos el manejo de los elementos hijo en la secuencia TransporteFerroviario-->
<xsl:template match="cartaporte30:TransporteFerroviario">
<!--Manejador de nodos tipo cartaporte30:TransporteFerroviario-->
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@TipoDeServicio"/>
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@TipoDeTrafico"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@NombreAseg"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@NumPolizaSeguro"/>
</xsl:call-template>
<!-- Iniciamos el tratamiento de los atributos de cartaporte30:DerechosDePaso-->
<xsl:for-each select="./cartaporte30:DerechosDePaso">
<xsl:apply-templates select="."/>
</xsl:for-each>
<!-- Iniciamos el tratamiento de los atributos de cartaporte30:Carro-->
<xsl:for-each select="./cartaporte30:Carro">
<xsl:apply-templates select="."/>
</xsl:for-each>
</xsl:template>
<!-- Iniciamos el manejo de los elementos hijo en la secuencia DerechosDePaso-->
<xsl:template match="cartaporte30:DerechosDePaso">
<!-- Iniciamos el manejo de los nodos dependientes -->
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@TipoDerechoDePaso"/>
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@KilometrajePagado"/>
</xsl:call-template>
</xsl:template>
<!-- Iniciamos el manejo de los elementos hijo en la secuencia Carro-->
<xsl:template match="cartaporte30:Carro">
<!--Manejador de nodos tipo cartaporte30:Carro-->
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@TipoCarro"/>
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@MatriculaCarro"/>
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@GuiaCarro"/>
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@ToneladasNetasCarro"/>
</xsl:call-template>
<!-- Iniciamos el tratamiento de los atributos de cartaporte30:Contenedor -->
<xsl:for-each select="./cartaporte30:Contenedor ">
<!-- Iniciamos el manejo de los elementos hijo en la secuencia Contenedor-->
<!-- Iniciamos el manejo de los nodos dependientes -->
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@TipoContenedor"/>
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@PesoContenedorVacio"/>
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@PesoNetoMercancia"/>
</xsl:call-template>
</xsl:for-each>
</xsl:template>
<!-- Iniciamos el manejo de los elementos hijo en la secuencia FiguraTransporte-->
<xsl:template match="cartaporte30:FiguraTransporte">
<!--Manejador de nodos tipo cartaporte30:FiguraTransporte-->
<!-- Iniciamos el tratamiento de los atributos de cartaporte30:TiposFigura-->
<xsl:for-each select="./cartaporte30:TiposFigura ">
<xsl:apply-templates select="."/>
</xsl:for-each>
</xsl:template>
<!-- Iniciamos el manejo de los elementos hijo en la secuencia TiposFigura-->
<xsl:template match="cartaporte30:TiposFigura">
<!-- Iniciamos el tratamiento de los atributos de cartaporte30:TiposFigura-->
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@TipoFigura"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@RFCFigura"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@NumLicencia"/>
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@NombreFigura"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@NumRegIdTribFigura"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@ResidenciaFiscalFigura"/>
</xsl:call-template>
<xsl:for-each select="./cartaporte30:PartesTransporte">
<xsl:apply-templates select="."/>
</xsl:for-each>
<!-- Iniciamos el tratamiento de los atributos de cartaporte30:Domicilio -->
<xsl:for-each select="./cartaporte30:Domicilio ">
<!-- Iniciamos el manejo de los elementos hijo en la secuencia Domicilio -->
<!-- Iniciamos el manejo de los nodos dependientes -->
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@Calle"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@NumeroExterior"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@NumeroInterior"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@Colonia"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@Localidad"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@Referencia"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@Municipio"/>
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@Estado"/>
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@Pais"/>
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@CodigoPostal"/>
</xsl:call-template>
</xsl:for-each>
</xsl:template>
<!-- Iniciamos el manejo de los elementos hijo en la secuencia PartesTransporte -->
<xsl:template match="cartaporte30:PartesTransporte">
<!-- Manejador de nodos tipo cartaporte30:PartesTransporte -->
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@ParteTransporte"/>
</xsl:call-template>
</xsl:template>
</xsl:stylesheet>

View File

@ -0,0 +1,171 @@
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:cce20="http://www.sat.gob.mx/ComercioExterior20">
<xsl:template match="cce20:ComercioExterior">
<!--Manejador de nodos tipo ComercioExterior-->
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@Version" />
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@MotivoTraslado" />
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@ClaveDePedimento" />
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@CertificadoOrigen" />
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@NumCertificadoOrigen" />
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@NumeroExportadorConfiable" />
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@Incoterm" />
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@Observaciones" />
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@TipoCambioUSD" />
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@TotalUSD" />
</xsl:call-template>
<!-- Iniciamos el manejo de los elementos hijo en la secuencia -->
<xsl:apply-templates select="./cce20:Emisor" />
<xsl:apply-templates select="./cce20:Receptor" />
<xsl:for-each select="./cce20:Destinatario">
<xsl:apply-templates select="."/>
</xsl:for-each>
<xsl:apply-templates select="./cce20:Mercancias" />
</xsl:template>
<xsl:template match="cce20:Emisor">
<!-- Iniciamos el tratamiento de los atributos de cce20:Emisor-->
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@Curp" />
</xsl:call-template>
<xsl:apply-templates select="./cce20:Domicilio" />
</xsl:template>
<xsl:template match="cce20:Propietario">
<!-- Iniciamos el tratamiento de los atributos de cce20:Propietario-->
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@NumRegIdTrib" />
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@ResidenciaFiscal" />
</xsl:call-template>
</xsl:template>
<xsl:template match="cce20:Receptor">
<!-- Tratamiento de los atributos de cce20:Receptor-->
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@NumRegIdTrib" />
</xsl:call-template>
<xsl:apply-templates select="./cce20:Domicilio" />
</xsl:template>
<xsl:template match="cce20:Destinatario">
<!-- Tratamiento de los atributos de cce20:Destinatario-->
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@NumRegIdTrib" />
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@Nombre" />
</xsl:call-template>
<!-- Manejo de los nodos dependientes -->
<xsl:for-each select="./cce20:Domicilio">
<xsl:apply-templates select="."/>
</xsl:for-each>
</xsl:template>
<xsl:template match="cce20:Mercancias">
<!-- Iniciamos el manejo de los nodos dependientes -->
<xsl:for-each select="./cce20:Mercancia">
<xsl:apply-templates select="."/>
</xsl:for-each>
</xsl:template>
<xsl:template match="cce20:Domicilio">
<!-- Iniciamos el tratamiento de los atributos de cce20:Domicilio-->
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@Calle" />
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@NumeroExterior" />
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@NumeroInterior" />
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@Colonia" />
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@Localidad" />
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@Referencia" />
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@Municipio" />
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@Estado" />
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@Pais" />
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@CodigoPostal" />
</xsl:call-template>
</xsl:template>
<xsl:template match="cce20:Mercancia">
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@NoIdentificacion" />
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@FraccionArancelaria" />
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@CantidadAduana" />
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@UnidadAduana" />
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@ValorUnitarioAduana" />
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@ValorDolares" />
</xsl:call-template>
<xsl:for-each select="./cce20:DescripcionesEspecificas">
<xsl:apply-templates select="."/>
</xsl:for-each>
</xsl:template>
<xsl:template match="cce20:DescripcionesEspecificas">
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@Marca" />
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@Modelo" />
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@SubModelo" />
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@NumeroSerie" />
</xsl:call-template>
</xsl:template>
</xsl:stylesheet>