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;
}
}