HEX
Server: Microsoft-IIS/8.5
System: Windows NT YDAWBH120 6.3 build 9600 (Windows Server 2012 R2 Standard Edition) AMD64
User: tentjecom_web (0)
PHP: 7.4.14
Disabled: NONE
Upload Files
File: D:/HostingSpaces/SBogers10/shop.komma.nl/app/Development/TestApiController.php
<?php


namespace App\Development;


use App\Addresses\Models\Address;
use App\Cart\ShoppingCartInterface;
use App\Cart\ShoppingCartItem;
use App\Cart\ShoppingCart;
use App\Categories\Kms\CategoryTreeService;
use App\Categories\Models\Category;
use App\Categories\Resources\Category as CategoryResource;
use App\Checkout\CheckoutService;
use App\Components\Component;
use App\Http\Middleware\WildcardResolver;
use App\Orders\Models\Order;
use App\Orders\Resources\Order as OrderResource;
use App\Products\AbstractProductable;
use App\Products\Product\Product;
use App\Products\Product\ProductResource;
use App\Products\Product\ProductTranslation;
use App\Products\ProductComposite\ProductComposite;
use App\Products\ProductComposite\ProductCompositeResource;
use App\Products\ProductGroup\ProductGroup;
use App\Products\ProductGroup\ProductGroupResource;
use App\ShipmentGroups\Resources\ShipmentGroup as ShipmentGroupResource;
use App\ShipmentGroups\ShipmentGroup;
use App\Shipments\Resources\Shipment as ShipmentResource;
use App\Shipments\Shipment;
use App\ShippingCosts\Resources\ShippingCostsResource;
use App\ShippingCosts\ShippingCost;
use App\ShippingCosts\ShippingCostsService;
use App\Site\Resources\Site as SiteResource;
use App\Site\Site;
use App\Users\Resources\KmsUserResource;
use App\Users\Resources\SiteUserResource;
use App\Users\SiteUser;
use App\Users\SiteUserInterface;
use App\Vat\VatService;
use Illuminate\Auth\Events\Registered;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
use Komma\KMS\Documents\Models\Document;
use Komma\KMS\Documents\Resources\Document as DocumentResource;
use Komma\KMS\Globalization\RegionInfo;
use Komma\KMS\Globalization\RegionInfoInterface;
use Komma\KMS\Globalization\Resources\RegionInfoResource;
use Komma\KMS\Sites\SiteServiceInterface;
use Komma\KMS\Users\Models\KmsUser;

/**
 * Class TestApiController
 *
 * Used by tools like cypress to setup a end to end test.
 * Make sure the controller NEVER is accessible in production
 *
 * @package App\Development
 */
class TestApiController extends Controller
{
    public function __construct()
    {
        if(app()->environment() === 'production') {
            throw new \RuntimeException('It is unsafe to expose the TestApiController to production environments.');
        }
    }

    /*
    |--------------------------------------------------------------------------
    | Components
    |--------------------------------------------------------------------------
    |
    */
    public function getComponents(Request $request) {
        $query = Component::query()->orderBy('created_at', 'desc');
        if($request->has('take')) $query->take($request->get('take'));
        $components = $query->get();
        return response()->json(['data' => $components]);
    }


    /*
    |--------------------------------------------------------------------------
    | Orders
    |--------------------------------------------------------------------------
    |
    | These functions act on orders. Only for dev purposes
    |
    */
    /**
     * Return an order as json
     */
    public function showOrder(Order $order = null)
    {
        if(!$order) {
            $order = Order::inRandomOrder()->first();
        }
        $order->load('customer', 'orderedProductComposites.orderedGroups.orderedProducts.product.translations', 'orderedGroups.orderedProducts.product.translations', 'orderedProducts.product.translations', 'transactions', 'shipments');
        $resource = new OrderResource($order);

        return $resource;
    }

