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 bezahlten Kundenrechnungen */ private function berechneEinnahmenAusRechnungen($datum_von, $datum_bis) { global $conf; // Bezahlte Rechnungen nach Zahlungsdatum (Zufluss-Prinzip!) $sql = "SELECT f.rowid, f.ref, f.datef as rechnungsdatum,"; $sql .= " pf.datep as zahlungsdatum, pf.amount as zahlung,"; $sql .= " f.total_ht as netto, f.total_tva as ust, f.total_ttc as brutto,"; $sql .= " s.nom as kunde,"; $sql .= " fd.tva_tx as ust_satz, fd.total_ht as zeile_netto, fd.total_tva as zeile_ust"; $sql .= " FROM ".MAIN_DB_PREFIX."facture as f"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON f.fk_soc = s.rowid"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."paiement_facture as pf ON pf.fk_facture = f.rowid"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."facturedet as fd ON fd.fk_facture = f.rowid"; $sql .= " WHERE f.entity = ".((int) $conf->entity); $sql .= " AND f.fk_statut IN (2, 3)"; // Bezahlt oder teilbezahlt $sql .= " AND pf.datep BETWEEN '".$this->db->escape($datum_von)."' AND '".$this->db->escape($datum_bis)."'"; $sql .= " ORDER BY pf.datep"; $resql = $this->db->query($sql); if ($resql) { $einnahmen_details = array(); while ($obj = $this->db->fetch_object($resql)) { $key = 'ust_'.(int)$obj->ust_satz; if (!isset($einnahmen_details[$key])) { $einnahmen_details[$key] = array( 'bezeichnung' => 'Erlöse '.(int)$obj->ust_satz.'% USt', 'netto' => 0, 'ust' => 0, 'brutto' => 0, 'ust_satz' => (int)$obj->ust_satz, 'anzahl' => 0 ); } $einnahmen_details[$key]['netto'] += $obj->zahlung / (1 + $obj->ust_satz/100); $einnahmen_details[$key]['ust'] += $obj->zahlung - ($obj->zahlung / (1 + $obj->ust_satz/100)); $einnahmen_details[$key]['brutto'] += $obj->zahlung; $einnahmen_details[$key]['anzahl']++; } foreach ($einnahmen_details as $key => $detail) { $this->einnahmen[$key] = $detail; $this->summe_einnahmen += $detail['netto']; $this->ust_summe += $detail['ust']; } } // Alternative: Wenn keine Zahlungen verknüpft, nimm Rechnungsdatum $sql2 = "SELECT f.rowid, f.ref, f.datef as datum,"; $sql2 .= " f.total_ht as netto, f.total_tva as ust, f.total_ttc as brutto,"; $sql2 .= " s.nom as kunde"; $sql2 .= " FROM ".MAIN_DB_PREFIX."facture as f"; $sql2 .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON f.fk_soc = s.rowid"; $sql2 .= " LEFT JOIN ".MAIN_DB_PREFIX."paiement_facture as pf ON pf.fk_facture = f.rowid"; $sql2 .= " WHERE f.entity = ".((int) $conf->entity); $sql2 .= " AND f.fk_statut IN (2, 3)"; $sql2 .= " AND f.datef BETWEEN '".$this->db->escape($datum_von)."' AND '".$this->db->escape($datum_bis)."'"; $sql2 .= " AND pf.rowid IS NULL"; // Keine Zahlungsverknüpfung $sql2 .= " ORDER BY f.datef"; $resql2 = $this->db->query($sql2); if ($resql2) { while ($obj = $this->db->fetch_object($resql2)) { $key = 'einnahmen_ohne_zahlung'; if (!isset($this->einnahmen[$key])) { $this->einnahmen[$key] = array( 'bezeichnung' => 'Erlöse (Rechnungsdatum)', 'netto' => 0, 'ust' => 0, 'brutto' => 0, 'anzahl' => 0 ); } $this->einnahmen[$key]['netto'] += $obj->netto; $this->einnahmen[$key]['ust'] += $obj->ust; $this->einnahmen[$key]['brutto'] += $obj->brutto; $this->einnahmen[$key]['anzahl']++; $this->summe_einnahmen += $obj->netto; $this->ust_summe += $obj->ust; } } } /** * Ausgaben aus bezahlten Lieferantenrechnungen */ private function berechneAusgabenAusLieferantenrechnungen($datum_von, $datum_bis) { global $conf; // Bezahlte Lieferantenrechnungen nach Zahlungsdatum (Abfluss-Prinzip!) $sql = "SELECT f.rowid, f.ref, f.ref_supplier, f.datef as rechnungsdatum,"; $sql .= " pf.datep as zahlungsdatum, pf.amount as zahlung,"; $sql .= " f.total_ht as netto, f.total_tva as vst, f.total_ttc as brutto,"; $sql .= " s.nom as lieferant,"; $sql .= " fd.tva_tx as vst_satz"; $sql .= " FROM ".MAIN_DB_PREFIX."facture_fourn as f"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON f.fk_soc = s.rowid"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."paiementfourn_facturefourn as pf ON pf.fk_facturefourn = f.rowid"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."facture_fourn_det as fd ON fd.fk_facture_fourn = f.rowid"; $sql .= " WHERE f.entity = ".((int) $conf->entity); $sql .= " AND f.fk_statut IN (2)"; // Bezahlt $sql .= " AND pf.datep BETWEEN '".$this->db->escape($datum_von)."' AND '".$this->db->escape($datum_bis)."'"; $sql .= " ORDER BY pf.datep"; $resql = $this->db->query($sql); if ($resql) { $ausgaben_details = array(); while ($obj = $this->db->fetch_object($resql)) { $vst_satz = isset($obj->vst_satz) ? (int)$obj->vst_satz : 19; $key = 'vst_'.$vst_satz; if (!isset($ausgaben_details[$key])) { $ausgaben_details[$key] = array( 'bezeichnung' => 'Betriebsausgaben '.$vst_satz.'% VSt', 'netto' => 0, 'vst' => 0, 'brutto' => 0, 'vst_satz' => $vst_satz, 'anzahl' => 0 ); } $ausgaben_details[$key]['brutto'] += $obj->zahlung; $ausgaben_details[$key]['netto'] += $obj->zahlung / (1 + $vst_satz/100); $ausgaben_details[$key]['vst'] += $obj->zahlung - ($obj->zahlung / (1 + $vst_satz/100)); $ausgaben_details[$key]['anzahl']++; } foreach ($ausgaben_details as $key => $detail) { $this->ausgaben[$key] = $detail; $this->summe_ausgaben += $detail['netto']; $this->vst_summe += $detail['vst']; } } // Alternative: Ohne Zahlungsverknüpfung $sql2 = "SELECT f.rowid, f.ref, f.datef as datum,"; $sql2 .= " f.total_ht as netto, f.total_tva as vst, f.total_ttc as brutto,"; $sql2 .= " s.nom as lieferant"; $sql2 .= " FROM ".MAIN_DB_PREFIX."facture_fourn as f"; $sql2 .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON f.fk_soc = s.rowid"; $sql2 .= " LEFT JOIN ".MAIN_DB_PREFIX."paiementfourn_facturefourn as pf ON pf.fk_facturefourn = f.rowid"; $sql2 .= " WHERE f.entity = ".((int) $conf->entity); $sql2 .= " AND f.fk_statut IN (2)"; $sql2 .= " AND f.datef BETWEEN '".$this->db->escape($datum_von)."' AND '".$this->db->escape($datum_bis)."'"; $sql2 .= " AND pf.rowid IS NULL"; $sql2 .= " ORDER BY f.datef"; $resql2 = $this->db->query($sql2); if ($resql2) { while ($obj = $this->db->fetch_object($resql2)) { $key = 'ausgaben_ohne_zahlung'; if (!isset($this->ausgaben[$key])) { $this->ausgaben[$key] = array( 'bezeichnung' => 'Betriebsausgaben (Rechnungsdatum)', 'netto' => 0, 'vst' => 0, 'brutto' => 0, 'anzahl' => 0 ); } $this->ausgaben[$key]['netto'] += $obj->netto; $this->ausgaben[$key]['vst'] += $obj->vst; $this->ausgaben[$key]['brutto'] += $obj->brutto; $this->ausgaben[$key]['anzahl']++; $this->summe_ausgaben += $obj->netto; $this->vst_summe += $obj->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) if ($typ == 'alle' || $typ == 'einnahme') { $sql = "SELECT 'einnahme' as buchungstyp, f.rowid, f.ref,"; $sql .= " COALESCE(pf.datep, f.datef) as datum,"; $sql .= " CONCAT('Rechnung ', f.ref, ' - ', s.nom) as beschreibung,"; $sql .= " f.total_ht as netto, f.total_tva as steuer, f.total_ttc as brutto,"; $sql .= " s.nom as partner, 'facture' as quelle"; $sql .= " FROM ".MAIN_DB_PREFIX."facture as f"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON f.fk_soc = s.rowid"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."paiement_facture as pf ON pf.fk_facture = f.rowid"; $sql .= " WHERE f.entity = ".((int) $conf->entity); $sql .= " AND f.fk_statut IN (2, 3)"; $sql .= " AND COALESCE(pf.datep, f.datef) BETWEEN '".$this->db->escape($datum_von)."' AND '".$this->db->escape($datum_bis)."'"; $sql .= " GROUP BY f.rowid"; $sql .= " ORDER BY datum"; $resql = $this->db->query($sql); if ($resql) { while ($obj = $this->db->fetch_object($resql)) { $buchungen[] = (array)$obj; } } } // Lieferantenrechnungen (Ausgaben) if ($typ == 'alle' || $typ == 'ausgabe') { $sql = "SELECT 'ausgabe' as buchungstyp, f.rowid, f.ref,"; $sql .= " COALESCE(pf.datep, f.datef) as datum,"; $sql .= " CONCAT('Lieferantenrechnung ', COALESCE(f.ref_supplier, f.ref), ' - ', s.nom) as beschreibung,"; $sql .= " f.total_ht as netto, f.total_tva as steuer, f.total_ttc as brutto,"; $sql .= " s.nom as partner, 'facture_fourn' as quelle"; $sql .= " FROM ".MAIN_DB_PREFIX."facture_fourn as f"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON f.fk_soc = s.rowid"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."paiementfourn_facturefourn as pf ON pf.fk_facturefourn = f.rowid"; $sql .= " WHERE f.entity = ".((int) $conf->entity); $sql .= " AND f.fk_statut IN (2)"; $sql .= " AND COALESCE(pf.datep, f.datef) BETWEEN '".$this->db->escape($datum_von)."' AND '".$this->db->escape($datum_bis)."'"; $sql .= " GROUP BY f.rowid"; $sql .= " ORDER BY datum"; $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; } }