Fatal Error: Call to undefined method stdClass::is_one_time() w OrderRepository:793. Zamieniono wywołania nieistniejących metod na stdClass na dostęp do właściwości + istniejącą metodę CouponRepository::markAsUsed(). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
59 lines
2.1 KiB
Markdown
59 lines
2.1 KiB
Markdown
# PLAN 07-01: Fix coupon stdClass method call crash
|
|
|
|
## Goal
|
|
Fix Fatal Error when placing an order with a coupon code — `stdClass::is_one_time()` undefined method.
|
|
|
|
## Bug Analysis
|
|
|
|
**Error**: `Call to undefined method stdClass::is_one_time()` at `OrderRepository.php:793`
|
|
**Stack**: `ShopBasketController::basketSave()` → `OrderRepository::createFromBasket()`
|
|
|
|
**Root cause**: `CouponRepository::findByName()` returns `(object)$coupon` — a plain `stdClass`. Line 793-794 in `OrderRepository::createFromBasket()` call `$coupon->is_one_time()` and `$coupon->set_as_used()` as if `$coupon` were a domain object with methods. `stdClass` has no methods.
|
|
|
|
**Impact**: CRITICAL — no orders with coupon codes can be placed (Fatal Error crashes the page).
|
|
|
|
## Tasks
|
|
|
|
### T1: Fix OrderRepository::createFromBasket() coupon handling
|
|
**File**: `autoload/Domain/Order/OrderRepository.php` (lines 793-795)
|
|
|
|
**Current (broken)**:
|
|
```php
|
|
if ($coupon && $coupon->is_one_time()) {
|
|
$coupon->set_as_used();
|
|
}
|
|
```
|
|
|
|
**Fix**:
|
|
```php
|
|
if ($coupon && (int)$coupon->one_time === 1) {
|
|
(new \Domain\Coupon\CouponRepository($this->db))->markAsUsed((int)$coupon->id);
|
|
}
|
|
```
|
|
|
|
**Rationale**:
|
|
- `one_time` is a property on stdClass (from `findByName()` casting)
|
|
- `CouponRepository::markAsUsed()` already exists (line 235) — sets `used=1` and `date_used`
|
|
- Consistent with how `incrementUsedCount()` is already called on line 722
|
|
|
|
### T2: Add test for coupon one-time marking in order creation
|
|
**File**: `tests/Unit/Domain/Order/OrderRepositoryTest.php` (or new if needed)
|
|
|
|
Verify that when `$coupon->one_time === 1`, `markAsUsed` is called on the coupon repository.
|
|
|
|
## Acceptance Criteria
|
|
|
|
- [ ] Orders with coupon codes complete without Fatal Error
|
|
- [ ] One-time coupons are correctly marked as used after order
|
|
- [ ] Non-one-time coupons are NOT marked as used
|
|
- [ ] Existing tests pass (`./test.ps1`)
|
|
|
|
## Risk Assessment
|
|
|
|
- **Low risk** — single-line property access fix, uses existing `markAsUsed()` method
|
|
- **No schema changes** needed
|
|
- **No side effects** — logic remains identical, just uses correct API
|
|
|
|
## Estimated Scope
|
|
~5 lines changed in 1 file. Minimal.
|