Sr Magnate

38.6K posts

Sr Magnate

Sr Magnate

@maherraizz

Yo ya no soy político y puedo decir la verdad

انضم Mart 2010
961 يتبع674 المتابعون
Sr Magnate أُعيد تغريده
Bruno Pérez Vázquez
Bruno Pérez Vázquez@bpvazquez·
Hoy en @abc_es entrevistamos a uno de los personajes del momento: @Jongonzlz Hablamos de sus célebres gráficas, de sus motivaciones, de la contaminación del debate público...Un puñado de reflexiones interesantes que no os deberíais perder #edtn=nacional&vca=fixed-btn&vso=rrss&vmc=tw&vli=economia" target="_blank" rel="nofollow noopener">abc.es/economia/jon-g… vía @ABCeconomia
Español
9
93
281
20.9K
Sr Magnate أُعيد تغريده
Jon González
Jon González@Jongonzlz·
Ha llegado el momento. Hoy, a igualdad de salario real, todos los trabajadores pagan más IRPF que en 2019. No es una opinión: son los datos. La inflación ha empujado a millones de personas en España a pagar más sin ganar más en términos reales. Deflactar el IRPF no es una cuestión ideológica; es justicia fiscal, especialmente con las rentas medias-bajas. Partidos del @ppopular @vox_es @JuntsXCat @eajpnv_eu @coalicion @upn_navarra. Es la hora de olvidarse de las diferencias y unirse por un objetivo común para mejorar la vida de los españoles. Asociaciones @atenea_esp @UnivHesperides @juandemariana @InstitutOstrom @voceslibres_esp @CivismoF. Es el momento de empujar esta medida. Hay que pasar de la 'Proposición no de ley' a una 'Proposición de ley' en el Congreso que deflacte los parámetros del IRPF de forma razonable pero suficiente. Si el Gobierno se escuda en el artículo 134.6 CE para no negociarla, amenazar con una moción de censura. Tenéis los números.
Jon González tweet media
Español
50
1K
2.4K
79.7K
Sr Magnate أُعيد تغريده
Ketty Garat
Ketty Garat@KettyGarat·
EXCLUSIVA. Uno de los secretos mejor guardados que precedió a la carrera meteórica de Nadia Calviño: su padre, José María Calviño, financió la mitad de la campaña de primarias de Pedro Sánchez 👇👇👇 theobjective.com/espana/politic…
Español
554
4.9K
8.7K
170.6K
Sr Magnate أُعيد تغريده
Jon González
Jon González@Jongonzlz·
¿Cuántas visualizaciones podemos conseguir en España en un tuit en el que he pegado a lo bruto un chorro de lineas de código con cálculos de IRPF?
Jon González@Jongonzlz

