feat: Centralize pricing calculations into a new calculateTotals utility function and Totals interface.
This commit is contained in:
@@ -4,7 +4,7 @@ import * as readline from 'node:readline/promises';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import { createElement } from 'react';
|
||||
import { renderToFile } from '@react-pdf/renderer';
|
||||
import { calculatePositions } from '../src/logic/pricing/calculator.js';
|
||||
import { calculatePositions, calculateTotals } from '../src/logic/pricing/calculator.js';
|
||||
import { CombinedQuotePDF } from '../src/components/CombinedQuotePDF.js';
|
||||
import { initialState, PRICING } from '../src/logic/pricing/constants.js';
|
||||
import { getTechDetails, getPrinciples } from '../src/logic/content-provider.js';
|
||||
@@ -35,9 +35,8 @@ async function main() {
|
||||
console.warn('⚠️ Missing recipient name or email. Document might look incomplete.');
|
||||
}
|
||||
|
||||
const totalPrice = calculateTotal(state);
|
||||
const monthlyPrice = calculateMonthly(state);
|
||||
const totalPagesCount = (state.selectedPages?.length || 0) + (state.otherPages?.length || 0) + (state.otherPagesCount || 0);
|
||||
const totals = calculateTotals(state, PRICING);
|
||||
const { totalPrice, monthlyPrice, totalPagesCount } = totals;
|
||||
|
||||
const finalOutputPath = generateDefaultPath(state);
|
||||
const outputDir = path.dirname(finalOutputPath);
|
||||
@@ -115,32 +114,6 @@ async function runWizard(state: any) {
|
||||
return state;
|
||||
}
|
||||
|
||||
function calculateTotal(state: any) {
|
||||
// Basic duplication of logic from ContactForm for consistency
|
||||
if (state.projectType !== 'website') return 0;
|
||||
const totalPagesCount = (state.selectedPages?.length || 0) + (state.otherPages?.length || 0) + (state.otherPagesCount || 0);
|
||||
let total = PRICING.BASE_WEBSITE;
|
||||
total += totalPagesCount * PRICING.PAGE;
|
||||
total += ((state.features?.length || 0) + (state.otherFeatures?.length || 0) + (state.otherFeaturesCount || 0)) * PRICING.FEATURE;
|
||||
total += ((state.functions?.length || 0) + (state.otherFunctions?.length || 0) + (state.otherFunctionsCount || 0)) * PRICING.FUNCTION;
|
||||
total += ((state.apiSystems?.length || 0) + (state.otherTech?.length || 0) + (state.otherTechCount || 0)) * PRICING.API_INTEGRATION;
|
||||
|
||||
if (state.cmsSetup) {
|
||||
total += PRICING.CMS_SETUP;
|
||||
total += ((state.features?.length || 0) + (state.otherFeatures?.length || 0) + (state.otherFeaturesCount || 0)) * PRICING.CMS_CONNECTION_PER_FEATURE;
|
||||
}
|
||||
|
||||
const languagesCount = state.languagesList?.length || 1;
|
||||
if (languagesCount > 1) {
|
||||
total *= (1 + (languagesCount - 1) * 0.2);
|
||||
}
|
||||
return Math.round(total);
|
||||
}
|
||||
|
||||
function calculateMonthly(state: any) {
|
||||
if (state.projectType !== 'website') return 0;
|
||||
return PRICING.HOSTING_MONTHLY + ((state.storageExpansion || 0) * PRICING.STORAGE_EXPANSION_MONTHLY);
|
||||
}
|
||||
|
||||
function generateDefaultPath(state: any) {
|
||||
const now = new Date();
|
||||
|
||||
Reference in New Issue
Block a user