comments.py 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546
  1. """Transactional comment writes shared by chat and follow-up editing."""
  2. from sqlalchemy import text
  3. def lock_comment_invoice(db, pkey):
  4. """Serialize comment writers before touching details or current flags."""
  5. row = db.execute(
  6. text("""
  7. SELECT Beleg_Nr FROM dbo.Forderungen_Kopf WITH (UPDLOCK, HOLDLOCK)
  8. WHERE Client_DB = :Client_DB AND Beleg_Nr = :Beleg_Nr
  9. """),
  10. pkey,
  11. ).first()
  12. if row is None:
  13. raise ValueError("Forderung nicht gefunden")
  14. def save_comment(db, pkey, *, username, timestamp, comment):
  15. """Write a comment and its current flags; the caller owns the transaction."""
  16. lock_comment_invoice(db, pkey)
  17. fibu = db.execute(
  18. text("""
  19. SELECT TOP 1 1 FROM dbo.Benutzer_Rolle
  20. WHERE Benutzer_ID = :Benutzer_ID AND Rolle_ID = 'FIBU'
  21. """),
  22. {"Benutzer_ID": username},
  23. ).first() is not None
  24. # The identifier comes exclusively from these two constants, never from input.
  25. column = "Aktuell_Fibu" if fibu else "Aktuell_Abteilung"
  26. db.execute(
  27. text(f"""
  28. UPDATE dbo.Forderungen_Kommentar SET {column} = 0
  29. WHERE Client_DB = :Client_DB AND Beleg_Nr = :Beleg_Nr
  30. """),
  31. pkey,
  32. )
  33. db.execute(
  34. text("""
  35. INSERT INTO dbo.Forderungen_Kommentar
  36. (Client_DB, Beleg_Nr, [Timestamp], Benutzer_ID, Kommentar, Aktuell_Fibu, Aktuell_Abteilung)
  37. VALUES (:Client_DB, :Beleg_Nr, :Timestamp, :Benutzer_ID, :Kommentar, :Aktuell_Fibu, :Aktuell_Abteilung)
  38. """),
  39. dict(pkey, Benutzer_ID=username, Timestamp=timestamp, Kommentar=comment,
  40. Aktuell_Fibu=int(fibu), Aktuell_Abteilung=int(not fibu)),
  41. )