catalogmx 0.3.0__py3-none-any.whl → 0.4.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- catalogmx/__init__.py +133 -19
- catalogmx/calculators/__init__.py +113 -0
- catalogmx/calculators/costo_trabajador.py +213 -0
- catalogmx/calculators/impuestos.py +920 -0
- catalogmx/calculators/imss.py +370 -0
- catalogmx/calculators/isr.py +290 -0
- catalogmx/calculators/resico.py +154 -0
- catalogmx/catalogs/banxico/__init__.py +29 -3
- catalogmx/catalogs/banxico/cetes_sqlite.py +279 -0
- catalogmx/catalogs/banxico/inflacion_sqlite.py +302 -0
- catalogmx/catalogs/banxico/salarios_minimos_sqlite.py +295 -0
- catalogmx/catalogs/banxico/tiie_sqlite.py +279 -0
- catalogmx/catalogs/banxico/tipo_cambio_usd_sqlite.py +255 -0
- catalogmx/catalogs/banxico/udis_sqlite.py +332 -0
- catalogmx/catalogs/cnbv/__init__.py +9 -0
- catalogmx/catalogs/cnbv/sectores.py +173 -0
- catalogmx/catalogs/conapo/__init__.py +15 -0
- catalogmx/catalogs/conapo/sistema_urbano_nacional.py +50 -0
- catalogmx/catalogs/conapo/zonas_metropolitanas.py +230 -0
- catalogmx/catalogs/ift/__init__.py +1 -1
- catalogmx/catalogs/ift/codigos_lada.py +517 -313
- catalogmx/catalogs/inegi/__init__.py +17 -0
- catalogmx/catalogs/inegi/scian.py +127 -0
- catalogmx/catalogs/mexico/__init__.py +2 -0
- catalogmx/catalogs/mexico/giros_mercantiles.py +119 -0
- catalogmx/catalogs/sat/carta_porte/material_peligroso.py +5 -1
- catalogmx/catalogs/sat/cfdi_4/clave_prod_serv.py +78 -0
- catalogmx/catalogs/sat/cfdi_4/tasa_o_cuota.py +2 -1
- catalogmx/catalogs/sepomex/__init__.py +2 -1
- catalogmx/catalogs/sepomex/codigos_postales.py +30 -2
- catalogmx/catalogs/sepomex/codigos_postales_completo.py +261 -0
- catalogmx/cli.py +12 -9
- catalogmx/data/__init__.py +10 -0
- catalogmx/data/mexico_dynamic.sqlite3 +0 -0
- catalogmx/data/updater.py +362 -0
- catalogmx/generators/__init__.py +20 -0
- catalogmx/generators/identity.py +582 -0
- catalogmx/helpers.py +177 -3
- catalogmx/utils/__init__.py +29 -0
- catalogmx/utils/clabe_utils.py +417 -0
- catalogmx/utils/text.py +7 -1
- catalogmx/validators/clabe.py +52 -2
- catalogmx/validators/nss.py +32 -27
- catalogmx/validators/rfc.py +185 -52
- catalogmx-0.4.0.dist-info/METADATA +905 -0
- {catalogmx-0.3.0.dist-info → catalogmx-0.4.0.dist-info}/RECORD +51 -25
- {catalogmx-0.3.0.dist-info → catalogmx-0.4.0.dist-info}/WHEEL +1 -1
- catalogmx/catalogs/banxico/udis.py +0 -279
- catalogmx-0.3.0.dist-info/METADATA +0 -644
- {catalogmx-0.3.0.dist-info → catalogmx-0.4.0.dist-info}/entry_points.txt +0 -0
- {catalogmx-0.3.0.dist-info → catalogmx-0.4.0.dist-info}/licenses/AUTHORS.rst +0 -0
- {catalogmx-0.3.0.dist-info → catalogmx-0.4.0.dist-info}/licenses/LICENSE +0 -0
- {catalogmx-0.3.0.dist-info → catalogmx-0.4.0.dist-info}/top_level.txt +0 -0
|
@@ -1,22 +1,40 @@
|
|
|
1
|
-
catalogmx/__init__.py,sha256=
|
|
2
|
-
catalogmx/cli.py,sha256=
|
|
3
|
-
catalogmx/helpers.py,sha256=
|
|
1
|
+
catalogmx/__init__.py,sha256=cwYHYfPYyA7Lexfjn_R4wxBed6p_hpvjJvnU7Yj09jg,4999
|
|
2
|
+
catalogmx/cli.py,sha256=jpRhbpWyfB0bComm5w221Fxn8zgMnQdjOVMPummKlCA,6659
|
|
3
|
+
catalogmx/helpers.py,sha256=rrlIRF5Z1iv12u-SsFqRSIAXz_VE79kX3NbSSayqBaw,13936
|
|
4
|
+
catalogmx/calculators/__init__.py,sha256=3jwa0siSrqiTpwQakafa15Lv10LE7tABpTPIeLLyGPI,2746
|
|
5
|
+
catalogmx/calculators/costo_trabajador.py,sha256=RNh97zl_jUKjaVtACuB-88GSz9ZW1efWYAITwXDUMa8,6238
|
|
6
|
+
catalogmx/calculators/impuestos.py,sha256=ymOIg-j9NzhHwbVa6xpayr2o0XO-2uZ5jAcEQWod7Y0,25777
|
|
7
|
+
catalogmx/calculators/imss.py,sha256=68UJFCKYxy9qk6ARu0ErWvuEfOQDaVupj1QLewk7elU,11481
|
|
8
|
+
catalogmx/calculators/isr.py,sha256=_5Sz5MzXYeyFP95V4tyMuEU0Vr4Y2UwTOuOnroJq9Ko,8177
|
|
9
|
+
catalogmx/calculators/resico.py,sha256=1gtxlP2JnCaZnBCd6Zxi1wDb8NAc41FjlrHfFR3KL-0,4439
|
|
4
10
|
catalogmx/catalogs/__init__.py,sha256=lOixEi9iR3ofgd6Z7G-j5ui06JN_sThLFbBR0zfypvg,117
|
|
5
|
-
catalogmx/catalogs/banxico/__init__.py,sha256=
|
|
11
|
+
catalogmx/catalogs/banxico/__init__.py,sha256=Nm4UsQBu5T2hqEvJeZBBZSiF1vlVwwDgUyaBqNXMu2w,1587
|
|
6
12
|
catalogmx/catalogs/banxico/banks.py,sha256=7s063MxLExU2xy5ERtiQJTryta3xsZX_MGCNC1iY5ik,4068
|
|
13
|
+
catalogmx/catalogs/banxico/cetes_sqlite.py,sha256=kXKLjIuwqwzfKpl4o0CsdD9LOOGa43JsPzBD7IgXx-o,8469
|
|
7
14
|
catalogmx/catalogs/banxico/codigos_plaza.py,sha256=b9rjWRdojSLQlKZ83Sj1cSwpvq4c2x8Pg80Lbl-g_Mk,9080
|
|
15
|
+
catalogmx/catalogs/banxico/inflacion_sqlite.py,sha256=Uc9ipktFB1SlYkVkXB96qJIp3SBnHbTN3Kd5oqyFZE4,8849
|
|
8
16
|
catalogmx/catalogs/banxico/instituciones_financieras.py,sha256=eUejaPUvvJJ3SB0desB_5ABj49jxtr2GuRZLOy7PLvk,10832
|
|
9
17
|
catalogmx/catalogs/banxico/monedas_divisas.py,sha256=1IjzAg-QuRH0e7G0cuy0TLnL5979xl7I3hmHoqaSqg0,12097
|
|
10
|
-
catalogmx/catalogs/banxico/
|
|
11
|
-
catalogmx/catalogs/
|
|
12
|
-
catalogmx/catalogs/
|
|
18
|
+
catalogmx/catalogs/banxico/salarios_minimos_sqlite.py,sha256=ODNx98gZeXfXPWXhCSwhVbTVHCmNESA0mcpSBH2Vaoo,8946
|
|
19
|
+
catalogmx/catalogs/banxico/tiie_sqlite.py,sha256=8-UWtH7yyii1ilmAGBfH9hDwp_C2MEeQy_5HJhDqA5w,8392
|
|
20
|
+
catalogmx/catalogs/banxico/tipo_cambio_usd_sqlite.py,sha256=v4Yy43UYTltxnAFrh7e0fc3QdqP0B4f8JJ2LMVmoPro,7432
|
|
21
|
+
catalogmx/catalogs/banxico/udis_sqlite.py,sha256=pIGJZhF5YoqV0bH7GF9I-90A1VdlYiXyiM_BF0ROmGE,9565
|
|
22
|
+
catalogmx/catalogs/cnbv/__init__.py,sha256=iBybd9iDaO7GTbfUpQLxfBwtiAY6QbkNTlAly_7yOuk,218
|
|
23
|
+
catalogmx/catalogs/cnbv/sectores.py,sha256=EszqASLQvVE2H06gPPZypjAMgHeitMedr2NQ1NHHVT0,4913
|
|
24
|
+
catalogmx/catalogs/conapo/__init__.py,sha256=cQ2JmPz1KNxFceAs-PUWe9j75Fp8bb6tYT8_K8H-Bdo,459
|
|
25
|
+
catalogmx/catalogs/conapo/sistema_urbano_nacional.py,sha256=3_wH-fv9_9p2DoLHx7Mcld7978n21RaKUWPGC9UEJ3Q,1433
|
|
26
|
+
catalogmx/catalogs/conapo/zonas_metropolitanas.py,sha256=vUFDxm3ASf_3vLZ5m0ORkzvAclShwy6UU5WQgbbjo34,7529
|
|
27
|
+
catalogmx/catalogs/ift/__init__.py,sha256=vQcaJEfce4uY9MmdWYJUHQM0TqnpZbTnE0_biF4p1XY,409
|
|
28
|
+
catalogmx/catalogs/ift/codigos_lada.py,sha256=Bx18OyaXy5e08homQTORw-rGmDZ4GV2Ub3tYGyGUT00,23052
|
|
13
29
|
catalogmx/catalogs/ift/operadores_moviles.py,sha256=sax0cmKtqkoQADmizIfQr60iZjHGixsdIVjmXdat3r0,10210
|
|
14
|
-
catalogmx/catalogs/inegi/__init__.py,sha256=
|
|
30
|
+
catalogmx/catalogs/inegi/__init__.py,sha256=sLX0v3u4TTL9LPvR-1bjwTHYMv4ZhXFFuAcf5qR6zGU,944
|
|
15
31
|
catalogmx/catalogs/inegi/localidades.py,sha256=7v4_BA2qvZZnA7M67YOLvI9ghJZq410uTiixNFuq15I,6662
|
|
16
32
|
catalogmx/catalogs/inegi/municipios.py,sha256=sFCd2sqvpOBgaTamam5CPmPNNxrWJnGIqsXWbYpkeL8,2573
|
|
17
33
|
catalogmx/catalogs/inegi/municipios_completo.py,sha256=q4rGNgkNX4rm6IiqDXZ52p6yiJsXZBPgeu-id_TEAFw,7343
|
|
34
|
+
catalogmx/catalogs/inegi/scian.py,sha256=-eyTqu1dEKUrncJP3amtU8zUXv2QScDBMydXLGxaII4,3847
|
|
18
35
|
catalogmx/catalogs/inegi/states.py,sha256=Tpce0xyHUmdWqY1_onTLyX7fAU3OpM5EPiIrcPVH2Sw,4560
|
|
19
|
-
catalogmx/catalogs/mexico/__init__.py,sha256=
|
|
36
|
+
catalogmx/catalogs/mexico/__init__.py,sha256=KSjPGA1lpLfT0S1zIpQrxjNFlLYNTSCe4WlXTPr_Rkk,473
|
|
37
|
+
catalogmx/catalogs/mexico/giros_mercantiles.py,sha256=Cb261urght3AYX1WUYBUvl6o4KRD0cXyBYoXcYTyusQ,3576
|
|
20
38
|
catalogmx/catalogs/mexico/hoy_no_circula.py,sha256=lRJX6iluJX-AsBb5n-brBkhNuUk72JLx9paZ4QtWrI4,6972
|
|
21
39
|
catalogmx/catalogs/mexico/placas_formatos.py,sha256=4HQY_yE0Bzc3KcqLS3_2GXXkvCxeA3TbHxuazDzo6d0,5180
|
|
22
40
|
catalogmx/catalogs/mexico/salarios_minimos.py,sha256=JPIy0zIjwACk6pshb2hIYIZa9BvO0otJ0IxtblN9Czo,4222
|
|
@@ -26,12 +44,12 @@ catalogmx/catalogs/sat/carta_porte/__init__.py,sha256=lrgRduA0SQYpR7LmhY7kkOCJq9
|
|
|
26
44
|
catalogmx/catalogs/sat/carta_porte/aeropuertos.py,sha256=VGDKHuOfRtKQXmvFGilA-Lrwz232s81eg-NkrPx6I8Q,2504
|
|
27
45
|
catalogmx/catalogs/sat/carta_porte/carreteras.py,sha256=sHxCr7TpkAJAgZVEt1gpk_JApQEZkp3a52VlA8KEweE,1805
|
|
28
46
|
catalogmx/catalogs/sat/carta_porte/config_autotransporte.py,sha256=gp_o0Cmw0PxKjAgHYwsbb_iuNofwimuXFyh5K-xO5Cg,1822
|
|
29
|
-
catalogmx/catalogs/sat/carta_porte/material_peligroso.py,sha256=
|
|
47
|
+
catalogmx/catalogs/sat/carta_porte/material_peligroso.py,sha256=G2I2PBxoc1YMBHDTJwnwhPx8_oLpKv6SQUv-wx414IQ,2504
|
|
30
48
|
catalogmx/catalogs/sat/carta_porte/puertos_maritimos.py,sha256=0Rw6PLdyAnm9Gtjc5hscFSqlgAP0oy6cN_y6nfRj-5Y,2115
|
|
31
49
|
catalogmx/catalogs/sat/carta_porte/tipo_embalaje.py,sha256=H4jKa9XBQEQoPqtCjeP8aJkBtNnEvdRun-1yUP6lr1s,1565
|
|
32
50
|
catalogmx/catalogs/sat/carta_porte/tipo_permiso.py,sha256=q38yYE8L-WYGsZ-zhujVuSaXq8uDnn7ona3uL_Lb7WI,1744
|
|
33
51
|
catalogmx/catalogs/sat/cfdi_4/__init__.py,sha256=sIUKqRKnv7zI737mKmfontkqJ2qi7qJhl2g9UFv3khc,1308
|
|
34
|
-
catalogmx/catalogs/sat/cfdi_4/clave_prod_serv.py,sha256=
|
|
52
|
+
catalogmx/catalogs/sat/cfdi_4/clave_prod_serv.py,sha256=M46cTqikjvqnZyun5dXcUqzs8i_NzRWUV8NtJoDfTUI,15686
|
|
35
53
|
catalogmx/catalogs/sat/cfdi_4/clave_unidad.py,sha256=-_vXnHh6bA5VYbMsp702ranmU_ix9_FL2euuP54erW4,8839
|
|
36
54
|
catalogmx/catalogs/sat/cfdi_4/exportacion.py,sha256=epYTPzM1m_-aG_p7ZhZWZx5k6pHxCkABVnKP6DfeOMc,1451
|
|
37
55
|
catalogmx/catalogs/sat/cfdi_4/forma_pago.py,sha256=GcwZodx7gykWiASOTVnnPyQTFtrpH89xSc0mEG_RBcs,1444
|
|
@@ -41,7 +59,7 @@ catalogmx/catalogs/sat/cfdi_4/metodo_pago.py,sha256=z2TZxSfiiFEGElbBVQ8n7DOUYSWk
|
|
|
41
59
|
catalogmx/catalogs/sat/cfdi_4/objeto_imp.py,sha256=JpzAm0ijZBOB4RVaxz00G38f5073RrZHd7ELEA9YxCs,1441
|
|
42
60
|
catalogmx/catalogs/sat/cfdi_4/periodicidad.py,sha256=4Sm4DRX8IcU62H4KNNK_33EUVtjpRzQrF-RXph1JB3k,957
|
|
43
61
|
catalogmx/catalogs/sat/cfdi_4/regimen_fiscal.py,sha256=wihc2JpNgnZw5i5OC9EKInSWaTpDgOsIdUP2axLLlPI,1967
|
|
44
|
-
catalogmx/catalogs/sat/cfdi_4/tasa_o_cuota.py,sha256=
|
|
62
|
+
catalogmx/catalogs/sat/cfdi_4/tasa_o_cuota.py,sha256=kS5JVi5TcmG7RumOvqZ3X-6Jm1bqbVD4-L6B_p1WEU4,1394
|
|
45
63
|
catalogmx/catalogs/sat/cfdi_4/tipo_comprobante.py,sha256=yI0JwLvo_JR6yZueBHwywgqWj6SQZkup22uaSiCHzKo,1481
|
|
46
64
|
catalogmx/catalogs/sat/cfdi_4/tipo_factor.py,sha256=5tAgZwDwZLOuacwEpnMGntQGbPGu4XCNbimmpDUuKkU,955
|
|
47
65
|
catalogmx/catalogs/sat/cfdi_4/tipo_relacion.py,sha256=ROV6QeXDe0j9MrSua1jPXooYbXSKabXaXtxiUwCgMWY,1453
|
|
@@ -64,18 +82,26 @@ catalogmx/catalogs/sat/nomina/tipo_contrato.py,sha256=lG7GWG_SiJtmwqewG7DUg4LYdI
|
|
|
64
82
|
catalogmx/catalogs/sat/nomina/tipo_jornada.py,sha256=TxNmAx_ce1DzragO2cdeYGlYWAJI9sQYLNyS8fCXOb8,1302
|
|
65
83
|
catalogmx/catalogs/sat/nomina/tipo_nomina.py,sha256=pcGwl2w3F8Fa1mO6raIM7IFOBZm_l5IOOYJP-_s1ty4,1584
|
|
66
84
|
catalogmx/catalogs/sat/nomina/tipo_regimen.py,sha256=TmXsWEbKmV2MO9WxVEkplmEU_SPakl5hu9W3sbEa9po,1507
|
|
67
|
-
catalogmx/catalogs/sepomex/__init__.py,sha256=
|
|
68
|
-
catalogmx/catalogs/sepomex/codigos_postales.py,sha256=
|
|
69
|
-
catalogmx/
|
|
85
|
+
catalogmx/catalogs/sepomex/__init__.py,sha256=xaUJvLLPyxN5daKb8Kq97ti7YJENClairwKRTocJDs8,193
|
|
86
|
+
catalogmx/catalogs/sepomex/codigos_postales.py,sha256=bqHsy1klB6CSu2LELRsBuHdhaEcfyh8gxd_bLIK4LFY,7833
|
|
87
|
+
catalogmx/catalogs/sepomex/codigos_postales_completo.py,sha256=9vdEWZKJge2BInz1g8DKB4gtD9ur5tGqYGwo2QdS5sI,9469
|
|
88
|
+
catalogmx/data/__init__.py,sha256=aI9gdbq7Qrgn7yiLRO2EbtXOBBUvK5SRrnbWRnj9wf0,277
|
|
89
|
+
catalogmx/data/mexico_dynamic.sqlite3,sha256=-y1_7prW_5QMkCM__FenhjkhEWKIGkZ-2uVbpCGkptc,6762496
|
|
90
|
+
catalogmx/data/updater.py,sha256=YQMCM6TdLa6REJ9YsD_L3QCU8Lp4uNjoW0V5P3717c8,11472
|
|
91
|
+
catalogmx/generators/__init__.py,sha256=uGQ10j85bs1_wNj4NQhMaQlpYZqYMq9M3bE9XbM9AbY,457
|
|
92
|
+
catalogmx/generators/identity.py,sha256=a25klKIwYWvp6pBF6hQR2uHoqL6WsA3FtoEGUROYgF8,19191
|
|
93
|
+
catalogmx/utils/__init__.py,sha256=eY5YHuDQG_g-l3zfG1l9Dr6EPn1TH-IMJtVrU43eMTE,605
|
|
94
|
+
catalogmx/utils/clabe_utils.py,sha256=lR5-4AQIG1D-k14UqD0H8_c1Drm3gv_6OqnuCfsFTAo,11240
|
|
95
|
+
catalogmx/utils/text.py,sha256=O8cfR5pwF1VYAimE5pRzZIyMs1PoA7j1pT1crUnus28,1570
|
|
70
96
|
catalogmx/validators/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
71
|
-
catalogmx/validators/clabe.py,sha256=
|
|
97
|
+
catalogmx/validators/clabe.py,sha256=oPs9kTOzlBxGFHy859qW24_C8Q_xMpaQ2dEHAakPoQY,8272
|
|
72
98
|
catalogmx/validators/curp.py,sha256=Hy6UJ_XohrKHDrcISGtnD_2XStNDOiK6-IpSkB6hYck,17220
|
|
73
|
-
catalogmx/validators/nss.py,sha256=
|
|
74
|
-
catalogmx/validators/rfc.py,sha256=
|
|
75
|
-
catalogmx-0.
|
|
76
|
-
catalogmx-0.
|
|
77
|
-
catalogmx-0.
|
|
78
|
-
catalogmx-0.
|
|
79
|
-
catalogmx-0.
|
|
80
|
-
catalogmx-0.
|
|
81
|
-
catalogmx-0.
|
|
99
|
+
catalogmx/validators/nss.py,sha256=reaiLnNncPdpPSr2cIW9bBplX4bt2wQgWhpWpDAsFHY,7640
|
|
100
|
+
catalogmx/validators/rfc.py,sha256=MKDLHsxqshI2MzRGhJD9I0qSgJaiJJfjPcj98tznD1g,36542
|
|
101
|
+
catalogmx-0.4.0.dist-info/licenses/AUTHORS.rst,sha256=0XQqnkH78uPwLaYC7Sf34uMvZQHC3JGuBVwem8XsCGg,75
|
|
102
|
+
catalogmx-0.4.0.dist-info/licenses/LICENSE,sha256=xQwocZIiQcPikSKuOi2Uqyw0eQgccjNh7RIBGQhiimc,1300
|
|
103
|
+
catalogmx-0.4.0.dist-info/METADATA,sha256=xP7VL6nIAQabWmGZWyeojsCYJrY4_GdfFEYQJI7f2sg,27651
|
|
104
|
+
catalogmx-0.4.0.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
105
|
+
catalogmx-0.4.0.dist-info/entry_points.txt,sha256=7cW_4Nx5UQ_JBIQ7ZqeOJSEZTErNS7sKzzsTg99y2J4,49
|
|
106
|
+
catalogmx-0.4.0.dist-info/top_level.txt,sha256=FZZG1iK2df2CwDM2iq_RdlMVuBtOfsVTWDzUcTbzAY0,10
|
|
107
|
+
catalogmx-0.4.0.dist-info/RECORD,,
|
|
@@ -1,279 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
UDI (Unidades de Inversión) Catalog
|
|
3
|
-
|
|
4
|
-
This module provides access to UDI values from Banco de México.
|
|
5
|
-
UDIs are inflation-indexed investment units used in Mexico.
|
|
6
|
-
"""
|
|
7
|
-
|
|
8
|
-
import json
|
|
9
|
-
from datetime import datetime
|
|
10
|
-
from pathlib import Path
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
class UDICatalog:
|
|
14
|
-
"""
|
|
15
|
-
Catalog of UDI (Unidades de Inversión) values
|
|
16
|
-
|
|
17
|
-
UDIs are inflation-indexed investment units maintained by Banco de México.
|
|
18
|
-
They are commonly used for mortgage loans and other long-term financial obligations.
|
|
19
|
-
"""
|
|
20
|
-
|
|
21
|
-
_data: list[dict] | None = None
|
|
22
|
-
_by_fecha: dict[str, dict] | None = None
|
|
23
|
-
_mensual: dict[str, dict] | None = None
|
|
24
|
-
_anual: dict[int, dict] | None = None
|
|
25
|
-
_daily: list[dict] | None = None
|
|
26
|
-
|
|
27
|
-
@classmethod
|
|
28
|
-
def _load_data(cls) -> None:
|
|
29
|
-
"""Load UDI data from JSON file"""
|
|
30
|
-
if cls._data is None:
|
|
31
|
-
# Path: catalogmx/packages/python/catalogmx/catalogs/banxico/udis.py
|
|
32
|
-
# Target: catalogmx/packages/shared-data/banxico/udis.json
|
|
33
|
-
current_file = Path(__file__)
|
|
34
|
-
shared_data_path = (
|
|
35
|
-
current_file.parent.parent.parent.parent.parent
|
|
36
|
-
/ "shared-data"
|
|
37
|
-
/ "banxico"
|
|
38
|
-
/ "udis.json"
|
|
39
|
-
)
|
|
40
|
-
|
|
41
|
-
with open(shared_data_path, encoding="utf-8") as f:
|
|
42
|
-
cls._data = json.load(f)
|
|
43
|
-
|
|
44
|
-
if cls._by_fecha is not None:
|
|
45
|
-
return
|
|
46
|
-
|
|
47
|
-
cls._by_fecha = {}
|
|
48
|
-
cls._mensual = {}
|
|
49
|
-
cls._anual = {}
|
|
50
|
-
daily: list[dict] = []
|
|
51
|
-
|
|
52
|
-
for record in cls._data:
|
|
53
|
-
fecha = record.get("fecha")
|
|
54
|
-
if not fecha:
|
|
55
|
-
continue
|
|
56
|
-
|
|
57
|
-
existing = cls._by_fecha.get(fecha)
|
|
58
|
-
if existing is None or (
|
|
59
|
-
record.get("tipo") == "diario" and existing.get("tipo") != "diario"
|
|
60
|
-
):
|
|
61
|
-
cls._by_fecha[fecha] = record
|
|
62
|
-
|
|
63
|
-
if record.get("tipo") == "diario":
|
|
64
|
-
daily.append(record)
|
|
65
|
-
elif record.get("tipo") == "promedio_mensual":
|
|
66
|
-
key = f"{record.get('año')}-{int(record.get('mes', 0)):02d}"
|
|
67
|
-
cls._mensual[key] = record
|
|
68
|
-
elif record.get("tipo") == "promedio_anual":
|
|
69
|
-
cls._anual[int(record.get("año"))] = record
|
|
70
|
-
|
|
71
|
-
daily.sort(key=lambda r: r["fecha"])
|
|
72
|
-
cls._daily = daily
|
|
73
|
-
|
|
74
|
-
@classmethod
|
|
75
|
-
def get_data(cls) -> list[dict]:
|
|
76
|
-
"""
|
|
77
|
-
Get all UDI data
|
|
78
|
-
|
|
79
|
-
:return: List of all UDI records
|
|
80
|
-
"""
|
|
81
|
-
cls._load_data()
|
|
82
|
-
return cls._data.copy()
|
|
83
|
-
|
|
84
|
-
@classmethod
|
|
85
|
-
def _get_by_fecha(cls, fecha: str) -> dict | None:
|
|
86
|
-
cls._load_data()
|
|
87
|
-
record = cls._by_fecha.get(fecha)
|
|
88
|
-
if record:
|
|
89
|
-
return record
|
|
90
|
-
|
|
91
|
-
try:
|
|
92
|
-
anio, mes, _dia = fecha.split("-")
|
|
93
|
-
mensual = cls._mensual.get(f"{int(anio)}-{int(mes):02d}") if cls._mensual else None
|
|
94
|
-
return mensual
|
|
95
|
-
except ValueError:
|
|
96
|
-
return None
|
|
97
|
-
|
|
98
|
-
@classmethod
|
|
99
|
-
def get_por_fecha(cls, fecha: str) -> dict | None:
|
|
100
|
-
"""
|
|
101
|
-
Get UDI value for a specific date
|
|
102
|
-
|
|
103
|
-
:param fecha: Date string in YYYY-MM-DD format
|
|
104
|
-
:return: UDI record or None if not found
|
|
105
|
-
"""
|
|
106
|
-
record = cls._get_by_fecha(fecha)
|
|
107
|
-
return record.copy() if record else None
|
|
108
|
-
|
|
109
|
-
@classmethod
|
|
110
|
-
def get_por_mes(cls, anio: int, mes: int) -> dict | None:
|
|
111
|
-
"""
|
|
112
|
-
Get monthly average UDI value
|
|
113
|
-
|
|
114
|
-
:param anio: Year (e.g., 2024)
|
|
115
|
-
:param mes: Month (1-12)
|
|
116
|
-
:return: UDI record with monthly average or None if not found
|
|
117
|
-
"""
|
|
118
|
-
cls._load_data()
|
|
119
|
-
key = f"{anio}-{mes:02d}"
|
|
120
|
-
record = cls._mensual.get(key) if cls._mensual else None
|
|
121
|
-
return record.copy() if record else None
|
|
122
|
-
|
|
123
|
-
@classmethod
|
|
124
|
-
def get_promedio_anual(cls, anio: int) -> dict | None:
|
|
125
|
-
"""
|
|
126
|
-
Get annual average UDI value
|
|
127
|
-
|
|
128
|
-
:param anio: Year (e.g., 2024)
|
|
129
|
-
:return: UDI record with annual average or None if not found
|
|
130
|
-
"""
|
|
131
|
-
cls._load_data()
|
|
132
|
-
|
|
133
|
-
record = cls._anual.get(anio) if cls._anual else None
|
|
134
|
-
return record.copy() if record else None
|
|
135
|
-
|
|
136
|
-
@classmethod
|
|
137
|
-
def get_por_anio(cls, anio: int) -> list[dict]:
|
|
138
|
-
"""Return the daily UDI series for a given year."""
|
|
139
|
-
cls._load_data()
|
|
140
|
-
|
|
141
|
-
source = (
|
|
142
|
-
cls._daily
|
|
143
|
-
if cls._daily
|
|
144
|
-
else [r for r in cls._data if r.get("tipo") == "promedio_mensual"]
|
|
145
|
-
)
|
|
146
|
-
return [record.copy() for record in source if record.get("año") == anio]
|
|
147
|
-
|
|
148
|
-
@classmethod
|
|
149
|
-
def get_actual(cls) -> dict | None:
|
|
150
|
-
"""
|
|
151
|
-
Get most recent UDI value
|
|
152
|
-
|
|
153
|
-
:return: Latest UDI record
|
|
154
|
-
"""
|
|
155
|
-
cls._load_data()
|
|
156
|
-
|
|
157
|
-
if cls._daily:
|
|
158
|
-
return cls._daily[-1].copy()
|
|
159
|
-
|
|
160
|
-
if not cls._data:
|
|
161
|
-
return None
|
|
162
|
-
|
|
163
|
-
record = max(cls._data, key=lambda r: r.get("fecha", ""), default=None)
|
|
164
|
-
return record.copy() if record else None
|
|
165
|
-
|
|
166
|
-
@classmethod
|
|
167
|
-
def _get_valor_cercano(cls, fecha: str) -> dict | None:
|
|
168
|
-
cls._load_data()
|
|
169
|
-
objetivo = datetime.fromisoformat(fecha)
|
|
170
|
-
|
|
171
|
-
candidatos = (
|
|
172
|
-
cls._daily
|
|
173
|
-
if cls._daily
|
|
174
|
-
else [r for r in cls._data if r.get("tipo") == "promedio_mensual"]
|
|
175
|
-
)
|
|
176
|
-
if not candidatos:
|
|
177
|
-
return None
|
|
178
|
-
|
|
179
|
-
def _diff(record: dict) -> float:
|
|
180
|
-
return abs((datetime.fromisoformat(record["fecha"]) - objetivo).total_seconds())
|
|
181
|
-
|
|
182
|
-
return min(candidatos, key=_diff)
|
|
183
|
-
|
|
184
|
-
@classmethod
|
|
185
|
-
def pesos_a_udis(cls, pesos: float, fecha: str) -> float | None:
|
|
186
|
-
"""
|
|
187
|
-
Convert Mexican pesos to UDIs
|
|
188
|
-
|
|
189
|
-
:param pesos: Amount in Mexican pesos
|
|
190
|
-
:param fecha: Date string in YYYY-MM-DD format
|
|
191
|
-
:return: Amount in UDIs or None if UDI value not found
|
|
192
|
-
"""
|
|
193
|
-
record = cls.get_por_fecha(fecha)
|
|
194
|
-
if not record:
|
|
195
|
-
record = cls._get_valor_cercano(fecha)
|
|
196
|
-
if not record:
|
|
197
|
-
return None
|
|
198
|
-
|
|
199
|
-
valor_udi = record.get("valor")
|
|
200
|
-
if not valor_udi:
|
|
201
|
-
return None
|
|
202
|
-
|
|
203
|
-
return pesos / valor_udi
|
|
204
|
-
|
|
205
|
-
@classmethod
|
|
206
|
-
def udis_a_pesos(cls, udis: float, fecha: str) -> float | None:
|
|
207
|
-
"""
|
|
208
|
-
Convert UDIs to Mexican pesos
|
|
209
|
-
|
|
210
|
-
:param udis: Amount in UDIs
|
|
211
|
-
:param fecha: Date string in YYYY-MM-DD format
|
|
212
|
-
:return: Amount in Mexican pesos or None if UDI value not found
|
|
213
|
-
"""
|
|
214
|
-
record = cls.get_por_fecha(fecha)
|
|
215
|
-
if not record:
|
|
216
|
-
record = cls._get_valor_cercano(fecha)
|
|
217
|
-
if not record:
|
|
218
|
-
return None
|
|
219
|
-
|
|
220
|
-
valor_udi = record.get("valor")
|
|
221
|
-
if not valor_udi:
|
|
222
|
-
return None
|
|
223
|
-
|
|
224
|
-
return udis * valor_udi
|
|
225
|
-
|
|
226
|
-
@classmethod
|
|
227
|
-
def calcular_variacion(cls, fecha_inicio: str, fecha_fin: str) -> float | None:
|
|
228
|
-
"""
|
|
229
|
-
Calculate percentage variation between two dates
|
|
230
|
-
|
|
231
|
-
:param fecha_inicio: Start date (YYYY-MM-DD)
|
|
232
|
-
:param fecha_fin: End date (YYYY-MM-DD)
|
|
233
|
-
:return: Percentage variation or None if values not found
|
|
234
|
-
"""
|
|
235
|
-
record_inicio = cls.get_por_fecha(fecha_inicio) or cls._get_valor_cercano(fecha_inicio)
|
|
236
|
-
record_fin = cls.get_por_fecha(fecha_fin) or cls._get_valor_cercano(fecha_fin)
|
|
237
|
-
|
|
238
|
-
if not record_inicio or not record_fin:
|
|
239
|
-
return None
|
|
240
|
-
|
|
241
|
-
valor_inicio = record_inicio.get("valor")
|
|
242
|
-
valor_fin = record_fin.get("valor")
|
|
243
|
-
|
|
244
|
-
if not valor_inicio or not valor_fin:
|
|
245
|
-
return None
|
|
246
|
-
|
|
247
|
-
return ((valor_fin - valor_inicio) / valor_inicio) * 100
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
# Convenience functions
|
|
251
|
-
def get_udi_actual() -> dict | None:
|
|
252
|
-
"""Get most recent UDI value"""
|
|
253
|
-
record = UDICatalog.get_actual()
|
|
254
|
-
return record.copy() if record else None
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
def get_udi_por_fecha(fecha: str) -> dict | None:
|
|
258
|
-
"""Get UDI value for a specific date"""
|
|
259
|
-
return UDICatalog.get_por_fecha(fecha)
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
def pesos_a_udis(pesos: float, fecha: str) -> float | None:
|
|
263
|
-
"""Convert pesos to UDIs"""
|
|
264
|
-
return UDICatalog.pesos_a_udis(pesos, fecha)
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
def udis_a_pesos(udis: float, fecha: str) -> float | None:
|
|
268
|
-
"""Convert UDIs to pesos"""
|
|
269
|
-
return UDICatalog.udis_a_pesos(udis, fecha)
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
# Export commonly used functions and classes
|
|
273
|
-
__all__ = [
|
|
274
|
-
"UDICatalog",
|
|
275
|
-
"get_udi_actual",
|
|
276
|
-
"get_udi_por_fecha",
|
|
277
|
-
"pesos_a_udis",
|
|
278
|
-
"udis_a_pesos",
|
|
279
|
-
]
|