GaboDataScientist commited on
Commit
89271ce
·
verified ·
1 Parent(s): 6ccd1e1

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +154 -0
app.py ADDED
@@ -0,0 +1,154 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import pandas as pd
3
+ import tempfile
4
+
5
+ def procesar_bases(file1, file2):
6
+ try:
7
+ # Leer archivos
8
+ dff = pd.read_excel(file1, engine='openpyxl')
9
+ dfp = pd.read_excel(file2, engine='openpyxl')
10
+
11
+ # --- Existing code from the provided script starts here ---
12
+ # FASE 1: FACTURAS
13
+ dff_expanded=dff.copy()
14
+ dff_expanded[['FORMA DE PAGO','CANAL','MES','AÑO','UNIDADES']]=None
15
+
16
+ dff_expanded=dff_expanded[['ID', 'FORMA DE PAGO','COMPANIA','CANAL', 'RFC', 'RAZON SOCIAL', 'CP', 'CORREO ELECTRONICO',
17
+ 'REGIMEN FISCAL', 'METODO DE PAGO', 'FECHA PAGO', 'USO CFDI',
18
+ 'ES RESICO', 'FECHA FACT.', 'MES', 'AÑO', 'OBSERVACIONES', 'EJECUTIVO ID SOl',
19
+ 'EJECUTIVO SOL', 'EJECUTIVO ID EMITE', 'EJECUTIVO EMITE',
20
+ 'EJECUTIVO FECHA EMITE', 'SUBTOTAL', 'RETENCIONES', 'DESCUENTO', 'IVA',
21
+ 'TOTAL', 'UUID', 'UUID REL', 'ESTATUS', 'SERIE', 'FOLIO',
22
+ 'UNIDADES','FOLIO COMPLEMENTO']]
23
+
24
+ # 2.- Agrego la columna CANAL
25
+ dff_expanded['CANAL'] = 'DIRECTO' # Valor por defecto
26
+ dff_expanded.loc[dff_expanded['SERIE'] == 'AFM', 'CANAL'] = 'ASEGURADORA'
27
+
28
+ dff_expanded['FECHA FACT.'] = pd.to_datetime(dff_expanded['FECHA FACT.'], format='%d/%m/%Y', errors='coerce')
29
+ # Extract the year and month
30
+ dff_expanded['AÑO'] = dff_expanded['FECHA FACT.'].dt.year
31
+ dff_expanded['MES'] = dff_expanded['FECHA FACT.'].dt.month
32
+
33
+ # FASE 2: PARTIDAS
34
+ #1.- Extraemos la información de la columna "CONCEPTO"
35
+ def split_concepto(row):
36
+ parts = row['CONCEPTO'].split(':')
37
+ return parts
38
+
39
+ # Aplicar la función a cada fila del DataFrame
40
+ dfp_expanded = dfp.copy() # Crear una copia para evitar modificar el original
41
+ dfp_expanded['concepto_split'] = dfp.apply(split_concepto, axis=1)
42
+
43
+ # Obtener el máximo número de partes para crear las nuevas columnas
44
+ max_parts = dfp_expanded['concepto_split'].apply(len).max()
45
+
46
+ # Crear nuevas columnas para cada parte del concepto
47
+ for i in range(max_parts):
48
+ dfp_expanded[f'concepto_{i+1}'] = dfp_expanded['concepto_split'].apply(lambda x: x[i] if len(x) > i else None)
49
+
50
+
51
+ # Eliminar la columna 'concepto_split'
52
+ dfp_expanded = dfp_expanded.drop('concepto_split', axis=1)
53
+
54
+ #- Quitamos las columnas que nos estorban y les cambiamos el nombre a las que nos funcionan
55
+ dfp_expanded_final=dfp_expanded[['ID FACTURA','concepto_2','concepto_5','concepto_8','concepto_11','concepto_13','concepto_14','ORDEN ASOCIADA', 'ORDEN ASOCIADA ID',
56
+ 'ORDEN ASOCIADA EJEC ID', 'ORDEN ASOCIADA EJECUTIVO','ORDEN ASOCIADA NEGOCIO', 'ORDEN ASOCIADA TIPO NEGOCIO','ORDEN ASOCIADA ESTATUS', 'CUENTA CONTABLE', 'CODIGO PRODUCTO',
57
+ 'CANTIDAD', 'MEDIDA', 'CODIGO UNIDAD', 'PRECIO UNITARIO', 'PARCIAL']]
58
+
59
+ dfp_expanded_final = dfp_expanded_final.rename(columns={'concepto_2': 'VIN', 'concepto_5':'RECIBO','concepto_8':'SOLUCION','concepto_11':'CONCEPTO','concepto_13':'PERIODO SERVICIO','concepto_14':'ULT SERVICIO CUBIERTO'})
60
+
61
+ empty_concepto_2 = dfp_expanded_final[(dfp_expanded_final['VIN'].isnull()) | (dfp_expanded_final['VIN'] == '')]
62
+ # 3.- Quitamos esas facturas de la tabla que vamos a manipular
63
+ dfp_expanded_final = dfp_expanded_final[dfp_expanded_final['VIN'].notnull()]
64
+ #Quito los espacios en los valores de la columna RECIBO
65
+ dfp_expanded_final['RECIBO'] = dfp_expanded_final['RECIBO'].str.strip()
66
+ dfp_expanded_final['FORMA DE PAGO'] = 'MENSUAL' # Default value
67
+ dfp_expanded_final.loc[dfp_expanded_final['RECIBO'] == '1/1', 'FORMA DE PAGO'] = 'CONTADO'
68
+
69
+ dfp_expanded_final['ORDEN NEGOCIO'] = 'OTRO' # Valor por defecto
70
+ dfp_expanded_final.loc[dfp_expanded_final['ORDEN ASOCIADA NEGOCIO'] == 'MOVIMIENTO', 'ORDEN NEGOCIO'] = 'MOVIMIENTO'
71
+ dfp_expanded_final.loc[dfp_expanded_final['ORDEN ASOCIADA NEGOCIO'].isin(['NUEVO', 'RECUPERADO NUEVO']), 'ORDEN NEGOCIO'] = 'NUEVO'
72
+ dfp_expanded_final.loc[dfp_expanded_final['ORDEN ASOCIADA NEGOCIO'].isin(['RENOVACIÓN','RENOVACION','RECUPERADO RENOVACIÓN','RECUPERADO RENOVACION','RENOVACI�N']), 'ORDEN NEGOCIO'] = 'RENOVACION'
73
+
74
+ dfp_expanded_final=pd.merge(dfp_expanded_final,dff_expanded[['ID','CANAL','FECHA FACT.','MES', 'AÑO','COMPANIA','RAZON SOCIAL','FOLIO']],left_on='ID FACTURA',right_on='ID',how='left')
75
+
76
+ dfp_expanded_final=dfp_expanded_final[['ID FACTURA','CANAL','FORMA DE PAGO', 'FECHA FACT.','COMPANIA','FOLIO','RAZON SOCIAL','VIN', 'RECIBO', 'SOLUCION', 'CONCEPTO',
77
+ 'PERIODO SERVICIO', 'ULT SERVICIO CUBIERTO', 'ORDEN ASOCIADA','ORDEN ASOCIADA ID', 'ORDEN ASOCIADA EJEC ID','ORDEN ASOCIADA EJECUTIVO','ORDEN NEGOCIO','ORDEN ASOCIADA NEGOCIO',
78
+ 'ORDEN ASOCIADA TIPO NEGOCIO', 'ORDEN ASOCIADA ESTATUS','CUENTA CONTABLE', 'CODIGO PRODUCTO', 'CANTIDAD', 'MEDIDA','CODIGO UNIDAD', 'PRECIO UNITARIO', 'PARCIAL','MES', 'AÑO']]
79
+
80
+ #FASE 3: FACTURAS
81
+ dff_expanded = dff_expanded.drop(columns=['FORMA DE PAGO'])
82
+ # Group by 'ID FACTURA' and get the unique payment methods
83
+ payment_methods_per_invoice = dfp_expanded_final.groupby('ID FACTURA')['FORMA DE PAGO'].unique()
84
+
85
+ # Create a new DataFrame with 'ID FACTURA' and the preferred payment method
86
+ facturas_forma_pago = pd.DataFrame({
87
+ 'ID FACTURA': payment_methods_per_invoice.index,
88
+ 'FORMA DE PAGO': payment_methods_per_invoice.values})
89
+
90
+ # Function to select the preferred payment method
91
+ def select_payment_method(payment_methods):
92
+ if 'MENSUAL' in payment_methods:
93
+ return 'MENSUAL'
94
+ else:
95
+ return payment_methods[0] # Return the first payment method if 'MENSUAL' is not present
96
+
97
+
98
+ # Apply the function to select the preferred payment method
99
+ facturas_forma_pago['FORMA DE PAGO'] = facturas_forma_pago['FORMA DE PAGO'].apply(select_payment_method)
100
+
101
+ # Perform the vlookup operation
102
+ dff_expanded = pd.merge(dff_expanded, facturas_forma_pago[['ID FACTURA', 'FORMA DE PAGO']], left_on='ID', right_on='ID FACTURA', how='left')
103
+ # Fill NaN values in 'FORMA DE PAGO' with 'CONTADO'
104
+ dff_expanded['FORMA DE PAGO'] = dff_expanded['FORMA DE PAGO'].fillna('CONTADO')
105
+
106
+ base_unidades = dfp_expanded_final['CANTIDAD'].groupby(dfp_expanded_final['ID FACTURA']).sum()
107
+ dff_expanded = dff_expanded.drop(columns=['UNIDADES'])
108
+ dff_expanded['UNIDADES']=pd.merge(dff_expanded,base_unidades.reset_index(),left_on='ID',right_on='ID FACTURA',how='left')['CANTIDAD']
109
+ # Fill NaN values in 'UNIDADES' column with 0
110
+ dff_expanded['UNIDADES'] = dff_expanded['UNIDADES'].fillna(0)
111
+
112
+ dff_expanded_final=dff_expanded[['ID','FORMA DE PAGO','COMPANIA', 'CANAL', 'RFC', 'RAZON SOCIAL', 'CP',
113
+ 'CORREO ELECTRONICO', 'REGIMEN FISCAL', 'METODO DE PAGO', 'FECHA PAGO',
114
+ 'USO CFDI', 'ES RESICO', 'FECHA FACT.', 'MES', 'AÑO', 'OBSERVACIONES',
115
+ 'EJECUTIVO ID SOl', 'EJECUTIVO SOL', 'EJECUTIVO ID EMITE',
116
+ 'EJECUTIVO EMITE', 'EJECUTIVO FECHA EMITE', 'SUBTOTAL', 'RETENCIONES',
117
+ 'DESCUENTO', 'IVA', 'TOTAL', 'UUID', 'UUID REL', 'ESTATUS', 'SERIE',
118
+ 'FOLIO','UNIDADES','FOLIO COMPLEMENTO']]
119
+
120
+
121
+
122
+ # --- Existing code ends here ---
123
+ # Resultado 1: copia de df1
124
+ temp1 = tempfile.NamedTemporaryFile(delete=False, suffix=".xlsx")
125
+ dff_expanded_final.to_excel(temp1.name, index=False, engine='openpyxl')
126
+
127
+ # Resultado 2: copia de df2
128
+ temp2 = tempfile.NamedTemporaryFile(delete=False, suffix=".xlsx")
129
+ dfp_expanded_final.to_excel(temp2.name, index=False, engine='openpyxl')
130
+
131
+ # Resultado 3: ejemplo filtrado → filas donde alguna columna esté vacía
132
+ temp3 = tempfile.NamedTemporaryFile(delete=False, suffix=".xlsx")
133
+ empty_concepto_2.to_excel(temp3.name, index=False, engine='openpyxl')
134
+
135
+ return temp1.name, temp2.name, temp3.name
136
+
137
+ except Exception as e:
138
+ return f"❌ Error: {str(e)}", None, None
139
+
140
+ # Interfaz Gradio
141
+ gr.Interface(
142
+ fn=procesar_bases,
143
+ inputs=[
144
+ gr.File(label="Sube archivo 1 (Excel)", type="filepath"),
145
+ gr.File(label="Sube archivo 2 (Excel)", type="filepath")
146
+ ],
147
+ outputs=[
148
+ gr.File(label="Resultado 1 (copia archivo 1)"),
149
+ gr.File(label="Resultado 2 (copia archivo 2)"),
150
+ gr.File(label="Resultado 3 (filtrado ejemplo)")
151
+ ],
152
+ title="Procesador de 2 Excel → 3 Archivos",
153
+ description="Sube dos archivos de Excel. El sistema devuelve tres archivos procesados."
154
+ ).launch()