Viewing File: /home/ubuntu/vedadeals-backend-base/app/Http/Controllers/Admin/ProductController.php

<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;

use Illuminate\Http\Request;

use App\Helpers\Helper;

use DB, Exception, Setting, Hash, Storage;

use App\Models\{ Product, ProductFile, User, Category, SubCategory, Discount, ProductInventory };

use App\Models\{ OrderProduct, OrderPayment };

use App\Http\Requests\Admin\Product\{ ProductPostRequest, ProductGetRequest };

use App\Http\Requests\Admin\Category\{ CategoryGetRequest };

use App\Services\{ ProductService };

use Excel;

use App\Exports\{ ProductsExport };

use App\Imports\{ ProductsImport };

use App\Jobs\{ProductPriceUpdateNotificationJob, PriceConvertionJob};

class ProductController extends Controller
{
    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct(Request $request)
    {
        $this->middleware('auth:admin');

        $this->skip = $request->skip ?: 0;

        $this->take = $request->take ?: (Setting::get('admin_take_count') ?: TAKE_COUNT);
    }

    /**
     * @method products_index()
     *
     * @uses to list the products
     *
     * @created Karthick
     *
     * @updated
     *
     * @param
     *
     * @return to products index page
     */

    public function products_index(Request $request) {

        try {

            $category = $sub_category = $categories = $sub_categories = '';

            $base_query = Product::Query()
                        ->with(['category', 'subCategory', 'orderProducts'])
                        ->withCount(['orderProducts'])
                        ->withSum('orderProducts', 'quantity')
                        ->when($request->deleted, function($query) {
                           $query->withTrashed()->whereNotNull('deleted_at');
                        })
                        ->when($request->filled('status'), function ($query) use ($request) {
                            $query->where('status', $request->status);
                        })->when($request->filled('stock_status'), function ($query) use ($request) {
                            $query->where('stock_status', $request->stock_status);
                        })->when($request->filled('category_id'), function ($query) use ($request) {
                            $query->where('category_id', $request->category_id);
                        })->when($request->filled('sub_category_id'), function ($query) use ($request) {
                            $query->where('sub_category_id', $request->sub_category_id);
                        })->when($request->filled('search_key'), function($query) use ($request) {
                            $query->where('name', "LIKE", "%" . $request->search_key . "%");
                            $query->orWhere('unique_id', "LIKE", "%" . $request->search_key . "%");
                        });

            if($request->filled('category_id')) {

                $category = Helper::check_model_exists($request->category_id, CATEGORY);
            }

            if($request->filled('sub_category_id')) {

                $sub_category = Helper::check_model_exists($request->sub_category_id, SUB_CATEGORY);
            }

            $products = $base_query->orderBy('id', 'DESC')->paginate($this->take);

            return view('admin.products.index')
                        ->with('page', 'products')
                        ->with('sub_page', $request->deleted ? 'products-deleted' : 'products-view')
                        ->with(compact(['products', 'category', 'sub_category', 'categories', 'sub_categories']));

        } catch (Exception $e) {

            return redirect()->route('admin.products.index')->with('flash_error', $e->getMessage());
        }

    }

    /**
     * @method products_create()
     *
     * @uses To create a new product
     *
     * @created  Karthick
     *
     * @updated
     *
     * @param create a new object
     *
     * @return to create product page
     *
     */
    public function products_create() {

        $product = new Product;

        $categories = Category::has('subCategories')->orderBy('name')->get(['id', 'name']);

        $sub_categories = SubCategory::orderBy('name')->get(['id', 'name']);

        return view('admin.products.create')
                    ->with('page', 'products')
                    ->with('sub_page', 'products-create')
                    ->with(compact(['product', 'categories', 'sub_categories']));
    }

    /**
     * @method products_edit()
     *
     * @uses to edit product details based on the product_id
     *
     * @created Karthick
     *
     * @updated
     *
     * @param object $request - product_id
     *
     * @return to edit product page
     *
     */
    public function products_edit(ProductGetRequest $request) {

        try {

            Helper::check_model_exists($request->product_id, PRODUCT);

            $product = Product::with(['productFiles'])->find($request->product_id);

            $categories = Category::orderBy('name')->get(['id', 'name']);

            return view('admin.products.edit')
                    ->with('page' , 'products')
                    ->with('sub_page','products-create')
                    ->with(compact(['product', 'categories']));

        } catch(Exception $e) {

            return redirect()->route('admin.products.index')->with('flash_error', $e->getMessage());
        }

    }

