Add planning docs for trade-ins, returns, tax exemptions, cycle counts, POs, bundles, backorders, barcode labels, instrument sizing, warranties, maintenance schedules, gift cards, layaway, rental agreements, and in-home trials
This commit is contained in:
@@ -232,4 +232,133 @@ When billing_group is null, the rental has its own independent Stripe subscripti
|
||||
|
||||
- Final invoice generated for any partial month charges
|
||||
|
||||
- If damage found, repair ticket created automatically and linked to rental record
|
||||
- If damage found, repair ticket created automatically and linked to rental record
|
||||
|
||||
|
||||
|
||||
# 7. Rental Agreement Contracts
|
||||
|
||||
Every rental requires a signed agreement before the instrument leaves the store. Agreements are generated from templates, capture all rental terms, and are stored as signed documents.
|
||||
|
||||
## 7.1 rental_agreement_template
|
||||
|
||||
Store-configurable contract templates. Most stores have one template per rental type, but can create variations for schools, events, etc.
|
||||
|
||||
Column | Type | Notes
|
||||
id | uuid PK |
|
||||
company_id | uuid FK | Tenant scoping
|
||||
name | varchar | e.g. "Standard Month-to-Month", "School RTO Agreement", "Short-Term Event Rental"
|
||||
rental_type | enum | month_to_month | rent_to_own | short_term | lease_purchase | all
|
||||
body | text | Contract body with merge fields (see §7.3)
|
||||
requires_signature | boolean | Default true — some internal/school agreements may waive
|
||||
requires_guardian_signature | boolean | Default true if member.is_minor
|
||||
include_insurance_terms | boolean | Whether insurance section is included
|
||||
include_rto_terms | boolean | Whether rent-to-own buyout terms are included
|
||||
include_damage_policy | boolean | Whether damage/loss liability section is included
|
||||
is_default | boolean | Default template for this rental_type
|
||||
is_active | boolean |
|
||||
created_at | timestamptz |
|
||||
updated_at | timestamptz |
|
||||
|
||||
## 7.2 rental_agreement
|
||||
|
||||
A generated, signed agreement instance linked to a specific rental.
|
||||
|
||||
Column | Type | Notes
|
||||
id | uuid PK |
|
||||
company_id | uuid FK |
|
||||
rental_id | uuid FK | The rental this agreement covers
|
||||
template_id | uuid FK | Template used to generate
|
||||
account_id | uuid FK |
|
||||
member_id | uuid FK | Member receiving the instrument
|
||||
agreement_number | varchar | Human-readable ID (auto-generated)
|
||||
generated_body | text | Full rendered contract text with all merge fields resolved — immutable after signing
|
||||
status | enum | draft | pending_signature | signed | voided
|
||||
signed_at | timestamptz | When signature was captured
|
||||
signer_name | varchar | Name of person who signed
|
||||
signer_relationship | varchar | Nullable — e.g. "parent", "guardian", "self"
|
||||
guardian_signed_at | timestamptz | Nullable — when guardian signed (if minor)
|
||||
guardian_name | varchar | Nullable
|
||||
signature_method | enum | in_store_tablet | in_store_paper | email | portal
|
||||
signature_data | text | Nullable — base64 signature image for tablet/paper capture
|
||||
document_url | varchar | Nullable — URL to stored PDF in object storage
|
||||
ip_address | varchar | Nullable — for email/portal signatures
|
||||
voided_reason | text | Nullable — why agreement was voided
|
||||
voided_by | uuid FK | Nullable
|
||||
created_at | timestamptz |
|
||||
updated_at | timestamptz |
|
||||
|
||||
## 7.3 Merge Fields
|
||||
|
||||
Templates use merge fields that are resolved at generation time. The generated_body stores the fully resolved text so the agreement is a permanent record even if account details change later.
|
||||
|
||||
Field | Resolves To
|
||||
{{account_name}} | account.name
|
||||
{{account_email}} | account.email
|
||||
{{account_phone}} | account.phone
|
||||
{{account_address}} | account.address (formatted)
|
||||
{{member_name}} | member.first_name + member.last_name
|
||||
{{member_is_minor}} | "Yes" / "No"
|
||||
{{instrument_description}} | product.name + product.brand + product.model
|
||||
{{instrument_size}} | inventory_unit.instrument_size or product.instrument_size
|
||||
{{serial_number}} | inventory_unit.serial_number
|
||||
{{instrument_condition}} | inventory_unit.condition at rental start
|
||||
{{rental_type}} | Formatted rental type name
|
||||
{{monthly_rate}} | rental.monthly_rate
|
||||
{{deposit_amount}} | rental.deposit_amount
|
||||
{{start_date}} | rental.start_date (formatted)
|
||||
{{end_date}} | rental.end_date or "Open-ended"
|
||||
{{rto_purchase_price}} | rental.rto_purchase_price (if RTO)
|
||||
{{rto_equity_percent}} | rental.rto_equity_percent (if RTO)
|
||||
{{company_name}} | company.name
|
||||
{{company_address}} | company.address
|
||||
{{company_phone}} | company.phone
|
||||
{{today_date}} | Current date
|
||||
{{agreement_number}} | rental_agreement.agreement_number
|
||||
|
||||
## 7.4 Agreement Workflow
|
||||
|
||||
1. Staff creates rental — system selects default template for rental_type (or staff picks one)
|
||||
2. Agreement generated: merge fields resolved, generated_body populated, status = "draft"
|
||||
3. Staff reviews agreement on screen — can edit before finalizing if needed
|
||||
4. Signature capture:
|
||||
a. **In-store tablet**: customer signs on screen, signature_data captured as base64
|
||||
b. **In-store paper**: staff prints, customer signs physical copy, staff scans/uploads
|
||||
c. **Email**: agreement emailed to account email with secure signing link
|
||||
d. **Portal**: customer signs via self-service portal (if MOD-PORTAL licensed)
|
||||
5. Agreement status updated to "signed" — PDF generated and stored
|
||||
6. Rental cannot activate until agreement is signed (unless overridden by manager)
|
||||
7. Signed agreement PDF available on rental record, account history, and customer portal
|
||||
|
||||
## 7.5 Guardian Signatures
|
||||
|
||||
- If member.is_minor = true, agreement requires guardian signature in addition to (or instead of) member signature
|
||||
- Guardian must be an adult member on the same account, or signer_relationship recorded for non-member guardian
|
||||
- Both signature fields must be completed before agreement is fully signed
|
||||
- Email/portal signing flow sends to account primary email (assumed to be parent/guardian)
|
||||
|
||||
## 7.6 Agreement Delivery
|
||||
|
||||
- **Print**: generated as PDF, sent to receipt printer or standard printer
|
||||
- **Email**: PDF attached to email sent to account.email
|
||||
- **Portal**: PDF available in customer portal under "My Agreements"
|
||||
- **All signed agreements**: stored in object storage (S3-compatible), URL recorded on rental_agreement.document_url
|
||||
|
||||
## 7.7 Voiding and Re-signing
|
||||
|
||||
- Voiding an agreement requires reason and manager approval
|
||||
- Voiding does not cancel the rental — but rental cannot remain active without a signed agreement
|
||||
- Common void reasons: incorrect terms, wrong instrument, customer requested change
|
||||
- After voiding, a new agreement is generated from template (or modified) and signed
|
||||
- Voided agreements retained for audit — never deleted
|
||||
|
||||
## 7.8 Business Rules
|
||||
|
||||
- Rental cannot activate without a signed agreement (manager override available with reason logged)
|
||||
- Agreement text is immutable after signing — edits require void and re-sign
|
||||
- generated_body is the legal record — template changes do not affect existing agreements
|
||||
- Signature data retained for the life of the agreement (minimum 7 years per record retention policy)
|
||||
- Agreement PDF regenerated on demand from generated_body + signature_data — not dependent on template
|
||||
- Schools with bulk rentals (MOD-BATCH): single master agreement can cover multiple instruments for a school account
|
||||
- Short-term rentals may use a simplified template with fewer terms
|
||||
- Agreement history visible on account record — all past and current agreements listed
|
||||
Reference in New Issue
Block a user