172 lines
5.5 KiB
PHP
172 lines
5.5 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Http\Controllers\Bo;
|
|
|
|
use App\Http\Controllers\Controller;
|
|
use App\Http\Requests\Bo\Discounts\StoreDiscountRequest;
|
|
use App\Http\Requests\Bo\Discounts\UpdateDiscountRequest;
|
|
use App\Models\Discount;
|
|
use App\Models\Product;
|
|
use App\Services\DataTableService;
|
|
use App\Traits\Controllers\ChangesModelOrder;
|
|
use App\Traits\Controllers\TogglesModelStatus;
|
|
use Domain\Enums\DiscountType;
|
|
use Illuminate\Contracts\View\View;
|
|
use Illuminate\Http\RedirectResponse;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Str;
|
|
|
|
class DiscountsController extends Controller
|
|
{
|
|
use ChangesModelOrder;
|
|
use TogglesModelStatus;
|
|
|
|
public function index(DataTableService $dataTable): View
|
|
{
|
|
$this->authorize('viewAny', Discount::class);
|
|
|
|
$query = Discount::query();
|
|
|
|
$dataTable->sortQuery(Discount::class, $query);
|
|
|
|
$discounts = $dataTable->paginateQuery($query);
|
|
|
|
return view('bo.discounts.index', compact('discounts'));
|
|
}
|
|
|
|
public function create(): View
|
|
{
|
|
$this->authorize('create', Discount::class);
|
|
|
|
$discountTypes = DiscountType::cases();
|
|
$existingProds = Product::query()
|
|
->select(['id', 'name'])
|
|
->orderBy('name')
|
|
->get();
|
|
$selectedProds = [];
|
|
|
|
return view('bo.discounts.create', compact(
|
|
'discountTypes',
|
|
'existingProds',
|
|
'selectedProds'
|
|
));
|
|
}
|
|
|
|
public function store(StoreDiscountRequest $request): RedirectResponse
|
|
{
|
|
$this->authorize('create', Discount::class);
|
|
|
|
return DB::transaction(function () use ($request) {
|
|
$discount = new Discount();
|
|
$discount->fill($request->only(
|
|
$discount->getFillable()
|
|
));
|
|
$discount->value = $request->getDiscountValue();
|
|
|
|
if ($discount->saveOrFail()) {
|
|
$this->syncAssociatedProducts(
|
|
$request->getAssociatedProductsIds(),
|
|
$discount
|
|
);
|
|
|
|
return to_route('bo.discounts.edit', $discount)
|
|
->with('success', trans('crud.messages.has_been_created', [
|
|
'model' => Str::ucfirst(trans_choice('models.classes.discounts', 1)),
|
|
]));
|
|
}
|
|
|
|
return to_route('bo.discounts.create')
|
|
->with('error', trans('crud.messages.cannot_be_created', [
|
|
'model' => Str::ucfirst(trans_choice('models.classes.discounts', 1)),
|
|
]));
|
|
});
|
|
}
|
|
|
|
public function edit(Discount $discount): View
|
|
{
|
|
$this->authorize('update', $discount);
|
|
|
|
$discountTypes = DiscountType::cases();
|
|
|
|
$selectedProds = $discount->products()
|
|
->select(['products.id', 'products.name'])
|
|
->get();
|
|
$existingProds = Product::query()
|
|
->select(['id', 'name'])
|
|
->whereNotIn('id', $selectedProds->pluck('id'))
|
|
->orderBy('name')
|
|
->get();
|
|
|
|
return view('bo.discounts.edit', compact(
|
|
'discount',
|
|
'discountTypes',
|
|
'existingProds',
|
|
'selectedProds',
|
|
));
|
|
}
|
|
|
|
public function update(UpdateDiscountRequest $request, Discount $discount): RedirectResponse
|
|
{
|
|
$this->authorize('update', $discount);
|
|
|
|
return DB::transaction(function () use ($request, $discount) {
|
|
$discount->fill($request->only(
|
|
$discount->getFillable()
|
|
));
|
|
|
|
$discount->value = $request->getDiscountValue();
|
|
|
|
$this->syncAssociatedProducts(
|
|
$request->getAssociatedProductsIds(),
|
|
$discount
|
|
);
|
|
|
|
if ($discount->saveOrFail()) {
|
|
return to_route('bo.discounts.edit', $discount)
|
|
->with('success', trans('crud.messages.has_been_updated', [
|
|
'model' => Str::ucfirst(trans_choice('models.classes.discounts', 1)),
|
|
]));
|
|
}
|
|
|
|
return to_route('bo.discounts.edit', $discount)
|
|
->with('error', trans('crud.messages.cannot_be_updated', [
|
|
'model' => Str::ucfirst(trans_choice('models.classes.discounts', 1)),
|
|
]));
|
|
});
|
|
}
|
|
|
|
public function destroy(Discount $discount): RedirectResponse
|
|
{
|
|
$this->authorize('delete', $discount);
|
|
|
|
return DB::transaction(function () use ($discount) {
|
|
if ($discount->deleteOrFail()) {
|
|
return to_route('bo.discounts.index')
|
|
->with('warning', trans('crud.messages.has_been_deleted', [
|
|
'model' => Str::ucfirst(trans_choice('models.classes.discounts', 1)),
|
|
]));
|
|
}
|
|
|
|
return to_route('bo.discounts.edit', $discount)
|
|
->with('error', trans('crud.messages.cannot_be_deleted', [
|
|
'model' => Str::ucfirst(trans_choice('models.classes.discounts', 1)),
|
|
]));
|
|
});
|
|
}
|
|
|
|
/** @param array<string> $productIdList */
|
|
private function syncAssociatedProducts(array $productIdList, Discount $discount): void
|
|
{
|
|
$discount->products()
|
|
->whereNotIn('id', $productIdList)
|
|
->update(['discount_id' => null]);
|
|
|
|
if (! empty($productIdList)) {
|
|
Product::query()
|
|
->whereIn('id', $productIdList)
|
|
->update(['discount_id' => $discount->id]);
|
|
}
|
|
}
|
|
}
|