command: sed -n '1,320p' app/Livewire/Admin/Discounts/Form.php

aggregated_output:
<?php

namespace App\Livewire\Admin\Discounts;

use App\Enums\DiscountStatus;
use App\Enums\DiscountType;
use App\Enums\DiscountValueType;
use App\Models\Collection as ProductCollection;
use App\Models\Discount;
use App\Models\Product;
use App\Models\Store;
use App\Support\Money;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Support\Collection as SupportCollection;
use Illuminate\Support\Str;
use Illuminate\Validation\Rule;
use Livewire\Component;

class Form extends Component
{
    use AuthorizesRequests;

    public ?Discount $discount = null;

    public string $type = 'code';

    public string $code = '';

    public string $valueType = 'percent';

    public string $valueAmount = '10';

    public string $minimumPurchaseAmount = '';

    /**
     * @var array<int, int>
     */
    public array $specificProductIds = [];

    /**
     * @var array<int, int>
     */
    public array $specificCollectionIds = [];

    public string $usageLimit = '';

    public bool $onePerCustomer = false;

    public string $startsAt = '';

    public string $endsAt = '';

    public bool $isActive = false;

    public string $productSearch = '';

    public string $collectionSearch = '';

    public string $storeCurrency = 'EUR';

    public function mount(?Discount $discount = null): void
    {
        $store = app('current_store');

        abort_unless($store instanceof Store, 404);

        $this->storeCurrency = $store->default_currency;

        if ($discount?->exists) {
            abort_unless((int) $discount->store_id === $store->getKey(), 404);

            $this->authorize('update', $discount);

            $this->discount = $discount;
            $this->fillFromDiscount($discount);

            return;
        }

        $this->authorize('create', Discount::class);

        $this->startsAt = now()->format('Y-m-d\TH:i');
    }

    public function save(): void
    {
        $store = app('current_store');

        abort_unless($store instanceof Store, 404);

        $this->authorizeSave();
        $this->normalizeCode();

        $this->validate([
            'type' => ['required', Rule::in(['code', 'automatic'])],
            'code' => [
                Rule::requiredIf($this->type === 'code'),
                'nullable',
                'string',
                'max:255',
                function (string $attribute, mixed $value, \Closure $fail) use ($store): void {
                    if ($value === null || trim((string) $value) === '') {
                        return;
                    }

                    $exists = Discount::withoutGlobalScopes()
                        ->where('store_id', $store->getKey())
                        ->whereRaw('lower(code) = ?', [Str::lower(trim((string) $value))])
                        ->when($this->discount instanceof Discount, fn ($query) => $query->where('id', '!=', $this->discount?->getKey()))
                        ->exists();

                    if ($exists) {
                        $fail(__('The discount code has already been taken.'));
                    }
                },
            ],
            'valueType' => ['required', Rule::in(['percent', 'fixed', 'free_shipping'])],
            'valueAmount' => $this->valueAmountRules(),
            'minimumPurchaseAmount' => ['nullable', 'numeric', 'min:0'],
            'usageLimit' => ['nullable', 'integer', 'min:1'],
            'startsAt' => ['required', 'date'],
            'endsAt' => ['nullable', 'date', 'after:startsAt'],
            'onePerCustomer' => ['boolean'],
            'isActive' => ['boolean'],
        ], [], [
            'valueAmount' => 'value amount',
        ]);

        $discount = $this->discount instanceof Discount
            ? tap($this->discount)->update($this->payload($store))
            : Discount::withoutGlobalScopes()->create($this->payload($store));

        $this->discount = $discount->refresh();
        $this->fillFromDiscount($this->discount);

        session()->flash('status', 'Discount saved');
        $this->dispatch('toast', type: 'success', message: __('Discount saved'));
    }

    public function generateCode(): void
    {
        do {
            $code = Str::upper(Str::random(8));
        } while (Discount::withoutGlobalScopes()
            ->where('store_id', $this->storeId())
            ->where('code', $code)
            ->exists());

        $this->code = $code;
    }

    public function addProduct(int $productId): void
    {
        abort_unless($this->productBelongsToStore($productId), 404);

        $this->specificProductIds = collect([...$this->specificProductIds, $productId])
            ->unique()
            ->values()
            ->all();
        $this->productSearch = '';
    }

