<?php

namespace App\Http\Controllers\V1\Production;

use App\Http\Controllers\Controller;
use App\Models\BOM;
use App\Models\BOMFgAltItems;
use App\Models\BOMRawMaterial;
use App\Models\BOMRawMaterialAltItem;
use App\Models\BOMScrap;
use App\Models\BOMRouting;
use App\Models\BOMDetails;
use App\Models\FGProcess;
use App\Models\Inventory;
use App\Models\InventoryLog;
use App\Models\ProductionOrder;
use App\Models\ProductionOrderStage;
use App\Models\BomChargesOption;
use App\Models\BOMChargesDetails;
use App\Models\BOMRotingMapping;
use App\Models\Organization;
use App\Models\FgProduced;
use App\Models\FGProducedIssuedRm;
use App\Models\FGProducedRouting;
use App\Models\FGPRoducedOtherCharges;
use App\Models\FGProducedScrapGenerated;
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;

class ProductionMetadataController extends Controller
{
    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 addBOM(Request $request): JsonResponse
    {

        try {
            $validator = Validator::make($request->all(), [
                'document_name' => 'required|string',
                'fg_store_id' => 'required|integer|exists:stores,id',
                'rm_store_id' => 'required|integer|exists:stores,id',
                'scrap_store_id' => 'required|integer|exists:stores,id',
                'description' => 'nullable',
                'comment' => 'nullable|string',
                'finished_good'=>'required|array',
                'finished_good.*.fg_product_id'=>'required|exists:products,id',
                'finished_good.*.qty'=>'required|integer|gt:0',
                'finished_good.*.comment'=>'nullable|string',
                'finished_good.*.cost_allocation'=>'required',
                // 'finished_good.*.unskilled_hours'=>'required',
                // 'finished_good.*.semi_skilled_hours'=>'required',
                // 'finished_good.*.total_cost'=>'required',
                'bom_charges'=>'nullable|array',
                'bom_charges.*.bom_charge_option_id'=>'nullable|exists:bom_charges_options,id',
                'bom_charges.*.amount'=>'nullable|integer|gt:0',
                'bom_charges.*.comment'=>'nullable|string',
                'fg_alt_items'=>'nullable|array',
                'fg_alt_items.*.alt_product_id'=>'nullable|exists:products,id',
                'fg_alt_items.*.qty'=> 'nullable|integer|gt:0',
                'fg_alt_items.*.comment'=>'nullable|string',
                'fg_alt_items.*.cost_allocation'=>'nullable',
                'raw_material'=>'required|array',
                'raw_material.*.rm_product_id'=>'required|exists:products,id',
                'raw_material.*.qty'=> 'required|integer|gt:0',
                'raw_material.*.comment'=>'nullable|string',
                'raw_material.*.cost_allocation'=>'required',
                'raw_material_alt_item'=>'nullable|array',
                'raw_material_alt_item.*.alt_product_id'=>'nullable|exists:products,id',
                'raw_material_alt_item.*.qty'=> 'nullable|integer|gt:0',
                'raw_material_alt_item.*.comment'=>'nullable|string',
                'raw_material_alt_item.*.cost_allocation'=>'nullable',
                'scrap'=>'nullable|array',
                'scrap.*.scrap_product_id'=>'nullable|exists:products,id',
                'scrap.*.qty'=> 'nullable|integer|gt:0',
                'scrap.*.comment'=>'nullable|string',
                'scrap.*.cost_allocation'=>'nullable',
                'routing'=>'array',
                'routing.*.bom_id'=>'nullable|string',
                'routing.*.bom_routing_id'=> 'nullable|integer|exists:bom_routing,id',
                'routing.*.comment'=>'nullable|string',

            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $newBOM = new BOM();
            $newBOM->document_name = $request->document_name;
            $count = BOM::count() + 1;
            $reference_no = 'BOMREF' . str_pad($count, 4, '0', STR_PAD_LEFT);
            $newBOM->reference_no = $reference_no;
            $newBOM->fg_store_id = $request->fg_store_id;
            $newBOM->rm_store_id = $request->rm_store_id;
            $newBOM->scrap_store_id = $request->scrap_store_id;
            $newBOM->description = $request->description;
            $newBOM->comment = $request->comment;
           // $newBOM->attachment_file = $this->saveImage($request->attachment_file, $request->document_name);
            $newBOM->save();
            if (is_array($request->finished_good) || is_object($request->finished_good)) {
            foreach($request->finished_good as $goods){
                $newFg=new BOMDetails;
                $newFg->bom_id = $newBOM->id;
                $newFg->fg_product_id = $goods['fg_product_id'];
                $newFg->qty=$goods['qty'];
                $newFg->comment = $goods['comment'];
                $newFg->cost_allocation = $goods['cost_allocation'];
                // $newFg->unskilled_hours = $goods['unskilled_hours'];
                // $newFg->semi_skilled_hours = $goods['semi_skilled_hours'];
                //$newFg->total_cost = $goods['total_cost'];
                $newFg->save();
            }
        }
            if (is_array($request->bom_charges) || is_object($request->bom_charges)) {
            foreach($request->bom_charges as $chrges){
                $newFgaltitems = new BOMChargesDetails;
                $newFgaltitems->bom_detail_id = $newFg->id;
                $newFgaltitems->bom_charge_option_id = $chrges['bom_charge_option_id'];
                $newFgaltitems->amount = $chrges['amount'];
                $newFgaltitems->comment = $chrges['comment'];
                $newFgaltitems->save();
        }
    }
    if (is_array($request->fg_alt_items) || is_object($request->fg_alt_items)) {
            foreach($request->fg_alt_items as $items){
                $newFgaltitems = new BOMFgAltItems;
                $newFgaltitems->bom_id = $newBOM->id;
                $newFgaltitems->alt_product_id = $items['alt_product_id'];
                $newFgaltitems->qty = $items['qty'];
                $newFgaltitems->comment = $items['comment'];
                $newFgaltitems->cost_allocation = $items['cost_allocation'];
                $newFgaltitems->save();
        }
    }
            foreach ($request->raw_material as $rowitems) {
                $newRm = new BOMRawMaterial;
                $newRm->bom_id = $newBOM->id;
                $newRm->rm_product_id = $rowitems['rm_product_id'];
                $newRm->qty = $rowitems['qty'];
                $newRm->comment = $rowitems['comment'];
                $newRm->cost_allocation = $rowitems['cost_allocation'];
                $newRm->save();
            }
            if (is_array($request->raw_material_alt_item) || is_object($request->raw_material_alt_item)) {
                foreach ($request->raw_material_alt_item as $rowaltitems) {
                    $newRmaltitem = new BOMRawMaterialAltItem;
                    $newRmaltitem->bom_rm_id =$request->bom_rm_id;
                    $newRmaltitem->alt_product_id = $rowaltitems['alt_product_id'];
                    $newRmaltitem->qty = $rowaltitems['qty'];
                    $newRmaltitem->comment = $rowaltitems['comment'];
                    $newRmaltitem->cost_allocation = $rowaltitems['cost_allocation'];
                    $newRmaltitem->save();
            }
        }
        if (is_array($request->scrap) || is_object($request->scrap)) {
            foreach($request->scrap as $scrapitem){
                $newscrap = new BOMScrap;
                $newscrap->bom_id = $newBOM->id;
                $newscrap->scrap_product_id = $scrapitem['scrap_product_id'];
                $newscrap->qty = $scrapitem['qty'];
                $newscrap->comment = $scrapitem['comment'];
                $newscrap->cost_allocation = $scrapitem['cost_allocation'];
                $newscrap->save();
            }
        }
        if (is_array($request->routing) || is_object($request->routing)) {
            foreach($request->routing as $newrouting){
                $routing = new BOMRotingMapping;
                $routing->bom_id = $newBOM->id;
                $routing->bom_routing_id = $newrouting['bom_routing_id'];
                $routing->comment = $newrouting['comment'];
                $routing->save();
            }
        }
            return $this->sendResponse([], 'Bill of material created successfully', true);
        } catch (Exception $e) {
            return $this->sendError('Something went wrong', $e->getMessage(), 413);
        }
    }
    public function getNextBOMId(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [

            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $response = 'BOMREF'.'000'.(BOM::query()->count()+1);
            return $this->sendResponse(["next_id" => $response], 'Data fetch successfully', true);
        } catch (Exception $e) {
            return $this->sendError('Something Went Wrong', $e->getMessage(), 413);
        }
    }
    public function editBOM(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'id' => 'integer|exists:bill_of_materials,id',
                'document_name' => 'string',
                'fg_store_id' => 'integer|exists:stores,id',
                'rm_store_id' => 'integer|exists:stores,id',
                'scrap_store_id' => 'integer|exists:stores,id',
                'description' => 'nullable',
                'comment' => 'string',
                'finished_good'=>'array',
                'finished_good.*.fg_product_id'=>'exists:products,id',
                'finished_good.*.qty'=>'integer|gt:0',
                'finished_good.*.comment'=>'string',
                'finished_good.*.cost_allocation'=>'required',
                // 'finished_good.*.unskilled_hours'=>'required',
                // 'finished_good.*.semi_skilled_hours'=>'required',
                // 'finished_good.*.total_cost'=>'required',
                'bom_charges'=>'array',
                'bom_charges.*.bom_charge_option_id'=>'exists:bom_charges_options,id',
                'bom_charges.*.amount'=>'integer|gt:0',
                'bom_charges.*.comment'=>'string',
                'fg_alt_items'=>'array',
                'fg_alt_items.*.alt_product_id'=>'exists:products,id',
                'fg_alt_items.*.qty'=> 'integer|gt:0',
                'fg_alt_items.*.comment'=>'string',
                'fg_alt_items.*.cost_allocation'=>'required',
                'raw_material'=>'array',
                'raw_material.*.rm_product_id'=>'exists:products,id',
                'raw_material.*.qty'=> 'integer|gt:0',
                'raw_material.*.comment'=>'string',
                'raw_material.*.cost_allocation'=>'required',
                'raw_material_alt_item'=>'array',
                'raw_material_alt_item.*.alt_product_id'=>'exists:products,id',
                'raw_material_alt_item.*.qty'=> 'integer|gt:0',
                'raw_material_alt_item.*.comment'=>'string',
                'raw_material_alt_item.*.cost_allocation'=>'required',
                'scrap'=>'array',
                'scrap.*.scrap_product_id'=>'exists:products,id',
                'scrap.*.qty'=> 'integer|gt:0',
                'scrap.*.comment'=>'string',
                'scrap.*.cost_allocation'=>'required',
                'routing'=>'array',
                'routing.*.bom_id'=>'nullable|string',
                'routing.*.bom_routing_id'=> 'nullable|string',
                'routing.*.comment'=>'nullable|string',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $editBOM = BOM::query()->where('id', $request->id)->first();

            if ($request->has('document_name')) {
                $editBOM->document_name = $request->document_name;
            }
            if ($request->has('fg_store_id')) {
                $editBOM->fg_store_id = $request->fg_store_id;
            }
            if ($request->has('rm_store_id')) {
                $editBOM->rm_store_id = $request->rm_store_id;
            }
            if ($request->has('scrap_store_id')) {
                $editBOM->scrap_store_id = $request->scrap_store_id;
            }
            if ($request->has('description')) {
                $editBOM->description = $request->description;
            }
            if ($request->has('comment')) {
                $editBOM->comment = $request->comment;
            }
            if ($request->attachment_file != "") {
                if (!str_contains($request->attachment_file, "http")) {
                    $editBOM->attachment_file = $this->saveImage($request->attachment_file, $request->document_name);
                }
            }
            $editBOM->save();
            foreach($request->finished_good as $goods){
                $newFg=new BOMDetails;
                $newFg->bom_id = $editBOM->id;
                $newFg->fg_product_id = $goods['fg_product_id'];
                $newFg->qty=$goods['qty'];
                $newFg->comment = $goods['comment'];
                $newFg->cost_allocation = $goods['cost_allocation'];
                // $newFg->unskilled_hours = $goods['unskilled_hours'];
                // $newFg->semi_skilled_hours = $goods['semi_skilled_hours'];
                // $newFg->total_cost = $goods['total_cost'];
                $newFg->save();
            }
            foreach($request->bom_charges as $chrges){
                $newFgaltitems = new BOMChargesDetails;
                $newFgaltitems->bom_detail_id = $newFg->id;
                $newFgaltitems->bom_charge_option_id = $chrges['bom_charge_option_id'];
                $newFgaltitems->amount = $chrges['amount'];
                $newFgaltitems->comment = $chrges['comment'];
                $newFgaltitems->save();
        }
            foreach($request->fg_alt_items as $items){
                $newFgaltitems = new BOMFgAltItems;
                $newFgaltitems->bom_id = $editBOM->id;
                $newFgaltitems->alt_product_id = $items['alt_product_id'];
                $newFgaltitems->qty = $items['qty'];
                $newFgaltitems->comment = $items['comment'];
                $newFgaltitems->cost_allocation = $items['cost_allocation'];
                $newFgaltitems->save();
        }
            foreach ($request->raw_material as $rowitems) {
                $newRm = new BOMRawMaterial;
                $newRm->bom_id = $editBOM->id;
                $newRm->rm_product_id = $rowitems['rm_product_id'];
                $newRm->qty = $rowitems['qty'];
                $newRm->comment = $rowitems['comment'];
                $newRm->cost_allocation = $rowitems['cost_allocation'];
                $newRm->save();
            }
                foreach ($request->raw_material_alt_item as $rowaltitems) {
                    $newRmaltitem = new BOMRawMaterialAltItem;
                    $newRmaltitem->bom_rm_id =$request->bom_rm_id;
                    $newRmaltitem->alt_product_id = $rowaltitems['alt_product_id'];
                    $newRmaltitem->qty = $rowaltitems['qty'];
                    $newRmaltitem->comment = $rowaltitems['comment'];
                    $newRmaltitem->cost_allocation = $rowaltitems['cost_allocation'];
                    $newRmaltitem->save();
            }
            foreach($request->scrap as $scrapitem){
                $newscrap = new BOMScrap;
                $newscrap->bom_id = $editBOM->id;
                $newscrap->scrap_product_id = $scrapitem['scrap_product_id'];
                $newscrap->qty = $scrapitem['qty'];
                $newscrap->comment = $scrapitem['comment'];
                $newscrap->cost_allocation = $scrapitem['cost_allocation'];
                $newscrap->save();
            }
            foreach($request->routing as $newrouting){
                $routing = new BOMRotingMapping;
                $routing->bom_id = $editBOM->id;
                $routing->bom_routing_id = $newrouting['bom_routing_id'];
                $routing->comment = $newrouting['comment'];
                $routing->save();
            }
            return $this->sendResponse([], 'Bill of material updated successfully');
        } catch (Exception $e) {
            return $this->sendError('Something Went Wrong', $e->getMessage(), 413);
        }
    }
    public function getAllBOM(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'limit' => 'numeric',
                'pageNo' => 'numeric',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $query = BOM::query()->with(['fg_store','rm_store','scrap_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();
            foreach ($getProducts as $user){
                if($user['id']!=null){
                    $product=BOMDetails::query()->where('bom_id',$user['id'])->with(['fg_product'])
                    ->get();
                    $user['bom_details']=$product;
                }
            }
            foreach ($getProducts as $user){
                if($user['id']!=null){
                    $product=BOMChargesDetails::query()->where('bom_detail_id',$user['id'])
                    ->get();
                    $user['bom_charges_details']=$product;
                }
            }
            foreach ($getProducts as $user){
                if($user['id']!=null){
                    $product=BOMFgAltItems::query()->where('bom_id',$user['id'])
                    ->with(['alt_product'])->get();
                    $user['bom_finishedgoods_alt_item']=$product;
                }
            }
            foreach ($getProducts as $user){
                if($user['id']!=null){
                    $product=BOMRawMaterial::query()->where('bom_id',$user['id'])
                    ->with(['alt_product'])->get();
                    $user['bom_raw_material']=$product;
                }
            }
            foreach ($getProducts as $user){
                if($user['id']!=null){
                    $product=BOMRawMaterialAltItem::query()->where('bom_rm_id',$user['id'])
                    ->with(['alt_product'])->get();
                    $user['bom_raw_material_alt_item']=$product;
                }
            }
            foreach ($getProducts as $user){
                if($user['id']!=null){
                    $product=BOMScrap::query()->where('bom_id',$user['id'])
                   ->get();
                    $user['bom_scrap']=$product;
                }
            }
            foreach ($getProducts as $user){
                if($user['id']!=null){
                    $product=BOMRotingMapping::query()->where('bom_id',$user['id'])
                    ->with(['routing'])->get();
                    $user['bom_routing']=$product;
                }
            }
            // foreach ($getProducts as $user){
            //     if($user['id']!=null){
            //         $product=FGProcess::query()->where('bom_id',$user['id'])
            //        ->get();
            //         $user['bom_finishedgoods_process']=$product;
            //     }
            // }
            if (count($getProducts) > 0) {
                return $this->sendResponse(["bill_of_materials" => $getProducts, 'count' => $count], 'Data fetch successfully');
            } else {
                return $this->sendResponse([], 'No bill of material are available', false);
            }
        } catch (Exception $e) {
            return $this->sendError('Something Went Wrong', $e->getMessage(), 413);
        }
    }
    public function deleteBOMById(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'id' => 'required|integer|exists:bill_of_materials,id',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $user = BOM::query()->where('id', $request->id)->first();
            $user->delete();
            return $this->sendResponse([], 'Bill of material deleted successfully', true);
        } catch (Exception $e) {
            return $this->sendError('Something went wrong', $e->getMessage(), 413);
        }
    }
    public function getBOMById(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'id' => 'required|integer|exists:bill_of_materials,id',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $getBOM = BOM::query()->with(['fg_store','rm_store','scrap_store'])->where('id', $request->id)->first();

            return $this->sendResponse($getBOM, 'Data fetch successfully', true);
        } catch (Exception $e) {
            return $this->sendError('Something Went Wrong', $e->getMessage(), 413);
        }
    }
    public function createProductionOrderStage(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'name' => 'required|string',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $newProductionOrderStage = new ProductionOrderStage;
            $newProductionOrderStage->name = $request->name;
            $newProductionOrderStage->save();
            return $this->sendResponse([], 'Production oredr stage created successfully', true);
        } catch (Exception $e) {
            return $this->sendError('Something went wrong', $e->getMessage(), 413);
        }
    }
    public function editProductionOrderStage(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'id' => 'required|integer|exists:production_order_stages,id',
                'name' => 'required|string',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $editProductionOrderStage = ProductionOrderStage::query()->where('id', $request->id)->first();
            if ($request->has('name')) {
                $editProductionOrderStage->name = $request->name;
            }
            $editProductionOrderStage->save();
            return $this->sendResponse([], 'Production oredr stage updated successfully', true);
        } catch (Exception $e) {
            return $this->sendError('Something went wrong', $e->getMessage(), 413);
        }
    }
    public function getAllProductionOrderStage(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'limit' => 'numeric',
                'pageNo' => 'numeric',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $query = ProductionOrderStage::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(["production_order_stage" => $getProducts, 'count' => $count], 'Data fetch successfully');
            } else {
                return $this->sendResponse([], 'No production order stage are available', false);
            }
        } catch (Exception $e) {
            return $this->sendError('Something Went Wrong', $e->getMessage(), 413);
        }
    }
    public function getProductionOrderStageById(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'id' => 'required|integer|exists:production_order_stages,id',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $getProductionOrderStage = ProductionOrderStage::query()->where('id', $request->id)->first();
            return $this->sendResponse($getProductionOrderStage, 'Data fetch successfully', true);
        } catch (Exception $e) {
            return $this->sendError('Something Went Wrong', $e->getMessage(), 413);
        }
    }
    public function deleteProductionOrderStageById(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'id' => 'required|integer|exists:production_order_stages,id',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $user = ProductionOrderStage::query()->where('id', $request->id)->first();
            $user->delete();
            return $this->sendResponse([], 'Production order stage deleted successfully', true);
        } catch (Exception $e) {
            return $this->sendError('Something went wrong', $e->getMessage(), 413);
        }
    }
    public function createProductionOrder(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'production'=>'required|array',
                'production.*.bom_id' => 'required|integer|exists:bill_of_materials,id',
                'production.*.product_id' => 'required|integer|exists:products,id',
                'production.*.reference_no' => 'string',
                'production.*.qty'=>'required|integer|gt:0',
                'production.*.fg_store_id' => 'required|integer|exists:stores,id',
                'production.*.rm_store_id' => 'required|integer|exists:stores,id',
                'production.*.scrap_store_id' => 'required|integer|exists:stores,id',
                'production.*.same_store_in_sub_process' => 'required|boolean',
                'production.*.product_uom_id'=>'required|integer|exists:product_uom,id',
                'production_stage_id' => 'required|integer|exists:production_order_stages,id',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            foreach($request->production as $productionOrder) {
                $count = ProductionOrder::count() + 1;
                $reference_no = 'POD' . str_pad($count, 4, '0', STR_PAD_LEFT);
                $newProductionOrder = new ProductionOrder;
                $newProductionOrder->bom_id =$productionOrder['bom_id'];
                $newProductionOrder->reference_no = $productionOrder['reference_no'];
                $newProductionOrder->product_id = $productionOrder['product_id'];
                $newProductionOrder->qty = $productionOrder['qty'];
                $newProductionOrder->fg_store_id = $productionOrder['fg_store_id'];
                $newProductionOrder->rm_store_id = $productionOrder['rm_store_id'];
                $newProductionOrder->scrap_store_id = $productionOrder['scrap_store_id'];
                $newProductionOrder->production_stage_id = $request->production_stage_id;
                $newProductionOrder->product_uom_id = $productionOrder['product_uom_id'];
                $newProductionOrder->same_store_in_sub_process = $productionOrder['same_store_in_sub_process'];
                $newProductionOrder->production_process_no=$reference_no;
                $newProductionOrder->completed_qty=0;
                $newProductionOrder->save();
            }
            return $this->sendResponse($newProductionOrder->id, 'Production order created successfully', true);
        } catch (Exception $e) {
            return $this->sendError('Something went wrong', $e->getMessage(), 413);
        }
    }

    public function editProductionOrder(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'bom_id' => 'integer|exists:bill_of_materials,id',
                'product_id' => 'integer|exists:products,id',
                'reference_no' => 'string',
                'qty'=>'integer|gt:0',
                'fg_store_id' => 'integer|exists:stores,id',
                'rm_store_id' => 'integer|exists:stores,id',
                'scrap_store_id' => 'integer|exists:stores,id',
                'product_uom_id'=>'integer|exists:product_uom,id',
                'production_stage_id' => 'integer|exists:production_order_stages,id',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $editProductionOrder = ProductionOrder::query()->where('id', $request->id)->first();
            if ($request->has('bom_id')) {
                $editProductionOrder->bom_id = $request->bom_id;
            }
            if ($request->has('reference_no')) {
                $editProductionOrder->reference_no = $request->reference_no;
            }
            if ($request->has('product_id')) {
                $editProductionOrder->product_id = $request->product_id;
            }
            if ($request->has('qty')) {
                $editProductionOrder->qty = $request->qty;
            }
            if ($request->has('fg_store_id')) {
                $editProductionOrder->fg_store_id = $request->fg_store_id;
            }
            if ($request->has('rm_store_id')) {
                $editProductionOrder->rm_store_id = $request->rm_store_id;
            }
            if ($request->has('scrap_store_id')) {
                $editProductionOrder->scrap_store_id = $request->scrap_store_id;
            }
            if ($request->has('product_uom_id')) {
                $editProductionOrder->product_uom_id = $request->product_uom_id;
            }
            if ($request->has('production_stage_id')) {
                $editProductionOrder->production_stage_id = $request->production_stage_id;
            }
            $user = auth::user()->id;
            $editProductionOrder->last_modified_by=$user;
            $editProductionOrder->save();
            return $this->sendResponse([], 'Production order updated successfully', true);
        } catch (Exception $e) {
            return $this->sendError('Something went wrong', $e->getMessage(), 413);
        }
    }

    public function getAllProductionOrder(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'limit' => 'numeric',
                'pageNo' => 'numeric',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $query = ProductionOrder::query()->with(['fg_product', 'production_order_stage','bill_of_materials','finished_goods_store','raw_material_store','scrap_store','last_modified_by']);
            $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) {
                foreach($getProducts as $product){
                    if($product['bill_of_materials']!=null){
                        $getBOM = $product['bill_of_materials'];
                        if($getBOM['id']!=null){
                            $product=BOMRotingMapping::query()->where('bom_id',$getBOM['id'])
                            ->with(['routing'])->get();
                            $getBOM['bom_routing']=$product;
                        }
                        if($getBOM['id']!=null){
                            $product=BOMScrap::query()->where('bom_id',$getBOM['id'])->with(['scrap_product'])
                           ->get();
                            $getBOM['bom_scrap']=$product;
                        }
                        if($getBOM['id']!=null){
                            $product=BOMRawMaterialAltItem::query()->where('bom_rm_id',$getBOM['id'])
                            ->with(['alt_product'])->get();
                            $getBOM['bom_raw_material_alt_item']=$product;
                        }
                        if($getBOM['id']!=null){
                            $product=BOMRawMaterial::query()->where('bom_id',$getBOM['id'])
                            ->with(['alt_product','rm_product'])->get();
                            $getBOM['bom_raw_material']=$product;
                        }
                        if($getBOM['id']!=null){
                            $product=BOMFgAltItems::query()->where('bom_id',$getBOM['id'])
                            ->with(['alt_product'])->get();
                            $getBOM['bom_finishedgoods_alt_item']=$product;
                        }
                        if($getBOM['id']!=null){
                            $product=BOMChargesDetails::query()->where('bom_detail_id',$getBOM['id'])->with(['bom_detail','bom_charge_option'])
                            ->get();
                            $getBOM['bom_charges_details']=$product;
                        }
                        if($getBOM['id']!=null){
                            $product=BOMDetails::query()->where('bom_id',$getBOM['id'])->with(['fg_product'])
                            ->get();
                            $getBOM['bom_details']=$product;
                        }

                    }
                }
                return $this->sendResponse(["production_orders" => $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 getProductionOrderById(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'id' => 'required|integer|exists:production_order,id',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $getProductionOrder = ProductionOrder::query()->with(['fg_product', 'production_order_stage','bill_of_materials','finished_goods_store','raw_material_store','scrap_store','last_modified_by'])->where('id', $request->id)->first();
            if($getProductionOrder['bill_of_materials']!=null){
                $getBOM = $getProductionOrder['bill_of_materials'];
                if($getBOM['id']!=null){
                    $product=BOMRotingMapping::query()->where('bom_id',$getBOM['id'])
                    ->with(['routing'])->get();
                    $getBOM['bom_routing']=$product;
                }
                if($getBOM['id']!=null){
                    $product=BOMScrap::query()->where('bom_id',$getBOM['id'])->with(['scrap_product'])
                   ->get();
                    $getBOM['bom_scrap']=$product;
                }
                if($getBOM['id']!=null){
                    $product=BOMRawMaterialAltItem::query()->where('bom_rm_id',$getBOM['id'])
                    ->with(['alt_product'])->get();
                    $getBOM['bom_raw_material_alt_item']=$product;
                }
                if($getBOM['id']!=null){
                    $product=BOMRawMaterial::query()->where('bom_id',$getBOM['id'])
                    ->with(['alt_product','rm_product'])->get();
                    $getBOM['bom_raw_material']=$product;
                }
                if($getBOM['id']!=null){
                    $product=BOMFgAltItems::query()->where('bom_id',$getBOM['id'])
                    ->with(['alt_product'])->get();
                    $getBOM['bom_finishedgoods_alt_item']=$product;
                }
                if($getBOM['id']!=null){
                    $product=BOMChargesDetails::query()->where('bom_detail_id',$getBOM['id'])->with(['bom_detail','bom_charge_option'])
                    ->get();
                    $getBOM['bom_charges_details']=$product;
                }
                if($getBOM['id']!=null){
                    $product=BOMDetails::query()->where('bom_id',$getBOM['id'])->with(['fg_product'])
                    ->get();
                    $getBOM['bom_details']=$product;
                }

            }
            return $this->sendResponse($getProductionOrder, 'Data fetch successfully', true);
        } catch (Exception $e) {
            return $this->sendError('Something Went Wrong', $e->getMessage(), 413);
        }
    }
    public function deleteProductioOrderById(Request $request): JsonResponse

    {
        try {
            $validator = Validator::make($request->all(), [
                'id' => 'required|integer|exists:production_order,id',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $user = ProductionOrder::query()->where('id', $request->id)->first();

            $user->delete();
            return $this->sendResponse([], 'Production order deleted successfully', true);
        } catch (Exception $e) {
            return $this->sendError('Something went wrong', $e->getMessage(), 413);
        }
    }
    public function updateProductionStage(Request $request): JsonResponse
    {
        try{
            $validator = Validator::make($request->all(),[
                'id' => 'required|integer|exists:production_order,id',
                'production_stage_id' => 'integer|exists:production_order_stages,id',
            ]);
            if($validator->fails()){
                return $this->sendError("Validation failed",$validator->errors());
            }
            $productionOrder = ProductionOrder::query()->where('id',$request->id)->first();
            if($request->has('production_stage_id')){
                $productionOrder->production_stage_id = $request->production_stage_id;
            }
            $productionOrder->save();
            return $this->sendResponse([],"Production order stage updated successfully",true);
        }catch(Exception $e){
            return $this->sendResponse("Something went wrong",$e->getMessage(),413);
        }
    }
    public function updateProductioOrderStatus(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'id' => 'required|integer|exists:production_order,id',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $editProductionOrder = ProductionOrder::query()->where('id', $request->id)->first();

            if ($request->has('pos_id')) {
                $editProductionOrder->pos_id = $request->pos_id;
            }
            $editProductionOrder->save();
            return $this->sendResponse([], 'Production order deleted successfully', true);
        } catch (Exception $e) {
            return $this->sendError('Something went wrong', $e->getMessage(), 413);
        }
    }
    public function addBomChargesOption(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'name' => 'required|string',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $bomCharges=new BomChargesOption;
            $bomCharges->name=$request->name;
            $bomCharges->save();
            return $this->sendResponse([], 'Bill of material charge option created successfully', true);
        } catch (Exception $e) {
            return $this->sendError('Something went wrong', $e->getMessage(), 413);
        }
    }
    public function editBomChargesOption(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'id' => 'required|integer|exists:bom_charges_options,id',
                'name' => 'string',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $editbomCharges = BomChargesOption::query()->where('id', $request->id)->first();
            if ($request->has('name')) {
                $editbomCharges->name = $request->name;
            }
            $editbomCharges->save();
            return $this->sendResponse([], 'Bill of material charge option updated successfully', true);
        } catch (Exception $e) {
            return $this->sendError('Something went wrong', $e->getTrace(), 413);
        }
    }
    public function getAllBomChargesOption(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'limit' => 'numeric',
                'pageNo' => 'numeric',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $query = BomChargesOption::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(["bom_charges_option" => $getProducts, 'count' => $count], 'Data fetch successfully');
            } else {
                return $this->sendResponse([], 'No bill of material charge option are available', false);
            }
        } catch (Exception $e) {
            return $this->sendError('Something Went Wrong', $e->getMessage(), 413);
        }
    }
    public function getBomChargesOptionById(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'id' => 'required|integer|exists:bom_charges_options,id',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $getBomChargesOption = BomChargesOption::query()->first();

            return $this->sendResponse($getBomChargesOption, 'Data fetch successfully', true);
        } catch (Exception $e) {
            return $this->sendError('Something Went Wrong', $e->getMessage(), 413);
        }
    }
    public function deleteBomChargesOptionById(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'id' => 'required|integer|exists:bom_charges_options,id',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $user = BomChargesOption::query()->where('id', $request->id)->first();
            $user->delete();
            return $this->sendResponse([], 'Bill of material charge option deleted successfully', true);
        } catch (Exception $e) {
            return $this->sendError('Something went wrong', $e->getMessage(), 413);
        }
    }
    public function addRouting(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'routing_name'=>'required|string',
                'description'=>'required|string',
                'routing_no'=>'required|string',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $newRouting = new BOMRouting;
            $newRouting->routing_name = $request->routing_name;
            $newRouting->description = $request->description;
            $newRouting->routing_no = $request->routing_no;
            $newRouting->save();
            return $this->sendResponse([], 'Bill of material routing created successfully', true);
        } catch (Exception $e) {
            return $this->sendError('Something went wrong', $e->getMessage(), 413);
        }
    }
    public function editRouting(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'id' => 'required|integer|exists:bom_routing,id',
                'routing_name'=>'string',
                'description'=>'string',
                'routing_no'=>'string',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $editBOMRouting = BOMRouting::query()->where('id', $request->id)->first();
            if ($request->has('routing_name')) {
                $editBOMRouting->routing_name = $request->routing_name;
            }
            if ($request->has('description')) {
                $editBOMRouting->description = $request->description;
            }
            if ($request->has('routing_no')) {
                $editBOMRouting->routing_no = $request->routing_no;
            }
            $editBOMRouting->save();
            return $this->sendResponse([], 'Bill of material routing updated successfully', true);
        } catch (Exception $e) {
            return $this->sendError('Something went wrong', $e->getTrace(), 413);
        }
    }
    public function getAllBOMRouting(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'limit' => 'numeric',
                'pageNo' => 'numeric',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $query = BOMRouting::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(["bom_routing" => $getProducts, 'count' => $count], 'Data fetch successfully');
            } else {
                return $this->sendResponse([], 'No bill of material routing are available', false);
            }
        } catch (Exception $e) {
            return $this->sendError('Something Went Wrong', $e->getMessage(), 413);
        }
    }
    public function getBOMRoutingById(Request $request): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'id' => 'required|integer|exists:bom_routing,id',
            ]);
            if ($validator->fails()) {
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $getBOMRouting = BOMRouting::query()->where('id', $request->id)->first();

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

            $user->delete();
            return $this->sendResponse([], 'Bill of material routing deleted successfully', true);
        } catch (Exception $e) {
            return $this->sendError('Something went wrong', $e->getMessage(), 413);
        }
    }
    public function getAllBOMbyProductId(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());
            }
            $query = BOMDetails::query();
            $count = $query->count();
            $bomDetails = $query->where('fg_product_id', $request->id)->with(['bom','fg_product'])->get();
            if (count($bomDetails) > 0) {
                return $this->sendResponse(["bom" => $bomDetails, 'count' => $count], 'Data fetch successfully');
            } else {
                return $this->sendResponse([], 'No bill of materials are available', false);
            }
        }catch(Exception $e){
            return $this->sendError('Something went wrong', $e->getMessage(),413);
        }
    }

    public function takeProductionAction(Request $request):JsonResponse
    {
        try{
            $validator = Validator::make($request->all(), [
                'id' => 'required|integer|exists:production_order,id',
                'stage_id'=>'integer|exists:production_order_stages,id',

                'fg_produced_qty_added'=>'numeric',
                'fg_produced_comment'=>'string',
                'fg_produced_product_id'=>'required|integer|exists:products,id',


                'fg_produced_issued_rm'=>'array',
                'fg_produced_issued_rm.*.type' => [
                    'string',
                    Rule::in(['issue_from_store', 'return_to_store', 'line_reject']),
                    function ($attribute, $value, $fail) {
                        if (empty($value)) {
                            request()->merge([$attribute => 'issue_from_store']); // Set the default value manually
                        }
                    }
                ],
                'fg_produced_issued_rm.*.change_in_qty'=>'numeric',
                'fg_produced_issued_rm.*.product_id'=>'integer|exists:products,id',
                'fg_produced_issued_rm.*.comment'=>'string',


                'fg_produced_scrap_generated'=>'array',
                'fg_produced_scrap_generated.*.product_id'=>'integer|exists:products,id',
                'fg_produced_scrap_generated.*.product_category_id'=>'integer|exists:product_categories,id',
                'fg_produced_scrap_generated.*.change_in_qty'=>'integer',
                'fg_produced_scrap_generated.*.comment'=>'string',


                'fg_produced_routing'=>'array',
                'fg_produced_routing.*.routing_id'=>'integer|exists:bom_routing,id',
                'fg_produced_routing.*.is_done'=>'boolean',
                'fg_produced_routing.*.comment'=>'string',



                'fg_produced_other_charges'=>'array',
                'fg_produced_other_charges.*.bom_charges_options_id'=>'integer|exists:bom_charges_options,id',
                'fg_produced_other_charges.*.actual_amount'=>'numeric',
                'fg_produced_other_charges.*.comment'=>'string',

            ]);
            if($validator->fails()){
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $productionOrder = ProductionOrder::query()->where('id',$request->id)->first();
            $newFgProduced=FgProduced::query()->where('production_id',$request->id)->first();
            if(!$newFgProduced){
                $newFgProduced=new FgProduced;
                $newFgProduced->save();
            }
            if($newFgProduced->new_qty==null){
                $newFgProduced->new_qty=0;
                $newFgProduced->save();
            }

            $newFgProduced->product_id = $request->fg_produced_product_id;
            if($request->has('fg_produced_qty_added')){
                $newFgProduced->qty_added =$request->fg_produced_qty_added;
                $newFgProduced->new_qty += $request->fg_produced_qty_added;


            }
            if($request->has('fg_produced_comment')){
                $newFgProduced->comment = $request->fg_produced_comment;
            }

            $newFgProduced->production_id=$request->id;
            $newFgProduced->save();
            if($request->has('fg_produced_qty_added')){
                //Updating fg store inventory
                $editFgInventory = Inventory::query()->where('store_id',$productionOrder->fg_store_id)->where('product_id',$newFgProduced->product_id)->first();
                if($editFgInventory){
                    $editFgInventory->qty+=$newFgProduced->qty_added;
                    $newInventoryLog = new InventoryLog();
                    $newInventoryLog->user_id = Auth::user()->id;
                    $newInventoryLog->type = 'credit';
                    $newInventoryLog->inventory_id = $editFgInventory->id;
                    $newInventoryLog->change_qty = $newFgProduced->qty_added;
                    $newInventoryLog->save();
                    $editFgInventory->save();
                }
            }

            $fg_produced_id = $newFgProduced->id;
            $production_id = $request->id;

            if($request->has('fg_produced_issued_rm')){
                foreach($request->fg_produced_issued_rm as $issued_rm) {
                    $newFgIssuedRm = FGProducedIssuedRm::query()->where('production_id',$production_id)->where('fg_produced_id',$fg_produced_id)->first();
                    if(!$newFgIssuedRm){
                        $newFgIssuedRm = new FGProducedIssuedRm;
                        $newFgIssuedRm->save();
                    }
                    if($newFgIssuedRm->new_qty==null){
                        $newFgIssuedRm->new_qty=0;
                        $newFgIssuedRm->save();
                    }

                    $newFgIssuedRm->production_id =$production_id;
                    $newFgIssuedRm->fg_produced_id = $fg_produced_id;

                    if(isset($issued_rm['type'])){
                        $newFgIssuedRm->type = $issued_rm['type'];
                    }
                    if(isset($issued_rm['change_in_qty'])){
                        $newFgIssuedRm->change_in_qty = $issued_rm['change_in_qty'];
                        if($newFgIssuedRm->type!='issue_from_store'){
                            $newFgIssuedRm->new_qty -= $newFgIssuedRm['change_in_qty'];
                        }else{
                            $newFgIssuedRm->new_qty += $newFgIssuedRm['change_in_qty'];
                        }

                    }
                    if(isset($issued_rm['comment'])){
                        $newFgIssuedRm->comment = $issued_rm['comment'];
                    }
                    if(isset($issued_rm['product_id'])){
                        $newFgIssuedRm->product_id = $issued_rm['product_id'];
                    }
                    $newFgIssuedRm->save();
                    if(isset($issued_rm['change_in_qty'])){
                        //Updating rm inventory
                        $editRmInventory = Inventory::query()->where('store_id',$productionOrder->rm_store_id)->where('product_id',$newFgIssuedRm->product_id)->first();
                        if($editRmInventory){
                            if($newFgIssuedRm->type!='issue_from_store'){
                                $editRmInventory->qty+= $newFgIssuedRm->change_in_qty;
                                $newInventoryLog = new InventoryLog();
                                $newInventoryLog->user_id = Auth::user()->id;
                                $newInventoryLog->type = 'credit';
                                $newInventoryLog->inventory_id = $editRmInventory->id;
                                $newInventoryLog->change_qty = $newFgIssuedRm->change_in_qty;
                                $newInventoryLog->save();
                            }
                            else{
                                $editRmInventory->qty-= $newFgIssuedRm->change_in_qty;
                                $newInventoryLog = new InventoryLog();
                                $newInventoryLog->user_id = Auth::user()->id;
                                $newInventoryLog->type = 'debit';
                                $newInventoryLog->inventory_id = $editRmInventory->id;
                                $newInventoryLog->change_qty = $newFgIssuedRm->change_in_qty;
                                $newInventoryLog->save();
                            }
                            $editRmInventory->save();
                        }
                    }
                }
            }

            if($request->has('fg_produced_scrap_generated')){
                foreach($request->fg_produced_scrap_generated as $generatedScrap) {
                    $newScrapGenerated = FGProducedScrapGenerated::query()->where('production_id',$production_id)->where('fg_produced_id',$fg_produced_id)->first();
                    if(!$newScrapGenerated){
                        $newScrapGenerated = new FGProducedScrapGenerated;
                        $newScrapGenerated->save();
                    }
                    if($newScrapGenerated->actual_qty==null){
                        $newScrapGenerated->actual_qty=0;
                        $newScrapGenerated->save();
                    }
                    $newScrapGenerated->production_id =$production_id;
                    $newScrapGenerated->fg_produced_id = $fg_produced_id;
                    if(isset($generatedScrap['product_category_id'])){
                        $newScrapGenerated->product_category_id = $generatedScrap['product_category_id'];
                    }

                    if( isset($generatedScrap['change_in_qty'])){
                        $newScrapGenerated->change_in_qty = $generatedScrap['change_in_qty'];

                        $newScrapGenerated->actual_qty += $generatedScrap['change_in_qty'];

                    }
                    if( isset($generatedScrap['comment'])){
                        $newScrapGenerated->comment = $generatedScrap['comment'];
                    }
                    if(isset($generatedScrap['product_id'])){
                        $newScrapGenerated->product_id = $generatedScrap['product_id'];
                    }
                    $newScrapGenerated->save();
                    if(isset($generatedScrap['change_in_qty'])){
                        //Updating scrap inventory
                        $editScrapInventory = Inventory::query()->where('store_id',$productionOrder->scrap_store_id)->where('product_id',$newScrapGenerated->product_id)->first();
                        if($editScrapInventory){
                            $editScrapInventory->qty += $newScrapGenerated->change_in_qty;
                            $editScrapInventory->save();
                            $newInventoryLog = new InventoryLog();
                            $newInventoryLog->user_id = Auth::user()->id;
                            $newInventoryLog->type = 'credit';
                            $newInventoryLog->inventory_id = $editScrapInventory->id;
                            $newInventoryLog->change_qty = $newScrapGenerated->change_in_qty;
                            $newInventoryLog->save();
                        }
                    }
                }
            }

            if($request->has('fg_produced_routing')){
                foreach($request->fg_produced_routing as $fgRoutingProduced) {
                    $newRoutingProduced = new FGProducedRouting;
                    $newRoutingProduced->production_id =$production_id;
                    $newRoutingProduced->fg_produced_id = $fg_produced_id;
                    if(isset($fgRoutingProduced['routing_id'])){
                        $newRoutingProduced->routing_id = $fgRoutingProduced['routing_id'];
                    }
                    if(isset($fgRoutingProduced['is_done'])){
                        $newRoutingProduced->is_done = $fgRoutingProduced['is_done'];
                    }
                    if(isset($fgRoutingProduced['comment'])){
                        $newRoutingProduced->comment = $fgRoutingProduced['comment'];
                    }
                    $newRoutingProduced->save();
                }
            }

            if($request->has('fg_produced_other_charges')){
                foreach($request->fg_produced_other_charges as $fgOtherCharges) {
                    $newFgOtherCharges = new FGPRoducedOtherCharges;
                    $newFgOtherCharges->production_id =$production_id;
                    $newFgOtherCharges->fg_produced_id = $fg_produced_id;
                    if(isset($fgOtherCharges['bom_charges_options_id'])){
                        $newFgOtherCharges->bom_charges_options_id = $fgOtherCharges['bom_charges_options_id'];
                    }
                    if(isset($fgOtherCharges['actual_amount'])){
                        $newFgOtherCharges->actual_amount = $fgOtherCharges['actual_amount'];
                    }
                    if(isset($fgOtherCharges['comment'])){
                        $newFgOtherCharges->comment = $fgOtherCharges['comment'];
                    }
                    $newFgOtherCharges->save();
                }
            }

            if($request->has('stage_id')){
                $productionOrderStageId = $request->stage_id;
                $productionOrder->production_stage_id = $productionOrderStageId;
            }
            $productionOrder->save();

            return $this->sendResponse([],'Production Process Executed successfully',true);
        }catch(Exception $e){
            return $this->sendError('Something went wrong', $e->getMessage(),413);
        }
    }

    public function completeProductionProcess(Request $request):JsonResponse
    {
        try{
            $validator = Validator::make($request->all(),[
                'id' => 'required|integer|exists:production_order,id',
            ]);
            if($validator->fails()){
                return $this->sendError('Validation Error.', $validator->errors());
            }
            $productionOrder = ProductionOrder::query()->with(['fg_product', 'production_order_stage','bill_of_materials','finished_goods_store','raw_material_store','scrap_store'])->where('id',$request->id)->first();
            $productionOrder->is_completed=true;
            $FgProduced = FgProduced::query()->where('production_id',$request->id)->first();




            $FGProducedIssuedRm = FGProducedIssuedRm::query()->where('production_id',$request->id)->where('fg_produced_id',$FgProduced->id)->get();

            $FGProducedScrapGenerated = FGProducedScrapGenerated::query()->where('production_id',$request->id)->where('fg_produced_id',$FgProduced->id)->get();


            $FGProducedRouting = FGProducedRouting::query()->where('production_id',$request->id)->where('fg_produced_id',$FgProduced->id)->get();

            $FGPRoducedOtherCharges = FGPRoducedOtherCharges::query()->where('production_id',$request->id)->where('fg_produced_id',$FgProduced->id)->get();

            if($productionOrder['bill_of_materials']!=null){
                $getBOM = $productionOrder['bill_of_materials'];
                if($getBOM['id']!=null){
                    $product=BOMRotingMapping::query()->where('bom_id',$getBOM['id'])
                    ->with(['routing'])->get();
                    $getBOM['bom_routing']=$product;
                }
                if($getBOM['id']!=null){
                    $product=BOMScrap::query()->where('bom_id',$getBOM['id'])
                   ->get();
                    $getBOM['bom_scrap']=$product;
                }
                if($getBOM['id']!=null){
                    $product=BOMRawMaterialAltItem::query()->where('bom_rm_id',$getBOM['id'])
                    ->with(['alt_product'])->get();
                    $getBOM['bom_raw_material_alt_item']=$product;
                }
                if($getBOM['id']!=null){
                    $product=BOMRawMaterial::query()->where('bom_id',$getBOM['id'])
                    ->with(['alt_product'])->get();
                    $getBOM['bom_raw_material']=$product;
                }
                if($getBOM['id']!=null){
                    $product=BOMFgAltItems::query()->where('bom_id',$getBOM['id'])
                    ->with(['alt_product'])->get();
                    $getBOM['bom_finishedgoods_alt_item']=$product;
                }
                if($getBOM['id']!=null){
                    $product=BOMChargesDetails::query()->where('bom_detail_id',$getBOM['id'])
                    ->get();
                    $getBOM['bom_charges_details']=$product;
                }
                if($getBOM['id']!=null){
                    $product=BOMDetails::query()->where('bom_id',$getBOM['id'])->with(['fg_product'])
                    ->get();
                    $getBOM['bom_details']=$product;
                }
            }

            $result = array(
                "production_order"=>$productionOrder,
                "fg_produced"=>$FgProduced,
                "fg_produced_issued_rm"=>$FGProducedIssuedRm,
                "fg_produced_scrap_generated"=>$FGProducedScrapGenerated,
                "fg_produced_routing"=>$FGProducedRouting,
                "fg_produced_other_charges"=>$FGPRoducedOtherCharges
            );
            return $this->sendResponse(["data"=>$result],"Production Proccess marked Completed",true);

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


}
