<?php

namespace App\Classes\Modules\PackingLists\Processors;

use App\Classes\Exceptions\MalformedRequestException;
use App\Classes\Exceptions\ResourceNotFoundException;
use App\Classes\Modules\Companies\Services\FetchesCompanyModule;
use App\Classes\Modules\Orders\Services\FetchesDataFromYDPortal;

use App\Classes\Modules\Orders\Services\FetchesOrder;
use App\Classes\Modules\PackingLists\DataTransferObjects\ContainerObject;
use App\Classes\Modules\PackingLists\DataTransferObjects\PackageObject;
use App\Classes\Modules\PackingLists\DataTransferObjects\PackingListObject;
use App\Classes\Modules\PackingLists\Services\Containers\FetchesContainer;
use App\Classes\Modules\PackingLists\Services\FetchesPackingList;
use App\Classes\Modules\Schedules\DataTransferObjects\ScheduleObject;
use App\Classes\Modules\Schedules\Services\CreatesSchedule;
use App\Classes\Modules\Steps\DataTransferObjects\StepsObject;
use App\Classes\Modules\Steps\Services\CreatesStep;
use App\Classes\Modules\Transports\DataTransferObjects\TransportObject;
use App\Classes\Modules\Transports\Services\CreatesTransport;
use App\Classes\Modules\Unity\Processors\ActivateContractProcessor;
use App\Classes\Modules\Unity\Processors\AssignContractEntityProcessor;
use App\Classes\Modules\Unity\Processors\CreateContractEntityProcessor;
use App\Classes\Modules\Unity\Services\CreatesContract;
use App\Classes\Modules\Unity\Services\UpdatesContractObligation;
use App\Classes\Notifications\ShipmentDepartureEmail;
use App\Classes\Notifications\ShipmentRescheduleEmail;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\ContainerTypes;
use App\Classes\ValueObjects\Constants\OrderRoleTypes;
use App\Classes\ValueObjects\Constants\PackageType;
use App\Classes\ValueObjects\Constants\PackingListType;
use App\Classes\ValueObjects\Constants\TransportType;
use App\Models\Container;
use App\Models\Order;
use App\Models\PackingList;
use App\Models\Transport;
use Carbon\Carbon;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Str;

class FetchOrderListsFromYdPortalProcessor
{
    /** @var FetchesDataFromYDPortal */
    private $fetchesDataFRomYDPortal;

    /** @var FetchesOrder */
    private $fetchesOrder;

    /** @var UpdatesContractObligation */
    private $updatesContractObligations;

    /** @var CreatePackingListProcessor */
    private $createPackingListProcessor;

    /** @var CreatePackageProcessor */
    private $createPackageProcessor;

    /** @var CreatesTransport */
    private $createsTransport;

    /** @var CreatesSchedule */
    private $createsSchedule;

    /** @var FetchesContainer */
    private $fetchesContainer;

    /** @var FetchesPackingList */
    private $fetchesPackingList;

    /** @var FetchesCompanyModule */
    private $fetchesCompanyModule;

    /** @var CreateContainerProcessor */
    private $createContainerProcessor;

    /** @var CreatesContract */
    private $unityCreateContract;

    /** @var AssignContractEntityProcessor */
    private $unityAssignContractEntity;

    /** @var CreateContractEntityProcessor */
    private $unityCreateContractEntity;

    /** @var CreatesStep */
    private $createsStep;

    /** @var ActivateContractProcessor */
    private $unityActivateContract;

