In a model OrderItem I’m trying to append coupon value through accessing the Order relationship like below:
public function getCouponValueAttribute() {
if($this->order->coupon_data) {
if(!$this->sale && !$this->gift) {
return ($this->original_price * $this->quantity) - (($this->original_price * $this->quantity) - (($this->original_price * $this->quantity)*($this->order->coupon_data['percentage']/100)));
}
}
return 0;
}
This results to the server to run out of memory.
Order Relationship through Order model
public function order() {
return $this->belongsTo(Order::class);
}
The Order Model looks like below:
class Order extends Model
{
use FilterQueryString;
protected $guarded = [];
protected $filters = ['in', 'inPayment', 'sort'];
protected $appends = ['subtotal', 'discountTotal', 'discountTotal2', 'couponDiscount', 'shipping_details', 'shipping_product_name', 'gross_value', 'net_value', 'shipping_iso', 'generated_tracking_url', 'is_retail'];
protected $casts = [
'shipping_address' => 'array',
'billing_address' => 'array',
'shipping_option' => 'array',
'coupon_data' => 'array',
'customer' => 'array',
'invoice' => 'array'
];
public function items() {
return $this->hasMany(OrderItem::class);
}
public function payment() {
return $this->hasOne(PaymentDetail::class);
}
public function user() {
return $this->belongsTo(User::class);
}
public function notes() {
return $this->hasMany(OrderNote::class);
}
public function added_payments() {
return $this->hasMany(AddedPayment::class);
}
public function inPayment($query, $value) {
$value = explode(",", $value);
return $query->whereHas('payment', function($q) use ($value) {
$q->whereIn('status', $value);
});
}
public function country() {
return $this->hasOneThrough(Country::class, User::class, 'country_id', 'id', 'user_id', 'id');
}
public function coupon() {
return $this->belongsTo(Coupon::class);
}
public function points() {
return $this->hasOne(LoyaltyPoint::class);
}
public function shipments() {
return $this->hasMany(OrderShipment::class);
}
public function scopeQuote($query) {
return $query->where('quote', true)->orWhere('was_quote', true);
}
public function scopeActive($query) {
return $query->whereIn('status', [1,2,3]);
}
public function getActiveItemsAttribute() {
return array_filter($this->items->toArray(), function($q) {
return $q['status'] == 1;
});
}
public function getSubtotalAttribute() {
$subtotal = 0;
foreach($this->items as $i) {
if($i->status) {
$subtotal += $i->price * $i->quantity;
}
}
return $subtotal;
}
public function getCouponDiscountAttribute() {
$discount = 0;
if($this->coupon_data) {
foreach($this->items as $i) {
if($i->status && !$i->sale && !$i->gift) {
$price = $i->bulk_price ? $i->bulk_price : $i->original_price;
$discount += ($price - $i->price) * $i->quantity;
}
}
}
return abs($discount);
}
public function getDiscountTotalAttribute() {
$discount = 0;
foreach($this->items as $i) {
if($i->status) {
$discount += ($i->original_price - $i->price) * $i->quantity;
}
}
return abs($discount);
}
public function getNetValueAttribute() {
$net_value = 0;
foreach($this->items as $i) {
$net_value += $i->price*$i->quantity;
}
return $net_value;
}
public function getShippingProfilesAttribute() {
return (array) [
(object)[
'quantity' => 4,
'length' => 25,
'width' => 20,
'height' => 10
],
(object) [
'quantity' => 8,
'length' => 30.5,
'width' => 21.5,
'height' => 20
],
(object) [
'quantity' => 15,
'length' => 32,
'width' => 24,
'height' => 24
],
(object) [
'quantity' => 20,
'length' => 50,
'width' => 30,
'height' => 20
],
(object) [
'quantity' => 30,
'length' => 50,
'width' => 30,
'height' => 25
],
(object) [
'quantity' => 40,
'length' => 60,
'width' => 40,
'height' => 20
],
(object) [
'quantity' => 50,
'length' => 48,
'width' => 40,
'height' => 30
],
(object) [
'quantity' => 60,
'length' => 60,
'width' => 40,
'height' => 25
]
];
}
public function getDhlPackagesAttribute() {
$packages = [];
$quantity = 0;
foreach($this->items as $i) {
$quantity += $i->quantity;
}
do {
foreach($this->shipping_profiles as $key => $p) {
if($quantity > 0) {
if($quantity <= $p->quantity) {
$data = (object)[
'weight' => number_format(floatVal((($p->length*$p->width*$p->height)/5000)), 2),
'dimensions' => (object)[
'length' => $p->length,
'width' => $p->width,
'height' => $p->height
]
];
$quantity -= $p->quantity;
array_push($packages, $data);
}
else if ($key == array_key_last($this->shipping_profiles)) {
$data = (object)[
'weight' => number_format(floatVal((($p->length*$p->width*$p->height)/5000)), 2),
'dimensions' => (object)[
'length' => $p->length,
'width' => $p->width,
'height' => $p->height
]
];
$quantity -= $p->quantity;
array_push($packages, $data);
}
}
}
}while($quantity > 0);
return $packages;
}
public function getDiscountTotal2Attribute() {
//Discount based on product discount
$discount = 0;
foreach($this->items as $i) {
if($i->sale && $i->status) {
$discount += ($i->original_price * $i->quantity) - ($i->price * $i->quantity);
}
}
return abs($discount);
}
public function getIsRetailAttribute() {
if(isset($this->user->is_retail)) {
if($this->user->is_retail) {
return true;
}
}
return false;
}
public function getGrossValueAttribute() {
$gross_value = 0;
foreach($this->items as $i) {
if($i->status) {
$gross_value += $i->original_price * $i->quantity;
}
}
return $gross_value;
}
public function getItemQuantityAttribute() {
$quantity = 0;
foreach($this->items as $i) {
if($i->status) {
$quantity += $i->quantity;
}
};
return $quantity;
}
public function getShippingDetailsAttribute() {
if(isset($this->shipping_option['shipping_option'])) {
return $this->shipping_option['shipping_option'];
}
if(isset($this->shipping_option)) {
return $this->shipping_option;
}
return null;
}
public function getShippingProductNameAttribute() {
if(isset($this->shipping_option['name'])) {
return $this->shipping_option['name'];
}
if(isset($this->shipping_option['productName'])) {
return $this->shipping_option['productName'];
}
return null;
}
public function getShippingIsoAttribute() {
$country = Country::find($this->shipping_address['country_id']);
return $country->iso2;
}
public function getGeneratedTrackingUrlAttribute() {
if($this->shipping_company == 'dhl') {
return 'https://www.dhl.com/gr-en/home/tracking.html?tracking-id='.$this->tracking_id;
}
if($this->shipping_company == 'speedex') {
return 'http://www.speedex.gr/isapohi.asp';
}
if($this->shipping_company == 'fedex') {
return 'https://www.fedex.com/fedextrack/?trknbr='.$this->tracking_id;
}
return null;
}
protected static function booted()
{
static::deleting(function ($order) {
$order->payment()->delete();
$order->added_payments()->delete();
$order->shipments()->delete();
$order->items()->delete();
$order->notes()->delete();
$order->points()->delete();
});
static::updated(function($order) {
Loyalty::calculateOrderPoints($order);
});
static::created(function($order) {
Loyalty::calculateOrderPoints($order);
});
}
}
Probably the attribute I’m trying to append is creating a loop somewhere and the server is running out of memory, i can’t figure it out.