2 Commits

10 changed files with 309 additions and 763 deletions

37
.env
View File

@@ -1,37 +0,0 @@
# -----------------------------
# Flask App Configuration
# -----------------------------
FLASK_ENV=development
FLASK_DEBUG=True
FLASK_HOST=0.0.0.0
FLASK_PORT=5015
# -----------------------------
# Security
# -----------------------------
SECRET_KEY=change-this-to-strong-secret-key
# -----------------------------
# Database Configuration
# -----------------------------
DB_DIALECT=mysql
DB_DRIVER=pymysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_NAME=comparisondb
DB_USER=root
DB_PASSWORD=root
# DATABASE_URL=mysql+pymysql://root:root@localhost/comparisondb
# -----------------------------
# LDAP Configuration new
# -----------------------------
LDAP_SERVER=ldap://host.docker.internal
LDAP_PORT=389
LDAP_USE_SSL=False
LDAP_DOMAIN=lcepl.org
LDAP_BASE_DN=DC=lcepl,DC=org
LDAP_SEARCH_BASE=OU=Users,DC=lcepl,DC=org

19
.gitignore vendored
View File

@@ -1,19 +1,22 @@
# Python # Python
app/__pycache__/ app/__pycache__/
__pycache__/
*.pyc *.pyc
*.pyo *.pyo
*.pyd *.pyd
*.__pycache__
# Ingnor upload files # Ignore upload files
app/static/uploads/ app/static/uploads/
# Ignore env files # Virtual environment
venv venv/
.venv/
# Ignore Log files ss # Environment / secrets
.env
.env.*
!.env.example
# Log files
logs/ logs/
*.log *.log

View File

@@ -4,7 +4,7 @@ from flask import (
request, request,
redirect, redirect,
url_for, url_for,
flash, jsonify flash
) )
from app.models.subcontractor_model import Subcontractor from app.models.subcontractor_model import Subcontractor
@@ -27,7 +27,25 @@ def engineering_master():
title="Engineering Masters" title="Engineering Masters"
) )
# Client rate model
@engi_bp.route("/subcontractor-rate")
def add_subcontractor_rates():
subcontractors = Subcontractor.query.filter_by(status="Active").all()
if request.method == "POST":
try:
SubcontractorRateService.save_rate(request.form)
flash(SuccessMessage.SAVE, "success")
return redirect(url_for("engineering.add_subcontractor_rates"))
except Exception as e:
flash(ErrorMessage.INTERNAL_SERVER_ERROR, "danger")
return render_template(
"engineering/add_rate.html",
title="Subcontractor Rate Master",
subcontractors=subcontractors
)
@engi_bp.route("/client-rate") @engi_bp.route("/client-rate")
def client_rates(): def client_rates():
@@ -36,72 +54,3 @@ def client_rates():
title="Client Rate Master" title="Client Rate Master"
) )
@engi_bp.route("/subcontractor-rate", methods=["GET", "POST"])
def add_subcontractor_rates():
subcontractors = Subcontractor.query.filter_by(status="Active").all()
if request.method == "POST":
result = SubcontractorRateService.save_or_update(request.form)
if result["success"]:
flash(result["message"], "success")
return redirect(url_for("engineering.add_subcontractor_rates"))
else:
flash(result["message"], "danger")
rates = SubcontractorRateService.get_all_rates()
return render_template(
"engineering/contractor_rate.html",
title="Subcontractor Rate Master",
subcontractors=subcontractors,
rates=rates
)
@engi_bp.route("/subcontractor-rate/edit/<int:rate_id>", methods=["GET", "POST"])
def edit_rate(rate_id):
subcontractors = Subcontractor.query.filter_by(status="Active").all()
if request.method == "POST":
result = SubcontractorRateService.save_or_update(request.form)
if result["success"]:
flash(result["message"], "success")
return redirect(url_for("engineering.add_subcontractor_rates"))
flash(result["message"], "danger")
rate = SubcontractorRateService.get_rate(rate_id)
rates = SubcontractorRateService.get_all_rates()
return render_template(
"engineering/contractor_rate.html",
subcontractors=subcontractors,
rate=rate,
rates=rates
)
@engi_bp.route("/subcontractor-rate/delete/<int:rate_id>")
def delete_rate(rate_id):
SubcontractorRateService.delete_rate(rate_id)
flash("Rate deleted successfully.", "success")
return redirect(url_for("engineering.add_subcontractor_rates"))
@engi_bp.route("/check-rate")
def check_rate():
exists = SubcontractorRateService.check_duplicate(
subcontractor_id=request.args.get("subcontractor_id"),
category=request.args.get("category"),
item_name=request.args.get("item_name"),
rate_id=request.args.get("rate_id")
)
return jsonify({
"exists": exists
})

View File

@@ -1,66 +1,28 @@
from app.services.db_service import db from app.services.db_service import db
from app.models.subcontractor_rate_model import SubcontractorRate from app.models.subcontractor_rate_model import SubcontractorRate
from sqlalchemy import func
class SubcontractorRateService: class SubcontractorRateService:
@staticmethod @staticmethod
def save_or_update(form): def save_rate(form):
rate_id = form.get("id") rate = SubcontractorRate(
subcontractor_id=form.get("subcontractor_id"),
subcontractor_id = form.get("subcontractor_id") category=form.get("category"),
category = form.get("category") item_code=form.get("item_code"),
item_name = form.get("item_name").strip() item_name=form.get("item_name"),
unit=form.get("unit"),
# ----------------------------- rate=form.get("rate"),
# Duplicate Validation effective_from=form.get("effective_from"),
# ----------------------------- effective_to=form.get("effective_to") or None,
duplicate = ( status=form.get("status")
SubcontractorRate.query
.filter(
SubcontractorRate.subcontractor_id == subcontractor_id,
SubcontractorRate.category == category,
func.lower(SubcontractorRate.item_name) == item_name.lower()
)
.first()
) )
# Ignore current record while editing db.session.add(rate)
if duplicate and (not rate_id or duplicate.id != int(rate_id)):
return {
"success": False,
"message": "Category and Rate already exists for this Subcontractor."
}
# -----------------------------
# Insert / Update
# -----------------------------
if rate_id:
rate = SubcontractorRate.query.get_or_404(rate_id)
else:
rate = SubcontractorRate()
rate.subcontractor_id = subcontractor_id
rate.category = category
rate.item_code = form.get("item_code")
rate.item_name = item_name
rate.unit = form.get("unit")
rate.rate = form.get("rate")
rate.effective_from = form.get("effective_from")
rate.effective_to = form.get("effective_to") or None
rate.status = form.get("status")
if not rate_id:
db.session.add(rate)
db.session.commit() db.session.commit()
return rate
return {
"success": True,
"message": "Saved Successfully."
}
@staticmethod @staticmethod
def get_all_rates(): def get_all_rates():
@@ -70,33 +32,34 @@ class SubcontractorRateService:
.order_by(SubcontractorRate.created_at.desc()) .order_by(SubcontractorRate.created_at.desc())
.all() .all()
) )
@staticmethod @staticmethod
def get_rate(rate_id): def get_rate(rate_id):
return SubcontractorRate.query.get_or_404(rate_id) return SubcontractorRate.query.get_or_404(rate_id)
def delete_rate(rate_id): @staticmethod
rate = SubcontractorRate.query.get_or_404(rate_id) def update_rate(rate_id, form):
db.session.delete(rate)
db.session.commit()
rate = SubcontractorRate.query.get_or_404(rate_id)
rate.subcontractor_id = form.get("subcontractor_id")
rate.category = form.get("category")
rate.item_code = form.get("item_code")
rate.item_name = form.get("item_name")
rate.unit = form.get("unit")
rate.rate = form.get("rate")
rate.effective_from = form.get("effective_from")
rate.effective_to = form.get("effective_to") or None
rate.status = form.get("status")
db.session.commit()
return rate
@staticmethod @staticmethod
def check_duplicate(subcontractor_id, category, item_name, rate_id=None): def delete_rate(rate_id):
query = SubcontractorRate.query.filter(
SubcontractorRate.subcontractor_id == subcontractor_id,
SubcontractorRate.category == category,
func.lower(SubcontractorRate.item_name) == item_name.strip().lower()
)
if rate_id:
query = query.filter(SubcontractorRate.id != int(rate_id))
return query.first() is not None
rate = SubcontractorRate.query.get_or_404(rate_id)
db.session.delete(rate)
db.session.commit()

View File

@@ -132,6 +132,7 @@
</ul> </ul>
</li> </li>
<!-- Formats --> <!-- Formats -->
<li class="nav-item"> <li class="nav-item">
<a class="nav-link" href="/file_format"> <a class="nav-link" href="/file_format">
@@ -139,37 +140,6 @@
</a> </a>
</li> </li>
<!-- Masters -->
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" data-bs-toggle="dropdown" href="/engi">
<i class="bi bi-gear me-2"></i> Masters
</a>
<ul class="dropdown-menu dropdown-menu-dark">
<!-- Client Standard Rates -->
<li class="nav-item">
<a class="nav-link" href="/engi/subcontractor-rate">
<i class="bi bi-file-earmark-text me-1"></i> Rate Master
</a>
</li>
<!-- Client Standard Rates -->
<li class="nav-item">
<a class="nav-link" href="/engi/client-rate">
<i class="bi bi-file-earmark-text me-1"></i> Client Standard Rates
</a>
</li>
<!-- Formats -->
<li class="nav-item">
<a class="nav-link" href="/file_format">
<i class="bi bi-file-earmark-text me-1"></i> Formats
</a>
</li>
</ul>
</li>
<!-- USER DROPDOWN --> <!-- USER DROPDOWN -->
{% if session.get("user_id") %} {% if session.get("user_id") %}
<li class="nav-item dropdown ms-lg-3"> <li class="nav-item dropdown ms-lg-3">
@@ -193,28 +163,18 @@
<small class="text-muted">Logged in user</small> <small class="text-muted">Logged in user</small>
</li> </li>
<!-- Dashboard -->
<li> <li>
<a class="dropdown-item text-light py-2" href="{{ url_for('dashboard.dashboard') }}"> <a class="dropdown-item" href="/dashboard">
<i class="bi bi-speedometer2 me-2"></i> Dashboard <i class="bi bi-speedometer2 me-2"></i> Dashboard
</a> </a>
</li> </li>
<li> <li>
<a class="dropdown-item text-light py-2" href="{{ url_for('activity.activity') }}"> <a class="dropdown-item" href="{{ url_for('activity.activity') }}">
<i class="bi bi-clock-history me-2"></i> Activity Log <i class="bi bi-clock-history me-2"></i>
Activity Log
</a> </a>
</li> </li>
<!-- Manage Account -->
<li>
<a class="dropdown-item py-2" href="#">
<i class="bi bi-gear me-2"></i> Manage Account
</a>
</li>
<li><hr class="dropdown-divider border-secondary m-0"></li>
<!-- Logout Account -->
<li> <li>
<a class="dropdown-item text-warning" href="/logout"> <a class="dropdown-item text-warning" href="/logout">
<i class="bi bi-box-arrow-right me-2"></i> Logout <i class="bi bi-box-arrow-right me-2"></i> Logout

