<?php

namespace App\Http\Controllers\V1\Inventory;

use App\Http\Controllers\Controller;
use App\Imports\DeleteProduct;
use App\Imports\ProductUpload;
use App\Imports\UpdateProduct;
use App\Models\Inventory;
use App\Models\InventoryLog;
use App\Models\InvtLocation;
use App\Models\ProductCategories;
use App\Models\ProductImages;
use App\Models\ProductLocationMapping;
use App\Models\Products;
use App\Models\ProductTags;
use App\Models\Store;
use App\Models\StoreLocation;
use App\Models\ProductUOM;
use App\Models\PaymentTerm;
use App\Models\VendorMappingProducts;
use App\Models\VendorPaymentTerms;
use App\Models\StockReconcillation;
use App\Models\User;
use App\Models\EWayBillUOM;
use App\Models\StockTransfer;
use App\Models\StockTransferProductDetails;
use App\Models\Client;
use App\Models\ClientAddress;
use App\Models\QuotationDetails;
use App\Models\Quotation;
use App\Models\QuotTaxInvoice;
use App\Models\QuotOc;
use App\Models\PoDetails;
use App\Models\PurchaseOrder;
use App\Models\ReleventProduct;
use Exception;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;
use Image;
use Picqer\Barcode\BarcodeGeneratorPNG;
use DB;
use Carbon\Carbon;
use PhpOffice\PhpSpreadsheet\IOFactory;
class InventoryMetadataController extends Controller
{

