From 359847958db83051294228c812c954f59000c5c5 Mon Sep 17 00:00:00 2001 From: anishd100 Date: Sat, 17 Jan 2026 18:06:58 +0530 Subject: [PATCH] Dowload report of client report fix --- app/routes/file_report.py | 89 +++++++++++++++++++------------- app/templates/client_report.html | 8 +-- 2 files changed, 57 insertions(+), 40 deletions(-) diff --git a/app/routes/file_report.py b/app/routes/file_report.py index 5fa0c0f..a4714b4 100644 --- a/app/routes/file_report.py +++ b/app/routes/file_report.py @@ -144,70 +144,87 @@ def report_file(): @file_report_bp.route("/client_report", methods=["GET", "POST"]) @login_required def client_vs_all_subcontractor(): - tables = {"tr": None, "mh": None, "dc": None} + # Initialize dictionary keys to match HTML variables + tables = {"tr": None, "mh": None, "dc": None, "laying": None} ra_val = "" - + if request.method == "POST": RA_Bill_No = request.form.get("RA_Bill_No") + action = request.form.get("action") # Identify if 'download' or 'preview' ra_val = RA_Bill_No - + if not RA_Bill_No: flash("Please enter RA Bill No.", "danger") - return render_template("generate_comparison_client_vs_subcont.html", tables=tables, ra_val=ra_val) - + return render_template("client_report.html", tables=tables, ra_val=ra_val) + clientBill = ClientBill() clientBill.Fetch(RA_Bill_No=RA_Bill_No) contractorBill = SubcontractorBill() contractorBill.Fetch(RA_Bill_No=RA_Bill_No) - - # --- SAFETY CHECK: Verify data exists before merging --- - if clientBill.df_tr.empty and clientBill.df_mh.empty: + + # Safety Check: Verify if data exists + if clientBill.df_tr.empty and clientBill.df_mh.empty and clientBill.df_laying.empty: flash(f"No Client records found for RA Bill {RA_Bill_No}", "warning") - return render_template("generate_comparison_client_vs_subcont.html", tables=tables, ra_val=ra_val) - - qty_cols = [...] # (Keep your existing list) - mh_dc_qty_cols = [...] # (Keep your existing list) - mh_lay_qty_cols =[...] + return render_template("client_report.html", tables=tables, ra_val=ra_val) + + # Define columns based on your model field names + qty_cols = [ + "pipe_150_mm", "pipe_200_mm", "pipe_250_mm", "pipe_300_mm", + "pipe_350_mm", "pipe_400_mm", "pipe_450_mm", "pipe_500_mm", + "pipe_600_mm", "pipe_700_mm", "pipe_900_mm", "pipe_1200_mm" + ] + mh_dc_qty_cols = ["qty", "total"] # Update these based on your DC model fields + mh_lay_qty_cols = qty_cols + ["Laying_Length", "CC_length"] def aggregate_df(df, group_cols, sum_cols): if df.empty: - # Create an empty DF with the correct columns to avoid Merge/Key Errors return pd.DataFrame(columns=group_cols + sum_cols) existing_cols = [c for c in sum_cols if c in df.columns] - # Ensure group_cols exist in the DF for col in group_cols: if col not in df.columns: - df[col] = "N/A" # Fill missing join keys + df[col] = "N/A" return df.groupby(group_cols, as_index=False)[existing_cols].sum() - - # Aggregate data + + # Aggregate data from Subcontractor tables df_sub_tr_grp = aggregate_df(contractorBill.df_tr, ["Location", "MH_NO"], qty_cols) df_sub_mh_grp = aggregate_df(contractorBill.df_mh, ["Location", "MH_NO"], qty_cols) df_sub_dc_grp = aggregate_df(contractorBill.df_dc, ["Location", "MH_NO"], mh_dc_qty_cols) - df_sub_lay_grp = aggregate_df(contractorBill.df_dc, ["Location", "MH_NO"], mh_lay_qty_cols) - - # --- FINAL MERGE LOGIC --- - # We check if "Location" exists in the client data. If not, we add it to prevent the KeyError. - for df_client in [clientBill.df_tr, clientBill.df_mh, clientBill.df_dc, clientBill.df_laying ]: + # FIXED: Aggregating from .df_laying + df_sub_lay_grp = aggregate_df(contractorBill.df_laying, ["Location", "MH_NO"], mh_lay_qty_cols) + + # Standardize "Location" column to prevent merge keys being missing + for df_client in [clientBill.df_tr, clientBill.df_mh, clientBill.df_dc, clientBill.df_laying]: if not df_client.empty and "Location" not in df_client.columns: df_client["Location"] = "Unknown" - + try: + # Final Merge for Comparison df_tr_cmp = clientBill.df_tr.merge(df_sub_tr_grp, on=["Location", "MH_NO"], how="left", suffixes=("_Client", "_Sub")) df_mh_cmp = clientBill.df_mh.merge(df_sub_mh_grp, on=["Location", "MH_NO"], how="left", suffixes=("_Client", "_Sub")) df_dc_cmp = clientBill.df_dc.merge(df_sub_dc_grp, on=["Location", "MH_NO"], how="left", suffixes=("_Client", "_Sub")) df_lay_cmp = clientBill.df_laying.merge(df_sub_lay_grp, on=["Location", "MH_NO"], how="left", suffixes=("_Client", "_Sub")) + + # --- EXCEL DOWNLOAD LOGIC --- + if action == "download": + output = io.BytesIO() + with pd.ExcelWriter(output, engine="xlsxwriter") as writer: + df_tr_cmp.to_excel(writer, index=False, sheet_name="Tr.Ex ") + df_mh_cmp.to_excel(writer, index=False, sheet_name="Mh.Ex ") + df_dc_cmp.to_excel(writer, index=False, sheet_name="DC ") + df_lay_cmp.to_excel(writer, index=False, sheet_name="Laying and Bedding") + output.seek(0) + file_name = f"Client_Comparison_RA_{RA_Bill_No}.xlsx" + return send_file(output, download_name=file_name, as_attachment=True) + + # --- PREVIEW HTML LOGIC --- + table_classes = 'table table-striped table-hover table-sm border shadow-sm' + tables["tr"] = df_tr_cmp.to_html(classes=table_classes, index=False) + tables["mh"] = df_mh_cmp.to_html(classes=table_classes, index=False) + tables["dc"] = df_dc_cmp.to_html(classes=table_classes, index=False) + tables["laying"] = df_lay_cmp.to_html(classes=table_classes, index=False) + except KeyError as e: - flash(f"Merge Error: Missing column {str(e)}. Check if 'Location' is defined in your database models.", "danger") + flash(f"Merge Error: Missing column {str(e)}", "danger") return render_template("client_report.html", tables=tables, ra_val=ra_val) - - - # Convert to HTML for preview - tables["tr"] = df_tr_cmp.to_html(classes='table table-striped table-hover table-sm', index=False) - tables["mh"] = df_mh_cmp.to_html(classes='table table-striped table-hover table-sm', index=False) - tables["dc"] = df_dc_cmp.to_html(classes='table table-striped table-hover table-sm', index=False) - tables["laying"] = df_lay_cmp.to_html(classes='table table-striped table-hover table-sm', index=False) - - - return render_template("client_report.html", tables=tables, ra_val=ra_val) - \ No newline at end of file + + return render_template("client_report.html", tables=tables, ra_val=ra_val) \ No newline at end of file diff --git a/app/templates/client_report.html b/app/templates/client_report.html index ee633c3..94f8bff 100644 --- a/app/templates/client_report.html +++ b/app/templates/client_report.html @@ -40,19 +40,19 @@