    /**
     * @method products_save()
     *
     * @uses to save the product details of new/existing object based on product_id
     *
     * @created Karthick
     *
     * @updated
     *
     * @param object $request - product_id
     *
     * @return view product page
     *
     * @note - price column is - selling price of product
     *
     */
    public function products_save(ProductPostRequest $request) {

        try {

            DB::begintransaction();

            $product = Product::updateOrCreate(['id' => $request->product_id], $request->validated());

            if($product) {

                if($request->has('pictures')) {

                    $is_default_file = ProductFile::where(['product_id' => $product->id, 'is_default' => YES])->exists();

                    foreach($request->pictures as $key => $file) {

                        $file_url = Helper::storage_upload_file($file, PRODUCT_FILE_PATH);

                        $file_type = in_array($file->getClientOriginalExtension(), ['jpg', 'jpeg', 'png']) ? IMAGE : VIDEO;

                        $product_file = ProductFile::Create(['product_id' => $product->id, 'file' => $file_url, 'file_type' => $file_type]);

                        if(!$is_default_file && $key == 0) {

                            $product_file->update(['is_default' => YES]);

                            $product->update(['file' => $file_url]);
                        }
                    }
                }

                if($product->wasChanged('quantity')) {

                    $update_inventory = ProductService::update_product_inventory($product->id, $request->quantity, PRODUCT_NOT_SOLD)->getData();

                    if(!$update_inventory->result) {

                        throw new Exception($update_inventory->error);
                    }
                }

                $originalPrice = $product->getOriginal('price');

                if($request->discount) {

                    $discount = Discount::updateOrCreate(
                                    ['product_id' => $product->id, 'discount' => $request->discount, 'discount_type' => $request->discount_type],
                                    ['product_id' => $product->id, 'discount' => $request->discount, 'discount_type' => $request->discount_type, 'is_current' => YES]
                                );

                    if($discount) {

                        Discount::where('id', '!=', $discount->id)->where(['product_id' => $request->product_id, 'is_current' => YES])->update(['is_current' => NO]);
                    }

                    if($product->discount->discount_type == DISCOUNT_TYPE_FLAT_PRICE) {

                        $price = $product->original_price - $product->discount->discount;

                        $product->update(['discount_price' => $product->discount->discount, 'price' => $price]);

                    }  elseif($product->discount->discount_type == DISCOUNT_TYPE_PERCENTAGE) {

                        $discount_percentage_amount = $product->discount->discount * ($product->original_price / 100);

                        $price = $product->original_price - $discount_percentage_amount;

                        $product->update(['discount_price' => $discount_percentage_amount, 'price' => $price]);
                    }

                } else {

                    $product->update(['discount_price' => 0, 'price' => $request->original_price]);
                }

                if($product->wasChanged('price')) {

                    ProductPriceUpdateNotificationJob::dispatch($product, $originalPrice);
                }

                if(!$product->wasRecentlyCreated && $product->banner) {

                    $result = $product->banner->update([
                        'link' => Setting::get('frontend_url')."product/$product->unique_id",
                        'product_unique_id' => $product->unique_id
                    ]);
                }

                DB::commit();

                $message = $request->product_id ? tr('product_updated_success') : tr('product_created_success');

                return redirect(route('admin.products.view', ['product_id' => $product->id ]))->with('flash_success', $message);

            }

            throw new Exception(tr('product_save_failed'));

        } catch(Exception $e){

            DB::rollback();

            return back()->withInput()->with('flash_error', $e->getMessage());

        }

    }

    /**
     * @method products_view()
     *
     * @uses to view the product details based on product_id
     *
     * @created Karthick
     *
     * @updated
     *
     * @param object $request - product_id
     *
     * @return View page
     *
     */
    public function products_view(ProductGetRequest $request) {

        try {

            Helper::check_model_exists($request->product_id, PRODUCT);

            $product = Product::find($request->product_id);

            $product_files = ProductFile::where('product_id', $request->product_id)->get();

            return view('admin.products.view')
                        ->with('page', 'products')
                        ->with('sub_page', 'products-view')
                        ->with(compact(['product', 'product_files']));

        } catch (Exception $e) {

            return redirect()->route('admin.products.index')->with('flash_error', $e->getMessage());
        }

    }


    /**
     * @method products_status
     *
     * @uses to change product status as DECLINED/APPROVED based on product_id
     *
     * @created Karthick
     *
     * @updated
     *
     * @param object $request - product_id
     *
     * @return response success/failure message
     *
     **/
    public function products_status(ProductGetRequest $request) {

        try {

            Helper::check_model_exists($request->product_id, PRODUCT);

            DB::beginTransaction();

            $product = Product::find($request->product_id);

            $result = $product->update(['status' => $product->status ? DECLINED : APPROVED]);

            if($result) {

                DB::commit();

                $message = $product->status ? tr('product_publish_success') : tr('product_un_publish_success');

                return back()->with('flash_success', $message);
            }

            throw new Exception(tr('product_status_change_failed'));

        } catch(Exception $e) {

            DB::rollback();

            return redirect()->route('admin.products.index')->with('flash_error', $e->getMessage());

        }

    }

    /**
     * @method products_delete()
     *
     * @uses to delete the product details based on product_id
     *
     * @created Karthick
     *
     * @updated
     *
     * @param object $request - product_id
     *
     * @return response of success/failure details with view page
     *
     */
    public function products_delete(ProductGetRequest $request) {

        try {

            Helper::check_model_exists($request->product_id, PRODUCT);

            DB::begintransaction();

            $product = Product::find($request->product_id);

            if($product->delete()) {

                DB::commit();

                return redirect()->route('admin.products.index')->with('flash_success',tr('product_deleted_success'));

            }

            throw new Exception(tr('product_delete_failed'));

        } catch(Exception $e){

            DB::rollback();

            return back()->with('flash_error', $e->getMessage());

        }

    }

    /**
     * @method products_stock_status
     *
     * @uses to add / remove product as in stock / out of stock based on product_id
     *
     * @created Karthick
     *
     * @updated
     *
     * @param object $request - product_id
     *
     * @return response success/failure message
     *
     **/
    public function products_stock_status(ProductGetRequest $request) {

        try {

            Helper::check_model_exists($request->product_id, PRODUCT);

            DB::beginTransaction();

            $product = Product::find($request->product_id);

            $result = $product->update(['quantity' => $request->quantity ? : 0, 'stock_status' => $product->stock_status ? OUT_OF_STOCK : IN_STOCK]);

            if($result) {

                ProductService::update_product_inventory($product->id, $product->quantity, PRODUCT_NOT_SOLD)->getData();

                DB::commit();

                $message = $product->stock_status ? tr('product_in_stock_status_success') : tr('product_out_of_stock_status_success');

                return back()->with('flash_success', $message);
            }

            throw new Exception(tr('product_stock_status_change_failed'));

        } catch(Exception $e) {

            DB::rollback();

            return redirect()->route('admin.products.index')->with('flash_error', $e->getMessage());

        }

    }

    /**
     * @method product_file_delete()
     *
     * @uses to delete the a product file based on product_file_id
     *
     * @created Karthick
     *
     * @updated
     *
     * @param object $request - product_file_id
     *
     * @return response of success/failure details with view page
     *
     */
    public function product_file_delete(Request $request) {

        try {

            $rules = ['product_file_id' => ['required', 'exists:product_files,id']];

            Helper::custom_validator($request->all(), $rules, []);

            $product_file = ProductFile::find($request->product_file_id);

            $product_files_count = ProductFile::where(['product_id' => $product_file->product_id])->count();

            if($product_files_count == 1) {

                throw new Exception(tr('file_delete_error_only_one_file_exists'));
            }

            $result = false;

            DB::begintransaction();

            if($product_file->is_default == YES) {

                $new_default_file = ProductFile::firstWhere(['product_id' => $product_file->product_id, 'is_default' => NO]);

                if(!$new_default_file) {

                    throw new Exception(tr('file_delete_error_only_one_file_exists'));
                }

                $new_default_file->update(['is_default' => YES]);

                Product::where(['id' => $new_default_file->product_id])->update(['file' => $new_default_file->file]);

            }

            if($product_file->delete()) {

                DB::commit();

                return back()->with('flash_success', tr('file_deleted_success'));

            }

            throw new Exception(tr('file_delete_failed'));

        } catch(Exception $e){

            DB::rollback();

            return back()->with('flash_error', $e->getMessage());

        }
    }