    public function uploadProductImages(Request $request){
        try {

            $validator = Validator::make($request->all(), [
                'file' => 'required|mimes:xlsx',

            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $file = $request->file('file');

            // Specify the storage path where the images will be stored
            $storagePath = 'public/images';

            // Load the Excel file
            $spreadsheet = IOFactory::load($file);

            // Get the active sheet
            $sheet = $spreadsheet->getActiveSheet();
            $notSavedProduct = [];

            // Iterate through the drawing collection in the worksheet
            foreach ($sheet->getDrawingCollection() as $key=>$drawing) {

//                dd($drawing instanceof \PhpOffice\PhpSpreadsheet\Worksheet\Drawing);
                // Check if the drawing is an image
                if ($drawing instanceof \PhpOffice\PhpSpreadsheet\Worksheet\Drawing) {
                    // Generate a unique filename for the image


                    $cellIndex = $drawing->getCoordinates();

                    $column = substr($cellIndex, 0, 1);
                    $row = substr($cellIndex, 1);
                    $previousColumn = chr(ord($column) - 1);


                    $previousCellIndex = $previousColumn . $row;

                    $productName = $sheet->getCell($previousCellIndex)->getValue();
                    // dd($productName);
                    $imageData = $drawing->getPath();
                    $zipReader = fopen($drawing->getPath(),'r');
                    $imageContents = '';
                    while (!feof($zipReader)) {
                        $imageContents .= fread($zipReader,1024);
                    }
                    fclose($zipReader);
                    $filename =$productName.rand(1,100).'.' . $drawing->getExtension();
                    $product = Products::where('product_code', $productName)->first();
                    // dd($imageContents);
                    if(!is_null($product)){
                        $product->image = $this->saveImage($drawing->getPath(),$productName );
                        $product->save();
                    }else{
                        //make an arrau nd list down cell number for which ismage is not uploaded you will find cell number in variable
                        //$cellIndex && $previousCellIndex
                        array_push($notSavedProduct,$previousCellIndex);
                    }


                    // Store the image using the Storage facade
                    // Storage::put($storagePath . '/' . $filename, file_put_contents($filename,$imageContents));
                }
            }
            // $excel = App::make('excel');
            // $data = $excel->import(new UpdateProduct(0),request()->file('file'));

            return $this->sendResponse(['notSavedRows'=>$notSavedProduct], 'Product file uploaded successfully', true);
        }catch (\Exception $e){
          // return $this->sendError('Validation Error',$e->getMessage(),413);
            return $this->sendError('Something went wrong', $e->getTrace(), 413);
        }
    }
    public function addProduct(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'product_code' => 'required|string',
                'catalogue_code' => 'nullable|string',
                'name' => 'required|string',
                'description' => 'nullable',
                'image' => '',
                'tax' => 'nullable|numeric|gt:0',
                'unit' => 'nullable',
                'price' => 'nullable',
                // 'material' => 'string',
                // 'avg_purchase_price' => 'required|numeric|gt:0',
                'avg_selling_price' => 'nullable|numeric|gt:0',
                'min_stock_level' => 'nullable|numeric|gt:0',
                'max_stock_level' => 'nullable|numeric|gt:0',
                'hsn_code' => 'nullable|string|unique:products',
                // 'product_category_id' => 'nullable|integer|exists:product_categories,id',
                'qty' => 'nullable|integer',
                'product_category' => ['required', Rule::in(['finished_goods','raw_materials','semi_finished_goods'])],
                'type' => ['required', Rule::in(['buy', 'both', 'sell'])],
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $newProducts = new Products();
            $newProducts->product_code = $request->product_code;
             $newProducts->hsn_code = $request->hsn_code;
            $newProducts->catalogue_code = $request->catalogue_code;
            $newProducts->name = $request->name;
            $newProducts->description = $request->description;
            $newProducts->tax = $request->tax;
            $newProducts->material = $request->material;
            if ($request->image != "") {
                if (!str_contains($request->image, "http")) {
                    $newProducts->image = $this->saveImage($request->image, $request->product_code);
                }
            }
            $newProducts->product_category = $request->product_category;
            $newProducts->avg_purchase_price = $request->avg_purchase_price;
            $newProducts->avg_selling_price = $request->avg_selling_price;
            $newProducts->min_stock_level = $request->min_stock_level;
            $newProducts->max_stock_level = $request->max_stock_level;
            $newProducts->serial_no = 100000 + Products::query()->count();
            $newProducts->product_type = $request->product_type;
            $newProducts->type = $request->type;
            $newProducts->price = $request->price;
            $newProducts->unit = $request->unit;
            $newProducts->discount = $request->discount;
            $newProducts->material_dimension = $request->material_dimension;
            $newProducts->current_stock = $request->current_stock ?? 0;
            $newProducts->pcs = $request->pcs;
            $newProducts->weight = $request->weight;
            $newProducts->coverage = $request->coverage;
            $newProducts->price_as_per_sq_ft = $request->price_as_per_sq_ft;
            $newProducts->size = $request->size;
            $generatorPNG = new BarcodeGeneratorPNG();

            $imagename = $request->product_code . '.png';

            $productObject = [
                'product_code' => '123123',
                'name' => 'rohit',
                'description' => 'It is good in working and easily available'
            ];
            file_put_contents('barcode/' . $imagename, $generatorPNG->getBarcode(json_encode($productObject), $generatorPNG::TYPE_CODE_128, 1));
            $newProducts->barcode_image = $imagename;
            $newProducts->save();
            $flag = 0;
            $getInventory = Inventory::query()
                ->where('product_id', $request->product_id)
                ->first();
            if (!is_null($getInventory)) {
                $flag = 1;
            }
            if ($flag == 1) {
                return $this->sendResponse([], 'Some product is already added in inventory having same name', false);
            }
            $newInventory = new Inventory();
            $newInventory->store_id = Auth::user()->store_id;
            $newInventory->product_id = $newProducts->id;
            $newInventory->qty = $newProducts->current_stock;
            $newInventory->save();
            $newInventoryLog = new InventoryLog();
            $newInventoryLog->user_id = Auth::user()->id;
            $newInventoryLog->type = 'credit';
            $newInventoryLog->inventory_id = $newInventory->id;
            $newInventoryLog->change_qty = $request->qty;
            $newInventoryLog->ref_no = 'REFNO';
            $newInventoryLog->save();
            return $this->sendResponse([], 'Product added successfully', true);
        } catch (Exception $e) {
            return $this->sendError('Something went wrong', $e->getMessage(), 413);
        }
    }
    public function saveImage($image, $productName)
    {
        $imageName = $productName . '-' . rand(100, 9999) . '.webp';

        $destinationPath = public_path('productimage\\' . $imageName);
        if (env('APP_ENV') == 'prod') {
            $destinationPath = public_path('productimage/' . $imageName);
        }
        $img = Image::make(file_get_contents($image))
            ->resize(300, null)
            ->save($destinationPath, 80, 'webp');

        return '/productimage/' . $imageName;
    }
    public function editProduct(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'id' => 'required|integer|exists:products,id',
                'product_code' => 'nullable|string',
                'catalogue_code' => 'nullable|string',
                'name' => 'nullable|string',
                'description' => 'nullable|string',
                'image' => 'nullable|nullable',
                //'vat' => 'numeric|gt:0',
                'material' => 'nullable|string',
                'avg_purchase_price' => 'nullable|numeric|gt:0',
                'avg_selling_price' => 'nullable|numeric|gt:0',
                'min_stock_level' => 'nullable|numeric|gt:0',
                'max_stock_level' => 'nullable|numeric|gt:0',
                'hsn_code' => 'nullable|string',
                'product_category_id' => 'nullable|integer|exists:product_categories,id',

            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $editProducts = Products::query()->where('id', $request->id)->first();
            if ($request->has('product_code')) {
                $editProducts->product_code = $request->product_code;
            }
            if ($request->has('catalogue_code')) {
                $editProducts->catalogue_code = $request->catalogue_code;
            }
            if ($request->has('name')) {
                $editProducts->name = $request->name;
            }
            if ($request->has('description')) {
                $editProducts->description = $request->description;
            }
            if ($request->has('price')) {
                $editProducts->price = $request->price;
            }
            if ($request->has('unit')) {
                $editProducts->unit = $request->unit;
            }
            if ($request->has('material_dimension')) {
                $editProducts->material_dimension = $request->material_dimension;
            }
            if ($request->has('current_stock')) {
                $editProducts->current_stock = $request->current_stock;
            }
            // if ($request->hasFile('image')) {
            //     $editProducts->image = $this->saveImage($request->file('image'));
            // }
            //$editProducts->image=$this->saveImage($request->image,$request->product_code);
            if ($request->image != "") {
                if (!str_contains($request->image, "http")) {
                    $editProducts->image = $this->saveImage($request->image, $request->product_code);
                }
            }
            // if ($request->has('vat')) {
            //     $editProducts->vat = $request->vat;
            // }
            if ($request->has('material')) {
                $editProducts->material = $request->material;
            }
            if ($request->has('avg_purchase_price')) {
                $editProducts->avg_purchase_price = $request->avg_purchase_price;
            }
            if ($request->has('avg_selling_price')) {
                $editProducts->avg_selling_price = $request->avg_selling_price;
            }
            if ($request->has('min_stock_level')) {
                $editProducts->min_stock_level = $request->min_stock_level;
            }
            if ($request->has('max_stock_level')) {
                $editProducts->max_stock_level = $request->max_stock_level;
            }
            if ($request->has('hsn_code')) {
                $editProducts->hsn_code = $request->hsn_code;
            }
            if ($request->has('product_category_id')) {
                $editProducts->product_category_id = $request->product_category_id;
            }
            if ($request->has('discount')) {
                $editProducts->discount = $request->discount;
            }
            if ($request->has('pcs')) {
                $editProducts->pcs = $request->pcs;
            }
            if ($request->has('weight')) {
                $editProducts->weight = $request->weight;
            }
            if ($request->has('coverage')) {
                $editProducts->coverage = $request->coverage;
            }
            if ($request->has('price_as_per_sq_ft')) {
                $editProducts->price_as_per_sq_ft = $request->price_as_per_sq_ft;
            }
            if ($request->has('size')) {
                $editProducts->size = $request->size;
            }
            $editProducts->save();
            return $this->sendResponse([], 'Product updated successfully');
        } catch (Exception $e) {
            return $this->sendError('Something Went Wrong', $e->getMessage(), 413);
        }
    }
    public function getAllProducts(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'limit' => 'numeric',
                'pageNo' => 'numeric',
                'stock_type' => [Rule::in(['minstock', 'maxstock'])],
                'start_date' =>'date',
                'end_date' =>'date'
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $query = Products::query();
            if ($request->has('start_date') && $request->has('end_date')) {
                $query = $query
                    ->whereBetween('created_at', [$request->start_date, $request->end_date])
                    ->orderBy('created_at', 'DESC');
            }
            if ($request->has('type')) {
                $query = $query->where('type', 'like', '%' . $request->type . '%');
            }
            if ($request->has('product_code')) {
                $query = $query->where('product_code', 'like', '%' . $request->product_code . '%');
            }
            if ($request->has('name')) {
                $query = $query->where('name', 'like', '%' . $request->name . '%');
            }
            if ($request->has('product_category_id')) {
                $query = $query->where('product_category_id', 'like', '%' . $request->product_category_id . '%');
            }
            if ($request->has('hsn_code')) {
                $query = $query->where('hsn_code', 'like', '%' . $request->hsn_code . '%');
            }
            if ($request->has('catalogue_code')) {
                $query = $query->where('catalogue_code', 'like', '%' . $request->catalogue_code. '%');
            }
            $count = $query->count();
            if ($request->has('pageNo') && $request->has('limit')) {
                $limit = $request->limit;
                $pageNo = $request->pageNo;
                $skip = $limit * $pageNo;
                $query = $query->skip($skip)->limit($limit);
            }
            $getProducts = $query->orderBy('id','DESC')->get();

            $list = [];
            if ($request->stock_type == 'minstock') {
                foreach ($getProducts as $user) {
                    if ($user['id'] != null) {
                        $productQty = Inventory::query()->where('product_id', $user['id'])->first();
                        if ($productQty != null) {
                            $user['product_details'] = $productQty;
                            if ($productQty['qty'] < $user['min_stock_level']) {
                                array_push($list, $user);

                            }
                        }
                    }
                }
            }
            if ($request->stock_type == 'maxstock') {
                foreach ($getProducts as $user) {
                    if ($user['id'] != null) {
                        $productQty = Inventory::query()->where('product_id', $user['id'])->first();
                        if ($productQty != null) {
                            $user['product_details'] = $productQty;
                            if ($productQty['qty'] > $user['max_stock_level']) {
                                array_push($list, $user);

                            }
                        }
                    }
                }
            } else {
                foreach ($getProducts as $user) {
                    if ($user['id'] != null) {
                        $productQty = Inventory::query()->where('product_id', $user['id'])->first();
                        $user['product_details'] = $productQty;
                    }
                }
            }
            // $count = $query->count();
            // $count = count($list);
            // dd($list);
            if (count($list) > 0) {
                return $this->sendResponse(["products" => $list, 'count' => count($list)], 'Data fetch successfully');
            } else {
                return $this->sendResponse(["products" => $getProducts, 'count' => $count], 'Data fetch successfully', true);
            }
        } catch (Exception $e) {
            return $this->sendError('Something Went Wrong', $e->getMessage(), 413);
        }
    }
    public function getAllMinstockMaxStockCount(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'limit' => 'numeric',
                'pageNo' => 'numeric',
            ]);

            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }

            $query = Products::query()->with(['product_category']);
            $count = $query->count();

            if ($request->has('pageNo') && $request->has('limit')) {
                $limit = $request->limit;
                $pageNo = $request->pageNo;
                $skip = $limit * $pageNo;
                $query = $query->skip($skip)->limit($limit);
            }

            $getProducts = $query->orderBy('name')->get();
            $minStockCount = 0;
            $maxStockCount = 0;

            foreach ($getProducts as $product) {
                if ($product['id'] != null) {
                    $productQty = Inventory::query()->where('product_id', $product['id'])->first();
                    if ($productQty != null) {
                        $product['product_details'] = $productQty;

                        if ($productQty['qty'] < $product['min_stock_level']) {
                            $minStockCount++;
                        } elseif ($productQty['qty'] > $product['max_stock_level']) {
                            $maxStockCount++;
                        }
                    }
                }
            }

            if ($minStockCount > 0 || $maxStockCount > 0) {
                return $this->sendResponse(["min_stock_count" => $minStockCount, "max_stock_count" => $maxStockCount], 'Data fetched successfully');
            } else {
                return $this->sendResponse(["products" => $getProducts, 'count' => $count], 'Data fetched successfully', true);
            }
        } catch (Exception $e) {
            return $this->sendError('Something Went Wrong', $e->getMessage(), 413);
        }
    }

    public function getAllMinStokeProducts(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'limit' => 'numeric',
                'pageNo' => 'numeric',
                'type' => [Rule::in(['minstock', 'maxstock'])],
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $query = Products::query();
            if ($request->has('pageNo') && $request->has('limit')) {
                $limit = $request->limit;
                $pageNo = $request->pageNo;
                $skip = $limit * $pageNo;
                $query = $query->skip($skip)->limit($limit);
            }
            $getProducts = $query
                ->orderBy('name')->get();
            // echo $getProducts;
            $list = [];
            foreach ($getProducts as $user) {
                if ($request->type == 'minstock') {
                    if ($user['id'] != null) {
                        $productQty = Inventory::query()->where('product_id', $user['id'])->first();
                        if ($productQty != null) {
                            $user['product_details'] = $productQty;
                            if ($productQty['qty'] < $user['min_stock_level']) {
                                array_push($list, $user);

                            }
                        }
                    }
                }
                if ($request->type == 'maxstock') {
                    if ($user['id'] != null) {
                        $productQty = Inventory::query()->where('product_id', $user['id'])->first();
                        if ($productQty != null) {
                            $user['product_details'] = $productQty;
                            if ($productQty['qty'] > $user['max_stock_level']) {
                                array_push($list, $user);

                            }
                        }
                    }
                } else {
                    foreach ($getProducts as $user) {
                        if ($user['id'] != null) {
                            $productQty = Inventory::query()->where('product_id', $user['id'])->first();
                            $user['product_details'] = $productQty;

                        }
                    }
                }
            }
            $count = $query->count();
            if (count($list) > 0) {
                return $this->sendResponse(["products" => $list, 'count' => count($list)], 'Data fetch successfully');
            } else {
                return $this->sendResponse(["products" => $getProducts, 'count' => $count], 'Data fetch successfully', true);
            }
        } catch (Exception $e) {
            return $this->sendError('Something Went Wrong', $e->getMessage(), 413);
        }
    }

    public function getStockValue(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'limit' => 'numeric',
                'pageNo' => 'numeric',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $query = Products::query();

            $count = $query->count();
            if ($request->has('pageNo') && $request->has('limit')) {
                $limit = $request->limit;
                $pageNo = $request->pageNo;
                $skip = $limit * $pageNo;
                $query = $query->skip($skip)->limit($limit);
            }
            $getProducts = $query->orderBy('id', 'DESC')->get();
            foreach ($getProducts as $user){
                if($user['id']!=null){
                    $product=Inventory::query()->where('product_id',$user['id'])
                    ->where('store_id',Auth::user()->id)
                    ->get();
                    $user['product_details']=$product;
                }
            }
            if (count($getProducts) > 0) {
                return $this->sendResponse(["Product_images" => $getProducts, 'count' => $count], 'Data fetch successfully');
            } else {
                return $this->sendResponse([], 'No Product locations are available', false);
            }
        } catch (Exception $e) {
            return $this->sendError('Something Went Wrong', $e->getMessage(), 413);
        }
    }
    public function getAllMaxStokeProducts(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'limit' => 'numeric',
                'pageNo' => 'numeric',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $query = Products::query();
            if ($request->has('pageNo') && $request->has('limit')) {
                $limit = $request->limit;
                $pageNo = $request->pageNo;
                $skip = $limit * $pageNo;
                $query = $query->skip($skip)->limit($limit);
            }
            $getProducts = $query
                ->orderBy('name')->get();
            $list = [];
            foreach ($getProducts as $user) {
                if ($user['id'] != null) {
                    $productQty = Inventory::query()->where('product_id', $user['id'])->first();
                    if ($productQty != null) {
                        $user['product_details'] = $productQty;
                        if ($productQty['qty'] > $user['max_stock_level']) {
                            array_push($list, $user);

                        }
                    }
                }
            }
            $count = $getProducts->count();
            if (count($list) > 0) {
                return $this->sendResponse(["products" => $list, 'count' => $count], 'Data fetch successfully');
            } else {
                return $this->sendResponse([], 'No products are available', false);
            }
        } catch (Exception $e) {
            return $this->sendError('Something Went Wrong', $e->getMessage(), 413);
        }
    }
    public function addProductImages(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'product_id' => 'required|exists:products,id',
                'image' => 'required'
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $newproductImage = new ProductImages();
            $newproductImage->product_id = $request->product_id;
            $newproductImage->image = $this->saveImage($request->image, $request->product_id);
            $newproductImage->save();
            return $this->sendResponse([], 'Product image added successfully', true);
        } catch (Exception $e) {
            return $this->sendError('Somthing went wrong', $e->getMessage(), 413);
        }
    }
    public function deleteProductImageById(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'id' => 'required|integer|exists:product_images,id',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $user = ProductImages::query()->where('id', $request->id)->first();

            $user->delete();
            return $this->sendResponse([], 'Product iamge deleted successfully', true);
        } catch (Exception $e) {
            return $this->sendError('Something went wrong', $e->getMessage(), 413);
        }
    }
    public function getProductImageById(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'product_id' => 'required|integer',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $getProductImages = ProductImages::query()->where('product_id', $request->product_id)->with(['product'])->get();

            return $this->sendResponse($getProductImages, 'Data fetch successfully', true);

        } catch (Exception $e) {
            return $this->sendError('Something Went Wrong', $e->getMessage(), 413);
        }
    }
    public function getAllProductImages(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'limit' => 'numeric',
                'pageNo' => 'numeric',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $query = ProductImages::query()->with(['product']);
            $count = $query->count();
            if ($request->has('pageNo') && $request->has('limit')) {
                $limit = $request->limit;
                $pageNo = $request->pageNo;
                $skip = $limit * $pageNo;
                $query = $query->skip($skip)->limit($limit);
            }
            $getProducts = $query->orderBy('id', 'DESC')->get();
            if (count($getProducts) > 0) {
                return $this->sendResponse(["Product_images" => $getProducts, 'count' => $count], 'Data fetch successfully');
            } else {
                return $this->sendResponse([], 'No Product locations are available', false);
            }
        } catch (Exception $e) {
            return $this->sendError('Something Went Wrong', $e->getMessage(), 413);
        }
    }
    public function getTableColumnName(Request $request): JsonResponse
    {
        try {
            $columns = Schema::getConnection()->getDoctrineSchemaManager()->listTableColumns('products');

            $listAllFields = [];
            foreach ($columns as $eachColumn) {
                array_push($listAllFields, ['name' => $eachColumn->getName(), 'type' => $eachColumn->getType()->getName(), 'isRequired' => $eachColumn->getNotnull()]);
            }
            return $this->sendResponse(["fields" => $listAllFields], 'Data fetch successfully', true);

        } catch (Exception $e) {
            return $this->sendError('Something Went Wrong', $e->getMessage(), 413);
        }
    }
    public function deleteProductById(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'id' => 'required|integer|exists:products,id',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $user = Products::query()->where('id', $request->id)->first();

            $user->delete();
            return $this->sendResponse([], 'Product deleted successfully', true);
        } catch (Exception $e) {
            return $this->sendError('Something went wrong', $e->getMessage(), 413);
        }
    }
    public function getProductById(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'id' => 'required|integer|exists:products,id',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $getProducts = Products::query()->where('id', $request->id)->first();
            if ($getProducts['id'] != null) {
                $productQty = Inventory::query()->where('product_id', $getProducts['id'])->first();
                $getProducts['product_details'] = $productQty;
            }
            return $this->sendResponse($getProducts, 'Data fetch successfully', true);
        } catch (Exception $e) {
            return $this->sendError('Something Went Wrong', $e->getMessage(), 413);
        }
    }

    public function bulkDeleteProduct(Request $request)
    {
        try {
            $validator = Validator::make($request->all(), [
                'file' => 'required',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $excel = App::make('excel');
            $data = $excel->import(new DeleteProduct(0), request()->file('file'));
            return $this->sendResponse([], 'Products deleted successfully', true);
        } catch (Exception $e) {
            return $this->sendError('Validation Error', $e->getMessage(), 413);
            // return $this->sendError('Something went wrong', $e->getMessage(), 413);
        }
    }
    public function bulkUpdateProduct(Request $request)
    {
        try {
            $validator = Validator::make($request->all(), [
                'file' => 'required',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $excel = App::make('excel');
            $data = $excel->import(new UpdateProduct(0), request()->file('file'));
            return $this->sendResponse([], 'Products deleted successfully', true);
        } catch (Exception $e) {
            return $this->sendError('Validation Error', $e->getMessage(), 413);
            // return $this->sendError('Something went wrong', $e->getMessage(), 413);
        }
    }
    public function addProductThroughJson(Request $request)
    {
        try {

            $validator = Validator::make($request->all(), [
                'products' => 'required|array',
                'products.*.product_code' => 'required|unique:products,product_code',
                'products.*.catalogue_code' => 'nullable',
                'products.*.name' => 'required|string|unique:products',
                // 'products.*.description' => 'string',
                // 'products.*.image' => 'string',
                'products.*.price' => 'nullable',
                // 'products.*.material' => 'string',
                // 'products.*.avg_purchase_price' => 'numeric|gt:0',
                // 'products.*.avg_selling_price' => 'numeric|gt:0',
                // 'products.*.min_stock_level' => 'numeric|gt:0',
                // 'products.*.max_stock_level' => 'numeric|gt:0',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            foreach ($request->products as $product) {
                $user = new Products();
                $user->product_code = $product['product_code'];
                $user->catalogue_code = $product['catalogue_code'];
                $user->name = $product['name'];
                $user->description = $product['description'];
                 $user->hsn_code = $product['hsn_code'];
                $user->price = $product['price'];
                $user->type = $product['type'];
                $user->product_type = $product['product_type'];
                $user->unit = $product['unit'];
                $user->tax = $product['tax'];
                $user->product_category = $product['product_category'];
                $user->material_dimension = $product['material_dimension'];
                $user->current_stock = $product['current_stock'];
                $user->material = $product['material'];
                $user->avg_purchase_price = $product['avg_purchase_price'];
                $user->avg_selling_price = $product['avg_selling_price'];
                $user->min_stock_level = $product['min_stock_level'];
                $user->max_stock_level = $product['max_stock_level'];
                $user->pcs = $product['pcs'];
                $user->weight = $product['weight'];
                $user->coverage = $product['coverage'];
                $user->price_as_per_sq_ft = $product['price_as_per_sq_ft'];
                $user->discount = $product['discount'];
                $user->size=$product['size'];
                $user->save();
                $addInventory=new Inventory();
                $addInventory->store_id=Auth::user()->store_id;
                $addInventory->product_id=$user->id;
                $addInventory->qty=$user->current_stock;
                $addInventory->save();
            }
            return $this->sendResponse([], "Product created successfully", 200);
        } catch (Exception $e) {
            return $this->sendError('Something Went Wrong', [$e->getMessage()], 413);
        }
    }

    public function addClientThroughJson(Request $request)
    {
        try {

            $validator = Validator::make($request->all(), [
                'clients' => 'nullable|array',
                'clients.*.address_line_1' => 'nullable|string',
                'clients.*.address_line_2' => 'nullable|string',
                'clients.*.pincode' => 'nullable|string',
                'clients.*.state' => 'nullable|string',
                'clients.*.city' => 'nullable|string',
                'clients.*.country' => 'nullable|string',
                'clients.*.company_name' => 'required|string',
                'clients.*.company_person_name' => 'required|string',
                'clients.*.company_person_mobile' => 'required|string|unique:clients,company_person_mobile',
                'clients.*.company_person_email' => 'required|string|email|unique:clients,company_person_email',
                'clients.*.company_email' => 'required|string|email|unique:clients,company_email',
               // 'clients.*.gst_no'=>'required',
                'clients.*.logo'=>'nullable|string',
               // 'clients.*.client_type_id'=> 'required|numeric',
                // 'tags' => 'array',
                // 'tags.*.product_tag_id' => 'nullable|numeric|exists:product_tags,id',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            foreach ($request->clients as $client) {
                $newAddress = new ClientAddress();
                $newAddress->address_line_1 = $client['address_line_1'] ;
                $newAddress->address_line_2 = $client['address_line_2'];
                $newAddress->pincode = $client['pincode'];
                $newAddress->state = $client['state'];
                $newAddress->city = $client['city'];
                $newAddress->country = $client['country'];
                $newAddress->save();
                $newClient = new Client();
                //$newClient->client_address_id =$newAddress->id;
                $newClient->company_name = $client['company_name'];
                $newClient->company_person_name = $client['company_person_name'];
                $newClient->company_person_mobile = $client['company_person_mobile'];
                $newClient->company_person_email = $client['company_person_email'];
                $newClient->company_email = $client['company_email'];
                $newClient->client_type = $client['client_type'];
                $newClient->save();
                $newAddress->client_id=$newClient->id;
                $newAddress->address_for='client';
                $newAddress->save();

            }
            return $this->sendResponse([], "client created successfully", 200);
        } catch (Exception $e) {
            return $this->sendError('Something Went Wrong', [$e->getMessage()], 413);
        }
    }
    public function deleteProductThroughJson(Request $request)
    {
        try {
            $validator = Validator::make($request->all(), [
                'products' => 'array',
                'products.*.product_code' => 'required|exists:products,product_code'
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            foreach ($request->products as $product) {
                $user = new Products;
                $user->product_code = $product['product_code'];
                // $user->catalogue_code = $product['catalogue_code'];
                // $user->name = $product['name'];
                // $user->description = $product['description'];
                // //  $user->image = $product['image'];
                // $user->vat = $product['vat'];
                // $user->material = $product['material'];
                // $user->avg_purchase_price = $product['avg_purchase_price'];
                // $user->avg_selling_price = $product['avg_selling_price'];
                // $user->min_stock_level = $product['min_stock_level'];
                // $user->max_stock_level = $product['max_stock_level'];
                $user = Products::query()->where('product_code', $user->product_code)->first();
                if ($user != null) {
                    $user->delete();
                }
            }
            return $this->sendResponse([], "Products deleted successfully", true);
        } catch (Exception $e) {
            return $this->sendError('Something Went Wrong', [$e->getTrace()], 413);
        }
    }
    public function upodateProductThroughJson(Request $request)
    {
        try {
            $validator = Validator::make($request->all(), [
                //'product_code'=>'required|exists:products,product_code'
                'products' => 'required|array',
                //   'products.*.product_code' => 'string|required|unique:products',
                'products.*.catalogue_code' => 'required|string',
                'products.*.name' => 'nullable|string',
                'products.*.description' => 'nullable',
                // 'products.*.image' => 'string',
                'products.*.tax' => 'numeric|gt:0',
                'products.*.avg_purchase_price' => 'nullable|numeric|gt:0',
                'products.*.avg_selling_price' => 'nullable|numeric|gt:0',
                'products.*.min_stock_level' => 'nullable|numeric|gt:0',
                'products.*.max_stock_level' => 'nullable|numeric|gt:0',
                'products.*.serial_no' => 'nullable|numeric|gt:0',
            ]);
            //dd($validator);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            foreach ($request->products as $product) {
                $updateProduct = Products::query()->where('product_code', $product['product_code'])->first();
                $updateProduct->product_code = $product['product_code'];
                $updateProduct->catalogue_code = $product['catalogue_code'];
                $updateProduct->name = $product['name'];
                $updateProduct->description = $product['description'];
                $updateProduct->price = $product['price'];
                $updateProduct->unit = $product['unit'];
                $updateProduct->tax = $product['tax'];
                $updateProduct->product_category = $product['product_category'];
                $updateProduct->material_dimension = $product['material_dimension'];
                $updateProduct->current_stock = $product['current_stock'];
                $updateProduct->material = $product['material'];
                $updateProduct->avg_purchase_price = $product['avg_purchase_price'];
                $updateProduct->avg_selling_price = $product['avg_selling_price'];
                $updateProduct->min_stock_level = $product['min_stock_level'];
                $updateProduct->max_stock_level = $product['max_stock_level'];
                $updateProduct->save();
            }
            return $this->sendResponse([], "Products update successfully", true);
        } catch (Exception $e) {
            return $this->sendError('Something Went Wrong', [$e->getMessage()], 413);
        }
    }
    public function productLocationMapping(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'product_id' => 'required|integer|exists:products,id',
                'invt_location_id' => 'required|integer|exists:invt_location,id',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $newProductLocationMapping = new ProductLocationMapping();
            $newProductLocationMapping->product_id = $request->product_id;
            $newProductLocationMapping->invt_location_id = $request->invt_location_id;
            $newProductLocationMapping->save();
            return $this->sendResponse([], 'Product location added successfully', true);
        } catch (Exception $e) {
            return $this->sendError('Something went wrong', $e->getTrace(), 413);
        }
    }
    public function editProductLocationMapping(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'id' => 'required|integer|exists:prod_location_map,id',
                'product_id' => 'integer',
                'invt_location_id' => 'integer',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $editProductLocationMapping = ProductLocationMapping::query()->where('id', $request->id)->first();
            if ($request->has('product_id')) {
                $editProductLocationMapping->product_id = $request->product_id;
            }
            if ($request->has('invt_location_id')) {
                $editProductLocationMapping->invt_location_id = $request->invt_location_id;
            }
            $editProductLocationMapping->save();
            return $this->sendResponse([], 'Product location updated successfully');
        } catch (Exception $e) {
            return $this->sendError('Something Went Wrong', $e->getMessage(), 413);
        }
    }
    public function getAllProductLocationMapping(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'limit' => 'numeric',
                'pageNo' => 'numeric',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $query = ProductLocationMapping::query()->with(['product', 'inventory_location']);
            $count = $query->count();
            if ($request->has('pageNo') && $request->has('limit')) {
                $limit = $request->limit;
                $pageNo = $request->pageNo;
                $skip = $limit * $pageNo;
                $query = $query->skip($skip)->limit($limit);
            }
            $getProducts = $query->orderBy('id', 'DESC')->get();
            if (count($getProducts) > 0) {
                return $this->sendResponse(["Product_location_mapping" => $getProducts, 'count' => $count], 'Data fetch successfully');
            } else {
                return $this->sendResponse([], 'No Product locations are available', false);
            }
        } catch (Exception $e) {
            return $this->sendError('Something Went Wrong', $e->getMessage(), 413);
        }
    }
    public function deleteProductLocationMappingById(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'id' => 'required|integer|exists:prod_location_map,id',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $deleteProductLocationMapping = ProductLocationMapping::query()->where('id', $request->id)->first();

            $deleteProductLocationMapping->delete();
            return $this->sendResponse([], 'Product location deleted successfully', true);
        } catch (Exception $e) {
            return $this->sendError('Something went wrong', $e->getMessage(), 413);
        }
    }
    public function getProductLocationMappingById(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'id' => 'required|integer|exists:prod_location_map,id',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $getProductLocationMapping = ProductLocationMapping::query()
                ->where('id', $request->id)
                ->with(['product', 'inventory_location'])->first();
            return $this->sendResponse($getProductLocationMapping, 'Data fetch successfully', true);
        } catch (Exception $e) {
            return $this->sendError('Something Went Wrong', $e->getMessage(), 413);
        }
    }
    public function getAllProductsByStore(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'limit' => 'numeric',
                'pageNo' => 'numeric',
                'store_id' => 'required|integer'
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $query = Inventory::query()
                ->where('store_id', $request->store_id)
                ->with(['product', 'store']);
            $count = $query->count();
            if ($request->has('pageNo') && $request->has('limit')) {
                $limit = $request->limit;
                $pageNo = $request->pageNo;
                $skip = $limit * $pageNo;
                $query = $query->skip($skip)->limit($limit);
            }
            $getProducts = $query->orderBy('id', 'DESC')->get();
            if (count($getProducts) > 0) {
                return $this->sendResponse(["products" => $getProducts, 'count' => $count], 'Data fetch successfully');
            } else {
                return $this->sendResponse([], 'No products are available', false);
            }
        } catch (Exception $e) {
            return $this->sendError('Something Went Wrong', $e->getMessage(), 413);
        }
    }
    public function addCategory(Request $request): JsonResponse
    {
        try {
            $velidator = validator::make($request->all(), [
                'name' => 'required|string|unique:product_categories'
            ]);
            $newCategory = new ProductCategories();
            $newCategory->name = $request->name;
            $newCategory->save();
            return $this->sendResponse([], 'category created successfully', true);
        } catch (Exception $e) {
            return $this->sendResponse('Something went wrong', $e->getMessage(), 413);
        }
    }
    public function editCategory(Request $request): JsonResponse
    {
        try {
            $velidator = validator::make($request->all(), [
                'id' => 'required|integer|exists:product_categories,id',
                'name' => 'required|string'
            ]);
            $editCategory = ProductCategories::query()->where('id', $request->id)->first();

            if ($request->has('name')) {
                $editCategory->name = $request->name;
            }
            $editCategory->save();
            return $this->sendResponse([], 'category updated successfully', true);
        } catch (Exception $e) {
            return $this->sendResponse('Something went wrong', $e->getMessage(), 413);
        }
    }
    public function getAllProductCategories(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'limit' => 'numeric',
                'pageNo' => 'numeric',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $query = ProductCategories::query();
            $count = $query->count();
            if ($request->has('pageNo') && $request->has('limit')) {
                $limit = $request->limit;
                $pageNo = $request->pageNo;
                $skip = $limit * $pageNo;
                $query = $query->skip($skip)->limit($limit);
            }
            $getProductCategories = $query->orderBy('id', 'DESC')->get();
            if (count($getProductCategories) > 0) {
                return $this->sendResponse(["product_categories" => $getProductCategories, 'count' => $count], 'Data fetch successfully');
            } else {
                return $this->sendResponse([], 'No product categories are available', false);
            }
        } catch (Exception $e) {
            return $this->sendError('Something Went Wrong', $e->getMessage(), 413);
        }
    }
    public function deleteProductCategoriesById(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'id' => 'required|integer|exists:product_categories,id',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $deleteProductCategories = ProductCategories::query()->where('id', $request->id)->first();
            $deleteProductCategories->delete();
            return $this->sendResponse([], 'Product category deleted successfully', true);
        } catch (Exception $e) {
            return $this->sendError('Something went wrong', $e->getMessage(), 413);
        }
    }
    public function getProductCategoriesById(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'id' => 'required|integer|exists:store_location,id',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $getProductCategories = ProductCategories::query()->where('id', $request->id)->first();
            return $this->sendResponse($getProductCategories, 'Data fetch successfully', true);
        } catch (Exception $e) {
            return $this->sendError('Something Went Wrong', $e->getMessage(), 413);
        }
    }
    public function addStoreLocation(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'location_name' => 'required|string|unique:store_location',
                'abbreviation' => 'required|string|unique:store_location',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $newStoreLocation = new StoreLocation();
            $newStoreLocation->location_name = $request->location_name;
            $newStoreLocation->abbreviation = $request->abbreviation;
            $newStoreLocation->save();
            return $this->sendResponse([], 'Store location added successfully', true);
        } catch (Exception $e) {
            return $this->sendError('Something went wrong', $e->getTrace(), 413);
        }
    }
    public function editStoreLocation(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'id' => 'required|integer|exists:store_location,id',
                'location_name' => 'string',
                'abbreviation' => 'string',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $editStoreLocation = StoreLocation::query()->where('id', $request->id)->first();
            if ($request->has('location_name')) {
                $editStoreLocation->location_name = $request->location_name;
            }
            if ($request->has('abbreviation')) {
                $editStoreLocation->abbreviation = $request->abbreviation;
            }
            $editStoreLocation->save();
            return $this->sendResponse([], 'Store location updated successfully');
        } catch (Exception $e) {
            return $this->sendError('Something Went Wrong', $e->getMessage(), 413);
        }
    }
    public function getAllStoreLocation(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'limit' => 'numeric',
                'pageNo' => 'numeric',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $query = StoreLocation::query();
            $count = $query->count();
            if ($request->has('pageNo') && $request->has('limit')) {
                $limit = $request->limit;
                $pageNo = $request->pageNo;
                $skip = $limit * $pageNo;
                $query = $query->skip($skip)->limit($limit);
            }
            $getStoreLocation = $query->orderBy('id', 'DESC')->get();
            if (count($getStoreLocation) > 0) {
                return $this->sendResponse(["store_locations" => $getStoreLocation, 'count' => $count], 'Data fetch successfully');
            } else {
                return $this->sendResponse([], 'No store locations are available', false);
            }
        } catch (Exception $e) {
            return $this->sendError('Something Went Wrong', $e->getMessage(), 413);
        }
    }
    public function deleteStoreLocationById(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'id' => 'required|integer|exists:store_location,id',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $deleteStoreLocation = StoreLocation::query()->where('id', $request->id)->first();
            $deleteStoreLocation->delete();
            return $this->sendResponse([], 'Store location deleted successfully', true);
        } catch (Exception $e) {
            return $this->sendError('Something went wrong', $e->getMessage(), 413);
        }
    }
    public function getStoreLocationById(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'id' => 'required|integer|exists:store_location,id',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $getStoreLocation = StoreLocation::query()->where('id', $request->id)->first();
            return $this->sendResponse($getStoreLocation, 'Data fetch successfully', true);

        } catch (Exception $e) {
            return $this->sendError('Something Went Wrong', $e->getMessage(), 413);
        }
    }
    public function addStore(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'name' => 'required|string',
              //  'location' => 'required|string',
                'store_location_id' => 'required|numeric|exists:store_location,id',
               // 'address_id' => 'required|numeric|exists:client_address,id',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $newAddress = new ClientAddress();
            $newAddress->address_line_1 = $request->address_line_1;
            $newAddress->address_line_2 = $request->address_line_2;
            $newAddress->pincode = $request->pincode;
            $newAddress->state = $request->state;
            $newAddress->city = $request->city;
            $newAddress->country = $request->country;
            $newAddress->address_for='store';
            $newAddress->save();
            $newStore = new Store();
            $newStore->name = $request->name;
            $newStore->location = $request->location;
            $newStore->store_location_id = $request->store_location_id;
            $newStore->address_id = $newAddress->id;
            $newStore->save();
            return $this->sendResponse([], 'Store added successfully', true);
        } catch (Exception $e) {
            return $this->sendError('Something went wrong', $e->getMessage(), 413);
        }
    }
    public function editStore(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'id' => 'required|integer|exists:stores,id',
                'name' => 'string',
                'location' => 'string',
                'store_location_id' => 'numeric|exists:store_location,id',
                'address_id' => 'numeric',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $editStore = Store::query()->where('id', $request->id)->first();
            if ($request->has('name')) {
                $editStore->name = $request->name;
            }
            if ($request->has('location')) {
                $editStore->location = $request->location;
            }
            if ($request->has('store_location_id')) {
                $editStore->store_location_id = $request->store_location_id;
            }
            if ($request->has('address_id')) {
                $editStore->address_id = $request->address_id;
            }
            $editStore->save();
            return $this->sendResponse([], 'Store updated successfully');
        } catch (Exception $e) {
            return $this->sendError('Something Went Wrong', $e->getMessage(), 413);
        }
    }
    public function getAllStore(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'limit' => 'numeric',
                'pageNo' => 'numeric',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $query = Store::query()->with(['store_location','address']);
            $count = $query->count();
            if ($request->has('pageNo') && $request->has('limit')) {
                $limit = $request->limit;
                $pageNo = $request->pageNo;
                $skip = $limit * $pageNo;
                $query = $query->skip($skip)->limit($limit);
            }
            $getStore = $query->orderBy('id', 'DESC')->get();
            if (count($getStore) > 0) {
                return $this->sendResponse(["store" => $getStore, 'count' => $count], 'Data fetch successfully');
            } else {
                return $this->sendResponse([], 'No store are available', false);
            }
        } catch (Exception $e) {
            return $this->sendError('Something Went Wrong', $e->getMessage(), 413);
        }
    }
    public function deleteStoreById(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'id' => 'required|integer|exists:stores,id',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $deleteStore = Store::query()->where('id', $request->id)->first();
            $deleteStore->delete();
            return $this->sendResponse([], 'Store deleted successfully', true);
        } catch (Exception $e) {
            return $this->sendError('Something went wrong', $e->getMessage(), 413);
        }
    }
    public function getStoreById(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'id' => 'required|integer|exists:stores,id',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $getStore = Store::query()->where('id', $request->id)->first();
            return $this->sendResponse($getStore, 'Data fetch successfully', true);
        } catch (Exception $e) {
            return $this->sendError('Something Went Wrong', $e->getMessage(), 413);
        }
    }
    public function addInventory(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                // 'store_id' => 'required|integer|exists:stores,id',
                'product_id' => 'required|integer|exists:products,id',
                'qty' => 'required|integer|gt:0',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $user=Auth::user()->store_id;
            $flag = 0;
            $getInventory = Inventory::query()
                ->where('store_id',$user)
                ->where('product_id', $request->product_id)
                ->first();
            if (!is_null($getInventory)) {
                $flag = 1;
            }
            if ($flag == 1) {
                return $this->sendResponse([], 'Some product is already added in inventory having same name', false);
            }
            $newInventory = new Inventory();
            $newInventory->store_id = $user;
            $newInventory->product_id = $request->product_id;
            $newInventory->qty = $request->qty;
            $newInventory->save();
            $newInventoryLog = new InventoryLog();
            $newInventoryLog->user_id = Auth::user()->id;
            $newInventoryLog->type = 'credit';
            $newInventoryLog->inventory_id = $newInventory->id;
            $newInventoryLog->save();
            return $this->sendResponse([], 'Inventory added successfully', true);
        } catch (Exception $e) {
            return $this->sendError('Something went wrong', $e->getMessage(), 413);
        }
    }
    public function editInventory(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                // 'id' => 'required|integer|exists:inventory,id',
                'product_id' => 'integer|exists:products,id',
                'qty' => 'integer|gt:0',
                'type' => ['required', Rule::in(['credit', 'debit'])],
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $editInventory = Inventory::query()->where('product_id', $request->product_id)->first();
            $editInventoryLog = new InventoryLog();
            $editProduct=Products::query()->where('id',$request->product_id)->first();
            $editInventoryLog->previous_qty = $editInventory->qty;
            if ($request->has('product_id')) {
                $editInventory->product_id = $request->product_id;
            }
            if ($request->has('qty')) {
                if ($request->type == 'credit') {
                    $getAvailableQty = ($editInventory->qty + $request->qty);
                    $addproductqtyincurrentstock=($editProduct->current_stock + $request->qty);
                } else
                    if ($request->type == 'debit') {
                        $getAvailableQty = ($editInventory->qty - $request->qty);
                        $addproductqtyincurrentstock=($editProduct->current_stock - $request->qty);
                    }
                $editInventory->qty = $getAvailableQty;
                $editProduct->current_stock=$addproductqtyincurrentstock;

            }
            $editProduct->save();
            $editInventory->save();
            $editInventoryLog->user_id = Auth::user()->id;
            $editInventoryLog->type = $request->type;
            $editInventoryLog->inventory_id = $editInventory->id;
            $editInventoryLog->change_qty = $request->qty;
            $editInventoryLog->ref_no = 'REFNO';
            $editInventoryLog->save();

            return $this->sendResponse([], 'Inventory updated successfully');
        } catch (Exception $e) {
            return $this->sendError('Something Went Wrong', $e->getMessage(), 413);
        }
    }
    public function getAllInventory(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'limit' => 'numeric',
                'pageNo' => 'numeric',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $query = Inventory::query()->with(['store', 'product']);
            $count = $query->count();
            if ($request->has('pageNo') && $request->has('limit')) {
                $limit = $request->limit;
                $pageNo = $request->pageNo;
                $skip = $limit * $pageNo;
                $query = $query->skip($skip)->limit($limit);
            }
            $getInventory = $query->orderBy('id', 'DESC')->get();
            if (count($getInventory) > 0) {
                return $this->sendResponse(["inventory" => $getInventory, 'count' => $count], 'Data fetch successfully');
            } else {
                return $this->sendResponse([], 'No inventory are available', false);
            }
        } catch (Exception $e) {
            return $this->sendError('Something Went Wrong', $e->getMessage(), 413);
        }
    }
    public function deleteInventoryById(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'id' => 'required|integer|exists:inventory,id',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $deleteInventory = Inventory::query()->where('id', $request->id)->first();
            $deleteInventory->delete();
            return $this->sendResponse([], 'Inventory deleted successfully', true);
        } catch (Exception $e) {
            return $this->sendError('Something went wrong', $e->getMessage(), 413);
        }
    }
    public function getInventoryById(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'id' => 'required|integer|exists:inventory,id',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $getInventory = Inventory::query()->where('id', $request->id)->with(['store', 'product'])->first();
            return $this->sendResponse($getInventory, 'Data fetch successfully', true);
        } catch (Exception $e) {
            return $this->sendError('Something Went Wrong', $e->getMessage(), 413);
        }
    }
    public function addInvtLocation(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'name' => 'required|string|unique:invt_location',
                'store_id' => 'required|integer|exists:stores,id',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $newInvtLocation = new InvtLocation();
            $newInvtLocation->name = $request->name;
            $newInvtLocation->store_id = $request->store_id;
            $newInvtLocation->save();
            return $this->sendResponse([], 'Location added successfully', true);
        } catch (Exception $e) {
            return $this->sendError('Something went wrong', $e->getTrace(), 413);
        }
    }
    public function editInvtLocation(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'id' => 'required|integer|exists:invt_location,id',
                'name' => 'string|unique:invt_location',
                'store_id' => 'integer|exists:stores,id'
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $editInvtLocation = InvtLocation::query()->where('id', $request->id)->first();
            if ($request->has('name')) {
                $editInvtLocation->name = $request->name;
            }
            if ($request->has('store_id')) {
                $editInvtLocation->store_id = $request->store_id;
            }
            $editInvtLocation->save();
            return $this->sendResponse([], 'Inventory location updated successfully');
        } catch (Exception $e) {
            return $this->sendError('Something Went Wrong', $e->getMessage(), 413);
        }
    }
    public function getAllInvtLocation(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'limit' => 'numeric',
                'pageNo' => 'numeric',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $query = InvtLocation::query();
            $count = $query->count();
            if ($request->has('pageNo') && $request->has('limit')) {
                $limit = $request->limit;
                $pageNo = $request->pageNo;
                $skip = $limit * $pageNo;
                $query = $query->skip($skip)->limit($limit);
            }
            $getProducts = $query->orderBy('id', 'DESC')->get();
            if (count($getProducts) > 0) {
                return $this->sendResponse(["inventory_locations" => $getProducts, 'count' => $count], 'Data fetch successfully');
            } else {
                return $this->sendResponse([], 'No inventory locations are available', false);
            }
        } catch (Exception $e) {
            return $this->sendError('Something Went Wrong', $e->getMessage(), 413);
        }
    }
    public function deleteInvtLocationById(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'id' => 'required|integer|exists:invt_location,id',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $deleteInvtLocation = InvtLocation::query()->where('id', $request->id)->first();
            $deleteInvtLocation->delete();
            return $this->sendResponse([], 'Inventory location deleted successfully', true);
        } catch (Exception $e) {
            return $this->sendError('Something went wrong', $e->getMessage(), 413);
        }
    }
    public function getInvtLocationById(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'id' => 'required|integer|exists:invt_location,id',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $getInvtLocation = InvtLocation::query()->where('id', $request->id)->first();
            return $this->sendResponse($getInvtLocation, 'Data fetch successfully', true);
        } catch (Exception $e) {
            return $this->sendError('Something Went Wrong', $e->getMessage(), 413);
        }
    }
    public function getAllInventoryLog(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'limit' => 'numeric',
                'pageNo' => 'numeric',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $query = InventoryLog::query()->with(['inventory', 'inventory.product', 'user']);
            if ($request->has('product_code')) {
                $getproduct = DB::table('products')->where('product_code', 'like', '%' . $request->product_code . '%')->first();
                if (is_null($getproduct)) {
                    return $this->sendResponse([], 'No inventory logs available', false);
                }
                $getInventory = Inventory::query()->where('product_id', $getproduct->id)->first();
                $query = $query->where('inventory_id', $getInventory->id);
            }
            $count = $query->count();
            if ($request->has('pageNo') && $request->has('limit')) {
                $limit = $request->limit;
                $pageNo = $request->pageNo;
                $skip = $limit * $pageNo;
                $query = $query->skip($skip)->limit($limit);
            }
            $getInventory = $query->orderBy('id', 'DESC')->get();
            if (count($getInventory) > 0) {
                return $this->sendResponse(["inventory" => $getInventory, 'count' => $count], 'Data fetch successfully');
            } else {
                return $this->sendResponse([], 'No inventory are available', false);
            }
        } catch (Exception $e) {
            return $this->sendError('Something Went Wrong', $e->getMessage(), 413);
        }
    }
    public function addProductTag(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'name' => 'required|string|unique:product_tags',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $newProductTag = new ProductTags();
            $newProductTag->name = $request->name;
            $newProductTag->is_active = 1;
            $newProductTag->save();
            return $this->sendResponse([], 'Product tag added successfully', true);
        } catch (Exception $e) {
            return $this->sendError('Something went wrong', $e->getMessage(), 413);
        }
    }
    public function editProductTag(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'id' => 'required|integer|exists:product_tags,id',
                'name' => 'string|unique:product_tags',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $editProductTag = ProductTags::query()->where('id', $request->id)->first();
            if ($request->has('name')) {
                $editProductTag->name = $request->name;
            }
            if ($request->has('is_active')) {
                $editProductTag->is_active = $request->is_active;
            }
            $editProductTag->save();
            return $this->sendResponse([], 'Product tag updated successfully');
        } catch (Exception $e) {
            return $this->sendError('Something Went Wrong', $e->getMessage(), 413);
        }
    }
    public function getAllProductTag(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'limit' => 'numeric',
                'pageNo' => 'numeric',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $query = ProductTags::query();
            $count = $query->count();
            if ($request->has('pageNo') && $request->has('limit')) {
                $limit = $request->limit;
                $pageNo = $request->pageNo;
                $skip = $limit * $pageNo;
                $query = $query->skip($skip)->limit($limit);
            }
            $getProductTag = $query->orderBy('id', 'DESC')->get();
            if (count($getProductTag) > 0) {
                return $this->sendResponse(["product_tags" => $getProductTag, 'count' => $count], 'Data fetch successfully');
            } else {
                return $this->sendResponse([], 'No Product tag are available', false);
            }
        } catch (Exception $e) {
            return $this->sendError('Something Went Wrong', $e->getMessage(), 413);
        }
    }
    public function deleteProductTagById(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'id' => 'required|integer|exists:product_tags,id',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $deleteProductTag = ProductTags::query()->where('id', $request->id)->first();
            $deleteProductTag->delete();
            return $this->sendResponse([], 'Product tag deleted successfully', true);
        } catch (Exception $e) {
            return $this->sendError('Something went wrong', $e->getMessage(), 413);
        }
    }
    public function getProductTagById(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'id' => 'required|integer|exists:product_tags,id',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $getProductTag = ProductTags::query()->where('id', $request->id)->first();
            return $this->sendResponse($getProductTag, 'Data fetch successfully', true);
        } catch (Exception $e) {
            return $this->sendError('Something Went Wrong', $e->getMessage(), 413);
        }
    }
    public function getTaxAsPerAddress(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                //'id' => 'required|integer|exists:product_tags,id',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $user = Auth::user()->id;
            $getTax = User::query()->with(['store', 'Store.address', 'organization', 'Organization.billing_address'])->where('id', $user)->first();
            if ($getTax != null) {
                if ($getTax['organization']['billing_address']['country'] == 'India') {
                    if ($getTax['store']['address']['state'] == $getTax['organization']['billing_address']['state']) {
                        $tax = "igst-cgst";
                    } else {
                        $tax = 'igst';
                    }
                } else {
                    $tax = 'vat 5%';
                }
            }
            return $this->sendResponse($tax, 'Tax as per Address', true);
        } catch (Exception $e) {
            return $this->sendError('Something went wrong', $e->getMessage(), 413);
        }
    }
    public function createEWayBillUOM(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'name' => 'required|string',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $newEWayBillUOM = new EWayBillUOM;
            $newEWayBillUOM->name = $request->name;
            $newEWayBillUOM->save();
            return $this->sendResponse([], 'UOM name created successfully', true);
        } catch (Exception $e) {
            return $this->sendError('Something went wrong', $e->getMessage(), 413);
        }
    }
    public function editEWayBillUOM(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'id' => 'required|integer|exists:e_way_bill_uom,id',
                'name' => 'required|string',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $editEWayBillUOM = EWayBillUOM::query()->where('id', $request->id)->first();
            if ($request->has('name')) {
                $editEWayBillUOM->name = $request->name;
            }
            $editEWayBillUOM->save();
            return $this->sendResponse([], 'UOM name updated successfully', true);
        } catch (Exception $e) {
            return $this->sendError('Something went wrong', $e->getMessage(), 413);
        }
    }
    public function getAllEWayBillUOM(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'limit' => 'numeric',
                'pageNo' => 'numeric',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $query = EWayBillUOM::query();
            $count = $query->count();
            if ($request->has('pageNo') && $request->has('limit')) {
                $limit = $request->limit;
                $pageNo = $request->pageNo;
                $skip = $limit * $pageNo;
                $query = $query->skip($skip)->limit($limit);
            }
            $getProducts = $query->get();
            if (count($getProducts) > 0) {
                return $this->sendResponse(["uom_name" => $getProducts, 'count' => $count], 'Data fetch successfully');
            } else {
                return $this->sendResponse([], 'No uom name are available', false);
            }
        } catch (Exception $e) {
            return $this->sendError('Something Went Wrong', $e->getMessage(), 413);
        }
    }
    public function getEWayBillUOMById(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'id' => 'required|integer|exists:e_way_bill_uom,id',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $getEWayBillUOM = EWayBillUOM::query()->where('id', $request->id)->first();

            return $this->sendResponse(["uom_name" =>$getEWayBillUOM], 'Data fetch successfully', true);

        } catch (Exception $e) {
            return $this->sendError('Something Went Wrong', $e->getMessage(), 413);
        }
    }
    public function deleteEWayBillUOMById(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'id' => 'required|integer|exists:e_way_bill_uom,id',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $user = EWayBillUOM::query()->where('id', $request->id)->first();
            $user->delete();
            return $this->sendResponse([], 'UOM Name deleted successfully', true);
        } catch (Exception $e) {
            return $this->sendError('Something went wrong', $e->getMessage(), 413);
        }
    }
  public function createUnitOfMeasurment(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'unit_name' => 'required|string',
                'descp' => 'nullable|string',
                'e_way_bill_uom_id'=>'required|integer|exists:e_way_bill_uom,id'
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $createUom=new ProductUOM;
            $createUom->unit_name = $request->unit_name;
            $createUom->descp = $request->descp;
            $createUom->e_way_bill_uom_id = $request->e_way_bill_uom_id;
            $createUom->save();
            return $this->sendResponse([], 'Unit of measurment created successfully', true);
        } catch (Exception $e) {
            return $this->sendError('Something went wrong', $e->getMessage(), 413);
        }
    }
    public function editUnitOfMeasurement(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'id' => 'required|integer|exists:product_uom,id',
                'unit_name' => 'string',
                'descp' => 'string',
                'e_way_bill_uom_id'=>'integer|exists:e_way_bill_uom,id'
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $editUOM = ProductUOM::query()->where('id', $request->id)->first();
            if ($request->has('unit_name')) {
                $editUOM->unit_name = $request->unit_name;
            }
            if ($request->has('descp')) {
                $editUOM->descp = $request->descp;
            }
            if ($request->has('e_way_bill_uom_id')) {
                $editUOM->e_way_bill_uom_id = $request->e_way_bill_uom_id;
            }
            $editUOM->save();
            return $this->sendResponse([],'Unit of measurment updated successfully');
        } catch (Exception $e) {
            return $this->sendError('Something Went Wrong', $e->getMessage(), 413);
        }
    }
    public function getAllProductUOM(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'limit' => 'numeric',
                'pageNo' => 'numeric',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $query = ProductUOM::query()->with(['uom']);
            $count = $query->count();
            if ($request->has('pageNo') && $request->has('limit')) {
                $limit = $request->limit;
                $pageNo = $request->pageNo;
                $skip = $limit * $pageNo;
                $query = $query->skip($skip)->limit($limit);
            }
            $getProductUOM = $query->orderBy('id', 'DESC')->get();
            if (count($getProductUOM) > 0) {
                return $this->sendResponse(["product_uom" => $getProductUOM, 'count' => $count], 'Data fetch successfully');
            } else {
                return $this->sendResponse([], 'No Product tag are available', false);
            }
        } catch (Exception $e) {
            return $this->sendError('Something Went Wrong', $e->getMessage(), 413);
        }
    }
    public function deleteProductUOMById(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'id' => 'required|integer|exists:product_uom,id',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $deleteProductUOM = ProductUOM::query()->where('id', $request->id)->with(['uom'])->first();
            $deleteProductUOM->delete();
            return $this->sendResponse([], 'Unit of measurment deleted successfully', true);
        } catch (Exception $e) {
            return $this->sendError('Something went wrong', $e->getMessage(), 413);
        }
    }
    public function getProductUOMById(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'id' => 'required|integer|exists:product_uom,id',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $getProductUOM = ProductUOM::query()->where('id', $request->id)->first();
            return $this->sendResponse($getProductUOM, 'Data fetch successfully', true);
        } catch (Exception $e) {
            return $this->sendError('Something Went Wrong', $e->getMessage(), 413);
        }
    }

    public function addstockReconcilliation(Request $request)
    {
        try {
            $validator = Validator::make($request->all(), [
                'stock' => 'array',
                'stock.*.store_id' => 'numeric|required',
                'stock.*.product_code' => 'required',
                'stock.*.physical_stock_qty' => 'nullable',
                'stock.*.difference' => 'nullable',
                'stock.*.transfer_price' => 'nullable|numeric|gt:0',
                'stock.*.comment' => 'nullable|string',
                'stock.*.as_on_date' => 'date',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }

            foreach ($request->stock as $stocks) {
                // get the product
                $products = Products::where('product_code', $stocks['product_code'])->first();
                if (!$products) {
                    return $this->sendError('Invalid Product Code', "Product code '{$stocks['product_code']}' does not exist.", 400);
                }

                $inventory = Inventory::where('product_id', $products->id)->first();
                if (!$inventory) {
                    // create new inventory if it does not exist
                    $inventory = new Inventory();
                    $inventory->store_id = Auth::user()->store_id;
                    $inventory->product_id = $products->id;
                }

                // update inventory qty
                if (!array_key_exists('physical_stock_qty', $stocks)) {
                    $physical_stock_qty = null;
                } else {
                    $physical_stock_qty = $stocks['physical_stock_qty'];
                }
                if ($physical_stock_qty !== null) {
                    $inventory->qty = $physical_stock_qty;
                } elseif (array_key_exists('difference', $stocks)) {
                    $inventory->qty += $stocks['difference'];
                }
                $inventory->save();

                // create stock reconcillation
                $stockReconcillation = new StockReconcillation();
                $stockReconcillation->store_id = $stocks['store_id'];
                $stockReconcillation->product_id = $products->id;
                $stockReconcillation->physical_stock_qty = $physical_stock_qty;
                $difference = $stocks['difference'] ?? null;
                $stockReconcillation->difference = $difference;
                $stockReconcillation->transfer_price = $stocks['transfer_price'] ?? null;
                $stockReconcillation->comment = $stocks['comment'] ?? null;
                $stockReconcillation->as_on_date = $stocks['as_on_date'] ?? null;
                $stockReconcillation->save();
            }
            return $this->sendResponse([], "Stock reconcillation created successfully", 200);
        } catch (Exception $e) {
            return $this->sendError('Something Went Wrong', [$e->getTrace()], 413);
        }
    }

    public function addinventorylogJson(Request $request)
    {
        try {
            $validator = Validator::make($request->all(), [
                'type' => ['required', Rule::in(['credit', 'debit'])],
                'log' => 'required|array',
                'log.*.user_id' => 'nullable|numeric',
                'log.*.inventory_id'=>'required|numeric',
                'log.*.change_by_qty' => 'required|numeric|gt:0',
                'log.*.adjustment_type' => ['required', Rule::in(['other','stock_return','production','reconcillation','transfer'])],
                'log.*.comment' => 'string',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            if($request->type=='credit'){
            foreach ($request->log as $logs) {
                $user = new InventoryLog();
                $user->user_id = $logs['user_id'];
                $user->type = 'credit';
                // $product_id=$logs['product_id'];
                // $product=Products::query()->where('id',$logs['product_id'])->first();
                // $addInventory=
                $user->inventory_id=$logs['inventory_id'];
                $user->change_by_qty = $logs['change_by_qty'];
                $user->adjustment_type = $logs['adjustment_type'];
                $user->comment = $logs['comment'];
                $user->save();
            $editInventory=Inventory::query()->where('id',$user->inventory_id)->first();
            $getAvailableQty = ($editInventory->qty + $user->change_by_qty );
            $editInventory->qty=$getAvailableQty;
            $editInventory->save();
            }
        }
        if($request->type=='debit'){
            foreach ($request->log as $logs) {
                $user = new InventoryLog();
                $user->user_id = $logs['user_id'];
                $user->type = 'debit';
                $user->inventory_id=$logs['inventory_id'];
                $user->change_by_qty = $logs['change_by_qty'];
                $user->adjustment_type = $logs['adjustment_type'];
                $user->comment = $logs['comment'];
                $user->save();
            $editInventory=Inventory::query()->where('id',$user->inventory_id)->first();
            $getAvailableQty = ($editInventory->qty - $user->change_by_qty );
            $editInventory->qty=$getAvailableQty;
            $editInventory->save();
            }
        }
            return $this->sendResponse([], "Inventory log added successfully", 200);
        } catch (Exception $e) {
            return $this->sendError('Something Went Wrong', [$e->getTrace()], 413);
        }
    }
    public function addPaymentTerm(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
               'name'=>'required|string'
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $addPaymentTerm=new PaymentTerm;
            $addPaymentTerm->name=$request->name;
            $addPaymentTerm->save();
            return $this->sendResponse([], 'Payment term added successfully', true);
        } catch (Exception $e) {
            return $this->sendError('Something went wrong', $e->getMessage(), 413);
        }
    }
    public function editPaymentTerm(Request $request): JsonResponse
    {
        try {
            $velidator = validator::make($request->all(), [
                'id' => 'required|integer|exists:payment_terms,id',
                'name' => 'required|string'
            ]);
            $editPaymentTerm = PaymentTerm::query()->where('id', $request->id)->first();
            if ($request->has('name')) {
                $editPaymentTerm->name = $request->name;
            }
            $editPaymentTerm->save();
            return $this->sendResponse([], 'Payment term updated successfully', true);
        } catch (Exception $e) {
            return $this->sendResponse('Something went wrong', $e->getMessage(), 413);
        }
    }
    public function getAllPaymentTerm(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'limit' => 'numeric',
                'pageNo' => 'numeric',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $query = PaymentTerm::query();

            $count = $query->count();
            if ($request->has('pageNo') && $request->has('limit')) {
                $limit = $request->limit;
                $pageNo = $request->pageNo;
                $skip = $limit * $pageNo;
                $query = $query->skip($skip)->limit($limit);
            }
            $getPaymentTerm = $query->orderBy('id', 'DESC')->get();
            if (count($getPaymentTerm) > 0) {
                return $this->sendResponse(["payment_terms" => $getPaymentTerm, 'count' => $count], 'Data fetch successfully');
            } else {
                return $this->sendResponse([], 'No payment term are available', false);
            }
        } catch (Exception $e) {
            return $this->sendError('Something Went Wrong', $e->getMessage(), 413);
        }
    }
    public function deletePaymentTermById(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'id' => 'required|integer|exists:payment_terms,id',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $deletePaymentTerm = PaymentTerm::query()->where('id', $request->id)->first();
            $deletePaymentTerm->delete();
            return $this->sendResponse([], 'Payment term deleted successfully', true);
        } catch (Exception $e) {
            return $this->sendError('Something went wrong', $e->getMessage(), 413);
        }
    }
    public function getPaymentTermById(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'id' => 'required|integer|exists:payment_terms,id',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $getPaymentTerm = PaymentTerm::query()->where('id', $request->id)->first();
            return $this->sendResponse($getPaymentTerm, 'Data fetch successfully', true);

        } catch (Exception $e) {
            return $this->sendError('Something Went Wrong', $e->getMessage(), 413);
        }
    }
    public function vendorMappingProductsThroughJson(Request $request)
    {
        try {
            $validator = Validator::make($request->all(), [
                'mapping' => 'required|array',
                'mapping.*.client_id' => 'required|numeric|exists:clients,id',
                'mapping.*.product_id' => 'required|required|exists:products,id',
                //'mapping.*.product_description' => 'required|string',
                'mapping.*.price' => 'required|numeric|gt:0',
               // 'mapping.*.comment' => 'string',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            foreach ($request->mapping as $mappingproduct) {
                $mappingProduct = new VendorMappingProducts();
                $mappingProduct->client_id = $mappingproduct['client_id'];
                $mappingProduct->product_id = $mappingproduct['product_id'];
                //$mappingProduct->product_description = $mappingproduct['product_description'];
                $mappingProduct->price = $mappingproduct['price'];
              //  $mappingProduct->comment = $mappingproduct['comment'];
                $mappingProduct->save();
            }
            return $this->sendResponse([], "Vendor mapping product created successfully", 200);
        } catch (Exception $e) {
            return $this->sendError('Something Went Wrong', [$e->getMessage()], 413);
        }
    }
    public function editVendorMappingProducts(Request $request)
    {
        try {
            $validator = Validator::make($request->all(), [
                'id' => 'required|numeric|exists:vendors_mapping_products,id',
                'client_id' => 'numeric|exists:clients,id',
                'product_id' => 'exists:products,id',
                'product_description' => 'string',
                'price' => 'numeric|gt:0',
                'comment' => 'string',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
                $editmappingProduct =VendorMappingProducts::query()->where('id',$request->id)->first();
                if ($request->has('client_id')) {
                    $editmappingProduct->client_id = $request->client_id;
                }
                if ($request->has('product_id')) {
                    $editmappingProduct->product_id = $request->product_id;
                }
                if ($request->has('product_description')) {
                    $editmappingProduct->product_description = $request->product_description;
                }
                if ($request->has('price')) {
                    $editmappingProduct->price = $request->price;
                }
                if ($request->has('comment')) {
                    $editmappingProduct->comment = $request->comment;
                }
                $editmappingProduct->save();
            return $this->sendResponse([], "Vendor mapping product updated successfully", 200);
        } catch (Exception $e) {
            return $this->sendError('Something Went Wrong', [$e->getMessage()], 413);
        }
    }
    public function getAllVendorMappingProducts(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'limit' => 'numeric',
                'pageNo' => 'numeric',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $query = VendorMappingProducts::query()->with(['client','product']);

            $count = $query->count();
            if ($request->has('pageNo') && $request->has('limit')) {
                $limit = $request->limit;
                $pageNo = $request->pageNo;
                $skip = $limit * $pageNo;
                $query = $query->skip($skip)->limit($limit);
            }
            $getVendorMappingProducts = $query->orderBy('id', 'DESC')->get();
            if (count($getVendorMappingProducts) > 0) {
                return $this->sendResponse(["vendor_mapping" => $getVendorMappingProducts, 'count' => $count], 'Data fetch successfully');
            } else {
                return $this->sendResponse([], 'No vendor mapping are available', false);
            }
        } catch (Exception $e) {
            return $this->sendError('Something Went Wrong', $e->getMessage(), 413);
        }
    }
    public function deleteVendorMappingProductsById(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'id' => 'required|integer|exists:payment_terms,id',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $deleteVendorMappingProducts = VendorMappingProducts::query()->where('id', $request->id)->first();
            $deleteVendorMappingProducts->delete();
            return $this->sendResponse([], 'Vendor mapping deleted successfully', true);
        } catch (Exception $e) {
            return $this->sendError('Something went wrong', $e->getMessage(), 413);
        }
    }
    public function getVendorMappingProductsById(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'id' => 'required|integer|exists:payment_terms,id',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $getVendorMappingProducts = VendorMappingProducts::query()->where('id', $request->id)->with(['client','product'])->first();
            return $this->sendResponse($getVendorMappingProducts, 'Data fetch successfully', true);

        } catch (Exception $e) {
            return $this->sendError('Something Went Wrong', $e->getMessage(), 413);
        }
    }
    public function vendorMappingPaymentTermsThroughJson(Request $request)
    {
        try {
            $validator = Validator::make($request->all(), [
                'payment_term' => 'required|array',
                'payment_term.*.client_id' => 'required|numeric|exists:clients,id',
             //   'payment_term.*.payment_terms_id' => 'required|numeric|exists:payment_terms,id',
                'payment_term.*.payment_term_descr' => 'string',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            foreach ($request->payment_term as $payment_terms) {
                $checkPaymentTerm=PaymentTerm::query()->where('name',$payment_terms['payment_term'])->first();
                if($checkPaymentTerm==null){
                    $addpaymentTerm = new PaymentTerm();
                    $addpaymentTerm->name = $payment_terms['payment_term'];
                    $addpaymentTerm->save();
                }
                $paymentTerms = new VendorPaymentTerms();
                $paymentTerms->client_id = $payment_terms['client_id'];
                $paymentTerm=PaymentTerm::where('name',$payment_terms['payment_term'])->first();
                $paymentTerms->payment_terms_id =$paymentTerm->id;
                $paymentTerms->payment_term_descr = $payment_terms['payment_term_descr'];
                $paymentTerms->save();
            }
            return $this->sendResponse([], "Vendor payments term created successfully", 200);

        } catch (Exception $e) {
            return $this->sendError('Something Went Wrong', [$e->getMessage()], 413);
        }
    }
    public function editVendorMappingPaymentTerms(Request $request)
    {
        try {
            $validator = Validator::make($request->all(), [
                'id' => 'required|numeric|exists:vendor_payment_terms,id',
                'client_id' => 'numeric|exists:clients,id',
                'payment_terms_id' => 'numeric|exists:payment_terms,id',
                'payment_term_descr' => 'string',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
                $editPaymentTerms =VendorPaymentTerms::query()->where('id',$request->id)->first();
                if ($request->has('client_id')) {
                    $editPaymentTerms->client_id = $request->client_id;
                }
                if ($request->has('payment_terms_id')) {
                    $editPaymentTerms->payment_terms_id = $request->payment_terms_id;
                }
                if ($request->has('payment_term_descr')) {
                    $editPaymentTerms->payment_term_descr = $request->payment_term_descr;
                }
                $editPaymentTerms->save();

            return $this->sendResponse([], "Vendor payment term updated successfully", 200);

        } catch (Exception $e) {
            return $this->sendError('Something Went Wrong', [$e->getMessage()], 413);
        }
    }
    public function getAllVendorPaymentTerms(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'limit' => 'numeric',
                'pageNo' => 'numeric',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $query = VendorPaymentTerms::query()->with(['client','payment_term']);

            $count = $query->count();
            if ($request->has('pageNo') && $request->has('limit')) {
                $limit = $request->limit;
                $pageNo = $request->pageNo;
                $skip = $limit * $pageNo;
                $query = $query->skip($skip)->limit($limit);
            }
            $getVendorPaymentTerms = $query->orderBy('id', 'DESC')->get();
            if (count($getVendorPaymentTerms) > 0) {
                return $this->sendResponse(["vendor_payment_terms" => $getVendorPaymentTerms, 'count' => $count], 'Data fetch successfully');
            } else {
                return $this->sendResponse([], 'No vendor payment term are available', false);
            }
        } catch (Exception $e) {
            return $this->sendError('Something Went Wrong', $e->getMessage(), 413);
        }
    }
    public function deleteVendorPaymentTermsById(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'id' => 'required|integer|exists:vendor_payment_terms,id',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $deleteVendorPaymentTerms = VendorPaymentTerms::query()->where('id', $request->id)->first();
            $deleteVendorPaymentTerms->delete();
            return $this->sendResponse([], 'Vendor payment term deleted successfully', true);
        } catch (Exception $e) {
            return $this->sendError('Something went wrong', $e->getMessage(), 413);
        }
    }
    public function getVendorPaymentTermsById(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'id' => 'required|integer|exists:vendor_payment_terms,id',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $getVendorPaymentTerms = VendorPaymentTerms::query()->where('id', $request->id)->with(['client','payment_term'])->first();
            return $this->sendResponse($getVendorPaymentTerms, 'Data fetch successfully', true);

        } catch (Exception $e) {
            return $this->sendError('Something Went Wrong', $e->getMessage(), 413);
        }
    }

    public function getStockValuationInventory(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'limit' => 'numeric',
                'pageNo' => 'numeric',
            ]);

            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }

            $user = auth::user()->store_id;
            $query = Inventory::query()->where('store_id', $user)
                ->with(['product', 'store']);

            $count = $query->count();

            if ($request->has('pageNo') && $request->has('limit')) {
                $limit = $request->limit;
                $pageNo = $request->pageNo;
                $skip = $limit * $pageNo;
                $query = $query->skip($skip)->limit($limit);
            }

            $getStockValuation = $query->orderBy('id', 'DESC')->get();

            if (count($getStockValuation) > 0) {
                $totalValue = 0;
                $productCount = 0;

                foreach ($getStockValuation as $item) {
                    if (isset($item->product) && isset($item->product->price)) {
                        $totalValue += $item->product->price * $item->qty;
                    }

                    $productCount += $item->qty;
                }

                return $this->sendResponse([
                    'total_value' => $totalValue,
                    // 'count' => $count,
                    // 'product_count' => $productCount
                ], 'Data fetched successfully');
            } else {
                return $this->sendResponse([], 'No vendor payment terms are available', false);
            }
        } catch (Exception $e) {
            return $this->sendError('Something Went Wrong', $e->getMessage(), 413);
        }
    }
    public function getStockValuation(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'limit' => 'numeric',
                'pageNo' => 'numeric',
            ]);

            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }

            $user = auth::user()->store_id;
            $query = Inventory::query()->where('store_id', $user)
                ->with(['product', 'store']);

            $count = $query->count();

            if ($request->has('pageNo') && $request->has('limit')) {
                $limit = $request->limit;
                $pageNo = $request->pageNo;
                $skip = $limit * $pageNo;
                $query = $query->skip($skip)->limit($limit);
            }

            $getStockValuation = $query->orderBy('id', 'DESC')->get();

            if (count($getStockValuation) > 0) {
                $totalValue = 0;
                $productCount = 0;

                foreach ($getStockValuation as $item) {
                    if (isset($item->product) && isset($item->product->price)) {
                        $totalValue += $item->product->price * $item->qty;
                    }

                    $productCount += $item->qty;
                }

                return $this->sendResponse([
                    'total_value' => $totalValue,
                    'count' => $count,
                    'product_count' => $productCount
                ], 'Data fetched successfully');
            } else {
                return $this->sendResponse([], 'No vendor payment terms are available', false);
            }
        } catch (Exception $e) {
            return $this->sendError('Something Went Wrong', $e->getMessage(), 413);
        }
    }