Quiero DEMOCRATIZAR el conocimiento del cálculo del IRPF y del salario neto, y las implicaciones de la progresividad en frío entre 2012 y 2026. Pero necesito fiscalistas y economistas con ojo al detalle y techies. Quiero que los que sabéis de fiscalidad auditéis los resultados de mi código para cada año atendiendo al más mínimo detalle (yo he tratado de hacerlo), Que los techies me propongáis mejoras en el código y optimizaciones en las salidas, y quiero que, finalmente, los que tenéis capacidad de montar una web con ello, os coordinéis y lo hagáis. También quiero que extraigáis un manual sencillo para que la gente lo entienda a partir de los cálculos que se hacen en el código. Y que se expliquen las distintas normativas y cómo impactaron. A TRABAJAR. GO GO GO! @Gsnchez @XMihura @Inspectores_IHE @frdelatorre @Jaume_Vinas @SantiCalvo_Eco Ahí va el código! import pandas as pd import numpy as np # ============================================================================= # 1. MÓDULO MACROECONÓMICO: INFLACIÓN ACUMULADA (DICIEMBRE A DICIEMBRE) # ============================================================================= IPC_ANUAL_DIC = { 2013: 0.003, 2014: -0.010, 2015: 0.000, 2016: 0.016, 2017: 0.011, 2018: 0.012, 2019: 0.008, 2020: -0.005, 2021: 0.065, 2022: 0.057, 2023: 0.031, 2024: 0.028, 2025: 0.029, 2026: 0.030 } def obtener_inflacion_acumulada(anio_base, anio_destino=2026): if anio_base == anio_destino: return 1.0 multiplicador = 1.0 for anio in range(anio_base + 1, anio_destino + 1): multiplicador *= (1 + IPC_ANUAL_DIC[anio]) return multiplicador INFLACION_A_2026 = {anio: obtener_inflacion_acumulada(anio, 2026) for anio in range(2012, 2027)} # ============================================================================= # 2. NORMATIVA FISCAL Y LABORAL (IRPF Y SS) # ============================================================================= def obtener_parametros(anio): p = {} # Bases y Tipos Generales SS p['base_max'] = { 2012: 39150.0, 2013: 41108.4, 2014: 43164.0, 2015: 43272.0, 2016: 43704.0, 2017: 45014.4, 2018: 45014.4, 2019: 48841.2, 2020: 48841.2, 2021: 48841.2, 2022: 49672.8, 2023: 53946.0, 2024: 56646.0, 2025: 58914.0, 2026: 61214.4 }[anio] p['ss_tipos'] = { 'comunes': [0.236, 0.047], 'desempleo': [0.055, 0.0155], 'fogasa': [0.002, 0.0], 'fp': [0.006, 0.001], 'atep': [0.015, 0.0] } # MEI y Solidaridad if anio == 2023: p['mei'] = [0.005, 0.001] elif anio == 2024: p['mei'] = [0.0058, 0.0012] elif anio == 2025: p['mei'] = [0.0067, 0.0013] elif anio >= 2026: p['mei'] = [0.0075, 0.0015] else: p['mei'] = [0.0, 0.0] if anio == 2025: p['solidaridad'] = [(1.10, 0.0092), (1.50, 0.0100), (float('inf'), 0.0117)] elif anio >= 2026: p['solidaridad'] = [(1.10, 0.0115), (1.50, 0.0125), (float('inf'), 0.0146)] else: p['solidaridad'] = [] # Mínimos y Gastos p['irpf_minimo'] = 5151 if anio <= 2014 else 5550 p['minimo_exento'] = { 2012: 11162, 2013: 11162, 2014: 11162, 2015: 12000, 2016: 12000, 2017: 12000, 2018: 12643, 2019: 14000, 2020: 14000, 2021: 14000, 2022: 14000, 2023: 15000, 2024: 15876, 2025: 15876, 2026: 15876 }[anio] p['gastos_fijos'] = 0 if anio <= 2014 else 2000 # Reducción Art 20 (y Metadatos para control) def get_art20_params(a): if a <= 2014: return {"U_Inf": 9180, "R_Max": 4080, "U_Sup": 13260, "R_Min": 2652} elif 2015 <= a <= 2017: return {"U_Inf": 11250, "R_Max": 3700, "U_Sup": 14450, "R_Min": 0} elif a == 2018: return {"U_Inf": "Transitorio", "R_Max": "Transitorio", "U_Sup": "Transitorio", "R_Min": "Transitorio"} elif 2019 <= a <= 2022: return {"U_Inf": 13115, "R_Max": 5565, "U_Sup": 16825, "R_Min": 0} elif a == 2023: return {"U_Inf": 14047.5, "R_Max": 6498, "U_Sup": 19747.5, "R_Min": 0} else: return {"U_Inf": 14852, "R_Max": 7302, "U_Sup": 19747.5, "R_Min": 0} p['art20_meta'] = get_art20_params(anio) def reduccion_trabajo(rn_previo): if anio <= 2014: if rn_previo <= 9180: return 4080.0 elif rn_previo <= 13260: return 4080.0 - 0.35 * (rn_previo - 9180.0) else: return 2652.0 elif 2015 <= anio <= 2017: if rn_previo <= 11250: return 3700.0 elif rn_previo <= 14450: return 3700.0 - 1.15625 * (rn_previo - 11250.0) else: return 0.0 elif anio == 2018: # Régimen Transitorio pre = 3700.0 if rn_previo <= 11250 else (3700.0 - 1.15625 * (rn_previo - 11250.0) if rn_previo <= 14450 else 0.0) post = 5565.0 if rn_previo <= 13115 else (max(0.0, 5565.0 - 1.5 * (rn_previo - 13115.0)) if rn_previo <= 16825 else 0.0) return (pre / 2.0) + (post / 2.0) elif 2019 <= anio <= 2022: if rn_previo <= 13115: return 5565.0 elif rn_previo <= 16825: return max(0.0, 5565.0 - 1.5 * (rn_previo - 13115.0)) else: return 0.0 elif anio == 2023: if rn_previo <= 14047.50: return 6498.0 elif rn_previo <= 19747.50: return max(0.0, 6498.0 - 1.14 * (rn_previo - 14047.50)) else: return 0.0 elif anio >= 2024: if rn_previo <= 14852: return 7302.0 elif rn_previo <= 17673.52: return 7302.0 - 1.75 * (rn_previo - 14852.0) elif rn_previo <= 19747.50: return 2364.34 - 1.14 * (rn_previo - 17673.52) else: return 0.0 return 0.0 p['reduccion_trabajo'] = reduccion_trabajo # Escalas IRPF if anio <= 2014: p['tramos_irpf'] = [(17707, 0.2475), (33007, 0.30), (53407, 0.40), (120000, 0.47), (175000, 0.49), (300000, 0.51), (float('inf'), 0.52)] elif anio == 2015: p['tramos_irpf'] = [(12450, 0.195), (20200, 0.245), (34000, 0.305), (60000, 0.38), (float('inf'), 0.46)] elif 2016 <= anio <= 2020: p['tramos_irpf'] = [(12450, 0.19), (20200, 0.24), (35200, 0.30), (60000, 0.37), (float('inf'), 0.45)] else: p['tramos_irpf'] = [(12450, 0.19), (20200, 0.24), (35200, 0.30), (60000, 0.37), (300000, 0.45), (float('inf'), 0.47)] # Deducción SMI def deduccion_smi(bruto): if anio == 2026: if bruto <= 17094: return 590.89 else: return max(0.0, 590.89 - 0.20 * (bruto - 17094.0)) elif anio == 2025: if bruto <= 16576: return 340.0 elif bruto <= 18276: return max(0, 340.0 - 0.20 * (bruto - 16576.0)) return 0.0 p['deduccion_smi'] = deduccion_smi return p # ============================================================================= # 3. GENERACIÓN DE HOJAS DE CONTROL DE PARÁMETROS # ============================================================================= def generar_hojas_control(): general = [] tramos_lista = [] for anio in range(2012, 2027): p = obtener_parametros(anio) tipo_emp = sum(x[0] for x in p['ss_tipos'].values()) tipo_tra = sum(x[1] for x in p['ss_tipos'].values()) general.append({ "Año": anio, "Base Máx. Anual": p['base_max'], "SS Empleador %": round(tipo_emp * 100, 2), "SS Empleado %": round(tipo_tra * 100, 2), "MEI Empleador %": round(p['mei'][0] * 100, 3), "MEI Empleado %": round(p['mei'][1] * 100, 3), "Gastos Fijos Art.19": p['gastos_fijos'], "Mín. Contribuyente": p['irpf_minimo'], "Mín. Exento Retención": p['minimo_exento'], "Art.20 Umbral Inf": p['art20_meta']['U_Inf'], "Art.20 Red. Máxima": p['art20_meta']['R_Max'], "Art.20 Umbral Sup": p['art20_meta']['U_Sup'], "Art.20 Red. Mínima": p['art20_meta']['R_Min'] }) for i, (lim, tip) in enumerate(p['tramos_irpf']): tramos_lista.append({ "Año": anio, "Nº Tramo": i + 1, "Hasta Base": lim if lim != float('inf') else "En adelante", "Tipo %": round(tip * 100, 2) }) return pd.DataFrame(general), pd.DataFrame(tramos_lista) # ============================================================================= # 4. MOTOR DETALLADO (PARA PESTAÑAS ANUALES DAT_YYYY) # ============================================================================= def calcular_cuotas_por_tramo(base_liq, tramos): cuotas_tramos = {f"T{i+1} ({round(tipo*100, 1)}%)": 0.0 for i, (_, tipo) in enumerate(tramos)} cuota_total = 0.0 if base_liq <= 0: return cuotas_tramos, cuota_total lim_ant = 0.0 for i, (lim, tipo) in enumerate(tramos): nombre = f"T{i+1} ({round(tipo*100, 1)}%)" if base_liq > lim: cuota = (lim - lim_ant) * tipo cuotas_tramos[nombre] = cuota cuota_total += cuota lim_ant = lim else: cuota = (base_liq - lim_ant) * tipo cuotas_tramos[nombre] = cuota cuota_total += cuota break return cuotas_tramos, cuota_total def procesar_ano(anio): p = obtener_parametros(anio) # Rango exhaustivo: 0 a 100.000€ de 1€ en 1€ salarios_brutos = np.arange(0, 100001, 1) resultados = [] for bruto in salarios_brutos: base_cotizacion = min(bruto, p['base_max']) exceso_base = max(0, bruto - p['base_max']) tipo_empresa = sum(x[0] for x in p['ss_tipos'].values()) + p['mei'][0] tipo_trabajador = sum(x[1] for x in p['ss_tipos'].values()) + p['mei'][1] cot_empresa = base_cotizacion * tipo_empresa cot_trabajador = base_cotizacion * tipo_trabajador if p['solidaridad'] and exceso_base > 0: tramo1_limite = p['base_max'] * 0.10 tramo2_limite = p['base_max'] * 0.50 exceso1 = min(exceso_base, tramo1_limite) exceso2 = min(max(0, exceso_base - tramo1_limite), tramo2_limite - tramo1_limite) exceso3 = max(0, exceso_base - tramo2_limite) cuota_sol_total = (exceso1 * p['solidaridad'][0][1]) + (exceso2 * p['solidaridad'][1][1]) + (exceso3 * p['solidaridad'][2][1]) cot_empresa += cuota_sol_total * (5/6) cot_trabajador += cuota_sol_total * (1/6) coste_laboral = bruto + cot_empresa rendimiento_previo_sin_fijos = bruto - cot_trabajador red_trabajo = p['reduccion_trabajo'](rendimiento_previo_sin_fijos) rendimiento_neto = max(0, rendimiento_previo_sin_fijos - p['gastos_fijos']) base_imponible = max(0, rendimiento_neto - red_trabajo) cuotas_tramos, cuota_integra = calcular_cuotas_por_tramo(base_imponible, p['tramos_irpf']) cuota_minimo = p['irpf_minimo'] * p['tramos_irpf'][0][1] cuota_teorica = max(0, cuota_integra - cuota_minimo) deduccion = p['deduccion_smi'](bruto) cuota_con_deduccion = max(0, cuota_teorica - deduccion) limite_retencion = max(0, (bruto - p['minimo_exento']) * 0.43) irpf_final = min(cuota_con_deduccion, limite_retencion) salario_neto = bruto - cot_trabajador - irpf_final fila = { "Salario Bruto": bruto, "Cot. Soc. Empresa": round(cot_empresa, 2), "Coste Laboral": round(coste_laboral, 2), "Cot. Soc. Trab.": round(cot_trabajador, 2), "Ren. Previo": round(rendimiento_previo_sin_fijos, 2), "Gastos Fijos": p['gastos_fijos'], "Red. Ren. Trab.": round(red_trabajo, 2), "Base Imponible": round(base_imponible, 2) } for k, v in cuotas_tramos.items(): fila[k] = round(v, 2) fila.update({ "Cuota Íntegra": round(cuota_integra, 2), "Cuota Mínimo Personal": round(cuota_minimo, 2), "Cuota Teórica": round(cuota_teorica, 2), "Deducción SMI": round(deduccion, 2), "Cuota tras SMI": round(cuota_con_deduccion, 2), "Límite 43% (Art 85.3)": round(limite_retencion, 2), "IRPF Final": round(irpf_final, 2), "Salario Neto": round(salario_neto, 2) }) resultados.append(fila) return pd.DataFrame(resultados) # ============================================================================= # 5. MOTOR RÁPIDO PARA COMPARATIVA INFLACIÓN # ============================================================================= def calcular_nomina_agregada(bruto, anio, p): base_cot = min(bruto, p['base_max']) exc_base = max(0, bruto - p['base_max']) t_emp = sum(x[0] for x in p['ss_tipos'].values()) + p['mei'][0] t_tra = sum(x[1] for x in p['ss_tipos'].values()) + p['mei'][1] cot_emp = base_cot * t_emp cot_tra = base_cot * t_tra if p['solidaridad'] and exc_base > 0: l1, l2 = p['base_max']*0.1, p['base_max']*0.5 e1, e2, e3 = min(exc_base, l1), min(max(0, exc_base-l1), l2-l1), max(0, exc_base-l2) q_sol = (e1*p['solidaridad'][0][1]) + (e2*p['solidaridad'][1][1]) + (e3*p['solidaridad'][2][1]) cot_emp += q_sol * (5/6); cot_tra += q_sol * (1/6) coste_lab = bruto + cot_emp rn_previo = bruto - cot_tra red20 = p['reduccion_trabajo'](rn_previo) base_imp = max(0, rn_previo - p['gastos_fijos'] - red20) q_integra = 0.0 lim_ant = 0.0 for lim, tipo in p['tramos_irpf']: if base_imp > lim: q_integra += (lim - lim_ant) * tipo lim_ant = lim else: q_integra += (base_imp - lim_ant) * tipo break q_min = p['irpf_minimo'] * p['tramos_irpf'][0][1] q_teorica = max(0, q_integra - q_min) q_smi = max(0, q_teorica - p['deduccion_smi'](bruto)) lim_ret = max(0, (bruto - p['minimo_exento']) * 0.43) irpf_final = min(q_smi, lim_ret) return coste_lab, cot_emp, cot_tra, irpf_final, bruto - cot_tra - irpf_final def generar_comparativa_inflacion(): # Análisis comparativo en saltos de 1.000€ salarios_2026 = np.arange(15000, 100001, 1000) p_2026 = obtener_parametros(2026) ref_2026 = {b: calcular_nomina_agregada(b, 2026, p_2026) for b in salarios_2026} resultados = [] for anio in range(2012, 2027): p_anio = obtener_parametros(anio) inf_acum = INFLACION_A_2026[anio] for bruto_26 in salarios_2026: bruto_nom = bruto_26 / inf_acum c_lab_n, c_emp_n, c_tra_n, irpf_n, neto_n = calcular_nomina_agregada(bruto_nom, anio, p_anio) c_lab_aj = c_lab_n * inf_acum c_emp_aj = c_emp_n * inf_acum c_tra_aj = c_tra_n * inf_acum irpf_aj = irpf_n * inf_acum neto_aj = neto_n * inf_acum neto_2026_real = ref_2026[bruto_26][4] dif_poder_adq = neto_aj - neto_2026_real resultados.append({ "Año a Comparar": anio, "Salario Equivalente (2026)": bruto_26, "Multiplicador IPC Acum.": round(inf_acum, 4), "IPC Acumulado (%)": f"{round((inf_acum - 1)*100, 2)}%", "Salario Bruto Nominal": round(bruto_nom, 2), "Coste Lab. (Euros 2026)": round(c_lab_aj, 2), "SS Emp. (Euros 2026)": round(c_emp_aj, 2), "SS Tra. (Euros 2026)": round(c_tra_aj, 2), "IRPF (Euros 2026)": round(irpf_aj, 2), "Neto Real en su Año": round(neto_aj, 2), "Neto Real en 2026": round(neto_2026_real, 2), "Variación Poder Adquisitivo Mensual vs 2026 (12 pagas)": round(dif_poder_adq / 12, 2), "Pérdida/Ganancia Anual Poder Adq.": round(dif_poder_adq, 2) }) return pd.DataFrame(resultados) # ============================================================================= # 6. EJECUCIÓN MAESTRA Y GENERACIÓN DEL EXCEL COMPLETO # ============================================================================= nombre_fichero = 'Auditoria_Integral_Nominas_e_Inflacion_2012_2026.xlsx' print("Iniciando la creación del mega-archivo Excel. ¡Paciencia, puede tardar un par de minutos!...") with pd.ExcelWriter(nombre_fichero, engine='openpyxl') as writer: # 1. Pestañas de Parámetros de Control print("Generando hojas de control normativo...") df_gen, df_tra = generar_hojas_control() df_gen.to_excel(writer, sheet_name='CONTROL_GENERAL', index=False) df_tra.to_excel(writer, sheet_name='CONTROL_TRAMOS_IRPF', index=False) # 2. Pestaña Comparativa Inflación print("Calculando y generando comparativa ajustada por IPC...") df_comparativa = generar_comparativa_inflacion() df_comparativa.to_excel(writer, sheet_name='COMPARATIVA_INFLACION', index=False) # 3. Pestañas Anuales Detalladas (de 1€ en 1€) for anio in range(2012, 2027): print(f"Calculando nóminas detalladas para el año {anio} (100.001 registros)...") df_ano = procesar_ano(anio) df_ano.to_excel(writer, sheet_name=f'DAT_{anio}', index=False) print(f"\n¡Éxito total! Archivo '{nombre_fichero}' creado correctamente con todas las auditorías solicitadas.")

