20-02-2026
This commit is contained in:
parent
a8b395e20d
commit
a00c42e770
252 changed files with 28785 additions and 8907 deletions
|
|
@ -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);
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue