All model filter are work and show bar chat and data table.

This commit is contained in:
2026-07-31 16:43:38 +05:30
parent 604e948986
commit 2d7d146ec3
3 changed files with 546 additions and 212 deletions

View File

@@ -22,6 +22,9 @@ from app.models.laying_model import Laying
# client models import # client models import
from app.models.tr_ex_client_model import TrenchExcavationClient from app.models.tr_ex_client_model import TrenchExcavationClient
from app.models.mh_ex_client_model import ManholeExcavationClient
from app.models.mh_dc_client_model import ManholeDomesticChamberClient
from app.models.laying_client_model import LayingClient
dashboard_bp = Blueprint("dashboard", __name__, url_prefix="/dashboard") dashboard_bp = Blueprint("dashboard", __name__, url_prefix="/dashboard")
@@ -71,7 +74,6 @@ def live_stats():
# subcontractor dashboard # subcontractor dashboard
@dashboard_bp.route("/subcontractor_dashboard") @dashboard_bp.route("/subcontractor_dashboard")
@login_required @login_required
@@ -137,7 +139,8 @@ def get_ra_bills():
def total(records, field): def total(records, field):
return float(sum(getattr(r, field) or 0 for r in records)) return float(sum(getattr(r, field) or 0 for r in records))
@dashboard_bp.route("/api/trench-analysis") # category= trench_excavation
@dashboard_bp.route("/api/tr-analysis")
def trench_analysis(): def trench_analysis():
subcontractor_id = request.args.get("subcontractor", "").strip() subcontractor_id = request.args.get("subcontractor", "").strip()
@@ -175,7 +178,6 @@ def trench_analysis():
if sub_keys: if sub_keys:
client_query = client_query.filter( client_query = client_query.filter(
tuple_( tuple_(
func.upper(func.trim(TrenchExcavationClient.MH_NO)), func.upper(func.trim(TrenchExcavationClient.MH_NO)),
func.upper(func.trim(TrenchExcavationClient.Location)) func.upper(func.trim(TrenchExcavationClient.Location))
@@ -186,7 +188,144 @@ def trench_analysis():
client_records = client_query.all() client_records = client_query.all()
chart_data = [ chart_data = [
{
"label": "Marshi 0 to 1.5",
"client": total(client_records, "Marshi_Muddy_Slushy_0_to_1_5_total"),
"sub": 0
},
{
"label": "Marshi 1.5 to 3.0",
"client": total(client_records, "Marshi_Muddy_Slushy_1_5_to_3_0_total"),
"sub": 0
},
{
"label": "Marshi 3.0 to 4.5",
"client": total(client_records, "Marshi_Muddy_Slushy_3_0_to_4_5_total"),
"sub": 0
},
{
"label": "Soft Murum 0 to 1.5",
"client": total(client_records, "Soft_Murum_0_to_1_5_total"),
"sub": total(sub_records, "Soft_Murum_0_to_1_5_total")
},
{
"label": "Soft Murum 1.5 to 3.0",
"client": total(client_records, "Soft_Murum_1_5_to_3_0_total"),
"sub": total(sub_records, "Soft_Murum_1_5_to_3_0_total")
},
{
"label": "Soft Murum 3.0 to 4.5",
"client": total(client_records, "Soft_Murum_3_0_to_4_5_total"),
"sub": total(sub_records, "Soft_Murum_3_0_to_4_5_total")
},
{
"label": "Hard Murum 0 to 1.5",
"client": total(client_records, "Hard_Murum_0_to_1_5_total"),
"sub": total(sub_records, "Hard_Murum_0_to_1_5_total")
},
{
"label": "Hard Murum 1.5 to 3.0",
"client": total(client_records, "Hard_Murum_1_5_to_3_0_total"),
"sub": total(sub_records, "Hard_Murum_1_5_and_above_total")
},
{
"label": "Soft Rock 0 to 1.5",
"client": total(client_records, "Soft_Rock_0_to_1_5_total"),
"sub": total(sub_records, "Soft_Rock_0_to_1_5_total")
},
{
"label": "Soft Rock 1.5 to 3.0",
"client": total(client_records, "Soft_Rock_1_5_to_3_0_total"),
"sub": total(sub_records, "Soft_Rock_1_5_and_above_total")
},
{
"label": "Hard Rock 0 to 1.5",
"client": total(client_records, "Hard_Rock_0_to_1_5_total"),
"sub": total(sub_records, "Hard_Rock_0_to_1_5_total")
},
{
"label": "Hard Rock 1.5 to 3.0",
"client": total(client_records, "Hard_Rock_1_5_to_3_0_total"),
"sub": total(sub_records, "Hard_Rock_1_5_to_3_0_total")
},
{
"label": "Hard Rock 3.0 to 4.5",
"client": total(client_records, "Hard_Rock_3_0_to_4_5_total"),
"sub": total(sub_records, "Hard_Rock_3_0_to_4_5_total")
},
{
"label": "Hard Rock 4.5 to 6.0",
"client": total(client_records, "Hard_Rock_4_5_to_6_0_total"),
"sub": total(sub_records, "Hard_Rock_4_5_to_6_0_total")
},
{
"label": "Hard Rock 6.0 to 7.5",
"client": total(client_records, "Hard_Rock_6_0_to_7_5_total"),
"sub": total(sub_records, "Hard_Rock_6_0_to_7_5_total")
}
]
return jsonify({
"title": "Trench Excavation Comparison",
"y_title": "Excavation Qty (Cum)",
"labels": [x["label"] for x in chart_data],
"client_qty": [x["client"] for x in chart_data],
"sub_qty": [x["sub"] for x in chart_data]
})
# category = manhole_excavation
@dashboard_bp.route("/api/mh-analysis")
def manhole_analysis():
subcontractor_id = request.args.get("subcontractor", "").strip()
ra_bill = request.args.get("ra_bill", "").strip()
# Convert "1,2,3" -> ["1", "2", "3"]
ra_bill_list = []
if ra_bill:
ra_bill_list = [x.strip() for x in ra_bill.split(",") if x.strip()]
# Subcontractor Query
sub_query = ManholeExcavation.query
if subcontractor_id:
sub_query = sub_query.filter(
ManholeExcavation.subcontractor_id == int(subcontractor_id)
)
if ra_bill_list:
sub_query = sub_query.filter(
ManholeExcavation.RA_Bill_No.in_(ra_bill_list)
)
sub_records = sub_query.all()
sub_keys = [
(
(r.MH_NO or "").strip().upper(),
(r.Location or "").strip().upper()
)
for r in sub_records
]
client_query = ManholeExcavationClient.query
if sub_keys:
client_query = client_query.filter(
tuple_(
func.upper(func.trim(ManholeExcavationClient.MH_NO)),
func.upper(func.trim(ManholeExcavationClient.Location))
).in_(sub_keys)
)
client_records = client_query.all()
chart_data = [
{ {
"label": "Marshi 0 to 1.5", "label": "Marshi 0 to 1.5",
"client": total(client_records, "Marshi_Muddy_Slushy_0_to_1_5_total"), "client": total(client_records, "Marshi_Muddy_Slushy_0_to_1_5_total"),
@@ -269,8 +408,207 @@ def trench_analysis():
] ]
return jsonify({ return jsonify({
"title": "Manhole Excavation Comparison",
"y_title": "Manhole Qty (Nos)",
"labels": [x["label"] for x in chart_data], "labels": [x["label"] for x in chart_data],
"client_qty": [x["client"] for x in chart_data], "client_qty": [x["client"] for x in chart_data],
"sub_qty": [x["sub"] for x in chart_data] "sub_qty": [x["sub"] for x in chart_data]
}) })
# category = Manhole_Domestic_Chamber
@dashboard_bp.route("/api/mdc-analysis")
def Manhole_Domestic_Chamber_analysis():
subcontractor_id = request.args.get("subcontractor", "").strip()
ra_bill = request.args.get("ra_bill", "").strip()
# Convert "1,2,3" -> ["1", "2", "3"]
ra_bill_list = []
if ra_bill:
ra_bill_list = [x.strip() for x in ra_bill.split(",") if x.strip()]
# Subcontractor Query
sub_query = ManholeDomesticChamber.query
if subcontractor_id:
sub_query = sub_query.filter(
ManholeDomesticChamber.subcontractor_id == int(subcontractor_id)
)
if ra_bill_list:
sub_query = sub_query.filter(
ManholeDomesticChamber.RA_Bill_No.in_(ra_bill_list)
)
sub_records = sub_query.all()
sub_keys = [
(
(r.MH_NO or "").strip().upper(),
(r.Location or "").strip().upper()
)
for r in sub_records
]
client_query = ManholeDomesticChamberClient.query
if sub_keys:
client_query = client_query.filter(
tuple_(
func.upper(func.trim(ManholeDomesticChamberClient.MH_NO)),
func.upper(func.trim(ManholeDomesticChamberClient.Location))
).in_(sub_keys)
)
client_records = client_query.all()
chart_data = [
{
"label": "Depth of MH",
"client": total(client_records, "Depth_of_MH"),
"sub": total(sub_records, "Depth_of_MH")
},
{
"label": "Domestic_Chambers Total",
"client": total(client_records, "Total"),
"sub": total(sub_records, "Total")
}
]
return jsonify({
"title": "Domestic Chamber Comparison",
"y_title": "Quantity (Nos)",
"labels": [x["label"] for x in chart_data],
"client_qty": [x["client"] for x in chart_data],
"sub_qty": [x["sub"] for x in chart_data]
})
# category = Laying
@dashboard_bp.route("/api/laying-analysis")
def laying_analysis():
subcontractor_id = request.args.get("subcontractor", "").strip()
ra_bill = request.args.get("ra_bill", "").strip()
# Convert "1,2,3" -> ["1", "2", "3"]
ra_bill_list = []
if ra_bill:
ra_bill_list = [x.strip() for x in ra_bill.split(",") if x.strip()]
# Subcontractor Query
sub_query = Laying.query
if subcontractor_id:
sub_query = sub_query.filter(
Laying.subcontractor_id == int(subcontractor_id)
)
if ra_bill_list:
sub_query = sub_query.filter(
Laying.RA_Bill_No.in_(ra_bill_list)
)
sub_records = sub_query.all()
sub_keys = [
(
(r.MH_NO or "").strip().upper(),
(r.Location or "").strip().upper()
)
for r in sub_records
]
client_query = LayingClient.query
if sub_keys:
client_query = client_query.filter(
tuple_(
func.upper(func.trim(LayingClient.MH_NO)),
func.upper(func.trim(LayingClient.Location))
).in_(sub_keys)
)
client_records = client_query.all()
chart_data = [
{
"label": "150 mm",
"client": total(client_records, "pipe_150_mm"),
"sub": total(sub_records, "pipe_150_mm")
},
{
"label": "200 mm",
"client": total(client_records, "pipe_200_mm"),
"sub": total(sub_records, "pipe_200_mm")
},
{
"label": "250 mm",
"client": total(client_records, "pipe_250_mm"),
"sub": total(sub_records, "pipe_250_mm")
},
{
"label": "300 mm",
"client": total(client_records, "pipe_300_mm"),
"sub": total(sub_records, "pipe_300_mm")
},
{
"label": "350 mm",
"client": total(client_records, "pipe_350_mm"),
"sub": total(sub_records, "pipe_350_mm")
},
{
"label": "400 mm",
"client": total(client_records, "pipe_400_mm"),
"sub": total(sub_records, "pipe_400_mm")
},
{
"label": "450 mm",
"client": total(client_records, "pipe_450_mm"),
"sub": total(sub_records, "pipe_450_mm")
},
{
"label": "500 mm",
"client": total(client_records, "pipe_500_mm"),
"sub": total(sub_records, "pipe_500_mm")
},
{
"label": "600 mm",
"client": total(client_records, "pipe_600_mm"),
"sub": total(sub_records, "pipe_600_mm")
},
{
"label": "700 mm",
"client": total(client_records, "pipe_700_mm"),
"sub": total(sub_records, "pipe_700_mm")
},
{
"label": "900 mm",
"client": total(client_records, "pipe_900_mm"),
"sub": total(sub_records, "pipe_900_mm")
},
{
"label": "1200 mm",
"client": total(client_records, "pipe_1200_mm"),
"sub": total(sub_records, "pipe_1200_mm")
}
]
return jsonify({
"title": "Pipe Laying Comparison",
"y_title": "Pipe Length (Mtr)",
"labels": [x["label"] for x in chart_data],
"client_qty": [x["client"] for x in chart_data],
"sub_qty": [x["sub"] for x in chart_data]
})

View File

@@ -1,204 +1,204 @@
from collections import defaultdict # from collections import defaultdict
import pandas as pd # import pandas as pd
from app.utils.regex_utils import RegularExpression # from app.utils.regex_utils import RegularExpression
class ComparisonService: # class ComparisonService:
TRENCH_MAPPING = [ # TRENCH_MAPPING = [
{ # {
"label": "Marshi 0 to 1.5", # "label": "Marshi 0 to 1.5",
"client": "Client_Marshi_Muddy_Slushy_0_to_1_5_total", # "client": "Client_Marshi_Muddy_Slushy_0_to_1_5_total",
"sub": None # "sub": None
}, # },
{ # {
"label": "Marshi 1.5 to 3.0", # "label": "Marshi 1.5 to 3.0",
"client": "Client_Marshi_Muddy_Slushy_1_5_to_3_0_total", # "client": "Client_Marshi_Muddy_Slushy_1_5_to_3_0_total",
"sub": None # "sub": None
}, # },
{ # {
"label": "Marshi 3.0 to 4.5", # "label": "Marshi 3.0 to 4.5",
"client": "Client_Marshi_Muddy_Slushy_3_0_to_4_5_total", # "client": "Client_Marshi_Muddy_Slushy_3_0_to_4_5_total",
"sub": None # "sub": None
}, # },
{ # {
"label": "Soft Murum 0 to 1.5", # "label": "Soft Murum 0 to 1.5",
"client": "Client_Soft_Murum_0_to_1_5_total", # "client": "Client_Soft_Murum_0_to_1_5_total",
"sub": "Sub_Soft_Murum_0_to_1_5_total" # "sub": "Sub_Soft_Murum_0_to_1_5_total"
}, # },
{ # {
"label": "Soft Murum 1.5 to 3.0", # "label": "Soft Murum 1.5 to 3.0",
"client": "Client_Soft_Murum_1_5_to_3_0_total", # "client": "Client_Soft_Murum_1_5_to_3_0_total",
"sub": "Sub_Soft_Murum_1_5_to_3_0_total" # "sub": "Sub_Soft_Murum_1_5_to_3_0_total"
}, # },
{ # {
"label": "Soft Murum 3.0 to 4.5", # "label": "Soft Murum 3.0 to 4.5",
"client": "Client_Soft_Murum_3_0_to_4_5_total", # "client": "Client_Soft_Murum_3_0_to_4_5_total",
"sub": "Sub_Soft_Murum_3_0_to_4_5_total" # "sub": "Sub_Soft_Murum_3_0_to_4_5_total"
}, # },
{ # {
"label": "Hard Murum 0 to 1.5", # "label": "Hard Murum 0 to 1.5",
"client": "Client_Hard_Murum_0_to_1_5_total", # "client": "Client_Hard_Murum_0_to_1_5_total",
"sub": "Sub_Hard_Murum_0_to_1_5_total" # "sub": "Sub_Hard_Murum_0_to_1_5_total"
}, # },
{ # {
"label": "Hard Murum 1.5+", # "label": "Hard Murum 1.5+",
"client": "Client_Hard_Murum_1_5_to_3_0_total", # "client": "Client_Hard_Murum_1_5_to_3_0_total",
"sub": "Sub_Hard_Murum_1_5_and_above_total" # "sub": "Sub_Hard_Murum_1_5_and_above_total"
}, # },
{ # {
"label": "Soft Rock 0 to 1.5", # "label": "Soft Rock 0 to 1.5",
"client": "Client_Soft_Rock_0_to_1_5_total", # "client": "Client_Soft_Rock_0_to_1_5_total",
"sub": "Sub_Soft_Rock_0_to_1_5_total" # "sub": "Sub_Soft_Rock_0_to_1_5_total"
}, # },
{ # {
"label": "Soft Rock 1.5+", # "label": "Soft Rock 1.5+",
"client": "Client_Soft_Rock_1_5_to_3_0_total", # "client": "Client_Soft_Rock_1_5_to_3_0_total",
"sub": "Sub_Soft_Rock_1_5_and_above_total" # "sub": "Sub_Soft_Rock_1_5_and_above_total"
}, # },
{ # {
"label": "Hard Rock 0 to 1.5", # "label": "Hard Rock 0 to 1.5",
"client": "Client_Hard_Rock_0_to_1_5_total", # "client": "Client_Hard_Rock_0_to_1_5_total",
"sub": "Sub_Hard_Rock_0_to_1_5_total" # "sub": "Sub_Hard_Rock_0_to_1_5_total"
}, # },
{ # {
"label": "Hard Rock 1.5 to 3.0", # "label": "Hard Rock 1.5 to 3.0",
"client": "Client_Hard_Rock_1_5_to_3_0_total", # "client": "Client_Hard_Rock_1_5_to_3_0_total",
"sub": "Sub_Hard_Rock_1_5_to_3_0_total" # "sub": "Sub_Hard_Rock_1_5_to_3_0_total"
}, # },
{ # {
"label": "Hard Rock 3.0 to 4.5", # "label": "Hard Rock 3.0 to 4.5",
"client": "Client_Hard_Rock_3_0_to_4_5_total", # "client": "Client_Hard_Rock_3_0_to_4_5_total",
"sub": "Sub_Hard_Rock_3_0_to_4_5_total" # "sub": "Sub_Hard_Rock_3_0_to_4_5_total"
}, # },
{ # {
"label": "Hard Rock 4.5 to 6.0", # "label": "Hard Rock 4.5 to 6.0",
"client": "Client_Hard_Rock_4_5_to_6_0_total", # "client": "Client_Hard_Rock_4_5_to_6_0_total",
"sub": "Sub_Hard_Rock_4_5_to_6_0_total" # "sub": "Sub_Hard_Rock_4_5_to_6_0_total"
}, # },
{ # {
"label": "Hard Rock 6.0 to 7.5", # "label": "Hard Rock 6.0 to 7.5",
"client": "Client_Hard_Rock_6_0_to_7_5_total", # "client": "Client_Hard_Rock_6_0_to_7_5_total",
"sub": "Sub_Hard_Rock_6_0_to_7_5_total" # "sub": "Sub_Hard_Rock_6_0_to_7_5_total"
} # }
] # ]
@staticmethod # @staticmethod
def normalize_key(value): # def normalize_key(value):
if value is None: # if value is None:
return "" # return ""
return str(value).strip().upper() # return str(value).strip().upper()
@classmethod # @classmethod
def make_lookup(cls, rows, key_field): # def make_lookup(cls, rows, key_field):
""" # """
Create lookup dictionary using: # Create lookup dictionary using:
(Location, MH_NO) # (Location, MH_NO)
""" # """
lookup = defaultdict(list) # lookup = defaultdict(list)
for row in rows: # for row in rows:
location = cls.normalize_key(row.get("Location")) # location = cls.normalize_key(row.get("Location"))
key = cls.normalize_key(row.get(key_field)) # key = cls.normalize_key(row.get(key_field))
if location and key: # if location and key:
lookup[(location, key)].append(row) # lookup[(location, key)].append(row)
return lookup # return lookup
@classmethod # @classmethod
def build_comparison(cls, client_rows, subcontractor_rows, key_field="MH_NO"): # def build_comparison(cls, client_rows, subcontractor_rows, key_field="MH_NO"):
subcontractor_lookup = cls.make_lookup( # subcontractor_lookup = cls.make_lookup(
subcontractor_rows, # subcontractor_rows,
key_field # key_field
) # )
used = defaultdict(int) # used = defaultdict(int)
output = [] # output = []
for client in client_rows: # for client in client_rows:
location = cls.normalize_key(client.get("Location")) # location = cls.normalize_key(client.get("Location"))
key = cls.normalize_key(client.get(key_field)) # key = cls.normalize_key(client.get(key_field))
if not location or not key: # if not location or not key:
continue # continue
rows = subcontractor_lookup.get((location, key)) # rows = subcontractor_lookup.get((location, key))
if not rows: # if not rows:
continue # continue
index = used[(location, key)] # index = used[(location, key)]
if index >= len(rows): # if index >= len(rows):
continue # continue
subcontractor = rows[index] # subcontractor = rows[index]
used[(location, key)] += 1 # used[(location, key)] += 1
client_total = sum( # client_total = sum(
float(v or 0) # float(v or 0)
for k, v in client.items() # for k, v in client.items()
if k.endswith("_total") # if k.endswith("_total")
or RegularExpression.D_RANGE_PATTERN.match(k) # or RegularExpression.D_RANGE_PATTERN.match(k)
or RegularExpression.PIPE_MM_PATTERN.match(k) # or RegularExpression.PIPE_MM_PATTERN.match(k)
) # )
subcontractor_total = sum( # subcontractor_total = sum(
float(v or 0) # float(v or 0)
for k, v in subcontractor.items() # for k, v in subcontractor.items()
if k.endswith("_total") # if k.endswith("_total")
or RegularExpression.D_RANGE_PATTERN.match(k) # or RegularExpression.D_RANGE_PATTERN.match(k)
or RegularExpression.PIPE_MM_PATTERN.match(k) # or RegularExpression.PIPE_MM_PATTERN.match(k)
) # )
row = { # row = {
"Location": location, # "Location": location,
key_field: key, # key_field: key,
"Client_Total": round(client_total, 2), # "Client_Total": round(client_total, 2),
"Subcontractor_Total": round(subcontractor_total, 2), # "Subcontractor_Total": round(subcontractor_total, 2),
"Difference": round( # "Difference": round(
client_total - subcontractor_total, # client_total - subcontractor_total,
2 # 2
) # )
} # }
# Client Columns # # Client Columns
for column, value in client.items(): # for column, value in client.items():
if column in [ # if column in [
"id", # "id",
"created_at" # "created_at"
]: # ]:
continue # continue
row[f"Client_{column}"] = value # row[f"Client_{column}"] = value
# Subcontractor Columns # # Subcontractor Columns
for column, value in subcontractor.items(): # for column, value in subcontractor.items():
if column in [ # if column in [
"id", # "id",
"created_at", # "created_at",
"subcontractor_id" # "subcontractor_id"
]: # ]:
continue # continue
row[f"Sub_{column}"] = value # row[f"Sub_{column}"] = value
output.append(row) # output.append(row)
return pd.DataFrame(output) # return pd.DataFrame(output)

View File

@@ -57,54 +57,43 @@
<!-- Contractor --> <!-- Contractor -->
<div class="col-lg-4"> <div class="col-lg-4">
<label class="form-label fw-bold"> Subcontractor </label> <label class="form-label fw-bold"> Subcontractor </label>
<select class="form-select" id="subcontractor"> <select class="form-select" id="subcontractor">
<option value="">--- select contractor ---</option> <option value="">--- select contractor ---</option>
{% for s in subcontractors %} {% for s in subcontractors %}
<option value="{{s.id}}"> <option value="{{s.id}}">
{{s.subcontractor_name}} {{s.subcontractor_name}}
</option> </option>
{% endfor %} {% endfor %}
</select> </select>
</div> </div>
<!-- Category --> <!-- Category -->
<div class="col-lg-4"> <div class="col-lg-4">
<label class="form-label fw-bold">Category</label> <label class="form-label fw-bold">Category</label>
<select class="form-select" id="category"> <select class="form-select" id="category">
<option value="">--- select category ---</option> <option value="">--- select category ---</option>
<option value="trench_excavation">Trench Excavation</option> <option value="trench_excavation">Trench Excavation</option>
<option value="manhole_excavation">Manhole Excavation</option> <option value="manhole_excavation">Manhole Excavation</option>
<option value="laying">Pipe Laying</option> <option value="Manhole_Domestic_Chamber">Manhole Domestic Chamber</option>
<option value="Laying">Pipe Laying</option>
</select> </select>
</div> </div>
<!-- RA Bill --> <!-- RA Bill -->
<div class="col-lg-4"> <div class="col-lg-4">
<label class="form-label fw-bold"> <label class="form-label fw-bold"> RA Bills</label>
RA Bills <select id="ra_bill" class="form-select" multiple></select>
</label>
<select id="ra_bill"
class="form-select"
multiple>
</select>
</div> </div>
</div> </div>
<hr> <hr>
<!-- Search button -->
<button class="btn btn-primary" id="searchBtn"> <button class="btn btn-primary" id="searchBtn">
<i class="bi bi-search"></i>Search <i class="bi bi-search"></i>Search
</button> </button>
<!-- Reset button -->
<button class="btn btn-secondary" id="resetBtn"> <button class="btn btn-secondary" id="resetBtn">
<i class="bi bi-arrow-clockwise"></i>Reset <i class="bi bi-arrow-clockwise"></i>Reset
</button> </button>
@@ -116,7 +105,7 @@
<div class="card-header"> <div class="card-header">
<ul class="nav nav-pills"> <ul class="nav nav-pills">
<!--Bar Chart Tab -->
<li class="nav-item"> <li class="nav-item">
<button class="nav-link active" <button class="nav-link active"
data-bs-toggle="tab" data-bs-toggle="tab"
@@ -124,7 +113,8 @@
<i class="bi bi-bar-chart"></i> Bar Chart <i class="bi bi-bar-chart"></i> Bar Chart
</button> </button>
</li> </li>
<!-- Data Table Tab -->
<li class="nav-item"> <li class="nav-item">
<button class="nav-link" <button class="nav-link"
data-bs-toggle="tab" data-bs-toggle="tab"
@@ -132,31 +122,23 @@
<i class="bi bi-table"></i> Data Table <i class="bi bi-table"></i> Data Table
</button> </button>
</li> </li>
</ul> </ul>
</div> </div>
<div class="card-body"> <div class="card-body">
<div class="tab-content"> <div class="tab-content">
<!-- BAR TAB --> <!-- BAR TAB -->
<div class="tab-pane fade show active" id="barTab"> <div class="tab-pane fade show active" id="barTab">
<div style="height:600px"> <div style="height:600px">
<canvas id="barChart"></canvas> <canvas id="barChart"></canvas>
</div> </div>
</div> </div>
<!-- TABLE TAB --> <!-- TABLE TAB -->
<div class="tab-pane fade" id="tableTab"> <div class="tab-pane fade" id="tableTab">
<div class="table-responsive"> <div class="table-responsive">
<table class="table table-bordered table-hover" id="resultTable"> <table class="table table-bordered table-hover" id="resultTable">
<thead class="table-dark"> <thead class="table-dark">
<tr> <tr>
<th>Sr No</th> <th>Sr No</th>
<th>Strata Type & Depth</th> <th>Strata Type & Depth</th>
@@ -164,22 +146,16 @@
<th class="text-end">Sub Contractor Qty</th> <th class="text-end">Sub Contractor Qty</th>
<th class="text-end">Difference</th> <th class="text-end">Difference</th>
</tr> </tr>
</thead> </thead>
<tbody></tbody> <tbody></tbody>
</table> </table>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script> <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
@@ -239,7 +215,6 @@
/* Search */ /* Search */
function loadDashboard() { function loadDashboard() {
const subcontractor = document.getElementById("subcontractor").value; const subcontractor = document.getElementById("subcontractor").value;
const category = document.getElementById("category").value; const category = document.getElementById("category").value;
@@ -249,14 +224,36 @@
raBills = raBillChoice.getValue(true); raBills = raBillChoice.getValue(true);
} }
fetch(`/dashboard/api/trench-analysis?subcontractor=${subcontractor}&category=${category}&ra_bill=${raBills.join(",")}`) let apiUrl = "";
switch (category) {
case "trench_excavation":
apiUrl = "/dashboard/api/tr-analysis";
break;
case "manhole_excavation":
apiUrl = "/dashboard/api/mh-analysis";
break;
case "Manhole_Domestic_Chamber":
apiUrl = "/dashboard/api/mdc-analysis";
break;
case "Laying":
apiUrl = "/dashboard/api/laying-analysis";
break;
default:
alert("Please select category");
return;
}
fetch(`${apiUrl}?subcontractor=${subcontractor}&category=${category}&ra_bill=${raBills.join(",")}`)
.then(response => response.json()) .then(response => response.json())
.then(data => { .then(data => {
console.log(data);
drawBar(data); drawBar(data);
drawTable(data); drawTable(data);
}) })
.catch(err => console.error(err)); .catch(err => console.error(err));
@@ -301,7 +298,7 @@
plugins: { plugins: {
title: { title: {
display: true, display: true,
text: "Excavation Comparison" text: data.title
}, },
legend: { legend: {
position: "bottom" position: "bottom"
@@ -320,7 +317,7 @@
beginAtZero: true, beginAtZero: true,
title: { title: {
display: true, display: true,
text: "Excavation Qty (Cum)" text: data.y_title
} }
} }
} }
@@ -334,18 +331,17 @@
let html=''; let html='';
for(let i=0;i<data.labels.length;i++){ for(let i=0;i<data.labels.length;i++){
const clientQty = Number(data.client_qty[i] || 0);
const subQty = Number(data.sub_qty[i] || 0);
const diff = clientQty - subQty;
html+=` html+=`
<tr> <tr>
<td class="text-center">${i + 1}</td> <td class="text-center">${i + 1}</td>
<td>${data.labels[i]}</td> <td>${data.labels[i]}</td>
<td class="text-end">${data.client_qty[i]}</td> <td class="text-end">${data.client_qty[i]}</td>
<td class="text-end">${data.sub_qty[i]}</td> <td class="text-end">${data.sub_qty[i]}</td>
<td class="text-end fw-bold ${data.client_qty[i]- data.sub_qty[i] >= 0 ? 'text-success' : 'text-danger'}"> <td class="text-end fw-bold ${diff >= 0 ? 'text-success' : 'text-danger'}">${diff.toFixed(2)}</td>
${data.client_qty[i]- data.sub_qty[i]}
</td>
</tr> </tr>
`; `;