Garage Door OS Docs
AI & Estimating

Garage Door Quote Tool

Implementation guide for the visual garage door quote builder and AI-assisted pricing.
10 min read

Garage Door Quote Tool - Implementation Documentation

🚪 Overview

This document provides detailed implementation guidance for the Garage Door Quote Tool integrated into ServiceFlow Pro. The tool provides a comprehensive solution for garage door repair services to create, manage, and share professional quotes with customers.

🏗️ Architecture Overview

Database Schema

The tool extends ServiceFlow Pro with garage door-specific tables:
-- Core garage door entities
GarageDoorColor          -- Door colors with hex codes
GarageDoorStyle          -- Door styles with preview images
GarageDoorManufacturer   -- Door manufacturers
GarageDoorInsulation     -- Insulation types with R-values
GarageDoorMotor          -- Motor options and pricing
GarageDoorWindow         -- Window options

-- Pricing system
DoorPriceList            -- Base pricing by specifications
DoorMaster               -- Door configurations
DoorMarkup               -- Business-specific markup rates

-- Quote management
GarageDoorQuote          -- Main quote entity
DoorPicture              -- Visual assets for doors

-- Custom attributes
GarageDoorAttribute      -- Business-specific attributes
GarageDoorAttributeField -- Attribute fields
GarageDoorAttributeInputValue -- Attribute values

Key Features

  1. Visual Quote Builder - Interactive door configuration
  2. Real-time Pricing - Instant price calculations with markup
  3. Customer Links - Shareable quote links for customer review
  4. PDF Generation - Professional quote documents
  5. Mobile Integration - Field technician quote creation
  6. Business Rules - Customizable pricing rules per business

📋 Implementation Checklist

Phase 1: Database Setup ✅

  • Database schema design
  • Prisma schema integration
  • Migration files
  • Seed data creation
  • Index optimization

Phase 2: API Development ✅

  • Quote management endpoints
  • Pricing calculation service
  • Customer sharing endpoints
  • Conversion endpoints (job/estimate/invoice)
  • Validation schemas
  • Error handling

Phase 3: Web Interface ✅

  • Quote builder component
  • Visual door preview
  • Pricing breakdown
  • Customer quote view
  • Quote management pages
  • PDF generation
  • Email templates

Phase 4: Mobile Integration 🔄

  • Mobile quote creation
  • Offline functionality
  • Photo integration
  • Field measurements

Phase 5: Advanced Features 📋

  • AI-powered recommendations
  • Competitor pricing analysis
  • Bulk quote generation
  • Integration with job management

🔧 Configuration Guide

Business Settings

Each business can configure:
// Example business configuration
const businessConfig = {
  defaultMarkup: 1.25, // 25% markup
  availableVendors: ['vendor1', 'vendor2'],
  customAttributes: [
    { name: 'Installation Type', type: 'SELECT', options: ['New', 'Replacement'] },
    { name: 'Warranty Level', type: 'SELECT', options: ['Standard', 'Extended'] }
  ],
  pricingRules: {
    volumeDiscounts: true,
    seasonalPricing: false,
    competitorMatching: true
  }
}

Quote Templates

Professional PDF templates with customizable branding:
// PDF template configuration
const pdfConfig = {
  template: 'professional',
  branding: {
    logo: 'business-logo.png',
    colors: ['#1890ff', '#52c41a'],
    fonts: ['Arial', 'Times New Roman']
  },
  sections: [
    'header',
    'customer_info',
    'door_specifications',
    'pricing_breakdown',
    'terms_conditions',
    'footer'
  ]
}

🚀 Quick Start Guide

1. Database Setup

# Navigate to garage door tool directory
cd garage_door_quote_tool

# Run migrations
npx prisma migrate dev

# Seed sample data
npx prisma db seed

2. API Integration

# Install dependencies
npm install

# Start development server
npm run dev

3. Web Interface

# Navigate to web app
cd ../apps/web

# Add garage door routes
# Add to src/routes/index.tsx:
{
  path: '/garage-door-quotes',
  element: <GarageDoorQuotesPage />
}

# Start web app
npm run dev

4. Mobile Integration

# Navigate to mobile app
cd ../apps/mobile

# Add garage door screens
# Add to navigation
# Start mobile app
npm run dev

📊 API Reference

Quote Management

// Create quote
POST /api/garage-door-quotes
{
  length: 16,
  height: 8,
  colorId: "color_123",
  styleId: "style_456",
  insulationId: "insulation_789",
  hasWindows: false,
  manufacturerId: "manufacturer_abc",
  motorId: "motor_def",
  onePieceConversion: false,
  dumpFee: true,
  framingRequired: false,
  customerId: "customer_xyz",
  notes: "Customer prefers morning installation"
}

