April 2026 waren Wirtschaft Feedback

This commit is contained in:
Kevin Adametz 2026-04-10 17:14:38 +02:00
parent 02f2a4c23e
commit 9ce711d6b2
167 changed files with 25278 additions and 8518 deletions

View file

@ -0,0 +1,59 @@
<?php
namespace App\Http\Controllers\Admin\Inventory;
use App\Http\Controllers\Controller;
use App\Http\Requests\Inventory\StoreLocationRequest;
use App\Http\Requests\Inventory\UpdateLocationRequest;
use App\Models\Location;
class LocationController extends Controller
{
public function index()
{
return view('admin.inventory.locations.index', [
'values' => Location::query()->orderBy('name')->get(),
]);
}
public function create()
{
return view('admin.inventory.locations.form', [
'model' => new Location(['active' => true]),
]);
}
public function store(StoreLocationRequest $request)
{
Location::create($request->validated());
\Session::flash('alert-save', '1');
return redirect()->route('admin.inventory.locations.index');
}
public function edit(Location $location)
{
return view('admin.inventory.locations.form', [
'model' => $location,
]);
}
public function update(UpdateLocationRequest $request, Location $location)
{
$location->update($request->validated());
\Session::flash('alert-save', '1');
return redirect()->route('admin.inventory.locations.index');
}
public function destroy(Location $location)
{
$location->delete();
\Session::flash('alert-success', __('Eintrag gelöscht'));
return redirect()->route('admin.inventory.locations.index');
}
}

View file

@ -0,0 +1,59 @@
<?php
namespace App\Http\Controllers\Admin\Inventory;
use App\Http\Controllers\Controller;
use App\Http\Requests\Inventory\StoreMaterialQualityRequest;
use App\Http\Requests\Inventory\UpdateMaterialQualityRequest;
use App\Models\MaterialQuality;
class MaterialQualityController extends Controller
{
public function index()
{
return view('admin.inventory.material-qualities.index', [
'values' => MaterialQuality::query()->orderBy('pos')->orderBy('name')->get(),
]);
}
public function create()
{
return view('admin.inventory.material-qualities.form', [
'model' => new MaterialQuality(['pos' => 0]),
]);
}
public function store(StoreMaterialQualityRequest $request)
{
MaterialQuality::create($request->validated());
\Session::flash('alert-save', '1');
return redirect()->route('admin.inventory.material-qualities.index');
}
public function edit(MaterialQuality $materialQuality)
{
return view('admin.inventory.material-qualities.form', [
'model' => $materialQuality,
]);
}
public function update(UpdateMaterialQualityRequest $request, MaterialQuality $materialQuality)
{
$materialQuality->update($request->validated());
\Session::flash('alert-save', '1');
return redirect()->route('admin.inventory.material-qualities.index');
}
public function destroy(MaterialQuality $materialQuality)
{
$materialQuality->delete();
\Session::flash('alert-success', __('Eintrag gelöscht'));
return redirect()->route('admin.inventory.material-qualities.index');
}
}

View file

@ -0,0 +1,98 @@
<?php
namespace App\Http\Controllers\Admin\Inventory;
use App\Http\Controllers\Controller;
use App\Http\Requests\Inventory\StorePackagingItemRequest;
use App\Http\Requests\Inventory\UpdatePackagingItemRequest;
use App\Models\PackagingItem;
use App\Models\PackagingMaterial;
use App\Models\Supplier;
use App\Repositories\PackagingItemRepository;
use Illuminate\Http\Request;
class PackagingItemController extends Controller
{
public function __construct(
protected PackagingItemRepository $packagingItemRepository
) {}
public function index(Request $request)
{
$category = $request->get('category', 'packaging');
$isShipping = $category === 'shipping';
$query = PackagingItem::query()
->with(['packagingMaterial', 'supplier'])
->orderBy('name');
if ($isShipping) {
$query->whereIn('category', ['shipping', 'label', 'shipping_office']);
} else {
$query->where('category', 'packaging');
}
return view('admin.inventory.packaging-items.index', [
'values' => $query->get(),
'category' => $category,
'pageTitle' => $isShipping ? __('Versandverpackung') : __('Produktverpackung'),
]);
}
public function create(Request $request)
{
$category = $request->get('category', 'packaging');
return view('admin.inventory.packaging-items.form', [
'model' => new PackagingItem(['active' => true, 'category' => $category === 'shipping' ? 'shipping' : 'packaging', 'weight_grams' => 0]),
'packagingMaterials' => PackagingMaterial::query()->orderBy('pos')->orderBy('name')->get(),
'suppliers' => Supplier::query()->orderBy('name')->get(),
'category' => $category,
]);
}
public function store(StorePackagingItemRequest $request)
{
$item = $this->packagingItemRepository->create($request->validated());
\Session::flash('alert-save', '1');
$category = in_array($item->category, ['shipping', 'label', 'shipping_office']) ? 'shipping' : 'packaging';
return redirect()->route('admin.inventory.packaging-items.index', ['category' => $category]);
}
public function edit(PackagingItem $packagingItem)
{
$category = in_array($packagingItem->category, ['shipping', 'label', 'shipping_office']) ? 'shipping' : 'packaging';
return view('admin.inventory.packaging-items.form', [
'model' => $packagingItem,
'packagingMaterials' => PackagingMaterial::query()->orderBy('pos')->orderBy('name')->get(),
'suppliers' => Supplier::query()->orderBy('name')->get(),
'category' => $category,
]);
}
public function update(UpdatePackagingItemRequest $request, PackagingItem $packagingItem)
{
$this->packagingItemRepository->update($packagingItem, $request->validated());
\Session::flash('alert-save', '1');
$category = in_array($packagingItem->category, ['shipping', 'label', 'shipping_office']) ? 'shipping' : 'packaging';
return redirect()->route('admin.inventory.packaging-items.index', ['category' => $category]);
}
public function destroy(PackagingItem $packagingItem)
{
$category = in_array($packagingItem->category, ['shipping', 'label', 'shipping_office']) ? 'shipping' : 'packaging';
$packagingItem->delete();
\Session::flash('alert-success', __('Eintrag gelöscht'));
return redirect()->route('admin.inventory.packaging-items.index', ['category' => $category]);
}
}

View file

@ -0,0 +1,59 @@
<?php
namespace App\Http\Controllers\Admin\Inventory;
use App\Http\Controllers\Controller;
use App\Http\Requests\Inventory\StorePackagingMaterialRequest;
use App\Http\Requests\Inventory\UpdatePackagingMaterialRequest;
use App\Models\PackagingMaterial;
class PackagingMaterialController extends Controller
{
public function index()
{
return view('admin.inventory.packaging-materials.index', [
'values' => PackagingMaterial::query()->orderBy('pos')->orderBy('name')->get(),
]);
}
public function create()
{
return view('admin.inventory.packaging-materials.form', [
'model' => new PackagingMaterial(['pos' => 0]),
]);
}
public function store(StorePackagingMaterialRequest $request)
{
PackagingMaterial::create($request->validated());
\Session::flash('alert-save', '1');
return redirect()->route('admin.inventory.packaging-materials.index');
}
public function edit(PackagingMaterial $packagingMaterial)
{
return view('admin.inventory.packaging-materials.form', [
'model' => $packagingMaterial,
]);
}
public function update(UpdatePackagingMaterialRequest $request, PackagingMaterial $packagingMaterial)
{
$packagingMaterial->update($request->validated());
\Session::flash('alert-save', '1');
return redirect()->route('admin.inventory.packaging-materials.index');
}
public function destroy(PackagingMaterial $packagingMaterial)
{
$packagingMaterial->delete();
\Session::flash('alert-success', __('Eintrag gelöscht'));
return redirect()->route('admin.inventory.packaging-materials.index');
}
}

View file

