From aad9b2b9670a2ba4549fec4c8818a50859726e1b Mon Sep 17 00:00:00 2001 From: pjpatil12 Date: Thu, 15 Jan 2026 12:27:29 +0530 Subject: [PATCH] import modify subcontractor sheet Laying model import added --- app/models/laying_model.py | 47 +++++++++++++++++++++++++ app/services/file_service.py | 67 +++++++++++++++++++++++++++++++++++- 2 files changed, 113 insertions(+), 1 deletion(-) create mode 100644 app/models/laying_model.py diff --git a/app/models/laying_model.py b/app/models/laying_model.py new file mode 100644 index 0000000..e43a1f1 --- /dev/null +++ b/app/models/laying_model.py @@ -0,0 +1,47 @@ +from app import db +from datetime import datetime + +class Laying(db.Model): + __tablename__ = "laying" + + id = db.Column(db.Integer, primary_key=True) + # Foreign Key to Subcontractor table + subcontractor_id = db.Column(db.Integer, db.ForeignKey("subcontractors.id"), nullable=False) + # Relationship for easy access (subcontractor.subcontractor_name) + subcontractor = db.relationship("Subcontractor", backref="laying_records") + + # Basic Fields + Location = db.Column(db.String(500)) + MH_NO = db.Column(db.String(100)) + CC_length = db.Column(db.Float) + + Pipe_Dia_mm = db.Column(db.Float) + ID_of_MH_m = db.Column(db.Float) + Laying_Length = db.Column(db.Float) + + pipe_150_mm = db.Column(db.Float) + pipe_200_mm = db.Column(db.Float) + pipe_250_mm = db.Column(db.Float) + pipe_300_mm = db.Column(db.Float) + pipe_350_mm = db.Column(db.Float) + pipe_400_mm = db.Column(db.Float) + pipe_450_mm = db.Column(db.Float) + pipe_500_mm = db.Column(db.Float) + pipe_600_mm = db.Column(db.Float) + pipe_700_mm = db.Column(db.Float) + pipe_900_mm = db.Column(db.Float) + pipe_1200_mm = db.Column(db.Float) + + + Total = db.Column(db.Float) + Remarks = db.Column(db.String(500)) + RA_Bill_No=db.Column(db.String(500)) + + created_at = db.Column(db.DateTime, default=datetime.today) + + + def __repr__(self): + return f"" + + def serialize(self): + return {c.name: getattr(self, c.name) for c in self.__table__.columns} diff --git a/app/services/file_service.py b/app/services/file_service.py index 82d3819..cbb07f3 100644 --- a/app/services/file_service.py +++ b/app/services/file_service.py @@ -1,19 +1,22 @@ import os import pandas as pd from werkzeug.utils import secure_filename +from app.utils.file_utils import ensure_upload_folder from app.config import Config from app import db +# Subcontractor models import from app.models.trench_excavation_model import TrenchExcavation from app.models.manhole_excavation_model import ManholeExcavation from app.models.manhole_domestic_chamber_model import ManholeDomesticChamber +from app.models.laying_model import Laying +# Client models import from app.models.tr_ex_client_model import TrenchExcavationClient from app.models.mh_ex_client_model import ManholeExcavationClient from app.models.mh_dc_client_model import ManholeDomesticChamberClient -from app.utils.file_utils import ensure_upload_folder class FileService: @@ -60,10 +63,12 @@ class FileService: df_tr_ex = pd.read_excel(filepath, sheet_name="Tr.Ex.", header=12, dtype={"MH No": str}) df_mh_ex = pd.read_excel(filepath, sheet_name="MH Ex.", header=12, dtype={"MH No": str}) df_mh_dc = pd.read_excel(filepath, sheet_name="MH & DC", header=11, dtype={"MH No": str}) + df_laying = pd.read_excel(filepath, sheet_name="Laying", header=11, dtype={"MH No": str}) self.process_trench_excavation(df_tr_ex, subcontractor_id, RA_Bill_No) self.process_manhole_excavation(df_mh_ex, subcontractor_id, RA_Bill_No) self.process_manhole_domestic_chamber(df_mh_dc, subcontractor_id, RA_Bill_No) + self.process_laying(df_laying, subcontractor_id, RA_Bill_No) return True, "SUBCONTRACTOR File uploaded successfully." @@ -245,6 +250,66 @@ class FileService: db.session.commit() + # ---------------- Laying (Subcontractor) ---------------- + def process_laying(self, df, subcontractor_id, RA_Bill_No): + + df.columns = ( + df.columns.astype(str) + .str.strip() + .str.replace(r"[^\w]", "_", regex=True) + .str.replace("__+", "_", regex=True) + .str.strip("_") + ) + + df = df.dropna(how="all") + + if "Location" in df.columns: + df["Location"] = df["Location"].ffill() + + errors = [] + + for idx, row in df.iterrows(): + location = self.normalize(row.get("Location")) + mh_no = self.normalize(row.get("MH_NO")) + + if not location or not mh_no: + continue + + # exists = ManholeDomesticChamber.query.filter_by( + # subcontractor_id=subcontractor_id, + # RA_Bill_No=RA_Bill_No, + # Location=location, + # MH_NO=mh_no, + # ).first() + + # if exists: + # errors.append( + # f"Model-MH & DC (Row {idx+1}): Duplicate → Location={location}, MH_NO={mh_no}" + # ) + # continue + + record_data = {} + for col in df.columns: + if hasattr(Laying, col): + val = row[col] + if pd.isna(val) or str(val).strip() in ["", "-", "—", "nan"]: + val = None + record_data[col] = val + + record = Laying( + subcontractor_id=subcontractor_id, + RA_Bill_No=RA_Bill_No, + **record_data, + ) + db.session.add(record) + + if errors: + raise Exception(" | ".join(errors)) + + db.session.commit() + + + # ---------------- CLIENT FILE UPLOAD ---------------- def handle_client_file_upload(self, file, RA_Bill_No):