    /**
     * @param Request $request
     * @return OrderResource
     */
    public function createOrder(Request $request) {
        /** @var SiteServiceInterface $siteService */
        $siteService = app(SiteServiceInterface::class);
        $siteService->setCurrentSiteToDefault();

        //CheckoutService
        $checkoutService = new CheckoutService();

        //ShoppingCart
        $shoppingCart = app(ShoppingCartInterface::class);

        //Get a random customer user to test with
        /** @var SiteUser $customer */
        $customer = factory(SiteUser::class)->create();

        //Give it an address
        /** @var Address $address */
        $address = factory(Address::class)->create();
        $customer->addresses()->save($address);

        //Put some random products in the shopping cart
        $products = Product::inRandomOrder()->take(3)->get();

        //Put some random product groups in the shopping cart
        $productGroups = ProductGroup::inRandomOrder()->take(2)->get();

        //Put some random product composites in the shopping cart
        $productComposites = ProductComposite::inRandomOrder()->take(1)->get();

        //Build an order
        $allProductables = collect();
        $allProductables = $allProductables->merge($products);
        $allProductables = $allProductables->merge($productGroups);
        $allProductables = $allProductables->merge($productComposites);

        $allProductables->each(function(AbstractProductable $productable) use ($shoppingCart) {
            /** @var ShoppingCartItem $shoppingCartItem */
            $shoppingCartItem = $shoppingCart->addProductable($productable, mt_rand(1, 3));
        });

        $order = $checkoutService->createOrder($shoppingCart, $customer, $customer->addresses()->first(), $customer->addresses()->first());

        //Check if the request has attributes
        if($request->has('attributes')) {
            $order->fill($request->get('attributes'));
            $order->save();
        }

        //Create the resource and return it.
        $resource = new OrderResource($order);
        return $resource;
    }


    /*
    |--------------------------------------------------------------------------
    | Shipping costs
    |--------------------------------------------------------------------------
    |
    | These functions act on shipping costs. Only for dev purposes
    */
    public function shippingCosts() {
        $vatService = new VatService();
        $shippingCostService = new ShippingCostsService();
        $shippingCosts = $shippingCostService->models()->get()->map(function(ShippingCost $shippingCost) use($vatService) {
            $vatService->calculateVatForModelWithVatScenarioEnum($shippingCost);
            return $shippingCost;
        });
        return ShippingCostsResource::collection($shippingCosts);
    }

    /*
    |--------------------------------------------------------------------------
    | Shipments
    |--------------------------------------------------------------------------
    |
    | These functions act on shipments. Only for dev purposes
    |
    */
    /**
     * Return an Shipment as json
     * @param Shipment|null $shipment
     * @return ShipmentResource
     */
    public function showShipment(Shipment $shipment = null)
    {
        if(!$shipment) $shipment = Shipment::inRandomOrder()->with('shipmentGroup', 'order')->first();
        $resource = new ShipmentResource($shipment);

        return $resource;
    }

    /**
     * List all shipments
     */
    public function indexShipments() {
        $shipments = Shipment::latest()->with('shipmentGroup', 'order')->get();
        return ShipmentResource::collection($shipments);
    }
    
    /*
    |--------------------------------------------------------------------------
    | Shipment Groups
    |--------------------------------------------------------------------------
    |
    | These functions act on shipment groups. Only for dev purposes
    |
    */
    /**
     * Return an ShipmentGroup as json
     * @param ShipmentGroup|null $shipmentGroup
     * @return ShipmentGroupResource
     */
    public function showShipmentGroup(ShipmentGroup $shipmentGroup = null)
    {
        if(!$shipmentGroup) $shipmentGroup = ShipmentGroup::inRandomOrder()->with('shipments')->first();
        $resource = new ShipmentGroupResource($shipmentGroup);

        return $resource;
    }

    /**
     * List all documents
     */
    public function indexShipmentGroups() {
        $shipmentGroups = ShipmentGroup::latest()->with('shipments')->get();
        return ShipmentGroupResource::collection($shipmentGroups);
    }

    /*
    |--------------------------------------------------------------------------
    | KMS Users
    |--------------------------------------------------------------------------
    |
    | These functions act on users. Only for dev purposes
    |
    */
    /**
     * Create a random user and return it.
     */
    public function createKmsUser(Request $request)
    {
        /*** @var $user KmsUser */
        $user = factory(KmsUser::class)->create();

        if($request->has('attributes')) {
            $attributes = $request->get('attributes');
            $user->fill($attributes);
            if(isset($attributes['password'])) $user->password = Hash::make($attributes['password']);
            $user->save();
        }

        $userResource = new KmsUserResource($user);
        return $userResource;
    }

    /**
     * Delete a kms user
     */
    public function deleteKmsUser(KmsUser $user)
    {
        $user = $user->delete();
        return response()->json(204);
    }

    /**
     * Show a random or specific
     */
    public function showKmsUser(KmsUser $user = null)
    {
        if(!$user) $user = KmsUser::inRandomOrder()->first();
        $userResource = new KmsUserResource($user);
        return $userResource;
    }

