Reverted delocalized function
This commit is contained in:
parent
ffa45347bb
commit
d0db0e4077
1 changed files with 150 additions and 1 deletions
151
api.py
151
api.py
|
|
@ -75,7 +75,6 @@ from schemas import (
|
|||
ContactCreate,
|
||||
ContactUpdate,
|
||||
)
|
||||
from utils.generic_functions import universign_envoyer, universign_statut
|
||||
from utils.normalization import normaliser_type_tiers
|
||||
|
||||
logging.basicConfig(
|
||||
|
|
@ -126,6 +125,156 @@ app.add_middleware(
|
|||
app.include_router(auth_router)
|
||||
|
||||
|
||||
|
||||
async def universign_envoyer(
|
||||
doc_id: str,
|
||||
pdf_bytes: bytes,
|
||||
email: str,
|
||||
nom: str,
|
||||
doc_data: dict,
|
||||
session: AsyncSession,
|
||||
) -> dict:
|
||||
import requests
|
||||
|
||||
try:
|
||||
api_key = settings.universign_api_key
|
||||
api_url = settings.universign_api_url
|
||||
auth = (api_key, "")
|
||||
|
||||
logger.info(f"Démarrage processus Universign pour {email}")
|
||||
|
||||
if not pdf_bytes or len(pdf_bytes) == 0:
|
||||
raise Exception("Le PDF généré est vide")
|
||||
|
||||
# ÉTAPE 1: Création transaction
|
||||
response = requests.post(
|
||||
f"{api_url}/transactions",
|
||||
auth=auth,
|
||||
json={"name": f"{doc_data.get('type_label', 'Document')} {doc_id}", "language": "fr"},
|
||||
timeout=30,
|
||||
)
|
||||
if response.status_code != 200:
|
||||
raise Exception(f"Erreur création transaction: {response.status_code}")
|
||||
transaction_id = response.json().get("id")
|
||||
|
||||
# ÉTAPE 2: Upload PDF
|
||||
files = {"file": (f"{doc_data.get('type_label', 'Document')}_{doc_id}.pdf", pdf_bytes, "application/pdf")}
|
||||
response = requests.post(f"{api_url}/files", auth=auth, files=files, timeout=60)
|
||||
if response.status_code not in [200, 201]:
|
||||
raise Exception(f"Erreur upload fichier: {response.status_code}")
|
||||
file_id = response.json().get("id")
|
||||
|
||||
# ÉTAPE 3: Ajout document
|
||||
response = requests.post(
|
||||
f"{api_url}/transactions/{transaction_id}/documents",
|
||||
auth=auth, data={"document": file_id}, timeout=30
|
||||
)
|
||||
if response.status_code not in [200, 201]:
|
||||
raise Exception(f"Erreur ajout document: {response.status_code}")
|
||||
document_id = response.json().get("id")
|
||||
|
||||
# ÉTAPE 4: Création champ signature
|
||||
response = requests.post(
|
||||
f"{api_url}/transactions/{transaction_id}/documents/{document_id}/fields",
|
||||
auth=auth, data={"type": "signature"}, timeout=30
|
||||
)
|
||||
if response.status_code not in [200, 201]:
|
||||
raise Exception(f"Erreur création champ: {response.status_code}")
|
||||
field_id = response.json().get("id")
|
||||
|
||||
# ÉTAPE 5: Liaison signataire
|
||||
response = requests.post(
|
||||
f"{api_url}/transactions/{transaction_id}/signatures",
|
||||
auth=auth, data={"signer": email, "field": field_id}, timeout=30
|
||||
)
|
||||
if response.status_code not in [200, 201]:
|
||||
raise Exception(f"Erreur liaison signataire: {response.status_code}")
|
||||
|
||||
# ÉTAPE 6: Démarrage
|
||||
response = requests.post(f"{api_url}/transactions/{transaction_id}/start", auth=auth, timeout=30)
|
||||
if response.status_code not in [200, 201]:
|
||||
raise Exception(f"Erreur démarrage: {response.status_code}")
|
||||
final_data = response.json()
|
||||
|
||||
# Récupération URL
|
||||
signer_url = ""
|
||||
if final_data.get("actions"):
|
||||
for action in final_data["actions"]:
|
||||
if action.get("url"):
|
||||
signer_url = action["url"]
|
||||
break
|
||||
if not signer_url and 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:
|
||||
raise ValueError("URL de signature non retournée par Universign")
|
||||
|
||||
# Préparation email
|
||||
template = templates_signature_email["demande_signature"]
|
||||
type_labels = {0: "Devis", 10: "Commande", 30: "Bon de Livraison", 60: "Facture", 50: "Avoir"}
|
||||
variables = {
|
||||
"NOM_SIGNATAIRE": nom,
|
||||
"TYPE_DOC": type_labels.get(doc_data.get("type_doc", 0), "Document"),
|
||||
"NUMERO": doc_id,
|
||||
"DATE": doc_data.get("date", datetime.now().strftime("%d/%m/%Y")),
|
||||
"MONTANT_TTC": f"{doc_data.get('montant_ttc', 0):.2f}",
|
||||
"SIGNER_URL": signer_url,
|
||||
"CONTACT_EMAIL": settings.smtp_from,
|
||||
}
|
||||
sujet = template["sujet"]
|
||||
corps = template["corps_html"]
|
||||
for var, valeur in variables.items():
|
||||
sujet = sujet.replace(f"{{{{{var}}}}}", str(valeur))
|
||||
corps = corps.replace(f"{{{{{var}}}}}", str(valeur))
|
||||
|
||||
email_log = EmailLog(
|
||||
id=str(uuid.uuid4()),
|
||||
destinataire=email,
|
||||
sujet=sujet,
|
||||
corps_html=corps,
|
||||
document_ids=doc_id,
|
||||
type_document=doc_data.get("type_doc"),
|
||||
statut=StatutEmailEnum.EN_ATTENTE,
|
||||
date_creation=datetime.now(),
|
||||
nb_tentatives=0,
|
||||
)
|
||||
session.add(email_log)
|
||||
await session.flush()
|
||||
email_queue.enqueue(email_log.id)
|
||||
|
||||
return {
|
||||
"transaction_id": transaction_id,
|
||||
"signer_url": signer_url,
|
||||
"statut": "ENVOYE",
|
||||
"email_log_id": email_log.id,
|
||||
"email_sent": True,
|
||||
}
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Erreur Universign: {e}", exc_info=True)
|
||||
return {"error": str(e), "statut": "ERREUR", "email_sent": False}
|
||||
|
||||
|
||||
async def universign_statut(transaction_id: str) -> dict:
|
||||
import requests
|
||||
try:
|
||||
response = requests.get(
|
||||
f"{settings.universign_api_url}/transactions/{transaction_id}",
|
||||
auth=(settings.universign_api_key, ""),
|
||||
timeout=10,
|
||||
)
|
||||
if response.status_code == 200:
|
||||
data = response.json()
|
||||
statut_map = {"draft": "EN_ATTENTE", "started": "EN_ATTENTE", "completed": "SIGNE", "refused": "REFUSE", "expired": "EXPIRE", "canceled": "REFUSE"}
|
||||
return {"statut": statut_map.get(data.get("state"), "EN_ATTENTE"), "date_signature": data.get("completed_at")}
|
||||
return {"statut": "ERREUR"}
|
||||
except Exception as e:
|
||||
logger.error(f"Erreur statut Universign: {e}")
|
||||
return {"statut": "ERREUR", "error": str(e)}
|
||||
|
||||
|
||||
@app.get("/clients", response_model=List[ClientDetails], tags=["Clients"])
|
||||
async def obtenir_clients(query: Optional[str] = Query(None)):
|
||||
try:
|
||||
|
|
|
|||
Loading…
Reference in a new issue