PluginProbe
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler / 1.7.0
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler v1.7.0
1.7.0 1.6.6 1.6.5 1.6.4 1.6.3 1.6.2 1.6.1 1.6.0 1.5.4 1.5.5 1.5.3 1.5.2 1.5.1 1.5.0 1.4.2 1.4.1 1.4.0 1.3.28 1.3.27 1.3.26 1.3.25 1.3.23 1.3.22 1.3.21 1.3.20 All 50 releases
← All changes | app/Models/OrderItem.php +59 -10 1.3.27 → 1.7.0 View file →
@@ -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 {
@@ -76,11 +77,19 @@
76 77 }
77 78
78 79 protected function getFormattedTotalAttribute()
79 80 {
80 - return Helper::toDecimal($this->subtotal);
81 + if ($this->line_total == 0 && $this->discount_total == 0) {
82 + return Helper::toDecimal($this->subtotal);
83 + }
84 + return Helper::toDecimal($this->line_total);
81 85 }
82 86
87 + public function getCouponDiscountAttribute()
88 + {
89 + return (int)($this->line_meta['coupon_discount'] ?? 0);
90 + }
91 +
83 92 public function setOtherInfoAttribute($value)
84 93 {
85 94 if (is_array($value) || is_object($value)) {
86 95 $this->attributes['other_info'] = json_encode($value);
@@ -146,8 +155,18 @@
146 155 {
147 156 return $this->belongsTo(ProductDownload::class, 'post_id', 'post_id');
148 157 }
149 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 +
150 169 public function createItem($orderItems)
151 170 {
152 171 return $this->belongsTo(ProductVariation::class, 'variation_id', 'id');
153 172 }
@@ -226,6 +245,36 @@
226 245 {
227 246 return $this->is_custom
228 247 ? ($this->other_info['view_url'] ?? '')
229 248 : '';
249 + }
250 +
251 + public function getDisplayTitle()
252 + {
253 + if ($this->post_title == $this->title) {
254 + return $this->title;
255 + }
256 +
257 + return $this->post_title . ' - ' . $this->title;
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 + );
230 279 }
231 280 }