Español
9
89
533
20.7K
Sr Magnate أُعيد تغريده
Finz
Finz@Finz_video·
Un héroe de las calles mexicanas
Español
210
616
14.9K
70.3K
ProfitAddict!
ProfitAddict!@Profit_Addict·
🏠 Sara tiene 31 años, enfermera. Lleva 6 años haciendo guardias nocturnas y ha ahorrado 45.000 € Encuentra un piso por 220.000 €. El banco le da el 80 % → 176.000 €. Necesita 44.000 € de entrada. 🚨 Entonces llega la factura que nadie te explica cuando firmas, el ITP. 22.000 € más. No son para el piso, tampoco para el banco, son para papa estado, por el simple hecho de comprar. De golpe necesitas 66.000 €. Sara esta jodida… y sin casa. Si el gobierno sabe que hay una crisis en la vivienda y “quiere ayudar al ciudadano”… ¿por qué no quita el ITP? 🧐
Español
483
1.7K
6.7K
505.3K
Sr Magnate
Sr Magnate@maherraizz·
@magarciadiaz @Jongonzlz No es que no haya gente capaz en las administraciones, el problema es que en este sistema tan democrático, lo primero que hace un partido en el gobierno es copar las administraciones de cargos a dedo para minar y controlar las instituciones y las opiniones
Español
0
0
2
199
Miguel Angel García
Miguel Angel García@magarciadiaz·
Una reflexión y pregunta a partir del excelente trabajo de @Jongonzlz (y mi experiencia como gestor de AAPP) ¿por qué las administraciones públicas no son capaces de hacer este tipo de trabajos para cumplir con su obligación de servicio a la ciudadanía ?
Jon González@Jongonzlz

