dolibarr.steuer/class/euer.class.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;
}
}