    /**
     * FetchOrderListsFromYdPortalProcessor constructor.
     * @param FetchesDataFromYDPortal $fetchesDataFRomYDPortal
     * @param FetchesOrder $fetchesOrder
     * @param UpdatesContractObligation $updatesContractObligations
     * @param CreatePackingListProcessor $createPackingListProcessor
     * @param CreatePackageProcessor $createPackageProcessor
     * @param CreatesTransport $createsTransport
     * @param CreatesSchedule $createsSchedule
     * @param FetchesContainer $fetchesContainer
     * @param FetchesPackingList $fetchesPackingList
     * @param FetchesCompanyModule $fetchesCompanyModule
     * @param CreateContainerProcessor $createContainerProcessor
     * @param CreatesContract $unityCreateContract
     * @param AssignContractEntityProcessor $unityAssignContractEntity
     * @param CreateContractEntityProcessor $unityCreateContractEntity
     * @param CreatesStep $createsStep
     * @param ActivateContractProcessor $unityActivateContract
     */
    public function __construct(FetchesDataFromYDPortal $fetchesDataFRomYDPortal, FetchesOrder $fetchesOrder, UpdatesContractObligation $updatesContractObligations, CreatePackingListProcessor $createPackingListProcessor, CreatePackageProcessor $createPackageProcessor, CreatesTransport $createsTransport, CreatesSchedule $createsSchedule, FetchesContainer $fetchesContainer, FetchesPackingList $fetchesPackingList, FetchesCompanyModule $fetchesCompanyModule, CreateContainerProcessor $createContainerProcessor, CreatesContract $unityCreateContract, AssignContractEntityProcessor $unityAssignContractEntity, CreateContractEntityProcessor $unityCreateContractEntity, CreatesStep $createsStep, ActivateContractProcessor $unityActivateContract)
    {
        $this->fetchesDataFRomYDPortal = $fetchesDataFRomYDPortal;
        $this->fetchesOrder = $fetchesOrder;
        $this->updatesContractObligations = $updatesContractObligations;
        $this->createPackingListProcessor = $createPackingListProcessor;
        $this->createPackageProcessor = $createPackageProcessor;
        $this->createsTransport = $createsTransport;
        $this->createsSchedule = $createsSchedule;
        $this->fetchesContainer = $fetchesContainer;
        $this->fetchesPackingList = $fetchesPackingList;
        $this->fetchesCompanyModule = $fetchesCompanyModule;
        $this->createContainerProcessor = $createContainerProcessor;
        $this->unityCreateContract = $unityCreateContract;
        $this->unityAssignContractEntity = $unityAssignContractEntity;
        $this->unityCreateContractEntity = $unityCreateContractEntity;
        $this->createsStep = $createsStep;
        $this->unityActivateContract = $unityActivateContract;
    }