// Get quote
GET /api/garage-door-quotes/:id

// Update quote
PUT /api/garage-door-quotes/:id

// Delete quote
DELETE /api/garage-door-quotes/:id

Pricing

// Get pricing options
GET /api/garage-door-pricing/options

// Calculate price
POST /api/garage-door-pricing/calculate
{
  length: 16,
  height: 8,
  colorId: "color_123",
  styleId: "style_456",
  insulationId: "insulation_789",
  hasWindows: false,
  manufacturerId: "manufacturer_abc"
}

Customer Sharing

// Share quote
POST /api/garage-door-quotes/:id/share
{
  email: "customer@example.com",
  message: "Here's your garage door quote"
}

// Public quote view
GET /api/garage-door-quotes/:id/public?token=abc123

// Accept quote
POST /api/garage-door-quotes/:id/accept
{
  token: "abc123",
  customerInfo: {
    firstName: "John",
    lastName: "Doe",
    email: "john@example.com",
    phone: "555-0123"
  }
}

// Decline quote
POST /api/garage-door-quotes/:id/decline
{
  token: "abc123",
  reason: "Price too high"
}

Conversion

// Convert to job
POST /api/garage-door-quotes/:id/convert-to-job
{
  customerId: "customer_xyz",
  scheduledDate: "2025-01-15T09:00:00Z",
  notes: "Morning installation preferred"
}

// Convert to estimate
POST /api/garage-door-quotes/:id/convert-to-estimate
{
  customerId: "customer_xyz",
  validUntil: "2025-02-15T23:59:59Z",
  notes: "Valid for 30 days"
}

// Convert to invoice
POST /api/garage-door-quotes/:id/convert-to-invoice
{
  customerId: "customer_xyz",
  dueDate: "2025-01-30T23:59:59Z",
  notes: "Net 30 terms"
}

🎨 UI Components

Quote Builder

import { GarageDoorQuoteBuilder } from './components/GarageDoorQuoteBuilder'

<GarageDoorQuoteBuilder
  onSuccess={(quote) => {
    // Handle successful quote creation
    navigate(`/garage-door-quotes/${quote.id}`)
  }}
  onCancel={() => {
    // Handle cancellation
    navigate('/garage-door-quotes')
  }}
  initialData={{
    length: 16,
    height: 8,
    customerId: 'customer_123'
  }}
/>

Customer View

import { CustomerQuoteView } from './components/CustomerQuoteView'

<CustomerQuoteView
  quote={quote}
  onAccept={(customerInfo) => {
    // Handle quote acceptance
    acceptQuote(quote.id, customerInfo)
  }}
  onDecline={(reason) => {
    // Handle quote decline
    declineQuote(quote.id, reason)
  }}
/>

Door Preview

import { DoorPreview } from './components/DoorPreview'

<DoorPreview
  specifications={{
    length: 16,
    height: 8,
    color: 'White',
    style: 'Traditional',
    insulation: 'R-16',
    manufacturer: 'Clopay',
    hasWindows: true
  }}
/>

Pricing Breakdown

import { PricingBreakdown } from './components/PricingBreakdown'

<PricingBreakdown
  pricing={{
    baseCost: new Decimal(1200),
    markupRate: new Decimal(1.25),
    markupAmount: new Decimal(300),
    totalPrice: new Decimal(1500),
    optionsBreakdown: [
      {
        name: 'Motor',
        cost: new Decimal(250),
        description: 'Chamberlain 1/2 HP'
      }
    ],
    doorDescription: 'Clopay-Traditional, 16 X 8, R-16, White, Traditional, No Windows',
    modelCode: 'ModelGDD-1200MI123/'
  }}
/>

📱 Mobile Integration

Mobile Quote Creation

// Mobile quote builder
import { MobileQuoteBuilder } from './components/MobileQuoteBuilder'

<MobileQuoteBuilder
  onSuccess={(quote) => {
    // Handle successful quote creation
    navigation.navigate('QuoteDetail', { quoteId: quote.id })
  }}
  offlineMode={true}
  photoIntegration={true}
/>

Offline Functionality

// Offline quote storage
const offlineService = new OfflineService()

// Save quote offline
await offlineService.saveQuoteOffline(quote)

// Sync when online
await offlineService.syncPendingQuotes()

🔒 Security & Permissions

Access Control

// Business-scoped data access
const quotes = await db.garageDoorQuote.findMany({
  where: { businessId: user.businessId }
})

// User role permissions
const canCreateQuotes = user.roles.includes('ADMIN') || user.roles.includes('SALES')
const canViewPricing = user.roles.includes('ADMIN') || user.roles.includes('MANAGER')

