Compare commits

..

12 Commits

Author SHA1 Message Date
b93509bd8a update 2026-04-06 13:39:04 +05:30
e99d43139b update excel summary 2026-04-06 13:04:42 +05:30
a202da621c unreleased_gst will comment for not use 2026-04-06 12:22:28 +05:30
5ae1fbe320 final payment reconciliation 2026-04-06 10:46:47 +05:30
0ca1749757 hold issue solve 2026-04-04 14:48:19 +05:30
7981ad0206 testing code 2026-04-04 14:18:58 +05:30
0ec878d2ec add excel.py 2026-04-01 19:24:32 +05:30
076f9ef2f1 update code and remove comments 2026-04-01 16:23:46 +05:30
ecd944d637 update 2026-04-01 11:09:45 +05:30
cd16c284ce update 2026-03-31 16:24:58 +05:30
4e5887b160 template 2026-03-31 13:08:12 +05:30
9163355924 update 2026-03-31 13:00:29 +05:30
44 changed files with 2650 additions and 3040 deletions

View File

@@ -7,12 +7,11 @@ from model.Block import Block
from model.Utilities import HtmlHelper from model.Utilities import HtmlHelper
block_bp = Blueprint('block', __name__) block_bp = Blueprint('block', __name__)
block = Block()
# --- Add Block page ------- # --- Add Block page -------
@block_bp.route('/add_block', methods=['GET', 'POST']) @block_bp.route('/add_block', methods=['GET', 'POST'])
@login_required @login_required
def add_block(): def add_block():
block = Block()
if request.method == 'POST': if request.method == 'POST':
block.AddBlock(request) block.AddBlock(request)
@@ -30,7 +29,7 @@ def add_block():
) )
# ✅ NEW ROUTE (FIX FOR DISTRICT FETCH) # get district
@block_bp.route('/get_districts/<int:state_id>') @block_bp.route('/get_districts/<int:state_id>')
@login_required @login_required
def get_districts(state_id): def get_districts(state_id):
@@ -62,7 +61,6 @@ def get_districts(state_id):
@login_required @login_required
def check_block(): def check_block():
block = Block()
return block.CheckBlock(request) return block.CheckBlock(request)
@@ -70,8 +68,6 @@ def check_block():
@login_required @login_required
def edit_block(block_id): def edit_block(block_id):
block = Block()
if request.method == 'POST': if request.method == 'POST':
block.EditBlock(request, block_id) block.EditBlock(request, block_id)
block.resultMessage block.resultMessage
@@ -90,7 +86,7 @@ def edit_block(block_id):
for rs in cursor.stored_results(): for rs in cursor.stored_results():
states = rs.fetchall() states = rs.fetchall()
cursor.callproc("GetAllDistrictsData") cursor.callproc("GetAllDistricts")
for rs in cursor.stored_results(): for rs in cursor.stored_results():
districts = rs.fetchall() districts = rs.fetchall()
@@ -111,7 +107,6 @@ def edit_block(block_id):
@login_required @login_required
def delete_block(block_id): def delete_block(block_id):
block = Block()
block.DeleteBlock(request, block_id) block.DeleteBlock(request, block_id)
return redirect(url_for('block.add_block')) return redirect(url_for('block.add_block'))

View File

@@ -5,12 +5,13 @@ from model.District import District
from model.State import State from model.State import State
district_bp = Blueprint('district', __name__) district_bp = Blueprint('district', __name__)
district = District()
# ------- District page -------- # ------- District page --------
@district_bp.route('/add_district', methods=['GET', 'POST']) @district_bp.route('/add_district', methods=['GET', 'POST'])
@login_required @login_required
def add_district(): def add_district():
district = District() # district = District()
if request.method == 'POST': if request.method == 'POST':
district.AddDistrict(request=request) district.AddDistrict(request=request)
@@ -32,7 +33,7 @@ def add_district():
@login_required @login_required
def check_district(): def check_district():
district = District() # district = District()
return district.CheckDistrict(request=request) return district.CheckDistrict(request=request)
@@ -41,7 +42,7 @@ def check_district():
@login_required @login_required
def delete_district(district_id): def delete_district(district_id):
district = District() # district = District()
district.DeleteDistrict(request=request, district_id=district_id) district.DeleteDistrict(request=request, district_id=district_id)
@@ -56,7 +57,7 @@ def delete_district(district_id):
@login_required @login_required
def edit_district(district_id): def edit_district(district_id):
district = District() # district = District()
state = State() state = State()
if request.method == 'POST': if request.method == 'POST':

View File

