diff --git a/app/app.ipynb b/app/app.ipynb index 88036bf..e3447dc 100644 --- a/app/app.ipynb +++ b/app/app.ipynb @@ -347,6 +347,9 @@ " return df\n", "\n", "def _build_cobertura(df):\n", + " if df is None or df.empty or 'CANT_DESCARGADA' not in df.columns:\n", + " return pd.DataFrame(columns=['FACTURAEXPO','FECHA_FACTURAEXPO',\n", + " 'componentes_total','componentes_100pct','pct_promedio'])\n", " df_d = df.copy()\n", " df_d['cant_cubierta'] = df_d['CANT_DESCARGADA'].where(df_d['TIPO'].isin(['ORIGINAL','SUSTITUTO']), 0)\n", " cob_comp = df_d.groupby(['FACTURAEXPO','FECHA_FACTURAEXPO','LINEA','PT','COMPONENTE_MP','UNIMED_BOM','CANT_REQUERIDA'],\n", @@ -597,7 +600,7 @@ "def graficar_impo_expo(cmp):\n", " plt.close('all')\n", " fig, axes = plt.subplots(2, 1, figsize=(11, 8))\n", - " fig.suptitle('IMPO vs EXPO por aanio‚±o', fontsize=14, fontweight='bold', y=1.0)\n", + " fig.suptitle('IMPO vs EXPO por a-o', fontsize=14, fontweight='bold', y=1.0)\n", " x = cmp['ANIO'].astype(int).values\n", " xpos = np.arange(len(x)); ancho = 0.4\n", " cI, cE = '#1976D2', '#F57C00'\n", @@ -617,7 +620,7 @@ " ax = axes[1]\n", " b1 = ax.bar(xpos-ancho/2, cmp['valor_me_impo'], ancho, label='IMPO', color=cI)\n", " b2 = ax.bar(xpos+ancho/2, cmp['valor_me_expo'], ancho, label='EXPO', color=cE)\n", - " ax.set_title('Valor ME (USD)'); ax.set_xticks(xpos); ax.set_xticklabels(x); ax.set_xlabel('Aanio‚±o')\n", + " ax.set_title('Valor ME (USD)'); ax.set_xticks(xpos); ax.set_xticklabels(x); ax.set_xlabel('A-o')\n", " ax.yaxis.set_major_formatter(mtick.FuncFormatter(lambda v,_: f'${v:,.0f}'))\n", " ax.legend(loc='upper left'); ax.grid(axis='y', linestyle=':', alpha=0.5)\n", " ax.set_ylim(top=ax.get_ylim()[1]*1.18); lab(ax, b1, cI, '${:,.0f}'); lab(ax, b2, cE, '${:,.0f}')\n", @@ -627,7 +630,7 @@ "def graficar_saldos_anio(por_anio):\n", " plt.close('all')\n", " fig, axes = plt.subplots(1, 2, figsize=(13, 5))\n", - " fig.suptitle('Saldo disponible por aanio‚±o de entrada', fontsize=13, fontweight='bold')\n", + " fig.suptitle('Saldo disponible por a-o de entrada', fontsize=13, fontweight='bold')\n", " x = por_anio['ANIO_ENTRADA'].astype(int).astype(str).values\n", " axes[0].bar(x, por_anio['saldo_cant'], color='#42A5F5')\n", " axes[0].set_title('Cantidad'); axes[0].grid(axis='y', linestyle=':', alpha=0.5)\n", @@ -686,7 +689,7 @@ "def graficar_pesos_anio(cmp):\n", " plt.close('all')\n", " fig, ax = plt.subplots(figsize=(13, 5.5))\n", - " fig.suptitle('Peso por aanio‚±o anio‚ IMPO / EXPO / CONSUMIDO / DESCARGAS', fontsize=13, fontweight='bold')\n", + " fig.suptitle('Peso por a-o - IMPO / EXPO / CONSUMIDO / DESCARGAS', fontsize=13, fontweight='bold')\n", " x = cmp['ANIO'].astype(int).values\n", " xpos = np.arange(len(x)); ancho = 0.2\n", " cI, cE, cC, cD = '#1976D2', '#F57C00', '#43A047', '#8E24AA'\n", @@ -694,7 +697,7 @@ " b2 = ax.bar(xpos-0.5*ancho, cmp['peso_expo'], ancho, label='EXPO', color=cE)\n", " b3 = ax.bar(xpos+0.5*ancho, cmp['peso_consumido'], ancho, label='CONSUMIDO', color=cC)\n", " b4 = ax.bar(xpos+1.5*ancho, cmp['peso_descargas'], ancho, label='DESCARGAS', color=cD)\n", - " ax.set_xticks(xpos); ax.set_xticklabels(x); ax.set_xlabel('Aanio‚±o')\n", + " ax.set_xticks(xpos); ax.set_xticklabels(x); ax.set_xlabel('A-o')\n", " ax.set_ylabel('Peso neto')\n", " ax.yaxis.set_major_formatter(mtick.FuncFormatter(lambda v,_: f'{v:,.0f}'))\n", " ax.legend(loc='upper left'); ax.grid(axis='y', linestyle=':', alpha=0.5)\n", @@ -734,19 +737,19 @@ " cmp['cantidad_impo'] = cmp['cantidad_impo'].round(2)\n", " cmp['cantidad_expo'] = cmp['cantidad_expo'].round(2)\n", " cmp['diferencia'] = (cmp['cantidad_expo'] - cmp['cantidad_impo']).round(2)\n", - " prog.done('Cantidades por aanio‚±o listas')\n", + " prog.done('Cantidades por a-o listas')\n", " return cmp\n", "\n", "def graficar_cantidades_anio(cmp):\n", " plt.close('all')\n", " fig, ax = plt.subplots(figsize=(12, 5.5))\n", - " fig.suptitle('Cantidades por aanio‚±o anio‚ IMPO vs EXPO', fontsize=13, fontweight='bold')\n", + " fig.suptitle('Cantidades por a-o - IMPO vs EXPO', fontsize=13, fontweight='bold')\n", " x = cmp['ANIO'].astype(int).values\n", " xpos = np.arange(len(x)); ancho = 0.4\n", " cI, cE = '#1976D2', '#F57C00'\n", " b1 = ax.bar(xpos-ancho/2, cmp['cantidad_impo'], ancho, label='IMPO', color=cI)\n", " b2 = ax.bar(xpos+ancho/2, cmp['cantidad_expo'], ancho, label='EXPO', color=cE)\n", - " ax.set_xticks(xpos); ax.set_xticklabels(x); ax.set_xlabel('Aanio‚±o')\n", + " ax.set_xticks(xpos); ax.set_xticklabels(x); ax.set_xlabel('A-o')\n", " ax.set_ylabel('Cantidad (suma de unidades, varias UM)')\n", " ax.yaxis.set_major_formatter(mtick.FuncFormatter(lambda v,_: f'{v:,.0f}'))\n", " ax.legend(loc='upper left'); ax.grid(axis='y', linestyle=':', alpha=0.5)\n", @@ -792,7 +795,7 @@ " cmp['cantidad_impo'] = cmp['cantidad_impo'].round(2)\n", " cmp['cantidad_expo'] = cmp['cantidad_expo'].round(2)\n", " cmp['diferencia'] = (cmp['cantidad_expo'] - cmp['cantidad_impo']).round(2)\n", - " prog.done('Cantidades por aanio‚±o + UM listas')\n", + " prog.done('Cantidades por a-o + UM listas')\n", " return cmp\n", "\n", "def graficar_cantidades_anio_um(cmp, top_ums=None):\n", @@ -809,7 +812,7 @@ " return fig\n", " n = len(top_ums)\n", " fig, axes = plt.subplots(n, 1, figsize=(12, 3.2*n), squeeze=False)\n", - " fig.suptitle('Cantidades por aanio‚±o (separado por UM, top {} UMs)'.format(n), fontsize=13, fontweight='bold', y=1.0)\n", + " fig.suptitle('Cantidades por a-o (separado por UM, top {} UMs)'.format(n), fontsize=13, fontweight='bold', y=1.0)\n", " for idx, um in enumerate(top_ums):\n", " sub = filt[filt['UM'] == um].sort_values('ANIO')\n", " ax = axes[idx][0]\n", @@ -1944,7 +1947,7 @@ "def ejecutar_valores(plan, dry_run=True, progress=None, log=print):\n", " \"\"\"Paso B: UPDATE SPartidasExpo por cada partida del plan, usando 3-part\n", " naming si la fila trae BaseDeDatos/Esquema (cuando se uso shelter).\n", - " Transaccion por (pedimento, BD) — rollback si alguna partida falla.\"\"\"\n", + " Transaccion por (pedimento, BD) rollback si alguna partida falla.\"\"\"\n", " assert isinstance(dry_run, bool), 'dry_run debe ser bool'\n", " prog = _Progress(progress)\n", " if plan is None or plan.empty:\n", @@ -3241,11 +3244,11 @@ "btn_p10.on_click(_on_p10)\n", "\n", "tab_desc = W.VBox([\n", - " W.HTML('
'\n", - " 'cant_req = (BOM.CANTIDAD / 100) anio‚Â PESONETO de la partida. Mismo PEPS, UM y sustitutos.
'),\n", + " 'cant_req = (BOM.CANTIDAD / 100) - PESONETO de la partida. Mismo PEPS, UM y sustitutos.'),\n", " btn_pron12, bar_pron12, out_pron12,\n", - " W.HTML(''\n",
" 'Recorre todas las bases de datos de la instancia SQL Server (las que el usuario '\n",
" 'puede acceder y tienen la tabla SPedimentos.PEDIMENTO) y reporta en '\n",
- " 'cual(es) base(s) vive cada pedimento del Excel. Solo es diagnostico — no '\n",
+ " 'cual(es) base(s) vive cada pedimento del Excel. Solo es diagnostico no '\n",
" 'modifica nada. Util cuando el cliente tiene varias BDs y no sabes a cual '\n",
" 'apuntar el ajuste.