filter task show main task value and main and sub task edit
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -3,7 +3,6 @@ from flask_login import login_user, logout_user, current_user
|
|||||||
from ldap3 import Server, Connection, ALL
|
from ldap3 import Server, Connection, ALL
|
||||||
from app import LDAPUser
|
from app import LDAPUser
|
||||||
|
|
||||||
|
|
||||||
def login_controller():
|
def login_controller():
|
||||||
if current_user.is_authenticated:
|
if current_user.is_authenticated:
|
||||||
return redirect(url_for("main.dashboard"))
|
return redirect(url_for("main.dashboard"))
|
||||||
@@ -56,7 +55,6 @@ def login_controller():
|
|||||||
# return render_template("login.html")
|
# return render_template("login.html")
|
||||||
|
|
||||||
# ldap_user_dn = f"uid={username},ou=users,dc=lcepl,dc=org"
|
# ldap_user_dn = f"uid={username},ou=users,dc=lcepl,dc=org"
|
||||||
|
|
||||||
# try:
|
# try:
|
||||||
# # Connect to LDAP server
|
# # Connect to LDAP server
|
||||||
# # server = Server("openldap", port=389, get_info=ALL)
|
# # server = Server("openldap", port=389, get_info=ALL)
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ from app import db
|
|||||||
def dashboard_controller():
|
def dashboard_controller():
|
||||||
|
|
||||||
selected_block = request.args.getlist('block[]', None)
|
selected_block = request.args.getlist('block[]', None)
|
||||||
|
|
||||||
rate_col = cast(Task.rate, Float)
|
rate_col = cast(Task.rate, Float)
|
||||||
qty_col = cast(Task.in_this_ra_bill_qty, Float)
|
qty_col = cast(Task.in_this_ra_bill_qty, Float)
|
||||||
|
|
||||||
@@ -29,7 +28,6 @@ def dashboard_controller():
|
|||||||
|
|
||||||
if selected_block and "All" not in selected_block:
|
if selected_block and "All" not in selected_block:
|
||||||
query = query.filter(Task.block_name.in_(selected_block))
|
query = query.filter(Task.block_name.in_(selected_block))
|
||||||
|
|
||||||
query = query.group_by(Task.block_name, Task.village_name)
|
query = query.group_by(Task.block_name, Task.village_name)
|
||||||
villages = query.all()
|
villages = query.all()
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,10 @@ from app import db
|
|||||||
from app.models import Task, WorkDetail
|
from app.models import Task, WorkDetail
|
||||||
from app.service.logger import log_activity
|
from app.service.logger import log_activity
|
||||||
|
|
||||||
|
import pandas as pd
|
||||||
|
from flask import request, send_file
|
||||||
|
from io import BytesIO
|
||||||
|
|
||||||
|
|
||||||
def filter_tasks_controller():
|
def filter_tasks_controller():
|
||||||
|
|
||||||
@@ -18,7 +22,7 @@ def filter_tasks_controller():
|
|||||||
# blocks
|
# blocks
|
||||||
if district:
|
if district:
|
||||||
blocks = [b[0] for b in db.session.query(WorkDetail.block)
|
blocks = [b[0] for b in db.session.query(WorkDetail.block)
|
||||||
.filter(WorkDetail.district == district).distinct()]
|
.filter(WorkDetail.district == district).distinct()]
|
||||||
else:
|
else:
|
||||||
blocks = []
|
blocks = []
|
||||||
|
|
||||||
@@ -40,7 +44,7 @@ def filter_tasks_controller():
|
|||||||
query = (
|
query = (
|
||||||
db.session.query(Task)
|
db.session.query(Task)
|
||||||
.join(WorkDetail,
|
.join(WorkDetail,
|
||||||
Task.village_name == WorkDetail.name_of_village)
|
Task.village_name == WorkDetail.name_of_village)
|
||||||
.filter(
|
.filter(
|
||||||
WorkDetail.district == district,
|
WorkDetail.district == district,
|
||||||
WorkDetail.block == block,
|
WorkDetail.block == block,
|
||||||
@@ -95,3 +99,58 @@ def filter_tasks_controller():
|
|||||||
selected_block=block,
|
selected_block=block,
|
||||||
selected_village=village
|
selected_village=village
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def download_filtered_tasks_controller():
|
||||||
|
district = request.args.get('district')
|
||||||
|
block = request.args.get('block')
|
||||||
|
village = request.args.get('village')
|
||||||
|
|
||||||
|
query = (
|
||||||
|
db.session.query(Task)
|
||||||
|
.join(WorkDetail,
|
||||||
|
Task.village_name == WorkDetail.name_of_village)
|
||||||
|
.filter(
|
||||||
|
WorkDetail.district == district,
|
||||||
|
WorkDetail.block == block,
|
||||||
|
WorkDetail.name_of_village == village
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
tasks = query.all()
|
||||||
|
|
||||||
|
data = []
|
||||||
|
for task in tasks:
|
||||||
|
data.append({
|
||||||
|
"Task Name": task.task_name,
|
||||||
|
"Unit": task.unit,
|
||||||
|
"Qty": task.qty,
|
||||||
|
"Rate": task.rate,
|
||||||
|
"BOQ Amount": task.boq_amount,
|
||||||
|
"Prev Billed Qty": task.previous_billed_qty,
|
||||||
|
"Prev Billing Amount": task.previous_billing_amount,
|
||||||
|
"RA Bill Qty": task.in_this_ra_bill_qty,
|
||||||
|
"RA Bill Amount": task.in_this_ra_billing_amount,
|
||||||
|
"Cum Billed Qty": task.cumulative_billed_qty,
|
||||||
|
"Cum Billed Amount": task.cumulative_billed_amount,
|
||||||
|
"Variation Qty": task.variation_qty,
|
||||||
|
"Variation Amount": task.variation_amount,
|
||||||
|
})
|
||||||
|
|
||||||
|
df = pd.DataFrame(data)
|
||||||
|
|
||||||
|
output = BytesIO()
|
||||||
|
df.to_excel(output, index=False, engine='openpyxl')
|
||||||
|
output.seek(0)
|
||||||
|
|
||||||
|
filename = f"{district}_{block}_{village}_tasks.xlsx"
|
||||||
|
|
||||||
|
return send_file(
|
||||||
|
output,
|
||||||
|
download_name=filename,
|
||||||
|
as_attachment=True,
|
||||||
|
mimetype='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
|
||||||
|
)
|
||||||
@@ -5,7 +5,7 @@ from app.models import Task
|
|||||||
from app.service.logger import log_activity
|
from app.service.logger import log_activity
|
||||||
|
|
||||||
|
|
||||||
def generate_report_page_controller():
|
def generate_report_page_controller():
|
||||||
|
|
||||||
selected_district = request.args.get('district')
|
selected_district = request.args.get('district')
|
||||||
selected_block = request.args.get('block')
|
selected_block = request.args.get('block')
|
||||||
|
|||||||
@@ -11,18 +11,20 @@ def recalc_task(task):
|
|||||||
|
|
||||||
prev_qty = float(task.previous_billed_qty or 0)
|
prev_qty = float(task.previous_billed_qty or 0)
|
||||||
ra_qty = float(task.in_this_ra_bill_qty or 0)
|
ra_qty = float(task.in_this_ra_bill_qty or 0)
|
||||||
|
# H = G * E
|
||||||
task.previous_billing_amount = round(prev_qty * rate, 2)
|
task.previous_billing_amount = round(prev_qty * rate, 2)
|
||||||
|
# J = I * E
|
||||||
task.in_this_ra_billing_amount = round(ra_qty * rate, 2)
|
task.in_this_ra_billing_amount = round(ra_qty * rate, 2)
|
||||||
|
# K = I + G
|
||||||
task.cumulative_billed_qty = round(prev_qty + ra_qty, 2)
|
task.cumulative_billed_qty = round(prev_qty + ra_qty, 2)
|
||||||
|
# L = K * E
|
||||||
task.cumulative_billed_amount = round(task.cumulative_billed_qty * rate, 2)
|
task.cumulative_billed_amount = round(task.cumulative_billed_qty * rate, 2)
|
||||||
|
# M = IF(K > D , K - D , 0)
|
||||||
if task.cumulative_billed_qty > qty:
|
if task.cumulative_billed_qty > qty:
|
||||||
task.variation_qty = round(task.cumulative_billed_qty - qty, 2)
|
task.variation_qty = round(task.cumulative_billed_qty - qty, 2)
|
||||||
else:
|
else:
|
||||||
task.variation_qty = 0
|
task.variation_qty = 0
|
||||||
|
# N = M * E
|
||||||
task.variation_amount = round(task.variation_qty * rate, 2)
|
task.variation_amount = round(task.variation_qty * rate, 2)
|
||||||
|
|
||||||
|
|
||||||
@@ -40,116 +42,54 @@ def update_tasks_controller():
|
|||||||
"variation_qty",
|
"variation_qty",
|
||||||
"variation_amount"
|
"variation_amount"
|
||||||
]
|
]
|
||||||
|
|
||||||
for key, new_value in updates.items():
|
for key, new_value in updates.items():
|
||||||
|
|
||||||
if '_' not in key:
|
if '_' not in key:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
field_name, task_id_str = key.rsplit('_', 1)
|
field_name, task_id_str = key.rsplit('_', 1)
|
||||||
|
|
||||||
if not task_id_str.isdigit():
|
if not task_id_str.isdigit():
|
||||||
continue
|
continue
|
||||||
|
|
||||||
task = Task.query.get(int(task_id_str))
|
task = Task.query.get(int(task_id_str))
|
||||||
|
|
||||||
if task:
|
if task:
|
||||||
|
|
||||||
if field_name in formula_fields:
|
if field_name in formula_fields:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
current_value = getattr(task, field_name, None)
|
current_value = getattr(task, field_name, None)
|
||||||
|
|
||||||
if str(current_value) != str(new_value):
|
if str(current_value) != str(new_value):
|
||||||
setattr(task, field_name, new_value)
|
setattr(task, field_name, new_value)
|
||||||
|
|
||||||
recalc_task(task)
|
recalc_task(task)
|
||||||
|
|
||||||
update_count += 1
|
update_count += 1
|
||||||
|
|
||||||
log_activity(
|
log_activity(
|
||||||
current_user.username,
|
current_user.username,
|
||||||
"Task Update",
|
"Task Update",
|
||||||
f"Task ID {task.id} - {field_name} changed to {new_value}"
|
f"Task ID {task.id} - {field_name} changed to {new_value}"
|
||||||
)
|
)
|
||||||
|
|
||||||
if update_count > 0:
|
if update_count > 0:
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
log_activity(
|
log_activity(
|
||||||
current_user.username,
|
current_user.username,
|
||||||
"Database Commit",
|
"Database Commit",
|
||||||
f"{update_count} task field(s) updated"
|
f"{update_count} task field(s) updated"
|
||||||
)
|
)
|
||||||
|
|
||||||
return jsonify({'message': f'count: {update_count} field(s) updated.'})
|
return jsonify({'message': f'count: {update_count} field(s) updated.'})
|
||||||
|
|
||||||
return jsonify({'message': 'No fields were updated.'})
|
return jsonify({'message': 'No fields were updated.'})
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
log_activity(current_user.username, "Error", str(e))
|
log_activity(current_user.username, "Error", str(e))
|
||||||
return jsonify({'error': 'Update failed'}), 500
|
return jsonify({'error': 'Update failed'}), 500
|
||||||
|
|
||||||
|
|
||||||
# # Update tasks route
|
|
||||||
# @main.route('/update_tasks', methods=['POST'])
|
|
||||||
# @login_required
|
|
||||||
# def update_tasks():
|
|
||||||
# try:
|
|
||||||
# updates = request.get_json()
|
|
||||||
# update_count = 0
|
|
||||||
|
|
||||||
# for key, new_value in updates.items():
|
|
||||||
# if '_' not in key:
|
|
||||||
# continue
|
|
||||||
|
|
||||||
# field_name, task_id_str = key.rsplit('_', 1)
|
|
||||||
# if not task_id_str.isdigit():
|
|
||||||
# continue
|
|
||||||
|
|
||||||
# task_id = int(task_id_str)
|
|
||||||
# task = db.session.query(Task).filter_by(id=task_id).first()
|
|
||||||
|
|
||||||
# if task:
|
|
||||||
# current_value = getattr(task, field_name, None)
|
|
||||||
# if current_value != new_value:
|
|
||||||
# setattr(task, field_name, new_value)
|
|
||||||
# update_count += 1
|
|
||||||
# log_activity(current_user.username, "Task Update", f"Task ID {task.id} - {field_name} changed to {new_value}")
|
|
||||||
|
|
||||||
# if update_count > 0:
|
|
||||||
# db.session.commit()
|
|
||||||
# log_activity(current_user.username, "Database Commit", f"{update_count} task field(s) updated")
|
|
||||||
# return jsonify({'message': f'count: {update_count} field(s) updated.'})
|
|
||||||
# else:
|
|
||||||
# return jsonify({'message': 'No fields were updated.'})
|
|
||||||
|
|
||||||
# except Exception as e:
|
|
||||||
# log_activity(current_user.username, "Error", f"Update tasks error: {str(e)}")
|
|
||||||
# return jsonify({'error': 'An error occurred while updating tasks.'}), 500
|
|
||||||
|
|
||||||
|
|
||||||
def display_tasks_controller():
|
def display_tasks_controller():
|
||||||
|
|
||||||
work_details = WorkDetail.query.order_by(
|
work_details = WorkDetail.query.order_by(
|
||||||
WorkDetail.uploaded_at.desc()
|
WorkDetail.uploaded_at.desc()
|
||||||
).first()
|
).first()
|
||||||
|
|
||||||
if not work_details:
|
if not work_details:
|
||||||
log_activity(current_user.username, "Tasks View", "No work details")
|
log_activity(current_user.username, "Tasks View", "No work details")
|
||||||
return "No work details available.", 404
|
return "No work details available.", 404
|
||||||
|
|
||||||
tasks = Task.query.filter_by(
|
tasks = Task.query.filter_by(
|
||||||
district=work_details.district,
|
district=work_details.district,
|
||||||
village_name=work_details.name_of_village,
|
village_name=work_details.name_of_village,
|
||||||
block_name=work_details.block
|
block_name=work_details.block
|
||||||
).order_by(Task.uploaded_at.desc()).all()
|
).order_by(Task.uploaded_at.desc()).all()
|
||||||
|
|
||||||
grouped_tasks = []
|
grouped_tasks = []
|
||||||
current_main_task = None
|
current_main_task = None
|
||||||
|
|
||||||
for task in tasks:
|
for task in tasks:
|
||||||
|
|
||||||
task_data = {
|
task_data = {
|
||||||
"id": task.id,
|
"id": task.id,
|
||||||
"task_name": task.task_name,
|
"task_name": task.task_name,
|
||||||
@@ -168,20 +108,17 @@ def display_tasks_controller():
|
|||||||
"remark": task.remark,
|
"remark": task.remark,
|
||||||
"district": task.district
|
"district": task.district
|
||||||
}
|
}
|
||||||
|
|
||||||
if task.serial_number:
|
if task.serial_number:
|
||||||
task_data["subtasks"] = []
|
task_data["subtasks"] = []
|
||||||
grouped_tasks.append(task_data)
|
grouped_tasks.append(task_data)
|
||||||
current_main_task = task_data
|
current_main_task = task_data
|
||||||
elif current_main_task:
|
elif current_main_task:
|
||||||
current_main_task["subtasks"].append(task_data)
|
current_main_task["subtasks"].append(task_data)
|
||||||
|
|
||||||
log_activity(
|
log_activity(
|
||||||
current_user.username,
|
current_user.username,
|
||||||
"Tasks View",
|
"Tasks View",
|
||||||
f"{work_details.name_of_village}, {work_details.block}"
|
f"{work_details.name_of_village}, {work_details.block}"
|
||||||
)
|
)
|
||||||
|
|
||||||
return render_template(
|
return render_template(
|
||||||
'tasks_display.html',
|
'tasks_display.html',
|
||||||
work_details=work_details,
|
work_details=work_details,
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ from flask import request, redirect, url_for, current_app
|
|||||||
from flask_login import current_user
|
from flask_login import current_user
|
||||||
from app import db
|
from app import db
|
||||||
from app.models import Task, WorkDetail
|
from app.models import Task, WorkDetail
|
||||||
from datetime import datetime
|
|
||||||
from app.service.logger import log_activity
|
from app.service.logger import log_activity
|
||||||
|
|
||||||
# keep helper inside controller
|
# keep helper inside controller
|
||||||
def to_2_decimal(value):
|
def to_2_decimal(value):
|
||||||
try:
|
try:
|
||||||
@@ -15,7 +15,6 @@ def to_2_decimal(value):
|
|||||||
except (TypeError, ValueError):
|
except (TypeError, ValueError):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
def upload_controller():
|
def upload_controller():
|
||||||
if 'file' not in request.files:
|
if 'file' not in request.files:
|
||||||
return "No file part"
|
return "No file part"
|
||||||
@@ -31,7 +30,6 @@ def upload_controller():
|
|||||||
log_activity(current_user.username, "File Upload", f"Uploaded file: {file.filename}")
|
log_activity(current_user.username, "File Upload", f"Uploaded file: {file.filename}")
|
||||||
|
|
||||||
work_details_data = pd.read_excel(filepath, nrows=11, header=None, dtype=str)
|
work_details_data = pd.read_excel(filepath, nrows=11, header=None, dtype=str)
|
||||||
|
|
||||||
work_details_dict = {
|
work_details_dict = {
|
||||||
"name_of_work": work_details_data.iloc[0, 1],
|
"name_of_work": work_details_data.iloc[0, 1],
|
||||||
"cover_agreement_no": work_details_data.iloc[1, 1],
|
"cover_agreement_no": work_details_data.iloc[1, 1],
|
||||||
@@ -45,15 +43,11 @@ def upload_controller():
|
|||||||
"measurement_book": work_details_data.iloc[9, 1],
|
"measurement_book": work_details_data.iloc[9, 1],
|
||||||
"district": work_details_data.iloc[10, 1]
|
"district": work_details_data.iloc[10, 1]
|
||||||
}
|
}
|
||||||
|
|
||||||
work_details_dict = {k: (None if pd.isna(v) else v) for k, v in work_details_dict.items()}
|
work_details_dict = {k: (None if pd.isna(v) else v) for k, v in work_details_dict.items()}
|
||||||
|
|
||||||
work_detail = WorkDetail(**work_details_dict)
|
work_detail = WorkDetail(**work_details_dict)
|
||||||
db.session.add(work_detail)
|
db.session.add(work_detail)
|
||||||
|
|
||||||
data = pd.read_excel(filepath, skiprows=10)
|
data = pd.read_excel(filepath, skiprows=10)
|
||||||
data = data.astype(object).where(pd.notna(data), None)
|
data = data.astype(object).where(pd.notna(data), None)
|
||||||
|
|
||||||
expected_columns = [
|
expected_columns = [
|
||||||
"serial_number", "task_name", "unit", "qty", "rate", "boq_amount",
|
"serial_number", "task_name", "unit", "qty", "rate", "boq_amount",
|
||||||
"previous_billed_qty", "previous_billing_amount",
|
"previous_billed_qty", "previous_billing_amount",
|
||||||
@@ -61,27 +55,21 @@ def upload_controller():
|
|||||||
"cumulative_billed_qty", "cumulative_billed_amount",
|
"cumulative_billed_qty", "cumulative_billed_amount",
|
||||||
"variation_qty", "variation_amount", "remark"
|
"variation_qty", "variation_amount", "remark"
|
||||||
]
|
]
|
||||||
|
|
||||||
if data.shape[1] == len(expected_columns):
|
if data.shape[1] == len(expected_columns):
|
||||||
data.columns = expected_columns
|
data.columns = expected_columns
|
||||||
else:
|
else:
|
||||||
data.columns = expected_columns[:data.shape[1]]
|
data.columns = expected_columns[:data.shape[1]]
|
||||||
|
|
||||||
current_main_task_serial = None
|
current_main_task_serial = None
|
||||||
current_main_task_name = None
|
current_main_task_name = None
|
||||||
|
|
||||||
for _, row in data.iterrows():
|
for _, row in data.iterrows():
|
||||||
|
|
||||||
task_name = str(row["task_name"]) if row["task_name"] else ""
|
task_name = str(row["task_name"]) if row["task_name"] else ""
|
||||||
serial_number = str(row["serial_number"]) if row["serial_number"] else None
|
serial_number = str(row["serial_number"]) if row["serial_number"] else None
|
||||||
|
|
||||||
if serial_number:
|
if serial_number:
|
||||||
current_main_task_serial = serial_number
|
current_main_task_serial = serial_number
|
||||||
current_main_task_name = task_name
|
current_main_task_name = task_name
|
||||||
parent_id = None
|
parent_id = None
|
||||||
else:
|
else:
|
||||||
parent_id = current_main_task_serial
|
parent_id = current_main_task_serial
|
||||||
|
|
||||||
task = Task(
|
task = Task(
|
||||||
district=work_details_dict.get("district"),
|
district=work_details_dict.get("district"),
|
||||||
block_name=work_details_dict["block"],
|
block_name=work_details_dict["block"],
|
||||||
@@ -104,9 +92,7 @@ def upload_controller():
|
|||||||
parent_task_name=current_main_task_name if not serial_number else None,
|
parent_task_name=current_main_task_name if not serial_number else None,
|
||||||
remark=row["remark"]
|
remark=row["remark"]
|
||||||
)
|
)
|
||||||
|
|
||||||
db.session.add(task)
|
db.session.add(task)
|
||||||
|
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
log_activity(
|
log_activity(
|
||||||
@@ -118,97 +104,3 @@ def upload_controller():
|
|||||||
return redirect(url_for('main.display_tasks'))
|
return redirect(url_for('main.display_tasks'))
|
||||||
|
|
||||||
|
|
||||||
# # File upload route
|
|
||||||
# @main.route('/upload', methods=['POST'])
|
|
||||||
# @login_required
|
|
||||||
# def upload():
|
|
||||||
# if 'file' not in request.files:
|
|
||||||
# return "No file part"
|
|
||||||
# file = request.files['file']
|
|
||||||
# if file.filename == '':
|
|
||||||
# return "No selected file"
|
|
||||||
# if file:
|
|
||||||
# filepath = os.path.join(current_app.config['UPLOAD_FOLDER'], file.filename)
|
|
||||||
# file.save(filepath)
|
|
||||||
# log_activity(current_user.username, "File Upload", f"Uploaded file: {file.filename}")
|
|
||||||
|
|
||||||
# # Read work details (first 11 rows)
|
|
||||||
# work_details_data = pd.read_excel(filepath, nrows=11, header=None)
|
|
||||||
# work_details_dict = {
|
|
||||||
|
|
||||||
# "name_of_work": work_details_data.iloc[0, 1],
|
|
||||||
# "cover_agreement_no": work_details_data.iloc[1, 1],
|
|
||||||
# "name_of_contractor": work_details_data.iloc[2, 1],
|
|
||||||
# "name_of_tpi_agency": work_details_data.iloc[3, 1],
|
|
||||||
# "name_of_division": work_details_data.iloc[4, 1],
|
|
||||||
# "name_of_village": work_details_data.iloc[5, 1],
|
|
||||||
# "block": work_details_data.iloc[6, 1],
|
|
||||||
# "scheme_id": work_details_data.iloc[7, 1],
|
|
||||||
# "date_of_billing": work_details_data.iloc[8, 1],
|
|
||||||
# "measurement_book": work_details_data.iloc[9, 1],
|
|
||||||
# "district": work_details_data.iloc[10, 1] # Example: row 11 (index 10), column 2 (index 1)
|
|
||||||
|
|
||||||
# }
|
|
||||||
|
|
||||||
# work_details_dict = {key: (None if pd.isna(value) else value) for key, value in work_details_dict.items()}
|
|
||||||
# work_detail = WorkDetail(**work_details_dict)
|
|
||||||
# db.session.add(work_detail)
|
|
||||||
|
|
||||||
# # Read task data starting from row 12
|
|
||||||
# data = pd.read_excel(filepath, skiprows=10)
|
|
||||||
# data = data.astype(str).replace({"nan": None, "NaT": None, "None": None})
|
|
||||||
|
|
||||||
# expected_columns = [
|
|
||||||
# "serial_number", "task_name", "unit", "qty", "rate", "boq_amount",
|
|
||||||
# "previous_billed_qty", "previous_billing_amount",
|
|
||||||
# "in_this_ra_bill_qty", "in_this_ra_billing_amount",
|
|
||||||
# "cumulative_billed_qty", "cumulative_billed_amount",
|
|
||||||
# "variation_qty", "variation_amount", "remark"
|
|
||||||
# ]
|
|
||||||
|
|
||||||
# if data.shape[1] == len(expected_columns):
|
|
||||||
# data.columns = expected_columns
|
|
||||||
# else:
|
|
||||||
# data.columns = expected_columns[:data.shape[1]] # Truncate
|
|
||||||
|
|
||||||
# current_main_task_serial = None
|
|
||||||
# current_main_task_name = None
|
|
||||||
|
|
||||||
# for _, row in data.iterrows():
|
|
||||||
# task_name = str(row["task_name"]) if row["task_name"] else ""
|
|
||||||
# serial_number = row["serial_number"]
|
|
||||||
|
|
||||||
# if serial_number: # Main task
|
|
||||||
# current_main_task_serial = serial_number
|
|
||||||
# current_main_task_name = task_name
|
|
||||||
# parent_id = None
|
|
||||||
# else: # Subtask
|
|
||||||
# parent_id = current_main_task_serial
|
|
||||||
|
|
||||||
# task = Task(
|
|
||||||
# district=work_details_dict.get("district"),
|
|
||||||
# block_name=work_details_dict["block"],
|
|
||||||
# village_name=work_details_dict["name_of_village"],
|
|
||||||
# serial_number=serial_number,
|
|
||||||
# task_name=task_name,
|
|
||||||
# unit=row["unit"],
|
|
||||||
# qty=row["qty"],
|
|
||||||
# rate=row["rate"],
|
|
||||||
# boq_amount=row["boq_amount"],
|
|
||||||
# previous_billed_qty=row["previous_billed_qty"],
|
|
||||||
# previous_billing_amount=row["previous_billing_amount"],
|
|
||||||
# in_this_ra_bill_qty=row["in_this_ra_bill_qty"],
|
|
||||||
# in_this_ra_billing_amount=row["in_this_ra_billing_amount"],
|
|
||||||
# cumulative_billed_qty=row["cumulative_billed_qty"],
|
|
||||||
# cumulative_billed_amount=row["cumulative_billed_amount"],
|
|
||||||
# variation_qty=row["variation_qty"],
|
|
||||||
# variation_amount=row["variation_amount"],
|
|
||||||
# parent_id=parent_id,
|
|
||||||
# parent_task_name=current_main_task_name if not serial_number else None,
|
|
||||||
# remark=row["remark"]
|
|
||||||
# )
|
|
||||||
# db.session.add(task)
|
|
||||||
|
|
||||||
# db.session.commit()
|
|
||||||
# log_activity(current_user.username, "Database Insert", f"Inserted work details and tasks from {file.filename}")
|
|
||||||
# return redirect(url_for('main.display_tasks'))
|
|
||||||
@@ -97,6 +97,7 @@ def create_app():
|
|||||||
from app.routes.reports import reports as reports_bp
|
from app.routes.reports import reports as reports_bp
|
||||||
app.register_blueprint(main_bp)
|
app.register_blueprint(main_bp)
|
||||||
app.register_blueprint(reports_bp)
|
app.register_blueprint(reports_bp)
|
||||||
|
|
||||||
except ImportError as e:
|
except ImportError as e:
|
||||||
print(f"Error importing blueprints: {e}")
|
print(f"Error importing blueprints: {e}")
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
197
app/activity.log
197
app/activity.log
@@ -4309,3 +4309,200 @@ Timestamp: 2026-04-15 11:51:20 | User: admin | Action: Task Update | Details: Ta
|
|||||||
Timestamp: 2026-04-15 11:51:20 | User: admin | Action: Database Commit | Details: 1 task field(s) updated
|
Timestamp: 2026-04-15 11:51:20 | User: admin | Action: Database Commit | Details: 1 task field(s) updated
|
||||||
Timestamp: 2026-04-15 11:51:21 | User: admin | Action: Filter Tasks | Details: district=Shamli, block=Kandhla, village=Aldi
|
Timestamp: 2026-04-15 11:51:21 | User: admin | Action: Filter Tasks | Details: district=Shamli, block=Kandhla, village=Aldi
|
||||||
Timestamp: 2026-04-15 11:55:04 | User: admin | Action: Filter Tasks | Details: district=Shamli, block=Kandhla, village=Aldi
|
Timestamp: 2026-04-15 11:55:04 | User: admin | Action: Filter Tasks | Details: district=Shamli, block=Kandhla, village=Aldi
|
||||||
|
Timestamp: 2026-04-15 12:34:30 | User: admin | Action: Task Update | Details: Task ID 5 - rate changed to 200025.06
|
||||||
|
Timestamp: 2026-04-15 12:34:30 | User: admin | Action: Database Commit | Details: 1 task field(s) updated
|
||||||
|
Timestamp: 2026-04-15 12:34:30 | User: admin | Action: Filter Tasks | Details: district=Shamli, block=Kandhla, village=Aldi
|
||||||
|
Timestamp: 2026-04-15 12:34:46 | User: admin | Action: Filter Tasks | Details: district=Shamli, block=Kandhla, village=Aldi
|
||||||
|
Timestamp: 2026-04-15 13:22:44 | User: admin | Action: Page Load | Details: Upload Excel page accessed
|
||||||
|
Timestamp: 2026-04-15 13:22:46 | User: admin | Action: Report Page | Details: district=None, block=None
|
||||||
|
Timestamp: 2026-04-15 13:22:58 | User: admin | Action: Filter Tasks | Details: district=Shamli, block=Kandhla, village=Aldi
|
||||||
|
Timestamp: 2026-04-15 13:23:28 | User: admin | Action: Report Page | Details: district=None, block=None
|
||||||
|
Timestamp: 2026-04-15 13:23:31 | User: admin | Action: Fetch Tasks | Details: Fetched tasks for block Kandhla
|
||||||
|
Timestamp: 2026-04-15 13:23:46 | User: admin | Action: Report Page | Details: district=None, block=None
|
||||||
|
Timestamp: 2026-04-15 13:23:51 | User: admin | Action: Fetch Tasks | Details: Fetched tasks for block Kandhla
|
||||||
|
Timestamp: 2026-04-15 13:23:56 | User: admin | Action: Report Page | Details: district=None, block=None
|
||||||
|
Timestamp: 2026-04-15 13:24:00 | User: admin | Action: Fetch Tasks | Details: Fetched tasks for block Kandhla
|
||||||
|
Timestamp: 2026-04-15 13:24:07 | User: admin | Action: Report Page | Details: district=None, block=None
|
||||||
|
Timestamp: 2026-04-15 13:24:11 | User: admin | Action: Fetch Tasks | Details: Fetched tasks for block Kandhla
|
||||||
|
Timestamp: 2026-04-15 13:24:14 | User: admin | Action: Report Page | Details: district=None, block=None
|
||||||
|
Timestamp: 2026-04-15 13:24:19 | User: admin | Action: Fetch Tasks | Details: Fetched tasks for block Kandhla
|
||||||
|
Timestamp: 2026-04-15 13:24:22 | User: admin | Action: Report Page | Details: district=None, block=None
|
||||||
|
Timestamp: 2026-04-15 13:24:25 | User: admin | Action: Fetch Tasks | Details: Fetched tasks for block Kandhla
|
||||||
|
Timestamp: 2026-04-15 13:24:28 | User: admin | Action: Report Page | Details: district=None, block=None
|
||||||
|
Timestamp: 2026-04-15 13:24:31 | User: admin | Action: Fetch Tasks | Details: Fetched tasks for block Kandhla
|
||||||
|
Timestamp: 2026-04-15 13:24:35 | User: admin | Action: Report Page | Details: district=None, block=None
|
||||||
|
Timestamp: 2026-04-15 13:24:39 | User: admin | Action: Fetch Tasks | Details: Fetched tasks for block Kandhla
|
||||||
|
Timestamp: 2026-04-15 13:24:42 | User: admin | Action: Report Page | Details: district=None, block=None
|
||||||
|
Timestamp: 2026-04-15 13:24:46 | User: admin | Action: Fetch Tasks | Details: Fetched tasks for block Kandhla
|
||||||
|
Timestamp: 2026-04-15 13:24:49 | User: admin | Action: Report Page | Details: district=None, block=None
|
||||||
|
Timestamp: 2026-04-15 13:24:53 | User: admin | Action: Fetch Tasks | Details: Fetched tasks for block Kandhla
|
||||||
|
Timestamp: 2026-04-15 13:24:58 | User: admin | Action: Report Page | Details: district=None, block=None
|
||||||
|
Timestamp: 2026-04-15 13:25:02 | User: admin | Action: Fetch Tasks | Details: Fetched tasks for block Kandhla
|
||||||
|
Timestamp: 2026-04-15 13:25:13 | User: admin | Action: Report Page | Details: district=None, block=None
|
||||||
|
Timestamp: 2026-04-15 13:25:22 | User: admin | Action: Filter Tasks | Details: district=Shamli, block=Kandhla, village=Aldi
|
||||||
|
Timestamp: 2026-04-15 13:27:09 | User: admin | Action: Report Page | Details: district=None, block=None
|
||||||
|
Timestamp: 2026-04-15 13:27:12 | User: admin | Action: Fetch Tasks | Details: Fetched tasks for block Kandhla
|
||||||
|
Timestamp: 2026-04-15 13:27:18 | User: admin | Action: Report Page | Details: district=None, block=None
|
||||||
|
Timestamp: 2026-04-15 13:27:21 | User: admin | Action: Fetch Tasks | Details: Fetched tasks for block Kandhla
|
||||||
|
Timestamp: 2026-04-15 13:27:31 | User: admin | Action: Report Page | Details: district=None, block=None
|
||||||
|
Timestamp: 2026-04-15 13:27:54 | User: admin | Action: Fetch Tasks | Details: Fetched tasks for block Kandhla
|
||||||
|
Timestamp: 2026-04-15 13:27:57 | User: admin | Action: Report Page | Details: district=None, block=None
|
||||||
|
Timestamp: 2026-04-15 13:28:08 | User: admin | Action: Fetch Tasks | Details: Fetched tasks for block Kandhla
|
||||||
|
Timestamp: 2026-04-15 13:33:19 | User: admin | Action: Page Load | Details: Upload Excel page accessed
|
||||||
|
Timestamp: 2026-04-15 13:33:25 | User: admin | Action: File Upload | Details: Uploaded file: Asadpur bamnauli.xlsx
|
||||||
|
Timestamp: 2026-04-15 13:33:26 | User: admin | Action: Database Insert | Details: Inserted work details and tasks from Asadpur bamnauli.xlsx
|
||||||
|
Timestamp: 2026-04-15 13:33:26 | User: admin | Action: Tasks View | Details: Asadpur Bamnauli, Kairana
|
||||||
|
Timestamp: 2026-04-15 13:34:33 | User: admin | Action: Report Page | Details: district=None, block=None
|
||||||
|
Timestamp: 2026-04-15 13:34:42 | User: admin | Action: Page Load | Details: Upload Excel page accessed
|
||||||
|
Timestamp: 2026-04-15 13:34:43 | User: admin | Action: Report Page | Details: district=None, block=None
|
||||||
|
Timestamp: 2026-04-15 13:34:50 | User: admin | Action: Report Page | Details: district=None, block=None
|
||||||
|
Timestamp: 2026-04-15 13:34:51 | User: admin | Action: Report Page | Details: district=None, block=None
|
||||||
|
Timestamp: 2026-04-15 13:34:58 | User: admin | Action: Page Load | Details: Upload Excel page accessed
|
||||||
|
Timestamp: 2026-04-15 13:34:59 | User: admin | Action: Report Page | Details: district=None, block=None
|
||||||
|
Timestamp: 2026-04-15 13:35:04 | User: admin | Action: Report Page | Details: district=None, block=None
|
||||||
|
Timestamp: 2026-04-15 13:35:06 | User: admin | Action: Report Page | Details: district=None, block=None
|
||||||
|
Timestamp: 2026-04-15 13:35:09 | User: admin | Action: Fetch Tasks | Details: Fetched tasks for block Kandhla
|
||||||
|
Timestamp: 2026-04-15 13:35:16 | User: admin | Action: Report Page | Details: district=None, block=None
|
||||||
|
Timestamp: 2026-04-15 13:35:22 | User: admin | Action: Fetch Tasks | Details: Fetched tasks for block Kairana
|
||||||
|
Timestamp: 2026-04-15 13:36:02 | User: admin | Action: Filter Tasks | Details: district=Shamli, block=Kandhla, village=Aldi
|
||||||
|
Timestamp: 2026-04-15 13:36:49 | User: admin | Action: Task Update | Details: Task ID 7 - previous_billed_qty changed to 4
|
||||||
|
Timestamp: 2026-04-15 13:36:49 | User: admin | Action: Database Commit | Details: 1 task field(s) updated
|
||||||
|
Timestamp: 2026-04-15 13:36:51 | User: admin | Action: Filter Tasks | Details: district=Shamli, block=Kandhla, village=Aldi
|
||||||
|
Timestamp: 2026-04-15 14:55:01 | User: admin | Action: Report Page | Details: district=None, block=None
|
||||||
|
Timestamp: 2026-04-15 15:40:52 | User: admin | Action: Report Page | Details: district=None, block=None
|
||||||
|
Timestamp: 2026-04-15 15:40:56 | User: admin | Action: Fetch Tasks | Details: Fetched tasks for block Kandhla
|
||||||
|
Timestamp: 2026-04-15 16:38:21 | User: admin | Action: Filter Tasks | Details: district=Shamli, block=Kandhla, village=Aldi
|
||||||
|
Timestamp: 2026-04-15 16:38:31 | User: admin | Action: Task Update | Details: Task ID 5 - previous_billed_qty changed to 3
|
||||||
|
Timestamp: 2026-04-15 16:38:31 | User: admin | Action: Database Commit | Details: 1 task field(s) updated
|
||||||
|
Timestamp: 2026-04-15 16:38:34 | User: admin | Action: Filter Tasks | Details: district=Shamli, block=Kandhla, village=Aldi
|
||||||
|
Timestamp: 2026-04-15 16:39:09 | User: admin | Action: Filter Tasks | Details: district=Shamli, block=Kandhla, village=Aldi
|
||||||
|
Timestamp: 2026-04-15 16:40:13 | User: admin | Action: Filter Tasks | Details: district=Shamli, block=Kandhla, village=Aldi
|
||||||
|
Timestamp: 2026-04-15 17:03:03 | User: admin | Action: Page Load | Details: Upload Excel page accessed
|
||||||
|
Timestamp: 2026-04-15 17:03:05 | User: admin | Action: Report Page | Details: district=None, block=None
|
||||||
|
Timestamp: 2026-04-15 17:03:11 | User: admin | Action: Filter Tasks | Details: district=Shamli, block=Kandhla, village=Aldi
|
||||||
|
Timestamp: 2026-04-15 17:03:24 | User: admin | Action: Report Page | Details: district=None, block=None
|
||||||
|
Timestamp: 2026-04-15 17:03:53 | User: admin | Action: Filter Tasks | Details: district=Shamli, block=Kairana, village=Asadpur Bamnauli
|
||||||
|
Timestamp: 2026-04-15 17:04:32 | User: admin | Action: Fetch Tasks | Details: Fetched tasks for block Kandhla
|
||||||
|
Timestamp: 2026-04-15 17:05:48 | User: admin | Action: Filter Tasks | Details: district=Shamli, block=Kandhla, village=Aldi
|
||||||
|
Timestamp: 2026-04-15 17:06:09 | User: admin | Action: Task Update | Details: Task ID 5 - in_this_ra_bill_qty changed to 5
|
||||||
|
Timestamp: 2026-04-15 17:06:10 | User: admin | Action: Database Commit | Details: 1 task field(s) updated
|
||||||
|
Timestamp: 2026-04-15 17:06:12 | User: admin | Action: Filter Tasks | Details: district=Shamli, block=Kandhla, village=Aldi
|
||||||
|
Timestamp: 2026-04-15 17:06:50 | User: admin | Action: Filter Tasks | Details: district=Shamli, block=Kairana, village=Asadpur Bamnauli
|
||||||
|
Timestamp: 2026-04-15 17:07:05 | User: admin | Action: Report Page | Details: district=None, block=None
|
||||||
|
Timestamp: 2026-04-15 17:07:08 | User: admin | Action: Fetch Tasks | Details: Fetched tasks for block Kairana
|
||||||
|
Timestamp: 2026-04-15 17:08:40 | User: admin | Action: Filter Tasks | Details: district=Shamli, block=Kairana, village=Asadpur Bamnauli
|
||||||
|
Timestamp: 2026-04-16 15:38:01 | User: admin | Action: Page Load | Details: Upload Excel page accessed
|
||||||
|
Timestamp: 2026-04-16 15:38:02 | User: admin | Action: Report Page | Details: district=None, block=None
|
||||||
|
Timestamp: 2026-04-16 15:38:08 | User: admin | Action: Filter Tasks | Details: district=Shamli, block=Kairana, village=Asadpur Bamnauli
|
||||||
|
Timestamp: 2026-04-16 15:40:15 | User: admin | Action: Filter Tasks | Details: district=Shamli, block=Kairana, village=Asadpur Bamnauli
|
||||||
|
Timestamp: 2026-04-16 15:41:52 | User: admin | Action: Page Load | Details: Upload Excel page accessed
|
||||||
|
Timestamp: 2026-04-16 15:45:55 | User: admin | Action: Report Page | Details: district=None, block=None
|
||||||
|
Timestamp: 2026-04-16 15:46:09 | User: admin | Action: Fetch Tasks | Details: Fetched tasks for block Kandhla
|
||||||
|
Timestamp: 2026-04-16 16:43:33 | User: admin | Action: Page Load | Details: Upload Excel page accessed
|
||||||
|
Timestamp: 2026-04-16 16:43:38 | User: admin | Action: Report Page | Details: district=None, block=None
|
||||||
|
Timestamp: 2026-04-16 16:43:57 | User: admin | Action: Filter Tasks | Details: district=Shamli, block=Kandhla, village=Aldi
|
||||||
|
Timestamp: 2026-04-16 16:45:50 | User: admin | Action: Page Load | Details: Upload Excel page accessed
|
||||||
|
Timestamp: 2026-04-16 16:45:56 | User: admin | Action: Page Load | Details: Upload Excel page accessed
|
||||||
|
Timestamp: 2026-04-16 16:45:59 | User: admin | Action: Report Page | Details: district=None, block=None
|
||||||
|
Timestamp: 2026-04-16 16:46:00 | User: admin | Action: Report Page | Details: district=None, block=None
|
||||||
|
Timestamp: 2026-04-16 16:46:01 | User: admin | Action: Page Load | Details: Upload Excel page accessed
|
||||||
|
Timestamp: 2026-04-17 10:39:37 | User: admin | Action: Filter Tasks | Details: district=Shamli, block=Kandhla, village=Aldi
|
||||||
|
Timestamp: 2026-04-17 10:48:16 | User: admin | Action: Task Update | Details: Task ID 9 - previous_billed_qty changed to 5
|
||||||
|
Timestamp: 2026-04-17 10:48:16 | User: admin | Action: Database Commit | Details: 1 task field(s) updated
|
||||||
|
Timestamp: 2026-04-17 10:48:17 | User: admin | Action: Filter Tasks | Details: district=Shamli, block=Kandhla, village=Aldi
|
||||||
|
Timestamp: 2026-04-17 10:56:16 | User: admin | Action: Filter Tasks | Details: district=Shamli, block=Kandhla, village=Aldi
|
||||||
|
Timestamp: 2026-04-17 11:14:15 | User: admin | Action: Report Page | Details: district=None, block=None
|
||||||
|
Timestamp: 2026-04-17 11:14:19 | User: admin | Action: Fetch Tasks | Details: Fetched tasks for block Kandhla
|
||||||
|
Timestamp: 2026-04-17 11:14:26 | User: admin | Action: Report Page | Details: district=None, block=None
|
||||||
|
Timestamp: 2026-04-17 11:14:37 | User: admin | Action: Fetch Tasks | Details: Fetched tasks for block Kandhla
|
||||||
|
Timestamp: 2026-04-17 11:14:43 | User: admin | Action: Report Page | Details: district=None, block=None
|
||||||
|
Timestamp: 2026-04-17 11:14:57 | User: admin | Action: Report Page | Details: district=None, block=None
|
||||||
|
Timestamp: 2026-04-17 11:15:09 | User: admin | Action: Report Page | Details: district=None, block=None
|
||||||
|
Timestamp: 2026-04-17 11:15:12 | User: admin | Action: Fetch Tasks | Details: Fetched tasks for block Kandhla
|
||||||
|
Timestamp: 2026-04-17 11:15:19 | User: admin | Action: Report Page | Details: district=None, block=None
|
||||||
|
Timestamp: 2026-04-17 11:15:26 | User: admin | Action: Report Page | Details: district=None, block=None
|
||||||
|
Timestamp: 2026-04-17 11:15:28 | User: admin | Action: Report Page | Details: district=None, block=None
|
||||||
|
Timestamp: 2026-04-17 11:15:32 | User: admin | Action: Filter Tasks | Details: district=Shamli, block=Kandhla, village=Aldi
|
||||||
|
Timestamp: 2026-04-17 11:15:41 | User: admin | Action: Report Page | Details: district=None, block=None
|
||||||
|
Timestamp: 2026-04-17 11:15:50 | User: admin | Action: Fetch Tasks | Details: Fetched tasks for block Kandhla
|
||||||
|
Timestamp: 2026-04-17 11:16:56 | User: admin | Action: Report Page | Details: district=None, block=None
|
||||||
|
Timestamp: 2026-04-17 11:16:58 | User: admin | Action: Report Page | Details: district=None, block=None
|
||||||
|
Timestamp: 2026-04-17 11:17:06 | User: admin | Action: Report Page | Details: district=None, block=None
|
||||||
|
Timestamp: 2026-04-17 11:17:10 | User: admin | Action: Fetch Tasks | Details: Fetched tasks for block Kandhla
|
||||||
|
Timestamp: 2026-04-17 11:17:54 | User: admin | Action: Report Page | Details: district=None, block=None
|
||||||
|
Timestamp: 2026-04-17 11:17:55 | User: admin | Action: Report Page | Details: district=None, block=None
|
||||||
|
Timestamp: 2026-04-17 11:17:58 | User: admin | Action: Report Page | Details: district=None, block=None
|
||||||
|
Timestamp: 2026-04-17 11:18:01 | User: admin | Action: Fetch Tasks | Details: Fetched tasks for block Kandhla
|
||||||
|
Timestamp: 2026-04-17 11:18:17 | User: admin | Action: Report Page | Details: district=None, block=None
|
||||||
|
Timestamp: 2026-04-17 11:18:18 | User: admin | Action: Report Page | Details: district=None, block=None
|
||||||
|
Timestamp: 2026-04-17 11:19:57 | User: admin | Action: Report Page | Details: district=None, block=None
|
||||||
|
Timestamp: 2026-04-17 11:20:00 | User: admin | Action: Fetch Tasks | Details: Fetched tasks for block Kandhla
|
||||||
|
Timestamp: 2026-04-17 11:23:27 | User: admin | Action: Report Page | Details: district=None, block=None
|
||||||
|
Timestamp: 2026-04-17 11:23:30 | User: admin | Action: Fetch Tasks | Details: Fetched tasks for block Kandhla
|
||||||
|
Timestamp: 2026-04-17 11:24:15 | User: admin | Action: Report Page | Details: district=None, block=None
|
||||||
|
Timestamp: 2026-04-17 11:24:37 | User: admin | Action: Report Page | Details: district=None, block=None
|
||||||
|
Timestamp: 2026-04-17 11:24:40 | User: admin | Action: Fetch Tasks | Details: Fetched tasks for block Kandhla
|
||||||
|
Timestamp: 2026-04-17 11:26:22 | User: admin | Action: Report Page | Details: district=None, block=None
|
||||||
|
Timestamp: 2026-04-17 11:27:27 | User: admin | Action: Report Page | Details: district=None, block=None
|
||||||
|
Timestamp: 2026-04-17 11:27:30 | User: admin | Action: Fetch Tasks | Details: Fetched tasks for block Kandhla
|
||||||
|
Timestamp: 2026-04-17 11:28:09 | User: admin | Action: Report Page | Details: district=None, block=None
|
||||||
|
Timestamp: 2026-04-17 11:28:41 | User: admin | Action: Report Page | Details: district=None, block=None
|
||||||
|
Timestamp: 2026-04-17 11:28:44 | User: admin | Action: Fetch Tasks | Details: Fetched tasks for block Kandhla
|
||||||
|
Timestamp: 2026-04-17 11:44:45 | User: admin | Action: Task Update | Details: Task ID 14 - previous_billed_qty changed to 34
|
||||||
|
Timestamp: 2026-04-17 11:44:45 | User: admin | Action: Task Update | Details: Task ID 15 - previous_billed_qty changed to 34
|
||||||
|
Timestamp: 2026-04-17 11:44:45 | User: admin | Action: Task Update | Details: Task ID 16 - previous_billed_qty changed to 34
|
||||||
|
Timestamp: 2026-04-17 11:44:45 | User: admin | Action: Task Update | Details: Task ID 17 - previous_billed_qty changed to 34
|
||||||
|
Timestamp: 2026-04-17 11:44:46 | User: admin | Action: Database Commit | Details: 4 task field(s) updated
|
||||||
|
Timestamp: 2026-04-17 11:44:48 | User: admin | Action: Filter Tasks | Details: district=Shamli, block=Kandhla, village=Aldi
|
||||||
|
Timestamp: 2026-04-17 15:28:30 | User: admin | Action: Report Page | Details: district=None, block=None
|
||||||
|
Timestamp: 2026-04-17 15:28:33 | User: admin | Action: Report Page | Details: district=None, block=None
|
||||||
|
Timestamp: 2026-04-18 11:05:41 | User: admin | Action: Report Page | Details: district=None, block=None
|
||||||
|
Timestamp: 2026-04-18 11:18:31 | User: admin | Action: Page Load | Details: Upload Excel page accessed
|
||||||
|
Timestamp: 2026-04-18 11:18:33 | User: admin | Action: Report Page | Details: district=None, block=None
|
||||||
|
Timestamp: 2026-04-18 11:27:44 | User: admin | Action: Page Load | Details: Upload Excel page accessed
|
||||||
|
Timestamp: 2026-04-18 11:27:48 | User: admin | Action: Report Page | Details: district=None, block=None
|
||||||
|
Timestamp: 2026-04-18 11:27:52 | User: admin | Action: Report Page | Details: district=None, block=None
|
||||||
|
Timestamp: 2026-04-18 11:29:11 | User: admin | Action: Page Load | Details: Upload Excel page accessed
|
||||||
|
Timestamp: 2026-04-18 11:29:13 | User: admin | Action: Report Page | Details: district=None, block=None
|
||||||
|
Timestamp: 2026-04-18 11:29:23 | User: admin | Action: Page Load | Details: Upload Excel page accessed
|
||||||
|
Timestamp: 2026-04-20 13:39:03 | User: admin | Action: Filter Tasks | Details: district=Shamli, block=Kandhla, village=Aldi
|
||||||
|
Timestamp: 2026-04-20 14:05:29 | User: admin | Action: Report Page | Details: district=None, block=None
|
||||||
|
Timestamp: 2026-04-20 14:05:44 | User: admin | Action: Fetch Tasks | Details: Fetched tasks for block Kairana
|
||||||
|
Timestamp: 2026-04-20 14:06:13 | User: admin | Action: Report Page | Details: district=None, block=None
|
||||||
|
Timestamp: 2026-04-20 14:09:27 | User: admin | Action: Report Page | Details: district=None, block=None
|
||||||
|
Timestamp: 2026-04-20 16:06:41 | User: admin | Action: Page Load | Details: Upload Excel page accessed
|
||||||
|
Timestamp: 2026-04-20 16:40:27 | User: admin | Action: File Upload | Details: Uploaded file: thanabhavan_ahatagarh.xlsx
|
||||||
|
Timestamp: 2026-04-20 16:41:16 | User: admin | Action: Page Load | Details: Upload Excel page accessed
|
||||||
|
Timestamp: 2026-04-20 16:41:21 | User: admin | Action: File Upload | Details: Uploaded file: thanabhavan_ahatagarh.xlsx
|
||||||
|
Timestamp: 2026-04-20 16:42:10 | User: admin | Action: File Upload | Details: Uploaded file: thanabhavan_ahatagarh.xlsx
|
||||||
|
Timestamp: 2026-04-20 16:42:11 | User: admin | Action: Database Insert | Details: Inserted work details and tasks from thanabhavan_ahatagarh.xlsx
|
||||||
|
Timestamp: 2026-04-20 16:42:11 | User: admin | Action: Tasks View | Details: None, None
|
||||||
|
Timestamp: 2026-04-20 16:47:42 | User: admin | Action: Filter Tasks | Details: district=Shamli, block=Kandhla, village=Aldi
|
||||||
|
Timestamp: 2026-04-20 16:48:07 | User: admin | Action: Report Page | Details: district=None, block=None
|
||||||
|
Timestamp: 2026-04-20 16:48:14 | User: admin | Action: Fetch Tasks | Details: Fetched tasks for block Kairana
|
||||||
|
Timestamp: 2026-04-20 16:48:22 | User: admin | Action: Fetch Tasks | Details: Fetched tasks for block Kandhla
|
||||||
|
Timestamp: 2026-04-20 16:52:41 | User: admin | Action: Tasks View | Details: None, None
|
||||||
|
Timestamp: 2026-04-20 16:53:51 | User: admin | Action: Filter Tasks | Details: district=Shamli, block=Kairana, village=Asadpur Bamnauli
|
||||||
|
Timestamp: 2026-04-20 16:55:24 | User: admin | Action: Report Page | Details: district=None, block=None
|
||||||
|
Timestamp: 2026-04-20 16:55:30 | User: admin | Action: Fetch Tasks | Details: Fetched tasks for block Kandhla
|
||||||
|
Timestamp: 2026-04-20 17:18:18 | User: admin | Action: Report Page | Details: district=None, block=None
|
||||||
|
Timestamp: 2026-04-20 17:18:43 | User: admin | Action: Filter Tasks | Details: district=Shamli, block=Kandhla, village=Aldi
|
||||||
|
Timestamp: 2026-04-20 17:22:57 | User: admin | Action: Filter Tasks | Details: district=Shamli, block=Kandhla, village=Aldi
|
||||||
|
Timestamp: 2026-04-20 17:40:32 | User: admin | Action: Filter Tasks | Details: district=Shamli, block=Kandhla, village=Aldi
|
||||||
|
Timestamp: 2026-04-20 17:41:37 | User: admin | Action: Filter Tasks | Details: district=Shamli, block=Kandhla, village=Aldi
|
||||||
|
Timestamp: 2026-04-20 17:49:29 | User: admin | Action: Filter Tasks | Details: district=Shamli, block=Kandhla, village=Aldi
|
||||||
|
Timestamp: 2026-04-20 18:44:28 | User: admin | Action: Filter Tasks | Details: district=Shamli, block=Kandhla, village=Aldi
|
||||||
|
Timestamp: 2026-04-20 18:46:24 | User: admin | Action: Filter Tasks | Details: district=Shamli, block=Kandhla, village=Aldi
|
||||||
|
Timestamp: 2026-04-20 18:51:45 | User: admin | Action: Filter Tasks | Details: district=Shamli, block=Kandhla, village=Aldi
|
||||||
|
Timestamp: 2026-04-20 18:52:52 | User: admin | Action: Filter Tasks | Details: district=Shamli, block=Kandhla, village=Aldi
|
||||||
|
Timestamp: 2026-04-20 18:54:38 | User: admin | Action: Filter Tasks | Details: district=Shamli, block=Kandhla, village=Aldi
|
||||||
|
Timestamp: 2026-04-20 19:40:23 | User: admin | Action: Filter Tasks | Details: district=Shamli, block=Kandhla, village=Aldi
|
||||||
|
Timestamp: 2026-04-20 20:01:45 | User: admin | Action: Report Page | Details: district=None, block=None
|
||||||
|
Timestamp: 2026-04-20 20:01:57 | User: admin | Action: Page Load | Details: Upload Excel page accessed
|
||||||
|
Timestamp: 2026-04-20 20:02:01 | User: admin | Action: Report Page | Details: district=None, block=None
|
||||||
|
Timestamp: 2026-04-21 10:02:55 | User: admin | Action: Filter Tasks | Details: district=Shamli, block=Kandhla, village=Aldi
|
||||||
|
Timestamp: 2026-04-21 10:18:57 | User: admin | Action: Filter Tasks | Details: district=Shamli, block=Kandhla, village=Aldi
|
||||||
|
Timestamp: 2026-04-21 10:20:03 | User: admin | Action: Report Page | Details: district=None, block=None
|
||||||
|
Timestamp: 2026-04-21 10:20:08 | User: admin | Action: Fetch Tasks | Details: Fetched tasks for block Kandhla
|
||||||
|
Timestamp: 2026-04-21 10:20:10 | User: admin | Action: Report Page | Details: district=None, block=None
|
||||||
|
Timestamp: 2026-04-21 10:20:20 | User: admin | Action: Filter Tasks | Details: district=Shamli, block=Kairana, village=Asadpur Bamnauli
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ class User(UserMixin, db.Model):
|
|||||||
return f'<User {self.username}>'
|
return f'<User {self.username}>'
|
||||||
|
|
||||||
# ==========================
|
# ==========================
|
||||||
# Your existing models below
|
# DB models below
|
||||||
# ==========================
|
# ==========================
|
||||||
|
|
||||||
class Task(db.Model):
|
class Task(db.Model):
|
||||||
@@ -66,7 +66,7 @@ class WorkDetail(db.Model):
|
|||||||
uploaded_at = db.Column(db.DateTime, default=datetime.utcnow)
|
uploaded_at = db.Column(db.DateTime, default=datetime.utcnow)
|
||||||
district = db.Column(db.String(255))
|
district = db.Column(db.String(255))
|
||||||
|
|
||||||
class ActivityLog(db.Model): # ✅ OUTSIDE WorkDetail
|
class ActivityLog(db.Model): # OUTSIDE WorkDetail
|
||||||
id = db.Column(db.Integer, primary_key=True)
|
id = db.Column(db.Integer, primary_key=True)
|
||||||
user = db.Column(db.String(100)) # can link with User model later
|
user = db.Column(db.String(100)) # can link with User model later
|
||||||
action = db.Column(db.String(255))
|
action = db.Column(db.String(255))
|
||||||
|
|||||||
Binary file not shown.
@@ -7,93 +7,110 @@ from app.Controllers.auth_controller import (login_controller,logout_controller)
|
|||||||
from app.Controllers.upload_controller import upload_controller
|
from app.Controllers.upload_controller import upload_controller
|
||||||
from app.Controllers.activity_controller import activity_log_controller
|
from app.Controllers.activity_controller import activity_log_controller
|
||||||
from app.Controllers.task_controller import (update_tasks_controller,display_tasks_controller)
|
from app.Controllers.task_controller import (update_tasks_controller,display_tasks_controller)
|
||||||
from app.Controllers.filter_controller import filter_tasks_controller
|
from app.Controllers.filter_controller import (filter_tasks_controller,download_filtered_tasks_controller)
|
||||||
from app.Controllers.report_controller import generate_report_page_controller
|
from app.Controllers.report_controller import generate_report_page_controller
|
||||||
from app.Controllers.dropdown_controller import (get_blocks_by_district_controller,get_tasks_by_block_controller,get_villages_by_block_controller)
|
from app.Controllers.dropdown_controller import (get_blocks_by_district_controller,get_tasks_by_block_controller,get_villages_by_block_controller)
|
||||||
|
|
||||||
main = Blueprint("main", __name__)
|
main = Blueprint("main", __name__)
|
||||||
|
|
||||||
|
# -----------Login-----------------------------------
|
||||||
@main.route("/login", methods=["GET", "POST"])
|
@main.route("/login", methods=["GET", "POST"])
|
||||||
def login():
|
def login():
|
||||||
return login_controller()
|
return login_controller()
|
||||||
|
|
||||||
|
|
||||||
@main.route("/logout")
|
@main.route("/logout")
|
||||||
@login_required
|
@login_required
|
||||||
def logout():
|
def logout():
|
||||||
return logout_controller()
|
return logout_controller()
|
||||||
|
# ----------------------------------------------------
|
||||||
|
|
||||||
|
# ------------Upload Excel----------------------------
|
||||||
@main.route('/upload_excel')
|
@main.route('/upload_excel')
|
||||||
@login_required
|
@login_required
|
||||||
def upload_excel():
|
def upload_excel():
|
||||||
log_activity(current_user.username, "Page Load", "Upload Excel page accessed")
|
log_activity(current_user.username, "Page Load", "Upload Excel page accessed")
|
||||||
return render_template('upload.html')
|
return render_template('upload.html')
|
||||||
|
# -----------------------------------------------------
|
||||||
|
|
||||||
# @main.route('/dashboard')
|
# @main.route('/dashboard')
|
||||||
# def upload_file():
|
# def upload_file():
|
||||||
# return render_template('dashboard.html')
|
# return render_template('dashboard.html')
|
||||||
|
|
||||||
|
# -----------Upload-----------------------------------
|
||||||
@main.route('/upload', methods=['POST'])
|
@main.route('/upload', methods=['POST'])
|
||||||
@login_required
|
@login_required
|
||||||
def upload():
|
def upload():
|
||||||
return upload_controller()
|
return upload_controller()
|
||||||
|
# ----------------------------------------------------
|
||||||
|
|
||||||
|
# -----------Update Task-----------------------------
|
||||||
@main.route('/update_tasks', methods=['POST'])
|
@main.route('/update_tasks', methods=['POST'])
|
||||||
@login_required
|
@login_required
|
||||||
def update_tasks():
|
def update_tasks():
|
||||||
return update_tasks_controller()
|
return update_tasks_controller()
|
||||||
|
# -----------------------------------------------------
|
||||||
|
|
||||||
|
# --------Task----------------------------------------
|
||||||
@main.route('/tasks')
|
@main.route('/tasks')
|
||||||
@login_required
|
@login_required
|
||||||
def display_tasks():
|
def display_tasks():
|
||||||
return display_tasks_controller()
|
return display_tasks_controller()
|
||||||
|
# ------------------------------------------------------
|
||||||
|
|
||||||
|
# ----------------Home----------------------------------
|
||||||
@main.route('/')
|
@main.route('/')
|
||||||
@login_required
|
@login_required
|
||||||
def dashboard():
|
def dashboard():
|
||||||
return dashboard_controller()
|
return dashboard_controller()
|
||||||
|
# -------------------------------------------------------
|
||||||
|
|
||||||
|
# ----------Get Block By Distrit-------------------------
|
||||||
|
|
||||||
@main.route('/get_blocks_by_district')
|
@main.route('/get_blocks_by_district')
|
||||||
@login_required
|
@login_required
|
||||||
def get_blocks_by_district():
|
def get_blocks_by_district():
|
||||||
return get_blocks_by_district_controller()
|
return get_blocks_by_district_controller()
|
||||||
|
# -------------------------------------------------------
|
||||||
|
|
||||||
|
# ------------------Get Task by Block--------------------
|
||||||
@main.route('/get_tasks_by_block')
|
@main.route('/get_tasks_by_block')
|
||||||
@login_required
|
@login_required
|
||||||
def get_tasks_by_block():
|
def get_tasks_by_block():
|
||||||
return get_tasks_by_block_controller()
|
return get_tasks_by_block_controller()
|
||||||
|
# ------------------------------------------------------
|
||||||
|
|
||||||
|
# ---------------Get Village by Block--------------------
|
||||||
@main.route('/get_villages_by_block')
|
@main.route('/get_villages_by_block')
|
||||||
@login_required
|
@login_required
|
||||||
def get_villages_by_block():
|
def get_villages_by_block():
|
||||||
return get_villages_by_block_controller()
|
return get_villages_by_block_controller()
|
||||||
|
# -------------------------------------------------------
|
||||||
|
|
||||||
|
# --------------genrate Report--------------------------
|
||||||
@main.route('/generate_report_page')
|
@main.route('/generate_report_page')
|
||||||
@login_required
|
@login_required
|
||||||
def generate_report_page():
|
def generate_report_page():
|
||||||
return generate_report_page_controller()
|
return generate_report_page_controller()
|
||||||
|
#-----------------------------------------------------
|
||||||
|
|
||||||
|
# -----------Filter Task---------------------------------
|
||||||
@main.route('/filter_tasks', methods=['GET'])
|
@main.route('/filter_tasks', methods=['GET'])
|
||||||
@login_required
|
@login_required
|
||||||
def filter_tasks():
|
def filter_tasks():
|
||||||
return filter_tasks_controller()
|
return filter_tasks_controller()
|
||||||
|
|
||||||
|
# --Download Filter Task--
|
||||||
|
@main.route('/download_filtered_tasks', methods=['GET'])
|
||||||
|
def download_filtered_tasks():
|
||||||
|
return download_filtered_tasks_controller()
|
||||||
|
|
||||||
|
# -----------------------------------------------------------
|
||||||
|
|
||||||
|
# ----------------Activity Log--------------------------
|
||||||
@main.route('/activity_log', methods=['GET', 'POST'])
|
@main.route('/activity_log', methods=['GET', 'POST'])
|
||||||
@login_required
|
@login_required
|
||||||
def activity_log():
|
def activity_log():
|
||||||
return activity_log_controller()
|
return activity_log_controller()
|
||||||
|
# -----------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -279,6 +279,7 @@
|
|||||||
<button class="edit-mode-button" type="button" onclick="toggleEditMode()">Edit Tasks</button>
|
<button class="edit-mode-button" type="button" onclick="toggleEditMode()">Edit Tasks</button>
|
||||||
<button class="edit-mode-button" type="button" id="cancelBtn" onclick="cancelEditMode()" style="display: none;">Cancel</button>
|
<button class="edit-mode-button" type="button" id="cancelBtn" onclick="cancelEditMode()" style="display: none;">Cancel</button>
|
||||||
<button class="edit-mode-button" type="button" onclick="submitChangedFields()">Submit Updates</button>
|
<button class="edit-mode-button" type="button" onclick="submitChangedFields()">Submit Updates</button>
|
||||||
|
<button class="edit-mode-button" type="button" onclick="downloadExcel()">Download Excel</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% if grouped_tasks %}
|
{% if grouped_tasks %}
|
||||||
@@ -311,25 +312,50 @@
|
|||||||
] %}
|
] %}
|
||||||
|
|
||||||
{% for group in grouped_tasks %}
|
{% for group in grouped_tasks %}
|
||||||
<tr class="main-task-row">
|
<!-- <tr class="main-task-row">
|
||||||
<td colspan="1">{{ group.task_name }}</td>
|
<td colspan="1">{{ group.task_name }}</td>
|
||||||
</tr>
|
</tr> -->
|
||||||
|
<!-- <tr class="main-task-row">
|
||||||
|
{% for field in ["task_name","unit","qty","rate","boq_amount","previous_billed_qty","previous_billing_amount","in_this_ra_bill_qty","in_this_ra_billing_amount","cumulative_billed_qty","cumulative_billed_amount","variation_qty","variation_amount"] %}
|
||||||
|
<td>
|
||||||
|
{{ '' if group[field] in [None, 0, "0"] else group[field] }}
|
||||||
|
</td>
|
||||||
|
{% endfor %}
|
||||||
|
</tr> -->
|
||||||
|
<tr class="main-task-row">
|
||||||
|
{% for field in ["task_name","unit","qty","rate","boq_amount","previous_billed_qty","previous_billing_amount","in_this_ra_bill_qty","in_this_ra_billing_amount","cumulative_billed_qty","cumulative_billed_amount","variation_qty","variation_amount"] %}
|
||||||
|
<td>
|
||||||
|
<span class="static-text">
|
||||||
|
{{ group[field] if group[field] is not none else '' }}
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
class="edit-field"
|
||||||
|
name="{{ field }}_main_{{ loop.index }}"
|
||||||
|
value="{{ group[field] if group[field] is not none else '' }}"
|
||||||
|
data-original-value="{{ group[field] if group[field] is not none else '' }}"
|
||||||
|
>
|
||||||
|
</td>
|
||||||
|
{% endfor %}
|
||||||
|
</tr>
|
||||||
{% for sub in group.subtasks %}
|
{% for sub in group.subtasks %}
|
||||||
<tr class="subtask-row">
|
<tr class="subtask-row">
|
||||||
{% for field in ["task_name","unit","qty","rate","boq_amount","previous_billed_qty","previous_billing_amount","in_this_ra_bill_qty","in_this_ra_billing_amount","cumulative_billed_qty","cumulative_billed_amount","variation_qty","variation_amount"] %}
|
{% for field in ["task_name","unit","qty","rate","boq_amount","previous_billed_qty","previous_billing_amount","in_this_ra_bill_qty","in_this_ra_billing_amount","cumulative_billed_qty","cumulative_billed_amount","variation_qty","variation_amount"] %}
|
||||||
<td>
|
<td>
|
||||||
<span class="static-text">{{ sub[field] }}</span>
|
<span class="static-text">
|
||||||
|
{{ sub[field] if sub[field] is not none else '' }}
|
||||||
|
</span>
|
||||||
|
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
class="edit-field"
|
class="edit-field"
|
||||||
name="{{ field }}_{{ sub.id }}"
|
name="{{ field }}_{{ sub.id }}"
|
||||||
value="{{ sub[field] }}"
|
value="{{ sub[field] if sub[field] is not none else '' }}"
|
||||||
data-original-value="{{ sub[field] | trim }}"
|
data-original-value="{{ sub[field] if sub[field] is not none else '' }}"
|
||||||
{% if field in formula_fields %} readonly style="background:#f5f5f5;" {% endif %}
|
{% if field in formula_fields %} readonly style="background:#f5f5f5;" {% endif %}
|
||||||
>
|
>
|
||||||
</td>
|
</td>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
@@ -434,6 +460,15 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function downloadExcel() {
|
||||||
|
const district = document.getElementById("district").value;
|
||||||
|
const block = document.getElementById("block").value;
|
||||||
|
const village = document.getElementById("village").value;
|
||||||
|
|
||||||
|
let url = `/download_filtered_tasks?district=${district}&block=${block}&village=${village}`;
|
||||||
|
window.location.href = url;
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
@@ -3,10 +3,15 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
|
<!-- <link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}"> -->
|
||||||
|
|
||||||
<title>LAXMI CIVIL ENGINEERING SERVICES PVT. LTD.</title>
|
<title>LAXMI CIVIL ENGINEERING SERVICES PVT. LTD.</title>
|
||||||
<style>
|
<style>
|
||||||
|
*{
|
||||||
|
padding:0;
|
||||||
|
margin: 0 ;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
body {
|
body {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-family: Arial, sans-serif;
|
font-family: Arial, sans-serif;
|
||||||
@@ -50,7 +55,6 @@
|
|||||||
background-color: #007bff;
|
background-color: #007bff;
|
||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
.header {
|
.header {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
background-color: #007bff;
|
background-color: #007bff;
|
||||||
@@ -65,7 +69,20 @@
|
|||||||
left: 0;
|
left: 0;
|
||||||
z-index: 1000;
|
z-index: 1000;
|
||||||
}
|
}
|
||||||
|
.header span {
|
||||||
|
display: inline-flex;
|
||||||
|
white-space: nowrap;
|
||||||
|
animation: scrollText 15s linear infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes scrollText {
|
||||||
|
from {
|
||||||
|
transform: translateX(100%);
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
transform: translateX(-100%);
|
||||||
|
}
|
||||||
|
}
|
||||||
.container {
|
.container {
|
||||||
margin: 100px 20px 20px 330px;
|
margin: 100px 20px 20px 330px;
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
@@ -110,8 +127,6 @@ tr:nth-child(even) {
|
|||||||
background-color: #f2f2f2;
|
background-color: #f2f2f2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.total-row {
|
.total-row {
|
||||||
position: -webkit-sticky; /* For Safari */
|
position: -webkit-sticky; /* For Safari */
|
||||||
position: sticky;
|
position: sticky;
|
||||||
@@ -130,10 +145,14 @@ tr:nth-child(even) {
|
|||||||
|
|
||||||
.summary-title {
|
.summary-title {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-size: 24px;
|
font-size: 30px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
|
font-family:'Times New Roman', Times, serif;
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
}
|
}
|
||||||
|
.summary-title:hover{
|
||||||
|
color: #ff0b23;
|
||||||
|
}
|
||||||
/* Style for the filter and search inputs */
|
/* Style for the filter and search inputs */
|
||||||
.filter-container,
|
.filter-container,
|
||||||
.search-container {
|
.search-container {
|
||||||
@@ -245,12 +264,11 @@ tr:nth-child(even) {
|
|||||||
background-color: #007bff;
|
background-color: #007bff;
|
||||||
padding: 5px 8px 5px 8px;
|
padding: 5px 8px 5px 8px;
|
||||||
border-radius: 7px;
|
border-radius: 7px;
|
||||||
border: 1px solid #007bff;
|
border: 1px solid #007bff;
|
||||||
height: 30px;
|
height: 30px;
|
||||||
width: 100px;
|
width: 100px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
@@ -268,9 +286,9 @@ tr:nth-child(even) {
|
|||||||
<a href="{{ url_for('main.logout') }}" style="margin-top:auto; color: #fff; background-color: #dc3545;">Logout</a>
|
<a href="{{ url_for('main.logout') }}" style="margin-top:auto; color: #fff; background-color: #dc3545;">Logout</a>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div class="header">LAXMI CIVIL ENGINEERING SERVICES PVT. LTD.</div>
|
<div class="header"><span>LAXMI CIVIL ENGINEERING SERVICES PVT. LTD.</span></div>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<h1 class="summary-title">Dashboard</h1>
|
<h1 class="summary-title">DASHBOARD</h1>
|
||||||
<!-- Block Selection Dropdown -->
|
<!-- Block Selection Dropdown -->
|
||||||
<form method="get" action="{{ url_for('main.dashboard') }}">
|
<form method="get" action="{{ url_for('main.dashboard') }}">
|
||||||
<div class="filter-container">
|
<div class="filter-container">
|
||||||
|
|||||||
@@ -4,33 +4,39 @@
|
|||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<title>LCEPL Client Billing Software</title>
|
<title>LCEPL Client Billing Software</title>
|
||||||
<style>
|
<style>
|
||||||
|
*{
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
body {
|
body {
|
||||||
font-family: Arial, sans-serif;
|
font-family: Arial, sans-serif;
|
||||||
background: #f3f3f3;
|
background: #f3f3f3;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
height: 100vh;
|
height: 98.3vh;
|
||||||
}
|
}
|
||||||
|
|
||||||
.login-container {
|
.login-container {
|
||||||
background: white;
|
background: white;
|
||||||
padding: 2rem;
|
padding: 2rem;
|
||||||
border-radius: 10px;
|
border-radius: 20px;
|
||||||
box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.1);
|
box-shadow: 10px 10px 20px rgba(110, 0, 0, 0.3);
|
||||||
width: 300px;
|
width: 21%;
|
||||||
}
|
}
|
||||||
|
|
||||||
h2 {
|
h2 {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
margin-bottom: 1.5rem;
|
margin-bottom: 1.5rem;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
input[type="text"],
|
input[type="text"],
|
||||||
input[type="password"] {
|
input[type="password"] {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding: 0.5rem;
|
padding: 0.5rem;
|
||||||
margin-bottom: 1rem;
|
margin-bottom: 1.5rem;
|
||||||
border: 1px solid #ccc;
|
border: 1px solid #ccc;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
}
|
}
|
||||||
@@ -57,6 +63,7 @@
|
|||||||
|
|
||||||
.subtitle {
|
.subtitle {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
margin: 20px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
|
|||||||
BIN
uploads/200 MMØ MSERW PlaneSlotted Pip_20260417_111715.xlsx
Normal file
BIN
uploads/200 MMØ MSERW PlaneSlotted Pip_20260417_111715.xlsx
Normal file
Binary file not shown.
BIN
uploads/200 MMØ_20260415_132725.xlsx
Normal file
BIN
uploads/200 MMØ_20260415_132725.xlsx
Normal file
Binary file not shown.
BIN
uploads/200 MMØ_20260417_111617.xlsx
Normal file
BIN
uploads/200 MMØ_20260417_111617.xlsx
Normal file
Binary file not shown.
BIN
uploads/30 HP_20260417_111739.xlsx
Normal file
BIN
uploads/30 HP_20260417_111739.xlsx
Normal file
Binary file not shown.
BIN
uploads/300 MMØ MSERW PlainSlotted Pip_20260417_111719.xlsx
Normal file
BIN
uploads/300 MMØ MSERW PlainSlotted Pip_20260417_111719.xlsx
Normal file
Binary file not shown.
BIN
uploads/300 MMØ_20260415_132727.xlsx
Normal file
BIN
uploads/300 MMØ_20260415_132727.xlsx
Normal file
Binary file not shown.
BIN
uploads/300 MMØ_20260417_111621.xlsx
Normal file
BIN
uploads/300 MMØ_20260417_111621.xlsx
Normal file
Binary file not shown.
BIN
uploads/325 Kl 14 M Staging_20260417_112456.xlsx
Normal file
BIN
uploads/325 Kl 14 M Staging_20260417_112456.xlsx
Normal file
Binary file not shown.
BIN
uploads/325 Kl 14 M Staging_20260417_113004.xlsx
Normal file
BIN
uploads/325 Kl 14 M Staging_20260417_113004.xlsx
Normal file
Binary file not shown.
BIN
uploads/500 MMØ_20260415_132506.xlsx
Normal file
BIN
uploads/500 MMØ_20260415_132506.xlsx
Normal file
Binary file not shown.
BIN
uploads/500 MMØ_20260415_144112.xlsx
Normal file
BIN
uploads/500 MMØ_20260415_144112.xlsx
Normal file
Binary file not shown.
BIN
uploads/500 MMØ_20260415_170439.xlsx
Normal file
BIN
uploads/500 MMØ_20260415_170439.xlsx
Normal file
Binary file not shown.
BIN
uploads/500 MMØ_20260415_170441.xlsx
Normal file
BIN
uploads/500 MMØ_20260415_170441.xlsx
Normal file
Binary file not shown.
BIN
uploads/500 MMØ_20260415_170443.xlsx
Normal file
BIN
uploads/500 MMØ_20260415_170443.xlsx
Normal file
Binary file not shown.
BIN
uploads/500 MMØ_20260415_170444.xlsx
Normal file
BIN
uploads/500 MMØ_20260415_170444.xlsx
Normal file
Binary file not shown.
BIN
uploads/500 MMØ_20260417_111554.xlsx
Normal file
BIN
uploads/500 MMØ_20260417_111554.xlsx
Normal file
Binary file not shown.
BIN
uploads/600 MMØ_20260415_132511.xlsx
Normal file
BIN
uploads/600 MMØ_20260415_132511.xlsx
Normal file
Binary file not shown.
BIN
uploads/600 MMØ_20260417_111601.xlsx
Normal file
BIN
uploads/600 MMØ_20260417_111601.xlsx
Normal file
Binary file not shown.
BIN
uploads/Asadpur bamnauli.xlsx
Normal file
BIN
uploads/Asadpur bamnauli.xlsx
Normal file
Binary file not shown.
BIN
uploads/Charges for Development by 250_20260417_111732.xlsx
Normal file
BIN
uploads/Charges for Development by 250_20260417_111732.xlsx
Normal file
Binary file not shown.
BIN
uploads/Charges for Development of TW _20260417_111736.xlsx
Normal file
BIN
uploads/Charges for Development of TW _20260417_111736.xlsx
Normal file
Binary file not shown.
BIN
uploads/Construction of 13 m high and _20260417_112338.xlsx
Normal file
BIN
uploads/Construction of 13 m high and _20260417_112338.xlsx
Normal file
Binary file not shown.
BIN
uploads/Construction of 13 m high and _20260420_164840.xlsx
Normal file
BIN
uploads/Construction of 13 m high and _20260420_164840.xlsx
Normal file
Binary file not shown.
BIN
uploads/Construction of 13 m high and _20260420_164849.xlsx
Normal file
BIN
uploads/Construction of 13 m high and _20260420_164849.xlsx
Normal file
Binary file not shown.
BIN
uploads/Construction of 13 m high and _20260420_164854.xlsx
Normal file
BIN
uploads/Construction of 13 m high and _20260420_164854.xlsx
Normal file
Binary file not shown.
BIN
uploads/Construction of 13 m high and _20260420_164858.xlsx
Normal file
BIN
uploads/Construction of 13 m high and _20260420_164858.xlsx
Normal file
Binary file not shown.
BIN
uploads/MS fittings such as clamp bai_20260417_111648.xlsx
Normal file
BIN
uploads/MS fittings such as clamp bai_20260417_111648.xlsx
Normal file
Binary file not shown.
BIN
uploads/MS fittings such as ring cent_20260417_111652.xlsx
Normal file
BIN
uploads/MS fittings such as ring cent_20260417_111652.xlsx
Normal file
Binary file not shown.
BIN
uploads/Provide all materials labour T_20260417_112251.xlsx
Normal file
BIN
uploads/Provide all materials labour T_20260417_112251.xlsx
Normal file
Binary file not shown.
BIN
uploads/Provide all materials labour T_20260417_112854.xlsx
Normal file
BIN
uploads/Provide all materials labour T_20260417_112854.xlsx
Normal file
Binary file not shown.
BIN
uploads/Provide all materials labour T_20260417_113139.xlsx
Normal file
BIN
uploads/Provide all materials labour T_20260417_113139.xlsx
Normal file
Binary file not shown.
BIN
uploads/SITC of Solar power plant for _20260415_133541.xlsx
Normal file
BIN
uploads/SITC of Solar power plant for _20260415_133541.xlsx
Normal file
Binary file not shown.
BIN
uploads/Supplying and unconsolidated p_20260417_111724.xlsx
Normal file
BIN
uploads/Supplying and unconsolidated p_20260417_111724.xlsx
Normal file
Binary file not shown.
BIN
uploads/Transportation Installation Di_20260415_132403.xlsx
Normal file
BIN
uploads/Transportation Installation Di_20260415_132403.xlsx
Normal file
Binary file not shown.
BIN
uploads/Transportation Installation Di_20260417_111730.xlsx
Normal file
BIN
uploads/Transportation Installation Di_20260417_111730.xlsx
Normal file
Binary file not shown.
BIN
uploads/thanabhavan_ahatagarh.xlsx
Normal file
BIN
uploads/thanabhavan_ahatagarh.xlsx
Normal file
Binary file not shown.
Reference in New Issue
Block a user