Fix #44 with Handlebars Templates

This commit is contained in:
2026-03-21 17:05:04 +01:00
parent 55bb2589a4
commit e3a1636018
3 changed files with 33 additions and 8 deletions

View File

@@ -1,6 +1,5 @@
import dayjs from "dayjs"; import dayjs from "dayjs";
import quarterOfYear from "dayjs/plugin/quarterOfYear"; import quarterOfYear from "dayjs/plugin/quarterOfYear";
import Handlebars from "handlebars";
import axios from "axios"; import axios from "axios";
import { eq, inArray, and } from "drizzle-orm"; // Drizzle Operatoren import { eq, inArray, and } from "drizzle-orm"; // Drizzle Operatoren
@@ -10,6 +9,7 @@ import { saveFile } from "../utils/files";
import {FastifyInstance} from "fastify"; import {FastifyInstance} from "fastify";
import {useNextNumberRangeNumber} from "../utils/functions"; import {useNextNumberRangeNumber} from "../utils/functions";
import {createInvoicePDF} from "../utils/pdf"; // Achtung: Muss Node.js Buffer unterstützen! import {createInvoicePDF} from "../utils/pdf"; // Achtung: Muss Node.js Buffer unterstützen!
import { documentTemplateHandlebars } from "../utils/handlebars";
dayjs.extend(quarterOfYear); dayjs.extend(quarterOfYear);
@@ -609,8 +609,8 @@ export function getDocumentDataBackend(
}; };
}; };
const templateStartText = Handlebars.compile(itemInfo.startText || ""); const templateStartText = documentTemplateHandlebars.compile(itemInfo.startText || "");
const templateEndText = Handlebars.compile(itemInfo.endText || ""); const templateEndText = documentTemplateHandlebars.compile(itemInfo.endText || "");
// --- 6. Title Sums Formatting --- // --- 6. Title Sums Formatting ---
let returnTitleSums: Record<string, string> = {}; let returnTitleSums: Record<string, string> = {};

View File

@@ -1,9 +1,9 @@
<script setup> <script setup>
import dayjs from "dayjs" import dayjs from "dayjs"
import Handlebars from "handlebars"
import { v4 as uuidv4 } from 'uuid'; import { v4 as uuidv4 } from 'uuid';
import {useFunctions} from "~/composables/useFunctions.js"; import {useFunctions} from "~/composables/useFunctions.js";
import EntityModalButtons from "~/components/EntityModalButtons.vue"; import EntityModalButtons from "~/components/EntityModalButtons.vue";
import { documentTemplateHandlebars } from "~/utils/handlebars";
const dataStore = useDataStore() const dataStore = useDataStore()
const profileStore = useProfileStore() const profileStore = useProfileStore()
@@ -1098,8 +1098,8 @@ const getDocumentData = async () => {
}) })
//Compile Start & EndText //Compile Start & EndText
const templateStartText = Handlebars.compile(itemInfo.value.startText); const templateStartText = documentTemplateHandlebars.compile(itemInfo.value.startText);
const templateEndText = Handlebars.compile(itemInfo.value.endText); const templateEndText = documentTemplateHandlebars.compile(itemInfo.value.endText);
const generateContext = (itemInfo, contactData) => { const generateContext = (itemInfo, contactData) => {
return { return {

View File

@@ -31,6 +31,12 @@ const variableDefinitions = [
{ key: '{{lohnkosten}}', label: 'Lohnkosten', desc: 'Ausgewiesene Lohnkosten' }, { key: '{{lohnkosten}}', label: 'Lohnkosten', desc: 'Ausgewiesene Lohnkosten' },
] ]
const conditionalExamples = [
'{{#if vorname}}Hallo {{vorname}},{{/if}}',
'{{#if (eq zahlungsart "Überweisung")}}Bitte überweisen Sie den Betrag.{{/if}}',
'{{#if (gt zahlungsziel_in_tagen 14)}}Vielen Dank für Ihre Zahlung innerhalb des erweiterten Zahlungsziels.{{/if}}',
]
// --- Shortcuts --- // --- Shortcuts ---
defineShortcuts({ defineShortcuts({
'+': () => openModal() '+': () => openModal()
@@ -148,7 +154,7 @@ const getDocLabel = (type) => {
color="primary" color="primary"
variant="soft" variant="soft"
title="Platzhalter nutzen" title="Platzhalter nutzen"
description="Nutzen Sie die Variablen im Editor, um dynamische Inhalte (wie Kundennamen) automatisch einzufügen." description="Nutzen Sie Variablen und Bedingungen im Editor, um dynamische Inhalte automatisch einzufügen."
class="mb-4 mx-5 mt-2" class="mb-4 mx-5 mt-2"
/> />
@@ -313,6 +319,25 @@ const getDocLabel = (type) => {
<UIcon name="i-heroicons-plus-circle" class="w-5 h-5 text-gray-300 group-hover:text-primary-500"/> <UIcon name="i-heroicons-plus-circle" class="w-5 h-5 text-gray-300 group-hover:text-primary-500"/>
</button> </button>
</div> </div>
<div class="mt-6">
<h5 class="text-sm font-semibold mb-2 flex items-center gap-2">
<UIcon name="i-heroicons-code-bracket"/>
Bedingungen
</h5>
<p class="text-xs text-gray-500 mb-3">
Unterstuetzt sind zum Beispiel `eq`, `ne`, `gt`, `gte`, `lt`, `lte`, `and`, `or`, `not` und `includes`.
</p>
<div class="flex flex-col gap-2">
<code
v-for="example in conditionalExamples"
:key="example"
class="text-xs whitespace-pre-wrap break-words rounded bg-white dark:bg-gray-900 px-2 py-1.5 border border-gray-200 dark:border-gray-700"
>
{{ example }}
</code>
</div>
</div>
</div> </div>
</div> </div>
@@ -349,4 +374,4 @@ const getDocLabel = (type) => {
</template> </template>
<style scoped> <style scoped>
</style> </style>