Python
This commit is contained in:
11
bin/Pipfile
Normal file
11
bin/Pipfile
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
[[source]]
|
||||||
|
name = "pypi"
|
||||||
|
url = "https://pypi.org/simple"
|
||||||
|
verify_ssl = true
|
||||||
|
|
||||||
|
[dev-packages]
|
||||||
|
|
||||||
|
[packages]
|
||||||
|
|
||||||
|
[requires]
|
||||||
|
python_version = "3.8"
|
16
bin/informes/Pipfile
Normal file
16
bin/informes/Pipfile
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
[[source]]
|
||||||
|
name = "pypi"
|
||||||
|
url = "https://pypi.org/simple"
|
||||||
|
verify_ssl = true
|
||||||
|
|
||||||
|
[dev-packages]
|
||||||
|
|
||||||
|
[packages]
|
||||||
|
pandas = "*"
|
||||||
|
xlsxwriter = "*"
|
||||||
|
httpx = "*"
|
||||||
|
flask = "*"
|
||||||
|
numpy = "*"
|
||||||
|
|
||||||
|
[requires]
|
||||||
|
python_version = "3.8"
|
14
bin/informes/app.py
Normal file
14
bin/informes/app.py
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
import argparse
|
||||||
|
from flask import Flask
|
||||||
|
from controllers.ventas import ventas_blueprint
|
||||||
|
|
||||||
|
|
||||||
|
app = Flask(__name__)
|
||||||
|
app.register_blueprint(ventas_blueprint, url_prefix='/ventas')
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
parser.add_argument('-p', '--port', default=8011)
|
||||||
|
args = parser.parse_args()
|
||||||
|
app.run(port=args.port, debug=True)
|
141
bin/informes/controllers/ventas.py
Normal file
141
bin/informes/controllers/ventas.py
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
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'})
|
Reference in New Issue
Block a user