From 7cb01bd9fbd8245a6eef837ba0e5bc7feca460cf Mon Sep 17 00:00:00 2001 From: pjpatil12 Date: Tue, 23 Dec 2025 19:40:41 +0530 Subject: [PATCH] new comparison --- app/routes/file_report.py | 161 +++++++++++++++++- app/templates/base.html | 5 +- ...generate_comparison_client_vs_subcont.html | 43 +++++ 3 files changed, 206 insertions(+), 3 deletions(-) create mode 100644 app/templates/generate_comparison_client_vs_subcont.html diff --git a/app/routes/file_report.py b/app/routes/file_report.py index 2e8555c..f82b869 100644 --- a/app/routes/file_report.py +++ b/app/routes/file_report.py @@ -3,6 +3,10 @@ from app.models.subcontractor_model import Subcontractor from app.models.manhole_excavation_model import ManholeExcavation from app.models.trench_excavation_model import TrenchExcavation from app.models.manhole_domestic_chamber_model import ManholeDomesticChamber +from app.models.mh_ex_client_model import ManholeExcavationClient +from app.models.tr_ex_client_model import TrenchExcavationClient +from app.models.mh_dc_client_model import ManholeDomesticChamberClient + from app import db import pandas as pd @@ -10,7 +14,7 @@ import io file_report_bp = Blueprint("file_report", __name__, url_prefix="/file") - +# get report by contractor id and dowanload @file_report_bp.route("/report", methods=["GET", "POST"]) def report_file(): subcontractors = Subcontractor.query.all() @@ -127,3 +131,158 @@ def report_file(): return render_template("report.html", subcontractors=subcontractors) + + + + + +@file_report_bp.route("/client_vs_subcont", methods=["GET", "POST"]) +def client_vs_all_subcontractor(): + + + if request.method == "POST": + RA_Bill_No = request.form.get("RA_Bill_No") + + if not RA_Bill_No: + flash("Please select RA Bill No.", "danger") + return render_template("generate_comparison_client_vs_subcont.html") + + + # CLIENT DATA (RA BILL WISE) + client_trench = TrenchExcavationClient.query.filter_by(RA_Bill_No=RA_Bill_No).all() + client_mh = ManholeExcavationClient.query.filter_by(RA_Bill_No=RA_Bill_No).all() + client_dc = ManholeDomesticChamberClient.query.filter_by(RA_Bill_No=RA_Bill_No).all() + + df_client_tr = pd.DataFrame([c.__dict__ for c in client_trench]) + df_client_mh = pd.DataFrame([c.__dict__ for c in client_mh]) + df_client_dc = pd.DataFrame([c.__dict__ for c in client_dc]) + + # ALL SUBCONTRACTOR DATA + sub_trench = TrenchExcavation.query.filter_by(RA_Bill_No=RA_Bill_No).all() + sub_mh = ManholeExcavation.query.filter_by(RA_Bill_No=RA_Bill_No).all() + sub_dc = ManholeDomesticChamber.query.filter_by(RA_Bill_No=RA_Bill_No).all() + + df_sub_tr = pd.DataFrame([s.__dict__ for s in sub_trench]) + df_sub_mh = pd.DataFrame([s.__dict__ for s in sub_mh]) + df_sub_dc = pd.DataFrame([s.__dict__ for s in sub_dc]) + + # CLEAN COLUMNS + drop_cols = ["id","created_at","Remarks","_sa_instance_state"] + + for df in [df_client_tr, df_client_mh, df_client_dc,df_sub_tr, df_sub_mh, df_sub_dc]: + if not df.empty: + df.drop(columns=drop_cols, errors="ignore", inplace=True) + + + # GROUP SUBCONTRACTOR DATA + qty_cols = [ + "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_to_3_0_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" + ] + + mh_dc_qty_cols = [ + "d_0_to_0_75", + "d_0_76_to_1_05", + "d_1_06_to_1_65", + "d_1_66_to_2_15", + "d_2_16_to_2_65", + "d_2_66_to_3_15", + "d_3_16_to_3_65", + "d_3_66_to_4_15", + "d_4_16_to_4_65", + "d_4_66_to_5_15", + "d_5_16_to_5_65", + "d_5_66_to_6_15", + "d_6_16_to_6_65", + "d_6_66_to_7_15", + "d_7_16_to_7_65", + "d_7_66_to_8_15", + "d_8_16_to_8_65", + "d_8_66_to_9_15", + "d_9_16_to_9_65", + "Domestic_Chambers" + ] + + df_sub_tr_grp = (df_sub_tr.groupby(["Location", "MH_NO"], as_index=False)[qty_cols].sum()) + + df_sub_mh_grp = (df_sub_mh.groupby(["Location", "MH_NO"], as_index=False)[qty_cols].sum()) + + df_sub_dc_grp = (df_sub_dc.groupby(["Location", "Node_No"], as_index=False)[mh_dc_qty_cols].sum()) + + # MERGE CLIENT VS SUBCONTRACTOR + df_tr_cmp = df_client_tr.merge( + df_sub_tr_grp, + on=["Location", "MH_NO"], + how="left", + suffixes=("_Client", "_Sub") + ) + + df_mh_cmp = df_client_mh.merge( + df_sub_mh_grp, + on=["Location", "MH_NO"], + how="left", + suffixes=("_Client", "_Sub") + ) + + if "MH_NO" in df_client_dc.columns: + df_client_dc.rename(columns={"MH_NO": "Node_No"}, inplace=True) + + df_dc_cmp = df_client_dc.merge( + df_sub_dc_grp, + on=["Location", "Node_No"], + how="left", + suffixes=("_Client", "_Sub") + ) + + # CALCULATE DIFFERENCE + for col in qty_cols: + if f"{col}_Client" in df_tr_cmp.columns: + df_tr_cmp[f"{col}_Diff"] = ( + df_tr_cmp[f"{col}_Client"].fillna(0) + - df_tr_cmp[f"{col}_Sub"].fillna(0) + ) + + print("Sum of df_tr_cmp::",df_tr_cmp) + + df_mh_cmp[f"{col}_Diff"] = ( + df_mh_cmp[f"{col}_Client"].fillna(0) + - df_mh_cmp[f"{col}_Sub"].fillna(0) + ) + print("Sum of df_mh_cmp::",df_mh_cmp) + + + df_dc_cmp["Domestic_Chambers_Diff"] = ( + df_dc_cmp["Domestic_Chambers_Client"].fillna(0) + - df_dc_cmp["Domestic_Chambers_Sub"].fillna(0) + ) + + + # EXPORT EXCEL + output = io.BytesIO() + file_name = f"Client_vs_All_Subcontractor_RA_{RA_Bill_No}.xlsx" + + with pd.ExcelWriter(output, engine="xlsxwriter") as writer: + df_tr_cmp.to_excel(writer, sheet_name="Tr.Ex", index=False) + df_mh_cmp.to_excel(writer, sheet_name="Mh.Ex", index=False) + df_dc_cmp.to_excel(writer, sheet_name="MH & DC", index=False) + + 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_client_vs_subcont.html") diff --git a/app/templates/base.html b/app/templates/base.html index 57099cc..49d95eb 100644 --- a/app/templates/base.html +++ b/app/templates/base.html @@ -45,13 +45,14 @@ - + diff --git a/app/templates/generate_comparison_client_vs_subcont.html b/app/templates/generate_comparison_client_vs_subcont.html new file mode 100644 index 0000000..9a3e62b --- /dev/null +++ b/app/templates/generate_comparison_client_vs_subcont.html @@ -0,0 +1,43 @@ +{% extends "base.html" %} + +{% block content %} +
+ +

File Comparison

+ + + {% with messages = get_flashed_messages(with_categories=true) %} + {% if messages %} + {% for category, message in messages %} + + {% endfor %} + {% endif %} + {% endwith %} + +
+ +
+ + + + + + + + + +
+ +
+
+{% endblock %} \ No newline at end of file