    /*
    |--------------------------------------------------------------------------
    | Site Users
    |--------------------------------------------------------------------------
    |
    | These functions act on users. Only for dev purposes
    |
    */
    /**
     * Create a random user and return it.
     */
    public function createSiteUser(Request $request)
    {
        /*** @var $user SiteUser */
        $user = factory(SiteUser::class)->create();

        if($request->has('attributes')) {
            $attributes = $request->get('attributes');
            $user->fill($attributes);
            if(isset($attributes['password'])) $user->password = Hash::make($attributes['password']);
            $user->save();
        }

        /** @var Address $address */
        $address = factory(Address::class)->make();
        $address->first_name = $user->first_name;
        $address->last_name_prefix = $user->last_name_prefix ?? '';
        $address->last_name = $user->last_name;
        $address->siteUser()->associate($user);
        $address->save();

        $user->accountAddress()->associate($address);
        $user->shippingAddress()->associate($address);
        $user->invoiceAddress()->associate($address);
        $user->save();

        return new SiteUserResource($user);
    }

    /**
     * Delete a site user
     */
    public function deleteSiteUser(SiteUser $user)
    {
        $user->addresses()->delete();
        $user->delete();
        return response()->json(204);
    }

    /**
     * Show a random or specific
     */
    public function showSiteUser(SiteUser $user = null)
    {
        if(!$user) $user = SiteUser::inRandomOrder()->first();
        $userResource = new SiteUserResource($user);
        return $userResource;
    }

    /**
     * Show a random or specific
     */
    public function me(Request $request)
    {
        /** @var SiteUser $siteUser */
        $siteUser = Auth::guard('site')->user();

        if($request->has('load') && is_array('load')) {
            $siteUser->load($request->get('load'));
        }

        return new SiteUserResource($siteUser);
    }

    /*
    |--------------------------------------------------------------------------
    | Documents
    |--------------------------------------------------------------------------
    |
    | These functions act on documents. Only for dev purposes
    |
    */
    /**
     * List all documents
     */
    public function indexDocuments() {
        $documents = Document::latest()->with('documentable')->get();
        return DocumentResource::collection($documents);
    }

    /**
     * Delete a document
     */
    public function deleteDocument(Document $document)
    {
        $document = $document->delete();
        return response()->json(204);
    }

    /*
    |--------------------------------------------------------------------------
    | Sites
    |--------------------------------------------------------------------------
    |
    | These functions act on sites. Only for dev purposes
    |
    */
    /**
     * List all documents
     */
    public function indexSites() {
        $sites = Site::latest()->get();
        return SiteResource::collection($sites);
    }

    /*
    |--------------------------------------------------------------------------
    | Cart
    |--------------------------------------------------------------------------
    |
    | These functions act on the shopping cart

    |
    */
    public function addToCart(Request $request) {
        $cart = app(ShoppingCartInterface::class);
        $vatService = new VatService();

        $cart->clear();

        if(!$request->has('items')) abort(400, 'Please specify your items in an array called "items"');

        foreach($request->get('items') as $item) {
            $productable = null;

            switch ($item['productable_type'] ?? null) {
                case 'product':
                    $productable = Product::find($item['id'] ?? null);
                    break;
                case 'product_group':
                    $productable = ProductGroup::find($item['id'] ?? null);
                    break;
                default:
                    abort(400, 'An item with a productable_type value of "'.$item['productable_type'].'" is not supported.');
            }

            if(!$productable) abort(400, 'An item with a productable_type value of "'.$item['productable_type'].'" and id of "'.$item['id'].'" was not found.');

            $vatService->calculateVatForModelWithVatScenarioEnum($productable);
            $cart->addProductable($productable, $item['quantity'] ?? '1');
        }
    }

    /*
    |--------------------------------------------------------------------------
    | Productables
    |--------------------------------------------------------------------------
    |
    | These functions act on productables. Only for dev purposes
    |
    */
    /**
     * List all products that do not have images
     */
    public function productsWithoutImage() {
        $vatService = new VatService();
        $productables = Product::latest()->with('translation', 'translations')->whereDoesntHave('images')->get()->map(function(Product $product) use($vatService) {
            $vatService->calculateVatForModelWithVatScenarioEnum($product);
            return $product;
        });

        return ProductResource::collection($productables);
    }

    /**
     * List all products that do not have images
     */
    public function productsWithImages() {
        $vatService = new VatService();
        $productables = Product::latest()->with('translation', 'translations')->get()->map(function(Product $product) use($vatService) {
            $vatService->calculateVatForModelWithVatScenarioEnum($product);
            return $product;
        });

        return ProductResource::collection($productables);
    }