Quote Sharing Security

// Secure share tokens
const shareToken = generateSecureToken()

// Token validation
const isValidToken = await validateShareToken(quoteId, token)

📈 Analytics & Reporting

Quote Analytics

// Quote statistics
const stats = await garageDoorQuoteService.getQuoteStats(businessId)

// Conversion rates
const conversionRate = (stats.acceptedQuotes / stats.totalQuotes) * 100

// Popular configurations
const popularConfigs = await getPopularDoorConfigurations(businessId)

Business Intelligence

// Revenue tracking
const revenue = await getQuoteRevenue(businessId, dateRange)

// Customer preferences
const preferences = await getCustomerPreferences(businessId)

// Market trends
const trends = await analyzeMarketTrends(businessId)

🚀 Deployment

Production Setup

# Environment variables
GARAGE_DOOR_QUOTE_ENABLED=true
GARAGE_DOOR_PDF_ENABLED=true
GARAGE_DOOR_SHARING_ENABLED=true
GARAGE_DOOR_EMAIL_ENABLED=true

# Database migration
npx prisma migrate deploy

# Build and deploy
npm run build
npm run deploy

Monitoring

// Quote generation metrics
const metrics = {
  quotesCreated: 150,
  quotesShared: 120,
  quotesAccepted: 45,
  conversionRate: 30,
  averageQuoteValue: 2500
}

// Performance monitoring
const performance = {
  averageResponseTime: 250,
  errorRate: 0.1,
  uptime: 99.9
}

🤝 Integration Points

ServiceFlow Pro Integration

// Customer management
const customer = await customerService.getById(customerId)
const customerQuotes = await garageDoorQuoteService.getQuotesByCustomer(customerId)

// Job creation
const job = await garageDoorQuoteService.convertToJob(quoteId, jobData)

// Invoice generation
const invoice = await garageDoorQuoteService.convertToInvoice(quoteId, invoiceData)

// Payment processing
const payment = await paymentService.processPayment(invoiceId, paymentData)

Third-party Services

// PDF generation
const pdf = await pdfService.generateQuotePDF(quote)

// Email notifications
await emailService.sendQuoteShareEmail(email, quoteData)

// SMS alerts
await smsService.sendQuoteNotification(phone, quoteData)

// Payment processing
const payment = await stripeService.processPayment(amount, paymentMethod)

📚 Testing Guide

Unit Tests

// Test pricing calculation
describe('GarageDoorPricingService', () => {
  it('should calculate correct pricing', async () => {
    const pricing = await pricingService.calculatePrice(businessId, quoteData)
    expect(pricing.totalPrice.toNumber()).toBe(1500)
  })
})

// Test quote creation
describe('GarageDoorQuoteService', () => {
  it('should create quote successfully', async () => {
    const quote = await quoteService.create(businessId, userId, quoteData)
    expect(quote.quoteNumber).toBeDefined()
  })
})

Integration Tests

// Test API endpoints
describe('Garage Door Quote API', () => {
  it('should create and retrieve quote', async () => {
    const quote = await createQuote(quoteData)
    const retrieved = await getQuote(quote.id)
    expect(retrieved.id).toBe(quote.id)
  })
})

E2E Tests

// Test complete workflow
describe('Garage Door Quote Workflow', () => {
  it('should create and share quote', async () => {
    await page.goto('/garage-door-quotes/new')
    await page.fill('[data-testid="length-input"]', '16')
    await page.fill('[data-testid="height-input"]', '8')
    await page.click('[data-testid="create-quote-button"]')
    await expect(page.locator('.ant-message-success')).toBeVisible()
  })
})

🆘 Troubleshooting

Common Issues

  1. Pricing not calculating
    • Check if all required fields are filled
    • Verify pricing data exists for the configuration
    • Check markup rates are configured
  2. Quote sharing not working
    • Verify share token generation
    • Check email service configuration
    • Validate share URL format
  3. Mobile offline sync issues
    • Check offline storage permissions
    • Verify sync queue implementation
    • Test network connectivity handling

Performance Optimization

  1. Database queries
    • Add indexes on frequently queried fields
    • Use pagination for large datasets
    • Implement query caching
  2. API responses
    • Compress large responses
    • Implement response caching
    • Use pagination for list endpoints
  3. Frontend performance
    • Lazy load components
    • Implement virtual scrolling for large lists
    • Optimize image loading

📞 Support

For technical support or feature requests:
  • Create an issue in the repository
  • Contact the development team
  • Check the troubleshooting guide
  • Review the API documentation

Version: 1.0.0
Last Updated: January 2025
Status: Active Development