Files
herolib/lib/threefold/models_to_move/legal/contract.v
2025-09-17 14:41:42 +02:00

374 lines
11 KiB
V

module legal
import time
// ContractStatus defines the possible statuses of a contract
pub enum ContractStatus {
draft // Contract is in draft state
pending_signatures // Waiting for signatures
signed // All parties have signed
active // Contract is active
expired // Contract has expired
cancelled // Contract was cancelled
}
// SignerStatus defines the status of a contract signer
pub enum SignerStatus {
pending // Signature is pending
signed // Signer has signed
rejected // Signer rejected the contract
}
// ContractRevision represents a version of the contract content
pub struct ContractRevision {
pub mut:
version u32 // Version number
content string // Contract content for this version
created_at u64 // Creation timestamp
created_by string // Who created this revision
comments ?string // Optional comments about this revision
}
// new creates a new ContractRevision
pub fn ContractRevision.new(version u32, content string, created_by string) ContractRevision {
return ContractRevision{
version: version
content: content
created_at: u64(time.now().unix_time())
created_by: created_by
comments: none
}
}
// comments sets comments for the revision (builder pattern)
pub fn (mut cr ContractRevision) comments(comments string) ContractRevision {
cr.comments = comments
return cr
}
// ContractSigner represents a party involved in signing a contract
pub struct ContractSigner {
pub mut:
id string // Unique ID for the signer (UUID string)
name string // Signer's name
email string // Signer's email
status SignerStatus // Current status
signed_at ?u64 // When they signed (optional)
comments ?string // Optional comments from signer
last_reminder_mail_sent_at ?u64 // Last reminder timestamp
signature_data ?string // Base64 encoded signature image data
}
// new creates a new ContractSigner
pub fn ContractSigner.new(id string, name string, email string) ContractSigner {
return ContractSigner{
id: id
name: name
email: email
status: .pending
signed_at: none
comments: none
last_reminder_mail_sent_at: none
signature_data: none
}
}
// status sets the signer status (builder pattern)
pub fn (mut cs ContractSigner) status(status SignerStatus) ContractSigner {
cs.status = status
return cs
}
// signed_at sets the signing timestamp (builder pattern)
pub fn (mut cs ContractSigner) signed_at(signed_at u64) ContractSigner {
cs.signed_at = signed_at
return cs
}
// comments sets comments (builder pattern)
pub fn (mut cs ContractSigner) comments(comments string) ContractSigner {
cs.comments = comments
return cs
}
// signature_data sets the signature data (builder pattern)
pub fn (mut cs ContractSigner) signature_data(signature_data string) ContractSigner {
cs.signature_data = signature_data
return cs
}
// can_send_reminder checks if a reminder can be sent (30-minute rate limiting)
pub fn (cs ContractSigner) can_send_reminder() bool {
current_time := u64(time.now().unix_time())
if last_sent := cs.last_reminder_mail_sent_at {
thirty_minutes := u64(30 * 60) // 30 minutes in seconds
return current_time >= last_sent + thirty_minutes
}
return true // No reminder sent yet
}
// reminder_cooldown_remaining gets remaining cooldown time in seconds
pub fn (cs ContractSigner) reminder_cooldown_remaining() ?u64 {
current_time := u64(time.now().unix_time())
if last_sent := cs.last_reminder_mail_sent_at {
thirty_minutes := u64(30 * 60)
cooldown_end := last_sent + thirty_minutes
if current_time < cooldown_end {
return cooldown_end - current_time
}
}
return none // No cooldown
}
// mark_reminder_sent updates the reminder timestamp to current time
pub fn (mut cs ContractSigner) mark_reminder_sent() {
cs.last_reminder_mail_sent_at = u64(time.now().unix_time())
}
// sign signs the contract with optional signature data and comments
pub fn (mut cs ContractSigner) sign(signature_data ?string, comments ?string) {
cs.status = .signed
cs.signed_at = u64(time.now().unix_time())
cs.signature_data = signature_data
if comment := comments {
cs.comments = comment
}
}
// Contract represents a legal agreement
@[heap]
pub struct Contract {
pub mut:
id u32 // Unique contract ID
contract_id string // Unique UUID for the contract
title string // Contract title
description string // Contract description
contract_type string // Type of contract
status ContractStatus // Current status
created_by string // Who created the contract
terms_and_conditions string // Terms and conditions text
start_date ?u64 // Optional start date
end_date ?u64 // Optional end date
renewal_period_days ?i32 // Optional renewal period in days
next_renewal_date ?u64 // Optional next renewal date
signers []ContractSigner // List of signers
revisions []ContractRevision // Contract revisions
current_version u32 // Current version number
last_signed_date ?u64 // Last signing date
created_at u64 // Creation timestamp
updated_at u64 // Last update timestamp
}
// new creates a new Contract
pub fn Contract.new(contract_id string) Contract {
now := u64(time.now().unix_time())
return Contract{
id: 0
contract_id: contract_id
title: ''
description: ''
contract_type: ''
status: .draft
created_by: ''
terms_and_conditions: ''
start_date: none
end_date: none
renewal_period_days: none
next_renewal_date: none
signers: []
revisions: []
current_version: 0
last_signed_date: none
created_at: now
updated_at: now
}
}
// title sets the contract title (builder pattern)
pub fn (mut c Contract) title(title string) Contract {
c.title = title
return c
}
// description sets the contract description (builder pattern)
pub fn (mut c Contract) description(description string) Contract {
c.description = description
return c
}
// contract_type sets the contract type (builder pattern)
pub fn (mut c Contract) contract_type(contract_type string) Contract {
c.contract_type = contract_type
return c
}
// status sets the contract status (builder pattern)
pub fn (mut c Contract) status(status ContractStatus) Contract {
c.status = status
return c
}
// created_by sets who created the contract (builder pattern)
pub fn (mut c Contract) created_by(created_by string) Contract {
c.created_by = created_by
return c
}
// terms_and_conditions sets the terms (builder pattern)
pub fn (mut c Contract) terms_and_conditions(terms string) Contract {
c.terms_and_conditions = terms
return c
}
// start_date sets the start date (builder pattern)
pub fn (mut c Contract) start_date(start_date u64) Contract {
c.start_date = start_date
return c
}
// end_date sets the end date (builder pattern)
pub fn (mut c Contract) end_date(end_date u64) Contract {
c.end_date = end_date
return c
}
// renewal_period_days sets the renewal period (builder pattern)
pub fn (mut c Contract) renewal_period_days(days i32) Contract {
c.renewal_period_days = days
return c
}
// next_renewal_date sets the next renewal date (builder pattern)
pub fn (mut c Contract) next_renewal_date(date u64) Contract {
c.next_renewal_date = date
return c
}
// add_signer adds a signer to the contract (builder pattern)
pub fn (mut c Contract) add_signer(signer ContractSigner) Contract {
c.signers << signer
return c
}
// signers sets all signers (builder pattern)
pub fn (mut c Contract) signers(signers []ContractSigner) Contract {
c.signers = signers
return c
}
// add_revision adds a revision to the contract (builder pattern)
pub fn (mut c Contract) add_revision(revision ContractRevision) Contract {
c.revisions << revision
return c
}
// revisions sets all revisions (builder pattern)
pub fn (mut c Contract) revisions(revisions []ContractRevision) Contract {
c.revisions = revisions
return c
}
// current_version sets the current version (builder pattern)
pub fn (mut c Contract) current_version(version u32) Contract {
c.current_version = version
return c
}
// last_signed_date sets the last signed date (builder pattern)
pub fn (mut c Contract) last_signed_date(date u64) Contract {
c.last_signed_date = date
return c
}
// set_status sets the contract status and updates timestamp
pub fn (mut c Contract) set_status(status ContractStatus) {
c.status = status
c.updated_at = u64(time.now().unix_time())
}
// is_draft checks if contract is in draft status
pub fn (c Contract) is_draft() bool {
return c.status == .draft
}
// is_pending_signatures checks if contract is pending signatures
pub fn (c Contract) is_pending_signatures() bool {
return c.status == .pending_signatures
}
// is_signed checks if contract is signed
pub fn (c Contract) is_signed() bool {
return c.status == .signed
}
// is_active checks if contract is active
pub fn (c Contract) is_active() bool {
return c.status == .active
}
// is_expired checks if contract is expired
pub fn (c Contract) is_expired() bool {
return c.status == .expired
}
// is_cancelled checks if contract is cancelled
pub fn (c Contract) is_cancelled() bool {
return c.status == .cancelled
}
// get_pending_signers returns signers with pending status
pub fn (c Contract) get_pending_signers() []ContractSigner {
return c.signers.filter(it.status == .pending)
}
// get_signed_signers returns signers who have signed
pub fn (c Contract) get_signed_signers() []ContractSigner {
return c.signers.filter(it.status == .signed)
}
// all_signed checks if all signers have signed
pub fn (c Contract) all_signed() bool {
if c.signers.len == 0 {
return false
}
for signer in c.signers {
if signer.status != .signed {
return false
}
}
return true
}
// get_signer_by_id finds a signer by ID
pub fn (c Contract) get_signer_by_id(id string) ?ContractSigner {
for signer in c.signers {
if signer.id == id {
return signer
}
}
return none
}
// get_current_revision gets the current revision
pub fn (c Contract) get_current_revision() ?ContractRevision {
for revision in c.revisions {
if revision.version == c.current_version {
return revision
}
}
return none
}
// status_string returns the status as a string
pub fn (c Contract) status_string() string {
return match c.status {
.draft { 'Draft' }
.pending_signatures { 'Pending Signatures' }
.signed { 'Signed' }
.active { 'Active' }
.expired { 'Expired' }
.cancelled { 'Cancelled' }
}
}