ValidationStatus::class, 'payment_status' => PaymentStatus::class, 'delivery_status' => DeliveryStatus::class ]; /** * Perform any actions required after the model boots. * * @return void */ protected static function booted() { static::creating(function (self $model) { // * ASSERTIONS static::assertCancelStatus($model); }); static::updating(function (self $model) { static::assertCancelStatus($model); }); } // * RELATIONSHIPS /** * BelongsToMany products relation * * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany */ public function products() { return $this->belongsToMany(Product::class, 'order_lines', 'order_id', 'product_id'); } /** * hasMany lines relation * * @return \Illuminate\Database\Eloquent\Relations\HasMany */ public function lines() { return $this->hasMany(OrderLine::class); } /** * BelongsTo customer relation * * @return \Illuminate\Database\Eloquent\Relations\BelongsTo */ public function customer() { return $this->belongsTo(Customer::class); } /** * hasOne timeslot relation * * @return \Illuminate\Database\Eloquent\Relations\HasOne */ public function timeslot() { return $this->hasOne(Timeslot::class); } // * METHODS /** * Getter can_be_cancelled * * On peut annuler la commande si le client * n'as pas payé et que la livraison n'a pas * encore été initié, et la commande n'est pas * déjà annulée. * * @return boolean */ public function getCanBeCancelledAttribute(): bool { return !$this->validation_status->equals(ValidationStatus::cancelled()) and !$this->payment_status->equals(PaymentStatus::payed()) and $this->delivery_status->equals(DeliveryStatus::pending()); } /** * Getter formated_total_ttc * * @return string */ public function getFormattedTotalTtcAttribute(): string { return sprintf( '%s €', number_format($this->total_ttc / 100, 2, ',', ' ') ); } /** * Getter total_ttc * * @return integer */ public function getTotalTtcAttribute(): int { /** @var \Illuminate\Database\Eloquent\Collection<\App\Models\OrderLine> */ $lines = $this->lines; return $lines->reduce(function ($previous, OrderLine $next) { /** @var int|null $previous */ return \intval($previous) + $next->getRawOriginal('total_ttc'); }); } /** * Check if order can be cancelled * * @param self $model * @return void * @throws \RuntimeException If the order is canceled while it cannot be. */ public static function assertCancelStatus(self $model) { if ( !$model->can_be_cancelled and $model->validation_status->equals(ValidationStatus::cancelled()) ) { throw new \RuntimeException("La commande '{$model->id}' ne peut être annulée"); } } }