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/database/seeds/TestMacBookGroupAndProducts.php
<?php

namespace App\seeds;

use App\Categories\Models\Category;
use App\Categories\Models\CategoryTranslation;
use App\Properties\Kms\PropertyService;
use App\Properties\Models\Property;
use App\Properties\Models\PropertyKey;
use App\Properties\Models\PropertyKeyTranslation;
use App\Properties\Resources\KeyValueTranslation;
use App\Site\Site;
use App\Vat\VatScenarioEnum;
use Illuminate\Database\Eloquent\Builder;
use \Illuminate\Database\Eloquent\Collection as DatabaseCollection;
use \Illuminate\Support\Collection as RegularCollection;
use Illuminate\Support\Str;
use Komma\KMS\Globalization\Languages\Models\Language;
use App\Products\Product\Product;
use App\Products\Product\ProductTranslation;
use App\Products\ProductGroup\ProductGroup;
use App\Products\ProductGroup\ProductGroupTranslation;
use App\Products\ProductGroupBehaviour\ProductGroupBehaviour;
use Illuminate\Database\Seeder;

class TestMacBookGroupAndProducts extends Seeder
{
    private int $eanNumberCounter = 1000000;

    /** @var ProductGroupBehaviour[]|DatabaseCollection */
    private ?DatabaseCollection $productGroupBehaviors;
    private ?Category $laptopsCategory;
    private ?Category $rootCategory;
    private PropertyService $propertyService;
    /** @var Language[]|DatabaseCollection */
    private ?DatabaseCollection $languages;
    /** @var PropertyKey[]|DatabaseCollection */
    private $keys;

    public function run()
    {
        $this->propertyService = new PropertyService();

        $site = Site::where('slug', '=', 'default')->first();
        $this->languages = $site->languages()->get();  //Language::whereIn('iso_2', ['nl', 'en'])->get(['id', 'iso_2']);

        $this->productGroupBehaviors = ProductGroupBehaviour::all()->keyBy('name');
        $this->rootCategory = Category::where(['active' => '0', 'site_id' => null, 'code_name' => 'root'])->first();

        $this->ensurePropertyKeysExist(); //This normally is done in the PropertyKeySection via your browser.
        $this->laptopsCategory = $this->createLaptopsCategory();
        $products = $this->createMacbookProducts();
        $this->createMacbookGroup($products);
    }

    public function ensurePropertyKeysExist()
    {
        $keysData = [
            [
                'nl' => 'Kleur',
                'en' => 'Color',
                'de' => 'Farbe',
            ],
            [
                'nl' => 'Processor',
                'en' => 'Processor',
                'de' => 'Processor',
            ],
            [
                'nl' => 'Totale opslag capaciteit',
                'en' => 'Total storage capacity',
                'de' => 'Gesamtspeicherkapazität',
            ]
        ];

        /** @var PropertyKeyTranslation $keyTranslation */
        $propertyService = $this->propertyService;
        $languages = $this->languages;
        $this->keys = collect($keysData)->map(function ($keyData) use ($propertyService, $languages) {
            //Check if the propertyKey and al its
            $propertyKeyQuery = PropertyKey::whereHas('translations',
                function (Builder $query) use ($languages, $keyData) {
                    $first = true;
                    foreach ($keyData as $iso_2 => $translation) {
                        $language = $languages->where('iso_2', '=', $iso_2)->first();
                        if ($first) {
                            $query->where(function (Builder $query) use ($language, $iso_2, $translation) {
                                $query->where('language_id', '=', $language->id);
                                $query->where('name', '=', $translation);
                            });
                            $first = false;
                        } else {
                            $query->orWhere(function (Builder $query) use ($language, $iso_2, $translation) {
                                $query->where('language_id', '=', $language->id);
                                $query->where('name', '=', $translation);
                            });
                        }
                    }
                });

            $propertyKey = $propertyKeyQuery->first();

            if (!$propertyKey) {
                $propertyKey = new PropertyKey();
                $propertyKey->save();

                foreach ($keyData as $iso_2 => $translation) {
                    $language = $languages->where('iso_2', '=', $iso_2)->first();
                    $propertyKeyTranslation = new PropertyKeyTranslation();
                    $propertyKeyTranslation->language()->associate($language);
                    $propertyKeyTranslation->name = $translation;
                    $propertyKeyTranslation->translatable()->associate($propertyKey);
                    $propertyKeyTranslation->save();
                }
            }

            return $propertyKey;
        });
    }