Quiero DEMOCRATIZAR el conocimiento del cálculo del IRPF y del salario neto, y las implicaciones de la progresividad en frío entre 2012 y 2026. Pero necesito fiscalistas y economistas con ojo al detalle y techies. Quiero que los que sabéis de fiscalidad auditéis los resultados de mi código para cada año atendiendo al más mínimo detalle (yo he tratado de hacerlo), Que los techies me propongáis mejoras en el código y optimizaciones en las salidas, y quiero que, finalmente, los que tenéis capacidad de montar una web con ello, os coordinéis y lo hagáis. También quiero que extraigáis un manual sencillo para que la gente lo entienda a partir de los cálculos que se hacen en el código. Y que se expliquen las distintas normativas y cómo impactaron. A TRABAJAR. GO GO GO! @Gsnchez @XMihura @Inspectores_IHE @frdelatorre @Jaume_Vinas @SantiCalvo_Eco Ahí va el código! import pandas as pd import numpy as np # ============================================================================= # 1. MÓDULO MACROECONÓMICO: INFLACIÓN ACUMULADA (DICIEMBRE A DICIEMBRE) # ============================================================================= IPC_ANUAL_DIC = { 2013: 0.003, 2014: -0.010, 2015: 0.000, 2016: 0.016, 2017: 0.011, 2018: 0.012, 2019: 0.008, 2020: -0.005, 2021: 0.065, 2022: 0.057, 2023: 0.031, 2024: 0.028, 2025: 0.029, 2026: 0.030 } def obtener_inflacion_acumulada(anio_base, anio_destino=2026): if anio_base == anio_destino: return 1.0 multiplicador = 1.0 for anio in range(anio_base + 1, anio_destino + 1): multiplicador *= (1 + IPC_ANUAL_DIC[anio]) return multiplicador INFLACION_A_2026 = {anio: obtener_inflacion_acumulada(anio, 2026) for anio in range(2012, 2027)} # ============================================================================= # 2. NORMATIVA FISCAL Y LABORAL (IRPF Y SS) # ============================================================================= def obtener_parametros(anio): p = {} # Bases y Tipos Generales SS p['base_max'] = { 2012: 39150.0, 2013: 41108.4, 2014: 43164.0, 2015: 43272.0, 2016: 43704.0, 2017: 45014.4, 2018: 45014.4, 2019: 48841.2, 2020: 48841.2, 2021: 48841.2, 2022: 49672.8, 2023: 53946.0, 2024: 56646.0, 2025: 58914.0, 2026: 61214.4 }[anio] p['ss_tipos'] = { 'comunes': [0.236, 0.047], 'desempleo': [0.055, 0.0155], 'fogasa': [0.002, 0.0], 'fp': [0.006, 0.001], 'atep': [0.015, 0.0] } # MEI y Solidaridad if anio == 2023: p['mei'] = [0.005, 0.001] elif anio == 2024: p['mei'] = [0.0058, 0.0012] elif anio == 2025: p['mei'] = [0.0067, 0.0013] elif anio >= 2026: p['mei'] = [0.0075, 0.0015] else: p['mei'] = [0.0, 0.0] if anio == 2025: p['solidaridad'] = [(1.10, 0.0092), (1.50, 0.0100), (float('inf'), 0.0117)] elif anio >= 2026: p['solidaridad'] = [(1.10, 0.0115), (1.50, 0.0125), (float('inf'), 0.0146)] else: p['solidaridad'] = [] # Mínimos y Gastos p['irpf_minimo'] = 5151 if anio <= 2014 else 5550 p['minimo_exento'] = { 2012: 11162, 2013: 11162, 2014: 11162, 2015: 12000, 2016: 12000, 2017: 12000, 2018: 12643, 2019: 14000, 2020: 14000, 2021: 14000, 2022: 14000, 2023: 15000, 2024: 15876, 2025: 15876, 2026: 15876 }[anio] p['gastos_fijos'] = 0 if anio <= 2014 else 2000 # Reducción Art 20 (y Metadatos para control) def get_art20_params(a): if a <= 2014: return {"U_Inf": 9180, "R_Max": 4080, "U_Sup": 13260, "R_Min": 2652} elif 2015 <= a <= 2017: return {"U_Inf": 11250, "R_Max": 3700, "U_Sup": 14450, "R_Min": 0} elif a == 2018: return {"U_Inf": "Transitorio", "R_Max": "Transitorio", "U_Sup": "Transitorio", "R_Min": "Transitorio"} elif 2019 <= a <= 2022: return {"U_Inf": 13115, "R_Max": 5565, "U_Sup": 16825, "R_Min": 0} elif a == 2023: return {"U_Inf": 14047.5, "R_Max": 6498, "U_Sup": 19747.5, "R_Min": 0} else: return {"U_Inf": 14852, "R_Max": 7302, "U_Sup": 19747.5, "R_Min": 0} p['art20_meta'] = get_art20_params(anio) def reduccion_trabajo(rn_previo): if anio <= 2014: if rn_previo <= 9180: return 4080.0 elif rn_previo <= 13260: return 4080.0 - 0.35 * (rn_previo - 9180.0) else: return 2652.0 elif 2015 <= anio <= 2017: if rn_previo <= 11250: return 3700.0 elif rn_previo <= 14450: return 3700.0 - 1.15625 * (rn_previo - 11250.0) else: return 0.0 elif anio == 2018: # Régimen Transitorio pre = 3700.0 if rn_previo <= 11250 else (3700.0 - 1.15625 * (rn_previo - 11250.0) if rn_previo <= 14450 else 0.0) post = 5565.0 if rn_previo <= 13115 else (max(0.0, 5565.0 - 1.5 * (rn_previo - 13115.0)) if rn_previo <= 16825 else 0.0) return (pre / 2.0) + (post / 2.0) elif 2019 <= anio <= 2022: if rn_previo <= 13115: return 5565.0 elif rn_previo <= 16825: return max(0.0, 5565.0 - 1.5 * (rn_previo - 13115.0)) else: return 0.0 elif anio == 2023: if rn_previo <= 14047.50: return 6498.0 elif rn_previo <= 19747.50: return max(0.0, 6498.0 - 1.14 * (rn_previo - 14047.50)) else: return 0.0 elif anio >= 2024: if rn_previo <= 14852: return 7302.0 elif rn_previo <= 17673.52: return 7302.0 - 1.75 * (rn_previo - 14852.0) elif rn_previo <= 19747.50: return 2364.34 - 1.14 * (rn_previo - 17673.52) else: return 0.0 return 0.0 p['reduccion_trabajo'] = reduccion_trabajo # Escalas IRPF if anio <= 2014: p['tramos_irpf'] = [(17707, 0.2475), (33007, 0.30), (53407, 0.40), (120000, 0.47), (175000, 0.49), (300000, 0.51), (float('inf'), 0.52)] elif anio == 2015: p['tramos_irpf'] = [(12450, 0.195), (20200, 0.245), (34000, 0.305), (60000, 0.38), (float('inf'), 0.46)] elif 2016 <= anio <= 2020: p['tramos_irpf'] = [(12450, 0.19), (20200, 0.24), (35200, 0.30), (60000, 0.37), (float('inf'), 0.45)] else: p['tramos_irpf'] = [(12450, 0.19), (20200, 0.24), (35200, 0.30), (60000, 0.37), (300000, 0.45), (float('inf'), 0.47)] # Deducción SMI def deduccion_smi(bruto): if anio == 2026: if bruto <= 17094: return 590.89 else: return max(0.0, 590.89 - 0.20 * (bruto - 17094.0)) elif anio == 2025: if bruto <= 16576: return 340.0 elif bruto <= 18276: return max(0, 340.0 - 0.20 * (bruto - 16576.0)) return 0.0 p['deduccion_smi'] = deduccion_smi return p # ============================================================================= # 3. GENERACIÓN DE HOJAS DE CONTROL DE PARÁMETROS # ============================================================================= def generar_hojas_control(): general = [] tramos_lista = [] for anio in range(2012, 2027): p = obtener_parametros(anio) tipo_emp = sum(x[0] for x in p['ss_tipos'].values()) tipo_tra = sum(x[1] for x in p['ss_tipos'].values()) general.append({ "Año": anio, "Base Máx. Anual": p['base_max'], "SS Empleador %": round(tipo_emp * 100, 2), "SS Empleado %": round(tipo_tra * 100, 2), "MEI Empleador %": round(p['mei'][0] * 100, 3), "MEI Empleado %": round(p['mei'][1] * 100, 3), "Gastos Fijos Art.19": p['gastos_fijos'], "Mín. Contribuyente": p['irpf_minimo'], "Mín. Exento Retención": p['minimo_exento'], "Art.20 Umbral Inf": p['art20_meta']['U_Inf'], "Art.20 Red. Máxima": p['art20_meta']['R_Max'], "Art.20 Umbral Sup": p['art20_meta']['U_Sup'], "Art.20 Red. Mínima": p['art20_meta']['R_Min'] }) for i, (lim, tip) in enumerate(p['tramos_irpf']): tramos_lista.append({ "Año": anio, "Nº Tramo": i + 1, "Hasta Base": lim if lim != float('inf') else "En adelante", "Tipo %": round(tip * 100, 2) }) return pd.DataFrame(general), pd.DataFrame(tramos_lista) # ============================================================================= # 4. MOTOR DETALLADO (PARA PESTAÑAS ANUALES DAT_YYYY) # ============================================================================= def calcular_cuotas_por_tramo(base_liq, tramos): cuotas_tramos = {f"T{i+1} ({round(tipo*100, 1)}%)": 0.0 for i, (_, tipo) in enumerate(tramos)} cuota_total = 0.0 if base_liq <= 0: return cuotas_tramos, cuota_total lim_ant = 0.0 for i, (lim, tipo) in enumerate(tramos): nombre = f"T{i+1} ({round(tipo*100, 1)}%)" if base_liq > lim: cuota = (lim - lim_ant) * tipo cuotas_tramos[nombre] = cuota cuota_total += cuota lim_ant = lim else: cuota = (base_liq - lim_ant) * tipo cuotas_tramos[nombre] = cuota cuota_total += cuota break return cuotas_tramos, cuota_total def procesar_ano(anio): p = obtener_parametros(anio) # Rango exhaustivo: 0 a 100.000€ de 1€ en 1€ salarios_brutos = np.arange(0, 100001, 1) resultados = [] for bruto in salarios_brutos: base_cotizacion = min(bruto, p['base_max']) exceso_base = max(0, bruto - p['base_max']) tipo_empresa = sum(x[0] for x in p['ss_tipos'].values()) + p['mei'][0] tipo_trabajador = sum(x[1] for x in p['ss_tipos'].values()) + p['mei'][1] cot_empresa = base_cotizacion * tipo_empresa cot_trabajador = base_cotizacion * tipo_trabajador if p['solidaridad'] and exceso_base > 0: tramo1_limite = p['base_max'] * 0.10 tramo2_limite = p['base_max'] * 0.50 exceso1 = min(exceso_base, tramo1_limite) exceso2 = min(max(0, exceso_base - tramo1_limite), tramo2_limite - tramo1_limite) exceso3 = max(0, exceso_base - tramo2_limite) cuota_sol_total = (exceso1 * p['solidaridad'][0][1]) + (exceso2 * p['solidaridad'][1][1]) + (exceso3 * p['solidaridad'][2][1]) cot_empresa += cuota_sol_total * (5/6) cot_trabajador += cuota_sol_total * (1/6) coste_laboral = bruto + cot_empresa rendimiento_previo_sin_fijos = bruto - cot_trabajador red_trabajo = p['reduccion_trabajo'](rendimiento_previo_sin_fijos) rendimiento_neto = max(0, rendimiento_previo_sin_fijos - p['gastos_fijos']) base_imponible = max(0, rendimiento_neto - red_trabajo) cuotas_tramos, cuota_integra = calcular_cuotas_por_tramo(base_imponible, p['tramos_irpf']) cuota_minimo = p['irpf_minimo'] * p['tramos_irpf'][0][1] cuota_teorica = max(0, cuota_integra - cuota_minimo) deduccion = p['deduccion_smi'](bruto) cuota_con_deduccion = max(0, cuota_teorica - deduccion) limite_retencion = max(0, (bruto - p['minimo_exento']) * 0.43) irpf_final = min(cuota_con_deduccion, limite_retencion) salario_neto = bruto - cot_trabajador - irpf_final fila = { "Salario Bruto": bruto, "Cot. Soc. Empresa": round(cot_empresa, 2), "Coste Laboral": round(coste_laboral, 2), "Cot. Soc. Trab.": round(cot_trabajador, 2), "Ren. Previo": round(rendimiento_previo_sin_fijos, 2), "Gastos Fijos": p['gastos_fijos'], "Red. Ren. Trab.": round(red_trabajo, 2), "Base Imponible": round(base_imponible, 2) } for k, v in cuotas_tramos.items(): fila[k] = round(v, 2) fila.update({ "Cuota Íntegra": round(cuota_integra, 2), "Cuota Mínimo Personal": round(cuota_minimo, 2), "Cuota Teórica": round(cuota_teorica, 2), "Deducción SMI": round(deduccion, 2), "Cuota tras SMI": round(cuota_con_deduccion, 2), "Límite 43% (Art 85.3)": round(limite_retencion, 2), "IRPF Final": round(irpf_final, 2), "Salario Neto": round(salario_neto, 2) }) resultados.append(fila) return pd.DataFrame(resultados) # ============================================================================= # 5. MOTOR RÁPIDO PARA COMPARATIVA INFLACIÓN # ============================================================================= def calcular_nomina_agregada(bruto, anio, p): base_cot = min(bruto, p['base_max']) exc_base = max(0, bruto - p['base_max']) t_emp = sum(x[0] for x in p['ss_tipos'].values()) + p['mei'][0] t_tra = sum(x[1] for x in p['ss_tipos'].values()) + p['mei'][1] cot_emp = base_cot * t_emp cot_tra = base_cot * t_tra if p['solidaridad'] and exc_base > 0: l1, l2 = p['base_max']*0.1, p['base_max']*0.5 e1, e2, e3 = min(exc_base, l1), min(max(0, exc_base-l1), l2-l1), max(0, exc_base-l2) q_sol = (e1*p['solidaridad'][0][1]) + (e2*p['solidaridad'][1][1]) + (e3*p['solidaridad'][2][1]) cot_emp += q_sol * (5/6); cot_tra += q_sol * (1/6) coste_lab = bruto + cot_emp rn_previo = bruto - cot_tra red20 = p['reduccion_trabajo'](rn_previo) base_imp = max(0, rn_previo - p['gastos_fijos'] - red20) q_integra = 0.0 lim_ant = 0.0 for lim, tipo in p['tramos_irpf']: if base_imp > lim: q_integra += (lim - lim_ant) * tipo lim_ant = lim else: q_integra += (base_imp - lim_ant) * tipo break q_min = p['irpf_minimo'] * p['tramos_irpf'][0][1] q_teorica = max(0, q_integra - q_min) q_smi = max(0, q_teorica - p['deduccion_smi'](bruto)) lim_ret = max(0, (bruto - p['minimo_exento']) * 0.43) irpf_final = min(q_smi, lim_ret) return coste_lab, cot_emp, cot_tra, irpf_final, bruto - cot_tra - irpf_final def generar_comparativa_inflacion(): # Análisis comparativo en saltos de 1.000€ salarios_2026 = np.arange(15000, 100001, 1000) p_2026 = obtener_parametros(2026) ref_2026 = {b: calcular_nomina_agregada(b, 2026, p_2026) for b in salarios_2026} resultados = [] for anio in range(2012, 2027): p_anio = obtener_parametros(anio) inf_acum = INFLACION_A_2026[anio] for bruto_26 in salarios_2026: bruto_nom = bruto_26 / inf_acum c_lab_n, c_emp_n, c_tra_n, irpf_n, neto_n = calcular_nomina_agregada(bruto_nom, anio, p_anio) c_lab_aj = c_lab_n * inf_acum c_emp_aj = c_emp_n * inf_acum c_tra_aj = c_tra_n * inf_acum irpf_aj = irpf_n * inf_acum neto_aj = neto_n * inf_acum neto_2026_real = ref_2026[bruto_26][4] dif_poder_adq = neto_aj - neto_2026_real resultados.append({ "Año a Comparar": anio, "Salario Equivalente (2026)": bruto_26, "Multiplicador IPC Acum.": round(inf_acum, 4), "IPC Acumulado (%)": f"{round((inf_acum - 1)*100, 2)}%", "Salario Bruto Nominal": round(bruto_nom, 2), "Coste Lab. (Euros 2026)": round(c_lab_aj, 2), "SS Emp. (Euros 2026)": round(c_emp_aj, 2), "SS Tra. (Euros 2026)": round(c_tra_aj, 2), "IRPF (Euros 2026)": round(irpf_aj, 2), "Neto Real en su Año": round(neto_aj, 2), "Neto Real en 2026": round(neto_2026_real, 2), "Variación Poder Adquisitivo Mensual vs 2026 (12 pagas)": round(dif_poder_adq / 12, 2), "Pérdida/Ganancia Anual Poder Adq.": round(dif_poder_adq, 2) }) return pd.DataFrame(resultados) # ============================================================================= # 6. EJECUCIÓN MAESTRA Y GENERACIÓN DEL EXCEL COMPLETO # ============================================================================= nombre_fichero = 'Auditoria_Integral_Nominas_e_Inflacion_2012_2026.xlsx' print("Iniciando la creación del mega-archivo Excel. ¡Paciencia, puede tardar un par de minutos!...") with pd.ExcelWriter(nombre_fichero, engine='openpyxl') as writer: # 1. Pestañas de Parámetros de Control print("Generando hojas de control normativo...") df_gen, df_tra = generar_hojas_control() df_gen.to_excel(writer, sheet_name='CONTROL_GENERAL', index=False) df_tra.to_excel(writer, sheet_name='CONTROL_TRAMOS_IRPF', index=False) # 2. Pestaña Comparativa Inflación print("Calculando y generando comparativa ajustada por IPC...") df_comparativa = generar_comparativa_inflacion() df_comparativa.to_excel(writer, sheet_name='COMPARATIVA_INFLACION', index=False) # 3. Pestañas Anuales Detalladas (de 1€ en 1€) for anio in range(2012, 2027): print(f"Calculando nóminas detalladas para el año {anio} (100.001 registros)...") df_ano = procesar_ano(anio) df_ano.to_excel(writer, sheet_name=f'DAT_{anio}', index=False) print(f"\n¡Éxito total! Archivo '{nombre_fichero}' creado correctamente con todas las auditorías solicitadas.")

