feat: Add signature functionality to ContractSigner

- Add `signature_data` field to `ContractSigner` to store base64
  encoded signature image data.  Allows for storing visual
  signatures alongside electronic ones.
- Implement `sign` method for `ContractSigner` to handle signing
  with optional signature data and comments. Improves the
  flexibility and expressiveness of the signing process.
- Add Rhai functions for signature management, including signing
  with/without data and clearing signature data.  Extends the
  Rhai scripting capabilities for contract management.
- Add comprehensive unit tests to cover the new signature
  functionality. Ensures correctness and robustness of the
  implementation.
- Update examples to demonstrate the new signature functionality.
  Provides clear usage examples for developers.
This commit is contained in:
Mahmoud-Emad
2025-06-12 14:30:58 +03:00
parent b9abfa50a9
commit f0a0dd6d73
6 changed files with 322 additions and 1 deletions

View File

@@ -40,16 +40,19 @@ print(`Signer 1 ID: ${signer1.id}, Name: ${signer1.name}, Email: ${signer1.email
print(`Signer 1 Status: ${signer1.status}, Comments: ${format_optional_string(signer1.comments, "N/A")}`);
print(`Signer 1 Signed At: ${format_optional_int(signer1.signed_at, "Not signed")}`);
print(`Signer 1 Last Reminder: ${format_optional_int(signer1.last_reminder_mail_sent_at, "Never sent")}`);
print(`Signer 1 Signature Data: ${format_optional_string(signer1.signature_data, "No signature")}`);
let signer2_id = "signer-uuid-002";
let signer2 = new_contract_signer(signer2_id, "Bob The Builder", "bob@example.com")
.status(SignerStatusConstants::Signed)
.signed_at(1678886400) // Example timestamp
.comments("Bob has already signed.")
.last_reminder_mail_sent_at(1678880000); // Example reminder timestamp
.last_reminder_mail_sent_at(1678880000) // Example reminder timestamp
.signature_data("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg=="); // Example signature
print(`Signer 2 ID: ${signer2.id}, Name: ${signer2.name}, Status: ${signer2.status}, Signed At: ${format_optional_int(signer2.signed_at, "N/A")}`);
print(`Signer 2 Last Reminder: ${format_optional_int(signer2.last_reminder_mail_sent_at, "Never sent")}`);
print(`Signer 2 Signature Data Length: ${signer2.signature_data.len()} characters`);
// --- Test ContractRevision Model ---
print("\n--- Testing ContractRevision Model ---");
@@ -146,4 +149,26 @@ if final_retrieved_contract.signers.len() > 0 {
}
}
// --- Test Signature Functionality ---
print("\n--- Testing Signature Functionality ---");
// Test signing with signature data
let test_signer = new_contract_signer("test-signer-001", "Test Signer", "test@example.com");
print(`Before signing: Status = ${test_signer.status}, Signature Data = ${format_optional_string(test_signer.signature_data, "None")}`);
// Sign with signature data
sign(test_signer, "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==", "I agree to the terms");
print(`After signing: Status = ${test_signer.status}, Signature Data Length = ${test_signer.signature_data.len()}`);
print(`Comments: ${format_optional_string(test_signer.comments, "No comments")}`);
// Test signing without signature data
let test_signer2 = new_contract_signer("test-signer-002", "Test Signer 2", "test2@example.com");
sign_without_signature(test_signer2, "Electronic signature without visual data");
print(`Signer 2 after signing: Status = ${test_signer2.status}, Signature Data = ${format_optional_string(test_signer2.signature_data, "None")}`);
// Test simple signing
let test_signer3 = new_contract_signer("test-signer-003", "Test Signer 3", "test3@example.com");
sign_simple(test_signer3);
print(`Signer 3 after simple signing: Status = ${test_signer3.status}`);
print("\nLegal Rhai example script finished.");