398 lines
16 KiB
PHP
398 lines
16 KiB
PHP
<?php
|
|
/**
|
|
* EÜR (Einnahmen-Überschuss-Rechnung) Klasse für Deutschland
|
|
* Steuerjahr 2025
|
|
*
|
|
* @package steuer
|
|
* @subpackage class
|
|
*/
|
|
|
|
require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php';
|
|
|
|
/**
|
|
* Klasse zur Verwaltung der EÜR
|
|
*/
|
|
class EUeR extends CommonObject
|
|
{
|
|
public $db;
|
|
public $error = '';
|
|
public $errors = array();
|
|
|
|
public $jahr;
|
|
public $entity;
|
|
|
|
// EÜR Daten
|
|
public $einnahmen = array();
|
|
public $ausgaben = array();
|
|
public $summe_einnahmen = 0;
|
|
public $summe_ausgaben = 0;
|
|
public $gewinn = 0;
|
|
|
|
// USt/VSt Daten
|
|
public $ust_summe = 0;
|
|
public $vst_summe = 0;
|
|
public $ust_zahllast = 0;
|
|
|
|
/**
|
|
* Constructor
|
|
*
|
|
* @param DoliDB $db Database handler
|
|
*/
|
|
public function __construct($db)
|
|
{
|
|
global $conf;
|
|
$this->db = $db;
|
|
$this->entity = $conf->entity;
|
|
}
|
|
|
|
/**
|
|
* Berechnet die EÜR aus den Dolibarr-Buchungen
|
|
*
|
|
* @param int $jahr Steuerjahr
|
|
* @param int $monat_von Monat von (1-12, 0=ganzes Jahr)
|
|
* @param int $monat_bis Monat bis (1-12, 0=ganzes Jahr)
|
|
* @return int 0 bei Erfolg, <0 bei Fehler
|
|
*/
|
|
public function berechneAusDolibarr($jahr, $monat_von = 0, $monat_bis = 0)
|
|
{
|
|
global $conf;
|
|
|
|
$this->jahr = $jahr;
|
|
|
|
// Datumsgrenzen
|
|
if ($monat_von > 0 && $monat_bis > 0) {
|
|
$datum_von = $jahr.'-'.sprintf('%02d', $monat_von).'-01';
|
|
$datum_bis = date('Y-m-t', strtotime($jahr.'-'.sprintf('%02d', $monat_bis).'-01'));
|
|
} else {
|
|
$datum_von = $jahr.'-01-01';
|
|
$datum_bis = $jahr.'-12-31';
|
|
}
|
|
|
|
// Reset
|
|
$this->einnahmen = array();
|
|
$this->ausgaben = array();
|
|
$this->summe_einnahmen = 0;
|
|
$this->summe_ausgaben = 0;
|
|
$this->ust_summe = 0;
|
|
$this->vst_summe = 0;
|
|
|
|
// EINNAHMEN aus Kundenrechnungen (bezahlt)
|
|
$this->berechneEinnahmenAusRechnungen($datum_von, $datum_bis);
|
|
|
|
// AUSGABEN aus Lieferantenrechnungen (bezahlt)
|
|
$this->berechneAusgabenAusLieferantenrechnungen($datum_von, $datum_bis);
|
|
|
|
// Manuelle Buchungen aus steuer_buchung Tabelle
|
|
$this->berechneManuelleBuchungen($datum_von, $datum_bis);
|
|
|
|
// Gewinn berechnen
|
|
$this->gewinn = $this->summe_einnahmen - $this->summe_ausgaben;
|
|
$this->ust_zahllast = $this->ust_summe - $this->vst_summe;
|
|
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* Einnahmen aus Kundenzahlungen (Ist-Versteuerung / Zufluss-Prinzip)
|
|
*/
|
|
private function berechneEinnahmenAusRechnungen($datum_von, $datum_bis)
|
|
{
|
|
global $conf;
|
|
|
|
// Zahlungsdatum liegt in llx_paiement, nicht in llx_paiement_facture!
|
|
$sql = "SELECT pf.amount as zahlung, p.datep as zahlungsdatum,";
|
|
$sql .= " f.total_ht as netto, f.total_tva as ust, f.total_ttc as brutto";
|
|
$sql .= " FROM ".MAIN_DB_PREFIX."paiement as p";
|
|
$sql .= " INNER JOIN ".MAIN_DB_PREFIX."paiement_facture as pf ON p.rowid = pf.fk_paiement";
|
|
$sql .= " INNER JOIN ".MAIN_DB_PREFIX."facture as f ON pf.fk_facture = f.rowid";
|
|
$sql .= " WHERE f.entity = ".((int) $conf->entity);
|
|
$sql .= " AND p.datep BETWEEN '".$this->db->escape($datum_von)."' AND '".$this->db->escape($datum_bis)."'";
|
|
|
|
$resql = $this->db->query($sql);
|
|
if ($resql) {
|
|
$summe_brutto = 0;
|
|
$summe_netto = 0;
|
|
$summe_ust = 0;
|
|
$anzahl = 0;
|
|
|
|
while ($obj = $this->db->fetch_object($resql)) {
|
|
// USt-Anteil aus der Rechnung berechnen (netto/brutto Verhältnis)
|
|
if ($obj->brutto != 0) {
|
|
$zahlung_netto = $obj->zahlung * ($obj->netto / $obj->brutto);
|
|
$zahlung_ust = $obj->zahlung * ($obj->ust / $obj->brutto);
|
|
} else {
|
|
$zahlung_netto = $obj->zahlung / 1.19;
|
|
$zahlung_ust = $obj->zahlung - $zahlung_netto;
|
|
}
|
|
|
|
$summe_brutto += $obj->zahlung;
|
|
$summe_netto += $zahlung_netto;
|
|
$summe_ust += $zahlung_ust;
|
|
$anzahl++;
|
|
}
|
|
|
|
if ($anzahl > 0) {
|
|
$this->einnahmen['zahlungseingaenge'] = array(
|
|
'bezeichnung' => 'Betriebseinnahmen (Zahlungseingang)',
|
|
'netto' => $summe_netto,
|
|
'ust' => $summe_ust,
|
|
'brutto' => $summe_brutto,
|
|
'ust_satz' => 19,
|
|
'anzahl' => $anzahl
|
|
);
|
|
$this->summe_einnahmen += $summe_netto;
|
|
$this->ust_summe += $summe_ust;
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Ausgaben aus Lieferantenzahlungen (Ist-Versteuerung / Abfluss-Prinzip)
|
|
*/
|
|
private function berechneAusgabenAusLieferantenrechnungen($datum_von, $datum_bis)
|
|
{
|
|
global $conf;
|
|
|
|
// Zahlungsdatum liegt in llx_paiementfourn, nicht in llx_paiementfourn_facturefourn!
|
|
$sql = "SELECT pf.amount as zahlung, p.datep as zahlungsdatum,";
|
|
$sql .= " f.total_ht as netto, f.total_tva as vst, f.total_ttc as brutto";
|
|
$sql .= " FROM ".MAIN_DB_PREFIX."paiementfourn as p";
|
|
$sql .= " INNER JOIN ".MAIN_DB_PREFIX."paiementfourn_facturefourn as pf ON p.rowid = pf.fk_paiementfourn";
|
|
$sql .= " INNER JOIN ".MAIN_DB_PREFIX."facture_fourn as f ON pf.fk_facturefourn = f.rowid";
|
|
$sql .= " WHERE f.entity = ".((int) $conf->entity);
|
|
$sql .= " AND p.datep BETWEEN '".$this->db->escape($datum_von)."' AND '".$this->db->escape($datum_bis)."'";
|
|
|
|
$resql = $this->db->query($sql);
|
|
if ($resql) {
|
|
$summe_brutto = 0;
|
|
$summe_netto = 0;
|
|
$summe_vst = 0;
|
|
$anzahl = 0;
|
|
|
|
while ($obj = $this->db->fetch_object($resql)) {
|
|
// VSt-Anteil aus der Rechnung berechnen (netto/brutto Verhältnis)
|
|
if ($obj->brutto != 0) {
|
|
$zahlung_netto = $obj->zahlung * ($obj->netto / $obj->brutto);
|
|
$zahlung_vst = $obj->zahlung * ($obj->vst / $obj->brutto);
|
|
} else {
|
|
$zahlung_netto = $obj->zahlung / 1.19;
|
|
$zahlung_vst = $obj->zahlung - $zahlung_netto;
|
|
}
|
|
|
|
$summe_brutto += $obj->zahlung;
|
|
$summe_netto += $zahlung_netto;
|
|
$summe_vst += $zahlung_vst;
|
|
$anzahl++;
|
|
}
|
|
|
|
if ($anzahl > 0) {
|
|
$this->ausgaben['zahlungsausgaenge'] = array(
|
|
'bezeichnung' => 'Betriebsausgaben (Zahlungsausgang)',
|
|
'netto' => $summe_netto,
|
|
'vst' => $summe_vst,
|
|
'brutto' => $summe_brutto,
|
|
'vst_satz' => 19,
|
|
'anzahl' => $anzahl
|
|
);
|
|
$this->summe_ausgaben += $summe_netto;
|
|
$this->vst_summe += $summe_vst;
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Manuelle Buchungen aus steuer_buchung Tabelle
|
|
*/
|
|
private function berechneManuelleBuchungen($datum_von, $datum_bis)
|
|
{
|
|
global $conf;
|
|
|
|
$sql = "SELECT b.*, k.kontonummer, k.bezeichnung as konto_bezeichnung, k.kategorie";
|
|
$sql .= " FROM ".MAIN_DB_PREFIX."steuer_buchung as b";
|
|
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."steuer_konto as k ON b.fk_konto = k.rowid";
|
|
$sql .= " WHERE b.entity = ".((int) $conf->entity);
|
|
$sql .= " AND b.status = 1";
|
|
$sql .= " AND b.datum BETWEEN '".$this->db->escape($datum_von)."' AND '".$this->db->escape($datum_bis)."'";
|
|
$sql .= " ORDER BY b.datum";
|
|
|
|
$resql = $this->db->query($sql);
|
|
if ($resql) {
|
|
while ($obj = $this->db->fetch_object($resql)) {
|
|
$key = 'manuell_'.$obj->kontonummer;
|
|
|
|
if ($obj->typ == 'einnahme') {
|
|
if (!isset($this->einnahmen[$key])) {
|
|
$this->einnahmen[$key] = array(
|
|
'bezeichnung' => $obj->konto_bezeichnung,
|
|
'kontonummer' => $obj->kontonummer,
|
|
'netto' => 0,
|
|
'ust' => 0,
|
|
'brutto' => 0,
|
|
'ust_satz' => (int)$obj->ust_satz,
|
|
'anzahl' => 0
|
|
);
|
|
}
|
|
$this->einnahmen[$key]['netto'] += $obj->betrag_netto;
|
|
$this->einnahmen[$key]['ust'] += $obj->betrag_ust;
|
|
$this->einnahmen[$key]['brutto'] += $obj->betrag_brutto;
|
|
$this->einnahmen[$key]['anzahl']++;
|
|
$this->summe_einnahmen += $obj->betrag_netto;
|
|
$this->ust_summe += $obj->betrag_ust;
|
|
} else {
|
|
if (!isset($this->ausgaben[$key])) {
|
|
$this->ausgaben[$key] = array(
|
|
'bezeichnung' => $obj->konto_bezeichnung,
|
|
'kontonummer' => $obj->kontonummer,
|
|
'netto' => 0,
|
|
'vst' => 0,
|
|
'brutto' => 0,
|
|
'vst_satz' => (int)$obj->ust_satz,
|
|
'anzahl' => 0
|
|
);
|
|
}
|
|
$this->ausgaben[$key]['netto'] += $obj->betrag_netto;
|
|
$this->ausgaben[$key]['vst'] += $obj->betrag_ust;
|
|
$this->ausgaben[$key]['brutto'] += $obj->betrag_brutto;
|
|
$this->ausgaben[$key]['anzahl']++;
|
|
$this->summe_ausgaben += $obj->betrag_netto;
|
|
$this->vst_summe += $obj->betrag_ust;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Holt detaillierte Buchungsliste für einen Zeitraum
|
|
*
|
|
* @param string $datum_von Von-Datum
|
|
* @param string $datum_bis Bis-Datum
|
|
* @param string $typ 'einnahme', 'ausgabe' oder 'alle'
|
|
* @return array Buchungsliste
|
|
*/
|
|
public function getBuchungsliste($datum_von, $datum_bis, $typ = 'alle')
|
|
{
|
|
global $conf;
|
|
$buchungen = array();
|
|
|
|
// Kundenrechnungen (Einnahmen) - nach Zahlungsdatum
|
|
// Zahlungsdatum liegt in llx_paiement!
|
|
if ($typ == 'alle' || $typ == 'einnahme') {
|
|
$sql = "SELECT 'einnahme' as buchungstyp, f.rowid, f.ref,";
|
|
$sql .= " p.datep as datum,";
|
|
$sql .= " CONCAT('Rechnung ', f.ref, ' - ', s.nom) as beschreibung,";
|
|
$sql .= " pf.amount as brutto,";
|
|
$sql .= " (pf.amount * f.total_ht / f.total_ttc) as netto,";
|
|
$sql .= " (pf.amount * f.total_tva / f.total_ttc) as steuer,";
|
|
$sql .= " s.nom as partner, 'facture' as quelle";
|
|
$sql .= " FROM ".MAIN_DB_PREFIX."paiement as p";
|
|
$sql .= " INNER JOIN ".MAIN_DB_PREFIX."paiement_facture as pf ON p.rowid = pf.fk_paiement";
|
|
$sql .= " INNER JOIN ".MAIN_DB_PREFIX."facture as f ON pf.fk_facture = f.rowid";
|
|
$sql .= " INNER JOIN ".MAIN_DB_PREFIX."societe as s ON f.fk_soc = s.rowid";
|
|
$sql .= " WHERE f.entity = ".((int) $conf->entity);
|
|
$sql .= " AND p.datep BETWEEN '".$this->db->escape($datum_von)."' AND '".$this->db->escape($datum_bis)."'";
|
|
$sql .= " ORDER BY p.datep";
|
|
|
|
$resql = $this->db->query($sql);
|
|
if ($resql) {
|
|
while ($obj = $this->db->fetch_object($resql)) {
|
|
$buchungen[] = (array)$obj;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Lieferantenrechnungen (Ausgaben) - nach Zahlungsdatum
|
|
// Zahlungsdatum liegt in llx_paiementfourn!
|
|
if ($typ == 'alle' || $typ == 'ausgabe') {
|
|
$sql = "SELECT 'ausgabe' as buchungstyp, f.rowid, f.ref,";
|
|
$sql .= " p.datep as datum,";
|
|
$sql .= " CONCAT('Lieferantenrechnung ', COALESCE(f.ref_supplier, f.ref), ' - ', s.nom) as beschreibung,";
|
|
$sql .= " pf.amount as brutto,";
|
|
$sql .= " (pf.amount * f.total_ht / f.total_ttc) as netto,";
|
|
$sql .= " (pf.amount * f.total_tva / f.total_ttc) as steuer,";
|
|
$sql .= " s.nom as partner, 'facture_fourn' as quelle";
|
|
$sql .= " FROM ".MAIN_DB_PREFIX."paiementfourn as p";
|
|
$sql .= " INNER JOIN ".MAIN_DB_PREFIX."paiementfourn_facturefourn as pf ON p.rowid = pf.fk_paiementfourn";
|
|
$sql .= " INNER JOIN ".MAIN_DB_PREFIX."facture_fourn as f ON pf.fk_facturefourn = f.rowid";
|
|
$sql .= " INNER JOIN ".MAIN_DB_PREFIX."societe as s ON f.fk_soc = s.rowid";
|
|
$sql .= " WHERE f.entity = ".((int) $conf->entity);
|
|
$sql .= " AND p.datep BETWEEN '".$this->db->escape($datum_von)."' AND '".$this->db->escape($datum_bis)."'";
|
|
$sql .= " ORDER BY p.datep";
|
|
|
|
$resql = $this->db->query($sql);
|
|
if ($resql) {
|
|
while ($obj = $this->db->fetch_object($resql)) {
|
|
$buchungen[] = (array)$obj;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Manuelle Buchungen
|
|
$sql = "SELECT b.typ as buchungstyp, b.rowid, b.ref,";
|
|
$sql .= " b.datum, b.beschreibung,";
|
|
$sql .= " b.betrag_netto as netto, b.betrag_ust as steuer, b.betrag_brutto as brutto,";
|
|
$sql .= " COALESCE(s.nom, '') as partner, 'manuell' as quelle";
|
|
$sql .= " FROM ".MAIN_DB_PREFIX."steuer_buchung as b";
|
|
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON b.fk_soc = s.rowid";
|
|
$sql .= " WHERE b.entity = ".((int) $conf->entity);
|
|
$sql .= " AND b.status = 1";
|
|
if ($typ != 'alle') {
|
|
$sql .= " AND b.typ = '".$this->db->escape($typ)."'";
|
|
}
|
|
$sql .= " AND b.datum BETWEEN '".$this->db->escape($datum_von)."' AND '".$this->db->escape($datum_bis)."'";
|
|
$sql .= " ORDER BY b.datum";
|
|
|
|
$resql = $this->db->query($sql);
|
|
if ($resql) {
|
|
while ($obj = $this->db->fetch_object($resql)) {
|
|
$buchungen[] = (array)$obj;
|
|
}
|
|
}
|
|
|
|
// Nach Datum sortieren
|
|
usort($buchungen, function($a, $b) {
|
|
return strcmp($a['datum'], $b['datum']);
|
|
});
|
|
|
|
return $buchungen;
|
|
}
|
|
|
|
/**
|
|
* Generiert das EÜR-Format für die Anlage EÜR
|
|
*
|
|
* @return array EÜR-Zeilen
|
|
*/
|
|
public function getAnlageEUeR()
|
|
{
|
|
$zeilen = array();
|
|
|
|
// EINNAHMEN
|
|
$zeilen[10] = array('zeile' => 10, 'bezeichnung' => 'Steuerfreie Betriebseinnahmen', 'betrag' => 0);
|
|
$zeilen[11] = array('zeile' => 11, 'bezeichnung' => 'Innergemeinschaftliche Lieferungen', 'betrag' => 0);
|
|
$zeilen[12] = array('zeile' => 12, 'bezeichnung' => 'Ausfuhrlieferungen', 'betrag' => 0);
|
|
$zeilen[14] = array('zeile' => 14, 'bezeichnung' => 'Umsatzsteuerpflichtige Betriebseinnahmen', 'betrag' => $this->summe_einnahmen);
|
|
$zeilen[16] = array('zeile' => 16, 'bezeichnung' => 'Sonstige Betriebseinnahmen', 'betrag' => 0);
|
|
$zeilen[19] = array('zeile' => 19, 'bezeichnung' => 'Private Kfz-/Telefonnutzung', 'betrag' => 0);
|
|
|
|
// Summe Einnahmen
|
|
$zeilen[22] = array('zeile' => 22, 'bezeichnung' => 'Summe Betriebseinnahmen', 'betrag' => $this->summe_einnahmen, 'summe' => true);
|
|
|
|
// AUSGABEN
|
|
$zeilen[26] = array('zeile' => 26, 'bezeichnung' => 'Waren, Roh- und Hilfsstoffe', 'betrag' => 0);
|
|
$zeilen[31] = array('zeile' => 31, 'bezeichnung' => 'Löhne und Gehälter', 'betrag' => 0);
|
|
$zeilen[32] = array('zeile' => 32, 'bezeichnung' => 'Gesetzliche Sozialaufwendungen', 'betrag' => 0);
|
|
$zeilen[34] = array('zeile' => 34, 'bezeichnung' => 'Raumkosten', 'betrag' => 0);
|
|
$zeilen[36] = array('zeile' => 36, 'bezeichnung' => 'AfA auf Sachanlagen', 'betrag' => 0);
|
|
$zeilen[38] = array('zeile' => 38, 'bezeichnung' => 'Leasing, GWG', 'betrag' => 0);
|
|
$zeilen[45] = array('zeile' => 45, 'bezeichnung' => 'Schuldzinsen', 'betrag' => 0);
|
|
$zeilen[49] = array('zeile' => 49, 'bezeichnung' => 'Übrige Betriebsausgaben', 'betrag' => $this->summe_ausgaben);
|
|
$zeilen[51] = array('zeile' => 51, 'bezeichnung' => 'Fahrzeugkosten', 'betrag' => 0);
|
|
|
|
// Summe Ausgaben
|
|
$zeilen[67] = array('zeile' => 67, 'bezeichnung' => 'Summe Betriebsausgaben', 'betrag' => $this->summe_ausgaben, 'summe' => true);
|
|
|
|
// GEWINN
|
|
$zeilen[87] = array('zeile' => 87, 'bezeichnung' => 'Gewinn/Verlust', 'betrag' => $this->gewinn, 'ergebnis' => true);
|
|
|
|
return $zeilen;
|
|
}
|
|
}
|