    /**
     * @method get_sub_categories()
     *
     * @uses to get all the sub categories of an use based on category id
     *
     * @created Karthick
     *
     * @updated
     *
     * @param
     *
     * @return return data
     *
     */
    public function get_sub_categories(CategoryGetRequest $request) {

        $sub_categories = SubCategory::where(['category_id' => $request->category_id])->orderBy('updated_at', 'desc')->get(['id', 'name']);

        $view_page = view('admin.products.sub_categories_list')->with('sub_categories' , $sub_categories)->render();

        $response_array = ['success' =>  true , 'view' => $view_page];

        return response()->json($response_array);
    }

    /**
     * @method products_inventory()
     *
     * @uses to view the product inventory details based on product_id
     *
     * @created Karthick
     *
     * @updated
     *
     * @param object $request - product_id
     *
     * @return Inventory page
     *
     */
    public function products_inventory(ProductGetRequest $request) {

        try {

            Helper::check_model_exists($request->product_id, PRODUCT);

            $product = Product::find($request->product_id);

            $product_inventory = ProductInventory::firstWhere(['product_id' => $product->id]);

            $order_ids = OrderProduct::where('product_id', $product->id)->pluck('order_id');

            $data['total_orders'] = count($order_ids) ?? 0;

            $data['total_revenue'] = OrderPayment::whereIn('order_id', $order_ids)->sum('total');

            $data['order_data'] = Helper::order_payments_month_graph_for_single_product(6, $order_ids);

            return view('admin.products.inventory')
                        ->with('page', 'products')
                        ->with('sub_page', 'products-view')
                        ->with(compact(['product', 'product_inventory', 'data']));

        } catch (Exception $e) {

            return redirect()->route('admin.products.index')->with('flash_error', $e->getMessage());
        }

    }

    /**
     * @method products_restore()
     *
     * @uses to restore the product details based on product_id
     *
     * @created Karthick
     *
     * @updated
     *
     * @param object $request - product_id
     *
     * @return response of success/failure details with view page
     *
     */
    public function products_restore(ProductGetRequest $request) {

        try {

            DB::begintransaction();

            $product = Product::withTrashed()->find($request->product_id);

            if($product->restore()) {

                DB::commit();

                return redirect()->route('admin.products.index', ['deleted' => YES])->with('flash_success', tr('product_restore_success'));

            }

            throw new Exception(tr('product_restore_failed'));

        } catch(Exception $e){

            DB::rollback();

            return back()->with('flash_error', $e->getMessage());

        }

    }

    /**
     * @method products_restore_all()
     *
     * @uses to restore all the products
     *
     * @created Karthick
     *
     * @updated
     *
     * @param
     *
     * @return response of success/failure details with view page
     *
     */
    public function products_restore_all(Request $request) {

        try {

            if(!Product::onlyTrashed()->count()) {

                throw new Exception(tr('deleted_products_not_available'));
            }

            DB::begintransaction();

            $result = Product::onlyTrashed()->restore();

            if($result) {

                DB::commit();

                return redirect()->route('admin.products.index')->with('flash_success', tr('product_restore_all_success'));

            }

            throw new Exception(tr('product_restore_all_failed'));

        } catch(Exception $e){

            DB::rollback();

            return back()->with('flash_error', $e->getMessage());
        }
    }

    /**
     * @method products_export()
     *
     * @uses to export products in excel format
     *
     * @created Karthick
     *
     * @updated
     *
     * @param
     *
     * @return
     *
     */
    public function products_export(Request $request) {

        try {

            $file_format = $request->file_format ? : '.xlsx';

            $filename = routefreestring(Setting::get('site_name'))."-".now()."-".uniqid().$file_format;

            return Excel::download(new ProductsExport($request), $filename);

        } catch(\Exception $e) {

            return redirect()->route('admin.products.index')->with('flash_error' , $e->getMessage());

        }
    }