View File

@@ -0,0 +1,236 @@
{% extends "base.html" %}
{% block content %}
<div class="container-fluid mt-4">
<div class="card shadow">
<div class="card-header bg-primary text-white">
<h4 class="mb-0">
<i class="bi bi-currency-rupee"></i>
Subcontractor Rate Master
</h4>
</div>
<div class="card-body">
<form method="POST">
<div class="row">
<!-- Subcontractor -->
<div class="col-md-4 mb-3">
<label class="form-label fw-bold">
Subcontractor
</label>
<select name="subcontractor_id"
class="form-select"
required>
<option value="">
Select Subcontractor
</option>
{% for sub in subcontractors %}
<option value="{{ sub.id }}">
{{ sub.subcontractor_name }}
</option>
{% endfor %}
</select>
</div>
<!-- Category -->
<div class="col-md-4 mb-3">
<label class="form-label fw-bold">
Category
</label>
<select name="category"
class="form-select"
required>
<option value="">
Select Category
</option>
<option value="TR_EX">
Trench Excavation
</option>
<option value="MH_EX">
Manhole Excavation
</option>
<option value="MH_DC">
Manhole & Domestic Chamber
</option>
<option value="LAYING">
Pipe Laying
</option>
</select>
</div>
<!-- Status -->
<div class="col-md-4 mb-3">
<label class="form-label fw-bold">
Status
</label>
<select name="status"
class="form-select">
<option value="Active">
Active
</option>
<option value="Inactive">
Inactive
</option>
</select>
</div>
</div>
<div class="row">
<!-- Item Code -->
<div class="col-md-3 mb-3">
<label class="form-label fw-bold">
Item Code
</label>
<input type="text"
name="item_code"
class="form-control"
placeholder="SM01"
required>
</div>
<!-- Item Name -->
<div class="col-md-5 mb-3">
<label class="form-label fw-bold">
Item Name
</label>
<input type="text"
name="item_name"
class="form-control"
placeholder="Soft Murum 0-1.5"
required>
</div>
<!-- Unit -->
<div class="col-md-2 mb-3">
<label class="form-label fw-bold">
Unit
</label>
<select name="unit"
class="form-select">
<option value="Cum">Cum</option>
<option value="Nos">Nos</option>
<option value="Rmt">Rmt</option>
<option value="Sqm">Sqm</option>
</select>
</div>
<!-- Rate -->
<div class="col-md-2 mb-3">
<label class="form-label fw-bold">
Rate (₹)
</label>
<input type="number"
step="0.01"
min="0"
name="rate"
class="form-control"
placeholder="0.00"
required>
</div>
</div>
<div class="row">
<!-- Effective From -->
<div class="col-md-3 mb-3">
<label class="form-label fw-bold">
Effective From
</label>
<input type="date"
name="effective_from"
class="form-control"
required>
</div>
<!-- Effective To -->
<div class="col-md-3 mb-3">
<label class="form-label fw-bold">
Effective To
</label>
<input type="date"
name="effective_to"
class="form-control">
</div>
</div>
<hr>
<div class="text-end">
<button type="reset"
class="btn btn-secondary">
<i class="bi bi-arrow-clockwise"></i>
Reset
</button>
<button type="submit"
class="btn btn-success">
<i class="bi bi-check-circle"></i>
Save Rate
</button>
</div>
</form>
</div>
</div>
</div>
{% endblock %}

View File

@@ -1,20 +0,0 @@
{% extends "base.html" %}
{% block content %}
<div class="container-fluid mt-4">
<div class="card shadow">
<div class="card-header bg-primary text-white d-flex justify-content-between align-items-center">
<h4 class="mb-0">
<i class="bi bi-currency-rupee"></i>
Client Rate Master
</h4>
</div>
</div>
{% endblock %}

View File

