mivita/app/Http/Controllers/Portal/OrderController.php
2026-04-10 17:15:27 +02:00

268 lines
9.7 KiB
PHP

<?php
namespace App\Http\Controllers\Portal;
use App\Http\Controllers\Controller;
use App\Models\Product;
use App\Models\ShoppingOrder;
use App\Models\ShoppingPayment;
use App\Models\ShoppingUser;
use App\Services\Payment;
use App\Services\ProductOrderContext;
use App\Services\Shop;
use App\Services\Util;
use Auth;
use Illuminate\Support\Facades\Session;
use Yard;
class OrderController extends Controller
{
private string $instance = 'webshop';
public function __construct()
{
$this->middleware('auth:customers');
}
/**
* Bestellübersicht anzeigen.
*/
public function myOrders()
{
return view('portal.order.my_orders');
}
/**
* DataTable-Daten für Bestellübersicht (server-side).
*/
public function ordersDatatable()
{
$user = Auth::guard('customers')->user();
if (! $user->shopping_user_id) {
return \DataTables::of(collect())->make(true);
}
$shopping_user = ShoppingUser::findOrFail($user->shopping_user_id);
$userIds = ShoppingUser::where('billing_email', $shopping_user->billing_email)
->where('member_id', $shopping_user->member_id)
->pluck('id');
$query = ShoppingOrder::with('shopping_user')
->select('shopping_orders.*')
->whereIn('shopping_user_id', $userIds)
->whereNotNull('txaction');
return \DataTables::eloquent($query)
->addColumn('id', function (ShoppingOrder $order) {
return '<a href="'.route('portal.my_orders.show', $order->id).'" '
.'class="btn icon-btn btn-sm btn-primary"><span class="fa fa-eye"></span></a>';
})
->addColumn('created_at', function (ShoppingOrder $order) {
return $order->created_at->format('d.m.Y');
})
->addColumn('total_shipping', function (ShoppingOrder $order) {
return '<span class="no-line-break">'.$order->getFormattedTotalShipping().' €</span>';
})
->addColumn('txaction', function (ShoppingOrder $order) {
return Payment::getShoppingOrderBadge($order);
})
->addColumn('shipped', function (ShoppingOrder $order) {
return '<span class="badge badge-pill badge-'.$order->getShippedColor().'">'
.$order->getShippedType().'</span>';
})
->addColumn('firstname', function (ShoppingOrder $order) {
return $order->shopping_user->billing_firstname ?? '-';
})
->addColumn('lastname', function (ShoppingOrder $order) {
return $order->shopping_user->billing_lastname ?? '-';
})
->addColumn('email', function (ShoppingOrder $order) {
return $order->shopping_user->billing_email ?? '-';
})
->addColumn('invoice', function (ShoppingOrder $order) {
if ($order->isInvoice()) {
return '<span class="no-line-break">'
.'<a href="'.route('storage_file', [$order->id, 'invoice', 'download']).'" '
.'class="btn btn-primary btn-xs"><i class="fa fa-download"></i></a> '
.'<a href="'.route('storage_file', [$order->id, 'invoice', 'stream']).'" '
.'target="_blank" class="btn btn-warning btn-xs"><i class="fa fa-eye"></i></a>'
.'</span>';
}
return '-';
})
->addColumn('payment_for', function (ShoppingOrder $order) {
return Payment::getPaymentForBadge($order);
})
->orderColumn('id', 'shopping_orders.id $1')
->orderColumn('created_at', 'shopping_orders.created_at $1')
->orderColumn('total_shipping', 'shopping_orders.total_shipping $1')
->orderColumn('txaction', 'shopping_orders.txaction $1')
->orderColumn('shipped', 'shopping_orders.shipped $1')
->rawColumns(['id', 'txaction', 'payment_for', 'total_shipping', 'invoice', 'shipped'])
->make(true);
}
/**
* Bestelldetail anzeigen.
*/
public function myOrderShow(int $id)
{
$user = Auth::guard('customers')->user();
if (! $user->shopping_user_id) {
abort(403, 'Unauthorized action.');
}
$shopping_order = ShoppingOrder::with('shopping_user', 'shopping_order_items.product.images')
->findOrFail($id);
$shopping_user = ShoppingUser::findOrFail($user->shopping_user_id);
if (! $this->orderBelongsToMember($shopping_order, $shopping_user)) {
abort(403, 'Unauthorized action.');
}
return view('portal.order.my_order_show', [
'shopping_order' => $shopping_order,
'shopping_user' => $shopping_user,
]);
}
/**
* DataTable-Daten für Zahlungen einer Bestellung (server-side).
*/
public function paymentsDatatable(int $id)
{
$user = Auth::guard('customers')->user();
if (! $user->shopping_user_id) {
return \DataTables::of(collect())->make(true);
}
$shopping_order = ShoppingOrder::findOrFail($id);
$shopping_user = ShoppingUser::findOrFail($user->shopping_user_id);
if (! $this->orderBelongsToMember($shopping_order, $shopping_user)) {
abort(403, 'Unauthorized action.');
}
$query = ShoppingPayment::where('shopping_order_id', $id);
$counter = 0;
return \DataTables::eloquent($query)
->addColumn('line_number', function (ShoppingPayment $payment) use (&$counter) {
$counter++;
return $counter;
})
->addColumn('payment_type', function (ShoppingPayment $payment) {
return $payment->getPaymentType();
})
->addColumn('amount', function (ShoppingPayment $payment) {
return $payment->getPaymentAmount();
})
->addColumn('status', function (ShoppingPayment $payment) {
return Payment::getShoppingPaymentBadge($payment);
})
->addColumn('created_at', function (ShoppingPayment $payment) {
return $payment->created_at->format('d.m.Y H:i');
})
->addColumn('reference', function (ShoppingPayment $payment) {
return $payment->reference;
})
->rawColumns(['status'])
->make(true);
}
/**
* Prüft, ob Bestellung zum Mitglied gehört (billing_email + member_id).
*/
private function orderBelongsToMember(ShoppingOrder $order, ShoppingUser $member): bool
{
$orderUser = $order->shopping_user;
return $orderUser
&& $orderUser->billing_email === $member->billing_email
&& $orderUser->member_id === $member->member_id;
}
/**
* Bestellung erneut in den Warenkorb legen.
*/
public function myOrderCreate(int $id)
{
$user = Auth::guard('customers')->user();
$shopping_order = ShoppingOrder::with('member.shop')->findOrFail($id);
if ($shopping_order->shopping_user_id != $user->shopping_user_id) {
$shopping_user = ShoppingUser::findOrFail($user->shopping_user_id);
if (! $this->orderBelongsToMember($shopping_order, $shopping_user)) {
abort(403, 'Unauthorized action.');
}
}
$shopping_user = ShoppingUser::findOrFail($user->shopping_user_id);
if ($shopping_order->is_abo) {
Session::flash('alert-error', __('order.reorder_abo_not_allowed'));
return redirect()->route('portal.my_orders.show', $shopping_order->id);
}
$delivery_country = $shopping_user->getDeliveryCountry(true);
\Session::put('user_init_country', strtolower($delivery_country->code));
\Session::forget('user_init_country_options');
\Session::put('locale', strtolower(\App::getLocale()));
Shop::initUserShopLang($delivery_country, $this->instance);
foreach ($shopping_order->shopping_order_items as $item) {
if ($item->product && ProductOrderContext::isProductAllowedInCustomerWebshop($item->product)) {
$this->addToCart($item->product_id, $item->qty);
}
}
return redirect(Util::getCustomerReorderCartUrl($shopping_order));
}
private function addToCart(int $productId, int $quantity = 1): void
{
$product = Product::find($productId);
if (! $product || ! ProductOrderContext::isProductAllowedInCustomerWebshop($product)) {
return;
}
$image = $product->images->first()?->slug ?? '';
$yard = Yard::instance($this->instance);
$cartItem = $yard->add(
$product->id,
$product->getLang('name'),
$quantity,
$product->getPriceWith($yard->getUserTaxFree(), false, $yard->getUserCountry()),
false,
false,
[
'image' => $image,
'slug' => $product->slug,
'weight' => $product->weight,
'points' => $product->points,
'no_commission' => $product->no_commission,
'no_free_shipping' => $product->no_free_shipping,
'show_on' => $product->show_on,
]
);
if ($yard->getUserTaxFree()) {
Yard::setTax($cartItem->rowId, 0);
} else {
Yard::setTax($cartItem->rowId, $product->getTaxWith($yard->getUserCountry()));
}
$yard->reCalculateShippingPrice();
\Session()->flash('show-card-after-add', true);
}
}