    /**
     * @param Carbon|null $start
     * @param Carbon|null $end
     * @return void
     * @throws \GuzzleHttp\Exception\GuzzleException
     */
    public function execute(?Carbon $start = null, ?Carbon $end = null)
    {
        ini_set('max_execution_time', '900');
//        $missingOrders = ['M202302161513122', 'YW202302161027442', 'YW202302151637022', 'M202302151605025', 'M202302151527103', 'M202302151527356', 'M202302151556019', 'YW202302151520241', 'YW202302151445068', 'M202302151359169', 'YW202302151349223', 'YW202302151336520', 'M202302151334316', 'YW202302151148129', 'M202302151145379', 'M202302151142411', 'M202302151037036', 'M202302151036398', 'M202302150919406', 'M202302141535009', 'YW202302141532318', 'M202302141319463', 'M202302141319045', 'YW202302141405471', 'M202302141334494', 'YW202302141321569', 'YW202302141323005', 'M202302141309053', 'M202302140905116', 'M202302141039558', 'M202302141022333', 'YW202302140943182', 'YW202302140923485', 'YW202302131728233', 'YW202302131702040', 'M202302131649417', 'M202302131638056', 'YW202302131601110', 'YW202302131530436', 'YW202302131411338', 'YW202302131355161', 'YW202302131312526', 'M202302130859076', 'M202302111708070', 'M202302111455134', 'M202302111457501', 'M202302111444041', 'M202302111506514', 'M202302111440286', 'M202302111354585', 'M202302111055551', 'M202302110900216', 'YW202302101743112', 'M202302091559443', 'M202302101716374', 'M202302101700402', 'M202302101633570', 'M202302101612095', 'M202302101611408', 'M202302101542340', 'M202302101408370', 'M202302101323341', 'M202302101129532', 'M202302101025109', 'M202302101006595', 'M202302091706357', 'YW202302091255022', 'YW202302091448196', 'YW202302091446431', 'M202302091138154', 'M202302091129396', 'YW202302091028175', 'M202302091006545', 'YW202302090942033', 'YW202302081743094', 'M202302081530599', 'M202302081531210', 'M202302081508571', 'YW202302081530492', 'M202302081500361', 'M202302081253105', 'M202302081303370', 'M202302071636303', 'M202302071741187', 'YW202302071735407', 'M202302071706323', 'M202302071537501', 'M202302071538092', 'YW202302071516453', 'M202302071311314', 'M202302071148154', 'YW202302071136018', 'M202302071036027', 'M202302071008010', 'M202302061742178', 'M202302061615198', 'M202302061502093', 'M202302061458532', 'M202302061552141', 'M202302061548431', 'M202302061555033', 'YW202302061404567', 'M202302061322463', 'M202302061042556', 'M202302061021277', 'M202302060917276', 'M202302041551570', 'M202302041552382', 'YW202302041515257', 'M202302041405502', 'M202302041030185', 'YW202302041215576', 'YW202302041058469', 'YW202302041024459', 'YW202302040939568', 'M202302031701053', 'M202302031700316', 'M202302031430562', 'M202302031431535', 'M202302031147213', 'YW202302031406529', 'YW202302031322256', 'M202302021718554', 'M202302021417415', 'YW202302021404542', 'M202302021055324', 'YW202302021037462', 'M202302011613381', 'M202302011347586', 'M202302011348245', 'M202301151635132', 'M202301141803516', 'YW202301141653536', 'M202301131504477', 'M202301131538220', 'M202301121327453', 'YW202301111153183', 'M202301091649543', 'M202212311641071', 'YW202212211532191', 'YW202212191605226'];

        $from = $end ? Carbon::today()->diff($end)->days : 0;
        $to = $start ? Carbon::today()->diff($start)->days : 10;

        for ($x = $from; $x <= $to; $x++) {
            try {
                $startDate = Carbon::today()->subDays($x);

                $startLimit = Carbon::parse('01-12-2021');

                if($startDate->isBefore($startLimit)){
                    $startDate = $startLimit;
                }

                $endDate = Carbon::today()->subDays($x - 1);

                $orderRequest = $this->fetchesDataFRomYDPortal->clientRequest('http://www.yd-wl.com/api/GetOrderList.ashx', 'GET', [
                    'begintime' => $startDate->timestamp,
                    'endtime' => $endDate->timestamp,
                ]);

                $rows = $this->fetchesDataFRomYDPortal->getResponseBody($orderRequest);

                if(!$rows->data) continue;

                foreach($rows->data as $row){
                    $time_start = microtime(true);

                    $containerReference = null;
                    $loadingDate = null;
                    $unstuffingDate = null;
                    $deliveryDate = null;
                    $etd = null;
                    $eta = null;
                    $delayDate = null;
                    $status = $row->status;

                    if($status >= 3){
                        $trackingRequest = $this->fetchesDataFRomYDPortal->clientRequest('http://www.yd-wl.com/api/ApiTracking.ashx', 'GET', [
                            'trakingno' => $row->expressno
                        ]);

                        $rows = $this->fetchesDataFRomYDPortal->getResponseBody($trackingRequest);

                        if(!$rows){
                            continue;
                        }

                        foreach (array_reverse($rows->data) as $trackingRow) {
                            if ($trackingRow->tracking === '货物已送达仓库准备入库中') {
                                $receiveDate = Carbon::parse($trackingRow->trackingtime);
                            }

                            if (strpos($trackingRow->tracking, '货物装柜完成。') !== false) {
                                $tracking = explode(':', $trackingRow->tracking);
                                $containerReference = explode('预计到港时间', $tracking[1])[0];
                                $loadingDate = Carbon::parse($trackingRow->trackingtime);
                                $etd = Carbon::parse($tracking[2])->subDays(5);
                                $eta = Carbon::parse($tracking[2]);
                            }

                            $rescheduleETD = strpos($trackingRow->remark, '开') || strpos($trackingRow->remark, '到港');
                            $rescheduleETA = strpos($trackingRow->remark, '到港');
                            if (($rescheduleETD !== false || $rescheduleETA !== false) && strpos($trackingRow->tracking, '货物装柜完成。') === false) {
                                preg_match_all('/([0-9]+.{3})/', $trackingRow->remark, $matches);
                                $dates = collect();

                                foreach($matches[0] as $date){
                                    try {
                                        $dates->push(Carbon::parse(str_replace('.', '/', $date).Carbon::now()->format('Y')));
                                    } catch (\Exception $exception) {
                                        continue;
                                    }

                                }

                                $rescheduleDate = $dates->sortDesc()->first();

                                if(!$delayDate || $rescheduleDate > $delayDate){
                                    /** @var Carbon $delayDate */
                                    $delayDate = $rescheduleDate;

                                    if($rescheduleETA === false && $delayDate) {
                                        $delayDate = $delayDate->addDays('5');
                                    }
                                }

                            }

                            if ($trackingRow->tracking === '到港') {
                                $delayDate = Carbon::parse($trackingRow->trackingtime);
                            }

                            if ($trackingRow->tracking === '已开船') {
                                $delayDate = Carbon::parse($trackingRow->trackingtime)->addDays('5');
                            }

                            if ($trackingRow->tracking === '货物已进目的港仓库') {
                                $unstuffingDate = Carbon::parse($trackingRow->trackingtime);
                            }

                            if (Str::contains($trackingRow->tracking, ['派送中', '已签收', '签收完成', ' 第三方提货', '货物已派送完成', '派送', 'delivery', 'delivered'])) {
                                $deliveryDate = Carbon::parse($trackingRow->trackingtime);
                            }
                        }
                    }

                    if($status >= 5){
                        $client = new \GuzzleHttp\Client(['cookies' => true, 'headers' => ['Cookie' => 'utc_offset=480']]);

                        try {
                            $request = $client->request('get', 'https://main.universe.com.my/Tracking/User/Paging?sEcho=1&sTrackingNo='.$row->expressno.'&sOrgId=sti');
                            $deliveryTracking = json_decode($request->getBody()->getContents());
                            foreach (array_reverse($deliveryTracking->aaData) as $trackingRow) {
                                $trackingDate = Carbon::createFromFormat('d/m/y H:i', $trackingRow->LocalDateTime);
                                if (Str::contains($trackingRow->PublicDescription, ['accepted/picked'])){
                                    $unstuffingDate = $trackingDate;
                                }

                                if (Str::contains($trackingRow->PublicDescription, ['delivered'])) {
                                    $deliveryDate = $trackingDate;
                                }
                            }
                        } catch (\Exception $exception){
                            Log::debug('failed to fetch delivery tracking');
                        }
                    }

                    $customerno = preg_split('(-|\(|\)|\/)', $row->customerno);

                    $orderNumber = $customerno[array_key_last($customerno)];
                    $allow_contract = true;

                    try {
                        $order = $this->fetchesOrder->execute(['reference' => $orderNumber]);
                    } catch (ResourceNotFoundException $exception) {
                        try {
                            $order = $this->fetchesOrder->execute(['reference' => substr($orderNumber, -9)]);
                        } catch (ResourceNotFoundException $exception) {
                            $order = $this->fetchesCompanyModule->execute(['id' => 1]);
                            $allow_contract = false;
                        }

                    }

                    $packingListReference = $row->expressno;

                    try{
                        $packingList = $this->fetchesPackingList->execute(['reference' => $row->expressno, 'type' => PackingListType::SHIPPING_PACKING_LIST]);

                        $packingList->packages()->delete();
                        $replica = $packingList->packingLists()->where('type', PackingListType::SHIPPING_PACKING_LIST_REPLICA)->first();
                        if($replica) $replica->packages()->delete();

                        $warehouseReceiveList = $this->fetchesPackingList->execute(['reference' => $row->expressno, 'type' => PackingListType::WAREHOUSE_RECEIVE_LIST]);
                        $warehouseReceiveList->packages()->delete();
                        $replica = $warehouseReceiveList->packingLists()->where('type', PackingListType::WAREHOUSE_RECEIVE_LIST_REPLICA)->first();
                        if($replica) $replica->packages()->delete();

                    } catch (ResourceNotFoundException $exception) {

                        if (!$allow_contract) {
                            $appointee_id = 2307;
                        } else {
                            $appointee_id = $order->orderRoles()->where('role_id', '=', OrderRoleTypes::ORIGIN_FREIGHT_FORWARDER)->first()->appointee->id;
                        }

                        $warehouseReceiveObject = new PackingListObject($packingListReference, $appointee_id, PackingListType::WAREHOUSE_RECEIVE_LIST, $allow_contract ? ApprovalStatus::APPROVED : ApprovalStatus::REJECTED);

                        /** @var PackingList $warehouseReceiveList */
                        $warehouseReceiveList = $this->createPackingListProcessor->execute($warehouseReceiveObject, $order);

                        $transportObject = new TransportObject(TransportType::LAND, null, $row->kuaidilist, Carbon::parse($receiveDate), Carbon::parse($receiveDate), $allow_contract ? ApprovalStatus::APPROVED : ApprovalStatus::REJECTED);
                        $transport = $this->createsTransport->execute($transportObject, $warehouseReceiveList);

                        if ($allow_contract) {

                            $contract = $this->unityCreateContract->execute();

                            $contractReference = $contract->hash_id;
                            $contractObligations = $contract->contract_obligation_list;

                            $this->unityActivateContract->execute($contractReference);

                            $supervisorHashId = $order->orderRoles()->where('role_id', '=', OrderRoleTypes::SUPERVISOR)->first()->appointee->unity_hash_id;

                            $supervisorContractEntity = $this->unityCreateContractEntity->execute($contractReference, $supervisorHashId);
                            $order->orderRoles()->where('role_id', '=', OrderRoleTypes::SUPERVISOR)->first()->update(['entity_hash_id' => $supervisorContractEntity->hash_id, 'entity_signature' => $supervisorContractEntity->entity_signature_hash_id]);

                            $importerContractEntity = $this->unityCreateContractEntity->execute($contractReference, $order->orderRoles()->where('role_id', '=', OrderRoleTypes::IMPORTER)->first()->appointee->unity_hash_id);
                            $order->orderRoles()->where('role_id', '=', OrderRoleTypes::IMPORTER)->first()->update(['entity_hash_id' => $importerContractEntity->hash_id, 'entity_signature' => $importerContractEntity->entity_signature_hash_id]);

                            $this->unityAssignContractEntity->execute($supervisorContractEntity->hash_id, $contractObligations);
                        }

                        $packingListObject = new PackingListObject($packingListReference, $appointee_id, PackingListType::SHIPPING_PACKING_LIST, ApprovalStatus::SUSPENDED, !$allow_contract ? null : $contractReference);

                        /** @var PackingList $packingList */
                        $packingList = $this->createPackingListProcessor->execute($packingListObject, $order);

                        if ($allow_contract) {
                            foreach ($contractObligations as $obligation) {
                                $stepObject = new StepsObject($order->orderRoles()->where('role_id', '=', OrderRoleTypes::SUPERVISOR)->first()->appointee->id, $obligation->reference, $obligation->sequence, $obligation->hash_id);
                                $this->createsStep->execute($packingList, $stepObject);
                            }
                        }
                    }

                    foreach($row->deliverysize as $package) {
                        $packageObject = new PackageObject(PackageType::CARTON, $row->goodname, (float) $package->width, (float) $package->height, (float) $package->length, 0, (float) $package->num, ApprovalStatus::APPROVED);
                        $this->createPackageProcessor->execute($packageObject, $warehouseReceiveList);
                        $this->createPackageProcessor->execute($packageObject, $packingList);
                    }

                    if(!count($row->deliverysize)){
                        $measurement = round(((float) $row->volume / (float) $row->goodcount) ** (1/3) * 100, 2);
                        $packageObject = new PackageObject(PackageType::CARTON, $row->goodname, (float) $measurement, (float) $measurement, (float) $measurement, 0, (float) $row->goodcount, ApprovalStatus::APPROVED);
                        $this->createPackageProcessor->execute($packageObject, $warehouseReceiveList);
                        $this->createPackageProcessor->execute($packageObject, $packingList);
                    }

                    $weightCbm = (float) $row->weight / 500;
                    $overWeightCbm = $weightCbm - $packingList->packages()->sum(DB::raw('(width/100) * (height/100) * (length/100) * quantity'));

                    if($overWeightCbm > 0){
                        $measurement = round($overWeightCbm ** (1/3) * 100, 2);
                        $packageObject = new PackageObject(PackageType::OVER_WEIGHT, 'Overweight CBM', (float) $measurement, (float) $measurement, (float) $measurement, 0, 1, ApprovalStatus::APPROVED);
                        $this->createPackageProcessor->execute($packageObject, $packingList);
                    }

                    if($order instanceof Order){
                        $marking = $order->companyModule->inviters()->withPivot('invitee_reference')->first()->pivot->invitee_reference;
                        if(!in_array($marking, ['1290CSW', '8997ITB', '3992WHE', '962LOW', '1152AAT'])){
                            $this->fetchesDataFRomYDPortal->clientRequest('http://www.yd-wl.com/api/confirmsendorder.ashx', 'GET', [
                                'expressno' => $row->expressno
                            ]);
                        }
                    }


                    if($containerReference) {
                        try {
                            $container = $this->fetchesContainer->execute(['reference' => $containerReference]);
                            $container->packingLists()->detach($packingList);
                            $container->packingLists()->attach($packingList);
                        } catch (ResourceNotFoundException $exception){

                            if (!$allow_contract) {
                                $appointee_id = 2307;
                            }
                            else {
                                $appointee_id = $order->orderRoles()->where('role_id', '=', OrderRoleTypes::ORIGIN_WAREHOUSE)->first()->appointee->id;
                            }

                            $originWarehouse = $this->fetchesCompanyModule->execute(['id' => $appointee_id]);

                            $containerObject = new ContainerObject($containerReference, '', '', ContainerTypes::FORTY_FEET_DRY_CONTAINER, $loadingDate, ApprovalStatus::PENDING_VERIFICATION);
                            /** @var Container $container */
                            $container = $this->createContainerProcessor->execute($containerObject, $originWarehouse);

                            $container->packingLists()->detach($packingList);
                            $container->packingLists()->attach($packingList);

                            $transport = $container->transports()->first();

                            if(!$transport){
                                $transportObject = new TransportObject(TransportType::SEA, null, null,  $etd, null, ApprovalStatus::APPROVED);
                                /** @var Transport $transport */
                                $transport = $this->createsTransport->execute($transportObject, $container);
                                $this->createsSchedule->execute($transport, new ScheduleObject($etd, $eta, ApprovalStatus::APPROVED));
                            }
                        }

                        if($delayDate){
                            $delayDate = $delayDate;
                            $transport = $container->transports()->first();

                            if(!$transport->schedules()->whereDate('eta', '>=', $delayDate)->first()) {
                                $etd = $transport->schedules()->where('status', '=', ApprovalStatus::APPROVED)->first()->etd;
                                $transport->schedules()->update(['status' => ApprovalStatus::EXPIRED]);
                                $this->createsSchedule->execute($transport, new ScheduleObject($etd, $delayDate, ApprovalStatus::APPROVED));
                                foreach ($container->packingLists as $packingList){
                                    if(!($packingList->owner instanceof Order)) continue;
                                    $user = $packingList->owner->companyModule->employees()->first();
                                    if(app()->environment(['production'])) {
                                        $user->notify(new ShipmentRescheduleEmail($user, $packingList));
                                    }
                                }
                            }

                        }

                        if($unstuffingDate && $container->status !== ApprovalStatus::COMPLETED){
                            $container->update(['status' => ApprovalStatus::COMPLETED]);
                            $container->transports()->first()->update(['drop_date' => $unstuffingDate, 'status' => ApprovalStatus::COMPLETED]);

                            /** @var PackingList $packingList */
                            foreach($container->packingLists as $packingList){

                                if($packingList->status === ApprovalStatus::PENDING_VERIFICATION){
                                    $packingList->status = ApprovalStatus::APPROVED;
                                    $packingList->save();
                                }

                                if ($allow_contract) {
                                    $signature = $packingList->owner->orderRoles()->where('role_id', '=', OrderRoleTypes::SUPERVISOR)->first()->appointee->entity_sigiture;
                                    foreach($packingList->steps()->where('reference', '!=', 'DELIVERY')->get() as $step){
                                        $this->updatesContractObligations->execute($signature, $step->obligation_hash_id);
                                        $step->update(['status' => ApprovalStatus::COMPLETED]);
                                    }
                                }

                            }
                        }
                    }

                    if($deliveryDate && !$packingList->transports()->exists()){
                        $packingList->status = ApprovalStatus::COMPLETED;
                        $packingList->save();

                        $deliveryDate = Carbon::parse($deliveryDate);
                        $transportObject = new TransportObject(TransportType::LAND, null, null,  $deliveryDate, $deliveryDate, ApprovalStatus::APPROVED);
                        /** @var Transport $transport */
                        $transport = $this->createsTransport->execute($transportObject, $packingList);
                        $this->createsSchedule->execute($transport, new ScheduleObject($deliveryDate, $deliveryDate, ApprovalStatus::APPROVED));


                        if ($allow_contract) {
                            $deliveryStep = $packingList->steps()->where('reference', '=', 'LAST_MILE_DELIVERY')->first();
                            $signature = $packingList->owner->orderRoles()->where('role_id', '=', OrderRoleTypes::SUPERVISOR)->first()->appointee->entity_sigiture;
                            $this->updatesContractObligations->execute($signature, $deliveryStep->obligation_hash_id);
                            $deliveryStep->update(['status' => ApprovalStatus::COMPLETED]);
                        }

                    }

                    $time_end = microtime(true);

                    $execution_time = ($time_end - $time_start)/60;

                    echo '<b>Total Execution Time:</b> '.$execution_time.' Mins';
                    echo 'successful';

                }

            } catch (\Exception $exception) {
                Log::debug($exception);
            }
        }



    }
}