@@ -66,7 +66,7 @@ def show_table(filename):
errors.append(f"State '{file_info['State']}' is not valid. Please add it.") errors.append(f"State '{file_info['State']}' is not valid. Please add it.")
if state_data: if state_data:
cursor.callproc('GetDistrictByNameAndState', [file_info['District'], state_data['State_ID']]) # Change GetDistrictByNameAndStates to GetDistrictByNameAndState cursor.callproc('GetDistrictByNameAndState', [file_info['District'], state_data['State_Id']]) # Change GetDistrictByNameAndStates to GetDistrictByNameAndState
for result in cursor.stored_results(): for result in cursor.stored_results():
district_data = result.fetchone() district_data = result.fetchone()
if not district_data: if not district_data:
@@ -84,7 +84,7 @@ def show_table(filename):
subcontractor_data = result.fetchone() subcontractor_data = result.fetchone()
if not subcontractor_data: if not subcontractor_data:
cursor.callproc('InsertSubcontractor', [file_info['Subcontractor']]) cursor.callproc('SaveContractor', [file_info.get('Subcontractor'),None,None,None,None,None,None,None,None])
connection.commit() connection.commit()
cursor.callproc('GetSubcontractorByName', [file_info['Subcontractor']]) cursor.callproc('GetSubcontractorByName', [file_info['Subcontractor']])
for result in cursor.stored_results(): for result in cursor.stored_results():
@@ -186,7 +186,7 @@ def save_data():
"SD_Amount": entry.get("SD_Amount", 0.00), "SD_Amount": entry.get("SD_Amount", 0.00),
"On_Commission": entry.get("On_Commission", 0.00), "On_Commission": entry.get("On_Commission", 0.00),
"Hydro_Testing": entry.get("Hydro_Testing", 0.00), "Hydro_Testing": entry.get("Hydro_Testing", 0.00),
"Hold_Amount": 0, "Hold_Amount": entry.get("Hold_Amount", 0.00), # change
"GST_SD_Amount": entry.get("GST_SD_Amount", 0.00), "GST_SD_Amount": entry.get("GST_SD_Amount", 0.00),
"Final_Amount": entry.get("Final_Amount", 0.00), "Final_Amount": entry.get("Final_Amount", 0.00),
"Payment_Amount": entry.get("Payment_Amount", 0.00), "Payment_Amount": entry.get("Payment_Amount", 0.00),
@@ -242,12 +242,7 @@ def save_data():
for result in cursor.stored_results(): for result in cursor.stored_results():
result = result.fetchone() result = result.fetchone()
village_id = result[0] if result else None village_id = result[0] if result else None
# print("village_id :", village_id)
# print("block_id :", block_id)
# print("invoice :", PMC_No, village_id, work_type, Invoice_Details, Invoice_Date, Invoice_No,
# Basic_Amount, Debit_Amount, After_Debit_Amount, Amount, GST_Amount, TDS_Amount,
# SD_Amount, On_Commission, Hydro_Testing, GST_SD_Amount, Final_Amount)
args = ( args = (
PMC_No, village_id, work_type, Invoice_Details, Invoice_Date, Invoice_No, PMC_No, village_id, work_type, Invoice_Details, Invoice_Date, Invoice_No,
Basic_Amount, Debit_Amount, After_Debit_Amount, Amount, GST_Amount, TDS_Amount, Basic_Amount, Debit_Amount, After_Debit_Amount, Amount, GST_Amount, TDS_Amount,
@@ -255,27 +250,25 @@ def save_data():
subcontractor_id, 0 subcontractor_id, 0
) )
# print("All invoice Details ",args)
# add subcontarctor id in invoice table # add subcontarctor id in invoice table
results = cursor.callproc('SaveInvoice', args) results = cursor.callproc('SaveInvoice', args)
invoice_id = results[-1] invoice_id = results[-1]
print("**************************************************************")
print(invoice_id)
print("**************************************************************")
cursor.callproc( cursor.callproc(
"SavePayment", "SavePayment",
( (
PMC_No, PMC_No,
Invoice_No, # required Invoice_No,
Payment_Amount, Payment_Amount,
TDS_Payment_Amount, TDS_Payment_Amount,
Total_Amount, Total_Amount,
UTR, UTR,
invoice_id # last invoice_id
) )
) )
# print("invoice id from the excel ", invoice_id)
if isinstance(hold_columns, str): if isinstance(hold_columns, str):
hold_columns = ast.literal_eval(hold_columns) hold_columns = ast.literal_eval(hold_columns)
if isinstance(hold_columns, list) and all(isinstance(hold, dict) for hold in hold_columns): if isinstance(hold_columns, list) and all(isinstance(hold, dict) for hold in hold_columns):
@@ -287,7 +280,7 @@ def save_data():
hold_amount = entry.get( hold_amount = entry.get(
hold_column_name) # Get the value for that specific hold column hold_column_name) # Get the value for that specific hold column
if hold_amount is not None: if hold_amount is not None:
# print(f"Processing hold type: {hold_column_name}, Hold Amount: {hold_amount}")
hold_join_data = { hold_join_data = {
"Contractor_Id": subcontractor_id, "Contractor_Id": subcontractor_id,
"Invoice_Id": invoice_id, "Invoice_Id": invoice_id,
@@ -304,10 +297,8 @@ def save_data():
print(f"Invalid hold entry: {hold}") print(f"Invalid hold entry: {hold}")
else: else:
print("Hold columns data is not a valid list of dictionaries.") print("Hold columns data is not a valid list of dictionaries.")
#---------------------------------------------Credit Note--------------------------------------------------------------------------- #-----------------------------------Credit Note----------------------------------------------------------------
elif any(keyword in Invoice_Details.lower() for keyword in ['credit note','logging report']): elif any(keyword in Invoice_Details.lower() for keyword in ['credit', 'logging report']):
# print("Credit note found:", PMC_No, Invoice_No, Basic_Amount, Debit_Amount, Final_Amount,
# After_Debit_Amount, GST_Amount, Amount, Final_Amount, Payment_Amount, Total_Amount, UTR, Invoice_No)
cursor.callproc( cursor.callproc(
'AddCreditNoteFromExcel', 'AddCreditNoteFromExcel',
[ [
@@ -316,7 +307,7 @@ def save_data():
subcontractor_id, Invoice_No subcontractor_id, Invoice_No
] ]
) )
#-----------------------------------------------Hold Amount---------------------------------------------------------------------- #---------------------------------------Hold Amount-----------------------------------------------------------
# Step 1: Normalize Invoice_Details: lowercase, trim, remove extra spaces # Step 1: Normalize Invoice_Details: lowercase, trim, remove extra spaces
normalized_details = re.sub(r'\s+', ' ', Invoice_Details.strip()).lower() normalized_details = re.sub(r'\s+', ' ', Invoice_Details.strip()).lower()
# Step 2: Define lowercase keywords # Step 2: Define lowercase keywords
@@ -332,65 +323,33 @@ def save_data():
] ]
# Step 3: Matching condition # Step 3: Matching condition
if any(kw in normalized_details for kw in keywords): if any(kw in normalized_details for kw in keywords):
# print("✅ Match found. Inserting hold release for:", Invoice_Details)
cursor.callproc( cursor.callproc(
'AddHoldReleaseFromExcel', 'AddHoldReleaseFromExcel',
[PMC_No, Invoice_No, Invoice_Details, Basic_Amount, Final_Amount, UTR, subcontractor_id] [PMC_No, Invoice_No, Invoice_Details, Basic_Amount, Final_Amount, UTR, subcontractor_id])
)
connection.commit() connection.commit()
# print("✅ Hold release inserted for:", PMC_No, Invoice_Details)
#------------------------------------------------------------------------------------------------------------------ #------------------------------------------------------------------------------------------------------------------
elif Invoice_Details and any( elif Invoice_Details and any(
keyword in Invoice_Details.lower() for keyword in ['gst', 'release', 'gst release note']): keyword in Invoice_Details.lower() for keyword in ['gst', 'release', 'gst release note']):
# print("Gst rels :", PMC_No, Invoice_No, Basic_Amount, Final_Amount,Total_Amount,UTR, subcontractor_id)
cursor.callproc( cursor.callproc(
'AddGSTReleaseFromExcel', 'AddGSTReleaseFromExcel',
[PMC_No, Invoice_No, Basic_Amount, Final_Amount, Total_Amount, UTR, subcontractor_id] [PMC_No, Invoice_No, Basic_Amount, Final_Amount, Total_Amount, UTR, subcontractor_id]
) )
# -------------------------------------- # --------------------------------------
# If no village/work detected, only PMC/Payment # If no village/work detected, only PMC/Payment
if not (Invoice_Details and 'village' in Invoice_Details.lower() and 'work' in Invoice_Details.lower()): if not (Invoice_Details and 'village' in Invoice_Details.lower() and 'work' in Invoice_Details.lower()):
# if not (Invoice_Details and 'village' in Invoice_Details.lower() and 'work' in Invoice_Details.lower() and 'gst' in Invoice_Details.lower() and 'gst release note' in Invoice_Details.lower() and 'release' in Invoice_Details.lower()):
# ---------- Only PMC / Payment rows ---------- # ---------- Only PMC / Payment rows ----------
if PMC_No and not Invoice_No and UTR : if PMC_No and not Invoice_No and UTR :
# print("No village/work, using PMC only :", PMC_No) cursor.callproc("insertExtrapaymet",(PMC_No, subcontractor_id))
for result in cursor.stored_results():
# check invoice exists row = result.fetchone()
# cursor.execute( invoice_id = row[0] if row else None
# "SELECT invoice_id FROM invoice WHERE PMC_No=%s ORDER BY invoice_id DESC LIMIT 1",
# (PMC_No,)
# )
# row = cursor.fetchone()
# invoice_id = row[0] if row else None
# # insert invoice if not exists
# if not invoice_id:
print(" extra payment :", PMC_No,Total_Amount,UTR, subcontractor_id)
cursor.execute(
"""
INSERT INTO invoice (PMC_No,Contractor_Id) VALUES (%s, %s);
""",
(PMC_No, subcontractor_id)
)
connection.commit()
cursor.execute(
"SELECT invoice_id FROM invoice WHERE PMC_No=%s AND Contractor_Id =%s ORDER BY invoice_id DESC LIMIT 1",
(PMC_No, subcontractor_id)
)
row = cursor.fetchone()
invoice_id = row[0] if row else None
# insert payment # insert payment
cursor.callproc( cursor.callproc(
"SavePayment", "SavePayment",
( (
PMC_No, PMC_No,
Invoice_No, # required Invoice_No,
Payment_Amount, Payment_Amount,
TDS_Payment_Amount, TDS_Payment_Amount,
Total_Amount, Total_Amount,
@@ -399,39 +358,6 @@ def save_data():
) )
) )
# if PMC_No and Total_Amount and UTR:
# print("Payment :", PMC_No, Invoice_No, Payment_Amount, TDS_Payment_Amount, Total_Amount, UTR )
# Add inoice id in payment table
# cursor.callproc("SavePayment",(PMC_No, Invoice_No, Payment_Amount, TDS_Payment_Amount, Total_Amount, UTR, invoice_id))
if not village_id:
village_id = None
# cursor.callproc('InsertOrUpdateInPayment', (
# PMC_No,
# village_id,
# work_type,
# Invoice_Details,
# Invoice_Date,
# Invoice_No,
# Basic_Amount,
# Debit_Amount,
# After_Debit_Amount,
# Amount,
# GST_Amount,
# TDS_Amount,
# SD_Amount,
# On_Commission,
# Hydro_Testing,
# 0,
# GST_SD_Amount,
# Final_Amount,
# Payment_Amount,
# TDS_Payment_Amount,
# Total_Amount,
# UTR,f
# subcontractor_id
# ))
connection.commit() connection.commit()
return jsonify({"success": "Data saved successfully!"}), 200 return jsonify({"success": "Data saved successfully!"}), 200
except Exception as e: except Exception as e:
@@ -441,4 +367,3 @@ def save_data():
cursor.close() cursor.close()
connection.close() connection.close()
return render_template('index.html') return render_template('index.html')
# ---------------------- Report --------------------------------

View File

@@ -1,20 +1,18 @@
from flask import Blueprint, render_template, request, jsonify, redirect, url_for from flask import Blueprint, render_template, request, jsonify, redirect, url_for
from flask_login import login_required from flask_login import login_required
from model.HoldTypes import HoldTypes from model.HoldTypes import HoldTypes
from model.GST import GST # from model.GST import GST
hold_bp = Blueprint("hold_types", __name__) hold_bp = Blueprint("hold_types", __name__)
hold = HoldTypes()
# ---------------- ADD HOLD TYPE ---------------- # ---------------- ADD HOLD TYPE ----------------
@hold_bp.route('/add_hold_type', methods=['GET','POST']) @hold_bp.route('/add_hold_type', methods=['GET','POST'])
@login_required @login_required
def add_hold_type(): def add_hold_type():
hold = HoldTypes()
if request.method == 'POST': if request.method == 'POST':
hold.AddHoldType(request) hold.AddHoldType(request)
# Always redirect to same page (NO JSON) # Always redirect to same page (NO JSON)
return redirect(url_for("hold_types.add_hold_type")) return redirect(url_for("hold_types.add_hold_type"))
# GET request → show data # GET request → show data
@@ -30,7 +28,6 @@ def add_hold_type():
@login_required @login_required
def check_hold_type(): def check_hold_type():
hold = HoldTypes()
return hold.CheckHoldType(request) # if exists return hold.CheckHoldType(request) # if exists
@@ -39,13 +36,11 @@ def check_hold_type():
@login_required @login_required
def edit_hold_type(id): def edit_hold_type(id):
hold = HoldTypes()
if request.method == 'POST': if request.method == 'POST':
hold.EditHoldType(request, id) # ✅ hold.EditHoldType(request, id)
return hold.resultMessage return hold.resultMessage
hold_data = hold.GetHoldTypeByID(id) # ✅ hold_data = hold.GetHoldTypeByID(id)
return render_template( return render_template(
"edit_hold_type.html", "edit_hold_type.html",
@@ -58,20 +53,18 @@ def edit_hold_type(id):
@login_required @login_required
def delete_hold_type(id): def delete_hold_type(id):
hold = HoldTypes() hold.DeleteHoldType(request, id)
hold.DeleteHoldType(request, id) # ✅
return redirect(url_for("hold_types.add_hold_type")) return redirect(url_for("hold_types.add_hold_type"))
# ---------------- GST ---------------- # ---------------- GST ----------------
@hold_bp.route('/unreleased_gst') # @hold_bp.route('/unreleased_gst')
@login_required # @login_required
def unreleased_gst(): # def unreleased_gst():
data = GST.get_unreleased_gst() # data = GST.get_unreleased_gst()
return render_template( # return render_template(
"unreleased_gst.html", # "unreleased_gst.html",
data=data # data=data
) # )

View File

@@ -1,5 +1,3 @@
# controllers/invoice_controller.py
from flask import Blueprint, request, jsonify, render_template from flask import Blueprint, request, jsonify, render_template
from flask_login import login_required, current_user from flask_login import login_required, current_user
from model.Invoice import * from model.Invoice import *
@@ -37,11 +35,7 @@ def add_invoice():
village_id = village_result['Village_Id'] village_id = village_result['Village_Id']
invoice_id = insert_invoice(data, village_id) invoice_id = insert_invoice(data, village_id)
# assign_subcontractor(data, village_id)
print("********************************************************************")
print("Manully added invoice id :",invoice_id)
print("********************************************************************")
insert_hold_types(data, invoice_id) insert_hold_types(data, invoice_id)
log_action("Add invoice", f"added invoice '{data.get('pmc_no')}'") log_action("Add invoice", f"added invoice '{data.get('pmc_no')}'")
@@ -84,7 +78,6 @@ def edit_invoice(invoice_id):
if request.method == 'POST': if request.method == 'POST':
data = request.form data = request.form
update_invoice(data, invoice_id) update_invoice(data, invoice_id)
# update_inpayment(data)
log_action("Edit invoice", f"edited invoice '{invoice_id}'") log_action("Edit invoice", f"edited invoice '{invoice_id}'")
return jsonify({"status": "success", "message": "Invoice updated successfully"}), 200 return jsonify({"status": "success", "message": "Invoice updated successfully"}), 200

View File

@@ -29,8 +29,7 @@ def add_payment():
LogHelper.log_action("Add Payment", f"User {current_user.id} Add Payment '{pmc_no}'") LogHelper.log_action("Add Payment", f"User {current_user.id} Add Payment '{pmc_no}'")
Paymentmodel.insert_payment(subcontractor_id,pmc_no, invoice_no, amount, tds_amount, total_amount, utr) Paymentmodel.insert_payment(subcontractor_id,pmc_no, invoice_no, amount, tds_amount, total_amount, utr)
# Paymentmodel.update_inpayment(subcontractor_id, pmc_no, invoice_no, amount, tds_amount, total_amount, utr)
return redirect(url_for('payment_bp.add_payment')) return redirect(url_for('payment_bp.add_payment'))
return render_template('add_payment.html', payments=payments) return render_template('add_payment.html', payments=payments)
@@ -71,14 +70,6 @@ def edit_payment(payment_id):
LogHelper.log_action("Edit Payment", f"User {current_user.id} Edit Payment '{pmc_no}'") LogHelper.log_action("Edit Payment", f"User {current_user.id} Edit Payment '{pmc_no}'")
Paymentmodel.call_update_payment_proc(payment_id, pmc_no, invoice_no, amount, tds_amount, total_amount, utr) Paymentmodel.call_update_payment_proc(payment_id, pmc_no, invoice_no, amount, tds_amount, total_amount, utr)
# Update inpayment
# connection = Paymentmodel.get_connection()
# cursor = connection.cursor()
# cursor.callproc('UpdateInpaymentByPMCInvoiceUTR',[amount, tds_amount, total_amount, pmc_no, invoice_no, utr])
# connection.commit()
# cursor.close()
# connection.close()
return redirect(url_for('payment_bp.add_payment')) return redirect(url_for('payment_bp.add_payment'))

View File

@@ -1,14 +1,13 @@
from flask import Blueprint, render_template, send_from_directory from flask import Blueprint, render_template, send_from_directory,send_file
from flask_login import login_required from flask_login import login_required
from model.PmcReport import PmcReport from model.UnifiedReportService import UnifiedReportService
pmc_report_bp = Blueprint("pmc_report", __name__) pmc_report_bp = Blueprint("pmc_report", __name__)
# ---------------- Contractor Report by pmc no ---------------- # ---------------- Contractor Report by pmc no ----------------
@pmc_report_bp.route("/pmc_report/<pmc_no>") @pmc_report_bp.route("/pmc_report/<pmc_no>")
@login_required @login_required
def pmc_report(pmc_no): def pmc_report(pmc_no):
data = PmcReport.get_pmc_report(pmc_no) data = UnifiedReportService.get_report(pmc_no=pmc_no)
if not data: if not data:
return "No PMC found with this number", 404 return "No PMC found with this number", 404
@@ -17,6 +16,7 @@ def pmc_report(pmc_no):
info=data["info"], info=data["info"],
invoices=data["invoices"], invoices=data["invoices"],
hold_types=data["hold_types"], hold_types=data["hold_types"],
hold_data=data["hold_data"],
gst_rel=data["gst_rel"], gst_rel=data["gst_rel"],
payments=data["payments"], payments=data["payments"],
credit_note=data["credit_note"], credit_note=data["credit_note"],
@@ -29,12 +29,9 @@ def pmc_report(pmc_no):
@login_required @login_required
def download_pmc_report(pmc_no): def download_pmc_report(pmc_no):
result = PmcReport.download_pmc_report(pmc_no) output_file = UnifiedReportService.download(pmc_no=pmc_no)
if not result: if not output_file:
return "No contractor found for this PMC No", 404 return "No contractor found for this PMC No", 404
output_folder, file_name = result return send_file(output_file, as_attachment=True)
return send_from_directory(output_folder, file_name, as_attachment=True)

View File

@@ -4,8 +4,8 @@ from flask_login import login_required, current_user
from model.Report import ReportHelper from model.Report import ReportHelper
from model.Log import LogHelper from model.Log import LogHelper
import os import os
from model.UnifiedReportService import UnifiedReportService
DOWNLOAD_FOLDER = "static/download"
report_bp = Blueprint("report", __name__) report_bp = Blueprint("report", __name__)
@@ -37,7 +37,8 @@ def search_contractor():
@login_required @login_required
def contractor_report(contractor_id): def contractor_report(contractor_id):
data = ReportHelper.get_contractor_report(contractor_id) # data = UnifiedReportService.get_report(contractor_id)
data = UnifiedReportService.get_report(contractor_id=contractor_id)
return render_template( return render_template(
'subcontractor_report.html', 'subcontractor_report.html',
@@ -45,19 +46,13 @@ def contractor_report(contractor_id):
**data **data
) )
# # ---------------- Contractor Download Report by contractor id ---------------- # ---------------- Contractor Download Report by contractor id ----------------
# @report_bp.route('/download_report/<int:contractor_id>')
# @login_required
# def download_report(contractor_id):
# return ReportHelper().download_report(contractor_id=contractor_id)
@report_bp.route('/download_report/<int:contractor_id>') @report_bp.route('/download_report/<int:contractor_id>')
def download_report(contractor_id): def download_report(contractor_id):
output_file, error = ReportHelper.create_contractor_report(contractor_id)
if error:
return error, 404
# Send the file to the user file_path = UnifiedReportService.download(contractor_id=contractor_id)
return send_file(output_file, as_attachment=True)
if not file_path:
return "Report not found", 404
return send_file(file_path, as_attachment=True)

View File

@@ -3,14 +3,12 @@ from flask_login import login_required
from model.State import State from model.State import State
state_bp = Blueprint('state', __name__) state_bp = Blueprint('state', __name__)
state = State()
# ----- State page ------ # ----- State page ------
@state_bp.route('/add_state', methods=['GET', 'POST']) @state_bp.route('/add_state', methods=['GET', 'POST'])
@login_required @login_required
def add_state(): def add_state():
state = State()
if request.method == 'POST': if request.method == 'POST':
state.AddState(request=request) state.AddState(request=request)
return state.resultMessage return state.resultMessage
@@ -24,8 +22,6 @@ def add_state():
@login_required @login_required
def check_state(): def check_state():
state = State()
return state.CheckState(request=request) return state.CheckState(request=request)
# ----- State delete by state id ------ # ----- State delete by state id ------
@@ -33,8 +29,6 @@ def check_state():
@login_required @login_required
def deleteState(id): def deleteState(id):
state = State()
state.DeleteState(request=request, id=id) state.DeleteState(request=request, id=id)
if not state.isSuccess: if not state.isSuccess:
@@ -47,8 +41,6 @@ def deleteState(id):
@login_required @login_required
def editState(id): def editState(id):
state = State()
if request.method == 'POST': if request.method == 'POST':
state.EditState(request=request, id=id) state.EditState(request=request, id=id)

View File

@@ -15,7 +15,6 @@ subcontractor_bp = Blueprint('subcontractor', __name__)
def subcontract(): def subcontract():
sub = Subcontractor() sub = Subcontractor()
# ---------------- GET ---------------- # ---------------- GET ----------------
if request.method == 'GET': if request.method == 'GET':
subcontractor = sub.GetAllSubcontractors(request) subcontractor = sub.GetAllSubcontractors(request)

View File

@@ -1,7 +1,3 @@
from flask import Blueprint, render_template, request, redirect, url_for, flash, jsonify from flask import Blueprint, render_template, request, redirect, url_for, flash, jsonify
from flask_login import login_required from flask_login import login_required
@@ -11,14 +7,12 @@ from model.State import State
# Create Blueprint # Create Blueprint
village_bp = Blueprint('village', __name__) village_bp = Blueprint('village', __name__)
village = Village()
# ------------------------- Add Village ------------------------- # ------------------------- Add Village -------------------------
@village_bp.route('/add_village', methods=['GET', 'POST']) @village_bp.route('/add_village', methods=['GET', 'POST'])
@login_required @login_required
def add_village(): def add_village():
village = Village()
if request.method == 'POST': if request.method == 'POST':
village.AddVillage(request=request) village.AddVillage(request=request)
@@ -79,17 +73,17 @@ def get_blocks(district_id):
@village_bp.route('/check_village', methods=['POST']) @village_bp.route('/check_village', methods=['POST'])
@login_required @login_required
def check_village(): def check_village():
village = Village()
return village.CheckVillage(request=request) return village.CheckVillage(request=request)
@village_bp.route('/delete_village/<int:village_id>') @village_bp.route('/delete_village/<int:village_id>')
@login_required @login_required
def delete_village(village_id): def delete_village(village_id):
village = Village()
village.DeleteVillage(request=request, village_id=village_id) village.DeleteVillage(request=request, village_id=village_id)
# ✅ Convert resultMessage to string if it's a Response or tuple # resultMessage to string if it's a Response or tuple
raw_msg = village.resultMessage raw_msg = village.resultMessage
if isinstance(raw_msg, tuple): if isinstance(raw_msg, tuple):
@@ -112,8 +106,6 @@ def delete_village(village_id):
@login_required @login_required
def edit_village(village_id): def edit_village(village_id):
village = Village()
if request.method == 'POST': if request.method == 'POST':
village.EditVillage(request=request, village_id=village_id) village.EditVillage(request=request, village_id=village_id)
@@ -135,7 +127,6 @@ def edit_village(village_id):
) )
else: else:
# ✅ FIXED HERE (removed request)
village_data = village.GetVillageByID(id=village_id) village_data = village.GetVillageByID(id=village_id)
if not village.isSuccess: if not village.isSuccess:

File diff suppressed because it is too large Load Diff

View File

@@ -1,14 +1,4 @@
from flask import Blueprint, render_template, request, redirect, url_for, jsonify
from model.Utilities import RegEx, ResponseHandler, HtmlHelper, ItemCRUDType from model.Utilities import RegEx, ResponseHandler, HtmlHelper, ItemCRUDType
from model.Log import LogData, LogHelper
import os
import config
import re
import mysql.connector
from mysql.connector import Error
from model.ItemCRUD import ItemCRUD, itemCRUDMapping from model.ItemCRUD import ItemCRUD, itemCRUDMapping

View File

@@ -1,6 +1,5 @@
from mysql.connector import Error from mysql.connector import Error
import config import config
from datetime import datetime
class ContractorInfo: class ContractorInfo:
@@ -31,7 +30,7 @@ class ContractorInfo:
connection = config.get_db_connection() connection = config.get_db_connection()
with connection.cursor(dictionary=True, buffered=True) as cursor: with connection.cursor(dictionary=True, buffered=True) as cursor:
# Fetch Hold Types # Fetch Hold Types
cursor.callproc('GetHoldTypesByContractor', [self.ID]) cursor.callproc('GetHoldAmountsAndHoldTypeByCtr', [self.ID])
hold_types = [] hold_types = []
for result in cursor.stored_results(): for result in cursor.stored_results():
hold_types = result.fetchall() hold_types = result.fetchall()

View File

@@ -1,51 +1,51 @@
from model.ItemCRUD import ItemCRUD # from model.ItemCRUD import ItemCRUD
from model.Utilities import ItemCRUDType # from model.Utilities import ItemCRUDType
class GST: # class GST:
@staticmethod # @staticmethod
def get_unreleased_gst(): # def get_unreleased_gst():
# Use ItemCRUD for Invoices # # Use ItemCRUD for Invoices
invoice_crud = ItemCRUD(itemType=ItemCRUDType.Invoice) # invoice_crud = ItemCRUD(itemType=ItemCRUDType.Invoice)
invoices_rows = invoice_crud.GetAllData(storedproc="GetAllInvoicesBasic") # invoices_rows = invoice_crud.GetAllData(storedproc="GetAllInvoicesBasic")
if not invoice_crud.isSuccess: # if not invoice_crud.isSuccess:
return [] # Could also log invoice_crud.resultMessage # return [] # Could also log invoice_crud.resultMessage
invoices = [ # invoices = [
dict( # dict(
Invoice_No=row[1], # Invoice_No=row[1],
GST_SD_Amount=float(row[2]) if row[2] is not None else 0 # GST_SD_Amount=float(row[2]) if row[2] is not None else 0
) # )
for row in invoices_rows # for row in invoices_rows
] # ]
# Use ItemCRUD for GST Releases # # Use ItemCRUD for GST Releases
gst_crud = ItemCRUD(itemType=ItemCRUDType.GSTRelease) # gst_crud = ItemCRUD(itemType=ItemCRUDType.GSTRelease)
gst_rows = gst_crud.GetAllData(storedproc="GetAllGSTReleasesBasic") # gst_rows = gst_crud.GetAllData(storedproc="GetAllGSTReleasesBasic")
if not gst_crud.isSuccess: # if not gst_crud.isSuccess:
return [] # Could also log gst_crud.resultMessage # return [] # Could also log gst_crud.resultMessage
gst_invoice_nos = { # gst_invoice_nos = {
g[2] # Invoice_No is at index 2 # g[2] # Invoice_No is at index 2
for g in gst_rows # for g in gst_rows
if g[2] # if g[2]
} # }
gst_basic_amounts = { # gst_basic_amounts = {
float(g[3]) # Basic_Amount at index 3 # float(g[3]) # Basic_Amount at index 3
for g in gst_rows # for g in gst_rows
if g[3] is not None # if g[3] is not None
} # }
# Filter unreleased invoices # # Filter unreleased invoices
unreleased = [] # unreleased = []
for inv in invoices: # for inv in invoices:
match_by_invoice = inv['Invoice_No'] in gst_invoice_nos # match_by_invoice = inv['Invoice_No'] in gst_invoice_nos
match_by_gst_amount = inv['GST_SD_Amount'] in gst_basic_amounts # match_by_gst_amount = inv['GST_SD_Amount'] in gst_basic_amounts
if not (match_by_invoice or match_by_gst_amount): # if not (match_by_invoice or match_by_gst_amount):
unreleased.append(inv) # unreleased.append(inv)
return unreleased # return unreleased

View File

@@ -33,7 +33,7 @@ class HoldTypes:
self.isSuccess = hold.isSuccess self.isSuccess = hold.isSuccess
self.resultMessage = hold.resultMessage self.resultMessage = hold.resultMessage
# Convert tuple → dictionary # Convert tuple → dictionary
data = [] data = []
for row in rows: for row in rows:
data.append({ data.append({
@@ -51,7 +51,7 @@ class HoldTypes:
self.isSuccess = hold.isSuccess self.isSuccess = hold.isSuccess
self.resultMessage = hold.resultMessage self.resultMessage = hold.resultMessage
#Convert tuple → dictionary #Convert tuple → dictionary
if row: if row:
return { return {
"hold_type_id": row[0], "hold_type_id": row[0],

View File

@@ -70,22 +70,7 @@ def get_all_villages():
# ------------------- Invoice Functions ------------------- # ------------------- Invoice Functions -------------------
def insert_invoice(data, village_id): def insert_invoice(data, village_id):
def operation(cursor): def operation(cursor):
# Insert invoice
# cursor.callproc('InsertInvoice', [
# data.get('pmc_no'),
# village_id,
# data.get('work_type'),
# data.get('invoice_details'),
# data.get('invoice_date'),
# data.get('invoice_no'),
# *get_numeric_values(data),
# data.get('subcontractor_id')
# ])
# invoice_row = fetch_one(cursor)
# if not invoice_row:
# raise Exception("Invoice ID not returned")
# invoice_id = invoice_row.get('invoice_id')
cursor.callproc('SaveInvoice', [ cursor.callproc('SaveInvoice', [
data.get('pmc_no'), data.get('pmc_no'),
village_id, village_id,
@@ -103,18 +88,6 @@ def insert_invoice(data, village_id):
if row: if row:
invoice_id = row['invoice_id'] invoice_id = row['invoice_id']
# # Insert inpayment
# cursor.callproc('InsertInpayment', [
# data.get('pmc_no'),
# village_id,
# data.get('work_type'),
# data.get('invoice_details'),
# data.get('invoice_date'),
# data.get('invoice_no'),
# *get_numeric_values(data),
# data.get('subcontractor_id')
# ])
# clear_results(cursor)
return invoice_id return invoice_id
return execute_db_operation(operation) return execute_db_operation(operation)
@@ -159,18 +132,6 @@ def update_invoice(data, invoice_id):
clear_results(cursor) clear_results(cursor)
execute_db_operation(operation) execute_db_operation(operation)
# def update_inpayment(data):
# def operation(cursor):
# cursor.callproc('UpdateInpayment', [
# data.get('work_type'),
# data.get('invoice_details'),
# data.get('invoice_date'),
# *get_numeric_values(data),
# data.get('pmc_no'),
# data.get('invoice_no')
# ])
# clear_results(cursor)
# execute_db_operation(operation)
def delete_invoice_data(invoice_id, user_id): def delete_invoice_data(invoice_id, user_id):
def operation(cursor): def operation(cursor):
@@ -190,24 +151,10 @@ def delete_invoice_data(invoice_id, user_id):
cursor.callproc("DeleteInvoice", (invoice_id,)) cursor.callproc("DeleteInvoice", (invoice_id,))
clear_results(cursor) clear_results(cursor)
# Delete inpayment
# cursor.callproc('DeleteInpaymentByPMCInvoice', (pmc_no, invoice_no))
# clear_results(cursor)
execute_db_operation(operation) execute_db_operation(operation)
# ------------------- Subcontractor Functions -------------------
# def assign_subcontractor(data, village_id):
# def operation(cursor):
# cursor.callproc('AssignSubcontractor', [
# data.get('pmc_no'),
# data.get('subcontractor_id'),
# village_id
# ])
# clear_results(cursor)
# execute_db_operation(operation)
# ------------------- Hold Types Functions ------------------- # ------------------- Hold Types Functions -------------------
def insert_hold_types(data, invoice_id): def insert_hold_types(data, invoice_id):

View File

@@ -332,7 +332,7 @@ class ItemCRUD:
# ---------------------------------------------------------- # ----------------------------------------------------------
# GET BY ID # GET BY ID
# ---------------------------------------------------------- # ----------------------------------------------------------
def GetDataByID(self, id, storedproc): def GetDataByID(self, id, storedproc):
data = None data = None
connection = config.get_db_connection() connection = config.get_db_connection()

View File

@@ -1,300 +1,185 @@
import openpyxl # import openpyxl
from openpyxl.styles import Font, PatternFill # from openpyxl.styles import Font, PatternFill
import config # import config
from flask_login import current_user # from flask_login import current_user
from model.Log import LogHelper # from model.Log import LogHelper
# from model.excel import excel
# from model.Report import ReportHelper
# from model.FolderAndFile import FolderAndFile
from model.Report import ReportHelper # class PmcReport:
from model.FolderAndFile import FolderAndFile
class PmcReport: # @staticmethod
# def get_pmc_report(pmc_no):
@staticmethod # connection = config.get_db_connection()
def get_pmc_report(pmc_no): # cursor = connection.cursor(dictionary=True, buffered=True)
connection = config.get_db_connection() # try:
cursor = connection.cursor(dictionary=True, buffered=True) # pmc_info = ReportHelper.execute_sp(cursor, 'GetContractorInfoByPmcNo', [pmc_no], True)
try: # if not pmc_info:
pmc_info = ReportHelper.execute_sp(cursor, 'GetContractorInfoByPmcNo', [pmc_no], True) # return None
if not pmc_info: # cursor.callproc("Get_pmc_hold_types", (pmc_no, pmc_info["Contractor_Id"]))
return None # hold_types = next(cursor.stored_results()).fetchall()
cursor.callproc("Get_pmc_hold_types", (pmc_no, pmc_info["Contractor_Id"])) # # Extract hold_type_ids
hold_types = next(cursor.stored_results()).fetchall() # hold_type_ids = [ht['hold_type_id'] for ht in hold_types]
# Extract hold_type_ids # invoices = []
hold_type_ids = [ht['hold_type_id'] for ht in hold_types] # hold_amount_total = 0
# hold_type_ids_str = ",".join(map(str, hold_type_ids))
invoices = [] # cursor.callproc(
hold_amount_total = 0 # 'GetInvoices_WithHold',
# if hold_type_ids: # [pmc_no, pmc_info["Contractor_Id"], hold_type_ids_str]
# hold_type_ids_str = ",".join(map(str, hold_type_ids)) # )
# cursor.callproc(
# 'GetInvoices_WithHold',
# [pmc_no, pmc_info["Contractor_Id"], hold_type_ids_str]
# )
# else:
# cursor.callproc(
# 'GetInvoices_NoHold',
# [pmc_no, pmc_info["Contractor_Id"]]
# )
hold_type_ids_str = ",".join(map(str, hold_type_ids))
cursor.callproc(
'GetInvoices_WithHold',
[pmc_no, pmc_info["Contractor_Id"], hold_type_ids_str]
)
for result in cursor.stored_results(): # for result in cursor.stored_results():
invoices = result.fetchall() # invoices = result.fetchall()
if hold_type_ids: # if hold_type_ids:
hold_amount_total = sum(row.get('hold_amount', 0) or 0 for row in invoices) # hold_amount_total = sum(row.get('hold_amount', 0) or 0 for row in invoices)
total_invo_final = sum(row.get('Final_Amount', 0) or 0 for row in invoices) # total_invo_final = sum(row.get('Final_Amount', 0) or 0 for row in invoices)
gst_rel = ReportHelper.execute_sp(cursor, 'GetGSTReleaseByPMC', [pmc_no]) # gst_rel = ReportHelper.execute_sp(cursor, 'GetGSTReleaseByPMC', [pmc_no])
total_gst_basic = sum(row.get('basic_amount', 0) or 0 for row in gst_rel) # total_gst_basic = sum(row.get('basic_amount', 0) or 0 for row in gst_rel)
total_gst_final = sum(row.get('final_amount', 0) or 0 for row in gst_rel) # total_gst_final = sum(row.get('final_amount', 0) or 0 for row in gst_rel)
hold_release = ReportHelper.execute_sp(cursor, 'GetHoldReleaseByPMC', [pmc_no]) # hold_release = ReportHelper.execute_sp(cursor, 'GetHoldReleaseByPMC', [pmc_no])
credit_note = ReportHelper.execute_sp(cursor, 'GetCreditNoteByPMC', [pmc_no]) # credit_note = ReportHelper.execute_sp(cursor, 'GetCreditNoteByPMC', [pmc_no])
payments = ReportHelper.execute_sp(cursor, 'GetPaymentsByPMC', [pmc_no]) # payments = ReportHelper.execute_sp(cursor, 'GetPaymentsByPMC', [pmc_no])
total_pay_amount = sum(row.get('Payment_Amount', 0) or 0 for row in payments) # total_pay_amount = sum(row.get('Payment_Amount', 0) or 0 for row in payments)
total_pay_total = sum(row.get('Total_amount', 0) or 0 for row in payments) # total_pay_total = sum(row.get('Total_amount', 0) or 0 for row in payments)
totals = { # totals = {
"sum_invo_basic_amt": sum(row.get('Basic_Amount', 0) or 0 for row in invoices), # "sum_invo_basic_amt": sum(row.get('Basic_Amount', 0) or 0 for row in invoices),
"sum_invo_debit_amt": sum(row.get('Debit_Amount', 0) or 0 for row in invoices), # "sum_invo_debit_amt": sum(row.get('Debit_Amount', 0) or 0 for row in invoices),
"sum_invo_after_debit_amt": sum(row.get('After_Debit_Amount', 0) or 0 for row in invoices), # "sum_invo_after_debit_amt": sum(row.get('After_Debit_Amount', 0) or 0 for row in invoices),
"sum_invo_amt": sum(row.get('Amount', 0) or 0 for row in invoices), # "sum_invo_amt": sum(row.get('Amount', 0) or 0 for row in invoices),
"sum_invo_gst_amt": sum(row.get('GST_Amount', 0) or 0 for row in invoices), # "sum_invo_gst_amt": sum(row.get('GST_Amount', 0) or 0 for row in invoices),
"sum_invo_tds_amt": sum(row.get('TDS_Amount', 0) or 0 for row in invoices), # "sum_invo_tds_amt": sum(row.get('TDS_Amount', 0) or 0 for row in invoices),
"sum_invo_ds_amt": sum(row.get('SD_Amount', 0) or 0 for row in invoices), # "sum_invo_ds_amt": sum(row.get('SD_Amount', 0) or 0 for row in invoices),
"sum_invo_on_commission": sum(row.get('On_Commission', 0) or 0 for row in invoices), # "sum_invo_on_commission": sum(row.get('On_Commission', 0) or 0 for row in invoices),
"sum_invo_hydro_test": sum(row.get('Hydro_Testing', 0) or 0 for row in invoices), # "sum_invo_hydro_test": sum(row.get('Hydro_Testing', 0) or 0 for row in invoices),
"sum_invo_gst_sd_amt": sum(row.get('GST_SD_Amount', 0) or 0 for row in invoices), # "sum_invo_gst_sd_amt": sum(row.get('GST_SD_Amount', 0) or 0 for row in invoices),
"sum_invo_final_amt": total_invo_final, # "sum_invo_final_amt": total_invo_final,
"sum_invo_hold_amt": hold_amount_total, # "sum_invo_hold_amt": hold_amount_total,
"sum_gst_basic_amt": total_gst_basic, # "sum_gst_basic_amt": total_gst_basic,
"sum_gst_final_amt": total_gst_final, # "sum_gst_final_amt": total_gst_final,
"sum_pay_payment_amt": total_pay_amount, # "sum_pay_payment_amt": total_pay_amount,
"sum_pay_tds_payment_amt": sum(row.get('TDS_Payment_Amount', 0) or 0 for row in payments), # "sum_pay_tds_payment_amt": sum(row.get('TDS_Payment_Amount', 0) or 0 for row in payments),
"sum_pay_total_amt": total_pay_total # "sum_pay_total_amt": total_pay_total
} # }
return { # return {
"info": pmc_info, # "info": pmc_info,
"invoices": invoices, # "invoices": invoices,
"hold_types": hold_types, # "hold_types": hold_types,
"gst_rel": gst_rel, # "gst_rel": gst_rel,
"payments": payments, # "payments": payments,
"credit_note": credit_note, # "credit_note": credit_note,
"hold_release": hold_release, # "hold_release": hold_release,
"total": totals # "total": totals
} # }
finally: # finally:
cursor.close() # cursor.close()
connection.close() # connection.close()
@staticmethod # @staticmethod
def download_pmc_report(pmc_no): # def download_pmc_report(pmc_no):
connection = config.get_db_connection() # connection = config.get_db_connection()
if not connection: # if not connection:
return None # return None
cursor = connection.cursor(dictionary=True) # cursor = connection.cursor(dictionary=True)
try: # try:
filename = f"PMC_Report_{pmc_no}.xlsx" # filename = f"PMC_Report_{pmc_no}.xlsx"
output_folder = FolderAndFile.get_download_folder() # output_folder = FolderAndFile.get_download_folder()
output_file = FolderAndFile.get_download_path(filename) # output_file = FolderAndFile.get_download_path(filename)
# ================= DATA FETCH ================= # # ================= DATA FETCH =================
contractor_info = ReportHelper.execute_sp( # contractor_info = ReportHelper.execute_sp(
cursor, 'GetContractorDetailsByPMC', [pmc_no] # cursor, 'GetContractorInfoByPmcNo', [pmc_no]
) # )
contractor_info = contractor_info[0] if contractor_info else None # contractor_info = contractor_info[0] if contractor_info else None
print("contractor_info:::",contractor_info) # print("contractor_info:::",contractor_info)
if not contractor_info: # if not contractor_info:
return None # return None
hold_types = ReportHelper.execute_sp( # hold_types = ReportHelper.execute_sp(
cursor, 'GetHoldTypesByContractor', # cursor, 'GetHoldTypesByContractor',
[contractor_info["Contractor_Id"]] # [contractor_info["Contractor_Id"]]
) # )
hold_type_map = { # hold_type_map = {
ht['hold_type_id']: ht['hold_type'] for ht in hold_types # ht['hold_type_id']: ht['hold_type'] for ht in hold_types
} # }
invoices = ReportHelper.execute_sp( # invoices = ReportHelper.execute_sp(
cursor, 'GetInvoicesByContractorOrPMCNo', [None,pmc_no] # cursor, 'GetInvoicesByContractorOrPMCNo', [None,pmc_no]
) # )
credit_notes = ReportHelper.execute_sp( # credit_notes = ReportHelper.execute_sp(
cursor, 'NewGetCreditNotesByPMCNo', [pmc_no] # cursor, 'NewGetCreditNotesByPMCNo', [pmc_no]
) # )
# credit_note_map = {}
# for cn in credit_notes:
# key = (
# str(cn['PMC_No']).strip()
# )
# credit_note_map.setdefault(key, []).append(cn)
hold_amounts = ReportHelper.execute_sp( # hold_amounts = ReportHelper.execute_sp(
cursor, 'GetHoldAmountsByContractor', # cursor, 'GetHoldAmountsByContractor',
[contractor_info["Contractor_Id"]] # [contractor_info["Contractor_Id"]]
) # )
gst_releases = ReportHelper.execute_sp( # gst_releases = ReportHelper.execute_sp(
cursor, 'GetGSTReleaseDetailsByPMC', [pmc_no] # cursor, 'GetGSTReleaseDetailsByPMC', [pmc_no]
) # )
# gst_release_map = {}
# for gr in gst_releases:
# ================= DATA MAPPING ================= # key = (
hold_data = {} # str(gr['PMC_No']).strip()
for h in hold_amounts: # )
hold_data.setdefault(h['Invoice_Id'], {})[h['hold_type_id']] = h['hold_amount'] # gst_release_map.setdefault(key, []).append(gr)
credit_note_map = {} # # ================= DATA MAPPING =================
for cn in credit_notes: # hold_data = {}
pmc = cn.get("PMC_No") # for h in hold_amounts:
if pmc: # hold_data.setdefault(h['Invoice_Id'], {})[h['hold_type_id']] = h['hold_amount']
credit_note_map.setdefault(pmc, []).append(cn)
gst_map = {}
for gst in gst_releases:
pmc = gst.get("PMC_No")
if pmc:
gst_map.setdefault(pmc, []).append(gst)
# ================= LOG =================
LogHelper.log_action(
"Download PMC Report",
f"User {current_user.id} Download PMC Report '{pmc_no}'"
)
# ================= EXCEL ================= # # ================= LOG =================
workbook = openpyxl.Workbook() # LogHelper.log_action(
sheet = workbook.active # "Download PMC Report",
sheet.title = "PMC Report" # f"User {current_user.id} Download PMC Report '{pmc_no}'"
# )
# HEADER INFO # excel.generate_excel(
sheet.append(["", "", "Laxmi Civil Engineering Services PVT. LTD."]) # 0, contractor_info, invoices, hold_types, hold_data,
sheet.append(["Contractor Name", contractor_info["Contractor_Name"]]) # credit_note_map,gst_release_map, output_file
sheet.append(["State", contractor_info["State_Name"]]) # )
sheet.append(["District", contractor_info["District_Name"]])
sheet.append(["Block", contractor_info["Block_Name"]])
sheet.append([])
base_headers = [ # return output_folder, filename
"PMC No", "Village", "Work Type", "Invoice Details",
"Invoice Date", "Invoice No", "Basic Amount", "Debit", "After Debit Amount",
"GST", "Amount", "TDS", "SD", "On Commission", "Hydro Testing", "GST SD Amount"
]
hold_headers = [ht['hold_type'] for ht in hold_types] # except Exception as e:
payment_headers = ["Final Amount", "Payment Amount", "TDS Payment", "Total Paid", "UTR"] # print(f"Error generating PMC report: {e}")
# return None
headers = base_headers + hold_headers + payment_headers # finally:
sheet.append(headers) # cursor.close()
for cell in sheet[sheet.max_row]: # connection.close()
cell.font = Font(bold=True)
# ================= INVOICE ROWS =================
for inv in invoices:
row = [
pmc_no,
inv.get("Village_Name", ""),
inv.get("Work_Type", ""),
inv.get("Invoice_Details", ""),
inv.get("Invoice_Date", ""),
inv.get("invoice_no", ""),
inv.get("Basic_Amount", ""),
inv.get("Debit_Amount", ""),
inv.get("After_Debit_Amount", ""),
inv.get("GST_Amount", ""),
inv.get("Amount", ""),
inv.get("TDS_Amount", ""),
inv.get("SD_Amount", ""),
inv.get("On_Commission", ""),
inv.get("Hydro_Testing", ""),
inv.get("GST_SD_Amount", "")
]
# HOLD DATA
invoice_holds = hold_data.get(inv.get("Invoice_Id"), {})
for ht_id in hold_type_map.keys():
row.append(invoice_holds.get(ht_id, ""))
# PAYMENT DATA
row += [
inv.get("Final_Amount", ""),
inv.get("Payment_Amount", ""),
inv.get("TDS_Payment_Amount", ""),
inv.get("Total_Amount", ""),
inv.get("UTR", "")
]
# GST release placeholders (will add real GST below)
row += ["", ""]
sheet.append(row)
for pmc, cn_list in credit_note_map.items():
for cn in cn_list:
cn_row = [
pmc_no,
"", "", "Credit Note",
"", cn.get("Invoice_No", ""),
cn.get("Basic_Amount", ""),
"", "", "", "", "", "", "", "", "", "", ""
]
cn_row += [""] * len(hold_headers)
cn_row += [
cn.get("Final_Amount", ""),
cn.get("Total_Amount", ""),
cn.get("UTR", "")
]
sheet.append(cn_row)
# ================= GST RELEASE ROWS =================
for gst in gst_releases:
gst_row = [
gst.get("PMC_No", ""),
"", "", "GST Release Note",
"", gst.get("Invoice_No", ""),
gst.get("Basic_Amount", ""),
"", "", "", "", "", "", "", "", ""
]
gst_row += [""] * len(hold_headers)
gst_row += [
gst.get("Final_Amount", ""),
"",
"",
gst.get("Total_Amount", ""),
gst.get("UTR", "")
]
sheet.append(gst_row)
# ================= AUTO WIDTH =================
for col in sheet.columns:
max_len = max((len(str(cell.value)) for cell in col if cell.value), default=0)
sheet.column_dimensions[col[0].column_letter].width = max_len + 2
workbook.save(output_file)
workbook.close()
return output_folder, filename
except Exception as e:
print(f"Error generating PMC report: {e}")
return None
finally:
cursor.close()
connection.close()

View File

@@ -1,11 +1,4 @@
import config import config
from datetime import datetime
from flask import send_file
import os
import openpyxl
from openpyxl.styles import Font, PatternFill
from model.FolderAndFile import FolderAndFile
class ReportHelper: class ReportHelper:
isSuccess = False isSuccess = False
@@ -86,309 +79,12 @@ class ReportHelper:
return data return data
@staticmethod
def get_contractor_report(contractor_id):
connection = config.get_db_connection()
cursor = connection.cursor(dictionary=True, buffered=True)
try:
# Contractor Info (only one fetch)
contInfo = ReportHelper.execute_sp(cursor, 'GetContractorInfo', [contractor_id], True)
# Hold Types
hold_types = ReportHelper.execute_sp(cursor, 'GetContractorHoldTypes', [contractor_id])
# Invoices
invoices = ReportHelper.execute_sp(cursor, 'GetContractorInvoices', [contractor_id])
# GST Release
gst_rel = ReportHelper.execute_sp(cursor, 'GetGSTRelease', [contractor_id])
# Hold Release
hold_release = ReportHelper.execute_sp(cursor, 'GetHoldRelease', [contractor_id])
# Credit Note
credit_note = ReportHelper.execute_sp(cursor, 'GetCreditNote', [contractor_id])
# Payments
payments = ReportHelper.execute_sp(cursor, 'GetPayments', [contractor_id])
# Totals
total = {
"sum_invo_basic_amt": float(sum(row['Basic_Amount'] or 0 for row in invoices)),
"sum_invo_debit_amt": float(sum(row['Debit_Amount'] or 0 for row in invoices)),
"sum_invo_after_debit_amt": float(sum(row['After_Debit_Amount'] or 0 for row in invoices)),
"sum_invo_amt": float(sum(row['Amount'] or 0 for row in invoices)),
"sum_invo_gst_amt": float(sum(row['GST_Amount'] or 0 for row in invoices)),
"sum_invo_tds_amt": float(sum(row['TDS_Amount'] or 0 for row in invoices)),
"sum_invo_ds_amt": float(sum(row['SD_Amount'] or 0 for row in invoices)),
"sum_invo_on_commission": float(sum(row['On_Commission'] or 0 for row in invoices)),
"sum_invo_hydro_test": float(sum(row['Hydro_Testing'] or 0 for row in invoices)),
"sum_invo_gst_sd_amt": float(sum(row['GST_SD_Amount'] or 0 for row in invoices)),
"sum_invo_final_amt": float(sum(row['Final_Amount'] or 0 for row in invoices)),
"sum_invo_hold_amt": float(sum(row['hold_amount'] or 0 for row in invoices)),
"sum_gst_basic_amt": float(sum(row['basic_amount'] or 0 for row in gst_rel)),
"sum_gst_final_amt": float(sum(row['final_amount'] or 0 for row in gst_rel)),
"sum_pay_payment_amt": float(sum(row['Payment_Amount'] or 0 for row in payments)),
"sum_pay_tds_payment_amt": float(sum(row['TDS_Payment_Amount'] or 0 for row in payments)),
"sum_pay_total_amt": float(sum(row['Total_amount'] or 0 for row in payments))
}
current_date = datetime.now().strftime('%Y-%m-%d')
finally:
cursor.close()
connection.close()
return {
"contInfo": contInfo,
"invoices": invoices,
"hold_types": hold_types,
"gst_rel": gst_rel,
"payments": payments,
"credit_note": credit_note,
"hold_release": hold_release,
"total": total,
"current_date": current_date
}
@staticmethod @staticmethod
def get_contractor_info(contractor_id): def get_contractor_info(contractor_id):
from model.ContractorInfo import ContractorInfo from model.ContractorInfo import ContractorInfo
contractor = ContractorInfo(contractor_id) contractor = ContractorInfo(contractor_id)
return contractor.contInfo if contractor.contInfo else None return contractor.contInfo if contractor.contInfo else None
# @staticmethod
# def generate_excel(contractor_id, contInfo, invoices, hold_types, hold_data,
# extra_payments_map, credit_note_map, gst_release_map, output_file):
@staticmethod
def generate_excel(contractor_id, contInfo, invoices, hold_types, hold_data,
credit_note_map, gst_release_map, output_file):
workbook = openpyxl.Workbook()
sheet = workbook.active
sheet.title = "Contractor Report"
# Contractor Info
for field, value in contInfo.items():
sheet.append([field.replace("_", " "), value])
sheet.append([])
# Headers
base_headers = ["PMC No", "Village", "Work Type", "Invoice Details", "Invoice Date", "Invoice No",
"Basic Amount", "Debit", "After Debit Amount", "GST (18%)", "Amount", "TDS (1%)",
"SD (5%)", "On Commission", "Hydro Testing", "GST SD Amount"]
hold_headers = [ht['hold_type'] for ht in hold_types]
payment_headers = ["Final Amount", "Payment Amount", "TDS Payment", "Total Paid", "UTR"]
all_headers = base_headers + hold_headers + payment_headers
sheet.append(all_headers)
for cell in sheet[sheet.max_row]:
cell.font = Font(bold=True)
cell.fill = PatternFill(start_color="ADD8E6", end_color="ADD8E6", fill_type="solid")
processed_gst_releases = set()
appended_credit_keys = set()
previous_pmc_no = None
for inv in invoices:
pmc_no = str(inv["PMC_No"]).strip()
invoice_no = (
inv["invoice_no"].replace(" ", "") if inv["invoice_no"] else ""
if inv["invoice_no"] not in (None, "", 0)
else ""
)
# key = (pmc_no, invoice_no)
key = (pmc_no)
# Yellow separator
if previous_pmc_no and pmc_no != previous_pmc_no:
sheet.append([""] * len(all_headers))
yellow_fill = PatternFill(start_color="FFFF99", end_color="FFFF99", fill_type="solid")
for cell in sheet[sheet.max_row]:
cell.fill = yellow_fill
previous_pmc_no = pmc_no
# Invoice Row
row = [
pmc_no,
inv.get("Village_Name", ""),
inv.get("Work_Type", ""),
inv.get("Invoice_Details", ""),
inv.get("Invoice_Date", ""),
# inv.get("invoice_no",""),
invoice_no,
inv.get("Basic_Amount", ""),
inv.get("Debit_Amount", ""),
inv.get("After_Debit_Amount", ""),
inv.get("GST_Amount", ""),
inv.get("Amount", ""),
inv.get("TDS_Amount", ""),
inv.get("SD_Amount", ""),
inv.get("On_Commission", ""),
inv.get("Hydro_Testing", ""),
inv.get("GST_SD_Amount", "")
]
# Hold values
invoice_holds = hold_data.get(inv["Invoice_Id"], {})
for ht_id in [ht['hold_type_id'] for ht in hold_types]:
row.append(invoice_holds.get(ht_id, ""))
# Payment values
row += [
inv.get("Final_Amount", ""),
inv.get("Payment_Amount", ""),
inv.get("TDS_Payment_Amount", ""),
inv.get("Total_Amount", ""),
inv.get("UTR", "")
]
sheet.append(row)
# # Extra Payments
# if pmc_no in extra_payments_map:
# for ep in extra_payments_map[pmc_no]:
# extra_row = [pmc_no] + [""] * (len(base_headers) - 1)
# extra_row += [""] * len(hold_headers)
# extra_row += [
# "",
# ep.get("Payment_Amount", ""),
# ep.get("TDS_Payment_Amount", ""),
# ep.get("Total_Amount", ""),
# ep.get("utr", "")
# ]
# sheet.append(extra_row)
# del extra_payments_map[pmc_no]
# GST Releases
if key in gst_release_map and key not in processed_gst_releases:
for gr in gst_release_map[key]:
gst_row = [
pmc_no, "", "", "GST Release Note", "", gr.get("Invoice_No", ""),
gr.get("Basic_Amount", ""), "", "", "", "", "", "", "", "", ""
]
gst_row += [""] * len(hold_headers)
gst_row += [
gr.get("Final_Amount", ""),
"",
"",
gr.get("Total_Amount", ""),
gr.get("UTR", "")
]
sheet.append(gst_row)
processed_gst_releases.add(key)
# Credit Notes
if key in credit_note_map and key not in appended_credit_keys:
for cn in credit_note_map[key]:
cn_row = [
pmc_no, "", "", cn.get("Invoice_Details", "Credit Note"), "",
cn.get("Invoice_No", ""),
cn.get("Basic_Amount", ""),
cn.get("Debit_Amount", ""),
cn.get("After_Debit_Amount", ""),
cn.get("GST_Amount", ""),
cn.get("Amount", ""),
"", "", "", "", ""
]
cn_row += [""] * len(hold_headers)
cn_row += [
cn.get("Final_Amount", ""),
"",
"",
cn.get("Total_Amount", ""),
cn.get("UTR", "")
]
sheet.append(cn_row)
appended_credit_keys.add(key)
# SAVE ONCE AT END
workbook.save(output_file)
@staticmethod
def create_contractor_report(contractor_id):
# DOWNLOAD_FOLDER = os.path.join("static", "download")
# os.makedirs(DOWNLOAD_FOLDER, exist_ok=True)
fileName=f"Contractor_Report_{contractor_id}.xlsx"
# output_file = os.path.join(DOWNLOAD_FOLDER, )
output_file = FolderAndFile.get_download_path(filename=fileName)
# Fetch Data
contInfo = ReportHelper.get_contractor_info(contractor_id)
if not contInfo:
return None, "No contractor found"
connection = config.get_db_connection()
cursor = connection.cursor(dictionary=True, buffered=True)
hold_types = ReportHelper.execute_sp(cursor, 'HoldTypesByContractorId', [contractor_id])
invoices = ReportHelper.execute_sp(cursor, 'GetInvoicesByContractorOrPMCNo', [contractor_id,None])
hold_amounts = ReportHelper.execute_sp(cursor, 'HoldAmountsByContractorId', [contractor_id])
hold_data = {}
for h in hold_amounts:
hold_data.setdefault(h['Invoice_Id'], {})[h['hold_type_id']] = h['hold_amount']
# # # -------- Extra Payments MAP --------
# # extra_payments_raw = ReportHelper.execute_sp(cursor, 'GetExtraPayments')
# # extra_payments_map = {}
# # for ep in extra_payments_raw:
# # pmc = str(ep['pmc_no']).strip()
# # extra_payments_map.setdefault(pmc, []).append(ep)
# -------- Credit Note MAP --------
credit_note_raw = ReportHelper.execute_sp(cursor, 'GetCreditNotesByContractor', [contractor_id])
credit_note_map = {}
for cn in credit_note_raw:
# key = (
# str(cn['PMC_No']).strip(),
# str(cn['Invoice_No']).replace(" ", "") if cn['Invoice_No'] else ""
# )
key = (
str(cn['PMC_No']).strip()
)
credit_note_map.setdefault(key, []).append(cn)
# -------- GST MAP --------
gst_release_raw = ReportHelper.execute_sp(cursor, 'GstReleasesByContractorId', [contractor_id])
gst_release_map = {}
for gr in gst_release_raw:
# key = (
# str(gr['PMC_No']).strip(),
# str(gr['Invoice_No']).replace(" ", "") if gr['Invoice_No'] else ""
# )
key = (
str(gr['PMC_No']).strip()
)
gst_release_map.setdefault(key, []).append(gr)
# print("GST MAP:", gst_release_map)
# Generate Excel
# ReportHelper.generate_excel(
# contractor_id, contInfo, invoices, hold_types, hold_data,
# extra_payments_map, credit_note_map, gst_release_map, output_file
# )
ReportHelper.generate_excel(
contractor_id, contInfo, invoices, hold_types, hold_data,
credit_note_map, gst_release_map, output_file
)
return output_file, None

View File

@@ -0,0 +1,155 @@
import config
from model.excel import excel
from model.Report import ReportHelper
from model.FolderAndFile import FolderAndFile
from decimal import Decimal
class UnifiedReportService:
# Static variable to cache report data
# _cached_report_data = None
# _cached_contractor_id = None
# _cached_pmc_no = None
@staticmethod
def get_report(contractor_id=None, pmc_no=None):
# If cached and same request, return cached data
# if (UnifiedReportService._cached_report_data and
# contractor_id == UnifiedReportService._cached_contractor_id and
# pmc_no == UnifiedReportService._cached_pmc_no):
# return UnifiedReportService._cached_report_data
connection = config.get_db_connection()
cursor = connection.cursor(dictionary=True, buffered=True)
try:
# ================= BASIC INFO =================
if contractor_id:
info = ReportHelper.execute_sp(cursor,'GetContractorInfo',[contractor_id],True)
else:
info = ReportHelper.execute_sp(cursor,'GetContractorInfoByPmcNo',[pmc_no],True)
contractor_id = info["Contractor_Id"] if info else None
if not info:
return None
# ================= HOLD TYPES =================
hold_types = ReportHelper.execute_sp(cursor,'GetHoldTypesByContractor',[contractor_id]) or []
# ================= INVOICES =================
if pmc_no:
invoices = ReportHelper.execute_sp(cursor,'GetInvoicesByContractorOrPMCNo',[None, pmc_no]) or []
credit_notes = ReportHelper.execute_sp(cursor,'NewGetCreditNotesByPMCNo',[pmc_no]) or []
gst_rel = ReportHelper.execute_sp(cursor,'GetGSTReleaseDetailsByPMC',[pmc_no]) or []
payments = ReportHelper.execute_sp(cursor,'GetPaymentsByPMC',[pmc_no]) or []
else:
invoices = ReportHelper.execute_sp(cursor,'GetInvoicesByContractorOrPMCNo',[contractor_id, None]) or []
credit_notes = ReportHelper.execute_sp(cursor,'GetCreditNotesByContractor',[contractor_id]) or []
gst_rel = ReportHelper.execute_sp(cursor,'GstReleasesByContractorId',[contractor_id]) or []
payments = ReportHelper.execute_sp(cursor,'GetPayments',[contractor_id]) or []
# ================= HOLD AMOUNTS =================
hold_amounts = ReportHelper.execute_sp(cursor,'GetHoldAmountsByContractor',[contractor_id]) or []
hold_data = {}
for h in hold_amounts:
hold_data.setdefault(h["Invoice_Id"], {})[h["hold_type_id"]] = h["hold_amount"]
# ================= CREDIT NOTES =================
credit_note_map = {}
for cn in credit_notes:
key = str(cn.get("PMC_No")).strip()
credit_note_map.setdefault(key, []).append(cn)
# ================= GST RELEASE =================
gst_release_map = {}
for gr in gst_rel:
key = str(gr.get("PMC_No")).strip()
gst_release_map.setdefault(key, []).append(gr)
# ================= PAYMENTS =================
total = {
"sum_invo_basic_amt": sum(row.get('Basic_Amount', 0) or 0 for row in invoices),
"sum_invo_debit_amt": sum(row.get('Debit_Amount', 0) or 0 for row in invoices),
"sum_invo_after_debit_amt": sum(row.get('After_Debit_Amount', 0) or 0 for row in invoices),
"sum_invo_amt": sum(row.get('Amount', 0) or 0 for row in invoices),
"sum_invo_gst_amt": sum(row.get('GST_Amount', 0) or 0 for row in invoices),
"sum_invo_tds_amt": sum(row.get('TDS_Amount', 0) or 0 for row in invoices),
"sum_invo_ds_amt": sum(row.get('SD_Amount', 0) or 0 for row in invoices),
"sum_invo_on_commission": sum(row.get('On_Commission', 0) or 0 for row in invoices),
"sum_invo_hydro_test": sum(row.get('Hydro_Testing', 0) or 0 for row in invoices),
"sum_invo_gst_sd_amt": sum(row.get('GST_SD_Amount', 0) or 0 for row in invoices),
"sum_invo_final_amt": sum(r.get("Final_Amount", 0) or 0 for r in invoices),
"sum_invo_hold_amt": sum(r.get("hold_amount", 0) or 0 for r in hold_amounts),
"sum_gst_basic_amt": sum(r.get("Basic_Amount", 0) or 0 for r in gst_rel),
"sum_gst_final_amt": sum(r.get("Final_Amount", 0) or 0 for r in gst_rel),
"sum_gst_total_amt": sum(r.get("Total_Amount", 0) or 0 for r in gst_rel),
"sum_pay_total_amt": sum(Decimal(r.get("Total_amount") or 0) for r in payments),
"sum_pay_payment_amt": sum(Decimal(r.get("Payment_Amount") or 0) for r in payments),
"sum_pay_tds_payment_amt": sum(Decimal(r.get("TDS_Payment_Amount") or 0) for r in payments),
"sum_credit_basic_amt": sum(Decimal(c.get("Basic_Amount") or 0) for c in credit_notes),
"sum_credit_final_amt": sum(Decimal(c.get("Final_Amount") or 0) for c in credit_notes),
"sum_credit_total_amt": sum(Decimal(c.get("Total_Amount") or 0) for c in credit_notes),
}
# Prepare final report
report_data = {
"info": info,
"invoices": invoices,
"hold_types": hold_types,
"payments": payments,
"hold_data": hold_data,
"hold_release": hold_data,
"credit_note_map": credit_note_map,
"credit_note": credit_notes,
"gst_release_map": gst_release_map,
"gst_rel": gst_rel,
"total": total
}
# # Cache the report
# UnifiedReportService._cached_report_data = report_data
# UnifiedReportService._cached_contractor_id = contractor_id
# UnifiedReportService._cached_pmc_no = pmc_no
return report_data
finally:
cursor.close()
connection.close()
# ================= DOWNLOAD EXCEL =================
@staticmethod
def download(contractor_id=None, pmc_no=None):
# Use cached report if available
report_data = UnifiedReportService.get_report(contractor_id, pmc_no)
if not report_data:
return None
fileName = (
f"Contractor_Report_{contractor_id}.xlsx"
if contractor_id else f"PMC_Report_{pmc_no}.xlsx"
)
output_file = FolderAndFile.get_download_path(fileName)
excel.generate_excel(
contractor_id or 0,
report_data["info"],
report_data["invoices"],
report_data["hold_types"],
report_data["hold_data"],
report_data["credit_note_map"],
report_data["gst_release_map"],
report_data["payments"],
report_data["total"],
output_file
)
return output_file

View File

@@ -9,6 +9,7 @@ class ItemCRUDType(Enum):
HoldType = 5 HoldType = 5
Subcontractor = 6 Subcontractor = 6
GSTRelease = 7 GSTRelease = 7
Invoice = 8
class RegEx: class RegEx:
patternAlphabetOnly = r"^[A-Za-z ]+$" patternAlphabetOnly = r"^[A-Za-z ]+$"

View File

@@ -13,14 +13,14 @@ class Village:
def __init__(self): def __init__(self):
self.isSuccess = False self.isSuccess = False
self.resultMessage = "" self.resultMessage = ""
self.response = {} # ✅ ADDED self.response = {}
self.village = ItemCRUD(itemType=ItemCRUDType.Village) self.village = ItemCRUD(itemType=ItemCRUDType.Village)
# 🔹 Helper: sync status # 🔹 Helper: sync status
def _set_status(self, village): def _set_status(self, village):
self.isSuccess = village.isSuccess self.isSuccess = village.isSuccess
# UPDATED (safe handling) # UPDATED (safe handling)
if hasattr(village, "response"): if hasattr(village, "response"):
self.response = village.response self.response = village.response
self.resultMessage = village.response.get("message", "") self.resultMessage = village.response.get("message", "")
@@ -75,7 +75,7 @@ class Village:
block_id, village_name = self._get_form_data(request) block_id, village_name = self._get_form_data(request)
if not village_name: if not village_name:
self.response = ResponseHandler.invalid_name("village") # ✅ UPDATED self.response = ResponseHandler.invalid_name("village")
self.resultMessage = self.response["message"] self.resultMessage = self.response["message"]
self.isSuccess = False self.isSuccess = False
return None return None
@@ -85,7 +85,7 @@ class Village:
request=request, request=request,
parentid=block_id, parentid=block_id,
childname=village_name, childname=village_name,
storedprocfetch="GetVillageByNameAndBlock" # Change GetVillageByNameAndBlocks to GetVillageByNameAndBlock storedprocfetch="GetVillageByNameAndBlock"
) )
self._set_status(self.village) self._set_status(self.village)
return result return result
@@ -113,7 +113,7 @@ class Village:
block_id, village_name = self._get_form_data(request) block_id, village_name = self._get_form_data(request)
if not village_name: if not village_name:
self.response = ResponseHandler.invalid_name("village") # ✅ UPDATED self.response = ResponseHandler.invalid_name("village")
self.resultMessage = self.response["message"] self.resultMessage = self.response["message"]
self.isSuccess = False self.isSuccess = False
return return
@@ -176,7 +176,6 @@ class Village:
print(f"Error fetching blocks: {e}") print(f"Error fetching blocks: {e}")
self.isSuccess = False self.isSuccess = False
# ✅ FIXED (removed jsonify response)
self.response = ResponseHandler.fetch_failure("block") self.response = ResponseHandler.fetch_failure("block")
self.resultMessage = self.response["message"] self.resultMessage = self.response["message"]

200
model/excel.py Normal file
View File

@@ -0,0 +1,200 @@
import openpyxl
from openpyxl.styles import Font, PatternFill
from datetime import datetime
from decimal import Decimal
from model.FolderAndFile import FolderAndFile
class excel:
@staticmethod
def generate_excel(contractor_id,info, invoices, hold_types, hold_data, credit_note_map, gst_release_map, payments,total,output_file):
workbook = openpyxl.Workbook()
sheet = workbook.active
sheet.title = "Contractor Report"
# Contractor Info
for field, value in info.items():
sheet.append([field.replace("_", " "), value])
sheet.append([])
# Headers
base_headers = ["PMC No", "Village", "Work Type", "Invoice Details", "Invoice Date", "Invoice No",
"Basic Amount", "Debit", "After Debit Amount", "GST (18%)", "Amount", "TDS (1%)",
"SD (5%)", "On Commission", "Hydro Testing", "GST SD Amount"]
hold_headers = [ht['hold_type'] for ht in hold_types]
payment_headers = ["Final Amount", "Payment Amount", "TDS Payment", "Total Paid", "UTR"]
all_headers = base_headers + hold_headers + payment_headers
sheet.append(all_headers)
for cell in sheet[sheet.max_row]:
cell.font = Font(bold=True)
cell.fill = PatternFill(start_color="ADD8E6", end_color="ADD8E6", fill_type="solid")
processed_gst_releases = set()
appended_credit_keys = set()
previous_pmc_no = None
for inv in invoices:
pmc_no = str(inv["PMC_No"]).strip()
invoice_no = (
inv["invoice_no"].replace(" ", "") if inv["invoice_no"] else ""
if inv["invoice_no"] not in (None, "", 0)
else ""
)
key = (pmc_no)
# Yellow separator
if previous_pmc_no and pmc_no != previous_pmc_no:
sheet.append([""] * len(all_headers))
yellow_fill = PatternFill(start_color="FFFF99", end_color="FFFF99", fill_type="solid")
for cell in sheet[sheet.max_row]:
cell.fill = yellow_fill
previous_pmc_no = pmc_no
# Invoice Row
row = [
pmc_no,
inv.get("Village_Name", ""),
inv.get("Work_Type", ""),
inv.get("Invoice_Details", ""),
inv.get("Invoice_Date", ""),
# inv.get("invoice_no",""),
invoice_no,
inv.get("Basic_Amount", ""),
inv.get("Debit_Amount", ""),
inv.get("After_Debit_Amount", ""),
inv.get("GST_Amount", ""),
inv.get("Amount", ""),
inv.get("TDS_Amount", ""),
inv.get("SD_Amount", ""),
inv.get("On_Commission", ""),
inv.get("Hydro_Testing", ""),
inv.get("GST_SD_Amount", "")
]
# Hold values
invoice_holds = hold_data.get(inv["Invoice_Id"], {})
for ht_id in [ht['hold_type_id'] for ht in hold_types]:
row.append(invoice_holds.get(ht_id, ""))
# Payment values
row += [
inv.get("Final_Amount", ""),
inv.get("Payment_Amount", ""),
inv.get("TDS_Payment_Amount", ""),
inv.get("Total_Amount", ""),
inv.get("UTR", "")
]
sheet.append(row)
# GST Releases
if key in gst_release_map and key not in processed_gst_releases:
for gr in gst_release_map[key]:
gst_row = [pmc_no, "", "", "GST Release Note", "", gr.get("Invoice_No", ""),
gr.get("Basic_Amount", ""), "", "", "", "", "", "", "", "", "" ]
gst_row += [""] * len(hold_headers)
gst_row += [ gr.get("Final_Amount", ""), "", "", gr.get("Total_Amount", ""), gr.get("UTR", "") ]
sheet.append(gst_row)
processed_gst_releases.add(key)
# Credit Notes
if key in credit_note_map and key not in appended_credit_keys:
for cn in credit_note_map[key]:
cn_row = [ pmc_no, "", "", cn.get("Invoice_Details", "Credit Note"), "",
cn.get("Invoice_No", ""), cn.get("Basic_Amount", ""),
cn.get("Debit_Amount", ""), cn.get("After_Debit_Amount", ""), cn.get("GST_Amount", ""), cn.get("Amount", ""), "", "", "", "", "" ]
cn_row += [""] * len(hold_headers)
cn_row += [ cn.get("Final_Amount", ""), "", "", cn.get("Total_Amount", ""), cn.get("UTR", "") ]
sheet.append(cn_row)
appended_credit_keys.add(key)
# total calculation
hold_totals = {ht['hold_type_id']: 0 for ht in hold_types}
for inv in invoices:
invoice_holds = hold_data.get(inv["Invoice_Id"], {})
for ht_id in hold_totals:
hold_totals[ht_id] += invoice_holds.get(ht_id, 0) or 0
total_basic_amount = total.get('sum_invo_basic_amt', 0)+total.get('sum_gst_basic_amt')+ total.get('sum_credit_basic_amt')
total_final_amount = total.get('sum_invo_final_amt', 0)+ total.get('sum_gst_final_amt', 0) + total.get('sum_credit_final_amt', 0)
total_total_amount = total.get('sum_pay_total_amt', 0)+ total.get('sum_gst_total_amt', 0) + total.get('sum_credit_total_amt', 0)
# total row insert
totalrow = ["Total","-","-","-","-","-",total_basic_amount,
total.get('sum_invo_debit_amt', 0), total.get('sum_invo_after_debit_amt', 0),total.get('sum_invo_gst_amt', 0),total.get('sum_invo_amt', 0),
total.get('sum_invo_tds_amt', 0),total.get('sum_invo_ds_amt', 0),total.get('sum_invo_on_commission', 0), total.get('sum_invo_hydro_test', 0),
total.get('sum_invo_gst_sd_amt', 0)]
for ht in hold_types:
totalrow.append(hold_totals.get(ht['hold_type_id'], 0))
totalrow += [total_final_amount, "","", total_total_amount]
sheet.append(totalrow)
# Apply style (color + bold)
for cell in sheet[sheet.max_row]:
cell.fill = PatternFill(start_color="FFFF00", end_color="FFFF00", fill_type="solid") # Yellow
cell.font = Font(bold=True)
# summary report
sheet.append([])
sheet.append(["Summary Report"])
today_date = datetime.today().strftime('%A, %Y-%m-%d')
sheet.append([])
sheet.append(["Contractor Name", info["Contractor_Name"]])
sheet.append(["Date", today_date])
sheet.append(["Description", "Amount"])
# Calculate surplus/advance
surplus_amount = total_final_amount - total_total_amount
sheet.append(["Advance/Surplus", str(surplus_amount)])
# Get the last appended row
current_row = sheet.max_row
cell = sheet.cell(row=current_row, column=2)
# Apply green fill if positive, red fill if negative
if surplus_amount >= 0:
fill_color = PatternFill(start_color="C6EFCE", end_color="C6EFCE", fill_type="solid") # Light green
else:
fill_color = PatternFill(start_color="FFC7CE", end_color="FFC7CE", fill_type="solid") # Light red
cell.fill = fill_color
# sheet.append(["Total Hold Amount", str(Decimal(total["sum_invo_hold_amt"]))])
for ht in hold_types:
sheet.append([ht['hold_type'], hold_totals.get(ht['hold_type_id'], 0)])
sheet.append(["Amount With TDS", str(total.get('sum_invo_tds_amt', 0))])
# Auto adjust column widths
for col in sheet.columns:
max_length = 0
col_letter = openpyxl.utils.get_column_letter(col[0].column)
for cell in col:
try:
if cell.value:
max_length = max(max_length, len(str(cell.value)))
except:
pass
sheet.column_dimensions[col_letter].width = max_length + 2
# SAVE ONCE AT END
workbook.save(output_file)

View File

@@ -14,12 +14,6 @@ class GSTRelease:
try: try:
gst = ItemCRUD(itemType=ItemCRUDType.GSTRelease) gst = ItemCRUD(itemType=ItemCRUDType.GSTRelease)
# Print the full form data
print("===== DEBUG: FORM DATA =====")
for key, value in request.form.items():
print(f"{key} : {value}")
print("=============================")
data = { data = {
"PMC_No": request.form.get("PMC_No", "").strip(), "PMC_No": request.form.get("PMC_No", "").strip(),
"Invoice_No": request.form.get("Invoice_No", "").strip(), "Invoice_No": request.form.get("Invoice_No", "").strip(),
@@ -30,10 +24,6 @@ class GSTRelease:
"Contractor_ID": int(request.form.get("Contractor_ID", 0) or 0) "Contractor_ID": int(request.form.get("Contractor_ID", 0) or 0)
} }
print("===== DEBUG: PARSED DATA =====")
print(data)
print("==============================")
# Add GST Release # Add GST Release
gst.AddItem( gst.AddItem(
request=request, request=request,
@@ -42,8 +32,6 @@ class GSTRelease:
storedprocadd="AddGSTReleaseFromExcel" storedprocadd="AddGSTReleaseFromExcel"
) )
print(f"AddItem result: isSuccess={gst.isSuccess}, message={gst.resultMessage}")
self.isSuccess = gst.isSuccess self.isSuccess = gst.isSuccess
self.resultMessage = str(gst.resultMessage) self.resultMessage = str(gst.resultMessage)
@@ -69,10 +57,6 @@ class GSTRelease:
"p_gst_release_id": gst_release_id "p_gst_release_id": gst_release_id
} }
print("===== DEBUG: UPDATE DATA =====")
print(data)
print("==============================")
# Call your stored procedure # Call your stored procedure
gst.EditItem( gst.EditItem(
request=request, request=request,

View File

@@ -72,24 +72,6 @@ class Paymentmodel:
if connection: if connection:
connection.close() connection.close()
# @staticmethod
# def update_inpayment(subcontractor_id, pmc_no, invoice_no, amount, tds_amount, total_amount, utr):
# connection = Paymentmodel.get_connection()
# if not connection:
# return False
# try:
# cursor = connection.cursor()
# cursor.callproc('UpdateInpaymentRecord', [
# subcontractor_id, pmc_no, invoice_no, amount, tds_amount, total_amount, utr
# ])
# connection.commit()
# return True
# except mysql.connector.Error as e:
# print(f"Error updating inpayment: {e}")
# return False
# finally:
# cursor.close()
# connection.close()
@staticmethod @staticmethod
def fetch_payment_by_id(payment_id): def fetch_payment_by_id(payment_id):
@@ -144,7 +126,7 @@ class Paymentmodel:
try: try:
cursor = connection.cursor(dictionary=True) cursor = connection.cursor(dictionary=True)
# Fetch PMC & Invoice before deleting # Fetch PMC & Invoice before deleting
cursor.callproc('GetPaymentPMCInvoiceById', [payment_id]) cursor.callproc('GetPaymentById', [payment_id])
record = {} record = {}
for result in cursor.stored_results(): for result in cursor.stored_results():
record = result.fetchone() or {} record = result.fetchone() or {}
@@ -155,9 +137,7 @@ class Paymentmodel:
# Delete payment # Delete payment
cursor.callproc("DeletePayment", (payment_id,)) cursor.callproc("DeletePayment", (payment_id,))
connection.commit() connection.commit()
# Reset inpayment fields
# cursor.callproc("ResetInpayment", [pmc_no, invoice_no])
# connection.commit()
return True, pmc_no, invoice_no return True, pmc_no, invoice_no
except mysql.connector.Error as e: except mysql.connector.Error as e:
print(f"Error deleting payment: {e}") print(f"Error deleting payment: {e}")

View File

@@ -16,6 +16,7 @@ form {
box-shadow: 0px 4px 10px rgba(0, 0, 0, 0.1); box-shadow: 0px 4px 10px rgba(0, 0, 0, 0.1);
display: flex; display: flex;
flex-direction: column; flex-direction: column;
margin: auto;
gap: 15px; gap: 15px;
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

View File

@@ -376,10 +376,12 @@
</a> </a>
</td> </td>
<td> <td>
<a <!-- <a
href="javascript:void(0);" href="javascript:void(0);"
onclick="deleteInvoice({{ invoice.Invoice_Id }}, this)" onclick="deleteInvoice({{ invoice.Invoice_Id }}, this)"
> > -->
<a href="javascript:void(0);"
onclick="deleteInvoice('{{ invoice.Invoice_Id }}', this)">
<img <img
src="{{ url_for('static', filename='images/icons/bin_red_icon.png') }}" src="{{ url_for('static', filename='images/icons/bin_red_icon.png') }}"
alt="Delete" alt="Delete"

View File

@@ -1,147 +0,0 @@
{% extends 'base.html' %}
{% block content %}
<head>
<title>Manage Purchases</title>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
</head>
<body>
<div class="button-container">
<button id="addButton" class="action-button">Add Purchase</button>
<button id="displayButton" class="action-button">Display Purchases</button>
</div>
<!-- ADD PURCHASE FORM -->
<!-- ADD PURCHASE FORM -->
<div id="addForm" style="display: none;">
<h2>Add Purchase Entry</h2>
<form action="/add_purchase_order" method="POST">
<label for="purchase_date">Purchase Date:</label><br>
<input type="date" id="purchase_date" name="purchase_date" required><br><br>
<label for="supplier_name">Supplier Name:</label><br>
<input type="text" id="supplier_name" name="supplier_name" required><br><br>
<label for="Purchase Order No">Purchase Order No:</label><br>
<input type="text" name="purchase_order_no" required><br><br>
<label for="unit">Item Name:</label><br>
<input type="text" id="item_name" name="item_name" required><br><br>
<label for="quantity">Quantity:</label><br>
<input type="number" id="quantity" name="quantity" step="1" required><br><br>
<label for="unit">Unit:</label><br>
<input type="text" id="unit" name="unit" required><br><br>
<label for="rate">Rate:</label><br>
<input type="number" step="0.01" id="rate" name="rate" required><br><br>
<label for="amount">Amount:</label><br>
<input type="number" step="0.01" id="amount" name="amount" readonly><br><br>
<!-- GST input -->
<label for="gst_percent">GST %:</label><br>
<input type="number" step="0.01" id="gst_percent"><br><br>
<label>GST Amount:</label><br>
<input type="number" step="0.01" id="GST_Amount" name="GST_Amount" readonly><br><br>
<!-- TDS input -->
<label for="tds_percent">TDS %:</label><br>
<input type="number" step="0.01" id="tds_percent"><br><br>
<label>TDS:</label><br>
<input type="number" step="0.01" id="TDS" name="TDS" readonly><br><br>
<label>Final Amount:</label><br>
<input type="number" step="0.01" id="final_amount" name="final_amount" readonly><br><br>
<input type="submit" value="Submit">
</form>
</div>
<!-- DISPLAY TABLE -->
<div id="displayTable" style="display: none;">
<h2>Purchase List</h2>
<table border="1">
<tr>
<th>ID</th>
<th>Purchase Date</th>
<th>Supplier Name</th>
<th>Purchase Order No</th>
<th>Item Name</th>
<th>Quantity</th>
<th>Unit</th>
<th>Rate</th>
<th>Amount</th>
<th>GST Amount</th>
<th>TDS</th>
<th>Final Amount</th>
<th>Edit</th>
<th>Delete</th>
</tr>
{% for purchase in purchases %}
<tr>
<td>{{ purchase['purchase_id'] }}</td>
<td>{{ purchase['purchase_date'] }}</td>
<td>{{ purchase['supplier_name'] }}</td>
<td>{{ purchase['purchase_order_no'] }}</td>
<td>{{ purchase['item_name'] }}</td>
<td>{{ purchase['quantity'] }}</td>
<td>{{ purchase['unit'] }}</td>
<td>{{ purchase['rate'] }}</td>
<td>{{ purchase['amount'] }}</td>
<td>{{ purchase['GST_Amount'] }}</td>
<td>{{ purchase['TDS'] }}</td>
<td>{{ purchase['final_amount'] }}</td>
<td><a href="{{ url_for('update_purchase', id=purchase['purchase_id']) }}">Edit</a></td>
<td>
<form method="POST" action="{{ url_for('delete_purchase', id=purchase['purchase_id']) }}" style="display:inline;">
<button type="submit" onclick="return confirm('Are you sure?')">Delete</button>
</form>
</td>
</tr>
{% endfor %}
</table>
</div>
<script>
$(document).ready(function() {
$('#addButton').click(function() {
$('#addForm').toggle();
});
$('#displayButton').click(function() {
$('#displayTable').toggle();
});
});
</script>
<script>
function calculateAmounts() {
const qty = parseFloat(document.getElementById('quantity').value) || 0;
const rate = parseFloat(document.getElementById('rate').value) || 0;
const gstPercent = parseFloat(document.getElementById('gst_percent').value) || 0;
const tdsPercent = parseFloat(document.getElementById('tds_percent').value) || 0;
const amount = qty * rate;
document.getElementById('amount').value = amount.toFixed(2);
const gstAmount = (gstPercent / 100) * amount;
document.getElementById('GST_Amount').value = gstAmount.toFixed(2);
const tdsAmount = (tdsPercent / 100) * amount;
document.getElementById('TDS').value = tdsAmount.toFixed(2);
const finalAmount = amount + gstAmount - tdsAmount;
document.getElementById('final_amount').value = finalAmount.toFixed(2);
}
// Attach events
document.getElementById('quantity').addEventListener('input', calculateAmounts);
document.getElementById('rate').addEventListener('input', calculateAmounts);
document.getElementById('gst_percent').addEventListener('input', calculateAmounts);
document.getElementById('tds_percent').addEventListener('input', calculateAmounts);
</script>
</body>
{% endblock %}

View File

@@ -106,7 +106,7 @@
</td> </td>
<td> <td>
<a href="javascript:void(0);" <a href="javascript:void(0);"
onclick="deleteVillage({{ village[0] }}, this)"> onclick="deleteVillage('{{ village[0] }}', this)">
<img src="{{ url_for('static', filename='images/icons/bin_red_icon.png') }}" <img src="{{ url_for('static', filename='images/icons/bin_red_icon.png') }}"
class="icon"> class="icon">
</a> </a>

View File

@@ -1,137 +0,0 @@
{% extends 'base.html' %}
{% block content %}
<head>
<title>Manage Work Order</title>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='css/style.css') }}">
</head>
</head>
<body>
<div class="button-container">
<button id="addButton" class="action-button">Add</button>
<button id="displayButton" class="action-button">Display</button>
</div>
<form action="/submit_work_order" method="POST">
<div id="addForm" style="display: none;">
<h2>Create Work Order</h2>
<!-- Subcontractor Dropdown -->
<label for="subcontractor_id">Select Vender Name:</label><br>
<select name="vendor_name" id="vendor_name" required>
<option value="">-- Select Subcontractor --</option>
{% for sc in subcontractor %}
<option value="{{ sc.Contractor_Name }}">{{ sc.Contractor_Name }}</option>
{% endfor %}
</select><br><br>
<label for="work_order_number">Work Order Number:</label><br>
<input type="text" id="work_order_number" name="work_order_number" required><br><br>
<label for="work_order_amount">Work Order Amount</label><br>
<input type="number" step="0.01" id="work_order_amount" name="work_order_amount" required><br><br>
<label for="gst_amount">GST Amount:</label><br>
<input type="number" step="0.01" id="gst_amount" name="gst_amount" required><br><br>
<label for="tds_amount">TDS Amount:</label><br>
<input type="number" step="0.01" id="tds_amount" name="tds_amount" required><br><br>
<label for="security_deposit">Security Deposit:</label><br>
<input type="number" step="0.01" id="security_deposit" name="security_deposit" required><br><br>
<label for="sd_against_gst">SD Against GST:</label><br>
<input type="number" step="0.01" id="sd_against_gst" name="sd_against_gst" required><br><br>
<label for="final_total">Final Total:</label><br>
<input type="number" step="0.01" id="final_total" name="final_total" readonly><br><br>
<input type="submit" value="Submit">
</div>
</form>
{# display data #}
<div id="addTable" style="display: none;">
{# <div class="search-container">#}
{# <h2>Hold Type List</h2>#}
{# <input type="text" id="searchBar" placeholder="Searching..." onkeyup="searchTable()">#}
{# </div>#}
<table id="sortableTable" border="1">
<tr>
<th>ID</th>
<th class="sortable-header">
Vender Name
{# <span class="sort-buttons">#}
{# <span class="sort-asc">⬆️</span>#}
{# <span class="sort-desc">⬇️</span>#}
{# </span>#}
</th>
<th>Work Order Type</th>
<th>Work Order Amount</th>
<th>BOQ Amount</th>
<th>Work Done Percentage</th>
<th>Update</th>
<th>Delete</th>
</tr>
{% for htd in wo %}
<tr>
<td>{{ htd.work_order_id }}</td>
<td>{{ htd['vendor_name'] }}</td>
<td>{{ htd['work_order_type'] }}</td>
<td>{{ htd['work_order_amount'] }}</td>
<td>{{ htd['boq_amount'] }}</td>
<td>{{ htd['work_done_percentage'] }}</td>
<td>{{ htd['work_order_number'] }}</td>
<td>{{ htd['gst_amount'] }}</td>
<td>{{ htd['tds_amount'] }}</td>
<td>{{ htd[''] }}</td>
<td><a href="{{ url_for('update_work_order', id=htd['work_order_id']) }}">Edit</a></td>
<td>
<form action="{{ url_for('delete_work_order', id=htd['work_order_id']) }}" method="POST" style="display:inline;">
<button type="submit" onclick="return confirm('Are you sure you want to delete this work order?');" class="delete-button">Delete</button>
</form>
</td>
</tr>
{% endfor %}
</table>
<a href="/">Back to Dashboard</a>
</div>
<script>
$(document).ready(function () {
$('#displayButton').click(function () {
$('#addTable').toggle();
});
$('#addButton').click(function () {
$('#addForm').toggle();
// Bind input event handlers ONLY after form is shown
setTimeout(function () {
["work_order_amount", "gst_amount", "tds_amount", "security_deposit", "sd_against_gst"].forEach(function (id) {
document.getElementById(id).addEventListener("input", calculateFinalTotal);
});
}, 100); // Delay ensures elements are available in DOM
});
function calculateFinalTotal() {
const workOrderAmount = parseFloat(document.getElementById("work_order_amount").value) || 0;
const gstAmount = parseFloat(document.getElementById("gst_amount").value) || 0;
const tdsAmount = parseFloat(document.getElementById("tds_amount").value) || 0;
const securityDeposit = parseFloat(document.getElementById("security_deposit").value) || 0;
const sdAgainstGst = parseFloat(document.getElementById("sd_against_gst").value) || 0;
const finalTotal = workOrderAmount + gstAmount - (tdsAmount + securityDeposit + sdAgainstGst);
document.getElementById("final_total").value = finalTotal.toFixed(2);
}
});
</script>
</body>
{% endblock %}

View File

@@ -1,39 +0,0 @@
<!DOCTYPE html>
<html>
<head><title>Edit GRN</title>
<link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
</head>
<body>
<h2>Edit GRN</h2>
<form method="POST">
<label>GRN Date:</label>
<input type="date" name="grn_date" value="{{ grn['grn_date'] }}" required><br><br>
<label>Purchase ID:</label>
<input type="number" name="purchase_id" value="{{ grn['purchase_id'] }}" required><br><br>
<label>Supplier Name:</label>
<input type="text" name="supplier_name" value="{{ grn['supplier_name'] }}" required><br><br>
<label>Item Description:</label>
<input type="text" name="item_description" value="{{ grn['item_description'] }}" required><br><br>
<label>Received Quantity:</label>
<input type="number" name="received_quantity" value="{{ grn['received_quantity'] }}" required><br><br>
<label>Unit:</label>
<input type="text" name="unit" value="{{ grn['unit'] }}" required><br><br>
<label>Rate:</label>
<input type="number" step="0.01" name="rate" value="{{ grn['rate'] }}" required><br><br>
<label>Amount:</label>
<input type="number" step="0.01" name="amount" value="{{ grn['amount'] }}" required><br><br>
<label>Remarks:</label>
<input type="text" name="remarks" value="{{ grn['remarks'] }}"><br><br>
<input type="submit" value="Update GRN">
</form>
</body>
</html>

View File

@@ -1,47 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>Edit Purchase</title>
<link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
</head>
<body>
<h2>Edit Purchase Order</h2>
<form method="POST">
<label>Purchase Date:</label>
<input type="date" name="purchase_date" value="{{ purchase['purchase_date'] }}" required><br><br>
<label>Supplier Name:</label>
<input type="text" name="supplier_name" value="{{ purchase['supplier_name'] }}" required><br><br>
<label>Purchase Order No:</label>
<input type="text" name="purchase_order_no" value="{{ purchase['purchase_order_no'] }}" required><br><br>
<label>Item Name:</label>
<input type="text" name="item_name" value="{{ purchase['item_name'] }}" required><br><br>
<label>Quantity:</label>
<input type="number" name="quantity" value="{{ purchase['quantity'] }}" required><br><br>
<label>Unit:</label>
<input type="text" name="unit" value="{{ purchase['unit'] }}" required><br><br>
<label>Rate:</label>
<input type="number" step="0.01" name="rate" value="{{ purchase['rate'] }}" required><br><br>
<label>Amount:</label>
<input type="number" step="0.01" name="amount" value="{{ purchase['amount'] }}" required><br><br>
<label>GST Amount:</label>
<input type="text" name="GST_Amount" value="{{ purchase['GST_Amount'] }}" required><br><br>
<label>TDS:</label>
<input type="number" step="0.01" name="TDS" value="{{ purchase['TDS'] }}" required><br><br>
<label>Final Amount:</label>
<input type="number" step="0.01" name="final_amount" value="{{ purchase['final_amount'] }}" required><br><br>
<input type="submit" value="Update">
</form>
</body>
</html>

View File

@@ -1,77 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>GRN Management</title>
<link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
</head>
<body>
<h2>Add GRN</h2>
<form method="POST" action="/add_grn">
<label>GRN Date:</label>
<input type="date" name="grn_date" required><br><br>
<label>Purchase ID:</label>
<input type="number" name="purchase_id" required><br><br>
{# <label for="purchase_id">Purchase Order:</label>#}
{# <select name="purchase_id" id="purchase_id" required>#}
{# {% for order in purchase_orders %}#}
{# <option value="{{ order['purchase_id'] }}">{{ order['supplier_name'] }}</option>#}
{# {% endfor %}#}
{#</select>#}
<label>Supplier Name:</label>
<input type="text" name="supplier_name" required><br><br>
<label>Item Description:</label>
<input type="text" name="item_description" required><br><br>
<label>Received Quantity:</label>
<input type="number" name="received_quantity" required><br><br>
<label>Unit:</label>
<input type="text" name="unit" required><br><br>
<label>Rate:</label>
<input type="number" step="0.01" name="rate" required><br><br>
<label>Amount:</label>
<input type="number" step="0.01" name="amount" required><br><br>
<label>Remarks:</label>
<input type="text" name="remarks"><br><br>
<input type="submit" value="Add GRN">
</form>
<h2>All GRNs</h2>
<table border="1">
<tr>
<th>ID</th><th>Date</th><th>Purchase ID</th><th>Supplier</th><th>Item</th>
<th>Qty</th><th>Unit</th><th>Rate</th><th>Amount</th><th>Remarks</th><th>Actions</th>
</tr>
{% for grn in grns %}
<tr>
<td>{{ grn[0] }}</td>
<td>{{ grn[1] }}</td>
<td>{{ grn[2] }}</td>
<td>{{ grn[3] }}</td>
<td>{{ grn[4] }}</td>
<td>{{ grn[5] }}</td>
<td>{{ grn[6] }}</td>
<td>{{ grn[7] }}</td>
<td>{{ grn[8] }}</td>
<td>{{ grn[9] }}</td>
<td style="white-space: nowrap;">
<a href="/update_grn/{{ grn['grn_id'] }}" style="margin-right: 10px;">Edit</a>
<form action="/delete_grn/{{ grn[0] }}" method="POST" style="display:inline;">
<button type="submit" onclick="return confirm('Are you sure you want to delete this GRN?')" style="background:none;border:none;color:blue;cursor:pointer;text-decoration:underline;">
Delete
</button>
</form>
</td>
</tr>
{% endfor %}
</table>
</body>
</html>

View File

@@ -34,7 +34,7 @@
<a href="/logout">Logout</a> <a href="/logout">Logout</a>
</div> </div>
<div class="sidebar"> <div class="sidebar">
<img src="https://lceplpmprod.btltech.xyz/assets/images/lcpl.png" alt="logo-image" class="logo"> <img src="http://lceplpmprod.btltech.xyz/assets/images/lcpl.png" alt="logo-image" class="logo">
<ul class="nav-menu"> <ul class="nav-menu">
<li class="nav-item"> <li class="nav-item">
@@ -70,7 +70,7 @@
</ul> </ul>
<div class="user-section"> <div class="user-section">
<img src="{{ url_for('static', filename='images/icons/male_profile.jpg') }}" alt="User Avatar"> <img src="{{ url_for('static', filename='images/icons/male_profile.jpeg') }}" alt="User Avatar">
<div class="user-info"> <div class="user-info">
<span>admin</span> <span>admin</span>
</div> </div>
@@ -133,30 +133,7 @@
<h2>Hold Types</h2> <h2>Hold Types</h2>
<a class="btn" href="/add_hold_type">Go ➜</a> <a class="btn" href="/add_hold_type">Go ➜</a>
</div> </div>
<div class="card">
<h2>Work Order</h2>
<!-- <a class="btn" href="/add_work_order">Go ➜</a> -->
<a class="btn">Go ➜</a>
</div>
<!-- <div class="card">
<h2>Purchase Order</h2>
<a class="btn" href="/add_purchase_order">Go ➜</a>
</div> -->
<!-- <div class="card">
<h2>Goods Receive Note</h2>
<a class="btn" href="/add_grn">Go ➜</a>
</div> -->
<!-- <div class="card">
<h2>Unreleased GST</h2>
<a class="btn" href="/unreleased_gst">Go ➜</a>
</div>
{# <div class="card">#}
{# <h2>Hold Release </h2>#}
{# <a class="btn" href="/add_hold_release">Go ➜</a>#}
{# </div>#}
</div> -->
</div> </div>
</body> </body>

View File

@@ -1,7 +1,6 @@
{% extends 'base.html' %} {% extends 'base.html' %}
{% block content %} {% block content %}
<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">
@@ -9,332 +8,334 @@
<!-- <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='css/style.css') }}">--> <!-- <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='css/style.css') }}">-->
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='css/subcontractor_report.css') }}"> <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='css/subcontractor_report.css') }}">
</head> </head>
<body> <body>
<div class="container"> <div class="container">
<h2>PMC Report</h2> <h2>PMC Report</h2>
<div class="info"> <div class="info">
<h2>Contractor Details</h2> <h2>Contractor Details</h2>
<div class="row2"> <div class="row2">
<div> <div>
<label for="subcontractor">Subcontractor Name:</label> <label for="subcontractor">Subcontractor Name:</label>
<input type="text" id="subcontractor" name="subcontractor" value="{{ info.Contractor_Name }}" <input type="text" id="subcontractor" name="subcontractor" value="{{ info.Contractor_Name }}"
readonly/> readonly />
</div>
<div>
<label for="Address">Address :</label>
<textarea id="Address" name="Address" readonly>{{ info.Address }}</textarea>
</div>
</div> </div>
<div> <div class="row3">
<label for="Address">Address :</label> <div>
<textarea id="Address" name="Address" readonly>{{ info.Address }}</textarea> <label for="PAN_No">PAN No :</label>
<input type="text" id="PAN_No" name="PAN_No" value="{{ info.PAN_No }}" readonly />
</div>
<div>
<label for="Mobile_No">Mobile Number :</label>
<input type="text" id="Mobile_No" name="Mobile_No" value="{{ info.Mobile_No }}" readonly />
</div>
<div>
<label for="Email">Email :</label>
<input type="text" id="Email" name="Email" value="{{ info.Email }}" readonly />
</div>
</div> </div>
</div> <div class="row2">
<div class="row3"> <div>
<div> <label for="GST_Registration_Type">GST Registration Type :</label>
<label for="PAN_No">PAN No :</label> <input type="text" id="GST_Registration_Type" name="GST_Registration_Type"
<input type="text" id="PAN_No" name="PAN_No" value="{{ info.PAN_No }}" readonly/> value="{{ info.GST_Registration_Type }}" readonly />
</div>
<div>
<label for="Mobile_No">Mobile Number :</label>
<input type="text" id="Mobile_No" name="Mobile_No" value="{{ info.Mobile_No }}" readonly/>
</div>
<div>
<label for="Email">Email :</label>
<input type="text" id="Email" name="Email" value="{{ info.Email }}" readonly/>
</div>
</div>
<div class="row2">
<div>
<label for="GST_Registration_Type">GST Registration Type :</label>
<input type="text" id="GST_Registration_Type" name="GST_Registration_Type"
value="{{ info.GST_Registration_Type }}" readonly/>
</div>
<div>
<label for="GST_No">GST No:</label>
<input type="text" id="GST_No" name="GST_No" value="{{ info.GST_No }}" readonly />
</div>
</div> </div>
<div> <h2>PMC Report for PMC No: {{ info.PMC_No}}</h2>
<label for="GST_No">GST No:</label> <div class="row3">
<input type="text" id="GST_No" name="GST_No" value="{{ info.GST_No }}" readonly/> <div>
<label for="State">State :</label>
<input type="text" id="State" name="State" value="{{ info.State_Name }}" readonly />
</div>
<div>
<label for="District">District :</label>
<input type="text" id="District" name="District" value="{{ info.District_Name }}" readonly />
</div>
<div>
<label for="Block">Block :</label>
<input type="text" id="Block" name="Block" value="{{ info.Block_Name }}" readonly />
</div>
</div> </div>
</div> <div class="row2">
<h2>PMC Report for PMC No: {{ info.PMC_No}}</h2> <div>
<div class="row3"> <label for="PMC_No">PMC No:</label>
<div> <input type="text" id="PMC_No" name="PMC_No" value="{{ info.PMC_No }}" readonly />
<label for="State">State :</label> </div>
<input type="text" id="State" name="State" value="{{ info.State_Name }}" readonly/> <div>
</div> <label for="Village_Name">Village Name :</label>
<div> <input type="text" id="Village_Name" name="Village_Name"
<label for="District">District :</label> value="{{ info.Village_Name.capitalize() }}" readonly />
<input type="text" id="District" name="District" value="{{ info.District_Name }}" readonly/> </div>
</div>
<div>
<label for="Block">Block :</label>
<input type="text" id="Block" name="Block" value="{{ info.Block_Name }}" readonly/>
</div>
</div>
<div class="row2">
<div>
<label for="PMC_No">PMC No:</label>
<input type="text" id="PMC_No" name="PMC_No" value="{{ info.PMC_No }}" readonly/>
</div>
<div>
<label for="Village_Name">Village Name :</label>
<input type="text" id="Village_Name" name="Village_Name"
value="{{ info.Village_Name.capitalize() }}" readonly/>
</div> </div>
</div> </div>
</div> </div>
</div>
<table class="total-table">
<tr>
<th colspan="2">Summary</th>
</tr>
<tr>
<th>Advance / Suplus</th>
<td>{{total["sum_invo_final_amt"]+total["sum_gst_final_amt"]-total["sum_pay_total_amt"]}}</td>
</tr>
{% if hold_types %}
<tr>
<th>
{% for hold in hold_types %}
{{ hold.hold_type }} ||
{% endfor %}
</th>
<td colspan="{{hold_types|length }}">{{total["sum_invo_hold_amt"]}}</td>
<h3>Invoice Details</h3> </tr>
<table> {% endif %}
<thead> <tr>
<tr> <th>Amount With TDS</th>
<th>PMC No</th> <td>{{total["sum_invo_tds_amt"]}}</td>
<th>Village Name</th> </tr>
<th>Work Type</th> </table>
<th>Invoice Details</th>
<th>Invoice Date</th>
<th>Invoice No</th>
<th>Basic Amount</th>
<th>Debit</th>
<th>After Debit Amt</th>
<th>GST (18%)</th>
<th>Amount</th>
<th>TDS (1%)</th>
<th>SD (5%)</th>
<th>On Commission</th>
<th>Hydro Testing</th>
<!-- Dynamic Hold Types --> <h3>Invoice Details</h3>
{% set hold_types = invoices | map(attribute='hold_type') | reject('none') | unique | list %} <table border="1" cellpadding="5" cellspacing="0">
{% for hold in hold_types %} <thead>
<th>{{ hold }}</th> <tr>
{% endfor %} <th>PMC No</th>
<th>Village Name</th>
<th>Work Type</th>
<th>Invoice Details</th>
<th>Invoice Date</th>
<th>Invoice No</th>
<th>Basic Amount</th>
<th>Debit</th>
<th>After Debit Amt</th>
<th>GST (18%)</th>
<th>Amount</th>
<th>TDS (1%)</th>
<th>SD (5%)</th>
<th>On Commission</th>
<th>Hydro Testing</th>
<th>GST SD (18%)</th> <!-- Dynamic Hold Types -->
<th>Final Amount</th> {% for ht in hold_types %}
</tr> <th>{{ ht.hold_type }}</th>
</thead> {% endfor %}
<tbody>
{% if invoices %}
{% for invoice in invoices %}
<tr>
<td>{{ invoice.PMC_No }}</td>
<td>{{ invoice.Village_Name.capitalize() if invoice.Village_Name else '' }}</td>
<td>{{ invoice.Work_Type }}</td>
<td>{{ invoice.Invoice_Details }}</td>
<td>{{ invoice.Invoice_Date }}</td>
<td>{{ invoice.Invoice_No }}</td>
<td>{{ invoice.Basic_Amount }}</td>
<td>{{ invoice.Debit_Amount }}</td>
<td>{{ invoice.After_Debit_Amount }}</td>
<td>{{ invoice.GST_Amount }}</td>
<td>{{ invoice.Amount }}</td>
<td>{{ invoice.TDS_Amount }}</td>
<td>{{ invoice.SD_Amount }}</td>
<td>{{ invoice.On_Commission }}</td>
<td>{{ invoice.Hydro_Testing }}</td>
<!-- Dynamic Hold Amounts --> <th>GST SD (18%)</th>
{% for hold in hold_types %} <th>Final Amount</th>
<td> </tr>
{% if invoice.hold_type == hold %} </thead>
{{ invoice.hold_amount }} <tbody>
{% if invoices %}
{% for invoice in invoices %}
<tr>
<td>{{ invoice.PMC_No }}</td>
<td>{{ invoice.Village_Name }}</td>
<td>{{ invoice.Work_Type }}</td>
<td>{{ invoice.Invoice_Details }}</td>
<td>{{ invoice.Invoice_Date }}</td>
<td>{{ invoice.invoice_no }}</td>
<td>{{ invoice.Basic_Amount }}</td>
<td>{{ invoice.Debit_Amount }}</td>
<td>{{ invoice.After_Debit_Amount }}</td>
<td>{{ invoice.GST_Amount }}</td>
<td>{{ invoice.Amount }}</td>
<td>{{ invoice.TDS_Amount }}</td>
<td>{{ invoice.SD_Amount }}</td>
<td>{{ invoice.On_Commission }}</td>
<td>{{ invoice.Hydro_Testing }}</td>
<!-- Hold Amounts -->
{% for ht in hold_types %}
<td>{{ hold_data.get(invoice.Invoice_Id, {}).get(ht.hold_type_id, 0) }}</td>
{% endfor %}
<td>{{ invoice.GST_SD_Amount }}</td>
<td>{{ invoice.Final_Amount }}</td>
</tr>
{% endfor %}
<!-- Total Row -->
<tr>
<th colspan="6">Total</th>
<th>{{ total.sum_invo_basic_amt }}</th>
<th>{{ total.get('sum_invo_debit_amt', 0) }}</th>
<th>{{ total.get('sum_invo_after_debit_amt', 0) }}</th>
<th>{{ total.get('sum_invo_gst_amt', 0) }}</th>
<th>{{ total.get('sum_invo_amt', 0) }}</th>
<th>{{ total.get('sum_invo_tds_amt', 0) }}</th>
<th>{{ total.get('sum_invo_ds_amt', 0) }}</th>
<th>{{ total.get('sum_invo_on_commission', 0) }}</th>
<th>{{ total.get('sum_invo_hydro_test', 0) }}</th>
{% if hold_types %}
<th colspan="{{hold_types|length }}">{{ total.sum_invo_hold_amt}}</th>
{% endif %}
<th>{{ total.get('sum_invo_gst_sd_amt', 0) }}</th>
<th>{{ total.sum_invo_final_amt }}</th>
</tr>
{% else %} {% else %}
0 <tr>
<td colspan="{{ 17 + hold_types|length }}">No invoices found.</td>
</tr>
{% endif %} {% endif %}
</td> </tbody>
{% endfor %} </table>
<td>{{ invoice.GST_SD_Amount }}</td> <br>
<td>{{ invoice.Final_Amount }}</td> <h3>GST Release Note Details</h3>
</tr>
{% endfor %} <table>
<tr> <thead>
<th colspan="6">Total</th> <tr>
<th>{{total["sum_invo_basic_amt"]}}</th> <th>PMC No</th>
<th>{{total["sum_invo_debit_amt"]}}</th> <th>Invoice No</th>
<th>{{total["sum_invo_after_debit_amt"]}}</th> <th>Basic Amount</th>
<th>{{total["sum_invo_gst_amt"]}}</th> <th>Final Amount</th>
<th>{{total["sum_invo_amt"]}}</th> <th>UTR</th>
<th>{{total["sum_invo_tds_amt"]}}</th> </tr>
<th>{{total["sum_invo_ds_amt"]}}</th> </thead>
<th>{{total["sum_invo_on_commission"]}}</th>
<th>{{total["sum_invo_hydro_test"]}}</th>
{% set hold_types = invoices | map(attribute='hold_type') | unique | list %}
{% for hold in hold_types %}
<th>{{total["sum_invo_hold_amt"]}}</th>
{% endfor %}
<th>{{total["sum_invo_gst_sd_amt"]}}</th>
<th>{{total["sum_invo_final_amt"]}}</th>
</tr>
{% else %} <tbody>
<tr>
<td colspan="{{ 17 + hold_types|length }}">No invoices found.</td>
</tr>
{% endif %}
</tbody>
</table>
<h3>Hold Release</h3>
<table>
<thead>
<tr>
<th>PMC No</th>
<th>Invoice No</th>
<th>Invoice Details</th>
<th>Basic Amount</th>
<th>Total Amount</th>
<th>UTR</th>
</tr>
</thead>
<tbody>
{%if hold_release%}
{%for hold in hold_release%}
<tr>
<td>{{ hold['PMC_No'] }}</td>
<td>{{ hold['Invoice_No'] }}</td>
<td>{{ hold['Invoice_Details'] }}</td>
<td>{{ hold['Basic_Amount'] }}</td>
<td>{{ hold['Total_Amount'] }}</td>
<td>{{ hold['UTR'] }}</td>
</tr>
{%endfor%}
{%else%}
<tr>
<td colspan="6" style="text-align:center;">No data present</td>
</tr>
{%endif%}
</tbody>
</table>
<br> {% if gst_rel %}
<h3>GST Release Note Details</h3> {% for gst in gst_rel %}
<table> <tr>
<thead> <td>{{ gst.PMC_No }}</td>
<tr> <td>{{ gst.invoice_no }}</td>
<th>PMC No</th> <td>{{ gst.Basic_Amount }}</td>
<th>Invoice No</th> <td>{{ gst.Final_Amount }}</td>
<th>Basic Amount</th> <td>{{gst.UTR}}</td>
<th>Final Amount</th> </TD>
</tr> </tr>
</thead> {% endfor %}
<tbody>
{% if gst_rel %}
{% for gst in gst_rel %}
<tr>
<td>{{ gst.pmc_no }}</td>
<td>{{ gst.invoice_no }}</td>
<td>{{ gst.basic_amount }}</td>
<td>{{ gst.final_amount }}</td>
</tr>
{% endfor %}
<tr>
<th colspan="2">Total</th>
<th>{{total["sum_gst_basic_amt"]}}</th> <tr>
<th>{{total["sum_gst_final_amt"]}}</th> <th colspan="2">Total</th>
</tr>
{% else %}
<tr>
<td colspan="4">No GST release found.</td>
</tr>
{% endif %}
</tbody>
</table>
<tr> <th>{{ total["sum_gst_basic_amt"] }}</th>
<th>{{ total["sum_gst_final_amt"] }}</th>
<th></th>
</tr>
{% else %}
<tr>
<td colspan="5">No GST release found.</td>
</tr>
{% endif %}
</tbody>
</table>
<tr>
<h3>Credit Details</h3> <h3>Credit Details</h3>
</tr> </tr>
<table> <table>
<thead> <thead>
<tr> <tr>
<th>PMC No</th> <th>PMC No</th>
<th>Invoice Details</th> <th>Invoice Details</th>
<th>Basic Amount</th> <th>Basic Amount</th>
<th>Debit</th> <th>Debit</th>
<th>After Debit Amt</th> <th>After Debit Amt</th>
<th>GST Amount</th> <th>GST Amount</th>
<th>Amount</th> <th>Amount</th>
<th>Final Amount</th> <th>Final Amount</th>
<th>Payment Amount</th> <th>Payment Amount</th>
<th>Total Amount</th> <th>Total Amount</th>
<th>UTR</th> <th>UTR</th>
</tr> </tr>
{% if credit_note %} {% if credit_note %}
{% for credit in credit_note %} {% for credit in credit_note %}
<tr> <tr>
<td>{{ credit["PMC_No"] }}</td> <td>{{ credit["PMC_No"] }}</td>
<td>{{ credit["Invoice_Details"] }}</td> <td>{{ credit["Invoice_Details"] }}</td>
<td>{{ credit["Basic_Amount"] }}</td> <td>{{ credit["Basic_Amount"] }}</td>
<td>{{ credit["Debit_Amount"] }}</td> <td>{{ credit["Debit_Amount"] }}</td>
<td>{{ credit["After_Debit_Amount"] }}</td> <td>{{ credit["After_Debit_Amount"] }}</td>
<td>{{ credit["GST_Amount"] }}</td> <td>{{ credit["GST_Amount"] }}</td>
<td>{{ credit["Amount"] }}</td> <td>{{ credit["Amount"] }}</td>
<td>{{ credit["Final_Amount"] }}</td> <td>{{ credit["Final_Amount"] }}</td>
<td>{{ credit["Payment_Amount"] }}</td> <td>{{ credit["Payment_Amount"] }}</td>
<td>{{ credit["Total_Amount"] }}</td> <td>{{ credit["Total_Amount"] }}</td>
<td>{{ credit["UTR"] }}</td> <td>{{ credit["UTR"] }}</td>
</tr> </tr>
{% endfor %} {% endfor %}
{% else %} {% else %}
<tr> <tr>
<td colspan="11">No Credit note found.</td> <td colspan="11">No Credit note found.</td>
</tr> </tr>
{% endif %} {% endif %}
</thead> </thead>
</table> </table>
<br> <br>
<h3>Payment Details</h3> <h3>Payment Details</h3>
<table> <table>
<thead> <thead>
<tr> <tr>
<th>PMC No</th> <th>PMC No</th>
<th>Invoice No</th> <th>Invoice No</th>
<th>Amount</th> <th>Amount</th>
<th>TDS Amount @ 1% on BASIC AMOUNT</th> <th>TDS Amount @ 1% on BASIC AMOUNT</th>
<th>Total Amount Paid</th> <th>Total Amount Paid</th>
<th>UTR</th> <th>UTR</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{% if payments %} {% if payments %}
{% for pay in payments %} {% for pay in payments %}
<tr> <tr>
<td>{{ pay.pmc_no }}</td> <td>{{ pay.pmc_no }}</td>
<td>{{ pay.invoice_no }}</td> <td>{{ pay.invoice_no }}</td>
<td>{{ pay.Payment_Amount }}</td> <td>{{ pay.Payment_Amount }}</td>
<td>{{ pay.TDS_Payment_Amount }}</td> <td>{{ pay.TDS_Payment_Amount }}</td>
<td>{{ pay.Total_amount }}</td> <td>{{ pay.Total_amount }}</td>
<td>{{ pay.UTR}}</td> <td>{{ pay.UTR}}</td>
</tr> </tr>
{% endfor %} {% endfor %}
<tr> <tr>
<th colspan="2">Total</th> <th colspan="2">Total</th>
<th>{{total["sum_pay_payment_amt"]}}</th> <th>{{total["sum_pay_payment_amt"]}}</th>
<th>{{total["sum_pay_tds_payment_amt"]}}</th> <th>{{total["sum_pay_tds_payment_amt"]}}</th>
<th>{{total["sum_pay_total_amt"]}}</th> <th>{{total["sum_pay_total_amt"]}}</th>
<th></th> <th></th>
</tr> </tr>
{% else %} {% else %}
<tr> <tr>
<td colspan="6">No payment found.</td> <td colspan="6">No payment found.</td>
</tr> </tr>
{% endif %} {% endif %}
</tbody> </tbody>
</table> </table>
<a href="/download_pmc_report/{{ info.PMC_No}}"> <a href="/download_pmc_report/{{ info.PMC_No}}">
<button class="download-btn">Download PMC Report</button> <button class="download-btn">Download PMC Report</button>
</a> </a>
</body> </body>
{% endblock %} {% endblock %}

View File

@@ -1,10 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Purchase Order</title>
</head>
<body>
</body>
</html>

View File

@@ -1,205 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>Purchase Order Report</title>
<link rel="stylesheet" href="{{ url_for('static', filename='css/subcontractor_report.css') }}">
<link href="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/css/select2.min.css" rel="stylesheet" />
<style>
h2.report-title {
font-size: 28px;
color: #1a73e8;
text-align: center;
margin-top: 20px;
margin-bottom: 30px;
}
.filter-section {
display: flex;
flex-direction: column;
align-items: center;
gap: 20px;
margin-bottom: 20px;
}
label {
font-weight: bold;
margin-right: 10px;
}
select {
padding: 6px;
}
#downloadBtn, #searchBtn {
padding: 10px 20px;
background-color: #4CAF50;
color: white;
border: none;
border-radius: 6px;
cursor: pointer;
margin-top: 20px;
}
#downloadBtn:hover, #searchBtn:hover {
background-color: #45a049;
}
table {
margin: 0 auto;
margin-top: 30px;
border-collapse: collapse;
width: 95%;
}
th, td {
padding: 10px;
text-align: center;
}
</style>
</head>
<body>
<h2 class="report-title">Purchase Order Report</h2>
<div class="filter-section">
<div>
<label for="supplier_name">Select Supplier Name:</label>
<select id="supplier_name" name="supplier_name" style="width: 300px;"></select>
</div>
<div>
<label for="purchase_order_no">Select Purchase Order Number:</label>
<select id="purchase_order_no" name="purchase_order_no" style="width: 300px;"></select>
</div>
<button id="searchBtn">Search</button>
<button id="downloadBtn" style="display: none;">Download Report</button>
</div>
<table border="1" id="purchaseorderTable" style="display: none;">
<thead>
<tr>
<th>Purchase ID</th>
<th>Purchase Date</th>
<th>Supplier Name</th>
<th>Purchase Order No</th>
<th>Item Name</th>
<th>Quantity</th>
<th>Unit</th>
<th>Rate</th>
<th>Amount</th>
<th>GST Amount</th>
<th>TDS</th>
<th>Final Amount</th>
</tr>
</thead>
<tbody></tbody>
</table>
<!-- JS Scripts -->
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.min.js"></script>
<script>
$(document).ready(function () {
// Initialize Select2 for supplier_name
$('#supplier_name').select2({
placeholder: 'Search Supplier Name',
ajax: {
url: '/get_supplier_names',
data: function (params) {
return { q: params.term };
},
processResults: function (data) {
return {
results: data.map(name => ({ id: name, text: name }))
};
},
delay: 250,
cache: true
}
});
// Initialize Select2 for purchase_order_no
$('#purchase_order_no').select2({
placeholder: 'Search Purchase Order No',
ajax: {
url: '/get_purchase_order_numbers',
data: function (params) {
return {
q: params.term,
supplier_name: $('#supplier_name').val()
};
},
processResults: function (data) {
return {
results: data.map(no => ({ id: no, text: no }))
};
},
delay: 250,
cache: true
}
});
// Search button click
$('#searchBtn').click(function () {
let supplier = $('#supplier_name').val();
let poNumber = $('#purchase_order_no').val();
if (!supplier && !poNumber) {
alert("Please select Supplier or Purchase Order No or both.");
return;
}
$.ajax({
url: '/get_purchase_order_data',
data: {
supplier_name: supplier,
purchase_order_no: poNumber
},
success: function (data) {
let tbody = $('#purchaseorderTable tbody');
tbody.empty();
if (data.length > 0) {
$('#purchaseorderTable').show();
$('#downloadBtn').show();
data.forEach(function (row) {
tbody.append(`
<tr>
<td>${row.purchase_id}</td>
<td>${row.purchase_date}</td>
<td>${row.supplier_name}</td>
<td>${row.purchase_order_no}</td>
<td>${row.item_name}</td>
<td>${row.quantity}</td>
<td>${row.unit}</td>
<td>${row.rate}</td>
<td>${row.amount}</td>
<td>${row.GST_Amount}</td>
<td>${row.TDS}</td>
<td>${row.final_amount}</td>
</tr>
`);
});
} else {
alert("No matching purchase orders found.");
$('#purchaseorderTable').hide();
$('#downloadBtn').hide();
}
}
});
});
// Download report
$('#downloadBtn').click(function () {
let supplier = $('#supplier_name').val();
let poNumber = $('#purchase_order_no').val();
if (!supplier && !poNumber) {
alert("Please select filters before downloading.");
return;
}
let url = '/download_purchase_order_report?';
if (supplier) url += 'supplier_name=' + encodeURIComponent(supplier);
if (poNumber) url += '&purchase_order_no=' + encodeURIComponent(poNumber);
window.location.href = url;
});
});
</script>
</body>
</html>

View File

@@ -58,7 +58,7 @@
<!-- Hidden fields for other necessary information --> <!-- Hidden fields for other necessary information -->
<input type="text" name="subcontractor_data" value="{{ subcontractor_data['Contractor_Id'] }}"> <input type="text" name="subcontractor_data" value="{{ subcontractor_data['Contractor_Id'] }}">
<input type="text" name="state_data" value="{{ state_data['State_ID'] }}"> <input type="text" name="state_data" value="{{ state_data['State_Id'] }}">
<!-- <input type="text" name="district_data" value="{{ district_data['District_ID'] }}"> --> <!-- <input type="text" name="district_data" value="{{ district_data['District_ID'] }}"> -->
<input type="text" name="district_data" value="{{ district_data['District_id'] }}"> <input type="text" name="district_data" value="{{ district_data['District_id'] }}">
<input type="text" name="block_data" value="{{ block_data['Block_Id'] }}"> <input type="text" name="block_data" value="{{ block_data['Block_Id'] }}">

View File

@@ -1,8 +1,6 @@
{% extends 'base.html' %} {% extends 'base.html' %}
{% block content %} {% block content %}
<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">
@@ -10,363 +8,341 @@
<!-- <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='css/style.css') }}">--> <!-- <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='css/style.css') }}">-->
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='css/subcontractor_report.css') }}"> <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='css/subcontractor_report.css') }}">
</head> </head>
<body> <body>
<div class="container"> <div class="container">
<h2>Contractor Report</h2> <h2>Contractor Report</h2>
<div class="info"> <div class="info">
<h2>Contractor Details</h2> <h2>Contractor Details</h2>
<div class="row2"> <div class="row2">
<div> <div>
<label for="subcontractor">Subcontractor Name:</label> <label for="subcontractor">Subcontractor Name:</label>
<input type="text" id="subcontractor" name="subcontractor" value="{{ contInfo.Contractor_Name }}" <input type="text" id="subcontractor" name="subcontractor" value="{{ info.Contractor_Name }}"
readonly/> readonly />
</div>
<div>
<label for="Address">Address :</label>
<textarea id="Address" name="Address" readonly>{{ info.Address }}</textarea>
</div>
</div> </div>
<div> <div class="row3">
<label for="Address">Address :</label> <div>
<textarea id="Address" name="Address" readonly>{{ contInfo.Address }}</textarea> <label for="PAN_No">PAN No :</label>
<input type="text" id="PAN_No" name="PAN_No" value="{{ info.PAN_No }}" readonly />
</div>
<div>
<label for="Mobile_No">Mobile Number :</label>
<input type="text" id="Mobile_No" name="Mobile_No" value="{{ info.Mobile_No }}" readonly />
</div>
<div>
<label for="Email">Email :</label>
<input type="text" id="Email" name="Email" value="{{ info.Email }}" readonly />
</div>
</div>
<div class="row2">
<div>
<label for="GST_Registration_Type">GST Registration Type :</label>
<input type="text" id="GST_Registration_Type" name="GST_Registration_Type"
value="{{ info.GST_Registration_Type }}" readonly />
</div>
<div>
<label for="GST_No">GST No:</label>
<input type="text" id="GST_No" name="GST_No" value="{{ info.GST_No }}" readonly />
</div>
</div>
<div class="row3">
<div>
<label for="State">State :</label>
<input type="text" id="State" name="State" value="{{ info.State_Name }}" readonly />
</div>
<div>
<label for="District">District :</label>
<input type="text" id="District" name="District" value="{{ info.District_Name }}" readonly />
</div>
<div>
<label for="Block">Block :</label>
<input type="text" id="Block" name="Block" value="{{ info.Block_Name }}" readonly />
</div>
</div> </div>
</div> </div>
<div class="row3">
<div>
<label for="PAN_No">PAN No :</label>
<input type="text" id="PAN_No" name="PAN_No" value="{{ contInfo.PAN_No }}" readonly/>
</div>
<div>
<label for="Mobile_No">Mobile Number :</label>
<input type="text" id="Mobile_No" name="Mobile_No" value="{{ contInfo.Mobile_No }}" readonly/>
</div>
<div>
<label for="Email">Email :</label>
<input type="text" id="Email" name="Email" value="{{ contInfo.Email }}" readonly/>
</div>
</div>
<div class="row2">
<div>
<label for="GST_Registration_Type">GST Registration Type :</label>
<input type="text" id="GST_Registration_Type" name="GST_Registration_Type"
value="{{ contInfo.GST_Registration_Type }}" readonly/>
</div> <h3>Total</h3>
<div> <table class="total-table">
<label for="GST_No">GST No:</label> <tr>
<input type="text" id="GST_No" name="GST_No" value="{{ contInfo.GST_No }}" readonly/> <th colspan="2">Summary</th>
</div> </tr>
</div> <tr>
<div class="row3"> <th>Advance / Suplus</th>
<div> <td>{{total["sum_invo_final_amt"]+total["sum_gst_final_amt"]-total["sum_pay_total_amt"]}}</td>
<label for="State">State :</label> </tr>
<input type="text" id="State" name="State" value="{{ contInfo.State_Name }}" readonly/> {% if hold_types %}
</div> <tr>
<div> <th>
<label for="District">District :</label> {% for hold in hold_types %}
<input type="text" id="District" name="District" value="{{ contInfo.District_Name }}" readonly/> {{ hold.hold_type }} ||
</div> {% endfor %}
<div> </th>
<label for="Block">Block :</label> <td colspan="{{hold_types|length }}">{{total["sum_invo_hold_amt"]}}</td>
<input type="text" id="Block" name="Block" value="{{ contInfo.Block_Name }}" readonly/>
</div>
</div>
</div>
<h3>Total</h3> </tr>
<table class="total-table"> {% endif %}
<tr> <tr>
<th colspan="2">{{current_date}}</th> <th>Amount With TDS</th>
</tr> <td>{{total["sum_invo_tds_amt"]}}</td>
<!-- <tr>--> </tr>
<!-- <th>Total Hold Amounnt</th>--> </table>
<!-- <td>0</td>-->
<!-- </tr>-->
<tr>
<th>Advance / Suplus</th>
<td>{{total["sum_invo_final_amt"]+total["sum_gst_final_amt"]-total["sum_pay_total_amt"]}}</td>
</tr>
{% if hold_types %}
<tr>
{% for hold in hold_types %}
<th>{{ hold.hold_type }}</th>
<td>{{total["sum_invo_hold_amt"]}}</td>
{% endfor %}
</tr>
{% endif %}
<tr>
<th>Amount With TDS</th>
<td>{{total["sum_invo_tds_amt"]}}</td>
</tr>
</table>
<!-- {% if hold_types %}--> <!-- {% if hold_types %}-->
<!-- <h3>Hold Types</h3>--> <!-- <h3>Hold Types</h3>-->
<!-- <ul>--> <!-- <ul>-->
<!-- {% for hold in hold_types %}--> <!-- {% for hold in hold_types %}-->
<!-- <li>{{ hold.hold_type }}</li>--> <!-- <li>{{ hold.hold_type }}</li>-->
<!-- {% endfor %}--> <!-- {% endfor %}-->
<!-- </ul>--> <!-- </ul>-->
<!-- {% endif %}--> <!-- {% endif %}-->
<h3>Invoice Details</h3> <h3>Invoice Details</h3>
<table> <table border="1" cellpadding="5" cellspacing="0">
<thead> <thead>
<tr> <tr>
<th>PMC No</th> <th>PMC No</th>
<th>Village Name</th> <th>Village Name</th>
<th>Work Type</th> <th>Work Type</th>
<th>Invoice Details</th> <th>Invoice Details</th>
<th>Invoice Date</th> <th>Invoice Date</th>
<th>Invoice No</th> <th>Invoice No</th>
<th>Basic Amount</th> <th>Basic Amount</th>
<th>Debit</th> <th>Debit</th>
<th>After Debit Amt</th> <th>After Debit Amt</th>
<th>GST (18%)</th> <th>GST (18%)</th>
<th>Amount</th> <th>Amount</th>
<th>TDS (1%)</th> <th>TDS (1%)</th>
<th>SD (5%)</th> <th>SD (5%)</th>
<th>On Commission</th> <th>On Commission</th>
<th>Hydro Testing</th> <th>Hydro Testing</th>
<!-- Dynamic Hold Types --> <!-- Dynamic Hold Types -->
{% set hold_types = invoices | map(attribute='hold_type') | unique | list %} {% for ht in hold_types %}
{% for hold in hold_types %} <th>{{ ht.hold_type }}</th>
<th>{{ hold }}</th> {% endfor %}
{% endfor %}
<th>GST SD (18%)</th> <th>GST SD (18%)</th>
<th>Final Amount</th> <th>Final Amount</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{% if invoices %} {% if invoices %}
{% for invoice in invoices %} {% for invoice in invoices %}
<tr> <tr>
<td>{{ invoice.PMC_No }}</td> <td>{{ invoice.PMC_No }}</td>
<td>{{ invoice.Village_Name.capitalize() }}</td> <td>{{ invoice.Village_Name }}</td>
<td>{{ invoice.Work_Type }}</td> <td>{{ invoice.Work_Type }}</td>
<td>{{ invoice.Invoice_Details }}</td> <td>{{ invoice.Invoice_Details }}</td>
<td>{{ invoice.Invoice_Date }}</td> <td>{{ invoice.Invoice_Date }}</td>
<td>{{ invoice.Invoice_No }}</td> <td>{{ invoice.invoice_no }}</td>
<td>{{ invoice.Basic_Amount }}</td> <td>{{ invoice.Basic_Amount }}</td>
<td>{{ invoice.Debit_Amount }}</td> <td>{{ invoice.Debit_Amount }}</td>
<td>{{ invoice.After_Debit_Amount }}</td> <td>{{ invoice.After_Debit_Amount }}</td>
<td>{{ invoice.GST_Amount }}</td> <td>{{ invoice.GST_Amount }}</td>
<td>{{ invoice.Amount }}</td> <td>{{ invoice.Amount }}</td>
<td>{{ invoice.TDS_Amount }}</td> <td>{{ invoice.TDS_Amount }}</td>
<td>{{ invoice.SD_Amount }}</td> <td>{{ invoice.SD_Amount }}</td>
<td>{{ invoice.On_Commission }}</td> <td>{{ invoice.On_Commission }}</td>
<td>{{ invoice.Hydro_Testing }}</td> <td>{{ invoice.Hydro_Testing }}</td>
<!-- Dynamic Hold Amounts --> <!-- Hold Amounts -->
{% set hold_types = invoices | map(attribute='hold_type') | unique | list %} {% for ht in hold_types %}
{% for hold in hold_types %} <td>{{ hold_data.get(invoice.Invoice_Id, {}).get(ht.hold_type_id, 0) }}</td>
<td> {% endfor %}
{% if invoice.hold_type == hold %}
{{ invoice.hold_amount }} <td>{{ invoice.GST_SD_Amount }}</td>
<td>{{ invoice.Final_Amount }}</td>
</tr>
{% endfor %}
<!-- Total Row -->
<tr>
<th colspan="6">Total</th>
<th>{{ total.sum_invo_basic_amt }}</th>
<th>{{ total.get('sum_invo_debit_amt', 0) }}</th>
<th>{{ total.get('sum_invo_after_debit_amt', 0) }}</th>
<th>{{ total.get('sum_invo_gst_amt', 0) }}</th>
<th>{{ total.get('sum_invo_amt', 0) }}</th>
<th>{{ total.get('sum_invo_tds_amt', 0) }}</th>
<th>{{ total.get('sum_invo_ds_amt', 0) }}</th>
<th>{{ total.get('sum_invo_on_commission', 0) }}</th>
<th>{{ total.get('sum_invo_hydro_test', 0) }}</th>
{% if hold_types %}
<th colspan="{{hold_types|length }}">{{ total.sum_invo_hold_amt}}</th>
{% endif %}
<th>{{ total.get('sum_invo_gst_sd_amt', 0) }}</th>
<th>{{ total.sum_invo_final_amt }}</th>
</tr>
{% else %} {% else %}
0.00 <tr>
<td colspan="{{ 17 + hold_types|length }}">No invoices found.</td>
</tr>
{% endif %} {% endif %}
</td> </tbody>
{% endfor %} </table>
<td>{{ invoice.GST_SD_Amount }}</td> <br>
<td>{{ invoice.Final_Amount }}</td>
</tr>
{% endfor %}
<tr> <tr>
<th colspan="6">Total</th> <h3>Credit Details</h3>
<th>{{total["sum_invo_basic_amt"]}}</th>
<th>{{total["sum_invo_debit_amt"]}}</th>
<th>{{total["sum_invo_after_debit_amt"]}}</th>
<th>{{total["sum_invo_gst_amt"]}}</th>
<th>{{total["sum_invo_amt"]}}</th>
<th>{{total["sum_invo_tds_amt"]}}</th>
<th>{{total["sum_invo_ds_amt"]}}</th>
<th>{{total["sum_invo_on_commission"]}}</th>
<th>{{total["sum_invo_hydro_test"]}}</th>
{% set hold_types = invoices | map(attribute='hold_type') | unique | list %}
{% for hold in hold_types %}
<th>{{total["sum_invo_hold_amt"]}}</th>
{% endfor %}
<th>{{total["sum_invo_gst_sd_amt"]}}</th>
<th>{{total["sum_invo_final_amt"]}}</th>
</tr> </tr>
<table>
<thead>
<tr>
<th>PMC No</th>
<th>Invoice Details</th>
<th>Basic Amount</th>
<th>Debit</th>
<th>After Debit Amt</th>
<th>GST Amount</th>
<th>Amount</th>
<th>Final Amount</th>
<th>Payment Amount</th>
<th>Total Amount</th>
<th>UTR</th>
{% else %} </tr>
<tr>
<td colspan="{{ 17 + hold_types|length }}">No invoices found.</td>
</tr>
{% endif %}
</tbody>
</table>
<h3>Hold Release</h3> {% if credit_note %}
<table> {% for credit in credit_note %}
<thead> <tr>
<tr> <td>{{ credit["PMC_No"] }}</td>
<th>PMC No</th> <td>{{ credit["Invoice_Details"] }}</td>
<th>Invoice No</th> <td>{{ credit["Basic_Amount"] }}</td>
<th>Invoice Details</th> <td>{{ credit["Debit_Amount"] }}</td>
<th>Basic Amount</th> <td>{{ credit["After_Debit_Amount"] }}</td>
<th>Total Amount</th> <td>{{ credit["GST_Amount"] }}</td>
<th>UTR</th> <td>{{ credit["Amount"] }}</td>
</tr> <td>{{ credit["Final_Amount"] }}</td>
</thead> <td>{{ credit["Payment_Amount"] }}</td>
<tbody> <td>{{ credit["Total_Amount"] }}</td>
{% if hold_release %} <td>{{ credit["UTR"] }}</td>
{% for hold in hold_release %}
<tr>
<td>{{ hold['PMC_No'] }}</td>
<td>{{ hold['Invoice_No'] }}</td>
<td>{{ hold['Invoice_Details'] }}</td>
<td>{{ hold['Basic_Amount'] }}</td>
<td>{{ hold['Total_Amount'] }}</td>
<td>{{ hold['UTR'] }}</td>
</tr>
{% endfor %}
{% else %}
<tr>
<td colspan="6" style="text-align:center;">No data present</td>
</tr>
{% endif %}
</tbody>
</table>
<br>
<tr> </tr>
<h3>Credit Details</h3> {% endfor %}
</tr>
<table>
<thead>
<tr>
<th>PMC No</th>
<th>Invoice Details</th>
<th>Basic Amount</th>
<th>Debit</th>
<th>After Debit Amt</th>
<th>GST Amount</th>
<th>Amount</th>
<th>Final Amount</th>
<th>Payment Amount</th>
<th>Total Amount</th>
<th>UTR</th>
</tr> {% else %}
<tr>
{% if credit_note %} <td colspan="11">No Credit note found.</td>
{% for credit in credit_note %} </tr>
<tr> {% endif %}
<td>{{ credit["PMC_No"] }}</td>
<td>{{ credit["Invoice_Details"] }}</td>
<td>{{ credit["Basic_Amount"] }}</td>
<td>{{ credit["Debit_Amount"] }}</td>
<td>{{ credit["After_Debit_Amount"] }}</td>
<td>{{ credit["GST_Amount"] }}</td>
<td>{{ credit["Amount"] }}</td>
<td>{{ credit["Final_Amount"] }}</td>
<td>{{ credit["Payment_Amount"] }}</td>
<td>{{ credit["Total_Amount"] }}</td>
<td>{{ credit["UTR"] }}</td>
</tr> </thead>
{% endfor %} </table>
<h3>GST Release Note Details</h3>
{% else %} <table>
<tr> <thead>
<td colspan="11">No Credit note found.</td> <tr>
</tr> <th>PMC No</th>
{% endif %} <th>Invoice No</th>
<th>Basic Amount</th>
<th>Final Amount</th>
<th>Total_Amount</th>
<th>UTR</th>
</tr>
</thead>
<tbody>
{% if gst_rel %}
{% for gst in gst_rel %}
<tr>
<td>{{ gst.PMC_No }}</td>
<td>{{ gst.Invoice_No }}</td>
<td>{{ gst.Basic_Amount }}</td>
<td>{{ gst.Final_Amount }}</td>
<td>{{gst.Total_Amount}}</td>
<td>{{gst.UTR}}</td>
</TD>
</tr>
{% endfor %}
<tr>
<th colspan="2">Total</th>
<th>{{ total["sum_gst_basic_amt"] }}</th>
<th>{{ total["sum_gst_final_amt"] }}</th>
<th>{{total["sum_gst_total_amt"]}}</th>
<th></th>
</tr>
{% else %}
<tr>
<td colspan="5">No GST release found.</td>
</tr>
{% endif %}
</tbody>
</table>
</thead> <br>
</table> <h3>Payment Details</h3>
<h3>GST Release Note Details</h3> <table>
<table> <thead>
<thead> <tr>
<tr> <th>PMC No</th>
<th>PMC No</th> <th>Invoice No</th>
<th>Invoice No</th> <th>Amount</th>
<th>Basic Amount</th> <th>TDS Amount @ 1% on BASIC AMOUNT</th>
<th>Final Amount</th> <th>Total Amount Paid</th>
</tr> <th>UTR</th>
</tr>
</thead>
<tbody>
{% if payments %}
{% for pay in payments %}
<tr>
<td>{{ pay.pmc_no }}</td>
<td>{{ pay.invoice_no }}</td>
<td>{{ pay.Payment_Amount }}</td>
<td>{{ pay.TDS_Payment_Amount }}</td>
<td>{{ pay.Total_amount }}</td>
<td>{{ pay.utr}}</td>
</tr>
{% endfor %}
<tr>
<th colspan="2">Total</th>
<th>{{total["sum_pay_payment_amt"]}}</th>
<th>{{total["sum_pay_tds_payment_amt"]}}</th>
<th>{{total["sum_pay_total_amt"]}}</th>
<th></th>
</tr>
{% else %}
<tr>
<td colspan="6">No payment found.</td>
</tr>
{% endif %}
</tbody>
</table>
</thead> <a href="{{ url_for('report.download_report', contractor_id=contractor_id) }}" class="download-btn">Download
<tbody> Report</a>
{% if gst_rel %} </div>
{% for gst in gst_rel %}
<tr>
<td>{{ gst.pmc_no }}</td>
<td>{{ gst.invoice_no }}</td>
<td>{{ gst.basic_amount }}</td>
<td>{{ gst.final_amount }}</td>
</tr>
{% endfor %}
<tr>
<th colspan="2">Total</th>
<th>{{total["sum_gst_basic_amt"]}}</th>
<th>{{total["sum_gst_final_amt"]}}</th>
</tr>
{% else %}
<tr>
<td colspan="4">No GST release found.</td>
</tr>
{% endif %}
</tbody>
</table>
<br>
<h3>Payment Details</h3>
<table>
<thead>
<tr>
<th>PMC No</th>
<th>Invoice No</th>
<th>Amount</th>
<th>TDS Amount @ 1% on BASIC AMOUNT</th>
<th>Total Amount Paid</th>
<th>UTR</th>
</tr>
</thead>
<tbody>
{% if payments %}
{% for pay in payments %}
<tr>
<td>{{ pay.pmc_no }}</td>
<td>{{ pay.invoice_no }}</td>
<td>{{ pay.Payment_Amount }}</td>
<td>{{ pay.TDS_Payment_Amount }}</td>
<td>{{ pay.Total_amount }}</td>
<td>{{ pay.utr}}</td>
</tr>
{% endfor %}
<tr>
<th colspan="2">Total</th>
<th>{{total["sum_pay_payment_amt"]}}</th>
<th>{{total["sum_pay_tds_payment_amt"]}}</th>
<th>{{total["sum_pay_total_amt"]}}</th>
<th></th>
</tr>
{% else %}
<tr>
<td colspan="6">No payment found.</td>
</tr>
{% endif %}
</tbody>
</table>
<a href="{{ url_for('report.download_report', contractor_id=contractor_id) }}" class="download-btn">Download Report</a>
</div>
</body> </body>
{% endblock %} {% endblock %}

View File

@@ -1,209 +0,0 @@
{% extends 'base.html' %}
{% block content %}
<head>
<title>Work Order Report</title>
<link rel="stylesheet" href="{{ url_for('static', filename='css/subcontractor_report.css') }}">
<link href="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/css/select2.min.css" rel="stylesheet" />
<style>
h2.report-title {
font-size: 28px;
color: #1a73e8;
text-align: center;
margin-top: 20px;
margin-bottom: 30px;
}
.filter-section {
display: flex;
flex-direction: column;
align-items: center;
gap: 20px;
margin-bottom: 20px;
}
label {
font-weight: bold;
margin-right: 10px;
}
select {
padding: 6px;
}
#downloadBtn, #searchBtn {
padding: 10px 20px;
background-color: #4CAF50;
color: white;
border: none;
border-radius: 6px;
cursor: pointer;
margin-top: 20px;
}
#downloadBtn:hover, #searchBtn:hover {
background-color: #45a049;
}
table {
margin: 0 auto;
margin-top: 30px;
border-collapse: collapse;
width: 95%;
}
th, td {
padding: 10px;
text-align: center;
}
</style>
</head>
<body>
<h2 class="report-title">Work Order Report</h2>
<div class="filter-section">
<div>
<label for="vendor_name">Select Vendor Name:</label>
<select id="vendor_name" name="vendor_name" style="width: 300px;"></select>
</div>
<div>
<label for="work_order_number">Select Work Order Number:</label>
<select id="work_order_number" name="work_order_number" style="width: 300px;"></select>
</div>
<button id="searchBtn">Search</button>
<button id="downloadBtn" style="display: none;">Download Report</button>
</div>
<table border="1" id="workOrderTable" style="display: none;">
<thead>
<tr>
<th>ID</th>
<th>Vendor Name</th>
<th>Work Order Type</th>
<th>Amount</th>
<th>BOQ</th>
<th>Done %</th>
<th>GST</th>
<th>TDS</th>
<th>Security Deposit</th>
<th>SD GST</th>
<th>Final Total</th>
<th>TDS of GST</th>
</tr>
</thead>
<tbody></tbody>
</table>
<!-- JS Scripts -->
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.min.js"></script>
<script>
$(document).ready(function () {
$('#vendor_name, #work_order_number').select2({
placeholder: 'Search',
minimumInputLength: 1,
ajax: {
delay: 250,
dataType: 'json',
cache: true
}
});
$('#vendor_name').select2({
placeholder: 'Search Vendor',
ajax: {
url: '/get_vendor_names',
data: function (params) {
return { q: params.term };
},
processResults: function (data) {
return {
results: data.map(v => ({ id: v, text: v }))
};
}
}
});
$('#work_order_number').select2({
placeholder: 'Search Work Order',
ajax: {
url: '/get_work_order_numbers',
data: function (params) {
return {
q: params.term,
vendor_name: $('#vendor_name').val()
};
},
processResults: function (data) {
return {
results: data.map(o => ({ id: o, text: o }))
};
}
}
});
// Fetch and display table
$('#searchBtn').click(function () {
let vendor = $('#vendor_name').val();
let order = $('#work_order_number').val();
if (!vendor && !order) {
alert("Please select Vendor or Work Order Number or both.");
return;
}
$.ajax({
url: '/get_work_order_data',
data: {
vendor_name: vendor,
work_order_number: order
},
success: function (data) {
let tbody = $('#workOrderTable tbody');
tbody.empty();
if (data.length > 0) {
$('#workOrderTable').show();
$('#downloadBtn').show();
data.forEach(function (row) {
tbody.append(`
<tr>
<td>${row.work_order_id}</td>
<td>${row.vendor_name}</td>
<td>${row.work_order_type}</td>
<td>${row.work_order_amount}</td>
<td>${row.boq_amount}</td>
<td>${row.work_done_percentage}</td>
<td>${row.gst_amount}</td>
<td>${row.tds_amount}</td>
<td>${row.security_deposit}</td>
<td>${row.sd_against_gst}</td>
<td>${row.final_total}</td>
<td>${row.tds_of_gst}</td>
</tr>
`);
});
} else {
alert("No data found for selected filters.");
$('#workOrderTable').hide();
$('#downloadBtn').hide();
}
}
});
});
// Download report
$('#downloadBtn').click(function () {
let vendor = $('#vendor_name').val();
let order = $('#work_order_number').val();
if (!vendor && !order) {
alert("Please select filters before downloading.");
return;
}
let url = '/download_work_order_report?';
if (vendor) url += 'vendor_name=' + encodeURIComponent(vendor);
if (order) url += '&work_order_number=' + encodeURIComponent(order);
window.location.href = url;
});
});
</script>
</body>
{% endblock %}

View File

@@ -1,482 +0,0 @@
logging.basicConfig(level=logging.DEBUG)
@app.route('/add_purchase_order', methods=['GET', 'POST'])
def add_purchase_order():
connection = config.get_db_connection()
cursor = connection.cursor(dictionary=True)
if request.method == 'POST':
# Fetch form fields
purchase_date = request.form.get('purchase_date')
supplier_name = request.form.get('supplier_name')
purchase_order_no = request.form.get('purchase_order_no')
item_name = request.form.get('item_name')
quantity = request.form.get('quantity')
unit = request.form.get('unit')
rate = request.form.get('rate')
amount = request.form.get('amount')
GST_Amount = request.form.get('GST_Amount')
TDS = request.form.get('TDS')
final_amount = request.form.get('final_amount')
LogHelper.log_action("Add purchase order", f"User {current_user.id} Added puirchase Order'{ purchase_order_no}'")
# Insert into database
insert_query = """
INSERT INTO purchase_order (
purchase_date, supplier_name, purchase_order_no, item_name, quantity, unit, rate, amount,
GST_Amount, TDS, final_amount
) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)
"""
cursor.execute(insert_query, (
purchase_date, supplier_name, purchase_order_no, item_name, quantity, unit, rate, amount,
GST_Amount, TDS, final_amount
))
connection.commit()
# ✅ Always fetch updated data
cursor.execute("SELECT * FROM purchase_order")
purchases = cursor.fetchall()
cursor.close()
connection.close()
return render_template('add_purchase_order.html', purchases=purchases)
# Show all purchases
@app.route('/purchase_orders')
def show_purchase_orders():
connection = config.get_db_connection()
cursor = connection.cursor(dictionary=True)
cursor.execute("SELECT * FROM purchase_order")
purchases = cursor.fetchall()
cursor.close()
connection.close()
return render_template('add_purchase_order.html', purchases=purchases)
# Delete purchase order
@app.route('/delete_purchase/<int:id>', methods=['POST'])
def delete_purchase(id):
connection = config.get_db_connection()
cursor = connection.cursor()
cursor.execute("DELETE FROM purchase_order WHERE purchase_id = %s", (id,))
connection.commit()
cursor.close()
connection.close()
LogHelper.log_action("Delete purchase order", f"User {current_user.id} Deleted puirchase Order'{ id}'")
return render_template(('add_purchase_order.html'))
# Edit purchase order (form + update logic)
@app.route('/update_purchase/<int:id>', methods=['GET', 'POST'])
def update_purchase(id):
connection = config.get_db_connection()
cursor = connection.cursor(dictionary=True)
if request.method == 'POST':
# ✅ Form submitted - update all fields
data = request.form
cursor.execute("""
UPDATE purchase_order
SET purchase_date = %s,
supplier_name = %s,
purchase_order_no = %s,
item_name = %s,
quantity = %s,
unit = %s,
rate = %s,
amount = %s,
GST_Amount = %s,
TDS = %s,
final_amount = %s
WHERE purchase_id = %s
""", (
data['purchase_date'], data['supplier_name'], data['purchase_order_no'], data['item_name'],
data['quantity'],
data['unit'], data['rate'], data['amount'], data['GST_Amount'], data['TDS'], data['final_amount'],
id
))
connection.commit()
cursor.close()
connection.close()
LogHelper.log_action("Delete purchase order", f"User {current_user.id} Deleted puirchase Order'{ id}'")
return redirect(url_for('show_purchase_orders'))
# Show edit form
cursor.execute("SELECT * FROM purchase_order WHERE purchase_id = %s", (id,))
purchase = cursor.fetchone()
cursor.close()
connection.close()
return render_template('edit_purchase.html', purchase=purchase)
# SHOW all GRNs + ADD form
@app.route('/grn', methods=['GET'])
def grn_page():
connection = config.get_db_connection()
cursor = connection.cursor(dictionary=True)
# Fetch purchase orders for dropdown
cursor.execute("SELECT purchase_id, supplier_name FROM purchase_order")
purchase_orders = cursor.fetchall()
# Fetch all GRNs to display
cursor.execute("SELECT * FROM goods_receive_note")
grns = cursor.fetchall()
print(grns)
cursor.close()
connection.close()
# Render the template with both datasets
return render_template('grn_form.html', purchase_orders=purchase_orders, grns=grns)
# ADD new GRN
@app.route('/add_grn', methods=['POST', 'GET'])
def add_grn():
data = request.form
connection = config.get_db_connection()
cursor = connection.cursor()
query = """
INSERT INTO goods_receive_note
(grn_date, purchase_id, supplier_name, item_description, received_quantity, unit, rate, amount, remarks)
VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s) \
"""
cursor.execute(query, (
data.get('grn_date'),
data.get('purchase_id'),
data.get('supplier_name'),
data.get('item_description'),
data.get('received_quantity'),
data.get('unit'),
data.get('rate'),
data.get('amount'),
data.get('remarks')
))
connection.commit()
cursor.execute("SELECT * FROM goods_receive_note")
grns = cursor.fetchall()
print(grns)
query = "select * from purchase_order"
cursor.execute(query)
purchase_orders = cursor.fetchall()
cursor.close()
connection.close()
return render_template('grn_form.html', purchase_orders=purchase_orders, grns=grns)
# UPDATE GRN
@app.route('/update_grn/<int:grn_id>', methods=['GET', 'POST'])
def update_grn(grn_id):
connection = config.get_db_connection()
cursor = connection.cursor(dictionary=True)
if request.method == 'POST':
data = request.form
query = """
UPDATE goods_receive_note
SET grn_date=%s, purchase_id=%s, supplier_name=%s, item_description=%s,
received_quantity=%s, unit=%s, rate=%s, amount=%s, remarks=%s
WHERE grn_id=%s
"""
cursor.execute(query, (
data['grn_date'], data['purchase_id'], data['supplier_name'],
data['item_description'], data['received_quantity'], data['unit'],
data['rate'], data['amount'], data['remarks'], grn_id
))
connection.commit()
cursor.close()
connection.close()
return redirect(url_for('grns'))
cursor.execute("SELECT * FROM goods_receive_note WHERE grn_id = %s", (grn_id,))
grn = cursor.fetchone()
cursor.close()
connection.close()
return render_template("edit_grn.html", grn=grn)
# DELETE GRN
@app.route('/delete_grn/<int:grn_id>', methods=['POST'])
def delete_grn(grn_id):
connection = config.get_db_connection()
cursor = connection.cursor()
cursor.execute("DELETE FROM goods_receive_note WHERE grn_id = %s", (grn_id,))
connection.commit()
cursor.close()
connection.close()
return render_template("grn_form.html")
@app.route('/work_order_report', methods=['GET'])
def work_order_report():
return render_template('work_order_report.html')
# ✅ Vendor Name Search (for Select2)
@app.route('/get_vendor_names')
def get_vendor_names():
query = request.args.get('q', '')
connection = config.get_db_connection()
cursor = connection.cursor()
cursor.execute("SELECT DISTINCT vendor_name FROM work_order WHERE vendor_name LIKE %s", (f"%{query}%",))
vendors = [row[0] for row in cursor.fetchall()]
cursor.close()
connection.close()
return jsonify(vendors)
# ✅ Work Order Number Search (with or without vendor)
@app.route('/get_work_order_numbers')
def get_work_order_numbers():
vendor = request.args.get('vendor_name', '')
query = request.args.get('q', '')
connection = config.get_db_connection()
cursor = connection.cursor()
if vendor:
cursor.execute(
"SELECT DISTINCT work_order_number FROM work_order WHERE vendor_name = %s AND work_order_number LIKE %s",
(vendor, f"%{query}%"))
else:
cursor.execute("SELECT DISTINCT work_order_number FROM work_order WHERE work_order_number LIKE %s",
(f"%{query}%",))
orders = [row[0] for row in cursor.fetchall()]
cursor.close()
connection.close()
return jsonify(orders)
# ✅ Get Work Order Data (Filtered)
@app.route('/get_work_order_data')
def get_work_order_data():
vendor = request.args.get('vendor_name')
order_number = request.args.get('work_order_number')
query = "SELECT * FROM work_order WHERE 1=1"
params = []
if vendor:
query += " AND vendor_name = %s"
params.append(vendor)
if order_number:
query += " AND work_order_number = %s"
params.append(order_number)
connection = config.get_db_connection()
cursor = connection.cursor(dictionary=True)
cursor.execute(query, tuple(params))
data = cursor.fetchall()
cursor.close()
connection.close()
return jsonify(data)
@app.route('/download_work_order_report')
def download_work_order_report():
vendor_name = request.args.get('vendor_name')
work_order_number = request.args.get('work_order_number')
if work_order_number == "null":
work_order_number = None
query = "SELECT * FROM work_order WHERE 1=1"
params = []
if vendor_name:
query += " AND vendor_name = %s"
params.append(vendor_name)
if work_order_number:
query += " AND work_order_number = %s"
params.append(work_order_number)
conn = config.get_db_connection()
cursor = conn.cursor(dictionary=True)
cursor.execute(query, tuple(params))
data = cursor.fetchall()
cursor.close()
conn.close()
if not data:
return "No data found for the selected filters", 404
# Convert to DataFrame
df = pd.DataFrame(data)
output_path = 'static/downloads/work_order_report.xlsx'
os.makedirs(os.path.dirname(output_path), exist_ok=True)
df.to_excel(output_path, index=False, startrow=2) # Leave space for heading
# Load workbook for styling
wb = load_workbook(output_path)
ws = wb.active
# Add a merged title
title = "Work Order Report"
ws.merge_cells(start_row=1, start_column=1, end_row=1, end_column=len(df.columns))
title_cell = ws.cell(row=1, column=1)
title_cell.value = title
title_cell.font = Font(size=14, bold=True, color="1F4E78")
title_cell.alignment = Alignment(horizontal="center", vertical="center")
# Style header row (row 3 because data starts from row 3)
header_font = Font(bold=True)
for col_num, column_name in enumerate(df.columns, 1):
cell = ws.cell(row=3, column=col_num)
cell.font = header_font
cell.alignment = Alignment(horizontal="center", vertical="center")
# Optional: adjust column width
max_length = max(len(str(column_name)), 12)
ws.column_dimensions[get_column_letter(col_num)].width = max_length + 2
wb.save(output_path)
return send_file(output_path, as_attachment=True)
@app.route('/purchase_order_report', methods=['GET'])
def purchase_order_report():
return render_template('purchase_order_report.html')
@app.route('/get_supplier_names')
def get_supplier_names():
query = request.args.get('q', '') # Get the search term from Select2
connection = config.get_db_connection()
cursor = connection.cursor()
# Fetch distinct supplier names that match the search query
cursor.execute(
"SELECT supplier_name FROM purchase_order WHERE supplier_name LIKE %s",
(f"%{query}%",)
)
suppliers = [row[0] for row in cursor.fetchall()]
cursor.close()
connection.close()
return jsonify(suppliers)
@app.route('/get_purchase_order_numbers')
def get_purchase_order_numbers():
supplier = request.args.get('supplier_name', '')
query = request.args.get('q', '')
connection = config.get_db_connection()
cursor = connection.cursor()
if supplier:
cursor.execute("""
SELECT purchase_order_no
FROM purchase_order
WHERE supplier_name = %s AND purchase_order_no LIKE %s
""", (supplier, f"%{query}%"))
else:
cursor.execute("""
SELECT purchase_order_no
FROM purchase_order
WHERE purchase_order_no LIKE %s
""", (f"%{query}%",))
orders = [row[0] for row in cursor.fetchall()]
cursor.close()
connection.close()
return jsonify(orders)
@app.route('/get_purchase_order_data')
def get_purchase_order_data():
supplier = request.args.get('supplier_name')
order_no = request.args.get('purchase_order_no')
query = "SELECT * FROM purchase_order WHERE 1=1"
params = []
if supplier:
query += " AND supplier_name = %s"
params.append(supplier)
if order_no:
query += " AND purchase_order_no = %s"
params.append(order_no)
connection = config.get_db_connection()
cursor = connection.cursor(dictionary=True)
cursor.execute(query, tuple(params))
data = cursor.fetchall()
cursor.close()
connection.close()
return jsonify(data)
@app.route('/download_purchase_order_report')
def download_purchase_order_report():
supplier_name = request.args.get('supplier_name')
purchase_order_no = request.args.get('purchase_order_no')
if purchase_order_no == "null":
purchase_order_no = None
LogHelper.log_action("Download purchase order", f"User {current_user.id} Download puirchase Order'{ purchase_order_no}'")
query = "SELECT * FROM purchase_order WHERE 1=1"
params = []
if supplier_name:
query += " AND supplier_name = %s"
params.append(supplier_name)
if purchase_order_no:
query += " AND purchase_order_no = %s"
params.append(purchase_order_no)
conn = config.get_db_connection()
cursor = conn.cursor(dictionary=True)
cursor.execute(query, tuple(params))
data = cursor.fetchall()
cursor.close()
conn.close()
if not data:
return "No data found for the selected filters", 404
# Convert to DataFrame
df = pd.DataFrame(data)
output_path = 'static/downloads/purchase_order_report.xlsx'
os.makedirs(os.path.dirname(output_path), exist_ok=True)
df.to_excel(output_path, index=False, startrow=2) # Reserve space for heading
# Load workbook for styling
wb = load_workbook(output_path)
ws = wb.active
# Add a merged title
title = "Purchase Order Report"
ws.merge_cells(start_row=1, start_column=1, end_row=1, end_column=len(df.columns))
title_cell = ws.cell(row=1, column=1)
title_cell.value = title
title_cell.font = Font(size=14, bold=True, color="1F4E78")
title_cell.alignment = Alignment(horizontal="center", vertical="center")
# Style header row (row 3 because data starts from row 3)
header_font = Font(bold=True)
for col_num, column_name in enumerate(df.columns, 1):
cell = ws.cell(row=3, column=col_num)
cell.font = header_font
cell.alignment = Alignment(horizontal="center", vertical="center")
max_length = max(len(str(column_name)), 12)
ws.column_dimensions[get_column_letter(col_num)].width = max_length + 2
wb.save(output_path)
return send_file(output_path, as_attachment=True)
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000, debug=True)

View File

@@ -1,128 +0,0 @@
# -- end hold types controlller --------------------
# Route to display the HTML form
@app.route('/add_work_order', methods=['GET'])
def add_work_order():
# Add database connection
connection = config.get_db_connection()
cursor = connection.cursor(dictionary=True)
cursor.execute("SELECT Contractor_id, Contractor_Name FROM subcontractors") # Adjust table/column names as needed
subcontractor = cursor.fetchall()
cursor.close()
connection.close()
return render_template('add_work_order.html', subcontractor=subcontractor) # This is your HTML form page
# Route to handle form submission (from action="/submit_work_order")
@app.route('/submit_work_order', methods=['POST', 'GET'])
def submit_work_order():
vendor_name = request.form['vendor_name']
work_order_type = request.form['work_order_type']
work_order_amount = request.form['work_order_amount']
boq_amount = request.form['boq_amount']
work_done_percentage = request.form['work_done_percentage']
work_order_number = request.form['work_order_number']
gst_amount = request.form['gst_amount']
tds_amount = request.form['tds_amount']
security_deposite = request.form['security_deposite']
sd_against_gst = request.form['sd_against_gst']
final_total = request.form['final_total']
tds_of_gst = request.form['tds_of_gst']
LogHelper.log_action("Submit Work Order", f"User {current_user.id} Submit Work Order'{ work_order_type}'")
# print("Good Morning How are U")
connection = config.get_db_connection()
cursor = connection.cursor(dictionary=True)
# print("Good morning and how are you")
insert_query = """
INSERT INTO work_order
(vendor_name, work_order_type, work_order_amount, boq_amount, work_done_percentage,work_order_number,gst_amount,tds_amount
,security_deposit,sd_against_gst,final_total,tds_of_gst)
VALUES (%s, %s, %s, %s, %s,%s,%s,%s,%s,%s,%s,%s)
"""
cursor.execute(insert_query,
(vendor_name, work_order_type, work_order_amount, boq_amount, work_done_percentage, work_order_number
, gst_amount, tds_amount, security_deposite, sd_against_gst, final_total, tds_of_gst))
connection.commit()
# ✅ Fetch all data after insert
select_query = "SELECT * FROM work_order"
cursor.execute(select_query)
wo = cursor.fetchall()
# print("The Work order data is ",wo)
print("The data from work order ", wo) # should now print the data properly
cursor.execute("SELECT Contractor_id, Contractor_Name FROM subcontractors") # Adjust table/column names as needed
subcontractor = cursor.fetchall()
cursor.close()
connection.close()
return render_template('add_work_order.html', work_order_type=work_order_type, wo=wo, subcontractor=subcontractor)
@app.route('/delete_work_order/<int:id>', methods=['POST'])
def delete_work_order(id):
connection = config.get_db_connection()
cursor = connection.cursor()
cursor.execute("DELETE FROM work_order WHERE work_order_id = %s", (id,))
connection.commit()
cursor.close()
connection.close()
LogHelper.log_action("delete Work Order", f"User {current_user.id} delete Work Order'{ id}'")
return jsonify({'success': True})
@app.route('/update_work_order/<int:id>', methods=['GET', 'POST'])
def update_work_order(id):
connection = config.get_db_connection()
cursor = connection.cursor(dictionary=True)
if request.method == 'POST':
work_order_type = request.form['work_order_type']
work_order_amount = request.form['work_order_amount']
boq_amount = request.form['boq_amount']
work_done_percentage = request.form['work_done_percentage']
work_order_number = request.form['work_order_number']
gst_amount = request.form['gst_amount']
tds_amount = request.form['tds_amount']
security_deposite = request.form['security_deposite']
sd_against_gst = request.form['sd_against_gst']
final_amount = request.form['final_amount']
tds_of_gst = request.form['tds_of_gst']
update_query = """
UPDATE work_order
SET work_order_type = %s,
work_order_amount = %s,
boq_amount = %s,
work_done_percentage = %s,
work_order_number= %s,
gst_amount = %s,
tds_amount= %s,
security_deposite= %s,
sd_against_gst=%s,
final_amount= %s,
tds_of_gst=%s
WHERE work_order_id = %s
"""
cursor.execute(update_query, (
work_order_type, work_order_amount, boq_amount, work_done_percentage, work_order_number, gst_amount,
tds_amount, security_deposite, sd_against_gst, final_amount, tds_of_gst, id))
connection.commit()
cursor.close()
connection.close()
# If GET request: fetch the existing record
cursor.execute("SELECT * FROM work_order WHERE work_order_id = %s", (id,))
work_order = cursor.fetchone()
cursor.close()
connection.close()
return render_template('update_work_order.html', work_order=work_order)
# Optional: Route to show a success message
@app.route('/success')
def success():
return "Work Order Submitted Successfully!"