- shopping_orders.shipped_at (+ Herkunft live/dhl/geschaetzt): gesetzt im Model, sobald der Versandstatus auf versendet wechselt, egal an welcher Stelle der Status gesetzt wird. sales:backfill-shipped-at traegt Altbestellungen aus dem DHL-Label nach oder schaetzt. - SalesVolumeService rechnet Absatzmengen je Produkt wahlweise nach Versand (inkl. externer/API-Bestellungen, Stornos im Monat des Stornobelegs) oder nach Rechnung. Sets werden fuer die zweite Liste in Einzelartikel aufgeloest. - Admin-Seite: Umschalter Versand/Rechnung, Datenqualitaet (Anteil geschaetzter Versanddaten), Export Produkte und Einzelartikel. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
188 lines
6.1 KiB
PHP
188 lines
6.1 KiB
PHP
<?php
|
||
|
||
namespace App\Http\Controllers\Admin;
|
||
|
||
use App\Exports\UserTeamExport;
|
||
use App\Exports\xExport;
|
||
use App\Http\Controllers\Controller;
|
||
use App\Services\HTMLHelper;
|
||
use App\Services\SalesVolumeService;
|
||
use Maatwebsite\Excel\Facades\Excel;
|
||
use Request;
|
||
|
||
/**
|
||
* Absatzmengen je Produkt – wahlweise nach Versand (Warenausgang) oder nach
|
||
* Rechnungseingang (Zahlung). Die eigentliche Ermittlung liegt in
|
||
* {@see SalesVolumeService}, hier stehen nur Filter, Datatables und Exporte.
|
||
*/
|
||
class PaymentSalesController extends Controller
|
||
{
|
||
/** Zweite Liste der Seite: Sets/Kits in ihre Anlagen aufgeloest. */
|
||
private const LIST_ARTICLES = 'articles';
|
||
|
||
public function __construct()
|
||
{
|
||
$this->middleware('admin');
|
||
}
|
||
|
||
public function index()
|
||
{
|
||
$service = $this->makeService();
|
||
|
||
$data = [
|
||
'filter_months' => HTMLHelper::getTransMonths(),
|
||
'filter_years' => HTMLHelper::getYearRange(2022),
|
||
'filter_basis' => SalesVolumeService::basisOptions(),
|
||
'basis' => $service->getBasis(),
|
||
'basis_label' => $service->getBasisLabel(),
|
||
'quality' => $service->getQualityStats(),
|
||
];
|
||
|
||
return view('admin.payment.salesvolume', $data);
|
||
}
|
||
|
||
public function datatable()
|
||
{
|
||
$service = $this->makeService();
|
||
|
||
$objects = Request::get('list') === self::LIST_ARTICLES
|
||
? $service->getArticleVolumes()
|
||
: $service->getProductVolumes();
|
||
|
||
$collection = collect();
|
||
|
||
foreach ($objects as $key => $obj) {
|
||
$collection->push([
|
||
'id' => $obj['product_id'] ?: $key,
|
||
'name' => $obj['name'],
|
||
'number' => $obj['number'],
|
||
'value' => $obj['value'],
|
||
]);
|
||
}
|
||
|
||
return \DataTables::of($collection)->toJson();
|
||
}
|
||
|
||
public function download()
|
||
{
|
||
if (Request::get('action') === 'exportfull_paid_invoice') {
|
||
return $this->exportFullList();
|
||
}
|
||
if (Request::get('action') === 'export_articles') {
|
||
return $this->exportKompaktList(self::LIST_ARTICLES);
|
||
}
|
||
if (Request::get('action') === 'export') {
|
||
return $this->exportKompaktList();
|
||
}
|
||
}
|
||
|
||
private function exportKompaktList(?string $list = null)
|
||
{
|
||
$service = $this->makeService();
|
||
$objects = $list === self::LIST_ARTICLES
|
||
? $service->getArticleVolumes()
|
||
: $service->getProductVolumes();
|
||
|
||
$columns = [];
|
||
$headers = ['#', 'Produkt', 'Artikelnummer', 'Menge'];
|
||
|
||
foreach ($objects as $key => $obj) {
|
||
$columns[] = [
|
||
'id' => $obj['product_id'] ?: $key,
|
||
'name' => $obj['name'],
|
||
'number' => $obj['number'],
|
||
'value' => $obj['value'],
|
||
];
|
||
}
|
||
|
||
$filename = 'mivita-absatzmengen-'.$this->getBasisSlug().'-'
|
||
.($list === self::LIST_ARTICLES ? 'einzelartikel' : 'kompakt').'-'
|
||
.session('payment_sales_vol_filter_month').'_'.session('payment_sales_vol_filter_year').'-export';
|
||
|
||
return Excel::download(new UserTeamExport($columns, $headers), $filename.'.xls');
|
||
}
|
||
|
||
private function exportFullList()
|
||
{
|
||
$service = $this->makeService();
|
||
$isShipping = $service->getBasis() === SalesVolumeService::BASIS_SHIPPING;
|
||
|
||
$headers = [
|
||
$isShipping ? 'Bestellung' : 'Rechnungsnummer',
|
||
$isShipping ? 'Versanddatum' : 'Rechnungsdatum',
|
||
'EMail',
|
||
'Zahlung',
|
||
'ProduktNummer',
|
||
'ProduktName',
|
||
'Anzahl',
|
||
'Summe',
|
||
'Hinweis',
|
||
];
|
||
|
||
$columns = [];
|
||
$total = [];
|
||
|
||
foreach ($service->getRows() as $row) {
|
||
$key = $row['product_id'] ?: $row['number'];
|
||
$total[$key] = ($total[$key] ?? 0) + $row['qty'];
|
||
|
||
$columns[] = [
|
||
'ref' => $row['ref'],
|
||
'date' => $row['date'],
|
||
'email' => $row['email'],
|
||
'payment' => $row['payment_type'],
|
||
'number' => $row['number'],
|
||
'name' => $row['name'],
|
||
'qty' => $row['qty'],
|
||
'sum' => $total[$key],
|
||
'note' => $row['note'],
|
||
];
|
||
}
|
||
|
||
$filename = 'mivita-absatzmengen-'.$this->getBasisSlug().'-voll-'
|
||
.session('payment_sales_vol_filter_month').'_'.session('payment_sales_vol_filter_year').'-export';
|
||
|
||
return Excel::download(new xExport($columns, $headers), $filename.'.xls');
|
||
}
|
||
|
||
private function makeService(): SalesVolumeService
|
||
{
|
||
$this->setFilterVars();
|
||
|
||
return new SalesVolumeService(
|
||
(int) session('payment_sales_vol_filter_month'),
|
||
(int) session('payment_sales_vol_filter_year'),
|
||
(string) session('payment_sales_vol_filter_basis'),
|
||
);
|
||
}
|
||
|
||
private function getBasisSlug(): string
|
||
{
|
||
return session('payment_sales_vol_filter_basis') === SalesVolumeService::BASIS_INVOICE
|
||
? 'rechnung'
|
||
: 'versand';
|
||
}
|
||
|
||
private function setFilterVars(): void
|
||
{
|
||
if (! session('payment_sales_vol_filter_month')) {
|
||
session(['payment_sales_vol_filter_month' => intval(date('m'))]);
|
||
}
|
||
if (! session('payment_sales_vol_filter_year')) {
|
||
session(['payment_sales_vol_filter_year' => intval(date('Y'))]);
|
||
}
|
||
if (! session('payment_sales_vol_filter_basis')) {
|
||
session(['payment_sales_vol_filter_basis' => SalesVolumeService::BASIS_SHIPPING]);
|
||
}
|
||
|
||
if (Request::get('payment_sales_vol_filter_month')) {
|
||
session(['payment_sales_vol_filter_month' => Request::get('payment_sales_vol_filter_month')]);
|
||
}
|
||
if (Request::get('payment_sales_vol_filter_year')) {
|
||
session(['payment_sales_vol_filter_year' => Request::get('payment_sales_vol_filter_year')]);
|
||
}
|
||
if (Request::get('payment_sales_vol_filter_basis')) {
|
||
session(['payment_sales_vol_filter_basis' => Request::get('payment_sales_vol_filter_basis')]);
|
||
}
|
||
}
|
||
}
|