updated code by aakash

This commit is contained in:
2026-03-30 11:36:16 +05:30
parent 88e8771b51
commit 0b72adef7d
28 changed files with 505 additions and 700 deletions

View File

@@ -1,16 +1,6 @@
from flask import Blueprint, render_template, request, redirect, url_for, jsonify
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
class Block:
@@ -22,9 +12,7 @@ class Block:
self.isSuccess = False
self.resultMessage = ""
# ----------------------------------------------------------
# Add Block
# ----------------------------------------------------------
def AddBlock(self, request):
block = ItemCRUD(itemType=ItemCRUDType.Block)
@@ -37,17 +25,7 @@ class Block:
self.resultMessage = block.resultMessage
return
# ----------------------------------------------------------
# Get All Blocks
# ----------------------------------------------------------
# def GetAllBlocks(self):
# block = ItemCRUD(itemType=ItemCRUDType.Block)
# blocksdata = block.GetAllData(request=request, storedproc="GetAllBlock")
# self.isSuccess = block.isSuccess
# self.resultMessage = block.resultMessage
# return blocksdata
# Get All Blocks
def GetAllBlocks(self, request):
block = ItemCRUD(itemType=ItemCRUDType.Block)
@@ -57,18 +35,8 @@ class Block:
self.resultMessage = block.resultMessage
return blocksdata
# ----------------------------------------------------------
# Check Block Exists
# ----------------------------------------------------------
# def CheckBlock(self, request):
# block = ItemCRUD(itemType=ItemCRUDType.Block)
# block_name = request.json.get('block_Name', '').strip()
# district_id = request.json.get('district_Id')
# result = block.CheckItem(request=request, parentid=district_id, childname=block_name, storedprocfetch="GetBlockByNameAndDistrict")
# self.isSuccess = block.isSuccess
# self.resultMessage = block.resultMessage
# return result
def CheckBlock(self, request):
block = ItemCRUD(itemType=ItemCRUDType.Block)
data = request.get_json(silent=True) or request.form
@@ -85,24 +53,7 @@ class Block:
self.resultMessage = block.resultMessage
return result
# ----------------------------------------------------------
# Get Block By ID
# ----------------------------------------------------------
# def GetBlockByID(self, id):
# block = ItemCRUD(itemType=ItemCRUDType.Village)
# blockdata = block.GetAllData(id=id,storedproc="GetBlockDataByID")
# self.isSuccess = block.isSuccess
# self.resultMessage = block.resultMessage
# print("akash"+blockdata)
# return blockdata
# def GetBlockByID(self,request,id):
# block = ItemCRUD(itemType=ItemCRUDType.Block)
# blockdata = block.GetDataByID(request=request,id=id,storedproc="GetBlockDataByID")
# self.isSuccess = block.isSuccess
# self.resultMessage = block.resultMessage
# return blockdata
def GetBlockByID(self, id):
block = ItemCRUD(itemType=ItemCRUDType.Block)
@@ -116,20 +67,8 @@ class Block:
self.resultMessage = block.resultMessage
return blockdata
# ----------------------------------------------------------
# Update Block
# ----------------------------------------------------------
# def EditBlock(self, request, block_id):
# block = ItemCRUD(itemType=ItemCRUDType.Block)
# district_id = request.form.get('district_Id')
# block_name = request.form.get('block_Name', '').strip()
# block.EditItem(request=request, childid=block_id, parentid=district_id, childname=block_name, storedprocadd="UpdateBlockById" )
# self.isSuccess = block.isSuccess
# self.resultMessage = block.resultMessage
# return
def EditBlock(self, request, block_id):
block = ItemCRUD(itemType=ItemCRUDType.Block)
@@ -149,9 +88,8 @@ class Block:
self.resultMessage = block.resultMessage
return
# ----------------------------------------------------------
# Delete Block
# ---------------------------------------------------------
# Delete Block
def DeleteBlock(self,request, id):
block = ItemCRUD(itemType=ItemCRUDType.Block)

View File