public function getstockLevelItems(Request $request): JsonResponse
{
    try {
        $validator = Validator::make($request->all(), [
            'limit' => 'numeric',
            'pageNo' => 'numeric',
        ]);
        if ($validator->fails()) {
            return $this->sendError('Validation Error.', $validator->errors());
        }
        $user=auth::user()->store_id;
        $query = Inventory::query()->where('store_id', $user)
            ->with(['product', 'store']);

        $lowStockcount = 0;

        if ($request->has('pageNo') && $request->has('limit')) {
            $limit = $request->limit;
            $pageNo = $request->pageNo;
            $skip = $limit * $pageNo;
            $inventoryItems = $query->skip($skip)->limit($limit)->orderBy('id', 'DESC')->get();
        } else {
            $inventoryItems = $query->orderBy('id', 'DESC')->get();
        }
        //low stock level
        $lowStockItems = $inventoryItems->filter(function ($item) {
            return $item->product && $item->qty <= $item->product->min_stock_level;
        });
        $lowStockcount = $lowStockItems->count();
        $lowStockPercentage = ($lowStockcount / $inventoryItems->count()) * 100;

        //max stock level
        $maxStockItems = $inventoryItems->filter(function ($item) {
            return $item->product && $item->qty >= $item->product->max_stock_level;
        });
        $maxStockcount = $maxStockItems->count();
        $maxStockPercentage = ($maxStockcount / $inventoryItems->count()) * 100;

        //negative stock
        $negativeStockItems = $inventoryItems->filter(function ($item) {
            return $item->product && $item->qty <0;
        });
        $negativeStockcount = $negativeStockItems->count();
        $negativeStockPercentage = ($negativeStockcount / $inventoryItems->count()) * 100;

        //optimum stock
        $optimumstock = $inventoryItems->count();
        $optimumStockPercentage = ($optimumstock / $inventoryItems->count()) * 100;

        //total stock level
        $totalStock = $inventoryItems->count();
        return $this->sendResponse([
            'low_stock_count' => $lowStockcount,
            'low_stock_percentage' => $lowStockPercentage,
            'max_stock_count' => $maxStockcount,
            'max_stock_percentage' => $maxStockPercentage,
            'negative_stock_count' => $negativeStockcount,
            'negative_stock_percentage' => $negativeStockPercentage,
            'optimum_stock_count' => $optimumstock,
            'optimum_stock_percentage' => $optimumStockPercentage,
            'reorder_stock_count' =>0,
            'reorder_stock_percentage' => 0,
            'excess_stock_count' =>0,
            'excess_stock_percentage' => 0,
            'total_stock_count' => $totalStock
        ], 'Data fetch successfully');
    } catch (Exception $e) {
        return $this->sendError('Something Went Wrong', $e->getMessage(), 413);
    }
}
public function getstockLevelItemsData(Request $request): JsonResponse
{
    try {
        $validator = Validator::make($request->all(), [
            'limit' => 'numeric',
            'pageNo' => 'numeric',
            'type' => ['required', Rule::in(['low_stock', 'max_stock', 'negative_stock', 'optimum_stock'])],
        ]);
        if ($validator->fails()) {
            return $this->sendError('Validation Error.', $validator->errors());
        }
        $user = auth()->user()->store_id;
        $query = Inventory::query()->where('store_id', $user)->with(['product', 'store']);
        if ($request->has('pageNo') && $request->has('limit')) {
            $limit = $request->limit;
            $pageNo = $request->pageNo;
            $skip = $limit * $pageNo;
            $inventoryItems = $query->skip($skip)->limit($limit)->orderBy('id', 'DESC')->get();
        } else {
            $inventoryItems = $query->orderBy('id', 'DESC')->get();
        }
        $list = [];
        if ($request->type == 'low_stock') {
            $lowStockItems = $inventoryItems->filter(function ($item) {
                return $item->product && $item->qty <= $item->product->min_stock_level;
            });
            $list = $lowStockItems->values()->all();
        }
        if ($request->type == 'max_stock') {
            $maxStockItems = $inventoryItems->filter(function ($item) {
                return $item->product && $item->qty >= $item->product->max_stock_level;
            });
            $list = $maxStockItems->values()->all();
        }
        if ($request->type == 'negative_stock') {
            $negativeStockItems = $inventoryItems->filter(function ($item) {
                return $item->product && $item->qty <0;
            });
            $list = $negativeStockItems->values()->all();
        }
        if ($request->type == 'optimum_stock') {
            $list = $inventoryItems->values()->all();
        }
        $count = count($list);

        return $this->sendResponse([
            'data' => $list,
            'count' => $count,
        ], 'Data fetch successfully');
    } catch (Exception $e) {
        return $this->sendError('Something Went Wrong', $e->getMessage(), 413);
    }
}
public function getStockValuvatiotionAgeCategoryStore(Request $request): JsonResponse
{
    try {
        $validator = Validator::make($request->all(), [
            'type' => ['required', Rule::in(['age', 'category', 'store'])],
            'time' => [Rule::in(['0-3_month_old', '3-6_month_old', '6-12_month_old', '12_month_old'])],
            'category_id' => 'numeric|exists:product_categories,id',
        ]);

        if ($validator->fails()) {
            return $this->sendError('Validation Error.', $validator->errors());
        }

        $user = auth::user()->store_id;

        $query = Inventory::query()->where('store_id', $user)->with(['product', 'store']);

        if ($request->has('pageNo') && $request->has('limit')) {
            $limit = $request->limit;
            $pageNo = $request->pageNo;
            $skip = $limit * $pageNo;
            $inventoryItems = $query->skip($skip)->limit($limit)->orderBy('id', 'DESC')->get();
        } else {
            $inventoryItems = $query->orderBy('id', 'DESC')->get();
        }

        $list = [];

        if ($request->type == 'age') {
            $currentDate = Carbon::now();

            if ($request->time == '0-3_month_old') {
                $threeMonthsAgo = $currentDate->copy()->subMonths(3);
                $filteredItems = $inventoryItems->filter(function ($item) use ($threeMonthsAgo, $currentDate) {
                    return $item->created_at->between($threeMonthsAgo, $currentDate);
                });
                $list = $filteredItems->toArray();
            } elseif ($request->time == '3-6_month_old') {
                $threeMonthsAgo = $currentDate->copy()->subMonths(3);
                $sixMonthsAgo = $currentDate->copy()->subMonths(6);
                $filteredItems = $inventoryItems->filter(function ($item) use ($sixMonthsAgo, $threeMonthsAgo) {
                    return $item->created_at->between($sixMonthsAgo, $threeMonthsAgo);
                });
                $list = $filteredItems->toArray();
            } elseif ($request->time == '6-12_month_old') {
                $twelveMonthsAgo = $currentDate->copy()->subMonths(12);
                $sixMonthsAgo = $currentDate->copy()->subMonths(6);
                $filteredItems = $inventoryItems->filter(function ($item) use ($twelveMonthsAgo, $sixMonthsAgo) {
                    return $item->created_at->between($twelveMonthsAgo, $sixMonthsAgo);
                });
                $list = $filteredItems->toArray();
            } elseif ($request->time == '12_month_old') {
                $twelveMonthsAgo = $currentDate->copy()->subMonths(12);
                $filteredItems = $inventoryItems->filter(function ($item) use ($twelveMonthsAgo) {
                    return $item->created_at->lessThanOrEqualTo($twelveMonthsAgo);
                });
                $list = $filteredItems->toArray();
            }
        } elseif ($request->type == 'category') {
            $category_id = $request->category_id;
            $query->whereHas('product', function ($q) use ($category_id) {
                $q->where('product_category_id', $category_id);
            });

            if ($request->has('pageNo') && $request->has('limit')) {
                $limit = $request->limit;
                $pageNo = $request->pageNo;
                $skip = $limit * $pageNo;
                $inventoryItems = $query->skip($skip)->limit($limit)->orderBy('id', 'DESC')->get();
            } else {
                $inventoryItems = $query->orderBy('id', 'DESC')->get();
            }

            $list = $inventoryItems->toArray();
        } elseif ($request->type == 'store') {
            $storeData = $query->orderBy('id', 'DESC')->get();
            $list = $storeData->toArray();
        }

        // Calculate stock valuation and filter out items without required data
        $list = array_filter($list, function ($item) {
            return isset($item['product'], $item['qty'], $item['product']['price']);
        });

        // Calculate stock valuation for each item
        foreach ($list as &$item) {
            $stockValuation = $item['qty'] * $item['product']['price'];
            $item['stock_valuation'] = $stockValuation;
        }

        // Sort list by stock valuation in descending order
        usort($list, function ($a, $b) {
            return $b['stock_valuation'] <=> $a['stock_valuation'];
        });

// Prepare the final response data
$responseData = [];
$totalCount = 0;
$totalValue = 0;

foreach ($list as $index => $item) {
    if ($index >= 5) {
        break; // Stop iterating after the first 5 items
    }

    $count = $item['qty'];
    $stockValuation = $item['stock_valuation'];

    $responseData[] = [
        'item_id' => $item['product']['product_code'],
        'product_name' => $item['product']['name'],
        'stock' => $count,
        'stock_valuation' => $stockValuation,
    ];

    $totalCount += $count;
    $totalValue += $stockValuation;
}
$totalList=count($list);
$totalItems = count($inventoryItems);
$percentage = ($totalItems > 0) ? round(($totalList / $totalItems) * 100) : 0;

return $this->sendResponse([
    'data' => $responseData,
    'count' => $totalItems,
    'product_stock' => $totalCount,
    'product_stock_value' => $totalValue,
    'percentage' => $percentage,
], 'Data fetched successfully');
    } catch (Exception $e) {
        return $this->sendError('Something Went Wrong', $e->getTrace(), 413);
    }
}
public function stockTransfer(Request $request): JsonResponse
{
    try {
        $validator = Validator::make($request->all(), [
            'from_store_id' => 'nullable|exists:stores,id',
            'to_store_id' => 'nullable|exists:stores,id',
            'product' => 'array',
            'product.*.change_by' => 'nullable|numeric',
            'product.*.comment' => 'nullable|string',
        ]);
        if ($validator->fails()) {
            return $this->sendError('Validation Error.', $validator->errors());
        }
        $user=Auth::user()->store_id;
        $stockTransfer = new StockTransfer();
        $stockTransfer->from_store_id = $request->from_store_id;
        $stockTransfer->to_store_id = $request->to_store_id;
        $stockTransfer->comment = $request->comment;
        $stockTransfer->save();
        foreach ($request->product as $products) {
            $stockTransferProducts = new StockTransferProductDetails();
            $stockTransferProducts->stock_transfer_id = $stockTransfer->id;
            $stockTransferProducts->product_id = $products['product_id'];
            $stockTransferProducts->change_by = $products['change_by'];
            $stockTransferProducts->comment = $products['comment'];
            $stockTransferProducts->save();
            $editInventory = Inventory::query()->where('store_id', $request->from_store_id)
                ->where('product_id', $products['product_id'])->first();
            if ($editInventory) {
                $getAvailableQty = $editInventory->qty - $products['change_by'];
                $editInventory->qty = $getAvailableQty;
                $editInventory->save();
            }
             else {
                    return $this->sendResponse([],'Product not found in inventory.',false);
                }
            $editInventoryaddStock = Inventory::query()->where('store_id', $request->to_store_id)
                ->where('product_id', $products['product_id'])->first();
            if ($editInventoryaddStock) {
                $getAvailableQty = $editInventoryaddStock->qty + $products['change_by'];
                $editInventoryaddStock->qty = $getAvailableQty;
                $editInventoryaddStock->save();
            }
            else
            {
                $addInventory=new Inventory();
                $addInventory->store_id=$stockTransfer->to_store_id;
                $addInventory->product_id=$stockTransferProducts->product_id;
                $addInventory->qty=$stockTransferProducts->change_by;
                $addInventory->save();
            }
        }
        return $this->sendResponse([], 'Stock transfer successfully', true);
    } catch (Exception $e) {
        return $this->sendError('Something went wrong', $e->getMessage(), 413);
    }
}
public function getAllStockTransferData(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'limit' => 'numeric',
                'pageNo' => 'numeric',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $query = StockTransfer::query()->with(['from_store', 'to_store']);
            $count = $query->count();
            if ($request->has('pageNo') && $request->has('limit')) {
                $limit = $request->limit;
                $pageNo = $request->pageNo;
                $skip = $limit * $pageNo;
                $query = $query->skip($skip)->limit($limit);
            }
            $getStockTransfer = $query->orderBy('id', 'DESC')->get();
            foreach ($getStockTransfer as $user){
                if($user['id']!=null){
                    $product=StockTransferProductDetails::query()->where('stock_transfer_id',$user['id'])
                    ->with(['product'])->get();
                    $user['stock_transfer_product_details']=$product;
                }
            }
            if (count($getStockTransfer) > 0) {
                return $this->sendResponse(["stock_transfer" => $getStockTransfer, 'count' => $count], 'Data fetch successfully');
            } else {
                return $this->sendResponse([], 'No Stock transfer are available', false);
            }
        } catch (Exception $e) {
            return $this->sendError('Something Went Wrong', $e->getMessage(), 413);
        }
    }
    public function getProductQtyOnAllStores(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'limit' => 'numeric',
                'pageNo' => 'numeric',
                'product_id'=>'numeric|exists:products,id'
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $query = Inventory::query()
            ->where('product_id',$request->product_id)
            ->with(['product', 'store']);
            $count = $query->count();
            if ($request->has('pageNo') && $request->has('limit')) {
                $limit = $request->limit;
                $pageNo = $request->pageNo;
                $skip = $limit * $pageNo;
                $query = $query->skip($skip)->limit($limit);
            }
            $getInventory = $query->orderBy('id', 'DESC')->get();

            if (count($getInventory) > 0) {
                return $this->sendResponse(["product_qty" => $getInventory, 'count' => $count], 'Data fetch successfully');
            } else {
                return $this->sendResponse([], 'No Stock transfer are available', false);
            }
        } catch (Exception $e) {
            return $this->sendError('Something Went Wrong', $e->getMessage(), 413);
        }
    }
    public function getClientTableColumnName(Request $request): JsonResponse
    {
        try {
            $columns = Schema::getConnection()->getDoctrineSchemaManager()->listTableColumns('clients');

            $listAllFields = [];
            foreach ($columns as $eachColumn) {
                array_push($listAllFields, ['name' => $eachColumn->getName(), 'type' => $eachColumn->getType()->getName(), 'isRequired' => $eachColumn->getNotnull()]);
            }
            return $this->sendResponse(["fields" => $listAllFields], 'Data fetch successfully', true);

        } catch (Exception $e) {
            return $this->sendError('Something Went Wrong', $e->getMessage(), 413);
        }
    }
    public function getAllCurrentStock(Request $request): JsonResponse
    {
        try{
            $validator = Validator::make($request->all(),[
                'id'=>'required|integer|exists:products,id',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $product = Products::query()->where('id',$request->id)->first();
            $allInventory = Inventory::query()->where('product_id',$request->id)->with(['store'])->get();
            $count = $allInventory->count();
            if($count<=0){
                return $this->sendResponse([],"No data found",false);
            }
            else{
                $data = array("product"=>$product,"stock_details"=>$allInventory);
                return $this->sendResponse($data,"Product stock details fetched successfully",true);
            }
        }catch(Exception $e){
            return $this->sendError('Something Went Wrong', $e->getMessage(), 413);
        }
    }
    public function getAllAllocatedStockDetails(Request $request):JsonResponse
    {
        try{
            $validator=Validator::make($request->all(),[
                'id'=>'required|integer|exists:products,id'
            ]);
            if($validator->fails()){
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $result=array();
            $product = Products::query()->where('id',$request->id)->first();
            $quotationDetails = QuotationDetails::query()->where('product_id',$request->id)->get();
            $count = $quotationDetails->count();
            if($count<=0){
                return $this->sendResponse([],"No data available",false);
            }
            foreach($quotationDetails as $key => $quot){
                $getQuotation = Quotation::query()->where('id',$quot->quotation_id)->with(['client'])->first();
                $getQuotOc = QuotOc::query()->where('quotation_id',$quot->quotation_id)->first();
                if(!$getQuotOc){
                    $quotationDetails->forget($key);
                }
                else{
                    $quot['quotation_ref']=$getQuotation->reference_no;
                    $quot['client_details']=$getQuotation->client;
                    array_push($result,$quot);
                }
            }
            if(count($quotationDetails)<=0){
                return $this->sendResponse([],"No data available",false);
            }
            $data = array("product"=>$product,"stock_details"=>$result);

            return $this->sendResponse($data,"Allocated stock details fetched successfully",true);
        }catch(Exception $e){
            return $this->sendError("Something went wrong",$e->getMessage(),413);
        }
    }
    public function getProductSellPurchaseHistory(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'id' => 'required|integer|exists:products,id',
                'limit' => 'integer',
                'pageNo' => 'integer',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $product = Products::query()->where('id', $request->id)->first();
            $pucrchaseHistory = [];
            $sellHistory = [];
            $poDetailsQuery = PoDetails::query()->where('product_id', $request->id)->orderBy('created_at', 'desc');
            $quotationDetailsQuery = QuotationDetails::query()->where('product_id', $request->id)->orderBy('created_at', 'desc');
            // If limit and pageNo are present, apply pagination to both queries
            if ($request->has('limit') && $request->has('pageNo')) {
                $limit = $request->limit;
                $pageNo = $request->pageNo;
                $poDetails = $poDetailsQuery->skip($limit * ($pageNo - 1))->take($limit)->get();
                $quotationDetails = $quotationDetailsQuery->skip($limit * ($pageNo - 1))->take($limit)->get();
            } else {
                // Otherwise, get the latest data and limit the results to 5
                $limit = 5;
                $poDetails = $poDetailsQuery->take($limit)->get();
                $quotationDetails = $quotationDetailsQuery->take($limit)->get();
            }
            foreach ($poDetails as $keys => $po) {
                $getPurchaseOrder = PurchaseOrder::query()->where('id', $po->purchase_order_id)->with(['client'])->first();
                if ($getPurchaseOrder) {
                    $po['reference_no'] = $getPurchaseOrder->reference_no;
                    $po['client_details'] = $getPurchaseOrder->client;
                    array_push($pucrchaseHistory, $po);
                }
            }
            foreach ($quotationDetails as $key => $quot) {
                $getQuotation = Quotation::query()->where('id', $quot->quotation_id)->with(['client'])->first();
                $getQuotTaxInvoice = QuotTaxInvoice::query()->where('quotation_id', $quot->quotation_id)->first();
                if ($getQuotation && $getQuotTaxInvoice) {
                    $quot['reference_no'] = $getQuotation->reference_no;
                    $quot['client_details'] = $getQuotation->client;
                    array_push($sellHistory, $quot);
                }
            }
            $finalArray = array("purchase_history" => $pucrchaseHistory, "sell_history" => $sellHistory);
            if (count($finalArray) <= 0) {
                return $this->sendResponse([], "No history available for this product", false);
            }
            $data = array("product" => $product, "purchase_history" => $pucrchaseHistory, "sell_history" => $sellHistory);
            return $this->sendResponse($data, 'Product history fetched successfully.');

        } catch (Exception $e) {
            return $this->sendError("Something went wrong", $e->getMessage(), 413);
        }
    }
    public function addReleventProduct(Request $request):JsonResponse
    {
        try{
            $validator=Validator::make($request->all(),[
                'id'=>'required|integer|exists:products,id',
                'relevent_prod'=>'required|array'
            ]);
            if($validator->fails())
            {
                return $this->sendError("Validation failed",$validator->errors());
            }
            foreach($request->relevent_prod as $prod){
                $getProd = Products::query()->where('product_code',$prod)->first();
                if($getProd){
                    $getRelvent = ReleventProduct::query()->where('parent_product',$request->id)->where('child_product',$getProd->id)->first();
                    if(!$getRelvent){
                        $newReleventProduct = new ReleventProduct;
                        $newReleventProduct->parent_product = $request->id;
                        $newReleventProduct->child_product = $getProd->id;
                        $newReleventProduct->save();
                    }
                }
            }
            return $this->sendResponse([],'Relevent products added successfully',true);
        }catch(Exception $e){
            return $this->sendError("Something went wrong",$e->getMessage(),413);
        }
    }

    // public function getAllReleventProductsByProdId(Request $request):JsonResponse
    // {
    //     try{
    //         $validator=Validator::make($request->all(),[
    //             'id'=>'required|integer|exists:products,id'
    //         ]);
    //         if($validator->fails()){
    //             return $this->sendError("Validation failed",$validator->errors());
    //         }
    //         $data = array();
    //         $product = Products::query()->where('id',$request->id)->first();
    //         $image = ProductImages::query()->where('product_id',$request->id)->where('is_active',true)->first();
    //         $prodData = array(
    //             'name'=>$product->name,
    //             'id'=>$product->id,
    //             'product_code'=>$product->product_code,
    //             'image'=>$image
    //         );
    //         array_push($data, $prodData);
    //         $releventProd = ReleventProduct::query()->where('parent_product',$request->id)->get();
    //         foreach ($releventProd as $prod) {
    //             $child = Products::query()->where('id', $prod->child_product)->first();
    //             $child_image = ProductImages::query()->where('product_id', $child->id)->where('is_active', true)->first();
    //             if ($child && $child->id !== $request->id) {
    //                 $childProdData = array(
    //                     'name' => $child->name,
    //                     'id' => $child->id,
    //                     'product_code' => $child->product_code,
    //                     'image' => $child->image
    //                 );
    //                 array_push($data, $childProdData);
    //             }
    //         }
    //         return $this->sendResponse($data,"Product and relevent products fetched successfully",true);
    //     }catch(Exception $e){
    //         return $this->sendError("Something went wrong",$e->getMessage(),413);
    //     }
    // }
    public function getAllReleventProductsByProdId(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'id' => 'required|integer|exists:products,id'
            ]);

            if ($validator->fails()) {
                return $this->sendError("Validation failed", $validator->errors());
            }

            $data = array();
            $product = Products::query()->where('id', $request->id)->first();
            $image = ProductImages::query()->where('product_id', $request->id)->where('is_active', true)->first();
            $prodData = array(
                'name' => $product->name,
                'id' => $product->id,
                'product_code' => $product->product_code,
                'image' => $image
            );
            array_push($data, $prodData);

            $relevantProd = ReleventProduct::query()
                ->where('parent_product', $request->id)
                ->where('child_product', '!=', $request->id)
                ->get();

            if ($relevantProd->isEmpty()) {
                // No relevant products found
                return $this->sendResponse([], "No relevant products found", true);
            } else {
                foreach ($relevantProd as $prod) {
                    $child = Products::query()->where('id', $prod->child_product)->first();
                    $child_image = ProductImages::query()->where('product_id', $child->id)->where('is_active', true)->first();
                    if ($child) {
                        $childProdData = array(
                            'name' => $child->name,
                            'id' => $child->id,
                            'product_code' => $child->product_code,
                            'image' => $child->image
                        );
                        array_push($data, $childProdData);
                    }
                }
            }
            return $this->sendResponse($data, "Product and relevant products fetched successfully", true);
        } catch (Exception $e) {
            return $this->sendError("Something went wrong", $e->getMessage(), 413);
        }
    }
    public function bulkAddReleventProducts(Request $request):JsonResponse
    {
        try{
            $validator=Validator::make($request->all(),[
                'data'=>'required|array',
                'data.*.product_code'=>'required|string|exists:products,product_code',
                'data.*.relevant_product_code'=>'required|string|exists:products,product_code',
            ]);
            if($validator->fails()){
                return $this->sendError("Validation failed",$validator->errors());
            }
            foreach($request->data as $prod){
                $productData = Products::query()->where('product_code',$prod['product_code'])->first();
                $getProd = Products::query()->where('product_code',$prod['relevant_product_code'])->first();
                if($getProd){
                    $getRelvent = ReleventProduct::query()->where('parent_product',$productData->id)->where('child_product',$getProd->id)->first();
                    if(!$getRelvent){
                        $newReleventProduct = new ReleventProduct;
                        $newReleventProduct->parent_product = $productData->id;
                        $newReleventProduct->child_product = $getProd->id;
                        $newReleventProduct->save();
                    }
                }
            }
            return $this->sendResponse([],'Relevent products added successfully',true);
        }catch(Exception $e){
            return $this->sendError("Something went wrong",$e->getMessage(),413);
        }
    }


}