Español
26
48
230
10.6K
Sr Magnate أُعيد تغريده
Canal Hispanidad
Canal Hispanidad@CanalHispanidad·
🎬Celebra todo lo que nos une. ¡YA EN CINES! Con esta película mostramos lo que fue España en la fundación de Estados Unidos. Una historia fascinante que está ahí, esperando a ser descubierta. We The Hispanos, la nueva película de José Luis López-Linares.
Español
0
157
367
108.2K
Sr Magnate أُعيد تغريده
Mr Rami
Mr Rami@ecorami·
Comparto todo lo que puedo las publicaciones de Jon. Se lo merece por el esfuerzo, el talento, la calidad del material y la buena fe que pone en todo. Pero es que, esta vez sí, creo que está cambiando algo, y llega donde tiene que llegar. Nuestros políticos responden a los incentivos que les damos. Es el momento en que vean que no cuela con el burdo engaño y la cortina de humo de retórica barata, y que demandamos argumentos construidos sobre datos de calidad. El debate público es hoy (por lo menos) un épsilon mejor. MUCHAS GRACIAS. A Jon y a todos los que colaboran en ello.
Jon González@Jongonzlz

Quiero DEMOCRATIZAR el conocimiento del cálculo del IRPF y del salario neto, y las implicaciones de la progresividad en frío entre 2012 y 2026. Pero necesito fiscalistas y economistas con ojo al detalle y techies. Quiero que los que sabéis de fiscalidad auditéis los resultados de mi código para cada año atendiendo al más mínimo detalle (yo he tratado de hacerlo), Que los techies me propongáis mejoras en el código y optimizaciones en las salidas, y quiero que, finalmente, los que tenéis capacidad de montar una web con ello, os coordinéis y lo hagáis. También quiero que extraigáis un manual sencillo para que la gente lo entienda a partir de los cálculos que se hacen en el código. Y que se expliquen las distintas normativas y cómo impactaron. A TRABAJAR. GO GO GO! @Gsnchez @XMihura @Inspectores_IHE @frdelatorre @Jaume_Vinas @SantiCalvo_Eco Ahí va el código! import pandas as pd import numpy as np # ============================================================================= # 1. MÓDULO MACROECONÓMICO: INFLACIÓN ACUMULADA (DICIEMBRE A DICIEMBRE) # ============================================================================= IPC_ANUAL_DIC = { 2013: 0.003, 2014: -0.010, 2015: 0.000, 2016: 0.016, 2017: 0.011, 2018: 0.012, 2019: 0.008, 2020: -0.005, 2021: 0.065, 2022: 0.057, 2023: 0.031, 2024: 0.028, 2025: 0.029, 2026: 0.030 } def obtener_inflacion_acumulada(anio_base, anio_destino=2026): if anio_base == anio_destino: return 1.0 multiplicador = 1.0 for anio in range(anio_base + 1, anio_destino + 1): multiplicador *= (1 + IPC_ANUAL_DIC[anio]) return multiplicador INFLACION_A_2026 = {anio: obtener_inflacion_acumulada(anio, 2026) for anio in range(2012, 2027)} # ============================================================================= # 2. NORMATIVA FISCAL Y LABORAL (IRPF Y SS) # ============================================================================= def obtener_parametros(anio): p = {} # Bases y Tipos Generales SS p['base_max'] = { 2012: 39150.0, 2013: 41108.4, 2014: 43164.0, 2015: 43272.0, 2016: 43704.0, 2017: 45014.4, 2018: 45014.4, 2019: 48841.2, 2020: 48841.2, 2021: 48841.2, 2022: 49672.8, 2023: 53946.0, 2024: 56646.0, 2025: 58914.0, 2026: 61214.4 }[anio] p['ss_tipos'] = { 'comunes': [0.236, 0.047], 'desempleo': [0.055, 0.0155], 'fogasa': [0.002, 0.0], 'fp': [0.006, 0.001], 'atep': [0.015, 0.0] } # MEI y Solidaridad if anio == 2023: p['mei'] = [0.005, 0.001] elif anio == 2024: p['mei'] = [0.0058, 0.0012] elif anio == 2025: p['mei'] = [0.0067, 0.0013] elif anio >= 2026: p['mei'] = [0.0075, 0.0015] else: p['mei'] = [0.0, 0.0] if anio == 2025: p['solidaridad'] = [(1.10, 0.0092), (1.50, 0.0100), (float('inf'), 0.0117)] elif anio >= 2026: p['solidaridad'] = [(1.10, 0.0115), (1.50, 0.0125), (float('inf'), 0.0146)] else: p['solidaridad'] = [] # Mínimos y Gastos p['irpf_minimo'] = 5151 if anio <= 2014 else 5550 p['minimo_exento'] = { 2012: 11162, 2013: 11162, 2014: 11162, 2015: 12000, 2016: 12000, 2017: 12000, 2018: 12643, 2019: 14000, 2020: 14000, 2021: 14000, 2022: 14000, 2023: 15000, 2024: 15876, 2025: 15876, 2026: 15876 }[anio] p['gastos_fijos'] = 0 if anio <= 2014 else 2000 # Reducción Art 20 (y Metadatos para control) def get_art20_params(a): if a <= 2014: return {"U_Inf": 9180, "R_Max": 4080, "U_Sup": 13260, "R_Min": 2652} elif 2015 <= a <= 2017: return {"U_Inf": 11250, "R_Max": 3700, "U_Sup": 14450, "R_Min": 0} elif a == 2018: return {"U_Inf": "Transitorio", "R_Max": "Transitorio", "U_Sup": "Transitorio", "R_Min": "Transitorio"} elif 2019 <= a <= 2022: return {"U_Inf": 13115, "R_Max": 5565, "U_Sup": 16825, "R_Min": 0} elif a == 2023: return {"U_Inf": 14047.5, "R_Max": 6498, "U_Sup": 19747.5, "R_Min": 0} else: return {"U_Inf": 14852, "R_Max": 7302, "U_Sup": 19747.5, "R_Min": 0} p['art20_meta'] = get_art20_params(anio) def reduccion_trabajo(rn_previo): if anio <= 2014: if rn_previo <= 9180: return 4080.0 elif rn_previo <= 13260: return 4080.0 - 0.35 * (rn_previo - 9180.0) else: return 2652.0 elif 2015 <= anio <= 2017: if rn_previo <= 11250: return 3700.0 elif rn_previo <= 14450: return 3700.0 - 1.15625 * (rn_previo - 11250.0) else: return 0.0 elif anio == 2018: # Régimen Transitorio pre = 3700.0 if rn_previo <= 11250 else (3700.0 - 1.15625 * (rn_previo - 11250.0) if rn_previo <= 14450 else 0.0) post = 5565.0 if rn_previo <= 13115 else (max(0.0, 5565.0 - 1.5 * (rn_previo - 13115.0)) if rn_previo <= 16825 else 0.0) return (pre / 2.0) + (post / 2.0) elif 2019 <= anio <= 2022: if rn_previo <= 13115: return 5565.0 elif rn_previo <= 16825: return max(0.0, 5565.0 - 1.5 * (rn_previo - 13115.0)) else: return 0.0 elif anio == 2023: if rn_previo <= 14047.50: return 6498.0 elif rn_previo <= 19747.50: return max(0.0, 6498.0 - 1.14 * (rn_previo - 14047.50)) else: return 0.0 elif anio >= 2024: if rn_previo <= 14852: return 7302.0 elif rn_previo <= 17673.52: return 7302.0 - 1.75 * (rn_previo - 14852.0) elif rn_previo <= 19747.50: return 2364.34 - 1.14 * (rn_previo - 17673.52) else: return 0.0 return 0.0 p['reduccion_trabajo'] = reduccion_trabajo # Escalas IRPF if anio <= 2014: p['tramos_irpf'] = [(17707, 0.2475), (33007, 0.30), (53407, 0.40), (120000, 0.47), (175000, 0.49), (300000, 0.51), (float('inf'), 0.52)] elif anio == 2015: p['tramos_irpf'] = [(12450, 0.195), (20200, 0.245), (34000, 0.305), (60000, 0.38), (float('inf'), 0.46)] elif 2016 <= anio <= 2020: p['tramos_irpf'] = [(12450, 0.19), (20200, 0.24), (35200, 0.30), (60000, 0.37), (float('inf'), 0.45)] else: p['tramos_irpf'] = [(12450, 0.19), (20200, 0.24), (35200, 0.30), (60000, 0.37), (300000, 0.45), (float('inf'), 0.47)] # Deducción SMI def deduccion_smi(bruto): if anio == 2026: if bruto <= 17094: return 590.89 else: return max(0.0, 590.89 - 0.20 * (bruto - 17094.0)) elif anio == 2025: if bruto <= 16576: return 340.0 elif bruto <= 18276: return max(0, 340.0 - 0.20 * (bruto - 16576.0)) return 0.0 p['deduccion_smi'] = deduccion_smi return p # ============================================================================= # 3. GENERACIÓN DE HOJAS DE CONTROL DE PARÁMETROS # ============================================================================= def generar_hojas_control(): general = [] tramos_lista = [] for anio in range(2012, 2027): p = obtener_parametros(anio) tipo_emp = sum(x[0] for x in p['ss_tipos'].values()) tipo_tra = sum(x[1] for x in p['ss_tipos'].values()) general.append({ "Año": anio, "Base Máx. Anual": p['base_max'], "SS Empleador %": round(tipo_emp * 100, 2), "SS Empleado %": round(tipo_tra * 100, 2), "MEI Empleador %": round(p['mei'][0] * 100, 3), "MEI Empleado %": round(p['mei'][1] * 100, 3), "Gastos Fijos Art.19": p['gastos_fijos'], "Mín. Contribuyente": p['irpf_minimo'], "Mín. Exento Retención": p['minimo_exento'], "Art.20 Umbral Inf": p['art20_meta']['U_Inf'], "Art.20 Red. Máxima": p['art20_meta']['R_Max'], "Art.20 Umbral Sup": p['art20_meta']['U_Sup'], "Art.20 Red. Mínima": p['art20_meta']['R_Min'] }) for i, (lim, tip) in enumerate(p['tramos_irpf']): tramos_lista.append({ "Año": anio, "Nº Tramo": i + 1, "Hasta Base": lim if lim != float('inf') else "En adelante", "Tipo %": round(tip * 100, 2) }) return pd.DataFrame(general), pd.DataFrame(tramos_lista) # ============================================================================= # 4. MOTOR DETALLADO (PARA PESTAÑAS ANUALES DAT_YYYY) # ============================================================================= def calcular_cuotas_por_tramo(base_liq, tramos): cuotas_tramos = {f"T{i+1} ({round(tipo*100, 1)}%)": 0.0 for i, (_, tipo) in enumerate(tramos)} cuota_total = 0.0 if base_liq <= 0: return cuotas_tramos, cuota_total lim_ant = 0.0 for i, (lim, tipo) in enumerate(tramos): nombre = f"T{i+1} ({round(tipo*100, 1)}%)" if base_liq > lim: cuota = (lim - lim_ant) * tipo cuotas_tramos[nombre] = cuota cuota_total += cuota lim_ant = lim else: cuota = (base_liq - lim_ant) * tipo cuotas_tramos[nombre] = cuota cuota_total += cuota break return cuotas_tramos, cuota_total def procesar_ano(anio): p = obtener_parametros(anio) # Rango exhaustivo: 0 a 100.000€ de 1€ en 1€ salarios_brutos = np.arange(0, 100001, 1) resultados = [] for bruto in salarios_brutos: base_cotizacion = min(bruto, p['base_max']) exceso_base = max(0, bruto - p['base_max']) tipo_empresa = sum(x[0] for x in p['ss_tipos'].values()) + p['mei'][0] tipo_trabajador = sum(x[1] for x in p['ss_tipos'].values()) + p['mei'][1] cot_empresa = base_cotizacion * tipo_empresa cot_trabajador = base_cotizacion * tipo_trabajador if p['solidaridad'] and exceso_base > 0: tramo1_limite = p['base_max'] * 0.10 tramo2_limite = p['base_max'] * 0.50 exceso1 = min(exceso_base, tramo1_limite) exceso2 = min(max(0, exceso_base - tramo1_limite), tramo2_limite - tramo1_limite) exceso3 = max(0, exceso_base - tramo2_limite) cuota_sol_total = (exceso1 * p['solidaridad'][0][1]) + (exceso2 * p['solidaridad'][1][1]) + (exceso3 * p['solidaridad'][2][1]) cot_empresa += cuota_sol_total * (5/6) cot_trabajador += cuota_sol_total * (1/6) coste_laboral = bruto + cot_empresa rendimiento_previo_sin_fijos = bruto - cot_trabajador red_trabajo = p['reduccion_trabajo'](rendimiento_previo_sin_fijos) rendimiento_neto = max(0, rendimiento_previo_sin_fijos - p['gastos_fijos']) base_imponible = max(0, rendimiento_neto - red_trabajo) cuotas_tramos, cuota_integra = calcular_cuotas_por_tramo(base_imponible, p['tramos_irpf']) cuota_minimo = p['irpf_minimo'] * p['tramos_irpf'][0][1] cuota_teorica = max(0, cuota_integra - cuota_minimo) deduccion = p['deduccion_smi'](bruto) cuota_con_deduccion = max(0, cuota_teorica - deduccion) limite_retencion = max(0, (bruto - p['minimo_exento']) * 0.43) irpf_final = min(cuota_con_deduccion, limite_retencion) salario_neto = bruto - cot_trabajador - irpf_final fila = { "Salario Bruto": bruto, "Cot. Soc. Empresa": round(cot_empresa, 2), "Coste Laboral": round(coste_laboral, 2), "Cot. Soc. Trab.": round(cot_trabajador, 2), "Ren. Previo": round(rendimiento_previo_sin_fijos, 2), "Gastos Fijos": p['gastos_fijos'], "Red. Ren. Trab.": round(red_trabajo, 2), "Base Imponible": round(base_imponible, 2) } for k, v in cuotas_tramos.items(): fila[k] = round(v, 2) fila.update({ "Cuota Íntegra": round(cuota_integra, 2), "Cuota Mínimo Personal": round(cuota_minimo, 2), "Cuota Teórica": round(cuota_teorica, 2), "Deducción SMI": round(deduccion, 2), "Cuota tras SMI": round(cuota_con_deduccion, 2), "Límite 43% (Art 85.3)": round(limite_retencion, 2), "IRPF Final": round(irpf_final, 2), "Salario Neto": round(salario_neto, 2) }) resultados.append(fila) return pd.DataFrame(resultados) # ============================================================================= # 5. MOTOR RÁPIDO PARA COMPARATIVA INFLACIÓN # ============================================================================= def calcular_nomina_agregada(bruto, anio, p): base_cot = min(bruto, p['base_max']) exc_base = max(0, bruto - p['base_max']) t_emp = sum(x[0] for x in p['ss_tipos'].values()) + p['mei'][0] t_tra = sum(x[1] for x in p['ss_tipos'].values()) + p['mei'][1] cot_emp = base_cot * t_emp cot_tra = base_cot * t_tra if p['solidaridad'] and exc_base > 0: l1, l2 = p['base_max']*0.1, p['base_max']*0.5 e1, e2, e3 = min(exc_base, l1), min(max(0, exc_base-l1), l2-l1), max(0, exc_base-l2) q_sol = (e1*p['solidaridad'][0][1]) + (e2*p['solidaridad'][1][1]) + (e3*p['solidaridad'][2][1]) cot_emp += q_sol * (5/6); cot_tra += q_sol * (1/6) coste_lab = bruto + cot_emp rn_previo = bruto - cot_tra red20 = p['reduccion_trabajo'](rn_previo) base_imp = max(0, rn_previo - p['gastos_fijos'] - red20) q_integra = 0.0 lim_ant = 0.0 for lim, tipo in p['tramos_irpf']: if base_imp > lim: q_integra += (lim - lim_ant) * tipo lim_ant = lim else: q_integra += (base_imp - lim_ant) * tipo break q_min = p['irpf_minimo'] * p['tramos_irpf'][0][1] q_teorica = max(0, q_integra - q_min) q_smi = max(0, q_teorica - p['deduccion_smi'](bruto)) lim_ret = max(0, (bruto - p['minimo_exento']) * 0.43) irpf_final = min(q_smi, lim_ret) return coste_lab, cot_emp, cot_tra, irpf_final, bruto - cot_tra - irpf_final def generar_comparativa_inflacion(): # Análisis comparativo en saltos de 1.000€ salarios_2026 = np.arange(15000, 100001, 1000) p_2026 = obtener_parametros(2026) ref_2026 = {b: calcular_nomina_agregada(b, 2026, p_2026) for b in salarios_2026} resultados = [] for anio in range(2012, 2027): p_anio = obtener_parametros(anio) inf_acum = INFLACION_A_2026[anio] for bruto_26 in salarios_2026: bruto_nom = bruto_26 / inf_acum c_lab_n, c_emp_n, c_tra_n, irpf_n, neto_n = calcular_nomina_agregada(bruto_nom, anio, p_anio) c_lab_aj = c_lab_n * inf_acum c_emp_aj = c_emp_n * inf_acum c_tra_aj = c_tra_n * inf_acum irpf_aj = irpf_n * inf_acum neto_aj = neto_n * inf_acum neto_2026_real = ref_2026[bruto_26][4] dif_poder_adq = neto_aj - neto_2026_real resultados.append({ "Año a Comparar": anio, "Salario Equivalente (2026)": bruto_26, "Multiplicador IPC Acum.": round(inf_acum, 4), "IPC Acumulado (%)": f"{round((inf_acum - 1)*100, 2)}%", "Salario Bruto Nominal": round(bruto_nom, 2), "Coste Lab. (Euros 2026)": round(c_lab_aj, 2), "SS Emp. (Euros 2026)": round(c_emp_aj, 2), "SS Tra. (Euros 2026)": round(c_tra_aj, 2), "IRPF (Euros 2026)": round(irpf_aj, 2), "Neto Real en su Año": round(neto_aj, 2), "Neto Real en 2026": round(neto_2026_real, 2), "Variación Poder Adquisitivo Mensual vs 2026 (12 pagas)": round(dif_poder_adq / 12, 2), "Pérdida/Ganancia Anual Poder Adq.": round(dif_poder_adq, 2) }) return pd.DataFrame(resultados) # ============================================================================= # 6. EJECUCIÓN MAESTRA Y GENERACIÓN DEL EXCEL COMPLETO # ============================================================================= nombre_fichero = 'Auditoria_Integral_Nominas_e_Inflacion_2012_2026.xlsx' print("Iniciando la creación del mega-archivo Excel. ¡Paciencia, puede tardar un par de minutos!...") with pd.ExcelWriter(nombre_fichero, engine='openpyxl') as writer: # 1. Pestañas de Parámetros de Control print("Generando hojas de control normativo...") df_gen, df_tra = generar_hojas_control() df_gen.to_excel(writer, sheet_name='CONTROL_GENERAL', index=False) df_tra.to_excel(writer, sheet_name='CONTROL_TRAMOS_IRPF', index=False) # 2. Pestaña Comparativa Inflación print("Calculando y generando comparativa ajustada por IPC...") df_comparativa = generar_comparativa_inflacion() df_comparativa.to_excel(writer, sheet_name='COMPARATIVA_INFLACION', index=False) # 3. Pestañas Anuales Detalladas (de 1€ en 1€) for anio in range(2012, 2027): print(f"Calculando nóminas detalladas para el año {anio} (100.001 registros)...") df_ano = procesar_ano(anio) df_ano.to_excel(writer, sheet_name=f'DAT_{anio}', index=False) print(f"\n¡Éxito total! Archivo '{nombre_fichero}' creado correctamente con todas las auditorías solicitadas.")

