splitStrasse($settings['strasse'] ?? ''); [$vorname, $nachname] = $this->splitName($inhaber); $x = fn(string $v): string => htmlspecialchars($v, ENT_XML1, 'UTF-8'); $dom = new \DOMDocument('1.0', 'UTF-8'); $dom->formatOutput = true; $ns = sprintf('http://finkonsens.de/elster/elsteranmeldung/ustva/v%d', $year); $anm = $dom->createElementNS($ns, 'Anmeldungssteuern'); $anm->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns', $ns); $anm->setAttribute('version', (string)$year); $dom->appendChild($anm); // DatenLieferant $dl = $dom->createElement('DatenLieferant'); foreach ([ 'Name' => $x($inhaber), 'Strasse' => $x($settings['strasse'] ?? ''), 'PLZ' => $x($settings['plz'] ?? ''), 'Ort' => $x($settings['ort'] ?? ''), 'Telefon' => $x($settings['telefon'] ?? ''), 'Email' => $x($settings['email'] ?? ''), ] as $tag => $val) { $dl->appendChild($dom->createElement($tag, $val)); } $anm->appendChild($dl); $anm->appendChild($dom->createElement('Erstellungsdatum', date('Ymd'))); // Steuerfall $sf = $dom->createElement('Steuerfall'); $anm->appendChild($sf); // Berater (leer) $berater = $dom->createElement('Berater'); foreach ([ 'Bezeichnung','Name','Vorname','Namensvorsatz','Namenszusatz', 'Str','Hausnummer','HNrZusatz','AnschriftenZusatz','Ort','PLZ', 'AuslandsPLZ','Land','PostfachOrt','Postfach','PostfachPLZ', 'GKPLZ','Telefon','Email', ] as $tag) { $berater->appendChild($dom->createElement($tag)); } $sf->appendChild($berater); // Mandant $mandant = $dom->createElement('Mandant'); foreach ([ 'Name' => $x($nachname), 'Vorname' => $x($vorname), 'MandantenNr' => '', 'Bearbeiterkennzeichen' => '', ] as $tag => $val) { $mandant->appendChild($dom->createElement($tag, $val)); } $sf->appendChild($mandant); // Unternehmer $unternehmer = $dom->createElement('Unternehmer'); foreach ([ 'Bezeichnung' => $x($firma), 'Name' => $x($nachname), 'Vorname' => $x($vorname), 'Namensvorsatz' => '', 'Namenszusatz' => '', 'Str' => $x($strasse), 'Hausnummer' => $x($hausnummer), 'HNrZusatz' => '', 'AnschriftenZusatz' => '', 'Ort' => $x($settings['ort'] ?? ''), 'PLZ' => $x($settings['plz'] ?? ''), 'AuslandsPLZ' => '', 'Land' => 'Deutschland', 'PostfachOrt' => '', 'Postfach' => '', 'PostfachPLZ' => '', 'GKPLZ' => '', 'Telefon' => $x($settings['telefon'] ?? ''), 'Email' => $x($settings['email'] ?? ''), ] as $tag => $val) { $unternehmer->appendChild($dom->createElement($tag, $val)); } $sf->appendChild($unternehmer); // Umsatzsteuervoranmeldung $ustva = $dom->createElement('Umsatzsteuervoranmeldung'); $sf->appendChild($ustva); $ustva->appendChild($dom->createElement('Jahr', (string)$year)); $ustva->appendChild($dom->createElement('Zeitraum', sprintf('%02d', $month))); $ustva->appendChild($dom->createElement('Steuernummer', $steuernummer)); // Kz-Felder: Bemessungsgrundlagen ganzzahlig, Steuerbeträge mit 2 Dezimalstellen. // ust81 und ust89 (abgeleitete Anzeigewerte) werden nicht übertragen. $kzBetrag = fn(float $v): string => (string)(int)round($v); $kzSteuer = fn(float $v): string => number_format($v, 2, '.', ''); $betragsfelder = ['81', '89']; foreach ($betragsfelder as $nr) { $val = (float)($kz[$nr]['betrag'] ?? 0.0); if ($val != 0.0) { $ustva->appendChild($dom->createElement('Kz' . $nr, $kzBetrag($val))); } } $steuerfelder = ['66', '61', '83']; foreach ($steuerfelder as $nr) { $val = (float)($kz[$nr]['steuer'] ?? 0.0); if ($val != 0.0) { $ustva->appendChild($dom->createElement('Kz' . $nr, $kzSteuer($val))); } } return $dom->saveXML(); } /** * Trennt Straßenname und Hausnummer. "Bietigheimer Str. 67" → ["Bietigheimer Str.", "67"] */ private function splitStrasse(string $strasse): array { if (preg_match('/^(.*?)\s+(\d+\w*)$/', trim($strasse), $m)) { return [$m[1], $m[2]]; } return [$strasse, '']; } /** * Trennt Vorname und Nachname. "Felix Schepmann" → ["Felix", "Schepmann"] */ private function splitName(string $name): array { $parts = explode(' ', trim($name), 2); if (count($parts) === 2) { return [$parts[0], $parts[1]]; } return ['', $name]; } }