const express = require('express'); const router = express.Router(); const { Service } = require('../models'); // Get all services for calculator router.get('/services', async (req, res) => { try { const services = await Service.findAll({ where: { isActive: true }, attributes: ['id', 'name', 'pricing', 'category', 'features', 'estimatedTime'], order: [['category', 'ASC'], ['name', 'ASC']] }); const servicesByCategory = services.reduce((acc, service) => { if (!acc[service.category]) { acc[service.category] = []; } acc[service.category].push(service); return acc; }, {}); res.json({ success: true, services: servicesByCategory, allServices: services }); } catch (error) { console.error('Calculator services error:', error); res.status(500).json({ success: false, message: 'Error fetching services' }); } }); // Calculate project estimate router.post('/calculate', async (req, res) => { try { const { selectedServices = [], projectComplexity = 'medium', timeline = 'standard', additionalFeatures = [], customRequirements = '' } = req.body; if (!selectedServices.length) { return res.status(400).json({ success: false, message: 'Please select at least one service' }); } // Get selected services details const services = await Service.findAll({ where: { id: selectedServices, isActive: true } }); if (services.length !== selectedServices.length) { return res.status(400).json({ success: false, message: 'Some selected services are not available' }); } // Calculate base cost let baseCost = 0; let totalTime = 0; // in days services.forEach(service => { baseCost += service.pricing.basePrice; totalTime += (service.estimatedTime.min + service.estimatedTime.max) / 2; }); // Apply complexity multiplier const complexityMultipliers = { 'simple': 0.7, 'medium': 1.0, 'complex': 1.5, 'enterprise': 2.0 }; const complexityMultiplier = complexityMultipliers[projectComplexity] || 1.0; // Apply timeline multiplier const timelineMultipliers = { 'rush': 1.8, // Less than 2 weeks 'fast': 1.4, // 2-4 weeks 'standard': 1.0, // 1-3 months 'flexible': 0.8 // 3+ months }; const timelineMultiplier = timelineMultipliers[timeline] || 1.0; // Additional features cost const featureCosts = { 'seo-optimization': 300000, 'analytics-setup': 150000, 'social-integration': 200000, 'payment-gateway': 500000, 'multilingual': 400000, 'admin-panel': 600000, 'api-integration': 350000, 'mobile-responsive': 250000, 'ssl-certificate': 100000, 'backup-system': 200000 }; let additionalCost = 0; additionalFeatures.forEach(feature => { additionalCost += featureCosts[feature] || 0; }); // Custom requirements cost (estimated based on description length and complexity) let customCost = 0; if (customRequirements && customRequirements.length > 50) { customCost = Math.min(customRequirements.length * 1000, 1000000); // Max 1M KRW } // Calculate final estimate const subtotal = baseCost * complexityMultiplier * timelineMultiplier; const total = subtotal + additionalCost + customCost; // Calculate time estimate const timeMultiplier = complexityMultiplier * timelineMultiplier; const estimatedDays = Math.ceil(totalTime * timeMultiplier); const estimatedWeeks = Math.ceil(estimatedDays / 7); // Create price ranges (±20%) const minPrice = Math.round(total * 0.8); const maxPrice = Math.round(total * 1.2); // Breakdown const breakdown = { baseServices: Math.round(baseCost), complexityAdjustment: Math.round(baseCost * (complexityMultiplier - 1)), timelineAdjustment: Math.round(baseCost * complexityMultiplier * (timelineMultiplier - 1)), additionalFeatures: additionalCost, customRequirements: customCost, subtotal: Math.round(subtotal), total: Math.round(total) }; const result = { success: true, estimate: { total: Math.round(total), range: { min: minPrice, max: maxPrice, formatted: `₩${minPrice.toLocaleString()} - ₩${maxPrice.toLocaleString()}` }, breakdown, timeline: { days: estimatedDays, weeks: estimatedWeeks, formatted: estimatedWeeks === 1 ? '1 week' : `${estimatedWeeks} weeks` }, currency: 'KRW', confidence: calculateConfidence(services.length, projectComplexity, customRequirements), recommendations: generateRecommendations(projectComplexity, timeline, services) }, selectedServices: services.map(s => ({ id: s._id, name: s.name, category: s.category, basePrice: s.pricing.basePrice })), calculatedAt: new Date() }; res.json(result); } catch (error) { console.error('Calculator calculation error:', error); res.status(500).json({ success: false, message: 'Error calculating estimate' }); } }); // Helper function to calculate confidence level function calculateConfidence(serviceCount, complexity, customRequirements) { let confidence = 85; // Base confidence // Adjust based on service count if (serviceCount === 1) confidence += 10; else if (serviceCount > 5) confidence -= 10; // Adjust based on complexity if (complexity === 'simple') confidence += 10; else if (complexity === 'enterprise') confidence -= 15; // Adjust based on custom requirements if (customRequirements && customRequirements.length > 200) { confidence -= 20; } return Math.max(60, Math.min(95, confidence)); } // Helper function to generate recommendations function generateRecommendations(complexity, timeline, services) { const recommendations = []; if (complexity === 'enterprise' && timeline === 'rush') { recommendations.push('Consider extending timeline for enterprise-level projects to ensure quality'); } if (services.length > 6) { recommendations.push('Consider breaking down into phases for better project management'); } if (timeline === 'flexible') { recommendations.push('Flexible timeline allows for better cost optimization and quality assurance'); } const hasDesign = services.some(s => s.category === 'design'); const hasDevelopment = services.some(s => s.category === 'development'); if (hasDevelopment && !hasDesign) { recommendations.push('Consider adding UI/UX design services for better user experience'); } return recommendations; } // Get pricing guidelines router.get('/pricing-guide', async (req, res) => { try { const pricingGuide = { serviceCategories: { 'development': { name: 'Web Development', priceRange: '₩500,000 - ₩5,000,000', description: 'Custom web applications and websites' }, 'design': { name: 'UI/UX Design', priceRange: '₩300,000 - ₩2,000,000', description: 'User interface and experience design' }, 'marketing': { name: 'Digital Marketing', priceRange: '₩200,000 - ₩1,500,000', description: 'SEO, social media, and online marketing' }, 'consulting': { name: 'Technical Consulting', priceRange: '₩150,000 - ₩1,000,000', description: 'Technology strategy and consultation' } }, complexityFactors: { 'simple': { name: 'Simple Project', multiplier: '0.7x', description: 'Basic functionality, standard design' }, 'medium': { name: 'Medium Project', multiplier: '1.0x', description: 'Moderate complexity, custom features' }, 'complex': { name: 'Complex Project', multiplier: '1.5x', description: 'Advanced features, integrations' }, 'enterprise': { name: 'Enterprise Project', multiplier: '2.0x', description: 'Large scale, high complexity' } }, timelineImpact: { 'rush': { name: 'Rush (< 2 weeks)', multiplier: '+80%', description: 'Requires overtime and priority handling' }, 'fast': { name: 'Fast (2-4 weeks)', multiplier: '+40%', description: 'Accelerated timeline' }, 'standard': { name: 'Standard (1-3 months)', multiplier: 'Standard', description: 'Normal project timeline' }, 'flexible': { name: 'Flexible (3+ months)', multiplier: '-20%', description: 'Extended timeline allows optimization' } } }; res.json({ success: true, pricingGuide }); } catch (error) { console.error('Pricing guide error:', error); res.status(500).json({ success: false, message: 'Error fetching pricing guide' }); } }); module.exports = router;