<?php  namespace App\Models;  use Closure; use App\Traits\HasTags; use App\Traits\HasLikes; use App\Traits\HasStorage; use App\Contracts\HasMedia; use Illuminate\Support\Str; use App\Traits\HasDiscounts; use App\Traits\HasTranslations; use App\Observers\ProductObserver; use App\Contracts\DiscountableItem; use Illuminate\Support\Facades\Cache; use Illuminate\Database\Eloquent\Builder; use App\Http\Resources\ProductListResource; use App\Services\Orders\MathMoneyOperations; use Illuminate\Http\Resources\Json\JsonResource; use App\Contracts\ImportableSyncableItemInterface; use Illuminate\Database\Eloquent\Relations\HasOne; use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Database\Eloquent\Relations\BelongsTo;  /**  * @property string $price  */ class Product extends Model implements HasMedia, DiscountableItem, ImportableSyncableItemInterface { 	use HasTranslations, HasStorage, HasDiscounts, HasLikes, HasTags;  	public const REGULAR_PRODUCT = 1;  	public const VINE_HARVEST_INQUIRY = 1; 	public const PRODUCT_AVAILABILITY_INQUIRY = 2;  	public const STATUS_AVAILABLE = 1; 	public const STATUS_NOT_CURRENTLY_AVAILABLE = 2; 	public const STATUS_UNAVAILABLE = 3;  	public const DYNAMIC_PIKTOGRAM_DISCOUNT = 15; // automatically applied if product currently has discount applied)  	public const PIKTOGRAMS = [ 		1 => 'OVCA', 		2 => 'KRAVA', 		3 => 'KOZA', 		//	4 => 'KRAVA/OVCA', 		// 5 => 'KRAVA/KOZA', 		// 6 => 'KRAVA/OVCA/KOZA', 		// 7 => 'OVCA/KOZA', 		8 => 'GMO-FREE', 		9 => 'BIO', 		10 => 'LACTOSE-FREE', 		11 => 'VEGAN', 		12 => 'VEGETARIAN', 		//	13 => 'BESPLATNA DOSTAVA', 		14 => 'NOVO', 		16 => 'PDO', 		17 => 'PGI', 		18 => 'EXPIRATION', 		19 => 'PRASCIC',  	];  	public const MEASURE_UNITS = [ 		1 => 'KG', 		2 => 'KOM', 	];  	public const ALTERNATIVE_MEASURE_UNITS = [ 		1 => 'KG', 		2 => 'L', 		3 => 'G', 	];  	public const STOCK_STORE_CODE = '011';  	protected $casts = [ 		'active' => 'boolean', 		'gratis' => 'boolean', 		'piktograms' => 'array', 		'unavailable' => 'boolean', 		'unit_of_measure' => 'integer', 		'type' => 'integer', 		'sort_number' => 'integer', 		'is_free_after_certain_quantity' => 'boolean', 		'sync_stock' => 'boolean', 	];  	public function mediaConfig(): array{}  	public function productCategories(): HasMany{}  	public function productFilters(): HasMany{}  	public function discountOrderItem(): HasOne{}  	public function scopeIncludes(object $query, ?string $lang = null): Builder{}  	public function saveFilterValues(?array $filters = []): self{}  	public function scopeSearch(Builder $query, ?string $search = null, ?string $lang = null): Builder{}  	public function scopefindByTag(Builder $query, string $tag_id, ?string $lang = null): Builder{}  	public function setNameAttribute(?string $value): void{}  	public static function generateSlug(string $productTitle): string 	{ 		$original_slug = strtolower(Str::slug($productTitle));  		if (self::where('slug', $original_slug)->exists()) { 			// Add UUID chunk to the end, untill it does not exist 			// if this chunk exists with this ID, try another chunk (won't happen but could happen) 			do { 				$uuid_chunk = explode('-', Str::uuid())[0]; 				$slug = $original_slug . '-' . $uuid_chunk; 			} while (self::where('slug', $slug)->exists()); 			$original_slug = $slug; 		}  		return $original_slug; 	}  	public function scopeUpsell(Builder $query, string $id): Builder{}  	public function scopeAdultOnly(Builder $query, ?bool $adultOnly = null): Builder{}  	public function fetchPiktograms(?Discount $on_discount = null): array|null{}  	public function variants(): HasMany{}  	public static function getMeasureUnites(): array 	{ 		return self::MEASURE_UNITS; 	}  	public static function getAlternativeMeasureUnites(): array 	{ 		return self::ALTERNATIVE_MEASURE_UNITS; 	}  	public function availabilityStatus(): int{}  	public function getCurrentlyApplicableDiscount(): Discount|null{}  	public function applyDiscount(?Discount $discount = null): ?string{}  	public function applyDiscountForPricePerUnitOfMeasure(?Discount $discount = null): ?string{}  	public function reviews(): HasMany{}  	public function getSecondPrice(?string $startingPrice): ?string{}  	public function getVatRate(string $countryCode = 'HR'): int|float{}  	public function scopeDynamicFilters(Builder $query, string $lang, ?array $filters = []): Builder{}  	public function scopeDynamicFilter(Builder $query, string $filter_id, array $values, string $lang): Builder{}  	public function saveFilterTranslations(string $lang = 'en', ?array $filters = [], ?array $filters_en = []): self{}  	public function getCode(): string{}  	public function isDiscountCodeApplicable(Discount $discount): bool{}  	public function scopeFilterPriceRange(Builder $query, ?int $price_min = null, ?int $price_max = null): Builder{}  	public function scopeUnderActiveDiscount(Builder $query, ?string $discountId = null): Builder{}  	public function getCategoriesId(): array{}  	public function lowestPriceInLastMonth(): string{}  	public function currentlyActiveDiscount(): BelongsTo{}  	public function canBeFree(): bool{}  	public function prices(): HasMany{}  	public function hasVatSet(): bool{}  	public function syncTagsByName(string|array|null $tags = null, ?Closure $closure = null): self{}  	public function scopeAvailableForTags(Builder $query): Builder{}  	public function shouldUpdateStock(): bool{}  	public function scopeAvailable(Builder $query): Builder{}  	public function getDiscount(): ?Discount{}  	public function getOrderItemName(): string{}  	public function requiresPricePerKg(): bool{}  	public function getResource(): JsonResource{}  	public function scopeMainPage(Builder $query): Builder{}  	public function orderItems(): HasMany{}  	public function reviewsCount(): int{}  	public function slugTranslationUpdateHandle(?string $name): ?string{}  	protected static function initObservers(): ?string 	{ 		return ProductObserver::class; 	} }