Compare commits
2 Commits
9cec54c929
...
2afd6c904a
| Author | SHA1 | Date | |
|---|---|---|---|
| 2afd6c904a | |||
| f2f3a689bb |
@@ -11,16 +11,20 @@ def create_app():
|
|||||||
db.init_app(app)
|
db.init_app(app)
|
||||||
|
|
||||||
# Register Blueprints
|
# Register Blueprints
|
||||||
|
from app.routes.subcontractor_routes import subcontractor_bp
|
||||||
from app.routes.dashboard import dashboard_bp
|
from app.routes.dashboard import dashboard_bp
|
||||||
from app.routes.file_import import file_import_bp
|
from app.routes.file_import import file_import_bp
|
||||||
# from app.routes.user import user_bp
|
# from app.routes.user import user_bp
|
||||||
|
from app.routes.file_report import file_report_bp
|
||||||
|
|
||||||
|
|
||||||
|
app.register_blueprint(subcontractor_bp)
|
||||||
app.register_blueprint(dashboard_bp)
|
app.register_blueprint(dashboard_bp)
|
||||||
app.register_blueprint(file_import_bp)
|
app.register_blueprint(file_import_bp)
|
||||||
# app.register_blueprint(user_bp)
|
# app.register_blueprint(user_bp)
|
||||||
|
app.register_blueprint(file_report_bp)
|
||||||
|
|
||||||
|
|
||||||
from app.routes.subcontractor_routes import subcontractor_bp
|
|
||||||
app.register_blueprint(subcontractor_bp)
|
|
||||||
|
|
||||||
return app
|
return app
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
BIN
app/routes/__pycache__/file_download.cpython-313.pyc
Normal file
BIN
app/routes/__pycache__/file_download.cpython-313.pyc
Normal file
Binary file not shown.
BIN
app/routes/__pycache__/file_report.cpython-313.pyc
Normal file
BIN
app/routes/__pycache__/file_report.cpython-313.pyc
Normal file
Binary file not shown.
22
app/routes/file_report.py
Normal file
22
app/routes/file_report.py
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
# app/routes/file_report.py
|
||||||
|
|
||||||
|
from flask import Blueprint, render_template, request, flash
|
||||||
|
from app.models.subcontractor_model import Subcontractor
|
||||||
|
|
||||||
|
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()
|
||||||
|
|
||||||
|
if request.method == "POST":
|
||||||
|
subcontractor_id = request.form.get("subcontractor_id")
|
||||||
|
|
||||||
|
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", title="Report Download", subcontractors=subcontractors)
|
||||||
|
|
||||||
|
return render_template("report.html", title="Report Download", subcontractors=subcontractors)
|
||||||
Binary file not shown.
@@ -52,7 +52,7 @@ class FileService:
|
|||||||
|
|
||||||
# Manhole and Domestic Chamber Construction save
|
# Manhole and Domestic Chamber Construction save
|
||||||
if file_type == "manhole_domestic_chamber":
|
if file_type == "manhole_domestic_chamber":
|
||||||
return self.process_manhole_excavation(df, subcontractor_id)
|
return self.process_manhole_domestic_chamber(df, subcontractor_id)
|
||||||
|
|
||||||
|
|
||||||
return True, "File uploaded successfully."
|
return True, "File uploaded successfully."
|
||||||
@@ -64,17 +64,12 @@ class FileService:
|
|||||||
|
|
||||||
# Trench Excavation save method (TrenchExcavation model)
|
# Trench Excavation save method (TrenchExcavation model)
|
||||||
def process_trench_excavation(self, df, subcontractor_id):
|
def process_trench_excavation(self, df, subcontractor_id):
|
||||||
|
|
||||||
# Clean column names (strip whitespace)
|
|
||||||
df.columns = [str(c).strip() for c in df.columns]
|
df.columns = [str(c).strip() for c in df.columns]
|
||||||
|
|
||||||
# If the sheet has merged cells -> forward fill Location
|
# If the sheet has merged cells -> forward fill Location
|
||||||
if "Location" in df.columns:
|
if "Location" in df.columns:
|
||||||
df["Location"] = df["Location"].ffill()
|
df["Location"] = df["Location"].ffill()
|
||||||
|
|
||||||
# REMOVE empty rows
|
df = df.dropna(how="all") # REMOVE empty rows
|
||||||
df = df.dropna(how="all")
|
|
||||||
|
|
||||||
# Identify missing location rows before insert
|
# Identify missing location rows before insert
|
||||||
missing_loc = df[df["Location"].isna() | (df["Location"].astype(str).str.strip() == "")]
|
missing_loc = df[df["Location"].isna() | (df["Location"].astype(str).str.strip() == "")]
|
||||||
if not missing_loc.empty:
|
if not missing_loc.empty:
|
||||||
@@ -84,14 +79,11 @@ class FileService:
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
for index, row in df.iterrows():
|
for index, row in df.iterrows():
|
||||||
|
|
||||||
record_data = {}
|
record_data = {}
|
||||||
|
|
||||||
# Insert only fields that exist in model
|
# Insert only fields that exist in model
|
||||||
for col in df.columns:
|
for col in df.columns:
|
||||||
if hasattr(TrenchExcavation, col):
|
if hasattr(TrenchExcavation, col):
|
||||||
value = row[col]
|
value = row[col]
|
||||||
|
|
||||||
# Normalize empty values
|
# Normalize empty values
|
||||||
if pd.isna(value) or str(value).strip() in ["", "-", "—", "nan", "NaN"]:
|
if pd.isna(value) or str(value).strip() in ["", "-", "—", "nan", "NaN"]:
|
||||||
value = None
|
value = None
|
||||||
@@ -116,17 +108,14 @@ class FileService:
|
|||||||
|
|
||||||
# Manhole Excavation save method (ManholeExcavation model)
|
# Manhole Excavation save method (ManholeExcavation model)
|
||||||
def process_manhole_excavation(self, df, subcontractor_id):
|
def process_manhole_excavation(self, df, subcontractor_id):
|
||||||
|
|
||||||
# Clean column names (strip whitespace)
|
# Clean column names (strip whitespace)
|
||||||
df.columns = [str(c).strip() for c in df.columns]
|
df.columns = [str(c).strip() for c in df.columns]
|
||||||
|
|
||||||
# If the sheet has merged cells -> forward fill Location
|
# If the sheet has merged cells -> forward fill Location
|
||||||
if "Location" in df.columns:
|
if "Location" in df.columns:
|
||||||
df["Location"] = df["Location"].ffill()
|
df["Location"] = df["Location"].ffill()
|
||||||
|
|
||||||
# REMOVE empty rows
|
# REMOVE empty rows
|
||||||
df = df.dropna(how="all")
|
df = df.dropna(how="all")
|
||||||
|
|
||||||
# Identify missing location rows before insert
|
# Identify missing location rows before insert
|
||||||
missing_loc = df[df["Location"].isna() | (df["Location"].astype(str).str.strip() == "")]
|
missing_loc = df[df["Location"].isna() | (df["Location"].astype(str).str.strip() == "")]
|
||||||
if not missing_loc.empty:
|
if not missing_loc.empty:
|
||||||
@@ -136,9 +125,7 @@ class FileService:
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
for index, row in df.iterrows():
|
for index, row in df.iterrows():
|
||||||
|
|
||||||
record_data = {}
|
record_data = {}
|
||||||
|
|
||||||
# Insert only fields that exist in model
|
# Insert only fields that exist in model
|
||||||
for col in df.columns:
|
for col in df.columns:
|
||||||
if hasattr(ManholeExcavation, col):
|
if hasattr(ManholeExcavation, col):
|
||||||
@@ -167,18 +154,15 @@ class FileService:
|
|||||||
|
|
||||||
|
|
||||||
# Manhole and Domestic Chamber Construction save method (ManholeDomesticChamber model)
|
# Manhole and Domestic Chamber Construction save method (ManholeDomesticChamber model)
|
||||||
def process_manhole_excavation(self, df, subcontractor_id):
|
def process_manhole_domestic_chamber(self, df, subcontractor_id):
|
||||||
|
|
||||||
# Clean column names (strip whitespace)
|
# Clean column names (strip whitespace)
|
||||||
df.columns = [str(c).strip() for c in df.columns]
|
df.columns = [str(c).strip() for c in df.columns]
|
||||||
|
|
||||||
# If the sheet has merged cells -> forward fill Location
|
# If the sheet has merged cells -> forward fill Location
|
||||||
if "Location" in df.columns:
|
if "Location" in df.columns:
|
||||||
df["Location"] = df["Location"].ffill()
|
df["Location"] = df["Location"].ffill()
|
||||||
|
|
||||||
# REMOVE empty rows
|
# REMOVE empty rows
|
||||||
df = df.dropna(how="all")
|
df = df.dropna(how="all")
|
||||||
|
|
||||||
# Identify missing location rows before insert
|
# Identify missing location rows before insert
|
||||||
missing_loc = df[df["Location"].isna() | (df["Location"].astype(str).str.strip() == "")]
|
missing_loc = df[df["Location"].isna() | (df["Location"].astype(str).str.strip() == "")]
|
||||||
if not missing_loc.empty:
|
if not missing_loc.empty:
|
||||||
@@ -188,14 +172,12 @@ class FileService:
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
for index, row in df.iterrows():
|
for index, row in df.iterrows():
|
||||||
|
|
||||||
record_data = {}
|
record_data = {}
|
||||||
|
|
||||||
# Insert only fields that exist in model
|
# Insert only fields that exist in model
|
||||||
for col in df.columns:
|
for col in df.columns:
|
||||||
if hasattr(ManholeDomesticChamber, col):
|
if hasattr(ManholeDomesticChamber, col):
|
||||||
value = row[col]
|
value = row[col]
|
||||||
|
|
||||||
# Normalize empty values
|
# Normalize empty values
|
||||||
if pd.isna(value) or str(value).strip() in ["", "-", "—", "nan", "NaN"]:
|
if pd.isna(value) or str(value).strip() in ["", "-", "—", "nan", "NaN"]:
|
||||||
value = None
|
value = None
|
||||||
@@ -222,4 +204,3 @@ class FileService:
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -25,8 +25,8 @@
|
|||||||
|
|
||||||
<li class="nav-item"><a class="nav-link" href="/dashboard">Dashboard</a></li>
|
<li class="nav-item"><a class="nav-link" href="/dashboard">Dashboard</a></li>
|
||||||
<li class="nav-item"><a class="nav-link" href="/file/import">File Import</a></li>
|
<li class="nav-item"><a class="nav-link" href="/file/import">File Import</a></li>
|
||||||
<!-- <li class="nav-item"><a class="nav-link" href="/user/list">Users</a></li> -->
|
<li class="nav-item"><a class="nav-link" href="/file/report">Reports Download</a></li>
|
||||||
<!-- <li class="nav-item"><a class="nav-link" href="/subcontractor/add">Subcontractor</a></li> -->
|
|
||||||
<li class="nav-item dropdown">
|
<li class="nav-item dropdown">
|
||||||
<a class="nav-link dropdown-toggle" data-bs-toggle="dropdown" href="#">Subcontractor</a>
|
<a class="nav-link dropdown-toggle" data-bs-toggle="dropdown" href="#">Subcontractor</a>
|
||||||
|
|
||||||
@@ -37,6 +37,7 @@
|
|||||||
</li>
|
</li>
|
||||||
<li class="nav-item"><a class="nav-link" href="/user/list">Users</a></li>
|
<li class="nav-item"><a class="nav-link" href="/user/list">Users</a></li>
|
||||||
|
|
||||||
|
<!-- <li class="nav-item"><a class="nav-link" href="/user/list">Users</a></li> -->
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
24
app/templates/report.html
Normal file
24
app/templates/report.html
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
{% extends "base.html" %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<h2 class="mb-4">File Report</h2>
|
||||||
|
|
||||||
|
<div class="card p-4 shadow-sm">
|
||||||
|
|
||||||
|
<form method="POST">
|
||||||
|
|
||||||
|
<!-- SELECT SUBCONTRACTOR -->
|
||||||
|
<label class="form-label">Select Subcontractor</label>
|
||||||
|
<select name="subcontractor_id" id="subcontractor_id" class="form-select mb-3" required>
|
||||||
|
<option value="">-- Select Subcontractor --</option>
|
||||||
|
|
||||||
|
{% for sc in subcontractors %}
|
||||||
|
<option value="{{ sc.id }}">{{ sc.subcontractor_name }}</option>
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<button class="btn btn-primary w-100">Generate Report</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
Reference in New Issue
Block a user