From b11a974869c277591c65cc9b49dad0e0c1b83577 Mon Sep 17 00:00:00 2001 From: pjpatil12 Date: Fri, 12 Dec 2025 18:38:50 +0530 Subject: [PATCH] Download all report bysubcontractor id commit --- .gitignore | 3 +- app/__init__.py | 20 --- app/__pycache__/__init__.cpython-313.pyc | Bin 1153 -> 1153 bytes app/__pycache__/config.cpython-313.pyc | Bin 655 -> 655 bytes ...ole_domestic_chamber_model.cpython-313.pyc | Bin 3486 -> 3486 bytes app/models/manhole_domestic_chamber_model.py | 2 +- .../__pycache__/file_report.cpython-313.pyc | Bin 1270 -> 5301 bytes app/routes/file_report.py | 121 +++++++++++++++++- app/templates/base.html | 4 +- app/templates/report.html | 41 ++++-- 10 files changed, 146 insertions(+), 45 deletions(-) diff --git a/.gitignore b/.gitignore index f349a89..6500874 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,6 @@ # Ignore folders instance/ -static/uploads/ - +app/static/uploads/ # Ignore files .env diff --git a/app/__init__.py b/app/__init__.py index fe63ee8..b589d00 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -29,23 +29,3 @@ def create_app(): return app - - - -# from flask import Flask -# from app.config import Config - -# def create_app(): -# app = Flask(__name__) -# app.config.from_object(Config) - -# # Register Blueprints -# from app.routes.dashboard import dashboard_bp -# from app.routes.file_import import file_import_bp -# from app.routes.user import user_bp - -# app.register_blueprint(dashboard_bp) -# app.register_blueprint(file_import_bp) -# app.register_blueprint(user_bp) - -# return app diff --git a/app/__pycache__/__init__.cpython-313.pyc b/app/__pycache__/__init__.cpython-313.pyc index 911bc21207092a54fb5d5d405053a1bdad3d79d9..e29c10b191ee4946ae5f6597f6f88df58e163cde 100644 GIT binary patch delta 23 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 delta 678 zcmZ`#L2DC16rP#QZZ_FuleA5(L3FDvx)&9-V49?$w2Fz1njwO14sNsCCb-SEvm1hi zTF;&=i_o7CZ@mcq0uP=hR1p>gg5)Nbe3c`^r!qE(vJ86^XhN8!gd8LPf$ZflAZINbc|M-lbgs1#%SXLy~6Ic!= zq5lz@$XNETp%RSyFHq*ugT!ir5A(oc6{_Gm!qOZXDH>Q!jTq}P|0-bq!pwhEJz6G; z?}QijE>^59hj`kC)v}1;S*Et`5DmB2>Q2ieM%`o8y~TMg2)pfi-E!R>g$ySyH@r=I zCvh^q=yY1PW0*P$M6c=DR-n3n?{M`93A6hGal37i=Ye3@HW2~vJ8C+^pG`sxbVSBD zR~fkcVZNNKDyJEdxv~rVMsgY+`LB`}RzAlH{aA`l5 zZ!FQrW-nn;+3G8qg95#Ji&mcY6oZD00ow)2x)O-%w&6Y_{Ktp({2)Lie`$OMhW*II ztjn$60+QkS6oWv{Z#rh%wid`VD3ye{y8BZ7 k1`}Ukx(Cy*o88&N$?iD{(-dZZqBvZG0|B7<5gq#c0SBm~00000 diff --git a/app/routes/file_report.py b/app/routes/file_report.py index 2a6cd1d..2e8555c 100644 --- a/app/routes/file_report.py +++ b/app/routes/file_report.py @@ -1,10 +1,16 @@ -# app/routes/file_report.py - -from flask import Blueprint, render_template, request, flash +from flask import Blueprint, render_template, request, send_file, flash 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 import db + +import pandas as pd +import io file_report_bp = Blueprint("file_report", __name__, url_prefix="/file") + @file_report_bp.route("/report", methods=["GET", "POST"]) def report_file(): subcontractors = Subcontractor.query.all() @@ -14,9 +20,110 @@ def report_file(): if not subcontractor_id: flash("Please select a subcontractor.", "danger") - else: - flash(f"Report generated for Subcontractor ID: {subcontractor_id}", "success") + return render_template("report.html", subcontractors=subcontractors) - return render_template("report.html", title="Report Download", subcontractors=subcontractors) + # Fetch subcontractor for file name + subcontractor = Subcontractor.query.get(subcontractor_id) + + manhole_excavation = ManholeExcavation.query.filter_by(subcontractor_id=subcontractor_id).all() + trench_excavation = TrenchExcavation.query.filter_by(subcontractor_id=subcontractor_id).all() + domestic_chamber = ManholeDomesticChamber.query.filter_by(subcontractor_id=subcontractor_id).all() + + + # Convert to DataFrame + df_mh_exc = pd.DataFrame([m.__dict__ for m in manhole_excavation]) + df_trench = pd.DataFrame([t.__dict__ for t in trench_excavation]) + df_domestic = pd.DataFrame([d.__dict__ for d in domestic_chamber]) + + # Drop unnecessary SQLAlchemy fields + drop_cols = ["id", "subcontractor_id", "created_at", "_sa_instance_state","Remarks"] + + df_mh_exc.drop(columns=drop_cols, errors="ignore", inplace=True) + df_trench.drop(columns=drop_cols, errors="ignore", inplace=True) + df_domestic.drop(columns=drop_cols, errors="ignore", inplace=True) + + + mh_exc_columns = [ + "Location", "MH_NO", "Upto_IL_Depth", "Cutting_Depth", "ID_of_MH_m", + "Ex_Dia_of_Manhole", "Area_of_Manhole", + + "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" + ] + + 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" + ] + + domestic_columns = [ + "Location", "Node_No", "Depth_of_MH", + "d_0_to_0_75", "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" + ] + + # Reorder columns serial wise + df_mh_exc = df_mh_exc.reindex(columns=mh_exc_columns, fill_value="") + df_trench = df_trench.reindex(columns=trench_columns, fill_value="") + df_domestic = df_domestic.reindex(columns=domestic_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_trench.to_excel(writer, index=False, sheet_name="Tr.Ex.") + df_mh_exc.to_excel(writer, index=False, sheet_name="MH.Ex.") + df_domestic.to_excel(writer, index=False, sheet_name="MH & DC") + + output.seek(0) + + return send_file( + output, + download_name=file_name, + as_attachment=True, + mimetype="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" + ) + + return render_template("report.html", subcontractors=subcontractors) - return render_template("report.html", title="Report Download", subcontractors=subcontractors) diff --git a/app/templates/base.html b/app/templates/base.html index 2f5941b..f77028f 100644 --- a/app/templates/base.html +++ b/app/templates/base.html @@ -37,7 +37,6 @@ - @@ -62,4 +61,5 @@ - \ No newline at end of file + + diff --git a/app/templates/report.html b/app/templates/report.html index a2a6d11..e6dd6c4 100644 --- a/app/templates/report.html +++ b/app/templates/report.html @@ -1,24 +1,39 @@ {% extends "base.html" %} {% block content %} -

File Report

+
-
+

File Report

-
+ + {% 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