from flask import Blueprint, render_template, request, send_file, flash from app.models.subcontractor_model import Subcontractor from app.models.trench_excavation_model import TrenchExcavation from app.models.tr_ex_client_model import TrenchExcavationClient from app import db import pandas as pd import io generate_report_bp = Blueprint("generate_report", __name__, url_prefix="/report") COMPARISON_COLUMNS = [ ("Soft Murum 0–1.5", "Soft_Murum_0_to_1_5_total", "Soft_Murum_0_to_1_5_total"), ("Soft Murum 1.5–3.0", "Soft_Murum_1_5_to_3_0_total", "Soft_Murum_1_5_to_3_0_total"), ("Soft Murum 3.0–4.5", "Soft_Murum_3_0_to_4_5_total", "Soft_Murum_3_0_to_4_5_total"), ("Hard Murum 0–1.5", "Hard_Murum_0_to_1_5_total", "Hard_Murum_0_to_1_5_total"), ("Hard Murum Above 1.5", "Hard_Murum_1_5_and_above_total", "Hard_Murum_1_5_to_3_0_total"), ("Soft Rock 0–1.5", "Soft_Rock_0_to_1_5_total", "Soft_Rock_0_to_1_5_total"), ("Soft Rock Above 1.5", "Soft_Rock_1_5_and_above_total", "Soft_Rock_1_5_to_3_0_total"), ("Hard Rock 0–1.5", "Hard_Rock_0_to_1_5_total", "Hard_Rock_0_to_1_5_total"), ("Hard Rock Above 1.5", "Hard_Rock_1_5_and_above_total", "Hard_Rock_1_5_to_3_0_total"), ("Hard Rock 3.0–4.5", "Hard_Rock_3_0_to_4_5_total", "Hard_Rock_3_0_to_4_5_total"), ("Hard Rock 4.5–6.0", "Hard_Rock_4_5_to_6_0_total", "Hard_Rock_4_5_to_6_0_total"), ("Hard Rock 6.0–7.5", "Hard_Rock_6_0_to_7_5_total", "Hard_Rock_6_0_to_7_5_total"), ] @generate_report_bp.route("/comparison_report", methods=["GET", "POST"]) def comparison_report(): subcontractors = Subcontractor.query.all() if request.method == "POST": subcontractor_id = request.form.get("subcontractor_id") if not subcontractor_id: flash("Please select a subcontractor.", "danger") return render_template("generate_comparison_report.html", subcontractors=subcontractors) subcontractor = Subcontractor.query.get_or_404(subcontractor_id) # Fetch data contractor_rows = TrenchExcavation.query.filter_by(subcontractor_id=subcontractor_id).all() client_rows = TrenchExcavationClient.query.filter_by(subcontractor_id=subcontractor_id).all() # Convert to DataFrame df_contractor = pd.DataFrame([r.__dict__ for r in contractor_rows]) df_client = pd.DataFrame([r.__dict__ for r in client_rows]) # Drop unwanted columns drop_cols = ["id", "subcontractor_id", "created_at", "_sa_instance_state", "Remarks"] df_contractor.drop(columns=drop_cols, errors="ignore", inplace=True) df_client.drop(columns=drop_cols, errors="ignore", inplace=True) # Convert to numeric df_contractor = df_contractor.apply(pd.to_numeric, errors="coerce").fillna(0) df_client = df_client.apply(pd.to_numeric, errors="coerce").fillna(0) # CREATE SUMMARY summary = [] for label, cont_col, client_col in COMPARISON_COLUMNS: cont_sum = round(df_contractor.get(cont_col, pd.Series()).sum(), 2) client_sum = round(df_client.get(client_col, pd.Series()).sum(), 2) diff = round(client_sum - cont_sum, 2) summary.append({ "Excavation Type": label, "Subcontractor Total": cont_sum, "Client Total": client_sum, "Difference (Client - Subcontractor)": diff }) df_summary = pd.DataFrame(summary) # EXPORT EXCEL output = io.BytesIO() file_name = f"{subcontractor.subcontractor_name}_Comparison_Report.xlsx" with pd.ExcelWriter(output, engine="xlsxwriter") as writer: df_contractor.to_excel(writer, index=False, sheet_name="Contractor_Data") df_client.to_excel(writer, index=False, sheet_name="Client_Data") df_summary.to_excel(writer, index=False, sheet_name="Comparison_Summary") output.seek(0) return send_file( output, as_attachment=True, download_name=file_name, mimetype="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" ) return render_template("generate_comparison_report.html", subcontractors=subcontractors) # @generate_report_bp.route("/comparison_report", methods=["GET", "POST"]) # def report_subcont_client(): # subcontractors = Subcontractor.query.all() # if request.method == "POST": # subcontractor_id = request.form.get("subcontractor_id") # if not subcontractor_id: # flash("Please select a subcontractor.", "danger") # return render_template("report.html", subcontractors=subcontractors) # # Fetch subcontractor for file name # subcontractor = Subcontractor.query.get(subcontractor_id) # trench_excavation1 = TrenchExcavation.query.filter_by(subcontractor_id=subcontractor_id).all() # trench_excavation2 = TrenchExcavationClient.query.filter_by(subcontractor_id=subcontractor_id).all() # # Convert to DataFrame # df_tr_ex1 = pd.DataFrame([m.__dict__ for m in trench_excavation1]) # df_tr_ex2 = pd.DataFrame([t.__dict__ for t in trench_excavation2]) # # Drop unnecessary SQLAlchemy fields # drop_cols = ["id", "subcontractor_id", "created_at", "_sa_instance_state","Remarks"] # df_tr_ex1.drop(columns=drop_cols, errors="ignore", inplace=True) # df_tr_ex2.drop(columns=drop_cols, errors="ignore", inplace=True) # trench_columns = [ # "Location", "MH_NO", "CC_length", "Invert_Level", "MH_Top_Level", # "Ground_Level", "ID_of_MH_m", "Actual_Trench_Length", "Pipe_Dia_mm", # "Width_0_to_2_5", "Width_2_5_to_3_0", "Width_3_0_to_4_5", "Width_4_5_to_6_0", # "Upto_IL_Depth", "Cutting_Depth", "Avg_Depth", # "Soft_Murum_0_to_1_5", "Soft_Murum_1_5_to_3_0", "Soft_Murum_3_0_to_4_5", # "Hard_Murum_0_to_1_5", "Hard_Murum_1_5_to_3_0", # "Soft_Rock_0_to_1_5", "Soft_Rock_1_5_to_3_0", # "Hard_Rock_0_to_1_5", "Hard_Rock_1_5_to_3_0", # "Hard_Rock_3_0_to_4_5", "Hard_Rock_4_5_to_6_0", "Hard_Rock_6_0_to_7_5", # "Soft_Murum_0_to_1_5_total", "Soft_Murum_1_5_to_3_0_total", # "Soft_Murum_3_0_to_4_5_total", # "Hard_Murum_0_to_1_5_total", "Hard_Murum_1_5_and_above_total", # "Soft_Rock_0_to_1_5_total", "Soft_Rock_1_5_and_above_total", # "Hard_Rock_0_to_1_5_total", "Hard_Rock_1_5_and_above_total", # "Hard_Rock_3_0_to_4_5_total", "Hard_Rock_4_5_to_6_0_total", # "Hard_Rock_6_0_to_7_5_total", # "Remarks", "Total" # ] # # Reorder columns serial wise # df_tr_ex1 = df_tr_ex1.reindex(columns=trench_columns, fill_value="") # df_tr_ex2 = df_tr_ex2.reindex(columns=trench_columns, fill_value="") # # WRITE EXCEL FILE # output = io.BytesIO() # file_name = f"{subcontractor.subcontractor_name}_Report.xlsx" # with pd.ExcelWriter(output, engine="xlsxwriter") as writer: # df_tr_ex1.to_excel(writer, index=False, sheet_name="Tr.Ex-contractor.") # df_tr_ex2.to_excel(writer, index=False, sheet_name="Tr.Ex-client.") # output.seek(0) # return send_file( # output, # download_name=file_name, # as_attachment=True, # mimetype="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" # ) # return render_template("generate_comparison_report.html", subcontractors=subcontractors)