@@ -1,384 +0,0 @@
{% extends "base.html" %}
{% block content %}
<div class="container-fluid mt-4">
<div class="card shadow">
<div class="card-header bg-primary text-white d-flex justify-content-between align-items-center">
<h4 class="mb-0">
<i class="bi bi-currency-rupee"></i>
Subcontractor Rate Master
</h4>
</div>
<div class="card-body">
<form method="POST" id="rateForm">
<!-- Hidden ID -->
<input type="hidden" id="rate_id" name="id" value="{{ rate.id if rate else '' }}">
<div class="row">
<!-- Subcontractor -->
<div class="col-md-4 mb-3">
<label class="form-label fw-bold"> Subcontractor </label>
<select id="subcontractor_id" name="subcontractor_id" class="form-select" required>
<option value="">-- Select Subcontractor --</option>
{% for sub in subcontractors %}
<option value="{{ sub.id }}"
{% if rate and rate.subcontractor_id==sub.id %}
selected
{% endif %}>
{{ sub.subcontractor_name }}
</option>
{% endfor %}
</select>
</div>
<!-- Category -->
<div class="col-md-4 mb-3">
<label class="form-label fw-bold"> Category </label>
<select id="category" name="category" class="form-select" required>
<option value="">-- Select Category --</option>
<option value="trench_excavation"
{% if rate and rate.category=="trench_excavation" %}selected{% endif %}>
Trench Excavation
</option>
<option value="manhole_excavation"
{% if rate and rate.category=="manhole_excavation" %}selected{% endif %}>
Manhole Excavation
</option>
<option value="Manhole_Domestic_Chamber"
{% if rate and rate.category=="Manhole_Domestic_Chamber" %}selected{% endif %}>
MH & Domestic Chamber
</option>
<option value="Laying"
{% if rate and rate.category=="Laying" %}selected{% endif %}>
Pipe Laying
</option>
</select>
</div>
<!-- Status -->
<div class="col-md-4 mb-3">
<label class="form-label fw-bold"> Status </label>
<select name="status" class="form-select">
<option value="Active"
{% if not rate or rate.status=="Active" %}selected{% endif %}>
Active
</option>
<option value="Inactive"
{% if rate and rate.status=="Inactive" %}selected{% endif %}>
Inactive
</option>
</select>
</div>
</div>
<div class="row">
<!-- Item Code -->
<div class="col-md-3 mb-3">
<label class="form-label fw-bold"> Item Code </label>
<input type="text" name="item_code" class="form-control" value="{{ rate.item_code if rate else '' }}" required>
</div>
<!-- Item Name -->
<div class="col-md-5 mb-3">
<label class="form-label fw-bold"> Item Name </label>
<input type="text"
id="item_name"
name="item_name"
class="form-control"
autocomplete="off"
value="{{ rate.item_name if rate else '' }}"
required>
<small id="duplicateMessage"
class="text-danger"
style="display:none;">
</small>
</div>
<!-- Unit -->
<div class="col-md-2 mb-3">
<label class="form-label fw-bold">Unit</label>
<select name="unit" class="form-select">
<option value="Cum"
{% if not rate or rate.unit=="Cum" %}selected{% endif %}>
Cum
</option>
<option value="Nos"
{% if rate and rate.unit=="Nos" %}selected{% endif %}>
Nos
</option>
<option value="Rmt"
{% if rate and rate.unit=="Rmt" %}selected{% endif %}>
Rmt
</option>
<option value="Sqm"
{% if rate and rate.unit=="Sqm" %}selected{% endif %}>
Sqm
</option>
</select>
</div>
<!-- Rate -->
<div class="col-md-2 mb-3">
<label class="form-label fw-bold">Rate</label>
<input type="number" step="0.01" name="rate" class="form-control" value="{{ rate.rate if rate else '' }}" required>
</div>
</div>
<div class="row">
<div class="col-md-3 mb-3">
<label class="form-label fw-bold"> Effective From </label>
<input type="date" name="effective_from" class="form-control" value="{{ rate.effective_from if rate else '' }}" required>
</div>
<div class="col-md-3 mb-3">
<label class="form-label fw-bold"> Effective To </label>
<input type="date" name="effective_to" class="form-control" value="{{ rate.effective_to if rate else '' }}">
</div>
</div>
<hr>
<div class="text-end">
<a href="{{ url_for('engineering.add_subcontractor_rates') }}" class="btn btn-secondary">
<i class="bi bi-arrow-clockwise"></i> Reset
</a>
<button type="submit" id="saveBtn" class="btn btn-success">
{% if rate %}
<i class="bi bi-pencil-square"></i>
Update Rate
{% else %}
<i class="bi bi-check-circle"></i>
Save Rate
{% endif %}
</button>
</div>
</form>
</div>
</div>
<!-- Table -->
<div class="card shadow mt-4">
<div class="card-header bg-dark text-white">
<h5 class="mb-0">
<i class="bi bi-table"></i>Rate List
</h5>
</div>
<div class="card-body">
<table class="table table-bordered table-hover table-striped" id="rateTable">
<thead class="table-primary">
<tr>
<th>#</th>
<th>Subcontractor</th>
<th>Category</th>
<th>Item Code</th>
<th>Item Name</th>
<th>Unit</th>
<th>Rate</th>
<th>Status</th>
<th width="130">Action</th>
</tr>
</thead>
<tbody>
{% for row in rates %}
<tr>
<td>{{ loop.index }}</td>
<td>{{ row.subcontractor.subcontractor_name }}</td>
<td>{{ row.category }}</td>
<td>{{ row.item_code }}</td>
<td>{{ row.item_name }}</td>
<td>{{ row.unit }}</td>
<td>{{ row.rate }}</td>
<td>
{% if row.status=="Active" %}
<span class="badge bg-success">
Active
</span>
{% else %}
<span class="badge bg-danger">
Inactive
</span>
{% endif %}
</td>
<td>
<a href="{{ url_for('engineering.edit_rate', rate_id=row.id) }}" class="btn btn-warning btn-sm">
<i class="bi bi-pencil-square"></i>
</a>
<a href="{{ url_for('engineering.delete_rate', rate_id=row.id) }}"
class="btn btn-danger btn-sm" onclick="return confirm('Delete this Item:{{row.item_name}} & Rate:{{row.rate}} ?')">
<i class="bi bi-trash"></i>
</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
<script>
$(document).ready(function () {
// ----------------------------
// DataTable
// ----------------------------
$("#rateTable").DataTable({
responsive: true,
pageLength: 10,
destroy: true
});
// ----------------------------
// Validate on field change
// ----------------------------
$("#subcontractor_id, #category").on("change", function () {
clearValidation();
checkDuplicateRate();
});
// ----------------------------
// Validate while typing
// ----------------------------
let timer;
$("#item_name").on("keyup input", function () {
clearTimeout(timer);
timer = setTimeout(function () {
checkDuplicateRate();
}, 300);
});
// Edit Mode
checkDuplicateRate();
// ----------------------------
// Prevent Submit
// ----------------------------
$("#rateForm").submit(function (e) {
if ($("#saveBtn").prop("disabled")) {
e.preventDefault();
$("#item_name").focus();
return false;
}
});
});
//=========================================
// Reset Validation
//=========================================
function clearValidation() {
$("#duplicateMessage")
.hide()
.text("")
.removeClass("text-success text-danger");
$("#item_name")
.removeClass("is-valid is-invalid");
$("#saveBtn").prop("disabled", false);
}
//=========================================
// Duplicate Validation
//=========================================
function checkDuplicateRate() {
let subcontractor = $("#subcontractor_id").val();
let category = $("#category").val();
let item_name = $("#item_name").val().trim();
let rate_id = $("#rate_id").val();
// Mandatory fields
if (
subcontractor == "" ||
category == "" ||
item_name.length < 2
) {
clearValidation();
return;
}
$.ajax({
url: "{{ url_for('engineering.check_rate') }}",
type: "GET",
dataType: "json",
data: {
subcontractor_id: subcontractor,
category: category,
item_name: item_name,
rate_id: rate_id
},
success: function (response) {
if (response.exists) {
$("#duplicateMessage")
.text("This Item Name already exists for the selected Subcontractor and Category.")
.removeClass("text-success")
.addClass("text-danger")
.show();
$("#item_name")
.removeClass("is-valid")
.addClass("is-invalid");
$("#saveBtn").prop("disabled", true);
}
else {
$("#duplicateMessage")
.text("Item Name is available.")
.removeClass("text-danger")
.addClass("text-success")
.show();
$("#item_name")
.removeClass("is-invalid")
.addClass("is-valid");
$("#saveBtn").prop("disabled", false);
}
},
error: function () {
clearValidation();
}
});
}
</script>
{% endblock %}

