From de7b85034d557963fba595cd83cb2ab778bdaca3 Mon Sep 17 00:00:00 2001 From: pjpatil12 Date: Thu, 6 Aug 2026 13:39:13 +0530 Subject: [PATCH 1/2] replace --- app/routes/file_report.py | 82 +++++++++------------------------------ 1 file changed, 19 insertions(+), 63 deletions(-) diff --git a/app/routes/file_report.py b/app/routes/file_report.py index c5bd57c..1e5de6b 100644 --- a/app/routes/file_report.py +++ b/app/routes/file_report.py @@ -360,78 +360,35 @@ class ClientBill: # --- CLIENT REPORT (PREVIEW + DOWNLOAD) --- @file_report_bp.route("/client_report", methods=["GET", "POST"]) @login_required -def client_vs_all_subcontractor(): - tables = {"tr": None, "mh": None, "dc": None} +def client_report(): + + tables = {"tr": None, "mh": None, "dc": None, "laying": None} ra_val = "" if request.method == "POST": # ⚠ MUST match HTML name RA_Bill_No = request.form.get("RA_Bill_No") + action = request.form.get("action") 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) - - 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: - 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 =[...] - - 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 - return df.groupby(group_cols, as_index=False)[existing_cols].sum() - - # Aggregate data - 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 ]: - if not df_client.empty and "Location" not in df_client.columns: - df_client["Location"] = "Unknown" - - try: - 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")) - except KeyError as e: - flash(f"Merge Error: Missing column {str(e)}. Check if 'Location' is defined in your database models.", "danger") return render_template("client_report.html", tables=tables, ra_val=ra_val) -<<<<<<< HEAD - - - # 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) - -======= + + # -------- FETCH CLIENT DATA -------- + bill_gen = ClientBill() + bill_gen.Fetch(RA_Bill_No) + + # If no data + if ( + bill_gen.df_tr.empty and + bill_gen.df_mh.empty and + bill_gen.df_dc.empty and + bill_gen.df_laying.empty + ): + flash(f"No Client records found for RA Bill {RA_Bill_No}", "warning") + return render_template("client_report.html", tables=tables, ra_val=ra_val) # -------- DOWNLOAD -------- if action == "download": @@ -549,5 +506,4 @@ def format_column_names(df): df.columns = new_columns - return df ->>>>>>> pankaj-dev + return df \ No newline at end of file From 12529800f06f3a54838ab6c9a23e1f3cfb7b31bf Mon Sep 17 00:00:00 2001 From: LaxmiB Date: Fri, 7 Aug 2026 11:49:18 +0530 Subject: [PATCH 2/2] fix: category filter, action icons, download filename, reset button --- app/routes/file_report.py | 117 ++++++++++++++++++++--- app/templates/base.html | 120 +++++++++--------------- app/templates/subcontractor_report.html | 87 +++++++++++------ logs/app.log | 47 ++++++++++ 4 files changed, 254 insertions(+), 117 deletions(-) diff --git a/app/routes/file_report.py b/app/routes/file_report.py index 1e5de6b..e48f87d 100644 --- a/app/routes/file_report.py +++ b/app/routes/file_report.py @@ -29,17 +29,24 @@ def add_action_columns(df, model_key): if df.empty: return df - df.insert(0, "Select", df["Id"].apply( + # Edit + Delete side by side in one "Action" column, both as icon buttons. + df.insert(0, "Action", df["Id"].apply( + lambda x: ( + f'
' + f'' + f'' + f'' + f'
' + ) + )) + + df.insert(1, "Select", df["Id"].apply( lambda x: f'' )) - - df["Update"] = df["Id"].apply( - lambda x: f' Edit' - ) - - df["Delete"] = df["Id"].apply( - lambda x: f'' - ) + + df["Id"] = range(1, len(df) + 1) + df = df.rename(columns={"Id": "Sr No"}) return df @@ -235,6 +242,30 @@ def report_file(): bill.Fetch(subcontractor_id=subcontractor_id) else: bill.Fetch(ra_bill_no,subcontractor_id,location) + + + # --------------------------------------------------------- + if ( + bill.df_tr.empty and + bill.df_mh.empty and + bill.df_dc.empty and + bill.df_laying.empty + ): + flash( + f"No records found for RA Bill No '{ra_bill_no}'. " + "Please check the RA Bill No and try again." + if ra_bill_no else + "No records found for the selected filters.", + "warning" + ) + return render_template( + "subcontractor_report.html", + subcontractors=subcontractors, + selected_sc_id=selected_sc_id, + selected_ra_bill=ra_bill_no, + selected_location=location, + selected_category=category + ) # ----------------------------------------- # Generate Abstract Report for Web @@ -254,6 +285,32 @@ def report_file(): bill.df_tr = bill.df_mh = bill.df_laying = pd.DataFrame() elif category == "laying": bill.df_tr = bill.df_mh = bill.df_dc = pd.DataFrame() + + + if ( + category in ("tr", "mh", "dc", "laying") + and bill.df_tr.empty and bill.df_mh.empty + and bill.df_dc.empty and bill.df_laying.empty + ): + category_labels = { + "tr": "Trench Excavation", + "mh": "Manhole Excavation", + "dc": "Domestic Chamber", + "laying": "Pipe Laying", + } + flash( + f"No {category_labels[category]} records found for the " + "selected filters.", + "warning" + ) + return render_template( + "subcontractor_report.html", + subcontractors=subcontractors, + selected_sc_id=selected_sc_id, + selected_ra_bill=ra_bill_no, + selected_location=location, + selected_category=category + ) # =================================================== @@ -267,16 +324,46 @@ def report_file(): abstract = AbstractReportService(subcontractor_id=subcontractor_id,ra_bill_no=ra_bill_no) abstract.generate(workbook) - bill.df_tr.to_excel(writer,sheet_name="Tr.Ex",index=False) - bill.df_mh.to_excel(writer,sheet_name="Mh.Ex",index=False) - bill.df_dc.to_excel(writer,sheet_name="MH & DC",index=False) - bill.df_laying.to_excel(writer,sheet_name="Pipe Laying",index=False) + + sheet_map = [ + (bill.df_tr, "Tr.Ex"), + (bill.df_mh, "Mh.Ex"), + (bill.df_dc, "MH & DC"), + (bill.df_laying, "Pipe Laying"), + ] + for df, sheet_name in sheet_map: + if not df.empty: + df.to_excel(writer, sheet_name=sheet_name, index=False) writer.close() output.seek(0) - + + + sc_obj = next( + (s for s in subcontractors if str(s.id) == str(subcontractor_id)), + None + ) + sc_name = sc_obj.subcontractor_name if sc_obj else "Subcontractor" + sc_name = re.sub(r'[^A-Za-z0-9_-]+', '_', sc_name).strip('_') + + name_parts = [sc_name] + + if ra_bill_no: + name_parts.append(f"RA{re.sub(r'[^A-Za-z0-9_-]+', '_', ra_bill_no)}") + + if location: + name_parts.append(re.sub(r'[^A-Za-z0-9_-]+', '_', location).strip('_')) + + if category and category != "all": + name_parts.append(category.upper()) + + if action == "excel_all": + name_parts.append("All") + + filename = "_".join(name_parts) + "_Report.xlsx" + return send_file( output, - download_name= "subcontractor_Report.xlsx", + download_name=filename, as_attachment=True ) diff --git a/app/templates/base.html b/app/templates/base.html index cca715e..ba89818 100644 --- a/app/templates/base.html +++ b/app/templates/base.html @@ -124,109 +124,66 @@ Client vs Subcontractor - + - - + + {% if session.get("user_id") %} +