from flask import Blueprint, request, Response import io import json import pandas as pd import numpy as np import datetime ventas_blueprint = Blueprint('ventas', __name__,) def format_data(data): df = pd.DataFrame(data) int_columns = ['Departamento', 'Estacionamientos', 'Bodegas'] for col in int_columns: df[col] = pd.to_numeric(df[col], errors='ignore') float_columns = ['Valor Promesa', 'Pie', 'Pie Pagado', '% Pie Pagado', 'Bono Pie', 'Valor Operador', 'Premios', 'Subsidio', 'Ahorro', 'Credito', 'Valor Ests & Bods', 'Valor Neto', 'UF/m²*', 'Comision', 'Venta s/Comision'] for col in float_columns: if col in df.columns: df[col] = pd.to_numeric(df[col], errors='coerce') df = df.replace(np.nan, 0, regex=True) df['Fecha Venta'] = pd.to_datetime(df['Fecha Venta'], format='%Y-%m-%d') df = df.sort_values(by=['Fecha Venta', 'Departamento']) df['Fecha Venta'] = df['Fecha Venta'].dt.strftime('%d.%m.%Y') return df def format_columns(workbook, columns): column_settings = [{'header': column} for column in columns] center_format = workbook.add_format({'align': 'center'}) amount_format = workbook.add_format({'num_format': '#,##0.00'}) percent_format = workbook.add_format({'num_format': '0.00%'}) amount_columns = ['m² Ponderados', 'Valor Promesa', 'Pie', 'Pie Pagado', 'Bono Pie', 'Valor Operador', 'Premios', 'Subsidio', 'Ahorro', 'Credito', 'Valor Ests & Bods', 'Valor Neto', 'UF/m²*', 'Comision', 'Venta s/Comision'] center_columns = ['Departamento', 'Estacionamientos', 'Bodegas'] sum_columns = ['m² Ponderados', 'Valor Promesa', 'Pie', 'Pie Pagado', 'Bono Pie', 'Subsidio', 'Ahorro', 'Credito', 'Valor Operador', 'Premios', 'Valor Ests & Bods', 'Valor Neto', 'Comision'] count_columns = ['Departamento', 'Estacionamientos', 'Bodegas'] for (k, col) in enumerate(column_settings): if col['header'] in amount_columns: column_settings[k]['format'] = amount_format if col['header'] in center_columns: column_settings[k]['format'] = center_format if col['header'] in sum_columns: column_settings[k]['total_function'] = 'sum' if col['header'] in count_columns: column_settings[k]['total_function'] = 'count' if col['header'] == '% Pie Pagado': column_settings[k]['format'] = percent_format if col['header'] == 'Propietario': column_settings[k]['total_string'] = 'TOTAL' return column_settings def format_excel(workbook, worksheet, data): center_format = workbook.add_format({'align': 'center'}) amount_format = workbook.add_format({'num_format': '#,##0.00'}) percent_format = workbook.add_format({'num_format': '0.00%'}) amount_columns = ['m² Ponderados', 'Valor Promesa', 'Pie', 'Pie Pagado', 'Bono Pie', 'Valor Operador', 'Premios', 'Subsidio', 'Ahorro', 'Credito', 'Valor Ests & Bods', 'Valor Neto', 'UF/m²*', 'Comision', 'Venta s/Comision'] center_columns = ['Departamento', 'Estacionamientos', 'Bodegas'] for col in amount_columns: if col not in data.columns: continue k = data.columns.get_loc(col) + 1 worksheet.set_column(k, k, cell_format=amount_format) for col in center_columns: if col not in data.columns: continue k = data.columns.get_loc(col) + 1 worksheet.set_column(k, k, cell_format=center_format) col = '% Pie Pagado' k = data.columns.get_loc(col) + 1 worksheet.set_column(k, k, cell_format=percent_format) return worksheet @ventas_blueprint.route('', methods=['POST']) def ventas(): data = json.loads(request.data) output = io.BytesIO() writer = pd.ExcelWriter('tmp.xlsx', engine='xlsxwriter') df = format_data(data['data']) start_row = 4 if 'Compañía' in data: start_row += 1 df.to_excel(writer, startrow=start_row+1, startcol=1, header=False, index=False, sheet_name='Ventas') wb = writer.book wb.filename = output title_format = wb.add_format({'font_size': 16, 'bold': True}) ws = writer.sheets['Ventas'] (max_row, max_col) = df.shape if 'Compañía' in data: ws.merge_range(1, 1, 1, max_col, data['Compañía']) ws.merge_range(start_row-3, 1, start_row-3, max_col, data['Proyecto'], cell_format=title_format) ws.write_string(start_row-2, 1, 'Ventas') column_settings = format_columns(wb, df.columns) ws.add_table(start_row, 1, max_row+start_row+1, max_col, {'name': 'Ventas', 'total_row': 1, 'columns': column_settings, 'style': 'Table Style Medium 1'}) ws = format_excel(wb, ws, df) column_widths = { 'B': 46, 'C': 16, 'D': 18, 'E': 10, 'F': 13, 'G': 7, 'H': 8, 'I': 16, 'J': 16, 'K': 13, 'L': 14 } for (col, wd) in column_widths.items(): ws.set_column('{0}:{0}'.format(col), wd) writer.save() output.seek(0) date = datetime.date.today() filename = "Informe de Ventas - {0} - {1}.xlsx".format(data['Proyecto'], date.strftime('%Y-%m-%d')) return Response(output, mimetype="application/ms-excel", headers={"Content-Disposition": "attachment;filename={0}".format(filename), "Content-Type": 'application/octet-stream; charset=utf-8'})