chore: add remaining db migration and translation scripts
This commit is contained in:
@@ -0,0 +1,271 @@
|
||||
import { getPayload } from 'payload'
|
||||
import configPromise from '../src/payload.config'
|
||||
|
||||
const translations: Record<string, Record<string, any>> = {
|
||||
'uslugi': {
|
||||
en: {
|
||||
pageHeader: { title: "Comprehensive tax settlements in Germany", subtitle: "Professional tax return preparation, tax assessment verification, and ongoing support." },
|
||||
servicesDetailed: {
|
||||
title: "What we do",
|
||||
subtitle: "We provide reliable and comprehensive support at every stage of income tax settlement in Germany.",
|
||||
services: [
|
||||
{ title: "Tax return preparation (Einkommensteuererklärung)", description: "We prepare a complete tax return, taking into account all applicable allowances, deductible expenses, and deductions. We ensure maximum refund and full compliance with German law." },
|
||||
{ title: "Preliminary calculation of expected refund", description: "Before sending the documents to the tax office, we calculate the exact amount of the expected refund or potential surcharge. You know exactly what to expect." },
|
||||
{ title: "Tax assessment verification (Steuerbescheid)", description: "We thoroughly verify the received decision from the tax office for any errors by officials. We check if the office has included all reported costs and allowances." },
|
||||
{ title: "Filing appeals (Einspruch)", description: "In the event of an unfavorable or incorrect decision from the office, we prepare an official appeal and represent you in the clarification proceedings." },
|
||||
{ title: "Year-round tax consulting", description: "We remain at your disposal throughout the tax year. We answer questions, help in ongoing correspondence with the office and advise when life situations change." },
|
||||
{ title: "Advice on choosing a tax class (Steuerklasse)", description: "We advise on the optimal selection of tax classes for marriages and people working in Germany. We help to choose the variant (e.g. III/V or IV/IV) that will bring the greatest financial benefits." },
|
||||
{ title: "Allowances, subsidies and deductions", description: "We help in obtaining Kindergeld, Riester-Rente and correct deduction of the costs of maintaining a double household (doppelter Haushalt) and commuting to work (Pendlerpauschale)." }
|
||||
]
|
||||
},
|
||||
eligibility: {
|
||||
title: "For whom — scope of advisory powers under §4 No. 11 StBerG",
|
||||
subtitle: "As an advisory point of b.b.h. Lohnsteuerhilfeverein e.V. we operate strictly within statutory limits for tax assistance associations.",
|
||||
eligibleTitle: "Who can benefit from our help",
|
||||
limitationsTitle: "Permissible additional income (rental, capital, other)",
|
||||
limitationsText: "Persons earning additional income — advice is possible only if the total income from these sources does not exceed €18,000 (singles) or €36,000 (married couples).",
|
||||
excludedTitle: "Who is NOT covered by our services (statutory limit)",
|
||||
legalNotice: "Tax assistance is provided only to members of the b.b.h. Lohnsteuerhilfeverein e.V. according to § 4 No. 11 Steuerberatungsgesetz (StBerG).",
|
||||
eligibleItems: [
|
||||
{ text: "Employees (Arbeitnehmer) and temporary workers" },
|
||||
{ text: "Civil servants (Beamte)" },
|
||||
{ text: "Pensioners and retirees (Rentner und Pensionäre)" },
|
||||
{ text: "Unemployed persons and social benefit recipients" },
|
||||
{ text: "Recipients of family benefits (Kindergeld, Elterngeld) and alimony" }
|
||||
],
|
||||
excludedItems: [
|
||||
{ text: "Sole traders (Gewerbe)" },
|
||||
{ text: "Entrepreneurs, partnerships and self-employed (Selbständige)" },
|
||||
{ text: "Persons generating income from agriculture and forestry (Land- und Forstwirtschaft)" },
|
||||
{ text: "Persons with rental or capital income exceeding limits" }
|
||||
]
|
||||
}
|
||||
},
|
||||
de: {
|
||||
pageHeader: { title: "Umfassende Steuererklärungen in Deutschland", subtitle: "Professionelle Erstellung, Prüfung von Steuerbescheiden und laufende Unterstützung." },
|
||||
servicesDetailed: {
|
||||
title: "Was wir tun",
|
||||
subtitle: "Wir bieten zuverlässige und umfassende Unterstützung in jeder Phase der Einkommensteuererklärung in Deutschland.",
|
||||
services: [
|
||||
{ title: "Erstellung der Einkommensteuererklärung", description: "Wir erstellen eine vollständige Steuererklärung unter Berücksichtigung aller zustehenden Freibeträge, Werbungskosten und Abzüge. Wir sorgen für maximale Rückerstattung und volle Übereinstimmung mit deutschem Recht." },
|
||||
{ title: "Vorläufige Berechnung der erwarteten Rückerstattung", description: "Bevor wir die Dokumente an das Finanzamt senden, berechnen wir die genaue Höhe der erwarteten Rückerstattung oder einer möglichen Nachzahlung." },
|
||||
{ title: "Prüfung des Steuerbescheids", description: "Wir prüfen den erhaltenen Bescheid des Finanzamtes eingehend auf Fehler der Sachbearbeiter. Wir prüfen, ob das Amt alle gemeldeten Kosten und Freibeträge berücksichtigt hat." },
|
||||
{ title: "Einspruchsverfahren", description: "Im Falle eines unvorteilhaften oder falschen Bescheids des Amtes erstellen wir einen offiziellen Einspruch und vertreten Sie im Klärungsverfahren." },
|
||||
{ title: "Ganzjährige Steuerberatung", description: "Wir stehen Ihnen während des gesamten Steuerjahres zur Verfügung. Wir beantworten Fragen, helfen bei der laufenden Korrespondenz mit dem Amt und beraten bei Veränderungen der Lebenssituation." },
|
||||
{ title: "Beratung bei der Wahl der Steuerklasse", description: "Wir beraten bei der optimalen Wahl der Steuerklassen für Verheiratete und Arbeitnehmer in Deutschland. Wir helfen bei der Wahl der Variante (z. B. III/V oder IV/IV)." },
|
||||
{ title: "Freibeträge, Zuschüsse und Abzüge", description: "Wir helfen bei der Erlangung von Kindergeld, Riester-Rente und dem korrekten Abzug der Kosten für eine doppelte Haushaltsführung und Fahrtkosten zur Arbeit (Pendlerpauschale)." }
|
||||
]
|
||||
},
|
||||
eligibility: {
|
||||
title: "Für wen — Beratungsumfang nach §4 Nr. 11 StBerG",
|
||||
subtitle: "Als Beratungsstelle des b.b.h. Lohnsteuerhilfeverein e.V. arbeiten wir streng im Rahmen der gesetzlichen Befugnisse.",
|
||||
eligibleTitle: "Wer unsere Hilfe in Anspruch nehmen kann",
|
||||
limitationsTitle: "Zulässige Zusatzeinnahmen (Vermietung, Kapital, Sonstige)",
|
||||
limitationsText: "Personen mit Zusatzeinkünften — eine Beratung ist nur möglich, wenn die Gesamteinnahmen aus diesen Quellen 18.000 € (Alleinstehende) oder 36.000 € (Verheiratete) nicht überschreiten.",
|
||||
excludedTitle: "Wer NICHT unter unsere Leistungen fällt",
|
||||
legalNotice: "Die Hilfeleistung in Steuersachen erfolgt ausschließlich für Mitglieder des b.b.h. Lohnsteuerhilfeverein e.V. gem. § 4 Nr. 11 StBerG.",
|
||||
eligibleItems: [
|
||||
{ text: "Arbeitnehmer und Leiharbeiter" },
|
||||
{ text: "Beamte" },
|
||||
{ text: "Rentner und Pensionäre" },
|
||||
{ text: "Arbeitslose und Bezieher von Sozialleistungen" },
|
||||
{ text: "Bezieher von Familienleistungen (Kindergeld, Elterngeld) und Unterhalt" }
|
||||
],
|
||||
excludedItems: [
|
||||
{ text: "Gewerbetreibende" },
|
||||
{ text: "Unternehmer, Gesellschaften und Selbständige" },
|
||||
{ text: "Personen mit Einkünften aus Land- und Forstwirtschaft" },
|
||||
{ text: "Personen mit Miet- oder Kapitaleinkünften, die die Grenzen überschreiten" }
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
'jak-sie-umowic': {
|
||||
en: {
|
||||
pageHeader: { title: "How to make an appointment", subtitle: "Simple, transparent, and 100% remote tax settlement process. You can handle everything without leaving your home." },
|
||||
process: {
|
||||
title: "Settlement in 3 simple steps",
|
||||
subtitle: "We provide full support and clear communication at every stage.",
|
||||
steps: [
|
||||
{ title: "Message us on WhatsApp", description: "Contact us directly via WhatsApp or the form below to start and discuss the details of your tax situation." },
|
||||
{ title: "Hand over documents", description: "Send your income certificates (Lohnsteuerbescheinigung, EU/EWR), tax identification number (IdNr), and potential expense confirmations." },
|
||||
{ title: "Receive ready settlement for signature", description: "We prepare the complete declaration, calculate the expected refund, and send the ready document for your approval and signature." }
|
||||
]
|
||||
},
|
||||
contactInfo: { hours: "Mon-Fri: 9:00 - 17:00\nBy appointment" }
|
||||
},
|
||||
de: {
|
||||
pageHeader: { title: "Termin vereinbaren", subtitle: "Einfacher, transparenter und 100% digitaler Prozess der Steuererklärung. Alles von zu Hause aus." },
|
||||
process: {
|
||||
title: "Steuererklärung in 3 einfachen Schritten",
|
||||
subtitle: "Wir bieten volle Unterstützung und klare Kommunikation in jeder Phase.",
|
||||
steps: [
|
||||
{ title: "Auf WhatsApp schreiben", description: "Kontaktieren Sie uns direkt über WhatsApp oder das Formular unten, um zu beginnen und die Details zu besprechen." },
|
||||
{ title: "Dokumente übergeben", description: "Senden Sie uns Ihre Lohnsteuerbescheinigungen (ggf. EU/EWR), Steueridentifikationsnummer (IdNr) und mögliche Kostenbelege." },
|
||||
{ title: "Erklärung zur Unterschrift erhalten", description: "Wir erstellen die komplette Erklärung, berechnen die erwartete Erstattung und senden das fertige Dokument zur Freigabe und Unterschrift." }
|
||||
]
|
||||
},
|
||||
contactInfo: { hours: "Mo-Fr: 9:00 - 17:00\nNach Vereinbarung" }
|
||||
}
|
||||
},
|
||||
'o-nas': {
|
||||
en: {
|
||||
pageHeader: { title: "About Us", subtitle: "Over 20 years of reliable tax support for Poles working in Germany." },
|
||||
bio: {
|
||||
paragraphs: [
|
||||
{ text: "For over two decades, I have been helping Polish workers and specialists in Germany to safely, stress-free, and fully legally settle income taxes before the tax office." },
|
||||
{ text: "My goal is to take the burden of complicated German tax regulations off your shoulders. We conduct the entire process in Polish — from initial document analysis, through precise calculations of allowances, to verification of the final tax decision." }
|
||||
],
|
||||
credentials: [
|
||||
{ text: "Over 20 years of practice in German tax law" },
|
||||
{ text: "Beratungsstellenleiter at b.b.h. Lohnsteuerhilfeverein e.V." },
|
||||
{ text: "Full service in Polish and German" },
|
||||
{ text: "Maximizing tax refunds and zero formal stress" }
|
||||
]
|
||||
},
|
||||
team: {
|
||||
title: "Our Team",
|
||||
subtitle: "Meet the experts who are committed to your finances. Each of us brings years of experience to guarantee your peace of mind and safety.",
|
||||
members: [
|
||||
{ role: "Owner / Beratungsstellenleiter", description: "Long-time tax law practitioner specializing in consulting for Polish workers in Germany." }
|
||||
]
|
||||
}
|
||||
},
|
||||
de: {
|
||||
pageHeader: { title: "Über uns", subtitle: "Über 20 Jahre zuverlässige Steuerunterstützung für Polen, die in Deutschland arbeiten." },
|
||||
bio: {
|
||||
paragraphs: [
|
||||
{ text: "Seit über zwei Jahrzehnten helfe ich polnischen Arbeitnehmern und Fachkräften in Deutschland bei der sicheren, stressfreien und völlig legalen Erledigung der Einkommensteuer gegenüber dem Finanzamt." },
|
||||
{ text: "Mein Ziel ist es, Ihnen die Last der komplizierten deutschen Steuervorschriften von den Schultern zu nehmen. Wir führen den gesamten Prozess auf Polnisch durch — von der ersten Dokumentenanalyse über präzise Berechnungen von Freibeträgen bis hin zur Überprüfung des finalen Steuerbescheids." }
|
||||
],
|
||||
credentials: [
|
||||
{ text: "Über 20 Jahre Praxis im deutschen Steuerrecht" },
|
||||
{ text: "Beratungsstellenleiter im b.b.h. Lohnsteuerhilfeverein e.V." },
|
||||
{ text: "Vollständiger Service in Polnisch und Deutsch" },
|
||||
{ text: "Maximierung der Steuerrückerstattung und null formaler Stress" }
|
||||
]
|
||||
},
|
||||
team: {
|
||||
title: "Unser Team",
|
||||
subtitle: "Lernen Sie die Experten kennen, die sich für Ihre Finanzen einsetzen. Jeder von uns bringt jahrelange Erfahrung mit, um Ihre Ruhe und Sicherheit zu garantieren.",
|
||||
members: [
|
||||
{ role: "Inhaber / Beratungsstellenleiter", description: "Langjähriger Steuerrechtspraktiker mit Spezialisierung auf die Beratung polnischer Arbeitnehmer in Deutschland." }
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function run() {
|
||||
const payload = await getPayload({ config: configPromise })
|
||||
|
||||
const pages = await payload.find({ collection: 'pages', limit: 100, locale: 'pl' })
|
||||
|
||||
for (const page of pages.docs) {
|
||||
if (!translations[page.slug || '']) continue;
|
||||
|
||||
for (const loc of ['en', 'de'] as const) {
|
||||
const dbPage = await payload.findByID({ collection: 'pages', id: page.id, locale: loc })
|
||||
if (!dbPage || !dbPage.layout) continue;
|
||||
|
||||
const tPage = translations[page.slug!][loc];
|
||||
let modified = false;
|
||||
|
||||
const layout = dbPage.layout.map((block: any) => {
|
||||
// preserve IDs
|
||||
for (const key of Object.keys(block)) {
|
||||
if (block[key] && typeof block[key] === 'object' && block[key].id !== undefined) {
|
||||
block[key] = block[key].id
|
||||
}
|
||||
}
|
||||
|
||||
if (block.blockType === 'pageHeader' && tPage.pageHeader) {
|
||||
block.title = tPage.pageHeader.title;
|
||||
block.subtitle = tPage.pageHeader.subtitle;
|
||||
modified = true;
|
||||
}
|
||||
|
||||
if (block.blockType === 'servicesDetailed' && tPage.servicesDetailed) {
|
||||
block.title = tPage.servicesDetailed.title;
|
||||
block.subtitle = tPage.servicesDetailed.subtitle;
|
||||
block.services = block.services.map((s: any, i: number) => ({
|
||||
...s,
|
||||
title: tPage.servicesDetailed.services[i]?.title || s.title,
|
||||
description: tPage.servicesDetailed.services[i]?.description || s.description
|
||||
}))
|
||||
modified = true;
|
||||
}
|
||||
|
||||
if (block.blockType === 'eligibility' && tPage.eligibility) {
|
||||
block.title = tPage.eligibility.title;
|
||||
block.subtitle = tPage.eligibility.subtitle;
|
||||
block.eligibleTitle = tPage.eligibility.eligibleTitle;
|
||||
block.limitationsTitle = tPage.eligibility.limitationsTitle;
|
||||
block.limitationsText = tPage.eligibility.limitationsText;
|
||||
block.excludedTitle = tPage.eligibility.excludedTitle;
|
||||
block.legalNotice = tPage.eligibility.legalNotice;
|
||||
|
||||
block.eligibleItems = block.eligibleItems.map((s: any, i: number) => ({
|
||||
...s, text: tPage.eligibility.eligibleItems[i]?.text || s.text
|
||||
}))
|
||||
block.excludedItems = block.excludedItems.map((s: any, i: number) => ({
|
||||
...s, text: tPage.eligibility.excludedItems[i]?.text || s.text
|
||||
}))
|
||||
modified = true;
|
||||
}
|
||||
|
||||
if (block.blockType === 'process' && tPage.process) {
|
||||
block.title = tPage.process.title;
|
||||
block.subtitle = tPage.process.subtitle;
|
||||
block.steps = block.steps.map((s: any, i: number) => ({
|
||||
...s,
|
||||
title: tPage.process.steps[i]?.title || s.title,
|
||||
description: tPage.process.steps[i]?.description || s.description
|
||||
}))
|
||||
modified = true;
|
||||
}
|
||||
|
||||
if (block.blockType === 'bio' && tPage.bio) {
|
||||
block.paragraphs = block.paragraphs.map((s: any, i: number) => ({
|
||||
...s, text: tPage.bio.paragraphs[i]?.text || s.text
|
||||
}))
|
||||
block.credentials = block.credentials.map((s: any, i: number) => ({
|
||||
...s, text: tPage.bio.credentials[i]?.text || s.text
|
||||
}))
|
||||
modified = true;
|
||||
}
|
||||
|
||||
if (block.blockType === 'team' && tPage.team) {
|
||||
block.title = tPage.team.title;
|
||||
block.subtitle = tPage.team.subtitle;
|
||||
block.members = block.members.map((s: any, i: number) => ({
|
||||
...s,
|
||||
role: tPage.team.members[i]?.role || s.role,
|
||||
description: tPage.team.members[i]?.description || s.description
|
||||
}))
|
||||
modified = true;
|
||||
}
|
||||
|
||||
if (block.blockType === 'contactInfo' && tPage.contactInfo) {
|
||||
block.hours = tPage.contactInfo.hours;
|
||||
modified = true;
|
||||
}
|
||||
|
||||
return block;
|
||||
});
|
||||
|
||||
if (modified) {
|
||||
await payload.update({
|
||||
collection: 'pages',
|
||||
id: page.id,
|
||||
locale: loc,
|
||||
data: { layout }
|
||||
})
|
||||
console.log(`Fully translated ${page.slug} to ${loc}`)
|
||||
}
|
||||
}
|
||||
}
|
||||
process.exit(0)
|
||||
}
|
||||
|
||||
run().catch(console.error)
|
||||
Reference in New Issue
Block a user