// heromodels - Legal Module Rhai Example print("Hero Models - Legal Rhai Example"); print("==============================="); // Helper to format Option (Dynamic in Rhai: String or ()) for printing fn format_optional_string(val, placeholder) { if val == () { placeholder } else { val } } // Helper to format Option (Dynamic in Rhai: i64 or ()) for printing fn format_optional_int(val, placeholder) { if val == () { placeholder } else { "" + val // Convert int to string for concatenation } } print("DB instance will be implicitly passed to DB functions."); // --- Using Enum Constants --- print(`\n--- Enum Constants ---`); print(`ContractStatus Draft: ${ContractStatusConstants::Draft}`); print(`ContractStatus Active: ${ContractStatusConstants::Active}`); print(`SignerStatus Pending: ${SignerStatusConstants::Pending}`); print(`SignerStatus Signed: ${SignerStatusConstants::Signed}`); // --- Test ContractSigner Model --- print("\n--- Testing ContractSigner Model ---"); let signer1_id = "signer-uuid-001"; let signer1 = new_contract_signer(signer1_id, "Alice Wonderland", "alice@example.com") .status(SignerStatusConstants::Pending) .comments("Alice is the primary signatory."); 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 .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 ---"); let revision1_version = 1; let revision1 = new_contract_revision(revision1_version, "Initial draft content for the agreement, version 1.", 1678880000, "user-admin-01") .comments("First version of the contract."); print(`Revision 1 Version: ${revision1.version}, Content: '${revision1.content}', Created At: ${revision1.created_at}, By: ${revision1.created_by}`); print(`Revision 1 Comments: ${format_optional_string(revision1.comments, "N/A")}`); let revision2_version = 2; let revision2 = new_contract_revision(revision2_version, "Updated content with new clauses, version 2.", 1678882200, "user-legal-02"); // --- Test Contract Model --- print("\n--- Testing Contract Model ---"); let contract1_base_id = 101; let contract1_uuid = "contract-uuid-xyz-001"; print(`Creating a new contract (ID: ${contract1_base_id}, UUID: ${contract1_uuid})...`); let contract1 = new_contract(contract1_base_id, contract1_uuid) .title("Master Service Agreement") .description("MSA between ACME Corp and Client Inc.") .contract_type("Services") .status(ContractStatusConstants::Draft) .created_by("user-admin-01") .terms_and_conditions("Standard terms and conditions apply. See Appendix A.") .start_date(1678900000) .current_version(revision1.version) .add_signer(signer1) .add_revision(revision1); print(`Contract 1 Title: ${contract1.title}, Status: ${contract1.status}`); print(`Contract 1 Signers: ${contract1.signers.len()}, Revisions: ${contract1.revisions.len()}`); // Add more data contract1 = contract1.add_signer(signer2).add_revision(revision2).current_version(revision2.version); print(`Contract 1 Updated Signers: ${contract1.signers.len()}, Revisions: ${contract1.revisions.len()}, Current Version: ${contract1.current_version}`); // Save the contract to the database print("Saving contract1 to database..."); set_contract(contract1); print("Contract1 saved."); // Retrieve the contract print(`Retrieving contract by ID (${contract1_base_id})...`); let retrieved_contract = get_contract_by_id(contract1_base_id); print(`Retrieved Contract: ${retrieved_contract.title}, Status: ${retrieved_contract.status}`); print(`Retrieved Contract Signers: ${retrieved_contract.signers.len()}, Revisions: ${retrieved_contract.revisions.len()}`); if retrieved_contract.signers.len() > 0 { print(`First signer of retrieved contract: ${retrieved_contract.signers[0].name}`); } if retrieved_contract.revisions.len() > 0 { print(`First revision content of retrieved contract: '${retrieved_contract.revisions[0].content}'`); } // --- Test updating a Contract --- print("\n--- Testing Update for Contract ---"); let updated_contract = retrieved_contract .status(ContractStatusConstants::Active) .end_date(1700000000) .description("MSA (Active) between ACME Corp and Client Inc. with new addendum."); print(`Updated Contract - Title: ${updated_contract.title}, Status: ${updated_contract.status}, End Date: ${format_optional_int(updated_contract.end_date, "N/A")}`); set_contract(updated_contract); // Save updated print("Updated Contract saved."); let final_retrieved_contract = get_contract_by_id(contract1_base_id); print(`Final Retrieved Contract - Status: ${final_retrieved_contract.status}, Description: '${final_retrieved_contract.description}'`); // --- Test Reminder Functionality --- print("\n--- Testing Reminder Functionality ---"); let current_time = 1678900000; // Example current timestamp // Test reminder functionality on signers if final_retrieved_contract.signers.len() > 0 { let test_signer = final_retrieved_contract.signers[0]; print(`Testing reminder for signer: ${test_signer.name}`); let can_send = can_send_reminder(test_signer, current_time); print(`Can send reminder: ${can_send}`); let cooldown_remaining = reminder_cooldown_remaining(test_signer, current_time); print(`Cooldown remaining: ${format_optional_int(cooldown_remaining, "No cooldown")}`); // Simulate sending a reminder if can_send { print("Simulating reminder sent..."); mark_reminder_sent(test_signer, current_time); print("Reminder timestamp updated"); // Check cooldown after sending let new_cooldown = reminder_cooldown_remaining(test_signer, current_time); print(`New cooldown: ${format_optional_int(new_cooldown, "No cooldown")} seconds`); } } // --- 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.");