diff --git a/app/routes/file_report.py b/app/routes/file_report.py index 0daaade..0469dd5 100644 --- a/app/routes/file_report.py +++ b/app/routes/file_report.py @@ -141,74 +141,65 @@ def report_file(): download_all=download_all ) -# --- client report only --- + +# --- 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("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: + + # -------- 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) - - 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) - - - # 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 + # -------- DOWNLOAD -------- + if action == "download": + + output = io.BytesIO() + + with pd.ExcelWriter(output, engine="xlsxwriter") as writer: + bill_gen.df_tr.to_excel(writer, index=False, sheet_name="Trench") + bill_gen.df_mh.to_excel(writer, index=False, sheet_name="MH") + bill_gen.df_dc.to_excel(writer, index=False, sheet_name="MH & DC") + bill_gen.df_laying.to_excel(writer, index=False, sheet_name="Laying") + + output.seek(0) + + return send_file( + output, + download_name=f"Client_RA_{RA_Bill_No}_Report.xlsx", + as_attachment=True + ) + + # -------- PREVIEW -------- + table_class = "table table-bordered table-striped table-hover table-sm" + + tables["tr"] = bill_gen.df_tr.to_html(classes=table_class, index=False) + tables["mh"] = bill_gen.df_mh.to_html(classes=table_class, index=False) + tables["dc"] = bill_gen.df_dc.to_html(classes=table_class, index=False) + tables["laying"] = bill_gen.df_laying.to_html(classes=table_class, index=False) + + return render_template("client_report.html", tables=tables, ra_val=ra_val) \ No newline at end of file diff --git a/app/routes/subcontractor_routes.py b/app/routes/subcontractor_routes.py index fa1f0e6..9de484e 100644 --- a/app/routes/subcontractor_routes.py +++ b/app/routes/subcontractor_routes.py @@ -37,6 +37,7 @@ def save_subcontractor(): subcontractor = Subcontractor( subcontractor_name=name, contact_person=request.form.get("contact_person"), + address=request.form.get("address"), mobile_no=request.form.get("mobile_no"), email_id=request.form.get("email_id"), gst_no=request.form.get("gst_no") @@ -115,6 +116,7 @@ def update_subcontractor(id): subcontractor.subcontractor_name = new_name subcontractor.contact_person = request.form.get("contact_person") + subcontractor.address = request.form.get("address") subcontractor.mobile_no = request.form.get("mobile_no") subcontractor.email_id = request.form.get("email_id") subcontractor.gst_no = request.form.get("gst_no") diff --git a/app/templates/client_report.html b/app/templates/client_report.html index ab95e43..9426901 100644 --- a/app/templates/client_report.html +++ b/app/templates/client_report.html @@ -71,4 +71,5 @@ {% endif %} - {% endblock %} \ No newline at end of file + +{% endblock %} \ No newline at end of file diff --git a/app/templates/subcontractor/add.html b/app/templates/subcontractor/add.html index b059196..68e5c36 100644 --- a/app/templates/subcontractor/add.html +++ b/app/templates/subcontractor/add.html @@ -16,6 +16,11 @@ +