feat: Add reminder functionality to ContractSigner model

- Added `last_reminder_mail_sent_at` field to track reminder
  timestamps.
- Implemented `can_send_reminder` to check if a reminder can be
  sent based on a 30-minute cooldown.
- Added `reminder_cooldown_remaining` to get remaining cooldown
  time.
- Added `mark_reminder_sent` to update reminder timestamp.
- Added example demonstrating reminder functionality in
  `legal_contract_example.rs`.
- Added tests for reminder functionality in
  `test_reminder_functionality.rs`.
- Updated Rhai scripts to include reminder-related functions and
  tests.
- Improved formatting and clarity in example code.
This commit is contained in:
Mahmoud-Emad
2025-06-10 15:41:49 +03:00
parent 20c075ec51
commit 970299b1a4
6 changed files with 828 additions and 173 deletions

View File

@@ -70,7 +70,7 @@ fn main() {
.add_signer(signer2.clone())
.add_revision(revision1.clone())
.add_revision(revision2.clone());
// The `#[model]` derive handles `created_at` and `updated_at` in `base_data`.
// `base_data.touch()` might be called internally by setters or needs explicit call if fields are set directly.
// For builder pattern, the final state of `base_data.updated_at` reflects the time of the last builder call if `touch()` is implicit.
@@ -87,7 +87,7 @@ fn main() {
println!("\n--- Contract Details After Signing ---");
println!("{:#?}", contract);
println!("\n--- Accessing Specific Fields ---");
println!("Contract Title: {}", contract.title);
println!("Contract Status: {:?}", contract.status);
@@ -97,7 +97,10 @@ fn main() {
println!("Updated At (timestamp): {}", contract.base_data.modified_at); // From BaseModelData
if let Some(first_signer_details) = contract.signers.first() {
println!("\nFirst Signer: {} ({})", first_signer_details.name, first_signer_details.email);
println!(
"\nFirst Signer: {} ({})",
first_signer_details.name, first_signer_details.email
);
println!(" Status: {:?}", first_signer_details.status);
if let Some(signed_time) = first_signer_details.signed_at {
println!(" Signed At: {}", signed_time);
@@ -110,6 +113,51 @@ fn main() {
println!(" Created By: {}", latest_rev.created_by);
println!(" Revision Created At: {}", latest_rev.created_at);
}
// Demonstrate reminder functionality
println!("\n--- Reminder Functionality Demo ---");
let current_time = current_timestamp_secs();
// Check if we can send reminders to signers
for (i, signer) in contract.signers.iter().enumerate() {
println!("\nSigner {}: {} ({})", i + 1, signer.name, signer.email);
println!(" Status: {:?}", signer.status);
if signer.last_reminder_mail_sent_at.is_none() {
println!(" Last reminder: Never sent");
} else {
println!(
" Last reminder: {}",
signer.last_reminder_mail_sent_at.unwrap()
);
}
let can_send = signer.can_send_reminder(current_time);
println!(" Can send reminder now: {}", can_send);
if let Some(remaining) = signer.reminder_cooldown_remaining(current_time) {
println!(" Cooldown remaining: {} seconds", remaining);
} else {
println!(" No cooldown active");
}
}
// Simulate sending a reminder to the first signer
if let Some(first_signer) = contract.signers.get_mut(0) {
if first_signer.can_send_reminder(current_time) {
println!("\nSimulating reminder sent to: {}", first_signer.name);
first_signer.mark_reminder_sent(current_time);
println!(
" Reminder timestamp updated to: {}",
first_signer.last_reminder_mail_sent_at.unwrap()
);
// Check cooldown after sending
if let Some(remaining) = first_signer.reminder_cooldown_remaining(current_time) {
println!(" New cooldown: {} seconds (30 minutes)", remaining);
}
}
}
println!("\nLegal Contract Model demonstration complete.");
}