| @@ -7,8 +7,9 @@ | ||
| 7 | 7 | use FluentCart\App\Models\Concerns\CanSearch; |
| 8 | 8 | use FluentCart\App\Models\Concerns\CanUpdateBatch; |
| 9 | 9 | use FluentCart\App\Models\WpModels\PostMeta; |
| 10 | 10 | use FluentCart\Framework\Database\Orm\Relations\HasOne; |
| 11 | +use FluentCart\Framework\Support\Arr; | |
| 11 | 12 | |
| 12 | 13 | /** |
| 13 | 14 | * OrderItem Model - DB Model for Order Items |
| 14 | 15 | * |
| @@ -54,19 +55,19 @@ | ||
| 54 | 55 | 'payment_type', |
| 55 | 56 | 'created_at', |
| 56 | 57 | // 'shipping_charge' |
| 57 | 58 | ]; |
| 58 | - protected $appends = ['payment_info', 'setup_info', 'is_custom']; | |
| 59 | + protected $appends = ['payment_info', 'setup_info', 'is_custom', 'variation_display_title']; | |
| 59 | 60 | |
| 60 | 61 | protected $casts = [ |
| 61 | - 'unit_price' => 'double', | |
| 62 | - 'cost' => 'double', | |
| 63 | - 'subtotal' => 'double', | |
| 64 | - 'tax_amount' => 'double', | |
| 65 | - 'shipping_charge' => 'double', | |
| 66 | - 'discount_total' => 'double', | |
| 67 | - 'line_total' => 'double', | |
| 68 | - 'refund_total' => 'double', | |
| 62 | + 'unit_price' => 'double', | |
| 63 | + 'cost' => 'double', | |
| 64 | + 'subtotal' => 'double', | |
| 65 | + 'tax_amount' => 'double', | |
| 66 | + 'shipping_charge' => 'double', | |
| 67 | + 'discount_total' => 'double', | |
| 68 | + 'line_total' => 'double', | |
| 69 | + 'refund_total' => 'double', | |
| 69 | 70 | ]; |
| 70 | 71 | |
| 71 | 72 | protected static function booted() |
| 72 | 73 | { |
| @@ -84,9 +85,9 @@ | ||
| 84 | 85 | } |
| 85 | 86 | |
| 86 | 87 | public function getCouponDiscountAttribute() |
| 87 | 88 | { |
| 88 | - return (int) ($this->line_meta['coupon_discount'] ?? 0); | |
| 89 | + return (int)($this->line_meta['coupon_discount'] ?? 0); | |
| 89 | 90 | } |
| 90 | 91 | |
| 91 | 92 | public function setOtherInfoAttribute($value) |
| 92 | 93 | { |
| @@ -154,8 +155,18 @@ | ||
| 154 | 155 | { |
| 155 | 156 | return $this->belongsTo(ProductDownload::class, 'post_id', 'post_id'); |
| 156 | 157 | } |
| 157 | 158 | |
| 159 | + /** | |
| 160 | + * All reviews of the product this line item points to — keyed on | |
| 161 | + * post_id, not on the item itself, so whereDoesntHave() over it | |
| 162 | + * expresses "the customer never reviewed this product". | |
| 163 | + */ | |
| 164 | + public function product_reviews() | |
| 165 | + { | |
| 166 | + return $this->hasMany(ProductReview::class, 'post_id', 'post_id'); | |
| 167 | + } | |
| 168 | + | |
| 158 | 169 | public function createItem($orderItems) |
| 159 | 170 | { |
| 160 | 171 | return $this->belongsTo(ProductVariation::class, 'variation_id', 'id'); |
| 161 | 172 | } |
| @@ -238,12 +249,32 @@ | ||
| 238 | 249 | } |
| 239 | 250 | |
| 240 | 251 | public function getDisplayTitle() |
| 241 | 252 | { |
| 242 | - if($this->post_title == $this->title) { | |
| 253 | + if ($this->post_title == $this->title) { | |
| 243 | 254 | return $this->title; |
| 244 | 255 | } |
| 245 | 256 | |
| 246 | 257 | return $this->post_title . ' - ' . $this->title; |
| 247 | 258 | |
| 259 | + } | |
| 260 | + | |
| 261 | + /** | |
| 262 | + * Labeled attribute combination resolved from the frozen | |
| 263 | + * other_info['item_attributes'] snapshot, e.g. "Color: Red | Size: XS". | |
| 264 | + * Falls back to the stored variation title when no attribute snapshot | |
| 265 | + * resolves (custom/simple items, or attrs whose groups were removed). | |
| 266 | + * | |
| 267 | + * @return string | |
| 268 | + */ | |
| 269 | + public function getVariationDisplayTitleAttribute() | |
| 270 | + { | |
| 271 | + // Order items carry the item_attributes snapshot (written at order | |
| 272 | + // creation), so resolve directly — getDisplayAttributesString renders | |
| 273 | + // the labeled combination and falls back to the variation title. | |
| 274 | + return \FluentCart\App\Helpers\AttributeHelper::getDisplayAttributesString( | |
| 275 | + Arr::get($this->other_info, 'item_attributes', []), | |
| 276 | + $this, | |
| 277 | + 'order_item' | |
| 278 | + ); | |
| 248 | 279 | } |
| 249 | 280 | } |