20-02-2026

This commit is contained in:
Kevin Adametz 2026-02-20 17:55:06 +01:00
parent a8b395e20d
commit a00c42e770
252 changed files with 28785 additions and 8907 deletions

View file

@ -1,246 +1,277 @@
<?php
namespace App\Http\Controllers;
use Auth;
use Request;
use ZipArchive;
use App\Models\UserInvoice;
use App\Models\DatevExport;
use App\Models\DatevExportLine;
use App\Services\DatevExportService;
use App\Services\HTMLHelper;
use App\Exports\UserTeamExport;
use App\Http\Controllers\Controller;
use Maatwebsite\Excel\Facades\Excel;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
class PaymentTaxAdvisorController extends Controller
{
private $BUKey = [
1 => 8120, //für Kunden aus der Schweiz
11 => 8125, //Steuerfreie EU-Lieferungen
2 => 8300, //Erlöse mit 7 % meistens für Käufe mit Aloe Vera
3 => 8400, //Regulär mit 19 %
];
private DatevExportService $datevService;
private $accountKey = [
'A'=>'10000',
'B'=>'10100',
'C'=>'10200',
'D'=>'10300',
'E'=>'10400',
'F'=>'10500',
'G'=>'10600',
'H'=>'10700',
'I'=>'10800',
'J'=>'10900',
'K'=>'11000',
'L'=>'11100',
'M'=>'11200',
'N'=>'11300',
'O'=>'11400',
'P'=>'11500',
'Q'=>'11600',
'R'=>'11700',
'S'=>'11800',
'SCH'=>'11900',
'T'=>'12000',
'U'=>'12100',
'V'=>'12200',
'W'=>'12300',
'X'=>'12400',
'Y'=>'12500',
'Z'=>'12600'
];
public function __construct()
public function __construct(DatevExportService $datevService)
{
$this->middleware('admin');
$this->datevService = $datevService;
}
public function index()
/**
* Hauptseite: Periodenauswahl + Export-Übersicht
*/
public function index(Request $request)
{
$this->setFilterVars();
$this->setFilterVars($request);
$month = intval(session('payment_taxadvisor_filter_month'));
$year = intval(session('payment_taxadvisor_filter_year'));
// Letzter Export für diese Periode
$currentExport = DatevExport::forPeriod($month, $year)
->generated()
->latest()
->first();
// Letzte 10 Exports für die Historie
$recentExports = DatevExport::generated()
->latest()
->limit(10)
->get();
$data = [
'filter_months' => HTMLHelper::getTransMonths(),
'filter_years' => HTMLHelper::getYearRange(2023),
'current_month' => $month,
'current_year' => $year,
'current_export' => $currentExport,
'recent_exports' => $recentExports,
];
return view('admin.payment.taxadvisor', $data);
}
public function createZip($filesToZip)
/**
* AJAX: Vorschau der Daten für die gewählte Periode.
*/
public function preview(Request $request)
{
$zip = new ZipArchive;
$zipFileName = 'mysample.zip';
$path = storage_path().'/app/public/zip/';
if ($zip->open($path.$zipFileName, ZipArchive::CREATE) === TRUE) {
foreach ($filesToZip as $file) {
$zip->addFile($file, basename($file));
}
$month = intval($request->get('month', session('payment_taxadvisor_filter_month')));
$year = intval($request->get('year', session('payment_taxadvisor_filter_year')));
$zip->close();
return response()->download($path.$zipFileName)->deleteFileAfterSend(true);
try {
$preview = $this->datevService->getPreview($month, $year);
return response()->json([
'success' => true,
'data' => $preview,
]);
} catch (\Exception $e) {
return response()->json([
'success' => false,
'message' => 'Fehler bei der Vorschau: '.$e->getMessage(),
], 500);
}
}
/**
* Export generieren und speichern.
*/
public function generate(Request $request)
{
$month = intval($request->get('month', session('payment_taxadvisor_filter_month')));
$year = intval($request->get('year', session('payment_taxadvisor_filter_year')));
try {
$export = $this->datevService->generateExport($month, $year);
return redirect()
->route('admin_payments_taxadvisor')
->with('success', "DATEV-Export für {$month}/{$year} erfolgreich generiert. {$export->total_lines} Buchungszeilen erstellt.");
} catch (\RuntimeException $e) {
return redirect()
->route('admin_payments_taxadvisor')
->with('error', $e->getMessage());
} catch (\Exception $e) {
return redirect()
->route('admin_payments_taxadvisor')
->with('error', 'Fehler beim Generieren: '.$e->getMessage());
}
}
/**
* CSV-Datei herunterladen.
*/
public function download($id)
{
$export = DatevExport::findOrFail($id);
if (! $export->isGenerated()) {
return redirect()
->route('admin_payments_taxadvisor')
->with('error', 'Export wurde noch nicht generiert.');
}
$disk = config('datev.storage_disk', 'local');
$path = $export->file_path;
if (! Storage::disk($disk)->exists($path)) {
// CSV neu generieren falls Datei nicht mehr vorhanden
$csvContent = $this->datevService->buildCsv($export);
Storage::disk($disk)->makeDirectory($export->getStoragePath());
Storage::disk($disk)->put($path, $csvContent);
}
// Status auf "heruntergeladen" setzen
$export->markAsDownloaded();
return Storage::disk($disk)->download($path, $export->filename, [
'Content-Type' => 'text/csv; charset=utf-8',
]);
}
/**
* DataTable: Export-Lines eines bestimmten Exports.
*/
public function datatable(Request $request)
{
$exportId = $request->get('export_id');
$query = DatevExportLine::select('datev_export_lines.*');
if ($exportId) {
$query->where('datev_export_id', $exportId);
} else {
return "Failed to create the zip file.";
}
}
// Fallback: Lines des aktuellen Perioden-Exports
$month = intval(session('payment_taxadvisor_filter_month', date('m')));
$year = intval(session('payment_taxadvisor_filter_year', date('Y')));
public function download(){
$export = DatevExport::forPeriod($month, $year)
->generated()
->latest()
->first();
$query = $this->initSearch();
$files = [];
$user_invoices = $query->get();
foreach ($user_invoices as $user_invoice) {
$filename = $user_invoice->filename;
$disk = $user_invoice->disk;
$path = $user_invoice->getDownloadPath();
if (Storage::disk($disk)->exists($path)) {
$file = Storage::disk($disk)->get($path);
$pdf_path = storage_path().'/app/public/'.$path;
$files[] = $pdf_path;
if ($export) {
$query->where('datev_export_id', $export->id);
} else {
$query->where('datev_export_id', 0); // Leere Ergebnismenge
}
}
return $this->createZip($files);
dd("asd");
return \DataTables::eloquent($query)
->editColumn('line_number', function (DatevExportLine $line) {
return $line->line_number;
})
->addColumn('source_type_label', function (DatevExportLine $line) {
return $line->source_type_label;
})
->addColumn('amount_display', function (DatevExportLine $line) {
return '<span class="no-line-break">'.$line->formatted_amount.'</span>';
})
->editColumn('soll_haben', function (DatevExportLine $line) {
$badge = $line->soll_haben === 'H' ? 'success' : 'warning';
return '<span class="badge badge-'.$badge.'">'.$line->soll_haben.'</span>';
})
->editColumn('konto', function (DatevExportLine $line) {
return $line->konto;
})
->editColumn('gegenkonto', function (DatevExportLine $line) {
return $line->gegenkonto;
})
->editColumn('bu_schluessel', function (DatevExportLine $line) {
return $line->bu_schluessel;
})
->addColumn('belegdatum_display', function (DatevExportLine $line) {
return $line->formatted_belegdatum;
})
->editColumn('belegfeld1', function (DatevExportLine $line) {
return $line->belegfeld1;
})
->editColumn('buchungstext', function (DatevExportLine $line) {
return $line->buchungstext;
})
->editColumn('eu_ustid', function (DatevExportLine $line) {
return $line->eu_ustid ?: '-';
})
->filterColumn('source_type_label', function ($query, $keyword) {
$typeMap = ['rechnung' => 'invoice', 'gutschrift' => 'credit', 'storno' => 'cancellation'];
foreach ($typeMap as $label => $type) {
if (stripos($label, $keyword) !== false) {
$query->where('source_type', $type);
if(Request::get('action') === "export"){
$objects = $this->initSearch(false);
$columns = [];
$filename = "mivita-absatzmengen-".session('payment_taxadvisor_filter_month').'_'.session('payment_taxadvisor_filter_year')."-export";
$headers = array(
'#',
'Produkt',
'Artikelnummer',
'Menge',
);
if($objects){
foreach ($objects as $key => $obj){
$columns[] = array(
'id' => $key,
'name' => $obj['name'],
'number' => $obj['number'],
'value' => $obj['value'],
);
return;
}
}
}
return Excel::download(new UserTeamExport($columns, $headers), $filename.'.xls');
}
$query->where('source_type', 'like', "%{$keyword}%");
})
->orderColumn('line_number', 'line_number $1')
->rawColumns(['amount_display', 'soll_haben'])
->make(true);
}
private function setFilterVars(){
/**
* Export sperren (Lock).
*/
public function lock($id)
{
$export = DatevExport::findOrFail($id);
if(!session('payment_taxadvisor_filter_month')){
if ($export->isLocked()) {
return redirect()
->route('admin_payments_taxadvisor')
->with('info', 'Export ist bereits gesperrt.');
}
$export->lock();
return redirect()
->route('admin_payments_taxadvisor')
->with('success', "Export {$export->period_label} wurde gesperrt.");
}
/**
* Export löschen (soft delete).
*/
public function destroy($id)
{
$export = DatevExport::findOrFail($id);
if ($export->isLocked()) {
return redirect()
->route('admin_payments_taxadvisor')
->with('error', 'Gesperrte Exports können nicht gelöscht werden.');
}
$export->delete();
return redirect()
->route('admin_payments_taxadvisor')
->with('success', "Export {$export->period_label} wurde gelöscht.");
}
/*
|--------------------------------------------------------------------------
| Private Hilfsmethoden
|--------------------------------------------------------------------------
*/
private function setFilterVars(Request $request): void
{
if (! session('payment_taxadvisor_filter_month')) {
session(['payment_taxadvisor_filter_month' => intval(date('m'))]);
}
if(!session('payment_taxadvisor_filter_year')){
if (! session('payment_taxadvisor_filter_year')) {
session(['payment_taxadvisor_filter_year' => intval(date('Y'))]);
}
if(Request::get('payment_taxadvisor_filter_month')){
session(['payment_taxadvisor_filter_month' => Request::get('payment_taxadvisor_filter_month')]);
if ($request->get('payment_taxadvisor_filter_month')) {
session(['payment_taxadvisor_filter_month' => $request->get('payment_taxadvisor_filter_month')]);
}
if(Request::get('payment_taxadvisor_filter_year')){
session(['payment_taxadvisor_filter_year' => Request::get('payment_taxadvisor_filter_year')]);
if ($request->get('payment_taxadvisor_filter_year')) {
session(['payment_taxadvisor_filter_year' => $request->get('payment_taxadvisor_filter_year')]);
}
}
private function initSearch()
{
$this->setFilterVars();
$query = UserInvoice::with('shopping_order')->with('shopping_order.shopping_user')->select('user_invoices.*')
->where('user_invoices.month', '=', Request::get('payment_taxadvisor_filter_month'))
->where('user_invoices.year', '=', Request::get('payment_taxadvisor_filter_year'));
return $query;
}
public function datatable(){
$query = $this->initSearch();
return \DataTables::eloquent($query)
->addColumn('id', function (UserInvoice $UserInvoice) {
return $UserInvoice->id;
})
->addColumn('turnover', function (UserInvoice $UserInvoice) {
return '<span class="no-line-break">'.$UserInvoice->shopping_order->getFormattedTotalShipping()." €</span>";
})
->addColumn('debit_credit_indicator', function (UserInvoice $UserInvoice) {
return "H";
})
->addColumn('account', function (UserInvoice $UserInvoice) {
if($UserInvoice->shopping_order && $UserInvoice->shopping_order->shopping_user){
$key = strtoupper(substr($UserInvoice->shopping_order->shopping_user->billing_lastname, 0, 1));
if($key === "S"){
if(strtoupper(substr($UserInvoice->shopping_order->shopping_user->billing_lastname, 0, 3)) === "SCH"){
return $this->accountKey['SCH'];
}
}
return isset($this->accountKey[$key]) ? $this->accountKey[$key] : $key;
}
return "-";
})
->addColumn('contra_account', function (UserInvoice $UserInvoice) {
return "-";
})
->addColumn('bu_key', function (UserInvoice $UserInvoice) {
if($UserInvoice->shopping_order){
return $UserInvoice->shopping_order->country_id;
}
})
->addColumn('voucher_date', function (UserInvoice $UserInvoice) {
// 101 -> für 01 Januar
return $UserInvoice->month."01";
})
->addColumn('document_field_1', function (UserInvoice $UserInvoice) {
//Rechnungsnummer
return $UserInvoice->full_number;
})
->addColumn('posting_text', function (UserInvoice $UserInvoice) {
//Buchungstext hier wäre es toll wenn der Name des Kunden steht.
if($UserInvoice->shopping_order && $UserInvoice->shopping_order->shopping_user){
return $UserInvoice->shopping_order->shopping_user->billing_firstname." ".$UserInvoice->shopping_order->shopping_user->billing_lastname;
}
return "-";
})
->addColumn('invoice', function (UserInvoice $UserInvoice) {
$ret = "";
$ret .= '<a href="'.route('storage_file', [$UserInvoice->shopping_order->id, 'invoice', 'download']).'" class="btn btn-primary btn-xs"><i class="fa fa-download"></i></a> ';
$ret .= '<a href="'.route('storage_file', [$UserInvoice->shopping_order->id, 'invoice', 'stream']).'" target="_blank" class="btn btn-warning btn-xs"><i class="fa fa-eye"></i></a>';
return $ret;
})
->orderColumn('id', 'id $1')
->orderColumn('invoice_number', 'invoice_number $1')
->orderColumn('turnover', 'turnover $1')
->orderColumn('shipped', 'shipped $1')
->orderColumn('total_shipping', 'total_shipping $1')
->rawColumns(['id', 'shipping_order', 'turnover', 'total_shipping', 'status', 'txaction', 'invoice'])
->make(true);
}
}
}