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,
|
||||
email: str,
|
||||
nom: str,
|
||||
doc_data: Dict, # Données du document (type, montant, date, etc.)
|
||||
doc_data: Dict,
|
||||
session: AsyncSession,
|
||||
) -> Dict:
|
||||
import requests
|
||||
|
|
@ -1430,19 +1430,35 @@ async def universign_envoyer_avec_email(
|
|||
api_url = settings.universign_api_url
|
||||
auth = (api_key, "")
|
||||
|
||||
# ========================================
|
||||
# ÉTAPE 1 : Créer la transaction
|
||||
# ========================================
|
||||
logger.info(f"🔐 Création transaction Universign pour {email}")
|
||||
|
||||
response = requests.post(
|
||||
f"{api_url}/transactions",
|
||||
auth=auth,
|
||||
json={
|
||||
"name": f"{doc_data.get('type_label', 'Document')} {doc_id}",
|
||||
"language": "fr",
|
||||
"profile": "default", # ✅ Ajout du profil
|
||||
},
|
||||
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()
|
||||
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 = {
|
||||
"file": (
|
||||
|
|
@ -1451,56 +1467,138 @@ async def universign_envoyer_avec_email(
|
|||
"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()
|
||||
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(
|
||||
f"{api_url}/transactions/{transaction_id}/documents",
|
||||
auth=auth,
|
||||
data={"document": file_id},
|
||||
json={"file": file_id}, # ✅ Utiliser 'file' au lieu de 'document'
|
||||
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()
|
||||
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(
|
||||
f"{api_url}/transactions/{transaction_id}/documents/{document_id}/fields",
|
||||
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,
|
||||
)
|
||||
|
||||
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()
|
||||
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(
|
||||
f"{api_url}/transactions/{transaction_id}/signatures",
|
||||
f"{api_url}/transactions/{transaction_id}/signers",
|
||||
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,
|
||||
)
|
||||
|
||||
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()
|
||||
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(
|
||||
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()
|
||||
signer_url = (
|
||||
final_data.get("actions", [{}])[0].get("url", "")
|
||||
if final_data.get("actions")
|
||||
else ""
|
||||
)
|
||||
|
||||
# ========================================
|
||||
# ÉTAPE 7 : Récupérer l'URL de signature
|
||||
# ========================================
|
||||
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:
|
||||
logger.warning("⚠️ URL de signature non trouvée dans la réponse")
|
||||
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"]
|
||||
|
||||
# Préparer les variables
|
||||
type_labels = {
|
||||
0: "Devis",
|
||||
10: "Commande",
|
||||
|
|
@ -1519,7 +1617,6 @@ async def universign_envoyer_avec_email(
|
|||
"CONTACT_EMAIL": settings.smtp_from,
|
||||
}
|
||||
|
||||
# Remplacer les variables dans le template
|
||||
sujet = template["sujet"]
|
||||
corps = template["corps_html"]
|
||||
|
||||
|
|
@ -1556,11 +1653,18 @@ async def universign_envoyer_avec_email(
|
|||
"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:
|
||||
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}
|
||||
|
||||
|
||||
async def universign_statut(transaction_id: str) -> Dict:
|
||||
"""Récupération statut signature"""
|
||||
import requests
|
||||
|
|
|
|||
Loading…
Reference in a new issue