@ -0,0 +1,169 @@
<?php
namespace App\Http\Controllers\Admin\Inventory;
use App\Http\Controllers\Controller;
use App\Http\Requests\Inventory\StoreProductionRequest;
use App\Models\Location;
use App\Models\Product;
use App\Models\Production;
use App\Repositories\ProductionRepository;
use App\Services\ProductionService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Validation\ValidationException;
use Illuminate\View\View;
class ProductionController extends Controller
{
public function __construct(
protected ProductionRepository $productionRepository,
protected ProductionService $productionService
) {}
public function index(): View
{
return view('admin.inventory.productions.index', [
'values' => $this->productionRepository->listForIndex(),
]);
}
public function create(): View
{
$defaultLocationId = Location::query()->where('name', 'like', '%öln%')->value('id')
?? Location::query()->where('active', true)->first()?->id;
return view('admin.inventory.productions.create', [
'products' => Product::query()->where('active', 1)->orderBy('name')->get(['id', 'name']),
'locations' => Location::query()->where('active', true)->orderBy('name')->get(),
'defaultLocationId' => $defaultLocationId,
'model' => null,
]);
}
public function store(StoreProductionRequest $request): RedirectResponse
{
$payload = $request->validatedPayload();
try {
$production = $this->productionService->store(
[
'product_id' => $payload['product_id'],
'location_id' => $payload['location_id'],
'produced_at' => $payload['produced_at'],
'quantity' => $payload['quantity'],
'notes' => $payload['notes'],
],
$payload['ingredient_lines'],
(int) $request->user()->id
);
} catch (ValidationException $e) {
return redirect()->back()->withInput()->withErrors($e->errors());
}
if ($production->mhd_warning) {
\Session::flash('alert-warning', __('Hinweis: Mindestens eine Rohstoff-Charge hat ein kürzeres MHD als das geplante Produkt-MHD.'));
}
\Session::flash('alert-save', '1');
return redirect()->route('admin.inventory.productions.show', $production);
}
public function show(Production $production): View
{
$production->load([
'product',
'location',
'producedByUser.account',
'productionIngredients.ingredient',
'productionIngredients.stockEntry',
'productionPackagings.packagingItem.packagingMaterial',
]);
return view('admin.inventory.productions.show', [
'model' => $production,
]);
}
public function edit(Production $production): View
{
$production->load([
'product',
'location',
'productionIngredients.ingredient',
'productionIngredients.stockEntry',
]);
$defaultLocationId = $production->location_id;
return view('admin.inventory.productions.edit', [
'model' => $production,
'products' => Product::query()->where('active', 1)
->orWhere('id', $production->product_id)
->orderBy('name')->get(['id', 'name']),
'locations' => Location::query()->where('active', true)->orderBy('name')->get(),
'defaultLocationId' => $defaultLocationId,
]);
}
public function update(StoreProductionRequest $request, Production $production): RedirectResponse
{
$payload = $request->validatedPayload();
try {
$production = $this->productionService->updateProduction(
$production,
[
'product_id' => $payload['product_id'],
'location_id' => $payload['location_id'],
'produced_at' => $payload['produced_at'],
'quantity' => $payload['quantity'],
'notes' => $payload['notes'],
],
$payload['ingredient_lines'],
(int) $request->user()->id
);
} catch (ValidationException $e) {
return redirect()->back()->withInput()->withErrors($e->errors());
}
if ($production->mhd_warning) {
\Session::flash('alert-warning', __('Hinweis: Mindestens eine Rohstoff-Charge hat ein kürzeres MHD als das geplante Produkt-MHD.'));
}
\Session::flash('alert-save', '1');
return redirect()->route('admin.inventory.productions.show', $production);
}
public function copy(Production $production): View
{
$production->load([
'product',
'productionIngredients.ingredient',
'productionIngredients.stockEntry',
]);
$defaultLocationId = $production->location_id;
return view('admin.inventory.productions.create', [
'model' => $production,
'products' => Product::query()->where('active', 1)->orderBy('name')->get(['id', 'name']),
'locations' => Location::query()->where('active', true)->orderBy('name')->get(),
'defaultLocationId' => $defaultLocationId,
]);
}
public function recipeJson(Request $request, Product $product): JsonResponse
{
$locationId = (int) $request->query('location_id', 0);
$quantity = (int) $request->query('quantity', 1);
if ($locationId < 1) {
return response()->json(['message' => __('location_id erforderlich')], 422);
}
return response()->json(
$this->productionService->buildRecipePayload($product, $locationId, max(1, $quantity))
);
}
}

View file

@ -0,0 +1,234 @@
<?php
namespace App\Http\Controllers\Admin\Inventory;
use App\Http\Controllers\Controller;
use App\Http\Requests\Inventory\ReceiveStockEntryRequest;
use App\Http\Requests\Inventory\StoreStockEntryRequest;
use App\Http\Requests\Inventory\UpdateStockEntryRequest;
use App\Models\Ingredient;
use App\Models\Location;
use App\Models\MaterialQuality;
use App\Models\PackagingItem;
use App\Models\StockEntry;
use App\Models\Supplier;
use App\Repositories\StockEntryRepository;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\View\View;
class StockEntryController extends Controller
{
public function __construct(
protected StockEntryRepository $stockEntryRepository
) {}
public function index(): View
{
return view('admin.inventory.stock-entries.index', array_merge($this->formSharedData(), [
'values' => $this->stockEntryRepository->listForIndex(),
]));
}
public function create(): View|RedirectResponse
{
if (! auth()->user()->isAdmin()) {
return redirect()->route('home');
}
return view('admin.inventory.stock-entries.create', array_merge($this->formSharedData(), [
'model' => new StockEntry([
'ordered_at' => now()->toDateString(),
'entry_type' => 'ingredient',
]),
]));
}
public function store(StoreStockEntryRequest $request): RedirectResponse
{
if (! $request->user()->isAdmin()) {
return redirect()->route('home');
}
$data = $request->validatedPayload();
$data['ordered_by'] = (int) auth()->id();
$this->stockEntryRepository->create($data);
\Session::flash('alert-save', '1');
return redirect()->route('admin.inventory.stock-entries.index');
}
public function show(StockEntry $stockEntry): View
{
$stockEntry->load([
'ingredient',
'packagingItem.packagingMaterial',
'supplier',
'location',
'quality',
'orderedByUser.account',
'receivedByUser.account',
]);
return view('admin.inventory.stock-entries.show', array_merge($this->formSharedData(), [
'model' => $stockEntry,
'materialQualities' => MaterialQuality::query()->orderBy('pos')->orderBy('name')->get(),
]));
}
public function edit(StockEntry $stockEntry): View|RedirectResponse
{
if (! auth()->user()->isAdmin()) {
return redirect()->route('home');
}
if (! $stockEntry->isPending()) {
\Session::flash('alert-error', __('Nur offene Bestellungen können bearbeitet werden.'));
return redirect()->route('admin.inventory.stock-entries.show', $stockEntry);
}
$stockEntry->load(['ingredient', 'packagingItem']);
return view('admin.inventory.stock-entries.edit', array_merge($this->formSharedData(), [
'model' => $stockEntry,
]));
}
public function update(UpdateStockEntryRequest $request, StockEntry $stockEntry): RedirectResponse
{
if (! $request->user()->isAdmin()) {
return redirect()->route('home');
}
if (! $stockEntry->isPending()) {
\Session::flash('alert-error', __('Nur offene Bestellungen können bearbeitet werden.'));
return redirect()->route('admin.inventory.stock-entries.show', $stockEntry);
}
$this->stockEntryRepository->update($stockEntry, $request->validatedPayload());
\Session::flash('alert-save', '1');
return redirect()->route('admin.inventory.stock-entries.index');
}
public function destroy(StockEntry $stockEntry): RedirectResponse
{
if (! auth()->user()->isAdmin()) {
return redirect()->route('home');
}
if (! $stockEntry->isPending()) {
\Session::flash('alert-error', __('Nur offene Bestellungen können gelöscht werden.'));
return redirect()->route('admin.inventory.stock-entries.index');
}
$stockEntry->delete();
\Session::flash('alert-success', __('Eintrag gelöscht'));
return redirect()->route('admin.inventory.stock-entries.index');
}
public function receive(ReceiveStockEntryRequest $request, StockEntry $stockEntry): RedirectResponse
{
if (! $stockEntry->isPending()) {
\Session::flash('alert-error', __('Eintrag nicht mehr offen.'));
return redirect()->route('admin.inventory.stock-entries.show', $stockEntry);
}
$data = $request->validated();
if ($stockEntry->entry_type !== 'ingredient') {
$data['quality_id'] = null;
$data['best_before'] = null;
}
$this->stockEntryRepository->receive($stockEntry, $data);
\Session::flash('alert-save', '1');
return redirect()->route('admin.inventory.stock-entries.show', $stockEntry->fresh());
}
public function searchIngredients(Request $request): JsonResponse
{
$term = trim((string) $request->query('q', ''));
if (mb_strlen($term) < 1) {
return response()->json(['results' => []]);
}
$rows = Ingredient::query()
->where('active', true)
->where(function ($query) use ($term) {
$query->where('name', 'like', '%'.$term.'%')
->orWhere('inci', 'like', '%'.$term.'%');
})
->orderBy('name')
->limit(30)
->get(['id', 'name', 'inci']);
$results = $rows->map(function (Ingredient $i) {
$text = $i->name;
if ($i->inci) {
$text .= ' ('.$i->inci.')';
}
return ['id' => $i->id, 'text' => $text];
})->values()->all();
return response()->json(['results' => $results]);
}
public function searchPackagingItems(Request $request): JsonResponse
{
$term = trim((string) $request->query('q', ''));
$entryType = $request->query('entry_type');
$categoryMap = [
'packaging' => 'packaging',
'label' => 'label',
'shipping_office' => 'shipping_office',
];
$query = PackagingItem::query()
->where('active', true);
if ($entryType && isset($categoryMap[$entryType])) {
$query->where('category', $categoryMap[$entryType]);
}
if (mb_strlen($term) >= 1) {
$query->where('name', 'like', '%'.$term.'%');
}
$rows = $query->orderBy('name')->limit(30)->get(['id', 'name']);
$results = $rows->map(fn (PackagingItem $p) => [
'id' => $p->id,
'text' => $p->name,
])->values()->all();
return response()->json(['results' => $results]);
}
/**
* @return array<string, mixed>
*/
protected function formSharedData(): array
{
return [
'suppliers' => Supplier::query()->where('active', true)->orderBy('name')->get(),
'locations' => Location::query()->where('active', true)->orderBy('name')->get(),
'entryTypeLabels' => [
'ingredient' => __('Rohstoff'),
'packaging' => __('Verpackung'),
'label' => __('Etikett'),
'shipping_office' => __('Versand & Büro'),
],
];
}
}

View file

@ -0,0 +1,59 @@
<?php
namespace App\Http\Controllers\Admin\Inventory;
use App\Http\Controllers\Controller;
use App\Http\Requests\Inventory\StoreSupplierCategoryRequest;
use App\Http\Requests\Inventory\UpdateSupplierCategoryRequest;
use App\Models\SupplierCategory;
class SupplierCategoryController extends Controller
{
public function index()
{
return view('admin.inventory.supplier-categories.index', [
'values' => SupplierCategory::query()->orderBy('pos')->orderBy('name')->get(),
]);
}
public function create()
{
return view('admin.inventory.supplier-categories.form', [
'model' => new SupplierCategory(['pos' => 0]),
]);
}
public function store(StoreSupplierCategoryRequest $request)
{
SupplierCategory::create($request->validated());
\Session::flash('alert-save', '1');
return redirect()->route('admin.inventory.supplier-categories.index');
}
public function edit(SupplierCategory $supplierCategory)
{
return view('admin.inventory.supplier-categories.form', [
'model' => $supplierCategory,
]);
}
public function update(UpdateSupplierCategoryRequest $request, SupplierCategory $supplierCategory)
{
$supplierCategory->update($request->validated());
\Session::flash('alert-save', '1');
return redirect()->route('admin.inventory.supplier-categories.index');
}
public function destroy(SupplierCategory $supplierCategory)
{
$supplierCategory->delete();
\Session::flash('alert-success', __('Eintrag gelöscht'));
return redirect()->route('admin.inventory.supplier-categories.index');
}
}

View file

@ -0,0 +1,74 @@
<?php
namespace App\Http\Controllers\Admin\Inventory;
use App\Http\Controllers\Controller;
use App\Http\Requests\Inventory\StoreSupplierRequest;
use App\Http\Requests\Inventory\UpdateSupplierRequest;
use App\Models\Country;
use App\Models\Supplier;
use App\Models\SupplierCategory;
use App\Repositories\SupplierRepository;
class SupplierController extends Controller
{
public function __construct(
protected SupplierRepository $supplierRepository
) {}
public function index()
{
return view('admin.inventory.suppliers.index', [
'values' => Supplier::query()->with(['country', 'supplierCategories'])->orderBy('name')->get(),
]);
}
public function create()
{
$defaultCountryId = Country::where('code', 'DE')->value('id');
return view('admin.inventory.suppliers.form', [
'model' => new Supplier(['active' => true, 'country_id' => $defaultCountryId]),
'countries' => Country::query()->orderBy('de')->get(),
'supplierCategories' => SupplierCategory::query()->orderBy('pos')->orderBy('name')->get(),
]);
}
public function store(StoreSupplierRequest $request)
{
$this->supplierRepository->create($request->validated());
\Session::flash('alert-save', '1');
return redirect()->route('admin.inventory.suppliers.index');
}
public function edit(Supplier $supplier)
{
$supplier->load('supplierCategories');
return view('admin.inventory.suppliers.form', [
'model' => $supplier,
'countries' => Country::query()->orderBy('de')->get(),
'supplierCategories' => SupplierCategory::query()->orderBy('pos')->orderBy('name')->get(),
]);
}
public function update(UpdateSupplierRequest $request, Supplier $supplier)
{
$this->supplierRepository->update($supplier, $request->validated());
\Session::flash('alert-save', '1');
return redirect()->route('admin.inventory.suppliers.index');
}
public function destroy(Supplier $supplier)
{
$supplier->delete();
\Session::flash('alert-success', __('Eintrag gelöscht'));
return redirect()->route('admin.inventory.suppliers.index');
}
}

View file

@ -2,11 +2,15 @@
namespace App\Http\Controllers;
use Storage;
use Response;
use App\Models\File;
use App\Models\ShoppingOrder;
use App\Models\UserCredit;
use App\Services\Credit;
use App\Services\Invoice;
use App\Services\PDFMerger;
use Auth;
use Response;
use Storage;
class FileController extends Controller
{
@ -15,58 +19,63 @@ class FileController extends Controller
*
* @return void
*/
public function __construct()
public function __construct() {}
private function isPermission($user_id)
{
}
private function isPermission($user_id){
if(Auth::user()->isAdmin() || $user_id == Auth::user()->id){
if (Auth::user()->isAdmin() || $user_id == Auth::user()->id) {
return true;
}
abort(404);
abort(404);
}
public function show($id = null, $disk = null, $do='file')
public function show($id = null, $disk = null, $do = 'file')
{
$path = "";
$filename = "";
$path = '';
$filename = '';
if($disk === 'user'){
$file = \App\Models\File::findOrFail($id);
if ($disk === 'user') {
$file = File::findOrFail($id);
$this->isPermission($file->user_id);
$path = Storage::disk($disk)->path($file->dir.$file->filename);
if (file_exists($path)) {
return Response::file($path);
}
}
if ($disk === 'invoice'){
$shopping_order = \App\Models\ShoppingOrder::findOrFail($id);
if ($disk === 'invoice') {
$shopping_order = ShoppingOrder::findOrFail($id);
$this->isPermission($shopping_order->auth_user_id);
$filename = Invoice::getFilename($shopping_order);
$filename = Invoice::getFilename($shopping_order);
$path = Invoice::getDownloadPath($shopping_order);
}
if ($disk === 'delivery'){
$shopping_order = \App\Models\ShoppingOrder::findOrFail($id);
if ($disk === 'delivery') {
$shopping_order = ShoppingOrder::findOrFail($id);
$this->isPermission($shopping_order->auth_user_id);
$filename = Invoice::getDeliveryFilename($shopping_order);
$filename = Invoice::getDeliveryFilename($shopping_order);
$path = Invoice::getDownloadPathDelivery($shopping_order);
}
if ($disk === 'invoice_delivery'){
$shopping_order = \App\Models\ShoppingOrder::findOrFail($id);
if ($disk === 'cancellation') {
$shopping_order = ShoppingOrder::findOrFail($id);
$this->isPermission($shopping_order->auth_user_id);
$filename = Invoice::getCancellationFilename($shopping_order);
$path = Invoice::getCancellationDownloadPath($shopping_order);
}
if ($disk === 'invoice_delivery') {
$shopping_order = ShoppingOrder::findOrFail($id);
$this->isPermission($shopping_order->auth_user_id);
$ifilename = Invoice::getFilename($shopping_order);
$ifilename = Invoice::getFilename($shopping_order);
$ipath = Invoice::getDownloadPath($shopping_order, true);
$dfilename = Invoice::getDeliveryFilename($shopping_order);
$dfilename = Invoice::getDeliveryFilename($shopping_order);
$dpath = Invoice::getDownloadPathDelivery($shopping_order, true);
$oMerger = new \App\Services\PDFMerger();
$oMerger = new PDFMerger;
$oMerger->init();
$oMerger->addPDF($ipath);
@ -75,61 +84,61 @@ class FileController extends Controller
$oMerger->setFileName($filename);
$oMerger->merge();
$file = $oMerger->output();
return Response::make($file, 200)
->header("Content-Type", 'application/pdf')
->header('Content-Type', 'application/pdf')
->header('Content-disposition', 'attachment; filename="'.$filename.'"');
}
if ($disk === 'credit'){
$UserCredit = \App\Models\UserCredit::findOrFail($id);
if ($disk === 'credit') {
$UserCredit = UserCredit::findOrFail($id);
$this->isPermission($UserCredit->auth_user_id);
$filename = Credit::getFilename($UserCredit);
$filename = Credit::getFilename($UserCredit);
$path = Credit::getDownloadPath($UserCredit);
}
if (!Storage::disk('public')->exists($path)) {
if (! Storage::disk('public')->exists($path)) {
return Response::make('File no found.', 404);
}
$file = Storage::disk('public')->get($path);
$mime = Storage::disk('public')->mimeType($path);
if($do === 'download'){
if ($do === 'download') {
return Response::make($file, 200)
->header("Content-Type", $mime)
->header('Content-Type', $mime)
->header('Content-disposition', 'attachment; filename="'.$filename.'"');
/* $full_path = Invoice::getDownloadPath($shopping_order, true);
$he
if (file_exists($full_path)) {
return Response::download($full_path, $filename);
}*/
/* $full_path = Invoice::getDownloadPath($shopping_order, true);
$he
if (file_exists($full_path)) {
return Response::download($full_path, $filename);
}*/
}
if($do === 'stream'){
if ($do === 'stream') {
return Response::make($file, 200)
->header("Content-Type", $mime)
->header('Content-disposition','filename="'.$filename.'"');
}
if($do === 'file'){
return Response::make($file, 200)
->header("Content-Type", $mime)
->header('Content-Type', $mime)
->header('Content-disposition', 'filename="'.$filename.'"');
}
if($do === 'image'){
return Response::make($file, 200)
->header("Content-Type", $mime);
}
if($do === 'pdf'){
$path = storage_path().'/app/public/' . $path;
$headers = array(
'Content-Type:'. $mime,
// 'Content-Length: ' . $file->size
// 'Content-Disposition: ' . $stream . '; filename=' . $file->original_name
);
return Response::download($path, $filename, $headers);
}
if ($do === 'file') {
return Response::make($file, 200)
->header('Content-Type', $mime)
->header('Content-disposition', 'filename="'.$filename.'"');
}
if ($do === 'image') {
return Response::make($file, 200)
->header('Content-Type', $mime);
}
if ($do === 'pdf') {
$path = storage_path().'/app/public/'.$path;
$headers = [
'Content-Type:'.$mime,
// 'Content-Length: ' . $file->size
// 'Content-Disposition: ' . $stream . '; filename=' . $file->original_name
];
return Response::download($path, $filename, $headers);
}
}
}
}

View file

@ -2,18 +2,12 @@
namespace App\Http\Controllers;
use App\Models\Category;
use App\Models\Ingredient;
use App\Models\IqImage;
use App\Models\ProductCategory;
use App\Models\ProductIngredient;
use Request;
class IngredientController extends Controller
{
public function __construct()
{
$this->middleware('copyreader');
@ -25,22 +19,24 @@ class IngredientController extends Controller
$data = [
'values' => Ingredient::all(),
];
return view('admin.ingredient.index', $data);
}
public function edit($id)
{
if($id === "new"){
$model = new Ingredient();
if ($id === 'new') {
$model = new Ingredient;
$model->active = true;
}else{
} else {
$model = Ingredient::findOrFail($id);
}
$data = [
'model' => $model,
//'trans' => array_keys(config('localization.supportedLocales')),
// 'trans' => array_keys(config('localization.supportedLocales')),
];
return view('admin.ingredient.edit', $data);
}
@ -49,30 +45,42 @@ class IngredientController extends Controller
$data = Request::all();
$data['active'] = isset($data['active']) ? true : false;
if($data['id'] === "new"){
if (isset($data['default_factor']) && $data['default_factor'] !== '') {
$data['default_factor'] = reFormatNumber($data['default_factor']) ?: 1.10;
}
if (isset($data['min_stock_alert']) && $data['min_stock_alert'] === '') {
$data['min_stock_alert'] = null;
} elseif (isset($data['min_stock_alert']) && $data['min_stock_alert'] !== null) {
$data['min_stock_alert'] = reFormatNumber($data['min_stock_alert']);
}
if (empty($data['material_quality_id'])) {
$data['material_quality_id'] = null;
}
if ($data['id'] === 'new') {
$model = Ingredient::create($data);
}else{
} else {
$model = Ingredient::find($data['id']);
$model->fill($data)->save();
}
\Session()->flash('alert-save', '1');
return redirect(route('admin_product_ingredients'));
return redirect(route('admin_product_ingredients'));
}
public function delete($id){
public function delete($id)
{
if(ProductIngredient::where('ingredient_id', $id)->count()) {
if (ProductIngredient::where('ingredient_id', $id)->count()) {
\Session()->flash('alert-error', 'Eintrag wird als Produkt-Inhaltsstoff verwendet');
return redirect(route('admin_product_ingredients'));
}
$model = Ingredient::findOrFail($id);
$model->delete();
\Session()->flash('alert-success', 'Eintrag gelöscht');
return redirect(route('admin_product_ingredients'));
}
}
}

View file

@ -3,6 +3,8 @@
namespace App\Http\Controllers;
use App\Models\Country;
use App\Models\Ingredient;
use App\Models\PackagingItem;
use App\Models\Product;
use App\Models\ProductImage;
use App\Models\ProductIngredient;
@ -10,8 +12,6 @@ use App\Repositories\ProductRepository;
use Request;
use Validator;
class ProductController extends Controller
{
protected $productRepo;
@ -24,35 +24,40 @@ class ProductController extends Controller
public function index()
{
if(Request::get('show_active_products')){
if (Request::get('show_active_products')) {
set_user_attr('show_active_products', Request::get('show_active_products'));
}
if(get_user_attr('show_active_products') === "true"){
if (get_user_attr('show_active_products') === 'true') {
$values = Product::where('active', true)->orderBy('pos', 'DESC')->orderBy('id', 'DESC')->get();
}else{
} else {
$values = Product::orderBy('pos', 'DESC')->orderBy('id', 'DESC')->get();
}
$data = [
'values' => $values
'values' => $values,
];
return view('admin.product.index', $data);
}
public function edit($id)
{
if($id === "new"){
$model = new Product();
if ($id === 'new') {
$model = new Product;
$model->active = true;
}else{
} else {
$model = Product::findOrFail($id);
$model->load(['packagings.packagingMaterial']);
}
$country_for_prices = Country::where('own_eur', '=', true)->orWhere('currency', '=', true)->get();
$data = [
'product' => $model,
'country_for_prices' => $country_for_prices,
'ingredient_catalog' => Ingredient::query()->where('active', true)->with('materialQuality')->orderBy('name')->get(['id', 'name', 'inci', 'effect', 'default_factor', 'material_quality_id']),
'packaging_catalog' => PackagingItem::query()->where('active', true)->with('packagingMaterial')->orderBy('name')->get(),
];
return view('admin.product.edit', $data);
}
@ -61,34 +66,36 @@ class ProductController extends Controller
$data = Request::all();
$rules = array(
$rules = [
'name' => 'required',
);
];
/*if(isset($data['number']) && $data['number'] != ""){
$rules['number'] = 'int';
}*/
if(isset($data['wp_number'])){
if($data['id'] !== "new"){
if (isset($data['wp_number'])) {
if ($data['id'] !== 'new') {
$model = Product::findOrFail($data['id']);
$rules['wp_number'] = 'unique:products,wp_number,'.$model->id;
}else{
} else {
$rules['wp_number'] = 'unique:products,wp_number';
}
}
$validator = Validator::make(Request::all(), $rules);
if($data['id'] === "new"){
$model = new Product();
}else{
if ($data['id'] === 'new') {
$model = new Product;
} else {
$model = Product::findOrFail($data['id']);
$model->load(['packagings.packagingMaterial']);
}
$country_for_prices = Country::where('own_eur', '=', true)->orWhere('currency', '=', true)->get();
$data = [
'product' => $model,
'country_for_prices' => $country_for_prices,
'ingredient_catalog' => Ingredient::query()->where('active', true)->with('materialQuality')->orderBy('name')->get(['id', 'name', 'inci', 'effect', 'default_factor', 'material_quality_id']),
'packaging_catalog' => PackagingItem::query()->where('active', true)->with('packagingMaterial')->orderBy('name')->get(),
];
if ($validator->fails()) {
@ -98,34 +105,41 @@ class ProductController extends Controller
} else {
$product = $this->productRepo->update(Request::all());
\Session()->flash('alert-save', true);
return redirect(route('admin_product_edit', [$product->id]));
}
\Session()->flash('alert-save', '1');
return redirect(route('admin_product_show'));
}
public function copy($id){
public function copy($id)
{
$model = Product::findOrFail($id);
$product = $this->productRepo->copy($model);
\Session()->flash('alert-success', 'Eintrag kopiert');
return redirect(route('admin_product_show'));
}
public function delete($id, $do = 'product', $did = null){
if($do === 'product'){
public function delete($id, $do = 'product', $did = null)
{
if ($do === 'product') {
$model = Product::findOrFail($id);
$model->delete();
\Session()->flash('alert-success', 'Eintrag gelöscht');
return redirect(route('admin_product_show'));
}
if($do === 'ingredient'){
if ($do === 'ingredient') {
$model = Product::findOrFail($id);
$ProductIngredient = ProductIngredient::where('ingredient_id', $did)->where('product_id', $model->id)->first();
if($ProductIngredient){
if ($ProductIngredient) {
$ProductIngredient->delete();
\Session()->flash('alert-success', 'Eintrag gelöscht');
return redirect(route('admin_product_edit', [$model->id]));
}
@ -134,24 +148,29 @@ class ProductController extends Controller
}
// Upload FILE -----------------------------------------------------------------------------------------------------------------------
public function imageUpload(){
public function imageUpload()
{
if(Request::has('product_id')){
if (Request::has('product_id')) {
$product = Product::findOrFail(Request::get('product_id'));
return \App\Services\ProductImage::imageUpload('product', $product, Request::get('upload_type'));
}
}
public function imageDelete($product_image_id, $product_id){
public function imageDelete($product_image_id, $product_id)
{
$product = Product::findOrFail($product_id);
return \App\Services\ProductImage::imageDelete('product', $product, $product_image_id);
}
public function imageAttribute($product_id, $attr, $val = false){
public function imageAttribute($product_id, $attr, $val = false)
{
if(is_numeric($val) && $val < 0){
if (is_numeric($val) && $val < 0) {
$val = 0;
}
@ -160,9 +179,9 @@ class ProductController extends Controller
$product_image->{$attr} = $val;
$product_image->save();
\Session()->flash('alert-success', "Wert gespeichert");
\Session()->flash('alert-success', 'Wert gespeichert');
return redirect()->back();
}
}
}

View file

@ -2,46 +2,48 @@
namespace App\Http\Controllers;
use Request;
use App\Models\Setting;
use App\Services\Payment;
use App\Models\ShoppingUser;
use App\Models\ShoppingOrder;
use App\Models\UserPayCredit;
use App\Models\ShoppingPayment;
use App\Models\PaymentTransaction;
use App\Services\CustomerPriority;
use App\Models\ShoppingUser;
use App\Repositories\InvoiceRepository;
use App\Services\CustomerPriority;
use App\Services\Invoice;
use App\Services\Payment;
use App\Services\PaymentService;
use Request;
class SalesController extends Controller
{
public function __construct(){
public function __construct()
{
$this->middleware('admin');
}
public function index(){
public function index()
{
if(Request::get('reset') === 'filter'){
if (Request::get('reset') === 'filter') {
set_user_attr('filter_txaction', null);
set_user_attr('filter_member_id', null);
set_user_attr('filter_art', null);
set_user_attr('filter_shipped', null);
return redirect(route('admin_sales'));
}
//set Filter!
// set Filter!
$filter_members = ShoppingOrder::join('users', 'member_id', '=', 'users.id')->groupBy('member_id')->join('user_accounts', 'account_id', '=', 'user_accounts.id')->select('users.id', 'users.email', 'user_accounts.first_name', 'user_accounts.last_name')->get();
$data = [
'filter_members' => $filter_members,
];
return view('admin.sales.index', $data);
}
public function detail($id){
public function detail($id)
{
$ShoppingOrder = ShoppingOrder::find($id);
if($ShoppingOrder->shipped == 0){
if ($ShoppingOrder->shipped == 0) {
$ShoppingOrder->shipped = 1;
$ShoppingOrder->save();
}
@ -54,37 +56,42 @@ class SalesController extends Controller
return view('admin.sales.detail', $data);
}
public function detailStore($id){
public function detailStore($id)
{
$data = Request::all();
$change_member_error = false;
if($data['action']==='shopping-order-change-member'){
if(!isset($data['change_member_key']) || $data['change_member_key'] !== config('main.edit_data_pass')){
$change_member_error = "Das Passwort ist falsch.";
}else{
//change
if ($data['action'] === 'shopping-order-change-member') {
if (! isset($data['change_member_key']) || $data['change_member_key'] !== config('main.edit_data_pass')) {
$change_member_error = 'Das Passwort ist falsch.';
} else {
// change
$shopping_order = ShoppingOrder::findOrFail($data['id']);
CustomerPriority::newMemberForOrder($shopping_order, $data['change_member_id'], $data['customer_set_member_for']);
\Session()->flash('alert-save', true);
return redirect(route('admin_sales_detail', [$shopping_order->id]));
}
}
if($data['action']==='shopping-user-is-like-member'){
if(!isset($data['change_member_key']) || $data['change_member_key'] !== config('main.edit_data_pass')){
\Session()->flash('alert-error', 'Das Passwort ist falsch.');
return redirect($data['back']);
}else{
if(!isset($data['is_like_shopping_user_id'])){
if ($data['action'] === 'shopping-user-is-like-member') {
if (! isset($data['change_member_key']) || $data['change_member_key'] !== config('main.edit_data_pass')) {
\Session()->flash('alert-error', 'Das Passwort ist falsch.');
return redirect($data['back']);
} else {
if (! isset($data['is_like_shopping_user_id'])) {
\Session()->flash('alert-error', 'Keine Änderung ausgewählt');
return redirect($data['back']);
}
$shopping_user = ShoppingUser::findOrFail($data['id']);
$set_like_shopping_user = ShoppingUser::findOrFail($data['is_like_shopping_user_id']);
$send_member_mail = isset($data['send_member_mail']) ? true : false;
$change_shopping_user = isset($data['change_shopping_user']) ? true : false;
//Mail send in setIsLike
// Mail send in setIsLike
CustomerPriority::setIsLike($shopping_user, $set_like_shopping_user, $send_member_mail, $change_shopping_user);
\Session()->flash('alert-save', true);
return redirect($data['back']);
}
}
@ -95,54 +102,57 @@ class SalesController extends Controller
'isAdmin' => true,
'isView' => $ShoppingOrder->auth_user_id ? 'sales_user' : 'sales_customer',
];
return view('admin.sales.detail', $data);
}
public function datatable(){
public function datatable()
{
$query = ShoppingOrder::with('shopping_user', 'shopping_payments')->select('shopping_orders.*');
set_user_attr('filter_txaction', Request::get('filter_txaction'));
if(Request::get('filter_txaction') != ""){
if(Request::get('filter_txaction') === 'NULL'){
$query->where('txaction', '=', NULL);
if (Request::get('filter_txaction') != '') {
if (Request::get('filter_txaction') === 'NULL') {
$query->where('txaction', '=', null);
}else{
} else {
$query->where('txaction', '=', Request::get('filter_txaction'));
}
}
set_user_attr('filter_member_id', Request::get('filter_member_id'));
if(Request::get('filter_member_id') != ""){
if (Request::get('filter_member_id') != '') {
$query->where('member_id', '=', Request::get('filter_member_id'));
}
set_user_attr('filter_art', Request::get('filter_art'));
if(Request::get('filter_art') != ""){
if(Request::get('filter_art') === 'user_order'){
$query->where('shopping_orders.auth_user_id', '!=', NULL)->where('payment_for', '!=', 6);
}elseif(Request::get('filter_art') === 'customer_order'){
$query->where('shopping_orders.auth_user_id', NULL);
}elseif(Request::get('filter_art') === 'user_for_customer'){
$query->where('shopping_user_id', '!=', NULL)->where('payment_for', '=', 6);
if (Request::get('filter_art') != '') {
if (Request::get('filter_art') === 'user_order') {
$query->where('shopping_orders.auth_user_id', '!=', null)->where('payment_for', '!=', 6);
} elseif (Request::get('filter_art') === 'customer_order') {
$query->where('shopping_orders.auth_user_id', null);
} elseif (Request::get('filter_art') === 'user_for_customer') {
$query->where('shopping_user_id', '!=', null)->where('payment_for', '=', 6);
}
// $query->where('payment_for', '=', Request::get('filter_art'));
// $query->where('payment_for', '=', Request::get('filter_art'));
}
set_user_attr('filter_shipped', Request::get('filter_shipped'));
if(Request::get('filter_shipped') != ""){
if (Request::get('filter_shipped') != '') {
$query->where('shipped', '=', Request::get('filter_shipped'));
}
return \DataTables::eloquent($query)
->addColumn('id', function (ShoppingOrder $ShoppingOrder) {
return '<a href="' . route('admin_sales_detail', [$ShoppingOrder->id]) . '" class="btn icon-btn btn-sm btn-primary"><span class="fa fa-edit"></span></a>';
return '<a href="'.route('admin_sales_detail', [$ShoppingOrder->id]).'" class="btn icon-btn btn-sm btn-primary"><span class="fa fa-edit"></span></a>';
})
->addColumn('created_at', function (ShoppingOrder $ShoppingOrder) {
return $ShoppingOrder->created_at->format("d.m.Y");
return $ShoppingOrder->created_at->format('d.m.Y');
})
->addColumn('txaction', function (ShoppingOrder $ShoppingOrder) {
return Payment::getShoppingOrderBadge($ShoppingOrder);
})
->addColumn('total_shipping', function (ShoppingOrder $ShoppingOrder) {
return $ShoppingOrder->getFormattedTotalShipping()."";
return $ShoppingOrder->getFormattedTotalShipping().' €';
})
->addColumn('payment', function (ShoppingOrder $ShoppingOrder) {
return $ShoppingOrder->getLastShoppingPayment('getPaymentType');
@ -157,10 +167,10 @@ class SalesController extends Controller
return $ShoppingOrder->getLastShoppingPayment('reference');
})
->addColumn('member_id', function (ShoppingOrder $ShoppingOrder) {
if($ShoppingOrder->member_id) {
return $ShoppingOrder->member_id ? '<a href="' . route('admin_lead_edit', [$ShoppingOrder->member_id]) . '">' . $ShoppingOrder->member->getFullName() . '</a>' : '';
if ($ShoppingOrder->member_id) {
return $ShoppingOrder->member_id ? '<a href="'.route('admin_lead_edit', [$ShoppingOrder->member_id]).'">'.$ShoppingOrder->member->getFullName().'</a>' : '';
}
if($ShoppingOrder->shopping_user && $ShoppingOrder->shopping_user->is_like){
if ($ShoppingOrder->shopping_user && $ShoppingOrder->shopping_user->is_like) {
return '<button type="button" class="btn btn-xs btn-outline-info" data-toggle="modal" data-target="#modals-load-content"
data-id="'.$ShoppingOrder->shopping_user->id.'"
data-action="shopping-user-is-like-member"
@ -168,6 +178,7 @@ class SalesController extends Controller
data-modal="modal-xl"
data-route="'.route('modal_load').'"><span class="fa fa-edit"></span> Vertriebspartner zuordnen</button>';
}
return '';
})
@ -382,9 +393,9 @@ class SalesController extends Controller
if($ShoppingOrder->shopping_user && $ShoppingOrder->shopping_user->is_like){
return '<button type="button" class="btn btn-xs btn-outline-info" data-toggle="modal" data-target="#modals-load-content"
data-id="'.$ShoppingOrder->shopping_user->id.'"
data-action="shopping-user-is-like-member"
data-back="'.route('admin_sales').'"
data-modal="modal-xl"
data-action="shopping-user-is-like-member"
data-back="'.route('admin_sales').'"
data-modal="modal-xl"
data-route="'.route('modal_load').'"><span class="fa fa-edit"></span> Vertriebspartner zuordnen</button>';
}
return '';
@ -400,34 +411,35 @@ class SalesController extends Controller
->make(true);
}*/
public function store(){
public function store()
{
$data = Request::all();
if(!isset($data['id'])){
if (! isset($data['id'])) {
abort(404);
}
if(isset($data['action'])){
if($data['action'] === 'store_shipped' && isset($data['shipped'])){
if (isset($data['action'])) {
if ($data['action'] === 'store_shipped' && isset($data['shipped'])) {
$shopping_order = ShoppingOrder::findOrFail($data['id']);
$shopping_order->shipped = $data['shipped'];
$shopping_order->save();
//handel Promotion Product and credit by storno
// handel Promotion Product and credit by storno
Payment::handelUserPromotionOrder($shopping_order);
Payment::handelUserShopOrder($shopping_order);
if($shopping_order->getAPIShippedType() === 'sent' || $shopping_order->getAPIShippedType() === 'close'){
if(!$shopping_order->shipped_at){
if ($shopping_order->getAPIShippedType() === 'sent' || $shopping_order->getAPIShippedType() === 'close') {
if (! $shopping_order->shipped_at) {
$shopping_order->shipped_at = now();
$shopping_order->save();
//is shipped set pending_to
if($shopping_order->shopping_order_margin){
if($shopping_order->shopping_order_margin->hasPartnerCommission()){
$days = Setting::getContentBySlug('pending_partner_commissions_in_days');
// is shipped set pending_to
if ($shopping_order->shopping_order_margin) {
if ($shopping_order->shopping_order_margin->hasPartnerCommission()) {
$days = Setting::getContentBySlug('pending_partner_commissions_in_days');
$days = $days ? $days : 20;
$partner_commission_pending_to = $shopping_order->shipped_at;
$partner_commission_pending_to->addDays($days);
$shopping_order->shopping_order_margin->partner_commission_pending_to = $partner_commission_pending_to;
$shopping_order->shopping_order_margin->save();
}else{
} else {
$days = Setting::getContentBySlug('pending_order_margins_in_days');
$days = $days ? $days : 20;
$margin_pending_to = $shopping_order->shipped_at;
@ -437,25 +449,25 @@ class SalesController extends Controller
}
}
}
}else{
} else {
$shopping_order->shipped_at = null;
$shopping_order->save();
if($shopping_order->shopping_order_margin){
//zurücksetzen der pending_to
if ($shopping_order->shopping_order_margin) {
// zurücksetzen der pending_to
$shopping_order->shopping_order_margin->partner_commission_pending_to = null;
$shopping_order->shopping_order_margin->margin_pending_to = null;
$shopping_order->shopping_order_margin->save();
}
}
if($shopping_order->getAPIShippedType() === 'cancel'){
if($shopping_order->shopping_order_margin){
if ($shopping_order->getAPIShippedType() === 'cancel') {
if ($shopping_order->shopping_order_margin) {
$shopping_order->shopping_order_margin->cancellation = true;
$shopping_order->shopping_order_margin->partner_commission_pending_to = null;
$shopping_order->shopping_order_margin->margin_pending_to = null;
$shopping_order->shopping_order_margin->save();
}
}else{
if($shopping_order->shopping_order_margin && $shopping_order->shopping_order_margin->cancellation){
} else {
if ($shopping_order->shopping_order_margin && $shopping_order->shopping_order_margin->cancellation) {
$shopping_order->shopping_order_margin->cancellation = false;
$shopping_order->shopping_order_margin->partner_commission_pending_to = null;
$shopping_order->shopping_order_margin->margin_pending_to = null;
@ -463,53 +475,94 @@ class SalesController extends Controller
}
}
}
/* txaction ändern
änderung der txaction von der Bestellung, Status Zahlung, offen, bezahlt, keine zahlung */
if($data['action'] === 'store_txaction' && isset($data['txaction']) && isset($data['payment_id'])){
if ($data['action'] === 'store_txaction' && isset($data['txaction']) && isset($data['payment_id'])) {
PaymentService::updateTransactionStatus($data['id'], $data['txaction'], $data['payment_id']);
}
}
if(isset($data['back'])){
if (isset($data['back'])) {
return redirect($data['back']);
}
return back();
}
public function invoice(){
public function invoice()
{
$data = Request::all();
if(!isset($data['id'])){
if (! isset($data['id'])) {
abort(404);
}
if(isset($data['action'])){
if($data['action'] === 'create_invoice'){
if (isset($data['action'])) {
if ($data['action'] === 'create_invoice') {
$shopping_order = ShoppingOrder::findOrFail($data['id']);
$invoice_repo = new InvoiceRepository($shopping_order);
if(\App\Services\Invoice::isInvoice($shopping_order)){
if (Invoice::isInvoice($shopping_order)) {
$user_invoice = $invoice_repo->update($data);
}else{
} else {
$user_invoice = $invoice_repo->create($data);
}
return redirect(route('admin_sales_detail', [$shopping_order->id]));
}
}
}
public function sendLogisticMail($id){
$shopping_order = ShoppingOrder::findOrFail($id);
if(\App\Services\Invoice::isInvoice($shopping_order)){
\App\Services\Invoice::sendLogisticMail($shopping_order);
\Session()->flash('alert-success', "Rechnung / Lieferschein wurde an den Versand gesendet.");
}else{
\Session()->flash('alert-error', "Keine Rechnung vorhanden.");
public function invoiceCancellation()
{
$data = Request::all();
if (! isset($data['id'])) {
abort(404);
}
return redirect(route('admin_sales_detail', [$shopping_order->id]));
if (isset($data['action'])) {
if ($data['action'] === 'create_cancellation_invoice') {
$shopping_order = ShoppingOrder::findOrFail($data['id']);
// Prüfen ob bereits eine Rechnung existiert
if (! Invoice::isInvoice($shopping_order)) {
\Session()->flash('alert-error', 'Es existiert keine Rechnung, die storniert werden kann.');
return redirect(route('admin_sales_detail', [$shopping_order->id]));
}
// Prüfen ob bereits eine Stornorechnung existiert
if (Invoice::isCancellationInvoice($shopping_order)) {
\Session()->flash('alert-error', 'Es existiert bereits eine Stornorechnung für diese Bestellung.');
return redirect(route('admin_sales_detail', [$shopping_order->id]));
}
$invoice_repo = new InvoiceRepository($shopping_order);
$cancellation_invoice = $invoice_repo->createCancellation($data);
if ($cancellation_invoice) {
\Session()->flash('alert-success', 'Stornorechnung wurde erfolgreich erstellt.');
} else {
\Session()->flash('alert-error', 'Fehler beim Erstellen der Stornorechnung.');
}
return redirect(route('admin_sales_detail', [$shopping_order->id]));
}
}
return redirect(route('admin_sales'));
}
}
public function sendLogisticMail($id)
{
$shopping_order = ShoppingOrder::findOrFail($id);
if (Invoice::isInvoice($shopping_order)) {
Invoice::sendLogisticMail($shopping_order);
\Session()->flash('alert-success', 'Rechnung / Lieferschein wurde an den Versand gesendet.');
} else {
\Session()->flash('alert-error', 'Keine Rechnung vorhanden.');
}
return redirect(route('admin_sales_detail', [$shopping_order->id]));
}
}

View file

@ -0,0 +1,34 @@
<?php
namespace App\Http\Requests\Inventory;
use Illuminate\Foundation\Http\FormRequest;
class ReceiveStockEntryRequest extends FormRequest
{
public function authorize(): bool
{
return true;
}
/**
* @return array<string, array<int, mixed>>
*/
public function rules(): array
{
return [
'received_at' => ['required', 'date'],
'received_quantity' => ['required', 'numeric', 'min:0.000001'],
'batch_number' => ['nullable', 'string', 'max:100'],
'best_before' => ['nullable', 'date'],
'quality_id' => ['nullable', 'integer', 'exists:material_qualities,id'],
];
}
protected function prepareForValidation(): void
{
$this->merge([
'received_quantity' => reFormatNumber($this->input('received_quantity')),
]);
}
}

View file

@ -0,0 +1,31 @@
<?php
namespace App\Http\Requests\Inventory;
use Illuminate\Foundation\Http\FormRequest;
class StoreLocationRequest extends FormRequest
{
public function authorize(): bool
{
return true;
}
/**
* @return array<string, array<int, string>>
*/
public function rules(): array
{
return [
'name' => ['required', 'string', 'max:255'],
'active' => ['sometimes', 'boolean'],
];
}
protected function prepareForValidation(): void
{
$this->merge([
'active' => $this->boolean('active'),
]);
}
}

View file

@ -0,0 +1,31 @@
<?php
namespace App\Http\Requests\Inventory;
use Illuminate\Foundation\Http\FormRequest;
class StoreMaterialQualityRequest extends FormRequest
{
public function authorize(): bool
{
return true;
}
/**
* @return array<string, array<int, string>>
*/
public function rules(): array
{
return [
'name' => ['required', 'string', 'max:255'],
'pos' => ['nullable', 'integer', 'min:0', 'max:255'],
];
}
protected function prepareForValidation(): void
{
if ($this->has('pos') && $this->input('pos') === '') {
$this->merge(['pos' => 0]);
}
}
}

View file

@ -0,0 +1,45 @@
<?php
namespace App\Http\Requests\Inventory;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;
class StorePackagingItemRequest extends FormRequest
{
public function authorize(): bool
{
return true;
}
/**
* @return array<string, array<int, mixed>>
*/
public function rules(): array
{
return [
'packaging_material_id' => ['required', 'integer', 'exists:packaging_materials,id'],
'supplier_id' => ['nullable', 'integer', 'exists:suppliers,id'],
'name' => ['required', 'string', 'max:255'],
'category' => ['required', Rule::in(['packaging', 'shipping', 'label', 'shipping_office'])],
'weight_grams' => ['nullable', 'numeric', 'min:0'],
'min_stock_alert' => ['nullable', 'integer', 'min:0'],
'url' => ['nullable', 'url', 'max:500'],
'product_id' => ['nullable', 'integer', 'exists:products,id'],
'active' => ['sometimes', 'boolean'],
];
}
protected function prepareForValidation(): void
{
$this->merge([
'active' => $this->boolean('active'),
]);
foreach (['supplier_id', 'product_id', 'min_stock_alert'] as $key) {
if ($this->input($key) === '' || $this->input($key) === null) {
$this->merge([$key => null]);
}
}
}
}

View file

@ -0,0 +1,31 @@
<?php
namespace App\Http\Requests\Inventory;
use Illuminate\Foundation\Http\FormRequest;
class StorePackagingMaterialRequest extends FormRequest
{
public function authorize(): bool
{
return true;
}
/**
* @return array<string, array<int, string>>
*/
public function rules(): array
{
return [
'name' => ['required', 'string', 'max:255'],
'pos' => ['nullable', 'integer', 'min:0', 'max:255'],
];
}
protected function prepareForValidation(): void
{
if ($this->has('pos') && $this->input('pos') === '') {
$this->merge(['pos' => 0]);
}
}
}

View file

@ -0,0 +1,54 @@
<?php
namespace App\Http\Requests\Inventory;
use Illuminate\Foundation\Http\FormRequest;
class StoreProductionRequest extends FormRequest
{
public function authorize(): bool
{
return true;
}
/**
* @return array<string, array<int, mixed|string>>
*/
public function rules(): array
{
return [
'product_id' => ['required', 'integer', 'exists:products,id'],
'location_id' => ['required', 'integer', 'exists:locations,id'],
'produced_at' => ['required', 'date'],
'quantity' => ['required', 'integer', 'min:1'],
'notes' => ['nullable', 'string', 'max:2000'],
'ingredient_lines' => ['required', 'array', 'min:1'],
'ingredient_lines.*.ingredient_id' => ['required', 'integer', 'exists:ingredients,id'],
'ingredient_lines.*.stock_entry_id' => ['required', 'integer', 'exists:stock_entries,id'],
'ingredient_lines.*.quantity_used' => ['required', 'string'],
];
}
/**
* @return array<string, mixed>
*/
public function validatedPayload(): array
{
$data = $this->validated();
return [
'product_id' => (int) $data['product_id'],
'location_id' => (int) $data['location_id'],
'produced_at' => $data['produced_at'],
'quantity' => (int) $data['quantity'],
'notes' => $data['notes'] ?? null,
'ingredient_lines' => array_map(function (array $line): array {
return [
'ingredient_id' => (int) $line['ingredient_id'],
'stock_entry_id' => (int) $line['stock_entry_id'],
'quantity_used' => $line['quantity_used'],
];
}, $data['ingredient_lines']),
];
}
}

View file

@ -0,0 +1,73 @@
<?php
namespace App\Http\Requests\Inventory;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;
use Illuminate\Validation\Validator;
class StoreStockEntryRequest extends FormRequest
{
public function authorize(): bool
{
return true;
}
/**
* @return array<string, array<int, mixed>>
*/
public function rules(): array
{
return [
'entry_type' => ['required', Rule::in(['ingredient', 'packaging', 'label', 'shipping_office'])],
'ingredient_id' => ['nullable', 'integer', 'exists:ingredients,id'],
'packaging_item_id' => ['nullable', 'integer', 'exists:packaging_items,id'],
'supplier_id' => ['required', 'integer', 'exists:suppliers,id'],
'location_id' => ['required', 'integer', 'exists:locations,id'],
'ordered_at' => ['required', 'date'],
'ordered_quantity' => ['required', 'numeric', 'min:0.000001'],
'price_per_kg' => ['nullable', 'numeric', 'min:0'],
'price_total' => ['nullable', 'numeric', 'min:0'],
];
}
protected function prepareForValidation(): void
{
$this->merge([
'ordered_quantity' => reFormatNumber($this->input('ordered_quantity')),
'price_per_kg' => $this->filled('price_per_kg') ? reFormatNumber($this->input('price_per_kg')) : null,
'price_total' => $this->filled('price_total') ? reFormatNumber($this->input('price_total')) : null,
]);
}
public function withValidator(Validator $validator): void
{
$validator->after(function (Validator $validator): void {
$type = $this->input('entry_type');
if ($type === 'ingredient') {
if (empty($this->input('ingredient_id'))) {
$validator->errors()->add('ingredient_id', __('Bitte einen Inhaltsstoff wählen.'));
}
} elseif (! empty($type)) {
if (empty($this->input('packaging_item_id'))) {
$validator->errors()->add('packaging_item_id', __('Bitte einen Verpackungsartikel wählen.'));
}
}
});
}
/**
* @return array<string, mixed>
*/
public function validatedPayload(): array
{
$data = $this->validated();
if (($data['entry_type'] ?? '') === 'ingredient') {
$data['packaging_item_id'] = null;
} else {
$data['ingredient_id'] = null;
}
return $data;
}
}

View file

@ -0,0 +1,31 @@
<?php
namespace App\Http\Requests\Inventory;
use Illuminate\Foundation\Http\FormRequest;
class StoreSupplierCategoryRequest extends FormRequest
{
public function authorize(): bool
{
return true;
}
/**
* @return array<string, array<int, string>>
*/
public function rules(): array
{
return [
'name' => ['required', 'string', 'max:255'],
'pos' => ['nullable', 'integer', 'min:0', 'max:255'],
];
}
protected function prepareForValidation(): void
{
if ($this->has('pos') && $this->input('pos') === '') {
$this->merge(['pos' => 0]);
}
}
}

View file

@ -0,0 +1,39 @@
<?php
namespace App\Http\Requests\Inventory;
use Illuminate\Foundation\Http\FormRequest;
class StoreSupplierRequest extends FormRequest
{
public function authorize(): bool
{
return true;
}
/**
* @return array<string, array<int, mixed>>
*/
public function rules(): array
{
return [
'name' => ['required', 'string', 'max:255'],
'url' => ['nullable', 'string', 'max:2048'],
'contact_person' => ['nullable', 'string', 'max:255'],
'email' => ['nullable', 'email', 'max:255'],
'phone' => ['nullable', 'string', 'max:100'],
'country_id' => ['required', 'integer', 'exists:countries,id'],
'notes' => ['nullable', 'string'],
'active' => ['sometimes', 'boolean'],
'supplier_category_ids' => ['nullable', 'array'],
'supplier_category_ids.*' => ['integer', 'exists:supplier_categories,id'],
];
}
protected function prepareForValidation(): void
{
$this->merge([
'active' => $this->boolean('active'),
]);
}
}

View file

@ -0,0 +1,31 @@
<?php
namespace App\Http\Requests\Inventory;
use Illuminate\Foundation\Http\FormRequest;
class UpdateLocationRequest extends FormRequest
{
public function authorize(): bool
{
return true;
}
/**
* @return array<string, array<int, string>>
*/
public function rules(): array
{
return [
'name' => ['required', 'string', 'max:255'],
'active' => ['sometimes', 'boolean'],
];
}
protected function prepareForValidation(): void
{
$this->merge([
'active' => $this->boolean('active'),
]);
}
}

View file

@ -0,0 +1,31 @@
<?php
namespace App\Http\Requests\Inventory;
use Illuminate\Foundation\Http\FormRequest;
class UpdateMaterialQualityRequest extends FormRequest
{
public function authorize(): bool
{
return true;
}
/**
* @return array<string, array<int, string>>
*/
public function rules(): array
{
return [
'name' => ['required', 'string', 'max:255'],
'pos' => ['nullable', 'integer', 'min:0', 'max:255'],
];
}
protected function prepareForValidation(): void
{
if ($this->has('pos') && $this->input('pos') === '') {
$this->merge(['pos' => 0]);
}
}
}

View file

@ -0,0 +1,45 @@
<?php
namespace App\Http\Requests\Inventory;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;
class UpdatePackagingItemRequest extends FormRequest
{
public function authorize(): bool
{
return true;
}
/**
* @return array<string, array<int, mixed>>
*/
public function rules(): array
{
return [
'packaging_material_id' => ['required', 'integer', 'exists:packaging_materials,id'],
'supplier_id' => ['nullable', 'integer', 'exists:suppliers,id'],
'name' => ['required', 'string', 'max:255'],
'category' => ['required', Rule::in(['packaging', 'shipping', 'label', 'shipping_office'])],
'weight_grams' => ['nullable', 'numeric', 'min:0'],
'min_stock_alert' => ['nullable', 'integer', 'min:0'],
'url' => ['nullable', 'url', 'max:500'],
'product_id' => ['nullable', 'integer', 'exists:products,id'],
'active' => ['sometimes', 'boolean'],
];
}
protected function prepareForValidation(): void
{
$this->merge([
'active' => $this->boolean('active'),
]);
foreach (['supplier_id', 'product_id', 'min_stock_alert'] as $key) {
if ($this->input($key) === '' || $this->input($key) === null) {
$this->merge([$key => null]);
}
}
}
}

View file

@ -0,0 +1,31 @@
<?php
namespace App\Http\Requests\Inventory;
use Illuminate\Foundation\Http\FormRequest;
class UpdatePackagingMaterialRequest extends FormRequest
{
public function authorize(): bool
{
return true;
}
/**
* @return array<string, array<int, string>>
*/
public function rules(): array
{
return [
'name' => ['required', 'string', 'max:255'],
'pos' => ['nullable', 'integer', 'min:0', 'max:255'],
];
}
protected function prepareForValidation(): void
{
if ($this->has('pos') && $this->input('pos') === '') {
$this->merge(['pos' => 0]);
}
}
}

View file

@ -0,0 +1,73 @@
<?php
namespace App\Http\Requests\Inventory;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;
use Illuminate\Validation\Validator;
class UpdateStockEntryRequest extends FormRequest
{
public function authorize(): bool
{
return true;
}
/**
* @return array<string, array<int, mixed>>
*/
public function rules(): array
{
return [
'entry_type' => ['required', Rule::in(['ingredient', 'packaging', 'label', 'shipping_office'])],
'ingredient_id' => ['nullable', 'integer', 'exists:ingredients,id'],
'packaging_item_id' => ['nullable', 'integer', 'exists:packaging_items,id'],
'supplier_id' => ['required', 'integer', 'exists:suppliers,id'],
'location_id' => ['required', 'integer', 'exists:locations,id'],
'ordered_at' => ['required', 'date'],
'ordered_quantity' => ['required', 'numeric', 'min:0.000001'],
'price_per_kg' => ['nullable', 'numeric', 'min:0'],
'price_total' => ['nullable', 'numeric', 'min:0'],
];
}
protected function prepareForValidation(): void
{
$this->merge([
'ordered_quantity' => reFormatNumber($this->input('ordered_quantity')),
'price_per_kg' => $this->filled('price_per_kg') ? reFormatNumber($this->input('price_per_kg')) : null,
'price_total' => $this->filled('price_total') ? reFormatNumber($this->input('price_total')) : null,
]);
}
public function withValidator(Validator $validator): void
{
$validator->after(function (Validator $validator): void {
$type = $this->input('entry_type');
if ($type === 'ingredient') {
if (empty($this->input('ingredient_id'))) {
$validator->errors()->add('ingredient_id', __('Bitte einen Inhaltsstoff wählen.'));
}
} elseif (! empty($type)) {
if (empty($this->input('packaging_item_id'))) {
$validator->errors()->add('packaging_item_id', __('Bitte einen Verpackungsartikel wählen.'));
}
}
});
}
/**
* @return array<string, mixed>
*/
public function validatedPayload(): array
{
$data = $this->validated();
if (($data['entry_type'] ?? '') === 'ingredient') {
$data['packaging_item_id'] = null;
} else {
$data['ingredient_id'] = null;
}
return $data;
}
}

View file

@ -0,0 +1,31 @@
<?php
namespace App\Http\Requests\Inventory;
use Illuminate\Foundation\Http\FormRequest;
class UpdateSupplierCategoryRequest extends FormRequest
{
public function authorize(): bool
{
return true;
}
/**
* @return array<string, array<int, string>>
*/
public function rules(): array
{
return [
'name' => ['required', 'string', 'max:255'],
'pos' => ['nullable', 'integer', 'min:0', 'max:255'],
];
}
protected function prepareForValidation(): void
{
if ($this->has('pos') && $this->input('pos') === '') {
$this->merge(['pos' => 0]);
}
}
}

View file

@ -0,0 +1,39 @@
<?php
namespace App\Http\Requests\Inventory;
use Illuminate\Foundation\Http\FormRequest;
class UpdateSupplierRequest extends FormRequest
{
public function authorize(): bool
{
return true;
}
/**
* @return array<string, array<int, mixed>>
*/
public function rules(): array
{
return [
'name' => ['required', 'string', 'max:255'],
'url' => ['nullable', 'string', 'max:2048'],
'contact_person' => ['nullable', 'string', 'max:255'],
'email' => ['nullable', 'email', 'max:255'],
'phone' => ['nullable', 'string', 'max:100'],
'country_id' => ['required', 'integer', 'exists:countries,id'],
'notes' => ['nullable', 'string'],
'active' => ['sometimes', 'boolean'],
'supplier_category_ids' => ['nullable', 'array'],
'supplier_category_ids.*' => ['integer', 'exists:supplier_categories,id'],
];
}
protected function prepareForValidation(): void
{
$this->merge([
'active' => $this->boolean('active'),
]);
}
}