File: D:/HostingSpaces/SBogers10/shop.komma.nl/app/Products/Product/ProductController.php
<?php
namespace App\Products\Product;
use App\Attributes\FreeProperties;
use App\Properties\Kms\PropertyService;
use App\Properties\Models\PropertizableInterface;
use Komma\KMS\Core\AbstractTranslatableModel;
use Komma\KMS\Core\AbstractTranslationModel;
use Komma\KMS\Core\Attributes\Attribute;
use Komma\KMS\Core\Attributes\QuantityDiscount;
use Komma\KMS\Core\SectionController;
use App\Categories\Kms\CategoryModelService;
use App\Discounts\Actions\ModifyPriceAction;
use App\Discounts\Conditions\QuantityDiscountCondition;
use App\Discounts\DiscountService;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Collection;
class ProductController extends SectionController
{
protected string $slug = "products";
protected string $classModelName = Product::class;
protected ?string $forTranslationModelName = ProductTranslation::class;
private CategoryModelService $categoryService;
private PropertyService $propertyService;
public function __construct()
{
$productSection = new ProductSection($this->slug);
parent::__construct($productSection);
$this->categoryService = new CategoryModelService();
$this->modelService = new ProductModelService();
$this->translationService = new ProductTranslationModelService();
$this->propertyService = new PropertyService();
}
/**
* A function that MUST delegate to services to accomplish saving.
* It MUST NOT act like a service.
*
* @param Model $model
* @param Collection $attributesByValueFrom
* @return Model
*/
protected function save(Model $model, Collection $attributesByValueFrom = null): Model
{
if($attributesByValueFrom == null) return $model;
$model = parent::save($model, $attributesByValueFrom);
//Use the site service
$this->siteService->save($model, $attributesByValueFrom->get(Attribute::ValueFromItself));
//Retrieve attributes whose value's determine if a translation must be saved.
//We do this because some things like properties are linked to a translation, and therefore it must exist if there are any.
$attributesThatCanForceTranslationSave = $attributesByValueFrom->flatten()->filter(function(Attribute $attribute) {
return is_a($attribute, FreeProperties::class);
});
if(is_a($model, AbstractTranslatableModel::class)) {
//When a documents, componentArea, properties attribute isn't empty, we need to save the translation
$this->translationService->forceSaveWhenTrue($model, function(AbstractTranslationModel $translation) use($attributesThatCanForceTranslationSave, $model) {
foreach($attributesThatCanForceTranslationSave as $attributeThatCanForceTranslationSave) {
if (!$translation->exists && $attributeThatCanForceTranslationSave->getValue() !== '[]') return true;
}
return false;
});
}
//Load property attributes
$this->propertyService->save($model, $attributesByValueFrom->get(Attribute::ValueFromItself));
//Use the discountService
// $discountService = $this->discountService;
// $attributesByValueFrom->collapse()->each(function(Attribute $attribute) use(&$model, &$quantity, &$quantityPrice, &$discountService) {
// if(!is_a($attribute, QuantityDiscount::class)) return;
// /** @var $attribute QuantityDiscount */
// $discountService->manageQuantityDiscountForASpecificProductable($model, $attribute->getQuantity(), $attribute->getDiscountPrice());
// });
return $model;
}
/**
* A function that MUST delegate to services to accomplish loading.
* It MUST NOT act like a service.
*
* @param Model $model
* @param Collection $attributesByValueFrom
* @return Collection
*/
protected function load(Model $model, Collection $attributesByValueFrom = null): Collection
{
$model->load('properties.key.translations', 'properties.values.translations', 'documents');
if($attributesByValueFrom == null) return new Collection();
parent::load($model, $attributesByValueFrom);
// $discountService = $this->discountService;
$attributesByValueFrom->collapse()->each(function(Attribute $attribute) use(&$model, &$quantity, &$quantityPrice, &$discountService) {
if(!is_a($attribute, QuantityDiscount::class)) return;
/** @var $attribute QuantityDiscount */
$discount = $discountService->getQuantityDiscountForASpecificDiscountable($model);
if(!$discount) return;
$quantityDiscountCondition = $discount->getDiscountCondition(); /** @var QuantityDiscountCondition $quantityDiscountCondition */
$modifyPriceAction = $discount->getDiscountAction(); /** @var ModifyPriceAction $modifyPriceAction */
$attribute->setValue($quantityDiscountCondition->getQuantity().'|'.$modifyPriceAction->getModificationValue());
});
//Load property attributes
$this->propertyService->load($model, $attributesByValueFrom->get(Attribute::ValueFromItself));
//Load site
$this->siteService->load($model, $attributesByValueFrom->get(Attribute::ValueFromItself));
//Load quantity discount
// $this->discountService->load($model, $attributesByValueFrom->collapse());
return $attributesByValueFrom;
}
}