Files
contractor/deploy/db/supplements.py
T

60 lines
2.1 KiB
Python

"""Supplements CRUD."""
from .connection import query, execute, execute_returning
def insert(contract_id, document_id, supp_type="additional"):
return execute_returning(
"""INSERT INTO supplements (contract_id, document_id, type)
VALUES (%s, %s, %s) RETURNING *""",
(contract_id, document_id, supp_type),
)
def list_by_contract(contract_id):
"""Supplements with parsed documents, ordered by created_at."""
return query(
"""SELECT s.id, s.type, s.document_id, d.filename
FROM supplements s
JOIN documents d ON s.document_id = d.id
WHERE s.contract_id = %s AND d.elements_json IS NOT NULL
ORDER BY s.created_at""",
(contract_id,),
)
def get(supp_id):
rows = query("SELECT * FROM supplements WHERE id = %s", (supp_id,))
return rows[0] if rows else None
def delete_by_document(contract_id, filename):
"""Delete ALL supplements+documents by contract+filename (cascade: spec_events first).
Handles duplicates from previously failed uploads."""
rows = query(
"""SELECT s.id as sid, s.document_id FROM supplements s
JOIN documents d ON d.id = s.document_id
WHERE s.contract_id = %s AND d.filename = %s""",
(contract_id, filename),
)
if not rows:
return False
for r in rows:
# 1. Delete spec_current rows referencing this supplement's events
execute(
"""DELETE FROM spec_current WHERE contract_id = %s
AND last_event_id IN (SELECT id FROM spec_events WHERE supplement_id = %s)""",
(contract_id, r["sid"]),
)
# 2. Delete spec_events referencing this supplement
execute("DELETE FROM spec_events WHERE supplement_id = %s", (r["sid"],))
# 3. Delete supplement
execute("DELETE FROM supplements WHERE id = %s", (r["sid"],))
# 4. Delete document
execute("DELETE FROM documents WHERE id = %s", (r["document_id"],))
return True
def delete(supp_id):
return execute("DELETE FROM supplements WHERE id = %s", (supp_id,))