@@ -1,10 +1,5 @@
from mysql.connector import Error
import config
from datetime import datetime
class ContractorInfo:
def __init__(self, contractor_id):

View File

@@ -1,12 +1,11 @@
import os
from flask import current_app
# -----------------------------
# BASE FOLDER Class
# -----------------------------
class FolderAndFile:
# -----------------------------
# BASE FOLDER METHODS
# -----------------------------
@staticmethod
def get_download_folder():
folder = os.path.join(current_app.root_path, "static", "downloads")

View File

@@ -10,7 +10,7 @@ class GST:
invoices_rows = invoice_crud.GetAllData(storedproc="GetAllInvoicesBasic")
if not invoice_crud.isSuccess:
return [] # Could also log invoice_crud.resultMessage
return []
invoices = [
dict(
@@ -25,16 +25,16 @@ class GST:
gst_rows = gst_crud.GetAllData(storedproc="GetAllGSTReleasesBasic")
if not gst_crud.isSuccess:
return [] # Could also log gst_crud.resultMessage
return []
gst_invoice_nos = {
g[2] # Invoice_No is at index 2
g[2]
for g in gst_rows
if g[2]
}
gst_basic_amounts = {
float(g[3]) # Basic_Amount at index 3
float(g[3])
for g in gst_rows
if g[3] is not None
}

View File

@@ -3,7 +3,6 @@ from model.ItemCRUD import ItemCRUD
from model.Utilities import ItemCRUDType
class HoldTypes:
"""CRUD operations for Hold Types using ItemCRUD"""
def __init__(self):
self.isSuccess = False
@@ -33,7 +32,7 @@ class HoldTypes:
self.isSuccess = hold.isSuccess
self.resultMessage = hold.resultMessage
# Convert tuple → dictionary
# Convert tuple → dictionary
data = []
for row in rows:
data.append({
@@ -51,7 +50,7 @@ class HoldTypes:
self.isSuccess = hold.isSuccess
self.resultMessage = hold.resultMessage
# Convert tuple → dictionary
# Convert tuple → dictionary
if row:
return {
"hold_type_id": row[0],

View File

@@ -1,6 +1,4 @@
import config
import mysql.connector
# ------------------- Helper Functions -------------------
def clear_results(cursor):
@@ -78,25 +76,15 @@ def insert_invoice(data, village_id):
data.get('invoice_details'),
data.get('invoice_date'),
data.get('invoice_no'),
*get_numeric_values(data)
*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')
# 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 execute_db_operation(operation)
@@ -141,18 +129,6 @@ def update_invoice(data, invoice_id):
clear_results(cursor)
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 operation(cursor):
@@ -164,18 +140,11 @@ def delete_invoice_data(invoice_id, user_id):
if not record:
raise Exception("Invoice not found")
# Use exact DB keys
pmc_no = record['PMC_No']
invoice_no = record['Invoice_No']
# Delete invoice
cursor.callproc("DeleteInvoice", (invoice_id,))
clear_results(cursor)
# Delete inpayment
cursor.callproc('DeleteInpaymentByPMCInvoice', (pmc_no, invoice_no))
clear_results(cursor)
execute_db_operation(operation)

View File

@@ -232,14 +232,13 @@ class ItemCRUD:
if self.itemCRUDType.name == "GSTRelease" and data:
cursor.callproc(storedprocupdate, (
childid,
data['PMC_No'],
data['Invoice_No'],
data['Basic_Amount'],
data['Final_Amount'],
data['Total_Amount'],
data['UTR'],
data['Contractor_ID']
data['p_pmc_no'], # PMC_No
data['p_invoice_no'], # Invoice_No
data['p_basic_amount'], # Basic_Amount
data['p_final_amount'], # Final_Amount
data['p_total_amount'], # Total_Amount
data['p_utr'], # UTR
data['p_gst_release_id']# GST_Release_Id
))
connection.commit()

View File

@@ -1,5 +1,4 @@
import os
from flask import current_app
from flask_login import LoginManager, UserMixin, login_user, logout_user, login_required, current_user
from datetime import datetime

View File

@@ -1,5 +1,5 @@
import openpyxl
from openpyxl.styles import Font, PatternFill
from openpyxl.styles import Font
import config
from flask_login import current_user
from model.Log import LogHelper
@@ -11,14 +11,10 @@ class PmcReport:
@staticmethod
def get_pmc_report(pmc_no):
connection = config.get_db_connection()
cursor = connection.cursor(dictionary=True, buffered=True)
try:
# cursor.callproc("GetContractorInfoByPmcNo", (pmc_no,))
# pmc_info = next(cursor.stored_results()).fetchone()
pmc_info = ReportHelper.execute_sp(cursor, 'GetContractorInfoByPmcNo', [pmc_no], True)
if not pmc_info:
@@ -51,44 +47,20 @@ class PmcReport:
total_invo_final = sum(row.get('Final_Amount', 0) or 0 for row in invoices)
# GST RELEASE
# cursor.callproc('GetGSTReleaseByPMC', [pmc_no])
# gst_rel = []
# for result in cursor.stored_results():
# gst_rel = result.fetchall()
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_final = sum(row.get('final_amount', 0) or 0 for row in gst_rel)
# ---------------- HOLD RELEASE ----------------
# cursor.callproc('GetHoldReleaseByPMC', [pmc_no])
# hold_release = []
# for result in cursor.stored_results():
# hold_release = result.fetchall()
hold_release = ReportHelper.execute_sp(cursor, 'GetHoldReleaseByPMC', [pmc_no])
# ---------------- CREDIT NOTE ----------------
# cursor.callproc('GetCreditNoteByPMC', [pmc_no])
# credit_note = []
# for result in cursor.stored_results():
# credit_note = result.fetchall()
credit_note = ReportHelper.execute_sp(cursor, 'GetCreditNoteByPMC', [pmc_no])
payments = ReportHelper.execute_sp(cursor, 'GetPaymentsByPMC', [pmc_no])
# ---------------- PAYMENTS ----------------
# cursor.callproc('GetPaymentsByPMC', [pmc_no])
# payments = []
# for result in cursor.stored_results():
# payments = result.fetchall()
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_total = sum(row.get('Total_amount', 0) or 0 for row in payments)
@@ -137,51 +109,51 @@ class PmcReport:
return None
cursor = connection.cursor(dictionary=True)
try:
# filename
filename = f"PMC_Report_{pmc_no}.xlsx"
output_folder = FolderAndFile.get_download_folder()
output_file = FolderAndFile.get_download_path(filename)
# ================= DATA FETCH =================
# ================= DATA FETCH =============
contractor_info = ReportHelper.execute_sp(cursor, 'GetContractorDetailsByPMC', [pmc_no])
contractor_info = ReportHelper.execute_sp(cursor, 'GetContractorDetailsByPMC', [pmc_no], "one")
contractor_info = contractor_info[0] if contractor_info else None
if not contractor_info:
return None
hold_types = ReportHelper.execute_sp(cursor, 'GetHoldTypesByContractor', [contractor_info["Contractor_Id"]])
hold_types = ReportHelper.execute_sp(cursor, 'GetHoldTypesByContractor',[contractor_info["Contractor_Id"]])
hold_type_map = {ht['hold_type_id']: ht['hold_type'] for ht in hold_types}
invoices = ReportHelper.execute_sp(cursor, 'GetInvoicesAndGstReleaseByPmcNo', [pmc_no])
credit_notes = ReportHelper.execute_sp(cursor, 'GetCreditNoteByContractor', [contractor_info["Contractor_Id"]])
credit_notes = ReportHelper.execute_sp(cursor, 'NewGetCreditNotesByPMCNo', [pmc_no])
hold_amounts = ReportHelper.execute_sp(cursor, 'GetHoldAmountsByContractor', [contractor_info["Contractor_Id"]])
all_payments = ReportHelper.execute_sp(cursor, 'GetAllPaymentsByPMC', [pmc_no])
hold_amounts = ReportHelper.execute_sp(cursor, 'GetHoldAmountsByContractor',[contractor_info["Contractor_Id"]])
gst_releases = ReportHelper.execute_sp(cursor, 'GetGSTReleaseDetailsByPMC', [pmc_no])
# ================= DATA MAPPING =================
hold_data = {}
for h in hold_amounts:
hold_data.setdefault(h['Invoice_Id'], {})[h['hold_type_id']] = h['hold_amount']
payments_map = {}
for pay in all_payments:
if pay['invoice_no']:
payments_map.setdefault(pay['invoice_no'], []).append(pay)
credit_note_map = {}
for cn in credit_notes:
pmc = cn.get("PMC_No")
if pmc:
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}'"
)
LogHelper.log_action("Download PMC Report",f"User {current_user.id} Download PMC Report '{pmc_no}'")
# ================= EXCEL =================
workbook = openpyxl.Workbook()
@@ -197,83 +169,101 @@ class PmcReport:
sheet.append([])
base_headers = [
"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"
"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]
payment_headers = ["Final Amount", "Payment Amount", "TDS Payment", "Total Paid", "UTR"]
payment_headers = [
"Final Amount","Payment Amount","TDS Payment","Total Paid","UTR"
]
headers = base_headers + hold_headers + payment_headers
headers = base_headers + hold_headers + payment_headers
sheet.append(headers)
# STYLE
for cell in sheet[sheet.max_row]:
cell.font = Font(bold=True)
# DATA
seen_invoices = set()
# ================= INVOICE ROWS =================
for inv in invoices:
invoice_no = inv["Invoice_No"]
payments = payments_map.get(invoice_no, [])
if invoice_no in seen_invoices:
continue
seen_invoices.add(invoice_no)
first_payment = payments[0] if payments else None
row = [
pmc_no,
inv["Village_Name"],
inv["Work_Type"],
inv["Invoice_Details"],
inv["Invoice_Date"],
invoice_no,
inv["Basic_Amount"],
inv["Debit_Amount"],
inv["After_Debit_Amount"],
inv["GST_Amount"],
inv["Amount"],
inv["TDS_Amount"],
inv["SD_Amount"],
inv["On_Commission"],
inv["Hydro_Testing"],
inv["GST_SD_Amount"]
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["Invoice_Id"], {})
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["Final_Amount"],
first_payment["Payment_Amount"] if first_payment else "",
first_payment["TDS_Payment_Amount"] if first_payment else "",
first_payment["Total_amount"] if first_payment else "",
first_payment["UTR"] if first_payment else ""
inv.get("Final_Amount", ""),
inv.get("Payment_Amount", ""),
inv.get("TDS_Payment_Amount", ""),
inv.get("Total_Amount", ""),
inv.get("UTR", "")
]
sheet.append(row)
row += ["", ""]
# AUTO WIDTH
sheet.append(row)
# ================= CREDIT NOTE ROWS =================
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
# SAVE
workbook.save(output_file)
workbook.close()
return output_folder, filename
except Exception as e:
@@ -283,174 +273,3 @@ class PmcReport:
finally:
cursor.close()
connection.close()
# @staticmethod
# def download_pmc_report(pmc_no):
# connection = config.get_db_connection()
# cursor = connection.cursor(dictionary=True)
# # output_folder = "static/download"
# # output_file = os.path.join(output_folder, f"PMC_Report_{pmc_no}.xlsx")
# output_folder = FolderAndFile.get_download_folder
# filename = f"PMC_Report_{pmc_no}.xlsx"
# output_file = FolderAndFile.get_download_path(filename)
# try:
# cursor.callproc('GetContractorDetailsByPMC', [pmc_no])
# contractor_info = next(cursor.stored_results()).fetchone()
# if not contractor_info:
# return None
# cursor.callproc('GetHoldTypesByContractor', [contractor_info["Contractor_Id"]])
# hold_types = next(cursor.stored_results()).fetchall()
# hold_type_map = {ht['hold_type_id']: ht['hold_type'] for ht in hold_types}
# cursor.callproc('GetInvoicesAndGstReleaseByPmcNo', [pmc_no])
# invoices = next(cursor.stored_results()).fetchall()
# cursor.callproc('GetCreditNoteByContractor',[contractor_info["Contractor_Id"]])
# credit_notes = []
# for result in cursor.stored_results():
# credit_notes = result.fetchall()
# credit_note_map = {}
# for cn in credit_notes:
# key = (cn["PMC_No"], cn["Invoice_No"])
# credit_note_map.setdefault(key, []).append(cn)
# cursor.callproc('GetHoldAmountsByContractor', [contractor_info["Contractor_Id"]])
# hold_amounts = next(cursor.stored_results()).fetchall()
# hold_data = {}
# for h in hold_amounts:
# hold_data.setdefault(h['Invoice_Id'], {})[h['hold_type_id']] = h['hold_amount']
# cursor.callproc('GetAllPaymentsByPMC', [pmc_no])
# all_payments = next(cursor.stored_results()).fetchall()
# payments_map = {}
# extra_payments = []
# for pay in all_payments:
# if pay['invoice_no']:
# payments_map.setdefault(pay['invoice_no'], []).append(pay)
# else:
# extra_payments.append(pay)
# # ---------------- GST RELEASE DETAILS ----------------
# cursor.callproc('GetGSTReleaseDetailsByPMC', [pmc_no])
# gst_releases = []
# for result in cursor.stored_results():
# gst_releases = result.fetchall()
# gst_release_map = {}
# for gr in gst_releases:
# invoice_nos = []
# if gr['Invoice_No']:
# cleaned = gr['Invoice_No'].replace(' ', '')
# if '&' in cleaned:
# invoice_nos = cleaned.split('&')
# elif ',' in cleaned:
# invoice_nos = cleaned.split(',')
# else:
# invoice_nos = [cleaned]
# for inv_no in invoice_nos:
# gst_release_map.setdefault(inv_no, []).append(gr)
# LogHelper.log_action(
# "Download PMC Report",
# f"User {current_user.id} Download PMC Report '{pmc_no}'"
# )
# workbook = openpyxl.Workbook()
# sheet = workbook.active
# sheet.title = "PMC Report"
# sheet.append(["", "", "Laxmi Civil Engineering Services PVT. LTD."])
# sheet.append(["Contractor Name", contractor_info["Contractor_Name"], "", "GST No", contractor_info["GST_No"], "", "GST Type", contractor_info["GST_Registration_Type"]])
# sheet.append(["State", contractor_info["State_Name"], "", "PAN No", contractor_info["PAN_No"], "", "Address", contractor_info["Address"]])
# sheet.append(["District", contractor_info["District_Name"], "", "Mobile No", contractor_info["Mobile_No"]])
# sheet.append(["Block", contractor_info["Block_Name"], "", "Email", contractor_info["Email"]])
# sheet.append([])
# 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"
# ]
# sheet.append(base_headers + hold_headers + payment_headers)
# header_fill = PatternFill(start_color="ADD8E6",end_color="ADD8E6",fill_type="solid")
# header_font = Font(bold=True)
# for cell in sheet[sheet.max_row]:
# cell.font = header_font
# cell.fill = header_fill
# seen_invoices = set()
# processed_payments = set()
# for inv in invoices:
# invoice_no = inv["Invoice_No"]
# payments = payments_map.get(invoice_no, [])
# if invoice_no not in seen_invoices:
# seen_invoices.add(invoice_no)
# first_payment = payments[0] if payments else None
# row = [
# pmc_no, inv["Village_Name"], inv["Work_Type"],
# inv["Invoice_Details"], inv["Invoice_Date"], invoice_no,
# inv["Basic_Amount"], inv["Debit_Amount"],
# inv["After_Debit_Amount"], inv["GST_Amount"],
# inv["Amount"], inv["TDS_Amount"], inv["SD_Amount"],
# inv["On_Commission"], inv["Hydro_Testing"], inv["GST_SD_Amount"]
# ]
# invoice_holds = hold_data.get(inv["Invoice_Id"], {})
# for ht_id in hold_type_map.keys():
# row.append(invoice_holds.get(ht_id, ""))
# row += [
# inv["Final_Amount"],
# first_payment["Payment_Amount"] if first_payment else "",
# first_payment["TDS_Payment_Amount"] if first_payment else "",
# first_payment["Total_amount"] if first_payment else "",
# first_payment["UTR"] if first_payment else ""
# ]
# sheet.append(row)
# workbook.save(output_file)
# workbook.close()
# return output_folder, filename
# finally:
# cursor.close()
# connection.close()

View File

@@ -1,8 +1,9 @@
import config
from datetime import datetime
from flask import send_file
import os
import openpyxl
from openpyxl.styles import Font
from openpyxl.styles import Font, PatternFill
from model.FolderAndFile import FolderAndFile
@@ -147,129 +148,199 @@ class ReportHelper:
"current_date": current_date
}
@staticmethod
def download_report(contractor_id):
try:
connection = config.get_db_connection()
cursor = connection.cursor(dictionary=True)
def get_contractor_info(contractor_id):
from model.ContractorInfo import ContractorInfo
contractor = ContractorInfo(contractor_id)
return contractor.contInfo if contractor.contInfo else None
# -------- Contractor Info --------
contInfo = ReportHelper.execute_sp(cursor, 'GetContractorInfo', [contractor_id], True)
if not contInfo:
return "No contractor found", 404
@staticmethod
def generate_excel(contractor_id, contInfo, invoices, hold_types, hold_data,
credit_note_map, gst_release_map, output_file):
# -------- Invoice Data --------
cursor.callproc('FetchInvoicesByContractor', [contractor_id])
workbook = openpyxl.Workbook()
sheet = workbook.active
sheet.title = "Contractor Report"
invoices = []
for result in cursor.stored_results():
invoices.extend(result.fetchall())
# Contractor Info
for field, value in contInfo.items():
sheet.append([field.replace("_", " "), value])
sheet.append([])
if not invoices:
return "No invoice data found"
# 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"]
# -------- Create Workbook --------
workbook = openpyxl.Workbook()
sheet = workbook.active
sheet.title = "Contractor Report"
hold_headers = [ht['hold_type'] for ht in hold_types]
# ================= CONTRACTOR DETAILS =================
sheet.append(["SUB CONTRACTOR DETAILS"])
sheet.cell(row=sheet.max_row, column=1).font = Font(bold=True)
sheet.append([])
payment_headers = ["Final Amount", "Payment Amount", "TDS Payment", "Total Paid", "UTR"]
sheet.append(["Name", contInfo.get("Contractor_Name") or ""])
sheet.append(["Mobile No", contInfo.get("Mobile_No") or ""])
sheet.append(["Email", contInfo.get("Email") or ""])
sheet.append(["Village", contInfo.get("Village_Name") or ""])
sheet.append(["Block", contInfo.get("Block_Name") or ""])
sheet.append(["District", contInfo.get("District_Name") or ""])
sheet.append(["State", contInfo.get("State_Name") or ""])
sheet.append(["Address", contInfo.get("Address") or ""])
sheet.append(["GST No", contInfo.get("GST_No") or ""])
sheet.append(["PAN No", contInfo.get("PAN_No") or ""])
sheet.append([])
sheet.append([])
all_headers = base_headers + hold_headers + payment_headers
sheet.append(all_headers)
# ================= TABLE HEADERS =================
headers = [
"PMC No", "Village", "Invoice No", "Invoice Date", "Work Type","Invoice_Details",
"Basic Amount", "Debit Amount", "After Debit Amount",
"Amount", "GST Amount", "TDS Amount", "SD Amount",
"On Commission", "Hydro Testing", "Hold Amount",
"GST SD Amount", "Final Amount",
"Payment Amount", "TDS Payment",
"Total Amount", "UTR"
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", "")
]
sheet.append(headers)
for col in range(1, len(headers) + 1):
sheet.cell(row=sheet.max_row, column=col).font = Font(bold=True)
# ================= DATA =================
total_final = 0
total_payment = 0
total_amount = 0
# 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, ""))
for inv in invoices:
row = [
inv.get("PMC_No"),
inv.get("Village_Name"),
inv.get("invoice_no"),
inv.get("Invoice_Date"),
inv.get("Work_Type"),
inv.get("Invoice_Details"),
inv.get("Basic_Amount"),
inv.get("Debit_Amount"),
inv.get("After_Debit_Amount"),
inv.get("Amount"),
inv.get("GST_Amount"),
inv.get("TDS_Amount"),
inv.get("SD_Amount"),
inv.get("On_Commission"),
inv.get("Hydro_Testing"),
inv.get("Hold_Amount"),
inv.get("GST_SD_Amount"),
inv.get("Final_Amount"),
inv.get("Payment_Amount"),
inv.get("TDS_Payment_Amount"),
inv.get("Total_Amount"),
inv.get("UTR")
]
# Payment values
row += [
inv.get("Final_Amount", ""),
inv.get("Payment_Amount", ""),
inv.get("TDS_Payment_Amount", ""),
inv.get("Total_Amount", ""),
inv.get("UTR", "")
]
total_final += float(inv.get("Final_Amount") or 0)
total_payment += float(inv.get("Payment_Amount") or 0)
total_amount += float(inv.get("Total_Amount") or 0)
sheet.append(row)
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", ""), "", "", "", "", "", "", "", "", ""
]
# ================= TOTAL ROW =================
sheet.append([])
sheet.append([
"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
"TOTAL",
total_final,
total_payment,
"",
total_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):
fileName = f"Contractor_Report_{contractor_id}.xlsx"
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, 'FetchInvoicesByContractor', [contractor_id])
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']
# -------- 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()
)
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()
)
gst_release_map.setdefault(key, []).append(gr)
# Generate Excel
ReportHelper.generate_excel(
contractor_id, contInfo, invoices, hold_types, hold_data,
credit_note_map, gst_release_map, output_file
)
return output_file, None
# ================= AUTO WIDTH =================
for column in sheet.columns:
max_length = 0
column_letter = column[0].column_letter
for cell in column:
if cell.value:
max_length = max(max_length, len(str(cell.value)))
sheet.column_dimensions[column_letter].width = max_length + 2
# ================= SAVE FILE =================
filename = f"Contractor_Report_{contInfo.get('Contractor_Name')}.xlsx"
output_file = FolderAndFile.get_download_path(filename)
workbook.save(output_file)
return send_file(output_file, as_attachment=True)
except Exception as e:
return str(e)

