Skip to content

Commit

Permalink
✨(backend) get signing progress on document for signature backends
Browse files Browse the repository at this point in the history
Instead of waiting for the webhook that a document has been signed
from the signature provider (the cause would be a latency to send us
the notification event), we have decided to add a new endpoint
on the backend signature provide to get the information if whether
the student or the organization have signed the document. The new
method returns a dictionary with boolean value that informs the
progression of signing procedure of a document.
  • Loading branch information
jonathanreveille committed Sep 20, 2024
1 parent ef1e8d3 commit e7b5e45
Show file tree
Hide file tree
Showing 8 changed files with 617 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ and this project adheres to

### Added

- Signature backend can now retrieve the signing progression of a document
- Debit installment on pending order transition if due date is on current day
- Display order credit card detail in the back office
- Send an email reminder to the user when an installment
Expand Down
9 changes: 9 additions & 0 deletions src/backend/joanie/signature/backends/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,3 +151,12 @@ def update_signatories(self, reference_id: str, all_signatories: bool):
"subclasses of BaseSignatureBackend must provide a "
"update_signatories() method."
)

def get_signature_state(self, reference_id: str):
"""
Get the signature state of a contract to know who has signed yet the document.
"""
raise NotImplementedError(
"subclasses of BaseSignatureBackend must provide a "
"get_signature_state() method."
)
19 changes: 19 additions & 0 deletions src/backend/joanie/signature/backends/dummy.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,3 +147,22 @@ def update_signatories(self, reference_id: str, all_signatories: bool) -> str:
raise ValidationError(f"The contract {contract.id} is already fully signed")

return contract.signature_backend_reference

def get_signature_state(self, reference_id: str) -> int:
"""
Dummy method that returns the state of document in signing process.
It returns whether the student and the organization have signed.
"""
if not reference_id.startswith(self.prefix_workflow):
raise ValidationError(f"The reference does not exist: {reference_id}.")
try:
contract = Contract.objects.get(signature_backend_reference=reference_id)
except Contract.DoesNotExist as exception:
raise ValidationError(
f"Contract with reference id {reference_id} does not exist."
) from exception

return {
"student": bool(contract.student_signed_on),
"organization": bool(contract.organization_signed_on),
}
34 changes: 34 additions & 0 deletions src/backend/joanie/signature/backends/lex_persona.py
Original file line number Diff line number Diff line change
Expand Up @@ -667,3 +667,37 @@ def update_signatories(self, reference_id: str, all_signatories: bool) -> str:
)

return response.json()["id"]

def get_signature_state(self, reference_id: str) -> dict:
"""
Get the signature state progress on a signing procedure.
It returns a dictionary whether the student and the organization have signed.
"""
timeout = settings.JOANIE_SIGNATURE_TIMEOUT
base_url = self.get_setting("BASE_URL")
token = self.get_setting("TOKEN")
url = f"{base_url}/api/workflows/{reference_id}/"
headers = {"Authorization": f"Bearer {token}"}

response = requests.get(url, headers=headers, timeout=timeout)

if not response.ok:
logger.error(
"Lex Persona: Unable to retrieve the signature procedure"
" the reference does not exist %s, reason: %s",
reference_id,
response.json(),
extra={
"url": url,
"response": response.json(),
},
)
raise exceptions.SignatureProcedureNotFound(
"Lex Persona: Unable to retrieve the signature procedure"
f" the reference does not exist {reference_id}"
)

return {
"student": response.json().get("steps")[0].get("isFinished"),
"organization": response.json().get("steps")[-1].get("isFinished"),
}
11 changes: 11 additions & 0 deletions src/backend/joanie/signature/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,3 +67,14 @@ class DeleteSignatureProcedureFailed(APIException):
status_code = HTTPStatus.BAD_REQUEST
default_detail = _("Cannot delete the signature procedure.")
default_code = "delete_signature_procedure_failed"


class SignatureProcedureNotFound(APIException):
"""
Exception triggered when retrieving the signing procedure from the signature
provider fails
"""

status_code = HTTPStatus.NOT_FOUND
default_detail = _("The reference of signing procedure does not exist.")
default_code = "signature_procedure_not_found"
Loading

0 comments on commit e7b5e45

Please sign in to comment.