    /**
     * @method product_default_status()
     *
     * @uses to mark / remove product file from default based on product_file_id
     *
     * @created Karthick
     *
     * @updated
     *
     * @param object $request - product_file_id
     *
     * @return response of success/failure details with view page
     *
     */
    public function product_default_status(Request $request) {

        try {

            $rules = ['product_file_id' => ['required', 'exists:product_files,id']];

            Helper::custom_validator($request->all(), $rules, []);

            $product_file = ProductFile::find($request->product_file_id);

            $product_files_count = ProductFile::where(['product_id' => $product_file->product_id])->count();

            if($product_files_count == 1) {

                throw new Exception(tr('file_default_status_error_only_one_file_exists'));
            }

            $result = false;

            DB::begintransaction();

            if($product_file->is_default == NO) {

                $old_default_file = ProductFile::firstWhere(['product_id' => $product_file->product_id, 'is_default' => YES]);

                if($old_default_file->update(['is_default' => NO])) {

                    $result = $product_file->update(['is_default' => YES]);

                    Product::where(['id' => $product_file->product_id])->update(['file' => $product_file->file]);
                }

            } else {

                $new_default_file = ProductFile::firstWhere(['product_id' => $product_file->product_id, 'is_default' => NO]);

                if($new_default_file->update(['is_default' => YES])) {

                    $result = $product_file->update(['is_default' => NO]);

                    Product::where(['id' => $new_default_file->product_id])->update(['file' => $new_default_file->file]);
                }
            }

            if($result) {

                DB::commit();

                return back()->with('flash_success', $product_file->is_default ? tr('file_marked_as_default') : tr('file_removed_from_default'));

            }

            throw new Exception(tr('file_change_default_status_failed'));

        } catch(Exception $e){

            DB::rollback();

            return back()->with('flash_error', $e->getMessage());

        }
    }

    /**
     * @method products_import()
     *
     * @uses to import products from excel
     *
     * @created Karthick
     *
     * @updated
     *
     * @param
     *
     * @return
     *
     */
    public function products_import(Request $request) {

        try {

            return view('admin.products.import')
                    ->with('page', 'products')
                    ->with('sub_page', 'products-import');

        } catch(\Exception $e) {

            return redirect()->route('admin.products.index')->with('flash_error' , $e->getMessage());

        }
    }

    /**
     * @method products_import_save()
     *
     * @uses to import products from excel
     *
     * @created Karthick
     *
     * @updated
     *
     * @param
     *
     * @return
     *
     */
    public function products_import_save(Request $request) {

        try {

            $rules = ['excel' => ['required', 'mimes:xlsx']];

            Helper::custom_validator($request->all(), $rules, []);

            Excel::import(new ProductsImport, request('excel'));

            return redirect()->route('admin.products.index');

        } catch(\Exception $e) {

            return redirect()->back()->with('flash_error' , $e->getMessage());
        }
    }

    /**
     * @method products_publish_all
     *
     * @uses to publish all the products
     *
     * @created Karthick
     *
     * @updated
     *
     * @param
     *
     * @return response success/failure message
     *
     **/
    public function products_publish_all(Request $request) {

        try {

            DB::beginTransaction();

            $result = Product::where(['status' => DECLINED])->update(['status' => APPROVED]);

            if(!$result) {

                throw new Exception(tr('already_all_the_products_are_published'));
            }

            DB::commit();

            return back()->with('flash_success', tr('products_publish_success'));

        } catch(Exception $e) {

            DB::rollback();

            return redirect()->route('admin.products.index')->with('flash_error', $e->getMessage());

        }

    }

    /**
     * @method products_update_drug_content_key()
     *
     * @uses to update products drug content key
     *
     * @created Karthick
     *
     * @updated
     *
     * @param
     *
     * @return to products index page
     */

    public function products_update_drug_content_key(Request $request) {

        try {

            DB::beginTransaction();

            $products = Product::orderBy('created_at')->get();

            $products->each(function($product) {

                $thc_drug_content = $cbd_drug_content = NO;
                
                if($product->thc_from || $product->thc_to || $product->thc_per_from || $product->thc_per_to) {
                    $thc_drug_content = YES;
                }

                if($product->cbd_from || $product->cbd_to || $product->cbd_per_from || $product->cbd_per_to) {
                    $cbd_drug_content = YES;
                }

                $product->update([
                    'thc_drug_content' => $thc_drug_content,
                    'cbd_drug_content' => $cbd_drug_content
                ]);
            });

            DB::commit();

            return back()->with('flash_success', tr('products_thc_cbd_drug_content_updated_success'));

        } catch(Exception $e) {

            DB::rollback();

            return redirect()->route('admin.products.index')->with('flash_error', $e->getMessage());

        }

    }

    public function update_price(Request $request) {

        try {

            throw_if(!$request->to, new Exception("Please add to parameter (usd or pscn)."));

            PriceConvertionJob::dispatch($request->to);

            return back()->with('flash_success', "Price convertion to ($request->to) started successfully.");

        } catch(Exception $e) {

            return back()->with('flash_error', $e->getMessage());
        }
    }
}
Back to Directory File Manager