feat(pdf): migrate PDF generation to @mintel/pdf package
Some checks failed
Build & Deploy / 🔍 Prepare (push) Successful in 7s
Build & Deploy / 🧪 QA (push) Failing after 1m3s
Build & Deploy / 🏗️ Build (push) Failing after 3m5s
Build & Deploy / 🚀 Deploy (push) Has been skipped
Build & Deploy / 🩺 Health Check (push) Has been skipped
Build & Deploy / 🔔 Notify (push) Successful in 2s
Some checks failed
Build & Deploy / 🔍 Prepare (push) Successful in 7s
Build & Deploy / 🧪 QA (push) Failing after 1m3s
Build & Deploy / 🏗️ Build (push) Failing after 3m5s
Build & Deploy / 🚀 Deploy (push) Has been skipped
Build & Deploy / 🩺 Health Check (push) Has been skipped
Build & Deploy / 🔔 Notify (push) Successful in 2s
This commit is contained in:
@@ -1,224 +0,0 @@
|
||||
import { FormState, Position, Totals } from "./types";
|
||||
import {
|
||||
FEATURE_LABELS,
|
||||
FUNCTION_LABELS,
|
||||
API_LABELS,
|
||||
PAGE_LABELS,
|
||||
} from "./constants";
|
||||
|
||||
export function calculateTotals(state: FormState, pricing: any): Totals {
|
||||
if (state.projectType !== "website") {
|
||||
return {
|
||||
totalPrice: 0,
|
||||
monthlyPrice: 0,
|
||||
totalPagesCount: 0,
|
||||
totalFeatures: 0,
|
||||
totalFunctions: 0,
|
||||
totalApis: 0,
|
||||
languagesCount: 0,
|
||||
};
|
||||
}
|
||||
|
||||
const sitemapPagesCount =
|
||||
state.sitemap?.reduce(
|
||||
(acc: number, cat: any) => acc + (cat.pages?.length || 0),
|
||||
0,
|
||||
) || 0;
|
||||
const totalPagesCount = Math.max(
|
||||
(state.selectedPages?.length || 0) +
|
||||
(state.otherPages?.length || 0) +
|
||||
(state.otherPagesCount || 0),
|
||||
sitemapPagesCount,
|
||||
);
|
||||
|
||||
const totalFeatures =
|
||||
(state.features?.length || 0) +
|
||||
(state.otherFeatures?.length || 0) +
|
||||
(state.otherFeaturesCount || 0);
|
||||
const totalFunctions =
|
||||
(state.functions?.length || 0) +
|
||||
(state.otherFunctions?.length || 0) +
|
||||
(state.otherFunctionsCount || 0);
|
||||
const totalApis =
|
||||
(state.apiSystems?.length || 0) +
|
||||
(state.otherTech?.length || 0) +
|
||||
(state.otherTechCount || 0);
|
||||
|
||||
let total = pricing.BASE_WEBSITE;
|
||||
total += totalPagesCount * pricing.PAGE;
|
||||
total += totalFeatures * pricing.FEATURE;
|
||||
total += totalFunctions * pricing.FUNCTION;
|
||||
total += totalApis * pricing.API_INTEGRATION;
|
||||
total += (state.newDatasets || 0) * pricing.NEW_DATASET;
|
||||
|
||||
if (state.cmsSetup) {
|
||||
total += Math.max(1, totalFeatures) * pricing.CMS_CONNECTION_PER_FEATURE;
|
||||
}
|
||||
|
||||
const languagesCount = state.languagesList?.length || 1;
|
||||
if (languagesCount > 1) {
|
||||
total *= 1 + (languagesCount - 1) * 0.2;
|
||||
}
|
||||
|
||||
const monthlyPrice =
|
||||
pricing.HOSTING_MONTHLY +
|
||||
(state.storageExpansion || 0) * pricing.STORAGE_EXPANSION_MONTHLY;
|
||||
|
||||
return {
|
||||
totalPrice: Math.round(total),
|
||||
monthlyPrice: Math.round(monthlyPrice),
|
||||
totalPagesCount,
|
||||
totalFeatures,
|
||||
totalFunctions,
|
||||
totalApis,
|
||||
languagesCount,
|
||||
};
|
||||
}
|
||||
|
||||
export function calculatePositions(state: FormState, pricing: any): Position[] {
|
||||
const positions: Position[] = [];
|
||||
let pos = 1;
|
||||
|
||||
if (state.projectType === "website") {
|
||||
positions.push({
|
||||
pos: pos++,
|
||||
title: "Das technische Fundament",
|
||||
desc: "Projekt-Setup, Infrastruktur, Hosting-Bereitstellung, Grundstruktur & Design-Vorlage, technisches SEO-Basics, Analytics.",
|
||||
qty: 1,
|
||||
price: pricing.BASE_WEBSITE,
|
||||
});
|
||||
|
||||
const sitemapPagesCount =
|
||||
state.sitemap?.reduce(
|
||||
(acc: number, cat: any) => acc + (cat.pages?.length || 0),
|
||||
0,
|
||||
) || 0;
|
||||
const totalPagesCount = Math.max(
|
||||
(state.selectedPages?.length || 0) +
|
||||
(state.otherPages?.length || 0) +
|
||||
(state.otherPagesCount || 0),
|
||||
sitemapPagesCount,
|
||||
);
|
||||
|
||||
const allPages = [
|
||||
...(state.selectedPages || []).map((p: string) => PAGE_LABELS[p] || p),
|
||||
...(state.otherPages || []),
|
||||
...(state.sitemap?.flatMap((cat: any) =>
|
||||
cat.pages?.map((p: any) => p.title),
|
||||
) || []),
|
||||
];
|
||||
|
||||
// Deduplicate labels
|
||||
const uniquePages = Array.from(new Set(allPages));
|
||||
|
||||
positions.push({
|
||||
pos: pos++,
|
||||
title: "Individuelle Seiten",
|
||||
desc: `Gestaltung und Umsetzung von ${totalPagesCount} individuellen Seiten-Layouts (${uniquePages.join(", ")}).`,
|
||||
qty: totalPagesCount,
|
||||
price: totalPagesCount * pricing.PAGE,
|
||||
});
|
||||
|
||||
if (state.features.length > 0 || (state.otherFeatures?.length || 0) > 0) {
|
||||
const allFeatures = [
|
||||
...state.features.map((f: string) => FEATURE_LABELS[f] || f),
|
||||
...(state.otherFeatures || []),
|
||||
];
|
||||
positions.push({
|
||||
pos: pos++,
|
||||
title: "System-Module (Features)",
|
||||
desc: `Implementierung funktionaler Bereiche: ${allFeatures.join(", ")}. Inklusive Datenstruktur und Darstellung.`,
|
||||
qty: allFeatures.length,
|
||||
price: allFeatures.length * pricing.FEATURE,
|
||||
});
|
||||
}
|
||||
|
||||
if (state.functions.length > 0 || (state.otherFunctions?.length || 0) > 0) {
|
||||
const allFunctions = [
|
||||
...state.functions.map((f: string) => FUNCTION_LABELS[f] || f),
|
||||
...(state.otherFunctions || []),
|
||||
];
|
||||
positions.push({
|
||||
pos: pos++,
|
||||
title: "Logik-Funktionen",
|
||||
desc: `Implementierung technischer Logik: ${allFunctions.join(", ")}.`,
|
||||
qty: allFunctions.length,
|
||||
price: allFunctions.length * pricing.FUNCTION,
|
||||
});
|
||||
}
|
||||
|
||||
if (state.apiSystems.length > 0 || (state.otherTech?.length || 0) > 0) {
|
||||
const allApis = [
|
||||
...state.apiSystems.map((a: string) => API_LABELS[a] || a),
|
||||
...(state.otherTech || []),
|
||||
];
|
||||
positions.push({
|
||||
pos: pos++,
|
||||
title: "Schnittstellen (API)",
|
||||
desc: `Anbindung externer Systeme zur Datensynchronisation: ${allApis.join(", ")}.`,
|
||||
qty: allApis.length,
|
||||
price: allApis.length * pricing.API_INTEGRATION,
|
||||
});
|
||||
}
|
||||
|
||||
if (state.cmsSetup) {
|
||||
const totalFeatures =
|
||||
state.features.length +
|
||||
(state.otherFeatures?.length || 0) +
|
||||
(state.otherFeaturesCount || 0);
|
||||
const qty = Math.max(1, totalFeatures);
|
||||
positions.push({
|
||||
pos: pos++,
|
||||
title: "Inhalts-Verwaltung",
|
||||
desc: "Anbindung der System-Module an das Redaktions-System zur eigenständigen Pflege von Inhalten.",
|
||||
qty: qty,
|
||||
price: qty * pricing.CMS_CONNECTION_PER_FEATURE,
|
||||
});
|
||||
}
|
||||
|
||||
if (state.newDatasets > 0) {
|
||||
positions.push({
|
||||
pos: pos++,
|
||||
title: "Inhaltliche Initial-Pflege",
|
||||
desc: `Manuelle Übernahme und Aufbereitung von ${state.newDatasets} Datensätzen (Produkte, Artikel) in das Zielsystem.`,
|
||||
qty: state.newDatasets,
|
||||
price: state.newDatasets * pricing.NEW_DATASET,
|
||||
});
|
||||
}
|
||||
|
||||
const languagesCount = state.languagesList.length || 1;
|
||||
if (languagesCount > 1) {
|
||||
const subtotal = positions.reduce((sum, p) => sum + p.price, 0);
|
||||
const factorPrice = subtotal * ((languagesCount - 1) * 0.2);
|
||||
|
||||
positions.push({
|
||||
pos: pos++,
|
||||
title: "Mehrsprachigkeit",
|
||||
desc: `Erweiterung des Systems auf ${languagesCount} Sprachen (Struktur & Logik).`,
|
||||
qty: languagesCount,
|
||||
price: Math.round(factorPrice),
|
||||
});
|
||||
}
|
||||
|
||||
const monthlyRate =
|
||||
pricing.HOSTING_MONTHLY +
|
||||
state.storageExpansion * pricing.STORAGE_EXPANSION_MONTHLY;
|
||||
positions.push({
|
||||
pos: pos++,
|
||||
title: "Sorglos Betrieb (1 Jahr)",
|
||||
desc: `Inklusive 1 Jahr Sicherung des technischen Betriebs, Hosting, Instandhaltung, Sicherheits-Updates und techn. Support gemäß AGB Punkt 7a.`,
|
||||
qty: 1,
|
||||
price: monthlyRate * 12,
|
||||
});
|
||||
} else {
|
||||
positions.push({
|
||||
pos: pos++,
|
||||
title: "Web App / Software Entwicklung",
|
||||
desc: "Individuelle Software-Entwicklung nach Aufwand. Abrechnung erfolgt auf Stundenbasis.",
|
||||
qty: 1,
|
||||
price: 0,
|
||||
});
|
||||
}
|
||||
|
||||
return positions;
|
||||
}
|
||||
@@ -1,3 +1,2 @@
|
||||
export * from './constants';
|
||||
export * from './calculator';
|
||||
export * from './types';
|
||||
export * from "./constants";
|
||||
export * from "./types";
|
||||
|
||||
Reference in New Issue
Block a user