269 lines
9.6 KiB
Python
269 lines
9.6 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Advanced Template Features Example
|
|
|
|
This script demonstrates how to use the enhanced template system
|
|
with conditional sections, loops, and rich formatting.
|
|
"""
|
|
|
|
import asyncio
|
|
import httpx
|
|
import json
|
|
from datetime import date, datetime
|
|
|
|
|
|
class AdvancedTemplateExample:
|
|
def __init__(self, base_url="http://localhost:8000"):
|
|
self.base_url = base_url
|
|
self.auth_token = None
|
|
|
|
async def authenticate(self, username="admin", password=None):
|
|
"""Authenticate and get access token"""
|
|
async with httpx.AsyncClient() as client:
|
|
from os import getenv
|
|
if password is None:
|
|
password = getenv("ADMIN_PASSWORD", "")
|
|
response = await client.post(
|
|
f"{self.base_url}/api/auth/token",
|
|
data={"username": username, "password": password}
|
|
)
|
|
if response.status_code == 200:
|
|
self.auth_token = response.json()["access_token"]
|
|
print("✅ Authentication successful")
|
|
else:
|
|
print(f"❌ Authentication failed: {response.text}")
|
|
return False
|
|
return True
|
|
|
|
@property
|
|
def headers(self):
|
|
if not self.auth_token:
|
|
raise ValueError("Not authenticated")
|
|
return {"Authorization": f"Bearer {self.auth_token}"}
|
|
|
|
async def test_variable_formatting(self):
|
|
"""Test variable formatting without generating documents"""
|
|
print("\n📝 Testing Variable Formatting...")
|
|
|
|
test_cases = [
|
|
{"value": "1234.56", "format": "currency", "expected": "$1,234.56"},
|
|
{"value": "2023-12-25", "format": "date:%B %d, %Y", "expected": "December 25, 2023"},
|
|
{"value": "5551234567", "format": "phone", "expected": "(555) 123-4567"},
|
|
{"value": "hello world", "format": "title", "expected": "Hello World"},
|
|
{"value": "75.5", "format": "percentage:1", "expected": "75.5%"}
|
|
]
|
|
|
|
async with httpx.AsyncClient() as client:
|
|
for test in test_cases:
|
|
response = await client.post(
|
|
f"{self.base_url}/api/templates/test-formatting",
|
|
headers=self.headers,
|
|
data={
|
|
"variable_value": test["value"],
|
|
"format_spec": test["format"]
|
|
}
|
|
)
|
|
|
|
if response.status_code == 200:
|
|
result = response.json()
|
|
actual = result["formatted_result"]
|
|
status = "✅" if actual == test["expected"] else "❌"
|
|
print(f" {status} {test['value']} | {test['format']} → {actual}")
|
|
else:
|
|
print(f" ❌ Error testing {test['format']}: {response.text}")
|
|
|
|
async def demonstrate_template_features(self):
|
|
"""Demonstrate advanced template features with sample data"""
|
|
print("\n🎯 Demonstrating Advanced Template Features...")
|
|
|
|
# Sample context data that would come from database
|
|
sample_context = {
|
|
"CLIENT_NAME": "Smith Family Trust",
|
|
"FILE_NO": "2023-1001",
|
|
"ATTORNEY": "Jane Doe, Esq.",
|
|
"TODAY": date.today().isoformat(),
|
|
"CLIENT_BALANCE": 2500.00,
|
|
"total_amount": 8750.00,
|
|
"payment_terms": "Net 30",
|
|
|
|
# Sample services for loop demonstration
|
|
"services": [
|
|
{
|
|
"description": "Estate Planning Consultation",
|
|
"date": "2023-11-15",
|
|
"hours": 2.5,
|
|
"rate": 350.00,
|
|
"amount": 875.00
|
|
},
|
|
{
|
|
"description": "Trust Document Preparation",
|
|
"date": "2023-11-20",
|
|
"hours": 6.0,
|
|
"rate": 350.00,
|
|
"amount": 2100.00
|
|
},
|
|
{
|
|
"description": "Document Review and Revision",
|
|
"date": "2023-11-25",
|
|
"hours": 3.5,
|
|
"rate": 350.00,
|
|
"amount": 1225.00
|
|
},
|
|
{
|
|
"description": "Client Meeting and Execution",
|
|
"date": "2023-11-30",
|
|
"hours": 2.0,
|
|
"rate": 350.00,
|
|
"amount": 700.00
|
|
}
|
|
],
|
|
|
|
# Sample payments for another loop
|
|
"payments": [
|
|
{"date": "2023-11-01", "amount": 1000.00, "method": "Check"},
|
|
{"date": "2023-11-15", "amount": 1500.00, "method": "Wire Transfer"}
|
|
]
|
|
}
|
|
|
|
print("Sample context data:")
|
|
print(json.dumps(sample_context, indent=2, default=str))
|
|
|
|
return sample_context
|
|
|
|
async def get_formatting_help(self):
|
|
"""Get and display formatting help"""
|
|
print("\n📚 Available Formatting Options...")
|
|
|
|
async with httpx.AsyncClient() as client:
|
|
response = await client.get(
|
|
f"{self.base_url}/api/templates/formatting-help",
|
|
headers=self.headers
|
|
)
|
|
|
|
if response.status_code == 200:
|
|
help_data = response.json()
|
|
|
|
print("\n🔧 Formatting Options:")
|
|
for category, info in help_data["formatting_options"].items():
|
|
print(f"\n {category.upper()}:")
|
|
print(f" Description: {info['description']}")
|
|
if 'syntax' in info:
|
|
print(f" Syntax: {info['syntax']}")
|
|
if 'examples' in info:
|
|
print(" Examples:")
|
|
for example in info['examples'][:2]: # Show first 2 examples
|
|
print(f" {example['input']} | {example['format']} → {example['output']}")
|
|
|
|
print("\n📝 Template Syntax:")
|
|
for syntax_type, syntax in help_data["template_syntax"].items():
|
|
print(f" {syntax_type}: {syntax}")
|
|
else:
|
|
print(f"❌ Error getting help: {response.text}")
|
|
|
|
async def create_sample_template_content(self):
|
|
"""Generate sample template content for demonstration"""
|
|
template_content = """
|
|
LEGAL SERVICES INVOICE
|
|
|
|
Client: {{ CLIENT_NAME | title }}
|
|
File Number: {{ FILE_NO }}
|
|
Attorney: {{ ATTORNEY }}
|
|
Date: {{ TODAY | date }}
|
|
|
|
{% if CLIENT_BALANCE > 0 %}
|
|
⚠️ NOTICE: Outstanding balance of {{ CLIENT_BALANCE | currency }}
|
|
{% endif %}
|
|
|
|
SERVICES PROVIDED:
|
|
{% for service in services %}
|
|
{{ service_index }}. {{ service.description }}
|
|
Date: {{ service.date | date:%m/%d/%Y }}
|
|
Hours: {{ service.hours | number:1 }}
|
|
Rate: {{ service.rate | currency }}
|
|
Amount: {{ service.amount | currency }}
|
|
{% endfor %}
|
|
|
|
SUBTOTAL: {{ format_currency(total_amount) }}
|
|
|
|
{% if payments %}
|
|
PAYMENTS RECEIVED:
|
|
{% for payment in payments %}
|
|
- {{ payment.date | date:%m/%d/%Y }}: {{ payment.amount | currency }} ({{ payment.method }})
|
|
{% endfor %}
|
|
{% endif %}
|
|
|
|
{% if payment_terms %}
|
|
PAYMENT TERMS: {{ payment_terms }}
|
|
{% else %}
|
|
Payment due within 30 days of invoice date.
|
|
{% endif %}
|
|
|
|
{% if CLIENT_BALANCE > 1000 %}
|
|
Please remit payment immediately to avoid service interruption.
|
|
{% else %}
|
|
Thank you for your prompt payment.
|
|
{% endif %}
|
|
|
|
Generated on {{ TODAY | date }} by the Delphi Database System
|
|
"""
|
|
|
|
print("\n📄 Sample Template Content:")
|
|
print("=" * 60)
|
|
print(template_content)
|
|
print("=" * 60)
|
|
|
|
return template_content
|
|
|
|
async def run_demonstration(self):
|
|
"""Run the complete demonstration"""
|
|
print("🚀 Advanced Template Features Demonstration")
|
|
print("=" * 50)
|
|
|
|
# Authenticate
|
|
if not await self.authenticate():
|
|
return
|
|
|
|
# Show available formatting options
|
|
await self.get_formatting_help()
|
|
|
|
# Test individual formatting functions
|
|
await self.test_variable_formatting()
|
|
|
|
# Show sample template and context
|
|
context = await self.demonstrate_template_features()
|
|
template_content = await self.create_sample_template_content()
|
|
|
|
print("\n✨ This demonstrates the following advanced features:")
|
|
print(" • Conditional sections ({% if %} blocks)")
|
|
print(" • Loop sections ({% for %} blocks)")
|
|
print(" • Variable formatting ({{ var | format }})")
|
|
print(" • Template functions ({{ format_currency() }})")
|
|
print(" • Rich context data with nested objects")
|
|
|
|
print("\n🔄 To use these features in your application:")
|
|
print(" 1. Create a DOCX template with the syntax above")
|
|
print(" 2. Upload it via /api/templates/upload")
|
|
print(" 3. Generate documents via /api/templates/{id}/generate-advanced")
|
|
print(" 4. Optionally convert to PDF by setting output_format: 'PDF'")
|
|
|
|
print("\n✅ Advanced template features are ready to use!")
|
|
|
|
|
|
async def main():
|
|
"""Main demonstration function"""
|
|
demo = AdvancedTemplateExample()
|
|
await demo.run_demonstration()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
print("Advanced Template Features Example")
|
|
print("Make sure the Delphi Database server is running on http://localhost:8000")
|
|
print()
|
|
|
|
try:
|
|
asyncio.run(main())
|
|
except KeyboardInterrupt:
|
|
print("\n👋 Demonstration interrupted")
|
|
except Exception as e:
|
|
print(f"\n❌ Error: {e}")
|