Refactored universign message function
This commit is contained in:
parent
2705de7a07
commit
dbdfa1e2df
1 changed files with 123 additions and 19 deletions
142
api.py
142
api.py
|
|
@ -1420,7 +1420,7 @@ async def universign_envoyer_avec_email(
|
||||||
pdf_bytes: bytes,
|
pdf_bytes: bytes,
|
||||||
email: str,
|
email: str,
|
||||||
nom: str,
|
nom: str,
|
||||||
doc_data: Dict, # Données du document (type, montant, date, etc.)
|
doc_data: Dict,
|
||||||
session: AsyncSession,
|
session: AsyncSession,
|
||||||
) -> Dict:
|
) -> Dict:
|
||||||
import requests
|
import requests
|
||||||
|
|
@ -1430,19 +1430,35 @@ async def universign_envoyer_avec_email(
|
||||||
api_url = settings.universign_api_url
|
api_url = settings.universign_api_url
|
||||||
auth = (api_key, "")
|
auth = (api_key, "")
|
||||||
|
|
||||||
|
# ========================================
|
||||||
|
# ÉTAPE 1 : Créer la transaction
|
||||||
|
# ========================================
|
||||||
|
logger.info(f"🔐 Création transaction Universign pour {email}")
|
||||||
|
|
||||||
response = requests.post(
|
response = requests.post(
|
||||||
f"{api_url}/transactions",
|
f"{api_url}/transactions",
|
||||||
auth=auth,
|
auth=auth,
|
||||||
json={
|
json={
|
||||||
"name": f"{doc_data.get('type_label', 'Document')} {doc_id}",
|
"name": f"{doc_data.get('type_label', 'Document')} {doc_id}",
|
||||||
"language": "fr",
|
"language": "fr",
|
||||||
|
"profile": "default", # ✅ Ajout du profil
|
||||||
},
|
},
|
||||||
timeout=30,
|
timeout=30,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if response.status_code != 200:
|
||||||
|
logger.error(f"❌ Erreur création transaction: {response.status_code} - {response.text}")
|
||||||
|
raise Exception(f"Erreur création transaction: {response.status_code}")
|
||||||
|
|
||||||
response.raise_for_status()
|
response.raise_for_status()
|
||||||
transaction_id = response.json().get("id")
|
transaction_id = response.json().get("id")
|
||||||
|
|
||||||
logger.info(f"✅ Transaction Universign créée: {transaction_id}")
|
logger.info(f"✅ Transaction créée: {transaction_id}")
|
||||||
|
|
||||||
|
# ========================================
|
||||||
|
# ÉTAPE 2 : Upload du fichier PDF
|
||||||
|
# ========================================
|
||||||
|
logger.info(f"📄 Upload PDF ({len(pdf_bytes)} octets)")
|
||||||
|
|
||||||
files = {
|
files = {
|
||||||
"file": (
|
"file": (
|
||||||
|
|
@ -1451,56 +1467,138 @@ async def universign_envoyer_avec_email(
|
||||||
"application/pdf",
|
"application/pdf",
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
response = requests.post(f"{api_url}/files", auth=auth, files=files, timeout=30)
|
response = requests.post(
|
||||||
|
f"{api_url}/files",
|
||||||
|
auth=auth,
|
||||||
|
files=files,
|
||||||
|
timeout=30
|
||||||
|
)
|
||||||
|
|
||||||
|
if response.status_code != 200:
|
||||||
|
logger.error(f"❌ Erreur upload fichier: {response.status_code} - {response.text}")
|
||||||
|
raise Exception(f"Erreur upload fichier: {response.status_code}")
|
||||||
|
|
||||||
response.raise_for_status()
|
response.raise_for_status()
|
||||||
file_id = response.json().get("id")
|
file_id = response.json().get("id")
|
||||||
|
|
||||||
|
logger.info(f"✅ Fichier uploadé: {file_id}")
|
||||||
|
|
||||||
|
# ========================================
|
||||||
|
# ÉTAPE 3 : Créer le document dans la transaction
|
||||||
|
# ========================================
|
||||||
|
logger.info(f"📋 Ajout document à la transaction")
|
||||||
|
|
||||||
response = requests.post(
|
response = requests.post(
|
||||||
f"{api_url}/transactions/{transaction_id}/documents",
|
f"{api_url}/transactions/{transaction_id}/documents",
|
||||||
auth=auth,
|
auth=auth,
|
||||||
data={"document": file_id},
|
json={"file": file_id}, # ✅ Utiliser 'file' au lieu de 'document'
|
||||||
timeout=30,
|
timeout=30,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if response.status_code != 200:
|
||||||
|
logger.error(f"❌ Erreur ajout document: {response.status_code} - {response.text}")
|
||||||
|
raise Exception(f"Erreur ajout document: {response.status_code}")
|
||||||
|
|
||||||
response.raise_for_status()
|
response.raise_for_status()
|
||||||
document_id = response.json().get("id")
|
document_id = response.json().get("id")
|
||||||
|
|
||||||
|
logger.info(f"✅ Document ajouté: {document_id}")
|
||||||
|
|
||||||
|
# ========================================
|
||||||
|
# ÉTAPE 4 : Ajouter un champ de signature
|
||||||
|
# ========================================
|
||||||
|
logger.info(f"✍️ Ajout champ signature")
|
||||||
|
|
||||||
response = requests.post(
|
response = requests.post(
|
||||||
f"{api_url}/transactions/{transaction_id}/documents/{document_id}/fields",
|
f"{api_url}/transactions/{transaction_id}/documents/{document_id}/fields",
|
||||||
auth=auth,
|
auth=auth,
|
||||||
data={"type": "signature"},
|
json={
|
||||||
|
"type": "signature",
|
||||||
|
"page": 1, # ✅ Préciser la page
|
||||||
|
# Position optionnelle - Universign peut la placer automatiquement
|
||||||
|
# "x": 100,
|
||||||
|
# "y": 600,
|
||||||
|
},
|
||||||
timeout=30,
|
timeout=30,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if response.status_code != 200:
|
||||||
|
logger.error(f"❌ Erreur ajout champ: {response.status_code} - {response.text}")
|
||||||
|
raise Exception(f"Erreur ajout champ signature: {response.status_code}")
|
||||||
|
|
||||||
response.raise_for_status()
|
response.raise_for_status()
|
||||||
field_id = response.json().get("id")
|
field_id = response.json().get("id")
|
||||||
|
|
||||||
|
logger.info(f"✅ Champ signature créé: {field_id}")
|
||||||
|
|
||||||
|
# ========================================
|
||||||
|
# ÉTAPE 5 : Ajouter le signataire
|
||||||
|
# ========================================
|
||||||
|
logger.info(f"👤 Ajout signataire: {nom} ({email})")
|
||||||
|
|
||||||
response = requests.post(
|
response = requests.post(
|
||||||
f"{api_url}/transactions/{transaction_id}/signatures",
|
f"{api_url}/transactions/{transaction_id}/signers",
|
||||||
auth=auth,
|
auth=auth,
|
||||||
data={"signer": email, "field": field_id},
|
json={
|
||||||
|
"email": email,
|
||||||
|
"firstName": nom.split()[0] if ' ' in nom else nom, # ✅ Prénom
|
||||||
|
"lastName": nom.split()[-1] if ' ' in nom else "", # ✅ Nom
|
||||||
|
# ✅ Lier le signataire au champ de signature
|
||||||
|
"fields": [field_id],
|
||||||
|
},
|
||||||
timeout=30,
|
timeout=30,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if response.status_code != 200:
|
||||||
|
logger.error(f"❌ Erreur ajout signataire: {response.status_code} - {response.text}")
|
||||||
|
raise Exception(f"Erreur ajout signataire: {response.status_code}")
|
||||||
|
|
||||||
response.raise_for_status()
|
response.raise_for_status()
|
||||||
|
signer_id = response.json().get("id")
|
||||||
|
|
||||||
|
logger.info(f"✅ Signataire ajouté: {signer_id}")
|
||||||
|
|
||||||
|
# ========================================
|
||||||
|
# ÉTAPE 6 : Démarrer la transaction
|
||||||
|
# ========================================
|
||||||
|
logger.info(f"🚀 Démarrage de la transaction")
|
||||||
|
|
||||||
response = requests.post(
|
response = requests.post(
|
||||||
f"{api_url}/transactions/{transaction_id}/start", auth=auth, timeout=30
|
f"{api_url}/transactions/{transaction_id}/start",
|
||||||
|
auth=auth,
|
||||||
|
json={}, # ✅ Body vide mais présent
|
||||||
|
timeout=30
|
||||||
)
|
)
|
||||||
response.raise_for_status()
|
|
||||||
|
|
||||||
|
if response.status_code != 200:
|
||||||
|
logger.error(f"❌ Erreur démarrage transaction: {response.status_code}")
|
||||||
|
logger.error(f"Réponse complète: {response.text}")
|
||||||
|
raise Exception(f"Erreur démarrage transaction: {response.status_code} - {response.text}")
|
||||||
|
|
||||||
|
response.raise_for_status()
|
||||||
final_data = response.json()
|
final_data = response.json()
|
||||||
signer_url = (
|
|
||||||
final_data.get("actions", [{}])[0].get("url", "")
|
# ========================================
|
||||||
if final_data.get("actions")
|
# ÉTAPE 7 : Récupérer l'URL de signature
|
||||||
else ""
|
# ========================================
|
||||||
)
|
signer_url = ""
|
||||||
|
if final_data.get("signers"):
|
||||||
|
for signer in final_data["signers"]:
|
||||||
|
if signer.get("email") == email:
|
||||||
|
signer_url = signer.get("url", "")
|
||||||
|
break
|
||||||
|
|
||||||
if not signer_url:
|
if not signer_url:
|
||||||
|
logger.warning("⚠️ URL de signature non trouvée dans la réponse")
|
||||||
raise ValueError("URL de signature non retournée par Universign")
|
raise ValueError("URL de signature non retournée par Universign")
|
||||||
|
|
||||||
logger.info(f"✅ Signature Universign démarrée: {transaction_id}")
|
logger.info(f"✅ Signature Universign prête: {transaction_id}")
|
||||||
|
|
||||||
|
# ========================================
|
||||||
|
# ÉTAPE 8 : Créer l'email de notification
|
||||||
|
# ========================================
|
||||||
template = templates_signature_email["demande_signature"]
|
template = templates_signature_email["demande_signature"]
|
||||||
|
|
||||||
# Préparer les variables
|
|
||||||
type_labels = {
|
type_labels = {
|
||||||
0: "Devis",
|
0: "Devis",
|
||||||
10: "Commande",
|
10: "Commande",
|
||||||
|
|
@ -1519,7 +1617,6 @@ async def universign_envoyer_avec_email(
|
||||||
"CONTACT_EMAIL": settings.smtp_from,
|
"CONTACT_EMAIL": settings.smtp_from,
|
||||||
}
|
}
|
||||||
|
|
||||||
# Remplacer les variables dans le template
|
|
||||||
sujet = template["sujet"]
|
sujet = template["sujet"]
|
||||||
corps = template["corps_html"]
|
corps = template["corps_html"]
|
||||||
|
|
||||||
|
|
@ -1556,11 +1653,18 @@ async def universign_envoyer_avec_email(
|
||||||
"email_sent": True,
|
"email_sent": True,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
except requests.exceptions.HTTPError as e:
|
||||||
|
logger.error(f"❌ Erreur HTTP Universign: {e}")
|
||||||
|
logger.error(f"Réponse: {e.response.text if e.response else 'N/A'}")
|
||||||
|
return {
|
||||||
|
"error": f"Erreur Universign: {e.response.status_code} - {e.response.text if e.response else str(e)}",
|
||||||
|
"statut": "ERREUR",
|
||||||
|
"email_sent": False,
|
||||||
|
}
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"❌ Erreur Universign+Email: {e}")
|
logger.error(f"❌ Erreur Universign+Email: {e}", exc_info=True)
|
||||||
return {"error": str(e), "statut": "ERREUR", "email_sent": False}
|
return {"error": str(e), "statut": "ERREUR", "email_sent": False}
|
||||||
|
|
||||||
|
|
||||||
async def universign_statut(transaction_id: str) -> Dict:
|
async def universign_statut(transaction_id: str) -> Dict:
|
||||||
"""Récupération statut signature"""
|
"""Récupération statut signature"""
|
||||||
import requests
|
import requests
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue