File: D:/HostingSpaces/SBogers10/shop.komma.nl/app/Products/ProductGroup/ProductGroupModelService.php
<?php
namespace App\Products\ProductGroup;
use App\Catalog\CatalogService;
use Komma\KMS\Core\Attributes\Models\SelectOption;
use Komma\KMS\Core\ModelService;
use Komma\KMS\Core\ModelServiceInterface;
use App\Orders\Models\Order;
use App\Orders\ProductGroup\OrderedProductGroup;
use App\Products\Product\Product;
use App\Products\Product\ProductModelService;
use App\Products\ProductGroupBehaviour\ProductGroupBehaviour;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
/**
* Class ProductGroupModelService
*
* @package App\Products
* @see ProductGroupModelService
*/
class ProductGroupModelService extends ModelService
{
protected $sortable = false;
/** @var ProductModelService $productModelService */
private $productModelService;
/** @var ModelServiceInterface $productGroupBehaviourService */
private $productGroupBehaviourService;
/**
* @var \Illuminate\Contracts\Foundation\Application|CatalogService
*/
private $catalogService;
function __construct()
{
$this->productModelService = app(ProductModelService::class);
$this->productGroupBehaviourService = app(ModelServiceInterface::class);
$this->productGroupBehaviourService->setModelClassName(ProductGroupBehaviour::class);
$this->catalogService = app(CatalogService::class);
$this->setModelClassName(ProductGroup::class);
parent::__construct();
}
/**
* @return SelectOption[]
*/
public function getOptionModelsForProductGroupSelect():array
{
$models = [];
$productGroup = $this->models()->with('translation')->get(['id']);
$productGroup->each(function ($productGroup) use (&$models) {
/** @var ProductGroup $productGroup */
$models[] = (new SelectOption())->setValue($productGroup->id)->setContent($productGroup->id)->setHtmlContent($productGroup->getSidebarName());
});
return $models;
}
/**
* @return SelectOption[]
*/
public function getOptionModelsForProductSelect():array
{
$models = [];
$products = $this->productModelService->models()->with('translation')->get();
$products->each(function ($product) use (&$models) {
/** @var $product Product */
$models[] = (new SelectOption())->setValue($product->id)->setContent($product->id)->setHtmlContent($product->getSidebarName());
});
return $models;
}
/**
* @return SelectOption[]
*/
public function getOptionModelsForBehaviourSelect():array
{
$models = [];
$behaviours = $this->productGroupBehaviourService->models()->get();
$behaviours->each(function ($behaviour) use (&$models) {
$models[] = (new SelectOption())->setValue($behaviour->id)->setContent($behaviour->name)->setHtmlContent(__('KMS::products.'.$behaviour->name));
});
return $models;
}
/**
* Return all groups that are not in composites
*
* @return Builder
*/
public function modelsNotInComposites()
{
$groups = $this->models() //Get all group models
->doesntHave('composites') //...that are not in composites
->with(['translation']); //...with all groupTranslations for the current language id of the current site
return $groups;
}
/**
* Returns the price of the items in the group or the entry-level price depending on the groups behaviour.
*
* @param ProductGroup $group
* @return int
*/
public function getPrice(ProductGroup $group):int {
/** @var ProductGroupBehaviour $behaviour */
$behaviour = $group->productGroupBehaviour()->get();
if(!$behaviour) return 0;
$price = false;
switch ($behaviour->name) {
case 'or':
case 'xor':
$price = $group->products()->min('price');
break;
case 'and':
$price = $group->products()->sum('price');
break;
}
if($price == 0) throw new \RuntimeException('The group "'.$group->name.'" did have a non implemented behaviour name: '.$behaviour->name);
}
/**
* Makes a single orderedProduct based of a product
*
* @param ProductGroup $productGroup
* @param Order $order
* @param int $quantity
* @return OrderedProductGroup
*/
public function createOrderedProductGroupFromProductGroup(ProductGroup $productGroup, Order $order, int $quantity)
{
$attributes = $productGroup->getAttributes();
unset($attributes['product_group_behaviour_id']);
unset($attributes['id']);
$orderedProductGroup = new OrderedProductGroup($attributes);
$orderedProductGroup->quantity = $quantity;
$orderedProductGroup->orderable()->associate($order);
$orderedProductGroup->productGroup()->associate($productGroup);
$orderedProductGroup->save();
$products = $productGroup->products()->get();
$orderedProducts = $products->map(function(Product $product) use ($order, $quantity) {
return $this->productModelService->createOrderedProductFromProduct($product, $order, $quantity);
});
$orderedProductGroup->products()->saveMany($products);
$orderedProductGroup->orderedProducts()->saveMany($orderedProducts);
return $orderedProductGroup;
}
public function destroyForModel(Model $model): Model
{
$this->catalogService->destroyForModel($model);
return $model;
}
}