View File

@@ -1,7 +1,6 @@
from model.Utilities import ItemCRUDType
from model.ItemCRUD import ItemCRUD
class Subcontractor:
def __init__(self):
self.isSuccess = False

View File

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

View File

@@ -8,12 +8,18 @@ class GSTRelease:
def __init__(self):
self.isSuccess = False
self.resultMessage = ""
# ------------------- Add GST Release -------------------
def AddGSTRelease(self, request):
try:
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 = {
"PMC_No": request.form.get("PMC_No", "").strip(),
"Invoice_No": request.form.get("Invoice_No", "").strip(),
@@ -24,6 +30,10 @@ class GSTRelease:
"Contractor_ID": int(request.form.get("Contractor_ID", 0) or 0)
}
print("===== DEBUG: PARSED DATA =====")
print(data)
print("==============================")
# Add GST Release
gst.AddItem(
request=request,
@@ -31,12 +41,8 @@ class GSTRelease:
storedprocfetch="CheckGSTReleaseExists",
storedprocadd="AddGSTReleaseFromExcel"
)
# Check if addition was successful
if gst.isSuccess:
print(f"GST Release Added: {data}")
else:
print(f"Failed to add GST Release: {gst.resultMessage}")
print(f"AddItem result: isSuccess={gst.isSuccess}, message={gst.resultMessage}")
self.isSuccess = gst.isSuccess
self.resultMessage = str(gst.resultMessage)
@@ -48,20 +54,26 @@ class GSTRelease:
return jsonify({"success": self.isSuccess, "message": self.resultMessage})
# ------------------- Edit GST Release -------------------
def EditGSTRelease(self, request, gst_release_id):
try:
gst = ItemCRUD(itemType=ItemCRUDType.GSTRelease)
# Map form inputs to stored procedure parameters
data = {
"PMC_No": request.form.get("PMC_No", "").strip(),
"Invoice_No": request.form.get("Invoice_No", "").strip(),
"Basic_Amount": float(request.form.get("Basic_Amount", 0) or 0),
"Final_Amount": float(request.form.get("Final_Amount", 0) or 0),
"Total_Amount": float(request.form.get("Total_Amount", 0) or 0),
"UTR": request.form.get("UTR", "").strip()
"p_pmc_no": request.form.get("PMC_No", "").strip(),
"p_invoice_no": request.form.get("invoice_no", "").strip(),
"p_basic_amount": float(request.form.get("Basic_Amount", 0) or 0),
"p_final_amount": float(request.form.get("Final_Amount", 0) or 0),
"p_total_amount": float(request.form.get("Total_Amount", 0) or 0),
"p_utr": request.form.get("UTR", "").strip(),
"p_gst_release_id": gst_release_id
}
print("===== DEBUG: UPDATE DATA =====")
print(data)
print("==============================")
# Call your stored procedure
gst.EditItem(
request=request,
childid=gst_release_id,
@@ -77,8 +89,6 @@ class GSTRelease:
self.isSuccess = False
self.resultMessage = str(e)
return jsonify({"success": self.isSuccess, "message": self.resultMessage})
# ------------------- Delete GST Release -------------------
def DeleteGSTRelease(self, gst_release_id):
try:

View File

@@ -2,7 +2,6 @@ import config
import mysql.connector
import config
import mysql.connector
from enum import Enum
from model.Utilities import ItemCRUDType
class Paymentmodel:
@@ -34,40 +33,44 @@ class Paymentmodel:
return payments
@staticmethod
def insert_payment(pmc_no, invoice_no, amount, tds_amount, total_amount, utr):
def insert_payment(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('InsertPayments', [pmc_no, invoice_no, amount, tds_amount, total_amount, utr])
connection.commit()
return True
except mysql.connector.Error as e:
print(f"Error inserting payment: {e}")
return False
finally:
cursor.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
cursor = None
try:
cursor = connection.cursor()
cursor.callproc('UpdateInpaymentRecord', [
subcontractor_id, pmc_no, invoice_no, amount, tds_amount, total_amount, utr
])
cursor.callproc('GetInvoiceId', [subcontractor_id, pmc_no, invoice_no])
invoice_id = None
for result in cursor.stored_results():
row = result.fetchone()
if row:
invoice_id = row[0]
if not invoice_id:
return False
cursor.callproc(
'InsertPayments',
[pmc_no, invoice_no, amount, tds_amount, total_amount, utr, invoice_id]
)
connection.commit()
return True
except mysql.connector.Error as e:
print(f"Error updating inpayment: {e}")
except Exception as e:
print(e)
return False
finally:
cursor.close()
connection.close()
if cursor:
cursor.close()
if connection:
connection.close()
@staticmethod
def fetch_payment_by_id(payment_id):
@@ -133,9 +136,7 @@ class Paymentmodel:
# Delete payment
cursor.callproc("DeletePayment", (payment_id,))
connection.commit()
# Reset inpayment fields
cursor.callproc("ResetInpayment", [pmc_no, invoice_no])
connection.commit()
return True, pmc_no, invoice_no
except mysql.connector.Error as e:
print(f"Error deleting payment: {e}")