Español
2
84
421
11.6K
Sr Magnate أُعيد تغريده
Santiago Calvo
Santiago Calvo@SantiCalvo_Eco·
Podríamos decir que esta es la foto que mejor representa lo que ha sucedido en España en los últimos 15 años: • Pensión media: +69,1% • IPC: +35,0% • Salario público: +27,8% • Salario privado: +24,6% Las pensiones ganan 25 puntos de poder adquisitivo real. El trabajador privado pierde 10. Y encima financia esas pensiones vía cotizaciones.
Santiago Calvo tweet media
Español
33
209
412
17K
Borrachito 🥃
Borrachito 🥃@borrachito·
¿Alguien me explica esto de las barberías? 😂 Apenas abren el local y ya aparecen 4 o 5 amigos del dueño que claramente no tienen nada que hacer. Se instalan en los sillones todo el día, platicando, viendo el teléfono y ocupando el lugar como si fuera su sala.
Borrachito 🥃 tweet media
Español
997
419
4K
390.1K
Sr Magnate
Sr Magnate@maherraizz·
@jcarlos2001 Y pensar que todo empezó con un sujetador con relleno
Sr Magnate tweet media
Español
0
0
2
119
HUMOR CANALLA
HUMOR CANALLA@jcarlos2001·
CAGÜENMIVIDA EL METEORITO SE TARDA
Español
26
34
209
23.4K
Sr Magnate أُعيد تغريده
Jon González
Jon González@Jongonzlz·
¡Mirad qué chulo! Ya van saliendo proyectos. Os juro que esto tiene la máxima precisión. ¿No es genial que ahora sea fácil y sencillo que podáis ver cuánto dinero habéis perdido como consecuencia de las decisiones del Gobierno?
Jon González tweet media
Demarquía Planetaria@DemarquiaCiu

@Jongonzlz Lo he pasado a HTML y lo he subido a la web: demarquia.org/recursos/html/…

Español
50
722
2.3K
95.8K
Bruce
Bruce@bruce_barrett·
These people are on our roads now.
English
823
2.1K
19.4K
3.1M