    /**
     * List all products
     */
    public function indexProducts() {
        $vatService = new VatService();
        $productables = Product::latest()->with('translation', 'translations')->get()->map(function(Product $product) use($vatService) {
            $vatService->calculateVatForModelWithVatScenarioEnum($product);
            return $product;
        });

        return ProductResource::collection($productables);
    }

    /**
     * List all product groups
     */
    public function indexProductGroups() {
        $productable = ProductGroup::latest()->with('translation', 'translations')->get();
        return ProductGroupResource::collection($productable);
    }

    /**
     * List all product groups
     */
    public function indexProductComposites() {
        $productable = ProductComposite::latest()->with('translation', 'translations')->get();
        return ProductCompositeResource::collection($productable);
    }

    /*
    |--------------------------------------------------------------------------
    | Categories
    |--------------------------------------------------------------------------
    |
    | These functions act on categories. Only for dev purposes
    |
    */
    /**
     * List all categories
     */
    public function indexCategories() {
        $category = Category::latest()->with('translation', 'translations')->where('id', '!=', 1)->get();
        return CategoryResource::collection($category);
    }

    /**
     * Return the top level categories
     */
    public function topLevelCategories() {
        $rootCategory = (new CategoryTreeService())->treeWithTranslationsLinksAndActiveStates(1);
        $categories = collect($rootCategory->getChildren())->sortBy(function(Category $category) {
            return $category->getDisplayName();
        });
        return CategoryResource::collection($categories);
    }

    /*
    |--------------------------------------------------------------------------
    | Region info
    |--------------------------------------------------------------------------
    |
    | Works with region info information.
    |
    */
    /**
     * Return an order as json
     *
     * @param Request $request
     * @return RegionInfoResource
     */
    public function randomRegionInfo(Request $request)
    {
        $regionInfo = false;
        while($regionInfo == false) {
            /** @var RegionInfo $regionInfo */
            $candidateRegionInfo = RegionInfo::getNeutralCultures()->random(1)->first();
            if(ShippingCost::where('code', '=', $candidateRegionInfo->getThreeLetterISORegionName())->count() == 0)
            {
                $regionInfo = $candidateRegionInfo;
                break;
            }
        }

        $resource = new RegionInfoResource($regionInfo);

        return $resource;
    }

    /*
    |--------------------------------------------------------------------------
    | Vat info
    |--------------------------------------------------------------------------
    |
    | Works with vat rate information.
    |
    */
    /**
     * Returns an object containing an catalog url and a vat rate for a random product.
     * So that you can test it using cypress
     *
     * @param Request $request
     * @return array
     */
    public function catalogVatTestData(Request $request)
    {
         //Initialize some services that are needed
         $rateService = new VatService();
         /** @var RegionInfo $regionInfo */
         $regionInfo = app(RegionInfoInterface::class);

         //Set the current site to the default one.
         /** @var SiteServiceInterface $siteService */
         $siteService = app(SiteServiceInterface::class);
         $siteService->setCurrentSiteToDefault();

         //Get a product
         /** @var Product $product */
         $product = Product::wherehas('translations')->with('translations.language')->first();

         //Construct the catalog url fo the product details
         /** @var ProductTranslation $translation */
         $translation = $product->translations->first();
         $baseRoute = WildcardResolver::getWildCardIndexRouteForPageWithCodeName('products');
         $url = $baseRoute->alias.'/'.$translation->slug;

         //Calculate model vat and put it in temporary variables in the product
         $rateService->calculateVatForModelWithVatScenarioEnum($product);

         return [
             'catalog_url' => $url,
             'vat_amount' => $product->vat_amount,
             'vat_amount_formatted' => $regionInfo->getNumberFormat()->centsToCurrency($product->vat_amount, true),
             'price_inc' => $product->price_inc,
             'price_inc_formatted' => $regionInfo->getNumberFormat()->centsToCurrency($product->price_inc, true),
         ];
    }


    /*
    |--------------------------------------------------------------------------
    | Mail intercepts
    |--------------------------------------------------------------------------
    |
    | These functions act on documents. Only for dev purposes
    */
    public function enableMailIntercepts()
    {
        session()->put('enable_mail_intercepts', true);
        return response('intercepting', 200);
    }

    public function disableMailIntercepts()
    {
        session()->put('enable_mail_intercepts', false);
        return response('stopped intercepting', 200);
    }

    public function getInterceptedMails()
    {
        $response = response()->json(session()->pull('e2e_mails', []));
        session()->remove('e2e_mails');
        return $response;
    }
}