View File

View File

@@ -1,124 +0,0 @@
2026-08-06 12:44:45 | INFO | User=System | IP=- | - | - | ======================================================================
2026-08-06 12:44:45 | INFO | User=System | IP=- | - | - | Application Started Successfully
2026-08-06 12:44:45 | INFO | User=System | IP=- | - | - | ======================================================================
<<<<<<< HEAD
=======
2026-08-07 11:46:57 | INFO | User=System | IP=- | - | - | ======================================================================
2026-08-07 11:46:57 | INFO | User=System | IP=- | - | - | Application Started Successfully
2026-08-07 11:46:57 | INFO | User=System | IP=- | - | - | ======================================================================
2026-08-07 11:47:12 | INFO | User=System | IP=- | - | - | ======================================================================
2026-08-07 11:47:12 | INFO | User=System | IP=- | - | - | Application Started Successfully
2026-08-07 11:47:12 | INFO | User=System | IP=- | - | - | ======================================================================
2026-08-07 11:47:14 | INFO | User=System | IP=- | - | - | ======================================================================
2026-08-07 11:47:14 | INFO | User=System | IP=- | - | - | Application Started Successfully
2026-08-07 11:47:14 | INFO | User=System | IP=- | - | - | ======================================================================
2026-08-07 11:47:18 | INFO | User=Laxmi | IP=192.168.0.142 | POST | http://192.168.0.142:5015/file/Subcontractor_report | Request Started
2026-08-07 11:47:18 | INFO | User=Laxmi | IP=192.168.0.142 | POST | http://192.168.0.142:5015/file/Subcontractor_report | Request Completed | Status=200
2026-08-07 11:47:19 | INFO | User=Laxmi | IP=192.168.0.142 | GET | http://192.168.0.142:5015/static/images/lcepl.png | Request Started
2026-08-07 11:47:19 | INFO | User=Laxmi | IP=192.168.0.142 | GET | http://192.168.0.142:5015/static/images/lcepl.png | Request Completed | Status=200
2026-08-07 11:47:22 | INFO | User=Laxmi | IP=192.168.0.142 | GET | http://192.168.0.142:5015/logout | Request Started
2026-08-07 11:47:22 | INFO | User=Anonymous | IP=192.168.0.142 | GET | http://192.168.0.142:5015/logout | Logout successful. User=Laxmi
2026-08-07 11:47:22 | INFO | User=Anonymous | IP=192.168.0.142 | GET | http://192.168.0.142:5015/logout | Request Completed | Status=302
2026-08-07 11:47:22 | INFO | User=Anonymous | IP=192.168.0.142 | GET | http://192.168.0.142:5015/login | Request Started
2026-08-07 11:47:22 | INFO | User=Anonymous | IP=192.168.0.142 | GET | http://192.168.0.142:5015/login | Request Completed | Status=200
2026-08-07 11:47:22 | INFO | User=Anonymous | IP=192.168.0.142 | GET | http://192.168.0.142:5015/static/images/lcepl.png | Request Started
2026-08-07 11:47:22 | INFO | User=Anonymous | IP=192.168.0.142 | GET | http://192.168.0.142:5015/static/images/lcepl.png | Request Completed | Status=304
2026-08-07 11:47:30 | INFO | User=Anonymous | IP=192.168.0.142 | POST | http://192.168.0.142:5015/login | Request Started
2026-08-07 11:47:30 | INFO | User=Laxmi | IP=192.168.0.142 | POST | http://192.168.0.142:5015/login | Login successful. User=Laxmi
2026-08-07 11:47:30 | INFO | User=Laxmi | IP=192.168.0.142 | POST | http://192.168.0.142:5015/login | Request Completed | Status=302
2026-08-07 11:47:30 | INFO | User=Laxmi | IP=192.168.0.142 | GET | http://192.168.0.142:5015/dashboard/ | Request Started
2026-08-07 11:47:30 | INFO | User=Laxmi | IP=192.168.0.142 | GET | http://192.168.0.142:5015/dashboard/ | Request Completed | Status=200
2026-08-07 11:47:30 | INFO | User=Laxmi | IP=192.168.0.142 | GET | http://192.168.0.142:5015/dashboard/api/live-stats | Request Started
2026-08-07 11:47:30 | INFO | User=Laxmi | IP=192.168.0.142 | GET | http://192.168.0.142:5015/dashboard/api/live-stats | Request Completed | Status=200
2026-08-07 11:47:35 | INFO | User=Laxmi | IP=192.168.0.142 | GET | http://192.168.0.142:5015/file/Subcontractor_report | Request Started
2026-08-07 11:47:35 | INFO | User=Laxmi | IP=192.168.0.142 | GET | http://192.168.0.142:5015/file/Subcontractor_report | Request Completed | Status=200
2026-08-07 11:47:40 | INFO | User=Laxmi | IP=192.168.0.142 | POST | http://192.168.0.142:5015/file/Subcontractor_report | Request Started
2026-08-07 11:47:40 | INFO | User=Laxmi | IP=192.168.0.142 | POST | http://192.168.0.142:5015/file/Subcontractor_report | Request Completed | Status=200
2026-08-07 11:47:41 | INFO | User=Laxmi | IP=192.168.0.142 | POST | http://192.168.0.142:5015/file/Subcontractor_report | Request Started
2026-08-07 11:47:42 | INFO | User=Laxmi | IP=192.168.0.142 | POST | http://192.168.0.142:5015/file/Subcontractor_report | Request Completed | Status=200
2026-08-07 11:47:44 | INFO | User=Laxmi | IP=192.168.0.142 | POST | http://192.168.0.142:5015/file/Subcontractor_report | Request Started
2026-08-07 11:47:44 | INFO | User=Laxmi | IP=192.168.0.142 | POST | http://192.168.0.142:5015/file/Subcontractor_report | Request Completed | Status=200
2026-08-07 11:47:46 | INFO | User=Laxmi | IP=192.168.0.142 | POST | http://192.168.0.142:5015/file/Subcontractor_report | Request Started
2026-08-07 11:47:46 | INFO | User=Laxmi | IP=192.168.0.142 | POST | http://192.168.0.142:5015/file/Subcontractor_report | Request Completed | Status=200
2026-08-07 11:47:49 | INFO | User=Laxmi | IP=192.168.0.142 | GET | http://192.168.0.142:5015/file/Subcontractor_report | Request Started
2026-08-07 11:47:49 | INFO | User=Laxmi | IP=192.168.0.142 | GET | http://192.168.0.142:5015/file/Subcontractor_report | Request Completed | Status=200
2026-08-07 11:47:54 | INFO | User=Laxmi | IP=192.168.0.142 | POST | http://192.168.0.142:5015/file/Subcontractor_report | Request Started
2026-08-07 11:47:54 | INFO | User=Laxmi | IP=192.168.0.142 | POST | http://192.168.0.142:5015/file/Subcontractor_report | Request Completed | Status=200
2026-08-07 11:47:57 | INFO | User=Laxmi | IP=192.168.0.142 | POST | http://192.168.0.142:5015/file/Subcontractor_report | Request Started
2026-08-07 11:47:57 | INFO | User=Laxmi | IP=192.168.0.142 | POST | http://192.168.0.142:5015/file/Subcontractor_report | Request Completed | Status=200
2026-08-07 11:48:07 | INFO | User=Laxmi | IP=192.168.0.142 | POST | http://192.168.0.142:5015/file/Subcontractor_report | Request Started
2026-08-07 11:48:07 | INFO | User=Laxmi | IP=192.168.0.142 | POST | http://192.168.0.142:5015/file/Subcontractor_report | Request Completed | Status=200
2026-08-07 11:48:11 | INFO | User=Laxmi | IP=192.168.0.142 | POST | http://192.168.0.142:5015/file/Subcontractor_report | Request Started
2026-08-07 11:48:11 | INFO | User=Laxmi | IP=192.168.0.142 | POST | http://192.168.0.142:5015/file/Subcontractor_report | Request Completed | Status=200
2026-08-07 12:02:57 | INFO | User=System | IP=- | - | - | ======================================================================
2026-08-07 12:02:57 | INFO | User=System | IP=- | - | - | Application Started Successfully
2026-08-07 12:02:57 | INFO | User=System | IP=- | - | - | ======================================================================
2026-08-07 12:03:04 | INFO | User=System | IP=- | - | - | ======================================================================
2026-08-07 12:03:04 | INFO | User=System | IP=- | - | - | Application Started Successfully
2026-08-07 12:03:04 | INFO | User=System | IP=- | - | - | ======================================================================
2026-08-07 12:04:23 | INFO | User=Admin | IP=192.168.0.118 | GET | http://192.168.0.118:5015/ | Request Started
2026-08-07 12:04:23 | INFO | User=Admin | IP=192.168.0.118 | GET | http://192.168.0.118:5015/ | Request Completed | Status=302
2026-08-07 12:04:23 | INFO | User=Admin | IP=192.168.0.118 | GET | http://192.168.0.118:5015/login | Request Started
2026-08-07 12:04:23 | INFO | User=Admin | IP=192.168.0.118 | GET | http://192.168.0.118:5015/login | User already logged in.
2026-08-07 12:04:23 | INFO | User=Admin | IP=192.168.0.118 | GET | http://192.168.0.118:5015/login | Request Completed | Status=302
2026-08-07 12:04:23 | INFO | User=Admin | IP=192.168.0.118 | GET | http://192.168.0.118:5015/dashboard/ | Request Started
2026-08-07 12:04:23 | INFO | User=Admin | IP=192.168.0.118 | GET | http://192.168.0.118:5015/dashboard/ | Request Completed | Status=200
2026-08-07 12:04:23 | INFO | User=Admin | IP=192.168.0.118 | GET | http://192.168.0.118:5015/dashboard/api/live-stats | Request Started
2026-08-07 12:04:23 | INFO | User=Admin | IP=192.168.0.118 | GET | http://192.168.0.118:5015/dashboard/api/live-stats | Request Completed | Status=200
2026-08-07 12:04:33 | INFO | User=Admin | IP=192.168.0.118 | GET | http://192.168.0.118:5015/dashboard/api/live-stats | Request Started
2026-08-07 12:04:33 | INFO | User=Admin | IP=192.168.0.118 | GET | http://192.168.0.118:5015/dashboard/api/live-stats | Request Completed | Status=200
2026-08-07 12:04:37 | INFO | User=Admin | IP=192.168.0.118 | GET | http://192.168.0.118:5015/engi/client-rate | Request Started
2026-08-07 12:04:37 | INFO | User=Admin | IP=192.168.0.118 | GET | http://192.168.0.118:5015/engi/client-rate | Request Completed | Status=200
2026-08-07 12:04:39 | INFO | User=Admin | IP=192.168.0.118 | GET | http://192.168.0.118:5015/file_format | Request Started
2026-08-07 12:04:39 | INFO | User=Admin | IP=192.168.0.118 | GET | http://192.168.0.118:5015/file_format | Request Completed | Status=200
2026-08-07 12:04:40 | INFO | User=Admin | IP=192.168.0.118 | GET | http://192.168.0.118:5015/file_format | Request Started
2026-08-07 12:04:40 | INFO | User=Admin | IP=192.168.0.118 | GET | http://192.168.0.118:5015/file_format | Request Completed | Status=200
2026-08-07 12:04:41 | INFO | User=Admin | IP=192.168.0.118 | GET | http://192.168.0.118:5015/file_format | Request Started
2026-08-07 12:04:41 | INFO | User=Admin | IP=192.168.0.118 | GET | http://192.168.0.118:5015/file_format | Request Completed | Status=200
2026-08-07 12:04:42 | INFO | User=Admin | IP=192.168.0.118 | GET | http://192.168.0.118:5015/file_format | Request Started
2026-08-07 12:04:42 | INFO | User=Admin | IP=192.168.0.118 | GET | http://192.168.0.118:5015/file_format | Request Completed | Status=200
2026-08-07 12:04:42 | INFO | User=Admin | IP=192.168.0.118 | GET | http://192.168.0.118:5015/file_format | Request Started
2026-08-07 12:04:42 | INFO | User=Admin | IP=192.168.0.118 | GET | http://192.168.0.118:5015/file_format | Request Completed | Status=200
2026-08-07 12:04:44 | INFO | User=Admin | IP=192.168.0.118 | GET | http://192.168.0.118:5015/file/import_client | Request Started
2026-08-07 12:04:44 | INFO | User=Admin | IP=192.168.0.118 | GET | http://192.168.0.118:5015/file/import_client | Request Completed | Status=200
2026-08-07 12:04:46 | INFO | User=Admin | IP=192.168.0.118 | GET | http://192.168.0.118:5015/file/Subcontractor_report | Request Started
2026-08-07 12:04:46 | INFO | User=Admin | IP=192.168.0.118 | GET | http://192.168.0.118:5015/file/Subcontractor_report | Request Completed | Status=200
2026-08-07 12:04:49 | INFO | User=Admin | IP=192.168.0.118 | GET | http://192.168.0.118:5015/file/Subcontractor_report | Request Started
2026-08-07 12:04:49 | INFO | User=Admin | IP=192.168.0.118 | GET | http://192.168.0.118:5015/file/Subcontractor_report | Request Completed | Status=200
2026-08-07 12:04:52 | INFO | User=Admin | IP=192.168.0.118 | POST | http://192.168.0.118:5015/file/Subcontractor_report | Request Started
2026-08-07 12:04:52 | INFO | User=Admin | IP=192.168.0.118 | POST | http://192.168.0.118:5015/file/Subcontractor_report | Request Completed | Status=200
2026-08-07 12:04:54 | INFO | User=Admin | IP=192.168.0.118 | GET | http://192.168.0.118:5015/file/Subcontractor_report | Request Started
2026-08-07 12:04:54 | INFO | User=Admin | IP=192.168.0.118 | GET | http://192.168.0.118:5015/file/Subcontractor_report | Request Completed | Status=200
2026-08-07 12:05:01 | INFO | User=Admin | IP=192.168.0.118 | GET | http://192.168.0.118:5015/dashboard/ | Request Started
2026-08-07 12:05:01 | INFO | User=Admin | IP=192.168.0.118 | GET | http://192.168.0.118:5015/dashboard/ | Request Completed | Status=200
2026-08-07 12:05:01 | INFO | User=Admin | IP=192.168.0.118 | GET | http://192.168.0.118:5015/dashboard/api/live-stats | Request Started
2026-08-07 12:05:01 | INFO | User=Admin | IP=192.168.0.118 | GET | http://192.168.0.118:5015/dashboard/api/live-stats | Request Completed | Status=200
2026-08-07 12:05:02 | INFO | User=Admin | IP=192.168.0.118 | GET | http://192.168.0.118:5015/activity/ | Request Started
2026-08-07 12:05:02 | INFO | User=Admin | IP=192.168.0.118 | GET | http://192.168.0.118:5015/activity/ | Request Completed | Status=200
2026-08-07 12:07:06 | INFO | User=System | IP=- | - | - | ======================================================================
2026-08-07 12:07:06 | INFO | User=System | IP=- | - | - | Application Started Successfully
2026-08-07 12:07:06 | INFO | User=System | IP=- | - | - | ======================================================================
2026-08-07 12:07:07 | INFO | User=System | IP=- | - | - | ======================================================================
2026-08-07 12:07:07 | INFO | User=System | IP=- | - | - | Application Started Successfully
2026-08-07 12:07:07 | INFO | User=System | IP=- | - | - | ======================================================================
2026-08-07 12:07:09 | INFO | User=Admin | IP=192.168.0.118 | GET | http://192.168.0.118:5015/activity/ | Request Started
2026-08-07 12:07:09 | INFO | User=Admin | IP=192.168.0.118 | GET | http://192.168.0.118:5015/activity/ | Request Completed | Status=200
2026-08-07 12:07:10 | INFO | User=Admin | IP=192.168.0.118 | GET | http://192.168.0.118:5015/engi/subcontractor-rate | Request Started
2026-08-07 12:07:11 | INFO | User=Admin | IP=192.168.0.118 | GET | http://192.168.0.118:5015/engi/subcontractor-rate | Request Completed | Status=200
2026-08-07 12:07:11 | INFO | User=Admin | IP=192.168.0.118 | GET | http://192.168.0.118:5015/static/images/lcepl.png | Request Started
2026-08-07 12:07:11 | INFO | User=Admin | IP=192.168.0.118 | GET | http://192.168.0.118:5015/static/images/lcepl.png | Request Completed | Status=304
2026-08-07 12:07:14 | INFO | User=Admin | IP=192.168.0.118 | GET | http://192.168.0.118:5015/engi/client-rate | Request Started
2026-08-07 12:07:14 | INFO | User=Admin | IP=192.168.0.118 | GET | http://192.168.0.118:5015/engi/client-rate | Request Completed | Status=200
2026-08-07 12:07:16 | INFO | User=Admin | IP=192.168.0.118 | GET | http://192.168.0.118:5015/file_format | Request Started
2026-08-07 12:07:16 | INFO | User=Admin | IP=192.168.0.118 | GET | http://192.168.0.118:5015/file_format | Request Completed | Status=200
2026-08-07 12:07:16 | INFO | User=Admin | IP=192.168.0.118 | GET | http://192.168.0.118:5015/engi/subcontractor-rate | Request Started
2026-08-07 12:07:16 | INFO | User=Admin | IP=192.168.0.118 | GET | http://192.168.0.118:5015/engi/subcontractor-rate | Request Completed | Status=200
2026-08-07 12:07:18 | INFO | User=Admin | IP=192.168.0.118 | GET | http://192.168.0.118:5015/engi/subcontractor-rate | Request Started
2026-08-07 12:07:18 | INFO | User=Admin | IP=192.168.0.118 | GET | http://192.168.0.118:5015/engi/subcontractor-rate | Request Completed | Status=200
2026-08-07 12:07:23 | INFO | User=Admin | IP=192.168.0.118 | GET | http://192.168.0.118:5015/dashboard/ | Request Started
2026-08-07 12:07:23 | INFO | User=Admin | IP=192.168.0.118 | GET | http://192.168.0.118:5015/dashboard/ | Request Completed | Status=200
2026-08-07 12:07:23 | INFO | User=Admin | IP=192.168.0.118 | GET | http://192.168.0.118:5015/dashboard/api/live-stats | Request Started
2026-08-07 12:07:23 | INFO | User=Admin | IP=192.168.0.118 | GET | http://192.168.0.118:5015/dashboard/api/live-stats | Request Completed | Status=200
2026-08-07 12:07:24 | INFO | User=Admin | IP=192.168.0.118 | GET | http://192.168.0.118:5015/engi/subcontractor-rate | Request Started
2026-08-07 12:07:24 | INFO | User=Admin | IP=192.168.0.118 | GET | http://192.168.0.118:5015/engi/subcontractor-rate | Request Completed | Status=200
>>>>>>> pankaj-dev