    public function createLaptopsCategory()
    {
        $category = new Category();

        $category->code_name = 'laptops';
        $category->active = 1;
        $category->makeLastChildOf($this->rootCategory); //Also saves

        $category->requiredPropertyKeys()->saveMany($this->keys);

        $language = Language::where('iso_2', '=', 'nl')->first();
        if (!$language) {
            return null;
        }

        $translation = new CategoryTranslation();
        $translation->language()->associate($language);
        $translation->translatable()->associate($category);
        $translation->slug = Str::slug('Laptops');
        $translation->name = 'Laptops';
        $translation->meta_title = 'Laptops';
        $translation->save();

        return $category;
    }

    /**
     * @return RegularCollection
     */
    public function createMacbookProducts()
    {
        //From low spec to high spec. From grey to gold to silver.
        $products = collect();

        $product = new Product([
            'active' => '1',
            'price' => '111900',
            'vat_scenario_enum' => VatScenarioEnum::high_inc,
            'stock_keeping_unit' => 'EAN' . $this->eanNumberCounter++,
            'stock' => mt_rand(1, 100),
        ]);
        $product->save();


        $translations = $this->languages->map(function (Language $language) {
            $translation = new ProductTranslation([
                'name' => 'Apple Macbook Air (2020) MWTJ2N/A Space Gray',
                'slug' => Str::slug('Apple Macbook Air (2020) MWTJ2N/A Space Gray'),
            ]);

            $translation->language()->associate($language);
            return $translation;
        });
        $product->translation()->saveMany($translations);
        $product->categories()->save($this->laptopsCategory);
        $products->push($product);


        $product = new Product([
            'active' => '1',
            'price' => '124900',
            'vat_scenario_enum' => VatScenarioEnum::high_inc,
            'stock_keeping_unit' => 'EAN' . $this->eanNumberCounter++,
            'stock' => mt_rand(1, 100),
        ]);
        $product->save();


        $translations = $this->languages->map(function (Language $language) {
            $translation = new ProductTranslation([
                'name' => 'Apple MacBook Air (2020) 8/256GB 1,1GHz Space Gray',
                'slug' => Str::slug('Apple MacBook Air (2020) 8/256GB 1,1GHz Space Gray'),
            ]);

            $translation->language()->associate($language);
            return $translation;
        });
        $product->translation()->saveMany($translations);
        $product->categories()->save($this->laptopsCategory);
        $products->push($product);

        $product = new Product([
            'active' => '1',
            'price' => '137900',
            'vat_scenario_enum' => VatScenarioEnum::high_inc,
            'stock_keeping_unit' => 'EAN' . $this->eanNumberCounter++,
            'stock' => mt_rand(1, 100),
        ]);
        $product->save();


        $translations = $this->languages->map(function (Language $language) {
            $translation = new ProductTranslation([
                'name' => 'Apple Macbook Air (2020) MVH22N/A Space Gray',
                'slug' => Str::slug('Apple Macbook Air (2020) MVH22N/A Space Gray'),
            ]);
            $translation->language()->associate($language);
            return $translation;
        });
        $product->translation()->saveMany($translations);
        $product->categories()->save($this->laptopsCategory);
        $products->push($product);

        return $products;
    }

    /**
     * @param RegularCollection $productsToLink
     *
     * @return ProductGroup
     */
    public function createMacbookGroup(RegularCollection $productsToLink): ProductGroup
    {
        $productGroup = new ProductGroup([
            'active' => '1',
        ]);
        $productGroup->productGroupBehaviour()->associate($this->productGroupBehaviors->get('xor'));
        $productGroup->save();

        $translations = $this->languages->map(function (Language $language) {
            $translation = new ProductGroupTranslation([
                'name' => 'Apple Macbook Air (2020)',
                'slug' => Str::slug('Apple Macbook Air (2020)'),
            ]);
            $translation->language()->associate($language);
            return $translation;
        });
        $productGroup->translation()->saveMany($translations);
        $productGroup->categories()->save($this->laptopsCategory);
        $productGroup->products()->saveMany($productsToLink);
        $productGroup->filterPropertyKeys()->saveMany($this->keys);
        return $productGroup;
    }
}