    public function removeProduct(int $productId): void
    {
        $this->specificProductIds = array_values(array_filter(
            $this->specificProductIds,
            fn (int $selectedProductId): bool => $selectedProductId !== $productId…775 chars truncated…       return collect();
        }

        return Product::withoutGlobalScopes()
            ->where('store_id', $this->storeId())
            ->whereNotIn('id', $this->specificProductIds)
            ->where('title', 'like', '%'.$this->productSearch.'%')
            ->orderBy('title')
            ->limit(5)
            ->get();
    }

    public function collectionResults(): SupportCollection
    {
        if (trim($this->collectionSearch) === '') {
            return collect();
        }

        return ProductCollection::withoutGlobalScopes()
            ->where('store_id', $this->storeId())
            ->whereNotIn('id', $this->specificCollectionIds)
            ->where('title', 'like', '%'.$this->collectionSearch.'%')
            ->orderBy('title')
            ->limit(5)
            ->get();
    }

    public function selectedProducts(): SupportCollection
    {
        return Product::withoutGlobalScopes()
            ->where('store_id', $this->storeId())
            ->whereKey($this->specificProductIds)
            ->orderBy('title')
            ->get();
    }

    public function selectedCollections(): SupportCollection
    {
        return ProductCollection::withoutGlobalScopes()
            ->where('store_id', $this->storeId())
            ->whereKey($this->specificCollectionIds)
            ->orderBy('title')
            ->get();
    }

    public function render(): mixed
    {
        return view('livewire.admin.discounts.form', [
            'isEditing' => $this->discount instanceof Discount,
            'productResults' => $this->productResults(),
            'collectionResults' => $this->collectionResults(),
            'selectedProducts' => $this->selectedProducts(),
            'selectedCollections' => $this->selectedCollections(),
        ])->layout('layouts.app', [
            'title' => $this->discount ? __('Edit discount') : __('Create discount'),
        ]);
    }

    private function fillFromDiscount(Discount $discount): void
    {
        $this->type = $discount->type->value;
        $this->code = (string) $discount->code;
        $this->valueType = $discount->value_type->value;
        $this->valueAmount = $discount->value_type === DiscountValueType::Fixed
            ? number_format($discount->value_amount / 100, 2, '.', '')
            : (string) $discount->value_amount;
        $this->minimumPurchaseAmount = data_get($discount->rules_json, 'min_purchase_amount')
            ? number_format(((int) data_get($discount->rules_json, 'min_purchase_amount')) / 100, 2, '.', '')
            : '';
        $this->specificProductIds = collect(data_get($discount->rules_json, 'applicable_product_ids', []))
            ->map(fn (mixed $id): int => (int) $id)
            ->all();
        $this->specificCollectionIds = collect(data_get($discount->rules_json, 'applicable_collection_ids', []))
            ->map(fn (mixed $id): int => (int) $id)
            ->all();
        $this->usageLimit = $discount->usage_limit !== null ? (string) $discount->usage_limit : '';
        $this->onePerCustomer = (bool) data_get($discount->rules_json, 'one_per_customer', false);
        $this->startsAt = $discount->starts_at->format('Y-m-d\TH:i');
        $this->endsAt = $discount->ends_at?->format('Y-m-d\TH:i') ?? '';
        $this->isActive = $discount->status === DiscountStatus::Active;
    }

    /**
     * @return array<string, mixed>
     */
    private function payload(Store $store): array
    {
        return [
            'store_id' => $store->getKey(),
            'type' => DiscountType::from($this->type),
            'code' => $this->type === 'code' ? Str::upper(trim($this->code)) : null,
            'value_type' => DiscountValueType::from($this->valueType),
            'value_amount' => $this->normalizedValueAmount(),
            'starts_at' => $this->startsAt,
            'ends_at' => $this->endsAt !== '' ? $this->endsAt : null,
            'usage_limit' => $this->usageLimit !== '' ? (int) $this->usageLimit : null,
            'rules_json' => $this->rulesPayload(),
            'status' => $this->statusForPayload(),
        ];
    }

    /**
     * @return array<string, mixed>
     */
    private function rulesPayload(): array
    {
        return [
            'min_purchase_amount' => $this->minimumPurchaseAmount !== '' ? Money::fromDecimalString($this->minimumPurchaseAmount) : 0,
            'applicable_product_ids' => $this->validProductIds(),
            'applicable_collection_ids' => $this->validCollectionIds(),
            'one_per_customer' => $this->onePerCustomer,
            'customer_eligibility' => 'all',
        ];
    }

    private function normalizedValueAmount(): int
    {
        return match ($this->valueType) {
            'fixed' => Money::fromDecimalString($this->valueAmount),
            'free_shipping' => 0,
            default => (int) round((float) $this->valueAmount),
        };
    }

    /**
     * @return array<int, int>
     */
    private function validProductIds(): array


output:
Chunk ID: b294c3
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 2694
Output:
<?php

namespace App\Livewire\Admin\Discounts;

use App\Enums\DiscountStatus;
use App\Enums\DiscountType;
use App\Enums\DiscountValueType;
use App\Models\Collection as ProductCollection;
use App\Models\Discount;
use App\Models\Product;
use App\Models\Store;
use App\Support\Money;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Support\Collection as SupportCollection;
use Illuminate\Support\Str;
use Illuminate\Validation\Rule;
use Livewire\Component;

class Form extends Component
{
    use AuthorizesRequests;

    public ?Discount $discount = null;

    public string $type = 'code';

    public string $code = '';

    public string $valueType = 'percent';

    public string $valueAmount = '10';

    public string $minimumPurchaseAmount = '';

    /**
     * @var array<int, int>
     */
    public array $specificProductIds = [];

    /**
     * @var array<int, int>
     */
    public array $specificCollectionIds = [];

    public string $usageLimit = '';

    public bool $onePerCustomer = false;

    public string $startsAt = '';

    public string $endsAt = '';

    public bool $isActive = false;

    public string $productSearch = '';

    public string $collectionSearch = '';

    public string $storeCurrency = 'EUR';

    public function mount(?Discount $discount = null): void
    {
        $store = app('current_store');

        abort_unless($store instanceof Store, 404);

        $this->storeCurrency = $store->default_currency;

        if ($discount?->exists) {
            abort_unless((int) $discount->store_id === $store->getKey(), 404);

            $this->authorize('update', $discount);

            $this->discount = $discount;
            $this->fillFromDiscount($discount);

            return;
        }

        $this->authorize('create', Discount::class);

        $this->startsAt = now()->format('Y-m-d\TH:i');
    }

    public function save(): void
    {
        $store = app('current_store');

        abort_unless($store instanceof Store, 404);

        $this->authorizeSave();
        $this->normalizeCode();

        $this->validate([
            'type' => ['required', Rule::in(['code', 'automatic'])],
            'code' => [
                Rule::requiredIf($this->type === 'code'),
                'nullable',
                'string',
                'max:255',
                function (string $attribute, mixed $value, \Closure $fail) use ($store): void {
                    if ($value === null || trim((string) $value) === '') {
                        return;
                    }

                    $exists = Discount::withoutGlobalScopes()
                        ->where('store_id', $store->getKey())
                        ->whereRaw('lower(code) = ?', [Str::lower(trim((string) $value))])
                        ->when($this->discount instanceof Discount, fn ($query) => $query->where('id', '!=', $this->discount?->getKey()))
                        ->exists();

                    if ($exists) {
                        $fail(__('The discount code has already been taken.'));
                    }
                },
            ],
            'valueType' => ['required', Rule::in(['percent', 'fixed', 'free_shipping'])],
            'valueAmount' => $this->valueAmountRules(),
            'minimumPurchaseAmount' => ['nullable', 'numeric', 'min:0'],
            'usageLimit' => ['nullable', 'integer', 'min:1'],
            'startsAt' => ['required', 'date'],
            'endsAt' => ['nullable', 'date', 'after:startsAt'],
            'onePerCustomer' => ['boolean'],
            'isActive' => ['boolean'],
        ], [], [
            'valueAmount' => 'value amount',
        ]);

        $discount = $this->discount instanceof Discount
            ? tap($this->discount)->update($this->payload($store))
            : Discount::withoutGlobalScopes()->create($this->payload($store));

        $this->discount = $discount->refresh();
        $this->fillFromDiscount($this->discount);

        session()->flash('status', 'Discount saved');
        $this->dispatch('toast', type: 'success', message: __('Discount saved'));
    }

    public function generateCode(): void
    {
        do {
            $code = Str::upper(Str::random(8));
        } while (Discount::withoutGlobalScopes()
            ->where('store_id', $this->storeId())
            ->where('code', $code)
            ->exists());

        $this->code = $code;
    }

    public function addProduct(int $productId): void
    {
        abort_unless($this->productBelongsToStore($productId), 404);

        $this->specificProductIds = collect([...$this->specificProductIds, $productId])
            ->unique()
            ->values()
            ->all();
        $this->productSearch = '';
    }

    public function removeProduct(int $productId): void
    {
        $this->specificProductIds = array_values(array_filter(
            $this->specificProductIds,
            fn (int $selectedProductId): bool => $selectedProductId !== $productId,
        ));
    }

    public function addCollection(int $collectionId): void
    {
        abort_unless($this->collectionBelongsToStore($collectionId), 404);

        $this->specificCollectionIds = collect([...$this->specificCollectionIds, $collectionId])
            ->unique()
            ->values()
            ->all();
        $this->collectionSearch = '';
    }

    public function removeCollection(int $collectionId): void
    {
        $this->specificCollectionIds = array_values(array_filter(
            $this->specificCollectionIds,
            fn (int $selectedCollectionId): bool => $selectedCollectionId !== $collectionId,
        ));
    }

    public function productResults(): SupportCollection
    {
        if (trim($this->productSearch) === '') {
            return collect();
        }

        return Product::withoutGlobalScopes()
            ->where('store_id', $this->storeId())
            ->whereNotIn('id', $this->specificProductIds)
            ->where('title', 'like', '%'.$this->productSearch.'%')
            ->orderBy('title')
            ->limit(5)
            ->get();
    }

    public function collectionResults(): SupportCollection
    {
        if (trim($this->collectionSearch) === '') {
            return collect();
        }

        return ProductCollection::withoutGlobalScopes()
            ->where('store_id', $this->storeId())
            ->whereNotIn('id', $this->specificCollectionIds)
            ->where('title', 'like', '%'.$this->collectionSearch.'%')
            ->orderBy('title')
            ->limit(5)
            ->get();
    }

    public function selectedProducts(): SupportCollection
    {
        return Product::withoutGlobalScopes()
            ->where('store_id', $this->storeId())
            ->whereKey($this->specificProductIds)
            ->orderBy('title')
            ->get();
    }

    public function selectedCollections(): SupportCollection
    {
        return ProductCollection::withoutGlobalScopes()
            ->where('store_id', $this->storeId())
            ->whereKey($this->specificCollectionIds)
            ->orderBy('title')
            ->get();
    }

    public function render(): mixed
    {
        return view('livewire.admin.discounts.form', [
            'isEditing' => $this->discount instanceof Discount,
            'productResults' => $this->productResults(),
            'collectionResults' => $this->collectionResults(),
            'selectedProducts' => $this->selectedProducts(),
            'selectedCollections' => $this->selectedCollections(),
        ])->layout('layouts.app', [
            'title' => $this->discount ? __('Edit discount') : __('Create discount'),
        ]);
    }

    private function fillFromDiscount(Discount $discount): void
    {
        $this->type = $discount->type->value;
        $this->code = (string) $discount->code;
        $this->valueType = $discount->value_type->value;
        $this->valueAmount = $discount->value_type === DiscountValueType::Fixed
            ? number_format($discount->value_amount / 100, 2, '.', '')
            : (string) $discount->value_amount;
        $this->minimumPurchaseAmount = data_get($discount->rules_json, 'min_purchase_amount')
            ? number_format(((int) data_get($discount->rules_json, 'min_purchase_amount')) / 100, 2, '.', '')
            : '';
        $this->specificProductIds = collect(data_get($discount->rules_json, 'applicable_product_ids', []))
            ->map(fn (mixed $id): int => (int) $id)
            ->all();
        $this->specificCollectionIds = collect(data_get($discount->rules_json, 'applicable_collection_ids', []))
            ->map(fn (mixed $id): int => (int) $id)
            ->all();
        $this->usageLimit = $discount->usage_limit !== null ? (string) $discount->usage_limit : '';
        $this->onePerCustomer = (bool) data_get($discount->rules_json, 'one_per_customer', false);
        $this->startsAt = $discount->starts_at->format('Y-m-d\TH:i');
        $this->endsAt = $discount->ends_at?->format('Y-m-d\TH:i') ?? '';
        $this->isActive = $discount->status === DiscountStatus::Active;
    }

    /**
     * @return array<string, mixed>
     */
    private function payload(Store $store): array
    {
        return [
            'store_id' => $store->getKey(),
            'type' => DiscountType::from($this->type),
            'code' => $this->type === 'code' ? Str::upper(trim($this->code)) : null,
            'value_type' => DiscountValueType::from($this->valueType),
            'value_amount' => $this->normalizedValueAmount(),
            'starts_at' => $this->startsAt,
            'ends_at' => $this->endsAt !== '' ? $this->endsAt : null,
            'usage_limit' => $this->usageLimit !== '' ? (int) $this->usageLimit : null,
            'rules_json' => $this->rulesPayload(),
            'status' => $this->statusForPayload(),
        ];
    }

    /**
     * @return array<string, mixed>
     */
    private function rulesPayload(): array
    {
        return [
            'min_purchase_amount' => $this->minimumPurchaseAmount !== '' ? Money::fromDecimalString($this->minimumPurchaseAmount) : 0,
            'applicable_product_ids' => $this->validProductIds(),
            'applicable_collection_ids' => $this->validCollectionIds(),
            'one_per_customer' => $this->onePerCustomer,
            'customer_eligibility' => 'all',
        ];
    }

    private function normalizedValueAmount(): int
    {
        return match ($this->valueType) {
            'fixed' => Money::fromDecimalString($this->valueAmount),
            'free_shipping' => 0,
            default => (int) round((float) $this->valueAmount),
        };
    }

    /**
     * @return array<int, int>
     */
    private function validProductIds(): array


output:
Chunk ID: 71a48e
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 1124
Output:
<?php

namespace App\Livewire\Admin\Discounts;

use App\Enums\DiscountStatus;
use App\Enums\DiscountValueType;
use App\Models\Discount;
use App\Models\Store;
use App\Support\Money;
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Livewire\Attributes\Locked;
use Livewire\Component;
use Livewire\WithPagination;

class Index extends Component
{
    use AuthorizesRequests;
    use WithPagination;

    #[Locked]
    public int $storeId;

    public string $storeCurrency = 'EUR';

    public string $search = '';

    public string $statusFilter = 'all';

    public string $typeFilter = 'all';

    public function mount(): void
    {
        $store = app('current_store');

        abort_unless($store instanceof Store, 404);

        $this->authorize('viewAny', Discount::class);

        $this->storeId = $store->getKey();
        $this->storeCurrency = $store->default_currency;
    }

    public function updatedSearch(): void
    {
        $this->resetPage();
    }

    public function updatedStatusFilter(): void
    {
        $this->resetPage();
    }

    public function updatedTypeFilter(): void
    {
        $this->resetPage();
    }

    public function discounts(): LengthAwarePaginator
    {
        return Discount::withoutGlobalScopes()
            ->where('store_id', $this->storeId)
            ->when($this->search !== '', function (Builder $query): void {
                $search = '%'.$this->search.'%';

                $query->where(function (Builder $query) use ($search): void {
                    $query
                        ->where('code', 'like', $search)
                        ->orWhere('type', 'like', $search);
                });
            })
            ->when($this->statusFilter !== 'all', fn (Builder $query) => $this->applyStatusFilter($query))
            ->when($this->typeFilter !== 'all', fn (Builder $query) => $query->where('type', $this->typeFilter))
            ->latest('starts_at')
            ->latest('id')
            ->paginate(20);
    }

    public function valueLabel(Discount $discount): string
    {
        return match ($discount->value_type) {
            DiscountValueType::Percent => $discount->value_amount.'%',
            DiscountValueType::Fixed => Money::format($discount->value_amount, $this->storeCurrency),
            DiscountValueType::FreeShipping => 'Free shipping',
        };
    }

    public function effectiveStatus(Discount $discount): string
    {
        if ($discount->status === DiscountStatus::Disabled) {
            return 'disabled';
        }

        if ($discount->starts_at->isFuture()) {
            return 'scheduled';
        }

        if ($discount->status === DiscountStatus::Expired || ($discount->ends_at !== null && $discount->ends_at->isPast())) {
            return 'expired';
        }

        return $discount->status->value;
    }

    public function statusColor(string $status): string
    {
        return match ($status) {
            'active' => 'green',
            'expired' => 'red',
            'scheduled' => 'amber',
            default => 'zinc',
        };
    }

    public function render(): mixed
    {
        return view('livewire.admin.discounts.index', [
            'discounts' => $this->discounts(),
        ])->layout('layouts.app', [
            'title' => __('Discounts'),
        ]);
    }

    private function applyStatusFilter(Builder $query): void
    {
        match ($this->statusFilter) {
            'active' => $query
                ->where('status', DiscountStatus::Active->value)
                ->where('starts_at', '<=', now())
                ->where(function (Builder $query): void {
                    $query->whereNull('ends_at')->orWhere('ends_at', '>=', now());
                }),
            'expired' => $query->where(function (Builder $query): void {
                $query
                    ->where('status', DiscountStatus::Expired->value)
                    ->orWhere(function (Builder $query): void {
                        $query
                            ->where('status', DiscountStatus::Active->value)
                            ->where('ends_at', '<', now());
                    });
            }),
            'scheduled' => $query
                ->where('status', DiscountStatus::Active->value)
                ->where('starts_at', '>', now()),
            default => null,
        };
    }
}


command: sed -n '1,280p' database/seeders/DiscountSeeder.php

DiscountSeeder.php

type: read

aggregated_output:
<?php

namespace Database\Seeders;

use App\Models\Discount;
use App\Models\Store;
use Illuminate\Database\Seeder;

class DiscountSeeder extends Seeder
{
    /**
     * Run the database seeds.
     */
    public function run(): void
    {
        Store::query()->get()->each(function (Store $store): void {
            foreach ($this->discounts() as $discount) {
                Discount::withoutGlobalScopes()->updateOrCreate(
                    [
                        'store_id' => $store->getKey(),
                        'code' => $discount['code'],
                    ],
                    [
                        'type' => 'code',
                        'value_type' => $discount['value_type'],
                        'value_amount' => $discount['value_amount'],
                        'starts_at' => $discount['starts_at'] ?? now()->subDay(),
                        'ends_at' => $discount['ends_at'] ?? now()->addMonth(),
                        'usage_limit' => $discount['usage_limit'] ?? null,
                        'usage_count' => $discount['usage_count'] ?? 0,
                        'rules_json' => $discount['rules_json'],
                        'status' => $discount['status'] ?? 'active',
                    ],
                );
            }
        });
    }

    /**
     * @return array<int, array{code: string, value_type: string, value_amount: int, rules_json: array<string, mixed>, starts_at?: \Illuminate\Support\Carbon, ends_at?: \Illuminate\Support\Carbon, usage_limit?: int|null, usage_count?: int, status?: string}>
     */
    private function discounts(): array
    {
        return [
            ['code' => 'WELCOME10', 'value_type' => 'percent', 'value_amount' => 10, 'usage_count' => 3, 'rules_json' => ['min_purchase_amount' => 2000]],
            ['code' => 'FLAT5', 'value_type' => 'fixed', 'value_amount' => 500, 'rules_json' => []],
            ['code' => 'SAVE10', 'value_type' => 'percent', 'value_amount' => 10, 'rules_json' => ['customer_eligibility' => 'all']],
            ['code' => '5OFF', 'value_type' => 'fixed', 'value_amount' => 500, 'rules_json' => ['min_purchase_amount' => 2500, 'customer_eligibility' => 'all']],
            ['code' => 'FREESHIP', 'value_type' => 'free_shipping', 'value_amount' => 0, 'rules_json' => ['customer_eligibility' => 'all']],
            ['code' => 'EXPIRED20', 'value_type' => 'percent', 'value_amount' => 20, 'ends_at' => now()->subDay(), 'rules_json' => [], 'status' => 'expired'],
            ['code' => 'MAXED', 'value_type' => 'percent', 'value_amount' => 10, 'usage_limit' => 5, 'usage_count' => 5, 'rules_json' => []],
        ];
    }
}

status: completed


command: sed -n '1,260p' database/factories/DiscountFactory.php

DiscountFactory.php

aggregated_output:
<?php

namespace Database\Factories;

use App\Enums\DiscountStatus;
use App\Enums\DiscountType;
use App\Enums\DiscountValueType;
use App\Models\Store;
use Illuminate\Database\Eloquent\Factories\Factory;

/**
 * @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\Discount>
 */
class DiscountFactory extends Factory
{
    /**
     * Define the model's default state.
     *
     * @return array<string, mixed>
     */
    public function definition(): array
    {
        return [
            'store_id' => Store::factory(),
            'type' => DiscountType::Code,
            'code' => fake()->unique()->bothify('SAVE##'),
            'value_type' => DiscountValueType::Percent,
            'value_amount' => 10,
            'starts_at' => now()->subDay(),
            'ends_at' => now()->addMonth(),
            'usage_limit' => null,
            'usage_count' => 0,
            'rules_json' => ['customer_eligibility' => 'all'],
            'status' => DiscountStatus::Active,
        ];
    }

    public function fixed(int $amount = 500): static
    {
        return $this->state(fn (array $attributes): array => [
            'value_type' => DiscountValueType::Fixed,
            'value_amount' => $amount,
        ]);
    }

    public function freeShipping(): static
    {
        return $this->state(fn (array $attributes): array => [
            'value_type' => DiscountValueType::FreeShipping,
            'value_amount' => 0,
        ]);
    }
}


output:
Chunk ID: 619bdc
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 369
Output:
<?php

namespace Database\Factories;

use App\Enums\DiscountStatus;
use App\Enums\DiscountType;
use App\Enums\DiscountValueType;
use App\Models\Store;
use Illuminate\Database\Eloquent\Factories\Factory;

/**
 * @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\Discount>
 */
class DiscountFactory extends Factory
{
    /**
     * Define the model's default state.
     *
     * @return array<string, mixed>
     */
    public function definition(): array
    {
        return [
            'store_id' => Store::factory(),
            'type' => DiscountType::Code,
            'code' => fake()->unique()->bothify('SAVE##'),
            'value_type' => DiscountValueType::Percent,
            'value_amount' => 10,
            'starts_at' => now()->subDay(),
            'ends_at' => now()->addMonth(),
            'usage_limit' => null,
            'usage_count' => 0,
            'rules_json' => ['customer_eligibility' => 'all'],
            'status' => DiscountStatus::Active,
        ];
    }

    public function fixed(int $amount = 500): static
    {
        return $this->state(fn (array $attributes): array => [
            'value_type' => DiscountValueType::Fixed,
            'value_amount' => $amount,
        ]);
    }

    public function freeShipping(): static
    {
        return $this->state(fn (array $attributes): array => [
            'value_type' => DiscountValueType::FreeShipping,
            'value_amount' => 0,
        ]);
    }
}


output:
Chunk ID: 8feb17
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 662
Output:
<?php

namespace Database\Seeders;

use App\Models\Discount;
use App\Models\Store;
use Illuminate\Database\Seeder;

class DiscountSeeder extends Seeder
{
    /**
     * Run the database seeds.
     */
    public function run(): void
    {
        Store::query()->get()->each(function (Store $store): void {
            foreach ($this->discounts() as $discount) {
                Discount::withoutGlobalScopes()->updateOrCreate(
                    [
                        'store_id' => $store->getKey(),
                        'code' => $discount['code'],
                    ],
                    [
                        'type' => 'code',
                        'value_type' => $discount['value_type'],
                        'value_amount' => $discount['value_amount'],
                        'starts_at' => $discount['starts_at'] ?? now()->subDay(),
                        'ends_at' => $discount['ends_at'] ?? now()->addMonth(),
                        'usage_limit' => $discount['usage_limit'] ?? null,
                        'usage_count' => $discount['usage_count'] ?? 0,
                        'rules_json' => $discount['rules_json'],
                        'status' => $discount['status'] ?? 'active',
                    ],
                );
            }
        });
    }

    /**
     * @return array<int, array{code: string, value_type: string, value_amount: int, rules_json: array<string, mixed>, starts_at?: \Illuminate\Support\Carbon, ends_at?: \Illuminate\Support\Carbon, usage_limit?: int|null, usage_count?: int, status?: string}>
     */
    private function discounts(): array
    {
        return [
            ['code' => 'WELCOME10', 'value_type' => 'percent', 'value_amount' => 10, 'usage_count' => 3, 'rules_json' => ['min_purchase_amount' => 2000]],
            ['code' => 'FLAT5', 'value_type' => 'fixed', 'value_amount' => 500, 'rules_json' => []],
            ['code' => 'SAVE10', 'value_type' => 'percent', 'value_amount' => 10, 'rules_json' => ['customer_eligibility' => 'all']],
            ['code' => '5OFF', 'value_type' => 'fixed', 'value_amount' => 500, 'rules_json' => ['min_purchase_amount' => 2500, 'customer_eligibility' => 'all']],
            ['code' => 'FREESHIP', 'value_type' => 'free_shipping', 'value_amount' => 0, 'rules_json' => ['customer_eligibility' => 'all']],
            ['code' => 'EXPIRED20', 'value_type' => 'percent', 'value_amount' => 20, 'ends_at' => now()->subDay(), 'rules_json' => [], 'status' => 'expired'],
            ['code' => 'MAXED', 'value_type' => 'percent', 'value_amount' => 10, 'usage_limit' => 5, 'usage_count' => 5, 'rules_json' => []],
        ];
    }
}


cmd: sed -n '320,640p' app/Livewire/Admin/Discounts/Form.php


command: sed -n '320,640p' app/Livewire/Admin/Discounts/Form.php

aggregated_output:
    private function validProductIds(): array
    {
        return Product::withoutGlobalScopes()
            ->where('store_id', $this->storeId())
            ->whereKey($this->specificProductIds)
            ->pluck('id')
            ->map(fn (int $id): int => $id)
            ->all();
    }

    /**
     * @return array<int, int>
     */
    private function validCollectionIds(): array
    {
        return ProductCollection::withoutGlobalScopes()
            ->where('store_id', $this->storeId())
            ->whereKey($this->specificCollectionIds)
            ->pluck('id')
            ->map(fn (int $id): int => $id)
            ->all();
    }

    private function productBelongsToStore(int $productId): bool
    {
        return Product::withoutGlobalScopes()
            ->where('store_id', $this->storeId())
            ->whereKey($productId)
            ->exists();
    }

    private function collectionBelongsToStore(int $collectionId): bool
    {
        return ProductCollection::withoutGlobalScopes()
            ->where('store_id', $this->storeId())
            ->whereKey($collectionId)
            ->exists();
    }

    private function storeId(): int
    {
        $store = app('current_store');

        abort_unless($store instanceof Store, 404);

        return $store->getKey();
    }

    private function authorizeSave(): void
    {
        if ($this->discount instanceof Discount) {
            $this->authorize('update', $this->discount);

            return;
        }

        $this->authorize('create', Discount::class);
    }

    private function normalizeCode(): void
    {
        if ($this->type !== DiscountType::Code->value) {
            $this->code = '';

            return;
        }

        $this->code = Str::upper(trim($this->code));
    }

    /**
     * @return list<mixed>
     */
    private function valueAmountRules(): array
    {
        return match ($this->valueType) {
            DiscountValueType::Percent->value => ['required', 'integer', 'min:1', 'max:100'],
            DiscountValueType::FreeShipping->value => ['nullable'],
            default => ['required', 'numeric', 'min:0.01'],
        };
    }

    private function statusForPayload(): DiscountStatus
    {
        if ($this->discount?->status === DiscountStatus::Expired) {
            return DiscountStatus::Expired;
        }

        if ($this->isActive) {
            return DiscountStatus::Active;
        }

        if ($this->discount?->status === DiscountStatus::Draft || ! $this->discount instanceof Discount) {
            return DiscountStatus::Draft;
        }

        return DiscountStatus::Disabled;
    }
}


output:
Chunk ID: 1a6306
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 663
Output:
    private function validProductIds(): array
    {
        return Product::withoutGlobalScopes()
            ->where('store_id', $this->storeId())
            ->whereKey($this->specificProductIds)
            ->pluck('id')
            ->map(fn (int $id): int => $id)
            ->all();
    }

    /**
     * @return array<int, int>
     */
    private function validCollectionIds(): array
    {
        return ProductCollection::withoutGlobalScopes()
            ->where('store_id', $this->storeId())
            ->whereKey($this->specificCollectionIds)
            ->pluck('id')
            ->map(fn (int $id): int => $id)
            ->all();
    }

    private function productBelongsToStore(int $productId): bool
    {
        return Product::withoutGlobalScopes()
            ->where('store_id', $this->storeId())
            ->whereKey($productId)
            ->exists();
    }

    private function collectionBelongsToStore(int $collectionId): bool
    {
        return ProductCollection::withoutGlobalScopes()
            ->where('store_id', $this->storeId())
            ->whereKey($collectionId)
            ->exists();
    }

    private function storeId(): int
    {
        $store = app('current_store');

        abort_unless($store instanceof Store, 404);

        return $store->getKey();
    }

    private function authorizeSave(): void
    {
        if ($this->discount instanceof Discount) {
            $this->authorize('update', $this->discount);

            return;
        }

        $this->authorize('create', Discount::class);
    }

    private function normalizeCode(): void
    {
        if ($this->type !== DiscountType::Code->value) {
            $this->code = '';

            return;
        }

        $this->code = Str::upper(trim($this->code));
    }

    /**
     * @return list<mixed>
     */
    private function valueAmountRules(): array
    {
        return match ($this->valueType) {
            DiscountValueType::Percent->value => ['required', 'integer', 'min:1', 'max:100'],
            DiscountValueType::FreeShipping->value => ['nullable'],
            default => ['required', 'numeric', 'min:0.01'],
        };
    }

    private function statusForPayload(): DiscountStatus
    {
        if ($this->discount?->status === DiscountStatus::Expired) {
            return DiscountStatus::Expired;
        }

        if ($this->isActive) {
            return DiscountStatus::Active;
        }

        if ($this->discount?->status === DiscountStatus::Draft || ! $this->discount instanceof Discount) {
            return DiscountStatus::Draft;
        }

        return DiscountStatus::Disabled;
    }
}


cmd: sed -n '1,240p' tests/Browser/Admin/ProductManagementTest.php


cmd: sed -n '1,220p' tests/Browser/Admin/OrderManagementTest.php


cmd: sed -n '1,220p' tests/Browser/Admin/AuthenticationTest.php


cmd: rg -n "data-test=|@" tests/Browser/Admin resources/views/livewire/admin -g '*.php' -g '*.blade.php'


command: sed -n '1,220p' tests/Browser/Admin/OrderManagementTest.php

aggregated_output:
<?php

use App\Enums\FinancialStatus;
use App\Enums\FulfillmentShipmentStatus;
use App\Enums\FulfillmentStatus;
use App\Enums\OrderStatus;
use App\Enums\PaymentMethod;
use App\Enums\PaymentStatus;
use App\Models\Customer;
use App\Models\Fulfillment;
use App\Models\InventoryItem;
use App\Models\Order;
use App\Models\OrderLine;
use App\Models\Payment;
use App\Models\Product;
use App\Models\ProductVariant;
use App\Models\Store;
use App\Models\User;
use Database\Seeders\DatabaseSeeder;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Pest\Browser\Playwright\Playwright;

uses(RefreshDatabase::class);

beforeEach(function (): void {
    Playwright::setHost('shop.test');

    $this->seed(DatabaseSeeder::class);
});

afterEach(function (): void {
    Playwright::setHost(null);
});

function adminOrderHost(): array
{
    return ['host' => 'shop.test'];
}

function adminOrderAuthenticate(mixed $testCase): void
{
    $store = Store::query()->where('handle', 'acme-fashion')->firstOrFail();
    $user = User::query()->where('email', 'admin@acme.test')->firstOrFail();

    $testCase->actingAs($user);
    $testCase->withSession(['current_store_id' => $store->getKey()]);
}

/**
 * @return array{store: Store, paid: Order, fulfilled: Order, bank: Order}
 */
function adminOrderFixtures(): array
{
    $store = Store::query()->where('handle', 'acme-fashion')->firstOrFail();
    $customer = Customer::query()->where('email', 'customer@acme.test')->firstOrFail();
    $product = Product::withoutGlobalScopes()
        ->where('store_id', $store->getKey())
        ->where('handle', 'classic-cotton-t-shirt')
        ->firstOrFail();
    $variant = ProductVariant::withoutGlobalScopes()
        ->where('product_id', $product->getKey())
        ->firstOrFail();

    $paid = adminOrderCreateOrder(
        store: $store,
        customer: $customer,
        product: $product,
        variant: $variant,
        orderNumber: '#1001',
        paymentMethod: PaymentMethod::CreditCard,
        status: OrderStatus::Paid,
        financialStatus: FinancialStatus::Paid,
        fulfillmentStatus: FulfillmentStatus::Unfulfilled,
        placedAt: now()->subDays(3),
    );

    $fulfilled = adminOrderCreateOrder(
        store: $store,
        customer: $customer,
        product: $product,
        variant: $variant,
        orderNumber: '#1002',
        paymentMethod: PaymentMethod::CreditCard,
        status: OrderStatus::Fulfilled,
        financialStatus: FinancialStatus::Paid,
        fulfillmentStatus: FulfillmentStatus::Fulfilled,
        placedAt: now()->subDays(2),
    );

    adminOrderCreateDeliveredFulfillment($fulfilled);

    $bank = adminOrderCreateOrder(
        store: $store,
        customer: $customer,
        product: $product,
        variant: $variant,
        orderNumber: '#1005',
        paymentMethod: PaymentMethod::BankTransfer,
        status: OrderStatus::Pending,
        financialStatus: FinancialStatus::Pending,
        fulfillmentStatus: FulfillmentStatus::Unfulfilled,
        placedAt: now()->subDay(),
    );

    InventoryItem::withoutGlobalScopes()
        ->where('variant_id', $variant->getKey())
        ->update([
            'quantity_on_hand' => 20,
            'quantity_reserved' => 1,
        ]);

    return [
        'store' => $store,
        'paid' => $paid,
        'fulfilled' => $fulfilled,
        'bank' => $bank,
    ];
}

function adminOrderCreateOrder(
    Store $store,
    Customer $customer,
    Product $product,
    ProductVariant $variant,
    string $orderNumber,
    PaymentMethod $paymentMethod,
    OrderStatus $status,
    FinancialStatus $financialStatus,
    FulfillmentStatus $fulfillmentStatus,
    mixed $placedAt,
): Order {
    $subtotal = $variant->price_amount;
    $shipping = 499;
    $tax = 0;
    $total = $subtotal + $shipping + $tax;

    $order = Order::factory()->create([
        'store_id' => $store->getKey(),
        'customer_id' => $customer->getKey(),
        'order_number' => $orderNumber,
        'payment_method' => $paymentMethod,
        'status' => $status,
        'financial_status' => $financialStatus,
        'fulfillment_status' => $fulfillmentStatus,
        'currency' => $store->default_currency,
        'subtotal_amount' => $subtotal,
        'discount_amount' => 0,
        'shipping_amount' => $shipping,
        'tax_amount' => $tax,
        'total_amount' => $total,
        'email' => $customer->email,
        'placed_at' => $placedAt,
    ]);

    OrderLine::factory()->create([
        'order_id' => $order->getKey(),
        'product_id' => $product->getKey(),
        'variant_id' => $variant->getKey(),
        'title_snapshot' => 'Classic Cotton T-Shirt',
        'sku_snapshot' => $variant->sku,
        'quantity' => 1,
        'unit_price_amount' => $variant->price_amount,
        'total_amount' => $variant->price_amount,
    ]);

    Payment::factory()->create([
        'order_id' => $order->getKey(),
        'method' => $paymentMethod,
        'status' => $financialStatus === FinancialStatus::Pending ? PaymentStatus::Pending : PaymentStatus::Captured,
        'amount' => $total,
        'currency' => $store->default_currency,
    ]);

    return $order->refresh();
}

function adminOrderCreateDeliveredFulfillment(Order $order): void
{
    $line = $order->lines()->firstOrFail();
    $fulfillment = Fulfillment::query()->create([
        'order_id' => $order->getKey(),
        'status' => FulfillmentShipmentStatus::Delivered,
        'tracking_company' => 'DHL',
        'tracking_number' => 'DHL1234567890',
        'shipped_at' => now()->subDay(),
        'delivered_at' => now(),
    ]);

    $fulfillment->lines()->create([
        'order_line_id' => $line->getKey(),
        'quantity' => $line->quantity,
    ]);
}

function adminOrderOpenOrders(mixed $testCase): mixed
{
    adminOrderFixtures();
    adminOrderAuthenticate($testCase);

    return visit('/admin/orders', adminOrderHost())
        ->wait(1)
        ->assertPathIs('/admin/orders')
        ->assertSee('Orders')
        ->assertNoJavaScriptErrors();
}

function adminOrderOpenOrder(mixed $testCase, string $orderNumber): mixed
{
    return adminOrderOpenOrders($testCase)
        ->assertSee($orderNumber)
        ->click("a:has-text(\"{$orderNumber}\")")
        ->wait(1)
        ->assertSee($orderNumber)
        ->assertNoJavaScriptErrors();
}

function adminOrderCreateFulfillmentInBrowser(mixed $page): mixed
{
    return $page
        ->click('button[data-test="fulfillment-modal-button"]')


command: sed -n '1,240p' tests/Browser/Admin/ProductManagementTest.php

aggregated_output:
<?php

use App\Models\Store;
use App\Models\User;
use Database\Seeders\DatabaseSeeder;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Pest\Browser\Playwright\Playwright;

uses(RefreshDatabase::class);

beforeEach(function (): void {
    Playwright::setHost('shop.test');

    $this->seed(DatabaseSeeder::class);
});

afterEach(function (): void {
    Playwright::setHost(null);
});

function adminProductHost(): array
{
    return ['host' => 'shop.test'];
}

function adminProductAuthenticate(mixed $testCase): void
{
    $store = Store::query()->where('handle', 'acme-fashion')->firstOrFail();
    $user = User::query()->where('email', 'admin@acme.test')->firstOrFail();

    $testCase->actingAs($user);
    $testCase->withSession(['current_store_id' => $store->getKey()]);
}

function adminProductOpenProducts(mixed $testCase): mixed
{
    adminProductAuthenticate($testCase);

    return visit('/admin/products', adminProductHost())
        ->wait(1)
        ->assertPathIs('/admin/products')
        ->assertSee('Products')
        ->assertNoJavaScriptErrors();
}

function adminProductFillProductForm(
    mixed $page,
    string $title,
    string $handle,
    string $sku,
    string $price,
    string $quantity,
    string $description = '',
    string $vendor = '',
    string $productType = '',
): mixed {
    $page
        ->fill('input[wire\\:model\\.live\\.debounce\\.300ms="title"]', $title)
        ->fill('input[wire\\:model="handle"]', $handle)
        ->fill('input[wire\\:model="variants.0.sku"]', $sku)
        ->fill('input[wire\\:model="variants.0.price"]', $price)
        ->fill('input[wire\\:model="variants.0.quantity"]', $quantity);

    if ($description !== '') {
        $page->fill('textarea[wire\\:model="descriptionHtml"]', $description);
    }

    if ($vendor !== '') {
        $page->fill('input[wire\\:model="vendor"]', $vendor);
    }

    if ($productType !== '') {
        $page->fill('input[wire\\:model="productType"]', $productType);
    }

    return $page->wait(1);
}

function adminProductSave(mixed $page): mixed
{
    return $page
        ->click('button[data-test="product-save-button"]')
        ->wait(1)
        ->assertSee('Product saved')
        ->assertNoJavaScriptErrors();
}

function adminProductReturnToList(mixed $page): mixed
{
    return $page
        ->click('ui-sidebar a[href$="/admin/products"]')
        ->wait(1)
        ->assertPathIs('/admin/products')
        ->assertSee('Products')
        ->assertNoJavaScriptErrors();
}

test('shows the product list with seeded products', function (): void {
    adminProductOpenProducts($this)
        ->assertSee('Classic Cotton T-Shirt')
        ->assertSee('Premium Slim Fit Jeans')
        ->assertNoJavaScriptErrors();
});

test('can create a new product', function (): void {
    $page = adminProductOpenProducts($this)
        ->click('a[href$="/admin/products/create"]')
        ->wait(1)
        ->assertPathIs('/admin/products/create')
        ->assertSee('Add product');

    adminProductFillProductForm(
        $page,
        'Test Product Created by E2E',
        'test-product-created-by-e2e',
        'E2E-TEST-001',
        '29.99',
        '50',
        'This product was created by the E2E test suite.',
        'Test Vendor',
        'T-Shirts',
    );

    adminProductSave($page);

    adminProductReturnToList($page)
        ->assertSee('Test Product Created by E2E')
        ->assertNoJavaScriptErrors();
});

test('can edit an existing product title', function (): void {
    $page = adminProductOpenProducts($this)
        ->assertSee('Classic Cotton T-Shirt')
        ->click('a:has-text("Classic Cotton T-Shirt")')
        ->wait(1)
        ->assertSee('Classic Cotton T-Shirt');

    $page
        ->fill('input[wire\\:model\\.live\\.debounce\\.300ms="title"]', 'Classic Cotton T-Shirt Updated')
        ->wait(1);

    adminProductSave($page);

    adminProductReturnToList($page)
        ->assertSee('Classic Cotton T-Shirt Updated')
        ->assertNoJavaScriptErrors();
});

test('can archive a product', function (): void {
    $page = adminProductOpenProducts($this)
        ->click('a[href$="/admin/products/create"]')
        ->wait(1)
        ->assertPathIs('/admin/products/create')
        ->assertSee('Add product');

    adminProductFillProductForm(
        $page,
        'Product To Archive',
        'product-to-archive',
        'E2E-ARCHIVE-001',
        '19.99',
        '10',
    );

    adminProductSave($page);

    adminProductReturnToList($page)
        ->assertSee('Product To Archive')
        ->click('a:has-text("Product To Archive")')
        ->wait(1)
        ->assertSee('Product To Archive')
        ->select('select[wire\\:model="status"]', 'archived');

    adminProductSave($page);

    adminProductReturnToList($page)
        ->assertDontSee('Product To Archive')
        ->assertNoJavaScriptErrors();
});

test('shows draft products only in admin and not storefront', function (): void {
    $page = adminProductOpenProducts($this)
        ->select('select[wire\\:model\\.live="statusFilter"]', 'draft')
        ->wait(1)
        ->assertSee('Unreleased Winter Jacket')
        ->assertSee('Draft')
        ->assertDontSee('Classic Cotton T-Shirt')
        ->assertNoJavaScriptErrors();

    $page->navigate('/collections/t-shirts')
        ->wait(1)
        ->assertPathIs('/collections/t-shirts')
        ->assertDontSee('Unreleased Winter Jacket')
        ->assertNoJavaScriptErrors()
        ->navigate('/search?q=draft')
        ->wait(1)
        ->assertPathIs('/search')
        ->assertDontSee('Unreleased Winter Jacket')
        ->assertNoJavaScriptErrors();
});

test('can search products in admin', function (): void {
    adminProductOpenProducts($this)
        ->fill('input[wire\\:model\\.live\\.debounce\\.300ms="search"]', 'Cotton')
        ->wait(1)
        ->assertSee('Classic Cotton T-Shirt')
        ->assertDontSee('Premium Slim Fit Jeans')
        ->assertNoJavaScriptErrors();
});

test('can filter products by status in admin', function (): void {
    adminProductOpenProducts($this)
        ->select('select[wire\\:model\\.live="statusFilter"]', 'draft')
        ->wait(1)
        ->assertSee('Unreleased Winter Jacket')
        ->assertDontSee('Classic Cotton T-Shirt')
        ->assertNoJavaScriptErrors()
        ->select('select[wire\\:model\\.live="statusFilter"]', 'active')
        ->wait(1)
        ->assertSee('Classic Cotton T-Shirt')
        ->assertDontSee('Unreleased Winter Jacket')
        ->assertNoJavaScriptErrors();
});


output:
Chunk ID: a65853
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 1638
Output:
<?php

use App\Models\Store;
use App\Models\User;
use Database\Seeders\DatabaseSeeder;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Pest\Browser\Playwright\Playwright;

uses(RefreshDatabase::class);

beforeEach(function (): void {
    Playwright::setHost('shop.test');

    $this->seed(DatabaseSeeder::class);
});

afterEach(function (): void {
    Playwright::setHost(null);
});

function adminProductHost(): array
{
    return ['host' => 'shop.test'];
}

function adminProductAuthenticate(mixed $testCase): void
{
    $store = Store::query()->where('handle', 'acme-fashion')->firstOrFail();
    $user = User::query()->where('email', 'admin@acme.test')->firstOrFail();

    $testCase->actingAs($user);
    $testCase->withSession(['current_store_id' => $store->getKey()]);
}

function adminProductOpenProducts(mixed $testCase): mixed
{
    adminProductAuthenticate($testCase);

    return visit('/admin/products', adminProductHost())
        ->wait(1)
        ->assertPathIs('/admin/products')
        ->assertSee('Products')
        ->assertNoJavaScriptErrors();
}

function adminProductFillProductForm(
    mixed $page,
    string $title,
    string $handle,
    string $sku,
    string $price,
    string $quantity,
    string $description = '',
    string $vendor = '',
    string $productType = '',
): mixed {
    $page
        ->fill('input[wire\\:model\\.live\\.debounce\\.300ms="title"]', $title)
        ->fill('input[wire\\:model="handle"]', $handle)
        ->fill('input[wire\\:model="variants.0.sku"]', $sku)
        ->fill('input[wire\\:model="variants.0.price"]', $price)
        ->fill('input[wire\\:model="variants.0.quantity"]', $quantity);

    if ($description !== '') {
        $page->fill('textarea[wire\\:model="descriptionHtml"]', $description);
    }

    if ($vendor !== '') {
        $page->fill('input[wire\\:model="vendor"]', $vendor);
    }

    if ($productType !== '') {
        $page->fill('input[wire\\:model="productType"]', $productType);
    }

    return $page->wait(1);
}

function adminProductSave(mixed $page): mixed
{
    return $page
        ->click('button[data-test="product-save-button"]')
        ->wait(1)
        ->assertSee('Product saved')
        ->assertNoJavaScriptErrors();
}

function adminProductReturnToList(mixed $page): mixed
{
    return $page
        ->click('ui-sidebar a[href$="/admin/products"]')
        ->wait(1)
        ->assertPathIs('/admin/products')
        ->assertSee('Products')
        ->assertNoJavaScriptErrors();
}

test('shows the product list with seeded products', function (): void {
    adminProductOpenProducts($this)
        ->assertSee('Classic Cotton T-Shirt')
        ->assertSee('Premium Slim Fit Jeans')
        ->assertNoJavaScriptErrors();
});

test('can create a new product', function (): void {
    $page = adminProductOpenProducts($this)
        ->click('a[href$="/admin/products/create"]')
        ->wait(1)
        ->assertPathIs('/admin/products/create')
        ->assertSee('Add product');

    adminProductFillProductForm(
        $page,
        'Test Product Created by E2E',
        'test-product-created-by-e2e',
        'E2E-TEST-001',
        '29.99',
        '50',
        'This product was created by the E2E test suite.',
        'Test Vendor',
        'T-Shirts',
    );

    adminProductSave($page);

    adminProductReturnToList($page)
        ->assertSee('Test Product Created by E2E')
        ->assertNoJavaScriptErrors();
});

test('can edit an existing product title', function (): void {
    $page = adminProductOpenProducts($this)
        ->assertSee('Classic Cotton T-Shirt')
        ->click('a:has-text("Classic Cotton T-Shirt")')
        ->wait(1)
        ->assertSee('Classic Cotton T-Shirt');

    $page
        ->fill('input[wire\\:model\\.live\\.debounce\\.300ms="title"]', 'Classic Cotton T-Shirt Updated')
        ->wait(1);

    adminProductSave($page);

    adminProductReturnToList($page)
        ->assertSee('Classic Cotton T-Shirt Updated')
        ->assertNoJavaScriptErrors();
});

test('can archive a product', function (): void {
    $page = adminProductOpenProducts($this)
        ->click('a[href$="/admin/products/create"]')
        ->wait(1)
        ->assertPathIs('/admin/products/create')
        ->assertSee('Add product');

    adminProductFillProductForm(
        $page,
        'Product To Archive',
        'product-to-archive',
        'E2E-ARCHIVE-001',
        '19.99',
        '10',
    );

    adminProductSave($page);

    adminProductReturnToList($page)
        ->assertSee('Product To Archive')
        ->click('a:has-text("Product To Archive")')
        ->wait(1)
        ->assertSee('Product To Archive')
        ->select('select[wire\\:model="status"]', 'archived');

    adminProductSave($page);

    adminProductReturnToList($page)
        ->assertDontSee('Product To Archive')
        ->assertNoJavaScriptErrors();
});

test('shows draft products only in admin and not storefront', function (): void {
    $page = adminProductOpenProducts($this)
        ->select('select[wire\\:model\\.live="statusFilter"]', 'draft')
        ->wait(1)
        ->assertSee('Unreleased Winter Jacket')
        ->assertSee('Draft')
        ->assertDontSee('Classic Cotton T-Shirt')
        ->assertNoJavaScriptErrors();

    $page->navigate('/collections/t-shirts')
        ->wait(1)
        ->assertPathIs('/collections/t-shirts')
        ->assertDontSee('Unreleased Winter Jacket')
        ->assertNoJavaScriptErrors()
        ->navigate('/search?q=draft')
        ->wait(1)
        ->assertPathIs('/search')
        ->assertDontSee('Unreleased Winter Jacket')
        ->assertNoJavaScriptErrors();
});

test('can search products in admin', function (): void {
    adminProductOpenProducts($this)
        ->fill('input[wire\\:model\\.live\\.debounce\\.300ms="search"]', 'Cotton')
        ->wait(1)
        ->assertSee('Classic Cotton T-Shirt')
        ->assertDontSee('Premium Slim Fit Jeans')
        ->assertNoJavaScriptErrors();
});

test('can filter products by status in admin', function (): void {
    adminProductOpenProducts($this)
        ->select('select[wire\\:model\\.live="statusFilter"]', 'draft')
        ->wait(1)
        ->assertSee('Unreleased Winter Jacket')
        ->assertDontSee('Classic Cotton T-Shirt')
        ->assertNoJavaScriptErrors()
        ->select('select[wire\\:model\\.live="statusFilter"]', 'active')
        ->wait(1)
        ->assertSee('Classic Cotton T-Shirt')
        ->assertDontSee('Unreleased Winter Jacket')
        ->assertNoJavaScriptErrors();
});


output:
Chunk ID: b87e34
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 1631
Output:
<?php

use App\Enums\FinancialStatus;
use App\Enums\FulfillmentShipmentStatus;
use App\Enums\FulfillmentStatus;
use App\Enums\OrderStatus;
use App\Enums\PaymentMethod;
use App\Enums\PaymentStatus;
use App\Models\Customer;
use App\Models\Fulfillment;
use App\Models\InventoryItem;
use App\Models\Order;
use App\Models\OrderLine;
use App\Models\Payment;
use App\Models\Product;
use App\Models\ProductVariant;
use App\Models\Store;
use App\Models\User;
use Database\Seeders\DatabaseSeeder;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Pest\Browser\Playwright\Playwright;

uses(RefreshDatabase::class);

beforeEach(function (): void {
    Playwright::setHost('shop.test');

    $this->seed(DatabaseSeeder::class);
});

afterEach(function (): void {
    Playwright::setHost(null);
});

function adminOrderHost(): array
{
    return ['host' => 'shop.test'];
}

function adminOrderAuthenticate(mixed $testCase): void
{
    $store = Store::query()->where('handle', 'acme-fashion')->firstOrFail();
    $user = User::query()->where('email', 'admin@acme.test')->firstOrFail();

    $testCase->actingAs($user);
    $testCase->withSession(['current_store_id' => $store->getKey()]);
}

/**
 * @return array{store: Store, paid: Order, fulfilled: Order, bank: Order}
 */
function adminOrderFixtures(): array
{
    $store = Store::query()->where('handle', 'acme-fashion')->firstOrFail();
    $customer = Customer::query()->where('email', 'customer@acme.test')->firstOrFail();
    $product = Product::withoutGlobalScopes()
        ->where('store_id', $store->getKey())
        ->where('handle', 'classic-cotton-t-shirt')
        ->firstOrFail();
    $variant = ProductVariant::withoutGlobalScopes()
        ->where('product_id', $product->getKey())
        ->firstOrFail();

    $paid = adminOrderCreateOrder(
        store: $store,
        customer: $customer,
        product: $product,
        variant: $variant,
        orderNumber: '#1001',
        paymentMethod: PaymentMethod::CreditCard,
        status: OrderStatus::Paid,
        financialStatus: FinancialStatus::Paid,
        fulfillmentStatus: FulfillmentStatus::Unfulfilled,
        placedAt: now()->subDays(3),
    );

    $fulfilled = adminOrderCreateOrder(
        store: $store,
        customer: $customer,
        product: $product,
        variant: $variant,
        orderNumber: '#1002',
        paymentMethod: PaymentMethod::CreditCard,
        status: OrderStatus::Fulfilled,
        financialStatus: FinancialStatus::Paid,
        fulfillmentStatus: FulfillmentStatus::Fulfilled,
        placedAt: now()->subDays(2),
    );

    adminOrderCreateDeliveredFulfillment($fulfilled);

    $bank = adminOrderCreateOrder(
        store: $store,
        customer: $customer,
        product: $product,
        variant: $variant,
        orderNumber: '#1005',
        paymentMethod: PaymentMethod::BankTransfer,
        status: OrderStatus::Pending,
        financialStatus: FinancialStatus::Pending,
        fulfillmentStatus: FulfillmentStatus::Unfulfilled,
        placedAt: now()->subDay(),
    );

    InventoryItem::withoutGlobalScopes()
        ->where('variant_id', $variant->getKey())
        ->update([
            'quantity_on_hand' => 20,
            'quantity_reserved' => 1,
        ]);

    return [
        'store' => $store,
        'paid' => $paid,
        'fulfilled' => $fulfilled,
        'bank' => $bank,
    ];
}

function adminOrderCreateOrder(
    Store $store,
    Customer $customer,
    Product $product,
    ProductVariant $variant,
    string $orderNumber,
    PaymentMethod $paymentMethod,
    OrderStatus $status,
    FinancialStatus $financialStatus,
    FulfillmentStatus $fulfillmentStatus,
    mixed $placedAt,
): Order {
    $subtotal = $variant->price_amount;
    $shipping = 499;
    $tax = 0;
    $total = $subtotal + $shipping + $tax;

    $order = Order::factory()->create([
        'store_id' => $store->getKey(),
        'customer_id' => $customer->getKey(),
        'order_number' => $orderNumber,
        'payment_method' => $paymentMethod,
        'status' => $status,
        'financial_status' => $financialStatus,
        'fulfillment_status' => $fulfillmentStatus,
        'currency' => $store->default_currency,
        'subtotal_amount' => $subtotal,
        'discount_amount' => 0,
        'shipping_amount' => $shipping,
        'tax_amount' => $tax,
        'total_amount' => $total,
        'email' => $customer->email,
        'placed_at' => $placedAt,
    ]);

    OrderLine::factory()->create([
        'order_id' => $order->getKey(),
        'product_id' => $product->getKey(),
        'variant_id' => $variant->getKey(),
        'title_snapshot' => 'Classic Cotton T-Shirt',
        'sku_snapshot' => $variant->sku,
        'quantity' => 1,
        'unit_price_amount' => $variant->price_amount,
        'total_amount' => $variant->price_amount,
    ]);

    Payment::factory()->create([
        'order_id' => $order->getKey(),
        'method' => $paymentMethod,
        'status' => $financialStatus === FinancialStatus::Pending ? PaymentStatus::Pending : PaymentStatus::Captured,
        'amount' => $total,
        'currency' => $store->default_currency,
    ]);

    return $order->refresh();
}

function adminOrderCreateDeliveredFulfillment(Order $order): void
{
    $line = $order->lines()->firstOrFail();
    $fulfillment = Fulfillment::query()->create([
        'order_id' => $order->getKey(),
        'status' => FulfillmentShipmentStatus::Delivered,
        'tracking_company' => 'DHL',
        'tracking_number' => 'DHL1234567890',
        'shipped_at' => now()->subDay(),
        'delivered_at' => now(),
    ]);

    $fulfillment->lines()->create([
        'order_line_id' => $line->getKey(),
        'quantity' => $line->quantity,
    ]);
}

function adminOrderOpenOrders(mixed $testCase): mixed
{
    adminOrderFixtures();
    adminOrderAuthenticate($testCase);

    return visit('/admin/orders', adminOrderHost())
        ->wait(1)
        ->assertPathIs('/admin/orders')
        ->assertSee('Orders')
        ->assertNoJavaScriptErrors();
}

function adminOrderOpenOrder(mixed $testCase, string $orderNumber): mixed
{
    return adminOrderOpenOrders($testCase)
        ->assertSee($orderNumber)
        ->click("a:has-text(\"{$orderNumber}\")")
        ->wait(1)
        ->assertSee($orderNumber)
        ->assertNoJavaScriptErrors();
}

function adminOrderCreateFulfillmentInBrowser(mixed $page): mixed
{
    return $page
        ->click('button[data-test="fulfillment-modal-button"]')


command: sed -n '1,220p' tests/Browser/Admin/AuthenticationTest.php

aggregated_output:
<?php

use Database\Seeders\DatabaseSeeder;
use Illuminate\Foundation\Testing\RefreshDatabase;

uses(RefreshDatabase::class);

beforeEach(function (): void {
    $this->seed(DatabaseSeeder::class);
});

function adminAuthenticationHost(): array
{
    return ['host' => 'shop.test'];
}

function adminAuthenticationLogin(): mixed
{
    return visit('/admin/login', adminAuthenticationHost())
        ->fill('input[type=email]', 'admin@acme.test')
        ->fill('input[type=password]', 'password')
        ->click('@admin-login-button')
        ->wait(1)
        ->assertPathIs('/admin')
        ->assertSee('Dashboard')
        ->assertNoJavaScriptErrors();
}

function adminAuthenticationSubmitWithoutBrowserRequired(string $email, string $password): mixed
{
    $page = visit('/admin/login', adminAuthenticationHost());

    $page->script('() => document.querySelectorAll("[required]").forEach((element) => element.removeAttribute("required"))');

    if ($email !== '') {
        $page->fill('input[type=email]', $email);
    }

    if ($password !== '') {
        $page->fill('input[type=password]', $password);
    }

    return $page->click('@admin-login-button')->wait(1);
}

test('can log in as admin', function (): void {
    adminAuthenticationLogin();
});

test('shows error for invalid credentials', function (): void {
    visit('/admin/login', adminAuthenticationHost())
        ->fill('input[type=email]', 'admin@acme.test')
        ->fill('input[type=password]', 'wrongpassword')
        ->click('@admin-login-button')
        ->wait(1)
        ->assertPathIs('/admin/login')
        ->assertSee('Invalid credentials')
        ->assertNoJavaScriptErrors();
});

test('shows error for empty email', function (): void {
    adminAuthenticationSubmitWithoutBrowserRequired('', 'password')
        ->assertPathIs('/admin/login')
        ->assertSee('email field is required')
        ->assertNoJavaScriptErrors();
});

test('shows error for empty password', function (): void {
    adminAuthenticationSubmitWithoutBrowserRequired('admin@acme.test', '')
        ->assertPathIs('/admin/login')
        ->assertSee('password field is required')
        ->assertNoJavaScriptErrors();
});

test('redirects unauthenticated users to login from dashboard', function (): void {
    visit('/admin', adminAuthenticationHost())
        ->wait(1)
        ->assertPathIs('/admin/login')
        ->assertSee('Sign in')
        ->assertNoJavaScriptErrors();
});

test('redirects unauthenticated users to login from products', function (): void {
    visit('/admin/products', adminAuthenticationHost())
        ->wait(1)
        ->assertPathIs('/admin/login')
        ->assertSee('Sign in')
        ->assertNoJavaScriptErrors();
});

test('can log out', function (): void {
    adminAuthenticationLogin()
        ->click('@sidebar-menu-button')
        ->click('button[data-test="logout-button"]:visible')
        ->wait(1)
        ->assertPathIs('/admin/login')
        ->assertSee('Sign in')
        ->assertNoJavaScriptErrors();
});

test('can navigate through admin sidebar sections', function (): void {
    $page = adminAuthenticationLogin();

    foreach ([
        '/admin/products' => 'Products',
        '/admin/orders' => 'Orders',
        '/admin/customers' => 'Customers',
        '/admin/discounts' => 'Discounts',
        '/admin/settings' => 'Store Settings',
    ] as $path => $heading) {
        $page->click("a[href$=\"{$path}\"]")
            ->wait(1)
            ->assertPathIs($path)
            ->assertSee($heading)
            ->assertNoJavaScriptErrors();
    }
});

test('can navigate to analytics from sidebar', function (): void {
    adminAuthenticationLogin()
        ->click('a[href$="/admin/analytics"]')
        ->wait(1)
        ->assertPathIs('/admin/analytics')
        ->assertSee('Analytics')
        ->assertNoJavaScriptErrors();
});

test('can navigate to themes from sidebar', function (): void {
    adminAuthenticationLogin()
        ->click('a[href$="/admin/themes"]')
        ->wait(1)
        ->assertPathIs('/admin/themes')
        ->assertSee('Themes')
        ->assertNoJavaScriptErrors();
});


output:
Chunk ID: 23c482
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 1035
Output:
<?php

use Database\Seeders\DatabaseSeeder;
use Illuminate\Foundation\Testing\RefreshDatabase;

uses(RefreshDatabase::class);

beforeEach(function (): void {
    $this->seed(DatabaseSeeder::class);
});

function adminAuthenticationHost(): array
{
    return ['host' => 'shop.test'];
}

function adminAuthenticationLogin(): mixed
{
    return visit('/admin/login', adminAuthenticationHost())
        ->fill('input[type=email]', 'admin@acme.test')
        ->fill('input[type=password]', 'password')
        ->click('@admin-login-button')
        ->wait(1)
        ->assertPathIs('/admin')
        ->assertSee('Dashboard')
        ->assertNoJavaScriptErrors();
}

function adminAuthenticationSubmitWithoutBrowserRequired(string $email, string $password): mixed
{
    $page = visit('/admin/login', adminAuthenticationHost());

    $page->script('() => document.querySelectorAll("[required]").forEach((element) => element.removeAttribute("required"))');

    if ($email !== '') {
        $page->fill('input[type=email]', $email);
    }

    if ($password !== '') {
        $page->fill('input[type=password]', $password);
    }

    return $page->click('@admin-login-button')->wait(1);
}

test('can log in as admin', function (): void {
    adminAuthenticationLogin();
});

test('shows error for invalid credentials', function (): void {
    visit('/admin/login', adminAuthenticationHost())
        ->fill('input[type=email]', 'admin@acme.test')
        ->fill('input[type=password]', 'wrongpassword')
        ->click('@admin-login-button')
        ->wait(1)
        ->assertPathIs('/admin/login')
        ->assertSee('Invalid credentials')
        ->assertNoJavaScriptErrors();
});

test('shows error for empty email', function (): void {
    adminAuthenticationSubmitWithoutBrowserRequired('', 'password')
        ->assertPathIs('/admin/login')
        ->assertSee('email field is required')
        ->assertNoJavaScriptErrors();
});

test('shows error for empty password', function (): void {
    adminAuthenticationSubmitWithoutBrowserRequired('admin@acme.test', '')
        ->assertPathIs('/admin/login')
        ->assertSee('password field is required')
        ->assertNoJavaScriptErrors();
});

test('redirects unauthenticated users to login from dashboard', function (): void {
    visit('/admin', adminAuthenticationHost())
        ->wait(1)
        ->assertPathIs('/admin/login')
        ->assertSee('Sign in')
        ->assertNoJavaScriptErrors();
});

test('redirects unauthenticated users to login from products', function (): void {
    visit('/admin/products', adminAuthenticationHost())
        ->wait(1)
        ->assertPathIs('/admin/login')
        ->assertSee('Sign in')
        ->assertNoJavaScriptErrors();
});

test('can log out', function (): void {
    adminAuthenticationLogin()
        ->click('@sidebar-menu-button')
        ->click('button[data-test="logout-button"]:visible')
        ->wait(1)
        ->assertPathIs('/admin/login')
        ->assertSee('Sign in')
        ->assertNoJavaScriptErrors();
});

test('can navigate through admin sidebar sections', function (): void {
    $page = adminAuthenticationLogin();

    foreach ([
        '/admin/products' => 'Products',
        '/admin/orders' => 'Orders',
        '/admin/customers' => 'Customers',
        '/admin/discounts' => 'Discounts',
        '/admin/settings' => 'Store Settings',
    ] as $path => $heading) {
        $page->click("a[href$=\"{$path}\"]")
            ->wait(1)
            ->assertPathIs($path)
            ->assertSee($heading)
            ->assertNoJavaScriptErrors();
    }
});

test('can navigate to analytics from sidebar', function (): void {
    adminAuthenticationLogin()
        ->click('a[href$="/admin/analytics"]')
        ->wait(1)
        ->assertPathIs('/admin/analytics')
        ->assertSee('Analytics')
        ->assertNoJavaScriptErrors();
});

test('can navigate to themes from sidebar', function (): void {
    adminAuthenticationLogin()
        ->click('a[href$="/admin/themes"]')
        ->wait(1)
        ->assertPathIs('/admin/themes')
        ->assertSee('Themes')
        ->assertNoJavaScriptErrors();
});


command: rg -n "data-test=|@" tests/Browser/Admin resources/views/livewire/admin -g '*.php' -g '*.blade.php'

type: search

cmd: rg -n 'data-test=|@' tests/Browser/Admin resources/views/livewire/admin -g '*.php' -g '*.blade.php'

query: data-test=|@

path: Admin

aggregated_output:
tests/Browser/Admin/OrderManagementTest.php:43:    $user = User::query()->where('email', 'admin@acme.test')->firstOrFail();
tests/Browser/Admin/OrderManagementTest.php:50: * @return array{store: Store, paid: Order, fulfilled: Order, bank: Order}
tests/Browser/Admin/OrderManagementTest.php:55:    $customer = Customer::query()->where('email', 'customer@acme.test')->firstOrFail();
tests/Browser/Admin/OrderManagementTest.php:220:        ->click('button[data-test="fulfillment-modal-button"]')
tests/Browser/Admin/OrderManagementTest.php:224:        ->click('button[data-test="fulfillment-submit-button"]')
tests/Browser/Admin/OrderManagementTest.php:282:        ->click('button[data-test="refund-modal-button"]')
tests/Browser/Admin/OrderManagementTest.php:286:        ->click('button[data-test="refund-submit-button"]')
tests/Browser/Admin/OrderManagementTest.php:295:        ->assertSee('customer@acme.test')
tests/Browser/Admin/OrderManagementTest.php:302:        ->assertPresent('button[data-test="confirm-payment-button"]')
tests/Browser/Admin/OrderManagementTest.php:303:        ->click('button[data-test="confirm-payment-button"]')
tests/Browser/Admin/OrderManagementTest.php:315:        ->assertScript('document.querySelector("button[data-test=\"fulfillment-modal-button\"]") === null')
tests/Browser/Admin/OrderManagementTest.php:322:    $page->click('button[data-test="mark-fulfillment-shipped-button"]')
tests/Browser/Admin/OrderManagementTest.php:331:    $page->click('button[data-test="mark-fulfillment-shipped-button"]')
tests/Browser/Admin/OrderManagementTest.php:333:        ->click('button[data-test="mark-fulfillment-delivered-button"]')
resources/views/livewire/admin/developers/index.blade.php:9:    @if (session('status'))
resources/views/livewire/admin/developers/index.blade.php:13:    @endif
resources/views/livewire/admin/developers/index.blade.php:15:    @if ($generatedToken)
resources/views/livewire/admin/developers/index.blade.php:22:    @endif
resources/views/livewire/admin/developers/index.blade.php:48:                    @forelse ($tokens as $token)
resources/views/livewire/admin/developers/index.blade.php:60:                    @empty
resources/views/livewire/admin/developers/index.blade.php:64:                    @endforelse
resources/views/livewire/admin/developers/index.blade.php:95:                    @forelse ($webhooks as $webhook)
resources/views/livewire/admin/developers/index.blade.php:109:                    @empty
resources/views/livewire/admin/developers/index.blade.php:113:                    @endforelse
resources/views/livewire/admin/developers/index.blade.php:140:                @foreach ($eventTypes as $eventType)
resources/views/livewire/admin/developers/index.blade.php:144:                @endforeach
tests/Browser/Admin/AuthenticationTest.php:20:        ->fill('input[type=email]', 'admin@acme.test')
tests/Browser/Admin/AuthenticationTest.php:22:        ->click('@admin-login-button')
tests/Browser/Admin/AuthenticationTest.php:43:    return $page->click('@admin-login-button')->wait(1);
tests/Browser/Admin/AuthenticationTest.php:52:        ->fill('input[type=email]', 'admin@acme.test')
tests/Browser/Admin/AuthenticationTest.php:54:        ->click('@admin-login-button')
tests/Browser/Admin/AuthenticationTest.php:69:    adminAuthenticationSubmitWithoutBrowserRequired('admin@acme.test', '')
tests/Browser/Admin/AuthenticationTest.php:93:        ->click('@sidebar-menu-button')
tests/Browser/Admin/AuthenticationTest.php:94:        ->click('button[data-test="logout-button"]:visible')
tests/Browser/Admin/ProductManagementTest.php:29:    $user = User::query()->where('email', 'admin@acme.test')->firstOrFail();
tests/Browser/Admin/ProductManagementTest.php:82:        ->click('button[data-test="product-save-button"]')
resources/views/livewire/admin/analytics/index.blade.php:40:        @if ($exportUrl)
resources/views/livewire/admin/analytics/index.blade.php:44:        @endif
resources/views/livewire/admin/analytics/index.blade.php:48:        @foreach ([
resources/views/livewire/admin/analytics/index.blade.php:66:        @endforeach
resources/views/livewire/admin/analytics/index.blade.php:78:            @foreach ($salesChartData as $point)
resources/views/livewire/admin/analytics/index.blade.php:79:                @php
resources/views/livewire/admin/analytics/index.blade.php:81:                @endphp
resources/views/livewire/admin/analytics/index.blade.php:85:                    @if ($loop->first || $loop->last || $loop->iteration % 7 === 0)
resources/views/livewire/admin/analytics/index.blade.php:87:                    @endif
resources/views/livewire/admin/analytics/index.blade.php:89:            @endforeach
resources/views/livewire/admin/analytics/index.blade.php:109:                        @forelse ($topProducts as $product)
resources/views/livewire/admin/analytics/index.blade.php:117:                        @empty
resources/views/livewire/admin/analytics/index.blade.php:121:                        @e…26830 chars truncated…/admin/dashboard.blade.php:28:            @php
resources/views/livewire/admin/dashboard.blade.php:31:            @endphp
resources/views/livewire/admin/dashboard.blade.php:50:        @endforeach
resources/views/livewire/admin/dashboard.blade.php:63:                @foreach ($ordersChartData as $point)
resources/views/livewire/admin/dashboard.blade.php:64:                    @php
resources/views/livewire/admin/dashboard.blade.php:66:                    @endphp
resources/views/livewire/admin/dashboard.blade.php:70:                        @if ($loop->first || $loop->last || $loop->iteration % 7 === 0)
resources/views/livewire/admin/dashboard.blade.php:72:                        @endif
resources/views/livewire/admin/dashboard.blade.php:74:                @endforeach
resources/views/livewire/admin/dashboard.blade.php:83:                @forelse ($topProducts as $product)
resources/views/livewire/admin/dashboard.blade.php:94:                @empty
resources/views/livewire/admin/dashboard.blade.php:99:                @endforelse
resources/views/livewire/admin/dashboard.blade.php:112:        @php
resources/views/livewire/admin/dashboard.blade.php:120:        @endphp
resources/views/livewire/admin/dashboard.blade.php:123:            @foreach ($funnelSteps as $key => $label)
resources/views/livewire/admin/dashboard.blade.php:124:                @php
resources/views/livewire/admin/dashboard.blade.php:127:                @endphp
resources/views/livewire/admin/dashboard.blade.php:139:            @endforeach
resources/views/livewire/admin/settings/index.blade.php:17:    @if (session('status'))
resources/views/livewire/admin/settings/index.blade.php:19:    @endif
resources/views/livewire/admin/settings/index.blade.php:46:                        @foreach ($currencyOptions as $currency)
resources/views/livewire/admin/settings/index.blade.php:48:                        @endforeach
resources/views/livewire/admin/settings/index.blade.php:52:                        @foreach ($localeOptions as $locale => $label)
resources/views/livewire/admin/settings/index.blade.php:54:                        @endforeach
resources/views/livewire/admin/settings/index.blade.php:58:                        @foreach ($timezoneOptions as $timezoneOption)
resources/views/livewire/admin/settings/index.blade.php:60:                        @endforeach
resources/views/livewire/admin/settings/index.blade.php:121:                    @foreach ($domains as $domain)
resources/views/livewire/admin/settings/index.blade.php:126:                                @if ($domain->is_primary)
resources/views/livewire/admin/settings/index.blade.php:128:                                @else
resources/views/livewire/admin/settings/index.blade.php:130:                                @endif
resources/views/livewire/admin/settings/index.blade.php:135:                                    @unless ($domain->is_primary)
resources/views/livewire/admin/settings/index.blade.php:137:                                    @endunless
resources/views/livewire/admin/settings/index.blade.php:142:                    @endforeach
resources/views/livewire/admin/customers/show.blade.php:58:                            @forelse ($orders as $order)
resources/views/livewire/admin/customers/show.blade.php:59:                                @php
resources/views/livewire/admin/customers/show.blade.php:66:                                @endphp
resources/views/livewire/admin/customers/show.blade.php:82:                            @empty
resources/views/livewire/admin/customers/show.blade.php:86:                            @endforelse
resources/views/livewire/admin/customers/show.blade.php:102:                @forelse ($customer->addresses as $address)
resources/views/livewire/admin/customers/show.blade.php:103:                    @php($addressData = $address->address_json ?? [])
resources/views/livewire/admin/customers/show.blade.php:110:                                    @if ($address->is_default)
resources/views/livewire/admin/customers/show.blade.php:112:                                    @endif
resources/views/livewire/admin/customers/show.blade.php:116:                                    @if (data_get($addressData, 'address2'))
resources/views/livewire/admin/customers/show.blade.php:118:                                    @endif
resources/views/livewire/admin/customers/show.blade.php:127:                            @unless ($address->is_default)
resources/views/livewire/admin/customers/show.blade.php:129:                            @endunless
resources/views/livewire/admin/customers/show.blade.php:133:                @empty
resources/views/livewire/admin/customers/show.blade.php:138:                @endforelse
resources/views/livewire/admin/customers/index.blade.php:24:                    @forelse ($customers as $customer)
resources/views/livewire/admin/customers/index.blade.php:38:                    @empty
resources/views/livewire/admin/customers/index.blade.php:50:                    @endforelse